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.
- package/dist/cli/entry.mjs +3 -3
- package/dist/cli/sdk-daemon.mjs +11 -314
- package/dist/cli/sdk-daemon.mjs.map +1 -1
- package/dist/{ctl-9dwvaRrC.mjs → ctl-BVPu-D57.mjs} +3 -3
- package/dist/{ctl-9dwvaRrC.mjs.map → ctl-BVPu-D57.mjs.map} +1 -1
- package/dist/{launcher-DXUM0K-z.mjs → launcher-BFPi7_wD.mjs} +3 -3
- package/dist/{launcher-DXUM0K-z.mjs.map → launcher-BFPi7_wD.mjs.map} +1 -1
- package/dist/{lock-Q6z0l6Mr.mjs → lock-CQ3xrIlj.mjs} +3 -26
- package/dist/lock-CQ3xrIlj.mjs.map +1 -0
- package/dist/src-BSCJv6SU.mjs +151 -0
- package/dist/src-BSCJv6SU.mjs.map +1 -0
- package/dist/src-DzUz8GPJ.mjs +921 -0
- package/dist/src-DzUz8GPJ.mjs.map +1 -0
- package/dist/{tui-DNqvslCq.mjs → tui-C3H6iRjz.mjs} +31 -292
- package/dist/tui-C3H6iRjz.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/lock-Q6z0l6Mr.mjs.map +0 -1
- package/dist/src-Xh68VkBy.mjs +0 -83
- package/dist/src-Xh68VkBy.mjs.map +0 -1
- package/dist/tui-DNqvslCq.mjs.map +0 -1
package/dist/cli/entry.mjs
CHANGED
|
@@ -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-
|
|
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-
|
|
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-
|
|
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"
|
package/dist/cli/sdk-daemon.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
import { a as
|
|
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
|
|
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,
|