Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions bin/nemoclaw.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down
47 changes: 45 additions & 2 deletions test/cli.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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", () => {
Expand Down