-
Notifications
You must be signed in to change notification settings - Fork 22
feat: add beans serve command with web UI
#23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
hmans
wants to merge
45
commits into
main
Choose a base branch
from
beans-serve
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- Add cmd/serve.go with HTTP server serving GraphQL API - GraphQL endpoint at POST /graphql - GraphQL Playground at GET /graphql for interactive queries - Supports --port/-p flag (default 8080) - Graceful shutdown on SIGINT/SIGTERM - Plan web UI feature with subtasks for future implementation
- Add internal/web/ package with go:embed for frontend assets - Serve embedded SPA from beans serve at / - Handle SPA routing (unknown paths serve index.html) - Add mise tasks: build:frontend, build:embed - Build pipeline now includes frontend compilation
- Use signal.NotifyContext for cleaner signal handling - Properly deregister signal handlers on exit
- Add gin.Logger() middleware to log HTTP requests
* main: perf: update beancore state incrementally instead of full reload feat: add channel-based file watcher with typed events doc: Add rule about prefixing bean titles w/ IDs when talking to humans doc: Add rule about not closing beans that contain open todos
- Add Subscription type with beanChanged field to schema
- Add BeanChangeEvent type and ChangeType enum (CREATED/UPDATED/DELETED)
- Implement subscription resolver using beancore.Subscribe()
- Add WebSocket transport to serve command for subscription support
- Start file watcher automatically when server starts
Usage: Subscribe to bean changes via GraphQL:
```graphql
subscription {
beanChanged {
type
beanId
bean { id title status }
}
}
```
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- BeansStore class with $state for reactive beans map - Load all beans via GraphQL query - Helper methods: byStatus, byType, children, blockedBy - Uses SvelteMap for proper reactivity - Singleton export for app-wide usage 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Display all beans in a card layout - Show id, type, status, title, tags, and date - Color-coded status and type badges - Loading and error states 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add subscribe() method to BeansStore - Handle CREATED/UPDATED/DELETED events from beanChanged subscription - Show "Live" indicator when connected - Clean up subscription on component destroy - Add wonka dependency for urql streams 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Configure gqlgen with explicit transports (WebSocket first for upgrade handling) - Add graphql-transport-ws subprotocol for graphql-ws client compatibility - Frontend connects WebSocket directly to backend in dev (bypasses Vite proxy) - Force-close connections if graceful shutdown times out - Add CORS middleware for development
Add includeInitial argument to beanChanged subscription that emits all current beans on connect as INITIAL events, followed by real-time CREATED/UPDATED/DELETED changes. This eliminates race conditions between loading and subscribing. - Add includeInitial argument (default false) to beanChanged subscription - Add INITIAL to ChangeType enum for initial state events - Update resolver to emit all beans with INITIAL type when includeInitial=true - Simplify frontend to use single subscribe() call instead of load()+subscribe()
Display beans in a tree structure matching CLI output: - Top-level beans shown at root - Children indented with visual tree lines - Color-coded left border by type (milestone, epic, feature, bug, task) - Shows child count on parent beans - Recursive BeanItem component for unlimited nesting depth
- Two-pane layout: bean list on left, detail view on right - Draggable separator with localStorage persistence (200-600px range) - Compact bean list items with short ID, title, status badge - Detail view shows: metadata, tags, relationships, body, timestamps - Click bean to select and view details - Selected bean stays in sync with real-time updates
- Add shiki package for syntax highlighting - Create markdown.ts utility with lazy highlighter initialization - Use github-dark theme for code blocks - Add styling for code blocks and inline code - Preload highlighter in layout for faster first render
- Remove header for cleaner layout - Make separator more subtle with gray tones - Fix HTML comment syntax
- Use shiki/core with explicit language imports instead of full bundle - Bundle 9 languages: JS, TS, Go, Bash, JSON, YAML, Markdown, GraphQL, Diff - Other languages fall back to plain styled code blocks - Skip shiki during SSR (browser-only) Frontend build: 9.7 MB → 1.8 MB (81% reduction) Go binary: 60 MB → 53 MB
- Add INITIAL_SYNC_COMPLETE event type for explicit sync signaling
- Replace fragile 500ms timeout in frontend with server-sent signal
- Add type guard to filter in BeanDetail.svelte for type safety
- Remove redundant {#if b} check since filter already excludes undefined
- Add tests for subscription resolver (INITIAL_SYNC_COMPLETE)
- Add tests for web embed package (Handler, DistFS)
- Change default port from 22880 to 8080 - Add `server.port` config option in `.beans.yml` - CLI `--port` flag overrides config value - Priority: CLI flag > config file > default (8080)
The `beans init` command now writes `server.port: 8080` to the generated `.beans.yml` file.
beans-4zsu: Add comments to generated .beans.yml config file
* main: chore: beans feat: add bean for agent-specific beans prime output chore: cleanup OpenCode plugin docs: add OpenCode plugin and integration instructions fix: Tweak `beans prime` prompt chore: Claude
* main: fix(cli): allow `beans version` to run without .beans directory (#28) fix: In the prompt primer, request the agent to check for existing beans before creating a new one feat(tui): add 'y' shortcut to copy bean-id (#26) docs: clarify completion rules for beans with unchecked items (#27) feat: support short IDs (without prefix) in GraphQL queries
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds a
beans servecommand that starts a web server providing a full-featured web UI for browsing and managing beans./api/graphqlexposing queries, mutations, and subscriptionsKey Features
Backend (
beans serve)//go:embed--portflag, config fileserver.port, or default (8080)Frontend (SvelteKit)
GraphQL Enhancements
Subscriptiontype withbeanChangedfieldincludeInitialparameter to receive existing beans on subscription startINITIAL_SYNC_COMPLETEevent for explicit sync signaling (no magic timeouts)BeanChangeEventtype withINITIAL,INITIAL_SYNC_COMPLETE,CREATED,UPDATED,DELETEDchange typesConfiguration
server.portoption in.beans.yml(default: 8080)beans initnow includes server config in generated file--portflag overrides config valueArchitecture
Usage
Development Workflow
Test Plan
beans serveand verify the web UI loads athttp://localhost:8080beans serveralias works--portflag overrides defaultserver.portin config is respected