feat: make nodes run exec-style

This commit is contained in:
Peter Steinberger
2026-01-21 20:24:12 +00:00
parent 6492e90c1b
commit 0d3b8f6ac3
5 changed files with 338 additions and 15 deletions

View File

@@ -27,6 +27,25 @@ const callGateway = vi.fn(async (opts: { method?: string }) => {
},
};
}
if (opts.method === "exec.approvals.get") {
return {
path: "/tmp/exec-approvals.json",
exists: true,
hash: "hash",
file: {
version: 1,
defaults: {
security: "allowlist",
ask: "on-miss",
askFallback: "deny",
},
agents: {},
},
};
}
if (opts.method === "exec.approval.request") {
return { decision: "allow-once" };
}
return { ok: true };
});
@@ -51,6 +70,10 @@ vi.mock("../runtime.js", () => ({
defaultRuntime,
}));
vi.mock("../config/config.js", () => ({
loadConfig: () => ({}),
}));
describe("nodes-cli coverage", () => {
it("lists nodes via node.list", async () => {
runtimeLogs.length = 0;
@@ -112,10 +135,43 @@ describe("nodes-cli coverage", () => {
env: { FOO: "bar" },
timeoutMs: 1200,
needsScreenRecording: true,
agentId: "main",
approved: true,
approvalDecision: "allow-once",
});
expect(invoke?.params?.timeoutMs).toBe(5000);
});
it("invokes system.run with raw command", async () => {
runtimeLogs.length = 0;
runtimeErrors.length = 0;
callGateway.mockClear();
randomIdempotencyKey.mockClear();
const { registerNodesCli } = await import("./nodes-cli.js");
const program = new Command();
program.exitOverride();
registerNodesCli(program);
await program.parseAsync(
["nodes", "run", "--agent", "main", "--node", "mac-1", "--raw", "echo hi"],
{ from: "user" },
);
const invoke = callGateway.mock.calls.find((call) => call[0]?.method === "node.invoke")?.[0];
expect(invoke).toBeTruthy();
expect(invoke?.params?.idempotencyKey).toBe("rk_test");
expect(invoke?.params?.command).toBe("system.run");
expect(invoke?.params?.params).toMatchObject({
command: ["/bin/sh", "-lc", "echo hi"],
rawCommand: "echo hi",
agentId: "main",
approved: true,
approvalDecision: "allow-once",
});
});
it("invokes system.notify with provided fields", async () => {
runtimeLogs.length = 0;
runtimeErrors.length = 0;