diff --git a/docs/FRANKENCODE.md b/docs/FRANKENCODE.md index a73513645..95bbd5603 100644 --- a/docs/FRANKENCODE.md +++ b/docs/FRANKENCODE.md @@ -1,55 +1,34 @@ -# Frankencode +# Frankencode: Technical Differences from OpenCode -Frankencode is a fork of [OpenCode](https://github.com/anomalyco/opencode) that adds subagent tabs, fork agents, context editing, and a verification/refinement loop. +Complete list of every change relative to upstream [OpenCode](https://github.com/anomalyco/opencode) (`dev` branch). For a feature overview, see [README.md](README.md). --- ## Tab Bar and Subagent Tabs -OpenCode shows one session at a time. Frankencode adds a **tab bar** at the top of the session view: - -``` -Main │ + │ S1 │ S2 │ F1 -``` - -- **Main** — the root session (always present) -- **+** — creates a fork agent (copies Main's conversation history) -- **S1, S2, ...** — subagents spawned by the LLM's task tool -- **F1, F2, ...** — fork agents created by the user via `+` +| File | Purpose | +|------|---------| +| `src/cli/cmd/tui/routes/session/tab.ts` | `useTab` hook — all tab state and actions | +| `src/cli/cmd/tui/routes/session/tabbar.tsx` | Pure renderer for tab chips | -**Navigation:** +Tab labels: **Main** (root), **+** (fork spawn), **S1-Sn** (LLM subagents), **F1-Fn** (user forks). -| Key | Action | -|-----|--------| -| Tab | Toggle focus between tab bar and chat prompt | -| ←/→ | Navigate tabs (immediately shows selected session) | -| ↓ / Escape | Return focus to chat prompt | -| Enter/Space | Activate selected tab (spawn fork if on `+`) | -| x | Kill selected agent | -| Shift+Tab | Cycle agent type (Build/Plan/etc.) | -| Ctrl+C | First: abort all + show hint. Second: exit app | -| Click | Select any tab and focus bar | +### Keybinding changes -Implementation: [`tab.ts`](../packages/opencode/src/cli/cmd/tui/routes/session/tab.ts) (hook + logic), [`tabbar.tsx`](../packages/opencode/src/cli/cmd/tui/routes/session/tabbar.tsx) (renderer) +| Keybind | OpenCode | Frankencode | +|---------|----------|-------------| +| Tab | Cycle agents | Toggle tab bar focus | +| Shift+Tab | (none) | Cycle agents (Build/Plan/etc.) | +| ←/→ (tab bar focused) | (N/A) | Navigate tabs | +| Ctrl+C | Exit immediately (if input empty) | Double-press to exit | --- ## Fork Agents -Fork agents are user-created branches of the main conversation. Pressing `+` in the tab bar forks Main's full conversation history into a new child session. +Fork agents are child sessions created via `+` that copy Main's conversation history. They cannot spawn subagents (`task` permission denied + system prompt constraint). Colored yellow in the tab bar. See [README.md](README.md#subagent-tab-bar) for the comparison table. -| Feature | Fork Agent (F) | Subagent (S) | -|---------|---------------|--------------| -| Created by | User via `+` | LLM via task tool | -| Conversation history | Copied from Main | Starts empty | -| Can spawn subagents | No (denied by permission) | Yes | -| Tab color | Yellow | Agent color | -| Lifetime | Until user kills with `x` | Auto-terminates when done | -| Promptable | Yes (user types in chat) | LLM-driven | - -Fork agents receive a system prompt explaining they cannot spawn subagents and should suggest delegating to Main if needed. - -Implementation: `Session.fork()` in [`session/index.ts`](../packages/opencode/src/session/index.ts), fork system prompt in [`prompt.ts`](../packages/opencode/src/session/prompt.ts) +Implementation: `Session.fork()` in `src/session/index.ts`, fork system prompt in `src/session/prompt.ts`. --- @@ -57,33 +36,29 @@ Implementation: `Session.fork()` in [`session/index.ts`](../packages/opencode/sr | Module | Files | Purpose | |--------|-------|---------| -| Content-Addressable Store | `src/cas/index.ts`, `src/cas/cas.sql.ts` | SHA-256 deduplicated content storage for edit originals | +| Content-Addressable Store | `src/cas/index.ts`, `src/cas/cas.sql.ts` | SHA-256 deduplicated storage for edit originals | | Edit Graph | `src/cas/graph.ts` | DAG-based version history for context edits | -| Context Editing | `src/context-edit/index.ts` | 6 edit operations (hide, unhide, replace, externalize, annotate, mark) | -| Side Threads | `src/session/side-thread.ts`, `src/session/side-thread.sql.ts` | Project-level deferred findings that survive across sessions | -| Objective Tracker | `src/session/objective.ts` | Extracts and tracks session objective from first user message | -| Tab Bar | `src/cli/cmd/tui/routes/session/tab.ts`, `tabbar.tsx` | `useTab` hook + pure renderer for subagent tabs | - -See [context-editing.md](context-editing.md) and [schema.md](schema.md) for details. +| Context Editing | `src/context-edit/index.ts` | 6 edit operations — see [context-editing.md](context-editing.md) | +| Side Threads | `src/session/side-thread.ts`, `src/session/side-thread.sql.ts` | Project-level deferred findings | +| Objective Tracker | `src/session/objective.ts` | Extracts session objective from first user message | +| Tab Bar | `src/cli/cmd/tui/routes/session/tab.ts`, `tabbar.tsx` | `useTab` hook + pure renderer | --- ## New Tools (10) -| Tool | File | Purpose | -|------|------|---------| -| `context_edit` | `src/tool/context-edit.ts` | Edit conversation parts (hide, replace, externalize, annotate, mark) | -| `context_deref` | `src/tool/context-deref.ts` | Retrieve CAS content by hash | -| `context_history` | `src/tool/context-history.ts` | Navigate edit DAG (log, tree, checkout, fork) | -| `thread_park` | `src/tool/thread-park.ts` | Park off-topic findings as side threads | -| `thread_list` | `src/tool/thread-list.ts` | List project-level side threads | -| `classifier_threads` | `src/tool/classifier-threads.ts` | Run classifier agent, return structured JSON | -| `distill_threads` | `src/tool/distill-threads.ts` | Classify + park side threads in one step | -| `objective_set` | `src/tool/objective-set.ts` | Set/update session objective | -| `verify` | `src/tool/verify.ts` | Run test/lint/typecheck with circuit breaker | -| `refine` | `src/tool/refine.ts` | Evaluator-optimizer loop for iterative improvement | - -See [context-editing.md](context-editing.md) for usage details. +| Tool | Purpose | +|------|---------| +| `context_edit` | Edit conversation parts (hide, replace, externalize, annotate, mark) | +| `context_deref` | Retrieve CAS content by hash | +| `context_history` | Navigate edit DAG (log, tree, checkout, fork) | +| `thread_park` | Park off-topic findings as side threads | +| `thread_list` | List project-level side threads | +| `classifier_threads` | Run classifier agent, return structured JSON | +| `distill_threads` | Classify + park side threads in one step | +| `objective_set` | Set/update session objective | +| `verify` | Run test/lint/typecheck with circuit breaker | +| `refine` | Evaluator-optimizer loop for iterative improvement | --- @@ -97,7 +72,7 @@ See [context-editing.md](context-editing.md) for usage details. | evaluator | Score code changes 1-10 with feedback | Enabled (hidden) | | optimizer | Improve code based on evaluator feedback | Enabled (hidden) | -See [agents.md](agents.md) for configuration and model recommendations. +See [agents.md](agents.md) for configuration, mode switching, and model recommendations. --- @@ -105,11 +80,11 @@ See [agents.md](agents.md) for configuration and model recommendations. | Command | Type | Purpose | |---------|------|---------| -| `/btw ` | Ephemeral | Side conversation in subagent, doesn't pollute context | -| `/focus` | Ephemeral | Classify + externalize stale output + park side threads | -| `/focus-rewrite-history` | Ephemeral | Full conversation rewrite with user confirmation | -| `/reset-context` | Ephemeral | Restore all edited parts from CAS originals | -| `/cost` | TUI dialog | Show session cost breakdown (tokens, pricing) | +| `/btw ` | Ephemeral | Side conversation in subagent | +| `/focus` | Ephemeral | Classify + externalize + park | +| `/focus-rewrite-history` | Ephemeral | Full conversation rewrite | +| `/reset-context` | Ephemeral | Restore all parts from CAS | +| `/cost` | TUI dialog | Session cost breakdown | | `/verify` | Command | Run test/lint/typecheck | | `/threads` | Ephemeral | List side threads | | `/history` | Ephemeral | Show edit history | @@ -118,107 +93,50 @@ See [agents.md](agents.md) for configuration and model recommendations. --- -## Schema Changes (4 new tables) +## Schema Changes -| Table | Purpose | -|-------|---------| -| `cas_object` | Content-addressable store (SHA-256 keyed) | -| `edit_graph_node` | Edit version DAG nodes | -| `edit_graph_head` | Per-session DAG head tracking + branches | -| `side_thread` | Project-level side threads | - -Plus 2 new fields on `PartBase` (all message parts): `edit` (EditMeta) and `lifecycle` (LifecycleMeta). See [schema.md](schema.md) for column details. +4 new tables: `cas_object`, `edit_graph_node`, `edit_graph_head`, `side_thread`. 2 new fields on `PartBase`: `edit` (EditMeta), `lifecycle` (LifecycleMeta). See [schema.md](schema.md). --- ## Prompt Pipeline Changes -Added to the message processing pipeline in `src/session/prompt.ts`: - -1. **`filterEdited()`** — removes hidden parts from LLM context (originals preserved in CAS) -2. **`filterEphemeral()`** — drops ephemeral command messages entirely -3. **Deterministic sweeper** — auto-hides/externalizes parts based on lifecycle markers -4. **Focus status injection** — adds objective + parked threads to system prompt when context_edit is available -5. **Fork agent prompt** — tells fork agents they cannot spawn subagents - ---- - -## Keybinding Changes - -| Keybind | OpenCode | Frankencode | -|---------|----------|-------------| -| Tab | Cycle agents | Toggle tab bar focus | -| Shift+Tab | (none) | Cycle agents (Build/Plan/etc.) | -| ←/→ (tab bar focused) | (N/A) | Navigate tabs | -| Ctrl+C | Exit immediately (if input empty) | Double-press to exit (first press aborts + shows hint) | +1. **`filterEdited()`** — removes hidden parts from LLM context +2. **`filterEphemeral()`** — drops ephemeral command messages +3. **Deterministic sweeper** — auto-hides/externalizes expired parts +4. **Focus status injection** — objective + parked threads in system prompt +5. **Fork agent prompt** — constrains fork agents from spawning subagents --- ## Promptable Agent Mode Switching -Build and Plan agents switch via `plan_enter`/`plan_exit` tools — see [agents.md](agents.md#promptable-mode-switching) for details. +Build/Plan agents switch via `plan_enter`/`plan_exit` tools with autonomous switching. See [agents.md](agents.md#promptable-mode-switching). --- ## Type Safety -~236 `any` types eliminated. Strong Zod schemas for all message types. 14 documented exceptions at SDK boundaries. - -| Area | Changes | -|------|---------| -| Strong Zod schemas | `JsonValue`, `ProviderMeta`, `ToolInput`, `ToolMeta` defined in message-v2.ts | -| z.any() elimination | All `z.any()` in message-v2.ts, config, permission, server routes replaced | -| SDK boundary casts | ~15 documented cast points (AI SDK, Drizzle, Bun/Node boundaries) | -| Remaining | 14 documented `any` at structural boundaries | +~236 `any` types eliminated. Strong Zod schemas (`JsonValue`, `ProviderMeta`, `ToolInput`, `ToolMeta`). 14 documented exceptions at SDK boundaries. --- ## Effect-TS Architecture -22 Effect services, dual-layer context model (InstanceALS + InstanceContext). See [EFFECTIFICATION.md](EFFECTIFICATION.md) for details. - -| Difference | Frankencode | Upstream | -|------------|-------------|----------| -| `src/project/instance.ts` | Deleted, split into InstanceALS + InstanceLifecycle + InstanceContext | Still has `instance-state.ts` using ScopedCache | -| ALS fallback patterns | 0 remaining (all 59 eliminated) | ~36 deferred | -| Test compatibility | `test/fixture/instance-shim.ts` for 58 test files | N/A | +22 Effect services, dual-layer context (InstanceALS + InstanceContext). See [EFFECTIFICATION.md](EFFECTIFICATION.md). --- ## Bug Fixes (64 total) -See `BUGS.md` at repo root for the complete bug tracker. - -| Range | Category | -|-------|----------| -| B1-B9 | Upstream backports (Phase 1) | -| B10-B16 | Upstream backports (Phase 2) | -| B17-B22 | Upstream app fixes (Phase 3) | -| B23-B52 | Code review fixes (CAS, circuit breaker, evaluator, session cleanup, etc.) | -| B53-B64 | QA rounds 1-6 (plugin hooks, markdown injection, MCP type mismatch, ripgrep, file count, processor timing) | +See `BUGS.md` at repo root. Ranges: B1-B22 (upstream backports + app fixes), B23-B52 (code review), B53-B64 (QA rounds). --- ## What Is NOT Different -These areas are identical to upstream OpenCode: - -- **API providers** — all 21+ providers, models.dev integration, transform pipeline (see [API_PROVIDERS.md](API_PROVIDERS.md)) -- **ACP support** — full ACP v1 protocol, same capabilities (see [AGENT_CLIENT_PROTOCOL.md](AGENT_CLIENT_PROTOCOL.md)) +- **API providers** — all 21+ providers, models.dev, transform pipeline — see [API_PROVIDERS.md](API_PROVIDERS.md) +- **ACP support** — full v1 protocol — see [AGENT_CLIENT_PROTOCOL.md](AGENT_CLIENT_PROTOCOL.md) - **Session/message format** — same MessageV2 schema (extended with EditMeta/LifecycleMeta) -- **Plugin system** — same plugin hooks (plus `context.edit.before`/`context.edit.after`) +- **Plugin system** — same hooks (plus `context.edit.before`/`context.edit.after`) - **Permission system** — same PermissionNext framework - ---- - -## Documentation Index - -| Document | What it covers | -|----------|---------------| -| [agents.md](agents.md) | Agent config, mode switching, fork agents, model recommendations | -| [context-editing.md](context-editing.md) | Edit operations, lifecycle markers, sweeper, slash commands | -| [schema.md](schema.md) | Database schema (4 new tables, part extensions) | -| [EFFECTIFICATION.md](EFFECTIFICATION.md) | Effect-TS services, layers, dual context | -| [API_PROVIDERS.md](API_PROVIDERS.md) | 21+ LLM providers | -| [AGENT_CLIENT_PROTOCOL.md](AGENT_CLIENT_PROTOCOL.md) | ACP v1 protocol for IDEs | -| [SECURITY_AUDIT.md](SECURITY_AUDIT.md) | CVEs, security issues | diff --git a/docs/README.md b/docs/README.md index bc0bfd2f5..c258f863f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,56 +1,122 @@ -# Frankencode Documentation +# Frankencode -> **Frankencode** is a fork of [OpenCode](https://github.com/anomalyco/opencode) that adds context editing, subagent tabs, fork agents, content-addressable storage, an edit graph, focus agents, side threads, and a verification/refinement loop. +A fork of [OpenCode](https://github.com/anomalyco/opencode) that adds subagent tabs, fork agents, context editing, and a verification/refinement loop. -## Documentation Map +--- -| Document | Description | -|----------|-------------| -| [FRANKENCODE.md](FRANKENCODE.md) | **Start here** — all Frankencode features, diff vs upstream, tab bar, fork agents, context editing | -| [context-editing.md](context-editing.md) | Context editing tools, lifecycle markers, and deterministic sweeper | -| [agents.md](agents.md) | Agents, mode switching, fork agents, model recommendations | -| [schema.md](schema.md) | Database schema changes (4 new tables, PartBase extensions) | -| [EFFECTIFICATION.md](EFFECTIFICATION.md) | Effect-TS architecture, 22 services, LayerMap, dual-layer context | -| [AGENT_CLIENT_PROTOCOL.md](AGENT_CLIENT_PROTOCOL.md) | ACP v1 protocol support for IDE integration | -| [API_PROVIDERS.md](API_PROVIDERS.md) | 21+ LLM providers, models.dev API, transform pipeline | -| [SECURITY_AUDIT.md](SECURITY_AUDIT.md) | CVEs, upstream security issues, Frankencode-specific vulnerabilities | -| [AI_ATTRIBUTION_POLICY.md](AI_ATTRIBUTION_POLICY.md) | AI tool attribution stripping policy, SAST checks | +## Why Frankencode? -## Architecture at a Glance +OpenCode is a powerful AI coding assistant. Frankencode extends it with features for **managing complex, long-running sessions** — where conversation context grows stale, multiple tasks run in parallel, and the LLM needs help staying focused. + +--- + +## Feature Comparison + +| Feature | OpenCode | Frankencode | +|---------|----------|-------------| +| **Subagent tabs** | One session at a time; subagents hidden | Tab bar: `Main │ + │ S1 │ F1` — see all agents | +| **Fork agents** | Fork creates independent session | `+` forks with conversation history, stays as child tab | +| **Context editing** | Full context always sent to LLM | Hide, replace, externalize stale content — LLM sees clean context | +| **Edit history** | None | DAG-based version history with checkout/fork (like git for context) | +| **Side threads** | None | Park off-topic findings, resume later across sessions | +| **Focus agents** | None | Classifier + focus agents auto-clean context | +| **Agent switching** | Tab cycles agents | Tab = tab bar, Shift+Tab = agents, LLM can switch autonomously | +| **Ctrl+C** | Single press exits (if input empty) | Double-press to exit (first press aborts + shows hint) | +| **Type safety** | ~250 `any` types | 14 documented exceptions (236 eliminated) | +| **Verify/refine** | None | Built-in test/lint/typecheck + evaluator-optimizer loop | + +--- + +## Subagent Tab Bar ``` - User / IDE Client - | - ACP (JSON-RPC/stdio) or TUI or HTTP API - | - TUI Tab Bar: Main │ + │ S1 │ F1 - | - InstanceLifecycle.boot(directory) - | - InstanceALS + InstanceContext (dual context) - | - +----+----+----+----+----+----+ - | | | | | | | - Session Provider Tools Agents Bus Config - | | | | - Prompt 21+ LLM 40+ classifier - Pipeline SDKs tools focus - | | evaluator - context_edit verify - filterEdited refine - sweeper thread_park - | - CAS + EditGraph - | - SQLite (Drizzle ORM) +Main │ + │ S1 │ S2 │ F1 ``` -## Tracking Documents (repo root) +| Key | Action | +|-----|--------| +| Tab | Toggle focus between tab bar and chat | +| ←/→ | Navigate tabs (shows session immediately) | +| ↓ / Escape | Return to chat | +| Enter/Space | Activate (fork if on `+`) | +| x | Kill agent | +| Shift+Tab | Cycle agent type (Build/Plan) | +| Ctrl+C | Abort all, then exit on second press | + +**Subagents (S1, S2)** — spawned by the LLM, auto-terminate when done. +**Fork agents (F1, F2)** — user-created via `+`, copy Main's history, yellow-colored, manually promptable, cannot spawn subagents. + +Details: [FRANKENCODE.md — Tab Bar](FRANKENCODE.md#tab-bar-and-subagent-tabs) + +--- + +## Context Editing + +The LLM's context grows stale as conversations get long. Frankencode lets the LLM (and user) **edit the conversation context** without losing the originals: + +- **Hide** — remove a part from LLM context (original saved to CAS) +- **Replace** — swap content with a new version +- **Externalize** — move verbose output to CAS, leave a compact summary +- **Annotate** — add notes to parts +- **Mark** — set lifecycle hints (auto-hide after N turns, pin, etc.) + +Originals are stored in a **content-addressable store** (SHA-256). All edits are tracked in a **DAG-based edit graph** with checkout and fork — like git for conversation context. + +Details: [context-editing.md](context-editing.md) + +--- + +## New Slash Commands + +| Command | What it does | +|---------|-------------| +| `/btw ` | Side conversation — forks session, answers without polluting main context | +| `/focus` | Auto-clean context: classify messages, externalize stale output, park side threads | +| `/classify` | Label messages by topic (main/side/mixed) | +| `/threads` | List parked side threads | +| `/history` | Show edit history for the session | +| `/reset-context` | Restore all parts to their original content | +| `/verify` | Run test/lint/typecheck with circuit breaker | + +--- + +## Architecture + +``` +User / IDE + │ +ACP or TUI or HTTP API + │ +Tab Bar: Main │ + │ S1 │ F1 + │ +InstanceLifecycle → InstanceALS + InstanceContext + │ +┌───┬───┬───┬───┬───┬───┐ +Session Provider Tools Agents Bus Config + │ │ │ │ +Prompt 21+ LLM 40+ classifier +Pipeline SDKs tools focus + │ │ evaluator +context_edit verify +filterEdited refine +sweeper thread_park + │ +CAS + EditGraph + │ +SQLite (Drizzle ORM) +``` + +--- + +## Documentation -| File | Purpose | -|------|---------| -| `BUGS.md` | Bug tracker (51 fixed, 0 open, 1 deferred) | -| `PLAN.md` | Feature roadmap and current work plan | -| `STATUS.md` | Project status snapshot | -| `WHAT_WE_DID.md` | Session work log | -| `GAP_ANALYSIS.md` | Target state vs current state | +| Document | Covers | +|----------|--------| +| [FRANKENCODE.md](FRANKENCODE.md) | Complete technical diff vs upstream — modules, tools, agents, schema, pipeline, keybindings, type safety, bugs | +| [agents.md](agents.md) | Agent configuration, mode switching, fork agents, model recommendations | +| [context-editing.md](context-editing.md) | Edit operations, lifecycle markers, sweeper, slash commands | +| [schema.md](schema.md) | Database schema (4 new tables, part extensions) | +| [EFFECTIFICATION.md](EFFECTIFICATION.md) | Effect-TS architecture, 22 services, dual context | +| [API_PROVIDERS.md](API_PROVIDERS.md) | 21+ LLM providers, models.dev, transform pipeline | +| [AGENT_CLIENT_PROTOCOL.md](AGENT_CLIENT_PROTOCOL.md) | ACP v1 protocol for IDE integration | +| [SECURITY_AUDIT.md](SECURITY_AUDIT.md) | CVEs, security issues |