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:
catlog22
2025-12-28 17:21:07 +08:00
parent a2c88ba885
commit 7aa1cda367
28 changed files with 7730 additions and 2 deletions

View File

@@ -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.

View 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)

View 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)

View 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)

View 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.

View 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)

View 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.