zelari-code 2.16.5 → 2.17.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/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 +848 -471
- package/dist/cli/main.bundled.js.map +4 -4
- 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 +118 -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 +7 -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, path90) {
|
|
3292
|
+
if (!path90)
|
|
3293
3293
|
return obj;
|
|
3294
|
-
return
|
|
3294
|
+
return path90.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(path90, 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(path90);
|
|
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, path90 = []) => {
|
|
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 }, [...path90, ...issue2.path]));
|
|
3848
3848
|
} else if (issue2.code === "invalid_key") {
|
|
3849
|
-
processError({ issues: issue2.issues }, [...
|
|
3849
|
+
processError({ issues: issue2.issues }, [...path90, ...issue2.path]);
|
|
3850
3850
|
} else if (issue2.code === "invalid_element") {
|
|
3851
|
-
processError({ issues: issue2.issues }, [...
|
|
3851
|
+
processError({ issues: issue2.issues }, [...path90, ...issue2.path]);
|
|
3852
3852
|
} else {
|
|
3853
|
-
const fullpath = [...
|
|
3853
|
+
const fullpath = [...path90, ...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, path90 = []) => {
|
|
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 }, [...path90, ...issue2.path]));
|
|
3885
3885
|
} else if (issue2.code === "invalid_key") {
|
|
3886
|
-
processError({ issues: issue2.issues }, [...
|
|
3886
|
+
processError({ issues: issue2.issues }, [...path90, ...issue2.path]);
|
|
3887
3887
|
} else if (issue2.code === "invalid_element") {
|
|
3888
|
-
processError({ issues: issue2.issues }, [...
|
|
3888
|
+
processError({ issues: issue2.issues }, [...path90, ...issue2.path]);
|
|
3889
3889
|
} else {
|
|
3890
|
-
const fullpath = [...
|
|
3890
|
+
const fullpath = [...path90, ...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 path90 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
3923
|
+
for (const seg of path90) {
|
|
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 path90 = ref.slice(1).split("/").filter(Boolean);
|
|
17427
|
+
if (path90.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 (path90[0] === defsKey) {
|
|
17432
|
+
const key = path90[1];
|
|
17433
17433
|
if (!key || !ctx.defs[key]) {
|
|
17434
17434
|
throw new Error(`Reference not found: ${ref}`);
|
|
17435
17435
|
}
|
|
@@ -19875,11 +19875,11 @@ var init_tools = __esm({
|
|
|
19875
19875
|
if (!ctx.addDocument)
|
|
19876
19876
|
return "Knowledge vault tool not available.";
|
|
19877
19877
|
const title = args["title"] || "New Document";
|
|
19878
|
-
const
|
|
19878
|
+
const path90 = args["path"] || `notes/${title.toLowerCase().replace(/[^a-z0-9]+/g, "-")}`;
|
|
19879
19879
|
const content = args["content"] || "";
|
|
19880
19880
|
const tags = args["tags"] || [];
|
|
19881
19881
|
ctx.addDocument({
|
|
19882
|
-
path:
|
|
19882
|
+
path: path90,
|
|
19883
19883
|
title,
|
|
19884
19884
|
content,
|
|
19885
19885
|
format: "markdown",
|
|
@@ -19888,7 +19888,7 @@ var init_tools = __esm({
|
|
|
19888
19888
|
workspaceId: ctx.workspaceId
|
|
19889
19889
|
});
|
|
19890
19890
|
ctx.addActivity("vault", "created document", title);
|
|
19891
|
-
return `Document "${title}" created at "${
|
|
19891
|
+
return `Document "${title}" created at "${path90}".`;
|
|
19892
19892
|
}
|
|
19893
19893
|
}
|
|
19894
19894
|
];
|
|
@@ -23610,10 +23610,10 @@ ${fromRunCache}`,
|
|
|
23610
23610
|
}
|
|
23611
23611
|
const existing = inflight.get(callKey);
|
|
23612
23612
|
if (existing) {
|
|
23613
|
-
const
|
|
23613
|
+
const shared = await existing;
|
|
23614
23614
|
return {
|
|
23615
23615
|
content: `[duplicate call \u2014 result repeated; do not call this tool again with the same arguments]
|
|
23616
|
-
${
|
|
23616
|
+
${shared.content}`,
|
|
23617
23617
|
isError: false,
|
|
23618
23618
|
durationMs: 0
|
|
23619
23619
|
};
|
|
@@ -25125,7 +25125,7 @@ var init_appServer = __esm({
|
|
|
25125
25125
|
services = factory(root);
|
|
25126
25126
|
this.workspaceServices.set(root, services);
|
|
25127
25127
|
}
|
|
25128
|
-
const
|
|
25128
|
+
const shared = services;
|
|
25129
25129
|
const server = this;
|
|
25130
25130
|
const count = this.sessionCounts.get(root) ?? 0;
|
|
25131
25131
|
this.sessionCounts.set(root, count + 1);
|
|
@@ -25133,13 +25133,13 @@ var init_appServer = __esm({
|
|
|
25133
25133
|
const session = {
|
|
25134
25134
|
id: id3,
|
|
25135
25135
|
workspaceRoot: root,
|
|
25136
|
-
services:
|
|
25136
|
+
services: shared,
|
|
25137
25137
|
runTurn(input) {
|
|
25138
25138
|
const deps = {
|
|
25139
25139
|
session: { id: id3, workspaceRoot: root },
|
|
25140
25140
|
services: {
|
|
25141
|
-
...
|
|
25142
|
-
completionProofWriter: server.trackProofWriter(
|
|
25141
|
+
...shared,
|
|
25142
|
+
completionProofWriter: server.trackProofWriter(shared.completionProofWriter)
|
|
25143
25143
|
}
|
|
25144
25144
|
};
|
|
25145
25145
|
return runTurn(input, deps);
|
|
@@ -25150,10 +25150,10 @@ var init_appServer = __esm({
|
|
|
25150
25150
|
server.sessionCounts.set(root, remaining);
|
|
25151
25151
|
if (remaining <= 0) {
|
|
25152
25152
|
server.sessionCounts.delete(root);
|
|
25153
|
-
const
|
|
25153
|
+
const shared2 = server.workspaceServices.get(root);
|
|
25154
25154
|
server.workspaceServices.delete(root);
|
|
25155
25155
|
try {
|
|
25156
|
-
|
|
25156
|
+
shared2?.lspManager?.dispose();
|
|
25157
25157
|
} catch {
|
|
25158
25158
|
}
|
|
25159
25159
|
}
|
|
@@ -26138,11 +26138,11 @@ var init_synthesisAudit = __esm({
|
|
|
26138
26138
|
import { existsSync as existsSync7, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "node:fs";
|
|
26139
26139
|
import { join as join4 } from "node:path";
|
|
26140
26140
|
function loadNfrSpec(zelariRoot) {
|
|
26141
|
-
const
|
|
26142
|
-
if (!existsSync7(
|
|
26141
|
+
const path90 = join4(zelariRoot, "nfr-spec.json");
|
|
26142
|
+
if (!existsSync7(path90))
|
|
26143
26143
|
return null;
|
|
26144
26144
|
try {
|
|
26145
|
-
const raw = JSON.parse(readFileSync7(
|
|
26145
|
+
const raw = JSON.parse(readFileSync7(path90, "utf8"));
|
|
26146
26146
|
if (raw.version !== 1 || !Array.isArray(raw.targets))
|
|
26147
26147
|
return null;
|
|
26148
26148
|
return raw;
|
|
@@ -28448,9 +28448,9 @@ var init_types5 = __esm({
|
|
|
28448
28448
|
import { readFileSync as readFileSync12 } from "node:fs";
|
|
28449
28449
|
import { join as join10 } from "node:path";
|
|
28450
28450
|
function readLessonsDeduped(zelariRoot) {
|
|
28451
|
-
const
|
|
28451
|
+
const path90 = join10(zelariRoot, LESSONS_FILE);
|
|
28452
28452
|
try {
|
|
28453
|
-
const raw = readFileSync12(
|
|
28453
|
+
const raw = readFileSync12(path90, "utf8");
|
|
28454
28454
|
const byId = /* @__PURE__ */ new Map();
|
|
28455
28455
|
for (const line of raw.split(/\r?\n/)) {
|
|
28456
28456
|
if (!line.trim())
|
|
@@ -28551,8 +28551,8 @@ function keywordsFrom(check2, signature) {
|
|
|
28551
28551
|
return [.../* @__PURE__ */ new Set([...fromId, ...words])].slice(0, 12);
|
|
28552
28552
|
}
|
|
28553
28553
|
function writeLesson(zelariRoot, lesson) {
|
|
28554
|
-
const
|
|
28555
|
-
appendFileSync(
|
|
28554
|
+
const path90 = join11(zelariRoot, LESSONS_FILE);
|
|
28555
|
+
appendFileSync(path90, `${JSON.stringify(lesson)}
|
|
28556
28556
|
`, "utf8");
|
|
28557
28557
|
}
|
|
28558
28558
|
function findSimilar(lessons, signature) {
|
|
@@ -30515,9 +30515,9 @@ function findCycle(nodes) {
|
|
|
30515
30515
|
if (color.get(start) !== WHITE)
|
|
30516
30516
|
continue;
|
|
30517
30517
|
const stack = [[start, 0]];
|
|
30518
|
-
const
|
|
30518
|
+
const path90 = [];
|
|
30519
30519
|
color.set(start, GRAY);
|
|
30520
|
-
|
|
30520
|
+
path90.push(start);
|
|
30521
30521
|
while (stack.length > 0) {
|
|
30522
30522
|
const top = stack[stack.length - 1];
|
|
30523
30523
|
const [id3, idx] = top;
|
|
@@ -30530,17 +30530,17 @@ function findCycle(nodes) {
|
|
|
30530
30530
|
continue;
|
|
30531
30531
|
const c = color.get(dep);
|
|
30532
30532
|
if (c === GRAY) {
|
|
30533
|
-
const at =
|
|
30534
|
-
return [...
|
|
30533
|
+
const at = path90.indexOf(dep);
|
|
30534
|
+
return [...path90.slice(at), dep];
|
|
30535
30535
|
}
|
|
30536
30536
|
if (c === WHITE) {
|
|
30537
30537
|
color.set(dep, GRAY);
|
|
30538
|
-
|
|
30538
|
+
path90.push(dep);
|
|
30539
30539
|
stack.push([dep, 0]);
|
|
30540
30540
|
}
|
|
30541
30541
|
} else {
|
|
30542
30542
|
color.set(id3, BLACK);
|
|
30543
|
-
|
|
30543
|
+
path90.pop();
|
|
30544
30544
|
stack.pop();
|
|
30545
30545
|
}
|
|
30546
30546
|
}
|
|
@@ -31460,8 +31460,8 @@ var init_runner = __esm({
|
|
|
31460
31460
|
failed: [...this.tentaclesById.values()].filter((r) => r.status === "error"),
|
|
31461
31461
|
pending: []
|
|
31462
31462
|
};
|
|
31463
|
-
const
|
|
31464
|
-
this.host.log(`checkpoint: ${label ?? "auto"} \u2192 ${
|
|
31463
|
+
const path90 = await this.host.saveSnapshot(snapshot, ".zelari/kraken/snapshots");
|
|
31464
|
+
this.host.log(`checkpoint: ${label ?? "auto"} \u2192 ${path90}`);
|
|
31465
31465
|
return snapshot;
|
|
31466
31466
|
}
|
|
31467
31467
|
callLog(msg, data) {
|
|
@@ -31553,16 +31553,12 @@ var init_types9 = __esm({
|
|
|
31553
31553
|
// once at session start / manifest change. State-only (never model-surface):
|
|
31554
31554
|
// data = {manifest, manifestHash}. Schema review per ADR-0021.
|
|
31555
31555
|
"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
31556
|
"user.message",
|
|
31560
31557
|
"assistant.message",
|
|
31561
31558
|
"tool.call",
|
|
31562
31559
|
"tool.result",
|
|
31563
31560
|
// 2.x B (crash-safe recovery): dangling call classified. State-only.
|
|
31564
31561
|
"tool.interrupted",
|
|
31565
|
-
"context.injected",
|
|
31566
31562
|
"session.compacted",
|
|
31567
31563
|
"task.created",
|
|
31568
31564
|
"task.updated",
|
|
@@ -31571,7 +31567,6 @@ var init_types9 = __esm({
|
|
|
31571
31567
|
// State-only: compaction projects it into CompactionStateSnapshot.
|
|
31572
31568
|
"task.contract",
|
|
31573
31569
|
"task.contract_updated",
|
|
31574
|
-
"kraken.task",
|
|
31575
31570
|
"council.member",
|
|
31576
31571
|
"mission.phase",
|
|
31577
31572
|
"mission.replan",
|
|
@@ -33917,16 +33912,16 @@ function runRetentionFromEnv() {
|
|
|
33917
33912
|
maxTotalBytes: Number.isFinite(parseMb) && parseMb > 0 ? Math.round(parseMb * 1024 * 1024) : DEFAULT_RUN_RETENTION_MAX_MB * 1024 * 1024
|
|
33918
33913
|
};
|
|
33919
33914
|
}
|
|
33920
|
-
async function dirSize(
|
|
33915
|
+
async function dirSize(path90) {
|
|
33921
33916
|
let total = 0;
|
|
33922
33917
|
let entries;
|
|
33923
33918
|
try {
|
|
33924
|
-
entries = await readdir(
|
|
33919
|
+
entries = await readdir(path90, { withFileTypes: true });
|
|
33925
33920
|
} catch {
|
|
33926
33921
|
return 0;
|
|
33927
33922
|
}
|
|
33928
33923
|
for (const entry of entries) {
|
|
33929
|
-
const child = join13(
|
|
33924
|
+
const child = join13(path90, entry.name);
|
|
33930
33925
|
if (entry.isDirectory())
|
|
33931
33926
|
total += await dirSize(child);
|
|
33932
33927
|
else {
|
|
@@ -33953,19 +33948,19 @@ async function enforceRunRetention(runsDir, options = {}) {
|
|
|
33953
33948
|
for (const entry of entries) {
|
|
33954
33949
|
if (!entry.isDirectory())
|
|
33955
33950
|
continue;
|
|
33956
|
-
const
|
|
33951
|
+
const path90 = join13(runsDir, entry.name);
|
|
33957
33952
|
let startedAt = 0;
|
|
33958
33953
|
let endedAt;
|
|
33959
33954
|
let completed = false;
|
|
33960
33955
|
try {
|
|
33961
|
-
const manifest = JSON.parse(await readFile(join13(
|
|
33956
|
+
const manifest = JSON.parse(await readFile(join13(path90, "manifest.json"), "utf8"));
|
|
33962
33957
|
startedAt = manifest.startedAt ?? 0;
|
|
33963
33958
|
endedAt = manifest.endedAt;
|
|
33964
33959
|
completed = Boolean(endedAt) && manifest.status !== "running";
|
|
33965
33960
|
} catch {
|
|
33966
33961
|
completed = false;
|
|
33967
33962
|
}
|
|
33968
|
-
infos.push({ name: entry.name, path:
|
|
33963
|
+
infos.push({ name: entry.name, path: path90, startedAt, endedAt, completed, bytes: await dirSize(path90) });
|
|
33969
33964
|
}
|
|
33970
33965
|
const remove = async (info) => {
|
|
33971
33966
|
await rm(info.path, { recursive: true, force: true });
|
|
@@ -34737,12 +34732,12 @@ var init_engine = __esm({
|
|
|
34737
34732
|
* content digest) and the returned ref carries the event seq when the
|
|
34738
34733
|
* emitter resolved one.
|
|
34739
34734
|
*/
|
|
34740
|
-
async fsEvidence(observation,
|
|
34735
|
+
async fsEvidence(observation, path90, sha256, content, extra = {}) {
|
|
34741
34736
|
const digest = sha256 && content !== void 0 ? sha256(content) : void 0;
|
|
34742
|
-
const seq = await this.emitEvidence({ observation, path:
|
|
34737
|
+
const seq = await this.emitEvidence({ observation, path: path90, ...extra, ...digest ? { digest } : {} });
|
|
34743
34738
|
return {
|
|
34744
34739
|
tier: "fs-observation",
|
|
34745
|
-
ref:
|
|
34740
|
+
ref: path90,
|
|
34746
34741
|
capturedAt: Date.now(),
|
|
34747
34742
|
...digest ? { digest } : {},
|
|
34748
34743
|
...seq !== void 0 ? { seq } : {}
|
|
@@ -37126,15 +37121,8 @@ async function noteHarnessLifecycle(spine, sessionId2, profileId, budget, baseDi
|
|
|
37126
37121
|
resourcePolicy: budget.policy
|
|
37127
37122
|
});
|
|
37128
37123
|
if (spine.resumedFromSeq !== void 0 && spine.resumedFromSeq > 0) {
|
|
37129
|
-
|
|
37130
|
-
if (original === null) {
|
|
37124
|
+
if (await lastHarnessManifestHash(sessionId2, baseDir) === null) {
|
|
37131
37125
|
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
37126
|
}
|
|
37139
37127
|
} else {
|
|
37140
37128
|
spine.harnessManifest(manifest, manifestHash);
|
|
@@ -37892,9 +37880,9 @@ function spillToolOutput(fullText, meta3) {
|
|
|
37892
37880
|
const rnd = randomBytes3(3).toString("hex");
|
|
37893
37881
|
const safeTool = (meta3?.toolName ?? "tool").replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 32);
|
|
37894
37882
|
const file2 = `${stamp}-${safeTool}-${hash3}-${rnd}.txt`;
|
|
37895
|
-
const
|
|
37896
|
-
writeFileSync11(
|
|
37897
|
-
return
|
|
37883
|
+
const path90 = join14(dir, file2);
|
|
37884
|
+
writeFileSync11(path90, fullText, "utf8");
|
|
37885
|
+
return path90;
|
|
37898
37886
|
} catch {
|
|
37899
37887
|
return null;
|
|
37900
37888
|
}
|
|
@@ -37940,10 +37928,10 @@ function truncateToolResult(text, capOrOpts = TOOL_RESULT_LINE_CAP) {
|
|
|
37940
37928
|
${tail2}`;
|
|
37941
37929
|
}
|
|
37942
37930
|
if (doSpill) {
|
|
37943
|
-
const
|
|
37944
|
-
if (
|
|
37931
|
+
const path90 = spillToolOutput(text, { toolName: opts.toolName });
|
|
37932
|
+
if (path90) {
|
|
37945
37933
|
const spillNote = `
|
|
37946
|
-
\u2026 [full output spilled to: ${
|
|
37934
|
+
\u2026 [full output spilled to: ${path90} \u2014 re-read with read_file if you need the complete text] \u2026`;
|
|
37947
37935
|
if (preview.includes("] \u2026\n")) {
|
|
37948
37936
|
preview = preview.replace("] \u2026\n", `] \u2026${spillNote}
|
|
37949
37937
|
`);
|
|
@@ -41056,28 +41044,28 @@ var init_storage = __esm({
|
|
|
41056
41044
|
VALID_SCALARS = /^(true|false|null|~)$/i;
|
|
41057
41045
|
Storage = class {
|
|
41058
41046
|
/** Read a Markdown file with frontmatter. Throws if not found. */
|
|
41059
|
-
read(
|
|
41060
|
-
if (!existsSync19(
|
|
41061
|
-
throw new Error(`File not found: ${
|
|
41047
|
+
read(path90) {
|
|
41048
|
+
if (!existsSync19(path90)) {
|
|
41049
|
+
throw new Error(`File not found: ${path90}`);
|
|
41062
41050
|
}
|
|
41063
|
-
const md = readFileSync16(
|
|
41051
|
+
const md = readFileSync16(path90, "utf8");
|
|
41064
41052
|
return parseFrontmatter(md);
|
|
41065
41053
|
}
|
|
41066
41054
|
/** Read a Markdown file; returns null if not found. */
|
|
41067
|
-
readIfExists(
|
|
41068
|
-
if (!existsSync19(
|
|
41069
|
-
return this.read(
|
|
41055
|
+
readIfExists(path90) {
|
|
41056
|
+
if (!existsSync19(path90)) return null;
|
|
41057
|
+
return this.read(path90);
|
|
41070
41058
|
}
|
|
41071
41059
|
/**
|
|
41072
41060
|
* Write a Markdown file atomically (tmp + rename). Creates parent dirs.
|
|
41073
41061
|
* The meta object is serialized as YAML frontmatter; body as Markdown.
|
|
41074
41062
|
*/
|
|
41075
|
-
write(
|
|
41076
|
-
mkdirSync10(dirname2(
|
|
41077
|
-
const tmp =
|
|
41063
|
+
write(path90, meta3, body) {
|
|
41064
|
+
mkdirSync10(dirname2(path90), { recursive: true });
|
|
41065
|
+
const tmp = path90 + ".tmp-" + process.pid;
|
|
41078
41066
|
const md = serializeFrontmatter(meta3, body);
|
|
41079
41067
|
writeFileSync13(tmp, md, "utf8");
|
|
41080
|
-
renameSync(tmp,
|
|
41068
|
+
renameSync(tmp, path90);
|
|
41081
41069
|
}
|
|
41082
41070
|
/** List all .md files in a directory (non-recursive). */
|
|
41083
41071
|
listMarkdown(dir) {
|
|
@@ -41139,8 +41127,8 @@ function nextPlanTaskId(store6) {
|
|
|
41139
41127
|
return `t${store6.counter}`;
|
|
41140
41128
|
}
|
|
41141
41129
|
function writePlanTaskArtifact(rootDir, task) {
|
|
41142
|
-
const
|
|
41143
|
-
mkdirSync11(dirname3(
|
|
41130
|
+
const path90 = join18(rootDir, "plan-tasks", `${task.id}.md`);
|
|
41131
|
+
mkdirSync11(dirname3(path90), { recursive: true });
|
|
41144
41132
|
const meta3 = {
|
|
41145
41133
|
kind: "task",
|
|
41146
41134
|
id: task.id,
|
|
@@ -41161,7 +41149,7 @@ function writePlanTaskArtifact(rootDir, task) {
|
|
|
41161
41149
|
task.notes?.trim() ? task.notes.trim() : "_(no notes)_",
|
|
41162
41150
|
""
|
|
41163
41151
|
].filter((l) => l !== null).join("\n");
|
|
41164
|
-
new Storage().write(
|
|
41152
|
+
new Storage().write(path90, meta3, body);
|
|
41165
41153
|
}
|
|
41166
41154
|
function loadHandle(rootDir) {
|
|
41167
41155
|
const jsonPath = join18(rootDir, "plan.json");
|
|
@@ -42960,6 +42948,7 @@ var init_servers = __esm({
|
|
|
42960
42948
|
// src/cli/lsp/manager.ts
|
|
42961
42949
|
import { spawn as spawn10 } from "node:child_process";
|
|
42962
42950
|
import { readFileSync as readFileSync18 } from "node:fs";
|
|
42951
|
+
import path34 from "node:path";
|
|
42963
42952
|
function processTransport(child) {
|
|
42964
42953
|
return {
|
|
42965
42954
|
send: (data) => {
|
|
@@ -42976,12 +42965,22 @@ function processTransport(child) {
|
|
|
42976
42965
|
};
|
|
42977
42966
|
}
|
|
42978
42967
|
function getSharedLspManager(cwd = process.cwd()) {
|
|
42979
|
-
|
|
42980
|
-
|
|
42968
|
+
const key = path34.resolve(cwd);
|
|
42969
|
+
const existing = sharedByRoot.get(key);
|
|
42970
|
+
if (existing) return existing;
|
|
42981
42971
|
const manager = new LspManager({ cwd });
|
|
42982
|
-
|
|
42972
|
+
sharedByRoot.set(key, manager);
|
|
42983
42973
|
return manager;
|
|
42984
42974
|
}
|
|
42975
|
+
function disposeSharedLspManager() {
|
|
42976
|
+
for (const manager of sharedByRoot.values()) {
|
|
42977
|
+
try {
|
|
42978
|
+
manager.dispose();
|
|
42979
|
+
} catch {
|
|
42980
|
+
}
|
|
42981
|
+
}
|
|
42982
|
+
sharedByRoot.clear();
|
|
42983
|
+
}
|
|
42985
42984
|
function normalizeLocations(res) {
|
|
42986
42985
|
if (!res) return [];
|
|
42987
42986
|
const arr = Array.isArray(res) ? res : [res];
|
|
@@ -43048,7 +43047,7 @@ function normalizeRename(res) {
|
|
|
43048
43047
|
if (files.length === 0) return null;
|
|
43049
43048
|
return { files, totalEdits: total };
|
|
43050
43049
|
}
|
|
43051
|
-
var SYMBOL_KINDS, LspManager,
|
|
43050
|
+
var SYMBOL_KINDS, LspManager, sharedByRoot;
|
|
43052
43051
|
var init_manager = __esm({
|
|
43053
43052
|
"src/cli/lsp/manager.ts"() {
|
|
43054
43053
|
"use strict";
|
|
@@ -43271,11 +43270,11 @@ var init_manager = __esm({
|
|
|
43271
43270
|
this.servers.clear();
|
|
43272
43271
|
}
|
|
43273
43272
|
};
|
|
43274
|
-
|
|
43273
|
+
sharedByRoot = /* @__PURE__ */ new Map();
|
|
43275
43274
|
if (typeof process !== "undefined" && typeof process.once === "function") {
|
|
43276
43275
|
process.once("exit", () => {
|
|
43277
43276
|
try {
|
|
43278
|
-
|
|
43277
|
+
disposeSharedLspManager();
|
|
43279
43278
|
} catch {
|
|
43280
43279
|
}
|
|
43281
43280
|
});
|
|
@@ -43285,9 +43284,9 @@ var init_manager = __esm({
|
|
|
43285
43284
|
|
|
43286
43285
|
// src/cli/ast/engine.ts
|
|
43287
43286
|
import { readFile as readFile2 } from "node:fs/promises";
|
|
43288
|
-
import
|
|
43287
|
+
import path35 from "node:path";
|
|
43289
43288
|
function isAstSupported(file2) {
|
|
43290
|
-
return TS_EXTENSIONS.has(
|
|
43289
|
+
return TS_EXTENSIONS.has(path35.extname(file2).toLowerCase());
|
|
43291
43290
|
}
|
|
43292
43291
|
function loadTs() {
|
|
43293
43292
|
if (!tsPromise) {
|
|
@@ -43299,8 +43298,8 @@ function errMessage(err) {
|
|
|
43299
43298
|
return err instanceof Error ? err.message : String(err);
|
|
43300
43299
|
}
|
|
43301
43300
|
async function parseFileSymbolsDiag(file2, cwd) {
|
|
43302
|
-
const resolvedPath =
|
|
43303
|
-
const extension =
|
|
43301
|
+
const resolvedPath = path35.isAbsolute(file2) ? file2 : path35.join(cwd ?? process.cwd(), file2);
|
|
43302
|
+
const extension = path35.extname(resolvedPath).toLowerCase();
|
|
43304
43303
|
if (!TS_EXTENSIONS.has(extension)) {
|
|
43305
43304
|
return {
|
|
43306
43305
|
status: "unsupported-extension",
|
|
@@ -43342,7 +43341,7 @@ async function parseFileSymbolsDiag(file2, cwd) {
|
|
|
43342
43341
|
}
|
|
43343
43342
|
let source2;
|
|
43344
43343
|
try {
|
|
43345
|
-
source2 = ts.createSourceFile(
|
|
43344
|
+
source2 = ts.createSourceFile(path35.basename(resolvedPath), text, ts.ScriptTarget.Latest, true);
|
|
43346
43345
|
} catch (err) {
|
|
43347
43346
|
return {
|
|
43348
43347
|
status: "parse-error",
|
|
@@ -43567,11 +43566,11 @@ var init_store2 = __esm({
|
|
|
43567
43566
|
// src/cli/semantic/index.ts
|
|
43568
43567
|
import { promises as fs18, existsSync as existsSync24, readFileSync as readFileSync19 } from "node:fs";
|
|
43569
43568
|
import { homedir as homedir7 } from "node:os";
|
|
43570
|
-
import
|
|
43569
|
+
import path36 from "node:path";
|
|
43571
43570
|
import { createHash as createHash12 } from "node:crypto";
|
|
43572
43571
|
function getIndexPath(root) {
|
|
43573
|
-
const hash3 = createHash12("sha1").update(
|
|
43574
|
-
return process.env.ZELARI_SEMANTIC_FILE ??
|
|
43572
|
+
const hash3 = createHash12("sha1").update(path36.resolve(root)).digest("hex").slice(0, 16);
|
|
43573
|
+
return process.env.ZELARI_SEMANTIC_FILE ?? path36.join(homedir7(), ".tmp", "zelari-code", "semantic", `${hash3}.json`);
|
|
43575
43574
|
}
|
|
43576
43575
|
async function collectSourceFiles(root, maxFiles = 1500) {
|
|
43577
43576
|
const out = [];
|
|
@@ -43589,11 +43588,11 @@ async function collectSourceFiles(root, maxFiles = 1500) {
|
|
|
43589
43588
|
if (entry.isDirectory() && IGNORE_DIRS.has(entry.name)) continue;
|
|
43590
43589
|
if (entry.isDirectory()) continue;
|
|
43591
43590
|
}
|
|
43592
|
-
const full =
|
|
43591
|
+
const full = path36.join(dir, entry.name);
|
|
43593
43592
|
if (entry.isDirectory()) {
|
|
43594
43593
|
if (IGNORE_DIRS.has(entry.name)) continue;
|
|
43595
43594
|
await walk2(full);
|
|
43596
|
-
} else if (SOURCE_EXTENSIONS.has(
|
|
43595
|
+
} else if (SOURCE_EXTENSIONS.has(path36.extname(entry.name).toLowerCase())) {
|
|
43597
43596
|
out.push(full);
|
|
43598
43597
|
}
|
|
43599
43598
|
}
|
|
@@ -43642,7 +43641,7 @@ async function buildIndex(files, embed, options) {
|
|
|
43642
43641
|
}
|
|
43643
43642
|
async function saveIndex(root, data) {
|
|
43644
43643
|
const file2 = getIndexPath(root);
|
|
43645
|
-
await fs18.mkdir(
|
|
43644
|
+
await fs18.mkdir(path36.dirname(file2), { recursive: true });
|
|
43646
43645
|
const tmp = `${file2}.tmp-${process.pid}`;
|
|
43647
43646
|
await fs18.writeFile(tmp, JSON.stringify(data), "utf8");
|
|
43648
43647
|
await fs18.rename(tmp, file2);
|
|
@@ -44524,7 +44523,7 @@ var init_provider = __esm({
|
|
|
44524
44523
|
});
|
|
44525
44524
|
|
|
44526
44525
|
// src/cli/semantic/tools.ts
|
|
44527
|
-
import
|
|
44526
|
+
import path37 from "node:path";
|
|
44528
44527
|
function createSemanticTool(deps) {
|
|
44529
44528
|
const buildEmbedFn = deps.buildEmbedFn ?? buildProviderEmbedFn;
|
|
44530
44529
|
return {
|
|
@@ -44551,7 +44550,7 @@ function createSemanticTool(deps) {
|
|
|
44551
44550
|
return typedOk({
|
|
44552
44551
|
count: res.hits.length,
|
|
44553
44552
|
results: res.hits.map((h) => ({
|
|
44554
|
-
location: `${
|
|
44553
|
+
location: `${path37.relative(deps.root, h.file) || h.file}:${h.startLine}-${h.endLine}`,
|
|
44555
44554
|
score: Number(h.score.toFixed(3)),
|
|
44556
44555
|
preview: h.text.length > 400 ? `${h.text.slice(0, 400)}\u2026` : h.text
|
|
44557
44556
|
}))
|
|
@@ -44571,7 +44570,7 @@ var init_tools4 = __esm({
|
|
|
44571
44570
|
|
|
44572
44571
|
// src/cli/browser/driver.ts
|
|
44573
44572
|
import { createRequire as createRequire2 } from "node:module";
|
|
44574
|
-
import
|
|
44573
|
+
import path38 from "node:path";
|
|
44575
44574
|
import { pathToFileURL } from "node:url";
|
|
44576
44575
|
function asPlaywright(mod) {
|
|
44577
44576
|
if (!mod || typeof mod !== "object") return null;
|
|
@@ -44582,10 +44581,10 @@ function asPlaywright(mod) {
|
|
|
44582
44581
|
return null;
|
|
44583
44582
|
}
|
|
44584
44583
|
async function loadPlaywright(cwd) {
|
|
44585
|
-
const base2 = cwd && cwd.length > 0 ?
|
|
44584
|
+
const base2 = cwd && cwd.length > 0 ? path38.resolve(cwd) : void 0;
|
|
44586
44585
|
if (base2) {
|
|
44587
44586
|
try {
|
|
44588
|
-
const req = createRequire2(
|
|
44587
|
+
const req = createRequire2(path38.join(base2, "package.json"));
|
|
44589
44588
|
const resolved = req.resolve("playwright");
|
|
44590
44589
|
const mod = await import(pathToFileURL(resolved).href);
|
|
44591
44590
|
const pw = asPlaywright(mod);
|
|
@@ -44800,7 +44799,7 @@ var init_driver = __esm({
|
|
|
44800
44799
|
});
|
|
44801
44800
|
|
|
44802
44801
|
// src/cli/browser/tools.ts
|
|
44803
|
-
import
|
|
44802
|
+
import path39 from "node:path";
|
|
44804
44803
|
import os8 from "node:os";
|
|
44805
44804
|
function createBrowserTool(deps = {}) {
|
|
44806
44805
|
return {
|
|
@@ -44819,7 +44818,7 @@ function createBrowserTool(deps = {}) {
|
|
|
44819
44818
|
execute: async (args, ctx) => {
|
|
44820
44819
|
const a = args;
|
|
44821
44820
|
const dir = deps.screenshotDir ?? os8.tmpdir();
|
|
44822
|
-
const screenshotPath = a.screenshot === false ? void 0 :
|
|
44821
|
+
const screenshotPath = a.screenshot === false ? void 0 : path39.join(dir, `zelari-browser-${Date.now()}.png`);
|
|
44823
44822
|
const result = await runBrowserCheck(
|
|
44824
44823
|
{
|
|
44825
44824
|
url: a.url,
|
|
@@ -44931,21 +44930,21 @@ function normalizeAuth(auth) {
|
|
|
44931
44930
|
return "agent";
|
|
44932
44931
|
}
|
|
44933
44932
|
function readSecrets() {
|
|
44934
|
-
const
|
|
44935
|
-
if (!existsSync25(
|
|
44933
|
+
const path90 = getSshSecretsPath();
|
|
44934
|
+
if (!existsSync25(path90)) return {};
|
|
44936
44935
|
try {
|
|
44937
|
-
return JSON.parse(readFileSync20(
|
|
44936
|
+
return JSON.parse(readFileSync20(path90, "utf8"));
|
|
44938
44937
|
} catch {
|
|
44939
44938
|
return {};
|
|
44940
44939
|
}
|
|
44941
44940
|
}
|
|
44942
44941
|
function writeSecrets(data) {
|
|
44943
|
-
const
|
|
44944
|
-
mkdirSync12(dirname4(
|
|
44945
|
-
writeFileSync15(
|
|
44942
|
+
const path90 = getSshSecretsPath();
|
|
44943
|
+
mkdirSync12(dirname4(path90), { recursive: true });
|
|
44944
|
+
writeFileSync15(path90, `${JSON.stringify(data, null, 2)}
|
|
44946
44945
|
`, "utf8");
|
|
44947
44946
|
try {
|
|
44948
|
-
chmodSync(
|
|
44947
|
+
chmodSync(path90, 384);
|
|
44949
44948
|
} catch {
|
|
44950
44949
|
}
|
|
44951
44950
|
}
|
|
@@ -44974,10 +44973,10 @@ function deleteSshPassword(id3) {
|
|
|
44974
44973
|
writeSecrets({ passwords });
|
|
44975
44974
|
}
|
|
44976
44975
|
function readStore2() {
|
|
44977
|
-
const
|
|
44978
|
-
if (!existsSync25(
|
|
44976
|
+
const path90 = getSshTargetsPath();
|
|
44977
|
+
if (!existsSync25(path90)) return [];
|
|
44979
44978
|
try {
|
|
44980
|
-
const parsed = JSON.parse(readFileSync20(
|
|
44979
|
+
const parsed = JSON.parse(readFileSync20(path90, "utf8"));
|
|
44981
44980
|
const list = Array.isArray(parsed.targets) ? parsed.targets : [];
|
|
44982
44981
|
return list.filter(
|
|
44983
44982
|
(t) => t && typeof t.id === "string" && typeof t.host === "string" && typeof t.user === "string"
|
|
@@ -44992,11 +44991,11 @@ function readStore2() {
|
|
|
44992
44991
|
}
|
|
44993
44992
|
}
|
|
44994
44993
|
function writeStore2(targets) {
|
|
44995
|
-
const
|
|
44996
|
-
mkdirSync12(dirname4(
|
|
44994
|
+
const path90 = getSshTargetsPath();
|
|
44995
|
+
mkdirSync12(dirname4(path90), { recursive: true });
|
|
44997
44996
|
const clean = targets.map(({ hasPassword: _hp, ...t }) => t);
|
|
44998
44997
|
writeFileSync15(
|
|
44999
|
-
|
|
44998
|
+
path90,
|
|
45000
44999
|
`${JSON.stringify({ targets: clean }, null, 2)}
|
|
45001
45000
|
`,
|
|
45002
45001
|
"utf8"
|
|
@@ -45242,11 +45241,11 @@ function formatSshTargetsForPrompt() {
|
|
|
45242
45241
|
];
|
|
45243
45242
|
for (const t of targets) {
|
|
45244
45243
|
const tags = t.tags?.length ? ` tags=[${t.tags.join(",")}]` : "";
|
|
45245
|
-
const
|
|
45244
|
+
const path90 = t.defaultRemotePath ? ` remotePath=${t.defaultRemotePath}` : "";
|
|
45246
45245
|
const allow = t.allowedCommands?.length ? ` allowed=${t.allowedCommands.join("|")}` : " allowed=status-only";
|
|
45247
45246
|
const auth = t.auth === "password" ? " auth=password" : t.auth === "keyPath" ? " auth=key" : " auth=agent";
|
|
45248
45247
|
lines.push(
|
|
45249
|
-
`- id=${t.id} name=${t.name} ${t.user}@${t.host}:${t.port ?? 22}${auth}${
|
|
45248
|
+
`- id=${t.id} name=${t.name} ${t.user}@${t.host}:${t.port ?? 22}${auth}${path90}${tags}${allow}`
|
|
45250
45249
|
);
|
|
45251
45250
|
}
|
|
45252
45251
|
return lines.join("\n");
|
|
@@ -45373,10 +45372,10 @@ var init_tools6 = __esm({
|
|
|
45373
45372
|
|
|
45374
45373
|
// src/cli/workspace/worldModel.ts
|
|
45375
45374
|
import { promises as fs19 } from "node:fs";
|
|
45376
|
-
import
|
|
45375
|
+
import path40 from "node:path";
|
|
45377
45376
|
import { spawn as spawn12 } from "node:child_process";
|
|
45378
45377
|
function worldDir(cwd) {
|
|
45379
|
-
return
|
|
45378
|
+
return path40.join(cwd, WORLD_DIR_NAME);
|
|
45380
45379
|
}
|
|
45381
45380
|
async function ensureWorldDir(cwd) {
|
|
45382
45381
|
const dir = worldDir(cwd);
|
|
@@ -45386,10 +45385,10 @@ async function ensureWorldDir(cwd) {
|
|
|
45386
45385
|
async function appendTimeline(cwd, entry) {
|
|
45387
45386
|
const dir = await ensureWorldDir(cwd);
|
|
45388
45387
|
const line = JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), ...entry }) + "\n";
|
|
45389
|
-
await fs19.appendFile(
|
|
45388
|
+
await fs19.appendFile(path40.join(dir, TIMELINE_FILE), line, "utf8");
|
|
45390
45389
|
}
|
|
45391
45390
|
async function readChecks(cwd) {
|
|
45392
|
-
const p3 =
|
|
45391
|
+
const p3 = path40.join(worldDir(cwd), CHECKS_FILE);
|
|
45393
45392
|
try {
|
|
45394
45393
|
const raw = await fs19.readFile(p3, "utf8");
|
|
45395
45394
|
const parsed = JSON.parse(raw);
|
|
@@ -45464,8 +45463,8 @@ function runShell(command, cwd, timeoutMs2, signal) {
|
|
|
45464
45463
|
});
|
|
45465
45464
|
}
|
|
45466
45465
|
async function runBacktest(cwd, signal) {
|
|
45467
|
-
const checksPath =
|
|
45468
|
-
const hypothesisPath =
|
|
45466
|
+
const checksPath = path40.join(worldDir(cwd), CHECKS_FILE);
|
|
45467
|
+
const hypothesisPath = path40.join(worldDir(cwd), HYPOTHESIS_FILE);
|
|
45469
45468
|
const checks = await readChecks(cwd);
|
|
45470
45469
|
if (checks.length === 0) {
|
|
45471
45470
|
return {
|
|
@@ -45534,7 +45533,7 @@ var init_worldModel = __esm({
|
|
|
45534
45533
|
"use strict";
|
|
45535
45534
|
init_zod();
|
|
45536
45535
|
init_toolTypes();
|
|
45537
|
-
WORLD_DIR_NAME =
|
|
45536
|
+
WORLD_DIR_NAME = path40.join(".zelari", "world");
|
|
45538
45537
|
HYPOTHESIS_FILE = "hypothesis.md";
|
|
45539
45538
|
CHECKS_FILE = "checks.json";
|
|
45540
45539
|
TIMELINE_FILE = "timeline.jsonl";
|
|
@@ -45551,7 +45550,7 @@ var init_worldModel = __esm({
|
|
|
45551
45550
|
execute: async (args, ctx) => {
|
|
45552
45551
|
try {
|
|
45553
45552
|
const dir = await ensureWorldDir(ctx.cwd);
|
|
45554
|
-
const file2 =
|
|
45553
|
+
const file2 = path40.join(dir, HYPOTHESIS_FILE);
|
|
45555
45554
|
if (args.append) {
|
|
45556
45555
|
const block = `
|
|
45557
45556
|
|
|
@@ -45590,7 +45589,7 @@ ${args.content}
|
|
|
45590
45589
|
execute: async (args, ctx) => {
|
|
45591
45590
|
try {
|
|
45592
45591
|
const dir = await ensureWorldDir(ctx.cwd);
|
|
45593
|
-
const file2 =
|
|
45592
|
+
const file2 = path40.join(dir, CHECKS_FILE);
|
|
45594
45593
|
const body = { checks: args.checks };
|
|
45595
45594
|
await fs19.writeFile(file2, JSON.stringify(body, null, 2) + "\n", "utf8");
|
|
45596
45595
|
await appendTimeline(ctx.cwd, { kind: "checks_set", count: args.checks.length });
|
|
@@ -45629,8 +45628,8 @@ ${args.content}
|
|
|
45629
45628
|
stdoutPreview: "(dryRun)",
|
|
45630
45629
|
mismatch: "dryRun"
|
|
45631
45630
|
})),
|
|
45632
|
-
hypothesisPath:
|
|
45633
|
-
checksPath:
|
|
45631
|
+
hypothesisPath: path40.join(worldDir(ctx.cwd), HYPOTHESIS_FILE),
|
|
45632
|
+
checksPath: path40.join(worldDir(ctx.cwd), CHECKS_FILE)
|
|
45634
45633
|
});
|
|
45635
45634
|
}
|
|
45636
45635
|
const result = await runBacktest(ctx.cwd, ctx.signal);
|
|
@@ -45654,7 +45653,7 @@ ${args.content}
|
|
|
45654
45653
|
execute: async (args, ctx) => {
|
|
45655
45654
|
try {
|
|
45656
45655
|
const dir = await ensureWorldDir(ctx.cwd);
|
|
45657
|
-
const file2 =
|
|
45656
|
+
const file2 = path40.join(dir, TIMELINE_FILE);
|
|
45658
45657
|
await appendTimeline(ctx.cwd, {
|
|
45659
45658
|
kind: args.kind,
|
|
45660
45659
|
summary: args.summary,
|
|
@@ -46317,12 +46316,12 @@ __export(folderTrust_exports, {
|
|
|
46317
46316
|
});
|
|
46318
46317
|
import { homedir as homedir9 } from "node:os";
|
|
46319
46318
|
import { existsSync as existsSync26, mkdirSync as mkdirSync13, readFileSync as readFileSync21, writeFileSync as writeFileSync16 } from "node:fs";
|
|
46320
|
-
import
|
|
46319
|
+
import path41 from "node:path";
|
|
46321
46320
|
function trustStorePath() {
|
|
46322
|
-
return _overrideStorePath ??
|
|
46321
|
+
return _overrideStorePath ?? path41.join(homedir9(), ".zelari-code", "trust.json");
|
|
46323
46322
|
}
|
|
46324
46323
|
function normalize4(p3) {
|
|
46325
|
-
const resolved =
|
|
46324
|
+
const resolved = path41.resolve(p3);
|
|
46326
46325
|
return process.platform === "win32" ? resolved.toLowerCase() : resolved;
|
|
46327
46326
|
}
|
|
46328
46327
|
function readStore3() {
|
|
@@ -46338,7 +46337,7 @@ function readStore3() {
|
|
|
46338
46337
|
function writeStore3(store6) {
|
|
46339
46338
|
const p3 = trustStorePath();
|
|
46340
46339
|
try {
|
|
46341
|
-
mkdirSync13(
|
|
46340
|
+
mkdirSync13(path41.dirname(p3), { recursive: true });
|
|
46342
46341
|
writeFileSync16(p3, JSON.stringify(store6, null, 2), "utf8");
|
|
46343
46342
|
} catch (err) {
|
|
46344
46343
|
throw new Error(
|
|
@@ -46364,7 +46363,7 @@ function isFolderTrusted(folderPath) {
|
|
|
46364
46363
|
}
|
|
46365
46364
|
function trustFolder(folderPath) {
|
|
46366
46365
|
const store6 = readStore3();
|
|
46367
|
-
const normalized =
|
|
46366
|
+
const normalized = path41.resolve(folderPath);
|
|
46368
46367
|
if (!store6.folders.some((f) => normalize4(f.path) === normalize4(normalized))) {
|
|
46369
46368
|
store6.folders.push({ path: normalized, trustedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
46370
46369
|
writeStore3(store6);
|
|
@@ -46548,7 +46547,7 @@ __export(policyEngine_exports, {
|
|
|
46548
46547
|
});
|
|
46549
46548
|
import { readFileSync as readFileSync22 } from "node:fs";
|
|
46550
46549
|
import { homedir as homedir11 } from "node:os";
|
|
46551
|
-
import
|
|
46550
|
+
import path42 from "node:path";
|
|
46552
46551
|
function emptyPolicySet() {
|
|
46553
46552
|
return { agents: /* @__PURE__ */ new Map(), warnings: [], precedence: policyPrecedenceFromEnv() };
|
|
46554
46553
|
}
|
|
@@ -46793,9 +46792,9 @@ function loadPolicySet(root, opts = {}) {
|
|
|
46793
46792
|
const mode = opts.mode ?? "permissive";
|
|
46794
46793
|
const warnings = [];
|
|
46795
46794
|
const precedence = policyPrecedenceFromEnv();
|
|
46796
|
-
const project = readPolicyFile(
|
|
46795
|
+
const project = readPolicyFile(path42.join(root, ".zelari", "policy.json"), warnings, mode);
|
|
46797
46796
|
const global = readPolicyFile(
|
|
46798
|
-
|
|
46797
|
+
path42.join(opts.homeDir ?? homedir11(), ".zelari", "policy.json"),
|
|
46799
46798
|
warnings,
|
|
46800
46799
|
mode
|
|
46801
46800
|
);
|
|
@@ -47232,7 +47231,7 @@ var init_resourceClaims = __esm({
|
|
|
47232
47231
|
// src/cli/toolResultCache.ts
|
|
47233
47232
|
import { createHash as createHash13 } from "node:crypto";
|
|
47234
47233
|
import { promises as fs20 } from "node:fs";
|
|
47235
|
-
import
|
|
47234
|
+
import path43 from "node:path";
|
|
47236
47235
|
function isToolCacheEnabled() {
|
|
47237
47236
|
const raw = process.env.ZELARI_TOOL_CACHE;
|
|
47238
47237
|
return raw !== "0" && raw !== "false" && raw !== "off";
|
|
@@ -47317,7 +47316,7 @@ async function statKey(toolName, input, ctx) {
|
|
|
47317
47316
|
if (!input || typeof input !== "object") return null;
|
|
47318
47317
|
const rawPath = input.path;
|
|
47319
47318
|
if (typeof rawPath !== "string" || rawPath.length === 0) return null;
|
|
47320
|
-
const abs =
|
|
47319
|
+
const abs = path43.isAbsolute(rawPath) ? rawPath : path43.join(ctx.cwd, rawPath);
|
|
47321
47320
|
try {
|
|
47322
47321
|
const st = await fs20.stat(abs);
|
|
47323
47322
|
return hashKey({
|
|
@@ -47459,13 +47458,13 @@ function resolveKrakenSubModel(agent, parentModel, env = process.env, opts = {})
|
|
|
47459
47458
|
const kindKey = agent === "explore" ? "ZELARI_KRAKEN_EXPLORE_MODEL" : agent === "verify" ? "ZELARI_KRAKEN_VERIFY_MODEL" : "ZELARI_KRAKEN_GENERAL_MODEL";
|
|
47460
47459
|
const specific = env[kindKey]?.trim();
|
|
47461
47460
|
if (specific) return specific;
|
|
47462
|
-
const
|
|
47463
|
-
if (
|
|
47461
|
+
const shared = env.ZELARI_KRAKEN_SUB_MODEL?.trim();
|
|
47462
|
+
if (shared) {
|
|
47464
47463
|
if (agent === "general" && !env.ZELARI_KRAKEN_GENERAL_MODEL) {
|
|
47465
|
-
if (env.ZELARI_KRAKEN_GENERAL_USES_SUB === "1") return
|
|
47464
|
+
if (env.ZELARI_KRAKEN_GENERAL_USES_SUB === "1") return shared;
|
|
47466
47465
|
return parentModel;
|
|
47467
47466
|
}
|
|
47468
|
-
return
|
|
47467
|
+
return shared;
|
|
47469
47468
|
}
|
|
47470
47469
|
if (agent === "verify" && opts.familyCandidates && opts.familyCandidates.length > 0) {
|
|
47471
47470
|
const picked = pickDifferentFamily(
|
|
@@ -47526,7 +47525,7 @@ __export(toolRegistry_exports, {
|
|
|
47526
47525
|
wrapWithSandbox: () => wrapWithSandbox
|
|
47527
47526
|
});
|
|
47528
47527
|
import { existsSync as existsSync27 } from "node:fs";
|
|
47529
|
-
import
|
|
47528
|
+
import path44 from "node:path";
|
|
47530
47529
|
function createBuiltinToolRegistry(options = {}) {
|
|
47531
47530
|
const root = options.root ?? process.cwd();
|
|
47532
47531
|
const audit = options.audit ?? new AuditLogger();
|
|
@@ -48084,14 +48083,14 @@ function wrapWithDiagnostics(original, root, runner) {
|
|
|
48084
48083
|
function claimedSourcePath(token, args, root) {
|
|
48085
48084
|
const cleaned = token.replace(/^["']|["']$/g, "");
|
|
48086
48085
|
if (!cleaned || cleaned.startsWith("-")) return null;
|
|
48087
|
-
if (!DIAG_SOURCE_EXTENSIONS.has(
|
|
48086
|
+
if (!DIAG_SOURCE_EXTENSIONS.has(path44.extname(cleaned).toLowerCase())) return null;
|
|
48088
48087
|
const bases = [root];
|
|
48089
48088
|
const cwd = args["cwd"];
|
|
48090
48089
|
if (typeof cwd === "string" && cwd.length > 0) {
|
|
48091
|
-
bases.unshift(
|
|
48090
|
+
bases.unshift(path44.isAbsolute(cwd) ? cwd : path44.resolve(root, cwd));
|
|
48092
48091
|
}
|
|
48093
48092
|
for (const base2 of bases) {
|
|
48094
|
-
const candidate =
|
|
48093
|
+
const candidate = path44.isAbsolute(cleaned) ? path44.normalize(cleaned) : path44.resolve(base2, cleaned);
|
|
48095
48094
|
try {
|
|
48096
48095
|
const contained = resolveSandboxedPath(candidate, { root });
|
|
48097
48096
|
if (existsSync27(contained)) return contained;
|
|
@@ -48379,7 +48378,7 @@ var init_toolRegistry = __esm({
|
|
|
48379
48378
|
|
|
48380
48379
|
// src/cli/metrics.ts
|
|
48381
48380
|
import { promises as fs21, existsSync as existsSync28, statSync as statSync4, renameSync as renameSync3, appendFileSync as appendFileSync3, mkdirSync as mkdirSync14 } from "node:fs";
|
|
48382
|
-
import
|
|
48381
|
+
import path45 from "node:path";
|
|
48383
48382
|
import os9 from "node:os";
|
|
48384
48383
|
async function readMetrics(file2) {
|
|
48385
48384
|
let raw = "";
|
|
@@ -48428,8 +48427,8 @@ var init_metrics3 = __esm({
|
|
|
48428
48427
|
file;
|
|
48429
48428
|
writeQueue = Promise.resolve();
|
|
48430
48429
|
constructor(file2) {
|
|
48431
|
-
this.file = file2 ?? process.env.ANATHEMA_METRICS_FILE ??
|
|
48432
|
-
mkdirSync14(
|
|
48430
|
+
this.file = file2 ?? process.env.ANATHEMA_METRICS_FILE ?? path45.join(os9.homedir(), ".tmp", "zelari-code", "metrics.jsonl");
|
|
48431
|
+
mkdirSync14(path45.dirname(this.file), { recursive: true });
|
|
48433
48432
|
}
|
|
48434
48433
|
/** Metrics file path — doctor/summary readers use this. */
|
|
48435
48434
|
get filePath() {
|
|
@@ -48752,7 +48751,7 @@ Current policy: **lead only**.
|
|
|
48752
48751
|
|
|
48753
48752
|
// src/cli/kraken/verificationAdapters/node.ts
|
|
48754
48753
|
import { readFile as readFile3, stat as stat2 } from "node:fs/promises";
|
|
48755
|
-
import
|
|
48754
|
+
import path46 from "node:path";
|
|
48756
48755
|
async function fileExists(candidate) {
|
|
48757
48756
|
try {
|
|
48758
48757
|
return (await stat2(candidate)).isFile();
|
|
@@ -48762,7 +48761,7 @@ async function fileExists(candidate) {
|
|
|
48762
48761
|
}
|
|
48763
48762
|
async function readPackageJson(root) {
|
|
48764
48763
|
try {
|
|
48765
|
-
return JSON.parse(await readFile3(
|
|
48764
|
+
return JSON.parse(await readFile3(path46.join(root, "package.json"), "utf-8"));
|
|
48766
48765
|
} catch {
|
|
48767
48766
|
return null;
|
|
48768
48767
|
}
|
|
@@ -48776,7 +48775,7 @@ async function resolvePackageManager(root) {
|
|
|
48776
48775
|
const fromField = packageManagerFromField(await readPackageJson(root));
|
|
48777
48776
|
if (fromField) return { pm: fromField, declaredToolchain: true };
|
|
48778
48777
|
for (const [marker, pm] of PM_LOCKFILES) {
|
|
48779
|
-
if (await fileExists(
|
|
48778
|
+
if (await fileExists(path46.join(root, marker))) return { pm, declaredToolchain: true };
|
|
48780
48779
|
}
|
|
48781
48780
|
return { pm: "npm", declaredToolchain: false };
|
|
48782
48781
|
}
|
|
@@ -48799,7 +48798,7 @@ var init_node = __esm({
|
|
|
48799
48798
|
KNOWN_PACKAGE_MANAGERS = /* @__PURE__ */ new Set(["npm", "pnpm", "yarn", "bun"]);
|
|
48800
48799
|
nodeAdapter = {
|
|
48801
48800
|
async detect(root) {
|
|
48802
|
-
if (!await fileExists(
|
|
48801
|
+
if (!await fileExists(path46.join(root, "package.json"))) return 0;
|
|
48803
48802
|
const { declaredToolchain } = await resolvePackageManager(root);
|
|
48804
48803
|
return declaredToolchain ? 20 : 10;
|
|
48805
48804
|
},
|
|
@@ -48818,7 +48817,7 @@ var init_node = __esm({
|
|
|
48818
48817
|
|
|
48819
48818
|
// src/cli/kraken/verificationAdapters/python.ts
|
|
48820
48819
|
import { readFile as readFile4, stat as stat3 } from "node:fs/promises";
|
|
48821
|
-
import
|
|
48820
|
+
import path47 from "node:path";
|
|
48822
48821
|
async function fileExists2(candidate) {
|
|
48823
48822
|
try {
|
|
48824
48823
|
return (await stat3(candidate)).isFile();
|
|
@@ -48854,7 +48853,7 @@ var init_python = __esm({
|
|
|
48854
48853
|
async detect(root) {
|
|
48855
48854
|
let best = 0;
|
|
48856
48855
|
for (const [marker, score] of DETECT_MARKERS) {
|
|
48857
|
-
if (score > best && await fileExists2(
|
|
48856
|
+
if (score > best && await fileExists2(path47.join(root, marker))) best = score;
|
|
48858
48857
|
}
|
|
48859
48858
|
return best;
|
|
48860
48859
|
},
|
|
@@ -48862,12 +48861,12 @@ var init_python = __esm({
|
|
|
48862
48861
|
const present = /* @__PURE__ */ new Map();
|
|
48863
48862
|
for (const name of SCAN_FILES) {
|
|
48864
48863
|
try {
|
|
48865
|
-
present.set(name, await readFile4(
|
|
48864
|
+
present.set(name, await readFile4(path47.join(root, name), "utf-8"));
|
|
48866
48865
|
} catch {
|
|
48867
48866
|
}
|
|
48868
48867
|
}
|
|
48869
48868
|
const hasToken = (token) => [...present.values()].some((text) => text.includes(token));
|
|
48870
|
-
const pytestEvidenced = hasToken("pytest") || await dirExists(
|
|
48869
|
+
const pytestEvidenced = hasToken("pytest") || await dirExists(path47.join(root, "tests"));
|
|
48871
48870
|
const mypyReferenced = hasToken("mypy") || present.has("mypy.ini") || present.has(".mypy.ini");
|
|
48872
48871
|
const pyrightReferenced = hasToken("pyright") || present.has("pyrightconfig.json");
|
|
48873
48872
|
return {
|
|
@@ -48883,7 +48882,7 @@ var init_python = __esm({
|
|
|
48883
48882
|
|
|
48884
48883
|
// src/cli/kraken/verificationAdapters/rust.ts
|
|
48885
48884
|
import { stat as stat4 } from "node:fs/promises";
|
|
48886
|
-
import
|
|
48885
|
+
import path48 from "node:path";
|
|
48887
48886
|
async function fileExists3(candidate) {
|
|
48888
48887
|
try {
|
|
48889
48888
|
return (await stat4(candidate)).isFile();
|
|
@@ -48897,7 +48896,7 @@ var init_rust = __esm({
|
|
|
48897
48896
|
"use strict";
|
|
48898
48897
|
rustAdapter = {
|
|
48899
48898
|
async detect(root) {
|
|
48900
|
-
return await fileExists3(
|
|
48899
|
+
return await fileExists3(path48.join(root, "Cargo.toml")) ? 10 : 0;
|
|
48901
48900
|
},
|
|
48902
48901
|
async buildPlan(_root) {
|
|
48903
48902
|
void _root;
|
|
@@ -48913,7 +48912,7 @@ var init_rust = __esm({
|
|
|
48913
48912
|
|
|
48914
48913
|
// src/cli/kraken/verificationAdapters/go.ts
|
|
48915
48914
|
import { stat as stat5 } from "node:fs/promises";
|
|
48916
|
-
import
|
|
48915
|
+
import path49 from "node:path";
|
|
48917
48916
|
async function fileExists4(candidate) {
|
|
48918
48917
|
try {
|
|
48919
48918
|
return (await stat5(candidate)).isFile();
|
|
@@ -48927,7 +48926,7 @@ var init_go = __esm({
|
|
|
48927
48926
|
"use strict";
|
|
48928
48927
|
goAdapter = {
|
|
48929
48928
|
async detect(root) {
|
|
48930
|
-
return await fileExists4(
|
|
48929
|
+
return await fileExists4(path49.join(root, "go.mod")) ? 10 : 0;
|
|
48931
48930
|
},
|
|
48932
48931
|
async buildPlan(_root) {
|
|
48933
48932
|
return {
|
|
@@ -48943,7 +48942,7 @@ var init_go = __esm({
|
|
|
48943
48942
|
|
|
48944
48943
|
// src/cli/kraken/verificationAdapters/java.ts
|
|
48945
48944
|
import { stat as stat6 } from "node:fs/promises";
|
|
48946
|
-
import
|
|
48945
|
+
import path50 from "node:path";
|
|
48947
48946
|
async function fileExists5(candidate) {
|
|
48948
48947
|
try {
|
|
48949
48948
|
return (await stat6(candidate)).isFile();
|
|
@@ -48953,13 +48952,13 @@ async function fileExists5(candidate) {
|
|
|
48953
48952
|
}
|
|
48954
48953
|
async function hasGradleMarker(root) {
|
|
48955
48954
|
for (const [marker] of GRADLE_MARKERS) {
|
|
48956
|
-
if (await fileExists5(
|
|
48955
|
+
if (await fileExists5(path50.join(root, marker))) return true;
|
|
48957
48956
|
}
|
|
48958
48957
|
return false;
|
|
48959
48958
|
}
|
|
48960
48959
|
async function gradleCommand(root, verb, platform = process.platform) {
|
|
48961
48960
|
const wrapper = platform === "win32" ? "gradlew.bat" : "gradlew";
|
|
48962
|
-
if (await fileExists5(
|
|
48961
|
+
if (await fileExists5(path50.join(root, wrapper))) {
|
|
48963
48962
|
return platform === "win32" ? `gradlew.bat ${verb}` : `./gradlew ${verb}`;
|
|
48964
48963
|
}
|
|
48965
48964
|
return `gradle ${verb}`;
|
|
@@ -48984,7 +48983,7 @@ var init_java = __esm({
|
|
|
48984
48983
|
async detect(root) {
|
|
48985
48984
|
let best = 0;
|
|
48986
48985
|
for (const [marker, score] of DETECT_MARKERS2) {
|
|
48987
|
-
if (score > best && await fileExists5(
|
|
48986
|
+
if (score > best && await fileExists5(path50.join(root, marker))) best = score;
|
|
48988
48987
|
}
|
|
48989
48988
|
return best;
|
|
48990
48989
|
},
|
|
@@ -48997,7 +48996,7 @@ var init_java = __esm({
|
|
|
48997
48996
|
buildCommand: await gradleCommand(root, "build")
|
|
48998
48997
|
};
|
|
48999
48998
|
}
|
|
49000
|
-
if (await fileExists5(
|
|
48999
|
+
if (await fileExists5(path50.join(root, "pom.xml"))) {
|
|
49001
49000
|
return {
|
|
49002
49001
|
typecheckCommand: null,
|
|
49003
49002
|
// compilation rides the test/package lifecycle
|
|
@@ -49106,7 +49105,7 @@ __export(nativeVerification_exports, {
|
|
|
49106
49105
|
resolvePackCommandsForRoot: () => resolvePackCommandsForRoot
|
|
49107
49106
|
});
|
|
49108
49107
|
import { readFile as readFile5 } from "node:fs/promises";
|
|
49109
|
-
import
|
|
49108
|
+
import path51 from "node:path";
|
|
49110
49109
|
function nativePackEnabled(env = process.env) {
|
|
49111
49110
|
const v = env.ZELARI_VERIFY_PACK?.toLowerCase();
|
|
49112
49111
|
if (v === "0" || v === "off" || v === "false") return false;
|
|
@@ -49149,7 +49148,7 @@ function packTimeoutMs(env = process.env) {
|
|
|
49149
49148
|
}
|
|
49150
49149
|
async function readPackageScripts(cwd = process.cwd()) {
|
|
49151
49150
|
try {
|
|
49152
|
-
const raw = await readFile5(
|
|
49151
|
+
const raw = await readFile5(path51.join(cwd, "package.json"), "utf-8");
|
|
49153
49152
|
const parsed = JSON.parse(raw);
|
|
49154
49153
|
if (parsed && typeof parsed === "object" && typeof parsed.scripts === "object") {
|
|
49155
49154
|
return parsed.scripts;
|
|
@@ -49195,16 +49194,28 @@ var init_nativeVerification = __esm({
|
|
|
49195
49194
|
|
|
49196
49195
|
// src/cli/kraken/verificationBridge.ts
|
|
49197
49196
|
import { createHash as createHash14 } from "node:crypto";
|
|
49198
|
-
function strictDoneEnabled(surface = "kraken") {
|
|
49197
|
+
function strictDoneEnabled(surface = "kraken", env = process.env) {
|
|
49199
49198
|
if (surface === "mission") {
|
|
49200
|
-
const v2 =
|
|
49199
|
+
const v2 = env.ZELARI_MISSION_STRICT;
|
|
49201
49200
|
if (v2 === "0" || v2 === "false") return false;
|
|
49202
49201
|
return true;
|
|
49203
49202
|
}
|
|
49204
|
-
const v =
|
|
49203
|
+
const v = env.ZELARI_STRICT_DONE;
|
|
49205
49204
|
if (v === "0" || v === "false") return false;
|
|
49206
49205
|
return true;
|
|
49207
49206
|
}
|
|
49207
|
+
function strictEnvOverlay(knobs, base2 = process.env) {
|
|
49208
|
+
const overlay = { ...base2 };
|
|
49209
|
+
if (knobs.strictDone !== void 0) {
|
|
49210
|
+
const v = knobs.strictDone ? "1" : "0";
|
|
49211
|
+
overlay.ZELARI_STRICT_DONE = v;
|
|
49212
|
+
overlay.ZELARI_MISSION_STRICT = v;
|
|
49213
|
+
}
|
|
49214
|
+
if (knobs.missionStrict !== void 0) {
|
|
49215
|
+
overlay.ZELARI_MISSION_STRICT = knobs.missionStrict ? "1" : "0";
|
|
49216
|
+
}
|
|
49217
|
+
return overlay;
|
|
49218
|
+
}
|
|
49208
49219
|
function criterionId(check2, index) {
|
|
49209
49220
|
const slug = check2.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48);
|
|
49210
49221
|
return `check-${index + 1}-${slug || "criterion"}`;
|
|
@@ -49341,7 +49352,7 @@ async function anchorSelectionEvidence(results, emit, toolTrace) {
|
|
|
49341
49352
|
}
|
|
49342
49353
|
async function evaluateStrictBuildGate(mode, options = {}) {
|
|
49343
49354
|
const gate = evaluateKrakenCompletionGate(mode);
|
|
49344
|
-
const strictOn = strictDoneEnabled(options.surface ?? "kraken");
|
|
49355
|
+
const strictOn = strictDoneEnabled(options.surface ?? "kraken", options.env);
|
|
49345
49356
|
const nativeOn = nativePackEnabled(options.env ?? process.env);
|
|
49346
49357
|
const selectionAvailable = gate.selectionUsed && gate.total > 0;
|
|
49347
49358
|
const scopeContract = options.taskContract ?? activeContractScope()?.contract;
|
|
@@ -49670,7 +49681,7 @@ var init_completionProofAttestation = __esm({
|
|
|
49670
49681
|
// src/cli/kraken/completionProofPersist.ts
|
|
49671
49682
|
import { open, rename, rm as rm2 } from "node:fs/promises";
|
|
49672
49683
|
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
49673
|
-
import
|
|
49684
|
+
import path52 from "node:path";
|
|
49674
49685
|
function isTruthyFlag2(v) {
|
|
49675
49686
|
const n = v?.trim().toLowerCase();
|
|
49676
49687
|
return n === "1" || n === "true" || n === "yes" || n === "on";
|
|
@@ -49712,8 +49723,8 @@ function isWindowsRenameBlock(err) {
|
|
|
49712
49723
|
return code === "EPERM" || code === "ENOTEMPTY" || code === "EEXIST";
|
|
49713
49724
|
}
|
|
49714
49725
|
async function writeFileAtomic(target, data) {
|
|
49715
|
-
const dir =
|
|
49716
|
-
const tmp =
|
|
49726
|
+
const dir = path52.dirname(target);
|
|
49727
|
+
const tmp = path52.join(dir, `.${path52.basename(target)}.${randomBytes5(6).toString("hex")}.tmp`);
|
|
49717
49728
|
let fh = null;
|
|
49718
49729
|
try {
|
|
49719
49730
|
fh = await open(tmp, "w");
|
|
@@ -49759,7 +49770,7 @@ var init_completionProofPersist = __esm({
|
|
|
49759
49770
|
|
|
49760
49771
|
// src/cli/kraken/completionProof.ts
|
|
49761
49772
|
import { mkdir as mkdir2 } from "node:fs/promises";
|
|
49762
|
-
import
|
|
49773
|
+
import path53 from "node:path";
|
|
49763
49774
|
function verdictOf(evaluation) {
|
|
49764
49775
|
return evaluation.evaluation?.verdict ?? (evaluation.blocked ? "BLOCKED" : "PASS");
|
|
49765
49776
|
}
|
|
@@ -49904,7 +49915,7 @@ async function writeCompletionProofDetailed(evaluation, options = {}) {
|
|
|
49904
49915
|
const mode = options.persistenceMode ?? activeProofPersistenceMode();
|
|
49905
49916
|
try {
|
|
49906
49917
|
const baseDir = options.baseDir ?? process.cwd();
|
|
49907
|
-
const dir =
|
|
49918
|
+
const dir = path53.join(baseDir, ".zelari");
|
|
49908
49919
|
await mkdir2(dir, { recursive: true });
|
|
49909
49920
|
const requested = options.attestation ?? {};
|
|
49910
49921
|
const plan = requested.skipProbes || requested.verificationPlan !== void 0 ? void 0 : await defaultVerificationPlanSnapshot(baseDir);
|
|
@@ -49924,8 +49935,8 @@ async function writeCompletionProofDetailed(evaluation, options = {}) {
|
|
|
49924
49935
|
baseDir
|
|
49925
49936
|
);
|
|
49926
49937
|
const rendered = renderCompletionProof(evaluation, options.meta ?? {}, wrapper.attestation);
|
|
49927
|
-
const markdownPath =
|
|
49928
|
-
const jsonPath =
|
|
49938
|
+
const markdownPath = path53.join(dir, "completion-proof.md");
|
|
49939
|
+
const jsonPath = path53.join(dir, "completion-proof.json");
|
|
49929
49940
|
await writeFileAtomic(markdownPath, rendered.markdown);
|
|
49930
49941
|
await writeFileAtomic(jsonPath, rendered.json);
|
|
49931
49942
|
return { paths: { markdownPath, jsonPath }, mode, requiredBlockReason: null };
|
|
@@ -49951,15 +49962,53 @@ var init_completionProof = __esm({
|
|
|
49951
49962
|
}
|
|
49952
49963
|
});
|
|
49953
49964
|
|
|
49965
|
+
// src/cli/memory/spineTelemetry.ts
|
|
49966
|
+
function spineMemoryEventNote(handle, event) {
|
|
49967
|
+
try {
|
|
49968
|
+
if (event.type === "memory_recall_end" && event.reason === "context-built") {
|
|
49969
|
+
handle.note("context.projection", {
|
|
49970
|
+
subject: "context.projection",
|
|
49971
|
+
...event.contextChars !== void 0 ? { contextChars: event.contextChars } : {},
|
|
49972
|
+
...event.returnedCount !== void 0 ? { returnedCount: event.returnedCount } : {},
|
|
49973
|
+
...event.durationMs !== void 0 ? { durationMs: event.durationMs } : {},
|
|
49974
|
+
...event.backend !== void 0 ? { backend: event.backend } : {}
|
|
49975
|
+
});
|
|
49976
|
+
return;
|
|
49977
|
+
}
|
|
49978
|
+
handle.note(`memory_${event.type}`, {
|
|
49979
|
+
subject: "memory_event",
|
|
49980
|
+
type: event.type,
|
|
49981
|
+
...event.durationMs !== void 0 ? { durationMs: event.durationMs } : {},
|
|
49982
|
+
...event.candidateCount !== void 0 ? { candidateCount: event.candidateCount } : {},
|
|
49983
|
+
...event.returnedCount !== void 0 ? { returnedCount: event.returnedCount } : {},
|
|
49984
|
+
...event.backend !== void 0 ? { backend: event.backend } : {},
|
|
49985
|
+
...event.reason !== void 0 ? { reason: event.reason } : {},
|
|
49986
|
+
...event.memoryId !== void 0 ? { memoryId: event.memoryId } : {}
|
|
49987
|
+
});
|
|
49988
|
+
} catch {
|
|
49989
|
+
}
|
|
49990
|
+
}
|
|
49991
|
+
function memorySinkFor(holder) {
|
|
49992
|
+
return (event) => {
|
|
49993
|
+
const handle = holder.current;
|
|
49994
|
+
if (handle) spineMemoryEventNote(handle, event);
|
|
49995
|
+
};
|
|
49996
|
+
}
|
|
49997
|
+
var init_spineTelemetry = __esm({
|
|
49998
|
+
"src/cli/memory/spineTelemetry.ts"() {
|
|
49999
|
+
"use strict";
|
|
50000
|
+
}
|
|
50001
|
+
});
|
|
50002
|
+
|
|
49954
50003
|
// src/cli/state/fileStateStore.ts
|
|
49955
50004
|
import { createHash as createHash16, randomUUID as randomUUID4 } from "node:crypto";
|
|
49956
50005
|
import { promises as fs22 } from "node:fs";
|
|
49957
|
-
import * as
|
|
50006
|
+
import * as path54 from "node:path";
|
|
49958
50007
|
function shortId() {
|
|
49959
50008
|
return randomUUID4().replace(/-/g, "").slice(0, 12);
|
|
49960
50009
|
}
|
|
49961
50010
|
async function writeJsonAtomic(filePath, data) {
|
|
49962
|
-
await fs22.mkdir(
|
|
50011
|
+
await fs22.mkdir(path54.dirname(filePath), { recursive: true });
|
|
49963
50012
|
const tmp = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
49964
50013
|
await fs22.writeFile(tmp, JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
49965
50014
|
await fs22.rename(tmp, filePath);
|
|
@@ -50020,11 +50069,11 @@ var init_fileStateStore = __esm({
|
|
|
50020
50069
|
indexPath = "";
|
|
50021
50070
|
async init(projectRoot) {
|
|
50022
50071
|
this.root = projectRoot;
|
|
50023
|
-
this.stateDir =
|
|
50024
|
-
this.commitsDir =
|
|
50025
|
-
this.artifactsDir =
|
|
50026
|
-
this.headPath =
|
|
50027
|
-
this.indexPath =
|
|
50072
|
+
this.stateDir = path54.join(projectRoot, ".zelari", "state");
|
|
50073
|
+
this.commitsDir = path54.join(this.stateDir, "commits");
|
|
50074
|
+
this.artifactsDir = path54.join(this.stateDir, "artifacts");
|
|
50075
|
+
this.headPath = path54.join(this.stateDir, "HEAD.json");
|
|
50076
|
+
this.indexPath = path54.join(this.stateDir, "index.jsonl");
|
|
50028
50077
|
await fs22.mkdir(this.commitsDir, { recursive: true });
|
|
50029
50078
|
await fs22.mkdir(this.artifactsDir, { recursive: true });
|
|
50030
50079
|
}
|
|
@@ -50037,13 +50086,13 @@ var init_fileStateStore = __esm({
|
|
|
50037
50086
|
const discoveries = input.discoveries ?? [];
|
|
50038
50087
|
const parent = await this.head();
|
|
50039
50088
|
const id3 = shortId();
|
|
50040
|
-
const artifactRel =
|
|
50041
|
-
const artifactAbs =
|
|
50089
|
+
const artifactRel = path54.join("artifacts", id3);
|
|
50090
|
+
const artifactAbs = path54.join(this.artifactsDir, id3);
|
|
50042
50091
|
await fs22.mkdir(artifactAbs, { recursive: true });
|
|
50043
50092
|
const summary = defaultSummary(input, discoveries);
|
|
50044
|
-
await fs22.writeFile(
|
|
50045
|
-
await writeJsonAtomic(
|
|
50046
|
-
await writeJsonAtomic(
|
|
50093
|
+
await fs22.writeFile(path54.join(artifactAbs, "summary.md"), summary + "\n", "utf8");
|
|
50094
|
+
await writeJsonAtomic(path54.join(artifactAbs, "discoveries.json"), discoveries);
|
|
50095
|
+
await writeJsonAtomic(path54.join(artifactAbs, "verification.json"), input.verification);
|
|
50047
50096
|
const meta3 = {
|
|
50048
50097
|
id: id3,
|
|
50049
50098
|
parentId: parent?.id ?? null,
|
|
@@ -50055,14 +50104,14 @@ var init_fileStateStore = __esm({
|
|
|
50055
50104
|
workspaceCheckpointId: input.workspaceCheckpointId,
|
|
50056
50105
|
verification: {
|
|
50057
50106
|
...input.verification,
|
|
50058
|
-
reportPath: input.verification.reportPath ??
|
|
50107
|
+
reportPath: input.verification.reportPath ?? path54.join(".zelari", "state", artifactRel, "verification.json").replace(/\\/g, "/")
|
|
50059
50108
|
},
|
|
50060
50109
|
changedPaths: input.changedPaths ?? [],
|
|
50061
50110
|
stablePromptHash: input.stablePromptHash,
|
|
50062
50111
|
discoveryCount: discoveries.length,
|
|
50063
50112
|
artifactDir: artifactRel.replace(/\\/g, "/")
|
|
50064
50113
|
};
|
|
50065
|
-
await writeJsonAtomic(
|
|
50114
|
+
await writeJsonAtomic(path54.join(this.commitsDir, `${id3}.json`), meta3);
|
|
50066
50115
|
await writeJsonAtomic(this.headPath, { id: id3, updatedAt: meta3.createdAt });
|
|
50067
50116
|
await fs22.appendFile(this.indexPath, JSON.stringify({ id: id3, createdAt: meta3.createdAt, label: meta3.label }) + "\n", "utf8");
|
|
50068
50117
|
return stripStored(meta3);
|
|
@@ -50073,7 +50122,7 @@ var init_fileStateStore = __esm({
|
|
|
50073
50122
|
return this.get(head.id);
|
|
50074
50123
|
}
|
|
50075
50124
|
async get(id3) {
|
|
50076
|
-
const stored = await readJsonFile(
|
|
50125
|
+
const stored = await readJsonFile(path54.join(this.commitsDir, `${id3}.json`));
|
|
50077
50126
|
return stored ? stripStored(stored) : null;
|
|
50078
50127
|
}
|
|
50079
50128
|
async list(limit = 20) {
|
|
@@ -50112,9 +50161,9 @@ var init_fileStateStore = __esm({
|
|
|
50112
50161
|
async loadDiscoveries(id3) {
|
|
50113
50162
|
const meta3 = id3 ? await this.get(id3) : await this.head();
|
|
50114
50163
|
if (!meta3) return [];
|
|
50115
|
-
const stored = await readJsonFile(
|
|
50164
|
+
const stored = await readJsonFile(path54.join(this.commitsDir, `${meta3.id}.json`));
|
|
50116
50165
|
if (!stored?.artifactDir) return [];
|
|
50117
|
-
const discPath =
|
|
50166
|
+
const discPath = path54.join(this.stateDir, stored.artifactDir, "discoveries.json");
|
|
50118
50167
|
return await readJsonFile(discPath) ?? [];
|
|
50119
50168
|
}
|
|
50120
50169
|
async materializeContext(id3, maxChars = DEFAULT_MATERIALIZE_CHARS) {
|
|
@@ -51367,10 +51416,10 @@ var init_mode = __esm({
|
|
|
51367
51416
|
|
|
51368
51417
|
// src/cli/headless.ts
|
|
51369
51418
|
import { readFileSync as readFileSync23 } from "node:fs";
|
|
51370
|
-
import
|
|
51419
|
+
import path55 from "node:path";
|
|
51371
51420
|
function resolveHeadlessCwd(opts) {
|
|
51372
51421
|
const raw = typeof opts.cwd === "string" ? opts.cwd.trim() : "";
|
|
51373
|
-
return
|
|
51422
|
+
return path55.resolve(raw.length > 0 ? raw : process.cwd());
|
|
51374
51423
|
}
|
|
51375
51424
|
function defaultProfileForMode(mode) {
|
|
51376
51425
|
switch (mode) {
|
|
@@ -51401,7 +51450,8 @@ function parseHeadlessFlags(argv) {
|
|
|
51401
51450
|
let profile;
|
|
51402
51451
|
let resumeSessionId;
|
|
51403
51452
|
let exportSessionPath;
|
|
51404
|
-
let strictDone
|
|
51453
|
+
let strictDone;
|
|
51454
|
+
let missionStrict;
|
|
51405
51455
|
let krakenGraph;
|
|
51406
51456
|
let planOnly = process.env.ZELARI_KRAKEN_PLAN_ONLY === "1" || process.env.ZELARI_KRAKEN_PLAN_ONLY === "true";
|
|
51407
51457
|
let runPlan = process.env.ZELARI_KRAKEN_RUN_PLAN;
|
|
@@ -51563,7 +51613,10 @@ function parseHeadlessFlags(argv) {
|
|
|
51563
51613
|
strictDone = true;
|
|
51564
51614
|
} else if (arg === "--no-strict-done") {
|
|
51565
51615
|
strictDone = false;
|
|
51566
|
-
|
|
51616
|
+
} else if (arg === "--mission-strict") {
|
|
51617
|
+
missionStrict = true;
|
|
51618
|
+
} else if (arg === "--no-mission-strict") {
|
|
51619
|
+
missionStrict = false;
|
|
51567
51620
|
} else if (arg === "--kraken-graph") {
|
|
51568
51621
|
krakenGraph = argv[i + 1];
|
|
51569
51622
|
i++;
|
|
@@ -51618,7 +51671,8 @@ function parseHeadlessFlags(argv) {
|
|
|
51618
51671
|
...profile ? { profile } : {},
|
|
51619
51672
|
...resumeSessionId ? { resumeSessionId } : {},
|
|
51620
51673
|
...exportSessionPath ? { exportSessionPath } : {},
|
|
51621
|
-
...strictDone ? { strictDone
|
|
51674
|
+
...strictDone !== void 0 ? { strictDone } : {},
|
|
51675
|
+
...missionStrict !== void 0 ? { missionStrict } : {},
|
|
51622
51676
|
...krakenGraph ? { krakenGraph } : {},
|
|
51623
51677
|
...planOnly ? { planOnly: true } : {},
|
|
51624
51678
|
...runPlan ? { runPlan } : {},
|
|
@@ -52305,7 +52359,7 @@ var init_claudeProvider = __esm({
|
|
|
52305
52359
|
// src/cli/memory/legacyImport.ts
|
|
52306
52360
|
import { createHash as createHash17 } from "node:crypto";
|
|
52307
52361
|
import { promises as fs23 } from "node:fs";
|
|
52308
|
-
import * as
|
|
52362
|
+
import * as path56 from "node:path";
|
|
52309
52363
|
function sourceId(fact, line) {
|
|
52310
52364
|
return `jsonl:${fact.id ?? createHash17("sha256").update(line).digest("hex")}`;
|
|
52311
52365
|
}
|
|
@@ -52323,7 +52377,7 @@ function timestamp(value) {
|
|
|
52323
52377
|
}
|
|
52324
52378
|
async function importLegacyMemoryLog(backend, service) {
|
|
52325
52379
|
const result = { found: 0, imported: 0, skipped: 0, corrupt: 0 };
|
|
52326
|
-
const logPath =
|
|
52380
|
+
const logPath = path56.join(path56.dirname(backend.databasePath), "log.jsonl");
|
|
52327
52381
|
let raw;
|
|
52328
52382
|
try {
|
|
52329
52383
|
raw = await fs23.readFile(logPath, "utf8");
|
|
@@ -52506,7 +52560,7 @@ var init_sqliteCodec = __esm({
|
|
|
52506
52560
|
// src/cli/memory/sqliteRpc.ts
|
|
52507
52561
|
import { existsSync as existsSync30 } from "node:fs";
|
|
52508
52562
|
import { fileURLToPath as fileURLToPath2, pathToFileURL as pathToFileURL2 } from "node:url";
|
|
52509
|
-
import * as
|
|
52563
|
+
import * as path57 from "node:path";
|
|
52510
52564
|
import { Worker } from "node:worker_threads";
|
|
52511
52565
|
function isBusy(error51) {
|
|
52512
52566
|
const candidate = error51;
|
|
@@ -52515,10 +52569,10 @@ function isBusy(error51) {
|
|
|
52515
52569
|
);
|
|
52516
52570
|
}
|
|
52517
52571
|
function resolveWorkerUrl() {
|
|
52518
|
-
const here =
|
|
52519
|
-
const direct =
|
|
52572
|
+
const here = path57.dirname(fileURLToPath2(import.meta.url));
|
|
52573
|
+
const direct = path57.join(here, "sqliteWorker.mjs");
|
|
52520
52574
|
if (existsSync30(direct)) return pathToFileURL2(direct);
|
|
52521
|
-
return pathToFileURL2(
|
|
52575
|
+
return pathToFileURL2(path57.join(here, "memory", "sqliteWorker.mjs"));
|
|
52522
52576
|
}
|
|
52523
52577
|
var SqliteWorkerRpc;
|
|
52524
52578
|
var init_sqliteRpc = __esm({
|
|
@@ -52807,7 +52861,7 @@ WHERE NOT EXISTS (SELECT 1 FROM memory_fts f WHERE f.node_id = n.id);
|
|
|
52807
52861
|
// src/cli/memory/sqliteBackend.ts
|
|
52808
52862
|
import { createHash as createHash18, randomUUID as randomUUID5 } from "node:crypto";
|
|
52809
52863
|
import { promises as fs24 } from "node:fs";
|
|
52810
|
-
import * as
|
|
52864
|
+
import * as path58 from "node:path";
|
|
52811
52865
|
function boundedLimit(value, fallback = 50) {
|
|
52812
52866
|
return Math.max(1, Math.min(Math.floor(value ?? fallback), 1e5));
|
|
52813
52867
|
}
|
|
@@ -52869,16 +52923,16 @@ VALUES (${Array.from({ length: 19 }, () => "?").join(",")})`;
|
|
|
52869
52923
|
try {
|
|
52870
52924
|
resolved = await fs24.realpath(projectRoot);
|
|
52871
52925
|
} catch {
|
|
52872
|
-
resolved =
|
|
52926
|
+
resolved = path58.resolve(projectRoot);
|
|
52873
52927
|
}
|
|
52874
52928
|
if (this.initialized && resolved === this.projectRoot) return;
|
|
52875
52929
|
if (this.initialized) await this.close();
|
|
52876
52930
|
const filename = this.options.filename ?? "memory.db";
|
|
52877
|
-
if (
|
|
52931
|
+
if (path58.basename(filename) !== filename || filename === "." || filename === "..") {
|
|
52878
52932
|
throw new Error("SQLite memory filename must not contain a path.");
|
|
52879
52933
|
}
|
|
52880
|
-
const zelariDirectory =
|
|
52881
|
-
const directory =
|
|
52934
|
+
const zelariDirectory = path58.join(resolved, ".zelari");
|
|
52935
|
+
const directory = path58.join(zelariDirectory, "memory");
|
|
52882
52936
|
for (const candidate of [zelariDirectory, directory]) {
|
|
52883
52937
|
let stat7;
|
|
52884
52938
|
try {
|
|
@@ -52897,12 +52951,12 @@ VALUES (${Array.from({ length: 19 }, () => "?").join(",")})`;
|
|
|
52897
52951
|
}
|
|
52898
52952
|
}
|
|
52899
52953
|
const canonicalDirectory = await fs24.realpath(directory);
|
|
52900
|
-
const relativeDirectory =
|
|
52901
|
-
if (relativeDirectory.startsWith("..") ||
|
|
52954
|
+
const relativeDirectory = path58.relative(resolved, canonicalDirectory);
|
|
52955
|
+
if (relativeDirectory.startsWith("..") || path58.isAbsolute(relativeDirectory)) {
|
|
52902
52956
|
throw new Error("SQLite memory directory resolves outside the active project.");
|
|
52903
52957
|
}
|
|
52904
52958
|
this.projectRoot = resolved;
|
|
52905
|
-
this.databasePath =
|
|
52959
|
+
this.databasePath = path58.join(canonicalDirectory, filename);
|
|
52906
52960
|
const opened = await this.rpc.open({
|
|
52907
52961
|
dbPath: this.databasePath,
|
|
52908
52962
|
schemaSql: SQLITE_MEMORY_BASE_SCHEMA,
|
|
@@ -53435,7 +53489,7 @@ __export(serviceFactory_exports, {
|
|
|
53435
53489
|
});
|
|
53436
53490
|
import { createHash as createHash19 } from "node:crypto";
|
|
53437
53491
|
import { promises as fs25 } from "node:fs";
|
|
53438
|
-
import * as
|
|
53492
|
+
import * as path59 from "node:path";
|
|
53439
53493
|
function isMemoryV2Enabled(env = process.env) {
|
|
53440
53494
|
if (env.ZELARI_MEMORY === "0") return false;
|
|
53441
53495
|
if (env.ZELARI_MEMORY_BACKEND === "file" || env.ZELARI_MEMORY_BACKEND === "jsonl") return false;
|
|
@@ -53456,7 +53510,7 @@ async function canonicalProjectId(projectRoot) {
|
|
|
53456
53510
|
try {
|
|
53457
53511
|
canonical = await fs25.realpath(projectRoot);
|
|
53458
53512
|
} catch {
|
|
53459
|
-
canonical =
|
|
53513
|
+
canonical = path59.resolve(projectRoot);
|
|
53460
53514
|
}
|
|
53461
53515
|
canonical = canonical.replace(/\\/g, "/").replace(/\/$/, "");
|
|
53462
53516
|
if (process.platform === "win32") canonical = canonical.toLocaleLowerCase("en-US");
|
|
@@ -54182,8 +54236,8 @@ function readPlan(ctx) {
|
|
|
54182
54236
|
} catch {
|
|
54183
54237
|
}
|
|
54184
54238
|
}
|
|
54185
|
-
const
|
|
54186
|
-
const doc = ctx.storage.readIfExists(
|
|
54239
|
+
const path90 = workspaceFile(ctx.rootDir, "plan");
|
|
54240
|
+
const doc = ctx.storage.readIfExists(path90);
|
|
54187
54241
|
if (!doc) return { phases: [], tasks: [], milestones: [] };
|
|
54188
54242
|
const meta3 = doc.meta;
|
|
54189
54243
|
return {
|
|
@@ -54361,7 +54415,7 @@ function addMilestoneRecord(ctx, summary, input) {
|
|
|
54361
54415
|
dueDate: input.dueDate,
|
|
54362
54416
|
targetVersion: version2
|
|
54363
54417
|
});
|
|
54364
|
-
const
|
|
54418
|
+
const path90 = join31(ctx.rootDir, "milestones", `${id3}.md`);
|
|
54365
54419
|
const meta3 = {
|
|
54366
54420
|
kind: "milestone",
|
|
54367
54421
|
id: id3,
|
|
@@ -54378,7 +54432,7 @@ function addMilestoneRecord(ctx, summary, input) {
|
|
|
54378
54432
|
`Target version: ${version2}`,
|
|
54379
54433
|
""
|
|
54380
54434
|
].join("\n");
|
|
54381
|
-
ctx.storage.write(
|
|
54435
|
+
ctx.storage.write(path90, meta3, body);
|
|
54382
54436
|
return { id: id3, created: true };
|
|
54383
54437
|
}
|
|
54384
54438
|
function readPlanSummary(ctx) {
|
|
@@ -54582,7 +54636,7 @@ function addIdeaStub(ctx) {
|
|
|
54582
54636
|
const tags = args["tags"] ?? [];
|
|
54583
54637
|
const category = args["category"] ?? "General";
|
|
54584
54638
|
const id3 = `${nextAdrId(ctx)}-${slugify3(title)}`;
|
|
54585
|
-
const
|
|
54639
|
+
const path90 = workspaceArtifact(ctx.rootDir, "decisions", id3);
|
|
54586
54640
|
const meta3 = {
|
|
54587
54641
|
kind: "adr",
|
|
54588
54642
|
status: "proposed",
|
|
@@ -54608,7 +54662,7 @@ function addIdeaStub(ctx) {
|
|
|
54608
54662
|
...consequences.map((c) => `- ${c}`),
|
|
54609
54663
|
""
|
|
54610
54664
|
].join("\n");
|
|
54611
|
-
ctx.storage.write(
|
|
54665
|
+
ctx.storage.write(path90, meta3, body);
|
|
54612
54666
|
return `ADR ${id3} created: "${title}". Status: proposed. Promote to accepted via /update ADR or manual edit.`;
|
|
54613
54667
|
});
|
|
54614
54668
|
}
|
|
@@ -54690,14 +54744,14 @@ function createDocumentStub(ctx) {
|
|
|
54690
54744
|
ctx.storage.write(risksPath, riskMeta, content);
|
|
54691
54745
|
return `Document "${title}" created at risks.md (workspace root).`;
|
|
54692
54746
|
}
|
|
54693
|
-
const
|
|
54747
|
+
const path90 = workspaceArtifact(ctx.rootDir, "docs", slug);
|
|
54694
54748
|
const meta3 = {
|
|
54695
54749
|
kind: "doc",
|
|
54696
54750
|
id: slug,
|
|
54697
54751
|
date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
|
|
54698
54752
|
tags
|
|
54699
54753
|
};
|
|
54700
|
-
ctx.storage.write(
|
|
54754
|
+
ctx.storage.write(path90, meta3, content);
|
|
54701
54755
|
return `Document "${title}" created at docs/${slug}.md.`;
|
|
54702
54756
|
});
|
|
54703
54757
|
}
|
|
@@ -55084,10 +55138,10 @@ function getUserMcpPath() {
|
|
|
55084
55138
|
function getProjectMcpPath(projectRoot) {
|
|
55085
55139
|
return join32(projectRoot, ".zelari", "mcp.json");
|
|
55086
55140
|
}
|
|
55087
|
-
function readFile6(
|
|
55088
|
-
if (!existsSync37(
|
|
55141
|
+
function readFile6(path90) {
|
|
55142
|
+
if (!existsSync37(path90)) return {};
|
|
55089
55143
|
try {
|
|
55090
|
-
const parsed = JSON.parse(readFileSync29(
|
|
55144
|
+
const parsed = JSON.parse(readFileSync29(path90, "utf8"));
|
|
55091
55145
|
const out = {};
|
|
55092
55146
|
for (const [name, cfg] of Object.entries(parsed.mcpServers ?? {})) {
|
|
55093
55147
|
if (!cfg || typeof cfg.command !== "string" || !cfg.command.trim()) continue;
|
|
@@ -55103,10 +55157,10 @@ function readFile6(path87) {
|
|
|
55103
55157
|
return {};
|
|
55104
55158
|
}
|
|
55105
55159
|
}
|
|
55106
|
-
function writeFile2(
|
|
55107
|
-
mkdirSync16(dirname9(
|
|
55160
|
+
function writeFile2(path90, servers) {
|
|
55161
|
+
mkdirSync16(dirname9(path90), { recursive: true });
|
|
55108
55162
|
const body = { mcpServers: servers };
|
|
55109
|
-
writeFileSync18(
|
|
55163
|
+
writeFileSync18(path90, `${JSON.stringify(body, null, 2)}
|
|
55110
55164
|
`, "utf8");
|
|
55111
55165
|
}
|
|
55112
55166
|
function listMcpServers(projectRoot) {
|
|
@@ -55139,9 +55193,9 @@ function upsertMcpServer(opts) {
|
|
|
55139
55193
|
if (!opts.config.command?.trim()) {
|
|
55140
55194
|
return { ok: false, error: "command is required" };
|
|
55141
55195
|
}
|
|
55142
|
-
let
|
|
55196
|
+
let path90;
|
|
55143
55197
|
if (opts.scope === "user") {
|
|
55144
|
-
|
|
55198
|
+
path90 = getUserMcpPath();
|
|
55145
55199
|
} else {
|
|
55146
55200
|
const root = opts.projectRoot?.trim();
|
|
55147
55201
|
if (!root) {
|
|
@@ -55150,30 +55204,30 @@ function upsertMcpServer(opts) {
|
|
|
55150
55204
|
error: "projectRoot required for project scope (Open Folder first)"
|
|
55151
55205
|
};
|
|
55152
55206
|
}
|
|
55153
|
-
|
|
55207
|
+
path90 = getProjectMcpPath(root);
|
|
55154
55208
|
}
|
|
55155
|
-
const current = readFile6(
|
|
55209
|
+
const current = readFile6(path90);
|
|
55156
55210
|
current[name] = {
|
|
55157
55211
|
command: opts.config.command.trim(),
|
|
55158
55212
|
args: opts.config.args,
|
|
55159
55213
|
env: opts.config.env,
|
|
55160
55214
|
enabled: opts.config.enabled !== false
|
|
55161
55215
|
};
|
|
55162
|
-
writeFile2(
|
|
55163
|
-
return { ok: true, path:
|
|
55216
|
+
writeFile2(path90, current);
|
|
55217
|
+
return { ok: true, path: path90 };
|
|
55164
55218
|
}
|
|
55165
55219
|
function removeMcpServer(opts) {
|
|
55166
|
-
const
|
|
55167
|
-
if (!
|
|
55220
|
+
const path90 = opts.scope === "user" ? getUserMcpPath() : opts.projectRoot ? getProjectMcpPath(opts.projectRoot) : null;
|
|
55221
|
+
if (!path90) {
|
|
55168
55222
|
return { ok: false, error: "projectRoot required for project scope" };
|
|
55169
55223
|
}
|
|
55170
|
-
const current = readFile6(
|
|
55224
|
+
const current = readFile6(path90);
|
|
55171
55225
|
if (!(opts.name in current)) {
|
|
55172
|
-
return { ok: false, error: `Server "${opts.name}" not found in ${
|
|
55226
|
+
return { ok: false, error: `Server "${opts.name}" not found in ${path90}` };
|
|
55173
55227
|
}
|
|
55174
55228
|
delete current[opts.name];
|
|
55175
|
-
writeFile2(
|
|
55176
|
-
return { ok: true, path:
|
|
55229
|
+
writeFile2(path90, current);
|
|
55230
|
+
return { ok: true, path: path90 };
|
|
55177
55231
|
}
|
|
55178
55232
|
var init_mcpConfigIo = __esm({
|
|
55179
55233
|
"src/cli/mcp/mcpConfigIo.ts"() {
|
|
@@ -55574,10 +55628,10 @@ import { createHash as createHash20 } from "node:crypto";
|
|
|
55574
55628
|
import { join as join34 } from "node:path";
|
|
55575
55629
|
import { readFile as readFile7 } from "node:fs/promises";
|
|
55576
55630
|
async function readPackageJson3(projectRoot) {
|
|
55577
|
-
const
|
|
55578
|
-
if (!existsSync39(
|
|
55631
|
+
const path90 = join34(projectRoot, "package.json");
|
|
55632
|
+
if (!existsSync39(path90)) return null;
|
|
55579
55633
|
try {
|
|
55580
|
-
return JSON.parse(await readFile7(
|
|
55634
|
+
return JSON.parse(await readFile7(path90, "utf8"));
|
|
55581
55635
|
} catch {
|
|
55582
55636
|
return null;
|
|
55583
55637
|
}
|
|
@@ -55659,9 +55713,9 @@ async function genBuild(ctx) {
|
|
|
55659
55713
|
].join("\n");
|
|
55660
55714
|
}
|
|
55661
55715
|
async function genOpenQuestions(ctx) {
|
|
55662
|
-
const
|
|
55663
|
-
if (!existsSync39(
|
|
55664
|
-
const content = readFileSync31(
|
|
55716
|
+
const path90 = join34(ctx.rootDir, "risks.md");
|
|
55717
|
+
if (!existsSync39(path90)) return "_No open questions._";
|
|
55718
|
+
const content = readFileSync31(path90, "utf8");
|
|
55665
55719
|
const lines = content.split("\n");
|
|
55666
55720
|
const questions = [];
|
|
55667
55721
|
let currentTitle = "";
|
|
@@ -55935,9 +55989,9 @@ function versionKey(value) {
|
|
|
55935
55989
|
function firstString2(v) {
|
|
55936
55990
|
return typeof v === "string" && v.trim().length > 0 ? v : null;
|
|
55937
55991
|
}
|
|
55938
|
-
function readFileSyncSafe(
|
|
55992
|
+
function readFileSyncSafe(path90) {
|
|
55939
55993
|
try {
|
|
55940
|
-
return readFileSync32(
|
|
55994
|
+
return readFileSync32(path90, "utf8");
|
|
55941
55995
|
} catch {
|
|
55942
55996
|
return null;
|
|
55943
55997
|
}
|
|
@@ -56400,8 +56454,8 @@ async function runPostCouncilHook(ctx, options) {
|
|
|
56400
56454
|
sources: scope.sources
|
|
56401
56455
|
} : void 0
|
|
56402
56456
|
});
|
|
56403
|
-
const
|
|
56404
|
-
completionHook = { ran: true, path:
|
|
56457
|
+
const path90 = writeCouncilCompletion(ctx.rootDir, completion);
|
|
56458
|
+
completionHook = { ran: true, path: path90, completion };
|
|
56405
56459
|
} catch (err) {
|
|
56406
56460
|
completionHook = {
|
|
56407
56461
|
ran: true,
|
|
@@ -56446,7 +56500,7 @@ import {
|
|
|
56446
56500
|
writeFileSync as writeFileSync21,
|
|
56447
56501
|
mkdirSync as mkdirSync17
|
|
56448
56502
|
} from "node:fs";
|
|
56449
|
-
import
|
|
56503
|
+
import path60 from "node:path";
|
|
56450
56504
|
import os10 from "node:os";
|
|
56451
56505
|
var FeedbackStore;
|
|
56452
56506
|
var init_councilFeedback = __esm({
|
|
@@ -56457,7 +56511,7 @@ var init_councilFeedback = __esm({
|
|
|
56457
56511
|
now;
|
|
56458
56512
|
entries = [];
|
|
56459
56513
|
constructor(options = {}) {
|
|
56460
|
-
this.file = options.file ?? (process.env.ANATHEMA_COUNCIL_FEEDBACK_FILE ??
|
|
56514
|
+
this.file = options.file ?? (process.env.ANATHEMA_COUNCIL_FEEDBACK_FILE ?? path60.join(os10.homedir(), ".tmp", "zelari-code", "council-feedback.json"));
|
|
56461
56515
|
this.now = options.now ?? Date.now;
|
|
56462
56516
|
this.load();
|
|
56463
56517
|
}
|
|
@@ -56563,7 +56617,7 @@ var init_councilFeedback = __esm({
|
|
|
56563
56617
|
}
|
|
56564
56618
|
}
|
|
56565
56619
|
save() {
|
|
56566
|
-
mkdirSync17(
|
|
56620
|
+
mkdirSync17(path60.dirname(this.file), { recursive: true });
|
|
56567
56621
|
writeFileSync21(
|
|
56568
56622
|
this.file,
|
|
56569
56623
|
JSON.stringify({ entries: this.entries }, null, 2),
|
|
@@ -56631,7 +56685,7 @@ import { execFile as execFile4 } from "node:child_process";
|
|
|
56631
56685
|
import { promisify as promisify3 } from "node:util";
|
|
56632
56686
|
import { mkdtempSync, rmSync as rmSync2 } from "node:fs";
|
|
56633
56687
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
56634
|
-
import
|
|
56688
|
+
import path61 from "node:path";
|
|
56635
56689
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
56636
56690
|
async function git4(cwd, args, env) {
|
|
56637
56691
|
const { stdout } = await execFileAsync3("git", ["-C", cwd, ...args], {
|
|
@@ -56651,8 +56705,8 @@ async function isGitRepo(cwd) {
|
|
|
56651
56705
|
return await gitSafe(cwd, ["rev-parse", "--is-inside-work-tree"]) === "true";
|
|
56652
56706
|
}
|
|
56653
56707
|
async function withTempIndex(fn) {
|
|
56654
|
-
const dir = mkdtempSync(
|
|
56655
|
-
const indexFile =
|
|
56708
|
+
const dir = mkdtempSync(path61.join(tmpdir3(), "zelari-ckpt-"));
|
|
56709
|
+
const indexFile = path61.join(dir, "index");
|
|
56656
56710
|
try {
|
|
56657
56711
|
return await fn(indexFile);
|
|
56658
56712
|
} finally {
|
|
@@ -56743,7 +56797,7 @@ async function restoreCheckpoint(cwd, id3) {
|
|
|
56743
56797
|
const deleted = [];
|
|
56744
56798
|
for (const rel2 of added) {
|
|
56745
56799
|
try {
|
|
56746
|
-
rmSync2(
|
|
56800
|
+
rmSync2(path61.join(cwd, rel2), { force: true });
|
|
56747
56801
|
deleted.push(rel2);
|
|
56748
56802
|
} catch {
|
|
56749
56803
|
}
|
|
@@ -56847,7 +56901,7 @@ __export(fileBackend_exports, {
|
|
|
56847
56901
|
});
|
|
56848
56902
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
56849
56903
|
import { promises as fs27 } from "node:fs";
|
|
56850
|
-
import * as
|
|
56904
|
+
import * as path62 from "node:path";
|
|
56851
56905
|
function tokenize2(text) {
|
|
56852
56906
|
return text.toLowerCase().split(/[^\p{L}\p{N}]+/u).filter((t) => t.length >= 3);
|
|
56853
56907
|
}
|
|
@@ -56861,10 +56915,12 @@ function matchesFilter(metadata2, filter) {
|
|
|
56861
56915
|
function isMemoryEnabled(env = process.env) {
|
|
56862
56916
|
return env.ZELARI_MEMORY !== "0";
|
|
56863
56917
|
}
|
|
56864
|
-
async function getMemoryBackend(projectRoot, env = process.env) {
|
|
56918
|
+
async function getMemoryBackend(projectRoot, env = process.env, onEvent) {
|
|
56865
56919
|
if (!isMemoryEnabled(env)) return new NoopMemoryBackend();
|
|
56866
56920
|
if (isMemoryV2Enabled(env)) {
|
|
56867
|
-
const service = await getMemoryService(projectRoot, env
|
|
56921
|
+
const service = await getMemoryService(projectRoot, env, {
|
|
56922
|
+
...onEvent ? { onEvent } : {}
|
|
56923
|
+
});
|
|
56868
56924
|
if (service instanceof NoopMemoryService) return new NoopMemoryBackend();
|
|
56869
56925
|
return new LegacyMemoryBackendAdapter(service);
|
|
56870
56926
|
}
|
|
@@ -56898,8 +56954,8 @@ var init_fileBackend = __esm({
|
|
|
56898
56954
|
logPath = "";
|
|
56899
56955
|
memoryDir = "";
|
|
56900
56956
|
async init(projectRoot) {
|
|
56901
|
-
this.memoryDir =
|
|
56902
|
-
this.logPath =
|
|
56957
|
+
this.memoryDir = path62.join(projectRoot, ".zelari", "memory");
|
|
56958
|
+
this.logPath = path62.join(this.memoryDir, "log.jsonl");
|
|
56903
56959
|
await fs27.mkdir(this.memoryDir, { recursive: true });
|
|
56904
56960
|
}
|
|
56905
56961
|
async add(content, metadata2 = {}, graph) {
|
|
@@ -56972,12 +57028,12 @@ var init_fileBackend = __esm({
|
|
|
56972
57028
|
|
|
56973
57029
|
// src/cli/traceStore.ts
|
|
56974
57030
|
import { promises as fs28 } from "node:fs";
|
|
56975
|
-
import * as
|
|
57031
|
+
import * as path63 from "node:path";
|
|
56976
57032
|
function traceDir(projectRoot) {
|
|
56977
|
-
return
|
|
57033
|
+
return path63.join(projectRoot, ".zelari", "trace");
|
|
56978
57034
|
}
|
|
56979
57035
|
function tracePath(projectRoot, missionId) {
|
|
56980
|
-
return
|
|
57036
|
+
return path63.join(traceDir(projectRoot), `${missionId}.json`);
|
|
56981
57037
|
}
|
|
56982
57038
|
async function saveTrace(projectRoot, missionId, entries) {
|
|
56983
57039
|
const dir = traceDir(projectRoot);
|
|
@@ -57014,7 +57070,7 @@ __export(zelariMission_exports, {
|
|
|
57014
57070
|
});
|
|
57015
57071
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
57016
57072
|
import { promises as fs29 } from "node:fs";
|
|
57017
|
-
import * as
|
|
57073
|
+
import * as path64 from "node:path";
|
|
57018
57074
|
function resolveMaxIterations(env = process.env) {
|
|
57019
57075
|
const raw = env.ZELARI_MISSION_MAX_ITER;
|
|
57020
57076
|
const n = raw ? Number.parseInt(raw, 10) : DEFAULT_MAX_ITER;
|
|
@@ -57057,10 +57113,10 @@ function isMissionAutoStart(env = process.env) {
|
|
|
57057
57113
|
return env.ZELARI_MISSION_AUTO === "1";
|
|
57058
57114
|
}
|
|
57059
57115
|
async function writeMissionState(projectRoot, state3) {
|
|
57060
|
-
const dir =
|
|
57116
|
+
const dir = path64.join(projectRoot, ".zelari");
|
|
57061
57117
|
await fs29.mkdir(dir, { recursive: true });
|
|
57062
57118
|
await fs29.writeFile(
|
|
57063
|
-
|
|
57119
|
+
path64.join(dir, "mission-state.json"),
|
|
57064
57120
|
JSON.stringify(state3, null, 2) + "\n",
|
|
57065
57121
|
"utf8"
|
|
57066
57122
|
);
|
|
@@ -57735,7 +57791,7 @@ function safeSocketPath(socketPath) {
|
|
|
57735
57791
|
return socketPath.trim();
|
|
57736
57792
|
}
|
|
57737
57793
|
function startPermissionBroker(socketPath, handlers, opts) {
|
|
57738
|
-
const
|
|
57794
|
+
const path90 = safeSocketPath(socketPath);
|
|
57739
57795
|
const requestTimeoutMs = opts?.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
|
|
57740
57796
|
const sockets = /* @__PURE__ */ new Set();
|
|
57741
57797
|
const server = createServer2((socket) => {
|
|
@@ -57835,10 +57891,10 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
57835
57891
|
return new Promise((resolve9, reject) => {
|
|
57836
57892
|
const onError = (err) => reject(err);
|
|
57837
57893
|
server.once("error", onError);
|
|
57838
|
-
server.listen(
|
|
57894
|
+
server.listen(path90, () => {
|
|
57839
57895
|
server.removeListener("error", onError);
|
|
57840
57896
|
resolve9({
|
|
57841
|
-
socketPath:
|
|
57897
|
+
socketPath: path90,
|
|
57842
57898
|
stop: () => new Promise((res) => {
|
|
57843
57899
|
for (const s of sockets) s.destroy();
|
|
57844
57900
|
sockets.clear();
|
|
@@ -57849,7 +57905,7 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
57849
57905
|
if (done) return;
|
|
57850
57906
|
done = true;
|
|
57851
57907
|
if (process.platform !== "win32") {
|
|
57852
|
-
unlink(
|
|
57908
|
+
unlink(path90, () => res());
|
|
57853
57909
|
} else {
|
|
57854
57910
|
res();
|
|
57855
57911
|
}
|
|
@@ -57862,11 +57918,11 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
57862
57918
|
});
|
|
57863
57919
|
}
|
|
57864
57920
|
function requestBrokerAsk(socketPath, ask, opts) {
|
|
57865
|
-
const
|
|
57921
|
+
const path90 = safeSocketPath(socketPath);
|
|
57866
57922
|
const requestTimeoutMs = opts?.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
|
|
57867
57923
|
const connectTimeoutMs = opts?.connectTimeoutMs ?? PERMISSION_BROKER_DEFAULT_CONNECT_TIMEOUT_MS;
|
|
57868
57924
|
return new Promise((resolve9, reject) => {
|
|
57869
|
-
const socket = connect(
|
|
57925
|
+
const socket = connect(path90);
|
|
57870
57926
|
let buffer = "";
|
|
57871
57927
|
let settled = false;
|
|
57872
57928
|
const settle = (fn) => {
|
|
@@ -57881,7 +57937,7 @@ function requestBrokerAsk(socketPath, ask, opts) {
|
|
|
57881
57937
|
settle(
|
|
57882
57938
|
() => reject(
|
|
57883
57939
|
new Error(
|
|
57884
|
-
`permission broker unavailable at "${
|
|
57940
|
+
`permission broker unavailable at "${path90}" (connect timed out after ${connectTimeoutMs}ms)`
|
|
57885
57941
|
)
|
|
57886
57942
|
)
|
|
57887
57943
|
);
|
|
@@ -58021,7 +58077,7 @@ var init_brokerHandlers = __esm({
|
|
|
58021
58077
|
// src/cli/gitOps.ts
|
|
58022
58078
|
import { execFile as execFile5 } from "node:child_process";
|
|
58023
58079
|
import { promisify as promisify4 } from "node:util";
|
|
58024
|
-
import
|
|
58080
|
+
import path65 from "node:path";
|
|
58025
58081
|
async function git5(cwd, args) {
|
|
58026
58082
|
try {
|
|
58027
58083
|
const { stdout } = await execFileAsync4("git", ["-C", cwd, ...args], {
|
|
@@ -58066,7 +58122,7 @@ async function undoWorkingChanges(opts = {}) {
|
|
|
58066
58122
|
};
|
|
58067
58123
|
}
|
|
58068
58124
|
function defaultProjectRoot() {
|
|
58069
|
-
return
|
|
58125
|
+
return path65.resolve(__dirname, "..", "..", "..");
|
|
58070
58126
|
}
|
|
58071
58127
|
var execFileAsync4;
|
|
58072
58128
|
var init_gitOps = __esm({
|
|
@@ -58684,9 +58740,9 @@ __export(graphMemory_exports, {
|
|
|
58684
58740
|
toGraphSnapshot: () => toGraphSnapshot
|
|
58685
58741
|
});
|
|
58686
58742
|
import { promises as fs32 } from "node:fs";
|
|
58687
|
-
import
|
|
58743
|
+
import path68 from "node:path";
|
|
58688
58744
|
function snapshotPath(cwd) {
|
|
58689
|
-
return
|
|
58745
|
+
return path68.join(cwd, SNAPSHOT_DIR, SNAPSHOT_FILE);
|
|
58690
58746
|
}
|
|
58691
58747
|
function toGraphSnapshot(graph, opts) {
|
|
58692
58748
|
const unresolved = (opts.unresolvedFindings ?? []).map((u) => ({
|
|
@@ -58713,7 +58769,7 @@ async function saveGraphSnapshot(cwd, snapshot) {
|
|
|
58713
58769
|
try {
|
|
58714
58770
|
await fs32.access(cwd);
|
|
58715
58771
|
const file2 = snapshotPath(cwd);
|
|
58716
|
-
await fs32.mkdir(
|
|
58772
|
+
await fs32.mkdir(path68.dirname(file2), { recursive: true });
|
|
58717
58773
|
await fs32.writeFile(file2, JSON.stringify(snapshot, null, 2) + "\n", "utf8");
|
|
58718
58774
|
} catch {
|
|
58719
58775
|
}
|
|
@@ -58780,7 +58836,7 @@ var SNAPSHOT_DIR, SNAPSHOT_FILE, MAX_SNAPSHOT_FINDINGS_CHARS;
|
|
|
58780
58836
|
var init_graphMemory = __esm({
|
|
58781
58837
|
"src/cli/kraken/graphMemory.ts"() {
|
|
58782
58838
|
"use strict";
|
|
58783
|
-
SNAPSHOT_DIR =
|
|
58839
|
+
SNAPSHOT_DIR = path68.join(".zelari", "kraken");
|
|
58784
58840
|
SNAPSHOT_FILE = "last-graph.json";
|
|
58785
58841
|
MAX_SNAPSHOT_FINDINGS_CHARS = 400;
|
|
58786
58842
|
}
|
|
@@ -58852,14 +58908,14 @@ var init_transactional = __esm({
|
|
|
58852
58908
|
|
|
58853
58909
|
// src/cli/kraken/workbench.ts
|
|
58854
58910
|
import { promises as fs33 } from "node:fs";
|
|
58855
|
-
import
|
|
58911
|
+
import path69 from "node:path";
|
|
58856
58912
|
function isWorkbenchEnabled(env = process.env) {
|
|
58857
58913
|
const v = (env.ZELARI_KRAKEN_WORKBENCH ?? "1").trim().toLowerCase();
|
|
58858
58914
|
if (v === "0" || v === "false" || v === "no" || v === "off") return false;
|
|
58859
58915
|
return true;
|
|
58860
58916
|
}
|
|
58861
58917
|
function workbenchPath(cwd, graphId) {
|
|
58862
|
-
return
|
|
58918
|
+
return path69.join(cwd, ".zelari", "radio", `workbench-${graphId}.md`);
|
|
58863
58919
|
}
|
|
58864
58920
|
function countByStatus2(nodes) {
|
|
58865
58921
|
const out = { pending: 0, running: 0, done: 0, error: 0, skipped: 0 };
|
|
@@ -59022,7 +59078,7 @@ var init_workbench = __esm({
|
|
|
59022
59078
|
if (!this.enabled) return null;
|
|
59023
59079
|
if (!this.dirty && this.lastWrite) return this.lastWrite;
|
|
59024
59080
|
const out = workbenchPath(this.cwd, this.graphId);
|
|
59025
|
-
await fs33.mkdir(
|
|
59081
|
+
await fs33.mkdir(path69.dirname(out), { recursive: true });
|
|
59026
59082
|
const body = this.render();
|
|
59027
59083
|
const tmp = `${out}.${process.pid}.${Date.now()}.tmp`;
|
|
59028
59084
|
await fs33.writeFile(tmp, body, "utf8");
|
|
@@ -59395,14 +59451,14 @@ var init_spawnRoi = __esm({
|
|
|
59395
59451
|
|
|
59396
59452
|
// src/cli/kraken/reputationStore.ts
|
|
59397
59453
|
import { appendFile as appendFile2, mkdir as mkdir3, readFile as readFile8, rename as rename2, writeFile as writeFile3 } from "node:fs/promises";
|
|
59398
|
-
import
|
|
59454
|
+
import path70 from "node:path";
|
|
59399
59455
|
function resolveReputationStorePath(cwd = process.cwd(), env = process.env) {
|
|
59400
59456
|
const override = env[REPUTATION_STORE_ENV]?.trim();
|
|
59401
59457
|
if (override) return override;
|
|
59402
|
-
return
|
|
59458
|
+
return path70.join(cwd, ".zelari", "reputation.jsonl");
|
|
59403
59459
|
}
|
|
59404
59460
|
async function appendRecord(storePath, record2) {
|
|
59405
|
-
await mkdir3(
|
|
59461
|
+
await mkdir3(path70.dirname(storePath), { recursive: true });
|
|
59406
59462
|
await appendFile2(storePath, `${JSON.stringify(record2)}
|
|
59407
59463
|
`, "utf8");
|
|
59408
59464
|
}
|
|
@@ -59802,7 +59858,7 @@ __export(executor_exports, {
|
|
|
59802
59858
|
thoroughnessForKind: () => thoroughnessForKind
|
|
59803
59859
|
});
|
|
59804
59860
|
import { existsSync as existsSync44 } from "node:fs";
|
|
59805
|
-
import
|
|
59861
|
+
import path71 from "node:path";
|
|
59806
59862
|
async function defaultSymbolExtractor(file2) {
|
|
59807
59863
|
if (!isAstSupported(file2)) return null;
|
|
59808
59864
|
const r = await parseFileSymbolsDiag(file2);
|
|
@@ -59868,7 +59924,7 @@ function isWorldModelGateEnabled(cwd, env = process.env, checksExists = defaultC
|
|
|
59868
59924
|
}
|
|
59869
59925
|
function defaultChecksExists(cwd) {
|
|
59870
59926
|
try {
|
|
59871
|
-
return existsSync44(
|
|
59927
|
+
return existsSync44(path71.join(cwd, ".zelari", "world", "checks.json"));
|
|
59872
59928
|
} catch {
|
|
59873
59929
|
return false;
|
|
59874
59930
|
}
|
|
@@ -60376,7 +60432,7 @@ var init_executor = __esm({
|
|
|
60376
60432
|
try {
|
|
60377
60433
|
const summary = aggregate(
|
|
60378
60434
|
records,
|
|
60379
|
-
{ repo:
|
|
60435
|
+
{ repo: path71.basename(this.parentCwd), role: agentForNode(node) },
|
|
60380
60436
|
now
|
|
60381
60437
|
);
|
|
60382
60438
|
sample = summary.sample;
|
|
@@ -60853,7 +60909,7 @@ ${upstream}` : node.prompt,
|
|
|
60853
60909
|
const model = res.ok && res.model && res.model !== "n/a" ? res.model : null;
|
|
60854
60910
|
const reviewerVerdict = res.ok && this.isReviewerKind(node.kind) && typeof node.result === "string" && node.result.length > 0 ? parseVerifyVerdict(node.result).verdict : null;
|
|
60855
60911
|
const record2 = reputationRecordFromNodeRun({
|
|
60856
|
-
repo:
|
|
60912
|
+
repo: path71.basename(this.parentCwd),
|
|
60857
60913
|
role: agentForNode(node),
|
|
60858
60914
|
kind: node.kind,
|
|
60859
60915
|
ok: res.ok,
|
|
@@ -61624,10 +61680,10 @@ var init_prereqChecks = __esm({
|
|
|
61624
61680
|
|
|
61625
61681
|
// src/cli/plugins/prefs.ts
|
|
61626
61682
|
import { existsSync as existsSync46, readFileSync as readFileSync36, writeFileSync as writeFileSync22, mkdirSync as mkdirSync18 } from "node:fs";
|
|
61627
|
-
import
|
|
61683
|
+
import path74 from "node:path";
|
|
61628
61684
|
import os11 from "node:os";
|
|
61629
61685
|
function getPluginPrefsPath() {
|
|
61630
|
-
return process.env.ZELARI_PLUGINS_PREFS_FILE ??
|
|
61686
|
+
return process.env.ZELARI_PLUGINS_PREFS_FILE ?? path74.join(os11.homedir(), ".tmp", "zelari-code", "plugins.json");
|
|
61631
61687
|
}
|
|
61632
61688
|
function getPluginPrefs() {
|
|
61633
61689
|
const file2 = getPluginPrefsPath();
|
|
@@ -61648,7 +61704,7 @@ function getPluginPrefs() {
|
|
|
61648
61704
|
}
|
|
61649
61705
|
function writePluginPrefs(prefs) {
|
|
61650
61706
|
const file2 = getPluginPrefsPath();
|
|
61651
|
-
mkdirSync18(
|
|
61707
|
+
mkdirSync18(path74.dirname(file2), { recursive: true });
|
|
61652
61708
|
writeFileSync22(file2, JSON.stringify(prefs, null, 2), {
|
|
61653
61709
|
encoding: "utf-8",
|
|
61654
61710
|
mode: 384
|
|
@@ -61685,7 +61741,7 @@ __export(registry_exports, {
|
|
|
61685
61741
|
isBinaryOnPath: () => isBinaryOnPath
|
|
61686
61742
|
});
|
|
61687
61743
|
import { existsSync as existsSync47 } from "node:fs";
|
|
61688
|
-
import
|
|
61744
|
+
import path75 from "node:path";
|
|
61689
61745
|
function detectLocalBin(bin) {
|
|
61690
61746
|
return (cwd) => {
|
|
61691
61747
|
try {
|
|
@@ -61703,7 +61759,7 @@ function isBinaryOnPath(bin, opts = {}) {
|
|
|
61703
61759
|
const platform = opts.platform ?? process.platform;
|
|
61704
61760
|
const exists = opts.exists ?? existsSync47;
|
|
61705
61761
|
const pathEnv = opts.pathEnv ?? process.env.PATH ?? "";
|
|
61706
|
-
const pathMod = platform === "win32" ?
|
|
61762
|
+
const pathMod = platform === "win32" ? path75.win32 : path75.posix;
|
|
61707
61763
|
const sep4 = platform === "win32" ? ";" : ":";
|
|
61708
61764
|
const dirs = pathEnv.split(sep4).filter((d) => d.length > 0);
|
|
61709
61765
|
const candidates = [bin];
|
|
@@ -62798,7 +62854,7 @@ var init_policy = __esm({
|
|
|
62798
62854
|
|
|
62799
62855
|
// src/cli/orchestration/facts.ts
|
|
62800
62856
|
import { promises as fs41 } from "node:fs";
|
|
62801
|
-
import
|
|
62857
|
+
import path80 from "node:path";
|
|
62802
62858
|
async function collectRepoFileCount(root = process.cwd()) {
|
|
62803
62859
|
try {
|
|
62804
62860
|
await fs41.readdir(root);
|
|
@@ -62818,7 +62874,7 @@ async function collectRepoFileCount(root = process.cwd()) {
|
|
|
62818
62874
|
}
|
|
62819
62875
|
for (const e of entries) {
|
|
62820
62876
|
if (e.isDirectory()) {
|
|
62821
|
-
if (!SKIP_DIRS.has(e.name)) queue.push(
|
|
62877
|
+
if (!SKIP_DIRS.has(e.name)) queue.push(path80.join(dir, e.name));
|
|
62822
62878
|
} else if (e.isFile()) {
|
|
62823
62879
|
count++;
|
|
62824
62880
|
if (count > MAX_WALK_FILES) return count;
|
|
@@ -62914,6 +62970,206 @@ var init_streamScrub = __esm({
|
|
|
62914
62970
|
}
|
|
62915
62971
|
});
|
|
62916
62972
|
|
|
62973
|
+
// src/cli/harnessState.ts
|
|
62974
|
+
import path81 from "node:path";
|
|
62975
|
+
function asString3(v) {
|
|
62976
|
+
return typeof v === "string" ? v : "";
|
|
62977
|
+
}
|
|
62978
|
+
function asNumber2(v) {
|
|
62979
|
+
return typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
62980
|
+
}
|
|
62981
|
+
function asCallId(v, seq) {
|
|
62982
|
+
return typeof v === "string" && v.length > 0 ? v : `seq:${seq}`;
|
|
62983
|
+
}
|
|
62984
|
+
function newTurn(index, userText) {
|
|
62985
|
+
return {
|
|
62986
|
+
index,
|
|
62987
|
+
userText: userText.length > 0 ? userText : void 0,
|
|
62988
|
+
toolCalls: 0,
|
|
62989
|
+
toolKinds: [],
|
|
62990
|
+
outcome: "pending",
|
|
62991
|
+
unsettledCallIds: /* @__PURE__ */ new Set(),
|
|
62992
|
+
settledCallIds: /* @__PURE__ */ new Set(),
|
|
62993
|
+
interrupted: 0,
|
|
62994
|
+
assistantMessages: 0
|
|
62995
|
+
};
|
|
62996
|
+
}
|
|
62997
|
+
function deriveHarnessState(events) {
|
|
62998
|
+
const session = {
|
|
62999
|
+
sessionId: events[events.length - 1]?.sessionId ?? "",
|
|
63000
|
+
status: "pending",
|
|
63001
|
+
lastSeq: 0
|
|
63002
|
+
};
|
|
63003
|
+
const support = { contextProjections: [], memoryEvents: 0, compactions: 0 };
|
|
63004
|
+
let tokensSaved;
|
|
63005
|
+
const acc = [];
|
|
63006
|
+
let current = null;
|
|
63007
|
+
for (const e of events) {
|
|
63008
|
+
session.lastSeq = e.seq;
|
|
63009
|
+
switch (e.kind) {
|
|
63010
|
+
case "session.started":
|
|
63011
|
+
session.startedAt ??= e.ts;
|
|
63012
|
+
break;
|
|
63013
|
+
case "session.ended": {
|
|
63014
|
+
session.endedAt = e.ts;
|
|
63015
|
+
const reason = asString3(e.data.reason);
|
|
63016
|
+
session.status = reason.length > 0 ? reason : "ended";
|
|
63017
|
+
if (current) {
|
|
63018
|
+
current.closedBy = "session-ended";
|
|
63019
|
+
current.endReason = reason;
|
|
63020
|
+
current = null;
|
|
63021
|
+
}
|
|
63022
|
+
break;
|
|
63023
|
+
}
|
|
63024
|
+
case "user.message": {
|
|
63025
|
+
if (current) current.closedBy = "next-turn";
|
|
63026
|
+
current = newTurn(acc.length + 1, asString3(e.data.text));
|
|
63027
|
+
acc.push(current);
|
|
63028
|
+
break;
|
|
63029
|
+
}
|
|
63030
|
+
case "assistant.message": {
|
|
63031
|
+
if (!current) break;
|
|
63032
|
+
current.assistantMessages += 1;
|
|
63033
|
+
const text = asString3(e.data.text);
|
|
63034
|
+
current.assistantChars = (current.assistantChars ?? 0) + text.length;
|
|
63035
|
+
current.assistantText = text;
|
|
63036
|
+
break;
|
|
63037
|
+
}
|
|
63038
|
+
case "tool.call": {
|
|
63039
|
+
if (!current) break;
|
|
63040
|
+
current.toolCalls += 1;
|
|
63041
|
+
const tool = asString3(e.data.tool);
|
|
63042
|
+
if (tool.length > 0 && !current.toolKinds.includes(tool)) current.toolKinds.push(tool);
|
|
63043
|
+
current.unsettledCallIds.add(asCallId(e.data.callId, e.seq));
|
|
63044
|
+
break;
|
|
63045
|
+
}
|
|
63046
|
+
case "tool.result": {
|
|
63047
|
+
if (!current) break;
|
|
63048
|
+
current.settledCallIds.add(asCallId(e.data.callId, e.seq));
|
|
63049
|
+
break;
|
|
63050
|
+
}
|
|
63051
|
+
case "tool.interrupted": {
|
|
63052
|
+
if (current) current.interrupted += 1;
|
|
63053
|
+
break;
|
|
63054
|
+
}
|
|
63055
|
+
case "verification.run": {
|
|
63056
|
+
if (!current) break;
|
|
63057
|
+
current.verification = {
|
|
63058
|
+
strict: e.data.strict === true,
|
|
63059
|
+
verdict: asString3(e.data.verdict) || "unknown"
|
|
63060
|
+
};
|
|
63061
|
+
break;
|
|
63062
|
+
}
|
|
63063
|
+
case "session.compacted": {
|
|
63064
|
+
support.compactions += 1;
|
|
63065
|
+
const saved = asNumber2(e.data.tokensSaved);
|
|
63066
|
+
if (saved !== void 0) tokensSaved = (tokensSaved ?? 0) + saved;
|
|
63067
|
+
break;
|
|
63068
|
+
}
|
|
63069
|
+
case "note": {
|
|
63070
|
+
const subject = asString3(e.data.subject);
|
|
63071
|
+
if (subject === "context.projection") {
|
|
63072
|
+
support.contextProjections.push({
|
|
63073
|
+
contextChars: asNumber2(e.data.contextChars) ?? 0,
|
|
63074
|
+
returnedCount: asNumber2(e.data.returnedCount) ?? 0
|
|
63075
|
+
});
|
|
63076
|
+
} else if (subject === "memory_event") {
|
|
63077
|
+
support.memoryEvents += 1;
|
|
63078
|
+
}
|
|
63079
|
+
break;
|
|
63080
|
+
}
|
|
63081
|
+
default:
|
|
63082
|
+
break;
|
|
63083
|
+
}
|
|
63084
|
+
}
|
|
63085
|
+
const turns = acc.map((t) => finalizeTurn(t));
|
|
63086
|
+
return {
|
|
63087
|
+
session,
|
|
63088
|
+
turns,
|
|
63089
|
+
execution: { turnsTotal: turns.length, contracts: acc.map((t) => contractFor(t)) },
|
|
63090
|
+
support: tokensSaved === void 0 ? support : { ...support, tokensSavedByCompaction: tokensSaved }
|
|
63091
|
+
};
|
|
63092
|
+
}
|
|
63093
|
+
function finalizeTurn(t) {
|
|
63094
|
+
let outcome;
|
|
63095
|
+
if (t.closedBy === void 0) outcome = "pending";
|
|
63096
|
+
else if (t.closedBy === "session-ended" && t.endReason !== "completed") outcome = "error";
|
|
63097
|
+
else outcome = "completed";
|
|
63098
|
+
return {
|
|
63099
|
+
index: t.index,
|
|
63100
|
+
userText: t.userText,
|
|
63101
|
+
assistantChars: t.assistantMessages > 0 ? t.assistantChars ?? 0 : void 0,
|
|
63102
|
+
assistantText: t.assistantMessages > 0 ? t.assistantText : void 0,
|
|
63103
|
+
toolCalls: t.toolCalls,
|
|
63104
|
+
toolKinds: t.toolKinds,
|
|
63105
|
+
verification: t.verification,
|
|
63106
|
+
outcome
|
|
63107
|
+
};
|
|
63108
|
+
}
|
|
63109
|
+
function contractFor(t) {
|
|
63110
|
+
const userMessage = true;
|
|
63111
|
+
const assistantReply = t.assistantMessages > 0;
|
|
63112
|
+
const allSettled = [...t.unsettledCallIds].every((id3) => t.settledCallIds.has(id3));
|
|
63113
|
+
const toolsSettled = allSettled && t.interrupted === 0;
|
|
63114
|
+
const blockers = [];
|
|
63115
|
+
if (!assistantReply) blockers.push("assistant-reply-missing");
|
|
63116
|
+
if (!toolsSettled) blockers.push("tools-unsettled");
|
|
63117
|
+
if (t.verification) {
|
|
63118
|
+
if (!t.verification.strict) blockers.push("verification-not-strict");
|
|
63119
|
+
else if (t.verification.verdict !== "PASS") blockers.push(`verification-verdict-${t.verification.verdict}`);
|
|
63120
|
+
} else if (t.closedBy === void 0) {
|
|
63121
|
+
blockers.push("turn-pending");
|
|
63122
|
+
} else if (t.closedBy === "session-ended" && t.endReason !== "completed") {
|
|
63123
|
+
blockers.push(`turn-error-${t.endReason}`);
|
|
63124
|
+
}
|
|
63125
|
+
return {
|
|
63126
|
+
turn: t.index,
|
|
63127
|
+
complete: userMessage && assistantReply && toolsSettled && blockers.length === 0,
|
|
63128
|
+
signals: {
|
|
63129
|
+
userMessage,
|
|
63130
|
+
assistantReply,
|
|
63131
|
+
toolsSettled,
|
|
63132
|
+
verification: t.verification
|
|
63133
|
+
},
|
|
63134
|
+
blockers
|
|
63135
|
+
};
|
|
63136
|
+
}
|
|
63137
|
+
async function readHarnessState(sessionDir) {
|
|
63138
|
+
const report = await readSessionLog(path81.join(sessionDir, "events.jsonl"));
|
|
63139
|
+
return deriveHarnessState(report.events);
|
|
63140
|
+
}
|
|
63141
|
+
var init_harnessState = __esm({
|
|
63142
|
+
"src/cli/harnessState.ts"() {
|
|
63143
|
+
"use strict";
|
|
63144
|
+
init_session();
|
|
63145
|
+
}
|
|
63146
|
+
});
|
|
63147
|
+
|
|
63148
|
+
// src/cli/headless/harnessStateEmit.ts
|
|
63149
|
+
import path82 from "node:path";
|
|
63150
|
+
async function emitHarnessStateEvent(opts) {
|
|
63151
|
+
if (opts.output !== "json") return;
|
|
63152
|
+
try {
|
|
63153
|
+
const sessionsDir = resolveSessionsDir({ workspaceRoot: opts.workspaceRoot });
|
|
63154
|
+
const state3 = await readHarnessState(path82.join(sessionsDir, opts.spine.sessionId));
|
|
63155
|
+
opts.emitEvent({ type: "harness_state", ...state3 });
|
|
63156
|
+
} catch (err) {
|
|
63157
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
63158
|
+
try {
|
|
63159
|
+
process.stderr.write(`[zelari-code --headless] harness_state unavailable: ${msg}
|
|
63160
|
+
`);
|
|
63161
|
+
} catch {
|
|
63162
|
+
}
|
|
63163
|
+
}
|
|
63164
|
+
}
|
|
63165
|
+
var init_harnessStateEmit = __esm({
|
|
63166
|
+
"src/cli/headless/harnessStateEmit.ts"() {
|
|
63167
|
+
"use strict";
|
|
63168
|
+
init_session();
|
|
63169
|
+
init_harnessState();
|
|
63170
|
+
}
|
|
63171
|
+
});
|
|
63172
|
+
|
|
62917
63173
|
// src/cli/headless/policyGate.ts
|
|
62918
63174
|
import { isAbsolute as isAbsolute5, resolve as resolve7 } from "node:path";
|
|
62919
63175
|
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
@@ -62959,7 +63215,7 @@ async function recordPolicyLoadBlockedOnSpine(block, opts = {}) {
|
|
|
62959
63215
|
sessionId: sessionId2,
|
|
62960
63216
|
...opts.mode ? { mode: opts.mode } : {},
|
|
62961
63217
|
...opts.profile ? { profile: opts.profile } : {},
|
|
62962
|
-
workspace: process.cwd()
|
|
63218
|
+
workspace: opts.workspace ?? process.cwd()
|
|
62963
63219
|
});
|
|
62964
63220
|
if (opts.mode === "zelari") {
|
|
62965
63221
|
spine.missionPhase("dispatch", block.reason);
|
|
@@ -63390,13 +63646,13 @@ var init_sessionControl = __esm({
|
|
|
63390
63646
|
|
|
63391
63647
|
// src/cli/extensions/sandboxedFs.ts
|
|
63392
63648
|
import { promises as fsp } from "node:fs";
|
|
63393
|
-
import
|
|
63649
|
+
import path83 from "node:path";
|
|
63394
63650
|
function errText(prefix, p3, err) {
|
|
63395
63651
|
const msg = err instanceof Error ? err.message : String(err);
|
|
63396
63652
|
return `[extension-fs] ${prefix} "${p3}": ${msg}`;
|
|
63397
63653
|
}
|
|
63398
63654
|
function bindSandboxedFs(root) {
|
|
63399
|
-
const resolvedRoot =
|
|
63655
|
+
const resolvedRoot = path83.resolve(root);
|
|
63400
63656
|
return {
|
|
63401
63657
|
root: resolvedRoot,
|
|
63402
63658
|
async readFile(relativePath) {
|
|
@@ -63412,7 +63668,7 @@ function bindSandboxedFs(root) {
|
|
|
63412
63668
|
try {
|
|
63413
63669
|
const target = resolveSandboxedPath(relativePath, { root: resolvedRoot });
|
|
63414
63670
|
verifyContainment(target, { root: resolvedRoot });
|
|
63415
|
-
await fsp.mkdir(
|
|
63671
|
+
await fsp.mkdir(path83.dirname(target), { recursive: true });
|
|
63416
63672
|
await fsp.writeFile(target, data, "utf8");
|
|
63417
63673
|
return typedOk({ path: target });
|
|
63418
63674
|
} catch (err) {
|
|
@@ -63597,7 +63853,7 @@ var init_loader = __esm({
|
|
|
63597
63853
|
|
|
63598
63854
|
// src/cli/headless/runOneTurn.ts
|
|
63599
63855
|
import { promises as fs42 } from "node:fs";
|
|
63600
|
-
import
|
|
63856
|
+
import path84 from "node:path";
|
|
63601
63857
|
function planModeFromOpts(opts) {
|
|
63602
63858
|
return (opts.phase ?? "build") === "plan";
|
|
63603
63859
|
}
|
|
@@ -63651,11 +63907,14 @@ async function writeProofSafe(gate, meta3, baseDir = process.cwd()) {
|
|
|
63651
63907
|
);
|
|
63652
63908
|
}
|
|
63653
63909
|
}
|
|
63654
|
-
async function runOneTurn(opts, provider, model, providerStream) {
|
|
63910
|
+
async function runOneTurn(opts, provider, model, providerStream, extras) {
|
|
63655
63911
|
const sessionId2 = crypto.randomUUID();
|
|
63656
63912
|
const cwd = resolveHeadlessCwd(opts);
|
|
63657
63913
|
const memoryFactory = await Promise.resolve().then(() => (init_serviceFactory(), serviceFactory_exports));
|
|
63658
|
-
const
|
|
63914
|
+
const spineHolder = {};
|
|
63915
|
+
const nativeMemory = memoryFactory.isMemoryV2Enabled() ? await memoryFactory.getMemoryService(cwd, process.env, {
|
|
63916
|
+
onEvent: memorySinkFor(spineHolder)
|
|
63917
|
+
}) : void 0;
|
|
63659
63918
|
const memoryAutoWrite = memoryFactory.isMemoryAutoWriteEnabled();
|
|
63660
63919
|
const controlQueue = new RuntimeControlQueue();
|
|
63661
63920
|
const harnessHolder = {};
|
|
@@ -63748,7 +64007,11 @@ async function runOneTurn(opts, provider, model, providerStream) {
|
|
|
63748
64007
|
},
|
|
63749
64008
|
...nativeMemory ? { memoryService: nativeMemory } : {},
|
|
63750
64009
|
memoryAutoWrite,
|
|
63751
|
-
...extensionRuntime ? { extensions: extensionRuntime } : {}
|
|
64010
|
+
...extensionRuntime ? { extensions: extensionRuntime } : {},
|
|
64011
|
+
// t37: serve-harness threads the kernel-owned workspace LspManager here
|
|
64012
|
+
// (TurnExtras). undefined keeps the shared per-root fallback — which is
|
|
64013
|
+
// itself one-manager-per-root since t37, so no cross-workspace thrash.
|
|
64014
|
+
...extras?.lspProvider ? { lspProvider: extras.lspProvider } : {}
|
|
63752
64015
|
});
|
|
63753
64016
|
await registerHeadlessMcp(toolRegistry, opts);
|
|
63754
64017
|
const spine = await openHeadlessSpine({
|
|
@@ -63759,6 +64022,7 @@ async function runOneTurn(opts, provider, model, providerStream) {
|
|
|
63759
64022
|
// 2.6.1 (plan §7): deep specs from THIS run’s registry.
|
|
63760
64023
|
toolSpecs: typeof toolRegistry.fingerprints === "function" ? toolRegistry.fingerprints() : void 0
|
|
63761
64024
|
});
|
|
64025
|
+
spineHolder.current = spine;
|
|
63762
64026
|
const seededHistory = await seedHeadlessModelHistory(spine, opts.history);
|
|
63763
64027
|
emitEvent(sessionStartedEvent(spine));
|
|
63764
64028
|
if (opts.orchestrationDecision) {
|
|
@@ -64067,8 +64331,9 @@ async function runOneTurn(opts, provider, model, providerStream) {
|
|
|
64067
64331
|
},
|
|
64068
64332
|
emit: (input) => spine.appendEvent(input)
|
|
64069
64333
|
};
|
|
64334
|
+
const strictEnv = strictEnvOverlay(opts);
|
|
64070
64335
|
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 });
|
|
64336
|
+
const strictGate = await evaluateStrictBuildGate("build", { emit: (input) => spine.appendEvent(input), cwd, env: strictEnv });
|
|
64072
64337
|
await runAdvisoryVerifierReview(strictGate, verifierReviewDeps).catch(() => void 0);
|
|
64073
64338
|
const gate = strictGate.gate;
|
|
64074
64339
|
const verificationPayload = strictGateEventPayload(strictGate);
|
|
@@ -64103,7 +64368,7 @@ async function runOneTurn(opts, provider, model, providerStream) {
|
|
|
64103
64368
|
successfulWrites: pass.successfulWrites + repair.successfulWrites,
|
|
64104
64369
|
emittedWrites: pass.emittedWrites + repair.emittedWrites
|
|
64105
64370
|
};
|
|
64106
|
-
const after = await evaluateStrictBuildGate("build", { emit: (input) => spine.appendEvent(input), cwd });
|
|
64371
|
+
const after = await evaluateStrictBuildGate("build", { emit: (input) => spine.appendEvent(input), cwd, env: strictEnv });
|
|
64107
64372
|
await runAdvisoryVerifierReview(after, verifierReviewDeps).catch(() => void 0);
|
|
64108
64373
|
const afterPayload = strictGateEventPayload(after);
|
|
64109
64374
|
spine.verificationRun(afterPayload);
|
|
@@ -64138,13 +64403,14 @@ async function runOneTurn(opts, provider, model, providerStream) {
|
|
|
64138
64403
|
await spine.close(closeStatus);
|
|
64139
64404
|
} catch {
|
|
64140
64405
|
}
|
|
64406
|
+
await emitHarnessStateEvent({ spine, workspaceRoot: cwd, output: opts.output, emitEvent });
|
|
64141
64407
|
if (opts.exportSessionPath) {
|
|
64142
64408
|
try {
|
|
64143
64409
|
const json3 = await spine.exportJson();
|
|
64144
64410
|
if (json3) {
|
|
64145
64411
|
if (opts.exportSessionPath === "-") process.stdout.write(json3 + "\n");
|
|
64146
64412
|
else {
|
|
64147
|
-
await fs42.mkdir(
|
|
64413
|
+
await fs42.mkdir(path84.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
64148
64414
|
await fs42.writeFile(opts.exportSessionPath, json3, "utf8");
|
|
64149
64415
|
}
|
|
64150
64416
|
}
|
|
@@ -64200,6 +64466,7 @@ var init_runOneTurn = __esm({
|
|
|
64200
64466
|
init_selectionPlaybook();
|
|
64201
64467
|
init_delegationPolicy();
|
|
64202
64468
|
init_facts();
|
|
64469
|
+
init_spineTelemetry();
|
|
64203
64470
|
init_headless();
|
|
64204
64471
|
init_mode();
|
|
64205
64472
|
init_skills2();
|
|
@@ -64213,6 +64480,7 @@ var init_runOneTurn = __esm({
|
|
|
64213
64480
|
init_modelContextBuilder();
|
|
64214
64481
|
init_metrics3();
|
|
64215
64482
|
init_headlessSpine();
|
|
64483
|
+
init_harnessStateEmit();
|
|
64216
64484
|
init_runtime2();
|
|
64217
64485
|
init_controlBridge();
|
|
64218
64486
|
init_protocol2();
|
|
@@ -65118,9 +65386,9 @@ __export(triggerLock_exports, {
|
|
|
65118
65386
|
releaseLock: () => releaseLock
|
|
65119
65387
|
});
|
|
65120
65388
|
import { promises as fs43 } from "node:fs";
|
|
65121
|
-
import * as
|
|
65389
|
+
import * as path85 from "node:path";
|
|
65122
65390
|
function lockPath(projectRoot) {
|
|
65123
|
-
return
|
|
65391
|
+
return path85.join(projectRoot, ".zelari", "trigger.lock");
|
|
65124
65392
|
}
|
|
65125
65393
|
function isPidAlive(pid) {
|
|
65126
65394
|
try {
|
|
@@ -65133,7 +65401,7 @@ function isPidAlive(pid) {
|
|
|
65133
65401
|
}
|
|
65134
65402
|
async function acquireLock(projectRoot, now = () => /* @__PURE__ */ new Date()) {
|
|
65135
65403
|
const lp = lockPath(projectRoot);
|
|
65136
|
-
const dir =
|
|
65404
|
+
const dir = path85.dirname(lp);
|
|
65137
65405
|
await fs43.mkdir(dir, { recursive: true });
|
|
65138
65406
|
try {
|
|
65139
65407
|
const raw = await fs43.readFile(lp, "utf8");
|
|
@@ -65165,13 +65433,10 @@ var init_triggerLock = __esm({
|
|
|
65165
65433
|
|
|
65166
65434
|
// src/cli/runHeadless.ts
|
|
65167
65435
|
import { promises as fs44 } from "node:fs";
|
|
65168
|
-
import
|
|
65436
|
+
import path86 from "node:path";
|
|
65169
65437
|
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
65170
65438
|
async function runHeadless(opts) {
|
|
65171
65439
|
resetTaskSpawnCount();
|
|
65172
|
-
if (opts.strictDone) {
|
|
65173
|
-
process.env.ZELARI_STRICT_DONE = "1";
|
|
65174
|
-
}
|
|
65175
65440
|
let crashed = false;
|
|
65176
65441
|
const handleFatal = (label, err) => {
|
|
65177
65442
|
if (crashed) return;
|
|
@@ -65245,7 +65510,13 @@ ${err.stack}` : "";
|
|
|
65245
65510
|
model
|
|
65246
65511
|
});
|
|
65247
65512
|
}
|
|
65248
|
-
return dispatchHeadlessTurn(opts, provider, model, providerStream
|
|
65513
|
+
return dispatchHeadlessTurn(opts, provider, model, providerStream, {
|
|
65514
|
+
// H10-fix3: the gate already ran above on the SAME input (no chdir in
|
|
65515
|
+
// between) — the one-shot marker keeps dispatchHeadlessTurn from
|
|
65516
|
+
// re-running it (duplicate `[policy]` stderr warning + double policy
|
|
65517
|
+
// load). Per-invocation flag only; never process-global.
|
|
65518
|
+
policyGateDone: true
|
|
65519
|
+
});
|
|
65249
65520
|
}
|
|
65250
65521
|
async function applyHeadlessPolicyGate(opts) {
|
|
65251
65522
|
const cwd = resolveHeadlessCwd(opts);
|
|
@@ -65257,6 +65528,9 @@ async function applyHeadlessPolicyGate(opts) {
|
|
|
65257
65528
|
reportPolicyLoadBlocked(policyLoad.block, opts.output);
|
|
65258
65529
|
await recordPolicyLoadBlockedOnSpine(policyLoad.block, {
|
|
65259
65530
|
mode: opts.mode,
|
|
65531
|
+
// H10-fix2: the spine must land in the RESOLVED workspace, not the
|
|
65532
|
+
// process cwd — a sidecar hosts N workspaces without `chdir`.
|
|
65533
|
+
workspace: cwd,
|
|
65260
65534
|
...opts.profile ? { profile: opts.profile } : {},
|
|
65261
65535
|
...opts.resumeSessionId ? { resumeSessionId: opts.resumeSessionId } : {}
|
|
65262
65536
|
});
|
|
@@ -65276,7 +65550,7 @@ function applyKrakenTurnEnv(opts) {
|
|
|
65276
65550
|
}
|
|
65277
65551
|
}
|
|
65278
65552
|
}
|
|
65279
|
-
async function dispatchHeadlessTurn(opts, provider, model, providerStream) {
|
|
65553
|
+
async function dispatchHeadlessTurn(opts, provider, model, providerStream, oneShot, extras) {
|
|
65280
65554
|
const cwd = resolveHeadlessCwd(opts);
|
|
65281
65555
|
if (typeof opts.mode === "string") {
|
|
65282
65556
|
const parsed = parseMode(opts.mode);
|
|
@@ -65304,8 +65578,10 @@ async function dispatchHeadlessTurn(opts, provider, model, providerStream) {
|
|
|
65304
65578
|
}
|
|
65305
65579
|
} catch {
|
|
65306
65580
|
}
|
|
65307
|
-
|
|
65308
|
-
|
|
65581
|
+
if (!oneShot?.policyGateDone) {
|
|
65582
|
+
const policyBlock = await applyHeadlessPolicyGate(opts);
|
|
65583
|
+
if (policyBlock !== void 0) return policyBlock;
|
|
65584
|
+
}
|
|
65309
65585
|
if (opts.orchestrationAuto) {
|
|
65310
65586
|
const facts = await collectOrchestrationFacts(cwd);
|
|
65311
65587
|
const verdict = chooseOrchestration(opts.task ?? "", facts);
|
|
@@ -65347,12 +65623,12 @@ async function dispatchHeadlessTurn(opts, provider, model, providerStream) {
|
|
|
65347
65623
|
`);
|
|
65348
65624
|
}
|
|
65349
65625
|
if (mode === "zelari") {
|
|
65350
|
-
return runHeadlessZelari(opts, provider, model, providerStream);
|
|
65626
|
+
return runHeadlessZelari(opts, provider, model, providerStream, extras);
|
|
65351
65627
|
}
|
|
65352
65628
|
if (mode === "council" || opts.useCouncil) {
|
|
65353
|
-
return runHeadlessCouncil(opts, provider, model, providerStream);
|
|
65629
|
+
return runHeadlessCouncil(opts, provider, model, providerStream, extras);
|
|
65354
65630
|
}
|
|
65355
|
-
return runOneTurn(opts, provider, model, providerStream);
|
|
65631
|
+
return runOneTurn(opts, provider, model, providerStream, extras);
|
|
65356
65632
|
}
|
|
65357
65633
|
async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
65358
65634
|
const { isKrakenGraphEnabled: isKrakenGraphEnabled2, KrakenGraphExecutor: KrakenGraphExecutor2 } = await Promise.resolve().then(() => (init_executor(), executor_exports));
|
|
@@ -65372,8 +65648,15 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
65372
65648
|
const { createKrakenSubAgentContextFactory: createKrakenSubAgentContextFactory2 } = await Promise.resolve().then(() => (init_toolRegistry(), toolRegistry_exports));
|
|
65373
65649
|
const cwd = resolveHeadlessCwd(opts);
|
|
65374
65650
|
const sessionId2 = crypto.randomUUID();
|
|
65651
|
+
const spine = await openHeadlessSpine({ sessionId: sessionId2, mode: "kraken", workspace: cwd });
|
|
65652
|
+
if (opts.output === "json") emitEvent(sessionStartedEvent(spine));
|
|
65653
|
+
spine.userMessage(prompt);
|
|
65375
65654
|
const { getMemoryService: getMemoryService2, isMemoryAutoWriteEnabled: isMemoryAutoWriteEnabled2, isMemoryV2Enabled: isMemoryV2Enabled2 } = await Promise.resolve().then(() => (init_serviceFactory(), serviceFactory_exports));
|
|
65376
|
-
const graphMemory = isMemoryV2Enabled2() ? await getMemoryService2(cwd, process.env
|
|
65655
|
+
const graphMemory = isMemoryV2Enabled2() ? await getMemoryService2(cwd, process.env, {
|
|
65656
|
+
// W2: the spine is already open here — memory events are noted
|
|
65657
|
+
// directly (context.projection / memory_event state-only payloads).
|
|
65658
|
+
onEvent: (event) => spineMemoryEventNote(spine, event)
|
|
65659
|
+
}) : void 0;
|
|
65377
65660
|
const log = (message) => {
|
|
65378
65661
|
if (opts.output === "json") {
|
|
65379
65662
|
emitEvent({ type: "log", message });
|
|
@@ -65388,28 +65671,32 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
65388
65671
|
abort.abort();
|
|
65389
65672
|
};
|
|
65390
65673
|
process.once("SIGINT", onSigint);
|
|
65674
|
+
let exitCode = 0;
|
|
65391
65675
|
try {
|
|
65392
65676
|
let preflightGraph;
|
|
65393
65677
|
if (opts.runPlan && opts.runPlan.trim() !== "") {
|
|
65394
|
-
const planPath =
|
|
65678
|
+
const planPath = path86.join(cwd, ".zelari", "radio", `plan-${opts.runPlan}.json`);
|
|
65395
65679
|
log(`loading pre-flight plan: ${planPath}`);
|
|
65396
65680
|
let raw;
|
|
65397
65681
|
try {
|
|
65398
65682
|
raw = await fs44.readFile(planPath, "utf8");
|
|
65399
65683
|
} catch (e) {
|
|
65400
65684
|
log(`plan file not found: ${planPath} (${e.message})`);
|
|
65401
|
-
|
|
65685
|
+
exitCode = 1;
|
|
65686
|
+
return exitCode;
|
|
65402
65687
|
}
|
|
65403
65688
|
let planJson;
|
|
65404
65689
|
try {
|
|
65405
65690
|
planJson = JSON.parse(raw);
|
|
65406
65691
|
} catch (e) {
|
|
65407
65692
|
log(`plan file is malformed JSON: ${e.message}`);
|
|
65408
|
-
|
|
65693
|
+
exitCode = 1;
|
|
65694
|
+
return exitCode;
|
|
65409
65695
|
}
|
|
65410
65696
|
if (!planJson || !Array.isArray(planJson.nodes)) {
|
|
65411
65697
|
log(`plan file is malformed: missing "nodes" array`);
|
|
65412
|
-
|
|
65698
|
+
exitCode = 1;
|
|
65699
|
+
return exitCode;
|
|
65413
65700
|
}
|
|
65414
65701
|
const { createGraph: createGraph2, validateGraph: validateGraph2 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
|
|
65415
65702
|
const validated = createGraph2(planJson.graphId ?? opts.runPlan, planJson.nodes);
|
|
@@ -65431,8 +65718,8 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
65431
65718
|
log(formatKrakenGraphAscii2(graph));
|
|
65432
65719
|
if (opts.planOnly) {
|
|
65433
65720
|
const planId = randomUUID10();
|
|
65434
|
-
const planDir =
|
|
65435
|
-
const planPath =
|
|
65721
|
+
const planDir = path86.join(cwd, ".zelari", "radio");
|
|
65722
|
+
const planPath = path86.join(planDir, `plan-${planId}.json`);
|
|
65436
65723
|
await fs44.mkdir(planDir, { recursive: true });
|
|
65437
65724
|
await fs44.writeFile(
|
|
65438
65725
|
planPath,
|
|
@@ -65451,7 +65738,8 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
65451
65738
|
emitEvent({ type: "log", message: `plan_only_id=${planId}` });
|
|
65452
65739
|
emitEvent({ type: "log", message: `plan_only_path=${planPath}` });
|
|
65453
65740
|
}
|
|
65454
|
-
|
|
65741
|
+
exitCode = 0;
|
|
65742
|
+
return exitCode;
|
|
65455
65743
|
}
|
|
65456
65744
|
const audit = new AuditLogger2();
|
|
65457
65745
|
const executor = new KrakenGraphExecutor2({
|
|
@@ -65508,7 +65796,8 @@ ${formatKrakenGraphDigest2(
|
|
|
65508
65796
|
process.stdout.write(`${finalAscii}
|
|
65509
65797
|
`);
|
|
65510
65798
|
}
|
|
65511
|
-
|
|
65799
|
+
exitCode = summary.converged ? 0 : 3;
|
|
65800
|
+
return exitCode;
|
|
65512
65801
|
} catch (err) {
|
|
65513
65802
|
const message = err instanceof Error ? err.message : String(err);
|
|
65514
65803
|
if (opts.output === "json") {
|
|
@@ -65517,17 +65806,25 @@ ${formatKrakenGraphDigest2(
|
|
|
65517
65806
|
process.stderr.write(`[zelari-code --headless] kraken graph failed: ${message}
|
|
65518
65807
|
`);
|
|
65519
65808
|
}
|
|
65520
|
-
|
|
65809
|
+
exitCode = 2;
|
|
65810
|
+
return exitCode;
|
|
65521
65811
|
} finally {
|
|
65522
65812
|
process.off("SIGINT", onSigint);
|
|
65523
65813
|
await graphMemory?.close().catch(() => void 0);
|
|
65814
|
+
try {
|
|
65815
|
+
const closeReason = abort.signal.aborted ? "cancelled" : exitCode === 0 ? "completed" : "error";
|
|
65816
|
+
await spine.close(closeReason);
|
|
65817
|
+
} catch {
|
|
65818
|
+
}
|
|
65819
|
+
await emitHarnessStateEvent({ spine, workspaceRoot: cwd, output: opts.output, emitEvent });
|
|
65524
65820
|
}
|
|
65525
65821
|
}
|
|
65526
|
-
async function buildCouncilToolRegistry(planMode, opts, memoryService, memoryAutoWrite = false) {
|
|
65822
|
+
async function buildCouncilToolRegistry(planMode, opts, memoryService, memoryAutoWrite = false, extras) {
|
|
65527
65823
|
const cwd = opts ? resolveHeadlessCwd(opts) : process.cwd();
|
|
65528
65824
|
const { registry: toolRegistry } = createBuiltinToolRegistry({
|
|
65529
65825
|
root: cwd,
|
|
65530
65826
|
planMode,
|
|
65827
|
+
...extras?.lspProvider ? { lspProvider: extras.lspProvider } : {},
|
|
65531
65828
|
permissionPolicy: {
|
|
65532
65829
|
read: "allow",
|
|
65533
65830
|
write: "allow",
|
|
@@ -65554,12 +65851,15 @@ async function buildCouncilToolRegistry(planMode, opts, memoryService, memoryAut
|
|
|
65554
65851
|
}
|
|
65555
65852
|
return { toolRegistry, workspaceCtx: realCtx };
|
|
65556
65853
|
}
|
|
65557
|
-
async function runHeadlessCouncil(opts, provider, model, providerStream) {
|
|
65854
|
+
async function runHeadlessCouncil(opts, provider, model, providerStream, extras) {
|
|
65558
65855
|
const { dispatchCouncil: dispatchCouncil2 } = await Promise.resolve().then(() => (init_councilDispatcher(), councilDispatcher_exports));
|
|
65559
65856
|
const sessionId2 = crypto.randomUUID();
|
|
65560
65857
|
const cwd = resolveHeadlessCwd(opts);
|
|
65561
65858
|
const memoryFactory = await Promise.resolve().then(() => (init_serviceFactory(), serviceFactory_exports));
|
|
65562
|
-
const
|
|
65859
|
+
const spineHolder = {};
|
|
65860
|
+
const nativeMemory = memoryFactory.isMemoryV2Enabled() ? await memoryFactory.getMemoryService(cwd, process.env, {
|
|
65861
|
+
onEvent: memorySinkFor(spineHolder)
|
|
65862
|
+
}) : void 0;
|
|
65563
65863
|
const memoryAutoWrite = memoryFactory.isMemoryAutoWriteEnabled();
|
|
65564
65864
|
const spine = await openHeadlessSpine({
|
|
65565
65865
|
sessionId: opts.resumeSessionId ?? sessionId2,
|
|
@@ -65567,6 +65867,7 @@ async function runHeadlessCouncil(opts, provider, model, providerStream) {
|
|
|
65567
65867
|
profile: opts.profile,
|
|
65568
65868
|
workspace: cwd
|
|
65569
65869
|
});
|
|
65870
|
+
spineHolder.current = spine;
|
|
65570
65871
|
const seededHistory = await seedHeadlessModelHistory(spine, opts.history);
|
|
65571
65872
|
emitEvent(sessionStartedEvent(spine));
|
|
65572
65873
|
if (opts.orchestrationDecision) {
|
|
@@ -65586,7 +65887,8 @@ async function runHeadlessCouncil(opts, provider, model, providerStream) {
|
|
|
65586
65887
|
planModeFromOpts(opts) || softGated,
|
|
65587
65888
|
opts,
|
|
65588
65889
|
nativeMemory,
|
|
65589
|
-
memoryAutoWrite
|
|
65890
|
+
memoryAutoWrite,
|
|
65891
|
+
extras
|
|
65590
65892
|
);
|
|
65591
65893
|
const { FeedbackStore: FeedbackStore2 } = await Promise.resolve().then(() => (init_councilFeedback(), councilFeedback_exports));
|
|
65592
65894
|
const feedbackStore = new FeedbackStore2();
|
|
@@ -65715,13 +66017,14 @@ async function runHeadlessCouncil(opts, provider, model, providerStream) {
|
|
|
65715
66017
|
await spine.close(exitCode === 0 ? "completed" : "error");
|
|
65716
66018
|
} catch {
|
|
65717
66019
|
}
|
|
66020
|
+
await emitHarnessStateEvent({ spine, workspaceRoot: cwd, output: opts.output, emitEvent });
|
|
65718
66021
|
if (opts.exportSessionPath) {
|
|
65719
66022
|
try {
|
|
65720
66023
|
const json3 = await spine.exportJson();
|
|
65721
66024
|
if (json3) {
|
|
65722
66025
|
if (opts.exportSessionPath === "-") process.stdout.write(json3 + "\n");
|
|
65723
66026
|
else {
|
|
65724
|
-
await fs44.mkdir(
|
|
66027
|
+
await fs44.mkdir(path86.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
65725
66028
|
await fs44.writeFile(opts.exportSessionPath, json3, "utf8");
|
|
65726
66029
|
}
|
|
65727
66030
|
}
|
|
@@ -65754,7 +66057,7 @@ async function runHeadlessCouncil(opts, provider, model, providerStream) {
|
|
|
65754
66057
|
await nativeMemory?.close().catch(() => void 0);
|
|
65755
66058
|
return exitCode;
|
|
65756
66059
|
}
|
|
65757
|
-
async function runHeadlessZelari(opts, provider, model, providerStream) {
|
|
66060
|
+
async function runHeadlessZelari(opts, provider, model, providerStream, extras) {
|
|
65758
66061
|
const projectRoot = resolveHeadlessCwd(opts);
|
|
65759
66062
|
const sessionId2 = opts.resumeSessionId ?? crypto.randomUUID();
|
|
65760
66063
|
const spine = await openHeadlessSpine({
|
|
@@ -65777,13 +66080,18 @@ async function runHeadlessZelari(opts, provider, model, providerStream) {
|
|
|
65777
66080
|
userMessage: opts.task,
|
|
65778
66081
|
hasPlan: hasWorkspacePlan2(projectRoot)
|
|
65779
66082
|
});
|
|
65780
|
-
const memory = await getMemoryBackend2(
|
|
66083
|
+
const memory = await getMemoryBackend2(
|
|
66084
|
+
projectRoot,
|
|
66085
|
+
process.env,
|
|
66086
|
+
(event) => spineMemoryEventNote(spine, event)
|
|
66087
|
+
);
|
|
65781
66088
|
const nativeMissionMemory = memory.service;
|
|
65782
66089
|
const { toolRegistry, workspaceCtx } = await buildCouncilToolRegistry(
|
|
65783
66090
|
planModeFromOpts(opts),
|
|
65784
66091
|
opts,
|
|
65785
66092
|
nativeMissionMemory,
|
|
65786
|
-
Boolean(nativeMissionMemory) && process.env.ZELARI_MEMORY_AUTO_WRITE !== "0"
|
|
66093
|
+
Boolean(nativeMissionMemory) && process.env.ZELARI_MEMORY_AUTO_WRITE !== "0",
|
|
66094
|
+
extras
|
|
65787
66095
|
);
|
|
65788
66096
|
const feedbackStore = new FeedbackStore2();
|
|
65789
66097
|
const chairmanBudget = envNumber(process.env.ZELARI_MODE_MAX_TOOLS_LUCIFER, {
|
|
@@ -66096,6 +66404,8 @@ ${ragContext}` : slicePrompt;
|
|
|
66096
66404
|
const missionGate = await evaluateStrictBuildGate("build", {
|
|
66097
66405
|
emit: (input) => spine.appendEvent(input),
|
|
66098
66406
|
surface: "mission",
|
|
66407
|
+
// H10-fix1: per-invocation env overlay — never process.env.
|
|
66408
|
+
env: strictEnvOverlay(opts),
|
|
66099
66409
|
cwd: projectRoot
|
|
66100
66410
|
});
|
|
66101
66411
|
const missionVerificationPayload = strictGateEventPayload(missionGate);
|
|
@@ -66132,13 +66442,14 @@ ${ragContext}` : slicePrompt;
|
|
|
66132
66442
|
else await spine.close(exitCode === 2 ? "error" : "stopped");
|
|
66133
66443
|
} catch {
|
|
66134
66444
|
}
|
|
66445
|
+
await emitHarnessStateEvent({ spine, workspaceRoot: projectRoot, output: opts.output, emitEvent });
|
|
66135
66446
|
if (opts.exportSessionPath) {
|
|
66136
66447
|
try {
|
|
66137
66448
|
const json3 = await spine.exportJson();
|
|
66138
66449
|
if (json3) {
|
|
66139
66450
|
if (opts.exportSessionPath === "-") process.stdout.write(json3 + "\n");
|
|
66140
66451
|
else {
|
|
66141
|
-
await fs44.mkdir(
|
|
66452
|
+
await fs44.mkdir(path86.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
66142
66453
|
await fs44.writeFile(opts.exportSessionPath, json3, "utf8");
|
|
66143
66454
|
}
|
|
66144
66455
|
}
|
|
@@ -66157,6 +66468,7 @@ var init_runHeadless = __esm({
|
|
|
66157
66468
|
init_toolRegistry();
|
|
66158
66469
|
init_policy();
|
|
66159
66470
|
init_facts();
|
|
66471
|
+
init_spineTelemetry();
|
|
66160
66472
|
init_councilConfig();
|
|
66161
66473
|
init_headless();
|
|
66162
66474
|
init_claudeProvider();
|
|
@@ -66172,6 +66484,7 @@ var init_runHeadless = __esm({
|
|
|
66172
66484
|
init_modelContextBuilder();
|
|
66173
66485
|
init_metrics3();
|
|
66174
66486
|
init_headlessSpine();
|
|
66487
|
+
init_harnessStateEmit();
|
|
66175
66488
|
init_policyGate();
|
|
66176
66489
|
init_policyLoadMode();
|
|
66177
66490
|
init_runOneTurn();
|
|
@@ -66749,7 +67062,7 @@ function upsertSkill(opts) {
|
|
|
66749
67062
|
}
|
|
66750
67063
|
dir = getProjectSkillsDir(root);
|
|
66751
67064
|
}
|
|
66752
|
-
const
|
|
67065
|
+
const path90 = skillFilePath(dir, name);
|
|
66753
67066
|
const content = serializeSkillMd({
|
|
66754
67067
|
name,
|
|
66755
67068
|
description,
|
|
@@ -66758,13 +67071,13 @@ function upsertSkill(opts) {
|
|
|
66758
67071
|
tools: opts.tools,
|
|
66759
67072
|
cost: opts.cost
|
|
66760
67073
|
});
|
|
66761
|
-
const parsed = parseSkillMd(content,
|
|
67074
|
+
const parsed = parseSkillMd(content, path90);
|
|
66762
67075
|
if (!parsed) {
|
|
66763
67076
|
return { ok: false, error: "Generated SKILL.md failed validation" };
|
|
66764
67077
|
}
|
|
66765
|
-
mkdirSync21(dirname13(
|
|
66766
|
-
writeFileSync24(
|
|
66767
|
-
return { ok: true, path:
|
|
67078
|
+
mkdirSync21(dirname13(path90), { recursive: true });
|
|
67079
|
+
writeFileSync24(path90, content, "utf8");
|
|
67080
|
+
return { ok: true, path: path90 };
|
|
66768
67081
|
}
|
|
66769
67082
|
function removeSkill(opts) {
|
|
66770
67083
|
const name = opts.name.trim().toLowerCase();
|
|
@@ -66782,8 +67095,8 @@ function removeSkill(opts) {
|
|
|
66782
67095
|
dir = getProjectSkillsDir(root);
|
|
66783
67096
|
}
|
|
66784
67097
|
const skillDir = join46(dir, name);
|
|
66785
|
-
const
|
|
66786
|
-
if (!existsSync52(
|
|
67098
|
+
const path90 = skillFilePath(dir, name);
|
|
67099
|
+
if (!existsSync52(path90) && !existsSync52(skillDir)) {
|
|
66787
67100
|
return { ok: false, error: `Skill "${name}" not found in ${dir}` };
|
|
66788
67101
|
}
|
|
66789
67102
|
try {
|
|
@@ -66794,7 +67107,7 @@ function removeSkill(opts) {
|
|
|
66794
67107
|
error: err instanceof Error ? err.message : String(err)
|
|
66795
67108
|
};
|
|
66796
67109
|
}
|
|
66797
|
-
return { ok: true, path:
|
|
67110
|
+
return { ok: true, path: path90 };
|
|
66798
67111
|
}
|
|
66799
67112
|
var NAME_RE, BUILTIN_SKILL_MODULES, builtinsLoaded;
|
|
66800
67113
|
var init_skillConfigIo = __esm({
|
|
@@ -66913,7 +67226,7 @@ var init_jsonApi = __esm({
|
|
|
66913
67226
|
});
|
|
66914
67227
|
|
|
66915
67228
|
// src/cli/memory/mcpAdapter.ts
|
|
66916
|
-
import * as
|
|
67229
|
+
import * as path87 from "node:path";
|
|
66917
67230
|
var id2, projectId, source, SearchSchema, AddSchema, LinkSchema, RetractSchema, MEMORY_MCP_TOOLS, MemoryMcpAdapter;
|
|
66918
67231
|
var init_mcpAdapter = __esm({
|
|
66919
67232
|
"src/cli/memory/mcpAdapter.ts"() {
|
|
@@ -67083,8 +67396,8 @@ var init_mcpAdapter = __esm({
|
|
|
67083
67396
|
this.takeWrite();
|
|
67084
67397
|
const externalFile = args.source?.file;
|
|
67085
67398
|
if (externalFile) {
|
|
67086
|
-
const normalized =
|
|
67087
|
-
if (
|
|
67399
|
+
const normalized = path87.normalize(externalFile);
|
|
67400
|
+
if (path87.isAbsolute(normalized) || normalized === ".." || normalized.startsWith(`..${path87.sep}`)) {
|
|
67088
67401
|
throw new Error("source.file must be project-relative and cannot escape the project");
|
|
67089
67402
|
}
|
|
67090
67403
|
}
|
|
@@ -67612,12 +67925,12 @@ function ensureHome() {
|
|
|
67612
67925
|
}
|
|
67613
67926
|
}
|
|
67614
67927
|
function loadCompanionConfig() {
|
|
67615
|
-
const
|
|
67616
|
-
if (!existsSync53(
|
|
67928
|
+
const path90 = getCompanionConfigPath();
|
|
67929
|
+
if (!existsSync53(path90)) {
|
|
67617
67930
|
return { projects: [] };
|
|
67618
67931
|
}
|
|
67619
67932
|
try {
|
|
67620
|
-
const raw = JSON.parse(readFileSync41(
|
|
67933
|
+
const raw = JSON.parse(readFileSync41(path90, "utf8"));
|
|
67621
67934
|
const projects = Array.isArray(raw.projects) ? raw.projects.filter(
|
|
67622
67935
|
(p3) => p3 && typeof p3.path === "string" && p3.path.trim() && typeof (p3.id ?? p3.name) === "string"
|
|
67623
67936
|
).map((p3) => ({
|
|
@@ -67655,16 +67968,16 @@ function loadOrCreateToken(explicit) {
|
|
|
67655
67968
|
return { token: explicit.trim(), created: false };
|
|
67656
67969
|
}
|
|
67657
67970
|
ensureHome();
|
|
67658
|
-
const
|
|
67659
|
-
if (existsSync53(
|
|
67660
|
-
const t = readFileSync41(
|
|
67971
|
+
const path90 = getCompanionTokenPath();
|
|
67972
|
+
if (existsSync53(path90)) {
|
|
67973
|
+
const t = readFileSync41(path90, "utf8").trim();
|
|
67661
67974
|
if (t) return { token: t, created: false };
|
|
67662
67975
|
}
|
|
67663
67976
|
const token = randomBytes7(24).toString("base64url");
|
|
67664
|
-
writeFileSync25(
|
|
67977
|
+
writeFileSync25(path90, token + "\n", "utf8");
|
|
67665
67978
|
try {
|
|
67666
67979
|
const fs45 = __require("node:fs");
|
|
67667
|
-
fs45.chmodSync?.(
|
|
67980
|
+
fs45.chmodSync?.(path90, 384);
|
|
67668
67981
|
} catch {
|
|
67669
67982
|
}
|
|
67670
67983
|
return { token, created: true };
|
|
@@ -67689,17 +68002,17 @@ function mergeProjects(cfg, extraPaths) {
|
|
|
67689
68002
|
byId.set(p3.id, p3);
|
|
67690
68003
|
}
|
|
67691
68004
|
for (const raw of extraPaths) {
|
|
67692
|
-
const
|
|
67693
|
-
if (!
|
|
67694
|
-
let id3 = slugFromPath(
|
|
68005
|
+
const path90 = raw.trim();
|
|
68006
|
+
if (!path90) continue;
|
|
68007
|
+
let id3 = slugFromPath(path90);
|
|
67695
68008
|
let n = 2;
|
|
67696
|
-
while (byId.has(id3) && byId.get(id3).path !==
|
|
67697
|
-
id3 = `${slugFromPath(
|
|
68009
|
+
while (byId.has(id3) && byId.get(id3).path !== path90) {
|
|
68010
|
+
id3 = `${slugFromPath(path90)}-${n++}`;
|
|
67698
68011
|
}
|
|
67699
68012
|
byId.set(id3, {
|
|
67700
68013
|
id: id3,
|
|
67701
|
-
name: slugFromPath(
|
|
67702
|
-
path:
|
|
68014
|
+
name: slugFromPath(path90),
|
|
68015
|
+
path: path90
|
|
67703
68016
|
});
|
|
67704
68017
|
}
|
|
67705
68018
|
return [...byId.values()];
|
|
@@ -67752,6 +68065,7 @@ __export(harnessServer_exports, {
|
|
|
67752
68065
|
bindHarnessTurnOptions: () => bindHarnessTurnOptions,
|
|
67753
68066
|
createCliRunTurn: () => createCliRunTurn,
|
|
67754
68067
|
createCliWorkspaceServices: () => createCliWorkspaceServices,
|
|
68068
|
+
resolveTurnLspProvider: () => resolveTurnLspProvider,
|
|
67755
68069
|
runHarnessServer: () => runHarnessServer,
|
|
67756
68070
|
startHarnessServer: () => startHarnessServer
|
|
67757
68071
|
});
|
|
@@ -67797,6 +68111,10 @@ function bindHarnessTurnOptions(input, workspaceRoot) {
|
|
|
67797
68111
|
useCouncil: turnInput.useCouncil === true || mode === "council"
|
|
67798
68112
|
};
|
|
67799
68113
|
}
|
|
68114
|
+
function resolveTurnLspProvider(services) {
|
|
68115
|
+
const candidate = services?.lspManager;
|
|
68116
|
+
return candidate instanceof LspManager ? candidate : void 0;
|
|
68117
|
+
}
|
|
67800
68118
|
function createCliRunTurn() {
|
|
67801
68119
|
let streamPromise = null;
|
|
67802
68120
|
const ensureStream = () => {
|
|
@@ -67823,11 +68141,14 @@ function createCliRunTurn() {
|
|
|
67823
68141
|
return async (input, deps) => {
|
|
67824
68142
|
const { provider, model, stream } = await ensureStream();
|
|
67825
68143
|
const opts = bindHarnessTurnOptions(input, deps.session.workspaceRoot);
|
|
68144
|
+
const lspProvider = resolveTurnLspProvider(deps.services);
|
|
67826
68145
|
const exitCode = await dispatchHeadlessTurn(
|
|
67827
68146
|
opts,
|
|
67828
68147
|
provider,
|
|
67829
68148
|
model,
|
|
67830
|
-
stream
|
|
68149
|
+
stream,
|
|
68150
|
+
void 0,
|
|
68151
|
+
lspProvider ? { lspProvider } : void 0
|
|
67831
68152
|
);
|
|
67832
68153
|
return { exitCode };
|
|
67833
68154
|
};
|
|
@@ -68666,9 +68987,9 @@ async function runCompanionServe(opts = {}) {
|
|
|
68666
68987
|
return;
|
|
68667
68988
|
}
|
|
68668
68989
|
const url2 = parseUrl(req);
|
|
68669
|
-
const
|
|
68990
|
+
const path90 = url2.pathname.replace(/\/+$/, "") || "/";
|
|
68670
68991
|
try {
|
|
68671
|
-
if (req.method === "GET" && (
|
|
68992
|
+
if (req.method === "GET" && (path90 === "/health" || path90 === "/v1/health")) {
|
|
68672
68993
|
sendJson2(res, 200, {
|
|
68673
68994
|
ok: true,
|
|
68674
68995
|
service: "zelari-companion",
|
|
@@ -68680,18 +69001,18 @@ async function runCompanionServe(opts = {}) {
|
|
|
68680
69001
|
});
|
|
68681
69002
|
return;
|
|
68682
69003
|
}
|
|
68683
|
-
if (
|
|
69004
|
+
if (path90.startsWith("/v1")) {
|
|
68684
69005
|
if (!tokenMatches(token, getBearer(req))) {
|
|
68685
69006
|
sendJson2(res, 401, { ok: false, error: "unauthorized" });
|
|
68686
69007
|
return;
|
|
68687
69008
|
}
|
|
68688
69009
|
}
|
|
68689
|
-
if (req.method === "GET" &&
|
|
69010
|
+
if (req.method === "GET" && path90 === "/v1/config") {
|
|
68690
69011
|
const snap = buildDesktopConfigSnapshot();
|
|
68691
69012
|
sendJson2(res, 200, { ok: true, ...snap });
|
|
68692
69013
|
return;
|
|
68693
69014
|
}
|
|
68694
|
-
if (req.method === "GET" &&
|
|
69015
|
+
if (req.method === "GET" && path90 === "/v1/projects") {
|
|
68695
69016
|
sendJson2(res, 200, {
|
|
68696
69017
|
ok: true,
|
|
68697
69018
|
projects: projects.map((p3) => ({
|
|
@@ -68702,7 +69023,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
68702
69023
|
});
|
|
68703
69024
|
return;
|
|
68704
69025
|
}
|
|
68705
|
-
if (req.method === "GET" &&
|
|
69026
|
+
if (req.method === "GET" && path90 === "/v1/runs") {
|
|
68706
69027
|
sendJson2(res, 200, {
|
|
68707
69028
|
ok: true,
|
|
68708
69029
|
active: runs.getActive(),
|
|
@@ -68720,7 +69041,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
68720
69041
|
});
|
|
68721
69042
|
return;
|
|
68722
69043
|
}
|
|
68723
|
-
if (req.method === "POST" &&
|
|
69044
|
+
if (req.method === "POST" && path90 === "/v1/runs") {
|
|
68724
69045
|
const raw = await readBody(req);
|
|
68725
69046
|
let body = {};
|
|
68726
69047
|
try {
|
|
@@ -68763,11 +69084,12 @@ async function runCompanionServe(opts = {}) {
|
|
|
68763
69084
|
createdAt: result.run.createdAt
|
|
68764
69085
|
},
|
|
68765
69086
|
eventsUrl: `/v1/runs/${result.run.id}/events`,
|
|
68766
|
-
cancelUrl: `/v1/runs/${result.run.id}/cancel
|
|
69087
|
+
cancelUrl: `/v1/runs/${result.run.id}/cancel`,
|
|
69088
|
+
steerUrl: `/v1/runs/${result.run.id}/steer`
|
|
68767
69089
|
});
|
|
68768
69090
|
return;
|
|
68769
69091
|
}
|
|
68770
|
-
const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(
|
|
69092
|
+
const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(path90);
|
|
68771
69093
|
if (req.method === "GET" && eventsMatch) {
|
|
68772
69094
|
const runId = eventsMatch[1];
|
|
68773
69095
|
const run = runs.getRun(runId);
|
|
@@ -68832,7 +69154,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
68832
69154
|
}, 500);
|
|
68833
69155
|
return;
|
|
68834
69156
|
}
|
|
68835
|
-
const cancelMatch = /^\/v1\/runs\/([^/]+)\/cancel$/.exec(
|
|
69157
|
+
const cancelMatch = /^\/v1\/runs\/([^/]+)\/cancel$/.exec(path90);
|
|
68836
69158
|
if (req.method === "POST" && cancelMatch) {
|
|
68837
69159
|
const runId = cancelMatch[1];
|
|
68838
69160
|
const result = runs.cancel(runId);
|
|
@@ -68843,6 +69165,30 @@ async function runCompanionServe(opts = {}) {
|
|
|
68843
69165
|
sendJson2(res, 200, { ok: true, cancelled: runId });
|
|
68844
69166
|
return;
|
|
68845
69167
|
}
|
|
69168
|
+
const steerMatch = /^\/v1\/runs\/([^/]+)\/steer$/.exec(path90);
|
|
69169
|
+
if (req.method === "POST" && steerMatch) {
|
|
69170
|
+
const runId = steerMatch[1];
|
|
69171
|
+
const raw = await readBody(req);
|
|
69172
|
+
let body = {};
|
|
69173
|
+
try {
|
|
69174
|
+
body = raw ? JSON.parse(raw) : {};
|
|
69175
|
+
} catch {
|
|
69176
|
+
sendJson2(res, 400, { ok: false, error: "invalid JSON body" });
|
|
69177
|
+
return;
|
|
69178
|
+
}
|
|
69179
|
+
const text = typeof body.text === "string" ? body.text.trim() : "";
|
|
69180
|
+
if (!text) {
|
|
69181
|
+
sendJson2(res, 400, { ok: false, error: "text is required" });
|
|
69182
|
+
return;
|
|
69183
|
+
}
|
|
69184
|
+
const result = await runs.steer(runId, text);
|
|
69185
|
+
if (!result.ok) {
|
|
69186
|
+
sendJson2(res, 404, { ok: false, error: result.error });
|
|
69187
|
+
return;
|
|
69188
|
+
}
|
|
69189
|
+
sendJson2(res, 200, { ok: true, steered: runId, result: result.result });
|
|
69190
|
+
return;
|
|
69191
|
+
}
|
|
68846
69192
|
sendJson2(res, 404, { ok: false, error: "not found" });
|
|
68847
69193
|
} catch (err) {
|
|
68848
69194
|
sendJson2(res, 500, {
|
|
@@ -68986,11 +69332,11 @@ import { execSync as execSync2 } from "node:child_process";
|
|
|
68986
69332
|
import { existsSync as existsSync55, readFileSync as readFileSync42, readlinkSync, statSync as statSync10 } from "node:fs";
|
|
68987
69333
|
import { createRequire as createRequire3 } from "node:module";
|
|
68988
69334
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
68989
|
-
import
|
|
69335
|
+
import path88 from "node:path";
|
|
68990
69336
|
function findPackageRoot(start) {
|
|
68991
69337
|
let dir = start;
|
|
68992
69338
|
for (let i = 0; i < 6; i += 1) {
|
|
68993
|
-
const candidate =
|
|
69339
|
+
const candidate = path88.join(dir, "package.json");
|
|
68994
69340
|
if (existsSync55(candidate)) {
|
|
68995
69341
|
try {
|
|
68996
69342
|
const pkg = JSON.parse(readFileSync42(candidate, "utf8"));
|
|
@@ -68998,11 +69344,11 @@ function findPackageRoot(start) {
|
|
|
68998
69344
|
} catch {
|
|
68999
69345
|
}
|
|
69000
69346
|
}
|
|
69001
|
-
const parent =
|
|
69347
|
+
const parent = path88.dirname(dir);
|
|
69002
69348
|
if (parent === dir) break;
|
|
69003
69349
|
dir = parent;
|
|
69004
69350
|
}
|
|
69005
|
-
return
|
|
69351
|
+
return path88.resolve(__dirname3, "..", "..", "..");
|
|
69006
69352
|
}
|
|
69007
69353
|
function tryExec(cmd) {
|
|
69008
69354
|
try {
|
|
@@ -69016,7 +69362,7 @@ function tryExec(cmd) {
|
|
|
69016
69362
|
}
|
|
69017
69363
|
function readPackageJson4() {
|
|
69018
69364
|
try {
|
|
69019
|
-
const pkgPath =
|
|
69365
|
+
const pkgPath = path88.join(packageRoot, "package.json");
|
|
69020
69366
|
return JSON.parse(readFileSync42(pkgPath, "utf8"));
|
|
69021
69367
|
} catch {
|
|
69022
69368
|
return null;
|
|
@@ -69032,7 +69378,7 @@ function checkShim(pkgName) {
|
|
|
69032
69378
|
}
|
|
69033
69379
|
const isWin = process.platform === "win32";
|
|
69034
69380
|
const shimName = isWin ? "zelari-code.cmd" : "zelari-code";
|
|
69035
|
-
const shimPath =
|
|
69381
|
+
const shimPath = path88.join(prefix, shimName);
|
|
69036
69382
|
if (!existsSync55(shimPath)) {
|
|
69037
69383
|
return FAIL(
|
|
69038
69384
|
`shim not found at ${shimPath}
|
|
@@ -69060,8 +69406,8 @@ function checkShim(pkgName) {
|
|
|
69060
69406
|
fix: npm install -g ${pkgName}@latest --force`
|
|
69061
69407
|
);
|
|
69062
69408
|
}
|
|
69063
|
-
const resolved =
|
|
69064
|
-
const expected =
|
|
69409
|
+
const resolved = path88.resolve(path88.dirname(shimPath), target);
|
|
69410
|
+
const expected = path88.join(
|
|
69065
69411
|
prefix,
|
|
69066
69412
|
"node_modules",
|
|
69067
69413
|
pkgName,
|
|
@@ -69100,7 +69446,7 @@ function checkNode(pkg) {
|
|
|
69100
69446
|
return OK(`node ${raw}`);
|
|
69101
69447
|
}
|
|
69102
69448
|
function checkBundle() {
|
|
69103
|
-
const bundle =
|
|
69449
|
+
const bundle = path88.join(packageRoot, "dist", "cli", "main.bundled.js");
|
|
69104
69450
|
if (!existsSync55(bundle)) {
|
|
69105
69451
|
return FAIL(
|
|
69106
69452
|
`dist/cli/main.bundled.js missing at ${bundle}
|
|
@@ -69121,7 +69467,7 @@ function checkRuntimeDeps() {
|
|
|
69121
69467
|
const missing = [];
|
|
69122
69468
|
for (const dep of required2) {
|
|
69123
69469
|
try {
|
|
69124
|
-
const localReq = createRequire3(
|
|
69470
|
+
const localReq = createRequire3(path88.join(packageRoot, "package.json"));
|
|
69125
69471
|
localReq.resolve(dep);
|
|
69126
69472
|
} catch {
|
|
69127
69473
|
missing.push(dep);
|
|
@@ -69321,7 +69667,7 @@ var init_doctor = __esm({
|
|
|
69321
69667
|
init_metrics3();
|
|
69322
69668
|
init_contextGrowthSummary();
|
|
69323
69669
|
require3 = createRequire3(import.meta.url);
|
|
69324
|
-
__dirname3 =
|
|
69670
|
+
__dirname3 = path88.dirname(fileURLToPath3(import.meta.url));
|
|
69325
69671
|
packageRoot = findPackageRoot(__dirname3);
|
|
69326
69672
|
OK = (message) => ({
|
|
69327
69673
|
ok: true,
|
|
@@ -69505,15 +69851,15 @@ __export(inspect_exports, {
|
|
|
69505
69851
|
collectInspectReport: () => collectInspectReport,
|
|
69506
69852
|
runInspect: () => runInspect
|
|
69507
69853
|
});
|
|
69508
|
-
import
|
|
69854
|
+
import path89 from "node:path";
|
|
69509
69855
|
import { existsSync as existsSync56, readFileSync as readFileSync43, readdirSync as readdirSync12 } from "node:fs";
|
|
69510
69856
|
import { homedir as homedir17 } from "node:os";
|
|
69511
69857
|
async function collectInspectReport(cwd = process.cwd()) {
|
|
69512
69858
|
ensureBuiltinSkillsLoadedSync();
|
|
69513
69859
|
const snap = listSkillsSnapshot(cwd);
|
|
69514
69860
|
const mcp = listMcpServers(cwd);
|
|
69515
|
-
const userMcpPath =
|
|
69516
|
-
const projectMcpPath =
|
|
69861
|
+
const userMcpPath = path89.join(homedir17(), ".zelari-code", "mcp.json");
|
|
69862
|
+
const projectMcpPath = path89.join(cwd, ".zelari", "mcp.json");
|
|
69517
69863
|
const globalHooks = globalHooksDir();
|
|
69518
69864
|
const projectHooks = projectHooksDir(cwd);
|
|
69519
69865
|
const projectTrusted = isFolderTrusted(cwd);
|
|
@@ -69541,9 +69887,9 @@ async function collectInspectReport(cwd = process.cwd()) {
|
|
|
69541
69887
|
configSources: [
|
|
69542
69888
|
{ path: userMcpPath, exists: existsSync56(userMcpPath) },
|
|
69543
69889
|
{ path: projectMcpPath, exists: existsSync56(projectMcpPath) },
|
|
69544
|
-
{ path:
|
|
69545
|
-
{ path:
|
|
69546
|
-
{ path:
|
|
69890
|
+
{ path: path89.join(homedir17(), ".zelari-code", "provider.json"), exists: existsSync56(path89.join(homedir17(), ".zelari-code", "provider.json")) },
|
|
69891
|
+
{ path: path89.join(cwd, ".zelari", "AGENTS.md"), exists: existsSync56(path89.join(cwd, ".zelari", "AGENTS.md")) },
|
|
69892
|
+
{ path: path89.join(cwd, "AGENTS.md"), exists: existsSync56(path89.join(cwd, "AGENTS.md")) }
|
|
69547
69893
|
],
|
|
69548
69894
|
skills: {
|
|
69549
69895
|
total: snap.skills.length,
|
|
@@ -69583,8 +69929,8 @@ function listJsonFiles(dir) {
|
|
|
69583
69929
|
}
|
|
69584
69930
|
function findAgentsMd(cwd) {
|
|
69585
69931
|
const candidates = [
|
|
69586
|
-
|
|
69587
|
-
|
|
69932
|
+
path89.join(cwd, "AGENTS.md"),
|
|
69933
|
+
path89.join(cwd, ".zelari", "AGENTS.md")
|
|
69588
69934
|
];
|
|
69589
69935
|
const found = [];
|
|
69590
69936
|
for (const c of candidates) {
|
|
@@ -72709,6 +73055,7 @@ init_completionGate();
|
|
|
72709
73055
|
init_verificationBridge();
|
|
72710
73056
|
init_completionProof();
|
|
72711
73057
|
init_nativeVerification();
|
|
73058
|
+
init_spineTelemetry();
|
|
72712
73059
|
|
|
72713
73060
|
// src/cli/hooks/permissionPicker.ts
|
|
72714
73061
|
init_toolPermissions();
|
|
@@ -72912,8 +73259,14 @@ function useChatTurn(params) {
|
|
|
72912
73259
|
try {
|
|
72913
73260
|
const memoryFactory = await Promise.resolve().then(() => (init_serviceFactory(), serviceFactory_exports));
|
|
72914
73261
|
if (memoryFactory.isMemoryV2Enabled()) {
|
|
73262
|
+
const tuiSpineHolder = {
|
|
73263
|
+
get current() {
|
|
73264
|
+
return writerRef.current?.spine;
|
|
73265
|
+
}
|
|
73266
|
+
};
|
|
72915
73267
|
memoryService = await memoryFactory.getMemoryService(process.cwd(), process.env, {
|
|
72916
|
-
onWarning: (warning) => appendSystem(setMessages, warning, Date.now())
|
|
73268
|
+
onWarning: (warning) => appendSystem(setMessages, warning, Date.now()),
|
|
73269
|
+
onEvent: memorySinkFor(tuiSpineHolder)
|
|
72917
73270
|
});
|
|
72918
73271
|
memoryAutoWrite = memoryFactory.isMemoryAutoWriteEnabled();
|
|
72919
73272
|
}
|
|
@@ -73880,8 +74233,14 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il membro riprende dop
|
|
|
73880
74233
|
try {
|
|
73881
74234
|
const memoryFactory = await Promise.resolve().then(() => (init_serviceFactory(), serviceFactory_exports));
|
|
73882
74235
|
if (memoryFactory.isMemoryV2Enabled()) {
|
|
74236
|
+
const councilSpineHolder = {
|
|
74237
|
+
get current() {
|
|
74238
|
+
return writerRef.current?.spine;
|
|
74239
|
+
}
|
|
74240
|
+
};
|
|
73883
74241
|
councilMemory = await memoryFactory.getMemoryService(process.cwd(), process.env, {
|
|
73884
|
-
onWarning: (warning) => appendSystem(setMessages, warning, Date.now())
|
|
74242
|
+
onWarning: (warning) => appendSystem(setMessages, warning, Date.now()),
|
|
74243
|
+
onEvent: memorySinkFor(councilSpineHolder)
|
|
73885
74244
|
});
|
|
73886
74245
|
councilMemoryAutoWrite = memoryFactory.isMemoryAutoWriteEnabled();
|
|
73887
74246
|
if (!overrides.ragContext) {
|
|
@@ -74490,7 +74849,12 @@ async function runZelariMissionInTui(userMessage, deps, emit) {
|
|
|
74490
74849
|
userMessage,
|
|
74491
74850
|
hasPlan: hasWorkspacePlan2(projectRoot)
|
|
74492
74851
|
});
|
|
74493
|
-
const
|
|
74852
|
+
const missionSpineHolder = {
|
|
74853
|
+
get current() {
|
|
74854
|
+
return deps.writerRef.current?.spine;
|
|
74855
|
+
}
|
|
74856
|
+
};
|
|
74857
|
+
const memory = await getMemoryBackend2(projectRoot, process.env, memorySinkFor(missionSpineHolder));
|
|
74494
74858
|
const chairmanBudget = envNumber(process.env.ZELARI_MODE_MAX_TOOLS_LUCIFER, {
|
|
74495
74859
|
default: 30,
|
|
74496
74860
|
min: 1
|
|
@@ -75735,11 +76099,11 @@ function handleCacheStats(ctx) {
|
|
|
75735
76099
|
init_messageHelpers();
|
|
75736
76100
|
init_serviceFactory();
|
|
75737
76101
|
import { promises as fs31 } from "node:fs";
|
|
75738
|
-
import * as
|
|
76102
|
+
import * as path67 from "node:path";
|
|
75739
76103
|
|
|
75740
76104
|
// src/cli/memory/promotion.ts
|
|
75741
76105
|
import { promises as fs30 } from "node:fs";
|
|
75742
|
-
import * as
|
|
76106
|
+
import * as path66 from "node:path";
|
|
75743
76107
|
var START = "<!-- zelari:memory-promotions:start -->";
|
|
75744
76108
|
var END = "<!-- zelari:memory-promotions:end -->";
|
|
75745
76109
|
var DURABLE_KINDS = /* @__PURE__ */ new Set(["fact", "decision", "constraint", "preference", "procedure"]);
|
|
@@ -75750,13 +76114,13 @@ function lineFor(node) {
|
|
|
75750
76114
|
}
|
|
75751
76115
|
async function promoteMemoryToAgentsMd(projectRoot, node) {
|
|
75752
76116
|
if (node.status !== "active") {
|
|
75753
|
-
return { added: false, path:
|
|
76117
|
+
return { added: false, path: path66.join(projectRoot, "AGENTS.md"), reason: `memory is ${node.status}` };
|
|
75754
76118
|
}
|
|
75755
76119
|
if (!DURABLE_KINDS.has(node.kind)) {
|
|
75756
|
-
return { added: false, path:
|
|
76120
|
+
return { added: false, path: path66.join(projectRoot, "AGENTS.md"), reason: `${node.kind} is not a durable instruction kind` };
|
|
75757
76121
|
}
|
|
75758
|
-
const root = await fs30.realpath(projectRoot).catch(() =>
|
|
75759
|
-
const target =
|
|
76122
|
+
const root = await fs30.realpath(projectRoot).catch(() => path66.resolve(projectRoot));
|
|
76123
|
+
const target = path66.join(root, "AGENTS.md");
|
|
75760
76124
|
try {
|
|
75761
76125
|
const stat7 = await fs30.lstat(target);
|
|
75762
76126
|
if (stat7.isSymbolicLink() || !stat7.isFile()) throw new Error("AGENTS.md must be a regular project file.");
|
|
@@ -75821,22 +76185,22 @@ function sourceLine(source2) {
|
|
|
75821
76185
|
return entries.length ? entries.map(([key, value]) => `${key}=${value}`).join(" \xB7 ") : "unknown";
|
|
75822
76186
|
}
|
|
75823
76187
|
function isInside(root, target) {
|
|
75824
|
-
const relative6 =
|
|
75825
|
-
return relative6 === "" || !relative6.startsWith("..") && !
|
|
76188
|
+
const relative6 = path67.relative(root, target);
|
|
76189
|
+
return relative6 === "" || !relative6.startsWith("..") && !path67.isAbsolute(relative6);
|
|
75826
76190
|
}
|
|
75827
76191
|
async function safeExportPath(cwd, requested) {
|
|
75828
|
-
const lexicalRoot =
|
|
76192
|
+
const lexicalRoot = path67.resolve(cwd);
|
|
75829
76193
|
const root = await fs31.realpath(lexicalRoot).catch(() => lexicalRoot);
|
|
75830
|
-
const fallback =
|
|
75831
|
-
const target = requested?.trim() ?
|
|
76194
|
+
const fallback = path67.join(root, ".zelari", "memory", `export-${Date.now()}.json`);
|
|
76195
|
+
const target = requested?.trim() ? path67.resolve(root, requested.trim()) : fallback;
|
|
75832
76196
|
if (!isInside(root, target)) {
|
|
75833
76197
|
throw new Error("Export path must stay inside the active project.");
|
|
75834
76198
|
}
|
|
75835
|
-
const parent =
|
|
75836
|
-
const relativeParent =
|
|
76199
|
+
const parent = path67.dirname(target);
|
|
76200
|
+
const relativeParent = path67.relative(root, parent);
|
|
75837
76201
|
let cursor = root;
|
|
75838
|
-
for (const segment of relativeParent.split(
|
|
75839
|
-
cursor =
|
|
76202
|
+
for (const segment of relativeParent.split(path67.sep).filter(Boolean)) {
|
|
76203
|
+
cursor = path67.join(cursor, segment);
|
|
75840
76204
|
try {
|
|
75841
76205
|
const stat7 = await fs31.lstat(cursor);
|
|
75842
76206
|
if (stat7.isSymbolicLink()) {
|
|
@@ -76008,9 +76372,9 @@ ${message}` : message
|
|
|
76008
76372
|
}
|
|
76009
76373
|
case "export": {
|
|
76010
76374
|
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(
|
|
76375
|
+
await fs31.mkdir(path67.dirname(target), { recursive: true });
|
|
76376
|
+
const root = await fs31.realpath(ctx.cwd).catch(() => path67.resolve(ctx.cwd));
|
|
76377
|
+
const realParent = await fs31.realpath(path67.dirname(target));
|
|
76014
76378
|
if (!isInside(root, realParent)) {
|
|
76015
76379
|
throw new Error("Export path resolves outside the active project.");
|
|
76016
76380
|
}
|
|
@@ -76128,6 +76492,7 @@ init_graphMemory();
|
|
|
76128
76492
|
init_executor();
|
|
76129
76493
|
init_graphStatus();
|
|
76130
76494
|
init_serviceFactory();
|
|
76495
|
+
init_spineTelemetry();
|
|
76131
76496
|
async function handleKrakenGraph(ctx, prompt) {
|
|
76132
76497
|
if (!isKrakenGraphEnabled()) {
|
|
76133
76498
|
appendSystem(
|
|
@@ -76141,8 +76506,14 @@ async function handleKrakenGraph(ctx, prompt) {
|
|
|
76141
76506
|
return;
|
|
76142
76507
|
}
|
|
76143
76508
|
appendSystem(ctx.setMessages, `[kraken] planning graph for: ${prompt.trim()}`);
|
|
76509
|
+
const tuiSpineHolder = {
|
|
76510
|
+
get current() {
|
|
76511
|
+
return ctx.writerRef?.current?.spine ?? void 0;
|
|
76512
|
+
}
|
|
76513
|
+
};
|
|
76144
76514
|
const memory = isMemoryV2Enabled() ? await getMemoryService(ctx.cwd, process.env, {
|
|
76145
|
-
onWarning: (warning) => appendSystem(ctx.setMessages, warning)
|
|
76515
|
+
onWarning: (warning) => appendSystem(ctx.setMessages, warning),
|
|
76516
|
+
onEvent: memorySinkFor(tuiSpineHolder)
|
|
76146
76517
|
}) : void 0;
|
|
76147
76518
|
const audit = new AuditLogger();
|
|
76148
76519
|
const taskToolDeps = {
|
|
@@ -76206,7 +76577,7 @@ import { promises as fs35 } from "node:fs";
|
|
|
76206
76577
|
init_zod();
|
|
76207
76578
|
init_taskTool();
|
|
76208
76579
|
import { promises as fs34 } from "node:fs";
|
|
76209
|
-
import
|
|
76580
|
+
import path72 from "node:path";
|
|
76210
76581
|
import { randomBytes as randomBytes6 } from "node:crypto";
|
|
76211
76582
|
var CsvFanoutArgsSchema = external_exports.object({
|
|
76212
76583
|
csv_path: external_exports.string().min(1),
|
|
@@ -76300,8 +76671,8 @@ function resolveMaxConcurrency(env = process.env) {
|
|
|
76300
76671
|
}
|
|
76301
76672
|
async function runCsvFanout(args, deps, opts) {
|
|
76302
76673
|
const start = Date.now();
|
|
76303
|
-
const absCsv =
|
|
76304
|
-
const absOut =
|
|
76674
|
+
const absCsv = path72.isAbsolute(args.csv_path) ? args.csv_path : path72.join(opts.parentCwd, args.csv_path);
|
|
76675
|
+
const absOut = path72.isAbsolute(args.output_csv_path) ? args.output_csv_path : path72.join(opts.parentCwd, args.output_csv_path);
|
|
76305
76676
|
const { headers: headers2, rows } = await readCsv(absCsv);
|
|
76306
76677
|
if (headers2.length === 0) {
|
|
76307
76678
|
throw new Error(`kraken_csv_fanout: ${absCsv} is empty`);
|
|
@@ -76357,7 +76728,7 @@ async function runCsvFanout(args, deps, opts) {
|
|
|
76357
76728
|
errored += 1;
|
|
76358
76729
|
errors.push(`${row[args.id_column] ?? i}: ${res.error}`);
|
|
76359
76730
|
}
|
|
76360
|
-
await fs34.mkdir(
|
|
76731
|
+
await fs34.mkdir(path72.dirname(absOut), { recursive: true });
|
|
76361
76732
|
await queueWrite(serializeCsv(outHeaders, outputRecords));
|
|
76362
76733
|
}
|
|
76363
76734
|
}
|
|
@@ -76552,7 +76923,7 @@ function splitArgs(s) {
|
|
|
76552
76923
|
// src/cli/slashHandlers/krakenWorkbench.ts
|
|
76553
76924
|
init_messageHelpers();
|
|
76554
76925
|
import { promises as fs36 } from "node:fs";
|
|
76555
|
-
import
|
|
76926
|
+
import path73 from "node:path";
|
|
76556
76927
|
|
|
76557
76928
|
// src/cli/kraken/workbenchView.ts
|
|
76558
76929
|
var EMPTY = {
|
|
@@ -76669,14 +77040,14 @@ function formatWorkbenchForTerminal(p3) {
|
|
|
76669
77040
|
|
|
76670
77041
|
// src/cli/slashHandlers/krakenWorkbench.ts
|
|
76671
77042
|
async function handleKrakenWorkbench(ctx) {
|
|
76672
|
-
const dir =
|
|
77043
|
+
const dir = path73.join(ctx.cwd, ".zelari", "radio");
|
|
76673
77044
|
let latest = null;
|
|
76674
77045
|
let latestMtime = 0;
|
|
76675
77046
|
try {
|
|
76676
77047
|
const files = await fs36.readdir(dir);
|
|
76677
77048
|
for (const f of files) {
|
|
76678
77049
|
if (!f.startsWith("workbench-") || !f.endsWith(".md")) continue;
|
|
76679
|
-
const full =
|
|
77050
|
+
const full = path73.join(dir, f);
|
|
76680
77051
|
const stat7 = await fs36.stat(full);
|
|
76681
77052
|
if (stat7.mtimeMs > latestMtime) {
|
|
76682
77053
|
latestMtime = stat7.mtimeMs;
|
|
@@ -76693,10 +77064,10 @@ async function handleKrakenWorkbench(ctx) {
|
|
|
76693
77064
|
const parsed = parseWorkbench(content);
|
|
76694
77065
|
const rendered = formatWorkbenchForTerminal(parsed);
|
|
76695
77066
|
if (!rendered.trim()) {
|
|
76696
|
-
appendSystem(ctx.setMessages, `[kraken workbench] ${
|
|
77067
|
+
appendSystem(ctx.setMessages, `[kraken workbench] ${path73.basename(latest)}: (no nodes / no events yet)`);
|
|
76697
77068
|
return;
|
|
76698
77069
|
}
|
|
76699
|
-
appendSystem(ctx.setMessages, `[kraken workbench] ${
|
|
77070
|
+
appendSystem(ctx.setMessages, `[kraken workbench] ${path73.basename(latest)}:
|
|
76700
77071
|
${rendered}`);
|
|
76701
77072
|
}
|
|
76702
77073
|
|
|
@@ -77003,15 +77374,15 @@ ${result.output.split("\n").slice(-8).join("\n")}` : "";
|
|
|
77003
77374
|
// src/cli/slashHandlers/promoteMember.ts
|
|
77004
77375
|
init_messageHelpers();
|
|
77005
77376
|
import { promises as fs37 } from "node:fs";
|
|
77006
|
-
import
|
|
77377
|
+
import path76 from "node:path";
|
|
77007
77378
|
import os12 from "node:os";
|
|
77008
77379
|
async function handlePromoteMember(ctx, memberId) {
|
|
77009
77380
|
try {
|
|
77010
77381
|
const { promoteMember: promoteMember2 } = await Promise.resolve().then(() => (init_council(), council_exports));
|
|
77011
77382
|
const { skill, markdown } = promoteMember2(memberId);
|
|
77012
|
-
const skillDir = process.env.ANATHEMA_SKILL_DIR ??
|
|
77383
|
+
const skillDir = process.env.ANATHEMA_SKILL_DIR ?? path76.join(os12.homedir(), ".tmp", "zelari-code", "skills");
|
|
77013
77384
|
await fs37.mkdir(skillDir, { recursive: true });
|
|
77014
|
-
const filePath =
|
|
77385
|
+
const filePath = path76.join(skillDir, `${skill.id}.md`);
|
|
77015
77386
|
await fs37.writeFile(filePath, markdown, "utf8");
|
|
77016
77387
|
appendSystem(
|
|
77017
77388
|
ctx.setMessages,
|
|
@@ -77029,24 +77400,24 @@ async function handlePromoteMember(ctx, memberId) {
|
|
|
77029
77400
|
|
|
77030
77401
|
// src/cli/branchManager.ts
|
|
77031
77402
|
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
|
|
77403
|
+
import path77 from "node:path";
|
|
77033
77404
|
import os13 from "node:os";
|
|
77034
77405
|
var META_FILENAME = "meta.json";
|
|
77035
77406
|
var SESSIONS_SUBDIR = "sessions";
|
|
77036
77407
|
function getBranchesBaseDir() {
|
|
77037
|
-
return process.env.ANATHEMA_BRANCHES_DIR ??
|
|
77408
|
+
return process.env.ANATHEMA_BRANCHES_DIR ?? path77.join(os13.homedir(), ".tmp", "zelari-code", "branches");
|
|
77038
77409
|
}
|
|
77039
77410
|
function getSessionsBaseDir() {
|
|
77040
|
-
return process.env.ANATHEMA_SESSIONS_DIR ??
|
|
77411
|
+
return process.env.ANATHEMA_SESSIONS_DIR ?? path77.join(os13.homedir(), ".tmp", "zelari-code", "sessions");
|
|
77041
77412
|
}
|
|
77042
77413
|
function branchPathFor(name, baseDir) {
|
|
77043
|
-
return
|
|
77414
|
+
return path77.join(baseDir, name);
|
|
77044
77415
|
}
|
|
77045
77416
|
function metaPathFor(name, baseDir) {
|
|
77046
|
-
return
|
|
77417
|
+
return path77.join(baseDir, name, META_FILENAME);
|
|
77047
77418
|
}
|
|
77048
77419
|
function sessionsPathFor(name, baseDir) {
|
|
77049
|
-
return
|
|
77420
|
+
return path77.join(baseDir, name, SESSIONS_SUBDIR);
|
|
77050
77421
|
}
|
|
77051
77422
|
function readBranchMeta(name, baseDir) {
|
|
77052
77423
|
const metaPath = metaPathFor(name, baseDir);
|
|
@@ -77071,7 +77442,7 @@ function readBranchMeta(name, baseDir) {
|
|
|
77071
77442
|
}
|
|
77072
77443
|
function writeBranchMeta(name, baseDir, meta3) {
|
|
77073
77444
|
const metaPath = metaPathFor(name, baseDir);
|
|
77074
|
-
mkdirSync19(
|
|
77445
|
+
mkdirSync19(path77.dirname(metaPath), { recursive: true });
|
|
77075
77446
|
writeFileSync23(metaPath, JSON.stringify(meta3, null, 2), "utf-8");
|
|
77076
77447
|
}
|
|
77077
77448
|
async function countSessions(name, baseDir) {
|
|
@@ -77122,14 +77493,14 @@ async function createBranch(name, fromSessionId, baseDir = getBranchesBaseDir(),
|
|
|
77122
77493
|
if (branchExists(name, baseDir)) {
|
|
77123
77494
|
throw new BranchAlreadyExistsError(name);
|
|
77124
77495
|
}
|
|
77125
|
-
const sourcePath =
|
|
77496
|
+
const sourcePath = path77.join(sessionsBaseDir, `${fromSessionId}.jsonl`);
|
|
77126
77497
|
if (!existsSync48(sourcePath)) {
|
|
77127
77498
|
throw new SessionNotFoundError(`Source session "${fromSessionId}" not found at ${sourcePath}`);
|
|
77128
77499
|
}
|
|
77129
77500
|
const branchPath = branchPathFor(name, baseDir);
|
|
77130
77501
|
const branchSessionsPath = sessionsPathFor(name, baseDir);
|
|
77131
77502
|
mkdirSync19(branchSessionsPath, { recursive: true });
|
|
77132
|
-
const destPath =
|
|
77503
|
+
const destPath = path77.join(branchSessionsPath, `${fromSessionId}.jsonl`);
|
|
77133
77504
|
await fs38.copyFile(sourcePath, destPath);
|
|
77134
77505
|
const meta3 = {
|
|
77135
77506
|
name,
|
|
@@ -77233,14 +77604,14 @@ async function handleBranchCheckout(ctx, branchName) {
|
|
|
77233
77604
|
// src/cli/slashHandlers/workspace.ts
|
|
77234
77605
|
init_messageHelpers();
|
|
77235
77606
|
import { promises as fs39 } from "node:fs";
|
|
77236
|
-
import
|
|
77607
|
+
import path78 from "node:path";
|
|
77237
77608
|
async function handleWorkspaceShow(ctx, what) {
|
|
77238
77609
|
try {
|
|
77239
|
-
const zelari =
|
|
77610
|
+
const zelari = path78.join(process.cwd(), ".zelari");
|
|
77240
77611
|
let content;
|
|
77241
77612
|
switch (what) {
|
|
77242
77613
|
case "plan": {
|
|
77243
|
-
const planPath =
|
|
77614
|
+
const planPath = path78.join(zelari, "plan.md");
|
|
77244
77615
|
try {
|
|
77245
77616
|
content = await fs39.readFile(planPath, "utf-8");
|
|
77246
77617
|
} catch {
|
|
@@ -77249,7 +77620,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
77249
77620
|
break;
|
|
77250
77621
|
}
|
|
77251
77622
|
case "decisions": {
|
|
77252
|
-
const decisionsDir =
|
|
77623
|
+
const decisionsDir = path78.join(zelari, "decisions");
|
|
77253
77624
|
try {
|
|
77254
77625
|
const files = (await fs39.readdir(decisionsDir)).filter((f) => f.endsWith(".md")).sort();
|
|
77255
77626
|
if (files.length === 0) {
|
|
@@ -77259,7 +77630,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
77259
77630
|
`];
|
|
77260
77631
|
const { parseFrontmatter: parseFrontmatter2 } = await Promise.resolve().then(() => (init_storage(), storage_exports));
|
|
77261
77632
|
for (const f of files) {
|
|
77262
|
-
const raw = await fs39.readFile(
|
|
77633
|
+
const raw = await fs39.readFile(path78.join(decisionsDir, f), "utf-8");
|
|
77263
77634
|
const { meta: meta3, body } = parseFrontmatter2(raw);
|
|
77264
77635
|
const title = meta3.title ?? body.split("\n")[0]?.replace(/^#\s*/, "").trim() ?? f;
|
|
77265
77636
|
lines.push(`- **${f.replace(/\.md$/, "")}** [${meta3.status ?? "unknown"}] ${title}`);
|
|
@@ -77272,7 +77643,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
77272
77643
|
break;
|
|
77273
77644
|
}
|
|
77274
77645
|
case "risks": {
|
|
77275
|
-
const risksPath =
|
|
77646
|
+
const risksPath = path78.join(zelari, "risks.md");
|
|
77276
77647
|
try {
|
|
77277
77648
|
content = await fs39.readFile(risksPath, "utf-8");
|
|
77278
77649
|
} catch {
|
|
@@ -77281,7 +77652,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
77281
77652
|
break;
|
|
77282
77653
|
}
|
|
77283
77654
|
case "agents": {
|
|
77284
|
-
const agentsPath =
|
|
77655
|
+
const agentsPath = path78.join(process.cwd(), "AGENTS.MD");
|
|
77285
77656
|
try {
|
|
77286
77657
|
content = await fs39.readFile(agentsPath, "utf-8");
|
|
77287
77658
|
} catch {
|
|
@@ -77290,7 +77661,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
77290
77661
|
break;
|
|
77291
77662
|
}
|
|
77292
77663
|
case "docs": {
|
|
77293
|
-
const docsDir =
|
|
77664
|
+
const docsDir = path78.join(zelari, "docs");
|
|
77294
77665
|
try {
|
|
77295
77666
|
const files = (await fs39.readdir(docsDir)).filter((f) => f.endsWith(".md")).sort();
|
|
77296
77667
|
content = files.length ? `# Docs (${files.length})
|
|
@@ -77332,7 +77703,7 @@ async function handleWorkspaceReset(ctx, force) {
|
|
|
77332
77703
|
return;
|
|
77333
77704
|
}
|
|
77334
77705
|
try {
|
|
77335
|
-
const target =
|
|
77706
|
+
const target = path78.join(process.cwd(), ".zelari");
|
|
77336
77707
|
await fs39.rm(target, { recursive: true, force: true });
|
|
77337
77708
|
appendSystem(ctx.setMessages, "[workspace] .zelari/ removed");
|
|
77338
77709
|
} catch (err) {
|
|
@@ -77344,7 +77715,7 @@ async function handleWorkspaceReset(ctx, force) {
|
|
|
77344
77715
|
init_provider2();
|
|
77345
77716
|
|
|
77346
77717
|
// src/cli/slashHandlers/skills.ts
|
|
77347
|
-
import
|
|
77718
|
+
import path79 from "node:path";
|
|
77348
77719
|
import os14 from "node:os";
|
|
77349
77720
|
|
|
77350
77721
|
// src/cli/skillHistory.ts
|
|
@@ -77473,7 +77844,7 @@ function handleSkillPicker(ctx, skills, openPicker, fallbackMessage) {
|
|
|
77473
77844
|
});
|
|
77474
77845
|
}
|
|
77475
77846
|
async function handleSkillStats(ctx, skillId) {
|
|
77476
|
-
const historyFile = process.env.ANATHEMA_SKILL_HISTORY_FILE ??
|
|
77847
|
+
const historyFile = process.env.ANATHEMA_SKILL_HISTORY_FILE ?? path79.join(os14.homedir(), ".tmp", "zelari-code", "skill-history.jsonl");
|
|
77477
77848
|
try {
|
|
77478
77849
|
const records = await readSkillHistory(historyFile);
|
|
77479
77850
|
const stats = getSkillStats(records, skillId);
|
|
@@ -77489,7 +77860,7 @@ async function handleSkillCompare(ctx, ids, fallbackMessage) {
|
|
|
77489
77860
|
appendSystem(ctx.setMessages, fallbackMessage ?? "[skill-compare] missing args");
|
|
77490
77861
|
return;
|
|
77491
77862
|
}
|
|
77492
|
-
const historyFile = process.env.ANATHEMA_SKILL_HISTORY_FILE ??
|
|
77863
|
+
const historyFile = process.env.ANATHEMA_SKILL_HISTORY_FILE ?? path79.join(os14.homedir(), ".tmp", "zelari-code", "skill-history.jsonl");
|
|
77493
77864
|
try {
|
|
77494
77865
|
const formatted = await compareSkillsFromFile(ids[0], ids[1], historyFile);
|
|
77495
77866
|
appendSystem(ctx.setMessages, formatted);
|
|
@@ -77945,7 +78316,10 @@ function useSlashDispatch(params) {
|
|
|
77945
78316
|
}
|
|
77946
78317
|
if (result.kind === "kraken_graph") {
|
|
77947
78318
|
const sid = (sessionId2 || "default").trim();
|
|
77948
|
-
await handleKrakenGraph(
|
|
78319
|
+
await handleKrakenGraph(
|
|
78320
|
+
{ setMessages, cwd: process.cwd(), sessionId: sid, writerRef: params.writerRef },
|
|
78321
|
+
result.graphPrompt ?? ""
|
|
78322
|
+
);
|
|
77949
78323
|
return;
|
|
77950
78324
|
}
|
|
77951
78325
|
if (result.kind === "kraken_fanout") {
|
|
@@ -78282,6 +78656,9 @@ function App() {
|
|
|
78282
78656
|
sessionId: session.sessionId,
|
|
78283
78657
|
messages: session.messages,
|
|
78284
78658
|
setMessages: session.setMessages,
|
|
78659
|
+
// W2: same writer ref passed to useChatTurn — lets /kraken graph project
|
|
78660
|
+
// memory events onto the session spine mirror.
|
|
78661
|
+
writerRef: session.writerRef,
|
|
78285
78662
|
setInput,
|
|
78286
78663
|
setBusy,
|
|
78287
78664
|
setSessionId: session.setSessionId,
|
|
@@ -79184,8 +79561,8 @@ function normalizeDraft(raw, sourceUrl, provider, model) {
|
|
|
79184
79561
|
let name = String(o.name ?? "").trim().toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64);
|
|
79185
79562
|
if (!name || !/^[a-z0-9][a-z0-9-]{0,63}$/.test(name)) {
|
|
79186
79563
|
try {
|
|
79187
|
-
const
|
|
79188
|
-
name =
|
|
79564
|
+
const path90 = new URL(sourceUrl).pathname.split("/").filter(Boolean).pop()?.replace(/\.[a-z0-9]+$/i, "").toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48);
|
|
79565
|
+
name = path90 && /^[a-z0-9]/.test(path90) ? path90 : "imported-skill";
|
|
79189
79566
|
} catch {
|
|
79190
79567
|
name = "imported-skill";
|
|
79191
79568
|
}
|