mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-14 02:42:04 +08:00
feat: Add templates for autonomous actions, orchestrators, sequential phases, and skill documentation
- Introduced a comprehensive template for autonomous actions, detailing structure, execution, and error handling. - Added an orchestrator template to manage state and decision logic for autonomous actions. - Created a sequential phase template to outline execution steps and objectives for structured workflows. - Developed a skill documentation template to standardize the generation of skill entry files. - Implemented a Python script to compare search results between hybrid and cascade methods, analyzing ranking changes.
This commit is contained in:
@@ -0,0 +1,239 @@
|
||||
# Phase 1: Requirements Discovery
|
||||
|
||||
收集新 Skill 的需求信息,生成配置文件。
|
||||
|
||||
## Objective
|
||||
|
||||
- 收集 Skill 基本信息(名称、描述、触发词)
|
||||
- 确定执行模式(Sequential / Autonomous)
|
||||
- 定义阶段/动作
|
||||
- 配置工具依赖和输出格式
|
||||
|
||||
## Execution Steps
|
||||
|
||||
### Step 1: 基本信息收集
|
||||
|
||||
```javascript
|
||||
const basicInfo = await AskUserQuestion({
|
||||
questions: [
|
||||
{
|
||||
question: "新 Skill 的名称是什么?(英文,小写-连字符格式,如 'api-docs')",
|
||||
header: "Skill 名称",
|
||||
multiSelect: false,
|
||||
options: [
|
||||
{ label: "自动生成", description: "根据后续描述自动生成名称" },
|
||||
{ label: "手动输入", description: "现在输入自定义名称" }
|
||||
]
|
||||
},
|
||||
{
|
||||
question: "Skill 的主要用途是什么?",
|
||||
header: "用途类型",
|
||||
multiSelect: false,
|
||||
options: [
|
||||
{ label: "文档生成", description: "生成 Markdown/HTML 文档(如手册、报告)" },
|
||||
{ label: "代码分析", description: "分析代码结构、质量、安全性" },
|
||||
{ label: "交互管理", description: "管理 Issue、任务、工作流(CRUD 操作)" },
|
||||
{ label: "数据处理", description: "ETL、格式转换、报告生成" }
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// 如果选择手动输入,进一步询问
|
||||
if (basicInfo["Skill 名称"] === "手动输入") {
|
||||
// 用户会在 "Other" 中输入
|
||||
}
|
||||
|
||||
// 根据用途类型推断描述模板
|
||||
const purposeTemplates = {
|
||||
"文档生成": "Generate {type} documents from {source}",
|
||||
"代码分析": "Analyze {target} for {purpose}",
|
||||
"交互管理": "Manage {entity} with interactive operations",
|
||||
"数据处理": "Process {data} and generate {output}"
|
||||
};
|
||||
```
|
||||
|
||||
### Step 2: 执行模式选择
|
||||
|
||||
```javascript
|
||||
const modeInfo = await AskUserQuestion({
|
||||
questions: [
|
||||
{
|
||||
question: "选择执行模式:",
|
||||
header: "执行模式",
|
||||
multiSelect: false,
|
||||
options: [
|
||||
{
|
||||
label: "Sequential (顺序模式)",
|
||||
description: "阶段按固定顺序执行(收集→分析→生成),适合流水线任务(推荐)"
|
||||
},
|
||||
{
|
||||
label: "Autonomous (自主模式)",
|
||||
description: "动态选择执行路径,适合交互式任务(如 Issue 管理)"
|
||||
},
|
||||
{
|
||||
label: "Hybrid (混合模式)",
|
||||
description: "初始化和收尾固定,中间交互灵活"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
const executionMode = modeInfo["执行模式"].includes("Sequential") ? "sequential" :
|
||||
modeInfo["执行模式"].includes("Autonomous") ? "autonomous" : "hybrid";
|
||||
```
|
||||
|
||||
### Step 3: 阶段/动作定义
|
||||
|
||||
#### Sequential 模式
|
||||
|
||||
```javascript
|
||||
if (executionMode === "sequential") {
|
||||
const phaseInfo = await AskUserQuestion({
|
||||
questions: [
|
||||
{
|
||||
question: "需要多少个执行阶段?",
|
||||
header: "阶段数量",
|
||||
multiSelect: false,
|
||||
options: [
|
||||
{ label: "3 阶段(简单)", description: "收集 → 处理 → 输出" },
|
||||
{ label: "5 阶段(标准)", description: "收集 → 探索 → 分析 → 组装 → 验证" },
|
||||
{ label: "7 阶段(完整)", description: "含并行处理、汇总、迭代优化" }
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// 根据选择生成阶段定义
|
||||
const phaseTemplates = {
|
||||
"3 阶段": [
|
||||
{ id: "01-collection", name: "Data Collection" },
|
||||
{ id: "02-processing", name: "Processing" },
|
||||
{ id: "03-output", name: "Output Generation" }
|
||||
],
|
||||
"5 阶段": [
|
||||
{ id: "01-collection", name: "Requirements Collection" },
|
||||
{ id: "02-exploration", name: "Project Exploration" },
|
||||
{ id: "03-analysis", name: "Deep Analysis" },
|
||||
{ id: "04-assembly", name: "Document Assembly" },
|
||||
{ id: "05-validation", name: "Validation" }
|
||||
],
|
||||
"7 阶段": [
|
||||
{ id: "01-collection", name: "Requirements Collection" },
|
||||
{ id: "02-exploration", name: "Project Exploration" },
|
||||
{ id: "03-parallel", name: "Parallel Analysis" },
|
||||
{ id: "03.5-consolidation", name: "Consolidation" },
|
||||
{ id: "04-assembly", name: "Document Assembly" },
|
||||
{ id: "05-refinement", name: "Iterative Refinement" },
|
||||
{ id: "06-output", name: "Final Output" }
|
||||
]
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
#### Autonomous 模式
|
||||
|
||||
```javascript
|
||||
if (executionMode === "autonomous") {
|
||||
const actionInfo = await AskUserQuestion({
|
||||
questions: [
|
||||
{
|
||||
question: "核心动作有哪些?(可多选)",
|
||||
header: "动作定义",
|
||||
multiSelect: true,
|
||||
options: [
|
||||
{ label: "初始化 (init)", description: "设置初始状态" },
|
||||
{ label: "列表 (list)", description: "显示当前项目列表" },
|
||||
{ label: "创建 (create)", description: "创建新项目" },
|
||||
{ label: "编辑 (edit)", description: "修改现有项目" },
|
||||
{ label: "删除 (delete)", description: "删除项目" },
|
||||
{ label: "搜索 (search)", description: "搜索/过滤项目" }
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### Step 4: 工具和输出配置
|
||||
|
||||
```javascript
|
||||
const toolsInfo = await AskUserQuestion({
|
||||
questions: [
|
||||
{
|
||||
question: "需要哪些特殊工具?(基础工具已默认包含)",
|
||||
header: "工具选择",
|
||||
multiSelect: true,
|
||||
options: [
|
||||
{ label: "用户交互 (AskUserQuestion)", description: "需要与用户对话" },
|
||||
{ label: "Chrome 截图 (mcp__chrome__*)", description: "需要网页截图" },
|
||||
{ label: "外部搜索 (mcp__exa__search)", description: "需要搜索外部信息" },
|
||||
{ label: "无特殊需求", description: "仅使用基础工具" }
|
||||
]
|
||||
},
|
||||
{
|
||||
question: "输出格式是什么?",
|
||||
header: "输出格式",
|
||||
multiSelect: false,
|
||||
options: [
|
||||
{ label: "Markdown", description: "适合文档和报告" },
|
||||
{ label: "HTML", description: "适合交互式文档" },
|
||||
{ label: "JSON", description: "适合数据和配置" }
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
### Step 5: 生成配置文件
|
||||
|
||||
```javascript
|
||||
const config = {
|
||||
skill_name: skillName,
|
||||
display_name: displayName,
|
||||
description: description,
|
||||
triggers: triggers,
|
||||
execution_mode: executionMode,
|
||||
|
||||
// 模式特定配置
|
||||
...(executionMode === "sequential" ? {
|
||||
sequential_config: { phases: phases }
|
||||
} : {
|
||||
autonomous_config: {
|
||||
state_schema: stateSchema,
|
||||
actions: actions,
|
||||
termination_conditions: ["user_exit", "error_limit", "task_completed"]
|
||||
}
|
||||
}),
|
||||
|
||||
allowed_tools: [
|
||||
"Task", "Read", "Write", "Glob", "Grep", "Bash",
|
||||
...selectedTools
|
||||
],
|
||||
|
||||
output: {
|
||||
format: outputFormat.toLowerCase(),
|
||||
location: `.workflow/.scratchpad/${skillName}-{timestamp}`,
|
||||
filename_pattern: `{name}-output.${outputFormat === "HTML" ? "html" : outputFormat === "JSON" ? "json" : "md"}`
|
||||
},
|
||||
|
||||
created_at: new Date().toISOString(),
|
||||
version: "1.0.0"
|
||||
};
|
||||
|
||||
// 写入配置文件
|
||||
const workDir = `.workflow/.scratchpad/skill-gen-${timestamp}`;
|
||||
Bash(`mkdir -p "${workDir}"`);
|
||||
Write(`${workDir}/skill-config.json`, JSON.stringify(config, null, 2));
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
- **File**: `skill-config.json`
|
||||
- **Location**: `.workflow/.scratchpad/skill-gen-{timestamp}/`
|
||||
- **Format**: JSON
|
||||
|
||||
## Next Phase
|
||||
|
||||
→ [Phase 2: Structure Generation](02-structure-generation.md)
|
||||
208
.claude/skills/skill-generator/phases/02-structure-generation.md
Normal file
208
.claude/skills/skill-generator/phases/02-structure-generation.md
Normal file
@@ -0,0 +1,208 @@
|
||||
# Phase 2: Structure Generation
|
||||
|
||||
根据配置创建 Skill 目录结构和入口文件。
|
||||
|
||||
## Objective
|
||||
|
||||
- 创建标准目录结构
|
||||
- 生成 SKILL.md 入口文件
|
||||
- 根据执行模式创建对应的子目录
|
||||
|
||||
## Input
|
||||
|
||||
- 依赖: `skill-config.json` (Phase 1 产出)
|
||||
|
||||
## Execution Steps
|
||||
|
||||
### Step 1: 读取配置
|
||||
|
||||
```javascript
|
||||
const config = JSON.parse(Read(`${workDir}/skill-config.json`));
|
||||
const skillDir = `.claude/skills/${config.skill_name}`;
|
||||
```
|
||||
|
||||
### Step 2: 创建目录结构
|
||||
|
||||
```javascript
|
||||
// 基础目录
|
||||
Bash(`mkdir -p "${skillDir}/phases"`);
|
||||
Bash(`mkdir -p "${skillDir}/specs"`);
|
||||
Bash(`mkdir -p "${skillDir}/templates"`);
|
||||
|
||||
// Autonomous 模式额外目录
|
||||
if (config.execution_mode === 'autonomous' || config.execution_mode === 'hybrid') {
|
||||
Bash(`mkdir -p "${skillDir}/phases/actions"`);
|
||||
}
|
||||
|
||||
// 可选: scripts 目录
|
||||
if (config.needs_scripts) {
|
||||
Bash(`mkdir -p "${skillDir}/scripts"`);
|
||||
}
|
||||
```
|
||||
|
||||
### Step 3: 生成 SKILL.md
|
||||
|
||||
```javascript
|
||||
const skillMdTemplate = `---
|
||||
name: ${config.skill_name}
|
||||
description: ${config.description}. Triggers on ${config.triggers.map(t => `"${t}"`).join(", ")}.
|
||||
allowed-tools: ${config.allowed_tools.join(", ")}
|
||||
---
|
||||
|
||||
# ${config.display_name}
|
||||
|
||||
${config.description}
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
\`\`\`
|
||||
${generateArchitectureDiagram(config)}
|
||||
\`\`\`
|
||||
|
||||
## Key Design Principles
|
||||
|
||||
${generateDesignPrinciples(config)}
|
||||
|
||||
## Execution Flow
|
||||
|
||||
${generateExecutionFlow(config)}
|
||||
|
||||
## Directory Setup
|
||||
|
||||
\`\`\`javascript
|
||||
const timestamp = new Date().toISOString().slice(0,19).replace(/[-:T]/g, '');
|
||||
const workDir = \`${config.output.location.replace('{timestamp}', '${timestamp}')}\`;
|
||||
|
||||
Bash(\`mkdir -p "\${workDir}"\`);
|
||||
${config.execution_mode === 'sequential' ?
|
||||
`Bash(\`mkdir -p "\${workDir}/sections"\`);` :
|
||||
`Bash(\`mkdir -p "\${workDir}/state"\`);`}
|
||||
\`\`\`
|
||||
|
||||
## Output Structure
|
||||
|
||||
\`\`\`
|
||||
${generateOutputStructure(config)}
|
||||
\`\`\`
|
||||
|
||||
## Reference Documents
|
||||
|
||||
${generateReferenceTable(config)}
|
||||
`;
|
||||
|
||||
Write(`${skillDir}/SKILL.md`, skillMdTemplate);
|
||||
```
|
||||
|
||||
### Step 4: 架构图生成函数
|
||||
|
||||
```javascript
|
||||
function generateArchitectureDiagram(config) {
|
||||
if (config.execution_mode === 'sequential') {
|
||||
return config.sequential_config.phases.map((p, i) =>
|
||||
`│ Phase ${i+1}: ${p.name.padEnd(15)} → ${p.output || 'output-' + (i+1) + '.json'}${' '.repeat(10)}│`
|
||||
).join('\n│ ↓' + ' '.repeat(45) + '│\n');
|
||||
} else {
|
||||
return `
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Orchestrator (状态驱动决策) │
|
||||
└───────────────┬─────────────────────────────────────────────────┘
|
||||
│
|
||||
┌───────────┼───────────┐
|
||||
↓ ↓ ↓
|
||||
${config.autonomous_config.actions.slice(0, 3).map(a =>
|
||||
`┌─────────┐ `).join('')}
|
||||
${config.autonomous_config.actions.slice(0, 3).map(a =>
|
||||
`│${a.name.slice(0, 7).padEnd(7)}│ `).join('')}
|
||||
${config.autonomous_config.actions.slice(0, 3).map(a =>
|
||||
`└─────────┘ `).join('')}`;
|
||||
}
|
||||
}
|
||||
|
||||
function generateDesignPrinciples(config) {
|
||||
const common = [
|
||||
"1. **规范遵循**: 严格遵循 `_shared/SKILL-DESIGN-SPEC.md`",
|
||||
"2. **简要返回**: Agent 返回路径+摘要,避免上下文溢出"
|
||||
];
|
||||
|
||||
if (config.execution_mode === 'sequential') {
|
||||
return [...common,
|
||||
"3. **阶段隔离**: 每个阶段独立可测",
|
||||
"4. **链式输出**: 阶段产出作为下阶段输入"
|
||||
].join('\n');
|
||||
} else {
|
||||
return [...common,
|
||||
"3. **状态驱动**: 显式状态管理,动态决策",
|
||||
"4. **动作独立**: 每个动作无副作用依赖"
|
||||
].join('\n');
|
||||
}
|
||||
}
|
||||
|
||||
function generateExecutionFlow(config) {
|
||||
if (config.execution_mode === 'sequential') {
|
||||
return '```\n' + config.sequential_config.phases.map((p, i) =>
|
||||
`├─ Phase ${i+1}: ${p.name}\n│ → Output: ${p.output || 'output.json'}`
|
||||
).join('\n') + '\n```';
|
||||
} else {
|
||||
return `\`\`\`
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Orchestrator Loop │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||||
│ │ Read │────▶│ Select │────▶│ Execute │ │
|
||||
│ │ State │ │ Action │ │ Action │ │
|
||||
│ └──────────┘ └──────────┘ └──────────┘ │
|
||||
│ ▲ │ │
|
||||
│ └──────────── Update State ◀───────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
\`\`\``;
|
||||
}
|
||||
}
|
||||
|
||||
function generateOutputStructure(config) {
|
||||
const base = `${config.output.location}/
|
||||
├── ${config.execution_mode === 'sequential' ? 'sections/' : 'state.json'}`;
|
||||
|
||||
if (config.execution_mode === 'sequential') {
|
||||
return base + '\n' + config.sequential_config.phases.map(p =>
|
||||
`│ └── ${p.output || 'section-' + p.id + '.md'}`
|
||||
).join('\n') + `\n└── ${config.output.filename_pattern}`;
|
||||
} else {
|
||||
return base + `
|
||||
├── actions-log.json
|
||||
└── ${config.output.filename_pattern}`;
|
||||
}
|
||||
}
|
||||
|
||||
function generateReferenceTable(config) {
|
||||
const rows = [];
|
||||
|
||||
if (config.execution_mode === 'sequential') {
|
||||
config.sequential_config.phases.forEach(p => {
|
||||
rows.push(`| [phases/${p.id}.md](phases/${p.id}.md) | ${p.name} |`);
|
||||
});
|
||||
} else {
|
||||
rows.push(`| [phases/orchestrator.md](phases/orchestrator.md) | 编排器 |`);
|
||||
rows.push(`| [phases/state-schema.md](phases/state-schema.md) | 状态定义 |`);
|
||||
config.autonomous_config.actions.forEach(a => {
|
||||
rows.push(`| [phases/actions/${a.id}.md](phases/actions/${a.id}.md) | ${a.name} |`);
|
||||
});
|
||||
}
|
||||
|
||||
rows.push(`| [specs/${config.skill_name}-requirements.md](specs/${config.skill_name}-requirements.md) | 领域规范 |`);
|
||||
rows.push(`| [specs/quality-standards.md](specs/quality-standards.md) | 质量标准 |`);
|
||||
|
||||
return `| Document | Purpose |\n|----------|---------||\n` + rows.join('\n');
|
||||
}
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
- **Directory**: `.claude/skills/{skill-name}/`
|
||||
- **Files**:
|
||||
- `SKILL.md` (入口文件)
|
||||
- `phases/` (空目录)
|
||||
- `specs/` (空目录)
|
||||
- `templates/` (空目录)
|
||||
|
||||
## Next Phase
|
||||
|
||||
→ [Phase 3: Phase Generation](03-phase-generation.md)
|
||||
396
.claude/skills/skill-generator/phases/03-phase-generation.md
Normal file
396
.claude/skills/skill-generator/phases/03-phase-generation.md
Normal file
@@ -0,0 +1,396 @@
|
||||
# Phase 3: Phase Generation
|
||||
|
||||
根据执行模式生成 Phase 文件。
|
||||
|
||||
## Objective
|
||||
|
||||
- Sequential 模式:生成顺序 Phase 文件 (`01-xx.md`, `02-xx.md`, ...)
|
||||
- Autonomous 模式:生成编排器和动作文件
|
||||
|
||||
## Input
|
||||
|
||||
- 依赖: `skill-config.json`, SKILL.md (Phase 1-2 产出)
|
||||
- 模板: `templates/sequential-phase.md`, `templates/autonomous-*.md`
|
||||
|
||||
## Execution Steps
|
||||
|
||||
### Step 1: 读取配置和模板
|
||||
|
||||
```javascript
|
||||
const config = JSON.parse(Read(`${workDir}/skill-config.json`));
|
||||
const skillDir = `.claude/skills/${config.skill_name}`;
|
||||
|
||||
// 读取模板
|
||||
const sequentialTemplate = Read(`${skillRoot}/templates/sequential-phase.md`);
|
||||
const orchestratorTemplate = Read(`${skillRoot}/templates/autonomous-orchestrator.md`);
|
||||
const actionTemplate = Read(`${skillRoot}/templates/autonomous-action.md`);
|
||||
```
|
||||
|
||||
### Step 2: Sequential 模式 - 生成阶段文件
|
||||
|
||||
```javascript
|
||||
if (config.execution_mode === 'sequential') {
|
||||
const phases = config.sequential_config.phases;
|
||||
|
||||
for (let i = 0; i < phases.length; i++) {
|
||||
const phase = phases[i];
|
||||
const prevPhase = i > 0 ? phases[i-1] : null;
|
||||
const nextPhase = i < phases.length - 1 ? phases[i+1] : null;
|
||||
|
||||
const content = generateSequentialPhase({
|
||||
phaseNumber: i + 1,
|
||||
phaseId: phase.id,
|
||||
phaseName: phase.name,
|
||||
phaseDescription: phase.description || `Execute ${phase.name}`,
|
||||
input: prevPhase ? prevPhase.output : "user input",
|
||||
output: phase.output,
|
||||
nextPhase: nextPhase ? nextPhase.id : null,
|
||||
config: config
|
||||
});
|
||||
|
||||
Write(`${skillDir}/phases/${phase.id}.md`, content);
|
||||
}
|
||||
}
|
||||
|
||||
function generateSequentialPhase(params) {
|
||||
return `# Phase ${params.phaseNumber}: ${params.phaseName}
|
||||
|
||||
${params.phaseDescription}
|
||||
|
||||
## Objective
|
||||
|
||||
- 主要目标描述
|
||||
- 具体任务列表
|
||||
|
||||
## Input
|
||||
|
||||
- 依赖: \`${params.input}\`
|
||||
- 配置: \`{workDir}/skill-config.json\`
|
||||
|
||||
## Execution Steps
|
||||
|
||||
### Step 1: 准备工作
|
||||
|
||||
\`\`\`javascript
|
||||
// 读取上一阶段产出
|
||||
${params.phaseNumber > 1 ?
|
||||
`const prevOutput = JSON.parse(Read(\`\${workDir}/${params.input}\`));` :
|
||||
`// 首阶段,直接从配置开始`}
|
||||
\`\`\`
|
||||
|
||||
### Step 2: 核心处理
|
||||
|
||||
\`\`\`javascript
|
||||
// TODO: 实现核心逻辑
|
||||
const result = {
|
||||
// 处理结果
|
||||
};
|
||||
\`\`\`
|
||||
|
||||
### Step 3: 输出结果
|
||||
|
||||
\`\`\`javascript
|
||||
Write(\`\${workDir}/${params.output}\`, JSON.stringify(result, null, 2));
|
||||
\`\`\`
|
||||
|
||||
## Output
|
||||
|
||||
- **File**: \`${params.output}\`
|
||||
- **Format**: ${params.output.endsWith('.json') ? 'JSON' : 'Markdown'}
|
||||
|
||||
## Quality Checklist
|
||||
|
||||
- [ ] 输入数据验证通过
|
||||
- [ ] 核心逻辑执行成功
|
||||
- [ ] 输出格式正确
|
||||
|
||||
${params.nextPhase ?
|
||||
`## Next Phase\n\n→ [Phase ${params.phaseNumber + 1}: ${params.nextPhase}](${params.nextPhase}.md)` :
|
||||
`## Completion\n\n此为最后阶段,输出最终产物。`}
|
||||
`;
|
||||
}
|
||||
```
|
||||
|
||||
### Step 3: Autonomous 模式 - 生成编排器
|
||||
|
||||
```javascript
|
||||
if (config.execution_mode === 'autonomous' || config.execution_mode === 'hybrid') {
|
||||
|
||||
// 生成状态 Schema
|
||||
const stateSchema = generateStateSchema(config);
|
||||
Write(`${skillDir}/phases/state-schema.md`, stateSchema);
|
||||
|
||||
// 生成编排器
|
||||
const orchestrator = generateOrchestrator(config);
|
||||
Write(`${skillDir}/phases/orchestrator.md`, orchestrator);
|
||||
|
||||
// 生成动作文件
|
||||
for (const action of config.autonomous_config.actions) {
|
||||
const actionContent = generateAction(action, config);
|
||||
Write(`${skillDir}/phases/actions/${action.id}.md`, actionContent);
|
||||
}
|
||||
}
|
||||
|
||||
function generateStateSchema(config) {
|
||||
return `# State Schema
|
||||
|
||||
## 状态文件
|
||||
|
||||
位置: \`{workDir}/state.json\`
|
||||
|
||||
## 结构定义
|
||||
|
||||
\`\`\`typescript
|
||||
interface ${toPascalCase(config.skill_name)}State {
|
||||
// 元信息
|
||||
skill_name: "${config.skill_name}";
|
||||
started_at: string;
|
||||
updated_at: string;
|
||||
|
||||
// 执行状态
|
||||
status: 'pending' | 'running' | 'completed' | 'failed';
|
||||
current_action: string | null;
|
||||
completed_actions: string[];
|
||||
|
||||
// 业务数据
|
||||
${config.autonomous_config.state_schema?.fields?.map(f =>
|
||||
` ${f.name}: ${f.type}; // ${f.description}`
|
||||
).join('\n') || ' context: Record<string, any>;'}
|
||||
|
||||
// 错误追踪
|
||||
errors: Array<{
|
||||
action: string;
|
||||
message: string;
|
||||
timestamp: string;
|
||||
}>;
|
||||
error_count: number;
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
## 初始状态
|
||||
|
||||
\`\`\`json
|
||||
{
|
||||
"skill_name": "${config.skill_name}",
|
||||
"started_at": "",
|
||||
"updated_at": "",
|
||||
"status": "pending",
|
||||
"current_action": null,
|
||||
"completed_actions": [],
|
||||
${config.autonomous_config.state_schema?.fields?.map(f =>
|
||||
` "${f.name}": ${getDefaultValue(f.type)}`
|
||||
).join(',\n') || ' "context": {}'}
|
||||
"errors": [],
|
||||
"error_count": 0
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
## 状态转换规则
|
||||
|
||||
| 当前状态 | 触发条件 | 目标状态 |
|
||||
|----------|----------|----------|
|
||||
| pending | 首次执行 | running |
|
||||
| running | 动作完成 | running |
|
||||
| running | 所有任务完成 | completed |
|
||||
| running | 错误超限 | failed |
|
||||
`;
|
||||
}
|
||||
|
||||
function generateOrchestrator(config) {
|
||||
const actions = config.autonomous_config.actions;
|
||||
|
||||
return `# Orchestrator
|
||||
|
||||
## Role
|
||||
|
||||
根据当前状态选择并执行下一个动作。
|
||||
|
||||
## State Reading
|
||||
|
||||
\`\`\`javascript
|
||||
const state = JSON.parse(Read(\`\${workDir}/state.json\`));
|
||||
\`\`\`
|
||||
|
||||
## Decision Logic
|
||||
|
||||
\`\`\`javascript
|
||||
function selectNextAction(state) {
|
||||
// 1. 检查终止条件
|
||||
${config.autonomous_config.termination_conditions?.map(c =>
|
||||
` if (${getTerminationCheck(c)}) return null;`
|
||||
).join('\n') || ' if (state.status === "completed") return null;'}
|
||||
|
||||
// 2. 错误检查
|
||||
if (state.error_count >= 3) return 'action-abort';
|
||||
|
||||
// 3. 根据状态选择动作
|
||||
${actions.map(a =>
|
||||
` if (${getPreconditionCheck(a)}) return '${a.id}';`
|
||||
).join('\n')}
|
||||
|
||||
// 4. 默认: 完成
|
||||
return 'action-complete';
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
## Execution Loop
|
||||
|
||||
\`\`\`javascript
|
||||
async function runOrchestrator() {
|
||||
while (true) {
|
||||
// 读取状态
|
||||
const state = JSON.parse(Read(\`\${workDir}/state.json\`));
|
||||
|
||||
// 选择动作
|
||||
const actionId = selectNextAction(state);
|
||||
if (!actionId) {
|
||||
console.log("任务完成或终止");
|
||||
break;
|
||||
}
|
||||
|
||||
// 更新当前动作
|
||||
state.current_action = actionId;
|
||||
state.updated_at = new Date().toISOString();
|
||||
Write(\`\${workDir}/state.json\`, JSON.stringify(state, null, 2));
|
||||
|
||||
// 执行动作
|
||||
try {
|
||||
const result = await executeAction(actionId, state);
|
||||
|
||||
// 更新状态
|
||||
state.completed_actions.push(actionId);
|
||||
state.current_action = null;
|
||||
Object.assign(state, result.stateUpdates);
|
||||
|
||||
} catch (error) {
|
||||
state.errors.push({
|
||||
action: actionId,
|
||||
message: error.message,
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
state.error_count++;
|
||||
}
|
||||
|
||||
Write(\`\${workDir}/state.json\`, JSON.stringify(state, null, 2));
|
||||
}
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
## Action Catalog
|
||||
|
||||
| Action | Purpose | Preconditions |
|
||||
|--------|---------|---------------|
|
||||
${actions.map(a =>
|
||||
`| [${a.id}](actions/${a.id}.md) | ${a.description || a.name} | ${a.preconditions?.join(', ') || '-'} |`
|
||||
).join('\n')}
|
||||
|
||||
## Termination Conditions
|
||||
|
||||
${config.autonomous_config.termination_conditions?.map(c => `- ${c}`).join('\n') || '- status === "completed"'}
|
||||
`;
|
||||
}
|
||||
|
||||
function generateAction(action, config) {
|
||||
return `# Action: ${action.name}
|
||||
|
||||
${action.description || '执行 ' + action.name + ' 操作'}
|
||||
|
||||
## Purpose
|
||||
|
||||
${action.description || 'TODO: 描述此动作的目的'}
|
||||
|
||||
## Preconditions
|
||||
|
||||
${action.preconditions?.map(p => `- [ ] ${p}`).join('\n') || '- [ ] 无特殊前置条件'}
|
||||
|
||||
## Execution
|
||||
|
||||
\`\`\`javascript
|
||||
async function execute(state) {
|
||||
// TODO: 实现动作逻辑
|
||||
|
||||
// 1. 读取必要数据
|
||||
|
||||
// 2. 执行核心逻辑
|
||||
|
||||
// 3. 返回状态更新
|
||||
return {
|
||||
stateUpdates: {
|
||||
// 更新的状态字段
|
||||
}
|
||||
};
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
## State Updates
|
||||
|
||||
\`\`\`javascript
|
||||
return {
|
||||
completed_actions: [...state.completed_actions, '${action.id}'],
|
||||
// 其他状态更新
|
||||
${action.effects?.map(e => ` // Effect: ${e}`).join('\n') || ''}
|
||||
};
|
||||
\`\`\`
|
||||
|
||||
## Error Handling
|
||||
|
||||
| 错误类型 | 处理方式 |
|
||||
|----------|----------|
|
||||
| 数据验证失败 | 返回错误,不更新状态 |
|
||||
| 执行异常 | 记录错误,增加 error_count |
|
||||
|
||||
## Next Actions (Hints)
|
||||
|
||||
- 成功时: 由编排器根据状态决定
|
||||
- 失败时: 重试或 \`action-abort\`
|
||||
`;
|
||||
}
|
||||
```
|
||||
|
||||
### Step 4: 辅助函数
|
||||
|
||||
```javascript
|
||||
function toPascalCase(str) {
|
||||
return str.split('-').map(s => s.charAt(0).toUpperCase() + s.slice(1)).join('');
|
||||
}
|
||||
|
||||
function getDefaultValue(type) {
|
||||
if (type.endsWith('[]')) return '[]';
|
||||
if (type === 'number') return '0';
|
||||
if (type === 'boolean') return 'false';
|
||||
if (type === 'string') return '""';
|
||||
return '{}';
|
||||
}
|
||||
|
||||
function getTerminationCheck(condition) {
|
||||
const checks = {
|
||||
'user_exit': 'state.status === "user_exit"',
|
||||
'error_limit': 'state.error_count >= 3',
|
||||
'task_completed': 'state.status === "completed"'
|
||||
};
|
||||
return checks[condition] || `state.${condition}`;
|
||||
}
|
||||
|
||||
function getPreconditionCheck(action) {
|
||||
if (!action.preconditions?.length) return 'true';
|
||||
return action.preconditions.map(p => `state.${p}`).join(' && ');
|
||||
}
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
### Sequential 模式
|
||||
|
||||
- `phases/01-{step}.md`
|
||||
- `phases/02-{step}.md`
|
||||
- ...
|
||||
|
||||
### Autonomous 模式
|
||||
|
||||
- `phases/orchestrator.md`
|
||||
- `phases/state-schema.md`
|
||||
- `phases/actions/action-{name}.md` (多个)
|
||||
|
||||
## Next Phase
|
||||
|
||||
→ [Phase 4: Specs & Templates](04-specs-templates.md)
|
||||
328
.claude/skills/skill-generator/phases/04-specs-templates.md
Normal file
328
.claude/skills/skill-generator/phases/04-specs-templates.md
Normal file
@@ -0,0 +1,328 @@
|
||||
# Phase 4: Specs & Templates Generation
|
||||
|
||||
生成规范文件和模板文件。
|
||||
|
||||
## Objective
|
||||
|
||||
- 生成领域规范 (`specs/{domain}-requirements.md`)
|
||||
- 生成质量标准 (`specs/quality-standards.md`)
|
||||
- 生成 Agent 模板 (`templates/agent-base.md`)
|
||||
- Autonomous 模式额外生成动作目录 (`specs/action-catalog.md`)
|
||||
|
||||
## Input
|
||||
|
||||
- 依赖: `skill-config.json`, SKILL.md, phases/*.md
|
||||
|
||||
## Execution Steps
|
||||
|
||||
### Step 1: 生成领域规范
|
||||
|
||||
```javascript
|
||||
const config = JSON.parse(Read(`${workDir}/skill-config.json`));
|
||||
const skillDir = `.claude/skills/${config.skill_name}`;
|
||||
|
||||
const domainRequirements = `# ${config.display_name} Requirements
|
||||
|
||||
${config.description}
|
||||
|
||||
## When to Use
|
||||
|
||||
| Phase | Usage | Reference |
|
||||
|-------|-------|-----------|
|
||||
${config.execution_mode === 'sequential' ?
|
||||
config.sequential_config.phases.map((p, i) =>
|
||||
`| Phase ${i+1} | ${p.name} | ${p.id}.md |`
|
||||
).join('\n') :
|
||||
`| Orchestrator | 动作选择 | orchestrator.md |
|
||||
| Actions | 动作执行 | actions/*.md |`}
|
||||
|
||||
---
|
||||
|
||||
## Domain Requirements
|
||||
|
||||
### 功能要求
|
||||
|
||||
- [ ] 要求1: TODO
|
||||
- [ ] 要求2: TODO
|
||||
- [ ] 要求3: TODO
|
||||
|
||||
### 输出要求
|
||||
|
||||
- [ ] 格式: ${config.output.format}
|
||||
- [ ] 位置: ${config.output.location}
|
||||
- [ ] 命名: ${config.output.filename_pattern}
|
||||
|
||||
### 质量要求
|
||||
|
||||
- [ ] 完整性: 所有必需内容存在
|
||||
- [ ] 一致性: 术语和格式统一
|
||||
- [ ] 准确性: 内容基于实际分析
|
||||
|
||||
## Validation Function
|
||||
|
||||
\`\`\`javascript
|
||||
function validate${toPascalCase(config.skill_name)}(output) {
|
||||
const checks = [
|
||||
// TODO: 添加验证规则
|
||||
{ name: "格式正确", pass: output.format === "${config.output.format}" },
|
||||
{ name: "内容完整", pass: output.content?.length > 0 }
|
||||
];
|
||||
|
||||
return {
|
||||
passed: checks.filter(c => c.pass).length,
|
||||
total: checks.length,
|
||||
details: checks
|
||||
};
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
## Error Handling
|
||||
|
||||
| Error | Recovery |
|
||||
|-------|----------|
|
||||
| 输入数据缺失 | 返回明确错误信息 |
|
||||
| 处理超时 | 缩小范围,重试 |
|
||||
| 输出验证失败 | 记录问题,人工审核 |
|
||||
`;
|
||||
|
||||
Write(`${skillDir}/specs/${config.skill_name}-requirements.md`, domainRequirements);
|
||||
```
|
||||
|
||||
### Step 2: 生成质量标准
|
||||
|
||||
```javascript
|
||||
const qualityStandards = `# Quality Standards
|
||||
|
||||
${config.display_name} 的质量评估标准。
|
||||
|
||||
## Quality Dimensions
|
||||
|
||||
### 1. Completeness (完整性) - 25%
|
||||
|
||||
| 要求 | 权重 | 检查方式 |
|
||||
|------|------|----------|
|
||||
| 所有必需输出存在 | 10 | 文件检查 |
|
||||
| 内容覆盖完整 | 10 | 内容分析 |
|
||||
| 无占位符残留 | 5 | 文本搜索 |
|
||||
|
||||
### 2. Consistency (一致性) - 25%
|
||||
|
||||
| 方面 | 检查 |
|
||||
|------|------|
|
||||
| 术语 | 同一概念使用相同术语 |
|
||||
| 格式 | 标题层级、代码块格式一致 |
|
||||
| 风格 | 语气和表达方式统一 |
|
||||
|
||||
### 3. Accuracy (准确性) - 25%
|
||||
|
||||
| 要求 | 说明 |
|
||||
|------|------|
|
||||
| 数据正确 | 引用和数据无错误 |
|
||||
| 逻辑正确 | 流程和关系描述准确 |
|
||||
| 代码正确 | 代码示例可运行 |
|
||||
|
||||
### 4. Usability (可用性) - 25%
|
||||
|
||||
| 指标 | 目标 |
|
||||
|------|------|
|
||||
| 可读性 | 结构清晰,易于理解 |
|
||||
| 可导航 | 目录和链接正确 |
|
||||
| 可操作 | 步骤明确,可执行 |
|
||||
|
||||
## Quality Gates
|
||||
|
||||
| Gate | Threshold | Action |
|
||||
|------|-----------|--------|
|
||||
| Pass | ≥ 80% | 输出最终产物 |
|
||||
| Review | 60-79% | 处理警告后继续 |
|
||||
| Fail | < 60% | 必须修复 |
|
||||
|
||||
## Issue Classification
|
||||
|
||||
### Errors (Must Fix)
|
||||
|
||||
- 必需输出缺失
|
||||
- 数据错误
|
||||
- 代码不可运行
|
||||
|
||||
### Warnings (Should Fix)
|
||||
|
||||
- 格式不一致
|
||||
- 内容深度不足
|
||||
- 缺少示例
|
||||
|
||||
### Info (Nice to Have)
|
||||
|
||||
- 优化建议
|
||||
- 增强机会
|
||||
|
||||
## Automated Checks
|
||||
|
||||
\`\`\`javascript
|
||||
function runQualityChecks(workDir) {
|
||||
const results = {
|
||||
completeness: checkCompleteness(workDir),
|
||||
consistency: checkConsistency(workDir),
|
||||
accuracy: checkAccuracy(workDir),
|
||||
usability: checkUsability(workDir)
|
||||
};
|
||||
|
||||
results.overall = (
|
||||
results.completeness * 0.25 +
|
||||
results.consistency * 0.25 +
|
||||
results.accuracy * 0.25 +
|
||||
results.usability * 0.25
|
||||
);
|
||||
|
||||
return {
|
||||
score: results.overall,
|
||||
gate: results.overall >= 80 ? 'pass' :
|
||||
results.overall >= 60 ? 'review' : 'fail',
|
||||
details: results
|
||||
};
|
||||
}
|
||||
\`\`\`
|
||||
`;
|
||||
|
||||
Write(`${skillDir}/specs/quality-standards.md`, qualityStandards);
|
||||
```
|
||||
|
||||
### Step 3: 生成 Agent 模板
|
||||
|
||||
```javascript
|
||||
const agentBase = `# Agent Base Template
|
||||
|
||||
${config.display_name} 的 Agent 基础模板。
|
||||
|
||||
## 通用 Prompt 结构
|
||||
|
||||
\`\`\`
|
||||
[ROLE] 你是{角色},专注于{职责}。
|
||||
|
||||
[PROJECT CONTEXT]
|
||||
Skill: ${config.skill_name}
|
||||
目标: ${config.description}
|
||||
|
||||
[TASK]
|
||||
{任务描述}
|
||||
- 输出: {output_path}
|
||||
- 格式: ${config.output.format}
|
||||
|
||||
[CONSTRAINTS]
|
||||
- 约束1
|
||||
- 约束2
|
||||
|
||||
[OUTPUT_FORMAT]
|
||||
1. 执行任务
|
||||
2. 返回 JSON 简要信息
|
||||
|
||||
[QUALITY_CHECKLIST]
|
||||
- [ ] 输出格式正确
|
||||
- [ ] 内容完整无遗漏
|
||||
- [ ] 无占位符残留
|
||||
\`\`\`
|
||||
|
||||
## 变量说明
|
||||
|
||||
| 变量 | 来源 | 示例 |
|
||||
|------|------|------|
|
||||
| {workDir} | 运行时 | .workflow/.scratchpad/${config.skill_name}-xxx |
|
||||
| {output_path} | 配置 | ${config.output.location}/${config.output.filename_pattern} |
|
||||
|
||||
## 返回格式
|
||||
|
||||
\`\`\`typescript
|
||||
interface AgentReturn {
|
||||
status: "completed" | "partial" | "failed";
|
||||
output_file: string;
|
||||
summary: string; // Max 50 chars
|
||||
stats?: {
|
||||
items_processed?: number;
|
||||
errors?: number;
|
||||
};
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
## 角色定义参考
|
||||
|
||||
${config.execution_mode === 'sequential' ?
|
||||
config.sequential_config.phases.map((p, i) =>
|
||||
`- **Phase ${i+1} Agent**: ${p.name} 专家`
|
||||
).join('\n') :
|
||||
config.autonomous_config.actions.map(a =>
|
||||
`- **${a.name} Agent**: ${a.description || a.name + ' 执行者'}`
|
||||
).join('\n')}
|
||||
`;
|
||||
|
||||
Write(`${skillDir}/templates/agent-base.md`, agentBase);
|
||||
```
|
||||
|
||||
### Step 4: Autonomous 模式 - 动作目录
|
||||
|
||||
```javascript
|
||||
if (config.execution_mode === 'autonomous' || config.execution_mode === 'hybrid') {
|
||||
const actionCatalog = `# Action Catalog
|
||||
|
||||
${config.display_name} 的可用动作目录。
|
||||
|
||||
## Available Actions
|
||||
|
||||
| Action | Purpose | Preconditions | Effects |
|
||||
|--------|---------|---------------|---------|
|
||||
${config.autonomous_config.actions.map(a =>
|
||||
`| [${a.id}](../phases/actions/${a.id}.md) | ${a.description || a.name} | ${a.preconditions?.join(', ') || '-'} | ${a.effects?.join(', ') || '-'} |`
|
||||
).join('\n')}
|
||||
|
||||
## Action Dependencies
|
||||
|
||||
\`\`\`mermaid
|
||||
graph TD
|
||||
${config.autonomous_config.actions.map((a, i, arr) => {
|
||||
if (i === 0) return ` ${a.id.replace(/-/g, '_')}[${a.name}]`;
|
||||
const prev = arr[i-1];
|
||||
return ` ${prev.id.replace(/-/g, '_')} --> ${a.id.replace(/-/g, '_')}[${a.name}]`;
|
||||
}).join('\n')}
|
||||
\`\`\`
|
||||
|
||||
## State Transitions
|
||||
|
||||
| From State | Action | To State |
|
||||
|------------|--------|----------|
|
||||
| pending | action-init | running |
|
||||
${config.autonomous_config.actions.slice(1).map(a =>
|
||||
`| running | ${a.id} | running |`
|
||||
).join('\n')}
|
||||
| running | action-complete | completed |
|
||||
| running | action-abort | failed |
|
||||
|
||||
## Selection Priority
|
||||
|
||||
当多个动作的前置条件都满足时,按以下优先级选择:
|
||||
|
||||
${config.autonomous_config.actions.map((a, i) =>
|
||||
`${i + 1}. \`${a.id}\` - ${a.name}`
|
||||
).join('\n')}
|
||||
`;
|
||||
|
||||
Write(`${skillDir}/specs/action-catalog.md`, actionCatalog);
|
||||
}
|
||||
```
|
||||
|
||||
### Step 5: 辅助函数
|
||||
|
||||
```javascript
|
||||
function toPascalCase(str) {
|
||||
return str.split('-').map(s => s.charAt(0).toUpperCase() + s.slice(1)).join('');
|
||||
}
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
- `specs/{skill-name}-requirements.md` - 领域规范
|
||||
- `specs/quality-standards.md` - 质量标准
|
||||
- `specs/action-catalog.md` - 动作目录 (Autonomous 模式)
|
||||
- `templates/agent-base.md` - Agent 模板
|
||||
|
||||
## Next Phase
|
||||
|
||||
→ [Phase 5: Validation](05-validation.md)
|
||||
334
.claude/skills/skill-generator/phases/05-validation.md
Normal file
334
.claude/skills/skill-generator/phases/05-validation.md
Normal file
@@ -0,0 +1,334 @@
|
||||
# Phase 5: Validation & Documentation
|
||||
|
||||
验证生成的 Skill 完整性并生成使用说明。
|
||||
|
||||
## Objective
|
||||
|
||||
- 验证所有必需文件存在
|
||||
- 检查文件内容完整性
|
||||
- 生成 README.md 使用说明
|
||||
- 输出验证报告
|
||||
|
||||
## Input
|
||||
|
||||
- 依赖: 所有前序阶段产出
|
||||
- 生成的 Skill 目录
|
||||
|
||||
## Execution Steps
|
||||
|
||||
### Step 1: 文件完整性检查
|
||||
|
||||
```javascript
|
||||
const config = JSON.parse(Read(`${workDir}/skill-config.json`));
|
||||
const skillDir = `.claude/skills/${config.skill_name}`;
|
||||
|
||||
const requiredFiles = {
|
||||
common: [
|
||||
'SKILL.md',
|
||||
`specs/${config.skill_name}-requirements.md`,
|
||||
'specs/quality-standards.md',
|
||||
'templates/agent-base.md'
|
||||
],
|
||||
sequential: config.sequential_config?.phases?.map(p => `phases/${p.id}.md`) || [],
|
||||
autonomous: [
|
||||
'phases/orchestrator.md',
|
||||
'phases/state-schema.md',
|
||||
'specs/action-catalog.md',
|
||||
...(config.autonomous_config?.actions?.map(a => `phases/actions/${a.id}.md`) || [])
|
||||
]
|
||||
};
|
||||
|
||||
const filesToCheck = [
|
||||
...requiredFiles.common,
|
||||
...(config.execution_mode === 'sequential' ? requiredFiles.sequential : requiredFiles.autonomous)
|
||||
];
|
||||
|
||||
const fileCheckResults = filesToCheck.map(file => {
|
||||
const fullPath = `${skillDir}/${file}`;
|
||||
try {
|
||||
const content = Read(fullPath);
|
||||
return {
|
||||
file: file,
|
||||
exists: true,
|
||||
size: content.length,
|
||||
hasContent: content.length > 100,
|
||||
hasTodo: content.includes('TODO')
|
||||
};
|
||||
} catch (e) {
|
||||
return {
|
||||
file: file,
|
||||
exists: false,
|
||||
size: 0,
|
||||
hasContent: false,
|
||||
hasTodo: false
|
||||
};
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### Step 2: 内容质量检查
|
||||
|
||||
```javascript
|
||||
const contentChecks = [];
|
||||
|
||||
// 检查 SKILL.md
|
||||
const skillMd = Read(`${skillDir}/SKILL.md`);
|
||||
contentChecks.push({
|
||||
file: 'SKILL.md',
|
||||
checks: [
|
||||
{ name: 'Front Matter', pass: skillMd.startsWith('---') },
|
||||
{ name: 'Architecture', pass: skillMd.includes('## Architecture') },
|
||||
{ name: 'Execution Flow', pass: skillMd.includes('## Execution Flow') },
|
||||
{ name: 'References', pass: skillMd.includes('## Reference Documents') }
|
||||
]
|
||||
});
|
||||
|
||||
// 检查 Phase 文件
|
||||
const phaseFiles = Glob(`${skillDir}/phases/*.md`);
|
||||
for (const phaseFile of phaseFiles) {
|
||||
if (phaseFile.includes('/actions/')) continue; // 单独检查
|
||||
|
||||
const content = Read(phaseFile);
|
||||
contentChecks.push({
|
||||
file: phaseFile.replace(skillDir + '/', ''),
|
||||
checks: [
|
||||
{ name: 'Objective', pass: content.includes('## Objective') },
|
||||
{ name: 'Execution', pass: content.includes('## Execution') || content.includes('## Execution Steps') },
|
||||
{ name: 'Output', pass: content.includes('## Output') },
|
||||
{ name: 'Code Blocks', pass: content.includes('```') }
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
// 检查 Specs 文件
|
||||
const specFiles = Glob(`${skillDir}/specs/*.md`);
|
||||
for (const specFile of specFiles) {
|
||||
const content = Read(specFile);
|
||||
contentChecks.push({
|
||||
file: specFile.replace(skillDir + '/', ''),
|
||||
checks: [
|
||||
{ name: 'Has Content', pass: content.length > 200 },
|
||||
{ name: 'Has Structure', pass: content.includes('##') },
|
||||
{ name: 'No Empty Sections', pass: !content.match(/##[^#]+\n\n##/) }
|
||||
]
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### Step 3: 生成验证报告
|
||||
|
||||
```javascript
|
||||
const report = {
|
||||
skill_name: config.skill_name,
|
||||
execution_mode: config.execution_mode,
|
||||
generated_at: new Date().toISOString(),
|
||||
|
||||
file_checks: {
|
||||
total: fileCheckResults.length,
|
||||
existing: fileCheckResults.filter(f => f.exists).length,
|
||||
with_content: fileCheckResults.filter(f => f.hasContent).length,
|
||||
with_todos: fileCheckResults.filter(f => f.hasTodo).length,
|
||||
details: fileCheckResults
|
||||
},
|
||||
|
||||
content_checks: {
|
||||
files_checked: contentChecks.length,
|
||||
all_passed: contentChecks.every(c => c.checks.every(ch => ch.pass)),
|
||||
details: contentChecks
|
||||
},
|
||||
|
||||
summary: {
|
||||
status: calculateOverallStatus(fileCheckResults, contentChecks),
|
||||
issues: collectIssues(fileCheckResults, contentChecks),
|
||||
recommendations: generateRecommendations(fileCheckResults, contentChecks)
|
||||
}
|
||||
};
|
||||
|
||||
Write(`${workDir}/validation-report.json`, JSON.stringify(report, null, 2));
|
||||
|
||||
function calculateOverallStatus(fileResults, contentResults) {
|
||||
const allFilesExist = fileResults.every(f => f.exists);
|
||||
const allContentPassed = contentResults.every(c => c.checks.every(ch => ch.pass));
|
||||
|
||||
if (allFilesExist && allContentPassed) return 'PASS';
|
||||
if (allFilesExist) return 'REVIEW';
|
||||
return 'FAIL';
|
||||
}
|
||||
|
||||
function collectIssues(fileResults, contentResults) {
|
||||
const issues = [];
|
||||
|
||||
fileResults.filter(f => !f.exists).forEach(f => {
|
||||
issues.push({ type: 'ERROR', message: `文件缺失: ${f.file}` });
|
||||
});
|
||||
|
||||
fileResults.filter(f => f.hasTodo).forEach(f => {
|
||||
issues.push({ type: 'WARNING', message: `包含 TODO: ${f.file}` });
|
||||
});
|
||||
|
||||
contentResults.forEach(c => {
|
||||
c.checks.filter(ch => !ch.pass).forEach(ch => {
|
||||
issues.push({ type: 'WARNING', message: `${c.file}: 缺少 ${ch.name}` });
|
||||
});
|
||||
});
|
||||
|
||||
return issues;
|
||||
}
|
||||
|
||||
function generateRecommendations(fileResults, contentResults) {
|
||||
const recommendations = [];
|
||||
|
||||
if (fileResults.some(f => f.hasTodo)) {
|
||||
recommendations.push('替换所有 TODO 占位符为实际内容');
|
||||
}
|
||||
|
||||
contentResults.forEach(c => {
|
||||
if (c.checks.some(ch => !ch.pass)) {
|
||||
recommendations.push(`完善 ${c.file} 的结构`);
|
||||
}
|
||||
});
|
||||
|
||||
return recommendations;
|
||||
}
|
||||
```
|
||||
|
||||
### Step 4: 生成 README.md
|
||||
|
||||
```javascript
|
||||
const readme = `# ${config.display_name}
|
||||
|
||||
${config.description}
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 触发词
|
||||
|
||||
${config.triggers.map(t => `- "${t}"`).join('\n')}
|
||||
|
||||
### 执行模式
|
||||
|
||||
**${config.execution_mode === 'sequential' ? 'Sequential (顺序)' : 'Autonomous (自主)'}**
|
||||
|
||||
${config.execution_mode === 'sequential' ?
|
||||
`阶段按固定顺序执行:\n${config.sequential_config.phases.map((p, i) =>
|
||||
`${i + 1}. ${p.name}`
|
||||
).join('\n')}` :
|
||||
`动作由编排器动态选择:\n${config.autonomous_config.actions.map(a =>
|
||||
`- ${a.name}: ${a.description || ''}`
|
||||
).join('\n')}`}
|
||||
|
||||
## Usage
|
||||
|
||||
\`\`\`
|
||||
# 直接触发
|
||||
用户: ${config.triggers[0]}
|
||||
|
||||
# 或使用 Skill 名称
|
||||
用户: /skill ${config.skill_name}
|
||||
\`\`\`
|
||||
|
||||
## Output
|
||||
|
||||
- **格式**: ${config.output.format}
|
||||
- **位置**: \`${config.output.location}\`
|
||||
- **文件名**: \`${config.output.filename_pattern}\`
|
||||
|
||||
## Directory Structure
|
||||
|
||||
\`\`\`
|
||||
.claude/skills/${config.skill_name}/
|
||||
├── SKILL.md # 入口文件
|
||||
├── phases/ # 执行阶段
|
||||
${config.execution_mode === 'sequential' ?
|
||||
config.sequential_config.phases.map(p => `│ ├── ${p.id}.md`).join('\n') :
|
||||
`│ ├── orchestrator.md
|
||||
│ ├── state-schema.md
|
||||
│ └── actions/
|
||||
${config.autonomous_config.actions.map(a => `│ ├── ${a.id}.md`).join('\n')}`}
|
||||
├── specs/ # 规范文件
|
||||
│ ├── ${config.skill_name}-requirements.md
|
||||
│ ├── quality-standards.md
|
||||
${config.execution_mode === 'autonomous' ? '│ └── action-catalog.md' : ''}
|
||||
└── templates/ # 模板文件
|
||||
└── agent-base.md
|
||||
\`\`\`
|
||||
|
||||
## Customization
|
||||
|
||||
### 修改执行逻辑
|
||||
|
||||
编辑 \`phases/\` 目录下的阶段文件。
|
||||
|
||||
### 调整质量标准
|
||||
|
||||
编辑 \`specs/quality-standards.md\`。
|
||||
|
||||
### 添加新${config.execution_mode === 'sequential' ? '阶段' : '动作'}
|
||||
|
||||
${config.execution_mode === 'sequential' ?
|
||||
`1. 在 \`phases/\` 创建新的阶段文件 (如 \`03.5-new-step.md\`)
|
||||
2. 更新 SKILL.md 的执行流程` :
|
||||
`1. 在 \`phases/actions/\` 创建新的动作文件
|
||||
2. 更新 \`specs/action-catalog.md\`
|
||||
3. 在 \`phases/orchestrator.md\` 添加选择逻辑`}
|
||||
|
||||
## Related Documents
|
||||
|
||||
- [设计规范](../_shared/SKILL-DESIGN-SPEC.md)
|
||||
- [执行模式规范](specs/../../../skill-generator/specs/execution-modes.md)
|
||||
|
||||
---
|
||||
|
||||
*Generated by skill-generator v1.0*
|
||||
`;
|
||||
|
||||
Write(`${skillDir}/README.md`, readme);
|
||||
```
|
||||
|
||||
### Step 5: 输出最终结果
|
||||
|
||||
```javascript
|
||||
const finalResult = {
|
||||
skill_name: config.skill_name,
|
||||
skill_path: skillDir,
|
||||
execution_mode: config.execution_mode,
|
||||
|
||||
generated_files: [
|
||||
'SKILL.md',
|
||||
'README.md',
|
||||
...filesToCheck
|
||||
],
|
||||
|
||||
validation: report.summary,
|
||||
|
||||
next_steps: [
|
||||
'1. 审阅生成的文件结构',
|
||||
'2. 替换 TODO 占位符',
|
||||
'3. 根据实际需求调整阶段逻辑',
|
||||
'4. 测试 Skill 执行流程',
|
||||
'5. 更新触发词和描述'
|
||||
]
|
||||
};
|
||||
|
||||
console.log('=== Skill 生成完成 ===');
|
||||
console.log(`路径: ${skillDir}`);
|
||||
console.log(`模式: ${config.execution_mode}`);
|
||||
console.log(`状态: ${report.summary.status}`);
|
||||
console.log('');
|
||||
console.log('下一步:');
|
||||
finalResult.next_steps.forEach(s => console.log(s));
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
- `{workDir}/validation-report.json` - 验证报告
|
||||
- `{skillDir}/README.md` - 使用说明
|
||||
|
||||
## Completion
|
||||
|
||||
Skill 生成流程完成。用户可以:
|
||||
|
||||
1. 查看生成的 Skill 目录
|
||||
2. 根据验证报告修复问题
|
||||
3. 自定义执行逻辑
|
||||
4. 测试 Skill 功能
|
||||
Reference in New Issue
Block a user