yaver-cli 1.99.190 → 1.99.192

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/postinstall.js +83 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yaver-cli",
3
- "version": "1.99.190",
3
+ "version": "1.99.192",
4
4
  "mcpName": "io.github.kivanccakmak/yaver",
5
5
  "description": "Unified npm bootstrap for the Yaver agent, SDK injection, and local-first developer runtime",
6
6
  "bin": {
@@ -272,6 +272,82 @@ function ensurePathOnUnix() {
272
272
  }
273
273
  }
274
274
 
275
+ // Update ~/.yaver/bin/current → versioned dir for the binary just
276
+ // installed. Without this, the symlink can lag behind npm — every time
277
+ // I bumped CLI on the user's Mac mini, `~/.yaver/bin/current` kept
278
+ // pointing at an older version, so `~/.yaver/bin/current/<arch>/yaver`
279
+ // silently ran the wrong binary even though `npm install -g yaver-cli@
280
+ // <new>` had succeeded. The auto-update watchdogs (heartbeat_watcher
281
+ // systemctl/launchctl kickstart paths) trust `current` too — so a
282
+ // stale symlink keeps the old binary running across a "restart"
283
+ // without anyone noticing. This belongs in postinstall, runs every
284
+ // global install, never throws.
285
+ function refreshCurrentSymlink(binaryPath) {
286
+ try {
287
+ if (process.platform === "win32") return;
288
+ if (!binaryPath) return;
289
+ // binaryPath is like ~/.yaver/bin/<version>/<cacheKey>/yaver — walk
290
+ // up two levels to the version dir, point `current` at it.
291
+ const versionDir = path.dirname(path.dirname(binaryPath));
292
+ if (!versionDir.startsWith(path.join(os.homedir(), ".yaver", "bin") + path.sep)) {
293
+ return;
294
+ }
295
+ if (!fs.existsSync(versionDir)) return;
296
+ const symlink = path.join(os.homedir(), ".yaver", "bin", "current");
297
+ let already = "";
298
+ try { already = fs.readlinkSync(symlink); } catch (_) {}
299
+ if (already === versionDir) return;
300
+ try { fs.unlinkSync(symlink); } catch (_) {}
301
+ fs.symlinkSync(versionDir, symlink);
302
+ log(`Repointed ~/.yaver/bin/current → ${path.basename(versionDir)}`);
303
+ } catch (err) {
304
+ log(`Skipping current symlink refresh: ${err.message}`);
305
+ }
306
+ }
307
+
308
+ // Restart whichever service supervisor the user has registered. Without
309
+ // this, a fresh `npm install -g yaver-cli@latest` updates the binary on
310
+ // disk but leaves the still-running agent process on the OLD binary
311
+ // until the user manually `yaver restart`s. Every supervisor variant
312
+ // is safe-to-call when not present — failures just no-op so we never
313
+ // block npm install.
314
+ function bounceRunningAgent() {
315
+ if (process.platform === "win32") return;
316
+ try {
317
+ if (process.platform === "darwin") {
318
+ // Per-user LaunchAgent — kickstart -k restarts in-place. We don't
319
+ // touch LaunchDaemon (system-wide) — that requires sudo and is
320
+ // out of scope for an unprivileged npm postinstall.
321
+ execSync(
322
+ `launchctl print "gui/$(id -u)/io.yaver.agent" >/dev/null 2>&1 && ` +
323
+ `launchctl kickstart -k "gui/$(id -u)/io.yaver.agent"`,
324
+ { stdio: "ignore", shell: "/bin/sh" },
325
+ );
326
+ log("Bounced launchd LaunchAgent so the new binary is live.");
327
+ return;
328
+ }
329
+ // Linux: try systemd user unit first, then system unit.
330
+ try {
331
+ execSync(
332
+ `systemctl --user is-active yaver >/dev/null 2>&1 && systemctl --user restart yaver`,
333
+ { stdio: "ignore", shell: "/bin/sh" },
334
+ );
335
+ log("Restarted yaver.service (systemd user unit).");
336
+ return;
337
+ } catch (_) {}
338
+ try {
339
+ execSync(
340
+ `systemctl is-active yaver-agent >/dev/null 2>&1 && systemctl restart yaver-agent`,
341
+ { stdio: "ignore", shell: "/bin/sh" },
342
+ );
343
+ log("Restarted yaver-agent.service (systemd system unit).");
344
+ return;
345
+ } catch (_) {}
346
+ } catch (err) {
347
+ // Best-effort.
348
+ }
349
+ }
350
+
275
351
  async function main() {
276
352
  if (envEnabled("YAVER_SKIP_POSTINSTALL") || envEnabled("YAVER_SKIP_POSTINSTALL_BOOTSTRAP")) {
277
353
  return;
@@ -280,12 +356,18 @@ async function main() {
280
356
  return;
281
357
  }
282
358
 
359
+ let installedBinary = null;
283
360
  try {
284
- await ensureAgentBinary({ quiet: true });
361
+ installedBinary = await ensureAgentBinary({ quiet: true });
285
362
  } catch (error) {
286
363
  log(`Skipping agent prefetch: ${error.message}`);
287
364
  return;
288
365
  }
366
+ // Repoint the canonical `current` symlink + bounce any registered
367
+ // service so a fresh `npm install -g yaver-cli@latest` actually
368
+ // takes effect without a manual `yaver restart`.
369
+ refreshCurrentSymlink(installedBinary);
370
+ bounceRunningAgent();
289
371
 
290
372
  // Platform-aware hermesc provisioning. Downloads the binary matching
291
373
  // this host from the react-native npm tarball, caches it under the