zelari-code 2.5.0 → 2.6.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/budget/budgetRuntime.js +115 -0
- package/dist/cli/budget/budgetRuntime.js.map +1 -0
- package/dist/cli/budget/modelContextBuilder.js +11 -0
- package/dist/cli/budget/modelContextBuilder.js.map +1 -1
- package/dist/cli/budget/resourceLedger.js +61 -0
- package/dist/cli/budget/resourceLedger.js.map +1 -0
- package/dist/cli/budget/resourceSnapshot.js +43 -0
- package/dist/cli/budget/resourceSnapshot.js.map +1 -0
- package/dist/cli/gauntlet/policy.js +9 -0
- package/dist/cli/gauntlet/policy.js.map +1 -1
- package/dist/cli/harnessManifest.js +62 -0
- package/dist/cli/harnessManifest.js.map +1 -0
- package/dist/cli/headlessSpine.js +15 -0
- package/dist/cli/headlessSpine.js.map +1 -1
- package/dist/cli/hooks/useChatTurn.js +4 -0
- package/dist/cli/hooks/useChatTurn.js.map +1 -1
- package/dist/cli/kraken/taskContract.js +44 -0
- package/dist/cli/kraken/taskContract.js.map +1 -0
- package/dist/cli/main.bundled.js +1223 -303
- package/dist/cli/main.bundled.js.map +4 -4
- package/dist/cli/runHeadless.js +5 -0
- package/dist/cli/runHeadless.js.map +1 -1
- package/dist/cli/sessionSpine.js +118 -4
- package/dist/cli/sessionSpine.js.map +1 -1
- package/package.json +5 -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, path65) {
|
|
3292
|
+
if (!path65)
|
|
3293
3293
|
return obj;
|
|
3294
|
-
return
|
|
3294
|
+
return path65.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(path65, 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(path65);
|
|
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, path65 = []) => {
|
|
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 }, [...path65, ...issue2.path]));
|
|
3848
3848
|
} else if (issue2.code === "invalid_key") {
|
|
3849
|
-
processError({ issues: issue2.issues }, [...
|
|
3849
|
+
processError({ issues: issue2.issues }, [...path65, ...issue2.path]);
|
|
3850
3850
|
} else if (issue2.code === "invalid_element") {
|
|
3851
|
-
processError({ issues: issue2.issues }, [...
|
|
3851
|
+
processError({ issues: issue2.issues }, [...path65, ...issue2.path]);
|
|
3852
3852
|
} else {
|
|
3853
|
-
const fullpath = [...
|
|
3853
|
+
const fullpath = [...path65, ...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, path65 = []) => {
|
|
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 }, [...path65, ...issue2.path]));
|
|
3885
3885
|
} else if (issue2.code === "invalid_key") {
|
|
3886
|
-
processError({ issues: issue2.issues }, [...
|
|
3886
|
+
processError({ issues: issue2.issues }, [...path65, ...issue2.path]);
|
|
3887
3887
|
} else if (issue2.code === "invalid_element") {
|
|
3888
|
-
processError({ issues: issue2.issues }, [...
|
|
3888
|
+
processError({ issues: issue2.issues }, [...path65, ...issue2.path]);
|
|
3889
3889
|
} else {
|
|
3890
|
-
const fullpath = [...
|
|
3890
|
+
const fullpath = [...path65, ...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 path65 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
3923
|
+
for (const seg of path65) {
|
|
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 path65 = ref.slice(1).split("/").filter(Boolean);
|
|
17427
|
+
if (path65.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 (path65[0] === defsKey) {
|
|
17432
|
+
const key = path65[1];
|
|
17433
17433
|
if (!key || !ctx.defs[key]) {
|
|
17434
17434
|
throw new Error(`Reference not found: ${ref}`);
|
|
17435
17435
|
}
|
|
@@ -19765,11 +19765,11 @@ var init_tools = __esm({
|
|
|
19765
19765
|
if (!ctx.addDocument)
|
|
19766
19766
|
return "Knowledge vault tool not available.";
|
|
19767
19767
|
const title = args["title"] || "New Document";
|
|
19768
|
-
const
|
|
19768
|
+
const path65 = args["path"] || `notes/${title.toLowerCase().replace(/[^a-z0-9]+/g, "-")}`;
|
|
19769
19769
|
const content = args["content"] || "";
|
|
19770
19770
|
const tags = args["tags"] || [];
|
|
19771
19771
|
ctx.addDocument({
|
|
19772
|
-
path:
|
|
19772
|
+
path: path65,
|
|
19773
19773
|
title,
|
|
19774
19774
|
content,
|
|
19775
19775
|
format: "markdown",
|
|
@@ -19778,7 +19778,7 @@ var init_tools = __esm({
|
|
|
19778
19778
|
workspaceId: ctx.workspaceId
|
|
19779
19779
|
});
|
|
19780
19780
|
ctx.addActivity("vault", "created document", title);
|
|
19781
|
-
return `Document "${title}" created at "${
|
|
19781
|
+
return `Document "${title}" created at "${path65}".`;
|
|
19782
19782
|
}
|
|
19783
19783
|
}
|
|
19784
19784
|
];
|
|
@@ -22177,6 +22177,19 @@ var init_AgentHarness = __esm({
|
|
|
22177
22177
|
* via Promise.all (chunked by ZELARI_MAX_PARALLEL_TOOLS, default 6); write/
|
|
22178
22178
|
* execute tools run one-at-a-time in order.
|
|
22179
22179
|
*/
|
|
22180
|
+
/**
|
|
22181
|
+
* v2.6 Phase 3 resource seam: consult the host-owned pre-dispatch gate.
|
|
22182
|
+
* Degrade-and-stop — a throwing gate NEVER blocks a tool call.
|
|
22183
|
+
*/
|
|
22184
|
+
checkToolCallGate(toolName, args) {
|
|
22185
|
+
if (!this.config.toolCallGate)
|
|
22186
|
+
return { allowed: true };
|
|
22187
|
+
try {
|
|
22188
|
+
return this.config.toolCallGate(toolName, args) ?? { allowed: true };
|
|
22189
|
+
} catch {
|
|
22190
|
+
return { allowed: true };
|
|
22191
|
+
}
|
|
22192
|
+
}
|
|
22180
22193
|
async executePendingTools(pending, maxToolCalls) {
|
|
22181
22194
|
const out = new Array(pending.length);
|
|
22182
22195
|
const maxParallel = Math.max(1, Number.parseInt(process.env.ZELARI_MAX_PARALLEL_TOOLS ?? "6", 10) || 6);
|
|
@@ -22189,6 +22202,14 @@ var init_AgentHarness = __esm({
|
|
|
22189
22202
|
durationMs: 0
|
|
22190
22203
|
};
|
|
22191
22204
|
}
|
|
22205
|
+
const gate = this.checkToolCallGate(p3.toolName, p3.args);
|
|
22206
|
+
if (!gate.allowed) {
|
|
22207
|
+
return {
|
|
22208
|
+
content: `[resource-gate] ${gate.reason ?? "denied by resource policy"} Prioritize verification/repair actions (test, typecheck, build, read failures) or finalize honestly.`,
|
|
22209
|
+
isError: true,
|
|
22210
|
+
durationMs: 0
|
|
22211
|
+
};
|
|
22212
|
+
}
|
|
22192
22213
|
const callKey = hashToolCall(p3.toolName, p3.args);
|
|
22193
22214
|
const nextCount = (this.toolCallCounts.get(callKey) ?? 0) + 1;
|
|
22194
22215
|
this.toolCallCounts.set(callKey, nextCount);
|
|
@@ -22708,6 +22729,21 @@ ${cached2}`
|
|
|
22708
22729
|
});
|
|
22709
22730
|
this.emit(startEv);
|
|
22710
22731
|
yield startEv;
|
|
22732
|
+
const gate = this.checkToolCallGate(tt.name, tt.args);
|
|
22733
|
+
if (!gate.allowed) {
|
|
22734
|
+
const denied = `[resource-gate] ${gate.reason ?? "denied by resource policy"} Prioritize verification/repair actions (test, typecheck, build, read failures) or finalize honestly.`;
|
|
22735
|
+
const denyEv = createBrainEvent("tool_execution_end", this.sessionId, {
|
|
22736
|
+
toolCallId,
|
|
22737
|
+
result: denied,
|
|
22738
|
+
isError: true,
|
|
22739
|
+
durationMs: 0
|
|
22740
|
+
});
|
|
22741
|
+
this.emit(denyEv);
|
|
22742
|
+
yield denyEv;
|
|
22743
|
+
turnToolResults.push({ toolCallId, content: denied });
|
|
22744
|
+
executedAny = true;
|
|
22745
|
+
continue;
|
|
22746
|
+
}
|
|
22711
22747
|
let resultStr = "";
|
|
22712
22748
|
let isError = false;
|
|
22713
22749
|
const startMs = Date.now();
|
|
@@ -24238,11 +24274,11 @@ var init_synthesisAudit = __esm({
|
|
|
24238
24274
|
import { existsSync as existsSync7, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "node:fs";
|
|
24239
24275
|
import { join as join2 } from "node:path";
|
|
24240
24276
|
function loadNfrSpec(zelariRoot) {
|
|
24241
|
-
const
|
|
24242
|
-
if (!existsSync7(
|
|
24277
|
+
const path65 = join2(zelariRoot, "nfr-spec.json");
|
|
24278
|
+
if (!existsSync7(path65))
|
|
24243
24279
|
return null;
|
|
24244
24280
|
try {
|
|
24245
|
-
const raw = JSON.parse(readFileSync7(
|
|
24281
|
+
const raw = JSON.parse(readFileSync7(path65, "utf8"));
|
|
24246
24282
|
if (raw.version !== 1 || !Array.isArray(raw.targets))
|
|
24247
24283
|
return null;
|
|
24248
24284
|
return raw;
|
|
@@ -26548,9 +26584,9 @@ var init_types4 = __esm({
|
|
|
26548
26584
|
import { readFileSync as readFileSync12 } from "node:fs";
|
|
26549
26585
|
import { join as join8 } from "node:path";
|
|
26550
26586
|
function readLessonsDeduped(zelariRoot) {
|
|
26551
|
-
const
|
|
26587
|
+
const path65 = join8(zelariRoot, LESSONS_FILE);
|
|
26552
26588
|
try {
|
|
26553
|
-
const raw = readFileSync12(
|
|
26589
|
+
const raw = readFileSync12(path65, "utf8");
|
|
26554
26590
|
const byId = /* @__PURE__ */ new Map();
|
|
26555
26591
|
for (const line of raw.split(/\r?\n/)) {
|
|
26556
26592
|
if (!line.trim())
|
|
@@ -26651,8 +26687,8 @@ function keywordsFrom(check2, signature) {
|
|
|
26651
26687
|
return [.../* @__PURE__ */ new Set([...fromId, ...words])].slice(0, 12);
|
|
26652
26688
|
}
|
|
26653
26689
|
function writeLesson(zelariRoot, lesson) {
|
|
26654
|
-
const
|
|
26655
|
-
appendFileSync(
|
|
26690
|
+
const path65 = join9(zelariRoot, LESSONS_FILE);
|
|
26691
|
+
appendFileSync(path65, `${JSON.stringify(lesson)}
|
|
26656
26692
|
`, "utf8");
|
|
26657
26693
|
}
|
|
26658
26694
|
function findSimilar(lessons, signature) {
|
|
@@ -27266,9 +27302,9 @@ function findCycle(nodes) {
|
|
|
27266
27302
|
if (color.get(start) !== WHITE)
|
|
27267
27303
|
continue;
|
|
27268
27304
|
const stack = [[start, 0]];
|
|
27269
|
-
const
|
|
27305
|
+
const path65 = [];
|
|
27270
27306
|
color.set(start, GRAY);
|
|
27271
|
-
|
|
27307
|
+
path65.push(start);
|
|
27272
27308
|
while (stack.length > 0) {
|
|
27273
27309
|
const top = stack[stack.length - 1];
|
|
27274
27310
|
const [id, idx] = top;
|
|
@@ -27281,17 +27317,17 @@ function findCycle(nodes) {
|
|
|
27281
27317
|
continue;
|
|
27282
27318
|
const c = color.get(dep);
|
|
27283
27319
|
if (c === GRAY) {
|
|
27284
|
-
const at =
|
|
27285
|
-
return [...
|
|
27320
|
+
const at = path65.indexOf(dep);
|
|
27321
|
+
return [...path65.slice(at), dep];
|
|
27286
27322
|
}
|
|
27287
27323
|
if (c === WHITE) {
|
|
27288
27324
|
color.set(dep, GRAY);
|
|
27289
|
-
|
|
27325
|
+
path65.push(dep);
|
|
27290
27326
|
stack.push([dep, 0]);
|
|
27291
27327
|
}
|
|
27292
27328
|
} else {
|
|
27293
27329
|
color.set(id, BLACK);
|
|
27294
|
-
|
|
27330
|
+
path65.pop();
|
|
27295
27331
|
stack.pop();
|
|
27296
27332
|
}
|
|
27297
27333
|
}
|
|
@@ -28211,8 +28247,8 @@ var init_runner = __esm({
|
|
|
28211
28247
|
failed: [...this.tentaclesById.values()].filter((r) => r.status === "error"),
|
|
28212
28248
|
pending: []
|
|
28213
28249
|
};
|
|
28214
|
-
const
|
|
28215
|
-
this.host.log(`checkpoint: ${label ?? "auto"} \u2192 ${
|
|
28250
|
+
const path65 = await this.host.saveSnapshot(snapshot, ".zelari/kraken/snapshots");
|
|
28251
|
+
this.host.log(`checkpoint: ${label ?? "auto"} \u2192 ${path65}`);
|
|
28216
28252
|
return snapshot;
|
|
28217
28253
|
}
|
|
28218
28254
|
callLog(msg, data) {
|
|
@@ -28300,6 +28336,10 @@ var init_types8 = __esm({
|
|
|
28300
28336
|
"session.resumed",
|
|
28301
28337
|
"session.ended",
|
|
28302
28338
|
"session.forked",
|
|
28339
|
+
// 2.6 Track A (harness manifest): canonical harness fingerprint recorded
|
|
28340
|
+
// once at session start / manifest change. State-only (never model-surface):
|
|
28341
|
+
// data = {manifest, manifestHash}. Schema review per ADR-0021.
|
|
28342
|
+
"session.harness_manifest",
|
|
28303
28343
|
"user.message",
|
|
28304
28344
|
"assistant.message",
|
|
28305
28345
|
"tool.call",
|
|
@@ -28310,6 +28350,11 @@ var init_types8 = __esm({
|
|
|
28310
28350
|
"session.compacted",
|
|
28311
28351
|
"task.created",
|
|
28312
28352
|
"task.updated",
|
|
28353
|
+
// 2.6 Track A (doc §14): first-class task contract. Append-only,
|
|
28354
|
+
// monotone versioning (task.contract_updated supersedes, never rewrites).
|
|
28355
|
+
// State-only: compaction projects it into CompactionStateSnapshot.
|
|
28356
|
+
"task.contract",
|
|
28357
|
+
"task.contract_updated",
|
|
28313
28358
|
"kraken.task",
|
|
28314
28359
|
"council.member",
|
|
28315
28360
|
"mission.phase",
|
|
@@ -28322,6 +28367,12 @@ var init_types8 = __esm({
|
|
|
28322
28367
|
// the session-log anchor EvidenceRef.seq points at (command output, fs
|
|
28323
28368
|
// observation, digest). Not model-surface. Schema review per ADR-0021.
|
|
28324
28369
|
"verification.evidence",
|
|
28370
|
+
// 2.6 Track B (resource-aware execution, doc §9-§12): host-owned resource
|
|
28371
|
+
// state. `resource.snapshot` is model-surface with LATEST-ONLY projection
|
|
28372
|
+
// (doc §10.2 — see modelSurface.ts); limit/reserve events are state-only.
|
|
28373
|
+
"resource.snapshot",
|
|
28374
|
+
"resource.limit_reached",
|
|
28375
|
+
"resource.reserve_entered",
|
|
28325
28376
|
"note"
|
|
28326
28377
|
];
|
|
28327
28378
|
SessionEventEnvelopeSchema = external_exports.object({
|
|
@@ -28479,9 +28530,13 @@ function buildCompactionStateSnapshot(events, toSeq) {
|
|
|
28479
28530
|
...typeof lastMissionAdvice?.data.recommendation === "string" ? { recommendation: lastMissionAdvice.data.recommendation } : {},
|
|
28480
28531
|
...stringsOf(lastMissionAdvice?.data.blockers).length > 0 ? { blockers: stringsOf(lastMissionAdvice?.data.blockers) } : {}
|
|
28481
28532
|
} : void 0;
|
|
28533
|
+
const latestContractEvent = [...scoped].reverse().find((event) => event.kind === "task.contract" || event.kind === "task.contract_updated");
|
|
28534
|
+
const contractRaw = latestContractEvent && typeof latestContractEvent.data.contract === "object" ? latestContractEvent.data.contract : void 0;
|
|
28535
|
+
const contractConstraints = Array.isArray(contractRaw?.constraints) ? contractRaw.constraints.filter((c) => c.source === "user" && c.required === true && typeof c.text === "string").map((c) => String(c.text)) : void 0;
|
|
28536
|
+
const contractCriteria = Array.isArray(contractRaw?.acceptanceCriteria) ? contractRaw.acceptanceCriteria.filter((c) => typeof c.id === "string").map((c) => ({ id: String(c.id), required: c.required === true })) : void 0;
|
|
28482
28537
|
return {
|
|
28483
28538
|
version: 1,
|
|
28484
|
-
activeCriteria,
|
|
28539
|
+
activeCriteria: contractCriteria ?? activeCriteria,
|
|
28485
28540
|
unresolvedIssues,
|
|
28486
28541
|
...latestVerification ? {
|
|
28487
28542
|
latestVerification: {
|
|
@@ -28492,7 +28547,7 @@ function buildCompactionStateSnapshot(events, toSeq) {
|
|
|
28492
28547
|
} : {},
|
|
28493
28548
|
retainedEvidenceRefs: evidenceFromResults(results),
|
|
28494
28549
|
affectedFiles: [...affectedFiles].slice(0, 64),
|
|
28495
|
-
userConstraints: [...userConstraints].slice(-12),
|
|
28550
|
+
userConstraints: contractConstraints ?? [...userConstraints].slice(-12),
|
|
28496
28551
|
...missionState ? { missionState } : {}
|
|
28497
28552
|
};
|
|
28498
28553
|
}
|
|
@@ -28630,13 +28685,45 @@ var init_compaction = __esm({
|
|
|
28630
28685
|
function isModelSurfaceEvent(event) {
|
|
28631
28686
|
return MODEL_SURFACE_KINDS.has(event.kind);
|
|
28632
28687
|
}
|
|
28688
|
+
function latestSurfaceSeqByKind(events) {
|
|
28689
|
+
const latest = /* @__PURE__ */ new Map();
|
|
28690
|
+
for (const e of events) {
|
|
28691
|
+
if (LATEST_ONLY_SURFACE_KINDS.has(e.kind) && !isSeqShadowed(e.seq, coveringCompactions(events))) {
|
|
28692
|
+
latest.set(e.kind, e.seq);
|
|
28693
|
+
}
|
|
28694
|
+
}
|
|
28695
|
+
return latest;
|
|
28696
|
+
}
|
|
28633
28697
|
function asString(value) {
|
|
28634
28698
|
return typeof value === "string" ? value : void 0;
|
|
28635
28699
|
}
|
|
28700
|
+
function asNumber(value) {
|
|
28701
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
28702
|
+
}
|
|
28703
|
+
function formatResourceSnapshot(data) {
|
|
28704
|
+
const used = asNumber(data.toolCallsUsed) ?? 0;
|
|
28705
|
+
const remaining = asNumber(data.toolCallsRemaining) ?? 0;
|
|
28706
|
+
const lines = [
|
|
28707
|
+
"RESOURCE STATUS",
|
|
28708
|
+
`Tool calls: ${used} / ${used + remaining}`,
|
|
28709
|
+
`Remaining: ${remaining}`
|
|
28710
|
+
];
|
|
28711
|
+
const wall = asNumber(data.wallMsRemaining);
|
|
28712
|
+
if (wall !== void 0)
|
|
28713
|
+
lines.push(`Wall clock remaining: ${Math.max(0, Math.round(wall / 1e3))}s`);
|
|
28714
|
+
lines.push(`Verification reserve: ${asNumber(data.verificationReserve) ?? 0}`);
|
|
28715
|
+
lines.push(`Repair reserve: ${asNumber(data.repairReserve) ?? 0}`);
|
|
28716
|
+
if (typeof data.stage === "string")
|
|
28717
|
+
lines.push(`Stage: ${data.stage}`);
|
|
28718
|
+
if (typeof data.pressure === "string")
|
|
28719
|
+
lines.push(`Pressure: ${data.pressure}`);
|
|
28720
|
+
return lines.join("\n");
|
|
28721
|
+
}
|
|
28636
28722
|
function deriveMessages(events, options = {}) {
|
|
28637
28723
|
const coverings = coveringCompactions(events);
|
|
28638
28724
|
const orderedCoverings = [...coverings].sort((a, b) => a.fromSeq - b.fromSeq || a.seq - b.seq);
|
|
28639
28725
|
const compactBySeq = new Map(coverings.map((c) => [c.seq, c]));
|
|
28726
|
+
const latestOfKind = latestSurfaceSeqByKind(events);
|
|
28640
28727
|
const messages = [];
|
|
28641
28728
|
let nextCheckpoint = 0;
|
|
28642
28729
|
const pushCheckpoint = (compact) => {
|
|
@@ -28663,6 +28750,8 @@ function deriveMessages(events, options = {}) {
|
|
|
28663
28750
|
continue;
|
|
28664
28751
|
if (!isModelSurfaceEvent(e))
|
|
28665
28752
|
continue;
|
|
28753
|
+
if (LATEST_ONLY_SURFACE_KINDS.has(e.kind) && latestOfKind.get(e.kind) !== e.seq)
|
|
28754
|
+
continue;
|
|
28666
28755
|
const d = e.data;
|
|
28667
28756
|
switch (e.kind) {
|
|
28668
28757
|
case "user.message":
|
|
@@ -28703,6 +28792,13 @@ function deriveMessages(events, options = {}) {
|
|
|
28703
28792
|
seq: e.seq
|
|
28704
28793
|
});
|
|
28705
28794
|
break;
|
|
28795
|
+
case "resource.snapshot":
|
|
28796
|
+
messages.push({
|
|
28797
|
+
role: "system",
|
|
28798
|
+
content: formatResourceSnapshot(d),
|
|
28799
|
+
seq: e.seq
|
|
28800
|
+
});
|
|
28801
|
+
break;
|
|
28706
28802
|
}
|
|
28707
28803
|
}
|
|
28708
28804
|
pushDueCheckpoints(Number.POSITIVE_INFINITY);
|
|
@@ -28729,7 +28825,7 @@ function pairToolCalls(events) {
|
|
|
28729
28825
|
}
|
|
28730
28826
|
return ordered;
|
|
28731
28827
|
}
|
|
28732
|
-
var MODEL_SURFACE_KINDS;
|
|
28828
|
+
var MODEL_SURFACE_KINDS, LATEST_ONLY_SURFACE_KINDS;
|
|
28733
28829
|
var init_modelSurface = __esm({
|
|
28734
28830
|
"packages/core/dist/session/modelSurface.js"() {
|
|
28735
28831
|
"use strict";
|
|
@@ -28739,8 +28835,11 @@ var init_modelSurface = __esm({
|
|
|
28739
28835
|
"assistant.message",
|
|
28740
28836
|
"tool.call",
|
|
28741
28837
|
"tool.result",
|
|
28742
|
-
"session.compacted"
|
|
28838
|
+
"session.compacted",
|
|
28839
|
+
// 2.6: budget awareness for the model (latest-only projection below).
|
|
28840
|
+
"resource.snapshot"
|
|
28743
28841
|
]);
|
|
28842
|
+
LATEST_ONLY_SURFACE_KINDS = /* @__PURE__ */ new Set(["resource.snapshot"]);
|
|
28744
28843
|
}
|
|
28745
28844
|
});
|
|
28746
28845
|
|
|
@@ -29493,6 +29592,60 @@ function pushCompactionViolations(events, knownSeq, pairs, violations) {
|
|
|
29493
29592
|
}
|
|
29494
29593
|
}
|
|
29495
29594
|
}
|
|
29595
|
+
function validateResourceAndContractEvents(events) {
|
|
29596
|
+
const violations = [];
|
|
29597
|
+
let lastToolCallsUsed = -1;
|
|
29598
|
+
for (const e of events) {
|
|
29599
|
+
if (e.kind === "resource.snapshot") {
|
|
29600
|
+
const used = e.data.toolCallsUsed;
|
|
29601
|
+
const remaining = e.data.toolCallsRemaining;
|
|
29602
|
+
if (typeof used !== "number" || typeof remaining !== "number" || used < 0 || remaining < 0) {
|
|
29603
|
+
violations.push({ code: "RESOURCE_SNAPSHOT_INVALID", seq: e.seq, message: "snapshot must carry non-negative toolCallsUsed/Remaining" });
|
|
29604
|
+
continue;
|
|
29605
|
+
}
|
|
29606
|
+
if (used < lastToolCallsUsed) {
|
|
29607
|
+
violations.push({ code: "RESOURCE_USED_MONOTONIC", seq: e.seq, message: `toolCallsUsed went ${lastToolCallsUsed} -> ${used}` });
|
|
29608
|
+
}
|
|
29609
|
+
lastToolCallsUsed = used;
|
|
29610
|
+
const limit = typeof e.data.toolCallsLimit === "number" ? e.data.toolCallsLimit : used + remaining;
|
|
29611
|
+
if (used + remaining !== limit) {
|
|
29612
|
+
violations.push({ code: "RESOURCE_REMAINING_COHERENT", seq: e.seq, message: `used(${used}) + remaining(${remaining}) != limit(${limit})` });
|
|
29613
|
+
}
|
|
29614
|
+
for (const key of ["verificationReserve", "repairReserve"]) {
|
|
29615
|
+
const v = e.data[key];
|
|
29616
|
+
if (typeof v === "number" && v < 0) {
|
|
29617
|
+
violations.push({ code: "RESERVE_NEGATIVE", seq: e.seq, message: `${key} is negative (${v})` });
|
|
29618
|
+
}
|
|
29619
|
+
}
|
|
29620
|
+
}
|
|
29621
|
+
if (e.kind === "session.harness_manifest") {
|
|
29622
|
+
if (typeof e.data.manifestHash !== "string" || !e.data.manifest) {
|
|
29623
|
+
violations.push({ code: "MANIFEST_PAYLOAD_INVALID", seq: e.seq, message: "session.harness_manifest needs {manifest, manifestHash}" });
|
|
29624
|
+
}
|
|
29625
|
+
}
|
|
29626
|
+
}
|
|
29627
|
+
let lastVersion = 0;
|
|
29628
|
+
for (const e of events) {
|
|
29629
|
+
if (e.kind !== "task.contract" && e.kind !== "task.contract_updated")
|
|
29630
|
+
continue;
|
|
29631
|
+
const contract = e.data.contract;
|
|
29632
|
+
const version2 = contract && typeof contract === "object" ? contract.version : void 0;
|
|
29633
|
+
if (typeof version2 !== "number" || version2 < 1) {
|
|
29634
|
+
violations.push({ code: "TASK_CONTRACT_VERSION_MONOTONIC", seq: e.seq, message: "contract payload must carry a positive version" });
|
|
29635
|
+
continue;
|
|
29636
|
+
}
|
|
29637
|
+
if (version2 <= lastVersion) {
|
|
29638
|
+
violations.push({ code: "TASK_CONTRACT_VERSION_MONOTONIC", seq: e.seq, message: `version ${version2} did not increase past ${lastVersion}` });
|
|
29639
|
+
}
|
|
29640
|
+
lastVersion = version2;
|
|
29641
|
+
const source = contract && typeof contract === "object" ? contract.source : void 0;
|
|
29642
|
+
const userSeq = source && typeof source === "object" ? source.userSeq : void 0;
|
|
29643
|
+
if (typeof userSeq !== "number" || userSeq < 1) {
|
|
29644
|
+
violations.push({ code: "TASK_CONTRACT_SOURCE_INVALID", seq: e.seq, message: "contract.source.userSeq must be a positive event seq" });
|
|
29645
|
+
}
|
|
29646
|
+
}
|
|
29647
|
+
return violations;
|
|
29648
|
+
}
|
|
29496
29649
|
var init_invariants = __esm({
|
|
29497
29650
|
"packages/core/dist/session/invariants.js"() {
|
|
29498
29651
|
"use strict";
|
|
@@ -29500,6 +29653,122 @@ var init_invariants = __esm({
|
|
|
29500
29653
|
}
|
|
29501
29654
|
});
|
|
29502
29655
|
|
|
29656
|
+
// packages/core/dist/session/taskContract.js
|
|
29657
|
+
function applyTaskContractUpdate(contract, update) {
|
|
29658
|
+
if (update.goal !== void 0 && update.goal !== contract.goal) {
|
|
29659
|
+
if (update.nextUserSeq === void 0) {
|
|
29660
|
+
throw new TaskContractConflictError("agent-derived update may not rewrite the goal");
|
|
29661
|
+
}
|
|
29662
|
+
}
|
|
29663
|
+
const constraints = contract.constraints.filter((c) => {
|
|
29664
|
+
if (!update.removeConstraintIds?.includes(c.id))
|
|
29665
|
+
return true;
|
|
29666
|
+
if (c.source === "user" && c.required) {
|
|
29667
|
+
throw new TaskContractConflictError(`required user constraint "${c.id}" cannot be removed`);
|
|
29668
|
+
}
|
|
29669
|
+
return false;
|
|
29670
|
+
});
|
|
29671
|
+
const criteria = contract.acceptanceCriteria.filter((c) => {
|
|
29672
|
+
if (!update.removeCriterionIds?.includes(c.id))
|
|
29673
|
+
return true;
|
|
29674
|
+
if (c.source === "user" && c.required) {
|
|
29675
|
+
throw new TaskContractConflictError(`required user criterion "${c.id}" cannot be removed`);
|
|
29676
|
+
}
|
|
29677
|
+
return false;
|
|
29678
|
+
});
|
|
29679
|
+
for (const add of update.addConstraints ?? []) {
|
|
29680
|
+
if (constraints.some((c) => c.id === add.id) || (update.addConstraints ?? []).filter((x) => x.id === add.id).length > 1) {
|
|
29681
|
+
throw new TaskContractConflictError(`duplicate constraint id "${add.id}"`);
|
|
29682
|
+
}
|
|
29683
|
+
}
|
|
29684
|
+
for (const add of update.addCriteria ?? []) {
|
|
29685
|
+
if (criteria.some((c) => c.id === add.id) || (update.addCriteria ?? []).filter((x) => x.id === add.id).length > 1) {
|
|
29686
|
+
throw new TaskContractConflictError(`duplicate criterion id "${add.id}"`);
|
|
29687
|
+
}
|
|
29688
|
+
}
|
|
29689
|
+
return TaskContractSchema.parse({
|
|
29690
|
+
version: contract.version + 1,
|
|
29691
|
+
goal: update.goal ?? contract.goal,
|
|
29692
|
+
constraints: [...constraints, ...update.addConstraints ?? []],
|
|
29693
|
+
acceptanceCriteria: [...criteria, ...update.addCriteria ?? []],
|
|
29694
|
+
source: {
|
|
29695
|
+
userSeq: update.nextUserSeq ?? contract.source.userSeq
|
|
29696
|
+
}
|
|
29697
|
+
});
|
|
29698
|
+
}
|
|
29699
|
+
function contractToCompactionFields(contract) {
|
|
29700
|
+
return {
|
|
29701
|
+
goal: contract.goal,
|
|
29702
|
+
userConstraints: contract.constraints.filter((c) => c.source === "user" && c.required).map((c) => c.text),
|
|
29703
|
+
activeCriteria: contract.acceptanceCriteria.map((c) => ({ id: c.id, required: c.required }))
|
|
29704
|
+
};
|
|
29705
|
+
}
|
|
29706
|
+
function deriveInitialContract(userSeq, text) {
|
|
29707
|
+
const lines = text.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
|
|
29708
|
+
const stripped = lines.map((l) => l.replace(/^[-*]\s+/, ""));
|
|
29709
|
+
const constraintLines = stripped.filter((l) => /^(do not|don't|never|no |non |without changing|keep)/i.test(l));
|
|
29710
|
+
const criteriaLines = stripped.filter((l) => /^\[?\s*[x ]?\s*\]?\s*/.test(l) === false ? /^(acceptance|verify|test)[:\s]/i.test(l) : true).map((l) => l.replace(/^\[?\s*[x ]?\s*\]?\s*/, "").replace(/^(acceptance|verify|test)[:\s]+/i, ""));
|
|
29711
|
+
return TaskContractSchema.parse({
|
|
29712
|
+
version: 1,
|
|
29713
|
+
goal: lines[0] ?? text.slice(0, 200),
|
|
29714
|
+
constraints: constraintLines.map((t, i) => ({
|
|
29715
|
+
id: `uc-${i + 1}`,
|
|
29716
|
+
text: t,
|
|
29717
|
+
source: "user",
|
|
29718
|
+
required: true
|
|
29719
|
+
})),
|
|
29720
|
+
acceptanceCriteria: criteriaLines.map((t, i) => ({
|
|
29721
|
+
id: `ac-${i + 1}`,
|
|
29722
|
+
text: t,
|
|
29723
|
+
source: "user",
|
|
29724
|
+
required: true
|
|
29725
|
+
})),
|
|
29726
|
+
source: { userSeq }
|
|
29727
|
+
});
|
|
29728
|
+
}
|
|
29729
|
+
var TaskConstraintSchema, TaskCriterionSchema, TaskContractSchema, TaskContractConflictError;
|
|
29730
|
+
var init_taskContract = __esm({
|
|
29731
|
+
"packages/core/dist/session/taskContract.js"() {
|
|
29732
|
+
"use strict";
|
|
29733
|
+
init_zod();
|
|
29734
|
+
TaskConstraintSchema = external_exports.object({
|
|
29735
|
+
id: external_exports.string().min(1),
|
|
29736
|
+
text: external_exports.string().min(1),
|
|
29737
|
+
source: external_exports.enum(["user", "agent-derived"]),
|
|
29738
|
+
required: external_exports.boolean()
|
|
29739
|
+
});
|
|
29740
|
+
TaskCriterionSchema = external_exports.object({
|
|
29741
|
+
id: external_exports.string().min(1),
|
|
29742
|
+
text: external_exports.string().min(1),
|
|
29743
|
+
source: external_exports.enum(["user", "agent-derived"]),
|
|
29744
|
+
required: external_exports.boolean(),
|
|
29745
|
+
verificationHint: external_exports.object({
|
|
29746
|
+
kind: external_exports.enum(["command", "tool", "semantic", "manual"]),
|
|
29747
|
+
value: external_exports.string().optional()
|
|
29748
|
+
}).optional()
|
|
29749
|
+
});
|
|
29750
|
+
TaskContractSchema = external_exports.object({
|
|
29751
|
+
version: external_exports.number().int().positive(),
|
|
29752
|
+
goal: external_exports.string().min(1),
|
|
29753
|
+
constraints: external_exports.array(TaskConstraintSchema),
|
|
29754
|
+
acceptanceCriteria: external_exports.array(TaskCriterionSchema),
|
|
29755
|
+
source: external_exports.object({
|
|
29756
|
+
/** Seq of the user.message the contract was extracted from. */
|
|
29757
|
+
userSeq: external_exports.number().int().positive()
|
|
29758
|
+
})
|
|
29759
|
+
});
|
|
29760
|
+
TaskContractConflictError = class extends Error {
|
|
29761
|
+
reason;
|
|
29762
|
+
code = "TASK_CONTRACT_CONFLICT";
|
|
29763
|
+
constructor(reason) {
|
|
29764
|
+
super(`task contract update rejected: ${reason}`);
|
|
29765
|
+
this.reason = reason;
|
|
29766
|
+
this.name = "TaskContractConflictError";
|
|
29767
|
+
}
|
|
29768
|
+
};
|
|
29769
|
+
}
|
|
29770
|
+
});
|
|
29771
|
+
|
|
29503
29772
|
// packages/core/dist/session/index.js
|
|
29504
29773
|
var init_session = __esm({
|
|
29505
29774
|
"packages/core/dist/session/index.js"() {
|
|
@@ -29515,6 +29784,7 @@ var init_session = __esm({
|
|
|
29515
29784
|
init_exportSession();
|
|
29516
29785
|
init_invariants();
|
|
29517
29786
|
init_recovery();
|
|
29787
|
+
init_taskContract();
|
|
29518
29788
|
}
|
|
29519
29789
|
});
|
|
29520
29790
|
|
|
@@ -29850,11 +30120,15 @@ function toolManifestHash(tools) {
|
|
|
29850
30120
|
const manifest = [...tools].sort().join(",");
|
|
29851
30121
|
return createHash3("sha256").update(manifest).digest("hex");
|
|
29852
30122
|
}
|
|
30123
|
+
function profileHash(profile) {
|
|
30124
|
+
return createHash3("sha256").update(stableStringify(profile)).digest("hex");
|
|
30125
|
+
}
|
|
29853
30126
|
var ProfileSchema, MINIMAL_TOOLS, MINIMAL_V1, KRAKEN_V1, COUNCIL_V1, MISSION_V1, BUILT_IN_PROFILES, UnknownProfileError;
|
|
29854
30127
|
var init_profiles = __esm({
|
|
29855
30128
|
"packages/core/dist/runtime/profiles.js"() {
|
|
29856
30129
|
"use strict";
|
|
29857
30130
|
init_zod();
|
|
30131
|
+
init_requestSnapshot();
|
|
29858
30132
|
ProfileSchema = external_exports.object({
|
|
29859
30133
|
/** `<name>/v<N>` — immutable once published. */
|
|
29860
30134
|
id: external_exports.string().regex(/^[a-z0-9-]+\/v\d+$/, "profile id must be <name>/v<N>"),
|
|
@@ -29926,6 +30200,99 @@ var init_profiles = __esm({
|
|
|
29926
30200
|
}
|
|
29927
30201
|
});
|
|
29928
30202
|
|
|
30203
|
+
// packages/core/dist/runtime/harnessManifest.js
|
|
30204
|
+
function hashHarnessManifest(manifest) {
|
|
30205
|
+
return sha256Hex(stableStringify(manifest));
|
|
30206
|
+
}
|
|
30207
|
+
function harnessInputHash(value) {
|
|
30208
|
+
return sha256Hex(stableStringify(value));
|
|
30209
|
+
}
|
|
30210
|
+
function collectPaths2(base, a, b, out, depth = 0) {
|
|
30211
|
+
if (depth > 6)
|
|
30212
|
+
return;
|
|
30213
|
+
if (stableStringify(a) === stableStringify(b))
|
|
30214
|
+
return;
|
|
30215
|
+
const objA = a && typeof a === "object" && !Array.isArray(a) ? a : null;
|
|
30216
|
+
const objB = b && typeof b === "object" && !Array.isArray(b) ? b : null;
|
|
30217
|
+
if (objA && objB) {
|
|
30218
|
+
for (const key of [.../* @__PURE__ */ new Set([...Object.keys(objA), ...Object.keys(objB)])].sort()) {
|
|
30219
|
+
collectPaths2(base ? `${base}.${key}` : key, objA[key], objB[key], out, depth + 1);
|
|
30220
|
+
}
|
|
30221
|
+
return;
|
|
30222
|
+
}
|
|
30223
|
+
out.push(base);
|
|
30224
|
+
}
|
|
30225
|
+
function diffHarnessManifest(oldManifest, newManifest) {
|
|
30226
|
+
const changed = [];
|
|
30227
|
+
collectPaths2("", oldManifest, newManifest, changed);
|
|
30228
|
+
return { changed: changed.sort() };
|
|
30229
|
+
}
|
|
30230
|
+
function classifyHarnessChanges(diff) {
|
|
30231
|
+
const byField = {};
|
|
30232
|
+
for (const field of diff.changed) {
|
|
30233
|
+
const hit = FIELD_CLASSES.find((m) => field === m.prefix || field.startsWith(m.prefix + "."));
|
|
30234
|
+
byField[field] = hit ? hit.cls : "cosmetic";
|
|
30235
|
+
}
|
|
30236
|
+
const order = { behavioral: 3, structural: 2, cosmetic: 1 };
|
|
30237
|
+
const overall = Object.values(byField).reduce((acc, cls) => order[cls] > order[acc] ? cls : acc, "cosmetic");
|
|
30238
|
+
return { overall, byField };
|
|
30239
|
+
}
|
|
30240
|
+
var HARNESS_MANIFEST_SCHEMA_VERSION, HarnessPromptsSchema, HarnessManifestV1Schema, FIELD_CLASSES;
|
|
30241
|
+
var init_harnessManifest = __esm({
|
|
30242
|
+
"packages/core/dist/runtime/harnessManifest.js"() {
|
|
30243
|
+
"use strict";
|
|
30244
|
+
init_zod();
|
|
30245
|
+
init_requestSnapshot();
|
|
30246
|
+
HARNESS_MANIFEST_SCHEMA_VERSION = 1;
|
|
30247
|
+
HarnessPromptsSchema = external_exports.object({
|
|
30248
|
+
kraken: external_exports.string().min(1).optional(),
|
|
30249
|
+
gauntlet: external_exports.string().min(1).optional(),
|
|
30250
|
+
council: external_exports.string().min(1).optional(),
|
|
30251
|
+
mission: external_exports.string().min(1).optional()
|
|
30252
|
+
});
|
|
30253
|
+
HarnessManifestV1Schema = external_exports.object({
|
|
30254
|
+
schemaVersion: external_exports.literal(HARNESS_MANIFEST_SCHEMA_VERSION),
|
|
30255
|
+
profile: external_exports.object({
|
|
30256
|
+
id: external_exports.string().min(1),
|
|
30257
|
+
/** WorkPhase of the session that recorded the manifest. */
|
|
30258
|
+
phase: external_exports.enum(["plan", "build"]),
|
|
30259
|
+
/** Hash of the full profile (see profileHash in profiles.ts). */
|
|
30260
|
+
hash: external_exports.string().min(1)
|
|
30261
|
+
}),
|
|
30262
|
+
prompts: HarnessPromptsSchema,
|
|
30263
|
+
capabilities: external_exports.object({
|
|
30264
|
+
toolManifestHash: external_exports.string().min(1),
|
|
30265
|
+
skillManifestHash: external_exports.string().min(1)
|
|
30266
|
+
}),
|
|
30267
|
+
policies: external_exports.object({
|
|
30268
|
+
routingHash: external_exports.string().min(1),
|
|
30269
|
+
verificationHash: external_exports.string().min(1),
|
|
30270
|
+
completionPolicyHash: external_exports.string().min(1),
|
|
30271
|
+
compactionHash: external_exports.string().min(1),
|
|
30272
|
+
/** Behavioural since 2.6 Track B: budget policy shapes execution. */
|
|
30273
|
+
resourcePolicyHash: external_exports.string().min(1)
|
|
30274
|
+
}),
|
|
30275
|
+
runtime: external_exports.object({
|
|
30276
|
+
coreVersion: external_exports.string().min(1),
|
|
30277
|
+
cliVersion: external_exports.string().min(1)
|
|
30278
|
+
})
|
|
30279
|
+
});
|
|
30280
|
+
FIELD_CLASSES = [
|
|
30281
|
+
{ prefix: "prompts", cls: "behavioral" },
|
|
30282
|
+
{ prefix: "capabilities.toolManifestHash", cls: "behavioral" },
|
|
30283
|
+
{ prefix: "capabilities.skillManifestHash", cls: "behavioral" },
|
|
30284
|
+
{ prefix: "policies.routingHash", cls: "behavioral" },
|
|
30285
|
+
{ prefix: "policies.verificationHash", cls: "behavioral" },
|
|
30286
|
+
{ prefix: "policies.completionPolicyHash", cls: "structural" },
|
|
30287
|
+
{ prefix: "policies.compactionHash", cls: "behavioral" },
|
|
30288
|
+
{ prefix: "policies.resourcePolicyHash", cls: "behavioral" },
|
|
30289
|
+
{ prefix: "profile", cls: "structural" },
|
|
30290
|
+
{ prefix: "runtime", cls: "structural" },
|
|
30291
|
+
{ prefix: "schemaVersion", cls: "structural" }
|
|
30292
|
+
];
|
|
30293
|
+
}
|
|
30294
|
+
});
|
|
30295
|
+
|
|
29929
30296
|
// packages/core/dist/experimental.js
|
|
29930
30297
|
function isExperimentalEnabled(flag, env = process.env) {
|
|
29931
30298
|
const raw = env.ZELARI_EXPERIMENTAL;
|
|
@@ -30008,6 +30375,155 @@ var init_executionContext = __esm({
|
|
|
30008
30375
|
}
|
|
30009
30376
|
});
|
|
30010
30377
|
|
|
30378
|
+
// packages/core/dist/runtime/resourcePolicy.js
|
|
30379
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
30380
|
+
function defaultResourcePolicy(profileId) {
|
|
30381
|
+
return PROFILE_RESOURCE_POLICIES[profileId] ?? PROFILE_RESOURCE_POLICIES["kraken/v1"];
|
|
30382
|
+
}
|
|
30383
|
+
function resourcePolicyHash(policy) {
|
|
30384
|
+
return createHash4("sha256").update(stableStringify(ResourcePolicySchema.parse(policy))).digest("hex");
|
|
30385
|
+
}
|
|
30386
|
+
var BudgetPressureSchema, ResourceStageSchema, PressureThresholdsSchema, DEFAULT_PRESSURE_THRESHOLDS, ResourcePolicySchema, PROFILE_RESOURCE_POLICIES;
|
|
30387
|
+
var init_resourcePolicy = __esm({
|
|
30388
|
+
"packages/core/dist/runtime/resourcePolicy.js"() {
|
|
30389
|
+
"use strict";
|
|
30390
|
+
init_zod();
|
|
30391
|
+
init_requestSnapshot();
|
|
30392
|
+
BudgetPressureSchema = external_exports.enum(["ample", "normal", "constrained", "critical"]);
|
|
30393
|
+
ResourceStageSchema = external_exports.enum(["explore", "implement", "verify", "repair"]);
|
|
30394
|
+
PressureThresholdsSchema = external_exports.object({
|
|
30395
|
+
/** remaining/usable >= ample → ample. */
|
|
30396
|
+
ample: external_exports.number().min(0).max(1),
|
|
30397
|
+
/** remaining/usable >= constrained → normal; below → constrained. */
|
|
30398
|
+
constrained: external_exports.number().min(0).max(1),
|
|
30399
|
+
/** remaining/usable < critical → critical. */
|
|
30400
|
+
critical: external_exports.number().min(0).max(1)
|
|
30401
|
+
});
|
|
30402
|
+
DEFAULT_PRESSURE_THRESHOLDS = Object.freeze({
|
|
30403
|
+
ample: 0.5,
|
|
30404
|
+
constrained: 0.25,
|
|
30405
|
+
critical: 0.1
|
|
30406
|
+
});
|
|
30407
|
+
ResourcePolicySchema = external_exports.object({
|
|
30408
|
+
maxToolCalls: external_exports.number().int().positive(),
|
|
30409
|
+
reserve: external_exports.object({
|
|
30410
|
+
/** Protected: tool budget the non-verification loop may not consume (§11.4). */
|
|
30411
|
+
verification: external_exports.number().int().min(0),
|
|
30412
|
+
/** Advisory-only by default (§11.4). */
|
|
30413
|
+
repair: external_exports.number().int().min(0)
|
|
30414
|
+
}),
|
|
30415
|
+
wallClockMs: external_exports.number().int().positive().optional(),
|
|
30416
|
+
/** Soft token ceiling (advisory telemetry, not enforced). */
|
|
30417
|
+
softMaxTokens: external_exports.number().int().positive().optional(),
|
|
30418
|
+
pressure: PressureThresholdsSchema.default(DEFAULT_PRESSURE_THRESHOLDS)
|
|
30419
|
+
});
|
|
30420
|
+
PROFILE_RESOURCE_POLICIES = Object.freeze({
|
|
30421
|
+
"minimal/v1": {
|
|
30422
|
+
maxToolCalls: 25,
|
|
30423
|
+
reserve: { verification: 4, repair: 3 },
|
|
30424
|
+
pressure: DEFAULT_PRESSURE_THRESHOLDS
|
|
30425
|
+
},
|
|
30426
|
+
"kraken/v1": {
|
|
30427
|
+
maxToolCalls: 40,
|
|
30428
|
+
reserve: { verification: 6, repair: 4 },
|
|
30429
|
+
wallClockMs: 9e5,
|
|
30430
|
+
pressure: DEFAULT_PRESSURE_THRESHOLDS
|
|
30431
|
+
},
|
|
30432
|
+
"council/v1": {
|
|
30433
|
+
maxToolCalls: 30,
|
|
30434
|
+
reserve: { verification: 4, repair: 2 },
|
|
30435
|
+
pressure: DEFAULT_PRESSURE_THRESHOLDS
|
|
30436
|
+
},
|
|
30437
|
+
"mission/v1": {
|
|
30438
|
+
maxToolCalls: 60,
|
|
30439
|
+
reserve: { verification: 8, repair: 6 },
|
|
30440
|
+
wallClockMs: 18e5,
|
|
30441
|
+
pressure: DEFAULT_PRESSURE_THRESHOLDS
|
|
30442
|
+
}
|
|
30443
|
+
});
|
|
30444
|
+
}
|
|
30445
|
+
});
|
|
30446
|
+
|
|
30447
|
+
// packages/core/dist/runtime/resourceBudget.js
|
|
30448
|
+
function computeBudget(policy, usage, stage = "explore") {
|
|
30449
|
+
const used = Math.max(0, Math.min(usage.toolCallsUsed, policy.maxToolCalls));
|
|
30450
|
+
return {
|
|
30451
|
+
toolCalls: {
|
|
30452
|
+
limit: policy.maxToolCalls,
|
|
30453
|
+
used,
|
|
30454
|
+
remaining: policy.maxToolCalls - used
|
|
30455
|
+
},
|
|
30456
|
+
wallTime: {
|
|
30457
|
+
limitMs: policy.wallClockMs,
|
|
30458
|
+
elapsedMs: Math.max(0, usage.elapsedMs ?? 0),
|
|
30459
|
+
remainingMs: policy.wallClockMs === void 0 ? void 0 : Math.max(0, policy.wallClockMs - (usage.elapsedMs ?? 0))
|
|
30460
|
+
},
|
|
30461
|
+
tokens: usage.tokensUsed === void 0 && policy.softMaxTokens === void 0 ? void 0 : {
|
|
30462
|
+
softLimit: policy.softMaxTokens,
|
|
30463
|
+
used: usage.tokensUsed ?? 0,
|
|
30464
|
+
remaining: policy.softMaxTokens === void 0 ? void 0 : Math.max(0, policy.softMaxTokens - (usage.tokensUsed ?? 0))
|
|
30465
|
+
},
|
|
30466
|
+
reserve: {
|
|
30467
|
+
verification: Math.max(0, policy.reserve.verification),
|
|
30468
|
+
repair: Math.max(0, policy.reserve.repair)
|
|
30469
|
+
},
|
|
30470
|
+
stage
|
|
30471
|
+
};
|
|
30472
|
+
}
|
|
30473
|
+
function usageFromLedger(entries) {
|
|
30474
|
+
const seen = /* @__PURE__ */ new Set();
|
|
30475
|
+
let toolCallsUsed = 0;
|
|
30476
|
+
let wallMs = 0;
|
|
30477
|
+
let tokensUsed = 0;
|
|
30478
|
+
for (const e of entries) {
|
|
30479
|
+
if (seen.has(e.seq))
|
|
30480
|
+
continue;
|
|
30481
|
+
seen.add(e.seq);
|
|
30482
|
+
toolCallsUsed += e.delta.toolCalls ?? 0;
|
|
30483
|
+
wallMs += e.delta.wallMs ?? 0;
|
|
30484
|
+
tokensUsed += e.delta.tokens ?? 0;
|
|
30485
|
+
}
|
|
30486
|
+
return { toolCallsUsed: Math.max(0, toolCallsUsed), wallMs: Math.max(0, wallMs), tokensUsed: Math.max(0, tokensUsed) };
|
|
30487
|
+
}
|
|
30488
|
+
function budgetPressure(budget, policy) {
|
|
30489
|
+
const usable = Math.max(0, budget.toolCalls.remaining - budget.reserve.verification);
|
|
30490
|
+
const capacity = Math.max(1, budget.toolCalls.limit - budget.reserve.verification);
|
|
30491
|
+
const ratio = usable / capacity;
|
|
30492
|
+
const t = policy.pressure;
|
|
30493
|
+
if (ratio >= t.ample)
|
|
30494
|
+
return "ample";
|
|
30495
|
+
if (ratio >= t.constrained)
|
|
30496
|
+
return "normal";
|
|
30497
|
+
if (ratio >= t.critical)
|
|
30498
|
+
return "constrained";
|
|
30499
|
+
return "critical";
|
|
30500
|
+
}
|
|
30501
|
+
function isVerificationReserveProtected(budget) {
|
|
30502
|
+
return budget.toolCalls.remaining <= budget.reserve.verification;
|
|
30503
|
+
}
|
|
30504
|
+
function canSpendOutsideReserve(budget, calls) {
|
|
30505
|
+
return budget.toolCalls.remaining - budget.reserve.verification >= calls;
|
|
30506
|
+
}
|
|
30507
|
+
function ledgerDeltaFor(reason, calls = 1) {
|
|
30508
|
+
switch (reason) {
|
|
30509
|
+
case "tool-call":
|
|
30510
|
+
return { toolCalls: calls };
|
|
30511
|
+
case "model-turn":
|
|
30512
|
+
case "verification":
|
|
30513
|
+
case "repair":
|
|
30514
|
+
return { toolCalls: calls };
|
|
30515
|
+
case "timeout":
|
|
30516
|
+
return {};
|
|
30517
|
+
case "reservation":
|
|
30518
|
+
return {};
|
|
30519
|
+
}
|
|
30520
|
+
}
|
|
30521
|
+
var init_resourceBudget = __esm({
|
|
30522
|
+
"packages/core/dist/runtime/resourceBudget.js"() {
|
|
30523
|
+
"use strict";
|
|
30524
|
+
}
|
|
30525
|
+
});
|
|
30526
|
+
|
|
30011
30527
|
// packages/core/dist/runtime/index.js
|
|
30012
30528
|
var init_runtime2 = __esm({
|
|
30013
30529
|
"packages/core/dist/runtime/index.js"() {
|
|
@@ -30017,7 +30533,10 @@ var init_runtime2 = __esm({
|
|
|
30017
30533
|
init_memoryProviders();
|
|
30018
30534
|
init_worktreeWorkspace();
|
|
30019
30535
|
init_profiles();
|
|
30536
|
+
init_harnessManifest();
|
|
30020
30537
|
init_executionContext();
|
|
30538
|
+
init_resourcePolicy();
|
|
30539
|
+
init_resourceBudget();
|
|
30021
30540
|
}
|
|
30022
30541
|
});
|
|
30023
30542
|
|
|
@@ -30194,9 +30713,9 @@ var init_scopeDiscipline = __esm({
|
|
|
30194
30713
|
});
|
|
30195
30714
|
|
|
30196
30715
|
// packages/core/dist/verification/engine.js
|
|
30197
|
-
import { createHash as
|
|
30716
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
30198
30717
|
function defaultSha256(input) {
|
|
30199
|
-
return
|
|
30718
|
+
return createHash5("sha256").update(input).digest("hex");
|
|
30200
30719
|
}
|
|
30201
30720
|
function tail(text, max = 400) {
|
|
30202
30721
|
return text.length > max ? `\u2026${text.slice(text.length - max)}` : text;
|
|
@@ -30358,12 +30877,12 @@ var init_engine = __esm({
|
|
|
30358
30877
|
* content digest) and the returned ref carries the event seq when the
|
|
30359
30878
|
* emitter resolved one.
|
|
30360
30879
|
*/
|
|
30361
|
-
async fsEvidence(observation,
|
|
30880
|
+
async fsEvidence(observation, path65, sha256, content, extra = {}) {
|
|
30362
30881
|
const digest = sha256 && content !== void 0 ? sha256(content) : void 0;
|
|
30363
|
-
const seq = await this.emitEvidence({ observation, path:
|
|
30882
|
+
const seq = await this.emitEvidence({ observation, path: path65, ...extra, ...digest ? { digest } : {} });
|
|
30364
30883
|
return {
|
|
30365
30884
|
tier: "fs-observation",
|
|
30366
|
-
ref:
|
|
30885
|
+
ref: path65,
|
|
30367
30886
|
capturedAt: Date.now(),
|
|
30368
30887
|
...digest ? { digest } : {},
|
|
30369
30888
|
...seq !== void 0 ? { seq } : {}
|
|
@@ -30682,6 +31201,23 @@ function verificationCostRatio(verificationMs, totalMs) {
|
|
|
30682
31201
|
return null;
|
|
30683
31202
|
return verificationMs / totalMs;
|
|
30684
31203
|
}
|
|
31204
|
+
function costPerVerifiedSolve(samples) {
|
|
31205
|
+
const solved = samples.filter((s) => s.verified === true);
|
|
31206
|
+
const totalCostUsd = samples.reduce((sum, s) => sum + s.modelCostUsd, 0);
|
|
31207
|
+
const totalWallMs = samples.reduce((sum, s) => sum + s.wallMs, 0);
|
|
31208
|
+
const totalToolCalls = samples.reduce((sum, s) => sum + s.toolCalls, 0);
|
|
31209
|
+
const n = solved.length;
|
|
31210
|
+
return {
|
|
31211
|
+
verifiedSolves: n,
|
|
31212
|
+
totalCostUsd: round(totalCostUsd),
|
|
31213
|
+
costPerVerifiedSolve: n > 0 ? round(totalCostUsd / n) : null,
|
|
31214
|
+
wallMsPerVerifiedSolve: n > 0 ? Math.round(totalWallMs / n) : null,
|
|
31215
|
+
toolCallsPerVerifiedSolve: n > 0 ? round(totalToolCalls / n) : null
|
|
31216
|
+
};
|
|
31217
|
+
}
|
|
31218
|
+
function round(v) {
|
|
31219
|
+
return Math.round(v * 1e6) / 1e6;
|
|
31220
|
+
}
|
|
30685
31221
|
var init_metrics = __esm({
|
|
30686
31222
|
"packages/core/dist/verification/metrics.js"() {
|
|
30687
31223
|
"use strict";
|
|
@@ -30890,6 +31426,44 @@ var init_verifier = __esm({
|
|
|
30890
31426
|
}
|
|
30891
31427
|
});
|
|
30892
31428
|
|
|
31429
|
+
// packages/core/dist/verification/resourceReserveGate.js
|
|
31430
|
+
function evaluateResourceReserveGate(input) {
|
|
31431
|
+
const { evaluation, budget } = input;
|
|
31432
|
+
if (evaluation.verdict === "PASS") {
|
|
31433
|
+
return {
|
|
31434
|
+
verdict: "PASS",
|
|
31435
|
+
deterministicVerdict: "PASS",
|
|
31436
|
+
resourceExhausted: false,
|
|
31437
|
+
evidenceAffordable: true,
|
|
31438
|
+
summary: evaluation.summary
|
|
31439
|
+
};
|
|
31440
|
+
}
|
|
31441
|
+
const spendable = Math.max(0, budget.toolCalls.remaining - budget.reserve.verification);
|
|
31442
|
+
const affordable = spendable + budget.reserve.verification > 0 && budget.toolCalls.remaining > 0;
|
|
31443
|
+
if (affordable) {
|
|
31444
|
+
return {
|
|
31445
|
+
verdict: evaluation.verdict,
|
|
31446
|
+
deterministicVerdict: evaluation.verdict,
|
|
31447
|
+
resourceExhausted: false,
|
|
31448
|
+
evidenceAffordable: true,
|
|
31449
|
+
summary: evaluation.summary
|
|
31450
|
+
};
|
|
31451
|
+
}
|
|
31452
|
+
const summary = `${evaluation.summary} \xB7 resource-exhausted: ${budget.toolCalls.used}/${budget.toolCalls.limit} tool calls used, no budget left for required evidence \u2014 BLOCKED, not a false done`;
|
|
31453
|
+
return {
|
|
31454
|
+
verdict: "BLOCKED",
|
|
31455
|
+
deterministicVerdict: evaluation.verdict,
|
|
31456
|
+
resourceExhausted: true,
|
|
31457
|
+
evidenceAffordable: false,
|
|
31458
|
+
summary
|
|
31459
|
+
};
|
|
31460
|
+
}
|
|
31461
|
+
var init_resourceReserveGate = __esm({
|
|
31462
|
+
"packages/core/dist/verification/resourceReserveGate.js"() {
|
|
31463
|
+
"use strict";
|
|
31464
|
+
}
|
|
31465
|
+
});
|
|
31466
|
+
|
|
30893
31467
|
// packages/core/dist/verification/index.js
|
|
30894
31468
|
var init_verification2 = __esm({
|
|
30895
31469
|
"packages/core/dist/verification/index.js"() {
|
|
@@ -30902,6 +31476,7 @@ var init_verification2 = __esm({
|
|
|
30902
31476
|
init_metrics();
|
|
30903
31477
|
init_verifier();
|
|
30904
31478
|
init_scopeDiscipline();
|
|
31479
|
+
init_resourceReserveGate();
|
|
30905
31480
|
}
|
|
30906
31481
|
});
|
|
30907
31482
|
|
|
@@ -31060,6 +31635,7 @@ __export(dist_exports, {
|
|
|
31060
31635
|
BENNETTS_RAZOR_SHORT: () => BENNETTS_RAZOR_SHORT,
|
|
31061
31636
|
BUILT_IN_PROFILES: () => BUILT_IN_PROFILES,
|
|
31062
31637
|
BonConfigSchema: () => BonConfigSchema,
|
|
31638
|
+
BudgetPressureSchema: () => BudgetPressureSchema,
|
|
31063
31639
|
CLARIFICATION_PROTOCOL_MODULE: () => CLARIFICATION_PROTOCOL_MODULE,
|
|
31064
31640
|
CODING_CATEGORY: () => CODING_CATEGORY,
|
|
31065
31641
|
CODING_PRACTICES_MODULE: () => CODING_PRACTICES_MODULE,
|
|
@@ -31074,6 +31650,7 @@ __export(dist_exports, {
|
|
|
31074
31650
|
DEFAULT_MAX_TENTACLES: () => DEFAULT_MAX_TENTACLES,
|
|
31075
31651
|
DEFAULT_NFR_SPEC: () => DEFAULT_NFR_SPEC,
|
|
31076
31652
|
DEFAULT_PLAN_TIMEOUT_MS: () => DEFAULT_PLAN_TIMEOUT_MS,
|
|
31653
|
+
DEFAULT_PRESSURE_THRESHOLDS: () => DEFAULT_PRESSURE_THRESHOLDS,
|
|
31077
31654
|
DEFAULT_VERIFIER_CONFIG: () => DEFAULT_VERIFIER_CONFIG,
|
|
31078
31655
|
DEGRADED_RUN_BANNER: () => DEGRADED_RUN_BANNER,
|
|
31079
31656
|
DESIGN_PHASE_MODE_BANNER: () => DESIGN_PHASE_MODE_BANNER,
|
|
@@ -31090,6 +31667,9 @@ __export(dist_exports, {
|
|
|
31090
31667
|
FileAbsentCheckSchema: () => FileAbsentCheckSchema,
|
|
31091
31668
|
FileContainsCheckSchema: () => FileContainsCheckSchema,
|
|
31092
31669
|
FileExistsCheckSchema: () => FileExistsCheckSchema,
|
|
31670
|
+
HARNESS_MANIFEST_SCHEMA_VERSION: () => HARNESS_MANIFEST_SCHEMA_VERSION,
|
|
31671
|
+
HarnessManifestV1Schema: () => HarnessManifestV1Schema,
|
|
31672
|
+
HarnessPromptsSchema: () => HarnessPromptsSchema,
|
|
31093
31673
|
IMPLEMENTATION_ADVISOR_BANNER: () => IMPLEMENTATION_ADVISOR_BANNER,
|
|
31094
31674
|
IMPLEMENTATION_IMPLEMENTER_BANNER: () => IMPLEMENTATION_IMPLEMENTER_BANNER,
|
|
31095
31675
|
IMPLEMENTATION_MODE_BANNER: () => IMPLEMENTATION_MODE_BANNER,
|
|
@@ -31099,6 +31679,7 @@ __export(dist_exports, {
|
|
|
31099
31679
|
KRAKEN_SELECTION_PLAYBOOK_MODULE: () => KRAKEN_SELECTION_PLAYBOOK_MODULE,
|
|
31100
31680
|
KRAKEN_V1: () => KRAKEN_V1,
|
|
31101
31681
|
LANGUAGE_POLICY_MODULE_TYPE: () => LANGUAGE_POLICY_MODULE_TYPE,
|
|
31682
|
+
LATEST_ONLY_SURFACE_KINDS: () => LATEST_ONLY_SURFACE_KINDS,
|
|
31102
31683
|
LAYOUT_MOTION_PROPS: () => LAYOUT_MOTION_PROPS,
|
|
31103
31684
|
LESSONS_FILE: () => LESSONS_FILE,
|
|
31104
31685
|
LifecycleHookRunner: () => LifecycleHookRunner,
|
|
@@ -31123,12 +31704,16 @@ __export(dist_exports, {
|
|
|
31123
31704
|
NoneCheckSchema: () => NoneCheckSchema,
|
|
31124
31705
|
NoopSubagentProvider: () => NoopSubagentProvider,
|
|
31125
31706
|
OUTPUT_QUALITY_DIRECTIVE: () => OUTPUT_QUALITY_DIRECTIVE,
|
|
31707
|
+
PROFILE_RESOURCE_POLICIES: () => PROFILE_RESOURCE_POLICIES,
|
|
31126
31708
|
PROMPT_MODULES: () => PROMPT_MODULES,
|
|
31127
31709
|
PROPRIETARY_REFUSAL_TEXT: () => PROPRIETARY_REFUSAL_TEXT,
|
|
31128
31710
|
PROPRIETARY_SECRECY_MARKER: () => PROPRIETARY_SECRECY_MARKER,
|
|
31129
31711
|
PROPRIETARY_SECRECY_MODULE: () => PROPRIETARY_SECRECY_MODULE,
|
|
31130
31712
|
PlanError: () => PlanError,
|
|
31713
|
+
PressureThresholdsSchema: () => PressureThresholdsSchema,
|
|
31131
31714
|
ProfileSchema: () => ProfileSchema,
|
|
31715
|
+
ResourcePolicySchema: () => ResourcePolicySchema,
|
|
31716
|
+
ResourceStageSchema: () => ResourceStageSchema,
|
|
31132
31717
|
SESSION_EVENT_KINDS: () => SESSION_EVENT_KINDS,
|
|
31133
31718
|
SESSION_EXPORT_FORMAT: () => SESSION_EXPORT_FORMAT,
|
|
31134
31719
|
SESSION_EXPORT_VERSION: () => SESSION_EXPORT_VERSION,
|
|
@@ -31152,6 +31737,10 @@ __export(dist_exports, {
|
|
|
31152
31737
|
TOOL_DEFINITIONS: () => TOOL_DEFINITIONS,
|
|
31153
31738
|
TOOL_USE_PROTOCOL_DIRECTIVE: () => TOOL_USE_PROTOCOL_DIRECTIVE,
|
|
31154
31739
|
TURN_COMPLETION_MODULE: () => TURN_COMPLETION_MODULE,
|
|
31740
|
+
TaskConstraintSchema: () => TaskConstraintSchema,
|
|
31741
|
+
TaskContractConflictError: () => TaskContractConflictError,
|
|
31742
|
+
TaskContractSchema: () => TaskContractSchema,
|
|
31743
|
+
TaskCriterionSchema: () => TaskCriterionSchema,
|
|
31155
31744
|
UnknownMemberError: () => UnknownMemberError,
|
|
31156
31745
|
UnknownProfileError: () => UnknownProfileError,
|
|
31157
31746
|
VAULT_TOOL_DEFINITIONS: () => VAULT_TOOL_DEFINITIONS,
|
|
@@ -31173,8 +31762,10 @@ __export(dist_exports, {
|
|
|
31173
31762
|
applyInlineJsAutofix: () => applyInlineJsAutofix,
|
|
31174
31763
|
applyMotionAutofix: () => applyMotionAutofix,
|
|
31175
31764
|
applyRetryIfMissing: () => applyRetryIfMissing,
|
|
31765
|
+
applyTaskContractUpdate: () => applyTaskContractUpdate,
|
|
31176
31766
|
auditDegradedBanner: () => auditDegradedBanner,
|
|
31177
31767
|
auditSynthesisTiers: () => auditSynthesisTiers,
|
|
31768
|
+
budgetPressure: () => budgetPressure,
|
|
31178
31769
|
buildCompactionStateSnapshot: () => buildCompactionStateSnapshot,
|
|
31179
31770
|
buildCouncilCompletion: () => buildCouncilCompletion,
|
|
31180
31771
|
buildCustomParameters: () => buildCustomParameters,
|
|
@@ -31192,12 +31783,14 @@ __export(dist_exports, {
|
|
|
31192
31783
|
buildSystemPrompt: () => buildSystemPrompt,
|
|
31193
31784
|
buildSystemPromptSplit: () => buildSystemPromptSplit,
|
|
31194
31785
|
canRunParallel: () => canRunParallel,
|
|
31786
|
+
canSpendOutsideReserve: () => canSpendOutsideReserve,
|
|
31195
31787
|
canonicalTools: () => canonicalTools,
|
|
31196
31788
|
captureFailure: () => captureFailure,
|
|
31197
31789
|
checkImplementationCompletion: () => checkImplementationCompletion,
|
|
31198
31790
|
checkImplementationDelivery: () => checkImplementationDelivery,
|
|
31199
31791
|
checkMemberToolEmissionSets: () => checkMemberToolEmissionSets,
|
|
31200
31792
|
checkMemberToolEmissions: () => checkMemberToolEmissions,
|
|
31793
|
+
classifyHarnessChanges: () => classifyHarnessChanges,
|
|
31201
31794
|
classifyInterruptedTools: () => classifyInterruptedTools,
|
|
31202
31795
|
classifyMission: () => classifyMission,
|
|
31203
31796
|
classifyTaskScope: () => classifyTaskScope,
|
|
@@ -31209,7 +31802,10 @@ __export(dist_exports, {
|
|
|
31209
31802
|
compareReplayPrefix: () => compareReplayPrefix,
|
|
31210
31803
|
computeAgentSkills: () => computeAgentSkills,
|
|
31211
31804
|
computeAgentTools: () => computeAgentTools,
|
|
31805
|
+
computeBudget: () => computeBudget,
|
|
31212
31806
|
computeFalseDoneRate: () => computeFalseDoneRate,
|
|
31807
|
+
contractToCompactionFields: () => contractToCompactionFields,
|
|
31808
|
+
costPerVerifiedSolve: () => costPerVerifiedSolve,
|
|
31213
31809
|
councilModeBanner: () => councilModeBanner,
|
|
31214
31810
|
councilTierFromSize: () => councilTierFromSize,
|
|
31215
31811
|
countByStatus: () => countByStatus,
|
|
@@ -31221,6 +31817,8 @@ __export(dist_exports, {
|
|
|
31221
31817
|
createGraph: () => createGraph,
|
|
31222
31818
|
createRoutedRequestSnapshot: () => createRoutedRequestSnapshot,
|
|
31223
31819
|
defaultPersonaParse: () => defaultPersonaParse,
|
|
31820
|
+
defaultResourcePolicy: () => defaultResourcePolicy,
|
|
31821
|
+
deriveInitialContract: () => deriveInitialContract,
|
|
31224
31822
|
deriveMessages: () => deriveMessages,
|
|
31225
31823
|
deriveMissionState: () => deriveMissionState,
|
|
31226
31824
|
derivedToAgentMessages: () => derivedToAgentMessages,
|
|
@@ -31228,11 +31826,13 @@ __export(dist_exports, {
|
|
|
31228
31826
|
detectAssistantTextLoopWindow: () => detectAssistantTextLoopWindow,
|
|
31229
31827
|
detectDegradedRun: () => detectDegradedRun,
|
|
31230
31828
|
detectResponseLanguage: () => detectResponseLanguage,
|
|
31829
|
+
diffHarnessManifest: () => diffHarnessManifest,
|
|
31231
31830
|
disjointScopeSets: () => disjointScopeSets,
|
|
31232
31831
|
emptyContextGrowthStats: () => emptyContextGrowthStats,
|
|
31233
31832
|
enforceDesignPhaseToolEmissions: () => enforceDesignPhaseToolEmissions,
|
|
31234
31833
|
evaluateCompletion: () => evaluateCompletion,
|
|
31235
31834
|
evaluateMissionContinuation: () => evaluateMissionContinuation,
|
|
31835
|
+
evaluateResourceReserveGate: () => evaluateResourceReserveGate,
|
|
31236
31836
|
executeTool: () => executeTool,
|
|
31237
31837
|
exportSession: () => exportSession,
|
|
31238
31838
|
exportSessionJson: () => exportSessionJson,
|
|
@@ -31249,6 +31849,7 @@ __export(dist_exports, {
|
|
|
31249
31849
|
forkSession: () => forkSession,
|
|
31250
31850
|
formatCompactionStateSnapshot: () => formatCompactionStateSnapshot,
|
|
31251
31851
|
formatLessonsForContext: () => formatLessonsForContext,
|
|
31852
|
+
formatResourceSnapshot: () => formatResourceSnapshot,
|
|
31252
31853
|
getAgent: () => getAgent,
|
|
31253
31854
|
getAllTools: () => getAllTools,
|
|
31254
31855
|
getAvailableTools: () => getAvailableTools,
|
|
@@ -31265,7 +31866,9 @@ __export(dist_exports, {
|
|
|
31265
31866
|
getSkillMetadata: () => getSkillMetadata,
|
|
31266
31867
|
getSkillsByCategory: () => getSkillsByCategory,
|
|
31267
31868
|
getToolDescriptions: () => getToolDescriptions,
|
|
31869
|
+
harnessInputHash: () => harnessInputHash,
|
|
31268
31870
|
hasInteractiveClarification: () => hasInteractiveClarification,
|
|
31871
|
+
hashHarnessManifest: () => hashHarnessManifest,
|
|
31269
31872
|
hashToolCall: () => hashToolCall,
|
|
31270
31873
|
hookMatches: () => hookMatches,
|
|
31271
31874
|
interruptedEventData: () => interruptedEventData,
|
|
@@ -31299,10 +31902,13 @@ __export(dist_exports, {
|
|
|
31299
31902
|
isSettled: () => isSettled,
|
|
31300
31903
|
isStatusTheaterUnit: () => isStatusTheaterUnit,
|
|
31301
31904
|
isValidTool: () => isValidTool,
|
|
31905
|
+
isVerificationReserveProtected: () => isVerificationReserveProtected,
|
|
31302
31906
|
isVerifyToolCheckSkipped: () => isVerifyToolCheckSkipped,
|
|
31303
31907
|
jaccardSimilarity: () => jaccardSimilarity,
|
|
31304
31908
|
jsonBytes: () => jsonBytes,
|
|
31305
31909
|
lastVerificationRun: () => lastVerificationRun,
|
|
31910
|
+
latestSurfaceSeqByKind: () => latestSurfaceSeqByKind,
|
|
31911
|
+
ledgerDeltaFor: () => ledgerDeltaFor,
|
|
31306
31912
|
lineageOf: () => lineageOf,
|
|
31307
31913
|
lintSynthesisHonesty: () => lintSynthesisHonesty,
|
|
31308
31914
|
listCodingSkills: () => listCodingSkills,
|
|
@@ -31331,6 +31937,7 @@ __export(dist_exports, {
|
|
|
31331
31937
|
parseVerifyVerdict: () => parseVerifyVerdict,
|
|
31332
31938
|
pathsOverlap: () => pathsOverlap,
|
|
31333
31939
|
pickWeakest: () => pickWeakest,
|
|
31940
|
+
profileHash: () => profileHash,
|
|
31334
31941
|
promoteMember: () => promoteMember,
|
|
31335
31942
|
rankByWeakness: () => rankByWeakness,
|
|
31336
31943
|
readLessonsDeduped: () => readLessonsDeduped,
|
|
@@ -31357,6 +31964,7 @@ __export(dist_exports, {
|
|
|
31357
31964
|
resolveSessionsDir: () => resolveSessionsDir,
|
|
31358
31965
|
resolveSkillDependencies: () => resolveSkillDependencies,
|
|
31359
31966
|
resolveVerifyRetryTool: () => resolveVerifyRetryTool,
|
|
31967
|
+
resourcePolicyHash: () => resourcePolicyHash,
|
|
31360
31968
|
restrictImplementationWrites: () => restrictImplementationWrites,
|
|
31361
31969
|
resumeSession: () => resumeSession,
|
|
31362
31970
|
retrySafetyForSideEffect: () => retrySafetyForSideEffect,
|
|
@@ -31394,9 +32002,11 @@ __export(dist_exports, {
|
|
|
31394
32002
|
topoLevels: () => topoLevels,
|
|
31395
32003
|
unregisterCustomTool: () => unregisterCustomTool,
|
|
31396
32004
|
unregisterSkill: () => unregisterSkill,
|
|
32005
|
+
usageFromLedger: () => usageFromLedger,
|
|
31397
32006
|
utf8Bytes: () => utf8Bytes,
|
|
31398
32007
|
validateCodingSkillRequires: () => validateCodingSkillRequires,
|
|
31399
32008
|
validateGraph: () => validateGraph,
|
|
32009
|
+
validateResourceAndContractEvents: () => validateResourceAndContractEvents,
|
|
31400
32010
|
validateSessionTrace: () => validateSessionTrace,
|
|
31401
32011
|
verificationCostRatio: () => verificationCostRatio,
|
|
31402
32012
|
verifiedSolveRate: () => verifiedSolveRate,
|
|
@@ -31695,6 +32305,189 @@ var init_sessionManager = __esm({
|
|
|
31695
32305
|
}
|
|
31696
32306
|
});
|
|
31697
32307
|
|
|
32308
|
+
// src/cli/budget/resourceLedger.ts
|
|
32309
|
+
function rebuildLedgerFromEvents(events) {
|
|
32310
|
+
const ledger = new ResourceLedger();
|
|
32311
|
+
for (const e of events) {
|
|
32312
|
+
if (e.kind === "tool.call") {
|
|
32313
|
+
ledger.record("tool-call", 1);
|
|
32314
|
+
} else if (e.kind === "verification.run") {
|
|
32315
|
+
ledger.record("verification", 0);
|
|
32316
|
+
}
|
|
32317
|
+
}
|
|
32318
|
+
return ledger;
|
|
32319
|
+
}
|
|
32320
|
+
var ResourceLedger;
|
|
32321
|
+
var init_resourceLedger = __esm({
|
|
32322
|
+
"src/cli/budget/resourceLedger.ts"() {
|
|
32323
|
+
"use strict";
|
|
32324
|
+
init_dist();
|
|
32325
|
+
init_dist();
|
|
32326
|
+
ResourceLedger = class _ResourceLedger {
|
|
32327
|
+
entries = [];
|
|
32328
|
+
nextSeq = 1;
|
|
32329
|
+
static fromEntries(entries) {
|
|
32330
|
+
const ledger = new _ResourceLedger();
|
|
32331
|
+
ledger.entries = [...entries];
|
|
32332
|
+
ledger.nextSeq = entries.reduce((m, e) => Math.max(m, e.seq), 0) + 1;
|
|
32333
|
+
return ledger;
|
|
32334
|
+
}
|
|
32335
|
+
/** Record one spend. Returns the entry (host call sites only). */
|
|
32336
|
+
record(reason, calls = 1) {
|
|
32337
|
+
const entry = { seq: this.nextSeq++, reason, delta: ledgerDeltaFor(reason, calls) };
|
|
32338
|
+
this.entries.push(entry);
|
|
32339
|
+
return entry;
|
|
32340
|
+
}
|
|
32341
|
+
snapshot() {
|
|
32342
|
+
return [...this.entries];
|
|
32343
|
+
}
|
|
32344
|
+
/** Replace state (BudgetRuntime resume path); host call sites only. */
|
|
32345
|
+
resetTo(entries) {
|
|
32346
|
+
this.entries = [...entries];
|
|
32347
|
+
this.nextSeq = entries.reduce((m, e) => Math.max(m, e.seq), 0) + 1;
|
|
32348
|
+
}
|
|
32349
|
+
usage() {
|
|
32350
|
+
return usageFromLedger(this.entries);
|
|
32351
|
+
}
|
|
32352
|
+
/** Current budget projection under the given policy. Pure over the ledger. */
|
|
32353
|
+
budget(policy, stage = "implement") {
|
|
32354
|
+
const usage = this.usage();
|
|
32355
|
+
return computeBudget(policy, { toolCallsUsed: usage.toolCallsUsed, elapsedMs: usage.wallMs, tokensUsed: usage.tokensUsed }, stage);
|
|
32356
|
+
}
|
|
32357
|
+
pressure(policy) {
|
|
32358
|
+
return budgetPressure(this.budget(policy), policy);
|
|
32359
|
+
}
|
|
32360
|
+
};
|
|
32361
|
+
}
|
|
32362
|
+
});
|
|
32363
|
+
|
|
32364
|
+
// src/cli/budget/resourceSnapshot.ts
|
|
32365
|
+
function buildResourceSnapshot(budget, policy) {
|
|
32366
|
+
return {
|
|
32367
|
+
toolCallsLimit: budget.toolCalls.limit,
|
|
32368
|
+
toolCallsUsed: budget.toolCalls.used,
|
|
32369
|
+
toolCallsRemaining: budget.toolCalls.remaining,
|
|
32370
|
+
...budget.wallTime.remainingMs !== void 0 ? { wallMsRemaining: budget.wallTime.remainingMs } : {},
|
|
32371
|
+
verificationReserve: budget.reserve.verification,
|
|
32372
|
+
repairReserve: budget.reserve.repair,
|
|
32373
|
+
stage: budget.stage,
|
|
32374
|
+
pressure: budgetPressure(budget, policy),
|
|
32375
|
+
reserveProtected: isVerificationReserveProtected(budget)
|
|
32376
|
+
};
|
|
32377
|
+
}
|
|
32378
|
+
function shouldEmitSnapshot(previous, next) {
|
|
32379
|
+
if (!previous) return true;
|
|
32380
|
+
if (previous.stage !== next.stage) return true;
|
|
32381
|
+
if (previous.pressure !== next.pressure) return true;
|
|
32382
|
+
if (previous.reserveProtected !== next.reserveProtected) return true;
|
|
32383
|
+
if (previous.toolCallsUsed !== next.toolCallsUsed) return true;
|
|
32384
|
+
return false;
|
|
32385
|
+
}
|
|
32386
|
+
var init_resourceSnapshot = __esm({
|
|
32387
|
+
"src/cli/budget/resourceSnapshot.ts"() {
|
|
32388
|
+
"use strict";
|
|
32389
|
+
init_dist();
|
|
32390
|
+
}
|
|
32391
|
+
});
|
|
32392
|
+
|
|
32393
|
+
// src/cli/budget/budgetRuntime.ts
|
|
32394
|
+
function resolveResourceEnforcement(env = process.env) {
|
|
32395
|
+
return env.ZELARI_RESOURCE_ENFORCEMENT === "protected" ? "protected" : "advisory";
|
|
32396
|
+
}
|
|
32397
|
+
var DEFAULT_ESSENTIAL_TOOLS, ADVISORY_NOTICE, PROTECTED_DENIAL, BudgetRuntime;
|
|
32398
|
+
var init_budgetRuntime = __esm({
|
|
32399
|
+
"src/cli/budget/budgetRuntime.ts"() {
|
|
32400
|
+
"use strict";
|
|
32401
|
+
init_dist();
|
|
32402
|
+
init_resourceLedger();
|
|
32403
|
+
init_resourceSnapshot();
|
|
32404
|
+
DEFAULT_ESSENTIAL_TOOLS = [
|
|
32405
|
+
"bash",
|
|
32406
|
+
"read_file",
|
|
32407
|
+
"edit_file",
|
|
32408
|
+
"write_file",
|
|
32409
|
+
"apply_diff",
|
|
32410
|
+
"grep_content",
|
|
32411
|
+
"list_files",
|
|
32412
|
+
"show_diff"
|
|
32413
|
+
];
|
|
32414
|
+
ADVISORY_NOTICE = "Resource advisory: verification reserve reached. Prioritize test/typecheck/build/diff and targeted repair; avoid broad exploration or delegation.";
|
|
32415
|
+
PROTECTED_DENIAL = "Resource protected: remaining tool calls are reserved for verification and targeted repair. Run the required checks (test/typecheck/build), read the failure, apply a minimal fix, retest \u2014 or report BLOCKED with the evidence you have.";
|
|
32416
|
+
BudgetRuntime = class {
|
|
32417
|
+
policy;
|
|
32418
|
+
enforcement;
|
|
32419
|
+
ledger;
|
|
32420
|
+
essential;
|
|
32421
|
+
stage;
|
|
32422
|
+
lastEmitted;
|
|
32423
|
+
constructor(profileId, opts = {}) {
|
|
32424
|
+
this.policy = opts.policy ?? defaultResourcePolicy(profileId);
|
|
32425
|
+
this.enforcement = opts.enforcement ?? "advisory";
|
|
32426
|
+
this.essential = new Set(opts.essentialTools ?? DEFAULT_ESSENTIAL_TOOLS);
|
|
32427
|
+
this.stage = opts.stage ?? "implement";
|
|
32428
|
+
this.ledger = new ResourceLedger();
|
|
32429
|
+
}
|
|
32430
|
+
/**
|
|
32431
|
+
* Count one tool call; returns the snapshot to emit when §10.4 says so
|
|
32432
|
+
* (first sight, stage/pressure change, reserve crossing, any usage delta).
|
|
32433
|
+
*/
|
|
32434
|
+
noteToolCall() {
|
|
32435
|
+
this.ledger.record("tool-call");
|
|
32436
|
+
return this.emitIfDue();
|
|
32437
|
+
}
|
|
32438
|
+
/** §10.4 verification start: stage change (and a zero-cost ledger mark). */
|
|
32439
|
+
noteVerificationStart() {
|
|
32440
|
+
this.ledger.record("verification", 0);
|
|
32441
|
+
return this.setStage("verify");
|
|
32442
|
+
}
|
|
32443
|
+
/** §10.4 repair start. */
|
|
32444
|
+
noteRepairStart() {
|
|
32445
|
+
return this.setStage("repair");
|
|
32446
|
+
}
|
|
32447
|
+
/** Stage transition; emits when the stage actually changes. */
|
|
32448
|
+
setStage(stage) {
|
|
32449
|
+
if (stage === this.stage) return null;
|
|
32450
|
+
this.stage = stage;
|
|
32451
|
+
return this.emitIfDue();
|
|
32452
|
+
}
|
|
32453
|
+
/** Current projection without emitting. */
|
|
32454
|
+
current() {
|
|
32455
|
+
return buildResourceSnapshot(this.ledger.budget(this.policy, this.stage), this.policy);
|
|
32456
|
+
}
|
|
32457
|
+
/** §11.3 gate — advisory mode never blocks; protected mode guards the zone. */
|
|
32458
|
+
gateToolCall(toolName) {
|
|
32459
|
+
const snapshot = this.current();
|
|
32460
|
+
if (!snapshot.reserveProtected) return { allowed: true, advisory: false, snapshot };
|
|
32461
|
+
if (this.enforcement === "advisory") {
|
|
32462
|
+
return { allowed: true, advisory: true, reason: ADVISORY_NOTICE, snapshot };
|
|
32463
|
+
}
|
|
32464
|
+
if (this.essential.has(toolName)) {
|
|
32465
|
+
return { allowed: true, advisory: true, reason: ADVISORY_NOTICE, snapshot };
|
|
32466
|
+
}
|
|
32467
|
+
return { allowed: false, advisory: false, reason: PROTECTED_DENIAL, snapshot };
|
|
32468
|
+
}
|
|
32469
|
+
/** Resume path (§9.5): rebuild usage from the session log, no emission. */
|
|
32470
|
+
adoptLedgerFromEvents(events) {
|
|
32471
|
+
const rebuilt = rebuildLedgerFromEvents(events);
|
|
32472
|
+
this.ledger.resetTo(rebuilt.snapshot());
|
|
32473
|
+
this.lastEmitted = void 0;
|
|
32474
|
+
}
|
|
32475
|
+
/** Latest emitted snapshot (what the model surface shows), if any. */
|
|
32476
|
+
latestEmitted() {
|
|
32477
|
+
return this.lastEmitted;
|
|
32478
|
+
}
|
|
32479
|
+
emitIfDue() {
|
|
32480
|
+
const next = this.current();
|
|
32481
|
+
if (shouldEmitSnapshot(this.lastEmitted, next)) {
|
|
32482
|
+
this.lastEmitted = next;
|
|
32483
|
+
return next;
|
|
32484
|
+
}
|
|
32485
|
+
return null;
|
|
32486
|
+
}
|
|
32487
|
+
};
|
|
32488
|
+
}
|
|
32489
|
+
});
|
|
32490
|
+
|
|
31698
32491
|
// src/cli/sessionSpine.ts
|
|
31699
32492
|
import path21 from "node:path";
|
|
31700
32493
|
function spineEnabled() {
|
|
@@ -31776,6 +32569,14 @@ function mapBrainEventToSpine(ev) {
|
|
|
31776
32569
|
}
|
|
31777
32570
|
async function wrapSessionWriter(inner, sessionId2, options = {}) {
|
|
31778
32571
|
const spine = await SessionSpineMirror.adopt(sessionId2, options);
|
|
32572
|
+
if (spine.status === "active") {
|
|
32573
|
+
const profile = options.extraStarted?.profile;
|
|
32574
|
+
spine.attachBudgetRuntime(
|
|
32575
|
+
new BudgetRuntime(typeof profile === "string" ? profile : "kraken/v1", {
|
|
32576
|
+
enforcement: resolveResourceEnforcement()
|
|
32577
|
+
})
|
|
32578
|
+
);
|
|
32579
|
+
}
|
|
31779
32580
|
return new SpineMirroringWriter(inner, spine.status === "active" ? spine : null);
|
|
31780
32581
|
}
|
|
31781
32582
|
var MAX_STREAM_BUFFERS, SessionSpineMirror, SpineMirroringWriter;
|
|
@@ -31785,6 +32586,7 @@ var init_sessionSpine = __esm({
|
|
|
31785
32586
|
init_session();
|
|
31786
32587
|
init_session();
|
|
31787
32588
|
init_verification2();
|
|
32589
|
+
init_budgetRuntime();
|
|
31788
32590
|
MAX_STREAM_BUFFERS = 32;
|
|
31789
32591
|
SessionSpineMirror = class _SessionSpineMirror {
|
|
31790
32592
|
constructor(sessionId2, options) {
|
|
@@ -31796,6 +32598,10 @@ var init_sessionSpine = __esm({
|
|
|
31796
32598
|
chain = Promise.resolve(null);
|
|
31797
32599
|
streamBuffers = /* @__PURE__ */ new Map();
|
|
31798
32600
|
warned = false;
|
|
32601
|
+
/** Host-owned budget runtime (attached via attachBudgetRuntime). */
|
|
32602
|
+
budgetRuntime = null;
|
|
32603
|
+
/** 2.6 Track A: set once a task.contract has been seeded (or the log had one). */
|
|
32604
|
+
contractSeeded = false;
|
|
31799
32605
|
status = "disabled";
|
|
31800
32606
|
/** Seq the log continued from when adopting an existing session. */
|
|
31801
32607
|
resumedFromSeq;
|
|
@@ -31812,6 +32618,9 @@ var init_sessionSpine = __esm({
|
|
|
31812
32618
|
const sessionDir = path21.join(mirror.sessionsDir, sessionId2);
|
|
31813
32619
|
const report = await readSessionLog(path21.join(sessionDir, "events.jsonl"));
|
|
31814
32620
|
const existed = report.events.length > 0 || report.issues.length > 0;
|
|
32621
|
+
if (report.events.some((e) => e.kind === "task.contract" || e.kind === "user.message")) {
|
|
32622
|
+
mirror.contractSeeded = true;
|
|
32623
|
+
}
|
|
31815
32624
|
const lastSeq = report.events[report.events.length - 1]?.seq ?? 0;
|
|
31816
32625
|
mirror.writer = await SessionLogWriter.open(sessionDir, sessionId2, lastSeq + 1, {
|
|
31817
32626
|
now: options.now
|
|
@@ -31828,6 +32637,16 @@ var init_sessionSpine = __esm({
|
|
|
31828
32637
|
...options.extraStarted
|
|
31829
32638
|
}
|
|
31830
32639
|
});
|
|
32640
|
+
if (options.harnessManifest) {
|
|
32641
|
+
await mirror.append({
|
|
32642
|
+
kind: "session.harness_manifest",
|
|
32643
|
+
actor: ACTOR_SYSTEM,
|
|
32644
|
+
data: {
|
|
32645
|
+
manifest: options.harnessManifest.manifest,
|
|
32646
|
+
manifestHash: options.harnessManifest.manifestHash
|
|
32647
|
+
}
|
|
32648
|
+
});
|
|
32649
|
+
}
|
|
31831
32650
|
mirror.status = "active";
|
|
31832
32651
|
} catch (err) {
|
|
31833
32652
|
if (err instanceof SessionLogLockedError) {
|
|
@@ -31842,7 +32661,8 @@ var init_sessionSpine = __esm({
|
|
|
31842
32661
|
}
|
|
31843
32662
|
/** Log the user prompt — the P1 gap the 1.x log never closed. */
|
|
31844
32663
|
userMessage(text) {
|
|
31845
|
-
|
|
32664
|
+
const seqP = this.append({ kind: "user.message", actor: ACTOR_USER, data: { text } });
|
|
32665
|
+
void seqP;
|
|
31846
32666
|
}
|
|
31847
32667
|
/**
|
|
31848
32668
|
* Log an assistant message outside the streaming path — legacy
|
|
@@ -31857,6 +32677,45 @@ var init_sessionSpine = __esm({
|
|
|
31857
32677
|
});
|
|
31858
32678
|
}
|
|
31859
32679
|
/** Await all pending appends (import → derive read-back needs this). */
|
|
32680
|
+
/**
|
|
32681
|
+
* Record the canonical harness manifest (2.6 Track A, doc section 6.5): one
|
|
32682
|
+
* state-only event at session start / manifest change. Degrade-and-stop
|
|
32683
|
+
* like every other mirror method - the spine never breaks the loop.
|
|
32684
|
+
*/
|
|
32685
|
+
harnessManifest(manifest, manifestHash) {
|
|
32686
|
+
void this.append({
|
|
32687
|
+
kind: "session.harness_manifest",
|
|
32688
|
+
actor: ACTOR_SYSTEM,
|
|
32689
|
+
data: { manifest, manifestHash }
|
|
32690
|
+
});
|
|
32691
|
+
}
|
|
32692
|
+
/**
|
|
32693
|
+
* Attach the host-owned budget runtime (2.6 Track B, Phase 2/3). From here
|
|
32694
|
+
* on every `tool.call` that lands on the spine is counted and — at §10.4
|
|
32695
|
+
* frequency — a `resource.snapshot` event is appended right after it.
|
|
32696
|
+
* Degrade-and-stop discipline applies: budget wiring never breaks a turn.
|
|
32697
|
+
*/
|
|
32698
|
+
attachBudgetRuntime(runtime) {
|
|
32699
|
+
this.budgetRuntime = runtime;
|
|
32700
|
+
}
|
|
32701
|
+
/** Latest emitted resource snapshot (the model-visible one), or null. */
|
|
32702
|
+
latestResourceSnapshot() {
|
|
32703
|
+
return this.budgetRuntime?.latestEmitted() ?? null;
|
|
32704
|
+
}
|
|
32705
|
+
/**
|
|
32706
|
+
* §11.3 pre-dispatch gate for hosts that enforce the protected zone
|
|
32707
|
+
* (Phase 3): delegates to the attached runtime, never throws. Null when
|
|
32708
|
+
* no runtime is attached (hosts treat as "no budget info, allow").
|
|
32709
|
+
*/
|
|
32710
|
+
gateResourceToolCall(toolName) {
|
|
32711
|
+
const gate = this.budgetRuntime?.gateToolCall(toolName);
|
|
32712
|
+
if (!gate) return null;
|
|
32713
|
+
return { allowed: gate.allowed, ...gate.reason ? { reason: gate.reason } : {} };
|
|
32714
|
+
}
|
|
32715
|
+
/** Count a landed tool.call; returns the snapshot due (§10.4), if any. */
|
|
32716
|
+
onToolCallBudget() {
|
|
32717
|
+
return this.budgetRuntime?.noteToolCall() ?? null;
|
|
32718
|
+
}
|
|
31860
32719
|
async flush() {
|
|
31861
32720
|
await this.chain;
|
|
31862
32721
|
}
|
|
@@ -31961,7 +32820,31 @@ var init_sessionSpine = __esm({
|
|
|
31961
32820
|
}
|
|
31962
32821
|
append(input) {
|
|
31963
32822
|
if (!this.writer || this.status === "closed") return Promise.resolve(null);
|
|
31964
|
-
|
|
32823
|
+
const dueSnapshot = input.kind === "tool.call" ? this.onToolCallBudget() : null;
|
|
32824
|
+
const dueContract = input.kind === "user.message" && process.env.ZELARI_TASK_CONTRACT === "1" && !this.contractSeeded ? (this.contractSeeded = true, input.data?.text) : null;
|
|
32825
|
+
let seq = this.chain.then(() => this.writer.append(input)).then((envelope) => envelope.seq);
|
|
32826
|
+
if (dueSnapshot) {
|
|
32827
|
+
seq = seq.then(
|
|
32828
|
+
(s) => this.writer.append({ kind: "resource.snapshot", actor: ACTOR_SYSTEM, data: { ...dueSnapshot } }).then(() => s)
|
|
32829
|
+
);
|
|
32830
|
+
}
|
|
32831
|
+
if (dueContract) {
|
|
32832
|
+
seq = seq.then(async (s) => {
|
|
32833
|
+
try {
|
|
32834
|
+
const contract = deriveInitialContract(s ?? 1, dueContract);
|
|
32835
|
+
if (contract) {
|
|
32836
|
+
await this.writer.append({
|
|
32837
|
+
kind: "task.contract",
|
|
32838
|
+
actor: ACTOR_SYSTEM,
|
|
32839
|
+
data: { contract, kind: "task.contract" }
|
|
32840
|
+
});
|
|
32841
|
+
}
|
|
32842
|
+
} catch {
|
|
32843
|
+
}
|
|
32844
|
+
return s;
|
|
32845
|
+
});
|
|
32846
|
+
}
|
|
32847
|
+
this.chain = seq.catch((err) => {
|
|
31965
32848
|
this.status = "degraded";
|
|
31966
32849
|
this.writer = null;
|
|
31967
32850
|
this.warnOnce(err);
|
|
@@ -33576,7 +34459,7 @@ var init_resolveStream = __esm({
|
|
|
33576
34459
|
});
|
|
33577
34460
|
|
|
33578
34461
|
// packages/core/dist/core/tools/toolOutputSpill.js
|
|
33579
|
-
import { createHash as
|
|
34462
|
+
import { createHash as createHash6, randomBytes as randomBytes2 } from "node:crypto";
|
|
33580
34463
|
import { existsSync as existsSync13, mkdirSync as mkdirSync7, writeFileSync as writeFileSync11 } from "node:fs";
|
|
33581
34464
|
import { homedir as homedir3, tmpdir } from "node:os";
|
|
33582
34465
|
import { join as join11 } from "node:path";
|
|
@@ -33606,14 +34489,14 @@ function spillToolOutput(fullText, meta3) {
|
|
|
33606
34489
|
if (!existsSync13(dir)) {
|
|
33607
34490
|
mkdirSync7(dir, { recursive: true });
|
|
33608
34491
|
}
|
|
33609
|
-
const hash3 =
|
|
34492
|
+
const hash3 = createHash6("sha256").update(fullText).digest("hex").slice(0, 12);
|
|
33610
34493
|
const stamp = Date.now().toString(36);
|
|
33611
34494
|
const rnd = randomBytes2(3).toString("hex");
|
|
33612
34495
|
const safeTool = (meta3?.toolName ?? "tool").replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 32);
|
|
33613
34496
|
const file2 = `${stamp}-${safeTool}-${hash3}-${rnd}.txt`;
|
|
33614
|
-
const
|
|
33615
|
-
writeFileSync11(
|
|
33616
|
-
return
|
|
34497
|
+
const path65 = join11(dir, file2);
|
|
34498
|
+
writeFileSync11(path65, fullText, "utf8");
|
|
34499
|
+
return path65;
|
|
33617
34500
|
} catch {
|
|
33618
34501
|
return null;
|
|
33619
34502
|
}
|
|
@@ -33659,10 +34542,10 @@ function truncateToolResult(text, capOrOpts = TOOL_RESULT_LINE_CAP) {
|
|
|
33659
34542
|
${tail2}`;
|
|
33660
34543
|
}
|
|
33661
34544
|
if (doSpill) {
|
|
33662
|
-
const
|
|
33663
|
-
if (
|
|
34545
|
+
const path65 = spillToolOutput(text, { toolName: opts.toolName });
|
|
34546
|
+
if (path65) {
|
|
33664
34547
|
const spillNote = `
|
|
33665
|
-
\u2026 [full output spilled to: ${
|
|
34548
|
+
\u2026 [full output spilled to: ${path65} \u2014 re-read with read_file if you need the complete text] \u2026`;
|
|
33666
34549
|
if (preview.includes("] \u2026\n")) {
|
|
33667
34550
|
preview = preview.replace("] \u2026\n", `] \u2026${spillNote}
|
|
33668
34551
|
`);
|
|
@@ -36078,7 +36961,7 @@ import {
|
|
|
36078
36961
|
} from "node:fs";
|
|
36079
36962
|
import { join as join13, basename } from "node:path";
|
|
36080
36963
|
import { homedir as homedir5 } from "node:os";
|
|
36081
|
-
import { createHash as
|
|
36964
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
36082
36965
|
function resolveWorkspaceRoot(projectRoot = process.cwd()) {
|
|
36083
36966
|
const candidates = [
|
|
36084
36967
|
join13(projectRoot, ".zelari"),
|
|
@@ -36094,7 +36977,7 @@ function resolveWorkspaceRoot(projectRoot = process.cwd()) {
|
|
|
36094
36977
|
return candidates[0];
|
|
36095
36978
|
}
|
|
36096
36979
|
function hashProject(projectPath) {
|
|
36097
|
-
return
|
|
36980
|
+
return createHash7("sha1").update(realpathSync(projectPath)).digest("hex").slice(0, 12);
|
|
36098
36981
|
}
|
|
36099
36982
|
function isWritableDir(dir) {
|
|
36100
36983
|
try {
|
|
@@ -36408,28 +37291,28 @@ var init_storage = __esm({
|
|
|
36408
37291
|
VALID_SCALARS = /^(true|false|null|~)$/i;
|
|
36409
37292
|
Storage = class {
|
|
36410
37293
|
/** Read a Markdown file with frontmatter. Throws if not found. */
|
|
36411
|
-
read(
|
|
36412
|
-
if (!existsSync19(
|
|
36413
|
-
throw new Error(`File not found: ${
|
|
37294
|
+
read(path65) {
|
|
37295
|
+
if (!existsSync19(path65)) {
|
|
37296
|
+
throw new Error(`File not found: ${path65}`);
|
|
36414
37297
|
}
|
|
36415
|
-
const md = readFileSync16(
|
|
37298
|
+
const md = readFileSync16(path65, "utf8");
|
|
36416
37299
|
return parseFrontmatter(md);
|
|
36417
37300
|
}
|
|
36418
37301
|
/** Read a Markdown file; returns null if not found. */
|
|
36419
|
-
readIfExists(
|
|
36420
|
-
if (!existsSync19(
|
|
36421
|
-
return this.read(
|
|
37302
|
+
readIfExists(path65) {
|
|
37303
|
+
if (!existsSync19(path65)) return null;
|
|
37304
|
+
return this.read(path65);
|
|
36422
37305
|
}
|
|
36423
37306
|
/**
|
|
36424
37307
|
* Write a Markdown file atomically (tmp + rename). Creates parent dirs.
|
|
36425
37308
|
* The meta object is serialized as YAML frontmatter; body as Markdown.
|
|
36426
37309
|
*/
|
|
36427
|
-
write(
|
|
36428
|
-
mkdirSync11(dirname2(
|
|
36429
|
-
const tmp =
|
|
37310
|
+
write(path65, meta3, body) {
|
|
37311
|
+
mkdirSync11(dirname2(path65), { recursive: true });
|
|
37312
|
+
const tmp = path65 + ".tmp-" + process.pid;
|
|
36430
37313
|
const md = serializeFrontmatter(meta3, body);
|
|
36431
37314
|
writeFileSync13(tmp, md, "utf8");
|
|
36432
|
-
renameSync2(tmp,
|
|
37315
|
+
renameSync2(tmp, path65);
|
|
36433
37316
|
}
|
|
36434
37317
|
/** List all .md files in a directory (non-recursive). */
|
|
36435
37318
|
listMarkdown(dir) {
|
|
@@ -36491,8 +37374,8 @@ function nextPlanTaskId(store6) {
|
|
|
36491
37374
|
return `t${store6.counter}`;
|
|
36492
37375
|
}
|
|
36493
37376
|
function writePlanTaskArtifact(rootDir, task) {
|
|
36494
|
-
const
|
|
36495
|
-
mkdirSync12(dirname3(
|
|
37377
|
+
const path65 = join15(rootDir, "plan-tasks", `${task.id}.md`);
|
|
37378
|
+
mkdirSync12(dirname3(path65), { recursive: true });
|
|
36496
37379
|
const meta3 = {
|
|
36497
37380
|
kind: "task",
|
|
36498
37381
|
id: task.id,
|
|
@@ -36513,7 +37396,7 @@ function writePlanTaskArtifact(rootDir, task) {
|
|
|
36513
37396
|
task.notes?.trim() ? task.notes.trim() : "_(no notes)_",
|
|
36514
37397
|
""
|
|
36515
37398
|
].filter((l) => l !== null).join("\n");
|
|
36516
|
-
new Storage().write(
|
|
37399
|
+
new Storage().write(path65, meta3, body);
|
|
36517
37400
|
}
|
|
36518
37401
|
function loadHandle(rootDir) {
|
|
36519
37402
|
const jsonPath = join15(rootDir, "plan.json");
|
|
@@ -36912,7 +37795,7 @@ var init_inspectTypecheckSafety = __esm({
|
|
|
36912
37795
|
|
|
36913
37796
|
// src/cli/tools/inspectCommand.ts
|
|
36914
37797
|
import { spawn as spawn7 } from "node:child_process";
|
|
36915
|
-
import { createHash as
|
|
37798
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
36916
37799
|
import { existsSync as existsSync21, promises as fs17 } from "node:fs";
|
|
36917
37800
|
import os8 from "node:os";
|
|
36918
37801
|
import path30 from "node:path";
|
|
@@ -36999,7 +37882,7 @@ function buildInspectCommand(op, ctx) {
|
|
|
36999
37882
|
}
|
|
37000
37883
|
case "typecheck": {
|
|
37001
37884
|
const project = path30.resolve(ctx.cwd, op.project ?? "tsconfig.json");
|
|
37002
|
-
const hash3 =
|
|
37885
|
+
const hash3 = createHash8("sha256").update(project).digest("hex").slice(0, 16);
|
|
37003
37886
|
const tsBuildInfoFile = path30.join(os8.tmpdir(), "zelari-inspect", `${hash3}.tsbuildinfo`);
|
|
37004
37887
|
return {
|
|
37005
37888
|
ok: true,
|
|
@@ -38438,9 +39321,9 @@ var init_store2 = __esm({
|
|
|
38438
39321
|
import { promises as fs18, existsSync as existsSync22, readFileSync as readFileSync19 } from "node:fs";
|
|
38439
39322
|
import { homedir as homedir6 } from "node:os";
|
|
38440
39323
|
import path33 from "node:path";
|
|
38441
|
-
import { createHash as
|
|
39324
|
+
import { createHash as createHash9 } from "node:crypto";
|
|
38442
39325
|
function getIndexPath(root) {
|
|
38443
|
-
const hash3 =
|
|
39326
|
+
const hash3 = createHash9("sha1").update(path33.resolve(root)).digest("hex").slice(0, 16);
|
|
38444
39327
|
return process.env.ZELARI_SEMANTIC_FILE ?? path33.join(homedir6(), ".tmp", "zelari-code", "semantic", `${hash3}.json`);
|
|
38445
39328
|
}
|
|
38446
39329
|
async function collectSourceFiles(root, maxFiles = 1500) {
|
|
@@ -39071,21 +39954,21 @@ function normalizeAuth(auth) {
|
|
|
39071
39954
|
return "agent";
|
|
39072
39955
|
}
|
|
39073
39956
|
function readSecrets() {
|
|
39074
|
-
const
|
|
39075
|
-
if (!existsSync23(
|
|
39957
|
+
const path65 = getSshSecretsPath();
|
|
39958
|
+
if (!existsSync23(path65)) return {};
|
|
39076
39959
|
try {
|
|
39077
|
-
return JSON.parse(readFileSync20(
|
|
39960
|
+
return JSON.parse(readFileSync20(path65, "utf8"));
|
|
39078
39961
|
} catch {
|
|
39079
39962
|
return {};
|
|
39080
39963
|
}
|
|
39081
39964
|
}
|
|
39082
39965
|
function writeSecrets(data) {
|
|
39083
|
-
const
|
|
39084
|
-
mkdirSync13(dirname4(
|
|
39085
|
-
writeFileSync15(
|
|
39966
|
+
const path65 = getSshSecretsPath();
|
|
39967
|
+
mkdirSync13(dirname4(path65), { recursive: true });
|
|
39968
|
+
writeFileSync15(path65, `${JSON.stringify(data, null, 2)}
|
|
39086
39969
|
`, "utf8");
|
|
39087
39970
|
try {
|
|
39088
|
-
chmodSync(
|
|
39971
|
+
chmodSync(path65, 384);
|
|
39089
39972
|
} catch {
|
|
39090
39973
|
}
|
|
39091
39974
|
}
|
|
@@ -39114,10 +39997,10 @@ function deleteSshPassword(id) {
|
|
|
39114
39997
|
writeSecrets({ passwords });
|
|
39115
39998
|
}
|
|
39116
39999
|
function readStore2() {
|
|
39117
|
-
const
|
|
39118
|
-
if (!existsSync23(
|
|
40000
|
+
const path65 = getSshTargetsPath();
|
|
40001
|
+
if (!existsSync23(path65)) return [];
|
|
39119
40002
|
try {
|
|
39120
|
-
const parsed = JSON.parse(readFileSync20(
|
|
40003
|
+
const parsed = JSON.parse(readFileSync20(path65, "utf8"));
|
|
39121
40004
|
const list = Array.isArray(parsed.targets) ? parsed.targets : [];
|
|
39122
40005
|
return list.filter(
|
|
39123
40006
|
(t) => t && typeof t.id === "string" && typeof t.host === "string" && typeof t.user === "string"
|
|
@@ -39132,11 +40015,11 @@ function readStore2() {
|
|
|
39132
40015
|
}
|
|
39133
40016
|
}
|
|
39134
40017
|
function writeStore2(targets) {
|
|
39135
|
-
const
|
|
39136
|
-
mkdirSync13(dirname4(
|
|
40018
|
+
const path65 = getSshTargetsPath();
|
|
40019
|
+
mkdirSync13(dirname4(path65), { recursive: true });
|
|
39137
40020
|
const clean = targets.map(({ hasPassword: _hp, ...t }) => t);
|
|
39138
40021
|
writeFileSync15(
|
|
39139
|
-
|
|
40022
|
+
path65,
|
|
39140
40023
|
`${JSON.stringify({ targets: clean }, null, 2)}
|
|
39141
40024
|
`,
|
|
39142
40025
|
"utf8"
|
|
@@ -39382,11 +40265,11 @@ function formatSshTargetsForPrompt() {
|
|
|
39382
40265
|
];
|
|
39383
40266
|
for (const t of targets) {
|
|
39384
40267
|
const tags = t.tags?.length ? ` tags=[${t.tags.join(",")}]` : "";
|
|
39385
|
-
const
|
|
40268
|
+
const path65 = t.defaultRemotePath ? ` remotePath=${t.defaultRemotePath}` : "";
|
|
39386
40269
|
const allow = t.allowedCommands?.length ? ` allowed=${t.allowedCommands.join("|")}` : " allowed=status-only";
|
|
39387
40270
|
const auth = t.auth === "password" ? " auth=password" : t.auth === "keyPath" ? " auth=key" : " auth=agent";
|
|
39388
40271
|
lines.push(
|
|
39389
|
-
`- id=${t.id} name=${t.name} ${t.user}@${t.host}:${t.port ?? 22}${auth}${
|
|
40272
|
+
`- id=${t.id} name=${t.name} ${t.user}@${t.host}:${t.port ?? 22}${auth}${path65}${tags}${allow}`
|
|
39390
40273
|
);
|
|
39391
40274
|
}
|
|
39392
40275
|
return lines.join("\n");
|
|
@@ -40064,7 +40947,7 @@ var init_lifecycleHooks = __esm({
|
|
|
40064
40947
|
});
|
|
40065
40948
|
|
|
40066
40949
|
// src/cli/toolResultCache.ts
|
|
40067
|
-
import { createHash as
|
|
40950
|
+
import { createHash as createHash10 } from "node:crypto";
|
|
40068
40951
|
import { promises as fs20 } from "node:fs";
|
|
40069
40952
|
import path39 from "node:path";
|
|
40070
40953
|
function isToolCacheEnabled() {
|
|
@@ -40077,7 +40960,7 @@ function resolveToolCacheTtlMs() {
|
|
|
40077
40960
|
return Number.isFinite(n) && n >= 0 ? n : TOOL_CACHE_DEFAULT_TTL_MS;
|
|
40078
40961
|
}
|
|
40079
40962
|
function hashKey(parts) {
|
|
40080
|
-
return
|
|
40963
|
+
return createHash10("sha256").update(JSON.stringify(parts), "utf8").digest("hex");
|
|
40081
40964
|
}
|
|
40082
40965
|
function resultBytes(result) {
|
|
40083
40966
|
try {
|
|
@@ -40832,7 +41715,7 @@ var init_toolRegistry = __esm({
|
|
|
40832
41715
|
});
|
|
40833
41716
|
|
|
40834
41717
|
// src/cli/state/fileStateStore.ts
|
|
40835
|
-
import { createHash as
|
|
41718
|
+
import { createHash as createHash12, randomUUID as randomUUID2 } from "node:crypto";
|
|
40836
41719
|
import { promises as fs21 } from "node:fs";
|
|
40837
41720
|
import * as path41 from "node:path";
|
|
40838
41721
|
function shortId() {
|
|
@@ -40884,7 +41767,7 @@ async function getStateStore(projectRoot, env = process.env) {
|
|
|
40884
41767
|
}
|
|
40885
41768
|
}
|
|
40886
41769
|
function hashStablePrompt(stable) {
|
|
40887
|
-
return
|
|
41770
|
+
return createHash12("sha256").update(stable, "utf8").digest("hex").slice(0, 16);
|
|
40888
41771
|
}
|
|
40889
41772
|
var DEFAULT_MATERIALIZE_CHARS, FileDurableStateStore, NoopDurableStateStore;
|
|
40890
41773
|
var init_fileStateStore = __esm({
|
|
@@ -41188,7 +42071,7 @@ function extractiveHistorySummary(dropped, opts) {
|
|
|
41188
42071
|
if (m.toolCalls) {
|
|
41189
42072
|
for (const tc of m.toolCalls) {
|
|
41190
42073
|
tools.set(tc.name, (tools.get(tc.name) ?? 0) + 1);
|
|
41191
|
-
|
|
42074
|
+
collectPaths3(tc.args, files);
|
|
41192
42075
|
}
|
|
41193
42076
|
}
|
|
41194
42077
|
} else if (m.role === "tool") {
|
|
@@ -41248,7 +42131,7 @@ function oneLine(s, max) {
|
|
|
41248
42131
|
if (t.length <= max) return t;
|
|
41249
42132
|
return `${t.slice(0, max - 1)}\u2026`;
|
|
41250
42133
|
}
|
|
41251
|
-
function
|
|
42134
|
+
function collectPaths3(args, out) {
|
|
41252
42135
|
if (!args || typeof args !== "object") return;
|
|
41253
42136
|
const obj = args;
|
|
41254
42137
|
for (const key of ["path", "file", "filepath", "filePath", "target", "cwd"]) {
|
|
@@ -42241,6 +43124,7 @@ __export(headlessSpine_exports, {
|
|
|
42241
43124
|
seedHeadlessModelHistory: () => seedHeadlessModelHistory,
|
|
42242
43125
|
sessionStartedEvent: () => sessionStartedEvent
|
|
42243
43126
|
});
|
|
43127
|
+
import path42 from "node:path";
|
|
42244
43128
|
function sessionStartedEvent(handle) {
|
|
42245
43129
|
return {
|
|
42246
43130
|
type: "session_started",
|
|
@@ -42272,6 +43156,14 @@ async function openHeadlessSpine(opts) {
|
|
|
42272
43156
|
};
|
|
42273
43157
|
const spine = await SessionSpineMirror.adopt(opts.sessionId, mirrorOpts);
|
|
42274
43158
|
if (spine.status === "active") {
|
|
43159
|
+
const budget = new BudgetRuntime(profileId, { enforcement: resolveResourceEnforcement() });
|
|
43160
|
+
if (spine.resumedFromSeq !== void 0 && spine.resumedFromSeq > 0) {
|
|
43161
|
+
const prior = await readSessionLog(
|
|
43162
|
+
path42.join(spine.sessionsDir, opts.sessionId, "events.jsonl")
|
|
43163
|
+
).catch(() => null);
|
|
43164
|
+
if (prior) budget.adoptLedgerFromEvents(prior.events);
|
|
43165
|
+
}
|
|
43166
|
+
spine.attachBudgetRuntime(budget);
|
|
42275
43167
|
spine.note("headless.profile", { profile: profileId, mode: opts.mode ?? "kraken" });
|
|
42276
43168
|
}
|
|
42277
43169
|
return {
|
|
@@ -42286,6 +43178,9 @@ async function openHeadlessSpine(opts) {
|
|
|
42286
43178
|
userMessage(text) {
|
|
42287
43179
|
spine.userMessage(text);
|
|
42288
43180
|
},
|
|
43181
|
+
gateResourceToolCall(toolName) {
|
|
43182
|
+
return spine.gateResourceToolCall(toolName);
|
|
43183
|
+
},
|
|
42289
43184
|
verificationRun(payload) {
|
|
42290
43185
|
spine.verificationRun(payload);
|
|
42291
43186
|
},
|
|
@@ -42402,8 +43297,10 @@ var init_headlessSpine = __esm({
|
|
|
42402
43297
|
init_dist();
|
|
42403
43298
|
init_session();
|
|
42404
43299
|
init_mission2();
|
|
43300
|
+
init_session();
|
|
42405
43301
|
init_runtime2();
|
|
42406
43302
|
init_sessionSpine();
|
|
43303
|
+
init_budgetRuntime();
|
|
42407
43304
|
init_headless();
|
|
42408
43305
|
}
|
|
42409
43306
|
});
|
|
@@ -43329,8 +44226,8 @@ function readPlan(ctx) {
|
|
|
43329
44226
|
} catch {
|
|
43330
44227
|
}
|
|
43331
44228
|
}
|
|
43332
|
-
const
|
|
43333
|
-
const doc = ctx.storage.readIfExists(
|
|
44229
|
+
const path65 = workspaceFile(ctx.rootDir, "plan");
|
|
44230
|
+
const doc = ctx.storage.readIfExists(path65);
|
|
43334
44231
|
if (!doc) return { phases: [], tasks: [], milestones: [] };
|
|
43335
44232
|
const meta3 = doc.meta;
|
|
43336
44233
|
return {
|
|
@@ -43508,7 +44405,7 @@ function addMilestoneRecord(ctx, summary, input) {
|
|
|
43508
44405
|
dueDate: input.dueDate,
|
|
43509
44406
|
targetVersion: version2
|
|
43510
44407
|
});
|
|
43511
|
-
const
|
|
44408
|
+
const path65 = join25(ctx.rootDir, "milestones", `${id}.md`);
|
|
43512
44409
|
const meta3 = {
|
|
43513
44410
|
kind: "milestone",
|
|
43514
44411
|
id,
|
|
@@ -43525,7 +44422,7 @@ function addMilestoneRecord(ctx, summary, input) {
|
|
|
43525
44422
|
`Target version: ${version2}`,
|
|
43526
44423
|
""
|
|
43527
44424
|
].join("\n");
|
|
43528
|
-
ctx.storage.write(
|
|
44425
|
+
ctx.storage.write(path65, meta3, body);
|
|
43529
44426
|
return { id, created: true };
|
|
43530
44427
|
}
|
|
43531
44428
|
function readPlanSummary(ctx) {
|
|
@@ -43729,7 +44626,7 @@ function addIdeaStub(ctx) {
|
|
|
43729
44626
|
const tags = args["tags"] ?? [];
|
|
43730
44627
|
const category = args["category"] ?? "General";
|
|
43731
44628
|
const id = `${nextAdrId(ctx)}-${slugify3(title)}`;
|
|
43732
|
-
const
|
|
44629
|
+
const path65 = workspaceArtifact(ctx.rootDir, "decisions", id);
|
|
43733
44630
|
const meta3 = {
|
|
43734
44631
|
kind: "adr",
|
|
43735
44632
|
status: "proposed",
|
|
@@ -43755,7 +44652,7 @@ function addIdeaStub(ctx) {
|
|
|
43755
44652
|
...consequences.map((c) => `- ${c}`),
|
|
43756
44653
|
""
|
|
43757
44654
|
].join("\n");
|
|
43758
|
-
ctx.storage.write(
|
|
44655
|
+
ctx.storage.write(path65, meta3, body);
|
|
43759
44656
|
return `ADR ${id} created: "${title}". Status: proposed. Promote to accepted via /update ADR or manual edit.`;
|
|
43760
44657
|
});
|
|
43761
44658
|
}
|
|
@@ -43837,14 +44734,14 @@ function createDocumentStub(ctx) {
|
|
|
43837
44734
|
ctx.storage.write(risksPath, riskMeta, content);
|
|
43838
44735
|
return `Document "${title}" created at risks.md (workspace root).`;
|
|
43839
44736
|
}
|
|
43840
|
-
const
|
|
44737
|
+
const path65 = workspaceArtifact(ctx.rootDir, "docs", slug);
|
|
43841
44738
|
const meta3 = {
|
|
43842
44739
|
kind: "doc",
|
|
43843
44740
|
id: slug,
|
|
43844
44741
|
date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
|
|
43845
44742
|
tags
|
|
43846
44743
|
};
|
|
43847
|
-
ctx.storage.write(
|
|
44744
|
+
ctx.storage.write(path65, meta3, content);
|
|
43848
44745
|
return `Document "${title}" created at docs/${slug}.md.`;
|
|
43849
44746
|
});
|
|
43850
44747
|
}
|
|
@@ -44065,15 +44962,15 @@ __export(updater_exports, {
|
|
|
44065
44962
|
import { createRequire as createRequire2 } from "node:module";
|
|
44066
44963
|
import { spawn as spawn12 } from "node:child_process";
|
|
44067
44964
|
import { existsSync as existsSync32 } from "node:fs";
|
|
44068
|
-
import
|
|
44965
|
+
import path43 from "node:path";
|
|
44069
44966
|
import { fileURLToPath } from "node:url";
|
|
44070
44967
|
function resolveBundledNpmCli(execPath = process.execPath) {
|
|
44071
|
-
const dir =
|
|
44968
|
+
const dir = path43.dirname(execPath);
|
|
44072
44969
|
const candidates = [
|
|
44073
44970
|
// Windows: C:\...\node.exe → C:\...\node_modules\npm\bin\npm-cli.js
|
|
44074
|
-
|
|
44971
|
+
path43.join(dir, "node_modules", "npm", "bin", "npm-cli.js"),
|
|
44075
44972
|
// POSIX: <prefix>/bin/node → <prefix>/lib/node_modules/npm/bin/npm-cli.js
|
|
44076
|
-
|
|
44973
|
+
path43.join(dir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js")
|
|
44077
44974
|
];
|
|
44078
44975
|
for (const candidate of candidates) {
|
|
44079
44976
|
try {
|
|
@@ -44090,7 +44987,7 @@ function looksLikeBrokenShim(exitCode, output) {
|
|
|
44090
44987
|
}
|
|
44091
44988
|
function getCurrentVersion() {
|
|
44092
44989
|
try {
|
|
44093
|
-
const pkgPath =
|
|
44990
|
+
const pkgPath = path43.resolve(__dirname2, "..", "..", "package.json");
|
|
44094
44991
|
const pkg = require2(pkgPath);
|
|
44095
44992
|
return pkg.version;
|
|
44096
44993
|
} catch {
|
|
@@ -44213,7 +45110,7 @@ var init_updater = __esm({
|
|
|
44213
45110
|
"use strict";
|
|
44214
45111
|
init_cmdline();
|
|
44215
45112
|
require2 = createRequire2(import.meta.url);
|
|
44216
|
-
__dirname2 =
|
|
45113
|
+
__dirname2 = path43.dirname(fileURLToPath(import.meta.url));
|
|
44217
45114
|
REGISTRY_URL = "https://registry.npmjs.org/zelari-code/latest";
|
|
44218
45115
|
}
|
|
44219
45116
|
});
|
|
@@ -44401,10 +45298,10 @@ function getUserMcpPath() {
|
|
|
44401
45298
|
function getProjectMcpPath(projectRoot) {
|
|
44402
45299
|
return join26(projectRoot, ".zelari", "mcp.json");
|
|
44403
45300
|
}
|
|
44404
|
-
function readFile3(
|
|
44405
|
-
if (!existsSync33(
|
|
45301
|
+
function readFile3(path65) {
|
|
45302
|
+
if (!existsSync33(path65)) return {};
|
|
44406
45303
|
try {
|
|
44407
|
-
const parsed = JSON.parse(readFileSync28(
|
|
45304
|
+
const parsed = JSON.parse(readFileSync28(path65, "utf8"));
|
|
44408
45305
|
const out = {};
|
|
44409
45306
|
for (const [name, cfg] of Object.entries(parsed.mcpServers ?? {})) {
|
|
44410
45307
|
if (!cfg || typeof cfg.command !== "string" || !cfg.command.trim()) continue;
|
|
@@ -44420,10 +45317,10 @@ function readFile3(path64) {
|
|
|
44420
45317
|
return {};
|
|
44421
45318
|
}
|
|
44422
45319
|
}
|
|
44423
|
-
function writeFile(
|
|
44424
|
-
mkdirSync16(dirname7(
|
|
45320
|
+
function writeFile(path65, servers) {
|
|
45321
|
+
mkdirSync16(dirname7(path65), { recursive: true });
|
|
44425
45322
|
const body = { mcpServers: servers };
|
|
44426
|
-
writeFileSync18(
|
|
45323
|
+
writeFileSync18(path65, `${JSON.stringify(body, null, 2)}
|
|
44427
45324
|
`, "utf8");
|
|
44428
45325
|
}
|
|
44429
45326
|
function listMcpServers(projectRoot) {
|
|
@@ -44456,9 +45353,9 @@ function upsertMcpServer(opts) {
|
|
|
44456
45353
|
if (!opts.config.command?.trim()) {
|
|
44457
45354
|
return { ok: false, error: "command is required" };
|
|
44458
45355
|
}
|
|
44459
|
-
let
|
|
45356
|
+
let path65;
|
|
44460
45357
|
if (opts.scope === "user") {
|
|
44461
|
-
|
|
45358
|
+
path65 = getUserMcpPath();
|
|
44462
45359
|
} else {
|
|
44463
45360
|
const root = opts.projectRoot?.trim();
|
|
44464
45361
|
if (!root) {
|
|
@@ -44467,30 +45364,30 @@ function upsertMcpServer(opts) {
|
|
|
44467
45364
|
error: "projectRoot required for project scope (Open Folder first)"
|
|
44468
45365
|
};
|
|
44469
45366
|
}
|
|
44470
|
-
|
|
45367
|
+
path65 = getProjectMcpPath(root);
|
|
44471
45368
|
}
|
|
44472
|
-
const current = readFile3(
|
|
45369
|
+
const current = readFile3(path65);
|
|
44473
45370
|
current[name] = {
|
|
44474
45371
|
command: opts.config.command.trim(),
|
|
44475
45372
|
args: opts.config.args,
|
|
44476
45373
|
env: opts.config.env,
|
|
44477
45374
|
enabled: opts.config.enabled !== false
|
|
44478
45375
|
};
|
|
44479
|
-
writeFile(
|
|
44480
|
-
return { ok: true, path:
|
|
45376
|
+
writeFile(path65, current);
|
|
45377
|
+
return { ok: true, path: path65 };
|
|
44481
45378
|
}
|
|
44482
45379
|
function removeMcpServer(opts) {
|
|
44483
|
-
const
|
|
44484
|
-
if (!
|
|
45380
|
+
const path65 = opts.scope === "user" ? getUserMcpPath() : opts.projectRoot ? getProjectMcpPath(opts.projectRoot) : null;
|
|
45381
|
+
if (!path65) {
|
|
44485
45382
|
return { ok: false, error: "projectRoot required for project scope" };
|
|
44486
45383
|
}
|
|
44487
|
-
const current = readFile3(
|
|
45384
|
+
const current = readFile3(path65);
|
|
44488
45385
|
if (!(opts.name in current)) {
|
|
44489
|
-
return { ok: false, error: `Server "${opts.name}" not found in ${
|
|
45386
|
+
return { ok: false, error: `Server "${opts.name}" not found in ${path65}` };
|
|
44490
45387
|
}
|
|
44491
45388
|
delete current[opts.name];
|
|
44492
|
-
writeFile(
|
|
44493
|
-
return { ok: true, path:
|
|
45389
|
+
writeFile(path65, current);
|
|
45390
|
+
return { ok: true, path: path65 };
|
|
44494
45391
|
}
|
|
44495
45392
|
var init_mcpConfigIo = __esm({
|
|
44496
45393
|
"src/cli/mcp/mcpConfigIo.ts"() {
|
|
@@ -44887,14 +45784,14 @@ __export(agentsMd_exports, {
|
|
|
44887
45784
|
updateAgentsMd: () => updateAgentsMd
|
|
44888
45785
|
});
|
|
44889
45786
|
import { existsSync as existsSync35, readFileSync as readFileSync30, writeFileSync as writeFileSync19 } from "node:fs";
|
|
44890
|
-
import { createHash as
|
|
45787
|
+
import { createHash as createHash13 } from "node:crypto";
|
|
44891
45788
|
import { join as join28 } from "node:path";
|
|
44892
45789
|
import { readFile as readFile4 } from "node:fs/promises";
|
|
44893
45790
|
async function readPackageJson2(projectRoot) {
|
|
44894
|
-
const
|
|
44895
|
-
if (!existsSync35(
|
|
45791
|
+
const path65 = join28(projectRoot, "package.json");
|
|
45792
|
+
if (!existsSync35(path65)) return null;
|
|
44896
45793
|
try {
|
|
44897
|
-
return JSON.parse(await readFile4(
|
|
45794
|
+
return JSON.parse(await readFile4(path65, "utf8"));
|
|
44898
45795
|
} catch {
|
|
44899
45796
|
return null;
|
|
44900
45797
|
}
|
|
@@ -44976,9 +45873,9 @@ async function genBuild(ctx) {
|
|
|
44976
45873
|
].join("\n");
|
|
44977
45874
|
}
|
|
44978
45875
|
async function genOpenQuestions(ctx) {
|
|
44979
|
-
const
|
|
44980
|
-
if (!existsSync35(
|
|
44981
|
-
const content = readFileSync30(
|
|
45876
|
+
const path65 = join28(ctx.rootDir, "risks.md");
|
|
45877
|
+
if (!existsSync35(path65)) return "_No open questions._";
|
|
45878
|
+
const content = readFileSync30(path65, "utf8");
|
|
44982
45879
|
const lines = content.split("\n");
|
|
44983
45880
|
const questions = [];
|
|
44984
45881
|
let currentTitle = "";
|
|
@@ -45102,7 +45999,7 @@ async function updateAgentsMd(ctx, projectRoot) {
|
|
|
45102
45999
|
return { changed: true, sections: changedSections };
|
|
45103
46000
|
}
|
|
45104
46001
|
function hash2(s) {
|
|
45105
|
-
return
|
|
46002
|
+
return createHash13("sha256").update(s).digest("hex").slice(0, 16);
|
|
45106
46003
|
}
|
|
45107
46004
|
var AUTO_SECTIONS, MARKER_OPEN, MARKER_CLOSE, GENERATORS;
|
|
45108
46005
|
var init_agentsMd = __esm({
|
|
@@ -45252,9 +46149,9 @@ function versionKey(value) {
|
|
|
45252
46149
|
function firstString2(v) {
|
|
45253
46150
|
return typeof v === "string" && v.trim().length > 0 ? v : null;
|
|
45254
46151
|
}
|
|
45255
|
-
function readFileSyncSafe(
|
|
46152
|
+
function readFileSyncSafe(path65) {
|
|
45256
46153
|
try {
|
|
45257
|
-
return readFileSync31(
|
|
46154
|
+
return readFileSync31(path65, "utf8");
|
|
45258
46155
|
} catch {
|
|
45259
46156
|
return null;
|
|
45260
46157
|
}
|
|
@@ -45717,8 +46614,8 @@ async function runPostCouncilHook(ctx, options) {
|
|
|
45717
46614
|
sources: scope.sources
|
|
45718
46615
|
} : void 0
|
|
45719
46616
|
});
|
|
45720
|
-
const
|
|
45721
|
-
completionHook = { ran: true, path:
|
|
46617
|
+
const path65 = writeCouncilCompletion(ctx.rootDir, completion);
|
|
46618
|
+
completionHook = { ran: true, path: path65, completion };
|
|
45722
46619
|
} catch (err) {
|
|
45723
46620
|
completionHook = {
|
|
45724
46621
|
ran: true,
|
|
@@ -45763,7 +46660,7 @@ import {
|
|
|
45763
46660
|
writeFileSync as writeFileSync21,
|
|
45764
46661
|
mkdirSync as mkdirSync17
|
|
45765
46662
|
} from "node:fs";
|
|
45766
|
-
import
|
|
46663
|
+
import path44 from "node:path";
|
|
45767
46664
|
import os10 from "node:os";
|
|
45768
46665
|
var FeedbackStore;
|
|
45769
46666
|
var init_councilFeedback = __esm({
|
|
@@ -45774,7 +46671,7 @@ var init_councilFeedback = __esm({
|
|
|
45774
46671
|
now;
|
|
45775
46672
|
entries = [];
|
|
45776
46673
|
constructor(options = {}) {
|
|
45777
|
-
this.file = options.file ?? (process.env.ANATHEMA_COUNCIL_FEEDBACK_FILE ??
|
|
46674
|
+
this.file = options.file ?? (process.env.ANATHEMA_COUNCIL_FEEDBACK_FILE ?? path44.join(os10.homedir(), ".tmp", "zelari-code", "council-feedback.json"));
|
|
45778
46675
|
this.now = options.now ?? Date.now;
|
|
45779
46676
|
this.load();
|
|
45780
46677
|
}
|
|
@@ -45880,7 +46777,7 @@ var init_councilFeedback = __esm({
|
|
|
45880
46777
|
}
|
|
45881
46778
|
}
|
|
45882
46779
|
save() {
|
|
45883
|
-
mkdirSync17(
|
|
46780
|
+
mkdirSync17(path44.dirname(this.file), { recursive: true });
|
|
45884
46781
|
writeFileSync21(
|
|
45885
46782
|
this.file,
|
|
45886
46783
|
JSON.stringify({ entries: this.entries }, null, 2),
|
|
@@ -45948,7 +46845,7 @@ import { execFile as execFile3 } from "node:child_process";
|
|
|
45948
46845
|
import { promisify as promisify2 } from "node:util";
|
|
45949
46846
|
import { mkdtempSync, rmSync as rmSync2 } from "node:fs";
|
|
45950
46847
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
45951
|
-
import
|
|
46848
|
+
import path45 from "node:path";
|
|
45952
46849
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
45953
46850
|
async function git3(cwd, args, env) {
|
|
45954
46851
|
const { stdout } = await execFileAsync2("git", ["-C", cwd, ...args], {
|
|
@@ -45968,8 +46865,8 @@ async function isGitRepo(cwd) {
|
|
|
45968
46865
|
return await gitSafe(cwd, ["rev-parse", "--is-inside-work-tree"]) === "true";
|
|
45969
46866
|
}
|
|
45970
46867
|
async function withTempIndex(fn) {
|
|
45971
|
-
const dir = mkdtempSync(
|
|
45972
|
-
const indexFile =
|
|
46868
|
+
const dir = mkdtempSync(path45.join(tmpdir2(), "zelari-ckpt-"));
|
|
46869
|
+
const indexFile = path45.join(dir, "index");
|
|
45973
46870
|
try {
|
|
45974
46871
|
return await fn(indexFile);
|
|
45975
46872
|
} finally {
|
|
@@ -46060,7 +46957,7 @@ async function restoreCheckpoint(cwd, id) {
|
|
|
46060
46957
|
const deleted = [];
|
|
46061
46958
|
for (const rel2 of added) {
|
|
46062
46959
|
try {
|
|
46063
|
-
rmSync2(
|
|
46960
|
+
rmSync2(path45.join(cwd, rel2), { force: true });
|
|
46064
46961
|
deleted.push(rel2);
|
|
46065
46962
|
} catch {
|
|
46066
46963
|
}
|
|
@@ -46161,7 +47058,7 @@ __export(fileBackend_exports, {
|
|
|
46161
47058
|
});
|
|
46162
47059
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
46163
47060
|
import { promises as fs23 } from "node:fs";
|
|
46164
|
-
import * as
|
|
47061
|
+
import * as path46 from "node:path";
|
|
46165
47062
|
function tokenize(text) {
|
|
46166
47063
|
return text.toLowerCase().split(/[^\p{L}\p{N}]+/u).filter((t) => t.length >= 3);
|
|
46167
47064
|
}
|
|
@@ -46205,8 +47102,8 @@ var init_fileBackend = __esm({
|
|
|
46205
47102
|
logPath = "";
|
|
46206
47103
|
memoryDir = "";
|
|
46207
47104
|
async init(projectRoot) {
|
|
46208
|
-
this.memoryDir =
|
|
46209
|
-
this.logPath =
|
|
47105
|
+
this.memoryDir = path46.join(projectRoot, ".zelari", "memory");
|
|
47106
|
+
this.logPath = path46.join(this.memoryDir, "log.jsonl");
|
|
46210
47107
|
await fs23.mkdir(this.memoryDir, { recursive: true });
|
|
46211
47108
|
}
|
|
46212
47109
|
async add(content, metadata = {}, graph) {
|
|
@@ -46279,12 +47176,12 @@ var init_fileBackend = __esm({
|
|
|
46279
47176
|
|
|
46280
47177
|
// src/cli/traceStore.ts
|
|
46281
47178
|
import { promises as fs24 } from "node:fs";
|
|
46282
|
-
import * as
|
|
47179
|
+
import * as path47 from "node:path";
|
|
46283
47180
|
function traceDir(projectRoot) {
|
|
46284
|
-
return
|
|
47181
|
+
return path47.join(projectRoot, ".zelari", "trace");
|
|
46285
47182
|
}
|
|
46286
47183
|
function tracePath(projectRoot, missionId) {
|
|
46287
|
-
return
|
|
47184
|
+
return path47.join(traceDir(projectRoot), `${missionId}.json`);
|
|
46288
47185
|
}
|
|
46289
47186
|
async function saveTrace(projectRoot, missionId, entries) {
|
|
46290
47187
|
const dir = traceDir(projectRoot);
|
|
@@ -46319,7 +47216,7 @@ __export(zelariMission_exports, {
|
|
|
46319
47216
|
});
|
|
46320
47217
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
46321
47218
|
import { promises as fs25 } from "node:fs";
|
|
46322
|
-
import * as
|
|
47219
|
+
import * as path48 from "node:path";
|
|
46323
47220
|
function resolveMaxIterations(env = process.env) {
|
|
46324
47221
|
const raw = env.ZELARI_MISSION_MAX_ITER;
|
|
46325
47222
|
const n = raw ? Number.parseInt(raw, 10) : DEFAULT_MAX_ITER;
|
|
@@ -46347,10 +47244,10 @@ function isMissionAutoStart(env = process.env) {
|
|
|
46347
47244
|
return env.ZELARI_MISSION_AUTO === "1";
|
|
46348
47245
|
}
|
|
46349
47246
|
async function writeMissionState(projectRoot, state3) {
|
|
46350
|
-
const dir =
|
|
47247
|
+
const dir = path48.join(projectRoot, ".zelari");
|
|
46351
47248
|
await fs25.mkdir(dir, { recursive: true });
|
|
46352
47249
|
await fs25.writeFile(
|
|
46353
|
-
|
|
47250
|
+
path48.join(dir, "mission-state.json"),
|
|
46354
47251
|
JSON.stringify(state3, null, 2) + "\n",
|
|
46355
47252
|
"utf8"
|
|
46356
47253
|
);
|
|
@@ -46972,7 +47869,7 @@ function safeSocketPath(socketPath) {
|
|
|
46972
47869
|
return socketPath.trim();
|
|
46973
47870
|
}
|
|
46974
47871
|
function startPermissionBroker(socketPath, handlers, opts) {
|
|
46975
|
-
const
|
|
47872
|
+
const path65 = safeSocketPath(socketPath);
|
|
46976
47873
|
const requestTimeoutMs = opts?.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
|
|
46977
47874
|
const sockets = /* @__PURE__ */ new Set();
|
|
46978
47875
|
const server = createServer2((socket) => {
|
|
@@ -47072,10 +47969,10 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
47072
47969
|
return new Promise((resolve3, reject) => {
|
|
47073
47970
|
const onError = (err) => reject(err);
|
|
47074
47971
|
server.once("error", onError);
|
|
47075
|
-
server.listen(
|
|
47972
|
+
server.listen(path65, () => {
|
|
47076
47973
|
server.removeListener("error", onError);
|
|
47077
47974
|
resolve3({
|
|
47078
|
-
socketPath:
|
|
47975
|
+
socketPath: path65,
|
|
47079
47976
|
stop: () => new Promise((res) => {
|
|
47080
47977
|
for (const s of sockets) s.destroy();
|
|
47081
47978
|
sockets.clear();
|
|
@@ -47086,7 +47983,7 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
47086
47983
|
if (done) return;
|
|
47087
47984
|
done = true;
|
|
47088
47985
|
if (process.platform !== "win32") {
|
|
47089
|
-
unlink(
|
|
47986
|
+
unlink(path65, () => res());
|
|
47090
47987
|
} else {
|
|
47091
47988
|
res();
|
|
47092
47989
|
}
|
|
@@ -47099,11 +47996,11 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
47099
47996
|
});
|
|
47100
47997
|
}
|
|
47101
47998
|
function requestBrokerAsk(socketPath, ask, opts) {
|
|
47102
|
-
const
|
|
47999
|
+
const path65 = safeSocketPath(socketPath);
|
|
47103
48000
|
const requestTimeoutMs = opts?.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
|
|
47104
48001
|
const connectTimeoutMs = opts?.connectTimeoutMs ?? PERMISSION_BROKER_DEFAULT_CONNECT_TIMEOUT_MS;
|
|
47105
48002
|
return new Promise((resolve3, reject) => {
|
|
47106
|
-
const socket = connect(
|
|
48003
|
+
const socket = connect(path65);
|
|
47107
48004
|
let buffer = "";
|
|
47108
48005
|
let settled = false;
|
|
47109
48006
|
const settle = (fn) => {
|
|
@@ -47118,7 +48015,7 @@ function requestBrokerAsk(socketPath, ask, opts) {
|
|
|
47118
48015
|
settle(
|
|
47119
48016
|
() => reject(
|
|
47120
48017
|
new Error(
|
|
47121
|
-
`permission broker unavailable at "${
|
|
48018
|
+
`permission broker unavailable at "${path65}" (connect timed out after ${connectTimeoutMs}ms)`
|
|
47122
48019
|
)
|
|
47123
48020
|
)
|
|
47124
48021
|
);
|
|
@@ -47851,9 +48748,9 @@ __export(graphMemory_exports, {
|
|
|
47851
48748
|
toGraphSnapshot: () => toGraphSnapshot
|
|
47852
48749
|
});
|
|
47853
48750
|
import { promises as fs26 } from "node:fs";
|
|
47854
|
-
import
|
|
48751
|
+
import path50 from "node:path";
|
|
47855
48752
|
function snapshotPath(cwd) {
|
|
47856
|
-
return
|
|
48753
|
+
return path50.join(cwd, SNAPSHOT_DIR, SNAPSHOT_FILE);
|
|
47857
48754
|
}
|
|
47858
48755
|
function toGraphSnapshot(graph, opts) {
|
|
47859
48756
|
const unresolved = (opts.unresolvedFindings ?? []).map((u) => ({
|
|
@@ -47880,7 +48777,7 @@ async function saveGraphSnapshot(cwd, snapshot) {
|
|
|
47880
48777
|
try {
|
|
47881
48778
|
await fs26.access(cwd);
|
|
47882
48779
|
const file2 = snapshotPath(cwd);
|
|
47883
|
-
await fs26.mkdir(
|
|
48780
|
+
await fs26.mkdir(path50.dirname(file2), { recursive: true });
|
|
47884
48781
|
await fs26.writeFile(file2, JSON.stringify(snapshot, null, 2) + "\n", "utf8");
|
|
47885
48782
|
} catch {
|
|
47886
48783
|
}
|
|
@@ -47947,7 +48844,7 @@ var SNAPSHOT_DIR, SNAPSHOT_FILE, MAX_SNAPSHOT_FINDINGS_CHARS;
|
|
|
47947
48844
|
var init_graphMemory = __esm({
|
|
47948
48845
|
"src/cli/kraken/graphMemory.ts"() {
|
|
47949
48846
|
"use strict";
|
|
47950
|
-
SNAPSHOT_DIR =
|
|
48847
|
+
SNAPSHOT_DIR = path50.join(".zelari", "kraken");
|
|
47951
48848
|
SNAPSHOT_FILE = "last-graph.json";
|
|
47952
48849
|
MAX_SNAPSHOT_FINDINGS_CHARS = 400;
|
|
47953
48850
|
}
|
|
@@ -47963,14 +48860,14 @@ var init_tentacle = __esm({
|
|
|
47963
48860
|
|
|
47964
48861
|
// src/cli/kraken/workbench.ts
|
|
47965
48862
|
import { promises as fs27 } from "node:fs";
|
|
47966
|
-
import
|
|
48863
|
+
import path51 from "node:path";
|
|
47967
48864
|
function isWorkbenchEnabled(env = process.env) {
|
|
47968
48865
|
const v = (env.ZELARI_KRAKEN_WORKBENCH ?? "1").trim().toLowerCase();
|
|
47969
48866
|
if (v === "0" || v === "false" || v === "no" || v === "off") return false;
|
|
47970
48867
|
return true;
|
|
47971
48868
|
}
|
|
47972
48869
|
function workbenchPath(cwd, graphId) {
|
|
47973
|
-
return
|
|
48870
|
+
return path51.join(cwd, ".zelari", "radio", `workbench-${graphId}.md`);
|
|
47974
48871
|
}
|
|
47975
48872
|
function countByStatus2(nodes) {
|
|
47976
48873
|
const out = { pending: 0, running: 0, done: 0, error: 0, skipped: 0 };
|
|
@@ -48133,7 +49030,7 @@ var init_workbench = __esm({
|
|
|
48133
49030
|
if (!this.enabled) return null;
|
|
48134
49031
|
if (!this.dirty && this.lastWrite) return this.lastWrite;
|
|
48135
49032
|
const out = workbenchPath(this.cwd, this.graphId);
|
|
48136
|
-
await fs27.mkdir(
|
|
49033
|
+
await fs27.mkdir(path51.dirname(out), { recursive: true });
|
|
48137
49034
|
const body = this.render();
|
|
48138
49035
|
const tmp = `${out}.${process.pid}.${Date.now()}.tmp`;
|
|
48139
49036
|
await fs27.writeFile(tmp, body, "utf8");
|
|
@@ -48330,7 +49227,7 @@ __export(executor_exports, {
|
|
|
48330
49227
|
thoroughnessForKind: () => thoroughnessForKind
|
|
48331
49228
|
});
|
|
48332
49229
|
import { existsSync as existsSync40 } from "node:fs";
|
|
48333
|
-
import
|
|
49230
|
+
import path52 from "node:path";
|
|
48334
49231
|
function resolveMaxParallel(env = process.env) {
|
|
48335
49232
|
const raw = env.ZELARI_KRAKEN_MAX_PARALLEL;
|
|
48336
49233
|
if (raw === void 0 || raw === "") return DEFAULT_MAX_PARALLEL;
|
|
@@ -48388,7 +49285,7 @@ function isWorldModelGateEnabled(cwd, env = process.env, checksExists = defaultC
|
|
|
48388
49285
|
}
|
|
48389
49286
|
function defaultChecksExists(cwd) {
|
|
48390
49287
|
try {
|
|
48391
|
-
return existsSync40(
|
|
49288
|
+
return existsSync40(path52.join(cwd, ".zelari", "world", "checks.json"));
|
|
48392
49289
|
} catch {
|
|
48393
49290
|
return false;
|
|
48394
49291
|
}
|
|
@@ -49184,8 +50081,8 @@ ${upstream}` : node.prompt,
|
|
|
49184
50081
|
* nodes that already exist, and the rewiring moves an existing edge forward
|
|
49185
50082
|
* along the chain rather than back into it.
|
|
49186
50083
|
*/
|
|
49187
|
-
spawnReworkPair(graph, writer, verify, findings, root,
|
|
49188
|
-
const reworkId = `rework-${root}-${
|
|
50084
|
+
spawnReworkPair(graph, writer, verify, findings, root, round2) {
|
|
50085
|
+
const reworkId = `rework-${root}-${round2}`;
|
|
49189
50086
|
const reworkNode = {
|
|
49190
50087
|
id: reworkId,
|
|
49191
50088
|
kind: "fix",
|
|
@@ -49212,7 +50109,7 @@ ${findings || "(the reviewer reported FAIL without detail)"}`,
|
|
|
49212
50109
|
const reVerifyNode = {
|
|
49213
50110
|
id: reVerifyId,
|
|
49214
50111
|
kind: "verify",
|
|
49215
|
-
label: `verify: ${writer.label} (rework ${
|
|
50112
|
+
label: `verify: ${writer.label} (rework ${round2})`,
|
|
49216
50113
|
prompt: verify.prompt,
|
|
49217
50114
|
deps: [reworkId],
|
|
49218
50115
|
status: "pending",
|
|
@@ -49230,7 +50127,7 @@ ${findings || "(the reviewer reported FAIL without detail)"}`,
|
|
|
49230
50127
|
this.radio("node_fix", {
|
|
49231
50128
|
description: reworkNode.label,
|
|
49232
50129
|
agent: "fix",
|
|
49233
|
-
detail: `verify FAIL on "${writer.label}" \u2014 rework round ${
|
|
50130
|
+
detail: `verify FAIL on "${writer.label}" \u2014 rework round ${round2}/${this.maxReviewRounds}`,
|
|
49234
50131
|
ok: false
|
|
49235
50132
|
});
|
|
49236
50133
|
}
|
|
@@ -49727,10 +50624,10 @@ var init_prereqChecks = __esm({
|
|
|
49727
50624
|
|
|
49728
50625
|
// src/cli/plugins/prefs.ts
|
|
49729
50626
|
import { existsSync as existsSync42, readFileSync as readFileSync35, writeFileSync as writeFileSync22, mkdirSync as mkdirSync18 } from "node:fs";
|
|
49730
|
-
import
|
|
50627
|
+
import path55 from "node:path";
|
|
49731
50628
|
import os11 from "node:os";
|
|
49732
50629
|
function getPluginPrefsPath() {
|
|
49733
|
-
return process.env.ZELARI_PLUGINS_PREFS_FILE ??
|
|
50630
|
+
return process.env.ZELARI_PLUGINS_PREFS_FILE ?? path55.join(os11.homedir(), ".tmp", "zelari-code", "plugins.json");
|
|
49734
50631
|
}
|
|
49735
50632
|
function getPluginPrefs() {
|
|
49736
50633
|
const file2 = getPluginPrefsPath();
|
|
@@ -49751,7 +50648,7 @@ function getPluginPrefs() {
|
|
|
49751
50648
|
}
|
|
49752
50649
|
function writePluginPrefs(prefs) {
|
|
49753
50650
|
const file2 = getPluginPrefsPath();
|
|
49754
|
-
mkdirSync18(
|
|
50651
|
+
mkdirSync18(path55.dirname(file2), { recursive: true });
|
|
49755
50652
|
writeFileSync22(file2, JSON.stringify(prefs, null, 2), {
|
|
49756
50653
|
encoding: "utf-8",
|
|
49757
50654
|
mode: 384
|
|
@@ -49788,7 +50685,7 @@ __export(registry_exports, {
|
|
|
49788
50685
|
isBinaryOnPath: () => isBinaryOnPath
|
|
49789
50686
|
});
|
|
49790
50687
|
import { existsSync as existsSync43 } from "node:fs";
|
|
49791
|
-
import
|
|
50688
|
+
import path56 from "node:path";
|
|
49792
50689
|
function detectLocalBin(bin) {
|
|
49793
50690
|
return (cwd) => {
|
|
49794
50691
|
try {
|
|
@@ -49806,7 +50703,7 @@ function isBinaryOnPath(bin, opts = {}) {
|
|
|
49806
50703
|
const platform = opts.platform ?? process.platform;
|
|
49807
50704
|
const exists = opts.exists ?? existsSync43;
|
|
49808
50705
|
const pathEnv = opts.pathEnv ?? process.env.PATH ?? "";
|
|
49809
|
-
const pathMod = platform === "win32" ?
|
|
50706
|
+
const pathMod = platform === "win32" ? path56.win32 : path56.posix;
|
|
49810
50707
|
const sep2 = platform === "win32" ? ";" : ":";
|
|
49811
50708
|
const dirs = pathEnv.split(sep2).filter((d) => d.length > 0);
|
|
49812
50709
|
const candidates = [bin];
|
|
@@ -50753,6 +51650,7 @@ __export(policy_exports, {
|
|
|
50753
51650
|
DEFAULT_MAX_ROUNDS: () => DEFAULT_MAX_ROUNDS,
|
|
50754
51651
|
DEFAULT_WALL_MS: () => DEFAULT_WALL_MS,
|
|
50755
51652
|
GAUNTLET_PARENT_BLOCKED_TOOLS: () => GAUNTLET_PARENT_BLOCKED_TOOLS,
|
|
51653
|
+
budgetAwareGauntletGate: () => budgetAwareGauntletGate,
|
|
50756
51654
|
isGauntletFlagOn: () => isGauntletFlagOn,
|
|
50757
51655
|
resolveGauntletCaps: () => resolveGauntletCaps,
|
|
50758
51656
|
shouldRunGauntletHostLoop: () => shouldRunGauntletHostLoop
|
|
@@ -50791,6 +51689,12 @@ function shouldRunGauntletHostLoop(opts) {
|
|
|
50791
51689
|
const phase2 = opts.phase ?? "build";
|
|
50792
51690
|
return phase2 !== "plan";
|
|
50793
51691
|
}
|
|
51692
|
+
function budgetAwareGauntletGate(input) {
|
|
51693
|
+
if (input.verdict === "PASS") return "proceed";
|
|
51694
|
+
if (input.toolCallsRemaining <= input.verificationReserve) return "finalize-verify";
|
|
51695
|
+
if (input.toolCallsRemaining <= 0) return "hold";
|
|
51696
|
+
return "proceed";
|
|
51697
|
+
}
|
|
50794
51698
|
var DEFAULT_MAX_PIECES, DEFAULT_MAX_ROUNDS, DEFAULT_MAX_PARALLEL2, DEFAULT_WALL_MS, GAUNTLET_PARENT_BLOCKED_TOOLS;
|
|
50795
51699
|
var init_policy = __esm({
|
|
50796
51700
|
"src/cli/gauntlet/policy.ts"() {
|
|
@@ -51169,9 +52073,9 @@ function builderUserPrompt(piece, gap, briefing) {
|
|
|
51169
52073
|
parts.push("", "Return: files touched, what changed, residual risks.");
|
|
51170
52074
|
return parts.join("\n");
|
|
51171
52075
|
}
|
|
51172
|
-
function criticUserPrompt(piece,
|
|
52076
|
+
function criticUserPrompt(piece, round2, rand) {
|
|
51173
52077
|
const parts = [
|
|
51174
|
-
`Round ${
|
|
52078
|
+
`Round ${round2}. Inspect the current tree against this piece.`,
|
|
51175
52079
|
"Do not edit files. Do not take the builder's word \u2014 open files / run checks.",
|
|
51176
52080
|
"",
|
|
51177
52081
|
`## Piece: ${piece.label}`,
|
|
@@ -51285,9 +52189,9 @@ async function runGauntletLoop(args) {
|
|
|
51285
52189
|
let winner;
|
|
51286
52190
|
let rounds = 0;
|
|
51287
52191
|
const i = Math.max(0, indexOf(piece));
|
|
51288
|
-
for (let
|
|
52192
|
+
for (let round2 = 1; round2 <= caps.maxRounds; round2++) {
|
|
51289
52193
|
if (stop()) break;
|
|
51290
|
-
rounds =
|
|
52194
|
+
rounds = round2;
|
|
51291
52195
|
const phase2 = gap ? "repairing" : "building";
|
|
51292
52196
|
emitProgress({
|
|
51293
52197
|
phase: phase2,
|
|
@@ -51295,13 +52199,13 @@ async function runGauntletLoop(args) {
|
|
|
51295
52199
|
pieceLabel: piece.label,
|
|
51296
52200
|
pieceIndex: i,
|
|
51297
52201
|
pieceCount: pieces.length,
|
|
51298
|
-
round,
|
|
52202
|
+
round: round2,
|
|
51299
52203
|
maxRounds: caps.maxRounds
|
|
51300
52204
|
});
|
|
51301
52205
|
const built = await deps.runBuilder({
|
|
51302
52206
|
piece,
|
|
51303
52207
|
prompt: builderUserPrompt(piece, gap, deps.briefing),
|
|
51304
|
-
round
|
|
52208
|
+
round: round2
|
|
51305
52209
|
});
|
|
51306
52210
|
if (stop()) break;
|
|
51307
52211
|
emitProgress({
|
|
@@ -51310,14 +52214,14 @@ async function runGauntletLoop(args) {
|
|
|
51310
52214
|
pieceLabel: piece.label,
|
|
51311
52215
|
pieceIndex: i,
|
|
51312
52216
|
pieceCount: pieces.length,
|
|
51313
|
-
round,
|
|
52217
|
+
round: round2,
|
|
51314
52218
|
maxRounds: caps.maxRounds
|
|
51315
52219
|
});
|
|
51316
52220
|
const criticized = await deps.runCritic({
|
|
51317
52221
|
piece,
|
|
51318
|
-
prompt: criticUserPrompt(piece,
|
|
52222
|
+
prompt: criticUserPrompt(piece, round2),
|
|
51319
52223
|
systemPrompt: GAUNTLET_CRITIC_SYSTEM,
|
|
51320
|
-
round
|
|
52224
|
+
round: round2
|
|
51321
52225
|
});
|
|
51322
52226
|
last = parseGauntletVerdict(criticized.result, {
|
|
51323
52227
|
toolTraceCount: criticized.toolTraceCount ?? 0,
|
|
@@ -51331,7 +52235,7 @@ async function runGauntletLoop(args) {
|
|
|
51331
52235
|
pieceLabel: piece.label,
|
|
51332
52236
|
pieceIndex: i,
|
|
51333
52237
|
pieceCount: pieces.length,
|
|
51334
|
-
round,
|
|
52238
|
+
round: round2,
|
|
51335
52239
|
maxRounds: caps.maxRounds,
|
|
51336
52240
|
verdict: last.kind,
|
|
51337
52241
|
gap: last.gap,
|
|
@@ -51500,10 +52404,10 @@ async function runHeadlessGauntlet(opts, provider, model) {
|
|
|
51500
52404
|
emit,
|
|
51501
52405
|
briefing: workspace.slice(0, 1200),
|
|
51502
52406
|
note: (text, data) => spine.note(text, data),
|
|
51503
|
-
runBuilder: async ({ piece, prompt, round }) => {
|
|
52407
|
+
runBuilder: async ({ piece, prompt, round: round2 }) => {
|
|
51504
52408
|
emit({
|
|
51505
52409
|
type: "log",
|
|
51506
|
-
message: `[gauntlet] ${piece.id} round ${
|
|
52410
|
+
message: `[gauntlet] ${piece.id} round ${round2}/${caps.maxRounds} builder`
|
|
51507
52411
|
});
|
|
51508
52412
|
const tent = await runTentacle({
|
|
51509
52413
|
deps,
|
|
@@ -51513,7 +52417,7 @@ async function runHeadlessGauntlet(opts, provider, model) {
|
|
|
51513
52417
|
sessionId: sessionId2,
|
|
51514
52418
|
signal: abort.signal,
|
|
51515
52419
|
args: {
|
|
51516
|
-
description: `gauntlet-builder ${piece.id} r${
|
|
52420
|
+
description: `gauntlet-builder ${piece.id} r${round2}`,
|
|
51517
52421
|
prompt,
|
|
51518
52422
|
...piece.scope ? { scope: piece.scope } : {},
|
|
51519
52423
|
...piece.acceptance.length > 0 ? { acceptance: piece.acceptance } : {}
|
|
@@ -51526,10 +52430,10 @@ async function runHeadlessGauntlet(opts, provider, model) {
|
|
|
51526
52430
|
toolTraceCount: tent.toolTrace?.length ?? 0
|
|
51527
52431
|
};
|
|
51528
52432
|
},
|
|
51529
|
-
runCritic: async ({ piece, prompt, systemPrompt, round }) => {
|
|
52433
|
+
runCritic: async ({ piece, prompt, systemPrompt, round: round2 }) => {
|
|
51530
52434
|
emit({
|
|
51531
52435
|
type: "log",
|
|
51532
|
-
message: `[gauntlet] ${piece.id} round ${
|
|
52436
|
+
message: `[gauntlet] ${piece.id} round ${round2}/${caps.maxRounds} critic`
|
|
51533
52437
|
});
|
|
51534
52438
|
const tent = await runTentacle({
|
|
51535
52439
|
deps,
|
|
@@ -51540,7 +52444,7 @@ async function runHeadlessGauntlet(opts, provider, model) {
|
|
|
51540
52444
|
signal: abort.signal,
|
|
51541
52445
|
systemPromptOverride: systemPrompt,
|
|
51542
52446
|
args: {
|
|
51543
|
-
description: `gauntlet-critic ${piece.id} r${
|
|
52447
|
+
description: `gauntlet-critic ${piece.id} r${round2}`,
|
|
51544
52448
|
prompt,
|
|
51545
52449
|
...piece.scope ? { scope: piece.scope } : {},
|
|
51546
52450
|
...piece.acceptance.length > 0 ? { acceptance: piece.acceptance } : {}
|
|
@@ -51611,9 +52515,9 @@ __export(triggerLock_exports, {
|
|
|
51611
52515
|
releaseLock: () => releaseLock
|
|
51612
52516
|
});
|
|
51613
52517
|
import { promises as fs35 } from "node:fs";
|
|
51614
|
-
import * as
|
|
52518
|
+
import * as path61 from "node:path";
|
|
51615
52519
|
function lockPath(projectRoot) {
|
|
51616
|
-
return
|
|
52520
|
+
return path61.join(projectRoot, ".zelari", "trigger.lock");
|
|
51617
52521
|
}
|
|
51618
52522
|
function isPidAlive(pid) {
|
|
51619
52523
|
try {
|
|
@@ -51626,7 +52530,7 @@ function isPidAlive(pid) {
|
|
|
51626
52530
|
}
|
|
51627
52531
|
async function acquireLock(projectRoot, now = () => /* @__PURE__ */ new Date()) {
|
|
51628
52532
|
const lp = lockPath(projectRoot);
|
|
51629
|
-
const dir =
|
|
52533
|
+
const dir = path61.dirname(lp);
|
|
51630
52534
|
await fs35.mkdir(dir, { recursive: true });
|
|
51631
52535
|
try {
|
|
51632
52536
|
const raw = await fs35.readFile(lp, "utf8");
|
|
@@ -52220,7 +53124,7 @@ function upsertSkill(opts) {
|
|
|
52220
53124
|
}
|
|
52221
53125
|
dir = getProjectSkillsDir(root);
|
|
52222
53126
|
}
|
|
52223
|
-
const
|
|
53127
|
+
const path65 = skillFilePath(dir, name);
|
|
52224
53128
|
const content = serializeSkillMd({
|
|
52225
53129
|
name,
|
|
52226
53130
|
description,
|
|
@@ -52229,13 +53133,13 @@ function upsertSkill(opts) {
|
|
|
52229
53133
|
tools: opts.tools,
|
|
52230
53134
|
cost: opts.cost
|
|
52231
53135
|
});
|
|
52232
|
-
const parsed = parseSkillMd(content,
|
|
53136
|
+
const parsed = parseSkillMd(content, path65);
|
|
52233
53137
|
if (!parsed) {
|
|
52234
53138
|
return { ok: false, error: "Generated SKILL.md failed validation" };
|
|
52235
53139
|
}
|
|
52236
|
-
mkdirSync21(dirname10(
|
|
52237
|
-
writeFileSync24(
|
|
52238
|
-
return { ok: true, path:
|
|
53140
|
+
mkdirSync21(dirname10(path65), { recursive: true });
|
|
53141
|
+
writeFileSync24(path65, content, "utf8");
|
|
53142
|
+
return { ok: true, path: path65 };
|
|
52239
53143
|
}
|
|
52240
53144
|
function removeSkill(opts) {
|
|
52241
53145
|
const name = opts.name.trim().toLowerCase();
|
|
@@ -52253,8 +53157,8 @@ function removeSkill(opts) {
|
|
|
52253
53157
|
dir = getProjectSkillsDir(root);
|
|
52254
53158
|
}
|
|
52255
53159
|
const skillDir = join37(dir, name);
|
|
52256
|
-
const
|
|
52257
|
-
if (!existsSync48(
|
|
53160
|
+
const path65 = skillFilePath(dir, name);
|
|
53161
|
+
if (!existsSync48(path65) && !existsSync48(skillDir)) {
|
|
52258
53162
|
return { ok: false, error: `Skill "${name}" not found in ${dir}` };
|
|
52259
53163
|
}
|
|
52260
53164
|
try {
|
|
@@ -52265,7 +53169,7 @@ function removeSkill(opts) {
|
|
|
52265
53169
|
error: err instanceof Error ? err.message : String(err)
|
|
52266
53170
|
};
|
|
52267
53171
|
}
|
|
52268
|
-
return { ok: true, path:
|
|
53172
|
+
return { ok: true, path: path65 };
|
|
52269
53173
|
}
|
|
52270
53174
|
var NAME_RE, BUILTIN_SKILL_MODULES, builtinsLoaded;
|
|
52271
53175
|
var init_skillConfigIo = __esm({
|
|
@@ -52566,7 +53470,7 @@ import {
|
|
|
52566
53470
|
} from "node:fs";
|
|
52567
53471
|
import { join as join38 } from "node:path";
|
|
52568
53472
|
import { homedir as homedir13 } from "node:os";
|
|
52569
|
-
import { createHash as
|
|
53473
|
+
import { createHash as createHash14, randomBytes as randomBytes5, timingSafeEqual } from "node:crypto";
|
|
52570
53474
|
function getZelariHome() {
|
|
52571
53475
|
return join38(homedir13(), ".zelari-code");
|
|
52572
53476
|
}
|
|
@@ -52583,12 +53487,12 @@ function ensureHome() {
|
|
|
52583
53487
|
}
|
|
52584
53488
|
}
|
|
52585
53489
|
function loadCompanionConfig() {
|
|
52586
|
-
const
|
|
52587
|
-
if (!existsSync49(
|
|
53490
|
+
const path65 = getCompanionConfigPath();
|
|
53491
|
+
if (!existsSync49(path65)) {
|
|
52588
53492
|
return { projects: [] };
|
|
52589
53493
|
}
|
|
52590
53494
|
try {
|
|
52591
|
-
const raw = JSON.parse(readFileSync39(
|
|
53495
|
+
const raw = JSON.parse(readFileSync39(path65, "utf8"));
|
|
52592
53496
|
const projects = Array.isArray(raw.projects) ? raw.projects.filter(
|
|
52593
53497
|
(p3) => p3 && typeof p3.path === "string" && p3.path.trim() && typeof (p3.id ?? p3.name) === "string"
|
|
52594
53498
|
).map((p3) => ({
|
|
@@ -52626,24 +53530,24 @@ function loadOrCreateToken(explicit) {
|
|
|
52626
53530
|
return { token: explicit.trim(), created: false };
|
|
52627
53531
|
}
|
|
52628
53532
|
ensureHome();
|
|
52629
|
-
const
|
|
52630
|
-
if (existsSync49(
|
|
52631
|
-
const t = readFileSync39(
|
|
53533
|
+
const path65 = getCompanionTokenPath();
|
|
53534
|
+
if (existsSync49(path65)) {
|
|
53535
|
+
const t = readFileSync39(path65, "utf8").trim();
|
|
52632
53536
|
if (t) return { token: t, created: false };
|
|
52633
53537
|
}
|
|
52634
53538
|
const token = randomBytes5(24).toString("base64url");
|
|
52635
|
-
writeFileSync25(
|
|
53539
|
+
writeFileSync25(path65, token + "\n", "utf8");
|
|
52636
53540
|
try {
|
|
52637
53541
|
const fs37 = __require("node:fs");
|
|
52638
|
-
fs37.chmodSync?.(
|
|
53542
|
+
fs37.chmodSync?.(path65, 384);
|
|
52639
53543
|
} catch {
|
|
52640
53544
|
}
|
|
52641
53545
|
return { token, created: true };
|
|
52642
53546
|
}
|
|
52643
53547
|
function tokenMatches(expected, provided) {
|
|
52644
53548
|
if (!provided) return false;
|
|
52645
|
-
const a =
|
|
52646
|
-
const b =
|
|
53549
|
+
const a = createHash14("sha256").update(expected).digest();
|
|
53550
|
+
const b = createHash14("sha256").update(provided).digest();
|
|
52647
53551
|
try {
|
|
52648
53552
|
return timingSafeEqual(a, b);
|
|
52649
53553
|
} catch {
|
|
@@ -52660,17 +53564,17 @@ function mergeProjects(cfg, extraPaths) {
|
|
|
52660
53564
|
byId.set(p3.id, p3);
|
|
52661
53565
|
}
|
|
52662
53566
|
for (const raw of extraPaths) {
|
|
52663
|
-
const
|
|
52664
|
-
if (!
|
|
52665
|
-
let id = slugFromPath(
|
|
53567
|
+
const path65 = raw.trim();
|
|
53568
|
+
if (!path65) continue;
|
|
53569
|
+
let id = slugFromPath(path65);
|
|
52666
53570
|
let n = 2;
|
|
52667
|
-
while (byId.has(id) && byId.get(id).path !==
|
|
52668
|
-
id = `${slugFromPath(
|
|
53571
|
+
while (byId.has(id) && byId.get(id).path !== path65) {
|
|
53572
|
+
id = `${slugFromPath(path65)}-${n++}`;
|
|
52669
53573
|
}
|
|
52670
53574
|
byId.set(id, {
|
|
52671
53575
|
id,
|
|
52672
|
-
name: slugFromPath(
|
|
52673
|
-
path:
|
|
53576
|
+
name: slugFromPath(path65),
|
|
53577
|
+
path: path65
|
|
52674
53578
|
});
|
|
52675
53579
|
}
|
|
52676
53580
|
return [...byId.values()];
|
|
@@ -53047,9 +53951,9 @@ async function runCompanionServe(opts = {}) {
|
|
|
53047
53951
|
return;
|
|
53048
53952
|
}
|
|
53049
53953
|
const url2 = parseUrl(req);
|
|
53050
|
-
const
|
|
53954
|
+
const path65 = url2.pathname.replace(/\/+$/, "") || "/";
|
|
53051
53955
|
try {
|
|
53052
|
-
if (req.method === "GET" && (
|
|
53956
|
+
if (req.method === "GET" && (path65 === "/health" || path65 === "/v1/health")) {
|
|
53053
53957
|
sendJson2(res, 200, {
|
|
53054
53958
|
ok: true,
|
|
53055
53959
|
service: "zelari-companion",
|
|
@@ -53061,18 +53965,18 @@ async function runCompanionServe(opts = {}) {
|
|
|
53061
53965
|
});
|
|
53062
53966
|
return;
|
|
53063
53967
|
}
|
|
53064
|
-
if (
|
|
53968
|
+
if (path65.startsWith("/v1")) {
|
|
53065
53969
|
if (!tokenMatches(token, getBearer(req))) {
|
|
53066
53970
|
sendJson2(res, 401, { ok: false, error: "unauthorized" });
|
|
53067
53971
|
return;
|
|
53068
53972
|
}
|
|
53069
53973
|
}
|
|
53070
|
-
if (req.method === "GET" &&
|
|
53974
|
+
if (req.method === "GET" && path65 === "/v1/config") {
|
|
53071
53975
|
const snap = buildDesktopConfigSnapshot();
|
|
53072
53976
|
sendJson2(res, 200, { ok: true, ...snap });
|
|
53073
53977
|
return;
|
|
53074
53978
|
}
|
|
53075
|
-
if (req.method === "GET" &&
|
|
53979
|
+
if (req.method === "GET" && path65 === "/v1/projects") {
|
|
53076
53980
|
sendJson2(res, 200, {
|
|
53077
53981
|
ok: true,
|
|
53078
53982
|
projects: projects.map((p3) => ({
|
|
@@ -53083,7 +53987,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
53083
53987
|
});
|
|
53084
53988
|
return;
|
|
53085
53989
|
}
|
|
53086
|
-
if (req.method === "GET" &&
|
|
53990
|
+
if (req.method === "GET" && path65 === "/v1/runs") {
|
|
53087
53991
|
sendJson2(res, 200, {
|
|
53088
53992
|
ok: true,
|
|
53089
53993
|
active: runs.getActive(),
|
|
@@ -53101,7 +54005,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
53101
54005
|
});
|
|
53102
54006
|
return;
|
|
53103
54007
|
}
|
|
53104
|
-
if (req.method === "POST" &&
|
|
54008
|
+
if (req.method === "POST" && path65 === "/v1/runs") {
|
|
53105
54009
|
const raw = await readBody(req);
|
|
53106
54010
|
let body = {};
|
|
53107
54011
|
try {
|
|
@@ -53148,7 +54052,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
53148
54052
|
});
|
|
53149
54053
|
return;
|
|
53150
54054
|
}
|
|
53151
|
-
const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(
|
|
54055
|
+
const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(path65);
|
|
53152
54056
|
if (req.method === "GET" && eventsMatch) {
|
|
53153
54057
|
const runId = eventsMatch[1];
|
|
53154
54058
|
const run = runs.getRun(runId);
|
|
@@ -53213,7 +54117,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
53213
54117
|
}, 500);
|
|
53214
54118
|
return;
|
|
53215
54119
|
}
|
|
53216
|
-
const cancelMatch = /^\/v1\/runs\/([^/]+)\/cancel$/.exec(
|
|
54120
|
+
const cancelMatch = /^\/v1\/runs\/([^/]+)\/cancel$/.exec(path65);
|
|
53217
54121
|
if (req.method === "POST" && cancelMatch) {
|
|
53218
54122
|
const runId = cancelMatch[1];
|
|
53219
54123
|
const result = runs.cancel(runId);
|
|
@@ -53366,11 +54270,11 @@ import { execSync as execSync2 } from "node:child_process";
|
|
|
53366
54270
|
import { existsSync as existsSync51, readFileSync as readFileSync40, readlinkSync, statSync as statSync10 } from "node:fs";
|
|
53367
54271
|
import { createRequire as createRequire3 } from "node:module";
|
|
53368
54272
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
53369
|
-
import
|
|
54273
|
+
import path63 from "node:path";
|
|
53370
54274
|
function findPackageRoot(start) {
|
|
53371
54275
|
let dir = start;
|
|
53372
54276
|
for (let i = 0; i < 6; i += 1) {
|
|
53373
|
-
const candidate =
|
|
54277
|
+
const candidate = path63.join(dir, "package.json");
|
|
53374
54278
|
if (existsSync51(candidate)) {
|
|
53375
54279
|
try {
|
|
53376
54280
|
const pkg = JSON.parse(readFileSync40(candidate, "utf8"));
|
|
@@ -53378,11 +54282,11 @@ function findPackageRoot(start) {
|
|
|
53378
54282
|
} catch {
|
|
53379
54283
|
}
|
|
53380
54284
|
}
|
|
53381
|
-
const parent =
|
|
54285
|
+
const parent = path63.dirname(dir);
|
|
53382
54286
|
if (parent === dir) break;
|
|
53383
54287
|
dir = parent;
|
|
53384
54288
|
}
|
|
53385
|
-
return
|
|
54289
|
+
return path63.resolve(__dirname3, "..", "..", "..");
|
|
53386
54290
|
}
|
|
53387
54291
|
function tryExec(cmd) {
|
|
53388
54292
|
try {
|
|
@@ -53396,7 +54300,7 @@ function tryExec(cmd) {
|
|
|
53396
54300
|
}
|
|
53397
54301
|
function readPackageJson3() {
|
|
53398
54302
|
try {
|
|
53399
|
-
const pkgPath =
|
|
54303
|
+
const pkgPath = path63.join(packageRoot, "package.json");
|
|
53400
54304
|
return JSON.parse(readFileSync40(pkgPath, "utf8"));
|
|
53401
54305
|
} catch {
|
|
53402
54306
|
return null;
|
|
@@ -53412,7 +54316,7 @@ function checkShim(pkgName) {
|
|
|
53412
54316
|
}
|
|
53413
54317
|
const isWin = process.platform === "win32";
|
|
53414
54318
|
const shimName = isWin ? "zelari-code.cmd" : "zelari-code";
|
|
53415
|
-
const shimPath =
|
|
54319
|
+
const shimPath = path63.join(prefix, shimName);
|
|
53416
54320
|
if (!existsSync51(shimPath)) {
|
|
53417
54321
|
return FAIL(
|
|
53418
54322
|
`shim not found at ${shimPath}
|
|
@@ -53440,8 +54344,8 @@ function checkShim(pkgName) {
|
|
|
53440
54344
|
fix: npm install -g ${pkgName}@latest --force`
|
|
53441
54345
|
);
|
|
53442
54346
|
}
|
|
53443
|
-
const resolved =
|
|
53444
|
-
const expected =
|
|
54347
|
+
const resolved = path63.resolve(path63.dirname(shimPath), target);
|
|
54348
|
+
const expected = path63.join(
|
|
53445
54349
|
prefix,
|
|
53446
54350
|
"node_modules",
|
|
53447
54351
|
pkgName,
|
|
@@ -53480,7 +54384,7 @@ function checkNode(pkg) {
|
|
|
53480
54384
|
return OK(`node ${raw}`);
|
|
53481
54385
|
}
|
|
53482
54386
|
function checkBundle() {
|
|
53483
|
-
const bundle =
|
|
54387
|
+
const bundle = path63.join(packageRoot, "dist", "cli", "main.bundled.js");
|
|
53484
54388
|
if (!existsSync51(bundle)) {
|
|
53485
54389
|
return FAIL(
|
|
53486
54390
|
`dist/cli/main.bundled.js missing at ${bundle}
|
|
@@ -53501,7 +54405,7 @@ function checkRuntimeDeps() {
|
|
|
53501
54405
|
const missing = [];
|
|
53502
54406
|
for (const dep of required2) {
|
|
53503
54407
|
try {
|
|
53504
|
-
const localReq = createRequire3(
|
|
54408
|
+
const localReq = createRequire3(path63.join(packageRoot, "package.json"));
|
|
53505
54409
|
localReq.resolve(dep);
|
|
53506
54410
|
} catch {
|
|
53507
54411
|
missing.push(dep);
|
|
@@ -53701,7 +54605,7 @@ var init_doctor = __esm({
|
|
|
53701
54605
|
init_metrics2();
|
|
53702
54606
|
init_contextGrowthSummary();
|
|
53703
54607
|
require3 = createRequire3(import.meta.url);
|
|
53704
|
-
__dirname3 =
|
|
54608
|
+
__dirname3 = path63.dirname(fileURLToPath2(import.meta.url));
|
|
53705
54609
|
packageRoot = findPackageRoot(__dirname3);
|
|
53706
54610
|
OK = (message) => ({
|
|
53707
54611
|
ok: true,
|
|
@@ -53885,15 +54789,15 @@ __export(inspect_exports, {
|
|
|
53885
54789
|
collectInspectReport: () => collectInspectReport,
|
|
53886
54790
|
runInspect: () => runInspect
|
|
53887
54791
|
});
|
|
53888
|
-
import
|
|
54792
|
+
import path64 from "node:path";
|
|
53889
54793
|
import { existsSync as existsSync52, readFileSync as readFileSync41, readdirSync as readdirSync11 } from "node:fs";
|
|
53890
54794
|
import { homedir as homedir14 } from "node:os";
|
|
53891
54795
|
async function collectInspectReport(cwd = process.cwd()) {
|
|
53892
54796
|
ensureBuiltinSkillsLoadedSync();
|
|
53893
54797
|
const snap = listSkillsSnapshot(cwd);
|
|
53894
54798
|
const mcp = listMcpServers(cwd);
|
|
53895
|
-
const userMcpPath =
|
|
53896
|
-
const projectMcpPath =
|
|
54799
|
+
const userMcpPath = path64.join(homedir14(), ".zelari-code", "mcp.json");
|
|
54800
|
+
const projectMcpPath = path64.join(cwd, ".zelari", "mcp.json");
|
|
53897
54801
|
const globalHooks = globalHooksDir();
|
|
53898
54802
|
const projectHooks = projectHooksDir(cwd);
|
|
53899
54803
|
const projectTrusted = isFolderTrusted(cwd);
|
|
@@ -53921,9 +54825,9 @@ async function collectInspectReport(cwd = process.cwd()) {
|
|
|
53921
54825
|
configSources: [
|
|
53922
54826
|
{ path: userMcpPath, exists: existsSync52(userMcpPath) },
|
|
53923
54827
|
{ path: projectMcpPath, exists: existsSync52(projectMcpPath) },
|
|
53924
|
-
{ path:
|
|
53925
|
-
{ path:
|
|
53926
|
-
{ path:
|
|
54828
|
+
{ path: path64.join(homedir14(), ".zelari-code", "provider.json"), exists: existsSync52(path64.join(homedir14(), ".zelari-code", "provider.json")) },
|
|
54829
|
+
{ path: path64.join(cwd, ".zelari", "AGENTS.md"), exists: existsSync52(path64.join(cwd, ".zelari", "AGENTS.md")) },
|
|
54830
|
+
{ path: path64.join(cwd, "AGENTS.md"), exists: existsSync52(path64.join(cwd, "AGENTS.md")) }
|
|
53927
54831
|
],
|
|
53928
54832
|
skills: {
|
|
53929
54833
|
total: snap.skills.length,
|
|
@@ -53963,8 +54867,8 @@ function listJsonFiles(dir) {
|
|
|
53963
54867
|
}
|
|
53964
54868
|
function findAgentsMd(cwd) {
|
|
53965
54869
|
const candidates = [
|
|
53966
|
-
|
|
53967
|
-
|
|
54870
|
+
path64.join(cwd, "AGENTS.md"),
|
|
54871
|
+
path64.join(cwd, ".zelari", "AGENTS.md")
|
|
53968
54872
|
];
|
|
53969
54873
|
const found = [];
|
|
53970
54874
|
for (const c of candidates) {
|
|
@@ -57239,7 +58143,7 @@ init_completionGate();
|
|
|
57239
58143
|
// src/cli/kraken/verificationBridge.ts
|
|
57240
58144
|
init_candidateRegistry();
|
|
57241
58145
|
init_completionGate();
|
|
57242
|
-
import { createHash as
|
|
58146
|
+
import { createHash as createHash11 } from "node:crypto";
|
|
57243
58147
|
|
|
57244
58148
|
// src/cli/kraken/nativeVerification.ts
|
|
57245
58149
|
init_runtime2();
|
|
@@ -57366,7 +58270,7 @@ function krakenResultsToContract(requiredChecks, results, now = Date.now()) {
|
|
|
57366
58270
|
return { criteria, results: verifications };
|
|
57367
58271
|
}
|
|
57368
58272
|
function sha256Hex2(input) {
|
|
57369
|
-
return
|
|
58273
|
+
return createHash11("sha256").update(input).digest("hex");
|
|
57370
58274
|
}
|
|
57371
58275
|
function matchNoteToToolTrace(note, trace) {
|
|
57372
58276
|
const n = normalize5(note);
|
|
@@ -58013,10 +58917,14 @@ function compactEventPayload(budget, stateSnapshot, telemetry) {
|
|
|
58013
58917
|
|
|
58014
58918
|
// src/cli/budget/modelContextBuilder.ts
|
|
58015
58919
|
init_headlessSpine();
|
|
58920
|
+
init_session();
|
|
58016
58921
|
function messageWasRecompacted(message, history2) {
|
|
58017
58922
|
if (message.compactedFromSeq === void 0) return false;
|
|
58018
58923
|
return !history2.some((candidate) => candidate.seq !== void 0 && candidate.seq === message.seq);
|
|
58019
58924
|
}
|
|
58925
|
+
function resourceStatusMessage(payload) {
|
|
58926
|
+
return { role: "system", content: formatResourceSnapshot(payload) };
|
|
58927
|
+
}
|
|
58020
58928
|
async function sessionHistory(session) {
|
|
58021
58929
|
if (!session || session.status !== "active") return null;
|
|
58022
58930
|
const derived = await session.derivedPriorTurns();
|
|
@@ -58083,6 +58991,9 @@ async function buildModelContext(input) {
|
|
|
58083
58991
|
};
|
|
58084
58992
|
input.onCompactionMetric?.(compactionMetrics);
|
|
58085
58993
|
}
|
|
58994
|
+
if (input.resourceSnapshot) {
|
|
58995
|
+
history2 = [...history2, resourceStatusMessage(input.resourceSnapshot)];
|
|
58996
|
+
}
|
|
58086
58997
|
if (requestSurface) {
|
|
58087
58998
|
const measured = measureRequest({
|
|
58088
58999
|
systemMessages: requestSurface.systemMessages,
|
|
@@ -58287,6 +59198,7 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il turno continua dopo
|
|
|
58287
59198
|
const modelContext = await buildModelContext({
|
|
58288
59199
|
fallbackHistory: historyForModel,
|
|
58289
59200
|
session: writerRef.current?.spine ?? null,
|
|
59201
|
+
resourceSnapshot: writerRef.current?.spine?.latestResourceSnapshot() ?? null,
|
|
58290
59202
|
phase: workPhase,
|
|
58291
59203
|
model: getActiveModel(),
|
|
58292
59204
|
provider: envConfig?.providerId ?? (localCli || "local"),
|
|
@@ -58512,6 +59424,9 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il turno continua dopo
|
|
|
58512
59424
|
})),
|
|
58513
59425
|
toolRegistry,
|
|
58514
59426
|
providerStream,
|
|
59427
|
+
// 2.6 Phase 3: host-owned pre-dispatch resource gate via the spine
|
|
59428
|
+
// mirror (doc section 11.3). Degrade-and-stop (null gate = allow).
|
|
59429
|
+
toolCallGate: (name) => writerRef.current?.spine?.gateResourceToolCall(name) ?? { allowed: true },
|
|
58515
59430
|
cwd,
|
|
58516
59431
|
maxToolCallsPerTurn,
|
|
58517
59432
|
maxToolLoopIterations,
|
|
@@ -60583,7 +61498,7 @@ init_sessionManager();
|
|
|
60583
61498
|
// src/cli/gitOps.ts
|
|
60584
61499
|
import { execFile as execFile4 } from "node:child_process";
|
|
60585
61500
|
import { promisify as promisify3 } from "node:util";
|
|
60586
|
-
import
|
|
61501
|
+
import path49 from "node:path";
|
|
60587
61502
|
var execFileAsync3 = promisify3(execFile4);
|
|
60588
61503
|
async function git4(cwd, args) {
|
|
60589
61504
|
try {
|
|
@@ -60629,7 +61544,7 @@ async function undoWorkingChanges(opts = {}) {
|
|
|
60629
61544
|
};
|
|
60630
61545
|
}
|
|
60631
61546
|
function defaultProjectRoot() {
|
|
60632
|
-
return
|
|
61547
|
+
return path49.resolve(__dirname, "..", "..", "..");
|
|
60633
61548
|
}
|
|
60634
61549
|
|
|
60635
61550
|
// src/cli/slashHandlers/git.ts
|
|
@@ -61081,7 +61996,7 @@ import { promises as fs29 } from "node:fs";
|
|
|
61081
61996
|
init_zod();
|
|
61082
61997
|
init_taskTool();
|
|
61083
61998
|
import { promises as fs28 } from "node:fs";
|
|
61084
|
-
import
|
|
61999
|
+
import path53 from "node:path";
|
|
61085
62000
|
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
61086
62001
|
var CsvFanoutArgsSchema = external_exports.object({
|
|
61087
62002
|
csv_path: external_exports.string().min(1),
|
|
@@ -61175,8 +62090,8 @@ function resolveMaxConcurrency(env = process.env) {
|
|
|
61175
62090
|
}
|
|
61176
62091
|
async function runCsvFanout(args, deps, opts) {
|
|
61177
62092
|
const start = Date.now();
|
|
61178
|
-
const absCsv =
|
|
61179
|
-
const absOut =
|
|
62093
|
+
const absCsv = path53.isAbsolute(args.csv_path) ? args.csv_path : path53.join(opts.parentCwd, args.csv_path);
|
|
62094
|
+
const absOut = path53.isAbsolute(args.output_csv_path) ? args.output_csv_path : path53.join(opts.parentCwd, args.output_csv_path);
|
|
61180
62095
|
const { headers: headers2, rows } = await readCsv(absCsv);
|
|
61181
62096
|
if (headers2.length === 0) {
|
|
61182
62097
|
throw new Error(`kraken_csv_fanout: ${absCsv} is empty`);
|
|
@@ -61232,7 +62147,7 @@ async function runCsvFanout(args, deps, opts) {
|
|
|
61232
62147
|
errored += 1;
|
|
61233
62148
|
errors.push(`${row[args.id_column] ?? i}: ${res.error}`);
|
|
61234
62149
|
}
|
|
61235
|
-
await fs28.mkdir(
|
|
62150
|
+
await fs28.mkdir(path53.dirname(absOut), { recursive: true });
|
|
61236
62151
|
await queueWrite(serializeCsv(outHeaders, outputRecords));
|
|
61237
62152
|
}
|
|
61238
62153
|
}
|
|
@@ -61427,7 +62342,7 @@ function splitArgs(s) {
|
|
|
61427
62342
|
// src/cli/slashHandlers/krakenWorkbench.ts
|
|
61428
62343
|
init_messageHelpers();
|
|
61429
62344
|
import { promises as fs30 } from "node:fs";
|
|
61430
|
-
import
|
|
62345
|
+
import path54 from "node:path";
|
|
61431
62346
|
|
|
61432
62347
|
// src/cli/kraken/workbenchView.ts
|
|
61433
62348
|
var EMPTY = {
|
|
@@ -61544,14 +62459,14 @@ function formatWorkbenchForTerminal(p3) {
|
|
|
61544
62459
|
|
|
61545
62460
|
// src/cli/slashHandlers/krakenWorkbench.ts
|
|
61546
62461
|
async function handleKrakenWorkbench(ctx) {
|
|
61547
|
-
const dir =
|
|
62462
|
+
const dir = path54.join(ctx.cwd, ".zelari", "radio");
|
|
61548
62463
|
let latest = null;
|
|
61549
62464
|
let latestMtime = 0;
|
|
61550
62465
|
try {
|
|
61551
62466
|
const files = await fs30.readdir(dir);
|
|
61552
62467
|
for (const f of files) {
|
|
61553
62468
|
if (!f.startsWith("workbench-") || !f.endsWith(".md")) continue;
|
|
61554
|
-
const full =
|
|
62469
|
+
const full = path54.join(dir, f);
|
|
61555
62470
|
const stat = await fs30.stat(full);
|
|
61556
62471
|
if (stat.mtimeMs > latestMtime) {
|
|
61557
62472
|
latestMtime = stat.mtimeMs;
|
|
@@ -61568,10 +62483,10 @@ async function handleKrakenWorkbench(ctx) {
|
|
|
61568
62483
|
const parsed = parseWorkbench(content);
|
|
61569
62484
|
const rendered = formatWorkbenchForTerminal(parsed);
|
|
61570
62485
|
if (!rendered.trim()) {
|
|
61571
|
-
appendSystem(ctx.setMessages, `[kraken workbench] ${
|
|
62486
|
+
appendSystem(ctx.setMessages, `[kraken workbench] ${path54.basename(latest)}: (no nodes / no events yet)`);
|
|
61572
62487
|
return;
|
|
61573
62488
|
}
|
|
61574
|
-
appendSystem(ctx.setMessages, `[kraken workbench] ${
|
|
62489
|
+
appendSystem(ctx.setMessages, `[kraken workbench] ${path54.basename(latest)}:
|
|
61575
62490
|
${rendered}`);
|
|
61576
62491
|
}
|
|
61577
62492
|
|
|
@@ -61878,15 +62793,15 @@ ${result.output.split("\n").slice(-8).join("\n")}` : "";
|
|
|
61878
62793
|
// src/cli/slashHandlers/promoteMember.ts
|
|
61879
62794
|
init_messageHelpers();
|
|
61880
62795
|
import { promises as fs31 } from "node:fs";
|
|
61881
|
-
import
|
|
62796
|
+
import path57 from "node:path";
|
|
61882
62797
|
import os12 from "node:os";
|
|
61883
62798
|
async function handlePromoteMember(ctx, memberId) {
|
|
61884
62799
|
try {
|
|
61885
62800
|
const { promoteMember: promoteMember2 } = await Promise.resolve().then(() => (init_council(), council_exports));
|
|
61886
62801
|
const { skill, markdown } = promoteMember2(memberId);
|
|
61887
|
-
const skillDir = process.env.ANATHEMA_SKILL_DIR ??
|
|
62802
|
+
const skillDir = process.env.ANATHEMA_SKILL_DIR ?? path57.join(os12.homedir(), ".tmp", "zelari-code", "skills");
|
|
61888
62803
|
await fs31.mkdir(skillDir, { recursive: true });
|
|
61889
|
-
const filePath =
|
|
62804
|
+
const filePath = path57.join(skillDir, `${skill.id}.md`);
|
|
61890
62805
|
await fs31.writeFile(filePath, markdown, "utf8");
|
|
61891
62806
|
appendSystem(
|
|
61892
62807
|
ctx.setMessages,
|
|
@@ -61904,24 +62819,24 @@ async function handlePromoteMember(ctx, memberId) {
|
|
|
61904
62819
|
|
|
61905
62820
|
// src/cli/branchManager.ts
|
|
61906
62821
|
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";
|
|
61907
|
-
import
|
|
62822
|
+
import path58 from "node:path";
|
|
61908
62823
|
import os13 from "node:os";
|
|
61909
62824
|
var META_FILENAME = "meta.json";
|
|
61910
62825
|
var SESSIONS_SUBDIR = "sessions";
|
|
61911
62826
|
function getBranchesBaseDir() {
|
|
61912
|
-
return process.env.ANATHEMA_BRANCHES_DIR ??
|
|
62827
|
+
return process.env.ANATHEMA_BRANCHES_DIR ?? path58.join(os13.homedir(), ".tmp", "zelari-code", "branches");
|
|
61913
62828
|
}
|
|
61914
62829
|
function getSessionsBaseDir() {
|
|
61915
|
-
return process.env.ANATHEMA_SESSIONS_DIR ??
|
|
62830
|
+
return process.env.ANATHEMA_SESSIONS_DIR ?? path58.join(os13.homedir(), ".tmp", "zelari-code", "sessions");
|
|
61916
62831
|
}
|
|
61917
62832
|
function branchPathFor(name, baseDir) {
|
|
61918
|
-
return
|
|
62833
|
+
return path58.join(baseDir, name);
|
|
61919
62834
|
}
|
|
61920
62835
|
function metaPathFor(name, baseDir) {
|
|
61921
|
-
return
|
|
62836
|
+
return path58.join(baseDir, name, META_FILENAME);
|
|
61922
62837
|
}
|
|
61923
62838
|
function sessionsPathFor(name, baseDir) {
|
|
61924
|
-
return
|
|
62839
|
+
return path58.join(baseDir, name, SESSIONS_SUBDIR);
|
|
61925
62840
|
}
|
|
61926
62841
|
function readBranchMeta(name, baseDir) {
|
|
61927
62842
|
const metaPath = metaPathFor(name, baseDir);
|
|
@@ -61946,7 +62861,7 @@ function readBranchMeta(name, baseDir) {
|
|
|
61946
62861
|
}
|
|
61947
62862
|
function writeBranchMeta(name, baseDir, meta3) {
|
|
61948
62863
|
const metaPath = metaPathFor(name, baseDir);
|
|
61949
|
-
mkdirSync19(
|
|
62864
|
+
mkdirSync19(path58.dirname(metaPath), { recursive: true });
|
|
61950
62865
|
writeFileSync23(metaPath, JSON.stringify(meta3, null, 2), "utf-8");
|
|
61951
62866
|
}
|
|
61952
62867
|
async function countSessions(name, baseDir) {
|
|
@@ -61997,14 +62912,14 @@ async function createBranch(name, fromSessionId, baseDir = getBranchesBaseDir(),
|
|
|
61997
62912
|
if (branchExists(name, baseDir)) {
|
|
61998
62913
|
throw new BranchAlreadyExistsError(name);
|
|
61999
62914
|
}
|
|
62000
|
-
const sourcePath =
|
|
62915
|
+
const sourcePath = path58.join(sessionsBaseDir, `${fromSessionId}.jsonl`);
|
|
62001
62916
|
if (!existsSync44(sourcePath)) {
|
|
62002
62917
|
throw new SessionNotFoundError(`Source session "${fromSessionId}" not found at ${sourcePath}`);
|
|
62003
62918
|
}
|
|
62004
62919
|
const branchPath = branchPathFor(name, baseDir);
|
|
62005
62920
|
const branchSessionsPath = sessionsPathFor(name, baseDir);
|
|
62006
62921
|
mkdirSync19(branchSessionsPath, { recursive: true });
|
|
62007
|
-
const destPath =
|
|
62922
|
+
const destPath = path58.join(branchSessionsPath, `${fromSessionId}.jsonl`);
|
|
62008
62923
|
await fs32.copyFile(sourcePath, destPath);
|
|
62009
62924
|
const meta3 = {
|
|
62010
62925
|
name,
|
|
@@ -62108,14 +63023,14 @@ async function handleBranchCheckout(ctx, branchName) {
|
|
|
62108
63023
|
// src/cli/slashHandlers/workspace.ts
|
|
62109
63024
|
init_messageHelpers();
|
|
62110
63025
|
import { promises as fs33 } from "node:fs";
|
|
62111
|
-
import
|
|
63026
|
+
import path59 from "node:path";
|
|
62112
63027
|
async function handleWorkspaceShow(ctx, what) {
|
|
62113
63028
|
try {
|
|
62114
|
-
const zelari =
|
|
63029
|
+
const zelari = path59.join(process.cwd(), ".zelari");
|
|
62115
63030
|
let content;
|
|
62116
63031
|
switch (what) {
|
|
62117
63032
|
case "plan": {
|
|
62118
|
-
const planPath =
|
|
63033
|
+
const planPath = path59.join(zelari, "plan.md");
|
|
62119
63034
|
try {
|
|
62120
63035
|
content = await fs33.readFile(planPath, "utf-8");
|
|
62121
63036
|
} catch {
|
|
@@ -62124,7 +63039,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
62124
63039
|
break;
|
|
62125
63040
|
}
|
|
62126
63041
|
case "decisions": {
|
|
62127
|
-
const decisionsDir =
|
|
63042
|
+
const decisionsDir = path59.join(zelari, "decisions");
|
|
62128
63043
|
try {
|
|
62129
63044
|
const files = (await fs33.readdir(decisionsDir)).filter((f) => f.endsWith(".md")).sort();
|
|
62130
63045
|
if (files.length === 0) {
|
|
@@ -62134,7 +63049,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
62134
63049
|
`];
|
|
62135
63050
|
const { parseFrontmatter: parseFrontmatter2 } = await Promise.resolve().then(() => (init_storage(), storage_exports));
|
|
62136
63051
|
for (const f of files) {
|
|
62137
|
-
const raw = await fs33.readFile(
|
|
63052
|
+
const raw = await fs33.readFile(path59.join(decisionsDir, f), "utf-8");
|
|
62138
63053
|
const { meta: meta3, body } = parseFrontmatter2(raw);
|
|
62139
63054
|
const title = meta3.title ?? body.split("\n")[0]?.replace(/^#\s*/, "").trim() ?? f;
|
|
62140
63055
|
lines.push(`- **${f.replace(/\.md$/, "")}** [${meta3.status ?? "unknown"}] ${title}`);
|
|
@@ -62147,7 +63062,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
62147
63062
|
break;
|
|
62148
63063
|
}
|
|
62149
63064
|
case "risks": {
|
|
62150
|
-
const risksPath =
|
|
63065
|
+
const risksPath = path59.join(zelari, "risks.md");
|
|
62151
63066
|
try {
|
|
62152
63067
|
content = await fs33.readFile(risksPath, "utf-8");
|
|
62153
63068
|
} catch {
|
|
@@ -62156,7 +63071,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
62156
63071
|
break;
|
|
62157
63072
|
}
|
|
62158
63073
|
case "agents": {
|
|
62159
|
-
const agentsPath =
|
|
63074
|
+
const agentsPath = path59.join(process.cwd(), "AGENTS.MD");
|
|
62160
63075
|
try {
|
|
62161
63076
|
content = await fs33.readFile(agentsPath, "utf-8");
|
|
62162
63077
|
} catch {
|
|
@@ -62165,7 +63080,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
62165
63080
|
break;
|
|
62166
63081
|
}
|
|
62167
63082
|
case "docs": {
|
|
62168
|
-
const docsDir =
|
|
63083
|
+
const docsDir = path59.join(zelari, "docs");
|
|
62169
63084
|
try {
|
|
62170
63085
|
const files = (await fs33.readdir(docsDir)).filter((f) => f.endsWith(".md")).sort();
|
|
62171
63086
|
content = files.length ? `# Docs (${files.length})
|
|
@@ -62207,7 +63122,7 @@ async function handleWorkspaceReset(ctx, force) {
|
|
|
62207
63122
|
return;
|
|
62208
63123
|
}
|
|
62209
63124
|
try {
|
|
62210
|
-
const target =
|
|
63125
|
+
const target = path59.join(process.cwd(), ".zelari");
|
|
62211
63126
|
await fs33.rm(target, { recursive: true, force: true });
|
|
62212
63127
|
appendSystem(ctx.setMessages, "[workspace] .zelari/ removed");
|
|
62213
63128
|
} catch (err) {
|
|
@@ -62219,7 +63134,7 @@ async function handleWorkspaceReset(ctx, force) {
|
|
|
62219
63134
|
init_provider2();
|
|
62220
63135
|
|
|
62221
63136
|
// src/cli/slashHandlers/skills.ts
|
|
62222
|
-
import
|
|
63137
|
+
import path60 from "node:path";
|
|
62223
63138
|
import os14 from "node:os";
|
|
62224
63139
|
|
|
62225
63140
|
// src/cli/skillHistory.ts
|
|
@@ -62348,7 +63263,7 @@ function handleSkillPicker(ctx, skills, openPicker, fallbackMessage) {
|
|
|
62348
63263
|
});
|
|
62349
63264
|
}
|
|
62350
63265
|
async function handleSkillStats(ctx, skillId) {
|
|
62351
|
-
const historyFile = process.env.ANATHEMA_SKILL_HISTORY_FILE ??
|
|
63266
|
+
const historyFile = process.env.ANATHEMA_SKILL_HISTORY_FILE ?? path60.join(os14.homedir(), ".tmp", "zelari-code", "skill-history.jsonl");
|
|
62352
63267
|
try {
|
|
62353
63268
|
const records = await readSkillHistory(historyFile);
|
|
62354
63269
|
const stats = getSkillStats(records, skillId);
|
|
@@ -62364,7 +63279,7 @@ async function handleSkillCompare(ctx, ids, fallbackMessage) {
|
|
|
62364
63279
|
appendSystem(ctx.setMessages, fallbackMessage ?? "[skill-compare] missing args");
|
|
62365
63280
|
return;
|
|
62366
63281
|
}
|
|
62367
|
-
const historyFile = process.env.ANATHEMA_SKILL_HISTORY_FILE ??
|
|
63282
|
+
const historyFile = process.env.ANATHEMA_SKILL_HISTORY_FILE ?? path60.join(os14.homedir(), ".tmp", "zelari-code", "skill-history.jsonl");
|
|
62368
63283
|
try {
|
|
62369
63284
|
const formatted = await compareSkillsFromFile(ids[0], ids[1], historyFile);
|
|
62370
63285
|
appendSystem(ctx.setMessages, formatted);
|
|
@@ -63908,7 +64823,7 @@ function createStreamScrubber2() {
|
|
|
63908
64823
|
init_taskTool();
|
|
63909
64824
|
init_sessionTodos();
|
|
63910
64825
|
import { promises as fs36 } from "node:fs";
|
|
63911
|
-
import
|
|
64826
|
+
import path62 from "node:path";
|
|
63912
64827
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
63913
64828
|
|
|
63914
64829
|
// src/cli/kraken/verifierLifecycle.ts
|
|
@@ -64165,7 +65080,7 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
64165
65080
|
try {
|
|
64166
65081
|
let preflightGraph;
|
|
64167
65082
|
if (opts.runPlan && opts.runPlan.trim() !== "") {
|
|
64168
|
-
const planPath =
|
|
65083
|
+
const planPath = path62.join(cwd, ".zelari", "radio", `plan-${opts.runPlan}.json`);
|
|
64169
65084
|
log(`loading pre-flight plan: ${planPath}`);
|
|
64170
65085
|
let raw;
|
|
64171
65086
|
try {
|
|
@@ -64205,8 +65120,8 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
64205
65120
|
log(formatKrakenGraphAscii2(graph));
|
|
64206
65121
|
if (opts.planOnly) {
|
|
64207
65122
|
const planId = randomUUID6();
|
|
64208
|
-
const planDir =
|
|
64209
|
-
const planPath =
|
|
65123
|
+
const planDir = path62.join(cwd, ".zelari", "radio");
|
|
65124
|
+
const planPath = path62.join(planDir, `plan-${planId}.json`);
|
|
64210
65125
|
await fs36.mkdir(planDir, { recursive: true });
|
|
64211
65126
|
await fs36.writeFile(
|
|
64212
65127
|
planPath,
|
|
@@ -64485,6 +65400,7 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
64485
65400
|
const modelContext = await buildModelContext({
|
|
64486
65401
|
fallbackHistory: seededHistory.history,
|
|
64487
65402
|
session: spine.spine,
|
|
65403
|
+
resourceSnapshot: spine.spine.latestResourceSnapshot(),
|
|
64488
65404
|
phase: opts.phase ?? "build",
|
|
64489
65405
|
model,
|
|
64490
65406
|
provider,
|
|
@@ -64524,6 +65440,10 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
64524
65440
|
tools,
|
|
64525
65441
|
toolRegistry,
|
|
64526
65442
|
providerStream,
|
|
65443
|
+
// 2.6 Phase 3: host-owned pre-dispatch resource gate (doc section 11.3).
|
|
65444
|
+
// Advisory by default; ZELARI_RESOURCE_ENFORCEMENT=protected enables the
|
|
65445
|
+
// protected verification reserve. Degrade-and-stop (null gate = allow).
|
|
65446
|
+
toolCallGate: (name) => spine.gateResourceToolCall(name) ?? { allowed: true },
|
|
64527
65447
|
maxToolLoopIterations: maxToolLoop
|
|
64528
65448
|
});
|
|
64529
65449
|
let finalReason = "completed";
|
|
@@ -64765,7 +65685,7 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
64765
65685
|
if (json2) {
|
|
64766
65686
|
if (opts.exportSessionPath === "-") process.stdout.write(json2 + "\n");
|
|
64767
65687
|
else {
|
|
64768
|
-
await fs36.mkdir(
|
|
65688
|
+
await fs36.mkdir(path62.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
64769
65689
|
await fs36.writeFile(opts.exportSessionPath, json2, "utf8");
|
|
64770
65690
|
}
|
|
64771
65691
|
}
|
|
@@ -64949,7 +65869,7 @@ async function runHeadlessCouncil(opts, provider, model, providerStream) {
|
|
|
64949
65869
|
if (json2) {
|
|
64950
65870
|
if (opts.exportSessionPath === "-") process.stdout.write(json2 + "\n");
|
|
64951
65871
|
else {
|
|
64952
|
-
await fs36.mkdir(
|
|
65872
|
+
await fs36.mkdir(path62.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
64953
65873
|
await fs36.writeFile(opts.exportSessionPath, json2, "utf8");
|
|
64954
65874
|
}
|
|
64955
65875
|
}
|
|
@@ -65313,7 +66233,7 @@ ${ragContext}` : slicePrompt;
|
|
|
65313
66233
|
if (json2) {
|
|
65314
66234
|
if (opts.exportSessionPath === "-") process.stdout.write(json2 + "\n");
|
|
65315
66235
|
else {
|
|
65316
|
-
await fs36.mkdir(
|
|
66236
|
+
await fs36.mkdir(path62.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
65317
66237
|
await fs36.writeFile(opts.exportSessionPath, json2, "utf8");
|
|
65318
66238
|
}
|
|
65319
66239
|
}
|
|
@@ -65515,8 +66435,8 @@ function normalizeDraft(raw, sourceUrl, provider, model) {
|
|
|
65515
66435
|
let name = String(o.name ?? "").trim().toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64);
|
|
65516
66436
|
if (!name || !/^[a-z0-9][a-z0-9-]{0,63}$/.test(name)) {
|
|
65517
66437
|
try {
|
|
65518
|
-
const
|
|
65519
|
-
name =
|
|
66438
|
+
const path65 = new URL(sourceUrl).pathname.split("/").filter(Boolean).pop()?.replace(/\.[a-z0-9]+$/i, "").toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48);
|
|
66439
|
+
name = path65 && /^[a-z0-9]/.test(path65) ? path65 : "imported-skill";
|
|
65520
66440
|
} catch {
|
|
65521
66441
|
name = "imported-skill";
|
|
65522
66442
|
}
|