ultracontext 1.4.7 → 1.4.9

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.
@@ -95,7 +95,7 @@ async function launchDaemon({ entryPath, diagnosticsHint } = {}) {
95
95
  try {
96
96
  child = spawn(process.execPath, [resolvedEntry, "--daemon"], {
97
97
  env: process.env,
98
- detached: true,
98
+ detached: false,
99
99
  stdio: [
100
100
  "ignore",
101
101
  outFd,
@@ -137,4 +137,4 @@ if (process.argv[1] && import.meta.url.endsWith(process.argv[1].replace(/.*\//,
137
137
 
138
138
  //#endregion
139
139
  export { launchDaemon };
140
- //# sourceMappingURL=launcher-DAaB8H6L.mjs.map
140
+ //# sourceMappingURL=launcher-BMMjzr5k.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launcher-BMMjzr5k.mjs","names":["fs","fsSync"],"sources":["../../sync/src/launcher.mjs"],"sourcesContent":["// daemon launcher — spawns daemon in background, exported as launchDaemon()\nimport fs from \"node:fs/promises\";\nimport fsSync from \"node:fs\";\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport { spawn } from \"node:child_process\";\nimport { fileURLToPath } from \"node:url\";\n\n\nimport { resolveLockPath } from \"./lock.mjs\";\nimport { expandHome } from \"./utils.mjs\";\n\nconst DEFAULT_LOG_FILE = \"~/.ultracontext/daemon.log\";\n\n// ── ANSI helpers ────────────────────────────────────────────────\n\nconst isTTY = process.stdout.isTTY;\nconst esc = (code) => (isTTY ? `\\x1b[${code}m` : \"\");\nconst reset = esc(0);\nconst bold = esc(1);\nconst dim = esc(2);\nconst blue = esc(\"38;2;47;111;179\");\nconst cyan = esc(\"38;2;126;195;255\");\nconst green = esc(\"38;2;80;200;120\");\nconst red = esc(\"38;2;220;80;80\");\nconst gray = esc(\"38;5;245\");\n\n// ── process helpers ─────────────────────────────────────────────\n\nfunction isPidAlive(pid) {\n if (!Number.isInteger(pid) || pid <= 1) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n if (error?.code === \"EPERM\") return true;\n if (error?.code === \"ESRCH\") return false;\n return false;\n }\n}\n\nasync function readJsonFile(filePath) {\n try {\n const raw = await fs.readFile(filePath, \"utf8\");\n const parsed = JSON.parse(raw);\n return parsed && typeof parsed === \"object\" ? parsed : null;\n } catch {\n return null;\n }\n}\n\nasync function readLogTail(logPath, lines = 12) {\n try {\n const raw = await fs.readFile(logPath, \"utf8\");\n const allLines = raw.split(\"\\n\").map((l) => l.trimEnd()).filter(Boolean);\n return allLines.length === 0 ? [] : allLines.slice(-Math.max(lines, 1));\n } catch {\n return [];\n }\n}\n\nfunction resolveDaemonLogFile(env = process.env) {\n return expandHome(env.ULTRACONTEXT_DAEMON_LOG_FILE ?? DEFAULT_LOG_FILE);\n}\n\nasync function resolveRunningProcess(lockPath) {\n const lock = await readJsonFile(lockPath);\n const lockPid = Number.parseInt(String(lock?.pid ?? \"\"), 10);\n if (isPidAlive(lockPid)) {\n return { pid: lockPid, startedAt: String(lock?.startedAt ?? \"\"), userId: String(lock?.userId ?? \"\"), host: String(lock?.host ?? \"\") };\n }\n return null;\n}\n\nasync function resolveWritableLogPath(preferredPath) {\n const primary = path.resolve(preferredPath);\n try {\n await fs.mkdir(path.dirname(primary), { recursive: true });\n fsSync.accessSync(path.dirname(primary), fsSync.constants.W_OK);\n return primary;\n } catch {\n const fallback = path.resolve(process.cwd(), \".ultracontext-daemon.log\");\n await fs.mkdir(path.dirname(fallback), { recursive: true });\n return fallback;\n }\n}\n\n// ── exported entry point ────────────────────────────────────────\n\nexport async function launchDaemon({ entryPath, diagnosticsHint } = {}) {\n const resolvedEntry = entryPath ?? fileURLToPath(new URL(\"./index.mjs\", import.meta.url));\n const hint = diagnosticsHint ?? \"pnpm --filter @ultracontext/sync run start\";\n\n const lockPath = path.resolve(resolveLockPath(process.env));\n const preferredLogPath = resolveDaemonLogFile(process.env);\n\n console.log(\"\");\n console.log(` ${blue}${bold}UltraContext${reset} ${dim}Daemon${reset}`);\n console.log(\"\");\n\n // already running\n const running = await resolveRunningProcess(lockPath);\n if (running) {\n console.log(` ${cyan}●${reset} ${bold}Already running${reset} ${gray}PID ${running.pid}${reset}`);\n console.log(\"\");\n process.exit(2);\n return;\n }\n\n // spawn daemon\n const logPath = await resolveWritableLogPath(preferredLogPath);\n const outFd = fsSync.openSync(logPath, \"a\");\n const errFd = fsSync.openSync(logPath, \"a\");\n\n let child;\n try {\n child = spawn(process.execPath, [resolvedEntry, \"--daemon\"], {\n env: process.env,\n detached: false,\n stdio: [\"ignore\", outFd, errFd],\n });\n child.unref();\n } finally {\n try { fsSync.closeSync(outFd); } catch { /* ignore */ }\n try { fsSync.closeSync(errFd); } catch { /* ignore */ }\n }\n\n await new Promise((resolve) => setTimeout(resolve, 350));\n\n // failed\n if (!isPidAlive(child.pid)) {\n console.log(` ${red}✕${reset} ${bold}Failed to start${reset}`);\n const tail = await readLogTail(logPath);\n if (tail.length > 0) {\n console.log(\"\");\n for (const line of tail) console.error(` ${gray}${line}${reset}`);\n }\n console.log(\"\");\n console.log(` ${dim}Try: ${hint}${reset}`);\n console.log(\"\");\n process.exit(1);\n return;\n }\n\n // success\n console.log(` ${green}✓${reset} ${bold}Started${reset} ${gray}PID ${child.pid}${reset}`);\n console.log(` ${gray}${logPath}${reset}`);\n console.log(\"\");\n}\n\n// auto-exec when run directly\nconst isDirectRun = process.argv[1] && import.meta.url.endsWith(process.argv[1].replace(/.*\\//, \"\"));\nif (isDirectRun) {\n launchDaemon().catch((error) => {\n console.error(` ${red}✕${reset} ${error instanceof Error ? error.message : String(error)}`);\n console.error(\"\");\n process.exit(1);\n });\n}\n"],"mappings":"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"}
@@ -2565,14 +2565,37 @@ async function tuiBoot({ assetsRoot, onFatalError } = {}) {
2565
2565
  ui.updatePrompt.selectedIndex = (ui.updatePrompt.selectedIndex + delta + total) % total;
2566
2566
  renderDashboard();
2567
2567
  }
2568
+ function teardownTui() {
2569
+ if (runtime.statusPollTimer) clearInterval(runtime.statusPollTimer);
2570
+ runtime.statusPollTimer = null;
2571
+ if (runtime.contextRefreshTimer) clearInterval(runtime.contextRefreshTimer);
2572
+ runtime.contextRefreshTimer = null;
2573
+ runtime.uiController?.stop();
2574
+ runtime.uiController = null;
2575
+ runtime.stop?.("update");
2576
+ runtime.stop = null;
2577
+ runtime.uc = null;
2578
+ }
2568
2579
  function chooseUpdatePrompt(index) {
2569
2580
  const choice = UPDATE_PROMPT_OPTIONS[Math.max(Math.min(index, UPDATE_PROMPT_OPTIONS.length - 1), 0)]?.id;
2570
2581
  ui.updatePrompt.active = false;
2571
2582
  renderDashboard();
2572
2583
  if (choice === "install") {
2573
- if (resumeOpenTerminalTab("ultracontext update").ok) ui.resume.notice = `Update started in new tab. Restart TUI after update.`;
2574
- else ui.resume.notice = `Run manually: ultracontext update`;
2575
- renderDashboard();
2584
+ teardownTui();
2585
+ const result = spawnSync(process$1.execPath, [process$1.argv[1], "update"], {
2586
+ stdio: "inherit",
2587
+ env: process$1.env
2588
+ });
2589
+ if (result.status === 0) {
2590
+ const restart = spawnSync(process$1.execPath, [process$1.argv[1]], {
2591
+ stdio: "inherit",
2592
+ env: process$1.env
2593
+ });
2594
+ process$1.exit(restart.status ?? 0);
2595
+ } else {
2596
+ console.error("Update failed. Run manually: ultracontext update");
2597
+ process$1.exit(result.status ?? 1);
2598
+ }
2576
2599
  }
2577
2600
  }
2578
2601
  async function openContextDetail() {
@@ -2868,4 +2891,4 @@ async function tuiBoot({ assetsRoot, onFatalError } = {}) {
2868
2891
 
2869
2892
  //#endregion
2870
2893
  export { tuiBoot };
2871
- //# sourceMappingURL=tui-BqBVUYgD.mjs.map
2894
+ //# sourceMappingURL=tui-tDv_fHC2.mjs.map