From b361a8c041f220b44efd3256bcfbd256ae669d3f Mon Sep 17 00:00:00 2001 From: catlog22 Date: Wed, 28 Jan 2026 21:29:21 +0800 Subject: [PATCH] Add CLI endpoints documentation and unified script template for Bash and Python - Updated AGENTS.md to include CLI tools usage and configuration details. - Introduced a new script template for both Bash and Python, outlining usage context, calling conventions, and implementation guidelines. - Provided examples for common patterns in both Bash and Python scripts. - Established a directory convention for script organization and naming. --- .claude/CLAUDE.md | 7 +- .claude/skills/skill-generator/SKILL.md | 6 +- .../templates/autonomous-action.md | 332 +--- .../skill-generator/templates/script-bash.md | 291 --- .../templates/script-python.md | 212 --- .../templates/script-template.md | 368 ++++ .../skill-tuning/specs/tuning-strategies.md | 1560 +++-------------- .codex/AGENTS.md | 9 + 8 files changed, 648 insertions(+), 2137 deletions(-) delete mode 100644 .claude/skills/skill-generator/templates/script-bash.md delete mode 100644 .claude/skills/skill-generator/templates/script-python.md create mode 100644 .claude/skills/skill-generator/templates/script-template.md diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index 2278290f..5ce4309e 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -9,12 +9,7 @@ **Strictly follow the cli-tools.json configuration** -Available CLI endpoints are dynamically defined by the config file: -- Built-in tools and their enable/disable status -- Custom API endpoints registered via the Dashboard -- Managed through the CCW Dashboard Status page - - +Available CLI endpoints are dynamically defined by the config file ## Tool Execution - **Context Requirements**: @~/.claude/workflows/context-tools.md diff --git a/.claude/skills/skill-generator/SKILL.md b/.claude/skills/skill-generator/SKILL.md index 8b8364f9..26da1afa 100644 --- a/.claude/skills/skill-generator/SKILL.md +++ b/.claude/skills/skill-generator/SKILL.md @@ -105,8 +105,7 @@ Phase 01 → Phase 02 → Phase 03 → ... → Phase N | [templates/autonomous-action.md](templates/autonomous-action.md) | Autonomous Action 模板 | | [templates/code-analysis-action.md](templates/code-analysis-action.md) | 代码分析 Action 模板 | | [templates/llm-action.md](templates/llm-action.md) | LLM Action 模板 | -| [templates/script-bash.md](templates/script-bash.md) | Bash 脚本模板 | -| [templates/script-python.md](templates/script-python.md) | Python 脚本模板 | +| [templates/script-template.md](templates/script-template.md) | 统一脚本模板 (Bash + Python) | ### 规范文档 (按需阅读) @@ -371,8 +370,7 @@ ELSE IF execution_mode === "autonomous": | [autonomous-action.md](templates/autonomous-action.md) | Action files | Phase 3 | | [code-analysis-action.md](templates/code-analysis-action.md) | Code analysis actions | Phase 3 | | [llm-action.md](templates/llm-action.md) | LLM-powered actions | Phase 3 | -| [script-bash.md](templates/script-bash.md) | Bash scripts | Phase 3/4 | -| [script-python.md](templates/script-python.md) | Python scripts | Phase 3/4 | +| [script-template.md](templates/script-template.md) | Bash + Python scripts | Phase 3/4 | ## Output Structure diff --git a/.claude/skills/skill-generator/templates/autonomous-action.md b/.claude/skills/skill-generator/templates/autonomous-action.md index 0bb8a21c..2786b0a4 100644 --- a/.claude/skills/skill-generator/templates/autonomous-action.md +++ b/.claude/skills/skill-generator/templates/autonomous-action.md @@ -84,10 +84,42 @@ return { | `{{error_handling_table}}` | 错误处理表格 | | `{{next_actions_hints}}` | 后续动作提示 | +## 动作生命周期 + +``` +状态驱动执行流: + + state.status === 'pending' + ↓ + ┌─ Init ─┐ ← 1次执行,环境准备 + │ 创建工作目录 │ + │ 初始化 context │ + │ status → running │ + └────┬────┘ + ↓ + ┌─ CRUD Loop ─┐ ← N次迭代,核心业务 + │ 编排器选择动作 │ List / Create / Edit / Delete + │ execute(state) │ 共享模式: 收集输入 → 操作 context.items → 返回更新 + │ 更新 state │ + └────┬────┘ + ↓ + ┌─ Complete ─┐ ← 1次执行,保存结果 + │ 序列化输出 │ + │ status → completed │ + └──────────┘ + +共享状态结构: + state.status → 'pending' | 'running' | 'completed' + state.context.items → 业务数据数组 + state.completed_actions → 已执行动作 ID 列表 +``` + ## 动作类型模板 ### 1. 初始化动作 (Init) +**触发条件**: `state.status === 'pending'`,仅执行一次 + ```markdown # Action: Initialize @@ -105,101 +137,29 @@ return { \`\`\`javascript async function execute(state) { - // 1. 创建工作目录 Bash(\`mkdir -p "\${workDir}"\`); - - // 2. 初始化数据 - const initialData = { - items: [], - metadata: {} - }; - - // 3. 返回状态更新 + return { stateUpdates: { status: 'running', - context: initialData + started_at: new Date().toISOString(), + context: { items: [], metadata: {} } } }; } \`\`\` -## State Updates - -\`\`\`javascript -return { - stateUpdates: { - status: 'running', - started_at: new Date().toISOString(), - context: { /* 初始数据 */ } - } -}; -\`\`\` - ## Next Actions -- 成功: 进入主处理循环 +- 成功: 进入主处理循环 (由编排器选择首个 CRUD 动作) - 失败: action-abort ``` -### 2. 列表动作 (List) +### 2. CRUD 动作 (List / Create / Edit / Delete) -```markdown -# Action: List Items +**触发条件**: `state.status === 'running'`,循环执行直至用户退出 -显示当前项目列表。 - -## Purpose - -展示所有项目供用户查看和选择。 - -## Preconditions - -- [ ] state.status === 'running' - -## Execution - -\`\`\`javascript -async function execute(state) { - const items = state.context.items || []; - - if (items.length === 0) { - console.log('暂无项目'); - } else { - console.log('项目列表:'); - items.forEach((item, i) => { - console.log(\`\${i + 1}. \${item.name} - \${item.status}\`); - }); - } - - return { - stateUpdates: { - last_action: 'list', - current_view: 'list' - } - }; -} -\`\`\` - -## State Updates - -\`\`\`javascript -return { - stateUpdates: { - current_view: 'list', - last_viewed_at: new Date().toISOString() - } -}; -\`\`\` - -## Next Actions - -- 用户选择创建: action-create -- 用户选择编辑: action-edit -- 用户退出: action-complete -``` - -### 3. 创建动作 (Create) +> 以 Create 为示例展示共享模式。List / Edit / Delete 遵循同一结构,仅 `执行逻辑` 和 `状态更新字段` 不同。 ```markdown # Action: Create Item @@ -208,7 +168,7 @@ return { ## Purpose -引导用户创建新项目。 +收集用户输入,向 context.items 追加新记录。 ## Preconditions @@ -218,26 +178,24 @@ return { \`\`\`javascript async function execute(state) { - // 1. 收集信息 + // 1. 收集输入 const input = await AskUserQuestion({ questions: [{ question: "请输入项目名称:", header: "名称", multiSelect: false, - options: [ - { label: "手动输入", description: "输入自定义名称" } - ] + options: [{ label: "手动输入", description: "输入自定义名称" }] }] }); - - // 2. 创建项目 + + // 2. 操作 context.items (核心逻辑因动作类型而异) const newItem = { id: Date.now().toString(), name: input["名称"], status: 'pending', created_at: new Date().toISOString() }; - + // 3. 返回状态更新 return { stateUpdates: { @@ -245,177 +203,30 @@ async function execute(state) { ...state.context, items: [...(state.context.items || []), newItem] }, - last_created_id: newItem.id + last_action: 'create' } }; } \`\`\` -## State Updates - -\`\`\`javascript -return { - stateUpdates: { - 'context.items': [...items, newItem], - last_action: 'create', - last_created_id: newItem.id - } -}; -\`\`\` - ## Next Actions -- 继续创建: action-create -- 返回列表: action-list +- 继续操作: 编排器根据 state 选择下一动作 +- 用户退出: action-complete ``` -### 4. 编辑动作 (Edit) +**其他 CRUD 动作差异对照:** -```markdown -# Action: Edit Item +| 动作 | 核心逻辑 | 额外前置条件 | 关键状态字段 | +|------|---------|------------|------------| +| List | `items.forEach(→ console.log)` | 无 | `current_view: 'list'` | +| Create | `items.push(newItem)` | 无 | `last_created_id` | +| Edit | `items.map(→ 替换匹配项)` | `selected_item_id !== null` | `updated_at` | +| Delete | `items.filter(→ 排除匹配项)` | `selected_item_id !== null` | 确认对话 → 执行 | -编辑现有项目。 +### 3. 完成动作 (Complete) -## Purpose - -修改已存在的项目。 - -## Preconditions - -- [ ] state.status === 'running' -- [ ] state.selected_item_id !== null - -## Execution - -\`\`\`javascript -async function execute(state) { - const itemId = state.selected_item_id; - const items = state.context.items || []; - const item = items.find(i => i.id === itemId); - - if (!item) { - throw new Error(\`Item not found: \${itemId}\`); - } - - // 1. 显示当前值 - console.log(\`当前名称: \${item.name}\`); - - // 2. 收集新值 - const input = await AskUserQuestion({ - questions: [{ - question: "请输入新名称(留空保持不变):", - header: "新名称", - multiSelect: false, - options: [ - { label: "保持不变", description: \`当前: \${item.name}\` }, - { label: "手动输入", description: "输入新名称" } - ] - }] - }); - - // 3. 更新项目 - const updatedItems = items.map(i => - i.id === itemId - ? { ...i, name: input["新名称"] || i.name, updated_at: new Date().toISOString() } - : i - ); - - return { - stateUpdates: { - context: { ...state.context, items: updatedItems }, - selected_item_id: null - } - }; -} -\`\`\` - -## State Updates - -\`\`\`javascript -return { - stateUpdates: { - 'context.items': updatedItems, - selected_item_id: null, - last_action: 'edit' - } -}; -\`\`\` - -## Next Actions - -- 返回列表: action-list -``` - -### 5. 删除动作 (Delete) - -```markdown -# Action: Delete Item - -删除项目。 - -## Purpose - -从列表中移除项目。 - -## Preconditions - -- [ ] state.status === 'running' -- [ ] state.selected_item_id !== null - -## Execution - -\`\`\`javascript -async function execute(state) { - const itemId = state.selected_item_id; - const items = state.context.items || []; - - // 1. 确认删除 - const confirm = await AskUserQuestion({ - questions: [{ - question: "确认删除此项目?", - header: "确认", - multiSelect: false, - options: [ - { label: "确认删除", description: "不可恢复" }, - { label: "取消", description: "返回列表" } - ] - }] - }); - - if (confirm["确认"] === "取消") { - return { stateUpdates: { selected_item_id: null } }; - } - - // 2. 执行删除 - const updatedItems = items.filter(i => i.id !== itemId); - - return { - stateUpdates: { - context: { ...state.context, items: updatedItems }, - selected_item_id: null - } - }; -} -\`\`\` - -## State Updates - -\`\`\`javascript -return { - stateUpdates: { - 'context.items': filteredItems, - selected_item_id: null, - last_action: 'delete' - } -}; -\`\`\` - -## Next Actions - -- 返回列表: action-list -``` - -### 6. 完成动作 (Complete) +**触发条件**: 用户明确退出或终止条件满足,仅执行一次 ```markdown # Action: Complete @@ -424,7 +235,7 @@ return { ## Purpose -保存最终状态,结束 Skill 执行。 +序列化最终状态,结束 Skill 执行。 ## Preconditions @@ -434,41 +245,26 @@ return { \`\`\`javascript async function execute(state) { - // 1. 保存最终数据 Write(\`\${workDir}/final-output.json\`, JSON.stringify(state.context, null, 2)); - - // 2. 生成摘要 + const summary = { total_items: state.context.items?.length || 0, duration: Date.now() - new Date(state.started_at).getTime(), actions_executed: state.completed_actions.length }; - - console.log('任务完成!'); - console.log(\`处理项目: \${summary.total_items}\`); - console.log(\`执行动作: \${summary.actions_executed}\`); - + + console.log(\`任务完成: \${summary.total_items} 项, \${summary.actions_executed} 次操作\`); + return { stateUpdates: { status: 'completed', - summary: summary + completed_at: new Date().toISOString(), + summary } }; } \`\`\` -## State Updates - -\`\`\`javascript -return { - stateUpdates: { - status: 'completed', - completed_at: new Date().toISOString(), - summary: { /* 统计信息 */ } - } -}; -\`\`\` - ## Next Actions - 无(终止状态) diff --git a/.claude/skills/skill-generator/templates/script-bash.md b/.claude/skills/skill-generator/templates/script-bash.md deleted file mode 100644 index 8d4108e1..00000000 --- a/.claude/skills/skill-generator/templates/script-bash.md +++ /dev/null @@ -1,291 +0,0 @@ -# Bash Script Template - -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 -#!/bin/bash -# {{script_description}} - -set -euo pipefail - -# ============================================================ -# 参数解析 -# ============================================================ - -INPUT_PATH="" -OUTPUT_DIR="" # 由调用方指定,不设默认值 - -show_help() { - echo "用法: $0 --input-path --output-dir " - echo "" - echo "参数:" - echo " --input-path 输入文件路径 (必需)" - echo " --output-dir 输出目录 (必需,由调用方指定)" - echo " --help 显示帮助信息" -} - -while [[ "$#" -gt 0 ]]; do - case $1 in - --input-path) - INPUT_PATH="$2" - shift - ;; - --output-dir) - OUTPUT_DIR="$2" - shift - ;; - --help) - show_help - exit 0 - ;; - *) - echo "错误: 未知参数 $1" >&2 - show_help >&2 - exit 1 - ;; - esac - shift -done - -# ============================================================ -# 参数验证 -# ============================================================ - -if [[ -z "$INPUT_PATH" ]]; then - echo "错误: --input-path 是必需参数" >&2 - exit 1 -fi - -if [[ -z "$OUTPUT_DIR" ]]; then - echo "错误: --output-dir 是必需参数" >&2 - exit 1 -fi - -if [[ ! -f "$INPUT_PATH" ]]; then - echo "错误: 输入文件不存在: $INPUT_PATH" >&2 - exit 1 -fi - -# 检查 jq 是否可用(用于 JSON 输出) -if ! command -v jq &> /dev/null; then - echo "错误: 需要安装 jq" >&2 - exit 1 -fi - -mkdir -p "$OUTPUT_DIR" - -# ============================================================ -# 核心逻辑 -# ============================================================ - -OUTPUT_FILE="$OUTPUT_DIR/result.txt" -ITEMS_COUNT=0 - -# TODO: 实现处理逻辑 -# 示例:处理输入文件 -while IFS= read -r line; do - echo "$line" >> "$OUTPUT_FILE" - ((ITEMS_COUNT++)) -done < "$INPUT_PATH" - -# ============================================================ -# 输出 JSON 结果(使用 jq 构建,避免特殊字符问题) -# ============================================================ - -jq -n \ - --arg output_file "$OUTPUT_FILE" \ - --argjson items_processed "$ITEMS_COUNT" \ - '{output_file: $output_file, items_processed: $items_processed, status: "success"}' -``` - -## 变量说明 - -| 变量 | 说明 | -|------|------| -| `{{script_description}}` | 脚本功能描述 | - -## 使用规范 - -### 脚本头部 - -```bash -#!/bin/bash -set -euo pipefail # 严格模式:出错退出、未定义变量报错、管道错误传递 -``` - -### 参数解析模式 - -```bash -while [[ "$#" -gt 0 ]]; do - case $1 in - --param-name) - PARAM_VAR="$2" - shift - ;; - --flag) - FLAG_VAR=true - ;; - *) - echo "Unknown: $1" >&2 - exit 1 - ;; - esac - shift -done -``` - -### 输出格式 - -- 最后一行打印单行 JSON -- **强烈推荐使用 `jq`**:自动处理转义和类型 - -```bash -# 推荐:使用 jq 构建(安全、可靠) -jq -n \ - --arg file "$FILE" \ - --argjson count "$COUNT" \ - '{output_file: $file, items_processed: $count}' - -# 备选:简单场景手动拼接(注意特殊字符转义) -echo "{\"file\": \"$FILE\", \"count\": $COUNT}" -``` - -**jq 参数类型**: -- `--arg name value`:字符串类型 -- `--argjson name value`:数字/布尔/null 类型 - -### 错误处理 - -```bash -# 验证错误 -if [[ -z "$PARAM" ]]; then - echo "错误: 参数不能为空" >&2 - exit 1 -fi - -# 命令错误 -if ! command -v jq &> /dev/null; then - echo "错误: 需要安装 jq" >&2 - exit 1 -fi - -# 运行时错误 -if ! some_command; then - echo "错误: 命令执行失败" >&2 - exit 1 -fi -``` - -## 常用模式 - -### 文件遍历 - -```bash -for file in "$INPUT_DIR"/*.json; do - [[ -f "$file" ]] || continue - echo "处理: $file" - # 处理逻辑... -done -``` - -### 临时文件 - -```bash -TEMP_FILE=$(mktemp) -trap "rm -f $TEMP_FILE" EXIT - -echo "data" > "$TEMP_FILE" -``` - -### 调用其他工具 - -```bash -# 检查工具存在 -require_command() { - if ! command -v "$1" &> /dev/null; then - echo "错误: 需要 $1" >&2 - exit 1 - fi -} - -require_command jq -require_command curl -``` - -### JSON 处理(使用 jq) - -```bash -# 读取 JSON 字段 -VALUE=$(jq -r '.field' "$INPUT_PATH") - -# 修改 JSON -jq '.field = "new_value"' "$INPUT_PATH" > "$OUTPUT_FILE" - -# 合并 JSON 文件 -jq -s 'add' file1.json file2.json > merged.json -``` - -## 生成函数 - -```javascript -function generateBashScript(scriptConfig) { - return `#!/bin/bash -# ${scriptConfig.description} - -set -euo pipefail - -# 参数定义 -${scriptConfig.inputs.map(i => - `${i.name.toUpperCase().replace(/-/g, '_')}="${i.default || ''}"` -).join('\n')} - -# 参数解析 -while [[ "$#" -gt 0 ]]; do - case $1 in -${scriptConfig.inputs.map(i => - ` --${i.name}) - ${i.name.toUpperCase().replace(/-/g, '_')}="$2" - shift - ;;` -).join('\n')} - *) - echo "未知参数: $1" >&2 - exit 1 - ;; - esac - shift -done - -# 参数验证 -${scriptConfig.inputs.filter(i => i.required).map(i => - `if [[ -z "$${i.name.toUpperCase().replace(/-/g, '_')}" ]]; then - echo "错误: --${i.name} 是必需参数" >&2 - exit 1 -fi` -).join('\n\n')} - -# TODO: 实现处理逻辑 - -# 输出结果 -echo "{${scriptConfig.outputs.map(o => - `\\"${o.name}\\": \\"\\$${o.name.toUpperCase().replace(/-/g, '_')}\\"` -).join(', ')}}" -`; -} -``` diff --git a/.claude/skills/skill-generator/templates/script-python.md b/.claude/skills/skill-generator/templates/script-python.md deleted file mode 100644 index 8584439c..00000000 --- a/.claude/skills/skill-generator/templates/script-python.md +++ /dev/null @@ -1,212 +0,0 @@ -# Python Script Template - -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 -#!/usr/bin/env python3 -""" -{{script_description}} -""" - -import argparse -import json -import sys -from pathlib import Path - - -def main(): - # 1. 定义参数 - parser = argparse.ArgumentParser(description='{{script_description}}') - parser.add_argument('--input-path', type=str, required=True, - help='输入文件路径') - parser.add_argument('--output-dir', type=str, required=True, - help='输出目录(由调用方指定)') - # 添加更多参数... - - args = parser.parse_args() - - # 2. 验证输入 - input_path = Path(args.input_path) - if not input_path.exists(): - print(f"错误: 输入文件不存在: {input_path}", file=sys.stderr) - sys.exit(1) - - output_dir = Path(args.output_dir) - output_dir.mkdir(parents=True, exist_ok=True) - - # 3. 执行核心逻辑 - try: - result = process(input_path, output_dir) - except Exception as e: - print(f"错误: {e}", file=sys.stderr) - sys.exit(1) - - # 4. 输出 JSON 结果 - print(json.dumps(result)) - - -def process(input_path: Path, output_dir: Path) -> dict: - """ - 核心处理逻辑 - - Args: - input_path: 输入文件路径 - output_dir: 输出目录 - - Returns: - dict: 包含输出结果的字典 - """ - # TODO: 实现处理逻辑 - - output_file = output_dir / 'result.json' - - # 示例:读取并处理数据 - with open(input_path, 'r', encoding='utf-8') as f: - data = json.load(f) - - # 处理数据... - processed_count = len(data) if isinstance(data, list) else 1 - - # 写入输出 - with open(output_file, 'w', encoding='utf-8') as f: - json.dump(data, f, indent=2, ensure_ascii=False) - - return { - 'output_file': str(output_file), - 'items_processed': processed_count, - 'status': 'success' - } - - -if __name__ == '__main__': - main() -``` - -## 变量说明 - -| 变量 | 说明 | -|------|------| -| `{{script_description}}` | 脚本功能描述 | - -## 使用规范 - -### 输入参数 - -- 使用 `argparse` 定义参数 -- 参数名使用 kebab-case:`--input-path` -- 必需参数设置 `required=True` -- 可选参数提供 `default` 值 - -### 输出格式 - -- 最后一行打印单行 JSON -- 包含所有输出文件路径和关键数据 -- 错误信息输出到 stderr - -### 错误处理 - -```python -# 验证错误 - 直接退出 -if not valid: - print("错误信息", file=sys.stderr) - sys.exit(1) - -# 运行时错误 - 捕获并退出 -try: - result = process() -except Exception as e: - print(f"错误: {e}", file=sys.stderr) - sys.exit(1) -``` - -## 常用模式 - -### 文件处理 - -```python -def process_files(input_dir: Path, pattern: str = '*.json') -> list: - results = [] - for file in input_dir.glob(pattern): - with open(file, 'r') as f: - data = json.load(f) - results.append({'file': str(file), 'data': data}) - return results -``` - -### 数据转换 - -```python -def transform_data(data: dict) -> dict: - return { - 'id': data.get('id'), - 'name': data.get('name', '').strip(), - 'timestamp': datetime.now().isoformat() - } -``` - -### 调用外部命令 - -```python -import subprocess - -def run_command(cmd: list) -> str: - result = subprocess.run(cmd, capture_output=True, text=True) - if result.returncode != 0: - raise RuntimeError(result.stderr) - return result.stdout -``` - -## 生成函数 - -```javascript -function generatePythonScript(scriptConfig) { - return `#!/usr/bin/env python3 -""" -${scriptConfig.description} -""" - -import argparse -import json -import sys -from pathlib import Path - - -def main(): - parser = argparse.ArgumentParser(description='${scriptConfig.description}') -${scriptConfig.inputs.map(i => - ` parser.add_argument('--${i.name}', type=${i.type || 'str'}, ${i.required ? 'required=True' : `default='${i.default}'`}, - help='${i.description}')` -).join('\n')} - args = parser.parse_args() - - # TODO: 实现处理逻辑 - result = { -${scriptConfig.outputs.map(o => - ` '${o.name}': None # ${o.description}` -).join(',\n')} - } - - print(json.dumps(result)) - - -if __name__ == '__main__': - main() -`; -} -``` diff --git a/.claude/skills/skill-generator/templates/script-template.md b/.claude/skills/skill-generator/templates/script-template.md new file mode 100644 index 00000000..10d0e385 --- /dev/null +++ b/.claude/skills/skill-generator/templates/script-template.md @@ -0,0 +1,368 @@ +# Script Template + +统一的脚本模板,覆盖 Bash 和 Python 两种运行时。 + +## Usage Context + +| Phase | Usage | +|-------|-------| +| Optional | Phase/Action 中声明 `## Scripts` 时使用 | +| Execution | 通过 `ExecuteScript('script-id', params)` 调用 | +| Output Location | `.claude/skills/{skill-name}/scripts/{script-id}.{ext}` | + +--- + +## 调用接口规范 + +所有脚本共享相同的调用约定: + +``` +调用者 + ↓ ExecuteScript('script-id', { key: value }) + ↓ +脚本入口 + ├─ 参数解析 (--key value) + ├─ 输入验证 (必需参数检查, 文件存在) + ├─ 核心处理 (数据读取 → 转换 → 写入) + └─ 输出结果 (最后一行: 单行 JSON → stdout) + ├─ 成功: {"status":"success", "output_file":"...", ...} + └─ 失败: stderr 输出错误信息, exit 1 +``` + +### 返回格式 + +```typescript +interface ScriptResult { + success: boolean; // exit code === 0 + stdout: string; // 标准输出 + stderr: string; // 标准错误 + outputs: object; // 从 stdout 最后一行解析的 JSON +} +``` + +### 参数约定 + +| 参数 | 必需 | 说明 | +|------|------|------| +| `--input-path` | ✓ | 输入文件路径 | +| `--output-dir` | ✓ | 输出目录(由调用方指定) | +| 其他 | 按需 | 脚本特定参数 | + +--- + +## Bash 实现 + +```bash +#!/bin/bash +# {{script_description}} + +set -euo pipefail + +# ============================================================ +# 参数解析 +# ============================================================ + +INPUT_PATH="" +OUTPUT_DIR="" + +while [[ "$#" -gt 0 ]]; do + case $1 in + --input-path) INPUT_PATH="$2"; shift ;; + --output-dir) OUTPUT_DIR="$2"; shift ;; + --help) + echo "用法: $0 --input-path --output-dir " + exit 0 + ;; + *) + echo "错误: 未知参数 $1" >&2 + exit 1 + ;; + esac + shift +done + +# ============================================================ +# 参数验证 +# ============================================================ + +[[ -z "$INPUT_PATH" ]] && { echo "错误: --input-path 是必需参数" >&2; exit 1; } +[[ -z "$OUTPUT_DIR" ]] && { echo "错误: --output-dir 是必需参数" >&2; exit 1; } +[[ ! -f "$INPUT_PATH" ]] && { echo "错误: 输入文件不存在: $INPUT_PATH" >&2; exit 1; } +command -v jq &> /dev/null || { echo "错误: 需要安装 jq" >&2; exit 1; } + +mkdir -p "$OUTPUT_DIR" + +# ============================================================ +# 核心逻辑 +# ============================================================ + +OUTPUT_FILE="$OUTPUT_DIR/result.txt" +ITEMS_COUNT=0 + +# TODO: 实现处理逻辑 +while IFS= read -r line; do + echo "$line" >> "$OUTPUT_FILE" + ((ITEMS_COUNT++)) +done < "$INPUT_PATH" + +# ============================================================ +# 输出 JSON 结果(使用 jq 构建,避免转义问题) +# ============================================================ + +jq -n \ + --arg output_file "$OUTPUT_FILE" \ + --argjson items_processed "$ITEMS_COUNT" \ + '{output_file: $output_file, items_processed: $items_processed, status: "success"}' +``` + +### Bash 常用模式 + +```bash +# 文件遍历 +for file in "$INPUT_DIR"/*.json; do + [[ -f "$file" ]] || continue + # 处理逻辑... +done + +# 临时文件 (自动清理) +TEMP_FILE=$(mktemp) +trap "rm -f $TEMP_FILE" EXIT + +# 工具依赖检查 +require_command() { + command -v "$1" &> /dev/null || { echo "错误: 需要 $1" >&2; exit 1; } +} +require_command jq + +# jq 处理 +VALUE=$(jq -r '.field' "$INPUT_PATH") # 读取字段 +jq '.field = "new"' input.json > output.json # 修改字段 +jq -s 'add' file1.json file2.json > merged.json # 合并文件 +``` + +--- + +## Python 实现 + +```python +#!/usr/bin/env python3 +""" +{{script_description}} +""" + +import argparse +import json +import sys +from pathlib import Path + + +def main(): + parser = argparse.ArgumentParser(description='{{script_description}}') + parser.add_argument('--input-path', type=str, required=True, help='输入文件路径') + parser.add_argument('--output-dir', type=str, required=True, help='输出目录') + args = parser.parse_args() + + # 验证输入 + input_path = Path(args.input_path) + if not input_path.exists(): + print(f"错误: 输入文件不存在: {input_path}", file=sys.stderr) + sys.exit(1) + + output_dir = Path(args.output_dir) + output_dir.mkdir(parents=True, exist_ok=True) + + # 执行处理 + try: + result = process(input_path, output_dir) + except Exception as e: + print(f"错误: {e}", file=sys.stderr) + sys.exit(1) + + # 输出 JSON 结果 + print(json.dumps(result)) + + +def process(input_path: Path, output_dir: Path) -> dict: + """核心处理逻辑""" + # TODO: 实现处理逻辑 + + output_file = output_dir / 'result.json' + + with open(input_path, 'r', encoding='utf-8') as f: + data = json.load(f) + + processed_count = len(data) if isinstance(data, list) else 1 + + with open(output_file, 'w', encoding='utf-8') as f: + json.dump(data, f, indent=2, ensure_ascii=False) + + return { + 'output_file': str(output_file), + 'items_processed': processed_count, + 'status': 'success' + } + + +if __name__ == '__main__': + main() +``` + +### Python 常用模式 + +```python +# 文件遍历 +def process_files(input_dir: Path, pattern: str = '*.json') -> list: + return [ + {'file': str(f), 'data': json.load(f.open())} + for f in input_dir.glob(pattern) + ] + +# 数据转换 +def transform(data: dict) -> dict: + return { + 'id': data.get('id'), + 'name': data.get('name', '').strip(), + 'timestamp': datetime.now().isoformat() + } + +# 外部命令调用 +import subprocess + +def run_command(cmd: list) -> str: + result = subprocess.run(cmd, capture_output=True, text=True) + if result.returncode != 0: + raise RuntimeError(result.stderr) + return result.stdout +``` + +--- + +## 运行时选择指南 + +``` +任务特征 + ↓ + ├─ 文件处理 / 系统命令 / 管道操作 + │ └─ 选 Bash (.sh) + │ + ├─ JSON 数据处理 / 复杂转换 / 数据分析 + │ └─ 选 Python (.py) + │ + └─ 简单读写 / 格式转换 + └─ 任选(Bash 更轻量) +``` + +--- + +## 生成函数 + +```javascript +function generateScript(scriptConfig) { + const runtime = scriptConfig.runtime || 'bash'; // 'bash' | 'python' + const ext = runtime === 'python' ? '.py' : '.sh'; + + if (runtime === 'python') { + return generatePythonScript(scriptConfig); + } + return generateBashScript(scriptConfig); +} + +function generateBashScript(scriptConfig) { + const { description, inputs = [], outputs = [] } = scriptConfig; + + const paramDefs = inputs.map(i => + `${i.name.toUpperCase().replace(/-/g, '_')}="${i.default || ''}"` + ).join('\n'); + + const paramParse = inputs.map(i => + ` --${i.name}) ${i.name.toUpperCase().replace(/-/g, '_')}="$2"; shift ;;` + ).join('\n'); + + const paramValidation = inputs.filter(i => i.required).map(i => { + const VAR = i.name.toUpperCase().replace(/-/g, '_'); + return `[[ -z "$${VAR}" ]] && { echo "错误: --${i.name} 是必需参数" >&2; exit 1; }`; + }).join('\n'); + + return `#!/bin/bash +# ${description} + +set -euo pipefail + +${paramDefs} + +while [[ "$#" -gt 0 ]]; do + case $1 in +${paramParse} + *) echo "未知参数: $1" >&2; exit 1 ;; + esac + shift +done + +${paramValidation} + +# TODO: 实现处理逻辑 + +# 输出结果 (jq 构建) +jq -n ${outputs.map(o => + `--arg ${o.name} "$${o.name.toUpperCase().replace(/-/g, '_')}"` +).join(' \\\n ')} \ + '{${outputs.map(o => `${o.name}: $${o.name}`).join(', ')}}' +`; +} + +function generatePythonScript(scriptConfig) { + const { description, inputs = [], outputs = [] } = scriptConfig; + + const argDefs = inputs.map(i => + ` parser.add_argument('--${i.name}', type=${i.type || 'str'}, ${ + i.required ? 'required=True' : `default='${i.default || ''}'` + }, help='${i.description || i.name}')` + ).join('\n'); + + const resultFields = outputs.map(o => + ` '${o.name}': None # ${o.description || o.name}` + ).join(',\n'); + + return `#!/usr/bin/env python3 +""" +${description} +""" + +import argparse +import json +import sys +from pathlib import Path + + +def main(): + parser = argparse.ArgumentParser(description='${description}') +${argDefs} + args = parser.parse_args() + + # TODO: 实现处理逻辑 + result = { +${resultFields} + } + + print(json.dumps(result)) + + +if __name__ == '__main__': + main() +`; +} +``` + +--- + +## 目录约定 + +``` +scripts/ +├── process-data.py # id: process-data, runtime: python +├── validate.sh # id: validate, runtime: bash +└── transform.js # id: transform, runtime: node +``` + +- **命名即 ID**: 文件名(不含扩展名)= 脚本 ID +- **扩展名即运行时**: `.py` → python, `.sh` → bash, `.js` → node diff --git a/.claude/skills/skill-tuning/specs/tuning-strategies.md b/.claude/skills/skill-tuning/specs/tuning-strategies.md index 18dacf5f..490e94c6 100644 --- a/.claude/skills/skill-tuning/specs/tuning-strategies.md +++ b/.claude/skills/skill-tuning/specs/tuning-strategies.md @@ -1,295 +1,160 @@ # Tuning Strategies -Detailed fix strategies for each problem category with implementation guidance. +Fix strategies for each problem category. Implementation patterns + verification methods. -## When to Use +## Usage Context -| Phase | Usage | Section | -|-------|-------|---------| -| action-propose-fixes | Strategy selection | Strategy Details | -| action-apply-fix | Implementation guidance | Implementation | -| action-verify | Verification steps | Verification | +| Phase | Usage | +|-------|-------| +| action-propose-fixes | Strategy selection + implementation guidance | +| action-apply-fix | Apply implementation pattern | +| action-verify | Run verification method | --- -## Authoring Principles Strategies (P0 - 首要准则) +## Selection Decision Tree -> **核心原则**:简洁高效 → 去除无关存储 → 去除中间存储 → 上下文流转 +``` +Context Explosion? +├── history grows unbounded? → sliding_window +├── full content in prompts? → path_reference +├── no summarization? → context_summarization +└── text-based context? → structured_state -### Strategy: eliminate_intermediate_files +Long-tail Forgetting? +├── constraints not in phases? → constraint_injection +├── no requirements in state? → state_constraints_field +├── no recovery points? → checkpoint_restore +└── goal drift risk? → goal_embedding -**Purpose**: 删除所有中间文件,改用上下文流转。 +Data Flow? +├── multiple state files? → state_centralization +├── no validation? → schema_enforcement +└── inconsistent names? → field_normalization -**Implementation**: -```javascript -// Before: 中间文件 -async function process() { - const step1 = await analyze(); - Write(`${workDir}/step1.json`, JSON.stringify(step1)); +Agent Coordination? +├── no error handling? → error_wrapping +├── no result validation? → result_validation +└── nested agent calls? → flatten_nesting - const step1Data = JSON.parse(Read(`${workDir}/step1.json`)); - const step2 = await transform(step1Data); - Write(`${workDir}/step2.json`, JSON.stringify(step2)); +Authoring Violation? +├── intermediate files? → eliminate_intermediate_files +├── state bloat (>15 fields)? → minimize_state +├── write→read relay? → context_passing +└── duplicate storage? → deduplicate_storage - const step2Data = JSON.parse(Read(`${workDir}/step2.json`)); - return finalize(step2Data); -} +Token Consumption? +├── verbose prompts? → prompt_compression +├── full content passing? → lazy_loading +├── verbose output? → output_minimization +├── bloated state? → state_field_reduction +└── multiple output files? → in_memory_consolidation -// After: 上下文流转 -async function process() { - const step1 = await analyze(); - const step2 = await transform(step1); // 直接传递 - return finalize(step2); // 只返回最终结果 -} +Documentation? +├── repeated definitions? → consolidate_to_ssot +├── hardcoded configs? → centralize_mapping_config +└── conflicting values? → reconcile_conflicting_definitions ``` -**Risk**: Low -**Verification**: `ls ${workDir}` 无 temp/intermediate 文件 - --- -### Strategy: minimize_state +## Authoring Principles Strategies (P0) -**Purpose**: 精简 State schema 至必要字段。 +> **Core Principle**: Simplicity → Remove intermediate files → Context passing + +### eliminate_intermediate_files + +```javascript +// Before: File relay between steps +const step1 = await analyze(); +Write(`${workDir}/step1.json`, JSON.stringify(step1)); +const step1Data = JSON.parse(Read(`${workDir}/step1.json`)); +const step2 = await transform(step1Data); + +// After: Direct context passing +const step1 = await analyze(); +const step2 = await transform(step1); // No file +return finalize(step2); // Only final result persisted +``` + +**Verification**: `ls ${workDir}` — no temp/intermediate files + +### minimize_state + +**Rules**: ≤15 fields, delete `debug_*`, `*_cache`, `*_temp`, apply sliding window to `*_history`. -**Implementation**: ```typescript -// Before: 膨胀的 State -interface State { - status: string; - target: TargetInfo; - user_input: string; - parsed_input: ParsedInput; // 删除 - 只在处理时用 - intermediate_result: any; // 删除 - 中间结果 - debug_info: DebugInfo; // 删除 - 调试信息 - analysis_cache: any; // 删除 - 缓存 - full_history: HistoryEntry[]; // 删除 - 无限增长 - step1_output: any; // 删除 - 中间输出 - step2_output: any; // 删除 - 中间输出 - final_result: FinalResult; -} +// Before: Bloated +interface State { status; target; user_input; parsed_input; intermediate_result; debug_info; analysis_cache; full_history; step1_output; step2_output; final_result; ... } -// After: 精简的 State +// After: Minimal interface State { - status: 'pending' | 'running' | 'completed' | 'failed'; + status: 'pending'|'running'|'completed'|'failed'; target: { name: string; path: string }; - result_path: string; // 最终结果路径 - error?: string; // 仅失败时有 + result_path: string; + error?: string; } ``` -**Rules**: -- State 字段 ≤ 15 个 -- 删除所有 `debug_*`, `*_cache`, `*_temp` 字段 -- `*_history` 数组设置上限或改用滚动窗口 +### context_passing -**Risk**: Medium (需确保不丢失必要数据) -**Verification**: Count state fields ≤ 15 - ---- - -### Strategy: context_passing - -**Purpose**: 用函数参数/返回值代替文件中转。 - -**Implementation**: ```javascript -// 上下文流转模式 async function executeWorkflow(initialContext) { let ctx = initialContext; - - // Phase 1: 直接传递上下文 - ctx = await executePhase1(ctx); - - // Phase 2: 继续传递 - ctx = await executePhase2(ctx); - - // Phase 3: 最终处理 + ctx = await executePhase1(ctx); // Pass context directly + ctx = await executePhase2(ctx); // Continue passing const result = await executePhase3(ctx); - - // 只存最终结果 - Write(`${ctx.workDir}/result.json`, JSON.stringify(result)); - + Write(`${ctx.workDir}/result.json`, JSON.stringify(result)); // Only final return result; } - -// Phase 函数模板 -async function executePhaseN(ctx) { - const { previousResult, constraints } = ctx; - - const result = await Task({ - prompt: ` - [CONTEXT] - ${JSON.stringify(previousResult)} - - [TASK] - Process and return result. - ` - }); - - // 返回更新后的上下文,不写文件 - return { - ...ctx, - previousResult: result, - completed: [...ctx.completed, 'phase-n'] - }; -} ``` -**Risk**: Low -**Verification**: 无 Write→Read 紧邻模式 +### deduplicate_storage ---- - -### Strategy: deduplicate_storage - -**Purpose**: 消除重复数据存储。 - -**Implementation**: ```javascript -// Before: 重复存储 -state.user_request = userInput; -state.original_request = userInput; -state.input_text = userInput; - -// After: 单一来源 -state.input = userInput; // 唯一存储点 +// Before: state.user_request = state.original_request = state.input_text = input +// After: state.input = input; // Single source ``` -**Risk**: Low -**Verification**: 无相同数据多字段存储 - --- ## Context Explosion Strategies -### Strategy: sliding_window +### sliding_window -**Purpose**: Limit context history to most recent N items. - -**Implementation**: ```javascript -// In orchestrator.md or phase files -const MAX_HISTORY_ITEMS = 5; - +const MAX_HISTORY = 5; function updateHistory(state, newItem) { - const history = state.history || []; - const updated = [...history, newItem].slice(-MAX_HISTORY_ITEMS); - return { ...state, history: updated }; + return { ...state, history: [...(state.history || []), newItem].slice(-MAX_HISTORY) }; } ``` -**Files to Modify**: -- `phases/orchestrator.md` - Add history management -- `phases/state-schema.md` - Document history limit +### path_reference -**Risk**: Low -**Verification**: -- Run skill for 10+ iterations -- Verify history.length never exceeds MAX_HISTORY_ITEMS - ---- - -### Strategy: path_reference - -**Purpose**: Pass file paths instead of full content. - -**Implementation**: ```javascript -// Before -const content = Read('data.json'); -const prompt = `Analyze: ${content}`; - -// After -const dataPath = `${workDir}/data.json`; -const prompt = `Analyze file at: ${dataPath}. Read it first.`; +// Before: const prompt = `Analyze: ${Read('data.json')}`; +// After: const prompt = `Analyze file at: ${dataPath}. Read it first.`; ``` -**Files to Modify**: -- All phase files with `${content}` in prompts +### context_summarization -**Risk**: Low -**Verification**: -- Verify agents can still access required data -- Check token count reduced - ---- - -### Strategy: context_summarization - -**Purpose**: Add summarization step before passing to next phase. - -**Implementation**: ```javascript -// Add summarization agent -const summarizeResult = await Task({ +// Add summarization before passing to next phase +const summary = await Task({ subagent_type: 'universal-executor', - prompt: ` - Summarize the following in <100 words, preserving key facts: - ${fullContent} - - Return JSON: { summary: "...", key_points: [...] } - ` + prompt: `Summarize in <100 words: ${fullContent}\nReturn JSON: { summary, key_points[] }` }); - -// Pass summary instead of full content -nextPhasePrompt = `Previous phase summary: ${summarizeResult.summary}`; +nextPhasePrompt = `Previous summary: ${summary.summary}`; ``` -**Files to Modify**: -- Phase transition points -- Orchestrator (if autonomous) - -**Risk**: Low -**Verification**: -- Compare output quality with/without summarization -- Verify key information preserved - ---- - -### Strategy: structured_state - -**Purpose**: Replace text-based context with structured JSON state. - -**Implementation**: -```javascript -// Before: Text-based context passing -const context = ` - User requested: ${userRequest} - Previous output: ${previousOutput} - Current status: ${status} -`; - -// After: Structured state -const state = { - original_request: userRequest, - previous_output_path: `${workDir}/output.md`, - previous_output_summary: "...", - status: status, - key_decisions: [...] -}; -``` - -**Files to Modify**: -- `phases/state-schema.md` - Define structure -- All phases - Use structured fields - -**Risk**: Medium (requires refactoring) -**Verification**: -- Verify all phases can access required state fields -- Check backward compatibility - --- ## Long-tail Forgetting Strategies -### Strategy: constraint_injection +### constraint_injection -**Purpose**: Inject original constraints into every phase prompt. - -**Implementation**: ```javascript -// Add to every phase prompt template +// Add to EVERY phase prompt const phasePrompt = ` [CONSTRAINTS - FROM ORIGINAL REQUEST] ${state.original_requirements.map(r => `- ${r}`).join('\n')} @@ -297,1015 +162,118 @@ ${state.original_requirements.map(r => `- ${r}`).join('\n')} [CURRENT TASK] ${taskDescription} -[REMINDER] -Output MUST satisfy all constraints listed above. +[REMINDER] Output MUST satisfy all constraints above. `; ``` -**Files to Modify**: -- All `phases/*.md` files -- `templates/agent-base.md` (if exists) +### state_constraints_field -**Risk**: Low -**Verification**: -- Verify constraints visible in each phase -- Test with specific constraint, verify output respects it - ---- - -### Strategy: state_constraints_field - -**Purpose**: Add dedicated field in state schema for requirements. - -**Implementation**: -```typescript -// In state-schema.md -interface State { - // Add these fields - original_requirements: string[]; // User's original constraints - goal_summary: string; // One-line goal statement - constraint_violations: string[]; // Track any violations -} - -// In action-init.md -function initState(userInput) { - return { - original_requirements: extractRequirements(userInput), - goal_summary: summarizeGoal(userInput), - constraint_violations: [] - }; -} -``` - -**Files to Modify**: -- `phases/state-schema.md` -- `phases/actions/action-init.md` - -**Risk**: Low -**Verification**: -- Verify state.json contains requirements after init -- Check requirements persist through all phases - ---- - -### Strategy: checkpoint_restore - -**Purpose**: Save state at key milestones for recovery and verification. - -**Implementation**: +Add to state-schema + action-init: ```javascript -// Add checkpoint function -function createCheckpoint(state, workDir, checkpointName) { - const checkpointPath = `${workDir}/checkpoints/${checkpointName}.json`; - Write(checkpointPath, JSON.stringify({ - state: state, - timestamp: new Date().toISOString(), - name: checkpointName - }, null, 2)); - return checkpointPath; -} - -// Use at key points -await executePhase2(); -createCheckpoint(state, workDir, 'after-phase-2'); +state.original_requirements = extractRequirements(userInput); +state.goal_summary = summarizeGoal(userInput); ``` -**Files to Modify**: -- `phases/orchestrator.md` -- Key phase files +### checkpoint_restore -**Risk**: Low -**Verification**: -- Verify checkpoints created at expected points -- Test restore from checkpoint - ---- - -### Strategy: goal_embedding - -**Purpose**: Track semantic similarity to original goal throughout execution. - -**Implementation**: ```javascript -// Store goal embedding at init -state.goal_embedding = await embed(state.goal_summary); - -// At each major phase, check alignment -const currentPlanEmbedding = await embed(currentPlan); -const similarity = cosineSimilarity(state.goal_embedding, currentPlanEmbedding); - -if (similarity < 0.7) { - console.warn('Goal drift detected! Similarity:', similarity); - // Trigger re-alignment +function createCheckpoint(state, workDir, name) { + Write(`${workDir}/checkpoints/${name}.json`, JSON.stringify({ + state, timestamp: new Date().toISOString(), name + })); } +// Use at key phase boundaries ``` -**Files to Modify**: -- State schema (add embedding field) -- Orchestrator (add similarity check) - -**Risk**: Medium (requires embedding infrastructure) -**Verification**: -- Test with intentional drift, verify detection -- Verify false positive rate acceptable - --- ## Data Flow Strategies -### Strategy: state_centralization +### state_centralization -**Purpose**: Use single state.json for all persistent data. - -**Implementation**: ```javascript -// Create state manager +// Single state manager — replace all direct writes const StateManager = { - read: (workDir) => JSON.parse(Read(`${workDir}/state.json`)), - - update: (workDir, updates) => { - const current = StateManager.read(workDir); - const next = { ...current, ...updates, updated_at: new Date().toISOString() }; - Write(`${workDir}/state.json`, JSON.stringify(next, null, 2)); + read: (dir) => JSON.parse(Read(`${dir}/state.json`)), + update: (dir, updates) => { + const next = { ...StateManager.read(dir), ...updates, updated_at: Date.now() }; + Write(`${dir}/state.json`, JSON.stringify(next, null, 2)); return next; - }, - - get: (workDir, path) => { - const state = StateManager.read(workDir); - return path.split('.').reduce((obj, key) => obj?.[key], state); } }; - -// Replace direct writes -// Before: Write(`${workDir}/config.json`, config); -// After: StateManager.update(workDir, { config }); ``` -**Files to Modify**: -- All phases that write state -- Create shared state manager +### schema_enforcement -**Risk**: Medium (significant refactoring) -**Verification**: -- Verify single state.json after full run -- Check no orphan state files - ---- - -### Strategy: schema_enforcement - -**Purpose**: Add runtime validation using Zod or similar. - -**Implementation**: ```javascript -// Define schema (in state-schema.md) -const StateSchema = { - status: ['pending', 'running', 'completed', 'failed'], - target_skill: { - name: 'string', - path: 'string' - }, - // ... full schema -}; - function validateState(state) { const errors = []; - - if (!StateSchema.status.includes(state.status)) { + if (!['pending','running','completed','failed'].includes(state.status)) errors.push(`Invalid status: ${state.status}`); - } - - if (typeof state.target_skill?.name !== 'string') { + if (typeof state.target_skill?.name !== 'string') errors.push('target_skill.name must be string'); - } - - if (errors.length > 0) { - throw new Error(`State validation failed:\n${errors.join('\n')}`); - } - - return true; -} - -// Use before state write -function updateState(workDir, updates) { - const newState = { ...currentState, ...updates }; - validateState(newState); // Throws if invalid - Write(`${workDir}/state.json`, JSON.stringify(newState, null, 2)); + if (errors.length) throw new Error(`Validation failed:\n${errors.join('\n')}`); } +// Call before every state write ``` -**Files to Modify**: -- `phases/state-schema.md` - Add validation function -- All state write locations +### field_normalization -**Risk**: Low -**Verification**: -- Test with invalid state, verify rejection -- Verify valid state accepted - ---- - -### Strategy: field_normalization - -**Purpose**: Normalize field names across all phases. - -**Implementation**: ```javascript -// Create normalization mapping -const FIELD_NORMALIZATIONS = { - 'title': 'name', - 'identifier': 'id', - 'state': 'status', - 'error': 'errors' -}; - +const NORMALIZATIONS = { 'title': 'name', 'identifier': 'id', 'state': 'status' }; function normalizeData(data) { - if (typeof data !== 'object' || data === null) return data; - - const normalized = {}; - for (const [key, value] of Object.entries(data)) { - const normalizedKey = FIELD_NORMALIZATIONS[key] || key; - normalized[normalizedKey] = normalizeData(value); - } - return normalized; + if (typeof data !== 'object' || !data) return data; + return Object.fromEntries( + Object.entries(data).map(([k, v]) => [NORMALIZATIONS[k] || k, normalizeData(v)]) + ); } - -// Apply when reading external data -const rawData = JSON.parse(Read(filePath)); -const normalizedData = normalizeData(rawData); ``` -**Files to Modify**: -- Data ingestion points -- State update functions - -**Risk**: Low -**Verification**: -- Verify consistent field names in state -- Check no data loss during normalization - --- ## Agent Coordination Strategies -### Strategy: error_wrapping +### error_wrapping -**Purpose**: Add try-catch to all Task calls. - -**Implementation**: ```javascript -// Wrapper function async function safeTask(config, state, updateState) { - const maxRetries = 3; - - for (let attempt = 1; attempt <= maxRetries; attempt++) { + for (let attempt = 1; attempt <= 3; attempt++) { try { const result = await Task(config); - - // Validate result - if (!result) throw new Error('Empty result from agent'); - + if (!result) throw new Error('Empty result'); return result; } catch (error) { - console.log(`Task attempt ${attempt} failed: ${error.message}`); - - if (attempt === maxRetries) { - updateState({ - errors: [...state.errors, { - action: config.subagent_type, - message: error.message, - timestamp: new Date().toISOString() - }], - error_count: state.error_count + 1 - }); + if (attempt === 3) { + updateState({ error_count: state.error_count + 1 }); throw error; } - - // Wait before retry await new Promise(r => setTimeout(r, 1000 * attempt)); } } } ``` -**Files to Modify**: -- All files with Task calls +### result_validation -**Risk**: Low -**Verification**: -- Simulate agent failure, verify graceful handling -- Verify retry logic works - ---- - -### Strategy: result_validation - -**Purpose**: Validate agent returns before use. - -**Implementation**: ```javascript -function validateAgentResult(result, expectedSchema) { - // Try JSON parse - let parsed; - try { - parsed = typeof result === 'string' ? JSON.parse(result) : result; - } catch (e) { - throw new Error(`Agent result is not valid JSON: ${result.slice(0, 100)}`); +function validateAgentResult(result, requiredFields) { + const parsed = typeof result === 'string' ? JSON.parse(result) : result; + for (const field of requiredFields) { + if (!(field in parsed)) throw new Error(`Missing: ${field}`); } - - // Check required fields - for (const field of expectedSchema.required || []) { - if (!(field in parsed)) { - throw new Error(`Missing required field: ${field}`); - } - } - return parsed; } - -// Usage -const rawResult = await Task({...}); -const validResult = validateAgentResult(rawResult, { - required: ['status', 'output_file'] -}); ``` -**Files to Modify**: -- All locations where agent results are used +### flatten_nesting -**Risk**: Low -**Verification**: -- Test with invalid agent output -- Verify proper error messages - ---- - -### Strategy: flatten_nesting - -**Purpose**: Remove nested agent calls, use orchestrator coordination. - -**Implementation**: ```javascript -// Before: Agent A calls Agent B in its prompt -// Agent A prompt: "... then call Task({subagent_type: 'B', ...}) ..." - +// Before: Agent A's prompt tells it to call Task({subagent_type: 'B'}) // After: Agent A returns signal, orchestrator handles -// Agent A prompt: "If you need further analysis, return: { needs_agent_b: true, context: ... }" - -// Orchestrator handles: -const resultA = await Task({ subagent_type: 'A', ... }); -const parsedA = JSON.parse(resultA); - +// Agent A: return { needs_agent_b: true, context: {...} } +// Orchestrator: if (parsedA.needs_agent_b) { - const resultB = await Task({ - subagent_type: 'B', - prompt: `Continue analysis with context: ${JSON.stringify(parsedA.context)}` - }); -} -``` - -**Files to Modify**: -- Phase files with nested Task calls -- Orchestrator decision logic - -**Risk**: Medium (may change agent behavior) -**Verification**: -- Verify no nested Task patterns -- Test agent chain via orchestrator - ---- - -## Documentation Strategies - -文档去重和冲突解决策略。 - ---- - -### Strategy: consolidate_to_ssot - -**Purpose**: 将重复定义合并到单一真相来源 (Single Source of Truth)。 - -**Implementation**: -```javascript -// 合并流程 -async function consolidateToSSOT(state, duplicates) { - // 1. 识别最完整的定义位置 - const canonical = selectCanonicalSource(duplicates); - - // 2. 确保规范位置包含完整定义 - const fullDefinition = mergeDefinitions(duplicates); - Write(canonical.file, fullDefinition); - - // 3. 替换其他位置为引用 - for (const dup of duplicates.filter(d => d.file !== canonical.file)) { - const reference = generateReference(canonical.file, dup.type); - // 例如: "详见 [state-schema.md](phases/state-schema.md)" - replaceWithReference(dup.file, dup.location, reference); - } - - return { canonical: canonical.file, removed: duplicates.length - 1 }; -} - -function selectCanonicalSource(duplicates) { - // 优先级: specs/ > phases/ > SKILL.md - const priority = ['specs/', 'phases/', 'SKILL.md']; - return duplicates.sort((a, b) => { - const aIdx = priority.findIndex(p => a.file.includes(p)); - const bIdx = priority.findIndex(p => b.file.includes(p)); - return aIdx - bIdx; - })[0]; -} -``` - -**Risk**: Low -**Verification**: -- 确认只有一处包含完整定义 -- 其他位置包含有效引用链接 - ---- - -### Strategy: centralize_mapping_config - -**Purpose**: 将硬编码配置提取到集中的 JSON 文件,代码改为加载配置。 - -**Implementation**: -```javascript -// 1. 创建集中配置文件 -const config = { - version: "1.0.0", - categories: { - context_explosion: { - pattern_ids: ["CTX-001", "CTX-002"], - strategies: ["sliding_window", "path_reference"] - } - // ... 从硬编码中提取 - } -}; -Write('specs/category-mappings.json', JSON.stringify(config, null, 2)); - -// 2. 重构代码加载配置 -// Before: -function findTaxonomyMatch(category) { - const patternMapping = { - 'context_explosion': { category: 'context_explosion', pattern_ids: [...] } - // 硬编码 - }; - return patternMapping[category]; -} - -// After: -function findTaxonomyMatch(category) { - const mappings = JSON.parse(Read('specs/category-mappings.json')); - const config = mappings.categories[category]; - if (!config) return null; - return { category, pattern_ids: config.pattern_ids, severity_hint: config.severity_hint }; -} -``` - -**Risk**: Medium (需要测试配置加载逻辑) -**Verification**: -- JSON 文件语法正确 -- 所有原硬编码的值都已迁移 -- 功能行为不变 - ---- - -### Strategy: reconcile_conflicting_definitions - -**Purpose**: 调和冲突的定义,由用户选择正确版本后统一更新。 - -**Implementation**: -```javascript -async function reconcileConflicts(conflicts) { - for (const conflict of conflicts) { - // 1. 展示冲突给用户 - const options = conflict.definitions.map(def => ({ - label: `${def.file}: ${def.value}`, - description: `来自 ${def.file}` - })); - - const choice = await AskUserQuestion({ - questions: [{ - question: `发现冲突定义: "${conflict.key}",请选择正确版本`, - header: '冲突解决', - options: options, - multiSelect: false - }] - }); - - // 2. 更新所有文件为选中的版本 - const selected = conflict.definitions[choice.index]; - for (const def of conflict.definitions) { - if (def.file !== selected.file) { - updateDefinition(def.file, conflict.key, selected.value); - } - } - } - - return { resolved: conflicts.length }; -} -``` - -**Risk**: Low (用户确认后执行) -**Verification**: -- 所有位置的定义一致 -- 无新冲突产生 - ---- - -## Strategy Selection Guide - -``` -Issue Type: Context Explosion -├── history grows unbounded? → sliding_window -├── full content in prompts? → path_reference -├── no summarization? → context_summarization -└── text-based context? → structured_state - -Issue Type: Long-tail Forgetting -├── constraints not in phases? → constraint_injection -├── no requirements in state? → state_constraints_field -├── no recovery points? → checkpoint_restore -└── goal drift risk? → goal_embedding - -Issue Type: Data Flow -├── multiple state files? → state_centralization -├── no validation? → schema_enforcement -└── inconsistent names? → field_normalization - -Issue Type: Agent Coordination -├── no error handling? → error_wrapping -├── no result validation? → result_validation -└── nested agent calls? → flatten_nesting - -Issue Type: Prompt Engineering -├── vague instructions? → structured_prompt -├── inconsistent output? → output_schema -├── hallucination risk? → grounding_context -└── format drift? → format_enforcement - -Issue Type: Architecture -├── unclear responsibilities? → phase_decomposition -├── tight coupling? → interface_contracts -├── poor extensibility? → plugin_architecture -└── complex flow? → state_machine - -Issue Type: Performance -├── high token usage? → token_budgeting -├── slow execution? → parallel_execution -├── redundant computation? → result_caching -└── large files? → lazy_loading - -Issue Type: Error Handling -├── no recovery? → graceful_degradation -├── silent failures? → error_propagation -├── no logging? → structured_logging -└── unclear errors? → error_context - -Issue Type: Output Quality -├── inconsistent quality? → quality_gates -├── no verification? → output_validation -├── format issues? → template_enforcement -└── incomplete output? → completeness_check - -Issue Type: User Experience -├── no progress? → progress_tracking -├── unclear status? → status_communication -├── no feedback? → interactive_checkpoints -└── confusing flow? → guided_workflow - -Issue Type: Documentation Redundancy -├── 核心定义重复? → consolidate_to_ssot -└── 硬编码配置重复? → centralize_mapping_config - -Issue Type: Documentation Conflict -└── 定义不一致? → reconcile_conflicting_definitions -``` - ---- - -## General Tuning Strategies (按需 via Gemini CLI) - -以下策略针对更通用的优化场景,通常需要 Gemini CLI 进行深度分析后生成具体实现。 - ---- - -### Prompt Engineering Strategies - -#### Strategy: structured_prompt - -**Purpose**: 将模糊指令转换为结构化提示词。 - -**Implementation**: -```javascript -// Before: Vague prompt -const prompt = "Please analyze the code and give suggestions"; - -// After: Structured prompt -const prompt = ` -[ROLE] -You are a code analysis expert specializing in ${domain}. - -[TASK] -Analyze the provided code for: -1. Code quality issues -2. Performance bottlenecks -3. Security vulnerabilities - -[INPUT] -File: ${filePath} -Context: ${context} - -[OUTPUT FORMAT] -Return JSON: -{ - "issues": [{ "type": "...", "severity": "...", "location": "...", "suggestion": "..." }], - "summary": "..." -} - -[CONSTRAINTS] -- Focus on actionable issues only -- Limit to top 10 findings -`; -``` - -**Risk**: Low -**Verification**: Check output consistency across multiple runs - ---- - -#### Strategy: output_schema - -**Purpose**: 强制 LLM 输出符合特定 schema。 - -**Implementation**: -```javascript -// Define expected schema -const outputSchema = { - type: 'object', - required: ['status', 'result'], - properties: { - status: { enum: ['success', 'error', 'partial'] }, - result: { type: 'object' }, - errors: { type: 'array' } - } -}; - -// Include in prompt -const prompt = ` -...task description... - -[OUTPUT SCHEMA] -Your response MUST be valid JSON matching this schema: -${JSON.stringify(outputSchema, null, 2)} - -[VALIDATION] -Before returning, verify your output: -1. Is it valid JSON? -2. Does it have all required fields? -3. Are field types correct? -`; -``` - -**Risk**: Low -**Verification**: JSON.parse + schema validation - ---- - -#### Strategy: grounding_context - -**Purpose**: 提供足够上下文减少幻觉。 - -**Implementation**: -```javascript -// Gather grounding context -const groundingContext = { - codebase_patterns: await analyzePatterns(skillPath), - existing_examples: await findSimilarImplementations(taskType), - constraints: state.original_requirements -}; - -const prompt = ` -[GROUNDING CONTEXT] -This skill follows these patterns: -${JSON.stringify(groundingContext.codebase_patterns)} - -Similar implementations exist at: -${groundingContext.existing_examples.map(e => `- ${e.path}`).join('\n')} - -[TASK] -${taskDescription} - -[IMPORTANT] -- Only suggest patterns that exist in the codebase -- Reference specific files when making suggestions -- If unsure, indicate uncertainty level -`; -``` - -**Risk**: Medium (requires context gathering) -**Verification**: Check suggestions match existing patterns - ---- - -### Architecture Strategies - -#### Strategy: phase_decomposition - -**Purpose**: 重新划分阶段以清晰化职责。 - -**Analysis via Gemini**: -```bash -ccw cli -p " -PURPOSE: Analyze phase decomposition for skill at ${skillPath} -TASK: • Map current phase responsibilities • Identify overlapping concerns • Suggest cleaner boundaries -MODE: analysis -CONTEXT: @phases/**/*.md -EXPECTED: { current_phases: [], overlaps: [], recommended_structure: [] } -" --tool gemini --mode analysis -``` - -**Implementation Pattern**: -``` -Before: Monolithic phases -Phase1: Collect + Analyze + Transform + Output - -After: Single-responsibility phases -Phase1: Collect (input gathering) -Phase2: Analyze (processing) -Phase3: Transform (conversion) -Phase4: Output (delivery) -``` - ---- - -#### Strategy: interface_contracts - -**Purpose**: 定义阶段间的数据契约。 - -**Implementation**: -```typescript -// Define contracts in state-schema.md -interface PhaseContract { - input: { - required: string[]; - optional: string[]; - schema: object; - }; - output: { - guarantees: string[]; - schema: object; - }; -} - -// Phase 1 output contract -const phase1Contract: PhaseContract = { - input: { - required: ['user_request'], - optional: ['preferences'], - schema: { /* ... */ } - }, - output: { - guarantees: ['parsed_requirements', 'validation_status'], - schema: { /* ... */ } - } -}; -``` - ---- - -### Performance Strategies - -#### Strategy: token_budgeting - -**Purpose**: 为每个阶段设置 Token 预算。 - -**Implementation**: -```javascript -const TOKEN_BUDGETS = { - 'phase-collect': 2000, - 'phase-analyze': 5000, - 'phase-generate': 8000, - total: 15000 -}; - -function checkBudget(phase, estimatedTokens) { - if (estimatedTokens > TOKEN_BUDGETS[phase]) { - console.warn(`Phase ${phase} exceeds budget: ${estimatedTokens} > ${TOKEN_BUDGETS[phase]}`); - // Trigger summarization or truncation - return false; - } - return true; -} -``` - ---- - -#### Strategy: parallel_execution - -**Purpose**: 并行执行独立任务。 - -**Implementation**: -```javascript -// Before: Sequential -const result1 = await Task({ subagent_type: 'analyzer', prompt: prompt1 }); -const result2 = await Task({ subagent_type: 'analyzer', prompt: prompt2 }); -const result3 = await Task({ subagent_type: 'analyzer', prompt: prompt3 }); - -// After: Parallel (when independent) -const [result1, result2, result3] = await Promise.all([ - Task({ subagent_type: 'analyzer', prompt: prompt1, run_in_background: true }), - Task({ subagent_type: 'analyzer', prompt: prompt2, run_in_background: true }), - Task({ subagent_type: 'analyzer', prompt: prompt3, run_in_background: true }) -]); -``` - ---- - -#### Strategy: result_caching - -**Purpose**: 缓存中间结果避免重复计算。 - -**Implementation**: -```javascript -const cache = {}; - -async function cachedAnalysis(key, analysisFunc) { - if (cache[key]) { - console.log(`Cache hit: ${key}`); - return cache[key]; - } - - const result = await analysisFunc(); - cache[key] = result; - - // Persist to disk for cross-session caching - Write(`${workDir}/cache/${key}.json`, JSON.stringify(result)); - - return result; -} -``` - ---- - -### Error Handling Strategies - -#### Strategy: graceful_degradation - -**Purpose**: 失败时降级而非崩溃。 - -**Implementation**: -```javascript -async function executeWithDegradation(primaryTask, fallbackTask) { - try { - return await primaryTask(); - } catch (error) { - console.warn(`Primary task failed: ${error.message}, using fallback`); - - try { - return await fallbackTask(); - } catch (fallbackError) { - console.error(`Fallback also failed: ${fallbackError.message}`); - return { - status: 'degraded', - partial_result: null, - error: fallbackError.message - }; - } - } -} -``` - ---- - -#### Strategy: structured_logging - -**Purpose**: 添加结构化日志便于调试。 - -**Implementation**: -```javascript -function log(level, action, data) { - const entry = { - timestamp: new Date().toISOString(), - level, - action, - ...data - }; - - // Append to log file - const logPath = `${workDir}/execution.log`; - const existing = Read(logPath) || ''; - Write(logPath, existing + JSON.stringify(entry) + '\n'); - - // Console output - console.log(`[${level}] ${action}:`, JSON.stringify(data)); -} - -// Usage -log('INFO', 'phase_start', { phase: 'analyze', input_size: 1000 }); -log('ERROR', 'agent_failure', { agent: 'universal-executor', error: err.message }); -``` - ---- - -### Output Quality Strategies - -#### Strategy: quality_gates - -**Purpose**: 输出前进行质量检查。 - -**Implementation**: -```javascript -const qualityGates = [ - { - name: 'completeness', - check: (output) => output.sections?.length >= 3, - message: 'Output must have at least 3 sections' - }, - { - name: 'format', - check: (output) => /^#\s/.test(output.content), - message: 'Output must start with markdown heading' - }, - { - name: 'length', - check: (output) => output.content?.length >= 500, - message: 'Output must be at least 500 characters' - } -]; - -function validateOutput(output) { - const failures = qualityGates - .filter(gate => !gate.check(output)) - .map(gate => gate.message); - - if (failures.length > 0) { - throw new Error(`Quality gate failures:\n${failures.join('\n')}`); - } - - return true; -} -``` - ---- - -### User Experience Strategies - -#### Strategy: progress_tracking - -**Purpose**: 显示执行进度。 - -**Implementation**: -```javascript -function updateProgress(current, total, description) { - const percentage = Math.round((current / total) * 100); - const progressBar = '█'.repeat(percentage / 5) + '░'.repeat(20 - percentage / 5); - - console.log(`[${progressBar}] ${percentage}% - ${description}`); - - // Update state for UI - updateState({ - progress: { - current, - total, - percentage, - description - } - }); -} - -// Usage -updateProgress(1, 5, 'Initializing tuning session...'); -updateProgress(2, 5, 'Running context diagnosis...'); -``` - ---- - -#### Strategy: interactive_checkpoints - -**Purpose**: 在关键点暂停获取用户确认。 - -**Implementation**: -```javascript -async function checkpoint(name, summary, options) { - console.log(`\n=== Checkpoint: ${name} ===`); - console.log(summary); - - const response = await AskUserQuestion({ - questions: [{ - question: `Review ${name} results. How to proceed?`, - header: 'Checkpoint', - options: options || [ - { label: 'Continue', description: 'Proceed with next step' }, - { label: 'Modify', description: 'Adjust parameters and retry' }, - { label: 'Skip', description: 'Skip this step' }, - { label: 'Abort', description: 'Stop the workflow' } - ], - multiSelect: false - }] - }); - - return response; + resultB = await Task({ subagent_type: 'B', prompt: `Context: ${parsedA.context}` }); } ``` @@ -1313,225 +281,105 @@ async function checkpoint(name, summary, options) { ## Token Consumption Strategies -Strategies for reducing token usage and simplifying skill outputs. +### prompt_compression ---- - -### Strategy: prompt_compression - -**Purpose**: Reduce verbose prompts by extracting static text and using templates. - -**Implementation**: ```javascript -// Before: Long inline prompt -const prompt = ` -You are an expert code analyzer specializing in identifying patterns. -Your role is to examine the provided code and identify any issues. -Please follow these detailed instructions carefully: -1. Read the code thoroughly -2. Identify any anti-patterns -3. Check for security vulnerabilities -... (continues for many lines) - -Code to analyze: -${fullCodeContent} -`; - -// After: Compressed with template reference -const PROMPT_TEMPLATE_PATH = 'templates/analyzer-prompt.md'; - -const prompt = ` -[TEMPLATE: ${PROMPT_TEMPLATE_PATH}] -[CODE_PATH: ${codePath}] -[FOCUS: patterns, security] -`; - -// Or use key instructions only -const prompt = ` -Analyze ${codePath} for: patterns, security, performance. -Return JSON: { issues: [], severity: string } -`; +// Before: Long inline prompt with role, detailed instructions, full code +// After: Key instructions only +const prompt = `Analyze ${codePath} for: patterns, security, performance. +Return JSON: { issues: [], severity: string }`; ``` -**Risk**: Low -**Verification**: Compare token count before/after compression +### lazy_loading ---- - -### Strategy: lazy_loading - -**Purpose**: Pass file paths instead of full content, let consumers load if needed. - -**Implementation**: ```javascript -// Before: Full content in prompt -const content = Read(filePath); -const prompt = `Analyze this content:\n${content}`; - -// After: Path reference with lazy loading instruction -const prompt = ` -Analyze file at: ${filePath} -(Read the file content if you need to examine it) -Return: { summary: string, issues: [] } -`; - -// For agent calls -const result = await Task({ - subagent_type: 'universal-executor', - prompt: ` - [FILE_PATH]: ${dataPath} - [TASK]: Analyze the file and extract key metrics. - [NOTE]: Read the file only if needed for your analysis. - ` -}); +// Before: const prompt = `Analyze:\n${Read(filePath)}`; +// After: const prompt = `Analyze file at: ${filePath}\n(Read if needed)\nReturn: { summary, issues[] }`; ``` -**Risk**: Low -**Verification**: Verify agents can still access required data +### output_minimization ---- - -### Strategy: output_minimization - -**Purpose**: Configure agents to return minimal, structured output instead of verbose text. - -**Implementation**: ```javascript -// Before: Verbose output expectation -const prompt = ` -Analyze the code and provide a detailed report including: -- Executive summary -- Detailed findings with explanations -- Code examples for each issue -- Recommendations with rationale -... -`; - -// After: Minimal structured output const prompt = ` Analyze the code. Return ONLY this JSON: -{ - "status": "pass|review|fail", - "issues": [{ "id": string, "severity": string, "file": string, "line": number }], - "summary": "one sentence" -} -Do not include explanations or code examples. +{ "status": "pass|review|fail", "issues": [{"id","severity","file","line"}], "summary": "one sentence" } +Do not include explanations. `; +``` -// Validation -const result = JSON.parse(agentOutput); -if (!result.status || !Array.isArray(result.issues)) { - throw new Error('Invalid output format'); +### state_field_reduction + +Audit checklist: +```javascript +function auditStateFields(schema) { + const candidates = Object.keys(schema).filter(k => + k.startsWith('debug_') || k.endsWith('_cache') || + k.endsWith('_temp') || k.includes('intermediate') + ); + return { total: Object.keys(schema).length, removable: candidates }; } ``` -**Risk**: Low -**Verification**: JSON.parse succeeds, output size reduced +### in_memory_consolidation + +```javascript +// Before: Multiple files — diagnosis-report.md, summary.json, tuning-report.md +// After: Single state.json with final_report rendered on demand +const consolidated = { ...state, final_report: { summary, generated_at: Date.now() } }; +Write(`${workDir}/state.json`, JSON.stringify(consolidated, null, 2)); +``` --- -### Strategy: state_field_reduction +## Documentation Strategies -**Purpose**: Audit and consolidate state fields to minimize serialization overhead. +### consolidate_to_ssot -**Implementation**: -```typescript -// Before: Bloated state -interface State { - status: string; - target: TargetInfo; - user_input: string; - parsed_input: ParsedInput; // Remove - temporary - intermediate_result: any; // Remove - not persisted - debug_info: DebugInfo; // Remove - debugging only - analysis_cache: any; // Remove - session cache - full_history: HistoryEntry[]; // Remove - unbounded - step1_output: any; // Remove - intermediate - step2_output: any; // Remove - intermediate - step3_output: any; // Remove - intermediate - final_result: FinalResult; - error_log: string[]; // Remove - debugging - metrics: Metrics; // Remove - optional -} - -// After: Minimal state (≤15 fields) -interface State { - status: 'pending' | 'running' | 'completed' | 'failed'; - target: { name: string; path: string }; - input_summary: string; // Summarized user input - result_path: string; // Path to final result - quality_gate: 'pass' | 'fail'; - error?: string; // Only if failed -} -``` - -**Audit Checklist**: ```javascript -function auditStateFields(stateSchema) { - const removeCandidates = []; - - for (const [key, type] of Object.entries(stateSchema)) { - // Identify removal candidates - if (key.startsWith('debug_')) removeCandidates.push(key); - if (key.endsWith('_cache')) removeCandidates.push(key); - if (key.endsWith('_temp')) removeCandidates.push(key); - if (key.includes('intermediate')) removeCandidates.push(key); - if (key.includes('step') && key.includes('output')) removeCandidates.push(key); - } - - return { - total_fields: Object.keys(stateSchema).length, - remove_candidates: removeCandidates, - estimated_reduction: removeCandidates.length - }; -} +// 1. Identify canonical source (priority: specs/ > phases/ > SKILL.md) +// 2. Ensure canonical has full definition +// 3. Replace other locations with reference links +// e.g., "See [state-schema.md](phases/state-schema.md)" ``` -**Risk**: Medium (ensure no essential data removed) -**Verification**: State field count ≤ 15, all essential data preserved +### centralize_mapping_config + +```javascript +// 1. Extract hardcoded mappings → specs/category-mappings.json +// 2. Runtime loads config: const map = JSON.parse(Read('specs/category-mappings.json')); +// 3. Replace all inline definitions with config lookup +``` + +### reconcile_conflicting_definitions + +```javascript +// 1. Present conflict to user via AskUserQuestion +// 2. Apply chosen version across all files +// 3. Verify no remaining conflicts +``` --- -### Strategy: in_memory_consolidation +## General Optimization Areas (via Gemini CLI) -**Purpose**: Consolidate outputs into single file, eliminate redundant report files. +For issues in these categories, use Gemini CLI for custom analysis: -**Implementation**: -```javascript -// Before: Multiple output files -Write(`${workDir}/diagnosis-report.md`, reportMarkdown); -Write(`${workDir}/diagnosis-summary.json`, summaryJson); -Write(`${workDir}/state.json`, JSON.stringify(state)); -Write(`${workDir}/tuning-report.md`, tuningReport); -Write(`${workDir}/tuning-summary.md`, finalSummary); +| Category | Issues | Gemini Analysis | +|----------|--------|-----------------| +| Prompt Engineering | Vague instructions, format drift | prompt optimization, structured output | +| Architecture | Phase overlap, tight coupling | phase_decomposition, interface_contracts | +| Performance | Slow execution, high tokens | token_budgeting, parallel_execution | +| Error Handling | Silent failures, no degradation | graceful_degradation, error_propagation | +| Output Quality | Inconsistent results | quality_gates, output_validation | +| User Experience | No progress visibility | progress_tracking, interactive_checkpoints | -// After: Single source of truth -const consolidatedState = { - ...state, - final_report: { - summary: summaryJson, - details_available_in_state: true, - generated_at: new Date().toISOString() - } -}; -Write(`${workDir}/state.json`, JSON.stringify(consolidatedState, null, 2)); - -// Report can be rendered from state on-demand -function renderReport(state) { - return ` -# Tuning Report: ${state.target_skill.name} -Status: ${state.status} -Quality: ${state.quality_gate} -Issues: ${state.issues.length} -... -`; -} +**Gemini CLI Template**: +```bash +ccw cli -p " +PURPOSE: [optimization goal for skill at ${skillPath}] +TASK: • [specific analysis steps] +MODE: analysis +CONTEXT: @${skillPath}/**/* +EXPECTED: [specific deliverable] +" --tool gemini --mode analysis ``` - -**Benefits**: -- Single file to read/write -- No data duplication -- On-demand rendering - -**Risk**: Low -**Verification**: Only state.json exists as output, rendering works correctly diff --git a/.codex/AGENTS.md b/.codex/AGENTS.md index 7b0b2149..9e5c5d8c 100644 --- a/.codex/AGENTS.md +++ b/.codex/AGENTS.md @@ -1,5 +1,14 @@ # Codex Code Guidelines +## CLI Endpoints + +- **CLI Tools Usage**: @~/.claude/workflows/cli-tools-usage.md +- **CLI Endpoints Config**: @~/.claude/cli-tools.json + +**Strictly follow the cli-tools.json configuration** + +Available CLI endpoints are dynamically defined by the config file + ## Code Quality Standards ### Code Quality