zelari-code 2.0.0-alpha.6 → 2.0.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.js +9 -0
- package/dist/cli/headless.js.map +1 -1
- package/dist/cli/headlessE2eSession.test.js +189 -0
- package/dist/cli/headlessE2eSession.test.js.map +1 -0
- package/dist/cli/headlessSpine.js +6 -0
- package/dist/cli/headlessSpine.js.map +1 -1
- package/dist/cli/hooks/chatState.js.map +1 -1
- package/dist/cli/hooks/eventsToMessages.js.map +1 -1
- package/dist/cli/hooks/useChatTurn.js +5 -3
- package/dist/cli/hooks/useChatTurn.js.map +1 -1
- package/dist/cli/hooks/useSession.js +0 -2
- package/dist/cli/hooks/useSession.js.map +1 -1
- package/dist/cli/kraken/evidenceAnchoring.test.js +92 -0
- package/dist/cli/kraken/evidenceAnchoring.test.js.map +1 -0
- package/dist/cli/kraken/nativeVerification.js +113 -0
- package/dist/cli/kraken/nativeVerification.js.map +1 -0
- package/dist/cli/kraken/nativeVerification.test.js +207 -0
- package/dist/cli/kraken/nativeVerification.test.js.map +1 -0
- package/dist/cli/kraken/strictDefaults.test.js +149 -0
- package/dist/cli/kraken/strictDefaults.test.js.map +1 -0
- package/dist/cli/kraken/verificationBridge.js +86 -8
- package/dist/cli/kraken/verificationBridge.js.map +1 -1
- package/dist/cli/kraken/verificationBridge.session.test.js +2 -2
- package/dist/cli/kraken/verificationBridge.session.test.js.map +1 -1
- package/dist/cli/kraken/verificationBridge.test.js +38 -22
- package/dist/cli/kraken/verificationBridge.test.js.map +1 -1
- package/dist/cli/kraken/verifierAdvisoryLock.test.js +154 -0
- package/dist/cli/kraken/verifierAdvisoryLock.test.js.map +1 -0
- package/dist/cli/kraken/verifierResolution.js +28 -0
- package/dist/cli/kraken/verifierResolution.js.map +1 -0
- package/dist/cli/kraken/verifierRoundTrip.test.js +166 -0
- package/dist/cli/kraken/verifierRoundTrip.test.js.map +1 -0
- package/dist/cli/legacyContextIsolation.test.js +3 -2
- package/dist/cli/legacyContextIsolation.test.js.map +1 -1
- package/dist/cli/main.bundled.js +707 -314
- package/dist/cli/main.bundled.js.map +4 -4
- package/dist/cli/missionContinuation.test.js +117 -0
- package/dist/cli/missionContinuation.test.js.map +1 -0
- package/dist/cli/profileMatrix.test.js +130 -0
- package/dist/cli/profileMatrix.test.js.map +1 -0
- package/dist/cli/runHeadless.js +39 -4
- package/dist/cli/runHeadless.js.map +1 -1
- package/dist/cli/sessionSpine.js +29 -3
- package/dist/cli/sessionSpine.js.map +1 -1
- package/dist/cli/zelariMission.js +16 -0
- package/dist/cli/zelariMission.js.map +1 -1
- package/package.json +2 -2
package/dist/cli/main.bundled.js
CHANGED
|
@@ -3288,10 +3288,10 @@ function mergeDefs(...defs) {
|
|
|
3288
3288
|
function cloneDef(schema) {
|
|
3289
3289
|
return mergeDefs(schema._zod.def);
|
|
3290
3290
|
}
|
|
3291
|
-
function getElementAtPath(obj,
|
|
3292
|
-
if (!
|
|
3291
|
+
function getElementAtPath(obj, path64) {
|
|
3292
|
+
if (!path64)
|
|
3293
3293
|
return obj;
|
|
3294
|
-
return
|
|
3294
|
+
return path64.reduce((acc, key) => acc?.[key], obj);
|
|
3295
3295
|
}
|
|
3296
3296
|
function promiseAllObject(promisesObj) {
|
|
3297
3297
|
const keys = Object.keys(promisesObj);
|
|
@@ -3619,11 +3619,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
3619
3619
|
}
|
|
3620
3620
|
return false;
|
|
3621
3621
|
}
|
|
3622
|
-
function prefixIssues(
|
|
3622
|
+
function prefixIssues(path64, issues) {
|
|
3623
3623
|
return issues.map((iss) => {
|
|
3624
3624
|
var _a3;
|
|
3625
3625
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
3626
|
-
iss.path.unshift(
|
|
3626
|
+
iss.path.unshift(path64);
|
|
3627
3627
|
return iss;
|
|
3628
3628
|
});
|
|
3629
3629
|
}
|
|
@@ -3841,16 +3841,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
3841
3841
|
}
|
|
3842
3842
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
3843
3843
|
const fieldErrors = { _errors: [] };
|
|
3844
|
-
const processError = (error52,
|
|
3844
|
+
const processError = (error52, path64 = []) => {
|
|
3845
3845
|
for (const issue2 of error52.issues) {
|
|
3846
3846
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
3847
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
3847
|
+
issue2.errors.map((issues) => processError({ issues }, [...path64, ...issue2.path]));
|
|
3848
3848
|
} else if (issue2.code === "invalid_key") {
|
|
3849
|
-
processError({ issues: issue2.issues }, [...
|
|
3849
|
+
processError({ issues: issue2.issues }, [...path64, ...issue2.path]);
|
|
3850
3850
|
} else if (issue2.code === "invalid_element") {
|
|
3851
|
-
processError({ issues: issue2.issues }, [...
|
|
3851
|
+
processError({ issues: issue2.issues }, [...path64, ...issue2.path]);
|
|
3852
3852
|
} else {
|
|
3853
|
-
const fullpath = [...
|
|
3853
|
+
const fullpath = [...path64, ...issue2.path];
|
|
3854
3854
|
if (fullpath.length === 0) {
|
|
3855
3855
|
fieldErrors._errors.push(mapper(issue2));
|
|
3856
3856
|
} else {
|
|
@@ -3877,17 +3877,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
3877
3877
|
}
|
|
3878
3878
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
3879
3879
|
const result = { errors: [] };
|
|
3880
|
-
const processError = (error52,
|
|
3880
|
+
const processError = (error52, path64 = []) => {
|
|
3881
3881
|
var _a3, _b;
|
|
3882
3882
|
for (const issue2 of error52.issues) {
|
|
3883
3883
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
3884
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
3884
|
+
issue2.errors.map((issues) => processError({ issues }, [...path64, ...issue2.path]));
|
|
3885
3885
|
} else if (issue2.code === "invalid_key") {
|
|
3886
|
-
processError({ issues: issue2.issues }, [...
|
|
3886
|
+
processError({ issues: issue2.issues }, [...path64, ...issue2.path]);
|
|
3887
3887
|
} else if (issue2.code === "invalid_element") {
|
|
3888
|
-
processError({ issues: issue2.issues }, [...
|
|
3888
|
+
processError({ issues: issue2.issues }, [...path64, ...issue2.path]);
|
|
3889
3889
|
} else {
|
|
3890
|
-
const fullpath = [...
|
|
3890
|
+
const fullpath = [...path64, ...issue2.path];
|
|
3891
3891
|
if (fullpath.length === 0) {
|
|
3892
3892
|
result.errors.push(mapper(issue2));
|
|
3893
3893
|
continue;
|
|
@@ -3919,8 +3919,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
3919
3919
|
}
|
|
3920
3920
|
function toDotPath(_path) {
|
|
3921
3921
|
const segs = [];
|
|
3922
|
-
const
|
|
3923
|
-
for (const seg of
|
|
3922
|
+
const path64 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
3923
|
+
for (const seg of path64) {
|
|
3924
3924
|
if (typeof seg === "number")
|
|
3925
3925
|
segs.push(`[${seg}]`);
|
|
3926
3926
|
else if (typeof seg === "symbol")
|
|
@@ -17423,13 +17423,13 @@ function resolveRef(ref, ctx) {
|
|
|
17423
17423
|
if (!ref.startsWith("#")) {
|
|
17424
17424
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
17425
17425
|
}
|
|
17426
|
-
const
|
|
17427
|
-
if (
|
|
17426
|
+
const path64 = ref.slice(1).split("/").filter(Boolean);
|
|
17427
|
+
if (path64.length === 0) {
|
|
17428
17428
|
return ctx.rootSchema;
|
|
17429
17429
|
}
|
|
17430
17430
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
17431
|
-
if (
|
|
17432
|
-
const key =
|
|
17431
|
+
if (path64[0] === defsKey) {
|
|
17432
|
+
const key = path64[1];
|
|
17433
17433
|
if (!key || !ctx.defs[key]) {
|
|
17434
17434
|
throw new Error(`Reference not found: ${ref}`);
|
|
17435
17435
|
}
|
|
@@ -19750,11 +19750,11 @@ var init_tools = __esm({
|
|
|
19750
19750
|
if (!ctx.addDocument)
|
|
19751
19751
|
return "Knowledge vault tool not available.";
|
|
19752
19752
|
const title = args["title"] || "New Document";
|
|
19753
|
-
const
|
|
19753
|
+
const path64 = args["path"] || `notes/${title.toLowerCase().replace(/[^a-z0-9]+/g, "-")}`;
|
|
19754
19754
|
const content = args["content"] || "";
|
|
19755
19755
|
const tags = args["tags"] || [];
|
|
19756
19756
|
ctx.addDocument({
|
|
19757
|
-
path:
|
|
19757
|
+
path: path64,
|
|
19758
19758
|
title,
|
|
19759
19759
|
content,
|
|
19760
19760
|
format: "markdown",
|
|
@@ -19763,7 +19763,7 @@ var init_tools = __esm({
|
|
|
19763
19763
|
workspaceId: ctx.workspaceId
|
|
19764
19764
|
});
|
|
19765
19765
|
ctx.addActivity("vault", "created document", title);
|
|
19766
|
-
return `Document "${title}" created at "${
|
|
19766
|
+
return `Document "${title}" created at "${path64}".`;
|
|
19767
19767
|
}
|
|
19768
19768
|
}
|
|
19769
19769
|
];
|
|
@@ -24197,11 +24197,11 @@ var init_synthesisAudit = __esm({
|
|
|
24197
24197
|
import { existsSync as existsSync7, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "node:fs";
|
|
24198
24198
|
import { join as join2 } from "node:path";
|
|
24199
24199
|
function loadNfrSpec(zelariRoot) {
|
|
24200
|
-
const
|
|
24201
|
-
if (!existsSync7(
|
|
24200
|
+
const path64 = join2(zelariRoot, "nfr-spec.json");
|
|
24201
|
+
if (!existsSync7(path64))
|
|
24202
24202
|
return null;
|
|
24203
24203
|
try {
|
|
24204
|
-
const raw = JSON.parse(readFileSync7(
|
|
24204
|
+
const raw = JSON.parse(readFileSync7(path64, "utf8"));
|
|
24205
24205
|
if (raw.version !== 1 || !Array.isArray(raw.targets))
|
|
24206
24206
|
return null;
|
|
24207
24207
|
return raw;
|
|
@@ -26507,9 +26507,9 @@ var init_types4 = __esm({
|
|
|
26507
26507
|
import { readFileSync as readFileSync12 } from "node:fs";
|
|
26508
26508
|
import { join as join8 } from "node:path";
|
|
26509
26509
|
function readLessonsDeduped(zelariRoot) {
|
|
26510
|
-
const
|
|
26510
|
+
const path64 = join8(zelariRoot, LESSONS_FILE);
|
|
26511
26511
|
try {
|
|
26512
|
-
const raw = readFileSync12(
|
|
26512
|
+
const raw = readFileSync12(path64, "utf8");
|
|
26513
26513
|
const byId = /* @__PURE__ */ new Map();
|
|
26514
26514
|
for (const line of raw.split(/\r?\n/)) {
|
|
26515
26515
|
if (!line.trim())
|
|
@@ -26610,8 +26610,8 @@ function keywordsFrom(check2, signature) {
|
|
|
26610
26610
|
return [.../* @__PURE__ */ new Set([...fromId, ...words])].slice(0, 12);
|
|
26611
26611
|
}
|
|
26612
26612
|
function writeLesson(zelariRoot, lesson) {
|
|
26613
|
-
const
|
|
26614
|
-
appendFileSync(
|
|
26613
|
+
const path64 = join9(zelariRoot, LESSONS_FILE);
|
|
26614
|
+
appendFileSync(path64, `${JSON.stringify(lesson)}
|
|
26615
26615
|
`, "utf8");
|
|
26616
26616
|
}
|
|
26617
26617
|
function findSimilar(lessons, signature) {
|
|
@@ -27225,9 +27225,9 @@ function findCycle(nodes) {
|
|
|
27225
27225
|
if (color.get(start) !== WHITE)
|
|
27226
27226
|
continue;
|
|
27227
27227
|
const stack = [[start, 0]];
|
|
27228
|
-
const
|
|
27228
|
+
const path64 = [];
|
|
27229
27229
|
color.set(start, GRAY);
|
|
27230
|
-
|
|
27230
|
+
path64.push(start);
|
|
27231
27231
|
while (stack.length > 0) {
|
|
27232
27232
|
const top = stack[stack.length - 1];
|
|
27233
27233
|
const [id, idx] = top;
|
|
@@ -27240,17 +27240,17 @@ function findCycle(nodes) {
|
|
|
27240
27240
|
continue;
|
|
27241
27241
|
const c = color.get(dep);
|
|
27242
27242
|
if (c === GRAY) {
|
|
27243
|
-
const at =
|
|
27244
|
-
return [...
|
|
27243
|
+
const at = path64.indexOf(dep);
|
|
27244
|
+
return [...path64.slice(at), dep];
|
|
27245
27245
|
}
|
|
27246
27246
|
if (c === WHITE) {
|
|
27247
27247
|
color.set(dep, GRAY);
|
|
27248
|
-
|
|
27248
|
+
path64.push(dep);
|
|
27249
27249
|
stack.push([dep, 0]);
|
|
27250
27250
|
}
|
|
27251
27251
|
} else {
|
|
27252
27252
|
color.set(id, BLACK);
|
|
27253
|
-
|
|
27253
|
+
path64.pop();
|
|
27254
27254
|
stack.pop();
|
|
27255
27255
|
}
|
|
27256
27256
|
}
|
|
@@ -28170,8 +28170,8 @@ var init_runner = __esm({
|
|
|
28170
28170
|
failed: [...this.tentaclesById.values()].filter((r) => r.status === "error"),
|
|
28171
28171
|
pending: []
|
|
28172
28172
|
};
|
|
28173
|
-
const
|
|
28174
|
-
this.host.log(`checkpoint: ${label ?? "auto"} \u2192 ${
|
|
28173
|
+
const path64 = await this.host.saveSnapshot(snapshot, ".zelari/kraken/snapshots");
|
|
28174
|
+
this.host.log(`checkpoint: ${label ?? "auto"} \u2192 ${path64}`);
|
|
28175
28175
|
return snapshot;
|
|
28176
28176
|
}
|
|
28177
28177
|
callLog(msg, data) {
|
|
@@ -28271,7 +28271,14 @@ var init_types8 = __esm({
|
|
|
28271
28271
|
"council.member",
|
|
28272
28272
|
"mission.phase",
|
|
28273
28273
|
"mission.replan",
|
|
28274
|
+
// F4 (doc §6 advisory continuation): driver → host advice record. State-only
|
|
28275
|
+
// (never model-surface): the recommendation must not feed the model loop.
|
|
28276
|
+
"mission.progress",
|
|
28274
28277
|
"verification.run",
|
|
28278
|
+
// F3 (ADR-0023 §5 evidence traceability): per-observation state event —
|
|
28279
|
+
// the session-log anchor EvidenceRef.seq points at (command output, fs
|
|
28280
|
+
// observation, digest). Not model-surface. Schema review per ADR-0021.
|
|
28281
|
+
"verification.evidence",
|
|
28275
28282
|
"note"
|
|
28276
28283
|
];
|
|
28277
28284
|
SessionEventEnvelopeSchema = external_exports.object({
|
|
@@ -28590,6 +28597,7 @@ function buildProjection(events, issues = []) {
|
|
|
28590
28597
|
toolResults: 0,
|
|
28591
28598
|
verifications: [],
|
|
28592
28599
|
missionPhases: [],
|
|
28600
|
+
missionAdvice: [],
|
|
28593
28601
|
replans: 0,
|
|
28594
28602
|
issues
|
|
28595
28603
|
};
|
|
@@ -28625,6 +28633,14 @@ function buildProjection(events, issues = []) {
|
|
|
28625
28633
|
case "mission.replan":
|
|
28626
28634
|
projection.replans += 1;
|
|
28627
28635
|
break;
|
|
28636
|
+
case "mission.progress":
|
|
28637
|
+
projection.missionAdvice.push({
|
|
28638
|
+
seq: e.seq,
|
|
28639
|
+
recommendation: String(e.data.recommendation ?? ""),
|
|
28640
|
+
rationale: String(e.data.rationale ?? "")
|
|
28641
|
+
});
|
|
28642
|
+
break;
|
|
28643
|
+
break;
|
|
28628
28644
|
}
|
|
28629
28645
|
}
|
|
28630
28646
|
return projection;
|
|
@@ -29365,7 +29381,12 @@ var init_runtime2 = __esm({
|
|
|
29365
29381
|
});
|
|
29366
29382
|
|
|
29367
29383
|
// packages/core/dist/verification/types.js
|
|
29368
|
-
|
|
29384
|
+
function isEventBackedEvidence(ref) {
|
|
29385
|
+
if (!EVENT_BACKED_EVIDENCE_TIERS.includes(ref.tier))
|
|
29386
|
+
return true;
|
|
29387
|
+
return typeof ref.seq === "number" && ref.seq > 0;
|
|
29388
|
+
}
|
|
29389
|
+
var CriterionSourceSchema, CommandCheckSchema, FileExistsCheckSchema, FileContainsCheckSchema, FileAbsentCheckSchema, NoneCheckSchema, DeterministicCheckSchema, CriterionSchema, EvidenceTierSchema, EvidenceRefSchema, EVENT_BACKED_EVIDENCE_TIERS, VerificationStatusSchema, VerificationSourceSchema, VerificationResultSchema;
|
|
29369
29390
|
var init_types9 = __esm({
|
|
29370
29391
|
"packages/core/dist/verification/types.js"() {
|
|
29371
29392
|
"use strict";
|
|
@@ -29428,7 +29449,11 @@ var init_types9 = __esm({
|
|
|
29428
29449
|
"human"
|
|
29429
29450
|
]);
|
|
29430
29451
|
EvidenceRefSchema = external_exports.object({
|
|
29431
|
-
/**
|
|
29452
|
+
/**
|
|
29453
|
+
* Seq of the originating session event. Required (by policy) for
|
|
29454
|
+
* event-backed tiers on the 2.0 path: evidence without a session anchor
|
|
29455
|
+
* is narration, not traceable output (F3 / ADR-0023 §5).
|
|
29456
|
+
*/
|
|
29432
29457
|
seq: external_exports.number().int().positive().optional(),
|
|
29433
29458
|
tier: EvidenceTierSchema,
|
|
29434
29459
|
/** Human-readable pointer: command line, file path, tool call id… */
|
|
@@ -29437,6 +29462,11 @@ var init_types9 = __esm({
|
|
|
29437
29462
|
/** sha256 of the captured output (audit chain). */
|
|
29438
29463
|
digest: external_exports.string().optional()
|
|
29439
29464
|
});
|
|
29465
|
+
EVENT_BACKED_EVIDENCE_TIERS = [
|
|
29466
|
+
"tool-output",
|
|
29467
|
+
"command-output",
|
|
29468
|
+
"fs-observation"
|
|
29469
|
+
];
|
|
29440
29470
|
VerificationStatusSchema = external_exports.enum(["pass", "fail", "unknown"]);
|
|
29441
29471
|
VerificationSourceSchema = external_exports.enum([
|
|
29442
29472
|
"deterministic-engine",
|
|
@@ -29482,21 +29512,52 @@ var init_engine = __esm({
|
|
|
29482
29512
|
results.push(await this.evaluateOne(criterion));
|
|
29483
29513
|
}
|
|
29484
29514
|
if (this.options.emit) {
|
|
29485
|
-
|
|
29486
|
-
|
|
29515
|
+
try {
|
|
29516
|
+
await this.options.emit({
|
|
29517
|
+
kind: "verification.run",
|
|
29518
|
+
actor: { type: "system", role: "verification" },
|
|
29519
|
+
data: {
|
|
29520
|
+
source: "deterministic-engine",
|
|
29521
|
+
packId: context.packId,
|
|
29522
|
+
results: results.map((r) => ({
|
|
29523
|
+
criterionId: r.criterionId,
|
|
29524
|
+
status: r.status,
|
|
29525
|
+
evidence: r.evidence.map((e) => ({
|
|
29526
|
+
tier: e.tier,
|
|
29527
|
+
ref: e.ref,
|
|
29528
|
+
digest: e.digest,
|
|
29529
|
+
...e.seq !== void 0 ? { seq: e.seq } : {}
|
|
29530
|
+
}))
|
|
29531
|
+
}))
|
|
29532
|
+
}
|
|
29533
|
+
});
|
|
29534
|
+
} catch {
|
|
29535
|
+
}
|
|
29536
|
+
}
|
|
29537
|
+
return results;
|
|
29538
|
+
}
|
|
29539
|
+
/**
|
|
29540
|
+
* F3: append one `verification.evidence` state event with the raw
|
|
29541
|
+
* observation and resolve to its session seq when the emitter returns it.
|
|
29542
|
+
* Spine failures degrade to `undefined` — an unreachable log must never
|
|
29543
|
+
* fail verification, it only leaves the evidence unanchored.
|
|
29544
|
+
*/
|
|
29545
|
+
async emitEvidence(data) {
|
|
29546
|
+
if (!this.options.emit)
|
|
29547
|
+
return void 0;
|
|
29548
|
+
try {
|
|
29549
|
+
const out = await this.options.emit({
|
|
29550
|
+
kind: "verification.evidence",
|
|
29487
29551
|
actor: { type: "system", role: "verification" },
|
|
29488
|
-
data
|
|
29489
|
-
source: "deterministic-engine",
|
|
29490
|
-
packId: context.packId,
|
|
29491
|
-
results: results.map((r) => ({
|
|
29492
|
-
criterionId: r.criterionId,
|
|
29493
|
-
status: r.status,
|
|
29494
|
-
evidence: r.evidence.map((e) => ({ tier: e.tier, ref: e.ref, digest: e.digest }))
|
|
29495
|
-
}))
|
|
29496
|
-
}
|
|
29552
|
+
data
|
|
29497
29553
|
});
|
|
29554
|
+
if (out && typeof out === "object" && typeof out.seq === "number") {
|
|
29555
|
+
return out.seq;
|
|
29556
|
+
}
|
|
29557
|
+
return void 0;
|
|
29558
|
+
} catch {
|
|
29559
|
+
return void 0;
|
|
29498
29560
|
}
|
|
29499
|
-
return results;
|
|
29500
29561
|
}
|
|
29501
29562
|
async evaluateOne(criterion) {
|
|
29502
29563
|
const started = this.options.now?.() ?? Date.now();
|
|
@@ -29536,12 +29597,23 @@ var init_engine = __esm({
|
|
|
29536
29597
|
return done({ status: "unknown", evidence: [], detail: "shell provider unavailable" });
|
|
29537
29598
|
}
|
|
29538
29599
|
const result = await shell.exec(check2.command, { timeoutMs: check2.timeoutMs });
|
|
29600
|
+
const digest = sha256(result.stdout);
|
|
29601
|
+
const seq = await this.emitEvidence({
|
|
29602
|
+
observation: "command",
|
|
29603
|
+
command: check2.command,
|
|
29604
|
+
exitCode: result.exitCode,
|
|
29605
|
+
timedOut: result.timedOut,
|
|
29606
|
+
digest,
|
|
29607
|
+
stdoutTail: tail(result.stdout),
|
|
29608
|
+
stderrTail: tail(result.stderr)
|
|
29609
|
+
});
|
|
29539
29610
|
const evidence = [
|
|
29540
29611
|
{
|
|
29541
29612
|
tier: "command-output",
|
|
29542
29613
|
ref: `${check2.command} \u2192 exit ${result.exitCode ?? "signal"}`,
|
|
29543
29614
|
capturedAt: Date.now(),
|
|
29544
|
-
digest
|
|
29615
|
+
digest,
|
|
29616
|
+
...seq !== void 0 ? { seq } : {}
|
|
29545
29617
|
}
|
|
29546
29618
|
];
|
|
29547
29619
|
if (result.timedOut) {
|
|
@@ -29564,8 +29636,21 @@ var init_engine = __esm({
|
|
|
29564
29636
|
}
|
|
29565
29637
|
return done({ status: "pass", evidence });
|
|
29566
29638
|
}
|
|
29567
|
-
|
|
29568
|
-
|
|
29639
|
+
/**
|
|
29640
|
+
* F3: the fs observation is logged to the spine (path, existence, optional
|
|
29641
|
+
* content digest) and the returned ref carries the event seq when the
|
|
29642
|
+
* emitter resolved one.
|
|
29643
|
+
*/
|
|
29644
|
+
async fsEvidence(observation, path64, sha256, content, extra = {}) {
|
|
29645
|
+
const digest = sha256 && content !== void 0 ? sha256(content) : void 0;
|
|
29646
|
+
const seq = await this.emitEvidence({ observation, path: path64, ...extra, ...digest ? { digest } : {} });
|
|
29647
|
+
return {
|
|
29648
|
+
tier: "fs-observation",
|
|
29649
|
+
ref: path64,
|
|
29650
|
+
capturedAt: Date.now(),
|
|
29651
|
+
...digest ? { digest } : {},
|
|
29652
|
+
...seq !== void 0 ? { seq } : {}
|
|
29653
|
+
};
|
|
29569
29654
|
}
|
|
29570
29655
|
async evalFileExists(check2, done) {
|
|
29571
29656
|
const sha256 = this.options.sha256 ?? defaultSha256;
|
|
@@ -29573,17 +29658,29 @@ var init_engine = __esm({
|
|
|
29573
29658
|
if (!fs37)
|
|
29574
29659
|
return done({ status: "unknown", evidence: [], detail: "fs provider unavailable" });
|
|
29575
29660
|
const exists = await fs37.exists(check2.path);
|
|
29576
|
-
if (!exists)
|
|
29661
|
+
if (!exists) {
|
|
29662
|
+
await this.emitEvidence({ observation: "file-exists", path: check2.path, exists: false });
|
|
29577
29663
|
return done({ status: "fail", evidence: [], detail: `file not found: ${check2.path}` });
|
|
29664
|
+
}
|
|
29578
29665
|
const content = await fs37.readFile(check2.path).catch(() => "");
|
|
29579
|
-
return done({
|
|
29666
|
+
return done({
|
|
29667
|
+
status: "pass",
|
|
29668
|
+
evidence: [await this.fsEvidence("file-exists", check2.path, sha256, content, { exists: true })]
|
|
29669
|
+
});
|
|
29580
29670
|
}
|
|
29581
29671
|
async evalFileAbsent(check2, done) {
|
|
29582
29672
|
const fs37 = this.services.fs;
|
|
29583
29673
|
if (!fs37)
|
|
29584
29674
|
return done({ status: "unknown", evidence: [], detail: "fs provider unavailable" });
|
|
29585
29675
|
const exists = await fs37.exists(check2.path);
|
|
29586
|
-
|
|
29676
|
+
if (exists) {
|
|
29677
|
+
await this.emitEvidence({ observation: "file-absent", path: check2.path, exists: true });
|
|
29678
|
+
return done({ status: "fail", evidence: [], detail: `file still present: ${check2.path}` });
|
|
29679
|
+
}
|
|
29680
|
+
return done({
|
|
29681
|
+
status: "pass",
|
|
29682
|
+
evidence: [await this.fsEvidence("file-absent", check2.path, void 0, void 0, { exists: false })]
|
|
29683
|
+
});
|
|
29587
29684
|
}
|
|
29588
29685
|
async evalFileContains(check2, done) {
|
|
29589
29686
|
const sha256 = this.options.sha256 ?? defaultSha256;
|
|
@@ -29594,9 +29691,10 @@ var init_engine = __esm({
|
|
|
29594
29691
|
try {
|
|
29595
29692
|
content = await fs37.readFile(check2.path);
|
|
29596
29693
|
} catch {
|
|
29694
|
+
await this.emitEvidence({ observation: "file-contains", path: check2.path, readable: false });
|
|
29597
29695
|
return done({ status: "fail", evidence: [], detail: `file not readable: ${check2.path}` });
|
|
29598
29696
|
}
|
|
29599
|
-
const evidence = [this.fsEvidence(check2.path,
|
|
29697
|
+
const evidence = [await this.fsEvidence("file-contains", check2.path, sha256, content)];
|
|
29600
29698
|
let hit;
|
|
29601
29699
|
try {
|
|
29602
29700
|
hit = new RegExp(check2.pattern, "m").test(content);
|
|
@@ -29622,6 +29720,7 @@ function evaluateCompletion(criteria, results, policy = STRICT_ALL_POLICY) {
|
|
|
29622
29720
|
const order = new Map(criteria.map((c, i) => [c.id, i]));
|
|
29623
29721
|
const satisfied = [];
|
|
29624
29722
|
const unsatisfied = [];
|
|
29723
|
+
let unbackedSatisfied = false;
|
|
29625
29724
|
const ids = [...requiredIds].sort((a, b) => (order.get(a) ?? 0) - (order.get(b) ?? 0));
|
|
29626
29725
|
for (const id of ids) {
|
|
29627
29726
|
const result = byId.get(id);
|
|
@@ -29646,7 +29745,8 @@ function evaluateCompletion(criteria, results, policy = STRICT_ALL_POLICY) {
|
|
|
29646
29745
|
continue;
|
|
29647
29746
|
}
|
|
29648
29747
|
const admissible = policy.admissibleTiers;
|
|
29649
|
-
|
|
29748
|
+
const tierOk = (e) => !admissible || admissible.includes(e.tier);
|
|
29749
|
+
if (!result.evidence.some(tierOk)) {
|
|
29650
29750
|
const tiers = [...new Set(result.evidence.map((e) => e.tier))].join(", ");
|
|
29651
29751
|
unsatisfied.push({
|
|
29652
29752
|
id,
|
|
@@ -29655,7 +29755,18 @@ function evaluateCompletion(criteria, results, policy = STRICT_ALL_POLICY) {
|
|
|
29655
29755
|
});
|
|
29656
29756
|
continue;
|
|
29657
29757
|
}
|
|
29758
|
+
const backed = result.evidence.filter(tierOk).some(isEventBackedEvidence);
|
|
29759
|
+
if (policy.requireEventBackedEvidence && !backed) {
|
|
29760
|
+
unsatisfied.push({
|
|
29761
|
+
id,
|
|
29762
|
+
status: "unknown",
|
|
29763
|
+
reason: "pass without event-backed evidence \u2014 no EvidenceRef.seq anchored to a session event"
|
|
29764
|
+
});
|
|
29765
|
+
continue;
|
|
29766
|
+
}
|
|
29658
29767
|
satisfied.push(id);
|
|
29768
|
+
if (!backed)
|
|
29769
|
+
unbackedSatisfied = true;
|
|
29659
29770
|
}
|
|
29660
29771
|
const verdict = unsatisfied.length === 0 ? "PASS" : unsatisfied.some((u) => u.status === "fail") ? "REPAIR_REQUIRED" : "BLOCKED";
|
|
29661
29772
|
return {
|
|
@@ -29663,6 +29774,7 @@ function evaluateCompletion(criteria, results, policy = STRICT_ALL_POLICY) {
|
|
|
29663
29774
|
satisfied,
|
|
29664
29775
|
unsatisfied,
|
|
29665
29776
|
evidenceComplete: unsatisfied.length === 0,
|
|
29777
|
+
eventBackedEvidenceComplete: unsatisfied.length === 0 && !unbackedSatisfied,
|
|
29666
29778
|
summary: verdict === "PASS" ? `complete: ${satisfied.length}/${ids.length} required criteria pass with evidence` : `incomplete (${verdict}): ${unsatisfied.map((u) => `${u.id}=${u.status}`).join(", ")}`
|
|
29667
29779
|
};
|
|
29668
29780
|
}
|
|
@@ -29670,6 +29782,7 @@ var STRICT_ALL_POLICY, DETERMINISTIC_EVIDENCE_TIERS, STRICT_BUILD_POLICY, strict
|
|
|
29670
29782
|
var init_completionPolicy = __esm({
|
|
29671
29783
|
"packages/core/dist/verification/completionPolicy.js"() {
|
|
29672
29784
|
"use strict";
|
|
29785
|
+
init_types9();
|
|
29673
29786
|
STRICT_ALL_POLICY = { mode: "strict", required: "*" };
|
|
29674
29787
|
DETERMINISTIC_EVIDENCE_TIERS = [
|
|
29675
29788
|
"tool-output",
|
|
@@ -29680,7 +29793,8 @@ var init_completionPolicy = __esm({
|
|
|
29680
29793
|
STRICT_BUILD_POLICY = {
|
|
29681
29794
|
mode: "strict",
|
|
29682
29795
|
required: "*",
|
|
29683
|
-
admissibleTiers: DETERMINISTIC_EVIDENCE_TIERS
|
|
29796
|
+
admissibleTiers: DETERMINISTIC_EVIDENCE_TIERS,
|
|
29797
|
+
requireEventBackedEvidence: true
|
|
29684
29798
|
};
|
|
29685
29799
|
strictBuildGate = evaluateCompletion;
|
|
29686
29800
|
}
|
|
@@ -29762,6 +29876,9 @@ function snapshotToCompletionEvaluation(snap) {
|
|
|
29762
29876
|
satisfied: [...snap.satisfied],
|
|
29763
29877
|
unsatisfied,
|
|
29764
29878
|
evidenceComplete: snap.evidenceComplete && unsatisfied.length === 0 && verdict === "PASS",
|
|
29879
|
+
// F3: snapshot summaries do not carry per-ref seq — event-backedness is
|
|
29880
|
+
// auditable from the raw spine events (verification.evidence), unknown here.
|
|
29881
|
+
eventBackedEvidenceComplete: false,
|
|
29765
29882
|
summary: snap.summary
|
|
29766
29883
|
};
|
|
29767
29884
|
}
|
|
@@ -29776,6 +29893,7 @@ var init_sessionEvidence = __esm({
|
|
|
29776
29893
|
// packages/core/dist/verification/criteriaPack.v1.js
|
|
29777
29894
|
function codingCriteriaPack(options = {}) {
|
|
29778
29895
|
const timeoutMs = options.commandTimeoutMs ?? 6e5;
|
|
29896
|
+
const withDefault = (o, d) => o === void 0 ? d : o;
|
|
29779
29897
|
const command = (command2) => command2 ? { kind: "command", command: command2, timeoutMs } : void 0;
|
|
29780
29898
|
const criteria = [
|
|
29781
29899
|
{
|
|
@@ -29783,21 +29901,21 @@ function codingCriteriaPack(options = {}) {
|
|
|
29783
29901
|
text: "Static checks (typecheck) pass with no new errors.",
|
|
29784
29902
|
source: "criteria-pack",
|
|
29785
29903
|
required: true,
|
|
29786
|
-
check: command(options.typecheckCommand
|
|
29904
|
+
check: command(withDefault(options.typecheckCommand, "npm run typecheck"))
|
|
29787
29905
|
},
|
|
29788
29906
|
{
|
|
29789
29907
|
id: "correctness.specification",
|
|
29790
29908
|
text: "The test suite passes \u2014 behavior matches the specification.",
|
|
29791
29909
|
source: "criteria-pack",
|
|
29792
29910
|
required: true,
|
|
29793
|
-
check: command(options.testCommand
|
|
29911
|
+
check: command(withDefault(options.testCommand, "npm run test"))
|
|
29794
29912
|
},
|
|
29795
29913
|
{
|
|
29796
29914
|
id: "correctness.observable-output",
|
|
29797
29915
|
text: "The project builds successfully (observable output artifact).",
|
|
29798
29916
|
source: "criteria-pack",
|
|
29799
29917
|
required: true,
|
|
29800
|
-
check: command(options.buildCommand
|
|
29918
|
+
check: command(withDefault(options.buildCommand, "npm run build"))
|
|
29801
29919
|
},
|
|
29802
29920
|
{
|
|
29803
29921
|
id: "quality.scope-discipline",
|
|
@@ -30095,7 +30213,8 @@ function deriveMissionState(projection) {
|
|
|
30095
30213
|
verifications: projection.verifications.length,
|
|
30096
30214
|
lastSeq: projection.lastSeq,
|
|
30097
30215
|
interrupted: projection.lastSeq > 0 && projection.endedAt === void 0,
|
|
30098
|
-
forkParent: projection.fork?.parentSessionId
|
|
30216
|
+
forkParent: projection.fork?.parentSessionId,
|
|
30217
|
+
lastAdvice: projection.missionAdvice[projection.missionAdvice.length - 1]
|
|
30099
30218
|
};
|
|
30100
30219
|
}
|
|
30101
30220
|
function missionSnapshot(state3) {
|
|
@@ -30113,11 +30232,99 @@ var init_missionState = __esm({
|
|
|
30113
30232
|
}
|
|
30114
30233
|
});
|
|
30115
30234
|
|
|
30235
|
+
// packages/core/dist/mission/continuationPolicy.js
|
|
30236
|
+
function requiredBlockers(progress) {
|
|
30237
|
+
const blockers = [];
|
|
30238
|
+
if (progress.ratio === null) {
|
|
30239
|
+
blockers.push("no verification criteria recorded yet");
|
|
30240
|
+
return blockers;
|
|
30241
|
+
}
|
|
30242
|
+
const missing = progress.criteriaTotal - progress.criteriaPassed;
|
|
30243
|
+
if (missing > 0) {
|
|
30244
|
+
blockers.push(`${missing}/${progress.criteriaTotal} required criteria not passing`);
|
|
30245
|
+
}
|
|
30246
|
+
if (progress.criteriaPassed === progress.criteriaTotal && !progress.evidenceComplete) {
|
|
30247
|
+
blockers.push("all criteria pass but evidence is incomplete (not event-backed)");
|
|
30248
|
+
}
|
|
30249
|
+
return blockers;
|
|
30250
|
+
}
|
|
30251
|
+
function evaluateMissionContinuation(input) {
|
|
30252
|
+
const { progress, verifier, budget, userSteer } = input;
|
|
30253
|
+
const base = { goalRewrite: false, doneByScore: false };
|
|
30254
|
+
const trend = verifier ? { tier: verifier.tier, value: verifier.value } : void 0;
|
|
30255
|
+
const blockers = requiredBlockers(progress);
|
|
30256
|
+
if (userSteer === "stop") {
|
|
30257
|
+
return {
|
|
30258
|
+
...base,
|
|
30259
|
+
recommendation: "wind-down",
|
|
30260
|
+
rationale: "user steer: explicit stop \u2014 winding down without claiming done",
|
|
30261
|
+
blockers,
|
|
30262
|
+
trend
|
|
30263
|
+
};
|
|
30264
|
+
}
|
|
30265
|
+
if (userSteer === "continue") {
|
|
30266
|
+
return {
|
|
30267
|
+
...base,
|
|
30268
|
+
recommendation: "continue",
|
|
30269
|
+
rationale: "user steer: explicit continue \u2014 overrides any trend-derived advice",
|
|
30270
|
+
blockers,
|
|
30271
|
+
trend
|
|
30272
|
+
};
|
|
30273
|
+
}
|
|
30274
|
+
if (budget && budget.iterationsUsed >= budget.iterationsMax) {
|
|
30275
|
+
return {
|
|
30276
|
+
...base,
|
|
30277
|
+
recommendation: "hold-for-user",
|
|
30278
|
+
rationale: `iteration budget exhausted (${budget.iterationsUsed}/${budget.iterationsMax}) \u2014 operator decides: raise budget or hand off`,
|
|
30279
|
+
blockers,
|
|
30280
|
+
trend
|
|
30281
|
+
};
|
|
30282
|
+
}
|
|
30283
|
+
if (blockers.length > 0) {
|
|
30284
|
+
const trendNote = verifier ? ` \xB7 verifier trend recorded as context only (tier ${verifier.tier}${verifier.value === null ? "" : `, ${verifier.value.toFixed(2)}`}) \u2014 trend is never authority` : "";
|
|
30285
|
+
return {
|
|
30286
|
+
...base,
|
|
30287
|
+
recommendation: "continue",
|
|
30288
|
+
rationale: `required criteria incomplete \u2192 no early-stop${trendNote}`,
|
|
30289
|
+
blockers,
|
|
30290
|
+
trend
|
|
30291
|
+
};
|
|
30292
|
+
}
|
|
30293
|
+
const blended = verifier?.tier === "blended" ? verifier.value : null;
|
|
30294
|
+
const rejected = verifier?.verdict === "rejected" || blended !== null && blended <= REJECTED_BLEND;
|
|
30295
|
+
if (rejected) {
|
|
30296
|
+
return {
|
|
30297
|
+
...base,
|
|
30298
|
+
recommendation: "hold-for-user",
|
|
30299
|
+
rationale: "deterministic evidence is complete and PASSing, but the verifier flags risk \u2014 attention requested; the deterministic verdict stands untouched",
|
|
30300
|
+
blockers: [],
|
|
30301
|
+
trend
|
|
30302
|
+
};
|
|
30303
|
+
}
|
|
30304
|
+
const confirmed = verifier?.verdict === "confirmed" || blended !== null && blended >= CONFIRMED_BLEND;
|
|
30305
|
+
return {
|
|
30306
|
+
...base,
|
|
30307
|
+
recommendation: "wind-down",
|
|
30308
|
+
rationale: confirmed ? "required criteria pass with evidence and the verifier confirms \u2014 candidate done (final say: driver + CompletionPolicy)" : "required criteria pass with evidence \u2014 candidate done on deterministic evidence (final say: driver + CompletionPolicy)",
|
|
30309
|
+
blockers: [],
|
|
30310
|
+
trend
|
|
30311
|
+
};
|
|
30312
|
+
}
|
|
30313
|
+
var CONFIRMED_BLEND, REJECTED_BLEND;
|
|
30314
|
+
var init_continuationPolicy = __esm({
|
|
30315
|
+
"packages/core/dist/mission/continuationPolicy.js"() {
|
|
30316
|
+
"use strict";
|
|
30317
|
+
CONFIRMED_BLEND = 0.8;
|
|
30318
|
+
REJECTED_BLEND = 0.35;
|
|
30319
|
+
}
|
|
30320
|
+
});
|
|
30321
|
+
|
|
30116
30322
|
// packages/core/dist/mission/index.js
|
|
30117
30323
|
var init_mission2 = __esm({
|
|
30118
30324
|
"packages/core/dist/mission/index.js"() {
|
|
30119
30325
|
"use strict";
|
|
30120
30326
|
init_missionState();
|
|
30327
|
+
init_continuationPolicy();
|
|
30121
30328
|
}
|
|
30122
30329
|
});
|
|
30123
30330
|
|
|
@@ -30157,6 +30364,7 @@ __export(dist_exports, {
|
|
|
30157
30364
|
DETERMINISTIC_EVIDENCE_TIERS: () => DETERMINISTIC_EVIDENCE_TIERS,
|
|
30158
30365
|
DOOM_LOOP_THRESHOLD: () => DOOM_LOOP_THRESHOLD,
|
|
30159
30366
|
DeterministicCheckSchema: () => DeterministicCheckSchema,
|
|
30367
|
+
EVENT_BACKED_EVIDENCE_TIERS: () => EVENT_BACKED_EVIDENCE_TIERS,
|
|
30160
30368
|
EXPERIMENTAL_FLAGS: () => EXPERIMENTAL_FLAGS,
|
|
30161
30369
|
EventBus: () => EventBus,
|
|
30162
30370
|
EvidenceRefSchema: () => EvidenceRefSchema,
|
|
@@ -30302,6 +30510,7 @@ __export(dist_exports, {
|
|
|
30302
30510
|
emptyContextGrowthStats: () => emptyContextGrowthStats,
|
|
30303
30511
|
enforceDesignPhaseToolEmissions: () => enforceDesignPhaseToolEmissions,
|
|
30304
30512
|
evaluateCompletion: () => evaluateCompletion,
|
|
30513
|
+
evaluateMissionContinuation: () => evaluateMissionContinuation,
|
|
30305
30514
|
executeTool: () => executeTool,
|
|
30306
30515
|
exportSession: () => exportSession,
|
|
30307
30516
|
exportSessionJson: () => exportSessionJson,
|
|
@@ -30357,6 +30566,7 @@ __export(dist_exports, {
|
|
|
30357
30566
|
isBrainToolExecutionStartEvent: () => isBrainToolExecutionStartEvent,
|
|
30358
30567
|
isBrainToolExecutionUpdateEvent: () => isBrainToolExecutionUpdateEvent,
|
|
30359
30568
|
isConverged: () => isConverged,
|
|
30569
|
+
isEventBackedEvidence: () => isEventBackedEvidence,
|
|
30360
30570
|
isExperimentalEnabled: () => isExperimentalEnabled,
|
|
30361
30571
|
isModelSurfaceEvent: () => isModelSurfaceEvent,
|
|
30362
30572
|
isReviewerKind: () => isReviewerKind,
|
|
@@ -30817,7 +31027,7 @@ var init_sessionSpine = __esm({
|
|
|
30817
31027
|
this.sessionsDir = resolveSessionsDir({ baseDir: options.baseDir });
|
|
30818
31028
|
}
|
|
30819
31029
|
writer = null;
|
|
30820
|
-
chain = Promise.resolve();
|
|
31030
|
+
chain = Promise.resolve(null);
|
|
30821
31031
|
streamBuffers = /* @__PURE__ */ new Map();
|
|
30822
31032
|
warned = false;
|
|
30823
31033
|
status = "disabled";
|
|
@@ -30953,18 +31163,44 @@ var init_sessionSpine = __esm({
|
|
|
30953
31163
|
data: { phase: phase2, ...note ? { note } : {} }
|
|
30954
31164
|
});
|
|
30955
31165
|
}
|
|
31166
|
+
/**
|
|
31167
|
+
* F4 (doc §6): append an advisory continuation record. State-only — the
|
|
31168
|
+
* recommendation must never feed the model loop or rewrite the goal.
|
|
31169
|
+
*/
|
|
31170
|
+
missionProgress(advice) {
|
|
31171
|
+
void this.append({
|
|
31172
|
+
kind: "mission.progress",
|
|
31173
|
+
actor: ACTOR_SYSTEM,
|
|
31174
|
+
data: {
|
|
31175
|
+
recommendation: advice.recommendation,
|
|
31176
|
+
rationale: advice.rationale,
|
|
31177
|
+
...advice.blockers ? { blockers: advice.blockers } : {},
|
|
31178
|
+
...advice.trend ? { trend: advice.trend } : {},
|
|
31179
|
+
...advice.iteration !== void 0 ? { iteration: advice.iteration } : {}
|
|
31180
|
+
}
|
|
31181
|
+
});
|
|
31182
|
+
}
|
|
30956
31183
|
note(text, data) {
|
|
30957
31184
|
void this.append({ kind: "note", actor: ACTOR_SYSTEM, data: { note: text, ...data } });
|
|
30958
31185
|
}
|
|
30959
31186
|
append(input) {
|
|
30960
|
-
if (!this.writer || this.status === "closed") return Promise.resolve();
|
|
30961
|
-
this.chain = this.chain.then(() => this.writer.append(input)).then(() =>
|
|
31187
|
+
if (!this.writer || this.status === "closed") return Promise.resolve(null);
|
|
31188
|
+
this.chain = this.chain.then(() => this.writer.append(input)).then((envelope) => envelope.seq).catch((err) => {
|
|
30962
31189
|
this.status = "degraded";
|
|
30963
31190
|
this.writer = null;
|
|
30964
31191
|
this.warnOnce(err);
|
|
31192
|
+
return null;
|
|
30965
31193
|
});
|
|
30966
31194
|
return this.chain;
|
|
30967
31195
|
}
|
|
31196
|
+
/**
|
|
31197
|
+
* F3 (ADR-0023 §5): append one spine event and resolve to its assigned
|
|
31198
|
+
* seq — the anchor EvidenceRef.seq points at. Null when degraded or
|
|
31199
|
+
* disabled: callers must treat null as "not traceable", never as failure.
|
|
31200
|
+
*/
|
|
31201
|
+
appendEvent(input) {
|
|
31202
|
+
return this.append(input);
|
|
31203
|
+
}
|
|
30968
31204
|
warnOnce(err) {
|
|
30969
31205
|
if (this.warned || this.options.quiet) return;
|
|
30970
31206
|
this.warned = true;
|
|
@@ -32583,9 +32819,9 @@ function spillToolOutput(fullText, meta3) {
|
|
|
32583
32819
|
const rnd = randomBytes2(3).toString("hex");
|
|
32584
32820
|
const safeTool = (meta3?.toolName ?? "tool").replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 32);
|
|
32585
32821
|
const file2 = `${stamp}-${safeTool}-${hash3}-${rnd}.txt`;
|
|
32586
|
-
const
|
|
32587
|
-
writeFileSync11(
|
|
32588
|
-
return
|
|
32822
|
+
const path64 = join11(dir, file2);
|
|
32823
|
+
writeFileSync11(path64, fullText, "utf8");
|
|
32824
|
+
return path64;
|
|
32589
32825
|
} catch {
|
|
32590
32826
|
return null;
|
|
32591
32827
|
}
|
|
@@ -32631,10 +32867,10 @@ function truncateToolResult(text, capOrOpts = TOOL_RESULT_LINE_CAP) {
|
|
|
32631
32867
|
${tail2}`;
|
|
32632
32868
|
}
|
|
32633
32869
|
if (doSpill) {
|
|
32634
|
-
const
|
|
32635
|
-
if (
|
|
32870
|
+
const path64 = spillToolOutput(text, { toolName: opts.toolName });
|
|
32871
|
+
if (path64) {
|
|
32636
32872
|
const spillNote = `
|
|
32637
|
-
\u2026 [full output spilled to: ${
|
|
32873
|
+
\u2026 [full output spilled to: ${path64} \u2014 re-read with read_file if you need the complete text] \u2026`;
|
|
32638
32874
|
if (preview.includes("] \u2026\n")) {
|
|
32639
32875
|
preview = preview.replace("] \u2026\n", `] \u2026${spillNote}
|
|
32640
32876
|
`);
|
|
@@ -35297,28 +35533,28 @@ var init_storage = __esm({
|
|
|
35297
35533
|
VALID_SCALARS = /^(true|false|null|~)$/i;
|
|
35298
35534
|
Storage = class {
|
|
35299
35535
|
/** Read a Markdown file with frontmatter. Throws if not found. */
|
|
35300
|
-
read(
|
|
35301
|
-
if (!existsSync19(
|
|
35302
|
-
throw new Error(`File not found: ${
|
|
35536
|
+
read(path64) {
|
|
35537
|
+
if (!existsSync19(path64)) {
|
|
35538
|
+
throw new Error(`File not found: ${path64}`);
|
|
35303
35539
|
}
|
|
35304
|
-
const md = readFileSync16(
|
|
35540
|
+
const md = readFileSync16(path64, "utf8");
|
|
35305
35541
|
return parseFrontmatter(md);
|
|
35306
35542
|
}
|
|
35307
35543
|
/** Read a Markdown file; returns null if not found. */
|
|
35308
|
-
readIfExists(
|
|
35309
|
-
if (!existsSync19(
|
|
35310
|
-
return this.read(
|
|
35544
|
+
readIfExists(path64) {
|
|
35545
|
+
if (!existsSync19(path64)) return null;
|
|
35546
|
+
return this.read(path64);
|
|
35311
35547
|
}
|
|
35312
35548
|
/**
|
|
35313
35549
|
* Write a Markdown file atomically (tmp + rename). Creates parent dirs.
|
|
35314
35550
|
* The meta object is serialized as YAML frontmatter; body as Markdown.
|
|
35315
35551
|
*/
|
|
35316
|
-
write(
|
|
35317
|
-
mkdirSync11(dirname2(
|
|
35318
|
-
const tmp =
|
|
35552
|
+
write(path64, meta3, body) {
|
|
35553
|
+
mkdirSync11(dirname2(path64), { recursive: true });
|
|
35554
|
+
const tmp = path64 + ".tmp-" + process.pid;
|
|
35319
35555
|
const md = serializeFrontmatter(meta3, body);
|
|
35320
35556
|
writeFileSync13(tmp, md, "utf8");
|
|
35321
|
-
renameSync2(tmp,
|
|
35557
|
+
renameSync2(tmp, path64);
|
|
35322
35558
|
}
|
|
35323
35559
|
/** List all .md files in a directory (non-recursive). */
|
|
35324
35560
|
listMarkdown(dir) {
|
|
@@ -35380,8 +35616,8 @@ function nextPlanTaskId(store6) {
|
|
|
35380
35616
|
return `t${store6.counter}`;
|
|
35381
35617
|
}
|
|
35382
35618
|
function writePlanTaskArtifact(rootDir, task) {
|
|
35383
|
-
const
|
|
35384
|
-
mkdirSync12(dirname3(
|
|
35619
|
+
const path64 = join15(rootDir, "plan-tasks", `${task.id}.md`);
|
|
35620
|
+
mkdirSync12(dirname3(path64), { recursive: true });
|
|
35385
35621
|
const meta3 = {
|
|
35386
35622
|
kind: "task",
|
|
35387
35623
|
id: task.id,
|
|
@@ -35402,7 +35638,7 @@ function writePlanTaskArtifact(rootDir, task) {
|
|
|
35402
35638
|
task.notes?.trim() ? task.notes.trim() : "_(no notes)_",
|
|
35403
35639
|
""
|
|
35404
35640
|
].filter((l) => l !== null).join("\n");
|
|
35405
|
-
new Storage().write(
|
|
35641
|
+
new Storage().write(path64, meta3, body);
|
|
35406
35642
|
}
|
|
35407
35643
|
function loadHandle(rootDir) {
|
|
35408
35644
|
const jsonPath = join15(rootDir, "plan.json");
|
|
@@ -37960,21 +38196,21 @@ function normalizeAuth(auth) {
|
|
|
37960
38196
|
return "agent";
|
|
37961
38197
|
}
|
|
37962
38198
|
function readSecrets() {
|
|
37963
|
-
const
|
|
37964
|
-
if (!existsSync23(
|
|
38199
|
+
const path64 = getSshSecretsPath();
|
|
38200
|
+
if (!existsSync23(path64)) return {};
|
|
37965
38201
|
try {
|
|
37966
|
-
return JSON.parse(readFileSync20(
|
|
38202
|
+
return JSON.parse(readFileSync20(path64, "utf8"));
|
|
37967
38203
|
} catch {
|
|
37968
38204
|
return {};
|
|
37969
38205
|
}
|
|
37970
38206
|
}
|
|
37971
38207
|
function writeSecrets(data) {
|
|
37972
|
-
const
|
|
37973
|
-
mkdirSync13(dirname4(
|
|
37974
|
-
writeFileSync15(
|
|
38208
|
+
const path64 = getSshSecretsPath();
|
|
38209
|
+
mkdirSync13(dirname4(path64), { recursive: true });
|
|
38210
|
+
writeFileSync15(path64, `${JSON.stringify(data, null, 2)}
|
|
37975
38211
|
`, "utf8");
|
|
37976
38212
|
try {
|
|
37977
|
-
chmodSync(
|
|
38213
|
+
chmodSync(path64, 384);
|
|
37978
38214
|
} catch {
|
|
37979
38215
|
}
|
|
37980
38216
|
}
|
|
@@ -38003,10 +38239,10 @@ function deleteSshPassword(id) {
|
|
|
38003
38239
|
writeSecrets({ passwords });
|
|
38004
38240
|
}
|
|
38005
38241
|
function readStore2() {
|
|
38006
|
-
const
|
|
38007
|
-
if (!existsSync23(
|
|
38242
|
+
const path64 = getSshTargetsPath();
|
|
38243
|
+
if (!existsSync23(path64)) return [];
|
|
38008
38244
|
try {
|
|
38009
|
-
const parsed = JSON.parse(readFileSync20(
|
|
38245
|
+
const parsed = JSON.parse(readFileSync20(path64, "utf8"));
|
|
38010
38246
|
const list = Array.isArray(parsed.targets) ? parsed.targets : [];
|
|
38011
38247
|
return list.filter(
|
|
38012
38248
|
(t) => t && typeof t.id === "string" && typeof t.host === "string" && typeof t.user === "string"
|
|
@@ -38021,11 +38257,11 @@ function readStore2() {
|
|
|
38021
38257
|
}
|
|
38022
38258
|
}
|
|
38023
38259
|
function writeStore2(targets) {
|
|
38024
|
-
const
|
|
38025
|
-
mkdirSync13(dirname4(
|
|
38260
|
+
const path64 = getSshTargetsPath();
|
|
38261
|
+
mkdirSync13(dirname4(path64), { recursive: true });
|
|
38026
38262
|
const clean = targets.map(({ hasPassword: _hp, ...t }) => t);
|
|
38027
38263
|
writeFileSync15(
|
|
38028
|
-
|
|
38264
|
+
path64,
|
|
38029
38265
|
`${JSON.stringify({ targets: clean }, null, 2)}
|
|
38030
38266
|
`,
|
|
38031
38267
|
"utf8"
|
|
@@ -38271,11 +38507,11 @@ function formatSshTargetsForPrompt() {
|
|
|
38271
38507
|
];
|
|
38272
38508
|
for (const t of targets) {
|
|
38273
38509
|
const tags = t.tags?.length ? ` tags=[${t.tags.join(",")}]` : "";
|
|
38274
|
-
const
|
|
38510
|
+
const path64 = t.defaultRemotePath ? ` remotePath=${t.defaultRemotePath}` : "";
|
|
38275
38511
|
const allow = t.allowedCommands?.length ? ` allowed=${t.allowedCommands.join("|")}` : " allowed=status-only";
|
|
38276
38512
|
const auth = t.auth === "password" ? " auth=password" : t.auth === "keyPath" ? " auth=key" : " auth=agent";
|
|
38277
38513
|
lines.push(
|
|
38278
|
-
`- id=${t.id} name=${t.name} ${t.user}@${t.host}:${t.port ?? 22}${auth}${
|
|
38514
|
+
`- id=${t.id} name=${t.name} ${t.user}@${t.host}:${t.port ?? 22}${auth}${path64}${tags}${allow}`
|
|
38279
38515
|
);
|
|
38280
38516
|
}
|
|
38281
38517
|
return lines.join("\n");
|
|
@@ -39985,6 +40221,9 @@ function parseHeadlessFlags(argv) {
|
|
|
39985
40221
|
i++;
|
|
39986
40222
|
} else if (arg === "--strict-done") {
|
|
39987
40223
|
strictDone = true;
|
|
40224
|
+
} else if (arg === "--no-strict-done") {
|
|
40225
|
+
strictDone = false;
|
|
40226
|
+
process.env.ZELARI_MISSION_STRICT = "0";
|
|
39988
40227
|
} else if (arg === "--kraken-graph") {
|
|
39989
40228
|
krakenGraph = argv[i + 1];
|
|
39990
40229
|
i++;
|
|
@@ -40138,12 +40377,18 @@ async function openHeadlessSpine(opts) {
|
|
|
40138
40377
|
verificationRun(payload) {
|
|
40139
40378
|
spine.verificationRun(payload);
|
|
40140
40379
|
},
|
|
40380
|
+
appendEvent(input) {
|
|
40381
|
+
return spine.appendEvent(input);
|
|
40382
|
+
},
|
|
40141
40383
|
lastVerificationRun() {
|
|
40142
40384
|
return spine.lastVerificationRun();
|
|
40143
40385
|
},
|
|
40144
40386
|
missionPhase(phase2, note) {
|
|
40145
40387
|
spine.missionPhase(phase2, note);
|
|
40146
40388
|
},
|
|
40389
|
+
missionProgress(advice) {
|
|
40390
|
+
spine.missionProgress(advice);
|
|
40391
|
+
},
|
|
40147
40392
|
note(text, data) {
|
|
40148
40393
|
spine.note(text, data);
|
|
40149
40394
|
},
|
|
@@ -40253,12 +40498,12 @@ var init_headlessSpine = __esm({
|
|
|
40253
40498
|
// src/cli/state/fileStateStore.ts
|
|
40254
40499
|
import { createHash as createHash10, randomUUID as randomUUID2 } from "node:crypto";
|
|
40255
40500
|
import { promises as fs21 } from "node:fs";
|
|
40256
|
-
import * as
|
|
40501
|
+
import * as path41 from "node:path";
|
|
40257
40502
|
function shortId() {
|
|
40258
40503
|
return randomUUID2().replace(/-/g, "").slice(0, 12);
|
|
40259
40504
|
}
|
|
40260
40505
|
async function writeJsonAtomic(filePath, data) {
|
|
40261
|
-
await fs21.mkdir(
|
|
40506
|
+
await fs21.mkdir(path41.dirname(filePath), { recursive: true });
|
|
40262
40507
|
const tmp = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
40263
40508
|
await fs21.writeFile(tmp, JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
40264
40509
|
await fs21.rename(tmp, filePath);
|
|
@@ -40319,11 +40564,11 @@ var init_fileStateStore = __esm({
|
|
|
40319
40564
|
indexPath = "";
|
|
40320
40565
|
async init(projectRoot) {
|
|
40321
40566
|
this.root = projectRoot;
|
|
40322
|
-
this.stateDir =
|
|
40323
|
-
this.commitsDir =
|
|
40324
|
-
this.artifactsDir =
|
|
40325
|
-
this.headPath =
|
|
40326
|
-
this.indexPath =
|
|
40567
|
+
this.stateDir = path41.join(projectRoot, ".zelari", "state");
|
|
40568
|
+
this.commitsDir = path41.join(this.stateDir, "commits");
|
|
40569
|
+
this.artifactsDir = path41.join(this.stateDir, "artifacts");
|
|
40570
|
+
this.headPath = path41.join(this.stateDir, "HEAD.json");
|
|
40571
|
+
this.indexPath = path41.join(this.stateDir, "index.jsonl");
|
|
40327
40572
|
await fs21.mkdir(this.commitsDir, { recursive: true });
|
|
40328
40573
|
await fs21.mkdir(this.artifactsDir, { recursive: true });
|
|
40329
40574
|
}
|
|
@@ -40336,13 +40581,13 @@ var init_fileStateStore = __esm({
|
|
|
40336
40581
|
const discoveries = input.discoveries ?? [];
|
|
40337
40582
|
const parent = await this.head();
|
|
40338
40583
|
const id = shortId();
|
|
40339
|
-
const artifactRel =
|
|
40340
|
-
const artifactAbs =
|
|
40584
|
+
const artifactRel = path41.join("artifacts", id);
|
|
40585
|
+
const artifactAbs = path41.join(this.artifactsDir, id);
|
|
40341
40586
|
await fs21.mkdir(artifactAbs, { recursive: true });
|
|
40342
40587
|
const summary = defaultSummary(input, discoveries);
|
|
40343
|
-
await fs21.writeFile(
|
|
40344
|
-
await writeJsonAtomic(
|
|
40345
|
-
await writeJsonAtomic(
|
|
40588
|
+
await fs21.writeFile(path41.join(artifactAbs, "summary.md"), summary + "\n", "utf8");
|
|
40589
|
+
await writeJsonAtomic(path41.join(artifactAbs, "discoveries.json"), discoveries);
|
|
40590
|
+
await writeJsonAtomic(path41.join(artifactAbs, "verification.json"), input.verification);
|
|
40346
40591
|
const meta3 = {
|
|
40347
40592
|
id,
|
|
40348
40593
|
parentId: parent?.id ?? null,
|
|
@@ -40354,14 +40599,14 @@ var init_fileStateStore = __esm({
|
|
|
40354
40599
|
workspaceCheckpointId: input.workspaceCheckpointId,
|
|
40355
40600
|
verification: {
|
|
40356
40601
|
...input.verification,
|
|
40357
|
-
reportPath: input.verification.reportPath ??
|
|
40602
|
+
reportPath: input.verification.reportPath ?? path41.join(".zelari", "state", artifactRel, "verification.json").replace(/\\/g, "/")
|
|
40358
40603
|
},
|
|
40359
40604
|
changedPaths: input.changedPaths ?? [],
|
|
40360
40605
|
stablePromptHash: input.stablePromptHash,
|
|
40361
40606
|
discoveryCount: discoveries.length,
|
|
40362
40607
|
artifactDir: artifactRel.replace(/\\/g, "/")
|
|
40363
40608
|
};
|
|
40364
|
-
await writeJsonAtomic(
|
|
40609
|
+
await writeJsonAtomic(path41.join(this.commitsDir, `${id}.json`), meta3);
|
|
40365
40610
|
await writeJsonAtomic(this.headPath, { id, updatedAt: meta3.createdAt });
|
|
40366
40611
|
await fs21.appendFile(this.indexPath, JSON.stringify({ id, createdAt: meta3.createdAt, label: meta3.label }) + "\n", "utf8");
|
|
40367
40612
|
return stripStored(meta3);
|
|
@@ -40372,7 +40617,7 @@ var init_fileStateStore = __esm({
|
|
|
40372
40617
|
return this.get(head.id);
|
|
40373
40618
|
}
|
|
40374
40619
|
async get(id) {
|
|
40375
|
-
const stored = await readJsonFile(
|
|
40620
|
+
const stored = await readJsonFile(path41.join(this.commitsDir, `${id}.json`));
|
|
40376
40621
|
return stored ? stripStored(stored) : null;
|
|
40377
40622
|
}
|
|
40378
40623
|
async list(limit = 20) {
|
|
@@ -40411,9 +40656,9 @@ var init_fileStateStore = __esm({
|
|
|
40411
40656
|
async loadDiscoveries(id) {
|
|
40412
40657
|
const meta3 = id ? await this.get(id) : await this.head();
|
|
40413
40658
|
if (!meta3) return [];
|
|
40414
|
-
const stored = await readJsonFile(
|
|
40659
|
+
const stored = await readJsonFile(path41.join(this.commitsDir, `${meta3.id}.json`));
|
|
40415
40660
|
if (!stored?.artifactDir) return [];
|
|
40416
|
-
const discPath =
|
|
40661
|
+
const discPath = path41.join(this.stateDir, stored.artifactDir, "discoveries.json");
|
|
40417
40662
|
return await readJsonFile(discPath) ?? [];
|
|
40418
40663
|
}
|
|
40419
40664
|
async materializeContext(id, maxChars = DEFAULT_MATERIALIZE_CHARS) {
|
|
@@ -42123,8 +42368,8 @@ function readPlan(ctx) {
|
|
|
42123
42368
|
} catch {
|
|
42124
42369
|
}
|
|
42125
42370
|
}
|
|
42126
|
-
const
|
|
42127
|
-
const doc = ctx.storage.readIfExists(
|
|
42371
|
+
const path64 = workspaceFile(ctx.rootDir, "plan");
|
|
42372
|
+
const doc = ctx.storage.readIfExists(path64);
|
|
42128
42373
|
if (!doc) return { phases: [], tasks: [], milestones: [] };
|
|
42129
42374
|
const meta3 = doc.meta;
|
|
42130
42375
|
return {
|
|
@@ -42302,7 +42547,7 @@ function addMilestoneRecord(ctx, summary, input) {
|
|
|
42302
42547
|
dueDate: input.dueDate,
|
|
42303
42548
|
targetVersion: version2
|
|
42304
42549
|
});
|
|
42305
|
-
const
|
|
42550
|
+
const path64 = join25(ctx.rootDir, "milestones", `${id}.md`);
|
|
42306
42551
|
const meta3 = {
|
|
42307
42552
|
kind: "milestone",
|
|
42308
42553
|
id,
|
|
@@ -42319,7 +42564,7 @@ function addMilestoneRecord(ctx, summary, input) {
|
|
|
42319
42564
|
`Target version: ${version2}`,
|
|
42320
42565
|
""
|
|
42321
42566
|
].join("\n");
|
|
42322
|
-
ctx.storage.write(
|
|
42567
|
+
ctx.storage.write(path64, meta3, body);
|
|
42323
42568
|
return { id, created: true };
|
|
42324
42569
|
}
|
|
42325
42570
|
function readPlanSummary(ctx) {
|
|
@@ -42523,7 +42768,7 @@ function addIdeaStub(ctx) {
|
|
|
42523
42768
|
const tags = args["tags"] ?? [];
|
|
42524
42769
|
const category = args["category"] ?? "General";
|
|
42525
42770
|
const id = `${nextAdrId(ctx)}-${slugify3(title)}`;
|
|
42526
|
-
const
|
|
42771
|
+
const path64 = workspaceArtifact(ctx.rootDir, "decisions", id);
|
|
42527
42772
|
const meta3 = {
|
|
42528
42773
|
kind: "adr",
|
|
42529
42774
|
status: "proposed",
|
|
@@ -42549,7 +42794,7 @@ function addIdeaStub(ctx) {
|
|
|
42549
42794
|
...consequences.map((c) => `- ${c}`),
|
|
42550
42795
|
""
|
|
42551
42796
|
].join("\n");
|
|
42552
|
-
ctx.storage.write(
|
|
42797
|
+
ctx.storage.write(path64, meta3, body);
|
|
42553
42798
|
return `ADR ${id} created: "${title}". Status: proposed. Promote to accepted via /update ADR or manual edit.`;
|
|
42554
42799
|
});
|
|
42555
42800
|
}
|
|
@@ -42631,14 +42876,14 @@ function createDocumentStub(ctx) {
|
|
|
42631
42876
|
ctx.storage.write(risksPath, riskMeta, content);
|
|
42632
42877
|
return `Document "${title}" created at risks.md (workspace root).`;
|
|
42633
42878
|
}
|
|
42634
|
-
const
|
|
42879
|
+
const path64 = workspaceArtifact(ctx.rootDir, "docs", slug);
|
|
42635
42880
|
const meta3 = {
|
|
42636
42881
|
kind: "doc",
|
|
42637
42882
|
id: slug,
|
|
42638
42883
|
date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
|
|
42639
42884
|
tags
|
|
42640
42885
|
};
|
|
42641
|
-
ctx.storage.write(
|
|
42886
|
+
ctx.storage.write(path64, meta3, content);
|
|
42642
42887
|
return `Document "${title}" created at docs/${slug}.md.`;
|
|
42643
42888
|
});
|
|
42644
42889
|
}
|
|
@@ -42859,15 +43104,15 @@ __export(updater_exports, {
|
|
|
42859
43104
|
import { createRequire as createRequire2 } from "node:module";
|
|
42860
43105
|
import { spawn as spawn12 } from "node:child_process";
|
|
42861
43106
|
import { existsSync as existsSync32 } from "node:fs";
|
|
42862
|
-
import
|
|
43107
|
+
import path42 from "node:path";
|
|
42863
43108
|
import { fileURLToPath } from "node:url";
|
|
42864
43109
|
function resolveBundledNpmCli(execPath = process.execPath) {
|
|
42865
|
-
const dir =
|
|
43110
|
+
const dir = path42.dirname(execPath);
|
|
42866
43111
|
const candidates = [
|
|
42867
43112
|
// Windows: C:\...\node.exe → C:\...\node_modules\npm\bin\npm-cli.js
|
|
42868
|
-
|
|
43113
|
+
path42.join(dir, "node_modules", "npm", "bin", "npm-cli.js"),
|
|
42869
43114
|
// POSIX: <prefix>/bin/node → <prefix>/lib/node_modules/npm/bin/npm-cli.js
|
|
42870
|
-
|
|
43115
|
+
path42.join(dir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js")
|
|
42871
43116
|
];
|
|
42872
43117
|
for (const candidate of candidates) {
|
|
42873
43118
|
try {
|
|
@@ -42884,7 +43129,7 @@ function looksLikeBrokenShim(exitCode, output) {
|
|
|
42884
43129
|
}
|
|
42885
43130
|
function getCurrentVersion() {
|
|
42886
43131
|
try {
|
|
42887
|
-
const pkgPath =
|
|
43132
|
+
const pkgPath = path42.resolve(__dirname2, "..", "..", "package.json");
|
|
42888
43133
|
const pkg = require2(pkgPath);
|
|
42889
43134
|
return pkg.version;
|
|
42890
43135
|
} catch {
|
|
@@ -43007,7 +43252,7 @@ var init_updater = __esm({
|
|
|
43007
43252
|
"use strict";
|
|
43008
43253
|
init_cmdline();
|
|
43009
43254
|
require2 = createRequire2(import.meta.url);
|
|
43010
|
-
__dirname2 =
|
|
43255
|
+
__dirname2 = path42.dirname(fileURLToPath(import.meta.url));
|
|
43011
43256
|
REGISTRY_URL = "https://registry.npmjs.org/zelari-code/latest";
|
|
43012
43257
|
}
|
|
43013
43258
|
});
|
|
@@ -43195,10 +43440,10 @@ function getUserMcpPath() {
|
|
|
43195
43440
|
function getProjectMcpPath(projectRoot) {
|
|
43196
43441
|
return join26(projectRoot, ".zelari", "mcp.json");
|
|
43197
43442
|
}
|
|
43198
|
-
function
|
|
43199
|
-
if (!existsSync33(
|
|
43443
|
+
function readFile3(path64) {
|
|
43444
|
+
if (!existsSync33(path64)) return {};
|
|
43200
43445
|
try {
|
|
43201
|
-
const parsed = JSON.parse(readFileSync28(
|
|
43446
|
+
const parsed = JSON.parse(readFileSync28(path64, "utf8"));
|
|
43202
43447
|
const out = {};
|
|
43203
43448
|
for (const [name, cfg] of Object.entries(parsed.mcpServers ?? {})) {
|
|
43204
43449
|
if (!cfg || typeof cfg.command !== "string" || !cfg.command.trim()) continue;
|
|
@@ -43214,17 +43459,17 @@ function readFile2(path63) {
|
|
|
43214
43459
|
return {};
|
|
43215
43460
|
}
|
|
43216
43461
|
}
|
|
43217
|
-
function writeFile(
|
|
43218
|
-
mkdirSync16(dirname7(
|
|
43462
|
+
function writeFile(path64, servers) {
|
|
43463
|
+
mkdirSync16(dirname7(path64), { recursive: true });
|
|
43219
43464
|
const body = { mcpServers: servers };
|
|
43220
|
-
writeFileSync18(
|
|
43465
|
+
writeFileSync18(path64, `${JSON.stringify(body, null, 2)}
|
|
43221
43466
|
`, "utf8");
|
|
43222
43467
|
}
|
|
43223
43468
|
function listMcpServers(projectRoot) {
|
|
43224
43469
|
const userPath = getUserMcpPath();
|
|
43225
|
-
const userServers =
|
|
43470
|
+
const userServers = readFile3(userPath);
|
|
43226
43471
|
const projectPath = projectRoot && projectRoot.trim() ? getProjectMcpPath(projectRoot.trim()) : null;
|
|
43227
|
-
const projectServers = projectPath ?
|
|
43472
|
+
const projectServers = projectPath ? readFile3(projectPath) : {};
|
|
43228
43473
|
const servers = [];
|
|
43229
43474
|
for (const [name, cfg] of Object.entries(userServers)) {
|
|
43230
43475
|
servers.push({ name, ...cfg, scope: "user", path: userPath });
|
|
@@ -43250,9 +43495,9 @@ function upsertMcpServer(opts) {
|
|
|
43250
43495
|
if (!opts.config.command?.trim()) {
|
|
43251
43496
|
return { ok: false, error: "command is required" };
|
|
43252
43497
|
}
|
|
43253
|
-
let
|
|
43498
|
+
let path64;
|
|
43254
43499
|
if (opts.scope === "user") {
|
|
43255
|
-
|
|
43500
|
+
path64 = getUserMcpPath();
|
|
43256
43501
|
} else {
|
|
43257
43502
|
const root = opts.projectRoot?.trim();
|
|
43258
43503
|
if (!root) {
|
|
@@ -43261,30 +43506,30 @@ function upsertMcpServer(opts) {
|
|
|
43261
43506
|
error: "projectRoot required for project scope (Open Folder first)"
|
|
43262
43507
|
};
|
|
43263
43508
|
}
|
|
43264
|
-
|
|
43509
|
+
path64 = getProjectMcpPath(root);
|
|
43265
43510
|
}
|
|
43266
|
-
const current =
|
|
43511
|
+
const current = readFile3(path64);
|
|
43267
43512
|
current[name] = {
|
|
43268
43513
|
command: opts.config.command.trim(),
|
|
43269
43514
|
args: opts.config.args,
|
|
43270
43515
|
env: opts.config.env,
|
|
43271
43516
|
enabled: opts.config.enabled !== false
|
|
43272
43517
|
};
|
|
43273
|
-
writeFile(
|
|
43274
|
-
return { ok: true, path:
|
|
43518
|
+
writeFile(path64, current);
|
|
43519
|
+
return { ok: true, path: path64 };
|
|
43275
43520
|
}
|
|
43276
43521
|
function removeMcpServer(opts) {
|
|
43277
|
-
const
|
|
43278
|
-
if (!
|
|
43522
|
+
const path64 = opts.scope === "user" ? getUserMcpPath() : opts.projectRoot ? getProjectMcpPath(opts.projectRoot) : null;
|
|
43523
|
+
if (!path64) {
|
|
43279
43524
|
return { ok: false, error: "projectRoot required for project scope" };
|
|
43280
43525
|
}
|
|
43281
|
-
const current =
|
|
43526
|
+
const current = readFile3(path64);
|
|
43282
43527
|
if (!(opts.name in current)) {
|
|
43283
|
-
return { ok: false, error: `Server "${opts.name}" not found in ${
|
|
43528
|
+
return { ok: false, error: `Server "${opts.name}" not found in ${path64}` };
|
|
43284
43529
|
}
|
|
43285
43530
|
delete current[opts.name];
|
|
43286
|
-
writeFile(
|
|
43287
|
-
return { ok: true, path:
|
|
43531
|
+
writeFile(path64, current);
|
|
43532
|
+
return { ok: true, path: path64 };
|
|
43288
43533
|
}
|
|
43289
43534
|
var init_mcpConfigIo = __esm({
|
|
43290
43535
|
"src/cli/mcp/mcpConfigIo.ts"() {
|
|
@@ -43683,12 +43928,12 @@ __export(agentsMd_exports, {
|
|
|
43683
43928
|
import { existsSync as existsSync35, readFileSync as readFileSync30, writeFileSync as writeFileSync19 } from "node:fs";
|
|
43684
43929
|
import { createHash as createHash11 } from "node:crypto";
|
|
43685
43930
|
import { join as join28 } from "node:path";
|
|
43686
|
-
import { readFile as
|
|
43931
|
+
import { readFile as readFile4 } from "node:fs/promises";
|
|
43687
43932
|
async function readPackageJson2(projectRoot) {
|
|
43688
|
-
const
|
|
43689
|
-
if (!existsSync35(
|
|
43933
|
+
const path64 = join28(projectRoot, "package.json");
|
|
43934
|
+
if (!existsSync35(path64)) return null;
|
|
43690
43935
|
try {
|
|
43691
|
-
return JSON.parse(await
|
|
43936
|
+
return JSON.parse(await readFile4(path64, "utf8"));
|
|
43692
43937
|
} catch {
|
|
43693
43938
|
return null;
|
|
43694
43939
|
}
|
|
@@ -43770,9 +44015,9 @@ async function genBuild(ctx) {
|
|
|
43770
44015
|
].join("\n");
|
|
43771
44016
|
}
|
|
43772
44017
|
async function genOpenQuestions(ctx) {
|
|
43773
|
-
const
|
|
43774
|
-
if (!existsSync35(
|
|
43775
|
-
const content = readFileSync30(
|
|
44018
|
+
const path64 = join28(ctx.rootDir, "risks.md");
|
|
44019
|
+
if (!existsSync35(path64)) return "_No open questions._";
|
|
44020
|
+
const content = readFileSync30(path64, "utf8");
|
|
43776
44021
|
const lines = content.split("\n");
|
|
43777
44022
|
const questions = [];
|
|
43778
44023
|
let currentTitle = "";
|
|
@@ -44046,9 +44291,9 @@ function versionKey(value) {
|
|
|
44046
44291
|
function firstString2(v) {
|
|
44047
44292
|
return typeof v === "string" && v.trim().length > 0 ? v : null;
|
|
44048
44293
|
}
|
|
44049
|
-
function readFileSyncSafe(
|
|
44294
|
+
function readFileSyncSafe(path64) {
|
|
44050
44295
|
try {
|
|
44051
|
-
return readFileSync31(
|
|
44296
|
+
return readFileSync31(path64, "utf8");
|
|
44052
44297
|
} catch {
|
|
44053
44298
|
return null;
|
|
44054
44299
|
}
|
|
@@ -44511,8 +44756,8 @@ async function runPostCouncilHook(ctx, options) {
|
|
|
44511
44756
|
sources: scope.sources
|
|
44512
44757
|
} : void 0
|
|
44513
44758
|
});
|
|
44514
|
-
const
|
|
44515
|
-
completionHook = { ran: true, path:
|
|
44759
|
+
const path64 = writeCouncilCompletion(ctx.rootDir, completion);
|
|
44760
|
+
completionHook = { ran: true, path: path64, completion };
|
|
44516
44761
|
} catch (err) {
|
|
44517
44762
|
completionHook = {
|
|
44518
44763
|
ran: true,
|
|
@@ -44557,7 +44802,7 @@ import {
|
|
|
44557
44802
|
writeFileSync as writeFileSync21,
|
|
44558
44803
|
mkdirSync as mkdirSync17
|
|
44559
44804
|
} from "node:fs";
|
|
44560
|
-
import
|
|
44805
|
+
import path43 from "node:path";
|
|
44561
44806
|
import os10 from "node:os";
|
|
44562
44807
|
var FeedbackStore;
|
|
44563
44808
|
var init_councilFeedback = __esm({
|
|
@@ -44568,7 +44813,7 @@ var init_councilFeedback = __esm({
|
|
|
44568
44813
|
now;
|
|
44569
44814
|
entries = [];
|
|
44570
44815
|
constructor(options = {}) {
|
|
44571
|
-
this.file = options.file ?? (process.env.ANATHEMA_COUNCIL_FEEDBACK_FILE ??
|
|
44816
|
+
this.file = options.file ?? (process.env.ANATHEMA_COUNCIL_FEEDBACK_FILE ?? path43.join(os10.homedir(), ".tmp", "zelari-code", "council-feedback.json"));
|
|
44572
44817
|
this.now = options.now ?? Date.now;
|
|
44573
44818
|
this.load();
|
|
44574
44819
|
}
|
|
@@ -44674,7 +44919,7 @@ var init_councilFeedback = __esm({
|
|
|
44674
44919
|
}
|
|
44675
44920
|
}
|
|
44676
44921
|
save() {
|
|
44677
|
-
mkdirSync17(
|
|
44922
|
+
mkdirSync17(path43.dirname(this.file), { recursive: true });
|
|
44678
44923
|
writeFileSync21(
|
|
44679
44924
|
this.file,
|
|
44680
44925
|
JSON.stringify({ entries: this.entries }, null, 2),
|
|
@@ -44742,7 +44987,7 @@ import { execFile as execFile3 } from "node:child_process";
|
|
|
44742
44987
|
import { promisify as promisify2 } from "node:util";
|
|
44743
44988
|
import { mkdtempSync, rmSync as rmSync2 } from "node:fs";
|
|
44744
44989
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
44745
|
-
import
|
|
44990
|
+
import path44 from "node:path";
|
|
44746
44991
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
44747
44992
|
async function git3(cwd, args, env) {
|
|
44748
44993
|
const { stdout } = await execFileAsync2("git", ["-C", cwd, ...args], {
|
|
@@ -44762,8 +45007,8 @@ async function isGitRepo(cwd) {
|
|
|
44762
45007
|
return await gitSafe(cwd, ["rev-parse", "--is-inside-work-tree"]) === "true";
|
|
44763
45008
|
}
|
|
44764
45009
|
async function withTempIndex(fn) {
|
|
44765
|
-
const dir = mkdtempSync(
|
|
44766
|
-
const indexFile =
|
|
45010
|
+
const dir = mkdtempSync(path44.join(tmpdir2(), "zelari-ckpt-"));
|
|
45011
|
+
const indexFile = path44.join(dir, "index");
|
|
44767
45012
|
try {
|
|
44768
45013
|
return await fn(indexFile);
|
|
44769
45014
|
} finally {
|
|
@@ -44854,7 +45099,7 @@ async function restoreCheckpoint(cwd, id) {
|
|
|
44854
45099
|
const deleted = [];
|
|
44855
45100
|
for (const rel2 of added) {
|
|
44856
45101
|
try {
|
|
44857
|
-
rmSync2(
|
|
45102
|
+
rmSync2(path44.join(cwd, rel2), { force: true });
|
|
44858
45103
|
deleted.push(rel2);
|
|
44859
45104
|
} catch {
|
|
44860
45105
|
}
|
|
@@ -44955,7 +45200,7 @@ __export(fileBackend_exports, {
|
|
|
44955
45200
|
});
|
|
44956
45201
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
44957
45202
|
import { promises as fs23 } from "node:fs";
|
|
44958
|
-
import * as
|
|
45203
|
+
import * as path45 from "node:path";
|
|
44959
45204
|
function tokenize(text) {
|
|
44960
45205
|
return text.toLowerCase().split(/[^\p{L}\p{N}]+/u).filter((t) => t.length >= 3);
|
|
44961
45206
|
}
|
|
@@ -44999,8 +45244,8 @@ var init_fileBackend = __esm({
|
|
|
44999
45244
|
logPath = "";
|
|
45000
45245
|
memoryDir = "";
|
|
45001
45246
|
async init(projectRoot) {
|
|
45002
|
-
this.memoryDir =
|
|
45003
|
-
this.logPath =
|
|
45247
|
+
this.memoryDir = path45.join(projectRoot, ".zelari", "memory");
|
|
45248
|
+
this.logPath = path45.join(this.memoryDir, "log.jsonl");
|
|
45004
45249
|
await fs23.mkdir(this.memoryDir, { recursive: true });
|
|
45005
45250
|
}
|
|
45006
45251
|
async add(content, metadata = {}, graph) {
|
|
@@ -45073,12 +45318,12 @@ var init_fileBackend = __esm({
|
|
|
45073
45318
|
|
|
45074
45319
|
// src/cli/traceStore.ts
|
|
45075
45320
|
import { promises as fs24 } from "node:fs";
|
|
45076
|
-
import * as
|
|
45321
|
+
import * as path46 from "node:path";
|
|
45077
45322
|
function traceDir(projectRoot) {
|
|
45078
|
-
return
|
|
45323
|
+
return path46.join(projectRoot, ".zelari", "trace");
|
|
45079
45324
|
}
|
|
45080
45325
|
function tracePath(projectRoot, missionId) {
|
|
45081
|
-
return
|
|
45326
|
+
return path46.join(traceDir(projectRoot), `${missionId}.json`);
|
|
45082
45327
|
}
|
|
45083
45328
|
async function saveTrace(projectRoot, missionId, entries) {
|
|
45084
45329
|
const dir = traceDir(projectRoot);
|
|
@@ -45113,7 +45358,7 @@ __export(zelariMission_exports, {
|
|
|
45113
45358
|
});
|
|
45114
45359
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
45115
45360
|
import { promises as fs25 } from "node:fs";
|
|
45116
|
-
import * as
|
|
45361
|
+
import * as path47 from "node:path";
|
|
45117
45362
|
function resolveMaxIterations(env = process.env) {
|
|
45118
45363
|
const raw = env.ZELARI_MISSION_MAX_ITER;
|
|
45119
45364
|
const n = raw ? Number.parseInt(raw, 10) : DEFAULT_MAX_ITER;
|
|
@@ -45141,10 +45386,10 @@ function isMissionAutoStart(env = process.env) {
|
|
|
45141
45386
|
return env.ZELARI_MISSION_AUTO === "1";
|
|
45142
45387
|
}
|
|
45143
45388
|
async function writeMissionState(projectRoot, state3) {
|
|
45144
|
-
const dir =
|
|
45389
|
+
const dir = path47.join(projectRoot, ".zelari");
|
|
45145
45390
|
await fs25.mkdir(dir, { recursive: true });
|
|
45146
45391
|
await fs25.writeFile(
|
|
45147
|
-
|
|
45392
|
+
path47.join(dir, "mission-state.json"),
|
|
45148
45393
|
JSON.stringify(state3, null, 2) + "\n",
|
|
45149
45394
|
"utf8"
|
|
45150
45395
|
);
|
|
@@ -45376,6 +45621,17 @@ async function runZelariMission(userMessage, brief, deps) {
|
|
|
45376
45621
|
deps.emit(`[zelari] state commit skipped: ${commitRes.error}`);
|
|
45377
45622
|
}
|
|
45378
45623
|
}
|
|
45624
|
+
const missionProgress = {
|
|
45625
|
+
criteriaTotal: 1,
|
|
45626
|
+
criteriaPassed: completionOk ? 1 : 0,
|
|
45627
|
+
ratio: completionOk ? 1 : 0,
|
|
45628
|
+
evidenceComplete: completionOk && (typeof result.writeCount === "number" ? result.writeCount > 0 : true)
|
|
45629
|
+
};
|
|
45630
|
+
const advice = evaluateMissionContinuation({
|
|
45631
|
+
progress: missionProgress,
|
|
45632
|
+
budget: { iterationsUsed: implStep, iterationsMax: maxIter }
|
|
45633
|
+
});
|
|
45634
|
+
deps.onMissionProgress?.(advice, step);
|
|
45379
45635
|
if (completionOk) {
|
|
45380
45636
|
state3.status = "success";
|
|
45381
45637
|
deps.onMissionPhase?.("done", "mvp-green");
|
|
@@ -45422,6 +45678,7 @@ var DEFAULT_MAX_ITER, DEFAULT_MAX_STALL;
|
|
|
45422
45678
|
var init_zelariMission = __esm({
|
|
45423
45679
|
"src/cli/zelariMission.ts"() {
|
|
45424
45680
|
"use strict";
|
|
45681
|
+
init_mission2();
|
|
45425
45682
|
init_fileBackend();
|
|
45426
45683
|
init_checkpointManager();
|
|
45427
45684
|
init_fileStateStore();
|
|
@@ -45754,7 +46011,7 @@ function safeSocketPath(socketPath) {
|
|
|
45754
46011
|
return socketPath.trim();
|
|
45755
46012
|
}
|
|
45756
46013
|
function startPermissionBroker(socketPath, handlers, opts) {
|
|
45757
|
-
const
|
|
46014
|
+
const path64 = safeSocketPath(socketPath);
|
|
45758
46015
|
const requestTimeoutMs = opts?.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
|
|
45759
46016
|
const sockets = /* @__PURE__ */ new Set();
|
|
45760
46017
|
const server = createServer2((socket) => {
|
|
@@ -45854,10 +46111,10 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
45854
46111
|
return new Promise((resolve3, reject) => {
|
|
45855
46112
|
const onError = (err) => reject(err);
|
|
45856
46113
|
server.once("error", onError);
|
|
45857
|
-
server.listen(
|
|
46114
|
+
server.listen(path64, () => {
|
|
45858
46115
|
server.removeListener("error", onError);
|
|
45859
46116
|
resolve3({
|
|
45860
|
-
socketPath:
|
|
46117
|
+
socketPath: path64,
|
|
45861
46118
|
stop: () => new Promise((res) => {
|
|
45862
46119
|
for (const s of sockets) s.destroy();
|
|
45863
46120
|
sockets.clear();
|
|
@@ -45868,7 +46125,7 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
45868
46125
|
if (done) return;
|
|
45869
46126
|
done = true;
|
|
45870
46127
|
if (process.platform !== "win32") {
|
|
45871
|
-
unlink(
|
|
46128
|
+
unlink(path64, () => res());
|
|
45872
46129
|
} else {
|
|
45873
46130
|
res();
|
|
45874
46131
|
}
|
|
@@ -45881,11 +46138,11 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
45881
46138
|
});
|
|
45882
46139
|
}
|
|
45883
46140
|
function requestBrokerAsk(socketPath, ask, opts) {
|
|
45884
|
-
const
|
|
46141
|
+
const path64 = safeSocketPath(socketPath);
|
|
45885
46142
|
const requestTimeoutMs = opts?.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
|
|
45886
46143
|
const connectTimeoutMs = opts?.connectTimeoutMs ?? PERMISSION_BROKER_DEFAULT_CONNECT_TIMEOUT_MS;
|
|
45887
46144
|
return new Promise((resolve3, reject) => {
|
|
45888
|
-
const socket = connect(
|
|
46145
|
+
const socket = connect(path64);
|
|
45889
46146
|
let buffer = "";
|
|
45890
46147
|
let settled = false;
|
|
45891
46148
|
const settle = (fn) => {
|
|
@@ -45900,7 +46157,7 @@ function requestBrokerAsk(socketPath, ask, opts) {
|
|
|
45900
46157
|
settle(
|
|
45901
46158
|
() => reject(
|
|
45902
46159
|
new Error(
|
|
45903
|
-
`permission broker unavailable at "${
|
|
46160
|
+
`permission broker unavailable at "${path64}" (connect timed out after ${connectTimeoutMs}ms)`
|
|
45904
46161
|
)
|
|
45905
46162
|
)
|
|
45906
46163
|
);
|
|
@@ -46633,9 +46890,9 @@ __export(graphMemory_exports, {
|
|
|
46633
46890
|
toGraphSnapshot: () => toGraphSnapshot
|
|
46634
46891
|
});
|
|
46635
46892
|
import { promises as fs26 } from "node:fs";
|
|
46636
|
-
import
|
|
46893
|
+
import path49 from "node:path";
|
|
46637
46894
|
function snapshotPath(cwd) {
|
|
46638
|
-
return
|
|
46895
|
+
return path49.join(cwd, SNAPSHOT_DIR, SNAPSHOT_FILE);
|
|
46639
46896
|
}
|
|
46640
46897
|
function toGraphSnapshot(graph, opts) {
|
|
46641
46898
|
const unresolved = (opts.unresolvedFindings ?? []).map((u) => ({
|
|
@@ -46662,7 +46919,7 @@ async function saveGraphSnapshot(cwd, snapshot) {
|
|
|
46662
46919
|
try {
|
|
46663
46920
|
await fs26.access(cwd);
|
|
46664
46921
|
const file2 = snapshotPath(cwd);
|
|
46665
|
-
await fs26.mkdir(
|
|
46922
|
+
await fs26.mkdir(path49.dirname(file2), { recursive: true });
|
|
46666
46923
|
await fs26.writeFile(file2, JSON.stringify(snapshot, null, 2) + "\n", "utf8");
|
|
46667
46924
|
} catch {
|
|
46668
46925
|
}
|
|
@@ -46729,7 +46986,7 @@ var SNAPSHOT_DIR, SNAPSHOT_FILE, MAX_SNAPSHOT_FINDINGS_CHARS;
|
|
|
46729
46986
|
var init_graphMemory = __esm({
|
|
46730
46987
|
"src/cli/kraken/graphMemory.ts"() {
|
|
46731
46988
|
"use strict";
|
|
46732
|
-
SNAPSHOT_DIR =
|
|
46989
|
+
SNAPSHOT_DIR = path49.join(".zelari", "kraken");
|
|
46733
46990
|
SNAPSHOT_FILE = "last-graph.json";
|
|
46734
46991
|
MAX_SNAPSHOT_FINDINGS_CHARS = 400;
|
|
46735
46992
|
}
|
|
@@ -46745,14 +47002,14 @@ var init_tentacle = __esm({
|
|
|
46745
47002
|
|
|
46746
47003
|
// src/cli/kraken/workbench.ts
|
|
46747
47004
|
import { promises as fs27 } from "node:fs";
|
|
46748
|
-
import
|
|
47005
|
+
import path50 from "node:path";
|
|
46749
47006
|
function isWorkbenchEnabled(env = process.env) {
|
|
46750
47007
|
const v = (env.ZELARI_KRAKEN_WORKBENCH ?? "1").trim().toLowerCase();
|
|
46751
47008
|
if (v === "0" || v === "false" || v === "no" || v === "off") return false;
|
|
46752
47009
|
return true;
|
|
46753
47010
|
}
|
|
46754
47011
|
function workbenchPath(cwd, graphId) {
|
|
46755
|
-
return
|
|
47012
|
+
return path50.join(cwd, ".zelari", "radio", `workbench-${graphId}.md`);
|
|
46756
47013
|
}
|
|
46757
47014
|
function countByStatus2(nodes) {
|
|
46758
47015
|
const out = { pending: 0, running: 0, done: 0, error: 0, skipped: 0 };
|
|
@@ -46915,7 +47172,7 @@ var init_workbench = __esm({
|
|
|
46915
47172
|
if (!this.enabled) return null;
|
|
46916
47173
|
if (!this.dirty && this.lastWrite) return this.lastWrite;
|
|
46917
47174
|
const out = workbenchPath(this.cwd, this.graphId);
|
|
46918
|
-
await fs27.mkdir(
|
|
47175
|
+
await fs27.mkdir(path50.dirname(out), { recursive: true });
|
|
46919
47176
|
const body = this.render();
|
|
46920
47177
|
const tmp = `${out}.${process.pid}.${Date.now()}.tmp`;
|
|
46921
47178
|
await fs27.writeFile(tmp, body, "utf8");
|
|
@@ -47112,7 +47369,7 @@ __export(executor_exports, {
|
|
|
47112
47369
|
thoroughnessForKind: () => thoroughnessForKind
|
|
47113
47370
|
});
|
|
47114
47371
|
import { existsSync as existsSync40 } from "node:fs";
|
|
47115
|
-
import
|
|
47372
|
+
import path51 from "node:path";
|
|
47116
47373
|
function resolveMaxParallel(env = process.env) {
|
|
47117
47374
|
const raw = env.ZELARI_KRAKEN_MAX_PARALLEL;
|
|
47118
47375
|
if (raw === void 0 || raw === "") return DEFAULT_MAX_PARALLEL;
|
|
@@ -47170,7 +47427,7 @@ function isWorldModelGateEnabled(cwd, env = process.env, checksExists = defaultC
|
|
|
47170
47427
|
}
|
|
47171
47428
|
function defaultChecksExists(cwd) {
|
|
47172
47429
|
try {
|
|
47173
|
-
return existsSync40(
|
|
47430
|
+
return existsSync40(path51.join(cwd, ".zelari", "world", "checks.json"));
|
|
47174
47431
|
} catch {
|
|
47175
47432
|
return false;
|
|
47176
47433
|
}
|
|
@@ -48509,10 +48766,10 @@ var init_prereqChecks = __esm({
|
|
|
48509
48766
|
|
|
48510
48767
|
// src/cli/plugins/prefs.ts
|
|
48511
48768
|
import { existsSync as existsSync42, readFileSync as readFileSync35, writeFileSync as writeFileSync22, mkdirSync as mkdirSync18 } from "node:fs";
|
|
48512
|
-
import
|
|
48769
|
+
import path54 from "node:path";
|
|
48513
48770
|
import os11 from "node:os";
|
|
48514
48771
|
function getPluginPrefsPath() {
|
|
48515
|
-
return process.env.ZELARI_PLUGINS_PREFS_FILE ??
|
|
48772
|
+
return process.env.ZELARI_PLUGINS_PREFS_FILE ?? path54.join(os11.homedir(), ".tmp", "zelari-code", "plugins.json");
|
|
48516
48773
|
}
|
|
48517
48774
|
function getPluginPrefs() {
|
|
48518
48775
|
const file2 = getPluginPrefsPath();
|
|
@@ -48533,7 +48790,7 @@ function getPluginPrefs() {
|
|
|
48533
48790
|
}
|
|
48534
48791
|
function writePluginPrefs(prefs) {
|
|
48535
48792
|
const file2 = getPluginPrefsPath();
|
|
48536
|
-
mkdirSync18(
|
|
48793
|
+
mkdirSync18(path54.dirname(file2), { recursive: true });
|
|
48537
48794
|
writeFileSync22(file2, JSON.stringify(prefs, null, 2), {
|
|
48538
48795
|
encoding: "utf-8",
|
|
48539
48796
|
mode: 384
|
|
@@ -48570,7 +48827,7 @@ __export(registry_exports, {
|
|
|
48570
48827
|
isBinaryOnPath: () => isBinaryOnPath
|
|
48571
48828
|
});
|
|
48572
48829
|
import { existsSync as existsSync43 } from "node:fs";
|
|
48573
|
-
import
|
|
48830
|
+
import path55 from "node:path";
|
|
48574
48831
|
function detectLocalBin(bin) {
|
|
48575
48832
|
return (cwd) => {
|
|
48576
48833
|
try {
|
|
@@ -48588,7 +48845,7 @@ function isBinaryOnPath(bin, opts = {}) {
|
|
|
48588
48845
|
const platform = opts.platform ?? process.platform;
|
|
48589
48846
|
const exists = opts.exists ?? existsSync43;
|
|
48590
48847
|
const pathEnv = opts.pathEnv ?? process.env.PATH ?? "";
|
|
48591
|
-
const pathMod = platform === "win32" ?
|
|
48848
|
+
const pathMod = platform === "win32" ? path55.win32 : path55.posix;
|
|
48592
48849
|
const sep2 = platform === "win32" ? ";" : ":";
|
|
48593
48850
|
const dirs = pathEnv.split(sep2).filter((d) => d.length > 0);
|
|
48594
48851
|
const candidates = [bin];
|
|
@@ -49535,9 +49792,9 @@ __export(triggerLock_exports, {
|
|
|
49535
49792
|
releaseLock: () => releaseLock
|
|
49536
49793
|
});
|
|
49537
49794
|
import { promises as fs35 } from "node:fs";
|
|
49538
|
-
import * as
|
|
49795
|
+
import * as path60 from "node:path";
|
|
49539
49796
|
function lockPath(projectRoot) {
|
|
49540
|
-
return
|
|
49797
|
+
return path60.join(projectRoot, ".zelari", "trigger.lock");
|
|
49541
49798
|
}
|
|
49542
49799
|
function isPidAlive(pid) {
|
|
49543
49800
|
try {
|
|
@@ -49550,7 +49807,7 @@ function isPidAlive(pid) {
|
|
|
49550
49807
|
}
|
|
49551
49808
|
async function acquireLock(projectRoot, now = () => /* @__PURE__ */ new Date()) {
|
|
49552
49809
|
const lp = lockPath(projectRoot);
|
|
49553
|
-
const dir =
|
|
49810
|
+
const dir = path60.dirname(lp);
|
|
49554
49811
|
await fs35.mkdir(dir, { recursive: true });
|
|
49555
49812
|
try {
|
|
49556
49813
|
const raw = await fs35.readFile(lp, "utf8");
|
|
@@ -50144,7 +50401,7 @@ function upsertSkill(opts) {
|
|
|
50144
50401
|
}
|
|
50145
50402
|
dir = getProjectSkillsDir(root);
|
|
50146
50403
|
}
|
|
50147
|
-
const
|
|
50404
|
+
const path64 = skillFilePath(dir, name);
|
|
50148
50405
|
const content = serializeSkillMd({
|
|
50149
50406
|
name,
|
|
50150
50407
|
description,
|
|
@@ -50153,13 +50410,13 @@ function upsertSkill(opts) {
|
|
|
50153
50410
|
tools: opts.tools,
|
|
50154
50411
|
cost: opts.cost
|
|
50155
50412
|
});
|
|
50156
|
-
const parsed = parseSkillMd(content,
|
|
50413
|
+
const parsed = parseSkillMd(content, path64);
|
|
50157
50414
|
if (!parsed) {
|
|
50158
50415
|
return { ok: false, error: "Generated SKILL.md failed validation" };
|
|
50159
50416
|
}
|
|
50160
|
-
mkdirSync21(dirname10(
|
|
50161
|
-
writeFileSync24(
|
|
50162
|
-
return { ok: true, path:
|
|
50417
|
+
mkdirSync21(dirname10(path64), { recursive: true });
|
|
50418
|
+
writeFileSync24(path64, content, "utf8");
|
|
50419
|
+
return { ok: true, path: path64 };
|
|
50163
50420
|
}
|
|
50164
50421
|
function removeSkill(opts) {
|
|
50165
50422
|
const name = opts.name.trim().toLowerCase();
|
|
@@ -50177,8 +50434,8 @@ function removeSkill(opts) {
|
|
|
50177
50434
|
dir = getProjectSkillsDir(root);
|
|
50178
50435
|
}
|
|
50179
50436
|
const skillDir = join37(dir, name);
|
|
50180
|
-
const
|
|
50181
|
-
if (!existsSync48(
|
|
50437
|
+
const path64 = skillFilePath(dir, name);
|
|
50438
|
+
if (!existsSync48(path64) && !existsSync48(skillDir)) {
|
|
50182
50439
|
return { ok: false, error: `Skill "${name}" not found in ${dir}` };
|
|
50183
50440
|
}
|
|
50184
50441
|
try {
|
|
@@ -50189,7 +50446,7 @@ function removeSkill(opts) {
|
|
|
50189
50446
|
error: err instanceof Error ? err.message : String(err)
|
|
50190
50447
|
};
|
|
50191
50448
|
}
|
|
50192
|
-
return { ok: true, path:
|
|
50449
|
+
return { ok: true, path: path64 };
|
|
50193
50450
|
}
|
|
50194
50451
|
var NAME_RE, BUILTIN_SKILL_MODULES, builtinsLoaded;
|
|
50195
50452
|
var init_skillConfigIo = __esm({
|
|
@@ -50507,12 +50764,12 @@ function ensureHome() {
|
|
|
50507
50764
|
}
|
|
50508
50765
|
}
|
|
50509
50766
|
function loadCompanionConfig() {
|
|
50510
|
-
const
|
|
50511
|
-
if (!existsSync49(
|
|
50767
|
+
const path64 = getCompanionConfigPath();
|
|
50768
|
+
if (!existsSync49(path64)) {
|
|
50512
50769
|
return { projects: [] };
|
|
50513
50770
|
}
|
|
50514
50771
|
try {
|
|
50515
|
-
const raw = JSON.parse(readFileSync39(
|
|
50772
|
+
const raw = JSON.parse(readFileSync39(path64, "utf8"));
|
|
50516
50773
|
const projects = Array.isArray(raw.projects) ? raw.projects.filter(
|
|
50517
50774
|
(p3) => p3 && typeof p3.path === "string" && p3.path.trim() && typeof (p3.id ?? p3.name) === "string"
|
|
50518
50775
|
).map((p3) => ({
|
|
@@ -50550,16 +50807,16 @@ function loadOrCreateToken(explicit) {
|
|
|
50550
50807
|
return { token: explicit.trim(), created: false };
|
|
50551
50808
|
}
|
|
50552
50809
|
ensureHome();
|
|
50553
|
-
const
|
|
50554
|
-
if (existsSync49(
|
|
50555
|
-
const t = readFileSync39(
|
|
50810
|
+
const path64 = getCompanionTokenPath();
|
|
50811
|
+
if (existsSync49(path64)) {
|
|
50812
|
+
const t = readFileSync39(path64, "utf8").trim();
|
|
50556
50813
|
if (t) return { token: t, created: false };
|
|
50557
50814
|
}
|
|
50558
50815
|
const token = randomBytes5(24).toString("base64url");
|
|
50559
|
-
writeFileSync25(
|
|
50816
|
+
writeFileSync25(path64, token + "\n", "utf8");
|
|
50560
50817
|
try {
|
|
50561
50818
|
const fs37 = __require("node:fs");
|
|
50562
|
-
fs37.chmodSync?.(
|
|
50819
|
+
fs37.chmodSync?.(path64, 384);
|
|
50563
50820
|
} catch {
|
|
50564
50821
|
}
|
|
50565
50822
|
return { token, created: true };
|
|
@@ -50584,17 +50841,17 @@ function mergeProjects(cfg, extraPaths) {
|
|
|
50584
50841
|
byId.set(p3.id, p3);
|
|
50585
50842
|
}
|
|
50586
50843
|
for (const raw of extraPaths) {
|
|
50587
|
-
const
|
|
50588
|
-
if (!
|
|
50589
|
-
let id = slugFromPath(
|
|
50844
|
+
const path64 = raw.trim();
|
|
50845
|
+
if (!path64) continue;
|
|
50846
|
+
let id = slugFromPath(path64);
|
|
50590
50847
|
let n = 2;
|
|
50591
|
-
while (byId.has(id) && byId.get(id).path !==
|
|
50592
|
-
id = `${slugFromPath(
|
|
50848
|
+
while (byId.has(id) && byId.get(id).path !== path64) {
|
|
50849
|
+
id = `${slugFromPath(path64)}-${n++}`;
|
|
50593
50850
|
}
|
|
50594
50851
|
byId.set(id, {
|
|
50595
50852
|
id,
|
|
50596
|
-
name: slugFromPath(
|
|
50597
|
-
path:
|
|
50853
|
+
name: slugFromPath(path64),
|
|
50854
|
+
path: path64
|
|
50598
50855
|
});
|
|
50599
50856
|
}
|
|
50600
50857
|
return [...byId.values()];
|
|
@@ -50971,9 +51228,9 @@ async function runCompanionServe(opts = {}) {
|
|
|
50971
51228
|
return;
|
|
50972
51229
|
}
|
|
50973
51230
|
const url2 = parseUrl(req);
|
|
50974
|
-
const
|
|
51231
|
+
const path64 = url2.pathname.replace(/\/+$/, "") || "/";
|
|
50975
51232
|
try {
|
|
50976
|
-
if (req.method === "GET" && (
|
|
51233
|
+
if (req.method === "GET" && (path64 === "/health" || path64 === "/v1/health")) {
|
|
50977
51234
|
sendJson2(res, 200, {
|
|
50978
51235
|
ok: true,
|
|
50979
51236
|
service: "zelari-companion",
|
|
@@ -50985,18 +51242,18 @@ async function runCompanionServe(opts = {}) {
|
|
|
50985
51242
|
});
|
|
50986
51243
|
return;
|
|
50987
51244
|
}
|
|
50988
|
-
if (
|
|
51245
|
+
if (path64.startsWith("/v1")) {
|
|
50989
51246
|
if (!tokenMatches(token, getBearer(req))) {
|
|
50990
51247
|
sendJson2(res, 401, { ok: false, error: "unauthorized" });
|
|
50991
51248
|
return;
|
|
50992
51249
|
}
|
|
50993
51250
|
}
|
|
50994
|
-
if (req.method === "GET" &&
|
|
51251
|
+
if (req.method === "GET" && path64 === "/v1/config") {
|
|
50995
51252
|
const snap = buildDesktopConfigSnapshot();
|
|
50996
51253
|
sendJson2(res, 200, { ok: true, ...snap });
|
|
50997
51254
|
return;
|
|
50998
51255
|
}
|
|
50999
|
-
if (req.method === "GET" &&
|
|
51256
|
+
if (req.method === "GET" && path64 === "/v1/projects") {
|
|
51000
51257
|
sendJson2(res, 200, {
|
|
51001
51258
|
ok: true,
|
|
51002
51259
|
projects: projects.map((p3) => ({
|
|
@@ -51007,7 +51264,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
51007
51264
|
});
|
|
51008
51265
|
return;
|
|
51009
51266
|
}
|
|
51010
|
-
if (req.method === "GET" &&
|
|
51267
|
+
if (req.method === "GET" && path64 === "/v1/runs") {
|
|
51011
51268
|
sendJson2(res, 200, {
|
|
51012
51269
|
ok: true,
|
|
51013
51270
|
active: runs.getActive(),
|
|
@@ -51025,7 +51282,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
51025
51282
|
});
|
|
51026
51283
|
return;
|
|
51027
51284
|
}
|
|
51028
|
-
if (req.method === "POST" &&
|
|
51285
|
+
if (req.method === "POST" && path64 === "/v1/runs") {
|
|
51029
51286
|
const raw = await readBody(req);
|
|
51030
51287
|
let body = {};
|
|
51031
51288
|
try {
|
|
@@ -51072,7 +51329,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
51072
51329
|
});
|
|
51073
51330
|
return;
|
|
51074
51331
|
}
|
|
51075
|
-
const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(
|
|
51332
|
+
const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(path64);
|
|
51076
51333
|
if (req.method === "GET" && eventsMatch) {
|
|
51077
51334
|
const runId = eventsMatch[1];
|
|
51078
51335
|
const run = runs.getRun(runId);
|
|
@@ -51137,7 +51394,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
51137
51394
|
}, 500);
|
|
51138
51395
|
return;
|
|
51139
51396
|
}
|
|
51140
|
-
const cancelMatch = /^\/v1\/runs\/([^/]+)\/cancel$/.exec(
|
|
51397
|
+
const cancelMatch = /^\/v1\/runs\/([^/]+)\/cancel$/.exec(path64);
|
|
51141
51398
|
if (req.method === "POST" && cancelMatch) {
|
|
51142
51399
|
const runId = cancelMatch[1];
|
|
51143
51400
|
const result = runs.cancel(runId);
|
|
@@ -51290,11 +51547,11 @@ import { execSync as execSync2 } from "node:child_process";
|
|
|
51290
51547
|
import { existsSync as existsSync51, readFileSync as readFileSync40, readlinkSync, statSync as statSync10 } from "node:fs";
|
|
51291
51548
|
import { createRequire as createRequire3 } from "node:module";
|
|
51292
51549
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
51293
|
-
import
|
|
51550
|
+
import path62 from "node:path";
|
|
51294
51551
|
function findPackageRoot(start) {
|
|
51295
51552
|
let dir = start;
|
|
51296
51553
|
for (let i = 0; i < 6; i += 1) {
|
|
51297
|
-
const candidate =
|
|
51554
|
+
const candidate = path62.join(dir, "package.json");
|
|
51298
51555
|
if (existsSync51(candidate)) {
|
|
51299
51556
|
try {
|
|
51300
51557
|
const pkg = JSON.parse(readFileSync40(candidate, "utf8"));
|
|
@@ -51302,11 +51559,11 @@ function findPackageRoot(start) {
|
|
|
51302
51559
|
} catch {
|
|
51303
51560
|
}
|
|
51304
51561
|
}
|
|
51305
|
-
const parent =
|
|
51562
|
+
const parent = path62.dirname(dir);
|
|
51306
51563
|
if (parent === dir) break;
|
|
51307
51564
|
dir = parent;
|
|
51308
51565
|
}
|
|
51309
|
-
return
|
|
51566
|
+
return path62.resolve(__dirname3, "..", "..", "..");
|
|
51310
51567
|
}
|
|
51311
51568
|
function tryExec(cmd) {
|
|
51312
51569
|
try {
|
|
@@ -51320,7 +51577,7 @@ function tryExec(cmd) {
|
|
|
51320
51577
|
}
|
|
51321
51578
|
function readPackageJson3() {
|
|
51322
51579
|
try {
|
|
51323
|
-
const pkgPath =
|
|
51580
|
+
const pkgPath = path62.join(packageRoot, "package.json");
|
|
51324
51581
|
return JSON.parse(readFileSync40(pkgPath, "utf8"));
|
|
51325
51582
|
} catch {
|
|
51326
51583
|
return null;
|
|
@@ -51336,7 +51593,7 @@ function checkShim(pkgName) {
|
|
|
51336
51593
|
}
|
|
51337
51594
|
const isWin = process.platform === "win32";
|
|
51338
51595
|
const shimName = isWin ? "zelari-code.cmd" : "zelari-code";
|
|
51339
|
-
const shimPath =
|
|
51596
|
+
const shimPath = path62.join(prefix, shimName);
|
|
51340
51597
|
if (!existsSync51(shimPath)) {
|
|
51341
51598
|
return FAIL(
|
|
51342
51599
|
`shim not found at ${shimPath}
|
|
@@ -51364,8 +51621,8 @@ function checkShim(pkgName) {
|
|
|
51364
51621
|
fix: npm install -g ${pkgName}@latest --force`
|
|
51365
51622
|
);
|
|
51366
51623
|
}
|
|
51367
|
-
const resolved =
|
|
51368
|
-
const expected =
|
|
51624
|
+
const resolved = path62.resolve(path62.dirname(shimPath), target);
|
|
51625
|
+
const expected = path62.join(
|
|
51369
51626
|
prefix,
|
|
51370
51627
|
"node_modules",
|
|
51371
51628
|
pkgName,
|
|
@@ -51404,7 +51661,7 @@ function checkNode(pkg) {
|
|
|
51404
51661
|
return OK(`node ${raw}`);
|
|
51405
51662
|
}
|
|
51406
51663
|
function checkBundle() {
|
|
51407
|
-
const bundle =
|
|
51664
|
+
const bundle = path62.join(packageRoot, "dist", "cli", "main.bundled.js");
|
|
51408
51665
|
if (!existsSync51(bundle)) {
|
|
51409
51666
|
return FAIL(
|
|
51410
51667
|
`dist/cli/main.bundled.js missing at ${bundle}
|
|
@@ -51425,7 +51682,7 @@ function checkRuntimeDeps() {
|
|
|
51425
51682
|
const missing = [];
|
|
51426
51683
|
for (const dep of required2) {
|
|
51427
51684
|
try {
|
|
51428
|
-
const localReq = createRequire3(
|
|
51685
|
+
const localReq = createRequire3(path62.join(packageRoot, "package.json"));
|
|
51429
51686
|
localReq.resolve(dep);
|
|
51430
51687
|
} catch {
|
|
51431
51688
|
missing.push(dep);
|
|
@@ -51625,7 +51882,7 @@ var init_doctor = __esm({
|
|
|
51625
51882
|
init_metrics2();
|
|
51626
51883
|
init_contextGrowthSummary();
|
|
51627
51884
|
require3 = createRequire3(import.meta.url);
|
|
51628
|
-
__dirname3 =
|
|
51885
|
+
__dirname3 = path62.dirname(fileURLToPath2(import.meta.url));
|
|
51629
51886
|
packageRoot = findPackageRoot(__dirname3);
|
|
51630
51887
|
OK = (message) => ({
|
|
51631
51888
|
ok: true,
|
|
@@ -51809,15 +52066,15 @@ __export(inspect_exports, {
|
|
|
51809
52066
|
collectInspectReport: () => collectInspectReport,
|
|
51810
52067
|
runInspect: () => runInspect
|
|
51811
52068
|
});
|
|
51812
|
-
import
|
|
52069
|
+
import path63 from "node:path";
|
|
51813
52070
|
import { existsSync as existsSync52, readFileSync as readFileSync41, readdirSync as readdirSync11 } from "node:fs";
|
|
51814
52071
|
import { homedir as homedir14 } from "node:os";
|
|
51815
52072
|
async function collectInspectReport(cwd = process.cwd()) {
|
|
51816
52073
|
ensureBuiltinSkillsLoadedSync();
|
|
51817
52074
|
const snap = listSkillsSnapshot(cwd);
|
|
51818
52075
|
const mcp = listMcpServers(cwd);
|
|
51819
|
-
const userMcpPath =
|
|
51820
|
-
const projectMcpPath =
|
|
52076
|
+
const userMcpPath = path63.join(homedir14(), ".zelari-code", "mcp.json");
|
|
52077
|
+
const projectMcpPath = path63.join(cwd, ".zelari", "mcp.json");
|
|
51821
52078
|
const globalHooks = globalHooksDir();
|
|
51822
52079
|
const projectHooks = projectHooksDir(cwd);
|
|
51823
52080
|
const projectTrusted = isFolderTrusted(cwd);
|
|
@@ -51845,9 +52102,9 @@ async function collectInspectReport(cwd = process.cwd()) {
|
|
|
51845
52102
|
configSources: [
|
|
51846
52103
|
{ path: userMcpPath, exists: existsSync52(userMcpPath) },
|
|
51847
52104
|
{ path: projectMcpPath, exists: existsSync52(projectMcpPath) },
|
|
51848
|
-
{ path:
|
|
51849
|
-
{ path:
|
|
51850
|
-
{ path:
|
|
52105
|
+
{ path: path63.join(homedir14(), ".zelari-code", "provider.json"), exists: existsSync52(path63.join(homedir14(), ".zelari-code", "provider.json")) },
|
|
52106
|
+
{ path: path63.join(cwd, ".zelari", "AGENTS.md"), exists: existsSync52(path63.join(cwd, ".zelari", "AGENTS.md")) },
|
|
52107
|
+
{ path: path63.join(cwd, "AGENTS.md"), exists: existsSync52(path63.join(cwd, "AGENTS.md")) }
|
|
51851
52108
|
],
|
|
51852
52109
|
skills: {
|
|
51853
52110
|
total: snap.skills.length,
|
|
@@ -51887,8 +52144,8 @@ function listJsonFiles(dir) {
|
|
|
51887
52144
|
}
|
|
51888
52145
|
function findAgentsMd(cwd) {
|
|
51889
52146
|
const candidates = [
|
|
51890
|
-
|
|
51891
|
-
|
|
52147
|
+
path63.join(cwd, "AGENTS.md"),
|
|
52148
|
+
path63.join(cwd, ".zelari", "AGENTS.md")
|
|
51892
52149
|
];
|
|
51893
52150
|
const found = [];
|
|
51894
52151
|
for (const c of candidates) {
|
|
@@ -55163,8 +55420,76 @@ init_completionGate();
|
|
|
55163
55420
|
// src/cli/kraken/verificationBridge.ts
|
|
55164
55421
|
init_candidateRegistry();
|
|
55165
55422
|
init_completionGate();
|
|
55423
|
+
|
|
55424
|
+
// src/cli/kraken/nativeVerification.ts
|
|
55425
|
+
init_runtime2();
|
|
55166
55426
|
init_verification2();
|
|
55167
|
-
|
|
55427
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
55428
|
+
import path40 from "node:path";
|
|
55429
|
+
function nativePackEnabled(env = process.env) {
|
|
55430
|
+
const v = env.ZELARI_VERIFY_PACK?.toLowerCase();
|
|
55431
|
+
return v === "1" || v === "on" || v === "true";
|
|
55432
|
+
}
|
|
55433
|
+
function resolvePackCommands(env, scripts) {
|
|
55434
|
+
const pick2 = (override, scriptName) => {
|
|
55435
|
+
if (override !== void 0) {
|
|
55436
|
+
const trimmed = override.trim();
|
|
55437
|
+
return trimmed === "" ? null : trimmed;
|
|
55438
|
+
}
|
|
55439
|
+
const script = scripts[scriptName];
|
|
55440
|
+
return typeof script === "string" && script.length > 0 ? `npm run ${scriptName}` : null;
|
|
55441
|
+
};
|
|
55442
|
+
return {
|
|
55443
|
+
typecheckCommand: pick2(env.ZELARI_VERIFY_TYPECHECK_CMD, "typecheck"),
|
|
55444
|
+
testCommand: pick2(env.ZELARI_VERIFY_TEST_CMD, "test"),
|
|
55445
|
+
buildCommand: pick2(env.ZELARI_VERIFY_BUILD_CMD, "build")
|
|
55446
|
+
};
|
|
55447
|
+
}
|
|
55448
|
+
function packTimeoutMs(env = process.env) {
|
|
55449
|
+
const raw = Number(env.ZELARI_VERIFY_TIMEOUT_MS);
|
|
55450
|
+
if (!Number.isFinite(raw) || raw <= 0) return 6e5;
|
|
55451
|
+
return Math.min(Math.floor(raw), 36e5);
|
|
55452
|
+
}
|
|
55453
|
+
async function readPackageScripts(cwd = process.cwd()) {
|
|
55454
|
+
try {
|
|
55455
|
+
const raw = await readFile2(path40.join(cwd, "package.json"), "utf-8");
|
|
55456
|
+
const parsed = JSON.parse(raw);
|
|
55457
|
+
if (parsed && typeof parsed === "object" && typeof parsed.scripts === "object") {
|
|
55458
|
+
return parsed.scripts;
|
|
55459
|
+
}
|
|
55460
|
+
return {};
|
|
55461
|
+
} catch {
|
|
55462
|
+
return {};
|
|
55463
|
+
}
|
|
55464
|
+
}
|
|
55465
|
+
function buildNativeCriteria(commands, timeoutMs) {
|
|
55466
|
+
const pack = codingCriteriaPack({ ...commands, commandTimeoutMs: timeoutMs });
|
|
55467
|
+
return pack.criteria.filter(
|
|
55468
|
+
(c) => !(c.required && (!c.check || c.check.kind === "none"))
|
|
55469
|
+
);
|
|
55470
|
+
}
|
|
55471
|
+
async function evaluateNativePack(deps = {}) {
|
|
55472
|
+
const env = deps.env ?? process.env;
|
|
55473
|
+
if (!nativePackEnabled(env)) return null;
|
|
55474
|
+
const cwd = deps.cwd ?? process.cwd();
|
|
55475
|
+
const commands = resolvePackCommands(env, await readPackageScripts(cwd));
|
|
55476
|
+
if (!commands.typecheckCommand && !commands.testCommand && !commands.buildCommand) return null;
|
|
55477
|
+
const criteria = buildNativeCriteria(commands, packTimeoutMs(env));
|
|
55478
|
+
if (criteria.length === 0) return null;
|
|
55479
|
+
const shell = deps.shell ?? new NodeShellProvider(new LocalWorkspace(cwd));
|
|
55480
|
+
const engine = deps.emit ? new VerificationEngine({ shell }, { emit: deps.emit }) : new VerificationEngine({ shell });
|
|
55481
|
+
const results = await engine.evaluate(criteria, { packId: ZELARI_CODING_PACK_ID });
|
|
55482
|
+
return { packId: ZELARI_CODING_PACK_ID, criteria, results };
|
|
55483
|
+
}
|
|
55484
|
+
|
|
55485
|
+
// src/cli/kraken/verificationBridge.ts
|
|
55486
|
+
init_verification2();
|
|
55487
|
+
function strictDoneEnabled(surface = "kraken") {
|
|
55488
|
+
if (surface === "mission") {
|
|
55489
|
+
const v2 = process.env.ZELARI_MISSION_STRICT;
|
|
55490
|
+
if (v2 === "0" || v2 === "false") return false;
|
|
55491
|
+
return true;
|
|
55492
|
+
}
|
|
55168
55493
|
const v = process.env.ZELARI_STRICT_DONE;
|
|
55169
55494
|
return v === "1" || v === "true";
|
|
55170
55495
|
}
|
|
@@ -55220,27 +55545,62 @@ function krakenResultsToContract(requiredChecks, results, now = Date.now()) {
|
|
|
55220
55545
|
});
|
|
55221
55546
|
return { criteria, results: verifications };
|
|
55222
55547
|
}
|
|
55223
|
-
function
|
|
55548
|
+
async function anchorSelectionEvidence(results, emit) {
|
|
55549
|
+
if (!emit) return;
|
|
55550
|
+
for (const r of results) {
|
|
55551
|
+
for (const ev of r.evidence) {
|
|
55552
|
+
if (ev.seq !== void 0) continue;
|
|
55553
|
+
if (ev.tier === "verifier-llm" || ev.tier === "human") continue;
|
|
55554
|
+
try {
|
|
55555
|
+
const appended = await emit({
|
|
55556
|
+
kind: "verification.evidence",
|
|
55557
|
+
actor: { type: "system", role: "verification" },
|
|
55558
|
+
data: {
|
|
55559
|
+
observation: "verify-report-note",
|
|
55560
|
+
criterionId: r.criterionId,
|
|
55561
|
+
ref: ev.ref,
|
|
55562
|
+
tier: ev.tier
|
|
55563
|
+
}
|
|
55564
|
+
});
|
|
55565
|
+
const seq = appended && typeof appended === "object" && "seq" in appended ? Number(appended.seq) : NaN;
|
|
55566
|
+
if (Number.isFinite(seq) && seq > 0) ev.seq = seq;
|
|
55567
|
+
} catch {
|
|
55568
|
+
}
|
|
55569
|
+
}
|
|
55570
|
+
}
|
|
55571
|
+
}
|
|
55572
|
+
async function evaluateStrictBuildGate(mode, options = {}) {
|
|
55224
55573
|
const gate = evaluateKrakenCompletionGate(mode);
|
|
55225
|
-
if (!gate.selectionUsed || gate.total === 0 || !strictDoneEnabled()) {
|
|
55574
|
+
if (!gate.selectionUsed || gate.total === 0 || !strictDoneEnabled(options.surface ?? "kraken")) {
|
|
55226
55575
|
return {
|
|
55227
55576
|
gate,
|
|
55228
55577
|
strict: false,
|
|
55229
55578
|
evaluation: null,
|
|
55579
|
+
native: null,
|
|
55230
55580
|
blocked: gate.blocked,
|
|
55231
55581
|
summary: gate.blocked ? `blocked: ${gate.failedChecks.length} failed, ${gate.unknownChecks.length} unknown` : "open"
|
|
55232
55582
|
};
|
|
55233
55583
|
}
|
|
55234
55584
|
const checks = krakenRequiredChecks();
|
|
55235
55585
|
const contract = krakenResultsToContract(checks, getKrakenCheckResults());
|
|
55236
|
-
|
|
55586
|
+
await anchorSelectionEvidence(contract.results, options.emit);
|
|
55587
|
+
const native = await evaluateNativePack({
|
|
55588
|
+
cwd: options.cwd,
|
|
55589
|
+
env: options.env,
|
|
55590
|
+
shell: options.shell,
|
|
55591
|
+
emit: options.emit
|
|
55592
|
+
}).catch(() => null);
|
|
55593
|
+
const allCriteria = [...contract.criteria, ...native?.criteria ?? []];
|
|
55594
|
+
const allResults = [...contract.results, ...native?.results ?? []];
|
|
55595
|
+
const evaluation = evaluateCompletion(allCriteria, allResults, STRICT_BUILD_POLICY);
|
|
55237
55596
|
const blocked = gate.blocked || evaluation.verdict !== "PASS";
|
|
55238
55597
|
return {
|
|
55239
55598
|
gate,
|
|
55240
55599
|
strict: true,
|
|
55241
55600
|
evaluation,
|
|
55601
|
+
native,
|
|
55242
55602
|
blocked,
|
|
55243
|
-
summary: blocked ? `blocked (strict ${evaluation?.verdict ?? "n/a"}): ${gate.passed}/${gate.total} legacy-pass, evidence ${evaluation?.evidenceComplete ? "complete" : "incomplete"}` : `open (strict PASS): ${evaluation?.satisfied.length ?? 0}/${
|
|
55603
|
+
summary: blocked ? `blocked (strict ${evaluation?.verdict ?? "n/a"}): ${gate.passed}/${gate.total} legacy-pass, evidence ${evaluation?.evidenceComplete ? "complete" : "incomplete"}` : `open (strict PASS): ${evaluation?.satisfied.length ?? 0}/${allCriteria.length} criteria pass with evidence`
|
|
55244
55604
|
};
|
|
55245
55605
|
}
|
|
55246
55606
|
var STRICT_DONE_EXIT_CODE = 4;
|
|
@@ -55249,7 +55609,7 @@ function strictGateExitCode(evaluation) {
|
|
|
55249
55609
|
}
|
|
55250
55610
|
function strictGateEventPayload(evaluation) {
|
|
55251
55611
|
return {
|
|
55252
|
-
engine: "kraken-legacy+completion-policy",
|
|
55612
|
+
engine: evaluation.native ? "kraken-legacy+completion-policy+criteria-pack" : "kraken-legacy+completion-policy",
|
|
55253
55613
|
strict: evaluation.strict,
|
|
55254
55614
|
verdict: evaluation.evaluation?.verdict ?? (evaluation.blocked ? "BLOCKED" : "PASS"),
|
|
55255
55615
|
legacy: {
|
|
@@ -55263,6 +55623,17 @@ function strictGateEventPayload(evaluation) {
|
|
|
55263
55623
|
unsatisfied: evaluation.evaluation.unsatisfied,
|
|
55264
55624
|
complete: evaluation.evaluation.evidenceComplete
|
|
55265
55625
|
} : null,
|
|
55626
|
+
// F2: deterministic pack results — real command evidence, replayable.
|
|
55627
|
+
native: evaluation.native ? {
|
|
55628
|
+
packId: evaluation.native.packId,
|
|
55629
|
+
criteria: evaluation.native.criteria.map((c) => ({ id: c.id, required: c.required })),
|
|
55630
|
+
results: evaluation.native.results.map((r) => ({
|
|
55631
|
+
criterionId: r.criterionId,
|
|
55632
|
+
status: r.status,
|
|
55633
|
+
evidence: r.evidence.map((e) => ({ tier: e.tier, ref: e.ref, digest: e.digest, ...e.seq !== void 0 ? { seq: e.seq } : {} })),
|
|
55634
|
+
detail: r.detail
|
|
55635
|
+
}))
|
|
55636
|
+
} : null,
|
|
55266
55637
|
summary: evaluation.summary
|
|
55267
55638
|
};
|
|
55268
55639
|
}
|
|
@@ -56017,8 +56388,9 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il turno continua dopo
|
|
|
56017
56388
|
progressRuntime.observe(event);
|
|
56018
56389
|
if (event.type === "agent_end") {
|
|
56019
56390
|
let krakenSuppressFinish = false;
|
|
56391
|
+
const krakenSpineEmit = (input) => writerRef.current?.spine?.appendEvent(input) ?? Promise.resolve(null);
|
|
56020
56392
|
if (event.reason === "completed" && !krakenRepairEnqueued && isKrakenSelectionEnabled() && workPhase === "build") {
|
|
56021
|
-
const strictGate = evaluateStrictBuildGate("build");
|
|
56393
|
+
const strictGate = await evaluateStrictBuildGate("build", { emit: krakenSpineEmit });
|
|
56022
56394
|
const krakenGate = strictGate.gate;
|
|
56023
56395
|
writerRef.current?.spine?.verificationRun(strictGateEventPayload(strictGate));
|
|
56024
56396
|
if (krakenGate.blocked) {
|
|
@@ -56034,10 +56406,10 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il turno continua dopo
|
|
|
56034
56406
|
krakenSuppressFinish = true;
|
|
56035
56407
|
}
|
|
56036
56408
|
}
|
|
56037
|
-
if (event.reason === "completed" && krakenRepairEnqueued && !evaluateStrictBuildGate("build").blocked) {
|
|
56409
|
+
if (event.reason === "completed" && krakenRepairEnqueued && !(await evaluateStrictBuildGate("build", { emit: krakenSpineEmit })).blocked) {
|
|
56038
56410
|
markRepairSucceeded();
|
|
56039
56411
|
} else if (event.reason === "completed" && krakenRepairEnqueued) {
|
|
56040
|
-
const still = evaluateStrictBuildGate("build");
|
|
56412
|
+
const still = await evaluateStrictBuildGate("build", { emit: krakenSpineEmit });
|
|
56041
56413
|
if (still.blocked) {
|
|
56042
56414
|
appendSystem(
|
|
56043
56415
|
setMessages,
|
|
@@ -58064,7 +58436,7 @@ init_sessionManager();
|
|
|
58064
58436
|
// src/cli/gitOps.ts
|
|
58065
58437
|
import { execFile as execFile4 } from "node:child_process";
|
|
58066
58438
|
import { promisify as promisify3 } from "node:util";
|
|
58067
|
-
import
|
|
58439
|
+
import path48 from "node:path";
|
|
58068
58440
|
var execFileAsync3 = promisify3(execFile4);
|
|
58069
58441
|
async function git4(cwd, args) {
|
|
58070
58442
|
try {
|
|
@@ -58110,7 +58482,7 @@ async function undoWorkingChanges(opts = {}) {
|
|
|
58110
58482
|
};
|
|
58111
58483
|
}
|
|
58112
58484
|
function defaultProjectRoot() {
|
|
58113
|
-
return
|
|
58485
|
+
return path48.resolve(__dirname, "..", "..", "..");
|
|
58114
58486
|
}
|
|
58115
58487
|
|
|
58116
58488
|
// src/cli/slashHandlers/git.ts
|
|
@@ -58562,7 +58934,7 @@ import { promises as fs29 } from "node:fs";
|
|
|
58562
58934
|
init_zod();
|
|
58563
58935
|
init_taskTool();
|
|
58564
58936
|
import { promises as fs28 } from "node:fs";
|
|
58565
|
-
import
|
|
58937
|
+
import path52 from "node:path";
|
|
58566
58938
|
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
58567
58939
|
var CsvFanoutArgsSchema = external_exports.object({
|
|
58568
58940
|
csv_path: external_exports.string().min(1),
|
|
@@ -58656,8 +59028,8 @@ function resolveMaxConcurrency(env = process.env) {
|
|
|
58656
59028
|
}
|
|
58657
59029
|
async function runCsvFanout(args, deps, opts) {
|
|
58658
59030
|
const start = Date.now();
|
|
58659
|
-
const absCsv =
|
|
58660
|
-
const absOut =
|
|
59031
|
+
const absCsv = path52.isAbsolute(args.csv_path) ? args.csv_path : path52.join(opts.parentCwd, args.csv_path);
|
|
59032
|
+
const absOut = path52.isAbsolute(args.output_csv_path) ? args.output_csv_path : path52.join(opts.parentCwd, args.output_csv_path);
|
|
58661
59033
|
const { headers: headers2, rows } = await readCsv(absCsv);
|
|
58662
59034
|
if (headers2.length === 0) {
|
|
58663
59035
|
throw new Error(`kraken_csv_fanout: ${absCsv} is empty`);
|
|
@@ -58713,7 +59085,7 @@ async function runCsvFanout(args, deps, opts) {
|
|
|
58713
59085
|
errored += 1;
|
|
58714
59086
|
errors.push(`${row[args.id_column] ?? i}: ${res.error}`);
|
|
58715
59087
|
}
|
|
58716
|
-
await fs28.mkdir(
|
|
59088
|
+
await fs28.mkdir(path52.dirname(absOut), { recursive: true });
|
|
58717
59089
|
await queueWrite(serializeCsv(outHeaders, outputRecords));
|
|
58718
59090
|
}
|
|
58719
59091
|
}
|
|
@@ -58908,7 +59280,7 @@ function splitArgs(s) {
|
|
|
58908
59280
|
// src/cli/slashHandlers/krakenWorkbench.ts
|
|
58909
59281
|
init_messageHelpers();
|
|
58910
59282
|
import { promises as fs30 } from "node:fs";
|
|
58911
|
-
import
|
|
59283
|
+
import path53 from "node:path";
|
|
58912
59284
|
|
|
58913
59285
|
// src/cli/kraken/workbenchView.ts
|
|
58914
59286
|
var EMPTY = {
|
|
@@ -59025,14 +59397,14 @@ function formatWorkbenchForTerminal(p3) {
|
|
|
59025
59397
|
|
|
59026
59398
|
// src/cli/slashHandlers/krakenWorkbench.ts
|
|
59027
59399
|
async function handleKrakenWorkbench(ctx) {
|
|
59028
|
-
const dir =
|
|
59400
|
+
const dir = path53.join(ctx.cwd, ".zelari", "radio");
|
|
59029
59401
|
let latest = null;
|
|
59030
59402
|
let latestMtime = 0;
|
|
59031
59403
|
try {
|
|
59032
59404
|
const files = await fs30.readdir(dir);
|
|
59033
59405
|
for (const f of files) {
|
|
59034
59406
|
if (!f.startsWith("workbench-") || !f.endsWith(".md")) continue;
|
|
59035
|
-
const full =
|
|
59407
|
+
const full = path53.join(dir, f);
|
|
59036
59408
|
const stat = await fs30.stat(full);
|
|
59037
59409
|
if (stat.mtimeMs > latestMtime) {
|
|
59038
59410
|
latestMtime = stat.mtimeMs;
|
|
@@ -59049,10 +59421,10 @@ async function handleKrakenWorkbench(ctx) {
|
|
|
59049
59421
|
const parsed = parseWorkbench(content);
|
|
59050
59422
|
const rendered = formatWorkbenchForTerminal(parsed);
|
|
59051
59423
|
if (!rendered.trim()) {
|
|
59052
|
-
appendSystem(ctx.setMessages, `[kraken workbench] ${
|
|
59424
|
+
appendSystem(ctx.setMessages, `[kraken workbench] ${path53.basename(latest)}: (no nodes / no events yet)`);
|
|
59053
59425
|
return;
|
|
59054
59426
|
}
|
|
59055
|
-
appendSystem(ctx.setMessages, `[kraken workbench] ${
|
|
59427
|
+
appendSystem(ctx.setMessages, `[kraken workbench] ${path53.basename(latest)}:
|
|
59056
59428
|
${rendered}`);
|
|
59057
59429
|
}
|
|
59058
59430
|
|
|
@@ -59359,15 +59731,15 @@ ${result.output.split("\n").slice(-8).join("\n")}` : "";
|
|
|
59359
59731
|
// src/cli/slashHandlers/promoteMember.ts
|
|
59360
59732
|
init_messageHelpers();
|
|
59361
59733
|
import { promises as fs31 } from "node:fs";
|
|
59362
|
-
import
|
|
59734
|
+
import path56 from "node:path";
|
|
59363
59735
|
import os12 from "node:os";
|
|
59364
59736
|
async function handlePromoteMember(ctx, memberId) {
|
|
59365
59737
|
try {
|
|
59366
59738
|
const { promoteMember: promoteMember2 } = await Promise.resolve().then(() => (init_council(), council_exports));
|
|
59367
59739
|
const { skill, markdown } = promoteMember2(memberId);
|
|
59368
|
-
const skillDir = process.env.ANATHEMA_SKILL_DIR ??
|
|
59740
|
+
const skillDir = process.env.ANATHEMA_SKILL_DIR ?? path56.join(os12.homedir(), ".tmp", "zelari-code", "skills");
|
|
59369
59741
|
await fs31.mkdir(skillDir, { recursive: true });
|
|
59370
|
-
const filePath =
|
|
59742
|
+
const filePath = path56.join(skillDir, `${skill.id}.md`);
|
|
59371
59743
|
await fs31.writeFile(filePath, markdown, "utf8");
|
|
59372
59744
|
appendSystem(
|
|
59373
59745
|
ctx.setMessages,
|
|
@@ -59385,24 +59757,24 @@ async function handlePromoteMember(ctx, memberId) {
|
|
|
59385
59757
|
|
|
59386
59758
|
// src/cli/branchManager.ts
|
|
59387
59759
|
import { promises as fs32, existsSync as existsSync44, readFileSync as readFileSync36, writeFileSync as writeFileSync23, mkdirSync as mkdirSync19, statSync as statSync7, rmSync as rmSync3 } from "node:fs";
|
|
59388
|
-
import
|
|
59760
|
+
import path57 from "node:path";
|
|
59389
59761
|
import os13 from "node:os";
|
|
59390
59762
|
var META_FILENAME = "meta.json";
|
|
59391
59763
|
var SESSIONS_SUBDIR = "sessions";
|
|
59392
59764
|
function getBranchesBaseDir() {
|
|
59393
|
-
return process.env.ANATHEMA_BRANCHES_DIR ??
|
|
59765
|
+
return process.env.ANATHEMA_BRANCHES_DIR ?? path57.join(os13.homedir(), ".tmp", "zelari-code", "branches");
|
|
59394
59766
|
}
|
|
59395
59767
|
function getSessionsBaseDir() {
|
|
59396
|
-
return process.env.ANATHEMA_SESSIONS_DIR ??
|
|
59768
|
+
return process.env.ANATHEMA_SESSIONS_DIR ?? path57.join(os13.homedir(), ".tmp", "zelari-code", "sessions");
|
|
59397
59769
|
}
|
|
59398
59770
|
function branchPathFor(name, baseDir) {
|
|
59399
|
-
return
|
|
59771
|
+
return path57.join(baseDir, name);
|
|
59400
59772
|
}
|
|
59401
59773
|
function metaPathFor(name, baseDir) {
|
|
59402
|
-
return
|
|
59774
|
+
return path57.join(baseDir, name, META_FILENAME);
|
|
59403
59775
|
}
|
|
59404
59776
|
function sessionsPathFor(name, baseDir) {
|
|
59405
|
-
return
|
|
59777
|
+
return path57.join(baseDir, name, SESSIONS_SUBDIR);
|
|
59406
59778
|
}
|
|
59407
59779
|
function readBranchMeta(name, baseDir) {
|
|
59408
59780
|
const metaPath = metaPathFor(name, baseDir);
|
|
@@ -59427,7 +59799,7 @@ function readBranchMeta(name, baseDir) {
|
|
|
59427
59799
|
}
|
|
59428
59800
|
function writeBranchMeta(name, baseDir, meta3) {
|
|
59429
59801
|
const metaPath = metaPathFor(name, baseDir);
|
|
59430
|
-
mkdirSync19(
|
|
59802
|
+
mkdirSync19(path57.dirname(metaPath), { recursive: true });
|
|
59431
59803
|
writeFileSync23(metaPath, JSON.stringify(meta3, null, 2), "utf-8");
|
|
59432
59804
|
}
|
|
59433
59805
|
async function countSessions(name, baseDir) {
|
|
@@ -59478,14 +59850,14 @@ async function createBranch(name, fromSessionId, baseDir = getBranchesBaseDir(),
|
|
|
59478
59850
|
if (branchExists(name, baseDir)) {
|
|
59479
59851
|
throw new BranchAlreadyExistsError(name);
|
|
59480
59852
|
}
|
|
59481
|
-
const sourcePath =
|
|
59853
|
+
const sourcePath = path57.join(sessionsBaseDir, `${fromSessionId}.jsonl`);
|
|
59482
59854
|
if (!existsSync44(sourcePath)) {
|
|
59483
59855
|
throw new SessionNotFoundError(`Source session "${fromSessionId}" not found at ${sourcePath}`);
|
|
59484
59856
|
}
|
|
59485
59857
|
const branchPath = branchPathFor(name, baseDir);
|
|
59486
59858
|
const branchSessionsPath = sessionsPathFor(name, baseDir);
|
|
59487
59859
|
mkdirSync19(branchSessionsPath, { recursive: true });
|
|
59488
|
-
const destPath =
|
|
59860
|
+
const destPath = path57.join(branchSessionsPath, `${fromSessionId}.jsonl`);
|
|
59489
59861
|
await fs32.copyFile(sourcePath, destPath);
|
|
59490
59862
|
const meta3 = {
|
|
59491
59863
|
name,
|
|
@@ -59589,14 +59961,14 @@ async function handleBranchCheckout(ctx, branchName) {
|
|
|
59589
59961
|
// src/cli/slashHandlers/workspace.ts
|
|
59590
59962
|
init_messageHelpers();
|
|
59591
59963
|
import { promises as fs33 } from "node:fs";
|
|
59592
|
-
import
|
|
59964
|
+
import path58 from "node:path";
|
|
59593
59965
|
async function handleWorkspaceShow(ctx, what) {
|
|
59594
59966
|
try {
|
|
59595
|
-
const zelari =
|
|
59967
|
+
const zelari = path58.join(process.cwd(), ".zelari");
|
|
59596
59968
|
let content;
|
|
59597
59969
|
switch (what) {
|
|
59598
59970
|
case "plan": {
|
|
59599
|
-
const planPath =
|
|
59971
|
+
const planPath = path58.join(zelari, "plan.md");
|
|
59600
59972
|
try {
|
|
59601
59973
|
content = await fs33.readFile(planPath, "utf-8");
|
|
59602
59974
|
} catch {
|
|
@@ -59605,7 +59977,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
59605
59977
|
break;
|
|
59606
59978
|
}
|
|
59607
59979
|
case "decisions": {
|
|
59608
|
-
const decisionsDir =
|
|
59980
|
+
const decisionsDir = path58.join(zelari, "decisions");
|
|
59609
59981
|
try {
|
|
59610
59982
|
const files = (await fs33.readdir(decisionsDir)).filter((f) => f.endsWith(".md")).sort();
|
|
59611
59983
|
if (files.length === 0) {
|
|
@@ -59615,7 +59987,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
59615
59987
|
`];
|
|
59616
59988
|
const { parseFrontmatter: parseFrontmatter2 } = await Promise.resolve().then(() => (init_storage(), storage_exports));
|
|
59617
59989
|
for (const f of files) {
|
|
59618
|
-
const raw = await fs33.readFile(
|
|
59990
|
+
const raw = await fs33.readFile(path58.join(decisionsDir, f), "utf-8");
|
|
59619
59991
|
const { meta: meta3, body } = parseFrontmatter2(raw);
|
|
59620
59992
|
const title = meta3.title ?? body.split("\n")[0]?.replace(/^#\s*/, "").trim() ?? f;
|
|
59621
59993
|
lines.push(`- **${f.replace(/\.md$/, "")}** [${meta3.status ?? "unknown"}] ${title}`);
|
|
@@ -59628,7 +60000,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
59628
60000
|
break;
|
|
59629
60001
|
}
|
|
59630
60002
|
case "risks": {
|
|
59631
|
-
const risksPath =
|
|
60003
|
+
const risksPath = path58.join(zelari, "risks.md");
|
|
59632
60004
|
try {
|
|
59633
60005
|
content = await fs33.readFile(risksPath, "utf-8");
|
|
59634
60006
|
} catch {
|
|
@@ -59637,7 +60009,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
59637
60009
|
break;
|
|
59638
60010
|
}
|
|
59639
60011
|
case "agents": {
|
|
59640
|
-
const agentsPath =
|
|
60012
|
+
const agentsPath = path58.join(process.cwd(), "AGENTS.MD");
|
|
59641
60013
|
try {
|
|
59642
60014
|
content = await fs33.readFile(agentsPath, "utf-8");
|
|
59643
60015
|
} catch {
|
|
@@ -59646,7 +60018,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
59646
60018
|
break;
|
|
59647
60019
|
}
|
|
59648
60020
|
case "docs": {
|
|
59649
|
-
const docsDir =
|
|
60021
|
+
const docsDir = path58.join(zelari, "docs");
|
|
59650
60022
|
try {
|
|
59651
60023
|
const files = (await fs33.readdir(docsDir)).filter((f) => f.endsWith(".md")).sort();
|
|
59652
60024
|
content = files.length ? `# Docs (${files.length})
|
|
@@ -59688,7 +60060,7 @@ async function handleWorkspaceReset(ctx, force) {
|
|
|
59688
60060
|
return;
|
|
59689
60061
|
}
|
|
59690
60062
|
try {
|
|
59691
|
-
const target =
|
|
60063
|
+
const target = path58.join(process.cwd(), ".zelari");
|
|
59692
60064
|
await fs33.rm(target, { recursive: true, force: true });
|
|
59693
60065
|
appendSystem(ctx.setMessages, "[workspace] .zelari/ removed");
|
|
59694
60066
|
} catch (err) {
|
|
@@ -59700,7 +60072,7 @@ async function handleWorkspaceReset(ctx, force) {
|
|
|
59700
60072
|
init_provider2();
|
|
59701
60073
|
|
|
59702
60074
|
// src/cli/slashHandlers/skills.ts
|
|
59703
|
-
import
|
|
60075
|
+
import path59 from "node:path";
|
|
59704
60076
|
import os14 from "node:os";
|
|
59705
60077
|
|
|
59706
60078
|
// src/cli/skillHistory.ts
|
|
@@ -59829,7 +60201,7 @@ function handleSkillPicker(ctx, skills, openPicker, fallbackMessage) {
|
|
|
59829
60201
|
});
|
|
59830
60202
|
}
|
|
59831
60203
|
async function handleSkillStats(ctx, skillId) {
|
|
59832
|
-
const historyFile = process.env.ANATHEMA_SKILL_HISTORY_FILE ??
|
|
60204
|
+
const historyFile = process.env.ANATHEMA_SKILL_HISTORY_FILE ?? path59.join(os14.homedir(), ".tmp", "zelari-code", "skill-history.jsonl");
|
|
59833
60205
|
try {
|
|
59834
60206
|
const records = await readSkillHistory(historyFile);
|
|
59835
60207
|
const stats = getSkillStats(records, skillId);
|
|
@@ -59845,7 +60217,7 @@ async function handleSkillCompare(ctx, ids, fallbackMessage) {
|
|
|
59845
60217
|
appendSystem(ctx.setMessages, fallbackMessage ?? "[skill-compare] missing args");
|
|
59846
60218
|
return;
|
|
59847
60219
|
}
|
|
59848
|
-
const historyFile = process.env.ANATHEMA_SKILL_HISTORY_FILE ??
|
|
60220
|
+
const historyFile = process.env.ANATHEMA_SKILL_HISTORY_FILE ?? path59.join(os14.homedir(), ".tmp", "zelari-code", "skill-history.jsonl");
|
|
59849
60221
|
try {
|
|
59850
60222
|
const formatted = await compareSkillsFromFile(ids[0], ids[1], historyFile);
|
|
59851
60223
|
appendSystem(ctx.setMessages, formatted);
|
|
@@ -61389,7 +61761,7 @@ function createStreamScrubber2() {
|
|
|
61389
61761
|
init_taskTool();
|
|
61390
61762
|
init_sessionTodos();
|
|
61391
61763
|
import { promises as fs36 } from "node:fs";
|
|
61392
|
-
import
|
|
61764
|
+
import path61 from "node:path";
|
|
61393
61765
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
61394
61766
|
init_headlessSpine();
|
|
61395
61767
|
async function runHeadless(opts) {
|
|
@@ -61546,7 +61918,7 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
61546
61918
|
try {
|
|
61547
61919
|
let preflightGraph;
|
|
61548
61920
|
if (opts.runPlan && opts.runPlan.trim() !== "") {
|
|
61549
|
-
const planPath =
|
|
61921
|
+
const planPath = path61.join(cwd, ".zelari", "radio", `plan-${opts.runPlan}.json`);
|
|
61550
61922
|
log(`loading pre-flight plan: ${planPath}`);
|
|
61551
61923
|
let raw;
|
|
61552
61924
|
try {
|
|
@@ -61586,8 +61958,8 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
61586
61958
|
log(formatKrakenGraphAscii2(graph));
|
|
61587
61959
|
if (opts.planOnly) {
|
|
61588
61960
|
const planId = randomUUID6();
|
|
61589
|
-
const planDir =
|
|
61590
|
-
const planPath =
|
|
61961
|
+
const planDir = path61.join(cwd, ".zelari", "radio");
|
|
61962
|
+
const planPath = path61.join(planDir, `plan-${planId}.json`);
|
|
61591
61963
|
await fs36.mkdir(planDir, { recursive: true });
|
|
61592
61964
|
await fs36.writeFile(
|
|
61593
61965
|
planPath,
|
|
@@ -62035,7 +62407,7 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
62035
62407
|
}
|
|
62036
62408
|
let strictExit = 0;
|
|
62037
62409
|
if (pass.finalReason === "completed" && pass.exitCode === 0 && opts.mode === "kraken" && isKrakenSelectionEnabled() && !planModeFromOpts(opts)) {
|
|
62038
|
-
const strictGate = evaluateStrictBuildGate("build");
|
|
62410
|
+
const strictGate = await evaluateStrictBuildGate("build", { emit: (input) => spine.appendEvent(input) });
|
|
62039
62411
|
const gate = strictGate.gate;
|
|
62040
62412
|
const verificationPayload = strictGateEventPayload(strictGate);
|
|
62041
62413
|
spine.verificationRun(verificationPayload);
|
|
@@ -62068,7 +62440,7 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
62068
62440
|
successfulWrites: pass.successfulWrites + repair.successfulWrites,
|
|
62069
62441
|
emittedWrites: pass.emittedWrites + repair.emittedWrites
|
|
62070
62442
|
};
|
|
62071
|
-
const after = evaluateStrictBuildGate("build");
|
|
62443
|
+
const after = await evaluateStrictBuildGate("build", { emit: (input) => spine.appendEvent(input) });
|
|
62072
62444
|
const afterPayload = strictGateEventPayload(after);
|
|
62073
62445
|
spine.verificationRun(afterPayload);
|
|
62074
62446
|
if (opts.output === "json") {
|
|
@@ -62140,7 +62512,7 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
62140
62512
|
if (json2) {
|
|
62141
62513
|
if (opts.exportSessionPath === "-") process.stdout.write(json2 + "\n");
|
|
62142
62514
|
else {
|
|
62143
|
-
await fs36.mkdir(
|
|
62515
|
+
await fs36.mkdir(path61.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
62144
62516
|
await fs36.writeFile(opts.exportSessionPath, json2, "utf8");
|
|
62145
62517
|
}
|
|
62146
62518
|
}
|
|
@@ -62307,7 +62679,7 @@ async function runHeadlessCouncil(opts, provider, model, providerStream) {
|
|
|
62307
62679
|
if (json2) {
|
|
62308
62680
|
if (opts.exportSessionPath === "-") process.stdout.write(json2 + "\n");
|
|
62309
62681
|
else {
|
|
62310
|
-
await fs36.mkdir(
|
|
62682
|
+
await fs36.mkdir(path61.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
62311
62683
|
await fs36.writeFile(opts.exportSessionPath, json2, "utf8");
|
|
62312
62684
|
}
|
|
62313
62685
|
}
|
|
@@ -62393,6 +62765,13 @@ ${JSON.stringify({ deliverable: brief.deliverableThisMission, mvp: brief.sliceMv
|
|
|
62393
62765
|
emit,
|
|
62394
62766
|
buildViaAgent,
|
|
62395
62767
|
onMissionPhase: (phase2, note) => spine.missionPhase(phase2, note),
|
|
62768
|
+
onMissionProgress: (advice, iteration) => spine.missionProgress({
|
|
62769
|
+
recommendation: advice.recommendation,
|
|
62770
|
+
rationale: advice.rationale,
|
|
62771
|
+
blockers: advice.blockers,
|
|
62772
|
+
...advice.trend ? { trend: advice.trend } : {},
|
|
62773
|
+
iteration
|
|
62774
|
+
}),
|
|
62396
62775
|
runSlice: async ({
|
|
62397
62776
|
userMessage: slicePrompt,
|
|
62398
62777
|
runMode,
|
|
@@ -62597,8 +62976,22 @@ ${ragContext}` : slicePrompt;
|
|
|
62597
62976
|
});
|
|
62598
62977
|
if (state3.status === "error") exitCode = exitCode || 3;
|
|
62599
62978
|
else if (state3.status === "success") {
|
|
62600
|
-
|
|
62601
|
-
|
|
62979
|
+
const missionGate = await evaluateStrictBuildGate("build", {
|
|
62980
|
+
emit: (input) => spine.appendEvent(input),
|
|
62981
|
+
surface: "mission"
|
|
62982
|
+
});
|
|
62983
|
+
const missionVerificationPayload = strictGateEventPayload(missionGate);
|
|
62984
|
+
spine.verificationRun(missionVerificationPayload);
|
|
62985
|
+
if (opts.output === "json") {
|
|
62986
|
+
emitEvent({ type: "verification_run", ...missionVerificationPayload });
|
|
62987
|
+
}
|
|
62988
|
+
if (missionGate.blocked) {
|
|
62989
|
+
exitCode = strictGateExitCode(missionGate);
|
|
62990
|
+
spine.missionPhase("verification", "mission-strict-blocked");
|
|
62991
|
+
} else {
|
|
62992
|
+
exitCode = 0;
|
|
62993
|
+
spine.missionPhase("done", "mission-success");
|
|
62994
|
+
}
|
|
62602
62995
|
} else if (state3.status === "stalled" || state3.status === "stopped") {
|
|
62603
62996
|
exitCode = exitCode || 0;
|
|
62604
62997
|
spine.missionPhase("verification", `mission-${state3.status}`);
|
|
@@ -62626,7 +63019,7 @@ ${ragContext}` : slicePrompt;
|
|
|
62626
63019
|
if (json2) {
|
|
62627
63020
|
if (opts.exportSessionPath === "-") process.stdout.write(json2 + "\n");
|
|
62628
63021
|
else {
|
|
62629
|
-
await fs36.mkdir(
|
|
63022
|
+
await fs36.mkdir(path61.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
62630
63023
|
await fs36.writeFile(opts.exportSessionPath, json2, "utf8");
|
|
62631
63024
|
}
|
|
62632
63025
|
}
|
|
@@ -62840,8 +63233,8 @@ function normalizeDraft(raw, sourceUrl, provider, model) {
|
|
|
62840
63233
|
let name = String(o.name ?? "").trim().toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64);
|
|
62841
63234
|
if (!name || !/^[a-z0-9][a-z0-9-]{0,63}$/.test(name)) {
|
|
62842
63235
|
try {
|
|
62843
|
-
const
|
|
62844
|
-
name =
|
|
63236
|
+
const path64 = new URL(sourceUrl).pathname.split("/").filter(Boolean).pop()?.replace(/\.[a-z0-9]+$/i, "").toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48);
|
|
63237
|
+
name = path64 && /^[a-z0-9]/.test(path64) ? path64 : "imported-skill";
|
|
62845
63238
|
} catch {
|
|
62846
63239
|
name = "imported-skill";
|
|
62847
63240
|
}
|