zelari-code 2.16.5 → 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/app.js +3 -0
- package/dist/cli/app.js.map +1 -1
- package/dist/cli/commands/inspectSession.js +86 -0
- package/dist/cli/commands/inspectSession.js.map +1 -0
- package/dist/cli/companion/serve.js +29 -0
- package/dist/cli/companion/serve.js.map +1 -1
- package/dist/cli/harnessState.js +240 -0
- package/dist/cli/harnessState.js.map +1 -0
- package/dist/cli/headless/harnessStateEmit.js +38 -0
- package/dist/cli/headless/harnessStateEmit.js.map +1 -0
- package/dist/cli/headless/policyGate.js +6 -3
- package/dist/cli/headless/policyGate.js.map +1 -1
- package/dist/cli/headless/runOneTurn.js +29 -5
- package/dist/cli/headless/runOneTurn.js.map +1 -1
- package/dist/cli/headless.js +20 -9
- package/dist/cli/headless.js.map +1 -1
- package/dist/cli/hooks/useChatTurn.js +25 -1
- package/dist/cli/hooks/useChatTurn.js.map +1 -1
- package/dist/cli/hooks/useSlashDispatch.js +1 -1
- package/dist/cli/hooks/useSlashDispatch.js.map +1 -1
- package/dist/cli/kraken/verificationBridge.js +27 -4
- package/dist/cli/kraken/verificationBridge.js.map +1 -1
- package/dist/cli/lsp/manager.js +31 -11
- package/dist/cli/lsp/manager.js.map +1 -1
- package/dist/cli/main.bundled.js +1030 -489
- 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/memory/fileBackend.js +7 -3
- package/dist/cli/memory/fileBackend.js.map +1 -1
- package/dist/cli/memory/spineTelemetry.js +49 -0
- package/dist/cli/memory/spineTelemetry.js.map +1 -0
- package/dist/cli/runHeadless.js +171 -30
- package/dist/cli/runHeadless.js.map +1 -1
- package/dist/cli/safety/jails/win32.js.map +1 -1
- package/dist/cli/serve/harnessServer.js +20 -1
- package/dist/cli/serve/harnessServer.js.map +1 -1
- package/dist/cli/sessionSpine.js +22 -13
- package/dist/cli/sessionSpine.js.map +1 -1
- package/dist/cli/slashHandlers/krakenGraph.js +11 -0
- package/dist/cli/slashHandlers/krakenGraph.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;
|
|
@@ -23610,10 +23624,10 @@ ${fromRunCache}`,
|
|
|
23610
23624
|
}
|
|
23611
23625
|
const existing = inflight.get(callKey);
|
|
23612
23626
|
if (existing) {
|
|
23613
|
-
const
|
|
23627
|
+
const shared = await existing;
|
|
23614
23628
|
return {
|
|
23615
23629
|
content: `[duplicate call \u2014 result repeated; do not call this tool again with the same arguments]
|
|
23616
|
-
${
|
|
23630
|
+
${shared.content}`,
|
|
23617
23631
|
isError: false,
|
|
23618
23632
|
durationMs: 0
|
|
23619
23633
|
};
|
|
@@ -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;
|
|
@@ -25125,7 +25149,7 @@ var init_appServer = __esm({
|
|
|
25125
25149
|
services = factory(root);
|
|
25126
25150
|
this.workspaceServices.set(root, services);
|
|
25127
25151
|
}
|
|
25128
|
-
const
|
|
25152
|
+
const shared = services;
|
|
25129
25153
|
const server = this;
|
|
25130
25154
|
const count = this.sessionCounts.get(root) ?? 0;
|
|
25131
25155
|
this.sessionCounts.set(root, count + 1);
|
|
@@ -25133,13 +25157,13 @@ var init_appServer = __esm({
|
|
|
25133
25157
|
const session = {
|
|
25134
25158
|
id: id3,
|
|
25135
25159
|
workspaceRoot: root,
|
|
25136
|
-
services:
|
|
25160
|
+
services: shared,
|
|
25137
25161
|
runTurn(input) {
|
|
25138
25162
|
const deps = {
|
|
25139
25163
|
session: { id: id3, workspaceRoot: root },
|
|
25140
25164
|
services: {
|
|
25141
|
-
...
|
|
25142
|
-
completionProofWriter: server.trackProofWriter(
|
|
25165
|
+
...shared,
|
|
25166
|
+
completionProofWriter: server.trackProofWriter(shared.completionProofWriter)
|
|
25143
25167
|
}
|
|
25144
25168
|
};
|
|
25145
25169
|
return runTurn(input, deps);
|
|
@@ -25150,10 +25174,10 @@ var init_appServer = __esm({
|
|
|
25150
25174
|
server.sessionCounts.set(root, remaining);
|
|
25151
25175
|
if (remaining <= 0) {
|
|
25152
25176
|
server.sessionCounts.delete(root);
|
|
25153
|
-
const
|
|
25177
|
+
const shared2 = server.workspaceServices.get(root);
|
|
25154
25178
|
server.workspaceServices.delete(root);
|
|
25155
25179
|
try {
|
|
25156
|
-
|
|
25180
|
+
shared2?.lspManager?.dispose();
|
|
25157
25181
|
} catch {
|
|
25158
25182
|
}
|
|
25159
25183
|
}
|
|
@@ -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) {
|
|
@@ -31553,16 +31579,12 @@ var init_types9 = __esm({
|
|
|
31553
31579
|
// once at session start / manifest change. State-only (never model-surface):
|
|
31554
31580
|
// data = {manifest, manifestHash}. Schema review per ADR-0021.
|
|
31555
31581
|
"session.harness_manifest",
|
|
31556
|
-
// 2.6.1 (closure plan §6): resume-time harness drift record. State-only:
|
|
31557
|
-
// data = {originalManifestHash, currentManifestHash}. Non-blocking signal.
|
|
31558
|
-
"session.harness_drift",
|
|
31559
31582
|
"user.message",
|
|
31560
31583
|
"assistant.message",
|
|
31561
31584
|
"tool.call",
|
|
31562
31585
|
"tool.result",
|
|
31563
31586
|
// 2.x B (crash-safe recovery): dangling call classified. State-only.
|
|
31564
31587
|
"tool.interrupted",
|
|
31565
|
-
"context.injected",
|
|
31566
31588
|
"session.compacted",
|
|
31567
31589
|
"task.created",
|
|
31568
31590
|
"task.updated",
|
|
@@ -31571,7 +31593,6 @@ var init_types9 = __esm({
|
|
|
31571
31593
|
// State-only: compaction projects it into CompactionStateSnapshot.
|
|
31572
31594
|
"task.contract",
|
|
31573
31595
|
"task.contract_updated",
|
|
31574
|
-
"kraken.task",
|
|
31575
31596
|
"council.member",
|
|
31576
31597
|
"mission.phase",
|
|
31577
31598
|
"mission.replan",
|
|
@@ -31592,6 +31613,15 @@ var init_types9 = __esm({
|
|
|
31592
31613
|
"resource.reserve_entered",
|
|
31593
31614
|
// 2.6.1 (closure plan §9): hard-limit overrun telemetry — state-only.
|
|
31594
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",
|
|
31595
31625
|
"note"
|
|
31596
31626
|
];
|
|
31597
31627
|
SessionEventEnvelopeSchema = external_exports.object({
|
|
@@ -33917,16 +33947,16 @@ function runRetentionFromEnv() {
|
|
|
33917
33947
|
maxTotalBytes: Number.isFinite(parseMb) && parseMb > 0 ? Math.round(parseMb * 1024 * 1024) : DEFAULT_RUN_RETENTION_MAX_MB * 1024 * 1024
|
|
33918
33948
|
};
|
|
33919
33949
|
}
|
|
33920
|
-
async function dirSize(
|
|
33950
|
+
async function dirSize(path91) {
|
|
33921
33951
|
let total = 0;
|
|
33922
33952
|
let entries;
|
|
33923
33953
|
try {
|
|
33924
|
-
entries = await readdir(
|
|
33954
|
+
entries = await readdir(path91, { withFileTypes: true });
|
|
33925
33955
|
} catch {
|
|
33926
33956
|
return 0;
|
|
33927
33957
|
}
|
|
33928
33958
|
for (const entry of entries) {
|
|
33929
|
-
const child = join13(
|
|
33959
|
+
const child = join13(path91, entry.name);
|
|
33930
33960
|
if (entry.isDirectory())
|
|
33931
33961
|
total += await dirSize(child);
|
|
33932
33962
|
else {
|
|
@@ -33953,19 +33983,19 @@ async function enforceRunRetention(runsDir, options = {}) {
|
|
|
33953
33983
|
for (const entry of entries) {
|
|
33954
33984
|
if (!entry.isDirectory())
|
|
33955
33985
|
continue;
|
|
33956
|
-
const
|
|
33986
|
+
const path91 = join13(runsDir, entry.name);
|
|
33957
33987
|
let startedAt = 0;
|
|
33958
33988
|
let endedAt;
|
|
33959
33989
|
let completed = false;
|
|
33960
33990
|
try {
|
|
33961
|
-
const manifest = JSON.parse(await readFile(join13(
|
|
33991
|
+
const manifest = JSON.parse(await readFile(join13(path91, "manifest.json"), "utf8"));
|
|
33962
33992
|
startedAt = manifest.startedAt ?? 0;
|
|
33963
33993
|
endedAt = manifest.endedAt;
|
|
33964
33994
|
completed = Boolean(endedAt) && manifest.status !== "running";
|
|
33965
33995
|
} catch {
|
|
33966
33996
|
completed = false;
|
|
33967
33997
|
}
|
|
33968
|
-
infos.push({ name: entry.name, path:
|
|
33998
|
+
infos.push({ name: entry.name, path: path91, startedAt, endedAt, completed, bytes: await dirSize(path91) });
|
|
33969
33999
|
}
|
|
33970
34000
|
const remove = async (info) => {
|
|
33971
34001
|
await rm(info.path, { recursive: true, force: true });
|
|
@@ -34737,12 +34767,12 @@ var init_engine = __esm({
|
|
|
34737
34767
|
* content digest) and the returned ref carries the event seq when the
|
|
34738
34768
|
* emitter resolved one.
|
|
34739
34769
|
*/
|
|
34740
|
-
async fsEvidence(observation,
|
|
34770
|
+
async fsEvidence(observation, path91, sha256, content, extra = {}) {
|
|
34741
34771
|
const digest = sha256 && content !== void 0 ? sha256(content) : void 0;
|
|
34742
|
-
const seq = await this.emitEvidence({ observation, path:
|
|
34772
|
+
const seq = await this.emitEvidence({ observation, path: path91, ...extra, ...digest ? { digest } : {} });
|
|
34743
34773
|
return {
|
|
34744
34774
|
tier: "fs-observation",
|
|
34745
|
-
ref:
|
|
34775
|
+
ref: path91,
|
|
34746
34776
|
capturedAt: Date.now(),
|
|
34747
34777
|
...digest ? { digest } : {},
|
|
34748
34778
|
...seq !== void 0 ? { seq } : {}
|
|
@@ -35782,6 +35812,8 @@ __export(dist_exports, {
|
|
|
35782
35812
|
TEXT_LOOP_RECOVERY_SYSTEM: () => TEXT_LOOP_RECOVERY_SYSTEM,
|
|
35783
35813
|
TEXT_LOOP_RECOVERY_USER_PROMPT: () => TEXT_LOOP_RECOVERY_USER_PROMPT,
|
|
35784
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,
|
|
35785
35817
|
TOOL_DEFINITIONS: () => TOOL_DEFINITIONS,
|
|
35786
35818
|
TOOL_USE_PROTOCOL_DIRECTIVE: () => TOOL_USE_PROTOCOL_DIRECTIVE,
|
|
35787
35819
|
TURN_COMPLETION_MODULE: () => TURN_COMPLETION_MODULE,
|
|
@@ -37083,6 +37115,15 @@ function mapBrainEventToSpine(ev) {
|
|
|
37083
37115
|
...ev.memberName ? { member: ev.memberName } : {}
|
|
37084
37116
|
}
|
|
37085
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;
|
|
37086
37127
|
default:
|
|
37087
37128
|
return null;
|
|
37088
37129
|
}
|
|
@@ -37126,15 +37167,8 @@ async function noteHarnessLifecycle(spine, sessionId2, profileId, budget, baseDi
|
|
|
37126
37167
|
resourcePolicy: budget.policy
|
|
37127
37168
|
});
|
|
37128
37169
|
if (spine.resumedFromSeq !== void 0 && spine.resumedFromSeq > 0) {
|
|
37129
|
-
|
|
37130
|
-
if (original === null) {
|
|
37170
|
+
if (await lastHarnessManifestHash(sessionId2, baseDir) === null) {
|
|
37131
37171
|
spine.harnessManifest(manifest, manifestHash);
|
|
37132
|
-
} else if (original !== manifestHash) {
|
|
37133
|
-
await spine.appendEvent({
|
|
37134
|
-
kind: "session.harness_drift",
|
|
37135
|
-
actor: ACTOR_SYSTEM,
|
|
37136
|
-
data: { originalManifestHash: original, currentManifestHash: manifestHash }
|
|
37137
|
-
});
|
|
37138
37172
|
}
|
|
37139
37173
|
} else {
|
|
37140
37174
|
spine.harnessManifest(manifest, manifestHash);
|
|
@@ -37146,6 +37180,7 @@ var MAX_STREAM_BUFFERS, SessionSpineMirror, SpineMirroringWriter;
|
|
|
37146
37180
|
var init_sessionSpine = __esm({
|
|
37147
37181
|
"src/cli/sessionSpine.ts"() {
|
|
37148
37182
|
"use strict";
|
|
37183
|
+
init_harness();
|
|
37149
37184
|
init_session();
|
|
37150
37185
|
init_session();
|
|
37151
37186
|
init_verification2();
|
|
@@ -37892,9 +37927,9 @@ function spillToolOutput(fullText, meta3) {
|
|
|
37892
37927
|
const rnd = randomBytes3(3).toString("hex");
|
|
37893
37928
|
const safeTool = (meta3?.toolName ?? "tool").replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 32);
|
|
37894
37929
|
const file2 = `${stamp}-${safeTool}-${hash3}-${rnd}.txt`;
|
|
37895
|
-
const
|
|
37896
|
-
writeFileSync11(
|
|
37897
|
-
return
|
|
37930
|
+
const path91 = join14(dir, file2);
|
|
37931
|
+
writeFileSync11(path91, fullText, "utf8");
|
|
37932
|
+
return path91;
|
|
37898
37933
|
} catch {
|
|
37899
37934
|
return null;
|
|
37900
37935
|
}
|
|
@@ -37940,10 +37975,10 @@ function truncateToolResult(text, capOrOpts = TOOL_RESULT_LINE_CAP) {
|
|
|
37940
37975
|
${tail2}`;
|
|
37941
37976
|
}
|
|
37942
37977
|
if (doSpill) {
|
|
37943
|
-
const
|
|
37944
|
-
if (
|
|
37978
|
+
const path91 = spillToolOutput(text, { toolName: opts.toolName });
|
|
37979
|
+
if (path91) {
|
|
37945
37980
|
const spillNote = `
|
|
37946
|
-
\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`;
|
|
37947
37982
|
if (preview.includes("] \u2026\n")) {
|
|
37948
37983
|
preview = preview.replace("] \u2026\n", `] \u2026${spillNote}
|
|
37949
37984
|
`);
|
|
@@ -41056,28 +41091,28 @@ var init_storage = __esm({
|
|
|
41056
41091
|
VALID_SCALARS = /^(true|false|null|~)$/i;
|
|
41057
41092
|
Storage = class {
|
|
41058
41093
|
/** Read a Markdown file with frontmatter. Throws if not found. */
|
|
41059
|
-
read(
|
|
41060
|
-
if (!existsSync19(
|
|
41061
|
-
throw new Error(`File not found: ${
|
|
41094
|
+
read(path91) {
|
|
41095
|
+
if (!existsSync19(path91)) {
|
|
41096
|
+
throw new Error(`File not found: ${path91}`);
|
|
41062
41097
|
}
|
|
41063
|
-
const md = readFileSync16(
|
|
41098
|
+
const md = readFileSync16(path91, "utf8");
|
|
41064
41099
|
return parseFrontmatter(md);
|
|
41065
41100
|
}
|
|
41066
41101
|
/** Read a Markdown file; returns null if not found. */
|
|
41067
|
-
readIfExists(
|
|
41068
|
-
if (!existsSync19(
|
|
41069
|
-
return this.read(
|
|
41102
|
+
readIfExists(path91) {
|
|
41103
|
+
if (!existsSync19(path91)) return null;
|
|
41104
|
+
return this.read(path91);
|
|
41070
41105
|
}
|
|
41071
41106
|
/**
|
|
41072
41107
|
* Write a Markdown file atomically (tmp + rename). Creates parent dirs.
|
|
41073
41108
|
* The meta object is serialized as YAML frontmatter; body as Markdown.
|
|
41074
41109
|
*/
|
|
41075
|
-
write(
|
|
41076
|
-
mkdirSync10(dirname2(
|
|
41077
|
-
const tmp =
|
|
41110
|
+
write(path91, meta3, body) {
|
|
41111
|
+
mkdirSync10(dirname2(path91), { recursive: true });
|
|
41112
|
+
const tmp = path91 + ".tmp-" + process.pid;
|
|
41078
41113
|
const md = serializeFrontmatter(meta3, body);
|
|
41079
41114
|
writeFileSync13(tmp, md, "utf8");
|
|
41080
|
-
renameSync(tmp,
|
|
41115
|
+
renameSync(tmp, path91);
|
|
41081
41116
|
}
|
|
41082
41117
|
/** List all .md files in a directory (non-recursive). */
|
|
41083
41118
|
listMarkdown(dir) {
|
|
@@ -41139,8 +41174,8 @@ function nextPlanTaskId(store6) {
|
|
|
41139
41174
|
return `t${store6.counter}`;
|
|
41140
41175
|
}
|
|
41141
41176
|
function writePlanTaskArtifact(rootDir, task) {
|
|
41142
|
-
const
|
|
41143
|
-
mkdirSync11(dirname3(
|
|
41177
|
+
const path91 = join18(rootDir, "plan-tasks", `${task.id}.md`);
|
|
41178
|
+
mkdirSync11(dirname3(path91), { recursive: true });
|
|
41144
41179
|
const meta3 = {
|
|
41145
41180
|
kind: "task",
|
|
41146
41181
|
id: task.id,
|
|
@@ -41161,7 +41196,7 @@ function writePlanTaskArtifact(rootDir, task) {
|
|
|
41161
41196
|
task.notes?.trim() ? task.notes.trim() : "_(no notes)_",
|
|
41162
41197
|
""
|
|
41163
41198
|
].filter((l) => l !== null).join("\n");
|
|
41164
|
-
new Storage().write(
|
|
41199
|
+
new Storage().write(path91, meta3, body);
|
|
41165
41200
|
}
|
|
41166
41201
|
function loadHandle(rootDir) {
|
|
41167
41202
|
const jsonPath = join18(rootDir, "plan.json");
|
|
@@ -42960,6 +42995,7 @@ var init_servers = __esm({
|
|
|
42960
42995
|
// src/cli/lsp/manager.ts
|
|
42961
42996
|
import { spawn as spawn10 } from "node:child_process";
|
|
42962
42997
|
import { readFileSync as readFileSync18 } from "node:fs";
|
|
42998
|
+
import path34 from "node:path";
|
|
42963
42999
|
function processTransport(child) {
|
|
42964
43000
|
return {
|
|
42965
43001
|
send: (data) => {
|
|
@@ -42976,12 +43012,22 @@ function processTransport(child) {
|
|
|
42976
43012
|
};
|
|
42977
43013
|
}
|
|
42978
43014
|
function getSharedLspManager(cwd = process.cwd()) {
|
|
42979
|
-
|
|
42980
|
-
|
|
43015
|
+
const key = path34.resolve(cwd);
|
|
43016
|
+
const existing = sharedByRoot.get(key);
|
|
43017
|
+
if (existing) return existing;
|
|
42981
43018
|
const manager = new LspManager({ cwd });
|
|
42982
|
-
|
|
43019
|
+
sharedByRoot.set(key, manager);
|
|
42983
43020
|
return manager;
|
|
42984
43021
|
}
|
|
43022
|
+
function disposeSharedLspManager() {
|
|
43023
|
+
for (const manager of sharedByRoot.values()) {
|
|
43024
|
+
try {
|
|
43025
|
+
manager.dispose();
|
|
43026
|
+
} catch {
|
|
43027
|
+
}
|
|
43028
|
+
}
|
|
43029
|
+
sharedByRoot.clear();
|
|
43030
|
+
}
|
|
42985
43031
|
function normalizeLocations(res) {
|
|
42986
43032
|
if (!res) return [];
|
|
42987
43033
|
const arr = Array.isArray(res) ? res : [res];
|
|
@@ -43048,7 +43094,7 @@ function normalizeRename(res) {
|
|
|
43048
43094
|
if (files.length === 0) return null;
|
|
43049
43095
|
return { files, totalEdits: total };
|
|
43050
43096
|
}
|
|
43051
|
-
var SYMBOL_KINDS, LspManager,
|
|
43097
|
+
var SYMBOL_KINDS, LspManager, sharedByRoot;
|
|
43052
43098
|
var init_manager = __esm({
|
|
43053
43099
|
"src/cli/lsp/manager.ts"() {
|
|
43054
43100
|
"use strict";
|
|
@@ -43271,11 +43317,11 @@ var init_manager = __esm({
|
|
|
43271
43317
|
this.servers.clear();
|
|
43272
43318
|
}
|
|
43273
43319
|
};
|
|
43274
|
-
|
|
43320
|
+
sharedByRoot = /* @__PURE__ */ new Map();
|
|
43275
43321
|
if (typeof process !== "undefined" && typeof process.once === "function") {
|
|
43276
43322
|
process.once("exit", () => {
|
|
43277
43323
|
try {
|
|
43278
|
-
|
|
43324
|
+
disposeSharedLspManager();
|
|
43279
43325
|
} catch {
|
|
43280
43326
|
}
|
|
43281
43327
|
});
|
|
@@ -43285,9 +43331,9 @@ var init_manager = __esm({
|
|
|
43285
43331
|
|
|
43286
43332
|
// src/cli/ast/engine.ts
|
|
43287
43333
|
import { readFile as readFile2 } from "node:fs/promises";
|
|
43288
|
-
import
|
|
43334
|
+
import path35 from "node:path";
|
|
43289
43335
|
function isAstSupported(file2) {
|
|
43290
|
-
return TS_EXTENSIONS.has(
|
|
43336
|
+
return TS_EXTENSIONS.has(path35.extname(file2).toLowerCase());
|
|
43291
43337
|
}
|
|
43292
43338
|
function loadTs() {
|
|
43293
43339
|
if (!tsPromise) {
|
|
@@ -43299,8 +43345,8 @@ function errMessage(err) {
|
|
|
43299
43345
|
return err instanceof Error ? err.message : String(err);
|
|
43300
43346
|
}
|
|
43301
43347
|
async function parseFileSymbolsDiag(file2, cwd) {
|
|
43302
|
-
const resolvedPath =
|
|
43303
|
-
const extension =
|
|
43348
|
+
const resolvedPath = path35.isAbsolute(file2) ? file2 : path35.join(cwd ?? process.cwd(), file2);
|
|
43349
|
+
const extension = path35.extname(resolvedPath).toLowerCase();
|
|
43304
43350
|
if (!TS_EXTENSIONS.has(extension)) {
|
|
43305
43351
|
return {
|
|
43306
43352
|
status: "unsupported-extension",
|
|
@@ -43342,7 +43388,7 @@ async function parseFileSymbolsDiag(file2, cwd) {
|
|
|
43342
43388
|
}
|
|
43343
43389
|
let source2;
|
|
43344
43390
|
try {
|
|
43345
|
-
source2 = ts.createSourceFile(
|
|
43391
|
+
source2 = ts.createSourceFile(path35.basename(resolvedPath), text, ts.ScriptTarget.Latest, true);
|
|
43346
43392
|
} catch (err) {
|
|
43347
43393
|
return {
|
|
43348
43394
|
status: "parse-error",
|
|
@@ -43567,11 +43613,11 @@ var init_store2 = __esm({
|
|
|
43567
43613
|
// src/cli/semantic/index.ts
|
|
43568
43614
|
import { promises as fs18, existsSync as existsSync24, readFileSync as readFileSync19 } from "node:fs";
|
|
43569
43615
|
import { homedir as homedir7 } from "node:os";
|
|
43570
|
-
import
|
|
43616
|
+
import path36 from "node:path";
|
|
43571
43617
|
import { createHash as createHash12 } from "node:crypto";
|
|
43572
43618
|
function getIndexPath(root) {
|
|
43573
|
-
const hash3 = createHash12("sha1").update(
|
|
43574
|
-
return process.env.ZELARI_SEMANTIC_FILE ??
|
|
43619
|
+
const hash3 = createHash12("sha1").update(path36.resolve(root)).digest("hex").slice(0, 16);
|
|
43620
|
+
return process.env.ZELARI_SEMANTIC_FILE ?? path36.join(homedir7(), ".tmp", "zelari-code", "semantic", `${hash3}.json`);
|
|
43575
43621
|
}
|
|
43576
43622
|
async function collectSourceFiles(root, maxFiles = 1500) {
|
|
43577
43623
|
const out = [];
|
|
@@ -43589,11 +43635,11 @@ async function collectSourceFiles(root, maxFiles = 1500) {
|
|
|
43589
43635
|
if (entry.isDirectory() && IGNORE_DIRS.has(entry.name)) continue;
|
|
43590
43636
|
if (entry.isDirectory()) continue;
|
|
43591
43637
|
}
|
|
43592
|
-
const full =
|
|
43638
|
+
const full = path36.join(dir, entry.name);
|
|
43593
43639
|
if (entry.isDirectory()) {
|
|
43594
43640
|
if (IGNORE_DIRS.has(entry.name)) continue;
|
|
43595
43641
|
await walk2(full);
|
|
43596
|
-
} else if (SOURCE_EXTENSIONS.has(
|
|
43642
|
+
} else if (SOURCE_EXTENSIONS.has(path36.extname(entry.name).toLowerCase())) {
|
|
43597
43643
|
out.push(full);
|
|
43598
43644
|
}
|
|
43599
43645
|
}
|
|
@@ -43642,7 +43688,7 @@ async function buildIndex(files, embed, options) {
|
|
|
43642
43688
|
}
|
|
43643
43689
|
async function saveIndex(root, data) {
|
|
43644
43690
|
const file2 = getIndexPath(root);
|
|
43645
|
-
await fs18.mkdir(
|
|
43691
|
+
await fs18.mkdir(path36.dirname(file2), { recursive: true });
|
|
43646
43692
|
const tmp = `${file2}.tmp-${process.pid}`;
|
|
43647
43693
|
await fs18.writeFile(tmp, JSON.stringify(data), "utf8");
|
|
43648
43694
|
await fs18.rename(tmp, file2);
|
|
@@ -44524,7 +44570,7 @@ var init_provider = __esm({
|
|
|
44524
44570
|
});
|
|
44525
44571
|
|
|
44526
44572
|
// src/cli/semantic/tools.ts
|
|
44527
|
-
import
|
|
44573
|
+
import path37 from "node:path";
|
|
44528
44574
|
function createSemanticTool(deps) {
|
|
44529
44575
|
const buildEmbedFn = deps.buildEmbedFn ?? buildProviderEmbedFn;
|
|
44530
44576
|
return {
|
|
@@ -44551,7 +44597,7 @@ function createSemanticTool(deps) {
|
|
|
44551
44597
|
return typedOk({
|
|
44552
44598
|
count: res.hits.length,
|
|
44553
44599
|
results: res.hits.map((h) => ({
|
|
44554
|
-
location: `${
|
|
44600
|
+
location: `${path37.relative(deps.root, h.file) || h.file}:${h.startLine}-${h.endLine}`,
|
|
44555
44601
|
score: Number(h.score.toFixed(3)),
|
|
44556
44602
|
preview: h.text.length > 400 ? `${h.text.slice(0, 400)}\u2026` : h.text
|
|
44557
44603
|
}))
|
|
@@ -44571,7 +44617,7 @@ var init_tools4 = __esm({
|
|
|
44571
44617
|
|
|
44572
44618
|
// src/cli/browser/driver.ts
|
|
44573
44619
|
import { createRequire as createRequire2 } from "node:module";
|
|
44574
|
-
import
|
|
44620
|
+
import path38 from "node:path";
|
|
44575
44621
|
import { pathToFileURL } from "node:url";
|
|
44576
44622
|
function asPlaywright(mod) {
|
|
44577
44623
|
if (!mod || typeof mod !== "object") return null;
|
|
@@ -44582,10 +44628,10 @@ function asPlaywright(mod) {
|
|
|
44582
44628
|
return null;
|
|
44583
44629
|
}
|
|
44584
44630
|
async function loadPlaywright(cwd) {
|
|
44585
|
-
const base2 = cwd && cwd.length > 0 ?
|
|
44631
|
+
const base2 = cwd && cwd.length > 0 ? path38.resolve(cwd) : void 0;
|
|
44586
44632
|
if (base2) {
|
|
44587
44633
|
try {
|
|
44588
|
-
const req = createRequire2(
|
|
44634
|
+
const req = createRequire2(path38.join(base2, "package.json"));
|
|
44589
44635
|
const resolved = req.resolve("playwright");
|
|
44590
44636
|
const mod = await import(pathToFileURL(resolved).href);
|
|
44591
44637
|
const pw = asPlaywright(mod);
|
|
@@ -44800,7 +44846,7 @@ var init_driver = __esm({
|
|
|
44800
44846
|
});
|
|
44801
44847
|
|
|
44802
44848
|
// src/cli/browser/tools.ts
|
|
44803
|
-
import
|
|
44849
|
+
import path39 from "node:path";
|
|
44804
44850
|
import os8 from "node:os";
|
|
44805
44851
|
function createBrowserTool(deps = {}) {
|
|
44806
44852
|
return {
|
|
@@ -44819,7 +44865,7 @@ function createBrowserTool(deps = {}) {
|
|
|
44819
44865
|
execute: async (args, ctx) => {
|
|
44820
44866
|
const a = args;
|
|
44821
44867
|
const dir = deps.screenshotDir ?? os8.tmpdir();
|
|
44822
|
-
const screenshotPath = a.screenshot === false ? void 0 :
|
|
44868
|
+
const screenshotPath = a.screenshot === false ? void 0 : path39.join(dir, `zelari-browser-${Date.now()}.png`);
|
|
44823
44869
|
const result = await runBrowserCheck(
|
|
44824
44870
|
{
|
|
44825
44871
|
url: a.url,
|
|
@@ -44931,21 +44977,21 @@ function normalizeAuth(auth) {
|
|
|
44931
44977
|
return "agent";
|
|
44932
44978
|
}
|
|
44933
44979
|
function readSecrets() {
|
|
44934
|
-
const
|
|
44935
|
-
if (!existsSync25(
|
|
44980
|
+
const path91 = getSshSecretsPath();
|
|
44981
|
+
if (!existsSync25(path91)) return {};
|
|
44936
44982
|
try {
|
|
44937
|
-
return JSON.parse(readFileSync20(
|
|
44983
|
+
return JSON.parse(readFileSync20(path91, "utf8"));
|
|
44938
44984
|
} catch {
|
|
44939
44985
|
return {};
|
|
44940
44986
|
}
|
|
44941
44987
|
}
|
|
44942
44988
|
function writeSecrets(data) {
|
|
44943
|
-
const
|
|
44944
|
-
mkdirSync12(dirname4(
|
|
44945
|
-
writeFileSync15(
|
|
44989
|
+
const path91 = getSshSecretsPath();
|
|
44990
|
+
mkdirSync12(dirname4(path91), { recursive: true });
|
|
44991
|
+
writeFileSync15(path91, `${JSON.stringify(data, null, 2)}
|
|
44946
44992
|
`, "utf8");
|
|
44947
44993
|
try {
|
|
44948
|
-
chmodSync(
|
|
44994
|
+
chmodSync(path91, 384);
|
|
44949
44995
|
} catch {
|
|
44950
44996
|
}
|
|
44951
44997
|
}
|
|
@@ -44974,10 +45020,10 @@ function deleteSshPassword(id3) {
|
|
|
44974
45020
|
writeSecrets({ passwords });
|
|
44975
45021
|
}
|
|
44976
45022
|
function readStore2() {
|
|
44977
|
-
const
|
|
44978
|
-
if (!existsSync25(
|
|
45023
|
+
const path91 = getSshTargetsPath();
|
|
45024
|
+
if (!existsSync25(path91)) return [];
|
|
44979
45025
|
try {
|
|
44980
|
-
const parsed = JSON.parse(readFileSync20(
|
|
45026
|
+
const parsed = JSON.parse(readFileSync20(path91, "utf8"));
|
|
44981
45027
|
const list = Array.isArray(parsed.targets) ? parsed.targets : [];
|
|
44982
45028
|
return list.filter(
|
|
44983
45029
|
(t) => t && typeof t.id === "string" && typeof t.host === "string" && typeof t.user === "string"
|
|
@@ -44992,11 +45038,11 @@ function readStore2() {
|
|
|
44992
45038
|
}
|
|
44993
45039
|
}
|
|
44994
45040
|
function writeStore2(targets) {
|
|
44995
|
-
const
|
|
44996
|
-
mkdirSync12(dirname4(
|
|
45041
|
+
const path91 = getSshTargetsPath();
|
|
45042
|
+
mkdirSync12(dirname4(path91), { recursive: true });
|
|
44997
45043
|
const clean = targets.map(({ hasPassword: _hp, ...t }) => t);
|
|
44998
45044
|
writeFileSync15(
|
|
44999
|
-
|
|
45045
|
+
path91,
|
|
45000
45046
|
`${JSON.stringify({ targets: clean }, null, 2)}
|
|
45001
45047
|
`,
|
|
45002
45048
|
"utf8"
|
|
@@ -45242,11 +45288,11 @@ function formatSshTargetsForPrompt() {
|
|
|
45242
45288
|
];
|
|
45243
45289
|
for (const t of targets) {
|
|
45244
45290
|
const tags = t.tags?.length ? ` tags=[${t.tags.join(",")}]` : "";
|
|
45245
|
-
const
|
|
45291
|
+
const path91 = t.defaultRemotePath ? ` remotePath=${t.defaultRemotePath}` : "";
|
|
45246
45292
|
const allow = t.allowedCommands?.length ? ` allowed=${t.allowedCommands.join("|")}` : " allowed=status-only";
|
|
45247
45293
|
const auth = t.auth === "password" ? " auth=password" : t.auth === "keyPath" ? " auth=key" : " auth=agent";
|
|
45248
45294
|
lines.push(
|
|
45249
|
-
`- 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}`
|
|
45250
45296
|
);
|
|
45251
45297
|
}
|
|
45252
45298
|
return lines.join("\n");
|
|
@@ -45373,10 +45419,10 @@ var init_tools6 = __esm({
|
|
|
45373
45419
|
|
|
45374
45420
|
// src/cli/workspace/worldModel.ts
|
|
45375
45421
|
import { promises as fs19 } from "node:fs";
|
|
45376
|
-
import
|
|
45422
|
+
import path40 from "node:path";
|
|
45377
45423
|
import { spawn as spawn12 } from "node:child_process";
|
|
45378
45424
|
function worldDir(cwd) {
|
|
45379
|
-
return
|
|
45425
|
+
return path40.join(cwd, WORLD_DIR_NAME);
|
|
45380
45426
|
}
|
|
45381
45427
|
async function ensureWorldDir(cwd) {
|
|
45382
45428
|
const dir = worldDir(cwd);
|
|
@@ -45386,10 +45432,10 @@ async function ensureWorldDir(cwd) {
|
|
|
45386
45432
|
async function appendTimeline(cwd, entry) {
|
|
45387
45433
|
const dir = await ensureWorldDir(cwd);
|
|
45388
45434
|
const line = JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), ...entry }) + "\n";
|
|
45389
|
-
await fs19.appendFile(
|
|
45435
|
+
await fs19.appendFile(path40.join(dir, TIMELINE_FILE), line, "utf8");
|
|
45390
45436
|
}
|
|
45391
45437
|
async function readChecks(cwd) {
|
|
45392
|
-
const p3 =
|
|
45438
|
+
const p3 = path40.join(worldDir(cwd), CHECKS_FILE);
|
|
45393
45439
|
try {
|
|
45394
45440
|
const raw = await fs19.readFile(p3, "utf8");
|
|
45395
45441
|
const parsed = JSON.parse(raw);
|
|
@@ -45464,8 +45510,8 @@ function runShell(command, cwd, timeoutMs2, signal) {
|
|
|
45464
45510
|
});
|
|
45465
45511
|
}
|
|
45466
45512
|
async function runBacktest(cwd, signal) {
|
|
45467
|
-
const checksPath =
|
|
45468
|
-
const hypothesisPath =
|
|
45513
|
+
const checksPath = path40.join(worldDir(cwd), CHECKS_FILE);
|
|
45514
|
+
const hypothesisPath = path40.join(worldDir(cwd), HYPOTHESIS_FILE);
|
|
45469
45515
|
const checks = await readChecks(cwd);
|
|
45470
45516
|
if (checks.length === 0) {
|
|
45471
45517
|
return {
|
|
@@ -45534,7 +45580,7 @@ var init_worldModel = __esm({
|
|
|
45534
45580
|
"use strict";
|
|
45535
45581
|
init_zod();
|
|
45536
45582
|
init_toolTypes();
|
|
45537
|
-
WORLD_DIR_NAME =
|
|
45583
|
+
WORLD_DIR_NAME = path40.join(".zelari", "world");
|
|
45538
45584
|
HYPOTHESIS_FILE = "hypothesis.md";
|
|
45539
45585
|
CHECKS_FILE = "checks.json";
|
|
45540
45586
|
TIMELINE_FILE = "timeline.jsonl";
|
|
@@ -45551,7 +45597,7 @@ var init_worldModel = __esm({
|
|
|
45551
45597
|
execute: async (args, ctx) => {
|
|
45552
45598
|
try {
|
|
45553
45599
|
const dir = await ensureWorldDir(ctx.cwd);
|
|
45554
|
-
const file2 =
|
|
45600
|
+
const file2 = path40.join(dir, HYPOTHESIS_FILE);
|
|
45555
45601
|
if (args.append) {
|
|
45556
45602
|
const block = `
|
|
45557
45603
|
|
|
@@ -45590,7 +45636,7 @@ ${args.content}
|
|
|
45590
45636
|
execute: async (args, ctx) => {
|
|
45591
45637
|
try {
|
|
45592
45638
|
const dir = await ensureWorldDir(ctx.cwd);
|
|
45593
|
-
const file2 =
|
|
45639
|
+
const file2 = path40.join(dir, CHECKS_FILE);
|
|
45594
45640
|
const body = { checks: args.checks };
|
|
45595
45641
|
await fs19.writeFile(file2, JSON.stringify(body, null, 2) + "\n", "utf8");
|
|
45596
45642
|
await appendTimeline(ctx.cwd, { kind: "checks_set", count: args.checks.length });
|
|
@@ -45629,8 +45675,8 @@ ${args.content}
|
|
|
45629
45675
|
stdoutPreview: "(dryRun)",
|
|
45630
45676
|
mismatch: "dryRun"
|
|
45631
45677
|
})),
|
|
45632
|
-
hypothesisPath:
|
|
45633
|
-
checksPath:
|
|
45678
|
+
hypothesisPath: path40.join(worldDir(ctx.cwd), HYPOTHESIS_FILE),
|
|
45679
|
+
checksPath: path40.join(worldDir(ctx.cwd), CHECKS_FILE)
|
|
45634
45680
|
});
|
|
45635
45681
|
}
|
|
45636
45682
|
const result = await runBacktest(ctx.cwd, ctx.signal);
|
|
@@ -45654,7 +45700,7 @@ ${args.content}
|
|
|
45654
45700
|
execute: async (args, ctx) => {
|
|
45655
45701
|
try {
|
|
45656
45702
|
const dir = await ensureWorldDir(ctx.cwd);
|
|
45657
|
-
const file2 =
|
|
45703
|
+
const file2 = path40.join(dir, TIMELINE_FILE);
|
|
45658
45704
|
await appendTimeline(ctx.cwd, {
|
|
45659
45705
|
kind: args.kind,
|
|
45660
45706
|
summary: args.summary,
|
|
@@ -46317,12 +46363,12 @@ __export(folderTrust_exports, {
|
|
|
46317
46363
|
});
|
|
46318
46364
|
import { homedir as homedir9 } from "node:os";
|
|
46319
46365
|
import { existsSync as existsSync26, mkdirSync as mkdirSync13, readFileSync as readFileSync21, writeFileSync as writeFileSync16 } from "node:fs";
|
|
46320
|
-
import
|
|
46366
|
+
import path41 from "node:path";
|
|
46321
46367
|
function trustStorePath() {
|
|
46322
|
-
return _overrideStorePath ??
|
|
46368
|
+
return _overrideStorePath ?? path41.join(homedir9(), ".zelari-code", "trust.json");
|
|
46323
46369
|
}
|
|
46324
46370
|
function normalize4(p3) {
|
|
46325
|
-
const resolved =
|
|
46371
|
+
const resolved = path41.resolve(p3);
|
|
46326
46372
|
return process.platform === "win32" ? resolved.toLowerCase() : resolved;
|
|
46327
46373
|
}
|
|
46328
46374
|
function readStore3() {
|
|
@@ -46338,7 +46384,7 @@ function readStore3() {
|
|
|
46338
46384
|
function writeStore3(store6) {
|
|
46339
46385
|
const p3 = trustStorePath();
|
|
46340
46386
|
try {
|
|
46341
|
-
mkdirSync13(
|
|
46387
|
+
mkdirSync13(path41.dirname(p3), { recursive: true });
|
|
46342
46388
|
writeFileSync16(p3, JSON.stringify(store6, null, 2), "utf8");
|
|
46343
46389
|
} catch (err) {
|
|
46344
46390
|
throw new Error(
|
|
@@ -46364,7 +46410,7 @@ function isFolderTrusted(folderPath) {
|
|
|
46364
46410
|
}
|
|
46365
46411
|
function trustFolder(folderPath) {
|
|
46366
46412
|
const store6 = readStore3();
|
|
46367
|
-
const normalized =
|
|
46413
|
+
const normalized = path41.resolve(folderPath);
|
|
46368
46414
|
if (!store6.folders.some((f) => normalize4(f.path) === normalize4(normalized))) {
|
|
46369
46415
|
store6.folders.push({ path: normalized, trustedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
46370
46416
|
writeStore3(store6);
|
|
@@ -46548,7 +46594,7 @@ __export(policyEngine_exports, {
|
|
|
46548
46594
|
});
|
|
46549
46595
|
import { readFileSync as readFileSync22 } from "node:fs";
|
|
46550
46596
|
import { homedir as homedir11 } from "node:os";
|
|
46551
|
-
import
|
|
46597
|
+
import path42 from "node:path";
|
|
46552
46598
|
function emptyPolicySet() {
|
|
46553
46599
|
return { agents: /* @__PURE__ */ new Map(), warnings: [], precedence: policyPrecedenceFromEnv() };
|
|
46554
46600
|
}
|
|
@@ -46793,9 +46839,9 @@ function loadPolicySet(root, opts = {}) {
|
|
|
46793
46839
|
const mode = opts.mode ?? "permissive";
|
|
46794
46840
|
const warnings = [];
|
|
46795
46841
|
const precedence = policyPrecedenceFromEnv();
|
|
46796
|
-
const project = readPolicyFile(
|
|
46842
|
+
const project = readPolicyFile(path42.join(root, ".zelari", "policy.json"), warnings, mode);
|
|
46797
46843
|
const global = readPolicyFile(
|
|
46798
|
-
|
|
46844
|
+
path42.join(opts.homeDir ?? homedir11(), ".zelari", "policy.json"),
|
|
46799
46845
|
warnings,
|
|
46800
46846
|
mode
|
|
46801
46847
|
);
|
|
@@ -47232,7 +47278,7 @@ var init_resourceClaims = __esm({
|
|
|
47232
47278
|
// src/cli/toolResultCache.ts
|
|
47233
47279
|
import { createHash as createHash13 } from "node:crypto";
|
|
47234
47280
|
import { promises as fs20 } from "node:fs";
|
|
47235
|
-
import
|
|
47281
|
+
import path43 from "node:path";
|
|
47236
47282
|
function isToolCacheEnabled() {
|
|
47237
47283
|
const raw = process.env.ZELARI_TOOL_CACHE;
|
|
47238
47284
|
return raw !== "0" && raw !== "false" && raw !== "off";
|
|
@@ -47317,7 +47363,7 @@ async function statKey(toolName, input, ctx) {
|
|
|
47317
47363
|
if (!input || typeof input !== "object") return null;
|
|
47318
47364
|
const rawPath = input.path;
|
|
47319
47365
|
if (typeof rawPath !== "string" || rawPath.length === 0) return null;
|
|
47320
|
-
const abs =
|
|
47366
|
+
const abs = path43.isAbsolute(rawPath) ? rawPath : path43.join(ctx.cwd, rawPath);
|
|
47321
47367
|
try {
|
|
47322
47368
|
const st = await fs20.stat(abs);
|
|
47323
47369
|
return hashKey({
|
|
@@ -47459,13 +47505,13 @@ function resolveKrakenSubModel(agent, parentModel, env = process.env, opts = {})
|
|
|
47459
47505
|
const kindKey = agent === "explore" ? "ZELARI_KRAKEN_EXPLORE_MODEL" : agent === "verify" ? "ZELARI_KRAKEN_VERIFY_MODEL" : "ZELARI_KRAKEN_GENERAL_MODEL";
|
|
47460
47506
|
const specific = env[kindKey]?.trim();
|
|
47461
47507
|
if (specific) return specific;
|
|
47462
|
-
const
|
|
47463
|
-
if (
|
|
47508
|
+
const shared = env.ZELARI_KRAKEN_SUB_MODEL?.trim();
|
|
47509
|
+
if (shared) {
|
|
47464
47510
|
if (agent === "general" && !env.ZELARI_KRAKEN_GENERAL_MODEL) {
|
|
47465
|
-
if (env.ZELARI_KRAKEN_GENERAL_USES_SUB === "1") return
|
|
47511
|
+
if (env.ZELARI_KRAKEN_GENERAL_USES_SUB === "1") return shared;
|
|
47466
47512
|
return parentModel;
|
|
47467
47513
|
}
|
|
47468
|
-
return
|
|
47514
|
+
return shared;
|
|
47469
47515
|
}
|
|
47470
47516
|
if (agent === "verify" && opts.familyCandidates && opts.familyCandidates.length > 0) {
|
|
47471
47517
|
const picked = pickDifferentFamily(
|
|
@@ -47526,7 +47572,7 @@ __export(toolRegistry_exports, {
|
|
|
47526
47572
|
wrapWithSandbox: () => wrapWithSandbox
|
|
47527
47573
|
});
|
|
47528
47574
|
import { existsSync as existsSync27 } from "node:fs";
|
|
47529
|
-
import
|
|
47575
|
+
import path44 from "node:path";
|
|
47530
47576
|
function createBuiltinToolRegistry(options = {}) {
|
|
47531
47577
|
const root = options.root ?? process.cwd();
|
|
47532
47578
|
const audit = options.audit ?? new AuditLogger();
|
|
@@ -48084,14 +48130,14 @@ function wrapWithDiagnostics(original, root, runner) {
|
|
|
48084
48130
|
function claimedSourcePath(token, args, root) {
|
|
48085
48131
|
const cleaned = token.replace(/^["']|["']$/g, "");
|
|
48086
48132
|
if (!cleaned || cleaned.startsWith("-")) return null;
|
|
48087
|
-
if (!DIAG_SOURCE_EXTENSIONS.has(
|
|
48133
|
+
if (!DIAG_SOURCE_EXTENSIONS.has(path44.extname(cleaned).toLowerCase())) return null;
|
|
48088
48134
|
const bases = [root];
|
|
48089
48135
|
const cwd = args["cwd"];
|
|
48090
48136
|
if (typeof cwd === "string" && cwd.length > 0) {
|
|
48091
|
-
bases.unshift(
|
|
48137
|
+
bases.unshift(path44.isAbsolute(cwd) ? cwd : path44.resolve(root, cwd));
|
|
48092
48138
|
}
|
|
48093
48139
|
for (const base2 of bases) {
|
|
48094
|
-
const candidate =
|
|
48140
|
+
const candidate = path44.isAbsolute(cleaned) ? path44.normalize(cleaned) : path44.resolve(base2, cleaned);
|
|
48095
48141
|
try {
|
|
48096
48142
|
const contained = resolveSandboxedPath(candidate, { root });
|
|
48097
48143
|
if (existsSync27(contained)) return contained;
|
|
@@ -48379,7 +48425,7 @@ var init_toolRegistry = __esm({
|
|
|
48379
48425
|
|
|
48380
48426
|
// src/cli/metrics.ts
|
|
48381
48427
|
import { promises as fs21, existsSync as existsSync28, statSync as statSync4, renameSync as renameSync3, appendFileSync as appendFileSync3, mkdirSync as mkdirSync14 } from "node:fs";
|
|
48382
|
-
import
|
|
48428
|
+
import path45 from "node:path";
|
|
48383
48429
|
import os9 from "node:os";
|
|
48384
48430
|
async function readMetrics(file2) {
|
|
48385
48431
|
let raw = "";
|
|
@@ -48428,8 +48474,8 @@ var init_metrics3 = __esm({
|
|
|
48428
48474
|
file;
|
|
48429
48475
|
writeQueue = Promise.resolve();
|
|
48430
48476
|
constructor(file2) {
|
|
48431
|
-
this.file = file2 ?? process.env.ANATHEMA_METRICS_FILE ??
|
|
48432
|
-
mkdirSync14(
|
|
48477
|
+
this.file = file2 ?? process.env.ANATHEMA_METRICS_FILE ?? path45.join(os9.homedir(), ".tmp", "zelari-code", "metrics.jsonl");
|
|
48478
|
+
mkdirSync14(path45.dirname(this.file), { recursive: true });
|
|
48433
48479
|
}
|
|
48434
48480
|
/** Metrics file path — doctor/summary readers use this. */
|
|
48435
48481
|
get filePath() {
|
|
@@ -48752,7 +48798,7 @@ Current policy: **lead only**.
|
|
|
48752
48798
|
|
|
48753
48799
|
// src/cli/kraken/verificationAdapters/node.ts
|
|
48754
48800
|
import { readFile as readFile3, stat as stat2 } from "node:fs/promises";
|
|
48755
|
-
import
|
|
48801
|
+
import path46 from "node:path";
|
|
48756
48802
|
async function fileExists(candidate) {
|
|
48757
48803
|
try {
|
|
48758
48804
|
return (await stat2(candidate)).isFile();
|
|
@@ -48762,7 +48808,7 @@ async function fileExists(candidate) {
|
|
|
48762
48808
|
}
|
|
48763
48809
|
async function readPackageJson(root) {
|
|
48764
48810
|
try {
|
|
48765
|
-
return JSON.parse(await readFile3(
|
|
48811
|
+
return JSON.parse(await readFile3(path46.join(root, "package.json"), "utf-8"));
|
|
48766
48812
|
} catch {
|
|
48767
48813
|
return null;
|
|
48768
48814
|
}
|
|
@@ -48776,7 +48822,7 @@ async function resolvePackageManager(root) {
|
|
|
48776
48822
|
const fromField = packageManagerFromField(await readPackageJson(root));
|
|
48777
48823
|
if (fromField) return { pm: fromField, declaredToolchain: true };
|
|
48778
48824
|
for (const [marker, pm] of PM_LOCKFILES) {
|
|
48779
|
-
if (await fileExists(
|
|
48825
|
+
if (await fileExists(path46.join(root, marker))) return { pm, declaredToolchain: true };
|
|
48780
48826
|
}
|
|
48781
48827
|
return { pm: "npm", declaredToolchain: false };
|
|
48782
48828
|
}
|
|
@@ -48799,7 +48845,7 @@ var init_node = __esm({
|
|
|
48799
48845
|
KNOWN_PACKAGE_MANAGERS = /* @__PURE__ */ new Set(["npm", "pnpm", "yarn", "bun"]);
|
|
48800
48846
|
nodeAdapter = {
|
|
48801
48847
|
async detect(root) {
|
|
48802
|
-
if (!await fileExists(
|
|
48848
|
+
if (!await fileExists(path46.join(root, "package.json"))) return 0;
|
|
48803
48849
|
const { declaredToolchain } = await resolvePackageManager(root);
|
|
48804
48850
|
return declaredToolchain ? 20 : 10;
|
|
48805
48851
|
},
|
|
@@ -48818,7 +48864,7 @@ var init_node = __esm({
|
|
|
48818
48864
|
|
|
48819
48865
|
// src/cli/kraken/verificationAdapters/python.ts
|
|
48820
48866
|
import { readFile as readFile4, stat as stat3 } from "node:fs/promises";
|
|
48821
|
-
import
|
|
48867
|
+
import path47 from "node:path";
|
|
48822
48868
|
async function fileExists2(candidate) {
|
|
48823
48869
|
try {
|
|
48824
48870
|
return (await stat3(candidate)).isFile();
|
|
@@ -48854,7 +48900,7 @@ var init_python = __esm({
|
|
|
48854
48900
|
async detect(root) {
|
|
48855
48901
|
let best = 0;
|
|
48856
48902
|
for (const [marker, score] of DETECT_MARKERS) {
|
|
48857
|
-
if (score > best && await fileExists2(
|
|
48903
|
+
if (score > best && await fileExists2(path47.join(root, marker))) best = score;
|
|
48858
48904
|
}
|
|
48859
48905
|
return best;
|
|
48860
48906
|
},
|
|
@@ -48862,12 +48908,12 @@ var init_python = __esm({
|
|
|
48862
48908
|
const present = /* @__PURE__ */ new Map();
|
|
48863
48909
|
for (const name of SCAN_FILES) {
|
|
48864
48910
|
try {
|
|
48865
|
-
present.set(name, await readFile4(
|
|
48911
|
+
present.set(name, await readFile4(path47.join(root, name), "utf-8"));
|
|
48866
48912
|
} catch {
|
|
48867
48913
|
}
|
|
48868
48914
|
}
|
|
48869
48915
|
const hasToken = (token) => [...present.values()].some((text) => text.includes(token));
|
|
48870
|
-
const pytestEvidenced = hasToken("pytest") || await dirExists(
|
|
48916
|
+
const pytestEvidenced = hasToken("pytest") || await dirExists(path47.join(root, "tests"));
|
|
48871
48917
|
const mypyReferenced = hasToken("mypy") || present.has("mypy.ini") || present.has(".mypy.ini");
|
|
48872
48918
|
const pyrightReferenced = hasToken("pyright") || present.has("pyrightconfig.json");
|
|
48873
48919
|
return {
|
|
@@ -48883,7 +48929,7 @@ var init_python = __esm({
|
|
|
48883
48929
|
|
|
48884
48930
|
// src/cli/kraken/verificationAdapters/rust.ts
|
|
48885
48931
|
import { stat as stat4 } from "node:fs/promises";
|
|
48886
|
-
import
|
|
48932
|
+
import path48 from "node:path";
|
|
48887
48933
|
async function fileExists3(candidate) {
|
|
48888
48934
|
try {
|
|
48889
48935
|
return (await stat4(candidate)).isFile();
|
|
@@ -48897,7 +48943,7 @@ var init_rust = __esm({
|
|
|
48897
48943
|
"use strict";
|
|
48898
48944
|
rustAdapter = {
|
|
48899
48945
|
async detect(root) {
|
|
48900
|
-
return await fileExists3(
|
|
48946
|
+
return await fileExists3(path48.join(root, "Cargo.toml")) ? 10 : 0;
|
|
48901
48947
|
},
|
|
48902
48948
|
async buildPlan(_root) {
|
|
48903
48949
|
void _root;
|
|
@@ -48913,7 +48959,7 @@ var init_rust = __esm({
|
|
|
48913
48959
|
|
|
48914
48960
|
// src/cli/kraken/verificationAdapters/go.ts
|
|
48915
48961
|
import { stat as stat5 } from "node:fs/promises";
|
|
48916
|
-
import
|
|
48962
|
+
import path49 from "node:path";
|
|
48917
48963
|
async function fileExists4(candidate) {
|
|
48918
48964
|
try {
|
|
48919
48965
|
return (await stat5(candidate)).isFile();
|
|
@@ -48927,7 +48973,7 @@ var init_go = __esm({
|
|
|
48927
48973
|
"use strict";
|
|
48928
48974
|
goAdapter = {
|
|
48929
48975
|
async detect(root) {
|
|
48930
|
-
return await fileExists4(
|
|
48976
|
+
return await fileExists4(path49.join(root, "go.mod")) ? 10 : 0;
|
|
48931
48977
|
},
|
|
48932
48978
|
async buildPlan(_root) {
|
|
48933
48979
|
return {
|
|
@@ -48943,7 +48989,7 @@ var init_go = __esm({
|
|
|
48943
48989
|
|
|
48944
48990
|
// src/cli/kraken/verificationAdapters/java.ts
|
|
48945
48991
|
import { stat as stat6 } from "node:fs/promises";
|
|
48946
|
-
import
|
|
48992
|
+
import path50 from "node:path";
|
|
48947
48993
|
async function fileExists5(candidate) {
|
|
48948
48994
|
try {
|
|
48949
48995
|
return (await stat6(candidate)).isFile();
|
|
@@ -48953,13 +48999,13 @@ async function fileExists5(candidate) {
|
|
|
48953
48999
|
}
|
|
48954
49000
|
async function hasGradleMarker(root) {
|
|
48955
49001
|
for (const [marker] of GRADLE_MARKERS) {
|
|
48956
|
-
if (await fileExists5(
|
|
49002
|
+
if (await fileExists5(path50.join(root, marker))) return true;
|
|
48957
49003
|
}
|
|
48958
49004
|
return false;
|
|
48959
49005
|
}
|
|
48960
49006
|
async function gradleCommand(root, verb, platform = process.platform) {
|
|
48961
49007
|
const wrapper = platform === "win32" ? "gradlew.bat" : "gradlew";
|
|
48962
|
-
if (await fileExists5(
|
|
49008
|
+
if (await fileExists5(path50.join(root, wrapper))) {
|
|
48963
49009
|
return platform === "win32" ? `gradlew.bat ${verb}` : `./gradlew ${verb}`;
|
|
48964
49010
|
}
|
|
48965
49011
|
return `gradle ${verb}`;
|
|
@@ -48984,7 +49030,7 @@ var init_java = __esm({
|
|
|
48984
49030
|
async detect(root) {
|
|
48985
49031
|
let best = 0;
|
|
48986
49032
|
for (const [marker, score] of DETECT_MARKERS2) {
|
|
48987
|
-
if (score > best && await fileExists5(
|
|
49033
|
+
if (score > best && await fileExists5(path50.join(root, marker))) best = score;
|
|
48988
49034
|
}
|
|
48989
49035
|
return best;
|
|
48990
49036
|
},
|
|
@@ -48997,7 +49043,7 @@ var init_java = __esm({
|
|
|
48997
49043
|
buildCommand: await gradleCommand(root, "build")
|
|
48998
49044
|
};
|
|
48999
49045
|
}
|
|
49000
|
-
if (await fileExists5(
|
|
49046
|
+
if (await fileExists5(path50.join(root, "pom.xml"))) {
|
|
49001
49047
|
return {
|
|
49002
49048
|
typecheckCommand: null,
|
|
49003
49049
|
// compilation rides the test/package lifecycle
|
|
@@ -49106,7 +49152,7 @@ __export(nativeVerification_exports, {
|
|
|
49106
49152
|
resolvePackCommandsForRoot: () => resolvePackCommandsForRoot
|
|
49107
49153
|
});
|
|
49108
49154
|
import { readFile as readFile5 } from "node:fs/promises";
|
|
49109
|
-
import
|
|
49155
|
+
import path51 from "node:path";
|
|
49110
49156
|
function nativePackEnabled(env = process.env) {
|
|
49111
49157
|
const v = env.ZELARI_VERIFY_PACK?.toLowerCase();
|
|
49112
49158
|
if (v === "0" || v === "off" || v === "false") return false;
|
|
@@ -49149,7 +49195,7 @@ function packTimeoutMs(env = process.env) {
|
|
|
49149
49195
|
}
|
|
49150
49196
|
async function readPackageScripts(cwd = process.cwd()) {
|
|
49151
49197
|
try {
|
|
49152
|
-
const raw = await readFile5(
|
|
49198
|
+
const raw = await readFile5(path51.join(cwd, "package.json"), "utf-8");
|
|
49153
49199
|
const parsed = JSON.parse(raw);
|
|
49154
49200
|
if (parsed && typeof parsed === "object" && typeof parsed.scripts === "object") {
|
|
49155
49201
|
return parsed.scripts;
|
|
@@ -49195,16 +49241,28 @@ var init_nativeVerification = __esm({
|
|
|
49195
49241
|
|
|
49196
49242
|
// src/cli/kraken/verificationBridge.ts
|
|
49197
49243
|
import { createHash as createHash14 } from "node:crypto";
|
|
49198
|
-
function strictDoneEnabled(surface = "kraken") {
|
|
49244
|
+
function strictDoneEnabled(surface = "kraken", env = process.env) {
|
|
49199
49245
|
if (surface === "mission") {
|
|
49200
|
-
const v2 =
|
|
49246
|
+
const v2 = env.ZELARI_MISSION_STRICT;
|
|
49201
49247
|
if (v2 === "0" || v2 === "false") return false;
|
|
49202
49248
|
return true;
|
|
49203
49249
|
}
|
|
49204
|
-
const v =
|
|
49250
|
+
const v = env.ZELARI_STRICT_DONE;
|
|
49205
49251
|
if (v === "0" || v === "false") return false;
|
|
49206
49252
|
return true;
|
|
49207
49253
|
}
|
|
49254
|
+
function strictEnvOverlay(knobs, base2 = process.env) {
|
|
49255
|
+
const overlay = { ...base2 };
|
|
49256
|
+
if (knobs.strictDone !== void 0) {
|
|
49257
|
+
const v = knobs.strictDone ? "1" : "0";
|
|
49258
|
+
overlay.ZELARI_STRICT_DONE = v;
|
|
49259
|
+
overlay.ZELARI_MISSION_STRICT = v;
|
|
49260
|
+
}
|
|
49261
|
+
if (knobs.missionStrict !== void 0) {
|
|
49262
|
+
overlay.ZELARI_MISSION_STRICT = knobs.missionStrict ? "1" : "0";
|
|
49263
|
+
}
|
|
49264
|
+
return overlay;
|
|
49265
|
+
}
|
|
49208
49266
|
function criterionId(check2, index) {
|
|
49209
49267
|
const slug = check2.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48);
|
|
49210
49268
|
return `check-${index + 1}-${slug || "criterion"}`;
|
|
@@ -49341,7 +49399,7 @@ async function anchorSelectionEvidence(results, emit, toolTrace) {
|
|
|
49341
49399
|
}
|
|
49342
49400
|
async function evaluateStrictBuildGate(mode, options = {}) {
|
|
49343
49401
|
const gate = evaluateKrakenCompletionGate(mode);
|
|
49344
|
-
const strictOn = strictDoneEnabled(options.surface ?? "kraken");
|
|
49402
|
+
const strictOn = strictDoneEnabled(options.surface ?? "kraken", options.env);
|
|
49345
49403
|
const nativeOn = nativePackEnabled(options.env ?? process.env);
|
|
49346
49404
|
const selectionAvailable = gate.selectionUsed && gate.total > 0;
|
|
49347
49405
|
const scopeContract = options.taskContract ?? activeContractScope()?.contract;
|
|
@@ -49670,7 +49728,7 @@ var init_completionProofAttestation = __esm({
|
|
|
49670
49728
|
// src/cli/kraken/completionProofPersist.ts
|
|
49671
49729
|
import { open, rename, rm as rm2 } from "node:fs/promises";
|
|
49672
49730
|
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
49673
|
-
import
|
|
49731
|
+
import path52 from "node:path";
|
|
49674
49732
|
function isTruthyFlag2(v) {
|
|
49675
49733
|
const n = v?.trim().toLowerCase();
|
|
49676
49734
|
return n === "1" || n === "true" || n === "yes" || n === "on";
|
|
@@ -49712,8 +49770,8 @@ function isWindowsRenameBlock(err) {
|
|
|
49712
49770
|
return code === "EPERM" || code === "ENOTEMPTY" || code === "EEXIST";
|
|
49713
49771
|
}
|
|
49714
49772
|
async function writeFileAtomic(target, data) {
|
|
49715
|
-
const dir =
|
|
49716
|
-
const tmp =
|
|
49773
|
+
const dir = path52.dirname(target);
|
|
49774
|
+
const tmp = path52.join(dir, `.${path52.basename(target)}.${randomBytes5(6).toString("hex")}.tmp`);
|
|
49717
49775
|
let fh = null;
|
|
49718
49776
|
try {
|
|
49719
49777
|
fh = await open(tmp, "w");
|
|
@@ -49759,7 +49817,7 @@ var init_completionProofPersist = __esm({
|
|
|
49759
49817
|
|
|
49760
49818
|
// src/cli/kraken/completionProof.ts
|
|
49761
49819
|
import { mkdir as mkdir2 } from "node:fs/promises";
|
|
49762
|
-
import
|
|
49820
|
+
import path53 from "node:path";
|
|
49763
49821
|
function verdictOf(evaluation) {
|
|
49764
49822
|
return evaluation.evaluation?.verdict ?? (evaluation.blocked ? "BLOCKED" : "PASS");
|
|
49765
49823
|
}
|
|
@@ -49904,7 +49962,7 @@ async function writeCompletionProofDetailed(evaluation, options = {}) {
|
|
|
49904
49962
|
const mode = options.persistenceMode ?? activeProofPersistenceMode();
|
|
49905
49963
|
try {
|
|
49906
49964
|
const baseDir = options.baseDir ?? process.cwd();
|
|
49907
|
-
const dir =
|
|
49965
|
+
const dir = path53.join(baseDir, ".zelari");
|
|
49908
49966
|
await mkdir2(dir, { recursive: true });
|
|
49909
49967
|
const requested = options.attestation ?? {};
|
|
49910
49968
|
const plan = requested.skipProbes || requested.verificationPlan !== void 0 ? void 0 : await defaultVerificationPlanSnapshot(baseDir);
|
|
@@ -49924,8 +49982,8 @@ async function writeCompletionProofDetailed(evaluation, options = {}) {
|
|
|
49924
49982
|
baseDir
|
|
49925
49983
|
);
|
|
49926
49984
|
const rendered = renderCompletionProof(evaluation, options.meta ?? {}, wrapper.attestation);
|
|
49927
|
-
const markdownPath =
|
|
49928
|
-
const jsonPath =
|
|
49985
|
+
const markdownPath = path53.join(dir, "completion-proof.md");
|
|
49986
|
+
const jsonPath = path53.join(dir, "completion-proof.json");
|
|
49929
49987
|
await writeFileAtomic(markdownPath, rendered.markdown);
|
|
49930
49988
|
await writeFileAtomic(jsonPath, rendered.json);
|
|
49931
49989
|
return { paths: { markdownPath, jsonPath }, mode, requiredBlockReason: null };
|
|
@@ -49951,15 +50009,53 @@ var init_completionProof = __esm({
|
|
|
49951
50009
|
}
|
|
49952
50010
|
});
|
|
49953
50011
|
|
|
50012
|
+
// src/cli/memory/spineTelemetry.ts
|
|
50013
|
+
function spineMemoryEventNote(handle, event) {
|
|
50014
|
+
try {
|
|
50015
|
+
if (event.type === "memory_recall_end" && event.reason === "context-built") {
|
|
50016
|
+
handle.note("context.projection", {
|
|
50017
|
+
subject: "context.projection",
|
|
50018
|
+
...event.contextChars !== void 0 ? { contextChars: event.contextChars } : {},
|
|
50019
|
+
...event.returnedCount !== void 0 ? { returnedCount: event.returnedCount } : {},
|
|
50020
|
+
...event.durationMs !== void 0 ? { durationMs: event.durationMs } : {},
|
|
50021
|
+
...event.backend !== void 0 ? { backend: event.backend } : {}
|
|
50022
|
+
});
|
|
50023
|
+
return;
|
|
50024
|
+
}
|
|
50025
|
+
handle.note(`memory_${event.type}`, {
|
|
50026
|
+
subject: "memory_event",
|
|
50027
|
+
type: event.type,
|
|
50028
|
+
...event.durationMs !== void 0 ? { durationMs: event.durationMs } : {},
|
|
50029
|
+
...event.candidateCount !== void 0 ? { candidateCount: event.candidateCount } : {},
|
|
50030
|
+
...event.returnedCount !== void 0 ? { returnedCount: event.returnedCount } : {},
|
|
50031
|
+
...event.backend !== void 0 ? { backend: event.backend } : {},
|
|
50032
|
+
...event.reason !== void 0 ? { reason: event.reason } : {},
|
|
50033
|
+
...event.memoryId !== void 0 ? { memoryId: event.memoryId } : {}
|
|
50034
|
+
});
|
|
50035
|
+
} catch {
|
|
50036
|
+
}
|
|
50037
|
+
}
|
|
50038
|
+
function memorySinkFor(holder) {
|
|
50039
|
+
return (event) => {
|
|
50040
|
+
const handle = holder.current;
|
|
50041
|
+
if (handle) spineMemoryEventNote(handle, event);
|
|
50042
|
+
};
|
|
50043
|
+
}
|
|
50044
|
+
var init_spineTelemetry = __esm({
|
|
50045
|
+
"src/cli/memory/spineTelemetry.ts"() {
|
|
50046
|
+
"use strict";
|
|
50047
|
+
}
|
|
50048
|
+
});
|
|
50049
|
+
|
|
49954
50050
|
// src/cli/state/fileStateStore.ts
|
|
49955
50051
|
import { createHash as createHash16, randomUUID as randomUUID4 } from "node:crypto";
|
|
49956
50052
|
import { promises as fs22 } from "node:fs";
|
|
49957
|
-
import * as
|
|
50053
|
+
import * as path54 from "node:path";
|
|
49958
50054
|
function shortId() {
|
|
49959
50055
|
return randomUUID4().replace(/-/g, "").slice(0, 12);
|
|
49960
50056
|
}
|
|
49961
50057
|
async function writeJsonAtomic(filePath, data) {
|
|
49962
|
-
await fs22.mkdir(
|
|
50058
|
+
await fs22.mkdir(path54.dirname(filePath), { recursive: true });
|
|
49963
50059
|
const tmp = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
49964
50060
|
await fs22.writeFile(tmp, JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
49965
50061
|
await fs22.rename(tmp, filePath);
|
|
@@ -50020,11 +50116,11 @@ var init_fileStateStore = __esm({
|
|
|
50020
50116
|
indexPath = "";
|
|
50021
50117
|
async init(projectRoot) {
|
|
50022
50118
|
this.root = projectRoot;
|
|
50023
|
-
this.stateDir =
|
|
50024
|
-
this.commitsDir =
|
|
50025
|
-
this.artifactsDir =
|
|
50026
|
-
this.headPath =
|
|
50027
|
-
this.indexPath =
|
|
50119
|
+
this.stateDir = path54.join(projectRoot, ".zelari", "state");
|
|
50120
|
+
this.commitsDir = path54.join(this.stateDir, "commits");
|
|
50121
|
+
this.artifactsDir = path54.join(this.stateDir, "artifacts");
|
|
50122
|
+
this.headPath = path54.join(this.stateDir, "HEAD.json");
|
|
50123
|
+
this.indexPath = path54.join(this.stateDir, "index.jsonl");
|
|
50028
50124
|
await fs22.mkdir(this.commitsDir, { recursive: true });
|
|
50029
50125
|
await fs22.mkdir(this.artifactsDir, { recursive: true });
|
|
50030
50126
|
}
|
|
@@ -50037,13 +50133,13 @@ var init_fileStateStore = __esm({
|
|
|
50037
50133
|
const discoveries = input.discoveries ?? [];
|
|
50038
50134
|
const parent = await this.head();
|
|
50039
50135
|
const id3 = shortId();
|
|
50040
|
-
const artifactRel =
|
|
50041
|
-
const artifactAbs =
|
|
50136
|
+
const artifactRel = path54.join("artifacts", id3);
|
|
50137
|
+
const artifactAbs = path54.join(this.artifactsDir, id3);
|
|
50042
50138
|
await fs22.mkdir(artifactAbs, { recursive: true });
|
|
50043
50139
|
const summary = defaultSummary(input, discoveries);
|
|
50044
|
-
await fs22.writeFile(
|
|
50045
|
-
await writeJsonAtomic(
|
|
50046
|
-
await writeJsonAtomic(
|
|
50140
|
+
await fs22.writeFile(path54.join(artifactAbs, "summary.md"), summary + "\n", "utf8");
|
|
50141
|
+
await writeJsonAtomic(path54.join(artifactAbs, "discoveries.json"), discoveries);
|
|
50142
|
+
await writeJsonAtomic(path54.join(artifactAbs, "verification.json"), input.verification);
|
|
50047
50143
|
const meta3 = {
|
|
50048
50144
|
id: id3,
|
|
50049
50145
|
parentId: parent?.id ?? null,
|
|
@@ -50055,14 +50151,14 @@ var init_fileStateStore = __esm({
|
|
|
50055
50151
|
workspaceCheckpointId: input.workspaceCheckpointId,
|
|
50056
50152
|
verification: {
|
|
50057
50153
|
...input.verification,
|
|
50058
|
-
reportPath: input.verification.reportPath ??
|
|
50154
|
+
reportPath: input.verification.reportPath ?? path54.join(".zelari", "state", artifactRel, "verification.json").replace(/\\/g, "/")
|
|
50059
50155
|
},
|
|
50060
50156
|
changedPaths: input.changedPaths ?? [],
|
|
50061
50157
|
stablePromptHash: input.stablePromptHash,
|
|
50062
50158
|
discoveryCount: discoveries.length,
|
|
50063
50159
|
artifactDir: artifactRel.replace(/\\/g, "/")
|
|
50064
50160
|
};
|
|
50065
|
-
await writeJsonAtomic(
|
|
50161
|
+
await writeJsonAtomic(path54.join(this.commitsDir, `${id3}.json`), meta3);
|
|
50066
50162
|
await writeJsonAtomic(this.headPath, { id: id3, updatedAt: meta3.createdAt });
|
|
50067
50163
|
await fs22.appendFile(this.indexPath, JSON.stringify({ id: id3, createdAt: meta3.createdAt, label: meta3.label }) + "\n", "utf8");
|
|
50068
50164
|
return stripStored(meta3);
|
|
@@ -50073,7 +50169,7 @@ var init_fileStateStore = __esm({
|
|
|
50073
50169
|
return this.get(head.id);
|
|
50074
50170
|
}
|
|
50075
50171
|
async get(id3) {
|
|
50076
|
-
const stored = await readJsonFile(
|
|
50172
|
+
const stored = await readJsonFile(path54.join(this.commitsDir, `${id3}.json`));
|
|
50077
50173
|
return stored ? stripStored(stored) : null;
|
|
50078
50174
|
}
|
|
50079
50175
|
async list(limit = 20) {
|
|
@@ -50112,9 +50208,9 @@ var init_fileStateStore = __esm({
|
|
|
50112
50208
|
async loadDiscoveries(id3) {
|
|
50113
50209
|
const meta3 = id3 ? await this.get(id3) : await this.head();
|
|
50114
50210
|
if (!meta3) return [];
|
|
50115
|
-
const stored = await readJsonFile(
|
|
50211
|
+
const stored = await readJsonFile(path54.join(this.commitsDir, `${meta3.id}.json`));
|
|
50116
50212
|
if (!stored?.artifactDir) return [];
|
|
50117
|
-
const discPath =
|
|
50213
|
+
const discPath = path54.join(this.stateDir, stored.artifactDir, "discoveries.json");
|
|
50118
50214
|
return await readJsonFile(discPath) ?? [];
|
|
50119
50215
|
}
|
|
50120
50216
|
async materializeContext(id3, maxChars = DEFAULT_MATERIALIZE_CHARS) {
|
|
@@ -51367,10 +51463,10 @@ var init_mode = __esm({
|
|
|
51367
51463
|
|
|
51368
51464
|
// src/cli/headless.ts
|
|
51369
51465
|
import { readFileSync as readFileSync23 } from "node:fs";
|
|
51370
|
-
import
|
|
51466
|
+
import path55 from "node:path";
|
|
51371
51467
|
function resolveHeadlessCwd(opts) {
|
|
51372
51468
|
const raw = typeof opts.cwd === "string" ? opts.cwd.trim() : "";
|
|
51373
|
-
return
|
|
51469
|
+
return path55.resolve(raw.length > 0 ? raw : process.cwd());
|
|
51374
51470
|
}
|
|
51375
51471
|
function defaultProfileForMode(mode) {
|
|
51376
51472
|
switch (mode) {
|
|
@@ -51401,7 +51497,8 @@ function parseHeadlessFlags(argv) {
|
|
|
51401
51497
|
let profile;
|
|
51402
51498
|
let resumeSessionId;
|
|
51403
51499
|
let exportSessionPath;
|
|
51404
|
-
let strictDone
|
|
51500
|
+
let strictDone;
|
|
51501
|
+
let missionStrict;
|
|
51405
51502
|
let krakenGraph;
|
|
51406
51503
|
let planOnly = process.env.ZELARI_KRAKEN_PLAN_ONLY === "1" || process.env.ZELARI_KRAKEN_PLAN_ONLY === "true";
|
|
51407
51504
|
let runPlan = process.env.ZELARI_KRAKEN_RUN_PLAN;
|
|
@@ -51563,7 +51660,10 @@ function parseHeadlessFlags(argv) {
|
|
|
51563
51660
|
strictDone = true;
|
|
51564
51661
|
} else if (arg === "--no-strict-done") {
|
|
51565
51662
|
strictDone = false;
|
|
51566
|
-
|
|
51663
|
+
} else if (arg === "--mission-strict") {
|
|
51664
|
+
missionStrict = true;
|
|
51665
|
+
} else if (arg === "--no-mission-strict") {
|
|
51666
|
+
missionStrict = false;
|
|
51567
51667
|
} else if (arg === "--kraken-graph") {
|
|
51568
51668
|
krakenGraph = argv[i + 1];
|
|
51569
51669
|
i++;
|
|
@@ -51618,7 +51718,8 @@ function parseHeadlessFlags(argv) {
|
|
|
51618
51718
|
...profile ? { profile } : {},
|
|
51619
51719
|
...resumeSessionId ? { resumeSessionId } : {},
|
|
51620
51720
|
...exportSessionPath ? { exportSessionPath } : {},
|
|
51621
|
-
...strictDone ? { strictDone
|
|
51721
|
+
...strictDone !== void 0 ? { strictDone } : {},
|
|
51722
|
+
...missionStrict !== void 0 ? { missionStrict } : {},
|
|
51622
51723
|
...krakenGraph ? { krakenGraph } : {},
|
|
51623
51724
|
...planOnly ? { planOnly: true } : {},
|
|
51624
51725
|
...runPlan ? { runPlan } : {},
|
|
@@ -52305,7 +52406,7 @@ var init_claudeProvider = __esm({
|
|
|
52305
52406
|
// src/cli/memory/legacyImport.ts
|
|
52306
52407
|
import { createHash as createHash17 } from "node:crypto";
|
|
52307
52408
|
import { promises as fs23 } from "node:fs";
|
|
52308
|
-
import * as
|
|
52409
|
+
import * as path56 from "node:path";
|
|
52309
52410
|
function sourceId(fact, line) {
|
|
52310
52411
|
return `jsonl:${fact.id ?? createHash17("sha256").update(line).digest("hex")}`;
|
|
52311
52412
|
}
|
|
@@ -52323,7 +52424,7 @@ function timestamp(value) {
|
|
|
52323
52424
|
}
|
|
52324
52425
|
async function importLegacyMemoryLog(backend, service) {
|
|
52325
52426
|
const result = { found: 0, imported: 0, skipped: 0, corrupt: 0 };
|
|
52326
|
-
const logPath =
|
|
52427
|
+
const logPath = path56.join(path56.dirname(backend.databasePath), "log.jsonl");
|
|
52327
52428
|
let raw;
|
|
52328
52429
|
try {
|
|
52329
52430
|
raw = await fs23.readFile(logPath, "utf8");
|
|
@@ -52506,7 +52607,7 @@ var init_sqliteCodec = __esm({
|
|
|
52506
52607
|
// src/cli/memory/sqliteRpc.ts
|
|
52507
52608
|
import { existsSync as existsSync30 } from "node:fs";
|
|
52508
52609
|
import { fileURLToPath as fileURLToPath2, pathToFileURL as pathToFileURL2 } from "node:url";
|
|
52509
|
-
import * as
|
|
52610
|
+
import * as path57 from "node:path";
|
|
52510
52611
|
import { Worker } from "node:worker_threads";
|
|
52511
52612
|
function isBusy(error51) {
|
|
52512
52613
|
const candidate = error51;
|
|
@@ -52515,10 +52616,10 @@ function isBusy(error51) {
|
|
|
52515
52616
|
);
|
|
52516
52617
|
}
|
|
52517
52618
|
function resolveWorkerUrl() {
|
|
52518
|
-
const here =
|
|
52519
|
-
const direct =
|
|
52619
|
+
const here = path57.dirname(fileURLToPath2(import.meta.url));
|
|
52620
|
+
const direct = path57.join(here, "sqliteWorker.mjs");
|
|
52520
52621
|
if (existsSync30(direct)) return pathToFileURL2(direct);
|
|
52521
|
-
return pathToFileURL2(
|
|
52622
|
+
return pathToFileURL2(path57.join(here, "memory", "sqliteWorker.mjs"));
|
|
52522
52623
|
}
|
|
52523
52624
|
var SqliteWorkerRpc;
|
|
52524
52625
|
var init_sqliteRpc = __esm({
|
|
@@ -52807,7 +52908,7 @@ WHERE NOT EXISTS (SELECT 1 FROM memory_fts f WHERE f.node_id = n.id);
|
|
|
52807
52908
|
// src/cli/memory/sqliteBackend.ts
|
|
52808
52909
|
import { createHash as createHash18, randomUUID as randomUUID5 } from "node:crypto";
|
|
52809
52910
|
import { promises as fs24 } from "node:fs";
|
|
52810
|
-
import * as
|
|
52911
|
+
import * as path58 from "node:path";
|
|
52811
52912
|
function boundedLimit(value, fallback = 50) {
|
|
52812
52913
|
return Math.max(1, Math.min(Math.floor(value ?? fallback), 1e5));
|
|
52813
52914
|
}
|
|
@@ -52869,16 +52970,16 @@ VALUES (${Array.from({ length: 19 }, () => "?").join(",")})`;
|
|
|
52869
52970
|
try {
|
|
52870
52971
|
resolved = await fs24.realpath(projectRoot);
|
|
52871
52972
|
} catch {
|
|
52872
|
-
resolved =
|
|
52973
|
+
resolved = path58.resolve(projectRoot);
|
|
52873
52974
|
}
|
|
52874
52975
|
if (this.initialized && resolved === this.projectRoot) return;
|
|
52875
52976
|
if (this.initialized) await this.close();
|
|
52876
52977
|
const filename = this.options.filename ?? "memory.db";
|
|
52877
|
-
if (
|
|
52978
|
+
if (path58.basename(filename) !== filename || filename === "." || filename === "..") {
|
|
52878
52979
|
throw new Error("SQLite memory filename must not contain a path.");
|
|
52879
52980
|
}
|
|
52880
|
-
const zelariDirectory =
|
|
52881
|
-
const directory =
|
|
52981
|
+
const zelariDirectory = path58.join(resolved, ".zelari");
|
|
52982
|
+
const directory = path58.join(zelariDirectory, "memory");
|
|
52882
52983
|
for (const candidate of [zelariDirectory, directory]) {
|
|
52883
52984
|
let stat7;
|
|
52884
52985
|
try {
|
|
@@ -52897,12 +52998,12 @@ VALUES (${Array.from({ length: 19 }, () => "?").join(",")})`;
|
|
|
52897
52998
|
}
|
|
52898
52999
|
}
|
|
52899
53000
|
const canonicalDirectory = await fs24.realpath(directory);
|
|
52900
|
-
const relativeDirectory =
|
|
52901
|
-
if (relativeDirectory.startsWith("..") ||
|
|
53001
|
+
const relativeDirectory = path58.relative(resolved, canonicalDirectory);
|
|
53002
|
+
if (relativeDirectory.startsWith("..") || path58.isAbsolute(relativeDirectory)) {
|
|
52902
53003
|
throw new Error("SQLite memory directory resolves outside the active project.");
|
|
52903
53004
|
}
|
|
52904
53005
|
this.projectRoot = resolved;
|
|
52905
|
-
this.databasePath =
|
|
53006
|
+
this.databasePath = path58.join(canonicalDirectory, filename);
|
|
52906
53007
|
const opened = await this.rpc.open({
|
|
52907
53008
|
dbPath: this.databasePath,
|
|
52908
53009
|
schemaSql: SQLITE_MEMORY_BASE_SCHEMA,
|
|
@@ -53435,7 +53536,7 @@ __export(serviceFactory_exports, {
|
|
|
53435
53536
|
});
|
|
53436
53537
|
import { createHash as createHash19 } from "node:crypto";
|
|
53437
53538
|
import { promises as fs25 } from "node:fs";
|
|
53438
|
-
import * as
|
|
53539
|
+
import * as path59 from "node:path";
|
|
53439
53540
|
function isMemoryV2Enabled(env = process.env) {
|
|
53440
53541
|
if (env.ZELARI_MEMORY === "0") return false;
|
|
53441
53542
|
if (env.ZELARI_MEMORY_BACKEND === "file" || env.ZELARI_MEMORY_BACKEND === "jsonl") return false;
|
|
@@ -53456,7 +53557,7 @@ async function canonicalProjectId(projectRoot) {
|
|
|
53456
53557
|
try {
|
|
53457
53558
|
canonical = await fs25.realpath(projectRoot);
|
|
53458
53559
|
} catch {
|
|
53459
|
-
canonical =
|
|
53560
|
+
canonical = path59.resolve(projectRoot);
|
|
53460
53561
|
}
|
|
53461
53562
|
canonical = canonical.replace(/\\/g, "/").replace(/\/$/, "");
|
|
53462
53563
|
if (process.platform === "win32") canonical = canonical.toLocaleLowerCase("en-US");
|
|
@@ -54182,8 +54283,8 @@ function readPlan(ctx) {
|
|
|
54182
54283
|
} catch {
|
|
54183
54284
|
}
|
|
54184
54285
|
}
|
|
54185
|
-
const
|
|
54186
|
-
const doc = ctx.storage.readIfExists(
|
|
54286
|
+
const path91 = workspaceFile(ctx.rootDir, "plan");
|
|
54287
|
+
const doc = ctx.storage.readIfExists(path91);
|
|
54187
54288
|
if (!doc) return { phases: [], tasks: [], milestones: [] };
|
|
54188
54289
|
const meta3 = doc.meta;
|
|
54189
54290
|
return {
|
|
@@ -54361,7 +54462,7 @@ function addMilestoneRecord(ctx, summary, input) {
|
|
|
54361
54462
|
dueDate: input.dueDate,
|
|
54362
54463
|
targetVersion: version2
|
|
54363
54464
|
});
|
|
54364
|
-
const
|
|
54465
|
+
const path91 = join31(ctx.rootDir, "milestones", `${id3}.md`);
|
|
54365
54466
|
const meta3 = {
|
|
54366
54467
|
kind: "milestone",
|
|
54367
54468
|
id: id3,
|
|
@@ -54378,7 +54479,7 @@ function addMilestoneRecord(ctx, summary, input) {
|
|
|
54378
54479
|
`Target version: ${version2}`,
|
|
54379
54480
|
""
|
|
54380
54481
|
].join("\n");
|
|
54381
|
-
ctx.storage.write(
|
|
54482
|
+
ctx.storage.write(path91, meta3, body);
|
|
54382
54483
|
return { id: id3, created: true };
|
|
54383
54484
|
}
|
|
54384
54485
|
function readPlanSummary(ctx) {
|
|
@@ -54582,7 +54683,7 @@ function addIdeaStub(ctx) {
|
|
|
54582
54683
|
const tags = args["tags"] ?? [];
|
|
54583
54684
|
const category = args["category"] ?? "General";
|
|
54584
54685
|
const id3 = `${nextAdrId(ctx)}-${slugify3(title)}`;
|
|
54585
|
-
const
|
|
54686
|
+
const path91 = workspaceArtifact(ctx.rootDir, "decisions", id3);
|
|
54586
54687
|
const meta3 = {
|
|
54587
54688
|
kind: "adr",
|
|
54588
54689
|
status: "proposed",
|
|
@@ -54608,7 +54709,7 @@ function addIdeaStub(ctx) {
|
|
|
54608
54709
|
...consequences.map((c) => `- ${c}`),
|
|
54609
54710
|
""
|
|
54610
54711
|
].join("\n");
|
|
54611
|
-
ctx.storage.write(
|
|
54712
|
+
ctx.storage.write(path91, meta3, body);
|
|
54612
54713
|
return `ADR ${id3} created: "${title}". Status: proposed. Promote to accepted via /update ADR or manual edit.`;
|
|
54613
54714
|
});
|
|
54614
54715
|
}
|
|
@@ -54690,14 +54791,14 @@ function createDocumentStub(ctx) {
|
|
|
54690
54791
|
ctx.storage.write(risksPath, riskMeta, content);
|
|
54691
54792
|
return `Document "${title}" created at risks.md (workspace root).`;
|
|
54692
54793
|
}
|
|
54693
|
-
const
|
|
54794
|
+
const path91 = workspaceArtifact(ctx.rootDir, "docs", slug);
|
|
54694
54795
|
const meta3 = {
|
|
54695
54796
|
kind: "doc",
|
|
54696
54797
|
id: slug,
|
|
54697
54798
|
date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
|
|
54698
54799
|
tags
|
|
54699
54800
|
};
|
|
54700
|
-
ctx.storage.write(
|
|
54801
|
+
ctx.storage.write(path91, meta3, content);
|
|
54701
54802
|
return `Document "${title}" created at docs/${slug}.md.`;
|
|
54702
54803
|
});
|
|
54703
54804
|
}
|
|
@@ -55084,10 +55185,10 @@ function getUserMcpPath() {
|
|
|
55084
55185
|
function getProjectMcpPath(projectRoot) {
|
|
55085
55186
|
return join32(projectRoot, ".zelari", "mcp.json");
|
|
55086
55187
|
}
|
|
55087
|
-
function readFile6(
|
|
55088
|
-
if (!existsSync37(
|
|
55188
|
+
function readFile6(path91) {
|
|
55189
|
+
if (!existsSync37(path91)) return {};
|
|
55089
55190
|
try {
|
|
55090
|
-
const parsed = JSON.parse(readFileSync29(
|
|
55191
|
+
const parsed = JSON.parse(readFileSync29(path91, "utf8"));
|
|
55091
55192
|
const out = {};
|
|
55092
55193
|
for (const [name, cfg] of Object.entries(parsed.mcpServers ?? {})) {
|
|
55093
55194
|
if (!cfg || typeof cfg.command !== "string" || !cfg.command.trim()) continue;
|
|
@@ -55103,10 +55204,10 @@ function readFile6(path87) {
|
|
|
55103
55204
|
return {};
|
|
55104
55205
|
}
|
|
55105
55206
|
}
|
|
55106
|
-
function writeFile2(
|
|
55107
|
-
mkdirSync16(dirname9(
|
|
55207
|
+
function writeFile2(path91, servers) {
|
|
55208
|
+
mkdirSync16(dirname9(path91), { recursive: true });
|
|
55108
55209
|
const body = { mcpServers: servers };
|
|
55109
|
-
writeFileSync18(
|
|
55210
|
+
writeFileSync18(path91, `${JSON.stringify(body, null, 2)}
|
|
55110
55211
|
`, "utf8");
|
|
55111
55212
|
}
|
|
55112
55213
|
function listMcpServers(projectRoot) {
|
|
@@ -55139,9 +55240,9 @@ function upsertMcpServer(opts) {
|
|
|
55139
55240
|
if (!opts.config.command?.trim()) {
|
|
55140
55241
|
return { ok: false, error: "command is required" };
|
|
55141
55242
|
}
|
|
55142
|
-
let
|
|
55243
|
+
let path91;
|
|
55143
55244
|
if (opts.scope === "user") {
|
|
55144
|
-
|
|
55245
|
+
path91 = getUserMcpPath();
|
|
55145
55246
|
} else {
|
|
55146
55247
|
const root = opts.projectRoot?.trim();
|
|
55147
55248
|
if (!root) {
|
|
@@ -55150,30 +55251,30 @@ function upsertMcpServer(opts) {
|
|
|
55150
55251
|
error: "projectRoot required for project scope (Open Folder first)"
|
|
55151
55252
|
};
|
|
55152
55253
|
}
|
|
55153
|
-
|
|
55254
|
+
path91 = getProjectMcpPath(root);
|
|
55154
55255
|
}
|
|
55155
|
-
const current = readFile6(
|
|
55256
|
+
const current = readFile6(path91);
|
|
55156
55257
|
current[name] = {
|
|
55157
55258
|
command: opts.config.command.trim(),
|
|
55158
55259
|
args: opts.config.args,
|
|
55159
55260
|
env: opts.config.env,
|
|
55160
55261
|
enabled: opts.config.enabled !== false
|
|
55161
55262
|
};
|
|
55162
|
-
writeFile2(
|
|
55163
|
-
return { ok: true, path:
|
|
55263
|
+
writeFile2(path91, current);
|
|
55264
|
+
return { ok: true, path: path91 };
|
|
55164
55265
|
}
|
|
55165
55266
|
function removeMcpServer(opts) {
|
|
55166
|
-
const
|
|
55167
|
-
if (!
|
|
55267
|
+
const path91 = opts.scope === "user" ? getUserMcpPath() : opts.projectRoot ? getProjectMcpPath(opts.projectRoot) : null;
|
|
55268
|
+
if (!path91) {
|
|
55168
55269
|
return { ok: false, error: "projectRoot required for project scope" };
|
|
55169
55270
|
}
|
|
55170
|
-
const current = readFile6(
|
|
55271
|
+
const current = readFile6(path91);
|
|
55171
55272
|
if (!(opts.name in current)) {
|
|
55172
|
-
return { ok: false, error: `Server "${opts.name}" not found in ${
|
|
55273
|
+
return { ok: false, error: `Server "${opts.name}" not found in ${path91}` };
|
|
55173
55274
|
}
|
|
55174
55275
|
delete current[opts.name];
|
|
55175
|
-
writeFile2(
|
|
55176
|
-
return { ok: true, path:
|
|
55276
|
+
writeFile2(path91, current);
|
|
55277
|
+
return { ok: true, path: path91 };
|
|
55177
55278
|
}
|
|
55178
55279
|
var init_mcpConfigIo = __esm({
|
|
55179
55280
|
"src/cli/mcp/mcpConfigIo.ts"() {
|
|
@@ -55574,10 +55675,10 @@ import { createHash as createHash20 } from "node:crypto";
|
|
|
55574
55675
|
import { join as join34 } from "node:path";
|
|
55575
55676
|
import { readFile as readFile7 } from "node:fs/promises";
|
|
55576
55677
|
async function readPackageJson3(projectRoot) {
|
|
55577
|
-
const
|
|
55578
|
-
if (!existsSync39(
|
|
55678
|
+
const path91 = join34(projectRoot, "package.json");
|
|
55679
|
+
if (!existsSync39(path91)) return null;
|
|
55579
55680
|
try {
|
|
55580
|
-
return JSON.parse(await readFile7(
|
|
55681
|
+
return JSON.parse(await readFile7(path91, "utf8"));
|
|
55581
55682
|
} catch {
|
|
55582
55683
|
return null;
|
|
55583
55684
|
}
|
|
@@ -55659,9 +55760,9 @@ async function genBuild(ctx) {
|
|
|
55659
55760
|
].join("\n");
|
|
55660
55761
|
}
|
|
55661
55762
|
async function genOpenQuestions(ctx) {
|
|
55662
|
-
const
|
|
55663
|
-
if (!existsSync39(
|
|
55664
|
-
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");
|
|
55665
55766
|
const lines = content.split("\n");
|
|
55666
55767
|
const questions = [];
|
|
55667
55768
|
let currentTitle = "";
|
|
@@ -55935,9 +56036,9 @@ function versionKey(value) {
|
|
|
55935
56036
|
function firstString2(v) {
|
|
55936
56037
|
return typeof v === "string" && v.trim().length > 0 ? v : null;
|
|
55937
56038
|
}
|
|
55938
|
-
function readFileSyncSafe(
|
|
56039
|
+
function readFileSyncSafe(path91) {
|
|
55939
56040
|
try {
|
|
55940
|
-
return readFileSync32(
|
|
56041
|
+
return readFileSync32(path91, "utf8");
|
|
55941
56042
|
} catch {
|
|
55942
56043
|
return null;
|
|
55943
56044
|
}
|
|
@@ -56400,8 +56501,8 @@ async function runPostCouncilHook(ctx, options) {
|
|
|
56400
56501
|
sources: scope.sources
|
|
56401
56502
|
} : void 0
|
|
56402
56503
|
});
|
|
56403
|
-
const
|
|
56404
|
-
completionHook = { ran: true, path:
|
|
56504
|
+
const path91 = writeCouncilCompletion(ctx.rootDir, completion);
|
|
56505
|
+
completionHook = { ran: true, path: path91, completion };
|
|
56405
56506
|
} catch (err) {
|
|
56406
56507
|
completionHook = {
|
|
56407
56508
|
ran: true,
|
|
@@ -56446,7 +56547,7 @@ import {
|
|
|
56446
56547
|
writeFileSync as writeFileSync21,
|
|
56447
56548
|
mkdirSync as mkdirSync17
|
|
56448
56549
|
} from "node:fs";
|
|
56449
|
-
import
|
|
56550
|
+
import path60 from "node:path";
|
|
56450
56551
|
import os10 from "node:os";
|
|
56451
56552
|
var FeedbackStore;
|
|
56452
56553
|
var init_councilFeedback = __esm({
|
|
@@ -56457,7 +56558,7 @@ var init_councilFeedback = __esm({
|
|
|
56457
56558
|
now;
|
|
56458
56559
|
entries = [];
|
|
56459
56560
|
constructor(options = {}) {
|
|
56460
|
-
this.file = options.file ?? (process.env.ANATHEMA_COUNCIL_FEEDBACK_FILE ??
|
|
56561
|
+
this.file = options.file ?? (process.env.ANATHEMA_COUNCIL_FEEDBACK_FILE ?? path60.join(os10.homedir(), ".tmp", "zelari-code", "council-feedback.json"));
|
|
56461
56562
|
this.now = options.now ?? Date.now;
|
|
56462
56563
|
this.load();
|
|
56463
56564
|
}
|
|
@@ -56563,7 +56664,7 @@ var init_councilFeedback = __esm({
|
|
|
56563
56664
|
}
|
|
56564
56665
|
}
|
|
56565
56666
|
save() {
|
|
56566
|
-
mkdirSync17(
|
|
56667
|
+
mkdirSync17(path60.dirname(this.file), { recursive: true });
|
|
56567
56668
|
writeFileSync21(
|
|
56568
56669
|
this.file,
|
|
56569
56670
|
JSON.stringify({ entries: this.entries }, null, 2),
|
|
@@ -56631,7 +56732,7 @@ import { execFile as execFile4 } from "node:child_process";
|
|
|
56631
56732
|
import { promisify as promisify3 } from "node:util";
|
|
56632
56733
|
import { mkdtempSync, rmSync as rmSync2 } from "node:fs";
|
|
56633
56734
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
56634
|
-
import
|
|
56735
|
+
import path61 from "node:path";
|
|
56635
56736
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
56636
56737
|
async function git4(cwd, args, env) {
|
|
56637
56738
|
const { stdout } = await execFileAsync3("git", ["-C", cwd, ...args], {
|
|
@@ -56651,8 +56752,8 @@ async function isGitRepo(cwd) {
|
|
|
56651
56752
|
return await gitSafe(cwd, ["rev-parse", "--is-inside-work-tree"]) === "true";
|
|
56652
56753
|
}
|
|
56653
56754
|
async function withTempIndex(fn) {
|
|
56654
|
-
const dir = mkdtempSync(
|
|
56655
|
-
const indexFile =
|
|
56755
|
+
const dir = mkdtempSync(path61.join(tmpdir3(), "zelari-ckpt-"));
|
|
56756
|
+
const indexFile = path61.join(dir, "index");
|
|
56656
56757
|
try {
|
|
56657
56758
|
return await fn(indexFile);
|
|
56658
56759
|
} finally {
|
|
@@ -56743,7 +56844,7 @@ async function restoreCheckpoint(cwd, id3) {
|
|
|
56743
56844
|
const deleted = [];
|
|
56744
56845
|
for (const rel2 of added) {
|
|
56745
56846
|
try {
|
|
56746
|
-
rmSync2(
|
|
56847
|
+
rmSync2(path61.join(cwd, rel2), { force: true });
|
|
56747
56848
|
deleted.push(rel2);
|
|
56748
56849
|
} catch {
|
|
56749
56850
|
}
|
|
@@ -56847,7 +56948,7 @@ __export(fileBackend_exports, {
|
|
|
56847
56948
|
});
|
|
56848
56949
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
56849
56950
|
import { promises as fs27 } from "node:fs";
|
|
56850
|
-
import * as
|
|
56951
|
+
import * as path62 from "node:path";
|
|
56851
56952
|
function tokenize2(text) {
|
|
56852
56953
|
return text.toLowerCase().split(/[^\p{L}\p{N}]+/u).filter((t) => t.length >= 3);
|
|
56853
56954
|
}
|
|
@@ -56861,10 +56962,12 @@ function matchesFilter(metadata2, filter) {
|
|
|
56861
56962
|
function isMemoryEnabled(env = process.env) {
|
|
56862
56963
|
return env.ZELARI_MEMORY !== "0";
|
|
56863
56964
|
}
|
|
56864
|
-
async function getMemoryBackend(projectRoot, env = process.env) {
|
|
56965
|
+
async function getMemoryBackend(projectRoot, env = process.env, onEvent) {
|
|
56865
56966
|
if (!isMemoryEnabled(env)) return new NoopMemoryBackend();
|
|
56866
56967
|
if (isMemoryV2Enabled(env)) {
|
|
56867
|
-
const service = await getMemoryService(projectRoot, env
|
|
56968
|
+
const service = await getMemoryService(projectRoot, env, {
|
|
56969
|
+
...onEvent ? { onEvent } : {}
|
|
56970
|
+
});
|
|
56868
56971
|
if (service instanceof NoopMemoryService) return new NoopMemoryBackend();
|
|
56869
56972
|
return new LegacyMemoryBackendAdapter(service);
|
|
56870
56973
|
}
|
|
@@ -56898,8 +57001,8 @@ var init_fileBackend = __esm({
|
|
|
56898
57001
|
logPath = "";
|
|
56899
57002
|
memoryDir = "";
|
|
56900
57003
|
async init(projectRoot) {
|
|
56901
|
-
this.memoryDir =
|
|
56902
|
-
this.logPath =
|
|
57004
|
+
this.memoryDir = path62.join(projectRoot, ".zelari", "memory");
|
|
57005
|
+
this.logPath = path62.join(this.memoryDir, "log.jsonl");
|
|
56903
57006
|
await fs27.mkdir(this.memoryDir, { recursive: true });
|
|
56904
57007
|
}
|
|
56905
57008
|
async add(content, metadata2 = {}, graph) {
|
|
@@ -56972,12 +57075,12 @@ var init_fileBackend = __esm({
|
|
|
56972
57075
|
|
|
56973
57076
|
// src/cli/traceStore.ts
|
|
56974
57077
|
import { promises as fs28 } from "node:fs";
|
|
56975
|
-
import * as
|
|
57078
|
+
import * as path63 from "node:path";
|
|
56976
57079
|
function traceDir(projectRoot) {
|
|
56977
|
-
return
|
|
57080
|
+
return path63.join(projectRoot, ".zelari", "trace");
|
|
56978
57081
|
}
|
|
56979
57082
|
function tracePath(projectRoot, missionId) {
|
|
56980
|
-
return
|
|
57083
|
+
return path63.join(traceDir(projectRoot), `${missionId}.json`);
|
|
56981
57084
|
}
|
|
56982
57085
|
async function saveTrace(projectRoot, missionId, entries) {
|
|
56983
57086
|
const dir = traceDir(projectRoot);
|
|
@@ -57014,7 +57117,7 @@ __export(zelariMission_exports, {
|
|
|
57014
57117
|
});
|
|
57015
57118
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
57016
57119
|
import { promises as fs29 } from "node:fs";
|
|
57017
|
-
import * as
|
|
57120
|
+
import * as path64 from "node:path";
|
|
57018
57121
|
function resolveMaxIterations(env = process.env) {
|
|
57019
57122
|
const raw = env.ZELARI_MISSION_MAX_ITER;
|
|
57020
57123
|
const n = raw ? Number.parseInt(raw, 10) : DEFAULT_MAX_ITER;
|
|
@@ -57057,10 +57160,10 @@ function isMissionAutoStart(env = process.env) {
|
|
|
57057
57160
|
return env.ZELARI_MISSION_AUTO === "1";
|
|
57058
57161
|
}
|
|
57059
57162
|
async function writeMissionState(projectRoot, state3) {
|
|
57060
|
-
const dir =
|
|
57163
|
+
const dir = path64.join(projectRoot, ".zelari");
|
|
57061
57164
|
await fs29.mkdir(dir, { recursive: true });
|
|
57062
57165
|
await fs29.writeFile(
|
|
57063
|
-
|
|
57166
|
+
path64.join(dir, "mission-state.json"),
|
|
57064
57167
|
JSON.stringify(state3, null, 2) + "\n",
|
|
57065
57168
|
"utf8"
|
|
57066
57169
|
);
|
|
@@ -57735,7 +57838,7 @@ function safeSocketPath(socketPath) {
|
|
|
57735
57838
|
return socketPath.trim();
|
|
57736
57839
|
}
|
|
57737
57840
|
function startPermissionBroker(socketPath, handlers, opts) {
|
|
57738
|
-
const
|
|
57841
|
+
const path91 = safeSocketPath(socketPath);
|
|
57739
57842
|
const requestTimeoutMs = opts?.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
|
|
57740
57843
|
const sockets = /* @__PURE__ */ new Set();
|
|
57741
57844
|
const server = createServer2((socket) => {
|
|
@@ -57835,10 +57938,10 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
57835
57938
|
return new Promise((resolve9, reject) => {
|
|
57836
57939
|
const onError = (err) => reject(err);
|
|
57837
57940
|
server.once("error", onError);
|
|
57838
|
-
server.listen(
|
|
57941
|
+
server.listen(path91, () => {
|
|
57839
57942
|
server.removeListener("error", onError);
|
|
57840
57943
|
resolve9({
|
|
57841
|
-
socketPath:
|
|
57944
|
+
socketPath: path91,
|
|
57842
57945
|
stop: () => new Promise((res) => {
|
|
57843
57946
|
for (const s of sockets) s.destroy();
|
|
57844
57947
|
sockets.clear();
|
|
@@ -57849,7 +57952,7 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
57849
57952
|
if (done) return;
|
|
57850
57953
|
done = true;
|
|
57851
57954
|
if (process.platform !== "win32") {
|
|
57852
|
-
unlink(
|
|
57955
|
+
unlink(path91, () => res());
|
|
57853
57956
|
} else {
|
|
57854
57957
|
res();
|
|
57855
57958
|
}
|
|
@@ -57862,11 +57965,11 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
57862
57965
|
});
|
|
57863
57966
|
}
|
|
57864
57967
|
function requestBrokerAsk(socketPath, ask, opts) {
|
|
57865
|
-
const
|
|
57968
|
+
const path91 = safeSocketPath(socketPath);
|
|
57866
57969
|
const requestTimeoutMs = opts?.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
|
|
57867
57970
|
const connectTimeoutMs = opts?.connectTimeoutMs ?? PERMISSION_BROKER_DEFAULT_CONNECT_TIMEOUT_MS;
|
|
57868
57971
|
return new Promise((resolve9, reject) => {
|
|
57869
|
-
const socket = connect(
|
|
57972
|
+
const socket = connect(path91);
|
|
57870
57973
|
let buffer = "";
|
|
57871
57974
|
let settled = false;
|
|
57872
57975
|
const settle = (fn) => {
|
|
@@ -57881,7 +57984,7 @@ function requestBrokerAsk(socketPath, ask, opts) {
|
|
|
57881
57984
|
settle(
|
|
57882
57985
|
() => reject(
|
|
57883
57986
|
new Error(
|
|
57884
|
-
`permission broker unavailable at "${
|
|
57987
|
+
`permission broker unavailable at "${path91}" (connect timed out after ${connectTimeoutMs}ms)`
|
|
57885
57988
|
)
|
|
57886
57989
|
)
|
|
57887
57990
|
);
|
|
@@ -58021,7 +58124,7 @@ var init_brokerHandlers = __esm({
|
|
|
58021
58124
|
// src/cli/gitOps.ts
|
|
58022
58125
|
import { execFile as execFile5 } from "node:child_process";
|
|
58023
58126
|
import { promisify as promisify4 } from "node:util";
|
|
58024
|
-
import
|
|
58127
|
+
import path65 from "node:path";
|
|
58025
58128
|
async function git5(cwd, args) {
|
|
58026
58129
|
try {
|
|
58027
58130
|
const { stdout } = await execFileAsync4("git", ["-C", cwd, ...args], {
|
|
@@ -58066,7 +58169,7 @@ async function undoWorkingChanges(opts = {}) {
|
|
|
58066
58169
|
};
|
|
58067
58170
|
}
|
|
58068
58171
|
function defaultProjectRoot() {
|
|
58069
|
-
return
|
|
58172
|
+
return path65.resolve(__dirname, "..", "..", "..");
|
|
58070
58173
|
}
|
|
58071
58174
|
var execFileAsync4;
|
|
58072
58175
|
var init_gitOps = __esm({
|
|
@@ -58684,9 +58787,9 @@ __export(graphMemory_exports, {
|
|
|
58684
58787
|
toGraphSnapshot: () => toGraphSnapshot
|
|
58685
58788
|
});
|
|
58686
58789
|
import { promises as fs32 } from "node:fs";
|
|
58687
|
-
import
|
|
58790
|
+
import path68 from "node:path";
|
|
58688
58791
|
function snapshotPath(cwd) {
|
|
58689
|
-
return
|
|
58792
|
+
return path68.join(cwd, SNAPSHOT_DIR, SNAPSHOT_FILE);
|
|
58690
58793
|
}
|
|
58691
58794
|
function toGraphSnapshot(graph, opts) {
|
|
58692
58795
|
const unresolved = (opts.unresolvedFindings ?? []).map((u) => ({
|
|
@@ -58713,7 +58816,7 @@ async function saveGraphSnapshot(cwd, snapshot) {
|
|
|
58713
58816
|
try {
|
|
58714
58817
|
await fs32.access(cwd);
|
|
58715
58818
|
const file2 = snapshotPath(cwd);
|
|
58716
|
-
await fs32.mkdir(
|
|
58819
|
+
await fs32.mkdir(path68.dirname(file2), { recursive: true });
|
|
58717
58820
|
await fs32.writeFile(file2, JSON.stringify(snapshot, null, 2) + "\n", "utf8");
|
|
58718
58821
|
} catch {
|
|
58719
58822
|
}
|
|
@@ -58780,13 +58883,19 @@ var SNAPSHOT_DIR, SNAPSHOT_FILE, MAX_SNAPSHOT_FINDINGS_CHARS;
|
|
|
58780
58883
|
var init_graphMemory = __esm({
|
|
58781
58884
|
"src/cli/kraken/graphMemory.ts"() {
|
|
58782
58885
|
"use strict";
|
|
58783
|
-
SNAPSHOT_DIR =
|
|
58886
|
+
SNAPSHOT_DIR = path68.join(".zelari", "kraken");
|
|
58784
58887
|
SNAPSHOT_FILE = "last-graph.json";
|
|
58785
58888
|
MAX_SNAPSHOT_FINDINGS_CHARS = 400;
|
|
58786
58889
|
}
|
|
58787
58890
|
});
|
|
58788
58891
|
|
|
58789
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
|
+
});
|
|
58790
58899
|
var init_tentacle = __esm({
|
|
58791
58900
|
"src/cli/kraken/tentacle.ts"() {
|
|
58792
58901
|
"use strict";
|
|
@@ -58852,14 +58961,14 @@ var init_transactional = __esm({
|
|
|
58852
58961
|
|
|
58853
58962
|
// src/cli/kraken/workbench.ts
|
|
58854
58963
|
import { promises as fs33 } from "node:fs";
|
|
58855
|
-
import
|
|
58964
|
+
import path69 from "node:path";
|
|
58856
58965
|
function isWorkbenchEnabled(env = process.env) {
|
|
58857
58966
|
const v = (env.ZELARI_KRAKEN_WORKBENCH ?? "1").trim().toLowerCase();
|
|
58858
58967
|
if (v === "0" || v === "false" || v === "no" || v === "off") return false;
|
|
58859
58968
|
return true;
|
|
58860
58969
|
}
|
|
58861
58970
|
function workbenchPath(cwd, graphId) {
|
|
58862
|
-
return
|
|
58971
|
+
return path69.join(cwd, ".zelari", "radio", `workbench-${graphId}.md`);
|
|
58863
58972
|
}
|
|
58864
58973
|
function countByStatus2(nodes) {
|
|
58865
58974
|
const out = { pending: 0, running: 0, done: 0, error: 0, skipped: 0 };
|
|
@@ -59022,7 +59131,7 @@ var init_workbench = __esm({
|
|
|
59022
59131
|
if (!this.enabled) return null;
|
|
59023
59132
|
if (!this.dirty && this.lastWrite) return this.lastWrite;
|
|
59024
59133
|
const out = workbenchPath(this.cwd, this.graphId);
|
|
59025
|
-
await fs33.mkdir(
|
|
59134
|
+
await fs33.mkdir(path69.dirname(out), { recursive: true });
|
|
59026
59135
|
const body = this.render();
|
|
59027
59136
|
const tmp = `${out}.${process.pid}.${Date.now()}.tmp`;
|
|
59028
59137
|
await fs33.writeFile(tmp, body, "utf8");
|
|
@@ -59395,14 +59504,14 @@ var init_spawnRoi = __esm({
|
|
|
59395
59504
|
|
|
59396
59505
|
// src/cli/kraken/reputationStore.ts
|
|
59397
59506
|
import { appendFile as appendFile2, mkdir as mkdir3, readFile as readFile8, rename as rename2, writeFile as writeFile3 } from "node:fs/promises";
|
|
59398
|
-
import
|
|
59507
|
+
import path70 from "node:path";
|
|
59399
59508
|
function resolveReputationStorePath(cwd = process.cwd(), env = process.env) {
|
|
59400
59509
|
const override = env[REPUTATION_STORE_ENV]?.trim();
|
|
59401
59510
|
if (override) return override;
|
|
59402
|
-
return
|
|
59511
|
+
return path70.join(cwd, ".zelari", "reputation.jsonl");
|
|
59403
59512
|
}
|
|
59404
59513
|
async function appendRecord(storePath, record2) {
|
|
59405
|
-
await mkdir3(
|
|
59514
|
+
await mkdir3(path70.dirname(storePath), { recursive: true });
|
|
59406
59515
|
await appendFile2(storePath, `${JSON.stringify(record2)}
|
|
59407
59516
|
`, "utf8");
|
|
59408
59517
|
}
|
|
@@ -59802,7 +59911,7 @@ __export(executor_exports, {
|
|
|
59802
59911
|
thoroughnessForKind: () => thoroughnessForKind
|
|
59803
59912
|
});
|
|
59804
59913
|
import { existsSync as existsSync44 } from "node:fs";
|
|
59805
|
-
import
|
|
59914
|
+
import path71 from "node:path";
|
|
59806
59915
|
async function defaultSymbolExtractor(file2) {
|
|
59807
59916
|
if (!isAstSupported(file2)) return null;
|
|
59808
59917
|
const r = await parseFileSymbolsDiag(file2);
|
|
@@ -59868,7 +59977,7 @@ function isWorldModelGateEnabled(cwd, env = process.env, checksExists = defaultC
|
|
|
59868
59977
|
}
|
|
59869
59978
|
function defaultChecksExists(cwd) {
|
|
59870
59979
|
try {
|
|
59871
|
-
return existsSync44(
|
|
59980
|
+
return existsSync44(path71.join(cwd, ".zelari", "world", "checks.json"));
|
|
59872
59981
|
} catch {
|
|
59873
59982
|
return false;
|
|
59874
59983
|
}
|
|
@@ -60376,7 +60485,7 @@ var init_executor = __esm({
|
|
|
60376
60485
|
try {
|
|
60377
60486
|
const summary = aggregate(
|
|
60378
60487
|
records,
|
|
60379
|
-
{ repo:
|
|
60488
|
+
{ repo: path71.basename(this.parentCwd), role: agentForNode(node) },
|
|
60380
60489
|
now
|
|
60381
60490
|
);
|
|
60382
60491
|
sample = summary.sample;
|
|
@@ -60853,7 +60962,7 @@ ${upstream}` : node.prompt,
|
|
|
60853
60962
|
const model = res.ok && res.model && res.model !== "n/a" ? res.model : null;
|
|
60854
60963
|
const reviewerVerdict = res.ok && this.isReviewerKind(node.kind) && typeof node.result === "string" && node.result.length > 0 ? parseVerifyVerdict(node.result).verdict : null;
|
|
60855
60964
|
const record2 = reputationRecordFromNodeRun({
|
|
60856
|
-
repo:
|
|
60965
|
+
repo: path71.basename(this.parentCwd),
|
|
60857
60966
|
role: agentForNode(node),
|
|
60858
60967
|
kind: node.kind,
|
|
60859
60968
|
ok: res.ok,
|
|
@@ -61624,10 +61733,10 @@ var init_prereqChecks = __esm({
|
|
|
61624
61733
|
|
|
61625
61734
|
// src/cli/plugins/prefs.ts
|
|
61626
61735
|
import { existsSync as existsSync46, readFileSync as readFileSync36, writeFileSync as writeFileSync22, mkdirSync as mkdirSync18 } from "node:fs";
|
|
61627
|
-
import
|
|
61736
|
+
import path74 from "node:path";
|
|
61628
61737
|
import os11 from "node:os";
|
|
61629
61738
|
function getPluginPrefsPath() {
|
|
61630
|
-
return process.env.ZELARI_PLUGINS_PREFS_FILE ??
|
|
61739
|
+
return process.env.ZELARI_PLUGINS_PREFS_FILE ?? path74.join(os11.homedir(), ".tmp", "zelari-code", "plugins.json");
|
|
61631
61740
|
}
|
|
61632
61741
|
function getPluginPrefs() {
|
|
61633
61742
|
const file2 = getPluginPrefsPath();
|
|
@@ -61648,7 +61757,7 @@ function getPluginPrefs() {
|
|
|
61648
61757
|
}
|
|
61649
61758
|
function writePluginPrefs(prefs) {
|
|
61650
61759
|
const file2 = getPluginPrefsPath();
|
|
61651
|
-
mkdirSync18(
|
|
61760
|
+
mkdirSync18(path74.dirname(file2), { recursive: true });
|
|
61652
61761
|
writeFileSync22(file2, JSON.stringify(prefs, null, 2), {
|
|
61653
61762
|
encoding: "utf-8",
|
|
61654
61763
|
mode: 384
|
|
@@ -61685,7 +61794,7 @@ __export(registry_exports, {
|
|
|
61685
61794
|
isBinaryOnPath: () => isBinaryOnPath
|
|
61686
61795
|
});
|
|
61687
61796
|
import { existsSync as existsSync47 } from "node:fs";
|
|
61688
|
-
import
|
|
61797
|
+
import path75 from "node:path";
|
|
61689
61798
|
function detectLocalBin(bin) {
|
|
61690
61799
|
return (cwd) => {
|
|
61691
61800
|
try {
|
|
@@ -61703,7 +61812,7 @@ function isBinaryOnPath(bin, opts = {}) {
|
|
|
61703
61812
|
const platform = opts.platform ?? process.platform;
|
|
61704
61813
|
const exists = opts.exists ?? existsSync47;
|
|
61705
61814
|
const pathEnv = opts.pathEnv ?? process.env.PATH ?? "";
|
|
61706
|
-
const pathMod = platform === "win32" ?
|
|
61815
|
+
const pathMod = platform === "win32" ? path75.win32 : path75.posix;
|
|
61707
61816
|
const sep4 = platform === "win32" ? ";" : ":";
|
|
61708
61817
|
const dirs = pathEnv.split(sep4).filter((d) => d.length > 0);
|
|
61709
61818
|
const candidates = [bin];
|
|
@@ -62798,7 +62907,7 @@ var init_policy = __esm({
|
|
|
62798
62907
|
|
|
62799
62908
|
// src/cli/orchestration/facts.ts
|
|
62800
62909
|
import { promises as fs41 } from "node:fs";
|
|
62801
|
-
import
|
|
62910
|
+
import path80 from "node:path";
|
|
62802
62911
|
async function collectRepoFileCount(root = process.cwd()) {
|
|
62803
62912
|
try {
|
|
62804
62913
|
await fs41.readdir(root);
|
|
@@ -62818,7 +62927,7 @@ async function collectRepoFileCount(root = process.cwd()) {
|
|
|
62818
62927
|
}
|
|
62819
62928
|
for (const e of entries) {
|
|
62820
62929
|
if (e.isDirectory()) {
|
|
62821
|
-
if (!SKIP_DIRS.has(e.name)) queue.push(
|
|
62930
|
+
if (!SKIP_DIRS.has(e.name)) queue.push(path80.join(dir, e.name));
|
|
62822
62931
|
} else if (e.isFile()) {
|
|
62823
62932
|
count++;
|
|
62824
62933
|
if (count > MAX_WALK_FILES) return count;
|
|
@@ -62914,6 +63023,206 @@ var init_streamScrub = __esm({
|
|
|
62914
63023
|
}
|
|
62915
63024
|
});
|
|
62916
63025
|
|
|
63026
|
+
// src/cli/harnessState.ts
|
|
63027
|
+
import path81 from "node:path";
|
|
63028
|
+
function asString3(v) {
|
|
63029
|
+
return typeof v === "string" ? v : "";
|
|
63030
|
+
}
|
|
63031
|
+
function asNumber2(v) {
|
|
63032
|
+
return typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
63033
|
+
}
|
|
63034
|
+
function asCallId(v, seq) {
|
|
63035
|
+
return typeof v === "string" && v.length > 0 ? v : `seq:${seq}`;
|
|
63036
|
+
}
|
|
63037
|
+
function newTurn(index, userText) {
|
|
63038
|
+
return {
|
|
63039
|
+
index,
|
|
63040
|
+
userText: userText.length > 0 ? userText : void 0,
|
|
63041
|
+
toolCalls: 0,
|
|
63042
|
+
toolKinds: [],
|
|
63043
|
+
outcome: "pending",
|
|
63044
|
+
unsettledCallIds: /* @__PURE__ */ new Set(),
|
|
63045
|
+
settledCallIds: /* @__PURE__ */ new Set(),
|
|
63046
|
+
interrupted: 0,
|
|
63047
|
+
assistantMessages: 0
|
|
63048
|
+
};
|
|
63049
|
+
}
|
|
63050
|
+
function deriveHarnessState(events) {
|
|
63051
|
+
const session = {
|
|
63052
|
+
sessionId: events[events.length - 1]?.sessionId ?? "",
|
|
63053
|
+
status: "pending",
|
|
63054
|
+
lastSeq: 0
|
|
63055
|
+
};
|
|
63056
|
+
const support = { contextProjections: [], memoryEvents: 0, compactions: 0 };
|
|
63057
|
+
let tokensSaved;
|
|
63058
|
+
const acc = [];
|
|
63059
|
+
let current = null;
|
|
63060
|
+
for (const e of events) {
|
|
63061
|
+
session.lastSeq = e.seq;
|
|
63062
|
+
switch (e.kind) {
|
|
63063
|
+
case "session.started":
|
|
63064
|
+
session.startedAt ??= e.ts;
|
|
63065
|
+
break;
|
|
63066
|
+
case "session.ended": {
|
|
63067
|
+
session.endedAt = e.ts;
|
|
63068
|
+
const reason = asString3(e.data.reason);
|
|
63069
|
+
session.status = reason.length > 0 ? reason : "ended";
|
|
63070
|
+
if (current) {
|
|
63071
|
+
current.closedBy = "session-ended";
|
|
63072
|
+
current.endReason = reason;
|
|
63073
|
+
current = null;
|
|
63074
|
+
}
|
|
63075
|
+
break;
|
|
63076
|
+
}
|
|
63077
|
+
case "user.message": {
|
|
63078
|
+
if (current) current.closedBy = "next-turn";
|
|
63079
|
+
current = newTurn(acc.length + 1, asString3(e.data.text));
|
|
63080
|
+
acc.push(current);
|
|
63081
|
+
break;
|
|
63082
|
+
}
|
|
63083
|
+
case "assistant.message": {
|
|
63084
|
+
if (!current) break;
|
|
63085
|
+
current.assistantMessages += 1;
|
|
63086
|
+
const text = asString3(e.data.text);
|
|
63087
|
+
current.assistantChars = (current.assistantChars ?? 0) + text.length;
|
|
63088
|
+
current.assistantText = text;
|
|
63089
|
+
break;
|
|
63090
|
+
}
|
|
63091
|
+
case "tool.call": {
|
|
63092
|
+
if (!current) break;
|
|
63093
|
+
current.toolCalls += 1;
|
|
63094
|
+
const tool = asString3(e.data.tool);
|
|
63095
|
+
if (tool.length > 0 && !current.toolKinds.includes(tool)) current.toolKinds.push(tool);
|
|
63096
|
+
current.unsettledCallIds.add(asCallId(e.data.callId, e.seq));
|
|
63097
|
+
break;
|
|
63098
|
+
}
|
|
63099
|
+
case "tool.result": {
|
|
63100
|
+
if (!current) break;
|
|
63101
|
+
current.settledCallIds.add(asCallId(e.data.callId, e.seq));
|
|
63102
|
+
break;
|
|
63103
|
+
}
|
|
63104
|
+
case "tool.interrupted": {
|
|
63105
|
+
if (current) current.interrupted += 1;
|
|
63106
|
+
break;
|
|
63107
|
+
}
|
|
63108
|
+
case "verification.run": {
|
|
63109
|
+
if (!current) break;
|
|
63110
|
+
current.verification = {
|
|
63111
|
+
strict: e.data.strict === true,
|
|
63112
|
+
verdict: asString3(e.data.verdict) || "unknown"
|
|
63113
|
+
};
|
|
63114
|
+
break;
|
|
63115
|
+
}
|
|
63116
|
+
case "session.compacted": {
|
|
63117
|
+
support.compactions += 1;
|
|
63118
|
+
const saved = asNumber2(e.data.tokensSaved);
|
|
63119
|
+
if (saved !== void 0) tokensSaved = (tokensSaved ?? 0) + saved;
|
|
63120
|
+
break;
|
|
63121
|
+
}
|
|
63122
|
+
case "note": {
|
|
63123
|
+
const subject = asString3(e.data.subject);
|
|
63124
|
+
if (subject === "context.projection") {
|
|
63125
|
+
support.contextProjections.push({
|
|
63126
|
+
contextChars: asNumber2(e.data.contextChars) ?? 0,
|
|
63127
|
+
returnedCount: asNumber2(e.data.returnedCount) ?? 0
|
|
63128
|
+
});
|
|
63129
|
+
} else if (subject === "memory_event") {
|
|
63130
|
+
support.memoryEvents += 1;
|
|
63131
|
+
}
|
|
63132
|
+
break;
|
|
63133
|
+
}
|
|
63134
|
+
default:
|
|
63135
|
+
break;
|
|
63136
|
+
}
|
|
63137
|
+
}
|
|
63138
|
+
const turns = acc.map((t) => finalizeTurn(t));
|
|
63139
|
+
return {
|
|
63140
|
+
session,
|
|
63141
|
+
turns,
|
|
63142
|
+
execution: { turnsTotal: turns.length, contracts: acc.map((t) => contractFor(t)) },
|
|
63143
|
+
support: tokensSaved === void 0 ? support : { ...support, tokensSavedByCompaction: tokensSaved }
|
|
63144
|
+
};
|
|
63145
|
+
}
|
|
63146
|
+
function finalizeTurn(t) {
|
|
63147
|
+
let outcome;
|
|
63148
|
+
if (t.closedBy === void 0) outcome = "pending";
|
|
63149
|
+
else if (t.closedBy === "session-ended" && t.endReason !== "completed") outcome = "error";
|
|
63150
|
+
else outcome = "completed";
|
|
63151
|
+
return {
|
|
63152
|
+
index: t.index,
|
|
63153
|
+
userText: t.userText,
|
|
63154
|
+
assistantChars: t.assistantMessages > 0 ? t.assistantChars ?? 0 : void 0,
|
|
63155
|
+
assistantText: t.assistantMessages > 0 ? t.assistantText : void 0,
|
|
63156
|
+
toolCalls: t.toolCalls,
|
|
63157
|
+
toolKinds: t.toolKinds,
|
|
63158
|
+
verification: t.verification,
|
|
63159
|
+
outcome
|
|
63160
|
+
};
|
|
63161
|
+
}
|
|
63162
|
+
function contractFor(t) {
|
|
63163
|
+
const userMessage = true;
|
|
63164
|
+
const assistantReply = t.assistantMessages > 0;
|
|
63165
|
+
const allSettled = [...t.unsettledCallIds].every((id3) => t.settledCallIds.has(id3));
|
|
63166
|
+
const toolsSettled = allSettled && t.interrupted === 0;
|
|
63167
|
+
const blockers = [];
|
|
63168
|
+
if (!assistantReply) blockers.push("assistant-reply-missing");
|
|
63169
|
+
if (!toolsSettled) blockers.push("tools-unsettled");
|
|
63170
|
+
if (t.verification) {
|
|
63171
|
+
if (!t.verification.strict) blockers.push("verification-not-strict");
|
|
63172
|
+
else if (t.verification.verdict !== "PASS") blockers.push(`verification-verdict-${t.verification.verdict}`);
|
|
63173
|
+
} else if (t.closedBy === void 0) {
|
|
63174
|
+
blockers.push("turn-pending");
|
|
63175
|
+
} else if (t.closedBy === "session-ended" && t.endReason !== "completed") {
|
|
63176
|
+
blockers.push(`turn-error-${t.endReason}`);
|
|
63177
|
+
}
|
|
63178
|
+
return {
|
|
63179
|
+
turn: t.index,
|
|
63180
|
+
complete: userMessage && assistantReply && toolsSettled && blockers.length === 0,
|
|
63181
|
+
signals: {
|
|
63182
|
+
userMessage,
|
|
63183
|
+
assistantReply,
|
|
63184
|
+
toolsSettled,
|
|
63185
|
+
verification: t.verification
|
|
63186
|
+
},
|
|
63187
|
+
blockers
|
|
63188
|
+
};
|
|
63189
|
+
}
|
|
63190
|
+
async function readHarnessState(sessionDir) {
|
|
63191
|
+
const report = await readSessionLog(path81.join(sessionDir, "events.jsonl"));
|
|
63192
|
+
return deriveHarnessState(report.events);
|
|
63193
|
+
}
|
|
63194
|
+
var init_harnessState = __esm({
|
|
63195
|
+
"src/cli/harnessState.ts"() {
|
|
63196
|
+
"use strict";
|
|
63197
|
+
init_session();
|
|
63198
|
+
}
|
|
63199
|
+
});
|
|
63200
|
+
|
|
63201
|
+
// src/cli/headless/harnessStateEmit.ts
|
|
63202
|
+
import path82 from "node:path";
|
|
63203
|
+
async function emitHarnessStateEvent(opts) {
|
|
63204
|
+
if (opts.output !== "json") return;
|
|
63205
|
+
try {
|
|
63206
|
+
const sessionsDir = resolveSessionsDir({ workspaceRoot: opts.workspaceRoot });
|
|
63207
|
+
const state3 = await readHarnessState(path82.join(sessionsDir, opts.spine.sessionId));
|
|
63208
|
+
opts.emitEvent({ type: "harness_state", ...state3 });
|
|
63209
|
+
} catch (err) {
|
|
63210
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
63211
|
+
try {
|
|
63212
|
+
process.stderr.write(`[zelari-code --headless] harness_state unavailable: ${msg}
|
|
63213
|
+
`);
|
|
63214
|
+
} catch {
|
|
63215
|
+
}
|
|
63216
|
+
}
|
|
63217
|
+
}
|
|
63218
|
+
var init_harnessStateEmit = __esm({
|
|
63219
|
+
"src/cli/headless/harnessStateEmit.ts"() {
|
|
63220
|
+
"use strict";
|
|
63221
|
+
init_session();
|
|
63222
|
+
init_harnessState();
|
|
63223
|
+
}
|
|
63224
|
+
});
|
|
63225
|
+
|
|
62917
63226
|
// src/cli/headless/policyGate.ts
|
|
62918
63227
|
import { isAbsolute as isAbsolute5, resolve as resolve7 } from "node:path";
|
|
62919
63228
|
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
@@ -62959,7 +63268,7 @@ async function recordPolicyLoadBlockedOnSpine(block, opts = {}) {
|
|
|
62959
63268
|
sessionId: sessionId2,
|
|
62960
63269
|
...opts.mode ? { mode: opts.mode } : {},
|
|
62961
63270
|
...opts.profile ? { profile: opts.profile } : {},
|
|
62962
|
-
workspace: process.cwd()
|
|
63271
|
+
workspace: opts.workspace ?? process.cwd()
|
|
62963
63272
|
});
|
|
62964
63273
|
if (opts.mode === "zelari") {
|
|
62965
63274
|
spine.missionPhase("dispatch", block.reason);
|
|
@@ -63390,13 +63699,13 @@ var init_sessionControl = __esm({
|
|
|
63390
63699
|
|
|
63391
63700
|
// src/cli/extensions/sandboxedFs.ts
|
|
63392
63701
|
import { promises as fsp } from "node:fs";
|
|
63393
|
-
import
|
|
63702
|
+
import path83 from "node:path";
|
|
63394
63703
|
function errText(prefix, p3, err) {
|
|
63395
63704
|
const msg = err instanceof Error ? err.message : String(err);
|
|
63396
63705
|
return `[extension-fs] ${prefix} "${p3}": ${msg}`;
|
|
63397
63706
|
}
|
|
63398
63707
|
function bindSandboxedFs(root) {
|
|
63399
|
-
const resolvedRoot =
|
|
63708
|
+
const resolvedRoot = path83.resolve(root);
|
|
63400
63709
|
return {
|
|
63401
63710
|
root: resolvedRoot,
|
|
63402
63711
|
async readFile(relativePath) {
|
|
@@ -63412,7 +63721,7 @@ function bindSandboxedFs(root) {
|
|
|
63412
63721
|
try {
|
|
63413
63722
|
const target = resolveSandboxedPath(relativePath, { root: resolvedRoot });
|
|
63414
63723
|
verifyContainment(target, { root: resolvedRoot });
|
|
63415
|
-
await fsp.mkdir(
|
|
63724
|
+
await fsp.mkdir(path83.dirname(target), { recursive: true });
|
|
63416
63725
|
await fsp.writeFile(target, data, "utf8");
|
|
63417
63726
|
return typedOk({ path: target });
|
|
63418
63727
|
} catch (err) {
|
|
@@ -63597,7 +63906,7 @@ var init_loader = __esm({
|
|
|
63597
63906
|
|
|
63598
63907
|
// src/cli/headless/runOneTurn.ts
|
|
63599
63908
|
import { promises as fs42 } from "node:fs";
|
|
63600
|
-
import
|
|
63909
|
+
import path84 from "node:path";
|
|
63601
63910
|
function planModeFromOpts(opts) {
|
|
63602
63911
|
return (opts.phase ?? "build") === "plan";
|
|
63603
63912
|
}
|
|
@@ -63651,11 +63960,14 @@ async function writeProofSafe(gate, meta3, baseDir = process.cwd()) {
|
|
|
63651
63960
|
);
|
|
63652
63961
|
}
|
|
63653
63962
|
}
|
|
63654
|
-
async function runOneTurn(opts, provider, model, providerStream) {
|
|
63963
|
+
async function runOneTurn(opts, provider, model, providerStream, extras) {
|
|
63655
63964
|
const sessionId2 = crypto.randomUUID();
|
|
63656
63965
|
const cwd = resolveHeadlessCwd(opts);
|
|
63657
63966
|
const memoryFactory = await Promise.resolve().then(() => (init_serviceFactory(), serviceFactory_exports));
|
|
63658
|
-
const
|
|
63967
|
+
const spineHolder = {};
|
|
63968
|
+
const nativeMemory = memoryFactory.isMemoryV2Enabled() ? await memoryFactory.getMemoryService(cwd, process.env, {
|
|
63969
|
+
onEvent: memorySinkFor(spineHolder)
|
|
63970
|
+
}) : void 0;
|
|
63659
63971
|
const memoryAutoWrite = memoryFactory.isMemoryAutoWriteEnabled();
|
|
63660
63972
|
const controlQueue = new RuntimeControlQueue();
|
|
63661
63973
|
const harnessHolder = {};
|
|
@@ -63748,7 +64060,11 @@ async function runOneTurn(opts, provider, model, providerStream) {
|
|
|
63748
64060
|
},
|
|
63749
64061
|
...nativeMemory ? { memoryService: nativeMemory } : {},
|
|
63750
64062
|
memoryAutoWrite,
|
|
63751
|
-
...extensionRuntime ? { extensions: extensionRuntime } : {}
|
|
64063
|
+
...extensionRuntime ? { extensions: extensionRuntime } : {},
|
|
64064
|
+
// t37: serve-harness threads the kernel-owned workspace LspManager here
|
|
64065
|
+
// (TurnExtras). undefined keeps the shared per-root fallback — which is
|
|
64066
|
+
// itself one-manager-per-root since t37, so no cross-workspace thrash.
|
|
64067
|
+
...extras?.lspProvider ? { lspProvider: extras.lspProvider } : {}
|
|
63752
64068
|
});
|
|
63753
64069
|
await registerHeadlessMcp(toolRegistry, opts);
|
|
63754
64070
|
const spine = await openHeadlessSpine({
|
|
@@ -63759,6 +64075,7 @@ async function runOneTurn(opts, provider, model, providerStream) {
|
|
|
63759
64075
|
// 2.6.1 (plan §7): deep specs from THIS run’s registry.
|
|
63760
64076
|
toolSpecs: typeof toolRegistry.fingerprints === "function" ? toolRegistry.fingerprints() : void 0
|
|
63761
64077
|
});
|
|
64078
|
+
spineHolder.current = spine;
|
|
63762
64079
|
const seededHistory = await seedHeadlessModelHistory(spine, opts.history);
|
|
63763
64080
|
emitEvent(sessionStartedEvent(spine));
|
|
63764
64081
|
if (opts.orchestrationDecision) {
|
|
@@ -64067,8 +64384,9 @@ async function runOneTurn(opts, provider, model, providerStream) {
|
|
|
64067
64384
|
},
|
|
64068
64385
|
emit: (input) => spine.appendEvent(input)
|
|
64069
64386
|
};
|
|
64387
|
+
const strictEnv = strictEnvOverlay(opts);
|
|
64070
64388
|
if (pass.finalReason === "completed" && pass.exitCode === 0 && isKrakenMode(opts.mode) && (isKrakenSelectionEnabled() || nativePackEnabled()) && !planModeFromOpts(opts)) {
|
|
64071
|
-
const strictGate = await evaluateStrictBuildGate("build", { emit: (input) => spine.appendEvent(input), cwd });
|
|
64389
|
+
const strictGate = await evaluateStrictBuildGate("build", { emit: (input) => spine.appendEvent(input), cwd, env: strictEnv });
|
|
64072
64390
|
await runAdvisoryVerifierReview(strictGate, verifierReviewDeps).catch(() => void 0);
|
|
64073
64391
|
const gate = strictGate.gate;
|
|
64074
64392
|
const verificationPayload = strictGateEventPayload(strictGate);
|
|
@@ -64103,7 +64421,7 @@ async function runOneTurn(opts, provider, model, providerStream) {
|
|
|
64103
64421
|
successfulWrites: pass.successfulWrites + repair.successfulWrites,
|
|
64104
64422
|
emittedWrites: pass.emittedWrites + repair.emittedWrites
|
|
64105
64423
|
};
|
|
64106
|
-
const after = await evaluateStrictBuildGate("build", { emit: (input) => spine.appendEvent(input), cwd });
|
|
64424
|
+
const after = await evaluateStrictBuildGate("build", { emit: (input) => spine.appendEvent(input), cwd, env: strictEnv });
|
|
64107
64425
|
await runAdvisoryVerifierReview(after, verifierReviewDeps).catch(() => void 0);
|
|
64108
64426
|
const afterPayload = strictGateEventPayload(after);
|
|
64109
64427
|
spine.verificationRun(afterPayload);
|
|
@@ -64138,13 +64456,14 @@ async function runOneTurn(opts, provider, model, providerStream) {
|
|
|
64138
64456
|
await spine.close(closeStatus);
|
|
64139
64457
|
} catch {
|
|
64140
64458
|
}
|
|
64459
|
+
await emitHarnessStateEvent({ spine, workspaceRoot: cwd, output: opts.output, emitEvent });
|
|
64141
64460
|
if (opts.exportSessionPath) {
|
|
64142
64461
|
try {
|
|
64143
64462
|
const json3 = await spine.exportJson();
|
|
64144
64463
|
if (json3) {
|
|
64145
64464
|
if (opts.exportSessionPath === "-") process.stdout.write(json3 + "\n");
|
|
64146
64465
|
else {
|
|
64147
|
-
await fs42.mkdir(
|
|
64466
|
+
await fs42.mkdir(path84.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
64148
64467
|
await fs42.writeFile(opts.exportSessionPath, json3, "utf8");
|
|
64149
64468
|
}
|
|
64150
64469
|
}
|
|
@@ -64200,6 +64519,7 @@ var init_runOneTurn = __esm({
|
|
|
64200
64519
|
init_selectionPlaybook();
|
|
64201
64520
|
init_delegationPolicy();
|
|
64202
64521
|
init_facts();
|
|
64522
|
+
init_spineTelemetry();
|
|
64203
64523
|
init_headless();
|
|
64204
64524
|
init_mode();
|
|
64205
64525
|
init_skills2();
|
|
@@ -64213,6 +64533,7 @@ var init_runOneTurn = __esm({
|
|
|
64213
64533
|
init_modelContextBuilder();
|
|
64214
64534
|
init_metrics3();
|
|
64215
64535
|
init_headlessSpine();
|
|
64536
|
+
init_harnessStateEmit();
|
|
64216
64537
|
init_runtime2();
|
|
64217
64538
|
init_controlBridge();
|
|
64218
64539
|
init_protocol2();
|
|
@@ -65118,9 +65439,9 @@ __export(triggerLock_exports, {
|
|
|
65118
65439
|
releaseLock: () => releaseLock
|
|
65119
65440
|
});
|
|
65120
65441
|
import { promises as fs43 } from "node:fs";
|
|
65121
|
-
import * as
|
|
65442
|
+
import * as path85 from "node:path";
|
|
65122
65443
|
function lockPath(projectRoot) {
|
|
65123
|
-
return
|
|
65444
|
+
return path85.join(projectRoot, ".zelari", "trigger.lock");
|
|
65124
65445
|
}
|
|
65125
65446
|
function isPidAlive(pid) {
|
|
65126
65447
|
try {
|
|
@@ -65133,7 +65454,7 @@ function isPidAlive(pid) {
|
|
|
65133
65454
|
}
|
|
65134
65455
|
async function acquireLock(projectRoot, now = () => /* @__PURE__ */ new Date()) {
|
|
65135
65456
|
const lp = lockPath(projectRoot);
|
|
65136
|
-
const dir =
|
|
65457
|
+
const dir = path85.dirname(lp);
|
|
65137
65458
|
await fs43.mkdir(dir, { recursive: true });
|
|
65138
65459
|
try {
|
|
65139
65460
|
const raw = await fs43.readFile(lp, "utf8");
|
|
@@ -65165,13 +65486,10 @@ var init_triggerLock = __esm({
|
|
|
65165
65486
|
|
|
65166
65487
|
// src/cli/runHeadless.ts
|
|
65167
65488
|
import { promises as fs44 } from "node:fs";
|
|
65168
|
-
import
|
|
65489
|
+
import path86 from "node:path";
|
|
65169
65490
|
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
65170
65491
|
async function runHeadless(opts) {
|
|
65171
65492
|
resetTaskSpawnCount();
|
|
65172
|
-
if (opts.strictDone) {
|
|
65173
|
-
process.env.ZELARI_STRICT_DONE = "1";
|
|
65174
|
-
}
|
|
65175
65493
|
let crashed = false;
|
|
65176
65494
|
const handleFatal = (label, err) => {
|
|
65177
65495
|
if (crashed) return;
|
|
@@ -65245,7 +65563,13 @@ ${err.stack}` : "";
|
|
|
65245
65563
|
model
|
|
65246
65564
|
});
|
|
65247
65565
|
}
|
|
65248
|
-
return dispatchHeadlessTurn(opts, provider, model, providerStream
|
|
65566
|
+
return dispatchHeadlessTurn(opts, provider, model, providerStream, {
|
|
65567
|
+
// H10-fix3: the gate already ran above on the SAME input (no chdir in
|
|
65568
|
+
// between) — the one-shot marker keeps dispatchHeadlessTurn from
|
|
65569
|
+
// re-running it (duplicate `[policy]` stderr warning + double policy
|
|
65570
|
+
// load). Per-invocation flag only; never process-global.
|
|
65571
|
+
policyGateDone: true
|
|
65572
|
+
});
|
|
65249
65573
|
}
|
|
65250
65574
|
async function applyHeadlessPolicyGate(opts) {
|
|
65251
65575
|
const cwd = resolveHeadlessCwd(opts);
|
|
@@ -65257,6 +65581,9 @@ async function applyHeadlessPolicyGate(opts) {
|
|
|
65257
65581
|
reportPolicyLoadBlocked(policyLoad.block, opts.output);
|
|
65258
65582
|
await recordPolicyLoadBlockedOnSpine(policyLoad.block, {
|
|
65259
65583
|
mode: opts.mode,
|
|
65584
|
+
// H10-fix2: the spine must land in the RESOLVED workspace, not the
|
|
65585
|
+
// process cwd — a sidecar hosts N workspaces without `chdir`.
|
|
65586
|
+
workspace: cwd,
|
|
65260
65587
|
...opts.profile ? { profile: opts.profile } : {},
|
|
65261
65588
|
...opts.resumeSessionId ? { resumeSessionId: opts.resumeSessionId } : {}
|
|
65262
65589
|
});
|
|
@@ -65276,7 +65603,7 @@ function applyKrakenTurnEnv(opts) {
|
|
|
65276
65603
|
}
|
|
65277
65604
|
}
|
|
65278
65605
|
}
|
|
65279
|
-
async function dispatchHeadlessTurn(opts, provider, model, providerStream) {
|
|
65606
|
+
async function dispatchHeadlessTurn(opts, provider, model, providerStream, oneShot, extras) {
|
|
65280
65607
|
const cwd = resolveHeadlessCwd(opts);
|
|
65281
65608
|
if (typeof opts.mode === "string") {
|
|
65282
65609
|
const parsed = parseMode(opts.mode);
|
|
@@ -65304,8 +65631,10 @@ async function dispatchHeadlessTurn(opts, provider, model, providerStream) {
|
|
|
65304
65631
|
}
|
|
65305
65632
|
} catch {
|
|
65306
65633
|
}
|
|
65307
|
-
|
|
65308
|
-
|
|
65634
|
+
if (!oneShot?.policyGateDone) {
|
|
65635
|
+
const policyBlock = await applyHeadlessPolicyGate(opts);
|
|
65636
|
+
if (policyBlock !== void 0) return policyBlock;
|
|
65637
|
+
}
|
|
65309
65638
|
if (opts.orchestrationAuto) {
|
|
65310
65639
|
const facts = await collectOrchestrationFacts(cwd);
|
|
65311
65640
|
const verdict = chooseOrchestration(opts.task ?? "", facts);
|
|
@@ -65347,12 +65676,12 @@ async function dispatchHeadlessTurn(opts, provider, model, providerStream) {
|
|
|
65347
65676
|
`);
|
|
65348
65677
|
}
|
|
65349
65678
|
if (mode === "zelari") {
|
|
65350
|
-
return runHeadlessZelari(opts, provider, model, providerStream);
|
|
65679
|
+
return runHeadlessZelari(opts, provider, model, providerStream, extras);
|
|
65351
65680
|
}
|
|
65352
65681
|
if (mode === "council" || opts.useCouncil) {
|
|
65353
|
-
return runHeadlessCouncil(opts, provider, model, providerStream);
|
|
65682
|
+
return runHeadlessCouncil(opts, provider, model, providerStream, extras);
|
|
65354
65683
|
}
|
|
65355
|
-
return runOneTurn(opts, provider, model, providerStream);
|
|
65684
|
+
return runOneTurn(opts, provider, model, providerStream, extras);
|
|
65356
65685
|
}
|
|
65357
65686
|
async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
65358
65687
|
const { isKrakenGraphEnabled: isKrakenGraphEnabled2, KrakenGraphExecutor: KrakenGraphExecutor2 } = await Promise.resolve().then(() => (init_executor(), executor_exports));
|
|
@@ -65372,8 +65701,15 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
65372
65701
|
const { createKrakenSubAgentContextFactory: createKrakenSubAgentContextFactory2 } = await Promise.resolve().then(() => (init_toolRegistry(), toolRegistry_exports));
|
|
65373
65702
|
const cwd = resolveHeadlessCwd(opts);
|
|
65374
65703
|
const sessionId2 = crypto.randomUUID();
|
|
65704
|
+
const spine = await openHeadlessSpine({ sessionId: sessionId2, mode: "kraken", workspace: cwd });
|
|
65705
|
+
if (opts.output === "json") emitEvent(sessionStartedEvent(spine));
|
|
65706
|
+
spine.userMessage(prompt);
|
|
65375
65707
|
const { getMemoryService: getMemoryService2, isMemoryAutoWriteEnabled: isMemoryAutoWriteEnabled2, isMemoryV2Enabled: isMemoryV2Enabled2 } = await Promise.resolve().then(() => (init_serviceFactory(), serviceFactory_exports));
|
|
65376
|
-
const graphMemory = isMemoryV2Enabled2() ? await getMemoryService2(cwd, process.env
|
|
65708
|
+
const graphMemory = isMemoryV2Enabled2() ? await getMemoryService2(cwd, process.env, {
|
|
65709
|
+
// W2: the spine is already open here — memory events are noted
|
|
65710
|
+
// directly (context.projection / memory_event state-only payloads).
|
|
65711
|
+
onEvent: (event) => spineMemoryEventNote(spine, event)
|
|
65712
|
+
}) : void 0;
|
|
65377
65713
|
const log = (message) => {
|
|
65378
65714
|
if (opts.output === "json") {
|
|
65379
65715
|
emitEvent({ type: "log", message });
|
|
@@ -65388,28 +65724,32 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
65388
65724
|
abort.abort();
|
|
65389
65725
|
};
|
|
65390
65726
|
process.once("SIGINT", onSigint);
|
|
65727
|
+
let exitCode = 0;
|
|
65391
65728
|
try {
|
|
65392
65729
|
let preflightGraph;
|
|
65393
65730
|
if (opts.runPlan && opts.runPlan.trim() !== "") {
|
|
65394
|
-
const planPath =
|
|
65731
|
+
const planPath = path86.join(cwd, ".zelari", "radio", `plan-${opts.runPlan}.json`);
|
|
65395
65732
|
log(`loading pre-flight plan: ${planPath}`);
|
|
65396
65733
|
let raw;
|
|
65397
65734
|
try {
|
|
65398
65735
|
raw = await fs44.readFile(planPath, "utf8");
|
|
65399
65736
|
} catch (e) {
|
|
65400
65737
|
log(`plan file not found: ${planPath} (${e.message})`);
|
|
65401
|
-
|
|
65738
|
+
exitCode = 1;
|
|
65739
|
+
return exitCode;
|
|
65402
65740
|
}
|
|
65403
65741
|
let planJson;
|
|
65404
65742
|
try {
|
|
65405
65743
|
planJson = JSON.parse(raw);
|
|
65406
65744
|
} catch (e) {
|
|
65407
65745
|
log(`plan file is malformed JSON: ${e.message}`);
|
|
65408
|
-
|
|
65746
|
+
exitCode = 1;
|
|
65747
|
+
return exitCode;
|
|
65409
65748
|
}
|
|
65410
65749
|
if (!planJson || !Array.isArray(planJson.nodes)) {
|
|
65411
65750
|
log(`plan file is malformed: missing "nodes" array`);
|
|
65412
|
-
|
|
65751
|
+
exitCode = 1;
|
|
65752
|
+
return exitCode;
|
|
65413
65753
|
}
|
|
65414
65754
|
const { createGraph: createGraph2, validateGraph: validateGraph2 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
|
|
65415
65755
|
const validated = createGraph2(planJson.graphId ?? opts.runPlan, planJson.nodes);
|
|
@@ -65431,8 +65771,8 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
65431
65771
|
log(formatKrakenGraphAscii2(graph));
|
|
65432
65772
|
if (opts.planOnly) {
|
|
65433
65773
|
const planId = randomUUID10();
|
|
65434
|
-
const planDir =
|
|
65435
|
-
const planPath =
|
|
65774
|
+
const planDir = path86.join(cwd, ".zelari", "radio");
|
|
65775
|
+
const planPath = path86.join(planDir, `plan-${planId}.json`);
|
|
65436
65776
|
await fs44.mkdir(planDir, { recursive: true });
|
|
65437
65777
|
await fs44.writeFile(
|
|
65438
65778
|
planPath,
|
|
@@ -65451,9 +65791,11 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
65451
65791
|
emitEvent({ type: "log", message: `plan_only_id=${planId}` });
|
|
65452
65792
|
emitEvent({ type: "log", message: `plan_only_path=${planPath}` });
|
|
65453
65793
|
}
|
|
65454
|
-
|
|
65794
|
+
exitCode = 0;
|
|
65795
|
+
return exitCode;
|
|
65455
65796
|
}
|
|
65456
65797
|
const audit = new AuditLogger2();
|
|
65798
|
+
const { runTentacle: runTentacle2 } = await Promise.resolve().then(() => (init_tentacle(), tentacle_exports));
|
|
65457
65799
|
const executor = new KrakenGraphExecutor2({
|
|
65458
65800
|
taskToolDeps: {
|
|
65459
65801
|
createSubAgentContext: createKrakenSubAgentContextFactory2({
|
|
@@ -65486,7 +65828,11 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
65486
65828
|
parentCwd: cwd,
|
|
65487
65829
|
sessionId: sessionId2,
|
|
65488
65830
|
goal: prompt,
|
|
65489
|
-
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))
|
|
65490
65836
|
});
|
|
65491
65837
|
const summary = await executor.execute(graph);
|
|
65492
65838
|
if (summary.cancelled) log("graph cancelled \u2014 partial results below");
|
|
@@ -65508,7 +65854,8 @@ ${formatKrakenGraphDigest2(
|
|
|
65508
65854
|
process.stdout.write(`${finalAscii}
|
|
65509
65855
|
`);
|
|
65510
65856
|
}
|
|
65511
|
-
|
|
65857
|
+
exitCode = summary.converged ? 0 : 3;
|
|
65858
|
+
return exitCode;
|
|
65512
65859
|
} catch (err) {
|
|
65513
65860
|
const message = err instanceof Error ? err.message : String(err);
|
|
65514
65861
|
if (opts.output === "json") {
|
|
@@ -65517,17 +65864,56 @@ ${formatKrakenGraphDigest2(
|
|
|
65517
65864
|
process.stderr.write(`[zelari-code --headless] kraken graph failed: ${message}
|
|
65518
65865
|
`);
|
|
65519
65866
|
}
|
|
65520
|
-
|
|
65867
|
+
exitCode = 2;
|
|
65868
|
+
return exitCode;
|
|
65521
65869
|
} finally {
|
|
65522
65870
|
process.off("SIGINT", onSigint);
|
|
65523
65871
|
await graphMemory?.close().catch(() => void 0);
|
|
65872
|
+
try {
|
|
65873
|
+
const closeReason = abort.signal.aborted ? "cancelled" : exitCode === 0 ? "completed" : "error";
|
|
65874
|
+
await spine.close(closeReason);
|
|
65875
|
+
} catch {
|
|
65876
|
+
}
|
|
65877
|
+
await emitHarnessStateEvent({ spine, workspaceRoot: cwd, output: opts.output, emitEvent });
|
|
65524
65878
|
}
|
|
65525
65879
|
}
|
|
65526
|
-
|
|
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
|
+
}
|
|
65911
|
+
async function buildCouncilToolRegistry(planMode, opts, memoryService, memoryAutoWrite = false, extras) {
|
|
65527
65912
|
const cwd = opts ? resolveHeadlessCwd(opts) : process.cwd();
|
|
65528
65913
|
const { registry: toolRegistry } = createBuiltinToolRegistry({
|
|
65529
65914
|
root: cwd,
|
|
65530
65915
|
planMode,
|
|
65916
|
+
...extras?.lspProvider ? { lspProvider: extras.lspProvider } : {},
|
|
65531
65917
|
permissionPolicy: {
|
|
65532
65918
|
read: "allow",
|
|
65533
65919
|
write: "allow",
|
|
@@ -65554,12 +65940,15 @@ async function buildCouncilToolRegistry(planMode, opts, memoryService, memoryAut
|
|
|
65554
65940
|
}
|
|
65555
65941
|
return { toolRegistry, workspaceCtx: realCtx };
|
|
65556
65942
|
}
|
|
65557
|
-
async function runHeadlessCouncil(opts, provider, model, providerStream) {
|
|
65943
|
+
async function runHeadlessCouncil(opts, provider, model, providerStream, extras) {
|
|
65558
65944
|
const { dispatchCouncil: dispatchCouncil2 } = await Promise.resolve().then(() => (init_councilDispatcher(), councilDispatcher_exports));
|
|
65559
65945
|
const sessionId2 = crypto.randomUUID();
|
|
65560
65946
|
const cwd = resolveHeadlessCwd(opts);
|
|
65561
65947
|
const memoryFactory = await Promise.resolve().then(() => (init_serviceFactory(), serviceFactory_exports));
|
|
65562
|
-
const
|
|
65948
|
+
const spineHolder = {};
|
|
65949
|
+
const nativeMemory = memoryFactory.isMemoryV2Enabled() ? await memoryFactory.getMemoryService(cwd, process.env, {
|
|
65950
|
+
onEvent: memorySinkFor(spineHolder)
|
|
65951
|
+
}) : void 0;
|
|
65563
65952
|
const memoryAutoWrite = memoryFactory.isMemoryAutoWriteEnabled();
|
|
65564
65953
|
const spine = await openHeadlessSpine({
|
|
65565
65954
|
sessionId: opts.resumeSessionId ?? sessionId2,
|
|
@@ -65567,6 +65956,7 @@ async function runHeadlessCouncil(opts, provider, model, providerStream) {
|
|
|
65567
65956
|
profile: opts.profile,
|
|
65568
65957
|
workspace: cwd
|
|
65569
65958
|
});
|
|
65959
|
+
spineHolder.current = spine;
|
|
65570
65960
|
const seededHistory = await seedHeadlessModelHistory(spine, opts.history);
|
|
65571
65961
|
emitEvent(sessionStartedEvent(spine));
|
|
65572
65962
|
if (opts.orchestrationDecision) {
|
|
@@ -65586,7 +65976,8 @@ async function runHeadlessCouncil(opts, provider, model, providerStream) {
|
|
|
65586
65976
|
planModeFromOpts(opts) || softGated,
|
|
65587
65977
|
opts,
|
|
65588
65978
|
nativeMemory,
|
|
65589
|
-
memoryAutoWrite
|
|
65979
|
+
memoryAutoWrite,
|
|
65980
|
+
extras
|
|
65590
65981
|
);
|
|
65591
65982
|
const { FeedbackStore: FeedbackStore2 } = await Promise.resolve().then(() => (init_councilFeedback(), councilFeedback_exports));
|
|
65592
65983
|
const feedbackStore = new FeedbackStore2();
|
|
@@ -65715,13 +66106,14 @@ async function runHeadlessCouncil(opts, provider, model, providerStream) {
|
|
|
65715
66106
|
await spine.close(exitCode === 0 ? "completed" : "error");
|
|
65716
66107
|
} catch {
|
|
65717
66108
|
}
|
|
66109
|
+
await emitHarnessStateEvent({ spine, workspaceRoot: cwd, output: opts.output, emitEvent });
|
|
65718
66110
|
if (opts.exportSessionPath) {
|
|
65719
66111
|
try {
|
|
65720
66112
|
const json3 = await spine.exportJson();
|
|
65721
66113
|
if (json3) {
|
|
65722
66114
|
if (opts.exportSessionPath === "-") process.stdout.write(json3 + "\n");
|
|
65723
66115
|
else {
|
|
65724
|
-
await fs44.mkdir(
|
|
66116
|
+
await fs44.mkdir(path86.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
65725
66117
|
await fs44.writeFile(opts.exportSessionPath, json3, "utf8");
|
|
65726
66118
|
}
|
|
65727
66119
|
}
|
|
@@ -65754,7 +66146,7 @@ async function runHeadlessCouncil(opts, provider, model, providerStream) {
|
|
|
65754
66146
|
await nativeMemory?.close().catch(() => void 0);
|
|
65755
66147
|
return exitCode;
|
|
65756
66148
|
}
|
|
65757
|
-
async function runHeadlessZelari(opts, provider, model, providerStream) {
|
|
66149
|
+
async function runHeadlessZelari(opts, provider, model, providerStream, extras) {
|
|
65758
66150
|
const projectRoot = resolveHeadlessCwd(opts);
|
|
65759
66151
|
const sessionId2 = opts.resumeSessionId ?? crypto.randomUUID();
|
|
65760
66152
|
const spine = await openHeadlessSpine({
|
|
@@ -65777,13 +66169,18 @@ async function runHeadlessZelari(opts, provider, model, providerStream) {
|
|
|
65777
66169
|
userMessage: opts.task,
|
|
65778
66170
|
hasPlan: hasWorkspacePlan2(projectRoot)
|
|
65779
66171
|
});
|
|
65780
|
-
const memory = await getMemoryBackend2(
|
|
66172
|
+
const memory = await getMemoryBackend2(
|
|
66173
|
+
projectRoot,
|
|
66174
|
+
process.env,
|
|
66175
|
+
(event) => spineMemoryEventNote(spine, event)
|
|
66176
|
+
);
|
|
65781
66177
|
const nativeMissionMemory = memory.service;
|
|
65782
66178
|
const { toolRegistry, workspaceCtx } = await buildCouncilToolRegistry(
|
|
65783
66179
|
planModeFromOpts(opts),
|
|
65784
66180
|
opts,
|
|
65785
66181
|
nativeMissionMemory,
|
|
65786
|
-
Boolean(nativeMissionMemory) && process.env.ZELARI_MEMORY_AUTO_WRITE !== "0"
|
|
66182
|
+
Boolean(nativeMissionMemory) && process.env.ZELARI_MEMORY_AUTO_WRITE !== "0",
|
|
66183
|
+
extras
|
|
65787
66184
|
);
|
|
65788
66185
|
const feedbackStore = new FeedbackStore2();
|
|
65789
66186
|
const chairmanBudget = envNumber(process.env.ZELARI_MODE_MAX_TOOLS_LUCIFER, {
|
|
@@ -66096,6 +66493,8 @@ ${ragContext}` : slicePrompt;
|
|
|
66096
66493
|
const missionGate = await evaluateStrictBuildGate("build", {
|
|
66097
66494
|
emit: (input) => spine.appendEvent(input),
|
|
66098
66495
|
surface: "mission",
|
|
66496
|
+
// H10-fix1: per-invocation env overlay — never process.env.
|
|
66497
|
+
env: strictEnvOverlay(opts),
|
|
66099
66498
|
cwd: projectRoot
|
|
66100
66499
|
});
|
|
66101
66500
|
const missionVerificationPayload = strictGateEventPayload(missionGate);
|
|
@@ -66132,13 +66531,14 @@ ${ragContext}` : slicePrompt;
|
|
|
66132
66531
|
else await spine.close(exitCode === 2 ? "error" : "stopped");
|
|
66133
66532
|
} catch {
|
|
66134
66533
|
}
|
|
66534
|
+
await emitHarnessStateEvent({ spine, workspaceRoot: projectRoot, output: opts.output, emitEvent });
|
|
66135
66535
|
if (opts.exportSessionPath) {
|
|
66136
66536
|
try {
|
|
66137
66537
|
const json3 = await spine.exportJson();
|
|
66138
66538
|
if (json3) {
|
|
66139
66539
|
if (opts.exportSessionPath === "-") process.stdout.write(json3 + "\n");
|
|
66140
66540
|
else {
|
|
66141
|
-
await fs44.mkdir(
|
|
66541
|
+
await fs44.mkdir(path86.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
66142
66542
|
await fs44.writeFile(opts.exportSessionPath, json3, "utf8");
|
|
66143
66543
|
}
|
|
66144
66544
|
}
|
|
@@ -66157,6 +66557,7 @@ var init_runHeadless = __esm({
|
|
|
66157
66557
|
init_toolRegistry();
|
|
66158
66558
|
init_policy();
|
|
66159
66559
|
init_facts();
|
|
66560
|
+
init_spineTelemetry();
|
|
66160
66561
|
init_councilConfig();
|
|
66161
66562
|
init_headless();
|
|
66162
66563
|
init_claudeProvider();
|
|
@@ -66172,6 +66573,7 @@ var init_runHeadless = __esm({
|
|
|
66172
66573
|
init_modelContextBuilder();
|
|
66173
66574
|
init_metrics3();
|
|
66174
66575
|
init_headlessSpine();
|
|
66576
|
+
init_harnessStateEmit();
|
|
66175
66577
|
init_policyGate();
|
|
66176
66578
|
init_policyLoadMode();
|
|
66177
66579
|
init_runOneTurn();
|
|
@@ -66749,7 +67151,7 @@ function upsertSkill(opts) {
|
|
|
66749
67151
|
}
|
|
66750
67152
|
dir = getProjectSkillsDir(root);
|
|
66751
67153
|
}
|
|
66752
|
-
const
|
|
67154
|
+
const path91 = skillFilePath(dir, name);
|
|
66753
67155
|
const content = serializeSkillMd({
|
|
66754
67156
|
name,
|
|
66755
67157
|
description,
|
|
@@ -66758,13 +67160,13 @@ function upsertSkill(opts) {
|
|
|
66758
67160
|
tools: opts.tools,
|
|
66759
67161
|
cost: opts.cost
|
|
66760
67162
|
});
|
|
66761
|
-
const parsed = parseSkillMd(content,
|
|
67163
|
+
const parsed = parseSkillMd(content, path91);
|
|
66762
67164
|
if (!parsed) {
|
|
66763
67165
|
return { ok: false, error: "Generated SKILL.md failed validation" };
|
|
66764
67166
|
}
|
|
66765
|
-
mkdirSync21(dirname13(
|
|
66766
|
-
writeFileSync24(
|
|
66767
|
-
return { ok: true, path:
|
|
67167
|
+
mkdirSync21(dirname13(path91), { recursive: true });
|
|
67168
|
+
writeFileSync24(path91, content, "utf8");
|
|
67169
|
+
return { ok: true, path: path91 };
|
|
66768
67170
|
}
|
|
66769
67171
|
function removeSkill(opts) {
|
|
66770
67172
|
const name = opts.name.trim().toLowerCase();
|
|
@@ -66782,8 +67184,8 @@ function removeSkill(opts) {
|
|
|
66782
67184
|
dir = getProjectSkillsDir(root);
|
|
66783
67185
|
}
|
|
66784
67186
|
const skillDir = join46(dir, name);
|
|
66785
|
-
const
|
|
66786
|
-
if (!existsSync52(
|
|
67187
|
+
const path91 = skillFilePath(dir, name);
|
|
67188
|
+
if (!existsSync52(path91) && !existsSync52(skillDir)) {
|
|
66787
67189
|
return { ok: false, error: `Skill "${name}" not found in ${dir}` };
|
|
66788
67190
|
}
|
|
66789
67191
|
try {
|
|
@@ -66794,7 +67196,7 @@ function removeSkill(opts) {
|
|
|
66794
67196
|
error: err instanceof Error ? err.message : String(err)
|
|
66795
67197
|
};
|
|
66796
67198
|
}
|
|
66797
|
-
return { ok: true, path:
|
|
67199
|
+
return { ok: true, path: path91 };
|
|
66798
67200
|
}
|
|
66799
67201
|
var NAME_RE, BUILTIN_SKILL_MODULES, builtinsLoaded;
|
|
66800
67202
|
var init_skillConfigIo = __esm({
|
|
@@ -66913,7 +67315,7 @@ var init_jsonApi = __esm({
|
|
|
66913
67315
|
});
|
|
66914
67316
|
|
|
66915
67317
|
// src/cli/memory/mcpAdapter.ts
|
|
66916
|
-
import * as
|
|
67318
|
+
import * as path87 from "node:path";
|
|
66917
67319
|
var id2, projectId, source, SearchSchema, AddSchema, LinkSchema, RetractSchema, MEMORY_MCP_TOOLS, MemoryMcpAdapter;
|
|
66918
67320
|
var init_mcpAdapter = __esm({
|
|
66919
67321
|
"src/cli/memory/mcpAdapter.ts"() {
|
|
@@ -67083,8 +67485,8 @@ var init_mcpAdapter = __esm({
|
|
|
67083
67485
|
this.takeWrite();
|
|
67084
67486
|
const externalFile = args.source?.file;
|
|
67085
67487
|
if (externalFile) {
|
|
67086
|
-
const normalized =
|
|
67087
|
-
if (
|
|
67488
|
+
const normalized = path87.normalize(externalFile);
|
|
67489
|
+
if (path87.isAbsolute(normalized) || normalized === ".." || normalized.startsWith(`..${path87.sep}`)) {
|
|
67088
67490
|
throw new Error("source.file must be project-relative and cannot escape the project");
|
|
67089
67491
|
}
|
|
67090
67492
|
}
|
|
@@ -67612,12 +68014,12 @@ function ensureHome() {
|
|
|
67612
68014
|
}
|
|
67613
68015
|
}
|
|
67614
68016
|
function loadCompanionConfig() {
|
|
67615
|
-
const
|
|
67616
|
-
if (!existsSync53(
|
|
68017
|
+
const path91 = getCompanionConfigPath();
|
|
68018
|
+
if (!existsSync53(path91)) {
|
|
67617
68019
|
return { projects: [] };
|
|
67618
68020
|
}
|
|
67619
68021
|
try {
|
|
67620
|
-
const raw = JSON.parse(readFileSync41(
|
|
68022
|
+
const raw = JSON.parse(readFileSync41(path91, "utf8"));
|
|
67621
68023
|
const projects = Array.isArray(raw.projects) ? raw.projects.filter(
|
|
67622
68024
|
(p3) => p3 && typeof p3.path === "string" && p3.path.trim() && typeof (p3.id ?? p3.name) === "string"
|
|
67623
68025
|
).map((p3) => ({
|
|
@@ -67655,16 +68057,16 @@ function loadOrCreateToken(explicit) {
|
|
|
67655
68057
|
return { token: explicit.trim(), created: false };
|
|
67656
68058
|
}
|
|
67657
68059
|
ensureHome();
|
|
67658
|
-
const
|
|
67659
|
-
if (existsSync53(
|
|
67660
|
-
const t = readFileSync41(
|
|
68060
|
+
const path91 = getCompanionTokenPath();
|
|
68061
|
+
if (existsSync53(path91)) {
|
|
68062
|
+
const t = readFileSync41(path91, "utf8").trim();
|
|
67661
68063
|
if (t) return { token: t, created: false };
|
|
67662
68064
|
}
|
|
67663
68065
|
const token = randomBytes7(24).toString("base64url");
|
|
67664
|
-
writeFileSync25(
|
|
68066
|
+
writeFileSync25(path91, token + "\n", "utf8");
|
|
67665
68067
|
try {
|
|
67666
68068
|
const fs45 = __require("node:fs");
|
|
67667
|
-
fs45.chmodSync?.(
|
|
68069
|
+
fs45.chmodSync?.(path91, 384);
|
|
67668
68070
|
} catch {
|
|
67669
68071
|
}
|
|
67670
68072
|
return { token, created: true };
|
|
@@ -67689,17 +68091,17 @@ function mergeProjects(cfg, extraPaths) {
|
|
|
67689
68091
|
byId.set(p3.id, p3);
|
|
67690
68092
|
}
|
|
67691
68093
|
for (const raw of extraPaths) {
|
|
67692
|
-
const
|
|
67693
|
-
if (!
|
|
67694
|
-
let id3 = slugFromPath(
|
|
68094
|
+
const path91 = raw.trim();
|
|
68095
|
+
if (!path91) continue;
|
|
68096
|
+
let id3 = slugFromPath(path91);
|
|
67695
68097
|
let n = 2;
|
|
67696
|
-
while (byId.has(id3) && byId.get(id3).path !==
|
|
67697
|
-
id3 = `${slugFromPath(
|
|
68098
|
+
while (byId.has(id3) && byId.get(id3).path !== path91) {
|
|
68099
|
+
id3 = `${slugFromPath(path91)}-${n++}`;
|
|
67698
68100
|
}
|
|
67699
68101
|
byId.set(id3, {
|
|
67700
68102
|
id: id3,
|
|
67701
|
-
name: slugFromPath(
|
|
67702
|
-
path:
|
|
68103
|
+
name: slugFromPath(path91),
|
|
68104
|
+
path: path91
|
|
67703
68105
|
});
|
|
67704
68106
|
}
|
|
67705
68107
|
return [...byId.values()];
|
|
@@ -67752,6 +68154,7 @@ __export(harnessServer_exports, {
|
|
|
67752
68154
|
bindHarnessTurnOptions: () => bindHarnessTurnOptions,
|
|
67753
68155
|
createCliRunTurn: () => createCliRunTurn,
|
|
67754
68156
|
createCliWorkspaceServices: () => createCliWorkspaceServices,
|
|
68157
|
+
resolveTurnLspProvider: () => resolveTurnLspProvider,
|
|
67755
68158
|
runHarnessServer: () => runHarnessServer,
|
|
67756
68159
|
startHarnessServer: () => startHarnessServer
|
|
67757
68160
|
});
|
|
@@ -67797,6 +68200,10 @@ function bindHarnessTurnOptions(input, workspaceRoot) {
|
|
|
67797
68200
|
useCouncil: turnInput.useCouncil === true || mode === "council"
|
|
67798
68201
|
};
|
|
67799
68202
|
}
|
|
68203
|
+
function resolveTurnLspProvider(services) {
|
|
68204
|
+
const candidate = services?.lspManager;
|
|
68205
|
+
return candidate instanceof LspManager ? candidate : void 0;
|
|
68206
|
+
}
|
|
67800
68207
|
function createCliRunTurn() {
|
|
67801
68208
|
let streamPromise = null;
|
|
67802
68209
|
const ensureStream = () => {
|
|
@@ -67823,11 +68230,14 @@ function createCliRunTurn() {
|
|
|
67823
68230
|
return async (input, deps) => {
|
|
67824
68231
|
const { provider, model, stream } = await ensureStream();
|
|
67825
68232
|
const opts = bindHarnessTurnOptions(input, deps.session.workspaceRoot);
|
|
68233
|
+
const lspProvider = resolveTurnLspProvider(deps.services);
|
|
67826
68234
|
const exitCode = await dispatchHeadlessTurn(
|
|
67827
68235
|
opts,
|
|
67828
68236
|
provider,
|
|
67829
68237
|
model,
|
|
67830
|
-
stream
|
|
68238
|
+
stream,
|
|
68239
|
+
void 0,
|
|
68240
|
+
lspProvider ? { lspProvider } : void 0
|
|
67831
68241
|
);
|
|
67832
68242
|
return { exitCode };
|
|
67833
68243
|
};
|
|
@@ -68666,9 +69076,9 @@ async function runCompanionServe(opts = {}) {
|
|
|
68666
69076
|
return;
|
|
68667
69077
|
}
|
|
68668
69078
|
const url2 = parseUrl(req);
|
|
68669
|
-
const
|
|
69079
|
+
const path91 = url2.pathname.replace(/\/+$/, "") || "/";
|
|
68670
69080
|
try {
|
|
68671
|
-
if (req.method === "GET" && (
|
|
69081
|
+
if (req.method === "GET" && (path91 === "/health" || path91 === "/v1/health")) {
|
|
68672
69082
|
sendJson2(res, 200, {
|
|
68673
69083
|
ok: true,
|
|
68674
69084
|
service: "zelari-companion",
|
|
@@ -68680,18 +69090,18 @@ async function runCompanionServe(opts = {}) {
|
|
|
68680
69090
|
});
|
|
68681
69091
|
return;
|
|
68682
69092
|
}
|
|
68683
|
-
if (
|
|
69093
|
+
if (path91.startsWith("/v1")) {
|
|
68684
69094
|
if (!tokenMatches(token, getBearer(req))) {
|
|
68685
69095
|
sendJson2(res, 401, { ok: false, error: "unauthorized" });
|
|
68686
69096
|
return;
|
|
68687
69097
|
}
|
|
68688
69098
|
}
|
|
68689
|
-
if (req.method === "GET" &&
|
|
69099
|
+
if (req.method === "GET" && path91 === "/v1/config") {
|
|
68690
69100
|
const snap = buildDesktopConfigSnapshot();
|
|
68691
69101
|
sendJson2(res, 200, { ok: true, ...snap });
|
|
68692
69102
|
return;
|
|
68693
69103
|
}
|
|
68694
|
-
if (req.method === "GET" &&
|
|
69104
|
+
if (req.method === "GET" && path91 === "/v1/projects") {
|
|
68695
69105
|
sendJson2(res, 200, {
|
|
68696
69106
|
ok: true,
|
|
68697
69107
|
projects: projects.map((p3) => ({
|
|
@@ -68702,7 +69112,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
68702
69112
|
});
|
|
68703
69113
|
return;
|
|
68704
69114
|
}
|
|
68705
|
-
if (req.method === "GET" &&
|
|
69115
|
+
if (req.method === "GET" && path91 === "/v1/runs") {
|
|
68706
69116
|
sendJson2(res, 200, {
|
|
68707
69117
|
ok: true,
|
|
68708
69118
|
active: runs.getActive(),
|
|
@@ -68720,7 +69130,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
68720
69130
|
});
|
|
68721
69131
|
return;
|
|
68722
69132
|
}
|
|
68723
|
-
if (req.method === "POST" &&
|
|
69133
|
+
if (req.method === "POST" && path91 === "/v1/runs") {
|
|
68724
69134
|
const raw = await readBody(req);
|
|
68725
69135
|
let body = {};
|
|
68726
69136
|
try {
|
|
@@ -68763,11 +69173,12 @@ async function runCompanionServe(opts = {}) {
|
|
|
68763
69173
|
createdAt: result.run.createdAt
|
|
68764
69174
|
},
|
|
68765
69175
|
eventsUrl: `/v1/runs/${result.run.id}/events`,
|
|
68766
|
-
cancelUrl: `/v1/runs/${result.run.id}/cancel
|
|
69176
|
+
cancelUrl: `/v1/runs/${result.run.id}/cancel`,
|
|
69177
|
+
steerUrl: `/v1/runs/${result.run.id}/steer`
|
|
68767
69178
|
});
|
|
68768
69179
|
return;
|
|
68769
69180
|
}
|
|
68770
|
-
const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(
|
|
69181
|
+
const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(path91);
|
|
68771
69182
|
if (req.method === "GET" && eventsMatch) {
|
|
68772
69183
|
const runId = eventsMatch[1];
|
|
68773
69184
|
const run = runs.getRun(runId);
|
|
@@ -68832,7 +69243,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
68832
69243
|
}, 500);
|
|
68833
69244
|
return;
|
|
68834
69245
|
}
|
|
68835
|
-
const cancelMatch = /^\/v1\/runs\/([^/]+)\/cancel$/.exec(
|
|
69246
|
+
const cancelMatch = /^\/v1\/runs\/([^/]+)\/cancel$/.exec(path91);
|
|
68836
69247
|
if (req.method === "POST" && cancelMatch) {
|
|
68837
69248
|
const runId = cancelMatch[1];
|
|
68838
69249
|
const result = runs.cancel(runId);
|
|
@@ -68843,6 +69254,30 @@ async function runCompanionServe(opts = {}) {
|
|
|
68843
69254
|
sendJson2(res, 200, { ok: true, cancelled: runId });
|
|
68844
69255
|
return;
|
|
68845
69256
|
}
|
|
69257
|
+
const steerMatch = /^\/v1\/runs\/([^/]+)\/steer$/.exec(path91);
|
|
69258
|
+
if (req.method === "POST" && steerMatch) {
|
|
69259
|
+
const runId = steerMatch[1];
|
|
69260
|
+
const raw = await readBody(req);
|
|
69261
|
+
let body = {};
|
|
69262
|
+
try {
|
|
69263
|
+
body = raw ? JSON.parse(raw) : {};
|
|
69264
|
+
} catch {
|
|
69265
|
+
sendJson2(res, 400, { ok: false, error: "invalid JSON body" });
|
|
69266
|
+
return;
|
|
69267
|
+
}
|
|
69268
|
+
const text = typeof body.text === "string" ? body.text.trim() : "";
|
|
69269
|
+
if (!text) {
|
|
69270
|
+
sendJson2(res, 400, { ok: false, error: "text is required" });
|
|
69271
|
+
return;
|
|
69272
|
+
}
|
|
69273
|
+
const result = await runs.steer(runId, text);
|
|
69274
|
+
if (!result.ok) {
|
|
69275
|
+
sendJson2(res, 404, { ok: false, error: result.error });
|
|
69276
|
+
return;
|
|
69277
|
+
}
|
|
69278
|
+
sendJson2(res, 200, { ok: true, steered: runId, result: result.result });
|
|
69279
|
+
return;
|
|
69280
|
+
}
|
|
68846
69281
|
sendJson2(res, 404, { ok: false, error: "not found" });
|
|
68847
69282
|
} catch (err) {
|
|
68848
69283
|
sendJson2(res, 500, {
|
|
@@ -68986,11 +69421,11 @@ import { execSync as execSync2 } from "node:child_process";
|
|
|
68986
69421
|
import { existsSync as existsSync55, readFileSync as readFileSync42, readlinkSync, statSync as statSync10 } from "node:fs";
|
|
68987
69422
|
import { createRequire as createRequire3 } from "node:module";
|
|
68988
69423
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
68989
|
-
import
|
|
69424
|
+
import path88 from "node:path";
|
|
68990
69425
|
function findPackageRoot(start) {
|
|
68991
69426
|
let dir = start;
|
|
68992
69427
|
for (let i = 0; i < 6; i += 1) {
|
|
68993
|
-
const candidate =
|
|
69428
|
+
const candidate = path88.join(dir, "package.json");
|
|
68994
69429
|
if (existsSync55(candidate)) {
|
|
68995
69430
|
try {
|
|
68996
69431
|
const pkg = JSON.parse(readFileSync42(candidate, "utf8"));
|
|
@@ -68998,11 +69433,11 @@ function findPackageRoot(start) {
|
|
|
68998
69433
|
} catch {
|
|
68999
69434
|
}
|
|
69000
69435
|
}
|
|
69001
|
-
const parent =
|
|
69436
|
+
const parent = path88.dirname(dir);
|
|
69002
69437
|
if (parent === dir) break;
|
|
69003
69438
|
dir = parent;
|
|
69004
69439
|
}
|
|
69005
|
-
return
|
|
69440
|
+
return path88.resolve(__dirname3, "..", "..", "..");
|
|
69006
69441
|
}
|
|
69007
69442
|
function tryExec(cmd) {
|
|
69008
69443
|
try {
|
|
@@ -69016,7 +69451,7 @@ function tryExec(cmd) {
|
|
|
69016
69451
|
}
|
|
69017
69452
|
function readPackageJson4() {
|
|
69018
69453
|
try {
|
|
69019
|
-
const pkgPath =
|
|
69454
|
+
const pkgPath = path88.join(packageRoot, "package.json");
|
|
69020
69455
|
return JSON.parse(readFileSync42(pkgPath, "utf8"));
|
|
69021
69456
|
} catch {
|
|
69022
69457
|
return null;
|
|
@@ -69032,7 +69467,7 @@ function checkShim(pkgName) {
|
|
|
69032
69467
|
}
|
|
69033
69468
|
const isWin = process.platform === "win32";
|
|
69034
69469
|
const shimName = isWin ? "zelari-code.cmd" : "zelari-code";
|
|
69035
|
-
const shimPath =
|
|
69470
|
+
const shimPath = path88.join(prefix, shimName);
|
|
69036
69471
|
if (!existsSync55(shimPath)) {
|
|
69037
69472
|
return FAIL(
|
|
69038
69473
|
`shim not found at ${shimPath}
|
|
@@ -69060,8 +69495,8 @@ function checkShim(pkgName) {
|
|
|
69060
69495
|
fix: npm install -g ${pkgName}@latest --force`
|
|
69061
69496
|
);
|
|
69062
69497
|
}
|
|
69063
|
-
const resolved =
|
|
69064
|
-
const expected =
|
|
69498
|
+
const resolved = path88.resolve(path88.dirname(shimPath), target);
|
|
69499
|
+
const expected = path88.join(
|
|
69065
69500
|
prefix,
|
|
69066
69501
|
"node_modules",
|
|
69067
69502
|
pkgName,
|
|
@@ -69100,7 +69535,7 @@ function checkNode(pkg) {
|
|
|
69100
69535
|
return OK(`node ${raw}`);
|
|
69101
69536
|
}
|
|
69102
69537
|
function checkBundle() {
|
|
69103
|
-
const bundle =
|
|
69538
|
+
const bundle = path88.join(packageRoot, "dist", "cli", "main.bundled.js");
|
|
69104
69539
|
if (!existsSync55(bundle)) {
|
|
69105
69540
|
return FAIL(
|
|
69106
69541
|
`dist/cli/main.bundled.js missing at ${bundle}
|
|
@@ -69121,7 +69556,7 @@ function checkRuntimeDeps() {
|
|
|
69121
69556
|
const missing = [];
|
|
69122
69557
|
for (const dep of required2) {
|
|
69123
69558
|
try {
|
|
69124
|
-
const localReq = createRequire3(
|
|
69559
|
+
const localReq = createRequire3(path88.join(packageRoot, "package.json"));
|
|
69125
69560
|
localReq.resolve(dep);
|
|
69126
69561
|
} catch {
|
|
69127
69562
|
missing.push(dep);
|
|
@@ -69321,7 +69756,7 @@ var init_doctor = __esm({
|
|
|
69321
69756
|
init_metrics3();
|
|
69322
69757
|
init_contextGrowthSummary();
|
|
69323
69758
|
require3 = createRequire3(import.meta.url);
|
|
69324
|
-
__dirname3 =
|
|
69759
|
+
__dirname3 = path88.dirname(fileURLToPath3(import.meta.url));
|
|
69325
69760
|
packageRoot = findPackageRoot(__dirname3);
|
|
69326
69761
|
OK = (message) => ({
|
|
69327
69762
|
ok: true,
|
|
@@ -69499,21 +69934,88 @@ var init_fixBudget = __esm({
|
|
|
69499
69934
|
}
|
|
69500
69935
|
});
|
|
69501
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
|
+
|
|
69502
70004
|
// src/cli/commands/inspect.ts
|
|
69503
70005
|
var inspect_exports = {};
|
|
69504
70006
|
__export(inspect_exports, {
|
|
69505
70007
|
collectInspectReport: () => collectInspectReport,
|
|
69506
70008
|
runInspect: () => runInspect
|
|
69507
70009
|
});
|
|
69508
|
-
import
|
|
69509
|
-
import { existsSync as
|
|
70010
|
+
import path90 from "node:path";
|
|
70011
|
+
import { existsSync as existsSync57, readFileSync as readFileSync43, readdirSync as readdirSync12 } from "node:fs";
|
|
69510
70012
|
import { homedir as homedir17 } from "node:os";
|
|
69511
70013
|
async function collectInspectReport(cwd = process.cwd()) {
|
|
69512
70014
|
ensureBuiltinSkillsLoadedSync();
|
|
69513
70015
|
const snap = listSkillsSnapshot(cwd);
|
|
69514
70016
|
const mcp = listMcpServers(cwd);
|
|
69515
|
-
const userMcpPath =
|
|
69516
|
-
const projectMcpPath =
|
|
70017
|
+
const userMcpPath = path90.join(homedir17(), ".zelari-code", "mcp.json");
|
|
70018
|
+
const projectMcpPath = path90.join(cwd, ".zelari", "mcp.json");
|
|
69517
70019
|
const globalHooks = globalHooksDir();
|
|
69518
70020
|
const projectHooks = projectHooksDir(cwd);
|
|
69519
70021
|
const projectTrusted = isFolderTrusted(cwd);
|
|
@@ -69539,11 +70041,11 @@ async function collectInspectReport(cwd = process.cwd()) {
|
|
|
69539
70041
|
folders: listTrustedFolders()
|
|
69540
70042
|
},
|
|
69541
70043
|
configSources: [
|
|
69542
|
-
{ path: userMcpPath, exists:
|
|
69543
|
-
{ path: projectMcpPath, exists:
|
|
69544
|
-
{ path:
|
|
69545
|
-
{ path:
|
|
69546
|
-
{ 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")) }
|
|
69547
70049
|
],
|
|
69548
70050
|
skills: {
|
|
69549
70051
|
total: snap.skills.length,
|
|
@@ -69556,7 +70058,7 @@ async function collectInspectReport(cwd = process.cwd()) {
|
|
|
69556
70058
|
user: mcp.servers.filter((s) => s.scope === "user").map((s) => ({ name: s.name, enabled: s.enabled !== false })),
|
|
69557
70059
|
project: mcp.servers.filter((s) => s.scope === "project").map((s) => ({ name: s.name, enabled: s.enabled !== false })),
|
|
69558
70060
|
projectTrusted,
|
|
69559
|
-
projectConfigExists:
|
|
70061
|
+
projectConfigExists: existsSync57(projectMcpPath)
|
|
69560
70062
|
},
|
|
69561
70063
|
hooks: {
|
|
69562
70064
|
global: {
|
|
@@ -69583,12 +70085,12 @@ function listJsonFiles(dir) {
|
|
|
69583
70085
|
}
|
|
69584
70086
|
function findAgentsMd(cwd) {
|
|
69585
70087
|
const candidates = [
|
|
69586
|
-
|
|
69587
|
-
|
|
70088
|
+
path90.join(cwd, "AGENTS.md"),
|
|
70089
|
+
path90.join(cwd, ".zelari", "AGENTS.md")
|
|
69588
70090
|
];
|
|
69589
70091
|
const found = [];
|
|
69590
70092
|
for (const c of candidates) {
|
|
69591
|
-
if (
|
|
70093
|
+
if (existsSync57(c)) {
|
|
69592
70094
|
try {
|
|
69593
70095
|
const text = readFileSync43(c, "utf8");
|
|
69594
70096
|
found.push(`${c} (${text.length} bytes)`);
|
|
@@ -72709,6 +73211,7 @@ init_completionGate();
|
|
|
72709
73211
|
init_verificationBridge();
|
|
72710
73212
|
init_completionProof();
|
|
72711
73213
|
init_nativeVerification();
|
|
73214
|
+
init_spineTelemetry();
|
|
72712
73215
|
|
|
72713
73216
|
// src/cli/hooks/permissionPicker.ts
|
|
72714
73217
|
init_toolPermissions();
|
|
@@ -72912,8 +73415,14 @@ function useChatTurn(params) {
|
|
|
72912
73415
|
try {
|
|
72913
73416
|
const memoryFactory = await Promise.resolve().then(() => (init_serviceFactory(), serviceFactory_exports));
|
|
72914
73417
|
if (memoryFactory.isMemoryV2Enabled()) {
|
|
73418
|
+
const tuiSpineHolder = {
|
|
73419
|
+
get current() {
|
|
73420
|
+
return writerRef.current?.spine;
|
|
73421
|
+
}
|
|
73422
|
+
};
|
|
72915
73423
|
memoryService = await memoryFactory.getMemoryService(process.cwd(), process.env, {
|
|
72916
|
-
onWarning: (warning) => appendSystem(setMessages, warning, Date.now())
|
|
73424
|
+
onWarning: (warning) => appendSystem(setMessages, warning, Date.now()),
|
|
73425
|
+
onEvent: memorySinkFor(tuiSpineHolder)
|
|
72917
73426
|
});
|
|
72918
73427
|
memoryAutoWrite = memoryFactory.isMemoryAutoWriteEnabled();
|
|
72919
73428
|
}
|
|
@@ -73880,8 +74389,14 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il membro riprende dop
|
|
|
73880
74389
|
try {
|
|
73881
74390
|
const memoryFactory = await Promise.resolve().then(() => (init_serviceFactory(), serviceFactory_exports));
|
|
73882
74391
|
if (memoryFactory.isMemoryV2Enabled()) {
|
|
74392
|
+
const councilSpineHolder = {
|
|
74393
|
+
get current() {
|
|
74394
|
+
return writerRef.current?.spine;
|
|
74395
|
+
}
|
|
74396
|
+
};
|
|
73883
74397
|
councilMemory = await memoryFactory.getMemoryService(process.cwd(), process.env, {
|
|
73884
|
-
onWarning: (warning) => appendSystem(setMessages, warning, Date.now())
|
|
74398
|
+
onWarning: (warning) => appendSystem(setMessages, warning, Date.now()),
|
|
74399
|
+
onEvent: memorySinkFor(councilSpineHolder)
|
|
73885
74400
|
});
|
|
73886
74401
|
councilMemoryAutoWrite = memoryFactory.isMemoryAutoWriteEnabled();
|
|
73887
74402
|
if (!overrides.ragContext) {
|
|
@@ -74490,7 +75005,12 @@ async function runZelariMissionInTui(userMessage, deps, emit) {
|
|
|
74490
75005
|
userMessage,
|
|
74491
75006
|
hasPlan: hasWorkspacePlan2(projectRoot)
|
|
74492
75007
|
});
|
|
74493
|
-
const
|
|
75008
|
+
const missionSpineHolder = {
|
|
75009
|
+
get current() {
|
|
75010
|
+
return deps.writerRef.current?.spine;
|
|
75011
|
+
}
|
|
75012
|
+
};
|
|
75013
|
+
const memory = await getMemoryBackend2(projectRoot, process.env, memorySinkFor(missionSpineHolder));
|
|
74494
75014
|
const chairmanBudget = envNumber(process.env.ZELARI_MODE_MAX_TOOLS_LUCIFER, {
|
|
74495
75015
|
default: 30,
|
|
74496
75016
|
min: 1
|
|
@@ -75735,11 +76255,11 @@ function handleCacheStats(ctx) {
|
|
|
75735
76255
|
init_messageHelpers();
|
|
75736
76256
|
init_serviceFactory();
|
|
75737
76257
|
import { promises as fs31 } from "node:fs";
|
|
75738
|
-
import * as
|
|
76258
|
+
import * as path67 from "node:path";
|
|
75739
76259
|
|
|
75740
76260
|
// src/cli/memory/promotion.ts
|
|
75741
76261
|
import { promises as fs30 } from "node:fs";
|
|
75742
|
-
import * as
|
|
76262
|
+
import * as path66 from "node:path";
|
|
75743
76263
|
var START = "<!-- zelari:memory-promotions:start -->";
|
|
75744
76264
|
var END = "<!-- zelari:memory-promotions:end -->";
|
|
75745
76265
|
var DURABLE_KINDS = /* @__PURE__ */ new Set(["fact", "decision", "constraint", "preference", "procedure"]);
|
|
@@ -75750,13 +76270,13 @@ function lineFor(node) {
|
|
|
75750
76270
|
}
|
|
75751
76271
|
async function promoteMemoryToAgentsMd(projectRoot, node) {
|
|
75752
76272
|
if (node.status !== "active") {
|
|
75753
|
-
return { added: false, path:
|
|
76273
|
+
return { added: false, path: path66.join(projectRoot, "AGENTS.md"), reason: `memory is ${node.status}` };
|
|
75754
76274
|
}
|
|
75755
76275
|
if (!DURABLE_KINDS.has(node.kind)) {
|
|
75756
|
-
return { added: false, path:
|
|
76276
|
+
return { added: false, path: path66.join(projectRoot, "AGENTS.md"), reason: `${node.kind} is not a durable instruction kind` };
|
|
75757
76277
|
}
|
|
75758
|
-
const root = await fs30.realpath(projectRoot).catch(() =>
|
|
75759
|
-
const target =
|
|
76278
|
+
const root = await fs30.realpath(projectRoot).catch(() => path66.resolve(projectRoot));
|
|
76279
|
+
const target = path66.join(root, "AGENTS.md");
|
|
75760
76280
|
try {
|
|
75761
76281
|
const stat7 = await fs30.lstat(target);
|
|
75762
76282
|
if (stat7.isSymbolicLink() || !stat7.isFile()) throw new Error("AGENTS.md must be a regular project file.");
|
|
@@ -75821,22 +76341,22 @@ function sourceLine(source2) {
|
|
|
75821
76341
|
return entries.length ? entries.map(([key, value]) => `${key}=${value}`).join(" \xB7 ") : "unknown";
|
|
75822
76342
|
}
|
|
75823
76343
|
function isInside(root, target) {
|
|
75824
|
-
const relative6 =
|
|
75825
|
-
return relative6 === "" || !relative6.startsWith("..") && !
|
|
76344
|
+
const relative6 = path67.relative(root, target);
|
|
76345
|
+
return relative6 === "" || !relative6.startsWith("..") && !path67.isAbsolute(relative6);
|
|
75826
76346
|
}
|
|
75827
76347
|
async function safeExportPath(cwd, requested) {
|
|
75828
|
-
const lexicalRoot =
|
|
76348
|
+
const lexicalRoot = path67.resolve(cwd);
|
|
75829
76349
|
const root = await fs31.realpath(lexicalRoot).catch(() => lexicalRoot);
|
|
75830
|
-
const fallback =
|
|
75831
|
-
const target = requested?.trim() ?
|
|
76350
|
+
const fallback = path67.join(root, ".zelari", "memory", `export-${Date.now()}.json`);
|
|
76351
|
+
const target = requested?.trim() ? path67.resolve(root, requested.trim()) : fallback;
|
|
75832
76352
|
if (!isInside(root, target)) {
|
|
75833
76353
|
throw new Error("Export path must stay inside the active project.");
|
|
75834
76354
|
}
|
|
75835
|
-
const parent =
|
|
75836
|
-
const relativeParent =
|
|
76355
|
+
const parent = path67.dirname(target);
|
|
76356
|
+
const relativeParent = path67.relative(root, parent);
|
|
75837
76357
|
let cursor = root;
|
|
75838
|
-
for (const segment of relativeParent.split(
|
|
75839
|
-
cursor =
|
|
76358
|
+
for (const segment of relativeParent.split(path67.sep).filter(Boolean)) {
|
|
76359
|
+
cursor = path67.join(cursor, segment);
|
|
75840
76360
|
try {
|
|
75841
76361
|
const stat7 = await fs31.lstat(cursor);
|
|
75842
76362
|
if (stat7.isSymbolicLink()) {
|
|
@@ -76008,9 +76528,9 @@ ${message}` : message
|
|
|
76008
76528
|
}
|
|
76009
76529
|
case "export": {
|
|
76010
76530
|
const target = await safeExportPath(ctx.cwd, args.join(" ").trim() || void 0);
|
|
76011
|
-
await fs31.mkdir(
|
|
76012
|
-
const root = await fs31.realpath(ctx.cwd).catch(() =>
|
|
76013
|
-
const realParent = await fs31.realpath(
|
|
76531
|
+
await fs31.mkdir(path67.dirname(target), { recursive: true });
|
|
76532
|
+
const root = await fs31.realpath(ctx.cwd).catch(() => path67.resolve(ctx.cwd));
|
|
76533
|
+
const realParent = await fs31.realpath(path67.dirname(target));
|
|
76014
76534
|
if (!isInside(root, realParent)) {
|
|
76015
76535
|
throw new Error("Export path resolves outside the active project.");
|
|
76016
76536
|
}
|
|
@@ -76128,6 +76648,7 @@ init_graphMemory();
|
|
|
76128
76648
|
init_executor();
|
|
76129
76649
|
init_graphStatus();
|
|
76130
76650
|
init_serviceFactory();
|
|
76651
|
+
init_spineTelemetry();
|
|
76131
76652
|
async function handleKrakenGraph(ctx, prompt) {
|
|
76132
76653
|
if (!isKrakenGraphEnabled()) {
|
|
76133
76654
|
appendSystem(
|
|
@@ -76141,8 +76662,14 @@ async function handleKrakenGraph(ctx, prompt) {
|
|
|
76141
76662
|
return;
|
|
76142
76663
|
}
|
|
76143
76664
|
appendSystem(ctx.setMessages, `[kraken] planning graph for: ${prompt.trim()}`);
|
|
76665
|
+
const tuiSpineHolder = {
|
|
76666
|
+
get current() {
|
|
76667
|
+
return ctx.writerRef?.current?.spine ?? void 0;
|
|
76668
|
+
}
|
|
76669
|
+
};
|
|
76144
76670
|
const memory = isMemoryV2Enabled() ? await getMemoryService(ctx.cwd, process.env, {
|
|
76145
|
-
onWarning: (warning) => appendSystem(ctx.setMessages, warning)
|
|
76671
|
+
onWarning: (warning) => appendSystem(ctx.setMessages, warning),
|
|
76672
|
+
onEvent: memorySinkFor(tuiSpineHolder)
|
|
76146
76673
|
}) : void 0;
|
|
76147
76674
|
const audit = new AuditLogger();
|
|
76148
76675
|
const taskToolDeps = {
|
|
@@ -76206,7 +76733,7 @@ import { promises as fs35 } from "node:fs";
|
|
|
76206
76733
|
init_zod();
|
|
76207
76734
|
init_taskTool();
|
|
76208
76735
|
import { promises as fs34 } from "node:fs";
|
|
76209
|
-
import
|
|
76736
|
+
import path72 from "node:path";
|
|
76210
76737
|
import { randomBytes as randomBytes6 } from "node:crypto";
|
|
76211
76738
|
var CsvFanoutArgsSchema = external_exports.object({
|
|
76212
76739
|
csv_path: external_exports.string().min(1),
|
|
@@ -76300,8 +76827,8 @@ function resolveMaxConcurrency(env = process.env) {
|
|
|
76300
76827
|
}
|
|
76301
76828
|
async function runCsvFanout(args, deps, opts) {
|
|
76302
76829
|
const start = Date.now();
|
|
76303
|
-
const absCsv =
|
|
76304
|
-
const absOut =
|
|
76830
|
+
const absCsv = path72.isAbsolute(args.csv_path) ? args.csv_path : path72.join(opts.parentCwd, args.csv_path);
|
|
76831
|
+
const absOut = path72.isAbsolute(args.output_csv_path) ? args.output_csv_path : path72.join(opts.parentCwd, args.output_csv_path);
|
|
76305
76832
|
const { headers: headers2, rows } = await readCsv(absCsv);
|
|
76306
76833
|
if (headers2.length === 0) {
|
|
76307
76834
|
throw new Error(`kraken_csv_fanout: ${absCsv} is empty`);
|
|
@@ -76357,7 +76884,7 @@ async function runCsvFanout(args, deps, opts) {
|
|
|
76357
76884
|
errored += 1;
|
|
76358
76885
|
errors.push(`${row[args.id_column] ?? i}: ${res.error}`);
|
|
76359
76886
|
}
|
|
76360
|
-
await fs34.mkdir(
|
|
76887
|
+
await fs34.mkdir(path72.dirname(absOut), { recursive: true });
|
|
76361
76888
|
await queueWrite(serializeCsv(outHeaders, outputRecords));
|
|
76362
76889
|
}
|
|
76363
76890
|
}
|
|
@@ -76552,7 +77079,7 @@ function splitArgs(s) {
|
|
|
76552
77079
|
// src/cli/slashHandlers/krakenWorkbench.ts
|
|
76553
77080
|
init_messageHelpers();
|
|
76554
77081
|
import { promises as fs36 } from "node:fs";
|
|
76555
|
-
import
|
|
77082
|
+
import path73 from "node:path";
|
|
76556
77083
|
|
|
76557
77084
|
// src/cli/kraken/workbenchView.ts
|
|
76558
77085
|
var EMPTY = {
|
|
@@ -76669,14 +77196,14 @@ function formatWorkbenchForTerminal(p3) {
|
|
|
76669
77196
|
|
|
76670
77197
|
// src/cli/slashHandlers/krakenWorkbench.ts
|
|
76671
77198
|
async function handleKrakenWorkbench(ctx) {
|
|
76672
|
-
const dir =
|
|
77199
|
+
const dir = path73.join(ctx.cwd, ".zelari", "radio");
|
|
76673
77200
|
let latest = null;
|
|
76674
77201
|
let latestMtime = 0;
|
|
76675
77202
|
try {
|
|
76676
77203
|
const files = await fs36.readdir(dir);
|
|
76677
77204
|
for (const f of files) {
|
|
76678
77205
|
if (!f.startsWith("workbench-") || !f.endsWith(".md")) continue;
|
|
76679
|
-
const full =
|
|
77206
|
+
const full = path73.join(dir, f);
|
|
76680
77207
|
const stat7 = await fs36.stat(full);
|
|
76681
77208
|
if (stat7.mtimeMs > latestMtime) {
|
|
76682
77209
|
latestMtime = stat7.mtimeMs;
|
|
@@ -76693,10 +77220,10 @@ async function handleKrakenWorkbench(ctx) {
|
|
|
76693
77220
|
const parsed = parseWorkbench(content);
|
|
76694
77221
|
const rendered = formatWorkbenchForTerminal(parsed);
|
|
76695
77222
|
if (!rendered.trim()) {
|
|
76696
|
-
appendSystem(ctx.setMessages, `[kraken workbench] ${
|
|
77223
|
+
appendSystem(ctx.setMessages, `[kraken workbench] ${path73.basename(latest)}: (no nodes / no events yet)`);
|
|
76697
77224
|
return;
|
|
76698
77225
|
}
|
|
76699
|
-
appendSystem(ctx.setMessages, `[kraken workbench] ${
|
|
77226
|
+
appendSystem(ctx.setMessages, `[kraken workbench] ${path73.basename(latest)}:
|
|
76700
77227
|
${rendered}`);
|
|
76701
77228
|
}
|
|
76702
77229
|
|
|
@@ -77003,15 +77530,15 @@ ${result.output.split("\n").slice(-8).join("\n")}` : "";
|
|
|
77003
77530
|
// src/cli/slashHandlers/promoteMember.ts
|
|
77004
77531
|
init_messageHelpers();
|
|
77005
77532
|
import { promises as fs37 } from "node:fs";
|
|
77006
|
-
import
|
|
77533
|
+
import path76 from "node:path";
|
|
77007
77534
|
import os12 from "node:os";
|
|
77008
77535
|
async function handlePromoteMember(ctx, memberId) {
|
|
77009
77536
|
try {
|
|
77010
77537
|
const { promoteMember: promoteMember2 } = await Promise.resolve().then(() => (init_council(), council_exports));
|
|
77011
77538
|
const { skill, markdown } = promoteMember2(memberId);
|
|
77012
|
-
const skillDir = process.env.ANATHEMA_SKILL_DIR ??
|
|
77539
|
+
const skillDir = process.env.ANATHEMA_SKILL_DIR ?? path76.join(os12.homedir(), ".tmp", "zelari-code", "skills");
|
|
77013
77540
|
await fs37.mkdir(skillDir, { recursive: true });
|
|
77014
|
-
const filePath =
|
|
77541
|
+
const filePath = path76.join(skillDir, `${skill.id}.md`);
|
|
77015
77542
|
await fs37.writeFile(filePath, markdown, "utf8");
|
|
77016
77543
|
appendSystem(
|
|
77017
77544
|
ctx.setMessages,
|
|
@@ -77029,24 +77556,24 @@ async function handlePromoteMember(ctx, memberId) {
|
|
|
77029
77556
|
|
|
77030
77557
|
// src/cli/branchManager.ts
|
|
77031
77558
|
import { promises as fs38, existsSync as existsSync48, readFileSync as readFileSync37, writeFileSync as writeFileSync23, mkdirSync as mkdirSync19, statSync as statSync7, rmSync as rmSync3 } from "node:fs";
|
|
77032
|
-
import
|
|
77559
|
+
import path77 from "node:path";
|
|
77033
77560
|
import os13 from "node:os";
|
|
77034
77561
|
var META_FILENAME = "meta.json";
|
|
77035
77562
|
var SESSIONS_SUBDIR = "sessions";
|
|
77036
77563
|
function getBranchesBaseDir() {
|
|
77037
|
-
return process.env.ANATHEMA_BRANCHES_DIR ??
|
|
77564
|
+
return process.env.ANATHEMA_BRANCHES_DIR ?? path77.join(os13.homedir(), ".tmp", "zelari-code", "branches");
|
|
77038
77565
|
}
|
|
77039
77566
|
function getSessionsBaseDir() {
|
|
77040
|
-
return process.env.ANATHEMA_SESSIONS_DIR ??
|
|
77567
|
+
return process.env.ANATHEMA_SESSIONS_DIR ?? path77.join(os13.homedir(), ".tmp", "zelari-code", "sessions");
|
|
77041
77568
|
}
|
|
77042
77569
|
function branchPathFor(name, baseDir) {
|
|
77043
|
-
return
|
|
77570
|
+
return path77.join(baseDir, name);
|
|
77044
77571
|
}
|
|
77045
77572
|
function metaPathFor(name, baseDir) {
|
|
77046
|
-
return
|
|
77573
|
+
return path77.join(baseDir, name, META_FILENAME);
|
|
77047
77574
|
}
|
|
77048
77575
|
function sessionsPathFor(name, baseDir) {
|
|
77049
|
-
return
|
|
77576
|
+
return path77.join(baseDir, name, SESSIONS_SUBDIR);
|
|
77050
77577
|
}
|
|
77051
77578
|
function readBranchMeta(name, baseDir) {
|
|
77052
77579
|
const metaPath = metaPathFor(name, baseDir);
|
|
@@ -77071,7 +77598,7 @@ function readBranchMeta(name, baseDir) {
|
|
|
77071
77598
|
}
|
|
77072
77599
|
function writeBranchMeta(name, baseDir, meta3) {
|
|
77073
77600
|
const metaPath = metaPathFor(name, baseDir);
|
|
77074
|
-
mkdirSync19(
|
|
77601
|
+
mkdirSync19(path77.dirname(metaPath), { recursive: true });
|
|
77075
77602
|
writeFileSync23(metaPath, JSON.stringify(meta3, null, 2), "utf-8");
|
|
77076
77603
|
}
|
|
77077
77604
|
async function countSessions(name, baseDir) {
|
|
@@ -77122,14 +77649,14 @@ async function createBranch(name, fromSessionId, baseDir = getBranchesBaseDir(),
|
|
|
77122
77649
|
if (branchExists(name, baseDir)) {
|
|
77123
77650
|
throw new BranchAlreadyExistsError(name);
|
|
77124
77651
|
}
|
|
77125
|
-
const sourcePath =
|
|
77652
|
+
const sourcePath = path77.join(sessionsBaseDir, `${fromSessionId}.jsonl`);
|
|
77126
77653
|
if (!existsSync48(sourcePath)) {
|
|
77127
77654
|
throw new SessionNotFoundError(`Source session "${fromSessionId}" not found at ${sourcePath}`);
|
|
77128
77655
|
}
|
|
77129
77656
|
const branchPath = branchPathFor(name, baseDir);
|
|
77130
77657
|
const branchSessionsPath = sessionsPathFor(name, baseDir);
|
|
77131
77658
|
mkdirSync19(branchSessionsPath, { recursive: true });
|
|
77132
|
-
const destPath =
|
|
77659
|
+
const destPath = path77.join(branchSessionsPath, `${fromSessionId}.jsonl`);
|
|
77133
77660
|
await fs38.copyFile(sourcePath, destPath);
|
|
77134
77661
|
const meta3 = {
|
|
77135
77662
|
name,
|
|
@@ -77233,14 +77760,14 @@ async function handleBranchCheckout(ctx, branchName) {
|
|
|
77233
77760
|
// src/cli/slashHandlers/workspace.ts
|
|
77234
77761
|
init_messageHelpers();
|
|
77235
77762
|
import { promises as fs39 } from "node:fs";
|
|
77236
|
-
import
|
|
77763
|
+
import path78 from "node:path";
|
|
77237
77764
|
async function handleWorkspaceShow(ctx, what) {
|
|
77238
77765
|
try {
|
|
77239
|
-
const zelari =
|
|
77766
|
+
const zelari = path78.join(process.cwd(), ".zelari");
|
|
77240
77767
|
let content;
|
|
77241
77768
|
switch (what) {
|
|
77242
77769
|
case "plan": {
|
|
77243
|
-
const planPath =
|
|
77770
|
+
const planPath = path78.join(zelari, "plan.md");
|
|
77244
77771
|
try {
|
|
77245
77772
|
content = await fs39.readFile(planPath, "utf-8");
|
|
77246
77773
|
} catch {
|
|
@@ -77249,7 +77776,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
77249
77776
|
break;
|
|
77250
77777
|
}
|
|
77251
77778
|
case "decisions": {
|
|
77252
|
-
const decisionsDir =
|
|
77779
|
+
const decisionsDir = path78.join(zelari, "decisions");
|
|
77253
77780
|
try {
|
|
77254
77781
|
const files = (await fs39.readdir(decisionsDir)).filter((f) => f.endsWith(".md")).sort();
|
|
77255
77782
|
if (files.length === 0) {
|
|
@@ -77259,7 +77786,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
77259
77786
|
`];
|
|
77260
77787
|
const { parseFrontmatter: parseFrontmatter2 } = await Promise.resolve().then(() => (init_storage(), storage_exports));
|
|
77261
77788
|
for (const f of files) {
|
|
77262
|
-
const raw = await fs39.readFile(
|
|
77789
|
+
const raw = await fs39.readFile(path78.join(decisionsDir, f), "utf-8");
|
|
77263
77790
|
const { meta: meta3, body } = parseFrontmatter2(raw);
|
|
77264
77791
|
const title = meta3.title ?? body.split("\n")[0]?.replace(/^#\s*/, "").trim() ?? f;
|
|
77265
77792
|
lines.push(`- **${f.replace(/\.md$/, "")}** [${meta3.status ?? "unknown"}] ${title}`);
|
|
@@ -77272,7 +77799,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
77272
77799
|
break;
|
|
77273
77800
|
}
|
|
77274
77801
|
case "risks": {
|
|
77275
|
-
const risksPath =
|
|
77802
|
+
const risksPath = path78.join(zelari, "risks.md");
|
|
77276
77803
|
try {
|
|
77277
77804
|
content = await fs39.readFile(risksPath, "utf-8");
|
|
77278
77805
|
} catch {
|
|
@@ -77281,7 +77808,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
77281
77808
|
break;
|
|
77282
77809
|
}
|
|
77283
77810
|
case "agents": {
|
|
77284
|
-
const agentsPath =
|
|
77811
|
+
const agentsPath = path78.join(process.cwd(), "AGENTS.MD");
|
|
77285
77812
|
try {
|
|
77286
77813
|
content = await fs39.readFile(agentsPath, "utf-8");
|
|
77287
77814
|
} catch {
|
|
@@ -77290,7 +77817,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
77290
77817
|
break;
|
|
77291
77818
|
}
|
|
77292
77819
|
case "docs": {
|
|
77293
|
-
const docsDir =
|
|
77820
|
+
const docsDir = path78.join(zelari, "docs");
|
|
77294
77821
|
try {
|
|
77295
77822
|
const files = (await fs39.readdir(docsDir)).filter((f) => f.endsWith(".md")).sort();
|
|
77296
77823
|
content = files.length ? `# Docs (${files.length})
|
|
@@ -77332,7 +77859,7 @@ async function handleWorkspaceReset(ctx, force) {
|
|
|
77332
77859
|
return;
|
|
77333
77860
|
}
|
|
77334
77861
|
try {
|
|
77335
|
-
const target =
|
|
77862
|
+
const target = path78.join(process.cwd(), ".zelari");
|
|
77336
77863
|
await fs39.rm(target, { recursive: true, force: true });
|
|
77337
77864
|
appendSystem(ctx.setMessages, "[workspace] .zelari/ removed");
|
|
77338
77865
|
} catch (err) {
|
|
@@ -77344,7 +77871,7 @@ async function handleWorkspaceReset(ctx, force) {
|
|
|
77344
77871
|
init_provider2();
|
|
77345
77872
|
|
|
77346
77873
|
// src/cli/slashHandlers/skills.ts
|
|
77347
|
-
import
|
|
77874
|
+
import path79 from "node:path";
|
|
77348
77875
|
import os14 from "node:os";
|
|
77349
77876
|
|
|
77350
77877
|
// src/cli/skillHistory.ts
|
|
@@ -77473,7 +78000,7 @@ function handleSkillPicker(ctx, skills, openPicker, fallbackMessage) {
|
|
|
77473
78000
|
});
|
|
77474
78001
|
}
|
|
77475
78002
|
async function handleSkillStats(ctx, skillId) {
|
|
77476
|
-
const historyFile = process.env.ANATHEMA_SKILL_HISTORY_FILE ??
|
|
78003
|
+
const historyFile = process.env.ANATHEMA_SKILL_HISTORY_FILE ?? path79.join(os14.homedir(), ".tmp", "zelari-code", "skill-history.jsonl");
|
|
77477
78004
|
try {
|
|
77478
78005
|
const records = await readSkillHistory(historyFile);
|
|
77479
78006
|
const stats = getSkillStats(records, skillId);
|
|
@@ -77489,7 +78016,7 @@ async function handleSkillCompare(ctx, ids, fallbackMessage) {
|
|
|
77489
78016
|
appendSystem(ctx.setMessages, fallbackMessage ?? "[skill-compare] missing args");
|
|
77490
78017
|
return;
|
|
77491
78018
|
}
|
|
77492
|
-
const historyFile = process.env.ANATHEMA_SKILL_HISTORY_FILE ??
|
|
78019
|
+
const historyFile = process.env.ANATHEMA_SKILL_HISTORY_FILE ?? path79.join(os14.homedir(), ".tmp", "zelari-code", "skill-history.jsonl");
|
|
77493
78020
|
try {
|
|
77494
78021
|
const formatted = await compareSkillsFromFile(ids[0], ids[1], historyFile);
|
|
77495
78022
|
appendSystem(ctx.setMessages, formatted);
|
|
@@ -77945,7 +78472,10 @@ function useSlashDispatch(params) {
|
|
|
77945
78472
|
}
|
|
77946
78473
|
if (result.kind === "kraken_graph") {
|
|
77947
78474
|
const sid = (sessionId2 || "default").trim();
|
|
77948
|
-
await handleKrakenGraph(
|
|
78475
|
+
await handleKrakenGraph(
|
|
78476
|
+
{ setMessages, cwd: process.cwd(), sessionId: sid, writerRef: params.writerRef },
|
|
78477
|
+
result.graphPrompt ?? ""
|
|
78478
|
+
);
|
|
77949
78479
|
return;
|
|
77950
78480
|
}
|
|
77951
78481
|
if (result.kind === "kraken_fanout") {
|
|
@@ -78282,6 +78812,9 @@ function App() {
|
|
|
78282
78812
|
sessionId: session.sessionId,
|
|
78283
78813
|
messages: session.messages,
|
|
78284
78814
|
setMessages: session.setMessages,
|
|
78815
|
+
// W2: same writer ref passed to useChatTurn — lets /kraken graph project
|
|
78816
|
+
// memory events onto the session spine mirror.
|
|
78817
|
+
writerRef: session.writerRef,
|
|
78285
78818
|
setInput,
|
|
78286
78819
|
setBusy,
|
|
78287
78820
|
setSessionId: session.setSessionId,
|
|
@@ -79184,8 +79717,8 @@ function normalizeDraft(raw, sourceUrl, provider, model) {
|
|
|
79184
79717
|
let name = String(o.name ?? "").trim().toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64);
|
|
79185
79718
|
if (!name || !/^[a-z0-9][a-z0-9-]{0,63}$/.test(name)) {
|
|
79186
79719
|
try {
|
|
79187
|
-
const
|
|
79188
|
-
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";
|
|
79189
79722
|
} catch {
|
|
79190
79723
|
name = "imported-skill";
|
|
79191
79724
|
}
|
|
@@ -79520,6 +80053,14 @@ function pickRootComponent() {
|
|
|
79520
80053
|
process.exit(1);
|
|
79521
80054
|
}
|
|
79522
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
|
+
}
|
|
79523
80064
|
const { runInspect: runInspect2 } = (init_inspect(), __toCommonJS(inspect_exports));
|
|
79524
80065
|
const json3 = argv.includes("--json");
|
|
79525
80066
|
void runInspect2({ json: json3 }).then((code) => process.exit(code));
|