salmon-loop 0.2.3 → 0.2.16

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 (234) 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 +161 -24
  4. package/dist/cli/commands/chat.js +30 -24
  5. package/dist/cli/commands/context.js +15 -3
  6. package/dist/cli/commands/flow-mode.js +63 -0
  7. package/dist/cli/commands/help-format.js +12 -0
  8. package/dist/cli/commands/registry.js +6 -7
  9. package/dist/cli/commands/run/benchmark-artifacts.js +41 -0
  10. package/dist/cli/commands/run/config-resolution.js +30 -24
  11. package/dist/cli/commands/run/early-errors.js +23 -0
  12. package/dist/cli/commands/run/handler.js +131 -44
  13. package/dist/cli/commands/run/headless-error-writer.js +8 -0
  14. package/dist/cli/commands/run/loop-params.js +3 -0
  15. package/dist/cli/commands/run/mode.js +2 -5
  16. package/dist/cli/commands/run/parse-options.js +18 -2
  17. package/dist/cli/commands/run/persist-session.js +10 -1
  18. package/dist/cli/commands/run/preflight.js +10 -0
  19. package/dist/cli/commands/run/reporter-factory.js +4 -0
  20. package/dist/cli/commands/run/runtime-llm.js +38 -11
  21. package/dist/cli/commands/run/runtime-options.js +2 -2
  22. package/dist/cli/commands/run/validate-options.js +0 -5
  23. package/dist/cli/commands/run/verbose.js +2 -7
  24. package/dist/cli/commands/serve.js +117 -90
  25. package/dist/cli/commands/tool-names.js +78 -78
  26. package/dist/cli/headless/anthropic-stream-normalized-encoder.js +6 -1
  27. package/dist/cli/headless/json-protocol.js +37 -0
  28. package/dist/cli/headless/native-stream-normalized-encoder.js +6 -1
  29. package/dist/cli/headless/protocol-metadata.js +22 -0
  30. package/dist/cli/headless/stream-json-protocol.js +34 -1
  31. package/dist/cli/index.js +6 -4
  32. package/dist/cli/locales/en.js +32 -6
  33. package/dist/cli/program-bootstrap.js +14 -4
  34. package/dist/cli/program-commands.js +9 -1
  35. package/dist/cli/program-options.js +1 -0
  36. package/dist/cli/reporters/anthropic-stream.js +7 -1
  37. package/dist/cli/reporters/json.js +4 -0
  38. package/dist/cli/reporters/stream-json.js +17 -2
  39. package/dist/cli/run-cli.js +5 -3
  40. package/dist/cli/slash/runtime.js +30 -15
  41. package/dist/cli/ui/components/CommandInput.js +7 -3
  42. package/dist/cli/ui/components/CommandSuggestionList.js +1 -1
  43. package/dist/cli/utils/command-option-source.js +13 -0
  44. package/dist/cli/utils/output-format.js +6 -0
  45. package/dist/cli/utils/resolve-cli-config.js +98 -0
  46. package/dist/cli/utils/verbose-level.js +8 -0
  47. package/dist/cli/utils/verify-resolver.js +8 -4
  48. package/dist/cli/utils/worktree-prepare-resolver.js +7 -3
  49. package/dist/core/adapters/fs/file-adapter.js +6 -0
  50. package/dist/core/adapters/fs/filesystem.js +2 -1
  51. package/dist/core/adapters/git/git-adapter.js +78 -1
  52. package/dist/core/benchmark/patch-artifact.js +124 -0
  53. package/dist/core/benchmark/swe-bench.js +25 -0
  54. package/dist/core/config/load.js +39 -18
  55. package/dist/core/config/merge.js +27 -0
  56. package/dist/core/config/paths.js +24 -5
  57. package/dist/core/config/resolve-llm.js +12 -0
  58. package/dist/core/config/resolve.js +7 -5
  59. package/dist/core/config/resolvers/server.js +0 -6
  60. package/dist/core/config/validate.js +94 -21
  61. package/dist/core/context/gatherers/metadata-gatherer.js +1 -0
  62. package/dist/core/context/gatherers/ripgrep-gatherer.js +84 -2
  63. package/dist/core/context/keywords.js +18 -4
  64. package/dist/core/context/service-deps.js +2 -2
  65. package/dist/core/context/service.js +8 -0
  66. package/dist/core/context/steps/context-gather.js +38 -0
  67. package/dist/core/context/summarization/summarizer.js +55 -12
  68. package/dist/core/context/targeting/target-resolver.js +4 -4
  69. package/dist/core/extensions/index.js +23 -5
  70. package/dist/core/extensions/paths.js +31 -0
  71. package/dist/core/extensions/schemas.js +8 -5
  72. package/dist/core/facades/cli-chat.js +6 -2
  73. package/dist/core/facades/cli-command-chat.js +2 -1
  74. package/dist/core/facades/cli-command-tool-names.js +2 -0
  75. package/dist/core/facades/cli-context.js +1 -0
  76. package/dist/core/facades/cli-observability.js +1 -1
  77. package/dist/core/facades/cli-run-handler.js +4 -2
  78. package/dist/core/facades/cli-run-persist-session.js +1 -0
  79. package/dist/core/facades/cli-serve.js +2 -4
  80. package/dist/core/facades/cli-utils-worktree.js +1 -1
  81. package/dist/core/failure/diagnostics.js +53 -1
  82. package/dist/core/grizzco/dsl/llm-strategy.js +4 -1
  83. package/dist/core/grizzco/engine/outcome/loop-result-mapper.js +67 -9
  84. package/dist/core/grizzco/engine/pipeline/pipeline.js +6 -2
  85. package/dist/core/grizzco/engine/transaction/attempt-failure.js +90 -15
  86. package/dist/core/grizzco/engine/transaction/report-mapper.js +17 -3
  87. package/dist/core/grizzco/engine/transaction/transaction-runner.js +173 -7
  88. package/dist/core/grizzco/flows/AutopilotFlow.js +18 -0
  89. package/dist/core/grizzco/flows/flow-dispatch.js +11 -0
  90. package/dist/core/grizzco/steps/answer.js +13 -14
  91. package/dist/core/grizzco/steps/autopilot.js +396 -0
  92. package/dist/core/grizzco/steps/cache-sharing.js +29 -0
  93. package/dist/core/grizzco/steps/explore.js +37 -21
  94. package/dist/core/grizzco/steps/generateReview.js +2 -5
  95. package/dist/core/grizzco/steps/patch/apply-check.js +10 -0
  96. package/dist/core/grizzco/steps/patch/diff-normalization.js +70 -0
  97. package/dist/core/grizzco/steps/patch/diff-salvage.js +46 -0
  98. package/dist/core/grizzco/steps/patch/prompt-input.js +42 -0
  99. package/dist/core/grizzco/steps/patch.js +105 -146
  100. package/dist/core/grizzco/steps/plan.js +101 -25
  101. package/dist/core/grizzco/steps/preflight.js +5 -3
  102. package/dist/core/grizzco/steps/request-assembly.js +78 -0
  103. package/dist/core/grizzco/steps/research.js +39 -36
  104. package/dist/core/grizzco/steps/tool-runtime.js +47 -0
  105. package/dist/core/grizzco/steps/verify-shared.js +23 -0
  106. package/dist/core/grizzco/steps/verify.js +13 -21
  107. package/dist/core/intent/chat-intent.js +0 -4
  108. package/dist/core/llm/ai-sdk/chat-executor.js +2 -0
  109. package/dist/core/llm/ai-sdk/high-level-phase-specs.js +63 -0
  110. package/dist/core/llm/ai-sdk/message-mapper.js +40 -10
  111. package/dist/core/llm/ai-sdk/provider-factory.js +14 -0
  112. package/dist/core/llm/ai-sdk/request-params.js +74 -1
  113. package/dist/core/llm/ai-sdk/result-mapper.js +16 -0
  114. package/dist/core/llm/ai-sdk.js +112 -27
  115. package/dist/core/llm/capabilities.js +12 -0
  116. package/dist/core/llm/contracts/repair.js +36 -30
  117. package/dist/core/llm/errors.js +83 -2
  118. package/dist/core/llm/message-composition.js +7 -22
  119. package/dist/core/llm/phase-router.js +29 -10
  120. package/dist/core/llm/redact.js +28 -3
  121. package/dist/core/llm/registry.js +2 -0
  122. package/dist/core/llm/request-augmentation.js +55 -0
  123. package/dist/core/llm/request-envelope.js +334 -0
  124. package/dist/core/llm/shared-request-assembly.js +35 -0
  125. package/dist/core/llm/stream-utils.js +13 -4
  126. package/dist/core/llm/utils.js +18 -29
  127. package/dist/core/memory/relevant-retrieval.js +144 -0
  128. package/dist/core/observability/logger.js +11 -2
  129. package/dist/core/patch/diff.js +1 -0
  130. package/dist/core/prompts/registry.js +39 -2
  131. package/dist/core/prompts/runtime.js +50 -12
  132. package/dist/core/prompts/templates/phases/patch_user.hbs +2 -5
  133. package/dist/core/prompts/templates/phases/research_user.hbs +11 -0
  134. package/dist/core/prompts/templates/phases/review_user.hbs +3 -0
  135. package/dist/core/prompts/templates/system/answer_system.hbs +5 -0
  136. package/dist/core/prompts/templates/system/autopilot_system.hbs +11 -0
  137. package/dist/core/prompts/templates/system/explore_system.hbs +14 -23
  138. package/dist/core/prompts/templates/system/main_system.hbs +4 -16
  139. package/dist/core/prompts/templates/system/patch_system.hbs +39 -8
  140. package/dist/core/prompts/templates/system/plan_system.hbs +86 -1
  141. package/dist/core/prompts/templates/system/research_system.hbs +2 -0
  142. package/dist/core/protocols/a2a/agent-card.js +3 -2
  143. package/dist/core/protocols/a2a/sdk/executor.js +8 -6
  144. package/dist/core/protocols/a2a/sdk/server.js +0 -1
  145. package/dist/core/protocols/acp/formal-agent.js +221 -55
  146. package/dist/core/protocols/acp/handlers.js +5 -1
  147. package/dist/core/protocols/acp/permission-provider.js +21 -1
  148. package/dist/core/protocols/shared/execution-request.js +24 -0
  149. package/dist/core/protocols/shared/flow-mode-mapping.js +23 -0
  150. package/dist/core/public-capabilities/flow-mode-metadata.js +39 -0
  151. package/dist/core/public-capabilities/projections.js +29 -0
  152. package/dist/core/public-capabilities/registry.js +26 -0
  153. package/dist/core/public-capabilities/types.js +2 -0
  154. package/dist/core/runtime/agent-server-runtime.js +47 -43
  155. package/dist/core/runtime/execution-profile.js +67 -0
  156. package/dist/core/session/artifact-state.js +160 -0
  157. package/dist/core/session/compaction/index.js +183 -0
  158. package/dist/core/session/compaction/microcompact.js +78 -0
  159. package/dist/core/session/compaction/tracking.js +48 -0
  160. package/dist/core/session/compaction/types.js +11 -0
  161. package/dist/core/session/compression.js +12 -4
  162. package/dist/core/session/manager.js +247 -10
  163. package/dist/core/session/pruning-strategy.js +55 -9
  164. package/dist/core/session/replacement-preview-provider.js +24 -0
  165. package/dist/core/session/replacement-state.js +131 -0
  166. package/dist/core/session/resume-repair/pipeline.js +79 -0
  167. package/dist/core/session/resume-repair/stages/load-raw-archive-state.js +40 -0
  168. package/dist/core/session/resume-repair/stages/reattach-runtime-state.js +8 -0
  169. package/dist/core/session/resume-repair/stages/recover-orphaned-branches.js +10 -0
  170. package/dist/core/session/resume-repair/stages/relink-boundary-and-tail.js +36 -0
  171. package/dist/core/session/resume-repair/stages/replay-startup-hooks.js +23 -0
  172. package/dist/core/session/resume-repair/stages/rescue-stale-metadata.js +17 -0
  173. package/dist/core/session/resume-repair/types.js +2 -0
  174. package/dist/core/session/summary-sync.js +164 -13
  175. package/dist/core/session/token-tracker.js +6 -0
  176. package/dist/core/skills/audit.js +34 -0
  177. package/dist/core/skills/bridge.js +84 -7
  178. package/dist/core/skills/discovery.js +94 -0
  179. package/dist/core/skills/feature-flags.js +52 -0
  180. package/dist/core/skills/index.js +1 -1
  181. package/dist/core/skills/loader.js +195 -20
  182. package/dist/core/skills/parser.js +296 -24
  183. package/dist/core/skills/permissions.js +117 -0
  184. package/dist/core/skills/runtime/MicroTaskRunner.js +10 -4
  185. package/dist/core/skills/runtime/SkillRunner.js +240 -61
  186. package/dist/core/strata/layers/shadow-driver/shadow-driver.js +37 -7
  187. package/dist/core/strata/layers/worktree.js +70 -13
  188. package/dist/core/strata/runtime/synchronizer.js +29 -2
  189. package/dist/core/streaming/stream-assembler.js +75 -31
  190. package/dist/core/sub-agent/context-snapshot.js +156 -0
  191. package/dist/core/sub-agent/core/loop.js +1 -1
  192. package/dist/core/sub-agent/core/manager.js +119 -20
  193. package/dist/core/sub-agent/dispatch-policy.js +29 -0
  194. package/dist/core/sub-agent/prefix-consistency.js +48 -0
  195. package/dist/core/sub-agent/registry-defaults.js +4 -0
  196. package/dist/core/sub-agent/tools/task-spawn.js +79 -2
  197. package/dist/core/sub-agent/types.js +134 -5
  198. package/dist/core/tools/audit.js +13 -4
  199. package/dist/core/tools/builtin/ast-grep.js +1 -1
  200. package/dist/core/tools/builtin/ast.js +1 -1
  201. package/dist/core/tools/builtin/benchmark.js +360 -0
  202. package/dist/core/tools/builtin/code-search/backends/rg.js +2 -1
  203. package/dist/core/tools/builtin/code-search/executor.js +6 -1
  204. package/dist/core/tools/builtin/code-search/spec.js +26 -2
  205. package/dist/core/tools/builtin/fs.js +256 -23
  206. package/dist/core/tools/builtin/git.js +2 -2
  207. package/dist/core/tools/builtin/index.js +51 -2
  208. package/dist/core/tools/builtin/interaction.js +8 -1
  209. package/dist/core/tools/builtin/plan.js +37 -15
  210. package/dist/core/tools/builtin/shell.js +1 -1
  211. package/dist/core/tools/loader.js +39 -16
  212. package/dist/core/tools/mapper.js +17 -3
  213. package/dist/core/tools/parallel/scheduler.js +35 -4
  214. package/dist/core/tools/permissions/permission-rules.js +5 -10
  215. package/dist/core/tools/policy.js +6 -1
  216. package/dist/core/tools/recoverable-tool-errors.js +10 -0
  217. package/dist/core/tools/router.js +24 -6
  218. package/dist/core/tools/session.js +458 -48
  219. package/dist/core/tools/tool-visibility.js +62 -0
  220. package/dist/core/tools/types.js +9 -1
  221. package/dist/core/types/execution.js +4 -0
  222. package/dist/core/types/flow-mode.js +8 -0
  223. package/dist/core/utils/path.js +52 -0
  224. package/dist/core/verification/runner.js +4 -1
  225. package/dist/interfaces/cli/task-runner.js +4 -3
  226. package/dist/languages/typescript/index.js +4 -1
  227. package/dist/locales/en.js +87 -2
  228. package/dist/utils/eol.js +1 -1
  229. package/package.json +15 -8
  230. package/scripts/fix-es-abstract-compat.js +77 -0
  231. package/dist/core/runtime/fastify-server-bundle.js +0 -26
  232. package/dist/core/runtime/sidecar-fastify-plugin.js +0 -35
  233. package/dist/core/runtime/sidecar-paths.js +0 -47
  234. package/dist/core/runtime/sidecar-route-catalog.js +0 -103
@@ -1,4 +1,9 @@
1
1
  import { encodeAnthropicStreamEvent, } from './anthropic-stream-protocol.js';
2
+ function asToolInput(value) {
3
+ return value && typeof value === 'object' && !Array.isArray(value)
4
+ ? value
5
+ : {};
6
+ }
2
7
  export function encodeNormalizedToAnthropicStreamLines(params) {
3
8
  if (params.event.type === 'normalized.message_start') {
4
9
  return [
@@ -64,7 +69,7 @@ export function encodeNormalizedToAnthropicStreamLines(params) {
64
69
  }
65
70
  if (params.event.type === 'normalized.tool_request_start') {
66
71
  const parentToolUseId = params.event.callId;
67
- const input = {};
72
+ const input = params.includeToolInput ? asToolInput(params.event.input) : {};
68
73
  return [
69
74
  encodeAnthropicStreamEvent({
70
75
  sessionId: params.sessionId,
@@ -1,3 +1,4 @@
1
+ import { HEADLESS_SCHEMA_VERSION, normalizeHeadlessWarnings, } from './protocol-metadata.js';
1
2
  function toExitCode(result) {
2
3
  if (result.reason === 'Operation cancelled by user')
3
4
  return 130;
@@ -31,6 +32,30 @@ function toAuthorizationDecisions(result) {
31
32
  timestamp: d.timestamp,
32
33
  }));
33
34
  }
35
+ function toPatchArtifact(result) {
36
+ const artifact = result.benchmarkPatchArtifact;
37
+ if (!artifact)
38
+ return undefined;
39
+ return {
40
+ kind: artifact.kind,
41
+ path: artifact.path,
42
+ sha256: artifact.sha256,
43
+ bytes: artifact.bytes,
44
+ changed_files: artifact.changedFiles,
45
+ is_empty: artifact.isEmpty,
46
+ };
47
+ }
48
+ function toBenchmarkArtifact(result) {
49
+ const artifact = result.benchmarkArtifact;
50
+ if (!artifact)
51
+ return undefined;
52
+ return {
53
+ provider: artifact.provider,
54
+ instance_id: artifact.instanceId,
55
+ model_name_or_path: artifact.modelNameOrPath,
56
+ predictions_path: artifact.predictionsPath,
57
+ };
58
+ }
34
59
  export function encodeJsonResult(params) {
35
60
  const overrides = params.overrides;
36
61
  const exitCode = overrides?.exitCode ?? toExitCode(params.loopResult);
@@ -41,11 +66,13 @@ export function encodeJsonResult(params) {
41
66
  const reason = overrides?.reason ?? safeHint;
42
67
  const reasonCode = overrides?.reasonCode ?? params.loopResult.reasonCode;
43
68
  const errorCode = overrides?.errorCode ?? params.loopResult.errorCode;
69
+ const warnings = normalizeHeadlessWarnings(params.warnings);
44
70
  return {
45
71
  result: params.resultText,
46
72
  structured_output: params.structuredOutput,
47
73
  session_id: params.sessionId,
48
74
  metadata: {
75
+ schema_version: HEADLESS_SCHEMA_VERSION,
49
76
  command: params.mode,
50
77
  repo_path: params.repoPath,
51
78
  instruction: params.instruction,
@@ -58,12 +85,15 @@ export function encodeJsonResult(params) {
58
85
  remediation_steps: remediationSteps,
59
86
  attempts: params.loopResult.attempts,
60
87
  changed_files: params.loopResult.changedFiles ?? [],
88
+ patch_artifact: toPatchArtifact(params.loopResult),
89
+ benchmark_artifact: toBenchmarkArtifact(params.loopResult),
61
90
  audit_path: params.loopResult.auditPath,
62
91
  error_code: errorCode,
63
92
  authorization_summary: params.loopResult.authorizationSummary,
64
93
  usage: toUsage(params.loopResult),
65
94
  authorization_decisions: toAuthorizationDecisions(params.loopResult),
66
95
  structured_output_error: overrides?.structuredOutputError,
96
+ warnings,
67
97
  timestamps: {
68
98
  started_at: params.startedAt.toISOString(),
69
99
  ended_at: params.endedAt.toISOString(),
@@ -79,11 +109,13 @@ export function encodeJsonResult(params) {
79
109
  export function encodeJsonFailure(params) {
80
110
  const at = params.at ?? new Date();
81
111
  const exitCode = params.exitCode ?? 1;
112
+ const warnings = normalizeHeadlessWarnings(params.warnings);
82
113
  return {
83
114
  result: '',
84
115
  structured_output: null,
85
116
  session_id: params.sessionId,
86
117
  metadata: {
118
+ schema_version: HEADLESS_SCHEMA_VERSION,
87
119
  command: params.mode,
88
120
  repo_path: params.repoPath,
89
121
  instruction: params.instruction,
@@ -91,6 +123,8 @@ export function encodeJsonFailure(params) {
91
123
  exit_code: exitCode,
92
124
  reason: params.message,
93
125
  error_code: params.errorCode,
126
+ audit_path: params.auditPath,
127
+ warnings,
94
128
  timestamps: {
95
129
  started_at: at.toISOString(),
96
130
  ended_at: at.toISOString(),
@@ -99,11 +133,13 @@ export function encodeJsonFailure(params) {
99
133
  };
100
134
  }
101
135
  export function encodeJsonCrash(params) {
136
+ const warnings = normalizeHeadlessWarnings(params.warnings);
102
137
  return {
103
138
  result: '',
104
139
  structured_output: null,
105
140
  session_id: params.sessionId,
106
141
  metadata: {
142
+ schema_version: HEADLESS_SCHEMA_VERSION,
107
143
  command: params.mode,
108
144
  repo_path: params.repoPath,
109
145
  instruction: params.instruction,
@@ -114,6 +150,7 @@ export function encodeJsonCrash(params) {
114
150
  message: params.error.message,
115
151
  stack: params.error.stack,
116
152
  },
153
+ warnings,
117
154
  timestamps: {
118
155
  started_at: params.startedAt.toISOString(),
119
156
  ended_at: params.endedAt.toISOString(),
@@ -1,4 +1,9 @@
1
1
  import { encodeStreamEvent, encodeStreamFailure, } from './stream-json-protocol.js';
2
+ function asToolInput(value) {
3
+ return value && typeof value === 'object' && !Array.isArray(value)
4
+ ? value
5
+ : {};
6
+ }
2
7
  export function encodeNormalizedToNativeStreamLines(params) {
3
8
  const at = params.event.timestamp;
4
9
  if (params.event.type === 'normalized.message_start') {
@@ -75,7 +80,7 @@ export function encodeNormalizedToNativeStreamLines(params) {
75
80
  const parentToolUseId = params.event.callId;
76
81
  const phase = params.event.phase;
77
82
  const round = params.event.round;
78
- const input = {};
83
+ const input = params.includeToolInput ? asToolInput(params.event.input) : {};
79
84
  return [
80
85
  encodeStreamEvent({
81
86
  uuid: params.uuid(),
@@ -0,0 +1,22 @@
1
+ export const HEADLESS_SCHEMA_VERSION = 1;
2
+ export const HEADLESS_NATIVE_STREAM_PROTOCOL_VERSION = 1;
3
+ export function normalizeHeadlessWarnings(warnings) {
4
+ if (!warnings?.length)
5
+ return [];
6
+ const seen = new Set();
7
+ const normalized = [];
8
+ for (const warning of warnings) {
9
+ const key = `${warning.source}:${warning.code}:${warning.message}`;
10
+ if (seen.has(key))
11
+ continue;
12
+ seen.add(key);
13
+ normalized.push({
14
+ code: warning.code,
15
+ message: warning.message,
16
+ source: warning.source,
17
+ severity: warning.severity,
18
+ });
19
+ }
20
+ return normalized;
21
+ }
22
+ //# sourceMappingURL=protocol-metadata.js.map
@@ -1,4 +1,5 @@
1
1
  import { getExitCode } from '../../core/facades/cli-headless.js';
2
+ import { HEADLESS_NATIVE_STREAM_PROTOCOL_VERSION, normalizeHeadlessWarnings, } from './protocol-metadata.js';
2
3
  function toIso(date) {
3
4
  return date.toISOString();
4
5
  }
@@ -27,6 +28,8 @@ function encodeEnvelope(params) {
27
28
  return dropUndefined({
28
29
  uuid: params.uuid,
29
30
  session_id: params.sessionId,
31
+ protocol_version: HEADLESS_NATIVE_STREAM_PROTOCOL_VERSION,
32
+ event_seq: params.eventSeq,
30
33
  event: params.event,
31
34
  parent_tool_use_id: params.parentToolUseId,
32
35
  });
@@ -42,6 +45,7 @@ export function encodeStreamStart(params) {
42
45
  repo_path: params.repoPath,
43
46
  instruction: params.instruction,
44
47
  }),
48
+ eventSeq: params.eventSeq,
45
49
  });
46
50
  }
47
51
  export function encodeStreamEvent(params) {
@@ -53,6 +57,7 @@ export function encodeStreamEvent(params) {
53
57
  ...params.event,
54
58
  timestamp: toIso(params.at),
55
59
  }),
60
+ eventSeq: params.eventSeq,
56
61
  });
57
62
  }
58
63
  export function encodeStreamLoopEvent(params) {
@@ -65,10 +70,30 @@ export function encodeStreamLoopEvent(params) {
65
70
  ...mapLoopEventToJson(params.event),
66
71
  timestamp: toIso(params.event.timestamp),
67
72
  }),
73
+ eventSeq: params.eventSeq,
68
74
  });
69
75
  }
70
76
  export function encodeStreamResult(params) {
71
77
  const exitCode = getStreamExitCode(params.loopResult);
78
+ const warnings = normalizeHeadlessWarnings(params.warnings);
79
+ const patchArtifact = params.loopResult.benchmarkPatchArtifact
80
+ ? {
81
+ kind: params.loopResult.benchmarkPatchArtifact.kind,
82
+ path: params.loopResult.benchmarkPatchArtifact.path,
83
+ sha256: params.loopResult.benchmarkPatchArtifact.sha256,
84
+ bytes: params.loopResult.benchmarkPatchArtifact.bytes,
85
+ changed_files: params.loopResult.benchmarkPatchArtifact.changedFiles,
86
+ is_empty: params.loopResult.benchmarkPatchArtifact.isEmpty,
87
+ }
88
+ : undefined;
89
+ const benchmarkArtifact = params.loopResult.benchmarkArtifact
90
+ ? {
91
+ provider: params.loopResult.benchmarkArtifact.provider,
92
+ instance_id: params.loopResult.benchmarkArtifact.instanceId,
93
+ model_name_or_path: params.loopResult.benchmarkArtifact.modelNameOrPath,
94
+ predictions_path: params.loopResult.benchmarkArtifact.predictionsPath,
95
+ }
96
+ : undefined;
72
97
  return encodeEnvelope({
73
98
  uuid: params.uuid,
74
99
  sessionId: params.sessionId,
@@ -83,17 +108,21 @@ export function encodeStreamResult(params) {
83
108
  safe_hint: params.loopResult.safeHint ?? params.loopResult.reason,
84
109
  remediation_steps: params.loopResult.remediationSteps ?? [],
85
110
  attempts: params.loopResult.attempts,
86
- changed_files: params.loopResult.changedFiles,
111
+ changed_files: params.loopResult.changedFiles ?? [],
112
+ patch_artifact: patchArtifact,
113
+ benchmark_artifact: benchmarkArtifact,
87
114
  audit_path: params.loopResult.auditPath,
88
115
  error_code: params.loopResult.errorCode,
89
116
  authorization_summary: params.loopResult.authorizationSummary,
90
117
  result: params.resultText,
118
+ warnings,
91
119
  run_end: {
92
120
  success: Boolean(params.loopResult.success),
93
121
  exit_code: exitCode,
94
122
  timestamp: toIso(params.at),
95
123
  },
96
124
  }),
125
+ eventSeq: params.eventSeq,
97
126
  });
98
127
  }
99
128
  export function encodeStreamFailure(params) {
@@ -103,12 +132,14 @@ export function encodeStreamFailure(params) {
103
132
  event: {
104
133
  type: 'error',
105
134
  timestamp: toIso(params.at),
135
+ audit_path: params.auditPath,
106
136
  error: dropUndefined({
107
137
  name: params.name,
108
138
  message: params.message,
109
139
  stack: params.stack,
110
140
  }),
111
141
  },
142
+ eventSeq: params.eventSeq,
112
143
  });
113
144
  }
114
145
  export function encodeStreamCrash(params) {
@@ -119,6 +150,7 @@ export function encodeStreamCrash(params) {
119
150
  message: params.error.message,
120
151
  name: params.error.name,
121
152
  stack: params.error.stack,
153
+ eventSeq: params.eventSeq,
122
154
  });
123
155
  }
124
156
  export function encodeStreamEnd(params) {
@@ -131,6 +163,7 @@ export function encodeStreamEnd(params) {
131
163
  success: params.success,
132
164
  exit_code: params.exitCode,
133
165
  },
166
+ eventSeq: params.eventSeq,
134
167
  });
135
168
  }
136
169
  //# sourceMappingURL=stream-json-protocol.js.map
package/dist/cli/index.js CHANGED
@@ -1,8 +1,10 @@
1
1
  #!/usr/bin/env bun
2
- // 1. MUST be the very first lines to force all chalk instances (even in node_modules)
3
- // to use color support before they complete initialization.
4
- process.env.FORCE_COLOR = '3';
2
+ import { detectHeadlessOutputFromArgv, shouldForceColorForArgv, } from './argv/headless-detection.js';
3
+ const headlessOutput = Boolean(detectHeadlessOutputFromArgv(process.argv).outputFormat);
4
+ if (!headlessOutput && shouldForceColorForArgv(process.argv)) {
5
+ process.env.FORCE_COLOR = '3';
6
+ }
5
7
  import 'dotenv/config';
6
- import { runCli } from './run-cli.js';
8
+ const { runCli } = await import('./run-cli.js');
7
9
  await runCli(process.argv);
8
10
  //# sourceMappingURL=index.js.map
@@ -3,7 +3,7 @@ export const en = {
3
3
  programDescription: 'A minimal viable loop for automated code patching',
4
4
  runDescription: 'Run the salmon-loop',
5
5
  contextDescription: 'Build and print the context prompt (no LLM call)',
6
- serveDescription: 'Start the A2A + sidecar server',
6
+ serveDescription: 'Start the A2A server and ACP stdio bridge',
7
7
  serveAcpDescription: 'Start the agent-client-protocol (ACP) stdio server only',
8
8
  noColorOption: 'Disable colored output in logs',
9
9
  // Chat mode
@@ -35,6 +35,7 @@ export const en = {
35
35
  chatAnswerEmpty: 'No answer produced.',
36
36
  unknownCommand: (cmd) => `Unknown command: ${cmd}. Type /help for available commands.`,
37
37
  helpAvailableCommands: (rows) => `Available Commands:\n${rows}`,
38
+ programHelpFooter: '\nTips:\n Use "s8p <command> --help" to see command-specific options.\n In chat, type /help to list slash commands.',
38
39
  slashHandlerUnavailable: 'Command handler unavailable',
39
40
  slashInternalError: 'Internal error',
40
41
  skillNoPrompt: (id) => `Skill ${id} did not produce a prompt`,
@@ -73,6 +74,7 @@ export const en = {
73
74
  commandLlmOutput: 'Set which LLM sections are shown in the UI (advanced)',
74
75
  commandMode: 'Set permission mode (interactive|yolo) and save to config',
75
76
  commandLogMode: 'Set UI verbosity (quiet|normal|debug) and save to config',
77
+ commandFlowMode: 'Set the current chat flow mode for this session',
76
78
  commandConfig: 'Settings hub (mode, log-mode, view, output, allowlist)',
77
79
  commandAuth: 'Manage tool allowlist',
78
80
  commandParallel: 'Manage parallel plans',
@@ -119,6 +121,25 @@ export const en = {
119
121
  modeUpdated: (mode) => `Permission mode updated: ${mode}`,
120
122
  modePersisted: (path) => `Permission mode saved to ${path}`,
121
123
  modePersistFailed: (error) => `Failed to save permission mode: ${error}`,
124
+ flowModeUsage: 'Usage: /flow-mode <patch|review|debug|research|answer|autopilot>',
125
+ flowModeSuggestion: (mode) => {
126
+ if (mode === 'patch')
127
+ return 'Patch code and run verification';
128
+ if (mode === 'review')
129
+ return 'Analyze code without modifying files';
130
+ if (mode === 'debug')
131
+ return 'Investigate issues, then patch and verify';
132
+ if (mode === 'research')
133
+ return 'Research the codebase and summarize findings';
134
+ if (mode === 'answer')
135
+ return 'Answer directly without modifying files';
136
+ if (mode === 'autopilot')
137
+ return 'Let SalmonLoop choose the appropriate flow';
138
+ return `Set flow mode to ${mode}`;
139
+ },
140
+ flowModeCurrent: (mode) => `Current chat flow mode: ${mode}`,
141
+ flowModeInvalid: (mode) => `Invalid flow mode: ${mode}. Expected one of: patch, review, debug, research, answer, autopilot.`,
142
+ flowModeUpdated: (mode) => `Chat flow mode updated: ${mode}`,
122
143
  logModeUsage: 'Usage: /log-mode <quiet|normal|debug>',
123
144
  logModeSuggestion: (mode) => {
124
145
  if (mode === 'quiet')
@@ -158,11 +179,9 @@ export const en = {
158
179
  a2aPortOption: 'A2A listen port (default: 7431)',
159
180
  a2aTokenOption: 'Bearer token for A2A auth (repeatable)',
160
181
  acpStdioDisableOption: 'Disable agent-client-protocol (ACP) stdio server',
161
- sidecarSocketOption: 'UDS path for the sidecar UI server',
162
- sidecarAllowConditionalOption: 'Expose conditional sidecar routes (use with care)',
163
182
  acpStdioStarted: (port) => `ACP (agent-client-protocol) stdio enabled; port ${port}`,
164
183
  invalidA2APort: (value) => `Invalid A2A port: ${value}`,
165
- serveStarted: (host, port, socket) => `A2A listening on ${host}:${port}; sidecar socket at ${socket}`,
184
+ serveStarted: (host, port) => `A2A listening on ${host}:${port}`,
166
185
  configAllowlistUsage: 'Usage: /config allowlist <list|add|remove|clear|hash|reload> [scope] [tool] [phase] [args=<hash>] [effects=a,b] [deny]',
167
186
  authUsage: 'Usage: /allowlist <list|add|remove|clear|hash|reload> [scope] [tool] [phase] [args=<hash>] [effects=a,b] [deny]',
168
187
  authSubcommandHint: (sub) => `Allowlist ${sub} command`,
@@ -234,6 +253,7 @@ export const en = {
234
253
  preflightPolicyOption: 'Preflight policy (lenient: continue on test failure, strict: fail on test failure)',
235
254
  checkpointStrategyOption: 'Checkpoint strategy to use (direct, worktree)',
236
255
  permissionModeOption: 'Permission mode (interactive, yolo)',
256
+ logModeOption: 'UI log mode (quiet, normal, debug)',
237
257
  environmentModeOption: 'Worktree environment mode (strict, parity)',
238
258
  applyBackOnDirtyOption: 'Behavior when apply-back detects a dirty workspace (3way, abort)',
239
259
  worktreePrepareOption: 'Optional setup command to run inside worktree',
@@ -241,6 +261,10 @@ export const en = {
241
261
  includePartialMessagesOption: 'Include partial message streaming events in stream-json output (alias for --stream-output).',
242
262
  outputFormatOption: 'Output format (text, json, stream-json)',
243
263
  outputProfileOption: 'Output profile for stream-json (native, anthropic, openai). Only valid with --output-format stream-json.',
264
+ exportPatchOption: 'Write the final workspace git unified diff to a patch file after the run completes.',
265
+ sweBenchInstanceIdOption: 'SWE-bench instance_id to include when writing a predictions JSONL record.',
266
+ sweBenchModelNameOption: 'SWE-bench model_name_or_path to include when writing a predictions JSONL record.',
267
+ sweBenchPredictionsOption: 'Append a SWE-bench predictions JSONL record containing instance_id, model_name_or_path, and model_patch.',
244
268
  headlessIncludeToolInputOption: 'Headless only: include (redacted) tool input in stream-json output. Only valid with --output-format stream-json.',
245
269
  headlessIncludeToolOutputOption: 'Headless only: include tool output summary in stream-json output. Only valid with --output-format stream-json.',
246
270
  headlessIncludeAuthorizationDecisionsOption: 'Headless only: include tool authorization decisions in headless output. Only valid with --output-format json or stream-json.',
@@ -250,7 +274,7 @@ export const en = {
250
274
  auditScopeOption: 'Audit log scope (repo, user)',
251
275
  contextDiffScopeOption: 'Diff scope for context (primary, ast_related)',
252
276
  contextBudgetCharsOption: 'Context budget in characters (e.g., 30000)',
253
- actModeOption: 'Flow mode to run (patch, review, debug, research)',
277
+ actModeOption: 'Flow mode to run (patch, review, debug, research, answer, autopilot)',
254
278
  // Error messages
255
279
  fileSelectionConflict: '--file and --selection are mutually exclusive',
256
280
  instructionRequired: '--instruction is required',
@@ -260,10 +284,12 @@ export const en = {
260
284
  jsonSchemaRequiresJsonOutput: '--json-schema is only valid when --output-format is set to "json".',
261
285
  jsonSchemaLoadFailed: (msg) => `Failed to load JSON schema: ${msg}.`,
262
286
  structuredOutputSchemaFailed: 'Structured output failed schema validation.',
263
- invalidActMode: (mode) => `Invalid --act-mode "${mode}". Expected "patch", "review", "debug", or "research".`,
287
+ invalidActMode: (mode) => `Invalid --act-mode "${mode}". Expected "patch", "review", "debug", "research", "answer", or "autopilot".`,
264
288
  invalidEnvironmentMode: (mode) => `Invalid --environment-mode "${mode}". Expected "strict" or "parity".`,
265
289
  invalidOutputFormat: (format) => `Invalid --output-format "${format}". Expected "text", "stream-json", or "json".`,
266
290
  invalidOutputProfile: (profile) => `Invalid --output-profile "${profile}". Expected "native", "anthropic", or "openai".`,
291
+ sweBenchInstanceRequired: '--swe-bench-predictions requires --swe-bench-instance-id.',
292
+ sweBenchModelRequired: '--swe-bench-predictions requires --swe-bench-model-name.',
267
293
  invalidAuditScope: (scope) => `Invalid --audit-scope "${scope}". Expected "repo" or "user".`,
268
294
  headlessToolPayloadRequiresStreamJson: '--headless-include-tool-input/--headless-include-tool-output are only valid when --output-format is set to "stream-json".',
269
295
  headlessToolPayloadNotSupportedWithOpenAiProfile: '--headless-include-tool-input/--headless-include-tool-output are not supported with --output-profile "openai".',
@@ -2,13 +2,23 @@ import chalk from 'chalk';
2
2
  import { Command } from 'commander';
3
3
  import { initializeRuntime } from '../core/facades/cli-program-bootstrap.js';
4
4
  import { text } from './locales/index.js';
5
- export function bootstrapProgram() {
5
+ export function bootstrapProgram(options = {}) {
6
6
  initializeRuntime();
7
- // Force global chalk level for all output paths.
8
- chalk.level = 3;
7
+ if (!options.headlessDetection?.outputFormat && process.env.NO_COLOR === undefined) {
8
+ // Force global chalk level for interactive output paths.
9
+ chalk.level = 3;
10
+ }
11
+ else {
12
+ chalk.level = 0;
13
+ }
9
14
  const program = new Command();
10
15
  program.exitOverride();
11
- program.name('s8p').alias('salmonloop').description(text.cli.programDescription).version('0.2.0');
16
+ program
17
+ .name('s8p')
18
+ .alias('salmonloop')
19
+ .description(text.cli.programDescription)
20
+ .version('0.2.0')
21
+ .addHelpText('after', text.cli.programHelpFooter);
12
22
  return program;
13
23
  }
14
24
  //# sourceMappingURL=program-bootstrap.js.map
@@ -22,7 +22,7 @@ export function registerProgramCommands(program) {
22
22
  .option('--force-reset', text.cli.forceResetOption)
23
23
  .option('--validate', text.cli.validateOption)
24
24
  .option('--preflight-policy <policy>', text.cli.preflightPolicyOption, 'lenient')
25
- .option('--act-mode <mode>', text.cli.actModeOption, 'patch')
25
+ .option('--act-mode <mode>', text.cli.actModeOption, 'autopilot')
26
26
  .option('--apply-back-on-dirty <mode>', text.cli.applyBackOnDirtyOption, '3way')
27
27
  .option('--environment-mode <mode>', text.cli.environmentModeOption, 'strict')
28
28
  .option('--worktree-prepare <command>', text.cli.worktreePrepareOption)
@@ -30,6 +30,10 @@ export function registerProgramCommands(program) {
30
30
  .option('--include-partial-messages', text.cli.includePartialMessagesOption)
31
31
  .option('--output-format <format>', text.cli.outputFormatOption, 'text')
32
32
  .option('--output-profile <profile>', text.cli.outputProfileOption)
33
+ .option('--export-patch <path>', text.cli.exportPatchOption)
34
+ .option('--swe-bench-instance-id <id>', text.cli.sweBenchInstanceIdOption)
35
+ .option('--swe-bench-model-name <name>', text.cli.sweBenchModelNameOption)
36
+ .option('--swe-bench-predictions <path>', text.cli.sweBenchPredictionsOption)
33
37
  .option('--headless-include-tool-input', text.cli.headlessIncludeToolInputOption)
34
38
  .option('--headless-include-tool-output', text.cli.headlessIncludeToolOutputOption)
35
39
  .option('--allow-outside-cache-root', text.cli.allowOutsideCacheRootOption)
@@ -90,6 +94,8 @@ export function registerProgramCommands(program) {
90
94
  .command('context')
91
95
  .description(text.cli.contextDescription)
92
96
  .option('-i, --instruction <instruction>', text.cli.instructionOption)
97
+ .option('--config <path>', text.cli.configOption)
98
+ .option('--no-config-file', text.cli.noConfigFileOption)
93
99
  .option('-f, --file <path>', text.cli.fileOption)
94
100
  .option('-s, --selection <text>', text.cli.selectionOption)
95
101
  .option('--diff-scope <scope>', text.cli.contextDiffScopeOption, 'primary')
@@ -100,6 +106,8 @@ export function registerProgramCommands(program) {
100
106
  program
101
107
  .command('chat', { isDefault: true })
102
108
  .description('Enter interactive chat mode (default)')
109
+ .option('--config <path>', text.cli.configOption)
110
+ .option('--no-config-file', text.cli.noConfigFileOption)
103
111
  .option('--verbose [level]', text.cli.verboseOption)
104
112
  .action(handleChatCommand);
105
113
  }
@@ -7,6 +7,7 @@ export function configureGlobalProgramOptions(program) {
7
7
  .option('--resume <sessionId>', text.cli.resumeOption)
8
8
  .option('-v, --verify <command>', text.cli.verifyOption)
9
9
  .option('--no-verify', 'Disable verification')
10
+ .option('--log-mode <mode>', text.cli.logModeOption)
10
11
  .option('-cs, --checkpoint-strategy <type>', text.cli.checkpointStrategyOption, 'worktree')
11
12
  .option('--mode <mode>', text.cli.permissionModeOption, 'interactive')
12
13
  .option('--llm-output <kinds>', text.cli.llmOutputOption)
@@ -8,13 +8,18 @@ export class AnthropicStreamReporter {
8
8
  repoPath;
9
9
  sessionId;
10
10
  writer;
11
+ includeToolInput;
11
12
  lastTextResult;
12
- assembler = new StreamAssembler();
13
+ assembler;
13
14
  constructor(options = {}) {
14
15
  this.mode = options.mode ?? 'run';
15
16
  this.repoPath = options.repoPath;
16
17
  this.sessionId = options.sessionId ?? randomUUID();
17
18
  this.writer = options.writer ?? createStdoutWriter();
19
+ this.includeToolInput = options.includeToolInput ?? false;
20
+ this.assembler = new StreamAssembler({
21
+ deferToolRequestsUntilExecutionInput: this.includeToolInput,
22
+ });
18
23
  }
19
24
  onStart(instruction) {
20
25
  this.emit(encodeAnthropicStart({
@@ -40,6 +45,7 @@ export class AnthropicStreamReporter {
40
45
  const lines = encodeNormalizedToAnthropicStreamLines({
41
46
  sessionId: this.sessionId,
42
47
  event: normalizedEvent,
48
+ includeToolInput: this.includeToolInput,
43
49
  });
44
50
  for (const line of lines)
45
51
  this.emit(line);
@@ -7,6 +7,7 @@ export class JsonReporter {
7
7
  sessionId;
8
8
  getStructuredOutput;
9
9
  getPayloadOverrides;
10
+ getWarnings;
10
11
  now;
11
12
  writer;
12
13
  startedAt = null;
@@ -18,6 +19,7 @@ export class JsonReporter {
18
19
  this.sessionId = options.sessionId ?? randomUUID();
19
20
  this.getStructuredOutput = options.getStructuredOutput;
20
21
  this.getPayloadOverrides = options.getPayloadOverrides;
22
+ this.getWarnings = options.getWarnings;
21
23
  this.now = options.now ?? (() => new Date());
22
24
  this.writer = options.writer ?? createStdoutWriter();
23
25
  }
@@ -48,6 +50,7 @@ export class JsonReporter {
48
50
  structuredOutput,
49
51
  loopResult: result,
50
52
  overrides,
53
+ warnings: this.getWarnings?.(),
51
54
  });
52
55
  this.writer.writeJsonLine(payload);
53
56
  }
@@ -62,6 +65,7 @@ export class JsonReporter {
62
65
  startedAt,
63
66
  endedAt,
64
67
  error,
68
+ warnings: this.getWarnings?.(),
65
69
  });
66
70
  this.writer.writeJsonLine(payload);
67
71
  }
@@ -10,8 +10,11 @@ export class StreamJsonReporter {
10
10
  now;
11
11
  uuid;
12
12
  writer;
13
+ getWarnings;
13
14
  lastTextResult;
14
- assembler = new StreamAssembler();
15
+ nextEventSeq = 0;
16
+ assembler;
17
+ includeToolInput;
15
18
  constructor(options = {}) {
16
19
  this.mode = options.mode ?? 'run';
17
20
  this.repoPath = options.repoPath;
@@ -19,6 +22,11 @@ export class StreamJsonReporter {
19
22
  this.now = options.now ?? (() => new Date());
20
23
  this.uuid = options.uuid ?? randomUUID;
21
24
  this.writer = options.writer ?? createStdoutWriter();
25
+ this.getWarnings = options.getWarnings;
26
+ this.includeToolInput = options.includeToolInput ?? false;
27
+ this.assembler = new StreamAssembler({
28
+ deferToolRequestsUntilExecutionInput: this.includeToolInput,
29
+ });
22
30
  }
23
31
  onStart(instruction) {
24
32
  this.emit(encodeStreamStart({
@@ -47,6 +55,7 @@ export class StreamJsonReporter {
47
55
  sessionId: this.sessionId,
48
56
  uuid: this.uuid,
49
57
  event: normalizedEvent,
58
+ includeToolInput: this.includeToolInput,
50
59
  });
51
60
  for (const line of lines)
52
61
  this.emit(line);
@@ -76,6 +85,7 @@ export class StreamJsonReporter {
76
85
  loopResult: result,
77
86
  at,
78
87
  resultText: this.lastTextResult,
88
+ warnings: this.getWarnings?.(),
79
89
  });
80
90
  this.emit(resultLine);
81
91
  const exitCode = getStreamExitCode(result);
@@ -88,6 +98,7 @@ export class StreamJsonReporter {
88
98
  }));
89
99
  }
90
100
  onError(error) {
101
+ const auditPath = typeof error.auditPath === 'string' ? error.auditPath : undefined;
91
102
  this.emit(encodeStreamFailure({
92
103
  uuid: this.uuid(),
93
104
  sessionId: this.sessionId,
@@ -95,6 +106,7 @@ export class StreamJsonReporter {
95
106
  message: error.message,
96
107
  name: error.name,
97
108
  stack: error.stack,
109
+ auditPath,
98
110
  }));
99
111
  this.emit(encodeStreamEnd({
100
112
  uuid: this.uuid(),
@@ -105,7 +117,10 @@ export class StreamJsonReporter {
105
117
  }));
106
118
  }
107
119
  emit(line) {
108
- this.writer.writeJsonLine(line);
120
+ this.writer.writeJsonLine({
121
+ ...line,
122
+ event_seq: line.event_seq ?? this.nextEventSeq++,
123
+ });
109
124
  }
110
125
  }
111
126
  //# sourceMappingURL=stream-json.js.map
@@ -1,17 +1,19 @@
1
+ import { detectHeadlessOutputFromArgv } from './argv/headless-detection.js';
1
2
  import { createCliRuntimeContext } from './cli-runtime-context.js';
2
3
  import { bootstrapProgram } from './program-bootstrap.js';
3
4
  import { registerProgramCommands } from './program-commands.js';
4
5
  import { configureGlobalProgramOptions } from './program-options.js';
5
6
  import { configureProgramOutputForHeadless } from './program-output-mode.js';
6
7
  import { parseProgramOrExit } from './program-parse.js';
7
- export function buildCliProgram() {
8
- const program = bootstrapProgram();
8
+ export function buildCliProgram(argv = process.argv) {
9
+ const headlessDetection = detectHeadlessOutputFromArgv(argv);
10
+ const program = bootstrapProgram({ headlessDetection });
9
11
  configureGlobalProgramOptions(program);
10
12
  registerProgramCommands(program);
11
13
  return program;
12
14
  }
13
15
  export function createCliContextFromArgv(argv) {
14
- const program = buildCliProgram();
16
+ const program = buildCliProgram(argv);
15
17
  return createCliRuntimeContext(program, argv);
16
18
  }
17
19
  export async function executeCliContext(context) {