ultracontext 1.3.3 → 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.
- package/dist/{Spinner-C_38udz8.mjs → Spinner-CwBjkXHv.mjs} +4 -4
- package/dist/Spinner-CwBjkXHv.mjs.map +1 -0
- package/dist/cli/entry.mjs +33 -69
- package/dist/cli/entry.mjs.map +1 -1
- package/dist/cli/onboarding.mjs +1 -1
- package/dist/cli/onboarding.mjs.map +1 -1
- package/dist/cli/{sdk-daemon.mjs → sdk-sync.mjs} +248 -577
- package/dist/cli/sdk-sync.mjs.map +1 -0
- package/dist/{ctl-BVPu-D57.mjs → ctl-iHUR6By1.mjs} +5 -5
- package/dist/ctl-iHUR6By1.mjs.map +1 -0
- package/dist/{launcher-BFPi7_wD.mjs → launcher-C_GUIW-o.mjs} +5 -6
- package/dist/launcher-C_GUIW-o.mjs.map +1 -0
- package/dist/{lock-CQ3xrIlj.mjs → lock-5aJnda81.mjs} +4 -37
- package/dist/lock-5aJnda81.mjs.map +1 -0
- package/dist/protocol-BI9ficcl.mjs +35 -0
- package/dist/protocol-BI9ficcl.mjs.map +1 -0
- package/dist/{src-DzUz8GPJ.mjs → src-B5tU1zKh.mjs} +2 -2
- package/dist/{src-DzUz8GPJ.mjs.map → src-B5tU1zKh.mjs.map} +1 -1
- package/dist/{tui-C3H6iRjz.mjs → tui-Df8--qZj.mjs} +129 -516
- package/dist/tui-Df8--qZj.mjs.map +1 -0
- package/dist/utils-CmuIYHtm.mjs +106 -0
- package/dist/utils-CmuIYHtm.mjs.map +1 -0
- package/package.json +3 -6
- package/dist/Spinner-C_38udz8.mjs.map +0 -1
- package/dist/cli/sdk-daemon.mjs.map +0 -1
- package/dist/ctl-BVPu-D57.mjs.map +0 -1
- package/dist/launcher-BFPi7_wD.mjs.map +0 -1
- package/dist/lock-CQ3xrIlj.mjs.map +0 -1
- package/dist/src-BSCJv6SU.mjs +0 -151
- package/dist/src-BSCJv6SU.mjs.map +0 -1
- package/dist/tui-C3H6iRjz.mjs.map +0 -1
|
@@ -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 ../
|
|
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 ../
|
|
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 ../
|
|
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-
|
|
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":"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"}
|
package/dist/cli/entry.mjs
CHANGED
|
@@ -27,12 +27,10 @@ function printHelp() {
|
|
|
27
27
|
Usage: ultracontext [command] [options]
|
|
28
28
|
|
|
29
29
|
Commands:
|
|
30
|
-
(none) Start daemon
|
|
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,12 +237,11 @@ 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("
|
|
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
|
|
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
|
-
const UPDATE_CHECK_INTERVAL = 10800 * 1e3;
|
|
252
245
|
const SKIP_UPDATE_CHECK = new Set([
|
|
253
246
|
"version",
|
|
254
247
|
"v",
|
|
@@ -256,28 +249,11 @@ const SKIP_UPDATE_CHECK = new Set([
|
|
|
256
249
|
"upgrade",
|
|
257
250
|
"help",
|
|
258
251
|
"h",
|
|
259
|
-
"stop"
|
|
260
|
-
"status"
|
|
252
|
+
"stop"
|
|
261
253
|
]);
|
|
262
|
-
function getUpdateCheckPath() {
|
|
263
|
-
const home = process.env.HOME || process.env.USERPROFILE || "~";
|
|
264
|
-
return path.join(home, ".ultracontext", "update-check.json");
|
|
265
|
-
}
|
|
266
|
-
function readUpdateCache() {
|
|
267
|
-
try {
|
|
268
|
-
return JSON.parse(fs.readFileSync(getUpdateCheckPath(), "utf8"));
|
|
269
|
-
} catch {
|
|
270
|
-
return null;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
function writeUpdateCache(data) {
|
|
274
|
-
try {
|
|
275
|
-
fs.writeFileSync(getUpdateCheckPath(), JSON.stringify(data));
|
|
276
|
-
} catch {}
|
|
277
|
-
}
|
|
278
254
|
async function fetchLatestVersion() {
|
|
279
255
|
const controller = new AbortController();
|
|
280
|
-
const timeout = setTimeout(() => controller.abort(),
|
|
256
|
+
const timeout = setTimeout(() => controller.abort(), 5e3);
|
|
281
257
|
try {
|
|
282
258
|
return (await (await fetch("https://registry.npmjs.org/ultracontext/latest", { signal: controller.signal })).json()).version ?? null;
|
|
283
259
|
} catch {
|
|
@@ -303,35 +279,23 @@ function printUpdateNotice(current, latest) {
|
|
|
303
279
|
async function checkForUpdate() {
|
|
304
280
|
const current = readVersion();
|
|
305
281
|
if (current === "unknown") return;
|
|
306
|
-
const cache = readUpdateCache();
|
|
307
|
-
if (cache?.lastCheck && Date.now() - cache.lastCheck < UPDATE_CHECK_INTERVAL) {
|
|
308
|
-
if (cache.latestVersion && isNewer(cache.latestVersion, current)) printUpdateNotice(current, cache.latestVersion);
|
|
309
|
-
return;
|
|
310
|
-
}
|
|
311
282
|
const latest = await fetchLatestVersion();
|
|
312
|
-
writeUpdateCache({
|
|
313
|
-
lastCheck: Date.now(),
|
|
314
|
-
latestVersion: latest
|
|
315
|
-
});
|
|
316
283
|
if (latest && isNewer(latest, current)) printUpdateNotice(current, latest);
|
|
317
284
|
}
|
|
318
|
-
async function
|
|
319
|
-
const { launchDaemon } = await import("../launcher-
|
|
285
|
+
async function launchSyncDaemon() {
|
|
286
|
+
const { launchDaemon } = await import("../launcher-C_GUIW-o.mjs");
|
|
320
287
|
await launchDaemon({
|
|
321
|
-
entryPath: fileURLToPath(new URL("./sdk-
|
|
322
|
-
diagnosticsHint: "DAEMON_VERBOSE=1 ultracontext
|
|
288
|
+
entryPath: fileURLToPath(new URL("./sdk-sync.mjs", import.meta.url)),
|
|
289
|
+
diagnosticsHint: "DAEMON_VERBOSE=1 ultracontext sync"
|
|
323
290
|
});
|
|
324
291
|
}
|
|
325
292
|
async function runCtlSDK() {
|
|
326
|
-
const { runCtl } = await import("../ctl-
|
|
293
|
+
const { runCtl } = await import("../ctl-iHUR6By1.mjs");
|
|
327
294
|
await runCtl();
|
|
328
295
|
}
|
|
329
|
-
async function
|
|
330
|
-
const { tuiBoot } = await import("../tui-
|
|
331
|
-
await tuiBoot({
|
|
332
|
-
assetsRoot: path.resolve(__dirname, "..", ".."),
|
|
333
|
-
offlineNotice: "Daemon offline. Run: ultracontext start"
|
|
334
|
-
});
|
|
296
|
+
async function launchTui() {
|
|
297
|
+
const { tuiBoot } = await import("../tui-Df8--qZj.mjs");
|
|
298
|
+
await tuiBoot({ assetsRoot: path.resolve(__dirname, "..", "..") });
|
|
335
299
|
}
|
|
336
300
|
async function run() {
|
|
337
301
|
if (!SKIP_UPDATE_CHECK.has(command)) await checkForUpdate();
|
|
@@ -341,27 +305,21 @@ async function run() {
|
|
|
341
305
|
if (!process.env.ULTRACONTEXT_API_KEY) onboardResult = await runOnboarding();
|
|
342
306
|
}
|
|
343
307
|
switch (command) {
|
|
344
|
-
case "
|
|
345
|
-
|
|
346
|
-
if (
|
|
308
|
+
case "sync":
|
|
309
|
+
case "":
|
|
310
|
+
if (!isDaemonRunning()) await launchSyncDaemon();
|
|
311
|
+
if (onboardResult?.launchTui !== false) await launchTui();
|
|
347
312
|
break;
|
|
348
313
|
case "stop":
|
|
349
314
|
process.argv[2] = "stop";
|
|
350
315
|
await runCtlSDK();
|
|
351
316
|
break;
|
|
352
|
-
case "status":
|
|
353
|
-
process.argv[2] = "status";
|
|
354
|
-
await runCtlSDK();
|
|
355
|
-
break;
|
|
356
317
|
case "config":
|
|
357
318
|
if ((await runOnboarding())?.launchTui) {
|
|
358
|
-
if (!isDaemonRunning()) await
|
|
359
|
-
await
|
|
319
|
+
if (!isDaemonRunning()) await launchSyncDaemon();
|
|
320
|
+
await launchTui();
|
|
360
321
|
}
|
|
361
322
|
break;
|
|
362
|
-
case "tui":
|
|
363
|
-
await launchTuiSDK();
|
|
364
|
-
break;
|
|
365
323
|
case "version":
|
|
366
324
|
case "v":
|
|
367
325
|
console.log(readVersion());
|
|
@@ -370,18 +328,24 @@ async function run() {
|
|
|
370
328
|
case "upgrade":
|
|
371
329
|
runUpdate(process.argv.slice(3));
|
|
372
330
|
break;
|
|
373
|
-
case "":
|
|
374
|
-
if (!isDaemonRunning()) await launchDaemonSDK();
|
|
375
|
-
await launchTuiSDK();
|
|
376
|
-
break;
|
|
377
331
|
case "help":
|
|
378
332
|
case "h":
|
|
379
333
|
printHelp();
|
|
380
334
|
break;
|
|
381
|
-
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
|
+
}
|
|
382
345
|
console.error(`Unknown command: ${process.argv[2]}`);
|
|
383
346
|
printHelp();
|
|
384
347
|
process.exit(1);
|
|
348
|
+
}
|
|
385
349
|
}
|
|
386
350
|
}
|
|
387
351
|
run().catch((error) => {
|
package/dist/cli/entry.mjs.map
CHANGED
|
@@ -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 UPDATE_CHECK_INTERVAL = 3 * 60 * 60 * 1000; // 3h\nconst SKIP_UPDATE_CHECK = new Set([\"version\", \"v\", \"update\", \"upgrade\", \"help\", \"h\", \"stop\", \"status\"]);\n\nfunction getUpdateCheckPath() {\n const home = process.env.HOME || process.env.USERPROFILE || \"~\";\n return path.join(home, \".ultracontext\", \"update-check.json\");\n}\n\nfunction readUpdateCache() {\n try { return JSON.parse(fs.readFileSync(getUpdateCheckPath(), \"utf8\")); }\n catch { return null; }\n}\n\nfunction writeUpdateCache(data) {\n try { fs.writeFileSync(getUpdateCheckPath(), JSON.stringify(data)); }\n catch { /* best effort */ }\n}\n\nasync function fetchLatestVersion() {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 3000);\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\nasync function checkForUpdate() {\n const current = readVersion();\n if (current === \"unknown\") return;\n\n // use cache if fresh\n const cache = readUpdateCache();\n if (cache?.lastCheck && Date.now() - cache.lastCheck < UPDATE_CHECK_INTERVAL) {\n if (cache.latestVersion && isNewer(cache.latestVersion, current)) {\n printUpdateNotice(current, cache.latestVersion);\n }\n return;\n }\n\n // fetch from registry\n const latest = await fetchLatestVersion();\n writeUpdateCache({ lastCheck: Date.now(), latestVersion: latest });\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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"}
|
package/dist/cli/onboarding.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as heroArtForWidth, i as UC_BRAND_BLUE, r as UC_BLUE_LIGHT, t as Spinner } from "../Spinner-
|
|
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":";;;;;;;;;;AAeA,MAAM,aAAa,KAAK,KAAK,QAAQ,IAAI,QAAQ,QAAQ,IAAI,eAAe,KAAK,gBAAgB;AACjG,MAAM,cAAc,KAAK,KAAK,YAAY,cAAc;AAExD,SAAS,aAAa;AACpB,KAAI;AACF,SAAO,KAAK,MAAM,GAAG,aAAa,aAAa,OAAO,CAAC;SACjD;AACN,SAAO,EAAE;;;AAIb,SAAS,YAAY,OAAO;CAC1B,MAAM,WAAW,YAAY;AAC7B,IAAG,UAAU,YAAY,EAAE,WAAW,MAAM,CAAC;AAC7C,IAAG,cAAc,aAAa,KAAK,UAAU;EAAE,GAAG;EAAU,GAAG;EAAO,EAAE,MAAM,EAAE,GAAG,MAAM,OAAO;;AAKlG,SAAS,QAAQ,KAAK;CACpB,MAAM,MAAM,QAAQ,aAAa,WAAW,SAAS;AACrD,KAAI;AAEF,EADc,MAAM,KAAK,CAAC,IAAI,EAAE;GAAE,UAAU;GAAM,OAAO;GAAU,CAAC,CAC9D,OAAO;SACP;;AAKV,SAAS,WAAW,KAAK;AACvB,QAAO,mBAAmB,KAAK,IAAI;;AAOrC,MAAM,eAAe,CACnB;CAAE,OAAO;CAA2B,OAAO;CAAS,EACpD;CAAE,OAAO;CAAa,OAAO;CAAY,CAC1C;AAED,MAAM,oBAAoB;CACxB;EAAE,OAAO;EAA0B,OAAO;EAAY;CACtD;EAAE,OAAO;EAAY,OAAO;EAAY;CACxC;EAAE,OAAO;EAAO,OAAO;EAAO;CAC/B;AAED,MAAM,iBAAiB,CACrB;CAAE,OAAO;CAAmC,OAAO;CAAM,EACzD;CAAE,OAAO;CAAyB,OAAO;CAAO,CACjD;AAID,SAAS,WAAW,MAAM;AACxB,KAAI,SAAS,UAAW,QAAO;AAC/B,KAAI,SAAS,OAAQ,QAAO;AAC5B,KAAI,SAAS,SAAS,SAAS,MAAO,QAAO;AAC7C,KAAI,SAAS,YAAa,QAAO;AACjC,KAAI,SAAS,SAAU,QAAO;AAC9B,QAAO;;AAGT,MAAM,cAAc;AAIpB,SAAS,WAAW,EAAE,UAAU;CAC9B,MAAM,EAAE,WAAW,WAAW;CAC9B,MAAM,OAAO,QAAQ,WAAW,QAAQ,OAAO,WAAW;CAE1D,MAAM,CAAC,MAAM,WAAW,MAAM,SAAS,UAAU;CACjD,MAAM,CAAC,SAAS,cAAc,MAAM,SAAS,QAAQ;CACrD,MAAM,CAAC,SAAS,cAAc,MAAM,SAAS,8BAA8B;CAC3E,MAAM,CAAC,QAAQ,aAAa,MAAM,SAAS,GAAG;CAC9C,MAAM,CAAC,eAAe,oBAAoB,MAAM,SAAS,WAAW;CACpE,MAAM,CAAC,eAAe,oBAAoB,MAAM,SAAS,EAAE;CAC3D,MAAM,CAAC,UAAU,eAAe,MAAM,SAAS,GAAG;CAClD,MAAM,CAAC,UAAU,eAAe,MAAM,SAAS,WAAW;CAC1D,MAAM,CAAC,OAAO,YAAY,MAAM,SAAS,GAAG;CAC5C,MAAM,CAAC,WAAW,gBAAgB,MAAM,SAAS,MAAM;CAGvD,MAAM,SAAS,MAAM,aAAa,UAAU,UAAU,mBAAmB;AACvE,cAAY;GAAE,QAAQ;GAAU,SAAS;GAAU,eAAe;GAAgB,CAAC;AACnF,UAAQ,IAAI,uBAAuB;AACnC,UAAQ,IAAI,wBAAwB;AACpC,UAAQ,SAAS;AACjB,mBAAiB,EAAE;IAClB,EAAE,CAAC;AAEN,WAAU,OAAO,QAAQ;AAEvB,MAAI,IAAI,UAAW,UAAU,OAAO,IAAI,KACtC,SAAQ,KAAK,EAAE;AAIjB,MAAI,SAAS,WAAW;AACtB,OAAI,IAAI,QAAQ;AACd,YAAQ,OAAO;AACf,qBAAiB,EAAE;;AAErB;;AAIF,MAAI,SAAS,QAAQ;AACnB,OAAI,IAAI,QAAS,mBAAkB,MAAM,KAAK,IAAI,IAAI,GAAG,EAAE,CAAC;AAC5D,OAAI,IAAI,UAAW,mBAAkB,MAAM,KAAK,IAAI,IAAI,GAAG,aAAa,SAAS,EAAE,CAAC;AACpF,OAAI,UAAU,IAAK,kBAAiB,EAAE;AACtC,OAAI,UAAU,IAAK,kBAAiB,EAAE;AAEtC,OAAI,IAAI,UAAU,UAAU,KAAK;IAC/B,MAAM,SAAS,aAAa,eAAe;AAC3C,eAAW,OAAO;AAClB,QAAI,WAAW,YAAY;AACzB,aAAQ,MAAM;AACd,iBAAY,WAAW;AACvB,cAAS,GAAG;WACP;AACL,gBAAW,8BAA8B;AACzC,aAAQ,0BAA0B;AAClC,aAAQ,MAAM;AACd,iBAAY,GAAG;AACf,cAAS,GAAG;;AAEd,qBAAiB,EAAE;;AAErB;;AAIF,MAAI,SAAS,OAAO;AAClB,OAAI,IAAI,QAAQ;IACd,MAAM,UAAU,SAAS,MAAM;AAC/B,QAAI,CAAC,WAAW,YAAY,YAAY;AACtC,cAAS,yBAAyB;AAClC;;AAEF,eAAW,QAAQ;AACnB,YAAQ,MAAM;AACd,gBAAY,GAAG;AACf,aAAS,GAAG;AACZ;;AAEF,OAAI,IAAI,aAAa,IAAI,QAAQ;AAC/B,iBAAa,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC;AAClC,aAAS,GAAG;AACZ;;AAEF,OAAI,SAAS,CAAC,IAAI,QAAQ,CAAC,IAAI,MAAM;AACnC,iBAAa,MAAM,IAAI,MAAM;AAC7B,aAAS,GAAG;;AAEd;;AAIF,MAAI,SAAS,OAAO;AAClB,OAAI,IAAI,QAAQ;IACd,MAAM,UAAU,SAAS,MAAM;AAC/B,QAAI,CAAC,SAAS;AACZ,cAAS,qBAAqB;AAC9B;;AAEF,QAAI,CAAC,WAAW,QAAQ,EAAE;AACxB,cAAS,2CAA2C;AACpD;;AAEF,cAAU,QAAQ;AAClB,YAAQ,YAAY;AACpB,qBAAiB,EAAE;AACnB,aAAS,GAAG;AACZ;;AAEF,OAAI,IAAI,aAAa,IAAI,QAAQ;AAC/B,iBAAa,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC;AAClC,aAAS,GAAG;AACZ;;AAEF,OAAI,SAAS,CAAC,IAAI,QAAQ,CAAC,IAAI,MAAM;AACnC,iBAAa,MAAM,IAAI,MAAM;AAC7B,aAAS,GAAG;;AAEd;;AAIF,MAAI,SAAS,aAAa;AACxB,OAAI,IAAI,QAAS,mBAAkB,MAAM,KAAK,IAAI,IAAI,GAAG,EAAE,CAAC;AAC5D,OAAI,IAAI,UAAW,mBAAkB,MAAM,KAAK,IAAI,IAAI,GAAG,kBAAkB,SAAS,EAAE,CAAC;AACzF,OAAI,UAAU,IAAK,kBAAiB,EAAE;AACtC,OAAI,UAAU,IAAK,kBAAiB,EAAE;AACtC,OAAI,UAAU,IAAK,kBAAiB,EAAE;AAEtC,OAAI,IAAI,UAAU,UAAU,KAAK;IAC/B,MAAM,SAAS,kBAAkB,eAAe;AAChD,qBAAiB,OAAO;AACxB,WAAO,QAAQ,SAAS,OAAO;;AAEjC;;AAIF,MAAI,SAAS,UAAU;AACrB,OAAI,IAAI,QAAS,mBAAkB,MAAM,KAAK,IAAI,IAAI,GAAG,EAAE,CAAC;AAC5D,OAAI,IAAI,UAAW,mBAAkB,MAAM,KAAK,IAAI,IAAI,GAAG,eAAe,SAAS,EAAE,CAAC;AACtF,OAAI,UAAU,IAAK,kBAAiB,EAAE;AACtC,OAAI,UAAU,IAAK,kBAAiB,EAAE;AAEtC,OAAI,IAAI,UAAU,UAAU,KAAK;IAC/B,MAAM,SAAS,eAAe,eAAe;AAC7C,iBAAa,OAAO;AACpB,YAAQ,OAAO;AACf,qBAAiB,OAAO,OAAO,EAAE,GAAG;;AAEtC;;GAEF;CAIF,MAAM,YAAY,gBAAgB,OAAO,EAAE;CAC3C,MAAM,UAAU,WAAW,KAAK;CAGhC,MAAM,OAAO,MAAM,cACjB,KACA;EAAE,eAAe;EAAO,gBAAgB;EAAU,OAAO;EAAQ,EACjE,MAAM,cAAc,SAAS,EAAE,OAAO,eAAe,CAAC,EACtD,MAAM,cAAc,KAAK,EAAE,OAAO,GAAG,CAAC,EACtC,MAAM,cACJ,KACA;EAAE,eAAe;EAAU,gBAAgB;EAAU,EACrD,GAAG,UAAU,KAAK,MAAM,MACtB,MAAM,cAAc,MAAM;EAAE,KAAK,IAAI;EAAK,OAAO;EAAS,MAAM;EAAM,EAAE,KAAK,CAC9E,CACF,CACF;CAGD,IAAI,UAAU;AAEd,KAAI,SAAS,UACX,WAAU,MAAM,cACd,KACA,EAAE,eAAe,UAAU,EAC3B,MAAM,cAAc,MAAM;EAAE,OAAO;EAAS,MAAM;EAAM,EAAE,0BAA0B,EACpF,MAAM,cAAc,MAAM,EAAE,OAAO,QAAQ,EAAE,4CAA4C,EACzF,MAAM,cAAc,KAAK,EAAE,QAAQ,GAAG,CAAC,EACvC,MAAM,cAAc,MAAM,EAAE,OAAO,eAAe,EAAE,gCAAgC,CACrF;AAGH,KAAI,SAAS,OACX,WAAU,MAAM,cACd,KACA,EAAE,eAAe,UAAU,EAC3B,MAAM,cAAc,MAAM;EAAE,OAAO;EAAS,MAAM;EAAM,EAAE,8BAA8B,EACxF,MAAM,cAAc,KAAK,EAAE,QAAQ,GAAG,CAAC,EACvC,GAAG,aAAa,KAAK,KAAK,MAAM;EAC9B,MAAM,MAAM,MAAM;AAClB,SAAO,MAAM,cACX,MACA;GAAE,KAAK,IAAI;GAAK,OAAO,MAAM,gBAAgB;GAAS,EACtD,MAAM,QAAa,OACnB,IAAI,IAAI,EAAE,IAAI,IAAI,QACnB;GACD,EACF,MAAM,cAAc,KAAK,EAAE,QAAQ,GAAG,CAAC,EACvC,MAAM,cAAc,MAAM,EAAE,OAAO,QAAQ,EAAE,0CAA0C,CACxF;AAGH,KAAI,SAAS,MACX,WAAU,MAAM,cACd,KACA,EAAE,eAAe,UAAU,EAC3B,MAAM,cAAc,MAAM;EAAE,OAAO;EAAS,MAAM;EAAM,EAAE,2BAA2B,EACrF,MAAM,cAAc,KAAK,EAAE,QAAQ,GAAG,CAAC,EACvC,MAAM,cAAc,MAAM,EAAE,OAAO,eAAe,EAAE,KAAK,SAAS,GAAG,EACrE,QAAQ,MAAM,cAAc,MAAM,EAAE,OAAO,OAAO,EAAE,MAAM,GAAG,MAC7D,MAAM,cAAc,KAAK,EAAE,QAAQ,GAAG,CAAC,EACvC,MAAM,cAAc,MAAM,EAAE,OAAO,QAAQ,EAAE,iCAAiC,CAC/E;AAGH,KAAI,SAAS,OAAO;EAClB,MAAM,YAAY,YAAY,UAC1B,iDACA;AAEJ,YAAU,MAAM,cACd,KACA,EAAE,eAAe,UAAU,EAC3B,MAAM,cAAc,MAAM;GAAE,OAAO;GAAS,MAAM;GAAM,EAAE,UAAU,EACpE,MAAM,cAAc,KAAK,EAAE,QAAQ,GAAG,CAAC,EACvC,MAAM,cAAc,MAAM,EAAE,OAAO,eAAe,EAAE,KAAK,SAAS,GAAG,EACrE,QAAQ,MAAM,cAAc,MAAM,EAAE,OAAO,OAAO,EAAE,MAAM,GAAG,MAC7D,MAAM,cAAc,KAAK,EAAE,QAAQ,GAAG,CAAC,EACvC,MAAM,cAAc,MAAM,EAAE,OAAO,QAAQ,EAAE,wDAAwD,CACtG;;AAGH,KAAI,SAAS,YACX,WAAU,MAAM,cACd,KACA,EAAE,eAAe,UAAU,EAC3B,MAAM,cAAc,MAAM;EAAE,OAAO;EAAS,MAAM;EAAM,EAAE,qBAAqB,EAC/E,MAAM,cAAc,KAAK,EAAE,QAAQ,GAAG,CAAC,EACvC,GAAG,kBAAkB,KAAK,KAAK,MAAM;EACnC,MAAM,MAAM,MAAM;AAClB,SAAO,MAAM,cACX,MACA;GAAE,KAAK,IAAI;GAAK,OAAO,MAAM,gBAAgB;GAAS,EACtD,MAAM,QAAa,OACnB,IAAI,IAAI,EAAE,IAAI,IAAI,QACnB;GACD,EACF,MAAM,cAAc,KAAK,EAAE,QAAQ,GAAG,CAAC,EACvC,MAAM,cAAc,MAAM,EAAE,OAAO,QAAQ,EAAE,4CAA4C,CAC1F;AAGH,KAAI,SAAS,SACX,WAAU,MAAM,cACd,KACA,EAAE,eAAe,UAAU,EAC3B,MAAM,cAAc,MAAM;EAAE,OAAO;EAAS,MAAM;EAAM,EAAE,4BAA4B,EACtF,MAAM,cAAc,KAAK,EAAE,QAAQ,GAAG,CAAC,EACvC,GAAG,eAAe,KAAK,KAAK,MAAM;EAChC,MAAM,MAAM,MAAM;AAClB,SAAO,MAAM,cACX,MACA;GAAE,KAAK,IAAI;GAAK,OAAO,MAAM,gBAAgB;GAAS,EACtD,MAAM,QAAa,OACnB,IAAI,IAAI,EAAE,IAAI,IAAI,QACnB;GACD,EACF,MAAM,cAAc,KAAK,EAAE,QAAQ,GAAG,CAAC,EACvC,MAAM,cAAc,MAAM,EAAE,OAAO,QAAQ,EAAE,0CAA0C,CACxF;AAGH,KAAI,SAAS,OACX,WAAU,MAAM,cACd,KACA,EAAE,eAAe,UAAU,EAC3B,MAAM,cAAc,MAAM;EAAE,OAAO;EAAS,MAAM;EAAM,EAAE,kBAAkB,EAC5E,MAAM,cAAc,MAAM,EAAE,OAAO,QAAQ,EAAE,mBAAmB,cAAc,CAC/E;CAGH,MAAM,WAAW,KAAK,IAAI,OAAO,GAAG,GAAG;AAEvC,QAAO,MAAM,cACX,KACA;EAAE,eAAe;EAAU,YAAY;EAAU,UAAU;EAAG,UAAU;EAAG,OAAO;EAAM,EACxF,MACA,MAAM,cAAc,MAAM;EAAE,OAAO;EAAe,MAAM;EAAM,EAAE,oCAAoC,EACpG,MAAM,cAAc,KAAK,EAAE,QAAQ,GAAG,CAAC,EACvC,MAAM,cACJ,WACA;EACE,aAAa;EACb,QAAQ,CAAC,QAAQ;EACjB,cAAc;EACd,aAAa;EACb,eAAe;EACf,UAAU;EACV,UAAU;EACV,OAAO;EACR,EACD,MAAM,cACJ,MACA;EAAE,OAAO;EAAQ,UAAU;EAAM,EACjC,SAAS,SAAS,QAAQ,QAAQ,MAAM,gBAAgB,OACzD,EACD,MAAM,cAAc,KAAK,EAAE,QAAQ,GAAG,CAAC,EACvC,QACD,CACF;;AAKH,SAAgB,UAAU;AACxB,QAAO,IAAI,SAAS,YAAY;EAC9B,MAAM,MAAM,OACV,MAAM,cAAc,YAAY,EAC9B,SAAS,aAAa;AACpB,OAAI,SAAS;AACb,WAAQ,EAAE,WAAW,QAAQ,SAAS,EAAE,CAAC;KAE5C,CAAC,EACF,EAAE,aAAa,OAAO,CACvB;GACD"}
|
|
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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"}
|