diff --git a/.claude/agents/conceptual-planning-agent.md b/.claude/agents/conceptual-planning-agent.md index a49debd9..c5fd1511 100644 --- a/.claude/agents/conceptual-planning-agent.md +++ b/.claude/agents/conceptual-planning-agent.md @@ -109,7 +109,7 @@ This agent processes **simplified inline [FLOW_CONTROL]** format from brainstorm 3. **load_session_metadata** - Action: Load session metadata - - Command: bash(cat .workflow/WFS-{session}/workflow-session.json) + - Command: ccw session read WFS-{session} --type session - Output: session_metadata ``` @@ -155,7 +155,7 @@ When called, you receive: - **User Context**: Specific requirements, constraints, and expectations from user discussion - **Output Location**: Directory path for generated analysis files - **Role Hint** (optional): Suggested role or role selection guidance -- **context-package.json** (CCW Workflow): Artifact paths catalog - extract using `jq -r '.brainstorm_artifacts.role_analyses[].files[].path'` +- **context-package.json** (CCW Workflow): Artifact paths catalog - use `ccw session read {session} --type context` to get context package - **ASSIGNED_ROLE** (optional): Specific role assignment - **ANALYSIS_DIMENSIONS** (optional): Role-specific analysis dimensions diff --git a/.claude/agents/test-fix-agent.md b/.claude/agents/test-fix-agent.md index 2d6e3683..1bb83486 100644 --- a/.claude/agents/test-fix-agent.md +++ b/.claude/agents/test-fix-agent.md @@ -83,17 +83,18 @@ When task JSON contains implementation_approach array: - L1 (Unit): `*.test.*`, `*.spec.*` in `__tests__/`, `tests/unit/` - L2 (Integration): `tests/integration/`, `*.integration.test.*` - L3 (E2E): `tests/e2e/`, `*.e2e.test.*`, `cypress/`, `playwright/` -- **context-package.json** (CCW Workflow): Extract artifact paths using `jq -r '.brainstorm_artifacts.role_analyses[].files[].path'` +- **context-package.json** (CCW Workflow): Use `ccw session read {session} --type context` to get context package with artifact paths - Identify test commands from project configuration ```bash # Detect test framework and multi-layered commands if [ -f "package.json" ]; then - # Extract layer-specific test commands - LINT_CMD=$(cat package.json | jq -r '.scripts.lint // "eslint ."') - UNIT_CMD=$(cat package.json | jq -r '.scripts["test:unit"] // .scripts.test') - INTEGRATION_CMD=$(cat package.json | jq -r '.scripts["test:integration"] // ""') - E2E_CMD=$(cat package.json | jq -r '.scripts["test:e2e"] // ""') + # Extract layer-specific test commands using Read tool or jq + PKG_JSON=$(cat package.json) + LINT_CMD=$(echo "$PKG_JSON" | jq -r '.scripts.lint // "eslint ."') + UNIT_CMD=$(echo "$PKG_JSON" | jq -r '.scripts["test:unit"] // .scripts.test') + INTEGRATION_CMD=$(echo "$PKG_JSON" | jq -r '.scripts["test:integration"] // ""') + E2E_CMD=$(echo "$PKG_JSON" | jq -r '.scripts["test:e2e"] // ""') elif [ -f "pytest.ini" ] || [ -f "setup.py" ]; then LINT_CMD="ruff check . || flake8 ." UNIT_CMD="pytest tests/unit/" diff --git a/.claude/commands/memory/docs.md b/.claude/commands/memory/docs.md index a01edb83..81e8d170 100644 --- a/.claude/commands/memory/docs.md +++ b/.claude/commands/memory/docs.md @@ -74,7 +74,7 @@ SlashCommand(command="/workflow:session:start --type docs --new \"{project_name} ```bash # Update workflow-session.json with docs-specific fields -bash(jq '. + {"target_path":"{target_path}","project_root":"{project_root}","project_name":"{project_name}","mode":"full","tool":"gemini","cli_execute":false}' .workflow/active/{sessionId}/workflow-session.json > tmp.json && mv tmp.json .workflow/active/{sessionId}/workflow-session.json) +ccw session update {sessionId} --type session --content '{"target_path":"{target_path}","project_root":"{project_root}","project_name":"{project_name}","mode":"full","tool":"gemini","cli_execute":false}' ``` ### Phase 2: Analyze Structure @@ -136,7 +136,8 @@ bash(if [ -d .workflow/docs/\${project_name} ]; then find .workflow/docs/\${proj ```bash # Count existing docs from doc-planning-data.json -bash(cat .workflow/active/WFS-docs-{timestamp}/.process/doc-planning-data.json | jq '.existing_docs.file_list | length') +ccw session read WFS-docs-{timestamp} --type process --filename doc-planning-data.json --raw | jq '.existing_docs.file_list | length' +# Or read entire process file and parse ``` **Data Processing**: Use count result, then use **Edit tool** to update `workflow-session.json`: @@ -190,10 +191,10 @@ Large Projects (single dir >10 docs): ```bash # 1. Get top-level directories from doc-planning-data.json -bash(cat .workflow/active/WFS-docs-{timestamp}/.process/doc-planning-data.json | jq -r '.top_level_dirs[]') +ccw session read WFS-docs-{timestamp} --type process --filename doc-planning-data.json --raw | jq -r '.top_level_dirs[]' # 2. Get mode from workflow-session.json -bash(cat .workflow/active/WFS-docs-{timestamp}/workflow-session.json | jq -r '.mode // "full"') +ccw session read WFS-docs-{timestamp} --type session --raw | jq -r '.mode // "full"' # 3. Check for HTTP API bash(grep -r "router\.|@Get\|@Post" src/ 2>/dev/null && echo "API_FOUND" || echo "NO_API") @@ -222,7 +223,7 @@ bash(grep -r "router\.|@Get\|@Post" src/ 2>/dev/null && echo "API_FOUND" || echo **Task ID Calculation**: ```bash -group_count=$(jq '.groups.count' .workflow/active/WFS-docs-{timestamp}/.process/doc-planning-data.json) +group_count=$(ccw session read WFS-docs-{timestamp} --type process --filename doc-planning-data.json --raw | jq '.groups.count') readme_id=$((group_count + 1)) # Next ID after groups arch_id=$((group_count + 2)) api_id=$((group_count + 3)) @@ -285,8 +286,8 @@ api_id=$((group_count + 3)) "step": "load_precomputed_data", "action": "Load Phase 2 analysis and extract group directories", "commands": [ - "bash(cat ${session_dir}/.process/doc-planning-data.json)", - "bash(jq '.groups.assignments[] | select(.group_id == \"${group_number}\") | .directories' ${session_dir}/.process/doc-planning-data.json)" + "ccw session read ${session_id} --type process --filename doc-planning-data.json", + "ccw session read ${session_id} --type process --filename doc-planning-data.json --raw | jq '.groups.assignments[] | select(.group_id == \"${group_number}\") | .directories'" ], "output_to": "phase2_context", "note": "Single JSON file contains all Phase 2 analysis results" diff --git a/.claude/commands/workflow/review.md b/.claude/commands/workflow/review.md index 869a2875..e40795a9 100644 --- a/.claude/commands/workflow/review.md +++ b/.claude/commands/workflow/review.md @@ -113,13 +113,14 @@ After bash validation, the model takes control to: 1. **Load Context**: Read completed task summaries and changed files ```bash # Load implementation summaries - cat .workflow/active/${sessionId}/.summaries/IMPL-*.md + ccw session read ${sessionId} --type summary --raw # Load test results (if available) - cat .workflow/active/${sessionId}/.summaries/TEST-FIX-*.md 2>/dev/null + ccw session read ${sessionId} --type summary --filename "TEST-FIX-*.md" --raw 2>/dev/null - # Get changed files - git log --since="$(cat .workflow/active/${sessionId}/workflow-session.json | jq -r .created_at)" --name-only --pretty=format: | sort -u + # Get session created_at for git log filter + created_at=$(ccw session read ${sessionId} --type session --raw | jq -r .created_at) + git log --since="$created_at" --name-only --pretty=format: | sort -u ``` 2. **Perform Specialized Review**: Based on `review_type` @@ -169,11 +170,11 @@ After bash validation, the model takes control to: - Verify all requirements and acceptance criteria met: ```bash # Load task requirements and acceptance criteria - find .workflow/active/${sessionId}/.task -name "IMPL-*.json" -exec jq -r ' + ccw session read ${sessionId} --type task --raw | jq -r ' "Task: " + .id + "\n" + "Requirements: " + (.context.requirements | join(", ")) + "\n" + "Acceptance: " + (.context.acceptance | join(", ")) - ' {} \; + ' # Check implementation summaries against requirements cd .workflow/active/${sessionId} && gemini -p " diff --git a/.claude/commands/workflow/tdd-verify.md b/.claude/commands/workflow/tdd-verify.md index 61f529ef..587ee3f9 100644 --- a/.claude/commands/workflow/tdd-verify.md +++ b/.claude/commands/workflow/tdd-verify.md @@ -77,18 +77,18 @@ find .workflow/active/ -name "WFS-*" -type d | head -1 | sed 's/.*\///' ```bash # Load all task JSONs -find .workflow/active/{sessionId}/.task/ -name '*.json' +ccw session read {sessionId} --type task # Extract task IDs -find .workflow/active/{sessionId}/.task/ -name '*.json' -exec jq -r '.id' {} \; +ccw session read {sessionId} --type task --raw | jq -r '.id' -# Check dependencies -find .workflow/active/{sessionId}/.task/ -name 'IMPL-*.json' -exec jq -r '.context.depends_on[]?' {} \; -find .workflow/active/{sessionId}/.task/ -name 'REFACTOR-*.json' -exec jq -r '.context.depends_on[]?' {} \; +# Check dependencies - read tasks and filter for IMPL/REFACTOR +ccw session read {sessionId} --type task --task-id "IMPL-*" --raw | jq -r '.context.depends_on[]?' +ccw session read {sessionId} --type task --task-id "REFACTOR-*" --raw | jq -r '.context.depends_on[]?' # Check meta fields -find .workflow/active/{sessionId}/.task/ -name '*.json' -exec jq -r '.meta.tdd_phase' {} \; -find .workflow/active/{sessionId}/.task/ -name '*.json' -exec jq -r '.meta.agent' {} \; +ccw session read {sessionId} --type task --raw | jq -r '.meta.tdd_phase' +ccw session read {sessionId} --type task --raw | jq -r '.meta.agent' ``` **Validation**: diff --git a/.claude/skills/command-guide/reference/agents/conceptual-planning-agent.md b/.claude/skills/command-guide/reference/agents/conceptual-planning-agent.md index a49debd9..c5fd1511 100644 --- a/.claude/skills/command-guide/reference/agents/conceptual-planning-agent.md +++ b/.claude/skills/command-guide/reference/agents/conceptual-planning-agent.md @@ -109,7 +109,7 @@ This agent processes **simplified inline [FLOW_CONTROL]** format from brainstorm 3. **load_session_metadata** - Action: Load session metadata - - Command: bash(cat .workflow/WFS-{session}/workflow-session.json) + - Command: ccw session read WFS-{session} --type session - Output: session_metadata ``` @@ -155,7 +155,7 @@ When called, you receive: - **User Context**: Specific requirements, constraints, and expectations from user discussion - **Output Location**: Directory path for generated analysis files - **Role Hint** (optional): Suggested role or role selection guidance -- **context-package.json** (CCW Workflow): Artifact paths catalog - extract using `jq -r '.brainstorm_artifacts.role_analyses[].files[].path'` +- **context-package.json** (CCW Workflow): Artifact paths catalog - use `ccw session read {session} --type context` to get context package - **ASSIGNED_ROLE** (optional): Specific role assignment - **ANALYSIS_DIMENSIONS** (optional): Role-specific analysis dimensions diff --git a/.claude/skills/command-guide/reference/agents/test-fix-agent.md b/.claude/skills/command-guide/reference/agents/test-fix-agent.md index 2d6e3683..1bb83486 100644 --- a/.claude/skills/command-guide/reference/agents/test-fix-agent.md +++ b/.claude/skills/command-guide/reference/agents/test-fix-agent.md @@ -83,17 +83,18 @@ When task JSON contains implementation_approach array: - L1 (Unit): `*.test.*`, `*.spec.*` in `__tests__/`, `tests/unit/` - L2 (Integration): `tests/integration/`, `*.integration.test.*` - L3 (E2E): `tests/e2e/`, `*.e2e.test.*`, `cypress/`, `playwright/` -- **context-package.json** (CCW Workflow): Extract artifact paths using `jq -r '.brainstorm_artifacts.role_analyses[].files[].path'` +- **context-package.json** (CCW Workflow): Use `ccw session read {session} --type context` to get context package with artifact paths - Identify test commands from project configuration ```bash # Detect test framework and multi-layered commands if [ -f "package.json" ]; then - # Extract layer-specific test commands - LINT_CMD=$(cat package.json | jq -r '.scripts.lint // "eslint ."') - UNIT_CMD=$(cat package.json | jq -r '.scripts["test:unit"] // .scripts.test') - INTEGRATION_CMD=$(cat package.json | jq -r '.scripts["test:integration"] // ""') - E2E_CMD=$(cat package.json | jq -r '.scripts["test:e2e"] // ""') + # Extract layer-specific test commands using Read tool or jq + PKG_JSON=$(cat package.json) + LINT_CMD=$(echo "$PKG_JSON" | jq -r '.scripts.lint // "eslint ."') + UNIT_CMD=$(echo "$PKG_JSON" | jq -r '.scripts["test:unit"] // .scripts.test') + INTEGRATION_CMD=$(echo "$PKG_JSON" | jq -r '.scripts["test:integration"] // ""') + E2E_CMD=$(echo "$PKG_JSON" | jq -r '.scripts["test:e2e"] // ""') elif [ -f "pytest.ini" ] || [ -f "setup.py" ]; then LINT_CMD="ruff check . || flake8 ." UNIT_CMD="pytest tests/unit/" diff --git a/.claude/skills/command-guide/reference/commands/memory/docs.md b/.claude/skills/command-guide/reference/commands/memory/docs.md index a01edb83..510065d3 100644 --- a/.claude/skills/command-guide/reference/commands/memory/docs.md +++ b/.claude/skills/command-guide/reference/commands/memory/docs.md @@ -74,7 +74,7 @@ SlashCommand(command="/workflow:session:start --type docs --new \"{project_name} ```bash # Update workflow-session.json with docs-specific fields -bash(jq '. + {"target_path":"{target_path}","project_root":"{project_root}","project_name":"{project_name}","mode":"full","tool":"gemini","cli_execute":false}' .workflow/active/{sessionId}/workflow-session.json > tmp.json && mv tmp.json .workflow/active/{sessionId}/workflow-session.json) +ccw session update {sessionId} --type session --content '{"target_path":"{target_path}","project_root":"{project_root}","project_name":"{project_name}","mode":"full","tool":"gemini","cli_execute":false}' ``` ### Phase 2: Analyze Structure @@ -136,7 +136,8 @@ bash(if [ -d .workflow/docs/\${project_name} ]; then find .workflow/docs/\${proj ```bash # Count existing docs from doc-planning-data.json -bash(cat .workflow/active/WFS-docs-{timestamp}/.process/doc-planning-data.json | jq '.existing_docs.file_list | length') +ccw session read WFS-docs-{timestamp} --type process --filename doc-planning-data.json --raw | jq '.existing_docs.file_list | length' +# Or read entire process file and parse ``` **Data Processing**: Use count result, then use **Edit tool** to update `workflow-session.json`: diff --git a/.claude/skills/command-guide/reference/commands/workflow/execute.md b/.claude/skills/command-guide/reference/commands/workflow/execute.md index 6844876a..669622a9 100644 --- a/.claude/skills/command-guide/reference/commands/workflow/execute.md +++ b/.claude/skills/command-guide/reference/commands/workflow/execute.md @@ -115,7 +115,7 @@ List sessions with metadata and prompt user selection: ```bash bash(for dir in .workflow/active/WFS-*/; do session=$(basename "$dir") - project=$(jq -r '.project // "Unknown"' "$dir/workflow-session.json" 2>/dev/null) + project=$(ccw session read "$session" --type session --raw 2>/dev/null | jq -r '.project // "Unknown"') total=$(grep -c "^- \[" "$dir/TODO_LIST.md" 2>/dev/null || echo "0") completed=$(grep -c "^- \[x\]" "$dir/TODO_LIST.md" 2>/dev/null || echo "0") [ "$total" -gt 0 ] && progress=$((completed * 100 / total)) || progress=0 @@ -152,7 +152,7 @@ Parse user input (supports: number "1", full ID "WFS-auth-system", or partial "a #### Step 1.3: Load Session Metadata ```bash -bash(cat .workflow/active/${sessionId}/workflow-session.json) +ccw session read ${sessionId} --type session ``` **Output**: Store session metadata in memory diff --git a/.claude/skills/command-guide/reference/commands/workflow/review.md b/.claude/skills/command-guide/reference/commands/workflow/review.md index 869a2875..e40795a9 100644 --- a/.claude/skills/command-guide/reference/commands/workflow/review.md +++ b/.claude/skills/command-guide/reference/commands/workflow/review.md @@ -113,13 +113,14 @@ After bash validation, the model takes control to: 1. **Load Context**: Read completed task summaries and changed files ```bash # Load implementation summaries - cat .workflow/active/${sessionId}/.summaries/IMPL-*.md + ccw session read ${sessionId} --type summary --raw # Load test results (if available) - cat .workflow/active/${sessionId}/.summaries/TEST-FIX-*.md 2>/dev/null + ccw session read ${sessionId} --type summary --filename "TEST-FIX-*.md" --raw 2>/dev/null - # Get changed files - git log --since="$(cat .workflow/active/${sessionId}/workflow-session.json | jq -r .created_at)" --name-only --pretty=format: | sort -u + # Get session created_at for git log filter + created_at=$(ccw session read ${sessionId} --type session --raw | jq -r .created_at) + git log --since="$created_at" --name-only --pretty=format: | sort -u ``` 2. **Perform Specialized Review**: Based on `review_type` @@ -169,11 +170,11 @@ After bash validation, the model takes control to: - Verify all requirements and acceptance criteria met: ```bash # Load task requirements and acceptance criteria - find .workflow/active/${sessionId}/.task -name "IMPL-*.json" -exec jq -r ' + ccw session read ${sessionId} --type task --raw | jq -r ' "Task: " + .id + "\n" + "Requirements: " + (.context.requirements | join(", ")) + "\n" + "Acceptance: " + (.context.acceptance | join(", ")) - ' {} \; + ' # Check implementation summaries against requirements cd .workflow/active/${sessionId} && gemini -p " diff --git a/.claude/skills/command-guide/reference/commands/workflow/tdd-verify.md b/.claude/skills/command-guide/reference/commands/workflow/tdd-verify.md index 61f529ef..587ee3f9 100644 --- a/.claude/skills/command-guide/reference/commands/workflow/tdd-verify.md +++ b/.claude/skills/command-guide/reference/commands/workflow/tdd-verify.md @@ -77,18 +77,18 @@ find .workflow/active/ -name "WFS-*" -type d | head -1 | sed 's/.*\///' ```bash # Load all task JSONs -find .workflow/active/{sessionId}/.task/ -name '*.json' +ccw session read {sessionId} --type task # Extract task IDs -find .workflow/active/{sessionId}/.task/ -name '*.json' -exec jq -r '.id' {} \; +ccw session read {sessionId} --type task --raw | jq -r '.id' -# Check dependencies -find .workflow/active/{sessionId}/.task/ -name 'IMPL-*.json' -exec jq -r '.context.depends_on[]?' {} \; -find .workflow/active/{sessionId}/.task/ -name 'REFACTOR-*.json' -exec jq -r '.context.depends_on[]?' {} \; +# Check dependencies - read tasks and filter for IMPL/REFACTOR +ccw session read {sessionId} --type task --task-id "IMPL-*" --raw | jq -r '.context.depends_on[]?' +ccw session read {sessionId} --type task --task-id "REFACTOR-*" --raw | jq -r '.context.depends_on[]?' # Check meta fields -find .workflow/active/{sessionId}/.task/ -name '*.json' -exec jq -r '.meta.tdd_phase' {} \; -find .workflow/active/{sessionId}/.task/ -name '*.json' -exec jq -r '.meta.agent' {} \; +ccw session read {sessionId} --type task --raw | jq -r '.meta.tdd_phase' +ccw session read {sessionId} --type task --raw | jq -r '.meta.agent' ``` **Validation**: diff --git a/ccw/src/commands/session.js b/ccw/src/commands/session.js index fca52a95..501652e5 100644 --- a/ccw/src/commands/session.js +++ b/ccw/src/commands/session.js @@ -7,6 +7,14 @@ import chalk from 'chalk'; import http from 'http'; import { executeTool } from '../tools/index.js'; +// Handle EPIPE errors gracefully (occurs when piping to head/jq that closes early) +process.stdout.on('error', (err) => { + if (err.code === 'EPIPE') { + process.exit(0); + } + throw err; +}); + /** * Notify dashboard of granular events (fire and forget) * @param {Object} data - Event data