@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/dist/run.js ADDED
@@ -0,0 +1,150 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ import { randomInt } from 'node:crypto';
3
+ import { readFileSync } from 'node:fs';
4
+ import { join, resolve } from 'node:path';
5
+ import { loadConfig } from './config.js';
6
+ import { generateAssignments } from './assignments.js';
7
+ import { generatePlan } from './planner.js';
8
+ import { buildRunRecoveryReport, readTaskStatus, writeRunState } from './status.js';
9
+ import { ensureDir, fileExists, readJson, writeAtomic, writeJson } from './storage.js';
10
+ export function generateRunId(now = new Date()) {
11
+ const date = now.toISOString().slice(0, 10).replace(/-/g, '_');
12
+ const sequence = String(randomInt(100, 1000));
13
+ return `run_${date}_${sequence}`;
14
+ }
15
+ export function createRun(options) {
16
+ const runId = getUniqueRunId(options.stwRoot);
17
+ const runPath = join(options.stwRoot, 'runs', runId);
18
+ ensureDir(runPath);
19
+ ensureDir(join(runPath, 'tasks'));
20
+ const manifest = {
21
+ schema_version: 1,
22
+ run_id: runId,
23
+ spec_path: options.specPath,
24
+ repo_root: options.repoRoot,
25
+ base_branch: options.baseBranch,
26
+ branch: `${options.branchPrefix}${runId.replace(/_/g, '-')}`,
27
+ status: 'pending',
28
+ pr_number: null,
29
+ created_at: new Date().toISOString(),
30
+ ...(options.greenfield !== undefined && { greenfield: options.greenfield }),
31
+ ...(options.seedDir && { seedDir: options.seedDir }),
32
+ };
33
+ writeJson(join(runPath, 'manifest.json'), manifest);
34
+ writeAtomic(join(options.stwRoot, 'ACTIVE_RUN'), runId);
35
+ // Create the run branch from current HEAD (non-fatal if not in a git repo)
36
+ try {
37
+ execFileSync('git', ['branch', manifest.branch, 'HEAD'], {
38
+ cwd: options.repoRoot,
39
+ encoding: 'utf-8',
40
+ stdio: 'pipe',
41
+ });
42
+ }
43
+ catch {
44
+ // Branch creation may fail if not in a git repo or branch already exists
45
+ }
46
+ return manifest;
47
+ }
48
+ export async function replanRun(options) {
49
+ const manifestPath = join(options.stwRoot, 'runs', options.runId, 'manifest.json');
50
+ const manifest = readJson(manifestPath);
51
+ validateRunCanBeReplanned(manifest.status);
52
+ const config = loadConfig(join(options.stwRoot, 'config.yml'));
53
+ const specPath = resolve(manifest.repo_root, manifest.spec_path);
54
+ const spec = readFileSync(specPath, 'utf-8');
55
+ const previousGraph = readExistingTaskGraph(options.stwRoot, options.runId);
56
+ const completedStatuses = collectCompletedTaskStatuses(options.stwRoot, options.runId, previousGraph);
57
+ const completedTaskIds = completedStatuses.map((entry) => entry.task.id);
58
+ const completedTaskContext = completedStatuses.map(({ task, status }) => ({
59
+ task_id: task.id,
60
+ description: task.description,
61
+ status: status.status,
62
+ notes: status.notes,
63
+ }));
64
+ const plannerResult = await generatePlan({
65
+ spec,
66
+ repoRoot: manifest.repo_root,
67
+ config,
68
+ runId: options.runId,
69
+ completedTasks: completedTaskContext,
70
+ });
71
+ const mergedGraph = mergeCompletedTasksIntoGraph(plannerResult.task_graph, completedStatuses);
72
+ writeJson(join(options.stwRoot, 'runs', options.runId, 'task_graph.json'), mergedGraph);
73
+ const agents = options.agents ?? getDefaultAgents();
74
+ const assignmentResult = generateAssignments(mergedGraph, agents, config);
75
+ writeJson(join(options.stwRoot, 'runs', options.runId, 'assignments.json'), assignmentResult.assignments);
76
+ const updatedManifest = setRunStateToPending(options.stwRoot, options.runId, manifest.status);
77
+ return {
78
+ manifest: updatedManifest,
79
+ taskGraph: mergedGraph,
80
+ completedTaskIds,
81
+ };
82
+ }
83
+ function getUniqueRunId(stwRoot) {
84
+ const MAX_RETRIES = 20;
85
+ for (let i = 0; i < MAX_RETRIES; i++) {
86
+ const runId = generateRunId();
87
+ if (!fileExists(join(stwRoot, 'runs', runId))) {
88
+ return runId;
89
+ }
90
+ }
91
+ throw new Error(`Failed to generate unique run ID after ${MAX_RETRIES} attempts`);
92
+ }
93
+ function validateRunCanBeReplanned(status) {
94
+ if (status === 'running') {
95
+ throw new Error('Cannot replan a run while it is running');
96
+ }
97
+ if (status === 'complete' || status === 'failed' || status === 'stopped') {
98
+ throw new Error(`Cannot replan a run in terminal state: ${status}`);
99
+ }
100
+ }
101
+ function readExistingTaskGraph(stwRoot, runId) {
102
+ const graphPath = join(stwRoot, 'runs', runId, 'task_graph.json');
103
+ if (!fileExists(graphPath)) {
104
+ throw new Error(`No task graph found for run ${runId}`);
105
+ }
106
+ return readJson(graphPath);
107
+ }
108
+ function collectCompletedTaskStatuses(stwRoot, runId, graph) {
109
+ return graph.tasks
110
+ .map((task) => ({ task, status: readTaskStatus(stwRoot, runId, task.id) }))
111
+ .filter((entry) => entry.status?.status === 'complete');
112
+ }
113
+ function mergeCompletedTasksIntoGraph(replannedGraph, completedTasks) {
114
+ const completedById = new Map(completedTasks.map((entry) => [entry.task.id, entry.task]));
115
+ const remainingTasks = replannedGraph.tasks.filter((task) => !completedById.has(task.id));
116
+ const mergedTasks = [...completedTasks.map((entry) => entry.task), ...remainingTasks];
117
+ return {
118
+ ...replannedGraph,
119
+ tasks: mergedTasks,
120
+ };
121
+ }
122
+ function setRunStateToPending(stwRoot, runId, currentStatus) {
123
+ if (currentStatus === 'pending') {
124
+ const manifestPath = join(stwRoot, 'runs', runId, 'manifest.json');
125
+ return readJson(manifestPath);
126
+ }
127
+ try {
128
+ return writeRunState(stwRoot, runId, 'pending');
129
+ }
130
+ catch {
131
+ const manifestPath = join(stwRoot, 'runs', runId, 'manifest.json');
132
+ const manifest = readJson(manifestPath);
133
+ manifest.status = 'pending';
134
+ writeJson(manifestPath, manifest);
135
+ return manifest;
136
+ }
137
+ }
138
+ function getDefaultAgents() {
139
+ return [
140
+ { agent_id: 'agent-strong-1', tool: 'claude-code', model: 'opus-4.6', tier: 'strong' },
141
+ { agent_id: 'agent-medium-1', tool: 'opencode', model: 'gpt-5.4', tier: 'medium' },
142
+ { agent_id: 'agent-cheap-1', tool: 'opencode', model: 'minimax-2.5', tier: 'cheap' },
143
+ ];
144
+ }
145
+ export function getRunRecoveryReport(stwRoot, runId) {
146
+ const graphPath = join(stwRoot, 'runs', runId, 'task_graph.json');
147
+ const taskIds = fileExists(graphPath) ? readJson(graphPath).tasks.map((task) => task.id) : [];
148
+ return buildRunRecoveryReport(stwRoot, runId, taskIds);
149
+ }
150
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { ImportGraph } from './planner-prompt.js';
2
+ import type { TaskGraph } from './types.js';
3
+ export interface ScopeExpansionResult {
4
+ expanded: Map<string, string[]>;
5
+ warnings: string[];
6
+ }
7
+ export declare function expandScopesFromImportGraph(graph: TaskGraph, importGraph: ImportGraph, options?: {
8
+ maxExpansionPerTask?: number;
9
+ maxScopeFilesPerTask?: number;
10
+ }): ScopeExpansionResult;
@@ -0,0 +1,117 @@
1
+ import { isTestFile } from './planner-prompt.js';
2
+ import { isSerialized } from './plan-validation.js';
3
+ export function expandScopesFromImportGraph(graph, importGraph, options) {
4
+ const maxExpansion = options?.maxExpansionPerTask ?? 3;
5
+ const maxScope = options?.maxScopeFilesPerTask ?? 8;
6
+ const expanded = new Map();
7
+ const warnings = [];
8
+ // Build reverse index: imported file -> list of importers
9
+ const reverseIndex = new Map();
10
+ for (const edge of importGraph.resolvedEdges) {
11
+ if (!edge.resolved)
12
+ continue;
13
+ const importers = reverseIndex.get(edge.resolved) ?? [];
14
+ if (!importers.includes(edge.importer)) {
15
+ importers.push(edge.importer);
16
+ }
17
+ reverseIndex.set(edge.resolved, importers);
18
+ }
19
+ const taskById = new Map(graph.tasks.map((t) => [t.id, t]));
20
+ const dependencyCache = new Map();
21
+ // Build map of file -> tasks that own it (for overlap detection)
22
+ const fileOwnership = new Map();
23
+ for (const task of graph.tasks) {
24
+ for (const file of task.scope.files) {
25
+ const owners = fileOwnership.get(file) ?? [];
26
+ owners.push(task.id);
27
+ fileOwnership.set(file, owners);
28
+ }
29
+ }
30
+ // Track files claimed by expansion across tasks (for parallel dedup)
31
+ const expansionClaims = new Map();
32
+ // First pass: compute candidate expansions per task with relevance scores
33
+ const candidatesPerTask = new Map();
34
+ for (const task of graph.tasks) {
35
+ const currentScope = new Set(task.scope.files);
36
+ const candidateScores = new Map();
37
+ for (const scopeFile of task.scope.files) {
38
+ const importers = reverseIndex.get(scopeFile) ?? [];
39
+ for (const importer of importers) {
40
+ if (currentScope.has(importer))
41
+ continue;
42
+ if (isTestFile(importer))
43
+ continue;
44
+ candidateScores.set(importer, (candidateScores.get(importer) ?? 0) + 1);
45
+ }
46
+ }
47
+ const ranked = [...candidateScores.entries()]
48
+ .map(([file, relevance]) => ({ file, relevance }))
49
+ .sort((a, b) => b.relevance - a.relevance || a.file.localeCompare(b.file));
50
+ candidatesPerTask.set(task.id, ranked);
51
+ }
52
+ // Second pass: deduplicate across parallel tasks
53
+ for (const task of graph.tasks) {
54
+ const candidates = candidatesPerTask.get(task.id) ?? [];
55
+ const added = [];
56
+ for (const candidate of candidates) {
57
+ if (added.length >= maxExpansion)
58
+ break;
59
+ if (task.scope.files.length + added.length >= maxScope) {
60
+ warnings.push(`${task.id}: skipped expanding ${candidate.file} (would exceed ${String(maxScope)}-file scope cap)`);
61
+ continue;
62
+ }
63
+ // Check if file is in a parallel task's scope
64
+ const owners = fileOwnership.get(candidate.file) ?? [];
65
+ const inParallelScope = owners.some((ownerId) => {
66
+ if (ownerId === task.id)
67
+ return false;
68
+ const ownerTask = taskById.get(ownerId);
69
+ if (ownerTask?.scope.allow_shared_files)
70
+ return false;
71
+ return !isSerialized(task.id, ownerId, taskById, dependencyCache);
72
+ });
73
+ if (inParallelScope)
74
+ continue;
75
+ // Deduplicate: if another parallel task also wants this file, pick the higher relevance
76
+ const existingClaim = expansionClaims.get(candidate.file);
77
+ if (existingClaim) {
78
+ const claimantParallel = !isSerialized(task.id, existingClaim.taskId, taskById, dependencyCache);
79
+ if (claimantParallel) {
80
+ if (candidate.relevance > existingClaim.relevance ||
81
+ (candidate.relevance === existingClaim.relevance && task.id < existingClaim.taskId)) {
82
+ // This task wins — remove from previous claimant
83
+ const prevAdded = expanded.get(existingClaim.taskId);
84
+ if (prevAdded) {
85
+ const idx = prevAdded.indexOf(candidate.file);
86
+ if (idx !== -1) {
87
+ prevAdded.splice(idx, 1);
88
+ const prevTask = taskById.get(existingClaim.taskId);
89
+ if (prevTask) {
90
+ const scopeIdx = prevTask.scope.files.indexOf(candidate.file);
91
+ if (scopeIdx !== -1)
92
+ prevTask.scope.files.splice(scopeIdx, 1);
93
+ }
94
+ }
95
+ }
96
+ warnings.push(`${existingClaim.taskId}: expansion of ${candidate.file} reassigned to ${task.id} (higher relevance)`);
97
+ expansionClaims.set(candidate.file, { taskId: task.id, relevance: candidate.relevance });
98
+ }
99
+ else {
100
+ warnings.push(`${task.id}: skipped expanding ${candidate.file} (already claimed by ${existingClaim.taskId})`);
101
+ continue;
102
+ }
103
+ }
104
+ }
105
+ else {
106
+ expansionClaims.set(candidate.file, { taskId: task.id, relevance: candidate.relevance });
107
+ }
108
+ added.push(candidate.file);
109
+ task.scope.files.push(candidate.file);
110
+ }
111
+ if (added.length > 0) {
112
+ expanded.set(task.id, added);
113
+ }
114
+ }
115
+ return { expanded, warnings };
116
+ }
117
+ //# sourceMappingURL=scope-expansion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope-expansion.js","sourceRoot":"","sources":["../src/scope-expansion.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Task } from './types.js';
2
+ export declare function expandScope(task: Task): string[];
3
+ export declare function isAllowedScopeFile(scopeFiles: string[], candidatePath: string): boolean;
4
+ export declare function toRelativePath(filePath: string): string;
package/dist/scope.js ADDED
@@ -0,0 +1,37 @@
1
+ import { normalize } from 'node:path';
2
+ const TEST_COMMAND_PATTERNS = /\b(vitest|jest|pytest|go\s+test|cargo\s+test)\b/;
3
+ export function expandScope(task) {
4
+ const base = [...task.scope.files, ...(task.scope.new_files ?? [])];
5
+ const hasTestCommand = task.acceptance_checks.some((check) => TEST_COMMAND_PATTERNS.test(check));
6
+ if (!hasTestCommand) {
7
+ return base;
8
+ }
9
+ const expanded = new Set(base.map((f) => toRelativePath(f)));
10
+ for (const file of base) {
11
+ const rel = toRelativePath(file);
12
+ // Extract the base filename without extension and its directory prefix
13
+ // e.g. "src/utils/foo.ts" -> stem="foo", ext=".ts"
14
+ const lastSlash = rel.lastIndexOf('/');
15
+ const filename = lastSlash >= 0 ? rel.slice(lastSlash + 1) : rel;
16
+ const dotIndex = filename.lastIndexOf('.');
17
+ if (dotIndex <= 0)
18
+ continue;
19
+ const stem = filename.slice(0, dotIndex);
20
+ const ext = filename.slice(dotIndex);
21
+ // Generate test file counterparts
22
+ expanded.add(`tests/${stem}.test${ext}`);
23
+ expanded.add(`test/${stem}.test${ext}`);
24
+ expanded.add(`__tests__/${stem}.test${ext}`);
25
+ // Python convention: test_<stem>
26
+ expanded.add(`tests/test_${stem}${ext}`);
27
+ }
28
+ return [...expanded];
29
+ }
30
+ export function isAllowedScopeFile(scopeFiles, candidatePath) {
31
+ const allowed = new Set(scopeFiles.map((file) => toRelativePath(file)));
32
+ return allowed.has(candidatePath);
33
+ }
34
+ export function toRelativePath(filePath) {
35
+ return normalize(filePath).replace(/^\.\//, '');
36
+ }
37
+ //# sourceMappingURL=scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope.js","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC,MAAM,qBAAqB,GAAG,iDAAiD,CAAC;AAEhF,MAAM,UAAU,WAAW,CAAC,IAAU;IACpC,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACjG,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE7D,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QACjC,uEAAuE;QACvE,mDAAmD;QACnD,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACvC,MAAM,QAAQ,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QACjE,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAC3C,IAAI,QAAQ,IAAI,CAAC;YAAE,SAAS;QAC5B,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAErC,kCAAkC;QAClC,QAAQ,CAAC,GAAG,CAAC,SAAS,IAAI,QAAQ,GAAG,EAAE,CAAC,CAAC;QACzC,QAAQ,CAAC,GAAG,CAAC,QAAQ,IAAI,QAAQ,GAAG,EAAE,CAAC,CAAC;QACxC,QAAQ,CAAC,GAAG,CAAC,aAAa,IAAI,QAAQ,GAAG,EAAE,CAAC,CAAC;QAC7C,iCAAiC;QACjC,QAAQ,CAAC,GAAG,CAAC,cAAc,IAAI,GAAG,GAAG,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,UAAoB,EAAE,aAAqB;IAC5E,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxE,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,OAAO,SAAS,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAClD,CAAC"}
@@ -0,0 +1,18 @@
1
+ export interface RunScorecard {
2
+ schema_version: 1;
3
+ run_id: string;
4
+ worker_cost_usd: number;
5
+ planner_cost_usd: number;
6
+ total_tasks: number;
7
+ auto_completed: number;
8
+ escalated: number;
9
+ rescued: number;
10
+ skipped: number;
11
+ total_retries: number;
12
+ auto_completion_rate: number;
13
+ wall_clock_seconds: number;
14
+ spec_to_ingest_seconds?: number;
15
+ }
16
+ export declare function generateScorecard(stwRoot: string, runId: string): RunScorecard;
17
+ export declare function formatScorecard(scorecard: RunScorecard): string;
18
+ export declare function writeScorecard(stwRoot: string, runId: string, scorecard: RunScorecard): void;
@@ -0,0 +1,128 @@
1
+ import { join } from 'node:path';
2
+ import { fileExists, readJson, runDir, taskDir, writeJson } from './storage.js';
3
+ import { loadCosts } from './cost.js';
4
+ function readManifest(stwRoot, runId) {
5
+ const manifestPath = join(runDir(stwRoot, runId), 'manifest.json');
6
+ if (!fileExists(manifestPath)) {
7
+ return null;
8
+ }
9
+ return readJson(manifestPath);
10
+ }
11
+ function readTaskGraph(stwRoot, runId) {
12
+ const graphPath = join(runDir(stwRoot, runId), 'task_graph.json');
13
+ if (!fileExists(graphPath)) {
14
+ return null;
15
+ }
16
+ return readJson(graphPath);
17
+ }
18
+ function readTaskStatuses(stwRoot, runId, taskIds) {
19
+ const statuses = new Map();
20
+ for (const taskId of taskIds) {
21
+ const statusPath = join(taskDir(stwRoot, runId, taskId), 'status.json');
22
+ if (fileExists(statusPath)) {
23
+ const status = readJson(statusPath);
24
+ statuses.set(taskId, status);
25
+ }
26
+ }
27
+ return statuses;
28
+ }
29
+ function parseRetriesFromNotes(notes) {
30
+ if (!notes)
31
+ return 0;
32
+ const match = notes.match(/attempts:\s*(\d+)/);
33
+ return match ? parseInt(match[1], 10) : 0;
34
+ }
35
+ export function generateScorecard(stwRoot, runId) {
36
+ const manifest = readManifest(stwRoot, runId);
37
+ const graph = readTaskGraph(stwRoot, runId);
38
+ const costs = loadCosts(stwRoot, runId);
39
+ const totalTasks = graph?.tasks.length ?? 0;
40
+ const taskIds = graph?.tasks.map((t) => t.id) ?? [];
41
+ const taskStatuses = readTaskStatuses(stwRoot, runId, taskIds);
42
+ let autoCompleted = 0;
43
+ let escalated = 0;
44
+ let rescued = 0;
45
+ let skipped = 0;
46
+ let totalRetries = 0;
47
+ for (const taskId of taskIds) {
48
+ const status = taskStatuses.get(taskId);
49
+ if (!status)
50
+ continue;
51
+ if (status.status === 'complete') {
52
+ autoCompleted++;
53
+ }
54
+ else if (status.status === 'escalated' || status.status === 'failed') {
55
+ escalated++;
56
+ }
57
+ else if (status.status === 'skipped') {
58
+ skipped++;
59
+ }
60
+ if (status.preserved_worktree_path) {
61
+ rescued++;
62
+ }
63
+ const attempts = parseRetriesFromNotes(status.notes);
64
+ if (attempts > 1) {
65
+ totalRetries += attempts - 1;
66
+ }
67
+ }
68
+ const workerCostUsd = costs?.total_cost_usd ?? 0;
69
+ const plannerCostUsd = 0;
70
+ const totalRetriesFromCosts = costs?.total_retries ?? 0;
71
+ const autoCompletionRate = totalTasks > 0 ? (autoCompleted / totalTasks) * 100 : 0;
72
+ let wallClockSeconds = 0;
73
+ if (manifest?.created_at) {
74
+ const startTime = new Date(manifest.created_at).getTime();
75
+ const endTime = Date.now();
76
+ wallClockSeconds = Math.floor((endTime - startTime) / 1000);
77
+ }
78
+ let specToIngestSeconds;
79
+ if (manifest?.spec_started_at && manifest?.spec_completed_at) {
80
+ const startTime = new Date(manifest.spec_started_at).getTime();
81
+ const endTime = new Date(manifest.spec_completed_at).getTime();
82
+ if (!isNaN(startTime) && !isNaN(endTime) && endTime > startTime) {
83
+ specToIngestSeconds = Math.floor((endTime - startTime) / 1000);
84
+ }
85
+ }
86
+ return {
87
+ schema_version: 1,
88
+ run_id: runId,
89
+ worker_cost_usd: workerCostUsd,
90
+ planner_cost_usd: plannerCostUsd,
91
+ total_tasks: totalTasks,
92
+ auto_completed: autoCompleted,
93
+ escalated: escalated,
94
+ rescued: rescued,
95
+ skipped: skipped,
96
+ total_retries: totalRetries + totalRetriesFromCosts,
97
+ auto_completion_rate: autoCompletionRate,
98
+ wall_clock_seconds: wallClockSeconds,
99
+ spec_to_ingest_seconds: specToIngestSeconds,
100
+ };
101
+ }
102
+ export function formatScorecard(scorecard) {
103
+ const lines = [];
104
+ lines.push('=== True-Cost Scorecard ===');
105
+ lines.push(`Run: ${scorecard.run_id}`);
106
+ lines.push('');
107
+ lines.push(`Total Tasks: ${scorecard.total_tasks}`);
108
+ lines.push(`Auto Completed: ${scorecard.auto_completed}`);
109
+ lines.push(`Escalated: ${scorecard.escalated}`);
110
+ lines.push(`Rescued: ${scorecard.rescued}`);
111
+ lines.push(`Skipped: ${scorecard.skipped}`);
112
+ lines.push(`Total Retries: ${scorecard.total_retries}`);
113
+ lines.push(`Auto-Completion Rate: ${scorecard.auto_completion_rate.toFixed(1)}%`);
114
+ lines.push('');
115
+ lines.push(`Worker Cost: $${scorecard.worker_cost_usd.toFixed(4)}`);
116
+ lines.push(`Planner Cost: $${scorecard.planner_cost_usd.toFixed(4)}`);
117
+ lines.push(`Total Cost: $${(scorecard.worker_cost_usd + scorecard.planner_cost_usd).toFixed(4)}`);
118
+ lines.push(`Wall Clock: ${scorecard.wall_clock_seconds}s`);
119
+ if (scorecard.spec_to_ingest_seconds != null) {
120
+ lines.push(`Spec-to-Ingest: ${scorecard.spec_to_ingest_seconds}s`);
121
+ }
122
+ return lines.join('\n');
123
+ }
124
+ export function writeScorecard(stwRoot, runId, scorecard) {
125
+ const scorecardPath = join(runDir(stwRoot, runId), 'scorecard.json');
126
+ writeJson(scorecardPath, scorecard);
127
+ }
128
+ //# sourceMappingURL=scorecard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scorecard.js","sourceRoot":"","sources":["../src/scorecard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function getTemplate(name: string): string | null;
2
+ export declare function listTemplates(): string[];