ultracontext 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +0,0 @@
1
- {"version":3,"file":"launcher-VTbHuuaQ.mjs","names":["fs","fsSync"],"sources":["../../daemon/src/launcher.mjs"],"sourcesContent":["// daemon launcher — spawns daemon in background, exported as launchDaemon()\nimport fs from \"node:fs/promises\";\nimport fsSync from \"node:fs\";\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport { spawn } from \"node:child_process\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { resolveDaemonWsInfoFile } from \"@ultracontext/protocol\";\n\nimport { resolveLockPath } from \"./lock.mjs\";\nimport { expandHome } from \"./utils.mjs\";\n\nconst DEFAULT_LOG_FILE = \"~/.ultracontext/daemon.log\";\n\n// ── ANSI helpers ────────────────────────────────────────────────\n\nconst isTTY = process.stdout.isTTY;\nconst esc = (code) => (isTTY ? `\\x1b[${code}m` : \"\");\nconst reset = esc(0);\nconst bold = esc(1);\nconst dim = esc(2);\nconst blue = esc(\"38;2;47;111;179\");\nconst cyan = esc(\"38;2;126;195;255\");\nconst green = esc(\"38;2;80;200;120\");\nconst red = esc(\"38;2;220;80;80\");\nconst gray = esc(\"38;5;245\");\n\n// ── process helpers ─────────────────────────────────────────────\n\nfunction isPidAlive(pid) {\n if (!Number.isInteger(pid) || pid <= 1) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n if (error?.code === \"EPERM\") return true;\n if (error?.code === \"ESRCH\") return false;\n return false;\n }\n}\n\nasync function readJsonFile(filePath) {\n try {\n const raw = await fs.readFile(filePath, \"utf8\");\n const parsed = JSON.parse(raw);\n return parsed && typeof parsed === \"object\" ? parsed : null;\n } catch {\n return null;\n }\n}\n\nasync function readLogTail(logPath, lines = 12) {\n try {\n const raw = await fs.readFile(logPath, \"utf8\");\n const allLines = raw.split(\"\\n\").map((l) => l.trimEnd()).filter(Boolean);\n return allLines.length === 0 ? [] : allLines.slice(-Math.max(lines, 1));\n } catch {\n return [];\n }\n}\n\nfunction resolveDaemonLogFile(env = process.env) {\n return expandHome(env.ULTRACONTEXT_DAEMON_LOG_FILE ?? DEFAULT_LOG_FILE);\n}\n\nasync function resolveRunningProcess(lockPath) {\n const lock = await readJsonFile(lockPath);\n const lockPid = Number.parseInt(String(lock?.pid ?? \"\"), 10);\n if (isPidAlive(lockPid)) {\n return { pid: lockPid, startedAt: String(lock?.startedAt ?? \"\"), engineerId: String(lock?.engineerId ?? \"\"), host: String(lock?.host ?? \"\") };\n }\n return null;\n}\n\nasync function resolveWritableLogPath(preferredPath) {\n const primary = path.resolve(preferredPath);\n try {\n await fs.mkdir(path.dirname(primary), { recursive: true });\n fsSync.accessSync(path.dirname(primary), fsSync.constants.W_OK);\n return primary;\n } catch {\n const fallback = path.resolve(process.cwd(), \".ultracontext-daemon.log\");\n await fs.mkdir(path.dirname(fallback), { recursive: true });\n return fallback;\n }\n}\n\n// ── exported entry point ────────────────────────────────────────\n\nexport async function launchDaemon({ entryPath, diagnosticsHint } = {}) {\n const resolvedEntry = entryPath ?? fileURLToPath(new URL(\"./index.mjs\", import.meta.url));\n const hint = diagnosticsHint ?? \"pnpm --filter @ultracontext/daemon run start:verbose\";\n\n const lockPath = path.resolve(resolveLockPath(process.env));\n const infoPath = path.resolve(resolveDaemonWsInfoFile(process.env));\n const preferredLogPath = resolveDaemonLogFile(process.env);\n\n console.log(\"\");\n console.log(` ${blue}${bold}UltraContext${reset} ${dim}Daemon${reset}`);\n console.log(\"\");\n\n // already running\n const running = await resolveRunningProcess(lockPath);\n if (running) {\n console.log(` ${cyan}●${reset} ${bold}Already running${reset} ${gray}PID ${running.pid}${reset}`);\n console.log(\"\");\n process.exit(2);\n return;\n }\n\n // spawn daemon\n const logPath = await resolveWritableLogPath(preferredLogPath);\n const outFd = fsSync.openSync(logPath, \"a\");\n const errFd = fsSync.openSync(logPath, \"a\");\n\n let child;\n try {\n child = spawn(process.execPath, [resolvedEntry, \"--daemon\"], {\n env: process.env,\n detached: true,\n stdio: [\"ignore\", outFd, errFd],\n });\n child.unref();\n } finally {\n try { fsSync.closeSync(outFd); } catch { /* ignore */ }\n try { fsSync.closeSync(errFd); } catch { /* ignore */ }\n }\n\n await new Promise((resolve) => setTimeout(resolve, 350));\n\n // failed\n if (!isPidAlive(child.pid)) {\n console.log(` ${red}✕${reset} ${bold}Failed to start${reset}`);\n const tail = await readLogTail(logPath);\n if (tail.length > 0) {\n console.log(\"\");\n for (const line of tail) console.error(` ${gray}${line}${reset}`);\n }\n console.log(\"\");\n console.log(` ${dim}Try: ${hint}${reset}`);\n console.log(\"\");\n process.exit(1);\n return;\n }\n\n // success\n console.log(` ${green}✓${reset} ${bold}Started${reset} ${gray}PID ${child.pid}${reset}`);\n console.log(` ${gray}${logPath}${reset}`);\n console.log(\"\");\n}\n\n// auto-exec when run directly\nconst isDirectRun = process.argv[1] && import.meta.url.endsWith(process.argv[1].replace(/.*\\//, \"\"));\nif (isDirectRun) {\n launchDaemon().catch((error) => {\n console.error(` ${red}✕${reset} ${error instanceof Error ? error.message : String(error)}`);\n console.error(\"\");\n process.exit(1);\n });\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"lock-H7LKrRSb.mjs","names":[],"sources":["../../daemon/src/utils.mjs","../../daemon/src/lock.mjs"],"sourcesContent":["import crypto from \"node:crypto\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nexport function sha256(value) {\n return crypto.createHash(\"sha256\").update(value).digest(\"hex\");\n}\n\nexport function expandHome(inputPath) {\n if (!inputPath || !inputPath.startsWith(\"~\")) return inputPath;\n if (inputPath === \"~\") return os.homedir();\n if (inputPath.startsWith(\"~/\")) return path.join(os.homedir(), inputPath.slice(2));\n return inputPath;\n}\n\nexport function toInt(value, fallback) {\n const parsed = Number.parseInt(String(value ?? \"\"), 10);\n return Number.isFinite(parsed) ? parsed : fallback;\n}\n\nexport function boolFromEnv(value, fallback = false) {\n if (value === undefined) return fallback;\n const normalized = String(value).trim().toLowerCase();\n if ([\"1\", \"true\", \"yes\", \"on\"].includes(normalized)) return true;\n if ([\"0\", \"false\", \"no\", \"off\"].includes(normalized)) return false;\n return fallback;\n}\n\nexport function truncateString(value, maxLen = 4000) {\n if (typeof value !== \"string\") return value;\n if (value.length <= maxLen) return value;\n return `${value.slice(0, maxLen)}... [truncated ${value.length - maxLen} chars]`;\n}\n\nexport function safeJsonParse(line) {\n try {\n return JSON.parse(line);\n } catch {\n return null;\n }\n}\n\nexport function extractSessionIdFromPath(filePath) {\n const uuidMatch = filePath.match(\n /([0-9a-f]{8}-[0-9a-f]{4,}-[0-9a-f]{4,}-[0-9a-f]{4,}-[0-9a-f]{8,})/i\n );\n if (uuidMatch) return uuidMatch[1];\n\n const fileName = path.basename(filePath, \".jsonl\");\n return fileName || \"unknown-session\";\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport process from \"node:process\";\n\nimport { expandHome } from \"./utils.mjs\";\n\nconst DEFAULT_LOCK_PATH = \"~/.ultracontext/daemon.lock\";\n\nfunction isPidAlive(pid) {\n if (!Number.isInteger(pid) || pid <= 1) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n if (error?.code === \"EPERM\") return true;\n if (error?.code === \"ESRCH\") return false;\n return false;\n }\n}\n\nasync function readExistingLock(lockPath) {\n try {\n const raw = await fs.readFile(lockPath, \"utf8\");\n const parsed = JSON.parse(raw);\n return parsed && typeof parsed === \"object\" ? parsed : null;\n } catch {\n return null;\n }\n}\n\nexport function resolveLockPath(env = process.env) {\n return expandHome(env.ULTRACONTEXT_LOCK_FILE ?? DEFAULT_LOCK_PATH);\n}\n\nexport async function acquireFileLock({\n lockPath = resolveLockPath(process.env),\n engineerId = \"\",\n host = \"\",\n} = {}) {\n const resolved = path.resolve(lockPath);\n await fs.mkdir(path.dirname(resolved), { recursive: true });\n\n let handle;\n try {\n handle = await fs.open(resolved, \"wx\");\n } catch (error) {\n if (error?.code !== \"EEXIST\") throw error;\n\n const existing = await readExistingLock(resolved);\n const existingPid = Number.parseInt(String(existing?.pid ?? \"\"), 10);\n if (!isPidAlive(existingPid)) {\n try {\n await fs.unlink(resolved);\n } catch {\n // ignore\n }\n handle = await fs.open(resolved, \"wx\");\n } else {\n const reason = existingPid\n ? `UltraContext daemon already running (PID: ${existingPid})`\n : \"UltraContext daemon already running\";\n const lockError = new Error(reason);\n lockError.code = \"ELOCKED\";\n lockError.pid = existingPid;\n throw lockError;\n }\n }\n\n const payload = {\n pid: process.pid,\n host: String(host ?? \"\"),\n engineerId: String(engineerId ?? \"\"),\n startedAt: new Date().toISOString(),\n };\n await handle.writeFile(`${JSON.stringify(payload, null, 2)}\\n`, \"utf8\");\n\n let released = false;\n const release = async () => {\n if (released) return;\n released = true;\n try {\n await handle.close();\n } catch {\n // ignore\n }\n try {\n await fs.unlink(resolved);\n } catch {\n // ignore\n }\n };\n\n return {\n lockPath: resolved,\n payload,\n release,\n };\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"src-NyDFgJXL.mjs","names":[],"sources":["../../../packages/protocol/src/index.mjs"],"sourcesContent":["import os from \"node:os\";\nimport path from \"node:path\";\n\nconst VERSION = \"v1\";\nconst DEFAULT_DAEMON_WS_HOST = \"127.0.0.1\";\nconst DEFAULT_DAEMON_WS_PORT = 0;\nconst DEFAULT_DAEMON_INFO_FILE = \"~/.ultracontext/daemon.info\";\n\nexport const DAEMON_WS_MESSAGE_TYPES = Object.freeze({\n SNAPSHOT: \"snapshot\",\n STATE: \"state\",\n LOG: \"log\",\n CONTEXT_EVENT: \"context:event\",\n CONFIG_STATE: \"config:state\",\n REQUEST_ACK: \"ack\",\n PING: \"ping\",\n PONG: \"pong\",\n CONFIG_GET: \"config:get\",\n CONFIG_SET: \"config:set\",\n BOOTSTRAP_RESET: \"bootstrap:reset\",\n});\n\nfunction norm(value, fallback = \"unknown\") {\n const trimmed = String(value ?? \"\").trim();\n return trimmed || fallback;\n}\n\nfunction expandHome(inputPath) {\n const raw = String(inputPath ?? \"\");\n if (!raw || !raw.startsWith(\"~\")) return raw;\n if (raw === \"~\") return os.homedir();\n if (raw.startsWith(\"~/\")) return path.join(os.homedir(), raw.slice(2));\n return raw;\n}\n\nexport function resolveDaemonWsHost(env = process.env) {\n const raw = String(env.ULTRACONTEXT_DAEMON_WS_HOST ?? env.ULTRACONTEXT_WS_HOST ?? \"\").trim();\n return raw || DEFAULT_DAEMON_WS_HOST;\n}\n\nexport function resolveDaemonWsPort(env = process.env) {\n const raw = Number.parseInt(String(env.ULTRACONTEXT_DAEMON_WS_PORT ?? env.ULTRACONTEXT_WS_PORT ?? \"\"), 10);\n if (Number.isInteger(raw) && raw >= 0 && raw <= 65535) return raw;\n return DEFAULT_DAEMON_WS_PORT;\n}\n\nexport function resolveDaemonWsInfoFile(env = process.env) {\n return expandHome(\n env.ULTRACONTEXT_DAEMON_INFO_FILE ??\n env.ULTRACONTEXT_DAEMON_WS_PORT_FILE ??\n env.ULTRACONTEXT_WS_INFO_FILE ??\n DEFAULT_DAEMON_INFO_FILE\n );\n}\n\nexport function resolveDaemonWsPortFile(env = process.env) {\n return resolveDaemonWsInfoFile(env);\n}\n\nexport function createBootstrapStateKey({ host, engineerId, sourceNames }) {\n const names = Array.isArray(sourceNames) ? sourceNames.map((name) => String(name ?? \"\").trim()).filter(Boolean) : [];\n const namesKey = names.sort().join(\",\");\n return `uc:daemon:bootstrap:${VERSION}:${norm(host)}:${norm(engineerId)}:${namesKey}`;\n}\n\nexport function normalizeBootstrapMode(raw, { allowPrompt = false } = {}) {\n const value = String(raw ?? \"\").trim().toLowerCase();\n if (allowPrompt && value === \"prompt\") return \"prompt\";\n if (value === \"new\" || value === \"new_only\" || value === \"latest\") return \"new_only\";\n if (value === \"24h\" || value === \"last_24h\" || value === \"last24h\") return \"last_24h\";\n if (value === \"all\" || value === \"full\") return \"all\";\n return \"\";\n}\n\nexport function parseProtocolJson(raw, fallback) {\n if (!raw) return fallback;\n try {\n return JSON.parse(raw);\n } catch {\n return fallback;\n }\n}\n\nexport function buildDaemonWsMessage(type, data = {}) {\n return { type: String(type ?? \"\"), data: data ?? {} };\n}\n\nexport function parseDaemonWsMessage(raw, fallback = null) {\n const parsed = typeof raw === \"string\" ? parseProtocolJson(raw, fallback) : raw;\n if (!parsed || typeof parsed !== \"object\") return fallback;\n const type = String(parsed.type ?? \"\").trim();\n if (!type) return fallback;\n return {\n ...parsed,\n type,\n data: parsed.data ?? {},\n };\n}\n"],"mappings":";;;;AAGA,MAAM,UAAU;AAChB,MAAM,yBAAyB;AAC/B,MAAM,yBAAyB;AAC/B,MAAM,2BAA2B;AAEjC,MAAa,0BAA0B,OAAO,OAAO;CACnD,UAAU;CACV,OAAO;CACP,KAAK;CACL,eAAe;CACf,cAAc;CACd,aAAa;CACb,MAAM;CACN,MAAM;CACN,YAAY;CACZ,YAAY;CACZ,iBAAiB;CAClB,CAAC;AAEF,SAAS,KAAK,OAAO,WAAW,WAAW;AAEzC,QADgB,OAAO,SAAS,GAAG,CAAC,MAAM,IACxB;;AAGpB,SAAS,WAAW,WAAW;CAC7B,MAAM,MAAM,OAAO,aAAa,GAAG;AACnC,KAAI,CAAC,OAAO,CAAC,IAAI,WAAW,IAAI,CAAE,QAAO;AACzC,KAAI,QAAQ,IAAK,QAAO,GAAG,SAAS;AACpC,KAAI,IAAI,WAAW,KAAK,CAAE,QAAO,KAAK,KAAK,GAAG,SAAS,EAAE,IAAI,MAAM,EAAE,CAAC;AACtE,QAAO;;AAGT,SAAgB,oBAAoB,MAAM,QAAQ,KAAK;AAErD,QADY,OAAO,IAAI,+BAA+B,IAAI,wBAAwB,GAAG,CAAC,MAAM,IAC9E;;AAGhB,SAAgB,oBAAoB,MAAM,QAAQ,KAAK;CACrD,MAAM,MAAM,OAAO,SAAS,OAAO,IAAI,+BAA+B,IAAI,wBAAwB,GAAG,EAAE,GAAG;AAC1G,KAAI,OAAO,UAAU,IAAI,IAAI,OAAO,KAAK,OAAO,MAAO,QAAO;AAC9D,QAAO;;AAGT,SAAgB,wBAAwB,MAAM,QAAQ,KAAK;AACzD,QAAO,WACL,IAAI,iCACF,IAAI,oCACJ,IAAI,6BACJ,yBACH;;AAOH,SAAgB,wBAAwB,EAAE,MAAM,YAAY,eAAe;CAEzE,MAAM,YADQ,MAAM,QAAQ,YAAY,GAAG,YAAY,KAAK,SAAS,OAAO,QAAQ,GAAG,CAAC,MAAM,CAAC,CAAC,OAAO,QAAQ,GAAG,EAAE,EAC7F,MAAM,CAAC,KAAK,IAAI;AACvC,QAAO,uBAAuB,QAAQ,GAAG,KAAK,KAAK,CAAC,GAAG,KAAK,WAAW,CAAC,GAAG;;AAG7E,SAAgB,uBAAuB,KAAK,EAAE,cAAc,UAAU,EAAE,EAAE;CACxE,MAAM,QAAQ,OAAO,OAAO,GAAG,CAAC,MAAM,CAAC,aAAa;AACpD,KAAI,eAAe,UAAU,SAAU,QAAO;AAC9C,KAAI,UAAU,SAAS,UAAU,cAAc,UAAU,SAAU,QAAO;AAC1E,KAAI,UAAU,SAAS,UAAU,cAAc,UAAU,UAAW,QAAO;AAC3E,KAAI,UAAU,SAAS,UAAU,OAAQ,QAAO;AAChD,QAAO;;AAGT,SAAgB,kBAAkB,KAAK,UAAU;AAC/C,KAAI,CAAC,IAAK,QAAO;AACjB,KAAI;AACF,SAAO,KAAK,MAAM,IAAI;SAChB;AACN,SAAO;;;AAIX,SAAgB,qBAAqB,MAAM,OAAO,EAAE,EAAE;AACpD,QAAO;EAAE,MAAM,OAAO,QAAQ,GAAG;EAAE,MAAM,QAAQ,EAAE;EAAE;;AAGvD,SAAgB,qBAAqB,KAAK,WAAW,MAAM;CACzD,MAAM,SAAS,OAAO,QAAQ,WAAW,kBAAkB,KAAK,SAAS,GAAG;AAC5E,KAAI,CAAC,UAAU,OAAO,WAAW,SAAU,QAAO;CAClD,MAAM,OAAO,OAAO,OAAO,QAAQ,GAAG,CAAC,MAAM;AAC7C,KAAI,CAAC,KAAM,QAAO;AAClB,QAAO;EACL,GAAG;EACH;EACA,MAAM,OAAO,QAAQ,EAAE;EACxB"}