@lightupai/polaris 0.0.98 → 0.0.100

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/cli/cli.ts +41 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightupai/polaris",
3
- "version": "0.0.98",
3
+ "version": "0.0.100",
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
@@ -182,6 +182,21 @@ const SYSTEMD_USER_DIR = join(homedir(), ".config", "systemd", "user");
182
182
  const SYSTEMD_SERVICE_FILE = join(SYSTEMD_USER_DIR, `${SYSTEMD_SERVICE_NAME}.service`);
183
183
 
184
184
  async function installSystemdService(daemonSecret?: string): Promise<void> {
185
+ // Resolve bun's absolute path at install time so systemd's minimal PATH
186
+ // doesn't matter. Bun.which() searches PATH; process.execPath is the
187
+ // interpreter we're already running under.
188
+ const resolvedBun = Bun.which("bun") ?? process.execPath;
189
+
190
+ // Warn when bun resolved to an npx cache directory — that path is volatile
191
+ // and will break the service if the cache is pruned or the hash changes.
192
+ const isVolatile = resolvedBun.includes("/_npx/") || resolvedBun.includes("/npx_cache/");
193
+ if (isVolatile) {
194
+ console.error(` Warning: bun was found at a volatile npm cache path:`);
195
+ console.error(` ${resolvedBun}`);
196
+ console.error(` The daemon service may break if npm cleans its cache.`);
197
+ console.error(` Install bun permanently for reliability: curl -fsSL https://bun.sh/install | bash`);
198
+ }
199
+
185
200
  const binDir = join(POLARIS_DIR, "bin");
186
201
  const runnerPath = join(binDir, "run-daemon.sh");
187
202
  const daemonTsPath = join(
@@ -189,15 +204,19 @@ async function installSystemdService(daemonSecret?: string): Promise<void> {
189
204
  );
190
205
 
191
206
  await mkdir(binDir, { recursive: true });
192
- // Runner searches common bun install locations — systemd user units inherit a
193
- // minimal PATH that may not include ~/.bun/bin
207
+ // Runner tries the baked-in path first (fast path), then falls back to
208
+ // common stable install locations, then npx as a last resort — so the
209
+ // service survives a cache prune or bun reinstall without needing
210
+ // `polaris install` to be rerun.
194
211
  const runner = [
195
212
  "#!/bin/sh",
196
213
  `# Polaris daemon — managed by systemd (${SYSTEMD_SERVICE_NAME}.service)`,
197
- `for BUNPATH in "$HOME/.bun/bin/bun" /usr/local/bin/bun /usr/bin/bun; do`,
198
- ` [ -x "$BUNPATH" ] && break`,
214
+ `DAEMONTS="${daemonTsPath}"`,
215
+ `for BUNPATH in "${resolvedBun}" "$HOME/.bun/bin/bun" /usr/local/bin/bun /usr/bin/bun; do`,
216
+ ` if [ -x "$BUNPATH" ]; then exec "$BUNPATH" run "$DAEMONTS"; fi`,
199
217
  `done`,
200
- `exec "$BUNPATH" run "${daemonTsPath}"`,
218
+ `# npx fallback — slow but avoids exit-127 restart loops`,
219
+ `exec npx --yes bun run "$DAEMONTS"`,
201
220
  ].join("\n") + "\n";
202
221
  await writeFile(runnerPath, runner);
203
222
  await chmod(runnerPath, 0o755);
@@ -212,7 +231,8 @@ Type=simple
212
231
  ExecStart=${runnerPath}
213
232
  Restart=always
214
233
  RestartSec=5
215
- ${secretLine}StandardOutput=append:/tmp/polaris-daemon.log
234
+ ${secretLine}Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
235
+ StandardOutput=append:/tmp/polaris-daemon.log
216
236
  StandardError=append:/tmp/polaris-daemon.log
217
237
 
218
238
  [Install]
@@ -222,12 +242,24 @@ WantedBy=default.target
222
242
  await mkdir(SYSTEMD_USER_DIR, { recursive: true });
223
243
  await writeFile(SYSTEMD_SERVICE_FILE, unit);
224
244
 
245
+ // Stop any existing manually-started daemon so it releases port 4322
246
+ // before systemd takes over
247
+ await killExistingDaemon();
248
+
225
249
  // Reload unit files, enable (start-at-login) and start/restart the service
226
250
  Bun.spawnSync(["systemctl", "--user", "daemon-reload"], { stdout: "ignore", stderr: "ignore" });
227
251
  Bun.spawnSync(["systemctl", "--user", "enable", SYSTEMD_SERVICE_NAME], { stdout: "ignore", stderr: "ignore" });
228
- const start = Bun.spawnSync(["systemctl", "--user", "restart", SYSTEMD_SERVICE_NAME], { stdout: "pipe", stderr: "pipe" });
229
- if (start.exitCode !== 0) {
230
- console.error(` Warning: could not start daemon service: ${start.stderr.toString().trim()}`);
252
+ Bun.spawnSync(["systemctl", "--user", "restart", SYSTEMD_SERVICE_NAME], { stdout: "ignore", stderr: "ignore" });
253
+
254
+ // Verify the service came up
255
+ const check = Bun.spawnSync(["systemctl", "--user", "is-active", SYSTEMD_SERVICE_NAME], { stdout: "pipe", stderr: "ignore" });
256
+ if (check.stdout.toString().trim() !== "active") {
257
+ console.error(` Warning: daemon service did not start. Check logs:`);
258
+ const journal = Bun.spawnSync(
259
+ ["journalctl", "--user", "-u", SYSTEMD_SERVICE_NAME, "-n", "10", "--no-pager"],
260
+ { stdout: "pipe", stderr: "ignore" }
261
+ );
262
+ console.error(journal.stdout.toString().trim());
231
263
  console.error(` Try manually: systemctl --user restart ${SYSTEMD_SERVICE_NAME}`);
232
264
  }
233
265