diff --git a/.claude/commands/memory/load.md b/.claude/commands/memory/prepare.md similarity index 88% rename from .claude/commands/memory/load.md rename to .claude/commands/memory/prepare.md index 630e1838..9a0fa892 100644 --- a/.claude/commands/memory/load.md +++ b/.claude/commands/memory/prepare.md @@ -1,18 +1,18 @@ --- -name: load +name: prepare description: Delegate to universal-executor agent to analyze project via Gemini/Qwen CLI and return JSON core content package for task context argument-hint: "[--tool gemini|qwen] \"task context description\"" allowed-tools: Task(*), Bash(*) examples: - - /memory:load "在当前前端基础上开发用户认证功能" - - /memory:load --tool qwen "重构支付模块API" + - /memory:prepare "在当前前端基础上开发用户认证功能" + - /memory:prepare --tool qwen "重构支付模块API" --- -# Memory Load Command (/memory:load) +# Memory Prepare Command (/memory:prepare) ## 1. Overview -The `memory:load` command **delegates to a universal-executor agent** to analyze the project and return a structured "Core Content Pack". This pack is loaded into the main thread's memory, providing essential context for subsequent agent operations while minimizing token consumption. +The `memory:prepare` command **delegates to a universal-executor agent** to analyze the project and return a structured "Core Content Pack". This pack is loaded into the main thread's memory, providing essential context for subsequent agent operations while minimizing token consumption. **Core Philosophy**: - **Agent-Driven**: Fully delegates execution to universal-executor agent @@ -95,11 +95,11 @@ The command fully delegates to **universal-executor agent**, which autonomously: ```javascript Task( subagent_type="universal-executor", - description="Load project memory: ${task_description}", + description="Prepare project memory: ${task_description}", prompt=` -## Mission: Load Project Memory Context +## Mission: Prepare Project Memory Context -**Task**: Load project memory context for: "${task_description}" +**Task**: Prepare project memory context for: "${task_description}" **Mode**: analysis **Tool Preference**: ${tool || 'gemini'} @@ -186,7 +186,7 @@ Before returning: ### Example 1: Load Context for New Feature ```bash -/memory:load "在当前前端基础上开发用户认证功能" +/memory:prepare "在当前前端基础上开发用户认证功能" ``` **Agent Execution**: @@ -212,7 +212,7 @@ Before returning: ### Example 2: Using Qwen Tool ```bash -/memory:load --tool qwen "重构支付模块API" +/memory:prepare --tool qwen "重构支付模块API" ``` Agent uses Qwen CLI for analysis, returns same structured package. @@ -220,7 +220,7 @@ Agent uses Qwen CLI for analysis, returns same structured package. ### Example 3: Bug Fix Context ```bash -/memory:load "修复登录验证错误" +/memory:prepare "修复登录验证错误" ``` Returns core context related to login validation, including test files and validation logic. @@ -229,7 +229,7 @@ Returns core context related to login validation, including test files and valid - **Session-Scoped**: Content package valid for current session - **Subsequent Reference**: All subsequent agents/commands can access -- **Reload Required**: New sessions need to re-execute /memory:load +- **Reload Required**: New sessions need to re-execute /memory:prepare ## 8. Notes diff --git a/.claude/skills/memory-manage/SKILL.md b/.claude/skills/memory-manage/SKILL.md new file mode 100644 index 00000000..ef6f54c2 --- /dev/null +++ b/.claude/skills/memory-manage/SKILL.md @@ -0,0 +1,229 @@ +--- +name: memory-manage +description: Unified memory management - CLAUDE.md updates and documentation generation with interactive routing. Triggers on "memory manage", "update claude", "update memory", "generate docs", "更新记忆", "生成文档". +allowed-tools: Task(*), Bash(*), AskUserQuestion(*), Read(*) +--- + +# Memory Management Skill + +Unified entry point for project memory (CLAUDE.md) updates and documentation (API.md/README.md) generation. Routes to specialized sub-commands via arguments or interactive needs assessment. + +## Architecture Overview + +``` +┌──────────────────────────────────────────────────────┐ +│ Memory Manage (Router) │ +│ → Parse input → Detect mode → Route to phase │ +└───────────────┬──────────────────────────────────────┘ + │ + ┌───────┴───────┐ + ↓ ↓ + ┌───────────┐ ┌───────────┐ + │ CLAUDE.md │ │ Docs │ + │ 管理 │ │ 生成 │ + └─────┬─────┘ └─────┬─────┘ + │ │ + ┌────┼────┐ ┌────┴────┐ + ↓ ↓ ↓ ↓ ↓ + Full Related Single Full Related + 全量 增量 单模块 全量 增量 +``` + +## Execution Flow + +### Step 1: Parse Input & Route + +Detect execution mode from user input: + +**Auto-Route Rules** (priority order): + +| Signal | Route | Examples | +|--------|-------|---------| +| Explicit sub-command token | → Direct dispatch | `update-full --tool qwen` | +| Keyword: full, 全量, all, entire + update/claude | → update-full | "全量更新claude" | +| Keyword: related, changed, 增量, diff + update/claude | → update-related | "更新变更模块" | +| Keyword: single, module, 单模块 + path-like token | → update-single | "更新 src/auth 模块" | +| Keyword: docs, documentation, 文档 + full/all/全量 | → docs-full | "全量生成文档" | +| Keyword: docs, documentation, 文档 + related/changed/增量 | → docs-related | "增量生成文档" | +| Ambiguous or no arguments | → **AskUserQuestion** | `/memory-manage` | + +Valid sub-command tokens: `update-full`, `update-related`, `update-single`, `docs-full`, `docs-related` + +**Direct dispatch examples**: +``` +input = "update-full --tool qwen" + → subcommand = "update-full", remainingArgs = "--tool qwen" + → Read phases/01-update-full.md, execute + +input = "update-single src/auth --tool gemini" + → subcommand = "update-single", remainingArgs = "src/auth --tool gemini" + → Read phases/03-update-single.md, execute +``` + +**When ambiguous or no arguments**, proceed to Step 2. + +### Step 2: Interactive Needs Assessment + +**Q1 — 确定内容类别**: + +``` +AskUserQuestion({ + questions: [{ + question: "你要管理哪类内容?", + header: "类别", + multiSelect: false, + options: [ + { + label: "CLAUDE.md (项目记忆)", + description: "更新模块指令文件,帮助Claude理解代码库结构和约定" + }, + { + label: "项目文档 (API+README)", + description: "生成API.md和README.md到.workflow/docs/目录" + } + ] + }] +}) +``` + +**Q2a — CLAUDE.md 管理范围** (用户选了 CLAUDE.md): + +``` +AskUserQuestion({ + questions: [{ + question: "CLAUDE.md 更新范围?", + header: "范围", + multiSelect: false, + options: [ + { + label: "增量更新 (Recommended)", + description: "仅更新git变更模块及其父级,日常开发首选" + }, + { + label: "全量更新", + description: "更新所有模块,3层架构bottom-up,适合重大重构后" + }, + { + label: "单模块更新", + description: "指定一个模块,Explore深度分析后生成说明书式文档" + } + ] + }] +}) +``` + +Route mapping: +- "增量更新" → `update-related` → Ref: phases/02-update-related.md +- "全量更新" → `update-full` → Ref: phases/01-update-full.md +- "单模块更新" → `update-single` → continue to Q3 + +**Q2b — 文档生成范围** (用户选了项目文档): + +``` +AskUserQuestion({ + questions: [{ + question: "文档生成范围?", + header: "范围", + multiSelect: false, + options: [ + { + label: "增量生成 (Recommended)", + description: "仅为git变更模块生成/更新文档,日常开发首选" + }, + { + label: "全量生成", + description: "所有模块+项目级文档(ARCHITECTURE.md等),适合初始化" + } + ] + }] +}) +``` + +Route mapping: +- "增量生成" → `docs-related` → Ref: phases/05-docs-related.md +- "全量生成" → `docs-full` → Ref: phases/04-docs-full.md + +**Q3 — 补充路径** (仅 update-single 需要,且无路径参数时): + +``` +AskUserQuestion({ + questions: [{ + question: "请指定要更新的模块路径:", + header: "路径", + multiSelect: false, + options: [ + { + label: "src", + description: "src 目录" + }, + { + label: ".", + description: "项目根目录" + } + ] + }] +}) +``` + +用户可选 "Other" 输入自定义路径。 + +### Step 3: Execute Selected Phase + +Based on routing result, read and execute the corresponding phase: + +**Phase Reference Documents** (read on-demand when phase executes): + +| Mode | Document | Purpose | +|------|----------|---------| +| update-full | [phases/01-update-full.md](phases/01-update-full.md) | Full CLAUDE.md update, 3-layer architecture, batched agents | +| update-related | [phases/02-update-related.md](phases/02-update-related.md) | Git-changed CLAUDE.md update, depth-first | +| update-single | [phases/03-update-single.md](phases/03-update-single.md) | Single module CLAUDE.md, Explore + handbook style | +| docs-full | [phases/04-docs-full.md](phases/04-docs-full.md) | Full API.md + README.md generation | +| docs-related | [phases/05-docs-related.md](phases/05-docs-related.md) | Git-changed docs generation, incremental | + +## Shared Configuration + +### Tool Fallback Hierarchy + +All sub-commands share the same fallback: + +``` +--tool gemini → [gemini, qwen, codex] // default +--tool qwen → [qwen, gemini, codex] +--tool codex → [codex, gemini, qwen] +``` + +### Common Parameters + +| Parameter | Description | Default | Used By | +|-----------|-------------|---------|---------| +| `--tool ` | Primary CLI tool | gemini | All | +| `--path ` | Target directory | . | update-full, docs-full | +| `` (positional) | Module path | _(required)_ | update-single | + +### Batching Thresholds + +| Sub-Command | Direct Execution | Agent Batch | Batch Size | +|-------------|-----------------|-------------|------------| +| update-full | <20 modules | ≥20 modules | 4/agent | +| update-related | <15 modules | ≥15 modules | 4/agent | +| update-single | always single | N/A | 1 | +| docs-full | <20 modules | ≥20 modules | 4/agent | +| docs-related | <15 modules | ≥15 modules | 4/agent | + +## Core Rules + +1. **Route before execute**: Determine sub-command before any execution +2. **Phase doc is truth**: All execution logic lives in phase docs, router only dispatches +3. **Read on-demand**: Only read the selected phase doc, never load all +4. **Pass arguments through**: Forward remaining args unchanged to sub-command +5. **User confirmation**: Each sub-command handles its own plan presentation and y/n confirmation + +## Error Handling + +| Error | Resolution | +|-------|------------| +| Unknown sub-command | Fall through to interactive flow | +| Phase doc not found | Abort with file path error | +| Missing path for update-single | Prompt via Q3 | +| Sub-command execution fails | Follow phase doc's own error handling | diff --git a/.claude/commands/memory/update-full.md b/.claude/skills/memory-manage/phases/01-update-full.md similarity index 86% rename from .claude/commands/memory/update-full.md rename to .claude/skills/memory-manage/phases/01-update-full.md index fcc52094..33d96d54 100644 --- a/.claude/commands/memory/update-full.md +++ b/.claude/skills/memory-manage/phases/01-update-full.md @@ -1,24 +1,26 @@ ---- -name: update-full -description: Update all CLAUDE.md files using layer-based execution (Layer 3→1) with batched agents (4 modules/agent) and gemini→qwen→codex fallback, <20 modules uses direct parallel -argument-hint: "[--tool gemini|qwen|codex] [--path ]" ---- +# Phase 1: Full CLAUDE.md Update (update-full) -# Full Documentation Update (/memory:update-full) +全项目 CLAUDE.md 更新,使用 3 层架构 (Layer 3→1),批量 agent 执行,自动 tool fallback。 -## Overview +## Objective -Orchestrates project-wide CLAUDE.md updates using batched agent execution with automatic tool fallback and 3-layer architecture support. +- 发现所有项目模块并按深度分层 +- 按 Layer 3→2→1 顺序 bottom-up 更新所有模块的 CLAUDE.md +- <20 模块直接并行,≥20 模块使用 agent 批处理 (4 modules/agent) +- 自动 tool fallback (gemini→qwen→codex) + +## Parameters -**Parameters**: - `--tool `: Primary tool (default: gemini) - `--path `: Target specific directory (default: entire project) +## Execution + **Execution Flow**: Discovery → Plan Presentation → Execution → Safety Verification -## 3-Layer Architecture & Auto-Strategy Selection +### 3-Layer Architecture & Auto-Strategy Selection -### Layer Definition & Strategy Assignment +#### Layer Definition & Strategy Assignment | Layer | Depth | Strategy | Purpose | Context Pattern | |-------|-------|----------|---------|----------------| @@ -30,20 +32,17 @@ Orchestrates project-wide CLAUDE.md updates using batched agent execution with a **Strategy Auto-Selection**: Strategies are automatically determined by directory depth - no user configuration needed. -### Strategy Details - #### Multi-Layer Strategy (Layer 3 Only) - **Use Case**: Deepest directories with unstructured file layouts - **Behavior**: Generates CLAUDE.md for current directory AND each subdirectory containing files - **Context**: All files in current directory tree (`@**/*`) - #### Single-Layer Strategy (Layers 1-2) - **Use Case**: Upper layers that aggregate from existing documentation - **Behavior**: Generates CLAUDE.md only for current directory - **Context**: Direct children CLAUDE.md files + current directory code files -### Example Flow +#### Example Flow ``` src/auth/handlers/ (depth 3) → MULTI-LAYER STRATEGY CONTEXT: @**/* (all files in handlers/ and subdirs) @@ -62,7 +61,7 @@ src/ (depth 1) → SINGLE-LAYER STRATEGY GENERATES: ./CLAUDE.md only ``` -## Core Execution Rules +### Core Execution Rules 1. **Analyze First**: Git cache + module discovery before updates 2. **Wait for Approval**: Present plan, no execution without user confirmation @@ -74,7 +73,7 @@ src/ (depth 1) → SINGLE-LAYER STRATEGY 6. **Safety Check**: Verify only CLAUDE.md files modified 7. **Layer-based Grouping**: Group modules by LAYER (not depth) for execution -## Tool Fallback Hierarchy +### Tool Fallback Hierarchy ```javascript --tool gemini → [gemini, qwen, codex] // default @@ -90,9 +89,7 @@ src/ (depth 1) → SINGLE-LAYER STRATEGY | qwen | Architecture, system design | gemini → codex | | codex | Implementation, code quality | gemini → qwen | -## Execution Phases - -### Phase 1: Discovery & Analysis +### Step 1.1: Discovery & Analysis ```javascript // Cache git changes @@ -109,7 +106,7 @@ Bash({command: "cd && ccw tool exec get_modules_by_depth '{\"forma **Smart filter**: Auto-detect and skip tests/build/config/docs based on project tech stack. -### Phase 2: Plan Presentation +### Step 1.2: Plan Presentation **For <20 modules**: ``` @@ -168,7 +165,7 @@ Update Plan: Confirm execution? (y/n) ``` -### Phase 3A: Direct Execution (<20 modules) +### Step 1.3A: Direct Execution (<20 modules) **Strategy**: Parallel execution within layer (max 4 concurrent), no agent overhead. @@ -202,7 +199,7 @@ for (let layer of [3, 2, 1]) { } ``` -### Phase 3B: Agent Batch Execution (≥20 modules) +### Step 1.3B: Agent Batch Execution (≥20 modules) **Strategy**: Batch modules into groups of 4, spawn memory-bridge agents per batch. @@ -284,7 +281,8 @@ REPORTING FORMAT: ⚠️ path/to/module failed with {tool}, trying next... ❌ FAILED: path/to/module - all tools exhausted ``` -### Phase 4: Safety Verification + +### Step 1.4: Safety Verification ```javascript // Check only CLAUDE.md files modified @@ -308,25 +306,11 @@ Update Summary: **Coordinator**: Invalid path abort, user decline handling, safety check with auto-revert **Fallback Triggers**: Non-zero exit code, script timeout, unexpected output -## Usage Examples +## Output -```bash -# Full project update (auto-strategy selection) -/memory:update-full +- **Files**: Updated CLAUDE.md files across all project modules +- **Report**: Summary with success/failure counts and tool usage statistics -# Target specific directory -/memory:update-full --path .claude -/memory:update-full --path src/features/auth +## Next Phase -# Use specific tool -/memory:update-full --tool qwen -/memory:update-full --path .claude --tool qwen -``` - -## Key Advantages - -- **Efficiency**: 30 modules → 8 agents (73% reduction from sequential) -- **Resilience**: 3-tier tool fallback per module -- **Performance**: Parallel batches, no concurrency limits -- **Observability**: Per-module tool usage, batch-level metrics -- **Automation**: Zero configuration - strategy auto-selected by directory depth +Return to [manage.md](../manage.md) router. diff --git a/.claude/commands/memory/update-related.md b/.claude/skills/memory-manage/phases/02-update-related.md similarity index 65% rename from .claude/commands/memory/update-related.md rename to .claude/skills/memory-manage/phases/02-update-related.md index da38eeee..3b7049c9 100644 --- a/.claude/commands/memory/update-related.md +++ b/.claude/skills/memory-manage/phases/02-update-related.md @@ -1,22 +1,23 @@ ---- -name: update-related -description: Update CLAUDE.md for git-changed modules using batched agent execution (4 modules/agent) with gemini→qwen→codex fallback, <15 modules uses direct execution -argument-hint: "[--tool gemini|qwen|codex]" ---- +# Phase 2: Related CLAUDE.md Update (update-related) -# Related Documentation Update (/memory:update-related) +仅更新 git 变更模块的 CLAUDE.md,使用深度优先执行和自动 tool fallback。 -## Overview +## Objective -Orchestrates context-aware CLAUDE.md updates for changed modules using batched agent execution with automatic tool fallback (gemini→qwen→codex). +- 检测 git 变更,识别受影响模块 +- 按深度 N→0 顺序更新变更模块及其父级上下文 +- <15 模块直接并行,≥15 模块使用 agent 批处理 +- 自动 tool fallback (gemini→qwen→codex) + +## Parameters -**Parameters**: - `--tool `: Primary tool (default: gemini) -**Execution Flow**: -1. Change Detection → 2. Plan Presentation → 3. Batched Agent Execution → 4. Safety Verification +## Execution -## Core Rules +**Execution Flow**: Change Detection → Plan Presentation → Batched Execution → Safety Verification + +### Core Rules 1. **Detect Changes First**: Use git diff to identify affected modules 2. **Wait for Approval**: Present plan, no execution without user confirmation @@ -27,7 +28,7 @@ Orchestrates context-aware CLAUDE.md updates for changed modules using batched a 5. **Depth Sequential**: Process depths N→0, parallel batches within depth (both modes) 6. **Related Mode**: Update only changed modules and their parent contexts -## Tool Fallback Hierarchy +### Tool Fallback Hierarchy ```javascript --tool gemini → [gemini, qwen, codex] // default @@ -37,7 +38,7 @@ Orchestrates context-aware CLAUDE.md updates for changed modules using batched a **Trigger**: Non-zero exit code from update script -## Phase 1: Change Detection & Analysis +### Step 2.1: Change Detection & Analysis ```javascript // Detect changed modules @@ -53,7 +54,7 @@ Bash({command: "git add -A 2>/dev/null || true", run_in_background: false}); **Fallback**: If no changes detected, use recent modules (first 10 by depth). -## Phase 2: Plan Presentation +### Step 2.2: Plan Presentation **Present filtered plan**: ``` @@ -87,7 +88,7 @@ Related Update Plan: - <15 modules: Direct execution - ≥15 modules: Agent batch execution -## Phase 3A: Direct Execution (<15 modules) +### Step 2.3A: Direct Execution (<15 modules) **Strategy**: Parallel execution within depth (max 4 concurrent), no agent overhead. @@ -119,11 +120,9 @@ for (let depth of sorted_depths.reverse()) { // N → 0 } ``` ---- +### Step 2.3B: Agent Batch Execution (≥15 modules) -## Phase 3B: Agent Batch Execution (≥15 modules) - -### Batching Strategy +#### Batching Strategy ```javascript // Batch modules into groups of 4 @@ -137,7 +136,7 @@ function batch_modules(modules, batch_size = 4) { // Examples: 10→[4,4,2] | 8→[4,4] | 3→[3] ``` -### Coordinator Orchestration +#### Coordinator Orchestration ```javascript let modules_by_depth = group_by_depth(changed_modules); @@ -161,7 +160,7 @@ for (let depth of sorted_depths.reverse()) { // N → 0 } ``` -### Batch Worker Prompt Template +#### Batch Worker Prompt Template ``` PURPOSE: Update CLAUDE.md for assigned modules with tool fallback (related mode) @@ -212,7 +211,7 @@ Report final summary with: - Tool usage: {{tool_1}}:X, {{tool_2}}:Y, {{tool_3}}:Z ``` -## Phase 4: Safety Verification +### Step 2.4: Safety Verification ```javascript // Check only CLAUDE.md modified @@ -240,16 +239,6 @@ Update Summary: 4 files changed, 82 insertions(+), 6 deletions(-) ``` -## Execution Summary - -**Module Count Threshold**: -- **<15 modules**: Coordinator executes Phase 3A (Direct Execution) -- **≥15 modules**: Coordinator executes Phase 3B (Agent Batch Execution) - -**Agent Hierarchy** (for ≥15 modules): -- **Coordinator**: Handles batch division, spawns worker agents per depth -- **Worker Agents**: Each processes 4 modules with tool fallback (related mode) - ## Error Handling **Batch Worker**: @@ -268,65 +257,11 @@ Update Summary: - Script timeout - Unexpected output -## Tool Reference +## Output -| Tool | Best For | Fallback To | -|--------|--------------------------------|----------------| -| gemini | Documentation, patterns | qwen → codex | -| qwen | Architecture, system design | gemini → codex | -| codex | Implementation, code quality | gemini → qwen | +- **Files**: Updated CLAUDE.md files for changed modules and their parents +- **Report**: Summary with success/failure counts, tool usage, and git diff statistics -## Usage Examples +## Next Phase -```bash -# Daily development update -/memory:update-related - -# After feature work with specific tool -/memory:update-related --tool qwen - -# Code quality review after implementation -/memory:update-related --tool codex -``` - -## Key Advantages - -**Efficiency**: 30 modules → 8 agents (73% reduction) -**Resilience**: 3-tier fallback per module -**Performance**: Parallel batches, no concurrency limits -**Context-aware**: Updates based on actual git changes -**Fast**: Only affected modules, not entire project - -## Coordinator Checklist - -- Parse `--tool` (default: gemini) -- Refresh code index for accurate change detection -- Detect changed modules via detect_changed_modules.sh -- **Smart filter modules** (auto-detect tech stack, skip tests/build/config/docs) -- Cache git changes -- Apply fallback if no changes (recent 10 modules) -- Construct tool fallback order -- **Present filtered plan** with skip reasons and change types -- **Wait for y/n confirmation** -- Determine execution mode: - - **<15 modules**: Direct execution (Phase 3A) - - For each depth (N→0): Sequential module updates with tool fallback - - **≥15 modules**: Agent batch execution (Phase 3B) - - For each depth (N→0): Batch modules (4 per batch), spawn batch workers in parallel -- Wait for depth/batch completion -- Aggregate results -- Safety check (only CLAUDE.md modified) -- Display git diff statistics + summary - -## Comparison with Full Update - -| Aspect | Related Update | Full Update | -|--------|----------------|-------------| -| **Scope** | Changed modules only | All project modules | -| **Speed** | Fast (minutes) | Slower (10-30 min) | -| **Use case** | Daily development | Major refactoring | -| **Mode** | `"related"` | `"full"` | -| **Trigger** | After commits | After major changes | -| **Batching** | 4 modules/agent | 4 modules/agent | -| **Fallback** | gemini→qwen→codex | gemini→qwen→codex | -| **Complexity threshold** | ≤15 modules | ≤20 modules | +Return to [manage.md](../manage.md) router. diff --git a/.claude/commands/memory/update-single.md b/.claude/skills/memory-manage/phases/03-update-single.md similarity index 75% rename from .claude/commands/memory/update-single.md rename to .claude/skills/memory-manage/phases/03-update-single.md index e89bebf3..0113b99f 100644 --- a/.claude/commands/memory/update-single.md +++ b/.claude/skills/memory-manage/phases/03-update-single.md @@ -1,81 +1,47 @@ ---- -name: update-single -description: Update single module CLAUDE.md using Explore agent for deep codebase understanding, producing manual-style documentation (handbook, not API reference) -argument-hint: " [--tool gemini|qwen|codex]" -allowed-tools: Task(*), Bash(*), AskUserQuestion(*) ---- +# Phase 3: Single Module CLAUDE.md Update (update-single) -# Single Module Documentation Update (/memory:update-single) +使用 Explore agent 深度分析后,为单个目标模块生成手册式 (说明书) CLAUDE.md。 -## Overview +## Objective -Generates a manual-style CLAUDE.md for a single target directory using Explore agent for deep semantic codebase understanding. The output reads like a module handbook — explaining what it does, how to use it, and how it integrates — rather than dry API documentation. - -**Core capabilities:** -- Explore agent for semantic codebase exploration (not just file scanning) -- Manual/handbook-style output (usage guide, not reference docs) -- Interactive confirmation with exploration summary preview +- 验证目标路径并扫描结构 +- 使用 Explore agent 进行 7 维度深度探索 +- 交互确认后通过 CLI tool 生成手册式 CLAUDE.md - Tool fallback (gemini→qwen→codex) -## Usage +## Parameters -```bash -/memory:update-single [--tool gemini|qwen|codex] +- ``: Target directory path (required) +- `--tool `: Primary CLI tool (default: gemini) -# Arguments - Target directory path (required) - -# Options ---tool Primary CLI tool (default: gemini) - -# Examples -/memory:update-single src/auth -/memory:update-single .claude/commands --tool qwen -/memory:update-single ccw/frontend/src/components/issue -``` - -## Output Artifacts - -| Artifact | Description | -|----------|-------------| -| `/CLAUDE.md` | Manual-style module handbook | - -**CLAUDE.md Style** — "说明书" not "文档": -- What this module does (purpose & responsibility) -- How to use it (patterns, conventions, examples) -- How it integrates (dependencies, exports, data flow) -- Important constraints (gotchas, rules, limitations) - -## Execution Process +## Execution ``` -Phase 1: Target Validation & Scan +Step 3.1: Target Validation & Scan ├─ Parse arguments (path, --tool) ├─ Validate target directory exists └─ Quick structure scan (file count, types, depth) -Phase 2: Deep Exploration (Explore Agent) +Step 3.2: Deep Exploration (Explore Agent) ├─ Launch Explore agent with "very thorough" level ├─ Analyze purpose, structure, patterns, exports, dependencies └─ Build comprehensive module understanding -Phase 3: Confirmation +Step 3.3: Confirmation ├─ Display exploration summary (key findings) └─ AskUserQuestion: Generate / Cancel -Phase 4: Generate CLAUDE.md (CLI Tool) +Step 3.4: Generate CLAUDE.md (CLI Tool) ├─ Construct manual-style prompt from exploration results ├─ Execute ccw cli with --mode write ├─ Tool fallback on failure └─ Write to /CLAUDE.md -Phase 5: Verification +Step 3.5: Verification └─ Display generated CLAUDE.md preview + stats ``` -## Implementation - -### Phase 1: Target Validation & Scan +### Step 3.1: Target Validation & Scan ```javascript // Parse arguments @@ -86,7 +52,7 @@ const primaryTool = toolFlagIdx !== -1 ? parts[toolFlagIdx + 1] : 'gemini' const targetPath = parts.find(p => !p.startsWith('--') && p !== primaryTool) if (!targetPath) { - console.log('ERROR: is required. Usage: /memory:update-single [--tool gemini|qwen|codex]') + console.log('ERROR: is required. Usage: /memory:manage update-single [--tool gemini|qwen|codex]') return } @@ -112,9 +78,9 @@ Launching deep exploration... `) ``` -### Phase 2: Deep Exploration (Explore Agent) +### Step 3.2: Deep Exploration (Explore Agent) -**⚠️ CRITICAL**: Use `run_in_background: false` — exploration results are REQUIRED before generation. +**CRITICAL**: Use `run_in_background: false` — exploration results are REQUIRED before generation. ```javascript const explorationResult = Task( @@ -173,7 +139,7 @@ Return a structured summary covering all 7 dimensions above. Include specific fi ) ``` -### Phase 3: Confirmation +### Step 3.3: Confirmation ```javascript console.log(` @@ -203,7 +169,7 @@ AskUserQuestion({ // Cancel → abort ``` -### Phase 4: Generate CLAUDE.md (CLI Tool) +### Step 3.4: Generate CLAUDE.md (CLI Tool) **Tool fallback hierarchy**: ```javascript @@ -285,7 +251,7 @@ CONSTRAINTS: Only write CLAUDE.md, no other files" --tool ${tool} --mode write - } ``` -### Phase 5: Verification +### Step 3.5: Verification ```javascript // Check file was created/updated @@ -311,8 +277,8 @@ console.log(` The generated CLAUDE.md is a **说明书 (handbook)**, NOT a reference doc: -| Aspect | Handbook Style ✅ | Reference Doc Style ❌ | -|--------|-------------------|----------------------| +| Aspect | Handbook Style | Reference Doc Style | +|--------|---------------|---------------------| | Purpose | "This module handles user auth" | "Authentication module" | | Content | How to work with it | What every function does | | Patterns | "Always use `createAuthMiddleware()`" | "List of all exports" | @@ -330,18 +296,11 @@ The generated CLAUDE.md is a **说明书 (handbook)**, NOT a reference doc: | Empty directory | Abort — nothing to document | | Existing CLAUDE.md | Overwrite entirely (full regeneration) | -## Usage Examples +## Output -```bash -# Generate handbook for a module -/memory:update-single src/auth +- **File**: `/CLAUDE.md` — Manual-style module handbook +- **Preview**: First 30 lines displayed after generation -# Use specific tool -/memory:update-single .claude/commands --tool qwen +## Next Phase -# Deep nested module -/memory:update-single ccw/frontend/src/components/issue - -# Root-level documentation -/memory:update-single . -``` +Return to [manage.md](../manage.md) router. diff --git a/.claude/commands/memory/docs-full-cli.md b/.claude/skills/memory-manage/phases/04-docs-full.md similarity index 83% rename from .claude/commands/memory/docs-full-cli.md rename to .claude/skills/memory-manage/phases/04-docs-full.md index c99f592f..27ef7498 100644 --- a/.claude/commands/memory/docs-full-cli.md +++ b/.claude/skills/memory-manage/phases/04-docs-full.md @@ -1,24 +1,27 @@ ---- -name: docs-full-cli -description: Generate full project documentation using CLI execution (Layer 3→1) with batched agents (4 modules/agent) and gemini→qwen→codex fallback, <20 modules uses direct parallel -argument-hint: "[path] [--tool ]" ---- +# Phase 4: Full Documentation Generation (docs-full) -# Full Documentation Generation - CLI Mode (/memory:docs-full-cli) +全项目 API.md + README.md 文档生成,使用 CLI 执行、3 层架构和自动 tool fallback,输出到 .workflow/docs/。 -## Overview +## Objective -Orchestrates project-wide documentation generation using CLI-based execution with batched agents and automatic tool fallback. +- 发现所有项目模块并按深度分层 +- 按 Layer 3→2→1 顺序生成 API.md + README.md 文档 +- <20 模块直接并行,≥20 模块使用 agent 批处理 +- 生成项目级文档 (README.md, ARCHITECTURE.md, EXAMPLES.md) +- 自动 tool fallback (gemini→qwen→codex) + +## Parameters -**Parameters**: - `path`: Target directory (default: current directory) - `--tool `: Primary tool (default: gemini) -**Execution Flow**: Discovery → Plan Presentation → Execution → Verification +## Execution -## 3-Layer Architecture & Auto-Strategy Selection +**Execution Flow**: Discovery → Plan Presentation → Execution → Project-Level Docs → Verification -### Layer Definition & Strategy Assignment +### 3-Layer Architecture & Auto-Strategy Selection + +#### Layer Definition & Strategy Assignment | Layer | Depth | Strategy | Purpose | Context Pattern | |-------|-------|----------|---------|----------------| @@ -28,24 +31,19 @@ Orchestrates project-wide documentation generation using CLI-based execution wit **Generation Direction**: Layer 3 → Layer 2 → Layer 1 (bottom-up dependency flow) -**Strategy Auto-Selection**: Strategies are automatically determined by directory depth - no user configuration needed. - -### Strategy Details - #### Full Strategy (Layer 3 Only) - **Use Case**: Deepest directories with comprehensive file coverage - **Behavior**: Generates API.md + README.md for current directory AND subdirectories containing code - **Context**: All files in current directory tree (`@**/*`) - **Output**: `.workflow/docs/{project_name}/{path}/API.md` + `README.md` - #### Single Strategy (Layers 1-2) - **Use Case**: Upper layers that aggregate from existing documentation - **Behavior**: Generates API.md + README.md only in current directory - **Context**: Direct children docs + current directory code files - **Output**: `.workflow/docs/{project_name}/{path}/API.md` + `README.md` -### Example Flow +#### Example Flow ``` src/auth/handlers/ (depth 3) → FULL STRATEGY CONTEXT: @**/* (all files in handlers/ and subdirs) @@ -64,7 +62,7 @@ src/ (depth 1) → SINGLE STRATEGY GENERATES: .workflow/docs/project/{API.md,README.md} only ``` -## Core Execution Rules +### Core Execution Rules 1. **Analyze First**: Module discovery + folder classification before generation 2. **Wait for Approval**: Present plan, no execution without user confirmation @@ -76,7 +74,7 @@ src/ (depth 1) → SINGLE STRATEGY 6. **Safety Check**: Verify only docs files modified in .workflow/docs/ 7. **Layer-based Grouping**: Group modules by LAYER (not depth) for execution -## Tool Fallback Hierarchy +### Tool Fallback Hierarchy ```javascript --tool gemini → [gemini, qwen, codex] // default @@ -84,17 +82,7 @@ src/ (depth 1) → SINGLE STRATEGY --tool codex → [codex, gemini, qwen] ``` -**Trigger**: Non-zero exit code from generation script - -| Tool | Best For | Fallback To | -|--------|--------------------------------|----------------| -| gemini | Documentation, patterns | qwen → codex | -| qwen | Architecture, system design | gemini → codex | -| codex | Implementation, code quality | gemini → qwen | - -## Execution Phases - -### Phase 1: Discovery & Analysis +### Step 4.1: Discovery & Analysis ```javascript // Get project metadata @@ -111,7 +99,7 @@ Bash({command: "cd && ccw tool exec get_modules_by_depth '{\"forma **Smart filter**: Auto-detect and skip tests/build/config/vendor based on project tech stack. -### Phase 2: Plan Presentation +### Step 4.2: Plan Presentation **For <20 modules**: ``` @@ -139,7 +127,6 @@ Documentation Generation Plan: Auto-skipped: ./tests, __pycache__, node_modules (15 paths) Execution order: Layer 2 → Layer 1 - Estimated time: ~5-10 minutes Confirm execution? (y/n) ``` @@ -176,12 +163,10 @@ Documentation Generation Plan: - Layer 2 (15 modules, depth 1-2): 4 agents [4, 4, 4, 3] - Layer 1 (2 modules, depth 0): 1 agent [2] - Estimated time: ~15-25 minutes - Confirm execution? (y/n) ``` -### Phase 3A: Direct Execution (<20 modules) +### Step 4.3A: Direct Execution (<20 modules) **Strategy**: Parallel execution within layer (max 4 concurrent), no agent overhead. @@ -217,7 +202,7 @@ for (let layer of [3, 2, 1]) { } ``` -### Phase 3B: Agent Batch Execution (≥20 modules) +### Step 4.3B: Agent Batch Execution (≥20 modules) **Strategy**: Batch modules into groups of 4, spawn memory-bridge agents per batch. @@ -290,7 +275,6 @@ EXECUTION FLOW (for each module): 2. Handle complete failure (all tools failed): if [ $exit_code -ne 0 ]; then report "❌ FAILED: {{module_path}} - all tools exhausted" - # Continue to next module (do not abort batch) fi FOLDER TYPE HANDLING: @@ -310,7 +294,7 @@ REPORTING FORMAT: ❌ FAILED: path/to/module - all tools exhausted ``` -### Phase 4: Project-Level Documentation +### Step 4.4: Project-Level Documentation **After all module documentation is generated, create project-level documentation files.** @@ -370,7 +354,7 @@ Project-Level Documentation: ✅ api/README.md (HTTP API reference) [optional] ``` -### Phase 5: Verification +### Step 4.5: Verification ```javascript // Check documentation files created @@ -398,12 +382,6 @@ Documentation Generation Summary: └── README.md ``` -## Error Handling - -**Batch Worker**: Tool fallback per module, batch isolation, clear status reporting -**Coordinator**: Invalid path abort, user decline handling, verification with cleanup -**Fallback Triggers**: Non-zero exit code, script timeout, unexpected output - ## Output Structure ``` @@ -426,36 +404,18 @@ Documentation Generation Summary: │ └── core/ │ ├── API.md │ └── README.md -├── README.md # ✨ Project root overview (auto-generated) -├── ARCHITECTURE.md # ✨ System design (auto-generated) -├── EXAMPLES.md # ✨ Usage examples (auto-generated) -└── api/ # ✨ Optional (auto-generated if HTTP API detected) +├── README.md # Project root overview (auto-generated) +├── ARCHITECTURE.md # System design (auto-generated) +├── EXAMPLES.md # Usage examples (auto-generated) +└── api/ # Optional (auto-generated if HTTP API detected) └── README.md # HTTP API reference ``` -## Usage Examples +## Error Handling -```bash -# Full project documentation generation -/memory:docs-full-cli - -# Target specific directory -/memory:docs-full-cli src/features/auth -/memory:docs-full-cli .claude - -# Use specific tool -/memory:docs-full-cli --tool qwen -/memory:docs-full-cli src --tool qwen -``` - -## Key Advantages - -- **Efficiency**: 30 modules → 8 agents (73% reduction from sequential) -- **Resilience**: 3-tier tool fallback per module -- **Performance**: Parallel batches, no concurrency limits -- **Observability**: Per-module tool usage, batch-level metrics -- **Automation**: Zero configuration - strategy auto-selected by directory depth -- **Path Mirroring**: Clear 1:1 mapping between source and documentation structure +**Batch Worker**: Tool fallback per module, batch isolation, clear status reporting +**Coordinator**: Invalid path abort, user decline handling, verification with cleanup +**Fallback Triggers**: Non-zero exit code, script timeout, unexpected output ## Template Reference @@ -464,8 +424,12 @@ Templates used from `~/.ccw/workflows/cli-templates/prompts/documentation/`: - `module-readme.txt`: Module purpose, usage, dependencies - `folder-navigation.txt`: Navigation README for folders with subdirectories -## Related Commands +## Output -- `/memory:docs` - Agent-based documentation planning workflow -- `/memory:docs-related-cli` - Update docs for changed modules only -- `/workflow:execute` - Execute documentation tasks (when using agent mode) +- **Directory**: `.workflow/docs/{project_name}/` — Complete documentation tree +- **Project-Level**: README.md, ARCHITECTURE.md, EXAMPLES.md, api/README.md (optional) +- **Report**: Summary with success/failure counts and tool usage statistics + +## Next Phase + +Return to [manage.md](../manage.md) router. diff --git a/.claude/commands/memory/docs-related-cli.md b/.claude/skills/memory-manage/phases/05-docs-related.md similarity index 68% rename from .claude/commands/memory/docs-related-cli.md rename to .claude/skills/memory-manage/phases/05-docs-related.md index 3dcc61a9..aba99189 100644 --- a/.claude/commands/memory/docs-related-cli.md +++ b/.claude/skills/memory-manage/phases/05-docs-related.md @@ -1,22 +1,24 @@ ---- -name: docs-related-cli -description: Generate/update documentation for git-changed modules using CLI execution with batched agents (4 modules/agent) and gemini→qwen→codex fallback, <15 modules uses direct parallel -argument-hint: "[--tool ]" ---- +# Phase 5: Related Documentation Generation (docs-related) -# Related Documentation Generation - CLI Mode (/memory:docs-related-cli) +仅为 git 变更模块生成/更新 API.md + README.md 文档,使用增量策略和自动 tool fallback。 -## Overview +## Objective -Orchestrates context-aware documentation generation/update for changed modules using CLI-based execution with batched agents and automatic tool fallback (gemini→qwen→codex). +- 检测 git 变更,识别受影响模块 +- 按深度 N→0 顺序为变更模块生成/更新文档 +- <15 模块直接并行,≥15 模块使用 agent 批处理 +- 使用 single 策略进行增量更新 +- 自动 tool fallback (gemini→qwen→codex) + +## Parameters -**Parameters**: - `--tool `: Primary tool (default: gemini) -**Execution Flow**: -1. Change Detection → 2. Plan Presentation → 3. Batched Execution → 4. Verification +## Execution -## Core Rules +**Execution Flow**: Change Detection → Plan Presentation → Batched Execution → Verification + +### Core Rules 1. **Detect Changes First**: Use git diff to identify affected modules 2. **Wait for Approval**: Present plan, no execution without user confirmation @@ -28,7 +30,7 @@ Orchestrates context-aware documentation generation/update for changed modules u 6. **Related Mode**: Generate/update only changed modules and their parent contexts 7. **Single Strategy**: Always use `single` strategy (incremental update) -## Tool Fallback Hierarchy +### Tool Fallback Hierarchy ```javascript --tool gemini → [gemini, qwen, codex] // default @@ -36,15 +38,7 @@ Orchestrates context-aware documentation generation/update for changed modules u --tool codex → [codex, gemini, qwen] ``` -**Trigger**: Non-zero exit code from generation script - -| Tool | Best For | Fallback To | -|--------|--------------------------------|----------------| -| gemini | Documentation, patterns | qwen → codex | -| qwen | Architecture, system design | gemini → codex | -| codex | Implementation, code quality | gemini → qwen | - -## Phase 1: Change Detection & Analysis +### Step 5.1: Change Detection & Analysis ```javascript // Get project metadata @@ -63,7 +57,7 @@ Bash({command: "git add -A 2>/dev/null || true", run_in_background: false}); **Fallback**: If no changes detected, use recent modules (first 10 by depth). -## Phase 2: Plan Presentation +### Step 5.2: Plan Presentation **Present filtered plan**: ``` @@ -95,8 +89,6 @@ Related Documentation Generation Plan: - Depth 1 (1 module): 1 agent [1] - Depth 0 (1 module): 1 agent [1] - Estimated time: ~5-10 minutes - Confirm execution? (y/n) ``` @@ -106,7 +98,7 @@ Related Documentation Generation Plan: - <15 modules: Direct execution - ≥15 modules: Agent batch execution -## Phase 3A: Direct Execution (<15 modules) +### Step 5.3A: Direct Execution (<15 modules) **Strategy**: Parallel execution within depth (max 4 concurrent), no agent overhead. @@ -140,9 +132,9 @@ for (let depth of sorted_depths.reverse()) { // N → 0 } ``` -## Phase 3B: Agent Batch Execution (≥15 modules) +### Step 5.3B: Agent Batch Execution (≥15 modules) -### Batching Strategy +#### Batching Strategy ```javascript // Batch modules into groups of 4 @@ -156,7 +148,7 @@ function batch_modules(modules, batch_size = 4) { // Examples: 10→[4,4,2] | 8→[4,4] | 3→[3] ``` -### Coordinator Orchestration +#### Coordinator Orchestration ```javascript let modules_by_depth = group_by_depth(changed_modules); @@ -181,7 +173,7 @@ for (let depth of sorted_depths.reverse()) { // N → 0 } ``` -### Batch Worker Prompt Template +#### Batch Worker Prompt Template ``` PURPOSE: Generate/update documentation for assigned modules with tool fallback (related mode) @@ -239,7 +231,7 @@ Report final summary with: - Tool usage: {{tool_1}}:X, {{tool_2}}:Y, {{tool_3}}:Z ``` -## Phase 4: Verification +### Step 5.4: Verification ```javascript // Check documentation files created/updated @@ -270,15 +262,23 @@ Documentation Generation Summary: .workflow/docs/myproject/README.md (updated) ``` -## Execution Summary +## Output Structure -**Module Count Threshold**: -- **<15 modules**: Coordinator executes Phase 3A (Direct Execution) -- **≥15 modules**: Coordinator executes Phase 3B (Agent Batch Execution) - -**Agent Hierarchy** (for ≥15 modules): -- **Coordinator**: Handles batch division, spawns worker agents per depth -- **Worker Agents**: Each processes 4 modules with tool fallback (related mode) +``` +.workflow/docs/{project_name}/ +├── src/ # Mirrors source structure +│ ├── modules/ +│ │ ├── README.md +│ │ ├── auth/ +│ │ │ ├── API.md # Updated based on code changes +│ │ │ └── README.md # Updated based on code changes +│ │ └── api/ +│ │ ├── API.md +│ │ └── README.md +│ └── utils/ +│ └── README.md +└── README.md +``` ## Error Handling @@ -298,80 +298,6 @@ Documentation Generation Summary: - Script timeout - Unexpected output -## Output Structure - -``` -.workflow/docs/{project_name}/ -├── src/ # Mirrors source structure -│ ├── modules/ -│ │ ├── README.md -│ │ ├── auth/ -│ │ │ ├── API.md # Updated based on code changes -│ │ │ └── README.md # Updated based on code changes -│ │ └── api/ -│ │ ├── API.md -│ │ └── README.md -│ └── utils/ -│ └── README.md -└── README.md -``` - -## Usage Examples - -```bash -# Daily development documentation update -/memory:docs-related-cli - -# After feature work with specific tool -/memory:docs-related-cli --tool qwen - -# Code quality documentation review after implementation -/memory:docs-related-cli --tool codex -``` - -## Key Advantages - -**Efficiency**: 30 modules → 8 agents (73% reduction) -**Resilience**: 3-tier fallback per module -**Performance**: Parallel batches, no concurrency limits -**Context-aware**: Updates based on actual git changes -**Fast**: Only affected modules, not entire project -**Incremental**: Single strategy for focused updates - -## Coordinator Checklist - -- Parse `--tool` (default: gemini) -- Get project metadata (name, root) -- Detect changed modules via detect_changed_modules.sh -- **Smart filter modules** (auto-detect tech stack, skip tests/build/config/vendor) -- Cache git changes -- Apply fallback if no changes (recent 10 modules) -- Construct tool fallback order -- **Present filtered plan** with skip reasons and change types -- **Wait for y/n confirmation** -- Determine execution mode: - - **<15 modules**: Direct execution (Phase 3A) - - For each depth (N→0): Sequential module updates with tool fallback - - **≥15 modules**: Agent batch execution (Phase 3B) - - For each depth (N→0): Batch modules (4 per batch), spawn batch workers in parallel -- Wait for depth/batch completion -- Aggregate results -- Verification check (documentation files created/updated) -- Display summary + recent changes - -## Comparison with Full Documentation Generation - -| Aspect | Related Generation | Full Generation | -|--------|-------------------|-----------------| -| **Scope** | Changed modules only | All project modules | -| **Speed** | Fast (minutes) | Slower (10-30 min) | -| **Use case** | Daily development | Initial setup, major refactoring | -| **Strategy** | `single` (all) | `full` (L3) + `single` (L1-2) | -| **Trigger** | After commits | After setup or major changes | -| **Batching** | 4 modules/agent | 4 modules/agent | -| **Fallback** | gemini→qwen→codex | gemini→qwen→codex | -| **Complexity threshold** | ≤15 modules | ≤20 modules | - ## Template Reference Templates used from `~/.ccw/workflows/cli-templates/prompts/documentation/`: @@ -379,8 +305,11 @@ Templates used from `~/.ccw/workflows/cli-templates/prompts/documentation/`: - `module-readme.txt`: Module purpose, usage, dependencies - `folder-navigation.txt`: Navigation README for folders -## Related Commands +## Output -- `/memory:docs-full-cli` - Full project documentation generation -- `/memory:docs` - Agent-based documentation planning workflow -- `/memory:update-related` - Update CLAUDE.md for changed modules +- **Directory**: `.workflow/docs/{project_name}/` — Updated documentation for changed modules +- **Report**: Summary with success/failure counts, tool usage, and file change list + +## Next Phase + +Return to [manage.md](../manage.md) router. diff --git a/ccw/.tmp-ccw-path-resolver-home/config/recent-paths.json b/ccw/.tmp-ccw-path-resolver-home/config/recent-paths.json new file mode 100644 index 00000000..198240cd --- /dev/null +++ b/ccw/.tmp-ccw-path-resolver-home/config/recent-paths.json @@ -0,0 +1,5 @@ +{ + "paths": [ + "C:/project/demo" + ] +} \ No newline at end of file diff --git a/ccw/frontend/src/components/issue/hub/ExecutionPanel.tsx b/ccw/frontend/src/components/issue/hub/ExecutionPanel.tsx index e4f778b1..aa3615d3 100644 --- a/ccw/frontend/src/components/issue/hub/ExecutionPanel.tsx +++ b/ccw/frontend/src/components/issue/hub/ExecutionPanel.tsx @@ -11,9 +11,7 @@ import { Play, CheckCircle, XCircle, - Clock, Terminal, - Loader2, } from 'lucide-react'; import { Card } from '@/components/ui/Card'; import { Badge } from '@/components/ui/Badge'; @@ -23,50 +21,9 @@ import { selectExecutionStats, useTerminalPanelStore, } from '@/stores'; -import type { QueueExecution, QueueExecutionStatus } from '@/stores/queueExecutionStore'; +import type { QueueExecution } from '@/stores/queueExecutionStore'; import { cn } from '@/lib/utils'; - -// ========== Helpers ========== - -function statusBadgeVariant(status: QueueExecutionStatus): 'info' | 'success' | 'destructive' | 'secondary' { - switch (status) { - case 'running': - return 'info'; - case 'completed': - return 'success'; - case 'failed': - return 'destructive'; - case 'pending': - default: - return 'secondary'; - } -} - -function statusIcon(status: QueueExecutionStatus) { - switch (status) { - case 'running': - return ; - case 'completed': - return ; - case 'failed': - return ; - case 'pending': - default: - return ; - } -} - -function formatRelativeTime(isoString: string): string { - const diff = Date.now() - new Date(isoString).getTime(); - const seconds = Math.floor(diff / 1000); - if (seconds < 60) return `${seconds}s ago`; - const minutes = Math.floor(seconds / 60); - if (minutes < 60) return `${minutes}m ago`; - const hours = Math.floor(minutes / 60); - if (hours < 24) return `${hours}h ago`; - const days = Math.floor(hours / 24); - return `${days}d ago`; -} +import { statusIcon, statusBadgeVariant, formatRelativeTime } from '@/lib/execution-display-utils'; // ========== Empty State ========== diff --git a/ccw/frontend/src/components/issue/queue/QueueItemExecutor.tsx b/ccw/frontend/src/components/issue/queue/QueueItemExecutor.tsx index 17f38265..b106fc51 100644 --- a/ccw/frontend/src/components/issue/queue/QueueItemExecutor.tsx +++ b/ccw/frontend/src/components/issue/queue/QueueItemExecutor.tsx @@ -38,6 +38,7 @@ import { } from '@/components/shared/CliExecutionSettings'; import { buildQueueItemContext } from '@/lib/queue-prompt'; import { useQueueExecutionStore, type QueueExecution } from '@/stores/queueExecutionStore'; +import type { Flow } from '@/types/flow'; // --------------------------------------------------------------------------- // Types @@ -70,7 +71,7 @@ export function QueueItemExecutor({ item, className }: QueueItemExecutorProps) { // Resolve the parent issue for context building const { issues } = useIssues(); const issue = useMemo( - () => issues.find((i) => i.id === item.issue_id) as any, + () => issues.find((i) => i.id === item.issue_id), [issues, item.issue_id] ); @@ -203,13 +204,13 @@ export function QueueItemExecutor({ item, className }: QueueItemExecutorProps) { throw new Error('Failed to create flow'); } - // Hydrate Orchestrator stores - const flowDto = created.data as any; + // Hydrate Orchestrator stores -- convert OrchestratorFlowDto to Flow + const flowDto = created.data; const parsedVersion = parseInt(String(flowDto.version ?? '1'), 10); - const flowForStore = { + const flowForStore: Flow = { ...flowDto, version: Number.isFinite(parsedVersion) ? parsedVersion : 1, - } as any; + } as Flow; useFlowStore.getState().setCurrentFlow(flowForStore); // Execute the flow diff --git a/ccw/frontend/src/components/mcp/CcwToolsMcpCard.tsx b/ccw/frontend/src/components/mcp/CcwToolsMcpCard.tsx index 391d4271..bce79ee1 100644 --- a/ccw/frontend/src/components/mcp/CcwToolsMcpCard.tsx +++ b/ccw/frontend/src/components/mcp/CcwToolsMcpCard.tsx @@ -59,7 +59,7 @@ export interface CcwConfig { enabledTools: string[]; projectRoot?: string; allowedDirs?: string; - disableSandbox?: boolean; + enableSandbox?: boolean; } /** @@ -75,7 +75,7 @@ export interface CcwToolsMcpCardProps { /** Comma-separated list of allowed directories */ allowedDirs?: string; /** Whether sandbox is disabled */ - disableSandbox?: boolean; + enableSandbox?: boolean; /** Callback when a tool is toggled */ onToggleTool: (tool: string, enabled: boolean) => void; /** Callback when configuration is updated */ @@ -110,7 +110,7 @@ export function CcwToolsMcpCard({ enabledTools, projectRoot, allowedDirs, - disableSandbox, + enableSandbox, onToggleTool, onUpdateConfig, onInstall, @@ -123,7 +123,7 @@ export function CcwToolsMcpCard({ // Local state for config inputs const [projectRootInput, setProjectRootInput] = useState(projectRoot || ''); const [allowedDirsInput, setAllowedDirsInput] = useState(allowedDirs || ''); - const [disableSandboxInput, setDisableSandboxInput] = useState(disableSandbox || false); + const [enableSandboxInput, setEnableSandboxInput] = useState(enableSandbox || false); const [isExpanded, setIsExpanded] = useState(false); const [installScope, setInstallScope] = useState<'global' | 'project'>('global'); @@ -193,7 +193,7 @@ export function CcwToolsMcpCard({ updateConfigMutation.mutate({ projectRoot: projectRootInput || undefined, allowedDirs: allowedDirsInput || undefined, - disableSandbox: disableSandboxInput, + enableSandbox: enableSandboxInput, }); }; @@ -387,22 +387,22 @@ export function CcwToolsMcpCard({

- {/* Disable Sandbox */} + {/* Enable Sandbox */}
setDisableSandboxInput(e.target.checked)} + id="ccw-enable-sandbox" + checked={enableSandboxInput} + onChange={(e) => setEnableSandboxInput(e.target.checked)} disabled={!isInstalled} className="w-4 h-4" />
diff --git a/ccw/frontend/src/components/terminal-panel/QueueExecutionListView.tsx b/ccw/frontend/src/components/terminal-panel/QueueExecutionListView.tsx new file mode 100644 index 00000000..8a29035c --- /dev/null +++ b/ccw/frontend/src/components/terminal-panel/QueueExecutionListView.tsx @@ -0,0 +1,133 @@ +// ======================================== +// QueueExecutionListView Component +// ======================================== +// Compact execution list for TerminalPanel queue view. +// Subscribes to queueExecutionStore and renders execution entries +// with status badges, tool/mode labels, and relative timestamps. +// Click navigates to terminal view (session) or orchestrator page. + +import { useMemo } from 'react'; +import { useIntl } from 'react-intl'; +import { useNavigate } from 'react-router-dom'; +import { ClipboardList } from 'lucide-react'; +import { Badge } from '@/components/ui/Badge'; +import { cn } from '@/lib/utils'; +import { useQueueExecutionStore } from '@/stores/queueExecutionStore'; +import { useTerminalPanelStore } from '@/stores/terminalPanelStore'; +import type { QueueExecution } from '@/stores/queueExecutionStore'; +import { ROUTES } from '@/router'; +import { statusIcon, statusBadgeVariant, formatRelativeTime } from '@/lib/execution-display-utils'; + +// ========== Execution Item ========== + +function QueueExecutionItem({ + execution, + onClick, +}: { + execution: QueueExecution; + onClick: () => void; +}) { + const { formatMessage } = useIntl(); + + const typeLabel = execution.type === 'session' + ? formatMessage({ id: 'home.terminalPanel.queueView.session' }) + : formatMessage({ id: 'home.terminalPanel.queueView.orchestrator' }); + + return ( + + ); +} + +// ========== Empty State ========== + +function QueueEmptyState() { + const { formatMessage } = useIntl(); + + return ( +
+
+ +

{formatMessage({ id: 'home.terminalPanel.queueView.emptyTitle' })}

+

{formatMessage({ id: 'home.terminalPanel.queueView.emptyDesc' })}

+
+
+ ); +} + +// ========== Main Component ========== + +export function QueueExecutionListView() { + const navigate = useNavigate(); + const executions = useQueueExecutionStore((s) => s.executions); + const setPanelView = useTerminalPanelStore((s) => s.setPanelView); + const openTerminal = useTerminalPanelStore((s) => s.openTerminal); + + // Sort: running first, then pending, then failed, then completed; within same status by startedAt desc + const sortedExecutions = useMemo(() => { + const all = Object.values(executions); + const statusOrder: Record = { + running: 0, + pending: 1, + failed: 2, + completed: 3, + }; + return all.sort((a, b) => { + const sa = statusOrder[a.status] ?? 4; + const sb = statusOrder[b.status] ?? 4; + if (sa !== sb) return sa - sb; + return new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime(); + }); + }, [executions]); + + const handleClick = (exec: QueueExecution) => { + if (exec.type === 'session' && exec.sessionKey) { + setPanelView('terminal'); + openTerminal(exec.sessionKey); + } else { + navigate(ROUTES.ORCHESTRATOR); + } + }; + + if (sortedExecutions.length === 0) { + return ; + } + + return ( +
+ {sortedExecutions.map((exec) => ( + handleClick(exec)} + /> + ))} +
+ ); +} diff --git a/ccw/frontend/src/components/terminal-panel/TerminalMainArea.tsx b/ccw/frontend/src/components/terminal-panel/TerminalMainArea.tsx index e4df5f15..a5263806 100644 --- a/ccw/frontend/src/components/terminal-panel/TerminalMainArea.tsx +++ b/ccw/frontend/src/components/terminal-panel/TerminalMainArea.tsx @@ -201,8 +201,9 @@ export function TerminalMainArea({ onClose }: TerminalMainAreaProps) { category: 'user', }, projectPath || undefined); setPrompt(''); - } catch { - // Error shown in terminal output + } catch (err) { + // Error shown in terminal output; log for DevTools debugging + console.error('[TerminalMainArea] executeInCliSession failed:', err); } finally { setIsExecuting(false); } diff --git a/ccw/frontend/src/hooks/useCliSessionCore.ts b/ccw/frontend/src/hooks/useCliSessionCore.ts index 58000db8..50fcd72a 100644 --- a/ccw/frontend/src/hooks/useCliSessionCore.ts +++ b/ccw/frontend/src/hooks/useCliSessionCore.ts @@ -22,6 +22,8 @@ export interface UseCliSessionCoreOptions { autoSelectLast?: boolean; /** Default resumeKey used when creating sessions via ensureSession/handleCreateSession. */ resumeKey?: string; + /** Shell to use when creating new sessions. Defaults to 'bash'. */ + preferredShell?: string; /** Additional createCliSession fields (cols, rows, tool, model). */ createSessionDefaults?: { cols?: number; @@ -60,6 +62,7 @@ export function useCliSessionCore(options: UseCliSessionCoreOptions = {}): UseCl const { autoSelectLast = true, resumeKey, + preferredShell = 'bash', createSessionDefaults, } = options; @@ -92,7 +95,7 @@ export function useCliSessionCore(options: UseCliSessionCoreOptions = {}): UseCl setError(null); try { const r = await fetchCliSessions(projectPath || undefined); - setSessions(r.sessions as unknown as CliSession[]); + setSessions(r.sessions); } catch (e) { setError(e instanceof Error ? e.message : String(e)); } finally { @@ -120,16 +123,16 @@ export function useCliSessionCore(options: UseCliSessionCoreOptions = {}): UseCl const created = await createCliSession( { workingDir: projectPath, - preferredShell: 'bash', + preferredShell, resumeKey, ...createSessionDefaults, }, projectPath ); - upsertSession(created.session as unknown as CliSession); + upsertSession(created.session); setSelectedSessionKey(created.session.sessionKey); return created.session.sessionKey; - }, [selectedSessionKey, projectPath, resumeKey, createSessionDefaults, upsertSession]); + }, [selectedSessionKey, projectPath, resumeKey, preferredShell, createSessionDefaults, upsertSession]); // ------- handleCreateSession ------- const handleCreateSession = useCallback(async () => { @@ -139,21 +142,21 @@ export function useCliSessionCore(options: UseCliSessionCoreOptions = {}): UseCl const created = await createCliSession( { workingDir: projectPath, - preferredShell: 'bash', + preferredShell, resumeKey, ...createSessionDefaults, }, projectPath ); - upsertSession(created.session as unknown as CliSession); + upsertSession(created.session); setSelectedSessionKey(created.session.sessionKey); // Refresh full list so store stays consistent const r = await fetchCliSessions(projectPath || undefined); - setSessions(r.sessions as unknown as CliSession[]); + setSessions(r.sessions); } catch (e) { setError(e instanceof Error ? e.message : String(e)); } - }, [projectPath, resumeKey, createSessionDefaults, upsertSession, setSessions]); + }, [projectPath, resumeKey, preferredShell, createSessionDefaults, upsertSession, setSessions]); return { sessions, diff --git a/ccw/frontend/src/lib/execution-display-utils.ts b/ccw/frontend/src/lib/execution-display-utils.ts new file mode 100644 index 00000000..43572b9e --- /dev/null +++ b/ccw/frontend/src/lib/execution-display-utils.ts @@ -0,0 +1,65 @@ +// ======================================== +// Execution Display Utilities +// ======================================== +// Shared helpers for rendering queue execution status across +// ExecutionPanel and QueueExecutionListView components. + +import type { ReactElement } from 'react'; +import { createElement } from 'react'; +import { + Loader2, + CheckCircle, + XCircle, + Clock, +} from 'lucide-react'; +import type { QueueExecutionStatus } from '@/stores/queueExecutionStore'; + +/** + * Map execution status to Badge variant. + */ +export function statusBadgeVariant(status: QueueExecutionStatus): 'info' | 'success' | 'destructive' | 'secondary' { + switch (status) { + case 'running': + return 'info'; + case 'completed': + return 'success'; + case 'failed': + return 'destructive'; + case 'pending': + default: + return 'secondary'; + } +} + +/** + * Map execution status to a small icon element. + */ +export function statusIcon(status: QueueExecutionStatus): ReactElement { + const base = 'w-3.5 h-3.5'; + switch (status) { + case 'running': + return createElement(Loader2, { className: `${base} animate-spin text-info` }); + case 'completed': + return createElement(CheckCircle, { className: `${base} text-success` }); + case 'failed': + return createElement(XCircle, { className: `${base} text-destructive` }); + case 'pending': + default: + return createElement(Clock, { className: `${base} text-muted-foreground` }); + } +} + +/** + * Format an ISO date string as a human-readable relative time. + */ +export function formatRelativeTime(isoString: string): string { + const diff = Date.now() - new Date(isoString).getTime(); + const seconds = Math.floor(diff / 1000); + if (seconds < 60) return `${seconds}s ago`; + const minutes = Math.floor(seconds / 60); + if (minutes < 60) return `${minutes}m ago`; + const hours = Math.floor(minutes / 60); + if (hours < 24) return `${hours}h ago`; + const days = Math.floor(hours / 24); + return `${days}d ago`; +} diff --git a/ccw/frontend/src/lib/queue-prompt.ts b/ccw/frontend/src/lib/queue-prompt.ts index 8ca16f82..62fd8dba 100644 --- a/ccw/frontend/src/lib/queue-prompt.ts +++ b/ccw/frontend/src/lib/queue-prompt.ts @@ -7,6 +7,34 @@ import type { QueueItem } from '@/lib/api'; +// --------------------------------------------------------------------------- +// Minimal interfaces for the issue data consumed by buildQueueItemContext. +// The backend may return solution.tasks[] which is not part of the core +// IssueSolution interface, so we define a local superset here. +// --------------------------------------------------------------------------- + +/** A lightweight task entry nested inside a solution from the backend. */ +interface SolutionTask { + id: string; + title?: string; + description?: string; +} + +/** Solution shape as consumed by the prompt builder (superset of IssueSolution). */ +interface PromptSolution { + id: string; + description?: string; + approach?: string; + tasks?: SolutionTask[]; +} + +/** Minimal issue shape consumed by the prompt builder. */ +export interface QueueItemIssue { + title?: string; + context?: string; + solutions?: PromptSolution[]; +} + /** * Build a context string for executing a queue item. * @@ -18,7 +46,7 @@ import type { QueueItem } from '@/lib/api'; */ export function buildQueueItemContext( item: QueueItem, - issue: any | undefined + issue: QueueItemIssue | undefined ): string { const lines: string[] = []; @@ -38,7 +66,7 @@ export function buildQueueItemContext( } const solution = Array.isArray(issue.solutions) - ? issue.solutions.find((s: any) => s?.id === item.solution_id) + ? issue.solutions.find((s) => s?.id === item.solution_id) : undefined; if (solution) { @@ -54,7 +82,7 @@ export function buildQueueItemContext( // Include matched task from solution.tasks when available const tasks = Array.isArray(solution.tasks) ? solution.tasks : []; const task = item.task_id - ? tasks.find((t: any) => t?.id === item.task_id) + ? tasks.find((t) => t?.id === item.task_id) : undefined; if (task) { lines.push(''); diff --git a/ccw/frontend/src/locales/en/mcp-manager.json b/ccw/frontend/src/locales/en/mcp-manager.json index 31ca569c..70f6d53c 100644 --- a/ccw/frontend/src/locales/en/mcp-manager.json +++ b/ccw/frontend/src/locales/en/mcp-manager.json @@ -153,7 +153,7 @@ "allowedDirs": "Allowed Directories", "allowedDirsPlaceholder": "dir1,dir2,dir3", "allowedDirsHint": "Comma-separated list of allowed directories", - "disableSandbox": "Disable Sandbox" + "enableSandbox": "Enable Sandbox (restrict to workspace files only)" }, "actions": { "enableAll": "Enable All", diff --git a/ccw/frontend/src/locales/zh/mcp-manager.json b/ccw/frontend/src/locales/zh/mcp-manager.json index 30518cb7..c0a0d953 100644 --- a/ccw/frontend/src/locales/zh/mcp-manager.json +++ b/ccw/frontend/src/locales/zh/mcp-manager.json @@ -153,7 +153,7 @@ "allowedDirs": "允许的目录", "allowedDirsPlaceholder": "目录1,目录2,目录3", "allowedDirsHint": "逗号分隔的允许目录列表", - "disableSandbox": "禁用沙箱" + "enableSandbox": "启用沙箱(仅允许修改工作空间下的文件)" }, "actions": { "enableAll": "全部启用", diff --git a/ccw/frontend/src/pages/McpManagerPage.tsx b/ccw/frontend/src/pages/McpManagerPage.tsx index 0f02a5d1..d9918b3a 100644 --- a/ccw/frontend/src/pages/McpManagerPage.tsx +++ b/ccw/frontend/src/pages/McpManagerPage.tsx @@ -349,7 +349,7 @@ export function McpManagerPage() { enabledTools: [], projectRoot: undefined, allowedDirs: undefined, - disableSandbox: undefined, + enableSandbox: undefined, }; const handleToggleCcwTool = async (tool: string, enabled: boolean) => { @@ -407,7 +407,7 @@ export function McpManagerPage() { enabledTools: [], projectRoot: undefined, allowedDirs: undefined, - disableSandbox: undefined, + enableSandbox: undefined, }; const handleToggleCcwToolCodex = async (tool: string, enabled: boolean) => { @@ -721,7 +721,7 @@ export function McpManagerPage() { enabledTools={ccwConfig.enabledTools} projectRoot={ccwConfig.projectRoot} allowedDirs={ccwConfig.allowedDirs} - disableSandbox={ccwConfig.disableSandbox} + enableSandbox={ccwConfig.enableSandbox} onToggleTool={handleToggleCcwTool} onUpdateConfig={handleUpdateCcwConfig} onInstall={handleCcwInstall} @@ -734,7 +734,7 @@ export function McpManagerPage() { enabledTools={ccwCodexConfig.enabledTools} projectRoot={ccwCodexConfig.projectRoot} allowedDirs={ccwCodexConfig.allowedDirs} - disableSandbox={ccwCodexConfig.disableSandbox} + enableSandbox={ccwCodexConfig.enableSandbox} onToggleTool={handleToggleCcwToolCodex} onUpdateConfig={handleUpdateCcwConfigCodex} onInstall={handleCcwInstallCodex} diff --git a/ccw/src/core/routes/mcp-routes.ts b/ccw/src/core/routes/mcp-routes.ts index 31cb0cbc..aa4d84fc 100644 --- a/ccw/src/core/routes/mcp-routes.ts +++ b/ccw/src/core/routes/mcp-routes.ts @@ -1191,8 +1191,8 @@ export async function handleMcpRoutes(ctx: RouteContext): Promise { return { error: 'projectPath is required', status: 400 }; } - // Check if sandbox should be disabled - const disableSandbox = body.disableSandbox === true; + // Check if sandbox should be enabled + const enableSandbox = body.enableSandbox === true; // Parse enabled tools from request body const enabledTools = Array.isArray(body.enabledTools) && body.enabledTools.length > 0 @@ -1207,7 +1207,7 @@ export async function handleMcpRoutes(ctx: RouteContext): Promise { args: isWin ? ["/c", "npx", "-y", "ccw-mcp"] : ["-y", "ccw-mcp"], env: { CCW_ENABLED_TOOLS: enabledTools, - ...(disableSandbox && { CCW_DISABLE_SANDBOX: "1" }) + ...(enableSandbox && { CCW_ENABLE_SANDBOX: "1" }) } }; diff --git a/ccw/src/mcp-server/index.ts b/ccw/src/mcp-server/index.ts index 331616d8..947a4ca6 100644 --- a/ccw/src/mcp-server/index.ts +++ b/ccw/src/mcp-server/index.ts @@ -12,7 +12,7 @@ import { } from '@modelcontextprotocol/sdk/types.js'; import { getAllToolSchemas, executeTool, executeToolWithProgress } from '../tools/index.js'; import type { ToolSchema, ToolResult } from '../types/tool.js'; -import { getProjectRoot, getAllowedDirectories, isSandboxDisabled } from '../utils/path-validator.js'; +import { getProjectRoot, getAllowedDirectories, isSandboxEnabled } from '../utils/path-validator.js'; const SERVER_NAME = 'ccw-tools'; const SERVER_VERSION = '6.2.0'; @@ -178,13 +178,14 @@ async function main(): Promise { // Log server start (to stderr to not interfere with stdio protocol) const projectRoot = getProjectRoot(); const allowedDirs = getAllowedDirectories(); - const sandboxDisabled = isSandboxDisabled(); + const sandboxEnabled = isSandboxEnabled(); console.error(`${SERVER_NAME} v${SERVER_VERSION} started`); console.error(`Project root: ${projectRoot}`); - if (sandboxDisabled) { - console.error(`Sandbox: DISABLED (CCW_DISABLE_SANDBOX=true)`); - } else { + if (sandboxEnabled) { + console.error(`Sandbox: ENABLED (CCW_ENABLE_SANDBOX=true)`); console.error(`Allowed directories: ${allowedDirs.join(', ')}`); + } else { + console.error(`Sandbox: DISABLED (default)`); } if (!process.env[ENV_PROJECT_ROOT]) { console.error(`[Warning] ${ENV_PROJECT_ROOT} not set, using process.cwd()`);