@co0ontty/wand 2.11.0 → 2.11.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.
@@ -1,6 +1,6 @@
1
1
  {
2
- "commit": "3354e091c2cf28e027f1a0b4b4b3d51cd72f4313",
3
- "builtAt": "2026-07-12T01:28:23.178Z",
4
- "version": "2.11.0",
2
+ "commit": "91ceeeaabff61dfaa09abd5bf1327dda55f51879",
3
+ "builtAt": "2026-07-12T01:48:23.296Z",
4
+ "version": "2.11.1",
5
5
  "channel": "stable"
6
6
  }
package/dist/server.js CHANGED
@@ -88,6 +88,7 @@ function readBuildInfo() {
88
88
  }
89
89
  const BUILD_INFO = readBuildInfo();
90
90
  const DISPLAY_VERSION = BUILD_INFO.version || PKG_VERSION;
91
+ const SERVER_INSTANCE_ID = crypto.randomUUID();
91
92
  let cachedGitHubApk = null;
92
93
  let gitHubApkCacheTs = 0;
93
94
  const GITHUB_APK_CACHE_TTL = 10 * 60 * 1000; // 10 minutes
@@ -1375,6 +1376,8 @@ export async function startServer(config, configPath) {
1375
1376
  latestVersion: cachedUpdateInfo?.latest ?? null,
1376
1377
  updateChannel: getUpdateChannel(),
1377
1378
  currentVersion: DISPLAY_VERSION,
1379
+ packageVersion: PKG_VERSION,
1380
+ serverInstanceId: SERVER_INSTANCE_ID,
1378
1381
  });
1379
1382
  });
1380
1383
  // ── Browser extension password vault endpoints ──
@@ -1874,7 +1877,12 @@ export async function startServer(config, configPath) {
1874
1877
  wsManager.emitEvent({
1875
1878
  type: "notification",
1876
1879
  sessionId: "__system__",
1877
- data: { kind: "auto-update-restart", current: info.current, latest: targetLabel },
1880
+ data: {
1881
+ kind: "auto-update-restart",
1882
+ current: info.current,
1883
+ latest: targetLabel,
1884
+ previousInstanceId: SERVER_INSTANCE_ID,
1885
+ },
1878
1886
  });
1879
1887
  res.json({
1880
1888
  ok: true,
@@ -1882,6 +1890,7 @@ export async function startServer(config, configPath) {
1882
1890
  restartRequired: false,
1883
1891
  detachedUpdate: true,
1884
1892
  version: targetLabel,
1893
+ previousInstanceId: SERVER_INSTANCE_ID,
1885
1894
  logPath: helper.logPath,
1886
1895
  });
1887
1896
  }
@@ -2612,7 +2621,12 @@ export async function startServer(config, configPath) {
2612
2621
  wsManager.emitEvent({
2613
2622
  type: "notification",
2614
2623
  sessionId: "__system__",
2615
- data: { kind: "auto-update-start", current: info.current, latest: info.latest },
2624
+ data: {
2625
+ kind: "auto-update-start",
2626
+ current: info.current,
2627
+ latest: info.latest,
2628
+ previousInstanceId: SERVER_INSTANCE_ID,
2629
+ },
2616
2630
  });
2617
2631
  try {
2618
2632
  await npmInstallGlobal(info.installSpec, 120000);
@@ -2624,7 +2638,12 @@ export async function startServer(config, configPath) {
2624
2638
  wsManager.emitEvent({
2625
2639
  type: "notification",
2626
2640
  sessionId: "__system__",
2627
- data: { kind: "auto-update-restart", current: info.current, latest: info.latest },
2641
+ data: {
2642
+ kind: "auto-update-restart",
2643
+ current: info.current,
2644
+ latest: info.latest,
2645
+ previousInstanceId: SERVER_INSTANCE_ID,
2646
+ },
2628
2647
  });
2629
2648
  // Restart after a brief delay
2630
2649
  setTimeout(() => {
@@ -29,6 +29,27 @@ function detectInstalledServiceScopes() {
29
29
  }
30
30
  return [];
31
31
  }
32
+ function readLaunchdJobPid(domain) {
33
+ const result = spawnSync("launchctl", ["print", `${domain}/com.wand.web`], {
34
+ encoding: "utf8",
35
+ timeout: 5_000,
36
+ });
37
+ if (result.status !== 0)
38
+ return null;
39
+ const match = (result.stdout || "").match(/(?:^|\n)\s*pid = (\d+)\s*(?:\n|$)/);
40
+ if (!match)
41
+ return null;
42
+ const pid = Number(match[1]);
43
+ return Number.isSafeInteger(pid) && pid > 1 ? pid : null;
44
+ }
45
+ function detectActiveDarwinServiceScope(pid) {
46
+ if (readLaunchdJobPid("system") === pid)
47
+ return "system";
48
+ const uid = typeof process.getuid === "function" ? process.getuid() : null;
49
+ if (uid !== null && readLaunchdJobPid(`gui/${uid}`) === pid)
50
+ return "user";
51
+ return null;
52
+ }
32
53
  /** A manifest alone is not enough: only a process actually launched by its manager may rely on auto-restart. */
33
54
  export function resolveManagedServiceScope(installedScope, platform = process.platform, env = process.env, pid = process.pid) {
34
55
  if (platform === "darwin") {
@@ -53,7 +74,13 @@ export function resolveManagedServiceScopeCandidates(installedScopes, platform =
53
74
  return managedScope;
54
75
  }
55
76
  function detectManagedServiceScope() {
56
- return resolveManagedServiceScopeCandidates(detectInstalledServiceScopes());
77
+ const installedScopes = detectInstalledServiceScopes();
78
+ if (process.platform === "darwin" && process.env.XPC_SERVICE_NAME === "com.wand.web") {
79
+ const activeScope = detectActiveDarwinServiceScope(process.pid);
80
+ if (activeScope && installedScopes.includes(activeScope))
81
+ return activeScope;
82
+ }
83
+ return resolveManagedServiceScopeCandidates(installedScopes);
57
84
  }
58
85
  export function isStableServiceEntrypoint(entrypoint, stableBin) {
59
86
  if (!entrypoint || !stableBin)
@@ -250,6 +277,16 @@ function spawnDetached(scriptPath, _logPath, env, serviceScope) {
250
277
  stdio: "ignore",
251
278
  env: baseEnv,
252
279
  });
280
+ child.once("error", (error) => {
281
+ try {
282
+ writeFileSync(_logPath, `[wand-update] helper spawn failed: ${error.message}\n`, { flag: "a" });
283
+ }
284
+ catch {
285
+ /* best effort */
286
+ }
287
+ });
288
+ if (!child.pid)
289
+ return null;
253
290
  child.unref();
254
291
  return { pid: child.pid, method };
255
292
  }
@@ -288,7 +325,8 @@ function spawnDetached(scriptPath, _logPath, env, serviceScope) {
288
325
  }
289
326
  }
290
327
  if (process.platform === "darwin") {
291
- const result = trySpawn("nohup", [resolveBashPath(), scriptPath], "nohup");
328
+ const nohupPath = existsSync("/usr/bin/nohup") ? "/usr/bin/nohup" : "nohup";
329
+ const result = trySpawn(nohupPath, [resolveBashPath(), scriptPath], "nohup");
292
330
  if (result)
293
331
  return result;
294
332
  }
@@ -326,6 +364,7 @@ export function startDetachedUpdateHelper(opts) {
326
364
  mode: 0o700,
327
365
  });
328
366
  chmodSync(scriptPath, 0o700);
367
+ writeFileSync(logPath, `[wand-update] helper queued at ${new Date().toISOString()}\n`, "utf8");
329
368
  const spawned = spawnDetached(scriptPath, logPath, opts.env, serviceScope);
330
369
  if (!spawned) {
331
370
  return {