zelari-code 2.17.0 → 2.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands/inspectSession.js +86 -0
- package/dist/cli/commands/inspectSession.js.map +1 -0
- package/dist/cli/main.bundled.js +351 -187
- package/dist/cli/main.bundled.js.map +4 -4
- package/dist/cli/main.js +15 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/runHeadless.js +53 -0
- package/dist/cli/runHeadless.js.map +1 -1
- package/dist/cli/sessionSpine.js +15 -0
- package/dist/cli/sessionSpine.js.map +1 -1
- package/package.json +2 -2
package/dist/cli/main.bundled.js
CHANGED
|
@@ -3288,10 +3288,10 @@ function mergeDefs(...defs) {
|
|
|
3288
3288
|
function cloneDef(schema) {
|
|
3289
3289
|
return mergeDefs(schema._zod.def);
|
|
3290
3290
|
}
|
|
3291
|
-
function getElementAtPath(obj,
|
|
3292
|
-
if (!
|
|
3291
|
+
function getElementAtPath(obj, path91) {
|
|
3292
|
+
if (!path91)
|
|
3293
3293
|
return obj;
|
|
3294
|
-
return
|
|
3294
|
+
return path91.reduce((acc, key) => acc?.[key], obj);
|
|
3295
3295
|
}
|
|
3296
3296
|
function promiseAllObject(promisesObj) {
|
|
3297
3297
|
const keys = Object.keys(promisesObj);
|
|
@@ -3619,11 +3619,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
3619
3619
|
}
|
|
3620
3620
|
return false;
|
|
3621
3621
|
}
|
|
3622
|
-
function prefixIssues(
|
|
3622
|
+
function prefixIssues(path91, issues) {
|
|
3623
3623
|
return issues.map((iss) => {
|
|
3624
3624
|
var _a3;
|
|
3625
3625
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
3626
|
-
iss.path.unshift(
|
|
3626
|
+
iss.path.unshift(path91);
|
|
3627
3627
|
return iss;
|
|
3628
3628
|
});
|
|
3629
3629
|
}
|
|
@@ -3841,16 +3841,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
3841
3841
|
}
|
|
3842
3842
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
3843
3843
|
const fieldErrors = { _errors: [] };
|
|
3844
|
-
const processError = (error52,
|
|
3844
|
+
const processError = (error52, path91 = []) => {
|
|
3845
3845
|
for (const issue2 of error52.issues) {
|
|
3846
3846
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
3847
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
3847
|
+
issue2.errors.map((issues) => processError({ issues }, [...path91, ...issue2.path]));
|
|
3848
3848
|
} else if (issue2.code === "invalid_key") {
|
|
3849
|
-
processError({ issues: issue2.issues }, [...
|
|
3849
|
+
processError({ issues: issue2.issues }, [...path91, ...issue2.path]);
|
|
3850
3850
|
} else if (issue2.code === "invalid_element") {
|
|
3851
|
-
processError({ issues: issue2.issues }, [...
|
|
3851
|
+
processError({ issues: issue2.issues }, [...path91, ...issue2.path]);
|
|
3852
3852
|
} else {
|
|
3853
|
-
const fullpath = [...
|
|
3853
|
+
const fullpath = [...path91, ...issue2.path];
|
|
3854
3854
|
if (fullpath.length === 0) {
|
|
3855
3855
|
fieldErrors._errors.push(mapper(issue2));
|
|
3856
3856
|
} else {
|
|
@@ -3877,17 +3877,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
3877
3877
|
}
|
|
3878
3878
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
3879
3879
|
const result = { errors: [] };
|
|
3880
|
-
const processError = (error52,
|
|
3880
|
+
const processError = (error52, path91 = []) => {
|
|
3881
3881
|
var _a3, _b;
|
|
3882
3882
|
for (const issue2 of error52.issues) {
|
|
3883
3883
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
3884
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
3884
|
+
issue2.errors.map((issues) => processError({ issues }, [...path91, ...issue2.path]));
|
|
3885
3885
|
} else if (issue2.code === "invalid_key") {
|
|
3886
|
-
processError({ issues: issue2.issues }, [...
|
|
3886
|
+
processError({ issues: issue2.issues }, [...path91, ...issue2.path]);
|
|
3887
3887
|
} else if (issue2.code === "invalid_element") {
|
|
3888
|
-
processError({ issues: issue2.issues }, [...
|
|
3888
|
+
processError({ issues: issue2.issues }, [...path91, ...issue2.path]);
|
|
3889
3889
|
} else {
|
|
3890
|
-
const fullpath = [...
|
|
3890
|
+
const fullpath = [...path91, ...issue2.path];
|
|
3891
3891
|
if (fullpath.length === 0) {
|
|
3892
3892
|
result.errors.push(mapper(issue2));
|
|
3893
3893
|
continue;
|
|
@@ -3919,8 +3919,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
3919
3919
|
}
|
|
3920
3920
|
function toDotPath(_path) {
|
|
3921
3921
|
const segs = [];
|
|
3922
|
-
const
|
|
3923
|
-
for (const seg of
|
|
3922
|
+
const path91 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
3923
|
+
for (const seg of path91) {
|
|
3924
3924
|
if (typeof seg === "number")
|
|
3925
3925
|
segs.push(`[${seg}]`);
|
|
3926
3926
|
else if (typeof seg === "symbol")
|
|
@@ -17423,13 +17423,13 @@ function resolveRef(ref, ctx) {
|
|
|
17423
17423
|
if (!ref.startsWith("#")) {
|
|
17424
17424
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
17425
17425
|
}
|
|
17426
|
-
const
|
|
17427
|
-
if (
|
|
17426
|
+
const path91 = ref.slice(1).split("/").filter(Boolean);
|
|
17427
|
+
if (path91.length === 0) {
|
|
17428
17428
|
return ctx.rootSchema;
|
|
17429
17429
|
}
|
|
17430
17430
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
17431
|
-
if (
|
|
17432
|
-
const key =
|
|
17431
|
+
if (path91[0] === defsKey) {
|
|
17432
|
+
const key = path91[1];
|
|
17433
17433
|
if (!key || !ctx.defs[key]) {
|
|
17434
17434
|
throw new Error(`Reference not found: ${ref}`);
|
|
17435
17435
|
}
|
|
@@ -18777,11 +18777,18 @@ function filterByInclude(entries, include) {
|
|
|
18777
18777
|
if (include.length === 0 || include.length === 1 && include[0] === "*") {
|
|
18778
18778
|
return entries.filter((e) => e.type === "file");
|
|
18779
18779
|
}
|
|
18780
|
-
const
|
|
18780
|
+
const pathRegexes = [];
|
|
18781
|
+
const baseRegexes = [];
|
|
18782
|
+
for (const g of include) {
|
|
18783
|
+
(g.includes("/") || g.includes("**") ? pathRegexes : baseRegexes).push(globToRegex(g));
|
|
18784
|
+
}
|
|
18781
18785
|
return entries.filter((e) => {
|
|
18782
18786
|
if (e.type !== "file")
|
|
18783
18787
|
return false;
|
|
18784
|
-
|
|
18788
|
+
if (pathRegexes.some((re) => re.test(e.name)))
|
|
18789
|
+
return true;
|
|
18790
|
+
const base2 = e.name.slice(e.name.lastIndexOf("/") + 1);
|
|
18791
|
+
return baseRegexes.some((re) => re.test(base2));
|
|
18785
18792
|
});
|
|
18786
18793
|
}
|
|
18787
18794
|
var REGEX_ESCAPE, DEFAULT_EXCLUDES;
|
|
@@ -18828,8 +18835,8 @@ function coerceStringList(value, fallback) {
|
|
|
18828
18835
|
}
|
|
18829
18836
|
return fallback;
|
|
18830
18837
|
}
|
|
18831
|
-
function
|
|
18832
|
-
return include.some((g) => g.includes("**"));
|
|
18838
|
+
function hasPathAnchoredGlob(include) {
|
|
18839
|
+
return include.some((g) => g.includes("/") || g.includes("**"));
|
|
18833
18840
|
}
|
|
18834
18841
|
function scopeWarnings(allEntries, include, matched) {
|
|
18835
18842
|
const warnings = [];
|
|
@@ -18837,15 +18844,17 @@ function scopeWarnings(allEntries, include, matched) {
|
|
|
18837
18844
|
if (filesWalked === 0)
|
|
18838
18845
|
return warnings;
|
|
18839
18846
|
if (matched === 0) {
|
|
18840
|
-
|
|
18847
|
+
const cause = hasPathAnchoredGlob(include) ? `path-anchored globs (with '/') match the relative path at exactly that level; use '**/<glob>' for recursive matching` : `flat globs ('*.ts') match the basename at any depth, so no file with these names/extensions exists in the walked tree`;
|
|
18848
|
+
warnings.push(`SEARCH_EMPTY_SCOPE: include globs matched 0 of ${filesWalked} files walked \u2014 ${cause}. Do not interpret this result as "pattern not found".`);
|
|
18841
18849
|
return warnings;
|
|
18842
18850
|
}
|
|
18843
|
-
if (
|
|
18851
|
+
if (!hasPathAnchoredGlob(include) || matched >= filesWalked)
|
|
18844
18852
|
return warnings;
|
|
18845
|
-
const
|
|
18853
|
+
const anchored = include.filter((g) => g.includes("/") || g.includes("**"));
|
|
18854
|
+
const recursiveRegexes = compileGlobs(anchored.map((g) => `**/${g}`));
|
|
18846
18855
|
const wouldMatch = allEntries.filter((e) => e.type === "file" && matchesAnyCompiled(e.name, recursiveRegexes)).length;
|
|
18847
18856
|
if (wouldMatch > matched) {
|
|
18848
|
-
warnings.push(`include globs matched ${matched} of ${filesWalked} files walked \u2014 '
|
|
18857
|
+
warnings.push(`include globs matched ${matched} of ${filesWalked} files walked \u2014 a path-anchored glob ('${anchored[0]}') matches only that exact level; a '**/${anchored[0]}'-style recursive glob would have matched ${wouldMatch - matched} more file(s) in subdirectories`);
|
|
18849
18858
|
}
|
|
18850
18859
|
return warnings;
|
|
18851
18860
|
}
|
|
@@ -18912,7 +18921,10 @@ var init_search = __esm({
|
|
|
18912
18921
|
/**
|
|
18913
18922
|
* Glob pattern(s) to INCLUDE when path is a directory.
|
|
18914
18923
|
* Accepts a string OR string[] (models often emit a bare string).
|
|
18915
|
-
*
|
|
18924
|
+
* A glob without '/' (e.g. '*.ts') matches the file basename at any depth
|
|
18925
|
+
* (grep --include style); a glob with '/' (e.g. 'src/*.ts') matches the
|
|
18926
|
+
* relative path at exactly that level. Default ['*'] = all files.
|
|
18927
|
+
* Ignored when path is a file.
|
|
18916
18928
|
*/
|
|
18917
18929
|
include: stringOrStringArray.optional().default(["*"]),
|
|
18918
18930
|
/**
|
|
@@ -18925,7 +18937,7 @@ var init_search = __esm({
|
|
|
18925
18937
|
});
|
|
18926
18938
|
grepContentTool = {
|
|
18927
18939
|
name: "grep_content",
|
|
18928
|
-
description:
|
|
18940
|
+
description: `Regex search for content in a file OR recursively in a directory. When path is a directory, include/exclude globs filter which files are searched (default: all files, excluding node_modules/dist/.git/etc.). Glob semantics (grep --include style): a glob without '/' (e.g. "*.md") matches the file basename at ANY depth; a glob with '/' (e.g. "src/*.ts") matches the relative path at exactly that level; "**" is explicit recursion ("**/*.ts" matches at any depth, same as the bare form). include/exclude accept a single glob string (e.g. "*.ts") OR an array of globs. Returns matches with line numbers and context, plus filesWalked/filesInTree counts and a warning when the include globs matched suspiciously few files.`,
|
|
18929
18941
|
permissions: ["read"],
|
|
18930
18942
|
sideEffect: "none",
|
|
18931
18943
|
timeoutMs: 3e4,
|
|
@@ -19875,11 +19887,11 @@ var init_tools = __esm({
|
|
|
19875
19887
|
if (!ctx.addDocument)
|
|
19876
19888
|
return "Knowledge vault tool not available.";
|
|
19877
19889
|
const title = args["title"] || "New Document";
|
|
19878
|
-
const
|
|
19890
|
+
const path91 = args["path"] || `notes/${title.toLowerCase().replace(/[^a-z0-9]+/g, "-")}`;
|
|
19879
19891
|
const content = args["content"] || "";
|
|
19880
19892
|
const tags = args["tags"] || [];
|
|
19881
19893
|
ctx.addDocument({
|
|
19882
|
-
path:
|
|
19894
|
+
path: path91,
|
|
19883
19895
|
title,
|
|
19884
19896
|
content,
|
|
19885
19897
|
format: "markdown",
|
|
@@ -19888,7 +19900,7 @@ var init_tools = __esm({
|
|
|
19888
19900
|
workspaceId: ctx.workspaceId
|
|
19889
19901
|
});
|
|
19890
19902
|
ctx.addActivity("vault", "created document", title);
|
|
19891
|
-
return `Document "${title}" created at "${
|
|
19903
|
+
return `Document "${title}" created at "${path91}".`;
|
|
19892
19904
|
}
|
|
19893
19905
|
}
|
|
19894
19906
|
];
|
|
@@ -23328,7 +23340,7 @@ function extractToolObjects(text) {
|
|
|
23328
23340
|
}
|
|
23329
23341
|
return out;
|
|
23330
23342
|
}
|
|
23331
|
-
var BUILD_LIVENESS_RECOVERY_PROMPT, AgentHarness, DOOM_LOOP_THRESHOLD;
|
|
23343
|
+
var TOOL_CALL_TRUNCATED_RECOVERY_MARKER, TOOL_CALL_TRUNCATED_RECOVERY_USER, BUILD_LIVENESS_RECOVERY_PROMPT, AgentHarness, DOOM_LOOP_THRESHOLD;
|
|
23332
23344
|
var init_AgentHarness = __esm({
|
|
23333
23345
|
"packages/core/dist/core/AgentHarness.js"() {
|
|
23334
23346
|
"use strict";
|
|
@@ -23340,6 +23352,8 @@ var init_AgentHarness = __esm({
|
|
|
23340
23352
|
init_textLoopDetect();
|
|
23341
23353
|
init_ObserverBus();
|
|
23342
23354
|
init_textLoopDetect();
|
|
23355
|
+
TOOL_CALL_TRUNCATED_RECOVERY_MARKER = "[harness] Previous tool call was truncated";
|
|
23356
|
+
TOOL_CALL_TRUNCATED_RECOVERY_USER = `${TOOL_CALL_TRUNCATED_RECOVERY_MARKER} by the provider before completion (finish_reason=tool_calls but no complete tool_call arrived). Retry with a shorter payload or split the work into smaller tool calls.`;
|
|
23343
23357
|
BUILD_LIVENESS_RECOVERY_PROMPT = "[build-liveness] The requested task requires an on-disk implementation, but no successful project mutation has occurred yet. Continue working. Inspect only as needed, then make the required change with an available mutating tool. Do not merely describe a patch or claim completion.";
|
|
23344
23358
|
AgentHarness = class {
|
|
23345
23359
|
config;
|
|
@@ -24343,7 +24357,8 @@ ${cached2}`
|
|
|
24343
24357
|
if (turnToolResults.length > 0) {
|
|
24344
24358
|
finishRef.value = "tool_calls";
|
|
24345
24359
|
}
|
|
24346
|
-
|
|
24360
|
+
const truncatedToolCall = finishRef.value === "tool_calls" && turnToolCalls.length === 0 && turnToolResults.length === 0;
|
|
24361
|
+
if (truncatedToolCall) {
|
|
24347
24362
|
const truncErr = createBrainEvent("error", this.sessionId, {
|
|
24348
24363
|
severity: "recoverable",
|
|
24349
24364
|
message: "Tool call was truncated (finish_reason=tool_calls but no complete tool_call received). The provider cut the response mid-arguments. Retry with a shorter payload or split the work.",
|
|
@@ -24383,6 +24398,15 @@ ${cached2}`
|
|
|
24383
24398
|
content: tr.content
|
|
24384
24399
|
});
|
|
24385
24400
|
}
|
|
24401
|
+
if (truncatedToolCall) {
|
|
24402
|
+
const last = this.config.messages[this.config.messages.length - 1];
|
|
24403
|
+
if (!(last?.role === "user" && typeof last.content === "string" && last.content.includes(TOOL_CALL_TRUNCATED_RECOVERY_MARKER))) {
|
|
24404
|
+
this.config.messages.push({
|
|
24405
|
+
role: "user",
|
|
24406
|
+
content: TOOL_CALL_TRUNCATED_RECOVERY_USER
|
|
24407
|
+
});
|
|
24408
|
+
}
|
|
24409
|
+
}
|
|
24386
24410
|
break;
|
|
24387
24411
|
} else if (delta.kind === "error") {
|
|
24388
24412
|
finishRef.providerError = true;
|
|
@@ -25317,6 +25341,8 @@ __export(harness_exports, {
|
|
|
25317
25341
|
SessionJsonlWriter: () => SessionJsonlWriter,
|
|
25318
25342
|
TEXT_LOOP_RECOVERY_SYSTEM: () => TEXT_LOOP_RECOVERY_SYSTEM,
|
|
25319
25343
|
TEXT_LOOP_RECOVERY_USER_PROMPT: () => TEXT_LOOP_RECOVERY_USER_PROMPT,
|
|
25344
|
+
TOOL_CALL_TRUNCATED_RECOVERY_MARKER: () => TOOL_CALL_TRUNCATED_RECOVERY_MARKER,
|
|
25345
|
+
TOOL_CALL_TRUNCATED_RECOVERY_USER: () => TOOL_CALL_TRUNCATED_RECOVERY_USER,
|
|
25320
25346
|
canonicalTools: () => canonicalTools,
|
|
25321
25347
|
collapseLoopedAssistantText: () => collapseLoopedAssistantText,
|
|
25322
25348
|
compareReplayPrefix: () => compareReplayPrefix,
|
|
@@ -26138,11 +26164,11 @@ var init_synthesisAudit = __esm({
|
|
|
26138
26164
|
import { existsSync as existsSync7, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "node:fs";
|
|
26139
26165
|
import { join as join4 } from "node:path";
|
|
26140
26166
|
function loadNfrSpec(zelariRoot) {
|
|
26141
|
-
const
|
|
26142
|
-
if (!existsSync7(
|
|
26167
|
+
const path91 = join4(zelariRoot, "nfr-spec.json");
|
|
26168
|
+
if (!existsSync7(path91))
|
|
26143
26169
|
return null;
|
|
26144
26170
|
try {
|
|
26145
|
-
const raw = JSON.parse(readFileSync7(
|
|
26171
|
+
const raw = JSON.parse(readFileSync7(path91, "utf8"));
|
|
26146
26172
|
if (raw.version !== 1 || !Array.isArray(raw.targets))
|
|
26147
26173
|
return null;
|
|
26148
26174
|
return raw;
|
|
@@ -28448,9 +28474,9 @@ var init_types5 = __esm({
|
|
|
28448
28474
|
import { readFileSync as readFileSync12 } from "node:fs";
|
|
28449
28475
|
import { join as join10 } from "node:path";
|
|
28450
28476
|
function readLessonsDeduped(zelariRoot) {
|
|
28451
|
-
const
|
|
28477
|
+
const path91 = join10(zelariRoot, LESSONS_FILE);
|
|
28452
28478
|
try {
|
|
28453
|
-
const raw = readFileSync12(
|
|
28479
|
+
const raw = readFileSync12(path91, "utf8");
|
|
28454
28480
|
const byId = /* @__PURE__ */ new Map();
|
|
28455
28481
|
for (const line of raw.split(/\r?\n/)) {
|
|
28456
28482
|
if (!line.trim())
|
|
@@ -28551,8 +28577,8 @@ function keywordsFrom(check2, signature) {
|
|
|
28551
28577
|
return [.../* @__PURE__ */ new Set([...fromId, ...words])].slice(0, 12);
|
|
28552
28578
|
}
|
|
28553
28579
|
function writeLesson(zelariRoot, lesson) {
|
|
28554
|
-
const
|
|
28555
|
-
appendFileSync(
|
|
28580
|
+
const path91 = join11(zelariRoot, LESSONS_FILE);
|
|
28581
|
+
appendFileSync(path91, `${JSON.stringify(lesson)}
|
|
28556
28582
|
`, "utf8");
|
|
28557
28583
|
}
|
|
28558
28584
|
function findSimilar(lessons, signature) {
|
|
@@ -30515,9 +30541,9 @@ function findCycle(nodes) {
|
|
|
30515
30541
|
if (color.get(start) !== WHITE)
|
|
30516
30542
|
continue;
|
|
30517
30543
|
const stack = [[start, 0]];
|
|
30518
|
-
const
|
|
30544
|
+
const path91 = [];
|
|
30519
30545
|
color.set(start, GRAY);
|
|
30520
|
-
|
|
30546
|
+
path91.push(start);
|
|
30521
30547
|
while (stack.length > 0) {
|
|
30522
30548
|
const top = stack[stack.length - 1];
|
|
30523
30549
|
const [id3, idx] = top;
|
|
@@ -30530,17 +30556,17 @@ function findCycle(nodes) {
|
|
|
30530
30556
|
continue;
|
|
30531
30557
|
const c = color.get(dep);
|
|
30532
30558
|
if (c === GRAY) {
|
|
30533
|
-
const at =
|
|
30534
|
-
return [...
|
|
30559
|
+
const at = path91.indexOf(dep);
|
|
30560
|
+
return [...path91.slice(at), dep];
|
|
30535
30561
|
}
|
|
30536
30562
|
if (c === WHITE) {
|
|
30537
30563
|
color.set(dep, GRAY);
|
|
30538
|
-
|
|
30564
|
+
path91.push(dep);
|
|
30539
30565
|
stack.push([dep, 0]);
|
|
30540
30566
|
}
|
|
30541
30567
|
} else {
|
|
30542
30568
|
color.set(id3, BLACK);
|
|
30543
|
-
|
|
30569
|
+
path91.pop();
|
|
30544
30570
|
stack.pop();
|
|
30545
30571
|
}
|
|
30546
30572
|
}
|
|
@@ -31460,8 +31486,8 @@ var init_runner = __esm({
|
|
|
31460
31486
|
failed: [...this.tentaclesById.values()].filter((r) => r.status === "error"),
|
|
31461
31487
|
pending: []
|
|
31462
31488
|
};
|
|
31463
|
-
const
|
|
31464
|
-
this.host.log(`checkpoint: ${label ?? "auto"} \u2192 ${
|
|
31489
|
+
const path91 = await this.host.saveSnapshot(snapshot, ".zelari/kraken/snapshots");
|
|
31490
|
+
this.host.log(`checkpoint: ${label ?? "auto"} \u2192 ${path91}`);
|
|
31465
31491
|
return snapshot;
|
|
31466
31492
|
}
|
|
31467
31493
|
callLog(msg, data) {
|
|
@@ -31587,6 +31613,15 @@ var init_types9 = __esm({
|
|
|
31587
31613
|
"resource.reserve_entered",
|
|
31588
31614
|
// 2.6.1 (closure plan §9): hard-limit overrun telemetry — state-only.
|
|
31589
31615
|
"resource.overrun",
|
|
31616
|
+
// ADR-0024 v1.1 (amended 2026-08-30): per-node ENVELOPE for kraken-graph
|
|
31617
|
+
// runs — written by the HOST (the sole spine writer) around the executor's
|
|
31618
|
+
// tentacle-run seam. State-only (never model-surface): data = {nodeId,
|
|
31619
|
+
// agent, graphId?, ok?, cancelled?, durationMs?}; node labels, prompts and
|
|
31620
|
+
// turn output stay on the kraken radio JSONL. One pair per attempt.
|
|
31621
|
+
// ADR-0021 schema review: additive state kinds need no SCHEMA_VERSION bump —
|
|
31622
|
+
// older readers skip them via the tolerant replay (schema-mismatch issues).
|
|
31623
|
+
"graph.node_started",
|
|
31624
|
+
"graph.node_ended",
|
|
31590
31625
|
"note"
|
|
31591
31626
|
];
|
|
31592
31627
|
SessionEventEnvelopeSchema = external_exports.object({
|
|
@@ -33912,16 +33947,16 @@ function runRetentionFromEnv() {
|
|
|
33912
33947
|
maxTotalBytes: Number.isFinite(parseMb) && parseMb > 0 ? Math.round(parseMb * 1024 * 1024) : DEFAULT_RUN_RETENTION_MAX_MB * 1024 * 1024
|
|
33913
33948
|
};
|
|
33914
33949
|
}
|
|
33915
|
-
async function dirSize(
|
|
33950
|
+
async function dirSize(path91) {
|
|
33916
33951
|
let total = 0;
|
|
33917
33952
|
let entries;
|
|
33918
33953
|
try {
|
|
33919
|
-
entries = await readdir(
|
|
33954
|
+
entries = await readdir(path91, { withFileTypes: true });
|
|
33920
33955
|
} catch {
|
|
33921
33956
|
return 0;
|
|
33922
33957
|
}
|
|
33923
33958
|
for (const entry of entries) {
|
|
33924
|
-
const child = join13(
|
|
33959
|
+
const child = join13(path91, entry.name);
|
|
33925
33960
|
if (entry.isDirectory())
|
|
33926
33961
|
total += await dirSize(child);
|
|
33927
33962
|
else {
|
|
@@ -33948,19 +33983,19 @@ async function enforceRunRetention(runsDir, options = {}) {
|
|
|
33948
33983
|
for (const entry of entries) {
|
|
33949
33984
|
if (!entry.isDirectory())
|
|
33950
33985
|
continue;
|
|
33951
|
-
const
|
|
33986
|
+
const path91 = join13(runsDir, entry.name);
|
|
33952
33987
|
let startedAt = 0;
|
|
33953
33988
|
let endedAt;
|
|
33954
33989
|
let completed = false;
|
|
33955
33990
|
try {
|
|
33956
|
-
const manifest = JSON.parse(await readFile(join13(
|
|
33991
|
+
const manifest = JSON.parse(await readFile(join13(path91, "manifest.json"), "utf8"));
|
|
33957
33992
|
startedAt = manifest.startedAt ?? 0;
|
|
33958
33993
|
endedAt = manifest.endedAt;
|
|
33959
33994
|
completed = Boolean(endedAt) && manifest.status !== "running";
|
|
33960
33995
|
} catch {
|
|
33961
33996
|
completed = false;
|
|
33962
33997
|
}
|
|
33963
|
-
infos.push({ name: entry.name, path:
|
|
33998
|
+
infos.push({ name: entry.name, path: path91, startedAt, endedAt, completed, bytes: await dirSize(path91) });
|
|
33964
33999
|
}
|
|
33965
34000
|
const remove = async (info) => {
|
|
33966
34001
|
await rm(info.path, { recursive: true, force: true });
|
|
@@ -34732,12 +34767,12 @@ var init_engine = __esm({
|
|
|
34732
34767
|
* content digest) and the returned ref carries the event seq when the
|
|
34733
34768
|
* emitter resolved one.
|
|
34734
34769
|
*/
|
|
34735
|
-
async fsEvidence(observation,
|
|
34770
|
+
async fsEvidence(observation, path91, sha256, content, extra = {}) {
|
|
34736
34771
|
const digest = sha256 && content !== void 0 ? sha256(content) : void 0;
|
|
34737
|
-
const seq = await this.emitEvidence({ observation, path:
|
|
34772
|
+
const seq = await this.emitEvidence({ observation, path: path91, ...extra, ...digest ? { digest } : {} });
|
|
34738
34773
|
return {
|
|
34739
34774
|
tier: "fs-observation",
|
|
34740
|
-
ref:
|
|
34775
|
+
ref: path91,
|
|
34741
34776
|
capturedAt: Date.now(),
|
|
34742
34777
|
...digest ? { digest } : {},
|
|
34743
34778
|
...seq !== void 0 ? { seq } : {}
|
|
@@ -35777,6 +35812,8 @@ __export(dist_exports, {
|
|
|
35777
35812
|
TEXT_LOOP_RECOVERY_SYSTEM: () => TEXT_LOOP_RECOVERY_SYSTEM,
|
|
35778
35813
|
TEXT_LOOP_RECOVERY_USER_PROMPT: () => TEXT_LOOP_RECOVERY_USER_PROMPT,
|
|
35779
35814
|
TIER_RANK: () => TIER_RANK,
|
|
35815
|
+
TOOL_CALL_TRUNCATED_RECOVERY_MARKER: () => TOOL_CALL_TRUNCATED_RECOVERY_MARKER,
|
|
35816
|
+
TOOL_CALL_TRUNCATED_RECOVERY_USER: () => TOOL_CALL_TRUNCATED_RECOVERY_USER,
|
|
35780
35817
|
TOOL_DEFINITIONS: () => TOOL_DEFINITIONS,
|
|
35781
35818
|
TOOL_USE_PROTOCOL_DIRECTIVE: () => TOOL_USE_PROTOCOL_DIRECTIVE,
|
|
35782
35819
|
TURN_COMPLETION_MODULE: () => TURN_COMPLETION_MODULE,
|
|
@@ -37078,6 +37115,15 @@ function mapBrainEventToSpine(ev) {
|
|
|
37078
37115
|
...ev.memberName ? { member: ev.memberName } : {}
|
|
37079
37116
|
}
|
|
37080
37117
|
};
|
|
37118
|
+
case "error":
|
|
37119
|
+
if (ev.code === "tool_call_truncated") {
|
|
37120
|
+
return {
|
|
37121
|
+
kind: "user.message",
|
|
37122
|
+
actor: ACTOR_USER,
|
|
37123
|
+
data: { text: TOOL_CALL_TRUNCATED_RECOVERY_USER }
|
|
37124
|
+
};
|
|
37125
|
+
}
|
|
37126
|
+
return null;
|
|
37081
37127
|
default:
|
|
37082
37128
|
return null;
|
|
37083
37129
|
}
|
|
@@ -37134,6 +37180,7 @@ var MAX_STREAM_BUFFERS, SessionSpineMirror, SpineMirroringWriter;
|
|
|
37134
37180
|
var init_sessionSpine = __esm({
|
|
37135
37181
|
"src/cli/sessionSpine.ts"() {
|
|
37136
37182
|
"use strict";
|
|
37183
|
+
init_harness();
|
|
37137
37184
|
init_session();
|
|
37138
37185
|
init_session();
|
|
37139
37186
|
init_verification2();
|
|
@@ -37880,9 +37927,9 @@ function spillToolOutput(fullText, meta3) {
|
|
|
37880
37927
|
const rnd = randomBytes3(3).toString("hex");
|
|
37881
37928
|
const safeTool = (meta3?.toolName ?? "tool").replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 32);
|
|
37882
37929
|
const file2 = `${stamp}-${safeTool}-${hash3}-${rnd}.txt`;
|
|
37883
|
-
const
|
|
37884
|
-
writeFileSync11(
|
|
37885
|
-
return
|
|
37930
|
+
const path91 = join14(dir, file2);
|
|
37931
|
+
writeFileSync11(path91, fullText, "utf8");
|
|
37932
|
+
return path91;
|
|
37886
37933
|
} catch {
|
|
37887
37934
|
return null;
|
|
37888
37935
|
}
|
|
@@ -37928,10 +37975,10 @@ function truncateToolResult(text, capOrOpts = TOOL_RESULT_LINE_CAP) {
|
|
|
37928
37975
|
${tail2}`;
|
|
37929
37976
|
}
|
|
37930
37977
|
if (doSpill) {
|
|
37931
|
-
const
|
|
37932
|
-
if (
|
|
37978
|
+
const path91 = spillToolOutput(text, { toolName: opts.toolName });
|
|
37979
|
+
if (path91) {
|
|
37933
37980
|
const spillNote = `
|
|
37934
|
-
\u2026 [full output spilled to: ${
|
|
37981
|
+
\u2026 [full output spilled to: ${path91} \u2014 re-read with read_file if you need the complete text] \u2026`;
|
|
37935
37982
|
if (preview.includes("] \u2026\n")) {
|
|
37936
37983
|
preview = preview.replace("] \u2026\n", `] \u2026${spillNote}
|
|
37937
37984
|
`);
|
|
@@ -41044,28 +41091,28 @@ var init_storage = __esm({
|
|
|
41044
41091
|
VALID_SCALARS = /^(true|false|null|~)$/i;
|
|
41045
41092
|
Storage = class {
|
|
41046
41093
|
/** Read a Markdown file with frontmatter. Throws if not found. */
|
|
41047
|
-
read(
|
|
41048
|
-
if (!existsSync19(
|
|
41049
|
-
throw new Error(`File not found: ${
|
|
41094
|
+
read(path91) {
|
|
41095
|
+
if (!existsSync19(path91)) {
|
|
41096
|
+
throw new Error(`File not found: ${path91}`);
|
|
41050
41097
|
}
|
|
41051
|
-
const md = readFileSync16(
|
|
41098
|
+
const md = readFileSync16(path91, "utf8");
|
|
41052
41099
|
return parseFrontmatter(md);
|
|
41053
41100
|
}
|
|
41054
41101
|
/** Read a Markdown file; returns null if not found. */
|
|
41055
|
-
readIfExists(
|
|
41056
|
-
if (!existsSync19(
|
|
41057
|
-
return this.read(
|
|
41102
|
+
readIfExists(path91) {
|
|
41103
|
+
if (!existsSync19(path91)) return null;
|
|
41104
|
+
return this.read(path91);
|
|
41058
41105
|
}
|
|
41059
41106
|
/**
|
|
41060
41107
|
* Write a Markdown file atomically (tmp + rename). Creates parent dirs.
|
|
41061
41108
|
* The meta object is serialized as YAML frontmatter; body as Markdown.
|
|
41062
41109
|
*/
|
|
41063
|
-
write(
|
|
41064
|
-
mkdirSync10(dirname2(
|
|
41065
|
-
const tmp =
|
|
41110
|
+
write(path91, meta3, body) {
|
|
41111
|
+
mkdirSync10(dirname2(path91), { recursive: true });
|
|
41112
|
+
const tmp = path91 + ".tmp-" + process.pid;
|
|
41066
41113
|
const md = serializeFrontmatter(meta3, body);
|
|
41067
41114
|
writeFileSync13(tmp, md, "utf8");
|
|
41068
|
-
renameSync(tmp,
|
|
41115
|
+
renameSync(tmp, path91);
|
|
41069
41116
|
}
|
|
41070
41117
|
/** List all .md files in a directory (non-recursive). */
|
|
41071
41118
|
listMarkdown(dir) {
|
|
@@ -41127,8 +41174,8 @@ function nextPlanTaskId(store6) {
|
|
|
41127
41174
|
return `t${store6.counter}`;
|
|
41128
41175
|
}
|
|
41129
41176
|
function writePlanTaskArtifact(rootDir, task) {
|
|
41130
|
-
const
|
|
41131
|
-
mkdirSync11(dirname3(
|
|
41177
|
+
const path91 = join18(rootDir, "plan-tasks", `${task.id}.md`);
|
|
41178
|
+
mkdirSync11(dirname3(path91), { recursive: true });
|
|
41132
41179
|
const meta3 = {
|
|
41133
41180
|
kind: "task",
|
|
41134
41181
|
id: task.id,
|
|
@@ -41149,7 +41196,7 @@ function writePlanTaskArtifact(rootDir, task) {
|
|
|
41149
41196
|
task.notes?.trim() ? task.notes.trim() : "_(no notes)_",
|
|
41150
41197
|
""
|
|
41151
41198
|
].filter((l) => l !== null).join("\n");
|
|
41152
|
-
new Storage().write(
|
|
41199
|
+
new Storage().write(path91, meta3, body);
|
|
41153
41200
|
}
|
|
41154
41201
|
function loadHandle(rootDir) {
|
|
41155
41202
|
const jsonPath = join18(rootDir, "plan.json");
|
|
@@ -44930,21 +44977,21 @@ function normalizeAuth(auth) {
|
|
|
44930
44977
|
return "agent";
|
|
44931
44978
|
}
|
|
44932
44979
|
function readSecrets() {
|
|
44933
|
-
const
|
|
44934
|
-
if (!existsSync25(
|
|
44980
|
+
const path91 = getSshSecretsPath();
|
|
44981
|
+
if (!existsSync25(path91)) return {};
|
|
44935
44982
|
try {
|
|
44936
|
-
return JSON.parse(readFileSync20(
|
|
44983
|
+
return JSON.parse(readFileSync20(path91, "utf8"));
|
|
44937
44984
|
} catch {
|
|
44938
44985
|
return {};
|
|
44939
44986
|
}
|
|
44940
44987
|
}
|
|
44941
44988
|
function writeSecrets(data) {
|
|
44942
|
-
const
|
|
44943
|
-
mkdirSync12(dirname4(
|
|
44944
|
-
writeFileSync15(
|
|
44989
|
+
const path91 = getSshSecretsPath();
|
|
44990
|
+
mkdirSync12(dirname4(path91), { recursive: true });
|
|
44991
|
+
writeFileSync15(path91, `${JSON.stringify(data, null, 2)}
|
|
44945
44992
|
`, "utf8");
|
|
44946
44993
|
try {
|
|
44947
|
-
chmodSync(
|
|
44994
|
+
chmodSync(path91, 384);
|
|
44948
44995
|
} catch {
|
|
44949
44996
|
}
|
|
44950
44997
|
}
|
|
@@ -44973,10 +45020,10 @@ function deleteSshPassword(id3) {
|
|
|
44973
45020
|
writeSecrets({ passwords });
|
|
44974
45021
|
}
|
|
44975
45022
|
function readStore2() {
|
|
44976
|
-
const
|
|
44977
|
-
if (!existsSync25(
|
|
45023
|
+
const path91 = getSshTargetsPath();
|
|
45024
|
+
if (!existsSync25(path91)) return [];
|
|
44978
45025
|
try {
|
|
44979
|
-
const parsed = JSON.parse(readFileSync20(
|
|
45026
|
+
const parsed = JSON.parse(readFileSync20(path91, "utf8"));
|
|
44980
45027
|
const list = Array.isArray(parsed.targets) ? parsed.targets : [];
|
|
44981
45028
|
return list.filter(
|
|
44982
45029
|
(t) => t && typeof t.id === "string" && typeof t.host === "string" && typeof t.user === "string"
|
|
@@ -44991,11 +45038,11 @@ function readStore2() {
|
|
|
44991
45038
|
}
|
|
44992
45039
|
}
|
|
44993
45040
|
function writeStore2(targets) {
|
|
44994
|
-
const
|
|
44995
|
-
mkdirSync12(dirname4(
|
|
45041
|
+
const path91 = getSshTargetsPath();
|
|
45042
|
+
mkdirSync12(dirname4(path91), { recursive: true });
|
|
44996
45043
|
const clean = targets.map(({ hasPassword: _hp, ...t }) => t);
|
|
44997
45044
|
writeFileSync15(
|
|
44998
|
-
|
|
45045
|
+
path91,
|
|
44999
45046
|
`${JSON.stringify({ targets: clean }, null, 2)}
|
|
45000
45047
|
`,
|
|
45001
45048
|
"utf8"
|
|
@@ -45241,11 +45288,11 @@ function formatSshTargetsForPrompt() {
|
|
|
45241
45288
|
];
|
|
45242
45289
|
for (const t of targets) {
|
|
45243
45290
|
const tags = t.tags?.length ? ` tags=[${t.tags.join(",")}]` : "";
|
|
45244
|
-
const
|
|
45291
|
+
const path91 = t.defaultRemotePath ? ` remotePath=${t.defaultRemotePath}` : "";
|
|
45245
45292
|
const allow = t.allowedCommands?.length ? ` allowed=${t.allowedCommands.join("|")}` : " allowed=status-only";
|
|
45246
45293
|
const auth = t.auth === "password" ? " auth=password" : t.auth === "keyPath" ? " auth=key" : " auth=agent";
|
|
45247
45294
|
lines.push(
|
|
45248
|
-
`- id=${t.id} name=${t.name} ${t.user}@${t.host}:${t.port ?? 22}${auth}${
|
|
45295
|
+
`- id=${t.id} name=${t.name} ${t.user}@${t.host}:${t.port ?? 22}${auth}${path91}${tags}${allow}`
|
|
45249
45296
|
);
|
|
45250
45297
|
}
|
|
45251
45298
|
return lines.join("\n");
|
|
@@ -54236,8 +54283,8 @@ function readPlan(ctx) {
|
|
|
54236
54283
|
} catch {
|
|
54237
54284
|
}
|
|
54238
54285
|
}
|
|
54239
|
-
const
|
|
54240
|
-
const doc = ctx.storage.readIfExists(
|
|
54286
|
+
const path91 = workspaceFile(ctx.rootDir, "plan");
|
|
54287
|
+
const doc = ctx.storage.readIfExists(path91);
|
|
54241
54288
|
if (!doc) return { phases: [], tasks: [], milestones: [] };
|
|
54242
54289
|
const meta3 = doc.meta;
|
|
54243
54290
|
return {
|
|
@@ -54415,7 +54462,7 @@ function addMilestoneRecord(ctx, summary, input) {
|
|
|
54415
54462
|
dueDate: input.dueDate,
|
|
54416
54463
|
targetVersion: version2
|
|
54417
54464
|
});
|
|
54418
|
-
const
|
|
54465
|
+
const path91 = join31(ctx.rootDir, "milestones", `${id3}.md`);
|
|
54419
54466
|
const meta3 = {
|
|
54420
54467
|
kind: "milestone",
|
|
54421
54468
|
id: id3,
|
|
@@ -54432,7 +54479,7 @@ function addMilestoneRecord(ctx, summary, input) {
|
|
|
54432
54479
|
`Target version: ${version2}`,
|
|
54433
54480
|
""
|
|
54434
54481
|
].join("\n");
|
|
54435
|
-
ctx.storage.write(
|
|
54482
|
+
ctx.storage.write(path91, meta3, body);
|
|
54436
54483
|
return { id: id3, created: true };
|
|
54437
54484
|
}
|
|
54438
54485
|
function readPlanSummary(ctx) {
|
|
@@ -54636,7 +54683,7 @@ function addIdeaStub(ctx) {
|
|
|
54636
54683
|
const tags = args["tags"] ?? [];
|
|
54637
54684
|
const category = args["category"] ?? "General";
|
|
54638
54685
|
const id3 = `${nextAdrId(ctx)}-${slugify3(title)}`;
|
|
54639
|
-
const
|
|
54686
|
+
const path91 = workspaceArtifact(ctx.rootDir, "decisions", id3);
|
|
54640
54687
|
const meta3 = {
|
|
54641
54688
|
kind: "adr",
|
|
54642
54689
|
status: "proposed",
|
|
@@ -54662,7 +54709,7 @@ function addIdeaStub(ctx) {
|
|
|
54662
54709
|
...consequences.map((c) => `- ${c}`),
|
|
54663
54710
|
""
|
|
54664
54711
|
].join("\n");
|
|
54665
|
-
ctx.storage.write(
|
|
54712
|
+
ctx.storage.write(path91, meta3, body);
|
|
54666
54713
|
return `ADR ${id3} created: "${title}". Status: proposed. Promote to accepted via /update ADR or manual edit.`;
|
|
54667
54714
|
});
|
|
54668
54715
|
}
|
|
@@ -54744,14 +54791,14 @@ function createDocumentStub(ctx) {
|
|
|
54744
54791
|
ctx.storage.write(risksPath, riskMeta, content);
|
|
54745
54792
|
return `Document "${title}" created at risks.md (workspace root).`;
|
|
54746
54793
|
}
|
|
54747
|
-
const
|
|
54794
|
+
const path91 = workspaceArtifact(ctx.rootDir, "docs", slug);
|
|
54748
54795
|
const meta3 = {
|
|
54749
54796
|
kind: "doc",
|
|
54750
54797
|
id: slug,
|
|
54751
54798
|
date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
|
|
54752
54799
|
tags
|
|
54753
54800
|
};
|
|
54754
|
-
ctx.storage.write(
|
|
54801
|
+
ctx.storage.write(path91, meta3, content);
|
|
54755
54802
|
return `Document "${title}" created at docs/${slug}.md.`;
|
|
54756
54803
|
});
|
|
54757
54804
|
}
|
|
@@ -55138,10 +55185,10 @@ function getUserMcpPath() {
|
|
|
55138
55185
|
function getProjectMcpPath(projectRoot) {
|
|
55139
55186
|
return join32(projectRoot, ".zelari", "mcp.json");
|
|
55140
55187
|
}
|
|
55141
|
-
function readFile6(
|
|
55142
|
-
if (!existsSync37(
|
|
55188
|
+
function readFile6(path91) {
|
|
55189
|
+
if (!existsSync37(path91)) return {};
|
|
55143
55190
|
try {
|
|
55144
|
-
const parsed = JSON.parse(readFileSync29(
|
|
55191
|
+
const parsed = JSON.parse(readFileSync29(path91, "utf8"));
|
|
55145
55192
|
const out = {};
|
|
55146
55193
|
for (const [name, cfg] of Object.entries(parsed.mcpServers ?? {})) {
|
|
55147
55194
|
if (!cfg || typeof cfg.command !== "string" || !cfg.command.trim()) continue;
|
|
@@ -55157,10 +55204,10 @@ function readFile6(path90) {
|
|
|
55157
55204
|
return {};
|
|
55158
55205
|
}
|
|
55159
55206
|
}
|
|
55160
|
-
function writeFile2(
|
|
55161
|
-
mkdirSync16(dirname9(
|
|
55207
|
+
function writeFile2(path91, servers) {
|
|
55208
|
+
mkdirSync16(dirname9(path91), { recursive: true });
|
|
55162
55209
|
const body = { mcpServers: servers };
|
|
55163
|
-
writeFileSync18(
|
|
55210
|
+
writeFileSync18(path91, `${JSON.stringify(body, null, 2)}
|
|
55164
55211
|
`, "utf8");
|
|
55165
55212
|
}
|
|
55166
55213
|
function listMcpServers(projectRoot) {
|
|
@@ -55193,9 +55240,9 @@ function upsertMcpServer(opts) {
|
|
|
55193
55240
|
if (!opts.config.command?.trim()) {
|
|
55194
55241
|
return { ok: false, error: "command is required" };
|
|
55195
55242
|
}
|
|
55196
|
-
let
|
|
55243
|
+
let path91;
|
|
55197
55244
|
if (opts.scope === "user") {
|
|
55198
|
-
|
|
55245
|
+
path91 = getUserMcpPath();
|
|
55199
55246
|
} else {
|
|
55200
55247
|
const root = opts.projectRoot?.trim();
|
|
55201
55248
|
if (!root) {
|
|
@@ -55204,30 +55251,30 @@ function upsertMcpServer(opts) {
|
|
|
55204
55251
|
error: "projectRoot required for project scope (Open Folder first)"
|
|
55205
55252
|
};
|
|
55206
55253
|
}
|
|
55207
|
-
|
|
55254
|
+
path91 = getProjectMcpPath(root);
|
|
55208
55255
|
}
|
|
55209
|
-
const current = readFile6(
|
|
55256
|
+
const current = readFile6(path91);
|
|
55210
55257
|
current[name] = {
|
|
55211
55258
|
command: opts.config.command.trim(),
|
|
55212
55259
|
args: opts.config.args,
|
|
55213
55260
|
env: opts.config.env,
|
|
55214
55261
|
enabled: opts.config.enabled !== false
|
|
55215
55262
|
};
|
|
55216
|
-
writeFile2(
|
|
55217
|
-
return { ok: true, path:
|
|
55263
|
+
writeFile2(path91, current);
|
|
55264
|
+
return { ok: true, path: path91 };
|
|
55218
55265
|
}
|
|
55219
55266
|
function removeMcpServer(opts) {
|
|
55220
|
-
const
|
|
55221
|
-
if (!
|
|
55267
|
+
const path91 = opts.scope === "user" ? getUserMcpPath() : opts.projectRoot ? getProjectMcpPath(opts.projectRoot) : null;
|
|
55268
|
+
if (!path91) {
|
|
55222
55269
|
return { ok: false, error: "projectRoot required for project scope" };
|
|
55223
55270
|
}
|
|
55224
|
-
const current = readFile6(
|
|
55271
|
+
const current = readFile6(path91);
|
|
55225
55272
|
if (!(opts.name in current)) {
|
|
55226
|
-
return { ok: false, error: `Server "${opts.name}" not found in ${
|
|
55273
|
+
return { ok: false, error: `Server "${opts.name}" not found in ${path91}` };
|
|
55227
55274
|
}
|
|
55228
55275
|
delete current[opts.name];
|
|
55229
|
-
writeFile2(
|
|
55230
|
-
return { ok: true, path:
|
|
55276
|
+
writeFile2(path91, current);
|
|
55277
|
+
return { ok: true, path: path91 };
|
|
55231
55278
|
}
|
|
55232
55279
|
var init_mcpConfigIo = __esm({
|
|
55233
55280
|
"src/cli/mcp/mcpConfigIo.ts"() {
|
|
@@ -55628,10 +55675,10 @@ import { createHash as createHash20 } from "node:crypto";
|
|
|
55628
55675
|
import { join as join34 } from "node:path";
|
|
55629
55676
|
import { readFile as readFile7 } from "node:fs/promises";
|
|
55630
55677
|
async function readPackageJson3(projectRoot) {
|
|
55631
|
-
const
|
|
55632
|
-
if (!existsSync39(
|
|
55678
|
+
const path91 = join34(projectRoot, "package.json");
|
|
55679
|
+
if (!existsSync39(path91)) return null;
|
|
55633
55680
|
try {
|
|
55634
|
-
return JSON.parse(await readFile7(
|
|
55681
|
+
return JSON.parse(await readFile7(path91, "utf8"));
|
|
55635
55682
|
} catch {
|
|
55636
55683
|
return null;
|
|
55637
55684
|
}
|
|
@@ -55713,9 +55760,9 @@ async function genBuild(ctx) {
|
|
|
55713
55760
|
].join("\n");
|
|
55714
55761
|
}
|
|
55715
55762
|
async function genOpenQuestions(ctx) {
|
|
55716
|
-
const
|
|
55717
|
-
if (!existsSync39(
|
|
55718
|
-
const content = readFileSync31(
|
|
55763
|
+
const path91 = join34(ctx.rootDir, "risks.md");
|
|
55764
|
+
if (!existsSync39(path91)) return "_No open questions._";
|
|
55765
|
+
const content = readFileSync31(path91, "utf8");
|
|
55719
55766
|
const lines = content.split("\n");
|
|
55720
55767
|
const questions = [];
|
|
55721
55768
|
let currentTitle = "";
|
|
@@ -55989,9 +56036,9 @@ function versionKey(value) {
|
|
|
55989
56036
|
function firstString2(v) {
|
|
55990
56037
|
return typeof v === "string" && v.trim().length > 0 ? v : null;
|
|
55991
56038
|
}
|
|
55992
|
-
function readFileSyncSafe(
|
|
56039
|
+
function readFileSyncSafe(path91) {
|
|
55993
56040
|
try {
|
|
55994
|
-
return readFileSync32(
|
|
56041
|
+
return readFileSync32(path91, "utf8");
|
|
55995
56042
|
} catch {
|
|
55996
56043
|
return null;
|
|
55997
56044
|
}
|
|
@@ -56454,8 +56501,8 @@ async function runPostCouncilHook(ctx, options) {
|
|
|
56454
56501
|
sources: scope.sources
|
|
56455
56502
|
} : void 0
|
|
56456
56503
|
});
|
|
56457
|
-
const
|
|
56458
|
-
completionHook = { ran: true, path:
|
|
56504
|
+
const path91 = writeCouncilCompletion(ctx.rootDir, completion);
|
|
56505
|
+
completionHook = { ran: true, path: path91, completion };
|
|
56459
56506
|
} catch (err) {
|
|
56460
56507
|
completionHook = {
|
|
56461
56508
|
ran: true,
|
|
@@ -57791,7 +57838,7 @@ function safeSocketPath(socketPath) {
|
|
|
57791
57838
|
return socketPath.trim();
|
|
57792
57839
|
}
|
|
57793
57840
|
function startPermissionBroker(socketPath, handlers, opts) {
|
|
57794
|
-
const
|
|
57841
|
+
const path91 = safeSocketPath(socketPath);
|
|
57795
57842
|
const requestTimeoutMs = opts?.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
|
|
57796
57843
|
const sockets = /* @__PURE__ */ new Set();
|
|
57797
57844
|
const server = createServer2((socket) => {
|
|
@@ -57891,10 +57938,10 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
57891
57938
|
return new Promise((resolve9, reject) => {
|
|
57892
57939
|
const onError = (err) => reject(err);
|
|
57893
57940
|
server.once("error", onError);
|
|
57894
|
-
server.listen(
|
|
57941
|
+
server.listen(path91, () => {
|
|
57895
57942
|
server.removeListener("error", onError);
|
|
57896
57943
|
resolve9({
|
|
57897
|
-
socketPath:
|
|
57944
|
+
socketPath: path91,
|
|
57898
57945
|
stop: () => new Promise((res) => {
|
|
57899
57946
|
for (const s of sockets) s.destroy();
|
|
57900
57947
|
sockets.clear();
|
|
@@ -57905,7 +57952,7 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
57905
57952
|
if (done) return;
|
|
57906
57953
|
done = true;
|
|
57907
57954
|
if (process.platform !== "win32") {
|
|
57908
|
-
unlink(
|
|
57955
|
+
unlink(path91, () => res());
|
|
57909
57956
|
} else {
|
|
57910
57957
|
res();
|
|
57911
57958
|
}
|
|
@@ -57918,11 +57965,11 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
57918
57965
|
});
|
|
57919
57966
|
}
|
|
57920
57967
|
function requestBrokerAsk(socketPath, ask, opts) {
|
|
57921
|
-
const
|
|
57968
|
+
const path91 = safeSocketPath(socketPath);
|
|
57922
57969
|
const requestTimeoutMs = opts?.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
|
|
57923
57970
|
const connectTimeoutMs = opts?.connectTimeoutMs ?? PERMISSION_BROKER_DEFAULT_CONNECT_TIMEOUT_MS;
|
|
57924
57971
|
return new Promise((resolve9, reject) => {
|
|
57925
|
-
const socket = connect(
|
|
57972
|
+
const socket = connect(path91);
|
|
57926
57973
|
let buffer = "";
|
|
57927
57974
|
let settled = false;
|
|
57928
57975
|
const settle = (fn) => {
|
|
@@ -57937,7 +57984,7 @@ function requestBrokerAsk(socketPath, ask, opts) {
|
|
|
57937
57984
|
settle(
|
|
57938
57985
|
() => reject(
|
|
57939
57986
|
new Error(
|
|
57940
|
-
`permission broker unavailable at "${
|
|
57987
|
+
`permission broker unavailable at "${path91}" (connect timed out after ${connectTimeoutMs}ms)`
|
|
57941
57988
|
)
|
|
57942
57989
|
)
|
|
57943
57990
|
);
|
|
@@ -58843,6 +58890,12 @@ var init_graphMemory = __esm({
|
|
|
58843
58890
|
});
|
|
58844
58891
|
|
|
58845
58892
|
// src/cli/kraken/tentacle.ts
|
|
58893
|
+
var tentacle_exports = {};
|
|
58894
|
+
__export(tentacle_exports, {
|
|
58895
|
+
TASK_TOOL_TIMEOUT_MS: () => TASK_TOOL_TIMEOUT_MS,
|
|
58896
|
+
runSubAgent: () => runSubAgent,
|
|
58897
|
+
runTentacle: () => runTentacle
|
|
58898
|
+
});
|
|
58846
58899
|
var init_tentacle = __esm({
|
|
58847
58900
|
"src/cli/kraken/tentacle.ts"() {
|
|
58848
58901
|
"use strict";
|
|
@@ -65742,6 +65795,7 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
65742
65795
|
return exitCode;
|
|
65743
65796
|
}
|
|
65744
65797
|
const audit = new AuditLogger2();
|
|
65798
|
+
const { runTentacle: runTentacle2 } = await Promise.resolve().then(() => (init_tentacle(), tentacle_exports));
|
|
65745
65799
|
const executor = new KrakenGraphExecutor2({
|
|
65746
65800
|
taskToolDeps: {
|
|
65747
65801
|
createSubAgentContext: createKrakenSubAgentContextFactory2({
|
|
@@ -65774,7 +65828,11 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
65774
65828
|
parentCwd: cwd,
|
|
65775
65829
|
sessionId: sessionId2,
|
|
65776
65830
|
goal: prompt,
|
|
65777
|
-
signal: abort.signal
|
|
65831
|
+
signal: abort.signal,
|
|
65832
|
+
// ADR-0024 v1.1: same delegate (`runTentacle`), wrapped so each node
|
|
65833
|
+
// turn leaves a graph.node_started / graph.node_ended envelope pair on
|
|
65834
|
+
// the spine. The executor owns scheduling; the HOST owns the spine.
|
|
65835
|
+
runTentacleFn: (runOpts) => nodeSpineEnvelopeRun(spine, runOpts, () => runTentacle2(runOpts))
|
|
65778
65836
|
});
|
|
65779
65837
|
const summary = await executor.execute(graph);
|
|
65780
65838
|
if (summary.cancelled) log("graph cancelled \u2014 partial results below");
|
|
@@ -65819,6 +65877,37 @@ ${formatKrakenGraphDigest2(
|
|
|
65819
65877
|
await emitHarnessStateEvent({ spine, workspaceRoot: cwd, output: opts.output, emitEvent });
|
|
65820
65878
|
}
|
|
65821
65879
|
}
|
|
65880
|
+
function nodeSpineEnvelopeRun(spine, runOpts, run) {
|
|
65881
|
+
const startedAt = Date.now();
|
|
65882
|
+
const noteNode = (kind2, extra) => {
|
|
65883
|
+
if (!runOpts.nodeId) return;
|
|
65884
|
+
void spine.appendEvent({
|
|
65885
|
+
kind: kind2,
|
|
65886
|
+
actor: { type: "system" },
|
|
65887
|
+
data: {
|
|
65888
|
+
nodeId: runOpts.nodeId,
|
|
65889
|
+
agent: runOpts.agent,
|
|
65890
|
+
...runOpts.graphId ? { graphId: runOpts.graphId } : {},
|
|
65891
|
+
...extra
|
|
65892
|
+
}
|
|
65893
|
+
});
|
|
65894
|
+
};
|
|
65895
|
+
noteNode("graph.node_started");
|
|
65896
|
+
return run().then(
|
|
65897
|
+
(res) => {
|
|
65898
|
+
noteNode("graph.node_ended", {
|
|
65899
|
+
ok: res.ok,
|
|
65900
|
+
...!res.ok && res.cancelled ? { cancelled: true } : {},
|
|
65901
|
+
durationMs: Date.now() - startedAt
|
|
65902
|
+
});
|
|
65903
|
+
return res;
|
|
65904
|
+
},
|
|
65905
|
+
(err) => {
|
|
65906
|
+
noteNode("graph.node_ended", { ok: false, durationMs: Date.now() - startedAt });
|
|
65907
|
+
throw err;
|
|
65908
|
+
}
|
|
65909
|
+
);
|
|
65910
|
+
}
|
|
65822
65911
|
async function buildCouncilToolRegistry(planMode, opts, memoryService, memoryAutoWrite = false, extras) {
|
|
65823
65912
|
const cwd = opts ? resolveHeadlessCwd(opts) : process.cwd();
|
|
65824
65913
|
const { registry: toolRegistry } = createBuiltinToolRegistry({
|
|
@@ -67062,7 +67151,7 @@ function upsertSkill(opts) {
|
|
|
67062
67151
|
}
|
|
67063
67152
|
dir = getProjectSkillsDir(root);
|
|
67064
67153
|
}
|
|
67065
|
-
const
|
|
67154
|
+
const path91 = skillFilePath(dir, name);
|
|
67066
67155
|
const content = serializeSkillMd({
|
|
67067
67156
|
name,
|
|
67068
67157
|
description,
|
|
@@ -67071,13 +67160,13 @@ function upsertSkill(opts) {
|
|
|
67071
67160
|
tools: opts.tools,
|
|
67072
67161
|
cost: opts.cost
|
|
67073
67162
|
});
|
|
67074
|
-
const parsed = parseSkillMd(content,
|
|
67163
|
+
const parsed = parseSkillMd(content, path91);
|
|
67075
67164
|
if (!parsed) {
|
|
67076
67165
|
return { ok: false, error: "Generated SKILL.md failed validation" };
|
|
67077
67166
|
}
|
|
67078
|
-
mkdirSync21(dirname13(
|
|
67079
|
-
writeFileSync24(
|
|
67080
|
-
return { ok: true, path:
|
|
67167
|
+
mkdirSync21(dirname13(path91), { recursive: true });
|
|
67168
|
+
writeFileSync24(path91, content, "utf8");
|
|
67169
|
+
return { ok: true, path: path91 };
|
|
67081
67170
|
}
|
|
67082
67171
|
function removeSkill(opts) {
|
|
67083
67172
|
const name = opts.name.trim().toLowerCase();
|
|
@@ -67095,8 +67184,8 @@ function removeSkill(opts) {
|
|
|
67095
67184
|
dir = getProjectSkillsDir(root);
|
|
67096
67185
|
}
|
|
67097
67186
|
const skillDir = join46(dir, name);
|
|
67098
|
-
const
|
|
67099
|
-
if (!existsSync52(
|
|
67187
|
+
const path91 = skillFilePath(dir, name);
|
|
67188
|
+
if (!existsSync52(path91) && !existsSync52(skillDir)) {
|
|
67100
67189
|
return { ok: false, error: `Skill "${name}" not found in ${dir}` };
|
|
67101
67190
|
}
|
|
67102
67191
|
try {
|
|
@@ -67107,7 +67196,7 @@ function removeSkill(opts) {
|
|
|
67107
67196
|
error: err instanceof Error ? err.message : String(err)
|
|
67108
67197
|
};
|
|
67109
67198
|
}
|
|
67110
|
-
return { ok: true, path:
|
|
67199
|
+
return { ok: true, path: path91 };
|
|
67111
67200
|
}
|
|
67112
67201
|
var NAME_RE, BUILTIN_SKILL_MODULES, builtinsLoaded;
|
|
67113
67202
|
var init_skillConfigIo = __esm({
|
|
@@ -67925,12 +68014,12 @@ function ensureHome() {
|
|
|
67925
68014
|
}
|
|
67926
68015
|
}
|
|
67927
68016
|
function loadCompanionConfig() {
|
|
67928
|
-
const
|
|
67929
|
-
if (!existsSync53(
|
|
68017
|
+
const path91 = getCompanionConfigPath();
|
|
68018
|
+
if (!existsSync53(path91)) {
|
|
67930
68019
|
return { projects: [] };
|
|
67931
68020
|
}
|
|
67932
68021
|
try {
|
|
67933
|
-
const raw = JSON.parse(readFileSync41(
|
|
68022
|
+
const raw = JSON.parse(readFileSync41(path91, "utf8"));
|
|
67934
68023
|
const projects = Array.isArray(raw.projects) ? raw.projects.filter(
|
|
67935
68024
|
(p3) => p3 && typeof p3.path === "string" && p3.path.trim() && typeof (p3.id ?? p3.name) === "string"
|
|
67936
68025
|
).map((p3) => ({
|
|
@@ -67968,16 +68057,16 @@ function loadOrCreateToken(explicit) {
|
|
|
67968
68057
|
return { token: explicit.trim(), created: false };
|
|
67969
68058
|
}
|
|
67970
68059
|
ensureHome();
|
|
67971
|
-
const
|
|
67972
|
-
if (existsSync53(
|
|
67973
|
-
const t = readFileSync41(
|
|
68060
|
+
const path91 = getCompanionTokenPath();
|
|
68061
|
+
if (existsSync53(path91)) {
|
|
68062
|
+
const t = readFileSync41(path91, "utf8").trim();
|
|
67974
68063
|
if (t) return { token: t, created: false };
|
|
67975
68064
|
}
|
|
67976
68065
|
const token = randomBytes7(24).toString("base64url");
|
|
67977
|
-
writeFileSync25(
|
|
68066
|
+
writeFileSync25(path91, token + "\n", "utf8");
|
|
67978
68067
|
try {
|
|
67979
68068
|
const fs45 = __require("node:fs");
|
|
67980
|
-
fs45.chmodSync?.(
|
|
68069
|
+
fs45.chmodSync?.(path91, 384);
|
|
67981
68070
|
} catch {
|
|
67982
68071
|
}
|
|
67983
68072
|
return { token, created: true };
|
|
@@ -68002,17 +68091,17 @@ function mergeProjects(cfg, extraPaths) {
|
|
|
68002
68091
|
byId.set(p3.id, p3);
|
|
68003
68092
|
}
|
|
68004
68093
|
for (const raw of extraPaths) {
|
|
68005
|
-
const
|
|
68006
|
-
if (!
|
|
68007
|
-
let id3 = slugFromPath(
|
|
68094
|
+
const path91 = raw.trim();
|
|
68095
|
+
if (!path91) continue;
|
|
68096
|
+
let id3 = slugFromPath(path91);
|
|
68008
68097
|
let n = 2;
|
|
68009
|
-
while (byId.has(id3) && byId.get(id3).path !==
|
|
68010
|
-
id3 = `${slugFromPath(
|
|
68098
|
+
while (byId.has(id3) && byId.get(id3).path !== path91) {
|
|
68099
|
+
id3 = `${slugFromPath(path91)}-${n++}`;
|
|
68011
68100
|
}
|
|
68012
68101
|
byId.set(id3, {
|
|
68013
68102
|
id: id3,
|
|
68014
|
-
name: slugFromPath(
|
|
68015
|
-
path:
|
|
68103
|
+
name: slugFromPath(path91),
|
|
68104
|
+
path: path91
|
|
68016
68105
|
});
|
|
68017
68106
|
}
|
|
68018
68107
|
return [...byId.values()];
|
|
@@ -68987,9 +69076,9 @@ async function runCompanionServe(opts = {}) {
|
|
|
68987
69076
|
return;
|
|
68988
69077
|
}
|
|
68989
69078
|
const url2 = parseUrl(req);
|
|
68990
|
-
const
|
|
69079
|
+
const path91 = url2.pathname.replace(/\/+$/, "") || "/";
|
|
68991
69080
|
try {
|
|
68992
|
-
if (req.method === "GET" && (
|
|
69081
|
+
if (req.method === "GET" && (path91 === "/health" || path91 === "/v1/health")) {
|
|
68993
69082
|
sendJson2(res, 200, {
|
|
68994
69083
|
ok: true,
|
|
68995
69084
|
service: "zelari-companion",
|
|
@@ -69001,18 +69090,18 @@ async function runCompanionServe(opts = {}) {
|
|
|
69001
69090
|
});
|
|
69002
69091
|
return;
|
|
69003
69092
|
}
|
|
69004
|
-
if (
|
|
69093
|
+
if (path91.startsWith("/v1")) {
|
|
69005
69094
|
if (!tokenMatches(token, getBearer(req))) {
|
|
69006
69095
|
sendJson2(res, 401, { ok: false, error: "unauthorized" });
|
|
69007
69096
|
return;
|
|
69008
69097
|
}
|
|
69009
69098
|
}
|
|
69010
|
-
if (req.method === "GET" &&
|
|
69099
|
+
if (req.method === "GET" && path91 === "/v1/config") {
|
|
69011
69100
|
const snap = buildDesktopConfigSnapshot();
|
|
69012
69101
|
sendJson2(res, 200, { ok: true, ...snap });
|
|
69013
69102
|
return;
|
|
69014
69103
|
}
|
|
69015
|
-
if (req.method === "GET" &&
|
|
69104
|
+
if (req.method === "GET" && path91 === "/v1/projects") {
|
|
69016
69105
|
sendJson2(res, 200, {
|
|
69017
69106
|
ok: true,
|
|
69018
69107
|
projects: projects.map((p3) => ({
|
|
@@ -69023,7 +69112,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
69023
69112
|
});
|
|
69024
69113
|
return;
|
|
69025
69114
|
}
|
|
69026
|
-
if (req.method === "GET" &&
|
|
69115
|
+
if (req.method === "GET" && path91 === "/v1/runs") {
|
|
69027
69116
|
sendJson2(res, 200, {
|
|
69028
69117
|
ok: true,
|
|
69029
69118
|
active: runs.getActive(),
|
|
@@ -69041,7 +69130,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
69041
69130
|
});
|
|
69042
69131
|
return;
|
|
69043
69132
|
}
|
|
69044
|
-
if (req.method === "POST" &&
|
|
69133
|
+
if (req.method === "POST" && path91 === "/v1/runs") {
|
|
69045
69134
|
const raw = await readBody(req);
|
|
69046
69135
|
let body = {};
|
|
69047
69136
|
try {
|
|
@@ -69089,7 +69178,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
69089
69178
|
});
|
|
69090
69179
|
return;
|
|
69091
69180
|
}
|
|
69092
|
-
const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(
|
|
69181
|
+
const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(path91);
|
|
69093
69182
|
if (req.method === "GET" && eventsMatch) {
|
|
69094
69183
|
const runId = eventsMatch[1];
|
|
69095
69184
|
const run = runs.getRun(runId);
|
|
@@ -69154,7 +69243,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
69154
69243
|
}, 500);
|
|
69155
69244
|
return;
|
|
69156
69245
|
}
|
|
69157
|
-
const cancelMatch = /^\/v1\/runs\/([^/]+)\/cancel$/.exec(
|
|
69246
|
+
const cancelMatch = /^\/v1\/runs\/([^/]+)\/cancel$/.exec(path91);
|
|
69158
69247
|
if (req.method === "POST" && cancelMatch) {
|
|
69159
69248
|
const runId = cancelMatch[1];
|
|
69160
69249
|
const result = runs.cancel(runId);
|
|
@@ -69165,7 +69254,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
69165
69254
|
sendJson2(res, 200, { ok: true, cancelled: runId });
|
|
69166
69255
|
return;
|
|
69167
69256
|
}
|
|
69168
|
-
const steerMatch = /^\/v1\/runs\/([^/]+)\/steer$/.exec(
|
|
69257
|
+
const steerMatch = /^\/v1\/runs\/([^/]+)\/steer$/.exec(path91);
|
|
69169
69258
|
if (req.method === "POST" && steerMatch) {
|
|
69170
69259
|
const runId = steerMatch[1];
|
|
69171
69260
|
const raw = await readBody(req);
|
|
@@ -69845,21 +69934,88 @@ var init_fixBudget = __esm({
|
|
|
69845
69934
|
}
|
|
69846
69935
|
});
|
|
69847
69936
|
|
|
69937
|
+
// src/cli/commands/inspectSession.ts
|
|
69938
|
+
var inspectSession_exports = {};
|
|
69939
|
+
__export(inspectSession_exports, {
|
|
69940
|
+
renderInspectReport: () => renderInspectReport,
|
|
69941
|
+
runInspectSession: () => runInspectSession
|
|
69942
|
+
});
|
|
69943
|
+
import path89 from "node:path";
|
|
69944
|
+
import { existsSync as existsSync56 } from "node:fs";
|
|
69945
|
+
function renderInspectReport(state3) {
|
|
69946
|
+
const lines = [
|
|
69947
|
+
`session ${state3.session.sessionId} status=${state3.session.status} turns=${state3.execution.turnsTotal}`
|
|
69948
|
+
];
|
|
69949
|
+
const contractByTurn = new Map(state3.execution.contracts.map((c) => [c.turn, c]));
|
|
69950
|
+
for (const turn of state3.turns) {
|
|
69951
|
+
const contract = contractByTurn.get(turn.index);
|
|
69952
|
+
const verification = turn.verification ? `${turn.verification.verdict}${turn.verification.strict ? "" : " (non-strict)"}` : "unknown";
|
|
69953
|
+
const blockers = contract?.blockers ?? [];
|
|
69954
|
+
const completion = contract?.complete ? "complete" : blockers.length > 0 ? `incomplete \u2014 ${blockers.length} blockers: ${blockers.join(", ")}` : "incomplete";
|
|
69955
|
+
lines.push(
|
|
69956
|
+
` turn ${turn.index} [${turn.outcome}] verification: ${verification} contract: ${completion}`
|
|
69957
|
+
);
|
|
69958
|
+
}
|
|
69959
|
+
lines.push("");
|
|
69960
|
+
lines.push("support lens:");
|
|
69961
|
+
const projections = state3.support.contextProjections;
|
|
69962
|
+
const last = projections[projections.length - 1];
|
|
69963
|
+
lines.push(
|
|
69964
|
+
` context projections: ${projections.length}` + (last ? ` (last: ${last.contextChars} chars \u2192 ${last.returnedCount} items)` : "")
|
|
69965
|
+
);
|
|
69966
|
+
lines.push(` memory events: ${state3.support.memoryEvents}`);
|
|
69967
|
+
const saved = state3.support.tokensSavedByCompaction;
|
|
69968
|
+
lines.push(
|
|
69969
|
+
` compactions: ${state3.support.compactions}${saved !== void 0 ? ` (${saved} tokens saved)` : ""}`
|
|
69970
|
+
);
|
|
69971
|
+
return lines.join("\n");
|
|
69972
|
+
}
|
|
69973
|
+
async function runInspectSession(opts) {
|
|
69974
|
+
const sessionsDir = resolveSessionsDir({ workspaceRoot: opts.cwd ?? process.cwd() });
|
|
69975
|
+
const sessionDir = path89.join(sessionsDir, opts.sessionId);
|
|
69976
|
+
const eventsPath = path89.join(sessionDir, "events.jsonl");
|
|
69977
|
+
if (!existsSync56(sessionDir)) {
|
|
69978
|
+
console.error(`zelari-code inspect: no session directory at ${sessionDir}`);
|
|
69979
|
+
return 1;
|
|
69980
|
+
}
|
|
69981
|
+
if (!existsSync56(eventsPath)) {
|
|
69982
|
+
console.error(`zelari-code inspect: session directory has no events.jsonl at ${eventsPath}`);
|
|
69983
|
+
return 1;
|
|
69984
|
+
}
|
|
69985
|
+
let state3;
|
|
69986
|
+
try {
|
|
69987
|
+
state3 = await readHarnessState(sessionDir);
|
|
69988
|
+
} catch (err) {
|
|
69989
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
69990
|
+
console.error(`zelari-code inspect: cannot read session at ${sessionDir}: ${msg}`);
|
|
69991
|
+
return 1;
|
|
69992
|
+
}
|
|
69993
|
+
console.log(opts.json ? JSON.stringify(state3, null, 2) : renderInspectReport(state3));
|
|
69994
|
+
return 0;
|
|
69995
|
+
}
|
|
69996
|
+
var init_inspectSession = __esm({
|
|
69997
|
+
"src/cli/commands/inspectSession.ts"() {
|
|
69998
|
+
"use strict";
|
|
69999
|
+
init_session();
|
|
70000
|
+
init_harnessState();
|
|
70001
|
+
}
|
|
70002
|
+
});
|
|
70003
|
+
|
|
69848
70004
|
// src/cli/commands/inspect.ts
|
|
69849
70005
|
var inspect_exports = {};
|
|
69850
70006
|
__export(inspect_exports, {
|
|
69851
70007
|
collectInspectReport: () => collectInspectReport,
|
|
69852
70008
|
runInspect: () => runInspect
|
|
69853
70009
|
});
|
|
69854
|
-
import
|
|
69855
|
-
import { existsSync as
|
|
70010
|
+
import path90 from "node:path";
|
|
70011
|
+
import { existsSync as existsSync57, readFileSync as readFileSync43, readdirSync as readdirSync12 } from "node:fs";
|
|
69856
70012
|
import { homedir as homedir17 } from "node:os";
|
|
69857
70013
|
async function collectInspectReport(cwd = process.cwd()) {
|
|
69858
70014
|
ensureBuiltinSkillsLoadedSync();
|
|
69859
70015
|
const snap = listSkillsSnapshot(cwd);
|
|
69860
70016
|
const mcp = listMcpServers(cwd);
|
|
69861
|
-
const userMcpPath =
|
|
69862
|
-
const projectMcpPath =
|
|
70017
|
+
const userMcpPath = path90.join(homedir17(), ".zelari-code", "mcp.json");
|
|
70018
|
+
const projectMcpPath = path90.join(cwd, ".zelari", "mcp.json");
|
|
69863
70019
|
const globalHooks = globalHooksDir();
|
|
69864
70020
|
const projectHooks = projectHooksDir(cwd);
|
|
69865
70021
|
const projectTrusted = isFolderTrusted(cwd);
|
|
@@ -69885,11 +70041,11 @@ async function collectInspectReport(cwd = process.cwd()) {
|
|
|
69885
70041
|
folders: listTrustedFolders()
|
|
69886
70042
|
},
|
|
69887
70043
|
configSources: [
|
|
69888
|
-
{ path: userMcpPath, exists:
|
|
69889
|
-
{ path: projectMcpPath, exists:
|
|
69890
|
-
{ path:
|
|
69891
|
-
{ path:
|
|
69892
|
-
{ path:
|
|
70044
|
+
{ path: userMcpPath, exists: existsSync57(userMcpPath) },
|
|
70045
|
+
{ path: projectMcpPath, exists: existsSync57(projectMcpPath) },
|
|
70046
|
+
{ path: path90.join(homedir17(), ".zelari-code", "provider.json"), exists: existsSync57(path90.join(homedir17(), ".zelari-code", "provider.json")) },
|
|
70047
|
+
{ path: path90.join(cwd, ".zelari", "AGENTS.md"), exists: existsSync57(path90.join(cwd, ".zelari", "AGENTS.md")) },
|
|
70048
|
+
{ path: path90.join(cwd, "AGENTS.md"), exists: existsSync57(path90.join(cwd, "AGENTS.md")) }
|
|
69893
70049
|
],
|
|
69894
70050
|
skills: {
|
|
69895
70051
|
total: snap.skills.length,
|
|
@@ -69902,7 +70058,7 @@ async function collectInspectReport(cwd = process.cwd()) {
|
|
|
69902
70058
|
user: mcp.servers.filter((s) => s.scope === "user").map((s) => ({ name: s.name, enabled: s.enabled !== false })),
|
|
69903
70059
|
project: mcp.servers.filter((s) => s.scope === "project").map((s) => ({ name: s.name, enabled: s.enabled !== false })),
|
|
69904
70060
|
projectTrusted,
|
|
69905
|
-
projectConfigExists:
|
|
70061
|
+
projectConfigExists: existsSync57(projectMcpPath)
|
|
69906
70062
|
},
|
|
69907
70063
|
hooks: {
|
|
69908
70064
|
global: {
|
|
@@ -69929,12 +70085,12 @@ function listJsonFiles(dir) {
|
|
|
69929
70085
|
}
|
|
69930
70086
|
function findAgentsMd(cwd) {
|
|
69931
70087
|
const candidates = [
|
|
69932
|
-
|
|
69933
|
-
|
|
70088
|
+
path90.join(cwd, "AGENTS.md"),
|
|
70089
|
+
path90.join(cwd, ".zelari", "AGENTS.md")
|
|
69934
70090
|
];
|
|
69935
70091
|
const found = [];
|
|
69936
70092
|
for (const c of candidates) {
|
|
69937
|
-
if (
|
|
70093
|
+
if (existsSync57(c)) {
|
|
69938
70094
|
try {
|
|
69939
70095
|
const text = readFileSync43(c, "utf8");
|
|
69940
70096
|
found.push(`${c} (${text.length} bytes)`);
|
|
@@ -79561,8 +79717,8 @@ function normalizeDraft(raw, sourceUrl, provider, model) {
|
|
|
79561
79717
|
let name = String(o.name ?? "").trim().toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64);
|
|
79562
79718
|
if (!name || !/^[a-z0-9][a-z0-9-]{0,63}$/.test(name)) {
|
|
79563
79719
|
try {
|
|
79564
|
-
const
|
|
79565
|
-
name =
|
|
79720
|
+
const path91 = new URL(sourceUrl).pathname.split("/").filter(Boolean).pop()?.replace(/\.[a-z0-9]+$/i, "").toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48);
|
|
79721
|
+
name = path91 && /^[a-z0-9]/.test(path91) ? path91 : "imported-skill";
|
|
79566
79722
|
} catch {
|
|
79567
79723
|
name = "imported-skill";
|
|
79568
79724
|
}
|
|
@@ -79897,6 +80053,14 @@ function pickRootComponent() {
|
|
|
79897
80053
|
process.exit(1);
|
|
79898
80054
|
}
|
|
79899
80055
|
if (argv.includes("--inspect") || argv.includes("inspect")) {
|
|
80056
|
+
const inspectAt = argv.findIndex((a) => a === "inspect" || a === "--inspect");
|
|
80057
|
+
const sessionId2 = inspectAt >= 0 ? argv.slice(inspectAt + 1).find((a) => !a.startsWith("-")) : void 0;
|
|
80058
|
+
if (sessionId2) {
|
|
80059
|
+
const { runInspectSession: runInspectSession2 } = (init_inspectSession(), __toCommonJS(inspectSession_exports));
|
|
80060
|
+
const json4 = argv.includes("--json");
|
|
80061
|
+
void runInspectSession2({ sessionId: sessionId2, json: json4 }).then((code) => process.exit(code));
|
|
80062
|
+
return { kind: "done" };
|
|
80063
|
+
}
|
|
79900
80064
|
const { runInspect: runInspect2 } = (init_inspect(), __toCommonJS(inspect_exports));
|
|
79901
80065
|
const json3 = argv.includes("--json");
|
|
79902
80066
|
void runInspect2({ json: json3 }).then((code) => process.exit(code));
|