@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,175 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { existsSync, mkdirSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { readJson, writeAtomic, writeJson } from './storage.js';
5
+ const MIN_AUTO_ANSWER_CONFIDENCE = 0.85;
6
+ const MAX_CONSECUTIVE_AUTO_ANSWERS_PER_THREAD = 1;
7
+ const MAX_TOTAL_AUTO_ANSWERS_PER_TASK = 2;
8
+ /**
9
+ * Normalizes question text for deterministic hashing.
10
+ * Lowercases, collapses whitespace, strips punctuation at boundaries.
11
+ */
12
+ export function normalizeQuestionText(text) {
13
+ return text
14
+ .toLowerCase()
15
+ .replace(/[\r\n]+/g, ' ')
16
+ .replace(/\s+/g, ' ')
17
+ .trim()
18
+ .replace(/[?!.,;:]+$/, '')
19
+ .trim();
20
+ }
21
+ /**
22
+ * Computes a deterministic question_thread_id from normalized question text.
23
+ * Uses SHA-256, returns first 16 hex chars prefixed with 'qt_'.
24
+ */
25
+ export function computeQuestionThreadId(question) {
26
+ const normalized = normalizeQuestionText(question);
27
+ const hash = createHash('sha256').update(normalized, 'utf8').digest('hex');
28
+ return `qt_${hash.slice(0, 16)}`;
29
+ }
30
+ /**
31
+ * Validates that evidence and confidence meet the bar for auto-answering.
32
+ */
33
+ function isEligibleForAutoAnswer(evidence, confidence) {
34
+ if (!evidence || evidence.trim().length === 0) {
35
+ return false;
36
+ }
37
+ if (confidence === undefined || confidence < MIN_AUTO_ANSWER_CONFIDENCE) {
38
+ return false;
39
+ }
40
+ return true;
41
+ }
42
+ function triageArtifactPath(taskDir) {
43
+ return join(taskDir, 'question-triage.json');
44
+ }
45
+ export function triageDecisionPath(taskDir) {
46
+ return join(taskDir, 'triage.json');
47
+ }
48
+ function loadTriageArtifact(taskDir, taskId) {
49
+ const path = triageArtifactPath(taskDir);
50
+ if (existsSync(path)) {
51
+ try {
52
+ return readJson(path);
53
+ }
54
+ catch { }
55
+ }
56
+ return {
57
+ schema_version: 1,
58
+ task_id: taskId,
59
+ total_auto_answers: 0,
60
+ threads: {},
61
+ };
62
+ }
63
+ function saveTriageArtifact(taskDir, artifact) {
64
+ mkdirSync(taskDir, { recursive: true });
65
+ writeAtomic(triageArtifactPath(taskDir), JSON.stringify(artifact, null, 2) + '\n');
66
+ }
67
+ function writeTriageDecisionArtifact(taskDir, artifact) {
68
+ writeJson(triageDecisionPath(taskDir), artifact);
69
+ }
70
+ export function triageQuestion(input) {
71
+ const { question, task, taskDir, evidence, confidence, questionNumber, maxAutoAnswers } = input;
72
+ const threadId = computeQuestionThreadId(question);
73
+ const artifact = loadTriageArtifact(taskDir, task.id);
74
+ const limit = maxAutoAnswers ?? MAX_TOTAL_AUTO_ANSWERS_PER_TASK;
75
+ const threadRecord = artifact.threads[threadId] ?? {
76
+ question_thread_id: threadId,
77
+ consecutive_auto_answers: 0,
78
+ last_decision: 'ask_human',
79
+ };
80
+ if (!isEligibleForAutoAnswer(evidence, confidence)) {
81
+ const result = {
82
+ decision: 'ask_human',
83
+ question_thread_id: threadId,
84
+ reason: 'Insufficient evidence or confidence for auto-answer',
85
+ };
86
+ persistDecision(taskDir, artifact, threadRecord, 'ask_human');
87
+ writeTriageDecisionArtifact(taskDir, {
88
+ schema_version: 1,
89
+ task_id: task.id,
90
+ question,
91
+ question_number: questionNumber ?? 1,
92
+ question_thread_id: threadId,
93
+ decision: 'ask_human',
94
+ reason: result.reason,
95
+ created_at: new Date().toISOString(),
96
+ });
97
+ return result;
98
+ }
99
+ if (artifact.total_auto_answers >= limit) {
100
+ const result = {
101
+ decision: 'ask_human',
102
+ question_thread_id: threadId,
103
+ reason: `Total auto-answer limit (${limit}) reached for this task`,
104
+ };
105
+ persistDecision(taskDir, artifact, threadRecord, 'ask_human');
106
+ writeTriageDecisionArtifact(taskDir, {
107
+ schema_version: 1,
108
+ task_id: task.id,
109
+ question,
110
+ question_number: questionNumber ?? 1,
111
+ question_thread_id: threadId,
112
+ decision: 'ask_human',
113
+ reason: result.reason,
114
+ created_at: new Date().toISOString(),
115
+ });
116
+ return result;
117
+ }
118
+ if (threadRecord.consecutive_auto_answers >= MAX_CONSECUTIVE_AUTO_ANSWERS_PER_THREAD) {
119
+ const result = {
120
+ decision: 'ask_human',
121
+ question_thread_id: threadId,
122
+ reason: `Consecutive auto-answer limit (${MAX_CONSECUTIVE_AUTO_ANSWERS_PER_THREAD}) reached for thread ${threadId}`,
123
+ };
124
+ persistDecision(taskDir, artifact, threadRecord, 'ask_human');
125
+ writeTriageDecisionArtifact(taskDir, {
126
+ schema_version: 1,
127
+ task_id: task.id,
128
+ question,
129
+ question_number: questionNumber ?? 1,
130
+ question_thread_id: threadId,
131
+ decision: 'ask_human',
132
+ reason: result.reason,
133
+ created_at: new Date().toISOString(),
134
+ });
135
+ return result;
136
+ }
137
+ const result = {
138
+ decision: 'auto_answer',
139
+ answer: evidence,
140
+ confidence,
141
+ question_thread_id: threadId,
142
+ reason: `Auto-answer approved (confidence=${confidence})`,
143
+ };
144
+ persistDecision(taskDir, artifact, threadRecord, 'auto_answer');
145
+ writeTriageDecisionArtifact(taskDir, {
146
+ schema_version: 1,
147
+ task_id: task.id,
148
+ question,
149
+ question_number: questionNumber ?? 1,
150
+ question_thread_id: threadId,
151
+ decision: 'auto_answer',
152
+ reason: result.reason,
153
+ answer: result.answer,
154
+ confidence,
155
+ created_at: new Date().toISOString(),
156
+ });
157
+ return result;
158
+ }
159
+ function persistDecision(taskDir, artifact, threadRecord, decision) {
160
+ const updated = {
161
+ ...threadRecord,
162
+ last_decision: decision,
163
+ consecutive_auto_answers: decision === 'auto_answer' ? threadRecord.consecutive_auto_answers + 1 : 0,
164
+ };
165
+ const updatedArtifact = {
166
+ ...artifact,
167
+ total_auto_answers: decision === 'auto_answer' ? artifact.total_auto_answers + 1 : artifact.total_auto_answers,
168
+ threads: {
169
+ ...artifact.threads,
170
+ [threadRecord.question_thread_id]: updated,
171
+ },
172
+ };
173
+ saveTriageArtifact(taskDir, updatedArtifact);
174
+ }
175
+ //# sourceMappingURL=question-triage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"question-triage.js","sourceRoot":"","sources":["../src/question-triage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { RepoProfile, RepoType } from './init.js';
2
+ export type { RepoProfile, RepoType };
3
+ export declare function detectWorktreeRepo(worktreePath: string): RepoProfile;
4
+ /**
5
+ * Detect repo type in a worktree and return acceptance-check commands.
6
+ * Returns an empty array when nothing is detected.
7
+ */
8
+ export declare function buildGreenfieldChecks(worktreePath: string): string[];
@@ -0,0 +1,18 @@
1
+ import { detectRepo } from './init.js';
2
+ export function detectWorktreeRepo(worktreePath) {
3
+ return detectRepo(worktreePath);
4
+ }
5
+ /**
6
+ * Detect repo type in a worktree and return acceptance-check commands.
7
+ * Returns an empty array when nothing is detected.
8
+ */
9
+ export function buildGreenfieldChecks(worktreePath) {
10
+ const profile = detectWorktreeRepo(worktreePath);
11
+ const commands = [];
12
+ if (profile.testCommand)
13
+ commands.push(profile.testCommand);
14
+ if (profile.lintCommand)
15
+ commands.push(profile.lintCommand);
16
+ return commands;
17
+ }
18
+ //# sourceMappingURL=repo-detection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-detection.js","sourceRoot":"","sources":["../src/repo-detection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAKvC,MAAM,UAAU,kBAAkB,CAAC,YAAoB;IACrD,OAAO,UAAU,CAAC,YAAY,CAAC,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,YAAoB;IACxD,MAAM,OAAO,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC;IACjD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,OAAO,CAAC,WAAW;QAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC5D,IAAI,OAAO,CAAC,WAAW;QAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC5D,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { RetryContextLevel, FailureCategory } from './types.js';
2
+ export declare function buildRetryContext(taskDir: string, retryReason: string, level: RetryContextLevel, failureCategory?: FailureCategory): string;
@@ -0,0 +1,196 @@
1
+ import { join } from 'node:path';
2
+ import { readdirSync } from 'node:fs';
3
+ import { fileExists, readText } from './storage.js';
4
+ import { inferCodeFence } from './prompt-builder.js';
5
+ const RETRY_SECTION_BUDGETS = {
6
+ minimal: 1200,
7
+ basic: 4000,
8
+ full: 12000,
9
+ };
10
+ const RETRY_SECTION_PRIORITY = [
11
+ 'failure_reason',
12
+ 'acceptance_errors',
13
+ 'diagnostic_stderr',
14
+ 'previous_diff',
15
+ 'worker_prompt',
16
+ 'status',
17
+ 'worker_response',
18
+ 'validation',
19
+ 'review',
20
+ ];
21
+ function estimateRetryTokens(text) {
22
+ return Math.ceil(text.length / 4);
23
+ }
24
+ function truncateSection(content, maxTokens, strategy) {
25
+ if (estimateRetryTokens(content) <= maxTokens) {
26
+ return content;
27
+ }
28
+ if (strategy === 'head') {
29
+ const hunkPattern = /^@@.*@@$/gm;
30
+ const hunkStarts = [];
31
+ let match;
32
+ while ((match = hunkPattern.exec(content)) !== null) {
33
+ hunkStarts.push(match.index);
34
+ }
35
+ const totalHunks = hunkStarts.length;
36
+ if (totalHunks === 0) {
37
+ const maxChars = maxTokens * 4;
38
+ return content.slice(0, maxChars) + '\n... (truncated)';
39
+ }
40
+ let keptHunks = 0;
41
+ let lastEnd = content.length;
42
+ for (let i = 0; i < hunkStarts.length; i++) {
43
+ const end = i < hunkStarts.length - 1 ? hunkStarts[i + 1] : content.length;
44
+ const partial = content.slice(0, end);
45
+ if (estimateRetryTokens(partial) > maxTokens) {
46
+ lastEnd = i > 0 ? hunkStarts[i] : end;
47
+ keptHunks = i > 0 ? i : 1;
48
+ break;
49
+ }
50
+ keptHunks = i + 1;
51
+ lastEnd = end;
52
+ }
53
+ return content.slice(0, lastEnd) + `\n... (truncated, ${keptHunks}/${totalHunks} hunks shown)`;
54
+ }
55
+ else {
56
+ const lines = content.split('\n');
57
+ let keptLines = 0;
58
+ const result = [];
59
+ for (let i = lines.length - 1; i >= 0; i--) {
60
+ const candidate = [lines[i], ...result].join('\n');
61
+ if (estimateRetryTokens(candidate) > maxTokens) {
62
+ break;
63
+ }
64
+ result.unshift(lines[i]);
65
+ keptLines++;
66
+ }
67
+ if (keptLines === 0 && lines.length > 0) {
68
+ result.push(lines[lines.length - 1]);
69
+ keptLines = 1;
70
+ }
71
+ return `... (truncated, showing last ${keptLines} lines)\n` + result.join('\n');
72
+ }
73
+ }
74
+ const TRUNCATION_STRATEGIES = {
75
+ previous_diff: 'head',
76
+ diagnostic_stderr: 'tail',
77
+ };
78
+ export function buildRetryContext(taskDir, retryReason, level, failureCategory) {
79
+ const attemptsDir = join(taskDir, 'attempts');
80
+ const latestAttemptDir = findLatestAttemptDir(attemptsDir);
81
+ if (!latestAttemptDir) {
82
+ const lines = ['Retry context:', `- Previous failure reason: ${retryReason}`];
83
+ if (failureCategory) {
84
+ lines.push(`- Failure category: ${failureCategory}`);
85
+ }
86
+ return lines.join('\n');
87
+ }
88
+ const sections = collectRetrySections(latestAttemptDir, retryReason, failureCategory);
89
+ const budget = RETRY_SECTION_BUDGETS[level];
90
+ const selected = [];
91
+ let used = 0;
92
+ for (const key of RETRY_SECTION_PRIORITY) {
93
+ const section = sections[key];
94
+ if (!section) {
95
+ continue;
96
+ }
97
+ let cost = estimateRetryTokens(section);
98
+ if (used + cost > budget) {
99
+ const remainingBudget = budget - used;
100
+ if (remainingBudget <= 0) {
101
+ continue;
102
+ }
103
+ const strategy = TRUNCATION_STRATEGIES[key] ?? 'head';
104
+ const truncated = truncateSection(section, remainingBudget, strategy);
105
+ const truncatedCost = estimateRetryTokens(truncated);
106
+ if (truncatedCost > remainingBudget) {
107
+ continue;
108
+ }
109
+ selected.push(truncated);
110
+ used += truncatedCost;
111
+ continue;
112
+ }
113
+ selected.push(section);
114
+ used += cost;
115
+ }
116
+ return ['Retry context:', ...selected].join('\n');
117
+ }
118
+ function findLatestAttemptDir(attemptsDir) {
119
+ try {
120
+ const entries = readdirSync(attemptsDir, { withFileTypes: true });
121
+ const attemptNumbers = entries
122
+ .filter((entry) => entry.isDirectory() && /^\d+$/.test(entry.name))
123
+ .map((entry) => Number(entry.name))
124
+ .sort((left, right) => right - left);
125
+ if (attemptNumbers.length === 0) {
126
+ return null;
127
+ }
128
+ return join(attemptsDir, String(attemptNumbers[0]));
129
+ }
130
+ catch {
131
+ return null;
132
+ }
133
+ }
134
+ function collectRetrySections(attemptDir, retryReason, failureCategory) {
135
+ const failureReasonLines = [`- Previous failure reason: ${retryReason}`];
136
+ if (failureCategory) {
137
+ failureReasonLines.push(`- Failure category: ${failureCategory}`);
138
+ }
139
+ return {
140
+ failure_reason: failureReasonLines.join('\n'),
141
+ acceptance_errors: readRetryArtifactSection(attemptDir, 'acceptance-errors.txt', 'Acceptance Check Failures'),
142
+ diagnostic_stderr: readDiagnosticStderr(attemptDir),
143
+ previous_diff: readPreviousDiff(attemptDir),
144
+ worker_prompt: readRetryArtifactSection(attemptDir, 'worker_prompt.md', 'Previous worker prompt'),
145
+ status: readRetryArtifactSection(attemptDir, 'status.json', 'Previous task status'),
146
+ worker_response: readRetryArtifactSection(attemptDir, 'worker_response.json', 'Previous worker response'),
147
+ validation: readRetryArtifactSection(attemptDir, 'validation.json', 'Previous validation result'),
148
+ review: readRetryArtifactSection(attemptDir, 'review.json', 'Previous review result'),
149
+ };
150
+ }
151
+ function readRetryArtifactSection(attemptDir, fileName, title) {
152
+ const artifactPath = join(attemptDir, fileName);
153
+ if (!fileExists(artifactPath)) {
154
+ return undefined;
155
+ }
156
+ const content = readText(artifactPath).trim();
157
+ if (content.length === 0) {
158
+ return undefined;
159
+ }
160
+ const fence = inferCodeFence(fileName);
161
+ return [`### ${title}`, '```' + fence, content, '```'].join('\n');
162
+ }
163
+ function readPreviousDiff(attemptDir) {
164
+ const diffPath = join(attemptDir, 'diff.patch');
165
+ if (!fileExists(diffPath)) {
166
+ return undefined;
167
+ }
168
+ const content = readText(diffPath).trim();
169
+ if (content.length === 0) {
170
+ return undefined;
171
+ }
172
+ return ['### Previous diff', '```patch', content, '```'].join('\n');
173
+ }
174
+ function readDiagnosticStderr(attemptDir) {
175
+ const diagnosticPath = join(attemptDir, 'diagnostic.json');
176
+ if (fileExists(diagnosticPath)) {
177
+ try {
178
+ const diagnostic = JSON.parse(readText(diagnosticPath));
179
+ if (diagnostic.stderr && diagnostic.stderr.trim().length > 0) {
180
+ return ['### Diagnostic stderr', '```text', diagnostic.stderr.trim(), '```'].join('\n');
181
+ }
182
+ }
183
+ catch {
184
+ // Fall through to agentic_stderr.txt
185
+ }
186
+ }
187
+ const agenticStderrPath = join(attemptDir, 'agentic_stderr.txt');
188
+ if (fileExists(agenticStderrPath)) {
189
+ const content = readText(agenticStderrPath).trim();
190
+ if (content.length > 0) {
191
+ return ['### Diagnostic stderr', '```text', content, '```'].join('\n');
192
+ }
193
+ }
194
+ return undefined;
195
+ }
196
+ //# sourceMappingURL=retry-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry-context.js","sourceRoot":"","sources":["../src/retry-context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { type ExecutionMode, type ModelTier, type RiskLevel, type StwConfig } from './types.js';
2
+ export declare function getNextTier(currentTier: ModelTier): ModelTier | null;
3
+ export interface RouteInput {
4
+ risk: RiskLevel;
5
+ task_type: string;
6
+ model_tier: string;
7
+ execution_mode?: ExecutionMode;
8
+ planner_eligible?: boolean;
9
+ estimated_prompt_tokens?: number;
10
+ max_prompt_tokens?: number;
11
+ }
12
+ export interface RouteResult {
13
+ tier: ModelTier;
14
+ model_id: string;
15
+ provider: string;
16
+ model: string;
17
+ }
18
+ export declare function routeTask(input: RouteInput, config: StwConfig): RouteResult;
package/dist/router.js ADDED
@@ -0,0 +1,137 @@
1
+ import { resolveModel } from './config.js';
2
+ import { MODEL_TIERS, } from './types.js';
3
+ const NEXT_TIER = {
4
+ cheap: 'medium',
5
+ medium: 'strong',
6
+ strong: null,
7
+ reader: 'strong',
8
+ };
9
+ export function getNextTier(currentTier) {
10
+ return NEXT_TIER[currentTier];
11
+ }
12
+ const ESCALATION_LADDER = {
13
+ cheap: ['cheap', 'medium', 'strong'],
14
+ medium: ['medium', 'strong'],
15
+ strong: ['strong'],
16
+ reader: ['reader', 'strong'],
17
+ };
18
+ export function routeTask(input, config) {
19
+ const normalizedInput = applyPreEscalationRouting(applyExecutionModeRouting(input, config));
20
+ if (config.models && Object.keys(config.models).length > 0) {
21
+ const routedFromModels = routeWithModelRegistry(normalizedInput, config);
22
+ if (routedFromModels) {
23
+ return routedFromModels;
24
+ }
25
+ const startingTier = asModelTier(normalizedInput.model_tier);
26
+ const reachableTiers = startingTier ? ESCALATION_LADDER[startingTier].join(', ') : normalizedInput.model_tier;
27
+ throw new Error(`No models configured for requested tier "${normalizedInput.model_tier}" or any reachable tier (${reachableTiers})`);
28
+ }
29
+ return routeWithLegacyProviders(normalizedInput, config);
30
+ }
31
+ function applyPreEscalationRouting(input) {
32
+ if (input.estimated_prompt_tokens === undefined || input.max_prompt_tokens === undefined) {
33
+ return input;
34
+ }
35
+ const ratio = input.estimated_prompt_tokens / input.max_prompt_tokens;
36
+ const currentTier = asModelTier(input.model_tier);
37
+ if (!currentTier) {
38
+ return input;
39
+ }
40
+ let escalatedTier = currentTier;
41
+ if (ratio > 0.9 && currentTier === 'medium') {
42
+ escalatedTier = 'strong';
43
+ }
44
+ else if (ratio > 0.7 && currentTier === 'cheap') {
45
+ escalatedTier = 'medium';
46
+ }
47
+ if (escalatedTier !== currentTier) {
48
+ return { ...input, model_tier: escalatedTier };
49
+ }
50
+ return input;
51
+ }
52
+ function routeWithModelRegistry(input, config) {
53
+ const exactMatch = resolveModel(config, input.model_tier);
54
+ if (exactMatch && exactMatch.id === input.model_tier) {
55
+ return toRouteResult(exactMatch);
56
+ }
57
+ const startingTier = exactMatch?.tier ?? asModelTier(input.model_tier);
58
+ if (!startingTier) {
59
+ return null;
60
+ }
61
+ for (const tier of ESCALATION_LADDER[startingTier]) {
62
+ const entries = listModelsForTier(config, tier);
63
+ if (entries.length === 0) {
64
+ continue;
65
+ }
66
+ const preferences = config.routing_policy.provider_preferences?.[tier] ?? Object.keys(config.providers);
67
+ for (const providerName of preferences) {
68
+ const modelEntry = entries.find((entry) => entry.provider === providerName);
69
+ if (!modelEntry) {
70
+ continue;
71
+ }
72
+ return toRouteResult(modelEntry);
73
+ }
74
+ const [fallbackEntry] = entries;
75
+ if (fallbackEntry) {
76
+ return toRouteResult(fallbackEntry);
77
+ }
78
+ }
79
+ return null;
80
+ }
81
+ function routeWithLegacyProviders(input, config) {
82
+ const requestedTier = asModelTier(input.model_tier);
83
+ if (!requestedTier) {
84
+ throw new Error(`No model configured for "${input.model_tier}"`);
85
+ }
86
+ for (const tier of ESCALATION_LADDER[requestedTier]) {
87
+ const preferences = config.routing_policy.provider_preferences?.[tier] ?? Object.keys(config.providers);
88
+ for (const providerName of preferences) {
89
+ const provider = config.providers[providerName];
90
+ if (!provider) {
91
+ continue;
92
+ }
93
+ const model = provider.models[tier];
94
+ if (!model) {
95
+ continue;
96
+ }
97
+ return {
98
+ tier,
99
+ model_id: tier,
100
+ provider: providerName,
101
+ model,
102
+ };
103
+ }
104
+ }
105
+ throw new Error(`No provider available for tier "${input.model_tier}" or any escalation tier`);
106
+ }
107
+ function listModelsForTier(config, tier) {
108
+ return Object.entries(config.models ?? {})
109
+ .filter(([, entry]) => entry.tier === tier)
110
+ .map(([id, entry]) => ({ id, ...entry }));
111
+ }
112
+ function toRouteResult(entry) {
113
+ return {
114
+ tier: entry.tier,
115
+ model_id: entry.id,
116
+ provider: entry.provider,
117
+ model: entry.model,
118
+ };
119
+ }
120
+ function asModelTier(value) {
121
+ return MODEL_TIERS.includes(value) ? value : null;
122
+ }
123
+ function applyExecutionModeRouting(input, config) {
124
+ const conservativeTaskTypes = new Set(config.routing_policy.conservative_execution_task_types ?? ['integration', 'final_validation']);
125
+ const shouldForceConservative = conservativeTaskTypes.has(input.task_type) || input.planner_eligible === false;
126
+ if (!shouldForceConservative) {
127
+ return input;
128
+ }
129
+ if (input.model_tier === 'cheap') {
130
+ return {
131
+ ...input,
132
+ model_tier: 'medium',
133
+ };
134
+ }
135
+ return input;
136
+ }
137
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ export type RunEventType = 'manual_completion' | 'status_correction' | 'resume' | 'retry' | 'replan' | 'sync_repair' | 'stop' | 'answer' | 'escalation';
2
+ export type EscalationCategory = 'human_review' | 'spec_gap' | 'validation_failure' | 'integration_issue' | 'sync_issue' | 'budget' | 'drift' | 'operator_override' | 'other';
3
+ export interface RunEvent {
4
+ schema_version: 1;
5
+ event_id: string;
6
+ run_id: string;
7
+ event_type: RunEventType;
8
+ created_at: string;
9
+ actor: string;
10
+ task_id?: string;
11
+ summary: string;
12
+ details?: string;
13
+ escalation_category?: EscalationCategory;
14
+ metadata?: Record<string, string | number | boolean | null>;
15
+ }
16
+ export interface RunEventsArtifact {
17
+ schema_version: 1;
18
+ run_id: string;
19
+ events: RunEvent[];
20
+ }
21
+ export interface RunMetricsArtifact {
22
+ schema_version: 1;
23
+ run_id: string;
24
+ machine: {
25
+ total_tasks?: number;
26
+ completed_tasks?: number;
27
+ failed_tasks?: number;
28
+ escalated_tasks?: number;
29
+ skipped_tasks?: number;
30
+ pending_tasks?: number;
31
+ total_cost_usd?: number;
32
+ total_input_tokens?: number;
33
+ total_output_tokens?: number;
34
+ avg_latency_ms?: number;
35
+ };
36
+ operator?: {
37
+ objective_score?: number;
38
+ outcome_notes?: string;
39
+ true_cost_notes?: string;
40
+ intervention_notes?: string;
41
+ };
42
+ updated_at: string;
43
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=run-artifact-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-artifact-types.js","sourceRoot":"","sources":["../src/run-artifact-types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,14 @@
1
+ import type { Task, CostsFile, RunManifest, BudgetConfig, TaskStatus } from './types.js';
2
+ import type { RunEventsArtifact, RunMetricsArtifact } from './types.js';
3
+ export interface RunSummaryOptions {
4
+ manifest: RunManifest;
5
+ tasks: Task[];
6
+ taskStatuses: Record<string, string>;
7
+ costs?: CostsFile | null;
8
+ budget?: BudgetConfig | null;
9
+ taskStatusRecords?: Record<string, TaskStatus> | null;
10
+ runEvents?: RunEventsArtifact | null;
11
+ runMetrics?: RunMetricsArtifact | null;
12
+ taskEvents?: Record<string, string[]> | null;
13
+ }
14
+ export declare function generateRunSummary(options: RunSummaryOptions): string;