Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions .github/workflows/claude-code-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ jobs:
permissions:
contents: read
pull-requests: write
issues: write
id-token: write
actions: read

steps:
- name: Checkout repository
Expand All @@ -39,9 +41,11 @@ jobs:
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
plugins: 'code-review@claude-code-plugins'
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
prompt: |
Review this PR for code quality, potential bugs, and improvements.
Focus on meaningful issues rather than style nits.
additional_permissions: |
actions: read
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options
env:
Expand Down
61 changes: 36 additions & 25 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,14 @@ uvx ruff format . # Format code (auto-fix)
uvx ruff check --no-fix . # Lint code (check only)
uvx pyright . # Type checking
uvx deadcode hooks/ scripts/ # Dead code detection
uvx pytest tests/ -v # Run test suite
```

The PostToolUse hook enforces a specific ruff rule subset on edited Python files:
```bash
uvx ruff check --select F,E711,E712,UP006,UP007,UP035,UP037,T201,S <file>
```

Test suite exists in `tests/` with comprehensive coverage for hooks and token efficiency features.
CI workflow exists (`.github/workflows/ci.yml`) but tests are currently disabled/placeholder.

---

Expand All @@ -80,13 +79,16 @@ In plugin mode, agent/skill names use prefix `workflow-orchestrator:` (e.g., `wo

### Execution Flow

**Token overhead:** Conditional injection (stub ~200 tokens on startup, full ~11K tokens on first delegation) + per-agent delegation (~350 tokens)

```
User prompt
→ UserPromptSubmit hook (clear state, record turn timestamp, clear team state)
→ SessionStart hooks (inject workflow_orchestrator.md + output style)
→ workflow_orchestrator detects multi-step → enters native plan mode (EnterPlanMode)
→ plan mode: main agent explores codebase, decomposes, assigns agents, creates tasks via TaskCreate
→ plan mode: evaluates execution_mode (subagent vs team via team_mode_score)
→ SessionStart hooks (inject stub orchestrator + output style + token efficiency)
[Stub version provides just enough system direction, avoiding unnecessary tokens]
→ Task detection: if multi-step connectors found, enters native plan mode (EnterPlanMode)
→ plan mode: injects full workflow_orchestrator, explores codebase, decomposes, assigns agents, creates tasks via TaskCreate
→ plan mode: evaluates execution_mode (subagent vs team via TeamCreate tool availability)
→ plan mode: exits via ExitPlanMode (requires lead approval)
→ PostToolUse hook (remind_skill_continuation.py): creates workflow_continuation_needed.json on ExitPlanMode
→ After ExitPlanMode approval, main agent continues to Stage 1
Expand All @@ -96,7 +98,7 @@ User prompt
→ Agents write to $CLAUDE_SCRATCHPAD_DIR, return DONE|{path}
→ SubagentStop hooks: remind task update, suggest verification
→ Main agent: TaskUpdate to mark completed, proceed to next wave
→ TEAM MODE (experimental, CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1):
→ TEAM MODE (when TeamCreate tool is available):
→ Create .claude/state/team_mode_active + team_config.json
→ TeamCreate(team_name=...), then Agent(team_name=...) for each teammate with agent configs
→ Create shared tasks with dependencies, bridge to framework Tasks API
Expand All @@ -106,22 +108,22 @@ User prompt
→ Stop hook: calculate turn duration, quality analysis
```

### Hook System (6 lifecycle events, 15 scripts)
### Hook System (6 lifecycle events, 14 hooks)

| Event | Scripts | Purpose |
|-------|---------|---------|
| **PreToolUse** (`*`, `Bash`) | `require_delegation.py`, `validate_task_graph_compliance.py`, `token_rewrite_hook.py` | Block non-allowed tools; validate Agent/Task invocations against active task graph; rewrite Bash commands for token efficiency |
| **PreToolUse** (`*`, `Bash`) | `validate_task_graph_compliance.py`, `require_delegation.py`, `token_rewrite_hook.py` (Bash only) | Validate Agent/Task invocations against active task graph; block non-allowed tools (compressed error messages); rewrite Bash commands for token efficiency (cd && pattern, eslint, next, tsc) |
| **PostToolUse** | `python_posttooluse_hook.py` (Edit/Write/MultiEdit), `remind_skill_continuation.py` (ExitPlanMode\|Skill\|SlashCommand), `validate_task_graph_depth.py` + `remind_todo_after_task.py` (Agent/Task) | Python validation (Ruff, Pyright, security), workflow continuation state (triggers on ExitPlanMode for plan mode flows), depth-3 enforcement, task reminders |
| **UserPromptSubmit** | `clear-delegation-sessions.py` | Clear delegation state, record turn start timestamp, clear team state (`team_mode_active`, `team_config.json`), rotate logs |
| **SessionStart** (`startup\|resume\|clear\|compact`) | `inject_workflow_orchestrator.py`, `inject-output-style.py`, `inject_token_efficiency.py` | Inject system prompt + output style + token efficiency guidance |
| **SessionStart** (`startup\|resume\|clear\|compact`) | `inject_workflow_orchestrator.py`, `inject-output-style.py`, `inject_token_efficiency.py` | Inject conditional orchestrator (stub on startup, full on /delegate), output style, token efficiency guidance |
| **SubagentStop** (`*`) | `remind_todo_update.py` (async), `trigger_verification.py` | Remind to update tasks, suggest verification |
| **Stop** | `python_stop_hook.py` | Turn duration, workflow continuation (block stop + inject "continue"), quality analysis |

Hook config source of truth: `hooks/plugin-hooks.json` (not settings.json). All hooks are Python for cross-platform compatibility (Windows/macOS/Linux).

### Tool Allowlist

Main agent can only use: `AskUserQuestion`, `TaskCreate`, `TaskUpdate`, `TaskList`, `TaskGet`, `Skill`, `SlashCommand`, `Agent`, `Task`, `SubagentTask`, `AgentTask`, `EnterPlanMode`, `ExitPlanMode`, `ToolSearch`
Main agent can only use: `AskUserQuestion`, `TaskCreate`, `TaskUpdate`, `TaskList`, `TaskGet`, `Skill`, `SlashCommand`, `Agent`, `Task`, `SubagentTask`, `AgentTask`, `EnterPlanMode`, `ExitPlanMode`, `ToolSearch`, `CronCreate`, `CronDelete`, `CronList`

Special cases:
- `Write` tool allowed for temp/scratchpad paths only (`/tmp/`, `/private/tmp/`, `/var/folders/`)
Expand All @@ -144,9 +146,10 @@ Special cases:

### Skills (forked context)

- **task-planner** (`skills/task-planner/SKILL.md`): Legacy planning skill, retained for reference/backward compatibility. The core planning logic (complexity scoring, tier classification, agent assignment, wave scheduling, task creation) has been absorbed into `system-prompts/workflow_orchestrator.md` and now executes as native plan mode (EnterPlanMode/ExitPlanMode) directly in the main agent context rather than a forked skill context.
- **breadth-reader** (`skills/breadth-reader/SKILL.md`): Lightweight read-only breadth tasks. Spawns `Explore` subagents (Haiku). Returns summary only.

**Note:** The `task-planner` skill has been removed. Its orchestration and planning functionality is now provided by native plan mode (EnterPlanMode/ExitPlanMode), which handles both planning and execution orchestration directly within the main agent context.

### Specialized Agents (8)

| Agent | Domain |
Expand Down Expand Up @@ -176,12 +179,13 @@ Two team workflow patterns:
- **Team mode (simple):** Single AGENT TEAM phase with `phase_type: "team"` and `teammates` array -- used for multi-perspective exploration (e.g., "explore from different angles")
- **Team mode (complex):** Multiple individual phases across waves, all executed as teammates via `Agent(team_name=...)` -- used for collaborative implementation (e.g., "implement project, tasks should be collaborative"). The plan has `execution_mode: "team"` at the top level; no individual phase needs `phase_type: "team"`

**Mode selection** uses `team_mode_score` (calculated during plan mode):
- Phase count >8: +2, Tier 3 complexity: +2, cross-phase data flow: +3
- Review-fix cycles: +3, iterative refinement: +2, user keyword "collaborate"/"team": +5
- Breadth task: -5, phase count <=3: -3
- With `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1`: default to team mode; only fall back to subagent when `team_mode_score <= -3` (breadth-only tasks)
- Without env var: always parallel subagent mode (≥2 subtasks mandatory)
**Mode selection** is based on TeamCreate tool availability (detected during plan mode):
- **If TeamCreate tool is available** (CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 is set): Calculate `team_mode_score` to determine whether to use team mode or subagent mode
- Phase count >8: +2, Tier 3 complexity: +2, cross-phase data flow: +3
- Review-fix cycles: +3, iterative refinement: +2, user keyword "collaborate"/"team": +5
- Breadth task: -5, phase count <=3: -3
- Default to team mode (score not calculated, absent, or > -3); use subagent mode only when score <= -3
- **If TeamCreate tool is not available** (env var not set): Always use subagent mode (≥2 subtasks mandatory)

**When team mode is active:**
- `validate_task_graph_compliance.py` hook is bypassed (team handles dependencies)
Expand All @@ -191,7 +195,10 @@ Two team workflow patterns:

Agent selection uses keyword matching (≥2 matches threshold, highest count wins). Falls back to general-purpose if 0-1 matches. See `system-prompts/workflow_orchestrator.md` for keyword lists.

Agent config format: YAML frontmatter (`name`, `description`, optional `tools`/`model`/`color`) + markdown system prompt body. All agents enforce `DONE|{output_file}` return format.
Agent config format: YAML frontmatter (`name`, `description`, optional `tools`/`model`/`color`) + markdown system prompt body. All agents enforce `DONE|{output_file}` return format. Custom agent instructions include:
- Return format must be exactly `DONE|{output_file_path}` (no summaries or explanations)
- Write directly to output file using Write tool (do not delegate writing)
- If Write is blocked, report error and stop (do not retry)

### State Files (Runtime)

Expand Down Expand Up @@ -241,7 +248,7 @@ Agent config format: YAML frontmatter (`name`, `description`, optional `tools`/`
| `CLAUDE_PLUGIN_ROOT` | Not set | Set by plugin system for path resolution |
| `CLAUDE_SCRATCHPAD_DIR` | Per-session | Session-isolated temp dir for agent output |
| `CLAUDE_PROJECT_DIR` | `$PWD` | State directory base path |
| `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` | `0` | Enable Agent Teams dual-mode (`1` to enable team mode scoring and tools) |
| `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` | `0` | Enable Agent Teams (TeamCreate tool availability and team mode scoring; `1` to enable) |
| `CLAUDE_CODE_ENABLE_TASKS` | `true` | Set `false` to revert to TodoWrite |
| `CLAUDE_CODE_TASK_LIST_ID` | Per-session | Share task list across sessions |
| `CLAUDE_TOKEN_EFFICIENCY` | `1` | Enable token-efficient CLI output compression (`0` to disable) |
Expand All @@ -252,11 +259,15 @@ Agent config format: YAML frontmatter (`name`, `description`, optional `tools`/`

Minimize command output to reduce context consumption. Enabled by default (`CLAUDE_TOKEN_EFFICIENCY=1`).

**Two-layer approach:**
**Multi-layer approach:**
1. **Behavioral guidance** (`system-prompts/token_efficient_cli.md`): Injected via SessionStart, teaches compact flag usage (e.g., `git status -sb`, `pytest -q --tb=short`)
2. **Output compression** (`hooks/compact_run.py`): PreToolUse hook rewrites matching Bash commands through `compact_run.py`, which compresses git/test/log output post-execution
3. **cd && pattern handling**: Hooks support chained commands with `cd && command` pattern for working directory preservation in compressed output
4. **Extended language support**: Rewrite hook supports eslint, next, tsc build tools in addition to git/test families
5. **Partial file reads**: Use Read tool with `offset` and `limit` parameters for files >200 lines to avoid loading entire file contents into context
6. **Compressed error messages**: Delegation error messages are optimized for minimal token consumption (use logging, never print statements)

**Supported command families:** git (push/pull/commit/etc), pytest, cargo test, npm/pnpm/yarn/bun test, npx (vitest/jest/mocha/playwright), go test, make test/check, docker/kubectl logs
**Supported command families:** git (push/pull/commit/etc), pytest, cargo test, npm/pnpm/yarn/bun test, npx (vitest/jest/mocha/playwright), go test, make test/check, docker/kubectl logs, eslint, next, tsc

Disable: `export CLAUDE_TOKEN_EFFICIENCY=0`

Expand Down Expand Up @@ -287,13 +298,13 @@ Ensure SessionStart hooks are installed (inject_workflow_orchestrator.py) so tha

**TeamCreate blocked:**
```bash
echo $CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS # Must be "1"
echo $CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS # Check if set to "1"
export CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1
```
The PreToolUse hook blocks all team tools (`TeamCreate`, `SendMessage`, pattern `*team*`/`*teammate*`) unless this env var is set. The hook prints a specific error message indicating the env var is missing.
The PreToolUse hook blocks all team tools (`TeamCreate`, `SendMessage`, pattern `*team*`/`*teammate*`) unless this env var is set. The hook auto-creates `.claude/state/team_mode_active` when the env var is "1" and a team tool is invoked.

**Team mode not activating despite keywords:**
When `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` is set, team mode is the default. It only falls back to subagent mode when `team_mode_score <= -3` (breadth-only tasks with no complexity factors). Without the env var, plan mode always selects `"subagent"` mode (with ≥2 subtasks mandatory).
Team mode is activated by tool availability detection during plan mode. Ensure `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` is set before running a workflow that should use team mode. The planning phase evaluates `team_mode_score` based on task complexity and characteristics. Without the env var, plan mode always selects `"subagent"` mode (with ≥2 subtasks mandatory).

**Team state files stale after crash:**
```bash
Expand Down
39 changes: 17 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,14 +252,14 @@ The `plugin-hooks.json` configures the delegation enforcement hooks using cross-

**Note:** All hooks use `uv run --no-project --script` for cross-platform compatibility (Windows, macOS, Linux). The `--no-project` flag allows execution without requiring a pyproject.toml, and `--script` directly runs Python scripts using uv's managed interpreter.

**Hook Events (6 lifecycle points, 15 scripts):**
**Hook Events (6 lifecycle points, 14 hooks):**

| Event | Scripts | Purpose |
|-------|---------|---------|
| **PreToolUse** | `validate_task_graph_compliance.py`, `require_delegation.py`, `token_rewrite_hook.py` (Bash only) | Validate task graph compliance; block non-delegated tools; rewrite Bash commands for token efficiency |
| **PreToolUse** | `validate_task_graph_compliance.py`, `require_delegation.py`, `token_rewrite_hook.py` (Bash only) | Validate task graph compliance; block non-delegated tools; rewrite Bash commands for token efficiency (cd && pattern, eslint, next, tsc support) |
| **PostToolUse** | `python_posttooluse_hook.py` (Edit/Write), `remind_skill_continuation.py` (ExitPlanMode/Skill/SlashCommand), `validate_task_graph_depth.py` (Agent/Task), `remind_todo_after_task.py` (Agent/Task, async) | Python validation (Ruff/Pyright); workflow continuation state; depth-3 enforcement; task reminders |
| **UserPromptSubmit** | `clear-delegation-sessions.py` | Clear delegation/team state, record turn timestamp |
| **SessionStart** | `inject_workflow_orchestrator.py`, `inject-output-style.py`, `inject_token_efficiency.py` | Inject system prompts (workflow orchestration, output style, token efficiency) |
| **SessionStart** | `inject_workflow_orchestrator.py`, `inject-output-style.py`, `inject_token_efficiency.py` | Inject conditional orchestrator (stub on startup, full on /delegate), output style, token efficiency guidance |
| **SubagentStop** | `remind_todo_update.py` (async), `trigger_verification.py` | Remind to update tasks, suggest verification |
| **Stop** | `python_stop_hook.py` | Turn duration tracking, workflow continuation |

Expand All @@ -268,22 +268,10 @@ The `plugin-hooks.json` configures the delegation enforcement hooks using cross-
Multi-step workflow orchestration requires the workflow_orchestrator system prompt to be appended:

**Automatic (via SessionStart hook):**
```json
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "append_system_prompt",
"path": "system-prompts/workflow_orchestrator.md"
}
]
}
]
}
}
```

The `inject_workflow_orchestrator.py` hook uses conditional injection:
- **On startup/resume:** Injects a lightweight stub that registers `/delegate` and `/bypass` commands without loading the full orchestrator prompt, keeping baseline token overhead minimal.
- **On `/delegate` invocation:** The full `workflow_orchestrator.md` system prompt is loaded on-demand, providing the complete planning and execution logic only when needed.

**What this enables:**
- Multi-step task detection via pattern matching
Expand Down Expand Up @@ -415,7 +403,7 @@ No other configuration is required. Plan mode automatically evaluates whether a

### How Mode Selection Works

During planning, plan mode calculates a `team_mode_score` based on task characteristics:
During planning, plan mode checks if the TeamCreate tool is available (indicator that Agent Teams are enabled). If available, it calculates a `team_mode_score` based on task characteristics:

| Factor | Points | Condition |
|---------------------------------------|--------|--------------------------------------------------------|
Expand All @@ -428,7 +416,7 @@ During planning, plan mode calculates a `team_mode_score` based on task characte
| Breadth task | -5 | Simple exploration is better as subagents |
| Phase count <= 3 | -3 | Small workflows don't need team overhead |

A score of **5 or higher** (with `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1`) triggers team mode. Otherwise, subagent mode is used.
Default to team mode when Agent Teams available (TeamCreate in tools). Falls back to subagent only when `team_mode_score <= -3` (breadth-only tasks). If TeamCreate tool is not available (env var not set), subagent mode is always selected.

### Subagent Mode vs Team Mode

Expand Down Expand Up @@ -503,7 +491,7 @@ Team mode creates two additional state files (automatically cleaned up on comple

The framework minimizes command output to reduce context consumption and preserve tokens for meaningful work. Token efficiency is enabled by default (`CLAUDE_TOKEN_EFFICIENCY=1`).

### Two-Layer Approach
### Multi-Layer Approach

1. **Behavioral Guidance** — The `token_efficient_cli.md` system prompt (injected via SessionStart) teaches compact flag usage:
- `git status -sb` (short branch format)
Expand All @@ -515,6 +503,13 @@ The framework minimizes command output to reduce context consumption and preserv
- Git: `push`, `pull`, `commit`, `merge`, `rebase`, `status`, etc.
- Test runners: `pytest`, `cargo test`, `npm/pnpm/yarn/bun test`, `vitest`, `jest`, `mocha`, etc.
- Logs: `docker logs`, `kubectl logs`, `make` output
- Build tools: `eslint`, `next`, `tsc`
- Command chaining: `cd && command` pattern support

3. **Conditional System Prompt Injection** — The orchestrator is injected conditionally:
- On session startup: Stub version (~200 tokens) provides minimal direction
- On first plan mode entry (via /delegate or detected multi-step): Full version (~11K tokens) for complete planning capability
- Saves tokens for single-step and read-only tasks

### Disable Token Efficiency

Expand Down
Loading
Loading