zelari-code 2.37.0 → 2.37.1
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/headless/runOneTurn.js +15 -5
- package/dist/cli/headless/runOneTurn.js.map +1 -1
- package/dist/cli/headless.js +11 -0
- package/dist/cli/headless.js.map +1 -1
- package/dist/cli/headlessSpine.js +26 -0
- package/dist/cli/headlessSpine.js.map +1 -1
- package/dist/cli/hooks/useChatTurn.js +12 -3
- package/dist/cli/hooks/useChatTurn.js.map +1 -1
- package/dist/cli/kraken/completionGate.js +78 -1
- package/dist/cli/kraken/completionGate.js.map +1 -1
- package/dist/cli/kraken/verificationBridge.js +153 -32
- package/dist/cli/kraken/verificationBridge.js.map +1 -1
- package/dist/cli/kraken/verifyReport.js.map +1 -1
- package/dist/cli/main.bundled.js +494 -341
- package/dist/cli/main.bundled.js.map +3 -3
- package/dist/cli/main.js +1 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/runHeadless.js +16 -1
- package/dist/cli/runHeadless.js.map +1 -1
- package/package.json +2 -2
package/dist/cli/main.bundled.js
CHANGED
|
@@ -3482,10 +3482,10 @@ function mergeDefs(...defs) {
|
|
|
3482
3482
|
function cloneDef(schema) {
|
|
3483
3483
|
return mergeDefs(schema._zod.def);
|
|
3484
3484
|
}
|
|
3485
|
-
function getElementAtPath(obj,
|
|
3486
|
-
if (!
|
|
3485
|
+
function getElementAtPath(obj, path101) {
|
|
3486
|
+
if (!path101)
|
|
3487
3487
|
return obj;
|
|
3488
|
-
return
|
|
3488
|
+
return path101.reduce((acc, key) => acc?.[key], obj);
|
|
3489
3489
|
}
|
|
3490
3490
|
function promiseAllObject(promisesObj) {
|
|
3491
3491
|
const keys = Object.keys(promisesObj);
|
|
@@ -3813,11 +3813,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
3813
3813
|
}
|
|
3814
3814
|
return false;
|
|
3815
3815
|
}
|
|
3816
|
-
function prefixIssues(
|
|
3816
|
+
function prefixIssues(path101, issues) {
|
|
3817
3817
|
return issues.map((iss) => {
|
|
3818
3818
|
var _a3;
|
|
3819
3819
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
3820
|
-
iss.path.unshift(
|
|
3820
|
+
iss.path.unshift(path101);
|
|
3821
3821
|
return iss;
|
|
3822
3822
|
});
|
|
3823
3823
|
}
|
|
@@ -4035,16 +4035,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
4035
4035
|
}
|
|
4036
4036
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
4037
4037
|
const fieldErrors = { _errors: [] };
|
|
4038
|
-
const processError = (error52,
|
|
4038
|
+
const processError = (error52, path101 = []) => {
|
|
4039
4039
|
for (const issue2 of error52.issues) {
|
|
4040
4040
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
4041
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
4041
|
+
issue2.errors.map((issues) => processError({ issues }, [...path101, ...issue2.path]));
|
|
4042
4042
|
} else if (issue2.code === "invalid_key") {
|
|
4043
|
-
processError({ issues: issue2.issues }, [...
|
|
4043
|
+
processError({ issues: issue2.issues }, [...path101, ...issue2.path]);
|
|
4044
4044
|
} else if (issue2.code === "invalid_element") {
|
|
4045
|
-
processError({ issues: issue2.issues }, [...
|
|
4045
|
+
processError({ issues: issue2.issues }, [...path101, ...issue2.path]);
|
|
4046
4046
|
} else {
|
|
4047
|
-
const fullpath = [...
|
|
4047
|
+
const fullpath = [...path101, ...issue2.path];
|
|
4048
4048
|
if (fullpath.length === 0) {
|
|
4049
4049
|
fieldErrors._errors.push(mapper(issue2));
|
|
4050
4050
|
} else {
|
|
@@ -4071,17 +4071,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
4071
4071
|
}
|
|
4072
4072
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
4073
4073
|
const result = { errors: [] };
|
|
4074
|
-
const processError = (error52,
|
|
4074
|
+
const processError = (error52, path101 = []) => {
|
|
4075
4075
|
var _a3, _b;
|
|
4076
4076
|
for (const issue2 of error52.issues) {
|
|
4077
4077
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
4078
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
4078
|
+
issue2.errors.map((issues) => processError({ issues }, [...path101, ...issue2.path]));
|
|
4079
4079
|
} else if (issue2.code === "invalid_key") {
|
|
4080
|
-
processError({ issues: issue2.issues }, [...
|
|
4080
|
+
processError({ issues: issue2.issues }, [...path101, ...issue2.path]);
|
|
4081
4081
|
} else if (issue2.code === "invalid_element") {
|
|
4082
|
-
processError({ issues: issue2.issues }, [...
|
|
4082
|
+
processError({ issues: issue2.issues }, [...path101, ...issue2.path]);
|
|
4083
4083
|
} else {
|
|
4084
|
-
const fullpath = [...
|
|
4084
|
+
const fullpath = [...path101, ...issue2.path];
|
|
4085
4085
|
if (fullpath.length === 0) {
|
|
4086
4086
|
result.errors.push(mapper(issue2));
|
|
4087
4087
|
continue;
|
|
@@ -4113,8 +4113,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
4113
4113
|
}
|
|
4114
4114
|
function toDotPath(_path) {
|
|
4115
4115
|
const segs = [];
|
|
4116
|
-
const
|
|
4117
|
-
for (const seg of
|
|
4116
|
+
const path101 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
4117
|
+
for (const seg of path101) {
|
|
4118
4118
|
if (typeof seg === "number")
|
|
4119
4119
|
segs.push(`[${seg}]`);
|
|
4120
4120
|
else if (typeof seg === "symbol")
|
|
@@ -17617,13 +17617,13 @@ function resolveRef(ref, ctx) {
|
|
|
17617
17617
|
if (!ref.startsWith("#")) {
|
|
17618
17618
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
17619
17619
|
}
|
|
17620
|
-
const
|
|
17621
|
-
if (
|
|
17620
|
+
const path101 = ref.slice(1).split("/").filter(Boolean);
|
|
17621
|
+
if (path101.length === 0) {
|
|
17622
17622
|
return ctx.rootSchema;
|
|
17623
17623
|
}
|
|
17624
17624
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
17625
|
-
if (
|
|
17626
|
-
const key =
|
|
17625
|
+
if (path101[0] === defsKey) {
|
|
17626
|
+
const key = path101[1];
|
|
17627
17627
|
if (!key || !ctx.defs[key]) {
|
|
17628
17628
|
throw new Error(`Reference not found: ${ref}`);
|
|
17629
17629
|
}
|
|
@@ -18457,17 +18457,17 @@ var init_newlines = __esm({
|
|
|
18457
18457
|
});
|
|
18458
18458
|
|
|
18459
18459
|
// packages/core/dist/core/tools/builtin/fileEvents.js
|
|
18460
|
-
function fileReadEvent(
|
|
18461
|
-
return { kind: "file.read", actor: { type: "tool" }, data: { path:
|
|
18460
|
+
function fileReadEvent(path101, snapshotId) {
|
|
18461
|
+
return { kind: "file.read", actor: { type: "tool" }, data: { path: path101, snapshotId } };
|
|
18462
18462
|
}
|
|
18463
|
-
function fileAppliedEvent(
|
|
18464
|
-
return { kind: "file.applied", actor: { type: "tool" }, data: { path:
|
|
18463
|
+
function fileAppliedEvent(path101, snapshotId, bytes) {
|
|
18464
|
+
return { kind: "file.applied", actor: { type: "tool" }, data: { path: path101, snapshotId, bytes } };
|
|
18465
18465
|
}
|
|
18466
|
-
function fileRejectedEvent(
|
|
18466
|
+
function fileRejectedEvent(path101, reason, hint) {
|
|
18467
18467
|
return {
|
|
18468
18468
|
kind: "file.rejected",
|
|
18469
18469
|
actor: { type: "tool" },
|
|
18470
|
-
data: hint === void 0 ? { path:
|
|
18470
|
+
data: hint === void 0 ? { path: path101, reason } : { path: path101, reason, hint }
|
|
18471
18471
|
};
|
|
18472
18472
|
}
|
|
18473
18473
|
function reReadHint(reject) {
|
|
@@ -20336,11 +20336,11 @@ var init_tools = __esm({
|
|
|
20336
20336
|
if (!ctx.addDocument)
|
|
20337
20337
|
return "Knowledge vault tool not available.";
|
|
20338
20338
|
const title = args["title"] || "New Document";
|
|
20339
|
-
const
|
|
20339
|
+
const path101 = args["path"] || `notes/${title.toLowerCase().replace(/[^a-z0-9]+/g, "-")}`;
|
|
20340
20340
|
const content = args["content"] || "";
|
|
20341
20341
|
const tags = args["tags"] || [];
|
|
20342
20342
|
ctx.addDocument({
|
|
20343
|
-
path:
|
|
20343
|
+
path: path101,
|
|
20344
20344
|
title,
|
|
20345
20345
|
content,
|
|
20346
20346
|
format: "markdown",
|
|
@@ -20349,7 +20349,7 @@ var init_tools = __esm({
|
|
|
20349
20349
|
workspaceId: ctx.workspaceId
|
|
20350
20350
|
});
|
|
20351
20351
|
ctx.addActivity("vault", "created document", title);
|
|
20352
|
-
return `Document "${title}" created at "${
|
|
20352
|
+
return `Document "${title}" created at "${path101}".`;
|
|
20353
20353
|
}
|
|
20354
20354
|
}
|
|
20355
20355
|
];
|
|
@@ -22036,7 +22036,20 @@ function evaluateKrakenCompletionGate(mode) {
|
|
|
22036
22036
|
};
|
|
22037
22037
|
}
|
|
22038
22038
|
}
|
|
22039
|
-
function
|
|
22039
|
+
function excerptEntries(excerpts) {
|
|
22040
|
+
if (!excerpts) return [];
|
|
22041
|
+
return excerpts instanceof Map ? [...excerpts.entries()] : Object.entries(excerpts);
|
|
22042
|
+
}
|
|
22043
|
+
function excerptBlock(name, raw) {
|
|
22044
|
+
const trimmed = raw.trim();
|
|
22045
|
+
const truncated = trimmed.length > REPAIR_FAIL_EXCERPT_CAP;
|
|
22046
|
+
const tail2 = truncated ? trimmed.slice(trimmed.length - REPAIR_FAIL_EXCERPT_CAP) : trimmed;
|
|
22047
|
+
const lines = [`Failure excerpt (tail, capped ${REPAIR_FAIL_EXCERPT_CAP} chars) \u2014 ${name}:`];
|
|
22048
|
+
if (truncated) lines.push(`\u2026[truncated ${trimmed.length - REPAIR_FAIL_EXCERPT_CAP} chars]`);
|
|
22049
|
+
lines.push(tail2, "");
|
|
22050
|
+
return lines;
|
|
22051
|
+
}
|
|
22052
|
+
function buildKrakenRepairPrompt(gate, excerpts) {
|
|
22040
22053
|
const lines = [
|
|
22041
22054
|
`The BUILD turn is ending, but the required checks from kraken_select are not all satisfied (passed ${gate.passed}/${gate.total}).`,
|
|
22042
22055
|
""
|
|
@@ -22053,6 +22066,36 @@ function buildKrakenRepairPrompt(gate) {
|
|
|
22053
22066
|
for (const check2 of gate.unknownChecks) lines.push(`- ${check2}`);
|
|
22054
22067
|
lines.push("");
|
|
22055
22068
|
}
|
|
22069
|
+
const entries = excerptEntries(excerpts);
|
|
22070
|
+
if (entries.length > 0) {
|
|
22071
|
+
const byName = new Map(entries);
|
|
22072
|
+
const used = /* @__PURE__ */ new Set();
|
|
22073
|
+
const blocks = [];
|
|
22074
|
+
let emitted = 0;
|
|
22075
|
+
for (const check2 of [...gate.failedChecks, ...gate.unknownChecks]) {
|
|
22076
|
+
if (emitted >= MAX_REPAIR_EXCERPTS) break;
|
|
22077
|
+
const raw = byName.get(check2);
|
|
22078
|
+
if (raw === void 0 || used.has(check2)) continue;
|
|
22079
|
+
used.add(check2);
|
|
22080
|
+
blocks.push(excerptBlock(check2, raw));
|
|
22081
|
+
emitted += 1;
|
|
22082
|
+
}
|
|
22083
|
+
let leadInPushed = false;
|
|
22084
|
+
for (const [name, raw] of entries) {
|
|
22085
|
+
if (emitted >= MAX_REPAIR_EXCERPTS) break;
|
|
22086
|
+
if (used.has(name)) continue;
|
|
22087
|
+
if (!leadInPushed) {
|
|
22088
|
+
blocks.push([
|
|
22089
|
+
"DETERMINISTIC check failures with captured output (criteria pack / task contract):",
|
|
22090
|
+
""
|
|
22091
|
+
]);
|
|
22092
|
+
leadInPushed = true;
|
|
22093
|
+
}
|
|
22094
|
+
blocks.push(excerptBlock(name, raw));
|
|
22095
|
+
emitted += 1;
|
|
22096
|
+
}
|
|
22097
|
+
for (const block of blocks) lines.push(...block);
|
|
22098
|
+
}
|
|
22056
22099
|
lines.push(
|
|
22057
22100
|
"Recover this turn:",
|
|
22058
22101
|
"1. The approach selection is settled \u2014 do NOT call kraken_select again.",
|
|
@@ -22063,7 +22106,7 @@ function buildKrakenRepairPrompt(gate) {
|
|
|
22063
22106
|
);
|
|
22064
22107
|
return lines.join("\n");
|
|
22065
22108
|
}
|
|
22066
|
-
var OPEN_GATE;
|
|
22109
|
+
var OPEN_GATE, REPAIR_FAIL_EXCERPT_CAP, MAX_REPAIR_EXCERPTS;
|
|
22067
22110
|
var init_completionGate = __esm({
|
|
22068
22111
|
"src/cli/kraken/completionGate.ts"() {
|
|
22069
22112
|
"use strict";
|
|
@@ -22076,6 +22119,8 @@ var init_completionGate = __esm({
|
|
|
22076
22119
|
failedChecks: [],
|
|
22077
22120
|
unknownChecks: []
|
|
22078
22121
|
};
|
|
22122
|
+
REPAIR_FAIL_EXCERPT_CAP = 2e3;
|
|
22123
|
+
MAX_REPAIR_EXCERPTS = 5;
|
|
22079
22124
|
}
|
|
22080
22125
|
});
|
|
22081
22126
|
|
|
@@ -25174,16 +25219,16 @@ function runRetentionFromEnv() {
|
|
|
25174
25219
|
maxTotalBytes: Number.isFinite(parseMb) && parseMb > 0 ? Math.round(parseMb * 1024 * 1024) : DEFAULT_RUN_RETENTION_MAX_MB * 1024 * 1024
|
|
25175
25220
|
};
|
|
25176
25221
|
}
|
|
25177
|
-
async function dirSize(
|
|
25222
|
+
async function dirSize(path101) {
|
|
25178
25223
|
let total = 0;
|
|
25179
25224
|
let entries;
|
|
25180
25225
|
try {
|
|
25181
|
-
entries = await readdir(
|
|
25226
|
+
entries = await readdir(path101, { withFileTypes: true });
|
|
25182
25227
|
} catch {
|
|
25183
25228
|
return 0;
|
|
25184
25229
|
}
|
|
25185
25230
|
for (const entry of entries) {
|
|
25186
|
-
const child = join3(
|
|
25231
|
+
const child = join3(path101, entry.name);
|
|
25187
25232
|
if (entry.isDirectory())
|
|
25188
25233
|
total += await dirSize(child);
|
|
25189
25234
|
else {
|
|
@@ -25210,19 +25255,19 @@ async function enforceRunRetention(runsDir, options = {}) {
|
|
|
25210
25255
|
for (const entry of entries) {
|
|
25211
25256
|
if (!entry.isDirectory())
|
|
25212
25257
|
continue;
|
|
25213
|
-
const
|
|
25258
|
+
const path101 = join3(runsDir, entry.name);
|
|
25214
25259
|
let startedAt = 0;
|
|
25215
25260
|
let endedAt;
|
|
25216
25261
|
let completed = false;
|
|
25217
25262
|
try {
|
|
25218
|
-
const manifest = JSON.parse(await readFile(join3(
|
|
25263
|
+
const manifest = JSON.parse(await readFile(join3(path101, "manifest.json"), "utf8"));
|
|
25219
25264
|
startedAt = manifest.startedAt ?? 0;
|
|
25220
25265
|
endedAt = manifest.endedAt;
|
|
25221
25266
|
completed = Boolean(endedAt) && manifest.status !== "running";
|
|
25222
25267
|
} catch {
|
|
25223
25268
|
completed = false;
|
|
25224
25269
|
}
|
|
25225
|
-
infos.push({ name: entry.name, path:
|
|
25270
|
+
infos.push({ name: entry.name, path: path101, startedAt, endedAt, completed, bytes: await dirSize(path101) });
|
|
25226
25271
|
}
|
|
25227
25272
|
const remove = async (info) => {
|
|
25228
25273
|
await rm(info.path, { recursive: true, force: true });
|
|
@@ -25709,12 +25754,12 @@ var init_engine = __esm({
|
|
|
25709
25754
|
* content digest) and the returned ref carries the event seq when the
|
|
25710
25755
|
* emitter resolved one.
|
|
25711
25756
|
*/
|
|
25712
|
-
async fsEvidence(observation,
|
|
25757
|
+
async fsEvidence(observation, path101, sha256, content, extra = {}) {
|
|
25713
25758
|
const digest = sha256 && content !== void 0 ? sha256(content) : void 0;
|
|
25714
|
-
const seq = await this.emitEvidence({ observation, path:
|
|
25759
|
+
const seq = await this.emitEvidence({ observation, path: path101, ...extra, ...digest ? { digest } : {} });
|
|
25715
25760
|
return {
|
|
25716
25761
|
tier: "fs-observation",
|
|
25717
|
-
ref:
|
|
25762
|
+
ref: path101,
|
|
25718
25763
|
capturedAt: Date.now(),
|
|
25719
25764
|
...digest ? { digest } : {},
|
|
25720
25765
|
...seq !== void 0 ? { seq } : {}
|
|
@@ -27184,11 +27229,14 @@ var init_contractCompiler = __esm({
|
|
|
27184
27229
|
var verificationBridge_exports = {};
|
|
27185
27230
|
__export(verificationBridge_exports, {
|
|
27186
27231
|
STRICT_DONE_EXIT_CODE: () => STRICT_DONE_EXIT_CODE,
|
|
27232
|
+
allowUnverified: () => allowUnverified,
|
|
27187
27233
|
anchorSelectionEvidence: () => anchorSelectionEvidence,
|
|
27188
27234
|
evaluateStrictBuildGate: () => evaluateStrictBuildGate,
|
|
27189
27235
|
evaluateStrictBuildGateFromSession: () => evaluateStrictBuildGateFromSession,
|
|
27190
27236
|
krakenResultsToContract: () => krakenResultsToContract,
|
|
27191
27237
|
matchNoteToToolTrace: () => matchNoteToToolTrace,
|
|
27238
|
+
missionClaimExitCode: () => missionClaimExitCode,
|
|
27239
|
+
repairExcerptsFromEvaluation: () => repairExcerptsFromEvaluation,
|
|
27192
27240
|
strictDoneEnabled: () => strictDoneEnabled,
|
|
27193
27241
|
strictEnvOverlay: () => strictEnvOverlay,
|
|
27194
27242
|
strictGateEventPayload: () => strictGateEventPayload,
|
|
@@ -27224,20 +27272,20 @@ function criterionId(check2, index) {
|
|
|
27224
27272
|
function normalize3(text) {
|
|
27225
27273
|
return text.toLowerCase().replace(/\s+/g, " ").trim();
|
|
27226
27274
|
}
|
|
27227
|
-
function matchResult(check2, byNormalized) {
|
|
27228
|
-
|
|
27229
|
-
|
|
27230
|
-
|
|
27231
|
-
for (const key of byNormalized.keys()) {
|
|
27232
|
-
if (key.length >= 8 && (key.includes(norm) || norm.includes(key))) {
|
|
27233
|
-
return byNormalized.get(key);
|
|
27234
|
-
}
|
|
27275
|
+
function matchResult(check2, byNormalized, byId, id3) {
|
|
27276
|
+
if (byId && id3) {
|
|
27277
|
+
const byCriterion = byId.get(id3);
|
|
27278
|
+
if (byCriterion) return byCriterion;
|
|
27235
27279
|
}
|
|
27236
|
-
return
|
|
27280
|
+
return byNormalized.get(normalize3(check2));
|
|
27237
27281
|
}
|
|
27238
27282
|
function krakenResultsToContract(requiredChecks, results, now = Date.now()) {
|
|
27239
27283
|
const byNormalized = /* @__PURE__ */ new Map();
|
|
27240
|
-
|
|
27284
|
+
const byId = /* @__PURE__ */ new Map();
|
|
27285
|
+
for (const r of results ?? []) {
|
|
27286
|
+
byNormalized.set(normalize3(r.check), r);
|
|
27287
|
+
if (r.criterionId) byId.set(r.criterionId, r);
|
|
27288
|
+
}
|
|
27241
27289
|
const criteria = [];
|
|
27242
27290
|
const verifications = [];
|
|
27243
27291
|
requiredChecks.forEach((check2, i) => {
|
|
@@ -27247,12 +27295,12 @@ function krakenResultsToContract(requiredChecks, results, now = Date.now()) {
|
|
|
27247
27295
|
text: check2,
|
|
27248
27296
|
source: "kraken-selection",
|
|
27249
27297
|
required: true,
|
|
27250
|
-
check: { kind: "none", reason: "
|
|
27298
|
+
check: { kind: "none", reason: "verify tentacle proposal \u2014 runtime evidence required" }
|
|
27251
27299
|
});
|
|
27252
|
-
const reported = matchResult(check2, byNormalized);
|
|
27300
|
+
const reported = matchResult(check2, byNormalized, byId, id3);
|
|
27253
27301
|
const evidence = reported?.note && reported.note.trim().length > 0 ? [
|
|
27254
27302
|
{
|
|
27255
|
-
tier: "
|
|
27303
|
+
tier: "verifier-llm",
|
|
27256
27304
|
ref: reported.note.trim().slice(0, 500),
|
|
27257
27305
|
capturedAt: now
|
|
27258
27306
|
}
|
|
@@ -27299,12 +27347,12 @@ async function anchorSelectionEvidence(results, emit, toolTrace) {
|
|
|
27299
27347
|
for (const r of results) {
|
|
27300
27348
|
for (const ev of r.evidence) {
|
|
27301
27349
|
if (ev.seq !== void 0) continue;
|
|
27302
|
-
if (ev.tier === "
|
|
27350
|
+
if (ev.tier === "human") continue;
|
|
27303
27351
|
try {
|
|
27304
27352
|
const match = toolTrace && toolTrace.length > 0 ? matchNoteToToolTrace(ev.ref, toolTrace) : null;
|
|
27305
27353
|
if (match) {
|
|
27306
27354
|
const digest = sha256Hex2(match.output);
|
|
27307
|
-
const
|
|
27355
|
+
const appended = await emit({
|
|
27308
27356
|
kind: "verification.evidence",
|
|
27309
27357
|
actor: { type: "system", role: "verification" },
|
|
27310
27358
|
data: {
|
|
@@ -27320,16 +27368,17 @@ async function anchorSelectionEvidence(results, emit, toolTrace) {
|
|
|
27320
27368
|
...match.command ? { command: match.command } : {}
|
|
27321
27369
|
}
|
|
27322
27370
|
});
|
|
27323
|
-
const toolSeq =
|
|
27371
|
+
const toolSeq = appended && typeof appended === "object" && "seq" in appended ? Number(appended.seq) : NaN;
|
|
27324
27372
|
if (Number.isFinite(toolSeq) && toolSeq > 0) {
|
|
27325
27373
|
ev.seq = toolSeq;
|
|
27326
27374
|
ev.digest = digest;
|
|
27375
|
+
ev.tier = "tool-output";
|
|
27327
27376
|
ev.ref = `${match.tool}${match.command ? ` ${match.command}` : ""} \u2192 ${match.ok ? "ok" : "error"} @seq`;
|
|
27328
27377
|
counts.toolResultAnchored += 1;
|
|
27329
27378
|
}
|
|
27330
27379
|
continue;
|
|
27331
27380
|
}
|
|
27332
|
-
|
|
27381
|
+
await emit({
|
|
27333
27382
|
kind: "verification.evidence",
|
|
27334
27383
|
actor: { type: "system", role: "verification" },
|
|
27335
27384
|
data: {
|
|
@@ -27337,14 +27386,11 @@ async function anchorSelectionEvidence(results, emit, toolTrace) {
|
|
|
27337
27386
|
provenance: "note-fallback",
|
|
27338
27387
|
criterionId: r.criterionId,
|
|
27339
27388
|
ref: ev.ref,
|
|
27340
|
-
tier: ev.tier
|
|
27389
|
+
tier: ev.tier,
|
|
27390
|
+
anchored: false
|
|
27341
27391
|
}
|
|
27342
27392
|
});
|
|
27343
|
-
|
|
27344
|
-
if (Number.isFinite(seq) && seq > 0) {
|
|
27345
|
-
ev.seq = seq;
|
|
27346
|
-
counts.noteFallback += 1;
|
|
27347
|
-
}
|
|
27393
|
+
counts.noteFallback += 1;
|
|
27348
27394
|
} catch {
|
|
27349
27395
|
}
|
|
27350
27396
|
}
|
|
@@ -27358,7 +27404,8 @@ async function evaluateStrictBuildGate(mode, options = {}) {
|
|
|
27358
27404
|
const selectionAvailable = gate.selectionUsed && gate.total > 0;
|
|
27359
27405
|
const scopeContract = options.taskContract ?? activeContractScope()?.contract;
|
|
27360
27406
|
const contractPlan = scopeContract ? compileVerificationCriteria(scopeContract) : [];
|
|
27361
|
-
|
|
27407
|
+
const nothingBindable = !selectionAvailable && !nativeOn && contractPlan.length === 0;
|
|
27408
|
+
if (!strictOn && !nativeOn) {
|
|
27362
27409
|
return {
|
|
27363
27410
|
gate,
|
|
27364
27411
|
strict: false,
|
|
@@ -27368,6 +27415,17 @@ async function evaluateStrictBuildGate(mode, options = {}) {
|
|
|
27368
27415
|
summary: gate.blocked ? `blocked: ${gate.failedChecks.length} failed, ${gate.unknownChecks.length} unknown` : "open"
|
|
27369
27416
|
};
|
|
27370
27417
|
}
|
|
27418
|
+
if (nothingBindable) {
|
|
27419
|
+
return {
|
|
27420
|
+
gate,
|
|
27421
|
+
strict: true,
|
|
27422
|
+
unverified: true,
|
|
27423
|
+
evaluation: null,
|
|
27424
|
+
native: null,
|
|
27425
|
+
blocked: true,
|
|
27426
|
+
summary: "unverified (strict on: no criteria \u2014 pack off/unbound, no selection contract, no task contract)"
|
|
27427
|
+
};
|
|
27428
|
+
}
|
|
27371
27429
|
const checks = selectionAvailable ? krakenRequiredChecks() : [];
|
|
27372
27430
|
const contract = selectionAvailable ? krakenResultsToContract(checks, getKrakenCheckResults()) : { criteria: [], results: [] };
|
|
27373
27431
|
const anchoring = await anchorSelectionEvidence(
|
|
@@ -27389,6 +27447,19 @@ async function evaluateStrictBuildGate(mode, options = {}) {
|
|
|
27389
27447
|
const allCriteria = [...contract.criteria, ...native?.criteria ?? [], ...compiled?.criteria ?? []];
|
|
27390
27448
|
const allResults = [...contract.results, ...native?.results ?? [], ...compiled?.results ?? []];
|
|
27391
27449
|
if (allCriteria.length === 0) {
|
|
27450
|
+
if (strictOn) {
|
|
27451
|
+
return {
|
|
27452
|
+
gate,
|
|
27453
|
+
strict: true,
|
|
27454
|
+
unverified: true,
|
|
27455
|
+
evaluation: null,
|
|
27456
|
+
native,
|
|
27457
|
+
compiled,
|
|
27458
|
+
results: allResults,
|
|
27459
|
+
blocked: true,
|
|
27460
|
+
summary: "unverified (strict on: native pack bound no command, no selection contract)"
|
|
27461
|
+
};
|
|
27462
|
+
}
|
|
27392
27463
|
return {
|
|
27393
27464
|
gate,
|
|
27394
27465
|
strict: false,
|
|
@@ -27414,14 +27485,51 @@ async function evaluateStrictBuildGate(mode, options = {}) {
|
|
|
27414
27485
|
summary: blocked ? `blocked (strict ${evaluation?.verdict ?? "n/a"}): ${legacyPart}evidence ${evaluation?.evidenceComplete ? "complete" : "incomplete"}` : `open (strict PASS): ${evaluation?.satisfied.length ?? 0}/${allCriteria.length} criteria pass with evidence`
|
|
27415
27486
|
};
|
|
27416
27487
|
}
|
|
27417
|
-
function
|
|
27418
|
-
|
|
27488
|
+
function repairExcerptsFromEvaluation(evaluation) {
|
|
27489
|
+
const excerpts = /* @__PURE__ */ new Map();
|
|
27490
|
+
const nameById = /* @__PURE__ */ new Map();
|
|
27491
|
+
for (const c of [...evaluation.native?.criteria ?? [], ...evaluation.compiled?.criteria ?? []]) {
|
|
27492
|
+
nameById.set(c.id, c.text);
|
|
27493
|
+
}
|
|
27494
|
+
try {
|
|
27495
|
+
krakenRequiredChecks().forEach((text, i) => {
|
|
27496
|
+
if (!nameById.has(criterionId(text, i))) nameById.set(criterionId(text, i), text);
|
|
27497
|
+
});
|
|
27498
|
+
} catch {
|
|
27499
|
+
}
|
|
27500
|
+
for (const r of evaluation.results ?? []) {
|
|
27501
|
+
if (r.status === "pass") continue;
|
|
27502
|
+
const detail = r.detail?.trim();
|
|
27503
|
+
if (!detail) continue;
|
|
27504
|
+
excerpts.set(nameById.get(r.criterionId) ?? r.criterionId, detail);
|
|
27505
|
+
}
|
|
27506
|
+
return excerpts;
|
|
27507
|
+
}
|
|
27508
|
+
function allowUnverified(env = process.env) {
|
|
27509
|
+
const v = env.ZELARI_ALLOW_UNVERIFIED?.toLowerCase();
|
|
27510
|
+
return v === "1" || v === "true" || v === "yes" || v === "on";
|
|
27511
|
+
}
|
|
27512
|
+
function strictGateExitCode(evaluation, env = process.env) {
|
|
27513
|
+
if (evaluation.strict && evaluation.blocked) {
|
|
27514
|
+
if (evaluation.unverified && allowUnverified(env)) return 0;
|
|
27515
|
+
return STRICT_DONE_EXIT_CODE;
|
|
27516
|
+
}
|
|
27517
|
+
return 0;
|
|
27518
|
+
}
|
|
27519
|
+
function missionClaimExitCode(evidenceCount, env = process.env) {
|
|
27520
|
+
if (evidenceCount < 0) return 0;
|
|
27521
|
+
if (evidenceCount > 0) return 0;
|
|
27522
|
+
if (allowUnverified(env)) return 0;
|
|
27523
|
+
return STRICT_DONE_EXIT_CODE;
|
|
27419
27524
|
}
|
|
27420
27525
|
function strictGateEventPayload(evaluation) {
|
|
27421
27526
|
return {
|
|
27422
27527
|
engine: evaluation.native ? "kraken-legacy+completion-policy+criteria-pack" : "kraken-legacy+completion-policy",
|
|
27423
27528
|
strict: evaluation.strict,
|
|
27424
27529
|
verdict: evaluation.evaluation?.verdict ?? (evaluation.blocked ? "BLOCKED" : "PASS"),
|
|
27530
|
+
// M1.2: UNVERIFIED marker — strict on, nothing evaluable. Present only
|
|
27531
|
+
// when true so historical payloads stay byte-identical.
|
|
27532
|
+
...evaluation.unverified ? { unverified: true } : {},
|
|
27425
27533
|
legacy: {
|
|
27426
27534
|
total: evaluation.gate.total,
|
|
27427
27535
|
passed: evaluation.gate.passed,
|
|
@@ -31734,11 +31842,11 @@ var init_synthesisAudit = __esm({
|
|
|
31734
31842
|
import { existsSync as existsSync10, readFileSync as readFileSync9, writeFileSync as writeFileSync6 } from "node:fs";
|
|
31735
31843
|
import { join as join5 } from "node:path";
|
|
31736
31844
|
function loadNfrSpec(zelariRoot) {
|
|
31737
|
-
const
|
|
31738
|
-
if (!existsSync10(
|
|
31845
|
+
const path101 = join5(zelariRoot, "nfr-spec.json");
|
|
31846
|
+
if (!existsSync10(path101))
|
|
31739
31847
|
return null;
|
|
31740
31848
|
try {
|
|
31741
|
-
const raw = JSON.parse(readFileSync9(
|
|
31849
|
+
const raw = JSON.parse(readFileSync9(path101, "utf8"));
|
|
31742
31850
|
if (raw.version !== 1 || !Array.isArray(raw.targets))
|
|
31743
31851
|
return null;
|
|
31744
31852
|
return raw;
|
|
@@ -34139,9 +34247,9 @@ var init_types9 = __esm({
|
|
|
34139
34247
|
import { readFileSync as readFileSync14 } from "node:fs";
|
|
34140
34248
|
import { join as join11 } from "node:path";
|
|
34141
34249
|
function readLessonsDeduped(zelariRoot) {
|
|
34142
|
-
const
|
|
34250
|
+
const path101 = join11(zelariRoot, LESSONS_FILE);
|
|
34143
34251
|
try {
|
|
34144
|
-
const raw = readFileSync14(
|
|
34252
|
+
const raw = readFileSync14(path101, "utf8");
|
|
34145
34253
|
const byId = /* @__PURE__ */ new Map();
|
|
34146
34254
|
for (const line of raw.split(/\r?\n/)) {
|
|
34147
34255
|
if (!line.trim())
|
|
@@ -34242,8 +34350,8 @@ function keywordsFrom(check2, signature) {
|
|
|
34242
34350
|
return [.../* @__PURE__ */ new Set([...fromId, ...words])].slice(0, 12);
|
|
34243
34351
|
}
|
|
34244
34352
|
function writeLesson(zelariRoot, lesson) {
|
|
34245
|
-
const
|
|
34246
|
-
appendFileSync(
|
|
34353
|
+
const path101 = join12(zelariRoot, LESSONS_FILE);
|
|
34354
|
+
appendFileSync(path101, `${JSON.stringify(lesson)}
|
|
34247
34355
|
`, "utf8");
|
|
34248
34356
|
}
|
|
34249
34357
|
function findSimilar(lessons, signature) {
|
|
@@ -36211,9 +36319,9 @@ function findCycle(nodes) {
|
|
|
36211
36319
|
if (color.get(start) !== WHITE)
|
|
36212
36320
|
continue;
|
|
36213
36321
|
const stack = [[start, 0]];
|
|
36214
|
-
const
|
|
36322
|
+
const path101 = [];
|
|
36215
36323
|
color.set(start, GRAY);
|
|
36216
|
-
|
|
36324
|
+
path101.push(start);
|
|
36217
36325
|
while (stack.length > 0) {
|
|
36218
36326
|
const top = stack[stack.length - 1];
|
|
36219
36327
|
const [id3, idx] = top;
|
|
@@ -36226,17 +36334,17 @@ function findCycle(nodes) {
|
|
|
36226
36334
|
continue;
|
|
36227
36335
|
const c = color.get(dep);
|
|
36228
36336
|
if (c === GRAY) {
|
|
36229
|
-
const at =
|
|
36230
|
-
return [...
|
|
36337
|
+
const at = path101.indexOf(dep);
|
|
36338
|
+
return [...path101.slice(at), dep];
|
|
36231
36339
|
}
|
|
36232
36340
|
if (c === WHITE) {
|
|
36233
36341
|
color.set(dep, GRAY);
|
|
36234
|
-
|
|
36342
|
+
path101.push(dep);
|
|
36235
36343
|
stack.push([dep, 0]);
|
|
36236
36344
|
}
|
|
36237
36345
|
} else {
|
|
36238
36346
|
color.set(id3, BLACK);
|
|
36239
|
-
|
|
36347
|
+
path101.pop();
|
|
36240
36348
|
stack.pop();
|
|
36241
36349
|
}
|
|
36242
36350
|
}
|
|
@@ -37156,8 +37264,8 @@ var init_runner = __esm({
|
|
|
37156
37264
|
failed: [...this.tentaclesById.values()].filter((r) => r.status === "error"),
|
|
37157
37265
|
pending: []
|
|
37158
37266
|
};
|
|
37159
|
-
const
|
|
37160
|
-
this.host.log(`checkpoint: ${label ?? "auto"} \u2192 ${
|
|
37267
|
+
const path101 = await this.host.saveSnapshot(snapshot, ".zelari/kraken/snapshots");
|
|
37268
|
+
this.host.log(`checkpoint: ${label ?? "auto"} \u2192 ${path101}`);
|
|
37161
37269
|
return snapshot;
|
|
37162
37270
|
}
|
|
37163
37271
|
callLog(msg, data) {
|
|
@@ -38308,7 +38416,7 @@ var CORE_VERSION;
|
|
|
38308
38416
|
var init_version = __esm({
|
|
38309
38417
|
"packages/core/dist/version.js"() {
|
|
38310
38418
|
"use strict";
|
|
38311
|
-
CORE_VERSION = "2.37.
|
|
38419
|
+
CORE_VERSION = "2.37.1";
|
|
38312
38420
|
}
|
|
38313
38421
|
});
|
|
38314
38422
|
|
|
@@ -40767,9 +40875,9 @@ function spillToolOutput(fullText, meta3) {
|
|
|
40767
40875
|
const rnd = randomBytes3(3).toString("hex");
|
|
40768
40876
|
const safeTool = (meta3?.toolName ?? "tool").replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 32);
|
|
40769
40877
|
const file2 = `${stamp}-${safeTool}-${hash3}-${rnd}.txt`;
|
|
40770
|
-
const
|
|
40771
|
-
writeFileSync12(
|
|
40772
|
-
return
|
|
40878
|
+
const path101 = join14(dir, file2);
|
|
40879
|
+
writeFileSync12(path101, fullText, "utf8");
|
|
40880
|
+
return path101;
|
|
40773
40881
|
} catch {
|
|
40774
40882
|
return null;
|
|
40775
40883
|
}
|
|
@@ -40815,10 +40923,10 @@ function truncateToolResult(text, capOrOpts = TOOL_RESULT_LINE_CAP) {
|
|
|
40815
40923
|
${tail2}`;
|
|
40816
40924
|
}
|
|
40817
40925
|
if (doSpill) {
|
|
40818
|
-
const
|
|
40819
|
-
if (
|
|
40926
|
+
const path101 = spillToolOutput(text, { toolName: opts.toolName });
|
|
40927
|
+
if (path101) {
|
|
40820
40928
|
const spillNote = `
|
|
40821
|
-
\u2026 [full output spilled to: ${
|
|
40929
|
+
\u2026 [full output spilled to: ${path101} \u2014 re-read with read_file if you need the complete text] \u2026`;
|
|
40822
40930
|
if (preview.includes("] \u2026\n")) {
|
|
40823
40931
|
preview = preview.replace("] \u2026\n", `] \u2026${spillNote}
|
|
40824
40932
|
`);
|
|
@@ -41589,28 +41697,28 @@ var init_storage = __esm({
|
|
|
41589
41697
|
VALID_SCALARS = /^(true|false|null|~)$/i;
|
|
41590
41698
|
Storage = class {
|
|
41591
41699
|
/** Read a Markdown file with frontmatter. Throws if not found. */
|
|
41592
|
-
read(
|
|
41593
|
-
if (!existsSync19(
|
|
41594
|
-
throw new Error(`File not found: ${
|
|
41700
|
+
read(path101) {
|
|
41701
|
+
if (!existsSync19(path101)) {
|
|
41702
|
+
throw new Error(`File not found: ${path101}`);
|
|
41595
41703
|
}
|
|
41596
|
-
const md = readFileSync17(
|
|
41704
|
+
const md = readFileSync17(path101, "utf8");
|
|
41597
41705
|
return parseFrontmatter(md);
|
|
41598
41706
|
}
|
|
41599
41707
|
/** Read a Markdown file; returns null if not found. */
|
|
41600
|
-
readIfExists(
|
|
41601
|
-
if (!existsSync19(
|
|
41602
|
-
return this.read(
|
|
41708
|
+
readIfExists(path101) {
|
|
41709
|
+
if (!existsSync19(path101)) return null;
|
|
41710
|
+
return this.read(path101);
|
|
41603
41711
|
}
|
|
41604
41712
|
/**
|
|
41605
41713
|
* Write a Markdown file atomically (tmp + rename). Creates parent dirs.
|
|
41606
41714
|
* The meta object is serialized as YAML frontmatter; body as Markdown.
|
|
41607
41715
|
*/
|
|
41608
|
-
write(
|
|
41609
|
-
mkdirSync10(dirname2(
|
|
41610
|
-
const tmp =
|
|
41716
|
+
write(path101, meta3, body) {
|
|
41717
|
+
mkdirSync10(dirname2(path101), { recursive: true });
|
|
41718
|
+
const tmp = path101 + ".tmp-" + process.pid;
|
|
41611
41719
|
const md = serializeFrontmatter(meta3, body);
|
|
41612
41720
|
writeFileSync14(tmp, md, "utf8");
|
|
41613
|
-
renameSync2(tmp,
|
|
41721
|
+
renameSync2(tmp, path101);
|
|
41614
41722
|
}
|
|
41615
41723
|
/** List all .md files in a directory (non-recursive). */
|
|
41616
41724
|
listMarkdown(dir) {
|
|
@@ -41721,8 +41829,8 @@ function nextPlanTaskId(store6) {
|
|
|
41721
41829
|
return `t${store6.counter}`;
|
|
41722
41830
|
}
|
|
41723
41831
|
function writePlanTaskArtifact(rootDir, task) {
|
|
41724
|
-
const
|
|
41725
|
-
mkdirSync11(dirname3(
|
|
41832
|
+
const path101 = join17(rootDir, "plan-tasks", `${task.id}.md`);
|
|
41833
|
+
mkdirSync11(dirname3(path101), { recursive: true });
|
|
41726
41834
|
const meta3 = {
|
|
41727
41835
|
kind: "task",
|
|
41728
41836
|
id: task.id,
|
|
@@ -41743,7 +41851,7 @@ function writePlanTaskArtifact(rootDir, task) {
|
|
|
41743
41851
|
task.notes?.trim() ? task.notes.trim() : "_(no notes)_",
|
|
41744
41852
|
""
|
|
41745
41853
|
].filter((l) => l !== null).join("\n");
|
|
41746
|
-
new Storage().write(
|
|
41854
|
+
new Storage().write(path101, meta3, body);
|
|
41747
41855
|
}
|
|
41748
41856
|
function loadHandle(rootDir) {
|
|
41749
41857
|
const jsonPath = join17(rootDir, "plan.json");
|
|
@@ -52074,21 +52182,21 @@ function normalizeAuth(auth) {
|
|
|
52074
52182
|
return "agent";
|
|
52075
52183
|
}
|
|
52076
52184
|
function readSecrets() {
|
|
52077
|
-
const
|
|
52078
|
-
if (!existsSync30(
|
|
52185
|
+
const path101 = getSshSecretsPath();
|
|
52186
|
+
if (!existsSync30(path101)) return {};
|
|
52079
52187
|
try {
|
|
52080
|
-
return JSON.parse(readFileSync22(
|
|
52188
|
+
return JSON.parse(readFileSync22(path101, "utf8"));
|
|
52081
52189
|
} catch {
|
|
52082
52190
|
return {};
|
|
52083
52191
|
}
|
|
52084
52192
|
}
|
|
52085
52193
|
function writeSecrets(data) {
|
|
52086
|
-
const
|
|
52087
|
-
mkdirSync13(dirname4(
|
|
52088
|
-
writeFileSync16(
|
|
52194
|
+
const path101 = getSshSecretsPath();
|
|
52195
|
+
mkdirSync13(dirname4(path101), { recursive: true });
|
|
52196
|
+
writeFileSync16(path101, `${JSON.stringify(data, null, 2)}
|
|
52089
52197
|
`, "utf8");
|
|
52090
52198
|
try {
|
|
52091
|
-
chmodSync(
|
|
52199
|
+
chmodSync(path101, 384);
|
|
52092
52200
|
} catch {
|
|
52093
52201
|
}
|
|
52094
52202
|
}
|
|
@@ -52117,10 +52225,10 @@ function deleteSshPassword(id3) {
|
|
|
52117
52225
|
writeSecrets({ passwords });
|
|
52118
52226
|
}
|
|
52119
52227
|
function readStore2() {
|
|
52120
|
-
const
|
|
52121
|
-
if (!existsSync30(
|
|
52228
|
+
const path101 = getSshTargetsPath();
|
|
52229
|
+
if (!existsSync30(path101)) return [];
|
|
52122
52230
|
try {
|
|
52123
|
-
const parsed = JSON.parse(readFileSync22(
|
|
52231
|
+
const parsed = JSON.parse(readFileSync22(path101, "utf8"));
|
|
52124
52232
|
const list = Array.isArray(parsed.targets) ? parsed.targets : [];
|
|
52125
52233
|
return list.filter(
|
|
52126
52234
|
(t) => t && typeof t.id === "string" && typeof t.host === "string" && typeof t.user === "string"
|
|
@@ -52135,11 +52243,11 @@ function readStore2() {
|
|
|
52135
52243
|
}
|
|
52136
52244
|
}
|
|
52137
52245
|
function writeStore2(targets) {
|
|
52138
|
-
const
|
|
52139
|
-
mkdirSync13(dirname4(
|
|
52246
|
+
const path101 = getSshTargetsPath();
|
|
52247
|
+
mkdirSync13(dirname4(path101), { recursive: true });
|
|
52140
52248
|
const clean = targets.map(({ hasPassword: _hp, ...t }) => t);
|
|
52141
52249
|
writeFileSync16(
|
|
52142
|
-
|
|
52250
|
+
path101,
|
|
52143
52251
|
`${JSON.stringify({ targets: clean }, null, 2)}
|
|
52144
52252
|
`,
|
|
52145
52253
|
"utf8"
|
|
@@ -52385,11 +52493,11 @@ function formatSshTargetsForPrompt() {
|
|
|
52385
52493
|
];
|
|
52386
52494
|
for (const t of targets) {
|
|
52387
52495
|
const tags = t.tags?.length ? ` tags=[${t.tags.join(",")}]` : "";
|
|
52388
|
-
const
|
|
52496
|
+
const path101 = t.defaultRemotePath ? ` remotePath=${t.defaultRemotePath}` : "";
|
|
52389
52497
|
const allow = t.allowedCommands?.length ? ` allowed=${t.allowedCommands.join("|")}` : " allowed=status-only";
|
|
52390
52498
|
const auth = t.auth === "password" ? " auth=password" : t.auth === "keyPath" ? " auth=key" : " auth=agent";
|
|
52391
52499
|
lines.push(
|
|
52392
|
-
`- id=${t.id} name=${t.name} ${t.user}@${t.host}:${t.port ?? 22}${auth}${
|
|
52500
|
+
`- id=${t.id} name=${t.name} ${t.user}@${t.host}:${t.port ?? 22}${auth}${path101}${tags}${allow}`
|
|
52393
52501
|
);
|
|
52394
52502
|
}
|
|
52395
52503
|
return lines.join("\n");
|
|
@@ -57289,6 +57397,8 @@ function parseHeadlessFlags(argv) {
|
|
|
57289
57397
|
missionStrict = true;
|
|
57290
57398
|
} else if (arg === "--no-mission-strict") {
|
|
57291
57399
|
missionStrict = false;
|
|
57400
|
+
} else if (arg === "--allow-unverified") {
|
|
57401
|
+
process.env.ZELARI_ALLOW_UNVERIFIED = "1";
|
|
57292
57402
|
} else if (arg === "--kraken-graph") {
|
|
57293
57403
|
krakenGraph = argv[i + 1];
|
|
57294
57404
|
i++;
|
|
@@ -57402,6 +57512,7 @@ __export(headlessSpine_exports, {
|
|
|
57402
57512
|
seedHeadlessModelHistory: () => seedHeadlessModelHistory,
|
|
57403
57513
|
sessionStartedEvent: () => sessionStartedEvent
|
|
57404
57514
|
});
|
|
57515
|
+
import path67 from "node:path";
|
|
57405
57516
|
function sessionStartedEvent(handle) {
|
|
57406
57517
|
return {
|
|
57407
57518
|
type: "session_started",
|
|
@@ -57413,6 +57524,20 @@ function resolveHeadlessProfileId(mode, explicit) {
|
|
|
57413
57524
|
if (explicit) return resolveProfile(explicit).id;
|
|
57414
57525
|
return defaultProfileForMode(mode ?? "kraken");
|
|
57415
57526
|
}
|
|
57527
|
+
async function countVerificationEvidenceInLog(mirror, sessionId2) {
|
|
57528
|
+
if (mirror.status !== "active" && mirror.status !== "closed") return -1;
|
|
57529
|
+
try {
|
|
57530
|
+
await mirror.flush().catch(() => void 0);
|
|
57531
|
+
const report = await readSessionLog(path67.join(mirror.sessionsDir, sessionId2, "events.jsonl"));
|
|
57532
|
+
return report.events.filter((e) => e.kind === "verification.evidence").length;
|
|
57533
|
+
} catch (err) {
|
|
57534
|
+
process.stderr.write(
|
|
57535
|
+
`[zelari-code] verification-evidence count unavailable (${err instanceof Error ? err.message : String(err)}) \u2014 event-back gate skipped
|
|
57536
|
+
`
|
|
57537
|
+
);
|
|
57538
|
+
return -1;
|
|
57539
|
+
}
|
|
57540
|
+
}
|
|
57416
57541
|
async function openHeadlessSpine(opts) {
|
|
57417
57542
|
const profileId = resolveHeadlessProfileId(opts.mode, opts.profile);
|
|
57418
57543
|
let profileTools = [];
|
|
@@ -57484,6 +57609,9 @@ async function openHeadlessSpine(opts) {
|
|
|
57484
57609
|
lastVerificationRun() {
|
|
57485
57610
|
return spine.lastVerificationRun();
|
|
57486
57611
|
},
|
|
57612
|
+
countVerificationEvidence() {
|
|
57613
|
+
return countVerificationEvidenceInLog(spine, opts.sessionId);
|
|
57614
|
+
},
|
|
57487
57615
|
missionPhase(phase2, note) {
|
|
57488
57616
|
spine.missionPhase(phase2, note);
|
|
57489
57617
|
},
|
|
@@ -57591,6 +57719,7 @@ var init_headlessSpine = __esm({
|
|
|
57591
57719
|
init_dist();
|
|
57592
57720
|
init_session();
|
|
57593
57721
|
init_mission2();
|
|
57722
|
+
init_session();
|
|
57594
57723
|
init_runtime();
|
|
57595
57724
|
init_sessionSpine();
|
|
57596
57725
|
init_budgetRuntime();
|
|
@@ -58194,7 +58323,7 @@ var init_planDetect = __esm({
|
|
|
58194
58323
|
// src/cli/memory/legacyImport.ts
|
|
58195
58324
|
import { createHash as createHash18 } from "node:crypto";
|
|
58196
58325
|
import { promises as fs27 } from "node:fs";
|
|
58197
|
-
import * as
|
|
58326
|
+
import * as path68 from "node:path";
|
|
58198
58327
|
function sourceId(fact, line) {
|
|
58199
58328
|
return `jsonl:${fact.id ?? createHash18("sha256").update(line).digest("hex")}`;
|
|
58200
58329
|
}
|
|
@@ -58212,7 +58341,7 @@ function timestamp(value) {
|
|
|
58212
58341
|
}
|
|
58213
58342
|
async function importLegacyMemoryLog(backend, service) {
|
|
58214
58343
|
const result = { found: 0, imported: 0, skipped: 0, corrupt: 0 };
|
|
58215
|
-
const logPath =
|
|
58344
|
+
const logPath = path68.join(path68.dirname(backend.databasePath), "log.jsonl");
|
|
58216
58345
|
let raw;
|
|
58217
58346
|
try {
|
|
58218
58347
|
raw = await fs27.readFile(logPath, "utf8");
|
|
@@ -58395,7 +58524,7 @@ var init_sqliteCodec = __esm({
|
|
|
58395
58524
|
// src/cli/memory/sqliteRpc.ts
|
|
58396
58525
|
import { existsSync as existsSync36 } from "node:fs";
|
|
58397
58526
|
import { fileURLToPath as fileURLToPath2, pathToFileURL as pathToFileURL2 } from "node:url";
|
|
58398
|
-
import * as
|
|
58527
|
+
import * as path69 from "node:path";
|
|
58399
58528
|
import { Worker } from "node:worker_threads";
|
|
58400
58529
|
function isBusy(error51) {
|
|
58401
58530
|
const candidate = error51;
|
|
@@ -58404,10 +58533,10 @@ function isBusy(error51) {
|
|
|
58404
58533
|
);
|
|
58405
58534
|
}
|
|
58406
58535
|
function resolveWorkerUrl() {
|
|
58407
|
-
const here =
|
|
58408
|
-
const direct =
|
|
58536
|
+
const here = path69.dirname(fileURLToPath2(import.meta.url));
|
|
58537
|
+
const direct = path69.join(here, "sqliteWorker.mjs");
|
|
58409
58538
|
if (existsSync36(direct)) return pathToFileURL2(direct);
|
|
58410
|
-
return pathToFileURL2(
|
|
58539
|
+
return pathToFileURL2(path69.join(here, "memory", "sqliteWorker.mjs"));
|
|
58411
58540
|
}
|
|
58412
58541
|
var SqliteWorkerRpc;
|
|
58413
58542
|
var init_sqliteRpc = __esm({
|
|
@@ -58696,7 +58825,7 @@ WHERE NOT EXISTS (SELECT 1 FROM memory_fts f WHERE f.node_id = n.id);
|
|
|
58696
58825
|
// src/cli/memory/sqliteBackend.ts
|
|
58697
58826
|
import { createHash as createHash19, randomUUID as randomUUID6 } from "node:crypto";
|
|
58698
58827
|
import { promises as fs28 } from "node:fs";
|
|
58699
|
-
import * as
|
|
58828
|
+
import * as path70 from "node:path";
|
|
58700
58829
|
function boundedLimit(value, fallback = 50) {
|
|
58701
58830
|
return Math.max(1, Math.min(Math.floor(value ?? fallback), 1e5));
|
|
58702
58831
|
}
|
|
@@ -58758,16 +58887,16 @@ VALUES (${Array.from({ length: 19 }, () => "?").join(",")})`;
|
|
|
58758
58887
|
try {
|
|
58759
58888
|
resolved = await fs28.realpath(projectRoot);
|
|
58760
58889
|
} catch {
|
|
58761
|
-
resolved =
|
|
58890
|
+
resolved = path70.resolve(projectRoot);
|
|
58762
58891
|
}
|
|
58763
58892
|
if (this.initialized && resolved === this.projectRoot) return;
|
|
58764
58893
|
if (this.initialized) await this.close();
|
|
58765
58894
|
const filename = this.options.filename ?? "memory.db";
|
|
58766
|
-
if (
|
|
58895
|
+
if (path70.basename(filename) !== filename || filename === "." || filename === "..") {
|
|
58767
58896
|
throw new Error("SQLite memory filename must not contain a path.");
|
|
58768
58897
|
}
|
|
58769
|
-
const zelariDirectory =
|
|
58770
|
-
const directory =
|
|
58898
|
+
const zelariDirectory = path70.join(resolved, ".zelari");
|
|
58899
|
+
const directory = path70.join(zelariDirectory, "memory");
|
|
58771
58900
|
for (const candidate of [zelariDirectory, directory]) {
|
|
58772
58901
|
let stat8;
|
|
58773
58902
|
try {
|
|
@@ -58786,12 +58915,12 @@ VALUES (${Array.from({ length: 19 }, () => "?").join(",")})`;
|
|
|
58786
58915
|
}
|
|
58787
58916
|
}
|
|
58788
58917
|
const canonicalDirectory = await fs28.realpath(directory);
|
|
58789
|
-
const relativeDirectory =
|
|
58790
|
-
if (relativeDirectory.startsWith("..") ||
|
|
58918
|
+
const relativeDirectory = path70.relative(resolved, canonicalDirectory);
|
|
58919
|
+
if (relativeDirectory.startsWith("..") || path70.isAbsolute(relativeDirectory)) {
|
|
58791
58920
|
throw new Error("SQLite memory directory resolves outside the active project.");
|
|
58792
58921
|
}
|
|
58793
58922
|
this.projectRoot = resolved;
|
|
58794
|
-
this.databasePath =
|
|
58923
|
+
this.databasePath = path70.join(canonicalDirectory, filename);
|
|
58795
58924
|
const opened = await this.rpc.open({
|
|
58796
58925
|
dbPath: this.databasePath,
|
|
58797
58926
|
schemaSql: SQLITE_MEMORY_BASE_SCHEMA,
|
|
@@ -59324,7 +59453,7 @@ __export(serviceFactory_exports, {
|
|
|
59324
59453
|
});
|
|
59325
59454
|
import { createHash as createHash20 } from "node:crypto";
|
|
59326
59455
|
import { promises as fs29 } from "node:fs";
|
|
59327
|
-
import * as
|
|
59456
|
+
import * as path71 from "node:path";
|
|
59328
59457
|
function isMemoryV2Enabled(env = process.env) {
|
|
59329
59458
|
if (env.ZELARI_MEMORY === "0") return false;
|
|
59330
59459
|
if (env.ZELARI_MEMORY_BACKEND === "file" || env.ZELARI_MEMORY_BACKEND === "jsonl") return false;
|
|
@@ -59345,7 +59474,7 @@ async function canonicalProjectId(projectRoot) {
|
|
|
59345
59474
|
try {
|
|
59346
59475
|
canonical = await fs29.realpath(projectRoot);
|
|
59347
59476
|
} catch {
|
|
59348
|
-
canonical =
|
|
59477
|
+
canonical = path71.resolve(projectRoot);
|
|
59349
59478
|
}
|
|
59350
59479
|
canonical = canonical.replace(/\\/g, "/").replace(/\/$/, "");
|
|
59351
59480
|
if (process.platform === "win32") canonical = canonical.toLocaleLowerCase("en-US");
|
|
@@ -60047,8 +60176,8 @@ function readPlan(ctx) {
|
|
|
60047
60176
|
} catch {
|
|
60048
60177
|
}
|
|
60049
60178
|
}
|
|
60050
|
-
const
|
|
60051
|
-
const doc = ctx.storage.readIfExists(
|
|
60179
|
+
const path101 = workspaceFile(ctx.rootDir, "plan");
|
|
60180
|
+
const doc = ctx.storage.readIfExists(path101);
|
|
60052
60181
|
if (!doc) return { phases: [], tasks: [], milestones: [] };
|
|
60053
60182
|
const meta3 = doc.meta;
|
|
60054
60183
|
return {
|
|
@@ -60229,7 +60358,7 @@ function addMilestoneRecord(ctx, summary, input) {
|
|
|
60229
60358
|
dueDate: input.dueDate,
|
|
60230
60359
|
targetVersion: version2
|
|
60231
60360
|
});
|
|
60232
|
-
const
|
|
60361
|
+
const path101 = join31(ctx.rootDir, "milestones", `${id3}.md`);
|
|
60233
60362
|
const meta3 = {
|
|
60234
60363
|
kind: "milestone",
|
|
60235
60364
|
id: id3,
|
|
@@ -60246,7 +60375,7 @@ function addMilestoneRecord(ctx, summary, input) {
|
|
|
60246
60375
|
`Target version: ${version2}`,
|
|
60247
60376
|
""
|
|
60248
60377
|
].join("\n");
|
|
60249
|
-
ctx.storage.write(
|
|
60378
|
+
ctx.storage.write(path101, meta3, body);
|
|
60250
60379
|
return { id: id3, created: true };
|
|
60251
60380
|
}
|
|
60252
60381
|
function readPlanSummary(ctx) {
|
|
@@ -60450,7 +60579,7 @@ function addIdeaStub(ctx) {
|
|
|
60450
60579
|
const tags = args["tags"] ?? [];
|
|
60451
60580
|
const category = args["category"] ?? "General";
|
|
60452
60581
|
const id3 = `${nextAdrId(ctx)}-${slugify3(title)}`;
|
|
60453
|
-
const
|
|
60582
|
+
const path101 = workspaceArtifact(ctx.rootDir, "decisions", id3);
|
|
60454
60583
|
const meta3 = {
|
|
60455
60584
|
kind: "adr",
|
|
60456
60585
|
status: "proposed",
|
|
@@ -60476,7 +60605,7 @@ function addIdeaStub(ctx) {
|
|
|
60476
60605
|
...consequences.map((c) => `- ${c}`),
|
|
60477
60606
|
""
|
|
60478
60607
|
].join("\n");
|
|
60479
|
-
ctx.storage.write(
|
|
60608
|
+
ctx.storage.write(path101, meta3, body);
|
|
60480
60609
|
return `ADR ${id3} created: "${title}". Status: proposed. Promote to accepted via /update ADR or manual edit.`;
|
|
60481
60610
|
});
|
|
60482
60611
|
}
|
|
@@ -60558,14 +60687,14 @@ function createDocumentStub(ctx) {
|
|
|
60558
60687
|
ctx.storage.write(risksPath, riskMeta, content);
|
|
60559
60688
|
return `Document "${title}" created at risks.md (workspace root).`;
|
|
60560
60689
|
}
|
|
60561
|
-
const
|
|
60690
|
+
const path101 = workspaceArtifact(ctx.rootDir, "docs", slug);
|
|
60562
60691
|
const meta3 = {
|
|
60563
60692
|
kind: "doc",
|
|
60564
60693
|
id: slug,
|
|
60565
60694
|
date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
|
|
60566
60695
|
tags
|
|
60567
60696
|
};
|
|
60568
|
-
ctx.storage.write(
|
|
60697
|
+
ctx.storage.write(path101, meta3, content);
|
|
60569
60698
|
return `Document "${title}" created at docs/${slug}.md.`;
|
|
60570
60699
|
});
|
|
60571
60700
|
}
|
|
@@ -61190,10 +61319,10 @@ function getUserMcpPath() {
|
|
|
61190
61319
|
function getProjectMcpPath(projectRoot) {
|
|
61191
61320
|
return join32(projectRoot, ".zelari", "mcp.json");
|
|
61192
61321
|
}
|
|
61193
|
-
function readFile9(
|
|
61194
|
-
if (!existsSync42(
|
|
61322
|
+
function readFile9(path101) {
|
|
61323
|
+
if (!existsSync42(path101)) return {};
|
|
61195
61324
|
try {
|
|
61196
|
-
const parsed = JSON.parse(readFileSync30(
|
|
61325
|
+
const parsed = JSON.parse(readFileSync30(path101, "utf8"));
|
|
61197
61326
|
const out = {};
|
|
61198
61327
|
for (const [name, cfg] of Object.entries(parsed.mcpServers ?? {})) {
|
|
61199
61328
|
const hasCommand = !!cfg && typeof cfg.command === "string" && !!cfg.command.trim();
|
|
@@ -61215,10 +61344,10 @@ function readFile9(path100) {
|
|
|
61215
61344
|
return {};
|
|
61216
61345
|
}
|
|
61217
61346
|
}
|
|
61218
|
-
function writeFile3(
|
|
61219
|
-
mkdirSync17(dirname9(
|
|
61347
|
+
function writeFile3(path101, servers) {
|
|
61348
|
+
mkdirSync17(dirname9(path101), { recursive: true });
|
|
61220
61349
|
const body = { mcpServers: servers };
|
|
61221
|
-
writeFileSync19(
|
|
61350
|
+
writeFileSync19(path101, `${JSON.stringify(body, null, 2)}
|
|
61222
61351
|
`, "utf8");
|
|
61223
61352
|
}
|
|
61224
61353
|
function listMcpServers(projectRoot) {
|
|
@@ -61256,9 +61385,9 @@ function upsertMcpServer(opts) {
|
|
|
61256
61385
|
error: "either command (stdio) or url (http) is required"
|
|
61257
61386
|
};
|
|
61258
61387
|
}
|
|
61259
|
-
let
|
|
61388
|
+
let path101;
|
|
61260
61389
|
if (opts.scope === "user") {
|
|
61261
|
-
|
|
61390
|
+
path101 = getUserMcpPath();
|
|
61262
61391
|
} else {
|
|
61263
61392
|
const root = opts.projectRoot?.trim();
|
|
61264
61393
|
if (!root) {
|
|
@@ -61267,9 +61396,9 @@ function upsertMcpServer(opts) {
|
|
|
61267
61396
|
error: "projectRoot required for project scope (Open Folder first)"
|
|
61268
61397
|
};
|
|
61269
61398
|
}
|
|
61270
|
-
|
|
61399
|
+
path101 = getProjectMcpPath(root);
|
|
61271
61400
|
}
|
|
61272
|
-
const current = readFile9(
|
|
61401
|
+
const current = readFile9(path101);
|
|
61273
61402
|
current[name] = {
|
|
61274
61403
|
command: hasCommand ? opts.config.command.trim() : void 0,
|
|
61275
61404
|
args: opts.config.args,
|
|
@@ -61280,21 +61409,21 @@ function upsertMcpServer(opts) {
|
|
|
61280
61409
|
serial: opts.config.serial,
|
|
61281
61410
|
enabled: opts.config.enabled !== false
|
|
61282
61411
|
};
|
|
61283
|
-
writeFile3(
|
|
61284
|
-
return { ok: true, path:
|
|
61412
|
+
writeFile3(path101, current);
|
|
61413
|
+
return { ok: true, path: path101 };
|
|
61285
61414
|
}
|
|
61286
61415
|
function removeMcpServer(opts) {
|
|
61287
|
-
const
|
|
61288
|
-
if (!
|
|
61416
|
+
const path101 = opts.scope === "user" ? getUserMcpPath() : opts.projectRoot ? getProjectMcpPath(opts.projectRoot) : null;
|
|
61417
|
+
if (!path101) {
|
|
61289
61418
|
return { ok: false, error: "projectRoot required for project scope" };
|
|
61290
61419
|
}
|
|
61291
|
-
const current = readFile9(
|
|
61420
|
+
const current = readFile9(path101);
|
|
61292
61421
|
if (!(opts.name in current)) {
|
|
61293
|
-
return { ok: false, error: `Server "${opts.name}" not found in ${
|
|
61422
|
+
return { ok: false, error: `Server "${opts.name}" not found in ${path101}` };
|
|
61294
61423
|
}
|
|
61295
61424
|
delete current[opts.name];
|
|
61296
|
-
writeFile3(
|
|
61297
|
-
return { ok: true, path:
|
|
61425
|
+
writeFile3(path101, current);
|
|
61426
|
+
return { ok: true, path: path101 };
|
|
61298
61427
|
}
|
|
61299
61428
|
var init_mcpConfigIo = __esm({
|
|
61300
61429
|
"src/cli/mcp/mcpConfigIo.ts"() {
|
|
@@ -61765,10 +61894,10 @@ import { createHash as createHash21 } from "node:crypto";
|
|
|
61765
61894
|
import { join as join34 } from "node:path";
|
|
61766
61895
|
import { readFile as readFile10 } from "node:fs/promises";
|
|
61767
61896
|
async function readPackageJson3(projectRoot) {
|
|
61768
|
-
const
|
|
61769
|
-
if (!existsSync44(
|
|
61897
|
+
const path101 = join34(projectRoot, "package.json");
|
|
61898
|
+
if (!existsSync44(path101)) return null;
|
|
61770
61899
|
try {
|
|
61771
|
-
return JSON.parse(await readFile10(
|
|
61900
|
+
return JSON.parse(await readFile10(path101, "utf8"));
|
|
61772
61901
|
} catch {
|
|
61773
61902
|
return null;
|
|
61774
61903
|
}
|
|
@@ -61850,9 +61979,9 @@ async function genBuild(ctx) {
|
|
|
61850
61979
|
].join("\n");
|
|
61851
61980
|
}
|
|
61852
61981
|
async function genOpenQuestions(ctx) {
|
|
61853
|
-
const
|
|
61854
|
-
if (!existsSync44(
|
|
61855
|
-
const content = readFileSync32(
|
|
61982
|
+
const path101 = join34(ctx.rootDir, "risks.md");
|
|
61983
|
+
if (!existsSync44(path101)) return "_No open questions._";
|
|
61984
|
+
const content = readFileSync32(path101, "utf8");
|
|
61856
61985
|
const lines = content.split("\n");
|
|
61857
61986
|
const questions = [];
|
|
61858
61987
|
let currentTitle = "";
|
|
@@ -62126,9 +62255,9 @@ function versionKey(value) {
|
|
|
62126
62255
|
function firstString2(v) {
|
|
62127
62256
|
return typeof v === "string" && v.trim().length > 0 ? v : null;
|
|
62128
62257
|
}
|
|
62129
|
-
function readFileSyncSafe(
|
|
62258
|
+
function readFileSyncSafe(path101) {
|
|
62130
62259
|
try {
|
|
62131
|
-
return readFileSync33(
|
|
62260
|
+
return readFileSync33(path101, "utf8");
|
|
62132
62261
|
} catch {
|
|
62133
62262
|
return null;
|
|
62134
62263
|
}
|
|
@@ -62376,7 +62505,7 @@ __export(evidenceFromSpine_exports, {
|
|
|
62376
62505
|
evidenceRefsFromEventLines: () => evidenceRefsFromEventLines
|
|
62377
62506
|
});
|
|
62378
62507
|
import { existsSync as existsSync47, readFileSync as readFileSync35 } from "node:fs";
|
|
62379
|
-
import
|
|
62508
|
+
import path72 from "node:path";
|
|
62380
62509
|
function asRecord2(v) {
|
|
62381
62510
|
return v && typeof v === "object" && !Array.isArray(v) ? v : void 0;
|
|
62382
62511
|
}
|
|
@@ -62414,7 +62543,7 @@ function evidenceRefsFromEventLines(lines) {
|
|
|
62414
62543
|
}
|
|
62415
62544
|
function collectSessionEvidenceRefs(sessionId2) {
|
|
62416
62545
|
try {
|
|
62417
|
-
const file2 =
|
|
62546
|
+
const file2 = path72.join(sessionsDir(), sessionId2, "events.jsonl");
|
|
62418
62547
|
if (!existsSync47(file2)) return [];
|
|
62419
62548
|
return evidenceRefsFromEventLines(readFileSync35(file2, "utf8").split("\n"));
|
|
62420
62549
|
} catch {
|
|
@@ -62664,8 +62793,8 @@ async function runPostCouncilHook(ctx, options) {
|
|
|
62664
62793
|
sources: scope.sources
|
|
62665
62794
|
} : void 0
|
|
62666
62795
|
});
|
|
62667
|
-
const
|
|
62668
|
-
completionHook = { ran: true, path:
|
|
62796
|
+
const path101 = writeCouncilCompletion(ctx.rootDir, completion);
|
|
62797
|
+
completionHook = { ran: true, path: path101, completion };
|
|
62669
62798
|
} catch (err) {
|
|
62670
62799
|
completionHook = {
|
|
62671
62800
|
ran: true,
|
|
@@ -62710,7 +62839,7 @@ import {
|
|
|
62710
62839
|
writeFileSync as writeFileSync22,
|
|
62711
62840
|
mkdirSync as mkdirSync18
|
|
62712
62841
|
} from "node:fs";
|
|
62713
|
-
import
|
|
62842
|
+
import path73 from "node:path";
|
|
62714
62843
|
var FeedbackStore;
|
|
62715
62844
|
var init_councilFeedback = __esm({
|
|
62716
62845
|
"src/cli/councilFeedback.ts"() {
|
|
@@ -62827,7 +62956,7 @@ var init_councilFeedback = __esm({
|
|
|
62827
62956
|
}
|
|
62828
62957
|
}
|
|
62829
62958
|
save() {
|
|
62830
|
-
mkdirSync18(
|
|
62959
|
+
mkdirSync18(path73.dirname(this.file), { recursive: true });
|
|
62831
62960
|
writeFileSync22(
|
|
62832
62961
|
this.file,
|
|
62833
62962
|
JSON.stringify({ entries: this.entries }, null, 2),
|
|
@@ -62902,12 +63031,12 @@ __export(ledger_exports, {
|
|
|
62902
63031
|
readLedger: () => readLedger
|
|
62903
63032
|
});
|
|
62904
63033
|
import { appendFileSync as appendFileSync4, existsSync as existsSync50, mkdirSync as mkdirSync19, readFileSync as readFileSync38 } from "node:fs";
|
|
62905
|
-
import
|
|
63034
|
+
import path74 from "node:path";
|
|
62906
63035
|
function evolutionMode(env = process.env) {
|
|
62907
63036
|
return env[EVOLUTION_ENV] === "shadow" ? "shadow" : "0";
|
|
62908
63037
|
}
|
|
62909
63038
|
function ledgerPath(cwd) {
|
|
62910
|
-
return
|
|
63039
|
+
return path74.join(cwd, LEDGER_REL);
|
|
62911
63040
|
}
|
|
62912
63041
|
function appendLedgerEntry(cwd, entry) {
|
|
62913
63042
|
if (evolutionMode() === "0") {
|
|
@@ -62915,7 +63044,7 @@ function appendLedgerEntry(cwd, entry) {
|
|
|
62915
63044
|
}
|
|
62916
63045
|
try {
|
|
62917
63046
|
const file2 = ledgerPath(cwd);
|
|
62918
|
-
mkdirSync19(
|
|
63047
|
+
mkdirSync19(path74.dirname(file2), { recursive: true });
|
|
62919
63048
|
appendFileSync4(file2, `${JSON.stringify(entry)}
|
|
62920
63049
|
`, "utf8");
|
|
62921
63050
|
return { written: true, path: file2 };
|
|
@@ -63016,7 +63145,7 @@ var init_ledger = __esm({
|
|
|
63016
63145
|
"src/cli/evolution/ledger.ts"() {
|
|
63017
63146
|
"use strict";
|
|
63018
63147
|
EVOLUTION_ENV = "ZELARI_EVOLUTION";
|
|
63019
|
-
LEDGER_REL =
|
|
63148
|
+
LEDGER_REL = path74.join(".zelari", "evolution", "ledger.jsonl");
|
|
63020
63149
|
TIER_WEIGHTS = {
|
|
63021
63150
|
build: 1,
|
|
63022
63151
|
"tool-output": 1,
|
|
@@ -63158,7 +63287,7 @@ __export(fileBackend_exports, {
|
|
|
63158
63287
|
});
|
|
63159
63288
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
63160
63289
|
import { promises as fs31 } from "node:fs";
|
|
63161
|
-
import * as
|
|
63290
|
+
import * as path75 from "node:path";
|
|
63162
63291
|
function tokenize2(text) {
|
|
63163
63292
|
return text.toLowerCase().split(/[^\p{L}\p{N}]+/u).filter((t) => t.length >= 3);
|
|
63164
63293
|
}
|
|
@@ -63211,8 +63340,8 @@ var init_fileBackend = __esm({
|
|
|
63211
63340
|
logPath = "";
|
|
63212
63341
|
memoryDir = "";
|
|
63213
63342
|
async init(projectRoot) {
|
|
63214
|
-
this.memoryDir =
|
|
63215
|
-
this.logPath =
|
|
63343
|
+
this.memoryDir = path75.join(projectRoot, ".zelari", "memory");
|
|
63344
|
+
this.logPath = path75.join(this.memoryDir, "log.jsonl");
|
|
63216
63345
|
await fs31.mkdir(this.memoryDir, { recursive: true });
|
|
63217
63346
|
}
|
|
63218
63347
|
async add(content, metadata2 = {}, graph) {
|
|
@@ -63285,12 +63414,12 @@ var init_fileBackend = __esm({
|
|
|
63285
63414
|
|
|
63286
63415
|
// src/cli/traceStore.ts
|
|
63287
63416
|
import { promises as fs32 } from "node:fs";
|
|
63288
|
-
import * as
|
|
63417
|
+
import * as path76 from "node:path";
|
|
63289
63418
|
function traceDir(projectRoot) {
|
|
63290
|
-
return
|
|
63419
|
+
return path76.join(projectRoot, ".zelari", "trace");
|
|
63291
63420
|
}
|
|
63292
63421
|
function tracePath(projectRoot, missionId) {
|
|
63293
|
-
return
|
|
63422
|
+
return path76.join(traceDir(projectRoot), `${missionId}.json`);
|
|
63294
63423
|
}
|
|
63295
63424
|
async function saveTrace(projectRoot, missionId, entries) {
|
|
63296
63425
|
const dir = traceDir(projectRoot);
|
|
@@ -63332,7 +63461,7 @@ __export(zelariMission_exports, {
|
|
|
63332
63461
|
});
|
|
63333
63462
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
63334
63463
|
import { promises as fs33 } from "node:fs";
|
|
63335
|
-
import * as
|
|
63464
|
+
import * as path77 from "node:path";
|
|
63336
63465
|
function resolveMaxIterations(env = process.env) {
|
|
63337
63466
|
const raw = env.ZELARI_MISSION_MAX_ITER;
|
|
63338
63467
|
const n = raw ? Number.parseInt(raw, 10) : DEFAULT_MAX_ITER;
|
|
@@ -63375,10 +63504,10 @@ function isMissionAutoStart(env = process.env) {
|
|
|
63375
63504
|
return env.ZELARI_MISSION_AUTO === "1";
|
|
63376
63505
|
}
|
|
63377
63506
|
async function writeMissionState(projectRoot, state3) {
|
|
63378
|
-
const dir =
|
|
63507
|
+
const dir = path77.join(projectRoot, ".zelari");
|
|
63379
63508
|
await fs33.mkdir(dir, { recursive: true });
|
|
63380
63509
|
await fs33.writeFile(
|
|
63381
|
-
|
|
63510
|
+
path77.join(dir, "mission-state.json"),
|
|
63382
63511
|
JSON.stringify(state3, null, 2) + "\n",
|
|
63383
63512
|
"utf8"
|
|
63384
63513
|
);
|
|
@@ -63392,7 +63521,7 @@ async function writeMissionState(projectRoot, state3) {
|
|
|
63392
63521
|
async function loadMissionState(projectRoot) {
|
|
63393
63522
|
try {
|
|
63394
63523
|
const raw = await fs33.readFile(
|
|
63395
|
-
|
|
63524
|
+
path77.join(projectRoot, ".zelari", "mission-state.json"),
|
|
63396
63525
|
"utf8"
|
|
63397
63526
|
);
|
|
63398
63527
|
const parsed = JSON.parse(raw);
|
|
@@ -64151,7 +64280,7 @@ function safeSocketPath(socketPath) {
|
|
|
64151
64280
|
return socketPath.trim();
|
|
64152
64281
|
}
|
|
64153
64282
|
function startPermissionBroker(socketPath, handlers, opts) {
|
|
64154
|
-
const
|
|
64283
|
+
const path101 = safeSocketPath(socketPath);
|
|
64155
64284
|
const requestTimeoutMs = opts?.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
|
|
64156
64285
|
const sockets = /* @__PURE__ */ new Set();
|
|
64157
64286
|
const server = createServer2((socket) => {
|
|
@@ -64251,10 +64380,10 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
64251
64380
|
return new Promise((resolve9, reject) => {
|
|
64252
64381
|
const onError = (err) => reject(err);
|
|
64253
64382
|
server.once("error", onError);
|
|
64254
|
-
server.listen(
|
|
64383
|
+
server.listen(path101, () => {
|
|
64255
64384
|
server.removeListener("error", onError);
|
|
64256
64385
|
resolve9({
|
|
64257
|
-
socketPath:
|
|
64386
|
+
socketPath: path101,
|
|
64258
64387
|
stop: () => new Promise((res) => {
|
|
64259
64388
|
for (const s of sockets) s.destroy();
|
|
64260
64389
|
sockets.clear();
|
|
@@ -64265,7 +64394,7 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
64265
64394
|
if (done) return;
|
|
64266
64395
|
done = true;
|
|
64267
64396
|
if (process.platform !== "win32") {
|
|
64268
|
-
unlink(
|
|
64397
|
+
unlink(path101, () => res());
|
|
64269
64398
|
} else {
|
|
64270
64399
|
res();
|
|
64271
64400
|
}
|
|
@@ -64278,11 +64407,11 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
64278
64407
|
});
|
|
64279
64408
|
}
|
|
64280
64409
|
function requestBrokerAsk(socketPath, ask, opts) {
|
|
64281
|
-
const
|
|
64410
|
+
const path101 = safeSocketPath(socketPath);
|
|
64282
64411
|
const requestTimeoutMs = opts?.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
|
|
64283
64412
|
const connectTimeoutMs = opts?.connectTimeoutMs ?? PERMISSION_BROKER_DEFAULT_CONNECT_TIMEOUT_MS;
|
|
64284
64413
|
return new Promise((resolve9, reject) => {
|
|
64285
|
-
const socket = connect(
|
|
64414
|
+
const socket = connect(path101);
|
|
64286
64415
|
let buffer = "";
|
|
64287
64416
|
let settled = false;
|
|
64288
64417
|
const settle = (fn) => {
|
|
@@ -64297,7 +64426,7 @@ function requestBrokerAsk(socketPath, ask, opts) {
|
|
|
64297
64426
|
settle(
|
|
64298
64427
|
() => reject(
|
|
64299
64428
|
new Error(
|
|
64300
|
-
`permission broker unavailable at "${
|
|
64429
|
+
`permission broker unavailable at "${path101}" (connect timed out after ${connectTimeoutMs}ms)`
|
|
64301
64430
|
)
|
|
64302
64431
|
)
|
|
64303
64432
|
);
|
|
@@ -65486,7 +65615,7 @@ var init_prereqChecks = __esm({
|
|
|
65486
65615
|
|
|
65487
65616
|
// src/cli/plugins/prefs.ts
|
|
65488
65617
|
import { existsSync as existsSync53, readFileSync as readFileSync40, writeFileSync as writeFileSync23, mkdirSync as mkdirSync20 } from "node:fs";
|
|
65489
|
-
import
|
|
65618
|
+
import path83 from "node:path";
|
|
65490
65619
|
function getPluginPrefsPath() {
|
|
65491
65620
|
return pluginsPrefsPath();
|
|
65492
65621
|
}
|
|
@@ -65509,7 +65638,7 @@ function getPluginPrefs() {
|
|
|
65509
65638
|
}
|
|
65510
65639
|
function writePluginPrefs(prefs) {
|
|
65511
65640
|
const file2 = getPluginPrefsPath();
|
|
65512
|
-
mkdirSync20(
|
|
65641
|
+
mkdirSync20(path83.dirname(file2), { recursive: true });
|
|
65513
65642
|
writeFileSync23(file2, JSON.stringify(prefs, null, 2), {
|
|
65514
65643
|
encoding: "utf-8",
|
|
65515
65644
|
mode: 384
|
|
@@ -65547,7 +65676,7 @@ __export(registry_exports, {
|
|
|
65547
65676
|
isBinaryOnPath: () => isBinaryOnPath
|
|
65548
65677
|
});
|
|
65549
65678
|
import { existsSync as existsSync54 } from "node:fs";
|
|
65550
|
-
import
|
|
65679
|
+
import path84 from "node:path";
|
|
65551
65680
|
function detectLocalBin(bin) {
|
|
65552
65681
|
return (cwd) => {
|
|
65553
65682
|
try {
|
|
@@ -65565,7 +65694,7 @@ function isBinaryOnPath(bin, opts = {}) {
|
|
|
65565
65694
|
const platform = opts.platform ?? process.platform;
|
|
65566
65695
|
const exists = opts.exists ?? existsSync54;
|
|
65567
65696
|
const pathEnv = opts.pathEnv ?? process.env.PATH ?? "";
|
|
65568
|
-
const pathMod = platform === "win32" ?
|
|
65697
|
+
const pathMod = platform === "win32" ? path84.win32 : path84.posix;
|
|
65569
65698
|
const sep4 = platform === "win32" ? ";" : ":";
|
|
65570
65699
|
const dirs = pathEnv.split(sep4).filter((d) => d.length > 0);
|
|
65571
65700
|
const candidates = [bin];
|
|
@@ -66670,7 +66799,7 @@ var init_policy = __esm({
|
|
|
66670
66799
|
|
|
66671
66800
|
// src/cli/orchestration/facts.ts
|
|
66672
66801
|
import { promises as fs43 } from "node:fs";
|
|
66673
|
-
import
|
|
66802
|
+
import path88 from "node:path";
|
|
66674
66803
|
async function collectRepoFileCount(root = process.cwd()) {
|
|
66675
66804
|
try {
|
|
66676
66805
|
await fs43.readdir(root);
|
|
@@ -66690,7 +66819,7 @@ async function collectRepoFileCount(root = process.cwd()) {
|
|
|
66690
66819
|
}
|
|
66691
66820
|
for (const e of entries) {
|
|
66692
66821
|
if (e.isDirectory()) {
|
|
66693
|
-
if (!SKIP_DIRS.has(e.name)) queue.push(
|
|
66822
|
+
if (!SKIP_DIRS.has(e.name)) queue.push(path88.join(dir, e.name));
|
|
66694
66823
|
} else if (e.isFile()) {
|
|
66695
66824
|
count++;
|
|
66696
66825
|
if (count > MAX_WALK_FILES) return count;
|
|
@@ -66788,7 +66917,7 @@ var init_streamScrub = __esm({
|
|
|
66788
66917
|
});
|
|
66789
66918
|
|
|
66790
66919
|
// src/cli/harnessState.ts
|
|
66791
|
-
import
|
|
66920
|
+
import path89 from "node:path";
|
|
66792
66921
|
function asString4(v) {
|
|
66793
66922
|
return typeof v === "string" ? v : "";
|
|
66794
66923
|
}
|
|
@@ -66963,7 +67092,7 @@ function contractFor(t) {
|
|
|
66963
67092
|
};
|
|
66964
67093
|
}
|
|
66965
67094
|
async function readHarnessState(sessionDir) {
|
|
66966
|
-
const report = await readSessionLog(
|
|
67095
|
+
const report = await readSessionLog(path89.join(sessionDir, "events.jsonl"));
|
|
66967
67096
|
return deriveHarnessState(report.events);
|
|
66968
67097
|
}
|
|
66969
67098
|
var init_harnessState = __esm({
|
|
@@ -66974,12 +67103,12 @@ var init_harnessState = __esm({
|
|
|
66974
67103
|
});
|
|
66975
67104
|
|
|
66976
67105
|
// src/cli/headless/harnessStateEmit.ts
|
|
66977
|
-
import
|
|
67106
|
+
import path90 from "node:path";
|
|
66978
67107
|
async function emitHarnessStateEvent(opts) {
|
|
66979
67108
|
if (opts.output !== "json") return;
|
|
66980
67109
|
try {
|
|
66981
67110
|
const sessionsDir2 = resolveSessionsDir({ workspaceRoot: opts.workspaceRoot });
|
|
66982
|
-
const state3 = await readHarnessState(
|
|
67111
|
+
const state3 = await readHarnessState(path90.join(sessionsDir2, opts.spine.sessionId));
|
|
66983
67112
|
opts.emitEvent({ type: "harness_state", ...state3 });
|
|
66984
67113
|
} catch (err) {
|
|
66985
67114
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -67536,13 +67665,13 @@ var init_verifierLifecycle = __esm({
|
|
|
67536
67665
|
|
|
67537
67666
|
// src/cli/extensions/sandboxedFs.ts
|
|
67538
67667
|
import { promises as fsp } from "node:fs";
|
|
67539
|
-
import
|
|
67668
|
+
import path91 from "node:path";
|
|
67540
67669
|
function errText(prefix, p3, err) {
|
|
67541
67670
|
const msg = err instanceof Error ? err.message : String(err);
|
|
67542
67671
|
return `[extension-fs] ${prefix} "${p3}": ${msg}`;
|
|
67543
67672
|
}
|
|
67544
67673
|
function bindSandboxedFs(root) {
|
|
67545
|
-
const resolvedRoot =
|
|
67674
|
+
const resolvedRoot = path91.resolve(root);
|
|
67546
67675
|
return {
|
|
67547
67676
|
root: resolvedRoot,
|
|
67548
67677
|
async readFile(relativePath) {
|
|
@@ -67558,7 +67687,7 @@ function bindSandboxedFs(root) {
|
|
|
67558
67687
|
try {
|
|
67559
67688
|
const target = resolveSandboxedPath(relativePath, { root: resolvedRoot });
|
|
67560
67689
|
verifyContainment(target, { root: resolvedRoot });
|
|
67561
|
-
await fsp.mkdir(
|
|
67690
|
+
await fsp.mkdir(path91.dirname(target), { recursive: true });
|
|
67562
67691
|
await fsp.writeFile(target, data, "utf8");
|
|
67563
67692
|
return typedOk({ path: target });
|
|
67564
67693
|
} catch (err) {
|
|
@@ -67743,7 +67872,7 @@ var init_loader = __esm({
|
|
|
67743
67872
|
|
|
67744
67873
|
// src/cli/headless/runOneTurn.ts
|
|
67745
67874
|
import { promises as fs44 } from "node:fs";
|
|
67746
|
-
import
|
|
67875
|
+
import path92 from "node:path";
|
|
67747
67876
|
function planModeFromOpts(opts) {
|
|
67748
67877
|
return (opts.phase ?? "build") === "plan";
|
|
67749
67878
|
}
|
|
@@ -68221,11 +68350,14 @@ async function runOneTurn(opts, provider, model, providerStream, extras) {
|
|
|
68221
68350
|
return null;
|
|
68222
68351
|
}
|
|
68223
68352
|
},
|
|
68224
|
-
|
|
68353
|
+
// F3 seam adapter (same as the gate sites below): the core engine reads
|
|
68354
|
+
// the anchor as `out.seq`, while the spine resolves the seq NUMBER. A bare
|
|
68355
|
+
// number here leaves the review evidence unanchored on the spine.
|
|
68356
|
+
emit: async (input) => ({ seq: await spine.appendEvent(input) })
|
|
68225
68357
|
};
|
|
68226
68358
|
const strictEnv = strictEnvOverlay(opts);
|
|
68227
68359
|
if (pass.finalReason === "completed" && pass.exitCode === 0 && isKrakenMode(opts.mode) && (isKrakenSelectionEnabled() || nativePackEnabled()) && !planModeFromOpts(opts)) {
|
|
68228
|
-
const strictGate = await evaluateStrictBuildGate("build", { emit: (input) => spine.appendEvent(input), cwd, env: strictEnv });
|
|
68360
|
+
const strictGate = await evaluateStrictBuildGate("build", { emit: async (input) => ({ seq: await spine.appendEvent(input) }), cwd, env: strictEnv });
|
|
68229
68361
|
await runAdvisoryVerifierReview(strictGate, verifierReviewDeps).catch(() => void 0);
|
|
68230
68362
|
const gate = strictGate.gate;
|
|
68231
68363
|
const verificationPayload = strictGateEventPayload(strictGate);
|
|
@@ -68235,7 +68367,7 @@ async function runOneTurn(opts, provider, model, providerStream, extras) {
|
|
|
68235
68367
|
}
|
|
68236
68368
|
await writeProofSafe(strictGate, { surface: "kraken", sessionId: spine.sessionId }, cwd);
|
|
68237
68369
|
if (strictGate.blocked) {
|
|
68238
|
-
const repairPrompt = buildKrakenRepairPrompt(gate);
|
|
68370
|
+
const repairPrompt = buildKrakenRepairPrompt(gate, repairExcerptsFromEvaluation(strictGate));
|
|
68239
68371
|
if (opts.output === "json") {
|
|
68240
68372
|
emitEvent({
|
|
68241
68373
|
type: "log",
|
|
@@ -68260,7 +68392,7 @@ async function runOneTurn(opts, provider, model, providerStream, extras) {
|
|
|
68260
68392
|
successfulWrites: pass.successfulWrites + repair.successfulWrites,
|
|
68261
68393
|
emittedWrites: pass.emittedWrites + repair.emittedWrites
|
|
68262
68394
|
};
|
|
68263
|
-
const after = await evaluateStrictBuildGate("build", { emit: (input) => spine.appendEvent(input), cwd, env: strictEnv });
|
|
68395
|
+
const after = await evaluateStrictBuildGate("build", { emit: async (input) => ({ seq: await spine.appendEvent(input) }), cwd, env: strictEnv });
|
|
68264
68396
|
await runAdvisoryVerifierReview(after, verifierReviewDeps).catch(() => void 0);
|
|
68265
68397
|
const afterPayload = strictGateEventPayload(after);
|
|
68266
68398
|
spine.verificationRun(afterPayload);
|
|
@@ -68310,7 +68442,7 @@ async function runOneTurn(opts, provider, model, providerStream, extras) {
|
|
|
68310
68442
|
if (json3) {
|
|
68311
68443
|
if (opts.exportSessionPath === "-") process.stdout.write(json3 + "\n");
|
|
68312
68444
|
else {
|
|
68313
|
-
await fs44.mkdir(
|
|
68445
|
+
await fs44.mkdir(path92.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
68314
68446
|
await fs44.writeFile(opts.exportSessionPath, json3, "utf8");
|
|
68315
68447
|
}
|
|
68316
68448
|
}
|
|
@@ -69359,9 +69491,9 @@ __export(triggerLock_exports, {
|
|
|
69359
69491
|
releaseLock: () => releaseLock
|
|
69360
69492
|
});
|
|
69361
69493
|
import { promises as fs45 } from "node:fs";
|
|
69362
|
-
import * as
|
|
69494
|
+
import * as path93 from "node:path";
|
|
69363
69495
|
function lockPath(projectRoot) {
|
|
69364
|
-
return
|
|
69496
|
+
return path93.join(projectRoot, ".zelari", "trigger.lock");
|
|
69365
69497
|
}
|
|
69366
69498
|
function isPidAlive(pid) {
|
|
69367
69499
|
try {
|
|
@@ -69374,7 +69506,7 @@ function isPidAlive(pid) {
|
|
|
69374
69506
|
}
|
|
69375
69507
|
async function acquireLock(projectRoot, now = () => /* @__PURE__ */ new Date()) {
|
|
69376
69508
|
const lp = lockPath(projectRoot);
|
|
69377
|
-
const dir =
|
|
69509
|
+
const dir = path93.dirname(lp);
|
|
69378
69510
|
await fs45.mkdir(dir, { recursive: true });
|
|
69379
69511
|
try {
|
|
69380
69512
|
const raw = await fs45.readFile(lp, "utf8");
|
|
@@ -69406,7 +69538,7 @@ var init_triggerLock = __esm({
|
|
|
69406
69538
|
|
|
69407
69539
|
// src/cli/runHeadless.ts
|
|
69408
69540
|
import { promises as fs46 } from "node:fs";
|
|
69409
|
-
import
|
|
69541
|
+
import path94 from "node:path";
|
|
69410
69542
|
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
69411
69543
|
async function runHeadless(opts) {
|
|
69412
69544
|
resetTaskSpawnCount();
|
|
@@ -69650,7 +69782,7 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
69650
69782
|
try {
|
|
69651
69783
|
let preflightGraph;
|
|
69652
69784
|
if (opts.runPlan && opts.runPlan.trim() !== "") {
|
|
69653
|
-
const planPath =
|
|
69785
|
+
const planPath = path94.join(cwd, ".zelari", "radio", `plan-${opts.runPlan}.json`);
|
|
69654
69786
|
log(`loading pre-flight plan: ${planPath}`);
|
|
69655
69787
|
let raw;
|
|
69656
69788
|
try {
|
|
@@ -69693,8 +69825,8 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
69693
69825
|
log(formatKrakenGraphAscii2(graph));
|
|
69694
69826
|
if (opts.planOnly) {
|
|
69695
69827
|
const planId = randomUUID10();
|
|
69696
|
-
const planDir =
|
|
69697
|
-
const planPath =
|
|
69828
|
+
const planDir = path94.join(cwd, ".zelari", "radio");
|
|
69829
|
+
const planPath = path94.join(planDir, `plan-${planId}.json`);
|
|
69698
69830
|
await fs46.mkdir(planDir, { recursive: true });
|
|
69699
69831
|
await fs46.writeFile(
|
|
69700
69832
|
planPath,
|
|
@@ -70085,7 +70217,7 @@ async function runHeadlessCouncilBody(opts, provider, model, providerStream, ext
|
|
|
70085
70217
|
if (json3) {
|
|
70086
70218
|
if (opts.exportSessionPath === "-") process.stdout.write(json3 + "\n");
|
|
70087
70219
|
else {
|
|
70088
|
-
await fs46.mkdir(
|
|
70220
|
+
await fs46.mkdir(path94.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
70089
70221
|
await fs46.writeFile(opts.exportSessionPath, json3, "utf8");
|
|
70090
70222
|
}
|
|
70091
70223
|
}
|
|
@@ -70508,6 +70640,22 @@ ${ragContext}` : slicePrompt;
|
|
|
70508
70640
|
if (missionGate.blocked) {
|
|
70509
70641
|
exitCode = strictGateExitCode(missionGate);
|
|
70510
70642
|
spine.missionPhase("verification", "mission-strict-blocked");
|
|
70643
|
+
} else if (
|
|
70644
|
+
// M2.1/R4b: an open strict gate is not enough — the success claim must
|
|
70645
|
+
// be event-backed: zero `verification.evidence` events in the spine
|
|
70646
|
+
// means narration-only done → strict exit code. Same overlay seam as
|
|
70647
|
+
// the gate above (H10-fix1) so --allow-unverified /
|
|
70648
|
+
// ZELARI_ALLOW_UNVERIFIED=1 waives mission-side too. `opts.phase` is
|
|
70649
|
+
// the only phase/mode discriminant on this site: `--phase plan`
|
|
70650
|
+
// missions are design-only (no verification expected), so the gate
|
|
70651
|
+
// applies unconditionally to build-phase claims.
|
|
70652
|
+
opts.phase !== "plan" && missionClaimExitCode(await spine.countVerificationEvidence(), strictEnvOverlay(opts)) !== 0
|
|
70653
|
+
) {
|
|
70654
|
+
exitCode = STRICT_DONE_EXIT_CODE;
|
|
70655
|
+
spine.missionPhase("verification", "mission-event-back-missing");
|
|
70656
|
+
process.stderr.write(
|
|
70657
|
+
"[zelari-code --headless] mission success claim has zero verification.evidence events (narration-only done) \u2014 exit 4 (waive with --allow-unverified / ZELARI_ALLOW_UNVERIFIED=1)\n"
|
|
70658
|
+
);
|
|
70511
70659
|
} else {
|
|
70512
70660
|
exitCode = 0;
|
|
70513
70661
|
spine.missionPhase("done", "mission-success");
|
|
@@ -70541,7 +70689,7 @@ ${ragContext}` : slicePrompt;
|
|
|
70541
70689
|
if (json3) {
|
|
70542
70690
|
if (opts.exportSessionPath === "-") process.stdout.write(json3 + "\n");
|
|
70543
70691
|
else {
|
|
70544
|
-
await fs46.mkdir(
|
|
70692
|
+
await fs46.mkdir(path94.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
70545
70693
|
await fs46.writeFile(opts.exportSessionPath, json3, "utf8");
|
|
70546
70694
|
}
|
|
70547
70695
|
}
|
|
@@ -71166,7 +71314,7 @@ function upsertSkill(opts) {
|
|
|
71166
71314
|
}
|
|
71167
71315
|
dir = getProjectSkillsDir(root);
|
|
71168
71316
|
}
|
|
71169
|
-
const
|
|
71317
|
+
const path101 = skillFilePath(dir, name);
|
|
71170
71318
|
const content = serializeSkillMd({
|
|
71171
71319
|
name,
|
|
71172
71320
|
description,
|
|
@@ -71175,13 +71323,13 @@ function upsertSkill(opts) {
|
|
|
71175
71323
|
tools: opts.tools,
|
|
71176
71324
|
cost: opts.cost
|
|
71177
71325
|
});
|
|
71178
|
-
const parsed = parseSkillMd(content,
|
|
71326
|
+
const parsed = parseSkillMd(content, path101);
|
|
71179
71327
|
if (!parsed) {
|
|
71180
71328
|
return { ok: false, error: "Generated SKILL.md failed validation" };
|
|
71181
71329
|
}
|
|
71182
|
-
mkdirSync23(dirname13(
|
|
71183
|
-
writeFileSync25(
|
|
71184
|
-
return { ok: true, path:
|
|
71330
|
+
mkdirSync23(dirname13(path101), { recursive: true });
|
|
71331
|
+
writeFileSync25(path101, content, "utf8");
|
|
71332
|
+
return { ok: true, path: path101 };
|
|
71185
71333
|
}
|
|
71186
71334
|
function removeSkill(opts) {
|
|
71187
71335
|
const name = opts.name.trim().toLowerCase();
|
|
@@ -71199,8 +71347,8 @@ function removeSkill(opts) {
|
|
|
71199
71347
|
dir = getProjectSkillsDir(root);
|
|
71200
71348
|
}
|
|
71201
71349
|
const skillDir = join46(dir, name);
|
|
71202
|
-
const
|
|
71203
|
-
if (!existsSync59(
|
|
71350
|
+
const path101 = skillFilePath(dir, name);
|
|
71351
|
+
if (!existsSync59(path101) && !existsSync59(skillDir)) {
|
|
71204
71352
|
return { ok: false, error: `Skill "${name}" not found in ${dir}` };
|
|
71205
71353
|
}
|
|
71206
71354
|
try {
|
|
@@ -71211,7 +71359,7 @@ function removeSkill(opts) {
|
|
|
71211
71359
|
error: err instanceof Error ? err.message : String(err)
|
|
71212
71360
|
};
|
|
71213
71361
|
}
|
|
71214
|
-
return { ok: true, path:
|
|
71362
|
+
return { ok: true, path: path101 };
|
|
71215
71363
|
}
|
|
71216
71364
|
var NAME_RE, BUILTIN_SKILL_MODULES, builtinsLoaded;
|
|
71217
71365
|
var init_skillConfigIo = __esm({
|
|
@@ -71332,7 +71480,7 @@ var init_jsonApi = __esm({
|
|
|
71332
71480
|
});
|
|
71333
71481
|
|
|
71334
71482
|
// src/cli/memory/mcpAdapter.ts
|
|
71335
|
-
import * as
|
|
71483
|
+
import * as path95 from "node:path";
|
|
71336
71484
|
var id2, projectId, source, SearchSchema, AddSchema, LinkSchema, RetractSchema, MEMORY_MCP_TOOLS, MemoryMcpAdapter;
|
|
71337
71485
|
var init_mcpAdapter = __esm({
|
|
71338
71486
|
"src/cli/memory/mcpAdapter.ts"() {
|
|
@@ -71502,8 +71650,8 @@ var init_mcpAdapter = __esm({
|
|
|
71502
71650
|
this.takeWrite();
|
|
71503
71651
|
const externalFile = args.source?.file;
|
|
71504
71652
|
if (externalFile) {
|
|
71505
|
-
const normalized =
|
|
71506
|
-
if (
|
|
71653
|
+
const normalized = path95.normalize(externalFile);
|
|
71654
|
+
if (path95.isAbsolute(normalized) || normalized === ".." || normalized.startsWith(`..${path95.sep}`)) {
|
|
71507
71655
|
throw new Error("source.file must be project-relative and cannot escape the project");
|
|
71508
71656
|
}
|
|
71509
71657
|
}
|
|
@@ -72030,12 +72178,12 @@ function ensureHome() {
|
|
|
72030
72178
|
}
|
|
72031
72179
|
}
|
|
72032
72180
|
function loadCompanionConfig() {
|
|
72033
|
-
const
|
|
72034
|
-
if (!existsSync60(
|
|
72181
|
+
const path101 = getCompanionConfigPath();
|
|
72182
|
+
if (!existsSync60(path101)) {
|
|
72035
72183
|
return { projects: [] };
|
|
72036
72184
|
}
|
|
72037
72185
|
try {
|
|
72038
|
-
const raw = JSON.parse(readFileSync45(
|
|
72186
|
+
const raw = JSON.parse(readFileSync45(path101, "utf8"));
|
|
72039
72187
|
const projects = Array.isArray(raw.projects) ? raw.projects.filter(
|
|
72040
72188
|
(p3) => p3 && typeof p3.path === "string" && p3.path.trim() && typeof (p3.id ?? p3.name) === "string"
|
|
72041
72189
|
).map((p3) => ({
|
|
@@ -72073,16 +72221,16 @@ function loadOrCreateToken(explicit) {
|
|
|
72073
72221
|
return { token: explicit.trim(), created: false };
|
|
72074
72222
|
}
|
|
72075
72223
|
ensureHome();
|
|
72076
|
-
const
|
|
72077
|
-
if (existsSync60(
|
|
72078
|
-
const t = readFileSync45(
|
|
72224
|
+
const path101 = getCompanionTokenPath();
|
|
72225
|
+
if (existsSync60(path101)) {
|
|
72226
|
+
const t = readFileSync45(path101, "utf8").trim();
|
|
72079
72227
|
if (t) return { token: t, created: false };
|
|
72080
72228
|
}
|
|
72081
72229
|
const token = randomBytes7(24).toString("base64url");
|
|
72082
|
-
writeFileSync26(
|
|
72230
|
+
writeFileSync26(path101, token + "\n", "utf8");
|
|
72083
72231
|
try {
|
|
72084
72232
|
const fs48 = __require("node:fs");
|
|
72085
|
-
fs48.chmodSync?.(
|
|
72233
|
+
fs48.chmodSync?.(path101, 384);
|
|
72086
72234
|
} catch {
|
|
72087
72235
|
}
|
|
72088
72236
|
return { token, created: true };
|
|
@@ -72107,17 +72255,17 @@ function mergeProjects(cfg, extraPaths) {
|
|
|
72107
72255
|
byId.set(p3.id, p3);
|
|
72108
72256
|
}
|
|
72109
72257
|
for (const raw of extraPaths) {
|
|
72110
|
-
const
|
|
72111
|
-
if (!
|
|
72112
|
-
let id3 = slugFromPath(
|
|
72258
|
+
const path101 = raw.trim();
|
|
72259
|
+
if (!path101) continue;
|
|
72260
|
+
let id3 = slugFromPath(path101);
|
|
72113
72261
|
let n = 2;
|
|
72114
|
-
while (byId.has(id3) && byId.get(id3).path !==
|
|
72115
|
-
id3 = `${slugFromPath(
|
|
72262
|
+
while (byId.has(id3) && byId.get(id3).path !== path101) {
|
|
72263
|
+
id3 = `${slugFromPath(path101)}-${n++}`;
|
|
72116
72264
|
}
|
|
72117
72265
|
byId.set(id3, {
|
|
72118
72266
|
id: id3,
|
|
72119
|
-
name: slugFromPath(
|
|
72120
|
-
path:
|
|
72267
|
+
name: slugFromPath(path101),
|
|
72268
|
+
path: path101
|
|
72121
72269
|
});
|
|
72122
72270
|
}
|
|
72123
72271
|
return [...byId.values()];
|
|
@@ -72360,7 +72508,7 @@ var init_askUserBridge = __esm({
|
|
|
72360
72508
|
|
|
72361
72509
|
// src/cli/serve/spineLockSweep.ts
|
|
72362
72510
|
import { promises as fs47 } from "node:fs";
|
|
72363
|
-
import
|
|
72511
|
+
import path96 from "node:path";
|
|
72364
72512
|
async function sweepOrphanSpineLocks(sessionsDir2, options = {}) {
|
|
72365
72513
|
const dir = sessionsDir2 ?? resolveSessionsDir();
|
|
72366
72514
|
const onSwept = options.onSwept ?? ((sessionId2, reason) => {
|
|
@@ -72378,7 +72526,7 @@ async function sweepOrphanSpineLocks(sessionsDir2, options = {}) {
|
|
|
72378
72526
|
return result;
|
|
72379
72527
|
}
|
|
72380
72528
|
for (const sessionId2 of entries) {
|
|
72381
|
-
const lockPath2 =
|
|
72529
|
+
const lockPath2 = path96.join(dir, sessionId2, "writer.lock");
|
|
72382
72530
|
try {
|
|
72383
72531
|
const raw = await fs47.readFile(lockPath2, "utf-8");
|
|
72384
72532
|
let lockInfo = {};
|
|
@@ -73375,9 +73523,9 @@ async function runCompanionServe(opts = {}) {
|
|
|
73375
73523
|
return;
|
|
73376
73524
|
}
|
|
73377
73525
|
const url2 = parseUrl(req);
|
|
73378
|
-
const
|
|
73526
|
+
const path101 = url2.pathname.replace(/\/+$/, "") || "/";
|
|
73379
73527
|
try {
|
|
73380
|
-
if (req.method === "GET" && (
|
|
73528
|
+
if (req.method === "GET" && (path101 === "/health" || path101 === "/v1/health")) {
|
|
73381
73529
|
sendJson2(res, 200, {
|
|
73382
73530
|
ok: true,
|
|
73383
73531
|
service: "zelari-companion",
|
|
@@ -73389,18 +73537,18 @@ async function runCompanionServe(opts = {}) {
|
|
|
73389
73537
|
});
|
|
73390
73538
|
return;
|
|
73391
73539
|
}
|
|
73392
|
-
if (
|
|
73540
|
+
if (path101.startsWith("/v1")) {
|
|
73393
73541
|
if (!tokenMatches(token, getBearer(req))) {
|
|
73394
73542
|
sendJson2(res, 401, { ok: false, error: "unauthorized" });
|
|
73395
73543
|
return;
|
|
73396
73544
|
}
|
|
73397
73545
|
}
|
|
73398
|
-
if (req.method === "GET" &&
|
|
73546
|
+
if (req.method === "GET" && path101 === "/v1/config") {
|
|
73399
73547
|
const snap = buildDesktopConfigSnapshot();
|
|
73400
73548
|
sendJson2(res, 200, { ok: true, ...snap });
|
|
73401
73549
|
return;
|
|
73402
73550
|
}
|
|
73403
|
-
if (req.method === "GET" &&
|
|
73551
|
+
if (req.method === "GET" && path101 === "/v1/projects") {
|
|
73404
73552
|
sendJson2(res, 200, {
|
|
73405
73553
|
ok: true,
|
|
73406
73554
|
projects: projects.map((p3) => ({
|
|
@@ -73411,7 +73559,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
73411
73559
|
});
|
|
73412
73560
|
return;
|
|
73413
73561
|
}
|
|
73414
|
-
if (req.method === "GET" &&
|
|
73562
|
+
if (req.method === "GET" && path101 === "/v1/runs") {
|
|
73415
73563
|
sendJson2(res, 200, {
|
|
73416
73564
|
ok: true,
|
|
73417
73565
|
active: runs.getActive(),
|
|
@@ -73429,7 +73577,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
73429
73577
|
});
|
|
73430
73578
|
return;
|
|
73431
73579
|
}
|
|
73432
|
-
if (req.method === "POST" &&
|
|
73580
|
+
if (req.method === "POST" && path101 === "/v1/runs") {
|
|
73433
73581
|
const raw = await readBody(req);
|
|
73434
73582
|
let body = {};
|
|
73435
73583
|
try {
|
|
@@ -73477,7 +73625,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
73477
73625
|
});
|
|
73478
73626
|
return;
|
|
73479
73627
|
}
|
|
73480
|
-
const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(
|
|
73628
|
+
const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(path101);
|
|
73481
73629
|
if (req.method === "GET" && eventsMatch) {
|
|
73482
73630
|
const runId = eventsMatch[1];
|
|
73483
73631
|
const run = runs.getRun(runId);
|
|
@@ -73542,7 +73690,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
73542
73690
|
}, 500);
|
|
73543
73691
|
return;
|
|
73544
73692
|
}
|
|
73545
|
-
const cancelMatch = /^\/v1\/runs\/([^/]+)\/cancel$/.exec(
|
|
73693
|
+
const cancelMatch = /^\/v1\/runs\/([^/]+)\/cancel$/.exec(path101);
|
|
73546
73694
|
if (req.method === "POST" && cancelMatch) {
|
|
73547
73695
|
const runId = cancelMatch[1];
|
|
73548
73696
|
const result = runs.cancel(runId);
|
|
@@ -73553,7 +73701,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
73553
73701
|
sendJson2(res, 200, { ok: true, cancelled: runId });
|
|
73554
73702
|
return;
|
|
73555
73703
|
}
|
|
73556
|
-
const steerMatch = /^\/v1\/runs\/([^/]+)\/steer$/.exec(
|
|
73704
|
+
const steerMatch = /^\/v1\/runs\/([^/]+)\/steer$/.exec(path101);
|
|
73557
73705
|
if (req.method === "POST" && steerMatch) {
|
|
73558
73706
|
const runId = steerMatch[1];
|
|
73559
73707
|
const raw = await readBody(req);
|
|
@@ -73722,11 +73870,11 @@ import { execSync as execSync2 } from "node:child_process";
|
|
|
73722
73870
|
import { existsSync as existsSync62, readFileSync as readFileSync46, readlinkSync, statSync as statSync10 } from "node:fs";
|
|
73723
73871
|
import { createRequire as createRequire3 } from "node:module";
|
|
73724
73872
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
73725
|
-
import
|
|
73873
|
+
import path97 from "node:path";
|
|
73726
73874
|
function findPackageRoot(start) {
|
|
73727
73875
|
let dir = start;
|
|
73728
73876
|
for (let i = 0; i < 6; i += 1) {
|
|
73729
|
-
const candidate =
|
|
73877
|
+
const candidate = path97.join(dir, "package.json");
|
|
73730
73878
|
if (existsSync62(candidate)) {
|
|
73731
73879
|
try {
|
|
73732
73880
|
const pkg = JSON.parse(readFileSync46(candidate, "utf8"));
|
|
@@ -73734,11 +73882,11 @@ function findPackageRoot(start) {
|
|
|
73734
73882
|
} catch {
|
|
73735
73883
|
}
|
|
73736
73884
|
}
|
|
73737
|
-
const parent =
|
|
73885
|
+
const parent = path97.dirname(dir);
|
|
73738
73886
|
if (parent === dir) break;
|
|
73739
73887
|
dir = parent;
|
|
73740
73888
|
}
|
|
73741
|
-
return
|
|
73889
|
+
return path97.resolve(__dirname3, "..", "..", "..");
|
|
73742
73890
|
}
|
|
73743
73891
|
function tryExec(cmd) {
|
|
73744
73892
|
try {
|
|
@@ -73752,7 +73900,7 @@ function tryExec(cmd) {
|
|
|
73752
73900
|
}
|
|
73753
73901
|
function readPackageJson4() {
|
|
73754
73902
|
try {
|
|
73755
|
-
const pkgPath =
|
|
73903
|
+
const pkgPath = path97.join(packageRoot, "package.json");
|
|
73756
73904
|
return JSON.parse(readFileSync46(pkgPath, "utf8"));
|
|
73757
73905
|
} catch {
|
|
73758
73906
|
return null;
|
|
@@ -73764,7 +73912,7 @@ function getGlobalPrefix() {
|
|
|
73764
73912
|
return (process.env.npm_config_prefix || process.env.NPM_CONFIG_PREFIX || "").trim();
|
|
73765
73913
|
}
|
|
73766
73914
|
function isSourceCheckout() {
|
|
73767
|
-
return existsSync62(
|
|
73915
|
+
return existsSync62(path97.join(packageRoot, "src", "cli", "main.ts")) && existsSync62(path97.join(packageRoot, "apps", "desktop", "package.json"));
|
|
73768
73916
|
}
|
|
73769
73917
|
function checkShim(pkgName) {
|
|
73770
73918
|
const prefix = getGlobalPrefix();
|
|
@@ -73773,9 +73921,9 @@ function checkShim(pkgName) {
|
|
|
73773
73921
|
}
|
|
73774
73922
|
const isWin = process.platform === "win32";
|
|
73775
73923
|
const shimName = isWin ? "zelari-code.cmd" : "zelari-code";
|
|
73776
|
-
const shimPath =
|
|
73924
|
+
const shimPath = path97.join(prefix, shimName);
|
|
73777
73925
|
if (!existsSync62(shimPath)) {
|
|
73778
|
-
const localBin =
|
|
73926
|
+
const localBin = path97.join(packageRoot, "bin", "zelari-code.js");
|
|
73779
73927
|
if (isSourceCheckout() && existsSync62(localBin)) {
|
|
73780
73928
|
return WARN(
|
|
73781
73929
|
`global shim not found at ${shimPath}
|
|
@@ -73809,8 +73957,8 @@ function checkShim(pkgName) {
|
|
|
73809
73957
|
fix: npm install -g ${pkgName}@latest --force`
|
|
73810
73958
|
);
|
|
73811
73959
|
}
|
|
73812
|
-
const resolved =
|
|
73813
|
-
const expected =
|
|
73960
|
+
const resolved = path97.resolve(path97.dirname(shimPath), target);
|
|
73961
|
+
const expected = path97.join(
|
|
73814
73962
|
prefix,
|
|
73815
73963
|
"node_modules",
|
|
73816
73964
|
pkgName,
|
|
@@ -73852,7 +74000,7 @@ function checkNode(pkg) {
|
|
|
73852
74000
|
return OK(`node ${raw} (engines.node ${enginesNode ?? ">= 20.0.0"})`);
|
|
73853
74001
|
}
|
|
73854
74002
|
function checkBundle() {
|
|
73855
|
-
const bundle =
|
|
74003
|
+
const bundle = path97.join(packageRoot, "dist", "cli", "main.bundled.js");
|
|
73856
74004
|
if (!existsSync62(bundle)) {
|
|
73857
74005
|
return FAIL(
|
|
73858
74006
|
`dist/cli/main.bundled.js missing at ${bundle}
|
|
@@ -73873,7 +74021,7 @@ function checkRuntimeDeps() {
|
|
|
73873
74021
|
const missing = [];
|
|
73874
74022
|
for (const dep of required2) {
|
|
73875
74023
|
try {
|
|
73876
|
-
const localReq = createRequire3(
|
|
74024
|
+
const localReq = createRequire3(path97.join(packageRoot, "package.json"));
|
|
73877
74025
|
localReq.resolve(dep);
|
|
73878
74026
|
} catch {
|
|
73879
74027
|
missing.push(dep);
|
|
@@ -74150,7 +74298,7 @@ var init_doctor = __esm({
|
|
|
74150
74298
|
init_metrics3();
|
|
74151
74299
|
init_contextGrowthSummary();
|
|
74152
74300
|
require3 = createRequire3(import.meta.url);
|
|
74153
|
-
__dirname3 =
|
|
74301
|
+
__dirname3 = path97.dirname(fileURLToPath3(import.meta.url));
|
|
74154
74302
|
packageRoot = findPackageRoot(__dirname3);
|
|
74155
74303
|
OK = (message) => ({
|
|
74156
74304
|
ok: true,
|
|
@@ -74259,7 +74407,7 @@ __export(userSettings_exports, {
|
|
|
74259
74407
|
settingsOverrides: () => settingsOverrides
|
|
74260
74408
|
});
|
|
74261
74409
|
import { existsSync as existsSync63, readFileSync as readFileSync47 } from "node:fs";
|
|
74262
|
-
import
|
|
74410
|
+
import path98 from "node:path";
|
|
74263
74411
|
function parseBool(raw) {
|
|
74264
74412
|
const v = raw.trim().toLowerCase();
|
|
74265
74413
|
if (["1", "true", "yes", "on"].includes(v)) return true;
|
|
@@ -74326,8 +74474,8 @@ function envValueFor(key, env) {
|
|
|
74326
74474
|
function resolveUserSettings(opts = {}) {
|
|
74327
74475
|
const cwd = opts.cwd ?? process.cwd();
|
|
74328
74476
|
const env = opts.env ?? process.env;
|
|
74329
|
-
const userPath =
|
|
74330
|
-
const projectPath =
|
|
74477
|
+
const userPath = path98.join(zelariHome(), SETTINGS_FILE_NAME);
|
|
74478
|
+
const projectPath = path98.join(cwd, ".zelari", SETTINGS_FILE_NAME);
|
|
74331
74479
|
const warnings = [];
|
|
74332
74480
|
const userLayer = loadFileLayer(userPath, "user", warnings);
|
|
74333
74481
|
const projectLayer = loadFileLayer(projectPath, "project", warnings);
|
|
@@ -74541,7 +74689,7 @@ __export(inspectSession_exports, {
|
|
|
74541
74689
|
renderInspectReport: () => renderInspectReport,
|
|
74542
74690
|
runInspectSession: () => runInspectSession
|
|
74543
74691
|
});
|
|
74544
|
-
import
|
|
74692
|
+
import path99 from "node:path";
|
|
74545
74693
|
import { existsSync as existsSync64 } from "node:fs";
|
|
74546
74694
|
function formatLimit(limit) {
|
|
74547
74695
|
return `${Math.round(limit / 1e3)}k`;
|
|
@@ -74575,8 +74723,8 @@ function renderInspectReport(state3) {
|
|
|
74575
74723
|
}
|
|
74576
74724
|
async function runInspectSession(opts) {
|
|
74577
74725
|
const sessionsDir2 = resolveSessionsDir({ workspaceRoot: opts.cwd ?? process.cwd() });
|
|
74578
|
-
const sessionDir =
|
|
74579
|
-
const eventsPath =
|
|
74726
|
+
const sessionDir = path99.join(sessionsDir2, opts.sessionId);
|
|
74727
|
+
const eventsPath = path99.join(sessionDir, "events.jsonl");
|
|
74580
74728
|
if (!existsSync64(sessionDir)) {
|
|
74581
74729
|
console.error(`zelari-code inspect: no session directory at ${sessionDir}`);
|
|
74582
74730
|
return 1;
|
|
@@ -74610,14 +74758,14 @@ __export(inspect_exports, {
|
|
|
74610
74758
|
collectInspectReport: () => collectInspectReport,
|
|
74611
74759
|
runInspect: () => runInspect
|
|
74612
74760
|
});
|
|
74613
|
-
import
|
|
74761
|
+
import path100 from "node:path";
|
|
74614
74762
|
import { existsSync as existsSync65, readFileSync as readFileSync48, readdirSync as readdirSync13 } from "node:fs";
|
|
74615
74763
|
async function collectInspectReport(cwd = process.cwd()) {
|
|
74616
74764
|
ensureBuiltinSkillsLoadedSync();
|
|
74617
74765
|
const snap = listSkillsSnapshot(cwd);
|
|
74618
74766
|
const mcp = listMcpServers(cwd);
|
|
74619
|
-
const userMcpPath =
|
|
74620
|
-
const projectMcpPath =
|
|
74767
|
+
const userMcpPath = path100.join(zelariHome(), "mcp.json");
|
|
74768
|
+
const projectMcpPath = path100.join(cwd, ".zelari", "mcp.json");
|
|
74621
74769
|
const globalHooks = globalHooksDir();
|
|
74622
74770
|
const projectHooks = projectHooksDir(cwd);
|
|
74623
74771
|
const projectTrusted = isFolderTrusted(cwd);
|
|
@@ -74645,9 +74793,9 @@ async function collectInspectReport(cwd = process.cwd()) {
|
|
|
74645
74793
|
configSources: [
|
|
74646
74794
|
{ path: userMcpPath, exists: existsSync65(userMcpPath) },
|
|
74647
74795
|
{ path: projectMcpPath, exists: existsSync65(projectMcpPath) },
|
|
74648
|
-
{ path:
|
|
74649
|
-
{ path:
|
|
74650
|
-
{ path:
|
|
74796
|
+
{ path: path100.join(zelariHome(), "provider.json"), exists: existsSync65(path100.join(zelariHome(), "provider.json")) },
|
|
74797
|
+
{ path: path100.join(cwd, ".zelari", "AGENTS.md"), exists: existsSync65(path100.join(cwd, ".zelari", "AGENTS.md")) },
|
|
74798
|
+
{ path: path100.join(cwd, "AGENTS.md"), exists: existsSync65(path100.join(cwd, "AGENTS.md")) }
|
|
74651
74799
|
],
|
|
74652
74800
|
skills: {
|
|
74653
74801
|
total: snap.skills.length,
|
|
@@ -74687,8 +74835,8 @@ function listJsonFiles(dir) {
|
|
|
74687
74835
|
}
|
|
74688
74836
|
function findAgentsMd(cwd) {
|
|
74689
74837
|
const candidates = [
|
|
74690
|
-
|
|
74691
|
-
|
|
74838
|
+
path100.join(cwd, "AGENTS.md"),
|
|
74839
|
+
path100.join(cwd, ".zelari", "AGENTS.md")
|
|
74692
74840
|
];
|
|
74693
74841
|
const found = [];
|
|
74694
74842
|
for (const c of candidates) {
|
|
@@ -78441,7 +78589,10 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il turno continua dopo
|
|
|
78441
78589
|
progressRuntime.observe(event);
|
|
78442
78590
|
if (event.type === "agent_end") {
|
|
78443
78591
|
let krakenSuppressFinish = false;
|
|
78444
|
-
const krakenSpineEmit = (input) =>
|
|
78592
|
+
const krakenSpineEmit = async (input) => {
|
|
78593
|
+
const seq = await (writerRef.current?.spine?.appendEvent(input) ?? Promise.resolve(null));
|
|
78594
|
+
return { seq };
|
|
78595
|
+
};
|
|
78445
78596
|
const writeProofSafe2 = (gate) => writeCompletionProof(gate, { meta: { surface: "kraken", sessionId: sessionId2 } }).then(
|
|
78446
78597
|
() => void 0,
|
|
78447
78598
|
() => void 0
|
|
@@ -78455,7 +78606,9 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il turno continua dopo
|
|
|
78455
78606
|
if (krakenGate.blocked) {
|
|
78456
78607
|
krakenRepairEnqueued = true;
|
|
78457
78608
|
markRepairTriggered();
|
|
78458
|
-
harness2.enqueue(
|
|
78609
|
+
harness2.enqueue(
|
|
78610
|
+
buildKrakenRepairPrompt(krakenGate, repairExcerptsFromEvaluation(strictGate))
|
|
78611
|
+
);
|
|
78459
78612
|
appendSystem(
|
|
78460
78613
|
setMessages,
|
|
78461
78614
|
formatStrictBlockExplanation(strictGate),
|
|
@@ -79949,10 +80102,10 @@ init_ledger();
|
|
|
79949
80102
|
|
|
79950
80103
|
// src/cli/evolution/proposals.ts
|
|
79951
80104
|
import { existsSync as existsSync51, readFileSync as readFileSync39 } from "node:fs";
|
|
79952
|
-
import
|
|
79953
|
-
var PROPOSALS_REL =
|
|
80105
|
+
import path78 from "node:path";
|
|
80106
|
+
var PROPOSALS_REL = path78.join(".zelari", "evolution", "proposals.jsonl");
|
|
79954
80107
|
function proposalsPath(cwd) {
|
|
79955
|
-
return
|
|
80108
|
+
return path78.join(cwd, PROPOSALS_REL);
|
|
79956
80109
|
}
|
|
79957
80110
|
function readProposalStore(cwd) {
|
|
79958
80111
|
const file2 = proposalsPath(cwd);
|
|
@@ -81062,11 +81215,11 @@ function handleCacheStats(ctx) {
|
|
|
81062
81215
|
init_messageHelpers();
|
|
81063
81216
|
init_serviceFactory();
|
|
81064
81217
|
import { promises as fs35 } from "node:fs";
|
|
81065
|
-
import * as
|
|
81218
|
+
import * as path80 from "node:path";
|
|
81066
81219
|
|
|
81067
81220
|
// src/cli/memory/promotion.ts
|
|
81068
81221
|
import { promises as fs34 } from "node:fs";
|
|
81069
|
-
import * as
|
|
81222
|
+
import * as path79 from "node:path";
|
|
81070
81223
|
var START = "<!-- zelari:memory-promotions:start -->";
|
|
81071
81224
|
var END = "<!-- zelari:memory-promotions:end -->";
|
|
81072
81225
|
var DURABLE_KINDS = /* @__PURE__ */ new Set(["fact", "decision", "constraint", "preference", "procedure"]);
|
|
@@ -81077,13 +81230,13 @@ function lineFor(node) {
|
|
|
81077
81230
|
}
|
|
81078
81231
|
async function promoteMemoryToAgentsMd(projectRoot, node) {
|
|
81079
81232
|
if (node.status !== "active") {
|
|
81080
|
-
return { added: false, path:
|
|
81233
|
+
return { added: false, path: path79.join(projectRoot, "AGENTS.md"), reason: `memory is ${node.status}` };
|
|
81081
81234
|
}
|
|
81082
81235
|
if (!DURABLE_KINDS.has(node.kind)) {
|
|
81083
|
-
return { added: false, path:
|
|
81236
|
+
return { added: false, path: path79.join(projectRoot, "AGENTS.md"), reason: `${node.kind} is not a durable instruction kind` };
|
|
81084
81237
|
}
|
|
81085
|
-
const root = await fs34.realpath(projectRoot).catch(() =>
|
|
81086
|
-
const target =
|
|
81238
|
+
const root = await fs34.realpath(projectRoot).catch(() => path79.resolve(projectRoot));
|
|
81239
|
+
const target = path79.join(root, "AGENTS.md");
|
|
81087
81240
|
try {
|
|
81088
81241
|
const stat8 = await fs34.lstat(target);
|
|
81089
81242
|
if (stat8.isSymbolicLink() || !stat8.isFile()) throw new Error("AGENTS.md must be a regular project file.");
|
|
@@ -81148,22 +81301,22 @@ function sourceLine(source2) {
|
|
|
81148
81301
|
return entries.length ? entries.map(([key, value]) => `${key}=${value}`).join(" \xB7 ") : "unknown";
|
|
81149
81302
|
}
|
|
81150
81303
|
function isInside(root, target) {
|
|
81151
|
-
const relative6 =
|
|
81152
|
-
return relative6 === "" || !relative6.startsWith("..") && !
|
|
81304
|
+
const relative6 = path80.relative(root, target);
|
|
81305
|
+
return relative6 === "" || !relative6.startsWith("..") && !path80.isAbsolute(relative6);
|
|
81153
81306
|
}
|
|
81154
81307
|
async function safeExportPath(cwd, requested) {
|
|
81155
|
-
const lexicalRoot =
|
|
81308
|
+
const lexicalRoot = path80.resolve(cwd);
|
|
81156
81309
|
const root = await fs35.realpath(lexicalRoot).catch(() => lexicalRoot);
|
|
81157
|
-
const fallback =
|
|
81158
|
-
const target = requested?.trim() ?
|
|
81310
|
+
const fallback = path80.join(root, ".zelari", "memory", `export-${Date.now()}.json`);
|
|
81311
|
+
const target = requested?.trim() ? path80.resolve(root, requested.trim()) : fallback;
|
|
81159
81312
|
if (!isInside(root, target)) {
|
|
81160
81313
|
throw new Error("Export path must stay inside the active project.");
|
|
81161
81314
|
}
|
|
81162
|
-
const parent =
|
|
81163
|
-
const relativeParent =
|
|
81315
|
+
const parent = path80.dirname(target);
|
|
81316
|
+
const relativeParent = path80.relative(root, parent);
|
|
81164
81317
|
let cursor = root;
|
|
81165
|
-
for (const segment of relativeParent.split(
|
|
81166
|
-
cursor =
|
|
81318
|
+
for (const segment of relativeParent.split(path80.sep).filter(Boolean)) {
|
|
81319
|
+
cursor = path80.join(cursor, segment);
|
|
81167
81320
|
try {
|
|
81168
81321
|
const stat8 = await fs35.lstat(cursor);
|
|
81169
81322
|
if (stat8.isSymbolicLink()) {
|
|
@@ -81335,9 +81488,9 @@ ${message}` : message
|
|
|
81335
81488
|
}
|
|
81336
81489
|
case "export": {
|
|
81337
81490
|
const target = await safeExportPath(ctx.cwd, args.join(" ").trim() || void 0);
|
|
81338
|
-
await fs35.mkdir(
|
|
81339
|
-
const root = await fs35.realpath(ctx.cwd).catch(() =>
|
|
81340
|
-
const realParent = await fs35.realpath(
|
|
81491
|
+
await fs35.mkdir(path80.dirname(target), { recursive: true });
|
|
81492
|
+
const root = await fs35.realpath(ctx.cwd).catch(() => path80.resolve(ctx.cwd));
|
|
81493
|
+
const realParent = await fs35.realpath(path80.dirname(target));
|
|
81341
81494
|
if (!isInside(root, realParent)) {
|
|
81342
81495
|
throw new Error("Export path resolves outside the active project.");
|
|
81343
81496
|
}
|
|
@@ -81552,7 +81705,7 @@ import { promises as fs37 } from "node:fs";
|
|
|
81552
81705
|
init_zod();
|
|
81553
81706
|
init_taskTool();
|
|
81554
81707
|
import { promises as fs36 } from "node:fs";
|
|
81555
|
-
import
|
|
81708
|
+
import path81 from "node:path";
|
|
81556
81709
|
import { randomBytes as randomBytes6 } from "node:crypto";
|
|
81557
81710
|
var CsvFanoutArgsSchema = external_exports.object({
|
|
81558
81711
|
csv_path: external_exports.string().min(1),
|
|
@@ -81646,8 +81799,8 @@ function resolveMaxConcurrency(env = process.env) {
|
|
|
81646
81799
|
}
|
|
81647
81800
|
async function runCsvFanout(args, deps, opts) {
|
|
81648
81801
|
const start = Date.now();
|
|
81649
|
-
const absCsv =
|
|
81650
|
-
const absOut =
|
|
81802
|
+
const absCsv = path81.isAbsolute(args.csv_path) ? args.csv_path : path81.join(opts.parentCwd, args.csv_path);
|
|
81803
|
+
const absOut = path81.isAbsolute(args.output_csv_path) ? args.output_csv_path : path81.join(opts.parentCwd, args.output_csv_path);
|
|
81651
81804
|
const { headers: headers3, rows } = await readCsv(absCsv);
|
|
81652
81805
|
if (headers3.length === 0) {
|
|
81653
81806
|
throw new Error(`kraken_csv_fanout: ${absCsv} is empty`);
|
|
@@ -81703,7 +81856,7 @@ async function runCsvFanout(args, deps, opts) {
|
|
|
81703
81856
|
errored += 1;
|
|
81704
81857
|
errors.push(`${row[args.id_column] ?? i}: ${res.error}`);
|
|
81705
81858
|
}
|
|
81706
|
-
await fs36.mkdir(
|
|
81859
|
+
await fs36.mkdir(path81.dirname(absOut), { recursive: true });
|
|
81707
81860
|
await queueWrite(serializeCsv(outHeaders, outputRecords));
|
|
81708
81861
|
}
|
|
81709
81862
|
}
|
|
@@ -81898,7 +82051,7 @@ function splitArgs(s) {
|
|
|
81898
82051
|
// src/cli/slashHandlers/krakenWorkbench.ts
|
|
81899
82052
|
init_messageHelpers();
|
|
81900
82053
|
import { promises as fs38 } from "node:fs";
|
|
81901
|
-
import
|
|
82054
|
+
import path82 from "node:path";
|
|
81902
82055
|
|
|
81903
82056
|
// src/cli/kraken/workbenchView.ts
|
|
81904
82057
|
var EMPTY = {
|
|
@@ -82015,14 +82168,14 @@ function formatWorkbenchForTerminal(p3) {
|
|
|
82015
82168
|
|
|
82016
82169
|
// src/cli/slashHandlers/krakenWorkbench.ts
|
|
82017
82170
|
async function handleKrakenWorkbench(ctx) {
|
|
82018
|
-
const dir =
|
|
82171
|
+
const dir = path82.join(ctx.cwd, ".zelari", "radio");
|
|
82019
82172
|
let latest = null;
|
|
82020
82173
|
let latestMtime = 0;
|
|
82021
82174
|
try {
|
|
82022
82175
|
const files = await fs38.readdir(dir);
|
|
82023
82176
|
for (const f of files) {
|
|
82024
82177
|
if (!f.startsWith("workbench-") || !f.endsWith(".md")) continue;
|
|
82025
|
-
const full =
|
|
82178
|
+
const full = path82.join(dir, f);
|
|
82026
82179
|
const stat8 = await fs38.stat(full);
|
|
82027
82180
|
if (stat8.mtimeMs > latestMtime) {
|
|
82028
82181
|
latestMtime = stat8.mtimeMs;
|
|
@@ -82039,10 +82192,10 @@ async function handleKrakenWorkbench(ctx) {
|
|
|
82039
82192
|
const parsed = parseWorkbench(content);
|
|
82040
82193
|
const rendered = formatWorkbenchForTerminal(parsed);
|
|
82041
82194
|
if (!rendered.trim()) {
|
|
82042
|
-
appendSystem(ctx.setMessages, `[kraken workbench] ${
|
|
82195
|
+
appendSystem(ctx.setMessages, `[kraken workbench] ${path82.basename(latest)}: (no nodes / no events yet)`);
|
|
82043
82196
|
return;
|
|
82044
82197
|
}
|
|
82045
|
-
appendSystem(ctx.setMessages, `[kraken workbench] ${
|
|
82198
|
+
appendSystem(ctx.setMessages, `[kraken workbench] ${path82.basename(latest)}:
|
|
82046
82199
|
${rendered}`);
|
|
82047
82200
|
}
|
|
82048
82201
|
|
|
@@ -82350,14 +82503,14 @@ ${result.output.split("\n").slice(-8).join("\n")}` : "";
|
|
|
82350
82503
|
init_messageHelpers();
|
|
82351
82504
|
init_paths();
|
|
82352
82505
|
import { promises as fs39 } from "node:fs";
|
|
82353
|
-
import
|
|
82506
|
+
import path85 from "node:path";
|
|
82354
82507
|
async function handlePromoteMember(ctx, memberId) {
|
|
82355
82508
|
try {
|
|
82356
82509
|
const { promoteMember: promoteMember2 } = await Promise.resolve().then(() => (init_council(), council_exports));
|
|
82357
82510
|
const { skill, markdown } = promoteMember2(memberId);
|
|
82358
82511
|
const skillDir = skillsDir();
|
|
82359
82512
|
await fs39.mkdir(skillDir, { recursive: true });
|
|
82360
|
-
const filePath =
|
|
82513
|
+
const filePath = path85.join(skillDir, `${skill.id}.md`);
|
|
82361
82514
|
const previous = await fs39.readFile(filePath, "utf8").catch(() => null);
|
|
82362
82515
|
const { createHash: createHash24 } = await import("node:crypto");
|
|
82363
82516
|
const sha = (s) => createHash24("sha256").update(s, "utf8").digest("hex");
|
|
@@ -82383,7 +82536,7 @@ ${lineage}
|
|
|
82383
82536
|
// src/cli/branchManager.ts
|
|
82384
82537
|
init_paths();
|
|
82385
82538
|
import { promises as fs40, existsSync as existsSync55, readFileSync as readFileSync41, writeFileSync as writeFileSync24, mkdirSync as mkdirSync21, statSync as statSync7, rmSync as rmSync3 } from "node:fs";
|
|
82386
|
-
import
|
|
82539
|
+
import path86 from "node:path";
|
|
82387
82540
|
var META_FILENAME = "meta.json";
|
|
82388
82541
|
var SESSIONS_SUBDIR = "sessions";
|
|
82389
82542
|
function getBranchesBaseDir() {
|
|
@@ -82393,13 +82546,13 @@ function getSessionsBaseDir() {
|
|
|
82393
82546
|
return sessionsDir();
|
|
82394
82547
|
}
|
|
82395
82548
|
function branchPathFor(name, baseDir) {
|
|
82396
|
-
return
|
|
82549
|
+
return path86.join(baseDir, name);
|
|
82397
82550
|
}
|
|
82398
82551
|
function metaPathFor(name, baseDir) {
|
|
82399
|
-
return
|
|
82552
|
+
return path86.join(baseDir, name, META_FILENAME);
|
|
82400
82553
|
}
|
|
82401
82554
|
function sessionsPathFor(name, baseDir) {
|
|
82402
|
-
return
|
|
82555
|
+
return path86.join(baseDir, name, SESSIONS_SUBDIR);
|
|
82403
82556
|
}
|
|
82404
82557
|
function readBranchMeta(name, baseDir) {
|
|
82405
82558
|
const metaPath = metaPathFor(name, baseDir);
|
|
@@ -82424,7 +82577,7 @@ function readBranchMeta(name, baseDir) {
|
|
|
82424
82577
|
}
|
|
82425
82578
|
function writeBranchMeta(name, baseDir, meta3) {
|
|
82426
82579
|
const metaPath = metaPathFor(name, baseDir);
|
|
82427
|
-
mkdirSync21(
|
|
82580
|
+
mkdirSync21(path86.dirname(metaPath), { recursive: true });
|
|
82428
82581
|
writeFileSync24(metaPath, JSON.stringify(meta3, null, 2), "utf-8");
|
|
82429
82582
|
}
|
|
82430
82583
|
async function countSessions(name, baseDir) {
|
|
@@ -82475,14 +82628,14 @@ async function createBranch(name, fromSessionId, baseDir = getBranchesBaseDir(),
|
|
|
82475
82628
|
if (branchExists(name, baseDir)) {
|
|
82476
82629
|
throw new BranchAlreadyExistsError(name);
|
|
82477
82630
|
}
|
|
82478
|
-
const sourcePath =
|
|
82631
|
+
const sourcePath = path86.join(sessionsBaseDir, `${fromSessionId}.jsonl`);
|
|
82479
82632
|
if (!existsSync55(sourcePath)) {
|
|
82480
82633
|
throw new SessionNotFoundError(`Source session "${fromSessionId}" not found at ${sourcePath}`);
|
|
82481
82634
|
}
|
|
82482
82635
|
const branchPath = branchPathFor(name, baseDir);
|
|
82483
82636
|
const branchSessionsPath = sessionsPathFor(name, baseDir);
|
|
82484
82637
|
mkdirSync21(branchSessionsPath, { recursive: true });
|
|
82485
|
-
const destPath =
|
|
82638
|
+
const destPath = path86.join(branchSessionsPath, `${fromSessionId}.jsonl`);
|
|
82486
82639
|
await fs40.copyFile(sourcePath, destPath);
|
|
82487
82640
|
const meta3 = {
|
|
82488
82641
|
name,
|
|
@@ -82586,14 +82739,14 @@ async function handleBranchCheckout(ctx, branchName) {
|
|
|
82586
82739
|
// src/cli/slashHandlers/workspace.ts
|
|
82587
82740
|
init_messageHelpers();
|
|
82588
82741
|
import { promises as fs41 } from "node:fs";
|
|
82589
|
-
import
|
|
82742
|
+
import path87 from "node:path";
|
|
82590
82743
|
async function handleWorkspaceShow(ctx, what) {
|
|
82591
82744
|
try {
|
|
82592
|
-
const zelari =
|
|
82745
|
+
const zelari = path87.join(process.cwd(), ".zelari");
|
|
82593
82746
|
let content;
|
|
82594
82747
|
switch (what) {
|
|
82595
82748
|
case "plan": {
|
|
82596
|
-
const planPath =
|
|
82749
|
+
const planPath = path87.join(zelari, "plan.md");
|
|
82597
82750
|
try {
|
|
82598
82751
|
content = await fs41.readFile(planPath, "utf-8");
|
|
82599
82752
|
} catch {
|
|
@@ -82602,7 +82755,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
82602
82755
|
break;
|
|
82603
82756
|
}
|
|
82604
82757
|
case "decisions": {
|
|
82605
|
-
const decisionsDir =
|
|
82758
|
+
const decisionsDir = path87.join(zelari, "decisions");
|
|
82606
82759
|
try {
|
|
82607
82760
|
const files = (await fs41.readdir(decisionsDir)).filter((f) => f.endsWith(".md")).sort();
|
|
82608
82761
|
if (files.length === 0) {
|
|
@@ -82612,7 +82765,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
82612
82765
|
`];
|
|
82613
82766
|
const { parseFrontmatter: parseFrontmatter2 } = await Promise.resolve().then(() => (init_storage(), storage_exports));
|
|
82614
82767
|
for (const f of files) {
|
|
82615
|
-
const raw = await fs41.readFile(
|
|
82768
|
+
const raw = await fs41.readFile(path87.join(decisionsDir, f), "utf-8");
|
|
82616
82769
|
const { meta: meta3, body } = parseFrontmatter2(raw);
|
|
82617
82770
|
const title = meta3.title ?? body.split("\n")[0]?.replace(/^#\s*/, "").trim() ?? f;
|
|
82618
82771
|
lines.push(`- **${f.replace(/\.md$/, "")}** [${meta3.status ?? "unknown"}] ${title}`);
|
|
@@ -82625,7 +82778,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
82625
82778
|
break;
|
|
82626
82779
|
}
|
|
82627
82780
|
case "risks": {
|
|
82628
|
-
const risksPath =
|
|
82781
|
+
const risksPath = path87.join(zelari, "risks.md");
|
|
82629
82782
|
try {
|
|
82630
82783
|
content = await fs41.readFile(risksPath, "utf-8");
|
|
82631
82784
|
} catch {
|
|
@@ -82634,7 +82787,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
82634
82787
|
break;
|
|
82635
82788
|
}
|
|
82636
82789
|
case "agents": {
|
|
82637
|
-
const agentsPath =
|
|
82790
|
+
const agentsPath = path87.join(process.cwd(), "AGENTS.MD");
|
|
82638
82791
|
try {
|
|
82639
82792
|
content = await fs41.readFile(agentsPath, "utf-8");
|
|
82640
82793
|
} catch {
|
|
@@ -82643,7 +82796,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
82643
82796
|
break;
|
|
82644
82797
|
}
|
|
82645
82798
|
case "docs": {
|
|
82646
|
-
const docsDir =
|
|
82799
|
+
const docsDir = path87.join(zelari, "docs");
|
|
82647
82800
|
try {
|
|
82648
82801
|
const files = (await fs41.readdir(docsDir)).filter((f) => f.endsWith(".md")).sort();
|
|
82649
82802
|
content = files.length ? `# Docs (${files.length})
|
|
@@ -82685,7 +82838,7 @@ async function handleWorkspaceReset(ctx, force) {
|
|
|
82685
82838
|
return;
|
|
82686
82839
|
}
|
|
82687
82840
|
try {
|
|
82688
|
-
const target =
|
|
82841
|
+
const target = path87.join(process.cwd(), ".zelari");
|
|
82689
82842
|
await fs41.rm(target, { recursive: true, force: true });
|
|
82690
82843
|
appendSystem(ctx.setMessages, "[workspace] .zelari/ removed");
|
|
82691
82844
|
} catch (err) {
|
|
@@ -84569,8 +84722,8 @@ function normalizeDraft(raw, sourceUrl, provider, model) {
|
|
|
84569
84722
|
let name = String(o.name ?? "").trim().toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64);
|
|
84570
84723
|
if (!name || !/^[a-z0-9][a-z0-9-]{0,63}$/.test(name)) {
|
|
84571
84724
|
try {
|
|
84572
|
-
const
|
|
84573
|
-
name =
|
|
84725
|
+
const path101 = new URL(sourceUrl).pathname.split("/").filter(Boolean).pop()?.replace(/\.[a-z0-9]+$/i, "").toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48);
|
|
84726
|
+
name = path101 && /^[a-z0-9]/.test(path101) ? path101 : "imported-skill";
|
|
84574
84727
|
} catch {
|
|
84575
84728
|
name = "imported-skill";
|
|
84576
84729
|
}
|
|
@@ -84983,7 +85136,7 @@ proposals: npm run evolve:propose \u2014 decisions in npm run evolve:decide (P1:
|
|
|
84983
85136
|
}
|
|
84984
85137
|
if (argv.includes("--help") || argv.includes("-h")) {
|
|
84985
85138
|
console.log(
|
|
84986
|
-
"zelari-code \u2014 AI Council coding agent CLI.\n\nUsage: zelari-code [options]\n\nOptions:\n --version, -v Print version and exit\n --help, -h Print this help and exit\n --doctor [--json] Diagnose install health (shim, bundle, PATH, deps,\n node/git/bash in the agent shell)\n --inspect [--json] Unified project inspection (config, skills, MCP,\n hooks, plugins, AGENTS.md, trust status)\n --trust [path] Trust the cwd (or path) so project MCP + hooks load\n --fix-path Add the npm global prefix to the user PATH\n (Windows only; fixes 'command not found' after install)\n --fix-budget Set recommended ZELARI_MAX_TOOL_LOOP_HARD=180,\n ZELARI_MAX_TOOL_LOOP_ITERATIONS=60, ZELARI_CONTEXT_LIMIT=400000\n at User scope (prevents the agent stopping mid-task)\n --permission-mcp <socket> MCP stdio server for external agent permission prompts\n (spawned by claude --permission-prompt-tool)\n --memory-mcp Optional MCP stdio server for project memory\n --cwd <path> Trusted project root (requires ZELARI_MEMORY_MCP=1)\n --client-id <id> Stable local owner identity for private memories\n --memory-json <json> Read-only project-memory bridge for Zelari Desktop\n --skip-checks Skip the boot-time prerequisite check\n (alias for ZELARI_SKIP_PREFLIGHT=1)\n --no-wizard Skip the first-run wizard\n --reset-config Re-run the wizard (clears provider.json on commit)\n --headless Run a single task without mounting the TUI\n --task <text> Task prompt (required in headless mode)\n --output json|plain Output format (default: json)\n --mode kraken|council|zelari Dispatch mode (default: kraken; agent=alias)\n zelari/mission mode auto-scopes slices from open tasks in .zelari/plan.json\n --council Alias for --mode council\n --phase plan|build Work phase (default: build)\n --provider <id> Provider override (default: active)\n --model <id> Model override (default: provider default)\n --profile <id> Capability profile (minimal/v1|kraken/v1|council/v1|mission/v1)\n --resume <id> Continue a 2.0 spine session\n --resume-mission Resume .zelari/mission-state.json (not the spine)\n --export-session <path> Write zelari-session-export/1 after the run\n --strict-done Evidence-based BUILD completion gate\n --task-file <path> Read the task prompt from a file (Windows argv cap)\n --once Single-cycle run (cron/git-hook triggers, ADR-0014)\n --kraken-graph <goal> Plan + execute a Kraken task graph\n (variant: --kraken-graph-file <path>; kill-switch\n ZELARI_KRAKEN_GRAPH=0)\n --plan-only Serialize the graph plan to .zelari/radio/ and exit 0\n --run-plan <id> Execute a pre-built .zelari/radio/plan-<id>.json\n --gauntlet Host-driven gauntlet loop (builder/critic tentacles)\n --session-export <id> Print a portable 2.0 session export (no LLM)\n serve Companion host for Android/remote clients (Tailscale)\n --bind <ip> Listen address (default: 127.0.0.1; use Tailscale IP)\n --port <n> Port (default: 7421)\n --token <secret> Bearer token (default: ~/.zelari-code/companion.token)\n --project <path> Allowlisted project root (repeatable)\n --save-projects Persist --project list to companion.json\n --serve-harness Long-lived harness kernel for hosts (NDJSON JSON-RPC\n on stdin/stdout; Desktop/companion transport)\n --print-config Print provider/model config as JSON (no secrets)\n --print-settings Print zelari.config.json values + the origin of\n each (default < user < project < env)\n --permissions <p> Permission preset: strict | standard | yolo \u2014 changes\n category DEFAULTS only (env vars and policy files win)\n --evolve-status Evolution ledger stats (read-only; ADR-0036; the\n ledger is written only when ZELARI_EVOLUTION=shadow)\n --plugins-status JSON status of optional plugins (Playwright, eslint, \u2026)\n --plugins-install <id> Install plugin (playwright also fetches Chromium)\n --cwd <path> Workspace for -D installs (default: process.cwd())\n --set-config Persist provider/model/endpoint\n --provider <id> Set active provider\n --model <id> Set model for that provider\n --endpoint <url> Custom OpenAI-compatible base URL\n --endpoint-clear Remove custom endpoint override\n --thinking <spec> Thinking effort (auto|off|low|medium|high|budget:N)\n --set-key Store an API key (never printed back)\n --provider <id> Provider id (required)\n --key <secret> API key (required)\n --login-oauth Start subscription OAuth (grok, chatgpt, anthropic)\n --provider <id> grok | chatgpt | anthropic\n --code <paste> Anthropic magic-link code (CODE#STATE)\n --no-browser Do not open the system browser\n --refresh-oauth Force-refresh an OAuth access token\n --provider <id> grok | chatgpt | anthropic\n --logout-oauth Clear stored OAuth credentials\n --provider <id> grok | chatgpt | anthropic\n --discover-models Refresh model list for a provider\n --provider <id> Provider (default: active)\n --print-mcp Print MCP server config (user + project)\n --cwd <path> Project root for .zelari/mcp.json\n --set-mcp Add/update an MCP server entry\n --name <id> Server name (required)\n --command <bin> Executable for stdio servers\n --url <endpoint> Streamable HTTP endpoint (e.g. UE 5.8 editor)\n --args <json> JSON array of args (stdio, optional)\n --timeout <ms> Per-server request timeout (http, optional)\n --scope user|project Default: user\n --enabled true|false Default: true\n --cwd <path> Required when scope=project\n --set-mcp-preset Install a named MCP preset (e.g. cua)\n --preset cua Cua Driver desktop computer-use (MCP)\n --preset unreal-mcp Unreal Engine 5.8+ editor (MCP over HTTP)\n --scope user|project Default: user\n --cwd <path> Required when scope=project\n --remove-mcp Remove an MCP server entry\n --name <id> --scope user|project [--cwd <path>]\n --print-skills Print skills (builtin + user + project)\n --cwd <path> Project root for .zelari/skills\n --set-skill Add/update a SKILL.md skill\n --name <id> Skill id (required)\n --description <t> One-line description (required)\n --body <text> Markdown instructions (required)\n --category <c> plan|refactor|debug|review|test|docs|ops|git|db|maint\n --tools <csv> Comma-separated required tools (optional)\n --cost <l> low|medium|high (default: medium)\n --scope user|project Default: user\n --cwd <path> Required when scope=project\n --remove-skill Remove a user/project SKILL.md\n --name <id> --scope user|project [--cwd <path>]\n --generate-skill-from-url Fetch URL + draft skill via model (JSON)\n --url <https://...> Required\n --provider <id> Override active provider\n --model <name> Override model for the selected provider\n --print-ssh-targets Print SSH deploy/monitor targets\n --set-ssh-target Upsert target (--json '{...}' or flags)\n --remove-ssh-target --id <id>\n --test-ssh-target --id <id> (BatchMode ssh true)\n --print-ssh-pubkey --path <private-or-.pub> (display public key)\n\nEnvironment:\n ZELARI_NO_WIZARD=1 Skip the first-run wizard\n ZELARI_SKIP_PREFLIGHT=1 Skip the boot prerequisite check\n ZELARI_NO_PLUGIN_PROMPT=1 Skip the boot plugin-install prompt\n ZELARI_MEMORY_MCP=1 Enable the optional external memory MCP server\n ANATHEMA_DEV=1 Disable background update check + preflight\n"
|
|
85139
|
+
"zelari-code \u2014 AI Council coding agent CLI.\n\nUsage: zelari-code [options]\n\nOptions:\n --version, -v Print version and exit\n --help, -h Print this help and exit\n --doctor [--json] Diagnose install health (shim, bundle, PATH, deps,\n node/git/bash in the agent shell)\n --inspect [--json] Unified project inspection (config, skills, MCP,\n hooks, plugins, AGENTS.md, trust status)\n --trust [path] Trust the cwd (or path) so project MCP + hooks load\n --fix-path Add the npm global prefix to the user PATH\n (Windows only; fixes 'command not found' after install)\n --fix-budget Set recommended ZELARI_MAX_TOOL_LOOP_HARD=180,\n ZELARI_MAX_TOOL_LOOP_ITERATIONS=60, ZELARI_CONTEXT_LIMIT=400000\n at User scope (prevents the agent stopping mid-task)\n --permission-mcp <socket> MCP stdio server for external agent permission prompts\n (spawned by claude --permission-prompt-tool)\n --memory-mcp Optional MCP stdio server for project memory\n --cwd <path> Trusted project root (requires ZELARI_MEMORY_MCP=1)\n --client-id <id> Stable local owner identity for private memories\n --memory-json <json> Read-only project-memory bridge for Zelari Desktop\n --skip-checks Skip the boot-time prerequisite check\n (alias for ZELARI_SKIP_PREFLIGHT=1)\n --no-wizard Skip the first-run wizard\n --reset-config Re-run the wizard (clears provider.json on commit)\n --headless Run a single task without mounting the TUI\n --task <text> Task prompt (required in headless mode)\n --output json|plain Output format (default: json)\n --mode kraken|council|zelari Dispatch mode (default: kraken; agent=alias)\n zelari/mission mode auto-scopes slices from open tasks in .zelari/plan.json\n --council Alias for --mode council\n --phase plan|build Work phase (default: build)\n --provider <id> Provider override (default: active)\n --model <id> Model override (default: provider default)\n --profile <id> Capability profile (minimal/v1|kraken/v1|council/v1|mission/v1)\n --resume <id> Continue a 2.0 spine session\n --resume-mission Resume .zelari/mission-state.json (not the spine)\n --export-session <path> Write zelari-session-export/1 after the run\n --strict-done Evidence-based BUILD completion gate\n --allow-unverified Exit 0 when strict is ON but nothing could be verified (M1.2)\n --task-file <path> Read the task prompt from a file (Windows argv cap)\n --once Single-cycle run (cron/git-hook triggers, ADR-0014)\n --kraken-graph <goal> Plan + execute a Kraken task graph\n (variant: --kraken-graph-file <path>; kill-switch\n ZELARI_KRAKEN_GRAPH=0)\n --plan-only Serialize the graph plan to .zelari/radio/ and exit 0\n --run-plan <id> Execute a pre-built .zelari/radio/plan-<id>.json\n --gauntlet Host-driven gauntlet loop (builder/critic tentacles)\n --session-export <id> Print a portable 2.0 session export (no LLM)\n serve Companion host for Android/remote clients (Tailscale)\n --bind <ip> Listen address (default: 127.0.0.1; use Tailscale IP)\n --port <n> Port (default: 7421)\n --token <secret> Bearer token (default: ~/.zelari-code/companion.token)\n --project <path> Allowlisted project root (repeatable)\n --save-projects Persist --project list to companion.json\n --serve-harness Long-lived harness kernel for hosts (NDJSON JSON-RPC\n on stdin/stdout; Desktop/companion transport)\n --print-config Print provider/model config as JSON (no secrets)\n --print-settings Print zelari.config.json values + the origin of\n each (default < user < project < env)\n --permissions <p> Permission preset: strict | standard | yolo \u2014 changes\n category DEFAULTS only (env vars and policy files win)\n --evolve-status Evolution ledger stats (read-only; ADR-0036; the\n ledger is written only when ZELARI_EVOLUTION=shadow)\n --plugins-status JSON status of optional plugins (Playwright, eslint, \u2026)\n --plugins-install <id> Install plugin (playwright also fetches Chromium)\n --cwd <path> Workspace for -D installs (default: process.cwd())\n --set-config Persist provider/model/endpoint\n --provider <id> Set active provider\n --model <id> Set model for that provider\n --endpoint <url> Custom OpenAI-compatible base URL\n --endpoint-clear Remove custom endpoint override\n --thinking <spec> Thinking effort (auto|off|low|medium|high|budget:N)\n --set-key Store an API key (never printed back)\n --provider <id> Provider id (required)\n --key <secret> API key (required)\n --login-oauth Start subscription OAuth (grok, chatgpt, anthropic)\n --provider <id> grok | chatgpt | anthropic\n --code <paste> Anthropic magic-link code (CODE#STATE)\n --no-browser Do not open the system browser\n --refresh-oauth Force-refresh an OAuth access token\n --provider <id> grok | chatgpt | anthropic\n --logout-oauth Clear stored OAuth credentials\n --provider <id> grok | chatgpt | anthropic\n --discover-models Refresh model list for a provider\n --provider <id> Provider (default: active)\n --print-mcp Print MCP server config (user + project)\n --cwd <path> Project root for .zelari/mcp.json\n --set-mcp Add/update an MCP server entry\n --name <id> Server name (required)\n --command <bin> Executable for stdio servers\n --url <endpoint> Streamable HTTP endpoint (e.g. UE 5.8 editor)\n --args <json> JSON array of args (stdio, optional)\n --timeout <ms> Per-server request timeout (http, optional)\n --scope user|project Default: user\n --enabled true|false Default: true\n --cwd <path> Required when scope=project\n --set-mcp-preset Install a named MCP preset (e.g. cua)\n --preset cua Cua Driver desktop computer-use (MCP)\n --preset unreal-mcp Unreal Engine 5.8+ editor (MCP over HTTP)\n --scope user|project Default: user\n --cwd <path> Required when scope=project\n --remove-mcp Remove an MCP server entry\n --name <id> --scope user|project [--cwd <path>]\n --print-skills Print skills (builtin + user + project)\n --cwd <path> Project root for .zelari/skills\n --set-skill Add/update a SKILL.md skill\n --name <id> Skill id (required)\n --description <t> One-line description (required)\n --body <text> Markdown instructions (required)\n --category <c> plan|refactor|debug|review|test|docs|ops|git|db|maint\n --tools <csv> Comma-separated required tools (optional)\n --cost <l> low|medium|high (default: medium)\n --scope user|project Default: user\n --cwd <path> Required when scope=project\n --remove-skill Remove a user/project SKILL.md\n --name <id> --scope user|project [--cwd <path>]\n --generate-skill-from-url Fetch URL + draft skill via model (JSON)\n --url <https://...> Required\n --provider <id> Override active provider\n --model <name> Override model for the selected provider\n --print-ssh-targets Print SSH deploy/monitor targets\n --set-ssh-target Upsert target (--json '{...}' or flags)\n --remove-ssh-target --id <id>\n --test-ssh-target --id <id> (BatchMode ssh true)\n --print-ssh-pubkey --path <private-or-.pub> (display public key)\n\nEnvironment:\n ZELARI_NO_WIZARD=1 Skip the first-run wizard\n ZELARI_SKIP_PREFLIGHT=1 Skip the boot prerequisite check\n ZELARI_NO_PLUGIN_PROMPT=1 Skip the boot plugin-install prompt\n ZELARI_MEMORY_MCP=1 Enable the optional external memory MCP server\n ANATHEMA_DEV=1 Disable background update check + preflight\n"
|
|
84987
85140
|
);
|
|
84988
85141
|
process.exit(0);
|
|
84989
85142
|
}
|