Commit Graph

35 Commits

Author SHA1 Message Date
Lukas May
008c783c50 fix(agent): Handle null refreshToken/expiresAt in credential manager
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>
2026-02-10 09:49:48 +01:00
Lukas May
c204aab403 fix(agent): Allow null refreshToken and expiresAt for setup tokens
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>
2026-02-10 09:49:36 +01:00
Lukas May
342b490fe7 feat: Task decomposition for Tailwind/Radix/shadcn foundation setup
Decomposed "Foundation Setup - Install Dependencies & Configure Tailwind"
phase into 6 executable tasks:

1. Install Tailwind CSS, PostCSS & Autoprefixer
2. Map MUI theme to Tailwind design tokens
3. Setup CSS variables for dynamic theming
4. Install Radix UI primitives
5. Initialize shadcn/ui and setup component directory
6. Move MUI to devDependencies and verify setup

Tasks follow logical dependency chain with final human verification
checkpoint before proceeding with component migration.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-10 09:48:51 +01:00
Lukas May
fab7706f5c feat: Phase schema refactor, agent lifecycle module, and log chunks
Phase model changes:
- Drop `number` column (ordering now by createdAt + dependency DAG)
- Replace `description` (plain text) with `content` (Tiptap JSON)
- Add `approved` status as dispatch gate
- Add phase dependency management (list, remove, dependents)
- Approval gate in PhaseDispatchManager.queuePhase()

Agent log chunks:
- New `agent_log_chunks` table for DB-first output persistence
- LogChunkRepository port + DrizzleLogChunkRepository adapter
- FileTailer onRawContent callback streams chunks to DB
- getAgentOutput reads from DB first, falls back to file

Agent lifecycle module (src/agent/lifecycle/):
- SignalManager: atomic signal.json read/write/wait operations
- RetryPolicy: exponential backoff with error-specific strategies
- ErrorAnalyzer: pattern-based error classification
- CleanupStrategy: debug archival vs production cleanup
- AgentLifecycleController: orchestrates retry/recovery flow
- Missing signal recovery with instruction injection

Completion detection fixes:
- Read signal.json file instead of parsing stdout as JSON
- Cancellable pollForCompletion with { cancel } handle
- Centralized state cleanup via cleanupAgentState()
- Credential handler consolidation (prepareProcessEnv)

Prompts refactor:
- Split monolithic prompts.ts into per-mode modules
- Add workspace layout section to agent prompts
- Fix markdown-to-tiptap double-serialization

Server/tRPC:
- Subscription heartbeat (30s) and bounded queue (1000 max)
- Phase CRUD: approvePhase, deletePhase, dependency queries
- Page: findByIds, getPageUpdatedAtMap
- Wire new repositories through container and context
2026-02-09 22:33:28 +01:00
Lukas May
43e2c8b0ba fix(agent): Eliminate race condition in completion handling
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
2026-02-08 15:51:32 +01:00
Lukas May
6f5fd3a0af fix(agent): Implement incremental JSONL parsing to eliminate race conditions
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.
2026-02-08 14:10:02 +01:00
Lukas May
604da7cd0d fix(agent): Replace hardcoded 500ms delay with robust file completion detection
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.
2026-02-08 14:03:47 +01:00
Lukas May
2877484012 Add userDismissedAt field to agents schema 2026-02-07 00:33:12 +01:00
Lukas May
5605547aea fix(13-01): parse structured_output from Claude CLI response
- Add structured_output field to ClaudeCliResult interface
- Read from structured_output when present (--json-schema response)
- Fall back to parsing result for backwards compatibility
2026-02-02 10:38:10 +01:00
Lukas May
a79b15376e test(12-07): add MockAgentManager decompose mode tests
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
2026-02-01 11:54:20 +01:00
Lukas May
7ff979becf feat(12-05): export buildDecomposePrompt from agent module
- Add buildDecomposePrompt to public exports
2026-02-01 11:49:57 +01:00
Lukas May
48336ec39d feat(12-05): create buildDecomposePrompt function
- Add buildDecomposePrompt for decompose mode agent operations
- Import Phase and Plan types from schema
- Comprehensive prompt explaining task breakdown rules, types, and output format
2026-02-01 11:49:45 +01:00
Lukas May
2bd0bc52a3 feat(12-03): add decompose mode support to MockAgentManager
- 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
2026-02-01 11:44:40 +01:00
Lukas May
8754cdea98 feat(12-03): add decompose mode support to ClaudeAgentManager
- Import decomposeOutputSchema and decomposeOutputJsonSchema from schema.ts
- Update getJsonSchemaForMode() to handle 'decompose' mode
- Add handleDecomposeOutput() method following pattern of handleBreakdownOutput()
- Update handleAgentCompletion() switch to call handleDecomposeOutput for decompose mode
- Handle decompose_complete/questions/unrecoverable_error statuses
2026-02-01 11:43:55 +01:00
Lukas May
8ffa54a531 feat(12-01): create decompose output schema
- 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
2026-02-01 11:34:31 +01:00
Lukas May
8da4e71075 feat(12-01): extend AgentMode with 'decompose'
- Add 'decompose' to AgentMode union type
- Update agents table mode column enum in database schema
- Update test-helpers.ts CREATE_TABLES_SQL with CHECK constraint
- Add missing getNextNumber implementation (blocking fix)
2026-02-01 11:32:18 +01:00
Lukas May
021937c28d feat(test): add TestHarness architect mode helpers and tRPC caller
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.
2026-01-31 19:26:46 +01:00
Lukas May
567d863a4a test(agent): add MockAgentManager mode tests
- 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
2026-01-31 19:23:22 +01:00
Lukas May
773f6f92ac feat(11-05): create comprehensive agent prompts module
- Add buildDiscussPrompt for context gathering mode
- Add buildBreakdownPrompt for phase decomposition mode
- Add buildExecutePrompt for standard task execution
- Export prompts from agent module index
2026-01-31 19:15:58 +01:00
Lukas May
937d24eca5 feat(11-03): update ClaudeAgentManager for mode-specific schemas
- 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
2026-01-31 19:12:31 +01:00
Lukas May
0abf02ac14 feat(11-01): update MockAgentManager for mode support
- 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
2026-01-31 19:06:40 +01:00
Lukas May
3f8d6d5357 feat(11-01): create mode-specific output schemas
- 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
2026-01-31 19:05:27 +01:00
Lukas May
91e57c66eb feat(11-01): add AgentMode type and database column
- 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
2026-01-31 19:03:42 +01:00
Lukas May
a9e46a2843 feat(10-02): update MockAgentManager for batched answers
- 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
2026-01-31 18:02:54 +01:00
Lukas May
d012680dbe feat(10-02): update ClaudeAgentManager for batched answers
- 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
2026-01-31 18:02:51 +01:00
Lukas May
151a4c99f7 feat(10-01): extend agent schema to multi-question array
- 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
2026-01-31 17:57:34 +01:00
Lukas May
565f9fdae9 test(08.1-02): update tests to use schema-aligned scenarios
- 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
2026-01-31 15:31:56 +01:00
Lukas May
ead4614383 feat(08.1-02): update MockAgentManager to schema-aligned scenarios
- 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
2026-01-31 15:28:38 +01:00
Lukas May
d9673d54a3 feat(08.1-01): update ClaudeAgentManager to use structured schema
- 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
2026-01-31 15:25:07 +01:00
Lukas May
41598f577f feat(08.1-01): define agent output schema with Zod
- 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
2026-01-31 15:21:09 +01:00
Lukas May
e305375820 test(07-01): add comprehensive tests for MockAgentManager
28 test cases covering:
- spawn() with default scenario (immediate success)
- spawn() with configured delay
- spawn() with crash scenario (agent:crashed, result.success=false)
- spawn() with waiting_for_input (agent:waiting, status='waiting_for_input')
- resume() after waiting_for_input (agent:resumed, continues scenario)
- stop() kills scheduled completion, emits agent:stopped
- list() returns all agents with correct status
- get() and getByName() lookups
- setScenario() overrides for specific agent names
- Event emission order verification (spawned before completion)
- Name uniqueness validation
- Constructor options (eventBus, defaultScenario)
- clear() cleanup

Export MockAgentManager and MockAgentScenario from src/agent/index.ts
2026-01-31 08:43:15 +01:00
Lukas May
6148af784e feat(07-01): implement MockAgentManager adapter
- MockAgentScenario interface with outcome, delay, message, filesModified, question
- Constructor takes optional eventBus and defaultScenario
- setScenario() for per-agent scenario overrides
- spawn() creates agent, schedules async completion based on scenario
- Emits all lifecycle events: agent:spawned, agent:stopped, agent:crashed, agent:waiting, agent:resumed
- stop() cancels pending completion, marks agent stopped
- resume() re-runs scenario for waiting_for_input agents
- getResult() returns stored result after completion
- clear() for test cleanup
2026-01-31 08:41:49 +01:00
Lukas May
b718d59cbf test(04-03): add comprehensive tests for ClaudeAgentManager
- Test spawn with worktree and agent record creation
- Test duplicate name rejection
- Test AgentSpawned event emission
- Test stop with subprocess kill and status update
- Test list, get, getByName operations
- Test resume with session_id and --resume flag
- Test AgentResumed event emission
- Fix: use agent.id from repository for activeAgents tracking
2026-01-30 20:07:28 +01:00
Lukas May
81934237ca feat(04-03): implement ClaudeAgentManager adapter
- Use Claude CLI with --output-format json for agent spawning
- Extract session_id from JSON result for resume capability
- Emit lifecycle events: spawned, stopped, crashed, resumed, waiting
- Handle waiting_for_input status for AskUserQuestion pauses
- Uses WorktreeManager for isolated agent workspaces
2026-01-30 20:05:03 +01:00
Lukas May
88889700c2 feat(04-02): define AgentManager port interface and domain types
- AgentStatus type for agent lifecycle states
- SpawnAgentOptions for spawn configuration
- AgentInfo for agent state representation
- AgentResult for execution results
- AgentManager interface with spawn, stop, list, get, getByName, resume, getResult
2026-01-30 19:58:55 +01:00