zelari-code 2.16.4 → 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 +849 -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 +122 -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);
|
|
@@ -65285,6 +65559,7 @@ async function dispatchHeadlessTurn(opts, provider, model, providerStream) {
|
|
|
65285
65559
|
opts = { ...opts, cwd };
|
|
65286
65560
|
}
|
|
65287
65561
|
applyKrakenTurnEnv(opts);
|
|
65562
|
+
resetTaskSpawnCount();
|
|
65288
65563
|
if (opts.todos && opts.todos.length > 0) {
|
|
65289
65564
|
writeSessionTodos(opts.todos, { merge: false });
|
|
65290
65565
|
}
|
|
@@ -65303,8 +65578,10 @@ async function dispatchHeadlessTurn(opts, provider, model, providerStream) {
|
|
|
65303
65578
|
}
|
|
65304
65579
|
} catch {
|
|
65305
65580
|
}
|
|
65306
|
-
|
|
65307
|
-
|
|
65581
|
+
if (!oneShot?.policyGateDone) {
|
|
65582
|
+
const policyBlock = await applyHeadlessPolicyGate(opts);
|
|
65583
|
+
if (policyBlock !== void 0) return policyBlock;
|
|
65584
|
+
}
|
|
65308
65585
|
if (opts.orchestrationAuto) {
|
|
65309
65586
|
const facts = await collectOrchestrationFacts(cwd);
|
|
65310
65587
|
const verdict = chooseOrchestration(opts.task ?? "", facts);
|
|
@@ -65346,12 +65623,12 @@ async function dispatchHeadlessTurn(opts, provider, model, providerStream) {
|
|
|
65346
65623
|
`);
|
|
65347
65624
|
}
|
|
65348
65625
|
if (mode === "zelari") {
|
|
65349
|
-
return runHeadlessZelari(opts, provider, model, providerStream);
|
|
65626
|
+
return runHeadlessZelari(opts, provider, model, providerStream, extras);
|
|
65350
65627
|
}
|
|
65351
65628
|
if (mode === "council" || opts.useCouncil) {
|
|
65352
|
-
return runHeadlessCouncil(opts, provider, model, providerStream);
|
|
65629
|
+
return runHeadlessCouncil(opts, provider, model, providerStream, extras);
|
|
65353
65630
|
}
|
|
65354
|
-
return runOneTurn(opts, provider, model, providerStream);
|
|
65631
|
+
return runOneTurn(opts, provider, model, providerStream, extras);
|
|
65355
65632
|
}
|
|
65356
65633
|
async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
65357
65634
|
const { isKrakenGraphEnabled: isKrakenGraphEnabled2, KrakenGraphExecutor: KrakenGraphExecutor2 } = await Promise.resolve().then(() => (init_executor(), executor_exports));
|
|
@@ -65371,8 +65648,15 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
65371
65648
|
const { createKrakenSubAgentContextFactory: createKrakenSubAgentContextFactory2 } = await Promise.resolve().then(() => (init_toolRegistry(), toolRegistry_exports));
|
|
65372
65649
|
const cwd = resolveHeadlessCwd(opts);
|
|
65373
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);
|
|
65374
65654
|
const { getMemoryService: getMemoryService2, isMemoryAutoWriteEnabled: isMemoryAutoWriteEnabled2, isMemoryV2Enabled: isMemoryV2Enabled2 } = await Promise.resolve().then(() => (init_serviceFactory(), serviceFactory_exports));
|
|
65375
|
-
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;
|
|
65376
65660
|
const log = (message) => {
|
|
65377
65661
|
if (opts.output === "json") {
|
|
65378
65662
|
emitEvent({ type: "log", message });
|
|
@@ -65387,28 +65671,32 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
65387
65671
|
abort.abort();
|
|
65388
65672
|
};
|
|
65389
65673
|
process.once("SIGINT", onSigint);
|
|
65674
|
+
let exitCode = 0;
|
|
65390
65675
|
try {
|
|
65391
65676
|
let preflightGraph;
|
|
65392
65677
|
if (opts.runPlan && opts.runPlan.trim() !== "") {
|
|
65393
|
-
const planPath =
|
|
65678
|
+
const planPath = path86.join(cwd, ".zelari", "radio", `plan-${opts.runPlan}.json`);
|
|
65394
65679
|
log(`loading pre-flight plan: ${planPath}`);
|
|
65395
65680
|
let raw;
|
|
65396
65681
|
try {
|
|
65397
65682
|
raw = await fs44.readFile(planPath, "utf8");
|
|
65398
65683
|
} catch (e) {
|
|
65399
65684
|
log(`plan file not found: ${planPath} (${e.message})`);
|
|
65400
|
-
|
|
65685
|
+
exitCode = 1;
|
|
65686
|
+
return exitCode;
|
|
65401
65687
|
}
|
|
65402
65688
|
let planJson;
|
|
65403
65689
|
try {
|
|
65404
65690
|
planJson = JSON.parse(raw);
|
|
65405
65691
|
} catch (e) {
|
|
65406
65692
|
log(`plan file is malformed JSON: ${e.message}`);
|
|
65407
|
-
|
|
65693
|
+
exitCode = 1;
|
|
65694
|
+
return exitCode;
|
|
65408
65695
|
}
|
|
65409
65696
|
if (!planJson || !Array.isArray(planJson.nodes)) {
|
|
65410
65697
|
log(`plan file is malformed: missing "nodes" array`);
|
|
65411
|
-
|
|
65698
|
+
exitCode = 1;
|
|
65699
|
+
return exitCode;
|
|
65412
65700
|
}
|
|
65413
65701
|
const { createGraph: createGraph2, validateGraph: validateGraph2 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
|
|
65414
65702
|
const validated = createGraph2(planJson.graphId ?? opts.runPlan, planJson.nodes);
|
|
@@ -65430,8 +65718,8 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
65430
65718
|
log(formatKrakenGraphAscii2(graph));
|
|
65431
65719
|
if (opts.planOnly) {
|
|
65432
65720
|
const planId = randomUUID10();
|
|
65433
|
-
const planDir =
|
|
65434
|
-
const planPath =
|
|
65721
|
+
const planDir = path86.join(cwd, ".zelari", "radio");
|
|
65722
|
+
const planPath = path86.join(planDir, `plan-${planId}.json`);
|
|
65435
65723
|
await fs44.mkdir(planDir, { recursive: true });
|
|
65436
65724
|
await fs44.writeFile(
|
|
65437
65725
|
planPath,
|
|
@@ -65450,7 +65738,8 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
65450
65738
|
emitEvent({ type: "log", message: `plan_only_id=${planId}` });
|
|
65451
65739
|
emitEvent({ type: "log", message: `plan_only_path=${planPath}` });
|
|
65452
65740
|
}
|
|
65453
|
-
|
|
65741
|
+
exitCode = 0;
|
|
65742
|
+
return exitCode;
|
|
65454
65743
|
}
|
|
65455
65744
|
const audit = new AuditLogger2();
|
|
65456
65745
|
const executor = new KrakenGraphExecutor2({
|
|
@@ -65507,7 +65796,8 @@ ${formatKrakenGraphDigest2(
|
|
|
65507
65796
|
process.stdout.write(`${finalAscii}
|
|
65508
65797
|
`);
|
|
65509
65798
|
}
|
|
65510
|
-
|
|
65799
|
+
exitCode = summary.converged ? 0 : 3;
|
|
65800
|
+
return exitCode;
|
|
65511
65801
|
} catch (err) {
|
|
65512
65802
|
const message = err instanceof Error ? err.message : String(err);
|
|
65513
65803
|
if (opts.output === "json") {
|
|
@@ -65516,17 +65806,25 @@ ${formatKrakenGraphDigest2(
|
|
|
65516
65806
|
process.stderr.write(`[zelari-code --headless] kraken graph failed: ${message}
|
|
65517
65807
|
`);
|
|
65518
65808
|
}
|
|
65519
|
-
|
|
65809
|
+
exitCode = 2;
|
|
65810
|
+
return exitCode;
|
|
65520
65811
|
} finally {
|
|
65521
65812
|
process.off("SIGINT", onSigint);
|
|
65522
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 });
|
|
65523
65820
|
}
|
|
65524
65821
|
}
|
|
65525
|
-
async function buildCouncilToolRegistry(planMode, opts, memoryService, memoryAutoWrite = false) {
|
|
65822
|
+
async function buildCouncilToolRegistry(planMode, opts, memoryService, memoryAutoWrite = false, extras) {
|
|
65526
65823
|
const cwd = opts ? resolveHeadlessCwd(opts) : process.cwd();
|
|
65527
65824
|
const { registry: toolRegistry } = createBuiltinToolRegistry({
|
|
65528
65825
|
root: cwd,
|
|
65529
65826
|
planMode,
|
|
65827
|
+
...extras?.lspProvider ? { lspProvider: extras.lspProvider } : {},
|
|
65530
65828
|
permissionPolicy: {
|
|
65531
65829
|
read: "allow",
|
|
65532
65830
|
write: "allow",
|
|
@@ -65553,12 +65851,15 @@ async function buildCouncilToolRegistry(planMode, opts, memoryService, memoryAut
|
|
|
65553
65851
|
}
|
|
65554
65852
|
return { toolRegistry, workspaceCtx: realCtx };
|
|
65555
65853
|
}
|
|
65556
|
-
async function runHeadlessCouncil(opts, provider, model, providerStream) {
|
|
65854
|
+
async function runHeadlessCouncil(opts, provider, model, providerStream, extras) {
|
|
65557
65855
|
const { dispatchCouncil: dispatchCouncil2 } = await Promise.resolve().then(() => (init_councilDispatcher(), councilDispatcher_exports));
|
|
65558
65856
|
const sessionId2 = crypto.randomUUID();
|
|
65559
65857
|
const cwd = resolveHeadlessCwd(opts);
|
|
65560
65858
|
const memoryFactory = await Promise.resolve().then(() => (init_serviceFactory(), serviceFactory_exports));
|
|
65561
|
-
const
|
|
65859
|
+
const spineHolder = {};
|
|
65860
|
+
const nativeMemory = memoryFactory.isMemoryV2Enabled() ? await memoryFactory.getMemoryService(cwd, process.env, {
|
|
65861
|
+
onEvent: memorySinkFor(spineHolder)
|
|
65862
|
+
}) : void 0;
|
|
65562
65863
|
const memoryAutoWrite = memoryFactory.isMemoryAutoWriteEnabled();
|
|
65563
65864
|
const spine = await openHeadlessSpine({
|
|
65564
65865
|
sessionId: opts.resumeSessionId ?? sessionId2,
|
|
@@ -65566,6 +65867,7 @@ async function runHeadlessCouncil(opts, provider, model, providerStream) {
|
|
|
65566
65867
|
profile: opts.profile,
|
|
65567
65868
|
workspace: cwd
|
|
65568
65869
|
});
|
|
65870
|
+
spineHolder.current = spine;
|
|
65569
65871
|
const seededHistory = await seedHeadlessModelHistory(spine, opts.history);
|
|
65570
65872
|
emitEvent(sessionStartedEvent(spine));
|
|
65571
65873
|
if (opts.orchestrationDecision) {
|
|
@@ -65585,7 +65887,8 @@ async function runHeadlessCouncil(opts, provider, model, providerStream) {
|
|
|
65585
65887
|
planModeFromOpts(opts) || softGated,
|
|
65586
65888
|
opts,
|
|
65587
65889
|
nativeMemory,
|
|
65588
|
-
memoryAutoWrite
|
|
65890
|
+
memoryAutoWrite,
|
|
65891
|
+
extras
|
|
65589
65892
|
);
|
|
65590
65893
|
const { FeedbackStore: FeedbackStore2 } = await Promise.resolve().then(() => (init_councilFeedback(), councilFeedback_exports));
|
|
65591
65894
|
const feedbackStore = new FeedbackStore2();
|
|
@@ -65714,13 +66017,14 @@ async function runHeadlessCouncil(opts, provider, model, providerStream) {
|
|
|
65714
66017
|
await spine.close(exitCode === 0 ? "completed" : "error");
|
|
65715
66018
|
} catch {
|
|
65716
66019
|
}
|
|
66020
|
+
await emitHarnessStateEvent({ spine, workspaceRoot: cwd, output: opts.output, emitEvent });
|
|
65717
66021
|
if (opts.exportSessionPath) {
|
|
65718
66022
|
try {
|
|
65719
66023
|
const json3 = await spine.exportJson();
|
|
65720
66024
|
if (json3) {
|
|
65721
66025
|
if (opts.exportSessionPath === "-") process.stdout.write(json3 + "\n");
|
|
65722
66026
|
else {
|
|
65723
|
-
await fs44.mkdir(
|
|
66027
|
+
await fs44.mkdir(path86.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
65724
66028
|
await fs44.writeFile(opts.exportSessionPath, json3, "utf8");
|
|
65725
66029
|
}
|
|
65726
66030
|
}
|
|
@@ -65753,7 +66057,7 @@ async function runHeadlessCouncil(opts, provider, model, providerStream) {
|
|
|
65753
66057
|
await nativeMemory?.close().catch(() => void 0);
|
|
65754
66058
|
return exitCode;
|
|
65755
66059
|
}
|
|
65756
|
-
async function runHeadlessZelari(opts, provider, model, providerStream) {
|
|
66060
|
+
async function runHeadlessZelari(opts, provider, model, providerStream, extras) {
|
|
65757
66061
|
const projectRoot = resolveHeadlessCwd(opts);
|
|
65758
66062
|
const sessionId2 = opts.resumeSessionId ?? crypto.randomUUID();
|
|
65759
66063
|
const spine = await openHeadlessSpine({
|
|
@@ -65776,13 +66080,18 @@ async function runHeadlessZelari(opts, provider, model, providerStream) {
|
|
|
65776
66080
|
userMessage: opts.task,
|
|
65777
66081
|
hasPlan: hasWorkspacePlan2(projectRoot)
|
|
65778
66082
|
});
|
|
65779
|
-
const memory = await getMemoryBackend2(
|
|
66083
|
+
const memory = await getMemoryBackend2(
|
|
66084
|
+
projectRoot,
|
|
66085
|
+
process.env,
|
|
66086
|
+
(event) => spineMemoryEventNote(spine, event)
|
|
66087
|
+
);
|
|
65780
66088
|
const nativeMissionMemory = memory.service;
|
|
65781
66089
|
const { toolRegistry, workspaceCtx } = await buildCouncilToolRegistry(
|
|
65782
66090
|
planModeFromOpts(opts),
|
|
65783
66091
|
opts,
|
|
65784
66092
|
nativeMissionMemory,
|
|
65785
|
-
Boolean(nativeMissionMemory) && process.env.ZELARI_MEMORY_AUTO_WRITE !== "0"
|
|
66093
|
+
Boolean(nativeMissionMemory) && process.env.ZELARI_MEMORY_AUTO_WRITE !== "0",
|
|
66094
|
+
extras
|
|
65786
66095
|
);
|
|
65787
66096
|
const feedbackStore = new FeedbackStore2();
|
|
65788
66097
|
const chairmanBudget = envNumber(process.env.ZELARI_MODE_MAX_TOOLS_LUCIFER, {
|
|
@@ -66095,6 +66404,8 @@ ${ragContext}` : slicePrompt;
|
|
|
66095
66404
|
const missionGate = await evaluateStrictBuildGate("build", {
|
|
66096
66405
|
emit: (input) => spine.appendEvent(input),
|
|
66097
66406
|
surface: "mission",
|
|
66407
|
+
// H10-fix1: per-invocation env overlay — never process.env.
|
|
66408
|
+
env: strictEnvOverlay(opts),
|
|
66098
66409
|
cwd: projectRoot
|
|
66099
66410
|
});
|
|
66100
66411
|
const missionVerificationPayload = strictGateEventPayload(missionGate);
|
|
@@ -66131,13 +66442,14 @@ ${ragContext}` : slicePrompt;
|
|
|
66131
66442
|
else await spine.close(exitCode === 2 ? "error" : "stopped");
|
|
66132
66443
|
} catch {
|
|
66133
66444
|
}
|
|
66445
|
+
await emitHarnessStateEvent({ spine, workspaceRoot: projectRoot, output: opts.output, emitEvent });
|
|
66134
66446
|
if (opts.exportSessionPath) {
|
|
66135
66447
|
try {
|
|
66136
66448
|
const json3 = await spine.exportJson();
|
|
66137
66449
|
if (json3) {
|
|
66138
66450
|
if (opts.exportSessionPath === "-") process.stdout.write(json3 + "\n");
|
|
66139
66451
|
else {
|
|
66140
|
-
await fs44.mkdir(
|
|
66452
|
+
await fs44.mkdir(path86.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
66141
66453
|
await fs44.writeFile(opts.exportSessionPath, json3, "utf8");
|
|
66142
66454
|
}
|
|
66143
66455
|
}
|
|
@@ -66156,6 +66468,7 @@ var init_runHeadless = __esm({
|
|
|
66156
66468
|
init_toolRegistry();
|
|
66157
66469
|
init_policy();
|
|
66158
66470
|
init_facts();
|
|
66471
|
+
init_spineTelemetry();
|
|
66159
66472
|
init_councilConfig();
|
|
66160
66473
|
init_headless();
|
|
66161
66474
|
init_claudeProvider();
|
|
@@ -66171,6 +66484,7 @@ var init_runHeadless = __esm({
|
|
|
66171
66484
|
init_modelContextBuilder();
|
|
66172
66485
|
init_metrics3();
|
|
66173
66486
|
init_headlessSpine();
|
|
66487
|
+
init_harnessStateEmit();
|
|
66174
66488
|
init_policyGate();
|
|
66175
66489
|
init_policyLoadMode();
|
|
66176
66490
|
init_runOneTurn();
|
|
@@ -66748,7 +67062,7 @@ function upsertSkill(opts) {
|
|
|
66748
67062
|
}
|
|
66749
67063
|
dir = getProjectSkillsDir(root);
|
|
66750
67064
|
}
|
|
66751
|
-
const
|
|
67065
|
+
const path90 = skillFilePath(dir, name);
|
|
66752
67066
|
const content = serializeSkillMd({
|
|
66753
67067
|
name,
|
|
66754
67068
|
description,
|
|
@@ -66757,13 +67071,13 @@ function upsertSkill(opts) {
|
|
|
66757
67071
|
tools: opts.tools,
|
|
66758
67072
|
cost: opts.cost
|
|
66759
67073
|
});
|
|
66760
|
-
const parsed = parseSkillMd(content,
|
|
67074
|
+
const parsed = parseSkillMd(content, path90);
|
|
66761
67075
|
if (!parsed) {
|
|
66762
67076
|
return { ok: false, error: "Generated SKILL.md failed validation" };
|
|
66763
67077
|
}
|
|
66764
|
-
mkdirSync21(dirname13(
|
|
66765
|
-
writeFileSync24(
|
|
66766
|
-
return { ok: true, path:
|
|
67078
|
+
mkdirSync21(dirname13(path90), { recursive: true });
|
|
67079
|
+
writeFileSync24(path90, content, "utf8");
|
|
67080
|
+
return { ok: true, path: path90 };
|
|
66767
67081
|
}
|
|
66768
67082
|
function removeSkill(opts) {
|
|
66769
67083
|
const name = opts.name.trim().toLowerCase();
|
|
@@ -66781,8 +67095,8 @@ function removeSkill(opts) {
|
|
|
66781
67095
|
dir = getProjectSkillsDir(root);
|
|
66782
67096
|
}
|
|
66783
67097
|
const skillDir = join46(dir, name);
|
|
66784
|
-
const
|
|
66785
|
-
if (!existsSync52(
|
|
67098
|
+
const path90 = skillFilePath(dir, name);
|
|
67099
|
+
if (!existsSync52(path90) && !existsSync52(skillDir)) {
|
|
66786
67100
|
return { ok: false, error: `Skill "${name}" not found in ${dir}` };
|
|
66787
67101
|
}
|
|
66788
67102
|
try {
|
|
@@ -66793,7 +67107,7 @@ function removeSkill(opts) {
|
|
|
66793
67107
|
error: err instanceof Error ? err.message : String(err)
|
|
66794
67108
|
};
|
|
66795
67109
|
}
|
|
66796
|
-
return { ok: true, path:
|
|
67110
|
+
return { ok: true, path: path90 };
|
|
66797
67111
|
}
|
|
66798
67112
|
var NAME_RE, BUILTIN_SKILL_MODULES, builtinsLoaded;
|
|
66799
67113
|
var init_skillConfigIo = __esm({
|
|
@@ -66912,7 +67226,7 @@ var init_jsonApi = __esm({
|
|
|
66912
67226
|
});
|
|
66913
67227
|
|
|
66914
67228
|
// src/cli/memory/mcpAdapter.ts
|
|
66915
|
-
import * as
|
|
67229
|
+
import * as path87 from "node:path";
|
|
66916
67230
|
var id2, projectId, source, SearchSchema, AddSchema, LinkSchema, RetractSchema, MEMORY_MCP_TOOLS, MemoryMcpAdapter;
|
|
66917
67231
|
var init_mcpAdapter = __esm({
|
|
66918
67232
|
"src/cli/memory/mcpAdapter.ts"() {
|
|
@@ -67082,8 +67396,8 @@ var init_mcpAdapter = __esm({
|
|
|
67082
67396
|
this.takeWrite();
|
|
67083
67397
|
const externalFile = args.source?.file;
|
|
67084
67398
|
if (externalFile) {
|
|
67085
|
-
const normalized =
|
|
67086
|
-
if (
|
|
67399
|
+
const normalized = path87.normalize(externalFile);
|
|
67400
|
+
if (path87.isAbsolute(normalized) || normalized === ".." || normalized.startsWith(`..${path87.sep}`)) {
|
|
67087
67401
|
throw new Error("source.file must be project-relative and cannot escape the project");
|
|
67088
67402
|
}
|
|
67089
67403
|
}
|
|
@@ -67611,12 +67925,12 @@ function ensureHome() {
|
|
|
67611
67925
|
}
|
|
67612
67926
|
}
|
|
67613
67927
|
function loadCompanionConfig() {
|
|
67614
|
-
const
|
|
67615
|
-
if (!existsSync53(
|
|
67928
|
+
const path90 = getCompanionConfigPath();
|
|
67929
|
+
if (!existsSync53(path90)) {
|
|
67616
67930
|
return { projects: [] };
|
|
67617
67931
|
}
|
|
67618
67932
|
try {
|
|
67619
|
-
const raw = JSON.parse(readFileSync41(
|
|
67933
|
+
const raw = JSON.parse(readFileSync41(path90, "utf8"));
|
|
67620
67934
|
const projects = Array.isArray(raw.projects) ? raw.projects.filter(
|
|
67621
67935
|
(p3) => p3 && typeof p3.path === "string" && p3.path.trim() && typeof (p3.id ?? p3.name) === "string"
|
|
67622
67936
|
).map((p3) => ({
|
|
@@ -67654,16 +67968,16 @@ function loadOrCreateToken(explicit) {
|
|
|
67654
67968
|
return { token: explicit.trim(), created: false };
|
|
67655
67969
|
}
|
|
67656
67970
|
ensureHome();
|
|
67657
|
-
const
|
|
67658
|
-
if (existsSync53(
|
|
67659
|
-
const t = readFileSync41(
|
|
67971
|
+
const path90 = getCompanionTokenPath();
|
|
67972
|
+
if (existsSync53(path90)) {
|
|
67973
|
+
const t = readFileSync41(path90, "utf8").trim();
|
|
67660
67974
|
if (t) return { token: t, created: false };
|
|
67661
67975
|
}
|
|
67662
67976
|
const token = randomBytes7(24).toString("base64url");
|
|
67663
|
-
writeFileSync25(
|
|
67977
|
+
writeFileSync25(path90, token + "\n", "utf8");
|
|
67664
67978
|
try {
|
|
67665
67979
|
const fs45 = __require("node:fs");
|
|
67666
|
-
fs45.chmodSync?.(
|
|
67980
|
+
fs45.chmodSync?.(path90, 384);
|
|
67667
67981
|
} catch {
|
|
67668
67982
|
}
|
|
67669
67983
|
return { token, created: true };
|
|
@@ -67688,17 +68002,17 @@ function mergeProjects(cfg, extraPaths) {
|
|
|
67688
68002
|
byId.set(p3.id, p3);
|
|
67689
68003
|
}
|
|
67690
68004
|
for (const raw of extraPaths) {
|
|
67691
|
-
const
|
|
67692
|
-
if (!
|
|
67693
|
-
let id3 = slugFromPath(
|
|
68005
|
+
const path90 = raw.trim();
|
|
68006
|
+
if (!path90) continue;
|
|
68007
|
+
let id3 = slugFromPath(path90);
|
|
67694
68008
|
let n = 2;
|
|
67695
|
-
while (byId.has(id3) && byId.get(id3).path !==
|
|
67696
|
-
id3 = `${slugFromPath(
|
|
68009
|
+
while (byId.has(id3) && byId.get(id3).path !== path90) {
|
|
68010
|
+
id3 = `${slugFromPath(path90)}-${n++}`;
|
|
67697
68011
|
}
|
|
67698
68012
|
byId.set(id3, {
|
|
67699
68013
|
id: id3,
|
|
67700
|
-
name: slugFromPath(
|
|
67701
|
-
path:
|
|
68014
|
+
name: slugFromPath(path90),
|
|
68015
|
+
path: path90
|
|
67702
68016
|
});
|
|
67703
68017
|
}
|
|
67704
68018
|
return [...byId.values()];
|
|
@@ -67751,6 +68065,7 @@ __export(harnessServer_exports, {
|
|
|
67751
68065
|
bindHarnessTurnOptions: () => bindHarnessTurnOptions,
|
|
67752
68066
|
createCliRunTurn: () => createCliRunTurn,
|
|
67753
68067
|
createCliWorkspaceServices: () => createCliWorkspaceServices,
|
|
68068
|
+
resolveTurnLspProvider: () => resolveTurnLspProvider,
|
|
67754
68069
|
runHarnessServer: () => runHarnessServer,
|
|
67755
68070
|
startHarnessServer: () => startHarnessServer
|
|
67756
68071
|
});
|
|
@@ -67796,6 +68111,10 @@ function bindHarnessTurnOptions(input, workspaceRoot) {
|
|
|
67796
68111
|
useCouncil: turnInput.useCouncil === true || mode === "council"
|
|
67797
68112
|
};
|
|
67798
68113
|
}
|
|
68114
|
+
function resolveTurnLspProvider(services) {
|
|
68115
|
+
const candidate = services?.lspManager;
|
|
68116
|
+
return candidate instanceof LspManager ? candidate : void 0;
|
|
68117
|
+
}
|
|
67799
68118
|
function createCliRunTurn() {
|
|
67800
68119
|
let streamPromise = null;
|
|
67801
68120
|
const ensureStream = () => {
|
|
@@ -67822,11 +68141,14 @@ function createCliRunTurn() {
|
|
|
67822
68141
|
return async (input, deps) => {
|
|
67823
68142
|
const { provider, model, stream } = await ensureStream();
|
|
67824
68143
|
const opts = bindHarnessTurnOptions(input, deps.session.workspaceRoot);
|
|
68144
|
+
const lspProvider = resolveTurnLspProvider(deps.services);
|
|
67825
68145
|
const exitCode = await dispatchHeadlessTurn(
|
|
67826
68146
|
opts,
|
|
67827
68147
|
provider,
|
|
67828
68148
|
model,
|
|
67829
|
-
stream
|
|
68149
|
+
stream,
|
|
68150
|
+
void 0,
|
|
68151
|
+
lspProvider ? { lspProvider } : void 0
|
|
67830
68152
|
);
|
|
67831
68153
|
return { exitCode };
|
|
67832
68154
|
};
|
|
@@ -68665,9 +68987,9 @@ async function runCompanionServe(opts = {}) {
|
|
|
68665
68987
|
return;
|
|
68666
68988
|
}
|
|
68667
68989
|
const url2 = parseUrl(req);
|
|
68668
|
-
const
|
|
68990
|
+
const path90 = url2.pathname.replace(/\/+$/, "") || "/";
|
|
68669
68991
|
try {
|
|
68670
|
-
if (req.method === "GET" && (
|
|
68992
|
+
if (req.method === "GET" && (path90 === "/health" || path90 === "/v1/health")) {
|
|
68671
68993
|
sendJson2(res, 200, {
|
|
68672
68994
|
ok: true,
|
|
68673
68995
|
service: "zelari-companion",
|
|
@@ -68679,18 +69001,18 @@ async function runCompanionServe(opts = {}) {
|
|
|
68679
69001
|
});
|
|
68680
69002
|
return;
|
|
68681
69003
|
}
|
|
68682
|
-
if (
|
|
69004
|
+
if (path90.startsWith("/v1")) {
|
|
68683
69005
|
if (!tokenMatches(token, getBearer(req))) {
|
|
68684
69006
|
sendJson2(res, 401, { ok: false, error: "unauthorized" });
|
|
68685
69007
|
return;
|
|
68686
69008
|
}
|
|
68687
69009
|
}
|
|
68688
|
-
if (req.method === "GET" &&
|
|
69010
|
+
if (req.method === "GET" && path90 === "/v1/config") {
|
|
68689
69011
|
const snap = buildDesktopConfigSnapshot();
|
|
68690
69012
|
sendJson2(res, 200, { ok: true, ...snap });
|
|
68691
69013
|
return;
|
|
68692
69014
|
}
|
|
68693
|
-
if (req.method === "GET" &&
|
|
69015
|
+
if (req.method === "GET" && path90 === "/v1/projects") {
|
|
68694
69016
|
sendJson2(res, 200, {
|
|
68695
69017
|
ok: true,
|
|
68696
69018
|
projects: projects.map((p3) => ({
|
|
@@ -68701,7 +69023,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
68701
69023
|
});
|
|
68702
69024
|
return;
|
|
68703
69025
|
}
|
|
68704
|
-
if (req.method === "GET" &&
|
|
69026
|
+
if (req.method === "GET" && path90 === "/v1/runs") {
|
|
68705
69027
|
sendJson2(res, 200, {
|
|
68706
69028
|
ok: true,
|
|
68707
69029
|
active: runs.getActive(),
|
|
@@ -68719,7 +69041,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
68719
69041
|
});
|
|
68720
69042
|
return;
|
|
68721
69043
|
}
|
|
68722
|
-
if (req.method === "POST" &&
|
|
69044
|
+
if (req.method === "POST" && path90 === "/v1/runs") {
|
|
68723
69045
|
const raw = await readBody(req);
|
|
68724
69046
|
let body = {};
|
|
68725
69047
|
try {
|
|
@@ -68762,11 +69084,12 @@ async function runCompanionServe(opts = {}) {
|
|
|
68762
69084
|
createdAt: result.run.createdAt
|
|
68763
69085
|
},
|
|
68764
69086
|
eventsUrl: `/v1/runs/${result.run.id}/events`,
|
|
68765
|
-
cancelUrl: `/v1/runs/${result.run.id}/cancel
|
|
69087
|
+
cancelUrl: `/v1/runs/${result.run.id}/cancel`,
|
|
69088
|
+
steerUrl: `/v1/runs/${result.run.id}/steer`
|
|
68766
69089
|
});
|
|
68767
69090
|
return;
|
|
68768
69091
|
}
|
|
68769
|
-
const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(
|
|
69092
|
+
const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(path90);
|
|
68770
69093
|
if (req.method === "GET" && eventsMatch) {
|
|
68771
69094
|
const runId = eventsMatch[1];
|
|
68772
69095
|
const run = runs.getRun(runId);
|
|
@@ -68831,7 +69154,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
68831
69154
|
}, 500);
|
|
68832
69155
|
return;
|
|
68833
69156
|
}
|
|
68834
|
-
const cancelMatch = /^\/v1\/runs\/([^/]+)\/cancel$/.exec(
|
|
69157
|
+
const cancelMatch = /^\/v1\/runs\/([^/]+)\/cancel$/.exec(path90);
|
|
68835
69158
|
if (req.method === "POST" && cancelMatch) {
|
|
68836
69159
|
const runId = cancelMatch[1];
|
|
68837
69160
|
const result = runs.cancel(runId);
|
|
@@ -68842,6 +69165,30 @@ async function runCompanionServe(opts = {}) {
|
|
|
68842
69165
|
sendJson2(res, 200, { ok: true, cancelled: runId });
|
|
68843
69166
|
return;
|
|
68844
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
|
+
}
|
|
68845
69192
|
sendJson2(res, 404, { ok: false, error: "not found" });
|
|
68846
69193
|
} catch (err) {
|
|
68847
69194
|
sendJson2(res, 500, {
|
|
@@ -68985,11 +69332,11 @@ import { execSync as execSync2 } from "node:child_process";
|
|
|
68985
69332
|
import { existsSync as existsSync55, readFileSync as readFileSync42, readlinkSync, statSync as statSync10 } from "node:fs";
|
|
68986
69333
|
import { createRequire as createRequire3 } from "node:module";
|
|
68987
69334
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
68988
|
-
import
|
|
69335
|
+
import path88 from "node:path";
|
|
68989
69336
|
function findPackageRoot(start) {
|
|
68990
69337
|
let dir = start;
|
|
68991
69338
|
for (let i = 0; i < 6; i += 1) {
|
|
68992
|
-
const candidate =
|
|
69339
|
+
const candidate = path88.join(dir, "package.json");
|
|
68993
69340
|
if (existsSync55(candidate)) {
|
|
68994
69341
|
try {
|
|
68995
69342
|
const pkg = JSON.parse(readFileSync42(candidate, "utf8"));
|
|
@@ -68997,11 +69344,11 @@ function findPackageRoot(start) {
|
|
|
68997
69344
|
} catch {
|
|
68998
69345
|
}
|
|
68999
69346
|
}
|
|
69000
|
-
const parent =
|
|
69347
|
+
const parent = path88.dirname(dir);
|
|
69001
69348
|
if (parent === dir) break;
|
|
69002
69349
|
dir = parent;
|
|
69003
69350
|
}
|
|
69004
|
-
return
|
|
69351
|
+
return path88.resolve(__dirname3, "..", "..", "..");
|
|
69005
69352
|
}
|
|
69006
69353
|
function tryExec(cmd) {
|
|
69007
69354
|
try {
|
|
@@ -69015,7 +69362,7 @@ function tryExec(cmd) {
|
|
|
69015
69362
|
}
|
|
69016
69363
|
function readPackageJson4() {
|
|
69017
69364
|
try {
|
|
69018
|
-
const pkgPath =
|
|
69365
|
+
const pkgPath = path88.join(packageRoot, "package.json");
|
|
69019
69366
|
return JSON.parse(readFileSync42(pkgPath, "utf8"));
|
|
69020
69367
|
} catch {
|
|
69021
69368
|
return null;
|
|
@@ -69031,7 +69378,7 @@ function checkShim(pkgName) {
|
|
|
69031
69378
|
}
|
|
69032
69379
|
const isWin = process.platform === "win32";
|
|
69033
69380
|
const shimName = isWin ? "zelari-code.cmd" : "zelari-code";
|
|
69034
|
-
const shimPath =
|
|
69381
|
+
const shimPath = path88.join(prefix, shimName);
|
|
69035
69382
|
if (!existsSync55(shimPath)) {
|
|
69036
69383
|
return FAIL(
|
|
69037
69384
|
`shim not found at ${shimPath}
|
|
@@ -69059,8 +69406,8 @@ function checkShim(pkgName) {
|
|
|
69059
69406
|
fix: npm install -g ${pkgName}@latest --force`
|
|
69060
69407
|
);
|
|
69061
69408
|
}
|
|
69062
|
-
const resolved =
|
|
69063
|
-
const expected =
|
|
69409
|
+
const resolved = path88.resolve(path88.dirname(shimPath), target);
|
|
69410
|
+
const expected = path88.join(
|
|
69064
69411
|
prefix,
|
|
69065
69412
|
"node_modules",
|
|
69066
69413
|
pkgName,
|
|
@@ -69099,7 +69446,7 @@ function checkNode(pkg) {
|
|
|
69099
69446
|
return OK(`node ${raw}`);
|
|
69100
69447
|
}
|
|
69101
69448
|
function checkBundle() {
|
|
69102
|
-
const bundle =
|
|
69449
|
+
const bundle = path88.join(packageRoot, "dist", "cli", "main.bundled.js");
|
|
69103
69450
|
if (!existsSync55(bundle)) {
|
|
69104
69451
|
return FAIL(
|
|
69105
69452
|
`dist/cli/main.bundled.js missing at ${bundle}
|
|
@@ -69120,7 +69467,7 @@ function checkRuntimeDeps() {
|
|
|
69120
69467
|
const missing = [];
|
|
69121
69468
|
for (const dep of required2) {
|
|
69122
69469
|
try {
|
|
69123
|
-
const localReq = createRequire3(
|
|
69470
|
+
const localReq = createRequire3(path88.join(packageRoot, "package.json"));
|
|
69124
69471
|
localReq.resolve(dep);
|
|
69125
69472
|
} catch {
|
|
69126
69473
|
missing.push(dep);
|
|
@@ -69320,7 +69667,7 @@ var init_doctor = __esm({
|
|
|
69320
69667
|
init_metrics3();
|
|
69321
69668
|
init_contextGrowthSummary();
|
|
69322
69669
|
require3 = createRequire3(import.meta.url);
|
|
69323
|
-
__dirname3 =
|
|
69670
|
+
__dirname3 = path88.dirname(fileURLToPath3(import.meta.url));
|
|
69324
69671
|
packageRoot = findPackageRoot(__dirname3);
|
|
69325
69672
|
OK = (message) => ({
|
|
69326
69673
|
ok: true,
|
|
@@ -69504,15 +69851,15 @@ __export(inspect_exports, {
|
|
|
69504
69851
|
collectInspectReport: () => collectInspectReport,
|
|
69505
69852
|
runInspect: () => runInspect
|
|
69506
69853
|
});
|
|
69507
|
-
import
|
|
69854
|
+
import path89 from "node:path";
|
|
69508
69855
|
import { existsSync as existsSync56, readFileSync as readFileSync43, readdirSync as readdirSync12 } from "node:fs";
|
|
69509
69856
|
import { homedir as homedir17 } from "node:os";
|
|
69510
69857
|
async function collectInspectReport(cwd = process.cwd()) {
|
|
69511
69858
|
ensureBuiltinSkillsLoadedSync();
|
|
69512
69859
|
const snap = listSkillsSnapshot(cwd);
|
|
69513
69860
|
const mcp = listMcpServers(cwd);
|
|
69514
|
-
const userMcpPath =
|
|
69515
|
-
const projectMcpPath =
|
|
69861
|
+
const userMcpPath = path89.join(homedir17(), ".zelari-code", "mcp.json");
|
|
69862
|
+
const projectMcpPath = path89.join(cwd, ".zelari", "mcp.json");
|
|
69516
69863
|
const globalHooks = globalHooksDir();
|
|
69517
69864
|
const projectHooks = projectHooksDir(cwd);
|
|
69518
69865
|
const projectTrusted = isFolderTrusted(cwd);
|
|
@@ -69540,9 +69887,9 @@ async function collectInspectReport(cwd = process.cwd()) {
|
|
|
69540
69887
|
configSources: [
|
|
69541
69888
|
{ path: userMcpPath, exists: existsSync56(userMcpPath) },
|
|
69542
69889
|
{ path: projectMcpPath, exists: existsSync56(projectMcpPath) },
|
|
69543
|
-
{ path:
|
|
69544
|
-
{ path:
|
|
69545
|
-
{ 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")) }
|
|
69546
69893
|
],
|
|
69547
69894
|
skills: {
|
|
69548
69895
|
total: snap.skills.length,
|
|
@@ -69582,8 +69929,8 @@ function listJsonFiles(dir) {
|
|
|
69582
69929
|
}
|
|
69583
69930
|
function findAgentsMd(cwd) {
|
|
69584
69931
|
const candidates = [
|
|
69585
|
-
|
|
69586
|
-
|
|
69932
|
+
path89.join(cwd, "AGENTS.md"),
|
|
69933
|
+
path89.join(cwd, ".zelari", "AGENTS.md")
|
|
69587
69934
|
];
|
|
69588
69935
|
const found = [];
|
|
69589
69936
|
for (const c of candidates) {
|
|
@@ -72708,6 +73055,7 @@ init_completionGate();
|
|
|
72708
73055
|
init_verificationBridge();
|
|
72709
73056
|
init_completionProof();
|
|
72710
73057
|
init_nativeVerification();
|
|
73058
|
+
init_spineTelemetry();
|
|
72711
73059
|
|
|
72712
73060
|
// src/cli/hooks/permissionPicker.ts
|
|
72713
73061
|
init_toolPermissions();
|
|
@@ -72911,8 +73259,14 @@ function useChatTurn(params) {
|
|
|
72911
73259
|
try {
|
|
72912
73260
|
const memoryFactory = await Promise.resolve().then(() => (init_serviceFactory(), serviceFactory_exports));
|
|
72913
73261
|
if (memoryFactory.isMemoryV2Enabled()) {
|
|
73262
|
+
const tuiSpineHolder = {
|
|
73263
|
+
get current() {
|
|
73264
|
+
return writerRef.current?.spine;
|
|
73265
|
+
}
|
|
73266
|
+
};
|
|
72914
73267
|
memoryService = await memoryFactory.getMemoryService(process.cwd(), process.env, {
|
|
72915
|
-
onWarning: (warning) => appendSystem(setMessages, warning, Date.now())
|
|
73268
|
+
onWarning: (warning) => appendSystem(setMessages, warning, Date.now()),
|
|
73269
|
+
onEvent: memorySinkFor(tuiSpineHolder)
|
|
72916
73270
|
});
|
|
72917
73271
|
memoryAutoWrite = memoryFactory.isMemoryAutoWriteEnabled();
|
|
72918
73272
|
}
|
|
@@ -73879,8 +74233,14 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il membro riprende dop
|
|
|
73879
74233
|
try {
|
|
73880
74234
|
const memoryFactory = await Promise.resolve().then(() => (init_serviceFactory(), serviceFactory_exports));
|
|
73881
74235
|
if (memoryFactory.isMemoryV2Enabled()) {
|
|
74236
|
+
const councilSpineHolder = {
|
|
74237
|
+
get current() {
|
|
74238
|
+
return writerRef.current?.spine;
|
|
74239
|
+
}
|
|
74240
|
+
};
|
|
73882
74241
|
councilMemory = await memoryFactory.getMemoryService(process.cwd(), process.env, {
|
|
73883
|
-
onWarning: (warning) => appendSystem(setMessages, warning, Date.now())
|
|
74242
|
+
onWarning: (warning) => appendSystem(setMessages, warning, Date.now()),
|
|
74243
|
+
onEvent: memorySinkFor(councilSpineHolder)
|
|
73884
74244
|
});
|
|
73885
74245
|
councilMemoryAutoWrite = memoryFactory.isMemoryAutoWriteEnabled();
|
|
73886
74246
|
if (!overrides.ragContext) {
|
|
@@ -74489,7 +74849,12 @@ async function runZelariMissionInTui(userMessage, deps, emit) {
|
|
|
74489
74849
|
userMessage,
|
|
74490
74850
|
hasPlan: hasWorkspacePlan2(projectRoot)
|
|
74491
74851
|
});
|
|
74492
|
-
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));
|
|
74493
74858
|
const chairmanBudget = envNumber(process.env.ZELARI_MODE_MAX_TOOLS_LUCIFER, {
|
|
74494
74859
|
default: 30,
|
|
74495
74860
|
min: 1
|
|
@@ -75734,11 +76099,11 @@ function handleCacheStats(ctx) {
|
|
|
75734
76099
|
init_messageHelpers();
|
|
75735
76100
|
init_serviceFactory();
|
|
75736
76101
|
import { promises as fs31 } from "node:fs";
|
|
75737
|
-
import * as
|
|
76102
|
+
import * as path67 from "node:path";
|
|
75738
76103
|
|
|
75739
76104
|
// src/cli/memory/promotion.ts
|
|
75740
76105
|
import { promises as fs30 } from "node:fs";
|
|
75741
|
-
import * as
|
|
76106
|
+
import * as path66 from "node:path";
|
|
75742
76107
|
var START = "<!-- zelari:memory-promotions:start -->";
|
|
75743
76108
|
var END = "<!-- zelari:memory-promotions:end -->";
|
|
75744
76109
|
var DURABLE_KINDS = /* @__PURE__ */ new Set(["fact", "decision", "constraint", "preference", "procedure"]);
|
|
@@ -75749,13 +76114,13 @@ function lineFor(node) {
|
|
|
75749
76114
|
}
|
|
75750
76115
|
async function promoteMemoryToAgentsMd(projectRoot, node) {
|
|
75751
76116
|
if (node.status !== "active") {
|
|
75752
|
-
return { added: false, path:
|
|
76117
|
+
return { added: false, path: path66.join(projectRoot, "AGENTS.md"), reason: `memory is ${node.status}` };
|
|
75753
76118
|
}
|
|
75754
76119
|
if (!DURABLE_KINDS.has(node.kind)) {
|
|
75755
|
-
return { added: false, path:
|
|
76120
|
+
return { added: false, path: path66.join(projectRoot, "AGENTS.md"), reason: `${node.kind} is not a durable instruction kind` };
|
|
75756
76121
|
}
|
|
75757
|
-
const root = await fs30.realpath(projectRoot).catch(() =>
|
|
75758
|
-
const target =
|
|
76122
|
+
const root = await fs30.realpath(projectRoot).catch(() => path66.resolve(projectRoot));
|
|
76123
|
+
const target = path66.join(root, "AGENTS.md");
|
|
75759
76124
|
try {
|
|
75760
76125
|
const stat7 = await fs30.lstat(target);
|
|
75761
76126
|
if (stat7.isSymbolicLink() || !stat7.isFile()) throw new Error("AGENTS.md must be a regular project file.");
|
|
@@ -75820,22 +76185,22 @@ function sourceLine(source2) {
|
|
|
75820
76185
|
return entries.length ? entries.map(([key, value]) => `${key}=${value}`).join(" \xB7 ") : "unknown";
|
|
75821
76186
|
}
|
|
75822
76187
|
function isInside(root, target) {
|
|
75823
|
-
const relative6 =
|
|
75824
|
-
return relative6 === "" || !relative6.startsWith("..") && !
|
|
76188
|
+
const relative6 = path67.relative(root, target);
|
|
76189
|
+
return relative6 === "" || !relative6.startsWith("..") && !path67.isAbsolute(relative6);
|
|
75825
76190
|
}
|
|
75826
76191
|
async function safeExportPath(cwd, requested) {
|
|
75827
|
-
const lexicalRoot =
|
|
76192
|
+
const lexicalRoot = path67.resolve(cwd);
|
|
75828
76193
|
const root = await fs31.realpath(lexicalRoot).catch(() => lexicalRoot);
|
|
75829
|
-
const fallback =
|
|
75830
|
-
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;
|
|
75831
76196
|
if (!isInside(root, target)) {
|
|
75832
76197
|
throw new Error("Export path must stay inside the active project.");
|
|
75833
76198
|
}
|
|
75834
|
-
const parent =
|
|
75835
|
-
const relativeParent =
|
|
76199
|
+
const parent = path67.dirname(target);
|
|
76200
|
+
const relativeParent = path67.relative(root, parent);
|
|
75836
76201
|
let cursor = root;
|
|
75837
|
-
for (const segment of relativeParent.split(
|
|
75838
|
-
cursor =
|
|
76202
|
+
for (const segment of relativeParent.split(path67.sep).filter(Boolean)) {
|
|
76203
|
+
cursor = path67.join(cursor, segment);
|
|
75839
76204
|
try {
|
|
75840
76205
|
const stat7 = await fs31.lstat(cursor);
|
|
75841
76206
|
if (stat7.isSymbolicLink()) {
|
|
@@ -76007,9 +76372,9 @@ ${message}` : message
|
|
|
76007
76372
|
}
|
|
76008
76373
|
case "export": {
|
|
76009
76374
|
const target = await safeExportPath(ctx.cwd, args.join(" ").trim() || void 0);
|
|
76010
|
-
await fs31.mkdir(
|
|
76011
|
-
const root = await fs31.realpath(ctx.cwd).catch(() =>
|
|
76012
|
-
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));
|
|
76013
76378
|
if (!isInside(root, realParent)) {
|
|
76014
76379
|
throw new Error("Export path resolves outside the active project.");
|
|
76015
76380
|
}
|
|
@@ -76127,6 +76492,7 @@ init_graphMemory();
|
|
|
76127
76492
|
init_executor();
|
|
76128
76493
|
init_graphStatus();
|
|
76129
76494
|
init_serviceFactory();
|
|
76495
|
+
init_spineTelemetry();
|
|
76130
76496
|
async function handleKrakenGraph(ctx, prompt) {
|
|
76131
76497
|
if (!isKrakenGraphEnabled()) {
|
|
76132
76498
|
appendSystem(
|
|
@@ -76140,8 +76506,14 @@ async function handleKrakenGraph(ctx, prompt) {
|
|
|
76140
76506
|
return;
|
|
76141
76507
|
}
|
|
76142
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
|
+
};
|
|
76143
76514
|
const memory = isMemoryV2Enabled() ? await getMemoryService(ctx.cwd, process.env, {
|
|
76144
|
-
onWarning: (warning) => appendSystem(ctx.setMessages, warning)
|
|
76515
|
+
onWarning: (warning) => appendSystem(ctx.setMessages, warning),
|
|
76516
|
+
onEvent: memorySinkFor(tuiSpineHolder)
|
|
76145
76517
|
}) : void 0;
|
|
76146
76518
|
const audit = new AuditLogger();
|
|
76147
76519
|
const taskToolDeps = {
|
|
@@ -76205,7 +76577,7 @@ import { promises as fs35 } from "node:fs";
|
|
|
76205
76577
|
init_zod();
|
|
76206
76578
|
init_taskTool();
|
|
76207
76579
|
import { promises as fs34 } from "node:fs";
|
|
76208
|
-
import
|
|
76580
|
+
import path72 from "node:path";
|
|
76209
76581
|
import { randomBytes as randomBytes6 } from "node:crypto";
|
|
76210
76582
|
var CsvFanoutArgsSchema = external_exports.object({
|
|
76211
76583
|
csv_path: external_exports.string().min(1),
|
|
@@ -76299,8 +76671,8 @@ function resolveMaxConcurrency(env = process.env) {
|
|
|
76299
76671
|
}
|
|
76300
76672
|
async function runCsvFanout(args, deps, opts) {
|
|
76301
76673
|
const start = Date.now();
|
|
76302
|
-
const absCsv =
|
|
76303
|
-
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);
|
|
76304
76676
|
const { headers: headers2, rows } = await readCsv(absCsv);
|
|
76305
76677
|
if (headers2.length === 0) {
|
|
76306
76678
|
throw new Error(`kraken_csv_fanout: ${absCsv} is empty`);
|
|
@@ -76356,7 +76728,7 @@ async function runCsvFanout(args, deps, opts) {
|
|
|
76356
76728
|
errored += 1;
|
|
76357
76729
|
errors.push(`${row[args.id_column] ?? i}: ${res.error}`);
|
|
76358
76730
|
}
|
|
76359
|
-
await fs34.mkdir(
|
|
76731
|
+
await fs34.mkdir(path72.dirname(absOut), { recursive: true });
|
|
76360
76732
|
await queueWrite(serializeCsv(outHeaders, outputRecords));
|
|
76361
76733
|
}
|
|
76362
76734
|
}
|
|
@@ -76551,7 +76923,7 @@ function splitArgs(s) {
|
|
|
76551
76923
|
// src/cli/slashHandlers/krakenWorkbench.ts
|
|
76552
76924
|
init_messageHelpers();
|
|
76553
76925
|
import { promises as fs36 } from "node:fs";
|
|
76554
|
-
import
|
|
76926
|
+
import path73 from "node:path";
|
|
76555
76927
|
|
|
76556
76928
|
// src/cli/kraken/workbenchView.ts
|
|
76557
76929
|
var EMPTY = {
|
|
@@ -76668,14 +77040,14 @@ function formatWorkbenchForTerminal(p3) {
|
|
|
76668
77040
|
|
|
76669
77041
|
// src/cli/slashHandlers/krakenWorkbench.ts
|
|
76670
77042
|
async function handleKrakenWorkbench(ctx) {
|
|
76671
|
-
const dir =
|
|
77043
|
+
const dir = path73.join(ctx.cwd, ".zelari", "radio");
|
|
76672
77044
|
let latest = null;
|
|
76673
77045
|
let latestMtime = 0;
|
|
76674
77046
|
try {
|
|
76675
77047
|
const files = await fs36.readdir(dir);
|
|
76676
77048
|
for (const f of files) {
|
|
76677
77049
|
if (!f.startsWith("workbench-") || !f.endsWith(".md")) continue;
|
|
76678
|
-
const full =
|
|
77050
|
+
const full = path73.join(dir, f);
|
|
76679
77051
|
const stat7 = await fs36.stat(full);
|
|
76680
77052
|
if (stat7.mtimeMs > latestMtime) {
|
|
76681
77053
|
latestMtime = stat7.mtimeMs;
|
|
@@ -76692,10 +77064,10 @@ async function handleKrakenWorkbench(ctx) {
|
|
|
76692
77064
|
const parsed = parseWorkbench(content);
|
|
76693
77065
|
const rendered = formatWorkbenchForTerminal(parsed);
|
|
76694
77066
|
if (!rendered.trim()) {
|
|
76695
|
-
appendSystem(ctx.setMessages, `[kraken workbench] ${
|
|
77067
|
+
appendSystem(ctx.setMessages, `[kraken workbench] ${path73.basename(latest)}: (no nodes / no events yet)`);
|
|
76696
77068
|
return;
|
|
76697
77069
|
}
|
|
76698
|
-
appendSystem(ctx.setMessages, `[kraken workbench] ${
|
|
77070
|
+
appendSystem(ctx.setMessages, `[kraken workbench] ${path73.basename(latest)}:
|
|
76699
77071
|
${rendered}`);
|
|
76700
77072
|
}
|
|
76701
77073
|
|
|
@@ -77002,15 +77374,15 @@ ${result.output.split("\n").slice(-8).join("\n")}` : "";
|
|
|
77002
77374
|
// src/cli/slashHandlers/promoteMember.ts
|
|
77003
77375
|
init_messageHelpers();
|
|
77004
77376
|
import { promises as fs37 } from "node:fs";
|
|
77005
|
-
import
|
|
77377
|
+
import path76 from "node:path";
|
|
77006
77378
|
import os12 from "node:os";
|
|
77007
77379
|
async function handlePromoteMember(ctx, memberId) {
|
|
77008
77380
|
try {
|
|
77009
77381
|
const { promoteMember: promoteMember2 } = await Promise.resolve().then(() => (init_council(), council_exports));
|
|
77010
77382
|
const { skill, markdown } = promoteMember2(memberId);
|
|
77011
|
-
const skillDir = process.env.ANATHEMA_SKILL_DIR ??
|
|
77383
|
+
const skillDir = process.env.ANATHEMA_SKILL_DIR ?? path76.join(os12.homedir(), ".tmp", "zelari-code", "skills");
|
|
77012
77384
|
await fs37.mkdir(skillDir, { recursive: true });
|
|
77013
|
-
const filePath =
|
|
77385
|
+
const filePath = path76.join(skillDir, `${skill.id}.md`);
|
|
77014
77386
|
await fs37.writeFile(filePath, markdown, "utf8");
|
|
77015
77387
|
appendSystem(
|
|
77016
77388
|
ctx.setMessages,
|
|
@@ -77028,24 +77400,24 @@ async function handlePromoteMember(ctx, memberId) {
|
|
|
77028
77400
|
|
|
77029
77401
|
// src/cli/branchManager.ts
|
|
77030
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";
|
|
77031
|
-
import
|
|
77403
|
+
import path77 from "node:path";
|
|
77032
77404
|
import os13 from "node:os";
|
|
77033
77405
|
var META_FILENAME = "meta.json";
|
|
77034
77406
|
var SESSIONS_SUBDIR = "sessions";
|
|
77035
77407
|
function getBranchesBaseDir() {
|
|
77036
|
-
return process.env.ANATHEMA_BRANCHES_DIR ??
|
|
77408
|
+
return process.env.ANATHEMA_BRANCHES_DIR ?? path77.join(os13.homedir(), ".tmp", "zelari-code", "branches");
|
|
77037
77409
|
}
|
|
77038
77410
|
function getSessionsBaseDir() {
|
|
77039
|
-
return process.env.ANATHEMA_SESSIONS_DIR ??
|
|
77411
|
+
return process.env.ANATHEMA_SESSIONS_DIR ?? path77.join(os13.homedir(), ".tmp", "zelari-code", "sessions");
|
|
77040
77412
|
}
|
|
77041
77413
|
function branchPathFor(name, baseDir) {
|
|
77042
|
-
return
|
|
77414
|
+
return path77.join(baseDir, name);
|
|
77043
77415
|
}
|
|
77044
77416
|
function metaPathFor(name, baseDir) {
|
|
77045
|
-
return
|
|
77417
|
+
return path77.join(baseDir, name, META_FILENAME);
|
|
77046
77418
|
}
|
|
77047
77419
|
function sessionsPathFor(name, baseDir) {
|
|
77048
|
-
return
|
|
77420
|
+
return path77.join(baseDir, name, SESSIONS_SUBDIR);
|
|
77049
77421
|
}
|
|
77050
77422
|
function readBranchMeta(name, baseDir) {
|
|
77051
77423
|
const metaPath = metaPathFor(name, baseDir);
|
|
@@ -77070,7 +77442,7 @@ function readBranchMeta(name, baseDir) {
|
|
|
77070
77442
|
}
|
|
77071
77443
|
function writeBranchMeta(name, baseDir, meta3) {
|
|
77072
77444
|
const metaPath = metaPathFor(name, baseDir);
|
|
77073
|
-
mkdirSync19(
|
|
77445
|
+
mkdirSync19(path77.dirname(metaPath), { recursive: true });
|
|
77074
77446
|
writeFileSync23(metaPath, JSON.stringify(meta3, null, 2), "utf-8");
|
|
77075
77447
|
}
|
|
77076
77448
|
async function countSessions(name, baseDir) {
|
|
@@ -77121,14 +77493,14 @@ async function createBranch(name, fromSessionId, baseDir = getBranchesBaseDir(),
|
|
|
77121
77493
|
if (branchExists(name, baseDir)) {
|
|
77122
77494
|
throw new BranchAlreadyExistsError(name);
|
|
77123
77495
|
}
|
|
77124
|
-
const sourcePath =
|
|
77496
|
+
const sourcePath = path77.join(sessionsBaseDir, `${fromSessionId}.jsonl`);
|
|
77125
77497
|
if (!existsSync48(sourcePath)) {
|
|
77126
77498
|
throw new SessionNotFoundError(`Source session "${fromSessionId}" not found at ${sourcePath}`);
|
|
77127
77499
|
}
|
|
77128
77500
|
const branchPath = branchPathFor(name, baseDir);
|
|
77129
77501
|
const branchSessionsPath = sessionsPathFor(name, baseDir);
|
|
77130
77502
|
mkdirSync19(branchSessionsPath, { recursive: true });
|
|
77131
|
-
const destPath =
|
|
77503
|
+
const destPath = path77.join(branchSessionsPath, `${fromSessionId}.jsonl`);
|
|
77132
77504
|
await fs38.copyFile(sourcePath, destPath);
|
|
77133
77505
|
const meta3 = {
|
|
77134
77506
|
name,
|
|
@@ -77232,14 +77604,14 @@ async function handleBranchCheckout(ctx, branchName) {
|
|
|
77232
77604
|
// src/cli/slashHandlers/workspace.ts
|
|
77233
77605
|
init_messageHelpers();
|
|
77234
77606
|
import { promises as fs39 } from "node:fs";
|
|
77235
|
-
import
|
|
77607
|
+
import path78 from "node:path";
|
|
77236
77608
|
async function handleWorkspaceShow(ctx, what) {
|
|
77237
77609
|
try {
|
|
77238
|
-
const zelari =
|
|
77610
|
+
const zelari = path78.join(process.cwd(), ".zelari");
|
|
77239
77611
|
let content;
|
|
77240
77612
|
switch (what) {
|
|
77241
77613
|
case "plan": {
|
|
77242
|
-
const planPath =
|
|
77614
|
+
const planPath = path78.join(zelari, "plan.md");
|
|
77243
77615
|
try {
|
|
77244
77616
|
content = await fs39.readFile(planPath, "utf-8");
|
|
77245
77617
|
} catch {
|
|
@@ -77248,7 +77620,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
77248
77620
|
break;
|
|
77249
77621
|
}
|
|
77250
77622
|
case "decisions": {
|
|
77251
|
-
const decisionsDir =
|
|
77623
|
+
const decisionsDir = path78.join(zelari, "decisions");
|
|
77252
77624
|
try {
|
|
77253
77625
|
const files = (await fs39.readdir(decisionsDir)).filter((f) => f.endsWith(".md")).sort();
|
|
77254
77626
|
if (files.length === 0) {
|
|
@@ -77258,7 +77630,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
77258
77630
|
`];
|
|
77259
77631
|
const { parseFrontmatter: parseFrontmatter2 } = await Promise.resolve().then(() => (init_storage(), storage_exports));
|
|
77260
77632
|
for (const f of files) {
|
|
77261
|
-
const raw = await fs39.readFile(
|
|
77633
|
+
const raw = await fs39.readFile(path78.join(decisionsDir, f), "utf-8");
|
|
77262
77634
|
const { meta: meta3, body } = parseFrontmatter2(raw);
|
|
77263
77635
|
const title = meta3.title ?? body.split("\n")[0]?.replace(/^#\s*/, "").trim() ?? f;
|
|
77264
77636
|
lines.push(`- **${f.replace(/\.md$/, "")}** [${meta3.status ?? "unknown"}] ${title}`);
|
|
@@ -77271,7 +77643,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
77271
77643
|
break;
|
|
77272
77644
|
}
|
|
77273
77645
|
case "risks": {
|
|
77274
|
-
const risksPath =
|
|
77646
|
+
const risksPath = path78.join(zelari, "risks.md");
|
|
77275
77647
|
try {
|
|
77276
77648
|
content = await fs39.readFile(risksPath, "utf-8");
|
|
77277
77649
|
} catch {
|
|
@@ -77280,7 +77652,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
77280
77652
|
break;
|
|
77281
77653
|
}
|
|
77282
77654
|
case "agents": {
|
|
77283
|
-
const agentsPath =
|
|
77655
|
+
const agentsPath = path78.join(process.cwd(), "AGENTS.MD");
|
|
77284
77656
|
try {
|
|
77285
77657
|
content = await fs39.readFile(agentsPath, "utf-8");
|
|
77286
77658
|
} catch {
|
|
@@ -77289,7 +77661,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
77289
77661
|
break;
|
|
77290
77662
|
}
|
|
77291
77663
|
case "docs": {
|
|
77292
|
-
const docsDir =
|
|
77664
|
+
const docsDir = path78.join(zelari, "docs");
|
|
77293
77665
|
try {
|
|
77294
77666
|
const files = (await fs39.readdir(docsDir)).filter((f) => f.endsWith(".md")).sort();
|
|
77295
77667
|
content = files.length ? `# Docs (${files.length})
|
|
@@ -77331,7 +77703,7 @@ async function handleWorkspaceReset(ctx, force) {
|
|
|
77331
77703
|
return;
|
|
77332
77704
|
}
|
|
77333
77705
|
try {
|
|
77334
|
-
const target =
|
|
77706
|
+
const target = path78.join(process.cwd(), ".zelari");
|
|
77335
77707
|
await fs39.rm(target, { recursive: true, force: true });
|
|
77336
77708
|
appendSystem(ctx.setMessages, "[workspace] .zelari/ removed");
|
|
77337
77709
|
} catch (err) {
|
|
@@ -77343,7 +77715,7 @@ async function handleWorkspaceReset(ctx, force) {
|
|
|
77343
77715
|
init_provider2();
|
|
77344
77716
|
|
|
77345
77717
|
// src/cli/slashHandlers/skills.ts
|
|
77346
|
-
import
|
|
77718
|
+
import path79 from "node:path";
|
|
77347
77719
|
import os14 from "node:os";
|
|
77348
77720
|
|
|
77349
77721
|
// src/cli/skillHistory.ts
|
|
@@ -77472,7 +77844,7 @@ function handleSkillPicker(ctx, skills, openPicker, fallbackMessage) {
|
|
|
77472
77844
|
});
|
|
77473
77845
|
}
|
|
77474
77846
|
async function handleSkillStats(ctx, skillId) {
|
|
77475
|
-
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");
|
|
77476
77848
|
try {
|
|
77477
77849
|
const records = await readSkillHistory(historyFile);
|
|
77478
77850
|
const stats = getSkillStats(records, skillId);
|
|
@@ -77488,7 +77860,7 @@ async function handleSkillCompare(ctx, ids, fallbackMessage) {
|
|
|
77488
77860
|
appendSystem(ctx.setMessages, fallbackMessage ?? "[skill-compare] missing args");
|
|
77489
77861
|
return;
|
|
77490
77862
|
}
|
|
77491
|
-
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");
|
|
77492
77864
|
try {
|
|
77493
77865
|
const formatted = await compareSkillsFromFile(ids[0], ids[1], historyFile);
|
|
77494
77866
|
appendSystem(ctx.setMessages, formatted);
|
|
@@ -77944,7 +78316,10 @@ function useSlashDispatch(params) {
|
|
|
77944
78316
|
}
|
|
77945
78317
|
if (result.kind === "kraken_graph") {
|
|
77946
78318
|
const sid = (sessionId2 || "default").trim();
|
|
77947
|
-
await handleKrakenGraph(
|
|
78319
|
+
await handleKrakenGraph(
|
|
78320
|
+
{ setMessages, cwd: process.cwd(), sessionId: sid, writerRef: params.writerRef },
|
|
78321
|
+
result.graphPrompt ?? ""
|
|
78322
|
+
);
|
|
77948
78323
|
return;
|
|
77949
78324
|
}
|
|
77950
78325
|
if (result.kind === "kraken_fanout") {
|
|
@@ -78281,6 +78656,9 @@ function App() {
|
|
|
78281
78656
|
sessionId: session.sessionId,
|
|
78282
78657
|
messages: session.messages,
|
|
78283
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,
|
|
78284
78662
|
setInput,
|
|
78285
78663
|
setBusy,
|
|
78286
78664
|
setSessionId: session.setSessionId,
|
|
@@ -79183,8 +79561,8 @@ function normalizeDraft(raw, sourceUrl, provider, model) {
|
|
|
79183
79561
|
let name = String(o.name ?? "").trim().toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64);
|
|
79184
79562
|
if (!name || !/^[a-z0-9][a-z0-9-]{0,63}$/.test(name)) {
|
|
79185
79563
|
try {
|
|
79186
|
-
const
|
|
79187
|
-
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";
|
|
79188
79566
|
} catch {
|
|
79189
79567
|
name = "imported-skill";
|
|
79190
79568
|
}
|