ultracontext 1.3.1 → 1.3.2

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 +1 @@
1
- {"version":3,"file":"lock-PqeXMp7P.mjs","names":[],"sources":["../../daemon/src/utils.mjs","../../daemon/src/lock.mjs"],"sourcesContent":["import crypto from \"node:crypto\";\n\n// shared utils from harness\nexport { expandHome, truncateString, safeJsonParse, extractSessionIdFromPath } from \"@ultracontext/harness/utils\";\n\nexport function sha256(value) {\n return crypto.createHash(\"sha256\").update(value).digest(\"hex\");\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\n// extract project path from JSONL file location\n// claude: ~/.claude/projects/-Users-fabio-Code-foo/session.jsonl → /Users/fabio/Code/foo\n// codex: ~/.codex/sessions/<uuid>.jsonl → null (cwd comes from session_meta)\n// openclaw: ~/.openclaw/agents/<name>/sessions/<uuid>.jsonl → null\nexport function extractProjectPathFromFile(filePath) {\n const match = filePath.match(/\\.claude\\/projects\\/([^/]+)/);\n if (!match) return null;\n\n // convert dash-separated path back to real path (leading dash = leading /)\n const encoded = match[1];\n return encoded.replace(/-/g, \"/\");\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 userId = \"\",\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 userId: String(userId ?? \"\"),\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":";;;;;;;AAKA,SAAgB,OAAO,OAAO;AAC5B,QAAO,OAAO,WAAW,SAAS,CAAC,OAAO,MAAM,CAAC,OAAO,MAAM;;AAGhE,SAAgB,MAAM,OAAO,UAAU;CACrC,MAAM,SAAS,OAAO,SAAS,OAAO,SAAS,GAAG,EAAE,GAAG;AACvD,QAAO,OAAO,SAAS,OAAO,GAAG,SAAS;;AAG5C,SAAgB,YAAY,OAAO,WAAW,OAAO;AACnD,KAAI,UAAU,OAAW,QAAO;CAChC,MAAM,aAAa,OAAO,MAAM,CAAC,MAAM,CAAC,aAAa;AACrD,KAAI;EAAC;EAAK;EAAQ;EAAO;EAAK,CAAC,SAAS,WAAW,CAAE,QAAO;AAC5D,KAAI;EAAC;EAAK;EAAS;EAAM;EAAM,CAAC,SAAS,WAAW,CAAE,QAAO;AAC7D,QAAO;;AAOT,SAAgB,2BAA2B,UAAU;CACnD,MAAM,QAAQ,SAAS,MAAM,8BAA8B;AAC3D,KAAI,CAAC,MAAO,QAAO;AAInB,QADgB,MAAM,GACP,QAAQ,MAAM,IAAI;;;;;AC1BnC,MAAM,oBAAoB;AAE1B,SAAS,WAAW,KAAK;AACvB,KAAI,CAAC,OAAO,UAAU,IAAI,IAAI,OAAO,EAAG,QAAO;AAC/C,KAAI;AACF,UAAQ,KAAK,KAAK,EAAE;AACpB,SAAO;UACA,OAAO;AACd,MAAI,OAAO,SAAS,QAAS,QAAO;AACpC,MAAI,OAAO,SAAS,QAAS,QAAO;AACpC,SAAO;;;AAIX,eAAe,iBAAiB,UAAU;AACxC,KAAI;EACF,MAAM,MAAM,MAAM,GAAG,SAAS,UAAU,OAAO;EAC/C,MAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,SAAO,UAAU,OAAO,WAAW,WAAW,SAAS;SACjD;AACN,SAAO;;;AAIX,SAAgB,gBAAgB,MAAM,QAAQ,KAAK;AACjD,QAAO,WAAW,IAAI,0BAA0B,kBAAkB;;AAGpE,eAAsB,gBAAgB,EACpC,WAAW,gBAAgB,QAAQ,IAAI,EACvC,SAAS,IACT,OAAO,OACL,EAAE,EAAE;CACN,MAAM,WAAW,KAAK,QAAQ,SAAS;AACvC,OAAM,GAAG,MAAM,KAAK,QAAQ,SAAS,EAAE,EAAE,WAAW,MAAM,CAAC;CAE3D,IAAI;AACJ,KAAI;AACF,WAAS,MAAM,GAAG,KAAK,UAAU,KAAK;UAC/B,OAAO;AACd,MAAI,OAAO,SAAS,SAAU,OAAM;EAEpC,MAAM,WAAW,MAAM,iBAAiB,SAAS;EACjD,MAAM,cAAc,OAAO,SAAS,OAAO,UAAU,OAAO,GAAG,EAAE,GAAG;AACpE,MAAI,CAAC,WAAW,YAAY,EAAE;AAC5B,OAAI;AACF,UAAM,GAAG,OAAO,SAAS;WACnB;AAGR,YAAS,MAAM,GAAG,KAAK,UAAU,KAAK;SACjC;GACL,MAAM,SAAS,cACX,6CAA6C,YAAY,KACzD;GACJ,MAAM,YAAY,IAAI,MAAM,OAAO;AACnC,aAAU,OAAO;AACjB,aAAU,MAAM;AAChB,SAAM;;;CAIV,MAAM,UAAU;EACd,KAAK,QAAQ;EACb,MAAM,OAAO,QAAQ,GAAG;EACxB,QAAQ,OAAO,UAAU,GAAG;EAC5B,4BAAW,IAAI,MAAM,EAAC,aAAa;EACpC;AACD,OAAM,OAAO,UAAU,GAAG,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC,KAAK,OAAO;CAEvE,IAAI,WAAW;CACf,MAAM,UAAU,YAAY;AAC1B,MAAI,SAAU;AACd,aAAW;AACX,MAAI;AACF,SAAM,OAAO,OAAO;UACd;AAGR,MAAI;AACF,SAAM,GAAG,OAAO,SAAS;UACnB;;AAKV,QAAO;EACL,UAAU;EACV;EACA;EACD"}
1
+ {"version":3,"file":"lock-CQ3xrIlj.mjs","names":[],"sources":["../../daemon/src/utils.mjs","../../daemon/src/lock.mjs"],"sourcesContent":["import crypto from \"node:crypto\";\n\n// shared utils from harness\nexport { expandHome, truncateString, safeJsonParse, extractSessionIdFromPath } from \"@ultracontext/parsers/utils\";\n\nexport function sha256(value) {\n return crypto.createHash(\"sha256\").update(value).digest(\"hex\");\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\n// extract project path from JSONL file location\n// claude: ~/.claude/projects/-Users-fabio-Code-foo/session.jsonl → /Users/fabio/Code/foo\n// codex: ~/.codex/sessions/<uuid>.jsonl → null (cwd comes from session_meta)\n// openclaw: ~/.openclaw/agents/<name>/sessions/<uuid>.jsonl → null\nexport function extractProjectPathFromFile(filePath) {\n const match = filePath.match(/\\.claude\\/projects\\/([^/]+)/);\n if (!match) return null;\n\n // convert dash-separated path back to real path (leading dash = leading /)\n const encoded = match[1];\n return encoded.replace(/-/g, \"/\");\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 userId = \"\",\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 userId: String(userId ?? \"\"),\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":";;;;;;;AAKA,SAAgB,OAAO,OAAO;AAC5B,QAAO,OAAO,WAAW,SAAS,CAAC,OAAO,MAAM,CAAC,OAAO,MAAM;;AAGhE,SAAgB,MAAM,OAAO,UAAU;CACrC,MAAM,SAAS,OAAO,SAAS,OAAO,SAAS,GAAG,EAAE,GAAG;AACvD,QAAO,OAAO,SAAS,OAAO,GAAG,SAAS;;AAG5C,SAAgB,YAAY,OAAO,WAAW,OAAO;AACnD,KAAI,UAAU,OAAW,QAAO;CAChC,MAAM,aAAa,OAAO,MAAM,CAAC,MAAM,CAAC,aAAa;AACrD,KAAI;EAAC;EAAK;EAAQ;EAAO;EAAK,CAAC,SAAS,WAAW,CAAE,QAAO;AAC5D,KAAI;EAAC;EAAK;EAAS;EAAM;EAAM,CAAC,SAAS,WAAW,CAAE,QAAO;AAC7D,QAAO;;AAOT,SAAgB,2BAA2B,UAAU;CACnD,MAAM,QAAQ,SAAS,MAAM,8BAA8B;AAC3D,KAAI,CAAC,MAAO,QAAO;AAInB,QADgB,MAAM,GACP,QAAQ,MAAM,IAAI;;;;;AC1BnC,MAAM,oBAAoB;AAE1B,SAAS,WAAW,KAAK;AACvB,KAAI,CAAC,OAAO,UAAU,IAAI,IAAI,OAAO,EAAG,QAAO;AAC/C,KAAI;AACF,UAAQ,KAAK,KAAK,EAAE;AACpB,SAAO;UACA,OAAO;AACd,MAAI,OAAO,SAAS,QAAS,QAAO;AACpC,MAAI,OAAO,SAAS,QAAS,QAAO;AACpC,SAAO;;;AAIX,eAAe,iBAAiB,UAAU;AACxC,KAAI;EACF,MAAM,MAAM,MAAM,GAAG,SAAS,UAAU,OAAO;EAC/C,MAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,SAAO,UAAU,OAAO,WAAW,WAAW,SAAS;SACjD;AACN,SAAO;;;AAIX,SAAgB,gBAAgB,MAAM,QAAQ,KAAK;AACjD,QAAO,WAAW,IAAI,0BAA0B,kBAAkB;;AAGpE,eAAsB,gBAAgB,EACpC,WAAW,gBAAgB,QAAQ,IAAI,EACvC,SAAS,IACT,OAAO,OACL,EAAE,EAAE;CACN,MAAM,WAAW,KAAK,QAAQ,SAAS;AACvC,OAAM,GAAG,MAAM,KAAK,QAAQ,SAAS,EAAE,EAAE,WAAW,MAAM,CAAC;CAE3D,IAAI;AACJ,KAAI;AACF,WAAS,MAAM,GAAG,KAAK,UAAU,KAAK;UAC/B,OAAO;AACd,MAAI,OAAO,SAAS,SAAU,OAAM;EAEpC,MAAM,WAAW,MAAM,iBAAiB,SAAS;EACjD,MAAM,cAAc,OAAO,SAAS,OAAO,UAAU,OAAO,GAAG,EAAE,GAAG;AACpE,MAAI,CAAC,WAAW,YAAY,EAAE;AAC5B,OAAI;AACF,UAAM,GAAG,OAAO,SAAS;WACnB;AAGR,YAAS,MAAM,GAAG,KAAK,UAAU,KAAK;SACjC;GACL,MAAM,SAAS,cACX,6CAA6C,YAAY,KACzD;GACJ,MAAM,YAAY,IAAI,MAAM,OAAO;AACnC,aAAU,OAAO;AACjB,aAAU,MAAM;AAChB,SAAM;;;CAIV,MAAM,UAAU;EACd,KAAK,QAAQ;EACb,MAAM,OAAO,QAAQ,GAAG;EACxB,QAAQ,OAAO,UAAU,GAAG;EAC5B,4BAAW,IAAI,MAAM,EAAC,aAAa;EACpC;AACD,OAAM,OAAO,UAAU,GAAG,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC,KAAK,OAAO;CAEvE,IAAI,WAAW;CACf,MAAM,UAAU,YAAY;AAC1B,MAAI,SAAU;AACd,aAAW;AACX,MAAI;AACF,SAAM,OAAO,OAAO;UACd;AAGR,MAAI;AACF,SAAM,GAAG,OAAO,SAAS;UACnB;;AAKV,QAAO;EACL,UAAU;EACV;EACA;EACD"}
@@ -1,7 +1,7 @@
1
1
  import path from "node:path";
2
2
  import os from "node:os";
3
3
 
4
- //#region ../../packages/harness/src/utils.mjs
4
+ //#region ../../packages/parsers/src/utils.mjs
5
5
  function expandHome$1(inputPath) {
6
6
  if (!inputPath || !inputPath.startsWith("~")) return inputPath;
7
7
  if (inputPath === "~") return os.homedir();
@@ -148,4 +148,4 @@ function parseDaemonWsMessage(raw, fallback = null) {
148
148
 
149
149
  //#endregion
150
150
  export { preserveText as _, parseDaemonWsMessage as a, truncateString as b, resolveDaemonWsInfoFile as c, coerceMessageText as d, expandHome$1 as f, normalizeWhitespace as g, normalizeRole as h, normalizeBootstrapMode as i, resolveDaemonWsPort as l, firstMessageTimestamp as m, buildDaemonWsMessage as n, parseProtocolJson as o, extractSessionIdFromPath as p, createBootstrapStateKey as r, resolveDaemonWsHost as s, DAEMON_WS_MESSAGE_TYPES as t, asIso as u, safeJsonParse as v, toMessage as y };
151
- //# sourceMappingURL=src-B9CWO5Xk.mjs.map
151
+ //# sourceMappingURL=src-BSCJv6SU.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"src-B9CWO5Xk.mjs","names":["expandHome"],"sources":["../../../packages/harness/src/utils.mjs","../../../packages/protocol/src/index.mjs"],"sourcesContent":["import os from \"node:os\";\nimport path from \"node:path\";\n\n// resolve ~ to home directory\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\n// safe truncation with indicator\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\n// swallow malformed JSON\nexport function safeJsonParse(line) {\n try {\n return JSON.parse(line);\n } catch {\n return null;\n }\n}\n\n// pull UUID from file path, fall back to filename\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\n// normalize role strings across agents\nexport function normalizeRole(role, fallback = \"system\") {\n const lowered = String(role ?? \"\").toLowerCase();\n if ([\"user\", \"human\"].includes(lowered)) return \"user\";\n if ([\"assistant\", \"agent\", \"ai\"].includes(lowered)) return \"assistant\";\n return fallback;\n}\n\n// collapse whitespace to single spaces\nexport function normalizeWhitespace(value) {\n return String(value ?? \"\").replace(/\\s+/g, \" \").trim();\n}\n\n// preserve newlines, trim lines, collapse 3+ blank lines → 2\nexport function preserveText(value) {\n return String(value ?? \"\")\n .split(\"\\n\")\n .map((l) => l.trimEnd())\n .join(\"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n\n// coerce message content to string\nexport function toMessage(raw, maxLen = 12000) {\n if (!raw) return \"\";\n if (typeof raw === \"string\") return truncateString(raw, maxLen);\n if (typeof raw === \"object\") return truncateString(JSON.stringify(raw), maxLen);\n return truncateString(String(raw), maxLen);\n}\n\n// coerce message content to plain text\nexport function coerceMessageText(message) {\n const content = message?.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 if (typeof content.raw === \"string\") return content.raw;\n }\n if (typeof message?.message === \"string\") return message.message;\n return \"\";\n}\n\n// get timestamp from first message\nexport function firstMessageTimestamp(messages) {\n return (\n messages?.[0]?.content?.timestamp ??\n messages?.[0]?.metadata?.timestamp ??\n new Date().toISOString()\n );\n}\n\n// coerce ISO timestamp, fall back to now\nexport function asIso(value) {\n if (!value) return new Date().toISOString();\n const d = new Date(String(value));\n if (Number.isNaN(d.getTime())) return new Date().toISOString();\n return d.toISOString();\n}\n","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, userId, 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(userId)}:${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":"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"}
1
+ {"version":3,"file":"src-BSCJv6SU.mjs","names":["expandHome"],"sources":["../../../packages/parsers/src/utils.mjs","../../../packages/protocol/src/index.mjs"],"sourcesContent":["import os from \"node:os\";\nimport path from \"node:path\";\n\n// resolve ~ to home directory\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\n// safe truncation with indicator\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\n// swallow malformed JSON\nexport function safeJsonParse(line) {\n try {\n return JSON.parse(line);\n } catch {\n return null;\n }\n}\n\n// pull UUID from file path, fall back to filename\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\n// normalize role strings across agents\nexport function normalizeRole(role, fallback = \"system\") {\n const lowered = String(role ?? \"\").toLowerCase();\n if ([\"user\", \"human\"].includes(lowered)) return \"user\";\n if ([\"assistant\", \"agent\", \"ai\"].includes(lowered)) return \"assistant\";\n return fallback;\n}\n\n// collapse whitespace to single spaces\nexport function normalizeWhitespace(value) {\n return String(value ?? \"\").replace(/\\s+/g, \" \").trim();\n}\n\n// preserve newlines, trim lines, collapse 3+ blank lines → 2\nexport function preserveText(value) {\n return String(value ?? \"\")\n .split(\"\\n\")\n .map((l) => l.trimEnd())\n .join(\"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n\n// coerce message content to string\nexport function toMessage(raw, maxLen = 12000) {\n if (!raw) return \"\";\n if (typeof raw === \"string\") return truncateString(raw, maxLen);\n if (typeof raw === \"object\") return truncateString(JSON.stringify(raw), maxLen);\n return truncateString(String(raw), maxLen);\n}\n\n// coerce message content to plain text\nexport function coerceMessageText(message) {\n const content = message?.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 if (typeof content.raw === \"string\") return content.raw;\n }\n if (typeof message?.message === \"string\") return message.message;\n return \"\";\n}\n\n// get timestamp from first message\nexport function firstMessageTimestamp(messages) {\n return (\n messages?.[0]?.content?.timestamp ??\n messages?.[0]?.metadata?.timestamp ??\n new Date().toISOString()\n );\n}\n\n// coerce ISO timestamp, fall back to now\nexport function asIso(value) {\n if (!value) return new Date().toISOString();\n const d = new Date(String(value));\n if (Number.isNaN(d.getTime())) return new Date().toISOString();\n return d.toISOString();\n}\n","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, userId, 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(userId)}:${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":"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"}
@@ -1,9 +1,9 @@
1
- import { _ as preserveText, b as truncateString, d as coerceMessageText, f as expandHome, g as normalizeWhitespace, h as normalizeRole, m as firstMessageTimestamp, p as extractSessionIdFromPath, u as asIso, v as safeJsonParse, y as toMessage } from "./src-B9CWO5Xk.mjs";
1
+ import { _ as preserveText, b as truncateString, d as coerceMessageText, f as expandHome, g as normalizeWhitespace, h as normalizeRole, m as firstMessageTimestamp, p as extractSessionIdFromPath, u as asIso, v as safeJsonParse, y as toMessage } from "./src-BSCJv6SU.mjs";
2
2
  import path from "node:path";
3
3
  import { randomUUID } from "node:crypto";
4
4
  import fs from "node:fs/promises";
5
5
 
6
- //#region ../../packages/harness/src/parsers/claude.mjs
6
+ //#region ../../packages/parsers/src/agents/claude.mjs
7
7
  function formatToolUse(item) {
8
8
  const name = (item.name ?? "unknown").toLowerCase();
9
9
  const input = item.input ?? {};
@@ -311,7 +311,7 @@ function parseClaudeCodeLine({ line, filePath }) {
311
311
  }
312
312
 
313
313
  //#endregion
314
- //#region ../../packages/harness/src/parsers/codex.mjs
314
+ //#region ../../packages/parsers/src/agents/codex.mjs
315
315
  function parseCodexLine({ line, filePath }) {
316
316
  const parsed = safeJsonParse(line);
317
317
  if (!parsed || typeof parsed !== "object") return null;
@@ -439,7 +439,7 @@ function parseCodexLine({ line, filePath }) {
439
439
  }
440
440
 
441
441
  //#endregion
442
- //#region ../../packages/harness/src/parsers/openclaw.mjs
442
+ //#region ../../packages/parsers/src/agents/openclaw.mjs
443
443
  function extractOpenClawTextContent(content) {
444
444
  if (!content) return "";
445
445
  if (typeof content === "string") return normalizeWhitespace(content);
@@ -609,7 +609,84 @@ function parseOpenClawLine({ line, filePath }) {
609
609
  }
610
610
 
611
611
  //#endregion
612
- //#region ../../packages/harness/src/writers/claude.mjs
612
+ //#region ../../packages/parsers/src/gstack.mjs
613
+ function extractGstackProjectSlug(filePath) {
614
+ return filePath.match(/\.gstack\/projects\/([^/]+)\//)?.[1] ?? "unknown-project";
615
+ }
616
+ function gstackFileType(filePath) {
617
+ const base = filePath.split("/").pop() ?? "";
618
+ if (base === "learnings.jsonl") return "learning";
619
+ if (base === "timeline.jsonl") return "timeline";
620
+ if (base === "resources-shown.jsonl") return "resource";
621
+ if (base.endsWith("-reviews.jsonl")) return "review";
622
+ return "unknown";
623
+ }
624
+ function parseGstackLine({ line, filePath }) {
625
+ const parsed = safeJsonParse(line);
626
+ if (!parsed || typeof parsed !== "object") return null;
627
+ const projectSlug = extractGstackProjectSlug(filePath);
628
+ const fileType = gstackFileType(filePath);
629
+ const timestamp = parsed.ts ?? parsed.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
630
+ const sessionId = projectSlug;
631
+ if (fileType === "learning") {
632
+ const insight = normalizeWhitespace(parsed.insight);
633
+ if (!insight) return null;
634
+ const skill = parsed.skill ?? "unknown";
635
+ const conf = typeof parsed.confidence === "number" ? ` [${parsed.confidence}/10]` : "";
636
+ return {
637
+ sessionId,
638
+ eventType: `gstack.learning.${parsed.type ?? "insight"}`,
639
+ kind: "system",
640
+ timestamp,
641
+ message: toMessage(`[${skill}]${conf} ${insight}`),
642
+ raw: parsed
643
+ };
644
+ }
645
+ if (fileType === "timeline") {
646
+ const skill = parsed.skill ?? "unknown";
647
+ const event = parsed.event ?? "unknown";
648
+ const branch = parsed.branch ? ` (${parsed.branch})` : "";
649
+ const outcome = parsed.outcome ? ` → ${parsed.outcome}` : "";
650
+ const duration = parsed.duration_s ? ` ${parsed.duration_s}s` : "";
651
+ return {
652
+ sessionId,
653
+ eventType: `gstack.timeline.${event}`,
654
+ kind: "system",
655
+ timestamp,
656
+ message: toMessage(`${skill} ${event}${branch}${outcome}${duration}`),
657
+ raw: parsed
658
+ };
659
+ }
660
+ if (fileType === "review") {
661
+ const skill = parsed.skill ?? "review";
662
+ const score = parsed.overall_score != null ? ` score=${parsed.overall_score}` : "";
663
+ return {
664
+ sessionId,
665
+ eventType: "gstack.review",
666
+ kind: "system",
667
+ timestamp,
668
+ message: toMessage(`${skill}${parsed.status ? ` [${parsed.status}]` : ""}${score}`),
669
+ raw: parsed
670
+ };
671
+ }
672
+ if (fileType === "resource") {
673
+ const title = normalizeWhitespace(parsed.title);
674
+ const url = parsed.url ?? "";
675
+ if (!title && !url) return null;
676
+ return {
677
+ sessionId,
678
+ eventType: "gstack.resource",
679
+ kind: "system",
680
+ timestamp,
681
+ message: toMessage(title ? `${title} — ${url}` : url),
682
+ raw: parsed
683
+ };
684
+ }
685
+ return null;
686
+ }
687
+
688
+ //#endregion
689
+ //#region ../../packages/parsers/src/writers/claude.mjs
613
690
  function isUuid(value) {
614
691
  return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(String(value ?? "").trim());
615
692
  }
@@ -722,7 +799,7 @@ async function writeClaudeSession({ sessionId, cwd, messages, baseDir }) {
722
799
  }
723
800
 
724
801
  //#endregion
725
- //#region ../../packages/harness/src/writers/codex.mjs
802
+ //#region ../../packages/parsers/src/writers/codex.mjs
726
803
  function buildEventMsgLine(message, fallbackTs) {
727
804
  const ts = asIso(message?.content?.timestamp ?? message?.metadata?.timestamp ?? fallbackTs);
728
805
  const role = normalizeRole(message?.role);
@@ -840,5 +917,5 @@ async function writeCodexSession({ sessionId, cwd, messages, baseDir }) {
840
917
  }
841
918
 
842
919
  //#endregion
843
- export { parseOpenClawLine as a, writeClaudeSession as i, writeCodexSession as n, parseCodexLine as o, hasLocalClaudeSession as r, parseClaudeCodeLine as s, hasLocalCodexSession as t };
844
- //# sourceMappingURL=src-B7VNX8_g.mjs.map
920
+ export { parseGstackLine as a, parseClaudeCodeLine as c, writeClaudeSession as i, writeCodexSession as n, parseOpenClawLine as o, hasLocalClaudeSession as r, parseCodexLine as s, hasLocalCodexSession as t };
921
+ //# sourceMappingURL=src-DzUz8GPJ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"src-DzUz8GPJ.mjs","names":[],"sources":["../../../packages/parsers/src/agents/claude.mjs","../../../packages/parsers/src/agents/codex.mjs","../../../packages/parsers/src/agents/openclaw.mjs","../../../packages/parsers/src/gstack.mjs","../../../packages/parsers/src/writers/claude.mjs","../../../packages/parsers/src/writers/codex.mjs"],"sourcesContent":["import {\n extractSessionIdFromPath,\n normalizeRole,\n normalizeWhitespace,\n preserveText,\n safeJsonParse,\n toMessage,\n truncateString,\n} from \"../utils.mjs\";\n\n// format a tool_use block into a readable string\nfunction formatToolUse(item) {\n const name = (item.name ?? \"unknown\").toLowerCase();\n const input = item.input ?? {};\n const filePath = input.file_path ?? input.path ?? \"\";\n\n if (name === \"write\") {\n const content = preserveText(input.content ?? input.file_text ?? \"\");\n return `[Write] ${filePath}\\n${content}`;\n }\n\n if (name === \"edit\") {\n const parts = [`[Edit] ${filePath}`];\n if (input.old_string) parts.push(`- ${preserveText(input.old_string)}`);\n if (input.new_string) parts.push(`+ ${preserveText(input.new_string)}`);\n return parts.join(\"\\n\");\n }\n\n if (name === \"read\") return `[Read] ${filePath}`;\n if (name === \"bash\") return `[Bash] ${preserveText(input.command ?? \"\")}`;\n\n // grep and glob share the same shape\n if (name === \"grep\" || name === \"glob\") {\n const loc = filePath ? ` in ${filePath}` : \"\";\n return `[${item.name}] ${input.pattern ?? \"\"}${loc}`;\n }\n\n // generic fallback\n const compact = JSON.stringify(input);\n return `[${item.name ?? name}] ${compact.length > 500 ? compact.slice(0, 500) + \"...\" : compact}`;\n}\n\n// format a tool_result block into a readable string\nfunction formatToolResult(item) {\n const content = item.content ?? \"\";\n\n if (typeof content === \"string\") {\n const text = preserveText(content);\n return text ? `[result] ${truncateString(text, 1000)}` : \"[result] ok\";\n }\n\n if (Array.isArray(content)) {\n const text = content\n .filter((c) => c?.type === \"text\" && typeof c.text === \"string\")\n .map((c) => preserveText(c.text))\n .filter(Boolean)\n .join(\"\\n\");\n return text ? `[result] ${truncateString(text, 1000)}` : \"[result] ok\";\n }\n\n return \"[result] ok\";\n}\n\n// extract text content from Claude Code's message.content (string, array, or object)\nexport function extractClaudeTextContent(content) {\n if (!content) return \"\";\n if (typeof content === \"string\") return preserveText(content);\n\n if (Array.isArray(content)) {\n const parts = [];\n for (const item of content) {\n if (!item || typeof item !== \"object\") continue;\n if (item.type === \"text\" && typeof item.text === \"string\") {\n const chunk = preserveText(item.text);\n if (chunk) parts.push(chunk);\n }\n if (item.type === \"thinking\" && typeof item.thinking === \"string\") {\n const chunk = preserveText(item.thinking);\n if (chunk) parts.push(`[thinking] ${chunk}`);\n }\n if (item.type === \"tool_use\") parts.push(formatToolUse(item));\n if (item.type === \"tool_result\") parts.push(formatToolResult(item));\n }\n return parts.join(\"\\n\\n\");\n }\n\n if (typeof content === \"object\") {\n if (typeof content.text === \"string\") return preserveText(content.text);\n if (typeof content.content === \"string\") return preserveText(content.content);\n }\n\n return \"\";\n}\n\n// parse a single JSONL line from a Claude Code session file\nexport function parseClaudeCodeLine({ line, filePath }) {\n const parsed = safeJsonParse(line);\n if (!parsed || typeof parsed !== \"object\") return null;\n\n const type = String(parsed.type ?? \"\").toLowerCase();\n const sessionId =\n parsed.sessionId ??\n parsed.session_id ??\n parsed.payload?.sessionId ??\n parsed.payload?.session_id ??\n extractSessionIdFromPath(filePath);\n const timestamp = parsed.timestamp ?? parsed.ts ?? new Date().toISOString();\n\n // summary entries\n if (type === \"summary\") {\n const summary = normalizeWhitespace(parsed.summary);\n if (!summary) return null;\n return {\n sessionId,\n eventType: \"claude.summary\",\n kind: \"system\",\n timestamp,\n message: toMessage(summary),\n raw: parsed,\n };\n }\n\n // file history snapshots\n if (type === \"file-history-snapshot\") {\n const trackedFiles = Object.keys(parsed.snapshot?.trackedFileBackups ?? {}).length;\n const label = parsed.isSnapshotUpdate ? \"File snapshot update\" : \"File snapshot\";\n const message = `${label}: ${trackedFiles} tracked files`;\n return {\n sessionId,\n eventType: \"claude.file_snapshot\",\n kind: \"system\",\n timestamp,\n message: toMessage(message),\n raw: parsed,\n };\n }\n\n // system entries (local_command, stop_hook_summary, turn_duration, etc.)\n if (type === \"system\") {\n const subtype = parsed.subtype ?? \"unknown\";\n let message;\n\n if (subtype === \"local_command\") {\n message = parsed.content ? preserveText(parsed.content) : \"Local command executed\";\n } else if (subtype === \"stop_hook_summary\") {\n message = `Hook summary: ${parsed.hookCount ?? 0} hooks`;\n } else if (subtype === \"turn_duration\") {\n message = `Turn completed in ${parsed.durationMs ?? 0}ms (${parsed.messageCount ?? 0} messages)`;\n } else {\n message = `System event: ${subtype}`;\n }\n\n if (!message) return null;\n return {\n sessionId,\n eventType: `claude.system.${subtype}`,\n kind: \"system\",\n timestamp,\n message: toMessage(message),\n raw: parsed,\n };\n }\n\n // attachment entries (deferred_tools_delta, mcp_instructions_delta, etc.)\n if (type === \"attachment\") {\n const attachmentType = parsed.attachment?.type ?? \"unknown\";\n const parts = [];\n const added = parsed.attachment?.addedNames;\n const removed = parsed.attachment?.removedNames;\n if (Array.isArray(added) && added.length) parts.push(`added: ${added.join(\", \")}`);\n if (Array.isArray(removed) && removed.length) parts.push(`removed: ${removed.join(\", \")}`);\n const detail = parts.length ? ` (${parts.join(\"; \")})` : \"\";\n return {\n sessionId,\n eventType: `claude.attachment.${attachmentType}`,\n kind: \"system\",\n timestamp,\n message: toMessage(`Attachment: ${attachmentType}${detail}`),\n raw: parsed,\n };\n }\n\n // progress entries (hook_progress, etc.)\n if (type === \"progress\") {\n const data = parsed.data ?? {};\n const subtype = data.type ?? \"unknown\";\n const label = data.hookName ?? subtype;\n return {\n sessionId,\n eventType: `claude.progress.${subtype}`,\n kind: \"system\",\n timestamp,\n message: toMessage(`Progress: ${subtype} (${label})`),\n raw: parsed,\n };\n }\n\n // queue operation entries (enqueue, dequeue, etc.)\n if (type === \"queue-operation\") {\n const operation = parsed.operation ?? \"unknown\";\n const content = parsed.content ? `: ${parsed.content}` : \"\";\n return {\n sessionId,\n eventType: \"claude.queue_operation\",\n kind: \"system\",\n timestamp,\n message: toMessage(`Queue ${operation}${content}`),\n raw: parsed,\n };\n }\n\n // custom title entries\n if (type === \"custom-title\") {\n const customTitle = parsed.customTitle ?? \"unknown\";\n return {\n sessionId,\n eventType: \"claude.custom_title\",\n kind: \"system\",\n timestamp,\n message: toMessage(`Custom title: ${customTitle}`),\n raw: parsed,\n };\n }\n\n // agent name entries\n if (type === \"agent-name\") {\n const agentName = parsed.agentName ?? \"unknown\";\n return {\n sessionId,\n eventType: \"claude.agent_name\",\n kind: \"system\",\n timestamp,\n message: toMessage(`Agent name: ${agentName}`),\n raw: parsed,\n };\n }\n\n // PR link entries\n if (type === \"pr-link\") {\n const prNumber = parsed.prNumber ?? 0;\n const prUrl = parsed.prUrl ?? \"\";\n return {\n sessionId,\n eventType: \"claude.pr_link\",\n kind: \"system\",\n timestamp,\n message: toMessage(`PR #${prNumber}: ${prUrl}`),\n raw: parsed,\n };\n }\n\n // permission mode changes\n if (type === \"permission-mode\") {\n return {\n sessionId,\n eventType: \"claude.permission_mode\",\n kind: \"system\",\n timestamp,\n message: toMessage(`Permission mode: ${parsed.permissionMode ?? \"unknown\"}`),\n raw: parsed,\n };\n }\n\n // last user prompt captured by the session\n if (type === \"last-prompt\") {\n const prompt = parsed.lastPrompt ?? \"\";\n if (!prompt) return null;\n return {\n sessionId,\n eventType: \"claude.last_prompt\",\n kind: \"system\",\n timestamp,\n message: toMessage(prompt),\n raw: parsed,\n };\n }\n\n // AI-generated session title\n if (type === \"ai-title\") {\n return {\n sessionId,\n eventType: \"claude.ai_title\",\n kind: \"system\",\n timestamp,\n message: toMessage(`AI title: ${parsed.aiTitle ?? \"unknown\"}`),\n raw: parsed,\n };\n }\n\n // periodic task summary (fork-generated, every min(5 steps, 2min))\n if (type === \"task-summary\") {\n return {\n sessionId,\n eventType: \"claude.task_summary\",\n kind: \"system\",\n timestamp,\n message: toMessage(parsed.summary ?? \"[task summary]\"),\n raw: parsed,\n };\n }\n\n // session tag for searchability\n if (type === \"tag\") {\n return {\n sessionId,\n eventType: \"claude.tag\",\n kind: \"system\",\n timestamp,\n message: toMessage(`Tag: ${parsed.tag ?? \"\"}`),\n raw: parsed,\n };\n }\n\n // agent color assignment (from /rename or swarm)\n if (type === \"agent-color\") {\n return {\n sessionId,\n eventType: \"claude.agent_color\",\n kind: \"system\",\n timestamp,\n message: toMessage(`Agent color: ${parsed.agentColor ?? \"unknown\"}`),\n raw: parsed,\n };\n }\n\n // agent setting/definition (from --agent flag)\n if (type === \"agent-setting\") {\n return {\n sessionId,\n eventType: \"claude.agent_setting\",\n kind: \"system\",\n timestamp,\n message: toMessage(`Agent setting: ${parsed.agentSetting ?? \"unknown\"}`),\n raw: parsed,\n };\n }\n\n // session mode (coordinator/normal)\n if (type === \"mode\") {\n return {\n sessionId,\n eventType: \"claude.mode\",\n kind: \"system\",\n timestamp,\n message: toMessage(`Mode: ${parsed.mode ?? \"unknown\"}`),\n raw: parsed,\n };\n }\n\n // worktree session state\n if (type === \"worktree-state\") {\n const ws = parsed.worktreeSession;\n const label = ws ? `entered ${ws.worktreePath ?? \"\"}` : \"exited\";\n return {\n sessionId,\n eventType: \"claude.worktree_state\",\n kind: \"system\",\n timestamp,\n message: toMessage(`Worktree: ${label}`),\n raw: parsed,\n };\n }\n\n // file attribution snapshot (character-level contribution tracking)\n if (type === \"attribution-snapshot\") {\n const fileCount = Object.keys(parsed.fileStates ?? {}).length;\n return {\n sessionId,\n eventType: \"claude.attribution_snapshot\",\n kind: \"system\",\n timestamp,\n message: toMessage(`Attribution snapshot: ${fileCount} files`),\n raw: parsed,\n };\n }\n\n // content replacement stubs (replayed on resume for prompt cache stability)\n if (type === \"content-replacement\") {\n const count = parsed.replacements?.length ?? 0;\n return {\n sessionId,\n eventType: \"claude.content_replacement\",\n kind: \"system\",\n timestamp,\n message: toMessage(`Content replacement: ${count} blocks`),\n raw: parsed,\n };\n }\n\n // speculation accept (speculative execution savings)\n if (type === \"speculation-accept\") {\n return {\n sessionId,\n eventType: \"claude.speculation_accept\",\n kind: \"system\",\n timestamp,\n message: toMessage(`Speculation accepted: saved ${parsed.timeSavedMs ?? 0}ms`),\n raw: parsed,\n };\n }\n\n // context collapse commit (marble-origami)\n if (type === \"marble-origami-commit\") {\n return {\n sessionId,\n eventType: \"claude.context_collapse_commit\",\n kind: \"system\",\n timestamp,\n message: toMessage(parsed.summary ?? `Context collapse: ${parsed.collapseId ?? \"\"}`),\n raw: parsed,\n };\n }\n\n // context collapse snapshot (marble-origami staged queue)\n if (type === \"marble-origami-snapshot\") {\n const stagedCount = parsed.staged?.length ?? 0;\n return {\n sessionId,\n eventType: \"claude.context_collapse_snapshot\",\n kind: \"system\",\n timestamp,\n message: toMessage(`Context collapse snapshot: ${stagedCount} staged`),\n raw: parsed,\n };\n }\n\n if (type !== \"user\" && type !== \"assistant\") return null;\n\n // user/assistant messages\n const rawContent =\n parsed.message?.content ??\n parsed.message ??\n parsed.content ??\n parsed.payload?.content ??\n \"\";\n let message = extractClaudeTextContent(rawContent);\n\n // thinking-only entries have redacted content — preserve them as system events\n if (!message) {\n const hasThinking = Array.isArray(rawContent) && rawContent.some((c) => c?.type === \"thinking\");\n if (!hasThinking) return null;\n message = \"[thinking]\";\n }\n\n const roleHint = parsed.message?.role ?? type;\n return {\n sessionId,\n eventType: `claude.${type}`,\n kind: normalizeRole(roleHint, type === \"user\" ? \"user\" : \"assistant\"),\n timestamp,\n message: toMessage(message),\n raw: parsed,\n };\n}\n","import { extractSessionIdFromPath, normalizeRole, safeJsonParse, toMessage } from \"../utils.mjs\";\n\n// parse a single JSONL line from a Codex session file\nexport function parseCodexLine({ line, filePath }) {\n const parsed = safeJsonParse(line);\n if (!parsed || typeof parsed !== \"object\") return null;\n\n const payload = parsed.payload ?? {};\n const sessionId =\n payload.session_id ??\n payload.id ??\n parsed.session_id ??\n extractSessionIdFromPath(filePath);\n\n // event messages (user/agent/task)\n if (parsed.type === \"event_msg\") {\n const eventType = payload.type ?? \"unknown\";\n if (![\"user_message\", \"agent_message\", \"task_started\", \"task_complete\", \"token_count\", \"agent_reasoning\", \"turn_aborted\", \"context_compacted\"].includes(eventType)) {\n return null;\n }\n\n // resolve kind based on event subtype\n const kind =\n eventType === \"user_message\" ? \"user\" :\n eventType === \"agent_message\" ? \"assistant\" :\n \"system\";\n\n // resolve message based on event subtype\n const message =\n eventType === \"token_count\" ? \"Token count update\" :\n eventType === \"agent_reasoning\" ? payload.text :\n eventType === \"turn_aborted\" ? (payload.reason ? `Turn aborted: ${payload.reason}` : \"Turn aborted\") :\n eventType === \"context_compacted\" ? \"Context compacted\" :\n payload.message ??\n payload.last_agent_message ??\n `${eventType}${payload.turn_id ? ` (${payload.turn_id})` : \"\"}`;\n\n return {\n sessionId,\n eventType: `event_msg.${eventType}`,\n kind,\n timestamp: parsed.timestamp ?? new Date().toISOString(),\n message: toMessage(message),\n raw: parsed,\n };\n }\n\n // session metadata\n if (parsed.type === \"session_meta\") {\n return {\n sessionId,\n eventType: \"session_meta\",\n kind: \"system\",\n timestamp: parsed.timestamp ?? new Date().toISOString(),\n message: `Session started in ${payload.cwd ?? \"unknown cwd\"}`,\n raw: parsed,\n };\n }\n\n // response items (message, reasoning, function calls)\n if (parsed.type === \"response_item\") {\n const subtype = payload.type;\n const ts = parsed.timestamp ?? new Date().toISOString();\n\n // assistant/user/developer messages\n if (subtype === \"message\") {\n const text = (payload.content ?? [])\n .map((c) => c.text ?? \"\")\n .filter(Boolean)\n .join(\"\\n\");\n const roleMap = { developer: \"system\", assistant: \"assistant\", user: \"user\" };\n const kind = roleMap[payload.role] ?? normalizeRole(payload.role);\n\n return {\n sessionId,\n eventType: \"response_item.message\",\n kind,\n timestamp: ts,\n message: toMessage(text || `[${payload.role ?? \"unknown\"} message]`),\n raw: parsed,\n };\n }\n\n // reasoning summaries\n if (subtype === \"reasoning\") {\n const text = (payload.summary ?? [])\n .map((s) => s.text ?? \"\")\n .filter(Boolean)\n .join(\"\\n\");\n\n return {\n sessionId,\n eventType: \"response_item.reasoning\",\n kind: \"system\",\n timestamp: ts,\n message: toMessage(text || \"[reasoning]\"),\n raw: parsed,\n };\n }\n\n // tool invocations\n if (subtype === \"function_call\") {\n const msg = `[${payload.name ?? \"unknown\"}] ${payload.arguments ?? \"\"}`;\n\n return {\n sessionId,\n eventType: \"response_item.function_call\",\n kind: \"system\",\n timestamp: ts,\n message: toMessage(msg),\n raw: parsed,\n };\n }\n\n // tool outputs\n if (subtype === \"function_call_output\") {\n return {\n sessionId,\n eventType: \"response_item.function_call_output\",\n kind: \"system\",\n timestamp: ts,\n message: toMessage(payload.output ?? `[output ${payload.call_id ?? \"\"}]`),\n raw: parsed,\n };\n }\n\n // web search invocations\n if (subtype === \"web_search_call\") {\n const query = payload.action?.query;\n return {\n sessionId,\n eventType: \"response_item.web_search_call\",\n kind: \"system\",\n timestamp: ts,\n message: query ? `[web_search] ${query}` : \"[web_search]\",\n raw: parsed,\n };\n }\n\n // custom tool invocations (e.g. apply_patch)\n if (subtype === \"custom_tool_call\") {\n const msg = `[${payload.name ?? \"unknown\"}] ${payload.input ?? \"\"}`;\n return {\n sessionId,\n eventType: \"response_item.custom_tool_call\",\n kind: \"system\",\n timestamp: ts,\n message: toMessage(msg),\n raw: parsed,\n };\n }\n\n // custom tool outputs\n if (subtype === \"custom_tool_call_output\") {\n return {\n sessionId,\n eventType: \"response_item.custom_tool_call_output\",\n kind: \"system\",\n timestamp: ts,\n message: toMessage(payload.output ?? `[output ${payload.call_id ?? \"\"}]`),\n raw: parsed,\n };\n }\n\n // unknown response_item subtype\n return null;\n }\n\n // session compacted (context window reset)\n if (parsed.type === \"compacted\") {\n return {\n sessionId,\n eventType: \"compacted\",\n kind: \"system\",\n timestamp: parsed.timestamp ?? new Date().toISOString(),\n message: \"Session compacted\",\n raw: parsed,\n };\n }\n\n // turn context (model, policies, cwd)\n if (parsed.type === \"turn_context\") {\n return {\n sessionId,\n eventType: \"turn_context\",\n kind: \"system\",\n timestamp: parsed.timestamp ?? new Date().toISOString(),\n message: `Turn context: model=${payload.model}, policy=${payload.approval_policy}`,\n raw: parsed,\n };\n }\n\n return null;\n}\n","import {\n extractSessionIdFromPath,\n normalizeWhitespace,\n safeJsonParse,\n toMessage,\n truncateString,\n} from \"../utils.mjs\";\n\n// extract text from OpenClaw content (string, array, or object)\nfunction extractOpenClawTextContent(content) {\n if (!content) return \"\";\n if (typeof content === \"string\") return normalizeWhitespace(content);\n\n if (Array.isArray(content)) {\n const textParts = [];\n for (const item of content) {\n if (!item || typeof item !== \"object\") continue;\n if (item.type === \"text\" && typeof item.text === \"string\") {\n const chunk = normalizeWhitespace(item.text);\n if (chunk) textParts.push(chunk);\n }\n }\n return textParts.join(\"\\n\");\n }\n\n if (typeof content === \"object\" && typeof content.text === \"string\") {\n return normalizeWhitespace(content.text);\n }\n\n return \"\";\n}\n\n// extract tool call names from OpenClaw content array\nfunction extractOpenClawToolCalls(content) {\n if (!Array.isArray(content)) return [];\n const names = [];\n for (const item of content) {\n if (!item || typeof item !== \"object\" || item.type !== \"toolCall\") continue;\n const name = normalizeWhitespace(item.name);\n if (name) names.push(name);\n }\n return names;\n}\n\n// build compact raw representation for storage\nfunction buildOpenClawRaw(parsed) {\n const raw = {\n type: parsed.type,\n id: parsed.id,\n parentId: parsed.parentId,\n timestamp: parsed.timestamp,\n };\n\n if (parsed.type === \"session\") {\n raw.session = {\n id: parsed.id,\n version: parsed.version,\n cwd: parsed.cwd,\n parentSession: parsed.parentSession,\n };\n return raw;\n }\n\n if (parsed.type === \"custom\") {\n raw.customType = parsed.customType;\n if (parsed.customType === \"model-snapshot\" && parsed.data && typeof parsed.data === \"object\") {\n raw.data = {\n provider: parsed.data.provider,\n modelApi: parsed.data.modelApi,\n modelId: parsed.data.modelId,\n timestamp: parsed.data.timestamp,\n };\n }\n return raw;\n }\n\n if (parsed.message && typeof parsed.message === \"object\") {\n const contentTypes = Array.isArray(parsed.message.content)\n ? parsed.message.content\n .filter((item) => item && typeof item === \"object\")\n .map((item) => String(item.type ?? \"unknown\"))\n .slice(0, 12)\n : [];\n\n raw.message = {\n role: parsed.message.role,\n stopReason: parsed.message.stopReason,\n toolName: parsed.message.toolName,\n toolCallId: parsed.message.toolCallId,\n isError: parsed.message.isError,\n contentTypes,\n };\n }\n\n if (parsed.type === \"compaction\") {\n raw.compaction = {\n firstKeptEntryId: parsed.firstKeptEntryId,\n tokensBefore: parsed.tokensBefore,\n };\n } else if (parsed.type === \"branch_summary\") {\n raw.branchSummary = {\n firstKeptEntryId: parsed.firstKeptEntryId,\n summary: typeof parsed.summary === \"string\" ? truncateString(parsed.summary, 350) : \"\",\n };\n }\n\n return raw;\n}\n\n// parse a single JSONL line from an OpenClaw session file\nexport function parseOpenClawLine({ line, filePath }) {\n const parsed = safeJsonParse(line);\n if (!parsed || typeof parsed !== \"object\") return null;\n\n const type = String(parsed.type ?? \"\").toLowerCase();\n const sessionId =\n parsed.session_id ??\n parsed.sessionId ??\n parsed.message?.session_id ??\n parsed.message?.sessionId ??\n extractSessionIdFromPath(filePath);\n\n const timestamp = parsed.timestamp ?? parsed.message?.timestamp ?? new Date().toISOString();\n\n // session start\n if (type === \"session\") {\n return {\n sessionId,\n eventType: \"openclaw.session\",\n kind: \"system\",\n timestamp,\n message: toMessage(`Session started in ${parsed.cwd ?? \"unknown cwd\"}`),\n raw: buildOpenClawRaw(parsed),\n };\n }\n\n // custom events\n if (type === \"custom\") {\n const customType = normalizeWhitespace(parsed.customType || \"custom\");\n if (customType === \"openclaw.cache-ttl\") return null;\n\n let message = `Custom event: ${customType}`;\n if (customType === \"model-snapshot\" && parsed.data && typeof parsed.data === \"object\") {\n const provider = normalizeWhitespace(parsed.data.provider || \"\");\n const modelId = normalizeWhitespace(parsed.data.modelId || \"\");\n const modelApi = normalizeWhitespace(parsed.data.modelApi || \"\");\n const details = [provider, modelId].filter(Boolean).join(\"/\");\n message = `Model snapshot${details ? `: ${details}` : \"\"}${modelApi ? ` (${modelApi})` : \"\"}`;\n }\n\n return {\n sessionId,\n eventType: `openclaw.custom.${customType || \"custom\"}`,\n kind: \"system\",\n timestamp,\n message: toMessage(message),\n raw: buildOpenClawRaw(parsed),\n };\n }\n\n // compaction\n if (type === \"compaction\") {\n return {\n sessionId,\n eventType: \"openclaw.compaction\",\n kind: \"system\",\n timestamp,\n message: toMessage(\"Session compaction summary updated\"),\n raw: buildOpenClawRaw(parsed),\n };\n }\n\n // branch summary\n if (type === \"branch_summary\") {\n const summary = normalizeWhitespace(parsed.summary || \"\");\n return {\n sessionId,\n eventType: \"openclaw.branch_summary\",\n kind: \"system\",\n timestamp,\n message: toMessage(summary || \"Branch summary updated\"),\n raw: buildOpenClawRaw(parsed),\n };\n }\n\n if (type !== \"message\" && type !== \"custom_message\") return null;\n\n // user/assistant messages\n const eventMessage = parsed.message ?? {};\n const role = String(eventMessage.role ?? \"\").toLowerCase();\n\n if (role === \"user\" || role === \"assistant\") {\n const text = extractOpenClawTextContent(eventMessage.content);\n if (text) {\n return {\n sessionId,\n eventType: `openclaw.${role}`,\n kind: role === \"user\" ? \"user\" : \"assistant\",\n timestamp,\n message: toMessage(text),\n raw: buildOpenClawRaw(parsed),\n };\n }\n\n // assistant tool calls without text\n if (role === \"assistant\") {\n const toolCalls = extractOpenClawToolCalls(eventMessage.content);\n if (toolCalls.length > 0) {\n const list = toolCalls.slice(0, 5).join(\", \");\n const suffix = toolCalls.length > 5 ? ` (+${toolCalls.length - 5})` : \"\";\n return {\n sessionId,\n eventType: \"openclaw.assistant.tool_use\",\n kind: \"system\",\n timestamp,\n message: toMessage(`Assistant requested tools: ${list}${suffix}`),\n raw: buildOpenClawRaw(parsed),\n };\n }\n }\n\n return null;\n }\n\n // tool results\n if (role === \"toolresult\") {\n const toolName = normalizeWhitespace(eventMessage.toolName || \"\");\n const isError = Boolean(eventMessage.isError);\n let message = `Tool result${toolName ? `: ${toolName}` : \"\"} (${isError ? \"error\" : \"ok\"})`;\n const text = extractOpenClawTextContent(eventMessage.content);\n if (text) message = `${message} ${truncateString(text, 320)}`;\n\n return {\n sessionId,\n eventType: \"openclaw.tool_result\",\n kind: \"system\",\n timestamp,\n message: toMessage(message),\n raw: buildOpenClawRaw(parsed),\n };\n }\n\n return null;\n}\n","import { normalizeWhitespace, safeJsonParse, toMessage } from \"./utils.mjs\";\n\n// extract project slug from gstack path: ~/.gstack/projects/{slug}/...\nfunction extractGstackProjectSlug(filePath) {\n const match = filePath.match(/\\.gstack\\/projects\\/([^/]+)\\//);\n return match?.[1] ?? \"unknown-project\";\n}\n\n// detect gstack file type from filename\nfunction gstackFileType(filePath) {\n const base = filePath.split(\"/\").pop() ?? \"\";\n if (base === \"learnings.jsonl\") return \"learning\";\n if (base === \"timeline.jsonl\") return \"timeline\";\n if (base === \"resources-shown.jsonl\") return \"resource\";\n if (base.endsWith(\"-reviews.jsonl\")) return \"review\";\n return \"unknown\";\n}\n\n// parse a single JSONL line from a gstack artifact file\nexport function parseGstackLine({ line, filePath }) {\n const parsed = safeJsonParse(line);\n if (!parsed || typeof parsed !== \"object\") return null;\n\n const projectSlug = extractGstackProjectSlug(filePath);\n const fileType = gstackFileType(filePath);\n const timestamp = parsed.ts ?? parsed.timestamp ?? new Date().toISOString();\n\n // sessionId = project slug — one context per gstack project\n const sessionId = projectSlug;\n\n // skill learnings (insights, patterns, preferences)\n if (fileType === \"learning\") {\n const insight = normalizeWhitespace(parsed.insight);\n if (!insight) return null;\n const skill = parsed.skill ?? \"unknown\";\n const conf = typeof parsed.confidence === \"number\" ? ` [${parsed.confidence}/10]` : \"\";\n return {\n sessionId,\n eventType: `gstack.learning.${parsed.type ?? \"insight\"}`,\n kind: \"system\",\n timestamp,\n message: toMessage(`[${skill}]${conf} ${insight}`),\n raw: parsed,\n };\n }\n\n // skill execution timeline (started, completed)\n if (fileType === \"timeline\") {\n const skill = parsed.skill ?? \"unknown\";\n const event = parsed.event ?? \"unknown\";\n const branch = parsed.branch ? ` (${parsed.branch})` : \"\";\n const outcome = parsed.outcome ? ` → ${parsed.outcome}` : \"\";\n const duration = parsed.duration_s ? ` ${parsed.duration_s}s` : \"\";\n return {\n sessionId,\n eventType: `gstack.timeline.${event}`,\n kind: \"system\",\n timestamp,\n message: toMessage(`${skill} ${event}${branch}${outcome}${duration}`),\n raw: parsed,\n };\n }\n\n // code review records\n if (fileType === \"review\") {\n const skill = parsed.skill ?? \"review\";\n const score = parsed.overall_score != null ? ` score=${parsed.overall_score}` : \"\";\n const status = parsed.status ? ` [${parsed.status}]` : \"\";\n return {\n sessionId,\n eventType: \"gstack.review\",\n kind: \"system\",\n timestamp,\n message: toMessage(`${skill}${status}${score}`),\n raw: parsed,\n };\n }\n\n // external resources shown during sessions\n if (fileType === \"resource\") {\n const title = normalizeWhitespace(parsed.title);\n const url = parsed.url ?? \"\";\n if (!title && !url) return null;\n return {\n sessionId,\n eventType: \"gstack.resource\",\n kind: \"system\",\n timestamp,\n message: toMessage(title ? `${title} — ${url}` : url),\n raw: parsed,\n };\n }\n\n return null;\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\n\nimport { asIso, coerceMessageText, expandHome, firstMessageTimestamp, normalizeRole } from \"../utils.mjs\";\n\n// validate UUID format\nfunction isUuid(value) {\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(\n String(value ?? \"\").trim()\n );\n}\n\n// ensure we have a valid UUID, generate one if not\nfunction normalizeSessionUuid(raw) {\n const value = String(raw ?? \"\").trim();\n if (isUuid(value)) return value;\n return randomUUID();\n}\n\n// build Claude Code project directory name from cwd\nfunction claudeProjectDirName(cwd) {\n const resolved = path.resolve(String(cwd || process.cwd()));\n return resolved.replace(/[\\\\/]/g, \"-\").replace(/[^A-Za-z0-9._-]/g, \"-\");\n}\n\n// compute session file path under ~/.claude/projects/<project>/\nfunction claudeSessionFilePath(sessionId, cwd, baseDir) {\n const root = baseDir || expandHome(\"~/.claude/projects\");\n return path.join(root, claudeProjectDirName(cwd), `${sessionId}.jsonl`);\n}\n\n// check if a Claude Code session already exists locally\nexport async function hasLocalClaudeSession(sessionId, cwd = \"\", baseDir) {\n const id = String(sessionId ?? \"\").trim();\n if (!id) return false;\n\n // check preferred path first\n const preferredPath = claudeSessionFilePath(id, cwd || process.cwd(), baseDir);\n try {\n const stat = await fs.stat(preferredPath);\n if (stat.isFile()) return true;\n } catch {\n // fall through to glob\n }\n\n // dynamic import to avoid bundling fast-glob as hard dep\n const fg = (await import(\"fast-glob\")).default;\n const root = baseDir || expandHome(\"~/.claude/projects\");\n const pattern = path.join(root, `**/*${id}.jsonl`);\n const files = await fg([pattern], {\n onlyFiles: true,\n absolute: true,\n unique: true,\n suppressErrors: true,\n followSymbolicLinks: false,\n });\n return files.some((filePath) => path.basename(filePath, \".jsonl\") === id);\n}\n\n// write a Claude Code-native JSONL session file from UltraContext messages\nexport async function writeClaudeSession({ sessionId, cwd, messages, baseDir }) {\n const runCwd = String(cwd || process.cwd());\n const resolvedSessionId = normalizeSessionUuid(sessionId);\n const firstTs = asIso(firstMessageTimestamp(messages));\n const filePath = claudeSessionFilePath(resolvedSessionId, runCwd, baseDir);\n\n if (await hasLocalClaudeSession(resolvedSessionId, runCwd, baseDir)) {\n return {\n written: false,\n reason: \"already_exists\",\n filePath,\n sessionId: resolvedSessionId,\n };\n }\n\n try {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n\n // build linked-list of message entries\n const lines = [];\n let parentUuid = null;\n for (let i = 0; i < (messages?.length ?? 0); i += 1) {\n const message = messages[i];\n const normalizedRole = normalizeRole(message?.role);\n const role = normalizedRole === \"assistant\" ? \"assistant\" : normalizedRole === \"user\" ? \"user\" : \"assistant\";\n const rawText = coerceMessageText(message).trim();\n if (!rawText) continue;\n const text = normalizedRole === \"system\" ? `[system] ${rawText}` : rawText;\n const ts = asIso(\n message?.content?.timestamp ??\n message?.metadata?.timestamp ??\n new Date(new Date(firstTs).getTime() + i * 1000).toISOString()\n );\n const entryUuid = randomUUID();\n lines.push(\n JSON.stringify({\n parentUuid,\n isSidechain: false,\n userType: \"external\",\n cwd: runCwd,\n sessionId: resolvedSessionId,\n version: \"adapter\",\n gitBranch: \"\",\n type: role,\n message: { role, content: text },\n timestamp: ts,\n uuid: entryUuid,\n })\n );\n parentUuid = entryUuid;\n }\n\n // fallback if no messages\n if (lines.length === 0) {\n const entryUuid = randomUUID();\n lines.push(\n JSON.stringify({\n parentUuid: null,\n isSidechain: false,\n userType: \"external\",\n cwd: runCwd,\n sessionId: resolvedSessionId,\n version: \"adapter\",\n gitBranch: \"\",\n type: \"assistant\",\n message: {\n role: \"assistant\",\n content: \"[system] Session restored from UltraContext with no user/assistant messages.\",\n },\n timestamp: new Date().toISOString(),\n uuid: entryUuid,\n })\n );\n }\n\n await fs.writeFile(filePath, `${lines.join(\"\\n\")}\\n`, \"utf8\");\n return {\n written: true,\n reason: \"created\",\n filePath,\n sessionId: resolvedSessionId,\n };\n } catch (error) {\n return {\n written: false,\n reason: \"write_failed\",\n filePath,\n sessionId: resolvedSessionId,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { asIso, coerceMessageText, expandHome, firstMessageTimestamp, normalizeRole } from \"../utils.mjs\";\n\n// build a single event_msg JSONL entry\nfunction buildEventMsgLine(message, fallbackTs) {\n const ts = asIso(message?.content?.timestamp ?? message?.metadata?.timestamp ?? fallbackTs);\n const role = normalizeRole(message?.role);\n const text = coerceMessageText(message).trim();\n if (!text) return null;\n\n if (role === \"user\") {\n return {\n timestamp: ts,\n type: \"event_msg\",\n payload: {\n type: \"user_message\",\n message: text,\n images: [],\n local_images: [],\n text_elements: [],\n },\n };\n }\n\n if (role === \"assistant\") {\n return {\n timestamp: ts,\n type: \"event_msg\",\n payload: { type: \"agent_message\", message: text },\n };\n }\n\n // system events\n return {\n timestamp: ts,\n type: \"event_msg\",\n payload: { type: \"agent_message\", message: `[system] ${text}` },\n };\n}\n\n// compute session file path under ~/.codex/sessions/YYYY/MM/DD/\nfunction sessionFilePath(sessionId, firstTimestamp, baseDir) {\n const iso = asIso(firstTimestamp);\n const [year, month, day] = iso.slice(0, 10).split(\"-\");\n const stamp = iso.replace(/\\.\\d{3}Z$/, \"\").replace(/:/g, \"-\").replace(\"Z\", \"\");\n const root = baseDir || expandHome(\"~/.codex/sessions\");\n const fileName = `rollout-${stamp}-${sessionId}.jsonl`;\n return path.join(root, year, month, day, fileName);\n}\n\n// check if a Codex session already exists locally\nexport async function hasLocalCodexSession(sessionId, baseDir) {\n const id = String(sessionId ?? \"\").trim();\n if (!id) return false;\n\n // dynamic import to avoid bundling fast-glob as hard dep\n const fg = (await import(\"fast-glob\")).default;\n const root = baseDir || expandHome(\"~/.codex/sessions\");\n const pattern = path.join(root, `**/*${id}*.jsonl`);\n const files = await fg([pattern], {\n onlyFiles: true,\n absolute: true,\n unique: true,\n suppressErrors: true,\n followSymbolicLinks: false,\n });\n return files.some((filePath) => filePath.includes(id));\n}\n\n// write a Codex-native JSONL session file from UltraContext messages\nexport async function writeCodexSession({ sessionId, cwd, messages, baseDir }) {\n const id = String(sessionId ?? \"\").trim();\n if (!id) return { written: false, reason: \"missing_session_id\", filePath: \"\" };\n\n if (await hasLocalCodexSession(id, baseDir)) {\n return { written: false, reason: \"already_exists\", filePath: \"\" };\n }\n\n const firstMessageTs = firstMessageTimestamp(messages);\n const firstTs = asIso(firstMessageTs);\n const filePath = sessionFilePath(id, firstTs, baseDir);\n\n try {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n\n // session_meta header\n const lines = [];\n lines.push(\n JSON.stringify({\n timestamp: firstTs,\n type: \"session_meta\",\n payload: {\n id,\n timestamp: firstTs,\n cwd: cwd || process.cwd(),\n originator: \"ultracontext_daemon\",\n cli_version: \"restored\",\n source: \"cli\",\n model_provider: \"openai\",\n },\n })\n );\n\n // event messages\n let emitted = 0;\n for (let i = 0; i < (messages?.length ?? 0); i += 1) {\n const fallbackTs = new Date(new Date(firstTs).getTime() + i * 1000).toISOString();\n const line = buildEventMsgLine(messages[i], fallbackTs);\n if (!line) continue;\n lines.push(JSON.stringify(line));\n emitted += 1;\n }\n\n // fallback if no messages\n if (emitted === 0) {\n lines.push(\n JSON.stringify({\n timestamp: new Date().toISOString(),\n type: \"event_msg\",\n payload: {\n type: \"agent_message\",\n message: \"[system] Session restored from UltraContext with no user/assistant messages.\",\n },\n })\n );\n }\n\n await fs.writeFile(filePath, `${lines.join(\"\\n\")}\\n`, \"utf8\");\n return { written: true, reason: \"created\", filePath };\n } catch (error) {\n return {\n written: false,\n reason: \"write_failed\",\n filePath,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { a as UC_CLAUDE_ORANGE, c as heroArtForWidth, i as UC_BRAND_BLUE, n as MENU_TABS, o as UC_CODEX_BLUE, r as UC_BLUE_LIGHT, s as UC_OPENCLAW_RED, t as Spinner } from "./Spinner-C_38udz8.mjs";
2
- import { a as parseDaemonWsMessage, c as resolveDaemonWsInfoFile, f as expandHome, i as normalizeBootstrapMode, s as resolveDaemonWsHost, t as DAEMON_WS_MESSAGE_TYPES } from "./src-B9CWO5Xk.mjs";
3
- import { i as writeClaudeSession, n as writeCodexSession, r as hasLocalClaudeSession, t as hasLocalCodexSession } from "./src-B7VNX8_g.mjs";
2
+ import { a as parseDaemonWsMessage, c as resolveDaemonWsInfoFile, f as expandHome, i as normalizeBootstrapMode, s as resolveDaemonWsHost, t as DAEMON_WS_MESSAGE_TYPES } from "./src-BSCJv6SU.mjs";
3
+ import { i as writeClaudeSession, n as writeCodexSession, r as hasLocalClaudeSession, t as hasLocalCodexSession } from "./src-DzUz8GPJ.mjs";
4
4
  import process$1 from "node:process";
5
5
  import { fileURLToPath } from "node:url";
6
6
  import path from "node:path";
@@ -963,7 +963,7 @@ function HeaderPanel({ snapshot, stdoutColumns }) {
963
963
  }, []);
964
964
  const health = snapshot.stats.errors > 0 ? "DEGRADED" : "HEALTHY";
965
965
  const healthColor = health === "HEALTHY" ? "green" : "yellow";
966
- const tagline = "The Context Hub for AI Agents";
966
+ const tagline = "Same context, everywhere";
967
967
  const innerWidth = Math.max(stdoutColumns, 40);
968
968
  const spinnerVisualWidth = 28;
969
969
  const gap = innerWidth >= 96 ? 3 : 2;
@@ -3423,4 +3423,4 @@ async function tuiBoot({ assetsRoot, offlineNotice, onFatalError } = {}) {
3423
3423
 
3424
3424
  //#endregion
3425
3425
  export { tuiBoot };
3426
- //# sourceMappingURL=tui-BmUdW0Nf.mjs.map
3426
+ //# sourceMappingURL=tui-C3H6iRjz.mjs.map