@calo-design/cli 0.4.7 → 0.4.8

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/bin/cli.js CHANGED
@@ -55,8 +55,17 @@ const ok = (s) => log(`${c.g("✓")} ${s}`);
55
55
  const warn = (s) => log(`${c.y("!")} ${s}`);
56
56
  const tilde = (p) => p.replace(os.homedir(), "~");
57
57
 
58
+ // npm/npx are .cmd shims on Windows, and Node >= 18.20.2 (CVE-2024-27980)
59
+ // refuses to spawn .cmd files without shell:true. With shell:true cmd.exe
60
+ // gets the args space-joined and unescaped, so quote anything with whitespace.
61
+ function winShell(bin, argv) {
62
+ if (process.platform !== "win32") return [bin, argv, false];
63
+ const q = (s) => (/[ \t]/.test(s) ? `"${s}"` : s);
64
+ return [q(bin), argv.map(q), true];
65
+ }
58
66
  function run(bin, argv, opts = {}) {
59
- const r = spawnSync(bin, argv, { stdio: "inherit", ...opts });
67
+ const [b, a, shell] = winShell(bin, argv);
68
+ const r = spawnSync(b, a, { stdio: "inherit", shell, ...opts });
60
69
  if (r.error) throw r.error;
61
70
  if (typeof r.status === "number" && r.status !== 0) throw new Error(`${bin} ${argv.join(" ")} exited ${r.status}`);
62
71
  return r;
@@ -68,7 +77,8 @@ function sleep(sec) {
68
77
  // races / rate limits) and recover on retry. Retry before giving up.
69
78
  function runWithRetry(bin, argv, tries = 3, opts = {}) {
70
79
  for (let i = 1; i <= tries; i++) {
71
- const r = spawnSync(bin, argv, { stdio: "inherit", ...opts });
80
+ const [b, a, shell] = winShell(bin, argv);
81
+ const r = spawnSync(b, a, { stdio: "inherit", shell, ...opts });
72
82
  if (!r.error && r.status === 0) return r;
73
83
  if (i < tries) { warn(`install hiccup — retrying (${i}/${tries - 1})…`); sleep(3); }
74
84
  }
@@ -50,14 +50,24 @@ const flag = (args, name, def) => {
50
50
  };
51
51
  const has = (args, name) => args.includes(name);
52
52
 
53
+ // npm/npx/eas are .cmd shims on Windows, and Node >= 18.20.2 (CVE-2024-27980)
54
+ // refuses to spawn .cmd files without shell:true. With shell:true cmd.exe
55
+ // gets the args space-joined and unescaped, so quote anything with whitespace.
56
+ function winShell(bin, argv) {
57
+ if (process.platform !== "win32") return [bin, argv, false];
58
+ const q = (s) => (/[ \t]/.test(s) ? `"${s}"` : s);
59
+ return [q(bin), argv.map(q), true];
60
+ }
53
61
  function run(bin, argv, opts = {}) {
54
- const r = spawnSync(bin, argv, { stdio: "inherit", ...opts });
62
+ const [b, a, shell] = winShell(bin, argv);
63
+ const r = spawnSync(b, a, { stdio: "inherit", shell, ...opts });
55
64
  if (r.error) throw r.error;
56
65
  if (typeof r.status === "number" && r.status !== 0) throw new Error(`${bin} ${argv.join(" ")} exited ${r.status}`);
57
66
  return r;
58
67
  }
59
68
  function capture(bin, argv, opts = {}) {
60
- const r = spawnSync(bin, argv, { encoding: "utf8", ...opts });
69
+ const [b, a, shell] = winShell(bin, argv);
70
+ const r = spawnSync(b, a, { encoding: "utf8", shell, ...opts });
61
71
  return { status: r.status == null ? 1 : r.status, out: `${r.stdout || ""}${r.stderr || ""}` };
62
72
  }
63
73
 
package/bin/share.js CHANGED
@@ -54,8 +54,17 @@ function readPkg(root) {
54
54
  try { return JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8")); } catch { return null; }
55
55
  }
56
56
 
57
+ // npm/npx/wrangler are .cmd shims on Windows, and Node >= 18.20.2 (CVE-2024-27980)
58
+ // refuses to spawn .cmd files without shell:true. With shell:true cmd.exe
59
+ // gets the args space-joined and unescaped, so quote anything with whitespace.
60
+ function winShell(bin, argv) {
61
+ if (process.platform !== "win32") return [bin, argv, false];
62
+ const q = (s) => (/[ \t]/.test(s) ? `"${s}"` : s);
63
+ return [q(bin), argv.map(q), true];
64
+ }
57
65
  function run(bin, argv, opts = {}) {
58
- const r = spawnSync(bin, argv, { stdio: "inherit", ...opts });
66
+ const [b, a, shell] = winShell(bin, argv);
67
+ const r = spawnSync(b, a, { stdio: "inherit", shell, ...opts });
59
68
  if (r.error) throw r.error;
60
69
  if (typeof r.status === "number" && r.status !== 0) throw new Error(`${bin} ${argv.join(" ")} exited ${r.status}`);
61
70
  return r;
@@ -63,7 +72,8 @@ function run(bin, argv, opts = {}) {
63
72
 
64
73
  // Run while capturing combined output (to parse the deploy URL) but still show it.
65
74
  function runCapture(bin, argv, opts = {}) {
66
- const r = spawnSync(bin, argv, { encoding: "utf8", ...opts });
75
+ const [b, a, shell] = winShell(bin, argv);
76
+ const r = spawnSync(b, a, { encoding: "utf8", shell, ...opts });
67
77
  if (r.error) throw r.error;
68
78
  const out = (r.stdout || "") + (r.stderr || "");
69
79
  process.stdout.write(out);
@@ -74,9 +84,9 @@ function runCapture(bin, argv, opts = {}) {
74
84
  // Prefer an installed wrangler (project-local, then global); else npx. Only used by
75
85
  // --direct — the default path needs no wrangler on this machine.
76
86
  function wranglerCmd(root) {
77
- const local = path.join(root, "node_modules", ".bin", "wrangler");
87
+ const local = path.join(root, "node_modules", ".bin", process.platform === "win32" ? "wrangler.cmd" : "wrangler");
78
88
  if (fs.existsSync(local)) return [local, []];
79
- const probe = spawnSync("wrangler", ["--version"], { stdio: "ignore" });
89
+ const probe = spawnSync("wrangler", ["--version"], { stdio: "ignore", shell: process.platform === "win32" });
80
90
  if (!probe.error && probe.status === 0) return ["wrangler", []];
81
91
  return ["npx", ["--yes", "wrangler@latest"]];
82
92
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@calo-design/cli",
3
- "version": "0.4.7",
3
+ "version": "0.4.8",
4
4
  "description": "One-line setup for Calo design tooling: logs in with your Calo email and installs the calo-design skill + design-system packages. No GitHub account needed.",
5
5
  "bin": {
6
6
  "calo-design": "bin/cli.js"