ultracontext 1.3.4 → 1.4.1
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 +34 -37
- 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,11 @@ 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
|
+
start Start daemon in background (no TUI)
|
|
33
|
+
stop Stop a running sync daemon
|
|
31
34
|
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
35
|
update Update CLI globally via npm/pnpm/bun
|
|
37
36
|
version Print version
|
|
38
37
|
help Show this help message
|
|
@@ -54,8 +53,8 @@ Options:
|
|
|
54
53
|
}
|
|
55
54
|
const NEEDS_KEY = new Set([
|
|
56
55
|
"",
|
|
57
|
-
"
|
|
58
|
-
"
|
|
56
|
+
"sync",
|
|
57
|
+
"start"
|
|
59
58
|
]);
|
|
60
59
|
async function runOnboarding() {
|
|
61
60
|
const { onboard } = await import("./onboarding.mjs");
|
|
@@ -245,7 +244,7 @@ function runUpdate(rawArgs) {
|
|
|
245
244
|
console.log(` ${green}●${r} ${d}Restarting daemon...${r}`);
|
|
246
245
|
const startCode = runCliSubcommand("start");
|
|
247
246
|
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
|
|
247
|
+
} else if (wasRunning) console.log(` ${gray}○${r} ${d}Daemon was stopped. Run:${r} ${cyan}ultracontext sync${r}`);
|
|
249
248
|
console.log("");
|
|
250
249
|
}
|
|
251
250
|
const SKIP_UPDATE_CHECK = new Set([
|
|
@@ -255,8 +254,7 @@ const SKIP_UPDATE_CHECK = new Set([
|
|
|
255
254
|
"upgrade",
|
|
256
255
|
"help",
|
|
257
256
|
"h",
|
|
258
|
-
"stop"
|
|
259
|
-
"status"
|
|
257
|
+
"stop"
|
|
260
258
|
]);
|
|
261
259
|
async function fetchLatestVersion() {
|
|
262
260
|
const controller = new AbortController();
|
|
@@ -289,23 +287,20 @@ async function checkForUpdate() {
|
|
|
289
287
|
const latest = await fetchLatestVersion();
|
|
290
288
|
if (latest && isNewer(latest, current)) printUpdateNotice(current, latest);
|
|
291
289
|
}
|
|
292
|
-
async function
|
|
293
|
-
const { launchDaemon } = await import("../launcher-
|
|
290
|
+
async function launchSyncDaemon() {
|
|
291
|
+
const { launchDaemon } = await import("../launcher-C_GUIW-o.mjs");
|
|
294
292
|
await launchDaemon({
|
|
295
|
-
entryPath: fileURLToPath(new URL("./sdk-
|
|
296
|
-
diagnosticsHint: "DAEMON_VERBOSE=1 ultracontext
|
|
293
|
+
entryPath: fileURLToPath(new URL("./sdk-sync.mjs", import.meta.url)),
|
|
294
|
+
diagnosticsHint: "DAEMON_VERBOSE=1 ultracontext sync"
|
|
297
295
|
});
|
|
298
296
|
}
|
|
299
297
|
async function runCtlSDK() {
|
|
300
|
-
const { runCtl } = await import("../ctl-
|
|
298
|
+
const { runCtl } = await import("../ctl-iHUR6By1.mjs");
|
|
301
299
|
await runCtl();
|
|
302
300
|
}
|
|
303
|
-
async function
|
|
304
|
-
const { tuiBoot } = await import("../tui-
|
|
305
|
-
await tuiBoot({
|
|
306
|
-
assetsRoot: path.resolve(__dirname, "..", ".."),
|
|
307
|
-
offlineNotice: "Daemon offline. Run: ultracontext start"
|
|
308
|
-
});
|
|
301
|
+
async function launchTui() {
|
|
302
|
+
const { tuiBoot } = await import("../tui-Df8--qZj.mjs");
|
|
303
|
+
await tuiBoot({ assetsRoot: path.resolve(__dirname, "..", "..") });
|
|
309
304
|
}
|
|
310
305
|
async function run() {
|
|
311
306
|
if (!SKIP_UPDATE_CHECK.has(command)) await checkForUpdate();
|
|
@@ -315,27 +310,24 @@ async function run() {
|
|
|
315
310
|
if (!process.env.ULTRACONTEXT_API_KEY) onboardResult = await runOnboarding();
|
|
316
311
|
}
|
|
317
312
|
switch (command) {
|
|
313
|
+
case "sync":
|
|
314
|
+
case "":
|
|
315
|
+
if (!isDaemonRunning()) await launchSyncDaemon();
|
|
316
|
+
if (onboardResult?.launchTui !== false) await launchTui();
|
|
317
|
+
break;
|
|
318
318
|
case "start":
|
|
319
|
-
await
|
|
320
|
-
if (onboardResult?.launchTui) await launchTuiSDK();
|
|
319
|
+
await launchSyncDaemon();
|
|
321
320
|
break;
|
|
322
321
|
case "stop":
|
|
323
322
|
process.argv[2] = "stop";
|
|
324
323
|
await runCtlSDK();
|
|
325
324
|
break;
|
|
326
|
-
case "status":
|
|
327
|
-
process.argv[2] = "status";
|
|
328
|
-
await runCtlSDK();
|
|
329
|
-
break;
|
|
330
325
|
case "config":
|
|
331
326
|
if ((await runOnboarding())?.launchTui) {
|
|
332
|
-
if (!isDaemonRunning()) await
|
|
333
|
-
await
|
|
327
|
+
if (!isDaemonRunning()) await launchSyncDaemon();
|
|
328
|
+
await launchTui();
|
|
334
329
|
}
|
|
335
330
|
break;
|
|
336
|
-
case "tui":
|
|
337
|
-
await launchTuiSDK();
|
|
338
|
-
break;
|
|
339
331
|
case "version":
|
|
340
332
|
case "v":
|
|
341
333
|
console.log(readVersion());
|
|
@@ -344,18 +336,23 @@ async function run() {
|
|
|
344
336
|
case "upgrade":
|
|
345
337
|
runUpdate(process.argv.slice(3));
|
|
346
338
|
break;
|
|
347
|
-
case "":
|
|
348
|
-
if (!isDaemonRunning()) await launchDaemonSDK();
|
|
349
|
-
await launchTuiSDK();
|
|
350
|
-
break;
|
|
351
339
|
case "help":
|
|
352
340
|
case "h":
|
|
353
341
|
printHelp();
|
|
354
342
|
break;
|
|
355
|
-
default:
|
|
343
|
+
default: {
|
|
344
|
+
const hint = {
|
|
345
|
+
tui: "The 'tui' command was removed. Use 'ultracontext sync' instead (TUI is now built-in).",
|
|
346
|
+
status: "The 'status' command was removed. The TUI shows daemon status automatically."
|
|
347
|
+
}[command];
|
|
348
|
+
if (hint) {
|
|
349
|
+
console.log(hint);
|
|
350
|
+
process.exit(0);
|
|
351
|
+
}
|
|
356
352
|
console.error(`Unknown command: ${process.argv[2]}`);
|
|
357
353
|
printHelp();
|
|
358
354
|
process.exit(1);
|
|
355
|
+
}
|
|
359
356
|
}
|
|
360
357
|
}
|
|
361
358
|
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 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 start Start daemon in background (no 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\", \"start\"]);\n\n// interactive onboarding wizard (Ink-based), returns { launchTui }\nasync function runOnboarding() {\n const { onboard } = await import(\"./onboarding.mjs\");\n return onboard();\n}\n\n// check if daemon is already running via lock file\nfunction isDaemonRunning() {\n try {\n const lockPath = path.join(process.env.HOME || process.env.USERPROFILE || \"~\", \".ultracontext\", \"daemon.lock\");\n const lock = JSON.parse(fs.readFileSync(lockPath, \"utf8\"));\n const pid = Number.parseInt(String(lock?.pid ?? \"\"), 10);\n if (!Number.isInteger(pid) || pid <= 1) return false;\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\n// try loading key from config file if env is empty\nfunction loadApiKeyFromConfig() {\n if (process.env.ULTRACONTEXT_API_KEY) return;\n try {\n const configPath = path.join(process.env.HOME || process.env.USERPROFILE || \"~\", \".ultracontext\", \"config.json\");\n const cfg = JSON.parse(fs.readFileSync(configPath, \"utf8\"));\n if (cfg.apiKey) process.env.ULTRACONTEXT_API_KEY = String(cfg.apiKey);\n } catch { /* no config */ }\n}\n\nfunction normalizeTag(value) {\n const trimmed = String(value ?? \"\").trim();\n if (!trimmed) return \"latest\";\n if (trimmed.startsWith(`${PACKAGE_NAME}@`)) return trimmed.slice(`${PACKAGE_NAME}@`.length);\n return trimmed;\n}\n\nfunction safeRealpath(targetPath) {\n try {\n return fs.realpathSync(targetPath);\n } catch {\n return path.resolve(targetPath);\n }\n}\n\nfunction pathsEqual(left, right) {\n return path.resolve(left) === path.resolve(right);\n}\n\nfunction runCapture(commandName, args) {\n const result = spawnSync(commandName, args, {\n env: process.env,\n encoding: \"utf8\",\n });\n return {\n ok: result.status === 0,\n stdout: String(result.stdout ?? \"\"),\n stderr: String(result.stderr ?? \"\"),\n };\n}\n\nfunction resolveBunGlobalRoot() {\n const home = process.env.HOME || process.env.USERPROFILE || os.homedir();\n const bunInstall = String(process.env.BUN_INSTALL ?? \"\").trim() || path.join(home, \".bun\");\n return path.join(bunInstall, \"install\", \"global\", \"node_modules\");\n}\n\nfunction detectGlobalInstallManager() {\n const packageRootReal = safeRealpath(packageRoot);\n const npmGlobalRoot = runCapture(\"npm\", [\"root\", \"-g\"]);\n if (npmGlobalRoot.ok) {\n const npmRoot = npmGlobalRoot.stdout.trim();\n if (npmRoot) {\n const npmExpected = safeRealpath(path.join(npmRoot, PACKAGE_NAME));\n if (pathsEqual(npmExpected, packageRootReal)) return \"npm\";\n }\n }\n\n const pnpmGlobalRoot = runCapture(\"pnpm\", [\"root\", \"-g\"]);\n if (pnpmGlobalRoot.ok) {\n const pnpmRoot = pnpmGlobalRoot.stdout.trim();\n if (pnpmRoot) {\n const pnpmExpected = safeRealpath(path.join(pnpmRoot, PACKAGE_NAME));\n if (pathsEqual(pnpmExpected, packageRootReal)) return \"pnpm\";\n }\n }\n\n const bunExpected = safeRealpath(path.join(resolveBunGlobalRoot(), PACKAGE_NAME));\n if (pathsEqual(bunExpected, packageRootReal)) return \"bun\";\n\n return null;\n}\n\nfunction parseUpdateOptions(args) {\n const opts = {\n tag: \"latest\",\n manager: null,\n restart: true,\n help: false,\n };\n\n for (let i = 0; i < args.length; i += 1) {\n const arg = String(args[i] ?? \"\").trim();\n if (!arg) continue;\n\n if (arg === \"-h\" || arg === \"--help\") {\n opts.help = true;\n continue;\n }\n\n if (arg === \"--no-restart\") {\n opts.restart = false;\n continue;\n }\n\n if (arg === \"--tag\") {\n const next = args[i + 1];\n if (!next || String(next).startsWith(\"-\")) {\n throw new Error(\"Missing value for --tag\");\n }\n opts.tag = normalizeTag(next);\n i += 1;\n continue;\n }\n\n if (arg === \"--manager\") {\n const next = String(args[i + 1] ?? \"\").trim().toLowerCase();\n if (!next || next.startsWith(\"-\")) {\n throw new Error(\"Missing value for --manager\");\n }\n if (![\"npm\", \"pnpm\", \"bun\"].includes(next)) {\n throw new Error(`Invalid --manager value: ${next}`);\n }\n opts.manager = next;\n i += 1;\n continue;\n }\n\n throw new Error(`Unknown update option: ${arg}`);\n }\n\n return opts;\n}\n\nfunction runCliSubcommand(subcommand) {\n const result = spawnSync(process.execPath, [cliWrapperPath, subcommand], {\n env: process.env,\n stdio: \"inherit\",\n });\n return result.status ?? 1;\n}\n\nfunction runGlobalUpdate(manager, tag) {\n const spec = `${PACKAGE_NAME}@${normalizeTag(tag)}`;\n const argvByManager = {\n npm: [\"npm\", [\"i\", \"-g\", spec]],\n pnpm: [\"pnpm\", [\"add\", \"-g\", spec]],\n bun: [\"bun\", [\"add\", \"-g\", spec]],\n };\n\n const tuple = argvByManager[manager];\n if (!tuple) {\n throw new Error(`Unsupported package manager: ${manager}`);\n }\n\n const [bin, args] = tuple;\n\n // skip postinstall to prevent launching a new instance mid-update\n const result = spawnSync(bin, args, {\n env: { ...process.env, ULTRACONTEXT_SKIP_POSTINSTALL: \"1\" },\n stdio: \"inherit\",\n });\n if (result.status !== 0) {\n throw new Error(`Update failed while running: ${bin} ${args.join(\" \")}`);\n }\n}\n\n// ── ANSI helpers ────────────────────────────────────────────────\n\nconst isTTY = process.stdout.isTTY;\nconst esc = (code) => (isTTY ? `\\x1b[${code}m` : \"\");\nconst r = esc(0);\nconst b = esc(1);\nconst d = esc(2);\nconst blue = esc(\"38;2;47;111;179\");\nconst green = esc(\"38;2;80;200;120\");\nconst red = esc(\"38;2;220;80;80\");\nconst cyan = esc(\"36\");\nconst gray = esc(\"38;5;245\");\n\nfunction runUpdate(rawArgs) {\n const opts = parseUpdateOptions(rawArgs);\n if (opts.help) {\n printUpdateHelp();\n return;\n }\n\n const manager = opts.manager ?? detectGlobalInstallManager();\n if (!manager) {\n throw new Error(\n \"Could not detect install manager for this CLI. Re-run with --manager <npm|pnpm|bun>.\",\n );\n }\n\n const previousVersion = readVersion();\n\n console.log(\"\");\n console.log(` ${blue}${b}UltraContext${r} ${d}Update${r}`);\n console.log(\"\");\n\n // stop daemon before update\n const wasRunning = isDaemonRunning();\n if (wasRunning && opts.restart) {\n console.log(` ${gray}○${r} ${d}Stopping daemon...${r}`);\n const stopCode = runCliSubcommand(\"stop\");\n if (stopCode !== 0) {\n throw new Error(`Failed to stop daemon before update (exit ${stopCode}).`);\n }\n }\n\n // run update\n console.log(` ${gray}↓${r} ${d}Updating via ${manager}${r} ${gray}(${PACKAGE_NAME}@${opts.tag})${r}`);\n runGlobalUpdate(manager, opts.tag);\n\n // read new version after update\n const newVersion = readVersion();\n console.log(\"\");\n console.log(` ${green}✓${r} ${b}Updated${r} ${gray}${previousVersion} → ${newVersion}${r}`);\n\n // restart daemon\n if (wasRunning && opts.restart) {\n console.log(` ${green}●${r} ${d}Restarting daemon...${r}`);\n const startCode = runCliSubcommand(\"start\");\n if (startCode !== 0) {\n throw new Error(`Update succeeded but daemon restart failed (exit ${startCode}).`);\n }\n } else if (wasRunning) {\n console.log(` ${gray}○${r} ${d}Daemon was stopped. Run:${r} ${cyan}ultracontext sync${r}`);\n }\n\n console.log(\"\");\n}\n\n// ── update check ────────────────────────────────────────────────\n\nconst SKIP_UPDATE_CHECK = new Set([\"version\", \"v\", \"update\", \"upgrade\", \"help\", \"h\", \"stop\"]);\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 // start: daemon background only (no TUI) — used by update restart flow\n case \"start\":\n await launchSyncDaemon();\n break;\n\n case \"stop\":\n process.argv[2] = \"stop\";\n await runCtlSDK();\n break;\n\n case \"config\": {\n const configResult = await runOnboarding();\n if (configResult?.launchTui) {\n if (!isDaemonRunning()) await launchSyncDaemon();\n await launchTui();\n }\n break;\n }\n\n case \"version\":\n case \"v\":\n console.log(readVersion());\n break;\n\n case \"update\":\n case \"upgrade\":\n runUpdate(process.argv.slice(3));\n break;\n\n case \"help\":\n case \"h\":\n printHelp();\n break;\n\n default: {\n // migration hints for removed commands\n const removed = {\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":"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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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"}
|