@openprd/cli 0.1.1 → 0.1.8

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.
Files changed (137) hide show
  1. package/.openprd/README.md +43 -69
  2. package/.openprd/README_EN.md +84 -0
  3. package/.openprd/benchmarks/index.md +7 -0
  4. package/.openprd/benchmarks/sources.yaml +25 -3
  5. package/.openprd/discovery/config.json +16 -2
  6. package/.openprd/engagements/active/flows.md +19 -14
  7. package/.openprd/engagements/active/handoff.md +11 -4
  8. package/.openprd/engagements/active/prd.md +99 -71
  9. package/.openprd/engagements/active/review.html +4 -4
  10. package/.openprd/engagements/active/roles.md +9 -8
  11. package/.openprd/engagements/work-units/wu-20260524015648-6d33ded7.json +4 -4
  12. package/.openprd/engagements/work-units/wu-20260602113956-a99b5b88.json +18 -0
  13. package/.openprd/engagements/work-units/wu-20260602122244-78656aaf.json +18 -0
  14. package/.openprd/engagements/work-units/wu-20260602122442-e96489e2.json +18 -0
  15. package/.openprd/engagements/work-units/wu-20260602132835-695429e8.json +18 -0
  16. package/.openprd/knowledge/candidates/candidate-turn-1780116203372-5f266a79e968c758/candidate.json +78 -0
  17. package/.openprd/knowledge/candidates/candidate-turn-1780116203372-5f266a79e968c758/diagnostic-report.json +129 -0
  18. package/.openprd/knowledge/candidates/candidate-turn-1780116203372-5f266a79e968c758/root-cause-candidates.json +41 -0
  19. package/.openprd/knowledge/candidates/candidate-turn-1780116203372-5f266a79e968c758/timeline.json +14 -0
  20. package/.openprd/knowledge/drafts/openprd-experience-diagnostic-candidate-turn-1780116203372-5f266a79e968c758/SKILL.md +49 -0
  21. package/.openprd/knowledge/index.json +44 -4
  22. package/.openprd/reviews/v0001.html +195 -129
  23. package/.openprd/reviews/v0002.html +1150 -0
  24. package/.openprd/reviews/v0003.html +1150 -0
  25. package/.openprd/reviews/v0004.html +1150 -0
  26. package/.openprd/reviews/v0005.html +1150 -0
  27. package/.openprd/standards/config.json +12 -9
  28. package/.openprd/state/changes.json +17 -2
  29. package/.openprd/state/current.json +399 -63
  30. package/.openprd/state/release-ledger.json +344 -0
  31. package/.openprd/state/version-index.json +52 -0
  32. package/.openprd/state/versions/v0002.json +264 -0
  33. package/.openprd/state/versions/v0002.md +183 -0
  34. package/.openprd/state/versions/v0003.json +269 -0
  35. package/.openprd/state/versions/v0003.md +188 -0
  36. package/.openprd/state/versions/v0004.json +274 -0
  37. package/.openprd/state/versions/v0004.md +193 -0
  38. package/.openprd/state/versions/v0005.json +299 -0
  39. package/.openprd/state/versions/v0005.md +189 -0
  40. package/.openprd/templates/agent/intake.md +5 -4
  41. package/.openprd/templates/b2b/intake.md +5 -4
  42. package/.openprd/templates/base/intake.md +10 -4
  43. package/.openprd/templates/company/README.md +9 -7
  44. package/.openprd/templates/company/README_EN.md +12 -0
  45. package/.openprd/templates/consumer/intake.md +5 -4
  46. package/.openprd/templates/industry/README.md +12 -10
  47. package/.openprd/templates/industry/README_EN.md +18 -0
  48. package/.openprd/templates/project/README.md +11 -9
  49. package/.openprd/templates/project/README_EN.md +16 -0
  50. package/.openprd/templates/session/README.md +11 -9
  51. package/.openprd/templates/session/README_EN.md +16 -0
  52. package/AGENTS.md +12 -8
  53. package/README.md +399 -438
  54. package/README_CN.md +4 -578
  55. package/README_EN.md +850 -0
  56. package/docs/assets/openprd-requirement-routing-en.png +0 -0
  57. package/docs/assets/openprd-requirement-routing-en.svg +102 -0
  58. package/docs/assets/openprd-requirement-routing-zh-refined.png +0 -0
  59. package/docs/assets/openprd-requirement-routing-zh.png +0 -0
  60. package/docs/assets/openprd-requirement-routing-zh.svg +102 -0
  61. package/package.json +6 -2
  62. package/scripts/dev-check-wrapup-copy.mjs +110 -0
  63. package/scripts/openprd-github-release-notes.mjs +99 -0
  64. package/scripts/quality-perf-check.mjs +203 -0
  65. package/skills/openprd-benchmark-router/SKILL.md +1 -0
  66. package/skills/openprd-benchmark-router/references/benchmark-sources.md +1 -0
  67. package/skills/openprd-benchmark-router/references/source-policy.md +2 -0
  68. package/skills/openprd-discovery-loop/SKILL.md +2 -2
  69. package/skills/openprd-harness/SKILL.md +46 -24
  70. package/skills/openprd-harness/references/workflow-gates.md +15 -0
  71. package/skills/openprd-quality/SKILL.md +10 -4
  72. package/skills/openprd-requirement-intake/SKILL.md +31 -20
  73. package/skills/openprd-requirement-intake/references/prd-template-lenses.md +6 -6
  74. package/skills/openprd-requirement-intake/references/routing-rubric.md +10 -2
  75. package/skills/openprd-router/SKILL.md +2 -2
  76. package/skills/openprd-shared/SKILL.md +51 -23
  77. package/skills/openprd-standards/SKILL.md +2 -1
  78. package/src/agent-integration.js +265 -65
  79. package/src/benchmark/constants.js +107 -0
  80. package/src/benchmark/operations.js +235 -0
  81. package/src/benchmark/registry.js +64 -0
  82. package/src/benchmark/render.js +115 -0
  83. package/src/benchmark/source.js +617 -0
  84. package/src/benchmark/storage.js +121 -0
  85. package/src/benchmark/verify.js +235 -0
  86. package/src/benchmark.js +50 -851
  87. package/src/change-summary.js +339 -0
  88. package/src/cli/args.js +67 -6
  89. package/src/cli/basic-print.js +365 -0
  90. package/src/cli/benchmark-print.js +91 -0
  91. package/src/cli/change-print.js +221 -0
  92. package/src/cli/doctor-print.js +268 -0
  93. package/src/cli/growth-print.js +176 -0
  94. package/src/cli/print.js +73 -1384
  95. package/src/cli/quality-print.js +284 -0
  96. package/src/cli/run-print.js +297 -0
  97. package/src/cli/shared-print.js +127 -0
  98. package/src/cli/workflow-print.js +195 -0
  99. package/src/codex-hook-runner-template.mjs +639 -117
  100. package/src/codex-runtime.js +324 -0
  101. package/src/dev-standards.js +178 -5
  102. package/src/diagram-core.js +5 -5
  103. package/src/discovery.js +2 -1
  104. package/src/execution-strategy.js +369 -0
  105. package/src/fleet.js +4 -0
  106. package/src/github-release.js +156 -0
  107. package/src/growth.js +311 -13
  108. package/src/html-artifact-utils.js +25 -0
  109. package/src/html-artifacts.js +157 -1596
  110. package/src/knowledge.js +1176 -75
  111. package/src/language-policy.js +2 -112
  112. package/src/learning-html-artifact.js +1031 -0
  113. package/src/learning-review.js +3 -2
  114. package/src/loop.js +280 -9
  115. package/src/openprd.js +341 -38
  116. package/src/openspec/change-validate.js +0 -9
  117. package/src/openspec/execute.js +79 -3
  118. package/src/openspec/generate.js +33 -20
  119. package/src/openspec/tasks.js +33 -2
  120. package/src/prd-core.js +10 -9
  121. package/src/product-type-copy.js +69 -0
  122. package/src/quality-html-artifact.js +108 -9
  123. package/src/quality-learning.js +30 -0
  124. package/src/quality-visual-review.js +237 -0
  125. package/src/quality.js +329 -43
  126. package/src/registry-hygiene.js +54 -0
  127. package/src/release-ledger.js +413 -0
  128. package/src/review-presentation.js +12 -6
  129. package/src/run-harness.js +722 -48
  130. package/src/session-binding.js +40 -3
  131. package/src/session-registry.js +159 -0
  132. package/src/standards.js +5 -3
  133. package/src/test-strategy.js +386 -0
  134. package/src/visual-compare.js +915 -34
  135. package/src/work-unit-migration.js +5 -1
  136. package/src/workspace-core.js +343 -19
  137. package/src/workspace-workflow.js +538 -134
package/src/cli/print.js CHANGED
@@ -1,1386 +1,73 @@
1
- function resolveActiveTemplatePack(ws) {
2
- return ws.data.currentState?.templatePack ?? ws.data.config?.activeTemplatePack ?? 'base';
3
- }
4
-
5
- function printValidation(report, json) {
6
- if (json) {
7
- console.log(JSON.stringify(report, null, 2));
8
- return;
9
- }
10
-
11
- if (report.valid) {
12
- console.log('OpenPrd 校验通过');
13
- if (report.warnings.length > 0) {
14
- console.log('警告:');
15
- for (const warning of report.warnings) {
16
- console.log(`- ${warning}`);
17
- }
18
- }
19
- return;
20
- }
21
-
22
- console.log('OpenPrd 校验失败');
23
- for (const error of report.errors) {
24
- console.log(`- ${error}`);
25
- }
26
- if (report.warnings.length > 0) {
27
- console.log('警告:');
28
- for (const warning of report.warnings) {
29
- console.log(`- ${warning}`);
30
- }
31
- }
32
- }
33
-
34
- function printStatus(ws, report, guidance, json) {
35
- const versionIndex = Array.isArray(ws.data.versionIndex) ? ws.data.versionIndex : [];
36
- const learningReview = ws.data.config?.learningReview ?? null;
37
- const summary = {
38
- projectRoot: ws.projectRoot,
39
- workspaceRoot: ws.workspaceRoot,
40
- schema: ws.data.schema?.name ?? null,
41
- templatePack: resolveActiveTemplatePack(ws),
42
- productTypes: ws.data.config?.supportedProductTypes ?? [],
43
- prdVersion: ws.data.currentState?.prdVersion ?? 0,
44
- latestVersionId: ws.data.currentState?.latestVersionId ?? versionIndex.at(-1)?.versionId ?? null,
45
- versionCount: versionIndex.length,
46
- valid: report.valid,
47
- errors: report.errors,
48
- warnings: report.warnings,
49
- activeEngagementStatus: ws.data.currentState?.status ?? 'unknown',
50
- scenario: guidance?.clarification?.scenario?.label ?? null,
51
- userParticipationMode: guidance?.clarification?.scenario?.userParticipation ?? null,
52
- currentGate: guidance?.gates?.currentGate ?? null,
53
- upcomingGate: guidance?.gates?.upcomingGate ?? null,
54
- learningReview,
55
- learningCurrent: ws.data.learningCurrent ?? null,
56
- };
57
-
58
- if (json) {
59
- console.log(JSON.stringify(summary, null, 2));
60
- return;
61
- }
62
-
63
- console.log(`工作区: ${summary.workspaceRoot}`);
64
- console.log(`Schema: ${summary.schema}`);
65
- console.log(`模板包: ${summary.templatePack}`);
66
- console.log(`产品类型: ${summary.productTypes.join(', ')}`);
67
- console.log(`PRD 版本: ${summary.prdVersion}`);
68
- console.log(`最新版本: ${summary.latestVersionId ?? '无'}`);
69
- console.log(`版本数量: ${summary.versionCount}`);
70
- console.log(`状态: ${summary.activeEngagementStatus}`);
71
- if (summary.scenario) {
72
- console.log(`场景: ${summary.scenario}`);
73
- }
74
- if (summary.userParticipationMode) {
75
- console.log(`用户参与模式: ${summary.userParticipationMode}`);
76
- }
77
- if (summary.currentGate) {
78
- console.log(`当前门禁: ${summary.currentGate}`);
79
- }
80
- if (summary.upcomingGate) {
81
- console.log(`后续门禁: ${summary.upcomingGate}`);
82
- }
83
- if (summary.learningReview) {
84
- console.log(`复盘学习模式: ${summary.learningReview.enabled !== false ? '开启' : '关闭'}`);
85
- console.log(`默认题材: ${summary.learningReview.defaultGenre ?? 'internet-product'}`);
86
- console.log(`自动打开: ${summary.learningReview.autoOpen !== false ? '是' : '否'}`);
87
- console.log(`来源范围: ${summary.learningReview.sourceScope ?? 'workspace'}`);
88
- }
89
- if (summary.learningCurrent?.packageId) {
90
- console.log(`最近学习包: ${summary.learningCurrent.packageId}`);
91
- }
92
- console.log(`验证: ${summary.valid ? '通过' : '失败'}`);
93
- if (summary.errors.length > 0) {
94
- console.log('错误:');
95
- for (const error of summary.errors) {
96
- console.log(`- ${error}`);
97
- }
98
- }
99
- if (summary.warnings.length > 0) {
100
- console.log('警告:');
101
- for (const warning of summary.warnings) {
102
- console.log(`- ${warning}`);
103
- }
104
- }
105
- }
106
-
107
- function printClassifyResult(result, json) {
108
- if (json) {
109
- console.log(JSON.stringify(result, null, 2));
110
- return;
111
- }
112
-
113
- console.log(`已分类产品类型: ${result.currentState.productType}`);
114
- console.log(`模板包: ${result.currentState.templatePack}`);
115
- }
116
-
117
- function printClarifyResult(result, json) {
118
- if (json) {
119
- console.log(JSON.stringify(result, null, 2));
120
- return;
121
- }
122
-
123
- console.log(`需要澄清: ${result.ws.workspaceRoot}`);
124
- console.log(`场景: ${result.clarification.scenario.label}`);
125
- console.log(`用户参与: ${result.clarification.scenario.userParticipation}`);
126
- console.log(`待确认关键信息: ${result.clarification.missingRequiredFields}`);
127
- console.log(`待确认问题: ${result.clarification.mustAskUser.length}`);
128
- if (result.clarifyPresentation) {
129
- console.log(`澄清呈现: ${result.clarifyPresentation.label}`);
130
- console.log(`呈现原因: ${result.clarifyPresentation.reason}`);
131
- }
132
- console.log('建议先确认的问题:');
133
- for (const item of result.clarification.mustAskUser) {
134
- console.log(`- ${item.prompt}`);
135
- }
136
- if (result.inlineClarification) {
137
- console.log('对话内澄清提纲:');
138
- for (const line of result.inlineClarification.lines) {
139
- console.log(line);
140
- }
141
- console.log('无需打开 HTML;请把上面的目标、范围、非目标和验收方式压缩给用户确认。');
142
- }
143
- if (result.clarification.canInferLater.length > 0) {
144
- console.log('之后可以再补充或细化:');
145
- for (const item of result.clarification.canInferLater.slice(0, 5)) {
146
- console.log(`- ${item.prompt}`);
147
- }
148
- }
149
- }
150
-
151
- function printCaptureResult(result, json) {
152
- if (json) {
153
- console.log(JSON.stringify(result, null, 2));
154
- return;
155
- }
156
-
157
- if (result.applied?.length > 1) {
158
- console.log(`已捕获 ${result.applied.length} 个字段`);
159
- for (const item of result.applied) {
160
- console.log(`- ${item.field} (${item.source}): ${JSON.stringify(item.value)}`);
161
- }
162
- } else {
163
- console.log(`已捕获 ${result.field}`);
164
- console.log(`状态 key: ${result.stateKey}`);
165
- console.log(`来源: ${result.source}`);
166
- console.log(`值: ${JSON.stringify(result.value)}`);
167
- }
168
- if (result.artifactMarkdown) {
169
- console.log(`来源 artifact markdown: ${result.artifactMarkdown}`);
170
- }
171
- console.log(`剩余缺失必填字段: ${result.analysis.missingRequiredFields}`);
172
- }
173
-
174
- function printInterviewResult(result, json) {
175
- if (json) {
176
- console.log(JSON.stringify(result, null, 2));
177
- return;
178
- }
179
-
180
- console.log(`访谈模式: ${result.productType ?? '未分类'}`);
181
- console.log(`来源文件: ${result.sourceFiles.join(', ')}`);
182
- console.log(result.transcript);
183
- }
184
-
185
- function printPlaygroundResult(result, json) {
186
- if (json) {
187
- console.log(JSON.stringify(result, null, 2));
188
- return;
189
- }
190
-
191
- console.log(`已生成 Playground: ${result.snapshot.title}`);
192
- console.log(`HTML: ${result.htmlPath}`);
193
- console.log(`Markdown 数据源: ${result.markdownPath}`);
194
- console.log(`捕获补丁: ${result.patchPath}`);
195
- console.log(`已打开: ${result.opened ? '是' : '否'}`);
196
- }
197
-
198
- function printLearningResult(result, json) {
199
- if (json) {
200
- console.log(JSON.stringify(result, null, 2));
201
- return;
202
- }
203
-
204
- if (result.action === 'learning-review-config') {
205
- console.log(`复盘学习模式: ${result.enabled ? '已开启' : '已关闭'}`);
206
- console.log(`默认题材: ${result.config?.defaultGenre ?? 'internet-product'}`);
207
- console.log(`自动打开: ${result.config?.autoOpen !== false ? '是' : '否'}`);
208
- return;
209
- }
210
-
211
- if (result.skipped) {
212
- console.log('复盘学习包: 已跳过');
213
- console.log(`原因: ${result.reason}`);
214
- return;
215
- }
216
-
217
- console.log(`复盘学习包: ${result.packageId}`);
218
- console.log(`题材: ${result.genre?.label ?? result.packageMeta?.genreLabel ?? '未知'}`);
219
- if (result.packageMeta?.styleLabel || result.content?.stylePromptPack?.label) {
220
- console.log(`子风格: ${result.packageMeta?.styleLabel ?? result.content?.stylePromptPack?.label}`);
221
- }
222
- console.log(`主题: ${result.content?.topic ?? result.packageMeta?.topic ?? '未知'}`);
223
- if (result.packageMeta?.authoringStatus) {
224
- console.log(`写作状态: ${result.packageMeta.authoringStatus}`);
225
- }
226
- console.log(`HTML: ${result.packagePaths?.readerHtml ?? '无'}`);
227
- console.log(`内容合同: ${result.packagePaths?.contentJson ?? '无'}`);
228
- console.log(`证据清单: ${result.packagePaths?.evidenceManifest ?? '无'}`);
229
- if (result.packagePaths?.agentPrompt) {
230
- console.log(`Agent 写作提示: ${result.packagePaths.agentPrompt}`);
231
- }
232
- if (result.packagePaths?.agentContext) {
233
- console.log(`Agent 上下文: ${result.packagePaths.agentContext}`);
234
- }
235
- console.log(`已打开: ${result.opened ? '是' : '否'}`);
236
- }
237
-
238
-
239
- function printSynthesizeResult(result, json) {
240
- if (json) {
241
- console.log(JSON.stringify(result, null, 2));
242
- return;
243
- }
244
-
245
- console.log(`已合成 PRD 版本 ${result.snapshot.versionId}`);
246
- console.log(`标题: ${result.snapshot.title}`);
247
- console.log(`产品类型: ${result.snapshot.productType ?? '未分类'}`);
248
- console.log(`摘要指纹: ${result.snapshot.digest}`);
249
- if (result.workUnitId) {
250
- console.log(`工作单元: ${result.workUnitId}`);
251
- }
252
- if (!result.reviewPresentationRequired && (result.reviewPath ?? result.stableReviewArtifact)) {
253
- console.log(`评审面板: ${result.reviewPath ?? result.stableReviewArtifact}`);
254
- }
255
- if (!result.reviewPresentationRequired && (result.reviewEntryPath ?? result.reviewArtifact)) {
256
- console.log(`固定入口: ${result.reviewEntryPath ?? result.reviewArtifact}`);
257
- }
258
- console.log(`已打开评审面板: ${result.opened ? '是' : '否'}`);
259
- if (result.reviewPresentationRequired) {
260
- console.log('评审面板: 尚未生成可确认页面');
261
- console.log('下一步: 先运行 openprd review-presentation . --template,填写 presentation JSON 后运行 openprd review-presentation . --presentation <json> --write --fail-on-violation。');
262
- const feedback = result.reviewPresentationGate?.violations ?? [];
263
- for (const item of feedback.slice(0, 6)) {
264
- const pathHint = item.jsonPath ? `${item.jsonPath}: ` : '';
265
- console.log(`- ${pathHint}${item.action}`);
266
- }
267
- } else if (result.reviewPath ?? result.stableReviewArtifact) {
268
- console.log('请让用户先评审版本绑定的评审面板;用户确认后,使用页面复制出的带 version/digest/work-unit 的命令记录确认。');
269
- }
270
- }
271
-
272
- function printReviewResult(result, json) {
273
- if (json) {
274
- console.log(JSON.stringify(result, null, 2));
275
- return;
276
- }
277
-
278
- if (!result.ok) {
279
- console.log('PRD 评审状态不可用');
280
- for (const error of result.errors ?? []) {
281
- console.log(`- ${error}`);
282
- }
283
- if (result.requiredCommand) {
284
- console.log(`下一步: ${result.requiredCommand}`);
285
- }
286
- for (const item of (result.presentationFeedback ?? []).slice(0, 6)) {
287
- const pathHint = item.jsonPath ? `${item.jsonPath}: ` : '';
288
- console.log(`- ${pathHint}${item.action}`);
289
- }
290
- return;
291
- }
292
-
293
- console.log(`PRD 评审状态: ${result.status}`);
294
- console.log(`版本: ${result.versionId}`);
295
- if (result.workUnitId) {
296
- console.log(`工作单元: ${result.workUnitId}`);
297
- }
298
- console.log(`HTML 评审面板: ${result.reviewPath ?? result.stableReviewArtifact ?? result.reviewArtifact}`);
299
- if (result.marked) {
300
- console.log(`已从 ${result.previousStatus} 更新为 ${result.status}`);
301
- }
302
- if (result.opened) {
303
- console.log('已打开评审面板');
304
- }
305
- }
306
-
307
- function printHistoryResult(result, json) {
308
- if (json) {
309
- console.log(JSON.stringify(result, null, 2));
310
- return;
311
- }
312
-
313
- console.log(`版本历史: ${result.ws.workspaceRoot}`);
314
- for (const entry of result.versions) {
315
- console.log(`- ${entry.versionId} | ${entry.title} | ${entry.productType ?? '未分类'} | ${entry.createdAt}`);
316
- }
317
- }
318
-
319
- function printDiffResult(result, json) {
320
- if (json) {
321
- console.log(JSON.stringify(result.diff, null, 2));
322
- return;
323
- }
324
-
325
- console.log(`差异 ${result.diff.fromVersionId} -> ${result.diff.toVersionId}`);
326
- console.log(`变更章节: ${result.diff.changedSections.length > 0 ? result.diff.changedSections.join(', ') : '无'}`);
327
- for (const change of result.diff.changes) {
328
- console.log(`- ${change.path}: ${JSON.stringify(change.before)} -> ${JSON.stringify(change.after)}`);
329
- }
330
- }
331
-
332
-
333
- function printNextResult(result, json) {
334
- if (json) {
335
- console.log(JSON.stringify(result, null, 2));
336
- return;
337
- }
338
-
339
- const { recommendation, analysis, workflow, taskGraph } = result;
340
- console.log(`下一步动作: ${recommendation.nextAction}`);
341
- if (recommendation.currentGate) {
342
- console.log(`当前门禁: ${recommendation.currentGate}`);
343
- }
344
- if (recommendation.upcomingGate) {
345
- console.log(`后续门禁: ${recommendation.upcomingGate}`);
346
- }
347
- console.log(`原因: ${recommendation.reason}`);
348
- console.log(`建议命令: ${recommendation.suggestedCommand}`);
349
- console.log(`完成度: ${analysis.completedRequiredFields}/${analysis.totalRequiredFields}`);
350
- if (taskGraph?.nextReadyNode) {
351
- console.log(`下一个就绪节点: ${taskGraph.nextReadyNode}`);
352
- }
353
- if (result.diagramState?.needed) {
354
- console.log(`图表门禁: ${result.diagramState.shouldGateFreeze ? '激活' : '已满足'}`);
355
- console.log(`建议图表: ${result.diagramState.preferredType}`);
356
- }
357
- console.log('工作流:');
358
- console.log(` ${workflow.join(' -> ')}`);
359
- if (recommendation.suggestedQuestions.length > 0) {
360
- console.log('建议问题:');
361
- for (const question of recommendation.suggestedQuestions) {
362
- console.log(`- ${question}`);
363
- }
364
- }
365
- }
366
-
367
- function printInitResult(result, json) {
368
- if (json) {
369
- console.log(JSON.stringify(result, null, 2));
370
- return;
371
- }
372
-
373
- console.log(`已初始化 OpenPrd 工作区: ${result.ws.workspaceRoot}`);
374
- console.log(`模板包: ${result.currentState.templatePack}`);
375
- console.log(`已复制种子文件: ${result.created}`);
376
- if (result.standards) {
377
- console.log(`标准化文档: ${result.standards.docsRoot}`);
378
- }
379
- if (result.agentIntegration) {
380
- console.log(`Agent 引导: ${result.agentIntegration.ok ? '已启用' : '需修复'} (${result.agentIntegration.tools.join(', ')})`);
381
- if (result.agentIntegration.hookProfile) {
382
- console.log(`Hook 模式: ${result.agentIntegration.hookProfile}`);
383
- }
384
- }
385
- }
386
-
387
- function printAgentIntegrationResult(result, json) {
388
- if (json) {
389
- console.log(JSON.stringify(result, null, 2));
390
- return;
391
- }
392
-
393
- console.log(`OpenPrd agent ${result.action}: ${result.ok ? '通过' : '需修复'}`);
394
- console.log(`项目: ${result.projectRoot}`);
395
- console.log(`工具: ${result.tools.join(', ')}`);
396
- if (result.hookProfile) {
397
- console.log(`Hook 模式: ${result.hookProfile}`);
398
- }
399
- if (result.initialized) {
400
- console.log(`已初始化工作区: ${result.init.workspaceRoot}`);
401
- }
402
- if (result.standards) {
403
- console.log(`标准化文档: ${result.standards.docsRoot}`);
404
- }
405
- if (result.migration) {
406
- const changed = result.migration.changes.filter((change) => change.status !== 'unchanged').length;
407
- console.log(`工作区迁移: ${changed} 项`);
408
- }
409
- if (result.registry) {
410
- console.log(`全局 registry: ${result.registry.status === 'created' ? '已登记' : '已刷新'} (${result.registry.registryPath})`);
411
- }
412
- console.log('变更:');
413
- for (const change of result.changes) {
414
- const detail = change.message ? ` (${change.message})` : '';
415
- console.log(`- ${change.status}: ${change.path}${detail}`);
416
- if (change.repairHint) {
417
- console.log(` 修复建议: ${change.repairHint}`);
418
- }
419
- }
420
- if (result.doctor?.errors?.length > 0) {
421
- console.log('待处理:');
422
- for (const error of result.doctor.errors) {
423
- console.log(`- ${error}`);
424
- }
425
- }
426
- }
427
-
428
- function doctorCheckLabel(check) {
429
- if (check.ok) return '通过';
430
- if (check.reason === 'missing-file') return '缺失';
431
- if (check.reason === 'missing-generated-marker') return '未受管';
432
- if (check.reason === 'checksum-drift') return '漂移';
433
- return '失败';
434
- }
435
-
436
- function printDoctorResult(result, json) {
437
- if (json) {
438
- console.log(JSON.stringify(result, null, 2));
439
- return;
440
- }
441
-
442
- console.log(`OpenPrd doctor: ${result.ok ? '通过' : '失败'}`);
443
- console.log(`项目: ${result.projectRoot}`);
444
- console.log(`工具: ${result.tools.join(', ')}`);
445
- if (result.agentIntegration.hookProfile) {
446
- console.log(`Hook 模式: ${result.agentIntegration.hookProfile}`);
447
- }
448
- console.log(`标准化: ${result.standards.ok ? '通过' : '失败'}`);
449
- console.log(`工作区验证: ${result.validation.valid ? '通过' : '失败'}`);
450
- if (result.agentIntegration.drift) {
451
- console.log(`生成物漂移: ${result.agentIntegration.drift.ok ? '无' : '存在'}`);
452
- }
453
- console.log('Agent 集成检查:');
454
- for (const check of result.agentIntegration.checks) {
455
- const reason = !check.ok && check.reason ? ` (${check.reason})` : '';
456
- console.log(`- ${doctorCheckLabel(check)}: ${check.path}${reason}`);
457
- if (!check.ok && check.repairHint) {
458
- console.log(` 修复建议: ${check.repairHint}`);
459
- }
460
- }
461
- if (result.errors.length > 0) {
462
- console.log('错误:');
463
- for (const error of result.errors) {
464
- console.log(`- ${error}`);
465
- }
466
- }
467
- }
468
-
469
- function printFleetResult(result, json) {
470
- if (json) {
471
- console.log(JSON.stringify(result, null, 2));
472
- return;
473
- }
474
-
475
- const mode = result.dryRun
476
- ? 'dry-run'
477
- : Object.entries(result.requestedActions)
478
- .filter(([, enabled]) => enabled)
479
- .map(([name]) => name)
480
- .join(', ');
481
- console.log(`OpenPrd fleet: ${result.ok ? '通过' : '需处理'}`);
482
- console.log(`根目录: ${result.root}`);
483
- console.log(`模式: ${mode || 'report'}`);
484
- console.log(`最大深度: ${result.maxDepth}`);
485
- console.log(`项目: ${result.summary.total}`);
486
- console.log(`- OpenPrd: ${result.summary.openprd}`);
487
- console.log(`- Agent-only: ${result.summary.agentConfigured}`);
488
- console.log(`- Plain: ${result.summary.plain}`);
489
- console.log(`结果: 计划 ${result.summary.planned},已更新 ${result.summary.updated},已接入 ${result.summary.setup},已检查 ${result.summary.doctored},已补身份 ${result.summary.backfilled},已同步 registry ${result.summary.synced},失败 ${result.summary.failed},跳过 ${result.summary.skipped}`);
490
- if (result.registry) {
491
- console.log(`全局 registry: 已知 ${result.registry.knownTotal},当前 root 命中 ${result.registry.scopedKnown},root 外 ${result.registry.outsideRoot},失效 ${result.registry.stale}`);
492
- }
493
- if ((result.summary.healthAttention ?? 0) > 0) {
494
- console.log(`项目健康: ${result.summary.healthAttention} 个需关注(已报告,不阻断本次更新)`);
495
- }
496
-
497
- const visibleProjects = result.projects
498
- .filter((project) => project.category !== 'plain-project' || project.status === 'failed' || (project.healthErrors?.length ?? 0) > 0)
499
- .slice(0, 50);
500
- if (visibleProjects.length > 0) {
501
- console.log('项目明细:');
502
- for (const project of visibleProjects) {
503
- console.log(`- ${project.status}: ${project.relativePath} (${project.category}) -> ${project.plannedAction}`);
504
- if (project.workUnits) {
505
- console.log(` 工作单元: ${project.workUnits.changedVersions}/${project.workUnits.totalVersions} 个历史版本已覆盖或计划覆盖`);
506
- }
507
- for (const error of project.errors.slice(0, 3)) {
508
- console.log(` 错误: ${error}`);
509
- }
510
- for (const error of (project.healthErrors ?? []).slice(0, 3)) {
511
- console.log(` 需关注: ${error}`);
512
- }
513
- }
514
- }
515
- const hiddenCount = result.projects.length - visibleProjects.length;
516
- if (hiddenCount > 0) {
517
- console.log(`还有 ${hiddenCount} 个 plain/skipped 项目未展开;使用 --json 查看完整明细。`);
518
- }
519
- if (result.reportPath) {
520
- console.log(`报告: ${result.reportPath}`);
521
- }
522
- }
523
-
524
- function printSelfUpdateResult(result, json) {
525
- if (json) {
526
- console.log(JSON.stringify(result, null, 2));
527
- return;
528
- }
529
-
530
- const status = result.dryRun
531
- ? '预演'
532
- : result.ok
533
- ? '完成'
534
- : result.skipped
535
- ? '已跳过'
536
- : '失败';
537
- console.log(`OpenPrd self-update: ${status}`);
538
- console.log(`当前版本: ${result.package?.version ?? 'unknown'}`);
539
- console.log(`安装源: ${result.source}`);
540
- console.log(`计划命令: ${result.installCommand.display}`);
541
- if (result.localCheckout) {
542
- console.log('运行环境: 本地源码 checkout');
543
- }
544
- if (result.dryRun) {
545
- console.log('dry-run: 未修改 CLI、项目或 registry。');
546
- }
547
- if (result.result) {
548
- console.log(`安装退出码: ${result.result.exitCode}`);
549
- }
550
- if (result.resolvedExecutable?.executable) {
551
- console.log(`OpenPrd 可执行文件: ${result.resolvedExecutable.executable}`);
552
- }
553
- for (const action of result.nextActions ?? []) {
554
- console.log(`下一步: ${action}`);
555
- }
556
- for (const error of result.errors ?? []) {
557
- console.log(`错误: ${error}`);
558
- }
559
- }
560
-
561
- function printUpgradeResult(result, json) {
562
- if (json) {
563
- console.log(JSON.stringify(result, null, 2));
564
- return;
565
- }
566
-
567
- console.log(`OpenPrd upgrade: ${result.dryRun ? '预演' : result.ok ? '完成' : '失败'}`);
568
- console.log(`模式: ${result.mode === 'fleet' ? '历史项目批量刷新' : '单项目刷新'}`);
569
- console.log(`目标: ${result.targetPath}`);
570
- console.log(`阶段 self-update: ${result.stages.selfUpdateOk ? '通过' : '失败'}`);
571
- console.log(`阶段 project-refresh: ${result.stages.projectRefreshOk ? '通过' : result.projectRefresh.skipped ? '跳过' : '失败'}`);
572
- console.log(`self-update 命令: ${result.selfUpdate.installCommand.display}`);
573
- console.log(`项目刷新命令: ${result.projectRefresh.command.display}`);
574
- if (result.dryRun) {
575
- console.log('dry-run: 未执行工具更新,也未刷新项目。');
576
- }
577
- if (result.selfUpdate.result) {
578
- console.log(`self-update 退出码: ${result.selfUpdate.result.exitCode}`);
579
- }
580
- if (result.projectRefresh.result) {
581
- console.log(`project-refresh 退出码: ${result.projectRefresh.result.exitCode}`);
582
- }
583
- for (const error of result.errors ?? []) {
584
- console.log(`错误: ${error}`);
585
- }
586
- }
587
-
588
- function printKnowledgeReview(knowledgeReview) {
589
- if (!knowledgeReview) {
590
- return;
591
- }
592
- if (knowledgeReview.skipped) {
593
- console.log(`项目经验回顾: 已跳过 (${knowledgeReview.reason})`);
594
- return;
595
- }
596
- if (knowledgeReview.ok === false) {
597
- console.log(`项目经验回顾: 失败 (${knowledgeReview.errors?.[0] ?? 'unknown'})`);
598
- return;
599
- }
600
- console.log(`项目经验草案: ${knowledgeReview.candidateId}`);
601
- if (knowledgeReview.summary) {
602
- console.log(`摘要: ${knowledgeReview.summary}`);
603
- }
604
- if (Array.isArray(knowledgeReview.categories) && knowledgeReview.categories.length > 0) {
605
- console.log(`类别: ${knowledgeReview.categories.join(', ')}`);
606
- }
607
- if (knowledgeReview.files?.draftSkill) {
608
- console.log(`Draft Skill: ${knowledgeReview.files.draftSkill}`);
609
- }
610
- if (knowledgeReview.files?.candidateDir) {
611
- console.log(`诊断候选: ${knowledgeReview.files.candidateDir}`);
612
- }
613
- if (knowledgeReview.suggestedLearnCommand) {
614
- console.log(`Promote: ${knowledgeReview.suggestedLearnCommand}`);
615
- }
616
- }
617
-
618
- function printRunResult(result, json) {
619
- if (json) {
620
- console.log(JSON.stringify(result, null, 2));
621
- return;
622
- }
623
-
624
- if (result.action === 'run-record-hook') {
625
- console.log(`OpenPrd run hook 已记录: ${result.event.eventName} -> ${result.event.outcome}`);
626
- console.log(`迭代记录: ${result.files.iterations}`);
627
- return;
628
- }
629
-
630
- if (result.action === 'run-verify') {
631
- const taskReady = result.readiness?.taskReady !== false;
632
- const workspaceReady = result.readiness?.workspaceReady !== false;
633
- const status = taskReady
634
- ? (workspaceReady ? '通过' : '当前任务通过,工作区待关注')
635
- : '当前任务失败';
636
- console.log(`OpenPrd run verify: ${status}`);
637
- if (result.readiness) {
638
- console.log(`任务就绪: ${taskReady ? '是' : '否'}`);
639
- console.log(`工作区就绪: ${workspaceReady ? '是' : '否'}`);
640
- if (result.readiness.qualityProductionReady !== null) {
641
- console.log(`质量门禁: ${result.readiness.qualityProductionReady ? 'production-ready' : '待补证据'}`);
642
- }
643
- }
644
- for (const check of result.checks) {
645
- const scope = check.scope === 'workspace' ? '工作区' : '任务';
646
- const detail = check.name === 'quality' && check.productionReady === false
647
- ? ' (production-ready=false)'
648
- : '';
649
- console.log(`- ${check.ok ? '通过' : '失败'}: ${check.name} [${scope}]${detail}`);
650
- }
651
- printKnowledgeReview(result.knowledgeReview);
652
- if (result.warnings.length > 0) {
653
- console.log('工作区待关注:');
654
- for (const warning of result.warnings) {
655
- console.log(`- ${warning}`);
656
- }
657
- }
658
- if (result.errors.length > 0) {
659
- console.log('错误:');
660
- for (const error of result.errors) {
661
- console.log(`- ${error}`);
662
- }
663
- }
664
- return;
665
- }
666
-
667
- console.log('OpenPrd 运行上下文');
668
- console.log(`项目: ${result.projectRoot}`);
669
- console.log(`验证: ${result.validation.valid ? '通过' : '失败'}`);
670
- if (result.lane?.summary) {
671
- console.log(`执行流: ${result.lane.summary}`);
672
- }
673
- if (result.activeChange) {
674
- const label = result.recommendation?.type === 'requirement-intake' ? '历史激活变更' : '激活变更';
675
- console.log(`${label}: ${result.activeChange}`);
676
- }
677
- if (result.focus?.changeId && result.focus.changeId !== result.activeChange) {
678
- console.log(`当前目标变更: ${result.focus.changeId}`);
679
- }
680
- if (result.activeRequirementGate) {
681
- console.log(`当前需求入口: ${result.activeRequirementGate.status ?? 'active'}`);
682
- }
683
- if (result.taskSummary) {
684
- console.log(`任务: ${result.taskSummary.completed}/${result.taskSummary.total} 完成,${result.taskSummary.pending} 待处理,${result.taskSummary.blocked} 阻塞`);
685
- if (result.taskSummary.implementation) {
686
- console.log(`实质实现任务: ${result.taskSummary.implementation.completed}/${result.taskSummary.implementation.total} 完成,${result.taskSummary.implementation.pending} 待处理`);
687
- }
688
- }
689
- if (result.discovery) {
690
- console.log(`持续发现: ${result.discovery.runId} 已覆盖 ${result.discovery.summary.covered}/${result.discovery.summary.total},待处理 ${result.discovery.summary.pending}`);
691
- }
692
- console.log(`下一步类型: ${result.recommendation.type}`);
693
- console.log(`下一步: ${result.recommendation.title}`);
694
- console.log(`原因: ${result.recommendation.reason}`);
695
- console.log(`建议只读命令: ${result.recommendation.command}`);
696
- if (result.recommendation.preparationCommand || result.recommendation.executionCommand || result.recommendation.commitCommand) {
697
- console.log('执行门槛: 仅当用户当前明确要求开发、实现、继续任务、深度调研、深度对标、复刻落地或提交时使用;规划、梳理、分析、审查类请求保持只读。');
698
- }
699
- if (result.recommendation.preparationCommand) {
700
- console.log(`准备命令: ${result.recommendation.preparationCommand}`);
701
- }
702
- if (result.recommendation.executionCommand) {
703
- console.log(`执行命令: ${result.recommendation.executionCommand}`);
704
- }
705
- if (result.recommendation.commitCommand) {
706
- console.log(`提交命令: ${result.recommendation.commitCommand}`);
707
- }
708
- if (result.recommendation.loop?.worktreeRecommended) {
709
- console.log('工作区建议: 使用独立 worktree 或等价隔离环境承接单任务 Loop。');
710
- }
711
- console.log(`验证命令: ${result.recommendation.verifyCommand}`);
712
- console.log(`状态文件: ${result.files.runState}`);
713
- }
714
-
715
- function printLoopResult(result, json) {
716
- if (json) {
717
- console.log(JSON.stringify(result, null, 2));
718
- return;
719
- }
720
-
721
- if (result.action === 'loop-prompt') {
722
- console.log(`OpenPrd loop 提示词: ${result.ok ? '就绪' : '阻塞'}`);
723
- if (result.task) {
724
- console.log(`任务: ${result.task.id} ${result.task.title}`);
725
- if (result.task.taskHandle) console.log(`任务句柄: ${result.task.taskHandle}`);
726
- }
727
- if (result.promptPath) {
728
- console.log(`提示词: ${result.promptPath}`);
729
- }
730
- if (result.invocation?.display) {
731
- console.log(`执行: ${result.invocation.display}`);
732
- }
733
- if (result.errors?.length) {
734
- for (const error of result.errors) console.log(`- ${error}`);
735
- }
736
- return;
737
- }
738
-
739
- if (result.action === 'loop-run') {
740
- console.log(`OpenPrd loop 运行: ${result.ok ? '通过' : '失败'}${result.dryRun ? ' (dry-run)' : ''}`);
741
- if (result.task) console.log(`任务: ${result.task.id} ${result.task.title}`);
742
- if (result.task?.taskHandle) console.log(`任务句柄: ${result.task.taskHandle}`);
743
- if (result.promptPath) console.log(`提示词: ${result.promptPath}`);
744
- if (result.invocation?.display) console.log(`执行: ${result.invocation.display}`);
745
- if (result.finish?.commit) {
746
- console.log(`提交: ${result.finish.commit.skipped ? '跳过' : result.finish.commit.sha}`);
747
- }
748
- if (result.finish?.testReport) {
749
- console.log(`测试报告: ${result.finish.testReport}`);
750
- }
751
- if (result.errors?.length) {
752
- for (const error of result.errors) console.log(`- ${error}`);
753
- }
754
- return;
755
- }
756
-
757
- if (result.action === 'loop-finish') {
758
- console.log(`OpenPrd loop finish: ${result.ok ? '通过' : '失败'}`);
759
- if (result.task) console.log(`任务: ${result.task.id} ${result.task.title}`);
760
- if (result.task?.taskHandle) console.log(`任务句柄: ${result.task.taskHandle}`);
761
- if (result.commit) console.log(`提交: ${result.commit.skipped ? '跳过' : result.commit.sha}`);
762
- if (result.testReport) console.log(`测试报告: ${result.testReport}`);
763
- if (result.learningReview) {
764
- if (result.learningReview.skipped) {
765
- console.log(`复盘学习包: 已跳过 (${result.learningReview.reason})`);
766
- } else if (result.learningReview.ok === false) {
767
- console.log(`复盘学习包: 生成失败 (${result.learningReview.errors?.[0] ?? 'unknown'})`);
768
- } else {
769
- console.log(`复盘学习包: ${result.learningReview.packageId}`);
770
- console.log(`HTML: ${result.learningReview.packagePaths?.readerHtml ?? '无'}`);
771
- console.log(`题材: ${result.learningReview.genre?.label ?? '未知'}`);
772
- if (result.learningReview.packageMeta?.styleLabel) console.log(`子风格: ${result.learningReview.packageMeta.styleLabel}`);
773
- if (result.learningReview.packageMeta?.authoringStatus) console.log(`写作状态: ${result.learningReview.packageMeta.authoringStatus}`);
774
- if (result.learningReview.packagePaths?.agentPrompt) console.log(`Agent 写作提示: ${result.learningReview.packagePaths.agentPrompt}`);
775
- console.log(`已打开: ${result.learningReview.opened ? '是' : '否'}`);
776
- }
777
- }
778
- printKnowledgeReview(result.knowledgeReview);
779
- if (result.next) {
780
- console.log(`下一任务: ${result.next.id} ${result.next.title}`);
781
- if (result.next.taskHandle) console.log(`下一任务句柄: ${result.next.taskHandle}`);
782
- }
783
- if (result.errors?.length) {
784
- for (const error of result.errors) console.log(`- ${error}`);
785
- }
786
- return;
787
- }
788
-
789
- console.log(`OpenPrd loop: ${result.action} ${result.ok ? '通过' : '失败'}`);
790
- if (result.changeId) console.log(`变更: ${result.changeId}`);
791
- if (result.summary) {
792
- console.log(`任务: ${result.summary.done}/${result.summary.total} 完成,${result.summary.pending} 待处理,${result.summary.failed} 失败,${result.summary.blocked} 阻塞`);
793
- }
794
- if (result.next) {
795
- console.log(`下一任务: ${result.next.id} ${result.next.title}`);
796
- if (result.next.taskHandle) console.log(`下一任务句柄: ${result.next.taskHandle}`);
797
- }
798
- if (result.files) {
799
- console.log(`任务清单: ${result.files.featureList}`);
800
- }
801
- if (result.errors?.length) {
802
- for (const error of result.errors) console.log(`- ${error}`);
803
- }
804
- }
805
-
806
- function printStandardsResult(result, json) {
807
- if (json) {
808
- console.log(JSON.stringify(result, null, 2));
809
- return;
810
- }
811
-
812
- if (result.action === 'init') {
813
- console.log(`已初始化 OpenPrd standards: ${result.docsRoot}`);
814
- for (const item of result.changed) {
815
- console.log(`- ${item.status}: ${item.path}`);
816
- }
817
- return;
818
- }
819
- if (result.action === 'classify-external-reference') {
820
- console.log(`已归类外部参考源码: ${result.path}`);
821
- console.log(`配置: ${result.configPath}`);
822
- console.log(`状态: ${result.alreadyPresent ? '已存在' : '已写入'}`);
823
- return;
824
- }
825
-
826
- console.log(`OpenPrd standards: ${result.ok ? '通过' : '失败'}`);
827
- console.log(`Docs root: ${result.docsRoot}`);
828
- for (const check of result.checks) {
829
- console.log(`- ${check}`);
830
- }
831
- if (result.errors.length > 0) {
832
- console.log('错误:');
833
- for (const error of result.errors) {
834
- console.log(`- ${error}`);
835
- }
836
- }
837
- if (result.warnings.length > 0) {
838
- console.log('警告:');
839
- for (const warning of result.warnings) {
840
- console.log(`- ${warning}`);
841
- }
842
- }
843
- const candidates = result.manualReport?.externalReferenceCandidates ?? [];
844
- if (candidates.length > 0) {
845
- console.log('外部参考源码候选:');
846
- console.log('请先询问用户这些目录是否只作为外部参考;用户确认后再运行归类命令。');
847
- for (const candidate of candidates) {
848
- console.log(`- ${candidate.path}: ${candidate.missingFiles} 个文件、${candidate.missingFolders} 个文件夹缺说明书;原因: ${candidate.reason};建议确认后运行 ${candidate.suggestedCommand}`);
849
- }
850
- }
851
- }
852
-
853
- function printDevelopmentStandardsResult(result, json) {
854
- if (json) {
855
- console.log(JSON.stringify(result, null, 2));
856
- return;
857
- }
858
-
859
- console.log(`OpenPrd dev-check: ${result.ok ? '完成' : '失败'}`);
860
- console.log(`阈值: ≤${result.thresholds.okMax} 行 ok,${result.thresholds.okMax + 1}-${result.thresholds.attentionMax} 行需注意,>${result.thresholds.warningAbove} 行警告。`);
861
- for (const file of result.files) {
862
- const lineText = file.lineCount === null || file.lineCount === undefined ? '未知行数' : `${file.lineCount} 行`;
863
- console.log(`- ${file.status}: ${file.path} (${lineText})`);
864
- console.log(` ${file.nextAction}`);
865
- }
866
- printKnowledgeReview(result.knowledgeReview);
867
- for (const error of result.errors ?? []) {
868
- console.log(`- ${error}`);
869
- }
870
- }
871
-
872
- function growthCandidateStatusLabel(status) {
873
- if (status === 'applied') return '已应用';
874
- if (status === 'rejected') return '已拒绝';
875
- return '待确认';
876
- }
877
-
878
- function growthCandidateApplyModeLabel(candidate) {
879
- if (candidate.applyMode === 'auto') return '自动补齐';
880
- if (candidate.applyMode === 'manual') return '手动采纳';
881
- return '未应用';
882
- }
883
-
884
- function growthCandidateScopeLabel(scope) {
885
- if (scope === 'user-local') return '当前用户本地偏好';
886
- if (scope === 'openprd-core') return 'OpenPrd 核心规则';
887
- return '项目共享规则';
888
- }
889
-
890
- function formatGrowthConfidence(confidence) {
891
- if (typeof confidence !== 'number' || Number.isNaN(confidence)) {
892
- return '未提供';
893
- }
894
- return `${Math.round(confidence * 100)}%`;
895
- }
896
-
897
- function describeGrowthCandidateImpact(candidate) {
898
- if (candidate.type === 'code-extension') {
899
- return `会把匹配 ${candidate.key} 的文件纳入代码文件识别,减少后续同类 dev-check 重复提醒。`;
900
- }
901
- if (candidate.type === 'exempt-path-segment') {
902
- return `会把路径片段 ${candidate.key} 加入代码行数规则豁免,影响对应目录下文件的 dev-check 判断。`;
903
- }
904
- if (candidate.type === 'exempt-file-pattern') {
905
- return `会把文件模式 ${candidate.key} 加入代码行数规则豁免,影响命中的文件。`;
906
- }
907
- if (candidate.type === 'user-preference') {
908
- return `会把偏好 ${candidate.key} 写入当前用户本地配置,不进入项目共享规则。`;
909
- }
910
- if (candidate.scope === 'openprd-core') {
911
- return '采纳后会进入 OpenPrd 核心规则,请确认是否值得作为跨项目默认行为。';
912
- }
913
- return `采纳后会写入${growthCandidateScopeLabel(candidate.scope)},请确认这是否是你想要固化的范围。`;
914
- }
915
-
916
- function formatGrowthEvidenceItem(item = {}) {
917
- if (typeof item === 'string') {
918
- return item;
919
- }
920
- const parts = [];
921
- if (item.path) {
922
- parts.push(String(item.path));
923
- }
924
- if (item.lineCount !== null && item.lineCount !== undefined) {
925
- parts.push(`${item.lineCount} 行`);
926
- }
927
- if (item.reason) {
928
- parts.push(`原因: ${item.reason}`);
929
- }
930
- if (item.note) {
931
- parts.push(`说明: ${item.note}`);
932
- }
933
- return parts.length > 0 ? parts.join(';') : JSON.stringify(item);
934
- }
935
-
936
- function formatGrowthSuggestedPatch(patch) {
937
- if (!patch) {
938
- return '未提供';
939
- }
940
- if (typeof patch === 'string') {
941
- return patch;
942
- }
943
- const file = patch.file ? String(patch.file) : 'unknown-file';
944
- const pathText = patch.path ? String(patch.path) : 'unknown-path';
945
- const op = patch.op ? String(patch.op) : 'update';
946
- const value = patch.value === undefined ? '' : ` ${JSON.stringify(patch.value)}`;
947
- return `${file} -> ${pathText} ${op}${value}`.trim();
948
- }
949
-
950
- function printGrowthResult(result, json) {
951
- if (json) {
952
- console.log(JSON.stringify(result, null, 2));
953
- return;
954
- }
955
-
956
- if (result.action === 'growth-init') {
957
- console.log('OpenPrd growth: 已初始化');
958
- console.log(`候选队列: ${result.files.candidates}`);
959
- return;
960
- }
961
-
962
- console.log(`OpenPrd growth: ${result.ok ? '完成' : '失败'}`);
963
- if (result.summary) {
964
- console.log(`候选: ${result.summary.pending} 待确认,${result.summary.applied} 已应用,${result.summary.rejected} 已拒绝。`);
965
- }
966
- const candidates = result.pending ?? (result.candidate ? [result.candidate] : []);
967
- for (const candidate of candidates) {
968
- console.log(`- ${candidate.id}: ${candidate.title}`);
969
- console.log(` 状态: ${growthCandidateStatusLabel(candidate.status)}`);
970
- console.log(` 作用范围: ${growthCandidateScopeLabel(candidate.scope)}`);
971
- if (candidate.status === 'applied') {
972
- console.log(` 应用方式: ${growthCandidateApplyModeLabel(candidate)}`);
973
- }
974
- console.log(` 置信度: ${formatGrowthConfidence(candidate.confidence)}`);
975
- if (candidate.summary) {
976
- console.log(` 摘要: ${candidate.summary}`);
977
- }
978
- console.log(` 采纳影响: ${describeGrowthCandidateImpact(candidate)}`);
979
- if ((candidate.evidence ?? []).length > 0) {
980
- console.log(' 证据:');
981
- for (const evidence of candidate.evidence) {
982
- console.log(` - ${formatGrowthEvidenceItem(evidence)}`);
983
- }
984
- }
985
- if (candidate.suggestedPatch) {
986
- console.log(' 拟写入:');
987
- console.log(` - ${formatGrowthSuggestedPatch(candidate.suggestedPatch)}`);
988
- }
989
- if (candidate.status === 'pending') {
990
- console.log(` 收工复盘采纳命令: openprd grow . --apply --id ${candidate.id}`);
991
- console.log(` 拒绝命令: openprd grow . --reject --id ${candidate.id}`);
992
- }
993
- }
994
- for (const change of result.changed ?? []) {
995
- console.log(`- 已更新: ${change}`);
996
- }
997
- const shouldSkipNextActions = candidates.some((candidate) => candidate.status === 'pending');
998
- for (const action of shouldSkipNextActions ? [] : (result.nextActions ?? [])) {
999
- console.log(`- 下一步: ${action}`);
1000
- }
1001
- for (const error of result.errors ?? []) {
1002
- console.log(`- ${error}`);
1003
- }
1004
- }
1005
-
1006
- function printQualityResult(result, json) {
1007
- if (json) {
1008
- console.log(JSON.stringify(result, null, 2));
1009
- return;
1010
- }
1011
-
1012
- if (result.action === 'quality-init') {
1013
- console.log(`OpenPrd quality: 已初始化 (${result.changed})`);
1014
- console.log(`配置: ${result.files.config}`);
1015
- console.log(`报告目录: ${result.files.reportsDir}`);
1016
- console.log(`知识库索引: ${result.files.knowledgeIndex}`);
1017
- return;
1018
- }
1019
-
1020
- if (result.action === 'quality-learn') {
1021
- console.log(`OpenPrd quality learn: ${result.ok ? '已沉淀' : '失败'}`);
1022
- if (result.ok) {
1023
- console.log(`来源类型: ${result.sourceKind}`);
1024
- console.log(`来源: ${result.sourcePath}`);
1025
- if (Array.isArray(result.sourcePaths) && result.sourcePaths.length > 1) {
1026
- console.log(`证据数: ${result.sourcePaths.length}`);
1027
- }
1028
- console.log(`事故: ${result.files.incident}`);
1029
- console.log(`模式: ${result.files.pattern}`);
1030
- console.log(`经验 Skill: ${result.files.skill}`);
1031
- return;
1032
- }
1033
- for (const error of result.errors ?? []) {
1034
- console.log(`- ${error}`);
1035
- }
1036
- return;
1037
- }
1038
-
1039
- if (result.action === 'quality-knowledge-review') {
1040
- console.log('OpenPrd quality review: 已完成');
1041
- printKnowledgeReview(result);
1042
- return;
1043
- }
1044
-
1045
- console.log(`OpenPrd quality: ${result.ok ? '完成' : '失败'}`);
1046
- if (result.report) {
1047
- console.log(`质量状态: ${result.report.summary.status}`);
1048
- console.log(`生产就绪: ${result.report.readiness.productionReady ? '是' : '否'}`);
1049
- console.log(`执行模式: ${result.report.readiness.enforcement}`);
1050
- if (result.report.qualityPolicy) {
1051
- console.log(`场景标签: ${result.report.qualityPolicy.scenarioTags.join(', ')}`);
1052
- console.log(`必需门禁: ${result.report.qualityPolicy.requiredGates.join(', ') || '无'}`);
1053
- }
1054
- if (result.report.readiness.attentionGates.length > 0) {
1055
- console.log(`需关注门禁: ${result.report.readiness.attentionGates.join(', ')}`);
1056
- }
1057
- console.log('门禁:');
1058
- for (const gate of result.report.gates) {
1059
- const scope = gate.required ? '必需' : '可选';
1060
- const evidence = gate.evidence?.present ? `证据 ${gate.evidence.sources.length}` : '缺证据';
1061
- console.log(`- ${gate.status}: ${gate.label} (${scope}, ${evidence})`);
1062
- }
1063
- }
1064
- if (result.reportPath) {
1065
- console.log(`JSON: ${result.reportPath}`);
1066
- }
1067
- if (result.htmlPath) {
1068
- console.log(`HTML: ${result.htmlPath}`);
1069
- }
1070
- printKnowledgeReview(result.knowledgeReview);
1071
- for (const error of result.errors ?? []) {
1072
- console.log(`- ${error}`);
1073
- }
1074
- }
1075
-
1076
- function printVisualCompareResult(result, json) {
1077
- if (json) {
1078
- console.log(JSON.stringify(result, null, 2));
1079
- return;
1080
- }
1081
-
1082
- console.log('OpenPrd visual compare: 已生成');
1083
- console.log(`输出图片: ${result.outputPath}`);
1084
- console.log(`格式: ${result.format}${result.quality ? `, quality=${result.quality}` : ''}`);
1085
- console.log(`画布: ${result.canvas.width}x${result.canvas.height}`);
1086
- console.log(`左侧: ${result.labels.reference} (${result.reference.rendered.width}x${result.reference.rendered.height})`);
1087
- console.log(`右侧: ${result.labels.actual} (${result.actual.rendered.width}x${result.actual.rendered.height})`);
1088
- for (const action of result.nextActions ?? []) {
1089
- console.log(`- 下一步: ${action}`);
1090
- }
1091
- }
1092
-
1093
- function printFreezeResult(result, json) {
1094
- if (json) {
1095
- console.log(JSON.stringify(result, null, 2));
1096
- return;
1097
- }
1098
-
1099
- console.log(`已 freeze OpenPrd 工作区: ${result.ws.workspaceRoot}`);
1100
- console.log(`版本: ${result.snapshot.latestVersionId}`);
1101
- console.log(`Digest: ${result.snapshot.digest}`);
1102
- console.log(`状态文件: ${result.ws.paths.freezeState}`);
1103
- }
1104
-
1105
- function printDiagramResult(result, json) {
1106
- if (json) {
1107
- console.log(JSON.stringify(result, null, 2));
1108
- return;
1109
- }
1110
-
1111
- if (result.snapshot) {
1112
- console.log(`已为 ${result.snapshot.title} 生成${result.type === 'product-flow' ? '产品流程' : '架构'}图`);
1113
- } else {
1114
- console.log(`已更新${result.type === 'product-flow' ? '产品流程' : '架构'}图`);
1115
- }
1116
- console.log(`HTML: ${result.htmlPath}`);
1117
- console.log(`JSON: ${result.jsonPath}`);
1118
- console.log(`Mermaid: ${result.mermaidPath}`);
1119
- if (result.inputPath) {
1120
- console.log(`输入 contract: ${result.inputPath}`);
1121
- }
1122
- if (result.marked) {
1123
- console.log(`评审状态: ${result.marked}`);
1124
- } else if (result.model?.metadata?.reviewStatus) {
1125
- console.log(`评审状态: ${result.model.metadata.reviewStatus}`);
1126
- }
1127
- console.log(`已打开: ${result.opened ? '是' : '否'}`);
1128
- }
1129
-
1130
- function printHandoffResult(result, json) {
1131
- if (json) {
1132
- console.log(JSON.stringify(result, null, 2));
1133
- return;
1134
- }
1135
-
1136
- console.log(`交接包已写入: ${result.exportDir}`);
1137
- console.log(`目标: ${result.handoff.target}`);
1138
- console.log(`版本: ${result.handoff.versionId}`);
1139
- console.log(`Digest: ${result.handoff.digest}`);
1140
- }
1141
-
1142
- function printOpenSpecDiscoveryResult(result, json) {
1143
- if (json) {
1144
- console.log(JSON.stringify(result, null, 2));
1145
- return;
1146
- }
1147
-
1148
- console.log(`OpenPrd discovery 运行: ${result.runId}`);
1149
- if (result.advanced) {
1150
- console.log(`已推进条目: ${result.advancedItem.id}`);
1151
- console.log(`条目状态: ${result.advancedItem.status}`);
1152
- if (result.claim) {
1153
- console.log(`Claim: ${result.claim.id}`);
1154
- }
1155
- }
1156
- if (result.verified) {
1157
- console.log(`验证: ${result.verification.valid ? '通过' : '失败'}`);
1158
- console.log(`完成: ${result.verification.complete ? '是' : '否'}`);
1159
- for (const check of result.verification.checks) {
1160
- console.log(`- ${check}`);
1161
- }
1162
- if (result.verification.errors.length > 0) {
1163
- console.log('错误:');
1164
- for (const error of result.verification.errors) {
1165
- console.log(`- ${error}`);
1166
- }
1167
- }
1168
- if (result.verification.warnings.length > 0) {
1169
- console.log('警告:');
1170
- for (const warning of result.verification.warnings) {
1171
- console.log(`- ${warning}`);
1172
- }
1173
- }
1174
- }
1175
- console.log(`是否恢复: ${result.resumed ? '是' : '否'}`);
1176
- console.log(`运行目录: ${result.runDir}`);
1177
- console.log(`模式: ${result.control.mode}`);
1178
- console.log(`状态: ${result.control.status}`);
1179
- console.log(`已索引来源文件: ${result.inventory.summary.files}`);
1180
- console.log(`覆盖待处理: ${result.coverageMatrix.summary.pending}/${result.coverageMatrix.summary.total}`);
1181
- console.log(`下一步动作: ${result.control.nextAction}`);
1182
- }
1183
-
1184
- function printOpenSpecChangeValidationResult(result, json) {
1185
- if (json) {
1186
- console.log(JSON.stringify(result, null, 2));
1187
- return;
1188
- }
1189
-
1190
- console.log(`OpenPrd change 验证: ${result.valid ? '通过' : '失败'}`);
1191
- console.log(`Change: ${result.changeId}`);
1192
- for (const check of result.checks) {
1193
- console.log(`- ${check}`);
1194
- }
1195
- if (result.errors.length > 0) {
1196
- console.log('错误:');
1197
- for (const error of result.errors) {
1198
- console.log(`- ${error}`);
1199
- }
1200
- }
1201
- if (result.warnings.length > 0) {
1202
- console.log('警告:');
1203
- for (const warning of result.warnings) {
1204
- console.log(`- ${warning}`);
1205
- }
1206
- }
1207
- }
1208
-
1209
- function printOpenSpecGenerateResult(result, json) {
1210
- if (json) {
1211
- console.log(JSON.stringify(result, null, 2));
1212
- return;
1213
- }
1214
-
1215
- console.log(`已生成 OpenPrd change: ${result.changeId}`);
1216
- console.log(`Capability: ${result.capability}`);
1217
- console.log(`任务数: ${result.taskCount}`);
1218
- console.log(`验证: ${result.validation.valid ? '通过' : '失败'}`);
1219
- console.log('文件:');
1220
- for (const file of result.files) {
1221
- console.log(`- ${file}`);
1222
- }
1223
- if (result.validation.errors.length > 0) {
1224
- console.log('错误:');
1225
- for (const error of result.validation.errors) {
1226
- console.log(`- ${error}`);
1227
- }
1228
- }
1229
- }
1230
-
1231
- function printOpenSpecTaskResult(result, json) {
1232
- if (json) {
1233
- console.log(JSON.stringify(result, null, 2));
1234
- return;
1235
- }
1236
-
1237
- console.log(`OpenPrd 任务: ${result.changeId}`);
1238
- if (result.action === 'list') {
1239
- console.log(`进度: ${result.summary.completed}/${result.summary.total} 已完成,${result.summary.pending} 待处理,${result.summary.blocked} 阻塞`);
1240
- if (result.summary.implementation) {
1241
- console.log(`实质实现任务: ${result.summary.implementation.completed}/${result.summary.implementation.total} 已完成,${result.summary.implementation.pending} 待处理`);
1242
- }
1243
- if (result.nextTask) {
1244
- console.log(`下一任务: ${result.nextTask.id} ${result.nextTask.title}`);
1245
- console.log(`验证命令: ${result.nextTask.metadata.verify}`);
1246
- } else {
1247
- console.log('下一任务: 无');
1248
- }
1249
- if (result.blockedTasks.length > 0) {
1250
- console.log('阻塞任务:');
1251
- for (const task of result.blockedTasks.slice(0, 10)) {
1252
- console.log(`- ${task.id}: ${[...task.missing, ...task.incomplete].join(', ')}`);
1253
- }
1254
- }
1255
- return;
1256
- }
1257
-
1258
- console.log(`任务: ${result.task.id} ${result.task.title}`);
1259
- if (result.verification) {
1260
- console.log(`验证: ${result.verification.ok ? '通过' : '失败'} (${result.verification.command})`);
1261
- if (!result.verification.ok && result.verification.stderr) {
1262
- console.log(result.verification.stderr.trim());
1263
- }
1264
- }
1265
- if (result.action === 'advance') {
1266
- console.log(`已推进: ${result.advanced ? '是' : '否'}`);
1267
- if (result.summary) {
1268
- console.log(`进度: ${result.summary.completed}/${result.summary.total} 已完成`);
1269
- }
1270
- if (result.nextTask) {
1271
- console.log(`下一任务: ${result.nextTask.id} ${result.nextTask.title}`);
1272
- }
1273
- }
1274
- }
1275
-
1276
- function printOpenPrdChangesResult(result, json) {
1277
- if (json) {
1278
- console.log(JSON.stringify(result, null, 2));
1279
- return;
1280
- }
1281
-
1282
- console.log(`OpenPrd changes: ${result.changes.length}`);
1283
- console.log(`当前激活 change: ${result.activeChange ?? '无'}`);
1284
- for (const change of result.changes) {
1285
- const marker = change.active ? '*' : '-';
1286
- console.log(`${marker} ${change.id} | ${change.status} | ${change.source} | 任务 ${change.taskTotal - change.taskIncomplete}/${change.taskTotal}`);
1287
- }
1288
- }
1289
-
1290
- function printOpenPrdChangeActionResult(result, json) {
1291
- if (json) {
1292
- console.log(JSON.stringify(result, null, 2));
1293
- return;
1294
- }
1295
-
1296
- console.log(`OpenPrd change ${result.action}: ${result.changeId}`);
1297
- if (result.action === 'apply') {
1298
- console.log(`已应用: ${result.ok ? '是' : '否'}`);
1299
- if (result.appliedSpecs?.length > 0) {
1300
- console.log('已接受 specs:');
1301
- for (const spec of result.appliedSpecs) {
1302
- console.log(`- ${spec.capability}: ${spec.specPath}`);
1303
- }
1304
- }
1305
- if (result.errors?.length > 0) {
1306
- console.log('错误:');
1307
- for (const error of result.errors) {
1308
- console.log(`- ${error}`);
1309
- }
1310
- }
1311
- }
1312
- if (result.action === 'archive') {
1313
- console.log(`归档目录: ${result.archiveDir}`);
1314
- console.log(`已移除来源: ${result.removedSource ? '是' : '否'}`);
1315
- }
1316
- if (result.action === 'activate') {
1317
- console.log(`当前激活 change: ${result.changeId}`);
1318
- }
1319
- }
1320
-
1321
- function printAcceptedSpecsResult(result, json) {
1322
- if (json) {
1323
- console.log(JSON.stringify(result, null, 2));
1324
- return;
1325
- }
1326
-
1327
- console.log(`已接受 specs: ${result.specs.length}`);
1328
- for (const spec of result.specs) {
1329
- const source = spec.metadata?.sourceChange ? ` 来自 ${spec.metadata.sourceChange}` : '';
1330
- console.log(`- ${spec.capability}${source}: ${spec.specPath}`);
1331
- }
1332
- console.log(`已应用 changes: ${result.appliedChanges.length}`);
1333
- }
1334
-
1335
- function printBenchmarkResult(result, json) {
1336
- if (json) {
1337
- console.log(JSON.stringify(result, null, 2));
1338
- return;
1339
- }
1340
-
1341
- if (result.action === 'benchmark-add') {
1342
- console.log(`OpenPrd benchmark add: ${result.ok ? '已加入 candidate' : '失败'}`);
1343
- if (result.source) {
1344
- console.log(`ID: ${result.source.id}`);
1345
- console.log(`标题: ${result.source.title}`);
1346
- console.log(`来源: ${result.source.url ?? result.source.path ?? 'unknown'}`);
1347
- console.log(`场景: ${result.source.scenarios.join(', ') || '未分类'}`);
1348
- }
1349
- if (result.error) {
1350
- console.log(`错误: ${result.error}`);
1351
- }
1352
- return;
1353
- }
1354
-
1355
- if (result.action === 'benchmark-approve') {
1356
- console.log('OpenPrd benchmark approve: 已加入 approved registry');
1357
- console.log(`ID: ${result.source.id}`);
1358
- console.log(`标题: ${result.source.title}`);
1359
- console.log(`已批准来源: ${result.counts.approved}`);
1360
- console.log(`待确认来源: ${result.counts.candidates}`);
1361
- return;
1362
- }
1363
-
1364
- if (result.action === 'benchmark-verify') {
1365
- console.log(`OpenPrd benchmark verify: ${result.ok ? '通过' : '失败'}`);
1366
- for (const check of result.checks) {
1367
- console.log(`- ${check.ok ? '通过' : '失败'}: ${check.id}`);
1368
- for (const issue of check.issues) {
1369
- console.log(` ${issue.level === 'error' ? '错误' : '警告'}: ${issue.message}`);
1370
- }
1371
- }
1372
- return;
1373
- }
1374
-
1375
- console.log(`OpenPrd benchmark list: approved ${result.counts.approved}, candidate ${result.counts.candidates}`);
1376
- for (const source of result.approved) {
1377
- console.log(`- approved ${source.id}: ${source.title}`);
1378
- }
1379
- for (const source of result.candidates) {
1380
- console.log(`- candidate ${source.id}: ${source.title}`);
1381
- }
1382
- }
1383
-
1
+ /*
2
+ * 核心功能
3
+ * 汇总 OpenPrd CLI 各子模块的终端输出函数,并保持对外 named exports 稳定。
4
+ *
5
+ * 输入
6
+ * 接收各 CLI 子模块导出的打印函数集合。
7
+ *
8
+ * 输出
9
+ * 作为统一 barrel 对外导出基础、工作流、诊断、运行、质量、growth、change 与 benchmark 输出函数。
10
+ *
11
+ * 定位
12
+ * 位于 CLI 表现层的汇总入口,不再承载具体格式化逻辑。
13
+ *
14
+ * 依赖
15
+ * 依赖同目录下的分域 print 模块。
16
+ *
17
+ * 维护规则
18
+ * 新增打印函数时优先放入对应子模块,再由这里补充导出,避免 barrel 重新膨胀。
19
+ */
20
+ import {
21
+ printCaptureResult,
22
+ printClarifyResult,
23
+ printClassifyResult,
24
+ printInitResult,
25
+ printInterviewResult,
26
+ printLearningResult,
27
+ printPlaygroundResult,
28
+ printReleaseResult,
29
+ printStatus,
30
+ printValidation,
31
+ } from './basic-print.js';
32
+ import { printBenchmarkResult } from './benchmark-print.js';
33
+ import {
34
+ printAcceptedSpecsResult,
35
+ printOpenPrdChangeActionResult,
36
+ printOpenPrdChangesResult,
37
+ printOpenSpecChangeValidationResult,
38
+ printOpenSpecDiscoveryResult,
39
+ printOpenSpecGenerateResult,
40
+ printOpenSpecTaskResult,
41
+ } from './change-print.js';
42
+ import {
43
+ printAgentIntegrationResult,
44
+ printDoctorResult,
45
+ printFleetResult,
46
+ printSelfUpdateResult,
47
+ printUpgradeResult,
48
+ } from './doctor-print.js';
49
+ import { printGrowthResult } from './growth-print.js';
50
+ import {
51
+ printDevelopmentStandardsResult,
52
+ printKnowledgeResult,
53
+ printQualityResult,
54
+ printStandardsResult,
55
+ printVisualCompareResult,
56
+ } from './quality-print.js';
57
+ import {
58
+ printLoopResult,
59
+ printRunResult,
60
+ } from './run-print.js';
61
+ import {
62
+ printDiagramResult,
63
+ printDiffResult,
64
+ printFreezeResult,
65
+ printHandoffResult,
66
+ printHistoryResult,
67
+ printNextResult,
68
+ printReviewResult,
69
+ printSynthesizeResult,
70
+ } from './workflow-print.js';
1384
71
 
1385
72
  export {
1386
73
  printValidation,
@@ -1391,6 +78,7 @@ export {
1391
78
  printInterviewResult,
1392
79
  printPlaygroundResult,
1393
80
  printLearningResult,
81
+ printReleaseResult,
1394
82
  printSynthesizeResult,
1395
83
  printReviewResult,
1396
84
  printHistoryResult,
@@ -1408,6 +96,7 @@ export {
1408
96
  printDevelopmentStandardsResult,
1409
97
  printGrowthResult,
1410
98
  printQualityResult,
99
+ printKnowledgeResult,
1411
100
  printVisualCompareResult,
1412
101
  printFreezeResult,
1413
102
  printDiagramResult,
@@ -1419,5 +108,5 @@ export {
1419
108
  printOpenPrdChangesResult,
1420
109
  printOpenPrdChangeActionResult,
1421
110
  printAcceptedSpecsResult,
1422
- printBenchmarkResult
111
+ printBenchmarkResult,
1423
112
  };