@computesdk/cli 2.1.0 → 2.1.1

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
@@ -44,6 +44,17 @@ override, pass `--org <slug>` (on the root command or any `sandboxes` /
44
44
  on the request. Precedence: `--org` > `COMPUTE_ORG` > the stored login's org.
45
45
  The platform ignores the header for org API keys.
46
46
 
47
+ For `compute sandboxes exec` and `compute sandboxes spawn`, everything after
48
+ the command's first word goes to the sandbox untouched — flags like `uname
49
+ -a` or `node -e` are not CLI options. Pass CLI options (`--json`,
50
+ `--timeout-ms`, `--cwd`, `-e/--env`, `--stdin`, `--org`) before the command;
51
+ a bare `--` before the command is optional but supported.
52
+
53
+ ```bash
54
+ compute sandboxes exec sb1 uname -a
55
+ compute sandboxes spawn sb1 --cwd /app -e NODE_ENV=production -- npm run dev
56
+ ```
57
+
47
58
  ## Migrating from @computesdk/cli 1.x
48
59
 
49
60
  v2 removes the legacy console authentication and its commands:
package/dist/index.js CHANGED
@@ -1872,8 +1872,82 @@ function printSnapshot(s) {
1872
1872
  ` provider: ${s.provider}${s.region ? ` (${s.region})` : ""} label: ${s.label ?? "\u2014"} created: ${s.createdAt}${s.expiresAt ? ` expires: ${s.expiresAt}` : ""}`
1873
1873
  );
1874
1874
  }
1875
+ var AUTH_LEAD_OPTS = [
1876
+ { aliases: ["--api-key"], key: "apiKey", flag: "value" },
1877
+ { aliases: ["--base-url"], key: "baseUrl", flag: "value" },
1878
+ { aliases: ["--allow-untrusted-host"], key: "allowUntrustedHost", flag: "bool" },
1879
+ { aliases: ["--org"], key: "org", flag: "value" },
1880
+ { aliases: ["--json"], key: "json", flag: "bool" }
1881
+ ];
1882
+ var EXEC_LEAD_OPTS = [
1883
+ ...AUTH_LEAD_OPTS,
1884
+ { aliases: ["--timeout-ms"], key: "timeoutMs", flag: "value" }
1885
+ ];
1886
+ var SPAWN_LEAD_OPTS = [
1887
+ ...AUTH_LEAD_OPTS,
1888
+ { aliases: ["--cwd"], key: "cwd", flag: "value" },
1889
+ { aliases: ["-e", "--env"], key: "env", flag: "repeat" },
1890
+ { aliases: ["--stdin"], key: "stdin", flag: "bool" }
1891
+ ];
1892
+ function takeLeadingOptions(argv, specs) {
1893
+ var _a;
1894
+ const byAlias = /* @__PURE__ */ new Map();
1895
+ for (const spec of specs) for (const alias of spec.aliases) byAlias.set(alias, spec);
1896
+ const inline = {};
1897
+ let i = 0;
1898
+ for (; i < argv.length; i++) {
1899
+ const token = argv[i];
1900
+ if (token === "--") {
1901
+ i++;
1902
+ break;
1903
+ }
1904
+ if (!token.startsWith("-") || token === "-") break;
1905
+ const eq = token.indexOf("=");
1906
+ const flag = eq === -1 ? token : token.slice(0, eq);
1907
+ let spec = byAlias.get(flag);
1908
+ let attached;
1909
+ if (!spec && !flag.startsWith("--") && flag.length > 2) {
1910
+ const shortSpec = byAlias.get(flag.slice(0, 2));
1911
+ if (shortSpec && shortSpec.flag !== "bool") {
1912
+ spec = shortSpec;
1913
+ attached = flag.slice(2);
1914
+ if (attached.startsWith("=")) attached = attached.slice(1);
1915
+ if (eq !== -1) attached += token.slice(eq);
1916
+ }
1917
+ }
1918
+ if (!spec) {
1919
+ throw new Error(
1920
+ `unknown option '${flag}' \u2014 pass CLI options before the command, or use -- to separate them`
1921
+ );
1922
+ }
1923
+ if (spec.flag === "bool") {
1924
+ if (eq !== -1) throw new Error(`option '${flag}' takes no value`);
1925
+ inline[spec.key] = true;
1926
+ } else {
1927
+ const value = attached ?? (eq !== -1 ? token.slice(eq + 1) : argv[++i]);
1928
+ if (value === void 0) throw new Error(`option '${flag}' requires a value`);
1929
+ if (spec.flag === "repeat") {
1930
+ (inline[_a = spec.key] ?? (inline[_a] = [])).push(value);
1931
+ } else {
1932
+ inline[spec.key] = value;
1933
+ }
1934
+ }
1935
+ }
1936
+ return { command: argv.slice(i), inline };
1937
+ }
1938
+ function mergeLeadOpts(opts, inline) {
1939
+ const merged = { ...opts };
1940
+ for (const [key, value] of Object.entries(inline)) {
1941
+ if (Array.isArray(value)) {
1942
+ merged[key] = [...merged[key] ?? [], ...value];
1943
+ } else {
1944
+ merged[key] = value;
1945
+ }
1946
+ }
1947
+ return merged;
1948
+ }
1875
1949
  function registerSandboxesCommands(program2) {
1876
- const cmd = program2.command("sandboxes").alias("sbx").description("Create and drive sandboxes through the platform").configureOutput({ outputError: usageErrorOutput });
1950
+ const cmd = program2.command("sandboxes").alias("sbx").description("Create and drive sandboxes through the platform").enablePositionalOptions().configureOutput({ outputError: usageErrorOutput });
1877
1951
  cmd.command("create").description('Place a sandbox (provider order walks 1,2,3; "market" bids first)').option("--order <providers>", 'provider order, comma-separated (e.g. "market,blaxel,vercel")').option("--label <label>", "label for the sandbox").option("--image <image>", "container image to boot").option("--snapshot-id <id>", "provider snapshot to resume").option("--cpus <n>", "CPU cores").option("--memory-mb <n>", "memory in MB").option("--disk-mb <n>", "ephemeral disk in MB").option("--timeout-ms <ms>", "sandbox timeout in ms").option("--secret <name>", "vault secret name to inject (repeatable)", (v, a) => a.concat(v), []).option("--api-key <key>", "platform API key (or COMPUTE_API_KEY)").option("--base-url <url>", "platform base URL").option("--allow-untrusted-host", "allow non-computesdk.com base URLs").option("--json", "print the raw response").action(async (opts) => {
1878
1952
  try {
1879
1953
  const c = await client(opts);
@@ -1928,8 +2002,13 @@ function registerSandboxesCommands(program2) {
1928
2002
  fail(e, opts);
1929
2003
  }
1930
2004
  });
1931
- cmd.command("exec <sandboxId> <command...>").description("Run a one-shot command and print its result").option("--timeout-ms <ms>", "command timeout in ms").option("--api-key <key>").option("--base-url <url>").option("--allow-untrusted-host").option("--json", "print the raw response").action(async (sandboxId, command, opts) => {
2005
+ cmd.command("exec <sandboxId> <command...>").description("Run a one-shot command and print its result (options before the command; -- also works)").option("--timeout-ms <ms>", "command timeout in ms").option("--api-key <key>").option("--base-url <url>").option("--allow-untrusted-host").option("--json", "print the raw response").passThroughOptions().action(async (sandboxId, rawCommand, rawOpts) => {
2006
+ let opts = rawOpts;
1932
2007
  try {
2008
+ const lead = takeLeadingOptions(rawCommand, EXEC_LEAD_OPTS);
2009
+ opts = mergeLeadOpts(rawOpts, lead.inline);
2010
+ const command = lead.command;
2011
+ if (command.length === 0) throw new Error("missing command to run");
1933
2012
  const c = await client(opts);
1934
2013
  const res = await c.post(
1935
2014
  `/api/v1/sandboxes/${sandboxId}/commands`,
@@ -1948,8 +2027,13 @@ function registerSandboxesCommands(program2) {
1948
2027
  fail(e, opts);
1949
2028
  }
1950
2029
  });
1951
- cmd.command("spawn <sandboxId> <command...>").description("Start a detached process that outlives this request").option("--cwd <dir>", "working directory").option("-e, --env <key=value>", "environment variable (repeatable)", (v, a) => a.concat(v), []).option("--stdin", "keep the process's stdin pipe open for `stdin`/`close-stdin`").option("--api-key <key>").option("--base-url <url>").option("--allow-untrusted-host").option("--json", "print the raw response").action(async (sandboxId, command, opts) => {
2030
+ cmd.command("spawn <sandboxId> <command...>").description("Start a detached process that outlives this request (options before the command; -- also works)").option("--cwd <dir>", "working directory").option("-e, --env <key=value>", "environment variable (repeatable)", (v, a) => a.concat(v), []).option("--stdin", "keep the process's stdin pipe open for `stdin`/`close-stdin`").option("--api-key <key>").option("--base-url <url>").option("--allow-untrusted-host").option("--json", "print the raw response").passThroughOptions().action(async (sandboxId, rawCommand, rawOpts) => {
2031
+ let opts = rawOpts;
1952
2032
  try {
2033
+ const lead = takeLeadingOptions(rawCommand, SPAWN_LEAD_OPTS);
2034
+ opts = mergeLeadOpts(rawOpts, lead.inline);
2035
+ const command = lead.command;
2036
+ if (command.length === 0) throw new Error("missing command to spawn");
1953
2037
  const c = await client(opts);
1954
2038
  const res = await c.post(
1955
2039
  `/api/v1/sandboxes/${sandboxId}/processes`,