mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-13 02:41:50 +08:00
feat: add issue discovery view for managing discovery sessions and findings
- Implemented main render function for the issue discovery view. - Added data loading functions to fetch discoveries, details, findings, and progress. - Created rendering functions for discovery list and detail sections. - Introduced filtering and searching capabilities for findings. - Implemented actions for exporting and dismissing findings. - Added polling mechanism to track discovery progress. - Included utility functions for HTML escaping and cleanup.
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
# Phase 1: Requirements Discovery
|
||||
|
||||
Collect user requirements and generate configuration for the manual generation process.
|
||||
|
||||
## Objective
|
||||
|
||||
Gather essential information about the software project to customize the manual generation:
|
||||
- Software type and characteristics
|
||||
- Target user audience
|
||||
- Documentation scope and depth
|
||||
- Special requirements
|
||||
|
||||
## Execution Steps
|
||||
|
||||
### Step 1: Software Information Collection
|
||||
|
||||
Use `AskUserQuestion` to collect:
|
||||
|
||||
```javascript
|
||||
AskUserQuestion({
|
||||
questions: [
|
||||
{
|
||||
question: "What type of software is this project?",
|
||||
header: "Software Type",
|
||||
options: [
|
||||
{ label: "Web Application", description: "Frontend + Backend web app with UI" },
|
||||
{ label: "CLI Tool", description: "Command-line interface tool" },
|
||||
{ label: "SDK/Library", description: "Developer library or SDK" },
|
||||
{ label: "Desktop App", description: "Desktop application (Electron, etc.)" }
|
||||
],
|
||||
multiSelect: false
|
||||
},
|
||||
{
|
||||
question: "Who is the target audience for this manual?",
|
||||
header: "Target Users",
|
||||
options: [
|
||||
{ label: "End Users", description: "Non-technical users who use the product" },
|
||||
{ label: "Developers", description: "Developers integrating or extending the product" },
|
||||
{ label: "Administrators", description: "System admins deploying and maintaining" },
|
||||
{ label: "All Audiences", description: "Mixed audience with different sections" }
|
||||
],
|
||||
multiSelect: false
|
||||
},
|
||||
{
|
||||
question: "What documentation scope do you need?",
|
||||
header: "Doc Scope",
|
||||
options: [
|
||||
{ label: "Quick Start", description: "Essential getting started guide only" },
|
||||
{ label: "User Guide", description: "Complete user-facing documentation" },
|
||||
{ label: "API Reference", description: "Focus on API documentation" },
|
||||
{ label: "Comprehensive", description: "Full documentation including all sections" }
|
||||
],
|
||||
multiSelect: false
|
||||
},
|
||||
{
|
||||
question: "What difficulty levels should code examples cover?",
|
||||
header: "Example Levels",
|
||||
options: [
|
||||
{ label: "Beginner Only", description: "Simple, basic examples" },
|
||||
{ label: "Beginner + Intermediate", description: "Basic to moderate complexity" },
|
||||
{ label: "All Levels", description: "Beginner, Intermediate, and Advanced" }
|
||||
],
|
||||
multiSelect: false
|
||||
}
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
### Step 2: Auto-Detection (Supplement)
|
||||
|
||||
Automatically detect project characteristics:
|
||||
|
||||
```javascript
|
||||
// Detect from package.json
|
||||
const packageJson = Read('package.json');
|
||||
const softwareName = packageJson.name;
|
||||
const version = packageJson.version;
|
||||
const description = packageJson.description;
|
||||
|
||||
// Detect tech stack
|
||||
const hasReact = packageJson.dependencies?.react;
|
||||
const hasVue = packageJson.dependencies?.vue;
|
||||
const hasExpress = packageJson.dependencies?.express;
|
||||
const hasNestJS = packageJson.dependencies?.['@nestjs/core'];
|
||||
|
||||
// Detect CLI
|
||||
const hasBin = !!packageJson.bin;
|
||||
|
||||
// Detect UI
|
||||
const hasPages = Glob('src/pages/**/*').length > 0 || Glob('pages/**/*').length > 0;
|
||||
const hasRoutes = Glob('**/routes.*').length > 0;
|
||||
```
|
||||
|
||||
### Step 3: Generate Configuration
|
||||
|
||||
Create `manual-config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"software": {
|
||||
"name": "{{detected or user input}}",
|
||||
"version": "{{from package.json}}",
|
||||
"description": "{{from package.json}}",
|
||||
"type": "{{web|cli|sdk|desktop}}"
|
||||
},
|
||||
"target_audience": "{{end_users|developers|admins|all}}",
|
||||
"doc_scope": "{{quick_start|user_guide|api_reference|comprehensive}}",
|
||||
"example_levels": ["beginner", "intermediate", "advanced"],
|
||||
"tech_stack": {
|
||||
"frontend": "{{react|vue|angular|vanilla}}",
|
||||
"backend": "{{express|nestjs|fastify|none}}",
|
||||
"language": "{{typescript|javascript}}",
|
||||
"ui_framework": "{{tailwind|mui|antd|none}}"
|
||||
},
|
||||
"features": {
|
||||
"has_ui": true,
|
||||
"has_api": true,
|
||||
"has_cli": false,
|
||||
"has_config": true
|
||||
},
|
||||
"agents_to_run": [
|
||||
"overview",
|
||||
"ui-guide",
|
||||
"api-docs",
|
||||
"config",
|
||||
"troubleshooting",
|
||||
"code-examples"
|
||||
],
|
||||
"screenshot_config": {
|
||||
"enabled": true,
|
||||
"dev_command": "npm run dev",
|
||||
"dev_url": "http://localhost:3000",
|
||||
"wait_timeout": 5000
|
||||
},
|
||||
"output": {
|
||||
"filename": "{{name}}-使用手册.html",
|
||||
"theme": "light",
|
||||
"language": "zh-CN"
|
||||
},
|
||||
"timestamp": "{{ISO8601}}"
|
||||
}
|
||||
```
|
||||
|
||||
## Agent Selection Logic
|
||||
|
||||
Based on `doc_scope`, select agents to run:
|
||||
|
||||
| Scope | Agents |
|
||||
|-------|--------|
|
||||
| quick_start | overview |
|
||||
| user_guide | overview, ui-guide, config, troubleshooting |
|
||||
| api_reference | overview, api-docs, code-examples |
|
||||
| comprehensive | ALL 6 agents |
|
||||
|
||||
## Output
|
||||
|
||||
- **File**: `manual-config.json`
|
||||
- **Location**: `.workflow/.scratchpad/manual-{timestamp}/`
|
||||
|
||||
## Next Phase
|
||||
|
||||
Proceed to [Phase 2: Project Exploration](02-project-exploration.md) with the generated configuration.
|
||||
101
.claude/skills/software-manual/phases/02-project-exploration.md
Normal file
101
.claude/skills/software-manual/phases/02-project-exploration.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# Phase 2: Project Exploration
|
||||
|
||||
使用 `cli-explore-agent` 探索项目结构,生成文档所需的结构化数据。
|
||||
|
||||
## 探索角度
|
||||
|
||||
```javascript
|
||||
const EXPLORATION_ANGLES = {
|
||||
web: ['architecture', 'ui-routes', 'api-endpoints', 'config'],
|
||||
cli: ['architecture', 'commands', 'config'],
|
||||
sdk: ['architecture', 'public-api', 'types', 'config'],
|
||||
desktop: ['architecture', 'ui-screens', 'config']
|
||||
};
|
||||
```
|
||||
|
||||
## 执行流程
|
||||
|
||||
```javascript
|
||||
const config = JSON.parse(Read(`${workDir}/manual-config.json`));
|
||||
const angles = EXPLORATION_ANGLES[config.software.type];
|
||||
|
||||
// 并行探索
|
||||
const tasks = angles.map(angle => Task({
|
||||
subagent_type: 'cli-explore-agent',
|
||||
run_in_background: false,
|
||||
prompt: buildExplorationPrompt(angle, config, workDir)
|
||||
}));
|
||||
|
||||
const results = await Promise.all(tasks);
|
||||
```
|
||||
|
||||
## 探索配置
|
||||
|
||||
```javascript
|
||||
const EXPLORATION_CONFIGS = {
|
||||
architecture: {
|
||||
task: '分析项目模块结构、入口点、依赖关系',
|
||||
patterns: ['src/*/', 'package.json', 'tsconfig.json'],
|
||||
output: 'exploration-architecture.json'
|
||||
},
|
||||
'ui-routes': {
|
||||
task: '提取 UI 路由、页面组件、导航结构',
|
||||
patterns: ['src/pages/**', 'src/views/**', 'app/**/page.*', 'src/router/**'],
|
||||
output: 'exploration-ui-routes.json'
|
||||
},
|
||||
'api-endpoints': {
|
||||
task: '提取 REST API 端点、请求/响应类型',
|
||||
patterns: ['src/**/*.controller.*', 'src/routes/**', 'openapi.*', 'swagger.*'],
|
||||
output: 'exploration-api-endpoints.json'
|
||||
},
|
||||
config: {
|
||||
task: '提取环境变量、配置文件选项',
|
||||
patterns: ['.env.example', 'config/**', 'docker-compose.yml'],
|
||||
output: 'exploration-config.json'
|
||||
},
|
||||
commands: {
|
||||
task: '提取 CLI 命令、选项、示例',
|
||||
patterns: ['src/cli*', 'bin/*', 'src/commands/**'],
|
||||
output: 'exploration-commands.json'
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## Prompt 构建
|
||||
|
||||
```javascript
|
||||
function buildExplorationPrompt(angle, config, workDir) {
|
||||
const cfg = EXPLORATION_CONFIGS[angle];
|
||||
return `
|
||||
[TASK]
|
||||
${cfg.task}
|
||||
|
||||
[SCOPE]
|
||||
项目类型: ${config.software.type}
|
||||
扫描模式: deep-scan
|
||||
文件模式: ${cfg.patterns.join(', ')}
|
||||
|
||||
[OUTPUT]
|
||||
文件: ${workDir}/exploration/${cfg.output}
|
||||
格式: JSON (schema-compliant)
|
||||
|
||||
[RETURN]
|
||||
简要说明发现的内容数量和关键发现
|
||||
`;
|
||||
}
|
||||
```
|
||||
|
||||
## 输出结构
|
||||
|
||||
```
|
||||
exploration/
|
||||
├── exploration-architecture.json # 模块结构
|
||||
├── exploration-ui-routes.json # UI 路由
|
||||
├── exploration-api-endpoints.json # API 端点
|
||||
├── exploration-config.json # 配置选项
|
||||
└── exploration-commands.json # CLI 命令 (if CLI)
|
||||
```
|
||||
|
||||
## 下一阶段
|
||||
|
||||
→ [Phase 3: Parallel Analysis](03-parallel-analysis.md)
|
||||
130
.claude/skills/software-manual/phases/03-parallel-analysis.md
Normal file
130
.claude/skills/software-manual/phases/03-parallel-analysis.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# Phase 3: Parallel Analysis
|
||||
|
||||
使用 `universal-executor` 并行生成 6 个文档章节。
|
||||
|
||||
## Agent 配置
|
||||
|
||||
```javascript
|
||||
const AGENT_CONFIGS = {
|
||||
overview: {
|
||||
role: 'Product Manager',
|
||||
output: 'section-overview.md',
|
||||
task: '撰写产品概览、核心功能、快速入门指南',
|
||||
focus: '产品定位、目标用户、5步快速入门、系统要求',
|
||||
input: ['exploration-architecture.json', 'README.md', 'package.json']
|
||||
},
|
||||
'ui-guide': {
|
||||
role: 'UX Expert',
|
||||
output: 'section-ui-guide.md',
|
||||
task: '撰写界面操作指南,分步骤说明各功能使用方法',
|
||||
focus: '界面布局、导航流程、功能操作、快捷键',
|
||||
input: ['exploration-ui-routes.json', 'pages/**', 'views/**']
|
||||
},
|
||||
'api-docs': {
|
||||
role: 'API Architect',
|
||||
output: 'section-api-reference.md',
|
||||
task: '撰写 REST API 和前端 API 参考文档',
|
||||
focus: 'API 概览、端点分类、请求/响应示例、错误码',
|
||||
input: ['exploration-api-endpoints.json', 'controllers/**', 'routes/**']
|
||||
},
|
||||
config: {
|
||||
role: 'DevOps Engineer',
|
||||
output: 'section-configuration.md',
|
||||
task: '撰写配置指南,涵盖环境变量、配置文件、部署设置',
|
||||
focus: '环境变量表格、配置文件格式、部署选项、安全设置',
|
||||
input: ['exploration-config.json', '.env.example', 'config/**']
|
||||
},
|
||||
troubleshooting: {
|
||||
role: 'Support Engineer',
|
||||
output: 'section-troubleshooting.md',
|
||||
task: '撰写故障排查指南,涵盖常见问题、错误码、FAQ',
|
||||
focus: '常见问题与解决方案、错误码参考、FAQ、获取帮助',
|
||||
input: ['all exploration files', 'error handling code']
|
||||
},
|
||||
'code-examples': {
|
||||
role: 'Developer Advocate',
|
||||
output: 'section-examples.md',
|
||||
task: '撰写多难度级别代码示例(入门40%/进阶40%/高级20%)',
|
||||
focus: '完整可运行代码、分步解释、预期输出、最佳实践',
|
||||
input: ['all exploration files', 'examples/**', 'tests/**']
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## 执行流程
|
||||
|
||||
```javascript
|
||||
const config = JSON.parse(Read(`${workDir}/manual-config.json`));
|
||||
|
||||
// 并行启动 6 个 universal-executor
|
||||
const tasks = Object.entries(AGENT_CONFIGS).map(([name, cfg]) =>
|
||||
Task({
|
||||
subagent_type: 'universal-executor',
|
||||
run_in_background: false,
|
||||
prompt: buildAgentPrompt(name, cfg, config, workDir)
|
||||
})
|
||||
);
|
||||
|
||||
const results = await Promise.all(tasks);
|
||||
```
|
||||
|
||||
## Prompt 构建
|
||||
|
||||
```javascript
|
||||
function buildAgentPrompt(name, cfg, config, workDir) {
|
||||
return `
|
||||
[ROLE] ${cfg.role}
|
||||
|
||||
[TASK]
|
||||
${cfg.task}
|
||||
输出: ${workDir}/sections/${cfg.output}
|
||||
|
||||
[INPUT]
|
||||
- Read: ${workDir}/manual-config.json
|
||||
- Read: ${cfg.input.map(f => `${workDir}/exploration/${f}`).join(', ')}
|
||||
|
||||
[STYLE]
|
||||
- 用户友好语言,避免技术术语
|
||||
- 步骤编号清晰
|
||||
- 代码块标注语言
|
||||
- 截图标记: <!-- SCREENSHOT: id="ss-xxx" url="/path" description="xxx" -->
|
||||
|
||||
[FOCUS]
|
||||
${cfg.focus}
|
||||
|
||||
[RETURN JSON]
|
||||
{
|
||||
"status": "completed",
|
||||
"output_file": "sections/${cfg.output}",
|
||||
"summary": "<50字>",
|
||||
"screenshots_needed": [],
|
||||
"cross_references": []
|
||||
}
|
||||
`;
|
||||
}
|
||||
```
|
||||
|
||||
## 结果收集
|
||||
|
||||
```javascript
|
||||
const agentResults = results.map(r => JSON.parse(r));
|
||||
const allScreenshots = agentResults.flatMap(r => r.screenshots_needed);
|
||||
|
||||
Write(`${workDir}/agent-results.json`, JSON.stringify({
|
||||
results: agentResults,
|
||||
screenshots_needed: allScreenshots,
|
||||
timestamp: new Date().toISOString()
|
||||
}, null, 2));
|
||||
```
|
||||
|
||||
## 质量检查
|
||||
|
||||
- [ ] Markdown 语法有效
|
||||
- [ ] 无占位符文本
|
||||
- [ ] 代码块标注语言
|
||||
- [ ] 截图标记格式正确
|
||||
- [ ] 交叉引用有效
|
||||
|
||||
## 下一阶段
|
||||
|
||||
→ [Phase 3.5: Consolidation](03.5-consolidation.md)
|
||||
82
.claude/skills/software-manual/phases/03.5-consolidation.md
Normal file
82
.claude/skills/software-manual/phases/03.5-consolidation.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Phase 3.5: Consolidation
|
||||
|
||||
使用 `universal-executor` 子 Agent 执行质量检查,避免主 Agent 内存溢出。
|
||||
|
||||
## 核心原则
|
||||
|
||||
**主 Agent 负责编排,子 Agent 负责繁重计算。**
|
||||
|
||||
## 执行流程
|
||||
|
||||
```javascript
|
||||
const agentResults = JSON.parse(Read(`${workDir}/agent-results.json`));
|
||||
|
||||
// 委托给 universal-executor 执行整合检查
|
||||
const result = Task({
|
||||
subagent_type: 'universal-executor',
|
||||
run_in_background: false,
|
||||
prompt: buildConsolidationPrompt(workDir)
|
||||
});
|
||||
|
||||
const consolidationResult = JSON.parse(result);
|
||||
```
|
||||
|
||||
## Prompt 构建
|
||||
|
||||
```javascript
|
||||
function buildConsolidationPrompt(workDir) {
|
||||
return `
|
||||
[ROLE] Quality Analyst
|
||||
|
||||
[TASK]
|
||||
检查所有章节的一致性和完整性
|
||||
|
||||
[INPUT]
|
||||
- 章节文件: ${workDir}/sections/section-*.md
|
||||
- Agent 结果: ${workDir}/agent-results.json
|
||||
|
||||
[CHECKS]
|
||||
1. Markdown 语法有效性
|
||||
2. 截图标记格式 (<!-- SCREENSHOT: id="..." -->)
|
||||
3. 交叉引用有效性
|
||||
4. 术语一致性
|
||||
5. 代码块语言标注
|
||||
|
||||
[OUTPUT]
|
||||
1. 写入 ${workDir}/consolidation-summary.md
|
||||
2. 写入 ${workDir}/screenshots-list.json (截图清单)
|
||||
|
||||
[RETURN JSON]
|
||||
{
|
||||
"status": "completed",
|
||||
"sections_checked": <n>,
|
||||
"screenshots_found": <n>,
|
||||
"issues": { "errors": <n>, "warnings": <n> },
|
||||
"quality_score": <0-100>
|
||||
}
|
||||
`;
|
||||
}
|
||||
```
|
||||
|
||||
## Agent 职责
|
||||
|
||||
1. **读取章节** → 逐个检查 section-*.md
|
||||
2. **提取截图** → 收集所有截图标记
|
||||
3. **验证引用** → 检查交叉引用有效性
|
||||
4. **评估质量** → 计算综合分数
|
||||
5. **输出报告** → consolidation-summary.md
|
||||
|
||||
## 输出
|
||||
|
||||
- `consolidation-summary.md` - 质量报告
|
||||
- `screenshots-list.json` - 截图清单(供 Phase 4 使用)
|
||||
|
||||
## 质量门禁
|
||||
|
||||
- [ ] 无错误
|
||||
- [ ] 总分 >= 60%
|
||||
- [ ] 交叉引用有效
|
||||
|
||||
## 下一阶段
|
||||
|
||||
→ [Phase 4: Screenshot Capture](04-screenshot-capture.md)
|
||||
271
.claude/skills/software-manual/phases/04-screenshot-capture.md
Normal file
271
.claude/skills/software-manual/phases/04-screenshot-capture.md
Normal file
@@ -0,0 +1,271 @@
|
||||
# Phase 4: Screenshot Capture
|
||||
|
||||
Capture screenshots using Chrome MCP for all identified UI elements.
|
||||
|
||||
## Objective
|
||||
|
||||
- Check Chrome MCP availability
|
||||
- Start development server
|
||||
- Capture all required screenshots
|
||||
- Convert to Base64 for embedding
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Chrome MCP configured and available
|
||||
- Development server can be started
|
||||
- All screenshot URLs accessible
|
||||
|
||||
## Execution Steps
|
||||
|
||||
### Step 1: Load Screenshot List
|
||||
|
||||
```javascript
|
||||
const consolidation = Read(`${workDir}/consolidation-summary.md`);
|
||||
const config = JSON.parse(Read(`${workDir}/manual-config.json`));
|
||||
|
||||
// Parse screenshot table from consolidation
|
||||
const screenshots = parseScreenshotTable(consolidation);
|
||||
```
|
||||
|
||||
### Step 2: Check Chrome MCP Availability
|
||||
|
||||
```javascript
|
||||
async function checkChromeMCP() {
|
||||
try {
|
||||
// Attempt to call Chrome MCP
|
||||
const version = await mcp__chrome__getVersion();
|
||||
return {
|
||||
available: true,
|
||||
version: version.version,
|
||||
browser: version.browser
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
available: false,
|
||||
error: error.message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const chromeMCP = await checkChromeMCP();
|
||||
|
||||
if (!chromeMCP.available) {
|
||||
// Fallback: generate manual screenshot instructions
|
||||
generateManualScreenshotGuide(screenshots);
|
||||
return {
|
||||
status: 'skipped',
|
||||
reason: 'Chrome MCP not available',
|
||||
manual_guide: `${workDir}/screenshots/MANUAL_CAPTURE.md`
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Step 3: Start Development Server
|
||||
|
||||
```javascript
|
||||
const devConfig = config.screenshot_config;
|
||||
|
||||
// Start dev server in background
|
||||
const serverTask = Bash({
|
||||
command: devConfig.dev_command,
|
||||
run_in_background: true
|
||||
});
|
||||
|
||||
// Wait for server to be ready
|
||||
async function waitForServer(url, timeout = 30000) {
|
||||
const start = Date.now();
|
||||
while (Date.now() - start < timeout) {
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
if (response.ok) return true;
|
||||
} catch (e) {
|
||||
// Server not ready yet
|
||||
}
|
||||
await sleep(1000);
|
||||
}
|
||||
throw new Error(`Server at ${url} did not start within ${timeout}ms`);
|
||||
}
|
||||
|
||||
await waitForServer(devConfig.dev_url, devConfig.wait_timeout);
|
||||
```
|
||||
|
||||
### Step 4: Batch Screenshot Capture
|
||||
|
||||
```javascript
|
||||
const capturedScreenshots = [];
|
||||
const failedScreenshots = [];
|
||||
|
||||
for (const ss of screenshots) {
|
||||
try {
|
||||
const fullUrl = new URL(ss.url, devConfig.dev_url).href;
|
||||
|
||||
// Configure capture options
|
||||
const captureOptions = {
|
||||
url: fullUrl,
|
||||
viewport: { width: 1280, height: 800 },
|
||||
fullPage: ss.fullPage || false,
|
||||
waitFor: ss.wait_for || null,
|
||||
delay: 500 // Wait for animations
|
||||
};
|
||||
|
||||
// Add selector for partial screenshot
|
||||
if (ss.selector) {
|
||||
captureOptions.selector = ss.selector;
|
||||
}
|
||||
|
||||
// Capture screenshot
|
||||
const result = await mcp__chrome__screenshot(captureOptions);
|
||||
|
||||
// Save screenshot
|
||||
const filename = `${ss.id}.png`;
|
||||
Write(`${workDir}/screenshots/${filename}`, result.data, { encoding: 'base64' });
|
||||
|
||||
capturedScreenshots.push({
|
||||
...ss,
|
||||
file: filename,
|
||||
base64_size: result.data.length,
|
||||
captured_at: new Date().toISOString()
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
failedScreenshots.push({
|
||||
...ss,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 5: Generate Screenshot Manifest
|
||||
|
||||
```javascript
|
||||
const manifest = {
|
||||
total: screenshots.length,
|
||||
captured: capturedScreenshots.length,
|
||||
failed: failedScreenshots.length,
|
||||
screenshots: capturedScreenshots,
|
||||
failures: failedScreenshots,
|
||||
dev_server: {
|
||||
url: devConfig.dev_url,
|
||||
command: devConfig.dev_command
|
||||
},
|
||||
capture_config: {
|
||||
viewport: { width: 1280, height: 800 },
|
||||
format: 'png'
|
||||
},
|
||||
timestamp: new Date().toISOString()
|
||||
};
|
||||
|
||||
Write(`${workDir}/screenshots/screenshots-manifest.json`, JSON.stringify(manifest, null, 2));
|
||||
```
|
||||
|
||||
### Step 6: Stop Development Server
|
||||
|
||||
```javascript
|
||||
// Kill the dev server process
|
||||
KillShell({ shell_id: serverTask.task_id });
|
||||
```
|
||||
|
||||
### Step 7: Handle Failures
|
||||
|
||||
If any screenshots failed:
|
||||
|
||||
```javascript
|
||||
if (failedScreenshots.length > 0) {
|
||||
// Generate manual capture instructions
|
||||
const manualGuide = `
|
||||
# Manual Screenshot Capture Required
|
||||
|
||||
The following screenshots could not be captured automatically:
|
||||
|
||||
${failedScreenshots.map(s => `
|
||||
## ${s.id}
|
||||
- **URL**: ${s.url}
|
||||
- **Description**: ${s.description}
|
||||
- **Error**: ${s.error}
|
||||
|
||||
**Instructions**:
|
||||
1. Navigate to ${s.url}
|
||||
2. Capture screenshot of ${s.selector || 'full page'}
|
||||
3. Save as \`${s.id}.png\`
|
||||
4. Place in \`screenshots/\` directory
|
||||
`).join('\n')}
|
||||
`;
|
||||
|
||||
Write(`${workDir}/screenshots/MANUAL_CAPTURE.md`, manualGuide);
|
||||
}
|
||||
```
|
||||
|
||||
## Fallback: Manual Screenshot Mode
|
||||
|
||||
When Chrome MCP is not available:
|
||||
|
||||
```javascript
|
||||
function generateManualScreenshotGuide(screenshots) {
|
||||
const guide = `
|
||||
# Manual Screenshot Capture Guide
|
||||
|
||||
Chrome MCP is not available. Please capture screenshots manually.
|
||||
|
||||
## Setup
|
||||
|
||||
1. Start your development server:
|
||||
\`\`\`bash
|
||||
${config.screenshot_config.dev_command}
|
||||
\`\`\`
|
||||
|
||||
2. Open browser to: ${config.screenshot_config.dev_url}
|
||||
|
||||
## Screenshots Required
|
||||
|
||||
${screenshots.map((s, i) => `
|
||||
### ${i + 1}. ${s.id}
|
||||
- **URL**: ${s.url}
|
||||
- **Description**: ${s.description}
|
||||
- **Save as**: \`screenshots/${s.id}.png\`
|
||||
${s.selector ? `- **Element**: Capture only \`${s.selector}\`` : '- **Type**: Full page'}
|
||||
`).join('\n')}
|
||||
|
||||
## After Capturing
|
||||
|
||||
Place all PNG files in the \`screenshots/\` directory, then run Phase 5 to continue.
|
||||
`;
|
||||
|
||||
Write(`${workDir}/screenshots/MANUAL_CAPTURE.md`, guide);
|
||||
}
|
||||
```
|
||||
|
||||
## Chrome MCP Configuration Reference
|
||||
|
||||
Expected MCP configuration:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"chrome": {
|
||||
"command": "npx",
|
||||
"args": ["@anthropic-ai/mcp-chrome"],
|
||||
"env": {
|
||||
"CHROME_PATH": "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
- **Files**: `screenshots/*.png`
|
||||
- **Manifest**: `screenshots/screenshots-manifest.json`
|
||||
- **Fallback**: `screenshots/MANUAL_CAPTURE.md` (if needed)
|
||||
|
||||
## Quality Checks
|
||||
|
||||
- [ ] All high-priority screenshots captured
|
||||
- [ ] Screenshot dimensions consistent (1280x800)
|
||||
- [ ] No broken/blank screenshots
|
||||
- [ ] Manifest file complete
|
||||
|
||||
## Next Phase
|
||||
|
||||
Proceed to [Phase 5: HTML Assembly](05-html-assembly.md) with captured screenshots.
|
||||
120
.claude/skills/software-manual/phases/05-html-assembly.md
Normal file
120
.claude/skills/software-manual/phases/05-html-assembly.md
Normal file
@@ -0,0 +1,120 @@
|
||||
# Phase 5: HTML Assembly
|
||||
|
||||
使用 `universal-executor` 子 Agent 生成最终 HTML,避免主 Agent 内存溢出。
|
||||
|
||||
## 核心原则
|
||||
|
||||
**主 Agent 负责编排,子 Agent 负责繁重计算。**
|
||||
|
||||
## 执行流程
|
||||
|
||||
```javascript
|
||||
const config = JSON.parse(Read(`${workDir}/manual-config.json`));
|
||||
|
||||
// 委托给 universal-executor 执行 HTML 组装
|
||||
const result = Task({
|
||||
subagent_type: 'universal-executor',
|
||||
run_in_background: false,
|
||||
prompt: buildAssemblyPrompt(config, workDir)
|
||||
});
|
||||
|
||||
const buildResult = JSON.parse(result);
|
||||
```
|
||||
|
||||
## Prompt 构建
|
||||
|
||||
```javascript
|
||||
function buildAssemblyPrompt(config, workDir) {
|
||||
return `
|
||||
[ROLE] HTML Assembler
|
||||
|
||||
[TASK]
|
||||
生成 TiddlyWiki 风格的交互式 HTML 手册
|
||||
|
||||
[INPUT]
|
||||
- 模板: .claude/skills/software-manual/templates/tiddlywiki-shell.html
|
||||
- CSS: .claude/skills/software-manual/templates/css/wiki-base.css, wiki-dark.css
|
||||
- 配置: ${workDir}/manual-config.json
|
||||
- 章节: ${workDir}/sections/section-*.md
|
||||
- 截图: ${workDir}/screenshots/
|
||||
|
||||
[STEPS]
|
||||
1. 读取 HTML 模板和 CSS
|
||||
2. 逐个读取 section-*.md,转换为 HTML tiddlers
|
||||
3. 处理 <!-- SCREENSHOT: id="..." --> 标记,嵌入 Base64 图片
|
||||
4. 生成目录、搜索索引
|
||||
5. 组装最终 HTML,写入 ${workDir}/${config.software.name}-使用手册.html
|
||||
6. 生成构建报告 ${workDir}/build-report.json
|
||||
|
||||
[HTML FEATURES]
|
||||
- 搜索: 全文检索 + 高亮
|
||||
- 折叠: 章节可展开/收起
|
||||
- 标签: 分类过滤
|
||||
- 主题: 亮/暗模式切换
|
||||
- 离线: 所有资源内嵌
|
||||
|
||||
[RETURN JSON]
|
||||
{
|
||||
"status": "completed",
|
||||
"output_file": "${config.software.name}-使用手册.html",
|
||||
"file_size": "<size>",
|
||||
"sections_count": <n>,
|
||||
"screenshots_embedded": <n>
|
||||
}
|
||||
`;
|
||||
}
|
||||
```
|
||||
|
||||
## Agent 职责
|
||||
|
||||
1. **读取模板** → HTML + CSS
|
||||
2. **转换章节** → Markdown → HTML tiddlers
|
||||
3. **嵌入截图** → Base64 编码
|
||||
4. **生成索引** → 搜索数据
|
||||
5. **组装输出** → 单文件 HTML
|
||||
|
||||
## Markdown 转换规则
|
||||
|
||||
Agent 内部实现:
|
||||
|
||||
```
|
||||
# H1 → <h1>
|
||||
## H2 → <h2>
|
||||
### H3 → <h3>
|
||||
```code``` → <pre><code>
|
||||
**bold** → <strong>
|
||||
*italic* → <em>
|
||||
[text](url) → <a href>
|
||||
- item → <li>
|
||||
<!-- SCREENSHOT: id="xxx" --> → <figure><img src="data:..."></figure>
|
||||
```
|
||||
|
||||
## Tiddler 结构
|
||||
|
||||
```html
|
||||
<article class="tiddler" id="tiddler-{name}" data-tags="..." data-difficulty="...">
|
||||
<header class="tiddler-header">
|
||||
<h2><button class="collapse-toggle">▼</button> {title}</h2>
|
||||
<div class="tiddler-meta">{badges}</div>
|
||||
</header>
|
||||
<div class="tiddler-content">{html}</div>
|
||||
</article>
|
||||
```
|
||||
|
||||
## 输出
|
||||
|
||||
- `{软件名}-使用手册.html` - 最终 HTML
|
||||
- `build-report.json` - 构建报告
|
||||
|
||||
## 质量门禁
|
||||
|
||||
- [ ] HTML 渲染正确
|
||||
- [ ] 搜索功能可用
|
||||
- [ ] 折叠/展开正常
|
||||
- [ ] 主题切换持久化
|
||||
- [ ] 截图显示正确
|
||||
- [ ] 文件大小 < 10MB
|
||||
|
||||
## 下一阶段
|
||||
|
||||
→ [Phase 6: Iterative Refinement](06-iterative-refinement.md)
|
||||
259
.claude/skills/software-manual/phases/06-iterative-refinement.md
Normal file
259
.claude/skills/software-manual/phases/06-iterative-refinement.md
Normal file
@@ -0,0 +1,259 @@
|
||||
# Phase 6: Iterative Refinement
|
||||
|
||||
Preview, collect feedback, and iterate until quality meets standards.
|
||||
|
||||
## Objective
|
||||
|
||||
- Preview generated HTML in browser
|
||||
- Collect user feedback
|
||||
- Address issues iteratively
|
||||
- Finalize documentation
|
||||
|
||||
## Execution Steps
|
||||
|
||||
### Step 1: Preview HTML
|
||||
|
||||
```javascript
|
||||
const buildReport = JSON.parse(Read(`${workDir}/build-report.json`));
|
||||
const outputFile = `${workDir}/${buildReport.output}`;
|
||||
|
||||
// Open in default browser for preview
|
||||
Bash({ command: `start "${outputFile}"` }); // Windows
|
||||
// Bash({ command: `open "${outputFile}"` }); // macOS
|
||||
|
||||
// Report to user
|
||||
console.log(`
|
||||
📖 Manual Preview
|
||||
|
||||
File: ${buildReport.output}
|
||||
Size: ${buildReport.size_human}
|
||||
Sections: ${buildReport.sections}
|
||||
Screenshots: ${buildReport.screenshots}
|
||||
|
||||
Please review the manual in your browser.
|
||||
`);
|
||||
```
|
||||
|
||||
### Step 2: Collect Feedback
|
||||
|
||||
```javascript
|
||||
const feedback = await AskUserQuestion({
|
||||
questions: [
|
||||
{
|
||||
question: "How does the manual look overall?",
|
||||
header: "Overall",
|
||||
options: [
|
||||
{ label: "Looks great!", description: "Ready to finalize" },
|
||||
{ label: "Minor issues", description: "Small tweaks needed" },
|
||||
{ label: "Major issues", description: "Significant changes required" },
|
||||
{ label: "Missing content", description: "Need to add more sections" }
|
||||
],
|
||||
multiSelect: false
|
||||
},
|
||||
{
|
||||
question: "Which aspects need improvement? (Select all that apply)",
|
||||
header: "Improvements",
|
||||
options: [
|
||||
{ label: "Content accuracy", description: "Fix incorrect information" },
|
||||
{ label: "More examples", description: "Add more code examples" },
|
||||
{ label: "Better screenshots", description: "Retake or add screenshots" },
|
||||
{ label: "Styling/Layout", description: "Improve visual appearance" }
|
||||
],
|
||||
multiSelect: true
|
||||
}
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
### Step 3: Address Feedback
|
||||
|
||||
Based on feedback, take appropriate action:
|
||||
|
||||
#### Minor Issues
|
||||
|
||||
```javascript
|
||||
if (feedback.overall === "Minor issues") {
|
||||
// Prompt for specific changes
|
||||
const details = await AskUserQuestion({
|
||||
questions: [{
|
||||
question: "What specific changes are needed?",
|
||||
header: "Details",
|
||||
options: [
|
||||
{ label: "Typo fixes", description: "Fix spelling/grammar" },
|
||||
{ label: "Reorder sections", description: "Change section order" },
|
||||
{ label: "Update content", description: "Modify existing text" },
|
||||
{ label: "Custom changes", description: "I'll describe the changes" }
|
||||
],
|
||||
multiSelect: true
|
||||
}]
|
||||
});
|
||||
|
||||
// Apply changes based on user input
|
||||
applyMinorChanges(details);
|
||||
}
|
||||
```
|
||||
|
||||
#### Major Issues
|
||||
|
||||
```javascript
|
||||
if (feedback.overall === "Major issues") {
|
||||
// Return to relevant phase
|
||||
console.log(`
|
||||
Major issues require returning to an earlier phase:
|
||||
|
||||
- Content issues → Phase 3 (Parallel Analysis)
|
||||
- Screenshot issues → Phase 4 (Screenshot Capture)
|
||||
- Structure issues → Phase 2 (Project Exploration)
|
||||
|
||||
Which phase should we return to?
|
||||
`);
|
||||
|
||||
const phase = await selectPhase();
|
||||
return { action: 'restart', from_phase: phase };
|
||||
}
|
||||
```
|
||||
|
||||
#### Missing Content
|
||||
|
||||
```javascript
|
||||
if (feedback.overall === "Missing content") {
|
||||
// Identify missing sections
|
||||
const missing = await AskUserQuestion({
|
||||
questions: [{
|
||||
question: "What content is missing?",
|
||||
header: "Missing",
|
||||
options: [
|
||||
{ label: "API endpoints", description: "More API documentation" },
|
||||
{ label: "UI features", description: "Additional UI guides" },
|
||||
{ label: "Examples", description: "More code examples" },
|
||||
{ label: "Troubleshooting", description: "More FAQ items" }
|
||||
],
|
||||
multiSelect: true
|
||||
}]
|
||||
});
|
||||
|
||||
// Run additional agent(s) for missing content
|
||||
await runSupplementaryAgents(missing);
|
||||
}
|
||||
```
|
||||
|
||||
### Step 4: Save Iteration
|
||||
|
||||
```javascript
|
||||
// Save current version before changes
|
||||
const iterationNum = getNextIterationNumber(workDir);
|
||||
const iterationDir = `${workDir}/iterations`;
|
||||
|
||||
// Copy current version
|
||||
Bash({ command: `copy "${outputFile}" "${iterationDir}\\v${iterationNum}.html"` });
|
||||
|
||||
// Log iteration
|
||||
const iterationLog = {
|
||||
version: iterationNum,
|
||||
timestamp: new Date().toISOString(),
|
||||
feedback: feedback,
|
||||
changes: appliedChanges
|
||||
};
|
||||
|
||||
Write(`${iterationDir}/iteration-${iterationNum}.json`, JSON.stringify(iterationLog, null, 2));
|
||||
```
|
||||
|
||||
### Step 5: Regenerate if Needed
|
||||
|
||||
```javascript
|
||||
if (changesApplied) {
|
||||
// Re-run HTML assembly with updated sections
|
||||
await runPhase('05-html-assembly');
|
||||
|
||||
// Open updated preview
|
||||
Bash({ command: `start "${outputFile}"` });
|
||||
}
|
||||
```
|
||||
|
||||
### Step 6: Finalize
|
||||
|
||||
When user approves:
|
||||
|
||||
```javascript
|
||||
if (feedback.overall === "Looks great!") {
|
||||
// Final quality check
|
||||
const finalReport = {
|
||||
...buildReport,
|
||||
iterations: iterationNum,
|
||||
finalized_at: new Date().toISOString(),
|
||||
quality_score: calculateFinalQuality()
|
||||
};
|
||||
|
||||
Write(`${workDir}/final-report.json`, JSON.stringify(finalReport, null, 2));
|
||||
|
||||
// Suggest final location
|
||||
console.log(`
|
||||
✅ Manual Finalized!
|
||||
|
||||
Output: ${buildReport.output}
|
||||
Size: ${buildReport.size_human}
|
||||
Quality: ${finalReport.quality_score}%
|
||||
Iterations: ${iterationNum}
|
||||
|
||||
Suggested actions:
|
||||
1. Copy to project root: copy "${outputFile}" "docs/"
|
||||
2. Add to version control
|
||||
3. Publish to documentation site
|
||||
`);
|
||||
|
||||
return { status: 'completed', output: outputFile };
|
||||
}
|
||||
```
|
||||
|
||||
## Iteration History
|
||||
|
||||
Each iteration is logged:
|
||||
|
||||
```
|
||||
iterations/
|
||||
├── v1.html # First version
|
||||
├── iteration-1.json # Feedback and changes
|
||||
├── v2.html # After first iteration
|
||||
├── iteration-2.json # Feedback and changes
|
||||
└── ...
|
||||
```
|
||||
|
||||
## Quality Metrics
|
||||
|
||||
Track improvement across iterations:
|
||||
|
||||
```javascript
|
||||
const qualityMetrics = {
|
||||
content_completeness: 0, // All sections present
|
||||
screenshot_coverage: 0, // Screenshots for all UI
|
||||
example_diversity: 0, // Different difficulty levels
|
||||
search_accuracy: 0, // Search returns relevant results
|
||||
user_satisfaction: 0 // Based on feedback
|
||||
};
|
||||
```
|
||||
|
||||
## Exit Conditions
|
||||
|
||||
The refinement phase ends when:
|
||||
1. User explicitly approves ("Looks great!")
|
||||
2. Maximum iterations reached (configurable, default: 5)
|
||||
3. Quality score exceeds threshold (default: 90%)
|
||||
|
||||
## Output
|
||||
|
||||
- **Final HTML**: `{软件名}-使用手册.html`
|
||||
- **Final Report**: `final-report.json`
|
||||
- **Iteration History**: `iterations/`
|
||||
|
||||
## Completion
|
||||
|
||||
When finalized, the skill is complete. Final output location:
|
||||
|
||||
```
|
||||
.workflow/.scratchpad/manual-{timestamp}/
|
||||
├── {软件名}-使用手册.html ← Final deliverable
|
||||
├── final-report.json
|
||||
└── iterations/
|
||||
```
|
||||
|
||||
Consider copying to a permanent location like `docs/` or project root.
|
||||
Reference in New Issue
Block a user