@superjackfruitlabs/salaam 0.0.3 → 0.0.5
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/CHANGELOG.md +86 -0
- package/README.md +12 -11
- package/dist/src/acp-desk.js +140 -0
- package/dist/src/acp-outcome.js +182 -18
- package/dist/src/acp.js +296 -15
- package/dist/src/agent-profiles.js +45 -0
- package/dist/src/agentpod-authority.js +169 -11
- package/dist/src/agentpod-default-config.js +12 -0
- package/dist/src/agentpod-work-decision-protocol.js +40 -6
- package/dist/src/agentpod-work-decisions.js +108 -4
- package/dist/src/agentpod-work.js +1214 -127
- package/dist/src/approval-rules.js +287 -0
- package/dist/src/attach.js +3 -1
- package/dist/src/autonomy.js +80 -9
- package/dist/src/board-reads.js +106 -0
- package/dist/src/children.js +83 -0
- package/dist/src/cli-help.js +61 -6
- package/dist/src/cli.js +140 -4
- package/dist/src/command-danger.js +797 -0
- package/dist/src/command-network.js +200 -0
- package/dist/src/command-sandbox.js +327 -0
- package/dist/src/custom-commands.js +159 -0
- package/dist/src/danger-classifier.js +286 -0
- package/dist/src/execution-evidence.js +33 -1
- package/dist/src/git-helpers.js +160 -0
- package/dist/src/hooks.js +351 -0
- package/dist/src/host-bind.js +111 -0
- package/dist/src/host-breaker.js +88 -0
- package/dist/src/host-start.js +41 -1
- package/dist/src/host.js +284 -6
- package/dist/src/house-extension.js +292 -61
- package/dist/src/local-coding.js +726 -35
- package/dist/src/local-edit-helper.js +25 -0
- package/dist/src/local-edits.js +168 -6
- package/dist/src/local-undo.js +25 -16
- package/dist/src/managed.js +1 -1
- package/dist/src/mentions.js +277 -0
- package/dist/src/operator-mcp-cli.js +107 -0
- package/dist/src/operator-mcp.js +342 -0
- package/dist/src/persona.js +31 -0
- package/dist/src/pi-sessions.js +5 -1
- package/dist/src/pi.js +22 -1
- package/dist/src/project-instructions.js +195 -0
- package/dist/src/protocol.js +9 -3
- package/dist/src/rate-limit-retries.js +62 -0
- package/dist/src/recurring-work.js +1 -0
- package/dist/src/repository-snapshots.js +5 -2
- package/dist/src/run-grants.js +62 -0
- package/dist/src/service.js +482 -10
- package/dist/src/session-pick.js +77 -0
- package/dist/src/shell-passthrough.js +39 -0
- package/dist/src/station-checkpoints.js +139 -0
- package/dist/src/station-config.js +8 -1
- package/dist/src/station-files.js +20 -1
- package/dist/src/station-task-verification.js +6 -3
- package/dist/src/station-work.js +315 -22
- package/dist/src/store.js +70 -4
- package/dist/src/supervisor.js +408 -25
- package/dist/src/task-budget.js +39 -3
- package/dist/src/task-context.js +8 -2
- package/dist/src/task-critic.js +115 -0
- package/dist/src/task-driver.js +46 -2
- package/dist/src/task-policy.js +44 -12
- package/dist/src/task-verification.js +42 -9
- package/dist/src/task-work.js +47 -0
- package/dist/src/terminal-status.js +88 -0
- package/dist/src/tool-identity.js +69 -0
- package/dist/src/tui-activity.js +99 -0
- package/dist/src/tui-classifier.js +25 -0
- package/dist/src/tui-client.js +186 -5
- package/dist/src/tui-commands.js +23 -5
- package/dist/src/tui-composer.js +113 -0
- package/dist/src/tui-keymap.js +116 -0
- package/dist/src/tui-mentions.js +38 -0
- package/dist/src/tui-modals.js +157 -34
- package/dist/src/tui-notify.js +62 -0
- package/dist/src/tui-review.js +55 -0
- package/dist/src/tui-turn-keys.js +52 -0
- package/dist/src/tui-view.js +243 -69
- package/dist/src/tui.js +875 -118
- package/dist/src/turn-checkpoints.js +221 -0
- package/dist/src/turn-rewind.js +168 -0
- package/dist/src/usage.js +1 -1
- package/dist/src/web-fetch.js +114 -0
- package/dist/src/web-guard.js +163 -0
- package/dist/src/web-search.js +302 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/src/acp-desk.ts +155 -0
- package/src/acp-outcome.ts +174 -20
- package/src/acp.ts +386 -30
- package/src/agent-profiles.ts +48 -0
- package/src/agentpod-authority.ts +234 -15
- package/src/agentpod-default-config.ts +16 -0
- package/src/agentpod-work-decision-protocol.ts +69 -8
- package/src/agentpod-work-decisions.ts +123 -5
- package/src/agentpod-work.ts +1455 -152
- package/src/approval-rules.ts +360 -0
- package/src/attach.ts +4 -1
- package/src/autonomy.ts +111 -10
- package/src/board-reads.ts +148 -0
- package/src/children.ts +112 -0
- package/src/cli-help.ts +60 -6
- package/src/cli.ts +174 -4
- package/src/command-danger.ts +886 -0
- package/src/command-network.ts +215 -0
- package/src/command-sandbox.ts +393 -0
- package/src/custom-commands.ts +175 -0
- package/src/danger-classifier.ts +321 -0
- package/src/execution-evidence.ts +31 -1
- package/src/git-helpers.ts +177 -0
- package/src/hooks.ts +425 -0
- package/src/host-bind.ts +156 -0
- package/src/host-breaker.ts +89 -0
- package/src/host-start.ts +51 -1
- package/src/host.ts +365 -6
- package/src/house-extension.ts +313 -60
- package/src/local-coding.ts +894 -43
- package/src/local-edit-helper.ts +26 -0
- package/src/local-edits.ts +191 -8
- package/src/local-undo.ts +29 -14
- package/src/managed.ts +2 -2
- package/src/mentions.ts +304 -0
- package/src/operator-mcp-cli.ts +108 -0
- package/src/operator-mcp.ts +420 -0
- package/src/persona.ts +37 -0
- package/src/pi-sessions.ts +9 -1
- package/src/pi.ts +23 -1
- package/src/project-instructions.ts +229 -0
- package/src/protocol.ts +25 -3
- package/src/rate-limit-retries.ts +69 -0
- package/src/recurring-work.ts +1 -0
- package/src/repository-snapshots.ts +5 -2
- package/src/run-grants.ts +107 -0
- package/src/service.ts +709 -10
- package/src/session-pick.ts +102 -0
- package/src/shell-passthrough.ts +38 -0
- package/src/station-checkpoints.ts +183 -0
- package/src/station-config.ts +10 -1
- package/src/station-files.ts +20 -1
- package/src/station-task-verification.ts +6 -3
- package/src/station-work.ts +369 -20
- package/src/store.ts +70 -3
- package/src/supervisor.ts +463 -26
- package/src/task-budget.ts +48 -3
- package/src/task-context.ts +9 -2
- package/src/task-critic.ts +171 -0
- package/src/task-driver.ts +49 -2
- package/src/task-policy.ts +65 -13
- package/src/task-verification.ts +53 -9
- package/src/task-work.ts +75 -0
- package/src/terminal-status.ts +103 -0
- package/src/tool-identity.ts +110 -0
- package/src/tui-activity.ts +133 -0
- package/src/tui-classifier.ts +38 -0
- package/src/tui-client.ts +239 -8
- package/src/tui-commands.ts +49 -10
- package/src/tui-composer.ts +124 -0
- package/src/tui-keymap.ts +152 -0
- package/src/tui-mentions.ts +43 -0
- package/src/tui-modals.ts +173 -43
- package/src/tui-notify.ts +77 -0
- package/src/tui-review.ts +76 -0
- package/src/tui-turn-keys.ts +77 -0
- package/src/tui-view.ts +341 -88
- package/src/tui.ts +1047 -137
- package/src/turn-checkpoints.ts +253 -0
- package/src/turn-rewind.ts +258 -0
- package/src/usage.ts +1 -1
- package/src/web-fetch.ts +140 -0
- package/src/web-guard.ts +195 -0
- package/src/web-search.ts +402 -0
package/src/cli.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { loadDangerClassifierOptions } from './danger-classifier.js';
|
|
3
|
+
import { loadWebSearchConfig } from './web-search.js';
|
|
4
|
+
import { SANDBOX_LEVELS, type SandboxLevel } from './command-sandbox.js';
|
|
2
5
|
import { acp } from './acp.js';
|
|
3
6
|
import { homedir } from 'node:os';
|
|
4
7
|
import { join, resolve, dirname } from 'node:path';
|
|
@@ -14,9 +17,13 @@ import {
|
|
|
14
17
|
realpathSync,
|
|
15
18
|
writeFileSync,
|
|
16
19
|
fsyncSync,
|
|
20
|
+
existsSync,
|
|
17
21
|
} from 'node:fs';
|
|
18
22
|
import { ROOT, VERSION } from './config.js';
|
|
19
23
|
import { cliHelp, hasHelpFlag } from './cli-help.js';
|
|
24
|
+
import { mcpCli, MCP_HELP } from './operator-mcp-cli.js';
|
|
25
|
+
import { operatorMcpPath, readOperatorMcpFile } from './operator-mcp.js';
|
|
26
|
+
import { defaultAgentPodConfig } from './agentpod-default-config.js';
|
|
20
27
|
import { SalaamService } from './service.js';
|
|
21
28
|
import { call } from './transport.js';
|
|
22
29
|
import { attach, acquireControl, Outbox } from './attach.js';
|
|
@@ -62,6 +69,19 @@ async function main(): Promise<void> {
|
|
|
62
69
|
console.log('salaam ' + VERSION);
|
|
63
70
|
return;
|
|
64
71
|
}
|
|
72
|
+
if (args[0] === '-c' || args[0] === '--continue') {
|
|
73
|
+
const { continueArgs } = await import('./session-pick.js');
|
|
74
|
+
args.splice(0, args.length, ...continueArgs(args)!);
|
|
75
|
+
}
|
|
76
|
+
if (args[0] === 'mcp') {
|
|
77
|
+
// Parsed before global help: a declared command's own flags follow "--".
|
|
78
|
+
const rest = args.slice(1);
|
|
79
|
+
const dash = rest.indexOf('--');
|
|
80
|
+
const flags = dash < 0 ? rest : rest.slice(0, dash);
|
|
81
|
+
if (!rest.length || flags.includes('--help') || flags.includes('-h')) console.log(MCP_HELP);
|
|
82
|
+
else console.log(mcpCli(rest));
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
65
85
|
if (
|
|
66
86
|
(!args.length && !(process.stdin.isTTY && process.stdout.isTTY)) ||
|
|
67
87
|
args[0] === 'help' ||
|
|
@@ -494,7 +514,21 @@ async function main(): Promise<void> {
|
|
|
494
514
|
return;
|
|
495
515
|
}
|
|
496
516
|
if (group === 'host') {
|
|
497
|
-
const {
|
|
517
|
+
const {
|
|
518
|
+
planHost,
|
|
519
|
+
readHost,
|
|
520
|
+
hostUnit,
|
|
521
|
+
runHost,
|
|
522
|
+
hostReceipt,
|
|
523
|
+
hostToolsUser,
|
|
524
|
+
hostApprovalTtlMs,
|
|
525
|
+
hostAllowsUnsandboxed,
|
|
526
|
+
hostAllowsFullAccessSessions,
|
|
527
|
+
hostAllowsYoloSessions,
|
|
528
|
+
hostDangerClassifier,
|
|
529
|
+
hostCommandNetwork,
|
|
530
|
+
hostReadPaths,
|
|
531
|
+
} = await import('./host.js');
|
|
498
532
|
if (verb?.startsWith('config-')) {
|
|
499
533
|
const file = option('--manifest');
|
|
500
534
|
if (!file) throw Error('Supply --manifest FILE');
|
|
@@ -526,6 +560,44 @@ async function main(): Promise<void> {
|
|
|
526
560
|
);
|
|
527
561
|
return;
|
|
528
562
|
}
|
|
563
|
+
if (verb === 'bind') {
|
|
564
|
+
const { bindHost } = await import('./host-bind.js');
|
|
565
|
+
const required = (name: string) => {
|
|
566
|
+
const v = option(name);
|
|
567
|
+
if (!v) throw new Error('Supply ' + name);
|
|
568
|
+
return v;
|
|
569
|
+
};
|
|
570
|
+
console.log(
|
|
571
|
+
JSON.stringify(
|
|
572
|
+
await bindHost({
|
|
573
|
+
organization_id: required('--organization'),
|
|
574
|
+
node_id: required('--node'),
|
|
575
|
+
station_key: required('--station-key'),
|
|
576
|
+
workspace: required('--workspace'),
|
|
577
|
+
tools_user: required('--tools-user'),
|
|
578
|
+
files: required('--files'),
|
|
579
|
+
runtime_root: required('--runtime-root'),
|
|
580
|
+
runtime_image_digest: required('--runtime-image-digest'),
|
|
581
|
+
operator_group: option('--operator-group'),
|
|
582
|
+
dir: option('--dir'),
|
|
583
|
+
state: explicitState ? state : undefined,
|
|
584
|
+
provider: option('--provider'),
|
|
585
|
+
model: option('--model'),
|
|
586
|
+
mcp_config: option('--mcp-config'),
|
|
587
|
+
persona: option('--persona'),
|
|
588
|
+
managed_mcp_config: option('--managed-mcp-config'),
|
|
589
|
+
}),
|
|
590
|
+
),
|
|
591
|
+
);
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
if (verb === 'unit-start') {
|
|
595
|
+
const { startHostUnit } = await import('./host-start.js');
|
|
596
|
+
const unit = option('--unit');
|
|
597
|
+
if (!unit || !explicitState) throw new Error('Supply --unit UNIT and --state DIR');
|
|
598
|
+
console.log(JSON.stringify(await startHostUnit(unit, state)));
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
529
601
|
const file = option('--manifest');
|
|
530
602
|
if (!file) throw new Error('Supply --manifest FILE');
|
|
531
603
|
if (verb === 'inspect') {
|
|
@@ -585,9 +657,32 @@ async function main(): Promise<void> {
|
|
|
585
657
|
: {}),
|
|
586
658
|
...(m.schema === 5 || m.schema === 6 ? { stationConfig: m.station_execution } : {}),
|
|
587
659
|
...(m.schema === 6 ? { agentpodWorkProgression: true } : {}),
|
|
660
|
+
...(m.schema === 6 && m.operator_access
|
|
661
|
+
? { operatorAccess: m.operator_access }
|
|
662
|
+
: {}),
|
|
663
|
+
...(m.schema === 6 && m.operator_mcp
|
|
664
|
+
? { operatorMcpConfig: m.operator_mcp.config }
|
|
665
|
+
: {}),
|
|
666
|
+
...(m.schema === 6 && m.persona ? { personaConfig: m.persona } : {}),
|
|
588
667
|
}),
|
|
589
668
|
hostManifestDigest: digest(m),
|
|
669
|
+
hostReceipt: hostReceipt(m),
|
|
670
|
+
toolsUser: hostToolsUser(m),
|
|
590
671
|
providerRoute: m.provider,
|
|
672
|
+
approvalTtlMs: hostApprovalTtlMs(m),
|
|
673
|
+
...(hostAllowsUnsandboxed(m) ? { unsandboxedCommands: 'allow' as const } : {}),
|
|
674
|
+
// A host session may choose full access only when the reviewed manifest says so.
|
|
675
|
+
allowFullAccessSessions: hostAllowsFullAccessSessions(m),
|
|
676
|
+
allowYoloSessions: hostAllowsYoloSessions(m),
|
|
677
|
+
// The command reviewer only as the reviewed manifest names it (forbidden when absent).
|
|
678
|
+
...(hostDangerClassifier(m).config
|
|
679
|
+
? { dangerClassifierConfig: hostDangerClassifier(m).config }
|
|
680
|
+
: {}),
|
|
681
|
+
...(hostDangerClassifier(m).pin
|
|
682
|
+
? { dangerClassifierPin: hostDangerClassifier(m).pin }
|
|
683
|
+
: {}),
|
|
684
|
+
...(hostCommandNetwork(m) ? { commandNetwork: hostCommandNetwork(m)! } : {}),
|
|
685
|
+
...(hostReadPaths(m).length ? { localSandboxReadPaths: hostReadPaths(m) } : {}),
|
|
591
686
|
});
|
|
592
687
|
if (process.connected) process.once('disconnect', () => void service.close());
|
|
593
688
|
for (const signal of ['SIGTERM', 'SIGINT'] as const)
|
|
@@ -614,6 +709,20 @@ async function main(): Promise<void> {
|
|
|
614
709
|
});
|
|
615
710
|
return;
|
|
616
711
|
}
|
|
712
|
+
if (group === 'code' || group === 'here') {
|
|
713
|
+
const { parseCodeStart } = await import('./session-pick.js');
|
|
714
|
+
const start = parseCodeStart(args.slice(1));
|
|
715
|
+
const { tui } = await import('./tui.js');
|
|
716
|
+
await tui({
|
|
717
|
+
state,
|
|
718
|
+
start,
|
|
719
|
+
cwd: option('--cwd'),
|
|
720
|
+
takeover: args.includes('--takeover'),
|
|
721
|
+
codingRoot: option('--coding-root'),
|
|
722
|
+
codingSocket: option('--coding-socket'),
|
|
723
|
+
});
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
617
726
|
if (
|
|
618
727
|
!group ||
|
|
619
728
|
group === 'tui' ||
|
|
@@ -767,7 +876,7 @@ async function main(): Promise<void> {
|
|
|
767
876
|
return;
|
|
768
877
|
}
|
|
769
878
|
if (group === 'acp') {
|
|
770
|
-
await acp(state, { coding: args.includes('--coding') });
|
|
879
|
+
await acp(state, { coding: args.includes('--coding'), local: args.includes('--local') });
|
|
771
880
|
return;
|
|
772
881
|
}
|
|
773
882
|
if (group === 'providers' && verb === 'list') {
|
|
@@ -1553,24 +1662,65 @@ async function main(): Promise<void> {
|
|
|
1553
1662
|
codingSocket = option('--coding-socket'),
|
|
1554
1663
|
harnessConfig = option('--harness-config'),
|
|
1555
1664
|
a2aConfig = option('--a2a-config'),
|
|
1556
|
-
agentpodConfig =
|
|
1557
|
-
|
|
1665
|
+
agentpodConfig =
|
|
1666
|
+
option('--agentpod-config') ?? defaultAgentPodConfig(process.env, existsSync),
|
|
1667
|
+
a2aListenConfig = option('--a2a-listen-config'),
|
|
1668
|
+
mcpConfig = resolve(option('--mcp-config') ?? operatorMcpPath(process.env)),
|
|
1669
|
+
toolsUser = option('--tools-user') ?? (process.env.SALAAM_TOOLS_USER || undefined),
|
|
1670
|
+
localSandbox = option('--local-sandbox') ?? (process.env.SALAAM_LOCAL_SANDBOX || undefined),
|
|
1671
|
+
unsandboxedCommands =
|
|
1672
|
+
option('--unsandboxed-commands') ?? (process.env.SALAAM_UNSANDBOXED_COMMANDS || undefined),
|
|
1673
|
+
localSandboxRead = (
|
|
1674
|
+
option('--local-sandbox-read') ??
|
|
1675
|
+
(process.env.SALAAM_LOCAL_SANDBOX_READ || '')
|
|
1676
|
+
)
|
|
1677
|
+
.split(',')
|
|
1678
|
+
.map((p) => p.trim())
|
|
1679
|
+
.filter(Boolean),
|
|
1680
|
+
webSearchConfig =
|
|
1681
|
+
option('--web-search-config') ?? (process.env.SALAAM_WEB_SEARCH_CONFIG || undefined),
|
|
1682
|
+
dangerClassifierConfig =
|
|
1683
|
+
option('--danger-classifier-config') ??
|
|
1684
|
+
(process.env.SALAAM_DANGER_CLASSIFIER_CONFIG || undefined);
|
|
1685
|
+
// Fail early on a bad command-reviewer config; its key is read from the named variable, never printed.
|
|
1686
|
+
if (dangerClassifierConfig)
|
|
1687
|
+
loadDangerClassifierOptions(
|
|
1688
|
+
JSON.parse(readFileSync(resolve(dangerClassifierConfig), 'utf8')),
|
|
1689
|
+
);
|
|
1690
|
+
// Fail early on a bad web search config; its keys are read, never printed.
|
|
1691
|
+
if (webSearchConfig) loadWebSearchConfig(resolve(webSearchConfig));
|
|
1692
|
+
if (localSandbox !== undefined && !(SANDBOX_LEVELS as readonly string[]).includes(localSandbox))
|
|
1693
|
+
throw Error('--local-sandbox is read-only, workspace-write or full-access');
|
|
1694
|
+
if (unsandboxedCommands !== undefined && unsandboxedCommands !== 'allow')
|
|
1695
|
+
throw Error('--unsandboxed-commands is allow or absent');
|
|
1558
1696
|
if (foreground) {
|
|
1559
1697
|
const service = await SalaamService.open({
|
|
1560
1698
|
stateDir: state,
|
|
1561
1699
|
providerRoute: route,
|
|
1562
1700
|
agentpodConfig: agentpodConfig ? resolve(agentpodConfig) : undefined,
|
|
1701
|
+
operatorMcpConfig: mcpConfig,
|
|
1563
1702
|
codingRoot: codingRoot ? resolve(codingRoot) : undefined,
|
|
1564
1703
|
codingSocket: codingSocket ? resolve(codingSocket) : undefined,
|
|
1565
1704
|
harnessConfig: harnessConfig ? resolve(harnessConfig) : undefined,
|
|
1566
1705
|
a2aConfig: a2aConfig ? resolve(a2aConfig) : undefined,
|
|
1567
1706
|
a2aListenConfig: a2aListenConfig ? resolve(a2aListenConfig) : undefined,
|
|
1707
|
+
toolsUser,
|
|
1708
|
+
...(localSandbox ? { localSandbox: localSandbox as SandboxLevel } : {}),
|
|
1709
|
+
...(unsandboxedCommands ? { unsandboxedCommands: 'allow' as const } : {}),
|
|
1710
|
+
...(localSandboxRead.length ? { localSandboxReadPaths: localSandboxRead } : {}),
|
|
1711
|
+
...(webSearchConfig ? { webSearchConfig: resolve(webSearchConfig) } : {}),
|
|
1712
|
+
...(dangerClassifierConfig
|
|
1713
|
+
? { dangerClassifierConfig: resolve(dangerClassifierConfig) }
|
|
1714
|
+
: {}),
|
|
1568
1715
|
effectConnector: effectSocket
|
|
1569
1716
|
? new SocketEffectConnector(resolve(effectSocket), { opaque })
|
|
1570
1717
|
: undefined,
|
|
1571
1718
|
});
|
|
1572
1719
|
const warning = service.supervisor.providerCapabilities().warning;
|
|
1573
1720
|
if (warning) console.error(warning);
|
|
1721
|
+
// Only a live provider has a credential to share; the offline proof route stays quiet.
|
|
1722
|
+
if (service.toolIdentity.warning && route.provider !== 'salaam-proof')
|
|
1723
|
+
console.error('warning: ' + service.toolIdentity.warning);
|
|
1574
1724
|
process.stdout.write(JSON.stringify({ socket, service: 'started' }) + '\n');
|
|
1575
1725
|
for (const signal of ['SIGINT', 'SIGTERM'] as const)
|
|
1576
1726
|
process.once(signal, () => {
|
|
@@ -1589,6 +1739,7 @@ async function main(): Promise<void> {
|
|
|
1589
1739
|
coding_socket?: string | null;
|
|
1590
1740
|
agentpod_config?: string | null;
|
|
1591
1741
|
agentpod_pins_digest?: string | null;
|
|
1742
|
+
operator_mcp?: { config: string; digest: string } | null;
|
|
1592
1743
|
}
|
|
1593
1744
|
| undefined;
|
|
1594
1745
|
try {
|
|
@@ -1613,6 +1764,15 @@ async function main(): Promise<void> {
|
|
|
1613
1764
|
throw new Error(
|
|
1614
1765
|
'Service is already running with another coding configuration; stop it first',
|
|
1615
1766
|
);
|
|
1767
|
+
if ((health.operator_mcp?.config ?? null) !== mcpConfig)
|
|
1768
|
+
throw new Error('Service is already running with another MCP config; stop it first');
|
|
1769
|
+
if (
|
|
1770
|
+
health.operator_mcp &&
|
|
1771
|
+
health.operator_mcp.digest !== digest(readOperatorMcpFile(mcpConfig))
|
|
1772
|
+
)
|
|
1773
|
+
console.error(
|
|
1774
|
+
'Declared MCP servers changed since the service started; run salaam service stop, then start, to apply them',
|
|
1775
|
+
);
|
|
1616
1776
|
console.log('Salaam service already running');
|
|
1617
1777
|
return;
|
|
1618
1778
|
}
|
|
@@ -1640,6 +1800,16 @@ async function main(): Promise<void> {
|
|
|
1640
1800
|
...(a2aConfig ? ['--a2a-config', resolve(a2aConfig)] : []),
|
|
1641
1801
|
...(agentpodConfig ? ['--agentpod-config', resolve(agentpodConfig)] : []),
|
|
1642
1802
|
...(a2aListenConfig ? ['--a2a-listen-config', resolve(a2aListenConfig)] : []),
|
|
1803
|
+
'--mcp-config',
|
|
1804
|
+
mcpConfig,
|
|
1805
|
+
...(toolsUser ? ['--tools-user', toolsUser] : []),
|
|
1806
|
+
...(localSandbox ? ['--local-sandbox', localSandbox] : []),
|
|
1807
|
+
...(unsandboxedCommands ? ['--unsandboxed-commands', 'allow'] : []),
|
|
1808
|
+
...(localSandboxRead.length ? ['--local-sandbox-read', localSandboxRead.join(',')] : []),
|
|
1809
|
+
...(webSearchConfig ? ['--web-search-config', resolve(webSearchConfig)] : []),
|
|
1810
|
+
...(dangerClassifierConfig
|
|
1811
|
+
? ['--danger-classifier-config', resolve(dangerClassifierConfig)]
|
|
1812
|
+
: []),
|
|
1643
1813
|
],
|
|
1644
1814
|
{ detached: true, stdio: ['ignore', fd, fd] },
|
|
1645
1815
|
);
|