docs(worker): update CLAUDE.md with CLI modernization changes
This commit is contained in:
67
src/ClaudeDo.Worker/CLAUDE.md
Normal file
67
src/ClaudeDo.Worker/CLAUDE.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# ClaudeDo.Worker
|
||||
|
||||
ASP.NET Core hosted service that executes tasks via Claude CLI in isolated environments.
|
||||
|
||||
## Architecture
|
||||
|
||||
- **Program.cs** — loads config, inits schema, registers DI, configures SignalR on `/hub`, binds to `127.0.0.1:47821`
|
||||
- **QueueService** — `BackgroundService` with two execution slots:
|
||||
- Queue slot: FIFO sequential processing of "agent"-tagged queued tasks
|
||||
- Override slot: immediate execution via `RunNow(taskId)`
|
||||
- Wake signaling via `SemaphoreSlim`, backstop timer (30s default)
|
||||
- **StaleTaskRecovery** — startup-only service, flips orphaned "running" tasks to "failed"
|
||||
|
||||
## Task Execution Pipeline
|
||||
|
||||
`TaskRunner` orchestrates:
|
||||
1. Load task + list metadata from DB; resolve config from `list_config` + task-level overrides (model, system_prompt, agent_path)
|
||||
2. Create worktree (if `WorkingDir` set) or sandbox directory
|
||||
3. Mark task "running", broadcast `TaskStarted`
|
||||
4. Build CLI args via `ClaudeArgsBuilder`; invoke `ClaudeProcess` with task prompt
|
||||
5. Stream NDJSON output through `StreamAnalyzer`; lines forwarded to log file and SignalR (`TaskMessage`)
|
||||
6. On success: auto-commit changes (worktree only), store run record, mark "done"
|
||||
7. On failure: retry once if session ID available (`--resume`), then mark "failed"
|
||||
|
||||
## Key Components
|
||||
|
||||
- **ClaudeProcess** — spawns `claude -p --output-format stream-json --verbose --dangerously-skip-permissions`. Writes prompt to stdin, reads NDJSON from stdout. Supports CancellationToken (kills process tree).
|
||||
- **ClaudeArgsBuilder** — dynamically constructs CLI args; supports `--model`, `--append-system-prompt`, `--agents`, `--json-schema`, `--resume`
|
||||
- **StreamAnalyzer** — parses rich NDJSON output; extracts session_id, token counts, turn counts, result text, structured output. Replaces MessageParser.
|
||||
- **WorktreeManager** — creates worktrees at `claudedo/{taskId[:8]}` branches, commits changes with semantic messages, updates DB with head commit and diff stats
|
||||
- **CommitMessageBuilder** — formats `{commitType}(slug): title\n\ndescription\n\nClaudeDo-Task: taskId`
|
||||
- **AgentFileService** — manages `~/.todo-app/agents/*.md` agent definition files; exposes list/refresh via SignalR
|
||||
- **LogWriter** — async StreamWriter wrapper, auto-creates parent dirs
|
||||
|
||||
## Execution History
|
||||
|
||||
Each CLI invocation is recorded in the `task_runs` table via `TaskRunRepository`:
|
||||
- Fields: `session_id`, input/output/cache token counts, turn count, `result` text, structured output JSON
|
||||
- Enables auto-retry on failure (resume last session) and multi-turn follow-up via `ContinueAsync`
|
||||
|
||||
## Multi-Turn / Continue
|
||||
|
||||
`TaskRunner.ContinueAsync` sends a follow-up prompt to an existing Claude session using `--resume <session_id>` with the stored session ID from the last run.
|
||||
|
||||
## SignalR Hub
|
||||
|
||||
**WorkerHub** methods: `Ping()`, `GetActive()`, `RunNow(taskId)`, `CancelTask(taskId)`, `WakeQueue()`, `ContinueTask(taskId, prompt)`, `GetAgents()`, `RefreshAgents()`
|
||||
|
||||
**HubBroadcaster** events: `TaskStarted`, `TaskFinished`, `TaskMessage`, `WorktreeUpdated`, `TaskUpdated`, `RunCreated`
|
||||
|
||||
## Config
|
||||
|
||||
Loaded from `~/.todo-app/worker.config.json`:
|
||||
- `db_path`, `sandbox_root`, `log_root`
|
||||
- `worktree_root_strategy` ("sibling" | "central"), `central_worktree_root`
|
||||
- `queue_backstop_interval_ms` (default 30000)
|
||||
- `signalr_port` (default 47821)
|
||||
- `claude_bin` (path to claude CLI)
|
||||
|
||||
Per-list config (`list_config` in DB) provides defaults for `model`, `system_prompt`, `agent_path`; tasks can override each individually.
|
||||
|
||||
## Notes
|
||||
|
||||
- The worker runs standalone — start it separately from the UI
|
||||
- Only listens on loopback (127.0.0.1)
|
||||
- ClaudeProcess uses `--dangerously-skip-permissions` — tasks run with full filesystem access
|
||||
- Worktree branches follow `claudedo/{id}` naming convention
|
||||
Reference in New Issue
Block a user