@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
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 mknightz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,277 @@
1
+ # stw
2
+
3
+ **Spec-to-Workers** (pronounced "stew") — a CLI orchestrator that turns markdown specs into reviewed, merge-ready code changes using AI agents.
4
+
5
+ You write a spec (or describe an idea), STW decomposes it into isolated tasks, routes each to an AI worker, validates the output, and produces a merge request with all changes.
6
+
7
+ ## How it works
8
+
9
+ ```
10
+ spec.md ──> planner ──> task graph ──> workers ──> review ──> MR
11
+ T1 ──────> worker ──> validate ──┐
12
+ T2 ──────> worker ──> validate ──┤
13
+ T3 (dep: T1) ─> worker ─> validate ┘
14
+ ```
15
+
16
+ 1. **Ingest** — validates your spec and creates a run
17
+ 2. **Plan** — an AI planner decomposes the spec into a task graph with scopes, dependencies, and acceptance checks
18
+ 3. **Run** — workers execute tasks in dependency order, each in an isolated git worktree
19
+ 4. **Review** — mechanical checks (tests, typecheck, scope) + optional LLM review
20
+ 5. **Retry** — failed tasks get diagnostic context and retry with tier escalation
21
+ 6. **Merge** — completed work is pushed and synced as a GitLab/GitHub MR
22
+
23
+ ## Quick start
24
+
25
+ ### 1. Install
26
+
27
+ ```bash
28
+ npm install -g stw
29
+ ```
30
+
31
+ ### 2. Prerequisites
32
+
33
+ STW needs an API provider for AI models and (optionally) an agentic backend for complex tasks.
34
+
35
+ **API provider** (required): An OpenAI-compatible API endpoint. [OpenRouter](https://openrouter.ai) works out of the box and gives access to multiple model families.
36
+
37
+ **Agentic backend** (optional, recommended): Either [OpenCode](https://github.com/opencode-ai/opencode) or [Claude Code](https://docs.anthropic.com/en/docs/claude-code) for tasks that need iterative exploration (read-edit-test loops).
38
+
39
+ ### 3. Initialize
40
+
41
+ ```bash
42
+ cd your-repo
43
+ stw init
44
+ ```
45
+
46
+ This creates `.stw/config.yml` with model routing, budget limits, and backend settings. Default preset is `minimax` (balanced cost/quality). Other presets: `glm5` (budget), `anthropic` (premium), `mixed` (multi-provider).
47
+
48
+ Set your API key:
49
+ ```bash
50
+ export OPENROUTER_API_KEY="sk-or-..."
51
+ ```
52
+
53
+ ### 4. Check readiness
54
+
55
+ ```bash
56
+ stw doctor
57
+ ```
58
+
59
+ Verifies: API keys are set, agentic backends are installed, config is valid.
60
+
61
+ ### 5. Create a spec
62
+
63
+ Write a markdown spec describing what you want built:
64
+
65
+ ```markdown
66
+ # Spec: Add rate limiting to API endpoints
67
+
68
+ ## Objective
69
+ Add configurable rate limiting to all public API endpoints.
70
+
71
+ ## Requirements
72
+
73
+ ### T1: Rate limiter middleware
74
+ Create a rate limiting middleware in src/middleware/rate-limit.ts.
75
+ - Accept requests-per-minute and burst-size as parameters
76
+ - Use a sliding window algorithm
77
+ - Return 429 with Retry-After header when exceeded
78
+
79
+ ### T2: Apply middleware to routes
80
+ Wire the rate limiter into src/routes/api.ts for all public endpoints.
81
+ - Default: 60 requests/minute, burst of 10
82
+ - Make limits configurable via environment variables
83
+
84
+ ## Constraints
85
+ - No external dependencies (use in-memory store)
86
+ - Must not break existing tests
87
+ ```
88
+
89
+ Save it as `specs/rate-limiting.md`.
90
+
91
+ ### 6. Run
92
+
93
+ ```bash
94
+ # Ingest the spec and create a run
95
+ stw ingest specs/rate-limiting.md
96
+
97
+ # Auto-plan tasks (or provide your own task graph)
98
+ stw plan-auto <run-id>
99
+
100
+ # Execute all tasks
101
+ stw run <run-id>
102
+
103
+ # Check progress
104
+ stw progress <run-id>
105
+
106
+ # Push to GitLab/GitHub
107
+ stw merge <run-id>
108
+ ```
109
+
110
+ Or use the shortcut that does ingest + plan + run in one command:
111
+
112
+ ```bash
113
+ stw go "add rate limiting to API endpoints" --spec specs/rate-limiting.md
114
+ ```
115
+
116
+ Or skip the spec entirely — just describe what you want:
117
+
118
+ ```bash
119
+ stw go "add dark mode toggle to the settings page"
120
+ ```
121
+
122
+ STW generates a structured spec from your rough idea, plans tasks, and executes them.
123
+
124
+ ## Configuration
125
+
126
+ STW uses `.stw/config.yml` in your repo root. Key sections:
127
+
128
+ ```yaml
129
+ # API providers — where to send model requests
130
+ providers:
131
+ openrouter:
132
+ api_key_env: OPENROUTER_API_KEY # env var name (not the key itself)
133
+ base_url: https://openrouter.ai/api/v1
134
+ models:
135
+ strong: anthropic/claude-sonnet-4 # for planning, review, complex tasks
136
+ medium: openai/gpt-4.1-mini # for moderate tasks
137
+ cheap: google/gemini-2.5-flash # for mechanical/simple tasks
138
+
139
+ # How tasks are routed to providers
140
+ routing_policy:
141
+ require_plan_approval: true # require human approval before execution
142
+ provider_preferences:
143
+ strong: [openrouter]
144
+ medium: [openrouter]
145
+ cheap: [openrouter]
146
+
147
+ # Execution defaults
148
+ defaults:
149
+ max_retries: 2 # retries per task before escalation
150
+ max_concurrent_workers: 2 # parallel task execution
151
+ task_timeout_minutes: 30
152
+ api_timeout_seconds: 120
153
+ execution_mode: agentic # 'agentic' or 'conservative'
154
+
155
+ # Agentic backend config (for iterative task execution)
156
+ agentic:
157
+ default_backend: opencode # 'opencode' or 'claude-code'
158
+ backends:
159
+ opencode:
160
+ command: opencode # path to opencode binary
161
+ claude-code:
162
+ command: claude # path to claude binary
163
+
164
+ # Optional: per-run budget limits
165
+ budget:
166
+ max_run_usd: 5.00
167
+ warn_at_usd: 3.00
168
+ ```
169
+
170
+ ### Model tiers
171
+
172
+ STW routes tasks to models based on complexity:
173
+
174
+ | Tier | Use case | Example models |
175
+ |------|----------|----------------|
176
+ | **cheap** | Mechanical refactors, simple edits | gemini-2.5-flash, minimax-m2.5 |
177
+ | **medium** | Moderate reasoning, test writing | gpt-4.1-mini, minimax-m2.7 |
178
+ | **strong** | Planning, review, complex logic | claude-sonnet-4, kimi-k2.5 |
179
+
180
+ The planner assigns tiers automatically. If a task fails, STW escalates to the next tier and retries.
181
+
182
+ ## Architecture
183
+
184
+ ```
185
+ src/
186
+ cli.ts # Command-line interface (commander.js)
187
+ planner.ts # AI planner — decomposes specs into task graphs
188
+ planner-prompt.ts # Planner prompt construction + import graph
189
+ task-executor.ts # Task execution pipeline (worker → review → retry)
190
+ worker-runner.ts # Worker dispatch (single-call API or agentic subprocess)
191
+ task-review.ts # Mechanical review + LLM review phase
192
+ validation.ts # Acceptance check execution (tests, typecheck)
193
+ router.ts # Model tier routing with escalation
194
+ provider.ts # OpenAI-compatible API client
195
+ agentic-runtime.ts # Agentic backend subprocess management
196
+ parallel.ts # Parallel task execution + merge-back
197
+ scope.ts # Scope enforcement (which files a task can touch)
198
+ cost.ts # Cost tracking and budget enforcement
199
+ config.ts # Config loading and validation
200
+ git-utils.ts # Git operations (worktrees, diffs, merges)
201
+
202
+ tests/ # 1100+ tests (vitest)
203
+ specs/ # Spec files (input)
204
+ .stw/ # Runtime state (runs, tasks, artifacts)
205
+ config.yml # Project configuration
206
+ runs/ # Per-run state and artifacts
207
+ <run-id>/
208
+ manifest.json # Run metadata
209
+ tasks/
210
+ T1/ # Per-task artifacts
211
+ status.json
212
+ diff.patch
213
+ worker_prompt.md
214
+ response.json
215
+ ```
216
+
217
+ ## CLI commands
218
+
219
+ | Command | Description |
220
+ |---------|-------------|
221
+ | `stw init` | Initialize repo with `.stw/config.yml` |
222
+ | `stw idea <description>` | Generate a spec from a rough idea |
223
+ | `stw ingest <spec>` | Validate spec and create a run |
224
+ | `stw plan-auto <run-id>` | AI-generate task graph from spec |
225
+ | `stw run <run-id>` | Execute all tasks in dependency order |
226
+ | `stw go <spec>` | Ingest + plan + run in one command |
227
+ | `stw progress <run-id>` | Show run progress and task status |
228
+ | `stw status <run-id>` | Detailed run/task status |
229
+ | `stw retry <run-id> <task-id>` | Retry a failed/escalated task |
230
+ | `stw resume <run-id>` | Resume from last checkpoint |
231
+ | `stw stop <run-id>` | Pause a running run |
232
+ | `stw continue <run-id>` | Resume a paused run |
233
+ | `stw merge <run-id>` | Push and create MR |
234
+ | `stw doctor` | Check local readiness |
235
+ | `stw cleanup [run-id]` | Clean up old runs/worktrees |
236
+ | `stw logs <run-id>` | View structured logs |
237
+
238
+ ## How tasks execute
239
+
240
+ Each task runs in an isolated git worktree branched from the run branch:
241
+
242
+ 1. **Worktree created** — fresh copy of the codebase
243
+ 2. **Dependencies installed** — `npm ci` if `package-lock.json` exists
244
+ 3. **Worker executes** — either a single API call (fast, cheap) or an agentic session (iterative, higher quality)
245
+ 4. **Scope enforced** — worker output is checked against declared scope files
246
+ 5. **Acceptance checks run** — tests, typecheck, linter (configured per task)
247
+ 6. **LLM review** (optional) — a reviewer model checks the diff
248
+ 7. **On failure** — diagnostic context is captured, task retries with the previous attempt's errors
249
+ 8. **On exhausted retries** — tier escalates (cheap → medium → strong), or task is marked escalated for human review
250
+ 9. **On success** — changes merge back to the run branch
251
+
252
+ ## Troubleshooting
253
+
254
+ **"No models configured for requested tier"** — Your `.stw/config.yml` is missing model entries for the tier the planner assigned. Add models to your provider's `models` section or adjust the preset.
255
+
256
+ **"Planner received null content"** — The planner model returned empty output. This happens with some reasoning models when `max_tokens` is too low. Try a different model or increase `api_timeout_seconds`.
257
+
258
+ **Task keeps escalating** — Check `.stw/runs/<run-id>/tasks/<task-id>/diagnostic.json` for the failure reason. Common causes: acceptance checks reference non-existent files, scope is too narrow (missing caller files), or the spec is ambiguous.
259
+
260
+ **"Agentic backend failed"** — The agentic backend (opencode/claude) crashed or timed out. Run `stw doctor` to verify it's installed. Check `agentic_transcript.txt` in the task directory for details.
261
+
262
+ **Budget exceeded** — Run `stw progress <run-id>` to see cost breakdown. Adjust `budget.max_run_usd` in config or use `stw continue <run-id>` to resume with remaining budget.
263
+
264
+ ## Development
265
+
266
+ ```bash
267
+ git clone https://gitlab.com/mygelknightz/mamarracho.git stw
268
+ cd stw
269
+ npm install
270
+ npm test # run all tests
271
+ npm run lint # eslint + tsc
272
+ npm run build # compile TypeScript
273
+ ```
274
+
275
+ ## License
276
+
277
+ MIT
@@ -0,0 +1,3 @@
1
+ import type { StwConfig, Task } from './types.js';
2
+ export declare function shouldFallbackToAgentic(task: Task, config: StwConfig): boolean;
3
+ export declare function buildAgenticFallbackTask(task: Task, config: StwConfig): Task;
@@ -0,0 +1,32 @@
1
+ export function shouldFallbackToAgentic(task, config) {
2
+ // If already agentic, no need to fallback
3
+ if (task.planner_metadata?.execution_mode === 'agentic') {
4
+ return false;
5
+ }
6
+ const fallback = config.defaults.agentic_fallback;
7
+ if (!fallback?.enabled) {
8
+ return false;
9
+ }
10
+ // If task_types is empty or undefined, all task types are eligible
11
+ // Only filter if task_types is explicitly provided with items
12
+ if (fallback.task_types && fallback.task_types.length > 0 && !fallback.task_types.includes(task.task_type)) {
13
+ return false;
14
+ }
15
+ // Filter by risk levels if specified
16
+ if (fallback.risk_levels && fallback.risk_levels.length > 0 && !fallback.risk_levels.includes(task.risk)) {
17
+ return false;
18
+ }
19
+ return true;
20
+ }
21
+ export function buildAgenticFallbackTask(task, config) {
22
+ return {
23
+ ...task,
24
+ planner_metadata: {
25
+ ...task.planner_metadata,
26
+ execution_mode: 'agentic',
27
+ agentic_backend: task.planner_metadata?.agentic_backend ?? config.defaults.agentic?.default_backend,
28
+ fallback_to_single_call: true,
29
+ },
30
+ };
31
+ }
32
+ //# sourceMappingURL=agentic-fallback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentic-fallback.js","sourceRoot":"","sources":["../src/agentic-fallback.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,uBAAuB,CAAC,IAAU,EAAE,MAAiB;IACnE,0CAA0C;IAC1C,IAAI,IAAI,CAAC,gBAAgB,EAAE,cAAc,KAAK,SAAS,EAAE,CAAC;QACxD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC;IAClD,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,mEAAmE;IACnE,8DAA8D;IAC9D,IAAI,QAAQ,CAAC,UAAU,IAAI,QAAQ,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3G,OAAO,KAAK,CAAC;IACf,CAAC;IAED,qCAAqC;IACrC,IAAI,QAAQ,CAAC,WAAW,IAAI,QAAQ,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACzG,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,IAAU,EAAE,MAAiB;IACpE,OAAO;QACL,GAAG,IAAI;QACP,gBAAgB,EAAE;YAChB,GAAG,IAAI,CAAC,gBAAgB;YACxB,cAAc,EAAE,SAAS;YACzB,eAAe,EAAE,IAAI,CAAC,gBAAgB,EAAE,eAAe,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,eAAe;YACnG,uBAAuB,EAAE,IAAI;SAC9B;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { type BuildWorkerPromptOptions } from './prompt-builder.js';
2
+ export declare function buildAgenticPrompt(options: BuildWorkerPromptOptions): string;
@@ -0,0 +1,68 @@
1
+ import { join } from 'node:path';
2
+ import { writeAtomic } from './storage.js';
3
+ import { buildRetryContext, gatherTaskContext, getSpecContext, renderContextFiles, renderList, withResolvedQuestionAnswers, } from './prompt-builder.js';
4
+ export function buildAgenticPrompt(options) {
5
+ const resolvedOptions = withResolvedQuestionAnswers(options);
6
+ const contextFiles = gatherTaskContext(resolvedOptions.repoRoot, resolvedOptions.task.scope.files);
7
+ const prompt = renderAgenticPrompt(resolvedOptions, contextFiles);
8
+ writeAtomic(join(resolvedOptions.taskDir, 'agentic_prompt.md'), prompt + '\n');
9
+ return prompt;
10
+ }
11
+ function renderAgenticPrompt(options, contextFiles) {
12
+ const specContext = getSpecContext(options.repoRoot, options.task.spec_path, options.task.id);
13
+ const specSection = specContext ? ['', '## Spec Context', '', specContext] : [];
14
+ const questionAnswers = options.questionAnswers
15
+ ? Object.entries(options.questionAnswers)
16
+ .map(([questionNumber, answer]) => [Number(questionNumber), answer])
17
+ .sort((left, right) => left[0] - right[0])
18
+ : [];
19
+ const persistedAnswers = questionAnswers.length > 0
20
+ ? [
21
+ '',
22
+ '## Persisted Human Answers',
23
+ 'The following answers have been provided to previous questions:',
24
+ ...questionAnswers.map(([num, answer]) => `- Question ${num}: ${answer}`),
25
+ ]
26
+ : [];
27
+ const retryContext = options.retryReason
28
+ ? ['', buildRetryContext(options.taskDir, options.retryReason, options.retryContextLevel ?? 'full')]
29
+ : [];
30
+ return [
31
+ 'You are the worker for one Spec-to-Workers task running in agentic mode.',
32
+ `Task ID: ${options.task.id}`,
33
+ `Task Description: ${options.task.description}`,
34
+ '',
35
+ 'You are executing directly inside the task worktree.',
36
+ 'Edit files in place only within the declared task scope.',
37
+ 'Do not return a structured JSON file-response artifact.',
38
+ 'Your job is to mutate the worktree directly and leave the final state ready for validation.',
39
+ '',
40
+ 'Allowed file scope:',
41
+ renderList(options.task.scope.files),
42
+ '',
43
+ 'Prohibited areas:',
44
+ '- Any file not explicitly listed in the allowed file scope',
45
+ '- Supporting context files included below are read-only unless they are also in scope',
46
+ '',
47
+ 'Success conditions:',
48
+ '- The resulting worktree changes stay within declared scope',
49
+ '- Acceptance checks should pass after your edits',
50
+ '- Leave the worktree in a reviewable state',
51
+ '',
52
+ 'Code conventions:',
53
+ '- TypeScript with ESM modules: use .js extensions in relative imports (e.g., import { foo } from "./bar.js")',
54
+ '- Follow the patterns shown in the repository context files below',
55
+ '',
56
+ 'Acceptance checks:',
57
+ renderList(options.task.acceptance_checks),
58
+ ...retryContext,
59
+ ...persistedAnswers,
60
+ ...specSection,
61
+ '',
62
+ 'Repository context:',
63
+ renderContextFiles(contextFiles),
64
+ ]
65
+ .flat()
66
+ .join('\n');
67
+ }
68
+ //# sourceMappingURL=agentic-prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentic-prompt.js","sourceRoot":"","sources":["../src/agentic-prompt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import type { AgenticBackend, AgenticBackendConfig } from './agentic-types.js';
2
+ import type { ActionableFailureClass, ExecutionObservabilityMode, StwConfig, Task } from './types.js';
3
+ export interface AgenticRunArtifact {
4
+ schema_version: 1;
5
+ task_id: string;
6
+ backend: AgenticBackend;
7
+ command: string[];
8
+ transcript_path: string;
9
+ summary_path: string;
10
+ changed_files: string[];
11
+ acceptance_checks_executed: boolean;
12
+ fallback_used: boolean;
13
+ exit_code: number;
14
+ model?: string;
15
+ execution_mode: ExecutionObservabilityMode;
16
+ failure_class?: ActionableFailureClass;
17
+ }
18
+ export declare function buildAgenticCommand(backend: AgenticBackend, prompt: string, promptPath: string, commandOverride?: string[], modelOverride?: string): string[];
19
+ export declare function formatBackendTranscript(backend: AgenticBackend, transcript: string, backendConfig?: AgenticBackendConfig): string;
20
+ export declare function getTaskExecutionObservabilityMode(task: Task): ExecutionObservabilityMode;
21
+ export declare function persistAgenticArtifacts(taskDir: string, input: {
22
+ task: Task;
23
+ backend: AgenticBackend;
24
+ command: string[];
25
+ transcript: string;
26
+ changedFiles: string[];
27
+ exitCode: number;
28
+ model?: string;
29
+ failureClass?: ActionableFailureClass;
30
+ }): void;
31
+ export declare function listChangedFiles(output: string, toRelativePath: (filePath: string) => string): string[];
32
+ export declare function resolveAgenticTierSelection(task: Task, config: StwConfig): {
33
+ backend: AgenticBackend;
34
+ model?: string;
35
+ };
36
+ export interface AgenticUsage {
37
+ input_tokens: number;
38
+ output_tokens: number;
39
+ cost_usd: number;
40
+ steps: number;
41
+ }
42
+ /**
43
+ * Parses JSONL output from an agentic backend (opencode --format json or claude-code --output-format json)
44
+ * and sums token usage and cost from all step_finish events.
45
+ *
46
+ * Returns null if no step_finish events are found (e.g. plain text output).
47
+ */
48
+ export declare function parseAgenticUsage(output: string): AgenticUsage | null;
@@ -0,0 +1,149 @@
1
+ import { join } from 'node:path';
2
+ import { writeAtomic, writeJson } from './storage.js';
3
+ export function buildAgenticCommand(backend, prompt, promptPath, commandOverride, modelOverride) {
4
+ if (backend === 'opencode') {
5
+ const base = commandOverride && commandOverride.length > 0 ? [commandOverride[0] ?? 'opencode'] : ['opencode'];
6
+ if (modelOverride && !base.includes('-m') && !base.includes('--model')) {
7
+ base.push('-m', modelOverride);
8
+ }
9
+ base.push('run', '--format', 'json');
10
+ return [...base, 'Follow the attached task contract exactly.', '-f', promptPath];
11
+ }
12
+ const claudeBase = commandOverride && commandOverride.length > 0 ? [...commandOverride] : ['claude'];
13
+ if (modelOverride && !claudeBase.includes('--model')) {
14
+ claudeBase.push('--model', modelOverride);
15
+ }
16
+ if (!claudeBase.includes('-p')) {
17
+ claudeBase.push('-p');
18
+ }
19
+ // Restrict Claude Code to safe tools only (no Agent spawning inside worker tasks)
20
+ if (!claudeBase.includes('--allowedTools')) {
21
+ claudeBase.push('--allowedTools', 'Edit,Write,Read,Bash,Glob,Grep');
22
+ }
23
+ // Request JSON output for structured transcript parsing
24
+ if (!claudeBase.includes('--output-format')) {
25
+ claudeBase.push('--output-format', 'json');
26
+ }
27
+ if (commandOverride && commandOverride.length > 0) {
28
+ return [...claudeBase, prompt];
29
+ }
30
+ switch (backend) {
31
+ case 'claude-code':
32
+ return [...claudeBase, prompt];
33
+ }
34
+ }
35
+ export function formatBackendTranscript(backend, transcript, backendConfig) {
36
+ const defaultFormat = backend === 'opencode' ? 'jsonl' : 'plain';
37
+ const format = backendConfig?.transcript_format ?? defaultFormat;
38
+ const header = backend === 'opencode'
39
+ ? format === 'jsonl'
40
+ ? '[opencode transcript: jsonl]'
41
+ : '[opencode transcript]'
42
+ : format === 'jsonl'
43
+ ? '[claude-code transcript: jsonl]'
44
+ : '[claude-code transcript]';
45
+ return `${header}\n${transcript}`.trim() + '\n';
46
+ }
47
+ export function getTaskExecutionObservabilityMode(task) {
48
+ if (task.planner_metadata?.execution_mode === 'agentic') {
49
+ return task.planner_metadata?.fallback_to_single_call === true ? 'fallback_to_agentic' : 'direct_agentic';
50
+ }
51
+ return 'conservative_only';
52
+ }
53
+ export function persistAgenticArtifacts(taskDir, input) {
54
+ const transcriptPath = join(taskDir, 'agentic_transcript.txt');
55
+ const summaryPath = join(taskDir, 'agentic_summary.json');
56
+ const executionMode = getTaskExecutionObservabilityMode(input.task);
57
+ writeAtomic(transcriptPath, input.transcript);
58
+ const summary = {
59
+ schema_version: 1,
60
+ task_id: input.task.id,
61
+ backend: input.backend,
62
+ command: input.command,
63
+ changed_files: input.changedFiles,
64
+ acceptance_checks_executed: false,
65
+ fallback_used: input.task.planner_metadata?.fallback_to_single_call === true,
66
+ transcript_preview: input.transcript.slice(0, 500),
67
+ execution_mode: executionMode,
68
+ failure_class: input.failureClass,
69
+ };
70
+ writeJson(summaryPath, summary);
71
+ const artifact = {
72
+ schema_version: 1,
73
+ task_id: input.task.id,
74
+ backend: input.backend,
75
+ command: input.command,
76
+ transcript_path: transcriptPath,
77
+ summary_path: summaryPath,
78
+ changed_files: input.changedFiles,
79
+ acceptance_checks_executed: false,
80
+ fallback_used: input.task.planner_metadata?.fallback_to_single_call === true,
81
+ exit_code: input.exitCode,
82
+ model: input.model,
83
+ execution_mode: executionMode,
84
+ failure_class: input.failureClass,
85
+ };
86
+ writeJson(join(taskDir, 'agentic_run.json'), artifact);
87
+ }
88
+ export function listChangedFiles(output, toRelativePath) {
89
+ return output
90
+ .split('\n')
91
+ .filter((line) => line.trim().length > 0)
92
+ .map((line) => line.slice(3).trim())
93
+ .map((filePath) => toRelativePath(filePath));
94
+ }
95
+ export function resolveAgenticTierSelection(task, config) {
96
+ const tierSelection = config.defaults.agentic?.tiers?.[task.model_tier];
97
+ const backend = task.planner_metadata?.agentic_backend ?? tierSelection?.backend ?? config.defaults.agentic?.default_backend;
98
+ if (!backend) {
99
+ throw new Error('Agentic execution requested but no agentic backend is configured on planner_metadata, defaults.agentic.tiers, or defaults.agentic.default_backend');
100
+ }
101
+ const model = tierSelection?.backend === backend ? tierSelection.model : undefined;
102
+ return { backend, model };
103
+ }
104
+ /**
105
+ * Parses JSONL output from an agentic backend (opencode --format json or claude-code --output-format json)
106
+ * and sums token usage and cost from all step_finish events.
107
+ *
108
+ * Returns null if no step_finish events are found (e.g. plain text output).
109
+ */
110
+ export function parseAgenticUsage(output) {
111
+ let totalInput = 0;
112
+ let totalOutput = 0;
113
+ let totalCost = 0;
114
+ let steps = 0;
115
+ for (const line of output.split('\n')) {
116
+ const trimmed = line.trim();
117
+ if (!trimmed)
118
+ continue;
119
+ try {
120
+ const event = JSON.parse(trimmed);
121
+ // opencode step_finish events
122
+ if (event.type === 'step_finish' && event.part) {
123
+ totalInput += event.part.tokens?.input ?? 0;
124
+ totalOutput += event.part.tokens?.output ?? 0;
125
+ totalCost += event.part.cost ?? 0;
126
+ steps++;
127
+ }
128
+ // Claude Code final result (single JSON object with result.usage)
129
+ if (event.result?.usage) {
130
+ totalInput += event.result.usage.input_tokens ?? 0;
131
+ totalOutput += event.result.usage.output_tokens ?? 0;
132
+ totalCost += event.result.cost_usd ?? 0;
133
+ steps++;
134
+ }
135
+ }
136
+ catch {
137
+ // Skip non-JSON lines
138
+ }
139
+ }
140
+ if (steps === 0)
141
+ return null;
142
+ return {
143
+ input_tokens: totalInput,
144
+ output_tokens: totalOutput,
145
+ cost_usd: totalCost,
146
+ steps,
147
+ };
148
+ }
149
+ //# sourceMappingURL=agentic-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentic-runtime.js","sourceRoot":"","sources":["../src/agentic-runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { ModelTier, RiskLevel } from './types.js';
2
+ export declare const AGENTIC_BACKENDS: readonly ["opencode", "claude-code"];
3
+ export type AgenticBackend = (typeof AGENTIC_BACKENDS)[number];
4
+ export interface AgenticFallbackConfig {
5
+ enabled?: boolean;
6
+ task_types?: string[];
7
+ risk_levels?: RiskLevel[];
8
+ }
9
+ export interface AgenticBackendConfig {
10
+ enabled?: boolean;
11
+ command?: string[];
12
+ transcript_format?: 'plain' | 'jsonl';
13
+ }
14
+ export interface AgenticConfig {
15
+ default_backend?: AgenticBackend;
16
+ backends?: Partial<Record<AgenticBackend, AgenticBackendConfig>>;
17
+ tiers?: Partial<Record<ModelTier, {
18
+ backend: AgenticBackend;
19
+ model?: string;
20
+ }>>;
21
+ }
22
+ export interface AgenticBackendResolution {
23
+ backend: AgenticBackend;
24
+ available: boolean;
25
+ command: string;
26
+ commandSource: 'default' | 'config';
27
+ configPath: string | null;
28
+ configPathSource: 'config' | 'default' | 'none';
29
+ resolvedConfigPath: string | null;
30
+ configExists: boolean | null;
31
+ installHint: string;
32
+ error?: string;
33
+ }
34
+ export interface AgenticRuntimeRequirement {
35
+ backend: AgenticBackend;
36
+ context?: string;
37
+ }
@@ -0,0 +1,2 @@
1
+ export const AGENTIC_BACKENDS = ['opencode', 'claude-code'];
2
+ //# sourceMappingURL=agentic-types.js.map