diff --git a/bin/nemoclaw.js b/bin/nemoclaw.js index 76e9512f5..9cc8bda65 100755 --- a/bin/nemoclaw.js +++ b/bin/nemoclaw.js @@ -570,6 +570,15 @@ async function sandboxConnect(sandboxName) { exitWithSpawnResult(result); } +function buildSandboxLogsArgs(sandboxName, follow) { + const args = ["sandbox", "connect", sandboxName, "--", "tail", "-n", "200"]; + if (follow) { + args.push("-f"); + } + args.push("/tmp/gateway.log"); + return args; +} + // eslint-disable-next-line complexity async function sandboxStatus(sandboxName) { const sb = registry.getSandbox(sandboxName); @@ -641,9 +650,7 @@ async function sandboxStatus(sandboxName) { } function sandboxLogs(sandboxName, follow) { - const args = ["logs", sandboxName]; - if (follow) args.push("--follow"); - runOpenshell(args); + runOpenshell(buildSandboxLogsArgs(sandboxName, follow)); } async function sandboxPolicyAdd(sandboxName) { diff --git a/test/cli.test.js b/test/cli.test.js index f255c6781..0912ee1f1 100644 --- a/test/cli.test.js +++ b/test/cli.test.js @@ -104,7 +104,7 @@ describe("CLI dispatch", () => { expect(r.out.includes("nemoclaw debug")).toBeTruthy(); }); - it("passes --follow through to openshell logs", () => { + it("routes logs to sandbox connect tailing the gateway log", () => { const home = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-cli-logs-follow-")); const localBin = path.join(home, "bin"); const registryDir = path.join(home, ".nemoclaw"); @@ -138,13 +138,56 @@ describe("CLI dispatch", () => { { mode: 0o755 } ); + const r = runWithEnv("alpha logs", { + HOME: home, + PATH: `${localBin}:${process.env.PATH || ""}`, + }); + + expect(r.code).toBe(0); + expect(fs.readFileSync(markerFile, "utf8")).toContain("sandbox connect alpha -- tail -n 200 /tmp/gateway.log"); + }); + + it("passes --follow through to tail inside sandbox connect", () => { + const home = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-cli-logs-follow-")); + const localBin = path.join(home, "bin"); + const registryDir = path.join(home, ".nemoclaw"); + const markerFile = path.join(home, "logs-follow-args"); + fs.mkdirSync(localBin, { recursive: true }); + fs.mkdirSync(registryDir, { recursive: true }); + fs.writeFileSync( + path.join(registryDir, "sandboxes.json"), + JSON.stringify({ + sandboxes: { + alpha: { + name: "alpha", + model: "test-model", + provider: "nvidia-prod", + gpuEnabled: false, + policies: [], + }, + }, + defaultSandbox: "alpha", + }), + { mode: 0o600 } + ); + fs.writeFileSync( + path.join(localBin, "openshell"), + [ + "#!/usr/bin/env bash", + `marker_file=${JSON.stringify(markerFile)}`, + "printf '%s ' \"$@\" > \"$marker_file\"", + "exit 0", + ].join("\n"), + { mode: 0o755 } + ); + const r = runWithEnv("alpha logs --follow", { HOME: home, PATH: `${localBin}:${process.env.PATH || ""}`, }); expect(r.code).toBe(0); - expect(fs.readFileSync(markerFile, "utf8")).toContain("logs alpha --follow"); + expect(fs.readFileSync(markerFile, "utf8")).toContain("sandbox connect alpha -- tail -n 200 -f /tmp/gateway.log"); }); it("connect does not pre-start a duplicate port forward", () => {