diff --git a/.claude/skills/workflow-tune/SKILL.md b/.claude/skills/workflow-tune/SKILL.md index f08d550a..1477e4ac 100644 --- a/.claude/skills/workflow-tune/SKILL.md +++ b/.claude/skills/workflow-tune/SKILL.md @@ -117,35 +117,42 @@ $ARGUMENTS → Parse: 2. Contains pipe "|" → Format 1 (inline commands) 3. Matches skill-name pattern → Format 2 (comma-separated skills) 4. Everything else → Format 4 (natural language → semantic decomposition) + 4a. Contains file path? → Read file as reference doc, extract workflow steps via LLM + 4b. Pure intent text → Direct intent-verb matching (intentMap) ``` ### Format 4: Semantic Decomposition (Natural Language) When input is free-text (e.g., "分析 src 目录代码质量,做代码评审,然后修复高优先级问题"), the orchestrator: +#### 4a. Reference Document Mode (input contains file path) + +When the input contains a file path (e.g., `d:\maestro2\guide\command-usage-guide.md 提取核心工作流`), the orchestrator: + +1. **Detect File Path**: Extract file path from input via path pattern matching +2. **Read Reference Doc**: Read the file content as workflow reference material +3. **Extract Workflow via LLM**: Use Gemini to analyze the document + user intent, extract executable workflow steps +4. **Step Chain Generation**: LLM returns structured step chain with commands, tools, and execution order +5. **Command Doc + Confirmation**: Same as 4b below + +#### 4b. Pure Intent Mode (no file path) + 1. **Semantic Parse**: Identify intent verbs and targets → map to available skills/commands 2. **Step Chain Generation**: Produce ordered step chain with tool/mode selection 3. **Command Doc**: Generate formatted execution plan document 4. **User Confirmation**: Display plan, ask user to confirm/edit before execution ```javascript -// Semantic decomposition uses intent-to-tool mapping +// ★ 4a: If input contains file path → read file, extract workflow via LLM +// Detect paths: Windows (D:\path\file.md), Unix (/path/file.md), relative (./file.md) +// Read file content → send to Gemini with user intent → get executable step chain +// See phases/01-setup.md Step 1.1b Mode 4a + +// ★ 4b: Pure intent text → regex-based intent-to-tool mapping const intentMap = { - // Analysis intents '分析|analyze|审查|inspect|scan': { tool: 'gemini', mode: 'analysis', rule: 'analysis-analyze-code-patterns' }, '评审|review|code review': { tool: 'gemini', mode: 'analysis', rule: 'analysis-review-code-quality' }, - '诊断|debug|排查|diagnose': { tool: 'gemini', mode: 'analysis', rule: 'analysis-diagnose-bug-root-cause' }, - '安全|security|漏洞': { tool: 'gemini', mode: 'analysis', rule: 'analysis-assess-security-risks' }, - '性能|performance|perf': { tool: 'gemini', mode: 'analysis', rule: 'analysis-analyze-performance' }, - '架构|architecture': { tool: 'gemini', mode: 'analysis', rule: 'analysis-review-architecture' }, - // Write intents - '修复|fix|repair|解决': { tool: 'claude', mode: 'write', rule: 'development-debug-runtime-issues' }, - '实现|implement|开发|create': { tool: 'claude', mode: 'write', rule: 'development-implement-feature' }, - '重构|refactor': { tool: 'claude', mode: 'write', rule: 'development-refactor-codebase' }, - '测试|test|generate test': { tool: 'claude', mode: 'write', rule: 'development-generate-tests' }, - // Planning intents - '规划|plan|设计|design': { tool: 'gemini', mode: 'analysis', rule: 'planning-plan-architecture-design' }, - '拆解|breakdown|分解': { tool: 'gemini', mode: 'analysis', rule: 'planning-breakdown-task-steps' }, + // ... (full map in phases/01-setup.md Step 1.1b Mode 4b) }; // Match input segments to intents, produce step chain @@ -377,7 +384,8 @@ User Input (workflow steps / natural language + context) ↓ Phase 1: Setup ├─ [Format 1-3] Direct parse → steps[] - ├─ [Format 4] Semantic decompose → steps[] + ├─ [Format 4a] File path detected → Read doc → LLM extract → steps[] + ├─ [Format 4b] Pure intent text → Regex intent matching → steps[] ↓ Command Document (formatted plan) ↓ diff --git a/.claude/skills/workflow-tune/phases/01-setup.md b/.claude/skills/workflow-tune/phases/01-setup.md index 4c5ce03a..a2c03a8d 100644 --- a/.claude/skills/workflow-tune/phases/01-setup.md +++ b/.claude/skills/workflow-tune/phases/01-setup.md @@ -67,6 +67,26 @@ else if (/^[\w-]+(,[\w-]+)+/.test(args.split(/\s/)[0])) { else { inputFormat = 'natural-language'; naturalLanguageInput = args.replace(/--\w+\s+"[^"]*"/g, '').replace(/--\w+\s+\S+/g, '').replace(/-y|--yes/g, '').trim(); + + // ★ 4a: Detect file paths in input (Windows absolute, Unix absolute, or relative paths) + const filePathPattern = /(?:[A-Za-z]:[\\\/][^\s,;,;、]+|\/[^\s,;,;、]+\.(?:md|txt|json|yaml|yml|toml)|\.\/?[^\s,;,;、]+\.(?:md|txt|json|yaml|yml|toml))/g; + const detectedPaths = naturalLanguageInput.match(filePathPattern) || []; + referenceDocContent = null; + referenceDocPath = null; + + if (detectedPaths.length > 0) { + // Read first detected file as reference document + referenceDocPath = detectedPaths[0]; + try { + referenceDocContent = Read(referenceDocPath); + // Remove file path from natural language input to get pure user intent + naturalLanguageInput = naturalLanguageInput.replace(referenceDocPath, '').trim(); + } catch (e) { + // File not readable — fall through to 4b (pure intent mode) + referenceDocContent = null; + } + } + // Steps will be populated in Step 1.1b steps = []; } @@ -102,10 +122,108 @@ if (!workflowContext) { > Skip this step if `inputFormat !== 'natural-language'`. -Decompose natural language input into a structured step chain by identifying intent verbs and mapping them to available tools/skills. +Two sub-modes based on whether a reference document was detected in Step 1.1: + +#### Mode 4a: Reference Document → LLM Extraction + +When `referenceDocContent` is available, use Gemini to extract executable workflow steps from the document, guided by the user's intent text. ```javascript -if (inputFormat === 'natural-language') { +if (inputFormat === 'natural-language' && referenceDocContent) { + // ★ 4a: Extract workflow steps from reference document via LLM + const extractPrompt = `PURPOSE: Extract an executable workflow step chain from the reference document below, guided by the user's intent. + +USER INTENT: ${naturalLanguageInput} +REFERENCE DOCUMENT PATH: ${referenceDocPath} + +REFERENCE DOCUMENT CONTENT: +${referenceDocContent} + +TASK: +1. Read the document and identify the workflow/process it describes (commands, steps, phases, procedures) +2. Filter by user intent — only extract the steps the user wants to test/tune +3. For each step, determine: + - The actual command to execute (shell command, CLI invocation, or skill name) + - The execution order and dependencies + - What tool to use (gemini/claude/codex/qwen) and mode (default: write) +4. Generate a step chain that can be directly executed + +IMPORTANT: +- Extract REAL executable commands from the document, not analysis tasks about the document +- The user wants to RUN these workflow steps, not analyze the document itself +- If the document describes CLI commands like "maestro init", "maestro plan", etc., those are the steps to extract +- Preserve the original command syntax from the document +- Map each command to appropriate tool/mode for ccw cli execution, OR mark as 'command' type for direct shell execution +- Default mode to "write" — almost all steps produce output artifacts (files, reports, configs), even analysis steps need write permission to save results + +EXPECTED OUTPUT (strict JSON, no markdown): +{ + "workflow_name": "", + "workflow_context": "", + "steps": [ + { + "name": "", + "type": "command|ccw-cli|skill", + "command": "", + "tool": "", + "mode": "", + "rule": "", + "original_text": "", + "expected_artifacts": [""], + "success_criteria": "" + } + ] +} + +CONSTRAINTS: Output ONLY valid JSON. Extract executable steps, NOT document analysis tasks.`; + + Bash({ + command: `ccw cli -p "${escapeForShell(extractPrompt)}" --tool gemini --mode analysis --rule universal-rigorous-style`, + run_in_background: true, + timeout: 300000 + }); + + // STOP — wait for hook callback + // After callback: parse JSON response into steps[] + + const extractOutput = /* CLI output from callback */; + const extractJsonMatch = extractOutput.match(/\{[\s\S]*\}/); + + if (extractJsonMatch) { + try { + const extracted = JSON.parse(extractJsonMatch[0]); + workflowName = extracted.workflow_name || 'doc-workflow'; + workflowContext = extracted.workflow_context || naturalLanguageInput; + steps = (extracted.steps || []).map((s, i) => ({ + name: s.name || `step-${i + 1}`, + type: s.type || 'command', + command: s.command, + tool: s.tool || null, + mode: s.mode || null, + rule: s.rule || null, + original_text: s.original_text || '', + expected_artifacts: s.expected_artifacts || [], + success_criteria: s.success_criteria || '' + })); + } catch (e) { + // JSON parse failed — fall through to 4b intent matching + referenceDocContent = null; + } + } + + if (steps.length === 0) { + // Extraction produced no steps — fall through to 4b + referenceDocContent = null; + } +} +``` + +#### Mode 4b: Pure Intent → Regex Matching + +When no reference document, or when 4a extraction failed, decompose by intent-verb matching. + +```javascript +if (inputFormat === 'natural-language' && !referenceDocContent) { // Intent-to-tool mapping (regex patterns → tool config) const intentMap = [ { pattern: /分析|analyze|审查|inspect|scan/i, name: 'analyze', tool: 'gemini', mode: 'analysis', rule: 'analysis-analyze-code-patterns' }, @@ -190,12 +308,16 @@ if (inputFormat === 'natural-language') { s.name = `${s.name}-${nameCount[s.name]}`; } }); +} - // Set workflow context from the full natural language input +// Common: set workflow context and name for Format 4 +if (inputFormat === 'natural-language') { if (!workflowContext) { workflowContext = naturalLanguageInput; } - workflowName = 'nl-workflow'; // natural language derived + if (!workflowName || workflowName === 'unnamed-workflow') { + workflowName = referenceDocPath ? 'doc-workflow' : 'nl-workflow'; + } } ``` diff --git a/ccw/frontend/src/components/dashboard/__tests__/DashboardIntegration.test.tsx b/ccw/frontend/src/components/dashboard/__tests__/DashboardIntegration.test.tsx index 33f1d5fe..f499049f 100644 --- a/ccw/frontend/src/components/dashboard/__tests__/DashboardIntegration.test.tsx +++ b/ccw/frontend/src/components/dashboard/__tests__/DashboardIntegration.test.tsx @@ -4,7 +4,7 @@ // Integration tests for HomePage data flows: stats + sessions loading concurrently import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; -import { renderWithI18n, screen, waitFor } from '@/test/i18n'; +import { renderWithI18n, waitFor } from '@/test/i18n'; import HomePage from '@/pages/HomePage'; // Mock hooks used by WorkflowTaskWidget diff --git a/package.json b/package.json index 2f2a4b97..7b7f346c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "claude-code-workflow", - "version": "7.2.10", + "version": "7.2.11", "description": "JSON-driven multi-agent development framework with intelligent CLI orchestration (Gemini/Qwen/Codex), context-first architecture, and automated workflow execution", "type": "module", "main": "ccw/dist/index.js",