@lightupai/polaris 0.0.80 → 0.0.82

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
@@ -77,7 +77,7 @@ npm install -g @lightupai/polaris
77
77
  polaris
78
78
 
79
79
  # Or run steps independently:
80
- polaris install # Install MCP server, hooks, skill, status line (no auth)
80
+ polaris install # Install MCP server, hooks, skill, status line + restart daemon
81
81
  polaris login # Authenticate against production
82
82
  polaris login --local # Authenticate against localhost (for local dev)
83
83
 
@@ -87,12 +87,22 @@ polaris use local # Switch to local dev
87
87
  polaris use prod # Switch to production
88
88
 
89
89
  # Other commands
90
- polaris daemon # Start the local daemon
90
+ polaris daemon # Start the local daemon (kills any existing daemon first)
91
91
  polaris status # Show active profile, daemon state, sessions
92
92
  polaris logout # Remove active profile credentials
93
93
  polaris logout --all # Remove all credentials
94
94
  ```
95
95
 
96
+ ### Upgrading
97
+
98
+ Because `polaris` is a **global install**, use `npm install -g` to upgrade — not `npx`:
99
+
100
+ ```sh
101
+ npm install -g @lightupai/polaris@latest
102
+ ```
103
+
104
+ `npx @lightupai/polaris@latest` will work for first-time installs but won't override a global binary already in `PATH`. The CLI warns you at startup if a newer version is available.
105
+
96
106
  ## Configuration
97
107
 
98
108
  Copy `.env.example` to `.env` and fill in your credentials. All settings are loaded by the Makefile and passed to services.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightupai/polaris",
3
- "version": "0.0.80",
3
+ "version": "0.0.82",
4
4
  "description": "Record and stream Claude Code sessions to Slack. Like Gong for AI coding — capture every prompt, response, and tool call. Multiplayer collaboration across AI coding agents.",
5
5
  "keywords": [
6
6
  "claude-code",
package/src/cli/cli.ts CHANGED
@@ -486,6 +486,23 @@ async function profiles() {
486
486
 
487
487
  // --- Daemon ---
488
488
 
489
+ async function killExistingDaemon(): Promise<void> {
490
+ // Ask the running daemon to shut down gracefully via the HTTP API, then
491
+ // wait briefly for the port to free up. Falls back silently if no daemon
492
+ // is running or the port is already free.
493
+ try {
494
+ const secret = await ensureDaemonSecret();
495
+ const headers: Record<string, string> = { "Content-Type": "application/json" };
496
+ if (secret) headers["x-polaris-daemon-secret"] = secret;
497
+ await fetch("http://127.0.0.1:4322/shutdown", { method: "POST", headers }).catch(() => {});
498
+ } catch { /* no daemon running */ }
499
+ // Give it a moment to exit, then kill any straggler by port
500
+ await new Promise((r) => setTimeout(r, 500));
501
+ try {
502
+ Bun.spawnSync(["sh", "-c", "lsof -ti :4322 | xargs kill -9 2>/dev/null || true"]);
503
+ } catch { /* best-effort */ }
504
+ }
505
+
489
506
  async function daemon() {
490
507
  const daemonPath = join(import.meta.dir, "..", "daemon", "daemon.ts");
491
508
  console.log("Starting Polaris daemon...");
@@ -761,6 +778,23 @@ async function logout(all = false) {
761
778
  console.log("MCP config and hooks are still installed — run `polaris install` to reset them.");
762
779
  }
763
780
 
781
+ // --- Update check ---
782
+ // Warn if a newer version is available on npm. Best-effort: never blocks startup.
783
+
784
+ async function checkForUpdate(): Promise<void> {
785
+ try {
786
+ const pkgPath = join(import.meta.dir, "..", "..", "package.json");
787
+ const { version: current } = JSON.parse(await readFile(pkgPath, "utf-8")) as { version: string };
788
+ const res = await fetch("https://registry.npmjs.org/@lightupai/polaris/latest", { signal: AbortSignal.timeout(3000) });
789
+ if (!res.ok) return;
790
+ const { version: latest } = await res.json() as { version: string };
791
+ if (latest !== current) {
792
+ console.error(`\n⚠ A newer version of Polaris is available: ${latest} (you have ${current})`);
793
+ console.error(" Run: npm install -g @lightupai/polaris@latest\n");
794
+ }
795
+ } catch { /* best-effort — network may be unavailable */ }
796
+ }
797
+
764
798
  // --- Main ---
765
799
 
766
800
  const args = process.argv.slice(2);
@@ -776,10 +810,23 @@ function hasFlag(name: string): boolean {
776
810
  return args.includes(`--${name}`);
777
811
  }
778
812
 
813
+ void checkForUpdate();
814
+
779
815
  switch (command) {
780
816
  case "install":
781
817
  console.log("Polaris — installing local components\n");
782
818
  await install();
819
+ // Restart daemon so it picks up any updates in the new package
820
+ await killExistingDaemon();
821
+ {
822
+ const daemonPath = join(import.meta.dir, "..", "daemon", "daemon.ts");
823
+ Bun.spawn(["bun", "run", daemonPath], {
824
+ stdout: "ignore",
825
+ stderr: "ignore",
826
+ env: { ...process.env },
827
+ }).unref?.();
828
+ }
829
+ console.log(" ✓ Daemon restarted");
783
830
  console.log("\nInstall complete.");
784
831
  break;
785
832
 
@@ -789,7 +836,8 @@ switch (command) {
789
836
  console.log("Polaris — authenticating\n");
790
837
  await login(appUrl, profileName);
791
838
  console.log("\n✓ Login complete!");
792
- // Auto-start daemon in background
839
+ // Replace any existing daemon with the current version
840
+ await killExistingDaemon();
793
841
  const daemonPath = join(import.meta.dir, "..", "daemon", "daemon.ts");
794
842
  Bun.spawn(["bun", "run", daemonPath], {
795
843
  stdout: "ignore",
@@ -815,6 +863,7 @@ switch (command) {
815
863
  break;
816
864
 
817
865
  case "daemon":
866
+ await killExistingDaemon();
818
867
  await daemon();
819
868
  break;
820
869
 
@@ -839,7 +888,8 @@ switch (command) {
839
888
  console.log("[2/2] Authenticating...\n");
840
889
  await login(DEFAULT_APP_URL);
841
890
  console.log("\n✓ Polaris is set up on this machine!");
842
- // Auto-start daemon in background
891
+ // Replace any existing daemon with the current version
892
+ await killExistingDaemon();
843
893
  const daemonPath = join(import.meta.dir, "..", "daemon", "daemon.ts");
844
894
  Bun.spawn(["bun", "run", daemonPath], {
845
895
  stdout: "ignore",
@@ -884,6 +884,13 @@ export function startDaemon(port = Number(process.env.POLARIS_DAEMON_PORT ?? 432
884
884
  }
885
885
  }
886
886
 
887
+ // POST /shutdown — graceful shutdown (used by `polaris install` to replace an old daemon)
888
+ if (method === "POST" && pathname === "/shutdown") {
889
+ // Respond first, then exit after a short delay so the response is delivered
890
+ setTimeout(() => process.exit(0), 100);
891
+ return json({ status: "shutting_down" });
892
+ }
893
+
887
894
  return error("Not found", 404);
888
895
  },
889
896
  });