Standalone agents (no initiative or 0 linked projects) run in a
workspace/ subdirectory, but signal.json lookups used the parent
directory. This caused all standalone agents to be marked "crashed"
despite successful completion.
Track the actual agent cwd at spawn time via ActiveAgent.agentCwd
and probe for the workspace/ subdirectory during reconciliation and
crash detection paths.
- New onConversationAnswer subscription: listens for conversation:answered
events matching a specific conversation ID, yields the answer text
- cw ask now subscribes via SSE instead of polling getConversation
- Removed --poll-interval and --timeout flags from cw ask
- Updated prompt to reflect SSE-based cw ask (no polling options)
- INTER_AGENT_COMMUNICATION constant → buildInterAgentCommunication(agentId) function
- Manager injects actual agent ID into prompt after DB record creation
- Agent ID hardcoded in cw listen/ask commands — no manifest.json indirection
- cw listen now uses onPendingConversation SSE subscription instead of polling
- CLI trpc-client upgraded with splitLink for subscription support
- All CLI flags (--agent-id, --from, --timeout, --poll-interval) documented in prompt
- conversation:created/answered added to ALL_EVENT_TYPES
Body: height 100vh + overflow hidden instead of min-height 100vh,
so the browser never shows a scrollbar on html/body.
AppLayout: h-screen flex column with shrink-0 header and flex-1
min-h-0 overflow-auto main. Pages like initiatives scroll within
main; agents page uses h-full with internal panel scrollers.
Enables parallel agents to communicate through a CLI-based conversation
mechanism coordinated via tRPC. Agents can ask questions to peers and
receive answers, with target resolution by agent ID, task ID, or phase ID.
Setup tokens from `claude setup-token` can't query the usage API,
resulting in a useless "Usage API request failed" message. Now shows
the actual HTTP status and guides users to complete OAuth setup.
Also distinguishes warning state (yellow) from error state (red)
in the AccountCard UI.
DB log chunk insertion is now the sole trigger for agent:output events.
Eliminates triple emission (FileTailer, handleStreamEvent, output buffer)
in favor of: FileTailer.onRawContent → DB insert → EventBus emit.
- createLogChunkCallback emits agent:output after successful DB insert
- spawnInternal now wires onRawContent callback (fixes session 1 gap)
- Remove eventBus from FileTailer (no longer touches EventBus)
- Remove eventBus from ProcessManager constructor (dead parameter)
- Remove agent:output emission from handleStreamEvent text_delta
- Remove outputBuffers map and all buffer helpers from manager/handler
- Remove getOutputBuffer from AgentManager interface and implementations
- getAgentOutput tRPC: DB-only, no file fallback
- onAgentOutput subscription: no initial buffer yield, events only
- AgentOutputViewer: accumulates raw JSONL chunks, parses uniformly
Full rename across the codebase for clarity:
- breakdown (initiative→phases) is now "plan"
- decompose (phase→tasks) is now "detail"
Updates schema enums, TypeScript types, events, prompts, output handler,
tRPC procedures, CLI commands, frontend components, tests, and docs.
Also fixes 0022 migration multi-statement issue (adds statement-breakpoint markers).
Breakdown and decompose agents now receive all existing phases, tasks,
and pages as read-only context so they can plan with awareness of what
already exists instead of operating in a vacuum.
Check for refresh token availability before attempting credential refresh.
Setup tokens that expire without a refresh token now return a clear error
instead of attempting an invalid refresh operation.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Check for refresh token availability before attempting credential refresh.
Setup tokens that expire without a refresh token now return a clear error
instead of attempting an invalid refresh operation.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Updated checkAccountHealth to handle setup tokens with null expiresAt:
- Changed currentExpiresAt type from number to number | null
- Use conditional for tokenExpiresAt ISO string conversion
This completes the OAuth setup token support across all credential
reading and validation functions.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add validation to check for refresh token availability before attempting
token refresh. Setup tokens that expire without a refresh token now
return a clear error message instead of attempting an invalid refresh.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Make refreshToken and expiresAt optional in usage credential validation.
Aligns with changes in default-credential-manager.ts.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Updated readCredentials and isTokenExpired to support setup tokens:
- Removed refreshToken requirement check
- Use nullish coalescing for refreshToken and expiresAt fields
- Treat tokens without expiresAt as non-expired
Completes OAuth credential handling for setup tokens across all
credential management functions.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Make refreshToken and expiresAt optional in OAuth credential validation.
Setup tokens without expiry are now treated as non-expired.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Updated DefaultAccountCredentialManager to handle setup tokens:
- Removed refreshToken requirement in validation check
- Use nullish coalescing for refreshToken and expiresAt
- Treat tokens without expiresAt as non-expired (setup tokens)
Completes the setup token support changes.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Modified OAuthCredentials interface to support setup tokens that don't
have refresh tokens or expiry times:
- refreshToken: string | null
- expiresAt: number | null
Updated in both src/agent/accounts/usage.ts and
src/agent/credentials/types.ts for consistency.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
PROBLEM:
- Agents completing with questions were incorrectly marked as "crashed"
- Race condition: polling handler AND crash handler both called handleCompletion()
- Caused database corruption and lost pending questions
SOLUTION:
- Add completion mutex in OutputHandler to prevent concurrent processing
- Remove duplicate completion call from crash handler
- Only one handler executes completion logic per agent
TESTING:
- Added mutex-completion.test.ts with 4 test cases
- Verified mutex prevents concurrent access
- Verified lock cleanup on exceptions
- Verified different agents can process concurrently
FIXES: residential-cuckoo and 12+ other agents stuck in crashed state
Replaces file completion detection with a superior approach that reads only
complete JSONL lines and tracks file position. This eliminates race conditions
without any delays or polling.
Key improvements:
- Read up to last complete line, avoiding partial lines during writes
- Track file position per agent for incremental reading
- Process only valid, complete JSON lines
- Clean up position tracking on completion/crash
- No hardcoded delays or polling required
This approach is more robust, responsive, and elegant than timing-based solutions.
The race condition where agents were marked as crashed is now completely resolved.
Fixes race condition where agents were incorrectly marked as crashed when
output files took longer than 500ms to complete writing.
Changes:
- Replace hardcoded 500ms delay with polling-based file completion detection
- Add signal file validation to ensure JSON is complete before processing
- Make status updates atomic to prevent race conditions
- Update cleanup manager to pass outputFilePath for proper timing
This resolves the issue where successful agents like "abundant-wolverine"
were marked as crashed despite producing valid output.
- Add structured_output field to ClaudeCliResult interface
- Read from structured_output when present (--json-schema response)
- Fall back to parsing result for backwards compatibility
Add tests for decompose mode scenarios:
- Spawn agent in decompose mode
- Complete with tasks on decompose_complete
- Pause on questions in decompose mode
- Emit stopped event with decompose_complete reason
- Set result message with task count
- Add buildDecomposePrompt for decompose mode agent operations
- Import Phase and Plan types from schema
- Comprehensive prompt explaining task breakdown rules, types, and output format
- Import TaskBreakdown from schema.ts
- Add decompose_complete status to MockAgentScenario type
- Update completeAgent() to handle decompose_complete scenarios
- Emit agent:stopped with reason 'decompose_complete' for E2E testing
- Add TaskBreakdown type with number, name, description, type, dependencies
- Create decomposeOutputSchema discriminated union (questions/decompose_complete/error)
- Create decomposeOutputJsonSchema for Claude CLI --json-schema flag
- Update module docstring to include decompose mode
Add convenience methods for architect mode testing:
- setArchitectDiscussComplete for context_complete scenarios
- setArchitectDiscussQuestions for discuss mode questions
- setArchitectBreakdownComplete for breakdown_complete scenarios
- getInitiative, getPhases, createInitiative, createPhasesFromBreakdown
- mockAgentManager alias, advanceTimers, getEmittedEvents helpers
- Wire up initiative/phase repositories and tRPC caller to harness
Also fix pre-existing test issues with dependencies and type casting.
- Test default execute mode on spawn
- Test discuss mode with context_complete scenario
- Test breakdown mode with breakdown_complete scenario
- Verify stopped event reasons for each mode
- Add buildDiscussPrompt for context gathering mode
- Add buildBreakdownPrompt for phase decomposition mode
- Add buildExecutePrompt for standard task execution
- Export prompts from agent module index
- Import all mode-specific JSON schemas (discuss, breakdown)
- Add getJsonSchemaForMode() helper to select schema by mode
- Update spawn() to pass mode to repository and use mode-specific schema
- Refactor handleAgentCompletion() to route to mode-specific handlers
- Add handleExecuteOutput() for execute mode (existing behavior)
- Add handleDiscussOutput() for discuss mode (context_complete status)
- Add handleBreakdownOutput() for breakdown mode (breakdown_complete status)
- Update resume() to use mode-specific JSON schema
- Add context_complete scenario for discuss mode
- Add breakdown_complete scenario for breakdown mode
- Import Decision and PhaseBreakdown types from schema
- Handle context_complete status with decisions array
- Handle breakdown_complete status with phases array
- Extend AgentStoppedEvent reason type for new completion reasons
- Export questionItemSchema and add QuestionItem type
- Add Decision type for discuss mode (topic/decision/reason)
- Add PhaseBreakdown type for breakdown mode
- Create discussOutputSchema (questions/context_complete/error)
- Create breakdownOutputSchema (questions/breakdown_complete/error)
- Add discussOutputJsonSchema for Claude CLI --json-schema
- Add breakdownOutputJsonSchema for Claude CLI --json-schema
- Add AgentMode type: 'execute' | 'discuss' | 'breakdown'
- Add mode column to agents table with 'execute' default
- Update SpawnAgentOptions to accept optional mode
- Update AgentInfo interface to include mode field
- Update ClaudeAgentManager.toAgentInfo to map mode
- Fix MockAgentManager to include mode in spawn
- Fix dispatch manager tests to include mode
- Change resume() signature from (agentId, prompt) to (agentId, answers)
- Accept Record<string, string> mapping question IDs to user answers
- Clear pendingQuestions on resume
- Update mock-manager tests for new signature
- Change resume() signature from (agentId, prompt) to (agentId, answers)
- Accept Record<string, string> mapping question IDs to user answers
- Format answers as structured prompt for Claude CLI
- Update AgentManager interface in types.ts
- Update manager tests for new signature
- Change status from 'question' to 'questions' (plural)
- Add QuestionItem with id field for answer matching
- Update PendingQuestion to PendingQuestions with questions array
- Update AgentWaitingEvent payload to questions array
- Update ClaudeAgentManager and MockAgentManager adapters
- Update TestHarness and all test files
- Update MockAgentManager tests to use status-based scenarios
- Change outcome:'crash' to status:'unrecoverable_error' with error field
- Change outcome:'waiting_for_input' to status:'question' with question field
- Change outcome:'success' to status:'done' with result field
- Add tests for structured question data (options, multiSelect)
- Add tests for getPendingQuestion and resume clearing pending question
- Update E2E edge-cases tests with new scenario format
- Update harness tests with new scenario format
- Change MockAgentScenario from outcome-based to status-based discriminated union
- Align with agent output schema: done/question/unrecoverable_error
- Update completeAgent() to handle new status types
- Update resume() to use new scenario format
- Pass --json-schema flag to Claude CLI for validated output
- Parse discriminated union (done/question/unrecoverable_error) in handleAgentCompletion
- Add getPendingQuestion method to AgentManager interface
- Add PendingQuestion type for structured question data
- Store pending question in ActiveAgent for later retrieval
- Remove hacky string matching for waiting_for_input detection
- Update MockAgentManager with getPendingQuestion and options support
- Update tests for new CLI arguments and result format
- Discriminated union with done/question/unrecoverable_error status
- Options schema for structured question choices
- JSON schema export for Claude CLI --json-schema flag
- Type export for runtime validation