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
@@ -0,0 +1,62 @@
1
+ import { Phase } from '../types/runtime.js';
2
+ const PLAN_RUNTIME_TOOL_NAMES = new Set(['plan.read', 'plan.update']);
3
+ const PATCH_VISIBLE_TOOL_NAMES = new Set(['fs.read', 'code.search']);
4
+ function isPhaseAllowed(tool, phase) {
5
+ return Array.isArray(tool.allowedPhases) && tool.allowedPhases.includes(phase);
6
+ }
7
+ export function resolvePlanVisibleTools(tools, runtime) {
8
+ const hasRuntimePlan = Boolean(runtime?.plan);
9
+ return tools.filter((tool) => {
10
+ if (!isPhaseAllowed(tool, Phase.PLAN))
11
+ return false;
12
+ if (!tool.name.startsWith('plan.'))
13
+ return true;
14
+ if (!hasRuntimePlan)
15
+ return false;
16
+ return PLAN_RUNTIME_TOOL_NAMES.has(tool.name);
17
+ });
18
+ }
19
+ export function resolvePatchVisibleTools(tools) {
20
+ return tools.filter((tool) => isPhaseAllowed(tool, Phase.PATCH) && PATCH_VISIBLE_TOOL_NAMES.has(tool.name));
21
+ }
22
+ export function resolveAutopilotVisibleTools(tools, runtime) {
23
+ const hasRuntimePlan = Boolean(runtime?.plan);
24
+ return tools.filter((tool) => {
25
+ if (!isPhaseAllowed(tool, Phase.AUTOPILOT))
26
+ return false;
27
+ if (!tool.name.startsWith('plan.'))
28
+ return true;
29
+ if (!hasRuntimePlan)
30
+ return false;
31
+ return PLAN_RUNTIME_TOOL_NAMES.has(tool.name);
32
+ });
33
+ }
34
+ export function resolvePhaseVisibleTools(params) {
35
+ if (params.phase === Phase.PLAN) {
36
+ return resolvePlanVisibleTools(params.tools, params.runtime);
37
+ }
38
+ if (params.phase === Phase.PATCH) {
39
+ return resolvePatchVisibleTools(params.tools);
40
+ }
41
+ if (params.phase === Phase.AUTOPILOT) {
42
+ return resolveAutopilotVisibleTools(params.tools, params.runtime);
43
+ }
44
+ return params.tools;
45
+ }
46
+ export function resolveVisibleToolSpecs(params) {
47
+ if (!params.toolstack)
48
+ return [];
49
+ const allowedSpecs = params.toolstack.registry.listAll().filter((spec) => params.toolstack.policy.decide(params.phase, spec, {
50
+ worktreeRoot: params.worktreeRoot,
51
+ flowMode: params.flowMode,
52
+ }).allowed);
53
+ return resolvePhaseVisibleTools({
54
+ phase: params.phase,
55
+ tools: allowedSpecs,
56
+ runtime: params.runtime,
57
+ });
58
+ }
59
+ export function resolveVisibleToolNames(params) {
60
+ return resolveVisibleToolSpecs(params).map((spec) => spec.name);
61
+ }
62
+ //# sourceMappingURL=tool-visibility.js.map
@@ -1,2 +1,10 @@
1
- export const TOOL_INTENTS = ['READ', 'SEARCH', 'LIST', 'WRITE', 'INFRA', 'AGENT'];
1
+ export const TOOL_INTENTS = [
2
+ 'READ',
3
+ 'SEARCH',
4
+ 'LIST',
5
+ 'WRITE',
6
+ 'INFRA',
7
+ 'AGENT',
8
+ 'REPORT',
9
+ ];
2
10
  //# sourceMappingURL=types.js.map
@@ -30,6 +30,9 @@ export const Phase = {
30
30
  // SLASH is an out-of-band interactive phase used for adapter-level slash routing and skill expansion.
31
31
  // It is intentionally excluded from EXECUTION_PHASES to avoid impacting the main SalmonLoop flow.
32
32
  SLASH: 'SLASH',
33
+ // AUTOPILOT is introduced as a driver-owned business phase. It is intentionally excluded from
34
+ // EXECUTION_PHASES until the dedicated AutopilotFlow lands.
35
+ AUTOPILOT: 'AUTOPILOT',
33
36
  PREFLIGHT: 'PREFLIGHT',
34
37
  PREPARE_DEPS: 'PREPARE_DEPS',
35
38
  CONTEXT: 'CONTEXT',
@@ -47,6 +50,7 @@ export const Phase = {
47
50
  };
48
51
  export const ALL_VISIBLE_STEPS = [
49
52
  ...EXECUTION_PHASES,
53
+ 'AUTOPILOT',
50
54
  'REVIEW',
51
55
  'REPORT',
52
56
  'ANALYZE_ISSUES',
@@ -0,0 +1,8 @@
1
+ export const FLOW_MODES = ['patch', 'review', 'debug', 'research', 'answer', 'autopilot'];
2
+ export function parseFlowMode(raw) {
3
+ const value = String(raw ?? '')
4
+ .trim()
5
+ .toLowerCase();
6
+ return FLOW_MODES.includes(value) ? value : undefined;
7
+ }
8
+ //# sourceMappingURL=flow-mode.js.map
@@ -17,6 +17,16 @@ function shouldUseWin32PathSemantics(p) {
17
17
  // This enables correct behavior for inputs like "src\\components\\file.ts" on POSIX.
18
18
  return p.includes('\\');
19
19
  }
20
+ function selectPathImplForAbsolutePath(p) {
21
+ const normalized = normalizePath(p);
22
+ if (isWindowsAbsolutePath(normalized) || normalized.startsWith('//')) {
23
+ return path.win32;
24
+ }
25
+ if (normalized.startsWith('/')) {
26
+ return path.posix;
27
+ }
28
+ return path;
29
+ }
20
30
  /**
21
31
  * Normalize a path to use forward slashes, regardless of the operating system.
22
32
  * This ensures consistency across Windows and Linux/macOS.
@@ -30,6 +40,19 @@ export function normalizePath(p) {
30
40
  }
31
41
  return replaced.replace(/\/{2,}/g, '/');
32
42
  }
43
+ /**
44
+ * Normalize a path-like input into a stable repo-relative form.
45
+ *
46
+ * Intended for:
47
+ * - Permission rules matching (stable normalization across platforms)
48
+ * - Tool argument normalization and auditing
49
+ *
50
+ * This function does NOT validate safety (absolute/traversal); use isSafeRelativePath() or
51
+ * sandbox resolution checks for security-sensitive operations.
52
+ */
53
+ export function normalizeRepoRelativePath(input) {
54
+ return normalizePath(String(input ?? '').trim()).replace(/^(\.\/|\/)+/, '');
55
+ }
33
56
  /**
34
57
  * Join path segments and normalize the result to use forward slashes.
35
58
  */
@@ -56,6 +79,35 @@ export function safeDirname(p) {
56
79
  export function safeRelative(from, to) {
57
80
  return normalizePath(path.relative(from, to));
58
81
  }
82
+ /**
83
+ * Normalize an absolute or canonical path into a stable form for comparisons.
84
+ * Windows-style paths are compared case-insensitively; POSIX paths preserve case.
85
+ */
86
+ export function normalizeComparableAbsolutePath(input) {
87
+ const normalized = normalizePath(String(input ?? '').trim());
88
+ const impl = selectPathImplForAbsolutePath(normalized);
89
+ const resolved = normalizePath(impl.resolve(normalized));
90
+ return impl === path.win32 ? resolved.toLowerCase() : resolved;
91
+ }
92
+ /**
93
+ * Compare canonical paths using platform-appropriate semantics.
94
+ */
95
+ export function arePathsEquivalent(left, right) {
96
+ return normalizeComparableAbsolutePath(left) === normalizeComparableAbsolutePath(right);
97
+ }
98
+ /**
99
+ * Check whether a canonical target path is contained within a canonical root path.
100
+ * Inputs should already be resolved/canonicalized by the caller when used for security checks.
101
+ */
102
+ export function isCanonicalPathWithinDirectory(root, target, options = {}) {
103
+ const { allowEqual = true } = options;
104
+ const normalizedRoot = normalizeComparableAbsolutePath(root);
105
+ const normalizedTarget = normalizeComparableAbsolutePath(target);
106
+ if (normalizedTarget === normalizedRoot) {
107
+ return allowEqual;
108
+ }
109
+ return normalizedTarget.startsWith(`${normalizedRoot}/`);
110
+ }
59
111
  /**
60
112
  * Check whether a path is a safe relative path (no absolute paths or traversal).
61
113
  */
@@ -53,7 +53,10 @@ export function classifyError(output) {
53
53
  }
54
54
  if (lowerOutput.includes('eslint') ||
55
55
  lowerOutput.includes('prettier') ||
56
- lowerOutput.includes('prettier/prettier')) {
56
+ lowerOutput.includes('prettier/prettier') ||
57
+ lowerOutput.includes('oxfmt') ||
58
+ lowerOutput.includes('format issues found') ||
59
+ lowerOutput.includes('script "format:check" exited with code')) {
57
60
  return ErrorType.LINT;
58
61
  }
59
62
  if (lowerOutput.includes('fail ') ||
@@ -1,10 +1,11 @@
1
+ import { buildCanonicalExecutionRequest } from '../../core/protocols/shared/execution-request.js';
1
2
  export function createCliTaskRunner(deps) {
2
3
  return {
3
4
  async run(input) {
4
- return deps.facade.createTask({
5
+ return deps.facade.createTask(buildCanonicalExecutionRequest({
5
6
  capability: input.capability,
6
- request: { instruction: input.instruction },
7
- });
7
+ instruction: input.instruction,
8
+ }));
8
9
  },
9
10
  };
10
11
  }
@@ -58,7 +58,10 @@ const commonDiagnostics = {
58
58
  // Lint error keywords
59
59
  if (lowerOutput.includes('eslint') ||
60
60
  lowerOutput.includes('prettier') ||
61
- lowerOutput.includes('stylelint')) {
61
+ lowerOutput.includes('stylelint') ||
62
+ lowerOutput.includes('oxfmt') ||
63
+ lowerOutput.includes('format issues found') ||
64
+ lowerOutput.includes('script "format:check" exited with code')) {
62
65
  return ErrorType.LINT;
63
66
  }
64
67
  return undefined;
@@ -86,6 +86,57 @@ export const en = {
86
86
  allowlistAtomicWriteBackupFailed: 'Allowlist atomic write backup failed.',
87
87
  allowlistAtomicRestoreFailed: 'Allowlist atomic restore failed.',
88
88
  allowlistPathBlocked: 'Allowlist blocked the requested path.',
89
+ // File system security errors
90
+ pathOutsideRepo: 'Access denied: Path is outside of repository root.',
91
+ reservedPathPrefix: (prefix) => `Access denied: Reserved path prefix: ${prefix}`,
92
+ pathNotFound: (p) => `Path not found: ${p}`,
93
+ // Worktree errors
94
+ worktreePathMustBeUnderParityRoot: 'Worktree path must be under parity worktree root',
95
+ worktreePathMustBeInTempDir: 'Worktree path must be in system temp directory',
96
+ worktreePathMustNotBeInsideRepo: 'Worktree path must not be inside repo path',
97
+ worktreePathNotInManagedRoots: 'Worktree path not in managed roots, refusing to delete',
98
+ // Shadow driver errors
99
+ aggressiveStrategyLinuxOnly: 'AGGRESSIVE strategy only supported on Linux',
100
+ commandTimedOut: 'Command timed out',
101
+ // Lock errors
102
+ failedToAcquireLock: 'Failed to acquire lock due to concurrent lock updates',
103
+ lockAcquisitionAborted: 'Lock acquisition aborted',
104
+ // Checkpoint errors
105
+ workspaceDirtyUseForce: 'Workspace is dirty. Use --force to overwrite.',
106
+ // Session errors
107
+ noActiveSession: 'No active session',
108
+ // Runtime errors
109
+ bunRuntimeNotAvailable: 'Bun runtime is not available',
110
+ runtimeAlreadyStarted: 'Runtime already started',
111
+ // Protocol errors
112
+ acpSessionPersistLockTimeout: 'ACP_SESSION_PERSIST_LOCK_TIMEOUT',
113
+ // Registry errors
114
+ subAgentRegistryNotInitialized: 'SubAgentRegistry is not initialized. Call setSubAgentRegistry() at startup.',
115
+ promptRegistryNotInitialized: 'PromptRegistry is not initialized. Call setPromptRegistry() at startup.',
116
+ pluginRegistryNotInitialized: 'PluginRegistry is not initialized. Call setPluginRegistry() at startup.',
117
+ monitorNotInitialized: 'Monitor is not initialized. Call setMonitor(createMonitor()) at startup.',
118
+ loggerNotInitialized: 'Logger is not initialized. Call setLogger(createLogger()) at startup.',
119
+ // Plan storage errors
120
+ invalidSessionId: 'Invalid sessionId (expected 6-64 chars of [a-zA-Z0-9_-]).',
121
+ invalidStepId: 'Invalid stepId.',
122
+ // Audit errors
123
+ invalidAuditFile: 'Invalid audit file: context.eventsRef.path is required',
124
+ // LLM errors
125
+ operationAborted: 'Operation aborted',
126
+ emptyLlmResponse: 'Empty LLM response',
127
+ streamAborted: 'Stream aborted',
128
+ // Worker errors
129
+ repoRootRequired: 'repoRoot context is required for union-merge reading',
130
+ patchContentEmpty: 'Patch content is empty',
131
+ // Transaction errors
132
+ runtimeEnvironmentMissingWorkspace: 'Runtime environment missing workspace after setup',
133
+ executionTerminatedWithoutReport: 'SalmonLoop execution terminated without a FlowReport',
134
+ // Decision engine errors
135
+ planBuilderContextNotBound: 'PlanBuilder: context not bound',
136
+ // Pipeline errors
137
+ operationCancelledByUser: 'Operation cancelled by user',
138
+ // Sub-agent errors
139
+ stopRequestedBeforeLaunch: 'Stop requested before launching Smallfry',
89
140
  },
90
141
  acp: {
91
142
  slashHelpDescription: 'Show available ACP slash commands',
@@ -102,6 +153,8 @@ export const en = {
102
153
  permissionPolicyAskDescription: 'Request user permission for side-effecting operations.',
103
154
  permissionPolicyDenyAllName: 'Deny all',
104
155
  permissionPolicyDenyAllDescription: 'Automatically deny side-effecting operations.',
156
+ permissionPolicyAllowAllName: 'Allow all',
157
+ permissionPolicyAllowAllDescription: 'Automatically allow side-effecting operations.',
105
158
  modeInteractiveDescription: 'Request permission before running side-effecting operations.',
106
159
  modeYoloDescription: 'Bypass permission prompts for side-effecting operations.',
107
160
  },
@@ -505,7 +558,12 @@ Please return the patch in PURE unified diff format:`;
505
558
  codeSearchDescription: 'Fast file pattern matching tool that works with any codebase size',
506
559
  fsReadDescription: 'Read the full content of a file from the repository',
507
560
  codeReadDescription: 'Read the full content of a source file from the repository',
508
- fsListDescription: 'List files and directories under a repository path',
561
+ fsListDescription: 'List directory entries under a repository path (legacy name). Prefer fs.list_directory for clarity.',
562
+ fsListDirectoryDescription: 'List directory entries (files and subdirectories) under a repository path',
563
+ fsListFilesDescription: 'List files (excluding subdirectories) under a repository path',
564
+ fsWriteFileDescription: 'Write a UTF-8 text file atomically (slash-only)',
565
+ fsCreateDirectoryDescription: 'Create a directory under the repository root (slash-only)',
566
+ fsDeleteFileDescription: 'Delete a file under the repository root (slash-only)',
509
567
  gitStatusDescription: 'Show the working tree status',
510
568
  gitCatDescription: 'Read file content from a specific git revision',
511
569
  codeAstDescription: 'Query AST definitions and references for symbols',
@@ -617,8 +675,35 @@ Please return the patch in PURE unified diff format:`;
617
675
  findingItem: (index, summary, confidence, uncertainty) => `Finding ${index}: ${summary}${typeof confidence === 'number' ? ` (confidence: ${confidence})` : ''}${uncertainty ? ` [uncertainty: ${uncertainty}]` : ''}`,
618
676
  },
619
677
  },
678
+ intent: {
679
+ researchKeywords: ['deep research', 'research', 'investigate', 'investigation'],
680
+ },
620
681
  skills: {
621
682
  maxRetriesExceeded: (id) => `Max retries exceeded for skill: ${id}. Possible circular dependency in dynamic data.`,
683
+ legacyRunnerForbidden: 'Legacy MicroTaskRunner is restricted to test context only. Use executeSkill() from SkillRunner.ts for production execution.',
684
+ missingFrontmatter: (filePath) => `Skill at ${filePath}: missing or malformed YAML frontmatter (expected --- delimiters).`,
685
+ invalidFrontmatter: (filePath, reason) => `Skill at ${filePath}: frontmatter validation failed — ${reason}`,
686
+ yamlParseError: (filePath, reason) => `Skill at ${filePath}: YAML parse error — ${reason}`,
687
+ nameDirMismatch: (filePath, expected, actual) => `Skill at ${filePath}: frontmatter name "${actual}" does not match parent directory "${expected}"`,
688
+ legacyDirectMdDeprecation: (filePath) => `Skill at ${filePath}: direct .md format is deprecated. Convert to subdirectory format: move to <skill-name>/SKILL.md`,
689
+ skillNotFoundInCatalog: (id) => `Skill "${id}" not found in catalog. Ensure loadCatalog() has been called and the skill exists.`,
690
+ skillActivated: (id) => `Skill "${id}" activated (Tier 2: full content loaded).`,
691
+ newSkillDiscovered: (id, location) => `New skill "${id}" discovered at ${location} during session.`,
692
+ conditionalSkillActivated: (id, matchedPattern) => `Conditional skill "${id}" activated: file matched pattern "${matchedPattern}".`,
693
+ permissionFileInvalidFormat: (filePath) => `Skill permissions file at ${filePath} has invalid format; starting with empty allowlist.`,
694
+ permissionFileLoadError: (filePath) => `Failed to load skill permissions from ${filePath}; starting with empty allowlist.`,
695
+ permissionFileSaveError: (filePath, reason) => `Failed to save skill permissions to ${filePath}: ${reason}`,
696
+ // Lenient validation warnings
697
+ nameTooLong: (filePath, name, len) => `Skill at ${filePath}: name "${name}" exceeds 64 characters (${len}); loading anyway`,
698
+ nameFormatWarning: (filePath, name) => `Skill at ${filePath}: name "${name}" does not match naming convention; loading anyway`,
699
+ descriptionTooLong: (filePath, len) => `Skill at ${filePath}: description exceeds 1024 characters (${len}); loading anyway`,
700
+ // YAML fallback
701
+ yamlFallbackApplied: (filePath, lines) => `Skill at ${filePath}: YAML fallback applied to fix common issues (${lines}); loading with corrected values`,
702
+ yamlFallbackFailed: (filePath) => `Skill at ${filePath}: YAML fallback recovery also failed; skipping skill`,
703
+ // Catalog disclosure
704
+ catalogDisclosurePreamble: 'The following skills provide specialized instructions for specific tasks. ' +
705
+ 'When a task matches a skill description, read the SKILL.md file at the listed location to load detailed instructions before proceeding. ' +
706
+ 'When a skill references relative paths, resolve them against the skill directory (the parent of SKILL.md).',
622
707
  },
623
708
  // Symbols for UI feedback
624
709
  symbols: {
@@ -671,7 +756,7 @@ Please return the patch in PURE unified diff format:`;
671
756
  missionFailedWithReason: (reason) => `Smallfry mission failed: ${reason}`,
672
757
  },
673
758
  ui: {
674
- spawnToolDescription: 'Deploy a specialized Smallfry (sub-agent) for autonomous task execution.',
759
+ spawnToolDescription: 'Delegate a concrete sub-task to a specialized sub-agent. This is not a no-argument action: always provide agent_ref and task. Use agent_ref="explorer" for read-only investigation, "reviewer" for audit, "surgeon" for implementation proposals, or "cleaner" for lint/format cleanup. Keep task self-contained with relevant files and the exact deliverable. Omit session_target unless shared context is explicitly required.',
675
760
  progressTitle: (id) => `[Smallfry: ${id}]`,
676
761
  },
677
762
  },
package/dist/utils/eol.js CHANGED
@@ -7,7 +7,7 @@ export class TextNormalizer {
7
7
  static read(content) {
8
8
  // 1. Count frequencies to handle mixed line endings
9
9
  const crlfCount = (content.match(/\r\n/g) || []).length;
10
- const lfCount = (content.match(/[^\r]\n/g) || []).length;
10
+ const lfCount = (content.match(/(?<!\r)\n/g) || []).length;
11
11
  // 2. Determine style (default to LF if LF >= CRLF)
12
12
  const eol = crlfCount > lfCount ? '\r\n' : '\n';
13
13
  // 3. Normalize to LF
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "salmon-loop",
3
- "version": "0.2.3",
3
+ "version": "0.2.16",
4
4
  "description": "A chat-first coding agent CLI for safe, reviewable repository changes",
5
5
  "type": "module",
6
6
  "bin": {
@@ -16,6 +16,7 @@
16
16
  "dist/locales/**/*.js",
17
17
  "dist/utils/**/*.js",
18
18
  "dist/core/prompts/templates/**/*.hbs",
19
+ "scripts/fix-es-abstract-compat.js",
19
20
  "README.md",
20
21
  "README.zh-CN.md",
21
22
  "LICENSE"
@@ -29,12 +30,16 @@
29
30
  "t": "bun run test:unit",
30
31
  "test:unit": "bun scripts/run-bun-file-tests.ts tests/unit",
31
32
  "test:integration": "bun scripts/run-bun-file-tests.ts tests/integration",
33
+ "test:integration:network": "RUN_A2A_NETWORK_INTEGRATION=1 bun test --timeout 90000 --preload ./tests/setup-bun.ts tests/integration/a2a-sdk-server.test.ts",
32
34
  "test:e2e": "bun scripts/run-bun-file-tests.ts tests/e2e",
33
- "test:full": "bun run test:unit && bun run test:integration && bun run test:perf",
35
+ "test:full": "bun run test:unit && bun run test:integration",
36
+ "test:all": "bun run test:full && bun run test:perf",
34
37
  "test:runtime-boundary": "bun test --preload ./tests/setup-bun.ts tests/unit/scripts/target-runtime-boundary.test.ts tests/unit/scripts/bun-purity.test.ts",
35
38
  "test:worktree-smoke": "bun scripts/worktree-smoke.js",
36
39
  "test:headless-smoke": "bun scripts/headless-smoke.ts",
40
+ "test:contract-smoke": "bun test --timeout 15000 --preload ./tests/setup-bun.ts tests/unit/architecture/request-assembly-invariant.test.ts tests/unit/architecture/replacement-preview-boundary-invariant.test.ts tests/unit/architecture/sub-agent-prefix-consistency-invariant.test.ts tests/unit/architecture/tool-naming-contract.test.ts tests/unit/architecture/verify-contract-smoke-gate.test.ts tests/unit/tools/session-streaming.test.ts tests/unit/core/grizzco/steps/plan-patch-toolcalling.test.ts tests/unit/core/session/replacement-state.test.ts",
37
41
  "setup:hooks": "git config core.hooksPath .githooks",
42
+ "postinstall": "node scripts/fix-es-abstract-compat.js",
38
43
  "check:bun-purity": "bun scripts/check-bun-purity.ts",
39
44
  "check:bun-purity:staged": "bun scripts/check-bun-purity.ts --staged",
40
45
  "check:target-runtime-boundary": "bun scripts/check-target-runtime-hardcoding.ts",
@@ -51,17 +56,20 @@
51
56
  "check:test-runner-migration": "bun scripts/check-test-runner-migration.ts",
52
57
  "lint": "bun ./node_modules/eslint/bin/eslint.js .",
53
58
  "typecheck": "bun ./node_modules/typescript/bin/tsc --noEmit",
54
- "verify": "bun run check:bun-purity && bun run check:target-runtime-boundary && bun run check:unit-boundary && bun run check:fs-git-boundary && bun run check:bun-native-boundary && bun run check:test-runner-migration && bun run lint && bun run typecheck && bun run test:full",
59
+ "verify": "bun run check:bun-purity && bun run check:target-runtime-boundary && bun run check:unit-boundary && bun run check:fs-git-boundary && bun run check:bun-native-boundary && bun run check:test-runner-migration && bun run format:check && bun run lint && bun run typecheck && bun run test:contract-smoke && bun run test:full",
55
60
  "test:watch": "bun test --watch --preload ./tests/setup-bun.ts tests",
56
61
  "test:watch:unit": "bun test --watch --preload ./tests/setup-bun.ts tests/unit",
57
62
  "test:watch:integration": "bun test --watch --preload ./tests/setup-bun.ts tests/integration",
58
63
  "test:perf": "bun scripts/run-bun-file-tests.ts tests/perf",
64
+ "test:perf:network": "RUN_A2A_PERF_BENCHMARKS=1 bun test tests/perf/a2a-performance-benchmark.test.ts",
65
+ "test:perf:all": "RUN_A2A_PERF_BENCHMARKS=1 bun scripts/run-bun-file-tests.ts tests/perf",
59
66
  "test:watch:perf": "bun test --watch --preload ./tests/setup-bun.ts tests/perf",
60
67
  "test:coverage": "bun test --coverage --preload ./tests/setup-bun.ts tests",
61
68
  "test:report": "bun test --reporter=junit --reporter-outfile=test-report.xml --preload ./tests/setup-bun.ts tests",
62
69
  "test:ci": "bun run verify",
63
70
  "pack:dry": "npm pack --dry-run",
64
- "format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"",
71
+ "format": "oxfmt --write \"src/**/*.ts\" \"tests/**/*.ts\"",
72
+ "format:check": "oxfmt --check \"src/**/*.ts\" \"tests/**/*.ts\"",
65
73
  "release": "bun scripts/release.ts cut",
66
74
  "release:cut": "bun scripts/release.ts cut",
67
75
  "release:publish": "bun scripts/release.ts publish"
@@ -106,10 +114,9 @@
106
114
  "eslint-config-prettier": "^10.1.8",
107
115
  "eslint-import-resolver-typescript": "^4.4.4",
108
116
  "eslint-plugin-import": "^2.32.0",
109
- "eslint-plugin-prettier": "^5.5.5",
110
- "fast-check": "^4.5.3",
117
+ "fast-check": "^4.6.0",
111
118
  "jsdom": "^27.4.0",
112
- "prettier": "^3.4.2",
119
+ "oxfmt": "^0.42.0",
113
120
  "react-devtools-core": "^7.0.1",
114
121
  "simple-git": "^3.30.0",
115
122
  "sinon": "^21.0.1",
@@ -138,7 +145,7 @@
138
145
  "ink-gradient": "^3.0.0",
139
146
  "ink-spinner": "^5.0.0",
140
147
  "ink-text-input": "^6.0.0",
141
- "marked": "^17.0.1",
148
+ "marked": "^16.4.2",
142
149
  "marked-terminal": "^7.3.0",
143
150
  "openai": "^6.16.0",
144
151
  "progress": "^2.0.3",
@@ -0,0 +1,77 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ async function fileExists(filePath) {
5
+ try {
6
+ await fs.access(filePath);
7
+ return true;
8
+ } catch {
9
+ return false;
10
+ }
11
+ }
12
+
13
+ async function listJsFiles(rootDir, baseDir = rootDir) {
14
+ const entries = await fs.readdir(rootDir, { withFileTypes: true });
15
+ const files = [];
16
+
17
+ for (const entry of entries) {
18
+ const full = path.join(rootDir, entry.name);
19
+ if (entry.isDirectory()) {
20
+ files.push(...(await listJsFiles(full, baseDir)));
21
+ continue;
22
+ }
23
+ if (entry.isFile() && entry.name.endsWith('.js')) {
24
+ files.push(path.relative(baseDir, full));
25
+ }
26
+ }
27
+
28
+ return files;
29
+ }
30
+
31
+ function toPosixPath(value) {
32
+ return value.split(path.sep).join('/');
33
+ }
34
+
35
+ async function writeCompatModule(dir2024, relativePath) {
36
+ const target = path.join(dir2024, relativePath);
37
+ const withoutExt = relativePath.replace(/\.js$/, '');
38
+ const requirePath = path.posix.join('..', '2025', toPosixPath(withoutExt));
39
+ const content = `'use strict';\n\nmodule.exports = require('${requirePath}');\n`;
40
+ await fs.mkdir(path.dirname(target), { recursive: true });
41
+ await fs.writeFile(target, content, 'utf8');
42
+ }
43
+
44
+ async function main() {
45
+ const root = path.resolve(process.cwd(), 'node_modules', 'es-abstract');
46
+ const dir2024 = path.join(root, '2024');
47
+ const dir2025 = path.join(root, '2025');
48
+
49
+ if (!(await fileExists(root)) || !(await fileExists(dir2025))) {
50
+ return;
51
+ }
52
+
53
+ await fs.mkdir(dir2024, { recursive: true });
54
+
55
+ const entries2025 = await listJsFiles(dir2025);
56
+ const missing = [];
57
+
58
+ for (const rel of entries2025) {
59
+ const target = path.join(dir2024, rel);
60
+ if (!(await fileExists(target))) {
61
+ missing.push(rel);
62
+ }
63
+ }
64
+
65
+ if (missing.length === 0) {
66
+ return;
67
+ }
68
+
69
+ for (const rel of missing) {
70
+ await writeCompatModule(dir2024, rel);
71
+ }
72
+ }
73
+
74
+ main().catch((error) => {
75
+ console.error(`Failed to apply es-abstract compatibility patch: ${error}`);
76
+ process.exitCode = 1;
77
+ });
@@ -1,26 +0,0 @@
1
- export function createFastifyServerBundle(deps) {
2
- const a2aServer = deps.createFastify();
3
- const sidecarServer = deps.createFastify();
4
- async function start() {
5
- if (deps.configureA2A) {
6
- await deps.configureA2A(a2aServer);
7
- }
8
- await a2aServer.register(deps.a2aPlugin);
9
- if (deps.configureSidecar) {
10
- await deps.configureSidecar(sidecarServer);
11
- }
12
- await sidecarServer.register(deps.sidecarPlugin);
13
- await a2aServer.listen(deps.a2aListen);
14
- await sidecarServer.listen(deps.sidecarListen);
15
- }
16
- async function close() {
17
- await Promise.all([a2aServer.close(), sidecarServer.close()]);
18
- }
19
- return {
20
- a2aServer,
21
- sidecarServer,
22
- start,
23
- close,
24
- };
25
- }
26
- //# sourceMappingURL=fastify-server-bundle.js.map
@@ -1,35 +0,0 @@
1
- import { buildFetchRequest, sendFetchResponse, } from './fastify-fetch-bridge.js';
2
- export function createSidecarFastifyPlugin(deps) {
3
- const baseUrl = deps.baseUrl ?? 'http://localhost';
4
- const allowConditional = deps.allowConditional ?? false;
5
- return async function sidecarFastifyPlugin(fastify) {
6
- for (const route of deps.routes) {
7
- if (route.exposure === 'forbidden')
8
- continue;
9
- if (route.scope !== 'both' && route.scope !== deps.scope)
10
- continue;
11
- if (!allowConditional && route.exposure === 'conditional')
12
- continue;
13
- const handler = async (request, reply) => {
14
- const fetchRequest = buildFetchRequest(request, baseUrl);
15
- if (deps.authorize) {
16
- const decision = await deps.authorize({
17
- request: fetchRequest,
18
- policyTag: route.policyTag,
19
- scope: deps.scope,
20
- });
21
- if (!decision.allowed) {
22
- await sendFetchResponse(reply, new Response(decision.message ?? 'Forbidden', {
23
- status: decision.status ?? 403,
24
- }));
25
- return;
26
- }
27
- }
28
- const response = await route.handler(fetchRequest);
29
- await sendFetchResponse(reply, response);
30
- };
31
- fastify.route({ method: route.method, url: route.path, handler });
32
- }
33
- };
34
- }
35
- //# sourceMappingURL=sidecar-fastify-plugin.js.map
@@ -1,47 +0,0 @@
1
- import os from 'node:os';
2
- import { defaultPathAdapter } from '../adapters/path/path-adapter.js';
3
- const DEFAULT_APP_NAME = 'SalmonLoop';
4
- export function resolveUserDataDir(options) {
5
- const platform = options?.platform ?? process.platform;
6
- const env = options?.env ?? process.env;
7
- const home = options?.homedir ?? os.homedir();
8
- const pathAdapter = options?.pathAdapter ?? defaultPathAdapter;
9
- const appName = options?.appName ?? DEFAULT_APP_NAME;
10
- if (platform === 'win32') {
11
- const base = env.APPDATA ?? env.LOCALAPPDATA ?? pathAdapter.join(home, 'AppData', 'Roaming');
12
- return pathAdapter.join(base, appName);
13
- }
14
- if (platform === 'darwin') {
15
- return pathAdapter.join(home, 'Library', 'Application Support', appName);
16
- }
17
- const xdg = env.XDG_DATA_HOME;
18
- const base = xdg && xdg.length > 0 ? xdg : pathAdapter.join(home, '.local', 'share');
19
- return pathAdapter.join(base, appName);
20
- }
21
- export function getSidecarSocketPath(options) {
22
- const platform = options?.platform ?? process.platform;
23
- const socketName = options?.socketName ?? 'agent-message.sock';
24
- if (platform === 'win32') {
25
- return '\\\\.\\pipe\\salmonloop-agent-message';
26
- }
27
- const dataDir = resolveUserDataDir(options);
28
- const pathAdapter = options?.pathAdapter ?? defaultPathAdapter;
29
- return pathAdapter.join(dataDir, 'sidecar', socketName);
30
- }
31
- export function isBunRuntime() {
32
- return typeof globalThis.Bun !== 'undefined';
33
- }
34
- export function createPipeListenOptions(path) {
35
- return { type: 'pipe', path };
36
- }
37
- export function createTcpListenOptions(port, host = '127.0.0.1') {
38
- return { type: 'tcp', port, host };
39
- }
40
- export function getSidecarListenOptions(options) {
41
- const platform = options?.platform ?? process.platform;
42
- if (platform === 'win32' && isBunRuntime()) {
43
- return { type: 'tcp', port: options?.sidecarPort ?? 7432, host: '127.0.0.1' };
44
- }
45
- return { type: 'pipe', path: getSidecarSocketPath(options) };
46
- }
47
- //# sourceMappingURL=sidecar-paths.js.map