From 1f44bc6d91321c4e45521f810073fb71ffec4b03 Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Thu, 15 Oct 2026 07:23:17 -0700 Subject: [PATCH] Add todo mode and replace the plan with TODO.md --- TODO.md | 117 ++++++++ api/openapi.yaml | 62 ++++ docs/operations.md | 10 +- docs/plan.md | 503 -------------------------------- internal/agents/guidance.go | 27 +- internal/agents/manager.go | 5 +- internal/agents/manager_test.go | 63 ++++ internal/agents/tasks.go | 50 ++++ internal/api/api.gen.go | 323 +++++++++++++------- internal/git/git.go | 12 + internal/server/server.go | 52 ++++ internal/store/store.go | 20 +- internal/todo/todo.go | 142 +++++++++ internal/todo/todo_test.go | 58 ++++ web/dist/panes.js | 4 +- web/dist/panes.js.map | 2 +- web/dist/task.js | 2 +- web/dist/task.js.map | 2 +- web/dist/todo.js | 121 ++++++++ web/dist/todo.js.map | 1 + web/src/api.gen.ts | 110 +++++++ web/src/panes.ts | 6 +- web/src/task.ts | 2 +- web/src/todo.ts | 147 ++++++++++ web/style.css | 55 ++++ 25 files changed, 1259 insertions(+), 637 deletions(-) create mode 100644 TODO.md delete mode 100644 docs/plan.md create mode 100644 internal/todo/todo.go create mode 100644 internal/todo/todo_test.go create mode 100644 web/dist/todo.js create mode 100644 web/dist/todo.js.map create mode 100644 web/src/todo.ts diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..0d6a7a5 --- /dev/null +++ b/TODO.md @@ -0,0 +1,117 @@ +# Bugs + +- Question answers given while the agent is working get lost + Answering an inbox question while the task's agent is mid-turn sometimes never reaches the agent. Answers are meant to be held and delivered as one message once the session is idle with no blocking question still waiting (`Deliver` in `internal/agents/inbox.go`, called when a turn ends). Find the path where a held answer is dropped. Byre restarts often while agents deploy, and a restart cuts the turn off and resumes it with the restart notice (`Recover` in `internal/agents/manager.go`), so check that path first. Add debugging output before changing code. +- Merge is forgotten if the human switches tasks before the merge turn ends + Clicking Merge starts a merge-in turn and records, in memory only, that the task is to be squashed when that turn ends (`m.merges` in `internal/agents/mergein.go`, read by `takeMerge` at turn end). The human then switched to another task, and when the turn finished nothing was merged. Switching tasks in the UI shouldn't affect server state, so the likelier cause is that byre restarted during the turn, which loses the in-memory intent (as described under "Closing a task" in `docs/operations.md`). Confirm the cause, and make the merge intent survive until the turn ends. + +# M0 — Skeleton + +- Per-task snapshot counts and disk usage in the Admin view + The Admin view already covers queue state, rate limits, process liveness, stuck and zombie detection, and protocol errors. Add each active task's snapshot count and the disk its snapshots and worktree use. + +# M1 — One agent end to end + +- Subagent views + Render the vendor's subagent activity in the transcript once agents use subagents. Vendor-specific events that don't map onto the core event kinds get vendor-specific UI components. +- Mermaid rendering in Markdown views + Render Mermaid source (in transcripts, inbox items and review attachments) as diagrams. +- Decide whether to render agent todo lists + Interface coverage is added one feature at a time as the workflow needs it, rather than mirroring the vendor's native interface. Decide whether the agent's own todo list gets rendered in the transcript. +- Decide whether to support @-file mentions in the composer + +# M2 — Seeing the work + +- Timeline scrubbing + A timeline over a task's snapshots, showing the diff at each point alongside the transcript up to that snapshot's `event_seq`. +- Forking from a snapshot + A new worktree from a snapshot commit plus a new agent session. Same vendor: the vendor's native session fork or resume. Different vendor: a handoff bundle from `export_context`, labelled in the UI as a handoff, not a true fork. +- Terminals + PTYs via `github.com/creack/pty`, rendered with xterm.js, one WebSocket per open terminal (the only WebSocket use in byre). Scoped to the task's worktree by default. Shown as a pane tab. +- Decide whether terminals survive a byre restart + Either accept that terminals are lost when byre restarts, or back each terminal with tmux. +- File browser + Read-only, scoped to project and worktree roots. Shown as a pane tab. +- Per-project setup config + A setup script run in each new worktree (dependency install, env file copying), and port allocation so parallel dev servers don't collide. +- Decide the format of per-project setup config + It holds the setup script, port allocation, and the run and capture config that visual reviews use. +- Previews + Web: byre supervises a per-task dev server and exposes it over Tailscale, preferably as a per-task port through `tailscale serve`, since path-prefix proxying breaks apps that use absolute paths. iOS: on-demand simulator screenshots and recordings attached to the task, with Screen Sharing over Tailscale as the manual fallback. Shown as a pane tab. +- Confirm `tailscale serve` can expose per-task preview ports + +# M3 — Second vendor and review + +- Codex adapter + A JSON-RPC client for `codex app-server`, with Go types generated from the protocol schema the CLI can emit. It needs: start thread, stream events, send turns, interrupt, resume, and the same interface coverage as Claude (interrupts, model switching, compaction, image input). Disable CLI auto-updates so the version changes only when the owner updates it, and keep a contract test suite built from recorded transcripts. +- Verify that Codex app-server can fork threads +- Review profiles and triggers + Reviews are done by a separate agent session, never the implementer, by default from a different vendor. Each review targets a snapshot and is cached by tree sha; when the task's tree moves on, existing reviews are marked stale. A review profile (security, performance, privacy, visual UX, plan conformance, ...) has a prompt, vendor, model, output schema and capture config; workflow stages reference profiles by name. Triggers: on `ask_human` (the inbox item appears at once and the review attaches when done, even if the item was resolved first), before merge, on demand, and periodically on elapsed time or diff size, debounced to turn boundaries or a quiet period. A `request_review(scope, concerns[], profile?)` MCP tool lets agents ask for one. +- Decide the periodic review thresholds + The defaults for elapsed time and diff size, with per-project overrides. +- Visual review output + Structured output that leans visual rather than quoting code: a summary; highlights, each with a category, severity and anchors to files or lines so the UI can jump to them; Mermaid diagrams of changed data flow, call graphs, state machines and schemas; screenshots or recordings of the running result (Playwright MCP for web projects, `xcrun simctl io` screenshot and recordVideo for iOS simulator projects); before/after pairs from the base ref and the current snapshot where possible. The UI should encourage, in increasing order: file diffs, diff stats, an agent-generated summary, agent highlights with visual explanations. +- Decide how simulators are allocated + iOS simulators are shared between parallel tasks and review agents and need allocation or locking. Parallel Xcode builds also compete for CPU, and per-worktree DerivedData costs disk and cold builds. +- Cross-vendor review + A review profile whose vendor differs from the implementer's. + +# M4 — Merging and history + +- Co-author trailers for humans who trigger forks + Squash commits already carry a `Co-authored-by` trailer for every other human with a message bubble in the task's transcript (see "Closing a task" in `docs/operations.md`). Once forks exist, a human who triggers a fork of the task should count too. +- Edit the drafted merge message before confirming +- Merge-resolution stage + A stage triggered when merging the default branch into a task branch conflicts; its result goes to review. +- Git notes on squash merges + Attach a note under `refs/notes/byre` to each squash commit, holding the plan, the handoff bundle, review summaries, eval results and resolved inbox decisions, with full transcripts referenced by task ID. Notes don't push or fetch by default, so the merge pushes the notes ref explicitly and project setup configures fetching it. +- Repeated merge cycles + Let a task merge more than once. After the squash commit lands, reset the task branch to the new default-branch head, since squash commits leave the agent's commits as non-ancestors and later cycles would accumulate spurious conflicts (the per-turn history stays reachable through snapshot refs). Then tell the agent explicitly that its branch was squashed and reset, so it doesn't try to repair history, and resume it; files on disk don't change. Test this per vendor. +- Archive search + Search closed tasks across transcripts, artifacts and decisions. +- GitHub Issues integration + Issue tracking is pluggable, GitHub Issues first. Tasks link to issues at intake, and each merge posts or updates a summary comment on the linked issues. + +# M5 — Workflows + +- Workflow definitions and storage + A workflow is a sequence of stages, each with a role prompt template, a vendor and model, typed artifact inputs and outputs, an optional gate, and optional review profiles. Definitions, prompt templates and review profiles live on the server, not in repos, and export and import as files. A task freezes its workflow definition at intake, so later edits to the workflow don't change running tasks. No general DAG engine until a real workflow needs one. +- Stages, gates and bounded loops + Gates are human approval through the inbox, a review pass or an eval pass. Loops are bounded, for example `on_fail: { goto: build, max: 3, then: escalate }`. +- Plan artifact + A versioned artifact with goal, approach, steps, acceptance criteria, risks and open questions. Humans edit it through the inbox; agents propose edits, which go to the inbox for approval. Stored on the server and attached to merges with git notes, never committed. A plan-conformance review profile compares the diff with it. +- Eval stages + Report pass or fail per acceptance criterion of the plan. +- Task intake + Pick a workflow, fill its inputs (a brief, attachments, linked GitHub issues, handoff bundles from other tasks), and optionally override vendors, models, prompts or review profiles per stage. +- Mid-task swapping of stage vendors, models, prompts and review profiles + At any point a human can swap a stage's vendor, model, prompt or review profiles, and add, remove or reorder the stages of the task's frozen workflow. + +# M6 — Fan-out + +- `export_context` and handoff bundles + An `export_context(purpose)` MCP tool producing a bundle with the goal, decisions made and why, current state, dead ends tried, open questions and relevant files. Used for cross-vendor forks, stage-to-stage handoff, and the durable record of a task. Compaction already writes the same contents. +- Same-vendor forks +- Cross-vendor handoffs +- Fork-and-compare + A fan-out of N forks with different vendors or prompts from one snapshot, followed by a judge stage that produces a comparison with visuals. +- Just-in-time fan-out with limits + `spawn_stages(stages[])` and `collect(stage_ids[])` MCP tools let agents build workflows on the fly, using the same stage definition format. Limits on maximum depth, concurrent spawned stages and per-task usage budget, all configurable; an optional per-workflow human gate on spawning. Spawned stages show in the task's UI tree marked as just-in-time, and a just-in-time structure can be saved as a reusable workflow. +- Decide the default limits for just-in-time fan-out + Defaults for maximum depth, concurrent spawned stages and per-task usage budget. + +# M7 — Inbox triage + +- Inbox triage agent + An agent that answers questions resolvable from the repo or docs and escalates the rest with its reasoning attached. Tune it on real inbox data. + +# UI + +- Decide whether to keep both the ⌘K switcher and the Tasks view + +# Known hazards + +- Pre-push hook on the shared repo + Agents share the repo's `.git` across worktrees and run fully permissive, so they can push, check out other branches, delete snapshot refs, or run `git gc` or `git worktree prune`. Session guidance already forbids this; add a pre-push hook on the shared repo that blocks pushes not made by byre, and periodically verify that snapshot refs survive. +- Consider moving large event payloads into blobs + Stream-json is verbose and tool outputs are large, so the event log grows fast. SSE resume and scrubbing need efficient queries; storing large payloads as blobs is one option. diff --git a/api/openapi.yaml b/api/openapi.yaml index 084fceb..9fdfda8 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -145,6 +145,43 @@ paths: "400": { $ref: "#/components/responses/Error" } "404": { $ref: "#/components/responses/Error" } + /api/projects/{projectId}/todo: + parameters: + - { name: projectId, in: path, required: true, schema: { type: string } } + get: + operationId: getTodo + description: The items of TODO.md at the root of the project's default branch, in file order. + responses: + "200": + description: The items; exists is false when the default branch has no TODO.md. + content: + application/json: + schema: { $ref: "#/components/schemas/Todo" } + "404": { $ref: "#/components/responses/Error" } + + /api/projects/{projectId}/todo/tasks: + parameters: + - { name: projectId, in: path, required: true, schema: { type: string } } + post: + operationId: startTodoItem + description: > + Creates a task for a TODO.md item, recording the item as its todo_item, and starts its agent with the item as + the first message. Refused while another active task has the same item. + requestBody: + required: true + content: + application/json: + schema: { $ref: "#/components/schemas/TodoStart" } + responses: + "201": + description: The new task. + content: + application/json: + schema: { $ref: "#/components/schemas/Task" } + "400": { $ref: "#/components/responses/Error" } + "404": { $ref: "#/components/responses/Error" } + "409": { $ref: "#/components/responses/Error" } + /api/tasks/{taskId}: parameters: - { name: taskId, in: path, required: true, schema: { type: string } } @@ -643,6 +680,31 @@ components: created_at: { type: string, format: date-time } closed_at: { type: string, format: date-time, description: When the task was merged or discarded. } merge_commit: { type: string, description: "merged: the squash commit on the default branch; empty when there was nothing to merge." } + todo_item: { type: string, description: "The title of the TODO.md item the task was started from; absent for other tasks." } + + Todo: + type: object + required: [exists, items] + properties: + exists: { type: boolean, description: Whether the default branch has a TODO.md at its root. } + items: + type: array + items: { $ref: "#/components/schemas/TodoItem" } + + TodoItem: + type: object + required: [title, body, section] + properties: + title: { type: string, description: "The item's first line, without its list marker: the item's identity." } + body: { type: string, description: The item's further lines, as Markdown with the item's indentation removed. } + section: { type: string, description: The text of the nearest heading above the item; empty when there is none. } + + TodoStart: + type: object + required: [title] + properties: + title: { type: string, description: The title of the item to start. } + model: { type: string } Unmerged: type: object diff --git a/docs/operations.md b/docs/operations.md index 0c072fb..aa50c9d 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -73,7 +73,7 @@ Agents don't commit; byre does. Each `user.message` event records `head`, the wo byre chooses the Claude session ID (`vendor_session_id`) up front, so every session can be resumed. Processes start on demand: the first message after a restart resumes the session with `--resume`. Sessions are `running` from the moment a turn is sent until its `result` arrives; on startup, every session still marked `running` was cut off mid-turn, and byre resumes it and sends a message telling the agent to re-check the working tree. Stopping the server kills all agent processes. Merging or discarding a task kills its sessions and marks them `completed`. -Every session gets byre's guidance (`guidance` in `internal/agents/guidance.go`): ask questions with `ask_human`, end each turn with a final message that summarizes it (including every departure from the plan), don't commit (byre commits each turn), and don't push, touch other branches or run git maintenance. It is passed as `--append-system-prompt`, which Claude Code records on a session's first request and reuses on resume, so a running session keeps the text it started with; a `UserPromptSubmit` hook also attaches it as `additionalContext` to every user turn, which reaches existing sessions too. +Every session gets byre's guidance (`guidance` in `internal/agents/guidance.go`): ask questions with `ask_human`, end each turn with a final message that summarizes it (including every departure from the plan), don't commit (byre commits each turn), and don't push, touch other branches or run git maintenance. A task started from a `TODO.md` item gets one more line naming the item and telling the agent to remove it from `TODO.md` in its worktree when the work is done (`taskGuidance`; see "Todo"). It is passed as `--append-system-prompt`, which Claude Code records on a session's first request and reuses on resume, so a running session keeps the text it started with; a `UserPromptSubmit` hook also attaches it as `additionalContext` to every user turn, which reaches existing sessions too. A Stop hook (`bounceProseQuestion` in `internal/agents/guidance.go`) bounces a turn whose final message asks the human something in prose: if `ask_human` wasn't called during the turn and the final message (`last_assistant_message`) has a sentence ending in `?` outside code spans, code blocks, quotes and blockquotes, the stop is blocked once with an instruction to ask through `ask_human`. The per-turn flags reset when the next user message is sent. Claude Code reports the block as a "Stop hook error" notification; that is expected. An agent told explicitly to ask in plain text will refuse the bounce. @@ -102,6 +102,14 @@ Messages byre itself sends an agent (actor `byre`: the restart notice, Sync and The task switcher (⌘K, or the navbar crumb) lists active tasks with their session state and open inbox item count, live while it is open. Tasks with inbox items come first; within each group, the task least recently visited in this browser comes first (never-visited tasks before all others, ties in the server's order: projects by name, tasks newest first). Visit times are kept in the browser's localStorage under `byre.visits`, stamped when a task is selected and again when it is left. Typing filters them and adds a last row that creates a task with the typed text as its title, in the current task's project (the first project when no task is selected); Enter picks the highlighted row. Picking a task here or in the Tasks view selects it and, if neither pane shows the Transcript tab, switches a pane that isn't showing Tasks to it. +## Todo + +A project's `TODO.md` is read from the root of its default branch in the project's checkout (`git cat-file blob :TODO.md`), so it shows what has been merged, not uncommitted edits in the checkout. `GET /api/projects/{id}/todo` returns `exists` and the parsed `items` (`internal/todo`): every top-level list item (`-`, `*`, `+`, `1.` or `1)` at the start of a line) is an item. Its first line, with any `[ ]` checkbox removed, is its `title`; the lines indented under it (and lines continuing it without a blank line between) are its `body`, with the common indentation removed; `section` is the nearest heading above it. Checked items (`[x]`) are skipped, list markers inside fenced code don't count, and paragraphs between items are ignored. + +The title is the item's identity. `POST /api/projects/{id}/todo/tasks` with a `title` re-reads `TODO.md`, refuses an unknown title (404) or one an active task already has (409), creates a task from the default branch with that title and `todo_item` (the `tasks.todo_item` column, empty for other tasks), and starts its session as the requesting user with `todoPrompt` (`internal/agents/tasks.go`): the item as written, and an instruction to remove it from `TODO.md` in the worktree when the work is done. The agent's guidance names the item too (`taskGuidance`, see "Agent sessions"), so the instruction survives compaction and resumes. The agent removes the item on its own branch, so the removal lands on the default branch in the same squash commit as the work. + +The **Todo** tab lists each project's items, grouped by section, with each body rendered as Markdown. An item with an active task whose `todo_item` equals its title shows that task's session state as a link to the task instead of a **Start** button. **Start** posts the item with the composer's default model, selects the new task and shows its transcript. The tab fetches every project's `TODO.md` when it opens, when the project list changes, when the SSE stream reconnects, and refetches a project's on `task.merged`; a change pushed to the default branch outside byre shows the next time one of those happens. + ## Inbox Agents ask questions with the `ask_human` MCP tool. Each question carries a `context` with the background the human needs to answer without reading the transcript, and its choices are written inline in that context as Markdown list items: `- ( ) text` for pick-one choices, with exactly one `- (*) text` marking the recommendation, or `- [ ] text` for pick-any choices, with `- [x] text` marking the recommended ones. There is no separate list of options. byre parses the choices out of `context` (`internal/agents/choices.go`; list items inside code fences and blockquotes don't count) and stores their text in the payload as `options`, with `multiple` (pick-any) and `recommended`. The UI renders the context as Markdown with a radio button or checkbox in place of each choice's marker. A malformed call (no `context` or `why_blocked`, fewer than two choices, pick-one and pick-any choices mixed, a pick-one question without exactly one recommendation, two choices with the same text, an unknown attachment kind, a foreign `thread_id`) is rejected with a message saying what to fix, and nothing is filed. The call returns the item's id as `question_id`. An agent withdraws a question it no longer needs answered (the human answered it in a chat message, say) with the `cancel_question` MCP tool and that id: an `open` question of its own session becomes `dismissed` with no `resolved_by` (its `inbox.updated` event has actor `agent`), which also stops a blocking one from holding back delivery; anything else is rejected with a message saying why. Each turn's final message (as a `report`) and each agent error (a turn that ends in error without a human interrupt, a process that dies mid-turn) also files an item. diff --git a/docs/plan.md b/docs/plan.md deleted file mode 100644 index a717b5a..0000000 --- a/docs/plan.md +++ /dev/null @@ -1,503 +0,0 @@ -# byre — Plan - -A self-hosted Go server on a home Mac Studio that manages third-party coding agents (Claude Code, Codex) across projects and tasks, exposed to a SPA over Tailscale. Built for its author first; multi-user and multi-device from the start. - -## Working agreement - -This plan reflects decisions already agreed. Do not deviate from it without asking first. If an approach turns out not to work, a decision needs revisiting, or something requires reverting work or a destructive action, stop and ask rather than choosing an alternative. Items under "Open items" are not yet decided; raise them when they become blocking. - -`AGENTS.md` holds the standing rules for working on byre (deploying before handoff, UI layout and look, web code). `docs/operations.md` describes how the built system works and runs. "Build sequence" below says what is built. - -## Goals - -- Manage many concurrent agent sessions across projects (repos) and tasks (worktrees). -- Spend human attention efficiently: an inbox of structured questions and reports, reviews that explain changes visually, and diffs as the least-encouraged way to understand work. -- Support customizable workflows (for example plan → build → eval) with per-stage vendors, models, and review types. -- Snapshot everything so work can be scrubbed through, forked, and compared. -- Keep the history of why work was done attached to the merges it produced. -- API-first so a future native macOS app is a second client, not a rewrite. - -## Non-goals (for now) - -- Mobile UI. -- Pull requests. Merges are local, then pushed. -- Our own agent. We orchestrate third-party agents only. -- Public internet exposure (no Tailscale Funnel, no cloud relay). -- Generic agent-to-agent wiring. Agent collaboration happens through workflow stages and the specific patterns below. -- General DAG workflow engine. - -## Future features - -- Humans editing code directly in task worktrees (open-in-editor, rules for hand edits while agents run). -- Mobile UI. -- Claim/assign ownership of inbox items. - ---- - -## Architecture - -### Server - -- Go, single binary, run under launchd on the Mac Studio. -- Binds to `127.0.0.1` only. Fronted by `tailscale serve` on its own HTTPS port of the machine's `*.ts.net` name (not a path prefix, which breaks the SPA's absolute paths), with a valid certificate. Clients get HTTP/2 and SSE passes through unbuffered. -- SPA served from `embed.FS` in release builds and `os.DirFS` behind a dev flag. Same handler either way. -- Storage: SQLite via `modernc.org/sqlite` (pure Go, no CGO), WAL mode. - -### Auth and identity - -- Identity comes from Tailscale's injected headers (`Tailscale-User-Login`, `Tailscale-User-Name`). Trust them only on requests arriving from loopback via the serve proxy. -- Multi-user is a real requirement. Every mutating action records the acting user. -- Users are created on first request. Each sets the git name and email used for commit authorship and co-author trailers through the API (`PUT /api/me`); agents can't start until it is set. - -### API - -- REST, OpenAPI spec-first (`api/openapi.yaml`). Go server types and routing are generated with `oapi-codegen`; the SPA's TypeScript types are generated with `openapi-typescript` and used through a small typed client. A Swift client can be generated later for the macOS app. -- Real-time state: one multiplexed SSE stream per client. Every event carries a monotonic sequence number; clients resume with `Last-Event-ID`. -- Terminals are the only WebSocket use: one WebSocket per open terminal. - -### Notifications - -- Web push via a service worker (possible because of the real `ts.net` certificate). -- Notify on blocked inbox items first; other kinds are opt-in. -- Per-user preferences; collapse bursts into one notification. - -### Server observability - -- Agent process liveness; detection of stuck and zombie processes. -- Adapter and protocol-parse errors. -- Snapshot counts and disk usage per task. -- Concurrency queue state and vendor rate-limit status. -- Exposed in an admin view in the SPA. - -### Concurrency and usage - -- Global and per-vendor caps on concurrently running agent turns (idle sessions don't count); excess turns queue. -- Usage (cost, duration, turns) is recorded per turn in the event log and available through the API per task, workflow stage, and vendor. The UI never shows it. -- Vendor rate-limit errors surface as their own inbox state rather than as generic failures. - ---- - -## Agent integration - -### Adapters and the event model - -Vendor specifics live behind adapters. The event model is a **shared core plus vendor-specific extensions**: - -- Core event kinds: message, tool call, tool result, file change, question, turn end, error. -- Vendor-specific event types for features that don't map cleanly, rendered by vendor-specific UI components. - -**Interface coverage.** The SPA covers the vendor capabilities this workflow actually uses, each added as a specific feature when it is needed, rather than mirroring the native interface wholesale: interrupts, model switching, compaction, and image input. Compaction is byre's own and vendor-agnostic, not the vendor's: the agent writes a handoff (the same contents as an `export_context` bundle) and the work continues in a new session that starts from it. Subagent views and Mermaid rendering come later, once agents use them. Not planned: generic slash-command passthrough (a command worth having gets its own UI) and plan mode (planning is a workflow stage). - -**Claude.** Implement the Claude Code CLI's stream-json control protocol natively in Go, reverse-engineered from the open-source Agent SDKs (TypeScript and Python). These SDKs spawn the `claude` CLI and exchange stream-json over stdio with a bidirectional control channel. Required capabilities: start session, stream events, send messages, interrupt, resume by session ID, fork session, register hooks (at minimum Stop and PostToolUse), attach MCP servers. - -**Codex.** Implement a JSON-RPC client for `codex app-server`. Generate Go types from the protocol schema the CLI can emit. Required capabilities: start thread, stream events, send turns, interrupt, resume. Fork support needs verification. - -**Protocol stability.** Neither protocol is a guaranteed public contract. - -- Disable CLI auto-updates, so the version changes only when the owner updates the CLI. The version is not pinned. -- Maintain a contract test suite built from recorded transcripts; run it after updating the CLI. -- Fallback if Claude protocol drift becomes painful: a thin Node sidecar wrapping the official SDK, speaking our protocol to Go. Do not adopt the fallback without asking. - -### Session configuration - -- Permission posture: fully permissive ("yolo"). Agents act freely inside their worktree; humans review afterwards. -- Agents don't commit. byre commits everything in the worktree to the task branch at the end of every turn that changed files, authored as the session's creator, with the first sentence of the turn's summary as the message. Turns are the unit the human reviews, and the merge cycle squashes the branch anyway, so these commits only mark turn boundaries for diffing and restore. For Claude, also disable co-author attribution via Claude Code's settings for the session, since attribution is a default behavior. -- Instruct agents not to push, not to touch other branches, and not to run git maintenance commands (see "Known hazards"). -- Every session is launched with our MCP server attached. - -### Lifecycle - -- Agent processes are children of the server. On server restart they are killed. -- On restart, sessions that were active are resumed by vendor session ID. The server then injects a message: the agent was interrupted mid-turn and must re-check the working tree before continuing. - -### MCP tools - -The Go server hosts an MCP server attached to every agent session. - -- `ask_human(context, question, why_blocked, attachments[], blocking, thread_id?)` - - `context` carries the background the human needs to answer without reading the transcript, with the choices inline as `- ( ) text` / `- (*) recommended` (pick one) or `- [ ] text` / `- [x] recommended` (pick any) list items. - - Non-blocking at the protocol level: returns immediately with "question filed." - - `blocking: true` means the agent should end its turn; `false` means it continues with unblocked work. - - The human's answer arrives as a structured next turn. - - `thread_id` continues an existing inbox thread. -- `set_merge_title(title)`: the title of the squash commit the task becomes (see "Merge cycle"). -- `request_review(scope, concerns[], profile?)` -- `export_context(purpose)` → a handoff bundle (see "Handoff bundles"). -- `spawn_stages(stages[])` and `collect(stage_ids[])` for just-in-time fan-out and fan-in (see "Workflows"). - -`attachments` share one schema across tools, inbox replies, and reviews: file and line-range references, diff references, images, diagrams (Mermaid source), links to tasks or snapshots, and URLs. - -Validation: reject malformed calls with a corrective message (for example, an `ask_human` with no choices in its context or no `why_blocked`). - -**Turn summaries.** There is no report tool. Each turn's final message is its summary: session guidance asks agents to end every turn with one covering what they did, every departure from the plan, risks, and what's next, and byre files it to the inbox as a report. A dedicated report tool was tried and dropped: models wrote the closing recap anyway, even when the tool's result, the system prompt and a per-turn reminder all said not to, so the human read everything twice. - -Questions asked in plain prose (a final message that asks something without an `ask_human` call) are bounced by a Stop hook that sends the agent back to ask properly, once per turn. Detection is a sentence ending in `?` outside code, quotes and blockquotes; expect to tune it, since overly strict detection produces nudge loops and overly lenient lets prose questions through. - ---- - -## Data model - -``` -User (tailscale_login, display_name, git_name, git_email, - notification_prefs) -Project (id, name, repo_path, default_branch, remote, setup_config, - issue_tracker_config) -Workflow (id, name, version, definition) -- server-side, exportable -Task (id, project_id, title, branch, worktree_path, base_ref, - status, workflow_id, workflow_snapshot, created_by, - created_at, closed_at, merge_commit) -TaskIssueLink (task_id, tracker, issue_ref) -Stage (id, task_id, parent_stage_id, def_id, role, vendor, model, - state, origin) -- origin: workflow | jit -AgentSession (id, task_id, stage_id, vendor, model, vendor_session_id, - parent_session_id, forked_from_snapshot_id, state, role) -Artifact (id, task_id, stage_id, kind, version, payload, created_by) - -- plan, eval-report, handoff, ... -Event (seq, agent_session_id, task_id, project_id, kind, - payload, created_at) -- append-only -Snapshot (id, task_id, agent_session_id, n, commit_sha, tree_sha, - event_seq, trigger, created_at) -InboxItem (id, project_id, task_id, agent_session_id, thread_id, kind, - priority, blocking, payload, snapshot_id, review_id, state) -InboxResponse (id, inbox_item_id, user_id, type, options, text, attachments, - created_at) -- type: option | other | dismiss -Review (id, task_id, snapshot_id, tree_sha, profile, reviewer_vendor, - trigger, state, summary, highlights, attachments, stale) -ReviewProfile (id, name, prompt, vendor, model, output_schema, capture_config) -Merge (id, task_id, cycle, commit_sha, merged_by, co_authors, - note_ref, pushed_at) -Blob (id, content_type, path) -- screenshots, recordings, etc. -Terminal (id, task_id, cwd, created_by, state) -Preview (id, task_id, port, url, process_state) -Participation (task_id, user_id, kind, since_merge_cycle) -- for co-author trailers -``` - -Notes: - -- `AgentSession.role` distinguishes implementers from planners, reviewers, evaluators, merge resolvers, judges, and triage agents. -- `Event` is the source of truth for the SSE stream and for scrubbing; `seq` is global and monotonic. -- `Task.workflow_snapshot` freezes the workflow definition at intake, so later edits to a workflow don't change running tasks. -- Browser connections are ephemeral and are not part of the persistent model. - ---- - -## Workflows - -### Model - -A workflow is a sequence of **stages**. Each stage has: - -- a role prompt template, -- a vendor and model, -- typed artifact inputs and outputs, -- an optional gate: human approval (via the inbox), a review pass, or an eval pass, -- optional review profiles to run during the stage. - -Engine scope: linear stages, gates, bounded loops (`on_fail: goto … max … then escalate`), and fan-out with fan-in. No general DAGs until a real workflow needs one. - -Example: - -```yaml -name: plan-build-eval -stages: - - id: plan - agent: { vendor: claude, model: opus } - prompt: templates/plan.md - outputs: [plan] - gate: human # approve / edit / redirect via inbox - - id: build - agent: { vendor: codex } - inputs: [plan] - reviews: [plan-conformance, security] - - id: eval - agent: { vendor: claude } - inputs: [plan, diff] - outputs: [eval-report] - on_fail: { goto: build, max: 3, then: escalate } -``` - -### Storage - -- Workflow definitions, prompt templates, and review profiles live on the server, not in repos. -- They are portable: export and import as files. - -### Everything is swappable - -Templates and roles are starting points. At intake and at any point mid-task, a human can swap a stage's vendor, model, prompt, or review profiles, and edit the task's frozen workflow (add, remove, or reorder stages). - -### Just-in-time fan-out - -Agents can construct workflows on the fly via `spawn_stages` and `collect`: - -- Spawned stages use the same stage definition format. -- Limits: maximum depth, maximum concurrent spawned stages, and per-task usage budget, all configurable. -- An optional human gate on spawning, configured per workflow. -- Spawned stages are visible in the task's UI tree with `origin: jit`. -- A just-in-time structure can be saved as a reusable workflow template. - -### Stage patterns - -The earlier "agent features" are expressed as stage patterns: - -1. **Cross-vendor review:** a review profile whose vendor differs from the implementer's. -2. **Merge resolution:** a stage triggered when merging the default branch into a task branch conflicts; its result goes to review. -3. **Fork-and-compare:** a fan-out stage (N forks with different vendors or prompts from one snapshot) followed by a judge stage that produces a comparison with visuals. -4. **Inbox triage:** an agent answers questions resolvable from the repo or docs and escalates the rest with its reasoning attached. Tune on real inbox data. - -Build them in that order. - -### Plan artifact - -Standard schema: - -- goal -- approach -- steps -- acceptance criteria -- risks -- open questions - -Rules: - -- Versioned. Humans edit through the inbox; agents propose edits, which go to the inbox for approval. -- Stored on the server and attached to merges via git notes. Not committed to the repo. -- Build agents state every departure from the plan in their turn summaries. -- Eval stages report pass or fail per acceptance criterion. -- The plan-conformance review profile compares the diff against the plan. - -### Task intake - -1. Pick a workflow. -2. Fill its inputs: a brief, attachments, linked GitHub issues, handoff bundles from other tasks. -3. Optionally override vendors, models, prompts, or review profiles per stage. - ---- - -## Handoff bundles - -Produced by `export_context(purpose)`: - -- goal -- decisions made and why -- current state -- dead ends tried -- open questions -- relevant files - -Used for: - -- cross-vendor forks (the forked agent receives exactly what it needs), -- stage-to-stage handoff in workflows, -- the durable record of a task. - ---- - -## Git mechanics - -### Worktrees - -- One worktree and one branch per task, created from the project's default branch. -- Per-project setup config: setup script (dependency install, env file copying) and port allocation so parallel dev servers don't collide. -- The repo's original checkout is used only by the server, as the integration checkout for merges. - -### Diffs and stats (never touching the real index) - -Compute "as if everything were staged" without forcing staging: - -``` -GIT_INDEX_FILE=$tmp git read-tree HEAD -GIT_INDEX_FILE=$tmp git add -A # respects .gitignore, includes untracked -GIT_INDEX_FILE=$tmp git write-tree # → tree sha -``` - -Diff and stats are computed between the resulting tree and the merge-base with the default branch. - -### Snapshots - -- Built with the same temp-index technique, then `git commit-tree` on the resulting tree. -- Stored under hidden refs: `refs/byre/tasks//snap/`. Git deduplicates blobs, so frequent snapshots are cheap. -- A snapshot pairs the code commit with the conversation position (`event_seq`). -- Triggers: after every tool call (PostToolUse hook where available; shell commands can change files, so file-editing tools alone are not enough), at turn end, on `ask_human`, and on a timer as a backstop. Skip if the tree sha is unchanged. -- Retention: keep everything until task completion. - -### Scrubbing and forking - -- Timeline UI over a task's snapshots, showing the diff at each point alongside the transcript up to that event. -- Fork: a new worktree from a snapshot commit plus a new AgentSession. - - Same vendor: native session fork/resume. - - Different vendor: a handoff bundle from `export_context`. The UI labels it as a handoff, not a true fork. - -### Merge cycle - -A task can go through many merge cycles before completion. Merges happen only at turn boundaries; partially done work is not merged. Each cycle: - -1. Wait for the task's implementer to reach a turn boundary, then pause it. -2. In the task worktree, merge the default branch into the task branch. The merge-resolution stage resolves conflicts; review runs on the result. -3. Human confirms. In the integration checkout, run `git merge --squash ` and commit: - - Author: the human who confirmed the merge. - - Co-author trailers: other humans who participated in the task since the last merge cycle (resolved inbox items, messaged agents, triggered forks). - - No agent attribution. - - Message: the task's merge title, which starts as the task title and which the agent updates with `set_merge_title` as the work evolves; merging the default branch in asks it to check the title. -4. Attach a git note to the squash commit (see "History"). -5. Push the default branch and the notes ref. If rejected because the remote moved, fetch and repeat from step 2. -6. Reset the task branch to the new default-branch head. Required because squash commits make agent commits non-ancestors of the default branch; without the reset, later cycles accumulate spurious conflicts. Pre-squash history (the per-turn commits) remains available via snapshot refs. -7. Tell the agent explicitly that its branch history was squashed and reset, so it doesn't try to repair history. Then resume it. Files on disk are unchanged by the reset. - -### Task completion - -An explicit human action, as one of two buttons: **Merge** squashes the task onto the default branch and then removes it; **Discard** removes it without merging, after a confirm that states the commits and changed files that will be lost. Either way the worktree, the task branch, and the task's snapshot refs are removed. Transcripts, artifacts, reviews, and inbox history remain archived in SQLite. Nothing deletes a task branch without one of these two buttons. - ---- - -## History - -- On each squash merge, attach a git note under `refs/notes/byre` containing: the plan, the handoff bundle, review summaries, eval results, and resolved inbox decisions. Full transcripts are referenced by task ID. -- Notes don't push or fetch by default; the merge cycle pushes the notes ref explicitly, and setup configures fetching it. -- Archived tasks are searchable across transcripts, artifacts, and decisions. - -### Issues - -- Issue tracker integration is pluggable; GitHub Issues first. -- Tasks link to issues at intake. -- On merge, post or update a summary comment on linked issues. - ---- - -## Reviews - -- Reviews are performed by a separate agent session, never the implementer grading itself. By default the reviewer is a different vendor from the implementer. -- Every review targets a specific snapshot and is cached by tree sha. When the task's tree moves on, existing reviews are marked stale. -- Review types are named **review profiles** (security, performance, privacy, visual UX, plan conformance, and so on), each with a prompt, vendor, model, output schema, and capture config. Stages reference profiles by name. -- Triggers: - - On `ask_human`: the inbox item appears immediately; the review attaches when it completes. If the item is resolved first, the review still attaches to its history. - - Before merge. - - On demand. - - Periodic: on whichever comes first of elapsed time or diff size, with per-project overrides. Debounced to turn boundaries or a quiet period so half-applied edits are not reviewed. - -### Review output - -Structured, leaning visual rather than quoting code: - -- Summary. -- Highlights, each with a category, severity, and anchors to files or lines so the UI can jump to them. -- Visual attachments: - - Mermaid diagrams for changed data flow, call graphs, state machines, and schemas. - - Screenshots or recordings of the running result. Per-project config declares how to run and capture: Playwright MCP for web projects; `xcrun simctl io` screenshot/recordVideo for iOS simulator projects. - - Before/after pairs from the base ref and the current snapshot where possible. - -### Change view - -In increasing order of how much the UI encourages their use: - -1. File diffs -2. Diff stats -3. Agent-generated summary -4. Agent highlights with visual explanations - ---- - -## Inbox - -### Views and priority - -- One underlying query with global, per-project, and per-task views. -- Sources: `ask_human` calls, reports, completed reviews, gate approvals, rate-limit states, sessions that went idle or errored. -- Grouped by task, tasks with a blocked item (an agent is idle waiting on it) first, then by project; within a task, items are in time order. -- Everyone sees every item. Resolutions record who resolved them and are broadcast to all clients over SSE. - -### Response types - -- **Pick choices**: one for a pick-one question, any number for a pick-any one, chosen where they appear in the context. -- **Other**: the only text field, for an answer outside the options, a question back, or new instructions. If it asks the agent something, the agent answers through a follow-up `ask_human` with the same `thread_id`. -- Reports are FYI and take only an OK. - -Responses can carry attachments (pasted images and sketches, file and line references, links to tasks or snapshots, URLs). When an agent asks several questions at once, they are answered as one form with one submit. - ---- - -## Other features - -### Previews - -- Web: the server supervises a per-task dev server and exposes it over Tailscale, preferably as per-task ports through `tailscale serve` (path-prefix proxying breaks apps that use absolute paths). -- iOS: on-demand simulator screenshots and recordings attached to the task; Screen Sharing over Tailscale as the manual fallback. - -### Terminals - -PTYs via `github.com/creack/pty`, rendered with xterm.js, one WebSocket each. Scoped to a task's worktree by default. - -### File browser - -Read-only, scoped to project and worktree roots. - -### UI - -- Two panes, always side by side at exactly half the width each, under one top navbar. Each pane has tabs and can show any view; new views (diff, files, terminal, preview) become tabs, never columns. `AGENTS.md` holds the binding layout and look rules. -- Fast task switching: a ⌘K switcher in the navbar, plus a Tasks view. -- Frameworkless: TypeScript compiled file-by-file to ES modules, no bundler. -- Atkinson Hyperlegible Mono throughout, self-hosted; high-contrast text on a quiet palette. - ---- - -## Known hazards - -Issues identified in review that implementation must account for: - -- **Shared `.git` across worktrees.** Permissive agents can delete snapshot refs, run `git gc` or `git worktree prune`, check out other branches, or push. Mitigate with instructions, a pre-push hook on the shared repo that blocks pushes not made by the server, and periodic verification that snapshot refs survive. -- **Snapshot cost.** `git add -A` on every tool call is slow in large repos, and non-ignored build output bloats the object store. Nothing is garbage-collectable until task completion. -- **Shared machine resources.** Parallel Xcode builds compete for CPU; per-worktree DerivedData costs disk and cold builds; iOS simulators are shared between tasks and review agents and need allocation or locking. -- **Visual review reliability.** Capturing meaningful screenshots requires building, seeding data, and navigating to the affected screen. Expect flakiness; noisy reviews train users to ignore them. -- **Squash-and-reset under a running agent.** Agents may notice their commits disappearing and try to repair history; step 7 of the merge cycle addresses this and needs testing per vendor. -- **Event log growth.** Stream-json is verbose and tool outputs are large. SSE resume and scrubbing need efficient queries; consider separating large payloads into blobs. -- **Migration numbering across branches.** Migrations are tracked by position (`PRAGMA user_version`). Each task branch appends its own, and byre is deployed from task branches, so two branches can claim the same number: the database records it as applied and the other branch's migration silently never runs. Fix: track applied migrations by name in a table. Before switching, make every existing data migration safe to run twice, since one recorded only by number would run again under its name. - - **Status: fixed.** Migrations are named and tracked in a `migrations` table (see `docs/operations.md`, "Data"). - ---- - -## Build sequence - -### Spike (first) - -**Status: done.** `internal/claude` is the client; `docs/claude-protocol.md` records the protocol; `internal/claude/session_test.go` exercises each capability against the real CLI and records transcripts into `internal/claude/testdata/transcripts/` (gitignored, local to each checkout), with the account email scrubbed. Fork is wired in but untested. - -A Go client for the Claude Code CLI's stream-json control protocol that can: - -- Start a session, stream events, send a message. -- Interrupt and resume by session ID. -- Register a Stop hook and a PostToolUse hook. -- Launch with co-author attribution disabled and `GIT_AUTHOR_*` environment variables set. -- Attach an MCP server. - -Record transcripts from the spike as the seed of the contract test suite. - -### Milestones - -- **M0 — Skeleton.** launchd service, tailscale serve auth, SQLite schema, OpenAPI spec, projects, tasks, worktree create/delete, event log, SSE stream with resume, embedded SPA shell, basic server observability. - - **Status: done**, and running as a service on the Mac Studio. Observability covers queue state, vendor rate-limit status, agent process liveness, stuck and zombie detection, and adapter and protocol-parse errors, through `GET /api/admin/status` and the SPA's Admin view; per-task snapshot counts and disk usage are not done. -- **M1 — One agent end to end (Claude).** Sessions, streaming, messaging, the interface coverage for Claude, the `ask_human` MCP tool, turn summaries, inbox with all views and response types, web push notifications, restart-and-resume, concurrency caps. - - **Done:** sessions, streaming, messaging, interrupt; `ask_human` with validation; each turn's final message filed to the inbox as its summary; inbox with global, project, and task views and every response type, answered as one batch and delivered to the agent as one message; restart-and-resume; global and per-vendor caps with queueing; rate limits as their own inbox state; the web UI (two panes, task switcher, transcript, inbox) with Markdown rendering; the session instructions from "Session configuration", given as an appended system prompt and a per-turn reminder; per-turn commits by byre; bouncing questions asked in plain prose; web push notifications through a service worker, with per-user preferences (blocking questions by default, other kinds opt-in) set in a Settings tab, bursts collapsed into one notification, and a click opening the task. Compaction is done, as a handoff into a fresh session; model switching is done, per message; image input is done, pasted or dropped into the composer and stored as blobs. - - **Later:** subagent views and Mermaid rendering. -- **M2 — Seeing the work.** Temp-index diffs and stats, snapshots, timeline scrubbing, terminals, file browser, previews. - - **Done:** temp-index diffs and stats, with a Changes view; snapshots on every tool call, turn end, `ask_human` and a timer while a turn runs, kept as hidden refs until the task is merged or discarded, listed through the API. - - **Not done:** timeline scrubbing, terminals, file browser, previews. -- **M3 — Second vendor and review.** Codex adapter with the same interface coverage, review profiles, review triggers, visual review output, cross-vendor review. -- **M4 — Merging and history.** Full merge cycle with squash, authorship and co-author trailers, drafted commit messages, merge-resolution stage, git notes, task completion and archive, archive search, GitHub Issues integration. - - **Done:** Merge and Discard replace "Complete task". Merge squashes the worktree, uncommitted files included, into one commit on the default branch, authored by the merging user, pushes it to the project's `origin`, and then fast-forwards the project checkout; it refuses while a turn is running. Merge first has the agent merge the default branch in (also available alone as "Sync from main"), then squashes when that turn ends. Merge fetches the remote's default branch into the checkout before the merge-in; a refused or failed push is filed as an error and the task stays active for another Merge. The squash commit's title is the task's merge title: the task title until the agent sets another with the `set_merge_title` MCP tool, which the merge-in prompt asks it to do when the current title no longer describes the branch. The commit carries a `Co-authored-by` trailer for every other human with a message bubble in the task's transcript (a message to its agent, or an inbox answer delivered under their name; dismissals don't count), derived from the task's `user.message` events rather than a `Participation` table; the Merge confirm lists them. - - **Not done:** co-author trailers for triggering forks, human editing of the drafted message before confirming, merge-resolution stage, git notes (and pushing the notes ref), repeated merge cycles, archive search, GitHub Issues. -- **M5 — Workflows.** Workflow definitions and storage, stages, gates, bounded loops, plan artifact, eval stages, task intake, mid-task swapping. -- **M6 — Fan-out.** `export_context` and handoff bundles, same-vendor forks, cross-vendor handoffs, fork-and-compare, just-in-time fan-out with limits. -- **M7 — Inbox triage.** - ---- - -## Open items - -- Verify Codex app-server support for forking threads. -- Confirm `tailscale serve` behavior for exposing per-task preview ports. -- Terminal persistence across server restarts: accept loss, or back terminals with tmux? -- Format of per-project setup config (setup script, port allocation, run/capture config for reviews). -- Simulator allocation strategy for parallel tasks and review agents. -- Periodic review thresholds (defaults for time and diff size). -- Default limits for just-in-time fan-out (depth, concurrency, budget). -- Task navigation: keep both the ⌘K switcher and the Tasks view, or only one. -- Interface coverage still undecided: todo-list rendering and `@`-file mentions. diff --git a/internal/agents/guidance.go b/internal/agents/guidance.go index eb2b213..c2a84cd 100644 --- a/internal/agents/guidance.go +++ b/internal/agents/guidance.go @@ -3,9 +3,12 @@ package agents import ( "context" "encoding/json" + "fmt" "regexp" + "g.fc.run/misc/byre/internal/api" "g.fc.run/misc/byre/internal/claude" + "g.fc.run/misc/byre/internal/todo" ) const guidance = `You are running inside byre. The human reads your work in byre's web UI, not a terminal. @@ -55,11 +58,21 @@ func (m *Manager) bounceProseQuestion(l *live) claude.HookFunc { } } -func remindGuidance(ctx context.Context, input json.RawMessage) (map[string]any, error) { - return map[string]any{ - "hookSpecificOutput": map[string]any{ - "hookEventName": "UserPromptSubmit", - "additionalContext": guidance, - }, - }, nil +func taskGuidance(task api.Task) string { + if task.TodoItem == nil { + return guidance + } + return guidance + fmt.Sprintf("\n- This task was started from the item %q in %s at the repo root. When the work is done, remove that item from %s in this worktree, so the removal lands in the same merge as the work.", + *task.TodoItem, todo.File, todo.File) +} + +func remindGuidance(text string) claude.HookFunc { + return func(ctx context.Context, input json.RawMessage) (map[string]any, error) { + return map[string]any{ + "hookSpecificOutput": map[string]any{ + "hookEventName": "UserPromptSubmit", + "additionalContext": text, + }, + }, nil + } } diff --git a/internal/agents/manager.go b/internal/agents/manager.go index 0fc60b3..6de37bf 100644 --- a/internal/agents/manager.go +++ b/internal/agents/manager.go @@ -559,15 +559,16 @@ func (m *Manager) ensureLive(ctx context.Context, sess api.AgentSession, task ap projectID: task.ProjectId, } + g := taskGuidance(task) opts := claude.Options{ Cwd: task.WorktreePath, Model: sess.Model, GitName: creator.GitName, GitEmail: creator.GitEmail, - Guidance: guidance, + Guidance: g, MCPServers: []*mcp.Server{{Name: "byre", Version: "0.0.0", Tools: []mcp.Tool{m.askTool(l), m.cancelQuestionTool(l), m.createTaskTool(l), m.setMergeTitleTool(l)}}}, Hooks: map[string][]claude.HookMatcher{ - "UserPromptSubmit": {{Func: remindGuidance}}, + "UserPromptSubmit": {{Func: remindGuidance(g)}}, "Stop": {{Func: m.bounceProseQuestion(l)}}, "PostToolUse": {{Func: m.snapshotAfterTool(l)}}, }, diff --git a/internal/agents/manager_test.go b/internal/agents/manager_test.go index 5d50d83..b96f873 100644 --- a/internal/agents/manager_test.go +++ b/internal/agents/manager_test.go @@ -2,6 +2,7 @@ package agents_test import ( "context" + "errors" "fmt" "os" "os/exec" @@ -873,6 +874,68 @@ func TestCreateTaskTool(t *testing.T) { } } +func TestStartTodo(t *testing.T) { + t.Parallel() + e := newEnv(t) + m := e.manager() + + writeTestFile(t, filepath.Join(e.repo, "TODO.md"), "# Todo\n\n- Create hello.txt\n It holds the single line `hi`.\n- Leave this one alone\n") + gitOut(t, e.repo, "add", "TODO.md") + gitOut(t, e.repo, "commit", "--quiet", "--message", "add todo") + + _, err := m.StartTodo(e.ctx, e.project, e.user, "No such item", testModel) + if !errors.Is(err, store.ErrNotFound) { + t.Fatalf("start unknown item: %v", err) + } + + task, err := m.StartTodo(e.ctx, e.project, e.user, "Create hello.txt", testModel) + if err != nil { + t.Fatalf("start todo: %v", err) + } + if task.TodoItem == nil || *task.TodoItem != "Create hello.txt" || task.Title != "Create hello.txt" { + t.Fatalf("todo task %+v", task) + } + + _, err = m.StartTodo(e.ctx, e.project, e.user, "Create hello.txt", testModel) + if !errors.Is(err, agents.ErrConflict) { + t.Fatalf("second start of the same item: %v", err) + } + + events := e.waitFor("todo turn end", func(ev api.Event) bool { + return ev.Kind == "turn.ended" && ev.TaskId != nil && *ev.TaskId == task.Id + }) + for _, ev := range events { + if ev.Kind == "user.message" && ev.TaskId != nil && *ev.TaskId == task.Id { + text, _ := ev.Payload["text"].(string) + if !strings.Contains(text, "- Create hello.txt\n It holds the single line `hi`.") || !strings.Contains(text, "remove this item from TODO.md") { + t.Fatalf("first prompt %q", text) + } + } + } + + stored, err := e.store.GetTask(e.ctx, task.Id) + if err != nil || stored.TodoItem == nil || *stored.TodoItem != "Create hello.txt" { + t.Fatalf("stored task %+v %v", stored, err) + } + + todoAfter, err := os.ReadFile(filepath.Join(task.WorktreePath, "TODO.md")) + if err != nil { + t.Fatalf("read worktree TODO.md: %v", err) + } + t.Logf("TODO.md after the turn:\n%s", todoAfter) + if strings.Contains(string(todoAfter), "Create hello.txt") || !strings.Contains(string(todoAfter), "Leave this one alone") { + t.Fatalf("agent didn't remove exactly its item from TODO.md") + } +} + +func writeTestFile(t *testing.T, path, content string) { + t.Helper() + err := os.WriteFile(path, []byte(content), 0o644) + if err != nil { + t.Fatalf("write %s: %v", path, err) + } +} + func TestQuestionReachesInbox(t *testing.T) { t.Parallel() e := newEnv(t) diff --git a/internal/agents/tasks.go b/internal/agents/tasks.go index 516116d..039417c 100644 --- a/internal/agents/tasks.go +++ b/internal/agents/tasks.go @@ -13,9 +13,58 @@ import ( "g.fc.run/misc/byre/internal/git" "g.fc.run/misc/byre/internal/mcp" "g.fc.run/misc/byre/internal/store" + "g.fc.run/misc/byre/internal/todo" ) func (m *Manager) CreateTask(ctx context.Context, project api.Project, title, createdBy, base string) (api.Task, error) { + return m.createTask(ctx, project, title, createdBy, base, nil) +} + +func (m *Manager) StartTodo(ctx context.Context, project api.Project, creator api.User, title, model string) (api.Task, error) { + if creator.GitName == "" || creator.GitEmail == "" { + return api.Task{}, ErrNoGitIdentity + } + + src, found, err := git.ReadFile(project.RepoPath, project.DefaultBranch, todo.File) + if err != nil { + return api.Task{}, err + } + if !found { + return api.Task{}, fmt.Errorf("%w: %s has no %s", store.ErrNotFound, project.DefaultBranch, todo.File) + } + item, found := todo.Find(todo.Parse(src), title) + if !found { + return api.Task{}, fmt.Errorf("%w: %s on %s has no item %q", store.ErrNotFound, todo.File, project.DefaultBranch, title) + } + + tasks, err := m.store.ListTasks(ctx, project.Id) + if err != nil { + return api.Task{}, err + } + for _, t := range tasks { + if t.Status == api.TaskStatusActive && t.TodoItem != nil && *t.TodoItem == title { + return api.Task{}, fmt.Errorf("%w: task %s is already working on %q", ErrConflict, t.Id, title) + } + } + + task, err := m.createTask(ctx, project, item.Title, creator.Login, project.DefaultBranch, &item.Title) + if err != nil { + return api.Task{}, err + } + + _, err = m.create(ctx, task, creator, todoPrompt(item), model, creator.Login, nil) + if err != nil { + return api.Task{}, fmt.Errorf("task %s created, but its agent did not start: %w", task.Id, err) + } + return task, nil +} + +func todoPrompt(item api.TodoItem) string { + return fmt.Sprintf("Work on this item from %[1]s at the repo root:\n\n%[2]s\n\nWhen the work is done, remove this item from %[1]s in this worktree, so the removal lands in the same merge as the work.", + todo.File, todo.Markdown(item)) +} + +func (m *Manager) createTask(ctx context.Context, project api.Project, title, createdBy, base string, todoItem *string) (api.Task, error) { id := store.NewID() t := api.Task{ Id: id, @@ -27,6 +76,7 @@ func (m *Manager) CreateTask(ctx context.Context, project api.Project, title, cr Status: api.TaskStatusActive, CreatedBy: createdBy, CreatedAt: time.Now().UTC(), + TodoItem: todoItem, } var err error diff --git a/internal/api/api.gen.go b/internal/api/api.gen.go index 89d66d0..d8c313a 100644 --- a/internal/api/api.gen.go +++ b/internal/api/api.gen.go @@ -675,11 +675,14 @@ type Task struct { MergeCommit *string `json:"merge_commit,omitempty"` // MergeTitle The title of the squash commit Merge makes: the task title until the agent sets another with set_merge_title. - MergeTitle string `json:"merge_title"` - ProjectId string `json:"project_id"` - Status TaskStatus `json:"status"` - Title string `json:"title"` - WorktreePath string `json:"worktree_path"` + MergeTitle string `json:"merge_title"` + ProjectId string `json:"project_id"` + Status TaskStatus `json:"status"` + Title string `json:"title"` + + // TodoItem The title of the TODO.md item the task was started from; absent for other tasks. + TodoItem *string `json:"todo_item,omitempty"` + WorktreePath string `json:"worktree_path"` } // TaskStatus defines model for Task.Status. @@ -700,6 +703,33 @@ type TaskCreate struct { Title string `json:"title"` } +// Todo defines model for Todo. +type Todo struct { + // Exists Whether the default branch has a TODO.md at its root. + Exists bool `json:"exists"` + Items []TodoItem `json:"items"` +} + +// TodoItem defines model for TodoItem. +type TodoItem struct { + // Body The item's further lines + Body string `json:"body"` + + // Section The text of the nearest heading above the item; empty when there is none. + Section string `json:"section"` + + // Title The item's first line, without its list marker: the item's identity. + Title string `json:"title"` +} + +// TodoStart defines model for TodoStart. +type TodoStart struct { + Model *string `json:"model,omitempty"` + + // Title The title of the item to start. + Title string `json:"title"` +} + // TurnRef defines model for TurnRef. type TurnRef struct { SessionId string `json:"session_id"` @@ -813,6 +843,9 @@ type CreateProjectJSONRequestBody = ProjectCreate // CreateTaskJSONRequestBody defines body for CreateTask for application/json ContentType. type CreateTaskJSONRequestBody = TaskCreate +// StartTodoItemJSONRequestBody defines body for StartTodoItem for application/json ContentType. +type StartTodoItemJSONRequestBody = TodoStart + // SendMessageJSONRequestBody defines body for SendMessage for application/json ContentType. type SendMessageJSONRequestBody = MessageCreate @@ -873,6 +906,12 @@ type ServerInterface interface { // (POST /api/projects/{projectId}/tasks) CreateTask(w http.ResponseWriter, r *http.Request, projectId string) + // (GET /api/projects/{projectId}/todo) + GetTodo(w http.ResponseWriter, r *http.Request, projectId string) + + // (POST /api/projects/{projectId}/todo/tasks) + StartTodoItem(w http.ResponseWriter, r *http.Request, projectId string) + // (GET /api/push/key) GetPushKey(w http.ResponseWriter, r *http.Request) @@ -1349,6 +1388,58 @@ func (siw *ServerInterfaceWrapper) CreateTask(w http.ResponseWriter, r *http.Req handler.ServeHTTP(w, r) } +// GetTodo operation middleware +func (siw *ServerInterfaceWrapper) GetTodo(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "projectId" ------------- + var projectId string + + err = runtime.BindStyledParameterWithOptions("simple", "projectId", r.PathValue("projectId"), &projectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "", ValueIsUnescaped: true}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "projectId", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetTodo(w, r, projectId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// StartTodoItem operation middleware +func (siw *ServerInterfaceWrapper) StartTodoItem(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "projectId" ------------- + var projectId string + + err = runtime.BindStyledParameterWithOptions("simple", "projectId", r.PathValue("projectId"), &projectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "", ValueIsUnescaped: true}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "projectId", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.StartTodoItem(w, r, projectId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + // GetPushKey operation middleware func (siw *ServerInterfaceWrapper) GetPushKey(w http.ResponseWriter, r *http.Request) { @@ -2036,6 +2127,8 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/api/projects/{projectId}", wrapper.GetProject) m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/api/projects/{projectId}/tasks", wrapper.ListTasks) m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/api/projects/{projectId}/tasks", wrapper.CreateTask) + m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/api/projects/{projectId}/todo", wrapper.GetTodo) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/api/projects/{projectId}/todo/tasks", wrapper.StartTodoItem) m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/api/tasks/{taskId}", wrapper.GetTask) m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/api/tasks/{taskId}/unmerged", wrapper.GetUnmerged) m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/api/tasks/{taskId}/co-authors", wrapper.GetCoAuthors) @@ -2068,113 +2161,119 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H // const string: with thousands of chunks the chained `+` fold is several // times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - "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", - "3hf0mIcswhpjBy3883CdzuRfNqN1f//fAQAA//8=", + "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", } // decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, diff --git a/internal/git/git.go b/internal/git/git.go index 35a0e32..5a43351 100644 --- a/internal/git/git.go +++ b/internal/git/git.go @@ -236,6 +236,18 @@ func Head(dir string) (string, error) { return run(dir, "rev-parse", "HEAD") } +func ReadFile(repo, rev, path string) (string, bool, error) { + _, _, code, err := runCode(repo, nil, "cat-file", "-e", rev+":"+path) + if err != nil { + return "", false, err + } + if code != 0 { + return "", false, nil + } + out, err := run(repo, "cat-file", "blob", rev+":"+path) + return out, true, err +} + func CommitAll(dir, message, name, email string) (string, error) { status, err := run(dir, "status", "--porcelain", "--untracked-files=all") if err != nil { diff --git a/internal/server/server.go b/internal/server/server.go index 62308b9..8d6de54 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -20,6 +20,7 @@ import ( "g.fc.run/misc/byre/internal/git" "g.fc.run/misc/byre/internal/push" "g.fc.run/misc/byre/internal/store" + "g.fc.run/misc/byre/internal/todo" ) type Server struct { @@ -272,6 +273,57 @@ func (s *Server) CreateTask(w http.ResponseWriter, r *http.Request, projectID st writeJSON(w, http.StatusCreated, t) } +func (s *Server) GetTodo(w http.ResponseWriter, r *http.Request, projectID string) { + p, err := s.store.GetProject(r.Context(), projectID) + if err != nil { + writeStoreError(w, err) + return + } + + src, found, err := git.ReadFile(p.RepoPath, p.DefaultBranch, todo.File) + if err != nil { + writeError(w, http.StatusInternalServerError, err) + return + } + writeJSON(w, http.StatusOK, api.Todo{Exists: found, Items: todo.Parse(src)}) +} + +func (s *Server) StartTodoItem(w http.ResponseWriter, r *http.Request, projectID string) { + req := api.TodoStart{} + if !readJSON(w, r, &req) { + return + } + + if strings.TrimSpace(req.Title) == "" { + writeError(w, http.StatusBadRequest, errors.New("title is required")) + return + } + + p, err := s.store.GetProject(r.Context(), projectID) + if err != nil { + writeStoreError(w, err) + return + } + + u, err := s.store.GetUser(r.Context(), actor(r)) + if err != nil { + writeStoreError(w, err) + return + } + + model := "" + if req.Model != nil { + model = *req.Model + } + + t, err := s.agents.StartTodo(r.Context(), p, u, req.Title, model) + if err != nil { + writeAgentError(w, err) + return + } + writeJSON(w, http.StatusCreated, t) +} + func (s *Server) GetTask(w http.ResponseWriter, r *http.Request, taskID string) { t, err := s.store.GetTask(r.Context(), taskID) if err != nil { diff --git a/internal/store/store.go b/internal/store/store.go index 3a059ae..ec3a9eb 100644 --- a/internal/store/store.go +++ b/internal/store/store.go @@ -206,6 +206,8 @@ UPDATE inbox_items SET payload = json_set(json_remove(payload, '$.recommended_op WHERE kind = 'question' AND json_type(payload, '$.recommended_option') IS NOT NULL; `}, {"unsnooze-inbox-items", ` UPDATE inbox_items SET snoozed_until = NULL WHERE snoozed_until IS NOT NULL; +`}, {"add-task-todo-item", ` +ALTER TABLE tasks ADD COLUMN todo_item TEXT NOT NULL DEFAULT ''; `}} type Store struct { @@ -426,11 +428,15 @@ func (s *Store) GetProject(ctx context.Context, id string) (api.Project, error) } func (s *Store) CreateTask(ctx context.Context, t api.Task) error { + todoItem := "" + if t.TodoItem != nil { + todoItem = *t.TodoItem + } return s.write(ctx, func(tx *sql.Tx, emit emitFunc) error { _, err := tx.ExecContext(ctx, ` - INSERT INTO tasks (id, project_id, title, branch, worktree_path, base_ref, status, created_by, created_at) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) - `, t.Id, t.ProjectId, t.Title, t.Branch, t.WorktreePath, t.BaseRef, string(t.Status), t.CreatedBy, formatTime(t.CreatedAt)) + INSERT INTO tasks (id, project_id, title, branch, worktree_path, base_ref, status, created_by, created_at, todo_item) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + `, t.Id, t.ProjectId, t.Title, t.Branch, t.WorktreePath, t.BaseRef, string(t.Status), t.CreatedBy, formatTime(t.CreatedAt), todoItem) if err != nil { return err } @@ -801,7 +807,7 @@ func (s *Store) write(ctx context.Context, fn func(tx *sql.Tx, emit emitFunc) er const projectColumns = `id, name, repo_path, default_branch, remote, created_by, created_at` -const taskColumns = `id, project_id, title, merge_title, branch, worktree_path, base_ref, status, created_by, created_at, closed_at, merge_commit` +const taskColumns = `id, project_id, title, merge_title, branch, worktree_path, base_ref, status, created_by, created_at, closed_at, merge_commit, todo_item` const sessionColumns = `id, task_id, vendor, model, vendor_session_id, state, role, created_by, created_at` @@ -826,7 +832,8 @@ func scanTask(row scanner) (api.Task, error) { createdAt := "" closedAt := sql.NullString{} mergeCommit := "" - err := row.Scan(&t.Id, &t.ProjectId, &t.Title, &t.MergeTitle, &t.Branch, &t.WorktreePath, &t.BaseRef, &status, &t.CreatedBy, &createdAt, &closedAt, &mergeCommit) + todoItem := "" + err := row.Scan(&t.Id, &t.ProjectId, &t.Title, &t.MergeTitle, &t.Branch, &t.WorktreePath, &t.BaseRef, &status, &t.CreatedBy, &createdAt, &closedAt, &mergeCommit, &todoItem) if err != nil { return t, err } @@ -848,6 +855,9 @@ func scanTask(row scanner) (api.Task, error) { if mergeCommit != "" { t.MergeCommit = &mergeCommit } + if todoItem != "" { + t.TodoItem = &todoItem + } return t, nil } diff --git a/internal/todo/todo.go b/internal/todo/todo.go new file mode 100644 index 0000000..4c2b960 --- /dev/null +++ b/internal/todo/todo.go @@ -0,0 +1,142 @@ +package todo + +import ( + "regexp" + "strings" + + "g.fc.run/misc/byre/internal/api" +) + +const File = "TODO.md" + +var ( + heading = regexp.MustCompile(`^#{1,6}\s+(.*?)\s*#*\s*$`) + listItem = regexp.MustCompile(`^(?:[-*+]|\d+[.)])\s+(.*)$`) + checkbox = regexp.MustCompile(`^\[([ xX])\]\s+`) + fence = regexp.MustCompile("^\\s*(```|~~~)") +) + +func Parse(src string) []api.TodoItem { + items := []api.TodoItem{} + section := "" + var cur *api.TodoItem + body := []string{} + inFence := false + blank := false + + finish := func() { + if cur == nil { + return + } + cur.Body = dedent(body) + items = append(items, *cur) + cur = nil + body = []string{} + } + + for _, line := range strings.Split(strings.ReplaceAll(src, "\r\n", "\n"), "\n") { + if fence.MatchString(line) { + inFence = !inFence + if cur != nil { + body = append(body, line) + } + continue + } + if inFence { + if cur != nil { + body = append(body, line) + } + continue + } + + if strings.TrimSpace(line) == "" { + blank = true + if cur != nil { + body = append(body, "") + } + continue + } + indented := line[0] == ' ' || line[0] == '\t' + afterBlank := blank + blank = false + + if m := heading.FindStringSubmatch(line); m != nil { + finish() + section = m[1] + continue + } + if m := listItem.FindStringSubmatch(line); m != nil { + finish() + title := m[1] + box := checkbox.FindStringSubmatch(title) + if box != nil && box[1] != " " { + continue + } + title = strings.TrimSpace(checkbox.ReplaceAllString(title, "")) + cur = &api.TodoItem{Title: title, Section: section} + continue + } + if cur == nil { + continue + } + if !indented && afterBlank { + finish() + continue + } + body = append(body, line) + } + finish() + + return items +} + +func Find(items []api.TodoItem, title string) (api.TodoItem, bool) { + for _, item := range items { + if item.Title == title { + return item, true + } + } + return api.TodoItem{}, false +} + +func Markdown(item api.TodoItem) string { + if item.Body == "" { + return "- " + item.Title + } + lines := []string{"- " + item.Title} + for _, line := range strings.Split(item.Body, "\n") { + if line == "" { + lines = append(lines, "") + continue + } + lines = append(lines, " "+line) + } + return strings.Join(lines, "\n") +} + +func dedent(lines []string) string { + for len(lines) > 0 && lines[len(lines)-1] == "" { + lines = lines[:len(lines)-1] + } + + indent := -1 + for _, line := range lines { + if line == "" { + continue + } + n := len(line) - len(strings.TrimLeft(line, " \t")) + if indent < 0 || n < indent { + indent = n + } + } + + out := []string{} + for _, line := range lines { + if line == "" { + out = append(out, "") + continue + } + out = append(out, line[indent:]) + } + return strings.Join(out, "\n") +} diff --git a/internal/todo/todo_test.go b/internal/todo/todo_test.go new file mode 100644 index 0000000..34d654a --- /dev/null +++ b/internal/todo/todo_test.go @@ -0,0 +1,58 @@ +package todo_test + +import ( + "reflect" + "testing" + + "g.fc.run/misc/byre/internal/api" + "g.fc.run/misc/byre/internal/todo" +) + +func TestParse(t *testing.T) { + src := "# TODO\n\n" + + "Notes before the list are not items.\n\n" + + "- Public key pinning\n" + + " When libcurl4-openssl-dev >= 7.39.0, add support to the C client via the\n" + + " options struct for public key pinning.\n" + + "\n" + + " ```\n" + + " - not an item\n" + + " ```\n" + + "- [ ] Client ID rotation\n" + + " - JS client\n" + + " - C client\n" + + "- [x] Already done\n" + + " with a body\n" + + "\n" + + "## Web\n\n" + + "1. Double-click zoom in\n" + + "2. Pinch to zoom\n" + + "\n" + + "A trailing paragraph.\n" + + want := []api.TodoItem{ + {Title: "Public key pinning", Section: "TODO", Body: "When libcurl4-openssl-dev >= 7.39.0, add support to the C client via the\noptions struct for public key pinning.\n\n```\n- not an item\n```"}, + {Title: "Client ID rotation", Section: "TODO", Body: "- JS client\n- C client"}, + {Title: "Double-click zoom in", Section: "Web"}, + {Title: "Pinch to zoom", Section: "Web"}, + } + + got := todo.Parse(src) + if !reflect.DeepEqual(got, want) { + t.Fatalf("parse:\n got %#v\nwant %#v", got, want) + } + + item, ok := todo.Find(got, "Client ID rotation") + if !ok { + t.Fatalf("find: no item") + } + if md := todo.Markdown(item); md != "- Client ID rotation\n - JS client\n - C client" { + t.Fatalf("markdown: %q", md) + } +} + +func TestParseEmpty(t *testing.T) { + if got := todo.Parse(""); len(got) != 0 { + t.Fatalf("parse empty: %#v", got) + } +} diff --git a/web/dist/panes.js b/web/dist/panes.js index 611de14..6ff480b 100644 --- a/web/dist/panes.js +++ b/web/dist/panes.js @@ -5,15 +5,17 @@ import { mountInbox } from "./inbox.js"; import { mountSettings } from "./settings.js"; import { mountTranscript } from "./task.js"; import { mountTasks } from "./tasks.js"; +import { mountTodo } from "./todo.js"; const views = { transcript: { label: "Transcript", mount: mountTranscript }, changes: { label: "Changes", mount: (root) => mountChanges(root) }, tasks: { label: "Tasks", mount: mountTasks }, + todo: { label: "Todo", mount: mountTodo }, inbox: { label: "Inbox", mount: mountInbox }, admin: { label: "Admin", mount: mountAdmin }, settings: { label: "Settings", mount: mountSettings }, }; -const order = ["transcript", "changes", "tasks", "inbox", "admin", "settings"]; +const order = ["transcript", "changes", "tasks", "todo", "inbox", "admin", "settings"]; const panes = []; export function openTranscript() { if (panes.some((p) => p.current() === "transcript")) { diff --git a/web/dist/panes.js.map b/web/dist/panes.js.map index bc47ac1..d4bf874 100644 --- a/web/dist/panes.js.map +++ b/web/dist/panes.js.map @@ -1 +1 @@ -{"version":3,"file":"panes.js","sourceRoot":"","sources":["../src/panes.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"panes.js","sourceRoot":"","sources":["../src/panes.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/web/dist/task.js b/web/dist/task.js index 54fb212..d2ecccc 100644 --- a/web/dist/task.js +++ b/web/dist/task.js @@ -3,7 +3,7 @@ import { ago, errorText, h, replace, showAlert, showConfirm } from "./dom.js"; import { markdown } from "./markdown.js"; import { openChanges } from "./panes.js"; import { currentSession, findTask, onEach, pinSnapshot, state } from "./state.js"; -const models = ["claude-opus-5-5", "claude-sonnet-5-5", "claude-haiku-5-5", "claude-fable-5-1"]; +export const models = ["claude-opus-5-5", "claude-sonnet-5-5", "claude-haiku-5-5", "claude-fable-5-1"]; export function mountTranscript(root) { const head = h("header", { class: "task-header" }); const transcript = h("div", { class: "transcript" }); diff --git a/web/dist/task.js.map b/web/dist/task.js.map index ce3da54..65fe3a3 100644 --- a/web/dist/task.js.map +++ b/web/dist/task.js.map @@ -1 +1 @@ -{"version":3,"file":"task.js","sourceRoot":"","sources":["../src/task.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"task.js","sourceRoot":"","sources":["../src/task.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/web/dist/todo.js b/web/dist/todo.js new file mode 100644 index 0000000..7eb45ff --- /dev/null +++ b/web/dist/todo.js @@ -0,0 +1,121 @@ +import { get, post } from "./api.js"; +import { errorText, h, replace, showAlert } from "./dom.js"; +import { markdown } from "./markdown.js"; +import { openTranscript } from "./panes.js"; +import { models } from "./task.js"; +import { currentSession, on, onEach, state } from "./state.js"; +const refreshKinds = new Set(["task.merged", "project.created"]); +export function mountTodo(root) { + const todos = new Map(); + const starting = new Set(); + let disposed = false; + const render = () => { + const scrollTop = root.querySelector(".todo-view")?.scrollTop ?? 0; + replace(root, h("div", { class: "todo-view" }, ...state.projects.map((p) => projectBlock(p, todos.get(p.id), starting, start)))); + root.querySelector(".todo-view").scrollTop = scrollTop; + }; + const load = async (projectId) => { + try { + const todo = await get("/api/projects/{projectId}/todo", { path: { projectId } }); + todos.set(projectId, todo); + } + catch (err) { + todos.set(projectId, `Couldn't read TODO.md: ${errorText(err)}`); + } + if (!disposed) { + render(); + } + }; + const refresh = () => { + for (const p of state.projects) { + void load(p.id); + } + }; + const start = async (project, item) => { + const key = `${project.id}\n${item.title}`; + starting.add(key); + render(); + try { + const task = await post("/api/projects/{projectId}/todo/tasks", { path: { projectId: project.id }, body: { title: item.title, model: models[0] } }); + location.hash = `#/task/${task.id}`; + openTranscript(); + } + catch (err) { + void showAlert(errorText(err)); + } + starting.delete(key); + if (!disposed) { + render(); + } + }; + const offs = [ + on("event", (detail) => { + const ev = detail; + if (!refreshKinds.has(ev.kind)) { + return; + } + if (ev.project_id) { + void load(ev.project_id); + } + }), + on("connection", () => { + if (state.connected) { + refresh(); + } + }), + on("projects", refresh), + onEach(["tasks", "sessions", "selection"], render), + ]; + render(); + refresh(); + return () => { + disposed = true; + for (const off of offs) { + off(); + } + }; +} +function projectBlock(project, todo, starting, start) { + const head = h("h2", {}, project.name, " ", h("span", { class: "repo" }, `TODO.md on ${project.default_branch}`)); + if (todo === undefined) { + return h("section", { class: "project" }, head, h("p", { class: "empty-row" }, "Loading…")); + } + if (typeof todo === "string") { + return h("section", { class: "project" }, head, h("p", { class: "empty-row error-text" }, todo)); + } + if (!todo.exists) { + return h("section", { class: "project" }, head, h("p", { class: "empty-row" }, `No TODO.md on ${project.default_branch}.`)); + } + if (todo.items.length === 0) { + return h("section", { class: "project" }, head, h("p", { class: "empty-row" }, "TODO.md has no items.")); + } + const active = (state.tasks.get(project.id) ?? []).filter((t) => t.status === "active" && t.todo_item); + const children = []; + let section = ""; + let list; + for (const item of todo.items) { + if (!list || item.section !== section) { + section = item.section; + if (section) { + children.push(h("h3", { class: "todo-section" }, section)); + } + list = h("ul", { class: "todo-list" }); + children.push(list); + } + const task = active.find((t) => t.todo_item === item.title); + let action; + if (task) { + const sess = currentSession(task.id); + action = h("a", { class: "todo-task", href: `#/task/${task.id}`, onclick: openTranscript }, h("span", { class: `dot ${sess?.state ?? "none"}`, title: sess?.state ?? "no session" }), sess?.state ?? "no agent"); + } + else { + const busy = starting.has(`${project.id}\n${item.title}`); + const button = h("button", { disabled: busy }, busy ? "Starting…" : "Start"); + button.onclick = () => void start(project, item); + action = button; + } + list.append(h("li", { class: task && task.id === state.selectedTaskId ? "selected" : "" }, h("div", { class: "todo-head" }, h("span", { class: "todo-title" }, item.title), action), item.body && markdown(item.body, "md todo-body"))); + } + return h("section", { class: "project" }, head, ...children); +} +//# sourceMappingURL=todo.js.map \ No newline at end of file diff --git a/web/dist/todo.js.map b/web/dist/todo.js.map new file mode 100644 index 0000000..cf7cf9f --- /dev/null +++ b/web/dist/todo.js.map @@ -0,0 +1 @@ +{"version":3,"file":"todo.js","sourceRoot":"","sources":["../src/todo.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/web/src/api.gen.ts b/web/src/api.gen.ts index a8aad88..b86de2d 100644 --- a/web/src/api.gen.ts +++ b/web/src/api.gen.ts @@ -123,6 +123,44 @@ export interface paths { patch?: never; trace?: never; }; + "/api/projects/{projectId}/todo": { + parameters: { + query?: never; + header?: never; + path: { + projectId: string; + }; + cookie?: never; + }; + /** @description The items of TODO.md at the root of the project's default branch, in file order. */ + get: operations["getTodo"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/projects/{projectId}/todo/tasks": { + parameters: { + query?: never; + header?: never; + path: { + projectId: string; + }; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Creates a task for a TODO.md item, recording the item as its todo_item, and starts its agent with the item as the first message. Refused while another active task has the same item. */ + post: operations["startTodoItem"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/api/tasks/{taskId}": { parameters: { query?: never; @@ -603,6 +641,26 @@ export interface components { closed_at?: string; /** @description merged: the squash commit on the default branch; empty when there was nothing to merge. */ merge_commit?: string; + /** @description The title of the TODO.md item the task was started from; absent for other tasks. */ + todo_item?: string; + }; + Todo: { + /** @description Whether the default branch has a TODO.md at its root. */ + exists: boolean; + items: components["schemas"]["TodoItem"][]; + }; + TodoItem: { + /** @description The item's first line, without its list marker: the item's identity. */ + title: string; + /** @description The item's further lines */ + body: string; + /** @description The text of the nearest heading above the item; empty when there is none. */ + section: string; + }; + TodoStart: { + /** @description The title of the item to start. */ + title: string; + model?: string; }; Unmerged: { /** @description Commits on the task branch that aren't on the default branch. */ @@ -1142,6 +1200,58 @@ export interface operations { 404: components["responses"]["Error"]; }; }; + getTodo: { + parameters: { + query?: never; + header?: never; + path: { + projectId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description The items; exists is false when the default branch has no TODO.md. */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["Todo"]; + }; + }; + 404: components["responses"]["Error"]; + }; + }; + startTodoItem: { + parameters: { + query?: never; + header?: never; + path: { + projectId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["TodoStart"]; + }; + }; + responses: { + /** @description The new task. */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["Task"]; + }; + }; + 400: components["responses"]["Error"]; + 404: components["responses"]["Error"]; + 409: components["responses"]["Error"]; + }; + }; getTask: { parameters: { query?: never; diff --git a/web/src/panes.ts b/web/src/panes.ts index 71f58fd..7ae87e6 100644 --- a/web/src/panes.ts +++ b/web/src/panes.ts @@ -5,19 +5,21 @@ import { mountInbox } from "./inbox.js"; import { mountSettings } from "./settings.js"; import { mountTranscript } from "./task.js"; import { mountTasks } from "./tasks.js"; +import { mountTodo } from "./todo.js"; -export type View = "transcript" | "changes" | "tasks" | "inbox" | "admin" | "settings"; +export type View = "transcript" | "changes" | "tasks" | "todo" | "inbox" | "admin" | "settings"; const views: Record () => void }> = { transcript: { label: "Transcript", mount: mountTranscript }, changes: { label: "Changes", mount: (root) => mountChanges(root) }, tasks: { label: "Tasks", mount: mountTasks }, + todo: { label: "Todo", mount: mountTodo }, inbox: { label: "Inbox", mount: mountInbox }, admin: { label: "Admin", mount: mountAdmin }, settings: { label: "Settings", mount: mountSettings }, }; -const order: View[] = ["transcript", "changes", "tasks", "inbox", "admin", "settings"]; +const order: View[] = ["transcript", "changes", "tasks", "todo", "inbox", "admin", "settings"]; const panes: Pane[] = []; diff --git a/web/src/task.ts b/web/src/task.ts index c226962..2fd9ca9 100644 --- a/web/src/task.ts +++ b/web/src/task.ts @@ -4,7 +4,7 @@ import { markdown } from "./markdown.js"; import { openChanges } from "./panes.js"; import { currentSession, findTask, onEach, pinSnapshot, state } from "./state.js"; -const models = ["claude-opus-5-5", "claude-sonnet-5-5", "claude-haiku-5-5", "claude-fable-5-1"]; +export const models = ["claude-opus-5-5", "claude-sonnet-5-5", "claude-haiku-5-5", "claude-fable-5-1"]; type Call = { name: string; target: string }; diff --git a/web/src/todo.ts b/web/src/todo.ts new file mode 100644 index 0000000..6305882 --- /dev/null +++ b/web/src/todo.ts @@ -0,0 +1,147 @@ +import { get, post, type ByreEvent, type Project, type Schemas } from "./api.js"; +import { errorText, h, replace, showAlert } from "./dom.js"; +import { markdown } from "./markdown.js"; +import { openTranscript } from "./panes.js"; +import { models } from "./task.js"; +import { currentSession, on, onEach, state } from "./state.js"; + +type Todo = Schemas["Todo"]; +type TodoItem = Schemas["TodoItem"]; + +const refreshKinds = new Set(["task.merged", "project.created"]); + +export function mountTodo(root: HTMLElement): () => void { + const todos = new Map(); + const starting = new Set(); + let disposed = false; + + const render = () => { + const scrollTop = root.querySelector(".todo-view")?.scrollTop ?? 0; + replace(root, h("div", { class: "todo-view" }, ...state.projects.map((p) => projectBlock(p, todos.get(p.id), starting, start)))); + root.querySelector(".todo-view")!.scrollTop = scrollTop; + }; + + const load = async (projectId: string) => { + try { + const todo = await get("/api/projects/{projectId}/todo", { path: { projectId } }); + todos.set(projectId, todo); + } catch (err) { + todos.set(projectId, `Couldn't read TODO.md: ${errorText(err)}`); + } + if (!disposed) { + render(); + } + }; + + const refresh = () => { + for (const p of state.projects) { + void load(p.id); + } + }; + + const start = async (project: Project, item: TodoItem) => { + const key = `${project.id}\n${item.title}`; + starting.add(key); + render(); + try { + const task = await post("/api/projects/{projectId}/todo/tasks", { path: { projectId: project.id }, body: { title: item.title, model: models[0] } }); + location.hash = `#/task/${task.id}`; + openTranscript(); + } catch (err) { + void showAlert(errorText(err)); + } + starting.delete(key); + if (!disposed) { + render(); + } + }; + + const offs = [ + on("event", (detail?: unknown) => { + const ev = detail as ByreEvent; + if (!refreshKinds.has(ev.kind)) { + return; + } + if (ev.project_id) { + void load(ev.project_id); + } + }), + on("connection", () => { + if (state.connected) { + refresh(); + } + }), + on("projects", refresh), + onEach(["tasks", "sessions", "selection"], render), + ]; + + render(); + refresh(); + + return () => { + disposed = true; + for (const off of offs) { + off(); + } + }; +} + +function projectBlock(project: Project, todo: Todo | string | undefined, starting: Set, start: (p: Project, item: TodoItem) => Promise): HTMLElement { + const head = h("h2", {}, project.name, " ", h("span", { class: "repo" }, `TODO.md on ${project.default_branch}`)); + + if (todo === undefined) { + return h("section", { class: "project" }, head, h("p", { class: "empty-row" }, "Loading…")); + } + if (typeof todo === "string") { + return h("section", { class: "project" }, head, h("p", { class: "empty-row error-text" }, todo)); + } + if (!todo.exists) { + return h("section", { class: "project" }, head, h("p", { class: "empty-row" }, `No TODO.md on ${project.default_branch}.`)); + } + if (todo.items.length === 0) { + return h("section", { class: "project" }, head, h("p", { class: "empty-row" }, "TODO.md has no items.")); + } + + const active = (state.tasks.get(project.id) ?? []).filter((t) => t.status === "active" && t.todo_item); + const children: HTMLElement[] = []; + let section = ""; + let list: HTMLElement | undefined; + for (const item of todo.items) { + if (!list || item.section !== section) { + section = item.section; + if (section) { + children.push(h("h3", { class: "todo-section" }, section)); + } + list = h("ul", { class: "todo-list" }); + children.push(list); + } + + const task = active.find((t) => t.todo_item === item.title); + let action: HTMLElement; + if (task) { + const sess = currentSession(task.id); + action = h( + "a", + { class: "todo-task", href: `#/task/${task.id}`, onclick: openTranscript }, + h("span", { class: `dot ${sess?.state ?? "none"}`, title: sess?.state ?? "no session" }), + sess?.state ?? "no agent", + ); + } else { + const busy = starting.has(`${project.id}\n${item.title}`); + const button = h("button", { disabled: busy }, busy ? "Starting…" : "Start"); + button.onclick = () => void start(project, item); + action = button; + } + + list.append( + h( + "li", + { class: task && task.id === state.selectedTaskId ? "selected" : "" }, + h("div", { class: "todo-head" }, h("span", { class: "todo-title" }, item.title), action), + item.body && markdown(item.body, "md todo-body"), + ), + ); + } + + return h("section", { class: "project" }, head, ...children); +} diff --git a/web/style.css b/web/style.css index 2d8842f..208b1ae 100644 --- a/web/style.css +++ b/web/style.css @@ -327,6 +327,61 @@ textarea { padding: 8px 16px 16px; } +.todo-view { + overflow-y: auto; + padding: 8px 16px 16px; +} + +.todo-section { + font-size: 12px; + color: var(--muted); + margin: 10px 0 4px; +} + +.todo-list { + list-style: none; + margin: 0 0 8px; + padding: 0; +} + +.todo-list li { + padding: 6px 10px; + border-radius: 6px; +} + +.todo-list li.selected { + background: var(--accent-tint); +} + +.todo-head { + display: flex; + align-items: center; + gap: 10px; +} + +.todo-title { + flex: 1; + min-width: 0; +} + +.todo-task { + display: flex; + align-items: center; + gap: 6px; + flex-shrink: 0; + color: var(--muted); + font-size: 11px; +} + +.todo-head button { + flex-shrink: 0; +} + +.todo-body { + color: var(--muted); + margin-top: 4px; +} + .project h2 { font-size: 13px; margin: 16px 0 6px;