@ornncompute/cli 0.2.5 → 0.2.6

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/README.md CHANGED
@@ -77,7 +77,7 @@ ornn node reboot <node-id> [--json]
77
77
  ornn node hard-reset <node-id> [--json]
78
78
  ornn node off-grid <node-id> [--reason <text>] [--yes] [--json]
79
79
  ornn node on-grid <node-id> [--yes] [--json]
80
- ornn node exec <node-id> --command <shell> --timeout-seconds <n> [--yes] [--json]
80
+ ornn node exec <node-id> --command <shell> --timeout-seconds <n> [--json]
81
81
  ornn node terminate <node-id> [--reason <text>] [--force] [--yes] [--json]
82
82
  ornn node admin-key <node-id> [--generate] [--json]
83
83
  ornn reservations commerce list --tenant <email-or-id> [--listing <listing-id>] [--json]
@@ -248,9 +248,9 @@ path.
248
248
  (remove Ornn agent management, leave the host powered on). Asks y/N unless `--yes`.
249
249
  - `ornn node on-grid <node-id> [--yes]` re-enrolls an off-grid host: orchestrator
250
250
  SSHs with the stored admin key and re-runs the installer. Asks y/N unless `--yes`.
251
- - `ornn node exec <node-id> --command <shell> --timeout-seconds <n> [--yes]` runs
251
+ - `ornn node exec <node-id> --command <shell> --timeout-seconds <n>` runs
252
252
  one unrestricted command over orchestrator SSH with the stored admin key. Not
253
- an interactive shell (`ornn ssh`). Asks y/N unless `--yes`.
253
+ an interactive shell (`ornn ssh`). Runs immediately; no y/N.
254
254
  - `ornn node terminate <node-id> [--reason <text>] [--force] [--yes]` best-effort
255
255
  cleans the host, removes the Ornn agent, and hard-deletes the node record.
256
256
  It does not return the host to a tenant. Asks y/N unless `--yes`. There is no
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ornncompute/cli",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "description": "Command-line interface for Ornn compute access workflows.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -468,24 +468,26 @@ export async function nodeOnGridCommand(args, context) {
468
468
  export async function nodeExecCommand(args, context) {
469
469
  const [nodeId, ...rest] = args;
470
470
  if (!nodeId) {
471
- throw new Error("Usage: ornn node exec <node-id> --command <shell> --timeout-seconds <n> [--yes] [--json]");
471
+ throw new Error("Usage: ornn node exec <node-id> --command <shell> --timeout-seconds <n> [--json]");
472
472
  }
473
473
  const options = context.parseCommandOptions(
474
474
  rest,
475
475
  { boolean: ["json", "yes"], value: ["command", "timeout-seconds"] },
476
- "Usage: ornn node exec <node-id> --command <shell> --timeout-seconds <n> [--yes] [--json]",
476
+ "Usage: ornn node exec <node-id> --command <shell> --timeout-seconds <n> [--json]",
477
477
  );
478
478
  const command = String(options.command ?? "").trim();
479
479
  const timeoutSeconds = Number(options.timeoutSeconds);
480
480
  if (!command || !Number.isFinite(timeoutSeconds) || timeoutSeconds <= 0) {
481
- throw new Error("Usage: ornn node exec <node-id> --command <shell> --timeout-seconds <n> [--yes] [--json]");
481
+ throw new Error("Usage: ornn node exec <node-id> --command <shell> --timeout-seconds <n> [--json]");
482
482
  }
483
- return runNodeLifecycle(
484
- "nodeExecCapability",
485
- { node_id: nodeId, command, timeout_seconds: timeoutSeconds, yes: options.yes === true },
486
- context,
487
- `Run ${JSON.stringify(command)} on node ${nodeId} (${timeoutSeconds}s)?`,
483
+ const { nodeExecCapability } = await loadCapabilities();
484
+ const result = await runCatalogCapability(
485
+ nodeExecCapability,
486
+ { node_id: nodeId, command, timeout_seconds: timeoutSeconds },
487
+ { ...context, staff: true, role: "admin" },
488
488
  );
489
+ context.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
490
+ return 0;
489
491
  }
490
492
 
491
493
  export async function nodeTerminateCommand(args, context) {
package/src/cli.mjs CHANGED
@@ -159,7 +159,7 @@ Usage:
159
159
  ornn node hard-reset <node-id> [--json]
160
160
  ornn node off-grid <node-id> [--reason <text>] [--yes] [--json]
161
161
  ornn node on-grid <node-id> [--yes] [--json]
162
- ornn node exec <node-id> --command <shell> --timeout-seconds <n> [--yes] [--json]
162
+ ornn node exec <node-id> --command <shell> --timeout-seconds <n> [--json]
163
163
  ornn node terminate <node-id> [--reason <text>] [--force] [--yes] [--json]
164
164
  ornn node admin-key <node-id> [--generate] [--json]
165
165
  ornn operators list [--json]
@@ -2195,7 +2195,7 @@ function nodeOpUsage(subcommand) {
2195
2195
  return "Usage: ornn node on-grid <node-id> [--yes] [--json]";
2196
2196
  }
2197
2197
  if (subcommand === "exec") {
2198
- return "Usage: ornn node exec <node-id> --command <shell> --timeout-seconds <n> [--yes] [--json]";
2198
+ return "Usage: ornn node exec <node-id> --command <shell> --timeout-seconds <n> [--json]";
2199
2199
  }
2200
2200
  if (subcommand === "terminate") {
2201
2201
  return "Usage: ornn node terminate <node-id> [--reason <text>] [--force] [--yes] [--json]";
@@ -179,8 +179,8 @@ export const nodeExecCapability = defineCapability({
179
179
  id: "node.exec",
180
180
  domain: "fleet",
181
181
  roles: ["admin"],
182
- description: "Admin-only. Run one unrestricted command on an enrolled node over orchestrator SSH with the stored admin key. Always pass timeout_seconds. Not an interactive shell. On NVIDIA hosts use nvidia-smi; on AMD Instinct use amd-smi. CLI asks y/N. Slack waits for a human confirm. MCP requires confirm: true.",
183
- mutation: "preview-confirm",
182
+ description: "Admin-only. Run one unrestricted command on an enrolled node over orchestrator SSH with the stored admin key. Always pass timeout_seconds. Not an interactive shell. On NVIDIA hosts use nvidia-smi; on AMD Instinct use amd-smi. Runs on the tool call no confirm, no y/N.",
183
+ mutation: "read",
184
184
  http: { method: "POST", path: "/internal/remote" },
185
185
  slack: {
186
186
  parameters: {
@@ -201,11 +201,10 @@ export const nodeExecCapability = defineCapability({
201
201
  const parsed = nodeExecInput.parse(input);
202
202
  const id = nodeIdOf(parsed);
203
203
  const timeoutSeconds = parsed.timeout_seconds ?? parsed.timeoutSeconds;
204
- const payload = { node_id: id, command: parsed.command, timeout_seconds: timeoutSeconds };
205
- if (!ctx.confirmed) {
206
- return { ok: true, action: "node.exec", payload };
207
- }
208
- return ctx.fetch("/internal/remote", { method: "POST", body: payload });
204
+ return ctx.fetch("/internal/remote", {
205
+ method: "POST",
206
+ body: { node_id: id, command: parsed.command, timeout_seconds: timeoutSeconds },
207
+ });
209
208
  },
210
209
  });
211
210
  export const nodeTerminateCapability = defineCapability({