Integrates main branch changes (headquarters dashboard, task retry count,
agent prompt persistence, remote sync improvements) with the initiative's
errand agent feature. Both features coexist in the merged result.
Key resolutions:
- Schema: take main's errands table (nullable projectId, no conflictFiles,
with errandsRelations); migrate to 0035_faulty_human_fly
- Router: keep both errandProcedures and headquartersProcedures
- Errand prompt: take main's simpler version (no question-asking flow)
- Manager: take main's status check (running|idle only, no waiting_for_input)
- Tests: update to match removed conflictFiles field and undefined vs null
Implements the errand workflow for small isolated changes that spawn a
dedicated agent in a git worktree:
- errand.create: branch + worktree + DB record + agent spawn
- errand.list / errand.get / errand.diff: read procedures
- errand.complete: transitions active→pending_review, stops agent
- errand.merge: merges branch, handles conflicts with conflictFiles
- errand.delete / errand.abandon: cleanup worktree, branch, agent
- errand.sendMessage: delivers user message directly to running agent
Supporting changes:
- Add 'errand' to AgentMode union and agents.mode enum
- Add sendUserMessage() to AgentManager interface and MockAgentManager
- MockAgentManager now accepts optional agentRepository to persist agents
to the DB (required for FK constraint satisfaction in tests)
- Add ORDER BY createdAt DESC, id DESC to errand findAll
- Fix dispatch/manager.test.ts missing sendUserMessage mock
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Task dispatch computed baseBranch as the phase branch name but never
ensured it existed in the git clone. When phases weren't dispatched
through the PhaseDispatchManager (which creates branches), the
git worktree add failed with "fatal: invalid reference".
Now DefaultDispatchManager calls ensureBranch for both the initiative
and phase branches before spawning, matching what PhaseDispatchManager
already does.
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.
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.
Wrap agentManager.spawn() in try/catch — on failure, block the task
instead of crashing the entire dispatch cycle. Move phase status update
to after branch creation succeeds — on branch failure, block the phase
and skip task queuing. Fix statement-breakpoint markers in migration
0020 to use separate lines.
- 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
Execution agents were spawning blind — no input files, no knowledge of
what predecessor tasks accomplished. This adds three capabilities:
1. summary column on tasks table — completeTask() reads the finishing
agent's result.message and stores it on the task record
2. dispatchNext() gathers full initiative context (initiative, phase,
sibling tasks, pages) and passes it as inputContext so agents get
.cw/input/task.md, initiative.md, phase.md, and context directories
3. context/tasks/*.md files now include the summary field in frontmatter
so dependent agents can see what prior agents accomplished
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
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