@mknightzzz/stw 0.1.0

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 (250) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +277 -0
  3. package/dist/agentic-fallback.d.ts +3 -0
  4. package/dist/agentic-fallback.js +32 -0
  5. package/dist/agentic-fallback.js.map +1 -0
  6. package/dist/agentic-prompt.d.ts +2 -0
  7. package/dist/agentic-prompt.js +68 -0
  8. package/dist/agentic-prompt.js.map +1 -0
  9. package/dist/agentic-runtime.d.ts +48 -0
  10. package/dist/agentic-runtime.js +149 -0
  11. package/dist/agentic-runtime.js.map +1 -0
  12. package/dist/agentic-types.d.ts +37 -0
  13. package/dist/agentic-types.js +2 -0
  14. package/dist/agentic-types.js.map +1 -0
  15. package/dist/agents.d.ts +7 -0
  16. package/dist/agents.js +2 -0
  17. package/dist/agents.js.map +1 -0
  18. package/dist/assignments.d.ts +7 -0
  19. package/dist/assignments.js +125 -0
  20. package/dist/assignments.js.map +1 -0
  21. package/dist/checkpoint.d.ts +35 -0
  22. package/dist/checkpoint.js +78 -0
  23. package/dist/checkpoint.js.map +1 -0
  24. package/dist/circuit-breaker.d.ts +17 -0
  25. package/dist/circuit-breaker.js +65 -0
  26. package/dist/circuit-breaker.js.map +1 -0
  27. package/dist/claim.d.ts +6 -0
  28. package/dist/claim.js +135 -0
  29. package/dist/claim.js.map +1 -0
  30. package/dist/clarity-gate.d.ts +12 -0
  31. package/dist/clarity-gate.js +83 -0
  32. package/dist/clarity-gate.js.map +1 -0
  33. package/dist/cli.d.ts +2 -0
  34. package/dist/cli.js +38 -0
  35. package/dist/cli.js.map +1 -0
  36. package/dist/command-dispatch.d.ts +45 -0
  37. package/dist/command-dispatch.js +206 -0
  38. package/dist/command-dispatch.js.map +1 -0
  39. package/dist/command-parser.d.ts +11 -0
  40. package/dist/command-parser.js +101 -0
  41. package/dist/command-parser.js.map +1 -0
  42. package/dist/commands/clean.d.ts +10 -0
  43. package/dist/commands/clean.js +133 -0
  44. package/dist/commands/clean.js.map +1 -0
  45. package/dist/commands/execution.d.ts +2 -0
  46. package/dist/commands/execution.js +327 -0
  47. package/dist/commands/execution.js.map +1 -0
  48. package/dist/commands/go.d.ts +2 -0
  49. package/dist/commands/go.js +197 -0
  50. package/dist/commands/go.js.map +1 -0
  51. package/dist/commands/helpers.d.ts +44 -0
  52. package/dist/commands/helpers.js +231 -0
  53. package/dist/commands/helpers.js.map +1 -0
  54. package/dist/commands/idea.d.ts +2 -0
  55. package/dist/commands/idea.js +89 -0
  56. package/dist/commands/idea.js.map +1 -0
  57. package/dist/commands/init.d.ts +2 -0
  58. package/dist/commands/init.js +94 -0
  59. package/dist/commands/init.js.map +1 -0
  60. package/dist/commands/integration.d.ts +7 -0
  61. package/dist/commands/integration.js +139 -0
  62. package/dist/commands/integration.js.map +1 -0
  63. package/dist/commands/maintenance.d.ts +2 -0
  64. package/dist/commands/maintenance.js +301 -0
  65. package/dist/commands/maintenance.js.map +1 -0
  66. package/dist/commands/run.d.ts +2 -0
  67. package/dist/commands/run.js +356 -0
  68. package/dist/commands/run.js.map +1 -0
  69. package/dist/commands/setup.d.ts +2 -0
  70. package/dist/commands/setup.js +198 -0
  71. package/dist/commands/setup.js.map +1 -0
  72. package/dist/commands/spec.d.ts +2 -0
  73. package/dist/commands/spec.js +35 -0
  74. package/dist/commands/spec.js.map +1 -0
  75. package/dist/commands/stats.d.ts +2 -0
  76. package/dist/commands/stats.js +80 -0
  77. package/dist/commands/stats.js.map +1 -0
  78. package/dist/commands/task-ops.d.ts +2 -0
  79. package/dist/commands/task-ops.js +406 -0
  80. package/dist/commands/task-ops.js.map +1 -0
  81. package/dist/config.d.ts +18 -0
  82. package/dist/config.js +338 -0
  83. package/dist/config.js.map +1 -0
  84. package/dist/cost.d.ts +30 -0
  85. package/dist/cost.js +167 -0
  86. package/dist/cost.js.map +1 -0
  87. package/dist/crash-recovery.d.ts +9 -0
  88. package/dist/crash-recovery.js +42 -0
  89. package/dist/crash-recovery.js.map +1 -0
  90. package/dist/diagnostic.d.ts +48 -0
  91. package/dist/diagnostic.js +328 -0
  92. package/dist/diagnostic.js.map +1 -0
  93. package/dist/doctor.d.ts +31 -0
  94. package/dist/doctor.js +225 -0
  95. package/dist/doctor.js.map +1 -0
  96. package/dist/drift.d.ts +11 -0
  97. package/dist/drift.js +57 -0
  98. package/dist/drift.js.map +1 -0
  99. package/dist/git-utils.d.ts +20 -0
  100. package/dist/git-utils.js +206 -0
  101. package/dist/git-utils.js.map +1 -0
  102. package/dist/gitlab.d.ts +54 -0
  103. package/dist/gitlab.js +101 -0
  104. package/dist/gitlab.js.map +1 -0
  105. package/dist/idea.d.ts +35 -0
  106. package/dist/idea.js +251 -0
  107. package/dist/idea.js.map +1 -0
  108. package/dist/import-resolution.d.ts +13 -0
  109. package/dist/import-resolution.js +111 -0
  110. package/dist/import-resolution.js.map +1 -0
  111. package/dist/inbox-renderer.d.ts +2 -0
  112. package/dist/inbox-renderer.js +67 -0
  113. package/dist/inbox-renderer.js.map +1 -0
  114. package/dist/init.d.ts +105 -0
  115. package/dist/init.js +235 -0
  116. package/dist/init.js.map +1 -0
  117. package/dist/llm-reviewer.d.ts +14 -0
  118. package/dist/llm-reviewer.js +109 -0
  119. package/dist/llm-reviewer.js.map +1 -0
  120. package/dist/lock.d.ts +26 -0
  121. package/dist/lock.js +76 -0
  122. package/dist/lock.js.map +1 -0
  123. package/dist/logger.d.ts +24 -0
  124. package/dist/logger.js +40 -0
  125. package/dist/logger.js.map +1 -0
  126. package/dist/math-utils.d.ts +2 -0
  127. package/dist/math-utils.js +7 -0
  128. package/dist/math-utils.js.map +1 -0
  129. package/dist/mechanical-review.d.ts +30 -0
  130. package/dist/mechanical-review.js +76 -0
  131. package/dist/mechanical-review.js.map +1 -0
  132. package/dist/merge.d.ts +83 -0
  133. package/dist/merge.js +363 -0
  134. package/dist/merge.js.map +1 -0
  135. package/dist/parallel.d.ts +35 -0
  136. package/dist/parallel.js +214 -0
  137. package/dist/parallel.js.map +1 -0
  138. package/dist/plan-validation.d.ts +19 -0
  139. package/dist/plan-validation.js +253 -0
  140. package/dist/plan-validation.js.map +1 -0
  141. package/dist/planner-prompt.d.ts +33 -0
  142. package/dist/planner-prompt.js +244 -0
  143. package/dist/planner-prompt.js.map +1 -0
  144. package/dist/planner.d.ts +29 -0
  145. package/dist/planner.js +511 -0
  146. package/dist/planner.js.map +1 -0
  147. package/dist/poller.d.ts +34 -0
  148. package/dist/poller.js +91 -0
  149. package/dist/poller.js.map +1 -0
  150. package/dist/progress.d.ts +34 -0
  151. package/dist/progress.js +122 -0
  152. package/dist/progress.js.map +1 -0
  153. package/dist/prompt-builder.d.ts +51 -0
  154. package/dist/prompt-builder.js +481 -0
  155. package/dist/prompt-builder.js.map +1 -0
  156. package/dist/provider.d.ts +14 -0
  157. package/dist/provider.js +278 -0
  158. package/dist/provider.js.map +1 -0
  159. package/dist/question-handler.d.ts +18 -0
  160. package/dist/question-handler.js +154 -0
  161. package/dist/question-handler.js.map +1 -0
  162. package/dist/question-triage.d.ts +31 -0
  163. package/dist/question-triage.js +175 -0
  164. package/dist/question-triage.js.map +1 -0
  165. package/dist/repo-detection.d.ts +8 -0
  166. package/dist/repo-detection.js +18 -0
  167. package/dist/repo-detection.js.map +1 -0
  168. package/dist/retry-context.d.ts +2 -0
  169. package/dist/retry-context.js +196 -0
  170. package/dist/retry-context.js.map +1 -0
  171. package/dist/router.d.ts +18 -0
  172. package/dist/router.js +137 -0
  173. package/dist/router.js.map +1 -0
  174. package/dist/run-artifact-types.d.ts +43 -0
  175. package/dist/run-artifact-types.js +2 -0
  176. package/dist/run-artifact-types.js.map +1 -0
  177. package/dist/run-summary.d.ts +14 -0
  178. package/dist/run-summary.js +347 -0
  179. package/dist/run-summary.js.map +1 -0
  180. package/dist/run-sync.d.ts +11 -0
  181. package/dist/run-sync.js +110 -0
  182. package/dist/run-sync.js.map +1 -0
  183. package/dist/run.d.ts +26 -0
  184. package/dist/run.js +150 -0
  185. package/dist/run.js.map +1 -0
  186. package/dist/scope-expansion.d.ts +10 -0
  187. package/dist/scope-expansion.js +117 -0
  188. package/dist/scope-expansion.js.map +1 -0
  189. package/dist/scope.d.ts +4 -0
  190. package/dist/scope.js +37 -0
  191. package/dist/scope.js.map +1 -0
  192. package/dist/scorecard.d.ts +18 -0
  193. package/dist/scorecard.js +128 -0
  194. package/dist/scorecard.js.map +1 -0
  195. package/dist/spec-templates.d.ts +2 -0
  196. package/dist/spec-templates.js +285 -0
  197. package/dist/spec-templates.js.map +1 -0
  198. package/dist/spec-validator.d.ts +8 -0
  199. package/dist/spec-validator.js +144 -0
  200. package/dist/spec-validator.js.map +1 -0
  201. package/dist/status.d.ts +68 -0
  202. package/dist/status.js +261 -0
  203. package/dist/status.js.map +1 -0
  204. package/dist/storage.d.ts +9 -0
  205. package/dist/storage.js +35 -0
  206. package/dist/storage.js.map +1 -0
  207. package/dist/task-executor-completion.d.ts +12 -0
  208. package/dist/task-executor-completion.js +67 -0
  209. package/dist/task-executor-completion.js.map +1 -0
  210. package/dist/task-executor-fallback.d.ts +20 -0
  211. package/dist/task-executor-fallback.js +12 -0
  212. package/dist/task-executor-fallback.js.map +1 -0
  213. package/dist/task-executor.d.ts +34 -0
  214. package/dist/task-executor.js +521 -0
  215. package/dist/task-executor.js.map +1 -0
  216. package/dist/task-graph.d.ts +11 -0
  217. package/dist/task-graph.js +226 -0
  218. package/dist/task-graph.js.map +1 -0
  219. package/dist/task-pipeline-helpers.d.ts +45 -0
  220. package/dist/task-pipeline-helpers.js +160 -0
  221. package/dist/task-pipeline-helpers.js.map +1 -0
  222. package/dist/task-review.d.ts +51 -0
  223. package/dist/task-review.js +410 -0
  224. package/dist/task-review.js.map +1 -0
  225. package/dist/transitions.d.ts +13 -0
  226. package/dist/transitions.js +104 -0
  227. package/dist/transitions.js.map +1 -0
  228. package/dist/types.d.ts +405 -0
  229. package/dist/types.js +101 -0
  230. package/dist/types.js.map +1 -0
  231. package/dist/utils.d.ts +1 -0
  232. package/dist/utils.js +23 -0
  233. package/dist/utils.js.map +1 -0
  234. package/dist/validation.d.ts +19 -0
  235. package/dist/validation.js +73 -0
  236. package/dist/validation.js.map +1 -0
  237. package/dist/worker-response.d.ts +12 -0
  238. package/dist/worker-response.js +60 -0
  239. package/dist/worker-response.js.map +1 -0
  240. package/dist/worker-runner.d.ts +19 -0
  241. package/dist/worker-runner.js +347 -0
  242. package/dist/worker-runner.js.map +1 -0
  243. package/dist/worktree-cleanup.d.ts +44 -0
  244. package/dist/worktree-cleanup.js +325 -0
  245. package/dist/worktree-cleanup.js.map +1 -0
  246. package/dist/worktree.d.ts +22 -0
  247. package/dist/worktree.js +213 -0
  248. package/dist/worktree.js.map +1 -0
  249. package/examples/spec.md +58 -0
  250. package/package.json +66 -0
@@ -0,0 +1,285 @@
1
+ const TEMPLATES = {
2
+ bugfix: `# Spec: <!-- Title: Fix [describe the bug] -->
3
+
4
+ ## Context
5
+
6
+ <!-- What's broken? Include error messages, reproduction steps, and where it was observed. -->
7
+
8
+ ## Objective
9
+
10
+ <!-- One sentence: what will be true after this fix ships? -->
11
+
12
+ ## Requirements
13
+
14
+ ### T1: <!-- Root-cause fix -->
15
+
16
+ <!-- Describe the fix. Include:
17
+ - Which file(s) and function(s) are affected
18
+ - What the current behavior is vs expected behavior
19
+ - The fix approach
20
+ -->
21
+
22
+ Modified file: <!-- e.g. src/foo.ts -->
23
+
24
+ ### T2: <!-- Regression test -->
25
+
26
+ <!-- Add a test that would have caught this bug. -->
27
+
28
+ Modified file: <!-- e.g. tests/foo.test.ts -->
29
+
30
+ ## Constraints
31
+
32
+ - Fix must not change public API or break existing tests
33
+ - Existing tests must continue to pass
34
+
35
+ ## Acceptance Criteria
36
+
37
+ - The bug no longer reproduces
38
+ - A regression test covers the failure case
39
+ - \`npx vitest run\` passes with no regressions
40
+ - \`npx tsc --noEmit\` passes
41
+
42
+ ## Risk Assessment
43
+
44
+ - <!-- What could go wrong with this fix? What's the blast radius? -->
45
+
46
+ ## Commands to Validate
47
+
48
+ - npx vitest run
49
+ - npx tsc --noEmit
50
+
51
+ ## Non-Goals
52
+
53
+ - <!-- What are you explicitly NOT fixing in this milestone? -->
54
+ `,
55
+ feature: `# Spec: <!-- Title: Add [feature name] -->
56
+
57
+ ## Context
58
+
59
+ <!-- Why does this feature need to exist? What problem does it solve? -->
60
+
61
+ ## Objective
62
+
63
+ <!-- One sentence: what new capability will exist after this ships? -->
64
+
65
+ Task Count: <!-- Exactly N tasks. -->
66
+
67
+ ## Requirements
68
+
69
+ ### T1: <!-- Core implementation -->
70
+
71
+ <!-- Describe what to build. Include:
72
+ - New files to create
73
+ - Existing files to modify
74
+ - Key interfaces/functions
75
+ - Behavior specification
76
+ -->
77
+
78
+ New file: <!-- e.g. src/new-feature.ts -->
79
+ Modified file: <!-- e.g. src/cli.ts -->
80
+
81
+ ### T2: <!-- Tests -->
82
+
83
+ <!-- Describe test coverage needed. -->
84
+
85
+ New file: <!-- e.g. tests/new-feature.test.ts -->
86
+
87
+ ## Constraints
88
+
89
+ - <!-- Boundaries: what this feature should NOT do -->
90
+ - Existing tests must continue to pass
91
+
92
+ ## Acceptance Criteria
93
+
94
+ - <!-- Concrete observable outcomes, one per bullet -->
95
+ - \`npx vitest run\` passes with no regressions
96
+ - \`npx tsc --noEmit\` passes
97
+
98
+ ## Risk Assessment
99
+
100
+ - <!-- What could go wrong? How is it mitigated? -->
101
+
102
+ ## Commands to Validate
103
+
104
+ - npx vitest run
105
+ - npx tsc --noEmit
106
+
107
+ ## Non-Goals
108
+
109
+ - <!-- What's explicitly out of scope? -->
110
+ `,
111
+ refactor: `# Spec: <!-- Title: Refactor [what] -->
112
+
113
+ ## Context
114
+
115
+ <!-- Why refactor now? What's the current pain point (duplication, complexity, performance)? -->
116
+
117
+ ## Objective
118
+
119
+ <!-- One sentence: what structural improvement will exist after this ships? Behavior must not change. -->
120
+
121
+ Task Count: <!-- Exactly N tasks. -->
122
+
123
+ ## Requirements
124
+
125
+ ### T1: <!-- Structural change -->
126
+
127
+ <!-- Describe the refactor. Include:
128
+ - Before: current structure
129
+ - After: target structure
130
+ - Invariants: what must remain true
131
+ -->
132
+
133
+ Modified file: <!-- e.g. src/foo.ts -->
134
+
135
+ ## Constraints
136
+
137
+ - **No behavior change** — all existing tests must pass without modification
138
+ - No new features or bug fixes bundled into the refactor
139
+ - Existing tests must continue to pass
140
+
141
+ ## Acceptance Criteria
142
+
143
+ - All existing tests pass without modification
144
+ - <!-- Structural goal achieved, e.g. "No function exceeds 50 lines" -->
145
+ - \`npx vitest run\` passes with no regressions
146
+ - \`npx tsc --noEmit\` passes
147
+
148
+ ## Risk Assessment
149
+
150
+ - <!-- What invariants could break? How do you verify they hold? -->
151
+
152
+ ## Commands to Validate
153
+
154
+ - npx vitest run
155
+ - npx tsc --noEmit
156
+
157
+ ## Non-Goals
158
+
159
+ - <!-- What cleanup are you NOT doing in this refactor? -->
160
+ `,
161
+ greenfield: `# Spec: <!-- Title: Scaffold [project name] -->
162
+
163
+ ## Tech Stack
164
+
165
+ - Language: <!-- e.g. TypeScript, Python, Go -->
166
+ - Framework: <!-- e.g. React, Express, FastAPI -->
167
+ - Package Manager: <!-- e.g. npm, pnpm, yarn, pip -->
168
+ - Test Runner: <!-- e.g. vitest, jest, pytest -->
169
+
170
+ ## Context
171
+
172
+ <!-- Why is this project being created from scratch? What need does it serve? -->
173
+
174
+ ## Objective
175
+
176
+ <!-- One sentence: what project will exist after scaffolding is complete? -->
177
+
178
+ ## Project Skeleton
179
+
180
+ <!-- Describe the directory structure. Example:
181
+ \\\`\\\`\\\`
182
+ ├── src/
183
+ │ ├── index.ts
184
+ │ └── ...
185
+ ├── tests/
186
+ ├── package.json
187
+ ├── tsconfig.json
188
+ └── ...
189
+ \\\`\\\`\\\`
190
+ -->
191
+
192
+ ## Requirements
193
+
194
+ ### T1: Scaffolding — create project, install dependencies, verify build
195
+
196
+ <!-- Set up the project from scratch. Include:
197
+ - Initialize the project (e.g. npm init, cargo init)
198
+ - Install core dependencies and dev dependencies
199
+ - Configure the build toolchain
200
+ - Verify the project compiles/builds and tests pass
201
+ -->
202
+
203
+ New files: <!-- e.g. package.json, tsconfig.json, src/index.ts -->
204
+
205
+ ## Constraints
206
+
207
+ - Project must build and pass tests after scaffolding
208
+ - No application logic beyond a minimal hello-world entry point
209
+
210
+ ## Acceptance Criteria
211
+
212
+ - \\\`<!-- test command, e.g. npm test, pytest, cargo test -->\\\` passes
213
+ - \\\`<!-- typecheck command, e.g. npx tsc --noEmit, mypy ., cargo check -->\\\` passes
214
+ - Project directory structure matches the skeleton above
215
+
216
+ ## Risk Assessment
217
+
218
+ - <!-- What could go wrong during scaffolding? Dependency conflicts, toolchain issues? -->
219
+
220
+ ## Commands to Validate
221
+
222
+ - <!-- test command matching the chosen stack -->
223
+ - <!-- typecheck/build command matching the chosen stack -->
224
+
225
+ ## Non-Goals
226
+
227
+ - <!-- What features or setup are explicitly NOT part of this scaffolding? -->
228
+ `,
229
+ cleanup: `# Spec: <!-- Title: Clean up [scope] -->
230
+
231
+ ## Context
232
+
233
+ <!-- What accumulated mess needs cleaning? Be specific about what and where. -->
234
+
235
+ ## Objective
236
+
237
+ <!-- One sentence: what will be cleaner after this ships? -->
238
+
239
+ Task Count: <!-- Exactly N tasks. -->
240
+
241
+ ## Requirements
242
+
243
+ ### T1: <!-- Cleanup scope -->
244
+
245
+ <!-- Describe exactly what to clean. Include:
246
+ - Which files
247
+ - What to remove/rename/consolidate
248
+ - Safety: how to verify nothing breaks
249
+ -->
250
+
251
+ Modified file: <!-- e.g. src/foo.ts -->
252
+
253
+ ## Constraints
254
+
255
+ - Each task must be independently verifiable
256
+ - No behavior changes unless explicitly noted
257
+ - Existing tests must continue to pass
258
+
259
+ ## Acceptance Criteria
260
+
261
+ - <!-- Concrete cleanup outcome per bullet -->
262
+ - \`npx vitest run\` passes with no regressions
263
+ - \`npx tsc --noEmit\` passes
264
+
265
+ ## Risk Assessment
266
+
267
+ - <!-- What could break during cleanup? What's the rollback plan? -->
268
+
269
+ ## Commands to Validate
270
+
271
+ - npx vitest run
272
+ - npx tsc --noEmit
273
+
274
+ ## Non-Goals
275
+
276
+ - <!-- What cleanup is explicitly NOT part of this milestone? -->
277
+ `,
278
+ };
279
+ export function getTemplate(name) {
280
+ return TEMPLATES[name] ?? null;
281
+ }
282
+ export function listTemplates() {
283
+ return Object.keys(TEMPLATES);
284
+ }
285
+ //# sourceMappingURL=spec-templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-templates.js","sourceRoot":"","sources":["../src/spec-templates.ts"],"names":[],"mappings":"AAAA,MAAM,SAAS,GAA2B;IACxC,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoDT;IAEC,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuDV;IAEC,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiDX;IAEC,UAAU,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmEb;IAEC,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgDV;CACA,CAAC;AAEF,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { ParsedSpec } from './types.js';
2
+ export interface SpecValidationResult {
3
+ valid: boolean;
4
+ spec: ParsedSpec | null;
5
+ errors: string[];
6
+ warnings: string[];
7
+ }
8
+ export declare function validateSpec(markdown: string): SpecValidationResult;
@@ -0,0 +1,144 @@
1
+ import { REQUIRED_SPEC_SECTIONS } from './types.js';
2
+ const WEAK_PLACEHOLDER_PATTERN = /\b(todo|tbd|later|various|misc|stuff|things|etc\.?|somehow|maybe|as needed)\b/i;
3
+ const BROAD_CLEANUP_PATTERN = /\b(clean\s*up|cleanup|refactor|polish|integrate|integration|wire\s*up|hook\s*up|finalize|general improvements?)\b/i;
4
+ const CATCH_ALL_VALIDATION_PATTERN = /\b(run\s+(all|full)\s+(tests|checks|validation)|validate\s+everything|full\s+validation|all\s+tests)\b/i;
5
+ const LOCAL_ONLY_COMMAND_PATTERN = /\b(cd|npm run|pnpm|yarn|node|npx|vitest|jest|tsc|pytest|go test|cargo test|mvn|gradle)\b/i;
6
+ const TASK_SHAPE_SPECIFICITY_PATTERN = /\b(file|files|command|test|api|function|module|component|task|migration|schema|endpoint|cli|script|validator|planner|assignment|graph)\b/i;
7
+ const TASK_SHAPE_AMBIGUITY_PATTERN = /\b(handle|support|improve|update|fix|adjust|address)\b/i;
8
+ const WEAK_ACCEPTANCE_CHECK_PATTERN = /\b(looks good|works as expected|verify manually|manual verification|sanity check|spot check)\b/i;
9
+ export function validateSpec(markdown) {
10
+ const errors = [];
11
+ const warnings = [];
12
+ const titleMatch = markdown.match(/^# Spec:\s*(.+?)\s*$/m);
13
+ const title = titleMatch?.[1]?.trim() ?? '';
14
+ const sections = parseSections(markdown);
15
+ if (!title) {
16
+ errors.push('Missing required title: # Spec: <title>');
17
+ }
18
+ for (const sectionName of REQUIRED_SPEC_SECTIONS) {
19
+ if (!sections.get(sectionName)) {
20
+ errors.push(`Missing required section: ${sectionName}`);
21
+ }
22
+ }
23
+ if (errors.length > 0) {
24
+ return { valid: false, spec: null, errors, warnings: [] };
25
+ }
26
+ const spec = {
27
+ title,
28
+ objective: sections.get('Objective') ?? '',
29
+ context: sections.get('Context') ?? '',
30
+ requirements: sections.get('Requirements') ?? '',
31
+ constraints: sections.get('Constraints') ?? '',
32
+ acceptance_criteria: sections.get('Acceptance Criteria') ?? '',
33
+ risk_assessment: sections.get('Risk Assessment') ?? '',
34
+ ...optionalField('target_files', sections.get('Target Files')),
35
+ ...optionalField('non_goals', sections.get('Non-Goals')),
36
+ ...optionalField('notes_for_reviewer', sections.get('Notes for Reviewer')),
37
+ ...optionalField('commands_to_validate', sections.get('Commands to Validate')),
38
+ };
39
+ warnings.push(...collectSpecWarnings(spec));
40
+ return {
41
+ valid: true,
42
+ spec,
43
+ errors: [],
44
+ warnings,
45
+ };
46
+ }
47
+ function collectSpecWarnings(spec) {
48
+ const warnings = [];
49
+ if (isWeakAcceptanceCriteria(spec.acceptance_criteria)) {
50
+ warnings.push('Acceptance Criteria appear weak or underspecified; include concrete expected outcomes.');
51
+ }
52
+ if (isAmbiguousTaskShape(spec.requirements, spec.objective)) {
53
+ warnings.push('Requirements/objective are ambiguous about the task shape; prefer explicit deliverables and boundaries.');
54
+ }
55
+ if (isBroadCleanupOrIntegration(spec.requirements, spec.objective)) {
56
+ warnings.push('Spec appears to describe broad cleanup/integration work; split into narrower, independently verifiable changes.');
57
+ }
58
+ if (hasWeakAcceptanceChecks(spec.acceptance_criteria)) {
59
+ warnings.push('Acceptance Criteria rely on weak checks like vague manual verification; prefer precise commands or observable outcomes.');
60
+ }
61
+ if (hasCatchAllValidation(spec.acceptance_criteria)) {
62
+ warnings.push('Acceptance Criteria include catch-all validation phrasing; enumerate the specific checks that matter.');
63
+ }
64
+ if (hasLocalOnlyCommandValidationGap(spec.commands_to_validate, spec.acceptance_criteria)) {
65
+ warnings.push('Commands to Validate is missing or weak for a spec that implies command-based validation; list local runnable commands.');
66
+ }
67
+ return warnings;
68
+ }
69
+ function isWeakAcceptanceCriteria(value) {
70
+ const lines = toMeaningfulLines(value);
71
+ if (lines.length === 0) {
72
+ return true;
73
+ }
74
+ if (lines.length < 3 && value.trim().length < 120) {
75
+ return true;
76
+ }
77
+ return (lines.some((line) => WEAK_PLACEHOLDER_PATTERN.test(line))
78
+ || hasWeakAcceptanceChecks(value)
79
+ || hasCatchAllValidation(value));
80
+ }
81
+ function isAmbiguousTaskShape(requirements, objective) {
82
+ const combined = `${objective}\n${requirements}`;
83
+ const lines = toMeaningfulLines(combined);
84
+ if (lines.length === 0) {
85
+ return true;
86
+ }
87
+ const lacksSpecificity = !TASK_SHAPE_SPECIFICITY_PATTERN.test(combined);
88
+ const hasAmbiguousWords = TASK_SHAPE_AMBIGUITY_PATTERN.test(combined);
89
+ return lacksSpecificity && hasAmbiguousWords;
90
+ }
91
+ function isBroadCleanupOrIntegration(requirements, objective) {
92
+ const combined = `${objective}\n${requirements}`;
93
+ return BROAD_CLEANUP_PATTERN.test(combined) && !/\b(single|specific|only|exact|limited)\b/i.test(combined);
94
+ }
95
+ function hasWeakAcceptanceChecks(value) {
96
+ return WEAK_ACCEPTANCE_CHECK_PATTERN.test(value);
97
+ }
98
+ function hasCatchAllValidation(value) {
99
+ return CATCH_ALL_VALIDATION_PATTERN.test(value);
100
+ }
101
+ function hasLocalOnlyCommandValidationGap(commandsToValidate, acceptanceCriteria) {
102
+ const impliesCommands = LOCAL_ONLY_COMMAND_PATTERN.test(acceptanceCriteria);
103
+ if (!impliesCommands) {
104
+ return false;
105
+ }
106
+ if (!commandsToValidate || toMeaningfulLines(commandsToValidate).length === 0) {
107
+ return true;
108
+ }
109
+ return !LOCAL_ONLY_COMMAND_PATTERN.test(commandsToValidate);
110
+ }
111
+ function toMeaningfulLines(value) {
112
+ return value
113
+ .split('\n')
114
+ .map((line) => line.replace(/^[-*]\s*/, '').trim())
115
+ .filter((line) => line.length > 0);
116
+ }
117
+ function parseSections(markdown) {
118
+ const sections = new Map();
119
+ const headingRegex = /^##\s+(.+?)\s*$/gm;
120
+ const headings = [];
121
+ let match;
122
+ while ((match = headingRegex.exec(markdown)) !== null) {
123
+ headings.push({
124
+ name: match[1].trim(),
125
+ contentStart: headingRegex.lastIndex,
126
+ headingStart: match.index,
127
+ });
128
+ }
129
+ for (let index = 0; index < headings.length; index += 1) {
130
+ const current = headings[index];
131
+ const next = headings[index + 1];
132
+ const contentEnd = next?.headingStart ?? markdown.length;
133
+ const value = markdown.slice(current.contentStart, contentEnd).trim();
134
+ sections.set(current.name, value);
135
+ }
136
+ return sections;
137
+ }
138
+ function optionalField(key, value) {
139
+ if (!value) {
140
+ return {};
141
+ }
142
+ return { [key]: value };
143
+ }
144
+ //# sourceMappingURL=spec-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-validator.js","sourceRoot":"","sources":["../src/spec-validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ import type { RunManifest, RunState, TaskState, TaskStateRecord, TaskStatus } from './types.js';
2
+ import type { EscalationCategory, RunEvent, RunEventsArtifact, RunMetricsArtifact } from './run-artifact-types.js';
3
+ export declare function writeTaskStatus(stwRoot: string, runId: string, taskId: string, input: {
4
+ agent_id: string;
5
+ status: TaskStatus['status'];
6
+ notes: string;
7
+ question_number?: number;
8
+ preserved_worktree_path?: string;
9
+ preserved_worktree_paths?: string[];
10
+ stop_reason?: string;
11
+ stopped_at?: string;
12
+ stopped_by?: string;
13
+ execution_mode?: TaskStatus['execution_mode'];
14
+ failure_class?: TaskStatus['failure_class'];
15
+ }): TaskStatus;
16
+ export declare function readTaskStatus(stwRoot: string, runId: string, taskId: string): TaskStatus | null;
17
+ export declare function writeTaskState(stwRoot: string, runId: string, taskId: string, state: TaskState, updatedBy: string): TaskStateRecord;
18
+ export declare function writeRunState(stwRoot: string, runId: string, state: RunState, options?: {
19
+ pause_reason?: string;
20
+ drift_detected?: boolean;
21
+ }): RunManifest;
22
+ export declare function readRunStatus(stwRoot: string, runId: string, taskIds: string[]): Record<string, TaskStatus['status'] | 'pending'>;
23
+ export interface StaleTaskReport {
24
+ taskId: string;
25
+ taskStatus: TaskStatus;
26
+ taskState: TaskStateRecord | null;
27
+ }
28
+ export interface RunRecoveryReport {
29
+ manifest: RunManifest;
30
+ stale: boolean;
31
+ reason: 'none' | 'stale_lock' | 'persisted_in_progress_without_live_lock';
32
+ staleTasks: StaleTaskReport[];
33
+ guidance: string[];
34
+ }
35
+ export declare function readTaskState(stwRoot: string, runId: string, taskId: string): TaskStateRecord | null;
36
+ export declare function buildRunRecoveryReport(stwRoot: string, runId: string, taskIds: string[]): RunRecoveryReport;
37
+ export declare function readRunEvents(stwRoot: string, runId: string): RunEventsArtifact;
38
+ export declare function recordRunEvent(stwRoot: string, runId: string, input: {
39
+ event_type: RunEvent['event_type'];
40
+ actor: string;
41
+ task_id?: string;
42
+ summary: string;
43
+ details?: string;
44
+ escalation_category?: EscalationCategory;
45
+ metadata?: Record<string, string | number | boolean | null>;
46
+ }): RunEvent;
47
+ export declare function readRunMetrics(stwRoot: string, runId: string): RunMetricsArtifact | null;
48
+ export declare function writeRunMetrics(stwRoot: string, runId: string, input: Omit<RunMetricsArtifact, 'schema_version' | 'run_id' | 'updated_at'>): RunMetricsArtifact;
49
+ export declare function resetTaskToPending(stwRoot: string, runId: string, taskId: string): void;
50
+ export declare function markTaskSkipped(stwRoot: string, runId: string, taskId: string, reason: string): void;
51
+ export declare function markTaskComplete(stwRoot: string, runId: string, taskId: string): void;
52
+ export interface StatusData {
53
+ runId: string;
54
+ manifest: RunManifest;
55
+ tasks: Array<{
56
+ id: string;
57
+ description: string;
58
+ task_type: string;
59
+ state: string;
60
+ status: string | null;
61
+ agent_id: string | null;
62
+ notes: string | null;
63
+ completed_at: string | null;
64
+ cost_usd: number | null;
65
+ }>;
66
+ total_cost_usd: number;
67
+ }
68
+ export declare function getStatusData(stwRoot: string, runId: string): StatusData;