@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,60 @@
1
+ export function stripCodeFences(content) {
2
+ const trimmed = content.trim();
3
+ if (trimmed.startsWith('```')) {
4
+ const firstNewline = trimmed.indexOf('\n');
5
+ const lastFence = trimmed.lastIndexOf('```');
6
+ if (lastFence > firstNewline) {
7
+ return trimmed.slice(firstNewline + 1, lastFence).trim();
8
+ }
9
+ }
10
+ return trimmed;
11
+ }
12
+ export function parseWorkerResponse(task, rawContent) {
13
+ const cleaned = stripCodeFences(rawContent);
14
+ let parsed;
15
+ try {
16
+ parsed = JSON.parse(cleaned);
17
+ }
18
+ catch (error) {
19
+ throw new Error(`Worker response was not valid JSON: ${getErrorMessage(error)}`);
20
+ }
21
+ if (typeof parsed !== 'object' || parsed === null) {
22
+ throw new Error('Worker response must be an object');
23
+ }
24
+ const artifact = parsed;
25
+ if (artifact.schema_version !== 1) {
26
+ throw new Error(`Worker response schema_version must be 1, got ${String(artifact.schema_version)}`);
27
+ }
28
+ if (artifact.task_id !== task.id) {
29
+ throw new Error(`Worker response task_id must be ${task.id}, got ${String(artifact.task_id)}`);
30
+ }
31
+ if (!Array.isArray(artifact.files)) {
32
+ throw new Error('Worker response files must be an array');
33
+ }
34
+ const files = artifact.files.map((file, index) => validateFileWrite(file, index));
35
+ return {
36
+ schema_version: 1,
37
+ task_id: task.id,
38
+ files,
39
+ };
40
+ }
41
+ function validateFileWrite(file, index) {
42
+ if (typeof file !== 'object' || file === null) {
43
+ throw new Error(`Worker response file at index ${index} must be an object`);
44
+ }
45
+ const candidate = file;
46
+ if (typeof candidate.path !== 'string' || candidate.path.length === 0) {
47
+ throw new Error(`Worker response file at index ${index} must include a non-empty path`);
48
+ }
49
+ if (typeof candidate.content !== 'string') {
50
+ throw new Error(`Worker response file at index ${index} must include string content`);
51
+ }
52
+ return {
53
+ path: candidate.path,
54
+ content: candidate.content,
55
+ };
56
+ }
57
+ function getErrorMessage(error) {
58
+ return error instanceof Error ? error.message : String(error);
59
+ }
60
+ //# sourceMappingURL=worker-response.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-response.js","sourceRoot":"","sources":["../src/worker-response.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { ActionableFailureClass, ExecutionObservabilityMode, StwConfig, Task } from './types.js';
2
+ import type { Logger } from './logger.js';
3
+ export type { WorkerFileWrite, WorkerResponseArtifact } from './worker-response.js';
4
+ export interface WorkerResult {
5
+ files_written: string[];
6
+ diff: string;
7
+ token_usage: {
8
+ input_tokens: number;
9
+ output_tokens: number;
10
+ };
11
+ model: string;
12
+ latency_ms: number;
13
+ execution_mode: ExecutionObservabilityMode;
14
+ failure_class?: ActionableFailureClass;
15
+ trimmed_files?: string[];
16
+ }
17
+ export type WorkerDispatchMode = 'single_call' | 'agentic';
18
+ export declare function resolveWorkerDispatchMode(task: Task, config: StwConfig, isRetry?: boolean, logger?: Logger): WorkerDispatchMode;
19
+ export declare function runWorker(task: Task, config: StwConfig, worktreePath: string, taskDir: string, tierOverride?: string, logger?: Logger, verbose?: boolean, attempt?: number, retryReason?: string): Promise<WorkerResult>;
@@ -0,0 +1,347 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ import { dirname, join, relative, resolve } from 'node:path';
3
+ import { computeDiff, revertFiles, runGit } from './git-utils.js';
4
+ import { callProvider } from './provider.js';
5
+ import { buildWorkerPrompt, estimateTokens } from './prompt-builder.js';
6
+ import { buildAgenticPrompt } from './agentic-prompt.js';
7
+ import { ensureDir, fileExists, readText, writeAtomic, writeJson } from './storage.js';
8
+ import { routeTask } from './router.js';
9
+ import { buildWorkerOutputFailureEvent, persistWorkerOutputFailureEvent } from './diagnostic.js';
10
+ import { buildAgenticCommand, formatBackendTranscript, getTaskExecutionObservabilityMode, listChangedFiles, parseAgenticUsage, persistAgenticArtifacts, resolveAgenticTierSelection, } from './agentic-runtime.js';
11
+ import { applyPreviousDiff } from './task-pipeline-helpers.js';
12
+ import { expandScope, isAllowedScopeFile, toRelativePath } from './scope.js';
13
+ import { parseWorkerResponse } from './worker-response.js';
14
+ export function resolveWorkerDispatchMode(task, config, isRetry = false, logger) {
15
+ const workerModesConfig = config.defaults?.worker_modes;
16
+ const modeConfig = isRetry ? workerModesConfig?.retry_with_context : workerModesConfig?.fresh_context;
17
+ const requestedAgentic = task.planner_metadata?.execution_mode === 'agentic' || config.defaults?.execution_mode === 'agentic';
18
+ const modeEnabled = modeConfig?.enabled ?? true;
19
+ const resolvedMode = requestedAgentic && modeEnabled ? 'agentic' : 'single_call';
20
+ logger?.debug(`Resolved dispatch mode: ${resolvedMode}`, {
21
+ worker_modes: workerModesConfig ? JSON.stringify(workerModesConfig) : undefined,
22
+ mode_context: isRetry ? 'retry_with_context' : 'fresh_context',
23
+ mode_enabled: modeConfig?.enabled,
24
+ });
25
+ return resolvedMode;
26
+ }
27
+ export async function runWorker(task, config, worktreePath, taskDir, tierOverride, logger, verbose, attempt = 1, retryReason) {
28
+ const dispatchMode = resolveWorkerDispatchMode(task, config, attempt > 1, logger);
29
+ if (dispatchMode === 'agentic') {
30
+ return runAgenticWorker(task, config, worktreePath, taskDir, logger, verbose, attempt);
31
+ }
32
+ const effectiveTier = tierOverride ?? task.model_tier;
33
+ const route = routeTask({
34
+ risk: task.risk,
35
+ task_type: task.task_type,
36
+ model_tier: effectiveTier,
37
+ }, config);
38
+ const providerConfig = config.providers[task.provider_hint ?? route.provider];
39
+ if (!providerConfig) {
40
+ throw new Error(`Provider not configured: ${task.provider_hint ?? route.provider}`);
41
+ }
42
+ let effectiveRetryReason = retryReason;
43
+ if (attempt > 1) {
44
+ const diffResult = applyPreviousDiff(taskDir, worktreePath, attempt);
45
+ if (diffResult.warning) {
46
+ effectiveRetryReason = effectiveRetryReason
47
+ ? `${effectiveRetryReason}\n${diffResult.warning}`
48
+ : diffResult.warning;
49
+ }
50
+ }
51
+ const prompt = buildWorkerPrompt({
52
+ repoRoot: worktreePath,
53
+ task,
54
+ taskDir,
55
+ retryReason: effectiveRetryReason,
56
+ });
57
+ const response = await callProvider({
58
+ model: route.model,
59
+ messages: [{ role: 'user', content: prompt }],
60
+ timeout_ms: config.defaults.api_timeout_seconds * 1000,
61
+ response_format: 'json',
62
+ }, providerConfig, config.defaults);
63
+ const rawContent = response.content ?? '';
64
+ if (!rawContent) {
65
+ throw new Error('Worker returned empty/null response content');
66
+ }
67
+ writeAtomic(join(taskDir, 'response_raw.txt'), rawContent);
68
+ if (verbose) {
69
+ logger?.info('Raw API Response (single_call mode)', { response: rawContent });
70
+ }
71
+ let artifact;
72
+ try {
73
+ artifact = parseWorkerResponse(task, rawContent);
74
+ }
75
+ catch (error) {
76
+ const errorMessage = error instanceof Error ? error.message : String(error);
77
+ const failureEvent = buildWorkerOutputFailureEvent(task.id, rawContent, errorMessage);
78
+ persistWorkerOutputFailureEvent(taskDir, failureEvent);
79
+ logger?.warn('Worker output parse failure', {
80
+ failure_class: failureEvent.failure_class,
81
+ message: errorMessage,
82
+ raw_content_length: failureEvent.raw_content_length,
83
+ });
84
+ throw error;
85
+ }
86
+ writeJson(join(taskDir, 'response.json'), artifact);
87
+ const expandedScopeFiles = expandScope(task);
88
+ const originalScopeFiles = [...task.scope.files, ...(task.scope.new_files ?? [])];
89
+ const inScopeFiles = [];
90
+ const outOfScopeFiles = [];
91
+ for (const file of artifact.files) {
92
+ const normalizedPath = toRelativePath(file.path);
93
+ const absolutePath = resolve(worktreePath, normalizedPath);
94
+ if (relative(worktreePath, absolutePath).startsWith('..'))
95
+ throw new Error(`Worker attempted to write outside worktree: ${file.path}`);
96
+ ensureDir(dirname(absolutePath));
97
+ writeAtomic(absolutePath, file.content);
98
+ if (isAllowedScopeFile(expandedScopeFiles, normalizedPath)) {
99
+ if (!isAllowedScopeFile(originalScopeFiles, normalizedPath))
100
+ logger?.info('Scope auto-expansion allowed file', { file: normalizedPath, task_id: task.id });
101
+ inScopeFiles.push(normalizedPath);
102
+ }
103
+ else {
104
+ outOfScopeFiles.push(normalizedPath);
105
+ }
106
+ }
107
+ let trimmedFiles;
108
+ if (outOfScopeFiles.length > 0) {
109
+ if (config.defaults.scope_trim_enabled !== false) {
110
+ const attemptDir = join(taskDir, 'attempts', String(attempt));
111
+ ensureDir(attemptDir);
112
+ const scopeTrimDiff = computeDiff(worktreePath, outOfScopeFiles);
113
+ writeAtomic(join(attemptDir, 'scope-trim.patch'), scopeTrimDiff);
114
+ revertFiles(worktreePath, outOfScopeFiles);
115
+ logger?.warn('Scope trim: reverted out-of-scope files', {
116
+ files: outOfScopeFiles,
117
+ task_id: task.id,
118
+ });
119
+ writeJson(join(attemptDir, 'trimmed-files.json'), { trimmed_files: outOfScopeFiles });
120
+ trimmedFiles = outOfScopeFiles;
121
+ if (inScopeFiles.length === 0) {
122
+ throw new Error('No in-scope changes remain');
123
+ }
124
+ }
125
+ else {
126
+ revertFiles(worktreePath, outOfScopeFiles);
127
+ throw new Error(`Worker attempted to write undeclared file: ${outOfScopeFiles[0]}`);
128
+ }
129
+ }
130
+ const filesWritten = inScopeFiles;
131
+ const diff = computeDiff(worktreePath, filesWritten);
132
+ writeAtomic(join(taskDir, 'diff.patch'), diff);
133
+ return {
134
+ files_written: filesWritten,
135
+ diff,
136
+ token_usage: response.usage,
137
+ model: response.model,
138
+ latency_ms: response.latency_ms,
139
+ execution_mode: getTaskExecutionObservabilityMode(task),
140
+ ...(trimmedFiles ? { trimmed_files: trimmedFiles } : {}),
141
+ };
142
+ }
143
+ function runAgenticWorker(task, config, worktreePath, taskDir, logger, verbose, attempt = 1) {
144
+ const { backend, model } = resolveAgenticTierSelection(task, config);
145
+ const backendConfig = config.defaults.agentic?.backends?.[backend];
146
+ const executionMode = getTaskExecutionObservabilityMode(task);
147
+ if (backendConfig?.enabled === false) {
148
+ throw new Error(`Agentic backend ${backend} is disabled in config`);
149
+ }
150
+ applyPreviousDiff(taskDir, worktreePath, attempt);
151
+ const prompt = buildAgenticPrompt({
152
+ repoRoot: worktreePath,
153
+ task,
154
+ taskDir,
155
+ });
156
+ const command = buildAgenticCommand(backend, prompt, join(taskDir, 'agentic_prompt.md'), config.defaults.agentic?.backends?.[backend]?.command, model);
157
+ const preWorkerHead = runGit(worktreePath, ['rev-parse', 'HEAD']).trim();
158
+ const startedAt = Date.now();
159
+ let transcript = '';
160
+ let rawOutput = '';
161
+ let exitCode = 0;
162
+ try {
163
+ const output = execFileSync(command[0] ?? '', command.slice(1), {
164
+ cwd: worktreePath,
165
+ encoding: 'utf-8',
166
+ stdio: ['ignore', 'pipe', 'pipe'],
167
+ timeout: task.timeout_minutes * 60_000,
168
+ });
169
+ rawOutput = String(output);
170
+ transcript = formatBackendTranscript(backend, rawOutput, backendConfig);
171
+ if (verbose) {
172
+ logger?.info('Agentic backend output', { backend, output: rawOutput });
173
+ }
174
+ }
175
+ catch (error) {
176
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
177
+ const e = error;
178
+ const errParts = [e.stdout, e.stderr, e.message].map((v) => (v ? String(v) : '')).filter(Boolean);
179
+ transcript = formatBackendTranscript(backend, errParts.join('\n'), backendConfig);
180
+ exitCode = e.status ?? 1;
181
+ const failureClass = task.planner_metadata?.fallback_to_single_call === true
182
+ ? 'backend_unavailable_during_fallback'
183
+ : 'backend_invocation_or_setup_failure';
184
+ persistAgenticArtifacts(taskDir, {
185
+ task,
186
+ backend,
187
+ command,
188
+ transcript,
189
+ changedFiles: [],
190
+ exitCode,
191
+ model,
192
+ failureClass,
193
+ });
194
+ logger?.warn('Agentic backend failed', { backend, exit_code: exitCode, failure_class: failureClass });
195
+ throw new Error(`Agentic backend ${backend} failed with exit code ${exitCode}`);
196
+ }
197
+ // Detect changes from both uncommitted files (git status) and committed files (git diff against pre-worker HEAD).
198
+ // Some agentic backends (e.g. OpenCode) commit changes themselves, making git status return empty.
199
+ const uncommitted = listChangedFiles(runGit(worktreePath, ['status', '--porcelain']), toRelativePath);
200
+ const currentHead = runGit(worktreePath, ['rev-parse', 'HEAD']).trim();
201
+ const committed = currentHead !== preWorkerHead
202
+ ? runGit(worktreePath, ['diff', '--name-only', preWorkerHead, currentHead])
203
+ .split('\n')
204
+ .filter((line) => line.trim().length > 0)
205
+ .map((filePath) => toRelativePath(filePath))
206
+ : [];
207
+ const changedFiles = [...new Set([...uncommitted, ...committed])];
208
+ if (changedFiles.length === 0) {
209
+ const failureClass = 'no_useful_in_scope_change';
210
+ persistAgenticArtifacts(taskDir, {
211
+ task,
212
+ backend,
213
+ command,
214
+ transcript,
215
+ changedFiles,
216
+ exitCode,
217
+ model,
218
+ failureClass,
219
+ });
220
+ throw new Error(`Agentic backend ${backend} produced no in-scope changes`);
221
+ }
222
+ const expandedScopeFilesAgentic = expandScope(task);
223
+ const originalScopeAgentic = [...task.scope.files, ...(task.scope.new_files ?? [])];
224
+ const inScopeFilesAgentic = [];
225
+ const outOfScopeFilesAgentic = [];
226
+ for (const fp of changedFiles) {
227
+ if (isAllowedScopeFile(expandedScopeFilesAgentic, fp)) {
228
+ if (!isAllowedScopeFile(originalScopeAgentic, fp))
229
+ logger?.info('Scope auto-expansion allowed agentic file', { file: fp, task_id: task.id });
230
+ inScopeFilesAgentic.push(fp);
231
+ }
232
+ else {
233
+ outOfScopeFilesAgentic.push(fp);
234
+ }
235
+ }
236
+ let trimmedFilesAgentic;
237
+ if (outOfScopeFilesAgentic.length > 0) {
238
+ if (config.defaults.scope_trim_enabled !== false) {
239
+ const attemptDir = join(taskDir, 'attempts', String(attempt));
240
+ ensureDir(attemptDir);
241
+ const scopeTrimDiff = computeDiff(worktreePath, outOfScopeFilesAgentic, { baseRef: preWorkerHead });
242
+ writeAtomic(join(attemptDir, 'scope-trim.patch'), scopeTrimDiff);
243
+ runGit(worktreePath, ['reset', '--soft', preWorkerHead]);
244
+ for (const file of outOfScopeFilesAgentic) {
245
+ runGit(worktreePath, ['restore', '--staged', '--', file]);
246
+ }
247
+ for (const file of outOfScopeFilesAgentic) {
248
+ try {
249
+ runGit(worktreePath, ['cat-file', '-e', `${preWorkerHead}:${file}`]);
250
+ runGit(worktreePath, ['restore', '--', file]);
251
+ }
252
+ catch {
253
+ runGit(worktreePath, ['clean', '-f', '--', file]);
254
+ }
255
+ }
256
+ if (inScopeFilesAgentic.length > 0) {
257
+ runGit(worktreePath, ['commit', '-m', 'worker changes (scope-trimmed)']);
258
+ }
259
+ logger?.warn('Agentic scope trim: reverted out-of-scope files', {
260
+ files: outOfScopeFilesAgentic,
261
+ task_id: task.id,
262
+ });
263
+ writeJson(join(attemptDir, 'trimmed-files.json'), { trimmed_files: outOfScopeFilesAgentic });
264
+ trimmedFilesAgentic = outOfScopeFilesAgentic;
265
+ if (inScopeFilesAgentic.length === 0) {
266
+ persistAgenticArtifacts(taskDir, {
267
+ task,
268
+ backend,
269
+ command,
270
+ transcript,
271
+ changedFiles: [],
272
+ exitCode,
273
+ model,
274
+ failureClass: 'no_useful_in_scope_change',
275
+ });
276
+ throw new Error('No in-scope changes remain after agentic trim');
277
+ }
278
+ }
279
+ else {
280
+ const failureClass = 'out_of_scope_mutation';
281
+ persistAgenticArtifacts(taskDir, {
282
+ task,
283
+ backend,
284
+ command,
285
+ transcript,
286
+ changedFiles,
287
+ exitCode,
288
+ model,
289
+ failureClass,
290
+ });
291
+ throw new Error(`Agentic backend attempted to change undeclared file: ${outOfScopeFilesAgentic[0]}`);
292
+ }
293
+ }
294
+ const filteredChangedFiles = inScopeFilesAgentic.length > 0 ? inScopeFilesAgentic : changedFiles;
295
+ const diff = computeDiff(worktreePath, filteredChangedFiles, { baseRef: preWorkerHead });
296
+ writeAtomic(join(taskDir, 'diff.patch'), diff);
297
+ persistAgenticArtifacts(taskDir, {
298
+ task,
299
+ backend,
300
+ command,
301
+ transcript,
302
+ changedFiles: filteredChangedFiles,
303
+ exitCode,
304
+ model,
305
+ });
306
+ // Parse real token usage from structured JSON output (step_finish events).
307
+ // Falls back to file-size estimation if JSON parsing yields nothing.
308
+ const parsedUsage = parseAgenticUsage(rawOutput);
309
+ let tokenUsage;
310
+ if (parsedUsage) {
311
+ tokenUsage = { input_tokens: parsedUsage.input_tokens, output_tokens: parsedUsage.output_tokens };
312
+ logger?.info('Parsed agentic usage from structured output', {
313
+ steps: parsedUsage.steps,
314
+ input_tokens: parsedUsage.input_tokens,
315
+ output_tokens: parsedUsage.output_tokens,
316
+ cost_usd: parsedUsage.cost_usd,
317
+ });
318
+ }
319
+ else {
320
+ tokenUsage = { input_tokens: 0, output_tokens: 0 };
321
+ try {
322
+ const promptPath = join(taskDir, 'agentic_prompt.md');
323
+ const transcriptPath = join(taskDir, 'agentic_transcript.txt');
324
+ if (fileExists(promptPath)) {
325
+ tokenUsage.input_tokens = estimateTokens(readText(promptPath));
326
+ }
327
+ if (fileExists(transcriptPath)) {
328
+ tokenUsage.output_tokens = estimateTokens(readText(transcriptPath));
329
+ }
330
+ logger?.info('Fell back to file-size token estimation (no structured output)');
331
+ }
332
+ catch {
333
+ // Fall back to zero counts if files can't be read — don't crash the worker.
334
+ tokenUsage = { input_tokens: 0, output_tokens: 0 };
335
+ }
336
+ }
337
+ return {
338
+ files_written: filteredChangedFiles,
339
+ diff,
340
+ token_usage: tokenUsage,
341
+ model: model ?? backend,
342
+ latency_ms: Date.now() - startedAt,
343
+ execution_mode: executionMode,
344
+ ...(trimmedFilesAgentic ? { trimmed_files: trimmedFilesAgentic } : {}),
345
+ };
346
+ }
347
+ //# sourceMappingURL=worker-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-runner.js","sourceRoot":"","sources":["../src/worker-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ export interface WorktreeInfo {
2
+ path: string;
3
+ commit: string;
4
+ branch: string;
5
+ }
6
+ export interface CleanupEligibility {
7
+ eligible: boolean;
8
+ reason?: string;
9
+ }
10
+ export interface CleanupResult {
11
+ runId: string;
12
+ worktreesPruned: number;
13
+ branchesDeleted: string[];
14
+ artifactsDeleted: string[];
15
+ skipped: boolean;
16
+ skipReason?: string;
17
+ }
18
+ export declare function listOrphanedWorktrees(repoRoot: string, runId?: string): WorktreeInfo[];
19
+ export declare function cleanupRunWorktrees(repoRoot: string, runId: string, opts?: {
20
+ dryRun?: boolean;
21
+ preservedPaths?: string[];
22
+ taskIds?: string[];
23
+ }): WorktreeInfo[];
24
+ export declare function checkRunEligibility(stwRoot: string, runId: string, options: {
25
+ gitlabAvailable: boolean;
26
+ force: boolean;
27
+ }): CleanupEligibility;
28
+ export declare function isGitlabAvailable(): boolean;
29
+ export declare function listTaskBranches(repoRoot: string, runId: string, taskIds?: string[]): string[];
30
+ export declare function deleteTaskBranches(repoRoot: string, runId: string, opts?: {
31
+ dryRun?: boolean;
32
+ taskIds?: string[];
33
+ }): string[];
34
+ export declare function cleanupRunArtifacts(stwRoot: string, runId: string, opts?: {
35
+ dryRun?: boolean;
36
+ }): string[];
37
+ export declare function cleanupRun(stwRoot: string, repoRoot: string, runId: string, opts: {
38
+ dryRun: boolean;
39
+ artifacts: boolean;
40
+ force: boolean;
41
+ gitlabAvailable: boolean;
42
+ }): CleanupResult;
43
+ export declare function listEligibleRuns(stwRoot: string): string[];
44
+ export declare function listStaleRuns(stwRoot: string, maxAgeDays?: number): string[];