@clawplays/ospec-cli 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.ospec/templates/hooks/post-merge +8 -0
- package/.ospec/templates/hooks/pre-commit +8 -0
- package/LICENSE +21 -0
- package/README.md +549 -0
- package/README.zh-CN.md +549 -0
- package/assets/for-ai/en-US/ai-guide.md +98 -0
- package/assets/for-ai/en-US/execution-protocol.md +64 -0
- package/assets/for-ai/zh-CN/ai-guide.md +102 -0
- package/assets/for-ai/zh-CN/execution-protocol.md +68 -0
- package/assets/git-hooks/post-merge +12 -0
- package/assets/git-hooks/pre-commit +12 -0
- package/assets/global-skills/claude/ospec-change/SKILL.md +116 -0
- package/assets/global-skills/codex/ospec-change/SKILL.md +117 -0
- package/assets/global-skills/codex/ospec-change/agents/openai.yaml +7 -0
- package/assets/global-skills/codex/ospec-change/skill.yaml +19 -0
- package/assets/project-conventions/en-US/development-guide.md +32 -0
- package/assets/project-conventions/en-US/naming-conventions.md +51 -0
- package/assets/project-conventions/en-US/skill-conventions.md +40 -0
- package/assets/project-conventions/en-US/workflow-conventions.md +70 -0
- package/assets/project-conventions/zh-CN/development-guide.md +32 -0
- package/assets/project-conventions/zh-CN/naming-conventions.md +51 -0
- package/assets/project-conventions/zh-CN/skill-conventions.md +40 -0
- package/assets/project-conventions/zh-CN/workflow-conventions.md +74 -0
- package/dist/adapters/codex-stitch-adapter.js +420 -0
- package/dist/adapters/gemini-stitch-adapter.js +408 -0
- package/dist/adapters/playwright-checkpoint-adapter.js +2260 -0
- package/dist/advanced/BatchOperations.d.ts +36 -0
- package/dist/advanced/BatchOperations.js +159 -0
- package/dist/advanced/CachingLayer.d.ts +66 -0
- package/dist/advanced/CachingLayer.js +136 -0
- package/dist/advanced/FeatureUpdater.d.ts +46 -0
- package/dist/advanced/FeatureUpdater.js +151 -0
- package/dist/advanced/PerformanceMonitor.d.ts +52 -0
- package/dist/advanced/PerformanceMonitor.js +129 -0
- package/dist/advanced/StatePersistence.d.ts +61 -0
- package/dist/advanced/StatePersistence.js +168 -0
- package/dist/advanced/index.d.ts +14 -0
- package/dist/advanced/index.js +22 -0
- package/dist/cli/commands/config.d.ts +5 -0
- package/dist/cli/commands/config.js +6 -0
- package/dist/cli/commands/feature.d.ts +5 -0
- package/dist/cli/commands/feature.js +6 -0
- package/dist/cli/commands/index.d.ts +5 -0
- package/dist/cli/commands/index.js +6 -0
- package/dist/cli/commands/project.d.ts +5 -0
- package/dist/cli/commands/project.js +6 -0
- package/dist/cli/commands/validate.d.ts +5 -0
- package/dist/cli/commands/validate.js +6 -0
- package/dist/cli/index.d.ts +5 -0
- package/dist/cli/index.js +6 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +1007 -0
- package/dist/commands/ArchiveCommand.d.ts +14 -0
- package/dist/commands/ArchiveCommand.js +241 -0
- package/dist/commands/BaseCommand.d.ts +33 -0
- package/dist/commands/BaseCommand.js +46 -0
- package/dist/commands/BatchCommand.d.ts +5 -0
- package/dist/commands/BatchCommand.js +42 -0
- package/dist/commands/ChangesCommand.d.ts +3 -0
- package/dist/commands/ChangesCommand.js +71 -0
- package/dist/commands/DocsCommand.d.ts +5 -0
- package/dist/commands/DocsCommand.js +118 -0
- package/dist/commands/FinalizeCommand.d.ts +3 -0
- package/dist/commands/FinalizeCommand.js +24 -0
- package/dist/commands/IndexCommand.d.ts +5 -0
- package/dist/commands/IndexCommand.js +57 -0
- package/dist/commands/InitCommand.d.ts +5 -0
- package/dist/commands/InitCommand.js +65 -0
- package/dist/commands/NewCommand.d.ts +11 -0
- package/dist/commands/NewCommand.js +262 -0
- package/dist/commands/PluginsCommand.d.ts +58 -0
- package/dist/commands/PluginsCommand.js +2491 -0
- package/dist/commands/ProgressCommand.d.ts +5 -0
- package/dist/commands/ProgressCommand.js +103 -0
- package/dist/commands/QueueCommand.d.ts +10 -0
- package/dist/commands/QueueCommand.js +147 -0
- package/dist/commands/RunCommand.d.ts +13 -0
- package/dist/commands/RunCommand.js +200 -0
- package/dist/commands/SkillCommand.d.ts +31 -0
- package/dist/commands/SkillCommand.js +1216 -0
- package/dist/commands/SkillsCommand.d.ts +5 -0
- package/dist/commands/SkillsCommand.js +68 -0
- package/dist/commands/StatusCommand.d.ts +6 -0
- package/dist/commands/StatusCommand.js +140 -0
- package/dist/commands/UpdateCommand.d.ts +8 -0
- package/dist/commands/UpdateCommand.js +251 -0
- package/dist/commands/VerifyCommand.d.ts +5 -0
- package/dist/commands/VerifyCommand.js +278 -0
- package/dist/commands/WorkflowCommand.d.ts +12 -0
- package/dist/commands/WorkflowCommand.js +150 -0
- package/dist/commands/index.d.ts +43 -0
- package/dist/commands/index.js +85 -0
- package/dist/core/constants.d.ts +41 -0
- package/dist/core/constants.js +73 -0
- package/dist/core/errors.d.ts +36 -0
- package/dist/core/errors.js +72 -0
- package/dist/core/index.d.ts +7 -0
- package/dist/core/index.js +23 -0
- package/dist/core/types.d.ts +369 -0
- package/dist/core/types.js +3 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +27 -0
- package/dist/presets/ProjectPresets.d.ts +41 -0
- package/dist/presets/ProjectPresets.js +190 -0
- package/dist/scaffolds/ProjectScaffoldPresets.d.ts +20 -0
- package/dist/scaffolds/ProjectScaffoldPresets.js +151 -0
- package/dist/services/ConfigManager.d.ts +14 -0
- package/dist/services/ConfigManager.js +386 -0
- package/dist/services/FeatureManager.d.ts +5 -0
- package/dist/services/FeatureManager.js +6 -0
- package/dist/services/FileService.d.ts +21 -0
- package/dist/services/FileService.js +152 -0
- package/dist/services/IndexBuilder.d.ts +12 -0
- package/dist/services/IndexBuilder.js +130 -0
- package/dist/services/Logger.d.ts +20 -0
- package/dist/services/Logger.js +48 -0
- package/dist/services/ProjectAssetRegistry.d.ts +12 -0
- package/dist/services/ProjectAssetRegistry.js +96 -0
- package/dist/services/ProjectAssetService.d.ts +49 -0
- package/dist/services/ProjectAssetService.js +223 -0
- package/dist/services/ProjectScaffoldCommandService.d.ts +73 -0
- package/dist/services/ProjectScaffoldCommandService.js +159 -0
- package/dist/services/ProjectScaffoldService.d.ts +44 -0
- package/dist/services/ProjectScaffoldService.js +507 -0
- package/dist/services/ProjectService.d.ts +209 -0
- package/dist/services/ProjectService.js +13239 -0
- package/dist/services/QueueService.d.ts +17 -0
- package/dist/services/QueueService.js +142 -0
- package/dist/services/RunService.d.ts +40 -0
- package/dist/services/RunService.js +420 -0
- package/dist/services/SkillParser.d.ts +30 -0
- package/dist/services/SkillParser.js +88 -0
- package/dist/services/StateManager.d.ts +16 -0
- package/dist/services/StateManager.js +127 -0
- package/dist/services/TemplateEngine.d.ts +43 -0
- package/dist/services/TemplateEngine.js +119 -0
- package/dist/services/TemplateGenerator.d.ts +40 -0
- package/dist/services/TemplateGenerator.js +273 -0
- package/dist/services/ValidationService.d.ts +19 -0
- package/dist/services/ValidationService.js +44 -0
- package/dist/services/Validator.d.ts +5 -0
- package/dist/services/Validator.js +6 -0
- package/dist/services/index.d.ts +52 -0
- package/dist/services/index.js +91 -0
- package/dist/services/templates/ExecutionTemplateBuilder.d.ts +12 -0
- package/dist/services/templates/ExecutionTemplateBuilder.js +300 -0
- package/dist/services/templates/ProjectTemplateBuilder.d.ts +38 -0
- package/dist/services/templates/ProjectTemplateBuilder.js +1897 -0
- package/dist/services/templates/TemplateBuilderBase.d.ts +19 -0
- package/dist/services/templates/TemplateBuilderBase.js +60 -0
- package/dist/services/templates/TemplateInputFactory.d.ts +16 -0
- package/dist/services/templates/TemplateInputFactory.js +298 -0
- package/dist/services/templates/templateTypes.d.ts +90 -0
- package/dist/services/templates/templateTypes.js +3 -0
- package/dist/tools/build-index.js +632 -0
- package/dist/utils/DateUtils.d.ts +18 -0
- package/dist/utils/DateUtils.js +40 -0
- package/dist/utils/PathUtils.d.ts +9 -0
- package/dist/utils/PathUtils.js +66 -0
- package/dist/utils/StringUtils.d.ts +26 -0
- package/dist/utils/StringUtils.js +47 -0
- package/dist/utils/helpers.d.ts +5 -0
- package/dist/utils/helpers.js +6 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.js +23 -0
- package/dist/utils/logger.d.ts +5 -0
- package/dist/utils/logger.js +6 -0
- package/dist/utils/path.d.ts +5 -0
- package/dist/utils/path.js +6 -0
- package/dist/utils/subcommandHelp.d.ts +11 -0
- package/dist/utils/subcommandHelp.js +119 -0
- package/dist/workflow/ArchiveGate.d.ts +30 -0
- package/dist/workflow/ArchiveGate.js +93 -0
- package/dist/workflow/ConfigurableWorkflow.d.ts +89 -0
- package/dist/workflow/ConfigurableWorkflow.js +186 -0
- package/dist/workflow/HookSystem.d.ts +38 -0
- package/dist/workflow/HookSystem.js +66 -0
- package/dist/workflow/IndexRegenerator.d.ts +49 -0
- package/dist/workflow/IndexRegenerator.js +147 -0
- package/dist/workflow/PluginWorkflowComposer.d.ts +138 -0
- package/dist/workflow/PluginWorkflowComposer.js +239 -0
- package/dist/workflow/SkillUpdateEngine.d.ts +26 -0
- package/dist/workflow/SkillUpdateEngine.js +113 -0
- package/dist/workflow/VerificationSystem.d.ts +24 -0
- package/dist/workflow/VerificationSystem.js +116 -0
- package/dist/workflow/WorkflowEngine.d.ts +15 -0
- package/dist/workflow/WorkflowEngine.js +57 -0
- package/dist/workflow/index.d.ts +19 -0
- package/dist/workflow/index.js +32 -0
- package/package.json +78 -0
- package/scripts/postinstall.js +43 -0
|
@@ -0,0 +1,1897 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ProjectTemplateBuilder = void 0;
|
|
4
|
+
const constants_1 = require("../../core/constants");
|
|
5
|
+
const TemplateBuilderBase_1 = require("./TemplateBuilderBase");
|
|
6
|
+
class ProjectTemplateBuilder extends TemplateBuilderBase_1.TemplateBuilderBase {
|
|
7
|
+
constructor(inputs) {
|
|
8
|
+
super();
|
|
9
|
+
this.inputs = inputs;
|
|
10
|
+
}
|
|
11
|
+
generateProjectReadmeTemplate(fallbackName, mode, input) {
|
|
12
|
+
const context = this.getProjectContext(fallbackName, mode, input);
|
|
13
|
+
if (this.isEnglish(context.documentLanguage)) {
|
|
14
|
+
return `# ${context.projectName}
|
|
15
|
+
|
|
16
|
+
> Generated by OSpec CLI
|
|
17
|
+
|
|
18
|
+
## OSpec Bootstrap
|
|
19
|
+
|
|
20
|
+
This repository has been initialized with OSpec in \`${mode}\` mode.
|
|
21
|
+
|
|
22
|
+
## Summary
|
|
23
|
+
|
|
24
|
+
${context.summary}
|
|
25
|
+
|
|
26
|
+
## Project Knowledge
|
|
27
|
+
|
|
28
|
+
- Root skill: \`SKILL.md\`
|
|
29
|
+
- Docs hub: \`docs/SKILL.md\`
|
|
30
|
+
- Source map: \`src/SKILL.md\`
|
|
31
|
+
- Test guide: \`tests/SKILL.md\`
|
|
32
|
+
- Index: \`SKILL.index.json\`
|
|
33
|
+
|
|
34
|
+
## Execution
|
|
35
|
+
|
|
36
|
+
Active changes live under \`changes/active/<change>\`.
|
|
37
|
+
`;
|
|
38
|
+
}
|
|
39
|
+
return `# ${context.projectName}
|
|
40
|
+
|
|
41
|
+
> 由 OSpec CLI 初始化生成
|
|
42
|
+
|
|
43
|
+
## OSpec Bootstrap
|
|
44
|
+
|
|
45
|
+
当前仓库已按 \`${mode}\` 模式完成 OSpec 初始化。
|
|
46
|
+
|
|
47
|
+
## 项目简介
|
|
48
|
+
|
|
49
|
+
${context.summary}
|
|
50
|
+
|
|
51
|
+
## 项目知识层
|
|
52
|
+
|
|
53
|
+
- 根技能文档:\`SKILL.md\`
|
|
54
|
+
- 文档中心:\`docs/SKILL.md\`
|
|
55
|
+
- 源码地图:\`src/SKILL.md\`
|
|
56
|
+
- 测试说明:\`tests/SKILL.md\`
|
|
57
|
+
- 语义索引:\`SKILL.index.json\`
|
|
58
|
+
|
|
59
|
+
## 执行层
|
|
60
|
+
|
|
61
|
+
Active change 位于 \`changes/active/<change>\`。
|
|
62
|
+
`;
|
|
63
|
+
}
|
|
64
|
+
generateRootSkillTemplate(fallbackName, mode, input) {
|
|
65
|
+
const context = this.getProjectContext(fallbackName, mode, input);
|
|
66
|
+
const body = this.isEnglish(context.documentLanguage)
|
|
67
|
+
? `# ${context.projectName}
|
|
68
|
+
|
|
69
|
+
> Layer: project root
|
|
70
|
+
|
|
71
|
+
## Project Overview
|
|
72
|
+
|
|
73
|
+
- **Project**: ${context.projectName}
|
|
74
|
+
- **Mode**: ${mode}
|
|
75
|
+
- **Status**: OSpec initialized
|
|
76
|
+
- **Summary**: ${context.summary}
|
|
77
|
+
|
|
78
|
+
## Tech Stack
|
|
79
|
+
|
|
80
|
+
${this.formatList(context.techStack, 'TBD')}
|
|
81
|
+
|
|
82
|
+
## Architecture
|
|
83
|
+
|
|
84
|
+
${context.architecture}
|
|
85
|
+
|
|
86
|
+
## Navigation
|
|
87
|
+
|
|
88
|
+
- Docs hub: [docs/SKILL.md](docs/SKILL.md)
|
|
89
|
+
- Source map: [src/SKILL.md](src/SKILL.md)
|
|
90
|
+
- Test guide: [tests/SKILL.md](tests/SKILL.md)
|
|
91
|
+
- AI guide: [for-ai/ai-guide.md](for-ai/ai-guide.md)
|
|
92
|
+
|
|
93
|
+
## Plugin Gates
|
|
94
|
+
|
|
95
|
+
- Read \`.skillrc\` before advancing an active change.
|
|
96
|
+
- If Stitch is enabled and the current change activates \`stitch_design_review\`, inspect \`changes/active/<change>/artifacts/stitch/approval.json\`.
|
|
97
|
+
- When Stitch approval is missing or its status is not \`approved\`, treat the change as blocked until design review is complete.`
|
|
98
|
+
: `# ${context.projectName}
|
|
99
|
+
|
|
100
|
+
> 层级:第 1 层(项目根文档)
|
|
101
|
+
|
|
102
|
+
## 项目概述
|
|
103
|
+
|
|
104
|
+
- **项目名称**:${context.projectName}
|
|
105
|
+
- **模式**:${mode}
|
|
106
|
+
- **状态**:已完成 OSpec 初始化
|
|
107
|
+
- **简介**:${context.summary}
|
|
108
|
+
|
|
109
|
+
## 技术栈
|
|
110
|
+
|
|
111
|
+
${this.formatList(context.techStack, '待补充')}
|
|
112
|
+
|
|
113
|
+
## 项目架构
|
|
114
|
+
|
|
115
|
+
${context.architecture}
|
|
116
|
+
|
|
117
|
+
## 目录导航
|
|
118
|
+
|
|
119
|
+
- 文档中心:[docs/SKILL.md](docs/SKILL.md)
|
|
120
|
+
- 源码地图:[src/SKILL.md](src/SKILL.md)
|
|
121
|
+
- 测试入口:[tests/SKILL.md](tests/SKILL.md)
|
|
122
|
+
- AI 指南:[for-ai/ai-guide.md](for-ai/ai-guide.md)
|
|
123
|
+
|
|
124
|
+
## 插件阻断
|
|
125
|
+
|
|
126
|
+
- 开始推进 active change 前先读取 \`.skillrc\`。
|
|
127
|
+
- 如果项目启用了 Stitch,且当前 change 激活了 \`stitch_design_review\`,先检查 \`changes/active/<change>/artifacts/stitch/approval.json\`。
|
|
128
|
+
- 当 Stitch 审批缺失或状态不是 \`approved\` 时,视为 change 仍被阻断,先完成设计审核再继续。`;
|
|
129
|
+
return this.withFrontmatter({
|
|
130
|
+
name: context.projectName,
|
|
131
|
+
title: this.copy(context.documentLanguage, context.projectName, `${context.projectName} Project`),
|
|
132
|
+
tags: ['ospec', 'project', mode],
|
|
133
|
+
}, body);
|
|
134
|
+
}
|
|
135
|
+
generateDocsSkillTemplate(fallbackName, input) {
|
|
136
|
+
const context = this.getProjectContext(fallbackName, 'standard', input);
|
|
137
|
+
const body = this.isEnglish(context.documentLanguage)
|
|
138
|
+
? `# Documentation Hub
|
|
139
|
+
|
|
140
|
+
> Layer: docs index
|
|
141
|
+
|
|
142
|
+
## Navigation
|
|
143
|
+
|
|
144
|
+
- Project overview: [project/overview.md](project/overview.md)
|
|
145
|
+
- Bootstrap summary: [project/bootstrap-summary.md](project/bootstrap-summary.md)
|
|
146
|
+
- Tech stack: [project/tech-stack.md](project/tech-stack.md)
|
|
147
|
+
- Architecture: [project/architecture.md](project/architecture.md)
|
|
148
|
+
- Module map: [project/module-map.md](project/module-map.md)
|
|
149
|
+
- API overview: [project/api-overview.md](project/api-overview.md)
|
|
150
|
+
- Design docs: [design/README.md](design/README.md)
|
|
151
|
+
- Planning docs: [planning/README.md](planning/README.md)
|
|
152
|
+
- API docs: [api/README.md](api/README.md)`
|
|
153
|
+
: `# 文档中心
|
|
154
|
+
|
|
155
|
+
> 层级:第 2 层(项目文档索引)
|
|
156
|
+
|
|
157
|
+
## 文档导航
|
|
158
|
+
|
|
159
|
+
- 项目概览:[project/overview.md](project/overview.md)
|
|
160
|
+
- 初始化摘要:[project/bootstrap-summary.md](project/bootstrap-summary.md)
|
|
161
|
+
- 技术栈:[project/tech-stack.md](project/tech-stack.md)
|
|
162
|
+
- 架构说明:[project/architecture.md](project/architecture.md)
|
|
163
|
+
- 模块地图:[project/module-map.md](project/module-map.md)
|
|
164
|
+
- API 总览:[project/api-overview.md](project/api-overview.md)
|
|
165
|
+
- 设计文档目录:[design/README.md](design/README.md)
|
|
166
|
+
- 计划文档目录:[planning/README.md](planning/README.md)
|
|
167
|
+
- API 文档目录:[api/README.md](api/README.md)`;
|
|
168
|
+
return this.withFrontmatter({
|
|
169
|
+
name: 'docs',
|
|
170
|
+
title: this.copy(context.documentLanguage, `${context.projectName} 文档中心`, `${context.projectName} Docs Hub`),
|
|
171
|
+
tags: ['docs', 'project', 'planning', 'api'],
|
|
172
|
+
}, body);
|
|
173
|
+
}
|
|
174
|
+
generateSrcSkillTemplate(fallbackName, input) {
|
|
175
|
+
const context = this.getProjectContext(fallbackName, 'standard', input);
|
|
176
|
+
const moduleLinks = this.formatLinkedList(context.modulePlans.map(plan => ({
|
|
177
|
+
displayName: plan.displayName,
|
|
178
|
+
path: plan.path.replace(`${constants_1.DIR_NAMES.SRC}/`, ''),
|
|
179
|
+
})), this.copy(context.documentLanguage, '待补充', 'TBD'));
|
|
180
|
+
const body = this.isEnglish(context.documentLanguage)
|
|
181
|
+
? `# Source Map
|
|
182
|
+
|
|
183
|
+
> Layer: source index
|
|
184
|
+
|
|
185
|
+
## Navigation
|
|
186
|
+
|
|
187
|
+
- Core layer: [core/SKILL.md](core/SKILL.md)
|
|
188
|
+
- Module layer: \`src/modules/<module>/SKILL.md\`
|
|
189
|
+
|
|
190
|
+
## Modules
|
|
191
|
+
|
|
192
|
+
${moduleLinks}`
|
|
193
|
+
: `# 源码地图
|
|
194
|
+
|
|
195
|
+
> 层级:第 2 层(源码索引)
|
|
196
|
+
|
|
197
|
+
## 目录导航
|
|
198
|
+
|
|
199
|
+
- 核心层:[core/SKILL.md](core/SKILL.md)
|
|
200
|
+
- 模块层:\`src/modules/<module>/SKILL.md\`
|
|
201
|
+
|
|
202
|
+
## 模块说明
|
|
203
|
+
|
|
204
|
+
${moduleLinks}`;
|
|
205
|
+
return this.withFrontmatter({
|
|
206
|
+
name: 'src',
|
|
207
|
+
title: this.copy(context.documentLanguage, `${context.projectName} 源码地图`, `${context.projectName} Source Map`),
|
|
208
|
+
tags: ['src', 'modules', 'architecture'],
|
|
209
|
+
}, body);
|
|
210
|
+
}
|
|
211
|
+
generateCoreSkillTemplate(fallbackName, input) {
|
|
212
|
+
const context = this.getProjectContext(fallbackName, 'standard', input);
|
|
213
|
+
const body = this.isEnglish(context.documentLanguage)
|
|
214
|
+
? `# Core Layer
|
|
215
|
+
|
|
216
|
+
> Layer: core module
|
|
217
|
+
> Parent: [src/SKILL.md](../SKILL.md)
|
|
218
|
+
|
|
219
|
+
## Module Overview
|
|
220
|
+
|
|
221
|
+
- **Role**: shared runtime and infrastructure capabilities
|
|
222
|
+
- **Path**: src/core/
|
|
223
|
+
- **Dependencies**: TBD
|
|
224
|
+
|
|
225
|
+
## API Docs
|
|
226
|
+
|
|
227
|
+
- Project API overview: [../../docs/project/api-overview.md](../../docs/project/api-overview.md)`
|
|
228
|
+
: `# Core 核心层
|
|
229
|
+
|
|
230
|
+
> 层级:第 3 层(核心模块)
|
|
231
|
+
> 上层:[src/SKILL.md](../SKILL.md)
|
|
232
|
+
|
|
233
|
+
## 模块概述
|
|
234
|
+
|
|
235
|
+
- **职责**:承载项目级公共能力
|
|
236
|
+
- **位置**:src/core/
|
|
237
|
+
- **依赖**:待补充
|
|
238
|
+
|
|
239
|
+
## API 文档
|
|
240
|
+
|
|
241
|
+
- 项目 API 总览:[../../docs/project/api-overview.md](../../docs/project/api-overview.md)`;
|
|
242
|
+
return this.withFrontmatter({
|
|
243
|
+
name: 'core',
|
|
244
|
+
title: this.copy(context.documentLanguage, `${context.projectName} 核心层`, `${context.projectName} Core Layer`),
|
|
245
|
+
tags: ['core', 'runtime', 'infrastructure'],
|
|
246
|
+
}, body);
|
|
247
|
+
}
|
|
248
|
+
generateTestsSkillTemplate(fallbackName, input) {
|
|
249
|
+
const context = this.getProjectContext(fallbackName, 'standard', input);
|
|
250
|
+
const body = this.isEnglish(context.documentLanguage)
|
|
251
|
+
? `# Test Guide
|
|
252
|
+
|
|
253
|
+
## Test Strategy
|
|
254
|
+
|
|
255
|
+
- Unit tests: TBD
|
|
256
|
+
- Integration tests: TBD
|
|
257
|
+
- End-to-end tests: TBD`
|
|
258
|
+
: `# 测试说明
|
|
259
|
+
|
|
260
|
+
## 测试策略
|
|
261
|
+
|
|
262
|
+
- 单元测试:待补充
|
|
263
|
+
- 集成测试:待补充
|
|
264
|
+
- 端到端测试:待补充`;
|
|
265
|
+
return this.withFrontmatter({
|
|
266
|
+
name: 'tests',
|
|
267
|
+
title: this.copy(context.documentLanguage, `${context.projectName} 测试说明`, `${context.projectName} Test Guide`),
|
|
268
|
+
tags: ['tests', 'quality', 'verification'],
|
|
269
|
+
}, body);
|
|
270
|
+
}
|
|
271
|
+
generateProjectOverviewTemplate(fallbackName, mode, input) {
|
|
272
|
+
const context = this.getProjectContext(fallbackName, mode, input);
|
|
273
|
+
const body = this.isEnglish(context.documentLanguage)
|
|
274
|
+
? `# Project Overview
|
|
275
|
+
|
|
276
|
+
## Background
|
|
277
|
+
|
|
278
|
+
\`${context.projectName}\` has been initialized by OSpec CLI in \`${mode}\` mode.
|
|
279
|
+
|
|
280
|
+
## Summary
|
|
281
|
+
|
|
282
|
+
${context.summary}
|
|
283
|
+
|
|
284
|
+
## Current Goals
|
|
285
|
+
|
|
286
|
+
- Complete the project knowledge layer
|
|
287
|
+
- Use [bootstrap-summary.md](bootstrap-summary.md) as the recorded bootstrap output
|
|
288
|
+
- Establish layered skill files
|
|
289
|
+
- Manage delivery through the change workflow`
|
|
290
|
+
: `# 项目概览
|
|
291
|
+
|
|
292
|
+
## 背景
|
|
293
|
+
|
|
294
|
+
\`${context.projectName}\` 已通过 OSpec CLI 初始化,当前模式为 \`${mode}\`。
|
|
295
|
+
|
|
296
|
+
## 项目简介
|
|
297
|
+
|
|
298
|
+
${context.summary}
|
|
299
|
+
|
|
300
|
+
## 当前目标
|
|
301
|
+
|
|
302
|
+
- 补齐项目知识层
|
|
303
|
+
- 以 [bootstrap-summary.md](bootstrap-summary.md) 记录初始化结果与脚手架输出
|
|
304
|
+
- 建立分层 SKILL 体系
|
|
305
|
+
- 使用 change workflow 管理需求交付`;
|
|
306
|
+
return this.withFrontmatter({
|
|
307
|
+
name: 'project-overview',
|
|
308
|
+
title: this.copy(context.documentLanguage, `${context.projectName} 项目概览`, `${context.projectName} Project Overview`),
|
|
309
|
+
tags: ['project', 'overview', 'bootstrap'],
|
|
310
|
+
}, body);
|
|
311
|
+
}
|
|
312
|
+
generateTechStackTemplate(fallbackName, input) {
|
|
313
|
+
const context = this.getProjectContext(fallbackName, 'standard', input);
|
|
314
|
+
const body = this.isEnglish(context.documentLanguage)
|
|
315
|
+
? `# Tech Stack
|
|
316
|
+
|
|
317
|
+
## Project
|
|
318
|
+
|
|
319
|
+
- **Project**: ${context.projectName}
|
|
320
|
+
|
|
321
|
+
## Stack List
|
|
322
|
+
|
|
323
|
+
${this.formatList(context.techStack, 'TBD')}`
|
|
324
|
+
: `# 技术栈
|
|
325
|
+
|
|
326
|
+
## 项目
|
|
327
|
+
|
|
328
|
+
- **项目名称**:${context.projectName}
|
|
329
|
+
|
|
330
|
+
## 技术栈清单
|
|
331
|
+
|
|
332
|
+
${this.formatList(context.techStack, '待补充')}`;
|
|
333
|
+
return this.withFrontmatter({
|
|
334
|
+
name: 'tech-stack',
|
|
335
|
+
title: this.copy(context.documentLanguage, `${context.projectName} 技术栈`, `${context.projectName} Tech Stack`),
|
|
336
|
+
tags: ['project', 'tech-stack', 'architecture'],
|
|
337
|
+
}, body);
|
|
338
|
+
}
|
|
339
|
+
generateArchitectureTemplate(fallbackName, input) {
|
|
340
|
+
const context = this.getProjectContext(fallbackName, 'standard', input);
|
|
341
|
+
const body = this.isEnglish(context.documentLanguage)
|
|
342
|
+
? `# Architecture
|
|
343
|
+
|
|
344
|
+
## System Architecture
|
|
345
|
+
|
|
346
|
+
- **Project**: ${context.projectName}
|
|
347
|
+
- **Current phase**: OSpec knowledge skeleton initialized
|
|
348
|
+
|
|
349
|
+
${context.architecture}
|
|
350
|
+
|
|
351
|
+
## Layers
|
|
352
|
+
|
|
353
|
+
- Project Knowledge
|
|
354
|
+
- Layered Skills
|
|
355
|
+
- Execution
|
|
356
|
+
- GUI`
|
|
357
|
+
: `# 架构说明
|
|
358
|
+
|
|
359
|
+
## 整体架构
|
|
360
|
+
|
|
361
|
+
- **项目**:${context.projectName}
|
|
362
|
+
- **当前阶段**:已建立 OSpec 项目知识骨架
|
|
363
|
+
|
|
364
|
+
${context.architecture}
|
|
365
|
+
|
|
366
|
+
## 分层说明
|
|
367
|
+
|
|
368
|
+
- Project Knowledge
|
|
369
|
+
- Layered Skills
|
|
370
|
+
- Execution
|
|
371
|
+
- GUI`;
|
|
372
|
+
return this.withFrontmatter({
|
|
373
|
+
name: 'architecture',
|
|
374
|
+
title: this.copy(context.documentLanguage, `${context.projectName} 架构说明`, `${context.projectName} Architecture`),
|
|
375
|
+
tags: ['project', 'architecture', 'layers'],
|
|
376
|
+
}, body);
|
|
377
|
+
}
|
|
378
|
+
generateModuleMapTemplate(fallbackName, input) {
|
|
379
|
+
const context = this.getProjectContext(fallbackName, 'standard', input);
|
|
380
|
+
const modules = this.formatLinkedList(context.modulePlans.map(plan => ({
|
|
381
|
+
displayName: plan.displayName,
|
|
382
|
+
path: plan.path,
|
|
383
|
+
})), this.copy(context.documentLanguage, '待补充', 'TBD'));
|
|
384
|
+
const body = this.isEnglish(context.documentLanguage)
|
|
385
|
+
? `# Module Map
|
|
386
|
+
|
|
387
|
+
## Project
|
|
388
|
+
|
|
389
|
+
- **Project**: ${context.projectName}
|
|
390
|
+
|
|
391
|
+
## Modules
|
|
392
|
+
|
|
393
|
+
${modules}`
|
|
394
|
+
: `# 模块地图
|
|
395
|
+
|
|
396
|
+
## 项目
|
|
397
|
+
|
|
398
|
+
- **项目名称**:${context.projectName}
|
|
399
|
+
|
|
400
|
+
## 模块列表
|
|
401
|
+
|
|
402
|
+
${modules}`;
|
|
403
|
+
return this.withFrontmatter({
|
|
404
|
+
name: 'module-map',
|
|
405
|
+
title: this.copy(context.documentLanguage, `${context.projectName} 模块地图`, `${context.projectName} Module Map`),
|
|
406
|
+
tags: ['project', 'modules', 'map'],
|
|
407
|
+
}, body);
|
|
408
|
+
}
|
|
409
|
+
generateApiOverviewTemplate(fallbackName, input) {
|
|
410
|
+
const context = this.getProjectContext(fallbackName, 'standard', input);
|
|
411
|
+
const apiAreas = this.formatLinkedList(context.apiAreaPlans.map(plan => ({
|
|
412
|
+
displayName: plan.displayName,
|
|
413
|
+
path: plan.path,
|
|
414
|
+
})), this.copy(context.documentLanguage, '待补充', 'TBD'));
|
|
415
|
+
const moduleApis = this.formatLinkedList(context.moduleApiPlans.map(plan => ({
|
|
416
|
+
displayName: plan.displayName,
|
|
417
|
+
path: plan.path,
|
|
418
|
+
})), this.copy(context.documentLanguage, '待补充', 'TBD'));
|
|
419
|
+
const body = this.isEnglish(context.documentLanguage)
|
|
420
|
+
? `# API Overview
|
|
421
|
+
|
|
422
|
+
## Project
|
|
423
|
+
|
|
424
|
+
- **Project**: ${context.projectName}
|
|
425
|
+
|
|
426
|
+
## API Areas
|
|
427
|
+
|
|
428
|
+
${apiAreas}
|
|
429
|
+
|
|
430
|
+
## Module API Docs
|
|
431
|
+
|
|
432
|
+
${moduleApis}`
|
|
433
|
+
: `# API 总览
|
|
434
|
+
|
|
435
|
+
## 项目
|
|
436
|
+
|
|
437
|
+
- **项目名称**:${context.projectName}
|
|
438
|
+
|
|
439
|
+
## API 边界
|
|
440
|
+
|
|
441
|
+
${apiAreas}
|
|
442
|
+
|
|
443
|
+
## 模块 API 文档
|
|
444
|
+
|
|
445
|
+
${moduleApis}`;
|
|
446
|
+
return this.withFrontmatter({
|
|
447
|
+
name: 'api-overview',
|
|
448
|
+
title: this.copy(context.documentLanguage, `${context.projectName} API 总览`, `${context.projectName} API Overview`),
|
|
449
|
+
tags: ['project', 'api', 'overview'],
|
|
450
|
+
}, body);
|
|
451
|
+
}
|
|
452
|
+
generateDesignDocsTemplate(fallbackName, input) {
|
|
453
|
+
const context = this.getProjectContext(fallbackName, 'standard', input);
|
|
454
|
+
const designDocs = this.formatLinkedList(context.designDocPlans.map(plan => ({
|
|
455
|
+
displayName: plan.displayName,
|
|
456
|
+
path: plan.path,
|
|
457
|
+
})), this.copy(context.documentLanguage, '待补充', 'TBD'));
|
|
458
|
+
const body = this.isEnglish(context.documentLanguage)
|
|
459
|
+
? `# Design Docs
|
|
460
|
+
|
|
461
|
+
## Project
|
|
462
|
+
|
|
463
|
+
- **Project**: ${context.projectName}
|
|
464
|
+
|
|
465
|
+
## Planned Design Docs
|
|
466
|
+
|
|
467
|
+
${designDocs}`
|
|
468
|
+
: `# 设计文档规划
|
|
469
|
+
|
|
470
|
+
## 项目
|
|
471
|
+
|
|
472
|
+
- **项目名称**:${context.projectName}
|
|
473
|
+
|
|
474
|
+
## 需要沉淀的设计文档
|
|
475
|
+
|
|
476
|
+
${designDocs}`;
|
|
477
|
+
return this.withFrontmatter({
|
|
478
|
+
name: 'design-docs',
|
|
479
|
+
title: this.copy(context.documentLanguage, `${context.projectName} 设计文档`, `${context.projectName} Design Docs`),
|
|
480
|
+
tags: ['docs', 'design', 'planning'],
|
|
481
|
+
}, body);
|
|
482
|
+
}
|
|
483
|
+
generatePlanningDocsTemplate(fallbackName, input) {
|
|
484
|
+
const context = this.getProjectContext(fallbackName, 'standard', input);
|
|
485
|
+
const planningDocs = this.formatLinkedList(context.planningDocPlans.map(plan => ({
|
|
486
|
+
displayName: plan.displayName,
|
|
487
|
+
path: plan.path,
|
|
488
|
+
})), this.copy(context.documentLanguage, '待补充', 'TBD'));
|
|
489
|
+
const body = this.isEnglish(context.documentLanguage)
|
|
490
|
+
? `# Planning Docs
|
|
491
|
+
|
|
492
|
+
## Project
|
|
493
|
+
|
|
494
|
+
- **Project**: ${context.projectName}
|
|
495
|
+
|
|
496
|
+
## Planning Documents
|
|
497
|
+
|
|
498
|
+
${planningDocs}`
|
|
499
|
+
: `# 开发计划文档
|
|
500
|
+
|
|
501
|
+
## 项目
|
|
502
|
+
|
|
503
|
+
- **项目名称**:${context.projectName}
|
|
504
|
+
|
|
505
|
+
## 计划文档需求
|
|
506
|
+
|
|
507
|
+
${planningDocs}`;
|
|
508
|
+
return this.withFrontmatter({
|
|
509
|
+
name: 'planning-docs',
|
|
510
|
+
title: this.copy(context.documentLanguage, `${context.projectName} 计划文档`, `${context.projectName} Planning Docs`),
|
|
511
|
+
tags: ['docs', 'planning', 'milestone'],
|
|
512
|
+
}, body);
|
|
513
|
+
}
|
|
514
|
+
generateApiDocsTemplate(fallbackName, input) {
|
|
515
|
+
const context = this.getProjectContext(fallbackName, 'standard', input);
|
|
516
|
+
const apiDocs = this.formatLinkedList(context.apiAreaPlans.map(plan => ({
|
|
517
|
+
displayName: plan.displayName,
|
|
518
|
+
path: plan.path,
|
|
519
|
+
})), this.copy(context.documentLanguage, '待补充', 'TBD'));
|
|
520
|
+
const body = this.isEnglish(context.documentLanguage)
|
|
521
|
+
? `# API Docs Directory
|
|
522
|
+
|
|
523
|
+
## Project
|
|
524
|
+
|
|
525
|
+
- **Project**: ${context.projectName}
|
|
526
|
+
|
|
527
|
+
## Planned API Docs
|
|
528
|
+
|
|
529
|
+
${apiDocs}`
|
|
530
|
+
: `# API 文档目录说明
|
|
531
|
+
|
|
532
|
+
## 项目
|
|
533
|
+
|
|
534
|
+
- **项目名称**:${context.projectName}
|
|
535
|
+
|
|
536
|
+
## API 文档规划
|
|
537
|
+
|
|
538
|
+
${apiDocs}`;
|
|
539
|
+
return this.withFrontmatter({
|
|
540
|
+
name: 'api-docs',
|
|
541
|
+
title: this.copy(context.documentLanguage, `${context.projectName} API 文档`, `${context.projectName} API Docs`),
|
|
542
|
+
tags: ['docs', 'api', 'reference'],
|
|
543
|
+
}, body);
|
|
544
|
+
}
|
|
545
|
+
generateModuleSkillTemplate(fallbackName, moduleName, input, moduleSlug) {
|
|
546
|
+
const context = this.getProjectContext(fallbackName, 'standard', input);
|
|
547
|
+
const slug = moduleSlug || this.slugify(moduleName) || 'module';
|
|
548
|
+
const matchedModuleApiDoc = context.moduleApiPlans.find(plan => plan.name === `module-${slug}`);
|
|
549
|
+
const matchedApiDocs = context.apiAreaPlans.filter(plan => plan.name.includes(slug) ||
|
|
550
|
+
plan.displayName.includes(moduleName) ||
|
|
551
|
+
moduleName.includes(plan.displayName.replace(/\s+api$/i, '')));
|
|
552
|
+
const refs = [
|
|
553
|
+
...(matchedModuleApiDoc
|
|
554
|
+
? [{ title: `${moduleName} module api`, path: matchedModuleApiDoc.path }]
|
|
555
|
+
: []),
|
|
556
|
+
...matchedApiDocs.map(plan => ({ title: plan.displayName, path: plan.path })),
|
|
557
|
+
];
|
|
558
|
+
const presetBody = this.getPresetModuleSkillBody(context, moduleName, slug, refs);
|
|
559
|
+
const body = presetBody ?? (this.isEnglish(context.documentLanguage)
|
|
560
|
+
? `# ${moduleName}
|
|
561
|
+
|
|
562
|
+
> Layer: module document
|
|
563
|
+
> Parent: [src/SKILL.md](../../SKILL.md)
|
|
564
|
+
|
|
565
|
+
## Module Overview
|
|
566
|
+
|
|
567
|
+
- **Project**: ${context.projectName}
|
|
568
|
+
- **Module**: ${moduleName}
|
|
569
|
+
- **Path**: src/modules/${slug}
|
|
570
|
+
|
|
571
|
+
## Responsibilities
|
|
572
|
+
|
|
573
|
+
- Own ${moduleName} domain behavior
|
|
574
|
+
- Connect project design and implementation in this module
|
|
575
|
+
- Maintain module boundaries, dependencies, and tests
|
|
576
|
+
|
|
577
|
+
## API Docs
|
|
578
|
+
|
|
579
|
+
${this.formatReferenceList(refs, 'TBD')}
|
|
580
|
+
|
|
581
|
+
## Dependencies
|
|
582
|
+
|
|
583
|
+
- Upstream: \`src/core/\`, project configuration, shared infrastructure
|
|
584
|
+
- Peer collaboration: keep clear boundaries with other \`src/modules/*\`
|
|
585
|
+
- Downstream impact: update API docs, change docs, and tests when behavior changes
|
|
586
|
+
|
|
587
|
+
## Testing Requirements
|
|
588
|
+
|
|
589
|
+
- Unit tests: cover core business rules and edge cases
|
|
590
|
+
- Integration tests: cover module interactions with APIs, data, and services
|
|
591
|
+
- Regression checks: align change verification when interfaces change
|
|
592
|
+
|
|
593
|
+
## Related Docs
|
|
594
|
+
|
|
595
|
+
- Module map: [../../../docs/project/module-map.md](../../../docs/project/module-map.md)
|
|
596
|
+
- API overview: [../../../docs/project/api-overview.md](../../../docs/project/api-overview.md)`
|
|
597
|
+
: `# ${moduleName} 模块
|
|
598
|
+
|
|
599
|
+
> 层级:第 3 层(业务模块文档)
|
|
600
|
+
> 上层:[src/SKILL.md](../../SKILL.md)
|
|
601
|
+
|
|
602
|
+
## 模块概述
|
|
603
|
+
|
|
604
|
+
- **项目**:${context.projectName}
|
|
605
|
+
- **模块名**:${moduleName}
|
|
606
|
+
- **路径**:src/modules/${slug}
|
|
607
|
+
|
|
608
|
+
## 主要职责
|
|
609
|
+
|
|
610
|
+
- 承载 ${moduleName} 相关业务能力
|
|
611
|
+
- 衔接项目级设计与当前模块实现
|
|
612
|
+
- 维护模块边界、依赖与测试要求
|
|
613
|
+
|
|
614
|
+
## API 文档
|
|
615
|
+
|
|
616
|
+
${this.formatReferenceList(refs, '待补充')}
|
|
617
|
+
|
|
618
|
+
## 依赖关系
|
|
619
|
+
|
|
620
|
+
- 上游依赖:\`src/core/\`、项目级配置、共享基础设施
|
|
621
|
+
- 同层协作:与其他 \`src/modules/*\` 保持清晰边界,通过文档和接口约定协作
|
|
622
|
+
- 下游影响:实现变更后需回看关联 API 文档、执行层 change 文档和测试说明
|
|
623
|
+
|
|
624
|
+
## 测试要求
|
|
625
|
+
|
|
626
|
+
- 单元测试:覆盖 ${moduleName} 模块核心业务规则和边界分支
|
|
627
|
+
- 集成测试:覆盖该模块与 API / 数据层 / 外部服务的集成路径
|
|
628
|
+
- 回归验证:当模块接口或行为变化时,同步更新 change 验证与相关文档
|
|
629
|
+
|
|
630
|
+
## 关联文档
|
|
631
|
+
|
|
632
|
+
- 项目模块地图:[../../../docs/project/module-map.md](../../../docs/project/module-map.md)
|
|
633
|
+
- API 总览:[../../../docs/project/api-overview.md](../../../docs/project/api-overview.md)
|
|
634
|
+
- 模块源码入口:当前目录`);
|
|
635
|
+
return this.withFrontmatter({
|
|
636
|
+
name: slug,
|
|
637
|
+
title: this.copy(context.documentLanguage, `${context.projectName} ${moduleName} 模块`, `${context.projectName} ${moduleName} Module`),
|
|
638
|
+
tags: ['module', slug, 'domain'],
|
|
639
|
+
}, body);
|
|
640
|
+
}
|
|
641
|
+
generateApiAreaDocTemplate(fallbackName, apiAreaName, input) {
|
|
642
|
+
const context = this.getProjectContext(fallbackName, 'standard', input);
|
|
643
|
+
const presetBody = this.getPresetApiAreaDocBody(context, apiAreaName);
|
|
644
|
+
const body = presetBody ?? (this.isEnglish(context.documentLanguage)
|
|
645
|
+
? `# ${apiAreaName}
|
|
646
|
+
|
|
647
|
+
## Project
|
|
648
|
+
|
|
649
|
+
- **Project**: ${context.projectName}
|
|
650
|
+
|
|
651
|
+
## Boundary
|
|
652
|
+
|
|
653
|
+
- Own ${apiAreaName} interfaces and contracts
|
|
654
|
+
- Document entrypoints, auth rules, error codes, and data models
|
|
655
|
+
|
|
656
|
+
## Checklist
|
|
657
|
+
|
|
658
|
+
- [ ] Routes
|
|
659
|
+
- [ ] Request / response payloads
|
|
660
|
+
- [ ] Permissions and security rules
|
|
661
|
+
- [ ] Tests and acceptance requirements`
|
|
662
|
+
: `# ${apiAreaName}
|
|
663
|
+
|
|
664
|
+
## 项目
|
|
665
|
+
|
|
666
|
+
- **项目名称**:${context.projectName}
|
|
667
|
+
|
|
668
|
+
## 边界说明
|
|
669
|
+
|
|
670
|
+
- 负责 ${apiAreaName} 相关接口能力
|
|
671
|
+
- 待补充请求入口、鉴权规则、错误码和数据模型
|
|
672
|
+
|
|
673
|
+
## 待补充清单
|
|
674
|
+
|
|
675
|
+
- [ ] 路由列表
|
|
676
|
+
- [ ] 请求/响应结构
|
|
677
|
+
- [ ] 权限与安全要求
|
|
678
|
+
- [ ] 测试与验收要求`);
|
|
679
|
+
return this.withFrontmatter({
|
|
680
|
+
name: this.slugify(apiAreaName) || 'api-area',
|
|
681
|
+
title: this.copy(context.documentLanguage, `${apiAreaName} API 文档`, `${apiAreaName} API Doc`),
|
|
682
|
+
tags: ['api', 'reference', 'module'],
|
|
683
|
+
}, body);
|
|
684
|
+
}
|
|
685
|
+
generateModuleApiDocTemplate(fallbackName, moduleName, input, moduleSlug) {
|
|
686
|
+
const context = this.getProjectContext(fallbackName, 'standard', input);
|
|
687
|
+
const slug = moduleSlug || this.slugify(moduleName) || 'module';
|
|
688
|
+
const presetBody = this.getPresetModuleApiDocBody(context, moduleName, slug);
|
|
689
|
+
const body = presetBody ?? (this.isEnglish(context.documentLanguage)
|
|
690
|
+
? `# ${moduleName} Module API
|
|
691
|
+
|
|
692
|
+
## Project
|
|
693
|
+
|
|
694
|
+
- **Project**: ${context.projectName}
|
|
695
|
+
- **Module**: ${moduleName}
|
|
696
|
+
- **Module path**: src/modules/${slug}
|
|
697
|
+
|
|
698
|
+
## Public Interface
|
|
699
|
+
|
|
700
|
+
- Document the services, events, commands, or APIs exposed by this module
|
|
701
|
+
|
|
702
|
+
## Dependencies
|
|
703
|
+
|
|
704
|
+
- Upstream: TBD
|
|
705
|
+
- Downstream consumers: TBD
|
|
706
|
+
- Shared dependencies: TBD
|
|
707
|
+
|
|
708
|
+
## Testing Requirements
|
|
709
|
+
|
|
710
|
+
- Unit tests: core logic and edge cases
|
|
711
|
+
- Integration tests: cross-module / API / data dependencies
|
|
712
|
+
- Regression checks: update change verification when interfaces change`
|
|
713
|
+
: `# ${moduleName} Module API
|
|
714
|
+
|
|
715
|
+
## 项目
|
|
716
|
+
|
|
717
|
+
- **项目名称**:${context.projectName}
|
|
718
|
+
- **模块名**:${moduleName}
|
|
719
|
+
- **模块路径**:src/modules/${slug}
|
|
720
|
+
|
|
721
|
+
## 对外接口
|
|
722
|
+
|
|
723
|
+
- 待补充该模块暴露的服务、事件、命令或接口
|
|
724
|
+
|
|
725
|
+
## 依赖关系
|
|
726
|
+
|
|
727
|
+
- 上游依赖:待补充
|
|
728
|
+
- 下游调用方:待补充
|
|
729
|
+
- 共享依赖:待补充
|
|
730
|
+
|
|
731
|
+
## 测试要求
|
|
732
|
+
|
|
733
|
+
- 单元测试:核心逻辑和边界条件
|
|
734
|
+
- 集成测试:跨模块 / API / 数据依赖
|
|
735
|
+
- 回归验证:接口变更后同步更新 change 验证`);
|
|
736
|
+
return this.withFrontmatter({
|
|
737
|
+
name: `module-${slug}`,
|
|
738
|
+
title: this.copy(context.documentLanguage, `${moduleName} 模块 API`, `${moduleName} Module API`),
|
|
739
|
+
tags: ['api', 'module', slug],
|
|
740
|
+
}, body);
|
|
741
|
+
}
|
|
742
|
+
generateDesignDocTemplate(fallbackName, docName, input) {
|
|
743
|
+
const context = this.getProjectContext(fallbackName, 'standard', input);
|
|
744
|
+
const presetBody = this.getPresetDesignDocBody(context, docName);
|
|
745
|
+
const body = presetBody ?? (this.isEnglish(context.documentLanguage)
|
|
746
|
+
? `# ${docName}
|
|
747
|
+
|
|
748
|
+
## Project
|
|
749
|
+
|
|
750
|
+
- **Project**: ${context.projectName}
|
|
751
|
+
|
|
752
|
+
## Design Goals
|
|
753
|
+
|
|
754
|
+
- Explain the background and goal of ${docName}
|
|
755
|
+
- Record boundaries, constraints, and tradeoffs
|
|
756
|
+
|
|
757
|
+
## To Be Completed
|
|
758
|
+
|
|
759
|
+
- Background
|
|
760
|
+
- Proposal
|
|
761
|
+
- Risks
|
|
762
|
+
- Verification`
|
|
763
|
+
: `# ${docName}
|
|
764
|
+
|
|
765
|
+
## 项目
|
|
766
|
+
|
|
767
|
+
- **项目名称**:${context.projectName}
|
|
768
|
+
|
|
769
|
+
## 设计目标
|
|
770
|
+
|
|
771
|
+
- 说明 ${docName} 的设计背景和目标
|
|
772
|
+
- 记录方案边界、关键约束和取舍
|
|
773
|
+
|
|
774
|
+
## 待补充内容
|
|
775
|
+
|
|
776
|
+
- 背景
|
|
777
|
+
- 方案
|
|
778
|
+
- 风险
|
|
779
|
+
- 验证方式`);
|
|
780
|
+
return this.withFrontmatter({
|
|
781
|
+
name: this.slugify(docName) || 'design-doc',
|
|
782
|
+
title: this.copy(context.documentLanguage, `${docName} 设计文档`, `${docName} Design Doc`),
|
|
783
|
+
tags: ['design', 'architecture', 'decision'],
|
|
784
|
+
}, body);
|
|
785
|
+
}
|
|
786
|
+
generatePlanningDocTemplate(fallbackName, docName, input) {
|
|
787
|
+
const context = this.getProjectContext(fallbackName, 'standard', input);
|
|
788
|
+
const presetBody = this.getPresetPlanningDocBody(context, docName);
|
|
789
|
+
const body = presetBody ?? (this.isEnglish(context.documentLanguage)
|
|
790
|
+
? `# ${docName}
|
|
791
|
+
|
|
792
|
+
## Project
|
|
793
|
+
|
|
794
|
+
- **Project**: ${context.projectName}
|
|
795
|
+
|
|
796
|
+
## Planning Goal
|
|
797
|
+
|
|
798
|
+
- Describe the phase goal and delivery boundary for ${docName}
|
|
799
|
+
|
|
800
|
+
## To Be Completed
|
|
801
|
+
|
|
802
|
+
- Milestones
|
|
803
|
+
- Task breakdown
|
|
804
|
+
- Risks and dependencies
|
|
805
|
+
- Acceptance cadence`
|
|
806
|
+
: `# ${docName}
|
|
807
|
+
|
|
808
|
+
## 项目
|
|
809
|
+
|
|
810
|
+
- **项目名称**:${context.projectName}
|
|
811
|
+
|
|
812
|
+
## 规划目标
|
|
813
|
+
|
|
814
|
+
- 说明 ${docName} 对应的阶段目标和交付边界
|
|
815
|
+
|
|
816
|
+
## 待补充内容
|
|
817
|
+
|
|
818
|
+
- 里程碑
|
|
819
|
+
- 任务拆解
|
|
820
|
+
- 风险与依赖
|
|
821
|
+
- 验收节奏`);
|
|
822
|
+
return this.withFrontmatter({
|
|
823
|
+
name: this.slugify(docName) || 'planning-doc',
|
|
824
|
+
title: this.copy(context.documentLanguage, `${docName} 计划文档`, `${docName} Planning Doc`),
|
|
825
|
+
tags: ['planning', 'delivery', 'milestone'],
|
|
826
|
+
}, body);
|
|
827
|
+
}
|
|
828
|
+
generateAiGuideTemplate(input) {
|
|
829
|
+
const language = input?.documentLanguage === 'en-US' ? 'en-US' : 'zh-CN';
|
|
830
|
+
return this.withFrontmatter({
|
|
831
|
+
name: 'ai-guide',
|
|
832
|
+
title: this.copy(language, 'AI 开发指南', 'AI Guide'),
|
|
833
|
+
tags: ['ai', 'guide', 'workflow'],
|
|
834
|
+
}, this.copy(language, `# AI 开发指南
|
|
835
|
+
|
|
836
|
+
## 工作顺序
|
|
837
|
+
|
|
838
|
+
1. 优先读取 \`SKILL.index.json\`。
|
|
839
|
+
2. 修改代码前先读取相关 \`SKILL.md\`。
|
|
840
|
+
3. 当前执行工作以 \`changes/active/<change>\` 为准。
|
|
841
|
+
4. 如果项目启用了 Stitch 且当前 change 激活了 \`stitch_design_review\`,先检查 \`artifacts/stitch/approval.json\`,未 \`approved\` 前不要把 change 视为可继续实现或可归档。
|
|
842
|
+
5. 如果涉及 Stitch 安装、provider 切换、doctor 修复、MCP 或认证配置,优先读取仓库内 Stitch 规范;若缺失规范文档,则使用内建基线:Gemini 用 \`%USERPROFILE%/.gemini/settings.json\` 的 \`mcpServers.stitch.httpUrl\` 与 \`headers.X-Goog-Api-Key\`,Codex 用 \`%USERPROFILE%/.codex/config.toml\` 的 \`[mcp_servers.stitch]\`、\`type = "http"\`、\`url = "https://stitch.googleapis.com/mcp"\` 与 \`X-Goog-Api-Key\`。
|
|
843
|
+
6. 如果内建 Codex provider 只读调用正常但 Stitch 写操作卡住,优先检查是否真正走了 \`codex exec --dangerously-bypass-approvals-and-sandbox\`;如果项目覆写了自定义 Codex runner,则该 runner 也必须显式带上这个参数。
|
|
844
|
+
7. 发生重要变更后同步更新技能文档并重建索引。`, `# AI Guide
|
|
845
|
+
|
|
846
|
+
## Working Order
|
|
847
|
+
|
|
848
|
+
1. Read \`SKILL.index.json\` when available.
|
|
849
|
+
2. Read the relevant \`SKILL.md\` files before editing code.
|
|
850
|
+
3. Use \`changes/active/<change>\` as the execution layer.
|
|
851
|
+
4. If Stitch is enabled and the current change activates \`stitch_design_review\`, inspect \`artifacts/stitch/approval.json\` first and do not treat the change as ready to continue or archive until it is \`approved\`.
|
|
852
|
+
5. If Stitch installation, provider switching, doctor remediation, MCP setup, or auth setup is involved, read the repo-local Stitch spec first; if the repo does not contain that spec, use the built-in baselines instead: Gemini uses \`%USERPROFILE%/.gemini/settings.json\` with \`mcpServers.stitch.httpUrl\` and \`headers.X-Goog-Api-Key\`, and Codex uses \`%USERPROFILE%/.codex/config.toml\` with \`[mcp_servers.stitch]\`, \`type = "http"\`, \`url = "https://stitch.googleapis.com/mcp"\`, and \`X-Goog-Api-Key\`.
|
|
853
|
+
6. If the built-in Codex provider succeeds on read-only calls but Stitch write operations stall, first verify the run actually uses \`codex exec --dangerously-bypass-approvals-and-sandbox\`; if the project overrides a custom Codex runner, that runner must also pass the same flag explicitly.
|
|
854
|
+
7. Update skill documents and rebuild the index after meaningful changes.`));
|
|
855
|
+
}
|
|
856
|
+
generateExecutionProtocolTemplate(input) {
|
|
857
|
+
const language = input?.documentLanguage === 'en-US' ? 'en-US' : 'zh-CN';
|
|
858
|
+
return this.withFrontmatter({
|
|
859
|
+
name: 'execution-protocol',
|
|
860
|
+
title: this.copy(language, '执行协议', 'Execution Protocol'),
|
|
861
|
+
tags: ['execution', 'protocol', 'workflow'],
|
|
862
|
+
}, this.copy(language, `# 执行协议
|
|
863
|
+
|
|
864
|
+
## 真正来源
|
|
865
|
+
|
|
866
|
+
- \`.skillrc\`
|
|
867
|
+
- \`changes/active/<change>/proposal.md\`
|
|
868
|
+
- \`changes/active/<change>/tasks.md\`
|
|
869
|
+
- \`changes/active/<change>/state.json\`
|
|
870
|
+
- \`changes/active/<change>/verification.md\`
|
|
871
|
+
|
|
872
|
+
## 规则
|
|
873
|
+
|
|
874
|
+
项目级文档和分层技能文档用于承载长期知识。
|
|
875
|
+
active change 文档用于承载当前实现工作。
|
|
876
|
+
|
|
877
|
+
## 插件阻断
|
|
878
|
+
|
|
879
|
+
- 先读取 \`.skillrc.plugins\`,判断是否存在启用中的阻断插件。
|
|
880
|
+
- 如果当前 change 在 \`tasks.md\` 或 \`verification.md\` 中激活了 \`stitch_design_review\`,先检查 \`artifacts/stitch/approval.json\`。
|
|
881
|
+
- 当 \`approval.json.status\` 不是 \`approved\` 时,不要把 change 视为可继续实现、可验证完成或可归档。
|
|
882
|
+
- 如果涉及 Stitch provider、MCP 或认证配置,优先读取仓库内 Stitch 规范;若缺失规范文档,则使用内建基线:Gemini 用 \`%USERPROFILE%/.gemini/settings.json\` 的 \`mcpServers.stitch.httpUrl\` 与 \`headers.X-Goog-Api-Key\`,Codex 用 \`%USERPROFILE%/.codex/config.toml\` 的 \`[mcp_servers.stitch]\`、\`type = "http"\`、\`url = "https://stitch.googleapis.com/mcp"\` 与 \`X-Goog-Api-Key\`。
|
|
883
|
+
- 如果内建 Codex provider 只读调用正常但 Stitch 写操作卡住,优先检查是否真正走了 \`codex exec --dangerously-bypass-approvals-and-sandbox\`;如果项目覆写了自定义 Codex runner,则该 runner 也必须显式带上这个参数。
|
|
884
|
+
- 记录人工审批时,优先使用 \`ospec plugins approve stitch <change-path>\` 或 \`ospec plugins reject stitch <change-path>\`。`, `# Execution Protocol
|
|
885
|
+
|
|
886
|
+
## Source of Truth
|
|
887
|
+
|
|
888
|
+
- \`.skillrc\`
|
|
889
|
+
- \`changes/active/<change>/proposal.md\`
|
|
890
|
+
- \`changes/active/<change>/tasks.md\`
|
|
891
|
+
- \`changes/active/<change>/state.json\`
|
|
892
|
+
- \`changes/active/<change>/verification.md\`
|
|
893
|
+
|
|
894
|
+
## Rule
|
|
895
|
+
|
|
896
|
+
Use project-level docs and layered skill files for long-lived knowledge.
|
|
897
|
+
Use active changes for current implementation work.
|
|
898
|
+
|
|
899
|
+
## Plugin Gates
|
|
900
|
+
|
|
901
|
+
- Read \`.skillrc.plugins\` first to detect enabled blocking plugins.
|
|
902
|
+
- If the current change activates \`stitch_design_review\` in \`tasks.md\` or \`verification.md\`, inspect \`artifacts/stitch/approval.json\` before advancing the change.
|
|
903
|
+
- When \`approval.json.status\` is not \`approved\`, do not treat the change as ready for continued implementation, completion claims, or archive readiness.
|
|
904
|
+
- If Stitch provider, MCP, or auth config is involved, read the repo-local Stitch spec first; if the repo does not contain that spec, use the built-in baselines instead: Gemini uses \`%USERPROFILE%/.gemini/settings.json\` with \`mcpServers.stitch.httpUrl\` and \`headers.X-Goog-Api-Key\`, and Codex uses \`%USERPROFILE%/.codex/config.toml\` with \`[mcp_servers.stitch]\`, \`type = "http"\`, \`url = "https://stitch.googleapis.com/mcp"\`, and \`X-Goog-Api-Key\`.
|
|
905
|
+
- If the built-in Codex provider succeeds on read-only calls but Stitch write operations stall, first verify the run actually uses \`codex exec --dangerously-bypass-approvals-and-sandbox\`; if the project overrides a custom Codex runner, that runner must also pass the same flag explicitly.
|
|
906
|
+
- When recording manual review decisions, prefer \`ospec plugins approve stitch <change-path>\` or \`ospec plugins reject stitch <change-path>\`.`));
|
|
907
|
+
}
|
|
908
|
+
generateBuildIndexScriptTemplate() {
|
|
909
|
+
return `#!/usr/bin/env node
|
|
910
|
+
|
|
911
|
+
const fs = require('fs-extra');
|
|
912
|
+
const path = require('path');
|
|
913
|
+
const yaml = require('js-yaml');
|
|
914
|
+
|
|
915
|
+
const rootDir = process.cwd();
|
|
916
|
+
const indexPath = path.join(rootDir, 'SKILL.index.json');
|
|
917
|
+
const modules = {};
|
|
918
|
+
const tagIndex = {};
|
|
919
|
+
|
|
920
|
+
async function scan(dir) {
|
|
921
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
922
|
+
for (const entry of entries) {
|
|
923
|
+
const fullPath = path.join(dir, entry.name);
|
|
924
|
+
if (entry.isDirectory()) {
|
|
925
|
+
if (['node_modules', 'dist', '.git', 'changes', 'for-ai'].includes(entry.name)) {
|
|
926
|
+
continue;
|
|
927
|
+
}
|
|
928
|
+
await scan(fullPath);
|
|
929
|
+
continue;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
if (entry.name !== 'SKILL.md') {
|
|
933
|
+
continue;
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
const content = await fs.readFile(fullPath, 'utf8');
|
|
937
|
+
const relativePath = path.relative(rootDir, fullPath).replace(/\\\\/g, '/');
|
|
938
|
+
const frontmatterMatch = content.match(/^---\\n([\\s\\S]*?)\\n---/);
|
|
939
|
+
if (!frontmatterMatch) {
|
|
940
|
+
continue;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
const frontmatter = yaml.load(frontmatterMatch[1]) || {};
|
|
944
|
+
const moduleName = frontmatter.name || relativePath;
|
|
945
|
+
const tags = Array.isArray(frontmatter.tags) ? frontmatter.tags : [];
|
|
946
|
+
const sections = {};
|
|
947
|
+
const headingRegex = /^(#{1,6})\\s+(.+?)$/gm;
|
|
948
|
+
let match;
|
|
949
|
+
|
|
950
|
+
while ((match = headingRegex.exec(content)) !== null) {
|
|
951
|
+
sections[match[2]] = {
|
|
952
|
+
level: match[1].length,
|
|
953
|
+
title: match[2],
|
|
954
|
+
start: match.index,
|
|
955
|
+
end: match.index + match[0].length,
|
|
956
|
+
};
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
modules[moduleName] = {
|
|
960
|
+
file: relativePath,
|
|
961
|
+
title: frontmatter.title || moduleName,
|
|
962
|
+
tags,
|
|
963
|
+
sections,
|
|
964
|
+
};
|
|
965
|
+
|
|
966
|
+
for (const tag of tags) {
|
|
967
|
+
if (!tagIndex[tag]) {
|
|
968
|
+
tagIndex[tag] = [];
|
|
969
|
+
}
|
|
970
|
+
tagIndex[tag].push(moduleName);
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
scan(rootDir)
|
|
976
|
+
.then(async () => {
|
|
977
|
+
const index = {
|
|
978
|
+
version: '1.0',
|
|
979
|
+
generated: new Date().toISOString(),
|
|
980
|
+
git_commit: null,
|
|
981
|
+
active_changes: [],
|
|
982
|
+
stats: {
|
|
983
|
+
totalFiles: Object.keys(modules).length,
|
|
984
|
+
totalModules: Object.keys(modules).length,
|
|
985
|
+
totalSections: Object.values(modules).reduce((count, module) => count + Object.keys(module.sections).length, 0),
|
|
986
|
+
},
|
|
987
|
+
modules,
|
|
988
|
+
tagIndex,
|
|
989
|
+
};
|
|
990
|
+
|
|
991
|
+
await fs.writeFile(indexPath, JSON.stringify(index, null, 2));
|
|
992
|
+
console.log('Index rebuilt:', indexPath);
|
|
993
|
+
})
|
|
994
|
+
.catch(error => {
|
|
995
|
+
console.error(error);
|
|
996
|
+
process.exit(1);
|
|
997
|
+
});
|
|
998
|
+
`;
|
|
999
|
+
}
|
|
1000
|
+
getProjectContext(fallbackName, mode, input) {
|
|
1001
|
+
return this.inputs.normalizeProjectBootstrapInput(input, fallbackName, mode);
|
|
1002
|
+
}
|
|
1003
|
+
getPresetModuleSkillBody(context, moduleName, slug, refs) {
|
|
1004
|
+
if (context.projectPresetId !== 'official-site') {
|
|
1005
|
+
return null;
|
|
1006
|
+
}
|
|
1007
|
+
const moduleKey = slug.toLowerCase();
|
|
1008
|
+
const docsLink = this.formatReferenceList(refs, this.copy(context.documentLanguage, '待补充', 'TBD'));
|
|
1009
|
+
const relatedDocs = this.isEnglish(context.documentLanguage)
|
|
1010
|
+
? `- Module map: [../../../docs/project/module-map.md](../../../docs/project/module-map.md)
|
|
1011
|
+
- API overview: [../../../docs/project/api-overview.md](../../../docs/project/api-overview.md)
|
|
1012
|
+
- Bootstrap summary: [../../../docs/project/bootstrap-summary.md](../../../docs/project/bootstrap-summary.md)`
|
|
1013
|
+
: `- 项目模块地图:[../../../docs/project/module-map.md](../../../docs/project/module-map.md)
|
|
1014
|
+
- API 总览:[../../../docs/project/api-overview.md](../../../docs/project/api-overview.md)
|
|
1015
|
+
- 初始化摘要:[../../../docs/project/bootstrap-summary.md](../../../docs/project/bootstrap-summary.md)`;
|
|
1016
|
+
const templates = {
|
|
1017
|
+
web: {
|
|
1018
|
+
zh: `# ${moduleName} 模块
|
|
1019
|
+
|
|
1020
|
+
> 层级:第 3 层(业务模块文档)
|
|
1021
|
+
> 上层:[src/SKILL.md](../../SKILL.md)
|
|
1022
|
+
|
|
1023
|
+
## 模块定位
|
|
1024
|
+
|
|
1025
|
+
- 负责官网首页、全局导航和关键 CTA 的首屏体验
|
|
1026
|
+
- 串联 docs、blog、admin、login 等主入口
|
|
1027
|
+
- 承担品牌展示、信息分发和主站级布局约束
|
|
1028
|
+
|
|
1029
|
+
## 主要职责
|
|
1030
|
+
|
|
1031
|
+
- 维护首页、导航、页脚与站点级布局
|
|
1032
|
+
- 暴露首页到 docs/blog/admin/login 的稳定跳转关系
|
|
1033
|
+
- 与 content 模块协作,消费首屏展示所需的内容摘要
|
|
1034
|
+
|
|
1035
|
+
## API 文档
|
|
1036
|
+
|
|
1037
|
+
${docsLink}
|
|
1038
|
+
|
|
1039
|
+
## 交付边界
|
|
1040
|
+
|
|
1041
|
+
- 首页 Hero、功能区、入口区块和页脚属于 web 模块
|
|
1042
|
+
- 站点级路由编排、导航配置和营销内容组合属于 web 模块
|
|
1043
|
+
- 具体文档内容、博客内容、后台内容工作流不在此模块内部实现
|
|
1044
|
+
|
|
1045
|
+
## 测试要求
|
|
1046
|
+
|
|
1047
|
+
- 单元测试:导航配置、首页区块配置、入口卡片等静态装配逻辑
|
|
1048
|
+
- 集成测试:首页到 docs/blog/admin/login 的关键跳转与路由装配
|
|
1049
|
+
- 回归验证:主导航或首页结构调整后同步验证官网 MVP change
|
|
1050
|
+
|
|
1051
|
+
## 关联文档
|
|
1052
|
+
|
|
1053
|
+
${relatedDocs}`,
|
|
1054
|
+
en: `# ${moduleName}
|
|
1055
|
+
|
|
1056
|
+
> Layer: module document
|
|
1057
|
+
> Parent: [src/SKILL.md](../../SKILL.md)
|
|
1058
|
+
|
|
1059
|
+
## Module Positioning
|
|
1060
|
+
|
|
1061
|
+
- Own the homepage, global navigation, and primary CTA experience
|
|
1062
|
+
- Connect docs, blog, admin, and login entry points
|
|
1063
|
+
- Hold brand presentation, information hierarchy, and site-wide layout constraints
|
|
1064
|
+
|
|
1065
|
+
## Responsibilities
|
|
1066
|
+
|
|
1067
|
+
- Maintain the homepage, navigation, footer, and global shell
|
|
1068
|
+
- Expose stable links from the homepage into docs, blog, admin, and login
|
|
1069
|
+
- Consume content summaries from the content module for marketing surfaces
|
|
1070
|
+
|
|
1071
|
+
## API Docs
|
|
1072
|
+
|
|
1073
|
+
${docsLink}
|
|
1074
|
+
|
|
1075
|
+
## Delivery Boundaries
|
|
1076
|
+
|
|
1077
|
+
- Hero, feature sections, entry cards, and footer belong to the web module
|
|
1078
|
+
- Site routing composition, navigation config, and marketing assembly belong here
|
|
1079
|
+
- Detailed docs/blog content and admin workflows do not live inside this module
|
|
1080
|
+
|
|
1081
|
+
## Testing Requirements
|
|
1082
|
+
|
|
1083
|
+
- Unit tests: navigation config, homepage section assembly, CTA cards
|
|
1084
|
+
- Integration tests: critical routing across home, docs, blog, admin, and login
|
|
1085
|
+
- Regression checks: validate the official-site MVP change after navigation updates
|
|
1086
|
+
|
|
1087
|
+
## Related Docs
|
|
1088
|
+
|
|
1089
|
+
${relatedDocs}`,
|
|
1090
|
+
},
|
|
1091
|
+
docs: {
|
|
1092
|
+
zh: `# ${moduleName} 模块
|
|
1093
|
+
|
|
1094
|
+
> 层级:第 3 层(业务模块文档)
|
|
1095
|
+
> 上层:[src/SKILL.md](../../SKILL.md)
|
|
1096
|
+
|
|
1097
|
+
## 模块定位
|
|
1098
|
+
|
|
1099
|
+
- 负责文档中心的信息架构、目录层级与阅读入口
|
|
1100
|
+
- 承接从首页进入 docs 的主路径
|
|
1101
|
+
- 与 content 模块协作,定义文档内容的展示形态
|
|
1102
|
+
|
|
1103
|
+
## 主要职责
|
|
1104
|
+
|
|
1105
|
+
- 维护文档首页、文档侧边栏、分类入口和阅读页骨架
|
|
1106
|
+
- 定义文档版本、栏目、目录层级的呈现结构
|
|
1107
|
+
- 约束搜索、上一篇/下一篇、返回导航等阅读辅助能力
|
|
1108
|
+
|
|
1109
|
+
## API 文档
|
|
1110
|
+
|
|
1111
|
+
${docsLink}
|
|
1112
|
+
|
|
1113
|
+
## 交付边界
|
|
1114
|
+
|
|
1115
|
+
- 文档目录结构、阅读布局和导航关系由 docs 模块负责
|
|
1116
|
+
- 原始文档实体、发布状态和内容获取策略由 content 模块负责
|
|
1117
|
+
- 后台内容编辑能力由 admin 模块负责
|
|
1118
|
+
|
|
1119
|
+
## 测试要求
|
|
1120
|
+
|
|
1121
|
+
- 单元测试:目录映射、文档导航、阅读辅助逻辑
|
|
1122
|
+
- 集成测试:首页进入 docs、文档列表到文档详情的主链路
|
|
1123
|
+
- 回归验证:文档信息架构调整后同步验证导航与内容落点
|
|
1124
|
+
|
|
1125
|
+
## 关联文档
|
|
1126
|
+
|
|
1127
|
+
${relatedDocs}`,
|
|
1128
|
+
en: `# ${moduleName}
|
|
1129
|
+
|
|
1130
|
+
> Layer: module document
|
|
1131
|
+
> Parent: [src/SKILL.md](../../SKILL.md)
|
|
1132
|
+
|
|
1133
|
+
## Module Positioning
|
|
1134
|
+
|
|
1135
|
+
- Own the docs-center information architecture, hierarchy, and reading entry points
|
|
1136
|
+
- Carry the primary route from the homepage into docs
|
|
1137
|
+
- Work with the content module to shape how documentation content is presented
|
|
1138
|
+
|
|
1139
|
+
## Responsibilities
|
|
1140
|
+
|
|
1141
|
+
- Maintain the docs home, sidebar, category entry points, and reading-page shell
|
|
1142
|
+
- Define the structure for versions, sections, and content hierarchy
|
|
1143
|
+
- Constrain search, prev/next navigation, and reading-assistance behavior
|
|
1144
|
+
|
|
1145
|
+
## API Docs
|
|
1146
|
+
|
|
1147
|
+
${docsLink}
|
|
1148
|
+
|
|
1149
|
+
## Delivery Boundaries
|
|
1150
|
+
|
|
1151
|
+
- Docs layout, reading shell, and navigation structure belong to this module
|
|
1152
|
+
- Source document entities and publication state belong to the content module
|
|
1153
|
+
- Admin editing flows belong to the admin module
|
|
1154
|
+
|
|
1155
|
+
## Testing Requirements
|
|
1156
|
+
|
|
1157
|
+
- Unit tests: hierarchy mapping, sidebar navigation, reading helpers
|
|
1158
|
+
- Integration tests: homepage-to-docs entry and docs-list-to-doc-detail flow
|
|
1159
|
+
- Regression checks: revalidate navigation and content placement after IA changes
|
|
1160
|
+
|
|
1161
|
+
## Related Docs
|
|
1162
|
+
|
|
1163
|
+
${relatedDocs}`,
|
|
1164
|
+
},
|
|
1165
|
+
content: {
|
|
1166
|
+
zh: `# ${moduleName} 模块
|
|
1167
|
+
|
|
1168
|
+
> 层级:第 3 层(业务模块文档)
|
|
1169
|
+
> 上层:[src/SKILL.md](../../SKILL.md)
|
|
1170
|
+
|
|
1171
|
+
## 模块定位
|
|
1172
|
+
|
|
1173
|
+
- 负责官网内容模型、内容读取边界和发布状态
|
|
1174
|
+
- 为 web、docs、blog 与 admin 模块提供统一内容来源
|
|
1175
|
+
- 约束文档、博客、更新日志等内容实体的一致性
|
|
1176
|
+
|
|
1177
|
+
## 主要职责
|
|
1178
|
+
|
|
1179
|
+
- 定义 docs、blog、changelog、site settings 等核心内容实体
|
|
1180
|
+
- 管理草稿、已发布、预览等内容状态
|
|
1181
|
+
- 提供内容摘要、详情和列表所需的装配逻辑
|
|
1182
|
+
|
|
1183
|
+
## API 文档
|
|
1184
|
+
|
|
1185
|
+
${docsLink}
|
|
1186
|
+
|
|
1187
|
+
## 交付边界
|
|
1188
|
+
|
|
1189
|
+
- 内容实体、字段约束、slug、发布日期和标签等属于 content 模块
|
|
1190
|
+
- 页面视觉布局不在此模块内部完成
|
|
1191
|
+
- 后台编辑界面与审批流在 admin 模块中承接
|
|
1192
|
+
|
|
1193
|
+
## 测试要求
|
|
1194
|
+
|
|
1195
|
+
- 单元测试:内容模型映射、状态转换、列表/详情装配
|
|
1196
|
+
- 集成测试:docs/blog/changelog 的读取与预览链路
|
|
1197
|
+
- 回归验证:内容字段或状态机调整后同步验证页面消费方
|
|
1198
|
+
|
|
1199
|
+
## 关联文档
|
|
1200
|
+
|
|
1201
|
+
${relatedDocs}`,
|
|
1202
|
+
en: `# ${moduleName}
|
|
1203
|
+
|
|
1204
|
+
> Layer: module document
|
|
1205
|
+
> Parent: [src/SKILL.md](../../SKILL.md)
|
|
1206
|
+
|
|
1207
|
+
## Module Positioning
|
|
1208
|
+
|
|
1209
|
+
- Own the official-site content model, delivery boundaries, and publication state
|
|
1210
|
+
- Serve as the shared content source for web, docs, blog, and admin surfaces
|
|
1211
|
+
- Keep documentation, blog, and changelog entities consistent
|
|
1212
|
+
|
|
1213
|
+
## Responsibilities
|
|
1214
|
+
|
|
1215
|
+
- Define docs, blog, changelog, and site-setting entities
|
|
1216
|
+
- Manage draft, published, and preview states
|
|
1217
|
+
- Provide the assembly logic behind content lists, summaries, and detail views
|
|
1218
|
+
|
|
1219
|
+
## API Docs
|
|
1220
|
+
|
|
1221
|
+
${docsLink}
|
|
1222
|
+
|
|
1223
|
+
## Delivery Boundaries
|
|
1224
|
+
|
|
1225
|
+
- Entities, field constraints, slugs, publish dates, and tags belong here
|
|
1226
|
+
- Visual page composition does not belong inside this module
|
|
1227
|
+
- Admin editing and approval flows are handled by the admin module
|
|
1228
|
+
|
|
1229
|
+
## Testing Requirements
|
|
1230
|
+
|
|
1231
|
+
- Unit tests: model mapping, state transitions, list/detail assembly
|
|
1232
|
+
- Integration tests: docs/blog/changelog delivery and preview flow
|
|
1233
|
+
- Regression checks: validate all consuming surfaces after schema changes
|
|
1234
|
+
|
|
1235
|
+
## Related Docs
|
|
1236
|
+
|
|
1237
|
+
${relatedDocs}`,
|
|
1238
|
+
},
|
|
1239
|
+
admin: {
|
|
1240
|
+
zh: `# ${moduleName} 模块
|
|
1241
|
+
|
|
1242
|
+
> 层级:第 3 层(业务模块文档)
|
|
1243
|
+
> 上层:[src/SKILL.md](../../SKILL.md)
|
|
1244
|
+
|
|
1245
|
+
## 模块定位
|
|
1246
|
+
|
|
1247
|
+
- 负责官网内容管理后台、运营入口和内容发布操作台
|
|
1248
|
+
- 承接内容编辑、预览、发布与回滚相关工作流
|
|
1249
|
+
- 与 auth 模块协作,确保后台访问边界清晰
|
|
1250
|
+
|
|
1251
|
+
## 主要职责
|
|
1252
|
+
|
|
1253
|
+
- 维护后台首页、内容列表、内容编辑、发布操作入口
|
|
1254
|
+
- 定义后台所需的角色权限边界和操作日志关注点
|
|
1255
|
+
- 承接内容审核、发布、撤回和预览流程
|
|
1256
|
+
|
|
1257
|
+
## API 文档
|
|
1258
|
+
|
|
1259
|
+
${docsLink}
|
|
1260
|
+
|
|
1261
|
+
## 交付边界
|
|
1262
|
+
|
|
1263
|
+
- admin 模块只负责后台工作流与管理入口,不负责公开站点渲染
|
|
1264
|
+
- 内容实体本身由 content 模块负责
|
|
1265
|
+
- 登录、会话与鉴权校验由 auth 模块负责
|
|
1266
|
+
|
|
1267
|
+
## 测试要求
|
|
1268
|
+
|
|
1269
|
+
- 单元测试:后台菜单、内容状态动作、操作约束
|
|
1270
|
+
- 集成测试:登录后进入后台、编辑内容、预览和发布链路
|
|
1271
|
+
- 回归验证:权限边界与内容状态切换需要与 auth/content 同步验证
|
|
1272
|
+
|
|
1273
|
+
## 关联文档
|
|
1274
|
+
|
|
1275
|
+
${relatedDocs}`,
|
|
1276
|
+
en: `# ${moduleName}
|
|
1277
|
+
|
|
1278
|
+
> Layer: module document
|
|
1279
|
+
> Parent: [src/SKILL.md](../../SKILL.md)
|
|
1280
|
+
|
|
1281
|
+
## Module Positioning
|
|
1282
|
+
|
|
1283
|
+
- Own the admin workspace, operator entry points, and publishing console
|
|
1284
|
+
- Carry editing, preview, publish, and rollback workflows
|
|
1285
|
+
- Work with the auth module to keep admin access boundaries explicit
|
|
1286
|
+
|
|
1287
|
+
## Responsibilities
|
|
1288
|
+
|
|
1289
|
+
- Maintain the admin home, content list, editor flow, and publish actions
|
|
1290
|
+
- Define role-sensitive boundaries and operator-facing audit concerns
|
|
1291
|
+
- Handle review, publish, rollback, and preview steps
|
|
1292
|
+
|
|
1293
|
+
## API Docs
|
|
1294
|
+
|
|
1295
|
+
${docsLink}
|
|
1296
|
+
|
|
1297
|
+
## Delivery Boundaries
|
|
1298
|
+
|
|
1299
|
+
- This module owns the admin workflow and management surface, not public rendering
|
|
1300
|
+
- Content entities themselves belong to the content module
|
|
1301
|
+
- Login/session enforcement belongs to the auth module
|
|
1302
|
+
|
|
1303
|
+
## Testing Requirements
|
|
1304
|
+
|
|
1305
|
+
- Unit tests: menu config, content-state actions, admin guard behavior
|
|
1306
|
+
- Integration tests: login-to-admin, edit-to-preview, and publish flow
|
|
1307
|
+
- Regression checks: validate auth/content boundaries after workflow changes
|
|
1308
|
+
|
|
1309
|
+
## Related Docs
|
|
1310
|
+
|
|
1311
|
+
${relatedDocs}`,
|
|
1312
|
+
},
|
|
1313
|
+
auth: {
|
|
1314
|
+
zh: `# ${moduleName} 模块
|
|
1315
|
+
|
|
1316
|
+
> 层级:第 3 层(业务模块文档)
|
|
1317
|
+
> 上层:[src/SKILL.md](../../SKILL.md)
|
|
1318
|
+
|
|
1319
|
+
## 模块定位
|
|
1320
|
+
|
|
1321
|
+
- 负责官网登录、会话状态和后台访问保护
|
|
1322
|
+
- 为 admin 模块提供权限门禁,为 web 模块提供登录入口
|
|
1323
|
+
- 统一处理用户身份、重定向与会话校验
|
|
1324
|
+
|
|
1325
|
+
## 主要职责
|
|
1326
|
+
|
|
1327
|
+
- 登录页、退出登录、会话恢复和路由守卫
|
|
1328
|
+
- 后台入口鉴权、未登录跳转和基础角色判断
|
|
1329
|
+
- 与 auth api 协作,落地会话创建、读取和销毁
|
|
1330
|
+
|
|
1331
|
+
## API 文档
|
|
1332
|
+
|
|
1333
|
+
${docsLink}
|
|
1334
|
+
|
|
1335
|
+
## 交付边界
|
|
1336
|
+
|
|
1337
|
+
- 登录流程、会话状态、守卫逻辑属于 auth 模块
|
|
1338
|
+
- 用户内容资料和运营内容不在此模块内部维护
|
|
1339
|
+
- 更复杂的 RBAC 与多组织模型不属于官网初始化范围
|
|
1340
|
+
|
|
1341
|
+
## 测试要求
|
|
1342
|
+
|
|
1343
|
+
- 单元测试:会话状态、守卫逻辑、登录跳转
|
|
1344
|
+
- 集成测试:login -> admin、会话失效 -> 重定向、退出登录链路
|
|
1345
|
+
- 回归验证:权限边界变化后同步验证 admin 页面可达性
|
|
1346
|
+
|
|
1347
|
+
## 关联文档
|
|
1348
|
+
|
|
1349
|
+
${relatedDocs}`,
|
|
1350
|
+
en: `# ${moduleName}
|
|
1351
|
+
|
|
1352
|
+
> Layer: module document
|
|
1353
|
+
> Parent: [src/SKILL.md](../../SKILL.md)
|
|
1354
|
+
|
|
1355
|
+
## Module Positioning
|
|
1356
|
+
|
|
1357
|
+
- Own login, session state, and admin access protection
|
|
1358
|
+
- Provide admin gating for the admin module and login entry points for the web module
|
|
1359
|
+
- Centralize identity, redirects, and session validation
|
|
1360
|
+
|
|
1361
|
+
## Responsibilities
|
|
1362
|
+
|
|
1363
|
+
- Login/logout flows, session restore, and route guards
|
|
1364
|
+
- Admin access checks, unauthenticated redirects, and basic role handling
|
|
1365
|
+
- Integrate with the auth API for session create/read/destroy flows
|
|
1366
|
+
|
|
1367
|
+
## API Docs
|
|
1368
|
+
|
|
1369
|
+
${docsLink}
|
|
1370
|
+
|
|
1371
|
+
## Delivery Boundaries
|
|
1372
|
+
|
|
1373
|
+
- Login flow, session state, and guard logic belong to this module
|
|
1374
|
+
- User profile content and editorial content do not belong here
|
|
1375
|
+
- Advanced RBAC or multi-tenant models are out of scope for bootstrap
|
|
1376
|
+
|
|
1377
|
+
## Testing Requirements
|
|
1378
|
+
|
|
1379
|
+
- Unit tests: session state, guard logic, redirect behavior
|
|
1380
|
+
- Integration tests: login-to-admin, expired-session redirect, logout flow
|
|
1381
|
+
- Regression checks: revalidate admin reachability after auth-boundary changes
|
|
1382
|
+
|
|
1383
|
+
## Related Docs
|
|
1384
|
+
|
|
1385
|
+
${relatedDocs}`,
|
|
1386
|
+
},
|
|
1387
|
+
};
|
|
1388
|
+
const template = templates[moduleKey];
|
|
1389
|
+
if (!template) {
|
|
1390
|
+
return null;
|
|
1391
|
+
}
|
|
1392
|
+
return this.isEnglish(context.documentLanguage) ? template.en : template.zh;
|
|
1393
|
+
}
|
|
1394
|
+
getPresetApiAreaDocBody(context, apiAreaName) {
|
|
1395
|
+
if (context.projectPresetId !== 'official-site') {
|
|
1396
|
+
return null;
|
|
1397
|
+
}
|
|
1398
|
+
const key = apiAreaName.trim().toLowerCase();
|
|
1399
|
+
const templates = {
|
|
1400
|
+
'content api': {
|
|
1401
|
+
zh: `# ${apiAreaName}
|
|
1402
|
+
|
|
1403
|
+
## 项目
|
|
1404
|
+
|
|
1405
|
+
- **项目名称**:${context.projectName}
|
|
1406
|
+
|
|
1407
|
+
## 边界说明
|
|
1408
|
+
|
|
1409
|
+
- 提供 docs、blog、changelog、站点配置等内容读取能力
|
|
1410
|
+
- 区分公开读取、预览读取和后台内容操作的接口边界
|
|
1411
|
+
- 维护 slug、发布时间、标签、草稿态等内容语义
|
|
1412
|
+
|
|
1413
|
+
## 建议接口分组
|
|
1414
|
+
|
|
1415
|
+
- 内容列表:docs / blog / changelog 列表与筛选
|
|
1416
|
+
- 内容详情:按 slug 获取详情、相邻内容、关联内容
|
|
1417
|
+
- 预览接口:供 admin 模块预览草稿内容
|
|
1418
|
+
- 站点配置:导航、页脚、公告位等站点级内容
|
|
1419
|
+
|
|
1420
|
+
## 待补充清单
|
|
1421
|
+
|
|
1422
|
+
- [ ] 路由列表
|
|
1423
|
+
- [ ] 请求/响应结构
|
|
1424
|
+
- [ ] 预览权限与缓存策略
|
|
1425
|
+
- [ ] 测试与验收要求`,
|
|
1426
|
+
en: `# ${apiAreaName}
|
|
1427
|
+
|
|
1428
|
+
## Project
|
|
1429
|
+
|
|
1430
|
+
- **Project**: ${context.projectName}
|
|
1431
|
+
|
|
1432
|
+
## Boundary
|
|
1433
|
+
|
|
1434
|
+
- Provide content delivery for docs, blog, changelog, and site settings
|
|
1435
|
+
- Separate public delivery, preview delivery, and admin-side content operations
|
|
1436
|
+
- Own slugs, publication dates, tags, and draft/published semantics
|
|
1437
|
+
|
|
1438
|
+
## Suggested Interface Groups
|
|
1439
|
+
|
|
1440
|
+
- Content lists: docs/blog/changelog list and filtering
|
|
1441
|
+
- Content detail: fetch by slug with adjacent/related content
|
|
1442
|
+
- Preview interfaces: allow admin previews for draft content
|
|
1443
|
+
- Site settings: navigation, footer, and announcement content
|
|
1444
|
+
|
|
1445
|
+
## Checklist
|
|
1446
|
+
|
|
1447
|
+
- [ ] Routes
|
|
1448
|
+
- [ ] Request / response payloads
|
|
1449
|
+
- [ ] Preview permissions and cache strategy
|
|
1450
|
+
- [ ] Tests and acceptance requirements`,
|
|
1451
|
+
},
|
|
1452
|
+
'auth api': {
|
|
1453
|
+
zh: `# ${apiAreaName}
|
|
1454
|
+
|
|
1455
|
+
## 项目
|
|
1456
|
+
|
|
1457
|
+
- **项目名称**:${context.projectName}
|
|
1458
|
+
|
|
1459
|
+
## 边界说明
|
|
1460
|
+
|
|
1461
|
+
- 提供登录、会话读取、退出登录与后台访问鉴权能力
|
|
1462
|
+
- 为 admin 页面和登录页提供统一的身份状态接口
|
|
1463
|
+
- 约束未登录跳转、会话失效与基础角色判定
|
|
1464
|
+
|
|
1465
|
+
## 建议接口分组
|
|
1466
|
+
|
|
1467
|
+
- 登录接口:用户名/邮箱 + 密码或其他登录方式
|
|
1468
|
+
- 会话接口:当前会话读取、刷新、失效处理
|
|
1469
|
+
- 退出接口:会话销毁、清理与跳转
|
|
1470
|
+
- 后台守卫:校验是否允许进入 admin 相关页面
|
|
1471
|
+
|
|
1472
|
+
## 待补充清单
|
|
1473
|
+
|
|
1474
|
+
- [ ] 路由列表
|
|
1475
|
+
- [ ] 请求/响应结构
|
|
1476
|
+
- [ ] Cookie / token 策略
|
|
1477
|
+
- [ ] 测试与验收要求`,
|
|
1478
|
+
en: `# ${apiAreaName}
|
|
1479
|
+
|
|
1480
|
+
## Project
|
|
1481
|
+
|
|
1482
|
+
- **Project**: ${context.projectName}
|
|
1483
|
+
|
|
1484
|
+
## Boundary
|
|
1485
|
+
|
|
1486
|
+
- Provide login, session read, logout, and admin-access enforcement
|
|
1487
|
+
- Expose a shared identity surface for admin pages and login flows
|
|
1488
|
+
- Define unauthenticated redirects, session expiry handling, and basic role checks
|
|
1489
|
+
|
|
1490
|
+
## Suggested Interface Groups
|
|
1491
|
+
|
|
1492
|
+
- Login: username/email and credential entry
|
|
1493
|
+
- Session: read, refresh, and expiry handling
|
|
1494
|
+
- Logout: session destroy and redirect behavior
|
|
1495
|
+
- Admin guards: verify whether admin access is allowed
|
|
1496
|
+
|
|
1497
|
+
## Checklist
|
|
1498
|
+
|
|
1499
|
+
- [ ] Routes
|
|
1500
|
+
- [ ] Request / response payloads
|
|
1501
|
+
- [ ] Cookie / token strategy
|
|
1502
|
+
- [ ] Tests and acceptance requirements`,
|
|
1503
|
+
},
|
|
1504
|
+
'admin api': {
|
|
1505
|
+
zh: `# ${apiAreaName}
|
|
1506
|
+
|
|
1507
|
+
## 项目
|
|
1508
|
+
|
|
1509
|
+
- **项目名称**:${context.projectName}
|
|
1510
|
+
|
|
1511
|
+
## 边界说明
|
|
1512
|
+
|
|
1513
|
+
- 提供内容管理后台所需的编辑、发布、回滚和预览操作接口
|
|
1514
|
+
- 衔接 admin 模块的操作台与 content 模块的内容模型
|
|
1515
|
+
- 记录后台动作的权限边界和审核要求
|
|
1516
|
+
|
|
1517
|
+
## 建议接口分组
|
|
1518
|
+
|
|
1519
|
+
- 内容管理:创建、更新、删除、归档内容
|
|
1520
|
+
- 状态流转:草稿、送审、发布、撤回
|
|
1521
|
+
- 预览入口:生成预览链接和预览上下文
|
|
1522
|
+
- 操作审计:关键操作日志、操作者信息、发布时间
|
|
1523
|
+
|
|
1524
|
+
## 待补充清单
|
|
1525
|
+
|
|
1526
|
+
- [ ] 路由列表
|
|
1527
|
+
- [ ] 请求/响应结构
|
|
1528
|
+
- [ ] 权限与审核规则
|
|
1529
|
+
- [ ] 测试与验收要求`,
|
|
1530
|
+
en: `# ${apiAreaName}
|
|
1531
|
+
|
|
1532
|
+
## Project
|
|
1533
|
+
|
|
1534
|
+
- **Project**: ${context.projectName}
|
|
1535
|
+
|
|
1536
|
+
## Boundary
|
|
1537
|
+
|
|
1538
|
+
- Provide the edit, publish, rollback, and preview actions needed by the admin workspace
|
|
1539
|
+
- Connect the admin workspace to the content model owned by the content module
|
|
1540
|
+
- Define permission boundaries and approval expectations for operator actions
|
|
1541
|
+
|
|
1542
|
+
## Suggested Interface Groups
|
|
1543
|
+
|
|
1544
|
+
- Content management: create, update, delete, and archive content
|
|
1545
|
+
- State transitions: draft, review, publish, and unpublish
|
|
1546
|
+
- Preview entry: create preview links and preview context
|
|
1547
|
+
- Audit trail: operator identity, timestamps, and action logs
|
|
1548
|
+
|
|
1549
|
+
## Checklist
|
|
1550
|
+
|
|
1551
|
+
- [ ] Routes
|
|
1552
|
+
- [ ] Request / response payloads
|
|
1553
|
+
- [ ] Permissions and review rules
|
|
1554
|
+
- [ ] Tests and acceptance requirements`,
|
|
1555
|
+
},
|
|
1556
|
+
};
|
|
1557
|
+
const template = templates[key];
|
|
1558
|
+
if (!template) {
|
|
1559
|
+
return null;
|
|
1560
|
+
}
|
|
1561
|
+
return this.isEnglish(context.documentLanguage) ? template.en : template.zh;
|
|
1562
|
+
}
|
|
1563
|
+
getPresetModuleApiDocBody(context, moduleName, slug) {
|
|
1564
|
+
if (context.projectPresetId !== 'official-site') {
|
|
1565
|
+
return null;
|
|
1566
|
+
}
|
|
1567
|
+
const docs = {
|
|
1568
|
+
web: {
|
|
1569
|
+
zh: `# ${moduleName} Module API
|
|
1570
|
+
|
|
1571
|
+
## 项目
|
|
1572
|
+
|
|
1573
|
+
- **项目名称**:${context.projectName}
|
|
1574
|
+
- **模块名**:${moduleName}
|
|
1575
|
+
- **模块路径**:src/modules/${slug}
|
|
1576
|
+
|
|
1577
|
+
## 对外接口
|
|
1578
|
+
|
|
1579
|
+
- 导航配置:站点主导航、页脚导航、首页入口卡片
|
|
1580
|
+
- 首页编排:Hero、能力介绍、内容入口、CTA 区块装配
|
|
1581
|
+
- 页面装配:首页对 docs/blog/admin/login 的路由出口
|
|
1582
|
+
|
|
1583
|
+
## 依赖关系
|
|
1584
|
+
|
|
1585
|
+
- 上游依赖:content 模块提供内容摘要,auth 模块提供登录态入口信息
|
|
1586
|
+
- 下游调用方:app/page.tsx、全局布局、站点导航组件
|
|
1587
|
+
- 共享依赖:路由常量、站点配置、内容摘要类型
|
|
1588
|
+
|
|
1589
|
+
## 测试要求
|
|
1590
|
+
|
|
1591
|
+
- 单元测试:导航配置、首页区块装配
|
|
1592
|
+
- 集成测试:首页到 docs/blog/admin/login 的跳转
|
|
1593
|
+
- 回归验证:站点入口调整后校验官网 MVP 主链路`,
|
|
1594
|
+
en: `# ${moduleName} Module API
|
|
1595
|
+
|
|
1596
|
+
## Project
|
|
1597
|
+
|
|
1598
|
+
- **Project**: ${context.projectName}
|
|
1599
|
+
- **Module**: ${moduleName}
|
|
1600
|
+
- **Module path**: src/modules/${slug}
|
|
1601
|
+
|
|
1602
|
+
## Public Interface
|
|
1603
|
+
|
|
1604
|
+
- Navigation config: primary nav, footer nav, homepage entry cards
|
|
1605
|
+
- Homepage composition: hero, capability sections, content entry blocks, CTA assembly
|
|
1606
|
+
- Route composition: public exit points into docs, blog, admin, and login
|
|
1607
|
+
|
|
1608
|
+
## Dependencies
|
|
1609
|
+
|
|
1610
|
+
- Upstream: content summaries from the content module, auth entry signals from auth
|
|
1611
|
+
- Downstream consumers: app/page.tsx, global shell, navigation components
|
|
1612
|
+
- Shared dependencies: route constants, site config, content summary types
|
|
1613
|
+
|
|
1614
|
+
## Testing Requirements
|
|
1615
|
+
|
|
1616
|
+
- Unit tests: navigation config and homepage section assembly
|
|
1617
|
+
- Integration tests: home-to-docs/blog/admin/login routing
|
|
1618
|
+
- Regression checks: validate the official-site MVP flow after shell updates`,
|
|
1619
|
+
},
|
|
1620
|
+
};
|
|
1621
|
+
const template = docs[slug.toLowerCase()];
|
|
1622
|
+
if (!template) {
|
|
1623
|
+
return null;
|
|
1624
|
+
}
|
|
1625
|
+
return this.isEnglish(context.documentLanguage) ? template.en : template.zh;
|
|
1626
|
+
}
|
|
1627
|
+
getPresetDesignDocBody(context, docName) {
|
|
1628
|
+
if (context.projectPresetId !== 'official-site') {
|
|
1629
|
+
return null;
|
|
1630
|
+
}
|
|
1631
|
+
const key = docName.trim().toLowerCase();
|
|
1632
|
+
const isChinese = !this.isEnglish(context.documentLanguage);
|
|
1633
|
+
if (['ui information architecture', '界面信息架构'].includes(key)) {
|
|
1634
|
+
return isChinese
|
|
1635
|
+
? `# ${docName}
|
|
1636
|
+
|
|
1637
|
+
## 项目
|
|
1638
|
+
|
|
1639
|
+
- **项目名称**:${context.projectName}
|
|
1640
|
+
|
|
1641
|
+
## 设计目标
|
|
1642
|
+
|
|
1643
|
+
- 明确官网首页、docs、blog、admin、login 五个主入口的页面关系
|
|
1644
|
+
- 明确首页到各内容面的导航层级和返回路径
|
|
1645
|
+
- 保证营销展示、文档阅读、后台运营三种体验的边界清晰
|
|
1646
|
+
|
|
1647
|
+
## 核心页面
|
|
1648
|
+
|
|
1649
|
+
- 首页:品牌表达、核心能力、主入口导航
|
|
1650
|
+
- docs:文档中心首页、分类页、文档阅读页
|
|
1651
|
+
- blog:博客/更新日志列表与详情
|
|
1652
|
+
- admin:内容管理后台首页、内容列表、编辑与发布入口
|
|
1653
|
+
- login:登录与会话恢复入口
|
|
1654
|
+
|
|
1655
|
+
## 待验证问题
|
|
1656
|
+
|
|
1657
|
+
- 顶部导航与侧边导航如何避免重复信息
|
|
1658
|
+
- docs/blog/admin 三个入口的优先级如何表达
|
|
1659
|
+
- 未登录访问 admin 时的跳转与返回路径如何设计`
|
|
1660
|
+
: `# ${docName}
|
|
1661
|
+
|
|
1662
|
+
## Project
|
|
1663
|
+
|
|
1664
|
+
- **Project**: ${context.projectName}
|
|
1665
|
+
|
|
1666
|
+
## Design Goals
|
|
1667
|
+
|
|
1668
|
+
- Define the relationship across home, docs, blog, admin, and login
|
|
1669
|
+
- Clarify the navigation hierarchy from the homepage into each content surface
|
|
1670
|
+
- Keep marketing, reading, and admin experiences clearly separated
|
|
1671
|
+
|
|
1672
|
+
## Core Surfaces
|
|
1673
|
+
|
|
1674
|
+
- Home: brand expression, key capabilities, primary entry navigation
|
|
1675
|
+
- Docs: docs home, category pages, reading pages
|
|
1676
|
+
- Blog: changelog/blog list and detail views
|
|
1677
|
+
- Admin: dashboard, content list, editor, and publish entry
|
|
1678
|
+
- Login: login and session-restore entry
|
|
1679
|
+
|
|
1680
|
+
## Open Validation Questions
|
|
1681
|
+
|
|
1682
|
+
- How should top navigation and sidebar navigation avoid duplicate signals?
|
|
1683
|
+
- How should docs/blog/admin priority be communicated from the homepage?
|
|
1684
|
+
- What should the admin redirect and return path look like for unauthenticated users?`;
|
|
1685
|
+
}
|
|
1686
|
+
if (['content model', '内容模型'].includes(key)) {
|
|
1687
|
+
return isChinese
|
|
1688
|
+
? `# ${docName}
|
|
1689
|
+
|
|
1690
|
+
## 项目
|
|
1691
|
+
|
|
1692
|
+
- **项目名称**:${context.projectName}
|
|
1693
|
+
|
|
1694
|
+
## 设计目标
|
|
1695
|
+
|
|
1696
|
+
- 统一官网 docs、blog、changelog 与站点配置的内容实体
|
|
1697
|
+
- 明确草稿、预览、已发布等状态语义
|
|
1698
|
+
- 为后台内容管理与公开站点消费提供稳定字段约束
|
|
1699
|
+
|
|
1700
|
+
## 核心实体
|
|
1701
|
+
|
|
1702
|
+
- DocPage:文档页面、目录、版本、slug
|
|
1703
|
+
- BlogPost:博客/更新日志文章、摘要、发布时间、标签
|
|
1704
|
+
- SiteConfig:导航、页脚、公告位、首页重点内容
|
|
1705
|
+
- Author / Tag:作者与标签等复用内容
|
|
1706
|
+
|
|
1707
|
+
## 关键约束
|
|
1708
|
+
|
|
1709
|
+
- 所有公开内容都必须具备 slug、状态、最后更新时间
|
|
1710
|
+
- 预览内容不能被公开缓存
|
|
1711
|
+
- docs 与 blog 虽可共用字段,但必须保留独立内容类型`
|
|
1712
|
+
: `# ${docName}
|
|
1713
|
+
|
|
1714
|
+
## Project
|
|
1715
|
+
|
|
1716
|
+
- **Project**: ${context.projectName}
|
|
1717
|
+
|
|
1718
|
+
## Design Goals
|
|
1719
|
+
|
|
1720
|
+
- Unify docs, blog, changelog, and site-setting entities for the official site
|
|
1721
|
+
- Define draft, preview, and published semantics
|
|
1722
|
+
- Provide stable field constraints for both admin workflows and public rendering
|
|
1723
|
+
|
|
1724
|
+
## Core Entities
|
|
1725
|
+
|
|
1726
|
+
- DocPage: document page, hierarchy, version, slug
|
|
1727
|
+
- BlogPost: blog/changelog post, summary, publish date, tags
|
|
1728
|
+
- SiteConfig: navigation, footer, announcement slots, homepage highlights
|
|
1729
|
+
- Author / Tag: reusable author and taxonomy entities
|
|
1730
|
+
|
|
1731
|
+
## Key Constraints
|
|
1732
|
+
|
|
1733
|
+
- Every public content entity must have slug, status, and last-updated metadata
|
|
1734
|
+
- Preview content must never be publicly cached
|
|
1735
|
+
- Docs and blog may share fields, but must remain separate content types`;
|
|
1736
|
+
}
|
|
1737
|
+
if (['cms workflow', 'cms 工作流'].includes(key)) {
|
|
1738
|
+
return isChinese
|
|
1739
|
+
? `# ${docName}
|
|
1740
|
+
|
|
1741
|
+
## 项目
|
|
1742
|
+
|
|
1743
|
+
- **项目名称**:${context.projectName}
|
|
1744
|
+
|
|
1745
|
+
## 设计目标
|
|
1746
|
+
|
|
1747
|
+
- 规范后台内容从创建到发布的最小可演示流程
|
|
1748
|
+
- 明确编辑、预览、送审、发布、撤回之间的状态转换
|
|
1749
|
+
- 保证后台动作与公开站点的内容可见性一致
|
|
1750
|
+
|
|
1751
|
+
## 工作流阶段
|
|
1752
|
+
|
|
1753
|
+
- 草稿:编辑中,仅后台可见
|
|
1754
|
+
- 预览:生成预览上下文,供内部确认
|
|
1755
|
+
- 待发布:内容已冻结,等待操作人确认
|
|
1756
|
+
- 已发布:公开站点可见
|
|
1757
|
+
- 已撤回:公开站点不可见,但保留历史记录
|
|
1758
|
+
|
|
1759
|
+
## 验证重点
|
|
1760
|
+
|
|
1761
|
+
- 后台操作是否正确驱动 content 状态变化
|
|
1762
|
+
- 预览内容是否与公开内容严格隔离
|
|
1763
|
+
- 发布和撤回后首页、docs、blog 是否同步更新`
|
|
1764
|
+
: `# ${docName}
|
|
1765
|
+
|
|
1766
|
+
## Project
|
|
1767
|
+
|
|
1768
|
+
- **Project**: ${context.projectName}
|
|
1769
|
+
|
|
1770
|
+
## Design Goals
|
|
1771
|
+
|
|
1772
|
+
- Define the smallest demonstrable editorial flow from creation to publish
|
|
1773
|
+
- Make the transitions between edit, preview, review, publish, and rollback explicit
|
|
1774
|
+
- Keep admin actions and public-site visibility consistent
|
|
1775
|
+
|
|
1776
|
+
## Workflow Stages
|
|
1777
|
+
|
|
1778
|
+
- Draft: editable and admin-only
|
|
1779
|
+
- Preview: generates internal preview context
|
|
1780
|
+
- Ready to publish: content is frozen and awaiting operator confirmation
|
|
1781
|
+
- Published: publicly visible
|
|
1782
|
+
- Unpublished / rolled back: hidden from the public site with history retained
|
|
1783
|
+
|
|
1784
|
+
## Validation Focus
|
|
1785
|
+
|
|
1786
|
+
- Whether admin actions correctly drive content-state transitions
|
|
1787
|
+
- Whether preview content remains isolated from public delivery
|
|
1788
|
+
- Whether home/docs/blog refresh consistently after publish and rollback`;
|
|
1789
|
+
}
|
|
1790
|
+
return null;
|
|
1791
|
+
}
|
|
1792
|
+
getPresetPlanningDocBody(context, docName) {
|
|
1793
|
+
if (context.projectPresetId !== 'official-site') {
|
|
1794
|
+
return null;
|
|
1795
|
+
}
|
|
1796
|
+
const key = docName.trim().toLowerCase();
|
|
1797
|
+
const isChinese = !this.isEnglish(context.documentLanguage);
|
|
1798
|
+
if (['delivery plan', '交付计划'].includes(key)) {
|
|
1799
|
+
return isChinese
|
|
1800
|
+
? `# ${docName}
|
|
1801
|
+
|
|
1802
|
+
## 项目
|
|
1803
|
+
|
|
1804
|
+
- **项目名称**:${context.projectName}
|
|
1805
|
+
|
|
1806
|
+
## 规划目标
|
|
1807
|
+
|
|
1808
|
+
- 先完成官网 MVP 的页面骨架、内容链路和后台入口
|
|
1809
|
+
- 再补齐内容工作流、鉴权与上线准备
|
|
1810
|
+
|
|
1811
|
+
## 建议里程碑
|
|
1812
|
+
|
|
1813
|
+
- M1:首页、docs、blog、admin、login 五个入口可达
|
|
1814
|
+
- M2:content 模型与 content api 成型,docs/blog 能读取内容
|
|
1815
|
+
- M3:admin 工作台支持预览、发布与回滚的最小链路
|
|
1816
|
+
- M4:上线检查清单完成,进入发布准备
|
|
1817
|
+
|
|
1818
|
+
## 风险与依赖
|
|
1819
|
+
|
|
1820
|
+
- 内容模型与页面结构若先后失配,会导致前后端重复返工
|
|
1821
|
+
- admin 与 auth 边界若过晚定义,会影响后台主链路联调
|
|
1822
|
+
- SEO、分析、部署等上线项不能拖到最后才补`
|
|
1823
|
+
: `# ${docName}
|
|
1824
|
+
|
|
1825
|
+
## Project
|
|
1826
|
+
|
|
1827
|
+
- **Project**: ${context.projectName}
|
|
1828
|
+
|
|
1829
|
+
## Planning Goal
|
|
1830
|
+
|
|
1831
|
+
- Deliver the official-site MVP shell, content flow, and admin entry first
|
|
1832
|
+
- Then harden content workflow, auth, and launch readiness
|
|
1833
|
+
|
|
1834
|
+
## Suggested Milestones
|
|
1835
|
+
|
|
1836
|
+
- M1: home, docs, blog, admin, and login entry points are all reachable
|
|
1837
|
+
- M2: content model and content API are in place for docs/blog delivery
|
|
1838
|
+
- M3: admin supports the minimum preview/publish/rollback loop
|
|
1839
|
+
- M4: launch checklist is complete and release prep begins
|
|
1840
|
+
|
|
1841
|
+
## Risks and Dependencies
|
|
1842
|
+
|
|
1843
|
+
- If content modeling and page structure drift apart, rework will multiply
|
|
1844
|
+
- If admin/auth boundaries are delayed, the operator flow will stall
|
|
1845
|
+
- SEO, analytics, and deployment tasks cannot be postponed to the very end`;
|
|
1846
|
+
}
|
|
1847
|
+
if (['launch checklist', '上线检查清单'].includes(key)) {
|
|
1848
|
+
return isChinese
|
|
1849
|
+
? `# ${docName}
|
|
1850
|
+
|
|
1851
|
+
## 项目
|
|
1852
|
+
|
|
1853
|
+
- **项目名称**:${context.projectName}
|
|
1854
|
+
|
|
1855
|
+
## 检查目标
|
|
1856
|
+
|
|
1857
|
+
- 在官网发布前统一检查内容、导航、后台、鉴权和基础运维准备
|
|
1858
|
+
|
|
1859
|
+
## 上线前检查项
|
|
1860
|
+
|
|
1861
|
+
- [ ] 首页、docs、blog、admin、login 五个入口均可访问
|
|
1862
|
+
- [ ] docs/blog 的内容来源、slug 和 SEO 基础字段已检查
|
|
1863
|
+
- [ ] admin 登录、会话恢复、退出登录链路可用
|
|
1864
|
+
- [ ] 预览内容不会被公开访问或缓存
|
|
1865
|
+
- [ ] 关键页面具备基础埋点、错误页和空态处理
|
|
1866
|
+
- [ ] 发布与回滚流程经过至少一轮 smoke 验证`
|
|
1867
|
+
: `# ${docName}
|
|
1868
|
+
|
|
1869
|
+
## Project
|
|
1870
|
+
|
|
1871
|
+
- **Project**: ${context.projectName}
|
|
1872
|
+
|
|
1873
|
+
## Checklist Goal
|
|
1874
|
+
|
|
1875
|
+
- Align content, navigation, admin, auth, and operational readiness before launch
|
|
1876
|
+
|
|
1877
|
+
## Pre-launch Checks
|
|
1878
|
+
|
|
1879
|
+
- [ ] Home, docs, blog, admin, and login entry points are reachable
|
|
1880
|
+
- [ ] docs/blog content source, slug rules, and base SEO fields are reviewed
|
|
1881
|
+
- [ ] admin login, session restore, and logout flows work correctly
|
|
1882
|
+
- [ ] Preview content is never publicly reachable or cached
|
|
1883
|
+
- [ ] Key pages have baseline analytics, empty states, and error handling
|
|
1884
|
+
- [ ] Publish and rollback have passed at least one smoke validation round`;
|
|
1885
|
+
}
|
|
1886
|
+
return null;
|
|
1887
|
+
}
|
|
1888
|
+
slugify(value) {
|
|
1889
|
+
return value
|
|
1890
|
+
.toLowerCase()
|
|
1891
|
+
.replace(/\.md$/i, '')
|
|
1892
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
1893
|
+
.replace(/^-+|-+$/g, '');
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1896
|
+
exports.ProjectTemplateBuilder = ProjectTemplateBuilder;
|
|
1897
|
+
//# sourceMappingURL=ProjectTemplateBuilder.js.map
|