update CLAUDE.md
This commit is contained in:
parent
6901b2a121
commit
96ff2ed961
348
CLAUDE.md
348
CLAUDE.md
@ -10,13 +10,19 @@ TAKT (TAKT Agent Koordination Topology) is a multi-agent orchestration system fo
|
|||||||
|
|
||||||
| Command | Description |
|
| Command | Description |
|
||||||
|---------|-------------|
|
|---------|-------------|
|
||||||
| `npm run build` | TypeScript build |
|
| `npm run build` | TypeScript build (also copies prompt .md, i18n .yaml, and preset .sh files to dist/) |
|
||||||
| `npm run watch` | TypeScript build in watch mode |
|
| `npm run watch` | TypeScript build in watch mode |
|
||||||
| `npm run test` | Run all tests |
|
| `npm run test` | Run all unit tests |
|
||||||
| `npm run test:watch` | Run tests in watch mode (alias: `npm run test -- --watch`) |
|
| `npm run test:watch` | Run tests in watch mode |
|
||||||
| `npm run lint` | ESLint |
|
| `npm run lint` | ESLint |
|
||||||
| `npx vitest run src/__tests__/client.test.ts` | Run single test file |
|
| `npx vitest run src/__tests__/client.test.ts` | Run single test file |
|
||||||
| `npx vitest run -t "pattern"` | Run tests matching pattern |
|
| `npx vitest run -t "pattern"` | Run tests matching pattern |
|
||||||
|
| `npm run test:e2e` | Run E2E tests with mock provider (includes GitHub connectivity check) |
|
||||||
|
| `npm run test:e2e:mock` | Run E2E tests with mock provider (direct, no connectivity check) |
|
||||||
|
| `npm run test:e2e:provider:claude` | Run E2E tests against Claude provider |
|
||||||
|
| `npm run test:e2e:provider:codex` | Run E2E tests against Codex provider |
|
||||||
|
| `npm run test:e2e:provider:opencode` | Run E2E tests against OpenCode provider |
|
||||||
|
| `npm run check:release` | Full release check (build + lint + test + e2e) with macOS notification |
|
||||||
| `npm run prepublishOnly` | Lint, build, and test before publishing |
|
| `npm run prepublishOnly` | Lint, build, and test before publishing |
|
||||||
|
|
||||||
## CLI Subcommands
|
## CLI Subcommands
|
||||||
@ -27,15 +33,25 @@ TAKT (TAKT Agent Koordination Topology) is a multi-agent orchestration system fo
|
|||||||
| `takt` | Interactive task input mode (chat with AI to refine requirements) |
|
| `takt` | Interactive task input mode (chat with AI to refine requirements) |
|
||||||
| `takt run` | Execute all pending tasks from `.takt/tasks/` once |
|
| `takt run` | Execute all pending tasks from `.takt/tasks/` once |
|
||||||
| `takt watch` | Watch `.takt/tasks/` and auto-execute tasks (resident process) |
|
| `takt watch` | Watch `.takt/tasks/` and auto-execute tasks (resident process) |
|
||||||
| `takt add` | Add a new task via AI conversation |
|
| `takt add [task]` | Add a new task via AI conversation |
|
||||||
| `takt list` | List task branches (try merge, merge & cleanup, or delete) |
|
| `takt list` | List task branches (merge, delete, retry) |
|
||||||
| `takt switch` | Switch piece interactively |
|
| `takt switch [piece]` | Switch piece interactively |
|
||||||
| `takt clear` | Clear agent conversation sessions (reset state) |
|
| `takt clear` | Clear agent conversation sessions (reset state) |
|
||||||
| `takt eject` | Copy builtin piece/agents to `~/.takt/` for customization |
|
| `takt eject [type] [name]` | Copy builtin piece or facet for customization (`--global` for ~/.takt/) |
|
||||||
|
| `takt prompt [piece]` | Preview assembled prompts for each movement and phase |
|
||||||
|
| `takt catalog [type]` | List available facets (personas, policies, knowledge, etc.) |
|
||||||
|
| `takt export-cc` | Export takt pieces/agents as Claude Code Skill (~/.claude/) |
|
||||||
|
| `takt reset config` | Reset global config to builtin template |
|
||||||
|
| `takt reset categories` | Reset piece categories to builtin defaults |
|
||||||
|
| `takt metrics review` | Show review quality metrics |
|
||||||
|
| `takt purge` | Purge old analytics event files |
|
||||||
|
| `takt repertoire add <spec>` | Install a repertoire package from GitHub |
|
||||||
|
| `takt repertoire remove <scope>` | Remove an installed repertoire package |
|
||||||
|
| `takt repertoire list` | List installed repertoire packages |
|
||||||
| `takt config` | Configure settings (permission mode) |
|
| `takt config` | Configure settings (permission mode) |
|
||||||
| `takt --help` | Show help message |
|
| `takt --help` | Show help message |
|
||||||
|
|
||||||
**Interactive mode:** Running `takt` (without arguments) or `takt {initial message}` starts an interactive planning session. The AI helps refine task requirements through conversation. Type `/go` to execute the task with the selected piece, or `/cancel` to abort. Implemented in `src/features/interactive/`.
|
**Interactive mode:** Running `takt` (without arguments) or `takt {initial message}` starts an interactive planning session. Supports 4 modes: `assistant` (default, AI asks clarifying questions), `passthrough` (passes input directly as task), `quiet` (generates instructions without questions), `persona` (uses first movement's persona for conversation). Type `/go` to execute the task with the selected piece, or `/cancel` to abort. Implemented in `src/features/interactive/`.
|
||||||
|
|
||||||
**Pipeline mode:** Specifying `--pipeline` enables non-interactive mode suitable for CI/CD. Automatically creates a branch, runs the piece, commits, and pushes. Use `--auto-pr` to also create a pull request. Use `--skip-git` to run piece only (no git operations). Implemented in `src/features/pipeline/`.
|
**Pipeline mode:** Specifying `--pipeline` enables non-interactive mode suitable for CI/CD. Automatically creates a branch, runs the piece, commits, and pushes. Use `--auto-pr` to also create a pull request. Use `--skip-git` to run piece only (no git operations). Implemented in `src/features/pipeline/`.
|
||||||
|
|
||||||
@ -48,36 +64,36 @@ TAKT (TAKT Agent Koordination Topology) is a multi-agent orchestration system fo
|
|||||||
| `--pipeline` | Enable pipeline (non-interactive) mode — required for CI/automation |
|
| `--pipeline` | Enable pipeline (non-interactive) mode — required for CI/automation |
|
||||||
| `-t, --task <text>` | Task content (as alternative to GitHub issue) |
|
| `-t, --task <text>` | Task content (as alternative to GitHub issue) |
|
||||||
| `-i, --issue <N>` | GitHub issue number (equivalent to `#N` in interactive mode) |
|
| `-i, --issue <N>` | GitHub issue number (equivalent to `#N` in interactive mode) |
|
||||||
| `-w, --piece <name or path>` | Piece name or path to piece YAML file (v0.3.8+) |
|
| `-w, --piece <name or path>` | Piece name or path to piece YAML file |
|
||||||
| `-b, --branch <name>` | Branch name (auto-generated if omitted) |
|
| `-b, --branch <name>` | Branch name (auto-generated if omitted) |
|
||||||
| `--auto-pr` | Create PR after execution (interactive: skip confirmation, pipeline: enable PR) |
|
| `--auto-pr` | Create PR after execution (interactive: skip confirmation, pipeline: enable PR) |
|
||||||
| `--skip-git` | Skip branch creation, commit, and push (pipeline mode, piece-only) |
|
| `--skip-git` | Skip branch creation, commit, and push (pipeline mode, piece-only) |
|
||||||
| `--repo <owner/repo>` | Repository for PR creation |
|
| `--repo <owner/repo>` | Repository for PR creation |
|
||||||
| `--create-worktree <yes\|no>` | Skip worktree confirmation prompt |
|
| `--create-worktree <yes\|no>` | Skip worktree confirmation prompt |
|
||||||
| `-q, --quiet` | **Minimal output mode: suppress AI output (for CI)** (v0.3.8+) |
|
| `-q, --quiet` | Minimal output mode: suppress AI output (for CI) |
|
||||||
| `--provider <name>` | Override agent provider (claude\|codex\|mock) (v0.3.8+) |
|
| `--provider <name>` | Override agent provider (claude\|codex\|opencode\|mock) |
|
||||||
| `--model <name>` | Override agent model (v0.3.8+) |
|
| `--model <name>` | Override agent model |
|
||||||
| `--config <path>` | Path to global config file (default: `~/.takt/config.yaml`) (v0.3.8+) |
|
| `--config <path>` | Path to global config file (default: `~/.takt/config.yaml`) |
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
### Core Flow
|
### Core Flow
|
||||||
|
|
||||||
```
|
```
|
||||||
CLI (cli.ts)
|
CLI (cli.ts → routing.ts)
|
||||||
→ Slash commands or executeTask()
|
→ Interactive mode / Pipeline mode / Direct task execution
|
||||||
→ PieceEngine (piece/engine.ts)
|
→ PieceEngine (piece/engine/PieceEngine.ts)
|
||||||
→ Per movement: 3-phase execution
|
→ Per movement, delegates to one of 4 runners:
|
||||||
Phase 1: runAgent() → main work
|
MovementExecutor — Normal movements (3-phase execution)
|
||||||
Phase 2: runReportPhase() → report output (if output_contracts defined)
|
ParallelRunner — Parallel sub-movements via Promise.allSettled()
|
||||||
Phase 3: runStatusJudgmentPhase() → status tag output (if tag-based rules)
|
ArpeggioRunner — Data-driven batch processing (CSV → template → LLM)
|
||||||
→ detectMatchedRule() → rule evaluation → determineNextStep()
|
TeamLeaderRunner — Dynamic task decomposition into sub-parts
|
||||||
→ Parallel movements: Promise.all() for sub-movements, aggregate evaluation
|
→ detectMatchedRule() → rule evaluation → determineNextMovementByRules()
|
||||||
```
|
```
|
||||||
|
|
||||||
### Three-Phase Movement Execution
|
### Three-Phase Movement Execution
|
||||||
|
|
||||||
Each movement executes in up to 3 phases (session is resumed across phases):
|
Each normal movement executes in up to 3 phases (session is resumed across phases):
|
||||||
|
|
||||||
| Phase | Purpose | Tools | When |
|
| Phase | Purpose | Tools | When |
|
||||||
|-------|---------|-------|------|
|
|-------|---------|-------|------|
|
||||||
@ -85,7 +101,7 @@ Each movement executes in up to 3 phases (session is resumed across phases):
|
|||||||
| Phase 2 | Report output | Write only | When `output_contracts` is defined |
|
| Phase 2 | Report output | Write only | When `output_contracts` is defined |
|
||||||
| Phase 3 | Status judgment | None (judgment only) | When movement has tag-based rules |
|
| Phase 3 | Status judgment | None (judgment only) | When movement has tag-based rules |
|
||||||
|
|
||||||
Phase 2/3 are implemented in `src/core/piece/engine/phase-runner.ts`. The session is resumed so the agent retains context from Phase 1.
|
Phase 2/3 are implemented in `src/core/piece/phase-runner.ts`. The session is resumed so the agent retains context from Phase 1.
|
||||||
|
|
||||||
### Rule Evaluation (5-Stage Fallback)
|
### Rule Evaluation (5-Stage Fallback)
|
||||||
|
|
||||||
@ -97,35 +113,48 @@ After movement execution, rules are evaluated to determine the next movement. Ev
|
|||||||
4. **AI judge (ai() only)** - AI evaluates `ai("condition text")` rules
|
4. **AI judge (ai() only)** - AI evaluates `ai("condition text")` rules
|
||||||
5. **AI judge fallback** - AI evaluates ALL conditions as final resort
|
5. **AI judge fallback** - AI evaluates ALL conditions as final resort
|
||||||
|
|
||||||
Implemented in `src/core/piece/evaluation/RuleEvaluator.ts`. The matched method is tracked as `RuleMatchMethod` type.
|
Implemented in `src/core/piece/evaluation/RuleEvaluator.ts`. The matched method is tracked as `RuleMatchMethod` type (`aggregate`, `auto_select`, `structured_output`, `phase3_tag`, `phase1_tag`, `ai_judge`, `ai_judge_fallback`).
|
||||||
|
|
||||||
### Key Components
|
### Key Components
|
||||||
|
|
||||||
**PieceEngine** (`src/core/piece/engine/PieceEngine.ts`)
|
**PieceEngine** (`src/core/piece/engine/PieceEngine.ts`)
|
||||||
- State machine that orchestrates agent execution via EventEmitter
|
- State machine that orchestrates agent execution via EventEmitter
|
||||||
- Manages movement transitions based on rule evaluation results
|
- Manages movement transitions based on rule evaluation results
|
||||||
- Emits events: `step:start`, `step:complete`, `step:blocked`, `step:loop_detected`, `piece:complete`, `piece:abort`, `iteration:limit`
|
- Emits events: `movement:start`, `movement:complete`, `movement:blocked`, `movement:report`, `movement:user_input`, `movement:loop_detected`, `movement:cycle_detected`, `phase:start`, `phase:complete`, `piece:complete`, `piece:abort`, `iteration:limit`
|
||||||
- Supports loop detection (`LoopDetector`) and iteration limits
|
- Supports loop detection (`LoopDetector`), cycle detection (`CycleDetector`), and iteration limits
|
||||||
- Maintains agent sessions per movement for conversation continuity
|
- Maintains agent sessions per movement for conversation continuity
|
||||||
- Delegates to `StepExecutor` (normal steps) and `ParallelRunner` (parallel steps)
|
- Delegates to `MovementExecutor` (normal), `ParallelRunner` (parallel), `ArpeggioRunner` (data-driven batch), and `TeamLeaderRunner` (task decomposition)
|
||||||
|
|
||||||
**StepExecutor** (`src/core/piece/engine/StepExecutor.ts`)
|
**MovementExecutor** (`src/core/piece/engine/MovementExecutor.ts`)
|
||||||
- Executes a single piece movement through the 3-phase model
|
- Executes a single piece movement through the 3-phase model
|
||||||
- Phase 1: Main agent execution (with tools)
|
- Phase 1: Main agent execution (with tools)
|
||||||
- Phase 2: Report output (Write-only, optional)
|
- Phase 2: Report output (Write-only, optional)
|
||||||
- Phase 3: Status judgment (no tools, optional)
|
- Phase 3: Status judgment (no tools, optional)
|
||||||
- Builds instructions via `InstructionBuilder`, detects matched rules via `RuleEvaluator`
|
- Builds instructions via `InstructionBuilder`, detects matched rules via `RuleEvaluator`
|
||||||
|
- Writes facet snapshots (knowledge/policy) per movement iteration
|
||||||
|
|
||||||
|
**ArpeggioRunner** (`src/core/piece/engine/ArpeggioRunner.ts`)
|
||||||
|
- Data-driven batch processing: reads data from a source (e.g., CSV), expands templates per batch, calls LLM for each batch with concurrency control
|
||||||
|
- Supports retry logic with configurable `maxRetries` and `retryDelayMs`
|
||||||
|
- Merge strategies: `concat` (default, join with separator) or `custom` (inline JS or file-based)
|
||||||
|
- Optional output file writing via `outputPath`
|
||||||
|
|
||||||
|
**TeamLeaderRunner** (`src/core/piece/engine/TeamLeaderRunner.ts`)
|
||||||
|
- Decomposes a task into sub-parts via AI (`decomposeTask()`), then executes each part as a sub-agent
|
||||||
|
- Uses `PartDefinition` schema (id, title, instruction, optional timeoutMs) for decomposed tasks
|
||||||
|
- Configured via `TeamLeaderConfig` (maxParts ≤3, separate persona/tools/permissions for parts)
|
||||||
|
- Aggregates sub-part results and evaluates parent rules
|
||||||
|
|
||||||
**ParallelRunner** (`src/core/piece/engine/ParallelRunner.ts`)
|
**ParallelRunner** (`src/core/piece/engine/ParallelRunner.ts`)
|
||||||
- Executes parallel sub-movements concurrently via `Promise.all()`
|
- Executes parallel sub-movements concurrently via `Promise.allSettled()`
|
||||||
- Aggregates sub-movement results for parent rule evaluation
|
- Uses `ParallelLogger` to prefix sub-movement output for readable interleaved display
|
||||||
- Supports `all()` / `any()` aggregate conditions
|
- Aggregates sub-movement results for parent rule evaluation with `all()` / `any()` conditions
|
||||||
|
|
||||||
**RuleEvaluator** (`src/core/piece/evaluation/RuleEvaluator.ts`)
|
**RuleEvaluator** (`src/core/piece/evaluation/RuleEvaluator.ts`)
|
||||||
- 5-stage fallback evaluation: aggregate → Phase 3 tag → Phase 1 tag → ai() judge → all-conditions AI judge
|
- 5-stage fallback evaluation: aggregate → Phase 3 tag → Phase 1 tag → ai() judge → all-conditions AI judge
|
||||||
- Returns `RuleMatch` with index and detection method (`aggregate`, `phase3_tag`, `phase1_tag`, `ai_judge`, `ai_fallback`)
|
- Returns `RuleMatch` with index and detection method
|
||||||
- Fail-fast: throws if rules exist but no rule matched
|
- Fail-fast: throws if rules exist but no rule matched
|
||||||
- **v0.3.8+:** Tag detection now uses **last match** instead of first match when multiple `[STEP:N]` tags appear in output
|
- Tag detection uses **last match** when multiple `[STEP:N]` tags appear in output
|
||||||
|
|
||||||
**Instruction Builder** (`src/core/piece/instruction/InstructionBuilder.ts`)
|
**Instruction Builder** (`src/core/piece/instruction/InstructionBuilder.ts`)
|
||||||
- Auto-injects standard sections into every instruction (no need for `{task}` or `{previous_response}` placeholders in templates):
|
- Auto-injects standard sections into every instruction (no need for `{task}` or `{previous_response}` placeholders in templates):
|
||||||
@ -141,59 +170,82 @@ Implemented in `src/core/piece/evaluation/RuleEvaluator.ts`. The matched method
|
|||||||
|
|
||||||
**Agent Runner** (`src/agents/runner.ts`)
|
**Agent Runner** (`src/agents/runner.ts`)
|
||||||
- Resolves agent specs (name or path) to agent configurations
|
- Resolves agent specs (name or path) to agent configurations
|
||||||
- **v0.3.8+:** Agent is optional — movements can execute with `instruction_template` only (no system prompt)
|
- Agent is optional — movements can execute with `instruction_template` only (no system prompt)
|
||||||
- Built-in agents with default tools:
|
- 4-layer resolution for provider/model: options.provider → options.stepProvider → config.provider → agentConfig.provider
|
||||||
- `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)
|
- Custom agents via `.takt/agents.yaml` or prompt files (.md)
|
||||||
- Inline system prompts: If agent file doesn't exist, the agent string is used as inline system prompt
|
- Inline system prompts: If agent file doesn't exist, the agent string is used as inline system prompt
|
||||||
|
|
||||||
**Provider Integration** (`src/infra/claude/`, `src/infra/codex/`)
|
**Provider Integration** (`src/infra/providers/`)
|
||||||
- **Claude** - Uses `@anthropic-ai/claude-agent-sdk`
|
- Unified `Provider` interface: `setup(AgentSetup) → ProviderAgent`, `ProviderAgent.call(prompt, options) → AgentResponse`
|
||||||
|
- **Claude** (`src/infra/claude/`) - Uses `@anthropic-ai/claude-agent-sdk`
|
||||||
- `client.ts` - High-level API: `callClaude()`, `callClaudeCustom()`, `callClaudeAgent()`, `callClaudeSkill()`
|
- `client.ts` - High-level API: `callClaude()`, `callClaudeCustom()`, `callClaudeAgent()`, `callClaudeSkill()`
|
||||||
- `process.ts` - SDK wrapper with `ClaudeProcess` class
|
- `process.ts` - SDK wrapper with `ClaudeProcess` class
|
||||||
- `executor.ts` - Query execution
|
- `executor.ts` - Query execution
|
||||||
- `query-manager.ts` - Concurrent query tracking with query IDs
|
- `query-manager.ts` - Concurrent query tracking with query IDs
|
||||||
- **Codex** - Direct OpenAI SDK integration
|
- **Codex** (`src/infra/codex/`) - Uses `@openai/codex-sdk`
|
||||||
- `CodexStreamHandler.ts` - Stream handling and tool execution
|
- Retry logic with exponential backoff (3 attempts, 250ms base)
|
||||||
|
- Stream handling with idle timeout (10 minutes)
|
||||||
|
- **OpenCode** (`src/infra/opencode/`) - Uses `@opencode-ai/sdk/v2`
|
||||||
|
- Shared server pooling with `acquireClient()` / `releaseClient()`
|
||||||
|
- Client-side permission auto-reply
|
||||||
|
- Requires explicit `model` specification (no default)
|
||||||
|
- **Mock** (`src/infra/mock/`) - Deterministic responses for testing
|
||||||
|
|
||||||
**Configuration** (`src/infra/config/`)
|
**Configuration** (`src/infra/config/`)
|
||||||
- `loaders/loader.ts` - Custom agent loading from `.takt/agents.yaml`
|
- `loaders/pieceParser.ts` - YAML parsing, movement/rule normalization with Zod validation. Rule regex: `AI_CONDITION_REGEX = /^ai\("(.+)"\)$/`, `AGGREGATE_CONDITION_REGEX = /^(all|any)\((.+)\)$/`
|
||||||
- `loaders/pieceParser.ts` - YAML parsing, movement/rule normalization with Zod validation
|
- `loaders/pieceResolver.ts` - **3-layer resolution**: project `.takt/pieces/` → user `~/.takt/pieces/` → builtin `builtins/{lang}/pieces/`. Also supports repertoire packages `@{owner}/{repo}/{piece-name}`
|
||||||
- `loaders/pieceResolver.ts` - **3-layer resolution with correct priority** (v0.3.8+: user → project → builtin)
|
|
||||||
- `loaders/pieceCategories.ts` - Piece categorization and filtering
|
- `loaders/pieceCategories.ts` - Piece categorization and filtering
|
||||||
- `loaders/agentLoader.ts` - Agent prompt file loading
|
- `loaders/agentLoader.ts` - Agent prompt file loading
|
||||||
- `paths.ts` - Directory structure (`.takt/`, `~/.takt/`), session management
|
- `paths.ts` - Directory structure (`.takt/`, `~/.takt/`), session management
|
||||||
- `global/globalConfig.ts` - Global configuration (provider, model, trusted dirs, **quiet mode** v0.3.8+)
|
- `global/globalConfig.ts` - Global configuration (provider, model, language, quiet mode)
|
||||||
- `project/projectConfig.ts` - Project-level configuration
|
- `project/projectConfig.ts` - Project-level configuration
|
||||||
|
|
||||||
**Task Management** (`src/features/tasks/`)
|
**Task Management** (`src/features/tasks/`)
|
||||||
- `execute/taskExecution.ts` - Main task execution orchestration
|
- `execute/taskExecution.ts` - Main task execution orchestration, worker pool for parallel tasks
|
||||||
- `execute/pieceExecution.ts` - Piece execution wrapper
|
- `execute/pieceExecution.ts` - Piece execution wrapper, analytics integration, NDJSON logging
|
||||||
- `add/index.ts` - Interactive task addition via AI conversation
|
- `add/index.ts` - Interactive task addition via AI conversation
|
||||||
- `list/index.ts` - List task branches with merge/delete actions
|
- `list/index.ts` - List task branches with merge/delete/retry actions
|
||||||
- `watch/index.ts` - Watch for task files and auto-execute
|
- `watch/index.ts` - Watch for task files and auto-execute
|
||||||
|
|
||||||
|
**Repertoire** (`src/features/repertoire/`)
|
||||||
|
- Package management for external facet/piece collections
|
||||||
|
- Install from GitHub: `github:{owner}/{repo}@{ref}`
|
||||||
|
- Config validation via `takt-repertoire.yaml` (path constraints, min_version semver check)
|
||||||
|
- Lock file for resolved dependencies
|
||||||
|
- Packages installed to `~/.takt/repertoire/@{owner}/{repo}/`
|
||||||
|
|
||||||
|
**Analytics** (`src/features/analytics/`)
|
||||||
|
- Event types: `MovementResultEvent`, `ReviewFindingEvent`, `FixActionEvent`, `RebuttalEvent`
|
||||||
|
- NDJSON storage at `.takt/events/`
|
||||||
|
- Integrated into piece execution: movement results, review findings, fix actions
|
||||||
|
|
||||||
|
**Catalog** (`src/features/catalog/`)
|
||||||
|
- Scans 3 layers (builtin → user → project) for available facets
|
||||||
|
- Shows override detection and source provenance
|
||||||
|
|
||||||
|
**Faceted Prompting** (`src/faceted-prompting/`)
|
||||||
|
- Independent module (no TAKT dependencies) for composing prompts from facets
|
||||||
|
- `compose(facets, options)` → `ComposedPrompt` (systemPrompt + userMessage)
|
||||||
|
- Supports template rendering, context truncation, facet path resolution, scope references
|
||||||
|
|
||||||
**GitHub Integration** (`src/infra/github/`)
|
**GitHub Integration** (`src/infra/github/`)
|
||||||
- `issue.ts` - Fetches issues via `gh` CLI, formats as task text with title/body/labels/comments
|
- `issue.ts` - Fetches issues via `gh` CLI, formats as task text, supports `createIssue()`
|
||||||
- `pr.ts` - Creates pull requests via `gh` CLI
|
- `pr.ts` - Creates pull requests via `gh` CLI, supports draft PRs and custom templates
|
||||||
|
|
||||||
### Data Flow
|
### Data Flow
|
||||||
|
|
||||||
1. User provides task (text or `#N` issue reference) or slash command → CLI
|
1. User provides task (text or `#N` issue reference) or slash command → CLI
|
||||||
2. CLI loads piece with **correct priority** (v0.3.8+): user `~/.takt/pieces/` → project `.takt/pieces/` → builtin `builtins/{lang}/pieces/`
|
2. CLI loads piece with **priority**: project `.takt/pieces/` → user `~/.takt/pieces/` → builtin `builtins/{lang}/pieces/`
|
||||||
3. PieceEngine starts at `initial_movement`
|
3. PieceEngine starts at `initial_movement`
|
||||||
4. Each movement: `buildInstruction()` → Phase 1 (main) → Phase 2 (report) → Phase 3 (status) → `detectMatchedRule()` → `determineNextStep()`
|
4. Each movement: delegate to appropriate runner → 3-phase execution → `detectMatchedRule()` → `determineNextMovementByRules()`
|
||||||
5. Rule evaluation determines next movement name (v0.3.8+: uses **last match** when multiple `[STEP:N]` tags appear)
|
5. Rule evaluation determines next movement name (uses **last match** when multiple `[STEP:N]` tags appear)
|
||||||
6. Special transitions: `COMPLETE` ends piece successfully, `ABORT` ends with failure
|
6. Special transitions: `COMPLETE` ends piece successfully, `ABORT` ends with failure
|
||||||
|
|
||||||
## Directory Structure
|
## Directory Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
~/.takt/ # Global user config (created on first run)
|
~/.takt/ # Global user config (created on first run)
|
||||||
config.yaml # Trusted dirs, default piece, log level, language
|
config.yaml # Language, provider, model, log level, etc.
|
||||||
pieces/ # User piece YAML files (override builtins)
|
pieces/ # User piece YAML files (override builtins)
|
||||||
facets/ # User facets
|
facets/ # User facets
|
||||||
personas/ # User persona prompt files (.md)
|
personas/ # User persona prompt files (.md)
|
||||||
@ -202,14 +254,16 @@ Implemented in `src/core/piece/evaluation/RuleEvaluator.ts`. The matched method
|
|||||||
instructions/ # User instruction files
|
instructions/ # User instruction files
|
||||||
output-contracts/ # User output contract files
|
output-contracts/ # User output contract files
|
||||||
repertoire/ # Installed repertoire packages
|
repertoire/ # Installed repertoire packages
|
||||||
|
@{owner}/{repo}/ # Per-package directory
|
||||||
|
|
||||||
.takt/ # Project-level config
|
.takt/ # Project-level config
|
||||||
config.yaml # Project configuration
|
config.yaml # Project configuration
|
||||||
agents.yaml # Custom agent definitions
|
agents.yaml # Custom agent definitions
|
||||||
facets/ # Project-level facets
|
facets/ # Project-level facets
|
||||||
tasks/ # Task files for /run-tasks
|
tasks/ # Task files for takt run
|
||||||
runs/ # Execution reports, logs, context
|
runs/ # Execution reports (runs/{slug}/reports/)
|
||||||
logs/ # Session logs in NDJSON format (gitignored)
|
logs/ # Session logs in NDJSON format (gitignored)
|
||||||
|
events/ # Analytics event files (NDJSON)
|
||||||
|
|
||||||
builtins/ # Bundled defaults (builtin, read from dist/ at runtime)
|
builtins/ # Bundled defaults (builtin, read from dist/ at runtime)
|
||||||
en/ # English
|
en/ # English
|
||||||
@ -220,7 +274,7 @@ builtins/ # Bundled defaults (builtin, read from dist/ at runtim
|
|||||||
skill/ # Claude Code skill files
|
skill/ # Claude Code skill files
|
||||||
```
|
```
|
||||||
|
|
||||||
Builtin resources are embedded in the npm package (`builtins/`). User files in `~/.takt/` take priority. Use `/eject` to copy builtins to `~/.takt/` for customization.
|
Builtin resources are embedded in the npm package (`builtins/`). Project files in `.takt/` take highest priority, then user files in `~/.takt/`, then builtins. Use `takt eject` to copy builtins for customization.
|
||||||
|
|
||||||
## Piece YAML Schema
|
## Piece YAML Schema
|
||||||
|
|
||||||
@ -229,6 +283,30 @@ name: piece-name
|
|||||||
description: Optional description
|
description: Optional description
|
||||||
max_movements: 10
|
max_movements: 10
|
||||||
initial_movement: plan # First movement to execute
|
initial_movement: plan # First movement to execute
|
||||||
|
interactive_mode: assistant # Default interactive mode (assistant|passthrough|quiet|persona)
|
||||||
|
answer_agent: agent-name # Route AskUserQuestion to this agent (optional)
|
||||||
|
|
||||||
|
# Piece-level provider options (inherited by all movements unless overridden)
|
||||||
|
piece_config:
|
||||||
|
provider_options:
|
||||||
|
codex: { network_access: true }
|
||||||
|
opencode: { network_access: true }
|
||||||
|
claude: { sandbox: { allow_unsandboxed_commands: true } }
|
||||||
|
runtime:
|
||||||
|
prepare: [node, gradle, ./custom-script.sh] # Runtime environment preparation
|
||||||
|
|
||||||
|
# Loop monitors (cycle detection between movements)
|
||||||
|
loop_monitors:
|
||||||
|
- cycle: [review, fix] # Movement names forming the cycle
|
||||||
|
threshold: 3 # Cycles before triggering judge
|
||||||
|
judge:
|
||||||
|
persona: supervisor
|
||||||
|
instruction_template: "Evaluate if the fix loop is making progress..."
|
||||||
|
rules:
|
||||||
|
- condition: "Progress is being made"
|
||||||
|
next: fix
|
||||||
|
- condition: "No progress"
|
||||||
|
next: ABORT
|
||||||
|
|
||||||
# Section maps (key → file path relative to piece YAML directory)
|
# Section maps (key → file path relative to piece YAML directory)
|
||||||
personas:
|
personas:
|
||||||
@ -248,13 +326,24 @@ movements:
|
|||||||
- name: movement-name
|
- name: movement-name
|
||||||
persona: coder # Persona key (references section map)
|
persona: coder # Persona key (references section map)
|
||||||
persona_name: coder # Display name (optional)
|
persona_name: coder # Display name (optional)
|
||||||
|
session: continue # Session continuity: continue (default) | refresh
|
||||||
policy: coding # Policy key (single or array)
|
policy: coding # Policy key (single or array)
|
||||||
knowledge: architecture # Knowledge key (single or array)
|
knowledge: architecture # Knowledge key (single or array)
|
||||||
instruction: plan # Instruction key (references section map)
|
instruction: plan # Instruction key (references section map)
|
||||||
provider: codex # claude|codex|opencode (optional)
|
provider: claude # claude|codex|opencode|mock (optional)
|
||||||
model: opus # Model name (optional)
|
model: opus # Model name (optional)
|
||||||
edit: true # Whether movement can edit files
|
edit: true # Whether movement can edit files
|
||||||
required_permission_mode: edit # Required minimum permission mode (optional)
|
required_permission_mode: edit # Required minimum permission mode (optional)
|
||||||
|
quality_gates: # AI directives for completion (optional)
|
||||||
|
- "All tests pass"
|
||||||
|
- "No lint errors"
|
||||||
|
provider_options: # Per-provider options (optional)
|
||||||
|
codex: { network_access: true }
|
||||||
|
claude: { sandbox: { excluded_commands: [rm] } }
|
||||||
|
mcp_servers: # MCP server configuration (optional)
|
||||||
|
my-server:
|
||||||
|
command: npx
|
||||||
|
args: [-y, my-mcp-server]
|
||||||
instruction_template: |
|
instruction_template: |
|
||||||
Custom instructions for this movement.
|
Custom instructions for this movement.
|
||||||
{task}, {previous_response} are auto-injected if not present as placeholders.
|
{task}, {previous_response} are auto-injected if not present as placeholders.
|
||||||
@ -263,6 +352,7 @@ movements:
|
|||||||
report:
|
report:
|
||||||
- name: 01-plan.md # Report file name
|
- name: 01-plan.md # Report file name
|
||||||
format: plan # References report_formats map
|
format: plan # References report_formats map
|
||||||
|
order: "Write the plan to {report_dir}/01-plan.md" # Instruction prepend
|
||||||
rules:
|
rules:
|
||||||
- condition: "Human-readable condition"
|
- condition: "Human-readable condition"
|
||||||
next: next-movement-name
|
next: next-movement-name
|
||||||
@ -270,6 +360,7 @@ movements:
|
|||||||
next: other-movement
|
next: other-movement
|
||||||
- condition: blocked
|
- condition: blocked
|
||||||
next: ABORT
|
next: ABORT
|
||||||
|
requires_user_input: true # Wait for user input (interactive only)
|
||||||
|
|
||||||
# Parallel movement (sub-movements execute concurrently)
|
# Parallel movement (sub-movements execute concurrently)
|
||||||
- name: reviewers
|
- name: reviewers
|
||||||
@ -280,7 +371,7 @@ movements:
|
|||||||
knowledge: architecture
|
knowledge: architecture
|
||||||
edit: false
|
edit: false
|
||||||
rules:
|
rules:
|
||||||
- condition: approved # next is optional for sub-movements
|
- condition: approved
|
||||||
- condition: needs_fix
|
- condition: needs_fix
|
||||||
instruction: review-arch
|
instruction: review-arch
|
||||||
- name: security-review
|
- name: security-review
|
||||||
@ -290,18 +381,51 @@ movements:
|
|||||||
- condition: approved
|
- condition: approved
|
||||||
- condition: needs_fix
|
- condition: needs_fix
|
||||||
instruction: review-security
|
instruction: review-security
|
||||||
rules: # Parent rules use aggregate conditions
|
rules:
|
||||||
- condition: all("approved")
|
- condition: all("approved")
|
||||||
next: supervise
|
next: supervise
|
||||||
- condition: any("needs_fix")
|
- condition: any("needs_fix")
|
||||||
next: fix
|
next: fix
|
||||||
|
|
||||||
|
# Arpeggio movement (data-driven batch processing)
|
||||||
|
- name: batch-process
|
||||||
|
persona: coder
|
||||||
|
arpeggio:
|
||||||
|
source: csv
|
||||||
|
source_path: ./data/items.csv # Relative to piece YAML
|
||||||
|
batch_size: 5 # Rows per batch (default: 1)
|
||||||
|
concurrency: 3 # Concurrent LLM calls (default: 1)
|
||||||
|
template: ./templates/process.txt # Prompt template file
|
||||||
|
max_retries: 2 # Retry attempts per batch (default: 2)
|
||||||
|
retry_delay_ms: 1000 # Delay between retries (default: 1000)
|
||||||
|
merge:
|
||||||
|
strategy: concat # concat (default) | custom
|
||||||
|
separator: "\n---\n" # For concat strategy
|
||||||
|
output_path: ./output/result.txt # Write merged results (optional)
|
||||||
|
rules:
|
||||||
|
- condition: "Processing complete"
|
||||||
|
next: COMPLETE
|
||||||
|
|
||||||
|
# Team leader movement (dynamic task decomposition)
|
||||||
|
- name: implement
|
||||||
|
team_leader:
|
||||||
|
max_parts: 3 # Max parallel parts (1-3, default: 3)
|
||||||
|
timeout_ms: 600000 # Per-part timeout (default: 600s)
|
||||||
|
part_persona: coder # Persona for part agents
|
||||||
|
part_edit: true # Edit permission for parts
|
||||||
|
part_permission_mode: edit # Permission mode for parts
|
||||||
|
part_allowed_tools: [Read, Glob, Grep, Edit, Write, Bash]
|
||||||
|
instruction_template: |
|
||||||
|
Decompose this task into independent subtasks.
|
||||||
|
rules:
|
||||||
|
- condition: "All parts completed"
|
||||||
|
next: review
|
||||||
```
|
```
|
||||||
|
|
||||||
Key points about parallel movements:
|
Key points about movement types (mutually exclusive: `parallel`, `arpeggio`, `team_leader`):
|
||||||
- Sub-movement `rules` define possible outcomes but `next` is ignored (parent handles routing)
|
- **Parallel**: Sub-movement `rules` define possible outcomes but `next` is ignored (parent handles routing). Parent uses `all("X")`/`any("X")` to aggregate.
|
||||||
- Parent `rules` use `all("X")`/`any("X")` to aggregate sub-movement results
|
- **Arpeggio**: Template placeholders: `{line:N}`, `{col:N:name}`, `{batch_index}`, `{total_batches}`. Merge custom strategy supports inline JS or file.
|
||||||
- `all("X")`: true if ALL sub-movements matched condition X
|
- **Team leader**: AI generates `PartDefinition[]` (JSON in ```json block), each part executed as sub-movement.
|
||||||
- `any("X")`: true if ANY sub-movements matched condition X
|
|
||||||
|
|
||||||
### Rule Condition Types
|
### Rule Condition Types
|
||||||
|
|
||||||
@ -351,8 +475,6 @@ show_others_category: true
|
|||||||
others_category_name: "Other Pieces"
|
others_category_name: "Other Pieces"
|
||||||
```
|
```
|
||||||
|
|
||||||
Implemented in `src/infra/config/loaders/pieceCategories.ts`.
|
|
||||||
|
|
||||||
### Model Resolution
|
### Model Resolution
|
||||||
|
|
||||||
Model is resolved in the following priority order:
|
Model is resolved in the following priority order:
|
||||||
@ -362,11 +484,19 @@ Model is resolved in the following priority order:
|
|||||||
3. **Global config `model`** - Default model in `~/.takt/config.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)
|
4. **Provider default** - Falls back to provider's default (Claude: sonnet, Codex: gpt-5.2-codex)
|
||||||
|
|
||||||
Example `~/.takt/config.yaml`:
|
### Loop Detection
|
||||||
```yaml
|
|
||||||
provider: claude
|
Two distinct mechanisms:
|
||||||
model: opus # Default model for all movements (unless overridden)
|
|
||||||
```
|
**LoopDetector** (`src/core/piece/engine/loop-detector.ts`):
|
||||||
|
- Detects consecutive same-movement executions (simple counter)
|
||||||
|
- Configurable: `maxConsecutiveSameStep` (default: 10), `action` (`warn` | `abort` | `ignore`)
|
||||||
|
|
||||||
|
**CycleDetector** (`src/core/piece/engine/cycle-detector.ts`):
|
||||||
|
- Detects cyclic patterns between movements (e.g., review → fix → review → fix)
|
||||||
|
- Configured via `loop_monitors` in piece config (cycle pattern + threshold + judge)
|
||||||
|
- When threshold reached, triggers a synthetic judge movement for decision-making
|
||||||
|
- Resets after judge intervention to prevent immediate re-triggering
|
||||||
|
|
||||||
## NDJSON Session Logging
|
## NDJSON Session Logging
|
||||||
|
|
||||||
@ -375,8 +505,8 @@ Session logs use NDJSON (`.jsonl`) format for real-time append-only writes. Reco
|
|||||||
| Record | Description |
|
| Record | Description |
|
||||||
|--------|-------------|
|
|--------|-------------|
|
||||||
| `piece_start` | Piece initialization with task, piece name |
|
| `piece_start` | Piece initialization with task, piece name |
|
||||||
| `step_start` | Step execution start |
|
| `movement_start` | Movement execution start |
|
||||||
| `step_complete` | Step result with status, content, matched rule info |
|
| `movement_complete` | Movement result with status, content, matched rule info |
|
||||||
| `piece_complete` | Successful completion |
|
| `piece_complete` | Successful completion |
|
||||||
| `piece_abort` | Abort with reason |
|
| `piece_abort` | Abort with reason |
|
||||||
|
|
||||||
@ -386,8 +516,8 @@ Files: `.takt/logs/{sessionId}.jsonl`, with `latest.json` pointer. Legacy `.json
|
|||||||
|
|
||||||
- ESM modules with `.js` extensions in imports
|
- ESM modules with `.js` extensions in imports
|
||||||
- Strict TypeScript with `noUncheckedIndexedAccess`
|
- Strict TypeScript with `noUncheckedIndexedAccess`
|
||||||
- Zod schemas for runtime validation (`src/core/models/schemas.ts`)
|
- Zod v4 schemas for runtime validation (`src/core/models/schemas.ts`)
|
||||||
- Uses `@anthropic-ai/claude-agent-sdk` for Claude integration
|
- Uses `@anthropic-ai/claude-agent-sdk` for Claude, `@openai/codex-sdk` for Codex, `@opencode-ai/sdk` for OpenCode
|
||||||
|
|
||||||
## Design Principles
|
## Design Principles
|
||||||
|
|
||||||
@ -424,12 +554,14 @@ Key rules:
|
|||||||
|
|
||||||
**Separation of concerns in piece engine:**
|
**Separation of concerns in piece engine:**
|
||||||
- `PieceEngine` - Orchestration, state management, event emission
|
- `PieceEngine` - Orchestration, state management, event emission
|
||||||
- `StepExecutor` - Single movement execution (3-phase model)
|
- `MovementExecutor` - Single movement execution (3-phase model)
|
||||||
- `ParallelRunner` - Parallel movement execution
|
- `ParallelRunner` - Parallel movement execution
|
||||||
|
- `ArpeggioRunner` - Data-driven batch processing
|
||||||
|
- `TeamLeaderRunner` - Dynamic task decomposition
|
||||||
- `RuleEvaluator` - Rule matching and evaluation
|
- `RuleEvaluator` - Rule matching and evaluation
|
||||||
- `InstructionBuilder` - Instruction template processing
|
- `InstructionBuilder` - Instruction template processing
|
||||||
|
|
||||||
**Session management:** Agent sessions are stored per-cwd in `~/.claude/projects/{encoded-path}/` (Claude Code) or in-memory (Codex). Sessions are resumed across phases (Phase 1 → Phase 2 → Phase 3) to maintain context. When `cwd !== projectCwd` (worktree/clone execution), session resume is skipped to avoid cross-directory contamination.
|
**Session management:** Agent sessions are stored per-cwd in `~/.claude/projects/{encoded-path}/` (Claude) or in-memory (Codex/OpenCode). Sessions are resumed across phases (Phase 1 → Phase 2 → Phase 3) to maintain context. Session key format: `{persona}:{provider}` to prevent cross-provider contamination. When `cwd !== projectCwd` (worktree/clone execution), session resume is skipped.
|
||||||
|
|
||||||
## Isolated Execution (Shared Clone)
|
## Isolated Execution (Shared Clone)
|
||||||
|
|
||||||
@ -448,14 +580,25 @@ Key constraints:
|
|||||||
|
|
||||||
## Error Propagation
|
## 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.
|
Provider errors 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.
|
||||||
|
|
||||||
**Error handling flow:**
|
**Error handling flow:**
|
||||||
1. Provider error (Claude SDK / Codex) → `AgentResponse.error`
|
1. Provider error (Claude SDK / Codex / OpenCode) → `AgentResponse.error`
|
||||||
2. `StepExecutor` captures error → `PieceEngine` emits `step:complete` with error
|
2. `MovementExecutor` captures error → `PieceEngine` emits `phase:complete` with error
|
||||||
3. Error logged to session log (`.takt/logs/{sessionId}.jsonl`)
|
3. Error logged to session log (`.takt/logs/{sessionId}.jsonl`)
|
||||||
4. Console output shows error details
|
4. Console output shows error details
|
||||||
5. Piece transitions to `ABORT` step if error is unrecoverable
|
5. Piece transitions to `ABORT` movement if error is unrecoverable
|
||||||
|
|
||||||
|
## Runtime Environment
|
||||||
|
|
||||||
|
Piece-level runtime preparation via `runtime.prepare` in piece config or `~/.takt/config.yaml`:
|
||||||
|
|
||||||
|
- **Presets**: `gradle` (sets `GRADLE_USER_HOME`, `JAVA_TOOL_OPTIONS`), `node` (sets `npm_config_cache`)
|
||||||
|
- **Custom scripts**: Arbitrary shell scripts, resolved relative to cwd or as absolute paths
|
||||||
|
- Environment injected: `TMPDIR`, `XDG_CACHE_HOME`, `XDG_CONFIG_HOME`, `XDG_STATE_HOME`, `CI=true`
|
||||||
|
- Creates `.takt/.runtime/` directory structure with `env.sh` for sourcing
|
||||||
|
|
||||||
|
Implemented in `src/core/runtime/runtime-environment.ts`.
|
||||||
|
|
||||||
## Debugging
|
## Debugging
|
||||||
|
|
||||||
@ -474,13 +617,15 @@ Debug logs are written to `.takt/logs/debug.log` (ndjson format). Log levels: `d
|
|||||||
|
|
||||||
## Testing Notes
|
## Testing Notes
|
||||||
|
|
||||||
- Vitest for testing framework
|
- Vitest for testing framework (single-thread mode, 15s timeout, 5s teardown timeout)
|
||||||
- Tests use file system fixtures in `__tests__/` subdirectories
|
- Unit tests: `src/__tests__/*.test.ts`
|
||||||
- Mock pieces and agent configs for integration tests
|
- E2E mock tests: configured via `vitest.config.e2e.mock.ts` (240s timeout, forceExit)
|
||||||
|
- E2E provider tests: configured via `vitest.config.e2e.provider.ts`
|
||||||
- Test single files: `npx vitest run src/__tests__/filename.test.ts`
|
- Test single files: `npx vitest run src/__tests__/filename.test.ts`
|
||||||
- Pattern matching: `npx vitest run -t "test pattern"`
|
- Pattern matching: `npx vitest run -t "test pattern"`
|
||||||
- Integration tests: Tests with `it-` prefix are integration tests that simulate full piece execution
|
- Integration tests: Tests with `it-` prefix simulate full piece execution
|
||||||
- Engine tests: Tests with `engine-` prefix test specific PieceEngine scenarios (happy path, error handling, parallel execution, etc.)
|
- Engine tests: Tests with `engine-` prefix test PieceEngine scenarios (happy path, error handling, parallel, arpeggio, team-leader, etc.)
|
||||||
|
- Environment variables cleared in test setup: `TAKT_CONFIG_DIR`, `TAKT_NOTIFY_WEBHOOK`
|
||||||
|
|
||||||
## Important Implementation Notes
|
## Important Implementation Notes
|
||||||
|
|
||||||
@ -500,31 +645,24 @@ Debug logs are written to `.takt/logs/debug.log` (ndjson format). Log levels: `d
|
|||||||
**Session continuity across phases:**
|
**Session continuity across phases:**
|
||||||
- Agent sessions persist across Phase 1 → Phase 2 → Phase 3 for context continuity
|
- Agent sessions persist across Phase 1 → Phase 2 → Phase 3 for context continuity
|
||||||
- Session ID is passed via `resumeFrom` in `RunAgentOptions`
|
- Session ID is passed via `resumeFrom` in `RunAgentOptions`
|
||||||
|
- Session key: `{persona}:{provider}` prevents cross-provider session contamination
|
||||||
- Sessions are stored per-cwd, so worktree executions create new sessions
|
- Sessions are stored per-cwd, so worktree executions create new sessions
|
||||||
- Use `takt clear` to reset all agent sessions
|
- Use `takt clear` to reset all agent sessions
|
||||||
|
|
||||||
**Worktree execution gotchas:**
|
|
||||||
- `git clone --shared` creates independent `.git` directory (not `git worktree`)
|
|
||||||
- Clone cwd ≠ project cwd: agents work in clone, reports write to clone, logs write to project
|
|
||||||
- Session resume is skipped when `cwd !== projectCwd` to avoid cross-directory contamination
|
|
||||||
- Reports write to `cwd/.takt/runs/{slug}/reports/` (clone) to prevent agents from discovering the main repository path via instruction
|
|
||||||
- Clones are ephemeral: created → task runs → auto-commit + push → deleted
|
|
||||||
- Use `takt list` to manage task branches after clone deletion
|
|
||||||
|
|
||||||
**Rule evaluation quirks:**
|
**Rule evaluation quirks:**
|
||||||
- Tag-based rules match by array index (0-based), not by exact condition text
|
- Tag-based rules match by array index (0-based), not by exact condition text
|
||||||
- **v0.3.8+:** When multiple `[STEP:N]` tags appear in output, **last match wins** (not first)
|
- When multiple `[STEP:N]` tags appear in output, **last match wins** (not first)
|
||||||
- `ai()` conditions are evaluated by Claude/Codex, not by string matching
|
- `ai()` conditions are evaluated by the provider, not by string matching
|
||||||
- Aggregate conditions (`all()`, `any()`) only work in parallel parent movements
|
- Aggregate conditions (`all()`, `any()`) only work in parallel parent movements
|
||||||
- Fail-fast: if rules exist but no rule matches, piece aborts
|
- Fail-fast: if rules exist but no rule matches, piece aborts
|
||||||
- Interactive-only rules are skipped in pipeline mode (`rule.interactiveOnly === true`)
|
- Interactive-only rules are skipped in pipeline mode (`rule.interactiveOnly === true`)
|
||||||
|
|
||||||
**Provider-specific behavior:**
|
**Provider-specific behavior:**
|
||||||
- Claude: Uses session files in `~/.claude/projects/`
|
- Claude: Uses session files in `~/.claude/projects/`, supports aliases: `opus`, `sonnet`, `haiku`
|
||||||
- Codex: In-memory sessions
|
- Codex: In-memory sessions, retry with exponential backoff (3 attempts)
|
||||||
|
- OpenCode: Shared server pooling, requires explicit `model`, client-side permission auto-reply
|
||||||
|
- Mock: Deterministic responses, scenario queue support
|
||||||
- Model names are passed directly to provider (no alias resolution in TAKT)
|
- Model names are passed directly to provider (no alias resolution in TAKT)
|
||||||
- Claude supports aliases: `opus`, `sonnet`, `haiku`
|
|
||||||
- Codex defaults to `codex` if model not specified
|
|
||||||
|
|
||||||
**Permission modes (provider-independent values):**
|
**Permission modes (provider-independent values):**
|
||||||
- `readonly`: Read-only access, no file modifications (Claude: `default`, Codex: `read-only`)
|
- `readonly`: Read-only access, no file modifications (Claude: `default`, Codex: `read-only`)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user