ultracontext 1.4.4 → 1.4.5
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/cli/entry.mjs
CHANGED
|
@@ -12,7 +12,7 @@ const command = (process.argv[2] ?? "").trim().toLowerCase().replace(/^--?/, "")
|
|
|
12
12
|
const subcommand = (process.argv[3] ?? "").trim().toLowerCase().replace(/^--?/, "");
|
|
13
13
|
const PACKAGE_NAME = "ultracontext";
|
|
14
14
|
const packageRoot = path.resolve(__dirname, "..", "..");
|
|
15
|
-
|
|
15
|
+
path.join(packageRoot, "ultracontext.mjs");
|
|
16
16
|
function readVersion() {
|
|
17
17
|
try {
|
|
18
18
|
const pkgPath = path.resolve(__dirname, "..", "..", "package.json");
|
|
@@ -170,12 +170,6 @@ function parseUpdateOptions(args) {
|
|
|
170
170
|
}
|
|
171
171
|
return opts;
|
|
172
172
|
}
|
|
173
|
-
function runCliSubcommand(subcommand) {
|
|
174
|
-
return spawnSync(process.execPath, [cliWrapperPath, subcommand], {
|
|
175
|
-
env: process.env,
|
|
176
|
-
stdio: "inherit"
|
|
177
|
-
}).status ?? 1;
|
|
178
|
-
}
|
|
179
173
|
function runGlobalUpdate(manager, tag) {
|
|
180
174
|
const spec = `${PACKAGE_NAME}@${normalizeTag(tag)}`;
|
|
181
175
|
const tuple = {
|
|
@@ -215,7 +209,7 @@ const green = esc("38;2;80;200;120");
|
|
|
215
209
|
esc("38;2;220;80;80");
|
|
216
210
|
const cyan = esc("36");
|
|
217
211
|
const gray = esc("38;5;245");
|
|
218
|
-
function runUpdate(rawArgs) {
|
|
212
|
+
async function runUpdate(rawArgs) {
|
|
219
213
|
const opts = parseUpdateOptions(rawArgs);
|
|
220
214
|
if (opts.help) {
|
|
221
215
|
printUpdateHelp();
|
|
@@ -230,8 +224,12 @@ function runUpdate(rawArgs) {
|
|
|
230
224
|
const wasRunning = isDaemonRunning();
|
|
231
225
|
if (wasRunning && opts.restart) {
|
|
232
226
|
console.log(` ${gray}○${r} ${d}Stopping daemon...${r}`);
|
|
233
|
-
|
|
234
|
-
|
|
227
|
+
try {
|
|
228
|
+
process.argv[2] = "stop";
|
|
229
|
+
await runCtlSDK();
|
|
230
|
+
} catch {
|
|
231
|
+
console.log(` ${gray}○${r} ${d}Could not stop daemon. Continuing update...${r}`);
|
|
232
|
+
}
|
|
235
233
|
}
|
|
236
234
|
console.log(` ${gray}↓${r} ${d}Updating via ${manager}${r} ${gray}(${PACKAGE_NAME}@${opts.tag})${r}`);
|
|
237
235
|
runGlobalUpdate(manager, opts.tag);
|
|
@@ -240,8 +238,11 @@ function runUpdate(rawArgs) {
|
|
|
240
238
|
console.log(` ${green}✓${r} ${b}Updated${r} ${gray}${previousVersion} → ${newVersion}${r}`);
|
|
241
239
|
if (wasRunning && opts.restart) {
|
|
242
240
|
console.log(` ${green}●${r} ${d}Restarting daemon...${r}`);
|
|
243
|
-
|
|
244
|
-
|
|
241
|
+
try {
|
|
242
|
+
await launchSyncDaemon();
|
|
243
|
+
} catch {
|
|
244
|
+
console.log(` ${gray}○${r} ${d}Auto-restart failed. Run:${r} ${cyan}ultracontext sync${r}`);
|
|
245
|
+
}
|
|
245
246
|
} else if (wasRunning) console.log(` ${gray}○${r} ${d}Daemon was stopped. Run:${r} ${cyan}ultracontext sync${r}`);
|
|
246
247
|
console.log("");
|
|
247
248
|
}
|
|
@@ -299,7 +300,7 @@ async function runCtlSDK() {
|
|
|
299
300
|
await runCtl();
|
|
300
301
|
}
|
|
301
302
|
async function launchTui() {
|
|
302
|
-
const { tuiBoot } = await import("../tui-
|
|
303
|
+
const { tuiBoot } = await import("../tui-qZlLkAXK.mjs");
|
|
303
304
|
await tuiBoot({ assetsRoot: path.resolve(__dirname, "..", "..") });
|
|
304
305
|
}
|
|
305
306
|
async function run() {
|
|
@@ -348,7 +349,7 @@ async function run() {
|
|
|
348
349
|
break;
|
|
349
350
|
case "update":
|
|
350
351
|
case "upgrade":
|
|
351
|
-
runUpdate(process.argv.slice(3));
|
|
352
|
+
await runUpdate(process.argv.slice(3));
|
|
352
353
|
break;
|
|
353
354
|
case "help":
|
|
354
355
|
case "h":
|
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 subcommand = (process.argv[3] ?? \"\").trim().toLowerCase().replace(/^--?/, \"\");\nconst PACKAGE_NAME = \"ultracontext\";\nconst packageRoot = path.resolve(__dirname, \"..\", \"..\");\nconst cliWrapperPath = path.join(packageRoot, \"ultracontext.mjs\");\n\n// resolve package version\nfunction readVersion() {\n try {\n const pkgPath = path.resolve(__dirname, \"..\", \"..\", \"package.json\");\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf8\"));\n return pkg.version ?? \"unknown\";\n } catch {\n return \"unknown\";\n }\n}\n\nfunction printHelp() {\n const version = readVersion();\n console.log(`ultracontext v${version}\n\nUsage: ultracontext [command] [options]\n\nCommands:\n (none) Start sync (daemon + TUI)\n sync Start sync (daemon + TUI)\n sync start Start daemon in background (no TUI)\n sync stop Stop a running daemon\n sync status Show daemon status\n config Run the setup wizard\n update Update CLI globally via npm/pnpm/bun\n version Print version\n help Show this help message\n\nEnvironment:\n ULTRACONTEXT_API_KEY Required. Your UltraContext API key.\n ULTRACONTEXT_BASE_URL API base URL (default: https://api.ultracontext.ai)\n`);\n}\n\nfunction printUpdateHelp() {\n console.log(`Usage: ultracontext update [options]\n\nOptions:\n --tag <dist-tag|version> Package tag/version (default: latest)\n --manager <npm|pnpm|bun> Force package manager (auto-detected by default)\n --no-restart Do not restart daemon after update\n -h, --help Show this help message\n`);\n}\n\n// commands that need an API key\nconst NEEDS_KEY = new Set([\"\", \"sync\"]);\n\n// interactive onboarding wizard (Ink-based), returns { launchTui }\nasync function runOnboarding() {\n const { onboard } = await import(\"./onboarding.mjs\");\n return onboard();\n}\n\n// check if daemon is already running via lock file\nfunction isDaemonRunning() {\n try {\n const lockPath = path.join(process.env.HOME || process.env.USERPROFILE || \"~\", \".ultracontext\", \"daemon.lock\");\n const lock = JSON.parse(fs.readFileSync(lockPath, \"utf8\"));\n const pid = Number.parseInt(String(lock?.pid ?? \"\"), 10);\n if (!Number.isInteger(pid) || pid <= 1) return false;\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\n// try loading key from config file if env is empty\nfunction loadApiKeyFromConfig() {\n if (process.env.ULTRACONTEXT_API_KEY) return;\n try {\n const configPath = path.join(process.env.HOME || process.env.USERPROFILE || \"~\", \".ultracontext\", \"config.json\");\n const cfg = JSON.parse(fs.readFileSync(configPath, \"utf8\"));\n if (cfg.apiKey) process.env.ULTRACONTEXT_API_KEY = String(cfg.apiKey);\n } catch { /* no config */ }\n}\n\nfunction normalizeTag(value) {\n const trimmed = String(value ?? \"\").trim();\n if (!trimmed) return \"latest\";\n if (trimmed.startsWith(`${PACKAGE_NAME}@`)) return trimmed.slice(`${PACKAGE_NAME}@`.length);\n return trimmed;\n}\n\nfunction safeRealpath(targetPath) {\n try {\n return fs.realpathSync(targetPath);\n } catch {\n return path.resolve(targetPath);\n }\n}\n\nfunction pathsEqual(left, right) {\n return path.resolve(left) === path.resolve(right);\n}\n\nfunction runCapture(commandName, args) {\n const result = spawnSync(commandName, args, {\n env: process.env,\n encoding: \"utf8\",\n });\n return {\n ok: result.status === 0,\n stdout: String(result.stdout ?? \"\"),\n stderr: String(result.stderr ?? \"\"),\n };\n}\n\nfunction resolveBunGlobalRoot() {\n const home = process.env.HOME || process.env.USERPROFILE || os.homedir();\n const bunInstall = String(process.env.BUN_INSTALL ?? \"\").trim() || path.join(home, \".bun\");\n return path.join(bunInstall, \"install\", \"global\", \"node_modules\");\n}\n\nfunction detectGlobalInstallManager() {\n const packageRootReal = safeRealpath(packageRoot);\n const npmGlobalRoot = runCapture(\"npm\", [\"root\", \"-g\"]);\n if (npmGlobalRoot.ok) {\n const npmRoot = npmGlobalRoot.stdout.trim();\n if (npmRoot) {\n const npmExpected = safeRealpath(path.join(npmRoot, PACKAGE_NAME));\n if (pathsEqual(npmExpected, packageRootReal)) return \"npm\";\n }\n }\n\n const pnpmGlobalRoot = runCapture(\"pnpm\", [\"root\", \"-g\"]);\n if (pnpmGlobalRoot.ok) {\n const pnpmRoot = pnpmGlobalRoot.stdout.trim();\n if (pnpmRoot) {\n const pnpmExpected = safeRealpath(path.join(pnpmRoot, PACKAGE_NAME));\n if (pathsEqual(pnpmExpected, packageRootReal)) return \"pnpm\";\n }\n }\n\n const bunExpected = safeRealpath(path.join(resolveBunGlobalRoot(), PACKAGE_NAME));\n if (pathsEqual(bunExpected, packageRootReal)) return \"bun\";\n\n return null;\n}\n\nfunction parseUpdateOptions(args) {\n const opts = {\n tag: \"latest\",\n manager: null,\n restart: true,\n help: false,\n };\n\n for (let i = 0; i < args.length; i += 1) {\n const arg = String(args[i] ?? \"\").trim();\n if (!arg) continue;\n\n if (arg === \"-h\" || arg === \"--help\") {\n opts.help = true;\n continue;\n }\n\n if (arg === \"--no-restart\") {\n opts.restart = false;\n continue;\n }\n\n if (arg === \"--tag\") {\n const next = args[i + 1];\n if (!next || String(next).startsWith(\"-\")) {\n throw new Error(\"Missing value for --tag\");\n }\n opts.tag = normalizeTag(next);\n i += 1;\n continue;\n }\n\n if (arg === \"--manager\") {\n const next = String(args[i + 1] ?? \"\").trim().toLowerCase();\n if (!next || next.startsWith(\"-\")) {\n throw new Error(\"Missing value for --manager\");\n }\n if (![\"npm\", \"pnpm\", \"bun\"].includes(next)) {\n throw new Error(`Invalid --manager value: ${next}`);\n }\n opts.manager = next;\n i += 1;\n continue;\n }\n\n throw new Error(`Unknown update option: ${arg}`);\n }\n\n return opts;\n}\n\nfunction runCliSubcommand(subcommand) {\n const result = spawnSync(process.execPath, [cliWrapperPath, subcommand], {\n env: process.env,\n stdio: \"inherit\",\n });\n return result.status ?? 1;\n}\n\nfunction runGlobalUpdate(manager, tag) {\n const spec = `${PACKAGE_NAME}@${normalizeTag(tag)}`;\n const argvByManager = {\n npm: [\"npm\", [\"i\", \"-g\", spec]],\n pnpm: [\"pnpm\", [\"add\", \"-g\", spec]],\n bun: [\"bun\", [\"add\", \"-g\", spec]],\n };\n\n const tuple = argvByManager[manager];\n if (!tuple) {\n throw new Error(`Unsupported package manager: ${manager}`);\n }\n\n const [bin, args] = tuple;\n\n // skip postinstall to prevent launching a new instance mid-update\n const result = spawnSync(bin, args, {\n env: { ...process.env, ULTRACONTEXT_SKIP_POSTINSTALL: \"1\" },\n stdio: \"inherit\",\n });\n if (result.status !== 0) {\n throw new Error(`Update failed while running: ${bin} ${args.join(\" \")}`);\n }\n}\n\n// ── ANSI helpers ────────────────────────────────────────────────\n\nconst isTTY = process.stdout.isTTY;\nconst esc = (code) => (isTTY ? `\\x1b[${code}m` : \"\");\nconst r = esc(0);\nconst b = esc(1);\nconst d = esc(2);\nconst blue = esc(\"38;2;47;111;179\");\nconst green = esc(\"38;2;80;200;120\");\nconst red = esc(\"38;2;220;80;80\");\nconst cyan = esc(\"36\");\nconst gray = esc(\"38;5;245\");\n\nfunction runUpdate(rawArgs) {\n const opts = parseUpdateOptions(rawArgs);\n if (opts.help) {\n printUpdateHelp();\n return;\n }\n\n const manager = opts.manager ?? detectGlobalInstallManager();\n if (!manager) {\n throw new Error(\n \"Could not detect install manager for this CLI. Re-run with --manager <npm|pnpm|bun>.\",\n );\n }\n\n const previousVersion = readVersion();\n\n console.log(\"\");\n console.log(` ${blue}${b}UltraContext${r} ${d}Update${r}`);\n console.log(\"\");\n\n // stop daemon before update\n const wasRunning = isDaemonRunning();\n if (wasRunning && opts.restart) {\n console.log(` ${gray}○${r} ${d}Stopping daemon...${r}`);\n const stopCode = runCliSubcommand(\"stop\");\n if (stopCode !== 0) {\n throw new Error(`Failed to stop daemon before update (exit ${stopCode}).`);\n }\n }\n\n // run update\n console.log(` ${gray}↓${r} ${d}Updating via ${manager}${r} ${gray}(${PACKAGE_NAME}@${opts.tag})${r}`);\n runGlobalUpdate(manager, opts.tag);\n\n // read new version after update\n const newVersion = readVersion();\n console.log(\"\");\n console.log(` ${green}✓${r} ${b}Updated${r} ${gray}${previousVersion} → ${newVersion}${r}`);\n\n // restart daemon\n if (wasRunning && opts.restart) {\n console.log(` ${green}●${r} ${d}Restarting daemon...${r}`);\n const startCode = runCliSubcommand(\"start\");\n if (startCode !== 0) {\n throw new Error(`Update succeeded but daemon restart failed (exit ${startCode}).`);\n }\n } else if (wasRunning) {\n console.log(` ${gray}○${r} ${d}Daemon was stopped. Run:${r} ${cyan}ultracontext sync${r}`);\n }\n\n console.log(\"\");\n}\n\n// ── update check ────────────────────────────────────────────────\n\nconst SKIP_UPDATE_CHECK = new Set([\"version\", \"v\", \"update\", \"upgrade\", \"help\", \"h\", \"stop\", \"sync\", \"\"]);\n\nasync function fetchLatestVersion() {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 5000);\n try {\n const res = await fetch(\"https://registry.npmjs.org/ultracontext/latest\", { signal: controller.signal });\n const data = await res.json();\n return data.version ?? null;\n } catch { return null; }\n finally { clearTimeout(timeout); }\n}\n\nfunction isNewer(latest, current) {\n const l = latest.split(\".\").map(Number);\n const c = current.split(\".\").map(Number);\n for (let i = 0; i < 3; i++) {\n if ((l[i] ?? 0) > (c[i] ?? 0)) return true;\n if ((l[i] ?? 0) < (c[i] ?? 0)) return false;\n }\n return false;\n}\n\nfunction printUpdateNotice(current, latest) {\n console.log(`\\n ${blue}${b}UltraContext${r} ${d}Update available${r}`);\n console.log(` ${gray}${current}${r} → ${green}${b}${latest}${r}`);\n console.log(` Run ${cyan}ultracontext update${r} to upgrade.\\n`);\n}\n\n// check on every invocation, no cache — like Claude Code\nasync function checkForUpdate() {\n const current = readVersion();\n if (current === \"unknown\") return;\n\n const latest = await fetchLatestVersion();\n if (latest && isNewer(latest, current)) {\n printUpdateNotice(current, latest);\n }\n}\n\n// ── launch helpers ──────────────────────────────────────────────\n\nasync function launchSyncDaemon() {\n const { launchDaemon } = await import(\"@ultracontext/sync/launcher\");\n await launchDaemon({\n entryPath: fileURLToPath(new URL(\"./sdk-sync.mjs\", import.meta.url)),\n diagnosticsHint: \"DAEMON_VERBOSE=1 ultracontext sync\",\n });\n}\n\nasync function runCtlSDK() {\n const { runCtl } = await import(\"@ultracontext/sync/ctl\");\n await runCtl();\n}\n\nasync function launchTui() {\n const { tuiBoot } = await import(\"@ultracontext/sync/tui\");\n await tuiBoot({\n assetsRoot: path.resolve(__dirname, \"..\", \"..\"),\n });\n}\n\n// ── main ────────────────────────────────────────────────────────\n\nasync function run() {\n // check for updates (silent on error, cached 24h)\n if (!SKIP_UPDATE_CHECK.has(command)) await checkForUpdate();\n\n // load saved key, then onboard if still missing\n let onboardResult = null;\n if (NEEDS_KEY.has(command)) {\n loadApiKeyFromConfig();\n if (!process.env.ULTRACONTEXT_API_KEY) onboardResult = await runOnboarding();\n }\n\n switch (command) {\n // sync: subcommand router\n case \"sync\":\n case \"\": {\n // sync start — daemon background only\n if (subcommand === \"start\") {\n await launchSyncDaemon();\n break;\n }\n\n // sync stop — stop daemon\n if (subcommand === \"stop\") {\n process.argv[2] = \"stop\";\n await runCtlSDK();\n break;\n }\n\n // sync status — show daemon status\n if (subcommand === \"status\") {\n process.argv[2] = \"status\";\n await runCtlSDK();\n break;\n }\n\n // bare sync (no subcommand) — daemon bg + TUI fg\n if (!isDaemonRunning()) await launchSyncDaemon();\n if (onboardResult?.launchTui !== false) await launchTui();\n break;\n }\n\n // legacy aliases — redirect to sync subcommands\n case \"start\":\n await launchSyncDaemon();\n break;\n\n case \"stop\":\n process.argv[2] = \"stop\";\n await runCtlSDK();\n break;\n\n case \"config\": {\n const configResult = await runOnboarding();\n if (configResult?.launchTui) {\n if (!isDaemonRunning()) await launchSyncDaemon();\n await launchTui();\n }\n break;\n }\n\n case \"version\":\n case \"v\":\n console.log(readVersion());\n break;\n\n case \"update\":\n case \"upgrade\":\n runUpdate(process.argv.slice(3));\n break;\n\n case \"help\":\n case \"h\":\n printHelp();\n break;\n\n default: {\n // migration hints for removed commands\n if (command === \"tui\") {\n console.log(\"The 'tui' command was removed. Use 'ultracontext sync' instead (TUI is now built-in).\");\n process.exit(0);\n }\n if (command === \"status\") {\n console.log(\"Use 'ultracontext sync status' instead.\");\n process.exit(0);\n }\n console.error(`Unknown command: ${process.argv[2]}`);\n printHelp();\n process.exit(1);\n }\n }\n}\n\nrun().catch((error) => {\n console.error(error instanceof Error ? error.message : String(error));\n process.exit(1);\n});\n"],"mappings":"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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 subcommand = (process.argv[3] ?? \"\").trim().toLowerCase().replace(/^--?/, \"\");\nconst PACKAGE_NAME = \"ultracontext\";\nconst packageRoot = path.resolve(__dirname, \"..\", \"..\");\nconst cliWrapperPath = path.join(packageRoot, \"ultracontext.mjs\");\n\n// resolve package version\nfunction readVersion() {\n try {\n const pkgPath = path.resolve(__dirname, \"..\", \"..\", \"package.json\");\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf8\"));\n return pkg.version ?? \"unknown\";\n } catch {\n return \"unknown\";\n }\n}\n\nfunction printHelp() {\n const version = readVersion();\n console.log(`ultracontext v${version}\n\nUsage: ultracontext [command] [options]\n\nCommands:\n (none) Start sync (daemon + TUI)\n sync Start sync (daemon + TUI)\n sync start Start daemon in background (no TUI)\n sync stop Stop a running daemon\n sync status Show daemon status\n config Run the setup wizard\n update Update CLI globally via npm/pnpm/bun\n version Print version\n help Show this help message\n\nEnvironment:\n ULTRACONTEXT_API_KEY Required. Your UltraContext API key.\n ULTRACONTEXT_BASE_URL API base URL (default: https://api.ultracontext.ai)\n`);\n}\n\nfunction printUpdateHelp() {\n console.log(`Usage: ultracontext update [options]\n\nOptions:\n --tag <dist-tag|version> Package tag/version (default: latest)\n --manager <npm|pnpm|bun> Force package manager (auto-detected by default)\n --no-restart Do not restart daemon after update\n -h, --help Show this help message\n`);\n}\n\n// commands that need an API key\nconst NEEDS_KEY = new Set([\"\", \"sync\"]);\n\n// interactive onboarding wizard (Ink-based), returns { launchTui }\nasync function runOnboarding() {\n const { onboard } = await import(\"./onboarding.mjs\");\n return onboard();\n}\n\n// check if daemon is already running via lock file\nfunction isDaemonRunning() {\n try {\n const lockPath = path.join(process.env.HOME || process.env.USERPROFILE || \"~\", \".ultracontext\", \"daemon.lock\");\n const lock = JSON.parse(fs.readFileSync(lockPath, \"utf8\"));\n const pid = Number.parseInt(String(lock?.pid ?? \"\"), 10);\n if (!Number.isInteger(pid) || pid <= 1) return false;\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\n// try loading key from config file if env is empty\nfunction loadApiKeyFromConfig() {\n if (process.env.ULTRACONTEXT_API_KEY) return;\n try {\n const configPath = path.join(process.env.HOME || process.env.USERPROFILE || \"~\", \".ultracontext\", \"config.json\");\n const cfg = JSON.parse(fs.readFileSync(configPath, \"utf8\"));\n if (cfg.apiKey) process.env.ULTRACONTEXT_API_KEY = String(cfg.apiKey);\n } catch { /* no config */ }\n}\n\nfunction normalizeTag(value) {\n const trimmed = String(value ?? \"\").trim();\n if (!trimmed) return \"latest\";\n if (trimmed.startsWith(`${PACKAGE_NAME}@`)) return trimmed.slice(`${PACKAGE_NAME}@`.length);\n return trimmed;\n}\n\nfunction safeRealpath(targetPath) {\n try {\n return fs.realpathSync(targetPath);\n } catch {\n return path.resolve(targetPath);\n }\n}\n\nfunction pathsEqual(left, right) {\n return path.resolve(left) === path.resolve(right);\n}\n\nfunction runCapture(commandName, args) {\n const result = spawnSync(commandName, args, {\n env: process.env,\n encoding: \"utf8\",\n });\n return {\n ok: result.status === 0,\n stdout: String(result.stdout ?? \"\"),\n stderr: String(result.stderr ?? \"\"),\n };\n}\n\nfunction resolveBunGlobalRoot() {\n const home = process.env.HOME || process.env.USERPROFILE || os.homedir();\n const bunInstall = String(process.env.BUN_INSTALL ?? \"\").trim() || path.join(home, \".bun\");\n return path.join(bunInstall, \"install\", \"global\", \"node_modules\");\n}\n\nfunction detectGlobalInstallManager() {\n const packageRootReal = safeRealpath(packageRoot);\n const npmGlobalRoot = runCapture(\"npm\", [\"root\", \"-g\"]);\n if (npmGlobalRoot.ok) {\n const npmRoot = npmGlobalRoot.stdout.trim();\n if (npmRoot) {\n const npmExpected = safeRealpath(path.join(npmRoot, PACKAGE_NAME));\n if (pathsEqual(npmExpected, packageRootReal)) return \"npm\";\n }\n }\n\n const pnpmGlobalRoot = runCapture(\"pnpm\", [\"root\", \"-g\"]);\n if (pnpmGlobalRoot.ok) {\n const pnpmRoot = pnpmGlobalRoot.stdout.trim();\n if (pnpmRoot) {\n const pnpmExpected = safeRealpath(path.join(pnpmRoot, PACKAGE_NAME));\n if (pathsEqual(pnpmExpected, packageRootReal)) return \"pnpm\";\n }\n }\n\n const bunExpected = safeRealpath(path.join(resolveBunGlobalRoot(), PACKAGE_NAME));\n if (pathsEqual(bunExpected, packageRootReal)) return \"bun\";\n\n return null;\n}\n\nfunction parseUpdateOptions(args) {\n const opts = {\n tag: \"latest\",\n manager: null,\n restart: true,\n help: false,\n };\n\n for (let i = 0; i < args.length; i += 1) {\n const arg = String(args[i] ?? \"\").trim();\n if (!arg) continue;\n\n if (arg === \"-h\" || arg === \"--help\") {\n opts.help = true;\n continue;\n }\n\n if (arg === \"--no-restart\") {\n opts.restart = false;\n continue;\n }\n\n if (arg === \"--tag\") {\n const next = args[i + 1];\n if (!next || String(next).startsWith(\"-\")) {\n throw new Error(\"Missing value for --tag\");\n }\n opts.tag = normalizeTag(next);\n i += 1;\n continue;\n }\n\n if (arg === \"--manager\") {\n const next = String(args[i + 1] ?? \"\").trim().toLowerCase();\n if (!next || next.startsWith(\"-\")) {\n throw new Error(\"Missing value for --manager\");\n }\n if (![\"npm\", \"pnpm\", \"bun\"].includes(next)) {\n throw new Error(`Invalid --manager value: ${next}`);\n }\n opts.manager = next;\n i += 1;\n continue;\n }\n\n throw new Error(`Unknown update option: ${arg}`);\n }\n\n return opts;\n}\n\nfunction runCliSubcommand(subcommand) {\n const result = spawnSync(process.execPath, [cliWrapperPath, subcommand], {\n env: process.env,\n stdio: \"inherit\",\n });\n return result.status ?? 1;\n}\n\nfunction runGlobalUpdate(manager, tag) {\n const spec = `${PACKAGE_NAME}@${normalizeTag(tag)}`;\n const argvByManager = {\n npm: [\"npm\", [\"i\", \"-g\", spec]],\n pnpm: [\"pnpm\", [\"add\", \"-g\", spec]],\n bun: [\"bun\", [\"add\", \"-g\", spec]],\n };\n\n const tuple = argvByManager[manager];\n if (!tuple) {\n throw new Error(`Unsupported package manager: ${manager}`);\n }\n\n const [bin, args] = tuple;\n\n // skip postinstall to prevent launching a new instance mid-update\n const result = spawnSync(bin, args, {\n env: { ...process.env, ULTRACONTEXT_SKIP_POSTINSTALL: \"1\" },\n stdio: \"inherit\",\n });\n if (result.status !== 0) {\n throw new Error(`Update failed while running: ${bin} ${args.join(\" \")}`);\n }\n}\n\n// ── ANSI helpers ────────────────────────────────────────────────\n\nconst isTTY = process.stdout.isTTY;\nconst esc = (code) => (isTTY ? `\\x1b[${code}m` : \"\");\nconst r = esc(0);\nconst b = esc(1);\nconst d = esc(2);\nconst blue = esc(\"38;2;47;111;179\");\nconst green = esc(\"38;2;80;200;120\");\nconst red = esc(\"38;2;220;80;80\");\nconst cyan = esc(\"36\");\nconst gray = esc(\"38;5;245\");\n\nasync function runUpdate(rawArgs) {\n const opts = parseUpdateOptions(rawArgs);\n if (opts.help) {\n printUpdateHelp();\n return;\n }\n\n const manager = opts.manager ?? detectGlobalInstallManager();\n if (!manager) {\n throw new Error(\n \"Could not detect install manager for this CLI. Re-run with --manager <npm|pnpm|bun>.\",\n );\n }\n\n const previousVersion = readVersion();\n\n console.log(\"\");\n console.log(` ${blue}${b}UltraContext${r} ${d}Update${r}`);\n console.log(\"\");\n\n // stop daemon before update (in-process, no subprocess)\n const wasRunning = isDaemonRunning();\n if (wasRunning && opts.restart) {\n console.log(` ${gray}○${r} ${d}Stopping daemon...${r}`);\n try {\n process.argv[2] = \"stop\";\n await runCtlSDK();\n } catch {\n console.log(` ${gray}○${r} ${d}Could not stop daemon. Continuing update...${r}`);\n }\n }\n\n // run update\n console.log(` ${gray}↓${r} ${d}Updating via ${manager}${r} ${gray}(${PACKAGE_NAME}@${opts.tag})${r}`);\n runGlobalUpdate(manager, opts.tag);\n\n // read new version after update\n const newVersion = readVersion();\n console.log(\"\");\n console.log(` ${green}✓${r} ${b}Updated${r} ${gray}${previousVersion} → ${newVersion}${r}`);\n\n // restart daemon in-process (no subprocess, no new terminal)\n if (wasRunning && opts.restart) {\n console.log(` ${green}●${r} ${d}Restarting daemon...${r}`);\n try {\n await launchSyncDaemon();\n } catch {\n console.log(` ${gray}○${r} ${d}Auto-restart failed. Run:${r} ${cyan}ultracontext sync${r}`);\n }\n } else if (wasRunning) {\n console.log(` ${gray}○${r} ${d}Daemon was stopped. Run:${r} ${cyan}ultracontext sync${r}`);\n }\n\n console.log(\"\");\n}\n\n// ── update check ────────────────────────────────────────────────\n\nconst SKIP_UPDATE_CHECK = new Set([\"version\", \"v\", \"update\", \"upgrade\", \"help\", \"h\", \"stop\", \"sync\", \"\"]);\n\nasync function fetchLatestVersion() {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 5000);\n try {\n const res = await fetch(\"https://registry.npmjs.org/ultracontext/latest\", { signal: controller.signal });\n const data = await res.json();\n return data.version ?? null;\n } catch { return null; }\n finally { clearTimeout(timeout); }\n}\n\nfunction isNewer(latest, current) {\n const l = latest.split(\".\").map(Number);\n const c = current.split(\".\").map(Number);\n for (let i = 0; i < 3; i++) {\n if ((l[i] ?? 0) > (c[i] ?? 0)) return true;\n if ((l[i] ?? 0) < (c[i] ?? 0)) return false;\n }\n return false;\n}\n\nfunction printUpdateNotice(current, latest) {\n console.log(`\\n ${blue}${b}UltraContext${r} ${d}Update available${r}`);\n console.log(` ${gray}${current}${r} → ${green}${b}${latest}${r}`);\n console.log(` Run ${cyan}ultracontext update${r} to upgrade.\\n`);\n}\n\n// check on every invocation, no cache — like Claude Code\nasync function checkForUpdate() {\n const current = readVersion();\n if (current === \"unknown\") return;\n\n const latest = await fetchLatestVersion();\n if (latest && isNewer(latest, current)) {\n printUpdateNotice(current, latest);\n }\n}\n\n// ── launch helpers ──────────────────────────────────────────────\n\nasync function launchSyncDaemon() {\n const { launchDaemon } = await import(\"@ultracontext/sync/launcher\");\n await launchDaemon({\n entryPath: fileURLToPath(new URL(\"./sdk-sync.mjs\", import.meta.url)),\n diagnosticsHint: \"DAEMON_VERBOSE=1 ultracontext sync\",\n });\n}\n\nasync function runCtlSDK() {\n const { runCtl } = await import(\"@ultracontext/sync/ctl\");\n await runCtl();\n}\n\nasync function launchTui() {\n const { tuiBoot } = await import(\"@ultracontext/sync/tui\");\n await tuiBoot({\n assetsRoot: path.resolve(__dirname, \"..\", \"..\"),\n });\n}\n\n// ── main ────────────────────────────────────────────────────────\n\nasync function run() {\n // check for updates (silent on error, cached 24h)\n if (!SKIP_UPDATE_CHECK.has(command)) await checkForUpdate();\n\n // load saved key, then onboard if still missing\n let onboardResult = null;\n if (NEEDS_KEY.has(command)) {\n loadApiKeyFromConfig();\n if (!process.env.ULTRACONTEXT_API_KEY) onboardResult = await runOnboarding();\n }\n\n switch (command) {\n // sync: subcommand router\n case \"sync\":\n case \"\": {\n // sync start — daemon background only\n if (subcommand === \"start\") {\n await launchSyncDaemon();\n break;\n }\n\n // sync stop — stop daemon\n if (subcommand === \"stop\") {\n process.argv[2] = \"stop\";\n await runCtlSDK();\n break;\n }\n\n // sync status — show daemon status\n if (subcommand === \"status\") {\n process.argv[2] = \"status\";\n await runCtlSDK();\n break;\n }\n\n // bare sync (no subcommand) — daemon bg + TUI fg\n if (!isDaemonRunning()) await launchSyncDaemon();\n if (onboardResult?.launchTui !== false) await launchTui();\n break;\n }\n\n // legacy aliases — redirect to sync subcommands\n case \"start\":\n await launchSyncDaemon();\n break;\n\n case \"stop\":\n process.argv[2] = \"stop\";\n await runCtlSDK();\n break;\n\n case \"config\": {\n const configResult = await runOnboarding();\n if (configResult?.launchTui) {\n if (!isDaemonRunning()) await launchSyncDaemon();\n await launchTui();\n }\n break;\n }\n\n case \"version\":\n case \"v\":\n console.log(readVersion());\n break;\n\n case \"update\":\n case \"upgrade\":\n await runUpdate(process.argv.slice(3));\n break;\n\n case \"help\":\n case \"h\":\n printHelp();\n break;\n\n default: {\n // migration hints for removed commands\n if (command === \"tui\") {\n console.log(\"The 'tui' command was removed. Use 'ultracontext sync' instead (TUI is now built-in).\");\n process.exit(0);\n }\n if (command === \"status\") {\n console.log(\"Use 'ultracontext sync status' instead.\");\n process.exit(0);\n }\n console.error(`Unknown command: ${process.argv[2]}`);\n printHelp();\n process.exit(1);\n }\n }\n}\n\nrun().catch((error) => {\n console.error(error instanceof Error ? error.message : String(error));\n process.exit(1);\n});\n"],"mappings":"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"}
|
|
@@ -1631,7 +1631,6 @@ async function tuiBoot({ assetsRoot, onFatalError } = {}) {
|
|
|
1631
1631
|
description: "Play duck sound when the TUI detects a new context"
|
|
1632
1632
|
}
|
|
1633
1633
|
];
|
|
1634
|
-
const UPDATE_CHECK_INTERVAL = 10800 * 1e3;
|
|
1635
1634
|
function readTuiVersion() {
|
|
1636
1635
|
try {
|
|
1637
1636
|
const pkgPath = path.resolve(APP_ROOT, "package.json");
|
|
@@ -1640,21 +1639,6 @@ async function tuiBoot({ assetsRoot, onFatalError } = {}) {
|
|
|
1640
1639
|
return "unknown";
|
|
1641
1640
|
}
|
|
1642
1641
|
}
|
|
1643
|
-
function getUpdateCheckPath() {
|
|
1644
|
-
return path.join(os.homedir(), ".ultracontext", "update-check.json");
|
|
1645
|
-
}
|
|
1646
|
-
function readUpdateCache() {
|
|
1647
|
-
try {
|
|
1648
|
-
return JSON.parse(fs.readFileSync(getUpdateCheckPath(), "utf8"));
|
|
1649
|
-
} catch {
|
|
1650
|
-
return null;
|
|
1651
|
-
}
|
|
1652
|
-
}
|
|
1653
|
-
function writeUpdateCache(data) {
|
|
1654
|
-
try {
|
|
1655
|
-
fs.writeFileSync(getUpdateCheckPath(), JSON.stringify(data));
|
|
1656
|
-
} catch {}
|
|
1657
|
-
}
|
|
1658
1642
|
async function fetchLatestVersion() {
|
|
1659
1643
|
const controller = new AbortController();
|
|
1660
1644
|
const timeout = setTimeout(() => controller.abort(), 3e3);
|
|
@@ -1685,16 +1669,7 @@ async function tuiBoot({ assetsRoot, onFatalError } = {}) {
|
|
|
1685
1669
|
ui.updatePrompt.latestVersion = latest;
|
|
1686
1670
|
renderDashboard();
|
|
1687
1671
|
};
|
|
1688
|
-
const cache = readUpdateCache();
|
|
1689
|
-
if (cache?.lastCheck && Date.now() - cache.lastCheck < UPDATE_CHECK_INTERVAL) {
|
|
1690
|
-
if (cache.latestVersion && isNewerVersion(cache.latestVersion, current)) notifyUpdate(cache.latestVersion);
|
|
1691
|
-
return;
|
|
1692
|
-
}
|
|
1693
1672
|
const latest = await fetchLatestVersion();
|
|
1694
|
-
writeUpdateCache({
|
|
1695
|
-
lastCheck: Date.now(),
|
|
1696
|
-
latestVersion: latest
|
|
1697
|
-
});
|
|
1698
1673
|
if (latest && isNewerVersion(latest, current)) notifyUpdate(latest);
|
|
1699
1674
|
}
|
|
1700
1675
|
const UPDATE_PROMPT_OPTIONS = [{
|
|
@@ -3021,4 +2996,4 @@ async function tuiBoot({ assetsRoot, onFatalError } = {}) {
|
|
|
3021
2996
|
|
|
3022
2997
|
//#endregion
|
|
3023
2998
|
export { tuiBoot };
|
|
3024
|
-
//# sourceMappingURL=tui-
|
|
2999
|
+
//# sourceMappingURL=tui-qZlLkAXK.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tui-qZlLkAXK.mjs","names":["fs","fsSync","process"],"sources":["../../sync/src/ui/layout.mjs","../../sync/src/ui/input-handlers/bootstrap.mjs","../../sync/src/ui/input-handlers/menu.mjs","../../sync/src/ui/input-handlers/quit.mjs","../../sync/src/ui/input-handlers/resume-target.mjs","../../sync/src/ui/input-handlers/update-prompt.mjs","../../sync/src/ui/input-handlers/view-contexts.mjs","../../sync/src/ui/input-handlers/view-configs.mjs","../../sync/src/ui/input-handlers/view.mjs","../../sync/src/ui/input.mjs","../../sync/src/ui/format.mjs","../../sync/src/ui/state.mjs","../../sync/src/ui/components/Section.mjs","../../sync/src/ui/components/ClientsPanel.mjs","../../sync/src/ui/components/HeroLockup.mjs","../../sync/src/ui/components/MenuPanel.mjs","../../sync/src/ui/components/NarrowWidthPanel.mjs","../../sync/src/ui/panels/BootstrapPanel.mjs","../../sync/src/ui/panels/ConfigsContent.mjs","../../sync/src/ui/panels/ContextDetailContent.mjs","../../sync/src/ui/panels/ContextsContent.mjs","../../sync/src/ui/panels/HeaderPanel.mjs","../../sync/src/ui/panels/LogsContent.mjs","../../sync/src/ui/panels/RightPanel.mjs","../../sync/src/ui/panels/MainPanels.mjs","../../sync/src/ui/panels/ResumeTargetPanel.mjs","../../sync/src/ui/panels/UpdatePromptPanel.mjs","../../sync/src/ui/DaemonTui.mjs","../../sync/src/ui/controller.mjs","../../sync/src/tui.mjs"],"sourcesContent":["export function computeTuiLayout(stdoutColumns, stdoutRows) {\n const safeCols = Math.max(Math.floor(Number(stdoutColumns) || 0), 1);\n const safeRows = Math.max(Math.floor(Number(stdoutRows) || 0), 1);\n const minWideCols = 64;\n const isNarrowWidth = safeCols < minWideCols;\n const frameWidth = Math.max(safeCols - 2, 1);\n const narrowWidth = frameWidth;\n const containerWidth = frameWidth;\n const contentWidth = Math.max(containerWidth - 2, 1);\n\n const compactLayoutBreakpoint = 114;\n const isCompactLayout = contentWidth < compactLayoutBreakpoint;\n const sidebarWidth = contentWidth >= 140 ? 34 : contentWidth >= 112 ? 30 : 24;\n const fullBottomPanelHeight = Math.max(safeRows - 12, 6);\n const targetBottomPanelHeight = Math.max(Math.floor(fullBottomPanelHeight * 0.75), 6);\n const maxBottomPanelHeight = Math.max(safeRows - 7, 4);\n const bottomPanelHeight = Math.min(targetBottomPanelHeight, maxBottomPanelHeight);\n\n // Wide layout (left sidebar + right panel)\n const minMenuPanelHeight = Math.min(5, Math.max(bottomPanelHeight, 1));\n const minAgentsPanelHeight = 0;\n let menuPanelHeight = Math.max(Math.floor(bottomPanelHeight * 0.52), minMenuPanelHeight);\n if (menuPanelHeight > bottomPanelHeight - minAgentsPanelHeight) {\n menuPanelHeight = Math.max(bottomPanelHeight - minAgentsPanelHeight, minMenuPanelHeight);\n }\n const agentsPanelHeight = Math.max(bottomPanelHeight - menuPanelHeight, 0);\n const showClientsPanel = agentsPanelHeight >= 4;\n const rightPanelContentRows = Math.max(bottomPanelHeight - 5, 1);\n const rightPanelApproxWidth = Math.max(contentWidth - sidebarWidth - 3, 24);\n const rightPanelTextCols = Math.max(rightPanelApproxWidth - 12, 12);\n\n // Compact layout (stacked panels)\n // In compact mode, prioritize readability of the main view.\n let compactMenuPanelHeight = Math.min(Math.max(Math.floor(bottomPanelHeight * 0.28), 3), Math.max(bottomPanelHeight - 3, 1));\n let compactRemaining = Math.max(bottomPanelHeight - compactMenuPanelHeight, 1);\n let compactAgentsPanelHeight = compactRemaining >= 10 ? 5 : 0;\n let compactViewPanelHeight = Math.max(compactRemaining - compactAgentsPanelHeight, 1);\n if (compactMenuPanelHeight + compactAgentsPanelHeight + compactViewPanelHeight > bottomPanelHeight) {\n compactViewPanelHeight = Math.max(bottomPanelHeight - compactMenuPanelHeight - compactAgentsPanelHeight, 1);\n }\n if (compactMenuPanelHeight + compactAgentsPanelHeight + compactViewPanelHeight > bottomPanelHeight) {\n compactAgentsPanelHeight = 0;\n compactViewPanelHeight = Math.max(bottomPanelHeight - compactMenuPanelHeight, 1);\n }\n compactRemaining = Math.max(bottomPanelHeight - compactMenuPanelHeight, 1);\n if (compactViewPanelHeight > compactRemaining) compactViewPanelHeight = compactRemaining;\n const compactShowClientsPanel = compactAgentsPanelHeight >= 4;\n const compactRightPanelContentRows = Math.max(compactViewPanelHeight - 4, 1);\n const compactRightPanelTextCols = Math.max(contentWidth - 12, 12);\n\n return {\n minWideCols,\n isNarrowWidth,\n narrowWidth,\n containerWidth,\n contentWidth,\n isCompactLayout,\n sidebarWidth,\n bottomPanelHeight,\n menuPanelHeight,\n agentsPanelHeight,\n showClientsPanel,\n rightPanelContentRows,\n rightPanelTextCols,\n compactMenuPanelHeight,\n compactAgentsPanelHeight,\n compactShowClientsPanel,\n compactViewPanelHeight,\n compactRightPanelContentRows,\n compactRightPanelTextCols,\n };\n}\n","export function handleBootstrapInput({ input, key, actions, snapshot }) {\n if (key.upArrow) {\n actions.moveBootstrap?.(-1);\n return;\n }\n if (key.downArrow) {\n actions.moveBootstrap?.(1);\n return;\n }\n if (input === \"1\" || input === \"2\" || input === \"3\") {\n actions.chooseBootstrap?.(Number(input) - 1);\n return;\n }\n if (key.return || input === \" \") {\n actions.chooseBootstrap?.(snapshot.bootstrap?.selectedIndex ?? 0);\n }\n}\n","import { MENU_TABS } from \"../constants.mjs\";\n\nexport function handleMenuInput({ input, key, actions, menuIndex, setFocusMode, moveMenuIndex }) {\n const activeTab = MENU_TABS[Math.max(Number(menuIndex) || 0, 0)]?.id ?? \"logs\";\n if ((input === \"r\" || input === \"R\") && activeTab === \"contexts\") {\n actions.refreshResume?.();\n return;\n }\n\n if (key.upArrow) {\n moveMenuIndex(-1);\n return;\n }\n if (key.downArrow) {\n moveMenuIndex(1);\n return;\n }\n if (key.return || key.rightArrow) {\n actions.selectTab(menuIndex);\n setFocusMode(\"view\");\n }\n}\n\nexport function buildMoveMenuIndex(actions, setMenuIndex) {\n return (delta) => {\n setMenuIndex((prev) => {\n const base = Number.isInteger(prev) ? prev : 0;\n const next = Math.max(0, Math.min(base + delta, MENU_TABS.length - 1));\n if (next !== base) actions.selectTab(next);\n return next;\n });\n };\n}\n","export function isQuitInput(input, key) {\n return (key.ctrl && input === \"c\") || input === \"\\u0003\" || input === \"q\" || input === \"Q\";\n}\n","export function handleResumeTargetInput({ input, key, actions, snapshot }) {\n if (key.upArrow) {\n actions.moveResumeTarget?.(-1);\n return;\n }\n if (key.downArrow) {\n actions.moveResumeTarget?.(1);\n return;\n }\n if (input === \"1\" || input === \"2\" || input === \"3\") {\n actions.chooseResumeTarget?.(Number(input) - 1);\n return;\n }\n if (key.leftArrow || key.escape) {\n actions.cancelResumeTarget?.();\n return;\n }\n if (key.return || input === \" \") {\n actions.chooseResumeTarget?.(snapshot.resumeTargetPicker?.selectedIndex ?? 0);\n }\n}\n","export function handleUpdatePromptInput({ input, key, actions, snapshot }) {\n if (key.upArrow) {\n actions.moveUpdatePrompt?.(-1);\n return;\n }\n if (key.downArrow) {\n actions.moveUpdatePrompt?.(1);\n return;\n }\n if (input === \"1\" || input === \"2\") {\n actions.chooseUpdatePrompt?.(Number(input) - 1);\n return;\n }\n if (key.return || input === \" \") {\n actions.chooseUpdatePrompt?.(snapshot.updatePrompt?.selectedIndex ?? 0);\n }\n}\n","export function handleContextsViewInput({ input, key, actions, snapshot }) {\n const detailActive = snapshot?.detailView?.active;\n\n // ── detail mode ───────────────────────────────────────────────\n if (detailActive) {\n if (key.escape || key.leftArrow) {\n actions.closeDetail();\n return true;\n }\n if (key.upArrow) {\n actions.scrollDetail(-1);\n return true;\n }\n if (key.downArrow) {\n actions.scrollDetail(1);\n return true;\n }\n if (input === \"j\") {\n actions.scrollDetailLine(1);\n return true;\n }\n if (input === \"k\") {\n actions.scrollDetailLine(-1);\n return true;\n }\n if (input === \"r\") {\n actions.refreshDetail();\n return true;\n }\n return true;\n }\n\n // ── list mode ─────────────────────────────────────────────────\n if (key.upArrow) {\n actions.moveResume(-1);\n return true;\n }\n if (key.downArrow) {\n actions.moveResume(1);\n return true;\n }\n if (input === \"r\") {\n actions.refreshResume();\n return true;\n }\n if (key.return || input === \" \") {\n actions.enterContext();\n return true;\n }\n return false;\n}\n","export function handleConfigsViewInput({ input, key, actions }) {\n if (key.upArrow) {\n actions.moveConfig(-1);\n return true;\n }\n if (key.downArrow) {\n actions.moveConfig(1);\n return true;\n }\n if (key.return || key.rightArrow || input === \" \") {\n actions.toggleConfig();\n return true;\n }\n return false;\n}\n","import { handleContextsViewInput } from \"./view-contexts.mjs\";\nimport { handleConfigsViewInput } from \"./view-configs.mjs\";\n\nexport function handleViewInput({ input, key, actions, snapshot, selectedTabIndex, setFocusMode, setMenuIndex }) {\n // detail view captures Esc/← to close itself instead of leaving view mode\n if (snapshot.selectedTab === \"contexts\" && snapshot.detailView?.active) {\n handleContextsViewInput({ input, key, actions, snapshot });\n return;\n }\n\n if (key.leftArrow || key.escape) {\n setMenuIndex(selectedTabIndex);\n setFocusMode(\"menu\");\n return;\n }\n\n if (snapshot.selectedTab === \"contexts\") {\n handleContextsViewInput({ input, key, actions, snapshot });\n return;\n }\n\n if (snapshot.selectedTab === \"configs\") {\n handleConfigsViewInput({ input, key, actions });\n }\n}\n","import {\n handleBootstrapInput,\n buildMoveMenuIndex,\n handleMenuInput,\n handleResumeTargetInput,\n handleUpdatePromptInput,\n handleViewInput,\n isQuitInput,\n} from \"./input-handlers/index.mjs\";\n\nexport { buildMoveMenuIndex } from \"./input-handlers/index.mjs\";\n\nexport function createInputHandler({\n snapshot,\n actions,\n focusMode,\n menuIndex,\n selectedTabIndex,\n setFocusMode,\n setMenuIndex,\n moveMenuIndex,\n bootstrapActive,\n updatePromptActive,\n resumeTargetPickerActive,\n}) {\n return (input, key) => {\n if (isQuitInput(input, key)) {\n actions.stop();\n return;\n }\n\n // update prompt has highest priority\n if (updatePromptActive) {\n handleUpdatePromptInput({ input, key, actions, snapshot });\n return;\n }\n if (bootstrapActive) {\n handleBootstrapInput({ input, key, actions, snapshot });\n return;\n }\n if (resumeTargetPickerActive) {\n handleResumeTargetInput({ input, key, actions, snapshot });\n return;\n }\n if (focusMode === \"menu\") {\n handleMenuInput({ input, key, actions, menuIndex, setFocusMode, moveMenuIndex });\n return;\n }\n\n handleViewInput({\n input,\n key,\n actions,\n snapshot,\n selectedTabIndex,\n setFocusMode,\n setMenuIndex,\n });\n };\n}\n","import React from \"react\";\nimport { Text } from \"ink\";\n\nimport { UC_CLAUDE_ORANGE, UC_CODEX_BLUE, UC_OPENCLAW_RED } from \"./constants.mjs\";\n\nexport function compact(value, max = 80) {\n const raw = String(value ?? \"\");\n if (raw.length <= max) return raw;\n if (max <= 3) return raw.slice(0, max);\n return `${raw.slice(0, max - 3)}...`;\n}\n\nexport function formatTime(value = Date.now()) {\n return new Date(value).toISOString().slice(11, 19);\n}\n\nexport function formatContextDate(value) {\n if (!value) return \"-\";\n const d = new Date(value);\n if (Number.isNaN(d.getTime())) return \"-\";\n const yyyy = String(d.getFullYear()).padStart(4, \"0\");\n const mm = String(d.getMonth() + 1).padStart(2, \"0\");\n const dd = String(d.getDate()).padStart(2, \"0\");\n const hh = String(d.getHours()).padStart(2, \"0\");\n const mi = String(d.getMinutes()).padStart(2, \"0\");\n return `${yyyy}-${mm}-${dd} ${hh}:${mi}`;\n}\n\nexport function levelColor(level) {\n if (level === \"error\") return \"red\";\n if (level === \"warn\") return \"yellow\";\n if (level === \"info\") return \"green\";\n return \"cyan\";\n}\n\nexport function sourceColor(source) {\n const normalized = String(source ?? \"\").trim().toLowerCase();\n if (normalized === \"claude\" || normalized === \"claude code\") return UC_CLAUDE_ORANGE;\n if (normalized === \"codex\") return UC_CODEX_BLUE;\n if (normalized === \"openclaw\") return UC_OPENCLAW_RED;\n return \"gray\";\n}\n\nexport function sourceLabel(source) {\n const normalized = String(source ?? \"\").trim().toLowerCase();\n if (normalized === \"claude\" || normalized === \"claude code\") return \"Claude Code\";\n if (normalized === \"codex\") return \"Codex\";\n if (normalized === \"openclaw\") return \"OpenClaw\";\n return String(source ?? \"\");\n}\n\nexport function contextBadge(source) {\n const normalized = String(source ?? \"\").trim().toLowerCase();\n if (normalized === \"codex\") return { text: \"Codex\", color: sourceColor(\"codex\") };\n if (normalized === \"claude\" || normalized === \"claude code\") {\n return { text: \"Claude Code\", color: sourceColor(\"claude\") };\n }\n if (normalized === \"openclaw\") {\n return { text: \"OpenClaw\", color: sourceColor(\"openclaw\") };\n }\n const label = sourceLabel(source) || \"Unknown\";\n return { text: `Context: ${label}`, color: \"gray\" };\n}\n\nexport function fitToWidth(text, width) {\n const raw = String(text ?? \"\");\n if (width <= 0) return \"\";\n if (raw.length <= width) return raw;\n if (width === 1) return raw.slice(0, 1);\n return `${raw.slice(0, width - 1)}…`;\n}\n\nexport function padElements(elements, maxRows, keyPrefix) {\n const rows = elements.slice(0, Math.max(maxRows, 0));\n while (rows.length < maxRows) {\n rows.push(React.createElement(Text, { key: `${keyPrefix}-pad-${rows.length}` }, \" \"));\n }\n return rows;\n}\n\nexport function centerText(text, width, bias = 0) {\n const fitted = fitToWidth(text, width);\n const centeredLeft = Math.floor((width - fitted.length) / 2);\n const left = Math.max(centeredLeft + bias, 0);\n const right = Math.max(width - fitted.length - left, 0);\n return `${\" \".repeat(left)}${fitted}${\" \".repeat(right)}`;\n}\n","import { MENU_TABS } from \"./constants.mjs\";\n\nexport function selectedTabIndexFromId(tabId) {\n return Math.max(\n MENU_TABS.findIndex((tab) => tab.id === tabId),\n 0\n );\n}\n\nexport function selectedTabTitle(tabId) {\n return MENU_TABS.find((tab) => tab.id === tabId)?.label ?? \"View\";\n}\n\nexport function footerHelpText({ updatePromptActive, bootstrapActive, resumeTargetPickerActive, detailViewActive, selectedTab, focusMode }) {\n if (updatePromptActive) {\n return \"Update: ↑/↓ select, 1/2, Enter to confirm, q to quit.\";\n }\n if (bootstrapActive) {\n return \"Bootstrap: choose initial mode (↑/↓, 1/2/3, Enter) or q to quit.\";\n }\n if (resumeTargetPickerActive) {\n return \"Resume target: choose Claude Code or Codex (↑/↓, 1/2, Enter), Esc/← cancel.\";\n }\n if (focusMode !== \"view\") {\n return \"Controls: ↑/↓ navigate, Enter focus/open, ← back, q/Ctrl+C quit.\";\n }\n if (selectedTab === \"contexts\" && detailViewActive) {\n return \"Detail: ↑/↓ messages, j/k lines, r refresh, Esc/← back.\";\n }\n if (selectedTab === \"contexts\") {\n return \"Contexts: ↑/↓ select, Enter open, r refresh, ← back, q/Ctrl+C quit.\";\n }\n if (selectedTab === \"configs\") {\n return \"Controls: ↑/↓ select config, Enter/→ apply, ← back, q/Ctrl+C quit.\";\n }\n return \"Controls: ↑/↓ navigate, Enter focus/open, ← back, q/Ctrl+C quit.\";\n}\n","import React from \"react\";\nimport { TitledBox } from \"@mishieck/ink-titled-box\";\n\nexport function Section({\n title,\n width,\n grow,\n height,\n children,\n marginRight = 0,\n borderColor = \"blue\",\n titleColor = \"cyan\",\n borderStyle = \"single\",\n paddingX = 2,\n paddingY = 1,\n}) {\n return React.createElement(\n TitledBox,\n {\n key: `section:${title}:${width ?? \"auto\"}:${height ?? \"auto\"}:${paddingX}:${paddingY}:${borderStyle}`,\n borderStyle,\n titles: [title],\n titleJustify: \"flex-start\",\n borderColor,\n flexDirection: \"column\",\n paddingX,\n paddingY,\n width,\n flexGrow: grow ? 1 : 0,\n height,\n flexShrink: 0,\n marginRight,\n },\n children\n );\n}\n","import React from \"react\";\nimport { Text } from \"ink\";\n\nimport { compact } from \"../format.mjs\";\nimport { fitToWidth } from \"../format.mjs\";\nimport { Section } from \"./Section.mjs\";\n\nconst CLIENTS_PADDING_X = 2;\nconst CLIENTS_PADDING_Y = 1;\nconst CLIENTS_HORIZONTAL_FRAME = 4;\nconst CLIENTS_VERTICAL_FRAME = 2;\nconst SPARK_CHARS = \"▁▂▃▄▅▆▇█\";\n\nfunction formatLag(ms) {\n const safeMs = Math.max(Number(ms) || 0, 0);\n const totalSeconds = Math.floor(safeMs / 1000);\n if (totalSeconds < 60) return `${totalSeconds}s`;\n const minutes = Math.floor(totalSeconds / 60);\n if (minutes < 60) return `${minutes}m`;\n const hours = Math.floor(minutes / 60);\n return `${hours}h`;\n}\n\nfunction sparklineFromLag(history) {\n const values = Array.isArray(history) ? history : [];\n if (values.length === 0) return SPARK_CHARS[0];\n return values\n .map((lagMs) => {\n const normalized = 1 - Math.max(Math.min((Number(lagMs) || 0) / 10000, 1), 0);\n const index = Math.max(Math.min(Math.round(normalized * (SPARK_CHARS.length - 1)), SPARK_CHARS.length - 1), 0);\n return SPARK_CHARS[index];\n })\n .join(\"\");\n}\n\nfunction clientLabel(client) {\n return `${compact(client.userId ?? \"-\", 12)}@${compact(client.host ?? \"-\", 20)}`;\n}\n\nfunction compactClientLine(client, lagMs, sparkline, maxCols) {\n const base = `● ${clientLabel(client)} lag ${formatLag(lagMs)} ${sparkline}`;\n return fitToWidth(base, maxCols);\n}\n\nexport function ClientsPanel({ clients, now, height, width }) {\n const innerCols = Math.max((Number(width ?? 0) || 0) - CLIENTS_HORIZONTAL_FRAME - CLIENTS_PADDING_X * 2, 10);\n const estimatedRows = Math.max((Number(height ?? 0) || 0) - CLIENTS_VERTICAL_FRAME - CLIENTS_PADDING_Y * 2, 1);\n const nowTs = Number(now ?? Date.now()) || Date.now();\n const historyRef = React.useRef(new Map());\n\n const list = (Array.isArray(clients) ? clients : [])\n .map((client) => ({\n ...client,\n id: `${String(client?.userId ?? \"-\")}@${String(client?.host ?? \"-\")}`,\n lagMs: Math.max(nowTs - Number(client?.ts ?? nowTs), 0),\n }))\n .sort((a, b) => a.lagMs - b.lagMs);\n\n const activeClientIds = new Set();\n for (const client of list) {\n activeClientIds.add(client.id);\n const previous = historyRef.current.get(client.id) ?? [];\n const next = [...previous, client.lagMs].slice(-8);\n historyRef.current.set(client.id, next);\n }\n for (const key of [...historyRef.current.keys()]) {\n if (!activeClientIds.has(key)) historyRef.current.delete(key);\n }\n\n const rows = [];\n if (list.length === 0) {\n rows.push(\n React.createElement(\n Text,\n { key: \"clients-empty\", color: \"yellow\", wrap: \"truncate-end\" },\n fitToWidth(\"No clients online\", innerCols)\n )\n );\n } else if (estimatedRows < 4) {\n const first = list[0];\n const sparkline = sparklineFromLag(historyRef.current.get(first.id) ?? []);\n rows.push(\n React.createElement(\n Text,\n { key: `clients-compact-${first.id}`, color: \"white\", wrap: \"truncate-end\" },\n compactClientLine(first, first.lagMs, sparkline, innerCols)\n )\n );\n if (list.length > 1 && rows.length < estimatedRows) {\n rows.push(\n React.createElement(\n Text,\n { key: \"clients-compact-more\", color: \"gray\", dim: true, wrap: \"truncate-end\" },\n fitToWidth(`+${list.length - 1} more online`, innerCols)\n )\n );\n }\n } else {\n const maxVisibleClients = Math.max(Math.floor(estimatedRows / 2), 1);\n const visible = list.slice(0, maxVisibleClients);\n for (let index = 0; index < visible.length; index += 1) {\n const client = visible[index];\n const sparkline = sparklineFromLag(historyRef.current.get(client.id) ?? []);\n const head = fitToWidth(`● ${clientLabel(client)}`, innerCols);\n const detail = fitToWidth(`lag ${formatLag(client.lagMs)} · activity ${sparkline}`, innerCols);\n\n rows.push(\n React.createElement(\n Text,\n { key: `clients-head-${client.id}-${index}`, wrap: \"truncate-end\" },\n React.createElement(Text, { color: \"green\" }, \"● \"),\n React.createElement(Text, { color: \"white\" }, head.slice(2))\n )\n );\n if (rows.length < estimatedRows) {\n rows.push(\n React.createElement(Text, { key: `clients-detail-${client.id}-${index}`, color: \"gray\", dim: true, wrap: \"truncate-end\" }, detail)\n );\n }\n }\n if (list.length > visible.length && rows.length < estimatedRows) {\n rows.push(\n React.createElement(\n Text,\n { key: \"clients-more\", color: \"gray\", dim: true, wrap: \"truncate-end\" },\n fitToWidth(`+${list.length - visible.length} more online`, innerCols)\n )\n );\n }\n }\n\n return React.createElement(\n Section,\n {\n title: \"Clients\",\n height,\n width,\n borderColor: \"gray\",\n titleColor: \"white\",\n paddingX: CLIENTS_PADDING_X,\n paddingY: CLIENTS_PADDING_Y,\n },\n ...rows\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport { fitToWidth } from \"../format.mjs\";\nimport { heroArtForWidth } from \"../hero-art.mjs\";\n\nfunction clamp(value, min, max) {\n return Math.min(Math.max(value, min), max);\n}\n\nfunction centerAround(text, width, center) {\n const fitted = fitToWidth(text, width);\n const safeCenter = clamp(Math.floor(center), 0, Math.max(width - 1, 0));\n const maxLeft = Math.max(width - fitted.length, 0);\n const left = clamp(safeCenter - Math.floor(fitted.length / 2), 0, maxLeft);\n const right = Math.max(width - fitted.length - left, 0);\n return `${\" \".repeat(left)}${fitted}${\" \".repeat(right)}`;\n}\n\nexport function HeroLockup({ width, tagline, artCenterBias = 0 }) {\n const lockupWidth = Math.max(width, 8);\n const rawArtLines = heroArtForWidth(lockupWidth).map((line) => fitToWidth(String(line ?? \"\"), lockupWidth));\n const artBlockWidth = Math.max(...rawArtLines.map((line) => line.length), 0);\n const maxLeft = Math.max(lockupWidth - artBlockWidth, 0);\n const artLeft = clamp(Math.floor((lockupWidth - artBlockWidth) / 2) + artCenterBias, 0, maxLeft);\n const artLines = rawArtLines.map((line) => fitToWidth(`${\" \".repeat(artLeft)}${line}`, lockupWidth));\n const taglineText = `[ ${tagline} ]`;\n const artCenter = artLeft + Math.floor(Math.max(artBlockWidth - 1, 0) / 2);\n const taglineLine = centerAround(taglineText, lockupWidth, artCenter);\n\n return React.createElement(\n Box,\n { flexDirection: \"column\", width: lockupWidth, alignItems: \"flex-start\", justifyContent: \"flex-start\" },\n ...artLines.map((line, index) =>\n React.createElement(Text, { key: `hero-${index}`, color: \"white\", bold: true }, line)\n ),\n React.createElement(Text, { color: \"white\" }, \" \"),\n React.createElement(Text, { color: \"blue\", bold: true }, taglineLine)\n );\n}\n","import React from \"react\";\nimport { Text } from \"ink\";\n\nimport { MENU_TABS, UC_BRAND_BLUE, UC_BLUE_LIGHT } from \"../constants.mjs\";\nimport { fitToWidth } from \"../format.mjs\";\nimport { Section } from \"./Section.mjs\";\n\nconst MENU_PADDING_X = 2;\nconst MENU_PADDING_Y = 1;\nconst MENU_HORIZONTAL_FRAME = 4;\nconst MENU_VERTICAL_FRAME = 2;\n\nexport function MenuPanel({ focusMode, menuIndex, selectedTab, height, width }) {\n const innerCols = Math.max(\n (Number(width ?? 0) || 0) - MENU_HORIZONTAL_FRAME - MENU_PADDING_X * 2,\n 10\n );\n const activeIndex = Math.max(\n focusMode === \"menu\" ? Number(menuIndex ?? 0) : MENU_TABS.findIndex((tab) => tab.id === selectedTab),\n 0\n );\n const estimatedRows = Math.max(\n (Number(height ?? 0) || 0) - MENU_VERTICAL_FRAME - MENU_PADDING_Y * 2,\n 1\n );\n const listCapacity = Math.max(Math.min(estimatedRows, MENU_TABS.length), 1);\n const start = Math.max(\n Math.min(activeIndex - Math.floor(listCapacity / 2), Math.max(MENU_TABS.length - listCapacity, 0)),\n 0\n );\n const end = Math.min(start + listCapacity, MENU_TABS.length);\n const visibleTabs = MENU_TABS.slice(start, end);\n\n return React.createElement(\n Section,\n {\n title: \"Menu\",\n width,\n height,\n borderColor: \"gray\",\n titleColor: \"white\",\n paddingX: MENU_PADDING_X,\n paddingY: MENU_PADDING_Y,\n },\n ...visibleTabs.map((tab, visibleIndex) => {\n const index = start + visibleIndex;\n const isFocusedInMenu = focusMode === \"menu\" && index === menuIndex;\n const isActiveInView = focusMode !== \"menu\" && index === activeIndex;\n const isHighlighted = isFocusedInMenu || isActiveInView;\n const marker = isHighlighted ? \"[•]\" : \"[ ]\";\n const markerColor = isHighlighted ? UC_BRAND_BLUE : \"white\";\n const labelColor = isHighlighted ? UC_BLUE_LIGHT : \"white\";\n const labelMax = Math.max(innerCols - marker.length - 1, 4);\n const label = fitToWidth(tab.label, labelMax);\n const lineLen = marker.length + 1 + label.length;\n const tailPad = \" \".repeat(Math.max(innerCols - lineLen, 0));\n\n return React.createElement(\n Text,\n { key: `menu-${tab.id}-${start}-${listCapacity}`, wrap: \"truncate-end\" },\n React.createElement(Text, { color: markerColor }, marker),\n \" \",\n React.createElement(Text, { color: labelColor, dim: !isHighlighted }, label),\n tailPad\n );\n })\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\nimport { TitledBox } from \"@mishieck/ink-titled-box\";\n\nimport { UC_BRAND_BLUE } from \"../constants.mjs\";\nimport { fitToWidth } from \"../format.mjs\";\n\nexport function NarrowWidthPanel({ minWideCols, narrowWidth, stdoutColumns }) {\n return React.createElement(\n Box,\n { flexDirection: \"column\" },\n React.createElement(\n TitledBox,\n {\n borderStyle: \"single\",\n titles: [\"UltraContext v1.1\"],\n titleJustify: \"flex-start\",\n borderColor: UC_BRAND_BLUE,\n flexDirection: \"column\",\n paddingX: 2,\n paddingY: 1,\n width: narrowWidth,\n },\n React.createElement(Text, { color: \"yellow\", bold: true, wrap: \"truncate-end\" }, \"Window too narrow\"),\n React.createElement(\n Text,\n { color: \"gray\", wrap: \"truncate-end\" },\n fitToWidth(`Resize terminal width to at least ${minWideCols} cols (current=${stdoutColumns}).`, Math.max(narrowWidth - 6, 12))\n )\n )\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\nimport { TitledBox } from \"@mishieck/ink-titled-box\";\n\nimport { UC_BLUE_LIGHT, UC_BRAND_BLUE } from \"../constants.mjs\";\n\nexport function BootstrapPanel({ snapshot, width }) {\n const options = snapshot.bootstrap?.options ?? [];\n const selectedIndex = Math.max(\n Math.min(snapshot.bootstrap?.selectedIndex ?? 0, Math.max(options.length - 1, 0)),\n 0\n );\n const sourceLabel = (snapshot.bootstrap?.sourceNames ?? []).join(\", \") || \"sources\";\n\n return React.createElement(\n TitledBox,\n {\n key: `bootstrap:${width}:${options.length}`,\n borderStyle: \"single\",\n titles: [\"First Sync Setup\"],\n titleJustify: \"flex-start\",\n borderColor: UC_BRAND_BLUE,\n flexDirection: \"column\",\n paddingX: 2,\n paddingY: 1,\n width,\n },\n React.createElement(Text, { color: \"white\", bold: true }, `How should sync start for: ${sourceLabel}?`),\n React.createElement(Box, { height: 1 }),\n ...options.map((option, index) => {\n const selected = index === selectedIndex;\n return React.createElement(\n Box,\n { key: `bootstrap-option-${option.id}`, flexDirection: \"column\" },\n React.createElement(\n Text,\n { color: selected ? UC_BLUE_LIGHT : \"white\" },\n selected ? \"[•]\" : \"[ ]\",\n ` ${index + 1}. ${option.label}`\n ),\n React.createElement(Text, { color: \"gray\" }, ` ${option.description}`)\n );\n }),\n React.createElement(Box, { height: 1 }),\n React.createElement(Text, { color: \"gray\" }, \"Choose: ↑/↓, 1/2/3 or Enter\")\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport { UC_BLUE_LIGHT } from \"../constants.mjs\";\nimport { compact, padElements } from \"../format.mjs\";\n\nexport function ConfigsContent({ snapshot, viewFocused, maxRows }) {\n const configItems = snapshot.configEditor?.items ?? [];\n const selectedConfigIndex = Math.max(\n Math.min(snapshot.configEditor?.selectedIndex ?? 0, Math.max(configItems.length - 1, 0)),\n 0\n );\n const rows = [];\n for (let index = 0; index < configItems.length; index += 1) {\n const item = configItems[index];\n const selected = index === selectedConfigIndex;\n const marker = selected ? \"[•]\" : \"[ ]\";\n const rowColor = selected && viewFocused ? UC_BLUE_LIGHT : \"white\";\n const status =\n item.kind === \"action\"\n ? item.valueLabel ?? \"RUN\"\n : item.kind === \"enum\"\n ? item.valueLabel ?? String(item.value ?? \"-\")\n : item.value ? \"ON\" : \"OFF\";\n const detail = item.blockedByMaster\n ? `${item.description ?? \"\"} (disabled while Master sounds is OFF)`\n : item.description ?? \"\";\n rows.push(\n React.createElement(\n Text,\n { key: `config-row-${item.key}`, color: rowColor },\n `${marker} ${item.label} [${status}]`\n )\n );\n if (detail) {\n rows.push(\n React.createElement(\n Text,\n { key: `config-detail-${item.key}`, color: item.blockedByMaster ? \"yellow\" : \"gray\" },\n compact(` ${detail}`, 130)\n )\n );\n }\n }\n\n if (rows.length === 0) {\n rows.push(React.createElement(Text, { key: \"config-empty\", color: \"yellow\" }, \"No editable configs found.\"));\n }\n if (snapshot.resume.notice) {\n rows.push(React.createElement(Text, { key: \"config-gap\" }, \" \"));\n rows.push(\n React.createElement(Text, { key: \"config-notice\", color: \"gray\" }, compact(`last action: ${snapshot.resume.notice}`, 130))\n );\n }\n\n return React.createElement(Box, { flexDirection: \"column\" }, ...padElements(rows, maxRows, \"cfg\"));\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport { compact, contextBadge, padElements } from \"../format.mjs\";\n\n// ── role helpers ─────────────────────────────────────────────────\n\nfunction roleColor(role) {\n if (role === \"user\") return \"green\";\n if (role === \"assistant\") return \"blue\";\n return \"gray\";\n}\n\nfunction normalizeRole(msg) {\n const role = String(msg?.role ?? \"system\").toLowerCase();\n if (role === \"user\" || role === \"human\") return \"user\";\n if (role === \"assistant\" || role === \"agent\") return \"assistant\";\n return \"system\";\n}\n\n// ── extract full message text (no truncation) ───────────────────\n\nfunction messageText(msg) {\n const content = msg?.content;\n if (typeof content === \"string\") return content;\n if (content && typeof content === \"object\") {\n if (typeof content.message === \"string\") return content.message;\n if (typeof content.text === \"string\") return content.text;\n return JSON.stringify(content, null, 2);\n }\n return \"\";\n}\n\nfunction messageTimestamp(msg) {\n const raw = msg?.content?.timestamp ?? msg?.metadata?.timestamp ?? \"\";\n if (!raw) return \"\";\n const d = new Date(raw);\n if (Number.isNaN(d.getTime())) return String(raw).slice(0, 5);\n const hh = String(d.getHours()).padStart(2, \"0\");\n const mm = String(d.getMinutes()).padStart(2, \"0\");\n return `${hh}:${mm}`;\n}\n\n// ── wrap a single line respecting maxWidth ──────────────────────\n\nfunction wrapLine(text, maxWidth) {\n if (!text) return [\"\"];\n const width = Math.max(maxWidth, 10);\n const lines = [];\n let remaining = text;\n while (remaining.length > width) {\n lines.push(remaining.slice(0, width));\n remaining = remaining.slice(width);\n }\n lines.push(remaining);\n return lines;\n}\n\n// ── build visual lines from messages ────────────────────────────\n\nfunction buildMessageLines(messages, maxWidth) {\n const lines = [];\n const separatorWidth = Math.max(maxWidth, 10);\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n const role = normalizeRole(msg);\n const ts = messageTimestamp(msg);\n const fullText = messageText(msg);\n const color = roleColor(role);\n\n // separator: ── role · HH:MM ──────────\n const label = ts ? `${role} · ${ts}` : role;\n const labelPart = `── ${label} `;\n const fillLen = Math.max(separatorWidth - labelPart.length, 0);\n const fill = \"─\".repeat(fillLen);\n lines.push({ type: \"separator\", color, label: `${labelPart}${fill}`, msgIndex: i });\n\n // split by real newlines, wrap each, preserve structure\n const rawLines = (fullText || \"(empty)\").split(/\\r?\\n/);\n for (const rawLine of rawLines) {\n for (const wrapped of wrapLine(rawLine, maxWidth)) {\n lines.push({ type: \"text\", text: wrapped, msgIndex: i });\n }\n }\n\n // blank line between messages\n if (i < messages.length - 1) {\n lines.push({ type: \"blank\", msgIndex: i });\n }\n }\n\n return lines;\n}\n\n// ── main component ──────────────────────────────────────────────\n\nexport function ContextDetailContent({ snapshot, maxRows, maxCols }) {\n const dv = snapshot.detailView;\n const textWidth = Math.max((maxCols ?? 60) - 2, 20);\n const rows = [];\n const totalMsgs = dv.messages.length;\n\n const source = dv.contextMeta?.source ?? \"unknown\";\n const badge = contextBadge(source);\n\n // header placeholder (filled after scroll info is known)\n const headerIdx = 0;\n rows.push(null);\n rows.push(React.createElement(Text, { key: \"detail-spacer\" }, \" \"));\n\n // loading state\n if (dv.loading) {\n rows[headerIdx] = renderHeader({ badge, dv, scrollInfo: \"loading...\" });\n rows.push(React.createElement(Text, { key: \"detail-loading\", color: \"yellow\" }, \"Loading messages...\"));\n return React.createElement(Box, { flexDirection: \"column\" }, ...padElements(rows, maxRows, \"dtl\"));\n }\n\n // error state\n if (dv.error) {\n rows[headerIdx] = renderHeader({ badge, dv, scrollInfo: \"error\" });\n rows.push(React.createElement(Text, { key: \"detail-error\", color: \"red\" }, `Error: ${dv.error}`));\n return React.createElement(Box, { flexDirection: \"column\" }, ...padElements(rows, maxRows, \"dtl\"));\n }\n\n // empty state\n if (totalMsgs === 0) {\n rows[headerIdx] = renderHeader({ badge, dv, scrollInfo: \"empty\" });\n rows.push(React.createElement(Text, { key: \"detail-empty\", color: \"gray\" }, \"No messages in this context.\"));\n return React.createElement(Box, { flexDirection: \"column\" }, ...padElements(rows, maxRows, \"dtl\"));\n }\n\n // build all visual lines\n const allLines = buildMessageLines(dv.messages, textWidth);\n const availableRows = Math.max(maxRows - rows.length, 1);\n\n // two-level scroll: ↑/↓ by message (scrollOffset), j/k by line (lineOffset)\n const targetMsg = Math.max(0, Math.min(dv.scrollOffset, totalMsgs - 1));\n let msgStartLine = 0;\n for (let i = 0; i < allLines.length; i++) {\n if (allLines[i].msgIndex === targetMsg) {\n msgStartLine = i;\n break;\n }\n }\n\n // apply fine line offset, clamped\n const maxScroll = Math.max(allLines.length - availableRows, 0);\n const startLine = Math.max(0, Math.min(msgStartLine + (dv.lineOffset ?? 0), maxScroll));\n\n // header with scroll info\n const msgLabel = `msg ${targetMsg + 1}/${totalMsgs}`;\n const pct = allLines.length > 0 ? Math.min(Math.round(((startLine + availableRows) / allLines.length) * 100), 100) : 100;\n rows[headerIdx] = renderHeader({ badge, dv, scrollInfo: `${msgLabel} ${pct}%` });\n\n // render visible slice\n const visibleLines = allLines.slice(startLine, startLine + availableRows);\n for (let i = 0; i < visibleLines.length; i++) {\n const line = visibleLines[i];\n if (line.type === \"separator\") {\n rows.push(React.createElement(Text, { key: `dtl-l-${i}`, color: line.color, bold: true }, line.label));\n } else if (line.type === \"text\") {\n rows.push(React.createElement(Text, { key: `dtl-l-${i}` }, line.text));\n } else {\n rows.push(React.createElement(Text, { key: `dtl-l-${i}` }, \" \"));\n }\n }\n\n return React.createElement(Box, { flexDirection: \"column\" }, ...padElements(rows, maxRows, \"dtl\"));\n}\n\n// ── header helper ───────────────────────────────────────────────\n\nfunction renderHeader({ badge, dv, scrollInfo }) {\n return React.createElement(\n Text,\n { key: \"detail-header\", wrap: \"truncate-end\" },\n React.createElement(Text, { color: badge.color, bold: true }, `[${badge.text}]`),\n React.createElement(Text, { color: \"gray\" }, ` ${compact(dv.contextId ?? \"\", 36)} `),\n React.createElement(Text, { color: \"cyan\" }, scrollInfo),\n React.createElement(Text, { color: \"gray\" }, \" ↑/↓ msg j/k line r refresh Esc back\")\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport { UC_BLUE_LIGHT } from \"../constants.mjs\";\nimport { compact, contextBadge, formatContextDate, padElements } from \"../format.mjs\";\nimport { ContextDetailContent } from \"./ContextDetailContent.mjs\";\n\nexport function ContextsContent({ snapshot, viewFocused, maxRows, maxCols }) {\n // detail view takes over the panel\n if (snapshot.detailView?.active) {\n return React.createElement(ContextDetailContent, { snapshot, maxRows, maxCols });\n }\n\n const contexts = snapshot.resume.contexts;\n const total = contexts.length;\n const selected = Math.max(Math.min(snapshot.resume.selectedIndex, Math.max(total - 1, 0)), 0);\n\n const rows = [];\n\n const tailRows = [];\n if (total > 0 && (snapshot.resume.notice || snapshot.resume.error || snapshot.resume.summaryPath || snapshot.resume.command)) {\n const selectedContext = contexts[selected];\n const selectedCreatedAt = formatContextDate(selectedContext?.created_at);\n const selectedInfo = contextBadge(selectedContext?.metadata?.source || \"unknown\");\n tailRows.push(\n React.createElement(\n Text,\n { key: \"contexts-selected\", color: \"gray\" },\n `selected: ${selectedCreatedAt} `,\n React.createElement(Text, { color: selectedInfo.color, bold: true }, `[${selectedInfo.text}]`),\n ` id=${compact(selectedContext?.id ?? \"-\", 36)}`\n )\n );\n }\n if (tailRows.length > 0) tailRows.push(React.createElement(Text, { key: \"contexts-spacer-1\" }, \" \"));\n if (snapshot.resume.notice) {\n tailRows.push(\n React.createElement(Text, { key: \"contexts-notice\", color: \"green\" }, `info: ${compact(snapshot.resume.notice, 120)}`)\n );\n }\n if (snapshot.resume.error) {\n tailRows.push(React.createElement(Text, { key: \"contexts-error\", color: \"red\" }, `error: ${compact(snapshot.resume.error, 120)}`));\n }\n if (snapshot.resume.summaryPath) {\n tailRows.push(\n React.createElement(Text, { key: \"contexts-summary\", color: \"gray\" }, `summary: ${compact(snapshot.resume.summaryPath, 120)}`)\n );\n }\n if (snapshot.resume.command) {\n tailRows.push(\n React.createElement(Text, { key: \"contexts-command\", color: \"gray\" }, `command: ${compact(snapshot.resume.command, 120)}`)\n );\n }\n if (snapshot.resume.commandPath) {\n tailRows.push(\n React.createElement(Text, { key: \"contexts-command-path\", color: \"gray\" }, `command file: ${compact(snapshot.resume.commandPath, 120)}`)\n );\n }\n\n const availableRows = Math.max(maxRows, 4);\n const listCapacity = Math.max(availableRows - tailRows.length, 1);\n\n if (total === 0) {\n rows.push(React.createElement(Text, { key: \"contexts-empty\", color: \"yellow\" }, \"No contexts available.\"));\n } else {\n const start = Math.max(Math.min(selected - Math.floor(listCapacity / 2), Math.max(total - listCapacity, 0)), 0);\n const end = Math.min(start + listCapacity, total);\n for (let i = start; i < end; i += 1) {\n const ctx = contexts[i];\n const md = ctx?.metadata ?? {};\n const rowSelected = i === selected;\n const marker = rowSelected ? \"[•]\" : \"[ ]\";\n const rowColor = viewFocused && rowSelected ? UC_BLUE_LIGHT : \"white\";\n const sourceInfo = contextBadge(md.source || \"unknown\");\n const createdAt = formatContextDate(ctx?.created_at);\n const user = compact(md.user_id ?? \"-\", 12);\n const sessionId = compact(md.session_id ?? \"-\", 28);\n rows.push(\n React.createElement(\n Text,\n { key: `contexts-row-${i}`, color: rowColor },\n `${marker} `,\n React.createElement(Text, { color: sourceInfo.color, bold: true }, `[${sourceInfo.text}]`),\n ` ${createdAt} ${user} ${sessionId}`\n )\n );\n }\n }\n rows.push(...tailRows);\n\n return React.createElement(Box, { flexDirection: \"column\" }, ...padElements(rows, maxRows, \"ctx\"));\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport Spinner from \"../../Spinner.mjs\";\nimport { HeroLockup } from \"../components/index.mjs\";\nimport { fitToWidth, formatTime } from \"../format.mjs\";\n\nfunction formatUptime(value) {\n const ms = Math.max(Number(value) || 0, 0);\n const totalSeconds = Math.floor(ms / 1000);\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n if (hours > 0) return `${hours}h${String(minutes).padStart(2, \"0\")}m`;\n if (minutes > 0) return `${minutes}m${String(seconds).padStart(2, \"0\")}s`;\n return `${seconds}s`;\n}\n\nexport function HeaderPanel({ snapshot, stdoutColumns }) {\n const [pulseOn, setPulseOn] = React.useState(true);\n\n React.useEffect(() => {\n const timer = setInterval(() => {\n setPulseOn((current) => !current);\n }, 320);\n timer.unref?.();\n return () => clearInterval(timer);\n }, []);\n\n const health = snapshot.stats.errors > 0 ? \"DEGRADED\" : \"HEALTHY\";\n const healthColor = health === \"HEALTHY\" ? \"green\" : \"yellow\";\n const tagline = \"Same context, everywhere\";\n const innerWidth = Math.max(stdoutColumns, 40);\n const spinnerVisualWidth = 28;\n const gap = innerWidth >= 96 ? 3 : 2;\n const artWidth = Math.max(innerWidth - spinnerVisualWidth - gap, 8);\n const statusPrefix = \"status \";\n const healthToken = `● ${health}`;\n const clientsOnline = Array.isArray(snapshot.onlineClients) ? snapshot.onlineClients.length : 0;\n const dashboardTail = [\n `live ${formatTime(snapshot.now)}`,\n `☻ ${snapshot.cfg.userId}`,\n `clients ${clientsOnline}`,\n `uptime ${formatUptime(Date.now() - Number(snapshot.stats.startedAt ?? 0))}`,\n ].join(\" │ \");\n const tailMax = Math.max(innerWidth - statusPrefix.length - healthToken.length - 3, 0);\n const fittedTail = fitToWidth(dashboardTail, tailMax);\n\n return React.createElement(\n Box,\n { flexDirection: \"column\", width: innerWidth },\n React.createElement(\n Box,\n { flexDirection: \"row\", alignItems: \"center\", width: innerWidth },\n React.createElement(Spinner, { color: \"white\" }),\n React.createElement(Box, { width: gap }),\n React.createElement(\n HeroLockup,\n { width: artWidth, tagline }\n )\n ),\n React.createElement(\n Box,\n { flexDirection: \"row\", width: innerWidth },\n React.createElement(Text, { color: \"gray\", dim: true }, statusPrefix),\n React.createElement(\n Text,\n { color: healthColor, bold: true },\n React.createElement(Text, { color: healthColor, dim: !pulseOn }, \"●\"),\n ` ${health}`\n ),\n fittedTail\n ? React.createElement(Text, { color: \"gray\", dim: true }, ` │ ${fittedTail}`)\n : null\n )\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport { fitToWidth, levelColor, padElements, sourceColor, sourceLabel } from \"../format.mjs\";\n\nfunction classifyLog(entry) {\n const text = String(entry?.text ?? \"\").toLowerCase();\n if (text.includes(\"bootstrap\")) return { label: \"BOOTSTRAP\", color: \"cyan\" };\n if (text.includes(\"config\")) return { label: \"CONFIG\", color: \"yellow\" };\n if (text.includes(\"daemon\") || text.includes(\"instance lock\")) return { label: \"DAEMON\", color: \"green\" };\n if (entry?.level === \"error\") return { label: \"ERROR\", color: \"red\" };\n if (entry?.level === \"warn\") return { label: \"WARN\", color: \"yellow\" };\n return { label: \"\", color: \"gray\" };\n}\n\nexport function LogsContent({ snapshot, maxRows, maxCols = 100 }) {\n const rows = [];\n const safeCols = Math.max(maxCols, 12);\n const visibleLogs = snapshot.recentLogs.slice(-Math.max(maxRows, 1)).reverse();\n\n if (visibleLogs.length === 0) {\n rows.push(\n React.createElement(Text, { key: \"log-empty\", color: \"gray\", wrap: \"truncate-end\" }, fitToWidth(\"waiting for activity...\", safeCols))\n );\n } else {\n rows.push(\n ...visibleLogs.map((entry, index) => {\n const category = classifyLog(entry);\n const sourceTag = entry.source ? `[${sourceLabel(entry.source)}]` : \"\";\n const timePrefix = `${String(entry.ts ?? \"--:--:--\")} `;\n const typePrefix = category.label ? `[${category.label}] ` : \"\";\n const sourcePrefix = sourceTag ? `${sourceTag} ` : \"\";\n const prefixWidth = 2 + 1 + timePrefix.length + typePrefix.length + sourcePrefix.length;\n const messageMax = Math.max(safeCols - prefixWidth, 8);\n const message = fitToWidth(String(entry.text ?? \"\"), messageMax);\n const messageColor = entry.level === \"warn\" || entry.level === \"error\" ? levelColor(entry.level) : \"white\";\n\n return React.createElement(\n Text,\n { key: `log-${index}`, wrap: \"truncate-end\" },\n React.createElement(Text, { color: category.color }, \"● \"),\n React.createElement(Text, { color: \"gray\", dim: true }, timePrefix),\n typePrefix\n ? React.createElement(Text, { color: category.color, bold: true }, typePrefix)\n : null,\n sourceTag\n ? React.createElement(Text, { color: sourceColor(entry.source), bold: true }, sourcePrefix)\n : null,\n React.createElement(Text, { color: messageColor }, message)\n );\n })\n );\n }\n\n return React.createElement(Box, { flexDirection: \"column\" }, ...padElements(rows, maxRows, \"log\"));\n}\n","import React from \"react\";\n\nimport { ConfigsContent } from \"./ConfigsContent.mjs\";\nimport { ContextsContent } from \"./ContextsContent.mjs\";\nimport { LogsContent } from \"./LogsContent.mjs\";\n\nexport function RightPanel({ snapshot, viewFocused, maxRows, maxCols }) {\n if (snapshot.selectedTab === \"configs\") return React.createElement(ConfigsContent, { snapshot, viewFocused, maxRows });\n if (snapshot.selectedTab === \"contexts\") return React.createElement(ContextsContent, { snapshot, viewFocused, maxRows, maxCols });\n return React.createElement(LogsContent, { snapshot, maxRows, maxCols });\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport { UC_BLUE_LIGHT, UC_BRAND_BLUE } from \"../constants.mjs\";\nimport { fitToWidth } from \"../format.mjs\";\nimport { selectedTabTitle } from \"../state.mjs\";\nimport { ClientsPanel, MenuPanel, Section } from \"../components/index.mjs\";\nimport { RightPanel } from \"./RightPanel.mjs\";\n\nfunction renderFocusedViewTop(width, title) {\n const safeWidth = Math.max(Number(width) || 0, 4);\n const innerWidth = Math.max(safeWidth - 2, 1);\n const paddedTitle = ` ${title} `;\n const shownTitle = fitToWidth(paddedTitle, innerWidth);\n const fillWidth = Math.max(innerWidth - shownTitle.length, 0);\n\n return React.createElement(\n Text,\n { color: UC_BRAND_BLUE, wrap: \"truncate-end\" },\n \"╔\",\n React.createElement(Text, { color: UC_BLUE_LIGHT, bold: true }, shownTitle),\n \"═\".repeat(fillWidth),\n \"╗\"\n );\n}\n\nfunction ViewSection({ snapshot, focusMode, width, grow, height, maxRows, maxCols }) {\n const viewFocused = focusMode === \"view\";\n const title = selectedTabTitle(snapshot.selectedTab);\n\n if (viewFocused) {\n return React.createElement(\n Box,\n { flexDirection: \"column\", width, flexGrow: grow ? 1 : 0, flexShrink: 0 },\n renderFocusedViewTop(width, title),\n React.createElement(\n Box,\n {\n borderStyle: \"double\",\n borderTop: false,\n borderColor: UC_BRAND_BLUE,\n flexDirection: \"column\",\n paddingX: 2,\n paddingY: 1,\n width,\n height,\n flexGrow: grow ? 1 : 0,\n flexShrink: 0,\n },\n React.createElement(RightPanel, {\n snapshot,\n viewFocused,\n maxRows,\n maxCols,\n })\n )\n );\n }\n\n return React.createElement(\n Section,\n {\n title,\n width,\n height,\n grow,\n borderColor: \"cyan\",\n titleColor: \"white\",\n borderStyle: \"double\",\n },\n React.createElement(RightPanel, {\n snapshot,\n viewFocused,\n maxRows,\n maxCols,\n })\n );\n}\n\nexport function MainPanels({ snapshot, layout, focusMode, menuIndex, clients }) {\n if (layout.isCompactLayout) {\n const clientsSection = layout.compactShowClientsPanel\n ? React.createElement(ClientsPanel, {\n clients,\n now: snapshot.now,\n height: layout.compactAgentsPanelHeight,\n width: layout.contentWidth,\n })\n : null;\n\n return React.createElement(\n Box,\n { flexDirection: \"column\", alignItems: \"flex-start\", width: layout.contentWidth },\n React.createElement(MenuPanel, {\n focusMode,\n menuIndex,\n selectedTab: snapshot.selectedTab,\n height: layout.compactMenuPanelHeight,\n width: layout.contentWidth,\n }),\n React.createElement(ViewSection, {\n snapshot,\n focusMode,\n width: layout.contentWidth,\n height: layout.compactViewPanelHeight,\n maxRows: layout.compactRightPanelContentRows,\n maxCols: layout.compactRightPanelTextCols,\n }),\n clientsSection\n );\n }\n\n const clientsSection = layout.showClientsPanel\n ? React.createElement(ClientsPanel, {\n clients,\n now: snapshot.now,\n height: layout.agentsPanelHeight,\n width: layout.sidebarWidth,\n })\n : null;\n\n const rightPanelWidth = Math.max(layout.contentWidth - layout.sidebarWidth, 20);\n\n return React.createElement(\n Box,\n { flexDirection: \"row\", alignItems: \"flex-start\", height: layout.bottomPanelHeight, width: layout.contentWidth },\n React.createElement(\n Box,\n { flexDirection: \"column\", width: layout.sidebarWidth, marginRight: 0, height: layout.bottomPanelHeight, flexShrink: 0 },\n React.createElement(MenuPanel, {\n focusMode,\n menuIndex,\n selectedTab: snapshot.selectedTab,\n height: layout.menuPanelHeight,\n width: layout.sidebarWidth,\n }),\n clientsSection\n ),\n React.createElement(ViewSection, {\n snapshot,\n focusMode,\n width: rightPanelWidth,\n height: layout.bottomPanelHeight,\n maxRows: layout.rightPanelContentRows,\n maxCols: layout.rightPanelTextCols,\n })\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\nimport { TitledBox } from \"@mishieck/ink-titled-box\";\n\nimport { UC_BLUE_LIGHT, UC_BRAND_BLUE } from \"../constants.mjs\";\nimport { compact, sourceColor, sourceLabel } from \"../format.mjs\";\n\nexport function ResumeTargetPanel({ snapshot, width }) {\n const picker = snapshot.resumeTargetPicker ?? {};\n const options = picker.options ?? [];\n const selectedIndex = Math.max(\n Math.min(picker.selectedIndex ?? 0, Math.max(options.length - 1, 0)),\n 0\n );\n const source = sourceLabel(picker.source || \"unknown\");\n const contextId = compact(picker.contextId ?? \"-\", 42);\n\n return React.createElement(\n TitledBox,\n {\n key: `resume-target:${width}:${options.length}`,\n borderStyle: \"single\",\n titles: [\"Continue Conversation\"],\n titleJustify: \"flex-start\",\n borderColor: UC_BRAND_BLUE,\n flexDirection: \"column\",\n paddingX: 2,\n paddingY: 1,\n width,\n },\n React.createElement(Text, { color: \"white\", bold: true }, \"Continue selected context in:\"),\n React.createElement(\n Text,\n { color: \"gray\" },\n `source=${source} id=${contextId}`\n ),\n React.createElement(Box, { height: 1 }),\n ...options.map((option, index) => {\n const selected = index === selectedIndex;\n return React.createElement(\n Text,\n { key: `resume-target-option-${option.id}`, color: selected ? UC_BLUE_LIGHT : \"white\" },\n selected ? \"[•]\" : \"[ ]\",\n \" \",\n React.createElement(Text, { color: sourceColor(option.id), bold: true }, option.label)\n );\n }),\n React.createElement(Box, { height: 1 }),\n React.createElement(Text, { color: \"gray\" }, `Choose: ↑/↓, ${options.map((_, i) => i + 1).join(\"/\")} or Enter`),\n React.createElement(Text, { color: \"gray\" }, \"Cancel: Esc or ←\")\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\nimport { TitledBox } from \"@mishieck/ink-titled-box\";\n\nimport { UC_BLUE_LIGHT, UC_BRAND_BLUE } from \"../constants.mjs\";\n\nexport function UpdatePromptPanel({ snapshot, width }) {\n const prompt = snapshot.updatePrompt ?? {};\n const options = prompt.options ?? [];\n const selectedIndex = Math.max(\n Math.min(prompt.selectedIndex ?? 0, Math.max(options.length - 1, 0)),\n 0\n );\n const current = snapshot.currentVersion ?? \"?\";\n const latest = prompt.latestVersion ?? \"?\";\n\n return React.createElement(\n TitledBox,\n {\n key: `update-prompt:${width}`,\n borderStyle: \"single\",\n titles: [\"Update Available\"],\n titleJustify: \"flex-start\",\n borderColor: UC_BRAND_BLUE,\n flexDirection: \"column\",\n paddingX: 2,\n paddingY: 1,\n width,\n },\n React.createElement(\n Text,\n { color: \"white\", bold: true },\n `New version available: `,\n React.createElement(Text, { color: \"gray\" }, `v${current}`),\n ` → `,\n React.createElement(Text, { color: \"green\", bold: true }, `v${latest}`)\n ),\n React.createElement(Box, { height: 1 }),\n ...options.map((option, index) => {\n const selected = index === selectedIndex;\n return React.createElement(\n Text,\n { key: `update-option-${option.id}`, color: selected ? UC_BLUE_LIGHT : \"white\" },\n selected ? \"[•]\" : \"[ ]\",\n ` ${index + 1}. ${option.label}`\n );\n }),\n React.createElement(Box, { height: 1 }),\n React.createElement(Text, { color: \"gray\" }, \"Choose: ↑/↓, 1/2 or Enter\")\n );\n}\n","import React from \"react\";\nimport { Box, Text, useInput, useStdout } from \"ink\";\n\nimport { UC_BLUE_LIGHT, UC_BRAND_BLUE } from \"./constants.mjs\";\nimport { computeTuiLayout } from \"./layout.mjs\";\nimport { buildMoveMenuIndex, createInputHandler } from \"./input.mjs\";\nimport { fitToWidth } from \"./format.mjs\";\nimport { footerHelpText, selectedTabIndexFromId } from \"./state.mjs\";\nimport { NarrowWidthPanel } from \"./components/index.mjs\";\nimport { BootstrapPanel, HeaderPanel, MainPanels, ResumeTargetPanel, UpdatePromptPanel } from \"./panels/index.mjs\";\n\nconst FOOTER_QUIPS = [\n \"Who is John Galt?\",\n \"ultrathink -> ultracontext\",\n \"Welcome to the beginning of infinity.\",\n \"Our job is to take the jobs.\",\n];\n\nfunction renderFooterQuip(quip) {\n const token = \"ultrathink\";\n const lower = String(quip ?? \"\").toLowerCase();\n const index = lower.indexOf(token);\n if (index < 0) {\n return React.createElement(Text, { color: \"gray\", bold: true }, quip);\n }\n\n const before = quip.slice(0, index);\n const match = quip.slice(index, index + token.length);\n const after = quip.slice(index + token.length);\n\n return React.createElement(\n Box,\n { flexDirection: \"row\", flexShrink: 0 },\n before ? React.createElement(Text, { key: \"quip-before\", color: \"gray\", bold: true }, before) : null,\n React.createElement(Text, { key: \"quip-strike\", color: \"gray\", bold: true, strikethrough: true }, match),\n after ? React.createElement(Text, { key: \"quip-after\", color: \"gray\", bold: true }, after) : null\n );\n}\n\nfunction renderMainFrameTop(width, title) {\n const safeWidth = Math.max(Number(width) || 0, 4);\n const innerWidth = Math.max(safeWidth - 2, 1);\n const paddedTitle = ` ${title} `;\n const shownTitle = fitToWidth(paddedTitle, innerWidth);\n const fillWidth = Math.max(innerWidth - shownTitle.length, 0);\n\n return React.createElement(\n Text,\n { color: UC_BRAND_BLUE, wrap: \"truncate-end\" },\n \"┌\",\n React.createElement(Text, { color: UC_BLUE_LIGHT, bold: true }, shownTitle),\n \"─\".repeat(fillWidth),\n \"┐\"\n );\n}\n\nexport function DaemonTui({ snapshot, actions }) {\n const { stdout } = useStdout();\n const [terminalSize, setTerminalSize] = React.useState(() => ({\n cols: stdout?.columns ?? process.stdout.columns ?? 120,\n rows: stdout?.rows ?? process.stdout.rows ?? 40,\n }));\n\n React.useEffect(() => {\n const target = stdout ?? process.stdout;\n if (!target) return;\n\n const update = () => {\n const next = {\n cols: Math.max(target.columns ?? process.stdout.columns ?? 120, 1),\n rows: Math.max(target.rows ?? process.stdout.rows ?? 40, 1),\n };\n setTerminalSize((current) => (current.cols === next.cols && current.rows === next.rows ? current : next));\n };\n\n update();\n target.on?.(\"resize\", update);\n return () => {\n if (typeof target.off === \"function\") {\n target.off(\"resize\", update);\n } else if (typeof target.removeListener === \"function\") {\n target.removeListener(\"resize\", update);\n }\n };\n }, [stdout]);\n\n const stdoutColumns = terminalSize.cols;\n const stdoutRows = terminalSize.rows;\n const layout = computeTuiLayout(stdoutColumns, stdoutRows);\n const selectedTabIndex = selectedTabIndexFromId(snapshot.selectedTab);\n\n const updatePromptActive = Boolean(snapshot.updatePrompt?.active);\n const bootstrapActive = Boolean(snapshot.bootstrap?.active);\n const resumeTargetPickerActive = Boolean(snapshot.resumeTargetPicker?.active);\n const [focusMode, setFocusMode] = React.useState(\"menu\");\n const [menuIndex, setMenuIndex] = React.useState(selectedTabIndex);\n const [quipIndex, setQuipIndex] = React.useState(0);\n\n React.useEffect(() => {\n if (focusMode === \"menu\") setMenuIndex(selectedTabIndex);\n }, [focusMode, selectedTabIndex]);\n\n React.useEffect(() => {\n const timer = setInterval(() => {\n setQuipIndex((current) => (current + 1) % FOOTER_QUIPS.length);\n }, 3800);\n return () => clearInterval(timer);\n }, []);\n\n const moveMenuIndex = React.useMemo(() => buildMoveMenuIndex(actions, setMenuIndex), [actions]);\n\n useInput(\n createInputHandler({\n snapshot,\n actions,\n focusMode,\n menuIndex,\n selectedTabIndex,\n setFocusMode,\n setMenuIndex,\n moveMenuIndex,\n bootstrapActive,\n updatePromptActive,\n resumeTargetPickerActive,\n })\n );\n\n const clients = Array.isArray(snapshot.onlineClients) ? snapshot.onlineClients : [];\n\n if (layout.isNarrowWidth) {\n return React.createElement(NarrowWidthPanel, {\n minWideCols: layout.minWideCols,\n narrowWidth: layout.narrowWidth,\n stdoutColumns,\n });\n }\n\n const bodyContent = updatePromptActive\n ? React.createElement(UpdatePromptPanel, { snapshot, width: layout.contentWidth })\n : bootstrapActive\n ? React.createElement(BootstrapPanel, { snapshot, width: layout.contentWidth })\n : resumeTargetPickerActive\n ? React.createElement(ResumeTargetPanel, { snapshot, width: layout.contentWidth })\n : React.createElement(MainPanels, { snapshot, layout, focusMode, menuIndex, clients });\n\n const footerLeft = footerHelpText({\n updatePromptActive,\n bootstrapActive,\n resumeTargetPickerActive,\n detailViewActive: Boolean(snapshot.detailView?.active),\n selectedTab: snapshot.selectedTab,\n focusMode,\n });\n const footerWidth = Math.max(layout.containerWidth, 24);\n const quipRaw = FOOTER_QUIPS[quipIndex % FOOTER_QUIPS.length];\n const quip = fitToWidth(quipRaw, Math.max(Math.floor(footerWidth * 0.48), 18));\n const leftMax = Math.max(footerWidth - quip.length - 2, 12);\n const left = fitToWidth(footerLeft, leftMax);\n const gap = \" \".repeat(Math.max(footerWidth - left.length - quip.length, 1));\n const footerRule = \"─\".repeat(Math.max(footerWidth, 1));\n\n return React.createElement(\n Box,\n { flexDirection: \"column\" },\n React.createElement(Box, { width: layout.containerWidth }, renderMainFrameTop(\n layout.containerWidth,\n snapshot.updateAvailable\n ? `UltraContext v${snapshot.currentVersion} ↑`\n : `UltraContext v${snapshot.currentVersion}`\n )),\n React.createElement(\n Box,\n {\n borderStyle: \"single\",\n borderTop: false,\n borderColor: UC_BRAND_BLUE,\n flexDirection: \"column\",\n paddingX: 0,\n paddingY: 0,\n width: layout.containerWidth,\n },\n React.createElement(HeaderPanel, { snapshot, stdoutColumns: layout.contentWidth }),\n bodyContent\n ),\n React.createElement(\n Box,\n { width: footerWidth, flexDirection: \"column\" },\n React.createElement(Text, { color: \"gray\", dim: true, wrap: \"truncate-end\" }, footerRule),\n React.createElement(\n Box,\n { width: footerWidth, flexDirection: \"row\" },\n React.createElement(\n Text,\n { color: \"gray\", wrap: \"truncate-end\" },\n `${left}${gap}`\n ),\n renderFooterQuip(quip)\n )\n )\n );\n}\n","import React from \"react\";\nimport { render } from \"ink\";\n\nimport { DaemonTui } from \"./DaemonTui.mjs\";\n\nexport function createInkUiController({ getSnapshot, actions }) {\n let app = null;\n let lastCols = null;\n let lastRows = null;\n const view = () => React.createElement(DaemonTui, { snapshot: getSnapshot(), actions });\n\n const readDims = () => ({\n cols: process.stdout.columns ?? 0,\n rows: process.stdout.rows ?? 0,\n });\n\n return {\n start() {\n if (app) return;\n app = render(view(), { exitOnCtrlC: false });\n const dims = readDims();\n lastCols = dims.cols;\n lastRows = dims.rows;\n },\n refresh() {\n if (!app) return;\n const dims = readDims();\n const sizeChanged = dims.cols !== lastCols || dims.rows !== lastRows;\n if (sizeChanged && typeof app.clear === \"function\") {\n app.clear();\n }\n lastCols = dims.cols;\n lastRows = dims.rows;\n app.rerender(view());\n },\n stop() {\n if (!app) return;\n app.unmount();\n app = null;\n lastCols = null;\n lastRows = null;\n },\n };\n}\n","// tui core — exported as tuiBoot(), no env.mjs import (caller handles that)\nimport fs from \"node:fs/promises\";\nimport fsSync from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport { spawn, spawnSync } from \"node:child_process\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { UltraContext } from \"ultracontext\";\nimport { normalizeBootstrapMode } from \"./protocol.mjs\";\n\nimport {\n hasLocalClaudeSession,\n hasLocalCodexSession,\n writeClaudeSession,\n writeCodexSession,\n} from \"@ultracontext/parsers\";\nimport { MENU_TABS, createInkUiController } from \"./ui.mjs\";\nimport { boolFromEnv, expandHome, toInt } from \"./utils.mjs\";\n\nconst DEFAULT_RUNTIME_CONFIG_FILE = \"~/.ultracontext/config.json\";\n\n// ── status.json polling path ───────────────────────────────────\n\nconst STATUS_FILE = path.join(os.homedir(), \".ultracontext\", \"status.json\");\n\nasync function readStatusJson() {\n try {\n const raw = await fs.readFile(STATUS_FILE, \"utf8\");\n return JSON.parse(raw);\n } catch { return null; }\n}\n\n// ── config.json write helper for TUI mutations ────────────────\n\nfunction writeConfigKey(key, value) {\n try {\n const configPath = path.join(os.homedir(), \".ultracontext\", \"config.json\");\n let data = {};\n try { data = JSON.parse(fsSync.readFileSync(configPath, \"utf8\")); } catch { /* empty */ }\n data[key] = value;\n const tmp = configPath + \".tmp.tui\";\n fsSync.writeFileSync(tmp, JSON.stringify(data, null, 2) + \"\\n\", \"utf8\");\n fsSync.renameSync(tmp, configPath);\n return true;\n } catch {\n return false;\n }\n}\n\n// ── exported boot function ──────────────────────────────────────\n\nexport async function tuiBoot({\n assetsRoot,\n onFatalError,\n} = {}) {\n\nconst APP_ROOT = assetsRoot ?? path.resolve(path.dirname(fileURLToPath(import.meta.url)), \"..\");\nconst DEFAULT_STARTUP_SOUND_FILE = path.join(APP_ROOT, \"assets\", \"sounds\", \"hello_mf.mp3\");\nconst DEFAULT_CONTEXT_SOUND_FILE = path.join(APP_ROOT, \"assets\", \"sounds\", \"quack.mp3\");\nconst OFFLINE_NOTICE = \"Daemon offline — status.json stale or missing.\";\n\nconst CONFIG_BOOTSTRAP_MODES = [\n { id: \"prompt\", label: \"Ask on startup\" },\n { id: \"new_only\", label: \"New only\" },\n { id: \"last_24h\", label: \"Last 24h\" },\n { id: \"all\", label: \"All\" },\n];\nconst CONFIG_RESUME_TERMINALS = [\n { id: \"terminal\", label: \"Terminal\" },\n { id: \"warp\", label: \"Warp\" },\n];\nconst RESUME_TARGET_OPTIONS = [\n { id: \"claude\", label: \"Claude Code\" },\n { id: \"codex\", label: \"Codex\" },\n];\nconst INSPECT_OPTION = { id: \"inspect\", label: \"Inspect messages\" };\nconst PERSISTED_CONFIG_FIELDS = [\n \"soundEnabled\",\n \"startupSoundEnabled\",\n \"contextSoundEnabled\",\n \"bootstrapMode\",\n \"resumeTerminal\",\n \"claudeIncludeSubagents\",\n \"resumeOpenTab\",\n \"startupGreetingFile\",\n \"contextCreatedSoundFile\",\n];\n\nfunction normalizeApiKey(raw) {\n if (!raw) return \"\";\n return String(raw).trim().replace(/^['\"]|['\"]$/g, \"\");\n}\n\nfunction normalizeResumeSourceFilter(raw) {\n const value = String(raw ?? \"all\").trim().toLowerCase();\n if (value === \"codex\" || value === \"claude\" || value === \"openclaw\" || value === \"all\") return value;\n return \"all\";\n}\n\nfunction normalizeResumeTerminal(raw) {\n const value = String(raw ?? \"terminal\").trim().toLowerCase();\n if (value === \"warp\") return \"warp\";\n return \"terminal\";\n}\n\nfunction resolveRuntimeConfigPath() {\n return expandHome(process.env.ULTRACONTEXT_CONFIG_FILE ?? DEFAULT_RUNTIME_CONFIG_FILE);\n}\n\nfunction normalizeBootstrapModeWithPrompt(raw) {\n return normalizeBootstrapMode(raw, { allowPrompt: true }) || \"\";\n}\n\nfunction readEnv(...keys) {\n for (const key of keys) {\n if (process.env[key] !== undefined) return process.env[key];\n }\n return undefined;\n}\n\nconst cfg = {\n apiKey: normalizeApiKey(process.env.ULTRACONTEXT_API_KEY),\n baseUrl: (process.env.ULTRACONTEXT_BASE_URL ?? \"https://api.ultracontext.ai\").trim(),\n userId: process.env.DAEMON_USER_ID ?? process.env.USER ?? \"unknown-user\",\n host: (process.env.DAEMON_HOST || os.hostname() || \"unknown-host\").trim(),\n uiRefreshMs: toInt(process.env.TUI_REFRESH_MS, 1200),\n resumeAutoRefreshMs: Math.max(toInt(process.env.RESUME_AUTO_REFRESH_MS, 3500), 0),\n uiRecentLimit: toInt(process.env.TUI_RECENT_LIMIT, 240),\n configFile: resolveRuntimeConfigPath(),\n soundEnabled: boolFromEnv(readEnv(\"TUI_SOUND_ENABLED\", \"DAEMON_SOUND_ENABLED\"), true),\n startupSoundEnabled: boolFromEnv(\n readEnv(\"TUI_STARTUP_SOUND_ENABLED\", \"DAEMON_STARTUP_SOUND_ENABLED\"),\n true\n ),\n contextSoundEnabled: boolFromEnv(\n readEnv(\"TUI_CONTEXT_SOUND_ENABLED\", \"DAEMON_CONTEXT_SOUND_ENABLED\"),\n true\n ),\n startupGreetingFile: expandHome(\n readEnv(\"TUI_STARTUP_SOUND_FILE\", \"DAEMON_STARTUP_GREETING_FILE\") ?? DEFAULT_STARTUP_SOUND_FILE\n ),\n contextCreatedSoundFile: expandHome(\n readEnv(\"TUI_CONTEXT_SOUND_FILE\", \"DAEMON_CONTEXT_SOUND_FILE\") ?? DEFAULT_CONTEXT_SOUND_FILE\n ),\n bootstrapMode: normalizeBootstrapModeWithPrompt(process.env.DAEMON_BOOTSTRAP_MODE ?? \"prompt\") || \"prompt\",\n bootstrapReset: boolFromEnv(process.env.DAEMON_BOOTSTRAP_RESET, false),\n claudeIncludeSubagents: boolFromEnv(process.env.CLAUDE_INCLUDE_SUBAGENTS, false),\n resumeTerminal: normalizeResumeTerminal(process.env.RESUME_TERMINAL),\n resumeContextLimit: toInt(process.env.RESUME_CONTEXT_LIMIT, 1000),\n resumeSourceFilter: normalizeResumeSourceFilter(process.env.RESUME_SOURCE_FILTER),\n resumeSummaryTail: toInt(process.env.RESUME_SUMMARY_TAIL, 14),\n resumeOutputDir: expandHome(process.env.RESUME_OUTPUT_DIR ?? \"~/.codex/resume\"),\n resumeOpenTab: boolFromEnv(process.env.RESUME_OPEN_TAB, true),\n};\n\nconst stats = {\n startedAt: Date.now(),\n cycles: 0,\n filesScanned: 0,\n linesRead: 0,\n parsedEvents: 0,\n appended: 0,\n deduped: 0,\n contextsCreated: 0,\n errors: 0,\n};\n\nconst CONFIG_TOGGLES = [\n {\n key: \"soundEnabled\",\n label: \"Master sounds\",\n description: \"Enable or disable all app sounds\",\n },\n {\n key: \"startupSoundEnabled\",\n label: \"Startup sounds\",\n description: \"Play sound when the TUI starts\",\n },\n {\n key: \"contextSoundEnabled\",\n label: \"Context sounds\",\n description: \"Play duck sound when the TUI detects a new context\",\n },\n];\n\n// ── update check helpers ─────────────────────────────────────────\n\n// no cache — check every invocation, like Claude Code\n\nfunction readTuiVersion() {\n try {\n const pkgPath = path.resolve(APP_ROOT, \"package.json\");\n const pkg = JSON.parse(fsSync.readFileSync(pkgPath, \"utf8\"));\n return pkg.version ?? \"unknown\";\n } catch { return \"unknown\"; }\n}\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 isNewerVersion(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\nasync function checkForUpdateSilent() {\n const current = readTuiVersion();\n if (current === \"unknown\") return;\n\n const notifyUpdate = (latest) => {\n ui.updateAvailable = latest;\n ui.updatePrompt.active = true;\n ui.updatePrompt.selectedIndex = 0;\n ui.updatePrompt.latestVersion = latest;\n renderDashboard();\n };\n\n // fetch from registry every invocation\n const latest = await fetchLatestVersion();\n if (latest && isNewerVersion(latest, current)) {\n notifyUpdate(latest);\n }\n}\n\nconst UPDATE_PROMPT_OPTIONS = [\n { id: \"install\", label: \"Install now\" },\n { id: \"skip\", label: \"Skip\" },\n];\n\nconst ui = {\n daemonOnline: false,\n currentVersion: readTuiVersion(),\n updateAvailable: \"\",\n updatePrompt: {\n active: false,\n selectedIndex: 0,\n latestVersion: \"\",\n },\n recentLogs: [],\n onlineClients: 0,\n sourceStats: [],\n selectedTab: \"logs\",\n configEditor: {\n selectedIndex: 0,\n },\n resume: {\n loading: false,\n syncing: false,\n contexts: [],\n selectedIndex: 0,\n loadedAt: 0,\n error: \"\",\n notice: \"\",\n summaryPath: \"\",\n command: \"\",\n commandPath: \"\",\n },\n detailView: {\n active: false,\n contextId: null,\n contextMeta: null,\n messages: [],\n scrollOffset: 0,\n lineOffset: 0,\n loading: false,\n error: null,\n },\n resumeTargetPicker: {\n active: false,\n selectedIndex: 0,\n source: \"\",\n contextId: \"\",\n options: RESUME_TARGET_OPTIONS,\n recommendedTarget: \"\",\n },\n bootstrap: {\n active: false,\n selectedIndex: 0,\n options: [],\n sourceNames: [],\n note: \"\",\n },\n};\n\nconst runtime = {\n uc: null,\n uiController: null,\n renderTimer: null,\n statusPollTimer: null,\n contextRefreshTimer: null,\n stop: null,\n seenLogSignatures: new Set(),\n seenLogQueue: [],\n syncCount: 0,\n resumeKnownContextIds: new Set(),\n resumeBaselineReady: false,\n};\n\nconst sound = { startupFile: \"\", contextFile: \"\", warnedNonDarwin: false };\n\n// ── status.json → UI state applicator ──────────────────────────\n\nfunction applyDaemonStatus(status) {\n if (!status) {\n ui.daemonOnline = false;\n return;\n }\n\n // check liveness — if updatedAt is stale by >5s, daemon is offline\n const updatedAt = new Date(status.updatedAt).getTime();\n const staleMs = Date.now() - updatedAt;\n ui.daemonOnline = staleMs < 30_000;\n\n if (!ui.daemonOnline) return;\n\n // apply stats\n Object.assign(stats, status.stats || {});\n\n // apply source stats\n ui.sourceStats = (status.sources || []).map(s => ({\n name: s.name,\n filesScanned: s.filesScanned || 0,\n linesRead: s.linesRead || 0,\n parsedEvents: s.parsedEvents || 0,\n appended: s.appended || 0,\n deduped: s.deduped || 0,\n contextsCreated: s.contextsCreated || 0,\n errors: s.errors || 0,\n lastEventType: s.lastEventType || \"-\",\n lastSessionId: s.lastSessionId || \"-\",\n lastAt: s.lastAt || 0,\n lastFile: s.lastFile || \"-\",\n }));\n\n // apply logs (deduplicate by signature)\n if (status.recentLogs && Array.isArray(status.recentLogs)) {\n for (const entry of status.recentLogs) {\n const sig = `${entry.ts}|${entry.level}|${entry.source}|${entry.text}`;\n if (!runtime.seenLogSignatures.has(sig)) {\n runtime.seenLogSignatures.add(sig);\n ui.recentLogs.push(entry);\n }\n }\n // cap logs + prune dedup set to prevent unbounded growth\n while (ui.recentLogs.length > cfg.uiRecentLimit) ui.recentLogs.shift();\n if (runtime.seenLogSignatures.size > cfg.uiRecentLimit * 2) {\n const keep = new Set();\n for (const entry of ui.recentLogs) {\n keep.add(`${entry.ts}|${entry.level}|${entry.source}|${entry.text}`);\n }\n runtime.seenLogSignatures = keep;\n }\n }\n\n // apply config from daemon\n if (status.config) {\n if (status.config.bootstrapMode) cfg.bootstrapMode = status.config.bootstrapMode;\n if (status.config.claudeIncludeSubagents !== undefined) cfg.claudeIncludeSubagents = Boolean(status.config.claudeIncludeSubagents);\n }\n\n // update online clients count (just show 1 if daemon is running)\n ui.onlineClients = ui.daemonOnline ? 1 : 0;\n}\n\n// ── poll daemon status ─────────────────────────────────────────\n\nasync function pollDaemonStatus() {\n const status = await readStatusJson();\n applyDaemonStatus(status);\n}\n\nfunction runtimeLogsKeep() {\n return Math.max(cfg.uiRecentLimit, 180);\n}\n\nfunction formatTime(value = Date.now()) {\n return new Date(value).toISOString().slice(11, 19);\n}\n\nfunction errorDetails(error) {\n if (!error || typeof error !== \"object\") {\n return { message: String(error) };\n }\n\n const details = {\n message: error.message ?? String(error),\n };\n\n if (\"status\" in error) details.status = error.status;\n if (\"url\" in error) details.url = error.url;\n if (\"bodyText\" in error) details.bodyText = error.bodyText;\n return details;\n}\n\nfunction renderDashboard() {\n runtime.uiController?.refresh();\n}\n\nfunction resumeCompact(value, max = 60) {\n const raw = String(value ?? \"\");\n if (raw.length <= max) return raw;\n if (max <= 3) return raw.slice(0, max);\n return `${raw.slice(0, max - 3)}...`;\n}\n\nfunction resumeNormalizeRole(message) {\n const role = String(message?.role ?? \"system\").toLowerCase();\n if (role === \"user\" || role === \"human\") return \"user\";\n if (role === \"assistant\" || role === \"agent\") return \"assistant\";\n return \"system\";\n}\n\nfunction resumeMessageText(message) {\n const content = message?.content;\n if (typeof content === \"string\") return resumeCompact(content.replace(/\\s+/g, \" \").trim(), 220);\n if (content && typeof content === \"object\") {\n if (typeof content.message === \"string\") return resumeCompact(content.message.replace(/\\s+/g, \" \").trim(), 220);\n if (typeof content.text === \"string\") return resumeCompact(content.text.replace(/\\s+/g, \" \").trim(), 220);\n return resumeCompact(JSON.stringify(content), 220);\n }\n return \"\";\n}\n\nfunction resumeMessageTimestamp(message) {\n return message?.content?.timestamp ?? message?.metadata?.timestamp ?? \"\";\n}\n\nfunction resumeMessageEventType(message) {\n return message?.content?.event_type ?? message?.metadata?.event_type ?? \"message\";\n}\n\nfunction resumeExtractSessionCwd(messages) {\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const cwd = messages[i]?.content?.raw?.payload?.cwd;\n if (typeof cwd === \"string\" && cwd.length > 0) return cwd;\n }\n return \"\";\n}\n\nasync function resumeResolveWorkingDirectory(preferredCwd) {\n if (!preferredCwd) return process.cwd();\n try {\n const stat = await fs.stat(preferredCwd);\n if (stat.isDirectory()) return preferredCwd;\n } catch {\n // Fall back to current directory.\n }\n return process.cwd();\n}\n\nfunction resumeShellQuote(value) {\n return `'${String(value).replace(/'/g, `'\"'\"'`)}'`;\n}\n\nfunction resumeAppleScriptString(value) {\n return `\"${String(value).replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"`;\n}\n\nfunction runAppleScriptLines(scriptLines) {\n const args = [];\n for (const line of scriptLines) args.push(\"-e\", line);\n const out = spawnSync(\"osascript\", args, { stdio: \"pipe\", encoding: \"utf8\" });\n if (out.status !== 0) {\n return {\n ok: false,\n reason: out.stderr?.trim() || out.stdout?.trim() || \"osascript failed\",\n };\n }\n return { ok: true };\n}\n\nfunction warpLaunchConfigDirs() {\n const home = os.homedir();\n return [\n path.join(home, \".warp\", \"launch_configurations\"),\n path.join(home, \"Library\", \"Application Support\", \"dev.warp.Warp-Stable\", \"launch_configurations\"),\n path.join(home, \"Library\", \"Application Support\", \"dev.warp.Warp-Preview\", \"launch_configurations\"),\n ];\n}\n\nfunction warpLaunchConfigYaml({ name, cwd, command }) {\n const safeCommand = String(command ?? \"\").replace(/\\r?\\n/g, \" && \");\n return [\n \"---\",\n `name: ${JSON.stringify(name)}`,\n \"windows:\",\n \" - tabs:\",\n \" - title: UltraContext Resume\",\n \" layout:\",\n ` cwd: ${JSON.stringify(cwd)}`,\n \" commands:\",\n ` - exec: ${JSON.stringify(safeCommand)}`,\n \"\",\n ].join(\"\\n\");\n}\n\nfunction runOpenUri(uri) {\n const out = spawnSync(\"open\", [uri], { stdio: \"pipe\", encoding: \"utf8\" });\n if (out.status !== 0) {\n return {\n ok: false,\n reason: out.stderr?.trim() || out.stdout?.trim() || \"open uri failed\",\n };\n }\n return { ok: true };\n}\n\nfunction resumeWarpPasteAndRun(command, { openNewTab = false } = {}) {\n const scriptLines = [\n \"set _uc_prev_clipboard to the clipboard\",\n `set the clipboard to ${resumeAppleScriptString(command)}`,\n \"tell application \\\"Warp\\\" to activate\",\n \"delay 0.85\",\n \"tell application \\\"System Events\\\"\",\n ];\n if (openNewTab) {\n scriptLines.push(\"keystroke \\\"t\\\" using {command down}\", \"delay 0.45\");\n }\n scriptLines.push(\n \"keystroke \\\"v\\\" using {command down}\",\n \"delay 0.25\",\n \"key code 36\",\n \"delay 0.18\",\n \"key code 36\",\n \"end tell\",\n \"delay 0.05\",\n \"set the clipboard to _uc_prev_clipboard\"\n );\n return runAppleScriptLines(scriptLines);\n}\n\nfunction resumeOpenWarpNewWindowAndRun(command) {\n spawnSync(\"open\", [\"-a\", \"Warp\"], { stdio: \"ignore\" });\n runAppleScriptLines([\"tell application \\\"Warp\\\" to activate\", \"delay 0.12\"]);\n\n const uri = `warp://action/new_window?path=${encodeURIComponent(process.cwd())}`;\n const opened = runOpenUri(uri);\n if (!opened.ok) return opened;\n\n runAppleScriptLines([\"tell application \\\"Warp\\\" to activate\", \"delay 0.3\"]);\n return resumeWarpPasteAndRun(command, { openNewTab: false });\n}\n\nfunction resumeOpenWarpViaUri(command) {\n try {\n const timestamp = Date.now();\n const launchName = `ultracontext_resume_${timestamp}_${process.pid}`;\n const yaml = warpLaunchConfigYaml({\n name: `UltraContext Resume ${timestamp}`,\n cwd: process.cwd(),\n command,\n });\n\n let primaryFilePath = \"\";\n for (const dir of warpLaunchConfigDirs()) {\n try {\n fsSync.mkdirSync(dir, { recursive: true });\n const filePath = path.join(dir, `${launchName}.yaml`);\n fsSync.writeFileSync(filePath, yaml, \"utf8\");\n if (!primaryFilePath) primaryFilePath = filePath;\n } catch {\n // Best effort.\n }\n }\n\n if (!primaryFilePath) {\n return { ok: false, reason: \"could not write Warp launch configuration file\" };\n }\n\n const uri = `warp://launch/${encodeURIComponent(primaryFilePath)}`;\n spawnSync(\"open\", [\"-a\", \"Warp\"], { stdio: \"ignore\" });\n runAppleScriptLines([\"tell application \\\"Warp\\\" to activate\", \"delay 0.12\"]);\n\n const opened = runOpenUri(uri);\n if (!opened.ok) return opened;\n\n runAppleScriptLines([\"tell application \\\"Warp\\\" to activate\", \"delay 0.12\"]);\n return { ok: true };\n } catch (error) {\n return {\n ok: false,\n reason: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nfunction resumeOpenAppleTerminalTab(command) {\n const scriptLines = [\n \"tell application \\\"Terminal\\\"\",\n \"activate\",\n \"if (count of windows) = 0 then\",\n ` do script ${resumeAppleScriptString(command)}`,\n \"else\",\n ` do script ${resumeAppleScriptString(command)} in front window`,\n \"end if\",\n \"end tell\",\n ];\n const out = runAppleScriptLines(scriptLines);\n return out.ok ? { ...out, method: \"terminal_applescript\" } : { ...out, method: \"terminal_applescript\" };\n}\n\nfunction resumeOpenWarpTab(command) {\n const uriLaunch = resumeOpenWarpViaUri(command);\n if (uriLaunch.ok) return { ...uriLaunch, method: \"warp_uri_launch\" };\n\n const newWindowFlow = resumeOpenWarpNewWindowAndRun(command);\n if (newWindowFlow.ok) return { ...newWindowFlow, method: \"warp_new_window_paste\" };\n\n const firstTry = resumeWarpPasteAndRun(command, { openNewTab: true });\n if (firstTry.ok) return { ...firstTry, method: \"warp_new_tab_paste\" };\n\n const fallback = resumeWarpPasteAndRun(command, { openNewTab: false });\n if (fallback.ok) return { ...fallback, method: \"warp_current_tab_paste\" };\n\n return {\n ok: false,\n method: \"warp_failed\",\n reason: `${newWindowFlow.reason}; ${uriLaunch.reason}; ${firstTry.reason}; fallback failed: ${fallback.reason}. Check macOS Accessibility permission for your terminal and osascript/System Events.`,\n };\n}\n\nfunction resumeOpenTerminalTab(command) {\n if (process.platform !== \"darwin\") {\n return { ok: false, reason: \"open-tab is available only on macOS\" };\n }\n if (cfg.resumeTerminal === \"warp\") return resumeOpenWarpTab(command);\n return resumeOpenAppleTerminalTab(command);\n}\n\nfunction readProcessInfo(pid) {\n try {\n const out = spawnSync(\"ps\", [\"-o\", \"ppid=,command=\", \"-p\", String(pid)], {\n stdio: \"pipe\",\n encoding: \"utf8\",\n });\n const raw = String(out.stdout ?? \"\").trim();\n if (!raw) return null;\n const match = raw.match(/^(\\d+)\\s+(.*)$/);\n if (!match) return null;\n return {\n ppid: Number(match[1]),\n command: match[2] ?? \"\",\n };\n } catch {\n return null;\n }\n}\n\nfunction isWatchCommand(command) {\n const raw = String(command ?? \"\").trim();\n if (!raw) return false;\n return raw.includes(\"node --watch\") || raw.includes(\" --watch \");\n}\n\nfunction stopWatchParentProcess() {\n let pid = Number(process.ppid);\n const seen = new Set();\n for (let depth = 0; depth < 10; depth += 1) {\n if (!Number.isInteger(pid) || pid <= 1) return false;\n if (seen.has(pid)) return false;\n seen.add(pid);\n\n const info = readProcessInfo(pid);\n if (!info) return false;\n if (isWatchCommand(info.command)) {\n try {\n process.kill(pid, \"SIGTERM\");\n return true;\n } catch {\n return false;\n }\n }\n pid = Number(info.ppid);\n }\n return false;\n}\n\nfunction resumeDedupeById(contexts) {\n const out = [];\n const seen = new Set();\n for (const item of contexts ?? []) {\n if (!item?.id || seen.has(item.id)) continue;\n seen.add(item.id);\n out.push(item);\n }\n return out;\n}\n\nfunction resumeFilterContexts(contexts) {\n return contexts.filter((ctx) => {\n const md = ctx?.metadata ?? {};\n const source = String(md.source ?? \"\").toLowerCase();\n if (cfg.resumeSourceFilter !== \"all\" && source && source !== cfg.resumeSourceFilter) return false;\n return true;\n });\n}\n\nfunction resumeSortContexts(contexts) {\n const ts = (ctx) => {\n const candidates = [ctx?.created_at, ctx?.updated_at, ctx?.metadata?.timestamp, ctx?.metadata?.created_at];\n for (const candidate of candidates) {\n const value = new Date(candidate ?? 0).getTime();\n if (!Number.isNaN(value) && value > 0) return value;\n }\n return 0;\n };\n\n return contexts.slice().sort((a, b) => {\n const diff = ts(b) - ts(a);\n if (diff !== 0) return diff;\n const aId = String(a?.id ?? \"\");\n const bId = String(b?.id ?? \"\");\n return bId.localeCompare(aId);\n });\n}\n\nfunction resumeFormatDate(value) {\n if (!value) return \"-\";\n const d = new Date(value);\n if (Number.isNaN(d.getTime())) return String(value);\n return d.toISOString().replace(\"T\", \" \").slice(0, 19);\n}\n\nfunction resumeContextSource(context) {\n const raw = String(context?.metadata?.source ?? \"\").trim().toLowerCase();\n if (raw === \"codex\") return \"codex\";\n if (raw === \"claude\") return \"claude\";\n return \"unknown\";\n}\n\nfunction isCodingContextSource(source) {\n return source === \"codex\" || source === \"claude\";\n}\n\nfunction resumeTargetAgent(source) {\n if (source === \"codex\") return \"claude\";\n if (source === \"claude\") return \"codex\";\n return \"codex\";\n}\n\nfunction resumeTargetOptionsForSource(source) {\n if (!isCodingContextSource(source)) return RESUME_TARGET_OPTIONS.slice();\n const recommended = resumeTargetAgent(source);\n const ordered = RESUME_TARGET_OPTIONS.slice().sort((a, b) => {\n if (a.id === recommended && b.id !== recommended) return -1;\n if (b.id === recommended && a.id !== recommended) return 1;\n return 0;\n });\n ordered.push(INSPECT_OPTION);\n return ordered;\n}\n\nfunction resumeAgentLabel(agent) {\n if (agent === \"claude\") return \"Claude Code\";\n if (agent === \"codex\") return \"Codex\";\n return \"Unknown\";\n}\n\nfunction resumeSummaryMarkdown({ context, messages }) {\n const counts = { user: 0, assistant: 0, system: 0 };\n for (const msg of messages) counts[resumeNormalizeRole(msg)] += 1;\n const recent = messages.slice(-Math.max(cfg.resumeSummaryTail, 4));\n const lines = [\n \"# UltraContext Resume\",\n \"\",\n `Generated at: ${new Date().toISOString()}`,\n `Context ID: ${context.id}`,\n `Created at: ${resumeFormatDate(context.created_at)}`,\n `Source: ${context.metadata?.source ?? \"-\"}`,\n `User: ${context.metadata?.user_id ?? \"-\"}`,\n `Session ID: ${context.metadata?.session_id ?? \"-\"}`,\n \"\",\n \"## Snapshot\",\n `- Messages: ${messages.length}`,\n `- Roles: user=${counts.user}, assistant=${counts.assistant}, system=${counts.system}`,\n \"\",\n `## Recent Timeline (last ${recent.length})`,\n ];\n\n for (const msg of recent) {\n const ts = resumeCompact(resumeMessageTimestamp(msg) || \"-\", 19).padEnd(19);\n const role = resumeNormalizeRole(msg).toUpperCase().padEnd(9);\n const eventType = resumeCompact(resumeMessageEventType(msg), 24).padEnd(24);\n const text = resumeMessageText(msg) || \"-\";\n lines.push(`- ${ts} ${role} ${eventType} ${text}`);\n }\n\n lines.push(\"\", \"## Resume Instructions\", \"1. Use the generated adapter command from the Contexts tab.\", \"2. Continue from the latest unresolved request.\", \"\");\n return lines.join(\"\\n\");\n}\n\nasync function loadResumeContexts({ silent = false } = {}) {\n if (!runtime.uc || ui.resume.loading) return;\n ui.resume.loading = true;\n if (!silent) {\n ui.resume.error = \"\";\n ui.resume.notice = \"Loading contexts from UltraContext...\";\n renderDashboard();\n }\n\n try {\n const listed = await runtime.uc.get({ limit: Math.max(cfg.resumeContextLimit, 1) });\n const filtered = resumeSortContexts(resumeFilterContexts(resumeDedupeById(listed.data)));\n const nextIds = new Set(filtered.map((ctx) => String(ctx?.id ?? \"\")).filter(Boolean));\n let newContextCount = 0;\n if (runtime.resumeBaselineReady) {\n for (const id of nextIds) {\n if (!runtime.resumeKnownContextIds.has(id)) newContextCount += 1;\n }\n }\n runtime.resumeKnownContextIds = nextIds;\n if (!runtime.resumeBaselineReady) runtime.resumeBaselineReady = true;\n\n if (newContextCount > 0) {\n playContextCreatedSound();\n }\n\n ui.resume.contexts = filtered;\n if (ui.resume.selectedIndex >= filtered.length) {\n ui.resume.selectedIndex = Math.max(filtered.length - 1, 0);\n }\n ui.resume.loadedAt = Date.now();\n\n const sourceCounts = { codex: 0, claude: 0, openclaw: 0, other: 0 };\n for (const ctx of filtered) {\n const source = String(ctx?.metadata?.source ?? \"\").toLowerCase();\n if (source === \"codex\") sourceCounts.codex += 1;\n else if (source === \"claude\") sourceCounts.claude += 1;\n else if (source === \"openclaw\") sourceCounts.openclaw += 1;\n else sourceCounts.other += 1;\n }\n\n if (!silent) {\n const filterLabel = cfg.resumeSourceFilter === \"all\" ? \"all sources\" : cfg.resumeSourceFilter;\n ui.resume.notice = `Loaded ${filtered.length} session contexts (${filterLabel}: codex=${sourceCounts.codex}, claude=${sourceCounts.claude}, openclaw=${sourceCounts.openclaw}, other=${sourceCounts.other})`;\n if (filtered.length === 0) {\n ui.resume.notice = `No contexts found for filter=${cfg.resumeSourceFilter}`;\n }\n }\n } catch (error) {\n if (!silent) {\n const details = errorDetails(error);\n ui.resume.error = details.message ?? \"Failed loading contexts\";\n ui.resume.notice = \"\";\n }\n } finally {\n ui.resume.loading = false;\n renderDashboard();\n }\n}\n\nfunction moveResumeSelection(delta) {\n const total = ui.resume.contexts.length;\n if (!total) return;\n const next = ui.resume.selectedIndex + delta;\n if (next < 0) {\n ui.resume.selectedIndex = total - 1;\n return;\n }\n if (next >= total) {\n ui.resume.selectedIndex = 0;\n return;\n }\n ui.resume.selectedIndex = next;\n}\n\nfunction recommendedResumeTargetForContext(context) {\n const sourceAgent = resumeContextSource(context);\n if (!isCodingContextSource(sourceAgent)) return \"\";\n return resumeTargetAgent(sourceAgent);\n}\n\nfunction openResumeTargetPicker() {\n if (ui.resume.syncing) return false;\n const context = ui.resume.contexts[ui.resume.selectedIndex];\n if (!context) {\n ui.resume.notice = \"No context selected\";\n renderDashboard();\n return false;\n }\n\n const sourceAgent = resumeContextSource(context);\n if (!isCodingContextSource(sourceAgent)) {\n ui.resume.notice = `Selected context source=${sourceAgent}. Adapt/Resume is available only for codex/claude contexts.`;\n renderDashboard();\n return false;\n }\n\n const recommendedTarget = recommendedResumeTargetForContext(context);\n ui.resumeTargetPicker.active = true;\n ui.resumeTargetPicker.selectedIndex = 0;\n ui.resumeTargetPicker.source = sourceAgent;\n ui.resumeTargetPicker.contextId = String(context.id ?? \"\");\n ui.resumeTargetPicker.options = resumeTargetOptionsForSource(sourceAgent);\n ui.resumeTargetPicker.recommendedTarget = recommendedTarget;\n renderDashboard();\n return true;\n}\n\nfunction closeResumeTargetPicker() {\n ui.resumeTargetPicker.active = false;\n ui.resumeTargetPicker.source = \"\";\n ui.resumeTargetPicker.contextId = \"\";\n ui.resumeTargetPicker.selectedIndex = 0;\n ui.resumeTargetPicker.options = RESUME_TARGET_OPTIONS;\n ui.resumeTargetPicker.recommendedTarget = \"\";\n renderDashboard();\n}\n\nfunction moveResumeTargetPickerSelection(delta) {\n const options = ui.resumeTargetPicker.options ?? RESUME_TARGET_OPTIONS;\n const total = options.length;\n if (total <= 0) return;\n const base = Number.isInteger(ui.resumeTargetPicker.selectedIndex) ? ui.resumeTargetPicker.selectedIndex : 0;\n ui.resumeTargetPicker.selectedIndex = (base + delta + total) % total;\n renderDashboard();\n}\n\nfunction resumeTargetPickerSelectionByIndex(index) {\n const options = ui.resumeTargetPicker.options ?? RESUME_TARGET_OPTIONS;\n const safeIndex = Math.max(Math.min(index, options.length - 1), 0);\n return options[safeIndex]?.id ?? \"codex\";\n}\n\nasync function buildCodexResumePlan({ sessionId, runCwd, messages }) {\n const originalSessionId = String(sessionId ?? \"\").trim();\n let canResumeBySessionId = originalSessionId ? await hasLocalCodexSession(originalSessionId) : false;\n let restoredPath = \"\";\n let restoredError = \"\";\n\n if (!canResumeBySessionId && originalSessionId) {\n const restored = await writeCodexSession({\n sessionId: originalSessionId,\n cwd: runCwd,\n messages,\n });\n canResumeBySessionId = await hasLocalCodexSession(originalSessionId);\n restoredPath = restored.filePath || \"\";\n restoredError = restored.error || \"\";\n }\n\n const command = canResumeBySessionId\n ? `codex -C ${resumeShellQuote(runCwd)} resume ${resumeShellQuote(originalSessionId)}`\n : `codex -C ${resumeShellQuote(runCwd)}`;\n\n return {\n targetAgent: \"codex\",\n sessionId: originalSessionId,\n command,\n canResumeBySessionId,\n restoredPath,\n restoredError,\n };\n}\n\nasync function buildClaudeResumePlan({ sessionId, runCwd, messages }) {\n const originalSessionId = String(sessionId ?? \"\").trim();\n let candidateSessionId = originalSessionId;\n let canResumeBySessionId = candidateSessionId ? await hasLocalClaudeSession(candidateSessionId, runCwd) : false;\n let restoredPath = \"\";\n let restoredError = \"\";\n\n if (!canResumeBySessionId || !candidateSessionId) {\n const restored = await writeClaudeSession({\n sessionId: candidateSessionId,\n cwd: runCwd,\n messages,\n });\n candidateSessionId = restored.sessionId || candidateSessionId;\n canResumeBySessionId = candidateSessionId ? await hasLocalClaudeSession(candidateSessionId, runCwd) : false;\n restoredPath = restored.filePath || \"\";\n restoredError = restored.error || \"\";\n }\n\n const command = canResumeBySessionId\n ? `cd ${resumeShellQuote(runCwd)} && claude --resume ${resumeShellQuote(candidateSessionId)}`\n : `cd ${resumeShellQuote(runCwd)} && claude`;\n\n return {\n targetAgent: \"claude\",\n sessionId: candidateSessionId,\n command,\n canResumeBySessionId,\n restoredPath,\n restoredError,\n };\n}\n\nasync function resumeSelectedContext({ targetAgentOverride = \"\" } = {}) {\n if (!runtime.uc || ui.resume.syncing) return;\n const context = ui.resume.contexts[ui.resume.selectedIndex];\n if (!context) {\n ui.resume.notice = \"No context selected\";\n renderDashboard();\n return;\n }\n\n const selectedSourceAgent = resumeContextSource(context);\n if (!isCodingContextSource(selectedSourceAgent)) {\n ui.resume.notice = `Selected context source=${selectedSourceAgent}. Adapt/Resume is available only for codex/claude contexts.`;\n renderDashboard();\n return;\n }\n\n ui.resume.syncing = true;\n ui.resumeTargetPicker.active = false;\n ui.resume.error = \"\";\n ui.resume.notice = `Pulling ${context.id}...`;\n renderDashboard();\n\n try {\n const detail = await runtime.uc.get(context.id);\n const messages = Array.isArray(detail.data) ? detail.data : [];\n\n const outDir = path.resolve(cfg.resumeOutputDir);\n await fs.mkdir(outDir, { recursive: true });\n\n const summaryPath = path.join(outDir, `${context.id}.md`);\n const snapshotPath = path.join(outDir, `${context.id}.json`);\n const commandPath = path.join(outDir, `${context.id}.command.txt`);\n\n const summary = resumeSummaryMarkdown({ context, messages });\n const snapshot = {\n exported_at: new Date().toISOString(),\n context_id: context.id,\n metadata: context.metadata ?? {},\n messages,\n };\n\n await fs.writeFile(summaryPath, summary, \"utf8\");\n await fs.writeFile(snapshotPath, JSON.stringify(snapshot, null, 2), \"utf8\");\n\n const originalCwd = resumeExtractSessionCwd(messages);\n const runCwd = await resumeResolveWorkingDirectory(originalCwd);\n const sourceAgent = selectedSourceAgent;\n const manualTarget = targetAgentOverride === \"claude\" || targetAgentOverride === \"codex\" ? targetAgentOverride : \"\";\n\n let targetAgent = manualTarget || resumeTargetAgent(sourceAgent);\n if (targetAgent === sourceAgent) {\n targetAgent = resumeTargetAgent(sourceAgent);\n }\n\n const sessionId = String(context.metadata?.session_id ?? \"\");\n const resumePlan =\n targetAgent === \"claude\"\n ? await buildClaudeResumePlan({ sessionId, runCwd, messages })\n : await buildCodexResumePlan({ sessionId, runCwd, messages });\n\n const command = resumePlan.command;\n await fs.writeFile(commandPath, `${command}\\n`, \"utf8\");\n\n ui.resume.summaryPath = summaryPath;\n ui.resume.command = command;\n ui.resume.commandPath = commandPath;\n\n const direction = `${resumeAgentLabel(sourceAgent)} -> ${resumeAgentLabel(targetAgent)}`;\n\n if (cfg.resumeOpenTab) {\n const opened = resumeOpenTerminalTab(command);\n const openMethod = opened.method ? ` method=${opened.method}` : \"\";\n if (opened.ok) {\n ui.resume.notice = resumePlan.canResumeBySessionId\n ? `Adapter ready (${direction}). Opened ${resumeAgentLabel(targetAgent)} via session_id ${resumePlan.sessionId}.${openMethod}`\n : `Adapter ready (${direction}). Opened ${resumeAgentLabel(targetAgent)} without session resume.${openMethod}`;\n if (resumePlan.restoredError) {\n ui.resume.notice = `${ui.resume.notice} Adapter warning: ${resumePlan.restoredError}`;\n }\n } else {\n ui.resume.notice = `Adapter ready (${direction}). Open tab failed: ${opened.reason}${openMethod}`;\n }\n } else {\n ui.resume.notice = resumePlan.canResumeBySessionId\n ? `Adapter ready (${direction}). Use generated ${resumeAgentLabel(targetAgent)} resume command.`\n : `Adapter ready (${direction}). Use generated command to start a clean ${resumeAgentLabel(targetAgent)} session.`;\n if (resumePlan.restoredPath) {\n ui.resume.notice = `${ui.resume.notice} Local adapter: ${resumePlan.restoredPath}`;\n } else if (resumePlan.restoredError) {\n ui.resume.notice = `${ui.resume.notice} Adapter warning: ${resumePlan.restoredError}`;\n }\n }\n } catch (error) {\n const details = errorDetails(error);\n ui.resume.error = details.message ?? \"Resume failed\";\n ui.resume.notice = \"\";\n } finally {\n ui.resume.syncing = false;\n ui.resumeTargetPicker.active = false;\n ui.resumeTargetPicker.source = \"\";\n ui.resumeTargetPicker.contextId = \"\";\n ui.resumeTargetPicker.selectedIndex = 0;\n ui.resumeTargetPicker.options = RESUME_TARGET_OPTIONS;\n ui.resumeTargetPicker.recommendedTarget = \"\";\n renderDashboard();\n }\n}\n\nfunction bootstrapModeConfigLabel(mode) {\n return CONFIG_BOOTSTRAP_MODES.find((entry) => entry.id === mode)?.label ?? mode;\n}\n\nfunction resumeTerminalConfigLabel(mode) {\n const normalized = normalizeResumeTerminal(mode);\n return CONFIG_RESUME_TERMINALS.find((entry) => entry.id === normalized)?.label ?? \"Terminal\";\n}\n\nfunction serializeConfigPrefs() {\n return {\n soundEnabled: Boolean(cfg.soundEnabled),\n startupSoundEnabled: Boolean(cfg.startupSoundEnabled),\n contextSoundEnabled: Boolean(cfg.contextSoundEnabled),\n bootstrapMode: normalizeBootstrapModeWithPrompt(cfg.bootstrapMode) || \"prompt\",\n resumeTerminal: normalizeResumeTerminal(cfg.resumeTerminal),\n claudeIncludeSubagents: Boolean(cfg.claudeIncludeSubagents),\n resumeOpenTab: Boolean(cfg.resumeOpenTab),\n startupGreetingFile: String(cfg.startupGreetingFile ?? \"\"),\n contextCreatedSoundFile: String(cfg.contextCreatedSoundFile ?? \"\"),\n };\n}\n\nasync function persistConfigPrefsToFile(targetFile = cfg.configFile) {\n const target = path.resolve(targetFile);\n await fs.mkdir(path.dirname(target), { recursive: true });\n\n // read-modify-write to preserve non-TUI keys (apiKey, _bootstrapState, etc.)\n let existing = {};\n try { existing = JSON.parse(await fs.readFile(target, \"utf8\")); } catch { /* empty */ }\n const merged = { ...existing, ...serializeConfigPrefs() };\n\n const tmp = target + \".tmp.prefs\";\n await fs.writeFile(tmp, JSON.stringify(merged, null, 2) + \"\\n\", \"utf8\");\n await fs.rename(tmp, target);\n return { saved: true, file: target };\n}\n\nasync function loadConfigPrefsFromPath(target) {\n let raw = \"\";\n try {\n raw = await fs.readFile(target, \"utf8\");\n } catch (error) {\n if (error?.code === \"ENOENT\") return { loaded: false, missing: true };\n return { loaded: false, missing: false, error };\n }\n\n let parsed = null;\n try {\n parsed = JSON.parse(raw);\n } catch (error) {\n return { loaded: false, missing: false, error };\n }\n\n applyConfigPrefs(parsed);\n return { loaded: true, missing: false };\n}\n\nasync function loadConfigPrefsFromFile() {\n const primary = path.resolve(cfg.configFile);\n const loaded = await loadConfigPrefsFromPath(primary);\n return {\n loaded: loaded.loaded,\n source: loaded.loaded ? \"primary\" : \"none\",\n file: loaded.loaded ? primary : \"\",\n };\n}\n\nfunction applyConfigPrefs(prefs) {\n if (!prefs || typeof prefs !== \"object\") return;\n for (const field of PERSISTED_CONFIG_FIELDS) {\n if (!(field in prefs)) continue;\n if (field === \"bootstrapMode\") {\n cfg.bootstrapMode = normalizeBootstrapModeWithPrompt(prefs.bootstrapMode) || \"prompt\";\n continue;\n }\n if (field === \"resumeTerminal\") {\n cfg.resumeTerminal = normalizeResumeTerminal(prefs.resumeTerminal);\n continue;\n }\n if (field === \"startupGreetingFile\") {\n cfg.startupGreetingFile = expandHome(String(prefs.startupGreetingFile ?? cfg.startupGreetingFile));\n continue;\n }\n if (field === \"contextCreatedSoundFile\") {\n cfg.contextCreatedSoundFile = expandHome(String(prefs.contextCreatedSoundFile ?? cfg.contextCreatedSoundFile));\n continue;\n }\n cfg[field] = Boolean(prefs[field]);\n }\n}\n\nasync function persistConfigPrefs() {\n let fileSaved = false;\n\n try {\n await persistConfigPrefsToFile();\n fileSaved = true;\n } catch {\n // ignore\n }\n\n return { fileSaved };\n}\n\nasync function resolveSoundFile(filePath, label) {\n if (!filePath) return \"\";\n try {\n const stat = await fs.stat(filePath);\n if (!stat.isFile()) {\n ui.resume.notice = `Configured sound is not a file: ${label}`;\n return \"\";\n }\n return filePath;\n } catch {\n ui.resume.notice = `Configured sound file not found: ${label}`;\n return \"\";\n }\n}\n\nasync function prepareSoundConfig() {\n sound.startupFile = \"\";\n sound.contextFile = \"\";\n sound.warnedNonDarwin = false;\n if (!cfg.soundEnabled) return;\n\n sound.startupFile = await resolveSoundFile(cfg.startupGreetingFile, \"startup\");\n sound.contextFile = await resolveSoundFile(cfg.contextCreatedSoundFile, \"context_created\");\n}\n\nfunction playSoundFile(filePath) {\n if (!cfg.soundEnabled || !filePath) return;\n\n if (process.platform !== \"darwin\") {\n if (!sound.warnedNonDarwin) {\n sound.warnedNonDarwin = true;\n ui.resume.notice = \"Sound notifications currently support only macOS (afplay).\";\n renderDashboard();\n }\n return;\n }\n\n try {\n const child = spawn(\"afplay\", [filePath], {\n detached: true,\n stdio: \"ignore\",\n });\n child.unref();\n } catch {\n // ignore playback errors\n }\n}\n\nfunction playStartupGreetingSound() {\n if (!cfg.startupSoundEnabled) return;\n playSoundFile(sound.startupFile);\n}\n\nfunction playContextCreatedSound() {\n if (!cfg.contextSoundEnabled) return;\n playSoundFile(sound.contextFile);\n}\n\nfunction configToggleItems() {\n const masterEnabled = Boolean(cfg.soundEnabled);\n const soundItems = CONFIG_TOGGLES.map((item) => {\n const rawValue = Boolean(cfg[item.key]);\n const isSoundToggle = item.key !== \"soundEnabled\";\n const blockedByMaster = isSoundToggle && !masterEnabled;\n const effectiveValue = blockedByMaster ? false : rawValue;\n return {\n ...item,\n kind: \"boolean\",\n rawValue,\n value: effectiveValue,\n valueLabel: effectiveValue ? \"ON\" : \"OFF\",\n blockedByMaster,\n };\n });\n\n const normalizedBootstrapMode = normalizeBootstrapModeWithPrompt(cfg.bootstrapMode) || \"prompt\";\n const syncItems = [\n {\n key: \"bootstrapMode\",\n kind: \"enum\",\n label: \"Sync profile\",\n description: \"Defines bootstrap strategy for next daemon startup/reset.\",\n value: normalizedBootstrapMode,\n valueLabel: bootstrapModeConfigLabel(normalizedBootstrapMode),\n blockedByMaster: false,\n },\n {\n key: \"resumeTerminal\",\n kind: \"enum\",\n label: \"Resume terminal\",\n description: \"Choose where resume opens (Terminal or Warp).\",\n value: normalizeResumeTerminal(cfg.resumeTerminal),\n valueLabel: resumeTerminalConfigLabel(cfg.resumeTerminal),\n blockedByMaster: false,\n },\n {\n key: \"bootstrapResetState\",\n kind: \"action\",\n label: \"Reset bootstrap state\",\n description: \"Clears daemon bootstrap state so re-bootstrap can run again.\",\n value: \"run\",\n valueLabel: \"RUN\",\n blockedByMaster: false,\n },\n ];\n\n return [...soundItems, ...syncItems];\n}\n\nfunction moveConfigSelection(delta) {\n const items = configToggleItems();\n const total = items.length;\n if (!total) return;\n const next = ui.configEditor.selectedIndex + delta;\n if (next < 0) {\n ui.configEditor.selectedIndex = total - 1;\n return;\n }\n if (next >= total) {\n ui.configEditor.selectedIndex = 0;\n return;\n }\n ui.configEditor.selectedIndex = next;\n}\n\nasync function toggleSelectedConfig() {\n const items = configToggleItems();\n if (items.length === 0) return;\n\n const selected = Math.max(Math.min(ui.configEditor.selectedIndex, items.length - 1), 0);\n const item = items[selected];\n\n try {\n // bootstrap reset — persist prefs first, then add flag on top so it isn't clobbered\n if (item.kind === \"action\" && item.key === \"bootstrapResetState\") {\n await persistConfigPrefs();\n const ok = writeConfigKey(\"bootstrapReset\", true);\n ui.resume.notice = ok\n ? \"Bootstrap reset requested. Daemon will apply next cycle.\"\n : \"Failed to write config.\";\n renderDashboard();\n return;\n }\n\n // bootstrap mode cycle — spawn CLI config set\n if (item.kind === \"enum\" && item.key === \"bootstrapMode\") {\n const currentIndex = Math.max(CONFIG_BOOTSTRAP_MODES.findIndex((entry) => entry.id === item.value), 0);\n const next = CONFIG_BOOTSTRAP_MODES[(currentIndex + 1) % CONFIG_BOOTSTRAP_MODES.length];\n cfg.bootstrapMode = next.id;\n cfg.bootstrapReset = next.id === \"prompt\";\n\n const saved = await persistConfigPrefs();\n ui.resume.notice = `Sync profile set: ${next.label}${saved.fileSaved ? \" (saved)\" : \"\"}.`;\n renderDashboard();\n return;\n }\n\n // resume terminal cycle — local only\n if (item.kind === \"enum\" && item.key === \"resumeTerminal\") {\n const current = normalizeResumeTerminal(item.value);\n const currentIndex = Math.max(CONFIG_RESUME_TERMINALS.findIndex((entry) => entry.id === current), 0);\n const next = CONFIG_RESUME_TERMINALS[(currentIndex + 1) % CONFIG_RESUME_TERMINALS.length];\n cfg.resumeTerminal = next.id;\n const saved = await persistConfigPrefs();\n ui.resume.notice = `Resume terminal: ${next.label}${saved.fileSaved ? \" (saved)\" : \"\"}.`;\n renderDashboard();\n return;\n }\n\n // boolean toggles\n if (item.kind === \"boolean\") {\n cfg[item.key] = !cfg[item.key];\n\n // sound toggles — local only\n if (\n item.key === \"soundEnabled\" ||\n item.key === \"startupSoundEnabled\" ||\n item.key === \"contextSoundEnabled\"\n ) {\n await prepareSoundConfig();\n const saved = await persistConfigPrefs();\n ui.resume.notice = `${item.label}: ${cfg[item.key] ? \"ON\" : \"OFF\"}${saved.fileSaved ? \" (file saved)\" : \"\"}.`;\n renderDashboard();\n return;\n }\n }\n } catch (error) {\n const details = errorDetails(error);\n ui.resume.notice = `Failed to apply config: ${details.message}`;\n renderDashboard();\n }\n}\n\n// ── update prompt actions ────────────────────────────────────────\n\nfunction moveUpdatePrompt(delta) {\n const total = UPDATE_PROMPT_OPTIONS.length;\n ui.updatePrompt.selectedIndex = (ui.updatePrompt.selectedIndex + delta + total) % total;\n renderDashboard();\n}\n\nfunction chooseUpdatePrompt(index) {\n const safeIndex = Math.max(Math.min(index, UPDATE_PROMPT_OPTIONS.length - 1), 0);\n const choice = UPDATE_PROMPT_OPTIONS[safeIndex]?.id;\n\n // dismiss prompt\n ui.updatePrompt.active = false;\n renderDashboard();\n\n if (choice === \"install\") {\n // stop TUI and run update in a new terminal tab\n const command = \"ultracontext update\";\n const opened = resumeOpenTerminalTab(command);\n if (opened.ok) {\n ui.resume.notice = `Update started in new tab. Restart TUI after update.`;\n } else {\n ui.resume.notice = `Run manually: ultracontext update`;\n }\n renderDashboard();\n }\n}\n\n// ── detail view actions ─────────────────────────────────────────\n\nasync function openContextDetail() {\n if (ui.detailView.loading) return;\n const context = ui.resume.contexts[ui.resume.selectedIndex];\n if (!context) return;\n\n ui.detailView.active = true;\n ui.detailView.contextId = context.id;\n ui.detailView.contextMeta = context.metadata ?? {};\n ui.detailView.messages = [];\n ui.detailView.scrollOffset = 0;\n ui.detailView.lineOffset = 0;\n ui.detailView.loading = true;\n ui.detailView.error = null;\n renderDashboard();\n\n try {\n const detail = await runtime.uc.get(context.id);\n const messages = Array.isArray(detail.data) ? detail.data : [];\n ui.detailView.messages = messages;\n } catch (error) {\n ui.detailView.error = error?.message ?? \"Failed to load context\";\n } finally {\n ui.detailView.loading = false;\n renderDashboard();\n }\n}\n\nfunction closeContextDetail() {\n ui.detailView.active = false;\n ui.detailView.contextId = null;\n ui.detailView.contextMeta = null;\n ui.detailView.messages = [];\n ui.detailView.scrollOffset = 0;\n ui.detailView.lineOffset = 0;\n ui.detailView.loading = false;\n ui.detailView.error = null;\n renderDashboard();\n}\n\nasync function refreshContextDetail() {\n if (!ui.detailView.active || !ui.detailView.contextId || ui.detailView.loading) return;\n ui.detailView.loading = true;\n ui.detailView.error = null;\n renderDashboard();\n\n try {\n const detail = await runtime.uc.get(ui.detailView.contextId);\n ui.detailView.messages = Array.isArray(detail.data) ? detail.data : [];\n } catch (error) {\n ui.detailView.error = error?.message ?? \"Failed to refresh\";\n } finally {\n ui.detailView.loading = false;\n renderDashboard();\n }\n}\n\n// message-level scroll — resets line offset\nfunction scrollContextDetail(delta) {\n const total = ui.detailView.messages.length;\n if (total === 0) return;\n const next = ui.detailView.scrollOffset + delta;\n if (next < 0) ui.detailView.scrollOffset = total - 1;\n else if (next >= total) ui.detailView.scrollOffset = 0;\n else ui.detailView.scrollOffset = next;\n ui.detailView.lineOffset = 0;\n renderDashboard();\n}\n\n// line-level fine scroll (j/k) within current view\nfunction scrollContextDetailLine(delta) {\n if (ui.detailView.messages.length === 0) return;\n ui.detailView.lineOffset = Math.max(0, ui.detailView.lineOffset + delta);\n renderDashboard();\n}\n\n// ── enter context (picker or detail based on source) ────────────\n\nfunction enterContext() {\n const context = ui.resume.contexts[ui.resume.selectedIndex];\n if (!context) {\n ui.resume.notice = \"No context selected\";\n renderDashboard();\n return;\n }\n\n const source = resumeContextSource(context);\n if (isCodingContextSource(source)) {\n openResumeTargetPicker();\n } else {\n void openContextDetail();\n }\n}\n\nfunction setSelectedTabByIndex(nextIndex) {\n const normalized = (nextIndex + MENU_TABS.length) % MENU_TABS.length;\n ui.selectedTab = MENU_TABS[normalized].id;\n}\n\nfunction ensureResumeTabDataLoaded() {\n if (ui.selectedTab !== \"contexts\") return;\n if (ui.resume.contexts.length === 0 && !ui.resume.loading) {\n void loadResumeContexts();\n }\n}\n\nfunction selectTabAndRefreshByIndex(index) {\n setSelectedTabByIndex(index);\n ensureResumeTabDataLoaded();\n renderDashboard();\n}\n\nfunction moveTabAndRefresh(delta) {\n const idx = MENU_TABS.findIndex((tab) => tab.id === ui.selectedTab);\n const current = idx === -1 ? 0 : idx;\n setSelectedTabByIndex(current + delta);\n ensureResumeTabDataLoaded();\n renderDashboard();\n}\n\nfunction buildUiSnapshot() {\n const configItems = configToggleItems();\n const selectedConfigIndex = Math.max(\n Math.min(ui.configEditor.selectedIndex, Math.max(configItems.length - 1, 0)),\n 0\n );\n\n return {\n now: Date.now(),\n currentVersion: ui.currentVersion,\n updateAvailable: ui.updateAvailable,\n updatePrompt: {\n active: ui.updatePrompt.active,\n selectedIndex: ui.updatePrompt.selectedIndex,\n latestVersion: ui.updatePrompt.latestVersion,\n options: UPDATE_PROMPT_OPTIONS,\n },\n cfg: {\n userId: cfg.userId,\n host: cfg.host,\n pollMs: 0,\n uiRefreshMs: cfg.uiRefreshMs,\n logLevel: \"info\",\n soundEnabled: cfg.soundEnabled,\n startupSoundEnabled: cfg.startupSoundEnabled,\n contextSoundEnabled: cfg.contextSoundEnabled,\n startupGreetingFile: cfg.startupGreetingFile,\n contextCreatedSoundFile: cfg.contextCreatedSoundFile,\n },\n stats,\n selectedTab: ui.selectedTab,\n configEditor: {\n selectedIndex: selectedConfigIndex,\n items: configItems,\n },\n recentLogs: ui.recentLogs.slice(-runtimeLogsKeep()),\n sourceStats: ui.sourceStats,\n resume: {\n ...ui.resume,\n contexts: ui.resume.contexts,\n },\n detailView: {\n active: ui.detailView.active,\n contextId: ui.detailView.contextId,\n contextMeta: ui.detailView.contextMeta,\n messages: ui.detailView.messages,\n scrollOffset: ui.detailView.scrollOffset,\n lineOffset: ui.detailView.lineOffset,\n loading: ui.detailView.loading,\n error: ui.detailView.error,\n },\n resumeTargetPicker: {\n active: ui.resumeTargetPicker.active,\n selectedIndex: ui.resumeTargetPicker.selectedIndex,\n source: ui.resumeTargetPicker.source,\n contextId: ui.resumeTargetPicker.contextId,\n options: ui.resumeTargetPicker.options,\n recommendedTarget: ui.resumeTargetPicker.recommendedTarget,\n },\n onlineClients: ui.onlineClients,\n bootstrap: {\n active: ui.bootstrap.active,\n selectedIndex: ui.bootstrap.selectedIndex,\n options: ui.bootstrap.options,\n sourceNames: ui.bootstrap.sourceNames,\n note: ui.bootstrap.note,\n },\n };\n}\n\nfunction validateConfig() {\n if (!cfg.apiKey) {\n throw new Error(\"Missing ULTRACONTEXT_API_KEY\");\n }\n}\n\n// ── main entry ──────────────────────────────────────────────────\n\nasync function tuiMain() {\n validateConfig();\n\n if (!process.stdout.isTTY) {\n throw new Error(\"TUI mode requires a TTY.\");\n }\n\n try {\n const fileLoad = await loadConfigPrefsFromFile();\n if (!fileLoad.loaded) {\n await persistConfigPrefsToFile();\n }\n } catch {\n // ignore config persistence startup issues\n }\n\n await prepareSoundConfig();\n playStartupGreetingSound();\n\n const uc = new UltraContext({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl });\n runtime.uc = uc;\n\n await uc.get({ limit: 1 });\n\n let running = true;\n let stopRequested = false;\n const stop = (reason = \"internal\") => {\n if (stopRequested) return;\n stopRequested = true;\n if (reason === \"user\" || reason === \"sigint\") {\n stopWatchParentProcess();\n }\n running = false;\n };\n runtime.stop = stop;\n\n runtime.uiController = createInkUiController({\n getSnapshot: buildUiSnapshot,\n actions: {\n stop: () => runtime.stop?.(\"user\"),\n moveBootstrap: () => {},\n chooseBootstrap: () => {},\n moveUpdatePrompt: (delta) => {\n moveUpdatePrompt(delta);\n },\n chooseUpdatePrompt: (index) => {\n chooseUpdatePrompt(index);\n },\n moveTab: moveTabAndRefresh,\n selectTab: selectTabAndRefreshByIndex,\n moveConfig: (delta) => {\n moveConfigSelection(delta);\n renderDashboard();\n },\n toggleConfig: () => {\n void toggleSelectedConfig();\n },\n moveResume: (delta) => {\n moveResumeSelection(delta);\n renderDashboard();\n },\n refreshResume: () => {\n void loadResumeContexts();\n },\n promptResumeTarget: () => {\n openResumeTargetPicker();\n },\n moveResumeTarget: (delta) => {\n moveResumeTargetPickerSelection(delta);\n },\n chooseResumeTarget: (index) => {\n const target = resumeTargetPickerSelectionByIndex(index);\n if (target === \"inspect\") {\n closeResumeTargetPicker();\n void openContextDetail();\n return;\n }\n void resumeSelectedContext({ targetAgentOverride: target });\n },\n cancelResumeTarget: () => {\n closeResumeTargetPicker();\n },\n enterContext: () => {\n enterContext();\n },\n openDetail: () => {\n void openContextDetail();\n },\n closeDetail: () => {\n closeContextDetail();\n },\n scrollDetail: (delta) => {\n scrollContextDetail(delta);\n },\n scrollDetailLine: (delta) => {\n scrollContextDetailLine(delta);\n },\n refreshDetail: () => {\n void refreshContextDetail();\n },\n },\n });\n\n runtime.uiController.start();\n renderDashboard();\n void loadResumeContexts();\n void checkForUpdateSilent();\n\n // initial status poll\n await pollDaemonStatus();\n\n // status.json polling + render loop\n runtime.statusPollTimer = setInterval(async () => {\n await pollDaemonStatus();\n renderDashboard();\n }, cfg.uiRefreshMs);\n runtime.statusPollTimer.unref?.();\n\n // context auto-refresh\n if (cfg.resumeAutoRefreshMs > 0) {\n runtime.contextRefreshTimer = setInterval(() => {\n if (ui.resume.loading || ui.resume.syncing) return;\n void loadResumeContexts({ silent: ui.selectedTab !== \"contexts\" });\n }, Math.max(cfg.resumeAutoRefreshMs, 1000));\n runtime.contextRefreshTimer.unref?.();\n }\n\n process.on(\"SIGINT\", () => stop(\"sigint\"));\n process.on(\"SIGTERM\", () => stop(\"sigterm\"));\n\n while (running) {\n await new Promise((resolve) => setTimeout(resolve, 120));\n }\n\n // cleanup\n if (runtime.statusPollTimer) clearInterval(runtime.statusPollTimer);\n runtime.statusPollTimer = null;\n if (runtime.contextRefreshTimer) clearInterval(runtime.contextRefreshTimer);\n runtime.contextRefreshTimer = null;\n\n runtime.uiController?.stop();\n runtime.uiController = null;\n\n runtime.stop = null;\n runtime.uc = null;\n}\n\ntuiMain().catch(async (error) => {\n if (runtime.statusPollTimer) clearInterval(runtime.statusPollTimer);\n runtime.statusPollTimer = null;\n if (runtime.contextRefreshTimer) clearInterval(runtime.contextRefreshTimer);\n runtime.contextRefreshTimer = null;\n\n runtime.uiController?.stop();\n runtime.uiController = null;\n\n runtime.stop = null;\n runtime.uc = null;\n\n if (onFatalError) {\n onFatalError(error);\n return;\n }\n\n const message = error instanceof Error ? error.message : String(error);\n console.error(`[error] UltraContext TUI failed: ${message}`);\n process.exit(1);\n});\n\n} // end tuiBoot\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tui-DTVj3nxD.mjs","names":["fs","fsSync","process"],"sources":["../../sync/src/ui/layout.mjs","../../sync/src/ui/input-handlers/bootstrap.mjs","../../sync/src/ui/input-handlers/menu.mjs","../../sync/src/ui/input-handlers/quit.mjs","../../sync/src/ui/input-handlers/resume-target.mjs","../../sync/src/ui/input-handlers/update-prompt.mjs","../../sync/src/ui/input-handlers/view-contexts.mjs","../../sync/src/ui/input-handlers/view-configs.mjs","../../sync/src/ui/input-handlers/view.mjs","../../sync/src/ui/input.mjs","../../sync/src/ui/format.mjs","../../sync/src/ui/state.mjs","../../sync/src/ui/components/Section.mjs","../../sync/src/ui/components/ClientsPanel.mjs","../../sync/src/ui/components/HeroLockup.mjs","../../sync/src/ui/components/MenuPanel.mjs","../../sync/src/ui/components/NarrowWidthPanel.mjs","../../sync/src/ui/panels/BootstrapPanel.mjs","../../sync/src/ui/panels/ConfigsContent.mjs","../../sync/src/ui/panels/ContextDetailContent.mjs","../../sync/src/ui/panels/ContextsContent.mjs","../../sync/src/ui/panels/HeaderPanel.mjs","../../sync/src/ui/panels/LogsContent.mjs","../../sync/src/ui/panels/RightPanel.mjs","../../sync/src/ui/panels/MainPanels.mjs","../../sync/src/ui/panels/ResumeTargetPanel.mjs","../../sync/src/ui/panels/UpdatePromptPanel.mjs","../../sync/src/ui/DaemonTui.mjs","../../sync/src/ui/controller.mjs","../../sync/src/tui.mjs"],"sourcesContent":["export function computeTuiLayout(stdoutColumns, stdoutRows) {\n const safeCols = Math.max(Math.floor(Number(stdoutColumns) || 0), 1);\n const safeRows = Math.max(Math.floor(Number(stdoutRows) || 0), 1);\n const minWideCols = 64;\n const isNarrowWidth = safeCols < minWideCols;\n const frameWidth = Math.max(safeCols - 2, 1);\n const narrowWidth = frameWidth;\n const containerWidth = frameWidth;\n const contentWidth = Math.max(containerWidth - 2, 1);\n\n const compactLayoutBreakpoint = 114;\n const isCompactLayout = contentWidth < compactLayoutBreakpoint;\n const sidebarWidth = contentWidth >= 140 ? 34 : contentWidth >= 112 ? 30 : 24;\n const fullBottomPanelHeight = Math.max(safeRows - 12, 6);\n const targetBottomPanelHeight = Math.max(Math.floor(fullBottomPanelHeight * 0.75), 6);\n const maxBottomPanelHeight = Math.max(safeRows - 7, 4);\n const bottomPanelHeight = Math.min(targetBottomPanelHeight, maxBottomPanelHeight);\n\n // Wide layout (left sidebar + right panel)\n const minMenuPanelHeight = Math.min(5, Math.max(bottomPanelHeight, 1));\n const minAgentsPanelHeight = 0;\n let menuPanelHeight = Math.max(Math.floor(bottomPanelHeight * 0.52), minMenuPanelHeight);\n if (menuPanelHeight > bottomPanelHeight - minAgentsPanelHeight) {\n menuPanelHeight = Math.max(bottomPanelHeight - minAgentsPanelHeight, minMenuPanelHeight);\n }\n const agentsPanelHeight = Math.max(bottomPanelHeight - menuPanelHeight, 0);\n const showClientsPanel = agentsPanelHeight >= 4;\n const rightPanelContentRows = Math.max(bottomPanelHeight - 5, 1);\n const rightPanelApproxWidth = Math.max(contentWidth - sidebarWidth - 3, 24);\n const rightPanelTextCols = Math.max(rightPanelApproxWidth - 12, 12);\n\n // Compact layout (stacked panels)\n // In compact mode, prioritize readability of the main view.\n let compactMenuPanelHeight = Math.min(Math.max(Math.floor(bottomPanelHeight * 0.28), 3), Math.max(bottomPanelHeight - 3, 1));\n let compactRemaining = Math.max(bottomPanelHeight - compactMenuPanelHeight, 1);\n let compactAgentsPanelHeight = compactRemaining >= 10 ? 5 : 0;\n let compactViewPanelHeight = Math.max(compactRemaining - compactAgentsPanelHeight, 1);\n if (compactMenuPanelHeight + compactAgentsPanelHeight + compactViewPanelHeight > bottomPanelHeight) {\n compactViewPanelHeight = Math.max(bottomPanelHeight - compactMenuPanelHeight - compactAgentsPanelHeight, 1);\n }\n if (compactMenuPanelHeight + compactAgentsPanelHeight + compactViewPanelHeight > bottomPanelHeight) {\n compactAgentsPanelHeight = 0;\n compactViewPanelHeight = Math.max(bottomPanelHeight - compactMenuPanelHeight, 1);\n }\n compactRemaining = Math.max(bottomPanelHeight - compactMenuPanelHeight, 1);\n if (compactViewPanelHeight > compactRemaining) compactViewPanelHeight = compactRemaining;\n const compactShowClientsPanel = compactAgentsPanelHeight >= 4;\n const compactRightPanelContentRows = Math.max(compactViewPanelHeight - 4, 1);\n const compactRightPanelTextCols = Math.max(contentWidth - 12, 12);\n\n return {\n minWideCols,\n isNarrowWidth,\n narrowWidth,\n containerWidth,\n contentWidth,\n isCompactLayout,\n sidebarWidth,\n bottomPanelHeight,\n menuPanelHeight,\n agentsPanelHeight,\n showClientsPanel,\n rightPanelContentRows,\n rightPanelTextCols,\n compactMenuPanelHeight,\n compactAgentsPanelHeight,\n compactShowClientsPanel,\n compactViewPanelHeight,\n compactRightPanelContentRows,\n compactRightPanelTextCols,\n };\n}\n","export function handleBootstrapInput({ input, key, actions, snapshot }) {\n if (key.upArrow) {\n actions.moveBootstrap?.(-1);\n return;\n }\n if (key.downArrow) {\n actions.moveBootstrap?.(1);\n return;\n }\n if (input === \"1\" || input === \"2\" || input === \"3\") {\n actions.chooseBootstrap?.(Number(input) - 1);\n return;\n }\n if (key.return || input === \" \") {\n actions.chooseBootstrap?.(snapshot.bootstrap?.selectedIndex ?? 0);\n }\n}\n","import { MENU_TABS } from \"../constants.mjs\";\n\nexport function handleMenuInput({ input, key, actions, menuIndex, setFocusMode, moveMenuIndex }) {\n const activeTab = MENU_TABS[Math.max(Number(menuIndex) || 0, 0)]?.id ?? \"logs\";\n if ((input === \"r\" || input === \"R\") && activeTab === \"contexts\") {\n actions.refreshResume?.();\n return;\n }\n\n if (key.upArrow) {\n moveMenuIndex(-1);\n return;\n }\n if (key.downArrow) {\n moveMenuIndex(1);\n return;\n }\n if (key.return || key.rightArrow) {\n actions.selectTab(menuIndex);\n setFocusMode(\"view\");\n }\n}\n\nexport function buildMoveMenuIndex(actions, setMenuIndex) {\n return (delta) => {\n setMenuIndex((prev) => {\n const base = Number.isInteger(prev) ? prev : 0;\n const next = Math.max(0, Math.min(base + delta, MENU_TABS.length - 1));\n if (next !== base) actions.selectTab(next);\n return next;\n });\n };\n}\n","export function isQuitInput(input, key) {\n return (key.ctrl && input === \"c\") || input === \"\\u0003\" || input === \"q\" || input === \"Q\";\n}\n","export function handleResumeTargetInput({ input, key, actions, snapshot }) {\n if (key.upArrow) {\n actions.moveResumeTarget?.(-1);\n return;\n }\n if (key.downArrow) {\n actions.moveResumeTarget?.(1);\n return;\n }\n if (input === \"1\" || input === \"2\" || input === \"3\") {\n actions.chooseResumeTarget?.(Number(input) - 1);\n return;\n }\n if (key.leftArrow || key.escape) {\n actions.cancelResumeTarget?.();\n return;\n }\n if (key.return || input === \" \") {\n actions.chooseResumeTarget?.(snapshot.resumeTargetPicker?.selectedIndex ?? 0);\n }\n}\n","export function handleUpdatePromptInput({ input, key, actions, snapshot }) {\n if (key.upArrow) {\n actions.moveUpdatePrompt?.(-1);\n return;\n }\n if (key.downArrow) {\n actions.moveUpdatePrompt?.(1);\n return;\n }\n if (input === \"1\" || input === \"2\") {\n actions.chooseUpdatePrompt?.(Number(input) - 1);\n return;\n }\n if (key.return || input === \" \") {\n actions.chooseUpdatePrompt?.(snapshot.updatePrompt?.selectedIndex ?? 0);\n }\n}\n","export function handleContextsViewInput({ input, key, actions, snapshot }) {\n const detailActive = snapshot?.detailView?.active;\n\n // ── detail mode ───────────────────────────────────────────────\n if (detailActive) {\n if (key.escape || key.leftArrow) {\n actions.closeDetail();\n return true;\n }\n if (key.upArrow) {\n actions.scrollDetail(-1);\n return true;\n }\n if (key.downArrow) {\n actions.scrollDetail(1);\n return true;\n }\n if (input === \"j\") {\n actions.scrollDetailLine(1);\n return true;\n }\n if (input === \"k\") {\n actions.scrollDetailLine(-1);\n return true;\n }\n if (input === \"r\") {\n actions.refreshDetail();\n return true;\n }\n return true;\n }\n\n // ── list mode ─────────────────────────────────────────────────\n if (key.upArrow) {\n actions.moveResume(-1);\n return true;\n }\n if (key.downArrow) {\n actions.moveResume(1);\n return true;\n }\n if (input === \"r\") {\n actions.refreshResume();\n return true;\n }\n if (key.return || input === \" \") {\n actions.enterContext();\n return true;\n }\n return false;\n}\n","export function handleConfigsViewInput({ input, key, actions }) {\n if (key.upArrow) {\n actions.moveConfig(-1);\n return true;\n }\n if (key.downArrow) {\n actions.moveConfig(1);\n return true;\n }\n if (key.return || key.rightArrow || input === \" \") {\n actions.toggleConfig();\n return true;\n }\n return false;\n}\n","import { handleContextsViewInput } from \"./view-contexts.mjs\";\nimport { handleConfigsViewInput } from \"./view-configs.mjs\";\n\nexport function handleViewInput({ input, key, actions, snapshot, selectedTabIndex, setFocusMode, setMenuIndex }) {\n // detail view captures Esc/← to close itself instead of leaving view mode\n if (snapshot.selectedTab === \"contexts\" && snapshot.detailView?.active) {\n handleContextsViewInput({ input, key, actions, snapshot });\n return;\n }\n\n if (key.leftArrow || key.escape) {\n setMenuIndex(selectedTabIndex);\n setFocusMode(\"menu\");\n return;\n }\n\n if (snapshot.selectedTab === \"contexts\") {\n handleContextsViewInput({ input, key, actions, snapshot });\n return;\n }\n\n if (snapshot.selectedTab === \"configs\") {\n handleConfigsViewInput({ input, key, actions });\n }\n}\n","import {\n handleBootstrapInput,\n buildMoveMenuIndex,\n handleMenuInput,\n handleResumeTargetInput,\n handleUpdatePromptInput,\n handleViewInput,\n isQuitInput,\n} from \"./input-handlers/index.mjs\";\n\nexport { buildMoveMenuIndex } from \"./input-handlers/index.mjs\";\n\nexport function createInputHandler({\n snapshot,\n actions,\n focusMode,\n menuIndex,\n selectedTabIndex,\n setFocusMode,\n setMenuIndex,\n moveMenuIndex,\n bootstrapActive,\n updatePromptActive,\n resumeTargetPickerActive,\n}) {\n return (input, key) => {\n if (isQuitInput(input, key)) {\n actions.stop();\n return;\n }\n\n // update prompt has highest priority\n if (updatePromptActive) {\n handleUpdatePromptInput({ input, key, actions, snapshot });\n return;\n }\n if (bootstrapActive) {\n handleBootstrapInput({ input, key, actions, snapshot });\n return;\n }\n if (resumeTargetPickerActive) {\n handleResumeTargetInput({ input, key, actions, snapshot });\n return;\n }\n if (focusMode === \"menu\") {\n handleMenuInput({ input, key, actions, menuIndex, setFocusMode, moveMenuIndex });\n return;\n }\n\n handleViewInput({\n input,\n key,\n actions,\n snapshot,\n selectedTabIndex,\n setFocusMode,\n setMenuIndex,\n });\n };\n}\n","import React from \"react\";\nimport { Text } from \"ink\";\n\nimport { UC_CLAUDE_ORANGE, UC_CODEX_BLUE, UC_OPENCLAW_RED } from \"./constants.mjs\";\n\nexport function compact(value, max = 80) {\n const raw = String(value ?? \"\");\n if (raw.length <= max) return raw;\n if (max <= 3) return raw.slice(0, max);\n return `${raw.slice(0, max - 3)}...`;\n}\n\nexport function formatTime(value = Date.now()) {\n return new Date(value).toISOString().slice(11, 19);\n}\n\nexport function formatContextDate(value) {\n if (!value) return \"-\";\n const d = new Date(value);\n if (Number.isNaN(d.getTime())) return \"-\";\n const yyyy = String(d.getFullYear()).padStart(4, \"0\");\n const mm = String(d.getMonth() + 1).padStart(2, \"0\");\n const dd = String(d.getDate()).padStart(2, \"0\");\n const hh = String(d.getHours()).padStart(2, \"0\");\n const mi = String(d.getMinutes()).padStart(2, \"0\");\n return `${yyyy}-${mm}-${dd} ${hh}:${mi}`;\n}\n\nexport function levelColor(level) {\n if (level === \"error\") return \"red\";\n if (level === \"warn\") return \"yellow\";\n if (level === \"info\") return \"green\";\n return \"cyan\";\n}\n\nexport function sourceColor(source) {\n const normalized = String(source ?? \"\").trim().toLowerCase();\n if (normalized === \"claude\" || normalized === \"claude code\") return UC_CLAUDE_ORANGE;\n if (normalized === \"codex\") return UC_CODEX_BLUE;\n if (normalized === \"openclaw\") return UC_OPENCLAW_RED;\n return \"gray\";\n}\n\nexport function sourceLabel(source) {\n const normalized = String(source ?? \"\").trim().toLowerCase();\n if (normalized === \"claude\" || normalized === \"claude code\") return \"Claude Code\";\n if (normalized === \"codex\") return \"Codex\";\n if (normalized === \"openclaw\") return \"OpenClaw\";\n return String(source ?? \"\");\n}\n\nexport function contextBadge(source) {\n const normalized = String(source ?? \"\").trim().toLowerCase();\n if (normalized === \"codex\") return { text: \"Codex\", color: sourceColor(\"codex\") };\n if (normalized === \"claude\" || normalized === \"claude code\") {\n return { text: \"Claude Code\", color: sourceColor(\"claude\") };\n }\n if (normalized === \"openclaw\") {\n return { text: \"OpenClaw\", color: sourceColor(\"openclaw\") };\n }\n const label = sourceLabel(source) || \"Unknown\";\n return { text: `Context: ${label}`, color: \"gray\" };\n}\n\nexport function fitToWidth(text, width) {\n const raw = String(text ?? \"\");\n if (width <= 0) return \"\";\n if (raw.length <= width) return raw;\n if (width === 1) return raw.slice(0, 1);\n return `${raw.slice(0, width - 1)}…`;\n}\n\nexport function padElements(elements, maxRows, keyPrefix) {\n const rows = elements.slice(0, Math.max(maxRows, 0));\n while (rows.length < maxRows) {\n rows.push(React.createElement(Text, { key: `${keyPrefix}-pad-${rows.length}` }, \" \"));\n }\n return rows;\n}\n\nexport function centerText(text, width, bias = 0) {\n const fitted = fitToWidth(text, width);\n const centeredLeft = Math.floor((width - fitted.length) / 2);\n const left = Math.max(centeredLeft + bias, 0);\n const right = Math.max(width - fitted.length - left, 0);\n return `${\" \".repeat(left)}${fitted}${\" \".repeat(right)}`;\n}\n","import { MENU_TABS } from \"./constants.mjs\";\n\nexport function selectedTabIndexFromId(tabId) {\n return Math.max(\n MENU_TABS.findIndex((tab) => tab.id === tabId),\n 0\n );\n}\n\nexport function selectedTabTitle(tabId) {\n return MENU_TABS.find((tab) => tab.id === tabId)?.label ?? \"View\";\n}\n\nexport function footerHelpText({ updatePromptActive, bootstrapActive, resumeTargetPickerActive, detailViewActive, selectedTab, focusMode }) {\n if (updatePromptActive) {\n return \"Update: ↑/↓ select, 1/2, Enter to confirm, q to quit.\";\n }\n if (bootstrapActive) {\n return \"Bootstrap: choose initial mode (↑/↓, 1/2/3, Enter) or q to quit.\";\n }\n if (resumeTargetPickerActive) {\n return \"Resume target: choose Claude Code or Codex (↑/↓, 1/2, Enter), Esc/← cancel.\";\n }\n if (focusMode !== \"view\") {\n return \"Controls: ↑/↓ navigate, Enter focus/open, ← back, q/Ctrl+C quit.\";\n }\n if (selectedTab === \"contexts\" && detailViewActive) {\n return \"Detail: ↑/↓ messages, j/k lines, r refresh, Esc/← back.\";\n }\n if (selectedTab === \"contexts\") {\n return \"Contexts: ↑/↓ select, Enter open, r refresh, ← back, q/Ctrl+C quit.\";\n }\n if (selectedTab === \"configs\") {\n return \"Controls: ↑/↓ select config, Enter/→ apply, ← back, q/Ctrl+C quit.\";\n }\n return \"Controls: ↑/↓ navigate, Enter focus/open, ← back, q/Ctrl+C quit.\";\n}\n","import React from \"react\";\nimport { TitledBox } from \"@mishieck/ink-titled-box\";\n\nexport function Section({\n title,\n width,\n grow,\n height,\n children,\n marginRight = 0,\n borderColor = \"blue\",\n titleColor = \"cyan\",\n borderStyle = \"single\",\n paddingX = 2,\n paddingY = 1,\n}) {\n return React.createElement(\n TitledBox,\n {\n key: `section:${title}:${width ?? \"auto\"}:${height ?? \"auto\"}:${paddingX}:${paddingY}:${borderStyle}`,\n borderStyle,\n titles: [title],\n titleJustify: \"flex-start\",\n borderColor,\n flexDirection: \"column\",\n paddingX,\n paddingY,\n width,\n flexGrow: grow ? 1 : 0,\n height,\n flexShrink: 0,\n marginRight,\n },\n children\n );\n}\n","import React from \"react\";\nimport { Text } from \"ink\";\n\nimport { compact } from \"../format.mjs\";\nimport { fitToWidth } from \"../format.mjs\";\nimport { Section } from \"./Section.mjs\";\n\nconst CLIENTS_PADDING_X = 2;\nconst CLIENTS_PADDING_Y = 1;\nconst CLIENTS_HORIZONTAL_FRAME = 4;\nconst CLIENTS_VERTICAL_FRAME = 2;\nconst SPARK_CHARS = \"▁▂▃▄▅▆▇█\";\n\nfunction formatLag(ms) {\n const safeMs = Math.max(Number(ms) || 0, 0);\n const totalSeconds = Math.floor(safeMs / 1000);\n if (totalSeconds < 60) return `${totalSeconds}s`;\n const minutes = Math.floor(totalSeconds / 60);\n if (minutes < 60) return `${minutes}m`;\n const hours = Math.floor(minutes / 60);\n return `${hours}h`;\n}\n\nfunction sparklineFromLag(history) {\n const values = Array.isArray(history) ? history : [];\n if (values.length === 0) return SPARK_CHARS[0];\n return values\n .map((lagMs) => {\n const normalized = 1 - Math.max(Math.min((Number(lagMs) || 0) / 10000, 1), 0);\n const index = Math.max(Math.min(Math.round(normalized * (SPARK_CHARS.length - 1)), SPARK_CHARS.length - 1), 0);\n return SPARK_CHARS[index];\n })\n .join(\"\");\n}\n\nfunction clientLabel(client) {\n return `${compact(client.userId ?? \"-\", 12)}@${compact(client.host ?? \"-\", 20)}`;\n}\n\nfunction compactClientLine(client, lagMs, sparkline, maxCols) {\n const base = `● ${clientLabel(client)} lag ${formatLag(lagMs)} ${sparkline}`;\n return fitToWidth(base, maxCols);\n}\n\nexport function ClientsPanel({ clients, now, height, width }) {\n const innerCols = Math.max((Number(width ?? 0) || 0) - CLIENTS_HORIZONTAL_FRAME - CLIENTS_PADDING_X * 2, 10);\n const estimatedRows = Math.max((Number(height ?? 0) || 0) - CLIENTS_VERTICAL_FRAME - CLIENTS_PADDING_Y * 2, 1);\n const nowTs = Number(now ?? Date.now()) || Date.now();\n const historyRef = React.useRef(new Map());\n\n const list = (Array.isArray(clients) ? clients : [])\n .map((client) => ({\n ...client,\n id: `${String(client?.userId ?? \"-\")}@${String(client?.host ?? \"-\")}`,\n lagMs: Math.max(nowTs - Number(client?.ts ?? nowTs), 0),\n }))\n .sort((a, b) => a.lagMs - b.lagMs);\n\n const activeClientIds = new Set();\n for (const client of list) {\n activeClientIds.add(client.id);\n const previous = historyRef.current.get(client.id) ?? [];\n const next = [...previous, client.lagMs].slice(-8);\n historyRef.current.set(client.id, next);\n }\n for (const key of [...historyRef.current.keys()]) {\n if (!activeClientIds.has(key)) historyRef.current.delete(key);\n }\n\n const rows = [];\n if (list.length === 0) {\n rows.push(\n React.createElement(\n Text,\n { key: \"clients-empty\", color: \"yellow\", wrap: \"truncate-end\" },\n fitToWidth(\"No clients online\", innerCols)\n )\n );\n } else if (estimatedRows < 4) {\n const first = list[0];\n const sparkline = sparklineFromLag(historyRef.current.get(first.id) ?? []);\n rows.push(\n React.createElement(\n Text,\n { key: `clients-compact-${first.id}`, color: \"white\", wrap: \"truncate-end\" },\n compactClientLine(first, first.lagMs, sparkline, innerCols)\n )\n );\n if (list.length > 1 && rows.length < estimatedRows) {\n rows.push(\n React.createElement(\n Text,\n { key: \"clients-compact-more\", color: \"gray\", dim: true, wrap: \"truncate-end\" },\n fitToWidth(`+${list.length - 1} more online`, innerCols)\n )\n );\n }\n } else {\n const maxVisibleClients = Math.max(Math.floor(estimatedRows / 2), 1);\n const visible = list.slice(0, maxVisibleClients);\n for (let index = 0; index < visible.length; index += 1) {\n const client = visible[index];\n const sparkline = sparklineFromLag(historyRef.current.get(client.id) ?? []);\n const head = fitToWidth(`● ${clientLabel(client)}`, innerCols);\n const detail = fitToWidth(`lag ${formatLag(client.lagMs)} · activity ${sparkline}`, innerCols);\n\n rows.push(\n React.createElement(\n Text,\n { key: `clients-head-${client.id}-${index}`, wrap: \"truncate-end\" },\n React.createElement(Text, { color: \"green\" }, \"● \"),\n React.createElement(Text, { color: \"white\" }, head.slice(2))\n )\n );\n if (rows.length < estimatedRows) {\n rows.push(\n React.createElement(Text, { key: `clients-detail-${client.id}-${index}`, color: \"gray\", dim: true, wrap: \"truncate-end\" }, detail)\n );\n }\n }\n if (list.length > visible.length && rows.length < estimatedRows) {\n rows.push(\n React.createElement(\n Text,\n { key: \"clients-more\", color: \"gray\", dim: true, wrap: \"truncate-end\" },\n fitToWidth(`+${list.length - visible.length} more online`, innerCols)\n )\n );\n }\n }\n\n return React.createElement(\n Section,\n {\n title: \"Clients\",\n height,\n width,\n borderColor: \"gray\",\n titleColor: \"white\",\n paddingX: CLIENTS_PADDING_X,\n paddingY: CLIENTS_PADDING_Y,\n },\n ...rows\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport { fitToWidth } from \"../format.mjs\";\nimport { heroArtForWidth } from \"../hero-art.mjs\";\n\nfunction clamp(value, min, max) {\n return Math.min(Math.max(value, min), max);\n}\n\nfunction centerAround(text, width, center) {\n const fitted = fitToWidth(text, width);\n const safeCenter = clamp(Math.floor(center), 0, Math.max(width - 1, 0));\n const maxLeft = Math.max(width - fitted.length, 0);\n const left = clamp(safeCenter - Math.floor(fitted.length / 2), 0, maxLeft);\n const right = Math.max(width - fitted.length - left, 0);\n return `${\" \".repeat(left)}${fitted}${\" \".repeat(right)}`;\n}\n\nexport function HeroLockup({ width, tagline, artCenterBias = 0 }) {\n const lockupWidth = Math.max(width, 8);\n const rawArtLines = heroArtForWidth(lockupWidth).map((line) => fitToWidth(String(line ?? \"\"), lockupWidth));\n const artBlockWidth = Math.max(...rawArtLines.map((line) => line.length), 0);\n const maxLeft = Math.max(lockupWidth - artBlockWidth, 0);\n const artLeft = clamp(Math.floor((lockupWidth - artBlockWidth) / 2) + artCenterBias, 0, maxLeft);\n const artLines = rawArtLines.map((line) => fitToWidth(`${\" \".repeat(artLeft)}${line}`, lockupWidth));\n const taglineText = `[ ${tagline} ]`;\n const artCenter = artLeft + Math.floor(Math.max(artBlockWidth - 1, 0) / 2);\n const taglineLine = centerAround(taglineText, lockupWidth, artCenter);\n\n return React.createElement(\n Box,\n { flexDirection: \"column\", width: lockupWidth, alignItems: \"flex-start\", justifyContent: \"flex-start\" },\n ...artLines.map((line, index) =>\n React.createElement(Text, { key: `hero-${index}`, color: \"white\", bold: true }, line)\n ),\n React.createElement(Text, { color: \"white\" }, \" \"),\n React.createElement(Text, { color: \"blue\", bold: true }, taglineLine)\n );\n}\n","import React from \"react\";\nimport { Text } from \"ink\";\n\nimport { MENU_TABS, UC_BRAND_BLUE, UC_BLUE_LIGHT } from \"../constants.mjs\";\nimport { fitToWidth } from \"../format.mjs\";\nimport { Section } from \"./Section.mjs\";\n\nconst MENU_PADDING_X = 2;\nconst MENU_PADDING_Y = 1;\nconst MENU_HORIZONTAL_FRAME = 4;\nconst MENU_VERTICAL_FRAME = 2;\n\nexport function MenuPanel({ focusMode, menuIndex, selectedTab, height, width }) {\n const innerCols = Math.max(\n (Number(width ?? 0) || 0) - MENU_HORIZONTAL_FRAME - MENU_PADDING_X * 2,\n 10\n );\n const activeIndex = Math.max(\n focusMode === \"menu\" ? Number(menuIndex ?? 0) : MENU_TABS.findIndex((tab) => tab.id === selectedTab),\n 0\n );\n const estimatedRows = Math.max(\n (Number(height ?? 0) || 0) - MENU_VERTICAL_FRAME - MENU_PADDING_Y * 2,\n 1\n );\n const listCapacity = Math.max(Math.min(estimatedRows, MENU_TABS.length), 1);\n const start = Math.max(\n Math.min(activeIndex - Math.floor(listCapacity / 2), Math.max(MENU_TABS.length - listCapacity, 0)),\n 0\n );\n const end = Math.min(start + listCapacity, MENU_TABS.length);\n const visibleTabs = MENU_TABS.slice(start, end);\n\n return React.createElement(\n Section,\n {\n title: \"Menu\",\n width,\n height,\n borderColor: \"gray\",\n titleColor: \"white\",\n paddingX: MENU_PADDING_X,\n paddingY: MENU_PADDING_Y,\n },\n ...visibleTabs.map((tab, visibleIndex) => {\n const index = start + visibleIndex;\n const isFocusedInMenu = focusMode === \"menu\" && index === menuIndex;\n const isActiveInView = focusMode !== \"menu\" && index === activeIndex;\n const isHighlighted = isFocusedInMenu || isActiveInView;\n const marker = isHighlighted ? \"[•]\" : \"[ ]\";\n const markerColor = isHighlighted ? UC_BRAND_BLUE : \"white\";\n const labelColor = isHighlighted ? UC_BLUE_LIGHT : \"white\";\n const labelMax = Math.max(innerCols - marker.length - 1, 4);\n const label = fitToWidth(tab.label, labelMax);\n const lineLen = marker.length + 1 + label.length;\n const tailPad = \" \".repeat(Math.max(innerCols - lineLen, 0));\n\n return React.createElement(\n Text,\n { key: `menu-${tab.id}-${start}-${listCapacity}`, wrap: \"truncate-end\" },\n React.createElement(Text, { color: markerColor }, marker),\n \" \",\n React.createElement(Text, { color: labelColor, dim: !isHighlighted }, label),\n tailPad\n );\n })\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\nimport { TitledBox } from \"@mishieck/ink-titled-box\";\n\nimport { UC_BRAND_BLUE } from \"../constants.mjs\";\nimport { fitToWidth } from \"../format.mjs\";\n\nexport function NarrowWidthPanel({ minWideCols, narrowWidth, stdoutColumns }) {\n return React.createElement(\n Box,\n { flexDirection: \"column\" },\n React.createElement(\n TitledBox,\n {\n borderStyle: \"single\",\n titles: [\"UltraContext v1.1\"],\n titleJustify: \"flex-start\",\n borderColor: UC_BRAND_BLUE,\n flexDirection: \"column\",\n paddingX: 2,\n paddingY: 1,\n width: narrowWidth,\n },\n React.createElement(Text, { color: \"yellow\", bold: true, wrap: \"truncate-end\" }, \"Window too narrow\"),\n React.createElement(\n Text,\n { color: \"gray\", wrap: \"truncate-end\" },\n fitToWidth(`Resize terminal width to at least ${minWideCols} cols (current=${stdoutColumns}).`, Math.max(narrowWidth - 6, 12))\n )\n )\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\nimport { TitledBox } from \"@mishieck/ink-titled-box\";\n\nimport { UC_BLUE_LIGHT, UC_BRAND_BLUE } from \"../constants.mjs\";\n\nexport function BootstrapPanel({ snapshot, width }) {\n const options = snapshot.bootstrap?.options ?? [];\n const selectedIndex = Math.max(\n Math.min(snapshot.bootstrap?.selectedIndex ?? 0, Math.max(options.length - 1, 0)),\n 0\n );\n const sourceLabel = (snapshot.bootstrap?.sourceNames ?? []).join(\", \") || \"sources\";\n\n return React.createElement(\n TitledBox,\n {\n key: `bootstrap:${width}:${options.length}`,\n borderStyle: \"single\",\n titles: [\"First Sync Setup\"],\n titleJustify: \"flex-start\",\n borderColor: UC_BRAND_BLUE,\n flexDirection: \"column\",\n paddingX: 2,\n paddingY: 1,\n width,\n },\n React.createElement(Text, { color: \"white\", bold: true }, `How should sync start for: ${sourceLabel}?`),\n React.createElement(Box, { height: 1 }),\n ...options.map((option, index) => {\n const selected = index === selectedIndex;\n return React.createElement(\n Box,\n { key: `bootstrap-option-${option.id}`, flexDirection: \"column\" },\n React.createElement(\n Text,\n { color: selected ? UC_BLUE_LIGHT : \"white\" },\n selected ? \"[•]\" : \"[ ]\",\n ` ${index + 1}. ${option.label}`\n ),\n React.createElement(Text, { color: \"gray\" }, ` ${option.description}`)\n );\n }),\n React.createElement(Box, { height: 1 }),\n React.createElement(Text, { color: \"gray\" }, \"Choose: ↑/↓, 1/2/3 or Enter\")\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport { UC_BLUE_LIGHT } from \"../constants.mjs\";\nimport { compact, padElements } from \"../format.mjs\";\n\nexport function ConfigsContent({ snapshot, viewFocused, maxRows }) {\n const configItems = snapshot.configEditor?.items ?? [];\n const selectedConfigIndex = Math.max(\n Math.min(snapshot.configEditor?.selectedIndex ?? 0, Math.max(configItems.length - 1, 0)),\n 0\n );\n const rows = [];\n for (let index = 0; index < configItems.length; index += 1) {\n const item = configItems[index];\n const selected = index === selectedConfigIndex;\n const marker = selected ? \"[•]\" : \"[ ]\";\n const rowColor = selected && viewFocused ? UC_BLUE_LIGHT : \"white\";\n const status =\n item.kind === \"action\"\n ? item.valueLabel ?? \"RUN\"\n : item.kind === \"enum\"\n ? item.valueLabel ?? String(item.value ?? \"-\")\n : item.value ? \"ON\" : \"OFF\";\n const detail = item.blockedByMaster\n ? `${item.description ?? \"\"} (disabled while Master sounds is OFF)`\n : item.description ?? \"\";\n rows.push(\n React.createElement(\n Text,\n { key: `config-row-${item.key}`, color: rowColor },\n `${marker} ${item.label} [${status}]`\n )\n );\n if (detail) {\n rows.push(\n React.createElement(\n Text,\n { key: `config-detail-${item.key}`, color: item.blockedByMaster ? \"yellow\" : \"gray\" },\n compact(` ${detail}`, 130)\n )\n );\n }\n }\n\n if (rows.length === 0) {\n rows.push(React.createElement(Text, { key: \"config-empty\", color: \"yellow\" }, \"No editable configs found.\"));\n }\n if (snapshot.resume.notice) {\n rows.push(React.createElement(Text, { key: \"config-gap\" }, \" \"));\n rows.push(\n React.createElement(Text, { key: \"config-notice\", color: \"gray\" }, compact(`last action: ${snapshot.resume.notice}`, 130))\n );\n }\n\n return React.createElement(Box, { flexDirection: \"column\" }, ...padElements(rows, maxRows, \"cfg\"));\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport { compact, contextBadge, padElements } from \"../format.mjs\";\n\n// ── role helpers ─────────────────────────────────────────────────\n\nfunction roleColor(role) {\n if (role === \"user\") return \"green\";\n if (role === \"assistant\") return \"blue\";\n return \"gray\";\n}\n\nfunction normalizeRole(msg) {\n const role = String(msg?.role ?? \"system\").toLowerCase();\n if (role === \"user\" || role === \"human\") return \"user\";\n if (role === \"assistant\" || role === \"agent\") return \"assistant\";\n return \"system\";\n}\n\n// ── extract full message text (no truncation) ───────────────────\n\nfunction messageText(msg) {\n const content = msg?.content;\n if (typeof content === \"string\") return content;\n if (content && typeof content === \"object\") {\n if (typeof content.message === \"string\") return content.message;\n if (typeof content.text === \"string\") return content.text;\n return JSON.stringify(content, null, 2);\n }\n return \"\";\n}\n\nfunction messageTimestamp(msg) {\n const raw = msg?.content?.timestamp ?? msg?.metadata?.timestamp ?? \"\";\n if (!raw) return \"\";\n const d = new Date(raw);\n if (Number.isNaN(d.getTime())) return String(raw).slice(0, 5);\n const hh = String(d.getHours()).padStart(2, \"0\");\n const mm = String(d.getMinutes()).padStart(2, \"0\");\n return `${hh}:${mm}`;\n}\n\n// ── wrap a single line respecting maxWidth ──────────────────────\n\nfunction wrapLine(text, maxWidth) {\n if (!text) return [\"\"];\n const width = Math.max(maxWidth, 10);\n const lines = [];\n let remaining = text;\n while (remaining.length > width) {\n lines.push(remaining.slice(0, width));\n remaining = remaining.slice(width);\n }\n lines.push(remaining);\n return lines;\n}\n\n// ── build visual lines from messages ────────────────────────────\n\nfunction buildMessageLines(messages, maxWidth) {\n const lines = [];\n const separatorWidth = Math.max(maxWidth, 10);\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n const role = normalizeRole(msg);\n const ts = messageTimestamp(msg);\n const fullText = messageText(msg);\n const color = roleColor(role);\n\n // separator: ── role · HH:MM ──────────\n const label = ts ? `${role} · ${ts}` : role;\n const labelPart = `── ${label} `;\n const fillLen = Math.max(separatorWidth - labelPart.length, 0);\n const fill = \"─\".repeat(fillLen);\n lines.push({ type: \"separator\", color, label: `${labelPart}${fill}`, msgIndex: i });\n\n // split by real newlines, wrap each, preserve structure\n const rawLines = (fullText || \"(empty)\").split(/\\r?\\n/);\n for (const rawLine of rawLines) {\n for (const wrapped of wrapLine(rawLine, maxWidth)) {\n lines.push({ type: \"text\", text: wrapped, msgIndex: i });\n }\n }\n\n // blank line between messages\n if (i < messages.length - 1) {\n lines.push({ type: \"blank\", msgIndex: i });\n }\n }\n\n return lines;\n}\n\n// ── main component ──────────────────────────────────────────────\n\nexport function ContextDetailContent({ snapshot, maxRows, maxCols }) {\n const dv = snapshot.detailView;\n const textWidth = Math.max((maxCols ?? 60) - 2, 20);\n const rows = [];\n const totalMsgs = dv.messages.length;\n\n const source = dv.contextMeta?.source ?? \"unknown\";\n const badge = contextBadge(source);\n\n // header placeholder (filled after scroll info is known)\n const headerIdx = 0;\n rows.push(null);\n rows.push(React.createElement(Text, { key: \"detail-spacer\" }, \" \"));\n\n // loading state\n if (dv.loading) {\n rows[headerIdx] = renderHeader({ badge, dv, scrollInfo: \"loading...\" });\n rows.push(React.createElement(Text, { key: \"detail-loading\", color: \"yellow\" }, \"Loading messages...\"));\n return React.createElement(Box, { flexDirection: \"column\" }, ...padElements(rows, maxRows, \"dtl\"));\n }\n\n // error state\n if (dv.error) {\n rows[headerIdx] = renderHeader({ badge, dv, scrollInfo: \"error\" });\n rows.push(React.createElement(Text, { key: \"detail-error\", color: \"red\" }, `Error: ${dv.error}`));\n return React.createElement(Box, { flexDirection: \"column\" }, ...padElements(rows, maxRows, \"dtl\"));\n }\n\n // empty state\n if (totalMsgs === 0) {\n rows[headerIdx] = renderHeader({ badge, dv, scrollInfo: \"empty\" });\n rows.push(React.createElement(Text, { key: \"detail-empty\", color: \"gray\" }, \"No messages in this context.\"));\n return React.createElement(Box, { flexDirection: \"column\" }, ...padElements(rows, maxRows, \"dtl\"));\n }\n\n // build all visual lines\n const allLines = buildMessageLines(dv.messages, textWidth);\n const availableRows = Math.max(maxRows - rows.length, 1);\n\n // two-level scroll: ↑/↓ by message (scrollOffset), j/k by line (lineOffset)\n const targetMsg = Math.max(0, Math.min(dv.scrollOffset, totalMsgs - 1));\n let msgStartLine = 0;\n for (let i = 0; i < allLines.length; i++) {\n if (allLines[i].msgIndex === targetMsg) {\n msgStartLine = i;\n break;\n }\n }\n\n // apply fine line offset, clamped\n const maxScroll = Math.max(allLines.length - availableRows, 0);\n const startLine = Math.max(0, Math.min(msgStartLine + (dv.lineOffset ?? 0), maxScroll));\n\n // header with scroll info\n const msgLabel = `msg ${targetMsg + 1}/${totalMsgs}`;\n const pct = allLines.length > 0 ? Math.min(Math.round(((startLine + availableRows) / allLines.length) * 100), 100) : 100;\n rows[headerIdx] = renderHeader({ badge, dv, scrollInfo: `${msgLabel} ${pct}%` });\n\n // render visible slice\n const visibleLines = allLines.slice(startLine, startLine + availableRows);\n for (let i = 0; i < visibleLines.length; i++) {\n const line = visibleLines[i];\n if (line.type === \"separator\") {\n rows.push(React.createElement(Text, { key: `dtl-l-${i}`, color: line.color, bold: true }, line.label));\n } else if (line.type === \"text\") {\n rows.push(React.createElement(Text, { key: `dtl-l-${i}` }, line.text));\n } else {\n rows.push(React.createElement(Text, { key: `dtl-l-${i}` }, \" \"));\n }\n }\n\n return React.createElement(Box, { flexDirection: \"column\" }, ...padElements(rows, maxRows, \"dtl\"));\n}\n\n// ── header helper ───────────────────────────────────────────────\n\nfunction renderHeader({ badge, dv, scrollInfo }) {\n return React.createElement(\n Text,\n { key: \"detail-header\", wrap: \"truncate-end\" },\n React.createElement(Text, { color: badge.color, bold: true }, `[${badge.text}]`),\n React.createElement(Text, { color: \"gray\" }, ` ${compact(dv.contextId ?? \"\", 36)} `),\n React.createElement(Text, { color: \"cyan\" }, scrollInfo),\n React.createElement(Text, { color: \"gray\" }, \" ↑/↓ msg j/k line r refresh Esc back\")\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport { UC_BLUE_LIGHT } from \"../constants.mjs\";\nimport { compact, contextBadge, formatContextDate, padElements } from \"../format.mjs\";\nimport { ContextDetailContent } from \"./ContextDetailContent.mjs\";\n\nexport function ContextsContent({ snapshot, viewFocused, maxRows, maxCols }) {\n // detail view takes over the panel\n if (snapshot.detailView?.active) {\n return React.createElement(ContextDetailContent, { snapshot, maxRows, maxCols });\n }\n\n const contexts = snapshot.resume.contexts;\n const total = contexts.length;\n const selected = Math.max(Math.min(snapshot.resume.selectedIndex, Math.max(total - 1, 0)), 0);\n\n const rows = [];\n\n const tailRows = [];\n if (total > 0 && (snapshot.resume.notice || snapshot.resume.error || snapshot.resume.summaryPath || snapshot.resume.command)) {\n const selectedContext = contexts[selected];\n const selectedCreatedAt = formatContextDate(selectedContext?.created_at);\n const selectedInfo = contextBadge(selectedContext?.metadata?.source || \"unknown\");\n tailRows.push(\n React.createElement(\n Text,\n { key: \"contexts-selected\", color: \"gray\" },\n `selected: ${selectedCreatedAt} `,\n React.createElement(Text, { color: selectedInfo.color, bold: true }, `[${selectedInfo.text}]`),\n ` id=${compact(selectedContext?.id ?? \"-\", 36)}`\n )\n );\n }\n if (tailRows.length > 0) tailRows.push(React.createElement(Text, { key: \"contexts-spacer-1\" }, \" \"));\n if (snapshot.resume.notice) {\n tailRows.push(\n React.createElement(Text, { key: \"contexts-notice\", color: \"green\" }, `info: ${compact(snapshot.resume.notice, 120)}`)\n );\n }\n if (snapshot.resume.error) {\n tailRows.push(React.createElement(Text, { key: \"contexts-error\", color: \"red\" }, `error: ${compact(snapshot.resume.error, 120)}`));\n }\n if (snapshot.resume.summaryPath) {\n tailRows.push(\n React.createElement(Text, { key: \"contexts-summary\", color: \"gray\" }, `summary: ${compact(snapshot.resume.summaryPath, 120)}`)\n );\n }\n if (snapshot.resume.command) {\n tailRows.push(\n React.createElement(Text, { key: \"contexts-command\", color: \"gray\" }, `command: ${compact(snapshot.resume.command, 120)}`)\n );\n }\n if (snapshot.resume.commandPath) {\n tailRows.push(\n React.createElement(Text, { key: \"contexts-command-path\", color: \"gray\" }, `command file: ${compact(snapshot.resume.commandPath, 120)}`)\n );\n }\n\n const availableRows = Math.max(maxRows, 4);\n const listCapacity = Math.max(availableRows - tailRows.length, 1);\n\n if (total === 0) {\n rows.push(React.createElement(Text, { key: \"contexts-empty\", color: \"yellow\" }, \"No contexts available.\"));\n } else {\n const start = Math.max(Math.min(selected - Math.floor(listCapacity / 2), Math.max(total - listCapacity, 0)), 0);\n const end = Math.min(start + listCapacity, total);\n for (let i = start; i < end; i += 1) {\n const ctx = contexts[i];\n const md = ctx?.metadata ?? {};\n const rowSelected = i === selected;\n const marker = rowSelected ? \"[•]\" : \"[ ]\";\n const rowColor = viewFocused && rowSelected ? UC_BLUE_LIGHT : \"white\";\n const sourceInfo = contextBadge(md.source || \"unknown\");\n const createdAt = formatContextDate(ctx?.created_at);\n const user = compact(md.user_id ?? \"-\", 12);\n const sessionId = compact(md.session_id ?? \"-\", 28);\n rows.push(\n React.createElement(\n Text,\n { key: `contexts-row-${i}`, color: rowColor },\n `${marker} `,\n React.createElement(Text, { color: sourceInfo.color, bold: true }, `[${sourceInfo.text}]`),\n ` ${createdAt} ${user} ${sessionId}`\n )\n );\n }\n }\n rows.push(...tailRows);\n\n return React.createElement(Box, { flexDirection: \"column\" }, ...padElements(rows, maxRows, \"ctx\"));\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport Spinner from \"../../Spinner.mjs\";\nimport { HeroLockup } from \"../components/index.mjs\";\nimport { fitToWidth, formatTime } from \"../format.mjs\";\n\nfunction formatUptime(value) {\n const ms = Math.max(Number(value) || 0, 0);\n const totalSeconds = Math.floor(ms / 1000);\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n if (hours > 0) return `${hours}h${String(minutes).padStart(2, \"0\")}m`;\n if (minutes > 0) return `${minutes}m${String(seconds).padStart(2, \"0\")}s`;\n return `${seconds}s`;\n}\n\nexport function HeaderPanel({ snapshot, stdoutColumns }) {\n const [pulseOn, setPulseOn] = React.useState(true);\n\n React.useEffect(() => {\n const timer = setInterval(() => {\n setPulseOn((current) => !current);\n }, 320);\n timer.unref?.();\n return () => clearInterval(timer);\n }, []);\n\n const health = snapshot.stats.errors > 0 ? \"DEGRADED\" : \"HEALTHY\";\n const healthColor = health === \"HEALTHY\" ? \"green\" : \"yellow\";\n const tagline = \"Same context, everywhere\";\n const innerWidth = Math.max(stdoutColumns, 40);\n const spinnerVisualWidth = 28;\n const gap = innerWidth >= 96 ? 3 : 2;\n const artWidth = Math.max(innerWidth - spinnerVisualWidth - gap, 8);\n const statusPrefix = \"status \";\n const healthToken = `● ${health}`;\n const clientsOnline = Array.isArray(snapshot.onlineClients) ? snapshot.onlineClients.length : 0;\n const dashboardTail = [\n `live ${formatTime(snapshot.now)}`,\n `☻ ${snapshot.cfg.userId}`,\n `clients ${clientsOnline}`,\n `uptime ${formatUptime(Date.now() - Number(snapshot.stats.startedAt ?? 0))}`,\n ].join(\" │ \");\n const tailMax = Math.max(innerWidth - statusPrefix.length - healthToken.length - 3, 0);\n const fittedTail = fitToWidth(dashboardTail, tailMax);\n\n return React.createElement(\n Box,\n { flexDirection: \"column\", width: innerWidth },\n React.createElement(\n Box,\n { flexDirection: \"row\", alignItems: \"center\", width: innerWidth },\n React.createElement(Spinner, { color: \"white\" }),\n React.createElement(Box, { width: gap }),\n React.createElement(\n HeroLockup,\n { width: artWidth, tagline }\n )\n ),\n React.createElement(\n Box,\n { flexDirection: \"row\", width: innerWidth },\n React.createElement(Text, { color: \"gray\", dim: true }, statusPrefix),\n React.createElement(\n Text,\n { color: healthColor, bold: true },\n React.createElement(Text, { color: healthColor, dim: !pulseOn }, \"●\"),\n ` ${health}`\n ),\n fittedTail\n ? React.createElement(Text, { color: \"gray\", dim: true }, ` │ ${fittedTail}`)\n : null\n )\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport { fitToWidth, levelColor, padElements, sourceColor, sourceLabel } from \"../format.mjs\";\n\nfunction classifyLog(entry) {\n const text = String(entry?.text ?? \"\").toLowerCase();\n if (text.includes(\"bootstrap\")) return { label: \"BOOTSTRAP\", color: \"cyan\" };\n if (text.includes(\"config\")) return { label: \"CONFIG\", color: \"yellow\" };\n if (text.includes(\"daemon\") || text.includes(\"instance lock\")) return { label: \"DAEMON\", color: \"green\" };\n if (entry?.level === \"error\") return { label: \"ERROR\", color: \"red\" };\n if (entry?.level === \"warn\") return { label: \"WARN\", color: \"yellow\" };\n return { label: \"\", color: \"gray\" };\n}\n\nexport function LogsContent({ snapshot, maxRows, maxCols = 100 }) {\n const rows = [];\n const safeCols = Math.max(maxCols, 12);\n const visibleLogs = snapshot.recentLogs.slice(-Math.max(maxRows, 1)).reverse();\n\n if (visibleLogs.length === 0) {\n rows.push(\n React.createElement(Text, { key: \"log-empty\", color: \"gray\", wrap: \"truncate-end\" }, fitToWidth(\"waiting for activity...\", safeCols))\n );\n } else {\n rows.push(\n ...visibleLogs.map((entry, index) => {\n const category = classifyLog(entry);\n const sourceTag = entry.source ? `[${sourceLabel(entry.source)}]` : \"\";\n const timePrefix = `${String(entry.ts ?? \"--:--:--\")} `;\n const typePrefix = category.label ? `[${category.label}] ` : \"\";\n const sourcePrefix = sourceTag ? `${sourceTag} ` : \"\";\n const prefixWidth = 2 + 1 + timePrefix.length + typePrefix.length + sourcePrefix.length;\n const messageMax = Math.max(safeCols - prefixWidth, 8);\n const message = fitToWidth(String(entry.text ?? \"\"), messageMax);\n const messageColor = entry.level === \"warn\" || entry.level === \"error\" ? levelColor(entry.level) : \"white\";\n\n return React.createElement(\n Text,\n { key: `log-${index}`, wrap: \"truncate-end\" },\n React.createElement(Text, { color: category.color }, \"● \"),\n React.createElement(Text, { color: \"gray\", dim: true }, timePrefix),\n typePrefix\n ? React.createElement(Text, { color: category.color, bold: true }, typePrefix)\n : null,\n sourceTag\n ? React.createElement(Text, { color: sourceColor(entry.source), bold: true }, sourcePrefix)\n : null,\n React.createElement(Text, { color: messageColor }, message)\n );\n })\n );\n }\n\n return React.createElement(Box, { flexDirection: \"column\" }, ...padElements(rows, maxRows, \"log\"));\n}\n","import React from \"react\";\n\nimport { ConfigsContent } from \"./ConfigsContent.mjs\";\nimport { ContextsContent } from \"./ContextsContent.mjs\";\nimport { LogsContent } from \"./LogsContent.mjs\";\n\nexport function RightPanel({ snapshot, viewFocused, maxRows, maxCols }) {\n if (snapshot.selectedTab === \"configs\") return React.createElement(ConfigsContent, { snapshot, viewFocused, maxRows });\n if (snapshot.selectedTab === \"contexts\") return React.createElement(ContextsContent, { snapshot, viewFocused, maxRows, maxCols });\n return React.createElement(LogsContent, { snapshot, maxRows, maxCols });\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport { UC_BLUE_LIGHT, UC_BRAND_BLUE } from \"../constants.mjs\";\nimport { fitToWidth } from \"../format.mjs\";\nimport { selectedTabTitle } from \"../state.mjs\";\nimport { ClientsPanel, MenuPanel, Section } from \"../components/index.mjs\";\nimport { RightPanel } from \"./RightPanel.mjs\";\n\nfunction renderFocusedViewTop(width, title) {\n const safeWidth = Math.max(Number(width) || 0, 4);\n const innerWidth = Math.max(safeWidth - 2, 1);\n const paddedTitle = ` ${title} `;\n const shownTitle = fitToWidth(paddedTitle, innerWidth);\n const fillWidth = Math.max(innerWidth - shownTitle.length, 0);\n\n return React.createElement(\n Text,\n { color: UC_BRAND_BLUE, wrap: \"truncate-end\" },\n \"╔\",\n React.createElement(Text, { color: UC_BLUE_LIGHT, bold: true }, shownTitle),\n \"═\".repeat(fillWidth),\n \"╗\"\n );\n}\n\nfunction ViewSection({ snapshot, focusMode, width, grow, height, maxRows, maxCols }) {\n const viewFocused = focusMode === \"view\";\n const title = selectedTabTitle(snapshot.selectedTab);\n\n if (viewFocused) {\n return React.createElement(\n Box,\n { flexDirection: \"column\", width, flexGrow: grow ? 1 : 0, flexShrink: 0 },\n renderFocusedViewTop(width, title),\n React.createElement(\n Box,\n {\n borderStyle: \"double\",\n borderTop: false,\n borderColor: UC_BRAND_BLUE,\n flexDirection: \"column\",\n paddingX: 2,\n paddingY: 1,\n width,\n height,\n flexGrow: grow ? 1 : 0,\n flexShrink: 0,\n },\n React.createElement(RightPanel, {\n snapshot,\n viewFocused,\n maxRows,\n maxCols,\n })\n )\n );\n }\n\n return React.createElement(\n Section,\n {\n title,\n width,\n height,\n grow,\n borderColor: \"cyan\",\n titleColor: \"white\",\n borderStyle: \"double\",\n },\n React.createElement(RightPanel, {\n snapshot,\n viewFocused,\n maxRows,\n maxCols,\n })\n );\n}\n\nexport function MainPanels({ snapshot, layout, focusMode, menuIndex, clients }) {\n if (layout.isCompactLayout) {\n const clientsSection = layout.compactShowClientsPanel\n ? React.createElement(ClientsPanel, {\n clients,\n now: snapshot.now,\n height: layout.compactAgentsPanelHeight,\n width: layout.contentWidth,\n })\n : null;\n\n return React.createElement(\n Box,\n { flexDirection: \"column\", alignItems: \"flex-start\", width: layout.contentWidth },\n React.createElement(MenuPanel, {\n focusMode,\n menuIndex,\n selectedTab: snapshot.selectedTab,\n height: layout.compactMenuPanelHeight,\n width: layout.contentWidth,\n }),\n React.createElement(ViewSection, {\n snapshot,\n focusMode,\n width: layout.contentWidth,\n height: layout.compactViewPanelHeight,\n maxRows: layout.compactRightPanelContentRows,\n maxCols: layout.compactRightPanelTextCols,\n }),\n clientsSection\n );\n }\n\n const clientsSection = layout.showClientsPanel\n ? React.createElement(ClientsPanel, {\n clients,\n now: snapshot.now,\n height: layout.agentsPanelHeight,\n width: layout.sidebarWidth,\n })\n : null;\n\n const rightPanelWidth = Math.max(layout.contentWidth - layout.sidebarWidth, 20);\n\n return React.createElement(\n Box,\n { flexDirection: \"row\", alignItems: \"flex-start\", height: layout.bottomPanelHeight, width: layout.contentWidth },\n React.createElement(\n Box,\n { flexDirection: \"column\", width: layout.sidebarWidth, marginRight: 0, height: layout.bottomPanelHeight, flexShrink: 0 },\n React.createElement(MenuPanel, {\n focusMode,\n menuIndex,\n selectedTab: snapshot.selectedTab,\n height: layout.menuPanelHeight,\n width: layout.sidebarWidth,\n }),\n clientsSection\n ),\n React.createElement(ViewSection, {\n snapshot,\n focusMode,\n width: rightPanelWidth,\n height: layout.bottomPanelHeight,\n maxRows: layout.rightPanelContentRows,\n maxCols: layout.rightPanelTextCols,\n })\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\nimport { TitledBox } from \"@mishieck/ink-titled-box\";\n\nimport { UC_BLUE_LIGHT, UC_BRAND_BLUE } from \"../constants.mjs\";\nimport { compact, sourceColor, sourceLabel } from \"../format.mjs\";\n\nexport function ResumeTargetPanel({ snapshot, width }) {\n const picker = snapshot.resumeTargetPicker ?? {};\n const options = picker.options ?? [];\n const selectedIndex = Math.max(\n Math.min(picker.selectedIndex ?? 0, Math.max(options.length - 1, 0)),\n 0\n );\n const source = sourceLabel(picker.source || \"unknown\");\n const contextId = compact(picker.contextId ?? \"-\", 42);\n\n return React.createElement(\n TitledBox,\n {\n key: `resume-target:${width}:${options.length}`,\n borderStyle: \"single\",\n titles: [\"Continue Conversation\"],\n titleJustify: \"flex-start\",\n borderColor: UC_BRAND_BLUE,\n flexDirection: \"column\",\n paddingX: 2,\n paddingY: 1,\n width,\n },\n React.createElement(Text, { color: \"white\", bold: true }, \"Continue selected context in:\"),\n React.createElement(\n Text,\n { color: \"gray\" },\n `source=${source} id=${contextId}`\n ),\n React.createElement(Box, { height: 1 }),\n ...options.map((option, index) => {\n const selected = index === selectedIndex;\n return React.createElement(\n Text,\n { key: `resume-target-option-${option.id}`, color: selected ? UC_BLUE_LIGHT : \"white\" },\n selected ? \"[•]\" : \"[ ]\",\n \" \",\n React.createElement(Text, { color: sourceColor(option.id), bold: true }, option.label)\n );\n }),\n React.createElement(Box, { height: 1 }),\n React.createElement(Text, { color: \"gray\" }, `Choose: ↑/↓, ${options.map((_, i) => i + 1).join(\"/\")} or Enter`),\n React.createElement(Text, { color: \"gray\" }, \"Cancel: Esc or ←\")\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\nimport { TitledBox } from \"@mishieck/ink-titled-box\";\n\nimport { UC_BLUE_LIGHT, UC_BRAND_BLUE } from \"../constants.mjs\";\n\nexport function UpdatePromptPanel({ snapshot, width }) {\n const prompt = snapshot.updatePrompt ?? {};\n const options = prompt.options ?? [];\n const selectedIndex = Math.max(\n Math.min(prompt.selectedIndex ?? 0, Math.max(options.length - 1, 0)),\n 0\n );\n const current = snapshot.currentVersion ?? \"?\";\n const latest = prompt.latestVersion ?? \"?\";\n\n return React.createElement(\n TitledBox,\n {\n key: `update-prompt:${width}`,\n borderStyle: \"single\",\n titles: [\"Update Available\"],\n titleJustify: \"flex-start\",\n borderColor: UC_BRAND_BLUE,\n flexDirection: \"column\",\n paddingX: 2,\n paddingY: 1,\n width,\n },\n React.createElement(\n Text,\n { color: \"white\", bold: true },\n `New version available: `,\n React.createElement(Text, { color: \"gray\" }, `v${current}`),\n ` → `,\n React.createElement(Text, { color: \"green\", bold: true }, `v${latest}`)\n ),\n React.createElement(Box, { height: 1 }),\n ...options.map((option, index) => {\n const selected = index === selectedIndex;\n return React.createElement(\n Text,\n { key: `update-option-${option.id}`, color: selected ? UC_BLUE_LIGHT : \"white\" },\n selected ? \"[•]\" : \"[ ]\",\n ` ${index + 1}. ${option.label}`\n );\n }),\n React.createElement(Box, { height: 1 }),\n React.createElement(Text, { color: \"gray\" }, \"Choose: ↑/↓, 1/2 or Enter\")\n );\n}\n","import React from \"react\";\nimport { Box, Text, useInput, useStdout } from \"ink\";\n\nimport { UC_BLUE_LIGHT, UC_BRAND_BLUE } from \"./constants.mjs\";\nimport { computeTuiLayout } from \"./layout.mjs\";\nimport { buildMoveMenuIndex, createInputHandler } from \"./input.mjs\";\nimport { fitToWidth } from \"./format.mjs\";\nimport { footerHelpText, selectedTabIndexFromId } from \"./state.mjs\";\nimport { NarrowWidthPanel } from \"./components/index.mjs\";\nimport { BootstrapPanel, HeaderPanel, MainPanels, ResumeTargetPanel, UpdatePromptPanel } from \"./panels/index.mjs\";\n\nconst FOOTER_QUIPS = [\n \"Who is John Galt?\",\n \"ultrathink -> ultracontext\",\n \"Welcome to the beginning of infinity.\",\n \"Our job is to take the jobs.\",\n];\n\nfunction renderFooterQuip(quip) {\n const token = \"ultrathink\";\n const lower = String(quip ?? \"\").toLowerCase();\n const index = lower.indexOf(token);\n if (index < 0) {\n return React.createElement(Text, { color: \"gray\", bold: true }, quip);\n }\n\n const before = quip.slice(0, index);\n const match = quip.slice(index, index + token.length);\n const after = quip.slice(index + token.length);\n\n return React.createElement(\n Box,\n { flexDirection: \"row\", flexShrink: 0 },\n before ? React.createElement(Text, { key: \"quip-before\", color: \"gray\", bold: true }, before) : null,\n React.createElement(Text, { key: \"quip-strike\", color: \"gray\", bold: true, strikethrough: true }, match),\n after ? React.createElement(Text, { key: \"quip-after\", color: \"gray\", bold: true }, after) : null\n );\n}\n\nfunction renderMainFrameTop(width, title) {\n const safeWidth = Math.max(Number(width) || 0, 4);\n const innerWidth = Math.max(safeWidth - 2, 1);\n const paddedTitle = ` ${title} `;\n const shownTitle = fitToWidth(paddedTitle, innerWidth);\n const fillWidth = Math.max(innerWidth - shownTitle.length, 0);\n\n return React.createElement(\n Text,\n { color: UC_BRAND_BLUE, wrap: \"truncate-end\" },\n \"┌\",\n React.createElement(Text, { color: UC_BLUE_LIGHT, bold: true }, shownTitle),\n \"─\".repeat(fillWidth),\n \"┐\"\n );\n}\n\nexport function DaemonTui({ snapshot, actions }) {\n const { stdout } = useStdout();\n const [terminalSize, setTerminalSize] = React.useState(() => ({\n cols: stdout?.columns ?? process.stdout.columns ?? 120,\n rows: stdout?.rows ?? process.stdout.rows ?? 40,\n }));\n\n React.useEffect(() => {\n const target = stdout ?? process.stdout;\n if (!target) return;\n\n const update = () => {\n const next = {\n cols: Math.max(target.columns ?? process.stdout.columns ?? 120, 1),\n rows: Math.max(target.rows ?? process.stdout.rows ?? 40, 1),\n };\n setTerminalSize((current) => (current.cols === next.cols && current.rows === next.rows ? current : next));\n };\n\n update();\n target.on?.(\"resize\", update);\n return () => {\n if (typeof target.off === \"function\") {\n target.off(\"resize\", update);\n } else if (typeof target.removeListener === \"function\") {\n target.removeListener(\"resize\", update);\n }\n };\n }, [stdout]);\n\n const stdoutColumns = terminalSize.cols;\n const stdoutRows = terminalSize.rows;\n const layout = computeTuiLayout(stdoutColumns, stdoutRows);\n const selectedTabIndex = selectedTabIndexFromId(snapshot.selectedTab);\n\n const updatePromptActive = Boolean(snapshot.updatePrompt?.active);\n const bootstrapActive = Boolean(snapshot.bootstrap?.active);\n const resumeTargetPickerActive = Boolean(snapshot.resumeTargetPicker?.active);\n const [focusMode, setFocusMode] = React.useState(\"menu\");\n const [menuIndex, setMenuIndex] = React.useState(selectedTabIndex);\n const [quipIndex, setQuipIndex] = React.useState(0);\n\n React.useEffect(() => {\n if (focusMode === \"menu\") setMenuIndex(selectedTabIndex);\n }, [focusMode, selectedTabIndex]);\n\n React.useEffect(() => {\n const timer = setInterval(() => {\n setQuipIndex((current) => (current + 1) % FOOTER_QUIPS.length);\n }, 3800);\n return () => clearInterval(timer);\n }, []);\n\n const moveMenuIndex = React.useMemo(() => buildMoveMenuIndex(actions, setMenuIndex), [actions]);\n\n useInput(\n createInputHandler({\n snapshot,\n actions,\n focusMode,\n menuIndex,\n selectedTabIndex,\n setFocusMode,\n setMenuIndex,\n moveMenuIndex,\n bootstrapActive,\n updatePromptActive,\n resumeTargetPickerActive,\n })\n );\n\n const clients = Array.isArray(snapshot.onlineClients) ? snapshot.onlineClients : [];\n\n if (layout.isNarrowWidth) {\n return React.createElement(NarrowWidthPanel, {\n minWideCols: layout.minWideCols,\n narrowWidth: layout.narrowWidth,\n stdoutColumns,\n });\n }\n\n const bodyContent = updatePromptActive\n ? React.createElement(UpdatePromptPanel, { snapshot, width: layout.contentWidth })\n : bootstrapActive\n ? React.createElement(BootstrapPanel, { snapshot, width: layout.contentWidth })\n : resumeTargetPickerActive\n ? React.createElement(ResumeTargetPanel, { snapshot, width: layout.contentWidth })\n : React.createElement(MainPanels, { snapshot, layout, focusMode, menuIndex, clients });\n\n const footerLeft = footerHelpText({\n updatePromptActive,\n bootstrapActive,\n resumeTargetPickerActive,\n detailViewActive: Boolean(snapshot.detailView?.active),\n selectedTab: snapshot.selectedTab,\n focusMode,\n });\n const footerWidth = Math.max(layout.containerWidth, 24);\n const quipRaw = FOOTER_QUIPS[quipIndex % FOOTER_QUIPS.length];\n const quip = fitToWidth(quipRaw, Math.max(Math.floor(footerWidth * 0.48), 18));\n const leftMax = Math.max(footerWidth - quip.length - 2, 12);\n const left = fitToWidth(footerLeft, leftMax);\n const gap = \" \".repeat(Math.max(footerWidth - left.length - quip.length, 1));\n const footerRule = \"─\".repeat(Math.max(footerWidth, 1));\n\n return React.createElement(\n Box,\n { flexDirection: \"column\" },\n React.createElement(Box, { width: layout.containerWidth }, renderMainFrameTop(\n layout.containerWidth,\n snapshot.updateAvailable\n ? `UltraContext v${snapshot.currentVersion} ↑`\n : `UltraContext v${snapshot.currentVersion}`\n )),\n React.createElement(\n Box,\n {\n borderStyle: \"single\",\n borderTop: false,\n borderColor: UC_BRAND_BLUE,\n flexDirection: \"column\",\n paddingX: 0,\n paddingY: 0,\n width: layout.containerWidth,\n },\n React.createElement(HeaderPanel, { snapshot, stdoutColumns: layout.contentWidth }),\n bodyContent\n ),\n React.createElement(\n Box,\n { width: footerWidth, flexDirection: \"column\" },\n React.createElement(Text, { color: \"gray\", dim: true, wrap: \"truncate-end\" }, footerRule),\n React.createElement(\n Box,\n { width: footerWidth, flexDirection: \"row\" },\n React.createElement(\n Text,\n { color: \"gray\", wrap: \"truncate-end\" },\n `${left}${gap}`\n ),\n renderFooterQuip(quip)\n )\n )\n );\n}\n","import React from \"react\";\nimport { render } from \"ink\";\n\nimport { DaemonTui } from \"./DaemonTui.mjs\";\n\nexport function createInkUiController({ getSnapshot, actions }) {\n let app = null;\n let lastCols = null;\n let lastRows = null;\n const view = () => React.createElement(DaemonTui, { snapshot: getSnapshot(), actions });\n\n const readDims = () => ({\n cols: process.stdout.columns ?? 0,\n rows: process.stdout.rows ?? 0,\n });\n\n return {\n start() {\n if (app) return;\n app = render(view(), { exitOnCtrlC: false });\n const dims = readDims();\n lastCols = dims.cols;\n lastRows = dims.rows;\n },\n refresh() {\n if (!app) return;\n const dims = readDims();\n const sizeChanged = dims.cols !== lastCols || dims.rows !== lastRows;\n if (sizeChanged && typeof app.clear === \"function\") {\n app.clear();\n }\n lastCols = dims.cols;\n lastRows = dims.rows;\n app.rerender(view());\n },\n stop() {\n if (!app) return;\n app.unmount();\n app = null;\n lastCols = null;\n lastRows = null;\n },\n };\n}\n","// tui core — exported as tuiBoot(), no env.mjs import (caller handles that)\nimport fs from \"node:fs/promises\";\nimport fsSync from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport { spawn, spawnSync } from \"node:child_process\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { UltraContext } from \"ultracontext\";\nimport { normalizeBootstrapMode } from \"./protocol.mjs\";\n\nimport {\n hasLocalClaudeSession,\n hasLocalCodexSession,\n writeClaudeSession,\n writeCodexSession,\n} from \"@ultracontext/parsers\";\nimport { MENU_TABS, createInkUiController } from \"./ui.mjs\";\nimport { boolFromEnv, expandHome, toInt } from \"./utils.mjs\";\n\nconst DEFAULT_RUNTIME_CONFIG_FILE = \"~/.ultracontext/config.json\";\n\n// ── status.json polling path ───────────────────────────────────\n\nconst STATUS_FILE = path.join(os.homedir(), \".ultracontext\", \"status.json\");\n\nasync function readStatusJson() {\n try {\n const raw = await fs.readFile(STATUS_FILE, \"utf8\");\n return JSON.parse(raw);\n } catch { return null; }\n}\n\n// ── config.json write helper for TUI mutations ────────────────\n\nfunction writeConfigKey(key, value) {\n try {\n const configPath = path.join(os.homedir(), \".ultracontext\", \"config.json\");\n let data = {};\n try { data = JSON.parse(fsSync.readFileSync(configPath, \"utf8\")); } catch { /* empty */ }\n data[key] = value;\n const tmp = configPath + \".tmp.tui\";\n fsSync.writeFileSync(tmp, JSON.stringify(data, null, 2) + \"\\n\", \"utf8\");\n fsSync.renameSync(tmp, configPath);\n return true;\n } catch {\n return false;\n }\n}\n\n// ── exported boot function ──────────────────────────────────────\n\nexport async function tuiBoot({\n assetsRoot,\n onFatalError,\n} = {}) {\n\nconst APP_ROOT = assetsRoot ?? path.resolve(path.dirname(fileURLToPath(import.meta.url)), \"..\");\nconst DEFAULT_STARTUP_SOUND_FILE = path.join(APP_ROOT, \"assets\", \"sounds\", \"hello_mf.mp3\");\nconst DEFAULT_CONTEXT_SOUND_FILE = path.join(APP_ROOT, \"assets\", \"sounds\", \"quack.mp3\");\nconst OFFLINE_NOTICE = \"Daemon offline — status.json stale or missing.\";\n\nconst CONFIG_BOOTSTRAP_MODES = [\n { id: \"prompt\", label: \"Ask on startup\" },\n { id: \"new_only\", label: \"New only\" },\n { id: \"last_24h\", label: \"Last 24h\" },\n { id: \"all\", label: \"All\" },\n];\nconst CONFIG_RESUME_TERMINALS = [\n { id: \"terminal\", label: \"Terminal\" },\n { id: \"warp\", label: \"Warp\" },\n];\nconst RESUME_TARGET_OPTIONS = [\n { id: \"claude\", label: \"Claude Code\" },\n { id: \"codex\", label: \"Codex\" },\n];\nconst INSPECT_OPTION = { id: \"inspect\", label: \"Inspect messages\" };\nconst PERSISTED_CONFIG_FIELDS = [\n \"soundEnabled\",\n \"startupSoundEnabled\",\n \"contextSoundEnabled\",\n \"bootstrapMode\",\n \"resumeTerminal\",\n \"claudeIncludeSubagents\",\n \"resumeOpenTab\",\n \"startupGreetingFile\",\n \"contextCreatedSoundFile\",\n];\n\nfunction normalizeApiKey(raw) {\n if (!raw) return \"\";\n return String(raw).trim().replace(/^['\"]|['\"]$/g, \"\");\n}\n\nfunction normalizeResumeSourceFilter(raw) {\n const value = String(raw ?? \"all\").trim().toLowerCase();\n if (value === \"codex\" || value === \"claude\" || value === \"openclaw\" || value === \"all\") return value;\n return \"all\";\n}\n\nfunction normalizeResumeTerminal(raw) {\n const value = String(raw ?? \"terminal\").trim().toLowerCase();\n if (value === \"warp\") return \"warp\";\n return \"terminal\";\n}\n\nfunction resolveRuntimeConfigPath() {\n return expandHome(process.env.ULTRACONTEXT_CONFIG_FILE ?? DEFAULT_RUNTIME_CONFIG_FILE);\n}\n\nfunction normalizeBootstrapModeWithPrompt(raw) {\n return normalizeBootstrapMode(raw, { allowPrompt: true }) || \"\";\n}\n\nfunction readEnv(...keys) {\n for (const key of keys) {\n if (process.env[key] !== undefined) return process.env[key];\n }\n return undefined;\n}\n\nconst cfg = {\n apiKey: normalizeApiKey(process.env.ULTRACONTEXT_API_KEY),\n baseUrl: (process.env.ULTRACONTEXT_BASE_URL ?? \"https://api.ultracontext.ai\").trim(),\n userId: process.env.DAEMON_USER_ID ?? process.env.USER ?? \"unknown-user\",\n host: (process.env.DAEMON_HOST || os.hostname() || \"unknown-host\").trim(),\n uiRefreshMs: toInt(process.env.TUI_REFRESH_MS, 1200),\n resumeAutoRefreshMs: Math.max(toInt(process.env.RESUME_AUTO_REFRESH_MS, 3500), 0),\n uiRecentLimit: toInt(process.env.TUI_RECENT_LIMIT, 240),\n configFile: resolveRuntimeConfigPath(),\n soundEnabled: boolFromEnv(readEnv(\"TUI_SOUND_ENABLED\", \"DAEMON_SOUND_ENABLED\"), true),\n startupSoundEnabled: boolFromEnv(\n readEnv(\"TUI_STARTUP_SOUND_ENABLED\", \"DAEMON_STARTUP_SOUND_ENABLED\"),\n true\n ),\n contextSoundEnabled: boolFromEnv(\n readEnv(\"TUI_CONTEXT_SOUND_ENABLED\", \"DAEMON_CONTEXT_SOUND_ENABLED\"),\n true\n ),\n startupGreetingFile: expandHome(\n readEnv(\"TUI_STARTUP_SOUND_FILE\", \"DAEMON_STARTUP_GREETING_FILE\") ?? DEFAULT_STARTUP_SOUND_FILE\n ),\n contextCreatedSoundFile: expandHome(\n readEnv(\"TUI_CONTEXT_SOUND_FILE\", \"DAEMON_CONTEXT_SOUND_FILE\") ?? DEFAULT_CONTEXT_SOUND_FILE\n ),\n bootstrapMode: normalizeBootstrapModeWithPrompt(process.env.DAEMON_BOOTSTRAP_MODE ?? \"prompt\") || \"prompt\",\n bootstrapReset: boolFromEnv(process.env.DAEMON_BOOTSTRAP_RESET, false),\n claudeIncludeSubagents: boolFromEnv(process.env.CLAUDE_INCLUDE_SUBAGENTS, false),\n resumeTerminal: normalizeResumeTerminal(process.env.RESUME_TERMINAL),\n resumeContextLimit: toInt(process.env.RESUME_CONTEXT_LIMIT, 1000),\n resumeSourceFilter: normalizeResumeSourceFilter(process.env.RESUME_SOURCE_FILTER),\n resumeSummaryTail: toInt(process.env.RESUME_SUMMARY_TAIL, 14),\n resumeOutputDir: expandHome(process.env.RESUME_OUTPUT_DIR ?? \"~/.codex/resume\"),\n resumeOpenTab: boolFromEnv(process.env.RESUME_OPEN_TAB, true),\n};\n\nconst stats = {\n startedAt: Date.now(),\n cycles: 0,\n filesScanned: 0,\n linesRead: 0,\n parsedEvents: 0,\n appended: 0,\n deduped: 0,\n contextsCreated: 0,\n errors: 0,\n};\n\nconst CONFIG_TOGGLES = [\n {\n key: \"soundEnabled\",\n label: \"Master sounds\",\n description: \"Enable or disable all app sounds\",\n },\n {\n key: \"startupSoundEnabled\",\n label: \"Startup sounds\",\n description: \"Play sound when the TUI starts\",\n },\n {\n key: \"contextSoundEnabled\",\n label: \"Context sounds\",\n description: \"Play duck sound when the TUI detects a new context\",\n },\n];\n\n// ── update check helpers ─────────────────────────────────────────\n\nconst UPDATE_CHECK_INTERVAL = 3 * 60 * 60 * 1000; // 3h\n\nfunction readTuiVersion() {\n try {\n const pkgPath = path.resolve(APP_ROOT, \"package.json\");\n const pkg = JSON.parse(fsSync.readFileSync(pkgPath, \"utf8\"));\n return pkg.version ?? \"unknown\";\n } catch { return \"unknown\"; }\n}\n\nfunction getUpdateCheckPath() {\n return path.join(os.homedir(), \".ultracontext\", \"update-check.json\");\n}\n\nfunction readUpdateCache() {\n try { return JSON.parse(fsSync.readFileSync(getUpdateCheckPath(), \"utf8\")); }\n catch { return null; }\n}\n\nfunction writeUpdateCache(data) {\n try { fsSync.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 isNewerVersion(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\nasync function checkForUpdateSilent() {\n const current = readTuiVersion();\n if (current === \"unknown\") return;\n\n const notifyUpdate = (latest) => {\n ui.updateAvailable = latest;\n ui.updatePrompt.active = true;\n ui.updatePrompt.selectedIndex = 0;\n ui.updatePrompt.latestVersion = latest;\n renderDashboard();\n };\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 && isNewerVersion(cache.latestVersion, current)) {\n notifyUpdate(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 && isNewerVersion(latest, current)) {\n notifyUpdate(latest);\n }\n}\n\nconst UPDATE_PROMPT_OPTIONS = [\n { id: \"install\", label: \"Install now\" },\n { id: \"skip\", label: \"Skip\" },\n];\n\nconst ui = {\n daemonOnline: false,\n currentVersion: readTuiVersion(),\n updateAvailable: \"\",\n updatePrompt: {\n active: false,\n selectedIndex: 0,\n latestVersion: \"\",\n },\n recentLogs: [],\n onlineClients: 0,\n sourceStats: [],\n selectedTab: \"logs\",\n configEditor: {\n selectedIndex: 0,\n },\n resume: {\n loading: false,\n syncing: false,\n contexts: [],\n selectedIndex: 0,\n loadedAt: 0,\n error: \"\",\n notice: \"\",\n summaryPath: \"\",\n command: \"\",\n commandPath: \"\",\n },\n detailView: {\n active: false,\n contextId: null,\n contextMeta: null,\n messages: [],\n scrollOffset: 0,\n lineOffset: 0,\n loading: false,\n error: null,\n },\n resumeTargetPicker: {\n active: false,\n selectedIndex: 0,\n source: \"\",\n contextId: \"\",\n options: RESUME_TARGET_OPTIONS,\n recommendedTarget: \"\",\n },\n bootstrap: {\n active: false,\n selectedIndex: 0,\n options: [],\n sourceNames: [],\n note: \"\",\n },\n};\n\nconst runtime = {\n uc: null,\n uiController: null,\n renderTimer: null,\n statusPollTimer: null,\n contextRefreshTimer: null,\n stop: null,\n seenLogSignatures: new Set(),\n seenLogQueue: [],\n syncCount: 0,\n resumeKnownContextIds: new Set(),\n resumeBaselineReady: false,\n};\n\nconst sound = { startupFile: \"\", contextFile: \"\", warnedNonDarwin: false };\n\n// ── status.json → UI state applicator ──────────────────────────\n\nfunction applyDaemonStatus(status) {\n if (!status) {\n ui.daemonOnline = false;\n return;\n }\n\n // check liveness — if updatedAt is stale by >5s, daemon is offline\n const updatedAt = new Date(status.updatedAt).getTime();\n const staleMs = Date.now() - updatedAt;\n ui.daemonOnline = staleMs < 30_000;\n\n if (!ui.daemonOnline) return;\n\n // apply stats\n Object.assign(stats, status.stats || {});\n\n // apply source stats\n ui.sourceStats = (status.sources || []).map(s => ({\n name: s.name,\n filesScanned: s.filesScanned || 0,\n linesRead: s.linesRead || 0,\n parsedEvents: s.parsedEvents || 0,\n appended: s.appended || 0,\n deduped: s.deduped || 0,\n contextsCreated: s.contextsCreated || 0,\n errors: s.errors || 0,\n lastEventType: s.lastEventType || \"-\",\n lastSessionId: s.lastSessionId || \"-\",\n lastAt: s.lastAt || 0,\n lastFile: s.lastFile || \"-\",\n }));\n\n // apply logs (deduplicate by signature)\n if (status.recentLogs && Array.isArray(status.recentLogs)) {\n for (const entry of status.recentLogs) {\n const sig = `${entry.ts}|${entry.level}|${entry.source}|${entry.text}`;\n if (!runtime.seenLogSignatures.has(sig)) {\n runtime.seenLogSignatures.add(sig);\n ui.recentLogs.push(entry);\n }\n }\n // cap logs + prune dedup set to prevent unbounded growth\n while (ui.recentLogs.length > cfg.uiRecentLimit) ui.recentLogs.shift();\n if (runtime.seenLogSignatures.size > cfg.uiRecentLimit * 2) {\n const keep = new Set();\n for (const entry of ui.recentLogs) {\n keep.add(`${entry.ts}|${entry.level}|${entry.source}|${entry.text}`);\n }\n runtime.seenLogSignatures = keep;\n }\n }\n\n // apply config from daemon\n if (status.config) {\n if (status.config.bootstrapMode) cfg.bootstrapMode = status.config.bootstrapMode;\n if (status.config.claudeIncludeSubagents !== undefined) cfg.claudeIncludeSubagents = Boolean(status.config.claudeIncludeSubagents);\n }\n\n // update online clients count (just show 1 if daemon is running)\n ui.onlineClients = ui.daemonOnline ? 1 : 0;\n}\n\n// ── poll daemon status ─────────────────────────────────────────\n\nasync function pollDaemonStatus() {\n const status = await readStatusJson();\n applyDaemonStatus(status);\n}\n\nfunction runtimeLogsKeep() {\n return Math.max(cfg.uiRecentLimit, 180);\n}\n\nfunction formatTime(value = Date.now()) {\n return new Date(value).toISOString().slice(11, 19);\n}\n\nfunction errorDetails(error) {\n if (!error || typeof error !== \"object\") {\n return { message: String(error) };\n }\n\n const details = {\n message: error.message ?? String(error),\n };\n\n if (\"status\" in error) details.status = error.status;\n if (\"url\" in error) details.url = error.url;\n if (\"bodyText\" in error) details.bodyText = error.bodyText;\n return details;\n}\n\nfunction renderDashboard() {\n runtime.uiController?.refresh();\n}\n\nfunction resumeCompact(value, max = 60) {\n const raw = String(value ?? \"\");\n if (raw.length <= max) return raw;\n if (max <= 3) return raw.slice(0, max);\n return `${raw.slice(0, max - 3)}...`;\n}\n\nfunction resumeNormalizeRole(message) {\n const role = String(message?.role ?? \"system\").toLowerCase();\n if (role === \"user\" || role === \"human\") return \"user\";\n if (role === \"assistant\" || role === \"agent\") return \"assistant\";\n return \"system\";\n}\n\nfunction resumeMessageText(message) {\n const content = message?.content;\n if (typeof content === \"string\") return resumeCompact(content.replace(/\\s+/g, \" \").trim(), 220);\n if (content && typeof content === \"object\") {\n if (typeof content.message === \"string\") return resumeCompact(content.message.replace(/\\s+/g, \" \").trim(), 220);\n if (typeof content.text === \"string\") return resumeCompact(content.text.replace(/\\s+/g, \" \").trim(), 220);\n return resumeCompact(JSON.stringify(content), 220);\n }\n return \"\";\n}\n\nfunction resumeMessageTimestamp(message) {\n return message?.content?.timestamp ?? message?.metadata?.timestamp ?? \"\";\n}\n\nfunction resumeMessageEventType(message) {\n return message?.content?.event_type ?? message?.metadata?.event_type ?? \"message\";\n}\n\nfunction resumeExtractSessionCwd(messages) {\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const cwd = messages[i]?.content?.raw?.payload?.cwd;\n if (typeof cwd === \"string\" && cwd.length > 0) return cwd;\n }\n return \"\";\n}\n\nasync function resumeResolveWorkingDirectory(preferredCwd) {\n if (!preferredCwd) return process.cwd();\n try {\n const stat = await fs.stat(preferredCwd);\n if (stat.isDirectory()) return preferredCwd;\n } catch {\n // Fall back to current directory.\n }\n return process.cwd();\n}\n\nfunction resumeShellQuote(value) {\n return `'${String(value).replace(/'/g, `'\"'\"'`)}'`;\n}\n\nfunction resumeAppleScriptString(value) {\n return `\"${String(value).replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"`;\n}\n\nfunction runAppleScriptLines(scriptLines) {\n const args = [];\n for (const line of scriptLines) args.push(\"-e\", line);\n const out = spawnSync(\"osascript\", args, { stdio: \"pipe\", encoding: \"utf8\" });\n if (out.status !== 0) {\n return {\n ok: false,\n reason: out.stderr?.trim() || out.stdout?.trim() || \"osascript failed\",\n };\n }\n return { ok: true };\n}\n\nfunction warpLaunchConfigDirs() {\n const home = os.homedir();\n return [\n path.join(home, \".warp\", \"launch_configurations\"),\n path.join(home, \"Library\", \"Application Support\", \"dev.warp.Warp-Stable\", \"launch_configurations\"),\n path.join(home, \"Library\", \"Application Support\", \"dev.warp.Warp-Preview\", \"launch_configurations\"),\n ];\n}\n\nfunction warpLaunchConfigYaml({ name, cwd, command }) {\n const safeCommand = String(command ?? \"\").replace(/\\r?\\n/g, \" && \");\n return [\n \"---\",\n `name: ${JSON.stringify(name)}`,\n \"windows:\",\n \" - tabs:\",\n \" - title: UltraContext Resume\",\n \" layout:\",\n ` cwd: ${JSON.stringify(cwd)}`,\n \" commands:\",\n ` - exec: ${JSON.stringify(safeCommand)}`,\n \"\",\n ].join(\"\\n\");\n}\n\nfunction runOpenUri(uri) {\n const out = spawnSync(\"open\", [uri], { stdio: \"pipe\", encoding: \"utf8\" });\n if (out.status !== 0) {\n return {\n ok: false,\n reason: out.stderr?.trim() || out.stdout?.trim() || \"open uri failed\",\n };\n }\n return { ok: true };\n}\n\nfunction resumeWarpPasteAndRun(command, { openNewTab = false } = {}) {\n const scriptLines = [\n \"set _uc_prev_clipboard to the clipboard\",\n `set the clipboard to ${resumeAppleScriptString(command)}`,\n \"tell application \\\"Warp\\\" to activate\",\n \"delay 0.85\",\n \"tell application \\\"System Events\\\"\",\n ];\n if (openNewTab) {\n scriptLines.push(\"keystroke \\\"t\\\" using {command down}\", \"delay 0.45\");\n }\n scriptLines.push(\n \"keystroke \\\"v\\\" using {command down}\",\n \"delay 0.25\",\n \"key code 36\",\n \"delay 0.18\",\n \"key code 36\",\n \"end tell\",\n \"delay 0.05\",\n \"set the clipboard to _uc_prev_clipboard\"\n );\n return runAppleScriptLines(scriptLines);\n}\n\nfunction resumeOpenWarpNewWindowAndRun(command) {\n spawnSync(\"open\", [\"-a\", \"Warp\"], { stdio: \"ignore\" });\n runAppleScriptLines([\"tell application \\\"Warp\\\" to activate\", \"delay 0.12\"]);\n\n const uri = `warp://action/new_window?path=${encodeURIComponent(process.cwd())}`;\n const opened = runOpenUri(uri);\n if (!opened.ok) return opened;\n\n runAppleScriptLines([\"tell application \\\"Warp\\\" to activate\", \"delay 0.3\"]);\n return resumeWarpPasteAndRun(command, { openNewTab: false });\n}\n\nfunction resumeOpenWarpViaUri(command) {\n try {\n const timestamp = Date.now();\n const launchName = `ultracontext_resume_${timestamp}_${process.pid}`;\n const yaml = warpLaunchConfigYaml({\n name: `UltraContext Resume ${timestamp}`,\n cwd: process.cwd(),\n command,\n });\n\n let primaryFilePath = \"\";\n for (const dir of warpLaunchConfigDirs()) {\n try {\n fsSync.mkdirSync(dir, { recursive: true });\n const filePath = path.join(dir, `${launchName}.yaml`);\n fsSync.writeFileSync(filePath, yaml, \"utf8\");\n if (!primaryFilePath) primaryFilePath = filePath;\n } catch {\n // Best effort.\n }\n }\n\n if (!primaryFilePath) {\n return { ok: false, reason: \"could not write Warp launch configuration file\" };\n }\n\n const uri = `warp://launch/${encodeURIComponent(primaryFilePath)}`;\n spawnSync(\"open\", [\"-a\", \"Warp\"], { stdio: \"ignore\" });\n runAppleScriptLines([\"tell application \\\"Warp\\\" to activate\", \"delay 0.12\"]);\n\n const opened = runOpenUri(uri);\n if (!opened.ok) return opened;\n\n runAppleScriptLines([\"tell application \\\"Warp\\\" to activate\", \"delay 0.12\"]);\n return { ok: true };\n } catch (error) {\n return {\n ok: false,\n reason: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nfunction resumeOpenAppleTerminalTab(command) {\n const scriptLines = [\n \"tell application \\\"Terminal\\\"\",\n \"activate\",\n \"if (count of windows) = 0 then\",\n ` do script ${resumeAppleScriptString(command)}`,\n \"else\",\n ` do script ${resumeAppleScriptString(command)} in front window`,\n \"end if\",\n \"end tell\",\n ];\n const out = runAppleScriptLines(scriptLines);\n return out.ok ? { ...out, method: \"terminal_applescript\" } : { ...out, method: \"terminal_applescript\" };\n}\n\nfunction resumeOpenWarpTab(command) {\n const uriLaunch = resumeOpenWarpViaUri(command);\n if (uriLaunch.ok) return { ...uriLaunch, method: \"warp_uri_launch\" };\n\n const newWindowFlow = resumeOpenWarpNewWindowAndRun(command);\n if (newWindowFlow.ok) return { ...newWindowFlow, method: \"warp_new_window_paste\" };\n\n const firstTry = resumeWarpPasteAndRun(command, { openNewTab: true });\n if (firstTry.ok) return { ...firstTry, method: \"warp_new_tab_paste\" };\n\n const fallback = resumeWarpPasteAndRun(command, { openNewTab: false });\n if (fallback.ok) return { ...fallback, method: \"warp_current_tab_paste\" };\n\n return {\n ok: false,\n method: \"warp_failed\",\n reason: `${newWindowFlow.reason}; ${uriLaunch.reason}; ${firstTry.reason}; fallback failed: ${fallback.reason}. Check macOS Accessibility permission for your terminal and osascript/System Events.`,\n };\n}\n\nfunction resumeOpenTerminalTab(command) {\n if (process.platform !== \"darwin\") {\n return { ok: false, reason: \"open-tab is available only on macOS\" };\n }\n if (cfg.resumeTerminal === \"warp\") return resumeOpenWarpTab(command);\n return resumeOpenAppleTerminalTab(command);\n}\n\nfunction readProcessInfo(pid) {\n try {\n const out = spawnSync(\"ps\", [\"-o\", \"ppid=,command=\", \"-p\", String(pid)], {\n stdio: \"pipe\",\n encoding: \"utf8\",\n });\n const raw = String(out.stdout ?? \"\").trim();\n if (!raw) return null;\n const match = raw.match(/^(\\d+)\\s+(.*)$/);\n if (!match) return null;\n return {\n ppid: Number(match[1]),\n command: match[2] ?? \"\",\n };\n } catch {\n return null;\n }\n}\n\nfunction isWatchCommand(command) {\n const raw = String(command ?? \"\").trim();\n if (!raw) return false;\n return raw.includes(\"node --watch\") || raw.includes(\" --watch \");\n}\n\nfunction stopWatchParentProcess() {\n let pid = Number(process.ppid);\n const seen = new Set();\n for (let depth = 0; depth < 10; depth += 1) {\n if (!Number.isInteger(pid) || pid <= 1) return false;\n if (seen.has(pid)) return false;\n seen.add(pid);\n\n const info = readProcessInfo(pid);\n if (!info) return false;\n if (isWatchCommand(info.command)) {\n try {\n process.kill(pid, \"SIGTERM\");\n return true;\n } catch {\n return false;\n }\n }\n pid = Number(info.ppid);\n }\n return false;\n}\n\nfunction resumeDedupeById(contexts) {\n const out = [];\n const seen = new Set();\n for (const item of contexts ?? []) {\n if (!item?.id || seen.has(item.id)) continue;\n seen.add(item.id);\n out.push(item);\n }\n return out;\n}\n\nfunction resumeFilterContexts(contexts) {\n return contexts.filter((ctx) => {\n const md = ctx?.metadata ?? {};\n const source = String(md.source ?? \"\").toLowerCase();\n if (cfg.resumeSourceFilter !== \"all\" && source && source !== cfg.resumeSourceFilter) return false;\n return true;\n });\n}\n\nfunction resumeSortContexts(contexts) {\n const ts = (ctx) => {\n const candidates = [ctx?.created_at, ctx?.updated_at, ctx?.metadata?.timestamp, ctx?.metadata?.created_at];\n for (const candidate of candidates) {\n const value = new Date(candidate ?? 0).getTime();\n if (!Number.isNaN(value) && value > 0) return value;\n }\n return 0;\n };\n\n return contexts.slice().sort((a, b) => {\n const diff = ts(b) - ts(a);\n if (diff !== 0) return diff;\n const aId = String(a?.id ?? \"\");\n const bId = String(b?.id ?? \"\");\n return bId.localeCompare(aId);\n });\n}\n\nfunction resumeFormatDate(value) {\n if (!value) return \"-\";\n const d = new Date(value);\n if (Number.isNaN(d.getTime())) return String(value);\n return d.toISOString().replace(\"T\", \" \").slice(0, 19);\n}\n\nfunction resumeContextSource(context) {\n const raw = String(context?.metadata?.source ?? \"\").trim().toLowerCase();\n if (raw === \"codex\") return \"codex\";\n if (raw === \"claude\") return \"claude\";\n return \"unknown\";\n}\n\nfunction isCodingContextSource(source) {\n return source === \"codex\" || source === \"claude\";\n}\n\nfunction resumeTargetAgent(source) {\n if (source === \"codex\") return \"claude\";\n if (source === \"claude\") return \"codex\";\n return \"codex\";\n}\n\nfunction resumeTargetOptionsForSource(source) {\n if (!isCodingContextSource(source)) return RESUME_TARGET_OPTIONS.slice();\n const recommended = resumeTargetAgent(source);\n const ordered = RESUME_TARGET_OPTIONS.slice().sort((a, b) => {\n if (a.id === recommended && b.id !== recommended) return -1;\n if (b.id === recommended && a.id !== recommended) return 1;\n return 0;\n });\n ordered.push(INSPECT_OPTION);\n return ordered;\n}\n\nfunction resumeAgentLabel(agent) {\n if (agent === \"claude\") return \"Claude Code\";\n if (agent === \"codex\") return \"Codex\";\n return \"Unknown\";\n}\n\nfunction resumeSummaryMarkdown({ context, messages }) {\n const counts = { user: 0, assistant: 0, system: 0 };\n for (const msg of messages) counts[resumeNormalizeRole(msg)] += 1;\n const recent = messages.slice(-Math.max(cfg.resumeSummaryTail, 4));\n const lines = [\n \"# UltraContext Resume\",\n \"\",\n `Generated at: ${new Date().toISOString()}`,\n `Context ID: ${context.id}`,\n `Created at: ${resumeFormatDate(context.created_at)}`,\n `Source: ${context.metadata?.source ?? \"-\"}`,\n `User: ${context.metadata?.user_id ?? \"-\"}`,\n `Session ID: ${context.metadata?.session_id ?? \"-\"}`,\n \"\",\n \"## Snapshot\",\n `- Messages: ${messages.length}`,\n `- Roles: user=${counts.user}, assistant=${counts.assistant}, system=${counts.system}`,\n \"\",\n `## Recent Timeline (last ${recent.length})`,\n ];\n\n for (const msg of recent) {\n const ts = resumeCompact(resumeMessageTimestamp(msg) || \"-\", 19).padEnd(19);\n const role = resumeNormalizeRole(msg).toUpperCase().padEnd(9);\n const eventType = resumeCompact(resumeMessageEventType(msg), 24).padEnd(24);\n const text = resumeMessageText(msg) || \"-\";\n lines.push(`- ${ts} ${role} ${eventType} ${text}`);\n }\n\n lines.push(\"\", \"## Resume Instructions\", \"1. Use the generated adapter command from the Contexts tab.\", \"2. Continue from the latest unresolved request.\", \"\");\n return lines.join(\"\\n\");\n}\n\nasync function loadResumeContexts({ silent = false } = {}) {\n if (!runtime.uc || ui.resume.loading) return;\n ui.resume.loading = true;\n if (!silent) {\n ui.resume.error = \"\";\n ui.resume.notice = \"Loading contexts from UltraContext...\";\n renderDashboard();\n }\n\n try {\n const listed = await runtime.uc.get({ limit: Math.max(cfg.resumeContextLimit, 1) });\n const filtered = resumeSortContexts(resumeFilterContexts(resumeDedupeById(listed.data)));\n const nextIds = new Set(filtered.map((ctx) => String(ctx?.id ?? \"\")).filter(Boolean));\n let newContextCount = 0;\n if (runtime.resumeBaselineReady) {\n for (const id of nextIds) {\n if (!runtime.resumeKnownContextIds.has(id)) newContextCount += 1;\n }\n }\n runtime.resumeKnownContextIds = nextIds;\n if (!runtime.resumeBaselineReady) runtime.resumeBaselineReady = true;\n\n if (newContextCount > 0) {\n playContextCreatedSound();\n }\n\n ui.resume.contexts = filtered;\n if (ui.resume.selectedIndex >= filtered.length) {\n ui.resume.selectedIndex = Math.max(filtered.length - 1, 0);\n }\n ui.resume.loadedAt = Date.now();\n\n const sourceCounts = { codex: 0, claude: 0, openclaw: 0, other: 0 };\n for (const ctx of filtered) {\n const source = String(ctx?.metadata?.source ?? \"\").toLowerCase();\n if (source === \"codex\") sourceCounts.codex += 1;\n else if (source === \"claude\") sourceCounts.claude += 1;\n else if (source === \"openclaw\") sourceCounts.openclaw += 1;\n else sourceCounts.other += 1;\n }\n\n if (!silent) {\n const filterLabel = cfg.resumeSourceFilter === \"all\" ? \"all sources\" : cfg.resumeSourceFilter;\n ui.resume.notice = `Loaded ${filtered.length} session contexts (${filterLabel}: codex=${sourceCounts.codex}, claude=${sourceCounts.claude}, openclaw=${sourceCounts.openclaw}, other=${sourceCounts.other})`;\n if (filtered.length === 0) {\n ui.resume.notice = `No contexts found for filter=${cfg.resumeSourceFilter}`;\n }\n }\n } catch (error) {\n if (!silent) {\n const details = errorDetails(error);\n ui.resume.error = details.message ?? \"Failed loading contexts\";\n ui.resume.notice = \"\";\n }\n } finally {\n ui.resume.loading = false;\n renderDashboard();\n }\n}\n\nfunction moveResumeSelection(delta) {\n const total = ui.resume.contexts.length;\n if (!total) return;\n const next = ui.resume.selectedIndex + delta;\n if (next < 0) {\n ui.resume.selectedIndex = total - 1;\n return;\n }\n if (next >= total) {\n ui.resume.selectedIndex = 0;\n return;\n }\n ui.resume.selectedIndex = next;\n}\n\nfunction recommendedResumeTargetForContext(context) {\n const sourceAgent = resumeContextSource(context);\n if (!isCodingContextSource(sourceAgent)) return \"\";\n return resumeTargetAgent(sourceAgent);\n}\n\nfunction openResumeTargetPicker() {\n if (ui.resume.syncing) return false;\n const context = ui.resume.contexts[ui.resume.selectedIndex];\n if (!context) {\n ui.resume.notice = \"No context selected\";\n renderDashboard();\n return false;\n }\n\n const sourceAgent = resumeContextSource(context);\n if (!isCodingContextSource(sourceAgent)) {\n ui.resume.notice = `Selected context source=${sourceAgent}. Adapt/Resume is available only for codex/claude contexts.`;\n renderDashboard();\n return false;\n }\n\n const recommendedTarget = recommendedResumeTargetForContext(context);\n ui.resumeTargetPicker.active = true;\n ui.resumeTargetPicker.selectedIndex = 0;\n ui.resumeTargetPicker.source = sourceAgent;\n ui.resumeTargetPicker.contextId = String(context.id ?? \"\");\n ui.resumeTargetPicker.options = resumeTargetOptionsForSource(sourceAgent);\n ui.resumeTargetPicker.recommendedTarget = recommendedTarget;\n renderDashboard();\n return true;\n}\n\nfunction closeResumeTargetPicker() {\n ui.resumeTargetPicker.active = false;\n ui.resumeTargetPicker.source = \"\";\n ui.resumeTargetPicker.contextId = \"\";\n ui.resumeTargetPicker.selectedIndex = 0;\n ui.resumeTargetPicker.options = RESUME_TARGET_OPTIONS;\n ui.resumeTargetPicker.recommendedTarget = \"\";\n renderDashboard();\n}\n\nfunction moveResumeTargetPickerSelection(delta) {\n const options = ui.resumeTargetPicker.options ?? RESUME_TARGET_OPTIONS;\n const total = options.length;\n if (total <= 0) return;\n const base = Number.isInteger(ui.resumeTargetPicker.selectedIndex) ? ui.resumeTargetPicker.selectedIndex : 0;\n ui.resumeTargetPicker.selectedIndex = (base + delta + total) % total;\n renderDashboard();\n}\n\nfunction resumeTargetPickerSelectionByIndex(index) {\n const options = ui.resumeTargetPicker.options ?? RESUME_TARGET_OPTIONS;\n const safeIndex = Math.max(Math.min(index, options.length - 1), 0);\n return options[safeIndex]?.id ?? \"codex\";\n}\n\nasync function buildCodexResumePlan({ sessionId, runCwd, messages }) {\n const originalSessionId = String(sessionId ?? \"\").trim();\n let canResumeBySessionId = originalSessionId ? await hasLocalCodexSession(originalSessionId) : false;\n let restoredPath = \"\";\n let restoredError = \"\";\n\n if (!canResumeBySessionId && originalSessionId) {\n const restored = await writeCodexSession({\n sessionId: originalSessionId,\n cwd: runCwd,\n messages,\n });\n canResumeBySessionId = await hasLocalCodexSession(originalSessionId);\n restoredPath = restored.filePath || \"\";\n restoredError = restored.error || \"\";\n }\n\n const command = canResumeBySessionId\n ? `codex -C ${resumeShellQuote(runCwd)} resume ${resumeShellQuote(originalSessionId)}`\n : `codex -C ${resumeShellQuote(runCwd)}`;\n\n return {\n targetAgent: \"codex\",\n sessionId: originalSessionId,\n command,\n canResumeBySessionId,\n restoredPath,\n restoredError,\n };\n}\n\nasync function buildClaudeResumePlan({ sessionId, runCwd, messages }) {\n const originalSessionId = String(sessionId ?? \"\").trim();\n let candidateSessionId = originalSessionId;\n let canResumeBySessionId = candidateSessionId ? await hasLocalClaudeSession(candidateSessionId, runCwd) : false;\n let restoredPath = \"\";\n let restoredError = \"\";\n\n if (!canResumeBySessionId || !candidateSessionId) {\n const restored = await writeClaudeSession({\n sessionId: candidateSessionId,\n cwd: runCwd,\n messages,\n });\n candidateSessionId = restored.sessionId || candidateSessionId;\n canResumeBySessionId = candidateSessionId ? await hasLocalClaudeSession(candidateSessionId, runCwd) : false;\n restoredPath = restored.filePath || \"\";\n restoredError = restored.error || \"\";\n }\n\n const command = canResumeBySessionId\n ? `cd ${resumeShellQuote(runCwd)} && claude --resume ${resumeShellQuote(candidateSessionId)}`\n : `cd ${resumeShellQuote(runCwd)} && claude`;\n\n return {\n targetAgent: \"claude\",\n sessionId: candidateSessionId,\n command,\n canResumeBySessionId,\n restoredPath,\n restoredError,\n };\n}\n\nasync function resumeSelectedContext({ targetAgentOverride = \"\" } = {}) {\n if (!runtime.uc || ui.resume.syncing) return;\n const context = ui.resume.contexts[ui.resume.selectedIndex];\n if (!context) {\n ui.resume.notice = \"No context selected\";\n renderDashboard();\n return;\n }\n\n const selectedSourceAgent = resumeContextSource(context);\n if (!isCodingContextSource(selectedSourceAgent)) {\n ui.resume.notice = `Selected context source=${selectedSourceAgent}. Adapt/Resume is available only for codex/claude contexts.`;\n renderDashboard();\n return;\n }\n\n ui.resume.syncing = true;\n ui.resumeTargetPicker.active = false;\n ui.resume.error = \"\";\n ui.resume.notice = `Pulling ${context.id}...`;\n renderDashboard();\n\n try {\n const detail = await runtime.uc.get(context.id);\n const messages = Array.isArray(detail.data) ? detail.data : [];\n\n const outDir = path.resolve(cfg.resumeOutputDir);\n await fs.mkdir(outDir, { recursive: true });\n\n const summaryPath = path.join(outDir, `${context.id}.md`);\n const snapshotPath = path.join(outDir, `${context.id}.json`);\n const commandPath = path.join(outDir, `${context.id}.command.txt`);\n\n const summary = resumeSummaryMarkdown({ context, messages });\n const snapshot = {\n exported_at: new Date().toISOString(),\n context_id: context.id,\n metadata: context.metadata ?? {},\n messages,\n };\n\n await fs.writeFile(summaryPath, summary, \"utf8\");\n await fs.writeFile(snapshotPath, JSON.stringify(snapshot, null, 2), \"utf8\");\n\n const originalCwd = resumeExtractSessionCwd(messages);\n const runCwd = await resumeResolveWorkingDirectory(originalCwd);\n const sourceAgent = selectedSourceAgent;\n const manualTarget = targetAgentOverride === \"claude\" || targetAgentOverride === \"codex\" ? targetAgentOverride : \"\";\n\n let targetAgent = manualTarget || resumeTargetAgent(sourceAgent);\n if (targetAgent === sourceAgent) {\n targetAgent = resumeTargetAgent(sourceAgent);\n }\n\n const sessionId = String(context.metadata?.session_id ?? \"\");\n const resumePlan =\n targetAgent === \"claude\"\n ? await buildClaudeResumePlan({ sessionId, runCwd, messages })\n : await buildCodexResumePlan({ sessionId, runCwd, messages });\n\n const command = resumePlan.command;\n await fs.writeFile(commandPath, `${command}\\n`, \"utf8\");\n\n ui.resume.summaryPath = summaryPath;\n ui.resume.command = command;\n ui.resume.commandPath = commandPath;\n\n const direction = `${resumeAgentLabel(sourceAgent)} -> ${resumeAgentLabel(targetAgent)}`;\n\n if (cfg.resumeOpenTab) {\n const opened = resumeOpenTerminalTab(command);\n const openMethod = opened.method ? ` method=${opened.method}` : \"\";\n if (opened.ok) {\n ui.resume.notice = resumePlan.canResumeBySessionId\n ? `Adapter ready (${direction}). Opened ${resumeAgentLabel(targetAgent)} via session_id ${resumePlan.sessionId}.${openMethod}`\n : `Adapter ready (${direction}). Opened ${resumeAgentLabel(targetAgent)} without session resume.${openMethod}`;\n if (resumePlan.restoredError) {\n ui.resume.notice = `${ui.resume.notice} Adapter warning: ${resumePlan.restoredError}`;\n }\n } else {\n ui.resume.notice = `Adapter ready (${direction}). Open tab failed: ${opened.reason}${openMethod}`;\n }\n } else {\n ui.resume.notice = resumePlan.canResumeBySessionId\n ? `Adapter ready (${direction}). Use generated ${resumeAgentLabel(targetAgent)} resume command.`\n : `Adapter ready (${direction}). Use generated command to start a clean ${resumeAgentLabel(targetAgent)} session.`;\n if (resumePlan.restoredPath) {\n ui.resume.notice = `${ui.resume.notice} Local adapter: ${resumePlan.restoredPath}`;\n } else if (resumePlan.restoredError) {\n ui.resume.notice = `${ui.resume.notice} Adapter warning: ${resumePlan.restoredError}`;\n }\n }\n } catch (error) {\n const details = errorDetails(error);\n ui.resume.error = details.message ?? \"Resume failed\";\n ui.resume.notice = \"\";\n } finally {\n ui.resume.syncing = false;\n ui.resumeTargetPicker.active = false;\n ui.resumeTargetPicker.source = \"\";\n ui.resumeTargetPicker.contextId = \"\";\n ui.resumeTargetPicker.selectedIndex = 0;\n ui.resumeTargetPicker.options = RESUME_TARGET_OPTIONS;\n ui.resumeTargetPicker.recommendedTarget = \"\";\n renderDashboard();\n }\n}\n\nfunction bootstrapModeConfigLabel(mode) {\n return CONFIG_BOOTSTRAP_MODES.find((entry) => entry.id === mode)?.label ?? mode;\n}\n\nfunction resumeTerminalConfigLabel(mode) {\n const normalized = normalizeResumeTerminal(mode);\n return CONFIG_RESUME_TERMINALS.find((entry) => entry.id === normalized)?.label ?? \"Terminal\";\n}\n\nfunction serializeConfigPrefs() {\n return {\n soundEnabled: Boolean(cfg.soundEnabled),\n startupSoundEnabled: Boolean(cfg.startupSoundEnabled),\n contextSoundEnabled: Boolean(cfg.contextSoundEnabled),\n bootstrapMode: normalizeBootstrapModeWithPrompt(cfg.bootstrapMode) || \"prompt\",\n resumeTerminal: normalizeResumeTerminal(cfg.resumeTerminal),\n claudeIncludeSubagents: Boolean(cfg.claudeIncludeSubagents),\n resumeOpenTab: Boolean(cfg.resumeOpenTab),\n startupGreetingFile: String(cfg.startupGreetingFile ?? \"\"),\n contextCreatedSoundFile: String(cfg.contextCreatedSoundFile ?? \"\"),\n };\n}\n\nasync function persistConfigPrefsToFile(targetFile = cfg.configFile) {\n const target = path.resolve(targetFile);\n await fs.mkdir(path.dirname(target), { recursive: true });\n\n // read-modify-write to preserve non-TUI keys (apiKey, _bootstrapState, etc.)\n let existing = {};\n try { existing = JSON.parse(await fs.readFile(target, \"utf8\")); } catch { /* empty */ }\n const merged = { ...existing, ...serializeConfigPrefs() };\n\n const tmp = target + \".tmp.prefs\";\n await fs.writeFile(tmp, JSON.stringify(merged, null, 2) + \"\\n\", \"utf8\");\n await fs.rename(tmp, target);\n return { saved: true, file: target };\n}\n\nasync function loadConfigPrefsFromPath(target) {\n let raw = \"\";\n try {\n raw = await fs.readFile(target, \"utf8\");\n } catch (error) {\n if (error?.code === \"ENOENT\") return { loaded: false, missing: true };\n return { loaded: false, missing: false, error };\n }\n\n let parsed = null;\n try {\n parsed = JSON.parse(raw);\n } catch (error) {\n return { loaded: false, missing: false, error };\n }\n\n applyConfigPrefs(parsed);\n return { loaded: true, missing: false };\n}\n\nasync function loadConfigPrefsFromFile() {\n const primary = path.resolve(cfg.configFile);\n const loaded = await loadConfigPrefsFromPath(primary);\n return {\n loaded: loaded.loaded,\n source: loaded.loaded ? \"primary\" : \"none\",\n file: loaded.loaded ? primary : \"\",\n };\n}\n\nfunction applyConfigPrefs(prefs) {\n if (!prefs || typeof prefs !== \"object\") return;\n for (const field of PERSISTED_CONFIG_FIELDS) {\n if (!(field in prefs)) continue;\n if (field === \"bootstrapMode\") {\n cfg.bootstrapMode = normalizeBootstrapModeWithPrompt(prefs.bootstrapMode) || \"prompt\";\n continue;\n }\n if (field === \"resumeTerminal\") {\n cfg.resumeTerminal = normalizeResumeTerminal(prefs.resumeTerminal);\n continue;\n }\n if (field === \"startupGreetingFile\") {\n cfg.startupGreetingFile = expandHome(String(prefs.startupGreetingFile ?? cfg.startupGreetingFile));\n continue;\n }\n if (field === \"contextCreatedSoundFile\") {\n cfg.contextCreatedSoundFile = expandHome(String(prefs.contextCreatedSoundFile ?? cfg.contextCreatedSoundFile));\n continue;\n }\n cfg[field] = Boolean(prefs[field]);\n }\n}\n\nasync function persistConfigPrefs() {\n let fileSaved = false;\n\n try {\n await persistConfigPrefsToFile();\n fileSaved = true;\n } catch {\n // ignore\n }\n\n return { fileSaved };\n}\n\nasync function resolveSoundFile(filePath, label) {\n if (!filePath) return \"\";\n try {\n const stat = await fs.stat(filePath);\n if (!stat.isFile()) {\n ui.resume.notice = `Configured sound is not a file: ${label}`;\n return \"\";\n }\n return filePath;\n } catch {\n ui.resume.notice = `Configured sound file not found: ${label}`;\n return \"\";\n }\n}\n\nasync function prepareSoundConfig() {\n sound.startupFile = \"\";\n sound.contextFile = \"\";\n sound.warnedNonDarwin = false;\n if (!cfg.soundEnabled) return;\n\n sound.startupFile = await resolveSoundFile(cfg.startupGreetingFile, \"startup\");\n sound.contextFile = await resolveSoundFile(cfg.contextCreatedSoundFile, \"context_created\");\n}\n\nfunction playSoundFile(filePath) {\n if (!cfg.soundEnabled || !filePath) return;\n\n if (process.platform !== \"darwin\") {\n if (!sound.warnedNonDarwin) {\n sound.warnedNonDarwin = true;\n ui.resume.notice = \"Sound notifications currently support only macOS (afplay).\";\n renderDashboard();\n }\n return;\n }\n\n try {\n const child = spawn(\"afplay\", [filePath], {\n detached: true,\n stdio: \"ignore\",\n });\n child.unref();\n } catch {\n // ignore playback errors\n }\n}\n\nfunction playStartupGreetingSound() {\n if (!cfg.startupSoundEnabled) return;\n playSoundFile(sound.startupFile);\n}\n\nfunction playContextCreatedSound() {\n if (!cfg.contextSoundEnabled) return;\n playSoundFile(sound.contextFile);\n}\n\nfunction configToggleItems() {\n const masterEnabled = Boolean(cfg.soundEnabled);\n const soundItems = CONFIG_TOGGLES.map((item) => {\n const rawValue = Boolean(cfg[item.key]);\n const isSoundToggle = item.key !== \"soundEnabled\";\n const blockedByMaster = isSoundToggle && !masterEnabled;\n const effectiveValue = blockedByMaster ? false : rawValue;\n return {\n ...item,\n kind: \"boolean\",\n rawValue,\n value: effectiveValue,\n valueLabel: effectiveValue ? \"ON\" : \"OFF\",\n blockedByMaster,\n };\n });\n\n const normalizedBootstrapMode = normalizeBootstrapModeWithPrompt(cfg.bootstrapMode) || \"prompt\";\n const syncItems = [\n {\n key: \"bootstrapMode\",\n kind: \"enum\",\n label: \"Sync profile\",\n description: \"Defines bootstrap strategy for next daemon startup/reset.\",\n value: normalizedBootstrapMode,\n valueLabel: bootstrapModeConfigLabel(normalizedBootstrapMode),\n blockedByMaster: false,\n },\n {\n key: \"resumeTerminal\",\n kind: \"enum\",\n label: \"Resume terminal\",\n description: \"Choose where resume opens (Terminal or Warp).\",\n value: normalizeResumeTerminal(cfg.resumeTerminal),\n valueLabel: resumeTerminalConfigLabel(cfg.resumeTerminal),\n blockedByMaster: false,\n },\n {\n key: \"bootstrapResetState\",\n kind: \"action\",\n label: \"Reset bootstrap state\",\n description: \"Clears daemon bootstrap state so re-bootstrap can run again.\",\n value: \"run\",\n valueLabel: \"RUN\",\n blockedByMaster: false,\n },\n ];\n\n return [...soundItems, ...syncItems];\n}\n\nfunction moveConfigSelection(delta) {\n const items = configToggleItems();\n const total = items.length;\n if (!total) return;\n const next = ui.configEditor.selectedIndex + delta;\n if (next < 0) {\n ui.configEditor.selectedIndex = total - 1;\n return;\n }\n if (next >= total) {\n ui.configEditor.selectedIndex = 0;\n return;\n }\n ui.configEditor.selectedIndex = next;\n}\n\nasync function toggleSelectedConfig() {\n const items = configToggleItems();\n if (items.length === 0) return;\n\n const selected = Math.max(Math.min(ui.configEditor.selectedIndex, items.length - 1), 0);\n const item = items[selected];\n\n try {\n // bootstrap reset — persist prefs first, then add flag on top so it isn't clobbered\n if (item.kind === \"action\" && item.key === \"bootstrapResetState\") {\n await persistConfigPrefs();\n const ok = writeConfigKey(\"bootstrapReset\", true);\n ui.resume.notice = ok\n ? \"Bootstrap reset requested. Daemon will apply next cycle.\"\n : \"Failed to write config.\";\n renderDashboard();\n return;\n }\n\n // bootstrap mode cycle — spawn CLI config set\n if (item.kind === \"enum\" && item.key === \"bootstrapMode\") {\n const currentIndex = Math.max(CONFIG_BOOTSTRAP_MODES.findIndex((entry) => entry.id === item.value), 0);\n const next = CONFIG_BOOTSTRAP_MODES[(currentIndex + 1) % CONFIG_BOOTSTRAP_MODES.length];\n cfg.bootstrapMode = next.id;\n cfg.bootstrapReset = next.id === \"prompt\";\n\n const saved = await persistConfigPrefs();\n ui.resume.notice = `Sync profile set: ${next.label}${saved.fileSaved ? \" (saved)\" : \"\"}.`;\n renderDashboard();\n return;\n }\n\n // resume terminal cycle — local only\n if (item.kind === \"enum\" && item.key === \"resumeTerminal\") {\n const current = normalizeResumeTerminal(item.value);\n const currentIndex = Math.max(CONFIG_RESUME_TERMINALS.findIndex((entry) => entry.id === current), 0);\n const next = CONFIG_RESUME_TERMINALS[(currentIndex + 1) % CONFIG_RESUME_TERMINALS.length];\n cfg.resumeTerminal = next.id;\n const saved = await persistConfigPrefs();\n ui.resume.notice = `Resume terminal: ${next.label}${saved.fileSaved ? \" (saved)\" : \"\"}.`;\n renderDashboard();\n return;\n }\n\n // boolean toggles\n if (item.kind === \"boolean\") {\n cfg[item.key] = !cfg[item.key];\n\n // sound toggles — local only\n if (\n item.key === \"soundEnabled\" ||\n item.key === \"startupSoundEnabled\" ||\n item.key === \"contextSoundEnabled\"\n ) {\n await prepareSoundConfig();\n const saved = await persistConfigPrefs();\n ui.resume.notice = `${item.label}: ${cfg[item.key] ? \"ON\" : \"OFF\"}${saved.fileSaved ? \" (file saved)\" : \"\"}.`;\n renderDashboard();\n return;\n }\n }\n } catch (error) {\n const details = errorDetails(error);\n ui.resume.notice = `Failed to apply config: ${details.message}`;\n renderDashboard();\n }\n}\n\n// ── update prompt actions ────────────────────────────────────────\n\nfunction moveUpdatePrompt(delta) {\n const total = UPDATE_PROMPT_OPTIONS.length;\n ui.updatePrompt.selectedIndex = (ui.updatePrompt.selectedIndex + delta + total) % total;\n renderDashboard();\n}\n\nfunction chooseUpdatePrompt(index) {\n const safeIndex = Math.max(Math.min(index, UPDATE_PROMPT_OPTIONS.length - 1), 0);\n const choice = UPDATE_PROMPT_OPTIONS[safeIndex]?.id;\n\n // dismiss prompt\n ui.updatePrompt.active = false;\n renderDashboard();\n\n if (choice === \"install\") {\n // stop TUI and run update in a new terminal tab\n const command = \"ultracontext update\";\n const opened = resumeOpenTerminalTab(command);\n if (opened.ok) {\n ui.resume.notice = `Update started in new tab. Restart TUI after update.`;\n } else {\n ui.resume.notice = `Run manually: ultracontext update`;\n }\n renderDashboard();\n }\n}\n\n// ── detail view actions ─────────────────────────────────────────\n\nasync function openContextDetail() {\n if (ui.detailView.loading) return;\n const context = ui.resume.contexts[ui.resume.selectedIndex];\n if (!context) return;\n\n ui.detailView.active = true;\n ui.detailView.contextId = context.id;\n ui.detailView.contextMeta = context.metadata ?? {};\n ui.detailView.messages = [];\n ui.detailView.scrollOffset = 0;\n ui.detailView.lineOffset = 0;\n ui.detailView.loading = true;\n ui.detailView.error = null;\n renderDashboard();\n\n try {\n const detail = await runtime.uc.get(context.id);\n const messages = Array.isArray(detail.data) ? detail.data : [];\n ui.detailView.messages = messages;\n } catch (error) {\n ui.detailView.error = error?.message ?? \"Failed to load context\";\n } finally {\n ui.detailView.loading = false;\n renderDashboard();\n }\n}\n\nfunction closeContextDetail() {\n ui.detailView.active = false;\n ui.detailView.contextId = null;\n ui.detailView.contextMeta = null;\n ui.detailView.messages = [];\n ui.detailView.scrollOffset = 0;\n ui.detailView.lineOffset = 0;\n ui.detailView.loading = false;\n ui.detailView.error = null;\n renderDashboard();\n}\n\nasync function refreshContextDetail() {\n if (!ui.detailView.active || !ui.detailView.contextId || ui.detailView.loading) return;\n ui.detailView.loading = true;\n ui.detailView.error = null;\n renderDashboard();\n\n try {\n const detail = await runtime.uc.get(ui.detailView.contextId);\n ui.detailView.messages = Array.isArray(detail.data) ? detail.data : [];\n } catch (error) {\n ui.detailView.error = error?.message ?? \"Failed to refresh\";\n } finally {\n ui.detailView.loading = false;\n renderDashboard();\n }\n}\n\n// message-level scroll — resets line offset\nfunction scrollContextDetail(delta) {\n const total = ui.detailView.messages.length;\n if (total === 0) return;\n const next = ui.detailView.scrollOffset + delta;\n if (next < 0) ui.detailView.scrollOffset = total - 1;\n else if (next >= total) ui.detailView.scrollOffset = 0;\n else ui.detailView.scrollOffset = next;\n ui.detailView.lineOffset = 0;\n renderDashboard();\n}\n\n// line-level fine scroll (j/k) within current view\nfunction scrollContextDetailLine(delta) {\n if (ui.detailView.messages.length === 0) return;\n ui.detailView.lineOffset = Math.max(0, ui.detailView.lineOffset + delta);\n renderDashboard();\n}\n\n// ── enter context (picker or detail based on source) ────────────\n\nfunction enterContext() {\n const context = ui.resume.contexts[ui.resume.selectedIndex];\n if (!context) {\n ui.resume.notice = \"No context selected\";\n renderDashboard();\n return;\n }\n\n const source = resumeContextSource(context);\n if (isCodingContextSource(source)) {\n openResumeTargetPicker();\n } else {\n void openContextDetail();\n }\n}\n\nfunction setSelectedTabByIndex(nextIndex) {\n const normalized = (nextIndex + MENU_TABS.length) % MENU_TABS.length;\n ui.selectedTab = MENU_TABS[normalized].id;\n}\n\nfunction ensureResumeTabDataLoaded() {\n if (ui.selectedTab !== \"contexts\") return;\n if (ui.resume.contexts.length === 0 && !ui.resume.loading) {\n void loadResumeContexts();\n }\n}\n\nfunction selectTabAndRefreshByIndex(index) {\n setSelectedTabByIndex(index);\n ensureResumeTabDataLoaded();\n renderDashboard();\n}\n\nfunction moveTabAndRefresh(delta) {\n const idx = MENU_TABS.findIndex((tab) => tab.id === ui.selectedTab);\n const current = idx === -1 ? 0 : idx;\n setSelectedTabByIndex(current + delta);\n ensureResumeTabDataLoaded();\n renderDashboard();\n}\n\nfunction buildUiSnapshot() {\n const configItems = configToggleItems();\n const selectedConfigIndex = Math.max(\n Math.min(ui.configEditor.selectedIndex, Math.max(configItems.length - 1, 0)),\n 0\n );\n\n return {\n now: Date.now(),\n currentVersion: ui.currentVersion,\n updateAvailable: ui.updateAvailable,\n updatePrompt: {\n active: ui.updatePrompt.active,\n selectedIndex: ui.updatePrompt.selectedIndex,\n latestVersion: ui.updatePrompt.latestVersion,\n options: UPDATE_PROMPT_OPTIONS,\n },\n cfg: {\n userId: cfg.userId,\n host: cfg.host,\n pollMs: 0,\n uiRefreshMs: cfg.uiRefreshMs,\n logLevel: \"info\",\n soundEnabled: cfg.soundEnabled,\n startupSoundEnabled: cfg.startupSoundEnabled,\n contextSoundEnabled: cfg.contextSoundEnabled,\n startupGreetingFile: cfg.startupGreetingFile,\n contextCreatedSoundFile: cfg.contextCreatedSoundFile,\n },\n stats,\n selectedTab: ui.selectedTab,\n configEditor: {\n selectedIndex: selectedConfigIndex,\n items: configItems,\n },\n recentLogs: ui.recentLogs.slice(-runtimeLogsKeep()),\n sourceStats: ui.sourceStats,\n resume: {\n ...ui.resume,\n contexts: ui.resume.contexts,\n },\n detailView: {\n active: ui.detailView.active,\n contextId: ui.detailView.contextId,\n contextMeta: ui.detailView.contextMeta,\n messages: ui.detailView.messages,\n scrollOffset: ui.detailView.scrollOffset,\n lineOffset: ui.detailView.lineOffset,\n loading: ui.detailView.loading,\n error: ui.detailView.error,\n },\n resumeTargetPicker: {\n active: ui.resumeTargetPicker.active,\n selectedIndex: ui.resumeTargetPicker.selectedIndex,\n source: ui.resumeTargetPicker.source,\n contextId: ui.resumeTargetPicker.contextId,\n options: ui.resumeTargetPicker.options,\n recommendedTarget: ui.resumeTargetPicker.recommendedTarget,\n },\n onlineClients: ui.onlineClients,\n bootstrap: {\n active: ui.bootstrap.active,\n selectedIndex: ui.bootstrap.selectedIndex,\n options: ui.bootstrap.options,\n sourceNames: ui.bootstrap.sourceNames,\n note: ui.bootstrap.note,\n },\n };\n}\n\nfunction validateConfig() {\n if (!cfg.apiKey) {\n throw new Error(\"Missing ULTRACONTEXT_API_KEY\");\n }\n}\n\n// ── main entry ──────────────────────────────────────────────────\n\nasync function tuiMain() {\n validateConfig();\n\n if (!process.stdout.isTTY) {\n throw new Error(\"TUI mode requires a TTY.\");\n }\n\n try {\n const fileLoad = await loadConfigPrefsFromFile();\n if (!fileLoad.loaded) {\n await persistConfigPrefsToFile();\n }\n } catch {\n // ignore config persistence startup issues\n }\n\n await prepareSoundConfig();\n playStartupGreetingSound();\n\n const uc = new UltraContext({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl });\n runtime.uc = uc;\n\n await uc.get({ limit: 1 });\n\n let running = true;\n let stopRequested = false;\n const stop = (reason = \"internal\") => {\n if (stopRequested) return;\n stopRequested = true;\n if (reason === \"user\" || reason === \"sigint\") {\n stopWatchParentProcess();\n }\n running = false;\n };\n runtime.stop = stop;\n\n runtime.uiController = createInkUiController({\n getSnapshot: buildUiSnapshot,\n actions: {\n stop: () => runtime.stop?.(\"user\"),\n moveBootstrap: () => {},\n chooseBootstrap: () => {},\n moveUpdatePrompt: (delta) => {\n moveUpdatePrompt(delta);\n },\n chooseUpdatePrompt: (index) => {\n chooseUpdatePrompt(index);\n },\n moveTab: moveTabAndRefresh,\n selectTab: selectTabAndRefreshByIndex,\n moveConfig: (delta) => {\n moveConfigSelection(delta);\n renderDashboard();\n },\n toggleConfig: () => {\n void toggleSelectedConfig();\n },\n moveResume: (delta) => {\n moveResumeSelection(delta);\n renderDashboard();\n },\n refreshResume: () => {\n void loadResumeContexts();\n },\n promptResumeTarget: () => {\n openResumeTargetPicker();\n },\n moveResumeTarget: (delta) => {\n moveResumeTargetPickerSelection(delta);\n },\n chooseResumeTarget: (index) => {\n const target = resumeTargetPickerSelectionByIndex(index);\n if (target === \"inspect\") {\n closeResumeTargetPicker();\n void openContextDetail();\n return;\n }\n void resumeSelectedContext({ targetAgentOverride: target });\n },\n cancelResumeTarget: () => {\n closeResumeTargetPicker();\n },\n enterContext: () => {\n enterContext();\n },\n openDetail: () => {\n void openContextDetail();\n },\n closeDetail: () => {\n closeContextDetail();\n },\n scrollDetail: (delta) => {\n scrollContextDetail(delta);\n },\n scrollDetailLine: (delta) => {\n scrollContextDetailLine(delta);\n },\n refreshDetail: () => {\n void refreshContextDetail();\n },\n },\n });\n\n runtime.uiController.start();\n renderDashboard();\n void loadResumeContexts();\n void checkForUpdateSilent();\n\n // initial status poll\n await pollDaemonStatus();\n\n // status.json polling + render loop\n runtime.statusPollTimer = setInterval(async () => {\n await pollDaemonStatus();\n renderDashboard();\n }, cfg.uiRefreshMs);\n runtime.statusPollTimer.unref?.();\n\n // context auto-refresh\n if (cfg.resumeAutoRefreshMs > 0) {\n runtime.contextRefreshTimer = setInterval(() => {\n if (ui.resume.loading || ui.resume.syncing) return;\n void loadResumeContexts({ silent: ui.selectedTab !== \"contexts\" });\n }, Math.max(cfg.resumeAutoRefreshMs, 1000));\n runtime.contextRefreshTimer.unref?.();\n }\n\n process.on(\"SIGINT\", () => stop(\"sigint\"));\n process.on(\"SIGTERM\", () => stop(\"sigterm\"));\n\n while (running) {\n await new Promise((resolve) => setTimeout(resolve, 120));\n }\n\n // cleanup\n if (runtime.statusPollTimer) clearInterval(runtime.statusPollTimer);\n runtime.statusPollTimer = null;\n if (runtime.contextRefreshTimer) clearInterval(runtime.contextRefreshTimer);\n runtime.contextRefreshTimer = null;\n\n runtime.uiController?.stop();\n runtime.uiController = null;\n\n runtime.stop = null;\n runtime.uc = null;\n}\n\ntuiMain().catch(async (error) => {\n if (runtime.statusPollTimer) clearInterval(runtime.statusPollTimer);\n runtime.statusPollTimer = null;\n if (runtime.contextRefreshTimer) clearInterval(runtime.contextRefreshTimer);\n runtime.contextRefreshTimer = null;\n\n runtime.uiController?.stop();\n runtime.uiController = null;\n\n runtime.stop = null;\n runtime.uc = null;\n\n if (onFatalError) {\n onFatalError(error);\n return;\n }\n\n const message = error instanceof Error ? error.message : String(error);\n console.error(`[error] UltraContext TUI failed: ${message}`);\n process.exit(1);\n});\n\n} // end tuiBoot\n"],"mappings":"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"}
|