salmon-loop 0.2.13 → 0.3.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 (224) hide show
  1. package/dist/cli/argv/headless-detection.js +27 -0
  2. package/dist/cli/chat-flow.js +11 -0
  3. package/dist/cli/chat.js +160 -24
  4. package/dist/cli/commands/chat.js +14 -7
  5. package/dist/cli/commands/flow-mode.js +63 -0
  6. package/dist/cli/commands/registry.js +2 -0
  7. package/dist/cli/commands/run/benchmark-artifacts.js +41 -0
  8. package/dist/cli/commands/run/early-errors.js +23 -0
  9. package/dist/cli/commands/run/handler.js +115 -27
  10. package/dist/cli/commands/run/headless-error-writer.js +8 -0
  11. package/dist/cli/commands/run/loop-params.js +2 -0
  12. package/dist/cli/commands/run/mode.js +2 -5
  13. package/dist/cli/commands/run/parse-options.js +16 -0
  14. package/dist/cli/commands/run/persist-session.js +10 -1
  15. package/dist/cli/commands/run/preflight.js +10 -0
  16. package/dist/cli/commands/run/reporter-factory.js +4 -0
  17. package/dist/cli/commands/run/runtime-llm.js +38 -11
  18. package/dist/cli/commands/run/runtime-options.js +2 -2
  19. package/dist/cli/commands/serve.js +97 -77
  20. package/dist/cli/commands/tool-names.js +78 -78
  21. package/dist/cli/headless/anthropic-stream-normalized-encoder.js +6 -1
  22. package/dist/cli/headless/json-protocol.js +37 -0
  23. package/dist/cli/headless/native-stream-normalized-encoder.js +6 -1
  24. package/dist/cli/headless/protocol-metadata.js +22 -0
  25. package/dist/cli/headless/stream-json-protocol.js +34 -1
  26. package/dist/cli/index.js +6 -4
  27. package/dist/cli/locales/en.js +30 -6
  28. package/dist/cli/program-bootstrap.js +10 -5
  29. package/dist/cli/program-commands.js +5 -1
  30. package/dist/cli/reporters/anthropic-stream.js +7 -1
  31. package/dist/cli/reporters/json.js +4 -0
  32. package/dist/cli/reporters/stream-json.js +17 -2
  33. package/dist/cli/run-cli.js +5 -3
  34. package/dist/cli/slash/runtime.js +27 -12
  35. package/dist/cli/ui/components/CommandInput.js +7 -3
  36. package/dist/cli/ui/components/CommandSuggestionList.js +1 -1
  37. package/dist/cli/utils/command-option-source.js +13 -0
  38. package/dist/cli/utils/verify-resolver.js +8 -4
  39. package/dist/cli/utils/worktree-prepare-resolver.js +7 -3
  40. package/dist/core/adapters/fs/file-adapter.js +6 -0
  41. package/dist/core/adapters/fs/filesystem.js +2 -1
  42. package/dist/core/adapters/git/git-adapter.js +78 -1
  43. package/dist/core/backends/salmon-loop/task-executor.js +1 -0
  44. package/dist/core/benchmark/patch-artifact.js +124 -0
  45. package/dist/core/benchmark/swe-bench.js +25 -0
  46. package/dist/core/config/load.js +18 -11
  47. package/dist/core/config/resolve-llm.js +12 -0
  48. package/dist/core/config/resolvers/server.js +0 -6
  49. package/dist/core/config/validate.js +73 -21
  50. package/dist/core/context/gatherers/metadata-gatherer.js +1 -0
  51. package/dist/core/context/gatherers/ripgrep-gatherer.js +84 -2
  52. package/dist/core/context/keywords.js +18 -4
  53. package/dist/core/context/service-deps.js +2 -2
  54. package/dist/core/context/service.js +8 -0
  55. package/dist/core/context/steps/context-gather.js +38 -0
  56. package/dist/core/context/summarization/summarizer.js +55 -12
  57. package/dist/core/context/targeting/target-resolver.js +4 -4
  58. package/dist/core/extensions/index.js +23 -5
  59. package/dist/core/extensions/merge.js +14 -0
  60. package/dist/core/extensions/paths.js +31 -0
  61. package/dist/core/extensions/schemas.js +8 -5
  62. package/dist/core/facades/cli-chat.js +6 -2
  63. package/dist/core/facades/cli-command-chat.js +1 -0
  64. package/dist/core/facades/cli-command-tool-names.js +2 -0
  65. package/dist/core/facades/cli-observability.js +1 -1
  66. package/dist/core/facades/cli-program-bootstrap.js +1 -0
  67. package/dist/core/facades/cli-run-handler.js +4 -2
  68. package/dist/core/facades/cli-run-persist-session.js +1 -0
  69. package/dist/core/facades/cli-serve.js +4 -4
  70. package/dist/core/facades/cli-utils-worktree.js +1 -1
  71. package/dist/core/failure/diagnostics.js +53 -1
  72. package/dist/core/grizzco/dsl/llm-strategy.js +4 -1
  73. package/dist/core/grizzco/engine/outcome/loop-result-mapper.js +67 -9
  74. package/dist/core/grizzco/engine/pipeline/pipeline.js +6 -2
  75. package/dist/core/grizzco/engine/transaction/attempt-failure.js +90 -15
  76. package/dist/core/grizzco/engine/transaction/report-mapper.js +17 -3
  77. package/dist/core/grizzco/engine/transaction/transaction-runner.js +165 -7
  78. package/dist/core/grizzco/flows/AutopilotFlow.js +18 -0
  79. package/dist/core/grizzco/flows/flow-dispatch.js +11 -0
  80. package/dist/core/grizzco/steps/answer.js +13 -14
  81. package/dist/core/grizzco/steps/autopilot.js +396 -0
  82. package/dist/core/grizzco/steps/cache-sharing.js +29 -0
  83. package/dist/core/grizzco/steps/explore.js +37 -21
  84. package/dist/core/grizzco/steps/generateReview.js +2 -5
  85. package/dist/core/grizzco/steps/patch/apply-check.js +10 -0
  86. package/dist/core/grizzco/steps/patch/diff-normalization.js +70 -0
  87. package/dist/core/grizzco/steps/patch/diff-salvage.js +46 -0
  88. package/dist/core/grizzco/steps/patch/prompt-input.js +42 -0
  89. package/dist/core/grizzco/steps/patch.js +105 -146
  90. package/dist/core/grizzco/steps/plan.js +101 -25
  91. package/dist/core/grizzco/steps/preflight.js +5 -6
  92. package/dist/core/grizzco/steps/request-assembly.js +78 -0
  93. package/dist/core/grizzco/steps/research.js +39 -36
  94. package/dist/core/grizzco/steps/tool-runtime.js +47 -0
  95. package/dist/core/grizzco/steps/verify-shared.js +23 -0
  96. package/dist/core/grizzco/steps/verify.js +13 -21
  97. package/dist/core/interaction/orchestration/facade.js +1 -1
  98. package/dist/core/llm/ai-sdk/chat-executor.js +2 -0
  99. package/dist/core/llm/ai-sdk/high-level-phase-specs.js +63 -0
  100. package/dist/core/llm/ai-sdk/message-mapper.js +40 -10
  101. package/dist/core/llm/ai-sdk/provider-factory.js +14 -0
  102. package/dist/core/llm/ai-sdk/request-params.js +113 -1
  103. package/dist/core/llm/ai-sdk/result-mapper.js +16 -0
  104. package/dist/core/llm/ai-sdk.js +112 -27
  105. package/dist/core/llm/capabilities.js +12 -0
  106. package/dist/core/llm/contracts/repair.js +36 -30
  107. package/dist/core/llm/errors.js +83 -2
  108. package/dist/core/llm/message-composition.js +7 -22
  109. package/dist/core/llm/phase-router.js +29 -10
  110. package/dist/core/llm/redact.js +28 -3
  111. package/dist/core/llm/registry.js +2 -0
  112. package/dist/core/llm/request-augmentation.js +55 -0
  113. package/dist/core/llm/request-envelope.js +334 -0
  114. package/dist/core/llm/shared-request-assembly.js +35 -0
  115. package/dist/core/llm/stream-utils.js +13 -4
  116. package/dist/core/llm/utils.js +18 -29
  117. package/dist/core/memory/relevant-retrieval.js +144 -0
  118. package/dist/core/observability/logger.js +11 -2
  119. package/dist/core/patch/diff.js +1 -0
  120. package/dist/core/prompts/registry.js +39 -2
  121. package/dist/core/prompts/runtime.js +50 -12
  122. package/dist/core/prompts/templates/phases/patch_user.hbs +2 -5
  123. package/dist/core/prompts/templates/phases/research_user.hbs +11 -0
  124. package/dist/core/prompts/templates/phases/review_user.hbs +3 -0
  125. package/dist/core/prompts/templates/system/answer_system.hbs +5 -0
  126. package/dist/core/prompts/templates/system/autopilot_system.hbs +11 -0
  127. package/dist/core/prompts/templates/system/explore_system.hbs +14 -23
  128. package/dist/core/prompts/templates/system/main_system.hbs +4 -16
  129. package/dist/core/prompts/templates/system/patch_system.hbs +39 -8
  130. package/dist/core/prompts/templates/system/plan_system.hbs +86 -1
  131. package/dist/core/prompts/templates/system/research_system.hbs +2 -0
  132. package/dist/core/protocols/a2a/agent-card.js +5 -3
  133. package/dist/core/protocols/a2a/sdk/executor.js +2 -1
  134. package/dist/core/protocols/a2a/sdk/server.js +0 -1
  135. package/dist/core/protocols/acp/formal-agent.js +300 -58
  136. package/dist/core/protocols/acp/handlers.js +5 -1
  137. package/dist/core/protocols/acp/permission-provider.js +1 -1
  138. package/dist/core/protocols/shared/flow-mode-mapping.js +23 -0
  139. package/dist/core/public-capabilities/flow-mode-metadata.js +39 -0
  140. package/dist/core/public-capabilities/projections.js +29 -0
  141. package/dist/core/public-capabilities/registry.js +26 -0
  142. package/dist/core/public-capabilities/types.js +2 -0
  143. package/dist/core/runtime/agent-server-runtime.js +47 -43
  144. package/dist/core/runtime/execution-profile.js +67 -0
  145. package/dist/core/session/artifact-state.js +160 -0
  146. package/dist/core/session/compaction/index.js +183 -0
  147. package/dist/core/session/compaction/microcompact.js +78 -0
  148. package/dist/core/session/compaction/tracking.js +48 -0
  149. package/dist/core/session/compaction/types.js +11 -0
  150. package/dist/core/session/compression.js +8 -0
  151. package/dist/core/session/manager.js +244 -8
  152. package/dist/core/session/pruning-strategy.js +55 -9
  153. package/dist/core/session/replacement-preview-provider.js +24 -0
  154. package/dist/core/session/replacement-state.js +131 -0
  155. package/dist/core/session/resume-repair/pipeline.js +79 -0
  156. package/dist/core/session/resume-repair/stages/load-raw-archive-state.js +40 -0
  157. package/dist/core/session/resume-repair/stages/reattach-runtime-state.js +8 -0
  158. package/dist/core/session/resume-repair/stages/recover-orphaned-branches.js +10 -0
  159. package/dist/core/session/resume-repair/stages/relink-boundary-and-tail.js +36 -0
  160. package/dist/core/session/resume-repair/stages/replay-startup-hooks.js +23 -0
  161. package/dist/core/session/resume-repair/stages/rescue-stale-metadata.js +17 -0
  162. package/dist/core/session/resume-repair/types.js +2 -0
  163. package/dist/core/session/summary-sync.js +164 -13
  164. package/dist/core/session/token-tracker.js +6 -0
  165. package/dist/core/skills/audit.js +34 -0
  166. package/dist/core/skills/bridge.js +84 -7
  167. package/dist/core/skills/discovery.js +94 -0
  168. package/dist/core/skills/feature-flags.js +52 -0
  169. package/dist/core/skills/index.js +1 -1
  170. package/dist/core/skills/loader.js +195 -20
  171. package/dist/core/skills/parser.js +296 -24
  172. package/dist/core/skills/permissions.js +117 -0
  173. package/dist/core/skills/runtime/MicroTaskRunner.js +10 -4
  174. package/dist/core/skills/runtime/SkillRunner.js +240 -61
  175. package/dist/core/strata/layers/shadow-driver/shadow-driver.js +37 -7
  176. package/dist/core/strata/layers/worktree.js +67 -10
  177. package/dist/core/strata/runtime/synchronizer.js +29 -2
  178. package/dist/core/streaming/stream-assembler.js +75 -31
  179. package/dist/core/sub-agent/context-snapshot.js +156 -0
  180. package/dist/core/sub-agent/core/loop.js +1 -1
  181. package/dist/core/sub-agent/core/manager.js +119 -20
  182. package/dist/core/sub-agent/dispatch-policy.js +29 -0
  183. package/dist/core/sub-agent/prefix-consistency.js +48 -0
  184. package/dist/core/sub-agent/registry-defaults.js +4 -0
  185. package/dist/core/sub-agent/tools/task-spawn.js +79 -2
  186. package/dist/core/sub-agent/types.js +134 -5
  187. package/dist/core/tools/audit.js +13 -4
  188. package/dist/core/tools/builtin/ast-grep.js +1 -1
  189. package/dist/core/tools/builtin/ast.js +1 -1
  190. package/dist/core/tools/builtin/benchmark.js +360 -0
  191. package/dist/core/tools/builtin/code-search/backends/rg.js +2 -1
  192. package/dist/core/tools/builtin/code-search/executor.js +6 -1
  193. package/dist/core/tools/builtin/code-search/spec.js +26 -2
  194. package/dist/core/tools/builtin/fs.js +256 -23
  195. package/dist/core/tools/builtin/git.js +2 -2
  196. package/dist/core/tools/builtin/index.js +51 -2
  197. package/dist/core/tools/builtin/interaction.js +8 -1
  198. package/dist/core/tools/builtin/plan.js +37 -15
  199. package/dist/core/tools/builtin/shell.js +1 -1
  200. package/dist/core/tools/loader.js +39 -16
  201. package/dist/core/tools/mapper.js +17 -3
  202. package/dist/core/tools/mcp/client.js +2 -1
  203. package/dist/core/tools/parallel/scheduler.js +35 -4
  204. package/dist/core/tools/permissions/permission-rules.js +5 -10
  205. package/dist/core/tools/policy.js +6 -1
  206. package/dist/core/tools/recoverable-tool-errors.js +10 -0
  207. package/dist/core/tools/router.js +24 -6
  208. package/dist/core/tools/session.js +458 -48
  209. package/dist/core/tools/tool-visibility.js +62 -0
  210. package/dist/core/tools/types.js +9 -1
  211. package/dist/core/types/execution.js +4 -0
  212. package/dist/core/types/flow-mode.js +8 -0
  213. package/dist/core/utils/path.js +52 -0
  214. package/dist/core/verification/runner.js +4 -1
  215. package/dist/core/version.js +17 -0
  216. package/dist/languages/typescript/index.js +4 -1
  217. package/dist/locales/en.js +35 -2
  218. package/dist/utils/eol.js +1 -1
  219. package/package.json +14 -7
  220. package/scripts/fix-es-abstract-compat.js +77 -0
  221. package/dist/core/runtime/fastify-server-bundle.js +0 -26
  222. package/dist/core/runtime/sidecar-fastify-plugin.js +0 -35
  223. package/dist/core/runtime/sidecar-paths.js +0 -47
  224. package/dist/core/runtime/sidecar-route-catalog.js +0 -103
@@ -1,12 +1,13 @@
1
1
  import { randomUUID } from 'crypto';
2
- import { buildSessionConversationContext, createPluginRegistry, createPromptRegistry, getExitCode, getDefaultSessionContextBudgetTokens, getLogger, normalizePermissionMode, setPluginRegistry, setPromptRegistry, } from '../../../core/facades/cli-run-handler.js';
2
+ import { buildEffectiveConversationContext, createPluginRegistry, createPromptRegistry, getExitCode, getDefaultSessionContextBudgetTokens, getLogger, normalizePermissionMode, resolveExecutionProfile, SilentReporter, setPluginRegistry, setPromptRegistry, } from '../../../core/facades/cli-run-handler.js';
3
3
  import { createStdoutWriter } from '../../headless/stdout-writer.js';
4
4
  import { text } from '../../locales/index.js';
5
- import { StderrLogReporter } from '../../reporters/stderr-log-reporter.js';
5
+ import { getOptionValueSourceWithGlobalFallback } from '../../utils/command-option-source.js';
6
6
  import { createOutcomeReporter } from '../../utils/outcome-reporter.js';
7
7
  import { resolveOutputFormat } from '../../utils/output-format.js';
8
8
  import { resolveCliCommonOptions } from '../../utils/resolve-cli-config.js';
9
9
  import { buildRunAssistantMessage } from './assistant-message.js';
10
+ import { attachRunBenchmarkArtifacts } from './benchmark-artifacts.js';
10
11
  import { resolveRunConfig } from './config-resolution.js';
11
12
  import { handleEarlyRunCommandErrors } from './early-errors.js';
12
13
  import { executeRunLoop } from './execute.js';
@@ -58,12 +59,16 @@ export async function handleRunCommand(options, command) {
58
59
  const headlessIncludeToolOutput = parsed.headlessIncludeToolOutput;
59
60
  const headlessIncludeAuthorizationDecisions = parsed.headlessIncludeAuthorizationDecisions;
60
61
  const allowOutsideCacheRoot = parsed.allowOutsideCacheRoot;
62
+ const exportPatchPath = parsed.exportPatchPath;
63
+ const sweBenchInstanceId = parsed.sweBenchInstanceId;
64
+ const sweBenchModelName = parsed.sweBenchModelName;
65
+ const sweBenchPredictionsPath = parsed.sweBenchPredictionsPath;
61
66
  const stdoutWriter = createStdoutWriter();
62
67
  const instruction = parsed.instruction;
63
68
  const printMode = Boolean(printInstruction);
64
69
  const useGui = !headlessOutput && !printMode && allOptions.gui !== false && process.stdout.isTTY;
65
70
  if (headlessOutput) {
66
- getLogger().setReporter(new StderrLogReporter());
71
+ getLogger().setReporter(new SilentReporter());
67
72
  }
68
73
  const wantSessionPersistence = !allOptions.printConfig &&
69
74
  (headlessOutput ||
@@ -94,6 +99,9 @@ export async function handleRunCommand(options, command) {
94
99
  continueSession,
95
100
  resumeSessionId,
96
101
  jsonSchemaSpec,
102
+ sweBenchInstanceId,
103
+ sweBenchModelName,
104
+ sweBenchPredictionsPath,
97
105
  sessionIdForOutput,
98
106
  headlessErrorWriter,
99
107
  });
@@ -149,6 +157,7 @@ export async function handleRunCommand(options, command) {
149
157
  repoPath: runPath,
150
158
  validate: Boolean(allOptions.validate),
151
159
  useGui,
160
+ headlessOutput,
152
161
  preflightPolicy,
153
162
  });
154
163
  if (allOptions.validate && !instruction)
@@ -158,6 +167,7 @@ export async function handleRunCommand(options, command) {
158
167
  exitCode: params.exitCode,
159
168
  message: params.message,
160
169
  errorCode: params.errorCode,
170
+ auditPath: params.auditPath,
161
171
  repoPath: params.repoPath,
162
172
  instruction: params.instruction,
163
173
  sessionId: sessionIdForOutput ?? randomUUID(),
@@ -181,6 +191,7 @@ export async function handleRunCommand(options, command) {
181
191
  resolvedConfig,
182
192
  cliOptions: allOptions,
183
193
  outputFormat,
194
+ headlessOutput,
184
195
  writeJsonFailure: ({ message, repoPath }) => writeJsonFailure({ message, repoPath }),
185
196
  });
186
197
  if (!runtimeOptions.ok) {
@@ -205,24 +216,54 @@ export async function handleRunCommand(options, command) {
205
216
  return;
206
217
  }
207
218
  const instructionText = instruction;
208
- const rawPermissionMode = allOptions.mode ?? resolvedConfig.permissionMode ?? 'interactive';
209
- const permissionMode = normalizePermissionMode(rawPermissionMode);
210
- if (!permissionMode) {
211
- getLogger().error(`Invalid --mode "${String(rawPermissionMode)}". Expected "interactive" or "yolo".`);
219
+ const actModeOptionSource = typeof command.getOptionValueSource === 'function'
220
+ ? command.getOptionValueSource('actMode')
221
+ : undefined;
222
+ const rawActMode = actModeOptionSource === 'cli' ? allOptions.actMode : undefined;
223
+ const mode = resolveRunMode(rawActMode);
224
+ if (!mode) {
225
+ const invalidMode = String(rawActMode ?? allOptions.actMode);
226
+ getLogger().error(text.cli.invalidActMode(invalidMode));
227
+ if (outputFormat === 'json') {
228
+ writeJsonFailure({
229
+ message: text.cli.invalidActMode(invalidMode),
230
+ errorCode: 'USAGE_ERROR',
231
+ instruction,
232
+ repoPath: runPath,
233
+ });
234
+ }
235
+ else if (outputFormat === 'stream-json') {
236
+ headlessErrorWriter.writeUsageError({
237
+ sessionId: sessionIdForOutput ?? randomUUID(),
238
+ message: text.cli.invalidActMode(invalidMode),
239
+ instruction,
240
+ });
241
+ }
212
242
  process.exitCode = 1;
213
243
  return;
214
244
  }
215
- const rawMode = String(allOptions.actMode || 'patch');
216
- const mode = resolveRunMode(rawMode);
217
- if (!mode) {
218
- getLogger().error(text.cli.invalidActMode(rawMode));
245
+ const profile = resolveExecutionProfile(mode);
246
+ const permissionModeOptionSource = getOptionValueSourceWithGlobalFallback(command, 'mode');
247
+ const rawPermissionMode = (permissionModeOptionSource === 'cli' ? allOptions.mode : undefined) ??
248
+ resolvedConfig.permissionMode ??
249
+ profile.defaultPermissionMode ??
250
+ 'interactive';
251
+ const permissionMode = normalizePermissionMode(rawPermissionMode);
252
+ if (!permissionMode) {
253
+ const message = `Invalid --mode "${String(rawPermissionMode)}". Expected "interactive" or "yolo".`;
254
+ getLogger().error(message);
219
255
  if (outputFormat === 'json') {
220
- writeJsonFailure({ message: text.cli.invalidActMode(rawMode), repoPath: runPath });
256
+ writeJsonFailure({
257
+ message,
258
+ errorCode: 'USAGE_ERROR',
259
+ instruction,
260
+ repoPath: runPath,
261
+ });
221
262
  }
222
263
  else if (outputFormat === 'stream-json') {
223
264
  headlessErrorWriter.writeUsageError({
224
265
  sessionId: sessionIdForOutput ?? randomUUID(),
225
- message: text.cli.invalidActMode(rawMode),
266
+ message,
226
267
  instruction,
227
268
  });
228
269
  }
@@ -235,6 +276,8 @@ export async function handleRunCommand(options, command) {
235
276
  if (outputFormat === 'json') {
236
277
  writeJsonFailure({
237
278
  message: text.cli.invalidEnvironmentMode(rawEnvironmentMode),
279
+ errorCode: 'USAGE_ERROR',
280
+ instruction,
238
281
  repoPath: runPath,
239
282
  });
240
283
  }
@@ -258,8 +301,19 @@ export async function handleRunCommand(options, command) {
258
301
  return;
259
302
  }
260
303
  const extensionResolution = extensionsResult.extensionResolution;
304
+ const operationalHeadlessWarnings = [];
261
305
  if (!effectiveVerify) {
262
- getLogger().warn(text.verify.noCommandFound);
306
+ if (!headlessOutput) {
307
+ getLogger().warn(text.verify.noCommandFound);
308
+ }
309
+ else {
310
+ operationalHeadlessWarnings.push({
311
+ code: 'VERIFY_COMMAND_MISSING',
312
+ message: text.verify.noCommandFound,
313
+ source: 'verify.runtime',
314
+ severity: 'warning',
315
+ });
316
+ }
263
317
  }
264
318
  const verboseLevel = commonOptions.options.verboseLevel;
265
319
  logRunVerboseSummary({
@@ -274,10 +328,14 @@ export async function handleRunCommand(options, command) {
274
328
  dryRun: allOptions.dryRun,
275
329
  configPath: resolvedConfig.source.used ? resolvedConfig.source.path || '' : undefined,
276
330
  });
331
+ let lastKnownAuditPath;
332
+ let activeReporter;
333
+ let activeReporterStarted = false;
277
334
  try {
278
- const { llm } = createRuntimeLlmAndWarn({
335
+ const { llm, headlessWarnings } = createRuntimeLlmAndWarn({
279
336
  llmConfig: resolvedConfig.llm,
280
337
  langfuseEnabled: resolvedConfig.observability.langfuse.enabled,
338
+ headlessOutput,
281
339
  });
282
340
  let structuredOutputState = { ok: true, candidate: null };
283
341
  const reporter = createRunReporter({
@@ -289,6 +347,7 @@ export async function handleRunCommand(options, command) {
289
347
  writer: stdoutWriter,
290
348
  verbose: Boolean(allOptions.verbose),
291
349
  model: resolvedConfig.llm.models?.selectedModelId,
350
+ includeToolInput: headlessIncludeToolInput,
292
351
  getStructuredOutput: () => structuredOutputState.ok ? structuredOutputState.candidate : null,
293
352
  getPayloadOverrides: () => {
294
353
  if (structuredOutputState.ok)
@@ -305,8 +364,11 @@ export async function handleRunCommand(options, command) {
305
364
  structuredOutputError: structuredOutputState.errorReason,
306
365
  };
307
366
  },
367
+ getWarnings: () => [...headlessWarnings, ...operationalHeadlessWarnings],
308
368
  });
369
+ activeReporter = reporter;
309
370
  reporter.onStart(instructionText);
371
+ activeReporterStarted = true;
310
372
  const applyBackOnDirty = allOptions.applyBackOnDirty === 'abort' ? 'abort' : '3way';
311
373
  const outcomeReporter = createOutcomeReporter({
312
374
  enabled: resolvedConfig.observability.langfuse.outcome,
@@ -320,11 +382,18 @@ export async function handleRunCommand(options, command) {
320
382
  process.env.S8P_MODEL;
321
383
  const shouldInjectSessionContext = Boolean(continueSession || resumeSessionId);
322
384
  const conversationContext = shouldInjectSessionContext && sessionManager
323
- ? buildSessionConversationContext(sessionManager.getMessages(), {
385
+ ? buildEffectiveConversationContext({
386
+ llm,
387
+ sessionManager,
324
388
  budgetTokens: getDefaultSessionContextBudgetTokens({ modelId: modelIdForBudget }),
325
- summaryState: sessionManager.getSummaryState(),
326
389
  })
327
390
  : [];
391
+ const artifactHints = shouldInjectSessionContext
392
+ ? sessionManager?.getArtifactState()
393
+ : undefined;
394
+ const replacementState = shouldInjectSessionContext
395
+ ? sessionManager?.getReplacementState()
396
+ : undefined;
328
397
  const loopParams = buildRunLoopParams({
329
398
  instruction: instructionText,
330
399
  verify: effectiveVerify,
@@ -332,17 +401,18 @@ export async function handleRunCommand(options, command) {
332
401
  llm,
333
402
  languagePlugins,
334
403
  conversationContext: conversationContext.length > 0 ? conversationContext : undefined,
404
+ artifactHints,
405
+ replacementState,
335
406
  mode,
336
407
  dryRun: allOptions.dryRun,
337
408
  forceReset: allOptions.forceReset,
338
409
  file: allOptions.file,
339
410
  selection: allOptions.selection,
340
411
  verbose: verboseLevel,
341
- checkpointStrategy: permissionMode === 'yolo' &&
342
- typeof command.getOptionValueSource === 'function' &&
343
- command.getOptionValueSource('checkpointStrategy') !== 'cli'
344
- ? 'direct'
345
- : allOptions.checkpointStrategy,
412
+ checkpointStrategy: getOptionValueSourceWithGlobalFallback(command, 'checkpointStrategy') === 'cli'
413
+ ? allOptions.checkpointStrategy
414
+ : (profile.defaultCheckpointStrategy ??
415
+ allOptions.checkpointStrategy),
346
416
  environmentMode: rawEnvironmentMode,
347
417
  applyBackOnDirty,
348
418
  worktreePrepare: effectiveWorktreePrepare,
@@ -360,11 +430,9 @@ export async function handleRunCommand(options, command) {
360
430
  headlessIncludeToolOutput,
361
431
  headlessIncludeAuthorizationDecisions,
362
432
  allowOutsideCacheRoot,
363
- permissionRules: permissionMode === 'yolo'
364
- ? undefined
365
- : allowedToolRules.length > 0 || disallowedToolRules.length > 0
366
- ? { allow: allowedToolRules, deny: disallowedToolRules }
367
- : undefined,
433
+ permissionRules: allowedToolRules.length > 0 || disallowedToolRules.length > 0
434
+ ? { allow: allowedToolRules, deny: disallowedToolRules }
435
+ : undefined,
368
436
  permissionMode,
369
437
  });
370
438
  const buildAssistantMessage = (result) => buildRunAssistantMessage({ mode, result });
@@ -384,6 +452,15 @@ export async function handleRunCommand(options, command) {
384
452
  logMode: resolvedConfig.ui.logMode,
385
453
  },
386
454
  });
455
+ lastKnownAuditPath = result.auditPath;
456
+ await attachRunBenchmarkArtifacts({
457
+ result,
458
+ repoPath: runPath,
459
+ exportPatchPath,
460
+ sweBenchInstanceId,
461
+ sweBenchModelName,
462
+ sweBenchPredictionsPath,
463
+ });
387
464
  structuredOutputState = await buildStructuredOutputState({
388
465
  outputFormat,
389
466
  jsonSchemaSpec,
@@ -418,12 +495,23 @@ export async function handleRunCommand(options, command) {
418
495
  message: text.cli.unexpectedError(msg),
419
496
  repoPath: runPath,
420
497
  instruction,
498
+ auditPath: lastKnownAuditPath,
421
499
  });
422
500
  }
501
+ else if (outputFormat === 'stream-json' &&
502
+ rawOutputProfile !== 'anthropic' &&
503
+ rawOutputProfile !== 'openai' &&
504
+ activeReporterStarted &&
505
+ activeReporter) {
506
+ const error = new Error(text.cli.unexpectedError(msg));
507
+ error.auditPath = lastKnownAuditPath;
508
+ activeReporter.onError(error);
509
+ }
423
510
  else if (outputFormat === 'stream-json') {
424
511
  headlessErrorWriter.writeUnexpectedError({
425
512
  sessionId: sessionIdForOutput ?? resumeSessionId ?? randomUUID(),
426
513
  message: text.cli.unexpectedError(msg),
514
+ auditPath: lastKnownAuditPath,
427
515
  });
428
516
  }
429
517
  process.exitCode = 1;
@@ -6,6 +6,7 @@ import { OpenAiStreamEncoder } from '../../headless/openai-stream-encoder.js';
6
6
  import { encodeStreamEnd, encodeStreamFailure, encodeStreamStart, } from '../../headless/stream-json-protocol.js';
7
7
  function writeStreamJsonEarlyFailure(params) {
8
8
  const at = new Date();
9
+ let eventSeq = 0;
9
10
  params.writer.writeJsonLine(encodeStreamStart({
10
11
  uuid: randomUUID(),
11
12
  mode: 'run',
@@ -13,12 +14,15 @@ function writeStreamJsonEarlyFailure(params) {
13
14
  sessionId: params.sessionId,
14
15
  instruction: params.instruction,
15
16
  at,
17
+ eventSeq: eventSeq++,
16
18
  }));
17
19
  params.writer.writeJsonLine(encodeStreamFailure({
18
20
  uuid: randomUUID(),
19
21
  sessionId: params.sessionId,
20
22
  at,
21
23
  message: params.message,
24
+ auditPath: params.auditPath,
25
+ eventSeq: eventSeq++,
22
26
  }));
23
27
  params.writer.writeJsonLine(encodeStreamEnd({
24
28
  uuid: randomUUID(),
@@ -26,6 +30,7 @@ function writeStreamJsonEarlyFailure(params) {
26
30
  at,
27
31
  success: false,
28
32
  exitCode: params.exitCode ?? 1,
33
+ eventSeq: eventSeq++,
29
34
  }));
30
35
  }
31
36
  function writeAnthropicEarlyFailure(params) {
@@ -84,6 +89,7 @@ export function createHeadlessErrorWriter(ctx) {
84
89
  instruction: params.instruction,
85
90
  message: params.message,
86
91
  errorCode: params.errorCode,
92
+ auditPath: params.auditPath,
87
93
  exitCode: params.exitCode ?? 1,
88
94
  }));
89
95
  };
@@ -137,6 +143,7 @@ export function createHeadlessErrorWriter(ctx) {
137
143
  message: params.message,
138
144
  repoPath: ctx.repoPath,
139
145
  instruction: params.instruction,
146
+ auditPath: params.auditPath,
140
147
  sessionId,
141
148
  });
142
149
  return;
@@ -163,6 +170,7 @@ export function createHeadlessErrorWriter(ctx) {
163
170
  repoPath: ctx.repoPath,
164
171
  sessionId,
165
172
  message: params.message,
173
+ auditPath: params.auditPath,
166
174
  instruction: params.instruction,
167
175
  });
168
176
  }
@@ -6,6 +6,8 @@ export function buildRunLoopParams(params) {
6
6
  repoPath: params.repoPath,
7
7
  llm: params.llm,
8
8
  conversationContext: params.conversationContext,
9
+ artifactHints: params.artifactHints,
10
+ replacementState: params.replacementState,
9
11
  mode: params.mode,
10
12
  dryRun: params.dryRun,
11
13
  forceReset: params.forceReset,
@@ -1,8 +1,5 @@
1
+ import { parseFlowMode } from '../../../core/types/flow-mode.js';
1
2
  export function resolveRunMode(raw) {
2
- const value = String(raw || 'patch');
3
- if (value === 'patch' || value === 'review' || value === 'debug' || value === 'research') {
4
- return value;
5
- }
6
- return undefined;
3
+ return parseFlowMode(raw || 'autopilot');
7
4
  }
8
5
  //# sourceMappingURL=mode.js.map
@@ -41,6 +41,18 @@ export function parseRunCommandOptions(command) {
41
41
  const headlessIncludeToolOutput = Boolean(allOptions.headlessIncludeToolOutput);
42
42
  const headlessIncludeAuthorizationDecisions = Boolean(allOptions.headlessIncludeAuthorizationDecisions);
43
43
  const allowOutsideCacheRoot = Boolean(allOptions.allowOutsideCacheRoot);
44
+ const exportPatchPath = typeof allOptions.exportPatch === 'string'
45
+ ? allOptions.exportPatch
46
+ : undefined;
47
+ const sweBenchInstanceId = typeof allOptions.sweBenchInstanceId === 'string'
48
+ ? allOptions.sweBenchInstanceId
49
+ : undefined;
50
+ const sweBenchModelName = typeof allOptions.sweBenchModelName === 'string'
51
+ ? allOptions.sweBenchModelName
52
+ : undefined;
53
+ const sweBenchPredictionsPath = typeof allOptions.sweBenchPredictions === 'string'
54
+ ? allOptions.sweBenchPredictions
55
+ : undefined;
44
56
  const instruction = explicitInstruction ?? printInstruction;
45
57
  const allowedToolRules = splitToolRules(allOptions.allowedTools);
46
58
  const disallowedToolRules = splitToolRules(allOptions.disallowedTools);
@@ -60,6 +72,10 @@ export function parseRunCommandOptions(command) {
60
72
  headlessIncludeToolOutput,
61
73
  headlessIncludeAuthorizationDecisions,
62
74
  allowOutsideCacheRoot,
75
+ exportPatchPath,
76
+ sweBenchInstanceId,
77
+ sweBenchModelName,
78
+ sweBenchPredictionsPath,
63
79
  allowedToolRules,
64
80
  disallowedToolRules,
65
81
  };
@@ -1,4 +1,4 @@
1
- import { refreshSessionSummary, } from '../../../core/facades/cli-run-persist-session.js';
1
+ import { buildSessionArtifactStateFromLoopResult, refreshSessionSummary, } from '../../../core/facades/cli-run-persist-session.js';
2
2
  export async function persistRunSession(params) {
3
3
  if (!params.sessionManager || typeof params.instruction !== 'string')
4
4
  return;
@@ -20,6 +20,15 @@ export async function persistRunSession(params) {
20
20
  iterationId,
21
21
  });
22
22
  }
23
+ params.sessionManager.mergeArtifactState(buildSessionArtifactStateFromLoopResult(params.result));
24
+ for (const preview of params.result.artifactHints?.toolResultPreviewArtifacts ?? []) {
25
+ params.sessionManager.freezeReplacementDecision({
26
+ toolResultId: `${preview.label}::${preview.artifact.handle}`,
27
+ decision: 'replaced',
28
+ preview: preview.label,
29
+ sourceArtifactHandle: preview.artifact.handle,
30
+ });
31
+ }
23
32
  await refreshSessionSummary({
24
33
  sessionManager: params.sessionManager,
25
34
  llm: params.llm,
@@ -46,10 +46,18 @@ function buildFailureMessage(details) {
46
46
  }
47
47
  async function runValidateCommand(params) {
48
48
  const maxBytesPerStream = 500_000;
49
+ const env = params.headlessOutput
50
+ ? {
51
+ ...process.env,
52
+ NO_COLOR: process.env.NO_COLOR ?? '1',
53
+ FORCE_COLOR: '0',
54
+ }
55
+ : process.env;
49
56
  const result = await spawnCommand({
50
57
  command: params.cmd,
51
58
  args: params.args,
52
59
  cwd: params.repoPath,
60
+ env,
53
61
  windowsHide: true,
54
62
  maxStdoutBytes: maxBytesPerStream,
55
63
  maxStderrBytes: maxBytesPerStream,
@@ -101,6 +109,7 @@ export async function runPreflight(params) {
101
109
  cmd: lintCommand.command,
102
110
  args: lintCommand.args,
103
111
  useGui: params.useGui,
112
+ headlessOutput: params.headlessOutput,
104
113
  });
105
114
  }
106
115
  catch (error) {
@@ -126,6 +135,7 @@ export async function runPreflight(params) {
126
135
  cmd: testCommand.command,
127
136
  args: testCommand.args,
128
137
  useGui: params.useGui,
138
+ headlessOutput: params.headlessOutput,
129
139
  });
130
140
  }
131
141
  catch (error) {
@@ -22,6 +22,7 @@ export function createRunReporter(params) {
22
22
  repoPath: params.repoPath,
23
23
  sessionId: params.sessionIdForOutput,
24
24
  writer: params.writer,
25
+ includeToolInput: params.includeToolInput,
25
26
  });
26
27
  }
27
28
  if (profile === 'openai') {
@@ -35,6 +36,8 @@ export function createRunReporter(params) {
35
36
  repoPath: params.repoPath,
36
37
  sessionId: params.sessionIdForOutput,
37
38
  writer: params.writer,
39
+ getWarnings: params.getWarnings,
40
+ includeToolInput: params.includeToolInput,
38
41
  });
39
42
  }
40
43
  if (params.outputFormat === 'json') {
@@ -45,6 +48,7 @@ export function createRunReporter(params) {
45
48
  writer: params.writer,
46
49
  getStructuredOutput: params.getStructuredOutput,
47
50
  getPayloadOverrides: params.getPayloadOverrides,
51
+ getWarnings: params.getWarnings,
48
52
  });
49
53
  }
50
54
  return new StandardReporter(params.verbose);
@@ -1,5 +1,32 @@
1
1
  import { createPhaseRoutingLlm, createRuntimeLlm, EXECUTION_PHASES, getLogger, Phase, } from '../../../core/facades/cli-run-runtime-llm.js';
2
2
  import { text } from '../../locales/index.js';
3
+ function runtimeWarningMessage(code, params) {
4
+ if (code === 'API_KEY_MISSING')
5
+ return text.cli.apiKeyMissing;
6
+ if (code === 'PROVIDER_NOT_SUPPORTED') {
7
+ return text.cli.providerNotSupported(String(params.llmType));
8
+ }
9
+ if (code === 'CLIENT_PACKAGE_NOT_SUPPORTED') {
10
+ return text.cli.clientPackageNotSupported(String(params.clientPackage || ''));
11
+ }
12
+ return code;
13
+ }
14
+ function toHeadlessWarning(code, params) {
15
+ if (code === 'API_KEY_MISSING') {
16
+ return {
17
+ code: 'LLM_CREDENTIAL_MISSING',
18
+ message: 'LLM credential not configured; using StubLLM. Configure provider credentials to use a real LLM.',
19
+ source: 'llm.runtime',
20
+ severity: 'warning',
21
+ };
22
+ }
23
+ return {
24
+ code,
25
+ message: runtimeWarningMessage(code, params).replace(/^\[WARN\]\s*/, ''),
26
+ source: 'llm.runtime',
27
+ severity: 'warning',
28
+ };
29
+ }
3
30
  export function createRuntimeLlmAndWarn(params) {
4
31
  const runtimeLlm = createRuntimeLlm(params.llmConfig, {
5
32
  langfuseEnabled: params.langfuseEnabled,
@@ -8,7 +35,7 @@ export function createRuntimeLlmAndWarn(params) {
8
35
  const phaseToProviderModel = params.llmConfig?.routing?.phaseToProviderModel;
9
36
  const phaseLlms = {};
10
37
  if (phaseToProviderModel && typeof phaseToProviderModel === 'object') {
11
- const validPhases = new Set([...EXECUTION_PHASES, Phase.SLASH]);
38
+ const validPhases = new Set([...EXECUTION_PHASES, Phase.SLASH, Phase.AUTOPILOT]);
12
39
  for (const [phase, target] of Object.entries(phaseToProviderModel)) {
13
40
  if (!validPhases.has(phase))
14
41
  continue;
@@ -29,6 +56,7 @@ export function createRuntimeLlmAndWarn(params) {
29
56
  selectedModelId: target.model?.id,
30
57
  selectedModelSlot: target.model?.slot || 'default',
31
58
  },
59
+ capabilities: target.capabilities,
32
60
  };
33
61
  const created = createRuntimeLlm(perPhaseConfig, { langfuseEnabled: params.langfuseEnabled });
34
62
  warnings.push(...created.warnings);
@@ -40,17 +68,16 @@ export function createRuntimeLlmAndWarn(params) {
40
68
  : runtimeLlm.llm;
41
69
  const llmType = params.llmConfig?.type;
42
70
  const clientPackage = params.llmConfig?.clientPackage;
43
- for (const w of Array.from(new Set(warnings))) {
44
- if (w === 'API_KEY_MISSING') {
45
- getLogger().warn(text.cli.apiKeyMissing);
46
- }
47
- else if (w === 'PROVIDER_NOT_SUPPORTED') {
48
- getLogger().warn(text.cli.providerNotSupported(String(llmType)));
49
- }
50
- else if (w === 'CLIENT_PACKAGE_NOT_SUPPORTED') {
51
- getLogger().warn(text.cli.clientPackageNotSupported(String(clientPackage || '')));
71
+ const uniqueWarnings = Array.from(new Set(warnings));
72
+ for (const w of uniqueWarnings) {
73
+ if (!params.headlessOutput) {
74
+ getLogger().warn(runtimeWarningMessage(w, { llmType, clientPackage }));
52
75
  }
53
76
  }
54
- return { llm, warnings: Array.from(new Set(warnings)) };
77
+ return {
78
+ llm,
79
+ warnings: uniqueWarnings,
80
+ headlessWarnings: uniqueWarnings.map((w) => toHeadlessWarning(w, { llmType, clientPackage })),
81
+ };
55
82
  }
56
83
  //# sourceMappingURL=runtime-llm.js.map
@@ -23,8 +23,8 @@ export async function resolveRunRuntimeOptions(params) {
23
23
  if (wantPartialMessages && !llmOutput.kinds.includes('plan')) {
24
24
  llmOutput.kinds.push('plan');
25
25
  }
26
- const effectiveVerify = await resolveVerifyOption(params.repoPath, params.cliOptions.verify, params.resolvedConfig.verify.command);
27
- const effectiveWorktreePrepare = await resolveWorktreePrepareOption(params.repoPath, params.cliOptions.checkpointStrategy, params.cliOptions.worktreePrepare);
26
+ const effectiveVerify = await resolveVerifyOption(params.repoPath, params.cliOptions.verify, params.resolvedConfig.verify.command, { quiet: params.headlessOutput });
27
+ const effectiveWorktreePrepare = await resolveWorktreePrepareOption(params.repoPath, params.cliOptions.checkpointStrategy, params.cliOptions.worktreePrepare, { quiet: params.headlessOutput });
28
28
  return { ok: true, llmOutput, effectiveVerify, effectiveWorktreePrepare };
29
29
  }
30
30
  //# sourceMappingURL=runtime-options.js.map