ultracontext 1.3.0 → 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.
@@ -313,18 +313,18 @@ async function checkForUpdate() {
313
313
  if (latest && isNewer(latest, current)) printUpdateNotice(current, latest);
314
314
  }
315
315
  async function launchDaemonSDK() {
316
- const { launchDaemon } = await import("../launcher-DXUM0K-z.mjs");
316
+ const { launchDaemon } = await import("../launcher-BFPi7_wD.mjs");
317
317
  await launchDaemon({
318
318
  entryPath: fileURLToPath(new URL("./sdk-daemon.mjs", import.meta.url)),
319
319
  diagnosticsHint: "DAEMON_VERBOSE=1 ultracontext start"
320
320
  });
321
321
  }
322
322
  async function runCtlSDK() {
323
- const { runCtl } = await import("../ctl-9dwvaRrC.mjs");
323
+ const { runCtl } = await import("../ctl-BVPu-D57.mjs");
324
324
  await runCtl();
325
325
  }
326
326
  async function launchTuiSDK() {
327
- const { tuiBoot } = await import("../tui-DNqvslCq.mjs");
327
+ const { tuiBoot } = await import("../tui-C3H6iRjz.mjs");
328
328
  await tuiBoot({
329
329
  assetsRoot: path.resolve(__dirname, "..", ".."),
330
330
  offlineNotice: "Daemon offline. Run: ultracontext start"
@@ -1,5 +1,6 @@
1
- import { a as extractProjectPathFromFile, c as sha256, i as expandHome, l as toInt, n as resolveLockPath, o as extractSessionIdFromPath, r as boolFromEnv, s as safeJsonParse, t as acquireFileLock, u as truncateString } from "../lock-Q6z0l6Mr.mjs";
2
- import { a as parseDaemonWsMessage, c as resolveDaemonWsInfoFile, i as normalizeBootstrapMode, l as resolveDaemonWsPort, n as buildDaemonWsMessage, o as parseProtocolJson, r as createBootstrapStateKey, s as resolveDaemonWsHost, t as DAEMON_WS_MESSAGE_TYPES } from "../src-Xh68VkBy.mjs";
1
+ import { a as parseDaemonWsMessage, b as truncateString, c as resolveDaemonWsInfoFile, f as expandHome, i as normalizeBootstrapMode, l as resolveDaemonWsPort, n as buildDaemonWsMessage, o as parseProtocolJson, r as createBootstrapStateKey, s as resolveDaemonWsHost, t as DAEMON_WS_MESSAGE_TYPES } from "../src-BSCJv6SU.mjs";
2
+ import { a as sha256, i as extractProjectPathFromFile, n as resolveLockPath, o as toInt, r as boolFromEnv, t as acquireFileLock } from "../lock-CQ3xrIlj.mjs";
3
+ import { a as parseGstackLine, c as parseClaudeCodeLine, o as parseOpenClawLine, s as parseCodexLine } from "../src-DzUz8GPJ.mjs";
3
4
  import process$1 from "node:process";
4
5
  import path from "node:path";
5
6
  import fs from "node:fs";
@@ -243,317 +244,6 @@ function redact(value, currentKey = "") {
243
244
  return REDACTED;
244
245
  }
245
246
 
246
- //#endregion
247
- //#region ../daemon/src/sources.mjs
248
- function normalizeKind(kind, fallback = "system") {
249
- const lowered = String(kind ?? "").toLowerCase();
250
- if (["user", "human"].includes(lowered)) return "user";
251
- if ([
252
- "assistant",
253
- "agent",
254
- "ai"
255
- ].includes(lowered)) return "assistant";
256
- return fallback;
257
- }
258
- function toMessage(raw, maxLen = 12e3) {
259
- if (!raw) return "";
260
- if (typeof raw === "string") return truncateString(raw, maxLen);
261
- if (typeof raw === "object") return truncateString(JSON.stringify(raw), maxLen);
262
- return truncateString(String(raw), maxLen);
263
- }
264
- function normalizeWhitespace(value) {
265
- return String(value ?? "").replace(/\s+/g, " ").trim();
266
- }
267
- function preserveText(value) {
268
- return String(value ?? "").split("\n").map((l) => l.trimEnd()).join("\n").replace(/\n{3,}/g, "\n\n").trim();
269
- }
270
- function formatToolUse(item) {
271
- const name = (item.name ?? "unknown").toLowerCase();
272
- const input = item.input ?? {};
273
- const filePath = input.file_path ?? input.path ?? "";
274
- if (name === "write") return `[Write] ${filePath}\n${preserveText(input.content ?? input.file_text ?? "")}`;
275
- if (name === "edit") {
276
- const parts = [`[Edit] ${filePath}`];
277
- if (input.old_string) parts.push(`- ${preserveText(input.old_string)}`);
278
- if (input.new_string) parts.push(`+ ${preserveText(input.new_string)}`);
279
- return parts.join("\n");
280
- }
281
- if (name === "read") return `[Read] ${filePath}`;
282
- if (name === "bash") return `[Bash] ${preserveText(input.command ?? "")}`;
283
- if (name === "grep" || name === "glob") {
284
- const loc = filePath ? ` in ${filePath}` : "";
285
- return `[${item.name}] ${input.pattern ?? ""}${loc}`;
286
- }
287
- const compact = JSON.stringify(input);
288
- return `[${item.name ?? name}] ${compact.length > 500 ? compact.slice(0, 500) + "..." : compact}`;
289
- }
290
- function formatToolResult(item) {
291
- const content = item.content ?? "";
292
- if (typeof content === "string") {
293
- const text = preserveText(content);
294
- return text ? `[result] ${truncateString(text, 1e3)}` : "[result] ok";
295
- }
296
- if (Array.isArray(content)) {
297
- const text = content.filter((c) => c?.type === "text" && typeof c.text === "string").map((c) => preserveText(c.text)).filter(Boolean).join("\n");
298
- return text ? `[result] ${truncateString(text, 1e3)}` : "[result] ok";
299
- }
300
- return "[result] ok";
301
- }
302
- function extractClaudeTextContent(content) {
303
- if (!content) return "";
304
- if (typeof content === "string") return preserveText(content);
305
- if (Array.isArray(content)) {
306
- const parts = [];
307
- for (const item of content) {
308
- if (!item || typeof item !== "object") continue;
309
- if (item.type === "text" && typeof item.text === "string") {
310
- const chunk = preserveText(item.text);
311
- if (chunk) parts.push(chunk);
312
- }
313
- if (item.type === "tool_use") parts.push(formatToolUse(item));
314
- if (item.type === "tool_result") parts.push(formatToolResult(item));
315
- }
316
- return parts.join("\n\n");
317
- }
318
- if (typeof content === "object") {
319
- if (typeof content.text === "string") return preserveText(content.text);
320
- if (typeof content.content === "string") return preserveText(content.content);
321
- }
322
- return "";
323
- }
324
- function extractOpenClawTextContent(content) {
325
- if (!content) return "";
326
- if (typeof content === "string") return normalizeWhitespace(content);
327
- if (Array.isArray(content)) {
328
- const textParts = [];
329
- for (const item of content) {
330
- if (!item || typeof item !== "object") continue;
331
- if (item.type === "text" && typeof item.text === "string") {
332
- const chunk = normalizeWhitespace(item.text);
333
- if (chunk) textParts.push(chunk);
334
- }
335
- }
336
- return textParts.join("\n");
337
- }
338
- if (typeof content === "object" && typeof content.text === "string") return normalizeWhitespace(content.text);
339
- return "";
340
- }
341
- function extractOpenClawToolCalls(content) {
342
- if (!Array.isArray(content)) return [];
343
- const names = [];
344
- for (const item of content) {
345
- if (!item || typeof item !== "object" || item.type !== "toolCall") continue;
346
- const name = normalizeWhitespace(item.name);
347
- if (name) names.push(name);
348
- }
349
- return names;
350
- }
351
- function buildOpenClawRaw(parsed) {
352
- const raw = {
353
- type: parsed.type,
354
- id: parsed.id,
355
- parentId: parsed.parentId,
356
- timestamp: parsed.timestamp
357
- };
358
- if (parsed.type === "session") {
359
- raw.session = {
360
- id: parsed.id,
361
- version: parsed.version,
362
- cwd: parsed.cwd,
363
- parentSession: parsed.parentSession
364
- };
365
- return raw;
366
- }
367
- if (parsed.type === "custom") {
368
- raw.customType = parsed.customType;
369
- if (parsed.customType === "model-snapshot" && parsed.data && typeof parsed.data === "object") raw.data = {
370
- provider: parsed.data.provider,
371
- modelApi: parsed.data.modelApi,
372
- modelId: parsed.data.modelId,
373
- timestamp: parsed.data.timestamp
374
- };
375
- return raw;
376
- }
377
- if (parsed.message && typeof parsed.message === "object") {
378
- const contentTypes = Array.isArray(parsed.message.content) ? parsed.message.content.filter((item) => item && typeof item === "object").map((item) => String(item.type ?? "unknown")).slice(0, 12) : [];
379
- raw.message = {
380
- role: parsed.message.role,
381
- stopReason: parsed.message.stopReason,
382
- toolName: parsed.message.toolName,
383
- toolCallId: parsed.message.toolCallId,
384
- isError: parsed.message.isError,
385
- contentTypes
386
- };
387
- }
388
- if (parsed.type === "compaction") raw.compaction = {
389
- firstKeptEntryId: parsed.firstKeptEntryId,
390
- tokensBefore: parsed.tokensBefore
391
- };
392
- else if (parsed.type === "branch_summary") raw.branchSummary = {
393
- firstKeptEntryId: parsed.firstKeptEntryId,
394
- summary: typeof parsed.summary === "string" ? truncateString(parsed.summary, 350) : ""
395
- };
396
- return raw;
397
- }
398
- function parseCodexLine({ line, filePath }) {
399
- const parsed = safeJsonParse(line);
400
- if (!parsed || typeof parsed !== "object") return null;
401
- const payload = parsed.payload ?? {};
402
- const sessionId = payload.session_id ?? payload.id ?? parsed.session_id ?? extractSessionIdFromPath(filePath);
403
- if (parsed.type === "event_msg") {
404
- const eventType = payload.type ?? "unknown";
405
- if (![
406
- "user_message",
407
- "agent_message",
408
- "task_started",
409
- "task_complete"
410
- ].includes(eventType)) return null;
411
- const kind = eventType === "user_message" ? "user" : eventType === "agent_message" ? "assistant" : "system";
412
- const message = payload.message ?? payload.last_agent_message ?? `${eventType}${payload.turn_id ? ` (${payload.turn_id})` : ""}`;
413
- return {
414
- sessionId,
415
- eventType: `event_msg.${eventType}`,
416
- kind,
417
- timestamp: parsed.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
418
- message: toMessage(message),
419
- raw: parsed
420
- };
421
- }
422
- if (parsed.type === "session_meta") return {
423
- sessionId,
424
- eventType: "session_meta",
425
- kind: "system",
426
- timestamp: parsed.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
427
- message: `Session started in ${payload.cwd ?? "unknown cwd"}`,
428
- raw: parsed
429
- };
430
- return null;
431
- }
432
- function parseClaudeCodeLine({ line, filePath }) {
433
- const parsed = safeJsonParse(line);
434
- if (!parsed || typeof parsed !== "object") return null;
435
- const type = String(parsed.type ?? "").toLowerCase();
436
- const sessionId = parsed.sessionId ?? parsed.session_id ?? parsed.payload?.sessionId ?? parsed.payload?.session_id ?? extractSessionIdFromPath(filePath);
437
- const timestamp = parsed.timestamp ?? parsed.ts ?? (/* @__PURE__ */ new Date()).toISOString();
438
- if (type === "summary") {
439
- const summary = normalizeWhitespace(parsed.summary);
440
- if (!summary) return null;
441
- return {
442
- sessionId,
443
- eventType: "claude.summary",
444
- kind: "system",
445
- timestamp,
446
- message: toMessage(summary),
447
- raw: parsed
448
- };
449
- }
450
- if (type !== "user" && type !== "assistant") return null;
451
- const message = extractClaudeTextContent(parsed.message?.content ?? parsed.message ?? parsed.content ?? parsed.payload?.content ?? "");
452
- if (!message) return null;
453
- const roleHint = parsed.message?.role ?? type;
454
- return {
455
- sessionId,
456
- eventType: `claude.${type}`,
457
- kind: normalizeKind(roleHint, type === "user" ? "user" : "assistant"),
458
- timestamp,
459
- message: toMessage(message),
460
- raw: parsed
461
- };
462
- }
463
- function parseOpenClawLine({ line, filePath }) {
464
- const parsed = safeJsonParse(line);
465
- if (!parsed || typeof parsed !== "object") return null;
466
- const type = String(parsed.type ?? "").toLowerCase();
467
- const sessionId = parsed.session_id ?? parsed.sessionId ?? parsed.message?.session_id ?? parsed.message?.sessionId ?? extractSessionIdFromPath(filePath);
468
- const timestamp = parsed.timestamp ?? parsed.message?.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
469
- if (type === "session") return {
470
- sessionId,
471
- eventType: "openclaw.session",
472
- kind: "system",
473
- timestamp,
474
- message: toMessage(`Session started in ${parsed.cwd ?? "unknown cwd"}`),
475
- raw: buildOpenClawRaw(parsed)
476
- };
477
- if (type === "custom") {
478
- const customType = normalizeWhitespace(parsed.customType || "custom");
479
- if (customType === "openclaw.cache-ttl") return null;
480
- let message = `Custom event: ${customType}`;
481
- if (customType === "model-snapshot" && parsed.data && typeof parsed.data === "object") {
482
- const provider = normalizeWhitespace(parsed.data.provider || "");
483
- const modelId = normalizeWhitespace(parsed.data.modelId || "");
484
- const modelApi = normalizeWhitespace(parsed.data.modelApi || "");
485
- const details = [provider, modelId].filter(Boolean).join("/");
486
- message = `Model snapshot${details ? `: ${details}` : ""}${modelApi ? ` (${modelApi})` : ""}`;
487
- }
488
- return {
489
- sessionId,
490
- eventType: `openclaw.custom.${customType || "custom"}`,
491
- kind: "system",
492
- timestamp,
493
- message: toMessage(message),
494
- raw: buildOpenClawRaw(parsed)
495
- };
496
- }
497
- if (type === "compaction") return {
498
- sessionId,
499
- eventType: "openclaw.compaction",
500
- kind: "system",
501
- timestamp,
502
- message: toMessage("Session compaction summary updated"),
503
- raw: buildOpenClawRaw(parsed)
504
- };
505
- if (type === "branch_summary") return {
506
- sessionId,
507
- eventType: "openclaw.branch_summary",
508
- kind: "system",
509
- timestamp,
510
- message: toMessage(normalizeWhitespace(parsed.summary || "") || "Branch summary updated"),
511
- raw: buildOpenClawRaw(parsed)
512
- };
513
- if (type !== "message" && type !== "custom_message") return null;
514
- const eventMessage = parsed.message ?? {};
515
- const role = String(eventMessage.role ?? "").toLowerCase();
516
- if (role === "user" || role === "assistant") {
517
- const text = extractOpenClawTextContent(eventMessage.content);
518
- if (text) return {
519
- sessionId,
520
- eventType: `openclaw.${role}`,
521
- kind: role === "user" ? "user" : "assistant",
522
- timestamp,
523
- message: toMessage(text),
524
- raw: buildOpenClawRaw(parsed)
525
- };
526
- if (role === "assistant") {
527
- const toolCalls = extractOpenClawToolCalls(eventMessage.content);
528
- if (toolCalls.length > 0) return {
529
- sessionId,
530
- eventType: "openclaw.assistant.tool_use",
531
- kind: "system",
532
- timestamp,
533
- message: toMessage(`Assistant requested tools: ${toolCalls.slice(0, 5).join(", ")}${toolCalls.length > 5 ? ` (+${toolCalls.length - 5})` : ""}`),
534
- raw: buildOpenClawRaw(parsed)
535
- };
536
- }
537
- return null;
538
- }
539
- if (role === "toolresult") {
540
- const toolName = normalizeWhitespace(eventMessage.toolName || "");
541
- const isError = Boolean(eventMessage.isError);
542
- let message = `Tool result${toolName ? `: ${toolName}` : ""} (${isError ? "error" : "ok"})`;
543
- const text = extractOpenClawTextContent(eventMessage.content);
544
- if (text) message = `${message} ${truncateString(text, 320)}`;
545
- return {
546
- sessionId,
547
- eventType: "openclaw.tool_result",
548
- kind: "system",
549
- timestamp,
550
- message: toMessage(message),
551
- raw: buildOpenClawRaw(parsed)
552
- };
553
- }
554
- return null;
555
- }
556
-
557
247
  //#endregion
558
248
  //#region ../daemon/src/ws-server.mjs
559
249
  function safeParseMessage(raw) {
@@ -1192,6 +882,13 @@ async function daemonBoot({ createStore, resolveDbPath }) {
1192
882
  globs: [openclawGlob],
1193
883
  parseLine: parseOpenClawLine
1194
884
  });
885
+ const gstackGlob = expandHome(process$1.env.GSTACK_GLOB ?? "~/.gstack/projects/**/*.jsonl");
886
+ if (boolFromEnv(process$1.env.INGEST_GSTACK, true)) sources.push({
887
+ name: "gstack",
888
+ enabled: true,
889
+ globs: [gstackGlob],
890
+ parseLine: parseGstackLine
891
+ });
1195
892
  return sources;
1196
893
  }
1197
894
  async function listSourceFiles(source) {
@@ -1696,7 +1393,7 @@ async function daemonBoot({ createStore, resolveDbPath }) {
1696
1393
  log("warn", "Failed to load persisted config preferences", errorDetails(error));
1697
1394
  }
1698
1395
  const sources = buildSources();
1699
- if (sources.length === 0) throw new Error("No sources enabled. Set INGEST_CODEX=true and/or INGEST_CLAUDE=true");
1396
+ if (sources.length === 0) throw new Error("No sources enabled. Set INGEST_CODEX=true, INGEST_CLAUDE=true, and/or INGEST_GSTACK=true");
1700
1397
  applyRuntimeSources(sources);
1701
1398
  runtime.lockHandle = await acquireFileLock({
1702
1399
  lockPath: cfg.lockFile,