Commit Graph

15 Commits

Author SHA1 Message Date
Lukas May
d4a28713f6 fix: conflict resolution tasks now get dispatched instead of permanently blocking initiative
- Remove original task blocking in handleConflict (task is already completed by handleAgentStopped)
- Return created conflict task from handleConflict so orchestrator can queue it for dispatch
- Add dedup check to prevent duplicate resolution tasks on crash retries
- Queue conflict resolution task via dispatchManager in mergeTaskIntoPhase
- Add recovery for erroneously blocked tasks in recoverDispatchQueues
- Update tests and docs
2026-03-06 20:37:29 +01:00
Lukas May
f63b1c5eec Merge branch 'cw/radar' into cw-merge-1772825408137 2026-03-06 20:30:08 +01:00
Lukas May
c0096503b2 fix: Re-record cassettes and exclude workdir from test discovery
Re-recorded all 4 cassette files to reflect current prompt templates.
Added `workdir/**` to vitest exclude list to prevent test discovery
in agent worktree directories.
2026-03-06 17:00:46 +01:00
Lukas May
5598e1c10f feat: implement Radar backend tRPC procedures with repository extensions
Add five new tRPC query procedures powering the Radar page's per-agent
behavioral metrics (questions asked, subagent spawns, compaction events,
inter-agent messages) plus the batch repository methods they require.

Repository changes:
- LogChunkRepository: add findByAgentIds() for batch fetching without N+1
- ConversationRepository: add countByFromAgentIds() and findByFromAgentId()
- Drizzle adapters: implement all three new methods using inArray()
- InMemoryConversationRepository (integration test): implement new methods

tRPC procedures added:
- agent.listForRadar: filtered agent list with per-agent metrics computed
  from log chunks (questionsCount, subagentsCount, compactionsCount) and
  conversation counts (messagesCount); supports timeRange/status/mode/initiative filters
- agent.getCompactionEvents: compact system init chunks for one agent (cap 200)
- agent.getSubagentSpawns: Agent tool_use entries with prompt preview (cap 200)
- agent.getQuestionsAsked: AskUserQuestion tool calls with questions array (cap 200)
- conversation.getByFromAgent: conversations by fromAgentId with toAgentName resolved

All 13 new unit tests pass; existing test suite unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 16:40:18 +01:00
Lukas May
1e16ad82e8 fix: Show conflict resolution agents in HQ dashboard
getHeadquartersDashboard had no section for active conflict agents,
so initiatives with a running conflict-* agent disappeared from all
HQ sections. Add resolvingConflicts array to surface them.
2026-03-06 16:39:48 +01:00
Lukas May
02ca1d568e fix: Disable EventEmitter maxListeners warning for SSE subscriptions
Each SSE client registers a listener per event type (30+ types), so a
few concurrent connections easily exceed the previous limit of 100.
Listeners are properly cleaned up on disconnect via eventBusIterable's
finally block, so this is not a real leak.
2026-03-06 16:39:36 +01:00
Lukas May
89c98d38cc feat: Add getHeadquartersDashboard tRPC procedure for HQ action items
Aggregates all user-blocking action items into a single composite query:
- waitingForInput: agents paused on questions (oldest first)
- pendingReviewInitiatives: initiatives awaiting content review
- pendingReviewPhases: phases awaiting diff review
- planningInitiatives: active initiatives with all phases pending and no running agents
- blockedPhases: phases in blocked state with optional last-message snippet

Wired into appRouter and covered by 10 unit tests using in-memory Drizzle DB
and an inline MockAgentManager (no real processes required).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 15:35:54 +01:00
Lukas May
1629285778 Merge branch 'refs/heads/main' into cw/agent-details-conflict-1772799979862
# Conflicts:
#	apps/server/drizzle/meta/_journal.json
2026-03-06 13:34:28 +01:00
Lukas May
b2f4004191 feat: Persist agent prompt in DB so getAgentPrompt survives log cleanup
The `getAgentPrompt` tRPC procedure previously read exclusively from
`.cw/agent-logs/<name>/PROMPT.md`. Once the cleanup-manager removes
that directory, the prompt is gone forever.

Adds a `prompt` text column to the `agents` table and writes the fully
assembled prompt (including workspace layout, inter-agent comms, and
preview sections) to the DB in the same `repository.update()` call
that saves pid/outputFilePath after spawn.

`getAgentPrompt` now reads from DB first (`agent.prompt`) and falls
back to the filesystem only for agents spawned before this change.

Addresses review comment [MMcmVlEK16bBfkJuXvG6h].

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 13:13:01 +01:00
Lukas May
7b93cfe7d7 feat: Remove checkpoint task types — per-phase review is sufficient
Checkpoint tasks (human-verify, decision, human-action) silently blocked
auto-dispatch with no UI to resolve them. Per-phase review + initiative
review already cover human verification, making checkpoints redundant.

Removed from: schema, dispatch manager, tRPC validators, detail prompt,
frontend types, tests, and docs.
2026-03-05 21:30:22 +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
bd0aec4499 fix: Convert sync file I/O to async in agent spawn path to unblock event loop
writeInputFiles, spawnDetached, and diagnostic writes now use
fs/promises (mkdir, writeFile) instead of mkdirSync/writeFileSync.
File writes in writeInputFiles are batched with Promise.all.
openSync/closeSync for child process stdio FDs remain sync as
spawn() requires the FDs immediately.
2026-03-04 12:15:31 +01:00
Lukas May
e4289659cd chore: Re-record full-flow cassettes after task dependency changes
Prompt changes in detail.ts invalidated the old cassette hashes.
Re-recorded all 4 cassettes with updated prompt content. Replay
verified passing in 12s.
2026-03-03 13:56:47 +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
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