takt/CLAUDE.md

208 lines
9.1 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
TAKT (Task Agent Koordination Tool) is a multi-agent orchestration system for Claude Code. It enables YAML-based workflow definitions that coordinate multiple AI agents through state machine transitions.
## Development Commands
| Command | Description |
|---------|-------------|
| `npm run build` | TypeScript build |
| `npm run test` | Run all tests |
| `npm run test:watch` | Watch mode |
| `npm run lint` | ESLint |
| `npx vitest run src/__tests__/client.test.ts` | Run single test file |
| `npx vitest run -t "pattern"` | Run tests matching pattern |
## CLI Slash Commands
| Command | Alias | Description |
|---------|-------|-------------|
| `takt /run-tasks` | `/run` | Execute all pending tasks from `.takt/tasks/` once |
| `takt /watch` | | Watch `.takt/tasks/` and auto-execute tasks (resident process) |
| `takt /add-task` | `/add` | Add a new task interactively (YAML format, multiline supported) |
| `takt /review-tasks` | `/review` | Review worktree task results (try merge, merge & cleanup, or delete) |
| `takt /switch` | | Switch workflow interactively |
| `takt /clear` | | Clear agent conversation sessions (reset state) |
| `takt /refresh-builtin` | | Update builtin resources from `resources/` to `~/.takt/` |
| `takt /help` | | Show help message |
| `takt /config` | | Display current configuration |
## Architecture
### Core Flow
```
CLI (cli.ts)
→ Slash commands (/run-tasks, /watch, /add-task, /switch, /clear, /refresh-builtin, /help, /config)
→ or executeTask()
→ WorkflowEngine (workflow/engine.ts)
→ runAgent() (agents/runner.ts)
→ callClaude() (claude/client.ts)
→ executeClaudeCli() (claude/process.ts)
→ ClaudeProcess (claude-agent-sdk)
```
### Key Components
**WorkflowEngine** (`src/workflow/engine.ts`)
- State machine that orchestrates agent execution via EventEmitter
- Manages step transitions based on agent response status
- Emits events: `step:start`, `step:complete`, `step:blocked`, `step:loop_detected`, `workflow:complete`, `workflow:abort`, `iteration:limit`
- Supports loop detection (`LoopDetector`) and iteration limits
- Maintains agent sessions per step for conversation continuity
**Agent Runner** (`src/agents/runner.ts`)
- Resolves agent specs (name or path) to agent configurations
- Built-in agents with default tools:
- `coder`: Read/Glob/Grep/Edit/Write/Bash/WebSearch/WebFetch
- `architect`: Read/Glob/Grep/WebSearch/WebFetch
- `supervisor`: Read/Glob/Grep/Bash/WebSearch/WebFetch
- `planner`: Read/Glob/Grep/Bash/WebSearch/WebFetch
- Custom agents via `.takt/agents.yaml` or prompt files (.md)
- Supports Claude Code agents (`claudeAgent`) and skills (`claudeSkill`)
**Claude Integration** (`src/claude/`)
- `client.ts` - High-level API: `callClaude()`, `callClaudeCustom()`, `callClaudeAgent()`, `callClaudeSkill()`, status detection via regex patterns
- `process.ts` - SDK wrapper with `ClaudeProcess` class, re-exports query management
- `executor.ts` - Query execution using `@anthropic-ai/claude-agent-sdk`
- `query-manager.ts` - Concurrent query tracking with query IDs
**Configuration** (`src/config/`)
- `loader.ts` - Custom agent loading from `.takt/agents.yaml`
- `workflowLoader.ts` - YAML workflow parsing with Zod validation (loads from `~/.takt/workflows/` only)
- `agentLoader.ts` - Agent prompt file loading
- `paths.ts` - Directory structure (`.takt/`, `~/.takt/`), session management
**Task Management** (`src/task/`)
- `runner.ts` - TaskRunner class for managing task files (`.takt/tasks/`)
- `watcher.ts` - TaskWatcher class for polling and auto-executing tasks (used by `/watch`)
- `index.ts` - Task operations (getNextTask, completeTask, addTask)
### Data Flow
1. User provides task or slash command → CLI
2. CLI loads workflow from `~/.takt/workflows/{name}.yaml`
3. WorkflowEngine starts at `initialStep`
4. Each step: `buildInstruction()``runStep()``runAgent()``callClaude()` → detect status → `determineNextStep()`
5. Status patterns (regex in `statusPatterns`) determine next step via `transitions`
6. Special transitions: `COMPLETE` ends workflow successfully, `ABORT` ends with failure
### Status Detection
Agents output status markers (e.g., `[CODER:DONE]`) that are matched against `GENERIC_STATUS_PATTERNS` in `src/models/schemas.ts`. Common statuses: `done`, `blocked`, `approved`, `rejected`, `improve`, `in_progress`, `interrupted`.
## Directory Structure
```
~/.takt/ # Global user config (created on first run)
config.yaml # Trusted dirs, default workflow, log level, language
workflows/ # Workflow YAML files (required location)
agents/ # Agent prompt files (.md)
.takt/ # Project-level config
agents.yaml # Custom agent definitions
tasks/ # Task files for /run-tasks
reports/ # Execution reports (auto-generated)
logs/ # Session logs (gitignored)
resources/ # Bundled defaults (copied to ~/.takt on init)
global/
en/ # English agents and workflows
ja/ # Japanese agents and workflows
```
## Workflow YAML Schema
```yaml
name: workflow-name
description: Optional description
max_iterations: 10 # snake_case in YAML
steps:
- name: step-name
agent: ~/.takt/agents/default/coder.md # Path to agent prompt
agent_name: coder # Display name (optional)
provider: codex # claude|codex (optional)
model: opus # Model name (optional)
instruction_template: |
{task}
{previous_response}
pass_previous_response: true # Default: true
transitions:
- condition: done
next_step: next-step
- condition: blocked
next_step: ABORT
on_no_status: complete # complete|continue|stay
```
### Template Variables
| Variable | Description |
|----------|-------------|
| `{task}` | Original user request |
| `{iteration}` | Current iteration number |
| `{max_iterations}` | Maximum iterations |
| `{previous_response}` | Previous step output (requires `pass_previous_response: true`) |
| `{user_inputs}` | Accumulated user inputs during workflow |
| `{git_diff}` | Current git diff (uncommitted changes) |
| `{report_dir}` | Report directory name (e.g., `20250126-143052-task-summary`) |
### Model Resolution
Model is resolved in the following priority order:
1. **Workflow step `model`** - Highest priority (specified in step YAML)
2. **Custom agent `model`** - Agent-level model in `.takt/agents.yaml`
3. **Global config `model`** - Default model in `~/.takt/config.yaml`
4. **Provider default** - Falls back to provider's default (Claude: sonnet, Codex: gpt-5.2-codex)
Example `~/.takt/config.yaml`:
```yaml
provider: claude
model: opus # Default model for all steps (unless overridden)
```
## TypeScript Notes
- ESM modules with `.js` extensions in imports
- Strict TypeScript with `noUncheckedIndexedAccess`
- Zod schemas (v4 syntax) for runtime validation (`src/models/schemas.ts`)
- Uses `@anthropic-ai/claude-agent-sdk` for Claude integration
## Design Principles
**Keep commands minimal.** One command per concept. Use arguments/modes instead of multiple similar commands. Before adding a new command, consider if existing commands can be extended.
**Do NOT expand schemas carelessly.** The `TransitionConditionSchema` defines allowed condition values for workflow transitions. Do NOT add new values without strong justification. Use existing values creatively:
- `done` - Task completed (minor fixes, successful completion)
- `blocked` - Cannot proceed (needs plan rework)
- `approved` - Review passed
- `rejected` - Review failed, needs major rework
- `improve` - Needs improvement (security concerns, quality issues)
- `always` - Unconditional transition
## Worktree Execution
When tasks specify `worktree: true` or `worktree: "path"`, code runs in a git worktree (separate checkout). Key constraints:
- **Session isolation**: Claude Code sessions are stored per-cwd in `~/.claude/projects/{encoded-path}/`. Sessions from the main project cannot be resumed in a worktree. The engine skips session resume when `cwd !== projectCwd`.
- **No node_modules**: Worktrees only contain tracked files. `node_modules/` is absent.
- **Dual cwd**: `cwd` = worktree path (where agents run), `projectCwd` = project root (where `.takt/` lives). Reports, logs, and session data always write to `projectCwd`.
## Error Propagation
`ClaudeResult` (from SDK) has an `error` field. This must be propagated through `AgentResponse.error` → session log history → console output. Without this, SDK failures (exit code 1, rate limits, auth errors) appear as empty `blocked` status with no diagnostic info.
## Testing Notes
- Vitest for testing framework
- Tests use file system fixtures in `__tests__/` subdirectories
- Mock workflows and agent configs for integration tests
- Test single files: `npx vitest run src/__tests__/filename.test.ts`
- Pattern matching: `npx vitest run -t "test pattern"`