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,6 +1,10 @@
1
- import { buildA2AAgentCard, buildSidecarRouteDescriptors, createAcpFormalAgent, createAgentServerRuntime, createInteractionFacade, createSalmonTaskExecutor, createTaskEventBus, createPluginRegistry, createPromptRegistry, defaultPathAdapter, defaultSidecarRouteCatalog, getSidecarListenOptions, getUserAcpSessionStorePath, GitSnapshotCheckpointService, getLogger, mkdir, PlainReporter, PluginLoader, resolveExtensions, runSalmonLoop, setPluginRegistry, setPromptRegistry, startAcpStdioServer, StderrReporter, } from '../../core/facades/cli-serve.js';
1
+ import { normalizePermissionMode } from '../../core/config/index.js';
2
+ import { buildA2AAgentCard, createAcpFormalAgent, createAgentServerRuntime, createInteractionFacade, createSalmonTaskExecutor, createTaskEventBus, createPluginRegistry, createPromptRegistry, getUserAcpSessionStorePath, GitSnapshotCheckpointService, getLogger, mergeResolvedExtensions, PACKAGE_VERSION, PlainReporter, PluginLoader, resolveExtensions, resolveExecutionProfile, runSalmonLoop, setPluginRegistry, setPromptRegistry, startAcpStdioServer, StderrReporter, } from '../../core/facades/cli-serve.js';
3
+ import { selectPublicCapabilitiesForSurface, toA2APublicSkills, } from '../../core/public-capabilities/projections.js';
4
+ import { buildPublicCapabilityRegistry } from '../../core/public-capabilities/registry.js';
2
5
  import { createTerminalAuthorizationProvider } from '../authorization/provider.js';
3
6
  import { text } from '../locales/index.js';
7
+ import { getOptionValueSourceWithGlobalFallback } from '../utils/command-option-source.js';
4
8
  import { createOutcomeReporter } from '../utils/outcome-reporter.js';
5
9
  import { resolveCliConfig } from '../utils/resolve-cli-config.js';
6
10
  import { createRuntimeLlmAndWarn } from './run/runtime-llm.js';
@@ -10,21 +14,44 @@ function parsePort(value, fallback) {
10
14
  const parsed = Number(value);
11
15
  return Number.isFinite(parsed) ? parsed : Number.NaN;
12
16
  }
13
- function buildSidecarHandlers(deps) {
17
+ function resolveDefaultAcpPermissionPolicy(permissionMode) {
18
+ return permissionMode === 'yolo' ? 'allow_all' : 'ask';
19
+ }
20
+ function resolveServePermissionMode({ command, allOptions, rawConfiguredPermissionMode, flowMode, }) {
21
+ const permissionModeOptionSource = getOptionValueSourceWithGlobalFallback(command, 'mode');
22
+ const configuredPermissionMode = normalizePermissionMode(rawConfiguredPermissionMode);
23
+ const rawPermissionMode = (permissionModeOptionSource === 'cli' ? allOptions.mode : undefined) ??
24
+ configuredPermissionMode ??
25
+ resolveExecutionProfile(flowMode).defaultPermissionMode ??
26
+ 'interactive';
27
+ const permissionMode = normalizePermissionMode(rawPermissionMode);
28
+ if (!permissionMode) {
29
+ getLogger().error(`Invalid --mode "${String(rawPermissionMode)}". Expected "interactive" or "yolo".`, true);
30
+ process.exit(1);
31
+ }
32
+ return permissionMode;
33
+ }
34
+ function buildServeLoopExecutionDefaults(mode) {
35
+ const profile = resolveExecutionProfile(mode);
36
+ const strategy = profile.defaultCheckpointStrategy ?? 'worktree';
14
37
  return {
15
- health: async () => Response.json({ status: 'ok' }),
16
- status: async () => Response.json({ state: 'idle' }),
17
- info: async () => Response.json({
18
- name: deps.name,
19
- version: deps.version,
20
- capabilities: deps.capabilities,
21
- }),
22
- abort: async () => new Response('Abort not implemented for this runtime', { status: 501 }),
23
- workspace_files: async () => new Response('Workspace file access not enabled', { status: 501 }),
24
- logs_stream: async () => new Response('Log streaming not enabled', { status: 501 }),
25
- config_patch: async () => new Response('Config patch not enabled', { status: 501 }),
38
+ strategy,
39
+ applyBackOnDirty: strategy === 'worktree' ? '3way' : undefined,
40
+ environmentMode: 'strict',
26
41
  };
27
42
  }
43
+ function registerServeShutdown({ message, closeRuntime, closeAcpStdio, }) {
44
+ process.once('SIGINT', async () => {
45
+ getLogger().info(message);
46
+ try {
47
+ await closeRuntime?.();
48
+ }
49
+ finally {
50
+ closeAcpStdio?.();
51
+ process.exit(0);
52
+ }
53
+ });
54
+ }
28
55
  export function registerServeCommands(program) {
29
56
  const serve = program
30
57
  .command('serve')
@@ -33,8 +60,6 @@ export function registerServeCommands(program) {
33
60
  .option('--a2a-port <port>', text.cli.a2aPortOption)
34
61
  .option('--a2a-token <token>', text.cli.a2aTokenOption, (value, previous) => previous.concat([value]), [])
35
62
  .option('--no-acp-stdio', text.cli.acpStdioDisableOption)
36
- .option('--sidecar-socket <path>', text.cli.sidecarSocketOption)
37
- .option('--sidecar-allow-conditional', text.cli.sidecarAllowConditionalOption)
38
63
  .option('--no-color', text.cli.noColorOption)
39
64
  .action(handleServeCommand);
40
65
  serve
@@ -58,6 +83,13 @@ export async function handleServeCommand(_options, command) {
58
83
  process.exit(1);
59
84
  }
60
85
  const { resolvedConfig, auditScope, repoPath: defaultRepoPath } = configResult;
86
+ const defaultFlowMode = 'autopilot';
87
+ const defaultPermissionMode = resolveServePermissionMode({
88
+ command,
89
+ allOptions,
90
+ rawConfiguredPermissionMode: resolvedConfig.raw?.mode,
91
+ flowMode: defaultFlowMode,
92
+ });
61
93
  const serverConfig = resolvedConfig.server;
62
94
  const rawA2aHost = allOptions.a2aHost ?? serverConfig?.a2a?.host;
63
95
  const a2aHost = String(rawA2aHost ?? '127.0.0.1');
@@ -71,13 +103,6 @@ export async function handleServeCommand(_options, command) {
71
103
  if (acpStdioEnabled) {
72
104
  getLogger().setReporter(allOptions.color === false ? new StderrReporter() : new PlainReporter());
73
105
  }
74
- const sidecarListen = typeof allOptions.sidecarSocket === 'string' && allOptions.sidecarSocket.length > 0
75
- ? { type: 'pipe', path: allOptions.sidecarSocket }
76
- : getSidecarListenOptions();
77
- const allowConditional = allOptions.sidecarAllowConditional ?? serverConfig?.sidecar?.allowConditional ?? false;
78
- if (sidecarListen.type === 'pipe' && !sidecarListen.path.startsWith('\\\\.\\pipe\\')) {
79
- await mkdir(defaultPathAdapter.dirname(sidecarListen.path), { recursive: true });
80
- }
81
106
  const languagePlugins = createPluginRegistry();
82
107
  setPluginRegistry(languagePlugins);
83
108
  setPromptRegistry(createPromptRegistry());
@@ -99,28 +124,34 @@ export async function handleServeCommand(_options, command) {
99
124
  forceNonInteractive: true,
100
125
  });
101
126
  const executor = createSalmonTaskExecutor({
102
- runLoop: async ({ instruction, mode, repoPath, onEvent, signal, authorizationProvider, authorizationMode, fileSystemOverride, }) => {
127
+ runLoop: async ({ instruction, mode, repoPath, onEvent, signal, authorizationProvider, authorizationMode, fileSystemOverride, extensions: taskExtensions, }) => {
103
128
  const effectiveRepoPath = repoPath ?? defaultRepoPath;
129
+ const flowMode = mode;
130
+ const executionDefaults = buildServeLoopExecutionDefaults(flowMode);
131
+ const permissionMode = resolveServePermissionMode({
132
+ command,
133
+ allOptions,
134
+ rawConfiguredPermissionMode: resolvedConfig.raw?.mode,
135
+ flowMode,
136
+ });
104
137
  return await runSalmonLoop({
105
138
  instruction,
106
139
  repoPath: effectiveRepoPath,
107
140
  llm,
108
- mode: mode,
141
+ mode: flowMode,
109
142
  verify: resolvedConfig.verify.command,
110
- strategy: 'worktree',
111
- applyBackOnDirty: '3way',
112
- environmentMode: 'strict',
143
+ ...executionDefaults,
113
144
  llmOutput: resolvedConfig.llmOutput,
114
145
  outcomeReporter,
115
146
  langfuseSessionId: resolvedConfig.observability.langfuse.sessionId,
116
147
  langfuseUserId: resolvedConfig.observability.langfuse.userId,
117
148
  auditScope,
118
- permissionMode: resolvedConfig.permissionMode,
149
+ permissionMode,
119
150
  languagePlugins,
120
151
  fileSystemOverride,
121
152
  authorizationProvider: authorizationProvider ?? defaultAuthorizationProvider,
122
153
  authorizationMode,
123
- extensions: extensions.resolved,
154
+ extensions: mergeResolvedExtensions(extensions.resolved, taskExtensions),
124
155
  onEvent,
125
156
  signal,
126
157
  });
@@ -157,27 +188,20 @@ export async function handleServeCommand(_options, command) {
157
188
  next();
158
189
  }
159
190
  : undefined;
160
- const capabilities = [{ id: 'patch', title: 'Patch code' }];
191
+ const a2aPublicCapabilities = selectPublicCapabilitiesForSurface('a2a', buildPublicCapabilityRegistry());
192
+ const a2aSkills = toA2APublicSkills(a2aPublicCapabilities);
161
193
  const agentCard = buildA2AAgentCard({
162
194
  name: 'salmon-loop',
163
195
  url: `http://${a2aHost}:${a2aPort}`,
164
- capabilities,
196
+ capabilities: a2aSkills,
165
197
  security: authTokens.length > 0 ? [{ type: 'http', scheme: 'bearer' }] : [],
166
198
  });
167
- const sidecarRoutes = buildSidecarRouteDescriptors({
168
- strict: true,
169
- catalog: defaultSidecarRouteCatalog,
170
- handlers: buildSidecarHandlers({
171
- name: 'salmon-loop',
172
- version: '0.2.0',
173
- capabilities,
174
- }),
175
- });
176
199
  if (acpStdioEnabled) {
177
200
  startAcpStdioServer((conn) => createAcpFormalAgent({
178
201
  conn,
179
- agentInfo: { name: 'salmon-loop', version: '0.2.0' },
180
- defaultModeId: resolvedConfig.permissionMode,
202
+ agentInfo: { name: 'salmon-loop', version: PACKAGE_VERSION },
203
+ defaultModeId: 'autopilot',
204
+ defaultPermissionPolicy: resolveDefaultAcpPermissionPolicy(defaultPermissionMode),
181
205
  checkpointReader: {
182
206
  listBySession: async ({ repoPath, sessionId, limit }) => await checkpointService.list({ repoPath, sessionId, limit }),
183
207
  getById: async ({ repoPath, checkpointId }) => (await checkpointService.loadWithStatus({ repoPath, checkpointId })).handle,
@@ -192,42 +216,25 @@ export async function handleServeCommand(_options, command) {
192
216
  eventBus: sharedEventBus,
193
217
  }));
194
218
  getLogger().info(text.cli.acpStdioStarted('n/a (stdio)'));
195
- // Handle SIGINT for graceful shutdown
196
- process.on('SIGINT', () => {
197
- getLogger().info('Received SIGINT, shutting down ACP server...');
198
- process.stdin.destroy();
199
- process.exit(0);
200
- });
201
219
  }
202
- const fastify = (await import('fastify')).default;
203
220
  const runtime = createAgentServerRuntime({
204
- createFastify: () => fastify(),
205
221
  a2a: {
206
222
  buildAgentCard: () => agentCard,
207
223
  executeTask: executor.execute,
208
224
  eventBus: sharedEventBus,
209
225
  authMiddleware,
210
226
  },
211
- sidecar: {
212
- routes: sidecarRoutes,
213
- allowConditional,
214
- },
215
227
  listen: {
216
228
  a2a: { host: a2aHost, port: a2aPort },
217
- sidecar: sidecarListen,
218
229
  },
219
- a2aBaseUrl: `http://${a2aHost}:${a2aPort}`,
220
230
  });
221
- // Handle SIGINT for graceful shutdown
222
- process.on('SIGINT', () => {
223
- getLogger().info('Received SIGINT, shutting down server...');
224
- runtime.close().then(() => process.exit(0));
231
+ registerServeShutdown({
232
+ message: 'Received SIGINT, shutting down server...',
233
+ closeRuntime: () => runtime.close(),
234
+ closeAcpStdio: acpStdioEnabled ? () => void process.stdin.destroy() : undefined,
225
235
  });
226
236
  await runtime.start();
227
- const sidecarAddress = sidecarListen.type === 'tcp'
228
- ? `http://${sidecarListen.host}:${sidecarListen.port}`
229
- : sidecarListen.path;
230
- getLogger().success(text.cli.serveStarted(a2aHost, a2aPort, sidecarAddress));
237
+ getLogger().success(text.cli.serveStarted(a2aHost, a2aPort));
231
238
  }
232
239
  export async function handleServeAcpCommand(_options, command) {
233
240
  const allOptions = command.optsWithGlobals();
@@ -244,6 +251,13 @@ export async function handleServeAcpCommand(_options, command) {
244
251
  process.exit(1);
245
252
  }
246
253
  const { resolvedConfig, auditScope, repoPath: defaultRepoPath } = configResult;
254
+ const defaultFlowMode = 'autopilot';
255
+ const defaultPermissionMode = resolveServePermissionMode({
256
+ command,
257
+ allOptions,
258
+ rawConfiguredPermissionMode: resolvedConfig.raw?.mode,
259
+ flowMode: defaultFlowMode,
260
+ });
247
261
  getLogger().setReporter(allOptions.color === false ? new StderrReporter() : new PlainReporter());
248
262
  const languagePlugins = createPluginRegistry();
249
263
  setPluginRegistry(languagePlugins);
@@ -266,27 +280,33 @@ export async function handleServeAcpCommand(_options, command) {
266
280
  forceNonInteractive: true,
267
281
  });
268
282
  const executor = createSalmonTaskExecutor({
269
- runLoop: async ({ instruction, mode, repoPath, onEvent, signal, authorizationProvider, authorizationMode, }) => {
283
+ runLoop: async ({ instruction, mode, repoPath, onEvent, signal, authorizationProvider, authorizationMode, extensions: taskExtensions, }) => {
270
284
  const effectiveRepoPath = repoPath ?? defaultRepoPath;
285
+ const flowMode = mode;
286
+ const executionDefaults = buildServeLoopExecutionDefaults(flowMode);
287
+ const permissionMode = resolveServePermissionMode({
288
+ command,
289
+ allOptions,
290
+ rawConfiguredPermissionMode: resolvedConfig.raw?.mode,
291
+ flowMode,
292
+ });
271
293
  return await runSalmonLoop({
272
294
  instruction,
273
295
  repoPath: effectiveRepoPath,
274
296
  llm,
275
- mode: mode,
297
+ mode: flowMode,
276
298
  verify: resolvedConfig.verify.command,
277
- strategy: 'worktree',
278
- applyBackOnDirty: '3way',
279
- environmentMode: 'strict',
299
+ ...executionDefaults,
280
300
  llmOutput: resolvedConfig.llmOutput,
281
301
  outcomeReporter,
282
302
  langfuseSessionId: resolvedConfig.observability.langfuse.sessionId,
283
303
  langfuseUserId: resolvedConfig.observability.langfuse.userId,
284
304
  auditScope,
285
- permissionMode: resolvedConfig.permissionMode,
305
+ permissionMode,
286
306
  languagePlugins,
287
307
  authorizationProvider: authorizationProvider ?? defaultAuthorizationProvider,
288
308
  authorizationMode,
289
- extensions: extensions.resolved,
309
+ extensions: mergeResolvedExtensions(extensions.resolved, taskExtensions),
290
310
  onEvent,
291
311
  signal,
292
312
  });
@@ -305,8 +325,9 @@ export async function handleServeAcpCommand(_options, command) {
305
325
  });
306
326
  startAcpStdioServer((conn) => createAcpFormalAgent({
307
327
  conn,
308
- agentInfo: { name: 'salmon-loop', version: '0.2.0' },
309
- defaultModeId: resolvedConfig.permissionMode,
328
+ agentInfo: { name: 'salmon-loop', version: PACKAGE_VERSION },
329
+ defaultModeId: 'autopilot',
330
+ defaultPermissionPolicy: resolveDefaultAcpPermissionPolicy(defaultPermissionMode),
310
331
  checkpointReader: {
311
332
  listBySession: async ({ repoPath, sessionId, limit }) => await checkpointService.list({ repoPath, sessionId, limit }),
312
333
  getById: async ({ repoPath, checkpointId }) => (await checkpointService.loadWithStatus({ repoPath, checkpointId })).handle,
@@ -321,10 +342,9 @@ export async function handleServeAcpCommand(_options, command) {
321
342
  eventBus: sharedEventBus,
322
343
  }));
323
344
  getLogger().info(text.cli.acpStdioStarted('n/a (stdio)'));
324
- process.on('SIGINT', () => {
325
- getLogger().info('Received SIGINT, shutting down ACP server...');
326
- process.stdin.destroy();
327
- process.exit(0);
345
+ registerServeShutdown({
346
+ message: 'Received SIGINT, shutting down ACP server...',
347
+ closeAcpStdio: () => void process.stdin.destroy(),
328
348
  });
329
349
  }
330
350
  //# sourceMappingURL=serve.js.map
@@ -1,7 +1,7 @@
1
1
  import * as os from 'os';
2
2
  import * as path from 'path';
3
- import { getLogger, registerAllBuiltins, skillToToolSpec, SkillParser, ToolRegistry, } from '../../core/facades/cli-command-tool-names.js';
4
- import { existsSync, readFileUtf8, readFileUtf8Sync, readdirDirents, readdirDirentsSync, safePathJoin, stat, statSync, } from '../utils/safe-fs.js';
3
+ import { getLogger, registerAllBuiltins, resolveExtensions, skillToToolSpec, SkillLoader, ToolRegistry, } from '../../core/facades/cli-command-tool-names.js';
4
+ import { stat, statSync } from '../utils/safe-fs.js';
5
5
  const VALID_SIDE_EFFECTS = new Set([
6
6
  'none',
7
7
  'fs_read',
@@ -11,40 +11,23 @@ const VALID_SIDE_EFFECTS = new Set([
11
11
  'git_read',
12
12
  'git_write',
13
13
  ]);
14
+ // Cache key includes repoRoot. Extensions config is not part of the key because
15
+ // tool-names is used for tab completion where extensions may not be available.
14
16
  const toolNameCache = new Map();
15
- async function loadSkillsFromPath(root) {
16
- if (!existsSync(root))
17
- return [];
18
- const entries = await readdirDirents(root, root);
19
- const skills = [];
20
- for (const entry of entries) {
21
- const skillFile = entry.isDirectory()
22
- ? safePathJoin(root, entry.name, 'SKILL.md')
23
- : entry.name.endsWith('.md')
24
- ? safePathJoin(root, entry.name)
25
- : null;
26
- if (!skillFile || !existsSync(skillFile, root))
27
- continue;
28
- try {
29
- const content = await readFileUtf8(skillFile, root);
30
- skills.push(SkillParser.parse(content, skillFile));
31
- }
32
- catch (error) {
33
- getLogger().warn(`Failed to load skill at ${skillFile}: ${error instanceof Error ? error.message : String(error)}`);
34
- }
35
- }
36
- return skills;
37
- }
38
- function getSkillSearchPaths(repoRoot) {
39
- return [
40
- path.join(os.homedir(), '.claude/skills'),
41
- path.join(repoRoot, '.salmonloop/skills'),
42
- path.join(repoRoot, '.claude/skills'),
17
+ /**
18
+ * Compute a cache-invalidation signature based on mtime of all skill search
19
+ * paths that SkillLoader would scan. Mirrors the strict search order.
20
+ */
21
+ async function computeSkillSignature(repoRoot, extraPaths = []) {
22
+ const searchPaths = [
23
+ ...extraPaths,
24
+ path.join(repoRoot, '.salmonloop', 'skills'),
25
+ path.join(repoRoot, '.agents', 'skills'),
26
+ path.join(os.homedir(), '.salmonloop', 'skills'),
27
+ path.join(os.homedir(), '.agents', 'skills'),
43
28
  ];
44
- }
45
- async function computeSkillSignature(repoRoot) {
46
29
  const parts = [];
47
- for (const searchPath of getSkillSearchPaths(repoRoot)) {
30
+ for (const searchPath of searchPaths) {
48
31
  try {
49
32
  const stats = await stat(searchPath);
50
33
  parts.push(`${searchPath}:${stats.mtimeMs}`);
@@ -56,8 +39,14 @@ async function computeSkillSignature(repoRoot) {
56
39
  return parts.join('|');
57
40
  }
58
41
  function computeSkillSignatureSync(repoRoot) {
42
+ const searchPaths = [
43
+ path.join(repoRoot, '.salmonloop', 'skills'),
44
+ path.join(repoRoot, '.agents', 'skills'),
45
+ path.join(os.homedir(), '.salmonloop', 'skills'),
46
+ path.join(os.homedir(), '.agents', 'skills'),
47
+ ];
59
48
  const parts = [];
60
- for (const searchPath of getSkillSearchPaths(repoRoot)) {
49
+ for (const searchPath of searchPaths) {
61
50
  try {
62
51
  const stats = statSync(searchPath);
63
52
  parts.push(`${searchPath}:${stats.mtimeMs}`);
@@ -68,52 +57,63 @@ function computeSkillSignatureSync(repoRoot) {
68
57
  }
69
58
  return parts.join('|');
70
59
  }
71
- function loadSkillsFromPathSync(root) {
72
- if (!existsSync(root))
73
- return [];
74
- const entries = readdirDirentsSync(root, root);
75
- const skills = [];
76
- for (const entry of entries) {
77
- const skillFile = entry.isDirectory()
78
- ? safePathJoin(root, entry.name, 'SKILL.md')
79
- : entry.name.endsWith('.md')
80
- ? safePathJoin(root, entry.name)
81
- : null;
82
- if (!skillFile || !existsSync(skillFile, root))
83
- continue;
84
- try {
85
- const content = readFileUtf8Sync(skillFile, root);
86
- skills.push(SkillParser.parse(content, skillFile));
87
- }
88
- catch (error) {
89
- getLogger().warn(`Failed to load skill at ${skillFile}: ${error instanceof Error ? error.message : String(error)}`);
90
- }
91
- }
92
- return skills;
93
- }
60
+ /**
61
+ * Get all known tool names including skills.
62
+ *
63
+ * Uses `resolveExtensions` to obtain the same SkillLoader configuration
64
+ * (extraPaths) as the main runtime, so that
65
+ * tool-name discovery and actual runtime skill availability stay consistent.
66
+ */
94
67
  export async function getKnownToolNames(repoRoot) {
95
- const signature = await computeSkillSignature(repoRoot);
68
+ // Resolve extensions to get the same loader config as the runtime
69
+ let skillDiscovery = {};
70
+ try {
71
+ const { resolved } = await resolveExtensions({ repoRoot });
72
+ skillDiscovery = resolved.skillDiscovery;
73
+ }
74
+ catch {
75
+ // Extensions config unavailable — fall back to loader defaults
76
+ }
77
+ const extraPaths = skillDiscovery.paths ?? [];
78
+ const signature = await computeSkillSignature(repoRoot, extraPaths);
96
79
  const cached = toolNameCache.get(repoRoot);
97
80
  if (cached && cached.signature === signature)
98
81
  return cached.names;
99
82
  const registry = new ToolRegistry();
100
83
  registerAllBuiltins(registry);
101
- for (const searchPath of getSkillSearchPaths(repoRoot)) {
102
- const skills = await loadSkillsFromPath(searchPath);
103
- for (const skill of skills) {
104
- try {
105
- registry.register(skillToToolSpec(skill));
106
- }
107
- catch (error) {
108
- const label = skill.metadata?.name || skill.id;
109
- getLogger().warn(`Failed to register skill ${label}: ${error instanceof Error ? error.message : String(error)}`);
110
- }
84
+ const routerBox = { router: null };
85
+ const skillLoader = new SkillLoader({
86
+ repoRoot,
87
+ extraPaths,
88
+ });
89
+ const catalog = await skillLoader.loadCatalog();
90
+ for (const entry of catalog) {
91
+ try {
92
+ // Name-only registration: executor is never called, so null router is safe.
93
+ // Use catalog entry for lightweight registration (progressive disclosure).
94
+ registry.register(skillToToolSpec({ entry, loader: skillLoader }, routerBox));
95
+ }
96
+ catch (error) {
97
+ const label = entry.name || entry.id;
98
+ getLogger().warn(`Failed to register skill ${label}: ${error instanceof Error ? error.message : String(error)}`);
111
99
  }
112
100
  }
113
101
  const names = new Set(registry.listAll().map((spec) => spec.name));
114
102
  toolNameCache.set(repoRoot, { names, signature });
115
103
  return names;
116
104
  }
105
+ /**
106
+ * Synchronous variant for tab completion only.
107
+ *
108
+ * @nonAuthoritative This returns a best-effort approximation of known tool
109
+ * names using loader defaults (no extensions resolution, since
110
+ * resolveExtensions is async). The result may differ from the actual runtime
111
+ * tool set when custom `skills.json` discovery paths are configured.
112
+ *
113
+ * DO NOT use this for security decisions (allowlist enforcement, permission
114
+ * checks). Use the async {@link getKnownToolNames} instead, which resolves
115
+ * extensions for full consistency with the runtime.
116
+ */
117
117
  export function getKnownToolNamesSync(repoRoot) {
118
118
  const signature = computeSkillSignatureSync(repoRoot);
119
119
  const cached = toolNameCache.get(repoRoot);
@@ -121,16 +121,16 @@ export function getKnownToolNamesSync(repoRoot) {
121
121
  return cached.names;
122
122
  const registry = new ToolRegistry();
123
123
  registerAllBuiltins(registry);
124
- for (const searchPath of getSkillSearchPaths(repoRoot)) {
125
- const skills = loadSkillsFromPathSync(searchPath);
126
- for (const skill of skills) {
127
- try {
128
- registry.register(skillToToolSpec(skill));
129
- }
130
- catch (error) {
131
- const label = skill.metadata?.name || skill.id;
132
- getLogger().warn(`Failed to register skill ${label}: ${error instanceof Error ? error.message : String(error)}`);
133
- }
124
+ const routerBox = { router: null };
125
+ const skillLoader = new SkillLoader({ repoRoot });
126
+ const skills = skillLoader.initializeSync();
127
+ for (const skill of skills) {
128
+ try {
129
+ registry.register(skillToToolSpec(skill, routerBox));
130
+ }
131
+ catch (error) {
132
+ const label = skill.metadata?.name || skill.id;
133
+ getLogger().warn(`Failed to register skill ${label}: ${error instanceof Error ? error.message : String(error)}`);
134
134
  }
135
135
  }
136
136
  const names = new Set(registry.listAll().map((spec) => spec.name));
@@ -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(),