ultracontext 1.3.4 → 1.4.0

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.
@@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react";
2
2
  import { Box, Text } from "ink";
3
3
  import figlet from "figlet";
4
4
 
5
- //#region ../tui/src/ui/hero-art.mjs
5
+ //#region ../sync/src/ui/hero-art.mjs
6
6
  const HERO_TEXT = "UltraContext";
7
7
  const HERO_FONT_ORDER = [
8
8
  "Standard",
@@ -44,7 +44,7 @@ function heroArtForWidth(columns) {
44
44
  }
45
45
 
46
46
  //#endregion
47
- //#region ../tui/src/ui/constants.mjs
47
+ //#region ../sync/src/ui/constants.mjs
48
48
  const UC_BRAND_BLUE = "#2f6fb3";
49
49
  const UC_BLUE_LIGHT = "#7ec3ff";
50
50
  const UC_CLAUDE_ORANGE = "#f4a261";
@@ -66,7 +66,7 @@ const MENU_TABS = [
66
66
  ];
67
67
 
68
68
  //#endregion
69
- //#region ../tui/src/Spinner.mjs
69
+ //#region ../sync/src/Spinner.mjs
70
70
  const WIDTH = 28;
71
71
  const HEIGHT = 10;
72
72
  const SCALE = 40;
@@ -150,4 +150,4 @@ const Spinner = ({ color = "green", prefix = "", suffix = "", prefixColor = "whi
150
150
 
151
151
  //#endregion
152
152
  export { UC_CLAUDE_ORANGE as a, heroArtForWidth as c, UC_BRAND_BLUE as i, MENU_TABS as n, UC_CODEX_BLUE as o, UC_BLUE_LIGHT as r, UC_OPENCLAW_RED as s, Spinner as t };
153
- //# sourceMappingURL=Spinner-C_38udz8.mjs.map
153
+ //# sourceMappingURL=Spinner-CwBjkXHv.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Spinner-CwBjkXHv.mjs","names":[],"sources":["../../sync/src/ui/hero-art.mjs","../../sync/src/ui/constants.mjs","../../sync/src/Spinner.mjs"],"sourcesContent":["import figlet from \"figlet\";\n\nconst HERO_TEXT = \"UltraContext\";\nconst HERO_FONT_ORDER = [\"Standard\", \"Small\", \"Mini\", \"Slant\"];\nconst HERO_ART_CACHE = new Map();\n\nfunction trimBlankEdgeLines(lines) {\n let start = 0;\n let end = lines.length;\n while (start < end && !String(lines[start] ?? \"\").trim()) start += 1;\n while (end > start && !String(lines[end - 1] ?? \"\").trim()) end -= 1;\n return lines.slice(start, end);\n}\n\nconst HERO_FONT_ART = HERO_FONT_ORDER.map((font) => {\n try {\n const raw = figlet.textSync(HERO_TEXT, {\n font,\n horizontalLayout: \"default\",\n verticalLayout: \"default\",\n });\n const lines = trimBlankEdgeLines(\n raw\n .replace(/\\n+$/g, \"\")\n .split(\"\\n\")\n .map((line) => line.replace(/\\s+$/g, \"\"))\n );\n const width = Math.max(...lines.map((line) => line.length), 0);\n return { lines, width };\n } catch {\n return null;\n }\n}).filter(Boolean);\n\nexport function heroArtForWidth(columns) {\n const available = Math.max(columns ?? 8, 8);\n const cacheKey = String(available);\n if (HERO_ART_CACHE.has(cacheKey)) return HERO_ART_CACHE.get(cacheKey);\n\n const candidate = HERO_FONT_ART.find((entry) => entry.width <= available);\n const art = candidate\n ? candidate.lines.map((line) => line.padEnd(candidate.width, \" \"))\n : available >= 12\n ? [HERO_TEXT]\n : [\"UC\"];\n\n HERO_ART_CACHE.set(cacheKey, art);\n return art;\n}\n","export const UC_BRAND_BLUE = \"#2f6fb3\";\nexport const UC_BLUE_LIGHT = \"#7ec3ff\";\nexport const UC_CLAUDE_ORANGE = \"#f4a261\";\nexport const UC_CODEX_BLUE = \"#5fb2ff\";\nexport const UC_OPENCLAW_RED = \"#e76f51\";\n\nexport const MENU_TABS = [\n { id: \"logs\", label: \"Live View\" },\n { id: \"contexts\", label: \"Contexts\" },\n { id: \"configs\", label: \"Configs\" },\n];\n","import React, { useState, useEffect } from \"react\";\nimport { Box, Text } from \"ink\";\n\nconst WIDTH = 28;\nconst HEIGHT = 10;\nconst SCALE = 40.0;\nconst CAMERA_Z = 20.0;\nconst CHARS = \"··..,,--::;;==!!**##$$@@\";\n\nconst zBuffer = new Float32Array(WIDTH * HEIGHT);\nconst screenBuffer = new Uint8Array(WIDTH * HEIGHT);\n\nconst pointsData = [];\nfunction addPoint(x, y, z, type) {\n pointsData.push(x, y, z, type);\n}\n\nfunction addLine(x1, y1, z1, x2, y2, z2) {\n const density = 15;\n for (let i = 0; i <= density; i++) {\n const t = i / density;\n addPoint(\n x1 + (x2 - x1) * t,\n y1 + (y2 - y1) * t,\n z1 + (z2 - z1) * t,\n 0\n );\n }\n}\n\naddLine(-1.8, -1.2, 0, -1.8, 1.2, 0);\naddLine(-1.8, 1.2, 0, -1.0, 1.2, 0);\naddLine(-1.8, -1.2, 0, -1.0, -1.2, 0);\n\naddLine(1.8, -1.2, 0, 1.8, 1.2, 0);\naddLine(1.8, 1.2, 0, 1.0, 1.2, 0);\naddLine(1.8, -1.2, 0, 1.0, -1.2, 0);\n\naddPoint(0, 0, 0, 1);\n\nconst points = new Float32Array(pointsData);\nconst pointCount = points.length / 4;\n\nfunction renderFrame(angle) {\n zBuffer.fill(-Infinity);\n screenBuffer.fill(32);\n\n const cosA = Math.cos(angle);\n const sinA = Math.sin(angle);\n\n for (let i = 0; i < pointCount; i++) {\n const idx = i * 4;\n const px = points[idx];\n const py = points[idx + 1];\n const pz = points[idx + 2];\n const ptype = points[idx + 3];\n\n const xRot = px * cosA - pz * sinA;\n const yRot = py;\n const zRot = px * sinA + pz * cosA;\n\n const zFinal = zRot - CAMERA_Z;\n const ooz = -1.0 / zFinal;\n\n const screenX = Math.floor(WIDTH / 2 + xRot * ooz * SCALE * 2.0);\n const screenY = Math.floor(HEIGHT / 2 - yRot * ooz * SCALE);\n\n if (screenX >= 0 && screenX < WIDTH && screenY >= 0 && screenY < HEIGHT) {\n const bufIdx = screenX + screenY * WIDTH;\n if (ooz > zBuffer[bufIdx]) {\n zBuffer[bufIdx] = ooz;\n if (ptype === 1) {\n screenBuffer[bufIdx] = 79;\n } else {\n let charIdx = Math.floor((zRot + 2.0) * 4.5);\n if (charIdx < 0) charIdx = 0;\n if (charIdx >= CHARS.length) charIdx = CHARS.length - 1;\n screenBuffer[bufIdx] = CHARS.charCodeAt(charIdx);\n }\n }\n }\n }\n\n const lines = [];\n for (let y = 0; y < HEIGHT; y++) {\n let row = \"\";\n const offset = y * WIDTH;\n for (let x = 0; x < WIDTH; x++) {\n row += String.fromCharCode(screenBuffer[offset + x]);\n }\n lines.push(row);\n }\n return lines;\n}\n\nconst Spinner = ({\n color = \"green\",\n prefix = \"\",\n suffix = \"\",\n prefixColor = \"white\",\n suffixColor = \"white\",\n sideLines = [],\n sideGap = 0,\n sideColor = \"white\",\n}) => {\n const [frameRows, setFrameRows] = useState(() => renderFrame(0));\n\n useEffect(() => {\n let angle = 0;\n const timer = setInterval(() => {\n angle += 0.05;\n setFrameRows(renderFrame(angle));\n }, 33);\n timer.unref?.();\n return () => clearInterval(timer);\n }, []);\n\n return React.createElement(\n Box,\n { flexDirection: \"column\" },\n ...frameRows.map((row, index) =>\n React.createElement(\n Text,\n { key: `spinner-row-${index}` },\n prefix ? React.createElement(Text, { color: prefixColor }, prefix) : \"\",\n React.createElement(Text, { color }, row),\n sideLines.length > 0\n ? React.createElement(Text, { color: sideColor }, `${\" \".repeat(Math.max(sideGap, 0))}${sideLines[index] ?? \"\"}`)\n : \"\",\n suffix ? React.createElement(Text, { color: suffixColor }, suffix) : \"\"\n )\n )\n );\n};\n\nexport default Spinner;\n"],"mappings":";;;;;AAEA,MAAM,YAAY;AAClB,MAAM,kBAAkB;CAAC;CAAY;CAAS;CAAQ;CAAQ;AAC9D,MAAM,iCAAiB,IAAI,KAAK;AAEhC,SAAS,mBAAmB,OAAO;CACjC,IAAI,QAAQ;CACZ,IAAI,MAAM,MAAM;AAChB,QAAO,QAAQ,OAAO,CAAC,OAAO,MAAM,UAAU,GAAG,CAAC,MAAM,CAAE,UAAS;AACnE,QAAO,MAAM,SAAS,CAAC,OAAO,MAAM,MAAM,MAAM,GAAG,CAAC,MAAM,CAAE,QAAO;AACnE,QAAO,MAAM,MAAM,OAAO,IAAI;;AAGhC,MAAM,gBAAgB,gBAAgB,KAAK,SAAS;AAClD,KAAI;EAMF,MAAM,QAAQ,mBALF,OAAO,SAAS,WAAW;GACrC;GACA,kBAAkB;GAClB,gBAAgB;GACjB,CAAC,CAGG,QAAQ,SAAS,GAAG,CACpB,MAAM,KAAK,CACX,KAAK,SAAS,KAAK,QAAQ,SAAS,GAAG,CAAC,CAC5C;AAED,SAAO;GAAE;GAAO,OADF,KAAK,IAAI,GAAG,MAAM,KAAK,SAAS,KAAK,OAAO,EAAE,EAAE;GACvC;SACjB;AACN,SAAO;;EAET,CAAC,OAAO,QAAQ;AAElB,SAAgB,gBAAgB,SAAS;CACvC,MAAM,YAAY,KAAK,IAAI,WAAW,GAAG,EAAE;CAC3C,MAAM,WAAW,OAAO,UAAU;AAClC,KAAI,eAAe,IAAI,SAAS,CAAE,QAAO,eAAe,IAAI,SAAS;CAErE,MAAM,YAAY,cAAc,MAAM,UAAU,MAAM,SAAS,UAAU;CACzE,MAAM,MAAM,YACR,UAAU,MAAM,KAAK,SAAS,KAAK,OAAO,UAAU,OAAO,IAAI,CAAC,GAChE,aAAa,KACX,CAAC,UAAU,GACX,CAAC,KAAK;AAEZ,gBAAe,IAAI,UAAU,IAAI;AACjC,QAAO;;;;;AC/CT,MAAa,gBAAgB;AAC7B,MAAa,gBAAgB;AAC7B,MAAa,mBAAmB;AAChC,MAAa,gBAAgB;AAC7B,MAAa,kBAAkB;AAE/B,MAAa,YAAY;CACvB;EAAE,IAAI;EAAQ,OAAO;EAAa;CAClC;EAAE,IAAI;EAAY,OAAO;EAAY;CACrC;EAAE,IAAI;EAAW,OAAO;EAAW;CACpC;;;;ACPD,MAAM,QAAQ;AACd,MAAM,SAAS;AACf,MAAM,QAAQ;AACd,MAAM,WAAW;AACjB,MAAM,QAAQ;AAEd,MAAM,UAAU,IAAI,aAAa,QAAQ,OAAO;AAChD,MAAM,eAAe,IAAI,WAAW,QAAQ,OAAO;AAEnD,MAAM,aAAa,EAAE;AACrB,SAAS,SAAS,GAAG,GAAG,GAAG,MAAM;AAC/B,YAAW,KAAK,GAAG,GAAG,GAAG,KAAK;;AAGhC,SAAS,QAAQ,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;CACvC,MAAM,UAAU;AAChB,MAAK,IAAI,IAAI,GAAG,KAAK,SAAS,KAAK;EACjC,MAAM,IAAI,IAAI;AACd,WACE,MAAM,KAAK,MAAM,GACjB,MAAM,KAAK,MAAM,GACjB,MAAM,KAAK,MAAM,GACjB,EACD;;;AAIL,QAAQ,MAAM,MAAM,GAAG,MAAM,KAAK,EAAE;AACpC,QAAQ,MAAM,KAAK,GAAG,IAAM,KAAK,EAAE;AACnC,QAAQ,MAAM,MAAM,GAAG,IAAM,MAAM,EAAE;AAErC,QAAQ,KAAK,MAAM,GAAG,KAAK,KAAK,EAAE;AAClC,QAAQ,KAAK,KAAK,GAAG,GAAK,KAAK,EAAE;AACjC,QAAQ,KAAK,MAAM,GAAG,GAAK,MAAM,EAAE;AAEnC,SAAS,GAAG,GAAG,GAAG,EAAE;AAEpB,MAAM,SAAS,IAAI,aAAa,WAAW;AAC3C,MAAM,aAAa,OAAO,SAAS;AAEnC,SAAS,YAAY,OAAO;AAC1B,SAAQ,KAAK,UAAU;AACvB,cAAa,KAAK,GAAG;CAErB,MAAM,OAAO,KAAK,IAAI,MAAM;CAC5B,MAAM,OAAO,KAAK,IAAI,MAAM;AAE5B,MAAK,IAAI,IAAI,GAAG,IAAI,YAAY,KAAK;EACnC,MAAM,MAAM,IAAI;EAChB,MAAM,KAAK,OAAO;EAClB,MAAM,KAAK,OAAO,MAAM;EACxB,MAAM,KAAK,OAAO,MAAM;EACxB,MAAM,QAAQ,OAAO,MAAM;EAE3B,MAAM,OAAO,KAAK,OAAO,KAAK;EAC9B,MAAM,OAAO;EACb,MAAM,OAAO,KAAK,OAAO,KAAK;EAG9B,MAAM,MAAM,MADG,OAAO;EAGtB,MAAM,UAAU,KAAK,MAAM,QAAQ,IAAI,OAAO,MAAM,QAAQ,EAAI;EAChE,MAAM,UAAU,KAAK,MAAM,SAAS,IAAI,OAAO,MAAM,MAAM;AAE3D,MAAI,WAAW,KAAK,UAAU,SAAS,WAAW,KAAK,UAAU,QAAQ;GACvE,MAAM,SAAS,UAAU,UAAU;AACnC,OAAI,MAAM,QAAQ,SAAS;AACzB,YAAQ,UAAU;AAClB,QAAI,UAAU,EACZ,cAAa,UAAU;SAClB;KACL,IAAI,UAAU,KAAK,OAAO,OAAO,KAAO,IAAI;AAC5C,SAAI,UAAU,EAAG,WAAU;AAC3B,SAAI,WAAW,GAAc,WAAU;AACvC,kBAAa,UAAU,MAAM,WAAW,QAAQ;;;;;CAMxD,MAAM,QAAQ,EAAE;AAChB,MAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,KAAK;EAC/B,IAAI,MAAM;EACV,MAAM,SAAS,IAAI;AACnB,OAAK,IAAI,IAAI,GAAG,IAAI,OAAO,IACzB,QAAO,OAAO,aAAa,aAAa,SAAS,GAAG;AAEtD,QAAM,KAAK,IAAI;;AAEjB,QAAO;;AAGT,MAAM,WAAW,EACf,QAAQ,SACR,SAAS,IACT,SAAS,IACT,cAAc,SACd,cAAc,SACd,YAAY,EAAE,EACd,UAAU,GACV,YAAY,cACR;CACJ,MAAM,CAAC,WAAW,gBAAgB,eAAe,YAAY,EAAE,CAAC;AAEhE,iBAAgB;EACd,IAAI,QAAQ;EACZ,MAAM,QAAQ,kBAAkB;AAC9B,YAAS;AACT,gBAAa,YAAY,MAAM,CAAC;KAC/B,GAAG;AACN,QAAM,SAAS;AACf,eAAa,cAAc,MAAM;IAChC,EAAE,CAAC;AAEN,QAAO,MAAM,cACX,KACA,EAAE,eAAe,UAAU,EAC3B,GAAG,UAAU,KAAK,KAAK,UACrB,MAAM,cACJ,MACA,EAAE,KAAK,eAAe,SAAS,EAC/B,SAAS,MAAM,cAAc,MAAM,EAAE,OAAO,aAAa,EAAE,OAAO,GAAG,IACrE,MAAM,cAAc,MAAM,EAAE,OAAO,EAAE,IAAI,EACzC,UAAU,SAAS,IACf,MAAM,cAAc,MAAM,EAAE,OAAO,WAAW,EAAE,GAAG,IAAI,OAAO,KAAK,IAAI,SAAS,EAAE,CAAC,GAAG,UAAU,UAAU,KAAK,GAC/G,IACJ,SAAS,MAAM,cAAc,MAAM,EAAE,OAAO,aAAa,EAAE,OAAO,GAAG,GACtE,CACF,CACF"}
@@ -27,12 +27,10 @@ function printHelp() {
27
27
  Usage: ultracontext [command] [options]
28
28
 
29
29
  Commands:
30
- (none) Start daemon if needed, then open TUI
30
+ (none) Start sync (daemon + TUI)
31
+ sync Start sync (daemon + TUI)
32
+ stop Stop a running sync daemon
31
33
  config Run the setup wizard
32
- start Start the daemon in the background
33
- stop Stop a running daemon
34
- status Show daemon status
35
- tui Launch the interactive terminal UI
36
34
  update Update CLI globally via npm/pnpm/bun
37
35
  version Print version
38
36
  help Show this help message
@@ -52,11 +50,7 @@ Options:
52
50
  -h, --help Show this help message
53
51
  `);
54
52
  }
55
- const NEEDS_KEY = new Set([
56
- "",
57
- "start",
58
- "tui"
59
- ]);
53
+ const NEEDS_KEY = new Set(["", "sync"]);
60
54
  async function runOnboarding() {
61
55
  const { onboard } = await import("./onboarding.mjs");
62
56
  return onboard();
@@ -243,9 +237,9 @@ function runUpdate(rawArgs) {
243
237
  console.log(` ${green}✓${r} ${b}Updated${r} ${gray}${previousVersion} → ${newVersion}${r}`);
244
238
  if (wasRunning && opts.restart) {
245
239
  console.log(` ${green}●${r} ${d}Restarting daemon...${r}`);
246
- const startCode = runCliSubcommand("start");
240
+ const startCode = runCliSubcommand("sync");
247
241
  if (startCode !== 0) throw new Error(`Update succeeded but daemon restart failed (exit ${startCode}).`);
248
- } else if (wasRunning) console.log(` ${gray}○${r} ${d}Daemon was stopped. Run:${r} ${cyan}ultracontext start${r}`);
242
+ } else if (wasRunning) console.log(` ${gray}○${r} ${d}Daemon was stopped. Run:${r} ${cyan}ultracontext sync${r}`);
249
243
  console.log("");
250
244
  }
251
245
  const SKIP_UPDATE_CHECK = new Set([
@@ -255,8 +249,7 @@ const SKIP_UPDATE_CHECK = new Set([
255
249
  "upgrade",
256
250
  "help",
257
251
  "h",
258
- "stop",
259
- "status"
252
+ "stop"
260
253
  ]);
261
254
  async function fetchLatestVersion() {
262
255
  const controller = new AbortController();
@@ -289,23 +282,20 @@ async function checkForUpdate() {
289
282
  const latest = await fetchLatestVersion();
290
283
  if (latest && isNewer(latest, current)) printUpdateNotice(current, latest);
291
284
  }
292
- async function launchDaemonSDK() {
293
- const { launchDaemon } = await import("../launcher-BFPi7_wD.mjs");
285
+ async function launchSyncDaemon() {
286
+ const { launchDaemon } = await import("../launcher-C_GUIW-o.mjs");
294
287
  await launchDaemon({
295
- entryPath: fileURLToPath(new URL("./sdk-daemon.mjs", import.meta.url)),
296
- diagnosticsHint: "DAEMON_VERBOSE=1 ultracontext start"
288
+ entryPath: fileURLToPath(new URL("./sdk-sync.mjs", import.meta.url)),
289
+ diagnosticsHint: "DAEMON_VERBOSE=1 ultracontext sync"
297
290
  });
298
291
  }
299
292
  async function runCtlSDK() {
300
- const { runCtl } = await import("../ctl-BVPu-D57.mjs");
293
+ const { runCtl } = await import("../ctl-iHUR6By1.mjs");
301
294
  await runCtl();
302
295
  }
303
- async function launchTuiSDK() {
304
- const { tuiBoot } = await import("../tui-C3H6iRjz.mjs");
305
- await tuiBoot({
306
- assetsRoot: path.resolve(__dirname, "..", ".."),
307
- offlineNotice: "Daemon offline. Run: ultracontext start"
308
- });
296
+ async function launchTui() {
297
+ const { tuiBoot } = await import("../tui-Df8--qZj.mjs");
298
+ await tuiBoot({ assetsRoot: path.resolve(__dirname, "..", "..") });
309
299
  }
310
300
  async function run() {
311
301
  if (!SKIP_UPDATE_CHECK.has(command)) await checkForUpdate();
@@ -315,27 +305,21 @@ async function run() {
315
305
  if (!process.env.ULTRACONTEXT_API_KEY) onboardResult = await runOnboarding();
316
306
  }
317
307
  switch (command) {
318
- case "start":
319
- await launchDaemonSDK();
320
- if (onboardResult?.launchTui) await launchTuiSDK();
308
+ case "sync":
309
+ case "":
310
+ if (!isDaemonRunning()) await launchSyncDaemon();
311
+ if (onboardResult?.launchTui !== false) await launchTui();
321
312
  break;
322
313
  case "stop":
323
314
  process.argv[2] = "stop";
324
315
  await runCtlSDK();
325
316
  break;
326
- case "status":
327
- process.argv[2] = "status";
328
- await runCtlSDK();
329
- break;
330
317
  case "config":
331
318
  if ((await runOnboarding())?.launchTui) {
332
- if (!isDaemonRunning()) await launchDaemonSDK();
333
- await launchTuiSDK();
319
+ if (!isDaemonRunning()) await launchSyncDaemon();
320
+ await launchTui();
334
321
  }
335
322
  break;
336
- case "tui":
337
- await launchTuiSDK();
338
- break;
339
323
  case "version":
340
324
  case "v":
341
325
  console.log(readVersion());
@@ -344,18 +328,24 @@ async function run() {
344
328
  case "upgrade":
345
329
  runUpdate(process.argv.slice(3));
346
330
  break;
347
- case "":
348
- if (!isDaemonRunning()) await launchDaemonSDK();
349
- await launchTuiSDK();
350
- break;
351
331
  case "help":
352
332
  case "h":
353
333
  printHelp();
354
334
  break;
355
- default:
335
+ default: {
336
+ const hint = {
337
+ start: "The 'start' command was removed. Use 'ultracontext sync' instead.",
338
+ tui: "The 'tui' command was removed. Use 'ultracontext sync' instead (TUI is now built-in).",
339
+ status: "The 'status' command was removed. The TUI shows daemon status automatically."
340
+ }[command];
341
+ if (hint) {
342
+ console.log(hint);
343
+ process.exit(0);
344
+ }
356
345
  console.error(`Unknown command: ${process.argv[2]}`);
357
346
  printHelp();
358
347
  process.exit(1);
348
+ }
359
349
  }
360
350
  }
361
351
  run().catch((error) => {
@@ -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 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 daemon if needed, then open TUI\n config Run the setup wizard\n start Start the daemon in the background\n stop Stop a running daemon\n status Show daemon status\n tui Launch the interactive terminal UI\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([\"\", \"start\", \"tui\"]);\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 start${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\", \"status\"]);\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 launchDaemonSDK() {\n const { launchDaemon } = await import(\"@ultracontext/daemon/launcher\");\n await launchDaemon({\n entryPath: fileURLToPath(new URL(\"./sdk-daemon.mjs\", import.meta.url)),\n diagnosticsHint: \"DAEMON_VERBOSE=1 ultracontext start\",\n });\n}\n\nasync function runCtlSDK() {\n const { runCtl } = await import(\"@ultracontext/daemon/ctl\");\n await runCtl();\n}\n\nasync function launchTuiSDK() {\n const { tuiBoot } = await import(\"@ultracontext/tui/tui\");\n await tuiBoot({\n assetsRoot: path.resolve(__dirname, \"..\", \"..\"),\n offlineNotice: \"Daemon offline. Run: ultracontext start\",\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 case \"start\":\n await launchDaemonSDK();\n if (onboardResult?.launchTui) await launchTuiSDK();\n break;\n\n case \"stop\":\n process.argv[2] = \"stop\";\n await runCtlSDK();\n break;\n\n case \"status\":\n process.argv[2] = \"status\";\n await runCtlSDK();\n break;\n\n case \"config\": {\n const configResult = await runOnboarding();\n if (configResult?.launchTui) {\n if (!isDaemonRunning()) await launchDaemonSDK();\n await launchTuiSDK();\n }\n break;\n }\n\n case \"tui\":\n await launchTuiSDK();\n break;\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 // default: ensure daemon running, then open TUI\n case \"\": {\n if (!isDaemonRunning()) await launchDaemonSDK();\n await launchTuiSDK();\n break;\n }\n\n case \"help\":\n case \"h\":\n printHelp();\n break;\n\n default:\n console.error(`Unknown command: ${process.argv[2]}`);\n printHelp();\n process.exit(1);\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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"}
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 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 stop Stop a running sync daemon\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(\"sync\");\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\"]);\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: ensure daemon running, then open TUI\n case \"sync\":\n case \"\": {\n if (!isDaemonRunning()) await launchSyncDaemon();\n if (onboardResult?.launchTui !== false) await launchTui();\n break;\n }\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 const removed = {\n start: \"The 'start' command was removed. Use 'ultracontext sync' instead.\",\n tui: \"The 'tui' command was removed. Use 'ultracontext sync' instead (TUI is now built-in).\",\n status: \"The 'status' command was removed. The TUI shows daemon status automatically.\",\n };\n const hint = removed[command];\n if (hint) {\n console.log(hint);\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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"}
@@ -1,4 +1,4 @@
1
- import { c as heroArtForWidth, i as UC_BRAND_BLUE, r as UC_BLUE_LIGHT, t as Spinner } from "../Spinner-C_38udz8.mjs";
1
+ import { c as heroArtForWidth, i as UC_BRAND_BLUE, r as UC_BLUE_LIGHT, t as Spinner } from "../Spinner-CwBjkXHv.mjs";
2
2
  import process from "node:process";
3
3
  import path from "node:path";
4
4
  import fs from "node:fs";
@@ -1 +1 @@
1
- {"version":3,"file":"onboarding.mjs","names":[],"sources":["../../src/cli/onboarding.mjs"],"sourcesContent":["// Interactive onboarding wizard — guides new users through setup\nimport React from \"react\";\nimport { render, Box, Text, useInput, useStdout } from \"ink\";\nimport { TitledBox } from \"@mishieck/ink-titled-box\";\nimport { spawn } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport process from \"node:process\";\n\nimport { heroArtForWidth } from \"@ultracontext/tui/ui/hero-art\";\nimport { UC_BRAND_BLUE, UC_BLUE_LIGHT } from \"@ultracontext/tui/ui/constants\";\nimport Spinner from \"@ultracontext/tui/Spinner\";\n\n// ── config helpers ──────────────────────────────────────────────\n\nconst CONFIG_DIR = path.join(process.env.HOME || process.env.USERPROFILE || \"~\", \".ultracontext\");\nconst CONFIG_PATH = path.join(CONFIG_DIR, \"config.json\");\n\nfunction readConfig() {\n try {\n return JSON.parse(fs.readFileSync(CONFIG_PATH, \"utf8\"));\n } catch {\n return {};\n }\n}\n\nfunction writeConfig(patch) {\n const existing = readConfig();\n fs.mkdirSync(CONFIG_DIR, { recursive: true });\n fs.writeFileSync(CONFIG_PATH, JSON.stringify({ ...existing, ...patch }, null, 2) + \"\\n\", \"utf8\");\n}\n\n// ── open URL (cross-platform) ───────────────────────────────────\n\nfunction openUrl(url) {\n const cmd = process.platform === \"darwin\" ? \"open\" : \"xdg-open\";\n try {\n const child = spawn(cmd, [url], { detached: true, stdio: \"ignore\" });\n child.unref();\n } catch { /* best effort */ }\n}\n\n// ── validation ──────────────────────────────────────────────────\n\nfunction isValidKey(key) {\n return /^uc_(live|test)_/.test(key);\n}\n\n// ── step constants ──────────────────────────────────────────────\n\nconst STEPS = [\"welcome\", \"mode\", \"url\", \"key\", \"bootstrap\", \"launch\", \"done\"];\n\nconst MODE_OPTIONS = [\n { label: \"Login (ultracontext.ai)\", value: \"cloud\" },\n { label: \"Self-host\", value: \"selfhost\" },\n];\n\nconst BOOTSTRAP_OPTIONS = [\n { label: \"New only (recommended)\", value: \"new_only\" },\n { label: \"Last 24h\", value: \"last_24h\" },\n { label: \"All\", value: \"all\" },\n];\n\nconst LAUNCH_OPTIONS = [\n { label: \"Yes, open the TUI (recommended)\", value: true },\n { label: \"No, just finish setup\", value: false },\n];\n\n// ── step number display ─────────────────────────────────────────\n\nfunction stepNumber(step) {\n if (step === \"welcome\") return 1;\n if (step === \"mode\") return 2;\n if (step === \"url\" || step === \"key\") return 3;\n if (step === \"bootstrap\") return 4;\n if (step === \"launch\") return 5;\n return 5;\n}\n\nconst TOTAL_STEPS = 5;\n\n// ── Onboarding component ────────────────────────────────────────\n\nfunction Onboarding({ onDone }) {\n const { stdout } = useStdout();\n const cols = stdout?.columns ?? process.stdout.columns ?? 80;\n\n const [step, setStep] = React.useState(\"welcome\");\n const [hosting, setHosting] = React.useState(\"cloud\");\n const [baseUrl, setBaseUrl] = React.useState(\"https://api.ultracontext.ai\");\n const [apiKey, setApiKey] = React.useState(\"\");\n const [bootstrapMode, setBootstrapMode] = React.useState(\"new_only\");\n const [selectedIndex, setSelectedIndex] = React.useState(0);\n const [keyInput, setKeyInput] = React.useState(\"\");\n const [urlInput, setUrlInput] = React.useState(\"https://\");\n const [error, setError] = React.useState(\"\");\n const [launchTui, setLaunchTui] = React.useState(false);\n\n // save config + env, advance to launch step\n const finish = React.useCallback((finalKey, finalUrl, finalBootstrap) => {\n writeConfig({ apiKey: finalKey, baseUrl: finalUrl, bootstrapMode: finalBootstrap });\n process.env.ULTRACONTEXT_API_KEY = finalKey;\n process.env.ULTRACONTEXT_BASE_URL = finalUrl;\n setStep(\"launch\");\n setSelectedIndex(0);\n }, []);\n\n useInput((input, key) => {\n // escape or ctrl+c exits at any step\n if (key.escape || (input === \"c\" && key.ctrl)) {\n process.exit(0);\n }\n\n // ── welcome ──\n if (step === \"welcome\") {\n if (key.return) {\n setStep(\"mode\");\n setSelectedIndex(0);\n }\n return;\n }\n\n // ── mode selection ──\n if (step === \"mode\") {\n if (key.upArrow) setSelectedIndex((i) => Math.max(i - 1, 0));\n if (key.downArrow) setSelectedIndex((i) => Math.min(i + 1, MODE_OPTIONS.length - 1));\n if (input === \"1\") setSelectedIndex(0);\n if (input === \"2\") setSelectedIndex(1);\n\n if (key.return || input === \" \") {\n const chosen = MODE_OPTIONS[selectedIndex].value;\n setHosting(chosen);\n if (chosen === \"selfhost\") {\n setStep(\"url\");\n setUrlInput(\"https://\");\n setError(\"\");\n } else {\n setBaseUrl(\"https://api.ultracontext.ai\");\n openUrl(\"https://ultracontext.ai\");\n setStep(\"key\");\n setKeyInput(\"\");\n setError(\"\");\n }\n setSelectedIndex(0);\n }\n return;\n }\n\n // ── url input (self-host) ──\n if (step === \"url\") {\n if (key.return) {\n const trimmed = urlInput.trim();\n if (!trimmed || trimmed === \"https://\") {\n setError(\"Enter a valid base URL\");\n return;\n }\n setBaseUrl(trimmed);\n setStep(\"key\");\n setKeyInput(\"\");\n setError(\"\");\n return;\n }\n if (key.backspace || key.delete) {\n setUrlInput((v) => v.slice(0, -1));\n setError(\"\");\n return;\n }\n if (input && !key.ctrl && !key.meta) {\n setUrlInput((v) => v + input);\n setError(\"\");\n }\n return;\n }\n\n // ── key input ──\n if (step === \"key\") {\n if (key.return) {\n const trimmed = keyInput.trim();\n if (!trimmed) {\n setError(\"Enter your API key\");\n return;\n }\n if (!isValidKey(trimmed)) {\n setError(\"Key must start with uc_live_ or uc_test_\");\n return;\n }\n setApiKey(trimmed);\n setStep(\"bootstrap\");\n setSelectedIndex(0);\n setError(\"\");\n return;\n }\n if (key.backspace || key.delete) {\n setKeyInput((v) => v.slice(0, -1));\n setError(\"\");\n return;\n }\n if (input && !key.ctrl && !key.meta) {\n setKeyInput((v) => v + input);\n setError(\"\");\n }\n return;\n }\n\n // ── bootstrap mode ──\n if (step === \"bootstrap\") {\n if (key.upArrow) setSelectedIndex((i) => Math.max(i - 1, 0));\n if (key.downArrow) setSelectedIndex((i) => Math.min(i + 1, BOOTSTRAP_OPTIONS.length - 1));\n if (input === \"1\") setSelectedIndex(0);\n if (input === \"2\") setSelectedIndex(1);\n if (input === \"3\") setSelectedIndex(2);\n\n if (key.return || input === \" \") {\n const chosen = BOOTSTRAP_OPTIONS[selectedIndex].value;\n setBootstrapMode(chosen);\n finish(apiKey, baseUrl, chosen);\n }\n return;\n }\n\n // ── launch TUI? ──\n if (step === \"launch\") {\n if (key.upArrow) setSelectedIndex((i) => Math.max(i - 1, 0));\n if (key.downArrow) setSelectedIndex((i) => Math.min(i + 1, LAUNCH_OPTIONS.length - 1));\n if (input === \"1\") setSelectedIndex(0);\n if (input === \"2\") setSelectedIndex(1);\n\n if (key.return || input === \" \") {\n const chosen = LAUNCH_OPTIONS[selectedIndex].value;\n setLaunchTui(chosen);\n setStep(\"done\");\n setTimeout(() => onDone(chosen), 80);\n }\n return;\n }\n });\n\n // ── render ──\n\n const heroLines = heroArtForWidth(cols - 4);\n const stepNum = stepNumber(step);\n\n // hero art — 3d spinner + figlet on all steps\n const hero = React.createElement(\n Box,\n { flexDirection: \"row\", justifyContent: \"center\", width: \"100%\" },\n React.createElement(Spinner, { color: UC_BLUE_LIGHT }),\n React.createElement(Box, { width: 3 }),\n React.createElement(\n Box,\n { flexDirection: \"column\", justifyContent: \"center\" },\n ...heroLines.map((line, i) =>\n React.createElement(Text, { key: `h${i}`, color: \"white\", bold: true }, line)\n )\n )\n );\n\n // step content\n let content = null;\n\n if (step === \"welcome\") {\n content = React.createElement(\n Box,\n { flexDirection: \"column\" },\n React.createElement(Text, { color: \"white\", bold: true }, \"Welcome to UltraContext\"),\n React.createElement(Text, { color: \"gray\" }, \"Context engineering for AI coding agents.\"),\n React.createElement(Box, { height: 1 }),\n React.createElement(Text, { color: UC_BLUE_LIGHT }, \"Press Enter to begin setup...\")\n );\n }\n\n if (step === \"mode\") {\n content = React.createElement(\n Box,\n { flexDirection: \"column\" },\n React.createElement(Text, { color: \"white\", bold: true }, \"How do you want to connect?\"),\n React.createElement(Box, { height: 1 }),\n ...MODE_OPTIONS.map((opt, i) => {\n const sel = i === selectedIndex;\n return React.createElement(\n Text,\n { key: `m${i}`, color: sel ? UC_BLUE_LIGHT : \"white\" },\n sel ? \"[\\u2022]\" : \"[ ]\",\n ` ${i + 1}. ${opt.label}`\n );\n }),\n React.createElement(Box, { height: 1 }),\n React.createElement(Text, { color: \"gray\" }, \"Navigate: up/down, 1/2 | Confirm: Enter\")\n );\n }\n\n if (step === \"url\") {\n content = React.createElement(\n Box,\n { flexDirection: \"column\" },\n React.createElement(Text, { color: \"white\", bold: true }, \"Enter your API base URL:\"),\n React.createElement(Box, { height: 1 }),\n React.createElement(Text, { color: UC_BLUE_LIGHT }, `> ${urlInput}_`),\n error ? React.createElement(Text, { color: \"red\" }, error) : null,\n React.createElement(Box, { height: 1 }),\n React.createElement(Text, { color: \"gray\" }, \"Enter to confirm | Esc to quit\")\n );\n }\n\n if (step === \"key\") {\n const keyPrompt = hosting === \"cloud\"\n ? \"Paste your API key (browser opened for you):\"\n : \"Enter your API key:\";\n\n content = React.createElement(\n Box,\n { flexDirection: \"column\" },\n React.createElement(Text, { color: \"white\", bold: true }, keyPrompt),\n React.createElement(Box, { height: 1 }),\n React.createElement(Text, { color: UC_BLUE_LIGHT }, `> ${keyInput}_`),\n error ? React.createElement(Text, { color: \"red\" }, error) : null,\n React.createElement(Box, { height: 1 }),\n React.createElement(Text, { color: \"gray\" }, \"Format: uc_live_... or uc_test_... | Enter to confirm\")\n );\n }\n\n if (step === \"bootstrap\") {\n content = React.createElement(\n Box,\n { flexDirection: \"column\" },\n React.createElement(Text, { color: \"white\", bold: true }, \"Initial sync mode:\"),\n React.createElement(Box, { height: 1 }),\n ...BOOTSTRAP_OPTIONS.map((opt, i) => {\n const sel = i === selectedIndex;\n return React.createElement(\n Text,\n { key: `b${i}`, color: sel ? UC_BLUE_LIGHT : \"white\" },\n sel ? \"[\\u2022]\" : \"[ ]\",\n ` ${i + 1}. ${opt.label}`\n );\n }),\n React.createElement(Box, { height: 1 }),\n React.createElement(Text, { color: \"gray\" }, \"Navigate: up/down, 1/2/3 | Confirm: Enter\")\n );\n }\n\n if (step === \"launch\") {\n content = React.createElement(\n Box,\n { flexDirection: \"column\" },\n React.createElement(Text, { color: \"white\", bold: true }, \"Launch the TUI dashboard?\"),\n React.createElement(Box, { height: 1 }),\n ...LAUNCH_OPTIONS.map((opt, i) => {\n const sel = i === selectedIndex;\n return React.createElement(\n Text,\n { key: `l${i}`, color: sel ? UC_BLUE_LIGHT : \"white\" },\n sel ? \"[\\u2022]\" : \"[ ]\",\n ` ${i + 1}. ${opt.label}`\n );\n }),\n React.createElement(Box, { height: 1 }),\n React.createElement(Text, { color: \"gray\" }, \"Navigate: up/down, 1/2 | Confirm: Enter\")\n );\n }\n\n if (step === \"done\") {\n content = React.createElement(\n Box,\n { flexDirection: \"column\" },\n React.createElement(Text, { color: \"green\", bold: true }, \"Setup complete!\"),\n React.createElement(Text, { color: \"gray\" }, `Config saved to ${CONFIG_PATH}`)\n );\n }\n\n const boxWidth = Math.min(cols - 2, 60);\n\n return React.createElement(\n Box,\n { flexDirection: \"column\", alignItems: \"center\", paddingX: 1, paddingY: 1, width: cols },\n hero,\n React.createElement(Text, { color: UC_BLUE_LIGHT, bold: true }, \"[ The Context Hub for AI Agents ]\"),\n React.createElement(Box, { height: 1 }),\n React.createElement(\n TitledBox,\n {\n borderStyle: \"single\",\n titles: [\"Setup\"],\n titleJustify: \"flex-start\",\n borderColor: UC_BRAND_BLUE,\n flexDirection: \"column\",\n paddingX: 2,\n paddingY: 1,\n width: boxWidth,\n },\n React.createElement(\n Text,\n { color: \"gray\", dimColor: true },\n step !== \"done\" ? `Step ${stepNum} of ${TOTAL_STEPS}` : \"Done\"\n ),\n React.createElement(Box, { height: 1 }),\n content\n )\n );\n}\n\n// ── public entry point ──────────────────────────────────────────\n\nexport function onboard() {\n return new Promise((resolve) => {\n const app = render(\n React.createElement(Onboarding, {\n onDone: (wantsTui) => {\n app.unmount();\n resolve({ launchTui: Boolean(wantsTui) });\n },\n }),\n { exitOnCtrlC: false }\n );\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"onboarding.mjs","names":[],"sources":["../../src/cli/onboarding.mjs"],"sourcesContent":["// Interactive onboarding wizard — guides new users through setup\nimport React from \"react\";\nimport { render, Box, Text, useInput, useStdout } from \"ink\";\nimport { TitledBox } from \"@mishieck/ink-titled-box\";\nimport { spawn } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport process from \"node:process\";\n\nimport { heroArtForWidth } from \"@ultracontext/sync/ui/hero-art\";\nimport { UC_BRAND_BLUE, UC_BLUE_LIGHT } from \"@ultracontext/sync/ui/constants\";\nimport Spinner from \"@ultracontext/sync/Spinner\";\n\n// ── config helpers ──────────────────────────────────────────────\n\nconst CONFIG_DIR = path.join(process.env.HOME || process.env.USERPROFILE || \"~\", \".ultracontext\");\nconst CONFIG_PATH = path.join(CONFIG_DIR, \"config.json\");\n\nfunction readConfig() {\n try {\n return JSON.parse(fs.readFileSync(CONFIG_PATH, \"utf8\"));\n } catch {\n return {};\n }\n}\n\nfunction writeConfig(patch) {\n const existing = readConfig();\n fs.mkdirSync(CONFIG_DIR, { recursive: true });\n fs.writeFileSync(CONFIG_PATH, JSON.stringify({ ...existing, ...patch }, null, 2) + \"\\n\", \"utf8\");\n}\n\n// ── open URL (cross-platform) ───────────────────────────────────\n\nfunction openUrl(url) {\n const cmd = process.platform === \"darwin\" ? \"open\" : \"xdg-open\";\n try {\n const child = spawn(cmd, [url], { detached: true, stdio: \"ignore\" });\n child.unref();\n } catch { /* best effort */ }\n}\n\n// ── validation ──────────────────────────────────────────────────\n\nfunction isValidKey(key) {\n return /^uc_(live|test)_/.test(key);\n}\n\n// ── step constants ──────────────────────────────────────────────\n\nconst STEPS = [\"welcome\", \"mode\", \"url\", \"key\", \"bootstrap\", \"launch\", \"done\"];\n\nconst MODE_OPTIONS = [\n { label: \"Login (ultracontext.ai)\", value: \"cloud\" },\n { label: \"Self-host\", value: \"selfhost\" },\n];\n\nconst BOOTSTRAP_OPTIONS = [\n { label: \"New only (recommended)\", value: \"new_only\" },\n { label: \"Last 24h\", value: \"last_24h\" },\n { label: \"All\", value: \"all\" },\n];\n\nconst LAUNCH_OPTIONS = [\n { label: \"Yes, open the TUI (recommended)\", value: true },\n { label: \"No, just finish setup\", value: false },\n];\n\n// ── step number display ─────────────────────────────────────────\n\nfunction stepNumber(step) {\n if (step === \"welcome\") return 1;\n if (step === \"mode\") return 2;\n if (step === \"url\" || step === \"key\") return 3;\n if (step === \"bootstrap\") return 4;\n if (step === \"launch\") return 5;\n return 5;\n}\n\nconst TOTAL_STEPS = 5;\n\n// ── Onboarding component ────────────────────────────────────────\n\nfunction Onboarding({ onDone }) {\n const { stdout } = useStdout();\n const cols = stdout?.columns ?? process.stdout.columns ?? 80;\n\n const [step, setStep] = React.useState(\"welcome\");\n const [hosting, setHosting] = React.useState(\"cloud\");\n const [baseUrl, setBaseUrl] = React.useState(\"https://api.ultracontext.ai\");\n const [apiKey, setApiKey] = React.useState(\"\");\n const [bootstrapMode, setBootstrapMode] = React.useState(\"new_only\");\n const [selectedIndex, setSelectedIndex] = React.useState(0);\n const [keyInput, setKeyInput] = React.useState(\"\");\n const [urlInput, setUrlInput] = React.useState(\"https://\");\n const [error, setError] = React.useState(\"\");\n const [launchTui, setLaunchTui] = React.useState(false);\n\n // save config + env, advance to launch step\n const finish = React.useCallback((finalKey, finalUrl, finalBootstrap) => {\n writeConfig({ apiKey: finalKey, baseUrl: finalUrl, bootstrapMode: finalBootstrap });\n process.env.ULTRACONTEXT_API_KEY = finalKey;\n process.env.ULTRACONTEXT_BASE_URL = finalUrl;\n setStep(\"launch\");\n setSelectedIndex(0);\n }, []);\n\n useInput((input, key) => {\n // escape or ctrl+c exits at any step\n if (key.escape || (input === \"c\" && key.ctrl)) {\n process.exit(0);\n }\n\n // ── welcome ──\n if (step === \"welcome\") {\n if (key.return) {\n setStep(\"mode\");\n setSelectedIndex(0);\n }\n return;\n }\n\n // ── mode selection ──\n if (step === \"mode\") {\n if (key.upArrow) setSelectedIndex((i) => Math.max(i - 1, 0));\n if (key.downArrow) setSelectedIndex((i) => Math.min(i + 1, MODE_OPTIONS.length - 1));\n if (input === \"1\") setSelectedIndex(0);\n if (input === \"2\") setSelectedIndex(1);\n\n if (key.return || input === \" \") {\n const chosen = MODE_OPTIONS[selectedIndex].value;\n setHosting(chosen);\n if (chosen === \"selfhost\") {\n setStep(\"url\");\n setUrlInput(\"https://\");\n setError(\"\");\n } else {\n setBaseUrl(\"https://api.ultracontext.ai\");\n openUrl(\"https://ultracontext.ai\");\n setStep(\"key\");\n setKeyInput(\"\");\n setError(\"\");\n }\n setSelectedIndex(0);\n }\n return;\n }\n\n // ── url input (self-host) ──\n if (step === \"url\") {\n if (key.return) {\n const trimmed = urlInput.trim();\n if (!trimmed || trimmed === \"https://\") {\n setError(\"Enter a valid base URL\");\n return;\n }\n setBaseUrl(trimmed);\n setStep(\"key\");\n setKeyInput(\"\");\n setError(\"\");\n return;\n }\n if (key.backspace || key.delete) {\n setUrlInput((v) => v.slice(0, -1));\n setError(\"\");\n return;\n }\n if (input && !key.ctrl && !key.meta) {\n setUrlInput((v) => v + input);\n setError(\"\");\n }\n return;\n }\n\n // ── key input ──\n if (step === \"key\") {\n if (key.return) {\n const trimmed = keyInput.trim();\n if (!trimmed) {\n setError(\"Enter your API key\");\n return;\n }\n if (!isValidKey(trimmed)) {\n setError(\"Key must start with uc_live_ or uc_test_\");\n return;\n }\n setApiKey(trimmed);\n setStep(\"bootstrap\");\n setSelectedIndex(0);\n setError(\"\");\n return;\n }\n if (key.backspace || key.delete) {\n setKeyInput((v) => v.slice(0, -1));\n setError(\"\");\n return;\n }\n if (input && !key.ctrl && !key.meta) {\n setKeyInput((v) => v + input);\n setError(\"\");\n }\n return;\n }\n\n // ── bootstrap mode ──\n if (step === \"bootstrap\") {\n if (key.upArrow) setSelectedIndex((i) => Math.max(i - 1, 0));\n if (key.downArrow) setSelectedIndex((i) => Math.min(i + 1, BOOTSTRAP_OPTIONS.length - 1));\n if (input === \"1\") setSelectedIndex(0);\n if (input === \"2\") setSelectedIndex(1);\n if (input === \"3\") setSelectedIndex(2);\n\n if (key.return || input === \" \") {\n const chosen = BOOTSTRAP_OPTIONS[selectedIndex].value;\n setBootstrapMode(chosen);\n finish(apiKey, baseUrl, chosen);\n }\n return;\n }\n\n // ── launch TUI? ──\n if (step === \"launch\") {\n if (key.upArrow) setSelectedIndex((i) => Math.max(i - 1, 0));\n if (key.downArrow) setSelectedIndex((i) => Math.min(i + 1, LAUNCH_OPTIONS.length - 1));\n if (input === \"1\") setSelectedIndex(0);\n if (input === \"2\") setSelectedIndex(1);\n\n if (key.return || input === \" \") {\n const chosen = LAUNCH_OPTIONS[selectedIndex].value;\n setLaunchTui(chosen);\n setStep(\"done\");\n setTimeout(() => onDone(chosen), 80);\n }\n return;\n }\n });\n\n // ── render ──\n\n const heroLines = heroArtForWidth(cols - 4);\n const stepNum = stepNumber(step);\n\n // hero art — 3d spinner + figlet on all steps\n const hero = React.createElement(\n Box,\n { flexDirection: \"row\", justifyContent: \"center\", width: \"100%\" },\n React.createElement(Spinner, { color: UC_BLUE_LIGHT }),\n React.createElement(Box, { width: 3 }),\n React.createElement(\n Box,\n { flexDirection: \"column\", justifyContent: \"center\" },\n ...heroLines.map((line, i) =>\n React.createElement(Text, { key: `h${i}`, color: \"white\", bold: true }, line)\n )\n )\n );\n\n // step content\n let content = null;\n\n if (step === \"welcome\") {\n content = React.createElement(\n Box,\n { flexDirection: \"column\" },\n React.createElement(Text, { color: \"white\", bold: true }, \"Welcome to UltraContext\"),\n React.createElement(Text, { color: \"gray\" }, \"Context engineering for AI coding agents.\"),\n React.createElement(Box, { height: 1 }),\n React.createElement(Text, { color: UC_BLUE_LIGHT }, \"Press Enter to begin setup...\")\n );\n }\n\n if (step === \"mode\") {\n content = React.createElement(\n Box,\n { flexDirection: \"column\" },\n React.createElement(Text, { color: \"white\", bold: true }, \"How do you want to connect?\"),\n React.createElement(Box, { height: 1 }),\n ...MODE_OPTIONS.map((opt, i) => {\n const sel = i === selectedIndex;\n return React.createElement(\n Text,\n { key: `m${i}`, color: sel ? UC_BLUE_LIGHT : \"white\" },\n sel ? \"[\\u2022]\" : \"[ ]\",\n ` ${i + 1}. ${opt.label}`\n );\n }),\n React.createElement(Box, { height: 1 }),\n React.createElement(Text, { color: \"gray\" }, \"Navigate: up/down, 1/2 | Confirm: Enter\")\n );\n }\n\n if (step === \"url\") {\n content = React.createElement(\n Box,\n { flexDirection: \"column\" },\n React.createElement(Text, { color: \"white\", bold: true }, \"Enter your API base URL:\"),\n React.createElement(Box, { height: 1 }),\n React.createElement(Text, { color: UC_BLUE_LIGHT }, `> ${urlInput}_`),\n error ? React.createElement(Text, { color: \"red\" }, error) : null,\n React.createElement(Box, { height: 1 }),\n React.createElement(Text, { color: \"gray\" }, \"Enter to confirm | Esc to quit\")\n );\n }\n\n if (step === \"key\") {\n const keyPrompt = hosting === \"cloud\"\n ? \"Paste your API key (browser opened for you):\"\n : \"Enter your API key:\";\n\n content = React.createElement(\n Box,\n { flexDirection: \"column\" },\n React.createElement(Text, { color: \"white\", bold: true }, keyPrompt),\n React.createElement(Box, { height: 1 }),\n React.createElement(Text, { color: UC_BLUE_LIGHT }, `> ${keyInput}_`),\n error ? React.createElement(Text, { color: \"red\" }, error) : null,\n React.createElement(Box, { height: 1 }),\n React.createElement(Text, { color: \"gray\" }, \"Format: uc_live_... or uc_test_... | Enter to confirm\")\n );\n }\n\n if (step === \"bootstrap\") {\n content = React.createElement(\n Box,\n { flexDirection: \"column\" },\n React.createElement(Text, { color: \"white\", bold: true }, \"Initial sync mode:\"),\n React.createElement(Box, { height: 1 }),\n ...BOOTSTRAP_OPTIONS.map((opt, i) => {\n const sel = i === selectedIndex;\n return React.createElement(\n Text,\n { key: `b${i}`, color: sel ? UC_BLUE_LIGHT : \"white\" },\n sel ? \"[\\u2022]\" : \"[ ]\",\n ` ${i + 1}. ${opt.label}`\n );\n }),\n React.createElement(Box, { height: 1 }),\n React.createElement(Text, { color: \"gray\" }, \"Navigate: up/down, 1/2/3 | Confirm: Enter\")\n );\n }\n\n if (step === \"launch\") {\n content = React.createElement(\n Box,\n { flexDirection: \"column\" },\n React.createElement(Text, { color: \"white\", bold: true }, \"Launch the TUI dashboard?\"),\n React.createElement(Box, { height: 1 }),\n ...LAUNCH_OPTIONS.map((opt, i) => {\n const sel = i === selectedIndex;\n return React.createElement(\n Text,\n { key: `l${i}`, color: sel ? UC_BLUE_LIGHT : \"white\" },\n sel ? \"[\\u2022]\" : \"[ ]\",\n ` ${i + 1}. ${opt.label}`\n );\n }),\n React.createElement(Box, { height: 1 }),\n React.createElement(Text, { color: \"gray\" }, \"Navigate: up/down, 1/2 | Confirm: Enter\")\n );\n }\n\n if (step === \"done\") {\n content = React.createElement(\n Box,\n { flexDirection: \"column\" },\n React.createElement(Text, { color: \"green\", bold: true }, \"Setup complete!\"),\n React.createElement(Text, { color: \"gray\" }, `Config saved to ${CONFIG_PATH}`)\n );\n }\n\n const boxWidth = Math.min(cols - 2, 60);\n\n return React.createElement(\n Box,\n { flexDirection: \"column\", alignItems: \"center\", paddingX: 1, paddingY: 1, width: cols },\n hero,\n React.createElement(Text, { color: UC_BLUE_LIGHT, bold: true }, \"[ The Context Hub for AI Agents ]\"),\n React.createElement(Box, { height: 1 }),\n React.createElement(\n TitledBox,\n {\n borderStyle: \"single\",\n titles: [\"Setup\"],\n titleJustify: \"flex-start\",\n borderColor: UC_BRAND_BLUE,\n flexDirection: \"column\",\n paddingX: 2,\n paddingY: 1,\n width: boxWidth,\n },\n React.createElement(\n Text,\n { color: \"gray\", dimColor: true },\n step !== \"done\" ? `Step ${stepNum} of ${TOTAL_STEPS}` : \"Done\"\n ),\n React.createElement(Box, { height: 1 }),\n content\n )\n );\n}\n\n// ── public entry point ──────────────────────────────────────────\n\nexport function onboard() {\n return new Promise((resolve) => {\n const app = render(\n React.createElement(Onboarding, {\n onDone: (wantsTui) => {\n app.unmount();\n resolve({ launchTui: Boolean(wantsTui) });\n },\n }),\n { exitOnCtrlC: false }\n );\n });\n}\n"],"mappings":"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"}