From 2bc080312cf59736d380ec14a777fa22bd48cf3e Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 15 Jun 2026 16:11:12 +0000 Subject: [PATCH] docs: refresh planning map and api references Co-authored-by: rwliebs --- docs/README.md | 2 +- docs/SYSTEM_ARCHITECTURE.md | 26 ++-- docs/docs-index.yaml | 48 +++++--- docs/domains/api-reference.md | 14 ++- docs/domains/data-contracts-reference.md | 23 ++-- docs/domains/map-reference.md | 36 +++--- docs/domains/mutation-reference.md | 21 +++- docs/domains/planning-reference.md | 35 ++++-- docs/product/user-workflows-reference.md | 6 +- docs/reference/api-endpoints.md | 145 +++++++++++++++++++++-- 10 files changed, 269 insertions(+), 87 deletions(-) diff --git a/docs/README.md b/docs/README.md index be476c3..7141dcb 100644 --- a/docs/README.md +++ b/docs/README.md @@ -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 diff --git a/docs/SYSTEM_ARCHITECTURE.md b/docs/SYSTEM_ARCHITECTURE.md index 06783d3..4eaefc4 100644 --- a/docs/SYSTEM_ARCHITECTURE.md +++ b/docs/SYSTEM_ARCHITECTURE.md @@ -1,7 +1,7 @@ --- document_id: doc.system-architecture -last_verified: 2026-03-06 -tokens_estimate: 950 +last_verified: 2026-06-15 +tokens_estimate: 1050 tags: - architecture - system @@ -37,13 +37,13 @@ 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 uses the Claude Agent SDK for credentialed users, with Claude CLI fallback when no credential is extractable. Build agents run in-process via `@anthropic-ai/claude-agent-sdk`. ``` ┌─────────────────────────────────────────────────────────────┐ │ Electron Shell │ │ ┌──────────────────────────────────────────────────────┐ │ -│ │ Next.js 15 (standalone) │ │ +│ │ Next.js 16 (standalone) │ │ │ │ ┌──────────┐ ┌──────────┐ ┌───────────────────┐ │ │ │ │ │ React 19 │ │ API │ │ Claude Agent SDK │ │ │ │ │ │ UI │──│ Routes │──│ (in-process, │ │ │ @@ -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 | Claude Agent SDK `query()` or Claude CLI fallback (streaming + non-streaming) | `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` | @@ -106,12 +106,12 @@ 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 → claude-client → Agent SDK query() or Claude CLI fallback → stream-action-parser → PlanningAction[] → validate → apply → SQLite` Detail: [planning-reference.md](domains/planning-reference.md) ### Map -`GET /map → fetchMapSnapshot → PlanningState → buildMapTree → nested JSON for UI` +`GET /map → getProject + workflows + activities + cards → group by workflow/activity → nested JSON for UI` Detail: [map-reference.md](domains/map-reference.md) @@ -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 | +| Auth | `ANTHROPIC_API_KEY`, OAuth token, or Claude CLI auth fallback | `ANTHROPIC_API_KEY` | +| SDK | `@anthropic-ai/claude-agent-sdk` for credentials; `claude -p` fallback | `@anthropic-ai/claude-agent-sdk` | +| Call style | `query()` for credentials; CLI subprocess fallback | `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) | +| Tools | Agent SDK path: `WebSearch`; plus `Read`, `Glob`, `Grep` when repo cwd is available | Read, Write, Edit, Bash, Glob, Grep, WebFetch, WebSearch | +| CWD | Connected repo clone when available; otherwise none | `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) | +| Model | `claude-haiku-4-5-20251001` for Agent SDK; `claude-sonnet-4-6` CLI default; configurable | `claude-sonnet-4-5-20250929` (configurable) | --- diff --git a/docs/docs-index.yaml b/docs/docs-index.yaml index fc6899f..5bc6524 100644 --- a/docs/docs-index.yaml +++ b/docs/docs-index.yaml @@ -6,31 +6,31 @@ docs_index: documents: - id: doc.system-architecture path: SYSTEM_ARCHITECTURE.md - tokens_estimate: 1200 + tokens_estimate: 1050 tags: [architecture, system, overview] anchors: - 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 LLM → actions → SQLite; 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-06-15" - id: doc.data-contracts path: domains/data-contracts-reference.md - tokens_estimate: 1800 + tokens_estimate: 1850 tags: [schemas, types, api, contracts] anchors: - id: contract summary: "Zod schemas in lib/schemas/; slice-a/b/c + action-payloads" - id: core-entities - summary: "Project, Workflow, WorkflowActivity, Step, Card hierarchy" + summary: "Project, Workflow, WorkflowActivity, Card hierarchy" - id: actions summary: "PlanningAction payloads and target_ref per action_type" depends_on: [doc.system-architecture] - last_verified: "2026-02-18" + last_verified: "2026-06-15" - id: doc.design-system path: design/design-system.md @@ -44,7 +44,7 @@ docs_index: - id: doc.user-workflows path: product/user-workflows-reference.md - tokens_estimate: 900 + tokens_estimate: 1200 tags: [ux, workflows, user-journey] anchors: - id: workflow-a @@ -54,21 +54,21 @@ docs_index: - id: workflow-c summary: "Build trigger to draft PR: agents, checks, approval" depends_on: [doc.system-architecture] - last_verified: "2026-02-18" + last_verified: "2026-06-15" - id: doc.api-reference path: domains/api-reference.md - tokens_estimate: 400 + tokens_estimate: 550 tags: [api, endpoints] anchors: - id: endpoints - summary: "REST API under /api/projects; map, actions, artifacts, cards" + summary: "REST API groups: setup, GitHub, map, actions, chat, cards, orchestration" depends_on: [doc.system-architecture] - last_verified: "2026-02-18" + last_verified: "2026-06-15" - id: doc.planning path: domains/planning-reference.md - tokens_estimate: 700 + tokens_estimate: 900 tags: [planning, llm, chat] anchors: - id: contract @@ -76,11 +76,11 @@ 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-06-15" - id: doc.mutation path: domains/mutation-reference.md - tokens_estimate: 650 + tokens_estimate: 800 tags: [mutation, actions, pipeline] anchors: - id: contract @@ -88,19 +88,19 @@ docs_index: - id: pipeline summary: "validate-action → apply-action; idempotency via key" depends_on: [doc.system-architecture, doc.data-contracts] - last_verified: "2026-02-18" + last_verified: "2026-06-15" - id: doc.map path: domains/map-reference.md - tokens_estimate: 550 + tokens_estimate: 650 tags: [map, snapshot, story-map] anchors: - id: contract - summary: "Map = Project + Workflow→Activity→Step→Card tree; PlanningState" + summary: "Map = Project + Workflow→Activity→Card tree; PlanningState" - id: build - summary: "fetchMapSnapshot → PlanningState; buildMapTree → API response" + summary: "GET /map batches project/workflow/activity/card queries into nested response" depends_on: [doc.system-architecture, doc.data-contracts] - last_verified: "2026-02-18" + last_verified: "2026-06-15" - id: doc.orchestration path: domains/orchestration-reference.md @@ -180,6 +180,16 @@ docs_index: depends_on: [] last_verified: "2026-03-06" + - id: doc.planning-agent-auth-paths + path: adr/0016-planning-agent-two-auth-paths.md + tokens_estimate: 650 + tags: [planning, llm, auth, adr] + anchors: + - id: decision + summary: "Credentialed planning uses Agent SDK; Claude CLI remains fallback" + depends_on: [doc.planning] + last_verified: "2026-06-15" + - id: doc.desktop-build-distribution path: reference/desktop-build-and-distribution.md tokens_estimate: 600 diff --git a/docs/domains/api-reference.md b/docs/domains/api-reference.md index 14b6ec6..99f2c0e 100644 --- a/docs/domains/api-reference.md +++ b/docs/domains/api-reference.md @@ -1,7 +1,7 @@ --- document_id: doc.api-reference -last_verified: 2026-02-18 -tokens_estimate: 400 +last_verified: 2026-06-15 +tokens_estimate: 550 tags: - api - endpoints @@ -24,13 +24,21 @@ ttl_expires_on: null | Group | Base Path | Purpose | |-------|-----------|---------| | Projects | `/api/projects` | CRUD projects | -| Map | `/api/projects/[id]/map` | Canonical map snapshot | +| Setup | `/api/setup`, `/api/setup/status` | Local credential setup status and config writes | +| GitHub | `/api/github/*` | OAuth, token disconnect, user/repo lookup, repo creation | +| Map | `/api/projects/[id]/map` | Canonical Workflow → Activity → Card snapshot | | Actions | `/api/projects/[id]/actions` | Submit planning actions | | Chat | `/api/projects/[id]/chat`, `/chat/stream` | Planning LLM | | Artifacts | `/api/projects/[id]/artifacts` | Context artifacts | +| Card finalize | `/api/projects/[id]/cards/[cardId]/finalize` | Card finalization package and SSE finalization | | Card knowledge | `/api/projects/[id]/cards/[cardId]/{requirements,facts,assumptions,questions}` | Knowledge items | | Planned files | `/api/projects/[id]/cards/[cardId]/planned-files` | Card planned files | +| Card context links | `/api/projects/[id]/cards/[cardId]/context-artifacts` | Context artifacts linked to a card | +| Card outputs | `/api/projects/[id]/cards/[cardId]/produced-files`, `/push` | Changed files and feature-branch push | | Files | `/api/projects/[id]/files` | File tree (planned or repo); `?source=repo` for produced code | +| Repository sync | `/api/projects/[id]/repo/sync` | Align local clone default branch with GitHub | +| Memory | `/api/projects/[id]/memory` | Project memory units and local storage paths | +| Orchestration | `/api/projects/[id]/orchestration/*` | Build runs, assignments, checks, approvals, PR candidates | ## Related - [data-contracts-reference.md](data-contracts-reference.md) diff --git a/docs/domains/data-contracts-reference.md b/docs/domains/data-contracts-reference.md index f748f15..f440be2 100644 --- a/docs/domains/data-contracts-reference.md +++ b/docs/domains/data-contracts-reference.md @@ -1,7 +1,7 @@ --- document_id: doc.data-contracts -last_verified: 2026-02-18 -tokens_estimate: 1800 +last_verified: 2026-06-15 +tokens_estimate: 1850 tags: - schemas - types @@ -11,7 +11,7 @@ anchors: - id: contract summary: "Zod schemas in lib/schemas/; slice-a/b/c + action-payloads" - id: core-entities - summary: "Project, Workflow, WorkflowActivity, Step, Card hierarchy" + summary: "Project, Workflow, WorkflowActivity, Card hierarchy" - id: card-context summary: "ContextArtifact, CardPlannedFile, knowledge items" - id: actions @@ -53,9 +53,7 @@ ttl_expires_on: null Project └── Workflow[] (position-ordered) └── WorkflowActivity[] (position-ordered) - ├── Step[] (position-ordered) - │ └── Card[] (step_id or activity-level) - └── Card[] (activity-level, no step) + └── Card[] (position/priority-ordered) ``` ### Project @@ -91,13 +89,13 @@ Project |-------|------|-------| | id | uuid | | | workflow_activity_id | uuid | | -| step_id | uuid \| null | optional, for step-scoped cards | | title | string (min 1) | | | description | string \| null | optional | | status | enum | todo\|active\|questions\|review\|production | | priority | int | | | position | int | | | quick_answer | string \| null | optional | +| finalized_at | datetime \| null | set by card finalization endpoint | --- @@ -147,18 +145,23 @@ All actions: `{ id, project_id, action_type, target_ref, payload }` | action_type | target_ref | payload | |-------------|------------|---------| -| updateProject | `{ project_id }` | `{ name?, description? }` | +| updateProject | `{ project_id }` | `{ name?, description?, customer_personas?, tech_stack?, deployment?, design_inspiration? }` | | createWorkflow | `{ project_id }` | `{ title, description?, position }` | | createActivity | `{ workflow_id }` | `{ title, color?, position }` | | createCard | `{ workflow_activity_id }` | `{ title, description?, status, priority, position }` | | updateCard | `{ card_id }` | `{ title?, description?, status?, priority?, quick_answer? }` | | reorderCard | `{ card_id }` | `{ new_position }` | +| deleteWorkflow | `{ workflow_id }` | `{}` | +| deleteActivity | `{ workflow_activity_id }` | `{}` | +| deleteCard | `{ card_id }` | `{}` | | linkContextArtifact | `{ card_id }` | `{ context_artifact_id, linked_by?, usage_hint? }` | | createContextArtifact | `{ project_id }` | `{ name, type, title?, content, card_id? }` | | upsertCardPlannedFile | `{ card_id }` | `{ logical_file_name, artifact_kind, action, intent_summary, contract_notes?, position, planned_file_id? }` | -| approveCardPlannedFile | `{ card_id }` | `{ planned_file_id, status: "approved"\|"proposed" }` | | upsertCardKnowledgeItem | `{ card_id }` | `{ item_type, text, evidence_source?, confidence?, position, knowledge_item_id? }` | -| setCardKnowledgeStatus | `{ card_id }` | `{ knowledge_item_id, status }` | + +Notes: +- Planned-file approval is a card planned-file REST update (`PATCH /api/projects/[projectId]/cards/[cardId]/planned-files/[fileId]`), not a PlanningAction. +- Knowledge-item status changes are handled by the relevant knowledge-item REST routes, not a PlanningAction. --- diff --git a/docs/domains/map-reference.md b/docs/domains/map-reference.md index b3e0dc0..feb6b7c 100644 --- a/docs/domains/map-reference.md +++ b/docs/domains/map-reference.md @@ -1,16 +1,16 @@ --- document_id: doc.map -last_verified: 2026-02-18 -tokens_estimate: 550 +last_verified: 2026-06-15 +tokens_estimate: 650 tags: - map - snapshot - story-map anchors: - id: contract - summary: "Map = Project + Workflow→Activity→Step→Card tree; PlanningState in memory" + summary: "Map = Project + Workflow→Activity→Card tree; PlanningState in memory" - id: build - summary: "fetchMapSnapshot → PlanningState; buildMapTree → nested API response" + summary: "GET /map batches project/workflow/activity/card queries into nested API response" - id: queries summary: "getWorkflowsByProject, getActivitiesByProject, getCardsByProject" ttl_expires_on: null @@ -22,12 +22,12 @@ ttl_expires_on: null ## Contract ### Invariants -- INVARIANT: Map structure: Project → Workflow[] → WorkflowActivity[] → Step[] → Card[] -- INVARIANT: Cards belong to activity; optionally to step (step_id) +- INVARIANT: Map structure: Project → Workflow[] → WorkflowActivity[] → Card[] +- INVARIANT: Cards belong directly to a workflow activity via `workflow_activity_id` - INVARIANT: PlanningState uses Map for O(1) lookup during validation ### Boundaries -- ALLOWED: fetchMapSnapshot, buildMapTree; queries via DbAdapter +- ALLOWED: `fetchMapSnapshot` for planning state; map route response assembly via DbAdapter queries - FORBIDDEN: Building map from ad-hoc queries; bypassing PlanningState shape --- @@ -36,37 +36,41 @@ ttl_expires_on: null ### Data Shape - **PlanningState**: In-memory; used by validate-action, apply-action, chat -- **Map API response**: Nested tree for UI; `workflows[].activities[].steps[].cards` + activity-level cards +- **Map API response**: Nested tree for UI; `workflows[].activities[].cards` ### Build Flow ``` GET /api/projects/[id]/map + → getProject, getWorkflowsByProject, getActivitiesByProject, getCardsByProject + → group activities by workflow_id + → group cards by workflow_activity_id + → nested JSON: project + workflows[].activities[].cards + +Chat/planning endpoints use: → fetchMapSnapshot(db, projectId) - → getProject, getWorkflowsByProject, getActivitiesByProject, getCardsByProject, getArtifactsByProject, getCardContextLinksByProject + → getProject, workflows, activities, cards, artifacts, card context links, requirements, planned files → createEmptyPlanningState + populate Maps - → buildMapTree(state) → nested JSON ``` ### Key Files | File | Purpose | |------|---------| -| `lib/db/map-snapshot.ts` | fetchMapSnapshot, buildMapTree | +| `lib/db/map-snapshot.ts` | fetchMapSnapshot for PlanningState used by chat/planning | | `lib/schemas/planning-state.ts` | PlanningState interface, createEmptyPlanningState | | `lib/db/queries.ts` | getProject, getWorkflowsByProject, getActivitiesByProject, getCardsByProject | -| `lib/db/queries/workflows.ts` | Workflow + activity + step tree queries | -| `app/api/projects/[id]/map/route.ts` | Map endpoint | +| `app/api/projects/[id]/map/route.ts` | UI map endpoint; assembles nested workflow/activity/card response | ### Tree Structure - Workflows ordered by position - Activities ordered by position within workflow -- Steps ordered by position within activity -- Cards: step-scoped (step_id) or activity-level (step_id null) +- Cards ordered by priority within activity in the map response +- The Step layer was removed; do not introduce `step_id` in new map contracts --- ## Verification - [ ] Map snapshot matches DB state after actions applied -- [ ] buildMapTree produces valid nested structure for UI +- [ ] `GET /api/projects/[id]/map` returns workflows with activities and cards only - [ ] PlanningState sufficient for validate-action refs ## Related diff --git a/docs/domains/mutation-reference.md b/docs/domains/mutation-reference.md index be8a15a..e4b6941 100644 --- a/docs/domains/mutation-reference.md +++ b/docs/domains/mutation-reference.md @@ -1,7 +1,7 @@ --- document_id: doc.mutation -last_verified: 2026-02-18 -tokens_estimate: 650 +last_verified: 2026-06-15 +tokens_estimate: 800 tags: - mutation - actions @@ -52,6 +52,23 @@ PlanningAction[] → validateAction() → [errors] | [] - For each action: validate against state → mutate state → persist via adapter - Increment project action_sequence on success +### PlanningAction Inventory + +Map/planning mutations accepted by `lib/schemas/slice-a.ts` and applied by `lib/db/mutations.ts`: + +| Category | Action types | +|----------|--------------| +| Project | `updateProject` | +| Map create/update | `createWorkflow`, `createActivity`, `createCard`, `updateCard`, `reorderCard` | +| Map delete | `deleteWorkflow`, `deleteActivity`, `deleteCard` | +| Context | `createContextArtifact`, `linkContextArtifact` | +| Card planning | `upsertCardPlannedFile`, `upsertCardKnowledgeItem` | + +Non-actions: +- Planned-file approval uses `PATCH /api/projects/[projectId]/cards/[cardId]/planned-files/[fileId]`. +- Knowledge-item status edits use the specific requirements/facts/assumptions/questions routes. +- The Step layer is removed; no mutation path should emit `createStep` or target `step_id`. + ### Key Files | File | Purpose | |------|---------| diff --git a/docs/domains/planning-reference.md b/docs/domains/planning-reference.md index 34afdf5..c665ff9 100644 --- a/docs/domains/planning-reference.md +++ b/docs/domains/planning-reference.md @@ -1,7 +1,7 @@ --- document_id: doc.planning -last_verified: 2026-03-06 -tokens_estimate: 750 +last_verified: 2026-06-15 +tokens_estimate: 900 tags: - planning - llm @@ -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 → Agent SDK or CLI fallback → stream-action-parser → actions" ttl_expires_on: null --- # Planning Domain Reference @@ -39,7 +39,7 @@ ttl_expires_on: null | Mode | When | Output | |------|------|--------| | scaffold | Map empty or no workflows | updateProject + createWorkflow only | -| populate | Workflows exist, activities/cards sparse | createActivity, createStep, createCard | +| populate | Workflows exist, activities/cards sparse | createActivity, createCard | | full | Map has structure | All action types; refinements, links, planned files | | finalize | Map fully planned; user triggers | createContextArtifact (project docs + card e2e tests) | @@ -49,20 +49,34 @@ 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.ts + → credential found: Agent SDK query() via planning-sdk-runner.ts + → no credential + Claude CLI available: claude -p fallback → stream-action-parser (parse JSON blocks) → PlanningAction[] emitted → POST /actions (validate + apply) ``` +Credentialed planning always uses `@anthropic-ai/claude-agent-sdk` `query()`. +Tool availability is based on repository context: +- Repo connected (`cwd` provided): `Read`, `Glob`, `Grep`, `WebSearch` +- No repo context: `WebSearch` +- CLI fallback has no managed read tools; it receives the system prompt and user message via stdin. + ### Per-Card Finalize Flow ``` -User clicks "Finalize" on card → POST /cards/[cardId]/finalize - → Assemble: project-wide docs + card context + e2e tests +User opens finalize panel → GET /cards/[cardId]/finalize + → Assemble: project-wide docs + linked card context + requirements + planned files → Return finalization package for review - → User edits (optional) - → POST /cards/[cardId]/finalize/confirm + +User clicks "Finalize" on card → POST /cards/[cardId]/finalize + → Validate project.finalized_at + → Validate card has at least one requirement + → Validate card has at least one planned file/folder + → Link project-wide docs to the card + → Generate e2e test artifact via LLM when planning LLM is enabled → Set card.finalized_at → card is build-ready + → Stream SSE events: finalize_progress, action, error, done ``` ### Key Files @@ -71,7 +85,8 @@ 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/claude-client.ts` | Planning LLM routing: Agent SDK for credentials; Claude CLI fallback | +| `lib/llm/planning-sdk-runner.ts` | Agent SDK `query()` wrapper and read-only planning tool policy | | `lib/llm/planning-credential.ts` | Resolves ANTHROPIC_API_KEY from env or ~/.dossier/config | | `app/api/projects/[id]/chat/route.ts` | Non-streaming chat | | `app/api/projects/[id]/chat/stream/route.ts` | Streaming chat (scaffold, populate, finalize) | diff --git a/docs/product/user-workflows-reference.md b/docs/product/user-workflows-reference.md index 3c0eae4..c280ce6 100644 --- a/docs/product/user-workflows-reference.md +++ b/docs/product/user-workflows-reference.md @@ -1,6 +1,6 @@ --- document_id: doc.user-workflows -last_verified: 2026-03-28 +last_verified: 2026-06-15 tokens_estimate: 1200 tags: - ux @@ -22,7 +22,7 @@ ttl_expires_on: null ## Contract ### Invariants -- INVARIANT: Map structure is Workflow → Activity → Step → Card; all mutations via PlanningAction +- INVARIANT: Map structure is Workflow → Activity → Card; all mutations via PlanningAction - INVARIANT: Build cannot trigger without finalized cards (planned files or folders are required; user must approve at least one per card before finalization. For new builds, the agent may propose folder paths (e.g. components/auth/) where files should go.) - INVARIANT: Project must be finalized before cards can be finalized - INVARIANT: Build cannot trigger without card.finalized_at set (card finalization confirmed) @@ -258,7 +258,7 @@ Workflows for evolving software that already exists (codebase in a repo). | Step | Actor | Action | |------|-------|--------| | 1 | User | Describes new functionality via chat (e.g. "add a workflow for exporting data", "add a card for bulk delete under Manage Items") | -| 2 | Planning LLM | Creates workflows, activities, steps, or cards in the appropriate place | +| 2 | Planning LLM | Creates workflows, activities, or cards in the appropriate place | | 3 | User | Edits map (reorder, refine); links context artifacts | | 4 | User | Finalizes new cards; triggers build | | 5 | Agent | Implements new functionality; may create new files or extend existing ones | diff --git a/docs/reference/api-endpoints.md b/docs/reference/api-endpoints.md index 692099b..ddd48ee 100644 --- a/docs/reference/api-endpoints.md +++ b/docs/reference/api-endpoints.md @@ -218,7 +218,7 @@ Common statuses: ### GET /api/projects/[projectId]/map -Canonical map snapshot: Workflow → WorkflowActivity → Step → Card tree. +Canonical UI map snapshot: Workflow → WorkflowActivity → Card tree. **Response:** `200` ```json @@ -230,8 +230,9 @@ Canonical map snapshot: Workflow → WorkflowActivity → Step → Card tree. "activities": [ { "id", "workflow_id", "title", "color", "position", - "steps": [{ "id", "title", "position", "cards": [...] }], - "cards": [] + "cards": [ + { "id", "workflow_activity_id", "title", "status", "priority", "build_state" } + ] } ] } @@ -255,7 +256,7 @@ Submit planning actions. Validates, applies, and persists. Rejects on first fail "actions": [ { "id": "uuid (optional)", - "action_type": "createWorkflow|createActivity|createStep|createCard|updateCard|reorderCard|linkContextArtifact|upsertCardPlannedFile|approveCardPlannedFile|upsertCardKnowledgeItem|setCardKnowledgeStatus", + "action_type": "updateProject|createWorkflow|createActivity|createCard|updateCard|reorderCard|deleteWorkflow|deleteActivity|deleteCard|linkContextArtifact|createContextArtifact|upsertCardPlannedFile|upsertCardKnowledgeItem", "target_ref": {}, "payload": {} } @@ -271,18 +272,72 @@ Submit planning actions. Validates, applies, and persists. Rejects on first fail |--------|-------------| | `createWorkflow` | Create a new workflow in the project | | `createActivity` | Create a workflow activity | -| `createStep` | Create a step within an activity | -| `createCard` | Create a card in a step or activity | +| `createCard` | Create a card in an activity | | `updateCard` | Update card title, description, status, or priority | -| `reorderCard` | Move card to new step/position | +| `reorderCard` | Move card to a new position within its activity | +| `deleteWorkflow` | Delete a workflow | +| `deleteActivity` | Delete a workflow activity | +| `deleteCard` | Delete a card | | `linkContextArtifact` | Link a context artifact to a card | +| `createContextArtifact` | Create project context, optionally linked to a card | | `upsertCardPlannedFile` | Create or update a planned file for a card | -| `approveCardPlannedFile` | Approve or revert a planned file | | `upsertCardKnowledgeItem` | Create or update a requirement, fact, assumption, or question | -| `setCardKnowledgeStatus` | Set status (draft/approved/rejected) on a knowledge item | Code-generation intents are rejected. +Planned-file approval and knowledge-item status edits use their REST routes; they are not PlanningAction types. + +--- + +## Planning Chat & Finalization + +### POST /api/projects/[projectId]/chat + +Non-streaming planning chat. Applies generated PlanningAction records directly. + +**Request body:** +```json +{ + "message": "Describe the product or requested change", + "mode": "scaffold|populate|finalize (optional)", + "workflow_id": "uuid (required for targeted populate)", + "mock_response": "string (tests only)" +} +``` + +**Response:** `200` +```json +{ + "status": "success", + "responseType": "clarification|actions|mixed", + "message": "string", + "applied": 2, + "workflow_ids_created": ["uuid"] +} +``` + +### POST /api/projects/[projectId]/chat/stream + +Streaming planning endpoint. Returns Server-Sent Events for scaffold, populate, full planning, and project finalize flows. + +Common SSE events include `phase_start`, `action`, `phase_complete`, `error`, and `done`. + +### GET /api/projects/[projectId]/cards/[cardId]/finalize + +Assembles the card finalization package: card, project docs (`doc|spec|design` artifacts), linked card artifacts, requirements, planned files, and existing `finalized_at`. + +### POST /api/projects/[projectId]/cards/[cardId]/finalize + +Finalizes a card and streams SSE progress. + +Constraints: +- Project must already have `finalized_at`. +- Card must have at least one requirement. +- Card must have at least one planned file or folder. +- Planning LLM must be enabled to generate the e2e test artifact. + +SSE events: `finalize_progress`, `action`, `error`, `done`. + --- ## Context Artifacts @@ -301,7 +356,7 @@ Create artifact. Requires at least one of: `content`, `uri`, `integration_ref`. ```json { "name": "string", - "type": "doc|design|code|research|link|image|skill|mcp|cli|api|prompt|spec|runbook", + "type": "doc|design|code|research|link|image|skill|mcp|cli|api|prompt|spec|runbook|test", "title": "string|null", "content": "string|null", "uri": "string|null", @@ -325,6 +380,12 @@ Update artifact. All fields optional. Delete artifact. **Response:** `204` +### GET /api/projects/[projectId]/cards/[cardId]/context-artifacts + +List context artifacts currently linked to a card. The route verifies the card belongs to the project, then resolves each card-artifact link to the underlying artifact. + +**Response:** `200` — Array of ContextArtifact + --- ## Card Knowledge Items @@ -406,6 +467,39 @@ Delete planned file. --- +## Card Build Outputs & Push + +### GET /api/projects/[projectId]/cards/[cardId]/produced-files + +Returns files added or modified by the latest completed build assignment for the card. + +**Response:** `200` +```json +[ + { "path": "app/page.tsx", "status": "modified" } +] +``` + +If the card has no completed build assignment, returns `[]`. + +### POST /api/projects/[projectId]/cards/[cardId]/push + +Pushes the card's completed build feature branch from the local clone to the configured GitHub remote. + +Constraints: +- Project must have a non-placeholder `repo_url`. +- Card must have a completed build assignment with a feature branch. +- GitHub credentials must be configured for `pushBranch`. + +Common statuses: +- `200` `{ "success": true, "branch": "feature/..." }` +- `400` repository not connected +- `401` GitHub token missing/invalid for push +- `409` no completed build for the card +- `502` upstream git push failed + +--- + ## Project Files (Planned + Repository) ### GET /api/projects/[projectId]/files @@ -467,6 +561,37 @@ Use this after merging PRs on GitHub so subsequent builds branch from an up-to-d --- +## Memory + +### GET /api/projects/[projectId]/memory + +Returns memory units stored for the project and the local storage paths used by SQLite and RuVector. + +**Response:** `200` +```json +{ + "projectId": "uuid", + "count": 1, + "units": [ + { + "id": "uuid", + "title": "Authentication decisions", + "content_type": "text", + "status": "active", + "updated_at": "2026-06-15T00:00:00.000Z", + "content_preview": "Use OAuth...", + "link_url": null + } + ], + "storage": { + "sqlite": "/home/user/.dossier/dossier.db", + "ruvector": "/home/user/.dossier/ruvector/vectors.db" + } +} +``` + +--- + ## Orchestration Coordination ### Build Trigger