zelari-code 2.0.0-alpha.5 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/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/headlessSessionEvent.test.js +83 -0
- package/dist/cli/headlessSessionEvent.test.js.map +1 -0
- package/dist/cli/headlessSpine.js +25 -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 +40 -7
- 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 +121 -8
- package/dist/cli/kraken/verificationBridge.js.map +1 -1
- package/dist/cli/kraken/verificationBridge.session.test.js +104 -0
- package/dist/cli/kraken/verificationBridge.session.test.js.map +1 -0
- package/dist/cli/kraken/verificationBridge.test.js +63 -17
- 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 +65 -0
- package/dist/cli/legacyContextIsolation.test.js.map +1 -0
- package/dist/cli/main.bundled.js +893 -317
- 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 +68 -8
- package/dist/cli/runHeadless.js.map +1 -1
- package/dist/cli/sessionManager.js +7 -0
- package/dist/cli/sessionManager.js.map +1 -1
- package/dist/cli/sessionSpine.js +43 -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 +3 -3
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);
|
|
@@ -29645,7 +29744,29 @@ function evaluateCompletion(criteria, results, policy = STRICT_ALL_POLICY) {
|
|
|
29645
29744
|
});
|
|
29646
29745
|
continue;
|
|
29647
29746
|
}
|
|
29747
|
+
const admissible = policy.admissibleTiers;
|
|
29748
|
+
const tierOk = (e) => !admissible || admissible.includes(e.tier);
|
|
29749
|
+
if (!result.evidence.some(tierOk)) {
|
|
29750
|
+
const tiers = [...new Set(result.evidence.map((e) => e.tier))].join(", ");
|
|
29751
|
+
unsatisfied.push({
|
|
29752
|
+
id,
|
|
29753
|
+
status: "unknown",
|
|
29754
|
+
reason: `pass with inadmissible evidence tiers only (${tiers}) \u2014 not acceptable for completion`
|
|
29755
|
+
});
|
|
29756
|
+
continue;
|
|
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
|
+
}
|
|
29648
29767
|
satisfied.push(id);
|
|
29768
|
+
if (!backed)
|
|
29769
|
+
unbackedSatisfied = true;
|
|
29649
29770
|
}
|
|
29650
29771
|
const verdict = unsatisfied.length === 0 ? "PASS" : unsatisfied.some((u) => u.status === "fail") ? "REPAIR_REQUIRED" : "BLOCKED";
|
|
29651
29772
|
return {
|
|
@@ -29653,21 +29774,126 @@ function evaluateCompletion(criteria, results, policy = STRICT_ALL_POLICY) {
|
|
|
29653
29774
|
satisfied,
|
|
29654
29775
|
unsatisfied,
|
|
29655
29776
|
evidenceComplete: unsatisfied.length === 0,
|
|
29777
|
+
eventBackedEvidenceComplete: unsatisfied.length === 0 && !unbackedSatisfied,
|
|
29656
29778
|
summary: verdict === "PASS" ? `complete: ${satisfied.length}/${ids.length} required criteria pass with evidence` : `incomplete (${verdict}): ${unsatisfied.map((u) => `${u.id}=${u.status}`).join(", ")}`
|
|
29657
29779
|
};
|
|
29658
29780
|
}
|
|
29659
|
-
var STRICT_ALL_POLICY, strictBuildGate;
|
|
29781
|
+
var STRICT_ALL_POLICY, DETERMINISTIC_EVIDENCE_TIERS, STRICT_BUILD_POLICY, strictBuildGate;
|
|
29660
29782
|
var init_completionPolicy = __esm({
|
|
29661
29783
|
"packages/core/dist/verification/completionPolicy.js"() {
|
|
29662
29784
|
"use strict";
|
|
29785
|
+
init_types9();
|
|
29663
29786
|
STRICT_ALL_POLICY = { mode: "strict", required: "*" };
|
|
29787
|
+
DETERMINISTIC_EVIDENCE_TIERS = [
|
|
29788
|
+
"tool-output",
|
|
29789
|
+
"command-output",
|
|
29790
|
+
"fs-observation",
|
|
29791
|
+
"human"
|
|
29792
|
+
];
|
|
29793
|
+
STRICT_BUILD_POLICY = {
|
|
29794
|
+
mode: "strict",
|
|
29795
|
+
required: "*",
|
|
29796
|
+
admissibleTiers: DETERMINISTIC_EVIDENCE_TIERS,
|
|
29797
|
+
requireEventBackedEvidence: true
|
|
29798
|
+
};
|
|
29664
29799
|
strictBuildGate = evaluateCompletion;
|
|
29665
29800
|
}
|
|
29666
29801
|
});
|
|
29667
29802
|
|
|
29803
|
+
// packages/core/dist/verification/sessionEvidence.js
|
|
29804
|
+
function asString2(v) {
|
|
29805
|
+
return typeof v === "string" ? v : null;
|
|
29806
|
+
}
|
|
29807
|
+
function asStringArray(v) {
|
|
29808
|
+
if (!Array.isArray(v))
|
|
29809
|
+
return [];
|
|
29810
|
+
return v.filter((x) => typeof x === "string");
|
|
29811
|
+
}
|
|
29812
|
+
function asUnsatisfied(v) {
|
|
29813
|
+
if (!Array.isArray(v))
|
|
29814
|
+
return [];
|
|
29815
|
+
const out = [];
|
|
29816
|
+
for (const item of v) {
|
|
29817
|
+
if (!item || typeof item !== "object")
|
|
29818
|
+
continue;
|
|
29819
|
+
const rec = item;
|
|
29820
|
+
const id = asString2(rec.id);
|
|
29821
|
+
if (id === null)
|
|
29822
|
+
continue;
|
|
29823
|
+
out.push({
|
|
29824
|
+
id,
|
|
29825
|
+
status: asString2(rec.status) ?? "unknown",
|
|
29826
|
+
reason: asString2(rec.reason) ?? ""
|
|
29827
|
+
});
|
|
29828
|
+
}
|
|
29829
|
+
return out;
|
|
29830
|
+
}
|
|
29831
|
+
function parseVerificationRunPayload(ev) {
|
|
29832
|
+
const data = ev.data;
|
|
29833
|
+
if (!data || typeof data !== "object")
|
|
29834
|
+
return null;
|
|
29835
|
+
const rec = data;
|
|
29836
|
+
const verdictRaw = asString2(rec.verdict);
|
|
29837
|
+
const verdict = verdictRaw !== null && VERDICTS.has(verdictRaw) ? verdictRaw : "unknown";
|
|
29838
|
+
const evidence = rec.evidence && typeof rec.evidence === "object" ? rec.evidence : null;
|
|
29839
|
+
const satisfied = asStringArray(evidence?.satisfied);
|
|
29840
|
+
const unsatisfied = asUnsatisfied(evidence?.unsatisfied);
|
|
29841
|
+
const completeRaw = evidence?.complete;
|
|
29842
|
+
return {
|
|
29843
|
+
seq: ev.seq,
|
|
29844
|
+
ts: ev.ts,
|
|
29845
|
+
engine: asString2(rec.engine),
|
|
29846
|
+
strict: rec.strict === true,
|
|
29847
|
+
verdict,
|
|
29848
|
+
satisfied,
|
|
29849
|
+
unsatisfied,
|
|
29850
|
+
evidenceComplete: typeof completeRaw === "boolean" ? completeRaw : verdict === "PASS" && satisfied.length > 0 && unsatisfied.length === 0,
|
|
29851
|
+
summary: asString2(rec.summary) ?? ""
|
|
29852
|
+
};
|
|
29853
|
+
}
|
|
29854
|
+
function lastVerificationRun(events) {
|
|
29855
|
+
for (let i = events.length - 1; i >= 0; i--) {
|
|
29856
|
+
const ev = events[i];
|
|
29857
|
+
if (ev.kind !== "verification.run")
|
|
29858
|
+
continue;
|
|
29859
|
+
const snap = parseVerificationRunPayload(ev);
|
|
29860
|
+
if (snap)
|
|
29861
|
+
return snap;
|
|
29862
|
+
}
|
|
29863
|
+
return null;
|
|
29864
|
+
}
|
|
29865
|
+
function snapshotToCompletionEvaluation(snap) {
|
|
29866
|
+
if (!snap.strict)
|
|
29867
|
+
return null;
|
|
29868
|
+
const unsatisfied = snap.unsatisfied.map((u) => ({
|
|
29869
|
+
id: u.id,
|
|
29870
|
+
status: u.status === "fail" || u.status === "missing" ? u.status : "unknown",
|
|
29871
|
+
reason: u.reason
|
|
29872
|
+
}));
|
|
29873
|
+
const verdict = snap.verdict === "PASS" || snap.verdict === "REPAIR_REQUIRED" || snap.verdict === "BLOCKED" ? snap.verdict : "BLOCKED";
|
|
29874
|
+
return {
|
|
29875
|
+
verdict,
|
|
29876
|
+
satisfied: [...snap.satisfied],
|
|
29877
|
+
unsatisfied,
|
|
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,
|
|
29882
|
+
summary: snap.summary
|
|
29883
|
+
};
|
|
29884
|
+
}
|
|
29885
|
+
var VERDICTS;
|
|
29886
|
+
var init_sessionEvidence = __esm({
|
|
29887
|
+
"packages/core/dist/verification/sessionEvidence.js"() {
|
|
29888
|
+
"use strict";
|
|
29889
|
+
VERDICTS = /* @__PURE__ */ new Set(["PASS", "REPAIR_REQUIRED", "BLOCKED"]);
|
|
29890
|
+
}
|
|
29891
|
+
});
|
|
29892
|
+
|
|
29668
29893
|
// packages/core/dist/verification/criteriaPack.v1.js
|
|
29669
29894
|
function codingCriteriaPack(options = {}) {
|
|
29670
29895
|
const timeoutMs = options.commandTimeoutMs ?? 6e5;
|
|
29896
|
+
const withDefault = (o, d) => o === void 0 ? d : o;
|
|
29671
29897
|
const command = (command2) => command2 ? { kind: "command", command: command2, timeoutMs } : void 0;
|
|
29672
29898
|
const criteria = [
|
|
29673
29899
|
{
|
|
@@ -29675,21 +29901,21 @@ function codingCriteriaPack(options = {}) {
|
|
|
29675
29901
|
text: "Static checks (typecheck) pass with no new errors.",
|
|
29676
29902
|
source: "criteria-pack",
|
|
29677
29903
|
required: true,
|
|
29678
|
-
check: command(options.typecheckCommand
|
|
29904
|
+
check: command(withDefault(options.typecheckCommand, "npm run typecheck"))
|
|
29679
29905
|
},
|
|
29680
29906
|
{
|
|
29681
29907
|
id: "correctness.specification",
|
|
29682
29908
|
text: "The test suite passes \u2014 behavior matches the specification.",
|
|
29683
29909
|
source: "criteria-pack",
|
|
29684
29910
|
required: true,
|
|
29685
|
-
check: command(options.testCommand
|
|
29911
|
+
check: command(withDefault(options.testCommand, "npm run test"))
|
|
29686
29912
|
},
|
|
29687
29913
|
{
|
|
29688
29914
|
id: "correctness.observable-output",
|
|
29689
29915
|
text: "The project builds successfully (observable output artifact).",
|
|
29690
29916
|
source: "criteria-pack",
|
|
29691
29917
|
required: true,
|
|
29692
|
-
check: command(options.buildCommand
|
|
29918
|
+
check: command(withDefault(options.buildCommand, "npm run build"))
|
|
29693
29919
|
},
|
|
29694
29920
|
{
|
|
29695
29921
|
id: "quality.scope-discipline",
|
|
@@ -29954,6 +30180,7 @@ var init_verification2 = __esm({
|
|
|
29954
30180
|
init_types9();
|
|
29955
30181
|
init_engine();
|
|
29956
30182
|
init_completionPolicy();
|
|
30183
|
+
init_sessionEvidence();
|
|
29957
30184
|
init_criteriaPack_v1();
|
|
29958
30185
|
init_metrics();
|
|
29959
30186
|
init_verifier();
|
|
@@ -29986,7 +30213,8 @@ function deriveMissionState(projection) {
|
|
|
29986
30213
|
verifications: projection.verifications.length,
|
|
29987
30214
|
lastSeq: projection.lastSeq,
|
|
29988
30215
|
interrupted: projection.lastSeq > 0 && projection.endedAt === void 0,
|
|
29989
|
-
forkParent: projection.fork?.parentSessionId
|
|
30216
|
+
forkParent: projection.fork?.parentSessionId,
|
|
30217
|
+
lastAdvice: projection.missionAdvice[projection.missionAdvice.length - 1]
|
|
29990
30218
|
};
|
|
29991
30219
|
}
|
|
29992
30220
|
function missionSnapshot(state3) {
|
|
@@ -30004,11 +30232,99 @@ var init_missionState = __esm({
|
|
|
30004
30232
|
}
|
|
30005
30233
|
});
|
|
30006
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
|
+
|
|
30007
30322
|
// packages/core/dist/mission/index.js
|
|
30008
30323
|
var init_mission2 = __esm({
|
|
30009
30324
|
"packages/core/dist/mission/index.js"() {
|
|
30010
30325
|
"use strict";
|
|
30011
30326
|
init_missionState();
|
|
30327
|
+
init_continuationPolicy();
|
|
30012
30328
|
}
|
|
30013
30329
|
});
|
|
30014
30330
|
|
|
@@ -30045,8 +30361,10 @@ __export(dist_exports, {
|
|
|
30045
30361
|
DESIGN_PHASE_MODE_BANNER: () => DESIGN_PHASE_MODE_BANNER,
|
|
30046
30362
|
DESIGN_PHASE_REQUIREMENTS: () => DESIGN_PHASE_REQUIREMENTS,
|
|
30047
30363
|
DESIGN_PHASE_REQUIREMENT_SETS: () => DESIGN_PHASE_REQUIREMENT_SETS,
|
|
30364
|
+
DETERMINISTIC_EVIDENCE_TIERS: () => DETERMINISTIC_EVIDENCE_TIERS,
|
|
30048
30365
|
DOOM_LOOP_THRESHOLD: () => DOOM_LOOP_THRESHOLD,
|
|
30049
30366
|
DeterministicCheckSchema: () => DeterministicCheckSchema,
|
|
30367
|
+
EVENT_BACKED_EVIDENCE_TIERS: () => EVENT_BACKED_EVIDENCE_TIERS,
|
|
30050
30368
|
EXPERIMENTAL_FLAGS: () => EXPERIMENTAL_FLAGS,
|
|
30051
30369
|
EventBus: () => EventBus,
|
|
30052
30370
|
EvidenceRefSchema: () => EvidenceRefSchema,
|
|
@@ -30100,6 +30418,7 @@ __export(dist_exports, {
|
|
|
30100
30418
|
SINGLE_AGENT_IDENTITY_MODULE: () => SINGLE_AGENT_IDENTITY_MODULE,
|
|
30101
30419
|
SKILL_CATALOG: () => SKILL_CATALOG,
|
|
30102
30420
|
STRICT_ALL_POLICY: () => STRICT_ALL_POLICY,
|
|
30421
|
+
STRICT_BUILD_POLICY: () => STRICT_BUILD_POLICY,
|
|
30103
30422
|
STRUCTURED_REASONING_DIRECTIVE: () => STRUCTURED_REASONING_DIRECTIVE,
|
|
30104
30423
|
ScriptRunner: () => ScriptRunner,
|
|
30105
30424
|
SessionActorSchema: () => SessionActorSchema,
|
|
@@ -30191,6 +30510,7 @@ __export(dist_exports, {
|
|
|
30191
30510
|
emptyContextGrowthStats: () => emptyContextGrowthStats,
|
|
30192
30511
|
enforceDesignPhaseToolEmissions: () => enforceDesignPhaseToolEmissions,
|
|
30193
30512
|
evaluateCompletion: () => evaluateCompletion,
|
|
30513
|
+
evaluateMissionContinuation: () => evaluateMissionContinuation,
|
|
30194
30514
|
executeTool: () => executeTool,
|
|
30195
30515
|
exportSession: () => exportSession,
|
|
30196
30516
|
exportSessionJson: () => exportSessionJson,
|
|
@@ -30246,6 +30566,7 @@ __export(dist_exports, {
|
|
|
30246
30566
|
isBrainToolExecutionStartEvent: () => isBrainToolExecutionStartEvent,
|
|
30247
30567
|
isBrainToolExecutionUpdateEvent: () => isBrainToolExecutionUpdateEvent,
|
|
30248
30568
|
isConverged: () => isConverged,
|
|
30569
|
+
isEventBackedEvidence: () => isEventBackedEvidence,
|
|
30249
30570
|
isExperimentalEnabled: () => isExperimentalEnabled,
|
|
30250
30571
|
isModelSurfaceEvent: () => isModelSurfaceEvent,
|
|
30251
30572
|
isReviewerKind: () => isReviewerKind,
|
|
@@ -30255,6 +30576,7 @@ __export(dist_exports, {
|
|
|
30255
30576
|
isVerifyToolCheckSkipped: () => isVerifyToolCheckSkipped,
|
|
30256
30577
|
jaccardSimilarity: () => jaccardSimilarity,
|
|
30257
30578
|
jsonBytes: () => jsonBytes,
|
|
30579
|
+
lastVerificationRun: () => lastVerificationRun,
|
|
30258
30580
|
lineageOf: () => lineageOf,
|
|
30259
30581
|
lintSynthesisHonesty: () => lintSynthesisHonesty,
|
|
30260
30582
|
listCodingSkills: () => listCodingSkills,
|
|
@@ -30276,6 +30598,7 @@ __export(dist_exports, {
|
|
|
30276
30598
|
parseProjectRootFromWorkspaceContext: () => parseProjectRootFromWorkspaceContext,
|
|
30277
30599
|
parseTextToolCalls: () => parseTextToolCalls,
|
|
30278
30600
|
parseThinking: () => parseThinking,
|
|
30601
|
+
parseVerificationRunPayload: () => parseVerificationRunPayload,
|
|
30279
30602
|
parseVerificationTable: () => parseVerificationTable,
|
|
30280
30603
|
parseVerifyVerdict: () => parseVerifyVerdict,
|
|
30281
30604
|
pathsOverlap: () => pathsOverlap,
|
|
@@ -30325,6 +30648,7 @@ __export(dist_exports, {
|
|
|
30325
30648
|
sha256Hex: () => sha256Hex,
|
|
30326
30649
|
shouldRetryMember: () => shouldRetryMember,
|
|
30327
30650
|
slugify: () => slugify2,
|
|
30651
|
+
snapshotToCompletionEvaluation: () => snapshotToCompletionEvaluation,
|
|
30328
30652
|
specificityFromAssumptions: () => specificityFromAssumptions,
|
|
30329
30653
|
stableStringify: () => stableStringify,
|
|
30330
30654
|
strictBuildGate: () => strictBuildGate,
|
|
@@ -30694,6 +31018,7 @@ var init_sessionSpine = __esm({
|
|
|
30694
31018
|
"use strict";
|
|
30695
31019
|
init_session();
|
|
30696
31020
|
init_session();
|
|
31021
|
+
init_verification2();
|
|
30697
31022
|
MAX_STREAM_BUFFERS = 32;
|
|
30698
31023
|
SessionSpineMirror = class _SessionSpineMirror {
|
|
30699
31024
|
constructor(sessionId2, options) {
|
|
@@ -30702,7 +31027,7 @@ var init_sessionSpine = __esm({
|
|
|
30702
31027
|
this.sessionsDir = resolveSessionsDir({ baseDir: options.baseDir });
|
|
30703
31028
|
}
|
|
30704
31029
|
writer = null;
|
|
30705
|
-
chain = Promise.resolve();
|
|
31030
|
+
chain = Promise.resolve(null);
|
|
30706
31031
|
streamBuffers = /* @__PURE__ */ new Map();
|
|
30707
31032
|
warned = false;
|
|
30708
31033
|
status = "disabled";
|
|
@@ -30781,6 +31106,19 @@ var init_sessionSpine = __esm({
|
|
|
30781
31106
|
if (!report || report.events.length === 0) return null;
|
|
30782
31107
|
return deriveMessages(report.events);
|
|
30783
31108
|
}
|
|
31109
|
+
/**
|
|
31110
|
+
* E2.1 (ADR-0023 × ADR-0021): last recognizable strict verification record
|
|
31111
|
+
* in this session's log — the completion verdict is reconstructible from
|
|
31112
|
+
* the spine alone (null when degraded/disabled or no record).
|
|
31113
|
+
*/
|
|
31114
|
+
async lastVerificationRun() {
|
|
31115
|
+
if (this.status !== "active" && this.status !== "closed") return null;
|
|
31116
|
+
const report = await readSessionLog(
|
|
31117
|
+
path21.join(this.sessionsDir, this.sessionId, "events.jsonl")
|
|
31118
|
+
).catch(() => null);
|
|
31119
|
+
if (!report) return null;
|
|
31120
|
+
return lastVerificationRun(report.events);
|
|
31121
|
+
}
|
|
30784
31122
|
/** Mirror one BrainEvent (coalescing message deltas until message_end). */
|
|
30785
31123
|
mirrorBrainEvent(ev) {
|
|
30786
31124
|
if (this.status !== "active" || !this.writer) return;
|
|
@@ -30825,18 +31163,44 @@ var init_sessionSpine = __esm({
|
|
|
30825
31163
|
data: { phase: phase2, ...note ? { note } : {} }
|
|
30826
31164
|
});
|
|
30827
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
|
+
}
|
|
30828
31183
|
note(text, data) {
|
|
30829
31184
|
void this.append({ kind: "note", actor: ACTOR_SYSTEM, data: { note: text, ...data } });
|
|
30830
31185
|
}
|
|
30831
31186
|
append(input) {
|
|
30832
|
-
if (!this.writer || this.status === "closed") return Promise.resolve();
|
|
30833
|
-
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) => {
|
|
30834
31189
|
this.status = "degraded";
|
|
30835
31190
|
this.writer = null;
|
|
30836
31191
|
this.warnOnce(err);
|
|
31192
|
+
return null;
|
|
30837
31193
|
});
|
|
30838
31194
|
return this.chain;
|
|
30839
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
|
+
}
|
|
30840
31204
|
warnOnce(err) {
|
|
30841
31205
|
if (this.warned || this.options.quiet) return;
|
|
30842
31206
|
this.warned = true;
|
|
@@ -32455,9 +32819,9 @@ function spillToolOutput(fullText, meta3) {
|
|
|
32455
32819
|
const rnd = randomBytes2(3).toString("hex");
|
|
32456
32820
|
const safeTool = (meta3?.toolName ?? "tool").replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 32);
|
|
32457
32821
|
const file2 = `${stamp}-${safeTool}-${hash3}-${rnd}.txt`;
|
|
32458
|
-
const
|
|
32459
|
-
writeFileSync11(
|
|
32460
|
-
return
|
|
32822
|
+
const path64 = join11(dir, file2);
|
|
32823
|
+
writeFileSync11(path64, fullText, "utf8");
|
|
32824
|
+
return path64;
|
|
32461
32825
|
} catch {
|
|
32462
32826
|
return null;
|
|
32463
32827
|
}
|
|
@@ -32503,10 +32867,10 @@ function truncateToolResult(text, capOrOpts = TOOL_RESULT_LINE_CAP) {
|
|
|
32503
32867
|
${tail2}`;
|
|
32504
32868
|
}
|
|
32505
32869
|
if (doSpill) {
|
|
32506
|
-
const
|
|
32507
|
-
if (
|
|
32870
|
+
const path64 = spillToolOutput(text, { toolName: opts.toolName });
|
|
32871
|
+
if (path64) {
|
|
32508
32872
|
const spillNote = `
|
|
32509
|
-
\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`;
|
|
32510
32874
|
if (preview.includes("] \u2026\n")) {
|
|
32511
32875
|
preview = preview.replace("] \u2026\n", `] \u2026${spillNote}
|
|
32512
32876
|
`);
|
|
@@ -35169,28 +35533,28 @@ var init_storage = __esm({
|
|
|
35169
35533
|
VALID_SCALARS = /^(true|false|null|~)$/i;
|
|
35170
35534
|
Storage = class {
|
|
35171
35535
|
/** Read a Markdown file with frontmatter. Throws if not found. */
|
|
35172
|
-
read(
|
|
35173
|
-
if (!existsSync19(
|
|
35174
|
-
throw new Error(`File not found: ${
|
|
35536
|
+
read(path64) {
|
|
35537
|
+
if (!existsSync19(path64)) {
|
|
35538
|
+
throw new Error(`File not found: ${path64}`);
|
|
35175
35539
|
}
|
|
35176
|
-
const md = readFileSync16(
|
|
35540
|
+
const md = readFileSync16(path64, "utf8");
|
|
35177
35541
|
return parseFrontmatter(md);
|
|
35178
35542
|
}
|
|
35179
35543
|
/** Read a Markdown file; returns null if not found. */
|
|
35180
|
-
readIfExists(
|
|
35181
|
-
if (!existsSync19(
|
|
35182
|
-
return this.read(
|
|
35544
|
+
readIfExists(path64) {
|
|
35545
|
+
if (!existsSync19(path64)) return null;
|
|
35546
|
+
return this.read(path64);
|
|
35183
35547
|
}
|
|
35184
35548
|
/**
|
|
35185
35549
|
* Write a Markdown file atomically (tmp + rename). Creates parent dirs.
|
|
35186
35550
|
* The meta object is serialized as YAML frontmatter; body as Markdown.
|
|
35187
35551
|
*/
|
|
35188
|
-
write(
|
|
35189
|
-
mkdirSync11(dirname2(
|
|
35190
|
-
const tmp =
|
|
35552
|
+
write(path64, meta3, body) {
|
|
35553
|
+
mkdirSync11(dirname2(path64), { recursive: true });
|
|
35554
|
+
const tmp = path64 + ".tmp-" + process.pid;
|
|
35191
35555
|
const md = serializeFrontmatter(meta3, body);
|
|
35192
35556
|
writeFileSync13(tmp, md, "utf8");
|
|
35193
|
-
renameSync2(tmp,
|
|
35557
|
+
renameSync2(tmp, path64);
|
|
35194
35558
|
}
|
|
35195
35559
|
/** List all .md files in a directory (non-recursive). */
|
|
35196
35560
|
listMarkdown(dir) {
|
|
@@ -35252,8 +35616,8 @@ function nextPlanTaskId(store6) {
|
|
|
35252
35616
|
return `t${store6.counter}`;
|
|
35253
35617
|
}
|
|
35254
35618
|
function writePlanTaskArtifact(rootDir, task) {
|
|
35255
|
-
const
|
|
35256
|
-
mkdirSync12(dirname3(
|
|
35619
|
+
const path64 = join15(rootDir, "plan-tasks", `${task.id}.md`);
|
|
35620
|
+
mkdirSync12(dirname3(path64), { recursive: true });
|
|
35257
35621
|
const meta3 = {
|
|
35258
35622
|
kind: "task",
|
|
35259
35623
|
id: task.id,
|
|
@@ -35274,7 +35638,7 @@ function writePlanTaskArtifact(rootDir, task) {
|
|
|
35274
35638
|
task.notes?.trim() ? task.notes.trim() : "_(no notes)_",
|
|
35275
35639
|
""
|
|
35276
35640
|
].filter((l) => l !== null).join("\n");
|
|
35277
|
-
new Storage().write(
|
|
35641
|
+
new Storage().write(path64, meta3, body);
|
|
35278
35642
|
}
|
|
35279
35643
|
function loadHandle(rootDir) {
|
|
35280
35644
|
const jsonPath = join15(rootDir, "plan.json");
|
|
@@ -37832,21 +38196,21 @@ function normalizeAuth(auth) {
|
|
|
37832
38196
|
return "agent";
|
|
37833
38197
|
}
|
|
37834
38198
|
function readSecrets() {
|
|
37835
|
-
const
|
|
37836
|
-
if (!existsSync23(
|
|
38199
|
+
const path64 = getSshSecretsPath();
|
|
38200
|
+
if (!existsSync23(path64)) return {};
|
|
37837
38201
|
try {
|
|
37838
|
-
return JSON.parse(readFileSync20(
|
|
38202
|
+
return JSON.parse(readFileSync20(path64, "utf8"));
|
|
37839
38203
|
} catch {
|
|
37840
38204
|
return {};
|
|
37841
38205
|
}
|
|
37842
38206
|
}
|
|
37843
38207
|
function writeSecrets(data) {
|
|
37844
|
-
const
|
|
37845
|
-
mkdirSync13(dirname4(
|
|
37846
|
-
writeFileSync15(
|
|
38208
|
+
const path64 = getSshSecretsPath();
|
|
38209
|
+
mkdirSync13(dirname4(path64), { recursive: true });
|
|
38210
|
+
writeFileSync15(path64, `${JSON.stringify(data, null, 2)}
|
|
37847
38211
|
`, "utf8");
|
|
37848
38212
|
try {
|
|
37849
|
-
chmodSync(
|
|
38213
|
+
chmodSync(path64, 384);
|
|
37850
38214
|
} catch {
|
|
37851
38215
|
}
|
|
37852
38216
|
}
|
|
@@ -37875,10 +38239,10 @@ function deleteSshPassword(id) {
|
|
|
37875
38239
|
writeSecrets({ passwords });
|
|
37876
38240
|
}
|
|
37877
38241
|
function readStore2() {
|
|
37878
|
-
const
|
|
37879
|
-
if (!existsSync23(
|
|
38242
|
+
const path64 = getSshTargetsPath();
|
|
38243
|
+
if (!existsSync23(path64)) return [];
|
|
37880
38244
|
try {
|
|
37881
|
-
const parsed = JSON.parse(readFileSync20(
|
|
38245
|
+
const parsed = JSON.parse(readFileSync20(path64, "utf8"));
|
|
37882
38246
|
const list = Array.isArray(parsed.targets) ? parsed.targets : [];
|
|
37883
38247
|
return list.filter(
|
|
37884
38248
|
(t) => t && typeof t.id === "string" && typeof t.host === "string" && typeof t.user === "string"
|
|
@@ -37893,11 +38257,11 @@ function readStore2() {
|
|
|
37893
38257
|
}
|
|
37894
38258
|
}
|
|
37895
38259
|
function writeStore2(targets) {
|
|
37896
|
-
const
|
|
37897
|
-
mkdirSync13(dirname4(
|
|
38260
|
+
const path64 = getSshTargetsPath();
|
|
38261
|
+
mkdirSync13(dirname4(path64), { recursive: true });
|
|
37898
38262
|
const clean = targets.map(({ hasPassword: _hp, ...t }) => t);
|
|
37899
38263
|
writeFileSync15(
|
|
37900
|
-
|
|
38264
|
+
path64,
|
|
37901
38265
|
`${JSON.stringify({ targets: clean }, null, 2)}
|
|
37902
38266
|
`,
|
|
37903
38267
|
"utf8"
|
|
@@ -38143,11 +38507,11 @@ function formatSshTargetsForPrompt() {
|
|
|
38143
38507
|
];
|
|
38144
38508
|
for (const t of targets) {
|
|
38145
38509
|
const tags = t.tags?.length ? ` tags=[${t.tags.join(",")}]` : "";
|
|
38146
|
-
const
|
|
38510
|
+
const path64 = t.defaultRemotePath ? ` remotePath=${t.defaultRemotePath}` : "";
|
|
38147
38511
|
const allow = t.allowedCommands?.length ? ` allowed=${t.allowedCommands.join("|")}` : " allowed=status-only";
|
|
38148
38512
|
const auth = t.auth === "password" ? " auth=password" : t.auth === "keyPath" ? " auth=key" : " auth=agent";
|
|
38149
38513
|
lines.push(
|
|
38150
|
-
`- 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}`
|
|
38151
38515
|
);
|
|
38152
38516
|
}
|
|
38153
38517
|
return lines.join("\n");
|
|
@@ -39857,6 +40221,9 @@ function parseHeadlessFlags(argv) {
|
|
|
39857
40221
|
i++;
|
|
39858
40222
|
} else if (arg === "--strict-done") {
|
|
39859
40223
|
strictDone = true;
|
|
40224
|
+
} else if (arg === "--no-strict-done") {
|
|
40225
|
+
strictDone = false;
|
|
40226
|
+
process.env.ZELARI_MISSION_STRICT = "0";
|
|
39860
40227
|
} else if (arg === "--kraken-graph") {
|
|
39861
40228
|
krakenGraph = argv[i + 1];
|
|
39862
40229
|
i++;
|
|
@@ -39959,8 +40326,16 @@ __export(headlessSpine_exports, {
|
|
|
39959
40326
|
missionStateFromSpine: () => missionStateFromSpine,
|
|
39960
40327
|
openHeadlessSpine: () => openHeadlessSpine,
|
|
39961
40328
|
resolveHeadlessProfileId: () => resolveHeadlessProfileId,
|
|
39962
|
-
seedHeadlessModelHistory: () => seedHeadlessModelHistory
|
|
40329
|
+
seedHeadlessModelHistory: () => seedHeadlessModelHistory,
|
|
40330
|
+
sessionStartedEvent: () => sessionStartedEvent
|
|
39963
40331
|
});
|
|
40332
|
+
function sessionStartedEvent(handle) {
|
|
40333
|
+
return {
|
|
40334
|
+
type: "session_started",
|
|
40335
|
+
sessionId: handle.sessionId,
|
|
40336
|
+
spine: handle.spine.status
|
|
40337
|
+
};
|
|
40338
|
+
}
|
|
39964
40339
|
function resolveHeadlessProfileId(mode, explicit) {
|
|
39965
40340
|
if (explicit) return resolveProfile(explicit).id;
|
|
39966
40341
|
return defaultProfileForMode(mode ?? "kraken");
|
|
@@ -40002,9 +40377,18 @@ async function openHeadlessSpine(opts) {
|
|
|
40002
40377
|
verificationRun(payload) {
|
|
40003
40378
|
spine.verificationRun(payload);
|
|
40004
40379
|
},
|
|
40380
|
+
appendEvent(input) {
|
|
40381
|
+
return spine.appendEvent(input);
|
|
40382
|
+
},
|
|
40383
|
+
lastVerificationRun() {
|
|
40384
|
+
return spine.lastVerificationRun();
|
|
40385
|
+
},
|
|
40005
40386
|
missionPhase(phase2, note) {
|
|
40006
40387
|
spine.missionPhase(phase2, note);
|
|
40007
40388
|
},
|
|
40389
|
+
missionProgress(advice) {
|
|
40390
|
+
spine.missionProgress(advice);
|
|
40391
|
+
},
|
|
40008
40392
|
note(text, data) {
|
|
40009
40393
|
spine.note(text, data);
|
|
40010
40394
|
},
|
|
@@ -40114,12 +40498,12 @@ var init_headlessSpine = __esm({
|
|
|
40114
40498
|
// src/cli/state/fileStateStore.ts
|
|
40115
40499
|
import { createHash as createHash10, randomUUID as randomUUID2 } from "node:crypto";
|
|
40116
40500
|
import { promises as fs21 } from "node:fs";
|
|
40117
|
-
import * as
|
|
40501
|
+
import * as path41 from "node:path";
|
|
40118
40502
|
function shortId() {
|
|
40119
40503
|
return randomUUID2().replace(/-/g, "").slice(0, 12);
|
|
40120
40504
|
}
|
|
40121
40505
|
async function writeJsonAtomic(filePath, data) {
|
|
40122
|
-
await fs21.mkdir(
|
|
40506
|
+
await fs21.mkdir(path41.dirname(filePath), { recursive: true });
|
|
40123
40507
|
const tmp = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
40124
40508
|
await fs21.writeFile(tmp, JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
40125
40509
|
await fs21.rename(tmp, filePath);
|
|
@@ -40180,11 +40564,11 @@ var init_fileStateStore = __esm({
|
|
|
40180
40564
|
indexPath = "";
|
|
40181
40565
|
async init(projectRoot) {
|
|
40182
40566
|
this.root = projectRoot;
|
|
40183
|
-
this.stateDir =
|
|
40184
|
-
this.commitsDir =
|
|
40185
|
-
this.artifactsDir =
|
|
40186
|
-
this.headPath =
|
|
40187
|
-
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");
|
|
40188
40572
|
await fs21.mkdir(this.commitsDir, { recursive: true });
|
|
40189
40573
|
await fs21.mkdir(this.artifactsDir, { recursive: true });
|
|
40190
40574
|
}
|
|
@@ -40197,13 +40581,13 @@ var init_fileStateStore = __esm({
|
|
|
40197
40581
|
const discoveries = input.discoveries ?? [];
|
|
40198
40582
|
const parent = await this.head();
|
|
40199
40583
|
const id = shortId();
|
|
40200
|
-
const artifactRel =
|
|
40201
|
-
const artifactAbs =
|
|
40584
|
+
const artifactRel = path41.join("artifacts", id);
|
|
40585
|
+
const artifactAbs = path41.join(this.artifactsDir, id);
|
|
40202
40586
|
await fs21.mkdir(artifactAbs, { recursive: true });
|
|
40203
40587
|
const summary = defaultSummary(input, discoveries);
|
|
40204
|
-
await fs21.writeFile(
|
|
40205
|
-
await writeJsonAtomic(
|
|
40206
|
-
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);
|
|
40207
40591
|
const meta3 = {
|
|
40208
40592
|
id,
|
|
40209
40593
|
parentId: parent?.id ?? null,
|
|
@@ -40215,14 +40599,14 @@ var init_fileStateStore = __esm({
|
|
|
40215
40599
|
workspaceCheckpointId: input.workspaceCheckpointId,
|
|
40216
40600
|
verification: {
|
|
40217
40601
|
...input.verification,
|
|
40218
|
-
reportPath: input.verification.reportPath ??
|
|
40602
|
+
reportPath: input.verification.reportPath ?? path41.join(".zelari", "state", artifactRel, "verification.json").replace(/\\/g, "/")
|
|
40219
40603
|
},
|
|
40220
40604
|
changedPaths: input.changedPaths ?? [],
|
|
40221
40605
|
stablePromptHash: input.stablePromptHash,
|
|
40222
40606
|
discoveryCount: discoveries.length,
|
|
40223
40607
|
artifactDir: artifactRel.replace(/\\/g, "/")
|
|
40224
40608
|
};
|
|
40225
|
-
await writeJsonAtomic(
|
|
40609
|
+
await writeJsonAtomic(path41.join(this.commitsDir, `${id}.json`), meta3);
|
|
40226
40610
|
await writeJsonAtomic(this.headPath, { id, updatedAt: meta3.createdAt });
|
|
40227
40611
|
await fs21.appendFile(this.indexPath, JSON.stringify({ id, createdAt: meta3.createdAt, label: meta3.label }) + "\n", "utf8");
|
|
40228
40612
|
return stripStored(meta3);
|
|
@@ -40233,7 +40617,7 @@ var init_fileStateStore = __esm({
|
|
|
40233
40617
|
return this.get(head.id);
|
|
40234
40618
|
}
|
|
40235
40619
|
async get(id) {
|
|
40236
|
-
const stored = await readJsonFile(
|
|
40620
|
+
const stored = await readJsonFile(path41.join(this.commitsDir, `${id}.json`));
|
|
40237
40621
|
return stored ? stripStored(stored) : null;
|
|
40238
40622
|
}
|
|
40239
40623
|
async list(limit = 20) {
|
|
@@ -40272,9 +40656,9 @@ var init_fileStateStore = __esm({
|
|
|
40272
40656
|
async loadDiscoveries(id) {
|
|
40273
40657
|
const meta3 = id ? await this.get(id) : await this.head();
|
|
40274
40658
|
if (!meta3) return [];
|
|
40275
|
-
const stored = await readJsonFile(
|
|
40659
|
+
const stored = await readJsonFile(path41.join(this.commitsDir, `${meta3.id}.json`));
|
|
40276
40660
|
if (!stored?.artifactDir) return [];
|
|
40277
|
-
const discPath =
|
|
40661
|
+
const discPath = path41.join(this.stateDir, stored.artifactDir, "discoveries.json");
|
|
40278
40662
|
return await readJsonFile(discPath) ?? [];
|
|
40279
40663
|
}
|
|
40280
40664
|
async materializeContext(id, maxChars = DEFAULT_MATERIALIZE_CHARS) {
|
|
@@ -41984,8 +42368,8 @@ function readPlan(ctx) {
|
|
|
41984
42368
|
} catch {
|
|
41985
42369
|
}
|
|
41986
42370
|
}
|
|
41987
|
-
const
|
|
41988
|
-
const doc = ctx.storage.readIfExists(
|
|
42371
|
+
const path64 = workspaceFile(ctx.rootDir, "plan");
|
|
42372
|
+
const doc = ctx.storage.readIfExists(path64);
|
|
41989
42373
|
if (!doc) return { phases: [], tasks: [], milestones: [] };
|
|
41990
42374
|
const meta3 = doc.meta;
|
|
41991
42375
|
return {
|
|
@@ -42163,7 +42547,7 @@ function addMilestoneRecord(ctx, summary, input) {
|
|
|
42163
42547
|
dueDate: input.dueDate,
|
|
42164
42548
|
targetVersion: version2
|
|
42165
42549
|
});
|
|
42166
|
-
const
|
|
42550
|
+
const path64 = join25(ctx.rootDir, "milestones", `${id}.md`);
|
|
42167
42551
|
const meta3 = {
|
|
42168
42552
|
kind: "milestone",
|
|
42169
42553
|
id,
|
|
@@ -42180,7 +42564,7 @@ function addMilestoneRecord(ctx, summary, input) {
|
|
|
42180
42564
|
`Target version: ${version2}`,
|
|
42181
42565
|
""
|
|
42182
42566
|
].join("\n");
|
|
42183
|
-
ctx.storage.write(
|
|
42567
|
+
ctx.storage.write(path64, meta3, body);
|
|
42184
42568
|
return { id, created: true };
|
|
42185
42569
|
}
|
|
42186
42570
|
function readPlanSummary(ctx) {
|
|
@@ -42384,7 +42768,7 @@ function addIdeaStub(ctx) {
|
|
|
42384
42768
|
const tags = args["tags"] ?? [];
|
|
42385
42769
|
const category = args["category"] ?? "General";
|
|
42386
42770
|
const id = `${nextAdrId(ctx)}-${slugify3(title)}`;
|
|
42387
|
-
const
|
|
42771
|
+
const path64 = workspaceArtifact(ctx.rootDir, "decisions", id);
|
|
42388
42772
|
const meta3 = {
|
|
42389
42773
|
kind: "adr",
|
|
42390
42774
|
status: "proposed",
|
|
@@ -42410,7 +42794,7 @@ function addIdeaStub(ctx) {
|
|
|
42410
42794
|
...consequences.map((c) => `- ${c}`),
|
|
42411
42795
|
""
|
|
42412
42796
|
].join("\n");
|
|
42413
|
-
ctx.storage.write(
|
|
42797
|
+
ctx.storage.write(path64, meta3, body);
|
|
42414
42798
|
return `ADR ${id} created: "${title}". Status: proposed. Promote to accepted via /update ADR or manual edit.`;
|
|
42415
42799
|
});
|
|
42416
42800
|
}
|
|
@@ -42492,14 +42876,14 @@ function createDocumentStub(ctx) {
|
|
|
42492
42876
|
ctx.storage.write(risksPath, riskMeta, content);
|
|
42493
42877
|
return `Document "${title}" created at risks.md (workspace root).`;
|
|
42494
42878
|
}
|
|
42495
|
-
const
|
|
42879
|
+
const path64 = workspaceArtifact(ctx.rootDir, "docs", slug);
|
|
42496
42880
|
const meta3 = {
|
|
42497
42881
|
kind: "doc",
|
|
42498
42882
|
id: slug,
|
|
42499
42883
|
date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
|
|
42500
42884
|
tags
|
|
42501
42885
|
};
|
|
42502
|
-
ctx.storage.write(
|
|
42886
|
+
ctx.storage.write(path64, meta3, content);
|
|
42503
42887
|
return `Document "${title}" created at docs/${slug}.md.`;
|
|
42504
42888
|
});
|
|
42505
42889
|
}
|
|
@@ -42720,15 +43104,15 @@ __export(updater_exports, {
|
|
|
42720
43104
|
import { createRequire as createRequire2 } from "node:module";
|
|
42721
43105
|
import { spawn as spawn12 } from "node:child_process";
|
|
42722
43106
|
import { existsSync as existsSync32 } from "node:fs";
|
|
42723
|
-
import
|
|
43107
|
+
import path42 from "node:path";
|
|
42724
43108
|
import { fileURLToPath } from "node:url";
|
|
42725
43109
|
function resolveBundledNpmCli(execPath = process.execPath) {
|
|
42726
|
-
const dir =
|
|
43110
|
+
const dir = path42.dirname(execPath);
|
|
42727
43111
|
const candidates = [
|
|
42728
43112
|
// Windows: C:\...\node.exe → C:\...\node_modules\npm\bin\npm-cli.js
|
|
42729
|
-
|
|
43113
|
+
path42.join(dir, "node_modules", "npm", "bin", "npm-cli.js"),
|
|
42730
43114
|
// POSIX: <prefix>/bin/node → <prefix>/lib/node_modules/npm/bin/npm-cli.js
|
|
42731
|
-
|
|
43115
|
+
path42.join(dir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js")
|
|
42732
43116
|
];
|
|
42733
43117
|
for (const candidate of candidates) {
|
|
42734
43118
|
try {
|
|
@@ -42745,7 +43129,7 @@ function looksLikeBrokenShim(exitCode, output) {
|
|
|
42745
43129
|
}
|
|
42746
43130
|
function getCurrentVersion() {
|
|
42747
43131
|
try {
|
|
42748
|
-
const pkgPath =
|
|
43132
|
+
const pkgPath = path42.resolve(__dirname2, "..", "..", "package.json");
|
|
42749
43133
|
const pkg = require2(pkgPath);
|
|
42750
43134
|
return pkg.version;
|
|
42751
43135
|
} catch {
|
|
@@ -42868,7 +43252,7 @@ var init_updater = __esm({
|
|
|
42868
43252
|
"use strict";
|
|
42869
43253
|
init_cmdline();
|
|
42870
43254
|
require2 = createRequire2(import.meta.url);
|
|
42871
|
-
__dirname2 =
|
|
43255
|
+
__dirname2 = path42.dirname(fileURLToPath(import.meta.url));
|
|
42872
43256
|
REGISTRY_URL = "https://registry.npmjs.org/zelari-code/latest";
|
|
42873
43257
|
}
|
|
42874
43258
|
});
|
|
@@ -43056,10 +43440,10 @@ function getUserMcpPath() {
|
|
|
43056
43440
|
function getProjectMcpPath(projectRoot) {
|
|
43057
43441
|
return join26(projectRoot, ".zelari", "mcp.json");
|
|
43058
43442
|
}
|
|
43059
|
-
function
|
|
43060
|
-
if (!existsSync33(
|
|
43443
|
+
function readFile3(path64) {
|
|
43444
|
+
if (!existsSync33(path64)) return {};
|
|
43061
43445
|
try {
|
|
43062
|
-
const parsed = JSON.parse(readFileSync28(
|
|
43446
|
+
const parsed = JSON.parse(readFileSync28(path64, "utf8"));
|
|
43063
43447
|
const out = {};
|
|
43064
43448
|
for (const [name, cfg] of Object.entries(parsed.mcpServers ?? {})) {
|
|
43065
43449
|
if (!cfg || typeof cfg.command !== "string" || !cfg.command.trim()) continue;
|
|
@@ -43075,17 +43459,17 @@ function readFile2(path63) {
|
|
|
43075
43459
|
return {};
|
|
43076
43460
|
}
|
|
43077
43461
|
}
|
|
43078
|
-
function writeFile(
|
|
43079
|
-
mkdirSync16(dirname7(
|
|
43462
|
+
function writeFile(path64, servers) {
|
|
43463
|
+
mkdirSync16(dirname7(path64), { recursive: true });
|
|
43080
43464
|
const body = { mcpServers: servers };
|
|
43081
|
-
writeFileSync18(
|
|
43465
|
+
writeFileSync18(path64, `${JSON.stringify(body, null, 2)}
|
|
43082
43466
|
`, "utf8");
|
|
43083
43467
|
}
|
|
43084
43468
|
function listMcpServers(projectRoot) {
|
|
43085
43469
|
const userPath = getUserMcpPath();
|
|
43086
|
-
const userServers =
|
|
43470
|
+
const userServers = readFile3(userPath);
|
|
43087
43471
|
const projectPath = projectRoot && projectRoot.trim() ? getProjectMcpPath(projectRoot.trim()) : null;
|
|
43088
|
-
const projectServers = projectPath ?
|
|
43472
|
+
const projectServers = projectPath ? readFile3(projectPath) : {};
|
|
43089
43473
|
const servers = [];
|
|
43090
43474
|
for (const [name, cfg] of Object.entries(userServers)) {
|
|
43091
43475
|
servers.push({ name, ...cfg, scope: "user", path: userPath });
|
|
@@ -43111,9 +43495,9 @@ function upsertMcpServer(opts) {
|
|
|
43111
43495
|
if (!opts.config.command?.trim()) {
|
|
43112
43496
|
return { ok: false, error: "command is required" };
|
|
43113
43497
|
}
|
|
43114
|
-
let
|
|
43498
|
+
let path64;
|
|
43115
43499
|
if (opts.scope === "user") {
|
|
43116
|
-
|
|
43500
|
+
path64 = getUserMcpPath();
|
|
43117
43501
|
} else {
|
|
43118
43502
|
const root = opts.projectRoot?.trim();
|
|
43119
43503
|
if (!root) {
|
|
@@ -43122,30 +43506,30 @@ function upsertMcpServer(opts) {
|
|
|
43122
43506
|
error: "projectRoot required for project scope (Open Folder first)"
|
|
43123
43507
|
};
|
|
43124
43508
|
}
|
|
43125
|
-
|
|
43509
|
+
path64 = getProjectMcpPath(root);
|
|
43126
43510
|
}
|
|
43127
|
-
const current =
|
|
43511
|
+
const current = readFile3(path64);
|
|
43128
43512
|
current[name] = {
|
|
43129
43513
|
command: opts.config.command.trim(),
|
|
43130
43514
|
args: opts.config.args,
|
|
43131
43515
|
env: opts.config.env,
|
|
43132
43516
|
enabled: opts.config.enabled !== false
|
|
43133
43517
|
};
|
|
43134
|
-
writeFile(
|
|
43135
|
-
return { ok: true, path:
|
|
43518
|
+
writeFile(path64, current);
|
|
43519
|
+
return { ok: true, path: path64 };
|
|
43136
43520
|
}
|
|
43137
43521
|
function removeMcpServer(opts) {
|
|
43138
|
-
const
|
|
43139
|
-
if (!
|
|
43522
|
+
const path64 = opts.scope === "user" ? getUserMcpPath() : opts.projectRoot ? getProjectMcpPath(opts.projectRoot) : null;
|
|
43523
|
+
if (!path64) {
|
|
43140
43524
|
return { ok: false, error: "projectRoot required for project scope" };
|
|
43141
43525
|
}
|
|
43142
|
-
const current =
|
|
43526
|
+
const current = readFile3(path64);
|
|
43143
43527
|
if (!(opts.name in current)) {
|
|
43144
|
-
return { ok: false, error: `Server "${opts.name}" not found in ${
|
|
43528
|
+
return { ok: false, error: `Server "${opts.name}" not found in ${path64}` };
|
|
43145
43529
|
}
|
|
43146
43530
|
delete current[opts.name];
|
|
43147
|
-
writeFile(
|
|
43148
|
-
return { ok: true, path:
|
|
43531
|
+
writeFile(path64, current);
|
|
43532
|
+
return { ok: true, path: path64 };
|
|
43149
43533
|
}
|
|
43150
43534
|
var init_mcpConfigIo = __esm({
|
|
43151
43535
|
"src/cli/mcp/mcpConfigIo.ts"() {
|
|
@@ -43544,12 +43928,12 @@ __export(agentsMd_exports, {
|
|
|
43544
43928
|
import { existsSync as existsSync35, readFileSync as readFileSync30, writeFileSync as writeFileSync19 } from "node:fs";
|
|
43545
43929
|
import { createHash as createHash11 } from "node:crypto";
|
|
43546
43930
|
import { join as join28 } from "node:path";
|
|
43547
|
-
import { readFile as
|
|
43931
|
+
import { readFile as readFile4 } from "node:fs/promises";
|
|
43548
43932
|
async function readPackageJson2(projectRoot) {
|
|
43549
|
-
const
|
|
43550
|
-
if (!existsSync35(
|
|
43933
|
+
const path64 = join28(projectRoot, "package.json");
|
|
43934
|
+
if (!existsSync35(path64)) return null;
|
|
43551
43935
|
try {
|
|
43552
|
-
return JSON.parse(await
|
|
43936
|
+
return JSON.parse(await readFile4(path64, "utf8"));
|
|
43553
43937
|
} catch {
|
|
43554
43938
|
return null;
|
|
43555
43939
|
}
|
|
@@ -43631,9 +44015,9 @@ async function genBuild(ctx) {
|
|
|
43631
44015
|
].join("\n");
|
|
43632
44016
|
}
|
|
43633
44017
|
async function genOpenQuestions(ctx) {
|
|
43634
|
-
const
|
|
43635
|
-
if (!existsSync35(
|
|
43636
|
-
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");
|
|
43637
44021
|
const lines = content.split("\n");
|
|
43638
44022
|
const questions = [];
|
|
43639
44023
|
let currentTitle = "";
|
|
@@ -43907,9 +44291,9 @@ function versionKey(value) {
|
|
|
43907
44291
|
function firstString2(v) {
|
|
43908
44292
|
return typeof v === "string" && v.trim().length > 0 ? v : null;
|
|
43909
44293
|
}
|
|
43910
|
-
function readFileSyncSafe(
|
|
44294
|
+
function readFileSyncSafe(path64) {
|
|
43911
44295
|
try {
|
|
43912
|
-
return readFileSync31(
|
|
44296
|
+
return readFileSync31(path64, "utf8");
|
|
43913
44297
|
} catch {
|
|
43914
44298
|
return null;
|
|
43915
44299
|
}
|
|
@@ -44372,8 +44756,8 @@ async function runPostCouncilHook(ctx, options) {
|
|
|
44372
44756
|
sources: scope.sources
|
|
44373
44757
|
} : void 0
|
|
44374
44758
|
});
|
|
44375
|
-
const
|
|
44376
|
-
completionHook = { ran: true, path:
|
|
44759
|
+
const path64 = writeCouncilCompletion(ctx.rootDir, completion);
|
|
44760
|
+
completionHook = { ran: true, path: path64, completion };
|
|
44377
44761
|
} catch (err) {
|
|
44378
44762
|
completionHook = {
|
|
44379
44763
|
ran: true,
|
|
@@ -44418,7 +44802,7 @@ import {
|
|
|
44418
44802
|
writeFileSync as writeFileSync21,
|
|
44419
44803
|
mkdirSync as mkdirSync17
|
|
44420
44804
|
} from "node:fs";
|
|
44421
|
-
import
|
|
44805
|
+
import path43 from "node:path";
|
|
44422
44806
|
import os10 from "node:os";
|
|
44423
44807
|
var FeedbackStore;
|
|
44424
44808
|
var init_councilFeedback = __esm({
|
|
@@ -44429,7 +44813,7 @@ var init_councilFeedback = __esm({
|
|
|
44429
44813
|
now;
|
|
44430
44814
|
entries = [];
|
|
44431
44815
|
constructor(options = {}) {
|
|
44432
|
-
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"));
|
|
44433
44817
|
this.now = options.now ?? Date.now;
|
|
44434
44818
|
this.load();
|
|
44435
44819
|
}
|
|
@@ -44535,7 +44919,7 @@ var init_councilFeedback = __esm({
|
|
|
44535
44919
|
}
|
|
44536
44920
|
}
|
|
44537
44921
|
save() {
|
|
44538
|
-
mkdirSync17(
|
|
44922
|
+
mkdirSync17(path43.dirname(this.file), { recursive: true });
|
|
44539
44923
|
writeFileSync21(
|
|
44540
44924
|
this.file,
|
|
44541
44925
|
JSON.stringify({ entries: this.entries }, null, 2),
|
|
@@ -44603,7 +44987,7 @@ import { execFile as execFile3 } from "node:child_process";
|
|
|
44603
44987
|
import { promisify as promisify2 } from "node:util";
|
|
44604
44988
|
import { mkdtempSync, rmSync as rmSync2 } from "node:fs";
|
|
44605
44989
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
44606
|
-
import
|
|
44990
|
+
import path44 from "node:path";
|
|
44607
44991
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
44608
44992
|
async function git3(cwd, args, env) {
|
|
44609
44993
|
const { stdout } = await execFileAsync2("git", ["-C", cwd, ...args], {
|
|
@@ -44623,8 +45007,8 @@ async function isGitRepo(cwd) {
|
|
|
44623
45007
|
return await gitSafe(cwd, ["rev-parse", "--is-inside-work-tree"]) === "true";
|
|
44624
45008
|
}
|
|
44625
45009
|
async function withTempIndex(fn) {
|
|
44626
|
-
const dir = mkdtempSync(
|
|
44627
|
-
const indexFile =
|
|
45010
|
+
const dir = mkdtempSync(path44.join(tmpdir2(), "zelari-ckpt-"));
|
|
45011
|
+
const indexFile = path44.join(dir, "index");
|
|
44628
45012
|
try {
|
|
44629
45013
|
return await fn(indexFile);
|
|
44630
45014
|
} finally {
|
|
@@ -44715,7 +45099,7 @@ async function restoreCheckpoint(cwd, id) {
|
|
|
44715
45099
|
const deleted = [];
|
|
44716
45100
|
for (const rel2 of added) {
|
|
44717
45101
|
try {
|
|
44718
|
-
rmSync2(
|
|
45102
|
+
rmSync2(path44.join(cwd, rel2), { force: true });
|
|
44719
45103
|
deleted.push(rel2);
|
|
44720
45104
|
} catch {
|
|
44721
45105
|
}
|
|
@@ -44816,7 +45200,7 @@ __export(fileBackend_exports, {
|
|
|
44816
45200
|
});
|
|
44817
45201
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
44818
45202
|
import { promises as fs23 } from "node:fs";
|
|
44819
|
-
import * as
|
|
45203
|
+
import * as path45 from "node:path";
|
|
44820
45204
|
function tokenize(text) {
|
|
44821
45205
|
return text.toLowerCase().split(/[^\p{L}\p{N}]+/u).filter((t) => t.length >= 3);
|
|
44822
45206
|
}
|
|
@@ -44860,8 +45244,8 @@ var init_fileBackend = __esm({
|
|
|
44860
45244
|
logPath = "";
|
|
44861
45245
|
memoryDir = "";
|
|
44862
45246
|
async init(projectRoot) {
|
|
44863
|
-
this.memoryDir =
|
|
44864
|
-
this.logPath =
|
|
45247
|
+
this.memoryDir = path45.join(projectRoot, ".zelari", "memory");
|
|
45248
|
+
this.logPath = path45.join(this.memoryDir, "log.jsonl");
|
|
44865
45249
|
await fs23.mkdir(this.memoryDir, { recursive: true });
|
|
44866
45250
|
}
|
|
44867
45251
|
async add(content, metadata = {}, graph) {
|
|
@@ -44934,12 +45318,12 @@ var init_fileBackend = __esm({
|
|
|
44934
45318
|
|
|
44935
45319
|
// src/cli/traceStore.ts
|
|
44936
45320
|
import { promises as fs24 } from "node:fs";
|
|
44937
|
-
import * as
|
|
45321
|
+
import * as path46 from "node:path";
|
|
44938
45322
|
function traceDir(projectRoot) {
|
|
44939
|
-
return
|
|
45323
|
+
return path46.join(projectRoot, ".zelari", "trace");
|
|
44940
45324
|
}
|
|
44941
45325
|
function tracePath(projectRoot, missionId) {
|
|
44942
|
-
return
|
|
45326
|
+
return path46.join(traceDir(projectRoot), `${missionId}.json`);
|
|
44943
45327
|
}
|
|
44944
45328
|
async function saveTrace(projectRoot, missionId, entries) {
|
|
44945
45329
|
const dir = traceDir(projectRoot);
|
|
@@ -44974,7 +45358,7 @@ __export(zelariMission_exports, {
|
|
|
44974
45358
|
});
|
|
44975
45359
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
44976
45360
|
import { promises as fs25 } from "node:fs";
|
|
44977
|
-
import * as
|
|
45361
|
+
import * as path47 from "node:path";
|
|
44978
45362
|
function resolveMaxIterations(env = process.env) {
|
|
44979
45363
|
const raw = env.ZELARI_MISSION_MAX_ITER;
|
|
44980
45364
|
const n = raw ? Number.parseInt(raw, 10) : DEFAULT_MAX_ITER;
|
|
@@ -45002,10 +45386,10 @@ function isMissionAutoStart(env = process.env) {
|
|
|
45002
45386
|
return env.ZELARI_MISSION_AUTO === "1";
|
|
45003
45387
|
}
|
|
45004
45388
|
async function writeMissionState(projectRoot, state3) {
|
|
45005
|
-
const dir =
|
|
45389
|
+
const dir = path47.join(projectRoot, ".zelari");
|
|
45006
45390
|
await fs25.mkdir(dir, { recursive: true });
|
|
45007
45391
|
await fs25.writeFile(
|
|
45008
|
-
|
|
45392
|
+
path47.join(dir, "mission-state.json"),
|
|
45009
45393
|
JSON.stringify(state3, null, 2) + "\n",
|
|
45010
45394
|
"utf8"
|
|
45011
45395
|
);
|
|
@@ -45237,6 +45621,17 @@ async function runZelariMission(userMessage, brief, deps) {
|
|
|
45237
45621
|
deps.emit(`[zelari] state commit skipped: ${commitRes.error}`);
|
|
45238
45622
|
}
|
|
45239
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);
|
|
45240
45635
|
if (completionOk) {
|
|
45241
45636
|
state3.status = "success";
|
|
45242
45637
|
deps.onMissionPhase?.("done", "mvp-green");
|
|
@@ -45283,6 +45678,7 @@ var DEFAULT_MAX_ITER, DEFAULT_MAX_STALL;
|
|
|
45283
45678
|
var init_zelariMission = __esm({
|
|
45284
45679
|
"src/cli/zelariMission.ts"() {
|
|
45285
45680
|
"use strict";
|
|
45681
|
+
init_mission2();
|
|
45286
45682
|
init_fileBackend();
|
|
45287
45683
|
init_checkpointManager();
|
|
45288
45684
|
init_fileStateStore();
|
|
@@ -45615,7 +46011,7 @@ function safeSocketPath(socketPath) {
|
|
|
45615
46011
|
return socketPath.trim();
|
|
45616
46012
|
}
|
|
45617
46013
|
function startPermissionBroker(socketPath, handlers, opts) {
|
|
45618
|
-
const
|
|
46014
|
+
const path64 = safeSocketPath(socketPath);
|
|
45619
46015
|
const requestTimeoutMs = opts?.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
|
|
45620
46016
|
const sockets = /* @__PURE__ */ new Set();
|
|
45621
46017
|
const server = createServer2((socket) => {
|
|
@@ -45715,10 +46111,10 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
45715
46111
|
return new Promise((resolve3, reject) => {
|
|
45716
46112
|
const onError = (err) => reject(err);
|
|
45717
46113
|
server.once("error", onError);
|
|
45718
|
-
server.listen(
|
|
46114
|
+
server.listen(path64, () => {
|
|
45719
46115
|
server.removeListener("error", onError);
|
|
45720
46116
|
resolve3({
|
|
45721
|
-
socketPath:
|
|
46117
|
+
socketPath: path64,
|
|
45722
46118
|
stop: () => new Promise((res) => {
|
|
45723
46119
|
for (const s of sockets) s.destroy();
|
|
45724
46120
|
sockets.clear();
|
|
@@ -45729,7 +46125,7 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
45729
46125
|
if (done) return;
|
|
45730
46126
|
done = true;
|
|
45731
46127
|
if (process.platform !== "win32") {
|
|
45732
|
-
unlink(
|
|
46128
|
+
unlink(path64, () => res());
|
|
45733
46129
|
} else {
|
|
45734
46130
|
res();
|
|
45735
46131
|
}
|
|
@@ -45742,11 +46138,11 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
45742
46138
|
});
|
|
45743
46139
|
}
|
|
45744
46140
|
function requestBrokerAsk(socketPath, ask, opts) {
|
|
45745
|
-
const
|
|
46141
|
+
const path64 = safeSocketPath(socketPath);
|
|
45746
46142
|
const requestTimeoutMs = opts?.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
|
|
45747
46143
|
const connectTimeoutMs = opts?.connectTimeoutMs ?? PERMISSION_BROKER_DEFAULT_CONNECT_TIMEOUT_MS;
|
|
45748
46144
|
return new Promise((resolve3, reject) => {
|
|
45749
|
-
const socket = connect(
|
|
46145
|
+
const socket = connect(path64);
|
|
45750
46146
|
let buffer = "";
|
|
45751
46147
|
let settled = false;
|
|
45752
46148
|
const settle = (fn) => {
|
|
@@ -45761,7 +46157,7 @@ function requestBrokerAsk(socketPath, ask, opts) {
|
|
|
45761
46157
|
settle(
|
|
45762
46158
|
() => reject(
|
|
45763
46159
|
new Error(
|
|
45764
|
-
`permission broker unavailable at "${
|
|
46160
|
+
`permission broker unavailable at "${path64}" (connect timed out after ${connectTimeoutMs}ms)`
|
|
45765
46161
|
)
|
|
45766
46162
|
)
|
|
45767
46163
|
);
|
|
@@ -46494,9 +46890,9 @@ __export(graphMemory_exports, {
|
|
|
46494
46890
|
toGraphSnapshot: () => toGraphSnapshot
|
|
46495
46891
|
});
|
|
46496
46892
|
import { promises as fs26 } from "node:fs";
|
|
46497
|
-
import
|
|
46893
|
+
import path49 from "node:path";
|
|
46498
46894
|
function snapshotPath(cwd) {
|
|
46499
|
-
return
|
|
46895
|
+
return path49.join(cwd, SNAPSHOT_DIR, SNAPSHOT_FILE);
|
|
46500
46896
|
}
|
|
46501
46897
|
function toGraphSnapshot(graph, opts) {
|
|
46502
46898
|
const unresolved = (opts.unresolvedFindings ?? []).map((u) => ({
|
|
@@ -46523,7 +46919,7 @@ async function saveGraphSnapshot(cwd, snapshot) {
|
|
|
46523
46919
|
try {
|
|
46524
46920
|
await fs26.access(cwd);
|
|
46525
46921
|
const file2 = snapshotPath(cwd);
|
|
46526
|
-
await fs26.mkdir(
|
|
46922
|
+
await fs26.mkdir(path49.dirname(file2), { recursive: true });
|
|
46527
46923
|
await fs26.writeFile(file2, JSON.stringify(snapshot, null, 2) + "\n", "utf8");
|
|
46528
46924
|
} catch {
|
|
46529
46925
|
}
|
|
@@ -46590,7 +46986,7 @@ var SNAPSHOT_DIR, SNAPSHOT_FILE, MAX_SNAPSHOT_FINDINGS_CHARS;
|
|
|
46590
46986
|
var init_graphMemory = __esm({
|
|
46591
46987
|
"src/cli/kraken/graphMemory.ts"() {
|
|
46592
46988
|
"use strict";
|
|
46593
|
-
SNAPSHOT_DIR =
|
|
46989
|
+
SNAPSHOT_DIR = path49.join(".zelari", "kraken");
|
|
46594
46990
|
SNAPSHOT_FILE = "last-graph.json";
|
|
46595
46991
|
MAX_SNAPSHOT_FINDINGS_CHARS = 400;
|
|
46596
46992
|
}
|
|
@@ -46606,14 +47002,14 @@ var init_tentacle = __esm({
|
|
|
46606
47002
|
|
|
46607
47003
|
// src/cli/kraken/workbench.ts
|
|
46608
47004
|
import { promises as fs27 } from "node:fs";
|
|
46609
|
-
import
|
|
47005
|
+
import path50 from "node:path";
|
|
46610
47006
|
function isWorkbenchEnabled(env = process.env) {
|
|
46611
47007
|
const v = (env.ZELARI_KRAKEN_WORKBENCH ?? "1").trim().toLowerCase();
|
|
46612
47008
|
if (v === "0" || v === "false" || v === "no" || v === "off") return false;
|
|
46613
47009
|
return true;
|
|
46614
47010
|
}
|
|
46615
47011
|
function workbenchPath(cwd, graphId) {
|
|
46616
|
-
return
|
|
47012
|
+
return path50.join(cwd, ".zelari", "radio", `workbench-${graphId}.md`);
|
|
46617
47013
|
}
|
|
46618
47014
|
function countByStatus2(nodes) {
|
|
46619
47015
|
const out = { pending: 0, running: 0, done: 0, error: 0, skipped: 0 };
|
|
@@ -46776,7 +47172,7 @@ var init_workbench = __esm({
|
|
|
46776
47172
|
if (!this.enabled) return null;
|
|
46777
47173
|
if (!this.dirty && this.lastWrite) return this.lastWrite;
|
|
46778
47174
|
const out = workbenchPath(this.cwd, this.graphId);
|
|
46779
|
-
await fs27.mkdir(
|
|
47175
|
+
await fs27.mkdir(path50.dirname(out), { recursive: true });
|
|
46780
47176
|
const body = this.render();
|
|
46781
47177
|
const tmp = `${out}.${process.pid}.${Date.now()}.tmp`;
|
|
46782
47178
|
await fs27.writeFile(tmp, body, "utf8");
|
|
@@ -46973,7 +47369,7 @@ __export(executor_exports, {
|
|
|
46973
47369
|
thoroughnessForKind: () => thoroughnessForKind
|
|
46974
47370
|
});
|
|
46975
47371
|
import { existsSync as existsSync40 } from "node:fs";
|
|
46976
|
-
import
|
|
47372
|
+
import path51 from "node:path";
|
|
46977
47373
|
function resolveMaxParallel(env = process.env) {
|
|
46978
47374
|
const raw = env.ZELARI_KRAKEN_MAX_PARALLEL;
|
|
46979
47375
|
if (raw === void 0 || raw === "") return DEFAULT_MAX_PARALLEL;
|
|
@@ -47031,7 +47427,7 @@ function isWorldModelGateEnabled(cwd, env = process.env, checksExists = defaultC
|
|
|
47031
47427
|
}
|
|
47032
47428
|
function defaultChecksExists(cwd) {
|
|
47033
47429
|
try {
|
|
47034
|
-
return existsSync40(
|
|
47430
|
+
return existsSync40(path51.join(cwd, ".zelari", "world", "checks.json"));
|
|
47035
47431
|
} catch {
|
|
47036
47432
|
return false;
|
|
47037
47433
|
}
|
|
@@ -48370,10 +48766,10 @@ var init_prereqChecks = __esm({
|
|
|
48370
48766
|
|
|
48371
48767
|
// src/cli/plugins/prefs.ts
|
|
48372
48768
|
import { existsSync as existsSync42, readFileSync as readFileSync35, writeFileSync as writeFileSync22, mkdirSync as mkdirSync18 } from "node:fs";
|
|
48373
|
-
import
|
|
48769
|
+
import path54 from "node:path";
|
|
48374
48770
|
import os11 from "node:os";
|
|
48375
48771
|
function getPluginPrefsPath() {
|
|
48376
|
-
return process.env.ZELARI_PLUGINS_PREFS_FILE ??
|
|
48772
|
+
return process.env.ZELARI_PLUGINS_PREFS_FILE ?? path54.join(os11.homedir(), ".tmp", "zelari-code", "plugins.json");
|
|
48377
48773
|
}
|
|
48378
48774
|
function getPluginPrefs() {
|
|
48379
48775
|
const file2 = getPluginPrefsPath();
|
|
@@ -48394,7 +48790,7 @@ function getPluginPrefs() {
|
|
|
48394
48790
|
}
|
|
48395
48791
|
function writePluginPrefs(prefs) {
|
|
48396
48792
|
const file2 = getPluginPrefsPath();
|
|
48397
|
-
mkdirSync18(
|
|
48793
|
+
mkdirSync18(path54.dirname(file2), { recursive: true });
|
|
48398
48794
|
writeFileSync22(file2, JSON.stringify(prefs, null, 2), {
|
|
48399
48795
|
encoding: "utf-8",
|
|
48400
48796
|
mode: 384
|
|
@@ -48431,7 +48827,7 @@ __export(registry_exports, {
|
|
|
48431
48827
|
isBinaryOnPath: () => isBinaryOnPath
|
|
48432
48828
|
});
|
|
48433
48829
|
import { existsSync as existsSync43 } from "node:fs";
|
|
48434
|
-
import
|
|
48830
|
+
import path55 from "node:path";
|
|
48435
48831
|
function detectLocalBin(bin) {
|
|
48436
48832
|
return (cwd) => {
|
|
48437
48833
|
try {
|
|
@@ -48449,7 +48845,7 @@ function isBinaryOnPath(bin, opts = {}) {
|
|
|
48449
48845
|
const platform = opts.platform ?? process.platform;
|
|
48450
48846
|
const exists = opts.exists ?? existsSync43;
|
|
48451
48847
|
const pathEnv = opts.pathEnv ?? process.env.PATH ?? "";
|
|
48452
|
-
const pathMod = platform === "win32" ?
|
|
48848
|
+
const pathMod = platform === "win32" ? path55.win32 : path55.posix;
|
|
48453
48849
|
const sep2 = platform === "win32" ? ";" : ":";
|
|
48454
48850
|
const dirs = pathEnv.split(sep2).filter((d) => d.length > 0);
|
|
48455
48851
|
const candidates = [bin];
|
|
@@ -49396,9 +49792,9 @@ __export(triggerLock_exports, {
|
|
|
49396
49792
|
releaseLock: () => releaseLock
|
|
49397
49793
|
});
|
|
49398
49794
|
import { promises as fs35 } from "node:fs";
|
|
49399
|
-
import * as
|
|
49795
|
+
import * as path60 from "node:path";
|
|
49400
49796
|
function lockPath(projectRoot) {
|
|
49401
|
-
return
|
|
49797
|
+
return path60.join(projectRoot, ".zelari", "trigger.lock");
|
|
49402
49798
|
}
|
|
49403
49799
|
function isPidAlive(pid) {
|
|
49404
49800
|
try {
|
|
@@ -49411,7 +49807,7 @@ function isPidAlive(pid) {
|
|
|
49411
49807
|
}
|
|
49412
49808
|
async function acquireLock(projectRoot, now = () => /* @__PURE__ */ new Date()) {
|
|
49413
49809
|
const lp = lockPath(projectRoot);
|
|
49414
|
-
const dir =
|
|
49810
|
+
const dir = path60.dirname(lp);
|
|
49415
49811
|
await fs35.mkdir(dir, { recursive: true });
|
|
49416
49812
|
try {
|
|
49417
49813
|
const raw = await fs35.readFile(lp, "utf8");
|
|
@@ -50005,7 +50401,7 @@ function upsertSkill(opts) {
|
|
|
50005
50401
|
}
|
|
50006
50402
|
dir = getProjectSkillsDir(root);
|
|
50007
50403
|
}
|
|
50008
|
-
const
|
|
50404
|
+
const path64 = skillFilePath(dir, name);
|
|
50009
50405
|
const content = serializeSkillMd({
|
|
50010
50406
|
name,
|
|
50011
50407
|
description,
|
|
@@ -50014,13 +50410,13 @@ function upsertSkill(opts) {
|
|
|
50014
50410
|
tools: opts.tools,
|
|
50015
50411
|
cost: opts.cost
|
|
50016
50412
|
});
|
|
50017
|
-
const parsed = parseSkillMd(content,
|
|
50413
|
+
const parsed = parseSkillMd(content, path64);
|
|
50018
50414
|
if (!parsed) {
|
|
50019
50415
|
return { ok: false, error: "Generated SKILL.md failed validation" };
|
|
50020
50416
|
}
|
|
50021
|
-
mkdirSync21(dirname10(
|
|
50022
|
-
writeFileSync24(
|
|
50023
|
-
return { ok: true, path:
|
|
50417
|
+
mkdirSync21(dirname10(path64), { recursive: true });
|
|
50418
|
+
writeFileSync24(path64, content, "utf8");
|
|
50419
|
+
return { ok: true, path: path64 };
|
|
50024
50420
|
}
|
|
50025
50421
|
function removeSkill(opts) {
|
|
50026
50422
|
const name = opts.name.trim().toLowerCase();
|
|
@@ -50038,8 +50434,8 @@ function removeSkill(opts) {
|
|
|
50038
50434
|
dir = getProjectSkillsDir(root);
|
|
50039
50435
|
}
|
|
50040
50436
|
const skillDir = join37(dir, name);
|
|
50041
|
-
const
|
|
50042
|
-
if (!existsSync48(
|
|
50437
|
+
const path64 = skillFilePath(dir, name);
|
|
50438
|
+
if (!existsSync48(path64) && !existsSync48(skillDir)) {
|
|
50043
50439
|
return { ok: false, error: `Skill "${name}" not found in ${dir}` };
|
|
50044
50440
|
}
|
|
50045
50441
|
try {
|
|
@@ -50050,7 +50446,7 @@ function removeSkill(opts) {
|
|
|
50050
50446
|
error: err instanceof Error ? err.message : String(err)
|
|
50051
50447
|
};
|
|
50052
50448
|
}
|
|
50053
|
-
return { ok: true, path:
|
|
50449
|
+
return { ok: true, path: path64 };
|
|
50054
50450
|
}
|
|
50055
50451
|
var NAME_RE, BUILTIN_SKILL_MODULES, builtinsLoaded;
|
|
50056
50452
|
var init_skillConfigIo = __esm({
|
|
@@ -50368,12 +50764,12 @@ function ensureHome() {
|
|
|
50368
50764
|
}
|
|
50369
50765
|
}
|
|
50370
50766
|
function loadCompanionConfig() {
|
|
50371
|
-
const
|
|
50372
|
-
if (!existsSync49(
|
|
50767
|
+
const path64 = getCompanionConfigPath();
|
|
50768
|
+
if (!existsSync49(path64)) {
|
|
50373
50769
|
return { projects: [] };
|
|
50374
50770
|
}
|
|
50375
50771
|
try {
|
|
50376
|
-
const raw = JSON.parse(readFileSync39(
|
|
50772
|
+
const raw = JSON.parse(readFileSync39(path64, "utf8"));
|
|
50377
50773
|
const projects = Array.isArray(raw.projects) ? raw.projects.filter(
|
|
50378
50774
|
(p3) => p3 && typeof p3.path === "string" && p3.path.trim() && typeof (p3.id ?? p3.name) === "string"
|
|
50379
50775
|
).map((p3) => ({
|
|
@@ -50411,16 +50807,16 @@ function loadOrCreateToken(explicit) {
|
|
|
50411
50807
|
return { token: explicit.trim(), created: false };
|
|
50412
50808
|
}
|
|
50413
50809
|
ensureHome();
|
|
50414
|
-
const
|
|
50415
|
-
if (existsSync49(
|
|
50416
|
-
const t = readFileSync39(
|
|
50810
|
+
const path64 = getCompanionTokenPath();
|
|
50811
|
+
if (existsSync49(path64)) {
|
|
50812
|
+
const t = readFileSync39(path64, "utf8").trim();
|
|
50417
50813
|
if (t) return { token: t, created: false };
|
|
50418
50814
|
}
|
|
50419
50815
|
const token = randomBytes5(24).toString("base64url");
|
|
50420
|
-
writeFileSync25(
|
|
50816
|
+
writeFileSync25(path64, token + "\n", "utf8");
|
|
50421
50817
|
try {
|
|
50422
50818
|
const fs37 = __require("node:fs");
|
|
50423
|
-
fs37.chmodSync?.(
|
|
50819
|
+
fs37.chmodSync?.(path64, 384);
|
|
50424
50820
|
} catch {
|
|
50425
50821
|
}
|
|
50426
50822
|
return { token, created: true };
|
|
@@ -50445,17 +50841,17 @@ function mergeProjects(cfg, extraPaths) {
|
|
|
50445
50841
|
byId.set(p3.id, p3);
|
|
50446
50842
|
}
|
|
50447
50843
|
for (const raw of extraPaths) {
|
|
50448
|
-
const
|
|
50449
|
-
if (!
|
|
50450
|
-
let id = slugFromPath(
|
|
50844
|
+
const path64 = raw.trim();
|
|
50845
|
+
if (!path64) continue;
|
|
50846
|
+
let id = slugFromPath(path64);
|
|
50451
50847
|
let n = 2;
|
|
50452
|
-
while (byId.has(id) && byId.get(id).path !==
|
|
50453
|
-
id = `${slugFromPath(
|
|
50848
|
+
while (byId.has(id) && byId.get(id).path !== path64) {
|
|
50849
|
+
id = `${slugFromPath(path64)}-${n++}`;
|
|
50454
50850
|
}
|
|
50455
50851
|
byId.set(id, {
|
|
50456
50852
|
id,
|
|
50457
|
-
name: slugFromPath(
|
|
50458
|
-
path:
|
|
50853
|
+
name: slugFromPath(path64),
|
|
50854
|
+
path: path64
|
|
50459
50855
|
});
|
|
50460
50856
|
}
|
|
50461
50857
|
return [...byId.values()];
|
|
@@ -50832,9 +51228,9 @@ async function runCompanionServe(opts = {}) {
|
|
|
50832
51228
|
return;
|
|
50833
51229
|
}
|
|
50834
51230
|
const url2 = parseUrl(req);
|
|
50835
|
-
const
|
|
51231
|
+
const path64 = url2.pathname.replace(/\/+$/, "") || "/";
|
|
50836
51232
|
try {
|
|
50837
|
-
if (req.method === "GET" && (
|
|
51233
|
+
if (req.method === "GET" && (path64 === "/health" || path64 === "/v1/health")) {
|
|
50838
51234
|
sendJson2(res, 200, {
|
|
50839
51235
|
ok: true,
|
|
50840
51236
|
service: "zelari-companion",
|
|
@@ -50846,18 +51242,18 @@ async function runCompanionServe(opts = {}) {
|
|
|
50846
51242
|
});
|
|
50847
51243
|
return;
|
|
50848
51244
|
}
|
|
50849
|
-
if (
|
|
51245
|
+
if (path64.startsWith("/v1")) {
|
|
50850
51246
|
if (!tokenMatches(token, getBearer(req))) {
|
|
50851
51247
|
sendJson2(res, 401, { ok: false, error: "unauthorized" });
|
|
50852
51248
|
return;
|
|
50853
51249
|
}
|
|
50854
51250
|
}
|
|
50855
|
-
if (req.method === "GET" &&
|
|
51251
|
+
if (req.method === "GET" && path64 === "/v1/config") {
|
|
50856
51252
|
const snap = buildDesktopConfigSnapshot();
|
|
50857
51253
|
sendJson2(res, 200, { ok: true, ...snap });
|
|
50858
51254
|
return;
|
|
50859
51255
|
}
|
|
50860
|
-
if (req.method === "GET" &&
|
|
51256
|
+
if (req.method === "GET" && path64 === "/v1/projects") {
|
|
50861
51257
|
sendJson2(res, 200, {
|
|
50862
51258
|
ok: true,
|
|
50863
51259
|
projects: projects.map((p3) => ({
|
|
@@ -50868,7 +51264,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
50868
51264
|
});
|
|
50869
51265
|
return;
|
|
50870
51266
|
}
|
|
50871
|
-
if (req.method === "GET" &&
|
|
51267
|
+
if (req.method === "GET" && path64 === "/v1/runs") {
|
|
50872
51268
|
sendJson2(res, 200, {
|
|
50873
51269
|
ok: true,
|
|
50874
51270
|
active: runs.getActive(),
|
|
@@ -50886,7 +51282,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
50886
51282
|
});
|
|
50887
51283
|
return;
|
|
50888
51284
|
}
|
|
50889
|
-
if (req.method === "POST" &&
|
|
51285
|
+
if (req.method === "POST" && path64 === "/v1/runs") {
|
|
50890
51286
|
const raw = await readBody(req);
|
|
50891
51287
|
let body = {};
|
|
50892
51288
|
try {
|
|
@@ -50933,7 +51329,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
50933
51329
|
});
|
|
50934
51330
|
return;
|
|
50935
51331
|
}
|
|
50936
|
-
const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(
|
|
51332
|
+
const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(path64);
|
|
50937
51333
|
if (req.method === "GET" && eventsMatch) {
|
|
50938
51334
|
const runId = eventsMatch[1];
|
|
50939
51335
|
const run = runs.getRun(runId);
|
|
@@ -50998,7 +51394,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
50998
51394
|
}, 500);
|
|
50999
51395
|
return;
|
|
51000
51396
|
}
|
|
51001
|
-
const cancelMatch = /^\/v1\/runs\/([^/]+)\/cancel$/.exec(
|
|
51397
|
+
const cancelMatch = /^\/v1\/runs\/([^/]+)\/cancel$/.exec(path64);
|
|
51002
51398
|
if (req.method === "POST" && cancelMatch) {
|
|
51003
51399
|
const runId = cancelMatch[1];
|
|
51004
51400
|
const result = runs.cancel(runId);
|
|
@@ -51151,11 +51547,11 @@ import { execSync as execSync2 } from "node:child_process";
|
|
|
51151
51547
|
import { existsSync as existsSync51, readFileSync as readFileSync40, readlinkSync, statSync as statSync10 } from "node:fs";
|
|
51152
51548
|
import { createRequire as createRequire3 } from "node:module";
|
|
51153
51549
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
51154
|
-
import
|
|
51550
|
+
import path62 from "node:path";
|
|
51155
51551
|
function findPackageRoot(start) {
|
|
51156
51552
|
let dir = start;
|
|
51157
51553
|
for (let i = 0; i < 6; i += 1) {
|
|
51158
|
-
const candidate =
|
|
51554
|
+
const candidate = path62.join(dir, "package.json");
|
|
51159
51555
|
if (existsSync51(candidate)) {
|
|
51160
51556
|
try {
|
|
51161
51557
|
const pkg = JSON.parse(readFileSync40(candidate, "utf8"));
|
|
@@ -51163,11 +51559,11 @@ function findPackageRoot(start) {
|
|
|
51163
51559
|
} catch {
|
|
51164
51560
|
}
|
|
51165
51561
|
}
|
|
51166
|
-
const parent =
|
|
51562
|
+
const parent = path62.dirname(dir);
|
|
51167
51563
|
if (parent === dir) break;
|
|
51168
51564
|
dir = parent;
|
|
51169
51565
|
}
|
|
51170
|
-
return
|
|
51566
|
+
return path62.resolve(__dirname3, "..", "..", "..");
|
|
51171
51567
|
}
|
|
51172
51568
|
function tryExec(cmd) {
|
|
51173
51569
|
try {
|
|
@@ -51181,7 +51577,7 @@ function tryExec(cmd) {
|
|
|
51181
51577
|
}
|
|
51182
51578
|
function readPackageJson3() {
|
|
51183
51579
|
try {
|
|
51184
|
-
const pkgPath =
|
|
51580
|
+
const pkgPath = path62.join(packageRoot, "package.json");
|
|
51185
51581
|
return JSON.parse(readFileSync40(pkgPath, "utf8"));
|
|
51186
51582
|
} catch {
|
|
51187
51583
|
return null;
|
|
@@ -51197,7 +51593,7 @@ function checkShim(pkgName) {
|
|
|
51197
51593
|
}
|
|
51198
51594
|
const isWin = process.platform === "win32";
|
|
51199
51595
|
const shimName = isWin ? "zelari-code.cmd" : "zelari-code";
|
|
51200
|
-
const shimPath =
|
|
51596
|
+
const shimPath = path62.join(prefix, shimName);
|
|
51201
51597
|
if (!existsSync51(shimPath)) {
|
|
51202
51598
|
return FAIL(
|
|
51203
51599
|
`shim not found at ${shimPath}
|
|
@@ -51225,8 +51621,8 @@ function checkShim(pkgName) {
|
|
|
51225
51621
|
fix: npm install -g ${pkgName}@latest --force`
|
|
51226
51622
|
);
|
|
51227
51623
|
}
|
|
51228
|
-
const resolved =
|
|
51229
|
-
const expected =
|
|
51624
|
+
const resolved = path62.resolve(path62.dirname(shimPath), target);
|
|
51625
|
+
const expected = path62.join(
|
|
51230
51626
|
prefix,
|
|
51231
51627
|
"node_modules",
|
|
51232
51628
|
pkgName,
|
|
@@ -51265,7 +51661,7 @@ function checkNode(pkg) {
|
|
|
51265
51661
|
return OK(`node ${raw}`);
|
|
51266
51662
|
}
|
|
51267
51663
|
function checkBundle() {
|
|
51268
|
-
const bundle =
|
|
51664
|
+
const bundle = path62.join(packageRoot, "dist", "cli", "main.bundled.js");
|
|
51269
51665
|
if (!existsSync51(bundle)) {
|
|
51270
51666
|
return FAIL(
|
|
51271
51667
|
`dist/cli/main.bundled.js missing at ${bundle}
|
|
@@ -51286,7 +51682,7 @@ function checkRuntimeDeps() {
|
|
|
51286
51682
|
const missing = [];
|
|
51287
51683
|
for (const dep of required2) {
|
|
51288
51684
|
try {
|
|
51289
|
-
const localReq = createRequire3(
|
|
51685
|
+
const localReq = createRequire3(path62.join(packageRoot, "package.json"));
|
|
51290
51686
|
localReq.resolve(dep);
|
|
51291
51687
|
} catch {
|
|
51292
51688
|
missing.push(dep);
|
|
@@ -51486,7 +51882,7 @@ var init_doctor = __esm({
|
|
|
51486
51882
|
init_metrics2();
|
|
51487
51883
|
init_contextGrowthSummary();
|
|
51488
51884
|
require3 = createRequire3(import.meta.url);
|
|
51489
|
-
__dirname3 =
|
|
51885
|
+
__dirname3 = path62.dirname(fileURLToPath2(import.meta.url));
|
|
51490
51886
|
packageRoot = findPackageRoot(__dirname3);
|
|
51491
51887
|
OK = (message) => ({
|
|
51492
51888
|
ok: true,
|
|
@@ -51670,15 +52066,15 @@ __export(inspect_exports, {
|
|
|
51670
52066
|
collectInspectReport: () => collectInspectReport,
|
|
51671
52067
|
runInspect: () => runInspect
|
|
51672
52068
|
});
|
|
51673
|
-
import
|
|
52069
|
+
import path63 from "node:path";
|
|
51674
52070
|
import { existsSync as existsSync52, readFileSync as readFileSync41, readdirSync as readdirSync11 } from "node:fs";
|
|
51675
52071
|
import { homedir as homedir14 } from "node:os";
|
|
51676
52072
|
async function collectInspectReport(cwd = process.cwd()) {
|
|
51677
52073
|
ensureBuiltinSkillsLoadedSync();
|
|
51678
52074
|
const snap = listSkillsSnapshot(cwd);
|
|
51679
52075
|
const mcp = listMcpServers(cwd);
|
|
51680
|
-
const userMcpPath =
|
|
51681
|
-
const projectMcpPath =
|
|
52076
|
+
const userMcpPath = path63.join(homedir14(), ".zelari-code", "mcp.json");
|
|
52077
|
+
const projectMcpPath = path63.join(cwd, ".zelari", "mcp.json");
|
|
51682
52078
|
const globalHooks = globalHooksDir();
|
|
51683
52079
|
const projectHooks = projectHooksDir(cwd);
|
|
51684
52080
|
const projectTrusted = isFolderTrusted(cwd);
|
|
@@ -51706,9 +52102,9 @@ async function collectInspectReport(cwd = process.cwd()) {
|
|
|
51706
52102
|
configSources: [
|
|
51707
52103
|
{ path: userMcpPath, exists: existsSync52(userMcpPath) },
|
|
51708
52104
|
{ path: projectMcpPath, exists: existsSync52(projectMcpPath) },
|
|
51709
|
-
{ path:
|
|
51710
|
-
{ path:
|
|
51711
|
-
{ 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")) }
|
|
51712
52108
|
],
|
|
51713
52109
|
skills: {
|
|
51714
52110
|
total: snap.skills.length,
|
|
@@ -51748,8 +52144,8 @@ function listJsonFiles(dir) {
|
|
|
51748
52144
|
}
|
|
51749
52145
|
function findAgentsMd(cwd) {
|
|
51750
52146
|
const candidates = [
|
|
51751
|
-
|
|
51752
|
-
|
|
52147
|
+
path63.join(cwd, "AGENTS.md"),
|
|
52148
|
+
path63.join(cwd, ".zelari", "AGENTS.md")
|
|
51753
52149
|
];
|
|
51754
52150
|
const found = [];
|
|
51755
52151
|
for (const c of candidates) {
|
|
@@ -55024,8 +55420,76 @@ init_completionGate();
|
|
|
55024
55420
|
// src/cli/kraken/verificationBridge.ts
|
|
55025
55421
|
init_candidateRegistry();
|
|
55026
55422
|
init_completionGate();
|
|
55423
|
+
|
|
55424
|
+
// src/cli/kraken/nativeVerification.ts
|
|
55425
|
+
init_runtime2();
|
|
55426
|
+
init_verification2();
|
|
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
|
|
55027
55486
|
init_verification2();
|
|
55028
|
-
function strictDoneEnabled() {
|
|
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
|
+
}
|
|
55029
55493
|
const v = process.env.ZELARI_STRICT_DONE;
|
|
55030
55494
|
return v === "1" || v === "true";
|
|
55031
55495
|
}
|
|
@@ -55081,32 +55545,71 @@ function krakenResultsToContract(requiredChecks, results, now = Date.now()) {
|
|
|
55081
55545
|
});
|
|
55082
55546
|
return { criteria, results: verifications };
|
|
55083
55547
|
}
|
|
55084
|
-
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 = {}) {
|
|
55085
55573
|
const gate = evaluateKrakenCompletionGate(mode);
|
|
55086
|
-
if (!gate.selectionUsed || gate.total === 0 || !strictDoneEnabled()) {
|
|
55574
|
+
if (!gate.selectionUsed || gate.total === 0 || !strictDoneEnabled(options.surface ?? "kraken")) {
|
|
55087
55575
|
return {
|
|
55088
55576
|
gate,
|
|
55089
55577
|
strict: false,
|
|
55090
55578
|
evaluation: null,
|
|
55579
|
+
native: null,
|
|
55091
55580
|
blocked: gate.blocked,
|
|
55092
55581
|
summary: gate.blocked ? `blocked: ${gate.failedChecks.length} failed, ${gate.unknownChecks.length} unknown` : "open"
|
|
55093
55582
|
};
|
|
55094
55583
|
}
|
|
55095
55584
|
const checks = krakenRequiredChecks();
|
|
55096
55585
|
const contract = krakenResultsToContract(checks, getKrakenCheckResults());
|
|
55097
|
-
|
|
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);
|
|
55098
55596
|
const blocked = gate.blocked || evaluation.verdict !== "PASS";
|
|
55099
55597
|
return {
|
|
55100
55598
|
gate,
|
|
55101
55599
|
strict: true,
|
|
55102
55600
|
evaluation,
|
|
55601
|
+
native,
|
|
55103
55602
|
blocked,
|
|
55104
|
-
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`
|
|
55105
55604
|
};
|
|
55106
55605
|
}
|
|
55606
|
+
var STRICT_DONE_EXIT_CODE = 4;
|
|
55607
|
+
function strictGateExitCode(evaluation) {
|
|
55608
|
+
return evaluation.strict && evaluation.blocked ? STRICT_DONE_EXIT_CODE : 0;
|
|
55609
|
+
}
|
|
55107
55610
|
function strictGateEventPayload(evaluation) {
|
|
55108
55611
|
return {
|
|
55109
|
-
engine: "kraken-legacy+completion-policy",
|
|
55612
|
+
engine: evaluation.native ? "kraken-legacy+completion-policy+criteria-pack" : "kraken-legacy+completion-policy",
|
|
55110
55613
|
strict: evaluation.strict,
|
|
55111
55614
|
verdict: evaluation.evaluation?.verdict ?? (evaluation.blocked ? "BLOCKED" : "PASS"),
|
|
55112
55615
|
legacy: {
|
|
@@ -55120,6 +55623,17 @@ function strictGateEventPayload(evaluation) {
|
|
|
55120
55623
|
unsatisfied: evaluation.evaluation.unsatisfied,
|
|
55121
55624
|
complete: evaluation.evaluation.evidenceComplete
|
|
55122
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,
|
|
55123
55637
|
summary: evaluation.summary
|
|
55124
55638
|
};
|
|
55125
55639
|
}
|
|
@@ -55631,7 +56145,7 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il turno continua dopo
|
|
|
55631
56145
|
});
|
|
55632
56146
|
}
|
|
55633
56147
|
const cwd = process.cwd();
|
|
55634
|
-
const budget = await applyBudgetPolicyAsync(
|
|
56148
|
+
const budget = await applyBudgetPolicyAsync(historyForModel, getPhase(), {
|
|
55635
56149
|
model: getActiveModel(),
|
|
55636
56150
|
sessionId: sessionId2,
|
|
55637
56151
|
// v1.36.0: envelope for full-request metering + cache-aware
|
|
@@ -55657,6 +56171,7 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il turno continua dopo
|
|
|
55657
56171
|
});
|
|
55658
56172
|
void writerRef.current?.append(compactionEvent);
|
|
55659
56173
|
}
|
|
56174
|
+
historyForModel = budget.history;
|
|
55660
56175
|
historySeedLen = historyForModel.length;
|
|
55661
56176
|
let composedWorkspace = "";
|
|
55662
56177
|
let composedInstructions = "";
|
|
@@ -55873,8 +56388,9 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il turno continua dopo
|
|
|
55873
56388
|
progressRuntime.observe(event);
|
|
55874
56389
|
if (event.type === "agent_end") {
|
|
55875
56390
|
let krakenSuppressFinish = false;
|
|
56391
|
+
const krakenSpineEmit = (input) => writerRef.current?.spine?.appendEvent(input) ?? Promise.resolve(null);
|
|
55876
56392
|
if (event.reason === "completed" && !krakenRepairEnqueued && isKrakenSelectionEnabled() && workPhase === "build") {
|
|
55877
|
-
const strictGate = evaluateStrictBuildGate("build");
|
|
56393
|
+
const strictGate = await evaluateStrictBuildGate("build", { emit: krakenSpineEmit });
|
|
55878
56394
|
const krakenGate = strictGate.gate;
|
|
55879
56395
|
writerRef.current?.spine?.verificationRun(strictGateEventPayload(strictGate));
|
|
55880
56396
|
if (krakenGate.blocked) {
|
|
@@ -55890,8 +56406,17 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il turno continua dopo
|
|
|
55890
56406
|
krakenSuppressFinish = true;
|
|
55891
56407
|
}
|
|
55892
56408
|
}
|
|
55893
|
-
if (event.reason === "completed" && krakenRepairEnqueued && !evaluateStrictBuildGate("build").blocked) {
|
|
56409
|
+
if (event.reason === "completed" && krakenRepairEnqueued && !(await evaluateStrictBuildGate("build", { emit: krakenSpineEmit })).blocked) {
|
|
55894
56410
|
markRepairSucceeded();
|
|
56411
|
+
} else if (event.reason === "completed" && krakenRepairEnqueued) {
|
|
56412
|
+
const still = await evaluateStrictBuildGate("build", { emit: krakenSpineEmit });
|
|
56413
|
+
if (still.blocked) {
|
|
56414
|
+
appendSystem(
|
|
56415
|
+
setMessages,
|
|
56416
|
+
`[kraken] strict done: evidence still incomplete after repair (${still.evaluation?.unsatisfied.length ?? "?"} unresolved) \u2014 turn is NOT verified-complete`,
|
|
56417
|
+
Date.now()
|
|
56418
|
+
);
|
|
56419
|
+
}
|
|
55895
56420
|
}
|
|
55896
56421
|
if (!krakenSuppressFinish) progressRuntime.finish(event.reason);
|
|
55897
56422
|
}
|
|
@@ -56285,14 +56810,31 @@ async function dispatchCouncilPromptImpl(text, deps, overrides = {}) {
|
|
|
56285
56810
|
return { completionOk: false, ran: false };
|
|
56286
56811
|
}
|
|
56287
56812
|
setBusy(true);
|
|
56288
|
-
|
|
56289
|
-
|
|
56813
|
+
let councilHistory = getHistory();
|
|
56814
|
+
{
|
|
56815
|
+
const mirror = writerRef.current?.spine ?? null;
|
|
56816
|
+
if (mirror && mirror.status === "active") {
|
|
56817
|
+
const derived = await mirror.derivedPriorTurns();
|
|
56818
|
+
if (derived && derived.length > 0) {
|
|
56819
|
+
councilHistory = derivedModelSeed(derived);
|
|
56820
|
+
}
|
|
56821
|
+
}
|
|
56822
|
+
}
|
|
56823
|
+
const councilBudget = await applyBudgetPolicyAsync(councilHistory, getPhase(), {
|
|
56290
56824
|
model: envConfig.model
|
|
56291
56825
|
});
|
|
56292
56826
|
setHistory(councilBudget.history);
|
|
56293
56827
|
for (const w of councilBudget.warnings) {
|
|
56294
56828
|
appendSystem(setMessages, w, Date.now());
|
|
56295
56829
|
}
|
|
56830
|
+
if ((councilBudget.messagesRemoved ?? 0) > 0) {
|
|
56831
|
+
void writerRef.current?.append(
|
|
56832
|
+
createBrainEvent("session_compacted", sessionId2, {
|
|
56833
|
+
summary: councilBudget.compactSummary ?? "",
|
|
56834
|
+
messagesRemoved: councilBudget.messagesRemoved ?? 0
|
|
56835
|
+
})
|
|
56836
|
+
);
|
|
56837
|
+
}
|
|
56296
56838
|
const anchored = maybeAnchorShortAnswer(text);
|
|
56297
56839
|
const effectiveText = anchored ?? text;
|
|
56298
56840
|
appendSystem(
|
|
@@ -57894,7 +58436,7 @@ init_sessionManager();
|
|
|
57894
58436
|
// src/cli/gitOps.ts
|
|
57895
58437
|
import { execFile as execFile4 } from "node:child_process";
|
|
57896
58438
|
import { promisify as promisify3 } from "node:util";
|
|
57897
|
-
import
|
|
58439
|
+
import path48 from "node:path";
|
|
57898
58440
|
var execFileAsync3 = promisify3(execFile4);
|
|
57899
58441
|
async function git4(cwd, args) {
|
|
57900
58442
|
try {
|
|
@@ -57940,7 +58482,7 @@ async function undoWorkingChanges(opts = {}) {
|
|
|
57940
58482
|
};
|
|
57941
58483
|
}
|
|
57942
58484
|
function defaultProjectRoot() {
|
|
57943
|
-
return
|
|
58485
|
+
return path48.resolve(__dirname, "..", "..", "..");
|
|
57944
58486
|
}
|
|
57945
58487
|
|
|
57946
58488
|
// src/cli/slashHandlers/git.ts
|
|
@@ -58392,7 +58934,7 @@ import { promises as fs29 } from "node:fs";
|
|
|
58392
58934
|
init_zod();
|
|
58393
58935
|
init_taskTool();
|
|
58394
58936
|
import { promises as fs28 } from "node:fs";
|
|
58395
|
-
import
|
|
58937
|
+
import path52 from "node:path";
|
|
58396
58938
|
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
58397
58939
|
var CsvFanoutArgsSchema = external_exports.object({
|
|
58398
58940
|
csv_path: external_exports.string().min(1),
|
|
@@ -58486,8 +59028,8 @@ function resolveMaxConcurrency(env = process.env) {
|
|
|
58486
59028
|
}
|
|
58487
59029
|
async function runCsvFanout(args, deps, opts) {
|
|
58488
59030
|
const start = Date.now();
|
|
58489
|
-
const absCsv =
|
|
58490
|
-
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);
|
|
58491
59033
|
const { headers: headers2, rows } = await readCsv(absCsv);
|
|
58492
59034
|
if (headers2.length === 0) {
|
|
58493
59035
|
throw new Error(`kraken_csv_fanout: ${absCsv} is empty`);
|
|
@@ -58543,7 +59085,7 @@ async function runCsvFanout(args, deps, opts) {
|
|
|
58543
59085
|
errored += 1;
|
|
58544
59086
|
errors.push(`${row[args.id_column] ?? i}: ${res.error}`);
|
|
58545
59087
|
}
|
|
58546
|
-
await fs28.mkdir(
|
|
59088
|
+
await fs28.mkdir(path52.dirname(absOut), { recursive: true });
|
|
58547
59089
|
await queueWrite(serializeCsv(outHeaders, outputRecords));
|
|
58548
59090
|
}
|
|
58549
59091
|
}
|
|
@@ -58738,7 +59280,7 @@ function splitArgs(s) {
|
|
|
58738
59280
|
// src/cli/slashHandlers/krakenWorkbench.ts
|
|
58739
59281
|
init_messageHelpers();
|
|
58740
59282
|
import { promises as fs30 } from "node:fs";
|
|
58741
|
-
import
|
|
59283
|
+
import path53 from "node:path";
|
|
58742
59284
|
|
|
58743
59285
|
// src/cli/kraken/workbenchView.ts
|
|
58744
59286
|
var EMPTY = {
|
|
@@ -58855,14 +59397,14 @@ function formatWorkbenchForTerminal(p3) {
|
|
|
58855
59397
|
|
|
58856
59398
|
// src/cli/slashHandlers/krakenWorkbench.ts
|
|
58857
59399
|
async function handleKrakenWorkbench(ctx) {
|
|
58858
|
-
const dir =
|
|
59400
|
+
const dir = path53.join(ctx.cwd, ".zelari", "radio");
|
|
58859
59401
|
let latest = null;
|
|
58860
59402
|
let latestMtime = 0;
|
|
58861
59403
|
try {
|
|
58862
59404
|
const files = await fs30.readdir(dir);
|
|
58863
59405
|
for (const f of files) {
|
|
58864
59406
|
if (!f.startsWith("workbench-") || !f.endsWith(".md")) continue;
|
|
58865
|
-
const full =
|
|
59407
|
+
const full = path53.join(dir, f);
|
|
58866
59408
|
const stat = await fs30.stat(full);
|
|
58867
59409
|
if (stat.mtimeMs > latestMtime) {
|
|
58868
59410
|
latestMtime = stat.mtimeMs;
|
|
@@ -58879,10 +59421,10 @@ async function handleKrakenWorkbench(ctx) {
|
|
|
58879
59421
|
const parsed = parseWorkbench(content);
|
|
58880
59422
|
const rendered = formatWorkbenchForTerminal(parsed);
|
|
58881
59423
|
if (!rendered.trim()) {
|
|
58882
|
-
appendSystem(ctx.setMessages, `[kraken workbench] ${
|
|
59424
|
+
appendSystem(ctx.setMessages, `[kraken workbench] ${path53.basename(latest)}: (no nodes / no events yet)`);
|
|
58883
59425
|
return;
|
|
58884
59426
|
}
|
|
58885
|
-
appendSystem(ctx.setMessages, `[kraken workbench] ${
|
|
59427
|
+
appendSystem(ctx.setMessages, `[kraken workbench] ${path53.basename(latest)}:
|
|
58886
59428
|
${rendered}`);
|
|
58887
59429
|
}
|
|
58888
59430
|
|
|
@@ -59189,15 +59731,15 @@ ${result.output.split("\n").slice(-8).join("\n")}` : "";
|
|
|
59189
59731
|
// src/cli/slashHandlers/promoteMember.ts
|
|
59190
59732
|
init_messageHelpers();
|
|
59191
59733
|
import { promises as fs31 } from "node:fs";
|
|
59192
|
-
import
|
|
59734
|
+
import path56 from "node:path";
|
|
59193
59735
|
import os12 from "node:os";
|
|
59194
59736
|
async function handlePromoteMember(ctx, memberId) {
|
|
59195
59737
|
try {
|
|
59196
59738
|
const { promoteMember: promoteMember2 } = await Promise.resolve().then(() => (init_council(), council_exports));
|
|
59197
59739
|
const { skill, markdown } = promoteMember2(memberId);
|
|
59198
|
-
const skillDir = process.env.ANATHEMA_SKILL_DIR ??
|
|
59740
|
+
const skillDir = process.env.ANATHEMA_SKILL_DIR ?? path56.join(os12.homedir(), ".tmp", "zelari-code", "skills");
|
|
59199
59741
|
await fs31.mkdir(skillDir, { recursive: true });
|
|
59200
|
-
const filePath =
|
|
59742
|
+
const filePath = path56.join(skillDir, `${skill.id}.md`);
|
|
59201
59743
|
await fs31.writeFile(filePath, markdown, "utf8");
|
|
59202
59744
|
appendSystem(
|
|
59203
59745
|
ctx.setMessages,
|
|
@@ -59215,24 +59757,24 @@ async function handlePromoteMember(ctx, memberId) {
|
|
|
59215
59757
|
|
|
59216
59758
|
// src/cli/branchManager.ts
|
|
59217
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";
|
|
59218
|
-
import
|
|
59760
|
+
import path57 from "node:path";
|
|
59219
59761
|
import os13 from "node:os";
|
|
59220
59762
|
var META_FILENAME = "meta.json";
|
|
59221
59763
|
var SESSIONS_SUBDIR = "sessions";
|
|
59222
59764
|
function getBranchesBaseDir() {
|
|
59223
|
-
return process.env.ANATHEMA_BRANCHES_DIR ??
|
|
59765
|
+
return process.env.ANATHEMA_BRANCHES_DIR ?? path57.join(os13.homedir(), ".tmp", "zelari-code", "branches");
|
|
59224
59766
|
}
|
|
59225
59767
|
function getSessionsBaseDir() {
|
|
59226
|
-
return process.env.ANATHEMA_SESSIONS_DIR ??
|
|
59768
|
+
return process.env.ANATHEMA_SESSIONS_DIR ?? path57.join(os13.homedir(), ".tmp", "zelari-code", "sessions");
|
|
59227
59769
|
}
|
|
59228
59770
|
function branchPathFor(name, baseDir) {
|
|
59229
|
-
return
|
|
59771
|
+
return path57.join(baseDir, name);
|
|
59230
59772
|
}
|
|
59231
59773
|
function metaPathFor(name, baseDir) {
|
|
59232
|
-
return
|
|
59774
|
+
return path57.join(baseDir, name, META_FILENAME);
|
|
59233
59775
|
}
|
|
59234
59776
|
function sessionsPathFor(name, baseDir) {
|
|
59235
|
-
return
|
|
59777
|
+
return path57.join(baseDir, name, SESSIONS_SUBDIR);
|
|
59236
59778
|
}
|
|
59237
59779
|
function readBranchMeta(name, baseDir) {
|
|
59238
59780
|
const metaPath = metaPathFor(name, baseDir);
|
|
@@ -59257,7 +59799,7 @@ function readBranchMeta(name, baseDir) {
|
|
|
59257
59799
|
}
|
|
59258
59800
|
function writeBranchMeta(name, baseDir, meta3) {
|
|
59259
59801
|
const metaPath = metaPathFor(name, baseDir);
|
|
59260
|
-
mkdirSync19(
|
|
59802
|
+
mkdirSync19(path57.dirname(metaPath), { recursive: true });
|
|
59261
59803
|
writeFileSync23(metaPath, JSON.stringify(meta3, null, 2), "utf-8");
|
|
59262
59804
|
}
|
|
59263
59805
|
async function countSessions(name, baseDir) {
|
|
@@ -59308,14 +59850,14 @@ async function createBranch(name, fromSessionId, baseDir = getBranchesBaseDir(),
|
|
|
59308
59850
|
if (branchExists(name, baseDir)) {
|
|
59309
59851
|
throw new BranchAlreadyExistsError(name);
|
|
59310
59852
|
}
|
|
59311
|
-
const sourcePath =
|
|
59853
|
+
const sourcePath = path57.join(sessionsBaseDir, `${fromSessionId}.jsonl`);
|
|
59312
59854
|
if (!existsSync44(sourcePath)) {
|
|
59313
59855
|
throw new SessionNotFoundError(`Source session "${fromSessionId}" not found at ${sourcePath}`);
|
|
59314
59856
|
}
|
|
59315
59857
|
const branchPath = branchPathFor(name, baseDir);
|
|
59316
59858
|
const branchSessionsPath = sessionsPathFor(name, baseDir);
|
|
59317
59859
|
mkdirSync19(branchSessionsPath, { recursive: true });
|
|
59318
|
-
const destPath =
|
|
59860
|
+
const destPath = path57.join(branchSessionsPath, `${fromSessionId}.jsonl`);
|
|
59319
59861
|
await fs32.copyFile(sourcePath, destPath);
|
|
59320
59862
|
const meta3 = {
|
|
59321
59863
|
name,
|
|
@@ -59419,14 +59961,14 @@ async function handleBranchCheckout(ctx, branchName) {
|
|
|
59419
59961
|
// src/cli/slashHandlers/workspace.ts
|
|
59420
59962
|
init_messageHelpers();
|
|
59421
59963
|
import { promises as fs33 } from "node:fs";
|
|
59422
|
-
import
|
|
59964
|
+
import path58 from "node:path";
|
|
59423
59965
|
async function handleWorkspaceShow(ctx, what) {
|
|
59424
59966
|
try {
|
|
59425
|
-
const zelari =
|
|
59967
|
+
const zelari = path58.join(process.cwd(), ".zelari");
|
|
59426
59968
|
let content;
|
|
59427
59969
|
switch (what) {
|
|
59428
59970
|
case "plan": {
|
|
59429
|
-
const planPath =
|
|
59971
|
+
const planPath = path58.join(zelari, "plan.md");
|
|
59430
59972
|
try {
|
|
59431
59973
|
content = await fs33.readFile(planPath, "utf-8");
|
|
59432
59974
|
} catch {
|
|
@@ -59435,7 +59977,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
59435
59977
|
break;
|
|
59436
59978
|
}
|
|
59437
59979
|
case "decisions": {
|
|
59438
|
-
const decisionsDir =
|
|
59980
|
+
const decisionsDir = path58.join(zelari, "decisions");
|
|
59439
59981
|
try {
|
|
59440
59982
|
const files = (await fs33.readdir(decisionsDir)).filter((f) => f.endsWith(".md")).sort();
|
|
59441
59983
|
if (files.length === 0) {
|
|
@@ -59445,7 +59987,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
59445
59987
|
`];
|
|
59446
59988
|
const { parseFrontmatter: parseFrontmatter2 } = await Promise.resolve().then(() => (init_storage(), storage_exports));
|
|
59447
59989
|
for (const f of files) {
|
|
59448
|
-
const raw = await fs33.readFile(
|
|
59990
|
+
const raw = await fs33.readFile(path58.join(decisionsDir, f), "utf-8");
|
|
59449
59991
|
const { meta: meta3, body } = parseFrontmatter2(raw);
|
|
59450
59992
|
const title = meta3.title ?? body.split("\n")[0]?.replace(/^#\s*/, "").trim() ?? f;
|
|
59451
59993
|
lines.push(`- **${f.replace(/\.md$/, "")}** [${meta3.status ?? "unknown"}] ${title}`);
|
|
@@ -59458,7 +60000,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
59458
60000
|
break;
|
|
59459
60001
|
}
|
|
59460
60002
|
case "risks": {
|
|
59461
|
-
const risksPath =
|
|
60003
|
+
const risksPath = path58.join(zelari, "risks.md");
|
|
59462
60004
|
try {
|
|
59463
60005
|
content = await fs33.readFile(risksPath, "utf-8");
|
|
59464
60006
|
} catch {
|
|
@@ -59467,7 +60009,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
59467
60009
|
break;
|
|
59468
60010
|
}
|
|
59469
60011
|
case "agents": {
|
|
59470
|
-
const agentsPath =
|
|
60012
|
+
const agentsPath = path58.join(process.cwd(), "AGENTS.MD");
|
|
59471
60013
|
try {
|
|
59472
60014
|
content = await fs33.readFile(agentsPath, "utf-8");
|
|
59473
60015
|
} catch {
|
|
@@ -59476,7 +60018,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
59476
60018
|
break;
|
|
59477
60019
|
}
|
|
59478
60020
|
case "docs": {
|
|
59479
|
-
const docsDir =
|
|
60021
|
+
const docsDir = path58.join(zelari, "docs");
|
|
59480
60022
|
try {
|
|
59481
60023
|
const files = (await fs33.readdir(docsDir)).filter((f) => f.endsWith(".md")).sort();
|
|
59482
60024
|
content = files.length ? `# Docs (${files.length})
|
|
@@ -59518,7 +60060,7 @@ async function handleWorkspaceReset(ctx, force) {
|
|
|
59518
60060
|
return;
|
|
59519
60061
|
}
|
|
59520
60062
|
try {
|
|
59521
|
-
const target =
|
|
60063
|
+
const target = path58.join(process.cwd(), ".zelari");
|
|
59522
60064
|
await fs33.rm(target, { recursive: true, force: true });
|
|
59523
60065
|
appendSystem(ctx.setMessages, "[workspace] .zelari/ removed");
|
|
59524
60066
|
} catch (err) {
|
|
@@ -59530,7 +60072,7 @@ async function handleWorkspaceReset(ctx, force) {
|
|
|
59530
60072
|
init_provider2();
|
|
59531
60073
|
|
|
59532
60074
|
// src/cli/slashHandlers/skills.ts
|
|
59533
|
-
import
|
|
60075
|
+
import path59 from "node:path";
|
|
59534
60076
|
import os14 from "node:os";
|
|
59535
60077
|
|
|
59536
60078
|
// src/cli/skillHistory.ts
|
|
@@ -59659,7 +60201,7 @@ function handleSkillPicker(ctx, skills, openPicker, fallbackMessage) {
|
|
|
59659
60201
|
});
|
|
59660
60202
|
}
|
|
59661
60203
|
async function handleSkillStats(ctx, skillId) {
|
|
59662
|
-
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");
|
|
59663
60205
|
try {
|
|
59664
60206
|
const records = await readSkillHistory(historyFile);
|
|
59665
60207
|
const stats = getSkillStats(records, skillId);
|
|
@@ -59675,7 +60217,7 @@ async function handleSkillCompare(ctx, ids, fallbackMessage) {
|
|
|
59675
60217
|
appendSystem(ctx.setMessages, fallbackMessage ?? "[skill-compare] missing args");
|
|
59676
60218
|
return;
|
|
59677
60219
|
}
|
|
59678
|
-
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");
|
|
59679
60221
|
try {
|
|
59680
60222
|
const formatted = await compareSkillsFromFile(ids[0], ids[1], historyFile);
|
|
59681
60223
|
appendSystem(ctx.setMessages, formatted);
|
|
@@ -61219,7 +61761,7 @@ function createStreamScrubber2() {
|
|
|
61219
61761
|
init_taskTool();
|
|
61220
61762
|
init_sessionTodos();
|
|
61221
61763
|
import { promises as fs36 } from "node:fs";
|
|
61222
|
-
import
|
|
61764
|
+
import path61 from "node:path";
|
|
61223
61765
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
61224
61766
|
init_headlessSpine();
|
|
61225
61767
|
async function runHeadless(opts) {
|
|
@@ -61376,7 +61918,7 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
61376
61918
|
try {
|
|
61377
61919
|
let preflightGraph;
|
|
61378
61920
|
if (opts.runPlan && opts.runPlan.trim() !== "") {
|
|
61379
|
-
const planPath =
|
|
61921
|
+
const planPath = path61.join(cwd, ".zelari", "radio", `plan-${opts.runPlan}.json`);
|
|
61380
61922
|
log(`loading pre-flight plan: ${planPath}`);
|
|
61381
61923
|
let raw;
|
|
61382
61924
|
try {
|
|
@@ -61416,8 +61958,8 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
61416
61958
|
log(formatKrakenGraphAscii2(graph));
|
|
61417
61959
|
if (opts.planOnly) {
|
|
61418
61960
|
const planId = randomUUID6();
|
|
61419
|
-
const planDir =
|
|
61420
|
-
const planPath =
|
|
61961
|
+
const planDir = path61.join(cwd, ".zelari", "radio");
|
|
61962
|
+
const planPath = path61.join(planDir, `plan-${planId}.json`);
|
|
61421
61963
|
await fs36.mkdir(planDir, { recursive: true });
|
|
61422
61964
|
await fs36.writeFile(
|
|
61423
61965
|
planPath,
|
|
@@ -61550,6 +62092,7 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
61550
62092
|
workspace: process.cwd()
|
|
61551
62093
|
});
|
|
61552
62094
|
const seededHistory = await seedHeadlessModelHistory(spine, opts.history);
|
|
62095
|
+
emitEvent(sessionStartedEvent(spine));
|
|
61553
62096
|
if (opts.task) spine.userMessage(opts.task);
|
|
61554
62097
|
resetKrakenCandidates();
|
|
61555
62098
|
resetKrakenTurnMetrics();
|
|
@@ -61862,8 +62405,9 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
61862
62405
|
emittedWrites: pass.emittedWrites + retry.emittedWrites
|
|
61863
62406
|
};
|
|
61864
62407
|
}
|
|
62408
|
+
let strictExit = 0;
|
|
61865
62409
|
if (pass.finalReason === "completed" && pass.exitCode === 0 && opts.mode === "kraken" && isKrakenSelectionEnabled() && !planModeFromOpts(opts)) {
|
|
61866
|
-
const strictGate = evaluateStrictBuildGate("build");
|
|
62410
|
+
const strictGate = await evaluateStrictBuildGate("build", { emit: (input) => spine.appendEvent(input) });
|
|
61867
62411
|
const gate = strictGate.gate;
|
|
61868
62412
|
const verificationPayload = strictGateEventPayload(strictGate);
|
|
61869
62413
|
spine.verificationRun(verificationPayload);
|
|
@@ -61896,13 +62440,20 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
61896
62440
|
successfulWrites: pass.successfulWrites + repair.successfulWrites,
|
|
61897
62441
|
emittedWrites: pass.emittedWrites + repair.emittedWrites
|
|
61898
62442
|
};
|
|
61899
|
-
const after = evaluateStrictBuildGate("build");
|
|
62443
|
+
const after = await evaluateStrictBuildGate("build", { emit: (input) => spine.appendEvent(input) });
|
|
61900
62444
|
const afterPayload = strictGateEventPayload(after);
|
|
61901
62445
|
spine.verificationRun(afterPayload);
|
|
61902
62446
|
if (opts.output === "json") {
|
|
61903
62447
|
emitEvent({ type: "verification_run", ...afterPayload });
|
|
61904
62448
|
}
|
|
61905
62449
|
if (!after.blocked) markRepairSucceeded();
|
|
62450
|
+
else {
|
|
62451
|
+
strictExit = strictGateExitCode(after);
|
|
62452
|
+
const gateMsg = `[headless] Kraken BUILD: strict completion gate still blocked after repair pass \u2014 closing non-success (exit ${strictExit}): ${after.summary}`;
|
|
62453
|
+
if (opts.output === "json") emitEvent({ type: "log", message: gateMsg });
|
|
62454
|
+
else process.stderr.write(`[zelari-code --headless] ${gateMsg}
|
|
62455
|
+
`);
|
|
62456
|
+
}
|
|
61906
62457
|
}
|
|
61907
62458
|
}
|
|
61908
62459
|
progressRuntime.finish(pass.finalReason);
|
|
@@ -61951,7 +62502,8 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
61951
62502
|
}
|
|
61952
62503
|
}
|
|
61953
62504
|
try {
|
|
61954
|
-
|
|
62505
|
+
const closeStatus = pass.finalReason === "error" ? "error" : strictExit !== 0 ? "stopped" : "completed";
|
|
62506
|
+
await spine.close(closeStatus);
|
|
61955
62507
|
} catch {
|
|
61956
62508
|
}
|
|
61957
62509
|
if (opts.exportSessionPath) {
|
|
@@ -61960,7 +62512,7 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
61960
62512
|
if (json2) {
|
|
61961
62513
|
if (opts.exportSessionPath === "-") process.stdout.write(json2 + "\n");
|
|
61962
62514
|
else {
|
|
61963
|
-
await fs36.mkdir(
|
|
62515
|
+
await fs36.mkdir(path61.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
61964
62516
|
await fs36.writeFile(opts.exportSessionPath, json2, "utf8");
|
|
61965
62517
|
}
|
|
61966
62518
|
}
|
|
@@ -61968,6 +62520,7 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
61968
62520
|
}
|
|
61969
62521
|
}
|
|
61970
62522
|
if (pass.finalReason === "error") return 3;
|
|
62523
|
+
if (strictExit !== 0) return strictExit;
|
|
61971
62524
|
return pass.exitCode;
|
|
61972
62525
|
}
|
|
61973
62526
|
async function buildCouncilToolRegistry(planMode, opts) {
|
|
@@ -62007,6 +62560,7 @@ async function runHeadlessCouncil(opts, provider, model, providerStream) {
|
|
|
62007
62560
|
workspace: process.cwd()
|
|
62008
62561
|
});
|
|
62009
62562
|
const seededHistory = await seedHeadlessModelHistory(spine, opts.history);
|
|
62563
|
+
emitEvent(sessionStartedEvent(spine));
|
|
62010
62564
|
if (opts.task) spine.userMessage(opts.task);
|
|
62011
62565
|
const { shouldAllowCouncilBuild: shouldAllowCouncilBuild2 } = await Promise.resolve().then(() => (init_buildPolicy(), buildPolicy_exports));
|
|
62012
62566
|
let councilRunMode = planModeFromOpts(opts) ? "design-phase" : "implementation";
|
|
@@ -62125,7 +62679,7 @@ async function runHeadlessCouncil(opts, provider, model, providerStream) {
|
|
|
62125
62679
|
if (json2) {
|
|
62126
62680
|
if (opts.exportSessionPath === "-") process.stdout.write(json2 + "\n");
|
|
62127
62681
|
else {
|
|
62128
|
-
await fs36.mkdir(
|
|
62682
|
+
await fs36.mkdir(path61.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
62129
62683
|
await fs36.writeFile(opts.exportSessionPath, json2, "utf8");
|
|
62130
62684
|
}
|
|
62131
62685
|
}
|
|
@@ -62144,6 +62698,7 @@ async function runHeadlessZelari(opts, provider, model, providerStream) {
|
|
|
62144
62698
|
workspace: projectRoot
|
|
62145
62699
|
});
|
|
62146
62700
|
const seededHistory = await seedHeadlessModelHistory(spine, opts.history);
|
|
62701
|
+
emitEvent(sessionStartedEvent(spine));
|
|
62147
62702
|
if (opts.task) spine.userMessage(opts.task);
|
|
62148
62703
|
spine.missionPhase("design", "mission-start");
|
|
62149
62704
|
const { buildMissionBrief: buildMissionBrief2 } = await Promise.resolve().then(() => (init_council(), council_exports));
|
|
@@ -62210,6 +62765,13 @@ ${JSON.stringify({ deliverable: brief.deliverableThisMission, mvp: brief.sliceMv
|
|
|
62210
62765
|
emit,
|
|
62211
62766
|
buildViaAgent,
|
|
62212
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
|
+
}),
|
|
62213
62775
|
runSlice: async ({
|
|
62214
62776
|
userMessage: slicePrompt,
|
|
62215
62777
|
runMode,
|
|
@@ -62414,8 +62976,22 @@ ${ragContext}` : slicePrompt;
|
|
|
62414
62976
|
});
|
|
62415
62977
|
if (state3.status === "error") exitCode = exitCode || 3;
|
|
62416
62978
|
else if (state3.status === "success") {
|
|
62417
|
-
|
|
62418
|
-
|
|
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
|
+
}
|
|
62419
62995
|
} else if (state3.status === "stalled" || state3.status === "stopped") {
|
|
62420
62996
|
exitCode = exitCode || 0;
|
|
62421
62997
|
spine.missionPhase("verification", `mission-${state3.status}`);
|
|
@@ -62443,7 +63019,7 @@ ${ragContext}` : slicePrompt;
|
|
|
62443
63019
|
if (json2) {
|
|
62444
63020
|
if (opts.exportSessionPath === "-") process.stdout.write(json2 + "\n");
|
|
62445
63021
|
else {
|
|
62446
|
-
await fs36.mkdir(
|
|
63022
|
+
await fs36.mkdir(path61.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
62447
63023
|
await fs36.writeFile(opts.exportSessionPath, json2, "utf8");
|
|
62448
63024
|
}
|
|
62449
63025
|
}
|
|
@@ -62657,8 +63233,8 @@ function normalizeDraft(raw, sourceUrl, provider, model) {
|
|
|
62657
63233
|
let name = String(o.name ?? "").trim().toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64);
|
|
62658
63234
|
if (!name || !/^[a-z0-9][a-z0-9-]{0,63}$/.test(name)) {
|
|
62659
63235
|
try {
|
|
62660
|
-
const
|
|
62661
|
-
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";
|
|
62662
63238
|
} catch {
|
|
62663
63239
|
name = "imported-skill";
|
|
62664
63240
|
}
|