Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ docs/
│ └── design-system.md
│
├── adr/ # Architecture Decision Records
│ └── 0001-*.md through 0015-*.md
│ └── 0001-*.md through 0016-*.md
│
├── Feature Plans/ # Future feature plans
│ ├── claude-plugin-packaging.md
Expand Down
24 changes: 12 additions & 12 deletions docs/SYSTEM_ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
document_id: doc.system-architecture
last_verified: 2026-03-06
last_verified: 2026-04-20
tokens_estimate: 950
tags:
- architecture
Expand Down Expand Up @@ -37,7 +37,7 @@ ttl_expires_on: null

## Overview

Single-user desktop app. Next.js serves UI + API. Electron wraps it. SQLite stores all state locally. RuVector stores embeddings locally. Anthropic API provides LLM. Build agents run in-process via `@anthropic-ai/claude-agent-sdk`.
Single-user desktop app. Next.js serves UI + API. Electron wraps it. SQLite stores all state locally. RuVector stores embeddings locally. Planning and build both use Claude agent tooling, with a CLI fallback for planning when no extractable credential is available.

```
┌─────────────────────────────────────────────────────────────┐
Expand Down Expand Up @@ -73,7 +73,7 @@ Single-user desktop app. Next.js serves UI + API. Electron wraps it. SQLite stor
| UI | React 19 + Tailwind v4 + shadcn/ui | `app/`, `components/` |
| API | Next.js App Router (route handlers) | `app/api/` |
| Database | SQLite via better-sqlite3 (local, no Supabase) | `lib/db/` |
| Planning LLM | Anthropic Claude (streaming + non-streaming) | `lib/llm/` |
| Planning LLM | Agent SDK `query()`/streaming (credentialed) + Claude CLI fallback | `lib/llm/` |
| Build agents | `@anthropic-ai/claude-agent-sdk` `query()` (streaming, in-process) | `lib/orchestration/` |
| Agent definitions | agentic-flow registry (system prompts only) | `node_modules/agentic-flow/` |
| Embeddings | all-MiniLM-L6-v2 (ONNX WASM, local) | `lib/memory/embedding.ts` |
Expand Down Expand Up @@ -106,7 +106,7 @@ Full schema details: [data-contracts-reference.md](domains/data-contracts-refere
## Data Flow (Summaries)

### Planning
`User chat → Anthropic streaming API → stream-action-parser → PlanningAction[] → validate → apply → SQLite`
`User chat → planning SDK/CLI execution → stream-action-parser → PlanningAction[] → validate → apply → SQLite`

Detail: [planning-reference.md](domains/planning-reference.md)

Expand Down Expand Up @@ -138,14 +138,14 @@ Two distinct connection patterns exist.

| Concern | Planning LLM | Build Agent |
|---------|-------------|-------------|
| Auth | `ANTHROPIC_API_KEY` | `ANTHROPIC_API_KEY` |
| SDK | `@anthropic-ai/sdk` (Messages API) | `@anthropic-ai/claude-agent-sdk` |
| Call style | `messages.create` / `messages.stream` | `query()` — async iterator |
| Streaming | Optional (non-streaming for simple calls, streaming for chat) | Always streaming (`for await` over messages) |
| Tools | None (text output only) | Read, Write, Edit, Bash, Glob, Grep, WebFetch, WebSearch |
| CWD | N/A | `worktree_path` (repo clone) |
| Lifecycle | Request-response per chat turn | Fire-and-forget; result via in-process webhook callback |
| Model | `claude-haiku-4-5-20251001` (configurable) | `claude-sonnet-4-5-20250929` (configurable) |
| Auth | Credential from env/config/Claude settings (`ANTHROPIC_API_KEY` or token); CLI fallback when no extractable credential | `ANTHROPIC_API_KEY` |
| SDK/runtime | `@anthropic-ai/claude-agent-sdk` (primary) + `claude -p` fallback | `@anthropic-ai/claude-agent-sdk` |
| Call style | `query()` / async iterator (SDK) or CLI subprocess | `query()` — async iterator |
| Streaming | SDK iterator streaming; CLI `stream-json` fallback | Always streaming (`for await` over messages) |
| Tools | `WebSearch` always; `Read/Glob/Grep` only when repo `cwd` is available | Read, Write, Edit, Bash, Glob, Grep, WebFetch, WebSearch |
| CWD | Optional clone path when repo connected | `worktree_path` (repo clone) |
| Lifecycle | Request-response per chat turn; planner may do multi-turn tool loops before final JSON | Fire-and-forget; result via in-process webhook callback |
| Model | `claude-haiku-4-5-20251001` SDK default; CLI default `claude-sonnet-4-6` (both configurable) | `claude-sonnet-4-5-20250929` (configurable) |

---

Expand Down
20 changes: 15 additions & 5 deletions docs/docs-index.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ docs_index:
- id: overview
summary: "Self-deployable Next.js app; SQLite + agentic-flow + RuVector"
- id: data-flow
summary: "Planning LLM → actions → DbAdapter; Build → orchestration → agents"
summary: "Planning SDK/CLI → actions → DbAdapter; Build → orchestration → agents"
- id: endpoints
summary: "REST API under /api/projects; map, actions, artifacts, cards"
depends_on: []
last_verified: "2026-02-18"
last_verified: "2026-04-20"

- id: doc.data-contracts
path: domains/data-contracts-reference.md
Expand Down Expand Up @@ -76,7 +76,7 @@ docs_index:
- id: modes
summary: "Scaffold, populate, full; mode selected by map state"
depends_on: [doc.system-architecture, doc.data-contracts]
last_verified: "2026-02-18"
last_verified: "2026-04-20"

- id: doc.mutation
path: domains/mutation-reference.md
Expand Down Expand Up @@ -110,9 +110,9 @@ docs_index:
- id: contract
summary: "OrchestrationRun → CardAssignment; checks before approval; PR user-gated"
- id: flow
summary: "createRun → assignments → agentic-flow → checks → approval → PR"
summary: "clone/sync → createRun → assignments → agentic-flow → checks → approval → PR"
depends_on: [doc.system-architecture, doc.data-contracts]
last_verified: "2026-02-18"
last_verified: "2026-04-20"

- id: doc.testing
path: testing-reference.md
Expand Down Expand Up @@ -189,3 +189,13 @@ docs_index:
summary: "Desktop installers workflow: manual or on v* tag; download .exe, .deb, .dmg"
depends_on: [doc.releases-distribution]
last_verified: "2026-03-06"

- id: doc.adr-0016-planning-auth-paths
path: adr/0016-planning-agent-two-auth-paths.md
tokens_estimate: 500
tags: [adr, planning, llm, auth]
anchors:
- id: decision
summary: "Planning uses Agent SDK for credentialed users, CLI fallback when no extractable credential exists"
depends_on: [doc.system-architecture, doc.planning]
last_verified: "2026-04-20"
8 changes: 5 additions & 3 deletions docs/domains/orchestration-reference.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
document_id: doc.orchestration
last_verified: 2026-03-06
last_verified: 2026-04-20
tokens_estimate: 950
tags:
- orchestration
Expand All @@ -10,7 +10,7 @@ anchors:
- id: contract
summary: "OrchestrationRun → CardAssignment; checks before approval; PR user-gated"
- id: flow
summary: "createRun → assignments → agentic-flow → checks → approval → PR"
summary: "clone/sync → createRun → assignments → agentic-flow → checks → approval → PR"
- id: policy
summary: "SystemPolicyProfile: required_checks, protected_paths, forbidden_paths"
ttl_expires_on: null
Expand Down Expand Up @@ -38,6 +38,7 @@ ttl_expires_on: null
```
User trigger (card | workflow)
→ ensureClone (repo to ~/.dossier/repos/<projectId>/) — single-card only for MVP
→ optional repo sync (`POST /api/projects/[projectId]/repo/sync`) to fast-forward local base branch from origin
→ createRun (validate policy, capture snapshots; worktree_root = clone path)
→ createFeatureBranch per card
→ createAssignment per card (feature_branch, worktree_path, allowed_paths, forbidden_paths)
Expand Down Expand Up @@ -75,11 +76,12 @@ dispatch.ts → createAgenticFlowClient() → SDK query()
### Key Files
| File | Purpose |
|------|---------|
| `lib/orchestration/repo-manager.ts` | ensureClone, createFeatureBranch; clone to ~/.dossier/repos/ |
| `lib/orchestration/repo-manager.ts` | ensureClone, syncMainBranch, createFeatureBranch; clone to ~/.dossier/repos/ |
| `lib/orchestration/repo-reader.ts` | getRepoFileTree, getChangedFiles, getFileContent, getFileDiff |
| `lib/orchestration/create-run.ts` | createRun; policy validation; snapshot capture |
| `lib/orchestration/create-assignment.ts` | CardAssignment per card |
| `lib/orchestration/trigger-build.ts` | Entry point; clones repo, creates branch, populates worktree_path |
| `app/api/projects/[projectId]/repo/sync/route.ts` | User-triggered base branch sync endpoint before subsequent builds |
| `lib/orchestration/dispatch.ts` | Dispatch to agentic-flow |
| `lib/orchestration/execute-checks.ts` | Run required checks |
| `lib/orchestration/approval-gates.ts` | Check pass before approval request |
Expand Down
20 changes: 15 additions & 5 deletions docs/domains/planning-reference.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
document_id: doc.planning
last_verified: 2026-03-06
last_verified: 2026-04-20
tokens_estimate: 750
tags:
- planning
Expand All @@ -12,7 +12,7 @@ anchors:
- id: modes
summary: "Scaffold, populate, full; mode selected by map state"
- id: flow
summary: "Chat → Claude → stream-action-parser → actions"
summary: "Chat → Planning SDK/CLI → stream-action-parser → actions"
ttl_expires_on: null
---
# Planning Domain Reference
Expand Down Expand Up @@ -49,12 +49,20 @@ Mode selected by `lib/llm/planning-prompt.ts` based on map state.
```
User message → POST /chat/stream
→ buildPlanningSystemPrompt() | buildScaffoldSystemPrompt() | buildPopulateSystemPrompt() | buildFinalizeSystemPrompt()
→ Claude API (streaming)
→ claude-client (Agent SDK query/stream for credentialed users; CLI fallback when no extractable credential)
→ stream-action-parser (parse JSON blocks)
→ PlanningAction[] emitted
→ POST /actions (validate + apply)
```

### Auth and execution paths
- Primary path: `runPlanningQuery()` / `streamPlanningQuery()` from `planning-sdk-runner.ts` using `@anthropic-ai/claude-agent-sdk`.
- Credential resolution order: env `ANTHROPIC_API_KEY` → `~/.dossier/config` → `~/.claude/settings.json` (`ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN`).
- CLI fallback: when no extractable credential is available but `claude` CLI is installed/authenticated.
- Planning tool access depends on repo context (`cwd`), not credential type:
- Repo connected: `Read`, `Glob`, `Grep`, `WebSearch`
- No repo connected: `WebSearch` only

### Per-Card Finalize Flow
```
User clicks "Finalize" on card → POST /cards/[cardId]/finalize
Expand All @@ -71,8 +79,9 @@ User clicks "Finalize" on card → POST /cards/[cardId]/finalize
| `lib/llm/planning-prompt.ts` | System prompts; mode selection |
| `lib/llm/stream-action-parser.ts` | Parse streaming JSON → actions |
| `lib/llm/build-preview-response.ts` | Preview response before apply |
| `lib/llm/claude-client.ts` | Planning LLM client (Messages API) |
| `lib/llm/planning-credential.ts` | Resolves ANTHROPIC_API_KEY from env or ~/.dossier/config |
| `lib/llm/claude-client.ts` | Planning client orchestrator (SDK primary path + CLI fallback) |
| `lib/llm/planning-sdk-runner.ts` | Agent SDK `query()` / streaming execution and planning tool policy |
| `lib/llm/planning-credential.ts` | Resolves planning credential from env/config/Claude CLI settings |
| `app/api/projects/[id]/chat/route.ts` | Non-streaming chat |
| `app/api/projects/[id]/chat/stream/route.ts` | Streaming chat (scaffold, populate, finalize) |
| `app/api/projects/[id]/cards/[cardId]/finalize/route.ts` | Per-card finalize endpoint |
Expand All @@ -88,6 +97,7 @@ User clicks "Finalize" on card → POST /cards/[cardId]/finalize
- [ ] No action proposes code generation (validate-action rejects)
- [ ] Prompt instructs LLM to use existing IDs from context
- [ ] User actions follow-up after populate (agent prompts for View Details, Build, etc.)
- [ ] Planning credential routing stays two-path (Agent SDK or CLI fallback); no Messages API routing in planning

## Related
- [mutation-reference.md](mutation-reference.md)