Commit Graph

83 Commits

Author SHA1 Message Date
Lukas May
2b06f9627b feat: Add addAccountByToken tRPC mutation with upsert logic
Adds the addAccountByToken procedure to accountProcedures(), which
accepts an email and raw OAuth token, stores the token as claudeAiOauth
credentials, and upserts the account (create or updateAccountAuth based
on findByEmail). Covers the four scenarios with unit tests: new account,
existing account, empty email, and empty token validation errors.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 20:58:44 +01:00
Lukas May
f19aac0a76 refactor: Remove dead lastEventId from subscription schemas and document at-most-once delivery
Strip the unused .input(z.object({ lastEventId })) from all 6 subscription
procedures — the parameter was never consumed by eventBusIterable. Remove the
now-unused zod import. Add at-most-once delivery JSDoc to the EventBus interface
to make the real guarantee explicit. Add compliance comment above
onConversationUpdate noting what to wire when a conversation view is built.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 20:51:58 +01:00
Lukas May
d81e0864f7 feat: Add retry mechanism for blocked tasks
Blocked tasks (from spawn failures) were a dead-end with no way to
recover. Add retryBlockedTask to DispatchManager that resets status
to pending and re-queues, a tRPC mutation that also kicks dispatchNext,
and a Retry button in the task slide-over when status is blocked.
2026-03-05 20:41:49 +01:00
Lukas May
2eac5b9908 fix: Remove agent:output from general SSE subscriptions to prevent listener leak
agent:output is high-frequency streaming data that was included in
ALL_EVENT_TYPES and AGENT_EVENT_TYPES, causing every onEvent/onAgentUpdate
SSE subscription to register a listener. With multiple subscriptions per
browser tab plus reconnections, this exceeded the 100 listener limit.

The dedicated onAgentOutput subscription handles output streaming already.
Bonus: stops useLiveUpdates from refetching listAgents on every output chunk.
2026-03-05 17:50:01 +01:00
Lukas May
8804455c77 Remove task-level approval system
Task-level approval (requiresApproval, mergeRequiresApproval,
pending_approval status) was redundant with executionMode
(yolo vs review_per_phase) and blocked the orchestrator's
phase completion flow. Tasks now complete directly;
phase-level review via executionMode is the right granularity.

Removed: schema columns (left in DB, removed from Drizzle),
TaskPendingApprovalEvent, approveTask/listPendingApprovals
procedures, findPendingApproval repository method, and all
frontend approval UI.
2026-03-05 17:09:48 +01:00
Lukas May
209629241d feat: Add PREVIEW_EVENT_TYPES, CONVERSATION_EVENT_TYPES, and subscription procedures
- Add preview:building/ready/stopped/failed to ALL_EVENT_TYPES
- Export PREVIEW_EVENT_TYPES and CONVERSATION_EVENT_TYPES constants
- Add onPreviewUpdate and onConversationUpdate subscription procedures
- Add audit comment confirming phase:pending_review presence (gap 3 verified)
- Add unit tests covering constants, filtering behavior, and procedure shape
- Update server-api.md to document new subscription procedures

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 17:07:00 +01:00
Lukas May
865e8bffa0 feat: Add initiative review gate before push
When all phases complete, the initiative now transitions to
pending_review status instead of silently stopping. The user
reviews the full initiative diff and chooses:
- Push Branch: push cw/<name> to remote for PR workflows
- Merge & Push: merge into default branch and push

Changes:
- Schema: Add pending_review to initiative status enum
- BranchManager: Add pushBranch port + SimpleGit adapter
- Events: initiative:pending_review, initiative:review_approved
- Orchestrator: checkInitiativeCompletion + approveInitiative
- tRPC: getInitiativeReviewDiff, getInitiativeReviewCommits,
  getInitiativeCommitDiff, approveInitiativeReview
- Frontend: InitiativeReview component in ReviewTab
- Subscriptions: Add initiative events + missing preview/conversation
  event types and subscription procedures
2026-03-05 17:02:17 +01:00
Lukas May
763871a2a5 fix: Refine flow — optimistic UI update + instruction passthrough
- Add getActiveRefineAgent to spawn mutation optimistic updates and
  live event invalidation rules so the refine panel reflects agent
  state immediately without manual refresh
- Accept optional instruction param in buildRefinePrompt() and inject
  it as <user_instruction> block so the agent knows what to focus on
- Pass input.instruction through in architect router spawn call
2026-03-05 16:58:12 +01:00
Lukas May
ebe186bd5e feat: Add agent preview integration with auto-teardown and simplified commands
- Add agentId label to preview containers (cw.agent-id) for tracking
- Add startForAgent/stopByAgentId methods to PreviewManager
- Auto-teardown: previews torn down on agent:stopped event
- Conditional preview prompt injection for execute/refine/discuss agents
- Agent-simplified CLI: cw preview start/stop --agent <id>
- cw preview setup command with --auto mode for guided config generation
- hasPreviewConfig hint on cw project register output
- New tRPC procedures: startPreviewForAgent, stopPreviewByAgent
2026-03-05 15:39:15 +01:00
Lukas May
143aad58e8 feat: Replace per-preview Caddy sidecars with shared gateway architecture
Refactor preview deployments to use a single shared Caddy gateway container
with subdomain routing (<previewId>.localhost:<port>) instead of one Caddy
sidecar and one port per preview. Adds dev/preview modes, git worktree
support for branch checkouts, and auto-start on phase:pending_review.

- Add GatewayManager for shared Caddy lifecycle + Caddyfile generation
- Add git worktree helpers for preview mode branch checkouts
- Add dev mode: volume-mount + dev server image instead of build
- Remove per-preview Caddy sidecar and port publishing
- Use shared cw-preview-net Docker network with container name DNS
- Auto-start previews when phase enters pending_review
- Delete unused PreviewPanel.tsx
- Update all tests (40 pass), docs, events, CLI, tRPC, frontend
2026-03-05 12:22:29 +01:00
Lukas May
5e77bf104c feat: Add remote sync for project clones
Fetch remote changes before agents start working so they build on
up-to-date code. Adds ProjectSyncManager with git fetch + ff-only
merge of defaultBranch, integrated into phase dispatch to sync
before branch creation.

- Schema: lastFetchedAt column on projects table (migration 0029)
- Events: project:synced, project:sync_failed
- Phase dispatch: sync all linked projects before creating branches
- tRPC: syncProject, syncAllProjects, getProjectSyncStatus
- CLI: cw project sync [name] --all, cw project status [name]
- Frontend: sync button + ahead/behind badge on projects settings
2026-03-05 11:45:09 +01:00
Lukas May
7e0749ef17 feat: Wire full request-changes flow for phase review
- Add PhaseChangesRequestedEvent to event bus
- Add requestChangesOnPhase() to ExecutionOrchestrator: reads unresolved
  comments, creates revision task (category='review'), resets phase to
  in_progress, queues task for dispatch
- Expand merge-skip and branch routing to include 'review' category so
  revision tasks work directly on the phase branch
- Add requestPhaseChanges tRPC procedure (reads comments from DB)
- Wire frontend: mutation replaces stub handler, window.prompt for
  optional summary, loading state on button
2026-03-05 11:35:34 +01:00
Lukas May
173c7f7916 feat: Persist review comments to database
Review comments on phase diffs now survive page reloads and phase
switches. Adds review_comments table (migration 0028), repository
port/adapter (13th repo), tRPC procedures (listReviewComments,
createReviewComment, resolveReviewComment, unresolveReviewComment),
and replaces useState-based comments in ReviewTab with tRPC queries
and mutations.
2026-03-05 11:16:54 +01:00
Lukas May
c58e0ea77e feat: Redesign review tab with phase selection, commit navigation, and consolidated toolbar
- Add BranchManager.listCommits() and diffCommit() for commit-level navigation
- Add getPhaseReviewCommits and getCommitDiff tRPC procedures
- New ReviewHeader: consolidated toolbar with phase selector pills, branch info,
  stats, integrated preview controls, and approve/reject actions
- New CommitNav: horizontal commit strip with "All changes" + individual commits,
  each showing hash, message, and change stats
- Slim down ReviewSidebar: file list only with dimming for out-of-scope files
  when viewing a single commit
- ReviewTab orchestrates all pieces in a single bordered card layout
2026-03-05 10:20:43 +01:00
Lukas May
70fd996fa1 Revert "fix: Spawn chat agent in background to avoid blocking event loop"
This reverts commit 8ee02f6013.
2026-03-04 12:07:00 +01:00
Lukas May
8ee02f6013 fix: Spawn chat agent in background to avoid blocking event loop
sendChatMessage was awaiting the full agentManager.spawn() which
includes worktree creation, ~50 writeFileSync calls for input files,
credential setup, and process spawning. This blocked the Node.js event
loop long enough to cause ECONNREFUSED on the SSE connection.

Now the mutation returns immediately after storing the user message
and creating the task. The heavy spawn work runs in a detached promise.
On failure, a system message is stored so the UI can display the error.
2026-03-04 12:05:21 +01:00
Lukas May
069eb66acb feat: Add project filter to listInitiatives
Add findByProjectId to InitiativeRepository using a subquery on the
initiative_projects junction table. Extend the listInitiatives tRPC
procedure to accept an optional projectId filter that composes with
the existing status filter. Add a project dropdown to the initiatives
page alongside the status filter.
2026-03-04 11:40:32 +01:00
Lukas May
9c09683029 fix: Add scope awareness to chat prompt so agents focus on target entities
Pass targetId to buildChatPrompt and add <scope> block that clearly
distinguishes primary target files from context files. Context entities
may be modified when necessary (e.g. dependency links) but the agent
is instructed to focus changes on the primary target.
2026-03-04 11:31:49 +01:00
Lukas May
354950bb8a fix: Retry sends message with retry flag to avoid duplicate storage
Added retry:true flag to sendChatMessage input. Server skips storing
the user message when retry is set. Frontend uses a dedicated
retryLastMessage function that skips the optimistic message add.
2026-03-04 11:25:43 +01:00
Lukas May
1aef986127 fix: Sort pipeline tasks by dependency order instead of priority+createdAt
The Execution tab's PipelinePhaseGroup was using sortByPriorityAndQueueTime
which ignores task dependencies entirely. Tasks now sort topologically via
topologicalSortPhases, matching the Plan tab's TaskGraph behavior.

- Add listInitiativeTaskDependencies tRPC procedure (bulk fetch)
- Fetch task deps in PipelineTab, group by phase, pass through
- Replace priority sort with topological sort in PipelinePhaseGroup
- Show "blocked by N" count on PipelineTaskCard
2026-03-04 10:18:26 +01:00
Lukas May
fcf822363c feat: Add persistent chat sessions for iterative phase/task refinement
Introduces a chat loop where users send instructions to an agent that
applies changes (create/update/delete phases, tasks, pages) and stays
alive for follow-up messages. Includes schema + migration, repository
layer, chat prompt, file-io action field extension, output handler chat
mode, revert support for deletes, tRPC procedures, events, frontend
slide-over UI with inline changeset display and revert, and docs.
2026-03-04 10:14:28 +01:00
Lukas May
2948eb1139 feat: Add tiptap editor for task descriptions in slide-over panel
- Add updateTask tRPC mutation (name, description fields)
- Replace static description with TiptapEditor in TaskSlideOver
- Auto-detect existing markdown descriptions and convert to tiptap JSON
- Debounced auto-save with flush on close/unmount
- Saving indicator in header
2026-03-04 09:06:44 +01:00
Lukas May
9e7c246280 fix: Switch auto-spawn from discuss to refine agent, surface in UI
The auto-spawned agent on initiative creation was using discuss mode
(Q&A) when it should use refine mode (expand content). Now:

- Description seeds root page as tiptap content (split on double newlines)
- Spawns refine agent with the populated page in inputContext
- getActiveRefineAgent broadened to also surface discuss agents (for
  CLI-spawned discuss agents)
- RefineAgentPanel shows mode-appropriate label for discuss vs refine
2026-03-03 14:25:43 +01:00
Lukas May
b38a2ec034 fix: Pass task with description to auto-spawned discuss agent
The discuss agent spawned on initiative creation received only the
initiative in its inputContext, missing the task that carries the user's
description. The agent started without knowing what to discuss.
2026-03-03 14:13:45 +01:00
Lukas May
3d04cb2081 fix: Surface active architect agents in initiative activity state
Auto-spawned discuss/plan/refine agents were invisible because:
1. listInitiatives only filtered for mode='detail' agents
2. deriveInitiativeActivity returned 'idle' for zero phases before
   checking for active agents

Broadened agent filter to all architect modes (discuss, plan, detail,
refine), moved active agent check before zero-phases early return, and
added 'discussing'/'refining' activity states with pulsing indicators.
2026-03-03 14:12:20 +01:00
Lukas May
9b91ffe0e5 fix: Persist and expose task dependencies from detail output
Detail agents define task dependencies in YAML frontmatter but they were
silently dropped — never written to the task_dependencies table. This
caused all tasks to dispatch in parallel regardless of intended ordering,
and the frontend showed no dependency information.

- Add fileIdToDbId mapping and second-pass dependency creation in
  output-handler.ts (mirrors existing phase dependency pattern)
- Add task_dependency to changeset entry entityType enum
- Add listPhaseTaskDependencies tRPC procedure for batch querying
- Wire blockedBy in PhaseDetailPanel and PhaseWithTasks from real data
- Clarify dependency semantics in detail prompt
2026-03-03 13:46:29 +01:00
Lukas May
86a1912959 feat: Add description field and auto-spawn discuss agent on initiative creation 2026-03-03 13:40:37 +01:00
Lukas May
9edc93a268 feat: Auto-resume idle agents for inter-agent conversations
When an agent asks a question via `cw ask` targeting an idle agent,
the conversation router now auto-resumes the idle agent's session so
it can answer. Previously, questions to idle agents sat unanswered
forever because target resolution only matched running agents.

Changes:
- Add `resumeForConversation()` to AgentManager interface and implement
  on MultiProviderAgentManager (mirrors resumeForCommit pattern)
- Relax createConversation target resolution: prefer running, fall back
  to idle (was running-only)
- Trigger auto-resume after conversation creation for idle targets
- Add concurrency lock (conversationResumeLocks Set) to prevent
  double-resume race conditions
2026-03-03 13:29:39 +01:00
Lukas May
3e678f2591 fix: Show detailing indicator by including detail tasks in listInitiativeTasks
listInitiativeTasks was filtering out detail tasks server-side, so the
detailAgentByPhase mapping could never resolve agent.taskId to a phaseId.
Move the filter to client-side (displayTasks) so detail tasks are available
for agent mapping but excluded from counts and display grouping.
2026-03-03 13:25:29 +01:00
Lukas May
411700d37d feat: Show detailing status in initiative overview and phase sidebar
Add 'detailing' activity state derived from active detail agents
(mode=detail, status running/waiting_for_input). Initiative cards show
pulsing "Detailing" indicator. Phase sidebar items show spinner during
active detailing and "Review changes" when the agent finishes.
2026-03-03 13:08:05 +01:00
Lukas May
96386e1c3d feat: Replace initiative card N+1 queries with server-computed activity indicator
listInitiatives now returns an activity object (state, activePhase, phase
counts) derived server-side from phases, eliminating per-card listPhases
queries. Initiative cards show a StatusDot with pulse animation + label
instead of a static StatusBadge. Removed redundant View and Spawn Architect
buttons from cards. Added variant override prop to StatusDot.
2026-03-03 12:49:07 +01:00
Lukas May
c8f370583a feat: Add codebase exploration to architect agent prompts
Architect agents (discuss, plan, detail, refine) were producing generic
analysis disconnected from the actual codebase. They had full tool access
in their worktrees but were never instructed to explore the code.

- Add CODEBASE_EXPLORATION shared constant: read project docs, explore
  structure, check existing patterns, use subagents for parallel exploration
- Inject into all 4 architect prompts after INPUT_FILES
- Strengthen discuss prompt: analysis method references codebase, examples
  cite specific paths, definition_of_done requires codebase references
- Fix spawnArchitectDiscuss to pass full context (pages/phases/tasks) via
  gatherInitiativeContext() — was only passing bare initiative metadata
- Update docs/agent.md with new tag ordering and shared block table
2026-03-03 12:45:14 +01:00
Lukas May
34578d39c6 refactor: Restructure monorepo to apps/server/ and apps/web/ layout
Move src/ → apps/server/ and packages/web/ → apps/web/ to adopt
standard monorepo conventions (apps/ for runnable apps, packages/
for reusable libraries). Update all config files, shared package
imports, test fixtures, and documentation to reflect new paths.

Key fixes:
- Update workspace config to ["apps/*", "packages/*"]
- Update tsconfig.json rootDir/include for apps/server/
- Add apps/web/** to vitest exclude list
- Update drizzle.config.ts schema path
- Fix ensure-schema.ts migration path detection (3 levels up in dev,
  2 levels up in dist)
- Fix tests/integration/cli-server.test.ts import paths
- Update packages/shared imports to apps/server/ paths
- Update all docs/ files with new paths
2026-03-03 11:22:53 +01:00