From 3998d24e32b1365e5e7650f36efa8f9775c77f05 Mon Sep 17 00:00:00 2001 From: catlog22 Date: Wed, 28 Jan 2026 20:34:03 +0800 Subject: [PATCH] Enhance skill generator documentation and templates - Updated Phase 1 and Phase 2 documentation to include next phase links and data flow details. - Expanded Phase 5 documentation to include comprehensive validation and README generation steps, along with validation report structure. - Added purpose and usage context sections to various action and script templates (e.g., autonomous-action, llm-action, script-bash). - Improved commands management by simplifying the command scanning logic and enabling/disabling commands through renaming files. - Enhanced dashboard command manager to format group names and display nested groups with appropriate icons and colors. - Updated LiteLLM executor to allow model overrides during execution. - Added action reference guide and template reference sections to the skill-tuning SKILL.md for better navigation and understanding. --- .claude/active_memory_config.json | 4 - .claude/commands/enhance-prompt.md | 93 --- .claude/commands/memory/code-map-memory.md | 687 ---------------- .claude/commands/memory/docs.md | 615 -------------- .claude/commands/memory/load-skill-memory.md | 182 ----- .claude/commands/memory/skill-memory.md | 525 ------------ .claude/commands/memory/swagger-docs.md | 773 ------------------ .../commands/memory/tech-research-rules.md | 310 ------- .claude/commands/memory/tips.md | 332 ++++++++ .../commands/memory/workflow-skill-memory.md | 517 ------------ .claude/commands/task/breakdown.md | 208 ----- .claude/commands/task/create.md | 152 ---- .claude/commands/task/execute.md | 270 ------ .claude/commands/task/replan.md | 441 ---------- .claude/commands/version.md | 254 ------ .../workflow/brainstorm/api-designer.md | 587 ------------- .../workflow/brainstorm/auto-parallel.md | 60 +- .../workflow/brainstorm/data-architect.md | 220 ----- .../workflow/brainstorm/product-manager.md | 200 ----- .../workflow/brainstorm/product-owner.md | 200 ----- .../workflow/brainstorm/role-analysis.md | 705 ++++++++++++++++ .../workflow/brainstorm/scrum-master.md | 200 ----- .../brainstorm/subject-matter-expert.md | 200 ----- .../workflow/brainstorm/system-architect.md | 389 --------- .../workflow/brainstorm/ui-designer.md | 221 ----- .../commands/workflow/brainstorm/ux-expert.md | 221 ----- .../phases/01-requirements-discovery.md | 8 + .../phases/02-structure-generation.md | 9 + .../skill-generator/phases/05-validation.md | 195 +++-- .../templates/autonomous-action.md | 14 + .../templates/autonomous-orchestrator.md | 14 + .../templates/code-analysis-action.md | 12 + .../skill-generator/templates/llm-action.md | 12 + .../skill-generator/templates/script-bash.md | 14 + .../templates/script-python.md | 14 + .../templates/sequential-phase.md | 14 + .../skill-generator/templates/skill-md.md | 14 + .claude/skills/skill-tuning/SKILL.md | 77 ++ assets/wechat-group-qr.png | Bin 188291 -> 233044 bytes ccw/src/config/litellm-api-config-manager.ts | 8 +- ccw/src/core/routes/commands-routes.ts | 196 ++--- ccw/src/templates/dashboard-js/i18n.js | 12 + .../dashboard-js/views/commands-manager.js | 75 +- ccw/src/tools/claude-cli-tools.ts | 4 +- ccw/src/tools/cli-executor-core.ts | 10 +- ccw/src/tools/litellm-executor.ts | 22 +- 46 files changed, 1559 insertions(+), 7731 deletions(-) delete mode 100644 .claude/active_memory_config.json delete mode 100644 .claude/commands/enhance-prompt.md delete mode 100644 .claude/commands/memory/code-map-memory.md delete mode 100644 .claude/commands/memory/docs.md delete mode 100644 .claude/commands/memory/load-skill-memory.md delete mode 100644 .claude/commands/memory/skill-memory.md delete mode 100644 .claude/commands/memory/swagger-docs.md delete mode 100644 .claude/commands/memory/tech-research-rules.md create mode 100644 .claude/commands/memory/tips.md delete mode 100644 .claude/commands/memory/workflow-skill-memory.md delete mode 100644 .claude/commands/task/breakdown.md delete mode 100644 .claude/commands/task/create.md delete mode 100644 .claude/commands/task/execute.md delete mode 100644 .claude/commands/task/replan.md delete mode 100644 .claude/commands/version.md delete mode 100644 .claude/commands/workflow/brainstorm/api-designer.md delete mode 100644 .claude/commands/workflow/brainstorm/data-architect.md delete mode 100644 .claude/commands/workflow/brainstorm/product-manager.md delete mode 100644 .claude/commands/workflow/brainstorm/product-owner.md create mode 100644 .claude/commands/workflow/brainstorm/role-analysis.md delete mode 100644 .claude/commands/workflow/brainstorm/scrum-master.md delete mode 100644 .claude/commands/workflow/brainstorm/subject-matter-expert.md delete mode 100644 .claude/commands/workflow/brainstorm/system-architect.md delete mode 100644 .claude/commands/workflow/brainstorm/ui-designer.md delete mode 100644 .claude/commands/workflow/brainstorm/ux-expert.md diff --git a/.claude/active_memory_config.json b/.claude/active_memory_config.json deleted file mode 100644 index f1b9cd57..00000000 --- a/.claude/active_memory_config.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "interval": "manual", - "tool": "gemini" -} \ No newline at end of file diff --git a/.claude/commands/enhance-prompt.md b/.claude/commands/enhance-prompt.md deleted file mode 100644 index 768563c7..00000000 --- a/.claude/commands/enhance-prompt.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -name: enhance-prompt -description: Enhanced prompt transformation using session memory and intent analysis with --enhance flag detection -argument-hint: "user input to enhance" ---- - -## Overview - -Systematically enhances user prompts by leveraging session memory context and intent analysis, translating ambiguous requests into actionable specifications. - -## Core Protocol - -**Enhancement Pipeline:** -`Intent Translation` → `Context Integration` → `Structured Output` - -**Context Sources:** -- Session memory (conversation history, previous analysis) -- Implicit technical requirements -- User intent patterns - -## Enhancement Rules - -### Intent Translation - -| User Says | Translate To | Focus | -|-----------|--------------|-------| -| "fix" | Debug and resolve | Root cause → preserve behavior | -| "improve" | Enhance/optimize | Performance/readability | -| "add" | Implement feature | Integration + edge cases | -| "refactor" | Restructure quality | Maintain behavior | -| "update" | Modernize | Version compatibility | - -### Context Integration Strategy - -**Session Memory:** -- Reference recent conversation context -- Reuse previously identified patterns -- Build on established understanding -- Infer technical requirements from discussion - -**Example:** -```bash -# User: "add login" -# Session Memory: Previous auth discussion, JWT mentioned -# Inferred: JWT-based auth, integrate with existing session management -# Action: Implement JWT authentication with session persistence -``` - -## Output Structure - -```bash -INTENT: [Clear technical goal] -CONTEXT: [Session memory + codebase patterns] -ACTION: [Specific implementation steps] -ATTENTION: [Critical constraints] -``` - -### Output Examples - -**Example 1:** -```bash -# Input: "fix login button" -INTENT: Debug non-functional login button -CONTEXT: From session - OAuth flow discussed, known state issue -ACTION: Check event binding → verify state updates → test auth flow -ATTENTION: Preserve existing OAuth integration -``` - -**Example 2:** -```bash -# Input: "refactor payment code" -INTENT: Restructure payment module for maintainability -CONTEXT: Session memory - PCI compliance requirements, Stripe integration patterns -ACTION: Extract reusable validators → isolate payment gateway logic → maintain adapter pattern -ATTENTION: Zero behavior change, maintain PCI compliance, full test coverage -``` - -## Enhancement Triggers - -- Ambiguous language: "fix", "improve", "clean up" -- Vague requests requiring clarification -- Complex technical requirements -- Architecture changes -- Critical systems: auth, payment, security -- Multi-step refactoring - -## Key Principles - -1. **Session Memory First**: Leverage conversation context and established understanding -2. **Context Reuse**: Build on previous discussions and decisions -3. **Clear Output**: Structured, actionable specifications -4. **Intent Clarification**: Transform vague requests into specific technical goals -5. **Avoid Duplication**: Reference existing context, don't repeat \ No newline at end of file diff --git a/.claude/commands/memory/code-map-memory.md b/.claude/commands/memory/code-map-memory.md deleted file mode 100644 index 0f88d4cb..00000000 --- a/.claude/commands/memory/code-map-memory.md +++ /dev/null @@ -1,687 +0,0 @@ ---- -name: code-map-memory -description: 3-phase orchestrator: parse feature keyword → cli-explore-agent analyzes (Deep Scan dual-source) → orchestrator generates Mermaid docs + SKILL package (skips phase 2 if exists) -argument-hint: "\"feature-keyword\" [--regenerate] [--tool ]" -allowed-tools: SlashCommand(*), TodoWrite(*), Bash(*), Read(*), Write(*), Task(*) ---- - -# Code Flow Mapping Generator - -## Overview - -**Pure Orchestrator with Agent Delegation**: Prepares context paths and delegates code flow analysis to specialized cli-explore-agent. Orchestrator transforms agent's JSON analysis into Mermaid documentation. - -**Auto-Continue Workflow**: Runs fully autonomously once triggered. Each phase completes and automatically triggers the next phase. - -**Execution Paths**: -- **Full Path**: All 3 phases (no existing codemap OR `--regenerate` specified) -- **Skip Path**: Phase 1 → Phase 3 (existing codemap found AND no `--regenerate` flag) -- **Phase 3 Always Executes**: SKILL index is always generated or updated - -**Agent Responsibility** (cli-explore-agent): -- Deep code flow analysis using dual-source strategy (Bash + Gemini CLI) -- Returns structured JSON with architecture, functions, data flow, conditionals, patterns -- NO file writing - analysis only - -**Orchestrator Responsibility**: -- Provides feature keyword and analysis scope to agent -- Transforms agent's JSON into Mermaid-enriched markdown documentation -- Writes all files (5 docs + metadata.json + SKILL.md) - -## Core Rules - -1. **Start Immediately**: First action is TodoWrite initialization, second action is Phase 1 execution -2. **Feature-Specific SKILL**: Each feature creates independent `.claude/skills/codemap-{feature}/` package -3. **Specialized Agent**: Phase 2a uses cli-explore-agent for professional code analysis (Deep Scan mode) -4. **Orchestrator Documentation**: Phase 2b transforms agent JSON into Mermaid markdown files -5. **Auto-Continue**: After completing each phase, update TodoWrite and immediately execute next phase -6. **No User Prompts**: Never ask user questions or wait for input between phases -7. **Track Progress**: Update TodoWrite after EVERY phase completion before starting next phase -8. **Multi-Level Detail**: Generate 4 levels: architecture → function → data → conditional - ---- - -## 3-Phase Execution - -### Phase 1: Parse Feature Keyword & Check Existing - -**Goal**: Normalize feature keyword, check existing codemap, prepare for analysis - -**Step 1: Parse Feature Keyword** -```bash -# Get feature keyword from argument -FEATURE_KEYWORD="$1" - -# Normalize: lowercase, spaces to hyphens -normalized_feature=$(echo "$FEATURE_KEYWORD" | tr '[:upper:]' '[:lower:]' | tr ' ' '-' | tr '_' '-') - -# Example: "User Authentication" → "user-authentication" -# Example: "支付处理" → "支付处理" (keep non-ASCII) -``` - -**Step 2: Set Tool Preference** -```bash -# Default to gemini unless --tool specified -TOOL="${tool_flag:-gemini}" -``` - -**Step 3: Check Existing Codemap** -```bash -# Define codemap directory -CODEMAP_DIR=".claude/skills/codemap-${normalized_feature}" - -# Check if codemap exists -bash(test -d "$CODEMAP_DIR" && echo "exists" || echo "not_exists") - -# Count existing files -bash(find "$CODEMAP_DIR" -name "*.md" 2>/dev/null | wc -l || echo 0) -``` - -**Step 4: Skip Decision** -```javascript -if (existing_files > 0 && !regenerate_flag) { - SKIP_GENERATION = true - message = "Codemap already exists, skipping Phase 2. Use --regenerate to force regeneration." -} else if (regenerate_flag) { - bash(rm -rf "$CODEMAP_DIR") - SKIP_GENERATION = false - message = "Regenerating codemap from scratch." -} else { - SKIP_GENERATION = false - message = "No existing codemap found, generating new code flow analysis." -} -``` - -**Output Variables**: -- `FEATURE_KEYWORD`: Original feature keyword -- `normalized_feature`: Normalized feature name for directory -- `CODEMAP_DIR`: `.claude/skills/codemap-{feature}` -- `TOOL`: CLI tool to use (gemini or qwen) -- `SKIP_GENERATION`: Boolean - whether to skip Phase 2 - -**TodoWrite**: -- If skipping: Mark phase 1 completed, phase 2 completed, phase 3 in_progress -- If not skipping: Mark phase 1 completed, phase 2 in_progress - ---- - -### Phase 2: Code Flow Analysis & Documentation Generation - -**Skip Condition**: Skipped if `SKIP_GENERATION = true` - -**Goal**: Use cli-explore-agent for professional code analysis, then orchestrator generates Mermaid documentation - -**Architecture**: Phase 2a (Agent Analysis) → Phase 2b (Orchestrator Documentation) - ---- - -#### Phase 2a: cli-explore-agent Analysis - -**Purpose**: Leverage specialized cli-explore-agent for deep code flow analysis - -**Agent Task Specification**: - -``` -Task( - subagent_type: "cli-explore-agent", - description: "Analyze code flow: {FEATURE_KEYWORD}", - prompt: " -Perform Deep Scan analysis for feature: {FEATURE_KEYWORD} - -**Analysis Mode**: deep-scan (Dual-source: Bash structural scan + Gemini semantic analysis) - -**Analysis Objectives**: -1. **Module Architecture**: Identify high-level module organization, interactions, and entry points -2. **Function Call Chains**: Trace execution paths, call sequences, and parameter flows -3. **Data Transformations**: Map data structure changes and transformation stages -4. **Conditional Paths**: Document decision trees, branches, and error handling strategies -5. **Design Patterns**: Discover architectural patterns and extract design intent - -**Scope**: -- Feature: {FEATURE_KEYWORD} -- CLI Tool: {TOOL} (gemini-2.5-pro or qwen coder-model) -- File Discovery: MCP Code Index (preferred) + rg fallback -- Target: 5-15 most relevant files - -**MANDATORY FIRST STEP**: -Read: ~/.claude/workflows/cli-templates/schemas/codemap-json-schema.json - -**Output**: Return JSON following schema exactly. NO FILE WRITING - return JSON analysis only. - -**Critical Requirements**: -- Use Deep Scan mode: Bash (Phase 1 - precise locations) + Gemini CLI (Phase 2 - semantic understanding) + Synthesis (Phase 3 - merge with attribution) -- Focus exclusively on {FEATURE_KEYWORD} feature flow -- Include file:line references for ALL findings -- Extract design intent from code structure and comments -- NO FILE WRITING - return JSON analysis only -- Handle tool failures gracefully (Gemini → Qwen fallback, MCP → rg fallback) - " -) -``` - -**Agent Output**: JSON analysis result with architecture, functions, data flow, conditionals, and patterns - ---- - -#### Phase 2b: Orchestrator Documentation Generation - -**Purpose**: Transform cli-explore-agent JSON into Mermaid-enriched documentation - -**Input**: Agent's JSON analysis result - -**Process**: - -1. **Parse Agent Analysis**: - ```javascript - const analysis = JSON.parse(agentResult) - const { feature, files_analyzed, architecture, function_calls, data_flow, conditional_logic, design_patterns } = analysis - ``` - -2. **Generate Mermaid Diagrams from Structured Data**: - - **a) architecture-flow.md** (~3K tokens): - ```javascript - // Convert architecture.modules + architecture.interactions → Mermaid graph TD - const architectureMermaid = ` - graph TD - ${architecture.modules.map(m => ` ${m.name}[${m.name}]`).join('\n')} - ${architecture.interactions.map(i => ` ${i.from} -->|${i.type}| ${i.to}`).join('\n')} - ` - - Write({ - file_path: `${CODEMAP_DIR}/architecture-flow.md`, - content: `--- -feature: ${feature} -level: architecture -detail: high-level module interactions ---- -# Architecture Flow: ${feature} - -## Overview -${architecture.overview} - -## Module Architecture -${architecture.modules.map(m => `### ${m.name}\n- **File**: ${m.file}\n- **Role**: ${m.responsibility}\n- **Dependencies**: ${m.dependencies.join(', ')}`).join('\n\n')} - -## Flow Diagram -\`\`\`mermaid -${architectureMermaid} -\`\`\` - -## Key Interactions -${architecture.interactions.map(i => `- **${i.from} → ${i.to}**: ${i.description}`).join('\n')} - -## Entry Points -${architecture.entry_points.map(e => `- **${e.function}** (${e.file}): ${e.description}`).join('\n')} -` - }) - ``` - - **b) function-calls.md** (~5K tokens): - ```javascript - // Convert function_calls.sequences → Mermaid sequenceDiagram - const sequenceMermaid = ` - sequenceDiagram - ${function_calls.sequences.map(s => ` ${s.from}->>${s.to}: ${s.method}`).join('\n')} - ` - - Write({ - file_path: `${CODEMAP_DIR}/function-calls.md`, - content: `--- -feature: ${feature} -level: function -detail: function-level call sequences ---- -# Function Call Chains: ${feature} - -## Call Sequence Diagram -\`\`\`mermaid -${sequenceMermaid} -\`\`\` - -## Detailed Call Chains -${function_calls.call_chains.map(chain => ` -### Chain ${chain.chain_id}: ${chain.description} -${chain.sequence.map(fn => `- **${fn.function}** (${fn.file})\n - Calls: ${fn.calls.join(', ')}`).join('\n')} -`).join('\n')} - -## Parameters & Returns -${function_calls.sequences.map(s => `- **${s.method}** → Returns: ${s.returns || 'void'}`).join('\n')} -` - }) - ``` - - **c) data-flow.md** (~4K tokens): - ```javascript - // Convert data_flow.transformations → Mermaid flowchart LR - const dataFlowMermaid = ` - flowchart LR - ${data_flow.transformations.map((t, i) => ` Stage${i}[${t.from}] -->|${t.transformer}| Stage${i+1}[${t.to}]`).join('\n')} - ` - - Write({ - file_path: `${CODEMAP_DIR}/data-flow.md`, - content: `--- -feature: ${feature} -level: data -detail: data structure transformations ---- -# Data Flow: ${feature} - -## Data Transformation Diagram -\`\`\`mermaid -${dataFlowMermaid} -\`\`\` - -## Data Structures -${data_flow.structures.map(s => `### ${s.name} (${s.stage})\n\`\`\`json\n${JSON.stringify(s.shape, null, 2)}\n\`\`\``).join('\n\n')} - -## Transformations -${data_flow.transformations.map(t => `- **${t.from} → ${t.to}** via \`${t.transformer}\` (${t.file})`).join('\n')} -` - }) - ``` - - **d) conditional-paths.md** (~4K tokens): - ```javascript - // Convert conditional_logic.branches → Mermaid flowchart TD - const conditionalMermaid = ` - flowchart TD - Start[Entry Point] - ${conditional_logic.branches.map((b, i) => ` - Start --> Check${i}{${b.condition}} - Check${i} -->|Yes| Path${i}A[${b.true_path}] - Check${i} -->|No| Path${i}B[${b.false_path}] - `).join('\n')} - ` - - Write({ - file_path: `${CODEMAP_DIR}/conditional-paths.md`, - content: `--- -feature: ${feature} -level: conditional -detail: decision trees and error paths ---- -# Conditional Paths: ${feature} - -## Decision Tree -\`\`\`mermaid -${conditionalMermaid} -\`\`\` - -## Branch Conditions -${conditional_logic.branches.map(b => `- **${b.condition}** (${b.file})\n - True: ${b.true_path}\n - False: ${b.false_path}`).join('\n')} - -## Error Handling -${conditional_logic.error_handling.map(e => `- **${e.error_type}**: Handler \`${e.handler}\` (${e.file}) - Recovery: ${e.recovery}`).join('\n')} -` - }) - ``` - - **e) complete-flow.md** (~8K tokens): - ```javascript - // Integrate all Mermaid diagrams - Write({ - file_path: `${CODEMAP_DIR}/complete-flow.md`, - content: `--- -feature: ${feature} -level: complete -detail: integrated multi-level view ---- -# Complete Flow: ${feature} - -## Integrated Flow Diagram -\`\`\`mermaid -graph TB - subgraph Architecture - ${architecture.modules.map(m => ` ${m.name}[${m.name}]`).join('\n')} - end - - subgraph "Function Calls" - ${function_calls.call_chains[0]?.sequence.map(fn => ` ${fn.function}`).join('\n') || ''} - end - - subgraph "Data Flow" - ${data_flow.structures.map(s => ` ${s.name}[${s.name}]`).join('\n')} - end -\`\`\` - -## Complete Trace -[Comprehensive end-to-end documentation combining all analysis layers] - -## Design Patterns Identified -${design_patterns.map(p => `- **${p.pattern}** in ${p.location}: ${p.description}`).join('\n')} - -## Recommendations -${analysis.recommendations.map(r => `- ${r}`).join('\n')} - -## Cross-References -- [Architecture Flow](./architecture-flow.md) - High-level module structure -- [Function Calls](./function-calls.md) - Detailed call chains -- [Data Flow](./data-flow.md) - Data transformation stages -- [Conditional Paths](./conditional-paths.md) - Decision trees and error handling -` - }) - ``` - -3. **Write metadata.json**: - ```javascript - Write({ - file_path: `${CODEMAP_DIR}/metadata.json`, - content: JSON.stringify({ - feature: feature, - normalized_name: normalized_feature, - generated_at: new Date().toISOString(), - tool_used: analysis.analysis_metadata.tool_used, - files_analyzed: files_analyzed.map(f => f.file), - analysis_summary: { - total_files: files_analyzed.length, - modules_traced: architecture.modules.length, - functions_traced: function_calls.call_chains.reduce((sum, c) => sum + c.sequence.length, 0), - patterns_discovered: design_patterns.length - } - }, null, 2) - }) - ``` - -4. **Report Phase 2 Completion**: - ``` - Phase 2 Complete: Code flow analysis and documentation generated - - - Agent Analysis: cli-explore-agent with {TOOL} - - Files Analyzed: {count} - - Documentation Generated: 5 markdown files + metadata.json - - Location: {CODEMAP_DIR} - ``` - -**Completion Criteria**: -- cli-explore-agent task completed successfully with JSON result -- 5 documentation files written with valid Mermaid diagrams -- metadata.json written with analysis summary -- All files properly formatted and cross-referenced - -**TodoWrite**: Mark phase 2 completed, phase 3 in_progress - ---- - -### Phase 3: Generate SKILL.md Index - -**Note**: This phase **ALWAYS executes** - generates or updates the SKILL index. - -**Goal**: Read generated flow documentation and create SKILL.md index with progressive loading - -**Steps**: - -1. **Verify Generated Files**: - ```bash - bash(find "{CODEMAP_DIR}" -name "*.md" -type f | sort) - ``` - -2. **Read metadata.json**: - ```javascript - Read({CODEMAP_DIR}/metadata.json) - // Extract: feature, normalized_name, files_analyzed, analysis_summary - ``` - -3. **Read File Headers** (optional, first 30 lines): - ```javascript - Read({CODEMAP_DIR}/architecture-flow.md, limit: 30) - Read({CODEMAP_DIR}/function-calls.md, limit: 30) - // Extract overview and diagram counts - ``` - -4. **Generate SKILL.md Index**: - - Template structure: - ```yaml - --- - name: codemap-{normalized_feature} - description: Code flow mapping for {FEATURE_KEYWORD} feature (located at {project_path}). Load this SKILL when analyzing, tracing, or understanding {FEATURE_KEYWORD} execution flow, especially when no relevant context exists in memory. - version: 1.0.0 - generated_at: {ISO_TIMESTAMP} - --- - # Code Flow Map: {FEATURE_KEYWORD} - - ## Feature: `{FEATURE_KEYWORD}` - - **Analysis Date**: {DATE} - **Tool Used**: {TOOL} - **Files Analyzed**: {COUNT} - - ## Progressive Loading - - ### Level 0: Quick Overview (~2K tokens) - - [Architecture Flow](./architecture-flow.md) - High-level module interactions - - ### Level 1: Core Flows (~10K tokens) - - [Architecture Flow](./architecture-flow.md) - Module architecture - - [Function Calls](./function-calls.md) - Function call chains - - ### Level 2: Complete Analysis (~20K tokens) - - [Architecture Flow](./architecture-flow.md) - - [Function Calls](./function-calls.md) - - [Data Flow](./data-flow.md) - Data transformations - - ### Level 3: Deep Dive (~30K tokens) - - [Architecture Flow](./architecture-flow.md) - - [Function Calls](./function-calls.md) - - [Data Flow](./data-flow.md) - - [Conditional Paths](./conditional-paths.md) - Branches and error handling - - [Complete Flow](./complete-flow.md) - Integrated comprehensive view - - ## Usage - - Load this SKILL package when: - - Analyzing {FEATURE_KEYWORD} implementation - - Tracing execution flow for debugging - - Understanding code dependencies - - Planning refactoring or enhancements - - ## Analysis Summary - - - **Modules Traced**: {modules_traced} - - **Functions Traced**: {functions_traced} - - **Files Analyzed**: {total_files} - - ## Mermaid Diagrams Included - - - Architecture flow diagram (graph TD) - - Function call sequence diagram (sequenceDiagram) - - Data transformation flowchart (flowchart LR) - - Conditional decision tree (flowchart TD) - - Complete integrated diagram (graph TB) - ``` - -5. **Write SKILL.md**: - ```javascript - Write({ - file_path: `{CODEMAP_DIR}/SKILL.md`, - content: generatedIndexMarkdown - }) - ``` - -**Completion Criteria**: -- SKILL.md index written -- All documentation files verified -- Progressive loading levels (0-3) properly structured -- Mermaid diagram references included - -**TodoWrite**: Mark phase 3 completed - -**Final Report**: -``` -Code Flow Mapping Complete - -Feature: {FEATURE_KEYWORD} -Location: .claude/skills/codemap-{normalized_feature}/ - -Files Generated: -- SKILL.md (index) -- architecture-flow.md (with Mermaid diagram) -- function-calls.md (with Mermaid sequence diagram) -- data-flow.md (with Mermaid flowchart) -- conditional-paths.md (with Mermaid decision tree) -- complete-flow.md (with integrated Mermaid diagram) -- metadata.json - -Analysis: -- Files analyzed: {count} -- Modules traced: {count} -- Functions traced: {count} - -Usage: Skill(command: "codemap-{normalized_feature}") -``` - ---- - -## Implementation Details - -### TodoWrite Patterns - -**Initialization** (Before Phase 1): -```javascript -TodoWrite({todos: [ - {"content": "Parse feature keyword and check existing", "status": "in_progress", "activeForm": "Parsing feature keyword"}, - {"content": "Agent analyzes code flow and generates files", "status": "pending", "activeForm": "Analyzing code flow"}, - {"content": "Generate SKILL.md index", "status": "pending", "activeForm": "Generating SKILL index"} -]}) -``` - -**Full Path** (SKIP_GENERATION = false): -```javascript -// After Phase 1 -TodoWrite({todos: [ - {"content": "Parse feature keyword and check existing", "status": "completed", ...}, - {"content": "Agent analyzes code flow and generates files", "status": "in_progress", ...}, - {"content": "Generate SKILL.md index", "status": "pending", ...} -]}) - -// After Phase 2 -TodoWrite({todos: [ - {"content": "Parse feature keyword and check existing", "status": "completed", ...}, - {"content": "Agent analyzes code flow and generates files", "status": "completed", ...}, - {"content": "Generate SKILL.md index", "status": "in_progress", ...} -]}) - -// After Phase 3 -TodoWrite({todos: [ - {"content": "Parse feature keyword and check existing", "status": "completed", ...}, - {"content": "Agent analyzes code flow and generates files", "status": "completed", ...}, - {"content": "Generate SKILL.md index", "status": "completed", ...} -]}) -``` - -**Skip Path** (SKIP_GENERATION = true): -```javascript -// After Phase 1 (skip Phase 2) -TodoWrite({todos: [ - {"content": "Parse feature keyword and check existing", "status": "completed", ...}, - {"content": "Agent analyzes code flow and generates files", "status": "completed", ...}, // Skipped - {"content": "Generate SKILL.md index", "status": "in_progress", ...} -]}) -``` - -### Execution Flow - -**Full Path**: -``` -User → TodoWrite Init → Phase 1 (parse) → Phase 2 (agent analyzes) → Phase 3 (write index) → Report -``` - -**Skip Path**: -``` -User → TodoWrite Init → Phase 1 (detect existing) → Phase 3 (update index) → Report -``` - -### Error Handling - -**Phase 1 Errors**: -- Empty feature keyword: Report error, ask user to provide feature description -- Invalid characters: Normalize and continue - -**Phase 2 Errors (Agent)**: -- Agent task fails: Retry once, report if fails again -- No files discovered: Warn user, ask for more specific feature keyword -- CLI failures: Agent handles internally with retries -- Invalid Mermaid syntax: Agent validates before writing - -**Phase 3 Errors**: -- Write failures: Report which files failed -- Missing files: Note in SKILL.md, suggest regeneration - ---- - -## Parameters - -```bash -/memory:code-map-memory "feature-keyword" [--regenerate] [--tool ] -``` - -**Arguments**: -- **"feature-keyword"**: Feature or flow to analyze (required) - - Examples: `"user authentication"`, `"payment processing"`, `"数据导入流程"` - - Can be English, Chinese, or mixed - - Spaces and underscores normalized to hyphens -- **--regenerate**: Force regenerate existing codemap (deletes and recreates) -- **--tool**: CLI tool for analysis (default: gemini) - - `gemini`: Comprehensive flow analysis with gemini-2.5-pro - - `qwen`: Alternative with coder-model - ---- - -## Examples - -**Generated File Structure** (for all examples): -``` -.claude/skills/codemap-{feature}/ -├── SKILL.md # Index (Phase 3) -├── architecture-flow.md # Agent (Phase 2) - High-level flow -├── function-calls.md # Agent (Phase 2) - Function chains -├── data-flow.md # Agent (Phase 2) - Data transformations -├── conditional-paths.md # Agent (Phase 2) - Branches & errors -├── complete-flow.md # Agent (Phase 2) - Integrated view -└── metadata.json # Agent (Phase 2) -``` - -### Example 1: User Authentication Flow - -```bash -/memory:code-map-memory "user authentication" -``` - -**Workflow**: -1. Phase 1: Normalizes to "user-authentication", checks existing codemap -2. Phase 2: Agent discovers auth-related files, executes CLI analysis, generates 5 flow docs with Mermaid -3. Phase 3: Generates SKILL.md index with progressive loading - -**Output**: `.claude/skills/codemap-user-authentication/` with 6 files + metadata - - -### Example 3: Regenerate with Qwen - -```bash -/memory:code-map-memory "payment processing" --regenerate --tool qwen -``` - -**Workflow**: -1. Phase 1: Deletes existing codemap due to --regenerate -2. Phase 2: Agent uses qwen with coder-model for fresh analysis -3. Phase 3: Generates updated SKILL.md - ---- - - -## Architecture - -``` -code-map-memory (orchestrator) - ├─ Phase 1: Parse & Check (bash commands, skip decision) - ├─ Phase 2: Code Analysis & Documentation (skippable) - │ ├─ Phase 2a: cli-explore-agent Analysis - │ │ └─ Deep Scan: Bash structural + Gemini semantic → JSON - │ └─ Phase 2b: Orchestrator Documentation - │ └─ Transform JSON → 5 Mermaid markdown files + metadata.json - └─ Phase 3: Write SKILL.md (index generation, always runs) - -Output: .claude/skills/codemap-{feature}/ -``` diff --git a/.claude/commands/memory/docs.md b/.claude/commands/memory/docs.md deleted file mode 100644 index b7ca1798..00000000 --- a/.claude/commands/memory/docs.md +++ /dev/null @@ -1,615 +0,0 @@ ---- -name: docs -description: Plan documentation workflow with dynamic grouping (≤10 docs/task), generates IMPL tasks for parallel module trees, README, ARCHITECTURE, and HTTP API docs -argument-hint: "[path] [--tool ] [--mode ] [--cli-execute]" ---- - -# Documentation Workflow (/memory:docs) - -## Overview -Lightweight planner that analyzes project structure, decomposes documentation work into tasks, and generates execution plans. Does NOT generate documentation content itself - delegates to doc-generator agent. - -**Execution Strategy**: -- **Dynamic Task Grouping**: Level 1 tasks grouped by top-level directories with document count limit - - **Primary constraint**: Each task generates ≤10 documents (API.md + README.md count) - - **Optimization goal**: Prefer grouping 2 top-level directories per task for context sharing - - **Conflict resolution**: If 2 dirs exceed 10 docs, reduce to 1 dir/task; if 1 dir exceeds 10 docs, split by subdirectories - - **Context benefit**: Same-task directories analyzed together via single Gemini call -- **Parallel Execution**: Multiple Level 1 tasks execute concurrently for faster completion -- **Pre-computed Analysis**: Phase 2 performs unified analysis once, stored in `.process/` for reuse -- **Efficient Data Loading**: All existing docs loaded once in Phase 2, shared across tasks - -**Path Mirroring**: Documentation structure mirrors source code under `.workflow/docs/{project_name}/` -- Example: `my_app/src/core/` → `.workflow/docs/my_app/src/core/API.md` - -**Two Execution Modes**: -- **Default (Agent Mode)**: CLI analyzes in `pre_analysis` (MODE=analysis), agent writes docs -- **--cli-execute (CLI Mode)**: CLI generates docs in `implementation_approach` (MODE=write), agent executes CLI commands - -## Path Mirroring Strategy - -**Principle**: Documentation structure **mirrors** source code structure under project-specific directory. - -| Source Path | Project Name | Documentation Path | -|------------|--------------|-------------------| -| `my_app/src/core/` | `my_app` | `.workflow/docs/my_app/src/core/API.md` | -| `my_app/src/modules/auth/` | `my_app` | `.workflow/docs/my_app/src/modules/auth/API.md` | -| `another_project/lib/utils/` | `another_project` | `.workflow/docs/another_project/lib/utils/API.md` | - - -## Parameters - -```bash -/memory:docs [path] [--tool ] [--mode ] [--cli-execute] -``` - -- **path**: Source directory to analyze (default: current directory) - - Specifies the source code directory to be documented - - Documentation is generated in a separate `.workflow/docs/{project_name}/` directory at the workspace root, **not** within the source `path` itself - - The source path's structure is mirrored within the project-specific documentation folder - - Example: analyzing `src/modules` produces documentation at `.workflow/docs/{project_name}/src/modules/` -- **--mode**: Documentation generation mode (default: full) - - `full`: Complete documentation (modules + README + ARCHITECTURE + EXAMPLES + HTTP API) - - `partial`: Module documentation only (API.md + README.md) -- **--tool**: CLI tool selection (default: gemini) - - `gemini`: Comprehensive documentation, pattern recognition - - `qwen`: Architecture analysis, system design focus - - `codex`: Implementation validation, code quality -- **--cli-execute**: Enable CLI-based documentation generation (optional) - -## Planning Workflow - -### Phase 1: Initialize Session - -```bash -# Get target path, project name, and root -bash(pwd && basename "$(pwd)" && git rev-parse --show-toplevel 2>/dev/null || pwd && date +%Y%m%d-%H%M%S) -``` - -```javascript -// Create docs session (type: docs) -SlashCommand(command="/workflow:session:start --type docs --new \"{project_name}-docs-{timestamp}\"") -// Parse output to get sessionId -``` - -```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) -``` - -### Phase 2: Analyze Structure - -**Smart filter**: Auto-detect and skip tests/build/config/vendor based on project tech stack. - -**Commands** (collect data with simple bash): - -```bash -# 1. Run folder analysis -bash(ccw tool exec get_modules_by_depth '{}' | ccw tool exec classify_folders '{}') - -# 2. Get top-level directories (first 2 path levels) -bash(ccw tool exec get_modules_by_depth '{}' | ccw tool exec classify_folders '{}' | awk -F'|' '{print $1}' | sed 's|^\./||' | awk -F'/' '{if(NF>=2) print $1"/"$2; else if(NF==1) print $1}' | sort -u) - -# 3. Find existing docs (if directory exists) -bash(if [ -d .workflow/docs/\${project_name} ]; then find .workflow/docs/\${project_name} -type f -name "*.md" ! -path "*/README.md" ! -path "*/ARCHITECTURE.md" ! -path "*/EXAMPLES.md" ! -path "*/api/*" 2>/dev/null; fi) - -# 4. Read existing docs content (if files exist) -bash(if [ -d .workflow/docs/\${project_name} ]; then find .workflow/docs/\${project_name} -type f -name "*.md" ! -path "*/README.md" ! -path "*/ARCHITECTURE.md" ! -path "*/EXAMPLES.md" ! -path "*/api/*" 2>/dev/null | xargs cat 2>/dev/null; fi) -``` - -**Data Processing**: Parse bash outputs, calculate statistics, use **Write tool** to create `${session_dir}/.process/doc-planning-data.json` with structure: - -```json -{ - "metadata": { - "generated_at": "2025-11-03T16:57:30.469669", - "project_name": "project_name", - "project_root": "/path/to/project" - }, - "folder_analysis": [ - {"path": "./src/core", "type": "code", "code_count": 5, "dirs_count": 2} - ], - "top_level_dirs": ["src/modules", "lib/core"], - "existing_docs": { - "file_list": [".workflow/docs/project/src/core/API.md"], - "content": "... existing docs content ..." - }, - "unified_analysis": [], - "statistics": { - "total": 15, - "code": 8, - "navigation": 7, - "top_level": 3 - } -} -``` - -**Then** use **Edit tool** to update `workflow-session.json` adding analysis field. - -**Output**: Single `doc-planning-data.json` with all analysis data (no temp files or Python scripts). - -**Auto-skipped**: Tests (`**/test/**`, `**/*.test.*`), Build (`**/node_modules/**`, `**/dist/**`), Config (root-level files), Vendor directories. - -### Phase 3: Detect Update Mode - -**Commands**: - -```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') -``` - -**Data Processing**: Use count result, then use **Edit tool** to update `workflow-session.json`: -- Add `"update_mode": "update"` if count > 0, else `"create"` -- Add `"existing_docs": ` - -### Phase 4: Decompose Tasks - -**Task Hierarchy** (Dynamic based on document count): - -``` -Small Projects (total ≤10 docs): - Level 1: IMPL-001 (all directories in single task, shared context) - Level 2: IMPL-002 (README, full mode only) - Level 3: IMPL-003 (ARCHITECTURE+EXAMPLES), IMPL-004 (HTTP API, optional) - -Medium Projects (Example: 7 top-level dirs, 18 total docs): - Step 1: Count docs per top-level dir - ├─ dir1: 3 docs, dir2: 4 docs → Group 1 (7 docs) - ├─ dir3: 5 docs, dir4: 3 docs → Group 2 (8 docs) - ├─ dir5: 2 docs → Group 3 (2 docs, can add more) - - Step 2: Create tasks with ≤10 docs constraint - Level 1: IMPL-001 to IMPL-003 (parallel groups) - ├─ IMPL-001: Group 1 (dir1 + dir2, 7 docs, shared context) - ├─ IMPL-002: Group 2 (dir3 + dir4, 8 docs, shared context) - └─ IMPL-003: Group 3 (remaining dirs, ≤10 docs) - Level 2: IMPL-004 (README, depends on Level 1, full mode only) - Level 3: IMPL-005 (ARCHITECTURE+EXAMPLES), IMPL-006 (HTTP API, optional) - -Large Projects (single dir >10 docs): - Step 1: Detect oversized directory - └─ src/modules/: 15 subdirs → 30 docs (exceeds limit) - - Step 2: Split by subdirectories - Level 1: IMPL-001 to IMPL-003 (split oversized dir) - ├─ IMPL-001: src/modules/ subdirs 1-5 (10 docs) - ├─ IMPL-002: src/modules/ subdirs 6-10 (10 docs) - └─ IMPL-003: src/modules/ subdirs 11-15 (10 docs) -``` - -**Grouping Algorithm**: -1. Count total docs for each top-level directory -2. Try grouping 2 directories (optimization for context sharing) -3. If group exceeds 10 docs, split to 1 dir/task -4. If single dir exceeds 10 docs, split by subdirectories -5. Create parallel Level 1 tasks with ≤10 docs each - - -**Commands**: - -```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[]') - -# 2. Get mode from workflow-session.json -bash(cat .workflow/active/WFS-docs-{timestamp}/workflow-session.json | 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") -``` - -**Data Processing**: -1. Count documents for each top-level directory (from folder_analysis): - - Code folders: 2 docs each (API.md + README.md) - - Navigation folders: 1 doc each (README.md only) -2. Apply grouping algorithm with ≤10 docs constraint: - - Try grouping 2 directories, calculate total docs - - If total ≤10 docs: create group - - If total >10 docs: split to 1 dir/group or subdivide - - If single dir >10 docs: split by subdirectories -3. Use **Edit tool** to update `doc-planning-data.json` adding groups field: - ```json - "groups": { - "count": 3, - "assignments": [ - {"group_id": "001", "directories": ["src/modules", "src/utils"], "doc_count": 5}, - {"group_id": "002", "directories": ["lib/core"], "doc_count": 6}, - {"group_id": "003", "directories": ["lib/helpers"], "doc_count": 3} - ] - } - ``` - -**Task ID Calculation**: -```bash -group_count=$(jq '.groups.count' .workflow/active/WFS-docs-{timestamp}/.process/doc-planning-data.json) -readme_id=$((group_count + 1)) # Next ID after groups -arch_id=$((group_count + 2)) -api_id=$((group_count + 3)) -``` - -### Phase 5: Generate Task JSONs - -**CLI Strategy**: - -| Mode | cli_execute | Placement | CLI MODE | Approval Flag | Agent Role | -|------|-------------|-----------|----------|---------------|------------| -| **Agent** | false | pre_analysis | analysis | (none) | Generate docs in implementation_approach | -| **CLI** | true | implementation_approach | write | --mode write | Execute CLI commands, validate output | - -**Command Patterns**: -- Gemini/Qwen: `ccw cli -p "..." --tool gemini --mode analysis --cd dir` -- CLI Mode: `ccw cli -p "..." --tool gemini --mode write --cd dir` -- Codex: `ccw cli -p "..." --tool codex --mode write --cd dir` - -**Generation Process**: -1. Read configuration values (tool, cli_execute, mode) from workflow-session.json -2. Read group assignments from doc-planning-data.json -3. Generate Level 1 tasks (IMPL-001 to IMPL-N, one per group) -4. Generate Level 2+ tasks if mode=full (README, ARCHITECTURE, HTTP API) - -## Task Templates - -### Level 1: Module Trees Group Task (Unified) - -**Execution Model**: Each task processes assigned directory group (max 2 directories) using pre-analyzed data from Phase 2. - -```json -{ - "id": "IMPL-${group_number}", - "title": "Document Module Trees Group ${group_number}", - "status": "pending", - "meta": { - "type": "docs-tree-group", - "agent": "@doc-generator", - "tool": "gemini", - "cli_execute": false, - "group_number": "${group_number}", - "total_groups": "${total_groups}" - }, - "context": { - "requirements": [ - "Process directories from group ${group_number} in doc-planning-data.json", - "Generate docs to .workflow/docs/${project_name}/ (mirrored structure)", - "Code folders: API.md + README.md; Navigation folders: README.md only", - "Use pre-analyzed data from Phase 2 (no redundant analysis)" - ], - "focus_paths": ["${group_dirs_from_json}"], - "precomputed_data": { - "phase2_analysis": "${session_dir}/.process/doc-planning-data.json" - } - }, - "flow_control": { - "pre_analysis": [ - { - "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)" - ], - "output_to": "phase2_context", - "note": "Single JSON file contains all Phase 2 analysis results" - } - ], - "implementation_approach": [ - { - "step": 1, - "title": "Generate documentation for assigned directory group", - "description": "Process directories in Group ${group_number} using pre-analyzed data", - "modification_points": [ - "Read group directories from [phase2_context].groups.assignments[${group_number}].directories", - "For each directory: parse folder types from folder_analysis, parse structure from unified_analysis", - "Map source_path to .workflow/docs/${project_name}/{path}", - "Generate API.md for code folders, README.md for all folders", - "Preserve user modifications from [phase2_context].existing_docs.content" - ], - "logic_flow": [ - "phase2 = parse([phase2_context])", - "dirs = phase2.groups.assignments[${group_number}].directories", - "for dir in dirs:", - " folder_info = find(dir, phase2.folder_analysis)", - " outline = find(dir, phase2.unified_analysis)", - " if folder_info.type == 'code': generate API.md + README.md", - " elif folder_info.type == 'navigation': generate README.md only", - " write to .workflow/docs/${project_name}/{dir}/" - ], - "depends_on": [], - "output": "group_module_docs" - } - ], - "target_files": [ - ".workflow/docs/${project_name}/*/API.md", - ".workflow/docs/${project_name}/*/README.md" - ] - } -} -``` - -**CLI Execute Mode Note**: When `cli_execute=true`, add Step 2 in `implementation_approach`: -```json -{ - "step": 2, - "title": "Batch generate documentation via CLI", - "command": "ccw cli -p 'PURPOSE: Generate module docs\\nTASK: Create documentation\\nMODE: write\\nCONTEXT: @**/* [phase2_context]\\nEXPECTED: API.md and README.md\\nRULES: Mirror structure' --tool gemini --mode write --cd ${dirs_from_group}", - "depends_on": [1], - "output": "generated_docs" -} -``` - -### Level 2: Project README Task - -**Task ID**: `IMPL-${readme_id}` (where `readme_id = group_count + 1`) -**Dependencies**: Depends on all Level 1 tasks completing. - -```json -{ - "id": "IMPL-${readme_id}", - "title": "Generate Project README", - "status": "pending", - "depends_on": ["IMPL-001", "...", "IMPL-${group_count}"], - "meta": {"type": "docs", "agent": "@doc-generator", "tool": "gemini", "cli_execute": false}, - "flow_control": { - "pre_analysis": [ - { - "step": "load_existing_readme", - "command": "bash(cat .workflow/docs/${project_name}/README.md 2>/dev/null || echo 'No existing README')", - "output_to": "existing_readme" - }, - { - "step": "load_module_docs", - "command": "bash(find .workflow/docs/${project_name} -type f -name '*.md' ! -path '.workflow/docs/${project_name}/README.md' ! -path '.workflow/docs/${project_name}/ARCHITECTURE.md' ! -path '.workflow/docs/${project_name}/EXAMPLES.md' ! -path '.workflow/docs/${project_name}/api/*' | xargs cat)", - "output_to": "all_module_docs" - }, - { - "step": "analyze_project", - "command": "bash(ccw cli -p \"PURPOSE: Analyze project structure\\nTASK: Extract overview from modules\\nMODE: analysis\\nCONTEXT: [all_module_docs]\\nEXPECTED: Project outline\" --tool gemini --mode analysis)", - "output_to": "project_outline" - } - ], - "implementation_approach": [ - { - "step": 1, - "title": "Generate project README", - "description": "Generate project README with navigation links while preserving user modifications", - "modification_points": [ - "Parse [project_outline] and [all_module_docs]", - "Generate README structure with navigation links", - "Preserve [existing_readme] user modifications" - ], - "logic_flow": ["Parse data", "Generate README with navigation", "Preserve modifications"], - "depends_on": [], - "output": "project_readme" - } - ], - "target_files": [".workflow/docs/${project_name}/README.md"] - } -} -``` - -### Level 3: Architecture & Examples Documentation Task - -**Task ID**: `IMPL-${arch_id}` (where `arch_id = group_count + 2`) -**Dependencies**: Depends on Level 2 (Project README). - -```json -{ - "id": "IMPL-${arch_id}", - "title": "Generate Architecture & Examples Documentation", - "status": "pending", - "depends_on": ["IMPL-${readme_id}"], - "meta": {"type": "docs", "agent": "@doc-generator", "tool": "gemini", "cli_execute": false}, - "flow_control": { - "pre_analysis": [ - {"step": "load_existing_docs", "command": "bash(cat .workflow/docs/${project_name}/{ARCHITECTURE,EXAMPLES}.md 2>/dev/null || echo 'No existing docs')", "output_to": "existing_arch_examples"}, - {"step": "load_all_docs", "command": "bash(cat .workflow/docs/${project_name}/README.md && find .workflow/docs/${project_name} -type f -name '*.md' ! -path '*/README.md' ! -path '*/ARCHITECTURE.md' ! -path '*/EXAMPLES.md' ! -path '*/api/*' | xargs cat)", "output_to": "all_docs"}, - {"step": "analyze_architecture", "command": "bash(ccw cli -p \"PURPOSE: Analyze system architecture\\nTASK: Synthesize architectural overview and examples\\nMODE: analysis\\nCONTEXT: [all_docs]\\nEXPECTED: Architecture + Examples outline\" --tool gemini --mode analysis)", "output_to": "arch_examples_outline"} - ], - "implementation_approach": [ - { - "step": 1, - "title": "Generate architecture and examples documentation", - "modification_points": [ - "Parse [arch_examples_outline] and [all_docs]", - "Generate ARCHITECTURE.md (system design, patterns)", - "Generate EXAMPLES.md (code snippets, usage)", - "Preserve [existing_arch_examples] modifications" - ], - "depends_on": [], - "output": "arch_examples_docs" - } - ], - "target_files": [".workflow/docs/${project_name}/ARCHITECTURE.md", ".workflow/docs/${project_name}/EXAMPLES.md"] - } -} -``` - -### Level 4: HTTP API Documentation Task (Optional) - -**Task ID**: `IMPL-${api_id}` (where `api_id = group_count + 3`) -**Dependencies**: Depends on Level 3. - -```json -{ - "id": "IMPL-${api_id}", - "title": "Generate HTTP API Documentation", - "status": "pending", - "depends_on": ["IMPL-${arch_id}"], - "meta": {"type": "docs", "agent": "@doc-generator", "tool": "gemini", "cli_execute": false}, - "flow_control": { - "pre_analysis": [ - {"step": "discover_api", "command": "bash(rg 'router\\.| @(Get|Post)' -g '*.{ts,js}')", "output_to": "endpoint_discovery"}, - {"step": "load_existing_api", "command": "bash(cat .workflow/docs/${project_name}/api/README.md 2>/dev/null || echo 'No existing API docs')", "output_to": "existing_api_docs"}, - {"step": "analyze_api", "command": "bash(ccw cli -p \"PURPOSE: Document HTTP API\\nTASK: Analyze endpoints\\nMODE: analysis\\nCONTEXT: @src/api/**/* [endpoint_discovery]\\nEXPECTED: API outline\" --tool gemini --mode analysis)", "output_to": "api_outline"} - ], - "implementation_approach": [ - { - "step": 1, - "title": "Generate HTTP API documentation", - "modification_points": [ - "Parse [api_outline] and [endpoint_discovery]", - "Document endpoints, request/response formats", - "Preserve [existing_api_docs] modifications" - ], - "depends_on": [], - "output": "api_docs" - } - ], - "target_files": [".workflow/docs/${project_name}/api/README.md"] - } -} -``` - -## Session Structure - -**Unified Structure** (single JSON replaces multiple text files): - -``` -.workflow/active/ -└── WFS-docs-{timestamp}/ - ├── workflow-session.json # Session metadata - ├── IMPL_PLAN.md - ├── TODO_LIST.md - ├── .process/ - │ └── doc-planning-data.json # All Phase 2 analysis data (replaces 7+ files) - └── .task/ - ├── IMPL-001.json # Small: all modules | Large: group 1 - ├── IMPL-00N.json # (Large only: groups 2-N) - ├── IMPL-{N+1}.json # README (full mode) - ├── IMPL-{N+2}.json # ARCHITECTURE+EXAMPLES (full mode) - └── IMPL-{N+3}.json # HTTP API (optional) -``` - -**doc-planning-data.json Structure**: -```json -{ - "metadata": { - "generated_at": "2025-11-03T16:41:06+08:00", - "project_name": "Claude_dms3", - "project_root": "/d/Claude_dms3" - }, - "folder_analysis": [ - {"path": "./src/core", "type": "code", "code_count": 5, "dirs_count": 2}, - {"path": "./src/utils", "type": "navigation", "code_count": 0, "dirs_count": 4} - ], - "top_level_dirs": ["src/modules", "src/utils", "lib/core"], - "existing_docs": { - "file_list": [".workflow/docs/project/src/core/API.md"], - "content": "... concatenated existing docs ..." - }, - "unified_analysis": [ - {"module_path": "./src/core", "outline_summary": "Core functionality"} - ], - "groups": { - "count": 4, - "assignments": [ - {"group_id": "001", "directories": ["src/modules", "src/utils"], "doc_count": 6}, - {"group_id": "002", "directories": ["lib/core", "lib/helpers"], "doc_count": 7} - ] - }, - "statistics": { - "total": 15, - "code": 8, - "navigation": 7, - "top_level": 3 - } -} -``` - -**Workflow Session Structure** (workflow-session.json): -```json -{ - "session_id": "WFS-docs-{timestamp}", - "project": "{project_name} documentation", - "status": "planning", - "timestamp": "2024-01-20T14:30:22+08:00", - "path": ".", - "target_path": "/path/to/project", - "project_root": "/path/to/project", - "project_name": "{project_name}", - "mode": "full", - "tool": "gemini", - "cli_execute": false, - "update_mode": "update", - "existing_docs": 5, - "analysis": { - "total": "15", - "code": "8", - "navigation": "7", - "top_level": "3" - } -} -``` - -## Generated Documentation - -**Structure mirrors project source directories under project-specific folder**: - -``` -.workflow/docs/ -└── {project_name}/ # Project-specific root - ├── src/ # Mirrors src/ directory - │ ├── modules/ - │ │ ├── README.md # Navigation - │ │ ├── auth/ - │ │ │ ├── API.md # API signatures - │ │ │ ├── README.md # Module docs - │ │ │ └── middleware/ - │ │ │ ├── API.md - │ │ │ └── README.md - │ │ └── api/ - │ │ ├── API.md - │ │ └── README.md - │ └── utils/ - │ └── README.md - ├── lib/ # Mirrors lib/ directory - │ └── core/ - │ ├── API.md - │ └── README.md - ├── README.md # Project root - ├── ARCHITECTURE.md # System design - ├── EXAMPLES.md # Usage examples - └── api/ # Optional - └── README.md # HTTP API reference -``` - -## Execution Commands - -```bash -# Execute entire workflow (auto-discovers active session) -/workflow:execute - -# Or specify session -/workflow:execute --resume-session="WFS-docs-yyyymmdd-hhmmss" - -# Individual task execution -/task:execute IMPL-001 -``` - -## Template Reference - -**Available Templates** (`~/.claude/workflows/cli-templates/prompts/documentation/`): -- `api.txt`: Code API (Part A) + HTTP API (Part B) -- `module-readme.txt`: Module purpose, usage, dependencies -- `folder-navigation.txt`: Navigation README for folders with subdirectories -- `project-readme.txt`: Project overview, getting started, navigation -- `project-architecture.txt`: System structure, module map, design patterns -- `project-examples.txt`: End-to-end usage examples - -## Execution Mode Summary - -| Mode | CLI Placement | CLI MODE | Approval Flag | Agent Role | -|------|---------------|----------|---------------|------------| -| **Agent (default)** | pre_analysis | analysis | (none) | Generates documentation content | -| **CLI (--cli-execute)** | implementation_approach | write | --mode write | Executes CLI commands, validates output | - -**Execution Flow**: -- **Phase 2**: Unified analysis once, results in `.process/` -- **Phase 4**: Dynamic grouping (max 2 dirs per group) -- **Level 1**: Parallel processing for module tree groups -- **Level 2+**: Sequential execution for project-level docs - -## Related Commands -- `/workflow:execute` - Execute documentation tasks -- `/workflow:status` - View task progress -- `/workflow:session:complete` - Mark session complete diff --git a/.claude/commands/memory/load-skill-memory.md b/.claude/commands/memory/load-skill-memory.md deleted file mode 100644 index 5d2e24ce..00000000 --- a/.claude/commands/memory/load-skill-memory.md +++ /dev/null @@ -1,182 +0,0 @@ ---- -name: load-skill-memory -description: Activate SKILL package (auto-detect from paths/keywords or manual) and intelligently load documentation based on task intent keywords -argument-hint: "[skill_name] \"task intent description\"" -allowed-tools: Bash(*), Read(*), Skill(*) ---- - -# Memory Load SKILL Command (/memory:load-skill-memory) - -## 1. Overview - -The `memory:load-skill-memory` command **activates SKILL package** (auto-detect from task or manual specification) and intelligently loads documentation based on user's task intent. The system automatically determines which documentation files to read based on the intent description. - -**Core Philosophy**: -- **Flexible Activation**: Auto-detect skill from task description/paths, or user explicitly specifies -- **Intent-Driven Loading**: System analyzes task intent to determine documentation scope -- **Intelligent Selection**: Automatically chooses appropriate documentation level and modules -- **Direct Context Loading**: Loads selected documentation into conversation memory - -**When to Use**: -- Manually activate a known SKILL package for a specific task -- Load SKILL context when system hasn't auto-triggered it -- Force reload SKILL documentation with specific intent focus - -**Note**: Normal SKILL activation happens automatically via description triggers or path mentions (system extracts skill name from file paths for intelligent triggering). Use this command only when manual activation is needed. - -## 2. Parameters - -- `[skill_name]` (Optional): Name of SKILL package to activate - - If omitted: System auto-detects from task description or file paths - - If specified: Direct activation of named SKILL package - - Example: `my_project`, `api_service` - - Must match directory name under `.claude/skills/` - -- `"task intent description"` (Required): Description of what you want to do - - Used for both: auto-detection (if skill_name omitted) and documentation scope selection - - **Analysis tasks**: "分析builder pattern实现", "理解参数系统架构" - - **Modification tasks**: "修改workflow逻辑", "增强thermal template功能" - - **Learning tasks**: "学习接口设计模式", "了解测试框架使用" - - **With paths**: "修改D:\projects\my_project\src\auth.py的认证逻辑" (auto-extracts `my_project`) - -## 3. Execution Flow - -### Step 1: Determine SKILL Name (if not provided) - -**Auto-Detection Strategy** (when skill_name parameter is omitted): -1. **Path Extraction**: Scan task description for file paths - - Extract potential project names from path segments - - Example: `"修改D:\projects\my_project\src\auth.py"` → extracts `my_project` -2. **Keyword Matching**: Match task keywords against SKILL descriptions - - Search for project-specific terms, domain keywords -3. **Validation**: Check if extracted name matches `.claude/skills/{skill_name}/` - -**Result**: Either uses provided skill_name or auto-detected name for activation - -### Step 2: Activate SKILL and Analyze Intent - -**Activate SKILL Package**: -```javascript -Skill(command: "${skill_name}") // Uses provided or auto-detected name -``` - -**What Happens After Activation**: -1. If SKILL exists in memory: System reads `.claude/skills/${skill_name}/SKILL.md` -2. If SKILL not found in memory: Error - SKILL package doesn't exist -3. SKILL description triggers are loaded into memory -4. Progressive loading mechanism becomes available -5. Documentation structure is now accessible - -**Intent Analysis**: -Based on task intent description, system determines: -- **Action type**: analyzing, modifying, learning -- **Scope**: specific module, architecture overview, complete system -- **Depth**: quick reference, detailed API, full documentation - -### Step 3: Intelligent Documentation Loading - -**Loading Strategy**: - -The system automatically selects documentation based on intent keywords: - -1. **Quick Understanding** ("了解", "快速理解", "什么是"): - - Load: Level 0 (README.md only, ~2K tokens) - - Use case: Quick overview of capabilities - -2. **Specific Module Analysis** ("分析XXX模块", "理解XXX实现"): - - Load: Module-specific README.md + API.md (~5K tokens) - - Use case: Deep dive into specific component - -3. **Architecture Review** ("架构", "设计模式", "整体结构"): - - Load: README.md + ARCHITECTURE.md (~10K tokens) - - Use case: System design understanding - -4. **Implementation/Modification** ("修改", "增强", "实现"): - - Load: Relevant module docs + EXAMPLES.md (~15K tokens) - - Use case: Code modification with examples - -5. **Comprehensive Learning** ("学习", "完整了解", "深入理解"): - - Load: Level 3 (All documentation, ~40K tokens) - - Use case: Complete system mastery - -**Documentation Loaded into Memory**: -After loading, the selected documentation content is available in conversation memory for subsequent operations. - -## 4. Usage Examples - -### Example 1: Manual Specification - -**User Command**: -```bash -/memory:load-skill-memory my_project "修改认证模块增加OAuth支持" -``` - -**Execution**: -```javascript -// Step 1: Use provided skill_name -skill_name = "my_project" // Directly from parameter - -// Step 2: Activate SKILL -Skill(command: "my_project") - -// Step 3: Intent Analysis -Keywords: ["修改", "认证模块", "增加", "OAuth"] -Action: modifying (implementation) -Scope: auth module + examples - -// Load documentation based on intent -Read(.workflow/docs/my_project/auth/README.md) -Read(.workflow/docs/my_project/auth/API.md) -Read(.workflow/docs/my_project/EXAMPLES.md) -``` - -### Example 2: Auto-Detection from Path - -**User Command**: -```bash -/memory:load-skill-memory "修改D:\projects\my_project\src\services\api.py的接口逻辑" -``` - -**Execution**: -```javascript -// Step 1: Auto-detect skill_name from path -Path detected: "D:\projects\my_project\src\services\api.py" -Extracted: "my_project" -Validated: .claude/skills/my_project/ exists ✓ -skill_name = "my_project" - -// Step 2: Activate SKILL -Skill(command: "my_project") - -// Step 3: Intent Analysis -Keywords: ["修改", "services", "接口逻辑"] -Action: modifying (implementation) -Scope: services module + examples - -// Load documentation based on intent -Read(.workflow/docs/my_project/services/README.md) -Read(.workflow/docs/my_project/services/API.md) -Read(.workflow/docs/my_project/EXAMPLES.md) -``` - -## 5. Intent Keyword Mapping - -**Quick Reference**: -- **Triggers**: "了解", "快速", "什么是", "简介" -- **Loads**: README.md only (~2K) - -**Module-Specific**: -- **Triggers**: "XXX模块", "XXX组件", "分析XXX" -- **Loads**: Module README + API (~5K) - -**Architecture**: -- **Triggers**: "架构", "设计", "整体结构", "系统设计" -- **Loads**: README + ARCHITECTURE (~10K) - -**Implementation**: -- **Triggers**: "修改", "增强", "实现", "开发", "集成" -- **Loads**: Relevant module + EXAMPLES (~15K) - -**Comprehensive**: -- **Triggers**: "完整", "深入", "全面", "学习整个" -- **Loads**: All documentation (~40K) diff --git a/.claude/commands/memory/skill-memory.md b/.claude/commands/memory/skill-memory.md deleted file mode 100644 index 22b399f8..00000000 --- a/.claude/commands/memory/skill-memory.md +++ /dev/null @@ -1,525 +0,0 @@ ---- -name: skill-memory -description: 4-phase autonomous orchestrator: check docs → /memory:docs planning → /workflow:execute → generate SKILL.md with progressive loading index (skips phases 2-3 if docs exist) -argument-hint: "[path] [--tool ] [--regenerate] [--mode ] [--cli-execute]" -allowed-tools: SlashCommand(*), TodoWrite(*), Bash(*), Read(*), Write(*) ---- - -# Memory SKILL Package Generator - -## Orchestrator Role - -**Pure Orchestrator**: Execute documentation generation workflow, then generate SKILL.md index. Does NOT create task JSON files. - -**Auto-Continue Workflow**: This command runs **fully autonomously** once triggered. Each phase completes and automatically triggers the next phase without user interaction. - -**Execution Paths**: -- **Full Path**: All 4 phases (no existing docs OR `--regenerate` specified) -- **Skip Path**: Phase 1 → Phase 4 (existing docs found AND no `--regenerate` flag) -- **Phase 4 Always Executes**: SKILL.md index is never skipped, always generated or updated - -## Core Rules - -1. **Start Immediately**: First action is TodoWrite initialization, second action is Phase 1 execution -2. **No Task JSON**: This command does not create task JSON files - delegates to /memory:docs -3. **Parse Every Output**: Extract required data from each command output (session_id, task_count, file paths) -4. **Auto-Continue**: After completing each phase, update TodoWrite and immediately execute next phase -5. **Track Progress**: Update TodoWrite after EVERY phase completion before starting next phase -6. **Direct Generation**: Phase 4 directly generates SKILL.md using Write tool -7. **No Manual Steps**: User should never be prompted for decisions between phases - ---- - -## 4-Phase Execution - -### Phase 1: Prepare Arguments - -**Goal**: Parse command arguments and check existing documentation - -**Step 1: Get Target Path and Project Name** -```bash -# Get current directory (or use provided path) -bash(pwd) - -# Get project name from directory -bash(basename "$(pwd)") - -# Get project root -bash(git rev-parse --show-toplevel 2>/dev/null || pwd) -``` - -**Output**: -- `target_path`: `/d/my_project` -- `project_name`: `my_project` -- `project_root`: `/d/my_project` - -**Step 2: Set Default Parameters** -```bash -# Default values (use these unless user specifies otherwise): -# - tool: "gemini" -# - mode: "full" -# - regenerate: false (no --regenerate flag) -# - cli_execute: false (no --cli-execute flag) -``` - -**Step 3: Check Existing Documentation** -```bash -# Check if docs directory exists -bash(test -d .workflow/docs/my_project && echo "exists" || echo "not_exists") - -# Count existing documentation files -bash(find .workflow/docs/my_project -name "*.md" 2>/dev/null | wc -l || echo 0) -``` - -**Output**: -- `docs_exists`: `exists` or `not_exists` -- `existing_docs`: `5` (or `0` if no docs) - -**Step 4: Determine Execution Path** - -**Decision Logic**: -```javascript -if (existing_docs > 0 && !regenerate_flag) { - // Documentation exists and no regenerate flag - SKIP_DOCS_GENERATION = true - message = "Documentation already exists, skipping Phase 2 and Phase 3. Use --regenerate to force regeneration." -} else if (regenerate_flag) { - // Force regeneration: delete existing docs - bash(rm -rf .workflow/docs/my_project 2>/dev/null || true) - SKIP_DOCS_GENERATION = false - message = "Regenerating documentation from scratch." -} else { - // No existing docs - SKIP_DOCS_GENERATION = false - message = "No existing documentation found, generating new documentation." -} -``` - -**Summary Variables**: -- `PROJECT_NAME`: `my_project` -- `TARGET_PATH`: `/d/my_project` -- `DOCS_PATH`: `.workflow/docs/my_project` -- `TOOL`: `gemini` (default) or user-specified -- `MODE`: `full` (default) or user-specified -- `CLI_EXECUTE`: `false` (default) or `true` if --cli-execute flag -- `REGENERATE`: `false` (default) or `true` if --regenerate flag -- `EXISTING_DOCS`: Count of existing documentation files -- `SKIP_DOCS_GENERATION`: `true` if skipping Phase 2/3, `false` otherwise - -**Completion & TodoWrite**: -- If `SKIP_DOCS_GENERATION = true`: Mark phase 1 completed, phase 2&3 completed (skipped), phase 4 in_progress -- If `SKIP_DOCS_GENERATION = false`: Mark phase 1 completed, phase 2 in_progress - -**Next Action**: -- If skipping: Display skip message → Jump to Phase 4 (SKILL.md generation) -- If not skipping: Display preparation results → Continue to Phase 2 (documentation planning) - ---- - -### Phase 2: Call /memory:docs - -**Skip Condition**: This phase is **skipped if SKIP_DOCS_GENERATION = true** (documentation already exists without --regenerate flag) - -**Goal**: Trigger documentation generation workflow - -**Command**: -```bash -SlashCommand(command="/memory:docs [targetPath] --tool [tool] --mode [mode] [--cli-execute]") -``` - -**Example**: -```bash -/memory:docs /d/my_app --tool gemini --mode full -/memory:docs /d/my_app --tool gemini --mode full --cli-execute -``` - -**Note**: The `--regenerate` flag is handled in Phase 1 by deleting existing documentation. This command always calls `/memory:docs` without the regenerate flag, relying on docs.md's built-in update detection. - -**Parse Output**: -- Extract session ID: `WFS-docs-[timestamp]` (store as `docsSessionId`) -- Extract task count (store as `taskCount`) - -**Completion Criteria**: -- `/memory:docs` command executed successfully -- Session ID extracted and stored -- Task count retrieved -- Task files created in `.workflow/[docsSessionId]/.task/` -- workflow-session.json exists - -**TodoWrite**: Mark phase 2 completed, phase 3 in_progress - -**Next Action**: Display docs planning results (session ID, task count) → Auto-continue to Phase 3 - ---- - -### Phase 3: Execute Documentation Generation - -**Skip Condition**: This phase is **skipped if SKIP_DOCS_GENERATION = true** (documentation already exists without --regenerate flag) - -**Goal**: Execute documentation generation tasks - -**Command**: -```bash -SlashCommand(command="/workflow:execute") -``` - -**Note**: `/workflow:execute` automatically discovers active session from Phase 2 - -**Completion Criteria**: -- `/workflow:execute` command executed successfully -- Documentation files generated in `.workflow/docs/[projectName]/` -- All tasks marked as completed in session -- At minimum: module documentation files exist (API.md and/or README.md) -- For full mode: Project README, ARCHITECTURE, EXAMPLES files generated - -**TodoWrite**: Mark phase 3 completed, phase 4 in_progress - -**Next Action**: Display execution results (file count, module count) → Auto-continue to Phase 4 - ---- - -### Phase 4: Generate SKILL.md Index - -**Note**: This phase is **NEVER skipped** - it always executes to generate or update the SKILL index. - -**Step 1: Read Key Files** (Use Read tool) -- `.workflow/docs/{project_name}/README.md` (required) -- `.workflow/docs/{project_name}/ARCHITECTURE.md` (optional) - -**Step 2: Discover Structure** -```bash -bash(find .workflow/docs/{project_name} -name "*.md" | sed 's|.workflow/docs/{project_name}/||' | awk -F'/' '{if(NF>=2) print $1"/"$2}' | sort -u) -``` - -**Step 3: Generate Intelligent Description** - -Extract from README + structure: Function (capabilities), Modules (names), Keywords (API/CLI/auth/etc.) - -**Format**: `{Project} {core capabilities} (located at {project_path}). Load this SKILL when analyzing, modifying, or learning about {domain_description} or files under this path, especially when no relevant context exists in memory.` - -**Key Elements**: -- **Path Reference**: Use `TARGET_PATH` from Phase 1 for precise location identification -- **Domain Description**: Extract human-readable domain/feature area from README (e.g., "workflow management", "thermal modeling") -- **Trigger Optimization**: Include project path, emphasize "especially when no relevant context exists in memory" -- **Action Coverage**: analyzing (分析), modifying (修改), learning (了解) - -**Example**: "Workflow orchestration system with CLI tools and documentation generation (located at /d/Claude_dms3). Load this SKILL when analyzing, modifying, or learning about workflow management or files under this path, especially when no relevant context exists in memory." - -**Step 4: Write SKILL.md** (Use Write tool) -```bash -bash(mkdir -p .claude/skills/{project_name}) -``` - -`.claude/skills/{project_name}/SKILL.md`: -```yaml ---- -name: {project_name} -description: {intelligent description from Step 3} -version: 1.0.0 ---- -# {Project Name} SKILL Package - -## Documentation: `../../../.workflow/docs/{project_name}/` - -## Progressive Loading -### Level 0: Quick Start (~2K) -- [README](../../../.workflow/docs/{project_name}/README.md) -### Level 1: Core Modules (~8K) -{Module READMEs} -### Level 2: Complete (~25K) -All modules + [Architecture](../../../.workflow/docs/{project_name}/ARCHITECTURE.md) -### Level 3: Deep Dive (~40K) -Everything + [Examples](../../../.workflow/docs/{project_name}/EXAMPLES.md) -``` - -**Completion Criteria**: -- SKILL.md file created at `.claude/skills/{project_name}/SKILL.md` -- Intelligent description generated from documentation -- Progressive loading levels (0-3) properly structured -- Module index includes all documented modules -- All file references use relative paths - -**TodoWrite**: Mark phase 4 completed - -**Final Action**: Report completion summary to user - -**Return to User**: -``` -SKILL Package Generation Complete - -Project: {project_name} -Documentation: .workflow/docs/{project_name}/ ({doc_count} files) -SKILL Index: .claude/skills/{project_name}/SKILL.md - -Generated: -- {task_count} documentation tasks completed -- SKILL.md with progressive loading (4 levels) -- Module index with {module_count} modules - -Usage: -- Load Level 0: Quick project overview (~2K tokens) -- Load Level 1: Core modules (~8K tokens) -- Load Level 2: Complete docs (~25K tokens) -- Load Level 3: Everything (~40K tokens) -``` - ---- - -## Implementation Details - -### Critical Rules - -1. **No User Prompts Between Phases**: Never ask user questions or wait for input between phases -2. **Immediate Phase Transition**: After TodoWrite update, immediately execute next phase command -3. **Status-Driven Execution**: Check TodoList status after each phase: - - If next task is "pending" → Mark it "in_progress" and execute - - If all tasks are "completed" → Report final summary -4. **Phase Completion Pattern**: - ``` - Phase N completes → Update TodoWrite (N=completed, N+1=in_progress) → Execute Phase N+1 - ``` - -### TodoWrite Patterns - -#### Initialization (Before Phase 1) - -**FIRST ACTION**: Create TodoList with all 4 phases -```javascript -TodoWrite({todos: [ - {"content": "Parse arguments and prepare", "status": "in_progress", "activeForm": "Parsing arguments"}, - {"content": "Call /memory:docs to plan documentation", "status": "pending", "activeForm": "Calling /memory:docs"}, - {"content": "Execute documentation generation", "status": "pending", "activeForm": "Executing documentation"}, - {"content": "Generate SKILL.md index", "status": "pending", "activeForm": "Generating SKILL.md"} -]}) -``` - -**SECOND ACTION**: Execute Phase 1 immediately - -#### Full Path (SKIP_DOCS_GENERATION = false) - -**After Phase 1**: -```javascript -TodoWrite({todos: [ - {"content": "Parse arguments and prepare", "status": "completed", "activeForm": "Parsing arguments"}, - {"content": "Call /memory:docs to plan documentation", "status": "in_progress", "activeForm": "Calling /memory:docs"}, - {"content": "Execute documentation generation", "status": "pending", "activeForm": "Executing documentation"}, - {"content": "Generate SKILL.md index", "status": "pending", "activeForm": "Generating SKILL.md"} -]}) -// Auto-continue to Phase 2 -``` - -**After Phase 2**: -```javascript -TodoWrite({todos: [ - {"content": "Parse arguments and prepare", "status": "completed", "activeForm": "Parsing arguments"}, - {"content": "Call /memory:docs to plan documentation", "status": "completed", "activeForm": "Calling /memory:docs"}, - {"content": "Execute documentation generation", "status": "in_progress", "activeForm": "Executing documentation"}, - {"content": "Generate SKILL.md index", "status": "pending", "activeForm": "Generating SKILL.md"} -]}) -// Auto-continue to Phase 3 -``` - -**After Phase 3**: -```javascript -TodoWrite({todos: [ - {"content": "Parse arguments and prepare", "status": "completed", "activeForm": "Parsing arguments"}, - {"content": "Call /memory:docs to plan documentation", "status": "completed", "activeForm": "Calling /memory:docs"}, - {"content": "Execute documentation generation", "status": "completed", "activeForm": "Executing documentation"}, - {"content": "Generate SKILL.md index", "status": "in_progress", "activeForm": "Generating SKILL.md"} -]}) -// Auto-continue to Phase 4 -``` - -**After Phase 4**: -```javascript -TodoWrite({todos: [ - {"content": "Parse arguments and prepare", "status": "completed", "activeForm": "Parsing arguments"}, - {"content": "Call /memory:docs to plan documentation", "status": "completed", "activeForm": "Calling /memory:docs"}, - {"content": "Execute documentation generation", "status": "completed", "activeForm": "Executing documentation"}, - {"content": "Generate SKILL.md index", "status": "completed", "activeForm": "Generating SKILL.md"} -]}) -// Report completion summary to user -``` - -#### Skip Path (SKIP_DOCS_GENERATION = true) - -**After Phase 1** (detects existing docs, skips Phase 2 & 3): -```javascript -TodoWrite({todos: [ - {"content": "Parse arguments and prepare", "status": "completed", "activeForm": "Parsing arguments"}, - {"content": "Call /memory:docs to plan documentation", "status": "completed", "activeForm": "Calling /memory:docs"}, - {"content": "Execute documentation generation", "status": "completed", "activeForm": "Executing documentation"}, - {"content": "Generate SKILL.md index", "status": "in_progress", "activeForm": "Generating SKILL.md"} -]}) -// Display skip message: "Documentation already exists, skipping Phase 2 and Phase 3. Use --regenerate to force regeneration." -// Jump directly to Phase 4 -``` - -**After Phase 4**: -```javascript -TodoWrite({todos: [ - {"content": "Parse arguments and prepare", "status": "completed", "activeForm": "Parsing arguments"}, - {"content": "Call /memory:docs to plan documentation", "status": "completed", "activeForm": "Calling /memory:docs"}, - {"content": "Execute documentation generation", "status": "completed", "activeForm": "Executing documentation"}, - {"content": "Generate SKILL.md index", "status": "completed", "activeForm": "Generating SKILL.md"} -]}) -// Report completion summary to user -``` - -### Execution Flow Diagrams - -#### Full Path Flow -``` -User triggers command - ↓ -[TodoWrite] Initialize 4 phases (Phase 1 = in_progress) - ↓ -[Execute] Phase 1: Parse arguments - ↓ -[TodoWrite] Phase 1 = completed, Phase 2 = in_progress - ↓ -[Execute] Phase 2: Call /memory:docs - ↓ -[TodoWrite] Phase 2 = completed, Phase 3 = in_progress - ↓ -[Execute] Phase 3: Call /workflow:execute - ↓ -[TodoWrite] Phase 3 = completed, Phase 4 = in_progress - ↓ -[Execute] Phase 4: Generate SKILL.md - ↓ -[TodoWrite] Phase 4 = completed - ↓ -[Report] Display completion summary -``` - -#### Skip Path Flow -``` -User triggers command - ↓ -[TodoWrite] Initialize 4 phases (Phase 1 = in_progress) - ↓ -[Execute] Phase 1: Parse arguments, detect existing docs - ↓ -[TodoWrite] Phase 1 = completed, Phase 2&3 = completed (skipped), Phase 4 = in_progress - ↓ -[Display] Skip message: "Documentation already exists, skipping Phase 2 and Phase 3" - ↓ -[Execute] Phase 4: Generate SKILL.md (always runs) - ↓ -[TodoWrite] Phase 4 = completed - ↓ -[Report] Display completion summary -``` - -### Error Handling - -- If any phase fails, mark it as "in_progress" (not completed) -- Report error details to user -- Do NOT auto-continue to next phase on failure - ---- - -## Parameters - -```bash -/memory:skill-memory [path] [--tool ] [--regenerate] [--mode ] [--cli-execute] -``` - -- **path**: Target directory (default: current directory) -- **--tool**: CLI tool for documentation (default: gemini) - - `gemini`: Comprehensive documentation - - `qwen`: Architecture analysis - - `codex`: Implementation validation -- **--regenerate**: Force regenerate all documentation - - When enabled: Deletes existing `.workflow/docs/{project_name}/` before regeneration - - Ensures fresh documentation from source code -- **--mode**: Documentation mode (default: full) - - `full`: Complete docs (modules + README + ARCHITECTURE + EXAMPLES) - - `partial`: Module docs only -- **--cli-execute**: Enable CLI-based documentation generation (optional) - - When enabled: CLI generates docs directly in implementation_approach - - When disabled (default): Agent generates documentation content - ---- - -## Examples - -### Example 1: Generate SKILL Package (Default) - -```bash -/memory:skill-memory -``` - -**Workflow**: -1. Phase 1: Detects current directory, checks existing docs -2. Phase 2: Calls `/memory:docs . --tool gemini --mode full` (Agent Mode) -3. Phase 3: Executes documentation generation via `/workflow:execute` -4. Phase 4: Generates SKILL.md at `.claude/skills/{project_name}/SKILL.md` - -### Example 2: Regenerate with Qwen - -```bash -/memory:skill-memory /d/my_app --tool qwen --regenerate -``` - -**Workflow**: -1. Phase 1: Parses target path, detects regenerate flag, deletes existing docs -2. Phase 2: Calls `/memory:docs /d/my_app --tool qwen --mode full` -3. Phase 3: Executes documentation regeneration -4. Phase 4: Generates updated SKILL.md - -### Example 3: Partial Mode (Modules Only) - -```bash -/memory:skill-memory --mode partial -``` - -**Workflow**: -1. Phase 1: Detects partial mode -2. Phase 2: Calls `/memory:docs . --tool gemini --mode partial` (Agent Mode) -3. Phase 3: Executes module documentation only -4. Phase 4: Generates SKILL.md with module-only index - -### Example 4: CLI Execute Mode - -```bash -/memory:skill-memory --cli-execute -``` - -**Workflow**: -1. Phase 1: Detects CLI execute mode -2. Phase 2: Calls `/memory:docs . --tool gemini --mode full --cli-execute` (CLI Mode) -3. Phase 3: Executes CLI-based documentation generation -4. Phase 4: Generates SKILL.md at `.claude/skills/{project_name}/SKILL.md` - -### Example 5: Skip Path (Existing Docs) - -```bash -/memory:skill-memory -``` - -**Scenario**: Documentation already exists in `.workflow/docs/{project_name}/` - -**Workflow**: -1. Phase 1: Detects existing docs (5 files), sets SKIP_DOCS_GENERATION = true -2. Display: "Documentation already exists, skipping Phase 2 and Phase 3. Use --regenerate to force regeneration." -3. Phase 4: Generates or updates SKILL.md index only (~5-10x faster) - ---- - - - -## Architecture - -``` -skill-memory (orchestrator) - ├─ Phase 1: Prepare (bash commands, skip decision) - ├─ Phase 2: /memory:docs (task planning, skippable) - ├─ Phase 3: /workflow:execute (task execution, skippable) - └─ Phase 4: Write SKILL.md (direct file generation, always runs) - -No task JSON created by this command -All documentation tasks managed by /memory:docs -Smart skip logic: 5-10x faster when docs exist -``` diff --git a/.claude/commands/memory/swagger-docs.md b/.claude/commands/memory/swagger-docs.md deleted file mode 100644 index 6cc3ffb6..00000000 --- a/.claude/commands/memory/swagger-docs.md +++ /dev/null @@ -1,773 +0,0 @@ ---- -name: swagger-docs -description: Generate complete Swagger/OpenAPI documentation following RESTful standards with global security, API details, error codes, and validation tests -argument-hint: "[path] [--tool ] [--format ] [--version ] [--lang ]" ---- - -# Swagger API Documentation Workflow (/memory:swagger-docs) - -## Overview - -Professional Swagger/OpenAPI documentation generator that strictly follows RESTful API design standards to produce enterprise-grade API documentation. - -**Core Features**: -- **RESTful Standards**: Strict adherence to REST architecture and HTTP semantics -- **Global Security**: Unified Authorization Token validation mechanism -- **Complete API Docs**: Descriptions, methods, URLs, parameters for each endpoint -- **Organized Structure**: Clear directory hierarchy by business domain -- **Detailed Fields**: Type, required, example, description for each field -- **Error Code Standards**: Unified error response format and code definitions -- **Validation Tests**: Boundary conditions and exception handling tests - -**Output Structure** (--lang zh): -``` -.workflow/docs/{project_name}/api/ -├── swagger.yaml # Main OpenAPI spec file -├── 概述/ -│ ├── README.md # API overview -│ ├── 认证说明.md # Authentication guide -│ ├── 错误码规范.md # Error code definitions -│ └── 版本历史.md # Version history -├── 用户模块/ # Grouped by business domain -│ ├── 用户认证.md -│ ├── 用户管理.md -│ └── 权限控制.md -├── 业务模块/ -│ └── ... -└── 测试报告/ - ├── 接口测试.md # API test results - └── 边界测试.md # Boundary condition tests -``` - -**Output Structure** (--lang en): -``` -.workflow/docs/{project_name}/api/ -├── swagger.yaml # Main OpenAPI spec file -├── overview/ -│ ├── README.md # API overview -│ ├── authentication.md # Authentication guide -│ ├── error-codes.md # Error code definitions -│ └── changelog.md # Version history -├── users/ # Grouped by business domain -│ ├── authentication.md -│ ├── management.md -│ └── permissions.md -├── orders/ -│ └── ... -└── test-reports/ - ├── api-tests.md # API test results - └── boundary-tests.md # Boundary condition tests -``` - -## Parameters - -```bash -/memory:swagger-docs [path] [--tool ] [--format ] [--version ] [--lang ] -``` - -- **path**: API source code directory (default: current directory) -- **--tool**: CLI tool selection (default: gemini) - - `gemini`: Comprehensive analysis, pattern recognition - - `qwen`: Architecture analysis, system design - - `codex`: Implementation validation, code quality -- **--format**: OpenAPI spec format (default: yaml) - - `yaml`: YAML format (recommended, better readability) - - `json`: JSON format -- **--version**: OpenAPI version (default: v3.0) - - `v3.0`: OpenAPI 3.0.x - - `v3.1`: OpenAPI 3.1.0 (supports JSON Schema 2020-12) -- **--lang**: Documentation language (default: zh) - - `zh`: Chinese documentation with Chinese directory names - - `en`: English documentation with English directory names - -## Planning Workflow - -### Phase 1: Initialize Session - -```bash -# Get project info -bash(pwd && basename "$(pwd)" && git rev-parse --show-toplevel 2>/dev/null || pwd && date +%Y%m%d-%H%M%S) -``` - -```javascript -// Create swagger-docs session -SlashCommand(command="/workflow:session:start --type swagger-docs --new \"{project_name}-swagger-{timestamp}\"") -// Parse output to get sessionId -``` - -```bash -# Update workflow-session.json -bash(jq '. + {"target_path":"{target_path}","project_root":"{project_root}","project_name":"{project_name}","format":"yaml","openapi_version":"3.0.3","lang":"{lang}","tool":"gemini"}' .workflow/active/{sessionId}/workflow-session.json > tmp.json && mv tmp.json .workflow/active/{sessionId}/workflow-session.json) -``` - -### Phase 2: Scan API Endpoints - -**Discovery Patterns**: Auto-detect framework signatures and API definition styles. - -**Supported Frameworks**: -| Framework | Detection Pattern | Example | -|-----------|-------------------|---------| -| Express.js | `router.get/post/put/delete` | `router.get('/users/:id')` | -| Fastify | `fastify.route`, `@Route` | `fastify.get('/api/users')` | -| NestJS | `@Controller`, `@Get/@Post` | `@Get('users/:id')` | -| Koa | `router.get`, `ctx.body` | `router.get('/users')` | -| Hono | `app.get/post`, `c.json` | `app.get('/users/:id')` | -| FastAPI | `@app.get`, `@router.post` | `@app.get("/users/{id}")` | -| Flask | `@app.route`, `@bp.route` | `@app.route('/users')` | -| Spring | `@GetMapping`, `@PostMapping` | `@GetMapping("/users/{id}")` | -| Go Gin | `r.GET`, `r.POST` | `r.GET("/users/:id")` | -| Go Chi | `r.Get`, `r.Post` | `r.Get("/users/{id}")` | - -**Commands**: - -```bash -# 1. Detect API framework type -bash( - if rg -q "@Controller|@Get|@Post|@Put|@Delete" --type ts 2>/dev/null; then echo "NESTJS"; - elif rg -q "router\.(get|post|put|delete|patch)" --type ts --type js 2>/dev/null; then echo "EXPRESS"; - elif rg -q "fastify\.(get|post|route)" --type ts --type js 2>/dev/null; then echo "FASTIFY"; - elif rg -q "@app\.(get|post|put|delete)" --type py 2>/dev/null; then echo "FASTAPI"; - elif rg -q "@GetMapping|@PostMapping|@RequestMapping" --type java 2>/dev/null; then echo "SPRING"; - elif rg -q 'r\.(GET|POST|PUT|DELETE)' --type go 2>/dev/null; then echo "GO_GIN"; - else echo "UNKNOWN"; fi -) - -# 2. Scan all API endpoint definitions -bash(rg -n "(router|app|fastify)\.(get|post|put|delete|patch)|@(Get|Post|Put|Delete|Patch|Controller|RequestMapping)" --type ts --type js --type py --type java --type go -g '!*.test.*' -g '!*.spec.*' -g '!node_modules/**' 2>/dev/null | head -200) - -# 3. Extract route paths -bash(rg -o "['\"](/api)?/[a-zA-Z0-9/:_-]+['\"]" --type ts --type js --type py -g '!*.test.*' 2>/dev/null | sort -u | head -100) - -# 4. Detect existing OpenAPI/Swagger files -bash(find . -type f \( -name "swagger.yaml" -o -name "swagger.json" -o -name "openapi.yaml" -o -name "openapi.json" \) ! -path "*/node_modules/*" 2>/dev/null) - -# 5. Extract DTO/Schema definitions -bash(rg -n "export (interface|type|class).*Dto|@ApiProperty|class.*Schema" --type ts -g '!*.test.*' 2>/dev/null | head -100) -``` - -**Data Processing**: Parse outputs, use **Write tool** to create `${session_dir}/.process/swagger-planning-data.json`: - -```json -{ - "metadata": { - "generated_at": "2025-01-01T12:00:00+08:00", - "project_name": "project_name", - "project_root": "/path/to/project", - "openapi_version": "3.0.3", - "format": "yaml", - "lang": "zh" - }, - "framework": { - "type": "NESTJS", - "detected_patterns": ["@Controller", "@Get", "@Post"], - "base_path": "/api/v1" - }, - "endpoints": [ - { - "file": "src/modules/users/users.controller.ts", - "line": 25, - "method": "GET", - "path": "/api/v1/users/:id", - "handler": "getUser", - "controller": "UsersController" - } - ], - "existing_specs": { - "found": false, - "files": [] - }, - "dto_schemas": [ - { - "name": "CreateUserDto", - "file": "src/modules/users/dto/create-user.dto.ts", - "properties": ["email", "password", "name"] - } - ], - "statistics": { - "total_endpoints": 45, - "by_method": {"GET": 20, "POST": 15, "PUT": 5, "DELETE": 5}, - "by_module": {"users": 12, "auth": 8, "orders": 15, "products": 10} - } -} -``` - -### Phase 3: Analyze API Structure - -**Commands**: - -```bash -# 1. Analyze controller/route file structure -bash(cat ${session_dir}/.process/swagger-planning-data.json | jq -r '.endpoints[].file' | sort -u | head -20) - -# 2. Extract request/response types -bash(for f in $(jq -r '.dto_schemas[].file' ${session_dir}/.process/swagger-planning-data.json | head -20); do echo "=== $f ===" && cat "$f" 2>/dev/null; done) - -# 3. Analyze authentication middleware -bash(rg -n "auth|guard|middleware|jwt|bearer|token" -i --type ts --type js -g '!*.test.*' -g '!node_modules/**' 2>/dev/null | head -50) - -# 4. Detect error handling patterns -bash(rg -n "HttpException|BadRequest|Unauthorized|Forbidden|NotFound|throw new" --type ts --type js -g '!*.test.*' 2>/dev/null | head -50) -``` - -**Deep Analysis via Gemini CLI**: - -```bash -ccw cli -p " -PURPOSE: Analyze API structure and generate OpenAPI specification outline for comprehensive documentation -TASK: -• Parse all API endpoints and identify business module boundaries -• Extract request parameters, request bodies, and response formats -• Identify authentication mechanisms and security requirements -• Discover error handling patterns and error codes -• Map endpoints to logical module groups -MODE: analysis -CONTEXT: @src/**/*.controller.ts @src/**/*.routes.ts @src/**/*.dto.ts @src/**/middleware/**/* -EXPECTED: JSON format API structure analysis report with modules, endpoints, security schemes, and error codes -CONSTRAINTS: Strict RESTful standards | Identify all public endpoints | Document output language: {lang} -" --tool gemini --mode analysis --rule analysis-code-patterns --cd {project_root} -``` - -**Update swagger-planning-data.json** with analysis results: - -```json -{ - "api_structure": { - "modules": [ - { - "name": "Users", - "name_zh": "用户模块", - "base_path": "/api/v1/users", - "endpoints": [ - { - "path": "/api/v1/users", - "method": "GET", - "operation_id": "listUsers", - "summary": "List all users", - "summary_zh": "获取用户列表", - "description": "Paginated list of system users with filtering by status and role", - "description_zh": "分页获取系统用户列表,支持按状态、角色筛选", - "tags": ["User Management"], - "tags_zh": ["用户管理"], - "security": ["bearerAuth"], - "parameters": { - "query": ["page", "limit", "status", "role"] - }, - "responses": { - "200": "UserListResponse", - "401": "UnauthorizedError", - "403": "ForbiddenError" - } - } - ] - } - ], - "security_schemes": { - "bearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT", - "description": "JWT Token authentication. Add Authorization: Bearer to request header" - } - }, - "error_codes": [ - {"code": "AUTH_001", "status": 401, "message": "Invalid or expired token", "message_zh": "Token 无效或已过期"}, - {"code": "AUTH_002", "status": 401, "message": "Authentication required", "message_zh": "未提供认证信息"}, - {"code": "AUTH_003", "status": 403, "message": "Insufficient permissions", "message_zh": "权限不足"} - ] - } -} -``` - -### Phase 4: Task Decomposition - -**Task Hierarchy**: - -``` -Level 1: Infrastructure Tasks (Parallel) - ├─ IMPL-001: Generate main OpenAPI spec file (swagger.yaml) - ├─ IMPL-002: Generate global security config and auth documentation - └─ IMPL-003: Generate unified error code specification - -Level 2: Module Documentation Tasks (Parallel, by business module) - ├─ IMPL-004: Users module API documentation - ├─ IMPL-005: Auth module API documentation - ├─ IMPL-006: Business module N API documentation - └─ ... - -Level 3: Aggregation Tasks (Depends on Level 1-2) - ├─ IMPL-N+1: Generate API overview and navigation - └─ IMPL-N+2: Generate version history and changelog - -Level 4: Validation Tasks (Depends on Level 1-3) - ├─ IMPL-N+3: API endpoint validation tests - └─ IMPL-N+4: Boundary condition tests -``` - -**Grouping Strategy**: -1. Group by business module (users, orders, products, etc.) -2. Maximum 10 endpoints per task -3. Large modules (>10 endpoints) split by submodules - -**Commands**: - -```bash -# 1. Count endpoints by module -bash(cat ${session_dir}/.process/swagger-planning-data.json | jq '.statistics.by_module') - -# 2. Calculate task groupings -bash(cat ${session_dir}/.process/swagger-planning-data.json | jq -r '.api_structure.modules[] | "\(.name):\(.endpoints | length)"') -``` - -**Data Processing**: Use **Edit tool** to update `swagger-planning-data.json` with task groups: - -```json -{ - "task_groups": { - "level1_count": 3, - "level2_count": 5, - "total_count": 12, - "assignments": [ - {"task_id": "IMPL-001", "level": 1, "type": "openapi-spec", "title": "Generate OpenAPI main spec file"}, - {"task_id": "IMPL-002", "level": 1, "type": "security", "title": "Generate global security config"}, - {"task_id": "IMPL-003", "level": 1, "type": "error-codes", "title": "Generate error code specification"}, - {"task_id": "IMPL-004", "level": 2, "type": "module-doc", "module": "users", "endpoint_count": 12}, - {"task_id": "IMPL-005", "level": 2, "type": "module-doc", "module": "auth", "endpoint_count": 8} - ] - } -} -``` - -### Phase 5: Generate Task JSONs - -**Generation Process**: -1. Read configuration values from workflow-session.json -2. Read task groups from swagger-planning-data.json -3. Generate Level 1 tasks (infrastructure) -4. Generate Level 2 tasks (by module) -5. Generate Level 3-4 tasks (aggregation and validation) - -## Task Templates - -### Level 1-1: OpenAPI Main Spec File - -```json -{ - "id": "IMPL-001", - "title": "Generate OpenAPI main specification file", - "status": "pending", - "meta": { - "type": "swagger-openapi-spec", - "agent": "@doc-generator", - "tool": "gemini", - "priority": "critical" - }, - "context": { - "requirements": [ - "Generate OpenAPI 3.0.3 compliant swagger.yaml", - "Include complete info, servers, tags, paths, components definitions", - "Follow RESTful design standards, use {lang} for descriptions" - ], - "precomputed_data": { - "planning_data": "${session_dir}/.process/swagger-planning-data.json" - } - }, - "flow_control": { - "pre_analysis": [ - { - "step": "load_analysis_data", - "action": "Load API analysis data", - "commands": [ - "bash(cat ${session_dir}/.process/swagger-planning-data.json)" - ], - "output_to": "api_analysis" - } - ], - "implementation_approach": [ - { - "step": 1, - "title": "Generate OpenAPI spec file", - "description": "Create complete swagger.yaml specification file", - "cli_prompt": "PURPOSE: Generate OpenAPI 3.0.3 specification file from analyzed API structure\nTASK:\n• Define openapi version: 3.0.3\n• Define info: title, description, version, contact, license\n• Define servers: development, staging, production environments\n• Define tags: organized by business modules\n• Define paths: all API endpoints with complete specifications\n• Define components: schemas, securitySchemes, parameters, responses\nMODE: write\nCONTEXT: @[api_analysis]\nEXPECTED: Complete swagger.yaml file following OpenAPI 3.0.3 specification\nCONSTRAINTS: Use {lang} for all descriptions | Strict RESTful standards\n--rule documentation-swagger-api", - "output": "swagger.yaml" - } - ], - "target_files": [ - ".workflow/docs/${project_name}/api/swagger.yaml" - ] - } -} -``` - -### Level 1-2: Global Security Configuration - -```json -{ - "id": "IMPL-002", - "title": "Generate global security configuration and authentication guide", - "status": "pending", - "meta": { - "type": "swagger-security", - "agent": "@doc-generator", - "tool": "gemini" - }, - "context": { - "requirements": [ - "Document Authorization header format in detail", - "Describe token acquisition, refresh, and expiration mechanisms", - "List permission requirements for each endpoint" - ] - }, - "flow_control": { - "pre_analysis": [ - { - "step": "analyze_auth", - "command": "bash(rg -n 'auth|guard|jwt|bearer' -i --type ts -g '!*.test.*' 2>/dev/null | head -50)", - "output_to": "auth_patterns" - } - ], - "implementation_approach": [ - { - "step": 1, - "title": "Generate authentication documentation", - "cli_prompt": "PURPOSE: Generate comprehensive authentication documentation for API security\nTASK:\n• Document authentication mechanism: JWT Bearer Token\n• Explain header format: Authorization: Bearer \n• Describe token lifecycle: acquisition, refresh, expiration handling\n• Define permission levels: public, user, admin, super_admin\n• Document authentication failure responses: 401/403 error handling\nMODE: write\nCONTEXT: @[auth_patterns] @src/**/auth/**/* @src/**/guard/**/*\nEXPECTED: Complete authentication guide in {lang}\nCONSTRAINTS: Include code examples | Clear step-by-step instructions\n--rule development-feature", - "output": "{auth_doc_name}" - } - ], - "target_files": [ - ".workflow/docs/${project_name}/api/{overview_dir}/{auth_doc_name}" - ] - } -} -``` - -### Level 1-3: Unified Error Code Specification - -```json -{ - "id": "IMPL-003", - "title": "Generate unified error code specification", - "status": "pending", - "meta": { - "type": "swagger-error-codes", - "agent": "@doc-generator", - "tool": "gemini" - }, - "context": { - "requirements": [ - "Define unified error response format", - "Create categorized error code system (auth, business, system)", - "Provide detailed description and examples for each error code" - ] - }, - "flow_control": { - "implementation_approach": [ - { - "step": 1, - "title": "Generate error code specification document", - "cli_prompt": "PURPOSE: Generate comprehensive error code specification for consistent API error handling\nTASK:\n• Define error response format: {code, message, details, timestamp}\n• Document authentication errors (AUTH_xxx): 401/403 series\n• Document parameter errors (PARAM_xxx): 400 series\n• Document business errors (BIZ_xxx): business logic errors\n• Document system errors (SYS_xxx): 500 series\n• For each error code: HTTP status, error message, possible causes, resolution suggestions\nMODE: write\nCONTEXT: @src/**/*.exception.ts @src/**/*.filter.ts\nEXPECTED: Complete error code specification in {lang} with tables and examples\nCONSTRAINTS: Include response examples | Clear categorization\n--rule development-feature", - "output": "{error_doc_name}" - } - ], - "target_files": [ - ".workflow/docs/${project_name}/api/{overview_dir}/{error_doc_name}" - ] - } -} -``` - -### Level 2: Module API Documentation (Template) - -```json -{ - "id": "IMPL-${module_task_id}", - "title": "Generate ${module_name} API documentation", - "status": "pending", - "depends_on": ["IMPL-001", "IMPL-002", "IMPL-003"], - "meta": { - "type": "swagger-module-doc", - "agent": "@doc-generator", - "tool": "gemini", - "module": "${module_name}", - "endpoint_count": "${endpoint_count}" - }, - "context": { - "requirements": [ - "Complete documentation for all endpoints in this module", - "Each endpoint: description, method, URL, parameters, responses", - "Include success and failure response examples", - "Mark API version and last update time" - ], - "focus_paths": ["${module_source_paths}"] - }, - "flow_control": { - "pre_analysis": [ - { - "step": "load_module_endpoints", - "action": "Load module endpoint information", - "commands": [ - "bash(cat ${session_dir}/.process/swagger-planning-data.json | jq '.api_structure.modules[] | select(.name == \"${module_name}\")')" - ], - "output_to": "module_endpoints" - }, - { - "step": "read_source_files", - "action": "Read module source files", - "commands": [ - "bash(cat ${module_source_files})" - ], - "output_to": "source_code" - } - ], - "implementation_approach": [ - { - "step": 1, - "title": "Generate module API documentation", - "description": "Generate complete API documentation for ${module_name}", - "cli_prompt": "PURPOSE: Generate complete RESTful API documentation for ${module_name} module\nTASK:\n• Create module overview: purpose, use cases, prerequisites\n• Generate endpoint index: grouped by functionality\n• For each endpoint document:\n - Functional description: purpose and business context\n - Request method: GET/POST/PUT/DELETE\n - URL path: complete API path\n - Request headers: Authorization and other required headers\n - Path parameters: {id} and other path variables\n - Query parameters: pagination, filters, etc.\n - Request body: JSON Schema format\n - Response body: success and error responses\n - Field description table: type, required, example, description\n• Add usage examples: cURL, JavaScript, Python\n• Add version info: v1.0.0, last updated date\nMODE: write\nCONTEXT: @[module_endpoints] @[source_code]\nEXPECTED: Complete module API documentation in {lang} with all endpoints fully documented\nCONSTRAINTS: RESTful standards | Include all response codes\n--rule documentation-swagger-api", - "output": "${module_doc_name}" - } - ], - "target_files": [ - ".workflow/docs/${project_name}/api/${module_dir}/${module_doc_name}" - ] - } -} -``` - -### Level 3: API Overview and Navigation - -```json -{ - "id": "IMPL-${overview_task_id}", - "title": "Generate API overview and navigation", - "status": "pending", - "depends_on": ["IMPL-001", "...", "IMPL-${last_module_task_id}"], - "meta": { - "type": "swagger-overview", - "agent": "@doc-generator", - "tool": "gemini" - }, - "flow_control": { - "pre_analysis": [ - { - "step": "load_all_docs", - "command": "bash(find .workflow/docs/${project_name}/api -type f -name '*.md' ! -path '*/{overview_dir}/*' | xargs cat)", - "output_to": "all_module_docs" - } - ], - "implementation_approach": [ - { - "step": 1, - "title": "Generate API overview", - "cli_prompt": "PURPOSE: Generate API overview document with navigation and quick start guide\nTASK:\n• Create introduction: system features, tech stack, version\n• Write quick start guide: authentication, first request example\n• Build module navigation: categorized links to all modules\n• Document environment configuration: development, staging, production\n• List SDKs and tools: client libraries, Postman collection\nMODE: write\nCONTEXT: @[all_module_docs] @.workflow/docs/${project_name}/api/swagger.yaml\nEXPECTED: Complete API overview in {lang} with navigation links\nCONSTRAINTS: Clear structure | Quick start focus\n--rule development-feature", - "output": "README.md" - } - ], - "target_files": [ - ".workflow/docs/${project_name}/api/{overview_dir}/README.md" - ] - } -} -``` - -### Level 4: Validation Tasks - -```json -{ - "id": "IMPL-${test_task_id}", - "title": "API endpoint validation tests", - "status": "pending", - "depends_on": ["IMPL-${overview_task_id}"], - "meta": { - "type": "swagger-validation", - "agent": "@test-fix-agent", - "tool": "codex" - }, - "context": { - "requirements": [ - "Validate accessibility of all endpoints", - "Test various boundary conditions", - "Verify exception handling" - ] - }, - "flow_control": { - "pre_analysis": [ - { - "step": "load_swagger_spec", - "command": "bash(cat .workflow/docs/${project_name}/api/swagger.yaml)", - "output_to": "swagger_spec" - } - ], - "implementation_approach": [ - { - "step": 1, - "title": "Generate test report", - "cli_prompt": "PURPOSE: Generate comprehensive API test validation report\nTASK:\n• Document test environment configuration\n• Calculate endpoint coverage statistics\n• Report test results: pass/fail counts\n• Document boundary tests: parameter limits, null values, special characters\n• Document exception tests: auth failures, permission denied, resource not found\n• List issues found with recommendations\nMODE: write\nCONTEXT: @[swagger_spec]\nEXPECTED: Complete test report in {lang} with detailed results\nCONSTRAINTS: Include test cases | Clear pass/fail status\n--rule development-tests", - "output": "{test_doc_name}" - } - ], - "target_files": [ - ".workflow/docs/${project_name}/api/{test_dir}/{test_doc_name}" - ] - } -} -``` - -## Language-Specific Directory Mapping - -| Component | --lang zh | --lang en | -|-----------|-----------|-----------| -| Overview dir | 概述 | overview | -| Auth doc | 认证说明.md | authentication.md | -| Error doc | 错误码规范.md | error-codes.md | -| Changelog | 版本历史.md | changelog.md | -| Users module | 用户模块 | users | -| Orders module | 订单模块 | orders | -| Products module | 商品模块 | products | -| Test dir | 测试报告 | test-reports | -| API test doc | 接口测试.md | api-tests.md | -| Boundary test doc | 边界测试.md | boundary-tests.md | - -## API Documentation Template - -### Single Endpoint Format - -Each endpoint must include: - -```markdown -### Get User Details - -**Description**: Retrieve detailed user information by ID, including profile and permissions. - -**Endpoint Info**: - -| Property | Value | -|----------|-------| -| Method | GET | -| URL | `/api/v1/users/{id}` | -| Version | v1.0.0 | -| Updated | 2025-01-01 | -| Auth | Bearer Token | -| Permission | user / admin | - -**Request Headers**: - -| Field | Type | Required | Example | Description | -|-------|------|----------|---------|-------------| -| Authorization | string | Yes | `Bearer eyJhbGc...` | JWT Token | -| Content-Type | string | No | `application/json` | Request content type | - -**Path Parameters**: - -| Field | Type | Required | Example | Description | -|-------|------|----------|---------|-------------| -| id | string | Yes | `usr_123456` | Unique user identifier | - -**Query Parameters**: - -| Field | Type | Required | Default | Example | Description | -|-------|------|----------|---------|---------|-------------| -| include | string | No | - | `roles,permissions` | Related data to include | - -**Success Response** (200 OK): - -```json -{ - "code": 0, - "message": "success", - "data": { - "id": "usr_123456", - "email": "user@example.com", - "name": "John Doe", - "status": "active", - "roles": ["user"], - "created_at": "2025-01-01T00:00:00Z", - "updated_at": "2025-01-01T00:00:00Z" - }, - "timestamp": "2025-01-01T12:00:00Z" -} -``` - -**Response Fields**: - -| Field | Type | Description | -|-------|------|-------------| -| code | integer | Business status code, 0 = success | -| message | string | Response message | -| data.id | string | Unique user identifier | -| data.email | string | User email address | -| data.name | string | User display name | -| data.status | string | User status: active/inactive/suspended | -| data.roles | array | User role list | -| data.created_at | string | Creation timestamp (ISO 8601) | -| data.updated_at | string | Last update timestamp (ISO 8601) | - -**Error Responses**: - -| Status | Code | Message | Possible Cause | -|--------|------|---------|----------------| -| 401 | AUTH_001 | Invalid or expired token | Token format error or expired | -| 403 | AUTH_003 | Insufficient permissions | No access to this user info | -| 404 | USER_001 | User not found | User ID doesn't exist or deleted | - -**Examples**: - -```bash -# cURL -curl -X GET "https://api.example.com/api/v1/users/usr_123456" \ - -H "Authorization: Bearer eyJhbGc..." \ - -H "Content-Type: application/json" -``` - -```javascript -// JavaScript (fetch) -const response = await fetch('https://api.example.com/api/v1/users/usr_123456', { - method: 'GET', - headers: { - 'Authorization': 'Bearer eyJhbGc...', - 'Content-Type': 'application/json' - } -}); -const data = await response.json(); -``` -``` - -## Session Structure - -``` -.workflow/active/ -└── WFS-swagger-{timestamp}/ - ├── workflow-session.json - ├── IMPL_PLAN.md - ├── TODO_LIST.md - ├── .process/ - │ └── swagger-planning-data.json - └── .task/ - ├── IMPL-001.json # OpenAPI spec - ├── IMPL-002.json # Security config - ├── IMPL-003.json # Error codes - ├── IMPL-004.json # Module 1 API - ├── ... - ├── IMPL-N+1.json # API overview - └── IMPL-N+2.json # Validation tests -``` - -## Execution Commands - -```bash -# Execute entire workflow -/workflow:execute - -# Specify session -/workflow:execute --resume-session="WFS-swagger-yyyymmdd-hhmmss" - -# Single task execution -/task:execute IMPL-001 -``` - -## Related Commands - -- `/workflow:execute` - Execute documentation tasks -- `/workflow:status` - View task progress -- `/workflow:session:complete` - Mark session complete -- `/memory:docs` - General documentation workflow diff --git a/.claude/commands/memory/tech-research-rules.md b/.claude/commands/memory/tech-research-rules.md deleted file mode 100644 index 285f4f2a..00000000 --- a/.claude/commands/memory/tech-research-rules.md +++ /dev/null @@ -1,310 +0,0 @@ ---- -name: tech-research-rules -description: "3-phase orchestrator: extract tech stack → Exa research → generate path-conditional rules (auto-loaded by Claude Code)" -argument-hint: "[session-id | tech-stack-name] [--regenerate] [--tool ]" -allowed-tools: SlashCommand(*), TodoWrite(*), Bash(*), Read(*), Write(*), Task(*) ---- - -# Tech Stack Rules Generator - -## Overview - -**Purpose**: Generate multi-layered, path-conditional rules that Claude Code automatically loads based on file context. - -**Output Structure**: -``` -.claude/rules/tech/{tech-stack}/ -├── core.md # paths: **/*.{ext} - Core principles -├── patterns.md # paths: src/**/*.{ext} - Implementation patterns -├── testing.md # paths: **/*.{test,spec}.{ext} - Testing rules -├── config.md # paths: *.config.* - Configuration rules -├── api.md # paths: **/api/**/* - API rules (backend only) -├── components.md # paths: **/components/**/* - Component rules (frontend only) -└── metadata.json # Generation metadata -``` - -**Templates Location**: `~/.claude/workflows/cli-templates/prompts/rules/` - ---- - -## Core Rules - -1. **Start Immediately**: First action is TodoWrite initialization -2. **Path-Conditional Output**: Every rule file includes `paths` frontmatter -3. **Template-Driven**: Agent reads templates before generating content -4. **Agent Produces Files**: Agent writes all rule files directly -5. **No Manual Loading**: Rules auto-activate when Claude works with matching files - ---- - -## 3-Phase Execution - -### Phase 1: Prepare Context & Detect Tech Stack - -**Goal**: Detect input mode, extract tech stack info, determine file extensions - -**Input Mode Detection**: -```bash -input="$1" - -if [[ "$input" == WFS-* ]]; then - MODE="session" - SESSION_ID="$input" - # Read workflow-session.json to extract tech stack -else - MODE="direct" - TECH_STACK_NAME="$input" -fi -``` - -**Tech Stack Analysis**: -```javascript -// Decompose composite tech stacks -// "typescript-react-nextjs" → ["typescript", "react", "nextjs"] - -const TECH_EXTENSIONS = { - "typescript": "{ts,tsx}", - "javascript": "{js,jsx}", - "python": "py", - "rust": "rs", - "go": "go", - "java": "java", - "csharp": "cs", - "ruby": "rb", - "php": "php" -}; - -const FRAMEWORK_TYPE = { - "react": "frontend", - "vue": "frontend", - "angular": "frontend", - "nextjs": "fullstack", - "nuxt": "fullstack", - "fastapi": "backend", - "express": "backend", - "django": "backend", - "rails": "backend" -}; -``` - -**Check Existing Rules**: -```bash -normalized_name=$(echo "$TECH_STACK_NAME" | tr '[:upper:]' '[:lower:]' | tr ' ' '-') -rules_dir=".claude/rules/tech/${normalized_name}" -existing_count=$(find "${rules_dir}" -name "*.md" 2>/dev/null | wc -l || echo 0) -``` - -**Skip Decision**: -- If `existing_count > 0` AND no `--regenerate` → `SKIP_GENERATION = true` -- If `--regenerate` → Delete existing and regenerate - -**Output Variables**: -- `TECH_STACK_NAME`: Normalized name -- `PRIMARY_LANG`: Primary language -- `FILE_EXT`: File extension pattern -- `FRAMEWORK_TYPE`: frontend | backend | fullstack | library -- `COMPONENTS`: Array of tech components -- `SKIP_GENERATION`: Boolean - -**TodoWrite**: Mark phase 1 completed - ---- - -### Phase 2: Agent Produces Path-Conditional Rules - -**Skip Condition**: Skipped if `SKIP_GENERATION = true` - -**Goal**: Delegate to agent for Exa research and rule file generation - -**Template Files**: -``` -~/.claude/workflows/cli-templates/prompts/rules/ -├── tech-rules-agent-prompt.txt # Agent instructions -├── rule-core.txt # Core principles template -├── rule-patterns.txt # Implementation patterns template -├── rule-testing.txt # Testing rules template -├── rule-config.txt # Configuration rules template -├── rule-api.txt # API rules template (backend) -└── rule-components.txt # Component rules template (frontend) -``` - -**Agent Task**: - -```javascript -Task({ - subagent_type: "general-purpose", - description: `Generate tech stack rules: ${TECH_STACK_NAME}`, - prompt: ` -You are generating path-conditional rules for Claude Code. - -## Context -- Tech Stack: ${TECH_STACK_NAME} -- Primary Language: ${PRIMARY_LANG} -- File Extensions: ${FILE_EXT} -- Framework Type: ${FRAMEWORK_TYPE} -- Components: ${JSON.stringify(COMPONENTS)} -- Output Directory: .claude/rules/tech/${TECH_STACK_NAME}/ - -## Instructions - -Read the agent prompt template for detailed instructions. -Use --rule rules-tech-rules-agent-prompt to load the template automatically. - -## Execution Steps - -1. Execute Exa research queries (see agent prompt) -2. Read each rule template -3. Generate rule files following template structure -4. Write files to output directory -5. Write metadata.json -6. Report completion - -## Variable Substitutions - -Replace in templates: -- {TECH_STACK_NAME} → ${TECH_STACK_NAME} -- {PRIMARY_LANG} → ${PRIMARY_LANG} -- {FILE_EXT} → ${FILE_EXT} -- {FRAMEWORK_TYPE} → ${FRAMEWORK_TYPE} -` -}) -``` - -**Completion Criteria**: -- 4-6 rule files written with proper `paths` frontmatter -- metadata.json written -- Agent reports files created - -**TodoWrite**: Mark phase 2 completed - ---- - -### Phase 3: Verify & Report - -**Goal**: Verify generated files and provide usage summary - -**Steps**: - -1. **Verify Files**: - ```bash - find ".claude/rules/tech/${TECH_STACK_NAME}" -name "*.md" -type f - ``` - -2. **Validate Frontmatter**: - ```bash - head -5 ".claude/rules/tech/${TECH_STACK_NAME}/core.md" - ``` - -3. **Read Metadata**: - ```javascript - Read(`.claude/rules/tech/${TECH_STACK_NAME}/metadata.json`) - ``` - -4. **Generate Summary Report**: - ``` - Tech Stack Rules Generated - - Tech Stack: {TECH_STACK_NAME} - Location: .claude/rules/tech/{TECH_STACK_NAME}/ - - Files Created: - ├── core.md → paths: **/*.{ext} - ├── patterns.md → paths: src/**/*.{ext} - ├── testing.md → paths: **/*.{test,spec}.{ext} - ├── config.md → paths: *.config.* - ├── api.md → paths: **/api/**/* (if backend) - └── components.md → paths: **/components/**/* (if frontend) - - Auto-Loading: - - Rules apply automatically when editing matching files - - No manual loading required - - Example Activation: - - Edit src/components/Button.tsx → core.md + patterns.md + components.md - - Edit tests/api.test.ts → core.md + testing.md - - Edit package.json → config.md - ``` - -**TodoWrite**: Mark phase 3 completed - ---- - -## Path Pattern Reference - -| Pattern | Matches | -|---------|---------| -| `**/*.ts` | All .ts files | -| `src/**/*` | All files under src/ | -| `*.config.*` | Config files in root | -| `**/*.{ts,tsx}` | .ts and .tsx files | - -| Tech Stack | Core Pattern | Test Pattern | -|------------|--------------|--------------| -| TypeScript | `**/*.{ts,tsx}` | `**/*.{test,spec}.{ts,tsx}` | -| Python | `**/*.py` | `**/test_*.py, **/*_test.py` | -| Rust | `**/*.rs` | `**/tests/**/*.rs` | -| Go | `**/*.go` | `**/*_test.go` | - ---- - -## Parameters - -```bash -/memory:tech-research [session-id | "tech-stack-name"] [--regenerate] -``` - -**Arguments**: -- **session-id**: `WFS-*` format - Extract from workflow session -- **tech-stack-name**: Direct input - `"typescript"`, `"typescript-react"` -- **--regenerate**: Force regenerate existing rules - ---- - -## Examples - -### Single Language - -```bash -/memory:tech-research "typescript" -``` - -**Output**: `.claude/rules/tech/typescript/` with 4 rule files - -### Frontend Stack - -```bash -/memory:tech-research "typescript-react" -``` - -**Output**: `.claude/rules/tech/typescript-react/` with 5 rule files (includes components.md) - -### Backend Stack - -```bash -/memory:tech-research "python-fastapi" -``` - -**Output**: `.claude/rules/tech/python-fastapi/` with 5 rule files (includes api.md) - -### From Session - -```bash -/memory:tech-research WFS-user-auth-20251104 -``` - -**Workflow**: Extract tech stack from session → Generate rules - ---- - -## Comparison: Rules vs SKILL - -| Aspect | SKILL Memory | Rules | -|--------|--------------|-------| -| Loading | Manual: `Skill("tech")` | Automatic by path | -| Scope | All files when loaded | Only matching files | -| Granularity | Monolithic packages | Per-file-type | -| Context | Full package | Only relevant rules | - -**When to Use**: -- **Rules**: Tech stack conventions per file type -- **SKILL**: Reference docs, APIs, examples for manual lookup diff --git a/.claude/commands/memory/tips.md b/.claude/commands/memory/tips.md new file mode 100644 index 00000000..52082a81 --- /dev/null +++ b/.claude/commands/memory/tips.md @@ -0,0 +1,332 @@ +--- +name: tips +description: Quick note-taking command to capture ideas, snippets, reminders, and insights for later reference +argument-hint: " [--tag ] [--context ]" +allowed-tools: mcp__ccw-tools__core_memory(*), Read(*) +examples: + - /memory:tips "Remember to use Redis for rate limiting" + - /memory:tips "Auth pattern: JWT with refresh tokens" --tag architecture,auth + - /memory:tips "Bug: memory leak in WebSocket handler after 24h" --context websocket-service + - /memory:tips "Performance: lazy loading reduced bundle by 40%" --tag performance +--- + +# Memory Tips Command (/memory:tips) + +## 1. Overview + +The `memory:tips` command provides **quick note-taking** for capturing: +- Quick ideas and insights +- Code snippets and patterns +- Reminders and follow-ups +- Bug notes and debugging hints +- Performance observations +- Architecture decisions +- Library/tool recommendations + +**Core Philosophy**: +- **Speed First**: Minimal friction for capturing thoughts +- **Searchable**: Tagged for easy retrieval +- **Context-Aware**: Optional context linking +- **Lightweight**: No complex session analysis + +## 2. Parameters + +- `` (Required): The tip/note content to save +- `--tag ` (Optional): Comma-separated tags for categorization +- `--context ` (Optional): Related context (file, module, feature) + +**Examples**: +```bash +/memory:tips "Use Zod for runtime validation - better DX than class-validator" +/memory:tips "Redis connection pool: max 10, min 2" --tag config,redis +/memory:tips "Fix needed: race condition in payment processor" --tag bug,payment --context src/payments +``` + +## 3. Structured Output Format + +```markdown +## Tip ID +TIP-YYYYMMDD-HHMMSS + +## Timestamp +YYYY-MM-DD HH:MM:SS + +## Project Root +[Absolute path to project root, e.g., D:\Claude_dms3] + +## Content +[The tip/note content exactly as provided] + +## Tags +[Comma-separated tags, or (none)] + +## Context +[Optional context linking - file, module, or feature reference] + +## Session Link +[WFS-ID if workflow session active, otherwise (none)] + +## Auto-Detected Context +[Files/topics from current conversation if relevant] +``` + +## 4. Field Definitions + +| Field | Purpose | Example | +|-------|---------|---------| +| **Tip ID** | Unique identifier with timestamp | TIP-20260128-143052 | +| **Timestamp** | When tip was created | 2026-01-28 14:30:52 | +| **Project Root** | Current project path | D:\Claude_dms3 | +| **Content** | The actual tip/note | "Use Redis for rate limiting" | +| **Tags** | Categorization labels | architecture, auth, performance | +| **Context** | Related code/feature | src/auth/**, payment-module | +| **Session Link** | Link to workflow session | WFS-auth-20260128 | +| **Auto-Detected Context** | Files from conversation | src/api/handler.ts | + +## 5. Execution Flow + +### Step 1: Parse Arguments + +```javascript +const parseTipsCommand = (input) => { + // Extract note content (everything before flags) + const contentMatch = input.match(/^"([^"]+)"|^([^\s-]+)/); + const content = contentMatch ? (contentMatch[1] || contentMatch[2]) : ''; + + // Extract tags + const tagsMatch = input.match(/--tag\s+([^\s-]+)/); + const tags = tagsMatch ? tagsMatch[1].split(',').map(t => t.trim()) : []; + + // Extract context + const contextMatch = input.match(/--context\s+([^\s-]+)/); + const context = contextMatch ? contextMatch[1] : ''; + + return { content, tags, context }; +}; +``` + +### Step 2: Gather Context + +```javascript +const gatherTipContext = async () => { + // Get project root + const projectRoot = process.cwd(); // or detect from environment + + // Get current session if active + const manifest = await mcp__ccw-tools__session_manager({ + operation: "list", + location: "active" + }); + const sessionId = manifest.sessions?.[0]?.id || null; + + // Auto-detect files from recent conversation + const recentFiles = extractRecentFilesFromConversation(); // Last 5 messages + + return { + projectRoot, + sessionId, + autoDetectedContext: recentFiles + }; +}; +``` + +### Step 3: Generate Structured Text + +```javascript +const generateTipText = (parsed, context) => { + const timestamp = new Date().toISOString().replace('T', ' ').slice(0, 19); + const tipId = `TIP-${new Date().toISOString().slice(0,10).replace(/-/g, '')}-${new Date().toTimeString().slice(0,8).replace(/:/g, '')}`; + + return `## Tip ID +${tipId} + +## Timestamp +${timestamp} + +## Project Root +${context.projectRoot} + +## Content +${parsed.content} + +## Tags +${parsed.tags.length > 0 ? parsed.tags.join(', ') : '(none)'} + +## Context +${parsed.context || '(none)'} + +## Session Link +${context.sessionId || '(none)'} + +## Auto-Detected Context +${context.autoDetectedContext.length > 0 + ? context.autoDetectedContext.map(f => `- ${f}`).join('\n') + : '(none)'}`; +}; +``` + +### Step 4: Save to Core Memory + +```javascript +mcp__ccw-tools__core_memory({ + operation: "import", + text: structuredText +}) +``` + +**Response Format**: +```json +{ + "operation": "import", + "id": "CMEM-YYYYMMDD-HHMMSS", + "message": "Created memory: CMEM-YYYYMMDD-HHMMSS" +} +``` + +### Step 5: Confirm to User + +``` +✓ Tip saved successfully + + ID: CMEM-YYYYMMDD-HHMMSS + Tags: architecture, auth + Context: src/auth/** + + To retrieve: /memory:search "auth patterns" + Or via MCP: core_memory(operation="search", query="auth") +``` + +## 6. Tag Categories (Suggested) + +**Technical**: +- `architecture` - Design decisions and patterns +- `performance` - Optimization insights +- `security` - Security considerations +- `bug` - Bug notes and fixes +- `config` - Configuration settings +- `api` - API design patterns + +**Development**: +- `testing` - Test strategies and patterns +- `debugging` - Debugging techniques +- `refactoring` - Refactoring notes +- `documentation` - Doc improvements + +**Domain Specific**: +- `auth` - Authentication/authorization +- `database` - Database patterns +- `frontend` - UI/UX patterns +- `backend` - Backend logic +- `devops` - Infrastructure and deployment + +**Organizational**: +- `reminder` - Follow-up items +- `research` - Research findings +- `idea` - Feature ideas +- `review` - Code review notes + +## 7. Search Integration + +Tips can be retrieved using: + +```bash +# Via command (if /memory:search exists) +/memory:search "rate limiting" + +# Via MCP tool +mcp__ccw-tools__core_memory({ + operation: "search", + query: "rate limiting", + source_type: "core_memory", + top_k: 10 +}) + +# Via CLI +ccw core-memory search --query "rate limiting" --top-k 10 +``` + +## 8. Quality Checklist + +Before saving: +- [ ] Content is clear and actionable +- [ ] Tags are relevant and consistent +- [ ] Context provides enough reference +- [ ] Auto-detected context is accurate +- [ ] Project root is absolute path +- [ ] Timestamp is properly formatted + +## 9. Best Practices + +### Good Tips Examples + +✅ **Specific and Actionable**: +``` +"Use connection pooling for Redis: { max: 10, min: 2, acquireTimeoutMillis: 30000 }" +--tag config,redis +``` + +✅ **With Context**: +``` +"Auth middleware must validate both access and refresh tokens" +--tag security,auth --context src/middleware/auth.ts +``` + +✅ **Problem + Solution**: +``` +"Memory leak fixed by unsubscribing event listeners in componentWillUnmount" +--tag bug,react --context src/components/Chat.tsx +``` + +### Poor Tips Examples + +❌ **Too Vague**: +``` +"Fix the bug" --tag bug +``` + +❌ **Too Long** (use /memory:compact instead): +``` +"Here's the complete implementation plan for the entire auth system... [3 paragraphs]" +``` + +❌ **No Context**: +``` +"Remember to update this later" +``` + +## 10. Use Cases + +### During Development +```bash +/memory:tips "JWT secret must be 256-bit minimum" --tag security,auth +/memory:tips "Use debounce (300ms) for search input" --tag performance,ux +``` + +### After Bug Fixes +```bash +/memory:tips "Race condition in payment: lock with Redis SETNX" --tag bug,payment +``` + +### Code Review Insights +```bash +/memory:tips "Prefer early returns over nested ifs" --tag style,readability +``` + +### Architecture Decisions +```bash +/memory:tips "Chose PostgreSQL over MongoDB for ACID compliance" --tag architecture,database +``` + +### Library Recommendations +```bash +/memory:tips "Zod > Yup for TypeScript validation - better type inference" --tag library,typescript +``` + +## 11. Notes + +- **Frequency**: Use liberally - capture all valuable insights +- **Retrieval**: Search by tags, content, or context +- **Lifecycle**: Tips persist across sessions +- **Organization**: Tags enable filtering and categorization +- **Integration**: Can reference tips in later workflows +- **Lightweight**: No complex session analysis required diff --git a/.claude/commands/memory/workflow-skill-memory.md b/.claude/commands/memory/workflow-skill-memory.md deleted file mode 100644 index ac483717..00000000 --- a/.claude/commands/memory/workflow-skill-memory.md +++ /dev/null @@ -1,517 +0,0 @@ ---- -name: workflow-skill-memory -description: Process WFS-* archived sessions using universal-executor agents with Gemini analysis to generate workflow-progress SKILL package (sessions-timeline, lessons, conflicts) -argument-hint: "session | all" -allowed-tools: Task(*), TodoWrite(*), Bash(*), Read(*), Write(*) ---- - -# Workflow SKILL Memory Generator - -## Overview - -Generate SKILL package from archived workflow sessions using agent-driven analysis. Supports single-session incremental updates or parallel processing of all sessions. - -**Scope**: Only processes WFS-* workflow sessions. Other session types (e.g., doc sessions) are automatically ignored. - -## Usage - -```bash -/memory:workflow-skill-memory session WFS- # Process single WFS session -/memory:workflow-skill-memory all # Process all WFS sessions in parallel -``` - -## Execution Modes - -### Mode 1: Single Session (`session `) - -**Purpose**: Incremental update - process one archived session and merge into existing SKILL package - -**Workflow**: -1. **Validate session**: Check if session exists in `.workflow/.archives/{session-id}/` -2. **Invoke agent**: Call `universal-executor` to analyze session and update SKILL documents -3. **Agent tasks**: - - Read session data from `.workflow/.archives/{session-id}/` - - Extract lessons, conflicts, and outcomes - - Use Gemini for intelligent aggregation (optional) - - Update or create SKILL documents using templates - - Regenerate SKILL.md index - -**Command Example**: -```bash -/memory:workflow-skill-memory session WFS-user-auth -``` - -**Expected Output**: -``` -Session WFS-user-auth processed -Updated: -- sessions-timeline.md (1 session added) -- lessons-learned.md (3 lessons merged) -- conflict-patterns.md (1 conflict added) -- SKILL.md (index regenerated) -``` - ---- - -### Mode 2: All Sessions (`all`) - -**Purpose**: Full regeneration - process all archived sessions in parallel for complete SKILL package - -**Workflow**: -1. **List sessions**: Read manifest.json to get all archived session IDs -2. **Parallel invocation**: Launch multiple `universal-executor` agents in parallel (one per session) -3. **Agent coordination**: - - Each agent processes one session independently - - Agents use Gemini for analysis - - Agents collect data into JSON (no direct file writes) - - Final aggregator agent merges results and generates SKILL documents - -**Command Example**: -```bash -/memory:workflow-skill-memory all -``` - -**Expected Output**: -``` -All sessions processed in parallel -Sessions: 8 total -Updated: -- sessions-timeline.md (8 sessions) -- lessons-learned.md (24 lessons aggregated) -- conflict-patterns.md (12 conflicts documented) -- SKILL.md (index regenerated) -``` - ---- - -## Implementation Flow - -### Phase 1: Validation and Setup - -**Step 1.1: Parse Command Arguments** - -Extract mode and session ID: -```javascript -if (args === "all") { - mode = "all" -} else if (args.startsWith("session ")) { - mode = "session" - session_id = args.replace("session ", "").trim() -} else { - ERROR = "Invalid arguments. Usage: session | all" - EXIT -} -``` - -**Step 1.2: Validate Archive Directory** -```bash -bash(test -d .workflow/.archives && echo "exists" || echo "missing") -``` - -If missing, report error and exit. - -**Step 1.3: Mode-Specific Validation** - -**Single Session Mode**: -```bash -# Validate session ID format (must start with WFS-) -if [[ ! "$session_id" =~ ^WFS- ]]; then - ERROR = "Invalid session ID format. Only WFS-* sessions are supported" - EXIT -fi - -# Check if session exists -bash(test -d .workflow/.archives/{session_id} && echo "exists" || echo "missing") -``` - -If missing, report error: "Session {session_id} not found in archives" - -**All Sessions Mode**: -```bash -# Read manifest and filter only WFS- sessions -bash(cat .workflow/.archives/manifest.json | jq -r '.archives[].session_id | select(startswith("WFS-"))') -``` - -Store filtered session IDs in array. Ignore doc sessions and other non-WFS sessions. - -**Step 1.4: TodoWrite Initialization** - -**Single Session Mode**: -```javascript -TodoWrite({todos: [ - {"content": "Validate session existence", "status": "completed", "activeForm": "Validating session"}, - {"content": "Invoke agent to process session", "status": "in_progress", "activeForm": "Invoking agent"}, - {"content": "Verify SKILL package updated", "status": "pending", "activeForm": "Verifying update"} -]}) -``` - -**All Sessions Mode**: -```javascript -TodoWrite({todos: [ - {"content": "Read manifest and list sessions", "status": "completed", "activeForm": "Reading manifest"}, - {"content": "Invoke agents in parallel", "status": "in_progress", "activeForm": "Invoking agents"}, - {"content": "Verify SKILL package regenerated", "status": "pending", "activeForm": "Verifying regeneration"} -]}) -``` - ---- - -### Phase 2: Agent Invocation - -#### Single Session Mode - Agent Task - -Invoke `universal-executor` with session-specific task: - -**Agent Prompt Structure**: -``` -Task: Process Workflow Session for SKILL Package - -Context: -- Session ID: {session_id} -- Session Path: .workflow/.archives/{session_id}/ -- Mode: Incremental update - -Objectives: - -1. Read session data: - - workflow-session.json (metadata) - - IMPL_PLAN.md (implementation summary) - - TODO_LIST.md (if exists) - - manifest.json entry for lessons - -2. Extract key information: - - Description, tags, metrics - - Lessons (successes, challenges, watch_patterns) - - Context package path (reference only) - - Key outcomes from IMPL_PLAN - -3. Use Gemini for aggregation (optional): - Command pattern: - ccw cli -p " - PURPOSE: Extract lessons and conflicts from workflow session - TASK: - • Analyze IMPL_PLAN and lessons from manifest - • Identify success patterns and challenges - • Extract conflict patterns with resolutions - • Categorize by functional domain - MODE: analysis - CONTEXT: @IMPL_PLAN.md @workflow-session.json - EXPECTED: Structured lessons and conflicts in JSON format - RULES: Template reference from skill-aggregation.txt - " --tool gemini --mode analysis --cd .workflow/.archives/{session_id} - -3.5. **Generate SKILL.md Description** (CRITICAL for auto-loading): - - Read skill-index.txt template Section: "Description Field Generation" - - Execute command to get project root: - ```bash - git rev-parse --show-toplevel # Example output: /d/Claude_dms3 - ``` - - Apply description format: - ``` - Progressive workflow development history (located at {project_root}). - Load this SKILL when continuing development, analyzing past implementations, - or learning from workflow history, especially when no relevant context exists in memory. - ``` - - **Validation**: - - [ ] Path uses forward slashes (not backslashes) - - [ ] All three use cases present - - [ ] Trigger optimization phrase included - - [ ] Path is absolute (starts with / or drive letter) - -4. Read templates for formatting guidance: - - ~/.claude/workflows/cli-templates/prompts/workflow/skill-sessions-timeline.txt - - ~/.claude/workflows/cli-templates/prompts/workflow/skill-lessons-learned.txt - - ~/.claude/workflows/cli-templates/prompts/workflow/skill-conflict-patterns.txt - - ~/.claude/workflows/cli-templates/prompts/workflow/skill-index.txt - - **CRITICAL**: From skill-index.txt, read these sections: - - "Description Field Generation" - Rules for generating description - - "Variable Substitution Guide" - All required variables - - "Generation Instructions" - Step-by-step generation process - - "Validation Checklist" - Final validation steps - -5. Update SKILL documents: - - sessions-timeline.md: Append new session, update domain grouping - - lessons-learned.md: Merge lessons into categories, update frequencies - - conflict-patterns.md: Add conflicts, update recurring pattern frequencies - - SKILL.md: Regenerate index with updated counts - - **For SKILL.md generation**: - - Follow "Generation Instructions" from skill-index.txt (Steps 1-7) - - Use git command for project_root: `git rev-parse --show-toplevel` - - Apply "Description Field Generation" rules - - Validate using "Validation Checklist" - - Increment version (patch level) - -6. Return result JSON: - { - "status": "success", - "session_id": "{session_id}", - "updates": { - "sessions_added": 1, - "lessons_merged": count, - "conflicts_added": count - } - } -``` - ---- - -#### All Sessions Mode - Parallel Agent Tasks - -**Step 2.1: Launch parallel session analyzers** - -Invoke multiple agents in parallel (one message with multiple Task calls): - -**Per-Session Agent Prompt**: -``` -Task: Extract Session Data for SKILL Package - -Context: -- Session ID: {session_id} -- Mode: Parallel analysis (no direct file writes) - -Objectives: - -1. Read session data (same as single mode) - -2. Extract key information (same as single mode) - -3. Use Gemini for analysis (same as single mode) - -4. Return structured data JSON: - { - "status": "success", - "session_id": "{session_id}", - "data": { - "metadata": { - "description": "...", - "archived_at": "...", - "tags": [...], - "metrics": {...} - }, - "lessons": { - "successes": [...], - "challenges": [...], - "watch_patterns": [...] - }, - "conflicts": [ - { - "type": "architecture|dependencies|testing|performance", - "pattern": "...", - "resolution": "...", - "code_impact": [...] - } - ], - "impl_summary": "First 200 chars of IMPL_PLAN", - "context_package_path": "..." - } - } -``` - -**Step 2.2: Aggregate results** - -After all session agents complete, invoke aggregator agent: - -**Aggregator Agent Prompt**: -``` -Task: Aggregate Session Results and Generate SKILL Package - -Context: -- Mode: Full regeneration -- Input: JSON results from {session_count} session agents - -Objectives: - -1. Aggregate all session data: - - Collect metadata from all sessions - - Merge lessons by category - - Group conflicts by type - - Sort sessions by date - -2. Use Gemini for final aggregation: - ccw cli -p " - PURPOSE: Aggregate lessons and conflicts from all workflow sessions - TASK: - • Group successes by functional domain - • Categorize challenges by severity (HIGH/MEDIUM/LOW) - • Identify recurring conflict patterns - • Calculate frequencies and prioritize - MODE: analysis - CONTEXT: [Provide aggregated JSON data] - EXPECTED: Final aggregated structure for SKILL documents - RULES: Template reference from skill-aggregation.txt - " --tool gemini --mode analysis - -3. Read templates for formatting (same 4 templates as single mode) - -4. Generate all SKILL documents: - - sessions-timeline.md (all sessions, sorted by date) - - lessons-learned.md (aggregated lessons with frequencies) - - conflict-patterns.md (recurring patterns with resolutions) - - SKILL.md (index with progressive loading) - -5. Write files to .claude/skills/workflow-progress/ - -6. Return result JSON: - { - "status": "success", - "sessions_processed": count, - "files_generated": ["SKILL.md", "sessions-timeline.md", ...], - "summary": { - "total_sessions": count, - "functional_domains": [...], - "date_range": "...", - "lessons_count": count, - "conflicts_count": count - } - } -``` - ---- - -### Phase 3: Verification - -**Step 3.1: Check SKILL Package Files** -```bash -bash(ls -lh .claude/skills/workflow-progress/) -``` - -Verify all 4 files exist: -- SKILL.md -- sessions-timeline.md -- lessons-learned.md -- conflict-patterns.md - -**Step 3.2: TodoWrite Completion** - -Mark all tasks as completed. - -**Step 3.3: Display Summary** - -**Single Session Mode**: -``` -Session {session_id} processed successfully - -Updated: -- sessions-timeline.md -- lessons-learned.md -- conflict-patterns.md -- SKILL.md - -SKILL Location: .claude/skills/workflow-progress/SKILL.md -``` - -**All Sessions Mode**: -``` -All sessions processed in parallel - -Sessions: {count} total -Functional Domains: {domain_list} -Date Range: {earliest} - {latest} - -Generated: -- sessions-timeline.md ({count} sessions) -- lessons-learned.md ({lessons_count} lessons) -- conflict-patterns.md ({conflicts_count} conflicts) -- SKILL.md (4-level progressive loading) - -SKILL Location: .claude/skills/workflow-progress/SKILL.md - -Usage: -- Level 0: Quick refresh (~2K tokens) -- Level 1: Recent history (~8K tokens) -- Level 2: Complete analysis (~25K tokens) -- Level 3: Deep dive (~40K tokens) -``` - ---- - -## Agent Guidelines - -### Agent Capabilities - -**universal-executor agents can**: -- Read files from `.workflow/.archives/` -- Execute bash commands -- Call Gemini CLI for intelligent analysis -- Read template files for formatting guidance -- Write SKILL package files (single mode) or return JSON (parallel mode) -- Return structured results - -### Gemini Usage Pattern - -**When to use Gemini**: -- Aggregating lessons from multiple sources -- Identifying recurring patterns -- Classifying conflicts by type and severity -- Extracting structured data from IMPL_PLAN - -**Fallback Strategy**: If Gemini fails or times out, use direct file parsing with structured extraction logic. - ---- - -## Template System - -### Template Files - -All templates located in: `~/.claude/workflows/cli-templates/prompts/workflow/` - -1. **skill-sessions-timeline.txt**: Format for sessions-timeline.md -2. **skill-lessons-learned.txt**: Format for lessons-learned.md -3. **skill-conflict-patterns.txt**: Format for conflict-patterns.md -4. **skill-index.txt**: Format for SKILL.md index -5. **skill-aggregation.txt**: Rules for Gemini aggregation (existing) - -### Template Usage in Agent - -**Agents read templates to understand**: -- File structure and markdown format -- Data sources (which files to read) -- Update strategy (incremental vs full) -- Formatting rules and conventions -- Aggregation logic (for Gemini) - -**Templates are NOT shown in this command documentation** - agents read them directly as needed. - ---- - -## Error Handling - -### Validation Errors -- **No archives directory**: "Error: No workflow archives found at .workflow/.archives/" -- **Invalid session ID format**: "Error: Invalid session ID format. Only WFS-* sessions are supported" -- **Session not found**: "Error: Session {session_id} not found in archives" -- **No WFS sessions in manifest**: "Error: No WFS-* workflow sessions found in manifest.json" - -### Agent Errors -- If agent fails, report error message from agent result -- If Gemini times out, agents use fallback direct parsing -- If template read fails, agents use inline format - -### Recovery -- Single session mode: Can be retried without affecting other sessions -- All sessions mode: If one agent fails, others continue; retry failed sessions individually - - - -## Integration - -### Called by `/workflow:session:complete` - -Automatically invoked after session archival: -```bash -SlashCommand(command="/memory:workflow-skill-memory session {session_id}") -``` - -### Manual Invocation - -Users can manually process sessions: -```bash -/memory:workflow-skill-memory session WFS-custom-feature # Single session -/memory:workflow-skill-memory all # Full regeneration -``` diff --git a/.claude/commands/task/breakdown.md b/.claude/commands/task/breakdown.md deleted file mode 100644 index e0412201..00000000 --- a/.claude/commands/task/breakdown.md +++ /dev/null @@ -1,208 +0,0 @@ ---- -name: breakdown -description: Decompose complex task into subtasks with dependency mapping, creates child task JSONs with parent references and execution order -argument-hint: "[-y|--yes] task-id" ---- - -## Auto Mode - -When `--yes` or `-y`: Auto-confirm breakdown, use recommended subtask structure. - -# Task Breakdown Command (/task:breakdown) - -## Overview -Breaks down complex tasks into executable subtasks with context inheritance and agent assignment. - -## Core Principles -**File Cohesion:** Related files must stay in same task -**10-Task Limit:** Total tasks cannot exceed 10 (triggers re-scoping) - -## Core Features - -**CRITICAL**: Manual breakdown with safety controls to prevent file conflicts and task limit violations. - -### Breakdown Process -1. **Session Check**: Verify active session contains parent task -2. **Task Validation**: Ensure parent is `pending` status -3. **10-Task Limit Check**: Verify breakdown won't exceed total limit -4. **Manual Decomposition**: User defines subtasks with validation -5. **File Conflict Detection**: Warn if same files appear in multiple subtasks -6. **Similar Function Warning**: Alert if subtasks have overlapping functionality -7. **Context Distribution**: Inherit parent requirements and scope -8. **Agent Assignment**: Auto-assign agents based on subtask type -9. **TODO_LIST Update**: Regenerate TODO_LIST.md with new structure - -### Breakdown Rules -- Only `pending` tasks can be broken down -- **Manual breakdown only**: Automated breakdown disabled to prevent violations -- Parent becomes `container` status (not executable) -- Subtasks use format: IMPL-N.M (max 2 levels) -- Context flows from parent to subtasks -- All relationships tracked in JSON -- **10-task limit enforced**: Breakdown rejected if total would exceed 10 tasks -- **File cohesion preserved**: Same files cannot be split across subtasks - -## Usage - -### Basic Breakdown -```bash -/task:breakdown impl-1 -``` - -Interactive process: -``` -Task: Build authentication module -Current total tasks: 6/10 - -MANUAL BREAKDOWN REQUIRED -Define subtasks manually (remaining capacity: 4 tasks): - -1. Enter subtask title: User authentication core - Focus files: models/User.js, routes/auth.js, middleware/auth.js - -2. Enter subtask title: OAuth integration - Focus files: services/OAuthService.js, routes/oauth.js - -FILE CONFLICT DETECTED: - - routes/auth.js appears in multiple subtasks - - Recommendation: Merge related authentication routes - -SIMILAR FUNCTIONALITY WARNING: - - "User authentication" and "OAuth integration" both handle auth - - Consider combining into single task - -# Use AskUserQuestion for confirmation -AskUserQuestion({ - questions: [{ - question: "File conflicts and/or similar functionality detected. How do you want to proceed?", - header: "Confirm", - options: [ - { label: "Proceed with breakdown", description: "Accept the risks and create the subtasks as defined." }, - { label: "Restart breakdown", description: "Discard current subtasks and start over." }, - { label: "Cancel breakdown", description: "Abort the operation and leave the parent task as is." } - ], - multiSelect: false - }] -}) - -User selected: "Proceed with breakdown" - -Task IMPL-1 broken down: -IMPL-1: Build authentication module (container) - ├── IMPL-1.1: User authentication core -> @code-developer - └── IMPL-1.2: OAuth integration -> @code-developer - -Files updated: .task/IMPL-1.json + 2 subtask files + TODO_LIST.md -``` - -## Decomposition Logic - -### Agent Assignment -- **Design/Planning** → `@planning-agent` -- **Implementation** → `@code-developer` -- **Testing** → `@code-developer` (type: "test-gen") -- **Test Validation** → `@test-fix-agent` (type: "test-fix") -- **Review** → `@universal-executor` (optional) - -### Context Inheritance -- Subtasks inherit parent requirements -- Scope refined for specific subtask -- Implementation details distributed appropriately - -## Safety Controls - -### File Conflict Detection -**Validates file cohesion across subtasks:** -- Scans `focus_paths` in all subtasks -- Warns if same file appears in multiple subtasks -- Suggests merging subtasks with overlapping files -- Blocks breakdown if critical conflicts detected - -### Similar Functionality Detection -**Prevents functional overlap:** -- Analyzes subtask titles for similar keywords -- Warns about potential functional redundancy -- Suggests consolidation of related functionality -- Examples: "user auth" + "login system" → merge recommendation - -### 10-Task Limit Enforcement -**Hard limit compliance:** -- Counts current total tasks in session -- Calculates breakdown impact on total -- Rejects breakdown if would exceed 10 tasks -- Suggests re-scoping if limit reached - -### Manual Control Requirements -**User-driven breakdown only:** -- No automatic subtask generation -- User must define each subtask title and scope -- Real-time validation during input -- Confirmation required before execution - -## Implementation Details - -- Complete task JSON schema -- Implementation field structure -- Context inheritance rules -- Agent assignment logic - -## Validation - -### Pre-breakdown Checks -1. Active session exists -2. Task found in session -3. Task status is `pending` -4. Not already broken down -5. **10-task limit compliance**: Total tasks + new subtasks ≤ 10 -6. **Manual mode enabled**: No automatic breakdown allowed - -### Post-breakdown Actions -1. Update parent to `container` status -2. Create subtask JSON files -3. Update parent subtasks list -4. Update session stats -5. **Regenerate TODO_LIST.md** with new hierarchy -6. Validate file paths in focus_paths -7. Update session task count - -## Examples - -### Basic Breakdown -```bash -/task:breakdown impl-1 - -impl-1: Build authentication (container) - ├── impl-1.1: Design schema -> @planning-agent - ├── impl-1.2: Implement logic + tests -> @code-developer - └── impl-1.3: Execute & fix tests -> @test-fix-agent -``` - -## Error Handling - -```bash -# Task not found -Task IMPL-5 not found - -# Already broken down -Task IMPL-1 already has subtasks - -# Wrong status -Cannot breakdown completed task IMPL-2 - -# 10-task limit exceeded -Breakdown would exceed 10-task limit (current: 8, proposed: 4) -Suggestion: Re-scope project into smaller iterations - -# File conflicts detected -File conflict: routes/auth.js appears in IMPL-1.1 and IMPL-1.2 -Recommendation: Merge subtasks or redistribute files - -# Similar functionality warning -Similar functions detected: "user login" and "authentication" -Consider consolidating related functionality - -# Manual breakdown required -Automatic breakdown disabled. Use manual breakdown process. -``` - -**System ensures**: Manual breakdown control with file cohesion enforcement, similar functionality detection, and 10-task limit compliance \ No newline at end of file diff --git a/.claude/commands/task/create.md b/.claude/commands/task/create.md deleted file mode 100644 index 02b70cd9..00000000 --- a/.claude/commands/task/create.md +++ /dev/null @@ -1,152 +0,0 @@ ---- -name: create -description: Generate task JSON from natural language description with automatic file pattern detection, scope inference, and dependency analysis -argument-hint: "\"task title\"" ---- - -# Task Create Command (/task:create) - -## Overview -Creates new implementation tasks with automatic context awareness and ID generation. - -## Core Principles -**Task System:** @~/.claude/workflows/task-core.md - -## Core Features - -### Automatic Behaviors -- **ID Generation**: Auto-generates IMPL-N format (max 2 levels) -- **Context Inheritance**: Inherits from active workflow session -- **JSON Creation**: Creates task JSON in active session -- **Status Setting**: Initial status = "pending" -- **Agent Assignment**: Suggests agent based on task type -- **Session Integration**: Updates workflow session stats - -### Context Awareness -- Validates active workflow session exists -- Avoids duplicate task IDs -- Inherits session requirements and scope -- Suggests task relationships - -## Usage - -### Basic Creation -```bash -/task:create "Build authentication module" -``` - -Output: -``` -Task created: IMPL-1 -Title: Build authentication module -Type: feature -Agent: code-developer -Status: pending -``` - -### Task Types -- `feature` - New functionality (default) -- `bugfix` - Bug fixes -- `refactor` - Code improvements -- `test` - Test implementation -- `docs` - Documentation - -## Task Creation Process - -1. **Session Validation**: Check active workflow session -2. **ID Generation**: Auto-increment IMPL-N -3. **Context Inheritance**: Load workflow context -4. **Implementation Setup**: Initialize implementation field -5. **Agent Assignment**: Select appropriate agent -6. **File Creation**: Save JSON to .task/ directory -7. **Session Update**: Update workflow stats - -**Task Schema**: See @~/.claude/workflows/task-core.md for complete JSON structure - -## Implementation Field Setup - -### Auto-Population Strategy -- **Detailed info**: Extract from task description and scope -- **Missing info**: Mark `pre_analysis` as multi-step array format for later pre-analysis -- **Basic structure**: Initialize with standard template - -### Analysis Triggers -When implementation details incomplete: -```bash -Task requires analysis for implementation details -Suggest running: gemini analysis for file locations and dependencies -``` - -## File Management - -### JSON Task File -- **Location**: `.task/IMPL-[N].json` in active session -- **Content**: Complete task with implementation field -- **Updates**: Session stats only - -### Simple Process -1. Validate session and inputs -2. Generate task JSON -3. Update session stats -4. Notify completion - -## Context Inheritance - -Tasks inherit from: -1. **Active Session** - Requirements and scope from workflow-session.json -2. **Planning Document** - Context from IMPL_PLAN.md -3. **Parent Task** - For subtasks (IMPL-N.M format) - -## Agent Assignment - -Based on task type and title keywords: -- **Build/Implement** → @code-developer -- **Design/Plan** → @planning-agent -- **Test Generation** → @code-developer (type: "test-gen") -- **Test Execution/Fix** → @test-fix-agent (type: "test-fix") -- **Review/Audit** → @universal-executor (optional, only when explicitly requested) - -## Validation Rules - -1. **Session Check** - Active workflow session required -2. **Duplicate Check** - Avoid similar task titles -3. **ID Uniqueness** - Auto-increment task IDs -4. **Schema Validation** - Ensure proper JSON structure - -## Error Handling - -```bash -# No workflow session -No active workflow found -Use: /workflow init "project name" - -# Duplicate task -Similar task exists: IMPL-3 -Continue anyway? (y/n) - -# Max depth exceeded -Cannot create IMPL-1.2.1 (max 2 levels) -Use: IMPL-2 for new main task -``` - -## Examples - -### Feature Task -```bash -/task:create "Implement user authentication" - -Created IMPL-1: Implement user authentication -Type: feature -Agent: code-developer -Status: pending -``` - -### Bug Fix -```bash -/task:create "Fix login validation bug" --type=bugfix - -Created IMPL-2: Fix login validation bug -Type: bugfix -Agent: code-developer -Status: pending -``` \ No newline at end of file diff --git a/.claude/commands/task/execute.md b/.claude/commands/task/execute.md deleted file mode 100644 index 607c556f..00000000 --- a/.claude/commands/task/execute.md +++ /dev/null @@ -1,270 +0,0 @@ ---- -name: execute -description: Execute task JSON using appropriate agent (@doc-generator/@implementation-agent/@test-agent) with pre-analysis context loading and status tracking -argument-hint: "task-id" ---- - -## Command Overview: /task:execute - -**Purpose**: Executes tasks using intelligent agent selection, context preparation, and progress tracking. - - -## Execution Modes - -- **auto (Default)** - - Fully autonomous execution with automatic agent selection. - - Provides progress updates at each checkpoint. - - Automatically completes the task when done. -- **guided** - - Executes step-by-step, requiring user confirmation at each checkpoint. - - Allows for dynamic adjustments and manual review during the process. -- **review** - - Optional manual review using `@universal-executor`. - - Used only when explicitly requested by user. - -## Agent Selection Logic - -The system determines the appropriate agent for a task using the following logic. - -```pseudo -FUNCTION select_agent(task, agent_override): - // A manual override always takes precedence. - // Corresponds to the --agent= flag. - IF agent_override IS NOT NULL: - RETURN agent_override - - // If no override, select based on keywords in the task title. - ELSE: - CASE task.title: - WHEN CONTAINS "Build API", "Implement": - RETURN "@code-developer" - WHEN CONTAINS "Design schema", "Plan": - RETURN "@planning-agent" - WHEN CONTAINS "Write tests", "Generate tests": - RETURN "@code-developer" // type: test-gen - WHEN CONTAINS "Execute tests", "Fix tests", "Validate": - RETURN "@test-fix-agent" // type: test-fix - WHEN CONTAINS "Review code": - RETURN "@universal-executor" // Optional manual review - DEFAULT: - RETURN "@code-developer" // Default agent - END CASE -END FUNCTION -``` - -## Core Execution Protocol - -`Pre-Execution` -> `Execution` -> `Post-Execution` - -### Pre-Execution Protocol - -`Validate Task & Dependencies` **->** `Prepare Execution Context` **->** `Coordinate with TodoWrite` - -- **Validation**: Checks for the task's JSON file in `.task/` and resolves its dependencies. -- **Context Preparation**: Loads task and workflow context, preparing it for the selected agent. -- **Session Context Injection**: Provides workflow directory paths to agents for TODO_LIST.md and summary management. -- **TodoWrite Coordination**: Generates execution Todos and checkpoints, syncing with `TODO_LIST.md`. - -### Post-Execution Protocol - -`Update Task Status` **->** `Generate Summary` **->** `Save Artifacts` **->** `Sync All Progress` **->** `Validate File Integrity` - -- Updates status in the task's JSON file and `TODO_LIST.md`. -- Creates a summary in `.summaries/`. -- Stores outputs and syncs progress across the entire workflow session. - -### Task & Subtask Execution Logic - -This logic defines how single, multiple, or parent tasks are handled. - -```pseudo -FUNCTION execute_task_command(task_id, mode, parallel_flag): - // Handle parent tasks by executing their subtasks. - IF is_parent_task(task_id): - subtasks = get_subtasks(task_id) - EXECUTE_SUBTASK_BATCH(subtasks, mode) - - // Handle wildcard execution (e.g., IMPL-001.*) - ELSE IF task_id CONTAINS "*": - subtasks = find_matching_tasks(task_id) - IF parallel_flag IS true: - EXECUTE_IN_PARALLEL(subtasks) - ELSE: - FOR each subtask in subtasks: - EXECUTE_SINGLE_TASK(subtask, mode) - - // Default case for a single task ID. - ELSE: - EXECUTE_SINGLE_TASK(task_id, mode) -END FUNCTION -``` - -### Error Handling & Recovery Logic - -```pseudo -FUNCTION pre_execution_check(task): - // Ensure dependencies are met before starting. - IF task.dependencies ARE NOT MET: - LOG_ERROR("Cannot execute " + task.id) - LOG_INFO("Blocked by: " + unmet_dependencies) - HALT_EXECUTION() - -FUNCTION on_execution_failure(checkpoint): - // Provide user with recovery options upon failure. - LOG_WARNING("Execution failed at checkpoint " + checkpoint) - PRESENT_OPTIONS([ - "Retry from checkpoint", - "Retry from beginning", - "Switch to guided mode", - "Abort execution" - ]) - AWAIT user_input - // System performs the selected action. -END FUNCTION -``` - - -### Simplified Context Structure (JSON) - -This is the simplified data structure loaded to provide context for task execution. - -```json -{ - "task": { - "id": "IMPL-1", - "title": "Build authentication module", - "type": "feature", - "status": "active", - "agent": "code-developer", - "context": { - "requirements": ["JWT authentication", "OAuth2 support"], - "scope": ["src/auth/*", "tests/auth/*"], - "acceptance": ["Module handles JWT tokens", "OAuth2 flow implemented"], - "inherited_from": "WFS-user-auth" - }, - "relations": { - "parent": null, - "subtasks": ["IMPL-1.1", "IMPL-1.2"], - "dependencies": ["IMPL-0"] - }, - "implementation": { - "files": [ - { - "path": "src/auth/login.ts", - "location": { - "function": "authenticateUser", - "lines": "25-65", - "description": "Main authentication logic" - }, - "original_code": "// Code snippet extracted via gemini analysis", - "modifications": { - "current_state": "Basic password authentication only", - "proposed_changes": [ - "Add JWT token generation", - "Implement OAuth2 callback handling", - "Add multi-factor authentication support" - ], - "logic_flow": [ - "validateCredentials() ───► checkUserExists()", - "◊─── if password ───► generateJWT() ───► return token", - "◊─── if OAuth ───► validateOAuthCode() ───► exchangeForToken()", - "◊─── if MFA ───► sendMFACode() ───► awaitVerification()" - ], - "reason": "Support modern authentication standards and security requirements", - "expected_outcome": "Comprehensive authentication system supporting multiple methods" - } - } - ], - "context_notes": { - "dependencies": ["jsonwebtoken", "passport", "speakeasy"], - "affected_modules": ["user-session", "auth-middleware", "api-routes"], - "risks": [ - "Breaking changes to existing login endpoints", - "Token storage and rotation complexity", - "OAuth provider configuration dependencies" - ], - "performance_considerations": "JWT validation adds ~10ms per request, OAuth callbacks may timeout", - "error_handling": "Ensure sensitive authentication errors don't leak user enumeration data" - }, - "pre_analysis": [ - { - "action": "analyze patterns", - "template": "~/.claude/workflows/cli-templates/prompts/analysis/02-analyze-code-patterns.txt", - "method": "gemini" - } - ] - } - }, - "workflow": { - "session": "WFS-user-auth", - "phase": "IMPLEMENT", - "session_context": { - "workflow_directory": ".workflow/active/WFS-user-auth/", - "todo_list_location": ".workflow/active/WFS-user-auth/TODO_LIST.md", - "summaries_directory": ".workflow/active/WFS-user-auth/.summaries/", - "task_json_location": ".workflow/active/WFS-user-auth/.task/" - } - }, - "execution": { - "agent": "code-developer", - "mode": "auto", - "attempts": 0 - } -} -``` - -### Agent-Specific Context - -Different agents receive context tailored to their function, including implementation details: - -**`@code-developer`**: -- Complete implementation.files array with file paths and locations -- original_code snippets and proposed_changes for precise modifications -- logic_flow diagrams for understanding data flow -- Dependencies and affected modules for integration planning -- Performance and error handling considerations - -**`@planning-agent`**: -- High-level requirements, constraints, success criteria -- Implementation risks and mitigation strategies -- Architecture implications from implementation.context_notes - -**`@test-fix-agent`**: -- Test files to execute from task.context.focus_paths -- Source files to fix from implementation.files[].path -- Expected behaviors from implementation.modifications.logic_flow -- Error conditions to validate from implementation.context_notes.error_handling -- Performance requirements from implementation.context_notes.performance_considerations - -**`@universal-executor`**: -- Used for optional manual reviews when explicitly requested -- Code quality standards and implementation patterns -- Security considerations from implementation.context_notes.risks -- Dependency validation from implementation.context_notes.dependencies -- Architecture compliance checks - -### Simplified File Output - -- **Task JSON File (`.task/.json`)**: Updated with status and last attempt time only. -- **Session File (`workflow-session.json`)**: Updated task stats (completed count). -- **Summary File**: Generated in `.summaries/` upon completion (optional). - -### Simplified Summary Template - -Optional summary file generated at `.summaries/IMPL-[task-id]-summary.md`. - -```markdown -# Task Summary: IMPL-1 Build Authentication Module - -## What Was Done -- Created src/auth/login.ts with JWT validation -- Added tests in tests/auth.test.ts - -## Execution Results -- **Agent**: code-developer -- **Status**: completed - -## Files Modified -- `src/auth/login.ts` (created) -- `tests/auth.test.ts` (created) -``` diff --git a/.claude/commands/task/replan.md b/.claude/commands/task/replan.md deleted file mode 100644 index 2223a3a7..00000000 --- a/.claude/commands/task/replan.md +++ /dev/null @@ -1,441 +0,0 @@ ---- -name: replan -description: Update task JSON with new requirements or batch-update multiple tasks from verification report, tracks changes in task-changes.json -argument-hint: "[-y|--yes] task-id [\"text\"|file.md] | --batch [verification-report.md]" -allowed-tools: Read(*), Write(*), Edit(*), TodoWrite(*), Glob(*), Bash(*) ---- - -## Auto Mode - -When `--yes` or `-y`: Auto-confirm updates, use recommended changes. - -# Task Replan Command (/task:replan) - -> **⚠️ DEPRECATION NOTICE**: This command is maintained for backward compatibility. For new workflows, use `/workflow:replan` which provides: -> - Session-level replanning with comprehensive artifact updates -> - Interactive boundary clarification -> - Updates to IMPL_PLAN.md, TODO_LIST.md, and session metadata -> - Better integration with workflow sessions -> -> **Migration**: Replace `/task:replan IMPL-1 "changes"` with `/workflow:replan IMPL-1 "changes"` - -## Overview -Replans individual tasks or batch processes multiple tasks with change tracking and backup management. - -**Modes**: -- **Single Task Mode**: Replan one task with specific changes -- **Batch Mode**: Process multiple tasks from action-plan verification report - -## Key Features -- **Single/Batch Operations**: Single task or multiple tasks from verification report -- **Multiple Input Sources**: Text, files, or verification report -- **Backup Management**: Automatic backup of previous versions -- **Change Documentation**: Track all modifications -- **Progress Tracking**: TodoWrite integration for batch operations - -**CRITICAL**: Validates active session before replanning - -## Operation Modes - -### Single Task Mode - -#### Direct Text (Default) -```bash -/task:replan IMPL-1 "Add OAuth2 authentication support" -``` - -#### File-based Input -```bash -/task:replan IMPL-1 updated-specs.md -``` -Supports: .md, .txt, .json, .yaml - -#### Interactive Mode -```bash -/task:replan IMPL-1 --interactive -``` -Guided step-by-step modification process with validation - -### Batch Mode - -#### From Verification Report -```bash -/task:replan --batch ACTION_PLAN_VERIFICATION.md -``` - -**Workflow**: -1. Parse verification report to extract replan recommendations -2. Create TodoWrite task list for all modifications -3. Process each task sequentially with confirmation -4. Track progress and generate summary report - -**Auto-detection**: If input file contains "Action Plan Verification Report" header, automatically enters batch mode - -## Replanning Process - -### Single Task Process - -1. **Load & Validate**: Read task JSON and validate session -2. **Parse Input**: Process changes from input source -3. **Create Backup**: Save previous version to backup folder -4. **Update Task**: Modify JSON structure and relationships -5. **Save Changes**: Write updated task and increment version -6. **Update Session**: Reflect changes in workflow stats - -### Batch Process - -1. **Parse Verification Report**: Extract all replan recommendations -2. **Initialize TodoWrite**: Create task list for tracking -3. **For Each Task**: - - Mark todo as in_progress - - Load and validate task JSON - - Create backup - - Apply recommended changes - - Save updated task - - Mark todo as completed -4. **Generate Summary**: Report all changes and backup locations - -## Backup Management - -### Backup Tracking -Tasks maintain backup history: -```json -{ - "id": "IMPL-1", - "version": "1.2", - "replan_history": [ - { - "version": "1.2", - "reason": "Add OAuth2 support", - "input_source": "direct_text", - "backup_location": ".task/backup/IMPL-1-v1.1.json", - "timestamp": "2025-10-17T10:30:00Z" - } - ] -} -``` - -**Complete schema**: See @~/.claude/workflows/task-core.md - -### File Structure -``` -.task/ -├── IMPL-1.json # Current version -├── backup/ -│ ├── IMPL-1-v1.0.json # Original version -│ ├── IMPL-1-v1.1.json # Previous backup -│ └── IMPL-1-v1.2.json # Latest backup -└── [new subtasks as needed] -``` - -**Backup Naming**: `{task-id}-v{version}.json` - -## Implementation Updates - -### Change Detection -Tracks modifications to: -- Files in implementation.files array -- Dependencies and affected modules -- Risk assessments and performance notes -- Logic flows and code locations - -### Analysis Triggers -May require gemini re-analysis when: -- New files need code extraction -- Function locations change -- Dependencies require re-evaluation - -## Document Updates - -### Planning Document -May update IMPL_PLAN.md sections when task structure changes significantly - -### TODO List Sync -If TODO_LIST.md exists, synchronizes: -- New subtasks (with [ ] checkbox) -- Modified tasks (marked as updated) -- Removed subtasks (deleted from list) - -## Change Documentation - -### Change Summary -Generates brief change log with: -- Version increment (1.1 → 1.2) -- Input source and reason -- Key modifications made -- Files updated/created -- Backup location - -## Session Updates - -Updates workflow-session.json with: -- Modified task tracking -- Task count changes (if subtasks added/removed) -- Last modification timestamps - -## Rollback Support - -```bash -/task:replan IMPL-1 --rollback v1.1 - -Rollback to version 1.1: -- Restore task from backup/.../IMPL-1-v1.1.json -- Remove new subtasks if any -- Update session stats - -# Use AskUserQuestion for confirmation -AskUserQuestion({ - questions: [{ - question: "Are you sure you want to roll back this task to a previous version?", - header: "Confirm", - options: [ - { label: "Yes, rollback", description: "Restore the task from the selected backup." }, - { label: "No, cancel", description: "Keep the current version of the task." } - ], - multiSelect: false - }] -}) - -User selected: "Yes, rollback" - -Task rolled back to version 1.1 -``` - -## Batch Processing with TodoWrite - -### Progress Tracking -When processing multiple tasks, automatically creates TodoWrite task list: - -```markdown -**Batch Replan Progress**: -- [x] IMPL-002: Add FR-12 draft saving acceptance criteria -- [x] IMPL-003: Add FR-14 history tracking acceptance criteria -- [ ] IMPL-004: Add FR-09 response surface explicit coverage -- [ ] IMPL-008: Add NFR performance validation steps -``` - -### Batch Report -After completion, generates summary: -```markdown -## Batch Replan Summary - -**Total Tasks**: 4 -**Successful**: 3 -**Failed**: 1 -**Skipped**: 0 - -### Changes Made -- IMPL-002 v1.0 → v1.1: Added FR-12 acceptance criteria -- IMPL-003 v1.0 → v1.1: Added FR-14 acceptance criteria -- IMPL-004 v1.0 → v1.1: Added FR-09 explicit coverage - -### Backups Created -- .task/backup/IMPL-002-v1.0.json -- .task/backup/IMPL-003-v1.0.json -- .task/backup/IMPL-004-v1.0.json - -### Errors -- IMPL-008: File not found (task may have been renamed) -``` - -## Examples - -### Single Task - Text Input -```bash -/task:replan IMPL-1 "Add OAuth2 authentication support" - -Processing changes... -Proposed updates: -+ Add OAuth2 integration -+ Update authentication flow - -# Use AskUserQuestion for confirmation -AskUserQuestion({ - questions: [{ - question: "Do you want to apply these changes to the task?", - header: "Apply", - options: [ - { label: "Yes, apply", description: "Create new version with these changes." }, - { label: "No, cancel", description: "Discard changes and keep current version." } - ], - multiSelect: false - }] -}) - -User selected: "Yes, apply" - -Version 1.2 created -Context updated -Backup saved to .task/backup/IMPL-1-v1.1.json -``` - -### Single Task - File Input -```bash -/task:replan IMPL-2 requirements.md - -Loading requirements.md... -Applying specification changes... - -Task updated with new requirements -Version 1.1 created -Backup saved to .task/backup/IMPL-2-v1.0.json -``` - -### Batch Mode - From Verification Report -```bash -/task:replan --batch .workflow/active/WFS-{session}/.process/ACTION_PLAN_VERIFICATION.md - -Parsing verification report... -Found 4 tasks requiring replanning: -- IMPL-002: Add FR-12 draft saving acceptance criteria -- IMPL-003: Add FR-14 history tracking acceptance criteria -- IMPL-004: Add FR-09 response surface explicit coverage -- IMPL-008: Add NFR performance validation steps - -Creating task tracking list... - -Processing IMPL-002... -Backup created: .task/backup/IMPL-002-v1.0.json -Updated to v1.1 - -Processing IMPL-003... -Backup created: .task/backup/IMPL-003-v1.0.json -Updated to v1.1 - -Processing IMPL-004... -Backup created: .task/backup/IMPL-004-v1.0.json -Updated to v1.1 - -Processing IMPL-008... -Backup created: .task/backup/IMPL-008-v1.0.json -Updated to v1.1 - -Batch replan completed: 4/4 successful -Summary report saved -``` - -### Batch Mode - Auto-detection -```bash -# If file contains "Action Plan Verification Report", auto-enters batch mode -/task:replan ACTION_PLAN_VERIFICATION.md - -Detected verification report format -Entering batch mode... -[same as above] -``` - -## Error Handling - -### Single Task Errors -```bash -# Task not found -Task IMPL-5 not found -Check task ID with /workflow:status - -# Task completed -Task IMPL-1 is completed (cannot replan) -Create new task for additional work - -# File not found -File requirements.md not found -Check file path - -# No input provided -Please specify changes needed -Provide text, file, or verification report -``` - -### Batch Mode Errors -```bash -# Invalid verification report -File does not contain valid verification report format -Check report structure or use single task mode - -# Partial failures -Batch completed with errors: 3/4 successful -Review error details in summary report - -# No replan recommendations found -Verification report contains no replan recommendations -Check report content or use /workflow:plan-verify first -``` - -## Batch Mode Integration - -### Input Format Expectations -Batch mode parses verification reports looking for: - -1. **Required Actions Section**: Commands like `/task:replan IMPL-X "changes"` -2. **Findings Table**: Task IDs with recommendations -3. **Next Actions Section**: Specific replan commands - -**Example Patterns**: -```markdown -#### 1. HIGH Priority - Address FR Coverage Gaps -/task:replan IMPL-004 " -Add explicit acceptance criteria: -- FR-09: Response surface 3D visualization -" - -#### 2. MEDIUM Priority - Enhance NFR Coverage -/task:replan IMPL-008 " -Add performance testing: -- NFR-01: Load test API endpoints -" -``` - -### Extraction Logic -1. Scan for `/task:replan` commands in report -2. Extract task ID and change description -3. Group by priority (HIGH, MEDIUM, LOW) -4. Process in priority order with TodoWrite tracking - -### Confirmation Behavior -- **Default**: Confirm each task before applying -- **With `--auto-confirm`**: Apply all changes without prompting - ```bash - /task:replan --batch report.md --auto-confirm - ``` - -## Implementation Details - -### Backup Management -```typescript -// Backup file naming convention -const backupPath = `.task/backup/${taskId}-v${previousVersion}.json`; - -// Backup metadata in task JSON -{ - "replan_history": [ - { - "version": "1.2", - "timestamp": "2025-10-17T10:30:00Z", - "reason": "Add FR-09 explicit coverage", - "input_source": "batch_verification_report", - "backup_location": ".task/backup/IMPL-004-v1.1.json" - } - ] -} -``` - -### TodoWrite Integration -```typescript -// Initialize tracking for batch mode -TodoWrite({ - todos: taskList.map(task => ({ - content: `${task.id}: ${task.changeDescription}`, - status: "pending", - activeForm: `Replanning ${task.id}` - })) -}); - -// Update progress during processing -TodoWrite({ - todos: updateTaskStatus(taskId, "in_progress") -}); - -// Mark completed -TodoWrite({ - todos: updateTaskStatus(taskId, "completed") -}); -``` \ No newline at end of file diff --git a/.claude/commands/version.md b/.claude/commands/version.md deleted file mode 100644 index e6382674..00000000 --- a/.claude/commands/version.md +++ /dev/null @@ -1,254 +0,0 @@ ---- -name: version -description: Display Claude Code version information and check for updates -allowed-tools: Bash(*) ---- - -# Version Command (/version) - -## Purpose -Display local and global installation versions, check for the latest updates from GitHub, and provide upgrade recommendations. - -## Execution Flow -1. **Local Version Check**: Read version information from `./.claude/version.json` if it exists. -2. **Global Version Check**: Read version information from `~/.claude/version.json` if it exists. -3. **Fetch Remote Versions**: Use GitHub API to get the latest stable release tag and the latest commit hash from the main branch. -4. **Compare & Suggest**: Compare installed versions with the latest remote versions and provide upgrade suggestions if applicable. - -## Step 1: Check Local Version - -### Check if local version.json exists -```bash -bash(test -f ./.claude/version.json && echo "found" || echo "not_found") -``` - -### Read local version (if exists) -```bash -bash(cat ./.claude/version.json) -``` - -### Extract version with jq (preferred) -```bash -bash(cat ./.claude/version.json | grep -o '"version": *"[^"]*"' | cut -d'"' -f4) -``` - -### Extract installation date -```bash -bash(cat ./.claude/version.json | grep -o '"installation_date_utc": *"[^"]*"' | cut -d'"' -f4) -``` - -**Output Format**: -``` -Local Version: 3.2.1 -Installed: 2025-10-03T12:00:00Z -``` - -## Step 2: Check Global Version - -### Check if global version.json exists -```bash -bash(test -f ~/.claude/version.json && echo "found" || echo "not_found") -``` - -### Read global version -```bash -bash(cat ~/.claude/version.json) -``` - -### Extract version -```bash -bash(cat ~/.claude/version.json | grep -o '"version": *"[^"]*"' | cut -d'"' -f4) -``` - -### Extract installation date -```bash -bash(cat ~/.claude/version.json | grep -o '"installation_date_utc": *"[^"]*"' | cut -d'"' -f4) -``` - -**Output Format**: -``` -Global Version: 3.2.1 -Installed: 2025-10-03T12:00:00Z -``` - -## Step 3: Fetch Latest Stable Release - -### Call GitHub API for latest release (with timeout) -```bash -bash(curl -fsSL "https://api.github.com/repos/catlog22/Claude-Code-Workflow/releases/latest" 2>/dev/null, timeout: 30000) -``` - -### Extract tag name (version) -```bash -bash(curl -fsSL "https://api.github.com/repos/catlog22/Claude-Code-Workflow/releases/latest" 2>/dev/null | grep -o '"tag_name": *"[^"]*"' | head -1 | cut -d'"' -f4, timeout: 30000) -``` - -### Extract release name -```bash -bash(curl -fsSL "https://api.github.com/repos/catlog22/Claude-Code-Workflow/releases/latest" 2>/dev/null | grep -o '"name": *"[^"]*"' | head -1 | cut -d'"' -f4, timeout: 30000) -``` - -### Extract published date -```bash -bash(curl -fsSL "https://api.github.com/repos/catlog22/Claude-Code-Workflow/releases/latest" 2>/dev/null | grep -o '"published_at": *"[^"]*"' | cut -d'"' -f4, timeout: 30000) -``` - -**Output Format**: -``` -Latest Stable: v3.2.2 -Release: v3.2.2: Independent Test-Gen Workflow with Cross-Session Context -Published: 2025-10-03T04:10:08Z -``` - -## Step 4: Fetch Latest Main Branch - -### Call GitHub API for latest commit on main (with timeout) -```bash -bash(curl -fsSL "https://api.github.com/repos/catlog22/Claude-Code-Workflow/commits/main" 2>/dev/null, timeout: 30000) -``` - -### Extract commit SHA (short) -```bash -bash(curl -fsSL "https://api.github.com/repos/catlog22/Claude-Code-Workflow/commits/main" 2>/dev/null | grep -o '"sha": *"[^"]*"' | head -1 | cut -d'"' -f4 | cut -c1-7, timeout: 30000) -``` - -### Extract commit message (first line only) -```bash -bash(curl -fsSL "https://api.github.com/repos/catlog22/Claude-Code-Workflow/commits/main" 2>/dev/null | grep '"message":' | cut -d'"' -f4 | cut -d'\' -f1, timeout: 30000) -``` - -### Extract commit date -```bash -bash(curl -fsSL "https://api.github.com/repos/catlog22/Claude-Code-Workflow/commits/main" 2>/dev/null | grep -o '"date": *"[^"]*"' | head -1 | cut -d'"' -f4, timeout: 30000) -``` - -**Output Format**: -``` -Latest Dev: a03415b -Message: feat: Add version tracking and upgrade check system -Date: 2025-10-03T04:46:44Z -``` - -## Step 5: Compare Versions and Suggest Upgrade - -### Normalize versions (remove 'v' prefix) -```bash -bash(echo "v3.2.1" | sed 's/^v//') -``` - -### Compare two versions -```bash -bash(printf "%s\n%s" "3.2.1" "3.2.2" | sort -V | tail -n 1) -``` - -### Check if versions are equal -```bash -# If equal: Up to date -# If remote newer: Upgrade available -# If local newer: Development version -``` - -**Output Scenarios**: - -**Scenario 1: Up to date** -``` -You are on the latest stable version (3.2.1) -``` - -**Scenario 2: Upgrade available** -``` -A newer stable version is available: v3.2.2 -Your version: 3.2.1 - -To upgrade: -PowerShell: iex (iwr -useb https://raw.githubusercontent.com/catlog22/Claude-Code-Workflow/main/install-remote.ps1) -Bash: bash <(curl -fsSL https://raw.githubusercontent.com/catlog22/Claude-Code-Workflow/main/install-remote.sh) -``` - -**Scenario 3: Development version** -``` -You are running a development version (3.4.0-dev) -This is newer than the latest stable release (v3.3.0) -``` - -## Simple Bash Commands - -### Basic Operations -```bash -# Check local version file -bash(test -f ./.claude/version.json && cat ./.claude/version.json) - -# Check global version file -bash(test -f ~/.claude/version.json && cat ~/.claude/version.json) - -# Extract version from JSON -bash(cat version.json | grep -o '"version": *"[^"]*"' | cut -d'"' -f4) - -# Extract date from JSON -bash(cat version.json | grep -o '"installation_date_utc": *"[^"]*"' | cut -d'"' -f4) - -# Fetch latest release (with timeout) -bash(curl -fsSL "https://api.github.com/repos/catlog22/Claude-Code-Workflow/releases/latest" 2>/dev/null, timeout: 30000) - -# Extract tag name -bash(curl -fsSL "https://api.github.com/repos/catlog22/Claude-Code-Workflow/releases/latest" 2>/dev/null | grep -o '"tag_name": *"[^"]*"' | cut -d'"' -f4, timeout: 30000) - -# Extract release name -bash(curl -fsSL "https://api.github.com/repos/catlog22/Claude-Code-Workflow/releases/latest" 2>/dev/null | grep -o '"name": *"[^"]*"' | head -1 | cut -d'"' -f4, timeout: 30000) - -# Fetch latest commit (with timeout) -bash(curl -fsSL "https://api.github.com/repos/catlog22/Claude-Code-Workflow/commits/main" 2>/dev/null, timeout: 30000) - -# Extract commit SHA -bash(curl -fsSL "https://api.github.com/repos/catlog22/Claude-Code-Workflow/commits/main" 2>/dev/null | grep -o '"sha": *"[^"]*"' | head -1 | cut -d'"' -f4 | cut -c1-7, timeout: 30000) - -# Extract commit message (first line) -bash(curl -fsSL "https://api.github.com/repos/catlog22/Claude-Code-Workflow/commits/main" 2>/dev/null | grep '"message":' | cut -d'"' -f4 | cut -d'\' -f1, timeout: 30000) - -# Compare versions -bash(printf "%s\n%s" "3.2.1" "3.2.2" | sort -V | tail -n 1) - -# Remove 'v' prefix -bash(echo "v3.2.1" | sed 's/^v//') -``` - -## Error Handling - -### No installation found -``` -WARNING: Claude Code Workflow not installed -Install using: -PowerShell: iex (iwr -useb https://raw.githubusercontent.com/catlog22/Claude-Code-Workflow/main/install-remote.ps1) -``` - -### Network error -``` -ERROR: Could not fetch latest version from GitHub -Check your network connection -``` - -### Invalid version.json -``` -ERROR: version.json is invalid or corrupted -``` - -## Design Notes - -- Uses simple, direct bash commands instead of complex functions -- Each step is independent and can be executed separately -- Fallback to grep/sed for JSON parsing (no jq dependency required) -- Network calls use curl with error suppression and 30-second timeout -- Version comparison uses `sort -V` for accurate semantic versioning -- Use `/commits/main` API instead of `/branches/main` for more reliable commit info -- Extract first line of commit message using `cut -d'\' -f1` to handle JSON escape sequences - -## API Endpoints - -### GitHub API Used -- **Latest Release**: `https://api.github.com/repos/catlog22/Claude-Code-Workflow/releases/latest` - - Fields: `tag_name`, `name`, `published_at` -- **Latest Commit**: `https://api.github.com/repos/catlog22/Claude-Code-Workflow/commits/main` - - Fields: `sha`, `commit.message`, `commit.author.date` - -### Timeout Configuration -All network calls should use `timeout: 30000` (30 seconds) to handle slow connections. diff --git a/.claude/commands/workflow/brainstorm/api-designer.md b/.claude/commands/workflow/brainstorm/api-designer.md deleted file mode 100644 index f260e95b..00000000 --- a/.claude/commands/workflow/brainstorm/api-designer.md +++ /dev/null @@ -1,587 +0,0 @@ ---- -name: api-designer -description: Generate or update api-designer/analysis.md addressing guidance-specification discussion points for API design perspective -argument-hint: "optional topic - uses existing framework if available" -allowed-tools: Task(conceptual-planning-agent), TodoWrite(*), Read(*), Write(*) ---- - -## 🔌 **API Designer Analysis Generator** - -### Purpose -**Specialized command for generating api-designer/analysis.md** that addresses guidance-specification.md discussion points from backend API design perspective. Creates or updates role-specific analysis with framework references. - -### Core Function -- **Framework-based Analysis**: Address each discussion point in guidance-specification.md -- **API Design Focus**: RESTful/GraphQL API design, endpoint structure, and contract definition -- **Update Mechanism**: Create new or update existing analysis.md -- **Agent Delegation**: Use conceptual-planning-agent for analysis generation - -### Analysis Scope -- **API Architecture**: RESTful/GraphQL design patterns and best practices -- **Endpoint Design**: Resource modeling, URL structure, and HTTP method selection -- **Data Contracts**: Request/response schemas, validation rules, and data transformation -- **API Documentation**: OpenAPI/Swagger specifications and developer experience - -### Role Boundaries & Responsibilities - -#### **What This Role OWNS (API Contract Within Architectural Framework)** -- **API Contract Definition**: Specific endpoint paths, HTTP methods, and status codes -- **Resource Modeling**: Mapping domain entities to RESTful resources or GraphQL types -- **Request/Response Schemas**: Detailed data contracts, validation rules, and error formats -- **API Versioning Strategy**: Version management, deprecation policies, and migration paths -- **Developer Experience**: API documentation (OpenAPI/Swagger), code examples, and SDKs - -#### **What This Role DOES NOT Own (Defers to Other Roles)** -- **System Architecture Decisions**: Microservices vs monolithic, overall communication patterns → Defers to **System Architect** -- **Canonical Data Model**: Underlying data schemas and entity relationships → Defers to **Data Architect** -- **UI/Frontend Integration**: How clients consume the API → Defers to **UI Designer** - -#### **Handoff Points** -- **FROM System Architect**: Receives architectural constraints (REST vs GraphQL, sync vs async) that define the design space -- **FROM Data Architect**: Receives canonical data model and translates it into public API data contracts (as projection/view) -- **TO Frontend Teams**: Provides complete API specifications, documentation, and integration guides - -## ⚙️ **Execution Protocol** - -### Phase 1: Session & Framework Detection -```bash -# Check active session and framework -CHECK: find .workflow/active/ -name "WFS-*" -type d -IF active_session EXISTS: - session_id = get_active_session() - brainstorm_dir = .workflow/active/WFS-{session}/.brainstorming/ - - CHECK: brainstorm_dir/guidance-specification.md - IF EXISTS: - framework_mode = true - load_framework = true - ELSE: - IF topic_provided: - framework_mode = false # Create analysis without framework - ELSE: - ERROR: "No framework found and no topic provided" -``` - -### Phase 2: Analysis Mode Detection -```bash -# Check existing analysis -CHECK: brainstorm_dir/api-designer/analysis.md -IF EXISTS: - SHOW existing analysis summary - ASK: "Analysis exists. Do you want to:" - OPTIONS: - 1. "Update with new insights" → Update existing - 2. "Replace completely" → Generate new - 3. "Cancel" → Exit without changes -ELSE: - CREATE new analysis -``` - -### Phase 3: Agent Task Generation -**Framework-Based Analysis** (when guidance-specification.md exists): -```bash -Task(subagent_type="conceptual-planning-agent", - run_in_background=false, - prompt="Generate API designer analysis addressing topic framework - - ## Framework Integration Required - **MANDATORY**: Load and address guidance-specification.md discussion points - **Framework Reference**: @{session.brainstorm_dir}/guidance-specification.md - **Output Location**: {session.brainstorm_dir}/api-designer/analysis.md - - ## Analysis Requirements - 1. **Load Topic Framework**: Read guidance-specification.md completely - 2. **Address Each Discussion Point**: Respond to all 5 framework sections from API design perspective - 3. **Include Framework Reference**: Start analysis.md with @../guidance-specification.md - 4. **API Design Focus**: Emphasize endpoint structure, data contracts, versioning strategies - 5. **Structured Response**: Use framework structure for analysis organization - - ## Framework Sections to Address - - Core Requirements (from API design perspective) - - Technical Considerations (detailed API architecture analysis) - - User Experience Factors (developer experience and API usability) - - Implementation Challenges (API design risks and solutions) - - Success Metrics (API performance metrics and adoption tracking) - - ## Output Structure Required - ```markdown - # API Designer Analysis: [Topic] - - **Framework Reference**: @../guidance-specification.md - **Role Focus**: Backend API Design and Contract Definition - - ## Core Requirements Analysis - [Address framework requirements from API design perspective] - - ## Technical Considerations - [Detailed API architecture and endpoint design analysis] - - ## Developer Experience Factors - [API usability, documentation, and integration ease] - - ## Implementation Challenges - [API design risks and mitigation strategies] - - ## Success Metrics - [API performance metrics, adoption rates, and developer satisfaction] - - ## API Design-Specific Recommendations - [Detailed API design recommendations and best practices] - ```", - description="Generate API designer framework-based analysis") -``` - -### Phase 4: Update Mechanism -**Analysis Update Process**: -```bash -# For existing analysis updates -IF update_mode = "incremental": - Task(subagent_type="conceptual-planning-agent", - run_in_background=false, - prompt="Update existing API designer analysis - - ## Current Analysis Context - **Existing Analysis**: @{session.brainstorm_dir}/api-designer/analysis.md - **Framework Reference**: @{session.brainstorm_dir}/guidance-specification.md - - ## Update Requirements - 1. **Preserve Structure**: Maintain existing analysis structure - 2. **Add New Insights**: Integrate new API design insights and recommendations - 3. **Framework Alignment**: Ensure continued alignment with topic framework - 4. **API Updates**: Add new endpoint patterns, versioning strategies, documentation improvements - 5. **Maintain References**: Keep @../guidance-specification.md reference - - ## Update Instructions - - Read existing analysis completely - - Identify areas for enhancement or new insights - - Add API design depth while preserving original structure - - Update recommendations with new API design patterns and approaches - - Maintain framework discussion point addressing", - description="Update API designer analysis incrementally") -``` - -## Document Structure - -### Output Files -``` -.workflow/active/WFS-[topic]/.brainstorming/ -├── guidance-specification.md # Input: Framework (if exists) -└── api-designer/ - └── analysis.md # ★ OUTPUT: Framework-based analysis -``` - -### Analysis Structure -**Required Elements**: -- **Framework Reference**: @../guidance-specification.md (if framework exists) -- **Role Focus**: Backend API Design and Contract Definition perspective -- **5 Framework Sections**: Address each framework discussion point -- **API Design Recommendations**: Endpoint-specific insights and solutions - -## ⚡ **Two-Step Execution Flow** - -### ⚠️ Session Management - FIRST STEP -Session detection and selection: -```bash -# Check for active sessions -active_sessions=$(find .workflow/active/ -name "WFS-*" -type d 2>/dev/null) -if [ multiple_sessions ]; then - prompt_user_to_select_session() -else - use_existing_or_create_new() -fi -``` - -### Step 1: Context Gathering Phase -**API Designer Perspective Questioning** - -Before agent assignment, gather comprehensive API design context: - -#### 📋 Role-Specific Questions -1. **API Type & Architecture** - - RESTful, GraphQL, or hybrid API approach? - - Synchronous vs asynchronous communication patterns? - - Real-time requirements (WebSocket, Server-Sent Events)? - -2. **Resource Modeling & Endpoints** - - What are the core domain resources/entities? - - Expected CRUD operations for each resource? - - Complex query requirements (filtering, sorting, pagination)? - -3. **Data Contracts & Validation** - - Request/response data format requirements (JSON, XML, Protocol Buffers)? - - Input validation and sanitization requirements? - - Data transformation and mapping needs? - -4. **API Management & Governance** - - API versioning strategy requirements? - - Authentication and authorization mechanisms? - - Rate limiting and throttling requirements? - - API documentation and developer portal needs? - -5. **Integration & Compatibility** - - Client platforms consuming the API (web, mobile, third-party)? - - Backward compatibility requirements? - - External API integrations needed? - -#### Context Validation -- **Minimum Response**: Each answer must be ≥50 characters -- **Re-prompting**: Insufficient detail triggers follow-up questions -- **Context Storage**: Save responses to `.brainstorming/api-designer-context.md` - -### Step 2: Agent Assignment with Flow Control -**Dedicated Agent Execution** - -```bash -Task(conceptual-planning-agent): " -[FLOW_CONTROL] - -Execute dedicated api-designer conceptual analysis for: {topic} - -ASSIGNED_ROLE: api-designer -OUTPUT_LOCATION: .brainstorming/api-designer/ -USER_CONTEXT: {validated_responses_from_context_gathering} - -Flow Control Steps: -[ - { - \"step\": \"load_role_template\", - \"action\": \"Load api-designer planning template\", - \"command\": \"bash($(cat ~/.claude/workflows/cli-templates/planning-roles/api-designer.md))\", - \"output_to\": \"role_template\" - } -] - -Conceptual Analysis Requirements: -- Apply api-designer perspective to topic analysis -- Focus on endpoint design, data contracts, and API governance -- Use loaded role template framework for analysis structure -- Generate role-specific deliverables in designated output location -- Address all user context from questioning phase - -Deliverables: -- analysis.md: Main API design analysis -- api-specification.md: Detailed endpoint specifications -- data-contracts.md: Request/response schemas and validation rules -- api-documentation.md: API documentation strategy and templates - -Embody api-designer role expertise for comprehensive conceptual planning." -``` - -### Progress Tracking -TodoWrite tracking for two-step process: -```json -[ - {"content": "Gather API designer context through role-specific questioning", "status": "in_progress", "activeForm": "Gathering context"}, - {"content": "Validate context responses and save to api-designer-context.md", "status": "pending", "activeForm": "Validating context"}, - {"content": "Load api-designer planning template via flow control", "status": "pending", "activeForm": "Loading template"}, - {"content": "Execute dedicated conceptual-planning-agent for api-designer role", "status": "pending", "activeForm": "Executing agent"} -] -``` - -## 📊 **Output Specification** - -### Output Location -``` -.workflow/active/WFS-{topic-slug}/.brainstorming/api-designer/ -├── analysis.md # Primary API design analysis -├── api-specification.md # Detailed endpoint specifications (OpenAPI/Swagger) -├── data-contracts.md # Request/response schemas and validation rules -├── versioning-strategy.md # API versioning and backward compatibility plan -└── developer-guide.md # API usage documentation and integration examples -``` - -### Document Templates - -#### analysis.md Structure -```markdown -# API Design Analysis: {Topic} -*Generated: {timestamp}* - -## Executive Summary -[Key API design findings and recommendations overview] - -## API Architecture Overview -### API Type Selection (REST/GraphQL/Hybrid) -### Communication Patterns -### Authentication & Authorization Strategy - -## Resource Modeling -### Core Domain Resources -### Resource Relationships -### URL Structure and Naming Conventions - -## Endpoint Design -### Resource Endpoints -- GET /api/v1/resources -- POST /api/v1/resources -- GET /api/v1/resources/{id} -- PUT /api/v1/resources/{id} -- DELETE /api/v1/resources/{id} - -### Query Parameters -- Filtering: ?filter[field]=value -- Sorting: ?sort=field,-field2 -- Pagination: ?page=1&limit=20 - -### HTTP Methods and Status Codes -- Success responses (2xx) -- Client errors (4xx) -- Server errors (5xx) - -## Data Contracts -### Request Schemas -[JSON Schema or OpenAPI definitions] - -### Response Schemas -[JSON Schema or OpenAPI definitions] - -### Validation Rules -- Required fields -- Data types and formats -- Business logic constraints - -## API Versioning Strategy -### Versioning Approach (URL/Header/Accept) -### Version Lifecycle Management -### Deprecation Policy -### Migration Paths - -## Security & Governance -### Authentication Mechanisms -- OAuth 2.0 / JWT / API Keys -### Authorization Patterns -- RBAC / ABAC / Resource-based -### Rate Limiting & Throttling -### CORS and Security Headers - -## Error Handling -### Standard Error Response Format -```json -{ - "error": { - "code": "ERROR_CODE", - "message": "Human-readable error message", - "details": [], - "trace_id": "uuid" - } -} -``` - -### Error Code Taxonomy -### Validation Error Responses - -## API Documentation -### OpenAPI/Swagger Specification -### Developer Portal Requirements -### Code Examples and SDKs -### Changelog and Migration Guides - -## Performance Optimization -### Response Caching Strategies -### Compression (gzip, brotli) -### Field Selection (sparse fieldsets) -### Bulk Operations and Batch Endpoints - -## Monitoring & Observability -### API Metrics -- Request count, latency, error rates -- Endpoint usage analytics -### Logging Strategy -### Distributed Tracing - -## Developer Experience -### API Usability Assessment -### Integration Complexity -### SDK and Client Library Needs -### Sandbox and Testing Environments -``` - -#### api-specification.md Structure -```markdown -# API Specification: {Topic} -*OpenAPI 3.0 Specification* - -## API Information -- **Title**: {API Name} -- **Version**: 1.0.0 -- **Base URL**: https://api.example.com/v1 -- **Contact**: api-team@example.com - -## Endpoints - -### Users API - -#### GET /users -**Description**: Retrieve a list of users - -**Parameters**: -- `page` (query, integer): Page number (default: 1) -- `limit` (query, integer): Items per page (default: 20, max: 100) -- `sort` (query, string): Sort field (e.g., "created_at", "-updated_at") -- `filter[status]` (query, string): Filter by user status - -**Response 200**: -```json -{ - "data": [ - { - "id": "uuid", - "username": "string", - "email": "string", - "created_at": "2025-10-15T00:00:00Z" - } - ], - "meta": { - "page": 1, - "limit": 20, - "total": 100 - }, - "links": { - "self": "/users?page=1", - "next": "/users?page=2", - "prev": null - } -} -``` - -#### POST /users -**Description**: Create a new user - -**Request Body**: -```json -{ - "username": "string (required, 3-50 chars)", - "email": "string (required, valid email)", - "password": "string (required, min 8 chars)", - "profile": { - "first_name": "string (optional)", - "last_name": "string (optional)" - } -} -``` - -**Response 201**: -```json -{ - "data": { - "id": "uuid", - "username": "string", - "email": "string", - "created_at": "2025-10-15T00:00:00Z" - } -} -``` - -**Response 400** (Validation Error): -```json -{ - "error": { - "code": "VALIDATION_ERROR", - "message": "Request validation failed", - "details": [ - { - "field": "email", - "message": "Invalid email format" - } - ] - } -} -``` - -[Continue for all endpoints...] - -## Authentication - -### OAuth 2.0 Flow -1. Client requests authorization -2. User grants permission -3. Client receives access token -4. Client uses token in requests - -**Header Format**: -``` -Authorization: Bearer {access_token} -``` - -## Rate Limiting - -**Headers**: -- `X-RateLimit-Limit`: 1000 -- `X-RateLimit-Remaining`: 999 -- `X-RateLimit-Reset`: 1634270400 - -**Response 429** (Too Many Requests): -```json -{ - "error": { - "code": "RATE_LIMIT_EXCEEDED", - "message": "API rate limit exceeded", - "retry_after": 3600 - } -} -``` -``` - -## 🔄 **Session Integration** - -### Status Synchronization -Upon completion, update `workflow-session.json`: -```json -{ - "phases": { - "BRAINSTORM": { - "api_designer": { - "status": "completed", - "completed_at": "timestamp", - "output_directory": ".workflow/active/WFS-{topic}/.brainstorming/api-designer/", - "key_insights": ["endpoint_design", "versioning_strategy", "data_contracts"] - } - } - } -} -``` - -### Cross-Role Collaboration -API designer perspective provides: -- **API Contract Specifications** → Frontend Developer -- **Data Schema Requirements** → Data Architect -- **Security Requirements** → Security Expert -- **Integration Endpoints** → System Architect -- **Performance Constraints** → DevOps Engineer - -## ✅ **Quality Assurance** - -### Required Analysis Elements -- [ ] Complete endpoint inventory with HTTP methods and paths -- [ ] Detailed request/response schemas with validation rules -- [ ] Clear versioning strategy and backward compatibility plan -- [ ] Comprehensive error handling and status code usage -- [ ] API documentation strategy (OpenAPI/Swagger) - -### API Design Principles -- [ ] **Consistency**: Uniform naming conventions and patterns across all endpoints -- [ ] **Simplicity**: Intuitive resource modeling and URL structures -- [ ] **Flexibility**: Support for filtering, sorting, pagination, and field selection -- [ ] **Security**: Proper authentication, authorization, and input validation -- [ ] **Performance**: Caching strategies, compression, and efficient data structures - -### Developer Experience Validation -- [ ] API is self-documenting with clear endpoint descriptions -- [ ] Error messages are actionable and helpful for debugging -- [ ] Response formats are consistent and predictable -- [ ] Code examples and integration guides are provided -- [ ] Sandbox environment available for testing - -### Technical Completeness -- [ ] **Resource Modeling**: All domain entities mapped to API resources -- [ ] **CRUD Coverage**: Complete create, read, update, delete operations -- [ ] **Query Capabilities**: Advanced filtering, sorting, and search functionality -- [ ] **Versioning**: Clear version management and migration paths -- [ ] **Monitoring**: API metrics, logging, and tracing strategies defined - -### Integration Readiness -- [ ] **Client Compatibility**: API works with all target client platforms -- [ ] **External Integration**: Third-party API dependencies identified -- [ ] **Backward Compatibility**: Changes don't break existing clients -- [ ] **Migration Path**: Clear upgrade paths for API consumers -- [ ] **SDK Support**: Client libraries and code generation considered diff --git a/.claude/commands/workflow/brainstorm/auto-parallel.md b/.claude/commands/workflow/brainstorm/auto-parallel.md index e84437c4..4f687571 100644 --- a/.claude/commands/workflow/brainstorm/auto-parallel.md +++ b/.claude/commands/workflow/brainstorm/auto-parallel.md @@ -132,55 +132,30 @@ SlashCommand(command="/workflow:brainstorm:artifacts \"{topic}\" --count {N}") ### Phase 2: Parallel Role Analysis Execution -**For Each Selected Role**: +**For Each Selected Role** (unified role-analysis command): ```bash -Task(conceptual-planning-agent): " -[FLOW_CONTROL] - -Execute {role-name} analysis for existing topic framework - -## Context Loading -ASSIGNED_ROLE: {role-name} -OUTPUT_LOCATION: .workflow/active/WFS-{session}/.brainstorming/{role}/ -TOPIC: {user-provided-topic} - -## Flow Control Steps -1. load_topic_framework → .workflow/active/WFS-{session}/.brainstorming/guidance-specification.md -2. load_role_template → ~/.claude/workflows/cli-templates/planning-roles/{role}.md -3. load_session_metadata → .workflow/active/WFS-{session}/workflow-session.json -4. load_style_skill (ui-designer only, if style_skill_package) → .claude/skills/style-{style_skill_package}/ - -## Analysis Requirements -**Primary Reference**: Original user prompt from workflow-session.json is authoritative -**Framework Source**: Address all discussion points in guidance-specification.md from {role-name} perspective -**Role Focus**: {role-name} domain expertise aligned with user intent -**Structured Approach**: Create analysis.md addressing framework discussion points -**Template Integration**: Apply role template guidelines within framework structure - -## Expected Deliverables -1. **analysis.md** (optionally with analysis-{slug}.md sub-documents) -2. **Framework Reference**: @../guidance-specification.md -3. **User Intent Alignment**: Validate against session_context - -## Completion Criteria -- Address each discussion point from guidance-specification.md with {role-name} expertise -- Provide actionable recommendations from {role-name} perspective within analysis files -- All output files MUST start with `analysis` prefix (no recommendations.md or other naming) -- Reference framework document using @ notation for integration -- Update workflow-session.json with completion status -" +SlashCommand(command="/workflow:brainstorm:role-analysis {role-name} --session {session-id} --skip-questions") ``` -**Parallel Execute**: -- Launch N agents simultaneously (one message with multiple Task calls) -- Each agent task **attached** to orchestrator's TodoWrite -- All agents execute concurrently, each attaching their own analysis sub-tasks -- Each agent operates independently reading same guidance-specification.md +**What It Does**: +- Unified command execution for each role +- Loads topic framework from guidance-specification.md +- Applies role-specific template and context +- Generates analysis.md addressing framework discussion points +- Supports optional interactive context gathering (via --include-questions flag) + +**Parallel Execution**: +- Launch N SlashCommand calls simultaneously (one message with multiple SlashCommand invokes) +- Each role command **attached** to orchestrator's TodoWrite +- All roles execute concurrently, each reading same guidance-specification.md +- Each role operates independently +- For ui-designer only: append `--style-skill {style_skill_package}` if provided **Input**: - `selected_roles[]` from Phase 1 - `session_id` from Phase 1 -- guidance-specification.md path +- `guidance-specification.md` (framework reference) +- `style_skill_package` (for ui-designer only) **Validation**: - Each role creates `.workflow/active/WFS-{topic}/.brainstorming/{role}/analysis.md` @@ -189,6 +164,7 @@ TOPIC: {user-provided-topic} - **FORBIDDEN**: `recommendations.md` or any non-`analysis` prefixed files - All N role analyses completed + **TodoWrite Update (Phase 2 agents executed - tasks attached in parallel)**: ```json [ diff --git a/.claude/commands/workflow/brainstorm/data-architect.md b/.claude/commands/workflow/brainstorm/data-architect.md deleted file mode 100644 index d6490dec..00000000 --- a/.claude/commands/workflow/brainstorm/data-architect.md +++ /dev/null @@ -1,220 +0,0 @@ ---- -name: data-architect -description: Generate or update data-architect/analysis.md addressing guidance-specification discussion points for data architecture perspective -argument-hint: "optional topic - uses existing framework if available" -allowed-tools: Task(conceptual-planning-agent), TodoWrite(*), Read(*), Write(*) ---- - -## 📊 **Data Architect Analysis Generator** - -### Purpose -**Specialized command for generating data-architect/analysis.md** that addresses guidance-specification.md discussion points from data architecture perspective. Creates or updates role-specific analysis with framework references. - -### Core Function -- **Framework-based Analysis**: Address each discussion point in guidance-specification.md -- **Data Architecture Focus**: Data models, pipelines, governance, and analytics perspective -- **Update Mechanism**: Create new or update existing analysis.md -- **Agent Delegation**: Use conceptual-planning-agent for analysis generation - -### Analysis Scope -- **Data Model Design**: Efficient and scalable data models and schemas -- **Data Flow Design**: Data collection, processing, and storage workflows -- **Data Quality Management**: Data accuracy, completeness, and consistency -- **Analytics and Insights**: Data analysis and business intelligence solutions - -### Role Boundaries & Responsibilities - -#### **What This Role OWNS (Canonical Data Model - Source of Truth)** -- **Canonical Data Model**: The authoritative, system-wide data schema representing domain entities and relationships -- **Entity-Relationship Design**: Defining entities, attributes, relationships, and constraints -- **Data Normalization & Optimization**: Ensuring data integrity, reducing redundancy, and optimizing storage -- **Database Schema Design**: Physical database structures, indexes, partitioning strategies -- **Data Pipeline Architecture**: ETL/ELT processes, data warehousing, and analytics pipelines -- **Data Governance**: Data quality standards, retention policies, and compliance requirements - -#### **What This Role DOES NOT Own (Defers to Other Roles)** -- **API Data Contracts**: Public-facing request/response schemas exposed by APIs → Defers to **API Designer** -- **System Integration Patterns**: How services communicate at the macro level → Defers to **System Architect** -- **UI Data Presentation**: How data is displayed to users → Defers to **UI Designer** - -#### **Handoff Points** -- **TO API Designer**: Provides canonical data model that API Designer translates into public API data contracts (as projection/view) -- **TO System Architect**: Provides data flow requirements and storage constraints to inform system design -- **FROM System Architect**: Receives system-level integration requirements and scalability constraints - -## ⚙️ **Execution Protocol** - -### Phase 1: Session & Framework Detection -```bash -# Check active session and framework -CHECK: find .workflow/active/ -name "WFS-*" -type d -IF active_session EXISTS: - session_id = get_active_session() - brainstorm_dir = .workflow/active/WFS-{session}/.brainstorming/ - - CHECK: brainstorm_dir/guidance-specification.md - IF EXISTS: - framework_mode = true - load_framework = true - ELSE: - IF topic_provided: - framework_mode = false # Create analysis without framework - ELSE: - ERROR: "No framework found and no topic provided" -``` - -### Phase 2: Analysis Mode Detection -```bash -# Determine execution mode -IF framework_mode == true: - mode = "framework_based_analysis" - topic_ref = load_framework_topic() - discussion_points = extract_framework_points() -ELSE: - mode = "standalone_analysis" - topic_ref = provided_topic - discussion_points = generate_basic_structure() -``` - -### Phase 3: Agent Execution with Flow Control -**Framework-Based Analysis Generation** - -```bash -Task(conceptual-planning-agent): " -[FLOW_CONTROL] - -Execute data-architect analysis for existing topic framework - -## Context Loading -ASSIGNED_ROLE: data-architect -OUTPUT_LOCATION: .workflow/active/WFS-{session}/.brainstorming/data-architect/ -ANALYSIS_MODE: {framework_mode ? "framework_based" : "standalone"} - -## Flow Control Steps -1. **load_topic_framework** - - Action: Load structured topic discussion framework - - Command: Read(.workflow/active/WFS-{session}/.brainstorming/guidance-specification.md) - - Output: topic_framework_content - -2. **load_role_template** - - Action: Load data-architect planning template - - Command: bash($(cat ~/.claude/workflows/cli-templates/planning-roles/data-architect.md)) - - Output: role_template_guidelines - -3. **load_session_metadata** - - Action: Load session metadata and existing context - - Command: Read(.workflow/active/WFS-{session}/workflow-session.json) - - Output: session_context - -## Analysis Requirements -**Framework Reference**: Address all discussion points in guidance-specification.md from data architecture perspective -**Role Focus**: Data models, pipelines, governance, analytics platforms -**Structured Approach**: Create analysis.md addressing framework discussion points -**Template Integration**: Apply role template guidelines within framework structure - -## Expected Deliverables -1. **analysis.md**: Comprehensive data architecture analysis addressing all framework discussion points -2. **Framework Reference**: Include @../guidance-specification.md reference in analysis - -## Completion Criteria -- Address each discussion point from guidance-specification.md with data architecture expertise -- Provide data model designs, pipeline architectures, and governance strategies -- Include scalability, performance, and quality considerations -- Reference framework document using @ notation for integration -" -``` - -## 📋 **TodoWrite Integration** - -### Workflow Progress Tracking -```javascript -TodoWrite({ - todos: [ - { - content: "Detect active session and locate topic framework", - status: "in_progress", - activeForm: "Detecting session and framework" - }, - { - content: "Load guidance-specification.md and session metadata for context", - status: "pending", - activeForm: "Loading framework and session context" - }, - { - content: "Execute data-architect analysis using conceptual-planning-agent with FLOW_CONTROL", - status: "pending", - activeForm: "Executing data-architect framework analysis" - }, - { - content: "Generate analysis.md addressing all framework discussion points", - status: "pending", - activeForm: "Generating structured data-architect analysis" - }, - { - content: "Update workflow-session.json with data-architect completion status", - status: "pending", - activeForm: "Updating session metadata" - } - ] -}); -``` - -## 📊 **Output Structure** - -### Framework-Based Analysis -``` -.workflow/active/WFS-{session}/.brainstorming/data-architect/ -└── analysis.md # Structured analysis addressing guidance-specification.md discussion points -``` - -### Analysis Document Structure -```markdown -# Data Architect Analysis: [Topic from Framework] - -## Framework Reference -**Topic Framework**: @../guidance-specification.md -**Role Focus**: Data Architecture perspective - -## Discussion Points Analysis -[Address each point from guidance-specification.md with data architecture expertise] - -### Core Requirements (from framework) -[Data architecture perspective on requirements] - -### Technical Considerations (from framework) -[Data model, pipeline, and storage considerations] - -### User Experience Factors (from framework) -[Data access patterns and analytics user experience] - -### Implementation Challenges (from framework) -[Data migration, quality, and governance challenges] - -### Success Metrics (from framework) -[Data quality metrics and analytics success criteria] - -## Data Architecture Specific Recommendations -[Role-specific data architecture recommendations and solutions] - ---- -*Generated by data-architect analysis addressing structured framework* -``` - -## 🔄 **Session Integration** - -### Completion Status Update -```json -{ - "data_architect": { - "status": "completed", - "framework_addressed": true, - "output_location": ".workflow/active/WFS-{session}/.brainstorming/data-architect/analysis.md", - "framework_reference": "@../guidance-specification.md" - } -} -``` - -### Integration Points -- **Framework Reference**: @../guidance-specification.md for structured discussion points -- **Cross-Role Synthesis**: Data architecture insights available for synthesis-report.md integration -- **Agent Autonomy**: Independent execution with framework guidance diff --git a/.claude/commands/workflow/brainstorm/product-manager.md b/.claude/commands/workflow/brainstorm/product-manager.md deleted file mode 100644 index 0c5806cf..00000000 --- a/.claude/commands/workflow/brainstorm/product-manager.md +++ /dev/null @@ -1,200 +0,0 @@ ---- -name: product-manager -description: Generate or update product-manager/analysis.md addressing guidance-specification discussion points for product management perspective -argument-hint: "optional topic - uses existing framework if available" -allowed-tools: Task(conceptual-planning-agent), TodoWrite(*), Read(*), Write(*) ---- - -## 🎯 **Product Manager Analysis Generator** - -### Purpose -**Specialized command for generating product-manager/analysis.md** that addresses guidance-specification.md discussion points from product strategy perspective. Creates or updates role-specific analysis with framework references. - -### Core Function -- **Framework-based Analysis**: Address each discussion point in guidance-specification.md -- **Product Strategy Focus**: User needs, business value, and market positioning -- **Update Mechanism**: Create new or update existing analysis.md -- **Agent Delegation**: Use conceptual-planning-agent for analysis generation - -### Analysis Scope -- **User Needs Analysis**: Target users, problems, and value propositions -- **Business Impact Assessment**: ROI, metrics, and commercial outcomes -- **Market Positioning**: Competitive analysis and differentiation -- **Product Strategy**: Roadmaps, priorities, and go-to-market approaches - -## ⚙️ **Execution Protocol** - -### Phase 1: Session & Framework Detection -```bash -# Check active session and framework -CHECK: find .workflow/active/ -name "WFS-*" -type d -IF active_session EXISTS: - session_id = get_active_session() - brainstorm_dir = .workflow/active/WFS-{session}/.brainstorming/ - - CHECK: brainstorm_dir/guidance-specification.md - IF EXISTS: - framework_mode = true - load_framework = true - ELSE: - IF topic_provided: - framework_mode = false # Create analysis without framework - ELSE: - ERROR: "No framework found and no topic provided" -``` - -### Phase 2: Analysis Mode Detection -```bash -# Determine execution mode -IF framework_mode == true: - mode = "framework_based_analysis" - topic_ref = load_framework_topic() - discussion_points = extract_framework_points() -ELSE: - mode = "standalone_analysis" - topic_ref = provided_topic - discussion_points = generate_basic_structure() -``` - -### Phase 3: Agent Execution with Flow Control -**Framework-Based Analysis Generation** - -```bash -Task(conceptual-planning-agent): " -[FLOW_CONTROL] - -Execute product-manager analysis for existing topic framework - -## Context Loading -ASSIGNED_ROLE: product-manager -OUTPUT_LOCATION: .workflow/active/WFS-{session}/.brainstorming/product-manager/ -ANALYSIS_MODE: {framework_mode ? "framework_based" : "standalone"} - -## Flow Control Steps -1. **load_topic_framework** - - Action: Load structured topic discussion framework - - Command: Read(.workflow/active/WFS-{session}/.brainstorming/guidance-specification.md) - - Output: topic_framework_content - -2. **load_role_template** - - Action: Load product-manager planning template - - Command: bash($(cat ~/.claude/workflows/cli-templates/planning-roles/product-manager.md)) - - Output: role_template_guidelines - -3. **load_session_metadata** - - Action: Load session metadata and existing context - - Command: Read(.workflow/active/WFS-{session}/workflow-session.json) - - Output: session_context - -## Analysis Requirements -**Framework Reference**: Address all discussion points in guidance-specification.md from product strategy perspective -**Role Focus**: User value, business impact, market positioning, product strategy -**Structured Approach**: Create analysis.md addressing framework discussion points -**Template Integration**: Apply role template guidelines within framework structure - -## Expected Deliverables -1. **analysis.md**: Comprehensive product strategy analysis addressing all framework discussion points -2. **Framework Reference**: Include @../guidance-specification.md reference in analysis - -## Completion Criteria -- Address each discussion point from guidance-specification.md with product management expertise -- Provide actionable business strategies and user value propositions -- Include market analysis and competitive positioning insights -- Reference framework document using @ notation for integration -" -``` - -## 📋 **TodoWrite Integration** - -### Workflow Progress Tracking -```javascript -TodoWrite({ - todos: [ - { - content: "Detect active session and locate topic framework", - status: "in_progress", - activeForm: "Detecting session and framework" - }, - { - content: "Load guidance-specification.md and session metadata for context", - status: "pending", - activeForm: "Loading framework and session context" - }, - { - content: "Execute product-manager analysis using conceptual-planning-agent with FLOW_CONTROL", - status: "pending", - activeForm: "Executing product-manager framework analysis" - }, - { - content: "Generate analysis.md addressing all framework discussion points", - status: "pending", - activeForm: "Generating structured product-manager analysis" - }, - { - content: "Update workflow-session.json with product-manager completion status", - status: "pending", - activeForm: "Updating session metadata" - } - ] -}); -``` - -## 📊 **Output Structure** - -### Framework-Based Analysis -``` -.workflow/active/WFS-{session}/.brainstorming/product-manager/ -└── analysis.md # Structured analysis addressing guidance-specification.md discussion points -``` - -### Analysis Document Structure -```markdown -# Product Manager Analysis: [Topic from Framework] - -## Framework Reference -**Topic Framework**: @../guidance-specification.md -**Role Focus**: Product Strategy perspective - -## Discussion Points Analysis -[Address each point from guidance-specification.md with product management expertise] - -### Core Requirements (from framework) -[Product strategy perspective on user needs and requirements] - -### Technical Considerations (from framework) -[Business and technical feasibility considerations] - -### User Experience Factors (from framework) -[User value proposition and market positioning analysis] - -### Implementation Challenges (from framework) -[Business execution and go-to-market considerations] - -### Success Metrics (from framework) -[Product success metrics and business KPIs] - -## Product Strategy Specific Recommendations -[Role-specific product management strategies and business solutions] - ---- -*Generated by product-manager analysis addressing structured framework* -``` - -## 🔄 **Session Integration** - -### Completion Status Update -```json -{ - "product_manager": { - "status": "completed", - "framework_addressed": true, - "output_location": ".workflow/active/WFS-{session}/.brainstorming/product-manager/analysis.md", - "framework_reference": "@../guidance-specification.md" - } -} -``` - -### Integration Points -- **Framework Reference**: @../guidance-specification.md for structured discussion points -- **Cross-Role Synthesis**: Product strategy insights available for synthesis-report.md integration -- **Agent Autonomy**: Independent execution with framework guidance diff --git a/.claude/commands/workflow/brainstorm/product-owner.md b/.claude/commands/workflow/brainstorm/product-owner.md deleted file mode 100644 index 639b3c2f..00000000 --- a/.claude/commands/workflow/brainstorm/product-owner.md +++ /dev/null @@ -1,200 +0,0 @@ ---- -name: product-owner -description: Generate or update product-owner/analysis.md addressing guidance-specification discussion points for product ownership perspective -argument-hint: "optional topic - uses existing framework if available" -allowed-tools: Task(conceptual-planning-agent), TodoWrite(*), Read(*), Write(*) ---- - -## 🎯 **Product Owner Analysis Generator** - -### Purpose -**Specialized command for generating product-owner/analysis.md** that addresses guidance-specification.md discussion points from product backlog and feature prioritization perspective. Creates or updates role-specific analysis with framework references. - -### Core Function -- **Framework-based Analysis**: Address each discussion point in guidance-specification.md -- **Product Backlog Focus**: Feature prioritization, user stories, and acceptance criteria -- **Update Mechanism**: Create new or update existing analysis.md -- **Agent Delegation**: Use conceptual-planning-agent for analysis generation - -### Analysis Scope -- **Backlog Management**: User story creation, refinement, and prioritization -- **Stakeholder Alignment**: Requirements gathering, value definition, and expectation management -- **Feature Prioritization**: ROI analysis, MoSCoW method, and value-driven delivery -- **Acceptance Criteria**: Definition of Done, acceptance testing, and quality standards - -## ⚙️ **Execution Protocol** - -### Phase 1: Session & Framework Detection -```bash -# Check active session and framework -CHECK: find .workflow/active/ -name "WFS-*" -type d -IF active_session EXISTS: - session_id = get_active_session() - brainstorm_dir = .workflow/active/WFS-{session}/.brainstorming/ - - CHECK: brainstorm_dir/guidance-specification.md - IF EXISTS: - framework_mode = true - load_framework = true - ELSE: - IF topic_provided: - framework_mode = false # Create analysis without framework - ELSE: - ERROR: "No framework found and no topic provided" -``` - -### Phase 2: Analysis Mode Detection -```bash -# Determine execution mode -IF framework_mode == true: - mode = "framework_based_analysis" - topic_ref = load_framework_topic() - discussion_points = extract_framework_points() -ELSE: - mode = "standalone_analysis" - topic_ref = provided_topic - discussion_points = generate_basic_structure() -``` - -### Phase 3: Agent Execution with Flow Control -**Framework-Based Analysis Generation** - -```bash -Task(conceptual-planning-agent): " -[FLOW_CONTROL] - -Execute product-owner analysis for existing topic framework - -## Context Loading -ASSIGNED_ROLE: product-owner -OUTPUT_LOCATION: .workflow/active/WFS-{session}/.brainstorming/product-owner/ -ANALYSIS_MODE: {framework_mode ? "framework_based" : "standalone"} - -## Flow Control Steps -1. **load_topic_framework** - - Action: Load structured topic discussion framework - - Command: Read(.workflow/active/WFS-{session}/.brainstorming/guidance-specification.md) - - Output: topic_framework_content - -2. **load_role_template** - - Action: Load product-owner planning template - - Command: bash($(cat ~/.claude/workflows/cli-templates/planning-roles/product-owner.md)) - - Output: role_template_guidelines - -3. **load_session_metadata** - - Action: Load session metadata and existing context - - Command: Read(.workflow/active/WFS-{session}/workflow-session.json) - - Output: session_context - -## Analysis Requirements -**Framework Reference**: Address all discussion points in guidance-specification.md from product backlog and feature prioritization perspective -**Role Focus**: Backlog management, stakeholder alignment, feature prioritization, acceptance criteria -**Structured Approach**: Create analysis.md addressing framework discussion points -**Template Integration**: Apply role template guidelines within framework structure - -## Expected Deliverables -1. **analysis.md**: Comprehensive product ownership analysis addressing all framework discussion points -2. **Framework Reference**: Include @../guidance-specification.md reference in analysis - -## Completion Criteria -- Address each discussion point from guidance-specification.md with product ownership expertise -- Provide actionable user stories and acceptance criteria definitions -- Include feature prioritization and stakeholder alignment strategies -- Reference framework document using @ notation for integration -" -``` - -## 📋 **TodoWrite Integration** - -### Workflow Progress Tracking -```javascript -TodoWrite({ - todos: [ - { - content: "Detect active session and locate topic framework", - status: "in_progress", - activeForm: "Detecting session and framework" - }, - { - content: "Load guidance-specification.md and session metadata for context", - status: "pending", - activeForm: "Loading framework and session context" - }, - { - content: "Execute product-owner analysis using conceptual-planning-agent with FLOW_CONTROL", - status: "pending", - activeForm: "Executing product-owner framework analysis" - }, - { - content: "Generate analysis.md addressing all framework discussion points", - status: "pending", - activeForm: "Generating structured product-owner analysis" - }, - { - content: "Update workflow-session.json with product-owner completion status", - status: "pending", - activeForm: "Updating session metadata" - } - ] -}); -``` - -## 📊 **Output Structure** - -### Framework-Based Analysis -``` -.workflow/active/WFS-{session}/.brainstorming/product-owner/ -└── analysis.md # Structured analysis addressing guidance-specification.md discussion points -``` - -### Analysis Document Structure -```markdown -# Product Owner Analysis: [Topic from Framework] - -## Framework Reference -**Topic Framework**: @../guidance-specification.md -**Role Focus**: Product Backlog & Feature Prioritization perspective - -## Discussion Points Analysis -[Address each point from guidance-specification.md with product ownership expertise] - -### Core Requirements (from framework) -[User story formulation and backlog refinement perspective] - -### Technical Considerations (from framework) -[Technical feasibility and implementation sequencing considerations] - -### User Experience Factors (from framework) -[User value definition and acceptance criteria analysis] - -### Implementation Challenges (from framework) -[Sprint planning, dependency management, and delivery strategies] - -### Success Metrics (from framework) -[Feature adoption, value delivery metrics, and stakeholder satisfaction indicators] - -## Product Owner Specific Recommendations -[Role-specific backlog management and feature prioritization strategies] - ---- -*Generated by product-owner analysis addressing structured framework* -``` - -## 🔄 **Session Integration** - -### Completion Status Update -```json -{ - "product_owner": { - "status": "completed", - "framework_addressed": true, - "output_location": ".workflow/active/WFS-{session}/.brainstorming/product-owner/analysis.md", - "framework_reference": "@../guidance-specification.md" - } -} -``` - -### Integration Points -- **Framework Reference**: @../guidance-specification.md for structured discussion points -- **Cross-Role Synthesis**: Product ownership insights available for synthesis-report.md integration -- **Agent Autonomy**: Independent execution with framework guidance diff --git a/.claude/commands/workflow/brainstorm/role-analysis.md b/.claude/commands/workflow/brainstorm/role-analysis.md new file mode 100644 index 00000000..debda864 --- /dev/null +++ b/.claude/commands/workflow/brainstorm/role-analysis.md @@ -0,0 +1,705 @@ +--- +name: role-analysis +description: Unified role-specific analysis generation with interactive context gathering and incremental updates +argument-hint: "[role-name] [--session session-id] [--update] [--include-questions] [--skip-questions]" +allowed-tools: Task(conceptual-planning-agent), AskUserQuestion(*), TodoWrite(*), Read(*), Write(*), Edit(*), Glob(*) +--- + +## 🎯 **Unified Role Analysis Generator** + +### Purpose +**Unified command for generating and updating role-specific analysis** with interactive context gathering, framework alignment, and incremental update support. Replaces 9 individual role commands with single parameterized workflow. + +### Core Function +- **Multi-Role Support**: Single command supports all 9 brainstorming roles +- **Interactive Context**: Dynamic question generation based on role and framework +- **Incremental Updates**: Merge new insights into existing analyses +- **Framework Alignment**: Address guidance-specification.md discussion points +- **Agent Delegation**: Use conceptual-planning-agent with role-specific templates + +### Supported Roles + +| Role ID | Title | Focus Area | Context Questions | +|---------|-------|------------|-------------------| +| `ux-expert` | UX专家 | User research, information architecture, user journey | 4 | +| `ui-designer` | UI设计师 | Visual design, high-fidelity mockups, design systems | 4 | +| `system-architect` | 系统架构师 | Technical architecture, scalability, integration patterns | 5 | +| `product-manager` | 产品经理 | Product strategy, roadmap, prioritization | 4 | +| `product-owner` | 产品负责人 | Backlog management, user stories, acceptance criteria | 4 | +| `scrum-master` | 敏捷教练 | Process facilitation, impediment removal, team dynamics | 3 | +| `subject-matter-expert` | 领域专家 | Domain knowledge, business rules, compliance | 4 | +| `data-architect` | 数据架构师 | Data models, storage strategies, data flow | 5 | +| `api-designer` | API设计师 | API contracts, versioning, integration patterns | 4 | + +--- + +## 📋 **Usage** + +```bash +# Generate new analysis with interactive context +/workflow:brainstorm:role-analysis ux-expert + +# Generate with existing framework + context questions +/workflow:brainstorm:role-analysis system-architect --session WFS-xxx --include-questions + +# Update existing analysis (incremental merge) +/workflow:brainstorm:role-analysis ui-designer --session WFS-xxx --update + +# Quick generation (skip interactive context) +/workflow:brainstorm:role-analysis product-manager --session WFS-xxx --skip-questions +``` + +--- + +## ⚙️ **Execution Protocol** + +### Phase 1: Detection & Validation + +**Step 1.1: Role Validation** +```bash +VALIDATE role_name IN [ + ux-expert, ui-designer, system-architect, product-manager, + product-owner, scrum-master, subject-matter-expert, + data-architect, api-designer +] +IF invalid: + ERROR: "Unknown role: {role_name}. Use one of: ux-expert, ui-designer, ..." + EXIT +``` + +**Step 1.2: Session Detection** +```bash +IF --session PROVIDED: + session_id = --session + brainstorm_dir = .workflow/active/{session_id}/.brainstorming/ +ELSE: + FIND .workflow/active/WFS-*/ + IF multiple: + PROMPT user to select + ELSE IF single: + USE existing + ELSE: + ERROR: "No active session. Run /workflow:brainstorm:artifacts first" + EXIT + +VALIDATE brainstorm_dir EXISTS +``` + +**Step 1.3: Framework Detection** +```bash +framework_file = {brainstorm_dir}/guidance-specification.md +IF framework_file EXISTS: + framework_mode = true + LOAD framework_content +ELSE: + WARN: "No framework found - will create standalone analysis" + framework_mode = false +``` + +**Step 1.4: Update Mode Detection** +```bash +existing_analysis = {brainstorm_dir}/{role_name}/analysis*.md +IF --update FLAG OR existing_analysis EXISTS: + update_mode = true + IF --update NOT PROVIDED: + ASK: "Analysis exists. Update or regenerate?" + OPTIONS: ["Incremental update", "Full regenerate", "Cancel"] +ELSE: + update_mode = false +``` + +### Phase 2: Interactive Context Gathering + +**Trigger Conditions**: +- Default: Always ask unless `--skip-questions` provided +- `--include-questions`: Force context gathering even if analysis exists +- `--skip-questions`: Skip all interactive questions + +**Step 2.1: Load Role Configuration** +```javascript +const roleConfig = { + 'ux-expert': { + title: 'UX专家', + focus_area: 'User research, information architecture, user journey', + question_categories: ['User Intent', 'Requirements', 'UX'], + question_count: 4, + template: '~/.claude/workflows/cli-templates/planning-roles/ux-expert.md' + }, + 'ui-designer': { + title: 'UI设计师', + focus_area: 'Visual design, high-fidelity mockups, design systems', + question_categories: ['Requirements', 'UX', 'Feasibility'], + question_count: 4, + template: '~/.claude/workflows/cli-templates/planning-roles/ui-designer.md' + }, + 'system-architect': { + title: '系统架构师', + focus_area: 'Technical architecture, scalability, integration patterns', + question_categories: ['Scale & Performance', 'Technical Constraints', 'Architecture Complexity', 'Non-Functional Requirements'], + question_count: 5, + template: '~/.claude/workflows/cli-templates/planning-roles/system-architect.md' + }, + 'product-manager': { + title: '产品经理', + focus_area: 'Product strategy, roadmap, prioritization', + question_categories: ['User Intent', 'Requirements', 'Process'], + question_count: 4, + template: '~/.claude/workflows/cli-templates/planning-roles/product-manager.md' + }, + 'product-owner': { + title: '产品负责人', + focus_area: 'Backlog management, user stories, acceptance criteria', + question_categories: ['Requirements', 'Decisions', 'Process'], + question_count: 4, + template: '~/.claude/workflows/cli-templates/planning-roles/product-owner.md' + }, + 'scrum-master': { + title: '敏捷教练', + focus_area: 'Process facilitation, impediment removal, team dynamics', + question_categories: ['Process', 'Risk', 'Decisions'], + question_count: 3, + template: '~/.claude/workflows/cli-templates/planning-roles/scrum-master.md' + }, + 'subject-matter-expert': { + title: '领域专家', + focus_area: 'Domain knowledge, business rules, compliance', + question_categories: ['Requirements', 'Feasibility', 'Terminology'], + question_count: 4, + template: '~/.claude/workflows/cli-templates/planning-roles/subject-matter-expert.md' + }, + 'data-architect': { + title: '数据架构师', + focus_area: 'Data models, storage strategies, data flow', + question_categories: ['Architecture', 'Scale & Performance', 'Technical Constraints', 'Feasibility'], + question_count: 5, + template: '~/.claude/workflows/cli-templates/planning-roles/data-architect.md' + }, + 'api-designer': { + title: 'API设计师', + focus_area: 'API contracts, versioning, integration patterns', + question_categories: ['Architecture', 'Requirements', 'Feasibility', 'Decisions'], + question_count: 4, + template: '~/.claude/workflows/cli-templates/planning-roles/api-designer.md' + } +}; + +config = roleConfig[role_name]; +``` + +**Step 2.2: Generate Role-Specific Questions** + +**9-Category Taxonomy** (from synthesis.md): + +| Category | Focus | Example Question Pattern | +|----------|-------|--------------------------| +| User Intent | 用户目标 | "该分析的核心目标是什么?" | +| Requirements | 需求细化 | "需求的优先级如何排序?" | +| Architecture | 架构决策 | "技术栈的选择考量?" | +| UX | 用户体验 | "交互复杂度的取舍?" | +| Feasibility | 可行性 | "资源约束下的实现范围?" | +| Risk | 风险管理 | "风险容忍度是多少?" | +| Process | 流程规范 | "开发迭代的节奏?" | +| Decisions | 决策确认 | "冲突的解决方案?" | +| Terminology | 术语统一 | "统一使用哪个术语?" | +| Scale & Performance | 性能扩展 | "预期的负载和性能要求?" | +| Technical Constraints | 技术约束 | "现有技术栈的限制?" | +| Architecture Complexity | 架构复杂度 | "架构的复杂度权衡?" | +| Non-Functional Requirements | 非功能需求 | "可用性和可维护性要求?" | + +**Question Generation Algorithm**: +```javascript +async function generateQuestions(role_name, framework_content) { + const config = roleConfig[role_name]; + const questions = []; + + // Parse framework for keywords + const keywords = extractKeywords(framework_content); + + // Generate category-specific questions + for (const category of config.question_categories) { + const question = generateCategoryQuestion(category, keywords, role_name); + questions.push(question); + } + + return questions.slice(0, config.question_count); +} +``` + +**Step 2.3: Multi-Round Question Execution** + +```javascript +const BATCH_SIZE = 4; +const user_context = {}; + +for (let i = 0; i < questions.length; i += BATCH_SIZE) { + const batch = questions.slice(i, i + BATCH_SIZE); + const currentRound = Math.floor(i / BATCH_SIZE) + 1; + const totalRounds = Math.ceil(questions.length / BATCH_SIZE); + + console.log(`\n[Round ${currentRound}/${totalRounds}] ${config.title} 上下文询问\n`); + + AskUserQuestion({ + questions: batch.map(q => ({ + question: q.question, + header: q.category.substring(0, 12), + multiSelect: false, + options: q.options.map(opt => ({ + label: opt.label, + description: opt.description + })) + })) + }); + + // Store responses before next round + for (const answer of responses) { + user_context[answer.question] = { + answer: answer.selected, + category: answer.category, + timestamp: new Date().toISOString() + }; + } +} + +// Save context to file +Write( + `${brainstorm_dir}/${role_name}/${role_name}-context.md`, + formatUserContext(user_context) +); +``` + +**Question Quality Rules** (from artifacts.md): + +**MUST Include**: +- ✅ All questions in Chinese (用中文提问) +- ✅ 业务场景作为问题前提 +- ✅ 技术选项的业务影响说明 +- ✅ 量化指标和约束条件 + +**MUST Avoid**: +- ❌ 纯技术选型无业务上下文 +- ❌ 过度抽象的通用问题 +- ❌ 脱离框架的重复询问 + +### Phase 3: Agent Execution + +**Step 3.1: Load Session Metadata** +```bash +session_metadata = Read(.workflow/active/{session_id}/workflow-session.json) +original_topic = session_metadata.topic +selected_roles = session_metadata.selected_roles +``` + +**Step 3.2: Prepare Agent Context** +```javascript +const agentContext = { + role_name: role_name, + role_config: roleConfig[role_name], + output_location: `${brainstorm_dir}/${role_name}/`, + framework_mode: framework_mode, + framework_path: framework_mode ? `${brainstorm_dir}/guidance-specification.md` : null, + update_mode: update_mode, + user_context: user_context, + original_topic: original_topic, + session_id: session_id +}; +``` + +**Step 3.3: Execute Conceptual Planning Agent** + +**Framework-Based Analysis** (when guidance-specification.md exists): +```javascript +Task( + subagent_type="conceptual-planning-agent", + run_in_background=false, + description=`Generate ${role_name} analysis`, + prompt=` +[FLOW_CONTROL] + +Execute ${role_name} analysis for existing topic framework + +## Context Loading +ASSIGNED_ROLE: ${role_name} +OUTPUT_LOCATION: ${agentContext.output_location} +ANALYSIS_MODE: ${framework_mode ? "framework_based" : "standalone"} +UPDATE_MODE: ${update_mode} + +## Flow Control Steps +1. **load_topic_framework** + - Action: Load structured topic discussion framework + - Command: Read(${agentContext.framework_path}) + - Output: topic_framework_content + +2. **load_role_template** + - Action: Load ${role_name} planning template + - Command: Read(${roleConfig[role_name].template}) + - Output: role_template_guidelines + +3. **load_session_metadata** + - Action: Load session metadata and user intent + - Command: Read(.workflow/active/${session_id}/workflow-session.json) + - Output: session_context + +4. **load_user_context** (if exists) + - Action: Load interactive context responses + - Command: Read(${brainstorm_dir}/${role_name}/${role_name}-context.md) + - Output: user_context_answers + +5. **${update_mode ? 'load_existing_analysis' : 'skip'}** + ${update_mode ? ` + - Action: Load existing analysis for incremental update + - Command: Read(${brainstorm_dir}/${role_name}/analysis.md) + - Output: existing_analysis_content + ` : ''} + +## Analysis Requirements +**Primary Reference**: Original user prompt from workflow-session.json is authoritative +**Framework Source**: Address all discussion points in guidance-specification.md from ${role_name} perspective +**User Context Integration**: Incorporate interactive Q&A responses into analysis +**Role Focus**: ${roleConfig[role_name].focus_area} +**Template Integration**: Apply role template guidelines within framework structure + +## Expected Deliverables +1. **analysis.md** (main document, optionally with analysis-{slug}.md sub-documents) +2. **Framework Reference**: @../guidance-specification.md (if framework_mode) +3. **User Context Reference**: @./${role_name}-context.md (if user context exists) +4. **User Intent Alignment**: Validate against session_context + +## Update Requirements (if UPDATE_MODE) +- **Preserve Structure**: Maintain existing analysis structure +- **Add "Clarifications" Section**: Document new user context with timestamp +- **Merge Insights**: Integrate new perspectives without removing existing content +- **Resolve Conflicts**: If new context contradicts existing analysis, document both and recommend resolution + +## Completion Criteria +- Address each discussion point from guidance-specification.md with ${role_name} expertise +- Provide actionable recommendations from ${role_name} perspective within analysis files +- All output files MUST start with "analysis" prefix (no recommendations.md or other naming) +- Reference framework document using @ notation for integration +- Update workflow-session.json with completion status +` +); +``` + +### Phase 4: Validation & Finalization + +**Step 4.1: Validate Output** +```bash +VERIFY EXISTS: ${brainstorm_dir}/${role_name}/analysis.md +VERIFY CONTAINS: "@../guidance-specification.md" (if framework_mode) +IF user_context EXISTS: + VERIFY CONTAINS: "@./${role_name}-context.md" OR "## Clarifications" section +``` + +**Step 4.2: Update Session Metadata** +```json +{ + "phases": { + "BRAINSTORM": { + "${role_name}": { + "status": "${update_mode ? 'updated' : 'completed'}", + "completed_at": "timestamp", + "framework_addressed": true, + "context_gathered": user_context ? true : false, + "output_location": "${brainstorm_dir}/${role_name}/analysis.md", + "update_history": [ + { + "timestamp": "ISO8601", + "mode": "${update_mode ? 'incremental' : 'initial'}", + "context_questions": question_count + } + ] + } + } + } +} +``` + +**Step 4.3: Completion Report** +```markdown +✅ ${roleConfig[role_name].title} Analysis Complete + +**Output**: ${brainstorm_dir}/${role_name}/analysis.md +**Mode**: ${update_mode ? 'Incremental Update' : 'New Generation'} +**Framework**: ${framework_mode ? '✓ Aligned' : '✗ Standalone'} +**Context Questions**: ${question_count} answered + +${update_mode ? ' +**Changes**: +- Added "Clarifications" section with new user context +- Merged new insights into existing sections +- Resolved conflicts with framework alignment +' : ''} + +**Next Steps**: +${selected_roles.length > 1 ? ` + - Continue with other roles: ${selected_roles.filter(r => r !== role_name).join(', ')} + - Run synthesis: /workflow:brainstorm:synthesis --session ${session_id} +` : ` + - Clarify insights: /workflow:brainstorm:synthesis --session ${session_id} + - Generate plan: /workflow:plan --session ${session_id} +`} +``` + +--- + +## 📋 **TodoWrite Integration** + +### Workflow Progress Tracking + +```javascript +TodoWrite({ + todos: [ + { + content: "Phase 1: Detect session and validate role configuration", + status: "in_progress", + activeForm: "Detecting session and role" + }, + { + content: "Phase 2: Interactive context gathering with AskUserQuestion", + status: "pending", + activeForm: "Gathering user context" + }, + { + content: "Phase 3: Execute conceptual-planning-agent for role analysis", + status: "pending", + activeForm: "Executing agent analysis" + }, + { + content: "Phase 4: Validate output and update session metadata", + status: "pending", + activeForm: "Finalizing and validating" + } + ] +}); +``` + +--- + +## 📊 **Output Structure** + +### Directory Layout + +``` +.workflow/active/WFS-{session}/.brainstorming/ +├── guidance-specification.md # Framework (if exists) +└── {role-name}/ + ├── {role-name}-context.md # Interactive Q&A responses + ├── analysis.md # Main analysis (REQUIRED) + └── analysis-{slug}.md # Section documents (optional, max 5) +``` + +### Analysis Document Structure (New Generation) + +```markdown +# ${roleConfig[role_name].title} Analysis: [Topic from Framework] + +## Framework Reference +**Topic Framework**: @../guidance-specification.md +**Role Focus**: ${roleConfig[role_name].focus_area} +**User Context**: @./${role_name}-context.md + +## User Context Summary +**Context Gathered**: ${question_count} questions answered +**Categories**: ${question_categories.join(', ')} + +${user_context ? formatContextSummary(user_context) : ''} + +## Discussion Points Analysis +[Address each point from guidance-specification.md with ${role_name} expertise] + +### Core Requirements (from framework) +[Role-specific perspective on requirements] + +### Technical Considerations (from framework) +[Role-specific technical analysis] + +### User Experience Factors (from framework) +[Role-specific UX considerations] + +### Implementation Challenges (from framework) +[Role-specific challenges and solutions] + +### Success Metrics (from framework) +[Role-specific metrics and KPIs] + +## ${roleConfig[role_name].title} Specific Recommendations +[Role-specific actionable strategies] + +--- +*Generated by ${role_name} analysis addressing structured framework* +*Context gathered: ${new Date().toISOString()}* +``` + +### Analysis Document Structure (Incremental Update) + +```markdown +# ${roleConfig[role_name].title} Analysis: [Topic] + +## Framework Reference +[Existing content preserved] + +## Clarifications +### Session ${new Date().toISOString().split('T')[0]} +${Object.entries(user_context).map(([q, a]) => ` +- **Q**: ${q} (Category: ${a.category}) + **A**: ${a.answer} +`).join('\n')} + +## User Context Summary +[Updated with new context] + +## Discussion Points Analysis +[Existing content enhanced with new insights] + +[Rest of sections updated based on clarifications] +``` + +--- + +## 🔄 **Integration with Other Commands** + +### Called By +- `/workflow:brainstorm:auto-parallel` (Phase 2 - parallel role execution) +- Manual invocation for single-role analysis + +### Calls To +- `conceptual-planning-agent` (agent execution) +- `AskUserQuestion` (interactive context gathering) + +### Coordinates With +- `/workflow:brainstorm:artifacts` (creates framework for role analysis) +- `/workflow:brainstorm:synthesis` (reads role analyses for integration) + +--- + +## ✅ **Quality Assurance** + +### Required Analysis Elements +- [ ] Framework discussion points addressed (if framework_mode) +- [ ] User context integrated (if context gathered) +- [ ] Role template guidelines applied +- [ ] Output files follow naming convention (analysis*.md only) +- [ ] Framework reference using @ notation +- [ ] Session metadata updated + +### Context Quality +- [ ] Questions in Chinese with business context +- [ ] Options include technical trade-offs +- [ ] Categories aligned with role focus +- [ ] No generic questions unrelated to framework + +### Update Quality (if update_mode) +- [ ] "Clarifications" section added with timestamp +- [ ] New insights merged without content loss +- [ ] Conflicts documented and resolved +- [ ] Framework alignment maintained + +--- + +## 🎛️ **Command Parameters** + +### Required Parameters +- `[role-name]`: Role identifier (ux-expert, ui-designer, system-architect, etc.) + +### Optional Parameters +- `--session [session-id]`: Specify brainstorming session (auto-detect if omitted) +- `--update`: Force incremental update mode (auto-detect if analysis exists) +- `--include-questions`: Force context gathering even if analysis exists +- `--skip-questions`: Skip all interactive context gathering +- `--style-skill [package]`: For ui-designer only, load style SKILL package + +### Parameter Combinations + +| Scenario | Command | Behavior | +|----------|---------|----------| +| New analysis | `role-analysis ux-expert` | Generate + ask context questions | +| Quick generation | `role-analysis ux-expert --skip-questions` | Generate without context | +| Update existing | `role-analysis ux-expert --update` | Ask clarifications + merge | +| Force questions | `role-analysis ux-expert --include-questions` | Ask even if exists | +| Specific session | `role-analysis ux-expert --session WFS-xxx` | Target specific session | + +--- + +## 🚫 **Error Handling** + +### Invalid Role Name +``` +ERROR: Unknown role: "ui-expert" +Valid roles: ux-expert, ui-designer, system-architect, product-manager, + product-owner, scrum-master, subject-matter-expert, + data-architect, api-designer +``` + +### No Active Session +``` +ERROR: No active brainstorming session found +Run: /workflow:brainstorm:artifacts "[topic]" to create session +``` + +### Missing Framework (with warning) +``` +WARN: No guidance-specification.md found +Generating standalone analysis without framework alignment +Recommend: Run /workflow:brainstorm:artifacts first for better results +``` + +### Agent Execution Failure +``` +ERROR: Conceptual planning agent failed +Check: ${brainstorm_dir}/${role_name}/error.log +Action: Retry with --skip-questions or check framework validity +``` + +--- + +## 🔧 **Advanced Usage** + +### Batch Role Generation (via auto-parallel) +```bash +# This command handles multiple roles in parallel +/workflow:brainstorm:auto-parallel "topic" --count 3 +# → Internally calls role-analysis for each selected role +``` + +### Manual Multi-Role Workflow +```bash +# 1. Create framework +/workflow:brainstorm:artifacts "Build real-time collaboration platform" --count 3 + +# 2. Generate each role with context +/workflow:brainstorm:role-analysis system-architect --include-questions +/workflow:brainstorm:role-analysis ui-designer --include-questions +/workflow:brainstorm:role-analysis product-manager --include-questions + +# 3. Synthesize insights +/workflow:brainstorm:synthesis --session WFS-xxx +``` + +### Iterative Refinement +```bash +# Initial generation +/workflow:brainstorm:role-analysis ux-expert + +# User reviews and wants more depth +/workflow:brainstorm:role-analysis ux-expert --update --include-questions +# → Asks clarification questions, merges new insights +``` + +--- + +## 📚 **Reference Information** + +### Role Template Locations +- Templates: `~/.claude/workflows/cli-templates/planning-roles/` +- Format: `{role-name}.md` (e.g., `ux-expert.md`, `system-architect.md`) + +### Related Commands +- `/workflow:brainstorm:artifacts` - Create framework and select roles +- `/workflow:brainstorm:auto-parallel` - Parallel multi-role execution +- `/workflow:brainstorm:synthesis` - Integrate role analyses +- `/workflow:plan` - Generate implementation plan from synthesis + +### Context Package +- Location: `.workflow/active/WFS-{session}/.process/context-package.json` +- Used by: `context-search-agent` (Phase 0 of artifacts) +- Contains: Project context, tech stack, conflict risks diff --git a/.claude/commands/workflow/brainstorm/scrum-master.md b/.claude/commands/workflow/brainstorm/scrum-master.md deleted file mode 100644 index 1e5f0f44..00000000 --- a/.claude/commands/workflow/brainstorm/scrum-master.md +++ /dev/null @@ -1,200 +0,0 @@ ---- -name: scrum-master -description: Generate or update scrum-master/analysis.md addressing guidance-specification discussion points for Agile process perspective -argument-hint: "optional topic - uses existing framework if available" -allowed-tools: Task(conceptual-planning-agent), TodoWrite(*), Read(*), Write(*) ---- - -## 🎯 **Scrum Master Analysis Generator** - -### Purpose -**Specialized command for generating scrum-master/analysis.md** that addresses guidance-specification.md discussion points from agile process and team collaboration perspective. Creates or updates role-specific analysis with framework references. - -### Core Function -- **Framework-based Analysis**: Address each discussion point in guidance-specification.md -- **Agile Process Focus**: Sprint planning, team dynamics, and delivery optimization -- **Update Mechanism**: Create new or update existing analysis.md -- **Agent Delegation**: Use conceptual-planning-agent for analysis generation - -### Analysis Scope -- **Sprint Planning**: Task breakdown, estimation, and iteration planning -- **Team Collaboration**: Communication patterns, impediment removal, and facilitation -- **Process Optimization**: Agile ceremonies, retrospectives, and continuous improvement -- **Delivery Management**: Velocity tracking, burndown analysis, and release planning - -## ⚙️ **Execution Protocol** - -### Phase 1: Session & Framework Detection -```bash -# Check active session and framework -CHECK: find .workflow/active/ -name "WFS-*" -type d -IF active_session EXISTS: - session_id = get_active_session() - brainstorm_dir = .workflow/active/WFS-{session}/.brainstorming/ - - CHECK: brainstorm_dir/guidance-specification.md - IF EXISTS: - framework_mode = true - load_framework = true - ELSE: - IF topic_provided: - framework_mode = false # Create analysis without framework - ELSE: - ERROR: "No framework found and no topic provided" -``` - -### Phase 2: Analysis Mode Detection -```bash -# Determine execution mode -IF framework_mode == true: - mode = "framework_based_analysis" - topic_ref = load_framework_topic() - discussion_points = extract_framework_points() -ELSE: - mode = "standalone_analysis" - topic_ref = provided_topic - discussion_points = generate_basic_structure() -``` - -### Phase 3: Agent Execution with Flow Control -**Framework-Based Analysis Generation** - -```bash -Task(conceptual-planning-agent): " -[FLOW_CONTROL] - -Execute scrum-master analysis for existing topic framework - -## Context Loading -ASSIGNED_ROLE: scrum-master -OUTPUT_LOCATION: .workflow/active/WFS-{session}/.brainstorming/scrum-master/ -ANALYSIS_MODE: {framework_mode ? "framework_based" : "standalone"} - -## Flow Control Steps -1. **load_topic_framework** - - Action: Load structured topic discussion framework - - Command: Read(.workflow/active/WFS-{session}/.brainstorming/guidance-specification.md) - - Output: topic_framework_content - -2. **load_role_template** - - Action: Load scrum-master planning template - - Command: bash($(cat ~/.claude/workflows/cli-templates/planning-roles/scrum-master.md)) - - Output: role_template_guidelines - -3. **load_session_metadata** - - Action: Load session metadata and existing context - - Command: Read(.workflow/active/WFS-{session}/workflow-session.json) - - Output: session_context - -## Analysis Requirements -**Framework Reference**: Address all discussion points in guidance-specification.md from agile process and team collaboration perspective -**Role Focus**: Sprint planning, team dynamics, process optimization, delivery management -**Structured Approach**: Create analysis.md addressing framework discussion points -**Template Integration**: Apply role template guidelines within framework structure - -## Expected Deliverables -1. **analysis.md**: Comprehensive agile process analysis addressing all framework discussion points -2. **Framework Reference**: Include @../guidance-specification.md reference in analysis - -## Completion Criteria -- Address each discussion point from guidance-specification.md with scrum mastery expertise -- Provide actionable sprint planning and team facilitation strategies -- Include process optimization and impediment removal insights -- Reference framework document using @ notation for integration -" -``` - -## 📋 **TodoWrite Integration** - -### Workflow Progress Tracking -```javascript -TodoWrite({ - todos: [ - { - content: "Detect active session and locate topic framework", - status: "in_progress", - activeForm: "Detecting session and framework" - }, - { - content: "Load guidance-specification.md and session metadata for context", - status: "pending", - activeForm: "Loading framework and session context" - }, - { - content: "Execute scrum-master analysis using conceptual-planning-agent with FLOW_CONTROL", - status: "pending", - activeForm: "Executing scrum-master framework analysis" - }, - { - content: "Generate analysis.md addressing all framework discussion points", - status: "pending", - activeForm: "Generating structured scrum-master analysis" - }, - { - content: "Update workflow-session.json with scrum-master completion status", - status: "pending", - activeForm: "Updating session metadata" - } - ] -}); -``` - -## 📊 **Output Structure** - -### Framework-Based Analysis -``` -.workflow/active/WFS-{session}/.brainstorming/scrum-master/ -└── analysis.md # Structured analysis addressing guidance-specification.md discussion points -``` - -### Analysis Document Structure -```markdown -# Scrum Master Analysis: [Topic from Framework] - -## Framework Reference -**Topic Framework**: @../guidance-specification.md -**Role Focus**: Agile Process & Team Collaboration perspective - -## Discussion Points Analysis -[Address each point from guidance-specification.md with scrum mastery expertise] - -### Core Requirements (from framework) -[Sprint planning and iteration breakdown perspective] - -### Technical Considerations (from framework) -[Technical debt management and process considerations] - -### User Experience Factors (from framework) -[User story refinement and acceptance criteria analysis] - -### Implementation Challenges (from framework) -[Impediment identification and removal strategies] - -### Success Metrics (from framework) -[Velocity tracking, burndown metrics, and team performance indicators] - -## Scrum Master Specific Recommendations -[Role-specific agile process optimization and team facilitation strategies] - ---- -*Generated by scrum-master analysis addressing structured framework* -``` - -## 🔄 **Session Integration** - -### Completion Status Update -```json -{ - "scrum_master": { - "status": "completed", - "framework_addressed": true, - "output_location": ".workflow/active/WFS-{session}/.brainstorming/scrum-master/analysis.md", - "framework_reference": "@../guidance-specification.md" - } -} -``` - -### Integration Points -- **Framework Reference**: @../guidance-specification.md for structured discussion points -- **Cross-Role Synthesis**: Agile process insights available for synthesis-report.md integration -- **Agent Autonomy**: Independent execution with framework guidance diff --git a/.claude/commands/workflow/brainstorm/subject-matter-expert.md b/.claude/commands/workflow/brainstorm/subject-matter-expert.md deleted file mode 100644 index 1ac0bac9..00000000 --- a/.claude/commands/workflow/brainstorm/subject-matter-expert.md +++ /dev/null @@ -1,200 +0,0 @@ ---- -name: subject-matter-expert -description: Generate or update subject-matter-expert/analysis.md addressing guidance-specification discussion points for domain expertise perspective -argument-hint: "optional topic - uses existing framework if available" -allowed-tools: Task(conceptual-planning-agent), TodoWrite(*), Read(*), Write(*) ---- - -## 🎯 **Subject Matter Expert Analysis Generator** - -### Purpose -**Specialized command for generating subject-matter-expert/analysis.md** that addresses guidance-specification.md discussion points from domain knowledge and technical expertise perspective. Creates or updates role-specific analysis with framework references. - -### Core Function -- **Framework-based Analysis**: Address each discussion point in guidance-specification.md -- **Domain Expertise Focus**: Deep technical knowledge, industry standards, and best practices -- **Update Mechanism**: Create new or update existing analysis.md -- **Agent Delegation**: Use conceptual-planning-agent for analysis generation - -### Analysis Scope -- **Domain Knowledge**: Industry-specific expertise, regulatory requirements, and compliance -- **Technical Standards**: Best practices, design patterns, and architectural guidelines -- **Risk Assessment**: Technical debt, scalability concerns, and maintenance implications -- **Knowledge Transfer**: Documentation strategies, training requirements, and expertise sharing - -## ⚙️ **Execution Protocol** - -### Phase 1: Session & Framework Detection -```bash -# Check active session and framework -CHECK: find .workflow/active/ -name "WFS-*" -type d -IF active_session EXISTS: - session_id = get_active_session() - brainstorm_dir = .workflow/active/WFS-{session}/.brainstorming/ - - CHECK: brainstorm_dir/guidance-specification.md - IF EXISTS: - framework_mode = true - load_framework = true - ELSE: - IF topic_provided: - framework_mode = false # Create analysis without framework - ELSE: - ERROR: "No framework found and no topic provided" -``` - -### Phase 2: Analysis Mode Detection -```bash -# Determine execution mode -IF framework_mode == true: - mode = "framework_based_analysis" - topic_ref = load_framework_topic() - discussion_points = extract_framework_points() -ELSE: - mode = "standalone_analysis" - topic_ref = provided_topic - discussion_points = generate_basic_structure() -``` - -### Phase 3: Agent Execution with Flow Control -**Framework-Based Analysis Generation** - -```bash -Task(conceptual-planning-agent): " -[FLOW_CONTROL] - -Execute subject-matter-expert analysis for existing topic framework - -## Context Loading -ASSIGNED_ROLE: subject-matter-expert -OUTPUT_LOCATION: .workflow/active/WFS-{session}/.brainstorming/subject-matter-expert/ -ANALYSIS_MODE: {framework_mode ? "framework_based" : "standalone"} - -## Flow Control Steps -1. **load_topic_framework** - - Action: Load structured topic discussion framework - - Command: Read(.workflow/active/WFS-{session}/.brainstorming/guidance-specification.md) - - Output: topic_framework_content - -2. **load_role_template** - - Action: Load subject-matter-expert planning template - - Command: bash($(cat ~/.claude/workflows/cli-templates/planning-roles/subject-matter-expert.md)) - - Output: role_template_guidelines - -3. **load_session_metadata** - - Action: Load session metadata and existing context - - Command: Read(.workflow/active/WFS-{session}/workflow-session.json) - - Output: session_context - -## Analysis Requirements -**Framework Reference**: Address all discussion points in guidance-specification.md from domain expertise and technical standards perspective -**Role Focus**: Domain knowledge, technical standards, risk assessment, knowledge transfer -**Structured Approach**: Create analysis.md addressing framework discussion points -**Template Integration**: Apply role template guidelines within framework structure - -## Expected Deliverables -1. **analysis.md**: Comprehensive domain expertise analysis addressing all framework discussion points -2. **Framework Reference**: Include @../guidance-specification.md reference in analysis - -## Completion Criteria -- Address each discussion point from guidance-specification.md with subject matter expertise -- Provide actionable technical standards and best practices recommendations -- Include risk assessment and compliance considerations -- Reference framework document using @ notation for integration -" -``` - -## 📋 **TodoWrite Integration** - -### Workflow Progress Tracking -```javascript -TodoWrite({ - todos: [ - { - content: "Detect active session and locate topic framework", - status: "in_progress", - activeForm: "Detecting session and framework" - }, - { - content: "Load guidance-specification.md and session metadata for context", - status: "pending", - activeForm: "Loading framework and session context" - }, - { - content: "Execute subject-matter-expert analysis using conceptual-planning-agent with FLOW_CONTROL", - status: "pending", - activeForm: "Executing subject-matter-expert framework analysis" - }, - { - content: "Generate analysis.md addressing all framework discussion points", - status: "pending", - activeForm: "Generating structured subject-matter-expert analysis" - }, - { - content: "Update workflow-session.json with subject-matter-expert completion status", - status: "pending", - activeForm: "Updating session metadata" - } - ] -}); -``` - -## 📊 **Output Structure** - -### Framework-Based Analysis -``` -.workflow/active/WFS-{session}/.brainstorming/subject-matter-expert/ -└── analysis.md # Structured analysis addressing guidance-specification.md discussion points -``` - -### Analysis Document Structure -```markdown -# Subject Matter Expert Analysis: [Topic from Framework] - -## Framework Reference -**Topic Framework**: @../guidance-specification.md -**Role Focus**: Domain Expertise & Technical Standards perspective - -## Discussion Points Analysis -[Address each point from guidance-specification.md with subject matter expertise] - -### Core Requirements (from framework) -[Domain-specific requirements and industry standards perspective] - -### Technical Considerations (from framework) -[Deep technical analysis, architectural patterns, and best practices] - -### User Experience Factors (from framework) -[Domain-specific usability standards and industry conventions] - -### Implementation Challenges (from framework) -[Technical risks, scalability concerns, and maintenance implications] - -### Success Metrics (from framework) -[Domain-specific KPIs, compliance metrics, and quality standards] - -## Subject Matter Expert Specific Recommendations -[Role-specific technical expertise and industry best practices] - ---- -*Generated by subject-matter-expert analysis addressing structured framework* -``` - -## 🔄 **Session Integration** - -### Completion Status Update -```json -{ - "subject_matter_expert": { - "status": "completed", - "framework_addressed": true, - "output_location": ".workflow/active/WFS-{session}/.brainstorming/subject-matter-expert/analysis.md", - "framework_reference": "@../guidance-specification.md" - } -} -``` - -### Integration Points -- **Framework Reference**: @../guidance-specification.md for structured discussion points -- **Cross-Role Synthesis**: Domain expertise insights available for synthesis-report.md integration -- **Agent Autonomy**: Independent execution with framework guidance diff --git a/.claude/commands/workflow/brainstorm/system-architect.md b/.claude/commands/workflow/brainstorm/system-architect.md deleted file mode 100644 index dfc60465..00000000 --- a/.claude/commands/workflow/brainstorm/system-architect.md +++ /dev/null @@ -1,389 +0,0 @@ ---- -name: system-architect -description: Generate or update system-architect/analysis.md addressing guidance-specification discussion points for system architecture perspective -argument-hint: "optional topic - uses existing framework if available" -allowed-tools: Task(conceptual-planning-agent), TodoWrite(*), Read(*), Write(*) ---- - -## 🏗️ **System Architect Analysis Generator** - -### Purpose -**Specialized command for generating system-architect/analysis.md** that addresses guidance-specification.md discussion points from system architecture perspective. Creates or updates role-specific analysis with framework references. - -### Core Function -- **Framework-based Analysis**: Address each discussion point in guidance-specification.md -- **Architecture Focus**: Technical architecture, scalability, and system design perspective -- **Update Mechanism**: Create new or update existing analysis.md -- **Agent Delegation**: Use conceptual-planning-agent for analysis generation - -### Analysis Scope -- **Technical Architecture**: Scalable and maintainable system design -- **Technology Selection**: Stack evaluation and architectural decisions -- **Performance & Scalability**: Capacity planning and optimization strategies -- **Integration Patterns**: System communication and data flow design - -### Role Boundaries & Responsibilities - -#### **What This Role OWNS (Macro-Architecture)** -- **System-Level Architecture**: Service boundaries, deployment topology, and system composition -- **Cross-Service Communication Patterns**: Choosing between microservices/monolithic, event-driven/request-response, sync/async patterns -- **Technology Stack Decisions**: Language, framework, database, and infrastructure choices -- **Non-Functional Requirements**: Scalability, performance, availability, disaster recovery, and monitoring strategies -- **Integration Planning**: How systems and services connect at the macro level (not specific API contracts) - -#### **What This Role DOES NOT Own (Defers to Other Roles)** -- **API Contract Details**: Specific endpoint definitions, URL structures, HTTP methods → Defers to **API Designer** -- **Data Schemas**: Detailed data model design and entity relationships → Defers to **Data Architect** -- **UI/UX Design**: Interface design and user experience → Defers to **UX Expert** and **UI Designer** - -#### **Handoff Points** -- **TO API Designer**: Provides architectural constraints (REST vs GraphQL, sync vs async) that define the API design space -- **TO Data Architect**: Provides system-level data flow requirements and integration patterns -- **FROM Data Architect**: Receives canonical data model to inform system integration design - -## ⚙️ **Execution Protocol** - -### Phase 1: Session & Framework Detection -```bash -# Check active session and framework -CHECK: find .workflow/active/ -name "WFS-*" -type d -IF active_session EXISTS: - session_id = get_active_session() - brainstorm_dir = .workflow/active/WFS-{session}/.brainstorming/ - - CHECK: brainstorm_dir/guidance-specification.md - IF EXISTS: - framework_mode = true - load_framework = true - ELSE: - IF topic_provided: - framework_mode = false # Create analysis without framework - ELSE: - ERROR: "No framework found and no topic provided" -``` - -### Phase 2: Analysis Mode Detection -```bash -# Check existing analysis -CHECK: brainstorm_dir/system-architect/analysis.md -IF EXISTS: - SHOW existing analysis summary - ASK: "Analysis exists. Do you want to:" - OPTIONS: - 1. "Update with new insights" → Update existing - 2. "Replace completely" → Generate new - 3. "Cancel" → Exit without changes -ELSE: - CREATE new analysis -``` - -### Phase 3: Agent Task Generation -**Framework-Based Analysis** (when guidance-specification.md exists): -```bash -Task(subagent_type="conceptual-planning-agent", - run_in_background=false, - prompt="Generate system architect analysis addressing topic framework - - ## Framework Integration Required - **MANDATORY**: Load and address guidance-specification.md discussion points - **Framework Reference**: @{session.brainstorm_dir}/guidance-specification.md - **Output Location**: {session.brainstorm_dir}/system-architect/analysis.md - - ## Analysis Requirements - 1. **Load Topic Framework**: Read guidance-specification.md completely - 2. **Address Each Discussion Point**: Respond to all 5 framework sections from system architecture perspective - 3. **Include Framework Reference**: Start analysis.md with @../guidance-specification.md - 4. **Technical Focus**: Emphasize scalability, architecture patterns, technology decisions - 5. **Structured Response**: Use framework structure for analysis organization - - ## Framework Sections to Address - - Core Requirements (from architecture perspective) - - Technical Considerations (detailed architectural analysis) - - User Experience Factors (technical UX considerations) - - Implementation Challenges (architecture risks and solutions) - - Success Metrics (technical metrics and monitoring) - - ## Output Structure Required - ```markdown - # System Architect Analysis: [Topic] - - **Framework Reference**: @../guidance-specification.md - **Role Focus**: System Architecture and Technical Design - - ## Core Requirements Analysis - [Address framework requirements from architecture perspective] - - ## Technical Considerations - [Detailed architectural analysis] - - ## User Experience Factors - [Technical aspects of UX implementation] - - ## Implementation Challenges - [Architecture risks and mitigation strategies] - - ## Success Metrics - [Technical metrics and system monitoring] - - ## Architecture-Specific Recommendations - [Detailed technical recommendations] - ```", - description="Generate system architect framework-based analysis") -``` - -### Phase 4: Update Mechanism -**Analysis Update Process**: -```bash -# For existing analysis updates -IF update_mode = "incremental": - Task(subagent_type="conceptual-planning-agent", - run_in_background=false, - prompt="Update existing system architect analysis - - ## Current Analysis Context - **Existing Analysis**: @{session.brainstorm_dir}/system-architect/analysis.md - **Framework Reference**: @{session.brainstorm_dir}/guidance-specification.md - - ## Update Requirements - 1. **Preserve Structure**: Maintain existing analysis structure - 2. **Add New Insights**: Integrate new technical insights and recommendations - 3. **Framework Alignment**: Ensure continued alignment with topic framework - 4. **Technical Updates**: Add new architecture patterns, technology considerations - 5. **Maintain References**: Keep @../guidance-specification.md reference - - ## Update Instructions - - Read existing analysis completely - - Identify areas for enhancement or new insights - - Add technical depth while preserving original structure - - Update recommendations with new architectural approaches - - Maintain framework discussion point addressing", - description="Update system architect analysis incrementally") -``` - -## Document Structure - -### Output Files -``` -.workflow/active/WFS-[topic]/.brainstorming/ -├── guidance-specification.md # Input: Framework (if exists) -└── system-architect/ - └── analysis.md # ★ OUTPUT: Framework-based analysis -``` - -### Analysis Structure -**Required Elements**: -- **Framework Reference**: @../guidance-specification.md (if framework exists) -- **Role Focus**: System Architecture and Technical Design perspective -- **5 Framework Sections**: Address each framework discussion point -- **Technical Recommendations**: Architecture-specific insights and solutions -- How should we design APIs and manage versioning? - -**4. Performance and Scalability** -- Where are the current system performance bottlenecks? -- How should we handle traffic growth and scaling demands? -- What database scaling and optimization strategies are needed? - -## ⚡ **Two-Step Execution Flow** - -### ⚠️ Session Management - FIRST STEP -Session detection and selection: -```bash -# Check for existing sessions -existing_sessions=$(find .workflow/active/ -name "WFS-*" -type d 2>/dev/null) -if [ multiple_sessions ]; then - prompt_user_to_select_session() -else - use_existing_or_create_new() -fi -``` - -### Step 1: Context Gathering Phase -**System Architect Perspective Questioning** - -Before agent assignment, gather comprehensive system architecture context: - -#### 📋 Role-Specific Questions -1. **Scale & Performance Requirements** - - Expected user load and traffic patterns? - - Performance requirements (latency, throughput)? - - Data volume and growth projections? - -2. **Technical Constraints & Environment** - - Existing technology stack and constraints? - - Integration requirements with external systems? - - Infrastructure and deployment environment? - -3. **Architecture Complexity & Patterns** - - Microservices vs monolithic considerations? - - Data consistency and transaction requirements? - - Event-driven vs request-response patterns? - -4. **Non-Functional Requirements** - - High availability and disaster recovery needs? - - Security and compliance requirements? - - Monitoring and observability expectations? - -#### Context Validation -- **Minimum Response**: Each answer must be ≥50 characters -- **Re-prompting**: Insufficient detail triggers follow-up questions -- **Context Storage**: Save responses to `.brainstorming/system-architect-context.md` - -### Step 2: Agent Assignment with Flow Control -**Dedicated Agent Execution** - -```bash -Task(conceptual-planning-agent): " -[FLOW_CONTROL] - -Execute dedicated system-architect conceptual analysis for: {topic} - -ASSIGNED_ROLE: system-architect -OUTPUT_LOCATION: .brainstorming/system-architect/ -USER_CONTEXT: {validated_responses_from_context_gathering} - -Flow Control Steps: -[ - { - \"step\": \"load_role_template\", - \"action\": \"Load system-architect planning template\", - \"command\": \"bash($(cat ~/.claude/workflows/cli-templates/planning-roles/system-architect.md))\", - \"output_to\": \"role_template\" - } -] - -Conceptual Analysis Requirements: -- Apply system-architect perspective to topic analysis -- Focus on architectural patterns, scalability, and integration points -- Use loaded role template framework for analysis structure -- Generate role-specific deliverables in designated output location -- Address all user context from questioning phase - -Deliverables: -- analysis.md: Main system architecture analysis -- recommendations.md: Architecture recommendations -- deliverables/: Architecture-specific outputs as defined in role template - -Embody system-architect role expertise for comprehensive conceptual planning." -``` - -### Progress Tracking -TodoWrite tracking for two-step process: -```json -[ - {"content": "Gather system architect context through role-specific questioning", "status": "in_progress", "activeForm": "Gathering context"}, - {"content": "Validate context responses and save to system-architect-context.md", "status": "pending", "activeForm": "Validating context"}, - {"content": "Load system-architect planning template via flow control", "status": "pending", "activeForm": "Loading template"}, - {"content": "Execute dedicated conceptual-planning-agent for system-architect role", "status": "pending", "activeForm": "Executing agent"} -] -``` - -## 📊 **Output Specification** - -### Output Location -``` -.workflow/active/WFS-{topic-slug}/.brainstorming/system-architect/ -├── analysis.md # Primary architecture analysis -├── architecture-design.md # Detailed system design and diagrams -├── technology-stack.md # Technology stack recommendations and justifications -└── integration-plan.md # System integration and API strategies -``` - -### Document Templates - -#### analysis.md Structure -```markdown -# System Architecture Analysis: {Topic} -*Generated: {timestamp}* - -## Executive Summary -[Key architectural findings and recommendations overview] - -## Current State Assessment -### Existing Architecture Overview -### Technical Stack Analysis -### Performance Bottlenecks -### Technical Debt Assessment - -## Requirements Analysis -### Functional Requirements -### Non-Functional Requirements -- Performance: [Response time, throughput requirements] -- Scalability: [User growth, data volume expectations] -- Availability: [Uptime requirements] -- Security: [Security requirements] - -## Proposed Architecture -### High-Level Architecture Design -### Component Breakdown -### Data Flow Diagrams -### Technology Stack Recommendations - -## Implementation Strategy -### Migration Planning -### Risk Mitigation -### Performance Optimization -### Security Considerations - -## Scalability and Maintenance -### Horizontal Scaling Strategy -### Monitoring and Observability -### Deployment Strategy -### Long-term Maintenance Plan -``` - -## 🔄 **Session Integration** - -### Status Synchronization -Upon completion, update `workflow-session.json`: -```json -{ - "phases": { - "BRAINSTORM": { - "system_architect": { - "status": "completed", - "completed_at": "timestamp", - "output_directory": ".workflow/active/WFS-{topic}/.brainstorming/system-architect/", - "key_insights": ["scalability_bottleneck", "architecture_pattern", "technology_recommendation"] - } - } - } -} -``` - -### Cross-Role Collaboration -System architect perspective provides: -- **Technical Constraints and Possibilities** → Product Manager -- **Architecture Requirements and Limitations** → UI Designer -- **Data Architecture Requirements** → Data Architect -- **Security Architecture Framework** → Security Expert -- **Technical Implementation Framework** → Feature Planner - -## ✅ **Quality Assurance** - -### Required Analysis Elements -- [ ] Clear architecture diagrams and component designs -- [ ] Detailed technology stack evaluation and recommendations -- [ ] Scalability and performance analysis with metrics -- [ ] System integration and API design specifications -- [ ] Comprehensive risk assessment and mitigation strategies - -### Architecture Design Principles -- [ ] **Scalability**: System can handle growth in users and data -- [ ] **Maintainability**: Clear code structure, easy to modify and extend -- [ ] **Reliability**: Built-in fault tolerance and recovery mechanisms -- [ ] **Security**: Integrated security controls and protection measures -- [ ] **Performance**: Meets response time and throughput requirements - -### Technical Decision Validation -- [ ] Technology choices have thorough justification and comparison analysis -- [ ] Architectural patterns align with business requirements and constraints -- [ ] Integration solutions consider compatibility and maintenance costs -- [ ] Deployment strategies are feasible with acceptable risk levels -- [ ] Monitoring and operations strategies are comprehensive and actionable - -### Implementation Readiness -- [ ] **Technical Feasibility**: All proposed solutions are technically achievable -- [ ] **Resource Planning**: Resource requirements clearly defined and realistic -- [ ] **Risk Management**: Technical risks identified with mitigation plans -- [ ] **Performance Validation**: Architecture can meet performance requirements -- [ ] **Evolution Strategy**: Design allows for future growth and changes diff --git a/.claude/commands/workflow/brainstorm/ui-designer.md b/.claude/commands/workflow/brainstorm/ui-designer.md deleted file mode 100644 index e14a87a5..00000000 --- a/.claude/commands/workflow/brainstorm/ui-designer.md +++ /dev/null @@ -1,221 +0,0 @@ ---- -name: ui-designer -description: Generate or update ui-designer/analysis.md addressing guidance-specification discussion points for UI design perspective -argument-hint: "optional topic - uses existing framework if available" -allowed-tools: Task(conceptual-planning-agent), TodoWrite(*), Read(*), Write(*) ---- - -## 🎨 **UI Designer Analysis Generator** - -### Purpose -**Specialized command for generating ui-designer/analysis.md** that addresses guidance-specification.md discussion points from UI/UX design perspective. Creates or updates role-specific analysis with framework references. - -### Core Function -- **Framework-based Analysis**: Address each discussion point in guidance-specification.md -- **UI/UX Focus**: User experience, interface design, and accessibility perspective -- **Update Mechanism**: Create new or update existing analysis.md -- **Agent Delegation**: Use conceptual-planning-agent for analysis generation - -### Analysis Scope -- **Visual Design**: Color palettes, typography, spacing, and visual hierarchy implementation -- **High-Fidelity Mockups**: Polished, pixel-perfect interface designs -- **Design System Implementation**: Component libraries, design tokens, and style guides -- **Micro-Interactions & Animations**: Transition effects, loading states, and interactive feedback -- **Responsive Design**: Layout adaptations for different screen sizes and devices - -### Role Boundaries & Responsibilities - -#### **What This Role OWNS (Concrete Visual Interface Implementation)** -- **Visual Design Language**: Colors, typography, iconography, spacing, and overall aesthetic -- **High-Fidelity Mockups**: Polished designs showing exactly how the interface will look -- **Design System Components**: Building and documenting reusable UI components (buttons, inputs, cards, etc.) -- **Design Tokens**: Defining variables for colors, spacing, typography that can be used in code -- **Micro-Interactions**: Hover states, transitions, animations, and interactive feedback details -- **Responsive Layouts**: Adapting designs for mobile, tablet, and desktop breakpoints - -#### **What This Role DOES NOT Own (Defers to Other Roles)** -- **User Research & Personas**: User behavior analysis and needs assessment → Defers to **UX Expert** -- **Information Architecture**: Content structure and navigation strategy → Defers to **UX Expert** -- **Low-Fidelity Wireframes**: Structural layouts without visual design → Defers to **UX Expert** - -#### **Handoff Points** -- **FROM UX Expert**: Receives wireframes, user flows, and information architecture as the foundation for visual design -- **TO Frontend Developers**: Provides design specifications, component libraries, and design tokens for implementation -- **WITH API Designer**: Coordinates on data presentation and form validation feedback (visual aspects only) - -## ⚙️ **Execution Protocol** - -### Phase 1: Session & Framework Detection -```bash -# Check active session and framework -CHECK: find .workflow/active/ -name "WFS-*" -type d -IF active_session EXISTS: - session_id = get_active_session() - brainstorm_dir = .workflow/active/WFS-{session}/.brainstorming/ - - CHECK: brainstorm_dir/guidance-specification.md - IF EXISTS: - framework_mode = true - load_framework = true - ELSE: - IF topic_provided: - framework_mode = false # Create analysis without framework - ELSE: - ERROR: "No framework found and no topic provided" -``` - -### Phase 2: Analysis Mode Detection -```bash -# Determine execution mode -IF framework_mode == true: - mode = "framework_based_analysis" - topic_ref = load_framework_topic() - discussion_points = extract_framework_points() -ELSE: - mode = "standalone_analysis" - topic_ref = provided_topic - discussion_points = generate_basic_structure() -``` - -### Phase 3: Agent Execution with Flow Control -**Framework-Based Analysis Generation** - -```bash -Task(conceptual-planning-agent): " -[FLOW_CONTROL] - -Execute ui-designer analysis for existing topic framework - -## Context Loading -ASSIGNED_ROLE: ui-designer -OUTPUT_LOCATION: .workflow/active/WFS-{session}/.brainstorming/ui-designer/ -ANALYSIS_MODE: {framework_mode ? "framework_based" : "standalone"} - -## Flow Control Steps -1. **load_topic_framework** - - Action: Load structured topic discussion framework - - Command: Read(.workflow/active/WFS-{session}/.brainstorming/guidance-specification.md) - - Output: topic_framework_content - -2. **load_role_template** - - Action: Load ui-designer planning template - - Command: bash($(cat ~/.claude/workflows/cli-templates/planning-roles/ui-designer.md)) - - Output: role_template_guidelines - -3. **load_session_metadata** - - Action: Load session metadata and existing context - - Command: Read(.workflow/active/WFS-{session}/workflow-session.json) - - Output: session_context - -## Analysis Requirements -**Framework Reference**: Address all discussion points in guidance-specification.md from UI/UX perspective -**Role Focus**: User experience design, interface optimization, accessibility compliance -**Structured Approach**: Create analysis.md addressing framework discussion points -**Template Integration**: Apply role template guidelines within framework structure - -## Expected Deliverables -1. **analysis.md**: Comprehensive UI/UX analysis addressing all framework discussion points -2. **Framework Reference**: Include @../guidance-specification.md reference in analysis - -## Completion Criteria -- Address each discussion point from guidance-specification.md with UI/UX design expertise -- Provide actionable design recommendations and interface solutions -- Include accessibility considerations and WCAG compliance planning -- Reference framework document using @ notation for integration -" -``` - -## 📋 **TodoWrite Integration** - -### Workflow Progress Tracking -```javascript -TodoWrite({ - todos: [ - { - content: "Detect active session and locate topic framework", - status: "in_progress", - activeForm: "Detecting session and framework" - }, - { - content: "Load guidance-specification.md and session metadata for context", - status: "pending", - activeForm: "Loading framework and session context" - }, - { - content: "Execute ui-designer analysis using conceptual-planning-agent with FLOW_CONTROL", - status: "pending", - activeForm: "Executing ui-designer framework analysis" - }, - { - content: "Generate analysis.md addressing all framework discussion points", - status: "pending", - activeForm: "Generating structured ui-designer analysis" - }, - { - content: "Update workflow-session.json with ui-designer completion status", - status: "pending", - activeForm: "Updating session metadata" - } - ] -}); -``` - -## 📊 **Output Structure** - -### Framework-Based Analysis -``` -.workflow/active/WFS-{session}/.brainstorming/ui-designer/ -└── analysis.md # Structured analysis addressing guidance-specification.md discussion points -``` - -### Analysis Document Structure -```markdown -# UI Designer Analysis: [Topic from Framework] - -## Framework Reference -**Topic Framework**: @../guidance-specification.md -**Role Focus**: UI/UX Design perspective - -## Discussion Points Analysis -[Address each point from guidance-specification.md with UI/UX expertise] - -### Core Requirements (from framework) -[UI/UX perspective on requirements] - -### Technical Considerations (from framework) -[Interface and design system considerations] - -### User Experience Factors (from framework) -[Detailed UX analysis and recommendations] - -### Implementation Challenges (from framework) -[Design implementation and accessibility considerations] - -### Success Metrics (from framework) -[UX metrics and usability success criteria] - -## UI/UX Specific Recommendations -[Role-specific design recommendations and solutions] - ---- -*Generated by ui-designer analysis addressing structured framework* -``` - -## 🔄 **Session Integration** - -### Completion Status Update -```json -{ - "ui_designer": { - "status": "completed", - "framework_addressed": true, - "output_location": ".workflow/active/WFS-{session}/.brainstorming/ui-designer/analysis.md", - "framework_reference": "@../guidance-specification.md" - } -} -``` - -### Integration Points -- **Framework Reference**: @../guidance-specification.md for structured discussion points -- **Cross-Role Synthesis**: UI/UX insights available for synthesis-report.md integration -- **Agent Autonomy**: Independent execution with framework guidance diff --git a/.claude/commands/workflow/brainstorm/ux-expert.md b/.claude/commands/workflow/brainstorm/ux-expert.md deleted file mode 100644 index 66dd9f4f..00000000 --- a/.claude/commands/workflow/brainstorm/ux-expert.md +++ /dev/null @@ -1,221 +0,0 @@ ---- -name: ux-expert -description: Generate or update ux-expert/analysis.md addressing guidance-specification discussion points for UX perspective -argument-hint: "optional topic - uses existing framework if available" -allowed-tools: Task(conceptual-planning-agent), TodoWrite(*), Read(*), Write(*) ---- - -## 🎯 **UX Expert Analysis Generator** - -### Purpose -**Specialized command for generating ux-expert/analysis.md** that addresses guidance-specification.md discussion points from user experience and interface design perspective. Creates or updates role-specific analysis with framework references. - -### Core Function -- **Framework-based Analysis**: Address each discussion point in guidance-specification.md -- **UX Design Focus**: User interface, interaction patterns, and usability optimization -- **Update Mechanism**: Create new or update existing analysis.md -- **Agent Delegation**: Use conceptual-planning-agent for analysis generation - -### Analysis Scope -- **User Research**: User personas, behavioral analysis, and needs assessment -- **Information Architecture**: Content structure, navigation hierarchy, and mental models -- **User Journey Mapping**: User flows, task analysis, and interaction models -- **Usability Strategy**: Accessibility planning, cognitive load reduction, and user testing frameworks -- **Wireframing**: Low-fidelity layouts and structural prototypes (not visual design) - -### Role Boundaries & Responsibilities - -#### **What This Role OWNS (Abstract User Experience & Research)** -- **User Research & Personas**: Understanding target users, their goals, pain points, and behaviors -- **Information Architecture**: Organizing content and defining navigation structures at a conceptual level -- **User Journey Mapping**: Defining user flows, task sequences, and interaction models -- **Wireframes & Low-Fidelity Prototypes**: Structural layouts showing information hierarchy (boxes and arrows, not colors/fonts) -- **Usability Testing Strategy**: Planning user testing, A/B tests, and validation methods -- **Accessibility Planning**: WCAG compliance strategy and inclusive design principles - -#### **What This Role DOES NOT Own (Defers to Other Roles)** -- **Visual Design**: Colors, typography, spacing, visual style → Defers to **UI Designer** -- **High-Fidelity Mockups**: Polished, pixel-perfect designs → Defers to **UI Designer** -- **Component Implementation**: Design system components, CSS, animations → Defers to **UI Designer** - -#### **Handoff Points** -- **TO UI Designer**: Provides wireframes, user flows, and information architecture that UI Designer will transform into high-fidelity visual designs -- **FROM User Research**: May receive external research data to inform UX decisions -- **TO Product Owner**: Provides user insights and validation results to inform feature prioritization - -## ⚙️ **Execution Protocol** - -### Phase 1: Session & Framework Detection -```bash -# Check active session and framework -CHECK: find .workflow/active/ -name "WFS-*" -type d -IF active_session EXISTS: - session_id = get_active_session() - brainstorm_dir = .workflow/active/WFS-{session}/.brainstorming/ - - CHECK: brainstorm_dir/guidance-specification.md - IF EXISTS: - framework_mode = true - load_framework = true - ELSE: - IF topic_provided: - framework_mode = false # Create analysis without framework - ELSE: - ERROR: "No framework found and no topic provided" -``` - -### Phase 2: Analysis Mode Detection -```bash -# Determine execution mode -IF framework_mode == true: - mode = "framework_based_analysis" - topic_ref = load_framework_topic() - discussion_points = extract_framework_points() -ELSE: - mode = "standalone_analysis" - topic_ref = provided_topic - discussion_points = generate_basic_structure() -``` - -### Phase 3: Agent Execution with Flow Control -**Framework-Based Analysis Generation** - -```bash -Task(conceptual-planning-agent): " -[FLOW_CONTROL] - -Execute ux-expert analysis for existing topic framework - -## Context Loading -ASSIGNED_ROLE: ux-expert -OUTPUT_LOCATION: .workflow/active/WFS-{session}/.brainstorming/ux-expert/ -ANALYSIS_MODE: {framework_mode ? "framework_based" : "standalone"} - -## Flow Control Steps -1. **load_topic_framework** - - Action: Load structured topic discussion framework - - Command: Read(.workflow/active/WFS-{session}/.brainstorming/guidance-specification.md) - - Output: topic_framework_content - -2. **load_role_template** - - Action: Load ux-expert planning template - - Command: bash($(cat ~/.claude/workflows/cli-templates/planning-roles/ux-expert.md)) - - Output: role_template_guidelines - -3. **load_session_metadata** - - Action: Load session metadata and existing context - - Command: Read(.workflow/active/WFS-{session}/workflow-session.json) - - Output: session_context - -## Analysis Requirements -**Framework Reference**: Address all discussion points in guidance-specification.md from user experience and interface design perspective -**Role Focus**: UI design, interaction patterns, usability optimization, design systems -**Structured Approach**: Create analysis.md addressing framework discussion points -**Template Integration**: Apply role template guidelines within framework structure - -## Expected Deliverables -1. **analysis.md**: Comprehensive UX design analysis addressing all framework discussion points -2. **Framework Reference**: Include @../guidance-specification.md reference in analysis - -## Completion Criteria -- Address each discussion point from guidance-specification.md with UX design expertise -- Provide actionable interface design and usability optimization strategies -- Include accessibility considerations and interaction pattern recommendations -- Reference framework document using @ notation for integration -" -``` - -## 📋 **TodoWrite Integration** - -### Workflow Progress Tracking -```javascript -TodoWrite({ - todos: [ - { - content: "Detect active session and locate topic framework", - status: "in_progress", - activeForm: "Detecting session and framework" - }, - { - content: "Load guidance-specification.md and session metadata for context", - status: "pending", - activeForm: "Loading framework and session context" - }, - { - content: "Execute ux-expert analysis using conceptual-planning-agent with FLOW_CONTROL", - status: "pending", - activeForm: "Executing ux-expert framework analysis" - }, - { - content: "Generate analysis.md addressing all framework discussion points", - status: "pending", - activeForm: "Generating structured ux-expert analysis" - }, - { - content: "Update workflow-session.json with ux-expert completion status", - status: "pending", - activeForm: "Updating session metadata" - } - ] -}); -``` - -## 📊 **Output Structure** - -### Framework-Based Analysis -``` -.workflow/active/WFS-{session}/.brainstorming/ux-expert/ -└── analysis.md # Structured analysis addressing guidance-specification.md discussion points -``` - -### Analysis Document Structure -```markdown -# UX Expert Analysis: [Topic from Framework] - -## Framework Reference -**Topic Framework**: @../guidance-specification.md -**Role Focus**: User Experience & Interface Design perspective - -## Discussion Points Analysis -[Address each point from guidance-specification.md with UX design expertise] - -### Core Requirements (from framework) -[User interface and interaction design requirements perspective] - -### Technical Considerations (from framework) -[Design system implementation and technical feasibility considerations] - -### User Experience Factors (from framework) -[Usability optimization, accessibility, and user-centered design analysis] - -### Implementation Challenges (from framework) -[Design implementation challenges and progressive enhancement strategies] - -### Success Metrics (from framework) -[UX metrics including usability testing, user satisfaction, and design KPIs] - -## UX Expert Specific Recommendations -[Role-specific interface design patterns and usability optimization strategies] - ---- -*Generated by ux-expert analysis addressing structured framework* -``` - -## 🔄 **Session Integration** - -### Completion Status Update -```json -{ - "ux_expert": { - "status": "completed", - "framework_addressed": true, - "output_location": ".workflow/active/WFS-{session}/.brainstorming/ux-expert/analysis.md", - "framework_reference": "@../guidance-specification.md" - } -} -``` - -### Integration Points -- **Framework Reference**: @../guidance-specification.md for structured discussion points -- **Cross-Role Synthesis**: UX design insights available for synthesis-report.md integration -- **Agent Autonomy**: Independent execution with framework guidance diff --git a/.claude/skills/skill-generator/phases/01-requirements-discovery.md b/.claude/skills/skill-generator/phases/01-requirements-discovery.md index d404bdf5..b54b69c2 100644 --- a/.claude/skills/skill-generator/phases/01-requirements-discovery.md +++ b/.claude/skills/skill-generator/phases/01-requirements-discovery.md @@ -218,3 +218,11 @@ Write(`${workDir}/skill-config.json`, JSON.stringify(config, null, 2)); ``` + +## Next Phase + +→ [Phase 2: Structure Generation](02-structure-generation.md) + +**Data Flow to Phase 2**: +- skill-config.json with all configuration parameters +- Execution mode decision drives directory structure creation diff --git a/.claude/skills/skill-generator/phases/02-structure-generation.md b/.claude/skills/skill-generator/phases/02-structure-generation.md index b840e362..0fdcad2a 100644 --- a/.claude/skills/skill-generator/phases/02-structure-generation.md +++ b/.claude/skills/skill-generator/phases/02-structure-generation.md @@ -191,3 +191,12 @@ function generateReferenceTable(config) { ``` + +## Next Phase + +→ [Phase 3: Phase Generation](03-phase-generation.md) + +**Data Flow to Phase 3**: +- Complete directory structure in .claude/skills/{skill-name}/ +- SKILL.md entry file ready for phase/action generation +- skill-config.json for template population diff --git a/.claude/skills/skill-generator/phases/05-validation.md b/.claude/skills/skill-generator/phases/05-validation.md index 07fb637b..2d90e1ef 100644 --- a/.claude/skills/skill-generator/phases/05-validation.md +++ b/.claude/skills/skill-generator/phases/05-validation.md @@ -1,27 +1,119 @@ # Phase 5: Validation & Documentation -验证生成的 Skill 完整性并生成使用说明。 +Verify generated skill completeness and generate user documentation. ## Objective -- 验证所有必需文件存在 -- 检查文件内容完整性 -- 生成 README.md 使用说明 -- 输出验证报告 +Comprehensive validation and documentation: +- Verify all required files exist +- Check file content quality and completeness +- Generate validation report with issues and recommendations +- Generate README.md usage documentation +- Output final status and next steps ## Input -- 依赖: 所有前序阶段产出 -- 生成的 Skill 目录 +**File Dependencies**: +- `skill-config.json` (from Phase 1) +- `.claude/skills/{skill-name}/` directory (from Phase 2) +- All generated phase/action files (from Phase 3) +- All generated specs/templates files (from Phase 4) -## Execution Steps +**Required Information**: +- Skill name, display name, description +- Execution mode +- Trigger words +- Output configuration +- Complete skill directory structure -### Step 1: 文件完整性检查 +## Output + +**Generated Files**: + +| File | Purpose | Content | +|------|---------|---------| +| `validation-report.json` (workDir) | Validation report with detailed checks | File completeness, content quality, issues, recommendations | +| `README.md` (skillDir) | User documentation | Quick Start, Usage, Output, Directory Structure, Customization | + +**Validation Report Structure** (`validation-report.json`): +```json +{ + "skill_name": "...", + "execution_mode": "sequential|autonomous", + "generated_at": "ISO timestamp", + "file_checks": { + "total": N, + "existing": N, + "with_content": N, + "with_todos": N, + "details": [...] + }, + "content_checks": { + "files_checked": N, + "all_passed": true|false, + "details": [...] + }, + "summary": { + "status": "PASS|REVIEW|FAIL", + "issues": [...], + "recommendations": [...] + } +} +``` + +**README Structure** (`README.md`): +```markdown +# {display_name} +- Quick Start (Triggers, Execution Mode) +- Usage (Examples) +- Output (Format, Location, Filename) +- Directory Structure (Tree view) +- Customization (How to modify) +- Related Documents (Links) +``` + +**Validation Status Gates**: + +| Status | Condition | Meaning | +|--------|-----------|---------| +| PASS | All files exist + All content checks passed | Ready for use | +| REVIEW | All files exist + Some content checks failed | Needs refinement | +| FAIL | Missing files | Incomplete generation | + +## Decision Logic + +``` +Decision (Validation Flow): + ├─ File Completeness Check + │ ├─ All files exist → Continue to content checks + │ └─ Missing files → Status = FAIL, collect missing file errors + │ + ├─ Content Quality Check + │ ├─ Sequential mode → Check phase files for structure + │ ├─ Autonomous mode → Check orchestrator + action files + │ └─ Common → Check SKILL.md, specs/, templates/ + │ + ├─ Status Calculation + │ ├─ All files exist + All checks pass → Status = PASS + │ ├─ All files exist + Some checks fail → Status = REVIEW + │ └─ Missing files → Status = FAIL + │ + └─ Generate Report & README + ├─ validation-report.json (with issues and recommendations) + └─ README.md (with usage documentation) +``` + +## Execution Protocol ```javascript +// Phase 5: Validation & Documentation +// Reference: phases/05-validation.md + +// Load config and setup const config = JSON.parse(Read(`${workDir}/skill-config.json`)); const skillDir = `.claude/skills/${config.skill_name}`; +// Step 1: File completeness check const requiredFiles = { common: [ 'SKILL.md', @@ -64,14 +156,11 @@ const fileCheckResults = filesToCheck.map(file => { }; } }); -``` -### Step 2: 内容质量检查 - -```javascript +// Step 2: Content quality check const contentChecks = []; -// 检查 SKILL.md +// Check SKILL.md structure const skillMd = Read(`${skillDir}/SKILL.md`); contentChecks.push({ file: 'SKILL.md', @@ -83,11 +172,11 @@ contentChecks.push({ ] }); -// 检查 Phase 文件 +// Check phase files const phaseFiles = Glob(`${skillDir}/phases/*.md`); for (const phaseFile of phaseFiles) { - if (phaseFile.includes('/actions/')) continue; // 单独检查 - + if (phaseFile.includes('/actions/')) continue; // Check separately + const content = Read(phaseFile); contentChecks.push({ file: phaseFile.replace(skillDir + '/', ''), @@ -100,7 +189,7 @@ for (const phaseFile of phaseFiles) { }); } -// 检查 Specs 文件 +// Check specs files const specFiles = Glob(`${skillDir}/specs/*.md`); for (const specFile of specFiles) { const content = Read(specFile); @@ -113,16 +202,13 @@ for (const specFile of specFiles) { ] }); } -``` -### Step 3: 生成验证报告 - -```javascript +// Step 3: Generate validation report const report = { skill_name: config.skill_name, execution_mode: config.execution_mode, generated_at: new Date().toISOString(), - + file_checks: { total: fileCheckResults.length, existing: fileCheckResults.filter(f => f.exists).length, @@ -130,13 +216,13 @@ const report = { with_todos: fileCheckResults.filter(f => f.hasTodo).length, details: fileCheckResults }, - + content_checks: { files_checked: contentChecks.length, all_passed: contentChecks.every(c => c.checks.every(ch => ch.pass)), details: contentChecks }, - + summary: { status: calculateOverallStatus(fileCheckResults, contentChecks), issues: collectIssues(fileCheckResults, contentChecks), @@ -146,10 +232,11 @@ const report = { Write(`${workDir}/validation-report.json`, JSON.stringify(report, null, 2)); +// Helper functions function calculateOverallStatus(fileResults, contentResults) { const allFilesExist = fileResults.every(f => f.exists); const allContentPassed = contentResults.every(c => c.checks.every(ch => ch.pass)); - + if (allFilesExist && allContentPassed) return 'PASS'; if (allFilesExist) return 'REVIEW'; return 'FAIL'; @@ -157,44 +244,41 @@ function calculateOverallStatus(fileResults, contentResults) { function collectIssues(fileResults, contentResults) { const issues = []; - + fileResults.filter(f => !f.exists).forEach(f => { issues.push({ type: 'ERROR', message: `文件缺失: ${f.file}` }); }); - + fileResults.filter(f => f.hasTodo).forEach(f => { issues.push({ type: 'WARNING', message: `包含 TODO: ${f.file}` }); }); - + contentResults.forEach(c => { c.checks.filter(ch => !ch.pass).forEach(ch => { issues.push({ type: 'WARNING', message: `${c.file}: 缺少 ${ch.name}` }); }); }); - + return issues; } function generateRecommendations(fileResults, contentResults) { const recommendations = []; - + if (fileResults.some(f => f.hasTodo)) { recommendations.push('替换所有 TODO 占位符为实际内容'); } - + contentResults.forEach(c => { if (c.checks.some(ch => !ch.pass)) { recommendations.push(`完善 ${c.file} 的结构`); } }); - + return recommendations; } -``` -### Step 4: 生成 README.md - -```javascript +// Step 4: Generate README.md const readme = `# ${config.display_name} ${config.description} @@ -210,10 +294,10 @@ ${config.triggers.map(t => `- "${t}"`).join('\n')} **${config.execution_mode === 'sequential' ? 'Sequential (顺序)' : 'Autonomous (自主)'}** ${config.execution_mode === 'sequential' ? - `阶段按固定顺序执行:\n${config.sequential_config.phases.map((p, i) => + `阶段按固定顺序执行:\n${config.sequential_config.phases.map((p, i) => `${i + 1}. ${p.name}` ).join('\n')}` : - `动作由编排器动态选择:\n${config.autonomous_config.actions.map(a => + `动作由编排器动态选择:\n${config.autonomous_config.actions.map(a => `- ${a.name}: ${a.description || ''}` ).join('\n')}`} @@ -283,24 +367,21 @@ ${config.execution_mode === 'sequential' ? `; Write(`${skillDir}/README.md`, readme); -``` -### Step 5: 输出最终结果 - -```javascript +// Step 5: Output final result const finalResult = { skill_name: config.skill_name, skill_path: skillDir, execution_mode: config.execution_mode, - + generated_files: [ 'SKILL.md', 'README.md', ...filesToCheck ], - + validation: report.summary, - + next_steps: [ '1. 审阅生成的文件结构', '2. 替换 TODO 占位符', @@ -319,16 +400,18 @@ console.log('下一步:'); finalResult.next_steps.forEach(s => console.log(s)); ``` -## Output +## Workflow Completion -- `{workDir}/validation-report.json` - 验证报告 -- `{skillDir}/README.md` - 使用说明 +**Final Status**: Skill generation pipeline complete -## Completion +**Generated Artifacts**: +- Complete skill directory structure in `.claude/skills/{skill-name}/` +- Validation report in `{workDir}/validation-report.json` +- User documentation in `{skillDir}/README.md` -Skill 生成流程完成。用户可以: - -1. 查看生成的 Skill 目录 -2. 根据验证报告修复问题 -3. 自定义执行逻辑 -4. 测试 Skill 功能 +**Next Steps**: +1. Review validation report for any issues or recommendations +2. Replace TODO placeholders with actual implementation +3. Test skill execution with trigger words +4. Customize phase logic based on specific requirements +5. Update triggers and descriptions as needed diff --git a/.claude/skills/skill-generator/templates/autonomous-action.md b/.claude/skills/skill-generator/templates/autonomous-action.md index 83cae3c7..0bb8a21c 100644 --- a/.claude/skills/skill-generator/templates/autonomous-action.md +++ b/.claude/skills/skill-generator/templates/autonomous-action.md @@ -2,6 +2,20 @@ 自主模式动作文件的模板。 +## Purpose + +生成 Autonomous 执行模式的 Action 文件,定义可独立执行的动作单元。 + +## Usage Context + +| Phase | Usage | +|-------|-------| +| Phase 3 (Phase Generation) | `config.execution_mode === 'autonomous'` 时生成 | +| Generation Trigger | 为每个 `config.autonomous_config.actions` 生成一个 action 文件 | +| Output Location | `.claude/skills/{skill-name}/phases/actions/{action-id}.md` | + +--- + ## 模板结构 ```markdown diff --git a/.claude/skills/skill-generator/templates/autonomous-orchestrator.md b/.claude/skills/skill-generator/templates/autonomous-orchestrator.md index c88f25eb..a44c9869 100644 --- a/.claude/skills/skill-generator/templates/autonomous-orchestrator.md +++ b/.claude/skills/skill-generator/templates/autonomous-orchestrator.md @@ -2,6 +2,20 @@ 自主模式编排器的模板。 +## Purpose + +生成 Autonomous 执行模式的 Orchestrator 文件,负责状态驱动的动作选择和执行循环。 + +## Usage Context + +| Phase | Usage | +|-------|-------| +| Phase 3 (Phase Generation) | `config.execution_mode === 'autonomous'` 时生成 | +| Generation Trigger | 创建编排器逻辑,管理动作选择和状态更新 | +| Output Location | `.claude/skills/{skill-name}/phases/orchestrator.md` | + +--- + ## ⚠️ 重要提示 > **Phase 0 是强制前置阶段**:在 Orchestrator 启动执行循环之前,必须先完成 Phase 0 的规范研读。 diff --git a/.claude/skills/skill-generator/templates/code-analysis-action.md b/.claude/skills/skill-generator/templates/code-analysis-action.md index c0233186..60b1f1d8 100644 --- a/.claude/skills/skill-generator/templates/code-analysis-action.md +++ b/.claude/skills/skill-generator/templates/code-analysis-action.md @@ -2,6 +2,18 @@ 代码分析动作模板,用于在 Skill 中集成代码探索和分析能力。 +## Purpose + +为 Skill 生成代码分析动作,集成 MCP 工具 (ACE) 和 Agent 进行语义搜索和深度分析。 + +## Usage Context + +| Phase | Usage | +|-------|-------| +| Optional | 当 Skill 需要代码探索和分析能力时使用 | +| Generation Trigger | 用户选择添加 code-analysis 动作类型 | +| Agent Types | Explore, cli-explore-agent, universal-executor | + --- ## 配置结构 diff --git a/.claude/skills/skill-generator/templates/llm-action.md b/.claude/skills/skill-generator/templates/llm-action.md index f003a618..84668a3e 100644 --- a/.claude/skills/skill-generator/templates/llm-action.md +++ b/.claude/skills/skill-generator/templates/llm-action.md @@ -2,6 +2,18 @@ LLM 动作模板,用于在 Skill 中集成 LLM 调用能力。 +## Purpose + +为 Skill 生成 LLM 动作,通过 CCW CLI 统一接口调用 Gemini/Qwen/Codex 进行分析或生成。 + +## Usage Context + +| Phase | Usage | +|-------|-------| +| Optional | 当 Skill 需要 LLM 能力时使用 | +| Generation Trigger | 用户选择添加 llm 动作类型 | +| Tools | gemini, qwen, codex (支持 fallback chain) | + --- ## 配置结构 diff --git a/.claude/skills/skill-generator/templates/script-bash.md b/.claude/skills/skill-generator/templates/script-bash.md index 9b90fa65..8d4108e1 100644 --- a/.claude/skills/skill-generator/templates/script-bash.md +++ b/.claude/skills/skill-generator/templates/script-bash.md @@ -2,6 +2,20 @@ Bash 脚本模板,用于生成技能中的确定性脚本。 +## Purpose + +为 Skill 生成 Bash 脚本,用于执行确定性操作(文件处理、系统命令、数据转换等)。 + +## Usage Context + +| Phase | Usage | +|-------|-------| +| Optional | Phase/Action 中声明 `## Scripts` 时使用 | +| Execution | 通过 `ExecuteScript('script-id', params)` 调用 | +| Output Location | `.claude/skills/{skill-name}/scripts/{script-id}.sh` | + +--- + ## 模板代码 ```bash diff --git a/.claude/skills/skill-generator/templates/script-python.md b/.claude/skills/skill-generator/templates/script-python.md index 87ebb934..8584439c 100644 --- a/.claude/skills/skill-generator/templates/script-python.md +++ b/.claude/skills/skill-generator/templates/script-python.md @@ -2,6 +2,20 @@ Python 脚本模板,用于生成技能中的确定性脚本。 +## Purpose + +为 Skill 生成 Python 脚本,用于执行确定性操作(数据处理、分析、转换等),比 Bash 提供更强的数据处理能力。 + +## Usage Context + +| Phase | Usage | +|-------|-------| +| Optional | Phase/Action 中声明 `## Scripts` 时使用 | +| Execution | 通过 `ExecuteScript('script-id', params)` 调用 | +| Output Location | `.claude/skills/{skill-name}/scripts/{script-id}.py` | + +--- + ## 模板代码 ```python diff --git a/.claude/skills/skill-generator/templates/sequential-phase.md b/.claude/skills/skill-generator/templates/sequential-phase.md index 859e8be5..e4eb0c14 100644 --- a/.claude/skills/skill-generator/templates/sequential-phase.md +++ b/.claude/skills/skill-generator/templates/sequential-phase.md @@ -2,6 +2,20 @@ 顺序模式 Phase 文件的模板。 +## Purpose + +生成 Sequential 执行模式的 Phase 文件,定义固定顺序的执行步骤。 + +## Usage Context + +| Phase | Usage | +|-------|-------| +| Phase 3 (Phase Generation) | `config.execution_mode === 'sequential'` 时生成 | +| Generation Trigger | 为每个 `config.sequential_config.phases` 生成一个 phase 文件 | +| Output Location | `.claude/skills/{skill-name}/phases/{phase-id}.md` | + +--- + ## ⚠️ 重要提示 > **Phase 0 是强制前置阶段**:在实现任何 Phase (1, 2, 3...) 之前,必须先完成 Phase 0 的规范研读。 diff --git a/.claude/skills/skill-generator/templates/skill-md.md b/.claude/skills/skill-generator/templates/skill-md.md index dc01c0fb..a76bc270 100644 --- a/.claude/skills/skill-generator/templates/skill-md.md +++ b/.claude/skills/skill-generator/templates/skill-md.md @@ -2,6 +2,20 @@ 用于生成新 Skill 入口文件的模板。 +## Purpose + +生成新 Skill 的入口文件 (SKILL.md),作为 Skill 的主文档和执行入口点。 + +## Usage Context + +| Phase | Usage | +|-------|-------| +| Phase 2 (Structure Generation) | 创建 SKILL.md 入口文件 | +| Generation Trigger | `config.execution_mode` 决定架构图样式 | +| Output Location | `.claude/skills/{skill-name}/SKILL.md` | + +--- + ## ⚠️ 重要:YAML Front Matter 规范 > **CRITICAL**: SKILL.md 文件必须以 YAML front matter 开头,即以 `---` 作为文件第一行。 diff --git a/.claude/skills/skill-tuning/SKILL.md b/.claude/skills/skill-tuning/SKILL.md index 5f699a01..1732eaba 100644 --- a/.claude/skills/skill-tuning/SKILL.md +++ b/.claude/skills/skill-tuning/SKILL.md @@ -278,6 +278,83 @@ Bash(`mkdir -p "${workDir}/backups"`); - `issues`: 发现的问题列表 - `proposed_fixes`: 建议的修复方案 +--- + +## Action Reference Guide + +Navigation and entry points for each action in the autonomous workflow: + +### Core Orchestration + +**Document**: 🔗 [phases/orchestrator.md](phases/orchestrator.md) + +| Attribute | Value | +|-----------|-------| +| **Purpose** | Drive tuning workflow via state-driven action selection | +| **Decision Logic** | Termination checks → Action preconditions → Selection | +| **Related** | [phases/state-schema.md](phases/state-schema.md) | + +--- + +### Initialization & Requirements + +| Action | Document | Purpose | Preconditions | +|--------|----------|---------|---------------| +| **action-init** | [action-init.md](phases/actions/action-init.md) | Initialize session, backup target skill | `state.status === 'pending'` | +| **action-analyze-requirements** | [action-analyze-requirements.md](phases/actions/action-analyze-requirements.md) | Decompose user request into dimensions via Gemini CLI | After init, before diagnosis | + +--- + +### Diagnosis Actions + +| Action | Document | Purpose | Detects | +|--------|----------|---------|---------| +| **action-diagnose-context** | [action-diagnose-context.md](phases/actions/action-diagnose-context.md) | Context explosion analysis | Token accumulation, multi-turn bloat | +| **action-diagnose-memory** | [action-diagnose-memory.md](phases/actions/action-diagnose-memory.md) | Long-tail forgetting analysis | Early constraint loss | +| **action-diagnose-dataflow** | [action-diagnose-dataflow.md](phases/actions/action-diagnose-dataflow.md) | Data flow analysis | State inconsistency, format drift | +| **action-diagnose-agent** | [action-diagnose-agent.md](phases/actions/action-diagnose-agent.md) | Agent coordination analysis | Call chain failures, merge issues | +| **action-diagnose-docs** | [action-diagnose-docs.md](phases/actions/action-diagnose-docs.md) | Documentation structure analysis | Missing specs, unclear flow | +| **action-diagnose-token-consumption** | [action-diagnose-token-consumption.md](phases/actions/action-diagnose-token-consumption.md) | Token consumption analysis | Verbose prompts, redundant I/O | + +--- + +### Analysis & Reporting + +| Action | Document | Purpose | Output | +|--------|----------|---------|--------| +| **action-gemini-analysis** | [action-gemini-analysis.md](phases/actions/action-gemini-analysis.md) | Deep analysis via Gemini CLI | Custom issue diagnosis | +| **action-generate-report** | [action-generate-report.md](phases/actions/action-generate-report.md) | Consolidate diagnosis results | `state.final_report` | +| **action-propose-fixes** | [action-propose-fixes.md](phases/actions/action-propose-fixes.md) | Generate fix strategies | `state.proposed_fixes[]` | + +--- + +### Fix & Verification + +| Action | Document | Purpose | Preconditions | +|--------|----------|---------|---------------| +| **action-apply-fix** | [action-apply-fix.md](phases/actions/action-apply-fix.md) | Apply selected fix with backup | User selected fix | +| **action-verify** | [action-verify.md](phases/actions/action-verify.md) | Re-run diagnosis, check quality gates | After fix applied | + +--- + +### Termination + +| Action | Document | Purpose | Trigger | +|--------|----------|---------|---------| +| **action-complete** | [action-complete.md](phases/actions/action-complete.md) | Finalize session with report | All quality gates pass | +| **action-abort** | [action-abort.md](phases/actions/action-abort.md) | Abort session, restore backup | Error limit exceeded | + +--- + +## Template Reference + +| Template | Purpose | When Used | +|----------|---------|-----------| +| [templates/diagnosis-report.md](templates/diagnosis-report.md) | Diagnosis report structure | action-generate-report | +| [templates/fix-proposal.md](templates/fix-proposal.md) | Fix proposal format | action-propose-fixes | + +--- + ## Reference Documents | Document | Purpose | diff --git a/assets/wechat-group-qr.png b/assets/wechat-group-qr.png index ea691d82ab761dab65f3d698e0158e773a33da66..da1fdce0e3f7115a4d4982adf0dee28d0a5e0700 100644 GIT binary patch literal 233044 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 R9O_djU$~@@C4cqa{{dq**H8ce literal 188291 zcmeGDRa9J2+ck)i-~^Z8?(XhTI0Ow4+}+(R!JXjllHl$VG!#%+aM$2cxOS2E{my@S zjK1jW9$#_6s$FZ#BlD5D){a#9B!hxPfCL2vg(4>lP=kVk;e&#L3r2v09Fdk6C4~HY z=c*JifdKjVA(%x#L6Jep0mL=DvX58gzEfETtlyr!danpmxcn^X zC`eOLny~P+J%X1Qkf92%$^{Ka!S@T%;@M3B6l0m-LKEG>I>cyur;=L&5e%#uRks3z2J+! z-h;eep6-7N(#R!!67##;40k+y4VO*28r9R&JI^@_NIUb}@9?|2j`zAcXOAZl-pcV@ z+uYg;iO4_V=x3`na2(<9$8_q9UE9guihd}pIY`NihMVE4Uq4$syPegkXga^#RS
gY@~` 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 z z60u=Cm@M$qygS*D)(0qM=zasF=_U58*JL{9Ax7W{=%zW<9hkt7Ou*gms#0B7H2Le; z^gam*#%u%|3TdvyhJvx7Quy^A`9D5za1P&n)&}K_3QUasuAtZ1ws9&7U3-O@K7W*v z^&DbB(HWdJWXKDZA!^hi3Rprj%@@A#N^#FgcNF-TT7JL~3~pt5|NX+Z8K>;BO-B|& z-ct(w2cE1LEIB6(N^zsZV}7XTV+G;?fIgvMV&DCbmF7sW0f@Eno*wKrq!)tHpk|2G z8@@vvb#tVoq{1v8K75GI1792==ED$ro$7qey=+w4Er+%O<;UvM-Y&Z1fC0kPqKxL}y2(uH4`vX#IKFlkJ_9x-ZSc8s< zp}sxqA)be7-3x1TMJ92w!MsY&W)FI0-;K^=06tfS6-@b<=jl8yKvN|+-XbS?aMYax zmK1O;Aedaq_?1()1tL}rk5|5J+l=e&qwr{?5)j*VoI!kBx8}Xy20osOP~w-(#7*QXVc3eu(FCT-ieh4QQ6K#!|8tyF{onl?aX zirHVST{oYFPX%wc5>_7l>u$)3^!Pofs$*}BrzB9!mm}Z45U~Mf*!M<|Hs;0B5%&>{ zBd2f&uyqINcaw+nTsJq_intfHZa?I}h9ps4>1R0jodKiyC!1@gG(| z%p=rJ0g|vgov%3EfoFaI@_jbi-UQ4>DR*&SHywP!fVf9h%RE><5XW3pKc3dtkHv=6 zfazSD6ToS~w~|tE`fej!WIXWl=s!nfB)N=SI+FX);7QK)unv7&3tnKO7pz~+V4x}j zJU|TF3h`^)CKK~iJAGbYD(Wk8<1&5+0Sv%OF}&)DkseegSFp+_izMCsqZzUBob|#8 zu=w8^vr|i5Korm=tT#~rXHUv3=f#tegR6k-1z{av=%8~&J-yL!A2&RusdR8! z^=A*x9|Ou~U@7XuT-@9lm`6b%1quctSz2!5+a`>1f>pzi$Ad_s9i|Oy%aWC6xt*PK zSFx~oVNXoGJPb84l!d#pLPRjX;-zdf`OV-(1-q{z^?K$Xb%7vlAy!=_5C;0!K^KuF z7@5IC=EHRRg8ojq3<4HQ1ruJI&dx`ix)Ah$n(_ygmMVfb1G|7YM8M|5xWc_aY*QVk zWfaI-{Mh+83-pDpY&RW!vzlftoJ1*wP{+tk{kE?e+E?gomm$>?>VpEK$F3aUi%|XO zU0aB^AGcZ5cw70WPu!q<_?h3V=LZ$?in9ek)CFVFasV|#t2h0iurDAn2uBjtbAeL^ zZ{4H!BS6Y1BYUHy$OIc2{=iw-u` z-#fqwIMVI&2yhxo=}z9CEu_Z<#{^yM@fNX65%%>83ZzY<}gH{wFzSf$!YDQa3#gk zYk6q3=kozoDx$}8jSJC&uk3IT)xh4LP@qKixMj)4EQOEOw$PB zA287M5COY1tzaLv#twwYcbB)~n>SxTu4Zi(MxaffqJPLin4TzWFRAkBH~hA@NAgI= zk7zWGXSKE0x()SgVIL|_wV#D0646q}bcVXgVI%`o-QbsHBhuIN?0=rcWo7Yw+nd>r zL)dnC`~Muc3cBYB{jFTjfFj+dva$=^gXKRF>-zA0^r0U2sV&yE%H1`KaZ+Vh+ci&} zQ~qTCAkJw6M^(@TT!jQ8x_#g%1A7Z%sIV7oDRvXa6zSSO7x|O}9*kbz&3`|K)kaor zdtm)&Zv9Zrl9ZG4QnHWnX)1D`JS-7;xWAd9BG)utI)&TJVRN8S{4E|{bJD5JUfmJ0 zJta1zdJ1-%c%Q~Q9)i`AiR~F@YRmp4ik^Mn;?pHe;yMP0+9z6{LYPdpEss63M$Y88 zlsS}ZW=B1R>n`=hcDKhShEK_%*tkn{`m0Cyp9X$!UCptJr}2t*Igde_@gAPW;{WUvE_V_4H;uttKK!_baEmk^P& z2yK7RS);R^^lAw%a4POVGOxYp^5x4x4O2yyj&vW$B(mJfl_O^zh!NosC`b4_0_hZ` zo#1O-*3OxSEpjwUE3x7{hJTO2Df7AfB zUHkC`PYUKI*%#dRW7`3W5vWUkm84oL*{s!q>y#K-|Qt#|jygb+AU)(o8tw3c0$ zP6vob8L4_vcuy=a`tZN*MH4%sCetL)!h&Cf65srWJ26hB)x~8=W7rmTMA&kZ4!SeK z?8yHE+T^Z?;VMj6LT64NV8d{YP%yHj*1JRaw*Omc)>^>iU3iM54DV|)151N%>D-Yl zh}j3m%TyYhTYz>FaT8`o%1>OfgB3bWkoqrUx}a#e)u73U5fRnz5elp)+YIzCg>wKR z1Qc%TFTd0-4b47f;N5cx6aieRe5%&5DgxiII@plBI|QJZ)5 z>f5C*ctDlmaaf&o1!LD0{Qlw66upWEKAdBus9$;3I0=sywUjVDUZIW~&qTU4{}!{}a= z0cP)oKx6E&^XkIBc^hMdMqf49Tih{mj+rnkEXQX5AT!fks2HCY zeq7%B19^A}=k~~r&&KYmVF$uq*)1Tb9<%>K8dmW+PtypX=0xoj25|2aIt^Y-XE}20 z7N5?GvL4VUYDLxkBoMh_f6(;8H|+g?(q#=EvV5?M#P3 znIi0aPsq+JYSjGmYt>4m{%Q=kQ(+6%i9|Sy@uJ5dyb1H@cnnf`_`*)=d?arRyiQ*X z_Jl!#+a4fR1h9fN-4*aPTS7=X-Z{c-(`9hZLQHie<)nEBd`78$N8iPN5KcwkrFCIiYfbho*3C%%#Nr4m@;|Vu+U!4Z z$|K9OJ>!^T8yEc#T$PVCe=LA4TA6Kc{`*P4F?bN-nExH%P&K?l#&1c?eFwho3fEwN z739^PNBMDnz~3`(L!xlBT7KrLcypZs-k#g&F8&LsUS<5H;@7pwW=fg+m&Dvl^}}^r zvbO)lR2gdyfVm{myh{VZe{L{-U?6{utE)`93?83QsK>4!M+Y(g9AeK+`f;A|9iD}P z1vGJAGK@yMFe0V(t@q;@({Bm001rf$g}o`);Pyf^?7)3aM7%nSGMqxxPO~FDX)r4= z-P#QX9z=R|fvK@^RBK*v=63fn7D^ZGfewYUsTj7nLNU{jYuAFKqF$vk2S8>H4G|2TN$$XrM#!BO57iGc?jr>Z#=hTffgp;(4V zuYlDz+4QkYooxvPf#S4Qe%T3%0ovh<#Loo1xYwk+wq>_cScs8#r`wEVUfR@ za^`zu8vwaSPW`K}j6(%ta2*pSVw1d!i;HVVfN{@cz#rg1(0~3C$8&CrM*wK&)NpBD zWl0GvbNQ+PU2F4<1Az<1!Y&v5@^Gtk;H3IMKg1(|Vs~wG9Z|EeO#tjL)_Q(%Lr*kgl@T)YE-IzfnIV>69mL58y-b();UfW2njx{F)o9l_aBcbugVMo3p!GU7^I z0FV-(ZGc1?t$xwMv+nMc-Kl>D5AuXbHA+!M?8RbdMzaY%L+S_Vd$+j^&BmDicz41pi@>qKFuSGSk1&{Qu%lK~=SiCn%Ni{eK#Ycf%ta6v#`p@jdfF;nO6mt=wg!#vm zF455Z;X|I{_015}lc}U5Vj%`J*zyt(C4r+8)MF$?>_`mGamX-*Cq{ZXPCX^st zdGkhFXLvrQbW|_sUq}2f2*qiPcoL8-B4<~Iq4n@IG)50~I|bIR1?=}DpcL=^1w4LI zFzdqV^!ytCZkQ@S+Ee18&hXW1n7G>j*;qAh!DF}#>VVx*@(5^jAN^n@6ppbFMq1sT zn|}B*)NIHkUk<^PkDDq~W(qg4MvEb*sPPjdI45TsyNvWTahkag&Z*l1{#Oz|nBPWD zH%@y!x!5<^-o$-HmaBSq05Y?2tpQoimggk{C=3r4zXCrzvRgyuswyjlF_q0_-hi-9 z+%bhMMv3!r^OWNwfOH?qX0&}5FjZV;v4*!T?k%(;M1hcu;OtAbzSB@{(d3&|Zh$`l zazzu}(B00yzI!9TwgbQdOJffE;4AUW%*@-`>z#|Q2VO`>;P21SAd?Mv4aI@nXGmo^ zgoTZ9!Gd-J3Zd)HrXO(RyMhott68KMPWeN&NC*}!T#sp;GxHdq^Ec0Xu01#Pe4xsw z3=_5U+ur8K1*Vq`>Hy_n9E&iF#^~}Hj|wsOSr_ool>61Srg@fV{-Z~&r1Fl@1n7tf zk%E7=KF2Ek275!os1+C-3|goPzP|M}448y!<9NQF$GiZ6n&j`q?9pzJj;%VbaFLn~ z7dQ7HytIRNH(?Lp0-}yZ)cdPBWbhcQOizX*HkYCt*SCm+74Q6$KY~-m0{54tqIV*r{(dYltePgAvnYud%+$*lf&);LI}-B?v+&`Lu!SeUDc zR1K&WjK*9riATttmFe$5Zjx~~=K#jgM+F7Lf$SU{249h`P=kIDEQk3Y`}P>39?R&S zZC%k>w{2*1Vt51f0{MlVqClF}19lx4rga<;@nE1mZh9pCJs22R=bmn6e(nP8LP2VLD9jmh^oA^pbk- zHIrfuy4GHzA?A3+!)X6Ae5`S{UDAIkcaa)E0TnjFjGxGZly1qaxzWn%R^#z)yHft_UT!O(TNCfFEpc?u-$~1N@9hxQ zGrBTB?zF27Nk$*ZhKV_kLEMEF0G;=S7e0&9Mqx_Z0& zPhximJDlF$z1&Yr?j^k( z6|l_Dky8w59KE_-aUc}8JQ!p@@baF${|cWIdTdh=wc970T(5oz(2gQfxMovF>jm5q6A z*xw$>$k;;U3ws`@frP_h=iJa#bhZFodJVQ0=Y|iU?GW9+fEe#KY=B?5t-wgB$AI$k z#j1nXaQ*s4#8hM(dC(L{1zyyuO5g9V`m^7avJrts&8}9psoxs73g-f3DoeM8<5vLp za?6lnXmINs7%*lyh|{33mwMhn#&K>72QtuxW3{l?_EWyWfU!>&6xGd+)Y*=?hc%N| zxd6CQ)iX&H*7aZ^N=(#S&Cvz3D3M3E#W5lUKwnDHR0JmPyVWiYMsgKa2mGxKQIk;m z!qd6{)*j4%NBr55KL<%wj`4W-S1kJ^w1f;N(nFl$6UelUyPD}%CH_h3B+29NSsMyh1jJ6gl$hCsZVb>nb#>X?-QAIO4{17}ol_W> z!YaQA!W?_V=XNc==VT4cHq(ISg3InK_gK-WaA*lmyClYGjXjj-m1jBi8cwi7~LR% zyek6HHxvdw0G#GSoP)>t9HjC=g&>{{@%1R;nW^D`Bbb}FcHP5_j99nZzI)l)SCa{i zECA|e>$u8mtZu~s+*klDETbS4{gjL+dE^}4gOZw>i~&3U+IK_*BMwf)G*b#J7iwU%I+ z@bSvC_=yJJPco=!X#qJFDGuvM!HcJ68@-7M#J?zyUog6hi{c{YkR=|Xwi5`zfMFcN zV0@`G5HgaGF}$5xj70_Zp`CtqNS+Uqk*=snN}C#l`~<9{g5`wUkDjpgPKzH?s~WCb zjXtq0Tb2S$TC$l(Fa@CE$B!SGu-U- z!TR^2lxr^!s|TG9Q6{<q{`+NHF;?${?sK>`1*ZXrJ$|EPEj6^`66gwh%${~Zvq8WZk_m4!p~_#DfmRaj^#WCZhq zM(;?KRLemuM*Hh{_xMIoLEEwUgGp_6roJ*zITI}+ZCr-uM~CCw=u6A6aLnPL$nig}k5j*%6Whb1Tz8a@zh z*9~dVJQa<#EkH7XMA_BK4%(vONl29(FvFJq06|V)&4z7{AAbWt0L%Zr%wpensfLSj zU1@NJKPj-?hN-Lc`SUh_yBF$AjEyOAmFiBd^T2x$>5OSOteLAOVK*mTO|SBZ4##2T z8xWu;vz2G->9u;DJ9k9k5~Xx(=(;a(2h)XxauhPEawU0AO+rV-(s5<6VmGdloD-ia z+^udx=8D`ZZ~S_M;Y^pJphhvuqt_&db5 zYm5)qpkWnSodtki1;e5Khy&?@*Cjk0xK@*rb+Adkfp;=-XilHBsObFxI~@}k4ybei z?_Y4*zxcjoK zG>ATm?{5C#U-VSp1{c)x0<-Jnq+)=ltTdPxy)q##yo6Yt^l5qkdg{#Nx6X<^tUckoB!wcui6Np$0xq-c-_rfsBXKg&tn7>k0ND5haSAI@2 z&b#Im4UkIwu~0aR2@-yk)2*Lviul5vA#w6S$ z?6Y6Mwq*-HD_?P3dK9Y1Vkgr}Z-1BBHSVrp7<53frtC+3S^H964ti*q-VvKMxNAIK z$8cAQ$uZZdW3JnayOhg9bPL{%Og4-R z343c#9KhEbzEe8zW^~=J%Z(fU`O>;e0X!x<1lD{@HtFRw8Rs{pFA24heeAg{u}?FL z6&W;hKNKE=g=qGO-ODaYPA9aQP@ky zUYu@et$Ap{UIcH$XOok_Ak<@=aF*k!9PpErtsL{3(U4rz(QZ+8(7-vz;o1h3$^M#%}^r6~*y-)XhN&Z+Q_kn!F7vgI4$TmvR9Y6^#)S(uPa)yu;u_IP{W8X01golbE z(vA`+3)t@xVC_x!>aZcQz^Vtfnp3M9BonZ0tb=pK#Kf@E{9QIkj!b6DZmKQftWOCx{WW4uvm?=jNGgzp%pWm=hv zg%@)019|N@atXekd00OxHkKDic|-+jVAXn9gEJ{FCk(yFJIn;JwMND zL-(whC7*I=`{WFchgT9xF`7}Xgk`p6)3RmDo*?Bk<@mm-cAu`5IVbrP9YTWzG5|V0 z$ILjVe`AUo)rVo~Z$)4nws9L7Zhmt)txyEQPFz1?yE-A{5%PU@XchVN91pI|VO8I| z_xfs18%xK9gS@3%URPGKuMNa2P?rv5KitIV_?!LipZO}BQ{~wS4-MEcDXa7+rym80 zDDxq3J}c>mMs5V(8Lf`oq?#%#)$D}r_^X+pe(brK^Z$a|9Ooc{a@9-@ID&l<$ry}m zyM>4ffX4Q8c}K0{;dYaRlp(Q`a|oiZq(!w`|F&S1rebIP&==1}|j7 z+^IM7mUZZ2fMPUET;H}G_m6nT5bUc+-40AiOU!%pi0p$xl?M6~B=*oNa6$4D?BlxA zzPi7qTM(}7<`ynPyAFgcI?HDwGf zCTmVii|g%fA+H3hXw{NV9Ei?98vTaBH@tapNGS}hTF*fAs1zRy`7!nrXoqpW!>)Q` z#u_OgOCvY5Ijb-)cq1KQbw<27I1O)yQ;aG-PN#r*uEE-j{ZgnBQg^tymbgv$)KktB z&}Q=$X`$`XIPq8W@x{GAcos7ddG)Z_8;FJgVKL5QL->sFmUOJ$=s6XyQ_+W=2-Ay6 zTh}j`Fo^YzoSeeZ8Gv%5UB!oHFkovXhaFnXl4)9}{hzv8vfS5cMfrk%NVMgGzZyt2 z=SqiKNcOrW~w)TedJG(73H=$Q|}SquuGE=UkG zAhbv=XMdVxxKIKsHk`T$NoqjE4i?C@Rrh!^Tm+ONlsGjAoMerN$U-0kdN)k5caWLR z`hhV6JSoosRs=krUkUjtILU88EeN|W%?Dk86o7+0AJ_X5#BF2* z^PvzqsWHP_-sZx$@iD==G>!Bi0{Q%+$?Ewk5#yln02VuTj}aA4f2 zG;b^eqd6XE9SAPlj%e15zm=Z79HJYwDT!H8x`lpCy-C2cA&vA_?7hhN%&7+l zko!lk27&zjIad(iL}<+88~YjIGoh~GVT&T9-}@k)jC_LKxsI%HnuIeqWPQ$I?U_AxA;G?6B z-^e3P;O87V`D7PM#$xQZ>5#$^#G0uic7l4w{zz;`eOR*{@W3!ryJPThk1*B8`RB-A zP%QcFyZaovm?`bLF#Mh^sOU%>&Qd68PN=3g3r|9qGF1O8#Ru`q?L%WCNMVh1g|jgr z12Bl*k-Uc^D|zp|73tGJS6$+jT1nWSOvSyNf;fw&7){_{fy|h!S?VWulYhm&^Z5iE zJ}(QH14u(%T$SL3H>d7Xj1S9}>9b4D*d3+3d|_IgxtcYOwIeb%uHzi%0xhN>8lC-N z)i232!8v%2Xw~)U*t9G*zdfqv`;{uJj^&Sa+)eF@KNozhyTb0W3`bT-Vs36?c)Dhn z+sIU@ja2=r`8C_XF}YqT`j&l3^p>Rd#F{TtT~j+`tzC<)X@lV`R(%Wk#x(w~oL&?D zc+5w}?@d_<>)E58H=0l0FqJ!$1UFm0THS;uR-JV>Y5JJRSGov zL31-LO{qENP?NUZVKDw&BMeOO<3B3S($v-+1U(>p>fFqD5`_^_VP1H^ASo3Ai zj(NUOnSR|xTWUrIwd*Q9d9qjjvp=m%5IbO!uvmaKzcCP!f;oP7US@FMq6lnvIN`a= z_G~?xy0$wunbk;3=3IIt`S|RQL&c0PAKCZ<^TpL=RxP+1AY+H$L-FiMHpTks6|?(U zS?>Mdp)|;(T{L}KZU;> zCncUgP-_OkKDi~itkyoW^;r54#Jx$UUerigcNtec$O)bh{iGoX*i0?z@>=<(5 zndE5!KuA&>H@S&Hl87N`V&D)WM+O7iQ9_4H9xxO-l&=^@!x>J6Jg{8*%1Mys@#wWs zu^WC8f=)X-zI;Is(n6@(06bWIc0ee3$V>k}6!HdB-P}z_>;XUFbXbOJ@kLNKG7XCj zOuEi^0%F4s4M+*gFm}E#blHT=c5#vr_7?Lbfsj!bc<`ivIUJ7T0MZ6n)zoxgU*5_mIfKQqJ9)J?DsQW3SKar3@W)%FQ zXlY2ujsfi?vM)2P zuMK`%q*ob!n8arbt4C!Xf3^}L3$KfrF(at~!EafoT=(@=Lqq`tS=|m-76Fx*y%!_$ zK*)Y#rUK{}JmU=x^``8?mjHhAL16hbDPgv2svUYNsE#p5aUR5v9U3F8H0(C_jiMl9 zLOCSIs{YDfQ&5@Wb(cuBxZhcFr*%vQHDlyU+^Dtd$AZQxJpBo)TSA2o*vK{`5p$qM zl_zZf)E{Y>7=%Z;*Mx%bqNJGdF(-WTz%~P}E#Up7j*2ZMLuX}SBq;x9A=&#~8XL3{ z1TuN;YP+EALZ)E_cM{%zL}t7FXA$WLRQju&t5Mz+^JD{ zIC}f_`oD@3HHyfch7a6)Q8|gF1|NqZast{10DZ1sWUls}p7zkP3;kS!i7Ma0Izya= z3AWHxM0&y8SGY~Y=z+pL<9%=vMq7I+1-27?LdKZVape9{F_c~u=(ME}r3u?jVgg3C zE5YdJ%;4IcPXo7|DZtCGt=Ay?)R@Y}%__9z$^>&M;bOt; zhKoUHb?Ok2?GUn{&JBD6lI%V(z3^x0{)?qBGY{^1%$|a$mr>^7`B-|M>la~oqHHlF zE-Js)a3Vhe?m7}QV=^YW46-5%-xuP3F~@wa!P$ac29cd*xXs>H?Bjq;f*40UBoE63 zI$+j^y^d6Cp^4OOgkcXgH0JwHU|tqS4>@!?!kRoNQ3DsJjS!?nY2fk8w!1oHbkpC1 z&0!&2RbeQ=k$_0-G7tv*=>DP!W>EcB6=lHxFrBVjx6?WwJR-?T$bu#q2*{FD*5t(v z6L^Z&g2l);)PdJ6aR{HK7erq#_U$^4uc8v}=UHvi%ruKZtP_m$Sn_0jvJTLnb@1p$ zw9yIxoZCS5r0r12Jf78Li|TE#5;|#Rl_a@3WeIMeL)Zt%FrYUMbb!uD8JGDpw#O-s zMAeHGIi3rZy^0km2r%tNCrm?Hdw+iWu*Q6EKB>iwkeZ;^Id|axV`mo^iq}-H!#Em% zS3EsA$*hJJX#ck#7Zs_~5Z0uKCMVn+8K*nc6Qowc@Yo8!wdMDZ3=C3Ix#sD@KL!U0 zB*Lu1Kxq_ZbEl#KG~viDug{yo04wMi%DBaky%S03hOi7_kPKeHrRh`!z@UAj2rBrm zs42on^b{}xrnxHPOQB}COj$6Nf5f-I-17{NF_l;9D{!$~!~ib7`27aV((ojjmltF8 zvH;|O{;N55*rv-Te$+I+Kr{pRXSDo0DcEwL(ZoWRTJP~=T0f=U1C9~|XO&+B2XEs! zf&8 z!U52LyaDi|;&ts?R5%{1pjZ6b_|wj_Dq{J7=qT^FY&2cwq}g5I+ZnHg9oxVUFd&Sw zu$T1*evd`q#@bARI&>D;BE_;IwLM7z{85-(L$b~+((X{YLvWtOzMK1uj3^+cuy@xV zx5A?<50WDo;DlfBBHqTo7_h8#);!0ZtdP(iN}6^x?WtFqxN>xjP3~W7lj{{xk5Ym9 zU9+Pv9~IE-m(mn7yZP5Y#Qx)r$C^gp|De7E5YKmH1Md6JXp_#EU+b4F+#7rHs2jVj za^LlTW-`neLH8l&P*jJi))%VUUl((vYIgpAaaUet274>4lmWF_)S3p(pXM4f;-!YT?8spUza?1_;)}%5Smz4T1qoi zq0DSt+A|S`n_vx{=onZ>q{~$;A*Kq*J41gLF|u>kEamw0U+Y-FUx%~+=vgL95D!n4Zf?Qq7o<^ zTPK#w84QH|N@(FT#v7Jw`g9@2a;krzgqVAEz_#%et}!2mU6<5)AgOkCNI)r#fKc^s zB0vLHLY`Q+OLn?T#NBTgs0Vd3A|)r~G8xIRkEfTqpwHtyWRZ1KeWcU?$YNdxMfXNL zqKJ+ae2wGK4pQ5&4&MO;qLE)cZTQ|=V4C1L?|G%gQ+XVP9O0oK*=Pr<&@cKjW^iu^ zE68~1@Jg`H)0ndlRi`*|rfp4t#17#B$`NcZ9-o-_6xlkM{5AU4At4XbLWPqTVS!|hsFfa5x9mQsn2khtapln{O=G3=Z--3RjUH=WC@dH z{)-vMDfI726>wxwM}Y0`*TwU_Sw=HcS?*X?EPD#bViE>= zIgOv@GHh#s#E&X5@eCIc*8-MKD2&aYpY0f#9`hOMv=gsu?mIBV9FEbT9hu4lwZp3MYe0j+tTW77fve}Bg~gprZpf{!Z#`25+#TV? zw_NPf|+{AxXdA6KgHwqvIpa}*AM_Fd%2w^Kwsj|W{ zh0r!bmyeXKNCAg7q7)1Ts9S%P>WqVURwE!$P@H1^2GF1@adyfBc{$S#s$Lb}_oPkO zZ2M?zUBB;0ArB#-!U?8BxE&)< zZ3DC;vI2RPIi-VUnAHisAYTeq6Z;~m3JxNoUoa>~RAAFu17{=}qgeTQVrdy@Zf@SV zQTy!qB#`1rZZtI)D94#`5cc$}S9q4M0d9&*t1UWRPS*bGLi>pW@GViN0eGT-C=T9l zP$3Q?;3O6_y+#LceK(Yc47nCC^58^L#r+i-h>k5xO>;r$v+##Qq0@%vcd~Jwgx)xI zMmDJ0%H}>qoXbkQ^w;iz!;meLcieT*|4>{3Olp{-nVI`|@stL?kJ}-#cx(nG%n_S@ z<7;QCs8P^pU3)b#dyZ!`uvsVx8;=Lfb+Gm#+|6z7rwF?6*MlXhg71d5^JS=zo zma%L0M#6l95b_K{Xb`}Bg2Br) zy?o`#Lf(|V0LKOsr_XgUlUZHEF^aKIQj%`@GTX9=J5QnXbyKNU1_b0Wc~2o`1_k;e@6@Vww=y^)! z9`!7WQl4;M)>kdS*QnqpBHe8~el?WA*?w9x7*;XKS-EqmJv?d+WiI zo3e_JdQR0$x^MM6<92zplbzLeZQ*3ikuv(KZR4t|WH;PAkOjrm|J#qgkXl!ml{Gu{ z?TYJ}=4B}1%SvsvTyw@_SyrqOTi@vPZ@|YlZsB!)OZF+p8=gN4T0X;YuxR(bjJC9g zubFml{oIqKe0P|=O6%>;g^g)T`m~N^$;Xs7EiArt>QF)A6|X+&OlNoNhvw7YA^NxN zmX(0Jy@8ipOej1$(bO_|5tRfFLOJeh?OrP*kDepxQ>|WK{+N3HaZLC8`Qrx)x>R+S zYbCLh#_~(`^_zo(c9K$3yPNyN3{3}rIayf=%$+xnKP&@SD*%MulgGs;e>D`VHz%c} z%nu0(VNKR__R%ed`xn&@rM=lw&CW_gR!)wNaA_(GdE7Ku-}-xZckWypjf{>i!+HADl#{{v$6G`GetR-XS5?iQx`q0U z?p2-H4W=Q5i*-bFu!=Xc_NlX6XuG)bgpvL7_V#w?o|L4g+BZ7_+DAqtA!pao)0>sO zpZoghhC0Mc_%)ciEt2}=zjzHk0JN^$!_Ewo-Nu_$)YXik!TW@~tZV?B4vY85jmJ0i zdg6nH;oBEvWq`~U+M>9fKAv-Gb`hw*ds0U1@dz78JRLJLv7Ti-G7gL_Q+N)9sS|7mOE`(8ZdLBH#v z^aT&NzEmT6#?jI7jYa$EyaBA4t%)~J47t9?gnAyF{(_&;0_vHiqhCJ=bHQbC zf#25w^>yvBmsT+;UD=y@_wLhjxzUW4^hiZ?#_2>P|%F2BAXlm`= z{me>kc)3nz4X%JECm9~28zbqK>)qtjlVj!b&qvgh_{5jBuKvKJ>UHPdy+xhTPNvIj zlqRFxzUMi^JltTcwRRR4&Msx;wVtm^cHCUSzENcr`#d(BbgVV52XO>!K2y|jzGOWh z13o?`WsiLT!jUo0csc`_%7o2{6g*Pw$RAjJ<#VweX$7n>9z3-P{VgN^K2|?dFIq z-TmT+>Ei#@-h0P$-M{a{l$J^vNir&t5GvUtlA^L#W+-H5X18P$l1c~_va|PytSckg zD+}15|G4k}@5lYe=X&(G>bk=F{eC^q=Q)n^IFC~}ib7&zT;Ve7qJwZ$ zVsi3lVvo&47={*Kyr5+duZW2!41*AxqCI@LL{EdAMsTIq?sw$CUm4Z)qCdYPfB$p7 zDaFi_K5!?YAcY6WIU!OuSGl+4+qX{>VkLUP7~7ylr<+3SFmBk#j~p@6JTDU4%yb;P z?yS}+cu?7EC$##edn_g29|_k`AGz!2@Bca2^RJPT(A_uk1Q*T^sp+%Hk|X0wE}}31 zA_`v48Jd_di>VWYce=MaH~7|&VD^b*vGq|M;rv=mbDlM?+ON`u@*7z0RXi z8Ct2NdHdBM;0zn*)`8Z6WF9^-u4zQm-A25^YJ>jfqmLgyz8$$PFaI;URo=hTS|?WV z7T~tkjag5g2~n3Ov6UYoSD5x_Ke~TH2nl)jcm8V$La!?iNq6t7NPP5Y+uwn$jhMtA zJ4v3uc<~b$`W1A^J0~$aWmB=^@Q;qN&784;I_T2{U*j$yqYq@8S_0>wk|kL51V=t8 zmy_AR{h|FYud}6hRQEsM-ca)cQsp%~o`0@kBl#2MX@`)|&_^P(#VU(tm*w75;Zi0h zCi+};=iuaQX>Vtn_`pEIT`)}b_s1@Yi*j;)9h1ykt2MvBt0?$dd9L)k@^BYToiokR z8q5JrTE}%dXSF@AlyyzS6D}JbXLiX2RV$Or*m0$b{Z2xF!MJe}mo1t1<7i{ndq<^r z2s{{ZTH&Gzl`JnfA>C$#4&%gIDYwB8}p`!8_?@+;BH?44jW2&!6Lv`LT zDL{tBs&JeQZ|7FQ1|cZc*4Cz%jxAX~kXh3n0=$IT{NlxL*VwtZp6i&LMZ+Ob;_u*r zxTg5LUfaEC#q)Aw_Juy*y|2m>*^T9S``7VjkluVf7*L25OTEv2M;4~#)UJJe`dB8u z!YEjb&AAL-{-Wwmmn7o5-`F(@g)ZY`Rs?%2vZQw~-Ty&~eyl9VXysm>s)*7>R@wEG zguUGP7Z<;lL?Y#~_E?DY`F`rTZF>GsKQ&G*FXcw}mA=uOdU4x7If*fKxoILCMH6ZmWqoc$_uBRxHb!MbVTY?(kPORjcYpg)ly;%kJu?^7RV>M>f)+^E~t zv$ghfvEu8gfAhuCQ~&#QhU11sO2642#oa|(7--96B=vKtdZ^^je{#;1D#vTt_s*6} zMrv{CTAb$X4>?Us{u?iM>(nk*yx$hwwnp-G;5zqo0)%Y181@ZLhPB)|v6xW=K zkKFVW{WXudNB%0OoKFkX69Y8Yq7pT8UpQvjmIXF%8s1FV5pOuXPVrtm(<9m^$LRXW zQ^aX%sHu5f<0*MA8N|zpTuPwq&)1Cb!;=CmgD?r6w`FDe-^5W=eU91sJDSl^J!ta- z>DH^^4JP+RB_woSCE_Spgi|nDM70qtw%c0-5zFjA<)A!~n;mW3BLp;CDW=ALs2t=tCTnK2BoXAA471vlrsC9ZOhg0i-< zwnF56i0g73Mo4Rd#g<)4i@c5ram|>zbYQZtK%|*n_!=hwTrg z)u3O$jCJf=E;obnV1w0z}Yx6ReE1pmNi z54ifk$kcQ<2DFIe5;gfFE9< z5gI#~BVWI6?&$FL=PtbZ-FY$HbAyuz_;sXiXFnt)w0!^mBrfg*&EdoTW}XA9Uj*jX z2e$ermr(cPS&^AUInbg3{>Wnnq^Q#6ob*8m(dwyeY}~c5s6u&y_7=;8waez8(R*Ml z8Gz$>V(EA&^<{v|H5Ws;_V3^CRr1f~rU$M{#fa^m&rW}~zHODoVcFK#FdF0|0tm0M z8840`S22}=*JBUO?QCu=>P7&g$(b%MCowiLVbO~D`O|Q0$wjFrHz((hd-{hDGO9;F zJRh5!MCO`}(H^Lx-u#~XFz80UkJy*i)>eFYCtmg!bXaCEV~Lun*CFVAkb$8IbR zL*0Y)`r>qYVWF1ltxChpw|RLTqplp`HV29gz|K>y)YwDuvkI{OBRWhOt!eRZ3W4$I`xy=7-))!qxn0bQRe4( z0rV&zA9k6uyLM65RT|e;NdB8H$L^h_vpo^F+jrRJ7ot5BepmO!K8ue^Q;~ zIr+)u6A9YsZLzs!-Q8O0cilIkxVjp3;%$p5?$_~;8-YPVa`N0q&H&v5VzvFp*6Owf zA?XuhmoKJw#Aj!JpIwihhCoB-EX_lt+A#&^-J-UDQa*(}#Ej4!I^@hMeIRF}?fdtO zNvb<7J&m)Dz_vXGPHk01Z=sQI1F}KP?4-T$^YHK;y#sxla7?I%d~?)Zn?6P%;dA@A zGK(NOnl_*J3;dAS9FllsHECO5L*%YR0;&-zMv|D4QblAmZ(JslBpdDtN99j^Ojf`1 zVIUFU_q`s=yuq-TzwZ)n--UR1V;R>yVAmw(jYp%v|L}U;)t?+3C$$H)E_)3Rrsnlm zKHR>mQp*@jn9`M!SzmH1l7^`6tVZFz>d9@BAF$(#UShT4fDOt^f9}zr{ybmG%O6-! zQ9k8B>npF{g;RVfNx`>JR)w7=AHkgvktB-!bV7uM$dZAxuzX~Auk4FjYiMkGTDR>U zg|~TH!A|(8ys@$*{CvRwpw%7(=K5JLMsvQJ$Aj{K*y6LXx3>)pj$db^M(`+(z6d~S zX?4b_jI;0!P>oCJ9Yz={NZ$6$9Fmy)y@;TurltosqGAAYz=d5xXM1j~>~BLE5z=VF z6IEjskDWQQe`#q6yZz?01}BM=BCNB;At@zA8Z`<1(W5M%>XiiF-1~AQA9abMs_IEI zS5%hhjxhH1^ zAP+a3UU8Ze{B=J5OFGqYi2L7^9%xaqOo0xn==;D)4EX3TZ`=T0O=!PCT4uuO`61_` z;m~Vy5?c!r0BYlMp_X+S&=bOKiOe7Og~)*_!faZm(@RU4Wa24-Of8DkKR3;~ML}^Q z)az=%kJ{SWa@fyt=dxLkl_I?@@sZ~$Hosn($Z=dsRUhg$PY?gwWvimD{#3zzLM3#i zXk)pjWYZm2Dz3CtPx%Pm%<6nZ8P}hzY68YOIr}e8VLy7KF|BOVrEZ<5SnzI>JIuFc zw>Bi|{td&FC7}T{=m1n;dhg`45g$E~GPssFqTKe=8?Q*k)y7ju>oDi^WHxkLYmK2T zIdO^4Z9*l6T##WP0x5&r=0Z&HRd=F-agO0k%ijjes4N2{dFkT-EOlaO_I#5lHE^8g zs!uC!m0#%48CvQdiO}bExo|x1^=o<^)HF)i?AOL3uRF4Zb-;N6nXfpDS)PhOc`izp?REUtds@ zXTMY9vL3d+!e~BHrL`g8ZyK}Z<3majnu)CRT({a=hi~28eqbe-YCM)YI31Y{VA=O@ znsjBz^{dx2y$AB{i!#eF^{^-{q9FK$_F}22#>4hH;Fu>~Tn+Lu+#VyS!oKS6U(@I` zoGC_i8G!UjZS~{}#$oT3Ry(I1k!PmYvzJlM8HbIWv9ac%zwXp{8*}DR$Das088+62>TiUr<;?rvo)Xvzlt%~ z{;6kr^-q&$&@N^--fp$yaSr7S3^e2(s0=!peB*-gWJ<7)vDagLnwWp26B;;%?A)qo zn*T2>3N^+Fzv=M*`6LG^Lr(1!G`(bc_in|RyxvEIa8D5j%}%J1Y!sf^&hXXXcjTaK zaKnh7*{+kyF<<4?R#X3qRed`flrw%_KH)sqNY!gi;ovXdoS4!U#$+r7GEctf-v1v^ zo(|aRYWmh1&l^0GmzXbcbYLeV5YR@6EjI#enw)ngMx}_GRJX3{GX5U5Dgn+M*1IpM zd;~bOhOR?60eGX5@Z$SAhCuVAqbvsH#J@!WhCvvr0tNcniAypT=Z{M=#Joj^v>AxE zMFA!>S!WkufI~?8Z`uhBY|J>F6&2-jF1r=&zI?M7e;>Mhgpsk@sdRxcy@T+*Xvkhw z79yZq^&M^+o8nc_d|<}moOCW*nn&omnx>B(xHG_KeZG%=YT(AMam0}TsA%rqva+_W z5nJhHDR=|%xz5P}p5nP}MEN0m2er?j_Q2YU4s*g=udS_}3@1?SL4w?t-DHgH(|x~j z*3EC?o~xg+Kv-h4Wiki2k@UO?8t2nva(XF!UZ10O^Qnj25qk+l0l9yPnt}#$ zHILu^`acl;Z#OsD0}o6}s(=W>>k00|TB)>X5U`YPE~W44Yag*SK&uatSZgU74XC|5 z#SaLu@l1_bP8^nK##J;H777>ReZ+NtZSvf-BgS?5dYrQ90%ee40{KSFVZMh9<<{N1 zb(3OO%#)635*u`})q!45TBDAbdTYGY%IJsBDc>kyGDfJwQK$*wZ?vvX2gHMl2hucAr zYMmkQW9#@FKuVIGe3W9sSpqmbOYxQto_Uc2uN;o#dAx*a8%-ikO5M+|NL`1SVi^!{_*NE?)blu z@QD*$Xf^%sSCCTt-~Ssbwo~xGU;N*v@n75c?@jst$`!nQ`M$;U8Q_9xGieujFg zs5~lq=|p4mFf1ee7xq|l*qVZRLEZY?8%jo?8lcs)LzTo)?Y3lm%Q0}wKRTca#ILwq zbR9yQEN#CmU$>2yyMDcxr91p>;AsQ~WNGi*iJ5FaKXSBA-lnJX{ByydsL0t*pO(a+ zEZeD58%$XMf>1=q0zg2Kjm)cZ5;Sy46u4h%YA%WYqA5a&1Fpm~h(clT=H=I4KAs=c zlP?48Lq%ke)pcUiIr|=}NdvTqAoe5)(j5?kLE8f9X>AP+Z_op=$3iMq-N?{TYSDu~ zazBa@^CTC=3l}Z`eYqqlN&264kOy0uwm%?L&f3~y-@PLPlJ=y}>TnLh;Q(dZ;M}Wc zP>(_JxVuAjbJ0Z%h%(U#0?H=H5cDi93EV<}aWX(zI(vMTlb*=LKm0s6R}_dI3*^ei z?9kD_fF`$+qT&NUQ!zcjFF>gPhvxb*u!g3mr|FoOUg#j+ zdMPJKqtk}TSt*W76u|v}N05*>7BOPx)*}y*@=z{hFRArn-n@~%dGp9~IaWVEzh+E# zcgbzX1jm8#q#wh>C!scdLXn016xz06C=p9(aZafBCYQSaK=RTD8l1tNGfF5h8=MLI ztBqBvV`J=uF}98?YH9glQvB^Y&V0}4rR27Wy!aetY;c6#b=ZHUWDytFqf^xZb6J)~wgt#h>YzgOOa zf9GhODIS$gZu<%LeCVVAmPw$yZOTUvf~f(NRffwBX;RPwdt^bCODtw(W?pek?U-Bw znBXm+@EKLU^p2_v^!t&0y^&8Cu>5XzAzSMV2^r%(4zIe~RHY5TnegLU$~H_1I;o7c zX-@Zrjof`Zx8tEzs$Gx;piJRkeZs8AG}k0fk+)pZ0B|15KAtr6-|-r7)u?7L9j=VX6s4qC^gS(ebaFDn_0SdPq=Hof*`+AaI}p*px_0+oJ`A5w2}rqv zL$InPxdNtT)l=CRQDFL58OX*$xElGr$<3zQ=mhPu8c)m zgK<$^ec3=O09XuIlb6zpBwlf4eg7XW0Jt$yyH+tj6nEu)N*i!uF510#8{jlt-X#cZ z{K*y*RNYjU;wn+617D7dG05vN;H8u5?ijSW<>EpQ6T+np$xe4Ie2T_6uv{uCs$0Bt z#gE7zrY-H*u|w(@F-Oo@=DAfEQ}Z6VE>$Bnj{nf1LsHN9+HtzEadF$A6AQCOE7qL8 zB(`<@88$F|q4$FkoE&F3n!0?QhJ2?W`xM*)z=V*Pm;*?^ahyOVE-w1gXqLum>*zd@ zPq+k-$6i>s%9|-&0AB%IlB7YQW1Cnel6y+46!*SFs8C~sX}?(xJwAAx^@F~{45!*liUt6ngWErjzAKb?;QTzUTm}8*tPOw?ssWBc|r|{kmUl}K&PE63y2TG2f!_X|c&AO_uHdl`d;o-rVa~3i* zMH;N2*JInLp>*@+>A%zHAjCa73PT64wzj@r3a0s7?oOxe6X>4azwz)Zn6gj5D>c>D zUUYECY2r_7F~y~M2GK%bV?)0B@~rmPpUAd9kXLSVw!UHXAoD$~|;>Z4gim(&$q_PZV-Hd(6YillWfe19j z%7cA^!%Uh?;e)eJ#h;<-yxMQV8u|4pKo*tnxd;aA?CivBF{l^KlLof7pPKutew_^o z`}4=SrG`RtGa8u*DOWJvZjJIQ7LR73>k(6y3RN(40RFfSjN7BraSNm}SRDvr)D9k& zR#sn7v>~WGd-cjUG?Z#_anWZzK5iKEb6Qpv>iwK!T|(BRE#Q znp)lH(cSw{WP=pMPUH9NR}40ctA6+Kx`-H@3Gi5{=c6h|%cyFg3`;*fOh#iO>qN6E*u^?4zk$i}MtE#H*W)VnHPfiR;fyr0qh-kjOpk8I>$`%S*s~;V# zvb|lMNTuMnah+bidGlO!pNLMokyT8meDUa5AQoxtJzR!-7b1I?;#3MDM6#)8v!qI)^;L*E7o99tr^^OzS;cUUI{1sWO#qbj-|*Rr)f)RU{@$ zh`fz-1rXUE3l*X?;Nhu3rihE;*3ScdP3OStTK-_Pq7zR(nhlB=I%5_n%-ue7!`Fp&K2L+sy-P3^YGebBmKD9e>+a^f^-Mn12jqh+kEdFmS) z&LXFR=rk8M_fL4O#exkep}p;xBqag8KlG{juA+?6rFQL~oJ^8{wdhLVjwcFP^tB8xVr=Dp+l+*Y=sMZ$J9v5(iXQLqlqz_5nuq7` zgb4aO7`?5#Bi)1d)f^%b9d*Qs!sp_5vz&Ls_oF!@@FaG)3Fp`fmf=%@Ao)gqv~Wbo z_c^Mr*b*dsF$Iq;_>ZEkglPKYc;(E%V*P@eq~ybcyRjS(*F$%StWB)M0_>1xvmDf4 zFw$zoca|lSr`70{0uDtzm|~cz$%`wB3}&#-0as{X8q3JG?+oizaC5{g(`p!U^?O-$l z1|4*GTyc!-Jf^JiOg@=$G@-fR)~`dz&7uSU60B(?|59m@>xMJ71&@sTR*K8lBI$qX zc^ufiwVOU%Ze)o@o;zMZ-OSqhKz9)0mXfCCZW7Q#_R+gRUpn-|LuYQ4Q~bUuNVT9s zge;TbdZT)~xl53bKCnZj|CX!-u0FC-9?>oZS=pP1e#}iF&;|ZsWD=K<2qxT*&>5tF zu^p4~{M|QZV0V~;+Y7Q0dS(c8Pwcsnt?^p!)|}yz5w2;he}me97I{;0+AHLm9tqaY zL7l+c7oBI&@t{r1L-9%zq>vKSPx7KkDE3$4y;FO4zOV~@veq;2#AqkTfNcK?8fLi8 z8txKkTUW~Ind=&=d_-r0@RQKks1!1FbL*WfoOV95#E|*xGz-h6`y}VZ#Y-nNpV-kq z{XBS(Ne`sKcxeA{CDY#IqBUqMAR6iMUwS!x3!0|UA3(z#i8E1;!-Wv5hJZPzYmHam zJ{Oyvt;)WFLM@J(jWfLdS=e*`K7}dvE={W@X+u;_lP5GkRYD4Rur9;Z%%2D043+w0 zWD}SaCqQxs?TdP$*LL6W6eJS9I&i zzkOUT+&gGzf+P(LVr`USfG5B=}iQm{w-Go`XYDHLMQ4bz4AC5Wwl}$oJLM)CeHL#ANiNFcwI- zvWi=nn=jlWAWh>s!TE-yp~A2!C?6mS zL5!uki!Dn;?-!RHSzmH}jwTl&kcO5o+ICM`=n-+ia6LF9HZeH~Ix(^7`1q01_07gX zo3}Xr;Rn5F*lz1T?;KS422+8n%_#Jr^5t-<_nZ%*+h?Qr9SBBjZmxQ5d~;jdNS>Xp zy85prz8mrtft8g~>7u((jT6gu;37Mk8!-}$0swi7p>6~NGKfRMrwyq>3MPLw`c3rLl~1qTHfcu@~Np5UO%(cYi#KW@VM!$s@140%Q|i#hzX(MhmTO-h(1K_H7AjY zd9Wuz9xg70sMfLBuR};CR&n)uKUekNzs2vK_`;PTmr&#gCsr?iHGT|04NnXh3PO%S zre?8B&mme`@|x4l1(ohrdRkhcmu)Ul^s-z-!C&$y5_h*!&J>>Wlipo(vDJE(7g14+ zxg<4+bNK#P0DB=JgIT>Ge`B^ab)p#5c`TkLg&7gTH><0Hpyi`d=O#nHniGBR$3c(w z17kZmcJ;=}1w;JdN2V+gveV@ifaSiB?DD#S6x`;U_FcdXqr779EXd^z#>TJnxxFnScA3kG$s5O`xn$5_vKH}xbL?vr;K@D@$a>=>c(IYzGx5Raq zby?7s9$5K0Z%p_%)M@XPkGyy=0%9BzaT2Zr2`|o#fKlt*W~MfyByXN+>sxoLH;NY} zCz%Y81uz{lutXNLbrfiXf+F%u2vaZ1anq0WPFd;OM(+$q=7QSDue*Jry9m>VE%Dy{ zpr$-vq0#t7ro<6WsEtD#?pgdP2?_nx8C~v(xxyZqG7s4itIrhPmuh!}VB{kAt}6z5 zP#S^kFO3J+boVG~y4l(%6%~@POvqv|VNCtV4_{zvZXPybCT-D_9YP>JVJ}~fU5FTH zotw*OBDv!3UczhbX=X-_R;&1m0DYhoS+`Z*dLQ?T8wv_YdZ~a};C1kC`~oeka)Q)As1zBLvfjAVXl zNocdtod`95T;VJyVyIQ#F?Hn3jGjg=xjQa(n1?we-SuSCcsK&uD*A=og%r&0iy?E2 zsN?rKyQzQbvN#))Pp2tu`#{1*X?%*?oXA9(#PnKAAqCx61gR6hTE z8Wb0Zq-jn>fcG%hU%e1rWy-gc!Hd(1iJ@ax@hrI2MWhXnlkdy)53Z3R4c` zcgw)AeR?N)r9Nc>c7;rfqTy-~&MN)X+00zNad4&bKREY;HWKpYs8kB--oef@TwE#j zq(fc(s0;{&G{@&+o;Z~dh8=g8cM1(k{Uq67*9ZbSG=ulGe7J##t8188JV&dhWf`N0Frw~|6-4? zWOAD!Lj7=?zIu?~?voJJ;(9prKgZ@3=(_kY5@8l}JvS?DW#vz1`yHG9ncWNs4sKxk z9ZiQ4y7I;rR7n9so&0C~I;waSYaKU|aa)`v_wXM&+5GheOm_GbUAY90{60|3-T0mieoa6YlWW(sVKw?HI@}#kWoa2K=wFVGv4h2Fqn+8RftJW`?7moY z2RoV+ZxR0Q{%pyLboibWd6L(Fo5^a4wQ`N?(H;6uOw0-{C3?!w1YSFT#SGjNySJ`Y ziLK+1I3z>j=N0~|Dou{c=d1B01%+TA*g+dGzNKlD^_vA-&xV7L= zYTGHwT4YF0p);hIebJ>v!v+A$9?)wzoD~UI z@D`NV=L5ruGviKh^h6U!mE#bi_-|}mtF+2v0TB??Sd*E9E9NkZb|FF00_ya&u;^&+ zzfKVSDQ8XXIKL7cDe_hbm1<+7eEJF+5FHb&n~i@kADW!D1sNAjhYj^4)#RY?Q58qe z6{~1Tjc~afGm(gfoDZkH018#QSA%13Loqcwd)R{-*^I#+8{0}L4gBfHzr5blX0kP!LrhG7m)t2N^@4M%p{Y=8_4mODiT|jI znEoY)C6^ML$L|2{iyfca=lG=i6*mXRyxgxt7Hd-McB2~N6>97>N_X{9eZLGHwij+` zZQY*L6#zF-Vaj*n^yxhyt<<2zz2q@5_$pq?%v)Gl)H=@Sy}T6wZ}?299}eh>-4cI` z;C#HC62Ko)8_>vax79{s_+E{rb2$H#7rJ0Mnyy1;mz68aqyhWW*1e9@qm# z4vr!2h~Az2unXHVBUJC736O~&(~(6>kTNaMerBQHCE#r*_6iIby;n}kfZpKSJ8x|3 zPbcf4?@)zNGHT^0WWT&(nDn?WRt$Wq3djKFu245UgUfGsQ=$(vZgX#}s(Lb~i+UX& zi_oP;#rM2z!oB5F^z^IR!?=$eK%uv>QE{-dU%Y&I2S~vT6uSsgWL#HHPL5PUw<%ve zcexUHo1&5vv$Mh7yar8o%-;h@2&I<9q>#Z#m?F0e5)r+Mmsjsh=yko4y?!0}k8Lw+ zPh~0|mFW;N*2+<4aW^^~3IXloO%lt@2nyIDP1Qn@T8e$5SdUT44nd5p7SESKmza!U zLY$xfDaN8>`*6dE4a10=6&R026@{V~UDQuza(>@W#UkvQd(cDWgomR^;n*Z&)$XdS z8|$xkMMp&i0z^8#ioCkHvvcginp~1V>4h%R6Zo{m~P3!JPX2Bf{DNC9%>k`N6#>hss0=I5WNhm;{`E`o4MeMD=6^-2***?qIg9 z(#F(e&``u)34> z9sqVqx}^nEiwkg#P!wu*kX+H#jhgF&RlDS1wgco#Hte$|y7;hDoZErZwS&$q)SMM$ zO(Zp1Per`7EiF?ICfWouP*cBzkoBQ$%H{K8=kaNA%f}Hy|3RXqoEI!P<#OGs!Na-vEkMWzPJGHb;qK9xk%FcvH=@tHuF~AgU*PW zjllP$orr}m)4@P@F+9?+xbv}FI8Mvg?gjk~n5<6*wY z3PHV|Enaxi!AP;IA5)=9cQCWE%VKYIYvOgb){i0i(eF~&*lL!q5AVe(tDsmfd3riG zFV8iw@!y`IC@!F|u(06=BQ_bR1=rWtKiM0kmAYK`tnjkSD=r}Fz0J7Km_TtIiSi+9 z@+tjJas?YmH88ku8yt(S29@xwnUf(XkBJQ#RG|^>In$ACeI-mbFS@)V|P)qWCO3HOX9t?ovrTncP1D%1A?Ug%s zSW!o+_gQpLJMP=Re-OPCy|Rj{jk7^C09^%4$TE8S+s~I%TJSZa5kX|IAYTou7zUy&Wc8XshknW$y)u&_e>Er{yC1LGvlcOKj{ zo!du3CP$X92kS5Cz6|iQ{8V)*ycLk~SQtN=!RT3HnIqmVSiFaiq<%NEIWlN_X+nANO-&H;Cfs8qu zhe=47SY@RpRkycGWZ+YA25_KOBfXNgyt2ZAt3xcnxX%5+ zZXp1<9oFrpe1=w5@~Vo>=LfS)GT1xavFGR!?^n6_7BU7(q+x7CS{E>OQ7U8Bi6z_Q z!~y%emOSq=zTr_B27zk^N;YbW1ZymnYA0YD@SZA%yJCx-Ba3aO0*y_ z9HM(pPMeE%YM_i6mW5)j^W(*9C!Yv2R+elQYrmUMMRR74Lc~|&tmaZY2~1xRV+#l) z(zne5mpDqUNuuOtQNErsapee93NKIpyeD_2HH!TXe;_f__u1NdTZmjrnSn z9_ZZe%=o*KzhJp)l-0${%liP2kC+>$7lFKUELFg^xwZ92Ks5A7gLCHGb|Y1M3@3d2 z8HV0>M#=BW>f(CSu)!L5C~L~)-TkyrpP~;0?%VnJnfZQA3J$WpY}ovTVFuL7_9K8$ zTWYRjF6!gQdUN|KU{J_y)Xz{)3f=gSlClqF4MFshkwy4C&dp5$wGh&TsZ>5eK_8@C z$gGK<16T{Q=RQqu>yMbcAq52mH;!Nz$4Rif3~Y|}B|&;Zj-fs%18oOnwXbJc=Sckf z_tnXdjd|$^P$zciJQR|?QN?EhCMCzn2F(YFt8M-LGYf_om)(JW0;U}CrqyQG{bq_1 zNJx{fgsz4GHT&kb4aa}{R5nbC#!5#lY|Kjqg*{G>^sgQHqaGB3N*Wr(5_ia-!wS3{ zWYy5^1Sw-s1XD%-@?1_IB{y$YP9N^#e)msn;B&aE!7sI95l&|?bx1wW z7Y;tzpwkX6i8H~&&Na8sIY;dp={!#8F zF7&drR6P9+Bgx6&i+*aDB8+RIB>G6-qfztvGUd>*`(~U%PZKTJL{$!`jasNNp-Fc7 zx&(ONi-kdGm+T!qk{NSYer7y|Khm;~DjI+<;Z@37#>el*6bPsbJI|lQ&JC|dN3>GL zLc&or9JCD-ijqe$v-6Ges4*Wsw91iAK0-lCXhBg%_P|}R2MA8%) zA1*r@cl^wm8)L)iHQA>vy?1dran7^ur#- z1$wZm7vs~@OXM~_XIhQ3FsSKlS*9doef7vVq++~CYTyAnMdrapf&(QW zF^vR(nMBM*M*^h>UdhYu&8W3;NmwshtK=#}y?e|%E)hwXQ;!8dMw|Wm^8oduJx*{G zfD)rCd-+BIT(t}wBM{W){(kPlX+C~_L(KOQ97fnLrl&sr`cWhSfDpVUJdy{%>j8?$ z3ysj=N0LuhZ}9HCSQQ%6kRwK2fZ>@*ypLVLJ^&&Ry#b&TPm36l54XwM-=ShhJ`6P9 z;Z-H&-fXSur}X`Y>s!C0DQCc***d;&J^SR!*fFQ0k&%%Lf1Z~@I|Xl+>cy4h^zWSJ}rL24^w%Yl)!d&=` zNFsgG(JiFqNC(IjigD8Mxfb?Ia?os}n&1MR;l=M52q`Q4-Si&D4?*{Uk z@%L4W=@Sfa5IRGq8V%Q=eRK8NUSR<7rwv3_-=2Ip}kx7 zq1A?xkWNA={#H4Opv7SD4|CzCEmZcn-8d6kx$#b&+=+>9#ij#e-HAH|dwp90*fb@` zgnU3(TPA=QBL@v@s`V%U3vff9MMR9YIqRXrU?<|k=BYB=OC-4kGa+#;rp3a`<^?T! z=H+)&NkftN7%UPM91Xcw#<_X~>jCqhTUZo>k?tb1k%y-E_Qt+Hi1k@&!mjD_59ijux?V0&`RVVbVTDgQXAA&hqSeVgn`8L&%t z4Uf3#UhImlmO?R^A6=aeEDRBV_%W7+Lsz@2)^gR3 zp%7%4h@OEMdP{fr>!mOG*vQ&jmkP@7_A-qs@89ldI6y*B9^WU8g?=C>)L@P< zR?nIT!S5bKBCvPHr@g(sc61>opa-P`_04Uz>NV#Xo;-N0q9i_e*)5+pT;VnIfFR`L zY9KJ|RDArO(FN?J2sE{}4uHZC9EN685m%uqy(ZQl3O>3^-jblu^7ID z{;$}~{ujfA1o(WINADlDw3?+?;(Ep!T(t4%z7RiLXR`c0g+cuX+TnS89P>;);g^U=59a3^jIfD#ut zrarfjusa?Wz4;`VnR9@lRB`nJwE_e3q*-Rs?0SNm8 z`s!gjj3YiPEc`m^81zDkrPlYLtdEM#7bl&M!Wv=!3qBatjVle*KU3>_s?(q#fT{pU z&llv0CJk!@WlVPf&(uVrOMnLo z!HJm|C{}r&qCs)8izEIoKA{mfkJt|UYI=>JjzwYJxv=os<%s*wE%$RQ7v6JU_;mwU zQd}fW-i))iZ*ghq&XAFT!JuY;84PHzi+u9Ee!Y5yD9~3x1*=B*FUD>H&H4abai@LZ z2Mi}O@2SJEr(8vAolA>*PoK!WuwUGA#P?2B#g{>hwlV_OX{Zc@=(5#bCD12Oy$a#- z#X%4zO|OI=N7mBO5wU}g@^_uX3OMP=?hoVEgfxtNV&&Sk-!v~MoTuyH>NPVgs=+oL zpH*Ii0qbYEV9G%a#uLpj@lA}{N>_O=EZ!q4V&=&L3L5}vG-GW&R2tR9LJYLse2_}r z$D)Mcg+H|;wysYPLo8RUIX8ilIcNZy^S9kuPKaN33r_ZK!zbK#;DAXR2NHzepqNzw z6{g5}<0yeU^%EgEW`FhpyV7o1X#ZhT)p(fhv-*c>!0ZvqFC%Dy-ynAnYQuOQ6EKd9T^dI{2@Ha&#hNXhl2Ju z+&&Vv)}RJ5`K-I`^5W6i#qjZ9uozido&gEO5cw*`W}2$_wWDt1(36tfeWqI&X41{6q>h zt6qdRFoh_854v_WsXx@t$;-O}OM!~;ZEE0O^_YFGi#|D>cXL(($G5#?MUug!>_yb` z$Q{wF2#Y9y<21Qs;DQ|~d^&~h!)5s4yQW4}^~lx5tyb2>9333))RfCkz5FeN*CAXi zvRoxDTKGB3qu%Sf9`;KUZ5BO0=FeuT=iKJsQ3>mwKw?RXh~Bkb zyLJr~&6f7i+Jb(-WcsSIop+jVJECv@CCiQC3v)Q!Z)xE{FTD&jK+*RLSBwV#5Q`BgjWJ^$^!t!6R&3@&0O@ET$hJ>jd9bYLnd z4P-DAK$uFVW&l36rna`fR4g`f9K|Qe@~p49C6v)HVtdnW0$t^)0r;w}-|CQ+!Is`` z^&MIi0zv2Pqv3|I{Tk}R0&v84)NTNAI+eR<3{f;VG!*gT`~m`5G1o91#4mmzt2YDH zXg5~qmXwH1mMG;yiQ)jWcmQA*9EmS37Lt}G4+XeGES<49I*D?XpP&EJY_^*fqH>qj zxjQD7qMwy^3ksgasz*P(#42Qba#;)DQLu#Zy=8?AVgZUz>}#(}+t`PsXb9OuOHa>H zc*C1&RiJVF1XD4lw>DaJd*Wvh^~B}_m$4qg?Zn|gpy#U)QgImW_=9ocWv)qy)JSaN zm{^7K?(@E?2(&A{V1FihSj^)~2rEQ@>B`OKKm>Afau{Kkj9{|1o`4<`^h0w5=%GR`*&ACW)gj~w7;hPGait19kW*OC)-p`Jc{np?7h z^qsh~gwFs9dT;aZpQ&z0rN2`9&8VKK+1vh4UTUgk&+j>8P1`MZxgJc1{=0G#4HE8< zrqOsfc_NP_++ikpDd862-c3B+B|4&r6v=bbjqk#RJ7QhpGdW6WPjR@ijuvntcSgf( zYX{(0;0AkMB)(uiHw{^Y-iWc3Kodc7(p{%MD6&_TLC?iux8Q!{e41IJ&IIwFrm_5D@==HR@-^J&S*)NFp3US_`lS#sTK+N=#V^#*P z60#YQnQl88%*y-2-trx%wcbF#+x4SEuZZ>3@X*n~`PSDs*!x&VQrh6#5UxVxfOwqv zO(^rsT<#hK(X#65VZyP(y|cL@U(jKMZoqWmcBy()-3naALP0qrB4>0vdwc&*J=w6E zy~$2vh{l=zC_4Q?Qw*wl+w8UAejWD-;*NmZ;L?=w9^ART0(j3@axiuCSIMVOR9GnV zwK5RrM&u(M`S<63ND`4YS+u}rP>PR_Z>nJEI!txhBSH6RDF%)>M%$yN_@eW6ei~`Y z&B+{vy9o*_A)-@QBcK!`p?CVvt(!M}Q7EDJ6M*>`%;ZTdw#MLyEYj!ZbF)09y`+v8X}$^9+ZM9`V@!#uZvR$` zgL)YmDbl8Qy4vt84EiU;{6M%pNZ3i{Cf!IBE#b6~V#5%w%0Y_|x+dXu1<0 z9bpnaGdP>I2kW>#MVaFo+~+6}B(gy~c}Q?F!_A3)Zz4h^lepWfXP=nBugo&snf2Ee^C+OqzU6iM`n86?E)X)^D}iv z=;?)_`mKV@@Qn){;-+tH$GvcFw3sVV>Szwl%c&npGf}!yFQ#+-L@daBqE6gln19F zu4)~L0`@*Ytu#^-p{i~L#ntzyht)4@XmoT%pZ)Evg47MstcKqim)ajEdtTztXak_{ z{*~^HA!T^X;o(9UDfR~vCX4*yCuVU^ZLY9O2=zBnNMuCX>ihZ}_{yik6((-6LsL9P zLfJuISGTY9)DzE*N&R^AKJgEQnnU$2L}2hB+}Wh$N&}!bT1{v|;4T?&y{2lf6abv$IVu*0}PF&U@t?)j=n^5Z2#KO+wP>r(q#B9vP5=l41-nTEd$^QHZ(T`RrW*7N&Lk(1mY%X^ zW+&MkeaRb2Zghym=b#M<{_!N)MuFdsIsf;!|2~5MTETxW!vEiV!PbG|W9ptRca_}< PcO`pSUOG+c)}#LepzaG3 diff --git a/ccw/src/config/litellm-api-config-manager.ts b/ccw/src/config/litellm-api-config-manager.ts index 6110920c..8bdeddb4 100644 --- a/ccw/src/config/litellm-api-config-manager.ts +++ b/ccw/src/config/litellm-api-config-manager.ts @@ -281,7 +281,8 @@ export function addEndpoint( addClaudeApiEndpoint(homedir(), { id: endpoint.id, name: endpoint.id, // Use endpoint ID as tool name for CLI access - enabled: endpoint.enabled !== false + enabled: endpoint.enabled !== false, + model: endpoint.model // Sync model as primaryModel/secondaryModel }); console.log(`[LiteLLM Config] Synced endpoint ${endpoint.id} to cli-tools.json (api-endpoint)`); } catch (syncError) { @@ -320,13 +321,14 @@ export function updateEndpoint( saveConfig(baseDir, config); - // Sync enabled status to cli-tools.json + // Sync enabled status and model to cli-tools.json const updatedEndpoint = config.endpoints[endpointIndex]; try { addClaudeApiEndpoint(homedir(), { id: updatedEndpoint.id, name: updatedEndpoint.id, - enabled: updatedEndpoint.enabled !== false + enabled: updatedEndpoint.enabled !== false, + model: updatedEndpoint.model // Sync model as primaryModel/secondaryModel }); console.log(`[LiteLLM Config] Synced endpoint ${updatedEndpoint.id} update to cli-tools.json`); } catch (syncError) { diff --git a/ccw/src/core/routes/commands-routes.ts b/ccw/src/core/routes/commands-routes.ts index c2786f71..df630de9 100644 --- a/ccw/src/core/routes/commands-routes.ts +++ b/ccw/src/core/routes/commands-routes.ts @@ -7,7 +7,7 @@ * - POST /api/commands/:name/toggle - Enable/disable single command * - POST /api/commands/group/:groupName/toggle - Batch toggle commands by group */ -import { existsSync, readdirSync, readFileSync, mkdirSync, cpSync, rmSync, renameSync, statSync } from 'fs'; +import { existsSync, readdirSync, readFileSync, mkdirSync, renameSync } from 'fs'; import { join, relative, dirname, basename } from 'path'; import { homedir } from 'os'; import { validatePath as validateAllowedPath } from '../../utils/path-validator.js'; @@ -78,15 +78,6 @@ function getCommandsDir(location: CommandLocation, projectPath: string): string return join(homedir(), '.claude', 'commands'); } -/** - * Get disabled commands directory path - */ -function getDisabledCommandsDir(location: CommandLocation, projectPath: string): string { - if (location === 'project') { - return join(projectPath, '.claude', 'commands', '_disabled'); - } - return join(homedir(), '.claude', 'commands', '_disabled'); -} /** * Parse YAML frontmatter from command file @@ -221,7 +212,6 @@ function scanCommandsRecursive( baseDir: string, currentDir: string, location: CommandLocation, - enabled: boolean, projectPath: string ): CommandInfo[] { const results: CommandInfo[] = []; @@ -235,37 +225,46 @@ function scanCommandsRecursive( for (const entry of entries) { const fullPath = join(currentDir, entry.name); - const relativePath = relative(baseDir, fullPath); + let relativePath = relative(baseDir, fullPath); if (entry.isDirectory()) { - // Skip _disabled directory when scanning enabled commands - if (entry.name === '_disabled') continue; - // Recursively scan subdirectories - results.push(...scanCommandsRecursive(baseDir, fullPath, location, enabled, projectPath)); - } else if (entry.isFile() && entry.name.endsWith('.md')) { - try { - const content = readFileSync(fullPath, 'utf8'); - const metadata = parseCommandFrontmatter(content); - const commandName = metadata.name || basename(entry.name, '.md'); + results.push(...scanCommandsRecursive(baseDir, fullPath, location, projectPath)); + } else if (entry.isFile()) { + // Check for .md or .md.disabled files + const isEnabled = entry.name.endsWith('.md') && !entry.name.endsWith('.md.disabled'); + const isDisabled = entry.name.endsWith('.md.disabled'); - // Get group from external config (not from frontmatter) - const group = getCommandGroup(commandName, relativePath, location, projectPath); + if (isEnabled || isDisabled) { + try { + const content = readFileSync(fullPath, 'utf8'); + const metadata = parseCommandFrontmatter(content); - results.push({ - name: commandName, - description: metadata.description, - group, - enabled, - location, - path: fullPath, - relativePath, - argumentHint: metadata.argumentHint, - allowedTools: metadata.allowedTools - }); - } catch (err) { - // Skip files that fail to read - console.error(`[Commands] Failed to read ${fullPath}:`, err); + // For disabled files, remove .disabled from relativePath for consistency + if (isDisabled) { + relativePath = relativePath.replace(/\.disabled$/, ''); + } + + const commandName = metadata.name || basename(relativePath, '.md'); + + // Get group from external config (not from frontmatter) + const group = getCommandGroup(commandName, relativePath, location, projectPath); + + results.push({ + name: commandName, + description: metadata.description, + group, + enabled: isEnabled, + location, + path: fullPath, + relativePath, + argumentHint: metadata.argumentHint, + allowedTools: metadata.allowedTools + }); + } catch (err) { + // Skip files that fail to read + console.error(`[Commands] Failed to read ${fullPath}:`, err); + } } } } @@ -289,33 +288,13 @@ function getCommandsConfig(projectPath: string): CommandsConfig { const groupSet = new Set(); try { - // Scan project commands + // Scan project commands (includes both .md and .md.disabled) const projectDir = getCommandsDir('project', projectPath); - const projectDisabledDir = getDisabledCommandsDir('project', projectPath); + result.projectCommands = scanCommandsRecursive(projectDir, projectDir, 'project', projectPath); - // Enabled project commands - const enabledProject = scanCommandsRecursive(projectDir, projectDir, 'project', true, projectPath); - result.projectCommands.push(...enabledProject); - - // Disabled project commands - if (existsSync(projectDisabledDir)) { - const disabledProject = scanCommandsRecursive(projectDisabledDir, projectDisabledDir, 'project', false, projectPath); - result.projectCommands.push(...disabledProject); - } - - // Scan user commands + // Scan user commands (includes both .md and .md.disabled) const userDir = getCommandsDir('user', projectPath); - const userDisabledDir = getDisabledCommandsDir('user', projectPath); - - // Enabled user commands - const enabledUser = scanCommandsRecursive(userDir, userDir, 'user', true, projectPath); - result.userCommands.push(...enabledUser); - - // Disabled user commands - if (existsSync(userDisabledDir)) { - const disabledUser = scanCommandsRecursive(userDisabledDir, userDisabledDir, 'user', false, projectPath); - result.userCommands.push(...disabledUser); - } + result.userCommands = scanCommandsRecursive(userDir, userDir, 'user', projectPath); // Collect all groups for (const cmd of [...result.projectCommands, ...result.userCommands]) { @@ -330,40 +309,6 @@ function getCommandsConfig(projectPath: string): CommandsConfig { return result; } -/** - * Move directory with fallback to copy-delete and rollback on failure - */ -function moveDirectory(source: string, target: string): void { - try { - // Ensure target parent directory exists - const targetParent = dirname(target); - if (!existsSync(targetParent)) { - mkdirSync(targetParent, { recursive: true }); - } - - // Try atomic rename first - renameSync(source, target); - } catch (error: unknown) { - const err = error as NodeJS.ErrnoException; - // If rename fails (cross-filesystem, permission issues), fallback to copy-delete - if (err.code === 'EXDEV' || err.code === 'EPERM' || err.code === 'EBUSY') { - cpSync(source, target, { recursive: true, force: true }); - try { - rmSync(source, { recursive: true, force: true }); - } catch (rmError) { - // Rollback: remove the copied target to avoid duplicates - try { - rmSync(target, { recursive: true, force: true }); - } catch { - // Ignore rollback errors - } - throw new Error(`Failed to remove source after copy: ${(rmError as Error).message}`); - } - } else { - throw error; - } - } -} /** * Find command by name in commands list @@ -416,47 +361,48 @@ async function toggleCommand( } const commandsDir = getCommandsDir(location, projectPath); - const disabledDir = getDisabledCommandsDir(location, projectPath); + // relativePath already includes .md extension (e.g., 'workflow/plan.md') + const commandPath = join(commandsDir, command.relativePath); + const disabledPath = commandPath + '.disabled'; if (command.enabled) { - // Disable: move from commands to _disabled - const targetPath = join(disabledDir, command.relativePath); - - // Check if target already exists - if (existsSync(targetPath)) { - return { success: false, message: 'Command already exists in disabled directory', status: 409 }; + // Disable: rename .md to .md.disabled + if (!existsSync(commandPath)) { + return { success: false, message: 'Command file not found', status: 404 }; + } + if (existsSync(disabledPath)) { + return { success: false, message: 'Command already disabled', status: 409 }; } - moveDirectory(command.path, targetPath); - return { - success: true, - message: 'Command disabled', - commandName: command.name, - location + renameSync(commandPath, disabledPath); + return { + success: true, + message: 'Command disabled', + commandName: command.name, + location }; } else { - // Enable: move from _disabled back to commands - // Calculate target path in enabled directory - const targetPath = join(commandsDir, command.relativePath); - - // Check if target already exists - if (existsSync(targetPath)) { - return { success: false, message: 'Command already exists in commands directory', status: 409 }; + // Enable: rename .md.disabled back to .md + if (!existsSync(disabledPath)) { + return { success: false, message: 'Disabled command not found', status: 404 }; + } + if (existsSync(commandPath)) { + return { success: false, message: 'Command already enabled', status: 409 }; } - moveDirectory(command.path, targetPath); - return { - success: true, - message: 'Command enabled', - commandName: command.name, - location + renameSync(disabledPath, commandPath); + return { + success: true, + message: 'Command enabled', + commandName: command.name, + location }; } } catch (error) { - return { - success: false, - message: (error as Error).message, - status: 500 + return { + success: false, + message: (error as Error).message, + status: 500 }; } } diff --git a/ccw/src/templates/dashboard-js/i18n.js b/ccw/src/templates/dashboard-js/i18n.js index 4b0a7ddc..b1768878 100644 --- a/ccw/src/templates/dashboard-js/i18n.js +++ b/ccw/src/templates/dashboard-js/i18n.js @@ -1631,6 +1631,12 @@ const i18n = { 'commands.group.task': 'Task', 'commands.group.issue': 'Issue', 'commands.group.other': 'Other', + 'commands.group.review': 'Review', + 'commands.group.execute': 'Execute', + 'commands.group.plan': 'Plan', + 'commands.group.test': 'Test', + 'commands.group.debug': 'Debug', + 'commands.group.tools': 'Tools', 'commands.enableAll': 'Enable All', 'commands.disableAll': 'Disable All', 'commands.enableGroupConfirm': 'Enable all commands in "{group}" group?', @@ -4307,6 +4313,12 @@ const i18n = { 'commands.group.task': '任务', 'commands.group.issue': '问题', 'commands.group.other': '其他', + 'commands.group.review': '审查', + 'commands.group.execute': '执行', + 'commands.group.plan': '规划', + 'commands.group.test': '测试', + 'commands.group.debug': '调试', + 'commands.group.tools': '工具', 'commands.enableAll': '全部启用', 'commands.disableAll': '全部禁用', 'commands.enableGroupConfirm': '启用 "{group}" 分组中的所有命令?', diff --git a/ccw/src/templates/dashboard-js/views/commands-manager.js b/ccw/src/templates/dashboard-js/views/commands-manager.js index 611b5020..066e99b7 100644 --- a/ccw/src/templates/dashboard-js/views/commands-manager.js +++ b/ccw/src/templates/dashboard-js/views/commands-manager.js @@ -205,6 +205,50 @@ function renderCommandsView() { if (typeof lucide !== 'undefined') lucide.createIcons(); } +// Format group name for display (e.g., 'workflow/review' -> 'Workflow > Review') +function formatGroupName(groupName) { + if (!groupName.includes('/')) { + return t('commands.group.' + groupName) || groupName; + } + + // Split path and translate each part + const parts = groupName.split('/'); + const translatedParts = parts.map(part => t('commands.group.' + part) || part); + return translatedParts.join(' › '); +} + +// Get icon for a group (use top-level parent's icon for nested groups) +function getGroupIcon(groupName) { + const groupIcons = { + cli: 'terminal', + workflow: 'git-branch', + memory: 'brain', + task: 'clipboard-list', + issue: 'alert-circle', + other: 'folder' + }; + + // For nested groups, use the top-level parent's icon + const topLevel = groupName.split('/')[0]; + return groupIcons[topLevel] || 'folder'; +} + +// Get color for a group (use top-level parent's color for nested groups) +function getGroupColor(groupName) { + const groupColors = { + cli: 'text-primary bg-primary/10', + workflow: 'text-success bg-success/10', + memory: 'text-indigo bg-indigo/10', + task: 'text-warning bg-warning/10', + issue: 'text-destructive bg-destructive/10', + other: 'text-muted-foreground bg-muted' + }; + + // For nested groups, use the top-level parent's color + const topLevel = groupName.split('/')[0]; + return groupColors[topLevel] || 'text-muted-foreground bg-muted'; +} + function renderAccordionGroup(groupName, commands) { // Default to expanded for new/custom groups if (expandedGroups[groupName] === undefined) expandedGroups[groupName] = true; @@ -217,31 +261,14 @@ function renderAccordionGroup(groupName, commands) { ? commands : enabledCommands; - // Group icons - const groupIcons = { - cli: 'terminal', - workflow: 'workflow', - memory: 'brain', - task: 'clipboard-list', - issue: 'alert-circle', - other: 'folder' - }; - - // Group colors - const groupColors = { - cli: 'text-primary bg-primary/10', - workflow: 'text-success bg-success/10', - memory: 'text-indigo bg-indigo/10', - task: 'text-warning bg-warning/10', - issue: 'text-destructive bg-destructive/10', - other: 'text-muted-foreground bg-muted' - }; - - const icon = groupIcons[groupName] || 'folder'; - const colorClass = groupColors[groupName] || 'text-muted-foreground bg-muted'; + const icon = getGroupIcon(groupName); + const colorClass = getGroupColor(groupName); + const displayName = formatGroupName(groupName); + const indentLevel = (groupName.match(/\//g) || []).length; + const indentStyle = indentLevel > 0 ? `style="margin-left: ${indentLevel * 20}px;"` : ''; return ` -

+
@@ -250,7 +277,7 @@ function renderAccordionGroup(groupName, commands) {
-

${t('commands.group.' + groupName) || groupName}

+

${displayName}

${enabledCommands.length}/${commands.length} ${t('commands.enabled') || 'enabled'}

diff --git a/ccw/src/tools/claude-cli-tools.ts b/ccw/src/tools/claude-cli-tools.ts index 7e1fa798..a962569c 100644 --- a/ccw/src/tools/claude-cli-tools.ts +++ b/ccw/src/tools/claude-cli-tools.ts @@ -802,13 +802,15 @@ export function getNativeResume(projectDir: string): boolean { */ export function addClaudeApiEndpoint( projectDir: string, - endpoint: { id: string; name: string; enabled: boolean } + endpoint: { id: string; name: string; enabled: boolean; model?: string } ): ClaudeCliToolsConfig { const config = loadClaudeCliTools(projectDir); // Add as a tool with type: 'api-endpoint' config.tools[endpoint.name] = { enabled: endpoint.enabled, + primaryModel: endpoint.model, // Use endpoint.model as primaryModel (can be overridden via --model) + secondaryModel: endpoint.model, // Same as primary for fallback tags: [], type: 'api-endpoint', id: endpoint.id // Store endpoint ID for settings lookup diff --git a/ccw/src/tools/cli-executor-core.ts b/ccw/src/tools/cli-executor-core.ts index 04ca5299..458aa98b 100644 --- a/ccw/src/tools/cli-executor-core.ts +++ b/ccw/src/tools/cli-executor-core.ts @@ -557,6 +557,11 @@ async function executeCliTool( // id field is the LiteLLM endpoint ID (e.g., "g25") const litellmEndpointId = toolConfig.id || toolName; + // Use configured primary model if no explicit model provided + // This allows --model parameter to override the tool's primaryModel + // Use undefined if primaryModel is empty string (endpoint.model will be used as fallback) + const apiEndpointEffectiveModel = model || (toolConfig.primaryModel || undefined); + // Find LiteLLM endpoint configuration const litellmEndpoint = findEndpointById(workingDir, litellmEndpointId); if (litellmEndpoint) { @@ -568,13 +573,14 @@ async function executeCliTool( }); } - // Execute via LiteLLM + // Execute via LiteLLM with model override const result = await executeLiteLLMEndpoint({ prompt, endpointId: litellmEndpointId, baseDir: workingDir, cwd: cd || workingDir, includeDirs: includeDirs ? includeDirs.split(',').map(d => d.trim()) : undefined, + model: apiEndpointEffectiveModel, // Pass effective model (--model or primaryModel) onOutput: onOutput || undefined, }); @@ -587,7 +593,7 @@ async function executeCliTool( id: customId || `${Date.now()}-litellm`, timestamp: new Date(startTime).toISOString(), tool: toolName, - model: litellmEndpoint.model, + model: result.model, // Use effective model from result (reflects any override) mode, prompt, status: result.success ? 'success' : 'error', diff --git a/ccw/src/tools/litellm-executor.ts b/ccw/src/tools/litellm-executor.ts index 2380f6a8..31ee251d 100644 --- a/ccw/src/tools/litellm-executor.ts +++ b/ccw/src/tools/litellm-executor.ts @@ -19,6 +19,7 @@ export interface LiteLLMExecutionOptions { cwd?: string; // Working directory for file resolution includeDirs?: string[]; // Additional directories for @patterns enableCache?: boolean; // Override endpoint cache setting + model?: string; // Override model for this execution (if not specified, uses endpoint.model) onOutput?: (unit: CliOutputUnit) => void; /** Number of retries after the initial attempt (default: 0) */ maxRetries?: number; @@ -56,7 +57,7 @@ export function extractPatterns(prompt: string): string[] { export async function executeLiteLLMEndpoint( options: LiteLLMExecutionOptions ): Promise { - const { prompt, endpointId, baseDir, cwd, includeDirs, enableCache, onOutput } = options; + const { prompt, endpointId, baseDir, cwd, includeDirs, enableCache, model: modelOverride, onOutput } = options; // 1. Find endpoint configuration const endpoint = findEndpointById(baseDir, endpointId); @@ -96,7 +97,10 @@ export async function executeLiteLLMEndpoint( }; } - // 3. Process context cache if enabled + // 3. Determine effective model: use override if provided, otherwise use endpoint.model + const effectiveModel = modelOverride || endpoint.model; + + // 4. Process context cache if enabled let finalPrompt = prompt; let cacheUsed = false; let cachedFiles: string[] = []; @@ -168,12 +172,12 @@ export async function executeLiteLLMEndpoint( } } - // 4. Call LiteLLM + // 5. Call LiteLLM try { if (onOutput) { onOutput({ type: 'stderr', - content: `[LiteLLM: Calling ${provider.type}/${endpoint.model}]\n`, + content: `[LiteLLM: Calling ${provider.type}/${effectiveModel}]\n`, timestamp: new Date().toISOString() }); } @@ -206,14 +210,14 @@ export async function executeLiteLLMEndpoint( delete process.env['CCW_LITELLM_EXTRA_HEADERS']; } - // Use litellm-client to call chat + // Use litellm-client to call chat with effective model const response = await callWithRetries( - () => client.chat(finalPrompt, endpoint.model), + () => client.chat(finalPrompt, effectiveModel), { maxRetries: options.maxRetries ?? 0, baseDelayMs: options.retryBaseDelayMs ?? 1000, onOutput, - rateLimitKey: `${provider.type}:${endpoint.model}`, + rateLimitKey: `${provider.type}:${effectiveModel}`, }, ); @@ -228,7 +232,7 @@ export async function executeLiteLLMEndpoint( return { success: true, output: response, - model: endpoint.model, + model: effectiveModel, provider: provider.type, cacheUsed, cachedFiles, @@ -246,7 +250,7 @@ export async function executeLiteLLMEndpoint( return { success: false, output: '', - model: endpoint.model, + model: effectiveModel, provider: provider.type, cacheUsed, error: errorMsg,