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,291 @@
1
+ /**
2
+ * Cross-Domain Collaboration Notes
3
+ *
4
+ * 每个 domain skill 都会被注入这些"跨领域协同"片段,作为 references/CROSS_DOMAIN.md
5
+ * 写入 progressive-disclosure 子目录。
6
+ *
7
+ * 内容是手写的,因为跨领域协作语义无法从 DomainModule 数据机械推导。
8
+ * 目的是让 agent 知道:触发了 domain X 时,是否应同时考虑 domain Y、
9
+ * 在边界处由谁拥有最终决定权、典型冲突点。
10
+ */
11
+ export const CROSS_DOMAIN_NOTES = {
12
+ security: `# security — Cross-domain collaboration
13
+
14
+ The security domain rarely fires alone. It overlays other domains and
15
+ expresses non-functional constraints; treat its checklist as **veto power**
16
+ on the others when the two disagree.
17
+
18
+ ## With architecture
19
+
20
+ - Auth boundaries / trust zones are architectural concerns; security defines
21
+ what each zone may carry. Disagreement: security wins on data-classification
22
+ and least-privilege; architecture wins on transport / topology.
23
+ - Threat-model the integration surface BEFORE picking patterns — a clean
24
+ hexagonal split is worthless if a port leaks PII.
25
+
26
+ ## With backend
27
+
28
+ - Every query authored under "backend" must pass security's parameterized-
29
+ query and authorization checks. Backend owns query shape, security owns
30
+ injection / IDOR / row-level access.
31
+ - Secret rotation lives here, not in backend operational scripts.
32
+
33
+ ## With frontend
34
+
35
+ - Output encoding (XSS) is a frontend implementation choice but a security
36
+ requirement. Frontend chooses the templating library; security audits the
37
+ escape contract.
38
+ - CSRF tokens / SameSite cookies span both domains — frontend renders, but
39
+ the policy is security's call.
40
+
41
+ ## With operations
42
+
43
+ - TLS termination, secret stores, WAF rules, dependency scanning in CI —
44
+ operations owns the plumbing, security owns the policy.
45
+ - Incident response runbooks need both inputs.
46
+
47
+ ## With quality
48
+
49
+ - Test coverage for auth flows (positive, negative, privilege escalation) is
50
+ a quality concern; the *list of attacks to cover* is security's deliverable.
51
+
52
+ ## Conflict triage
53
+
54
+ If two checklists collide, security wins for: data classification, key
55
+ material, audit-trail completeness, deny-by-default. The other domain wins
56
+ for: structural choice (service shape, data model, render strategy).
57
+ `,
58
+ architecture: `# architecture — Cross-domain collaboration
59
+
60
+ Architecture sets the structural skeleton everyone else lives in. It rarely
61
+ adds *correctness* clauses on its own; it constrains how the others compose.
62
+
63
+ ## With backend
64
+
65
+ - Service boundaries, port/adapter shapes, transactional scope: architecture
66
+ proposes, backend implements. Backend may push back if the proposal forces
67
+ N+1 queries or distributed transactions.
68
+ - Data ownership per service is architecture's call.
69
+
70
+ ## With frontend
71
+
72
+ - Frontend/backend contract (REST, GraphQL, RPC, events) is architectural;
73
+ frontend then chooses client library + state shape.
74
+ - BFF (backend-for-frontend) decisions are joint, owned by architecture
75
+ but vetted by frontend for ergonomics.
76
+
77
+ ## With security
78
+
79
+ - See security/CROSS_DOMAIN: architecture defines zones, security defines
80
+ what may cross them. Whenever a proposed boundary moves PII / secrets,
81
+ re-open the threat model.
82
+
83
+ ## With operations
84
+
85
+ - Deployable unit shape (monolith, services, functions) is the
86
+ architecture↔operations contract. Architecture decides "what's a unit",
87
+ operations decides "how it ships and runs".
88
+ - Architectural change ⇒ runbook change. Tag operations on every
89
+ topology-affecting proposal.
90
+
91
+ ## With quality
92
+
93
+ - Testability is non-negotiable architecture pressure: any boundary that
94
+ resists unit testing is an anti-pattern even if it "feels clean".
95
+ - Cross-service contract tests are an architecture deliverable.
96
+
97
+ ## Conflict triage
98
+
99
+ Architecture loses to security on data-flow restrictions; loses to
100
+ operations on deploy-feasibility; loses to backend on real-world data-shape
101
+ performance. It wins on: long-term modular evolution, boundary clarity,
102
+ public-API stability.
103
+ `,
104
+ operations: `# operations — Cross-domain collaboration
105
+
106
+ Operations owns *how the system runs in production*. Most other domains
107
+ generate operations requirements as side-effects of their own deliverables.
108
+
109
+ ## With architecture
110
+
111
+ - See architecture/CROSS_DOMAIN: deployable unit shape is the contract.
112
+ Operations rejects topologies it cannot observe or roll back.
113
+ - Migration / canary / blue-green strategy is operations' call once
114
+ architecture has settled the unit shape.
115
+
116
+ ## With backend
117
+
118
+ - Database migrations, queue / cache provisioning, connection-pool sizing:
119
+ joint, but operations owns the runbook and the alarm thresholds.
120
+ - Backward-compatibility windows during deploys are operations' veto.
121
+
122
+ ## With frontend
123
+
124
+ - Static asset CDN, cache headers, build artifact versioning, error-tracking
125
+ integration are operations concerns; frontend owns the build pipeline shape.
126
+ - Feature-flag system: operations supplies the platform, frontend uses it.
127
+
128
+ ## With security
129
+
130
+ - See security/CROSS_DOMAIN: operations runs the plumbing for security
131
+ policy. Secret stores, TLS certificates, audit-log retention all live here.
132
+ - Incident response on-call rotations and access reviews are operations.
133
+
134
+ ## With quality
135
+
136
+ - CI/CD pipeline, flaky-test quarantine, performance regression gates are
137
+ operations' tooling for quality's policies.
138
+
139
+ ## Conflict triage
140
+
141
+ Operations vetoes anything it cannot monitor, roll back, or scale. Wins
142
+ on: release safety, observability, capacity planning. Loses to security on
143
+ audit/retention policy; loses to architecture on long-term unit shape.
144
+ `,
145
+ backend: `# backend — Cross-domain collaboration
146
+
147
+ Backend owns data + business-logic execution. It produces evidence the
148
+ other domains audit.
149
+
150
+ ## With architecture
151
+
152
+ - Architecture proposes the service / boundary; backend implements with
153
+ concrete data shapes and persistence choices. Backend pushes back on
154
+ proposals that hide N+1, fan-out joins, or distributed-transaction needs.
155
+
156
+ ## With frontend
157
+
158
+ - API contract (shape, pagination, error envelope) is a joint deliverable.
159
+ Backend owns canonical types; frontend owns DTOs / view models.
160
+ - Optimistic-update friendliness is a backend concern (idempotency keys,
161
+ ETag support, status codes).
162
+
163
+ ## With security
164
+
165
+ - See security/CROSS_DOMAIN: every backend query passes security's audit
166
+ for parameterization, IDOR prevention, and authorization checks.
167
+ - Soft-delete vs hard-delete is security ↔ backend joint (compliance +
168
+ storage cost).
169
+
170
+ ## With operations
171
+
172
+ - Migration scripts, index changes, connection-pool tuning: backend writes,
173
+ operations runs and monitors. Joint runbook required.
174
+ - Backward-compatibility windows during schema migrations are operations'
175
+ ask but backend's design constraint (additive-then-removal pattern).
176
+
177
+ ## With quality
178
+
179
+ - Test pyramid: unit tests for pure business logic, integration tests for
180
+ data access, contract tests for the public API. Backend owns the structure;
181
+ quality owns the discipline.
182
+
183
+ ## Conflict triage
184
+
185
+ Backend wins on: data model fidelity, transactional correctness, read/write
186
+ performance. Loses to security on injection/authorization, loses to
187
+ operations on migration safety, loses to architecture on long-term API
188
+ stability when the two collide.
189
+ `,
190
+ quality: `# quality — Cross-domain collaboration
191
+
192
+ Quality is a *meta-domain*: it overlays whatever business-domain skills are
193
+ matched, enforcing TDD discipline, review rigor, and regression prevention.
194
+
195
+ ## With every domain
196
+
197
+ - Quality has no exclusive checklist of its own; instead, every business-
198
+ domain's verify.checklist must be **enforceable by automation** under
199
+ quality's discipline. If a check requires manual eyeballing only, quality
200
+ flags it as a refactor candidate.
201
+
202
+ ## With security
203
+
204
+ - Test coverage for auth / authz / injection paths is jointly owned: the
205
+ attacks to cover are security's, the test infrastructure is quality's.
206
+ - Security audit findings flow into quality's regression-test backlog.
207
+
208
+ ## With backend
209
+
210
+ - Contract tests (provider + consumer) sit on quality's pyramid but the
211
+ contracts themselves are backend deliverables. Flaky contract tests are
212
+ quality's escalation, backend's fix.
213
+
214
+ ## With frontend
215
+
216
+ - Visual regression / a11y testing infrastructure is quality; the snapshot /
217
+ axe rule set is frontend.
218
+ - Component testing strategy (RTL + jsdom vs full browser) is a joint
219
+ decision.
220
+
221
+ ## With architecture
222
+
223
+ - Testability is the joint pressure: any architectural boundary that
224
+ resists testing must be revisited. Architecture loses ties here.
225
+
226
+ ## With operations
227
+
228
+ - CI / CD configuration, flaky-test quarantine, mutation testing, mutation-
229
+ coverage gates: quality writes the policy, operations runs the pipeline.
230
+ - Performance regression gates are joint.
231
+
232
+ ## Conflict triage
233
+
234
+ Quality never wins a design argument on its own ("we should restructure
235
+ this for testability") — it wins by tagging in the relevant business domain
236
+ (usually architecture) to make the case structurally. Its veto is on:
237
+ PR merge without proportionate test evidence, broken regression suite,
238
+ test coverage regression on critical paths.
239
+ `,
240
+ frontend: `# frontend — Cross-domain collaboration
241
+
242
+ Frontend owns the user-facing surface — rendering, interaction, perceived
243
+ performance. It consumes contracts from backend and is policed by security
244
+ on output handling.
245
+
246
+ ## With backend
247
+
248
+ - API contract (REST / GraphQL / RPC shape, error envelope, pagination,
249
+ status-code semantics) is joint. Frontend asks for ergonomic shapes;
250
+ backend asks for performance-friendly shapes.
251
+ - Optimistic UI requires backend support (idempotency keys, ETag, retry-
252
+ safe POSTs). Not all flows can be optimistic — frontend must defer to
253
+ backend's safe-set.
254
+
255
+ ## With security
256
+
257
+ - See security/CROSS_DOMAIN: every render of user-controlled content runs
258
+ through security's encoding rules. Frontend chooses the templating
259
+ library; security audits the escape contract.
260
+ - CSRF / CSP / SameSite cookies are policy → security, mechanism → frontend.
261
+
262
+ ## With architecture
263
+
264
+ - Routing topology (SPA, MPA, RSC, islands) is architectural; component
265
+ shape (atomic, feature-folder) is frontend. The boundary is "where the
266
+ network actually splits".
267
+ - BFF (backend-for-frontend) decisions are joint, vetted by frontend for
268
+ ergonomics.
269
+
270
+ ## With operations
271
+
272
+ - Build pipeline (Vite / Next / Webpack), CDN caching, source-map upload,
273
+ error-tracking integration: frontend owns the build, operations owns the
274
+ delivery infrastructure.
275
+ - Feature flags: operations provides the platform; frontend consumes.
276
+
277
+ ## With quality
278
+
279
+ - a11y testing, visual regression, RTL component testing, lighthouse
280
+ budgets: infrastructure is quality, rule set is frontend.
281
+ - "Test from the user's perspective" maxim is jointly owned.
282
+
283
+ ## Conflict triage
284
+
285
+ Frontend wins on: user-perceived performance, a11y compliance, interaction
286
+ ergonomics. Loses to backend on API shape when the two collide (the
287
+ contract is the source of truth — DTO mapping is the price). Loses to
288
+ security on output encoding. Loses to operations on bundle size budgets.
289
+ `,
290
+ };
291
+ //# sourceMappingURL=cross-domain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cross-domain.js","sourceRoot":"","sources":["../../../src/core/skill-content/cross-domain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAA2B;IACxD,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6CX;IAEC,YAAY,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6Cf;IAEC,UAAU,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwCb;IAEC,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4CV;IAEC,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiDV;IAEC,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiDX;CACA,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Protocol Skill Examples
3
+ *
4
+ * 手写的 do/don't 代码示例,给 protocol skill 的 references/EXAMPLES.md。
5
+ * 目前只有 review-to-solid 一个 protocol,所以这里只有一段内容。
6
+ *
7
+ * 内容覆盖:S / O / L / I / D 各一段,每段含
8
+ * - 抽象违例 → 修复方向(不是手把手改写)
9
+ * - review-to-solid 工作流如何识别它
10
+ * - 与"轻度 review"(P3) vs "重构必需"(P1) 的分级
11
+ */
12
+ export declare const PROTOCOL_EXAMPLES: Record<string, string>;
13
+ //# sourceMappingURL=protocol-examples.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol-examples.d.ts","sourceRoot":"","sources":["../../../src/core/skill-content/protocol-examples.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAiLpD,CAAC"}
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Protocol Skill Examples
3
+ *
4
+ * 手写的 do/don't 代码示例,给 protocol skill 的 references/EXAMPLES.md。
5
+ * 目前只有 review-to-solid 一个 protocol,所以这里只有一段内容。
6
+ *
7
+ * 内容覆盖:S / O / L / I / D 各一段,每段含
8
+ * - 抽象违例 → 修复方向(不是手把手改写)
9
+ * - review-to-solid 工作流如何识别它
10
+ * - 与"轻度 review"(P3) vs "重构必需"(P1) 的分级
11
+ */
12
+ export const PROTOCOL_EXAMPLES = {
13
+ 'review-to-solid': `# review-to-solid — Do / Don't examples
14
+
15
+ Pairs of "violation" / "fix direction" across the five SOLID letters,
16
+ annotated with the severity the protocol would tag (P1/P2/P3) and the
17
+ workflow step that surfaces it.
18
+
19
+ ---
20
+
21
+ ## S — Single Responsibility
22
+
23
+ **Violation (P2, flagged in Step 3 "Solid lens"):**
24
+
25
+ \`\`\`ts
26
+ class UserService {
27
+ async createUser(input: UserInput): Promise<User> {
28
+ const validated = this.validate(input); // validation
29
+ const hashed = await bcrypt.hash(input.password, 12); // crypto
30
+ const user = await this.db.insert('users', validated);// persistence
31
+ await this.mailer.send(user.email, 'welcome'); // I/O
32
+ await this.metrics.increment('user.created'); // telemetry
33
+ return user;
34
+ }
35
+ }
36
+ \`\`\`
37
+
38
+ Five reasons to change in one method. Reviewer should write in the
39
+ **Findings** section:
40
+
41
+ > **[P2 / S]** \`UserService.createUser\` couples validation, crypto,
42
+ > persistence, transactional email, and telemetry. Extract three:
43
+ > \`PasswordHasher\`, \`UserMailer\` (post-commit hook), and metrics
44
+ > middleware. Validation can stay if it's pure input shape.
45
+
46
+ **Fix direction:**
47
+
48
+ \`\`\`ts
49
+ class UserService {
50
+ constructor(
51
+ private hasher: PasswordHasher,
52
+ private mailer: UserMailer,
53
+ private db: DB,
54
+ ) {}
55
+ async createUser(input: UserInput): Promise<User> {
56
+ const validated = this.validate(input);
57
+ const passwordHash = await this.hasher.hash(input.password);
58
+ const user = await this.db.insert('users', { ...validated, passwordHash });
59
+ this.mailer.sendWelcomeAfterCommit(user);
60
+ return user;
61
+ }
62
+ }
63
+ \`\`\`
64
+
65
+ (Metrics moved to a middleware decorator; not shown.)
66
+
67
+ ---
68
+
69
+ ## O — Open / Closed
70
+
71
+ **Violation (P2, flagged in Step 3):**
72
+
73
+ \`\`\`ts
74
+ function priceFor(item: Item, tier: 'free' | 'pro' | 'enterprise'): number {
75
+ if (tier === 'free') return item.basePrice;
76
+ if (tier === 'pro') return item.basePrice * 0.9;
77
+ if (tier === 'enterprise') return item.basePrice * 0.7;
78
+ throw new Error('unknown tier');
79
+ }
80
+ \`\`\`
81
+
82
+ Every new tier forces a code edit + redeploy. **Fix direction:** push the
83
+ discount into a \`PricingStrategy\` data table or per-tier object so adding
84
+ a tier means adding data, not changing behavior code.
85
+
86
+ > **[P2 / O]** \`priceFor\` is closed only to data; open to behavior. Add
87
+ > a tier registry that drives discount lookup; the conditional ladder goes
88
+ > away.
89
+
90
+ ---
91
+
92
+ ## L — Liskov Substitution
93
+
94
+ **Violation (P1, flagged in Step 3 — substitution failures are correctness
95
+ bugs, not stylistic):**
96
+
97
+ \`\`\`ts
98
+ class Rectangle {
99
+ setWidth(w: number) { this.w = w; }
100
+ setHeight(h: number) { this.h = h; }
101
+ area() { return this.w * this.h; }
102
+ }
103
+ class Square extends Rectangle {
104
+ setWidth(w: number) { this.w = w; this.h = w; }
105
+ setHeight(h: number) { this.w = h; this.h = h; }
106
+ }
107
+ // callers expecting Rectangle break when they get Square
108
+ \`\`\`
109
+
110
+ > **[P1 / L]** \`Square extends Rectangle\` violates LSP: setters mutate
111
+ > the sibling axis, so any caller using \`.setWidth(x); .setHeight(y);
112
+ > .area()\` returns x*y for a Rectangle but y² for a Square. Either drop
113
+ > the inheritance (composition: Shape interface) or make both immutable
114
+ > (no setters).
115
+
116
+ ---
117
+
118
+ ## I — Interface Segregation
119
+
120
+ **Violation (P3, flagged in Step 3 — cosmetic unless it breaks evolution):**
121
+
122
+ \`\`\`ts
123
+ interface Worker {
124
+ work(): void;
125
+ eat(): void; // robots don't eat
126
+ sleep(): void; // robots don't sleep
127
+ }
128
+ \`\`\`
129
+
130
+ > **[P3 / I]** \`Worker\` mixes orthogonal concerns. Split into
131
+ > \`Workable\`, \`Feedable\`, \`Restable\`; let each implementor pick.
132
+ > Low urgency if no second implementor exists yet — note it for the next
133
+ > evolution, don't block this PR.
134
+
135
+ ---
136
+
137
+ ## D — Dependency Inversion
138
+
139
+ **Violation (P1 when the dependency is I/O, P3 when it's a value type):**
140
+
141
+ \`\`\`ts
142
+ class OrderService {
143
+ private mailer = new SmtpMailer({ host: 'smtp.gmail.com' }); // hardcoded
144
+ async place(order: Order) {
145
+ await this.mailer.send(order.customerEmail, 'order placed');
146
+ }
147
+ }
148
+ \`\`\`
149
+
150
+ Cannot unit-test without a real SMTP server.
151
+
152
+ > **[P1 / D]** \`OrderService\` constructs \`SmtpMailer\` internally,
153
+ > blocking unit-testability and forcing a config bleed. Inject a
154
+ > \`Mailer\` interface; let the composition root pick \`SmtpMailer\` vs
155
+ > \`FakeMailer\` (tests) vs \`NoopMailer\` (CI).
156
+
157
+ **Fix direction:**
158
+
159
+ \`\`\`ts
160
+ interface Mailer { send(to: string, msg: string): Promise<void>; }
161
+ class OrderService {
162
+ constructor(private mailer: Mailer) {}
163
+ async place(order: Order) {
164
+ await this.mailer.send(order.customerEmail, 'order placed');
165
+ }
166
+ }
167
+ \`\`\`
168
+
169
+ ---
170
+
171
+ ## Workflow reminders
172
+
173
+ - **Step 3** ("Solid lens") is the only step where these patterns are
174
+ surfaced. Don't sneak SOLID critique into Step 1/2 (which is reading +
175
+ smell-listing).
176
+ - **Severity assignment** must be consistent across the same PR — pick a
177
+ rubric (e.g. "P1 = correctness or test-blocker; P2 = scaling pain; P3 =
178
+ cosmetic"), state it once in the **Final Verdict** preamble, then apply.
179
+ - **Step 6** (Re-review) loops back to Step 4 if the fix introduces new
180
+ violations. The Delta Table records initial vs final counts per letter.
181
+
182
+ ## Anti-pattern: SOLID-style review on a 5-line bug fix
183
+
184
+ Triggering review-to-solid on \`if (x === null) return\` is over-eager.
185
+ The protocol's \`suppressionPhrases\` and \`doNotUseWhen\` exist precisely
186
+ for this — see the SKILL.md header. When in doubt, do a light review
187
+ (comment quality, test coverage, naming) and skip the full SOLID pass.
188
+ `,
189
+ };
190
+ //# sourceMappingURL=protocol-examples.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol-examples.js","sourceRoot":"","sources":["../../../src/core/skill-content/protocol-examples.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAA2B;IACvD,iBAAiB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+KpB;CACA,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Workflow Skill Content
3
+ *
4
+ * 5 个工作流 skill 的完整 progressive-disclosure 内容:
5
+ * 每个 skill 由 1 个精炼 SKILL.md(≤ 50 行)+ 1-2 个 references/*.md 组成。
6
+ *
7
+ * - SKILL.md: When to use / Quick command / 链接 references / Next step
8
+ * - references/REFERENCE.md: 完整命令矩阵、所有标志、exit code、错误恢复
9
+ * - references/EXAMPLES.md: 1-2 段真实对话样本
10
+ *
11
+ * 当前内容约束:
12
+ * - 不导出 `specdo-init` skill(input 由 agent 直接引导)
13
+ * - exit code 列表对齐当前 CLI 行为
14
+ * - description 包含真实 trigger 短语("let's plan", "scaffold the change" 等)
15
+ *
16
+ * Source of truth 为代码本身(运行时渲染,无模板文件)。
17
+ */
18
+ export interface WorkflowSkillContent {
19
+ name: string;
20
+ description: string;
21
+ body: string;
22
+ references: Record<string, string>;
23
+ }
24
+ export declare const WORKFLOW_SKILLS: WorkflowSkillContent[];
25
+ //# sourceMappingURL=workflow-content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-content.d.ts","sourceRoot":"","sources":["../../../src/core/skill-content/workflow-content.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AA0/CD,eAAO,MAAM,eAAe,EAAE,oBAAoB,EAmDjD,CAAC"}