ultracontext 1.4.4 → 1.4.6

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.
@@ -12,7 +12,7 @@ const command = (process.argv[2] ?? "").trim().toLowerCase().replace(/^--?/, "")
12
12
  const subcommand = (process.argv[3] ?? "").trim().toLowerCase().replace(/^--?/, "");
13
13
  const PACKAGE_NAME = "ultracontext";
14
14
  const packageRoot = path.resolve(__dirname, "..", "..");
15
- const cliWrapperPath = path.join(packageRoot, "ultracontext.mjs");
15
+ path.join(packageRoot, "ultracontext.mjs");
16
16
  function readVersion() {
17
17
  try {
18
18
  const pkgPath = path.resolve(__dirname, "..", "..", "package.json");
@@ -170,12 +170,6 @@ function parseUpdateOptions(args) {
170
170
  }
171
171
  return opts;
172
172
  }
173
- function runCliSubcommand(subcommand) {
174
- return spawnSync(process.execPath, [cliWrapperPath, subcommand], {
175
- env: process.env,
176
- stdio: "inherit"
177
- }).status ?? 1;
178
- }
179
173
  function runGlobalUpdate(manager, tag) {
180
174
  const spec = `${PACKAGE_NAME}@${normalizeTag(tag)}`;
181
175
  const tuple = {
@@ -215,7 +209,7 @@ const green = esc("38;2;80;200;120");
215
209
  esc("38;2;220;80;80");
216
210
  const cyan = esc("36");
217
211
  const gray = esc("38;5;245");
218
- function runUpdate(rawArgs) {
212
+ async function runUpdate(rawArgs) {
219
213
  const opts = parseUpdateOptions(rawArgs);
220
214
  if (opts.help) {
221
215
  printUpdateHelp();
@@ -230,8 +224,12 @@ function runUpdate(rawArgs) {
230
224
  const wasRunning = isDaemonRunning();
231
225
  if (wasRunning && opts.restart) {
232
226
  console.log(` ${gray}○${r} ${d}Stopping daemon...${r}`);
233
- const stopCode = runCliSubcommand("stop");
234
- if (stopCode !== 0) throw new Error(`Failed to stop daemon before update (exit ${stopCode}).`);
227
+ try {
228
+ process.argv[2] = "stop";
229
+ await runCtlSDK();
230
+ } catch {
231
+ console.log(` ${gray}○${r} ${d}Could not stop daemon. Continuing update...${r}`);
232
+ }
235
233
  }
236
234
  console.log(` ${gray}↓${r} ${d}Updating via ${manager}${r} ${gray}(${PACKAGE_NAME}@${opts.tag})${r}`);
237
235
  runGlobalUpdate(manager, opts.tag);
@@ -240,8 +238,11 @@ function runUpdate(rawArgs) {
240
238
  console.log(` ${green}✓${r} ${b}Updated${r} ${gray}${previousVersion} → ${newVersion}${r}`);
241
239
  if (wasRunning && opts.restart) {
242
240
  console.log(` ${green}●${r} ${d}Restarting daemon...${r}`);
243
- const startCode = runCliSubcommand("start");
244
- if (startCode !== 0) throw new Error(`Update succeeded but daemon restart failed (exit ${startCode}).`);
241
+ try {
242
+ await launchSyncDaemon();
243
+ } catch {
244
+ console.log(` ${gray}○${r} ${d}Auto-restart failed. Run:${r} ${cyan}ultracontext sync${r}`);
245
+ }
245
246
  } else if (wasRunning) console.log(` ${gray}○${r} ${d}Daemon was stopped. Run:${r} ${cyan}ultracontext sync${r}`);
246
247
  console.log("");
247
248
  }
@@ -299,7 +300,7 @@ async function runCtlSDK() {
299
300
  await runCtl();
300
301
  }
301
302
  async function launchTui() {
302
- const { tuiBoot } = await import("../tui-DTVj3nxD.mjs");
303
+ const { tuiBoot } = await import("../tui-Dc0sp0j1.mjs");
303
304
  await tuiBoot({ assetsRoot: path.resolve(__dirname, "..", "..") });
304
305
  }
305
306
  async function run() {
@@ -348,7 +349,7 @@ async function run() {
348
349
  break;
349
350
  case "update":
350
351
  case "upgrade":
351
- runUpdate(process.argv.slice(3));
352
+ await runUpdate(process.argv.slice(3));
352
353
  break;
353
354
  case "help":
354
355
  case "h":
@@ -1 +1 @@
1
- {"version":3,"file":"entry.mjs","names":[],"sources":["../../src/cli/entry.mjs"],"sourcesContent":["#!/usr/bin/env node\n\n// CLI router — dispatches subcommands to daemon/tui entry points\nimport process from \"node:process\";\nimport { fileURLToPath } from \"node:url\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport { spawnSync } from \"node:child_process\";\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst command = (process.argv[2] ?? \"\").trim().toLowerCase().replace(/^--?/, \"\");\nconst subcommand = (process.argv[3] ?? \"\").trim().toLowerCase().replace(/^--?/, \"\");\nconst PACKAGE_NAME = \"ultracontext\";\nconst packageRoot = path.resolve(__dirname, \"..\", \"..\");\nconst cliWrapperPath = path.join(packageRoot, \"ultracontext.mjs\");\n\n// resolve package version\nfunction readVersion() {\n try {\n const pkgPath = path.resolve(__dirname, \"..\", \"..\", \"package.json\");\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf8\"));\n return pkg.version ?? \"unknown\";\n } catch {\n return \"unknown\";\n }\n}\n\nfunction printHelp() {\n const version = readVersion();\n console.log(`ultracontext v${version}\n\nUsage: ultracontext [command] [options]\n\nCommands:\n (none) Start sync (daemon + TUI)\n sync Start sync (daemon + TUI)\n sync start Start daemon in background (no TUI)\n sync stop Stop a running daemon\n sync status Show daemon status\n config Run the setup wizard\n update Update CLI globally via npm/pnpm/bun\n version Print version\n help Show this help message\n\nEnvironment:\n ULTRACONTEXT_API_KEY Required. Your UltraContext API key.\n ULTRACONTEXT_BASE_URL API base URL (default: https://api.ultracontext.ai)\n`);\n}\n\nfunction printUpdateHelp() {\n console.log(`Usage: ultracontext update [options]\n\nOptions:\n --tag <dist-tag|version> Package tag/version (default: latest)\n --manager <npm|pnpm|bun> Force package manager (auto-detected by default)\n --no-restart Do not restart daemon after update\n -h, --help Show this help message\n`);\n}\n\n// commands that need an API key\nconst NEEDS_KEY = new Set([\"\", \"sync\"]);\n\n// interactive onboarding wizard (Ink-based), returns { launchTui }\nasync function runOnboarding() {\n const { onboard } = await import(\"./onboarding.mjs\");\n return onboard();\n}\n\n// check if daemon is already running via lock file\nfunction isDaemonRunning() {\n try {\n const lockPath = path.join(process.env.HOME || process.env.USERPROFILE || \"~\", \".ultracontext\", \"daemon.lock\");\n const lock = JSON.parse(fs.readFileSync(lockPath, \"utf8\"));\n const pid = Number.parseInt(String(lock?.pid ?? \"\"), 10);\n if (!Number.isInteger(pid) || pid <= 1) return false;\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\n// try loading key from config file if env is empty\nfunction loadApiKeyFromConfig() {\n if (process.env.ULTRACONTEXT_API_KEY) return;\n try {\n const configPath = path.join(process.env.HOME || process.env.USERPROFILE || \"~\", \".ultracontext\", \"config.json\");\n const cfg = JSON.parse(fs.readFileSync(configPath, \"utf8\"));\n if (cfg.apiKey) process.env.ULTRACONTEXT_API_KEY = String(cfg.apiKey);\n } catch { /* no config */ }\n}\n\nfunction normalizeTag(value) {\n const trimmed = String(value ?? \"\").trim();\n if (!trimmed) return \"latest\";\n if (trimmed.startsWith(`${PACKAGE_NAME}@`)) return trimmed.slice(`${PACKAGE_NAME}@`.length);\n return trimmed;\n}\n\nfunction safeRealpath(targetPath) {\n try {\n return fs.realpathSync(targetPath);\n } catch {\n return path.resolve(targetPath);\n }\n}\n\nfunction pathsEqual(left, right) {\n return path.resolve(left) === path.resolve(right);\n}\n\nfunction runCapture(commandName, args) {\n const result = spawnSync(commandName, args, {\n env: process.env,\n encoding: \"utf8\",\n });\n return {\n ok: result.status === 0,\n stdout: String(result.stdout ?? \"\"),\n stderr: String(result.stderr ?? \"\"),\n };\n}\n\nfunction resolveBunGlobalRoot() {\n const home = process.env.HOME || process.env.USERPROFILE || os.homedir();\n const bunInstall = String(process.env.BUN_INSTALL ?? \"\").trim() || path.join(home, \".bun\");\n return path.join(bunInstall, \"install\", \"global\", \"node_modules\");\n}\n\nfunction detectGlobalInstallManager() {\n const packageRootReal = safeRealpath(packageRoot);\n const npmGlobalRoot = runCapture(\"npm\", [\"root\", \"-g\"]);\n if (npmGlobalRoot.ok) {\n const npmRoot = npmGlobalRoot.stdout.trim();\n if (npmRoot) {\n const npmExpected = safeRealpath(path.join(npmRoot, PACKAGE_NAME));\n if (pathsEqual(npmExpected, packageRootReal)) return \"npm\";\n }\n }\n\n const pnpmGlobalRoot = runCapture(\"pnpm\", [\"root\", \"-g\"]);\n if (pnpmGlobalRoot.ok) {\n const pnpmRoot = pnpmGlobalRoot.stdout.trim();\n if (pnpmRoot) {\n const pnpmExpected = safeRealpath(path.join(pnpmRoot, PACKAGE_NAME));\n if (pathsEqual(pnpmExpected, packageRootReal)) return \"pnpm\";\n }\n }\n\n const bunExpected = safeRealpath(path.join(resolveBunGlobalRoot(), PACKAGE_NAME));\n if (pathsEqual(bunExpected, packageRootReal)) return \"bun\";\n\n return null;\n}\n\nfunction parseUpdateOptions(args) {\n const opts = {\n tag: \"latest\",\n manager: null,\n restart: true,\n help: false,\n };\n\n for (let i = 0; i < args.length; i += 1) {\n const arg = String(args[i] ?? \"\").trim();\n if (!arg) continue;\n\n if (arg === \"-h\" || arg === \"--help\") {\n opts.help = true;\n continue;\n }\n\n if (arg === \"--no-restart\") {\n opts.restart = false;\n continue;\n }\n\n if (arg === \"--tag\") {\n const next = args[i + 1];\n if (!next || String(next).startsWith(\"-\")) {\n throw new Error(\"Missing value for --tag\");\n }\n opts.tag = normalizeTag(next);\n i += 1;\n continue;\n }\n\n if (arg === \"--manager\") {\n const next = String(args[i + 1] ?? \"\").trim().toLowerCase();\n if (!next || next.startsWith(\"-\")) {\n throw new Error(\"Missing value for --manager\");\n }\n if (![\"npm\", \"pnpm\", \"bun\"].includes(next)) {\n throw new Error(`Invalid --manager value: ${next}`);\n }\n opts.manager = next;\n i += 1;\n continue;\n }\n\n throw new Error(`Unknown update option: ${arg}`);\n }\n\n return opts;\n}\n\nfunction runCliSubcommand(subcommand) {\n const result = spawnSync(process.execPath, [cliWrapperPath, subcommand], {\n env: process.env,\n stdio: \"inherit\",\n });\n return result.status ?? 1;\n}\n\nfunction runGlobalUpdate(manager, tag) {\n const spec = `${PACKAGE_NAME}@${normalizeTag(tag)}`;\n const argvByManager = {\n npm: [\"npm\", [\"i\", \"-g\", spec]],\n pnpm: [\"pnpm\", [\"add\", \"-g\", spec]],\n bun: [\"bun\", [\"add\", \"-g\", spec]],\n };\n\n const tuple = argvByManager[manager];\n if (!tuple) {\n throw new Error(`Unsupported package manager: ${manager}`);\n }\n\n const [bin, args] = tuple;\n\n // skip postinstall to prevent launching a new instance mid-update\n const result = spawnSync(bin, args, {\n env: { ...process.env, ULTRACONTEXT_SKIP_POSTINSTALL: \"1\" },\n stdio: \"inherit\",\n });\n if (result.status !== 0) {\n throw new Error(`Update failed while running: ${bin} ${args.join(\" \")}`);\n }\n}\n\n// ── ANSI helpers ────────────────────────────────────────────────\n\nconst isTTY = process.stdout.isTTY;\nconst esc = (code) => (isTTY ? `\\x1b[${code}m` : \"\");\nconst r = esc(0);\nconst b = esc(1);\nconst d = esc(2);\nconst blue = esc(\"38;2;47;111;179\");\nconst green = esc(\"38;2;80;200;120\");\nconst red = esc(\"38;2;220;80;80\");\nconst cyan = esc(\"36\");\nconst gray = esc(\"38;5;245\");\n\nfunction runUpdate(rawArgs) {\n const opts = parseUpdateOptions(rawArgs);\n if (opts.help) {\n printUpdateHelp();\n return;\n }\n\n const manager = opts.manager ?? detectGlobalInstallManager();\n if (!manager) {\n throw new Error(\n \"Could not detect install manager for this CLI. Re-run with --manager <npm|pnpm|bun>.\",\n );\n }\n\n const previousVersion = readVersion();\n\n console.log(\"\");\n console.log(` ${blue}${b}UltraContext${r} ${d}Update${r}`);\n console.log(\"\");\n\n // stop daemon before update\n const wasRunning = isDaemonRunning();\n if (wasRunning && opts.restart) {\n console.log(` ${gray}○${r} ${d}Stopping daemon...${r}`);\n const stopCode = runCliSubcommand(\"stop\");\n if (stopCode !== 0) {\n throw new Error(`Failed to stop daemon before update (exit ${stopCode}).`);\n }\n }\n\n // run update\n console.log(` ${gray}↓${r} ${d}Updating via ${manager}${r} ${gray}(${PACKAGE_NAME}@${opts.tag})${r}`);\n runGlobalUpdate(manager, opts.tag);\n\n // read new version after update\n const newVersion = readVersion();\n console.log(\"\");\n console.log(` ${green}✓${r} ${b}Updated${r} ${gray}${previousVersion} → ${newVersion}${r}`);\n\n // restart daemon\n if (wasRunning && opts.restart) {\n console.log(` ${green}●${r} ${d}Restarting daemon...${r}`);\n const startCode = runCliSubcommand(\"start\");\n if (startCode !== 0) {\n throw new Error(`Update succeeded but daemon restart failed (exit ${startCode}).`);\n }\n } else if (wasRunning) {\n console.log(` ${gray}○${r} ${d}Daemon was stopped. Run:${r} ${cyan}ultracontext sync${r}`);\n }\n\n console.log(\"\");\n}\n\n// ── update check ────────────────────────────────────────────────\n\nconst SKIP_UPDATE_CHECK = new Set([\"version\", \"v\", \"update\", \"upgrade\", \"help\", \"h\", \"stop\", \"sync\", \"\"]);\n\nasync function fetchLatestVersion() {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 5000);\n try {\n const res = await fetch(\"https://registry.npmjs.org/ultracontext/latest\", { signal: controller.signal });\n const data = await res.json();\n return data.version ?? null;\n } catch { return null; }\n finally { clearTimeout(timeout); }\n}\n\nfunction isNewer(latest, current) {\n const l = latest.split(\".\").map(Number);\n const c = current.split(\".\").map(Number);\n for (let i = 0; i < 3; i++) {\n if ((l[i] ?? 0) > (c[i] ?? 0)) return true;\n if ((l[i] ?? 0) < (c[i] ?? 0)) return false;\n }\n return false;\n}\n\nfunction printUpdateNotice(current, latest) {\n console.log(`\\n ${blue}${b}UltraContext${r} ${d}Update available${r}`);\n console.log(` ${gray}${current}${r} → ${green}${b}${latest}${r}`);\n console.log(` Run ${cyan}ultracontext update${r} to upgrade.\\n`);\n}\n\n// check on every invocation, no cache — like Claude Code\nasync function checkForUpdate() {\n const current = readVersion();\n if (current === \"unknown\") return;\n\n const latest = await fetchLatestVersion();\n if (latest && isNewer(latest, current)) {\n printUpdateNotice(current, latest);\n }\n}\n\n// ── launch helpers ──────────────────────────────────────────────\n\nasync function launchSyncDaemon() {\n const { launchDaemon } = await import(\"@ultracontext/sync/launcher\");\n await launchDaemon({\n entryPath: fileURLToPath(new URL(\"./sdk-sync.mjs\", import.meta.url)),\n diagnosticsHint: \"DAEMON_VERBOSE=1 ultracontext sync\",\n });\n}\n\nasync function runCtlSDK() {\n const { runCtl } = await import(\"@ultracontext/sync/ctl\");\n await runCtl();\n}\n\nasync function launchTui() {\n const { tuiBoot } = await import(\"@ultracontext/sync/tui\");\n await tuiBoot({\n assetsRoot: path.resolve(__dirname, \"..\", \"..\"),\n });\n}\n\n// ── main ────────────────────────────────────────────────────────\n\nasync function run() {\n // check for updates (silent on error, cached 24h)\n if (!SKIP_UPDATE_CHECK.has(command)) await checkForUpdate();\n\n // load saved key, then onboard if still missing\n let onboardResult = null;\n if (NEEDS_KEY.has(command)) {\n loadApiKeyFromConfig();\n if (!process.env.ULTRACONTEXT_API_KEY) onboardResult = await runOnboarding();\n }\n\n switch (command) {\n // sync: subcommand router\n case \"sync\":\n case \"\": {\n // sync start — daemon background only\n if (subcommand === \"start\") {\n await launchSyncDaemon();\n break;\n }\n\n // sync stop — stop daemon\n if (subcommand === \"stop\") {\n process.argv[2] = \"stop\";\n await runCtlSDK();\n break;\n }\n\n // sync status — show daemon status\n if (subcommand === \"status\") {\n process.argv[2] = \"status\";\n await runCtlSDK();\n break;\n }\n\n // bare sync (no subcommand) — daemon bg + TUI fg\n if (!isDaemonRunning()) await launchSyncDaemon();\n if (onboardResult?.launchTui !== false) await launchTui();\n break;\n }\n\n // legacy aliases — redirect to sync subcommands\n case \"start\":\n await launchSyncDaemon();\n break;\n\n case \"stop\":\n process.argv[2] = \"stop\";\n await runCtlSDK();\n break;\n\n case \"config\": {\n const configResult = await runOnboarding();\n if (configResult?.launchTui) {\n if (!isDaemonRunning()) await launchSyncDaemon();\n await launchTui();\n }\n break;\n }\n\n case \"version\":\n case \"v\":\n console.log(readVersion());\n break;\n\n case \"update\":\n case \"upgrade\":\n runUpdate(process.argv.slice(3));\n break;\n\n case \"help\":\n case \"h\":\n printHelp();\n break;\n\n default: {\n // migration hints for removed commands\n if (command === \"tui\") {\n console.log(\"The 'tui' command was removed. Use 'ultracontext sync' instead (TUI is now built-in).\");\n process.exit(0);\n }\n if (command === \"status\") {\n console.log(\"Use 'ultracontext sync status' instead.\");\n process.exit(0);\n }\n console.error(`Unknown command: ${process.argv[2]}`);\n printHelp();\n process.exit(1);\n }\n }\n}\n\nrun().catch((error) => {\n console.error(error instanceof Error ? error.message : String(error));\n process.exit(1);\n});\n"],"mappings":";;;;;;;;;AAUA,MAAM,YAAY,KAAK,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;AAC9D,MAAM,WAAW,QAAQ,KAAK,MAAM,IAAI,MAAM,CAAC,aAAa,CAAC,QAAQ,QAAQ,GAAG;AAChF,MAAM,cAAc,QAAQ,KAAK,MAAM,IAAI,MAAM,CAAC,aAAa,CAAC,QAAQ,QAAQ,GAAG;AACnF,MAAM,eAAe;AACrB,MAAM,cAAc,KAAK,QAAQ,WAAW,MAAM,KAAK;AACvD,MAAM,iBAAiB,KAAK,KAAK,aAAa,mBAAmB;AAGjE,SAAS,cAAc;AACrB,KAAI;EACF,MAAM,UAAU,KAAK,QAAQ,WAAW,MAAM,MAAM,eAAe;AAEnE,SADY,KAAK,MAAM,GAAG,aAAa,SAAS,OAAO,CAAC,CAC7C,WAAW;SAChB;AACN,SAAO;;;AAIX,SAAS,YAAY;CACnB,MAAM,UAAU,aAAa;AAC7B,SAAQ,IAAI,iBAAiB,QAAQ;;;;;;;;;;;;;;;;;;EAkBrC;;AAGF,SAAS,kBAAkB;AACzB,SAAQ,IAAI;;;;;;;EAOZ;;AAIF,MAAM,YAAY,IAAI,IAAI,CAAC,IAAI,OAAO,CAAC;AAGvC,eAAe,gBAAgB;CAC7B,MAAM,EAAE,YAAY,MAAM,OAAO;AACjC,QAAO,SAAS;;AAIlB,SAAS,kBAAkB;AACzB,KAAI;EACF,MAAM,WAAW,KAAK,KAAK,QAAQ,IAAI,QAAQ,QAAQ,IAAI,eAAe,KAAK,iBAAiB,cAAc;EAC9G,MAAM,OAAO,KAAK,MAAM,GAAG,aAAa,UAAU,OAAO,CAAC;EAC1D,MAAM,MAAM,OAAO,SAAS,OAAO,MAAM,OAAO,GAAG,EAAE,GAAG;AACxD,MAAI,CAAC,OAAO,UAAU,IAAI,IAAI,OAAO,EAAG,QAAO;AAC/C,UAAQ,KAAK,KAAK,EAAE;AACpB,SAAO;SACD;AACN,SAAO;;;AAKX,SAAS,uBAAuB;AAC9B,KAAI,QAAQ,IAAI,qBAAsB;AACtC,KAAI;EACF,MAAM,aAAa,KAAK,KAAK,QAAQ,IAAI,QAAQ,QAAQ,IAAI,eAAe,KAAK,iBAAiB,cAAc;EAChH,MAAM,MAAM,KAAK,MAAM,GAAG,aAAa,YAAY,OAAO,CAAC;AAC3D,MAAI,IAAI,OAAQ,SAAQ,IAAI,uBAAuB,OAAO,IAAI,OAAO;SAC/D;;AAGV,SAAS,aAAa,OAAO;CAC3B,MAAM,UAAU,OAAO,SAAS,GAAG,CAAC,MAAM;AAC1C,KAAI,CAAC,QAAS,QAAO;AACrB,KAAI,QAAQ,WAAW,GAAG,aAAa,GAAG,CAAE,QAAO,QAAQ,MAAM,GAAG,aAAa,GAAG,OAAO;AAC3F,QAAO;;AAGT,SAAS,aAAa,YAAY;AAChC,KAAI;AACF,SAAO,GAAG,aAAa,WAAW;SAC5B;AACN,SAAO,KAAK,QAAQ,WAAW;;;AAInC,SAAS,WAAW,MAAM,OAAO;AAC/B,QAAO,KAAK,QAAQ,KAAK,KAAK,KAAK,QAAQ,MAAM;;AAGnD,SAAS,WAAW,aAAa,MAAM;CACrC,MAAM,SAAS,UAAU,aAAa,MAAM;EAC1C,KAAK,QAAQ;EACb,UAAU;EACX,CAAC;AACF,QAAO;EACL,IAAI,OAAO,WAAW;EACtB,QAAQ,OAAO,OAAO,UAAU,GAAG;EACnC,QAAQ,OAAO,OAAO,UAAU,GAAG;EACpC;;AAGH,SAAS,uBAAuB;CAC9B,MAAM,OAAO,QAAQ,IAAI,QAAQ,QAAQ,IAAI,eAAe,GAAG,SAAS;CACxE,MAAM,aAAa,OAAO,QAAQ,IAAI,eAAe,GAAG,CAAC,MAAM,IAAI,KAAK,KAAK,MAAM,OAAO;AAC1F,QAAO,KAAK,KAAK,YAAY,WAAW,UAAU,eAAe;;AAGnE,SAAS,6BAA6B;CACpC,MAAM,kBAAkB,aAAa,YAAY;CACjD,MAAM,gBAAgB,WAAW,OAAO,CAAC,QAAQ,KAAK,CAAC;AACvD,KAAI,cAAc,IAAI;EACpB,MAAM,UAAU,cAAc,OAAO,MAAM;AAC3C,MAAI,SAEF;OAAI,WADgB,aAAa,KAAK,KAAK,SAAS,aAAa,CAAC,EACtC,gBAAgB,CAAE,QAAO;;;CAIzD,MAAM,iBAAiB,WAAW,QAAQ,CAAC,QAAQ,KAAK,CAAC;AACzD,KAAI,eAAe,IAAI;EACrB,MAAM,WAAW,eAAe,OAAO,MAAM;AAC7C,MAAI,UAEF;OAAI,WADiB,aAAa,KAAK,KAAK,UAAU,aAAa,CAAC,EACvC,gBAAgB,CAAE,QAAO;;;AAK1D,KAAI,WADgB,aAAa,KAAK,KAAK,sBAAsB,EAAE,aAAa,CAAC,EACrD,gBAAgB,CAAE,QAAO;AAErD,QAAO;;AAGT,SAAS,mBAAmB,MAAM;CAChC,MAAM,OAAO;EACX,KAAK;EACL,SAAS;EACT,SAAS;EACT,MAAM;EACP;AAED,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,GAAG;EACvC,MAAM,MAAM,OAAO,KAAK,MAAM,GAAG,CAAC,MAAM;AACxC,MAAI,CAAC,IAAK;AAEV,MAAI,QAAQ,QAAQ,QAAQ,UAAU;AACpC,QAAK,OAAO;AACZ;;AAGF,MAAI,QAAQ,gBAAgB;AAC1B,QAAK,UAAU;AACf;;AAGF,MAAI,QAAQ,SAAS;GACnB,MAAM,OAAO,KAAK,IAAI;AACtB,OAAI,CAAC,QAAQ,OAAO,KAAK,CAAC,WAAW,IAAI,CACvC,OAAM,IAAI,MAAM,0BAA0B;AAE5C,QAAK,MAAM,aAAa,KAAK;AAC7B,QAAK;AACL;;AAGF,MAAI,QAAQ,aAAa;GACvB,MAAM,OAAO,OAAO,KAAK,IAAI,MAAM,GAAG,CAAC,MAAM,CAAC,aAAa;AAC3D,OAAI,CAAC,QAAQ,KAAK,WAAW,IAAI,CAC/B,OAAM,IAAI,MAAM,8BAA8B;AAEhD,OAAI,CAAC;IAAC;IAAO;IAAQ;IAAM,CAAC,SAAS,KAAK,CACxC,OAAM,IAAI,MAAM,4BAA4B,OAAO;AAErD,QAAK,UAAU;AACf,QAAK;AACL;;AAGF,QAAM,IAAI,MAAM,0BAA0B,MAAM;;AAGlD,QAAO;;AAGT,SAAS,iBAAiB,YAAY;AAKpC,QAJe,UAAU,QAAQ,UAAU,CAAC,gBAAgB,WAAW,EAAE;EACvE,KAAK,QAAQ;EACb,OAAO;EACR,CAAC,CACY,UAAU;;AAG1B,SAAS,gBAAgB,SAAS,KAAK;CACrC,MAAM,OAAO,GAAG,aAAa,GAAG,aAAa,IAAI;CAOjD,MAAM,QANgB;EACpB,KAAK,CAAC,OAAO;GAAC;GAAK;GAAM;GAAK,CAAC;EAC/B,MAAM,CAAC,QAAQ;GAAC;GAAO;GAAM;GAAK,CAAC;EACnC,KAAK,CAAC,OAAO;GAAC;GAAO;GAAM;GAAK,CAAC;EAClC,CAE2B;AAC5B,KAAI,CAAC,MACH,OAAM,IAAI,MAAM,gCAAgC,UAAU;CAG5D,MAAM,CAAC,KAAK,QAAQ;AAOpB,KAJe,UAAU,KAAK,MAAM;EAClC,KAAK;GAAE,GAAG,QAAQ;GAAK,+BAA+B;GAAK;EAC3D,OAAO;EACR,CAAC,CACS,WAAW,EACpB,OAAM,IAAI,MAAM,gCAAgC,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG;;AAM5E,MAAM,QAAQ,QAAQ,OAAO;AAC7B,MAAM,OAAO,SAAU,QAAQ,QAAQ,KAAK,KAAK;AACjD,MAAM,IAAI,IAAI,EAAE;AAChB,MAAM,IAAI,IAAI,EAAE;AAChB,MAAM,IAAI,IAAI,EAAE;AAChB,MAAM,OAAO,IAAI,kBAAkB;AACnC,MAAM,QAAQ,IAAI,kBAAkB;AACxB,IAAI,iBAAiB;AACjC,MAAM,OAAO,IAAI,KAAK;AACtB,MAAM,OAAO,IAAI,WAAW;AAE5B,SAAS,UAAU,SAAS;CAC1B,MAAM,OAAO,mBAAmB,QAAQ;AACxC,KAAI,KAAK,MAAM;AACb,mBAAiB;AACjB;;CAGF,MAAM,UAAU,KAAK,WAAW,4BAA4B;AAC5D,KAAI,CAAC,QACH,OAAM,IAAI,MACR,uFACD;CAGH,MAAM,kBAAkB,aAAa;AAErC,SAAQ,IAAI,GAAG;AACf,SAAQ,IAAI,KAAK,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,QAAQ,IAAI;AAC3D,SAAQ,IAAI,GAAG;CAGf,MAAM,aAAa,iBAAiB;AACpC,KAAI,cAAc,KAAK,SAAS;AAC9B,UAAQ,IAAI,KAAK,KAAK,GAAG,EAAE,GAAG,EAAE,oBAAoB,IAAI;EACxD,MAAM,WAAW,iBAAiB,OAAO;AACzC,MAAI,aAAa,EACf,OAAM,IAAI,MAAM,6CAA6C,SAAS,IAAI;;AAK9E,SAAQ,IAAI,KAAK,KAAK,GAAG,EAAE,GAAG,EAAE,eAAe,UAAU,EAAE,GAAG,KAAK,GAAG,aAAa,GAAG,KAAK,IAAI,GAAG,IAAI;AACtG,iBAAgB,SAAS,KAAK,IAAI;CAGlC,MAAM,aAAa,aAAa;AAChC,SAAQ,IAAI,GAAG;AACf,SAAQ,IAAI,KAAK,MAAM,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,OAAO,gBAAgB,KAAK,aAAa,IAAI;AAG7F,KAAI,cAAc,KAAK,SAAS;AAC9B,UAAQ,IAAI,KAAK,MAAM,GAAG,EAAE,GAAG,EAAE,sBAAsB,IAAI;EAC3D,MAAM,YAAY,iBAAiB,QAAQ;AAC3C,MAAI,cAAc,EAChB,OAAM,IAAI,MAAM,oDAAoD,UAAU,IAAI;YAE3E,WACT,SAAQ,IAAI,KAAK,KAAK,GAAG,EAAE,GAAG,EAAE,0BAA0B,EAAE,GAAG,KAAK,mBAAmB,IAAI;AAG7F,SAAQ,IAAI,GAAG;;AAKjB,MAAM,oBAAoB,IAAI,IAAI;CAAC;CAAW;CAAK;CAAU;CAAW;CAAQ;CAAK;CAAQ;CAAQ;CAAG,CAAC;AAEzG,eAAe,qBAAqB;CAClC,MAAM,aAAa,IAAI,iBAAiB;CACxC,MAAM,UAAU,iBAAiB,WAAW,OAAO,EAAE,IAAK;AAC1D,KAAI;AAGF,UADa,OADD,MAAM,MAAM,kDAAkD,EAAE,QAAQ,WAAW,QAAQ,CAAC,EACjF,MAAM,EACjB,WAAW;SACjB;AAAE,SAAO;WACT;AAAE,eAAa,QAAQ;;;AAGjC,SAAS,QAAQ,QAAQ,SAAS;CAChC,MAAM,IAAI,OAAO,MAAM,IAAI,CAAC,IAAI,OAAO;CACvC,MAAM,IAAI,QAAQ,MAAM,IAAI,CAAC,IAAI,OAAO;AACxC,MAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,OAAK,EAAE,MAAM,MAAM,EAAE,MAAM,GAAI,QAAO;AACtC,OAAK,EAAE,MAAM,MAAM,EAAE,MAAM,GAAI,QAAO;;AAExC,QAAO;;AAGT,SAAS,kBAAkB,SAAS,QAAQ;AAC1C,SAAQ,IAAI,OAAO,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,kBAAkB,IAAI;AACvE,SAAQ,IAAI,KAAK,OAAO,UAAU,EAAE,KAAK,QAAQ,IAAI,SAAS,IAAI;AAClE,SAAQ,IAAI,SAAS,KAAK,qBAAqB,EAAE,gBAAgB;;AAInE,eAAe,iBAAiB;CAC9B,MAAM,UAAU,aAAa;AAC7B,KAAI,YAAY,UAAW;CAE3B,MAAM,SAAS,MAAM,oBAAoB;AACzC,KAAI,UAAU,QAAQ,QAAQ,QAAQ,CACpC,mBAAkB,SAAS,OAAO;;AAMtC,eAAe,mBAAmB;CAChC,MAAM,EAAE,iBAAiB,MAAM,OAAO;AACtC,OAAM,aAAa;EACjB,WAAW,cAAc,IAAI,IAAI,kBAAkB,OAAO,KAAK,IAAI,CAAC;EACpE,iBAAiB;EAClB,CAAC;;AAGJ,eAAe,YAAY;CACzB,MAAM,EAAE,WAAW,MAAM,OAAO;AAChC,OAAM,QAAQ;;AAGhB,eAAe,YAAY;CACzB,MAAM,EAAE,YAAY,MAAM,OAAO;AACjC,OAAM,QAAQ,EACZ,YAAY,KAAK,QAAQ,WAAW,MAAM,KAAK,EAChD,CAAC;;AAKJ,eAAe,MAAM;AAEnB,KAAI,CAAC,kBAAkB,IAAI,QAAQ,CAAE,OAAM,gBAAgB;CAG3D,IAAI,gBAAgB;AACpB,KAAI,UAAU,IAAI,QAAQ,EAAE;AAC1B,wBAAsB;AACtB,MAAI,CAAC,QAAQ,IAAI,qBAAsB,iBAAgB,MAAM,eAAe;;AAG9E,SAAQ,SAAR;EAEE,KAAK;EACL,KAAK;AAEH,OAAI,eAAe,SAAS;AAC1B,UAAM,kBAAkB;AACxB;;AAIF,OAAI,eAAe,QAAQ;AACzB,YAAQ,KAAK,KAAK;AAClB,UAAM,WAAW;AACjB;;AAIF,OAAI,eAAe,UAAU;AAC3B,YAAQ,KAAK,KAAK;AAClB,UAAM,WAAW;AACjB;;AAIF,OAAI,CAAC,iBAAiB,CAAE,OAAM,kBAAkB;AAChD,OAAI,eAAe,cAAc,MAAO,OAAM,WAAW;AACzD;EAIF,KAAK;AACH,SAAM,kBAAkB;AACxB;EAEF,KAAK;AACH,WAAQ,KAAK,KAAK;AAClB,SAAM,WAAW;AACjB;EAEF,KAAK;AAEH,QADqB,MAAM,eAAe,GACxB,WAAW;AAC3B,QAAI,CAAC,iBAAiB,CAAE,OAAM,kBAAkB;AAChD,UAAM,WAAW;;AAEnB;EAGF,KAAK;EACL,KAAK;AACH,WAAQ,IAAI,aAAa,CAAC;AAC1B;EAEF,KAAK;EACL,KAAK;AACH,aAAU,QAAQ,KAAK,MAAM,EAAE,CAAC;AAChC;EAEF,KAAK;EACL,KAAK;AACH,cAAW;AACX;EAEF;AAEE,OAAI,YAAY,OAAO;AACrB,YAAQ,IAAI,wFAAwF;AACpG,YAAQ,KAAK,EAAE;;AAEjB,OAAI,YAAY,UAAU;AACxB,YAAQ,IAAI,0CAA0C;AACtD,YAAQ,KAAK,EAAE;;AAEjB,WAAQ,MAAM,oBAAoB,QAAQ,KAAK,KAAK;AACpD,cAAW;AACX,WAAQ,KAAK,EAAE;;;AAKrB,KAAK,CAAC,OAAO,UAAU;AACrB,SAAQ,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CAAC;AACrE,SAAQ,KAAK,EAAE;EACf"}
1
+ {"version":3,"file":"entry.mjs","names":[],"sources":["../../src/cli/entry.mjs"],"sourcesContent":["#!/usr/bin/env node\n\n// CLI router — dispatches subcommands to daemon/tui entry points\nimport process from \"node:process\";\nimport { fileURLToPath } from \"node:url\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport { spawnSync } from \"node:child_process\";\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst command = (process.argv[2] ?? \"\").trim().toLowerCase().replace(/^--?/, \"\");\nconst subcommand = (process.argv[3] ?? \"\").trim().toLowerCase().replace(/^--?/, \"\");\nconst PACKAGE_NAME = \"ultracontext\";\nconst packageRoot = path.resolve(__dirname, \"..\", \"..\");\nconst cliWrapperPath = path.join(packageRoot, \"ultracontext.mjs\");\n\n// resolve package version\nfunction readVersion() {\n try {\n const pkgPath = path.resolve(__dirname, \"..\", \"..\", \"package.json\");\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf8\"));\n return pkg.version ?? \"unknown\";\n } catch {\n return \"unknown\";\n }\n}\n\nfunction printHelp() {\n const version = readVersion();\n console.log(`ultracontext v${version}\n\nUsage: ultracontext [command] [options]\n\nCommands:\n (none) Start sync (daemon + TUI)\n sync Start sync (daemon + TUI)\n sync start Start daemon in background (no TUI)\n sync stop Stop a running daemon\n sync status Show daemon status\n config Run the setup wizard\n update Update CLI globally via npm/pnpm/bun\n version Print version\n help Show this help message\n\nEnvironment:\n ULTRACONTEXT_API_KEY Required. Your UltraContext API key.\n ULTRACONTEXT_BASE_URL API base URL (default: https://api.ultracontext.ai)\n`);\n}\n\nfunction printUpdateHelp() {\n console.log(`Usage: ultracontext update [options]\n\nOptions:\n --tag <dist-tag|version> Package tag/version (default: latest)\n --manager <npm|pnpm|bun> Force package manager (auto-detected by default)\n --no-restart Do not restart daemon after update\n -h, --help Show this help message\n`);\n}\n\n// commands that need an API key\nconst NEEDS_KEY = new Set([\"\", \"sync\"]);\n\n// interactive onboarding wizard (Ink-based), returns { launchTui }\nasync function runOnboarding() {\n const { onboard } = await import(\"./onboarding.mjs\");\n return onboard();\n}\n\n// check if daemon is already running via lock file\nfunction isDaemonRunning() {\n try {\n const lockPath = path.join(process.env.HOME || process.env.USERPROFILE || \"~\", \".ultracontext\", \"daemon.lock\");\n const lock = JSON.parse(fs.readFileSync(lockPath, \"utf8\"));\n const pid = Number.parseInt(String(lock?.pid ?? \"\"), 10);\n if (!Number.isInteger(pid) || pid <= 1) return false;\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\n// try loading key from config file if env is empty\nfunction loadApiKeyFromConfig() {\n if (process.env.ULTRACONTEXT_API_KEY) return;\n try {\n const configPath = path.join(process.env.HOME || process.env.USERPROFILE || \"~\", \".ultracontext\", \"config.json\");\n const cfg = JSON.parse(fs.readFileSync(configPath, \"utf8\"));\n if (cfg.apiKey) process.env.ULTRACONTEXT_API_KEY = String(cfg.apiKey);\n } catch { /* no config */ }\n}\n\nfunction normalizeTag(value) {\n const trimmed = String(value ?? \"\").trim();\n if (!trimmed) return \"latest\";\n if (trimmed.startsWith(`${PACKAGE_NAME}@`)) return trimmed.slice(`${PACKAGE_NAME}@`.length);\n return trimmed;\n}\n\nfunction safeRealpath(targetPath) {\n try {\n return fs.realpathSync(targetPath);\n } catch {\n return path.resolve(targetPath);\n }\n}\n\nfunction pathsEqual(left, right) {\n return path.resolve(left) === path.resolve(right);\n}\n\nfunction runCapture(commandName, args) {\n const result = spawnSync(commandName, args, {\n env: process.env,\n encoding: \"utf8\",\n });\n return {\n ok: result.status === 0,\n stdout: String(result.stdout ?? \"\"),\n stderr: String(result.stderr ?? \"\"),\n };\n}\n\nfunction resolveBunGlobalRoot() {\n const home = process.env.HOME || process.env.USERPROFILE || os.homedir();\n const bunInstall = String(process.env.BUN_INSTALL ?? \"\").trim() || path.join(home, \".bun\");\n return path.join(bunInstall, \"install\", \"global\", \"node_modules\");\n}\n\nfunction detectGlobalInstallManager() {\n const packageRootReal = safeRealpath(packageRoot);\n const npmGlobalRoot = runCapture(\"npm\", [\"root\", \"-g\"]);\n if (npmGlobalRoot.ok) {\n const npmRoot = npmGlobalRoot.stdout.trim();\n if (npmRoot) {\n const npmExpected = safeRealpath(path.join(npmRoot, PACKAGE_NAME));\n if (pathsEqual(npmExpected, packageRootReal)) return \"npm\";\n }\n }\n\n const pnpmGlobalRoot = runCapture(\"pnpm\", [\"root\", \"-g\"]);\n if (pnpmGlobalRoot.ok) {\n const pnpmRoot = pnpmGlobalRoot.stdout.trim();\n if (pnpmRoot) {\n const pnpmExpected = safeRealpath(path.join(pnpmRoot, PACKAGE_NAME));\n if (pathsEqual(pnpmExpected, packageRootReal)) return \"pnpm\";\n }\n }\n\n const bunExpected = safeRealpath(path.join(resolveBunGlobalRoot(), PACKAGE_NAME));\n if (pathsEqual(bunExpected, packageRootReal)) return \"bun\";\n\n return null;\n}\n\nfunction parseUpdateOptions(args) {\n const opts = {\n tag: \"latest\",\n manager: null,\n restart: true,\n help: false,\n };\n\n for (let i = 0; i < args.length; i += 1) {\n const arg = String(args[i] ?? \"\").trim();\n if (!arg) continue;\n\n if (arg === \"-h\" || arg === \"--help\") {\n opts.help = true;\n continue;\n }\n\n if (arg === \"--no-restart\") {\n opts.restart = false;\n continue;\n }\n\n if (arg === \"--tag\") {\n const next = args[i + 1];\n if (!next || String(next).startsWith(\"-\")) {\n throw new Error(\"Missing value for --tag\");\n }\n opts.tag = normalizeTag(next);\n i += 1;\n continue;\n }\n\n if (arg === \"--manager\") {\n const next = String(args[i + 1] ?? \"\").trim().toLowerCase();\n if (!next || next.startsWith(\"-\")) {\n throw new Error(\"Missing value for --manager\");\n }\n if (![\"npm\", \"pnpm\", \"bun\"].includes(next)) {\n throw new Error(`Invalid --manager value: ${next}`);\n }\n opts.manager = next;\n i += 1;\n continue;\n }\n\n throw new Error(`Unknown update option: ${arg}`);\n }\n\n return opts;\n}\n\nfunction runCliSubcommand(subcommand) {\n const result = spawnSync(process.execPath, [cliWrapperPath, subcommand], {\n env: process.env,\n stdio: \"inherit\",\n });\n return result.status ?? 1;\n}\n\nfunction runGlobalUpdate(manager, tag) {\n const spec = `${PACKAGE_NAME}@${normalizeTag(tag)}`;\n const argvByManager = {\n npm: [\"npm\", [\"i\", \"-g\", spec]],\n pnpm: [\"pnpm\", [\"add\", \"-g\", spec]],\n bun: [\"bun\", [\"add\", \"-g\", spec]],\n };\n\n const tuple = argvByManager[manager];\n if (!tuple) {\n throw new Error(`Unsupported package manager: ${manager}`);\n }\n\n const [bin, args] = tuple;\n\n // skip postinstall to prevent launching a new instance mid-update\n const result = spawnSync(bin, args, {\n env: { ...process.env, ULTRACONTEXT_SKIP_POSTINSTALL: \"1\" },\n stdio: \"inherit\",\n });\n if (result.status !== 0) {\n throw new Error(`Update failed while running: ${bin} ${args.join(\" \")}`);\n }\n}\n\n// ── ANSI helpers ────────────────────────────────────────────────\n\nconst isTTY = process.stdout.isTTY;\nconst esc = (code) => (isTTY ? `\\x1b[${code}m` : \"\");\nconst r = esc(0);\nconst b = esc(1);\nconst d = esc(2);\nconst blue = esc(\"38;2;47;111;179\");\nconst green = esc(\"38;2;80;200;120\");\nconst red = esc(\"38;2;220;80;80\");\nconst cyan = esc(\"36\");\nconst gray = esc(\"38;5;245\");\n\nasync function runUpdate(rawArgs) {\n const opts = parseUpdateOptions(rawArgs);\n if (opts.help) {\n printUpdateHelp();\n return;\n }\n\n const manager = opts.manager ?? detectGlobalInstallManager();\n if (!manager) {\n throw new Error(\n \"Could not detect install manager for this CLI. Re-run with --manager <npm|pnpm|bun>.\",\n );\n }\n\n const previousVersion = readVersion();\n\n console.log(\"\");\n console.log(` ${blue}${b}UltraContext${r} ${d}Update${r}`);\n console.log(\"\");\n\n // stop daemon before update (in-process, no subprocess)\n const wasRunning = isDaemonRunning();\n if (wasRunning && opts.restart) {\n console.log(` ${gray}○${r} ${d}Stopping daemon...${r}`);\n try {\n process.argv[2] = \"stop\";\n await runCtlSDK();\n } catch {\n console.log(` ${gray}○${r} ${d}Could not stop daemon. Continuing update...${r}`);\n }\n }\n\n // run update\n console.log(` ${gray}↓${r} ${d}Updating via ${manager}${r} ${gray}(${PACKAGE_NAME}@${opts.tag})${r}`);\n runGlobalUpdate(manager, opts.tag);\n\n // read new version after update\n const newVersion = readVersion();\n console.log(\"\");\n console.log(` ${green}✓${r} ${b}Updated${r} ${gray}${previousVersion} → ${newVersion}${r}`);\n\n // restart daemon in-process (no subprocess, no new terminal)\n if (wasRunning && opts.restart) {\n console.log(` ${green}●${r} ${d}Restarting daemon...${r}`);\n try {\n await launchSyncDaemon();\n } catch {\n console.log(` ${gray}○${r} ${d}Auto-restart failed. Run:${r} ${cyan}ultracontext sync${r}`);\n }\n } else if (wasRunning) {\n console.log(` ${gray}○${r} ${d}Daemon was stopped. Run:${r} ${cyan}ultracontext sync${r}`);\n }\n\n console.log(\"\");\n}\n\n// ── update check ────────────────────────────────────────────────\n\nconst SKIP_UPDATE_CHECK = new Set([\"version\", \"v\", \"update\", \"upgrade\", \"help\", \"h\", \"stop\", \"sync\", \"\"]);\n\nasync function fetchLatestVersion() {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 5000);\n try {\n const res = await fetch(\"https://registry.npmjs.org/ultracontext/latest\", { signal: controller.signal });\n const data = await res.json();\n return data.version ?? null;\n } catch { return null; }\n finally { clearTimeout(timeout); }\n}\n\nfunction isNewer(latest, current) {\n const l = latest.split(\".\").map(Number);\n const c = current.split(\".\").map(Number);\n for (let i = 0; i < 3; i++) {\n if ((l[i] ?? 0) > (c[i] ?? 0)) return true;\n if ((l[i] ?? 0) < (c[i] ?? 0)) return false;\n }\n return false;\n}\n\nfunction printUpdateNotice(current, latest) {\n console.log(`\\n ${blue}${b}UltraContext${r} ${d}Update available${r}`);\n console.log(` ${gray}${current}${r} → ${green}${b}${latest}${r}`);\n console.log(` Run ${cyan}ultracontext update${r} to upgrade.\\n`);\n}\n\n// check on every invocation, no cache — like Claude Code\nasync function checkForUpdate() {\n const current = readVersion();\n if (current === \"unknown\") return;\n\n const latest = await fetchLatestVersion();\n if (latest && isNewer(latest, current)) {\n printUpdateNotice(current, latest);\n }\n}\n\n// ── launch helpers ──────────────────────────────────────────────\n\nasync function launchSyncDaemon() {\n const { launchDaemon } = await import(\"@ultracontext/sync/launcher\");\n await launchDaemon({\n entryPath: fileURLToPath(new URL(\"./sdk-sync.mjs\", import.meta.url)),\n diagnosticsHint: \"DAEMON_VERBOSE=1 ultracontext sync\",\n });\n}\n\nasync function runCtlSDK() {\n const { runCtl } = await import(\"@ultracontext/sync/ctl\");\n await runCtl();\n}\n\nasync function launchTui() {\n const { tuiBoot } = await import(\"@ultracontext/sync/tui\");\n await tuiBoot({\n assetsRoot: path.resolve(__dirname, \"..\", \"..\"),\n });\n}\n\n// ── main ────────────────────────────────────────────────────────\n\nasync function run() {\n // check for updates (silent on error, cached 24h)\n if (!SKIP_UPDATE_CHECK.has(command)) await checkForUpdate();\n\n // load saved key, then onboard if still missing\n let onboardResult = null;\n if (NEEDS_KEY.has(command)) {\n loadApiKeyFromConfig();\n if (!process.env.ULTRACONTEXT_API_KEY) onboardResult = await runOnboarding();\n }\n\n switch (command) {\n // sync: subcommand router\n case \"sync\":\n case \"\": {\n // sync start — daemon background only\n if (subcommand === \"start\") {\n await launchSyncDaemon();\n break;\n }\n\n // sync stop — stop daemon\n if (subcommand === \"stop\") {\n process.argv[2] = \"stop\";\n await runCtlSDK();\n break;\n }\n\n // sync status — show daemon status\n if (subcommand === \"status\") {\n process.argv[2] = \"status\";\n await runCtlSDK();\n break;\n }\n\n // bare sync (no subcommand) — daemon bg + TUI fg\n if (!isDaemonRunning()) await launchSyncDaemon();\n if (onboardResult?.launchTui !== false) await launchTui();\n break;\n }\n\n // legacy aliases — redirect to sync subcommands\n case \"start\":\n await launchSyncDaemon();\n break;\n\n case \"stop\":\n process.argv[2] = \"stop\";\n await runCtlSDK();\n break;\n\n case \"config\": {\n const configResult = await runOnboarding();\n if (configResult?.launchTui) {\n if (!isDaemonRunning()) await launchSyncDaemon();\n await launchTui();\n }\n break;\n }\n\n case \"version\":\n case \"v\":\n console.log(readVersion());\n break;\n\n case \"update\":\n case \"upgrade\":\n await runUpdate(process.argv.slice(3));\n break;\n\n case \"help\":\n case \"h\":\n printHelp();\n break;\n\n default: {\n // migration hints for removed commands\n if (command === \"tui\") {\n console.log(\"The 'tui' command was removed. Use 'ultracontext sync' instead (TUI is now built-in).\");\n process.exit(0);\n }\n if (command === \"status\") {\n console.log(\"Use 'ultracontext sync status' instead.\");\n process.exit(0);\n }\n console.error(`Unknown command: ${process.argv[2]}`);\n printHelp();\n process.exit(1);\n }\n }\n}\n\nrun().catch((error) => {\n console.error(error instanceof Error ? error.message : String(error));\n process.exit(1);\n});\n"],"mappings":"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"}
@@ -7,7 +7,7 @@ import { fileURLToPath } from "node:url";
7
7
  import path from "node:path";
8
8
  import fs from "node:fs";
9
9
  import os from "node:os";
10
- import { spawn, spawnSync } from "node:child_process";
10
+ import { spawnSync } from "node:child_process";
11
11
  import React from "react";
12
12
  import { Box, Text, render, useInput, useStdout } from "ink";
13
13
  import { TitledBox } from "@mishieck/ink-titled-box";
@@ -1508,8 +1508,6 @@ function writeConfigKey(key, value) {
1508
1508
  }
1509
1509
  async function tuiBoot({ assetsRoot, onFatalError } = {}) {
1510
1510
  const APP_ROOT = assetsRoot ?? path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
1511
- const DEFAULT_STARTUP_SOUND_FILE = path.join(APP_ROOT, "assets", "sounds", "hello_mf.mp3");
1512
- const DEFAULT_CONTEXT_SOUND_FILE = path.join(APP_ROOT, "assets", "sounds", "quack.mp3");
1513
1511
  const CONFIG_BOOTSTRAP_MODES = [
1514
1512
  {
1515
1513
  id: "prompt",
@@ -1547,15 +1545,10 @@ async function tuiBoot({ assetsRoot, onFatalError } = {}) {
1547
1545
  label: "Inspect messages"
1548
1546
  };
1549
1547
  const PERSISTED_CONFIG_FIELDS = [
1550
- "soundEnabled",
1551
- "startupSoundEnabled",
1552
- "contextSoundEnabled",
1553
1548
  "bootstrapMode",
1554
1549
  "resumeTerminal",
1555
1550
  "claudeIncludeSubagents",
1556
- "resumeOpenTab",
1557
- "startupGreetingFile",
1558
- "contextCreatedSoundFile"
1551
+ "resumeOpenTab"
1559
1552
  ];
1560
1553
  function normalizeApiKey(raw) {
1561
1554
  if (!raw) return "";
@@ -1576,9 +1569,6 @@ async function tuiBoot({ assetsRoot, onFatalError } = {}) {
1576
1569
  function normalizeBootstrapModeWithPrompt(raw) {
1577
1570
  return normalizeBootstrapMode(raw, { allowPrompt: true }) || "";
1578
1571
  }
1579
- function readEnv(...keys) {
1580
- for (const key of keys) if (process$1.env[key] !== void 0) return process$1.env[key];
1581
- }
1582
1572
  const cfg = {
1583
1573
  apiKey: normalizeApiKey(process$1.env.ULTRACONTEXT_API_KEY),
1584
1574
  baseUrl: (process$1.env.ULTRACONTEXT_BASE_URL ?? "https://api.ultracontext.ai").trim(),
@@ -1588,11 +1578,6 @@ async function tuiBoot({ assetsRoot, onFatalError } = {}) {
1588
1578
  resumeAutoRefreshMs: Math.max(toInt(process$1.env.RESUME_AUTO_REFRESH_MS, 3500), 0),
1589
1579
  uiRecentLimit: toInt(process$1.env.TUI_RECENT_LIMIT, 240),
1590
1580
  configFile: resolveRuntimeConfigPath(),
1591
- soundEnabled: boolFromEnv(readEnv("TUI_SOUND_ENABLED", "DAEMON_SOUND_ENABLED"), true),
1592
- startupSoundEnabled: boolFromEnv(readEnv("TUI_STARTUP_SOUND_ENABLED", "DAEMON_STARTUP_SOUND_ENABLED"), true),
1593
- contextSoundEnabled: boolFromEnv(readEnv("TUI_CONTEXT_SOUND_ENABLED", "DAEMON_CONTEXT_SOUND_ENABLED"), true),
1594
- startupGreetingFile: expandHome(readEnv("TUI_STARTUP_SOUND_FILE", "DAEMON_STARTUP_GREETING_FILE") ?? DEFAULT_STARTUP_SOUND_FILE),
1595
- contextCreatedSoundFile: expandHome(readEnv("TUI_CONTEXT_SOUND_FILE", "DAEMON_CONTEXT_SOUND_FILE") ?? DEFAULT_CONTEXT_SOUND_FILE),
1596
1581
  bootstrapMode: normalizeBootstrapModeWithPrompt(process$1.env.DAEMON_BOOTSTRAP_MODE ?? "prompt") || "prompt",
1597
1582
  bootstrapReset: boolFromEnv(process$1.env.DAEMON_BOOTSTRAP_RESET, false),
1598
1583
  claudeIncludeSubagents: boolFromEnv(process$1.env.CLAUDE_INCLUDE_SUBAGENTS, false),
@@ -1614,24 +1599,6 @@ async function tuiBoot({ assetsRoot, onFatalError } = {}) {
1614
1599
  contextsCreated: 0,
1615
1600
  errors: 0
1616
1601
  };
1617
- const CONFIG_TOGGLES = [
1618
- {
1619
- key: "soundEnabled",
1620
- label: "Master sounds",
1621
- description: "Enable or disable all app sounds"
1622
- },
1623
- {
1624
- key: "startupSoundEnabled",
1625
- label: "Startup sounds",
1626
- description: "Play sound when the TUI starts"
1627
- },
1628
- {
1629
- key: "contextSoundEnabled",
1630
- label: "Context sounds",
1631
- description: "Play duck sound when the TUI detects a new context"
1632
- }
1633
- ];
1634
- const UPDATE_CHECK_INTERVAL = 10800 * 1e3;
1635
1602
  function readTuiVersion() {
1636
1603
  try {
1637
1604
  const pkgPath = path.resolve(APP_ROOT, "package.json");
@@ -1640,21 +1607,6 @@ async function tuiBoot({ assetsRoot, onFatalError } = {}) {
1640
1607
  return "unknown";
1641
1608
  }
1642
1609
  }
1643
- function getUpdateCheckPath() {
1644
- return path.join(os.homedir(), ".ultracontext", "update-check.json");
1645
- }
1646
- function readUpdateCache() {
1647
- try {
1648
- return JSON.parse(fs.readFileSync(getUpdateCheckPath(), "utf8"));
1649
- } catch {
1650
- return null;
1651
- }
1652
- }
1653
- function writeUpdateCache(data) {
1654
- try {
1655
- fs.writeFileSync(getUpdateCheckPath(), JSON.stringify(data));
1656
- } catch {}
1657
- }
1658
1610
  async function fetchLatestVersion() {
1659
1611
  const controller = new AbortController();
1660
1612
  const timeout = setTimeout(() => controller.abort(), 3e3);
@@ -1685,16 +1637,7 @@ async function tuiBoot({ assetsRoot, onFatalError } = {}) {
1685
1637
  ui.updatePrompt.latestVersion = latest;
1686
1638
  renderDashboard();
1687
1639
  };
1688
- const cache = readUpdateCache();
1689
- if (cache?.lastCheck && Date.now() - cache.lastCheck < UPDATE_CHECK_INTERVAL) {
1690
- if (cache.latestVersion && isNewerVersion(cache.latestVersion, current)) notifyUpdate(cache.latestVersion);
1691
- return;
1692
- }
1693
1640
  const latest = await fetchLatestVersion();
1694
- writeUpdateCache({
1695
- lastCheck: Date.now(),
1696
- latestVersion: latest
1697
- });
1698
1641
  if (latest && isNewerVersion(latest, current)) notifyUpdate(latest);
1699
1642
  }
1700
1643
  const UPDATE_PROMPT_OPTIONS = [{
@@ -1769,11 +1712,6 @@ async function tuiBoot({ assetsRoot, onFatalError } = {}) {
1769
1712
  resumeKnownContextIds: /* @__PURE__ */ new Set(),
1770
1713
  resumeBaselineReady: false
1771
1714
  };
1772
- const sound = {
1773
- startupFile: "",
1774
- contextFile: "",
1775
- warnedNonDarwin: false
1776
- };
1777
1715
  function applyDaemonStatus(status) {
1778
1716
  if (!status) {
1779
1717
  ui.daemonOnline = false;
@@ -2211,7 +2149,6 @@ async function tuiBoot({ assetsRoot, onFatalError } = {}) {
2211
2149
  }
2212
2150
  runtime.resumeKnownContextIds = nextIds;
2213
2151
  if (!runtime.resumeBaselineReady) runtime.resumeBaselineReady = true;
2214
- if (newContextCount > 0) playContextCreatedSound();
2215
2152
  ui.resume.contexts = filtered;
2216
2153
  if (ui.resume.selectedIndex >= filtered.length) ui.resume.selectedIndex = Math.max(filtered.length - 1, 0);
2217
2154
  ui.resume.loadedAt = Date.now();
@@ -2452,15 +2389,10 @@ async function tuiBoot({ assetsRoot, onFatalError } = {}) {
2452
2389
  }
2453
2390
  function serializeConfigPrefs() {
2454
2391
  return {
2455
- soundEnabled: Boolean(cfg.soundEnabled),
2456
- startupSoundEnabled: Boolean(cfg.startupSoundEnabled),
2457
- contextSoundEnabled: Boolean(cfg.contextSoundEnabled),
2458
2392
  bootstrapMode: normalizeBootstrapModeWithPrompt(cfg.bootstrapMode) || "prompt",
2459
2393
  resumeTerminal: normalizeResumeTerminal(cfg.resumeTerminal),
2460
2394
  claudeIncludeSubagents: Boolean(cfg.claudeIncludeSubagents),
2461
- resumeOpenTab: Boolean(cfg.resumeOpenTab),
2462
- startupGreetingFile: String(cfg.startupGreetingFile ?? ""),
2463
- contextCreatedSoundFile: String(cfg.contextCreatedSoundFile ?? "")
2395
+ resumeOpenTab: Boolean(cfg.resumeOpenTab)
2464
2396
  };
2465
2397
  }
2466
2398
  async function persistConfigPrefsToFile(targetFile = cfg.configFile) {
@@ -2534,14 +2466,6 @@ async function tuiBoot({ assetsRoot, onFatalError } = {}) {
2534
2466
  cfg.resumeTerminal = normalizeResumeTerminal(prefs.resumeTerminal);
2535
2467
  continue;
2536
2468
  }
2537
- if (field === "startupGreetingFile") {
2538
- cfg.startupGreetingFile = expandHome(String(prefs.startupGreetingFile ?? cfg.startupGreetingFile));
2539
- continue;
2540
- }
2541
- if (field === "contextCreatedSoundFile") {
2542
- cfg.contextCreatedSoundFile = expandHome(String(prefs.contextCreatedSoundFile ?? cfg.contextCreatedSoundFile));
2543
- continue;
2544
- }
2545
2469
  cfg[field] = Boolean(prefs[field]);
2546
2470
  }
2547
2471
  }
@@ -2553,69 +2477,9 @@ async function tuiBoot({ assetsRoot, onFatalError } = {}) {
2553
2477
  } catch {}
2554
2478
  return { fileSaved };
2555
2479
  }
2556
- async function resolveSoundFile(filePath, label) {
2557
- if (!filePath) return "";
2558
- try {
2559
- if (!(await fs$1.stat(filePath)).isFile()) {
2560
- ui.resume.notice = `Configured sound is not a file: ${label}`;
2561
- return "";
2562
- }
2563
- return filePath;
2564
- } catch {
2565
- ui.resume.notice = `Configured sound file not found: ${label}`;
2566
- return "";
2567
- }
2568
- }
2569
- async function prepareSoundConfig() {
2570
- sound.startupFile = "";
2571
- sound.contextFile = "";
2572
- sound.warnedNonDarwin = false;
2573
- if (!cfg.soundEnabled) return;
2574
- sound.startupFile = await resolveSoundFile(cfg.startupGreetingFile, "startup");
2575
- sound.contextFile = await resolveSoundFile(cfg.contextCreatedSoundFile, "context_created");
2576
- }
2577
- function playSoundFile(filePath) {
2578
- if (!cfg.soundEnabled || !filePath) return;
2579
- if (process$1.platform !== "darwin") {
2580
- if (!sound.warnedNonDarwin) {
2581
- sound.warnedNonDarwin = true;
2582
- ui.resume.notice = "Sound notifications currently support only macOS (afplay).";
2583
- renderDashboard();
2584
- }
2585
- return;
2586
- }
2587
- try {
2588
- spawn("afplay", [filePath], {
2589
- detached: true,
2590
- stdio: "ignore"
2591
- }).unref();
2592
- } catch {}
2593
- }
2594
- function playStartupGreetingSound() {
2595
- if (!cfg.startupSoundEnabled) return;
2596
- playSoundFile(sound.startupFile);
2597
- }
2598
- function playContextCreatedSound() {
2599
- if (!cfg.contextSoundEnabled) return;
2600
- playSoundFile(sound.contextFile);
2601
- }
2602
2480
  function configToggleItems() {
2603
- const masterEnabled = Boolean(cfg.soundEnabled);
2604
- const soundItems = CONFIG_TOGGLES.map((item) => {
2605
- const rawValue = Boolean(cfg[item.key]);
2606
- const blockedByMaster = item.key !== "soundEnabled" && !masterEnabled;
2607
- const effectiveValue = blockedByMaster ? false : rawValue;
2608
- return {
2609
- ...item,
2610
- kind: "boolean",
2611
- rawValue,
2612
- value: effectiveValue,
2613
- valueLabel: effectiveValue ? "ON" : "OFF",
2614
- blockedByMaster
2615
- };
2616
- });
2617
2481
  const normalizedBootstrapMode = normalizeBootstrapModeWithPrompt(cfg.bootstrapMode) || "prompt";
2618
- const syncItems = [
2482
+ return [
2619
2483
  {
2620
2484
  key: "bootstrapMode",
2621
2485
  kind: "enum",
@@ -2644,7 +2508,6 @@ async function tuiBoot({ assetsRoot, onFatalError } = {}) {
2644
2508
  blockedByMaster: false
2645
2509
  }
2646
2510
  ];
2647
- return [...soundItems, ...syncItems];
2648
2511
  }
2649
2512
  function moveConfigSelection(delta) {
2650
2513
  const total = configToggleItems().length;
@@ -2690,16 +2553,7 @@ async function tuiBoot({ assetsRoot, onFatalError } = {}) {
2690
2553
  renderDashboard();
2691
2554
  return;
2692
2555
  }
2693
- if (item.kind === "boolean") {
2694
- cfg[item.key] = !cfg[item.key];
2695
- if (item.key === "soundEnabled" || item.key === "startupSoundEnabled" || item.key === "contextSoundEnabled") {
2696
- await prepareSoundConfig();
2697
- const saved = await persistConfigPrefs();
2698
- ui.resume.notice = `${item.label}: ${cfg[item.key] ? "ON" : "OFF"}${saved.fileSaved ? " (file saved)" : ""}.`;
2699
- renderDashboard();
2700
- return;
2701
- }
2702
- }
2556
+ if (item.kind === "boolean") cfg[item.key] = !cfg[item.key];
2703
2557
  } catch (error) {
2704
2558
  const details = errorDetails(error);
2705
2559
  ui.resume.notice = `Failed to apply config: ${details.message}`;
@@ -2832,12 +2686,7 @@ async function tuiBoot({ assetsRoot, onFatalError } = {}) {
2832
2686
  host: cfg.host,
2833
2687
  pollMs: 0,
2834
2688
  uiRefreshMs: cfg.uiRefreshMs,
2835
- logLevel: "info",
2836
- soundEnabled: cfg.soundEnabled,
2837
- startupSoundEnabled: cfg.startupSoundEnabled,
2838
- contextSoundEnabled: cfg.contextSoundEnabled,
2839
- startupGreetingFile: cfg.startupGreetingFile,
2840
- contextCreatedSoundFile: cfg.contextCreatedSoundFile
2689
+ logLevel: "info"
2841
2690
  },
2842
2691
  stats,
2843
2692
  selectedTab: ui.selectedTab,
@@ -2888,8 +2737,6 @@ async function tuiBoot({ assetsRoot, onFatalError } = {}) {
2888
2737
  try {
2889
2738
  if (!(await loadConfigPrefsFromFile()).loaded) await persistConfigPrefsToFile();
2890
2739
  } catch {}
2891
- await prepareSoundConfig();
2892
- playStartupGreetingSound();
2893
2740
  const uc = new UltraContext({
2894
2741
  apiKey: cfg.apiKey,
2895
2742
  baseUrl: cfg.baseUrl
@@ -3021,4 +2868,4 @@ async function tuiBoot({ assetsRoot, onFatalError } = {}) {
3021
2868
 
3022
2869
  //#endregion
3023
2870
  export { tuiBoot };
3024
- //# sourceMappingURL=tui-DTVj3nxD.mjs.map
2871
+ //# sourceMappingURL=tui-Dc0sp0j1.mjs.map