cicy-desktop 2.1.324 → 2.1.325

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cicy-desktop",
3
- "version": "2.1.324",
3
+ "version": "2.1.325",
4
4
  "description": "CiCy - AI-powered operating system browser",
5
5
  "main": "src/main.js",
6
6
  "bin": {
package/scripts/r2.mjs CHANGED
@@ -23,6 +23,7 @@
23
23
  // list has no wrangler equivalent, so it goes through the REST API.
24
24
 
25
25
  import { spawnSync } from "node:child_process";
26
+ import { pathToFileURL } from "node:url";
26
27
  import { existsSync, statSync } from "node:fs";
27
28
 
28
29
  const BUCKET = process.env.R2_BUCKET || "cicy-assets-poc";
@@ -42,12 +43,23 @@ function needCreds() {
42
43
  if (!ACCOUNT || !TOKEN) die("R2_ACCOUNT_ID and R2_API_TOKEN must be set");
43
44
  }
44
45
 
46
+ // Windows: npx is npx.cmd, which Node only spawns with shell:true — and then
47
+ // cmd.exe re-parses the argv, so anything with a space ("CiCy Desktop Setup
48
+ // 2.1.324.exe") must be quoted or it arrives as several arguments.
49
+ export function shellQuote(arg, platform = process.platform) {
50
+ const s = String(arg);
51
+ if (platform !== "win32" || !/[\s"&|<>^()]/.test(s)) return s;
52
+ return `"${s.replace(/"/g, '\\"')}"`;
53
+ }
54
+
45
55
  function wrangler(args) {
46
56
  needCreds();
47
- const npx = process.platform === "win32" ? "npx.cmd" : "npx";
48
- const r = spawnSync(npx, ["--yes", WRANGLER, ...args, "--remote"], {
57
+ const isWin = process.platform === "win32";
58
+ const npx = isWin ? "npx.cmd" : "npx";
59
+ const argv = ["--yes", WRANGLER, ...args, "--remote"].map((a) => shellQuote(a));
60
+ const r = spawnSync(npx, argv, {
49
61
  stdio: "inherit",
50
- shell: process.platform === "win32",
62
+ shell: isWin,
51
63
  env: { ...process.env, CLOUDFLARE_ACCOUNT_ID: ACCOUNT, CLOUDFLARE_API_TOKEN: TOKEN },
52
64
  });
53
65
  return r.status == null ? 1 : r.status;
@@ -122,4 +134,5 @@ async function main() {
122
134
  }
123
135
  }
124
136
 
125
- main();
137
+ // Only run when executed directly (tests import shellQuote).
138
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) main();
@@ -0,0 +1,13 @@
1
+ const test = require("node:test");
2
+ const assert = require("node:assert");
3
+
4
+ // scripts/r2.mjs is ESM and runs main() on load; pull just the exported helper.
5
+ async function load() { const m = await import("../scripts/r2.mjs"); return m.shellQuote; }
6
+
7
+ test("shellQuote: Windows paths with spaces are quoted for cmd.exe re-parsing", async () => {
8
+ const q = await load();
9
+ assert.strictEqual(q("CiCy Desktop Setup 2.1.324.exe", "win32"), '"CiCy Desktop Setup 2.1.324.exe"');
10
+ assert.strictEqual(q("releases/win/CiCy-Desktop-Setup-2.1.324.exe", "win32"), "releases/win/CiCy-Desktop-Setup-2.1.324.exe");
11
+ assert.strictEqual(q('a "b" c', "win32"), '"a \\"b\\" c"');
12
+ assert.strictEqual(q("CiCy Desktop Setup 2.1.324.exe", "linux"), "CiCy Desktop Setup 2.1.324.exe");
13
+ });