Commit Graph

286 Commits

Author SHA1 Message Date
ca028a4024 docs: add git-diff-panel implementation planning artifacts
Implementation decision log, iteration history, synthesis input, the
implementation plan, and discovery notes for the git-diff-panel feature.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 02:26:04 +00:00
3e7115afad docs: record @boocode/contracts SSOT + schema-migration learnings in CLAUDE.md
Add the packages/contracts package to the monorepo list, a consolidated
@boocode/contracts conventions bullet (subpaths, build-first, web-local strict
WsFrame union, built-dist consumption), and the `SELECT *` view / DROP COLUMN
(2BP01) schema gotcha that crash-looped boocoder.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 02:25:59 +00:00
9a139633b8 fix(coder): drop human_inbox view before dropping tasks columns
The audit-cleanup migration dropped tasks.feature_values/worktree_path, but
human_inbox is `SELECT * FROM tasks` and pins every column, so the DROP COLUMN
failed (2BP01) on any existing DB and crash-looped boocoder on boot. Drop the
view, drop the columns, then recreate it — idempotent on fresh and existing DBs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 00:29:28 +00:00
2c4ff2063d fix: reconcile audit-cleanup refactor with @boocode/contracts SSOT (worktree-risk type, frame-emitter import)
worktree-risk.ts now returns the package's WorktreeRiskReport (local RiskReport interface removed); frame-emitter.ts imports WsFrame from @boocode/contracts/ws-frames (the deleted @boocode/server/ws-frames subpath).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 23:25:50 +00:00
ae3f10b19d Merge remote-tracking branch 'origin/main' 2026-06-02 21:30:28 +00:00
cc4bd04aa4 Merge contracts-ssot-pkg: v2.7.13 single-source cross-app wire contracts in @boocode/contracts v2.7.13-contracts-ssot 2026-06-02 21:24:14 +00:00
649ce71eff feat: single-source cross-app wire contracts in @boocode/contracts (v2.7.13)
Move all hand-synced cross-app wire contracts into one built workspace
package, @boocode/contracts, consumed by server/web/coder/coder-web via
workspace:* + a per-subpath exports map. The ws-frames and provider-config
Zod schemas are schema-first (z.infer); MessageMetadata, ErrorReason,
AgentSessionConfig, the provider snapshot types, and WorktreeRiskReport are
each single-sourced. Deletes the byte-identical copies and their parity
tests, fixes a live AgentSessionConfig drift (coder dead copy removed,
unified to the web required/nullable shape), removes the dead pending_change
WS arms in the fallback SPA, and inverts the build order (contracts builds
first) across root build, Dockerfile, and the coder deploy docs. Reverses
the shared-package decision declined in v2.5.12.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 21:24:08 +00:00
2a05d2f9fe docs: archive shipped openspec batches; add feature/plan/research notes
Move 13 shipped openspec change docs under openspec/changes/archived/.
Add docs/features/git-diff-panel, docs/plans/post-review-backlog, and
docs/research/cross-app-contract-ssot.md (the research behind the
@boocode/contracts SSOT work). Update BOOCHAT.md, BOOCODER.md, and
boocode_roadmap.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 21:20:33 +00:00
8c200216eb refactor: codebase audit cleanup — dead code, dedup, module splits
Multi-agent audit + aggressive cleanup across server/web/coder/booterm,
delivered behind a DEFER discipline so none of the in-flight files were
touched. Removes dead code/deps/columns, dedups server + coder helpers,
and splits the oversized modules (tools.ts, opencode-server.ts,
sentinel-summaries, turn.ts, TerminalPane.tsx) behind stable contracts.
Adds 78 parity/unit tests (server 587, coder 323); fixes two latent bugs
(ChatPane queue keys, FileViewerOverlay blank-line parity).

Intended tag: v2.7.12-audit-cleanup.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v2.7.12-audit-cleanup
2026-06-02 21:12:29 +00:00
e5ce01ae72 fix(coder): include model in WS snapshot SELECT so the attribution chip survives refresh
CoderPane hydrates from the HTTP listMessages fetch (SELECT has model) AND the WS snapshot frame, and the snapshot handler setMessages-overwrites the HTTP load. The snapshot query in apps/coder/src/routes/ws.ts had its own column list that omitted model, so on coder refresh the chip's model was lost (it showed live via the message_complete frame). One-column fix: add model to that SELECT. CLAUDE.md mapper-chain note updated to list the WS snapshot SELECT.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v2.7.11-coder-model-snapshot
2026-06-02 18:03:10 +00:00
81470f5a77 Merge composer-chips: v2.7.10 composer attach-file button + slash-commands chip (icon-only on mobile)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v2.7.10-composer-chips
2026-06-02 17:27:59 +00:00
35dba828e1 feat: composer attach-file button + slash-commands chip (icon-only on mobile)
Move the slash-commands menu out of the full-width AgentCommandsHint disclosure into a compact chip in the composer's bottom controls row, and add an attach-file button that reuses the existing drag-drop pipeline (5MB/binary gate, 10-attachment cap, chips + preview). On mobile both collapse to icon-only (count hidden). Shared ChatInput, so it applies to both BooChat and BooCoder; typed-/ autocomplete is unchanged. Removes the now-unused AgentCommandsHint component.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 17:26:27 +00:00
ce621bc003 Merge mcp-env-keys-batch: v2.7.9 MCP {env:VAR} key substitution + coder model/tool-result fixes + docs refactor v2.7.9-mcp-keys-docs-coder-fixes 2026-06-02 17:01:11 +00:00
afaca9e426 feat: MCP {env:VAR} key substitution + coder model/tool-result fixes + docs refactor (v2.7.9)
- MCP secrets: substituteEnvVars recursively resolves {env:NAME} in mcp.json string values from process.env before Zod (opencode-compatible); unset -> '' + boot warning, and invalid-config log names the unset vars (an empty {env:VAR} in a strict url/command field invalidates the whole config)
- data/mcp.json now untracked (.gitignore flips !data/mcp.json -> !data/mcp.example.json); tracked template data/mcp.example.json carries "{env:CONTEXT7_API_KEY}"; .env.example documents the key (9 mcp-config tests)
- Coder fix: message_complete frame model widened string -> string|null (server+web ws-frames parity); dispatcher publishes model: task.model at all 4 external completion points — a null model otherwise fail-closed in publishFrame and dropped the whole frame incl. status:'complete' (regression test)
- Coder fix: claude-sdk mapUserToolResults maps user-message tool_result blocks -> terminal tool_update events (completed/failed w/ output) so tool snapshots resolve instead of spinning forever
- Composer: AgentComposerBar drops §9b resumed/history/new chip + token readout, loses flex-wrap so the row stays one line; CoderPane gains a per-chat localStorage agent-config cache (restores last model on reopen) + threads model into the timeline/chip
- Docs: root CLAUDE.md slimmed (~190 lines), per-app refs split to apps/{coder,server,web}/CLAUDE.md; new docs/coder-backends.md, docs/project-discovery.md, docs/coding-standards/ (cross-app-contract-parity); ARCHITECTURE.md links the backends doc

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 17:01:03 +00:00
7ca4a6b344 chore: prune unused brand PNGs (keep banner-mascot + banner-wordmark)
Removes boo-badge / boocode-icon / boocode-wordmark / boocode-wordmark-tight —
copied from the design bundle but unreferenced; only the two banner badges are
imported (ProjectSidebar).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 23:10:12 +00:00
27f3a6c463 Merge boocode-ui-ember-coder-model: v2.7.8 Ember theme + brand banner + coder tabs + model-attribution chips v2.7.8-ember-coder-tabs-model-chips 2026-06-01 22:30:58 +00:00
3a646fd6df feat: BooCode 2.0 UI — Ember theme, brand banner, coder tabs, model-attribution chips
- Ember theme (Obsidian charcoal + #ff7a18 orange), now DEFAULT_THEME_ID; server theme_id whitelist gains 'ember'
- Brand banner: transparent Westie mascot + >_BooCode wordmark, big/edge-to-edge (flood-filled to transparency + cropped)
- Coder panes are multi-tab: + opens a BooCode tab, split opens a pane (shared ChatTabBar via tabKind + createCoderTab; closeOtherTabs/tab-numbering extended to coder)
- Model-attribution: new messages.model column stamped at finalizeCompletion (BooChat/native coder) + dispatcher assistant-row creation (external coder); surfaced via view + wire types + live frame; rendered as a subtle shortened-name chip (shortenModelName)
- Composer Web toggle moved into a boxed focus-ringed input; glowing accent dot on tool rows
- Claude SDK follow-ups (1M context, follow-up-message fix, collapsed thinking/tool chips) + CLAUDE_SDK_BACKEND=1

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 22:30:47 +00:00
7098014261 Merge pane-header-shared: v2.7.7 shared pane-header cluster + chat-resolve WorkspaceState fix 2026-06-01 14:29:00 +00:00
c56d169ef9 feat: shared PaneHeaderActions + chat-resolve WorkspaceState fix (v2.7.7)
In-flight workspace UX work.

- Extract a shared PaneHeaderActions cluster (+/Split/Reopen/History/Close)
  used by ChatTabBar + the Workspace coder/terminal pane headers, replacing the
  divergent per-header copies; SessionLandingPage history + useWorkspacePanes
  tweaks.
- Fix coder-side correctness bug: resolveChatId read sessions.workspace_panes as
  a bare WorkspacePane[] but v2.6.5 widened it to a WorkspaceState envelope, so
  it mis-read panes and clobbered tabNumbers/nextTabNumber/closedPaneStack on
  every pane-chat write. New normalizeWorkspaceState handles either shape and
  preserves the envelope (+ regression test).
- CLAUDE.md doc-sync (coder vitest suite, deploy-by-surface, dual-remote push,
  in-flight-web-WIP staging, release-branch naming).

Web tsc + coder build + coder tests green. Builds on v2.7.6.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v2.7.7-pane-header-actions
2026-06-01 14:28:49 +00:00
b7fb254e5d Merge agent-status-dot: v2.7.6 normalized external-agent status (scoped #10) 2026-06-01 14:04:26 +00:00
59cf082e06 feat: normalized external-agent status (#10 scoped) (v2.7.6)
Scoped half of boocode_code_review_v2 §1 #10 — publish the agent status
BooCoder already observes (the config-injection notify-hook is the documented
follow-on, clean-room from superset ELv2).

- agent_status_updated WS frame (working|blocked|idle|error), server+web parity.
- Published from the dispatcher's turn boundaries (warm-acp/opencode/sdk/pty:
  working at start, idle/error at end) + the permission flow (blocked/working).
  Best-effort, never breaks a turn.
- Clean-room normalizeAgentEvent helper (superset's vendor-event -> Start/blocked
  /Stop collapse, event names as facts) + 25 tests — reused by the follow-on.
- AgentComposerBar status dot (distinct from the WS-liveness dot), tracked per
  (chat,agent) by a useAgentStatus map in CoderPane.

Built by 2 parallel agents vs a pinned frame contract. Server 545 + coder 294
tests passing (25 new); web tsc + builds clean; ws-frames parity green. Clears
the actionable review backlog (#1/#3/#4/#6-#12). Builds on v2.7.5.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v2.7.6-agent-status-normalize
2026-06-01 14:04:04 +00:00
6fc3175730 Merge claude-sdk-backend: v2.7.5 Claude SDK backend + clean-room PostgresSessionStore 2026-06-01 13:38:05 +00:00
f3a0197d6a feat: Claude Agent SDK backend + clean-room PostgresSessionStore (v2.7.5)
Lands the lean-SDK direction (boocode_code_review_v2 §1 #9) behind a flag.
Adds @anthropic-ai/claude-agent-sdk@0.3.159 (Commercial Terms, runtime dep).

- PostgresSessionStore: clean-room impl of the SDK's real SessionStore type
  over a new claude_session_entries table. Typechecks against the SDK type;
  8 DB-integration tests.
- ClaudeSdkBackend (implements AgentBackend): one warm query() per (chat,claude)
  in streaming-input mode via a pushable async-iterable pump, sessionStore +
  resume continuity, pure mapSdkMessage->AgentEvent, session_id from init,
  usage/cost onto agent_sessions (backend CHECK gains 'claude_sdk').
- Routing env-gated by CLAUDE_SDK_BACKEND (default off) -> PTY path UNCHANGED.
- Built against real SDK 0.3.159 types (install paid off: partial=stream_event
  needing includePartialMessages, MessageParam, result error arm).
- Fix latent test-infra deadlock: serialize DB suites (fileParallelism:false).

Coder 269 passing default / 290 with DB; tsc clean vs SDK types; builds clean.
LIVE pump + resume + actual claude turn need a host smoke (CLAUDE_SDK_BACKEND=1
+ claude binary + auth). zod peer-dep wants ^4 (workspace 3.25). Builds on v2.7.4.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v2.7.5-claude-sdk-sessionstore
2026-06-01 13:37:57 +00:00
7e0ecde83d Merge mistake-tracker-ledger: v2.7.4 heterogeneous-failure recovery + file-read ledger 2026-06-01 13:05:19 +00:00
bcc89d8adc feat: MistakeTracker + file-provenance ledger (v2.7.4)
Two native-inference hardening features from boocode_code_review_v2 §1 #12.

MistakeTracker: new pure mistake-tracker.ts tracks consecutive heterogeneous
tool failures (kinds surfaced per tool from tool-phase.ts). On 3 in a row the
turn loop soft-nudges (model-facing recovery guidance + mistake_recovery
sentinel + reset), then escalates to stopping the turn (cap-hit-style, Continue
affordance) on a re-trip. Complements doom-loop (identical repeats) + cap-hit.

File-provenance ledger: compaction.ts derives a deterministic ## Files Read list
from the head messages' read-tool calls and injects it into the rolling-summary
prompt so provenance survives compaction (no new table; read-only).

mistake_recovery sentinel: MessageMetadata arm (server + web) + MessageBubble
render branch. Built by 2 parallel agents. Server 545 tests passing (23 new);
build + web tsc clean. Native-inference only. Builds on v2.7.3.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v2.7.4-mistake-tracker-ledger
2026-06-01 13:05:03 +00:00
f53d6a8afd Merge sampling-knobs-streamjson: v2.7.3 sampling knobs + live PTY stream-json + token UI 2026-06-01 12:47:31 +00:00
a584dd16b0 feat: sampling knobs + live PTY stream-json + token UI (v2.7.3)
Three small wins from boocode_code_review_v2 §1 #11/#7/#8.

#11 sampling knobs: top_n_sigma + dry_* family as first-class Agent fields,
threaded into the request body via providerOptions.openaiCompatible. Fixes a
latent bug — top_k (rejected by the AI-SDK provider) and min_p (never passed to
streamText) were dead on the wire; both now route through the same channel.
--reasoning-budget documented in data/AGENTS.md.

#7 live PTY stream-json: new stream-json-parser.ts line-buffers qwen/claude
NDJSON and emits text/reasoning/tool frames live + persists, with a fallback to
the old opaque slice. claude gets --output-format stream-json --verbose.

#8 token UI: agent_sessions input/output_tokens/cost now flow through the route
+ type and render beside the AgentComposerBar session chip.

Built by 3 parallel agents. Server 523 + coder 245 tests passing; builds + web
tsc clean. Builds on v2.7.2. openspec sampling-streamjson-tokens.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v2.7.3-sampling-streamjson-tokens
2026-06-01 12:47:17 +00:00
5651f56039 Merge checkpoint-idor-fix: v2.7.2 close 2 checkpoint IDOR holes 2026-06-01 12:16:08 +00:00
9c7d80e2d8 fix(security): scope checkpoint routes to session — close 2 IDORs (v2.7.2)
Flagged by the automated push security review on v2.7.1.

- GET /checkpoints?chat_id= : the chat_id branch filtered by chat_id alone
  (any session's chat_id read its checkpoints). Now joins chats and gates on
  chats.session_id.
- restoreCheckpoint scope guard was fail-open: `cp.session_id && cp.session_id
  !== sessionId` fell through on a null denormalized session_id, allowing a
  cross-session restore (worktree reset + transcript trim). Now resolves the
  owning session via the checkpoint's chat and denies on missing/mismatch.
- Adds a DB-integration regression for the null-session_id cross-session case.

Both scope authoritatively through chats.session_id (checkpoints.session_id is
a nullable hint). Coder suite 234 passing; 7/7 checkpoint tests (incl. the
regression) against live postgres+git; typecheck clean. Hotfix on v2.7.1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v2.7.2-checkpoint-idor
2026-06-01 12:15:54 +00:00
a41a02a62b Merge fuzzy-checkpoints: v2.7.1 write/edit robustness (fuzzy applier + worktree checkpoints) 2026-06-01 12:02:06 +00:00
59f07e8cb8 feat: write/edit robustness — fuzzy patch applier + worktree checkpoints (v2.7.1)
#3 Fuzzy patch applier: new pure fuzzy-match.ts (locateMatch, exact→trim→
unicode-canon→Levenshtein≥0.66, refuse-on-ambiguous) wired into pending_changes
applyOne/rewindOne so local-model whitespace/unicode drift in old_string no
longer loses the edit.

#4 Worktree checkpoint + conversation-trim: checkpoints table + checkpoints.ts
(shadow-commit of tracked+untracked into refs/boocode/checkpoints, hooked into
the 3 external-agent dispatcher paths) + POST restore route (reset --hard +
clean -fd -> transcript trim -> backend-session reset) + "Restore to here" UI.

Built by 3 parallel agents; DB-integration testing caught a created_at
self-deletion bug. Coder suite 234 passing; server+coder build + web tsc clean.
Builds on v2.7.0-mit. openspec write-edit-robustness.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v2.7.1-write-edit-robustness
2026-06-01 12:01:57 +00:00
1108d07fb2 Merge relicense-agpl-to-mit: v2.7.0 AGPL-3.0 → MIT relicense 2026-06-01 08:16:25 +00:00
a8bfde8f8d feat: relicense AGPL-3.0 → MIT (v2.7.0)
Clear the 3 Unsloth-Studio-derived AGPL files and flip LICENSE + 5
package.json from AGPL-3.0-only to MIT.

- html-to-md.ts → MIT node-html-markdown (parse5 dropped)
- llama-args-validator.ts → clean-room (flag denylist = facts)
- tool-call-parser.ts → delete dead Unsloth-ported code; keep
  extractToolCallBlocks/stripToolMarkup byte-identical (no behavior change)
- LICENSE → MIT (Copyright (c) 2026 indifferentketchup); 5 package.json → MIT;
  AGPL SPDX headers removed; README License section; license-mit guard test
- roadmap License-debt batch marked shipped; openspec/changes/license-debt-mit

Decouples the relicense from the native-parsing retirement (the ported parser
was dead code). Server suite 519 passing; build + coder typecheck clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v2.7.0-mit
2026-06-01 08:16:03 +00:00
9c1ddcaa7c Merge v2611-followups: v2.6.11 apps/server close-hook caller + DiffPanel staging hint 2026-06-01 02:35:21 +00:00
217f487395 docs(changelog): v2.6.11-close-hooks-staging (closes the v2.6 openspec)
CHANGELOG + roadmap (through v2.6.11) + openspec v2-6 Phase 3 fully closed (3.7 + apps/server close-hook caller done).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v2.6.11-close-hooks-staging
2026-06-01 02:35:21 +00:00
2dfbef4c41 feat: v2.6 follow-ups — apps/server close-hook caller + DiffPanel staging hint (3.7)
apps/server fire-and-forgets BooCoder's Phase-3 close hooks (new coder-notify.ts, reuses BOOCODER_URL, never-rejects) on session-delete + chat archive/archive-all/delete, so warm backends + worktrees tear down immediately (idle-evict/reaper was the backstop). 3.7: BooCoder DiffPanel shows a muted one-liner when the selected provider can't see another agent's unapplied worktree edits (pure derivation from per-change agent + current provider, no new state). 6 new server tests (coder-notify); 537 server tests pass; web+server tsc/build clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 02:35:11 +00:00
c7a8128059 Merge phase3-lifecycle: v2.6.10 lifecycle hardening (completes v2.6 persistent agent sessions) 2026-06-01 01:10:16 +00:00
986c8a83a9 docs(changelog): v2.6.10-lifecycle-hardening (completes v2.6)
CHANGELOG + roadmap (through v2.6.10; v2.6 marked complete) + openspec v2-6 Phase 3 checked off (3.1-3.6; 3.7 frontend + apps/server caller as follow-ups).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v2.6.10-lifecycle-hardening
2026-06-01 01:10:16 +00:00
aa3797e356 feat(coder): v2.6 Phase 3 — lifecycle hardening (idle evict, crash recovery, worktree reaper)
Idle TTL eviction per (chat,agent) + LRU cap (never a busy backend); pure lifecycle-decisions.ts (TDD). Crash recovery lifts openchamber's health-monitor + busy-aware-restart + stale-grace state machine into opencode-server.ts (+ port reclaim) and warm-acp.ts; opencode crash -> fresh sessions, ACP -> re-session/new. F.1 turn-guard + U.6 usage preserved (their tests pass). Orphan worktree reaper (1h grace, superset-style dirty/unpushed preflight, Paseo soft-delete) + close hooks + diff re-baseline after apply_pending. 35 new tests + DB-opt-in reconnect test; 215 coder tests pass; tsc + build clean. Completes v2.6. Follow-ups out of scope: apps/server close-hook caller, 3.7 DiffPanel staging hint, live smokes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 01:10:09 +00:00
850d48853f Merge phase2-warm-acp: v2.6.9 warm ACP backend for goose/qwen 2026-05-31 23:57:14 +00:00
f619ae0978 docs(changelog): v2.6.9-warm-acp
CHANGELOG + roadmap (through v2.6.9) + openspec v2-6 Phase 2 checked off (2.1-2.4; Smoke 2/2b pending live).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v2.6.9-warm-acp
2026-05-31 23:57:09 +00:00
0d3d08f5f2 feat(coder): v2.6 Phase 2 — warm ACP backend for goose/qwen
WarmAcpBackend (AgentBackend) holds one persistent goose acp / qwen --acp child + ClientSideConnection + ACP session per (chat,agent); initialize+session/new once, reused across turns. Abort = session/cancel the prompt only (never kills the child); child exit -> agent_sessions.status='crashed' -> re-spawn next turn. Dispatcher routes goose/qwen chat-tab tasks to the pooled warm backend via pure shouldUseWarmBackend (needs session_id+chat_id); one-shot runExternalAgent kept as fallback for arena/MCP/new_task. handleSessionUpdate extracted to a shared pure acp-event-map.ts (one-shot path byte-identical). SDK: installed @agentclientprotocol/sdk@^0.22.1 has stable resumeSession/loadSession; resume moot in the warm hot path, deferred to Phase 3. 15 new tests (warm-acp-routing, acp-event-map); 180 coder tests pass; tsc + build clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 23:57:03 +00:00
0658d19b64 Merge phase1-ux: v2.6.8 agent attribution (DiffPanel badges + composer chip + agent-sessions route + opencode usage) 2026-05-31 22:07:39 +00:00
631af5dd4c docs(changelog): v2.6.8-agent-attribution
CHANGELOG + roadmap shipped record (through v2.6.8) + openspec v2-6 Phase 1-UX checked off (U.1-U.6; Smoke U pending the frontend Docker rebuild).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v2.6.8-agent-attribution
2026-05-31 22:07:32 +00:00
5db6551361 feat(web): Phase 1-UX frontend — DiffPanel agent badges + resumed/new-session chip
DiffPanel renders a per-row agent badge (icon+label; null -> 'manual') + a 'Changes from X, Y' note when the pending set spans >1 agent. AgentComposerBar gains an optional sessionId prop -> resumed/history/new-session chip beside the Provider picker (gated, so BooChat callers are unchanged), driven by a new useAgentSessions hook (refetch on message-complete). providerIcon extracted to shared components/coder/providerIcons.tsx; api.coder gains agentSessions(sessionId); PendingChange type gains agent. web tsc clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 22:07:26 +00:00
c060778258 feat(coder): Phase 1-UX backend — agent attribution + agent-sessions route + opencode usage
pending_changes.agent stamped at every queue site (native -> 'boocode', dispatched external -> task.agent, manual RightRail -> NULL) + flows through listPending. New GET /api/sessions/:id/agent-sessions -> [{agent,status,has_session,last_active_at}] per (chat,agent). opencode warm server consumes session.next.step.ended, accumulating input_tokens/output_tokens/cost onto agent_sessions (new idempotent columns) via a pure opencode-usage.ts mapper. Tests: agent-sessions.routes (3) + opencode-usage (6); tsc clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 22:07:14 +00:00
48c1d70baf Merge f1-interrupt-guard: F.1 opencode post-interrupt stale-terminal guard + doc reconciliation (v2.6.7) 2026-05-31 21:32:25 +00:00
457010391a docs(changelog): v2.6.7-interrupt-guard + reconcile roadmap/review/openspec
CHANGELOG entry for v2.6.7. Plus the session's doc reconciliation: roadmap shipped record synced through v2.6.7 (v2.3 lifecycle marked shipped, relicense AGPL->MIT batch, fork-sweep lift items, claude-agent-sdk SessionStore, ACP package fix); boocode_code_review_v2 (two fork sweeps, relicense decision = 3 AGPL files, jinja gate green); openspec v2-3 reconciled to shipped (v2.5.4-v2.5.13); openspec v2-6 Phase 0/1 + P1.5 shipped, F.1 done, remaining-phase plan + lift sources.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v2.6.7-interrupt-guard
2026-05-31 21:31:47 +00:00
372651bcb1 fix(coder): F.1 post-interrupt stale-terminal guard (opencode warm server)
opencode emits one trailing session.idle/error for a turn cancelled via client.session.abort(), carrying only a sessionID (no turn id). The warm-server backend settled activeTurn on that event, so after Stop + an immediate new message the orphan idle settled the NEXT turn early as success (one-click reachable since v2.6.5's Send->Stop composer).

Adds a pure per-session guard (backends/turn-guard.ts: armAbortGuard / noteTurnActivity / consumeTerminal over swallowNextTerminal) wired into opencode-server.ts: abort arms it, the next terminal is swallowed once, and a new turn's first delta self-heals so a never-arriving orphan can't strand a real turn. Test-first; 3 regression tests in turn-guard.test.ts. Paseo parallel: 1d38aac.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 21:31:35 +00:00
d66948c925 docs(changelog): v2.6.6-claude-md
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v2.6.6-claude-md
2026-05-31 12:44:33 +00:00