specdo 1.0.2

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 (161) hide show
  1. package/CHANGELOG.md +139 -0
  2. package/README.md +308 -0
  3. package/README.zh-CN.md +306 -0
  4. package/bin/specdo.js +3 -0
  5. package/dist/cli/index.d.ts +15 -0
  6. package/dist/cli/index.d.ts.map +1 -0
  7. package/dist/cli/index.js +297 -0
  8. package/dist/cli/index.js.map +1 -0
  9. package/dist/commands/_shared.d.ts +45 -0
  10. package/dist/commands/_shared.d.ts.map +1 -0
  11. package/dist/commands/_shared.js +124 -0
  12. package/dist/commands/_shared.js.map +1 -0
  13. package/dist/commands/apply.d.ts +30 -0
  14. package/dist/commands/apply.d.ts.map +1 -0
  15. package/dist/commands/apply.js +393 -0
  16. package/dist/commands/apply.js.map +1 -0
  17. package/dist/commands/archive.d.ts +25 -0
  18. package/dist/commands/archive.d.ts.map +1 -0
  19. package/dist/commands/archive.js +362 -0
  20. package/dist/commands/archive.js.map +1 -0
  21. package/dist/commands/doctor.d.ts +21 -0
  22. package/dist/commands/doctor.d.ts.map +1 -0
  23. package/dist/commands/doctor.js +180 -0
  24. package/dist/commands/doctor.js.map +1 -0
  25. package/dist/commands/domains.d.ts +14 -0
  26. package/dist/commands/domains.d.ts.map +1 -0
  27. package/dist/commands/domains.js +107 -0
  28. package/dist/commands/domains.js.map +1 -0
  29. package/dist/commands/explore.d.ts +48 -0
  30. package/dist/commands/explore.d.ts.map +1 -0
  31. package/dist/commands/explore.js +378 -0
  32. package/dist/commands/explore.js.map +1 -0
  33. package/dist/commands/init.d.ts +45 -0
  34. package/dist/commands/init.d.ts.map +1 -0
  35. package/dist/commands/init.js +243 -0
  36. package/dist/commands/init.js.map +1 -0
  37. package/dist/commands/list.d.ts +23 -0
  38. package/dist/commands/list.d.ts.map +1 -0
  39. package/dist/commands/list.js +135 -0
  40. package/dist/commands/list.js.map +1 -0
  41. package/dist/commands/propose.d.ts +22 -0
  42. package/dist/commands/propose.d.ts.map +1 -0
  43. package/dist/commands/propose.js +316 -0
  44. package/dist/commands/propose.js.map +1 -0
  45. package/dist/commands/show.d.ts +15 -0
  46. package/dist/commands/show.d.ts.map +1 -0
  47. package/dist/commands/show.js +214 -0
  48. package/dist/commands/show.js.map +1 -0
  49. package/dist/commands/status.d.ts +17 -0
  50. package/dist/commands/status.d.ts.map +1 -0
  51. package/dist/commands/status.js +146 -0
  52. package/dist/commands/status.js.map +1 -0
  53. package/dist/commands/sync.d.ts +21 -0
  54. package/dist/commands/sync.d.ts.map +1 -0
  55. package/dist/commands/sync.js +113 -0
  56. package/dist/commands/sync.js.map +1 -0
  57. package/dist/commands/validate.d.ts +117 -0
  58. package/dist/commands/validate.d.ts.map +1 -0
  59. package/dist/commands/validate.js +446 -0
  60. package/dist/commands/validate.js.map +1 -0
  61. package/dist/core/apply-brief-renderer.d.ts +35 -0
  62. package/dist/core/apply-brief-renderer.d.ts.map +1 -0
  63. package/dist/core/apply-brief-renderer.js +242 -0
  64. package/dist/core/apply-brief-renderer.js.map +1 -0
  65. package/dist/core/config-store.d.ts +190 -0
  66. package/dist/core/config-store.d.ts.map +1 -0
  67. package/dist/core/config-store.js +280 -0
  68. package/dist/core/config-store.js.map +1 -0
  69. package/dist/core/context-store.d.ts +96 -0
  70. package/dist/core/context-store.d.ts.map +1 -0
  71. package/dist/core/context-store.js +426 -0
  72. package/dist/core/context-store.js.map +1 -0
  73. package/dist/core/json-schemas.d.ts +349 -0
  74. package/dist/core/json-schemas.d.ts.map +1 -0
  75. package/dist/core/json-schemas.js +125 -0
  76. package/dist/core/json-schemas.js.map +1 -0
  77. package/dist/core/skill-content/cross-domain.d.ts +12 -0
  78. package/dist/core/skill-content/cross-domain.d.ts.map +1 -0
  79. package/dist/core/skill-content/cross-domain.js +291 -0
  80. package/dist/core/skill-content/cross-domain.js.map +1 -0
  81. package/dist/core/skill-content/protocol-examples.d.ts +13 -0
  82. package/dist/core/skill-content/protocol-examples.d.ts.map +1 -0
  83. package/dist/core/skill-content/protocol-examples.js +190 -0
  84. package/dist/core/skill-content/protocol-examples.js.map +1 -0
  85. package/dist/core/skill-content/workflow-content.d.ts +25 -0
  86. package/dist/core/skill-content/workflow-content.d.ts.map +1 -0
  87. package/dist/core/skill-content/workflow-content.js +1572 -0
  88. package/dist/core/skill-content/workflow-content.js.map +1 -0
  89. package/dist/core/skill-exporter.d.ts +186 -0
  90. package/dist/core/skill-exporter.d.ts.map +1 -0
  91. package/dist/core/skill-exporter.js +922 -0
  92. package/dist/core/skill-exporter.js.map +1 -0
  93. package/dist/core/spec-sync.d.ts +65 -0
  94. package/dist/core/spec-sync.d.ts.map +1 -0
  95. package/dist/core/spec-sync.js +226 -0
  96. package/dist/core/spec-sync.js.map +1 -0
  97. package/dist/core/task-parser.d.ts +58 -0
  98. package/dist/core/task-parser.d.ts.map +1 -0
  99. package/dist/core/task-parser.js +244 -0
  100. package/dist/core/task-parser.js.map +1 -0
  101. package/dist/core/template-renderer.d.ts +51 -0
  102. package/dist/core/template-renderer.d.ts.map +1 -0
  103. package/dist/core/template-renderer.js +362 -0
  104. package/dist/core/template-renderer.js.map +1 -0
  105. package/dist/domains/architecture.d.ts +34 -0
  106. package/dist/domains/architecture.d.ts.map +1 -0
  107. package/dist/domains/architecture.js +341 -0
  108. package/dist/domains/architecture.js.map +1 -0
  109. package/dist/domains/backend.d.ts +35 -0
  110. package/dist/domains/backend.d.ts.map +1 -0
  111. package/dist/domains/backend.js +367 -0
  112. package/dist/domains/backend.js.map +1 -0
  113. package/dist/domains/frontend.d.ts +36 -0
  114. package/dist/domains/frontend.d.ts.map +1 -0
  115. package/dist/domains/frontend.js +373 -0
  116. package/dist/domains/frontend.js.map +1 -0
  117. package/dist/domains/index.d.ts +49 -0
  118. package/dist/domains/index.d.ts.map +1 -0
  119. package/dist/domains/index.js +255 -0
  120. package/dist/domains/index.js.map +1 -0
  121. package/dist/domains/operations.d.ts +37 -0
  122. package/dist/domains/operations.d.ts.map +1 -0
  123. package/dist/domains/operations.js +344 -0
  124. package/dist/domains/operations.js.map +1 -0
  125. package/dist/domains/pool-ranking.d.ts +43 -0
  126. package/dist/domains/pool-ranking.d.ts.map +1 -0
  127. package/dist/domains/pool-ranking.js +153 -0
  128. package/dist/domains/pool-ranking.js.map +1 -0
  129. package/dist/domains/quality.d.ts +45 -0
  130. package/dist/domains/quality.d.ts.map +1 -0
  131. package/dist/domains/quality.js +368 -0
  132. package/dist/domains/quality.js.map +1 -0
  133. package/dist/domains/security.d.ts +19 -0
  134. package/dist/domains/security.d.ts.map +1 -0
  135. package/dist/domains/security.js +364 -0
  136. package/dist/domains/security.js.map +1 -0
  137. package/dist/domains/signal-match.d.ts +25 -0
  138. package/dist/domains/signal-match.d.ts.map +1 -0
  139. package/dist/domains/signal-match.js +67 -0
  140. package/dist/domains/signal-match.js.map +1 -0
  141. package/dist/domains/types.d.ts +354 -0
  142. package/dist/domains/types.d.ts.map +1 -0
  143. package/dist/domains/types.js +12 -0
  144. package/dist/domains/types.js.map +1 -0
  145. package/dist/index.d.ts +9 -0
  146. package/dist/index.d.ts.map +1 -0
  147. package/dist/index.js +9 -0
  148. package/dist/index.js.map +1 -0
  149. package/dist/protocols/index.d.ts +36 -0
  150. package/dist/protocols/index.d.ts.map +1 -0
  151. package/dist/protocols/index.js +85 -0
  152. package/dist/protocols/index.js.map +1 -0
  153. package/dist/protocols/review-to-solid.d.ts +32 -0
  154. package/dist/protocols/review-to-solid.d.ts.map +1 -0
  155. package/dist/protocols/review-to-solid.js +309 -0
  156. package/dist/protocols/review-to-solid.js.map +1 -0
  157. package/dist/utils/prompt.d.ts +37 -0
  158. package/dist/utils/prompt.d.ts.map +1 -0
  159. package/dist/utils/prompt.js +81 -0
  160. package/dist/utils/prompt.js.map +1 -0
  161. package/package.json +80 -0
@@ -0,0 +1,309 @@
1
+ /**
2
+ * Review-To-Solid Protocol
3
+ *
4
+ * 来源: content/skills/review-to-solid/SKILL.md (463 行)
5
+ *
6
+ * 该协议是方法论型工作流,包含 DomainModule 无法表达的元素:
7
+ * 1. 7 步闭环工作流 + 步骤 4-5-6 循环回退(修复 → 再审 → 继续修复)
8
+ * 2. P1/P2/P3 严重度分级
9
+ * 3. 4 段强制输出契约(Final Verdict / Findings / Fix Summary / Delta Table)
10
+ * 4. 6 类工件分派(product / architecture / readme / pr / prompt-agent-skill / openspec)
11
+ * 5. 停止条件与禁止行为
12
+ *
13
+ * 设计决策(来自 Phase 1b POC):
14
+ * review-to-solid 不内嵌进 qualityDomain;保留为独立 Protocol,由 Phase 2 `apply` 命令
15
+ * 按需注入到 apply-brief.md 的 "Execution Discipline" 段。
16
+ *
17
+ * POC 决策证据表:
18
+ * | 证据 | DomainModule 是否可表达 | Protocol 保留方式 | Phase 1b 结论 |
19
+ * |------|-------------------------|-------------------|---------------|
20
+ * | 三层审查: 单工件 / 跨工件 / 生产级充分性 | 否。DomainModule 只有 stage 列表,不能表达审查顺序和层级覆盖要求 | workflow.step 3 actions | 独立 Protocol 保留执行顺序 |
21
+ * | P1/P2/P3 严重度影响是否继续修复 | 否。领域 checklist 不能驱动停止条件 | severityLevels + stopConditions | 独立 Protocol 可表达收敛门槛 |
22
+ * | 修复循环 review → fix → re-review → iterate | 否。DomainModule 无 loopBackTo 语义 | workflow.step 6 loopBackTo: [4, 5] | 独立 Protocol 保留闭环 |
23
+ * | Delta Table 是最终输出契约,不是领域知识 | 否。压进 DomainModule 会变成普通 checklist,无法保证输出段和列 | outputContract.Initial-vs-Final Delta Table | 独立 Protocol 满足 Phase 1b POC |
24
+ *
25
+ * 与 quality 域的关系:
26
+ * quality 域提供"代码评审 / 调试 / 测试 / 性能 / 验证"的 checklist 知识;
27
+ * review-to-solid 提供"如何把工件硬化到生产级"的执行纪律。
28
+ * 两者是知识 vs 流程,互不替代。
29
+ */
30
+ export const reviewToSolidProtocol = {
31
+ name: 'review-to-solid',
32
+ description: 'Closed-loop hardening protocol: review → fix → re-review → converge → produce initial-vs-final delta table for production-grade artifacts.',
33
+ goal: 'Move an important artifact from "looks finished" to a state where the objective is clear, scope is explicit, ' +
34
+ 'constraints are complete, risks are visible, execution is realistic, verification is concrete, and the artifact ' +
35
+ 'can support production-grade delivery — or clearly explains why it cannot. The default target is production-grade ' +
36
+ 'delivery, not a minimal implementation, demo, or happy-path-only proposal.',
37
+ triggerPhrases: [
38
+ 'use review-to-solid to converge this plan',
39
+ 'run review-to-solid on this artifact',
40
+ 'review, fix, and re-review this until there are no risks',
41
+ 'converge this document set and give me a comparison table',
42
+ 'review, fix, re-review, and continue until there are no high-risk issues',
43
+ 'harden this plan to production grade',
44
+ 'review until there are no obvious p1/p2 risks',
45
+ 'do not just suggest improvements; fix it',
46
+ 'end with a table that shows what changed',
47
+ ],
48
+ suppressionPhrases: [
49
+ 'polish wording',
50
+ 'copy-edit',
51
+ 'copy edit',
52
+ 'review-only',
53
+ 'review only',
54
+ 'quick take a look',
55
+ 'take a quick look',
56
+ 'light review',
57
+ 'single-line typo',
58
+ 'formatting fix',
59
+ ],
60
+ doNotUseWhen: [
61
+ 'User asks for a quick "take a look" or light review — use code-reviewer or documentation-writer instead',
62
+ 'User asks to "polish wording" — that is a copy-edit task, not a hardening task',
63
+ 'User explicitly asks for review-only without fixes — honor that scope',
64
+ 'Task is a single-line typo / formatting fix — closed-loop overhead is not justified',
65
+ 'Multi-file work without a hardening or convergence intent — being large does not by itself trigger this protocol',
66
+ ],
67
+ workflow: [
68
+ {
69
+ step: 1,
70
+ title: 'Establish the Working Boundary',
71
+ goal: 'Identify the target artifact, its type, current location, and the delivery standard the user expects ' +
72
+ 'before doing anything else. Wrong-target review wastes the entire loop.',
73
+ actions: [
74
+ 'Identify what the target artifact is and where the current version lives',
75
+ 'Classify artifact type: product-plan / architecture / readme / pr / prompt-agent-skill / openspec / generic-doc',
76
+ 'Determine the delivery standard expected by the user (production-grade by default unless explicitly downgraded)',
77
+ 'Note whether the task involves code, docs, config, release, product, or business decisions',
78
+ 'Surface critical ambiguities that must be clarified before review can be useful',
79
+ ],
80
+ exitCriteria: [
81
+ 'Target artifact path / identity is unambiguous',
82
+ 'Artifact type is classified for downstream check selection',
83
+ 'Delivery standard is recorded (production / prototype / demo)',
84
+ ],
85
+ },
86
+ {
87
+ step: 2,
88
+ title: 'Preserve the Initial Baseline',
89
+ goal: 'Snapshot the initial state before any edits so that the final delta table can faithfully describe ' +
90
+ 'what changed. Without a baseline, the closing comparison is unverifiable.',
91
+ actions: [
92
+ 'Read the current files in scope and capture their state',
93
+ 'Check current git diff and uncommitted changes',
94
+ 'Record first-pass observations as a baseline note (do not edit yet)',
95
+ 'Copy a concise baseline summary into working notes for use in the final delta table',
96
+ ],
97
+ exitCriteria: [
98
+ 'Baseline summary is recorded and survives subsequent fixes',
99
+ 'Initial issues are listed before any edit is applied',
100
+ ],
101
+ },
102
+ {
103
+ step: 3,
104
+ title: 'First Review — Three Layers',
105
+ goal: 'Review must come before any edit. Cover three orthogonal layers so that single-artifact polish does not ' +
106
+ 'mask cross-artifact contradictions or production-grade gaps.',
107
+ actions: [
108
+ 'Layer 1 — Single-artifact quality: objective clarity, scope/non-goals, constraints, risks/edge cases, verification',
109
+ 'Layer 2 — Cross-artifact consistency: aligned goals, propagated decisions, tasks/verification follow design, no terminology drift',
110
+ 'Layer 3 — Production-grade sufficiency: not just "possible to build" but safe to run and maintain; performance, capacity, scalability, observability, security, ops detail',
111
+ 'Order findings by severity (P1 / P2 / P3); say "No findings" explicitly if applicable',
112
+ 'Do not disguise vague suggestions as P1/P2 — severity reflects probability and blast radius',
113
+ ],
114
+ exitCriteria: [
115
+ 'Findings list exists with explicit severity per item',
116
+ 'Each finding cites a concrete location (file / section / claim) — not vague impression',
117
+ ],
118
+ },
119
+ {
120
+ step: 4,
121
+ title: 'Fix Directly (with Decision-Point Carve-Outs)',
122
+ goal: 'Apply the smallest defensible fix per finding, except for decisions that the user must own. ' +
123
+ 'Reviewing without fixing is a downgrade unless the user asked for review-only.',
124
+ actions: [
125
+ 'Fix issues that are factual / structural / verification-related directly (vague verification, missing failure paths, unactionable tasks, doc-vs-behavior drift)',
126
+ 'For decision-heavy items (product positioning / pricing / arch direction / legal-finance-security / external facts): surface options + risk notes + decision points instead of unilaterally finalizing',
127
+ 'Do not expand scope beyond what the user requested',
128
+ 'Do not invent test results, performance data, or external validation',
129
+ 'Do not delete valid existing user content',
130
+ 'Do not sacrifice accuracy for polish',
131
+ ],
132
+ exitCriteria: [
133
+ 'Each fixed item is paired with the original finding it addresses',
134
+ 'Decision-only items are explicitly flagged as awaiting user input rather than silently dropped',
135
+ ],
136
+ },
137
+ {
138
+ step: 5,
139
+ title: 'Re-Review After Fixes',
140
+ goal: 'Verify that fixes actually resolved the original findings without introducing new contradictions. ' +
141
+ 'Skipping re-review is the most common way the loop silently fails.',
142
+ actions: [
143
+ 'Confirm each previous finding is now resolved or explicitly downgraded with rationale',
144
+ 'Check whether the fix introduced new contradictions across files / sections',
145
+ 'Re-run the three-layer scan focused on changed areas plus their dependents',
146
+ 'Update the running findings list — do not silently drop unresolved items',
147
+ ],
148
+ exitCriteria: [
149
+ 'Every original P1/P2 finding has a resolution status: closed / partially-closed / blocked',
150
+ 'New findings discovered during re-review are added to the list, not ignored',
151
+ ],
152
+ },
153
+ {
154
+ step: 6,
155
+ title: 'Iterate Until Convergence',
156
+ goal: 'Loop fix → re-review until stop conditions are met. Multiple rounds are allowed and expected; ' +
157
+ 'one fix pass is rarely enough for a production-grade artifact.',
158
+ actions: [
159
+ 'If obvious P1/P2 issues remain, return to step 4 with the updated findings list',
160
+ 'Each round must make concrete progress — no "we will revisit this" hand-waving',
161
+ 'If repeated rounds reveal a problem that cannot be resolved with current information, convert it into a documented blocker / open question / user decision rather than looping forever',
162
+ ],
163
+ exitCriteria: [
164
+ 'At least one stop condition (see protocol.stopConditions) is satisfied',
165
+ 'Remaining issues are either low-risk presentation items or explicitly-documented blockers',
166
+ ],
167
+ loopBackTo: [4, 5],
168
+ },
169
+ {
170
+ step: 7,
171
+ title: 'Final Output — Verdict + Findings + Fix Summary + Delta Table',
172
+ goal: 'Close the loop with a structured output that lets the user verify convergence without re-reading the entire artifact. ' +
173
+ 'Missing the delta table means the protocol did not actually run.',
174
+ actions: [
175
+ 'Write Final Verdict: converged? blocking risk? suitable for next step (implementation / release / signoff)?',
176
+ 'List Final Findings by severity OR write "No remaining high-risk findings"',
177
+ 'Write Fix Summary: what was actually changed this round (do not turn it into a changelog)',
178
+ 'Render Initial-vs-Final Delta Table with the required columns',
179
+ 'If blockers remain, append a Blockers / Open Questions section after the delta table',
180
+ ],
181
+ exitCriteria: [
182
+ 'All four required output sections are present',
183
+ 'Delta table only contains rows that reflect real changes — no padded artificial rows',
184
+ ],
185
+ },
186
+ ],
187
+ severityLevels: {
188
+ P1: 'Would cause wrong implementation, wrong decisions, wrong acceptance, launch risk, or security risk. ' +
189
+ 'Must be resolved or explicitly converted to a blocker before stopping.',
190
+ P2: 'Would create likely rework, scope drift, missed critical paths, verification gaps, or maintenance risk. ' +
191
+ 'Must be resolved or explicitly downgraded with rationale.',
192
+ P3: 'Weak wording, average structure, readability issues, or low-risk maintainability problems. ' +
193
+ 'May remain after convergence if higher-severity items are clean.',
194
+ },
195
+ outputContract: [
196
+ {
197
+ name: 'Final Verdict',
198
+ required: true,
199
+ format: 'plain text, 2–4 short bullets',
200
+ description: 'State concisely: whether the current version is basically converged, whether any blocking risk remains, ' +
201
+ 'and whether it is suitable for the next step (implementation / release / review / open source / launch / signoff).',
202
+ },
203
+ {
204
+ name: 'Final Findings',
205
+ required: true,
206
+ format: 'severity-grouped list (P1 / P2 / P3) OR the literal string "No remaining high-risk findings"',
207
+ description: 'List remaining findings ordered by severity. If no high-risk issues remain, write "No remaining high-risk findings" explicitly. ' +
208
+ 'Do not pad with vague suggestions promoted to P1/P2.',
209
+ },
210
+ {
211
+ name: 'Fix Summary',
212
+ required: true,
213
+ format: 'short bullet list of behavior-level changes',
214
+ description: 'Summarize what was actually fixed in this round. Behavior-level descriptions, not file-level changelog. ' +
215
+ 'One line per coherent fix.',
216
+ },
217
+ {
218
+ name: 'Initial-vs-Final Delta Table',
219
+ required: true,
220
+ format: 'markdown table with exactly the columns: | Area | Initial Issue | Adjustment | Current Status | Impact |',
221
+ description: 'Compare initial baseline (from step 2) to current state. Area examples: goal alignment, scope boundaries, ' +
222
+ 'design completeness, task structure, verification design, failure handling, acceptance criteria, executability, ' +
223
+ 'performance and capacity, scalability, security and permissions, production operations, long-term maintainability, ' +
224
+ 'user value, business viability. Only include rows for areas that actually changed — do not pad.',
225
+ },
226
+ {
227
+ name: 'Blockers / Open Questions',
228
+ required: false,
229
+ format: 'numbered list, each item linking back to the finding it derives from',
230
+ description: 'Only present when issues remain that need user input or external facts. Each blocker must state: what is unknown, ' +
231
+ 'what answer would unblock progress, and which finding it ties back to.',
232
+ },
233
+ ],
234
+ stopConditions: [
235
+ 'No obvious P1 or P2 risks remain in the artifact',
236
+ 'All remaining issues are low-risk wording or presentation improvements (P3 only)',
237
+ 'A critical ambiguity, missing input, or user decision still blocks progress, AND the blocker has been clearly documented in the output',
238
+ ],
239
+ prohibitions: [
240
+ 'Do not only review without fixing unless the user explicitly asked for review-only',
241
+ 'Do not fix one file while ignoring consistency with related artifacts',
242
+ 'Do not declare completion without re-review (skipping step 5/6)',
243
+ 'Do not say "this is fine" while obvious P1/P2 risks remain',
244
+ 'Do not omit the final Initial-vs-Final Delta Table',
245
+ 'Do not skip goal creation or equivalent goal-driven thinking for complex / multi-file / high-risk hardening',
246
+ 'Do not wrap up without a clear "initial vs current" comparison',
247
+ 'Do not default to "let us do a minimal version first" unless the user explicitly accepts a prototype or demo',
248
+ 'Do not restrict this protocol to OpenSpec / SuperSpec scenarios — it applies to any production-grade artifact',
249
+ 'Do not let this protocol take over normal one-pass review, code review, or light editing tasks',
250
+ 'Do not make unverifiable decisions on behalf of the user in strategic / legal / financial / security / compliance artifacts',
251
+ 'Do not invent test results, performance numbers, or external validation evidence',
252
+ 'Do not delete valid existing user content under the guise of "cleanup"',
253
+ 'Do not pad the delta table with artificial rows that do not reflect real changes',
254
+ ],
255
+ artifactChecklists: {
256
+ 'product-plan': [
257
+ 'Users, scenarios, and pain points are concrete — not generic personas',
258
+ 'Revenue model, cost structure, and risk assumptions are explicit',
259
+ 'Key metrics, validation experiments, and failure criteria are explicit',
260
+ 'Wishes are not presented as facts',
261
+ 'Competition, channels, conversion, retention, or commercial loop are not silently missing',
262
+ ],
263
+ architecture: [
264
+ 'Architecture boundaries, module responsibilities, and data flow are clear',
265
+ 'Key technical choices have real trade-off reasoning (rejected alternatives + why)',
266
+ 'Failure handling, degradation, rollback, and observability are covered',
267
+ 'Security, permissions, and data consistency are explicit',
268
+ 'Tasks and verification can actually drive engineering implementation, not just describe intent',
269
+ ],
270
+ readme: [
271
+ 'A new user can tell what the project is in under 30 seconds',
272
+ 'The minimum success path appears early',
273
+ 'Command side effects, outputs, and failure handling are explained',
274
+ 'Install / upgrade / migration guidance does not contradict itself',
275
+ 'Text contains no over-marketing or vague AI-flavored filler',
276
+ ],
277
+ pr: [
278
+ 'Change scope is clear — what is in vs out of this PR',
279
+ 'Risk, rollback, compatibility, and validation evidence are explicit',
280
+ 'Executed vs unexecuted checks are clearly separated — no implied success',
281
+ 'User impact, data impact, or operational impact is not silently missing',
282
+ ],
283
+ 'prompt-agent-skill': [
284
+ 'Trigger conditions are clear — when does this fire and when does it not',
285
+ 'Inputs, outputs, boundaries, and prohibitions are explicit',
286
+ 'Does not encourage overreach, fake verification, or false promises',
287
+ 'Can work independently downstream — not bound to a specific session',
288
+ 'Not over-bound to one project or one filesystem path',
289
+ ],
290
+ openspec: [
291
+ 'proposal.md clearly explains purpose, scope, non-goals, and risk',
292
+ 'design.md explains implementation path, boundaries, failure paths, and constraints',
293
+ 'tasks.md satisfies the current system\'s execution-ready contract, including stable task refs such as 1.1 / 2.1 where decomposition is needed',
294
+ 'specs/<capability>/spec.md files cover critical behavior, constraints, and acceptance semantics',
295
+ 'Proposal goals are carried through by design / specs / tasks consistently',
296
+ 'Task verification requirements align with specs — no contradictions',
297
+ ],
298
+ },
299
+ generalConstraints: [
300
+ 'Default to Chinese when responding to the end user',
301
+ 'Put findings before summary',
302
+ 'Do not tell a story',
303
+ 'Do not add hollow encouragement',
304
+ 'Do not treat "we can revisit this later" as completion',
305
+ 'For document tasks, prioritize contract clarity, consistency, executability, and verifiability',
306
+ 'Explicitly reject any attempt to downgrade a production-grade goal into a demo, minimal implementation, or basic sample',
307
+ ],
308
+ };
309
+ //# sourceMappingURL=review-to-solid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-to-solid.js","sourceRoot":"","sources":["../../src/protocols/review-to-solid.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * prompt — 轻量交互工具(基于 Node 内置 readline)
3
+ *
4
+ * 设计目标:
5
+ * 1. specdo 砍掉 @inquirer/core / @inquirer/prompts 11 个依赖中的部分
6
+ * 复杂提示库,仅保留文本输入交互场景
7
+ * 2. 任何命令在 CI / 非 TTY / `--non-interactive` 标记下必须能跳过
8
+ * 交互,由 `--answers <json>` 等替代输入
9
+ * 3. 提供同步可测试的实现:测试可通过传入 `input` / `output` 流模拟
10
+ * 用户输入,避免 mock readline
11
+ */
12
+ /** 判断当前进程是否处于"非交互"环境(CI / 无 TTY / 显式禁用) */
13
+ export declare function isNonInteractive(env?: NodeJS.ProcessEnv): boolean;
14
+ export interface AskQuestionOptions {
15
+ /** 自定义输入流(测试时可注入) */
16
+ input?: NodeJS.ReadableStream;
17
+ /** 自定义输出流(测试时可注入) */
18
+ output?: NodeJS.WritableStream;
19
+ }
20
+ /**
21
+ * 同步式(async)从交互终端读取一行输入。
22
+ *
23
+ * 调用前请先用 isNonInteractive 判断;非交互环境下应避免调用本函数。
24
+ */
25
+ export declare function askQuestion(question: string, options?: AskQuestionOptions): Promise<string>;
26
+ /**
27
+ * 解析 `--answers <json>` 参数为 Record<string,string>。
28
+ *
29
+ * 接受格式:
30
+ * - `'{"security:0":"yes","security:1":"no"}'`:直接 JSON 对象
31
+ * - `'[]'` / `'{}'`:返回空对象
32
+ *
33
+ * 异常:JSON 解析失败、非对象、值非字符串均抛 Error,调用方应捕获后以
34
+ * exit code 1 结束并提示用户。
35
+ */
36
+ export declare function parseAnswersJson(raw: string): Record<string, string>;
37
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/utils/prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,2CAA2C;AAC3C,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAK9E;AAED,MAAM,WAAW,kBAAkB;IACjC,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,qBAAqB;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;CAChC;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAcrG;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAwBpE"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * prompt — 轻量交互工具(基于 Node 内置 readline)
3
+ *
4
+ * 设计目标:
5
+ * 1. specdo 砍掉 @inquirer/core / @inquirer/prompts 11 个依赖中的部分
6
+ * 复杂提示库,仅保留文本输入交互场景
7
+ * 2. 任何命令在 CI / 非 TTY / `--non-interactive` 标记下必须能跳过
8
+ * 交互,由 `--answers <json>` 等替代输入
9
+ * 3. 提供同步可测试的实现:测试可通过传入 `input` / `output` 流模拟
10
+ * 用户输入,避免 mock readline
11
+ */
12
+ import * as readline from 'node:readline';
13
+ /** 判断当前进程是否处于"非交互"环境(CI / 无 TTY / 显式禁用) */
14
+ export function isNonInteractive(env = process.env) {
15
+ if (env.SPECDO_NON_INTERACTIVE === '1' || env.SPECDO_NON_INTERACTIVE === 'true')
16
+ return true;
17
+ if (env.CI === 'true' || env.CI === '1')
18
+ return true;
19
+ if (!process.stdin.isTTY)
20
+ return true;
21
+ return false;
22
+ }
23
+ /**
24
+ * 同步式(async)从交互终端读取一行输入。
25
+ *
26
+ * 调用前请先用 isNonInteractive 判断;非交互环境下应避免调用本函数。
27
+ */
28
+ export async function askQuestion(question, options = {}) {
29
+ const rl = readline.createInterface({
30
+ input: options.input ?? process.stdin,
31
+ output: options.output ?? process.stdout,
32
+ });
33
+ try {
34
+ return await new Promise((resolve) => {
35
+ rl.question(question.endsWith(' ') ? question : question + ' ', (answer) => {
36
+ resolve(answer.trim());
37
+ });
38
+ });
39
+ }
40
+ finally {
41
+ rl.close();
42
+ }
43
+ }
44
+ /**
45
+ * 解析 `--answers <json>` 参数为 Record<string,string>。
46
+ *
47
+ * 接受格式:
48
+ * - `'{"security:0":"yes","security:1":"no"}'`:直接 JSON 对象
49
+ * - `'[]'` / `'{}'`:返回空对象
50
+ *
51
+ * 异常:JSON 解析失败、非对象、值非字符串均抛 Error,调用方应捕获后以
52
+ * exit code 1 结束并提示用户。
53
+ */
54
+ export function parseAnswersJson(raw) {
55
+ const MAX_ANSWERS_BYTES = 50_000; // 50 KB
56
+ if (raw.length > MAX_ANSWERS_BYTES) {
57
+ throw new Error(`--answers payload too large (${raw.length} bytes; max ${MAX_ANSWERS_BYTES})`);
58
+ }
59
+ let parsed;
60
+ try {
61
+ parsed = JSON.parse(raw);
62
+ }
63
+ catch (err) {
64
+ throw new Error(`--answers JSON parse failed: ${err.message}`);
65
+ }
66
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
67
+ throw new Error('--answers must be a JSON object whose values are strings');
68
+ }
69
+ // Use null-prototype object to avoid __proto__ / constructor key pitfalls
70
+ const result = Object.create(null);
71
+ for (const [key, value] of Object.entries(parsed)) {
72
+ if (key === '__proto__' || key === 'constructor' || key === 'prototype')
73
+ continue;
74
+ if (typeof value !== 'string') {
75
+ throw new Error(`--answers value for key "${key}" must be a string`);
76
+ }
77
+ result[key] = value;
78
+ }
79
+ return result;
80
+ }
81
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/utils/prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAE1C,2CAA2C;AAC3C,MAAM,UAAU,gBAAgB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACnE,IAAI,GAAG,CAAC,sBAAsB,KAAK,GAAG,IAAI,GAAG,CAAC,sBAAsB,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAC7F,IAAI,GAAG,CAAC,EAAE,KAAK,MAAM,IAAI,GAAG,CAAC,EAAE,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IACrD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACtC,OAAO,KAAK,CAAC;AACf,CAAC;AASD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,QAAgB,EAAE,UAA8B,EAAE;IAClF,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;QAClC,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK;QACrC,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM;KACzC,CAAC,CAAC;IACH,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;YAC3C,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,GAAG,GAAG,EAAE,CAAC,MAAM,EAAE,EAAE;gBACzE,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YACzB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,MAAM,iBAAiB,GAAG,MAAM,CAAC,CAAC,QAAQ;IAC1C,IAAI,GAAG,CAAC,MAAM,GAAG,iBAAiB,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,gCAAgC,GAAG,CAAC,MAAM,eAAe,iBAAiB,GAAG,CAAC,CAAC;IACjG,CAAC;IACD,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,gCAAiC,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5E,CAAC;IACD,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3E,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IACD,0EAA0E;IAC1E,MAAM,MAAM,GAA2B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC3D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAiC,CAAC,EAAE,CAAC;QAC7E,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,aAAa,IAAI,GAAG,KAAK,WAAW;YAAE,SAAS;QAClF,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,4BAA4B,GAAG,oBAAoB,CAAC,CAAC;QACvE,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACtB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "specdo",
3
+ "version": "1.0.2",
4
+ "description": "Self-contained CLI for spec-driven development with built-in domain knowledge",
5
+ "keywords": [
6
+ "specdo",
7
+ "spec-driven",
8
+ "specification",
9
+ "cli",
10
+ "tdd",
11
+ "domain-driven",
12
+ "workflow",
13
+ "changelog"
14
+ ],
15
+ "license": "MIT",
16
+ "author": "SpecDo Contributors",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/MoonCoder-HAPPY/SpecDo.git"
20
+ },
21
+ "homepage": "https://github.com/MoonCoder-HAPPY/SpecDo#readme",
22
+ "bugs": {
23
+ "url": "https://github.com/MoonCoder-HAPPY/SpecDo/issues"
24
+ },
25
+ "type": "module",
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "bin": {
30
+ "specdo": "bin/specdo.js"
31
+ },
32
+ "files": [
33
+ "dist",
34
+ "bin",
35
+ "docs",
36
+ "README.md",
37
+ "CHANGELOG.md",
38
+ "LICENSE",
39
+ "SECURITY.md",
40
+ "CONTRIBUTING.md",
41
+ "CODE_OF_CONDUCT.md"
42
+ ],
43
+ "scripts": {
44
+ "clean": "node scripts/clean-artifacts.mjs",
45
+ "lint": "eslint src/ build.js build-activation.test.mjs vitest.config.ts scripts/release-check.mjs scripts/pack-dry-run.mjs scripts/verify-packed-cli.mjs scripts/clean-artifacts.mjs scripts/clean-artifacts.test.mjs",
46
+ "build": "node build.js",
47
+ "dev": "tsc --watch",
48
+ "test": "vitest run",
49
+ "test:watch": "vitest",
50
+ "test:coverage": "vitest --coverage",
51
+ "prepare": "husky",
52
+ "prepack": "pnpm run build",
53
+ "release:check": "node scripts/clean-artifacts.mjs && pnpm lint && pnpm exec tsc --noEmit && pnpm test -- --maxWorkers=1 && pnpm run build && node scripts/release-check.mjs && node scripts/pack-dry-run.mjs && node scripts/verify-packed-cli.mjs && bash ./scripts/smoke-test.sh",
54
+ "prepublishOnly": "pnpm run release:check"
55
+ },
56
+ "lint-staged": {
57
+ "src/**/*.ts": [
58
+ "eslint --fix"
59
+ ]
60
+ },
61
+ "engines": {
62
+ "node": ">=20.19.0"
63
+ },
64
+ "devDependencies": {
65
+ "@types/node": "^24.2.0",
66
+ "@vitest/coverage-v8": "^4.1.8",
67
+ "eslint": "^9.39.2",
68
+ "husky": "^9.1.7",
69
+ "lint-staged": "^17.0.5",
70
+ "typescript": "^5.9.3",
71
+ "typescript-eslint": "^8.50.1",
72
+ "vitest": "^3.2.4"
73
+ },
74
+ "dependencies": {
75
+ "chalk": "^5.5.0",
76
+ "commander": "^14.0.0",
77
+ "yaml": "^2.8.2",
78
+ "zod": "^4.0.17"
79
+ }
80
+ }