From 2fb1d1243c5d665a575ed883c19015a3466d3d84 Mon Sep 17 00:00:00 2001 From: catlog22 Date: Thu, 22 Jan 2026 23:37:42 +0800 Subject: [PATCH] feat: prioritize user config, do not merge default tools Changed loadClaudeCliTools() to only load tools explicitly defined in user config. Previously, DEFAULT_TOOLS_CONFIG.tools was spread before user tools, causing all default tools to be loaded even if not present in user config. User config now has complete control over which tools are loaded. --- .codex/agents/ccw-loop-b-complete.md | 4 +-- .codex/agents/ccw-loop-executor.md | 8 ++--- .codex/skills/ccw-loop-b/README.md | 4 +-- .codex/skills/ccw-loop-b/SKILL.md | 8 ++--- .../skills/ccw-loop-b/phases/orchestrator.md | 4 +-- .../skills/ccw-loop-b/phases/state-schema.md | 6 ++-- .codex/skills/ccw-loop/README.md | 6 ++-- .codex/skills/ccw-loop/SKILL.md | 32 +++++++++---------- .../phases/actions/action-complete.md | 8 ++--- .../ccw-loop/phases/actions/action-debug.md | 6 ++-- .../ccw-loop/phases/actions/action-develop.md | 10 +++--- .../ccw-loop/phases/actions/action-init.md | 10 +++--- .../ccw-loop/phases/actions/action-menu.md | 4 +-- .../phases/actions/action-validate.md | 10 +++--- .codex/skills/ccw-loop/phases/orchestrator.md | 12 +++---- .codex/skills/ccw-loop/phases/state-schema.md | 22 ++++++------- ccw/src/tools/claude-cli-tools.ts | 4 +-- 17 files changed, 79 insertions(+), 79 deletions(-) diff --git a/.codex/agents/ccw-loop-b-complete.md b/.codex/agents/ccw-loop-b-complete.md index bc696770..766e96e3 100644 --- a/.codex/agents/ccw-loop-b-complete.md +++ b/.codex/agents/ccw-loop-b-complete.md @@ -41,8 +41,8 @@ PROJECT CONTEXT: ## Execution Steps 1. **Read all progress** - - Load worker outputs from `.loop/{loopId}.workers/` - - Read progress files from `.loop/{loopId}.progress/` + - Load worker outputs from `.workflow/.loop/{loopId}.workers/` + - Read progress files from `.workflow/.loop/{loopId}.progress/` - Consolidate findings 2. **Verify completeness** diff --git a/.codex/agents/ccw-loop-executor.md b/.codex/agents/ccw-loop-executor.md index 4b040a52..327498b0 100644 --- a/.codex/agents/ccw-loop-executor.md +++ b/.codex/agents/ccw-loop-executor.md @@ -39,7 +39,7 @@ You are a CCW Loop Executor - a stateless iterative development specialist that ```javascript // Read current state -const state = JSON.parse(Read('.loop/{loopId}.json')) +const state = JSON.parse(Read('.workflow/.loop/{loopId}.json')) // Check control signals if (state.status === 'paused') { @@ -110,7 +110,7 @@ NEXT_ACTION_NEEDED: {action_name} | WAITING_INPUT | COMPLETED | PAUSED ```javascript function updateState(loopId, skillStateUpdates) { - const state = JSON.parse(Read(`.loop/${loopId}.json`)) + const state = JSON.parse(Read(`.workflow/.loop/${loopId}.json`)) state.updated_at = getUtc8ISOString() state.skill_state = { ...state.skill_state, @@ -118,7 +118,7 @@ function updateState(loopId, skillStateUpdates) { last_action: currentAction, completed_actions: [...state.skill_state.completed_actions, currentAction] } - Write(`.loop/${loopId}.json`, JSON.stringify(state, null, 2)) + Write(`.workflow/.loop/${loopId}.json`, JSON.stringify(state, null, 2)) } ``` @@ -136,7 +136,7 @@ function updateState(loopId, skillStateUpdates) { 5. Update state with skill_state **Output**: -- `.loop/{loopId}.progress/develop.md` (initialized) +- `.workflow/.loop/{loopId}.progress/develop.md` (initialized) - State: skill_state populated with tasks ### DEVELOP Action diff --git a/.codex/skills/ccw-loop-b/README.md b/.codex/skills/ccw-loop-b/README.md index f09e3297..aeb708a4 100644 --- a/.codex/skills/ccw-loop-b/README.md +++ b/.codex/skills/ccw-loop-b/README.md @@ -91,7 +91,7 @@ Spawn multiple workers simultaneously, batch wait for results. ## Session Structure ``` -.loop/ +.workflow/.loop/ +-- {loopId}.json # Master state +-- {loopId}.workers/ # Worker outputs | +-- init.output.json @@ -184,7 +184,7 @@ Coordinator adapts to mode: ### 3. State Management -Unified state at `.loop/{loopId}.json`: +Unified state at `.workflow/.loop/{loopId}.json`: - **API compatible**: Works with CCW API - **Extension fields**: Skill-specific data in `skill_state` - **Worker outputs**: Structured JSON for each action diff --git a/.codex/skills/ccw-loop-b/SKILL.md b/.codex/skills/ccw-loop-b/SKILL.md index 0e19004e..2217b2f2 100644 --- a/.codex/skills/ccw-loop-b/SKILL.md +++ b/.codex/skills/ccw-loop-b/SKILL.md @@ -61,7 +61,7 @@ Coordinator -> spawn [develop, debug, validate] in parallel -> wait({ ids: all } ## Session Structure ``` -.loop/ +.workflow/.loop/ +-- {loopId}.json # Master state +-- {loopId}.workers/ # Worker outputs | +-- develop.output.json @@ -242,9 +242,9 @@ function buildWorkerPrompt(action, loopId, state) { - **Loop ID**: ${loopId} - **Action**: ${action} -- **State File**: .loop/${loopId}.json -- **Output File**: .loop/${loopId}.workers/${action}.output.json -- **Progress File**: .loop/${loopId}.progress/${action}.md +- **State File**: .workflow/.loop/${loopId}.json +- **Output File**: .workflow/.loop/${loopId}.workers/${action}.output.json +- **Progress File**: .workflow/.loop/${loopId}.progress/${action}.md ## CURRENT STATE diff --git a/.codex/skills/ccw-loop-b/phases/orchestrator.md b/.codex/skills/ccw-loop-b/phases/orchestrator.md index c65ce6ee..3cc29752 100644 --- a/.codex/skills/ccw-loop-b/phases/orchestrator.md +++ b/.codex/skills/ccw-loop-b/phases/orchestrator.md @@ -14,7 +14,7 @@ Read state -> Select mode -> Spawn workers -> Wait results -> Merge -> Update st ```javascript function readState(loopId) { - const stateFile = `.loop/${loopId}.json` + const stateFile = `.workflow/.loop/${loopId}.json` return fs.existsSync(stateFile) ? JSON.parse(Read(stateFile)) : null @@ -252,6 +252,6 @@ function parseWorkerResult(output) { ## Best Practices 1. **Worker 生命周期**: spawn → wait → close,不保留 worker -2. **结果持久化**: Worker 输出写入 `.loop/{loopId}.workers/` +2. **结果持久化**: Worker 输出写入 `.workflow/.loop/{loopId}.workers/` 3. **状态同步**: 每次 worker 完成后更新 state 4. **超时处理**: send_input 请求收敛,再超时则跳过 diff --git a/.codex/skills/ccw-loop-b/phases/state-schema.md b/.codex/skills/ccw-loop-b/phases/state-schema.md index d7581e96..17dbf966 100644 --- a/.codex/skills/ccw-loop-b/phases/state-schema.md +++ b/.codex/skills/ccw-loop-b/phases/state-schema.md @@ -56,7 +56,7 @@ ## Worker Output Structure -Each worker writes to `.loop/{loopId}.workers/{action}.output.json`: +Each worker writes to `.workflow/.loop/{loopId}.workers/{action}.output.json`: ```json { @@ -81,7 +81,7 @@ Each worker writes to `.loop/{loopId}.workers/{action}.output.json`: ## Progress File Structure -Human-readable progress in `.loop/{loopId}.progress/{action}.md`: +Human-readable progress in `.workflow/.loop/{loopId}.progress/{action}.md`: ```markdown # Develop Progress @@ -165,7 +165,7 @@ When `mode === 'parallel'`: ## Directory Structure ``` -.loop/ +.workflow/.loop/ +-- loop-b-20260122-abc123.json # Master state +-- loop-b-20260122-abc123.workers/ | +-- init.output.json diff --git a/.codex/skills/ccw-loop/README.md b/.codex/skills/ccw-loop/README.md index 4af1f973..b3b18863 100644 --- a/.codex/skills/ccw-loop/README.md +++ b/.codex/skills/ccw-loop/README.md @@ -68,7 +68,7 @@ Files are in `.codex/skills/ccw-loop/`: ``` 1. Parse arguments (task or --loop-id) -2. Create/read state from .loop/{loopId}.json +2. Create/read state from .workflow/.loop/{loopId}.json 3. spawn_agent with ccw-loop-executor role 4. Main loop: a. wait() for agent output @@ -84,7 +84,7 @@ Files are in `.codex/skills/ccw-loop/`: ## Session Files ``` -.loop/ +.workflow/.loop/ +-- {loopId}.json # Master state (API + Skill) +-- {loopId}.progress/ +-- develop.md # Development timeline @@ -157,7 +157,7 @@ spawn_agent({ Works with CCW Dashboard Loop Monitor: - Dashboard creates loop via API - API triggers this skill with `--loop-id` -- Skill reads/writes `.loop/{loopId}.json` +- Skill reads/writes `.workflow/.loop/{loopId}.json` - Dashboard polls state for real-time updates ### Control Signals diff --git a/.codex/skills/ccw-loop/SKILL.md b/.codex/skills/ccw-loop/SKILL.md index b69fb653..74d0306e 100644 --- a/.codex/skills/ccw-loop/SKILL.md +++ b/.codex/skills/ccw-loop/SKILL.md @@ -27,8 +27,8 @@ Stateless iterative development loop using Codex subagent pattern. Supports deve +-------------------------------------------------------------+ | loop-v2-routes.ts (Control Plane) | | | -| State: .loop/{loopId}.json (MASTER) | -| Tasks: .loop/{loopId}.tasks.jsonl | +| State: .workflow/.loop/{loopId}.json (MASTER) | +| Tasks: .workflow/.loop/{loopId}.tasks.jsonl | | | | /start -> Trigger ccw-loop skill with --loop-id | | /pause -> Set status='paused' (skill checks before action) | @@ -42,8 +42,8 @@ Stateless iterative development loop using Codex subagent pattern. Supports deve | | | Codex Pattern: spawn_agent -> wait -> send_input -> close | | | -| Reads/Writes: .loop/{loopId}.json (unified state) | -| Writes: .loop/{loopId}.progress/* (progress files) | +| Reads/Writes: .workflow/.loop/{loopId}.json (unified state) | +| Writes: .workflow/.loop/{loopId}.progress/* (progress files) | | | | BEFORE each action: | | -> Check status: paused/stopped -> exit gracefully | @@ -55,9 +55,9 @@ Stateless iterative development loop using Codex subagent pattern. Supports deve ## Key Design Principles (Codex Adaptation) -1. **Unified State**: API and Skill share `.loop/{loopId}.json` state file +1. **Unified State**: API and Skill share `.workflow/.loop/{loopId}.json` state file 2. **Control Signals**: Skill checks status field before each action (paused/stopped) -3. **File-Driven**: All progress documented in `.loop/{loopId}.progress/` +3. **File-Driven**: All progress documented in `.workflow/.loop/{loopId}.progress/` 4. **Resumable**: Continue any loop with `--loop-id` 5. **Dual Trigger**: Supports API trigger (`--loop-id`) and direct call (task description) 6. **Single Agent Deep Interaction**: Use send_input for multi-phase execution instead of multiple agents @@ -100,7 +100,7 @@ Develop -> Debug -> Validate -> (if issues) -> Develop -> ... ## Session Structure (Unified Location) ``` -.loop/ +.workflow/.loop/ +-- {loopId}.json # Master state file (API + Skill shared) +-- {loopId}.tasks.jsonl # Task list (API managed) +-- {loopId}.progress/ # Skill progress files @@ -129,8 +129,8 @@ const loopId = args['--loop-id'] || (() => { return `loop-v2-${timestamp}-${random}` })() -const loopFile = `.loop/${loopId}.json` -const progressDir = `.loop/${loopId}.progress` +const loopFile = `.workflow/.loop/${loopId}.json` +const progressDir = `.workflow/.loop/${loopId}.progress` // Create progress directory mkdir -p "${progressDir}" @@ -144,14 +144,14 @@ mkdir -p "${progressDir}" // Step 1: Read or create initial state let state = null if (existingLoopId) { - state = JSON.parse(Read(`.loop/${loopId}.json`)) + state = JSON.parse(Read(`.workflow/.loop/${loopId}.json`)) if (!state) { console.error(`Loop not found: ${loopId}`) return } } else { state = createInitialState(loopId, taskDescription) - Write(`.loop/${loopId}.json`, JSON.stringify(state, null, 2)) + Write(`.workflow/.loop/${loopId}.json`, JSON.stringify(state, null, 2)) } // Step 2: Create orchestrator agent (single agent handles all phases) @@ -169,7 +169,7 @@ const agent = spawn_agent({ ## LOOP CONTEXT - **Loop ID**: ${loopId} -- **State File**: .loop/${loopId}.json +- **State File**: .workflow/.loop/${loopId}.json - **Progress Dir**: ${progressDir} - **Mode**: ${mode} // 'interactive' or 'auto' @@ -186,7 +186,7 @@ ${taskDescription} You are executing CCW Loop orchestrator. Your job: 1. **Check Control Signals** - - Read .loop/${loopId}.json + - Read .workflow/.loop/${loopId}.json - If status === 'paused' -> Output "PAUSED" and stop - If status === 'failed' -> Output "STOPPED" and stop - If status === 'running' -> Continue @@ -200,7 +200,7 @@ You are executing CCW Loop orchestrator. Your job: 3. **Execute Action** - Follow action instructions from ~/.codex/skills/ccw-loop/phases/actions/ - Update progress files in ${progressDir}/ - - Update state in .loop/${loopId}.json + - Update state in .workflow/.loop/${loopId}.json 4. **Output Format** \`\`\` @@ -283,10 +283,10 @@ Continue with: ${actionResult.next_action} } // Update iteration count in state - const currentState = JSON.parse(Read(`.loop/${loopId}.json`)) + const currentState = JSON.parse(Read(`.workflow/.loop/${loopId}.json`)) currentState.current_iteration = iteration currentState.updated_at = getUtc8ISOString() - Write(`.loop/${loopId}.json`, JSON.stringify(currentState, null, 2)) + Write(`.workflow/.loop/${loopId}.json`, JSON.stringify(currentState, null, 2)) } // Step 4: Cleanup diff --git a/.codex/skills/ccw-loop/phases/actions/action-complete.md b/.codex/skills/ccw-loop/phases/actions/action-complete.md index df4f9a63..bd15d6e8 100644 --- a/.codex/skills/ccw-loop/phases/actions/action-complete.md +++ b/.codex/skills/ccw-loop/phases/actions/action-complete.md @@ -20,7 +20,7 @@ Complete CCW Loop session and generate summary report. ### Step 1: Verify Control Signals ```javascript -const state = JSON.parse(Read(`.loop/${loopId}.json`)) +const state = JSON.parse(Read(`.workflow/.loop/${loopId}.json`)) if (state.status !== 'running') { return { @@ -174,7 +174,7 @@ state.updated_at = timestamp state.skill_state.last_action = 'COMPLETE' state.skill_state.summary = stats -Write(`.loop/${loopId}.json`, JSON.stringify(state, null, 2)) +Write(`.workflow/.loop/${loopId}.json`, JSON.stringify(state, null, 2)) ``` ## Output Format @@ -190,8 +190,8 @@ ACTION_RESULT: } FILES_UPDATED: -- .loop/{loopId}.json: Status set to completed -- .loop/{loopId}.progress/summary.md: Summary report generated +- .workflow/.loop/{loopId}.json: Status set to completed +- .workflow/.loop/{loopId}.progress/summary.md: Summary report generated NEXT_ACTION_NEEDED: COMPLETED ``` diff --git a/.codex/skills/ccw-loop/phases/actions/action-debug.md b/.codex/skills/ccw-loop/phases/actions/action-debug.md index 6102e76a..3f5fbeb0 100644 --- a/.codex/skills/ccw-loop/phases/actions/action-debug.md +++ b/.codex/skills/ccw-loop/phases/actions/action-debug.md @@ -233,7 +233,7 @@ if (confirmedHypothesis) { state.skill_state.last_action = 'DEBUG' state.updated_at = timestamp -Write(`.loop/${loopId}.json`, JSON.stringify(state, null, 2)) +Write(`.workflow/.loop/${loopId}.json`, JSON.stringify(state, null, 2)) ``` ## Output Format @@ -249,8 +249,8 @@ ACTION_RESULT: } FILES_UPDATED: -- .loop/{loopId}.progress/debug.md: Understanding updated -- .loop/{loopId}.progress/hypotheses.json: Hypotheses updated +- .workflow/.loop/{loopId}.progress/debug.md: Understanding updated +- .workflow/.loop/{loopId}.progress/hypotheses.json: Hypotheses updated - [Source files]: Instrumentation added NEXT_ACTION_NEEDED: {DEBUG | VALIDATE | DEVELOP | MENU} diff --git a/.codex/skills/ccw-loop/phases/actions/action-develop.md b/.codex/skills/ccw-loop/phases/actions/action-develop.md index 8a7322ea..0b23a3ba 100644 --- a/.codex/skills/ccw-loop/phases/actions/action-develop.md +++ b/.codex/skills/ccw-loop/phases/actions/action-develop.md @@ -20,7 +20,7 @@ Execute development task and record progress to develop.md. ### Step 1: Verify Control Signals ```javascript -const state = JSON.parse(Read(`.loop/${loopId}.json`)) +const state = JSON.parse(Read(`.workflow/.loop/${loopId}.json`)) if (state.status !== 'running') { return { @@ -133,7 +133,7 @@ state.skill_state.last_action = 'DEVELOP' state.skill_state.completed_actions.push('DEVELOP') state.updated_at = timestamp -Write(`.loop/${loopId}.json`, JSON.stringify(state, null, 2)) +Write(`.workflow/.loop/${loopId}.json`, JSON.stringify(state, null, 2)) ``` ## Output Format @@ -149,9 +149,9 @@ ACTION_RESULT: } FILES_UPDATED: -- .loop/{loopId}.json: Task status updated -- .loop/{loopId}.progress/develop.md: Progress entry added -- .loop/{loopId}.progress/changes.log: Change entry added +- .workflow/.loop/{loopId}.json: Task status updated +- .workflow/.loop/{loopId}.progress/develop.md: Progress entry added +- .workflow/.loop/{loopId}.progress/changes.log: Change entry added NEXT_ACTION_NEEDED: {DEVELOP | DEBUG | VALIDATE | MENU} ``` diff --git a/.codex/skills/ccw-loop/phases/actions/action-init.md b/.codex/skills/ccw-loop/phases/actions/action-init.md index 49bb11dd..c9dec20d 100644 --- a/.codex/skills/ccw-loop/phases/actions/action-init.md +++ b/.codex/skills/ccw-loop/phases/actions/action-init.md @@ -19,7 +19,7 @@ Initialize CCW Loop session, create directory structure and initial state. ### Step 1: Verify Control Signals ```javascript -const state = JSON.parse(Read(`.loop/${loopId}.json`)) +const state = JSON.parse(Read(`.workflow/.loop/${loopId}.json`)) if (state.status !== 'running') { return { @@ -34,7 +34,7 @@ if (state.status !== 'running') { ### Step 2: Create Directory Structure ```javascript -const progressDir = `.loop/${loopId}.progress` +const progressDir = `.workflow/.loop/${loopId}.progress` // Directories created by orchestrator, verify they exist // mkdir -p ${progressDir} @@ -131,7 +131,7 @@ const skillState = { state.skill_state = skillState state.updated_at = getUtc8ISOString() -Write(`.loop/${loopId}.json`, JSON.stringify(state, null, 2)) +Write(`.workflow/.loop/${loopId}.json`, JSON.stringify(state, null, 2)) ``` ## Output Format @@ -143,8 +143,8 @@ ACTION_RESULT: - message: Session initialized with {N} development tasks FILES_UPDATED: -- .loop/{loopId}.json: skill_state initialized -- .loop/{loopId}.progress/develop.md: Progress document created +- .workflow/.loop/{loopId}.json: skill_state initialized +- .workflow/.loop/{loopId}.progress/develop.md: Progress document created NEXT_ACTION_NEEDED: {DEVELOP (auto) | MENU (interactive)} ``` diff --git a/.codex/skills/ccw-loop/phases/actions/action-menu.md b/.codex/skills/ccw-loop/phases/actions/action-menu.md index 825791f1..d67e0cbe 100644 --- a/.codex/skills/ccw-loop/phases/actions/action-menu.md +++ b/.codex/skills/ccw-loop/phases/actions/action-menu.md @@ -20,7 +20,7 @@ Display interactive action menu for user selection. ### Step 1: Verify Control Signals ```javascript -const state = JSON.parse(Read(`.loop/${loopId}.json`)) +const state = JSON.parse(Read(`.workflow/.loop/${loopId}.json`)) if (state.status !== 'running') { return { @@ -172,7 +172,7 @@ If user selects "exit": // Save current state state.status = 'user_exit' state.updated_at = getUtc8ISOString() -Write(`.loop/${loopId}.json`, JSON.stringify(state, null, 2)) +Write(`.workflow/.loop/${loopId}.json`, JSON.stringify(state, null, 2)) return { action: 'MENU', diff --git a/.codex/skills/ccw-loop/phases/actions/action-validate.md b/.codex/skills/ccw-loop/phases/actions/action-validate.md index fd34dd48..6ebf8109 100644 --- a/.codex/skills/ccw-loop/phases/actions/action-validate.md +++ b/.codex/skills/ccw-loop/phases/actions/action-validate.md @@ -21,7 +21,7 @@ Run tests and verify implementation, record results to validate.md. ### Step 1: Verify Control Signals ```javascript -const state = JSON.parse(Read(`.loop/${loopId}.json`)) +const state = JSON.parse(Read(`.workflow/.loop/${loopId}.json`)) if (state.status !== 'running') { return { @@ -174,7 +174,7 @@ state.skill_state.validate.last_run_at = timestamp state.skill_state.last_action = 'VALIDATE' state.updated_at = timestamp -Write(`.loop/${loopId}.json`, JSON.stringify(state, null, 2)) +Write(`.workflow/.loop/${loopId}.json`, JSON.stringify(state, null, 2)) ``` ## Output Format @@ -191,9 +191,9 @@ ACTION_RESULT: } FILES_UPDATED: -- .loop/{loopId}.progress/validate.md: Validation report created -- .loop/{loopId}.progress/test-results.json: Test results saved -- .loop/{loopId}.progress/coverage.json: Coverage data saved (if available) +- .workflow/.loop/{loopId}.progress/validate.md: Validation report created +- .workflow/.loop/{loopId}.progress/test-results.json: Test results saved +- .workflow/.loop/{loopId}.progress/coverage.json: Coverage data saved (if available) NEXT_ACTION_NEEDED: {COMPLETE | DEBUG | DEVELOP | MENU} ``` diff --git a/.codex/skills/ccw-loop/phases/orchestrator.md b/.codex/skills/ccw-loop/phases/orchestrator.md index e357a9d3..e5a8d2cf 100644 --- a/.codex/skills/ccw-loop/phases/orchestrator.md +++ b/.codex/skills/ccw-loop/phases/orchestrator.md @@ -45,7 +45,7 @@ const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOSt * @param loopId - Loop ID (e.g., "loop-v2-20260122-abc123") */ function readLoopState(loopId) { - const stateFile = `.loop/${loopId}.json` + const stateFile = `.workflow/.loop/${loopId}.json` if (!fs.existsSync(stateFile)) { return null @@ -63,7 +63,7 @@ function readLoopState(loopId) { * Create new loop state (only for direct calls, API triggers have existing state) */ function createLoopState(loopId, taskDescription) { - const stateFile = `.loop/${loopId}.json` + const stateFile = `.workflow/.loop/${loopId}.json` const now = getUtc8ISOString() const state = { @@ -83,7 +83,7 @@ function createLoopState(loopId, taskDescription) { // Ensure directories exist mkdir -p ".loop" - mkdir -p ".loop/${loopId}.progress" + mkdir -p ".workflow/.loop/${loopId}.progress" Write(stateFile, JSON.stringify(state, null, 2)) return state @@ -137,7 +137,7 @@ async function runOrchestrator(options = {}) { return { status: 'error', message: 'Missing loopId or task' } } - const progressDir = `.loop/${loopId}.progress` + const progressDir = `.workflow/.loop/${loopId}.progress` // 2. Create executor agent (single agent for entire loop) const agent = spawn_agent({ @@ -154,7 +154,7 @@ async function runOrchestrator(options = {}) { ## LOOP CONTEXT - **Loop ID**: ${loopId} -- **State File**: .loop/${loopId}.json +- **State File**: .workflow/.loop/${loopId}.json - **Progress Dir**: ${progressDir} - **Mode**: ${mode} @@ -213,7 +213,7 @@ Execution timeout reached. Please: state = readLoopState(loopId) state.current_iteration = iteration state.updated_at = getUtc8ISOString() - Write(`.loop/${loopId}.json`, JSON.stringify(state, null, 2)) + Write(`.workflow/.loop/${loopId}.json`, JSON.stringify(state, null, 2)) // Handle different outcomes switch (actionResult.next_action) { diff --git a/.codex/skills/ccw-loop/phases/state-schema.md b/.codex/skills/ccw-loop/phases/state-schema.md index e1576b5f..6fc12d9f 100644 --- a/.codex/skills/ccw-loop/phases/state-schema.md +++ b/.codex/skills/ccw-loop/phases/state-schema.md @@ -4,7 +4,7 @@ CCW Loop state structure definition for Codex subagent pattern. ## State File -**Location**: `.loop/{loopId}.json` (unified location, API + Skill shared) +**Location**: `.workflow/.loop/{loopId}.json` (unified location, API + Skill shared) ## Structure Definition @@ -208,7 +208,7 @@ Agent checks control signals at start of every action: * @returns { continue: boolean, action: 'pause_exit' | 'stop_exit' | 'continue' } */ function checkControlSignals(loopId) { - const state = JSON.parse(Read(`.loop/${loopId}.json`)) + const state = JSON.parse(Read(`.workflow/.loop/${loopId}.json`)) switch (state.status) { case 'paused': @@ -338,17 +338,17 @@ State-to-file mapping: | State Field | Sync File | Sync Timing | |-------------|-----------|-------------| -| Entire LoopState | `.loop/{loopId}.json` | Every state change (master) | -| `skill_state.develop` | `.loop/{loopId}.progress/develop.md` | After each dev operation | -| `skill_state.debug` | `.loop/{loopId}.progress/debug.md` | After each debug operation | -| `skill_state.validate` | `.loop/{loopId}.progress/validate.md` | After each validation | -| Code changes log | `.loop/{loopId}.progress/changes.log` | Each file modification (NDJSON) | -| Debug log | `.loop/{loopId}.progress/debug.log` | Each debug log (NDJSON) | +| Entire LoopState | `.workflow/.loop/{loopId}.json` | Every state change (master) | +| `skill_state.develop` | `.workflow/.loop/{loopId}.progress/develop.md` | After each dev operation | +| `skill_state.debug` | `.workflow/.loop/{loopId}.progress/debug.md` | After each debug operation | +| `skill_state.validate` | `.workflow/.loop/{loopId}.progress/validate.md` | After each validation | +| Code changes log | `.workflow/.loop/{loopId}.progress/changes.log` | Each file modification (NDJSON) | +| Debug log | `.workflow/.loop/{loopId}.progress/debug.log` | Each debug log (NDJSON) | ### File Structure ``` -.loop/ +.workflow/.loop/ +-- loop-v2-20260122-abc123.json # Master state file (API + Skill) +-- loop-v2-20260122-abc123.tasks.jsonl # Task list (API managed) +-- loop-v2-20260122-abc123.progress/ # Skill progress files @@ -366,7 +366,7 @@ If master state file corrupted, rebuild skill_state from progress files: ```javascript function rebuildSkillStateFromProgress(loopId) { - const progressDir = `.loop/${loopId}.progress` + const progressDir = `.workflow/.loop/${loopId}.progress` // Parse progress files to rebuild state const skill_state = { @@ -381,7 +381,7 @@ function rebuildSkillStateFromProgress(loopId) { ## Codex Pattern Notes -1. **Agent reads state**: Agent reads `.loop/{loopId}.json` at action start +1. **Agent reads state**: Agent reads `.workflow/.loop/{loopId}.json` at action start 2. **Agent writes state**: Agent updates state after action completion 3. **Orchestrator tracks iterations**: Main loop tracks `current_iteration` 4. **Single agent context**: All state updates in same agent conversation via send_input diff --git a/ccw/src/tools/claude-cli-tools.ts b/ccw/src/tools/claude-cli-tools.ts index 9b9b2022..9aed6810 100644 --- a/ccw/src/tools/claude-cli-tools.ts +++ b/ccw/src/tools/claude-cli-tools.ts @@ -439,9 +439,9 @@ export function loadClaudeCliTools(projectDir: string): ClaudeCliToolsConfig & { const migrated = migrateConfig(parsed, projectDir); const needsSave = migrated.version !== parsed.version; - // Merge tools with defaults and ensure required fields exist + // Load user-configured tools only (defaults NOT merged) const mergedTools: Record = {}; - for (const [key, tool] of Object.entries({ ...DEFAULT_TOOLS_CONFIG.tools, ...(migrated.tools || {}) })) { + for (const [key, tool] of Object.entries(migrated.tools || {})) { mergedTools[key] = { ...ensureToolTags(tool), type: tool.type ?? 'builtin',