@koda-sl/baker-bridge 0.124.0 → 0.125.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +1 -1
  2. package/dist/broker/broker-process.d.ts +10 -0
  3. package/dist/broker/broker-process.d.ts.map +1 -0
  4. package/dist/broker/broker-process.js +20 -0
  5. package/dist/broker/broker-process.js.map +1 -0
  6. package/dist/broker/broker-process.test.d.ts +2 -0
  7. package/dist/broker/broker-process.test.d.ts.map +1 -0
  8. package/dist/broker/broker-process.test.js +13 -0
  9. package/dist/broker/broker-process.test.js.map +1 -0
  10. package/dist/broker/env.d.ts +2 -0
  11. package/dist/broker/env.d.ts.map +1 -1
  12. package/dist/broker/env.js +4 -0
  13. package/dist/broker/env.js.map +1 -1
  14. package/dist/broker/main.js +8 -2
  15. package/dist/broker/main.js.map +1 -1
  16. package/dist/broker/socket-service.d.ts.map +1 -1
  17. package/dist/broker/socket-service.js +12 -2
  18. package/dist/broker/socket-service.js.map +1 -1
  19. package/dist/broker/socket-service.test.js +7 -0
  20. package/dist/broker/socket-service.test.js.map +1 -1
  21. package/dist/broker/supervisor-main.d.ts +3 -0
  22. package/dist/broker/supervisor-main.d.ts.map +1 -0
  23. package/dist/broker/supervisor-main.js +70 -0
  24. package/dist/broker/supervisor-main.js.map +1 -0
  25. package/dist/broker/supervisor.d.ts +25 -0
  26. package/dist/broker/supervisor.d.ts.map +1 -0
  27. package/dist/broker/supervisor.js +88 -0
  28. package/dist/broker/supervisor.js.map +1 -0
  29. package/dist/broker/supervisor.test.d.ts +2 -0
  30. package/dist/broker/supervisor.test.d.ts.map +1 -0
  31. package/dist/broker/supervisor.test.js +161 -0
  32. package/dist/broker/supervisor.test.js.map +1 -0
  33. package/dist/cli.d.ts.map +1 -1
  34. package/dist/cli.js +2 -0
  35. package/dist/cli.js.map +1 -1
  36. package/dist/hono/bridge-job.d.ts.map +1 -1
  37. package/dist/hono/bridge-job.js +4 -0
  38. package/dist/hono/bridge-job.js.map +1 -1
  39. package/dist/hono/bridge-job.test.js +13 -0
  40. package/dist/hono/bridge-job.test.js.map +1 -1
  41. package/dist/hono/oom-priority.agent.test.d.ts +2 -0
  42. package/dist/hono/oom-priority.agent.test.d.ts.map +1 -0
  43. package/dist/hono/oom-priority.agent.test.js +138 -0
  44. package/dist/hono/oom-priority.agent.test.js.map +1 -0
  45. package/dist/hono/oom-priority.d.ts +39 -0
  46. package/dist/hono/oom-priority.d.ts.map +1 -0
  47. package/dist/hono/oom-priority.js +138 -0
  48. package/dist/hono/oom-priority.js.map +1 -0
  49. package/dist/hono/oom-priority.test.d.ts +2 -0
  50. package/dist/hono/oom-priority.test.d.ts.map +1 -0
  51. package/dist/hono/oom-priority.test.js +52 -0
  52. package/dist/hono/oom-priority.test.js.map +1 -0
  53. package/package.json +3 -2
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=oom-priority.agent.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oom-priority.agent.test.d.ts","sourceRoot":"","sources":["../../src/hono/oom-priority.agent.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,138 @@
1
+ import { chmodSync, existsSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { createServer } from "node:http";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { query } from "@anthropic-ai/claude-agent-sdk";
6
+ import { afterEach, describe, expect, it } from "vitest";
7
+ import { AGENT_COMM, agentShellPrefixEnv, KILL_FIRST_ADJ, killFirstWrapper } from "./oom-priority.js";
8
+ function stream(res, content, stopReason) {
9
+ res.writeHead(200, { "content-type": "text/event-stream" });
10
+ const events = [
11
+ [
12
+ "message_start",
13
+ {
14
+ type: "message_start",
15
+ message: {
16
+ id: "msg_test",
17
+ type: "message",
18
+ role: "assistant",
19
+ model: "claude-sonnet-4-5",
20
+ content: [],
21
+ stop_reason: null,
22
+ usage: { input_tokens: 1, output_tokens: 1 },
23
+ },
24
+ },
25
+ ],
26
+ ...content,
27
+ ["message_delta", { type: "message_delta", delta: { stop_reason: stopReason }, usage: { output_tokens: 1 } }],
28
+ ["message_stop", { type: "message_stop" }],
29
+ ];
30
+ for (const [event, data] of events)
31
+ res.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`);
32
+ res.end();
33
+ }
34
+ function text(value) {
35
+ return [
36
+ ["content_block_start", { type: "content_block_start", index: 0, content_block: { type: "text", text: "" } }],
37
+ ["content_block_delta", { type: "content_block_delta", index: 0, delta: { type: "text_delta", text: value } }],
38
+ ["content_block_stop", { type: "content_block_stop", index: 0 }],
39
+ ];
40
+ }
41
+ function bash(command) {
42
+ return [
43
+ [
44
+ "content_block_start",
45
+ {
46
+ type: "content_block_start",
47
+ index: 0,
48
+ content_block: { type: "tool_use", id: "toolu_probe", name: "Bash", input: {} },
49
+ },
50
+ ],
51
+ [
52
+ "content_block_delta",
53
+ {
54
+ type: "content_block_delta",
55
+ index: 0,
56
+ delta: { type: "input_json_delta", partial_json: JSON.stringify({ command, description: "probe" }) },
57
+ },
58
+ ],
59
+ ["content_block_stop", { type: "content_block_stop", index: 0 }],
60
+ ];
61
+ }
62
+ /** A model that asks for one Bash command, then records what the command printed. */
63
+ function scriptedModel(command) {
64
+ const toolResults = [];
65
+ const server = createServer((req, res) => {
66
+ let body = "";
67
+ req.on("data", (chunk) => {
68
+ body += chunk;
69
+ });
70
+ req.on("end", () => {
71
+ if (!req.url?.includes("/v1/messages") || req.url.includes("count_tokens")) {
72
+ res.writeHead(200, { "content-type": "application/json" });
73
+ res.end(JSON.stringify({ input_tokens: 1 }));
74
+ return;
75
+ }
76
+ const request = JSON.parse(body || "{}");
77
+ const messages = JSON.stringify(request.messages ?? []);
78
+ if (!request.tools?.length)
79
+ return stream(res, text("ok"), "end_turn");
80
+ if (!messages.includes("tool_result"))
81
+ return stream(res, bash(command), "tool_use");
82
+ toolResults.push(messages);
83
+ return stream(res, text("done"), "end_turn");
84
+ });
85
+ });
86
+ return { server, toolResults };
87
+ }
88
+ const servers = [];
89
+ afterEach(() => {
90
+ for (const server of servers.splice(0))
91
+ server.close();
92
+ });
93
+ /** Our wrapper behind one that logs how many arguments the agent handed it. */
94
+ function recordingPrefix(wrapper) {
95
+ const dir = mkdtempSync(join(tmpdir(), "kill-first-recorder-"));
96
+ const log = join(dir, "calls.log");
97
+ const prefix = join(dir, "record.sh");
98
+ writeFileSync(prefix, `#!/bin/sh\necho "argc=$#" >> ${log}\nexec ${wrapper} "$@"\n`);
99
+ chmodSync(prefix, 0o755);
100
+ return { prefix, calls: () => (existsSync(log) ? readFileSync(log, "utf8") : "") };
101
+ }
102
+ describe("the agent's Bash commands", () => {
103
+ it("run through the kill-first wrapper, as the script the agent would have run", async () => {
104
+ const model = scriptedModel('echo "probe-adj=$(cat /proc/self/oom_score_adj 2>/dev/null || echo none) probe-agent=$(cat /proc/$PPID/comm 2>/dev/null || echo none)"; [[ 1 == 1 ]]');
105
+ servers.push(model.server);
106
+ await new Promise((resolve) => model.server.listen(0, "127.0.0.1", resolve));
107
+ const { port } = model.server.address();
108
+ const recorder = recordingPrefix(agentShellPrefixEnv(killFirstWrapper(), {}).CLAUDE_CODE_SHELL_PREFIX ?? "");
109
+ const run = query({
110
+ prompt: "probe",
111
+ options: {
112
+ model: "claude-sonnet-4-5",
113
+ cwd: mkdtempSync(join(tmpdir(), "kill-first-agent-")),
114
+ settingSources: [],
115
+ allowedTools: ["Bash"],
116
+ permissionMode: "bypassPermissions",
117
+ allowDangerouslySkipPermissions: true,
118
+ env: {
119
+ PATH: process.env.PATH,
120
+ HOME: mkdtempSync(join(tmpdir(), "kill-first-home-")),
121
+ ANTHROPIC_BASE_URL: `http://127.0.0.1:${port}`,
122
+ ANTHROPIC_API_KEY: "sk-ant-test",
123
+ CLAUDE_CODE_SHELL_PREFIX: recorder.prefix,
124
+ },
125
+ },
126
+ });
127
+ for await (const _message of run) {
128
+ // Drain the turn.
129
+ }
130
+ expect(recorder.calls()).toBe("argc=1\n");
131
+ // Off Linux there is no score to read; the command must still run intact.
132
+ const expected = process.platform === "linux" ? String(KILL_FIRST_ADJ) : "none";
133
+ expect(model.toolResults.join("")).toContain(`probe-adj=${expected}`);
134
+ // The scan behind the wrapper finds the agent by its process name.
135
+ expect(model.toolResults.join("")).toContain(`probe-agent=${process.platform === "linux" ? AGENT_COMM : "none"}`);
136
+ });
137
+ });
138
+ //# sourceMappingURL=oom-priority.agent.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oom-priority.agent.test.js","sourceRoot":"","sources":["../../src/hono/oom-priority.agent.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ export type ProcessEntry = {
2
+ pid: number;
3
+ ppid: number;
4
+ comm: string;
5
+ oomScoreAdj: number;
6
+ };
7
+ /** The kernel's maximum: a command of any size is killed before any process left alone, whatever score it started with. */
8
+ export declare const KILL_FIRST_ADJ = 1000;
9
+ /** The agent binary's process name, which the scan finds it by. */
10
+ export declare const AGENT_COMM = "claude";
11
+ /** Pids of the agent's commands — every descendant of an agent process that is not one itself. */
12
+ export declare function killFirst(processes: readonly ProcessEntry[]): number[];
13
+ /** `pid (comm) state ppid …` — the name can hold spaces and parentheses, so it ends at the last `)`. */
14
+ export declare function parseStat(stat: string): {
15
+ pid: number;
16
+ ppid: number;
17
+ comm: string;
18
+ } | null;
19
+ /**
20
+ * Marks the agent's commands every 2 s: the backstop for what the wrapper never
21
+ * sees (an MCP server, a hook not run by bash). Raising a score needs no
22
+ * privilege, so the bridge does it for the processes its agent started; a
23
+ * command dead between the scan and the write is skipped. Off where there is no
24
+ * /proc.
25
+ */
26
+ export declare function startOomPriority(log?: (message: string) => void): void;
27
+ /** Writes the wrapper into `dir` and returns its path. */
28
+ export declare function installKillFirstWrapper(dir: string): string;
29
+ /** The agent's env addition: the wrapper, unless the Runtime already wraps commands its own way. */
30
+ export declare function agentShellPrefixEnv(wrapper: string | null, env: Record<string, string | undefined>): {
31
+ CLAUDE_CODE_SHELL_PREFIX?: string;
32
+ };
33
+ /**
34
+ * The wrapper, written on first use so no agent starts without it whatever
35
+ * started the bridge. Null only where the temp dir is not writable. Off Linux
36
+ * the score write fails quietly and the command runs as is.
37
+ */
38
+ export declare function killFirstWrapper(log?: (message: string) => void): string | null;
39
+ //# sourceMappingURL=oom-priority.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oom-priority.d.ts","sourceRoot":"","sources":["../../src/hono/oom-priority.ts"],"names":[],"mappings":"AAaA,MAAM,MAAM,YAAY,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5F,2HAA2H;AAC3H,eAAO,MAAM,cAAc,OAAO,CAAC;AAEnC,mEAAmE;AACnE,eAAO,MAAM,UAAU,WAAW,CAAC;AAEnC,kGAAkG;AAClG,wBAAgB,SAAS,CAAC,SAAS,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,EAAE,CAetE;AAED,wGAAwG;AACxG,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAQ1F;AAkBD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAmB,GAAG,IAAI,CAmBpF;AAgBD,0DAA0D;AAC1D,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK3D;AAED,oGAAoG;AACpG,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GACtC;IAAE,wBAAwB,CAAC,EAAE,MAAM,CAAA;CAAE,CAGvC;AAID;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAmB,GAAG,MAAM,GAAG,IAAI,CAW7F"}
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Which processes the kernel's OOM killer takes first in a Runtime.
3
+ *
4
+ * Every process starts at the same score, so the kernel kills the biggest. When
5
+ * parallel agents fill the sandbox's memory with their commands (a 20-agent run
6
+ * held 60 `baker` processes of ~126 MB each), the biggest is the agent itself
7
+ * or the credential broker, and either ends the turn. A command the agent ran is
8
+ * the one to lose: it fails as `Killed` and the agent can run it again.
9
+ */
10
+ import { chmodSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
11
+ import { tmpdir } from "node:os";
12
+ import { join } from "node:path";
13
+ /** The kernel's maximum: a command of any size is killed before any process left alone, whatever score it started with. */
14
+ export const KILL_FIRST_ADJ = 1000;
15
+ /** The agent binary's process name, which the scan finds it by. */
16
+ export const AGENT_COMM = "claude";
17
+ /** Pids of the agent's commands — every descendant of an agent process that is not one itself. */
18
+ export function killFirst(processes) {
19
+ const byPid = new Map(processes.map((entry) => [entry.pid, entry]));
20
+ function underAgent(entry) {
21
+ const seen = new Set();
22
+ let parent = byPid.get(entry.ppid);
23
+ while (parent && !seen.has(parent.pid)) {
24
+ if (parent.comm === AGENT_COMM)
25
+ return true;
26
+ seen.add(parent.pid);
27
+ parent = byPid.get(parent.ppid);
28
+ }
29
+ return false;
30
+ }
31
+ return processes
32
+ .filter((entry) => entry.comm !== AGENT_COMM && entry.oomScoreAdj < KILL_FIRST_ADJ && underAgent(entry))
33
+ .map((entry) => entry.pid);
34
+ }
35
+ /** `pid (comm) state ppid …` — the name can hold spaces and parentheses, so it ends at the last `)`. */
36
+ export function parseStat(stat) {
37
+ const open = stat.indexOf("(");
38
+ const close = stat.lastIndexOf(")");
39
+ if (open < 0 || close < open)
40
+ return null;
41
+ const pid = Number(stat.slice(0, open).trim());
42
+ const ppid = Number(stat.slice(close + 2).split(" ")[1]);
43
+ if (!Number.isInteger(pid) || !Number.isInteger(ppid))
44
+ return null;
45
+ return { pid, ppid, comm: stat.slice(open + 1, close) };
46
+ }
47
+ function readProcesses() {
48
+ const entries = [];
49
+ for (const name of readdirSync("/proc")) {
50
+ if (!/^\d+$/.test(name))
51
+ continue;
52
+ try {
53
+ const stat = parseStat(readFileSync(`/proc/${name}/stat`, "utf8"));
54
+ if (stat)
55
+ entries.push({ ...stat, oomScoreAdj: Number(readFileSync(`/proc/${name}/oom_score_adj`, "utf8")) });
56
+ }
57
+ catch {
58
+ // Gone between the listing and the read.
59
+ }
60
+ }
61
+ return entries;
62
+ }
63
+ const SCAN_INTERVAL_MS = 2_000;
64
+ /**
65
+ * Marks the agent's commands every 2 s: the backstop for what the wrapper never
66
+ * sees (an MCP server, a hook not run by bash). Raising a score needs no
67
+ * privilege, so the bridge does it for the processes its agent started; a
68
+ * command dead between the scan and the write is skipped. Off where there is no
69
+ * /proc.
70
+ */
71
+ export function startOomPriority(log = console.warn) {
72
+ try {
73
+ readdirSync("/proc/self");
74
+ }
75
+ catch {
76
+ return;
77
+ }
78
+ let warned = false;
79
+ const timer = setInterval(() => {
80
+ for (const pid of killFirst(readProcesses())) {
81
+ try {
82
+ writeFileSync(`/proc/${pid}/oom_score_adj`, String(KILL_FIRST_ADJ));
83
+ }
84
+ catch (error) {
85
+ if (warned)
86
+ continue;
87
+ warned = true;
88
+ log(`[oom-priority] could not mark command ${pid}: ${error instanceof Error ? error.message : String(error)}`);
89
+ }
90
+ }
91
+ }, SCAN_INTERVAL_MS);
92
+ timer.unref();
93
+ }
94
+ /**
95
+ * The agent's command wrapper (`CLAUDE_CODE_SHELL_PREFIX`). Claude Code hands
96
+ * it one argument, the script it would otherwise run with `bash -c`, so every
97
+ * command — and all it starts — is the OOM killer's first choice from its first
98
+ * instruction, before the scan below could reach it. A burst of parallel
99
+ * commands can fill memory inside one scan interval.
100
+ */
101
+ const KILL_FIRST_WRAPPER = `#!/bin/sh
102
+ # Written by the Baker bridge (oom-priority.ts): mark this command the OOM killer's first choice, then run it.
103
+ echo ${KILL_FIRST_ADJ} > /proc/self/oom_score_adj 2>/dev/null
104
+ if [ "$#" -eq 1 ]; then exec /bin/bash -c "$1"; fi
105
+ exec "$@"
106
+ `;
107
+ /** Writes the wrapper into `dir` and returns its path. */
108
+ export function installKillFirstWrapper(dir) {
109
+ const path = join(dir, "baker-kill-first.sh");
110
+ writeFileSync(path, KILL_FIRST_WRAPPER);
111
+ chmodSync(path, 0o755);
112
+ return path;
113
+ }
114
+ /** The agent's env addition: the wrapper, unless the Runtime already wraps commands its own way. */
115
+ export function agentShellPrefixEnv(wrapper, env) {
116
+ if (wrapper === null || env.CLAUDE_CODE_SHELL_PREFIX)
117
+ return {};
118
+ return { CLAUDE_CODE_SHELL_PREFIX: wrapper };
119
+ }
120
+ let installedWrapper;
121
+ /**
122
+ * The wrapper, written on first use so no agent starts without it whatever
123
+ * started the bridge. Null only where the temp dir is not writable. Off Linux
124
+ * the score write fails quietly and the command runs as is.
125
+ */
126
+ export function killFirstWrapper(log = console.warn) {
127
+ if (installedWrapper)
128
+ return installedWrapper;
129
+ try {
130
+ installedWrapper = installKillFirstWrapper(tmpdir());
131
+ return installedWrapper;
132
+ }
133
+ catch (error) {
134
+ log(`[oom-priority] could not write the command wrapper: ${error instanceof Error ? error.message : String(error)}`);
135
+ return null;
136
+ }
137
+ }
138
+ //# sourceMappingURL=oom-priority.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oom-priority.js","sourceRoot":"","sources":["../../src/hono/oom-priority.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=oom-priority.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oom-priority.test.d.ts","sourceRoot":"","sources":["../../src/hono/oom-priority.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,52 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { mkdtempSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { describe, expect, it } from "vitest";
6
+ import { agentShellPrefixEnv, installKillFirstWrapper, KILL_FIRST_ADJ, killFirst, parseStat } from "./oom-priority.js";
7
+ const bridge = { pid: 100, ppid: 1, comm: "MainThread", oomScoreAdj: 100 };
8
+ const agent = { pid: 200, ppid: 100, comm: "claude", oomScoreAdj: 100 };
9
+ const shell = { pid: 300, ppid: 200, comm: "bash", oomScoreAdj: 100 };
10
+ const bakerCommand = { pid: 301, ppid: 300, comm: "MainThread", oomScoreAdj: 100 };
11
+ describe("killFirst", () => {
12
+ it("marks every command the agent runs, and what they start, to be killed before the agent", () => {
13
+ expect(killFirst([bridge, agent, shell, bakerCommand]).sort()).toEqual([300, 301]);
14
+ });
15
+ it("marks commands even in a sandbox whose processes all start with a high score", () => {
16
+ const high = (entry) => ({ ...entry, oomScoreAdj: 900 });
17
+ expect(killFirst([high(bridge), high(agent), high(shell)])).toEqual([300]);
18
+ });
19
+ it("skips a command already marked, so a scan rewrites only what is new", () => {
20
+ const marked = { ...shell, oomScoreAdj: KILL_FIRST_ADJ };
21
+ expect(killFirst([bridge, agent, marked, bakerCommand])).toEqual([301]);
22
+ });
23
+ });
24
+ describe("parseStat", () => {
25
+ it("reads the parent and the name from /proc/<pid>/stat, even a name holding spaces and parentheses", () => {
26
+ expect(parseStat("4847 (claude) S 2933 4847 2920 0 -1 4194560 2 0")).toEqual({
27
+ pid: 4847,
28
+ ppid: 2933,
29
+ comm: "claude",
30
+ });
31
+ expect(parseStat("77 (a) b (c) R 12 77 1 0")).toEqual({ pid: 77, ppid: 12, comm: "a) b (c" });
32
+ });
33
+ });
34
+ describe("the kill-first wrapper", () => {
35
+ // Claude Code hands CLAUDE_CODE_SHELL_PREFIX one argument: the whole script it would run with `bash -c`.
36
+ it("runs the one script it is handed as the agent's bash would, output and exit code intact", () => {
37
+ const wrapper = installKillFirstWrapper(mkdtempSync(join(tmpdir(), "kill-first-")));
38
+ const run = spawnSync(wrapper, ["source /dev/null && eval 'echo from-bash; [[ 1 == 1 ]] && exit 3'"], {
39
+ encoding: "utf8",
40
+ });
41
+ expect(run.stdout).toBe("from-bash\n");
42
+ expect(run.status).toBe(3);
43
+ });
44
+ });
45
+ describe("agentShellPrefixEnv", () => {
46
+ it("hands the agent the wrapper, unless the Runtime already wraps its commands", () => {
47
+ expect(agentShellPrefixEnv("/tmp/w.sh", {})).toEqual({ CLAUDE_CODE_SHELL_PREFIX: "/tmp/w.sh" });
48
+ expect(agentShellPrefixEnv("/tmp/w.sh", { CLAUDE_CODE_SHELL_PREFIX: "/opt/audit.sh" })).toEqual({});
49
+ expect(agentShellPrefixEnv(null, {})).toEqual({});
50
+ });
51
+ });
52
+ //# sourceMappingURL=oom-priority.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oom-priority.test.js","sourceRoot":"","sources":["../../src/hono/oom-priority.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@koda-sl/baker-bridge",
3
- "version": "0.124.0",
3
+ "version": "0.125.0",
4
4
  "description": "HTTP server wrapping the Claude Agent SDK. Persists chat events to Convex; the dashboard subscribes via Convex realtime",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "bin": {
8
8
  "baker-bridge": "dist/cli.js",
9
- "baker-credential-broker": "dist/broker/main.js"
9
+ "baker-credential-broker": "dist/broker/main.js",
10
+ "baker-credential-broker-supervisor": "dist/broker/supervisor-main.js"
10
11
  },
11
12
  "exports": {
12
13
  "./hono": {