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.
- package/dist/cli/argv/headless-detection.js +27 -0
- package/dist/cli/chat-flow.js +11 -0
- package/dist/cli/chat.js +161 -24
- package/dist/cli/commands/chat.js +30 -24
- package/dist/cli/commands/context.js +15 -3
- package/dist/cli/commands/flow-mode.js +63 -0
- package/dist/cli/commands/help-format.js +12 -0
- package/dist/cli/commands/registry.js +6 -7
- package/dist/cli/commands/run/benchmark-artifacts.js +41 -0
- package/dist/cli/commands/run/config-resolution.js +30 -24
- package/dist/cli/commands/run/early-errors.js +23 -0
- package/dist/cli/commands/run/handler.js +131 -44
- package/dist/cli/commands/run/headless-error-writer.js +8 -0
- package/dist/cli/commands/run/loop-params.js +3 -0
- package/dist/cli/commands/run/mode.js +2 -5
- package/dist/cli/commands/run/parse-options.js +18 -2
- package/dist/cli/commands/run/persist-session.js +10 -1
- package/dist/cli/commands/run/preflight.js +10 -0
- package/dist/cli/commands/run/reporter-factory.js +4 -0
- package/dist/cli/commands/run/runtime-llm.js +38 -11
- package/dist/cli/commands/run/runtime-options.js +2 -2
- package/dist/cli/commands/run/validate-options.js +0 -5
- package/dist/cli/commands/run/verbose.js +2 -7
- package/dist/cli/commands/serve.js +117 -90
- package/dist/cli/commands/tool-names.js +78 -78
- package/dist/cli/headless/anthropic-stream-normalized-encoder.js +6 -1
- package/dist/cli/headless/json-protocol.js +37 -0
- package/dist/cli/headless/native-stream-normalized-encoder.js +6 -1
- package/dist/cli/headless/protocol-metadata.js +22 -0
- package/dist/cli/headless/stream-json-protocol.js +34 -1
- package/dist/cli/index.js +6 -4
- package/dist/cli/locales/en.js +32 -6
- package/dist/cli/program-bootstrap.js +14 -4
- package/dist/cli/program-commands.js +9 -1
- package/dist/cli/program-options.js +1 -0
- package/dist/cli/reporters/anthropic-stream.js +7 -1
- package/dist/cli/reporters/json.js +4 -0
- package/dist/cli/reporters/stream-json.js +17 -2
- package/dist/cli/run-cli.js +5 -3
- package/dist/cli/slash/runtime.js +30 -15
- package/dist/cli/ui/components/CommandInput.js +7 -3
- package/dist/cli/ui/components/CommandSuggestionList.js +1 -1
- package/dist/cli/utils/command-option-source.js +13 -0
- package/dist/cli/utils/output-format.js +6 -0
- package/dist/cli/utils/resolve-cli-config.js +98 -0
- package/dist/cli/utils/verbose-level.js +8 -0
- package/dist/cli/utils/verify-resolver.js +8 -4
- package/dist/cli/utils/worktree-prepare-resolver.js +7 -3
- package/dist/core/adapters/fs/file-adapter.js +6 -0
- package/dist/core/adapters/fs/filesystem.js +2 -1
- package/dist/core/adapters/git/git-adapter.js +78 -1
- package/dist/core/benchmark/patch-artifact.js +124 -0
- package/dist/core/benchmark/swe-bench.js +25 -0
- package/dist/core/config/load.js +39 -18
- package/dist/core/config/merge.js +27 -0
- package/dist/core/config/paths.js +24 -5
- package/dist/core/config/resolve-llm.js +12 -0
- package/dist/core/config/resolve.js +7 -5
- package/dist/core/config/resolvers/server.js +0 -6
- package/dist/core/config/validate.js +94 -21
- package/dist/core/context/gatherers/metadata-gatherer.js +1 -0
- package/dist/core/context/gatherers/ripgrep-gatherer.js +84 -2
- package/dist/core/context/keywords.js +18 -4
- package/dist/core/context/service-deps.js +2 -2
- package/dist/core/context/service.js +8 -0
- package/dist/core/context/steps/context-gather.js +38 -0
- package/dist/core/context/summarization/summarizer.js +55 -12
- package/dist/core/context/targeting/target-resolver.js +4 -4
- package/dist/core/extensions/index.js +23 -5
- package/dist/core/extensions/paths.js +31 -0
- package/dist/core/extensions/schemas.js +8 -5
- package/dist/core/facades/cli-chat.js +6 -2
- package/dist/core/facades/cli-command-chat.js +2 -1
- package/dist/core/facades/cli-command-tool-names.js +2 -0
- package/dist/core/facades/cli-context.js +1 -0
- package/dist/core/facades/cli-observability.js +1 -1
- package/dist/core/facades/cli-run-handler.js +4 -2
- package/dist/core/facades/cli-run-persist-session.js +1 -0
- package/dist/core/facades/cli-serve.js +2 -4
- package/dist/core/facades/cli-utils-worktree.js +1 -1
- package/dist/core/failure/diagnostics.js +53 -1
- package/dist/core/grizzco/dsl/llm-strategy.js +4 -1
- package/dist/core/grizzco/engine/outcome/loop-result-mapper.js +67 -9
- package/dist/core/grizzco/engine/pipeline/pipeline.js +6 -2
- package/dist/core/grizzco/engine/transaction/attempt-failure.js +90 -15
- package/dist/core/grizzco/engine/transaction/report-mapper.js +17 -3
- package/dist/core/grizzco/engine/transaction/transaction-runner.js +173 -7
- package/dist/core/grizzco/flows/AutopilotFlow.js +18 -0
- package/dist/core/grizzco/flows/flow-dispatch.js +11 -0
- package/dist/core/grizzco/steps/answer.js +13 -14
- package/dist/core/grizzco/steps/autopilot.js +396 -0
- package/dist/core/grizzco/steps/cache-sharing.js +29 -0
- package/dist/core/grizzco/steps/explore.js +37 -21
- package/dist/core/grizzco/steps/generateReview.js +2 -5
- package/dist/core/grizzco/steps/patch/apply-check.js +10 -0
- package/dist/core/grizzco/steps/patch/diff-normalization.js +70 -0
- package/dist/core/grizzco/steps/patch/diff-salvage.js +46 -0
- package/dist/core/grizzco/steps/patch/prompt-input.js +42 -0
- package/dist/core/grizzco/steps/patch.js +105 -146
- package/dist/core/grizzco/steps/plan.js +101 -25
- package/dist/core/grizzco/steps/preflight.js +5 -3
- package/dist/core/grizzco/steps/request-assembly.js +78 -0
- package/dist/core/grizzco/steps/research.js +39 -36
- package/dist/core/grizzco/steps/tool-runtime.js +47 -0
- package/dist/core/grizzco/steps/verify-shared.js +23 -0
- package/dist/core/grizzco/steps/verify.js +13 -21
- package/dist/core/intent/chat-intent.js +0 -4
- package/dist/core/llm/ai-sdk/chat-executor.js +2 -0
- package/dist/core/llm/ai-sdk/high-level-phase-specs.js +63 -0
- package/dist/core/llm/ai-sdk/message-mapper.js +40 -10
- package/dist/core/llm/ai-sdk/provider-factory.js +14 -0
- package/dist/core/llm/ai-sdk/request-params.js +74 -1
- package/dist/core/llm/ai-sdk/result-mapper.js +16 -0
- package/dist/core/llm/ai-sdk.js +112 -27
- package/dist/core/llm/capabilities.js +12 -0
- package/dist/core/llm/contracts/repair.js +36 -30
- package/dist/core/llm/errors.js +83 -2
- package/dist/core/llm/message-composition.js +7 -22
- package/dist/core/llm/phase-router.js +29 -10
- package/dist/core/llm/redact.js +28 -3
- package/dist/core/llm/registry.js +2 -0
- package/dist/core/llm/request-augmentation.js +55 -0
- package/dist/core/llm/request-envelope.js +334 -0
- package/dist/core/llm/shared-request-assembly.js +35 -0
- package/dist/core/llm/stream-utils.js +13 -4
- package/dist/core/llm/utils.js +18 -29
- package/dist/core/memory/relevant-retrieval.js +144 -0
- package/dist/core/observability/logger.js +11 -2
- package/dist/core/patch/diff.js +1 -0
- package/dist/core/prompts/registry.js +39 -2
- package/dist/core/prompts/runtime.js +50 -12
- package/dist/core/prompts/templates/phases/patch_user.hbs +2 -5
- package/dist/core/prompts/templates/phases/research_user.hbs +11 -0
- package/dist/core/prompts/templates/phases/review_user.hbs +3 -0
- package/dist/core/prompts/templates/system/answer_system.hbs +5 -0
- package/dist/core/prompts/templates/system/autopilot_system.hbs +11 -0
- package/dist/core/prompts/templates/system/explore_system.hbs +14 -23
- package/dist/core/prompts/templates/system/main_system.hbs +4 -16
- package/dist/core/prompts/templates/system/patch_system.hbs +39 -8
- package/dist/core/prompts/templates/system/plan_system.hbs +86 -1
- package/dist/core/prompts/templates/system/research_system.hbs +2 -0
- package/dist/core/protocols/a2a/agent-card.js +3 -2
- package/dist/core/protocols/a2a/sdk/executor.js +8 -6
- package/dist/core/protocols/a2a/sdk/server.js +0 -1
- package/dist/core/protocols/acp/formal-agent.js +221 -55
- package/dist/core/protocols/acp/handlers.js +5 -1
- package/dist/core/protocols/acp/permission-provider.js +21 -1
- package/dist/core/protocols/shared/execution-request.js +24 -0
- package/dist/core/protocols/shared/flow-mode-mapping.js +23 -0
- package/dist/core/public-capabilities/flow-mode-metadata.js +39 -0
- package/dist/core/public-capabilities/projections.js +29 -0
- package/dist/core/public-capabilities/registry.js +26 -0
- package/dist/core/public-capabilities/types.js +2 -0
- package/dist/core/runtime/agent-server-runtime.js +47 -43
- package/dist/core/runtime/execution-profile.js +67 -0
- package/dist/core/session/artifact-state.js +160 -0
- package/dist/core/session/compaction/index.js +183 -0
- package/dist/core/session/compaction/microcompact.js +78 -0
- package/dist/core/session/compaction/tracking.js +48 -0
- package/dist/core/session/compaction/types.js +11 -0
- package/dist/core/session/compression.js +12 -4
- package/dist/core/session/manager.js +247 -10
- package/dist/core/session/pruning-strategy.js +55 -9
- package/dist/core/session/replacement-preview-provider.js +24 -0
- package/dist/core/session/replacement-state.js +131 -0
- package/dist/core/session/resume-repair/pipeline.js +79 -0
- package/dist/core/session/resume-repair/stages/load-raw-archive-state.js +40 -0
- package/dist/core/session/resume-repair/stages/reattach-runtime-state.js +8 -0
- package/dist/core/session/resume-repair/stages/recover-orphaned-branches.js +10 -0
- package/dist/core/session/resume-repair/stages/relink-boundary-and-tail.js +36 -0
- package/dist/core/session/resume-repair/stages/replay-startup-hooks.js +23 -0
- package/dist/core/session/resume-repair/stages/rescue-stale-metadata.js +17 -0
- package/dist/core/session/resume-repair/types.js +2 -0
- package/dist/core/session/summary-sync.js +164 -13
- package/dist/core/session/token-tracker.js +6 -0
- package/dist/core/skills/audit.js +34 -0
- package/dist/core/skills/bridge.js +84 -7
- package/dist/core/skills/discovery.js +94 -0
- package/dist/core/skills/feature-flags.js +52 -0
- package/dist/core/skills/index.js +1 -1
- package/dist/core/skills/loader.js +195 -20
- package/dist/core/skills/parser.js +296 -24
- package/dist/core/skills/permissions.js +117 -0
- package/dist/core/skills/runtime/MicroTaskRunner.js +10 -4
- package/dist/core/skills/runtime/SkillRunner.js +240 -61
- package/dist/core/strata/layers/shadow-driver/shadow-driver.js +37 -7
- package/dist/core/strata/layers/worktree.js +70 -13
- package/dist/core/strata/runtime/synchronizer.js +29 -2
- package/dist/core/streaming/stream-assembler.js +75 -31
- package/dist/core/sub-agent/context-snapshot.js +156 -0
- package/dist/core/sub-agent/core/loop.js +1 -1
- package/dist/core/sub-agent/core/manager.js +119 -20
- package/dist/core/sub-agent/dispatch-policy.js +29 -0
- package/dist/core/sub-agent/prefix-consistency.js +48 -0
- package/dist/core/sub-agent/registry-defaults.js +4 -0
- package/dist/core/sub-agent/tools/task-spawn.js +79 -2
- package/dist/core/sub-agent/types.js +134 -5
- package/dist/core/tools/audit.js +13 -4
- package/dist/core/tools/builtin/ast-grep.js +1 -1
- package/dist/core/tools/builtin/ast.js +1 -1
- package/dist/core/tools/builtin/benchmark.js +360 -0
- package/dist/core/tools/builtin/code-search/backends/rg.js +2 -1
- package/dist/core/tools/builtin/code-search/executor.js +6 -1
- package/dist/core/tools/builtin/code-search/spec.js +26 -2
- package/dist/core/tools/builtin/fs.js +256 -23
- package/dist/core/tools/builtin/git.js +2 -2
- package/dist/core/tools/builtin/index.js +51 -2
- package/dist/core/tools/builtin/interaction.js +8 -1
- package/dist/core/tools/builtin/plan.js +37 -15
- package/dist/core/tools/builtin/shell.js +1 -1
- package/dist/core/tools/loader.js +39 -16
- package/dist/core/tools/mapper.js +17 -3
- package/dist/core/tools/parallel/scheduler.js +35 -4
- package/dist/core/tools/permissions/permission-rules.js +5 -10
- package/dist/core/tools/policy.js +6 -1
- package/dist/core/tools/recoverable-tool-errors.js +10 -0
- package/dist/core/tools/router.js +24 -6
- package/dist/core/tools/session.js +458 -48
- package/dist/core/tools/tool-visibility.js +62 -0
- package/dist/core/tools/types.js +9 -1
- package/dist/core/types/execution.js +4 -0
- package/dist/core/types/flow-mode.js +8 -0
- package/dist/core/utils/path.js +52 -0
- package/dist/core/verification/runner.js +4 -1
- package/dist/interfaces/cli/task-runner.js +4 -3
- package/dist/languages/typescript/index.js +4 -1
- package/dist/locales/en.js +87 -2
- package/dist/utils/eol.js +1 -1
- package/package.json +15 -8
- package/scripts/fix-es-abstract-compat.js +77 -0
- package/dist/core/runtime/fastify-server-bundle.js +0 -26
- package/dist/core/runtime/sidecar-fastify-plugin.js +0 -35
- package/dist/core/runtime/sidecar-paths.js +0 -47
- 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
|
package/dist/core/tools/types.js
CHANGED
|
@@ -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
|
package/dist/core/utils/path.js
CHANGED
|
@@ -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
|
-
|
|
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;
|
package/dist/locales/en.js
CHANGED
|
@@ -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
|
|
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: '
|
|
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(/
|
|
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
|
+
"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
|
|
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": "
|
|
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
|
-
"
|
|
110
|
-
"fast-check": "^4.5.3",
|
|
117
|
+
"fast-check": "^4.6.0",
|
|
111
118
|
"jsdom": "^27.4.0",
|
|
112
|
-
"
|
|
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": "^
|
|
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
|