zelari-code 2.10.0 → 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/headless/controlBridge.js +91 -0
- package/dist/cli/headless/controlBridge.js.map +1 -0
- package/dist/cli/headless/controlReader.js +88 -0
- package/dist/cli/headless/controlReader.js.map +1 -0
- package/dist/cli/headless/protocol.js +53 -0
- package/dist/cli/headless/protocol.js.map +1 -0
- package/dist/cli/main.bundled.js +2471 -336
- package/dist/cli/main.bundled.js.map +4 -4
- package/dist/cli/runHeadless.js +31 -0
- package/dist/cli/runHeadless.js.map +1 -1
- package/dist/cli/toolRegistry.js +1 -0
- package/dist/cli/toolRegistry.js.map +1 -1
- package/dist/cli/tools/taskTool.js +53 -8
- package/dist/cli/tools/taskTool.js.map +1 -1
- package/package.json +2 -2
package/dist/cli/main.bundled.js
CHANGED
|
@@ -276,8 +276,8 @@ function formatDuration(ms) {
|
|
|
276
276
|
const rs = s % 60;
|
|
277
277
|
if (m < 60) return rs === 0 ? `${m}m${sign}` : `${m}m ${rs}s${sign}`;
|
|
278
278
|
const h = Math.floor(m / 60);
|
|
279
|
-
const
|
|
280
|
-
if (h < 24) return
|
|
279
|
+
const rm2 = m % 60;
|
|
280
|
+
if (h < 24) return rm2 === 0 ? `${h}h${sign}` : `${h}h ${rm2}m${sign}`;
|
|
281
281
|
const d = Math.floor(h / 24);
|
|
282
282
|
const rh = h % 24;
|
|
283
283
|
return rh === 0 ? `${d}d${sign}` : `${d}d ${rh}h${sign}`;
|
|
@@ -1627,12 +1627,12 @@ var init_keyStore = __esm({
|
|
|
1627
1627
|
|
|
1628
1628
|
// src/cli/thinkingCapability.ts
|
|
1629
1629
|
function thinkingCapabilityFor(id3, model) {
|
|
1630
|
-
const
|
|
1630
|
+
const base2 = PROVIDER_THINKING_CAPABILITY[id3] ?? {};
|
|
1631
1631
|
const efforts = effortLevelsFor(id3, model);
|
|
1632
1632
|
const budget = supportsBudget(id3, model);
|
|
1633
1633
|
return {
|
|
1634
|
-
...
|
|
1635
|
-
effort: efforts.length > 0 || Boolean(
|
|
1634
|
+
...base2,
|
|
1635
|
+
effort: efforts.length > 0 || Boolean(base2.effort),
|
|
1636
1636
|
budget,
|
|
1637
1637
|
efforts: efforts.length > 0 ? efforts : void 0
|
|
1638
1638
|
};
|
|
@@ -18536,8 +18536,8 @@ var init_shellResolver = __esm({
|
|
|
18536
18536
|
// packages/core/dist/core/tools/builtin/shell.js
|
|
18537
18537
|
import { spawn } from "node:child_process";
|
|
18538
18538
|
import { dirname } from "node:path";
|
|
18539
|
-
function withNodeDirOnPath(
|
|
18540
|
-
const env = { ...
|
|
18539
|
+
function withNodeDirOnPath(base2) {
|
|
18540
|
+
const env = { ...base2 };
|
|
18541
18541
|
try {
|
|
18542
18542
|
const nodeDir = dirname(process.execPath);
|
|
18543
18543
|
if (!nodeDir)
|
|
@@ -18840,8 +18840,8 @@ async function searchFile(absPath, relPath, regex, contextLines, remainingSlots)
|
|
|
18840
18840
|
}
|
|
18841
18841
|
async function isDirectory(p3) {
|
|
18842
18842
|
try {
|
|
18843
|
-
const
|
|
18844
|
-
return
|
|
18843
|
+
const stat2 = await fs6.stat(p3);
|
|
18844
|
+
return stat2.isDirectory();
|
|
18845
18845
|
} catch {
|
|
18846
18846
|
return false;
|
|
18847
18847
|
}
|
|
@@ -21207,8 +21207,8 @@ function formatTodoStatusSummary(list = todos) {
|
|
|
21207
21207
|
(t) => t.status === "completed" || t.status === "cancelled"
|
|
21208
21208
|
).length;
|
|
21209
21209
|
const active = list.filter((t) => t.status === "in_progress").length;
|
|
21210
|
-
const
|
|
21211
|
-
return active > 0 ? `${
|
|
21210
|
+
const base2 = `todos ${done}/${list.length}`;
|
|
21211
|
+
return active > 0 ? `${base2} \xB7 ${active} active` : base2;
|
|
21212
21212
|
}
|
|
21213
21213
|
var todos;
|
|
21214
21214
|
var init_sessionTodos = __esm({
|
|
@@ -21622,11 +21622,11 @@ function createRoutedRequestSnapshot(params) {
|
|
|
21622
21622
|
};
|
|
21623
21623
|
}
|
|
21624
21624
|
function compareReplayPrefix(snapshot, messages) {
|
|
21625
|
-
const
|
|
21626
|
-
const n = Math.min(
|
|
21625
|
+
const base2 = snapshot.conversation;
|
|
21626
|
+
const n = Math.min(base2.length, messages.length);
|
|
21627
21627
|
let matching = 0;
|
|
21628
21628
|
for (let i = 0; i < n; i++) {
|
|
21629
|
-
if (stableStringify(
|
|
21629
|
+
if (stableStringify(base2[i]) !== stableStringify(messages[i])) {
|
|
21630
21630
|
return { exact: false, matchingMessages: matching, mismatchIndex: i };
|
|
21631
21631
|
}
|
|
21632
21632
|
matching++;
|
|
@@ -21835,6 +21835,1156 @@ var init_textLoopDetect = __esm({
|
|
|
21835
21835
|
}
|
|
21836
21836
|
});
|
|
21837
21837
|
|
|
21838
|
+
// packages/core/dist/runtime/observers/types.js
|
|
21839
|
+
var CONTINUE;
|
|
21840
|
+
var init_types2 = __esm({
|
|
21841
|
+
"packages/core/dist/runtime/observers/types.js"() {
|
|
21842
|
+
"use strict";
|
|
21843
|
+
CONTINUE = { action: "continue" };
|
|
21844
|
+
}
|
|
21845
|
+
});
|
|
21846
|
+
|
|
21847
|
+
// packages/core/dist/runtime/observers/resolve.js
|
|
21848
|
+
function resolveInterventions(results) {
|
|
21849
|
+
if (results.length === 0)
|
|
21850
|
+
return CONTINUE;
|
|
21851
|
+
let best = results[0];
|
|
21852
|
+
let bestRank = ACTION_RANK[best.action];
|
|
21853
|
+
for (let i = 1; i < results.length; i += 1) {
|
|
21854
|
+
const rank = ACTION_RANK[results[i].action];
|
|
21855
|
+
if (rank > bestRank) {
|
|
21856
|
+
best = results[i];
|
|
21857
|
+
bestRank = rank;
|
|
21858
|
+
}
|
|
21859
|
+
}
|
|
21860
|
+
return best;
|
|
21861
|
+
}
|
|
21862
|
+
var ACTION_RANK;
|
|
21863
|
+
var init_resolve = __esm({
|
|
21864
|
+
"packages/core/dist/runtime/observers/resolve.js"() {
|
|
21865
|
+
"use strict";
|
|
21866
|
+
init_types2();
|
|
21867
|
+
ACTION_RANK = {
|
|
21868
|
+
deny_tool: 6,
|
|
21869
|
+
stop: 5,
|
|
21870
|
+
retry: 4,
|
|
21871
|
+
replace: 3,
|
|
21872
|
+
inject: 2,
|
|
21873
|
+
continue: 1
|
|
21874
|
+
};
|
|
21875
|
+
}
|
|
21876
|
+
});
|
|
21877
|
+
|
|
21878
|
+
// packages/core/dist/runtime/guards/RepetitionGuard.js
|
|
21879
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
21880
|
+
function toolCallFingerprint(tool, args) {
|
|
21881
|
+
const argsHash = createHash3("sha256").update(stableStringify(args ?? null)).digest("hex");
|
|
21882
|
+
return { tool, argsHash };
|
|
21883
|
+
}
|
|
21884
|
+
var REASSESS_MESSAGE, RepetitionGuard;
|
|
21885
|
+
var init_RepetitionGuard = __esm({
|
|
21886
|
+
"packages/core/dist/runtime/guards/RepetitionGuard.js"() {
|
|
21887
|
+
"use strict";
|
|
21888
|
+
init_requestSnapshot();
|
|
21889
|
+
init_types2();
|
|
21890
|
+
REASSESS_MESSAGE = [
|
|
21891
|
+
"The same tool call has produced no new progress multiple times.",
|
|
21892
|
+
"Reassess the current hypothesis before repeating it again."
|
|
21893
|
+
].join("\n");
|
|
21894
|
+
RepetitionGuard = class {
|
|
21895
|
+
counts = /* @__PURE__ */ new Map();
|
|
21896
|
+
warnAfter;
|
|
21897
|
+
stopAfter;
|
|
21898
|
+
constructor(config2 = {}) {
|
|
21899
|
+
this.warnAfter = config2.warnAfter ?? 2;
|
|
21900
|
+
this.stopAfter = config2.stopAfter ?? 5;
|
|
21901
|
+
}
|
|
21902
|
+
async onToolCall(event) {
|
|
21903
|
+
const fingerprint = toolCallFingerprint(event.toolName, event.args);
|
|
21904
|
+
const key = `${fingerprint.tool}\0${fingerprint.argsHash}`;
|
|
21905
|
+
const count = (this.counts.get(key) ?? 0) + 1;
|
|
21906
|
+
this.counts.set(key, count);
|
|
21907
|
+
if (count >= this.stopAfter) {
|
|
21908
|
+
return {
|
|
21909
|
+
action: "stop",
|
|
21910
|
+
reason: `repeated tool call "${fingerprint.tool}" ${count} times without new progress`,
|
|
21911
|
+
code: "repeated_tool"
|
|
21912
|
+
};
|
|
21913
|
+
}
|
|
21914
|
+
if (count >= this.warnAfter) {
|
|
21915
|
+
return {
|
|
21916
|
+
action: "inject",
|
|
21917
|
+
message: { role: "user", kind: "runtime-warning", content: REASSESS_MESSAGE }
|
|
21918
|
+
};
|
|
21919
|
+
}
|
|
21920
|
+
return CONTINUE;
|
|
21921
|
+
}
|
|
21922
|
+
reset() {
|
|
21923
|
+
this.counts.clear();
|
|
21924
|
+
}
|
|
21925
|
+
};
|
|
21926
|
+
}
|
|
21927
|
+
});
|
|
21928
|
+
|
|
21929
|
+
// packages/core/dist/runtime/guards/FailureSignatureGuard.js
|
|
21930
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
21931
|
+
function stripAnsi(text) {
|
|
21932
|
+
return text.replace(/\u001b\[[0-9;]*[A-Za-z]/g, "");
|
|
21933
|
+
}
|
|
21934
|
+
function normalizeFailureTail(text, tailChars = 2e3) {
|
|
21935
|
+
const tail2 = stripAnsi(text).slice(-tailChars);
|
|
21936
|
+
const lines = tail2.split(/\r?\n/).map((line) => line.replace(/\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:?\d{2})?/g, "<ts>").replace(/\b\d{1,2}:\d{2}:\d{2}(\.\d+)?\b/g, "<time>").replace(/\b\d+(\.\d+)?\s*(ms|s|sec|secs|seconds|min|mins|minutes)\b/gi, "<dur>").replace(/\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/gi, "<uuid>").replace(/\b(?:pid|process)\s*[:=]?\s*\d+\b/gi, "<pid>").replace(/(?:\/tmp\/|\/var\/tmp\/|\b[A-Za-z]:\\Users\\[^\\]*\\AppData\\Local\\Temp\\)[^\s"']*/gi, "<tmp>"));
|
|
21937
|
+
const meaningful = lines.filter((line) => {
|
|
21938
|
+
const trimmed = line.trim();
|
|
21939
|
+
if (!trimmed)
|
|
21940
|
+
return false;
|
|
21941
|
+
if (/^\s*[✓✔●○◐◑◌]/.test(line))
|
|
21942
|
+
return false;
|
|
21943
|
+
if (/^\s*[|/\\-–—]\s*$/.test(line))
|
|
21944
|
+
return false;
|
|
21945
|
+
if (/^\s*\d+\s*\/\s*\d+\s*$/.test(line))
|
|
21946
|
+
return false;
|
|
21947
|
+
return true;
|
|
21948
|
+
});
|
|
21949
|
+
return meaningful.join("\n");
|
|
21950
|
+
}
|
|
21951
|
+
function extractFailure(result) {
|
|
21952
|
+
if (typeof result === "string")
|
|
21953
|
+
return { text: result };
|
|
21954
|
+
if (result && typeof result === "object") {
|
|
21955
|
+
const r = result;
|
|
21956
|
+
const parts = [r.stdout, r.stderr, r.output, r.content, r.message].filter((p3) => typeof p3 === "string");
|
|
21957
|
+
if (typeof r.exitCode === "number" || parts.length > 0) {
|
|
21958
|
+
return { exitCode: r.exitCode, text: parts.join("\n") };
|
|
21959
|
+
}
|
|
21960
|
+
return { text: stableStringify(result).slice(0, 4e3) };
|
|
21961
|
+
}
|
|
21962
|
+
return void 0;
|
|
21963
|
+
}
|
|
21964
|
+
var REASSESS_MESSAGE2, MAX_PENDING, FailureSignatureGuard;
|
|
21965
|
+
var init_FailureSignatureGuard = __esm({
|
|
21966
|
+
"packages/core/dist/runtime/guards/FailureSignatureGuard.js"() {
|
|
21967
|
+
"use strict";
|
|
21968
|
+
init_requestSnapshot();
|
|
21969
|
+
init_types2();
|
|
21970
|
+
init_RepetitionGuard();
|
|
21971
|
+
REASSESS_MESSAGE2 = [
|
|
21972
|
+
"The same failure signature has persisted across multiple attempts.",
|
|
21973
|
+
"Do not repeat the previous edit strategy. Re-evaluate the root cause,",
|
|
21974
|
+
"inspect upstream state, or delegate a fresh verification/exploration task."
|
|
21975
|
+
].join("\n");
|
|
21976
|
+
MAX_PENDING = 256;
|
|
21977
|
+
FailureSignatureGuard = class {
|
|
21978
|
+
counts = /* @__PURE__ */ new Map();
|
|
21979
|
+
pendingArgs = /* @__PURE__ */ new Map();
|
|
21980
|
+
warnAfter;
|
|
21981
|
+
stopAfter;
|
|
21982
|
+
tailChars;
|
|
21983
|
+
constructor(config2 = {}) {
|
|
21984
|
+
this.warnAfter = config2.warnAfter ?? 2;
|
|
21985
|
+
this.stopAfter = config2.stopAfter ?? 5;
|
|
21986
|
+
this.tailChars = config2.tailChars ?? 2e3;
|
|
21987
|
+
}
|
|
21988
|
+
/** Track per-call command hashes so onToolResult can bind args → result. */
|
|
21989
|
+
async onToolCall(event) {
|
|
21990
|
+
const { argsHash } = toolCallFingerprint(event.toolName, event.args);
|
|
21991
|
+
if (this.pendingArgs.size >= MAX_PENDING) {
|
|
21992
|
+
const oldest = this.pendingArgs.keys().next().value;
|
|
21993
|
+
if (oldest !== void 0)
|
|
21994
|
+
this.pendingArgs.delete(oldest);
|
|
21995
|
+
}
|
|
21996
|
+
this.pendingArgs.set(event.toolCallId, `${event.toolName}\0${argsHash}`);
|
|
21997
|
+
return CONTINUE;
|
|
21998
|
+
}
|
|
21999
|
+
async onToolResult(event) {
|
|
22000
|
+
const commandHash = this.pendingArgs.get(event.toolCallId) ?? event.toolName;
|
|
22001
|
+
this.pendingArgs.delete(event.toolCallId);
|
|
22002
|
+
const failure = extractFailure(event.result);
|
|
22003
|
+
if (!failure || !failure.text.trim())
|
|
22004
|
+
return CONTINUE;
|
|
22005
|
+
const failed = failure.exitCode !== void 0 ? failure.exitCode !== 0 : event.ok === false;
|
|
22006
|
+
if (!failed) {
|
|
22007
|
+
for (const key2 of this.counts.keys()) {
|
|
22008
|
+
if (key2.startsWith(`${commandHash}\0`))
|
|
22009
|
+
this.counts.delete(key2);
|
|
22010
|
+
}
|
|
22011
|
+
return CONTINUE;
|
|
22012
|
+
}
|
|
22013
|
+
const tailHash = createHash4("sha256").update(normalizeFailureTail(failure.text, this.tailChars)).digest("hex");
|
|
22014
|
+
const key = `${commandHash}\0${failure.exitCode ?? "x"}\0${tailHash}`;
|
|
22015
|
+
const count = (this.counts.get(key) ?? 0) + 1;
|
|
22016
|
+
this.counts.set(key, count);
|
|
22017
|
+
if (count >= this.stopAfter) {
|
|
22018
|
+
return {
|
|
22019
|
+
action: "stop",
|
|
22020
|
+
reason: `same failure signature (exit ${failure.exitCode ?? "n/a"}) recurred ${count} times after edits`,
|
|
22021
|
+
code: "repeated_failure"
|
|
22022
|
+
};
|
|
22023
|
+
}
|
|
22024
|
+
if (count >= this.warnAfter) {
|
|
22025
|
+
return {
|
|
22026
|
+
action: "inject",
|
|
22027
|
+
message: { role: "user", kind: "runtime-warning", content: REASSESS_MESSAGE2 }
|
|
22028
|
+
};
|
|
22029
|
+
}
|
|
22030
|
+
return CONTINUE;
|
|
22031
|
+
}
|
|
22032
|
+
reset() {
|
|
22033
|
+
this.counts.clear();
|
|
22034
|
+
this.pendingArgs.clear();
|
|
22035
|
+
}
|
|
22036
|
+
};
|
|
22037
|
+
}
|
|
22038
|
+
});
|
|
22039
|
+
|
|
22040
|
+
// packages/core/dist/runtime/guards/DuplicateSearchGuard.js
|
|
22041
|
+
function isSearchTool(tool) {
|
|
22042
|
+
return SEARCH_TOOLS.has(tool);
|
|
22043
|
+
}
|
|
22044
|
+
function normalizeQuery(text) {
|
|
22045
|
+
return text.toLowerCase().replace(/[.,;:!?()"'`—–…]+/g, " ").replace(/\s+/g, " ").trim().slice(0, 512);
|
|
22046
|
+
}
|
|
22047
|
+
function queryJaccard(a, b) {
|
|
22048
|
+
const ta = new Set(a.split(" ").filter(Boolean));
|
|
22049
|
+
const tb = new Set(b.split(" ").filter(Boolean));
|
|
22050
|
+
if (ta.size === 0 && tb.size === 0)
|
|
22051
|
+
return 1;
|
|
22052
|
+
if (ta.size === 0 || tb.size === 0)
|
|
22053
|
+
return 0;
|
|
22054
|
+
let intersection2 = 0;
|
|
22055
|
+
for (const token of ta)
|
|
22056
|
+
if (tb.has(token))
|
|
22057
|
+
intersection2++;
|
|
22058
|
+
const union2 = ta.size + tb.size - intersection2;
|
|
22059
|
+
return union2 === 0 ? 0 : intersection2 / union2;
|
|
22060
|
+
}
|
|
22061
|
+
function extractSearchQuery(toolName, args) {
|
|
22062
|
+
if (!isSearchTool(toolName))
|
|
22063
|
+
return void 0;
|
|
22064
|
+
const a = args ?? {};
|
|
22065
|
+
switch (toolName) {
|
|
22066
|
+
case "grep_content": {
|
|
22067
|
+
if (typeof a.pattern !== "string" || a.pattern.trim() === "")
|
|
22068
|
+
return void 0;
|
|
22069
|
+
const include = Array.isArray(a.include) ? a.include.join(",") : typeof a.include === "string" ? a.include : "";
|
|
22070
|
+
return {
|
|
22071
|
+
scope: [
|
|
22072
|
+
typeof a.path === "string" ? a.path : "",
|
|
22073
|
+
include
|
|
22074
|
+
].join("\0"),
|
|
22075
|
+
query: normalizeQuery(a.pattern)
|
|
22076
|
+
};
|
|
22077
|
+
}
|
|
22078
|
+
case "semantic_search":
|
|
22079
|
+
case "web_search": {
|
|
22080
|
+
if (typeof a.query !== "string" || a.query.trim() === "")
|
|
22081
|
+
return void 0;
|
|
22082
|
+
return { scope: "", query: normalizeQuery(a.query) };
|
|
22083
|
+
}
|
|
22084
|
+
case "list_files": {
|
|
22085
|
+
if (typeof a.path !== "string" || a.path.trim() === "")
|
|
22086
|
+
return void 0;
|
|
22087
|
+
return { scope: String(a.maxDepth ?? ""), query: normalizeQuery(a.path) };
|
|
22088
|
+
}
|
|
22089
|
+
default:
|
|
22090
|
+
return void 0;
|
|
22091
|
+
}
|
|
22092
|
+
}
|
|
22093
|
+
var SEARCH_TOOLS, REFINE_MESSAGE, DuplicateSearchGuard;
|
|
22094
|
+
var init_DuplicateSearchGuard = __esm({
|
|
22095
|
+
"packages/core/dist/runtime/guards/DuplicateSearchGuard.js"() {
|
|
22096
|
+
"use strict";
|
|
22097
|
+
init_types2();
|
|
22098
|
+
SEARCH_TOOLS = /* @__PURE__ */ new Set([
|
|
22099
|
+
"grep_content",
|
|
22100
|
+
"semantic_search",
|
|
22101
|
+
"web_search",
|
|
22102
|
+
"list_files"
|
|
22103
|
+
]);
|
|
22104
|
+
REFINE_MESSAGE = [
|
|
22105
|
+
"Search queries are being repeated with only cosmetic differences in the same scope.",
|
|
22106
|
+
"Reuse the results already in context, or change the query/scope meaningfully."
|
|
22107
|
+
].join("\n");
|
|
22108
|
+
DuplicateSearchGuard = class {
|
|
22109
|
+
buckets = /* @__PURE__ */ new Map();
|
|
22110
|
+
warnAfter;
|
|
22111
|
+
stopAfter;
|
|
22112
|
+
similarityThreshold;
|
|
22113
|
+
window;
|
|
22114
|
+
maxBuckets;
|
|
22115
|
+
constructor(config2 = {}) {
|
|
22116
|
+
this.warnAfter = config2.warnAfter ?? 2;
|
|
22117
|
+
this.stopAfter = config2.stopAfter ?? 5;
|
|
22118
|
+
this.similarityThreshold = config2.similarityThreshold ?? 0.8;
|
|
22119
|
+
this.window = config2.window ?? 8;
|
|
22120
|
+
this.maxBuckets = config2.maxBuckets ?? 256;
|
|
22121
|
+
}
|
|
22122
|
+
async onToolCall(event) {
|
|
22123
|
+
const ref = extractSearchQuery(event.toolName, event.args);
|
|
22124
|
+
if (!ref)
|
|
22125
|
+
return CONTINUE;
|
|
22126
|
+
const key = `${event.toolName}\0${ref.scope}`;
|
|
22127
|
+
let bucket = this.buckets.get(key);
|
|
22128
|
+
if (!bucket) {
|
|
22129
|
+
bucket = { recent: [], duplicateCount: 0 };
|
|
22130
|
+
this.buckets.set(key, bucket);
|
|
22131
|
+
this.evictIfNeeded();
|
|
22132
|
+
}
|
|
22133
|
+
let best = 0;
|
|
22134
|
+
for (const previous of bucket.recent) {
|
|
22135
|
+
best = Math.max(best, queryJaccard(previous, ref.query));
|
|
22136
|
+
}
|
|
22137
|
+
bucket.duplicateCount = best >= this.similarityThreshold ? bucket.duplicateCount + 1 : 1;
|
|
22138
|
+
bucket.recent.push(ref.query);
|
|
22139
|
+
if (bucket.recent.length > this.window)
|
|
22140
|
+
bucket.recent.shift();
|
|
22141
|
+
if (bucket.duplicateCount >= this.stopAfter) {
|
|
22142
|
+
return {
|
|
22143
|
+
action: "stop",
|
|
22144
|
+
reason: `near-duplicate search queries for "${event.toolName}" ${bucket.duplicateCount} times in the same scope`,
|
|
22145
|
+
code: "duplicate_search"
|
|
22146
|
+
};
|
|
22147
|
+
}
|
|
22148
|
+
if (bucket.duplicateCount >= this.warnAfter) {
|
|
22149
|
+
return {
|
|
22150
|
+
action: "inject",
|
|
22151
|
+
message: { role: "user", kind: "runtime-warning", content: REFINE_MESSAGE }
|
|
22152
|
+
};
|
|
22153
|
+
}
|
|
22154
|
+
return CONTINUE;
|
|
22155
|
+
}
|
|
22156
|
+
reset() {
|
|
22157
|
+
this.buckets.clear();
|
|
22158
|
+
}
|
|
22159
|
+
evictIfNeeded() {
|
|
22160
|
+
while (this.buckets.size > this.maxBuckets) {
|
|
22161
|
+
const oldest = this.buckets.keys().next().value;
|
|
22162
|
+
if (oldest === void 0)
|
|
22163
|
+
break;
|
|
22164
|
+
this.buckets.delete(oldest);
|
|
22165
|
+
}
|
|
22166
|
+
}
|
|
22167
|
+
};
|
|
22168
|
+
}
|
|
22169
|
+
});
|
|
22170
|
+
|
|
22171
|
+
// packages/core/dist/runtime/guards/NoProgressGuard.js
|
|
22172
|
+
var FILE_WRITING_TOOLS, REASSESS_MESSAGE3, NoProgressGuard;
|
|
22173
|
+
var init_NoProgressGuard = __esm({
|
|
22174
|
+
"packages/core/dist/runtime/guards/NoProgressGuard.js"() {
|
|
22175
|
+
"use strict";
|
|
22176
|
+
init_types2();
|
|
22177
|
+
init_RepetitionGuard();
|
|
22178
|
+
FILE_WRITING_TOOLS = /* @__PURE__ */ new Set([
|
|
22179
|
+
"write_file",
|
|
22180
|
+
"edit_file",
|
|
22181
|
+
"apply_diff"
|
|
22182
|
+
]);
|
|
22183
|
+
REASSESS_MESSAGE3 = [
|
|
22184
|
+
"The run has made no measurable progress for several turns.",
|
|
22185
|
+
"Change strategy: inspect different files, delegate exploration, or revise the hypothesis."
|
|
22186
|
+
].join("\n");
|
|
22187
|
+
NoProgressGuard = class {
|
|
22188
|
+
seenFingerprints = /* @__PURE__ */ new Set();
|
|
22189
|
+
soft;
|
|
22190
|
+
hard;
|
|
22191
|
+
stallTurns = 0;
|
|
22192
|
+
turnToolCalls = 0;
|
|
22193
|
+
turnWrites = 0;
|
|
22194
|
+
turnNewFingerprints = 0;
|
|
22195
|
+
constructor(config2 = {}) {
|
|
22196
|
+
this.soft = config2.softStallTurns ?? 2;
|
|
22197
|
+
this.hard = config2.hardStallTurns ?? 5;
|
|
22198
|
+
}
|
|
22199
|
+
async onToolCall(event) {
|
|
22200
|
+
this.turnToolCalls += 1;
|
|
22201
|
+
if (FILE_WRITING_TOOLS.has(event.toolName))
|
|
22202
|
+
this.turnWrites += 1;
|
|
22203
|
+
const fingerprint = toolCallFingerprint(event.toolName, event.args);
|
|
22204
|
+
const key = `${fingerprint.tool}\0${fingerprint.argsHash}`;
|
|
22205
|
+
if (!this.seenFingerprints.has(key)) {
|
|
22206
|
+
this.seenFingerprints.add(key);
|
|
22207
|
+
this.turnNewFingerprints += 1;
|
|
22208
|
+
}
|
|
22209
|
+
return CONTINUE;
|
|
22210
|
+
}
|
|
22211
|
+
async onTurnEnd(_event) {
|
|
22212
|
+
if (this.turnToolCalls === 0) {
|
|
22213
|
+
return CONTINUE;
|
|
22214
|
+
}
|
|
22215
|
+
const productive = this.turnWrites > 0 || this.turnNewFingerprints > 0;
|
|
22216
|
+
this.stallTurns = productive ? 0 : this.stallTurns + 1;
|
|
22217
|
+
this.turnToolCalls = 0;
|
|
22218
|
+
this.turnWrites = 0;
|
|
22219
|
+
this.turnNewFingerprints = 0;
|
|
22220
|
+
if (this.stallTurns >= this.hard) {
|
|
22221
|
+
return {
|
|
22222
|
+
action: "stop",
|
|
22223
|
+
reason: `no measurable progress for ${this.stallTurns} consecutive turns`,
|
|
22224
|
+
code: "no_progress"
|
|
22225
|
+
};
|
|
22226
|
+
}
|
|
22227
|
+
if (this.stallTurns >= this.soft) {
|
|
22228
|
+
return {
|
|
22229
|
+
action: "inject",
|
|
22230
|
+
message: { role: "user", kind: "runtime-warning", content: REASSESS_MESSAGE3 }
|
|
22231
|
+
};
|
|
22232
|
+
}
|
|
22233
|
+
return CONTINUE;
|
|
22234
|
+
}
|
|
22235
|
+
reset() {
|
|
22236
|
+
this.seenFingerprints.clear();
|
|
22237
|
+
this.stallTurns = 0;
|
|
22238
|
+
this.turnToolCalls = 0;
|
|
22239
|
+
this.turnWrites = 0;
|
|
22240
|
+
this.turnNewFingerprints = 0;
|
|
22241
|
+
}
|
|
22242
|
+
};
|
|
22243
|
+
}
|
|
22244
|
+
});
|
|
22245
|
+
|
|
22246
|
+
// packages/core/dist/runtime/guards/ReasoningWatchdog.js
|
|
22247
|
+
function envPositiveInt(name, fallback) {
|
|
22248
|
+
const raw = process.env[name]?.trim();
|
|
22249
|
+
if (!raw)
|
|
22250
|
+
return fallback;
|
|
22251
|
+
const parsed = Number.parseInt(raw, 10);
|
|
22252
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
22253
|
+
}
|
|
22254
|
+
var DEFAULT_FIRST_TOKEN_WARN_MS, DEFAULT_STREAM_IDLE_WARN_MS, MAX_COMPLETED, ReasoningWatchdog;
|
|
22255
|
+
var init_ReasoningWatchdog = __esm({
|
|
22256
|
+
"packages/core/dist/runtime/guards/ReasoningWatchdog.js"() {
|
|
22257
|
+
"use strict";
|
|
22258
|
+
init_types2();
|
|
22259
|
+
DEFAULT_FIRST_TOKEN_WARN_MS = 6e4;
|
|
22260
|
+
DEFAULT_STREAM_IDLE_WARN_MS = 3e4;
|
|
22261
|
+
MAX_COMPLETED = 100;
|
|
22262
|
+
ReasoningWatchdog = class {
|
|
22263
|
+
firstTokenWarnMs;
|
|
22264
|
+
streamIdleWarnMs;
|
|
22265
|
+
now;
|
|
22266
|
+
current = null;
|
|
22267
|
+
lastDeltaAt;
|
|
22268
|
+
completed = [];
|
|
22269
|
+
warnings = [];
|
|
22270
|
+
constructor(config2 = {}, now = Date.now) {
|
|
22271
|
+
this.firstTokenWarnMs = config2.firstTokenWarnMs ?? envPositiveInt("ZELARI_MODEL_FIRST_TOKEN_WARN_MS", DEFAULT_FIRST_TOKEN_WARN_MS);
|
|
22272
|
+
this.streamIdleWarnMs = config2.streamIdleWarnMs ?? envPositiveInt("ZELARI_MODEL_STREAM_IDLE_WARN_MS", DEFAULT_STREAM_IDLE_WARN_MS);
|
|
22273
|
+
this.now = now;
|
|
22274
|
+
}
|
|
22275
|
+
async onModelAttempt(event) {
|
|
22276
|
+
this.finalizeCurrent();
|
|
22277
|
+
this.current = {
|
|
22278
|
+
attemptId: event.id,
|
|
22279
|
+
startedAt: this.now(),
|
|
22280
|
+
deltas: 0,
|
|
22281
|
+
warnedFirstToken: false,
|
|
22282
|
+
warnedIdle: false
|
|
22283
|
+
};
|
|
22284
|
+
this.lastDeltaAt = void 0;
|
|
22285
|
+
return CONTINUE;
|
|
22286
|
+
}
|
|
22287
|
+
async onModelDelta(event) {
|
|
22288
|
+
const attempt = this.current;
|
|
22289
|
+
if (!attempt)
|
|
22290
|
+
return CONTINUE;
|
|
22291
|
+
const at = this.now();
|
|
22292
|
+
attempt.deltas += 1;
|
|
22293
|
+
if (attempt.firstTokenAt === void 0) {
|
|
22294
|
+
attempt.firstTokenAt = at;
|
|
22295
|
+
const ttft = at - attempt.startedAt;
|
|
22296
|
+
attempt.timeToFirstTokenMs = ttft;
|
|
22297
|
+
if (!attempt.warnedFirstToken && ttft > this.firstTokenWarnMs) {
|
|
22298
|
+
attempt.warnedFirstToken = true;
|
|
22299
|
+
this.warn("time_to_first_token", attempt, ttft, this.firstTokenWarnMs);
|
|
22300
|
+
}
|
|
22301
|
+
} else {
|
|
22302
|
+
const gap = at - (this.lastDeltaAt ?? attempt.firstTokenAt);
|
|
22303
|
+
if (gap > (attempt.maxStreamIdleMs ?? 0))
|
|
22304
|
+
attempt.maxStreamIdleMs = gap;
|
|
22305
|
+
if (!attempt.warnedIdle && gap > this.streamIdleWarnMs) {
|
|
22306
|
+
attempt.warnedIdle = true;
|
|
22307
|
+
this.warn("stream_idle", attempt, gap, this.streamIdleWarnMs);
|
|
22308
|
+
}
|
|
22309
|
+
}
|
|
22310
|
+
this.lastDeltaAt = at;
|
|
22311
|
+
return CONTINUE;
|
|
22312
|
+
}
|
|
22313
|
+
async onModelResponse(_event) {
|
|
22314
|
+
this.finalizeCurrent();
|
|
22315
|
+
return CONTINUE;
|
|
22316
|
+
}
|
|
22317
|
+
async onRunEnd(_event) {
|
|
22318
|
+
this.finalizeCurrent();
|
|
22319
|
+
return CONTINUE;
|
|
22320
|
+
}
|
|
22321
|
+
async onCancelled(_event) {
|
|
22322
|
+
this.finalizeCurrent();
|
|
22323
|
+
return CONTINUE;
|
|
22324
|
+
}
|
|
22325
|
+
/** Completed attempt metrics, oldest first (bounded). */
|
|
22326
|
+
getAttemptMetrics() {
|
|
22327
|
+
return this.completed.map((attempt) => ({ ...attempt }));
|
|
22328
|
+
}
|
|
22329
|
+
getWarnings() {
|
|
22330
|
+
return this.warnings.map((warning) => ({ ...warning }));
|
|
22331
|
+
}
|
|
22332
|
+
reset() {
|
|
22333
|
+
this.current = null;
|
|
22334
|
+
this.lastDeltaAt = void 0;
|
|
22335
|
+
this.completed.length = 0;
|
|
22336
|
+
this.warnings.length = 0;
|
|
22337
|
+
}
|
|
22338
|
+
finalizeCurrent() {
|
|
22339
|
+
const attempt = this.current;
|
|
22340
|
+
if (!attempt)
|
|
22341
|
+
return;
|
|
22342
|
+
attempt.endedAt = this.now();
|
|
22343
|
+
if (attempt.firstTokenAt !== void 0) {
|
|
22344
|
+
attempt.generationDurationMs = attempt.endedAt - attempt.startedAt;
|
|
22345
|
+
}
|
|
22346
|
+
this.completed.push({ ...attempt });
|
|
22347
|
+
if (this.completed.length > MAX_COMPLETED)
|
|
22348
|
+
this.completed.shift();
|
|
22349
|
+
this.current = null;
|
|
22350
|
+
this.lastDeltaAt = void 0;
|
|
22351
|
+
}
|
|
22352
|
+
warn(metric, attempt, valueMs, thresholdMs) {
|
|
22353
|
+
this.warnings.push({
|
|
22354
|
+
code: "provider_idle",
|
|
22355
|
+
metric,
|
|
22356
|
+
attemptId: attempt.attemptId,
|
|
22357
|
+
valueMs,
|
|
22358
|
+
thresholdMs,
|
|
22359
|
+
message: metric === "time_to_first_token" ? `Provider first token took ${valueMs}ms (threshold ${thresholdMs}ms).` : `Provider stream idle for ${valueMs}ms between deltas (threshold ${thresholdMs}ms).`,
|
|
22360
|
+
ts: this.now()
|
|
22361
|
+
});
|
|
22362
|
+
}
|
|
22363
|
+
};
|
|
22364
|
+
}
|
|
22365
|
+
});
|
|
22366
|
+
|
|
22367
|
+
// packages/core/dist/runtime/observers/TraceObserver.js
|
|
22368
|
+
var DEFAULT_CAPACITY, TraceObserver;
|
|
22369
|
+
var init_TraceObserver = __esm({
|
|
22370
|
+
"packages/core/dist/runtime/observers/TraceObserver.js"() {
|
|
22371
|
+
"use strict";
|
|
22372
|
+
init_types2();
|
|
22373
|
+
DEFAULT_CAPACITY = 500;
|
|
22374
|
+
TraceObserver = class {
|
|
22375
|
+
entries = [];
|
|
22376
|
+
sink;
|
|
22377
|
+
capacity;
|
|
22378
|
+
constructor(options = {}) {
|
|
22379
|
+
this.sink = options.sink;
|
|
22380
|
+
this.capacity = Math.max(1, options.capacity ?? DEFAULT_CAPACITY);
|
|
22381
|
+
}
|
|
22382
|
+
async onRunStart(event) {
|
|
22383
|
+
return this.record("onRunStart", event);
|
|
22384
|
+
}
|
|
22385
|
+
async onModelAttempt(event) {
|
|
22386
|
+
return this.record("onModelAttempt", event);
|
|
22387
|
+
}
|
|
22388
|
+
async onModelDelta(event) {
|
|
22389
|
+
return this.record("onModelDelta", event);
|
|
22390
|
+
}
|
|
22391
|
+
async onModelResponse(event) {
|
|
22392
|
+
return this.record("onModelResponse", event);
|
|
22393
|
+
}
|
|
22394
|
+
async onToolCall(event) {
|
|
22395
|
+
return this.record("onToolCall", event);
|
|
22396
|
+
}
|
|
22397
|
+
async onToolResult(event) {
|
|
22398
|
+
return this.record("onToolResult", event);
|
|
22399
|
+
}
|
|
22400
|
+
async onTurnEnd(event) {
|
|
22401
|
+
return this.record("onTurnEnd", event);
|
|
22402
|
+
}
|
|
22403
|
+
async onRunEnd(event) {
|
|
22404
|
+
return this.record("onRunEnd", event);
|
|
22405
|
+
}
|
|
22406
|
+
async onCancelled(event) {
|
|
22407
|
+
return this.record("onCancelled", event);
|
|
22408
|
+
}
|
|
22409
|
+
/** Recorded entries, oldest first. */
|
|
22410
|
+
getEntries() {
|
|
22411
|
+
return [...this.entries];
|
|
22412
|
+
}
|
|
22413
|
+
get size() {
|
|
22414
|
+
return this.entries.length;
|
|
22415
|
+
}
|
|
22416
|
+
clear() {
|
|
22417
|
+
this.entries.length = 0;
|
|
22418
|
+
}
|
|
22419
|
+
record(hook, event) {
|
|
22420
|
+
const entry = {
|
|
22421
|
+
hook,
|
|
22422
|
+
eventId: event.id,
|
|
22423
|
+
ts: event.ts,
|
|
22424
|
+
agentId: event.identity.agentId,
|
|
22425
|
+
role: event.identity.role,
|
|
22426
|
+
turn: event.turn
|
|
22427
|
+
};
|
|
22428
|
+
this.entries.push(entry);
|
|
22429
|
+
if (this.entries.length > this.capacity)
|
|
22430
|
+
this.entries.shift();
|
|
22431
|
+
try {
|
|
22432
|
+
this.sink?.(entry);
|
|
22433
|
+
} catch {
|
|
22434
|
+
}
|
|
22435
|
+
return CONTINUE;
|
|
22436
|
+
}
|
|
22437
|
+
};
|
|
22438
|
+
}
|
|
22439
|
+
});
|
|
22440
|
+
|
|
22441
|
+
// packages/core/dist/runtime/observers/MetricsObserver.js
|
|
22442
|
+
var MetricsObserver;
|
|
22443
|
+
var init_MetricsObserver = __esm({
|
|
22444
|
+
"packages/core/dist/runtime/observers/MetricsObserver.js"() {
|
|
22445
|
+
"use strict";
|
|
22446
|
+
init_types2();
|
|
22447
|
+
MetricsObserver = class {
|
|
22448
|
+
runsStarted = 0;
|
|
22449
|
+
modelAttempts = 0;
|
|
22450
|
+
modelDeltas = 0;
|
|
22451
|
+
modelResponses = 0;
|
|
22452
|
+
toolCalls = 0;
|
|
22453
|
+
toolResults = 0;
|
|
22454
|
+
toolFailures = 0;
|
|
22455
|
+
turnsEnded = 0;
|
|
22456
|
+
runsEnded = 0;
|
|
22457
|
+
cancelled = 0;
|
|
22458
|
+
firstEventTs;
|
|
22459
|
+
lastEventTs;
|
|
22460
|
+
async onRunStart(event) {
|
|
22461
|
+
this.tick(event.ts);
|
|
22462
|
+
this.runsStarted += 1;
|
|
22463
|
+
return CONTINUE;
|
|
22464
|
+
}
|
|
22465
|
+
async onModelAttempt(event) {
|
|
22466
|
+
this.tick(event.ts);
|
|
22467
|
+
this.modelAttempts += 1;
|
|
22468
|
+
return CONTINUE;
|
|
22469
|
+
}
|
|
22470
|
+
async onModelDelta(event) {
|
|
22471
|
+
this.tick(event.ts);
|
|
22472
|
+
this.modelDeltas += 1;
|
|
22473
|
+
return CONTINUE;
|
|
22474
|
+
}
|
|
22475
|
+
async onModelResponse(event) {
|
|
22476
|
+
this.tick(event.ts);
|
|
22477
|
+
this.modelResponses += 1;
|
|
22478
|
+
return CONTINUE;
|
|
22479
|
+
}
|
|
22480
|
+
async onToolCall(event) {
|
|
22481
|
+
this.tick(event.ts);
|
|
22482
|
+
this.toolCalls += 1;
|
|
22483
|
+
return CONTINUE;
|
|
22484
|
+
}
|
|
22485
|
+
async onToolResult(event) {
|
|
22486
|
+
this.tick(event.ts);
|
|
22487
|
+
this.toolResults += 1;
|
|
22488
|
+
if (!event.ok)
|
|
22489
|
+
this.toolFailures += 1;
|
|
22490
|
+
return CONTINUE;
|
|
22491
|
+
}
|
|
22492
|
+
async onTurnEnd(event) {
|
|
22493
|
+
this.tick(event.ts);
|
|
22494
|
+
this.turnsEnded += 1;
|
|
22495
|
+
return CONTINUE;
|
|
22496
|
+
}
|
|
22497
|
+
async onRunEnd(event) {
|
|
22498
|
+
this.tick(event.ts);
|
|
22499
|
+
this.runsEnded += 1;
|
|
22500
|
+
return CONTINUE;
|
|
22501
|
+
}
|
|
22502
|
+
async onCancelled(event) {
|
|
22503
|
+
this.tick(event.ts);
|
|
22504
|
+
this.cancelled += 1;
|
|
22505
|
+
return CONTINUE;
|
|
22506
|
+
}
|
|
22507
|
+
snapshot() {
|
|
22508
|
+
return {
|
|
22509
|
+
runsStarted: this.runsStarted,
|
|
22510
|
+
modelAttempts: this.modelAttempts,
|
|
22511
|
+
modelDeltas: this.modelDeltas,
|
|
22512
|
+
modelResponses: this.modelResponses,
|
|
22513
|
+
toolCalls: this.toolCalls,
|
|
22514
|
+
toolResults: this.toolResults,
|
|
22515
|
+
toolFailures: this.toolFailures,
|
|
22516
|
+
turnsEnded: this.turnsEnded,
|
|
22517
|
+
runsEnded: this.runsEnded,
|
|
22518
|
+
cancelled: this.cancelled,
|
|
22519
|
+
firstEventTs: this.firstEventTs,
|
|
22520
|
+
lastEventTs: this.lastEventTs
|
|
22521
|
+
};
|
|
22522
|
+
}
|
|
22523
|
+
reset() {
|
|
22524
|
+
this.runsStarted = 0;
|
|
22525
|
+
this.modelAttempts = 0;
|
|
22526
|
+
this.modelDeltas = 0;
|
|
22527
|
+
this.modelResponses = 0;
|
|
22528
|
+
this.toolCalls = 0;
|
|
22529
|
+
this.toolResults = 0;
|
|
22530
|
+
this.toolFailures = 0;
|
|
22531
|
+
this.turnsEnded = 0;
|
|
22532
|
+
this.runsEnded = 0;
|
|
22533
|
+
this.cancelled = 0;
|
|
22534
|
+
this.firstEventTs = void 0;
|
|
22535
|
+
this.lastEventTs = void 0;
|
|
22536
|
+
}
|
|
22537
|
+
tick(ts) {
|
|
22538
|
+
if (this.firstEventTs === void 0 || ts < this.firstEventTs) {
|
|
22539
|
+
this.firstEventTs = ts;
|
|
22540
|
+
}
|
|
22541
|
+
if (this.lastEventTs === void 0 || ts > this.lastEventTs) {
|
|
22542
|
+
this.lastEventTs = ts;
|
|
22543
|
+
}
|
|
22544
|
+
}
|
|
22545
|
+
};
|
|
22546
|
+
}
|
|
22547
|
+
});
|
|
22548
|
+
|
|
22549
|
+
// packages/core/dist/runtime/recorder/Redactor.js
|
|
22550
|
+
function redactString(input) {
|
|
22551
|
+
let out = input;
|
|
22552
|
+
for (const { re, replacement } of VALUE_PATTERNS) {
|
|
22553
|
+
out = out.replace(re, replacement);
|
|
22554
|
+
}
|
|
22555
|
+
return out;
|
|
22556
|
+
}
|
|
22557
|
+
function redactRuntimePayload(value) {
|
|
22558
|
+
if (value === null || value === void 0)
|
|
22559
|
+
return value;
|
|
22560
|
+
if (typeof value === "string")
|
|
22561
|
+
return redactString(value);
|
|
22562
|
+
if (typeof value === "number" || typeof value === "boolean")
|
|
22563
|
+
return value;
|
|
22564
|
+
if (Array.isArray(value))
|
|
22565
|
+
return value.map((item) => redactRuntimePayload(item));
|
|
22566
|
+
if (typeof value === "object") {
|
|
22567
|
+
const out = {};
|
|
22568
|
+
for (const [key, val] of Object.entries(value)) {
|
|
22569
|
+
out[key] = SECRET_KEY_RE.test(key) ? REDACTED : redactRuntimePayload(val);
|
|
22570
|
+
}
|
|
22571
|
+
return out;
|
|
22572
|
+
}
|
|
22573
|
+
return REDACTED;
|
|
22574
|
+
}
|
|
22575
|
+
var REDACTED, SECRET_KEY_RE, VALUE_PATTERNS;
|
|
22576
|
+
var init_Redactor = __esm({
|
|
22577
|
+
"packages/core/dist/runtime/recorder/Redactor.js"() {
|
|
22578
|
+
"use strict";
|
|
22579
|
+
REDACTED = "[REDACTED]";
|
|
22580
|
+
SECRET_KEY_RE = /(pass(word|wd)?|secret|token|api[-_]?key|auth(orization)?|credential|private[-_]?key|access[-_]?key)/i;
|
|
22581
|
+
VALUE_PATTERNS = [
|
|
22582
|
+
// "Authorization: <credential>" (with optional bearer/Basic scheme prefix) — whole value.
|
|
22583
|
+
// Value class excludes [ ] so the [REDACTED] marker can never be re-matched.
|
|
22584
|
+
{
|
|
22585
|
+
re: /\b(authorization\s*[:=]\s*)(?:bearer|basic|token)\s+[^\s,;"'}\]\[]+/gi,
|
|
22586
|
+
replacement: "$1[REDACTED]"
|
|
22587
|
+
},
|
|
22588
|
+
{
|
|
22589
|
+
re: /\b(authorization\s*[:=]\s*)[^\s,;"'}\]\[]+/gi,
|
|
22590
|
+
replacement: "$1[REDACTED]"
|
|
22591
|
+
},
|
|
22592
|
+
// Bare bearer schemes anywhere ("bearer <token>", any casing)
|
|
22593
|
+
{ re: /\bbearer\s+[A-Za-z0-9\-._~+/]+=*/gi, replacement: "bearer [REDACTED]" },
|
|
22594
|
+
// OpenAI-style keys (sk-, sk-proj-)
|
|
22595
|
+
{ re: /\bsk-(proj-)?[A-Za-z0-9_-]{8,}\b/g, replacement: "sk-[REDACTED]" },
|
|
22596
|
+
// GitHub tokens
|
|
22597
|
+
{
|
|
22598
|
+
re: /\b(ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{20,}\b/g,
|
|
22599
|
+
replacement: "[REDACTED]"
|
|
22600
|
+
},
|
|
22601
|
+
{ re: /\bgithub_pat_[A-Za-z0-9_]{20,}\b/g, replacement: "[REDACTED]" },
|
|
22602
|
+
// Slack
|
|
22603
|
+
{ re: /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g, replacement: "[REDACTED]" },
|
|
22604
|
+
// AWS access keys
|
|
22605
|
+
{ re: /\bAKIA[0-9A-Z]{16}\b/g, replacement: "[REDACTED]" },
|
|
22606
|
+
// Google OAuth
|
|
22607
|
+
{ re: /\bya29\.[A-Za-z0-9\-_.]+/g, replacement: "[REDACTED]" },
|
|
22608
|
+
// Secret-looking assignments, UPPER_SNAKE or lower: FOO_PASSWORD=x, password: x
|
|
22609
|
+
{
|
|
22610
|
+
re: /\b([A-Za-z0-9_]*(?:password|passwd|secret|token|api[_-]?key|apikey|access[_-]?key|private[_-]?key)[A-Za-z0-9_]*)\s*[:=]\s*("[^"]*"|'[^']*'|[^\s,;}&\]]+)/gi,
|
|
22611
|
+
replacement: "$1=[REDACTED]"
|
|
22612
|
+
}
|
|
22613
|
+
];
|
|
22614
|
+
}
|
|
22615
|
+
});
|
|
22616
|
+
|
|
22617
|
+
// packages/core/dist/runtime/recorder/RunRecorder.js
|
|
22618
|
+
import { appendFile, mkdir, writeFile } from "node:fs/promises";
|
|
22619
|
+
import { join } from "node:path";
|
|
22620
|
+
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
22621
|
+
function newRunId(now = Date.now) {
|
|
22622
|
+
return `run_${now().toString(36)}_${randomBytes2(4).toString("hex")}`;
|
|
22623
|
+
}
|
|
22624
|
+
function runRecordEnabled() {
|
|
22625
|
+
const raw = process.env.ZELARI_RUN_RECORD?.trim().toLowerCase();
|
|
22626
|
+
return raw === "1" || raw === "true" || raw === "on";
|
|
22627
|
+
}
|
|
22628
|
+
function sanitizeAgentId(agentId) {
|
|
22629
|
+
const safe = agentId.replace(/[^a-zA-Z0-9._-]/g, "-").slice(0, 64);
|
|
22630
|
+
return safe.length > 0 ? safe : "agent";
|
|
22631
|
+
}
|
|
22632
|
+
var RunRecorder;
|
|
22633
|
+
var init_RunRecorder = __esm({
|
|
22634
|
+
"packages/core/dist/runtime/recorder/RunRecorder.js"() {
|
|
22635
|
+
"use strict";
|
|
22636
|
+
init_Redactor();
|
|
22637
|
+
RunRecorder = class {
|
|
22638
|
+
runId;
|
|
22639
|
+
runDir;
|
|
22640
|
+
opts;
|
|
22641
|
+
now;
|
|
22642
|
+
chain = Promise.resolve();
|
|
22643
|
+
startedAt = 0;
|
|
22644
|
+
started = false;
|
|
22645
|
+
finalized = false;
|
|
22646
|
+
models;
|
|
22647
|
+
counters = { modelCalls: 0, toolCalls: 0, toolFailures: 0, turns: 0 };
|
|
22648
|
+
constructor(options) {
|
|
22649
|
+
this.opts = options;
|
|
22650
|
+
this.now = options.now ?? Date.now;
|
|
22651
|
+
this.runId = options.runId ?? newRunId(this.now);
|
|
22652
|
+
this.runDir = join(options.runsDir, this.runId);
|
|
22653
|
+
this.models = { ...options.models ?? {} };
|
|
22654
|
+
}
|
|
22655
|
+
/** Create the run dir and write the initial manifest. Idempotent. */
|
|
22656
|
+
start() {
|
|
22657
|
+
if (this.started)
|
|
22658
|
+
return;
|
|
22659
|
+
this.started = true;
|
|
22660
|
+
this.startedAt = this.now();
|
|
22661
|
+
this.enqueue(async () => {
|
|
22662
|
+
await mkdir(this.runDir, { recursive: true });
|
|
22663
|
+
await mkdir(join(this.runDir, "agents"), { recursive: true });
|
|
22664
|
+
await writeFile(join(this.runDir, "manifest.json"), JSON.stringify(this.buildManifest("running"), null, 2));
|
|
22665
|
+
});
|
|
22666
|
+
}
|
|
22667
|
+
/** Append one redacted event to trace.jsonl. */
|
|
22668
|
+
record(event) {
|
|
22669
|
+
if (!this.started)
|
|
22670
|
+
this.start();
|
|
22671
|
+
this.enqueue(() => appendFile(join(this.runDir, "trace.jsonl"), `${JSON.stringify(redactRuntimePayload(event))}
|
|
22672
|
+
`));
|
|
22673
|
+
}
|
|
22674
|
+
/** Append one redacted event to the per-agent stream. */
|
|
22675
|
+
recordAgent(agentId, event) {
|
|
22676
|
+
if (!this.started)
|
|
22677
|
+
this.start();
|
|
22678
|
+
this.enqueue(() => appendFile(join(this.runDir, "agents", `${sanitizeAgentId(agentId)}.jsonl`), `${JSON.stringify(redactRuntimePayload(event))}
|
|
22679
|
+
`));
|
|
22680
|
+
}
|
|
22681
|
+
/** Track which model served which role, for the final manifest. */
|
|
22682
|
+
noteModel(role, model) {
|
|
22683
|
+
if (role && model)
|
|
22684
|
+
this.models[role] = model;
|
|
22685
|
+
}
|
|
22686
|
+
bumpModelCall() {
|
|
22687
|
+
this.counters.modelCalls += 1;
|
|
22688
|
+
}
|
|
22689
|
+
bumpToolCall() {
|
|
22690
|
+
this.counters.toolCalls += 1;
|
|
22691
|
+
}
|
|
22692
|
+
bumpToolFailure() {
|
|
22693
|
+
this.counters.toolFailures += 1;
|
|
22694
|
+
}
|
|
22695
|
+
bumpTurn() {
|
|
22696
|
+
this.counters.turns += 1;
|
|
22697
|
+
}
|
|
22698
|
+
getMetrics() {
|
|
22699
|
+
return {
|
|
22700
|
+
durationMs: this.finalized || this.startedAt > 0 ? Math.max(0, this.now() - this.startedAt) : 0,
|
|
22701
|
+
...this.counters
|
|
22702
|
+
};
|
|
22703
|
+
}
|
|
22704
|
+
/** Write final manifest + metrics.json. Idempotent. */
|
|
22705
|
+
finalize(status) {
|
|
22706
|
+
if (this.finalized)
|
|
22707
|
+
return;
|
|
22708
|
+
if (!this.started)
|
|
22709
|
+
this.start();
|
|
22710
|
+
this.finalized = true;
|
|
22711
|
+
const endedAt = this.now();
|
|
22712
|
+
this.enqueue(async () => {
|
|
22713
|
+
await writeFile(join(this.runDir, "manifest.json"), JSON.stringify(this.buildManifest(status, endedAt), null, 2));
|
|
22714
|
+
await writeFile(join(this.runDir, "metrics.json"), JSON.stringify(this.getMetrics(), null, 2));
|
|
22715
|
+
});
|
|
22716
|
+
}
|
|
22717
|
+
/** Await pending writes (tests / graceful shutdown). */
|
|
22718
|
+
async flush() {
|
|
22719
|
+
await this.chain;
|
|
22720
|
+
}
|
|
22721
|
+
buildManifest(status, endedAt) {
|
|
22722
|
+
return {
|
|
22723
|
+
version: 1,
|
|
22724
|
+
runId: this.runId,
|
|
22725
|
+
sessionId: this.opts.sessionId,
|
|
22726
|
+
mode: this.opts.mode ?? "kraken",
|
|
22727
|
+
phase: this.opts.phase ?? "build",
|
|
22728
|
+
startedAt: this.startedAt,
|
|
22729
|
+
...endedAt !== void 0 ? { endedAt } : {},
|
|
22730
|
+
status,
|
|
22731
|
+
cwd: this.opts.cwd ?? process.cwd(),
|
|
22732
|
+
models: this.models
|
|
22733
|
+
};
|
|
22734
|
+
}
|
|
22735
|
+
/**
|
|
22736
|
+
* Serial best-effort write queue: preserves trace ordering and swallows
|
|
22737
|
+
* IO errors (§102 — recorder failure must not block the run).
|
|
22738
|
+
*/
|
|
22739
|
+
enqueue(write) {
|
|
22740
|
+
this.chain = this.chain.then(write).catch(() => {
|
|
22741
|
+
});
|
|
22742
|
+
}
|
|
22743
|
+
};
|
|
22744
|
+
}
|
|
22745
|
+
});
|
|
22746
|
+
|
|
22747
|
+
// packages/core/dist/runtime/recorder/recorderObserver.js
|
|
22748
|
+
function base(event) {
|
|
22749
|
+
return {
|
|
22750
|
+
id: event.id,
|
|
22751
|
+
ts: event.ts,
|
|
22752
|
+
turn: event.turn,
|
|
22753
|
+
agentId: event.identity.agentId,
|
|
22754
|
+
role: event.identity.role
|
|
22755
|
+
};
|
|
22756
|
+
}
|
|
22757
|
+
function createRecorderObserver(recorder) {
|
|
22758
|
+
return {
|
|
22759
|
+
onRunStart(event) {
|
|
22760
|
+
recorder.noteModel(event.identity.role, event.identity.model);
|
|
22761
|
+
recorder.start();
|
|
22762
|
+
recorder.record({ type: "run_start", ...base(event) });
|
|
22763
|
+
return CONTINUE;
|
|
22764
|
+
},
|
|
22765
|
+
onModelAttempt(event) {
|
|
22766
|
+
recorder.bumpModelCall();
|
|
22767
|
+
recorder.record({ type: "model_attempt", ...base(event) });
|
|
22768
|
+
return CONTINUE;
|
|
22769
|
+
},
|
|
22770
|
+
onModelResponse(event) {
|
|
22771
|
+
recorder.record({ type: "model_response", ...base(event) });
|
|
22772
|
+
return CONTINUE;
|
|
22773
|
+
},
|
|
22774
|
+
onToolCall(event) {
|
|
22775
|
+
recorder.bumpToolCall();
|
|
22776
|
+
recorder.record({ type: "tool_call", ...base(event), toolCallId: event.toolCallId, tool: event.toolName });
|
|
22777
|
+
return CONTINUE;
|
|
22778
|
+
},
|
|
22779
|
+
onToolResult(event) {
|
|
22780
|
+
if (!event.ok)
|
|
22781
|
+
recorder.bumpToolFailure();
|
|
22782
|
+
const line = { type: "tool_result", ...base(event), toolCallId: event.toolCallId, tool: event.toolName, ok: event.ok };
|
|
22783
|
+
recorder.record(line);
|
|
22784
|
+
recorder.recordAgent(event.identity.agentId, line);
|
|
22785
|
+
return CONTINUE;
|
|
22786
|
+
},
|
|
22787
|
+
onTurnEnd(event) {
|
|
22788
|
+
recorder.bumpTurn();
|
|
22789
|
+
recorder.record({ type: "turn_end", ...base(event) });
|
|
22790
|
+
return CONTINUE;
|
|
22791
|
+
},
|
|
22792
|
+
onRunEnd(event) {
|
|
22793
|
+
recorder.record({ type: "run_end", ...base(event), reason: event.reason });
|
|
22794
|
+
recorder.finalize(event.reason === "completed" ? "completed" : event.reason === "cancelled" ? "cancelled" : "failed");
|
|
22795
|
+
return CONTINUE;
|
|
22796
|
+
},
|
|
22797
|
+
onCancelled(event) {
|
|
22798
|
+
recorder.record({ type: "run_cancelled", ...base(event), reason: event.reason });
|
|
22799
|
+
recorder.finalize("cancelled");
|
|
22800
|
+
return CONTINUE;
|
|
22801
|
+
}
|
|
22802
|
+
};
|
|
22803
|
+
}
|
|
22804
|
+
var init_recorderObserver = __esm({
|
|
22805
|
+
"packages/core/dist/runtime/recorder/recorderObserver.js"() {
|
|
22806
|
+
"use strict";
|
|
22807
|
+
init_types2();
|
|
22808
|
+
}
|
|
22809
|
+
});
|
|
22810
|
+
|
|
22811
|
+
// packages/core/dist/runtime/controls/SteeringObserver.js
|
|
22812
|
+
function renderSteers(steers) {
|
|
22813
|
+
const lines = ["Runtime user steering received during execution:", ""];
|
|
22814
|
+
steers.forEach((steer, index) => {
|
|
22815
|
+
lines.push(`[${index + 1}]`);
|
|
22816
|
+
lines.push(steer.text);
|
|
22817
|
+
lines.push("");
|
|
22818
|
+
});
|
|
22819
|
+
lines.push("Later instructions may supersede earlier ones.");
|
|
22820
|
+
return lines.join("\n");
|
|
22821
|
+
}
|
|
22822
|
+
var SteeringObserver;
|
|
22823
|
+
var init_SteeringObserver = __esm({
|
|
22824
|
+
"packages/core/dist/runtime/controls/SteeringObserver.js"() {
|
|
22825
|
+
"use strict";
|
|
22826
|
+
init_types2();
|
|
22827
|
+
SteeringObserver = class {
|
|
22828
|
+
queue;
|
|
22829
|
+
constructor(queue) {
|
|
22830
|
+
this.queue = queue;
|
|
22831
|
+
}
|
|
22832
|
+
async onTurnEnd(_event) {
|
|
22833
|
+
const steers = this.queue.drainSteers();
|
|
22834
|
+
if (steers.length === 0) {
|
|
22835
|
+
return CONTINUE;
|
|
22836
|
+
}
|
|
22837
|
+
return {
|
|
22838
|
+
action: "inject",
|
|
22839
|
+
message: {
|
|
22840
|
+
role: "user",
|
|
22841
|
+
kind: "runtime-steer",
|
|
22842
|
+
content: renderSteers(steers)
|
|
22843
|
+
}
|
|
22844
|
+
};
|
|
22845
|
+
}
|
|
22846
|
+
};
|
|
22847
|
+
}
|
|
22848
|
+
});
|
|
22849
|
+
|
|
22850
|
+
// packages/core/dist/runtime/observers/ObserverBus.js
|
|
22851
|
+
import { join as join2 } from "node:path";
|
|
22852
|
+
function runtimeObserversEnabled() {
|
|
22853
|
+
const raw = process.env.ZELARI_RUNTIME_OBSERVERS?.trim().toLowerCase();
|
|
22854
|
+
return raw === "1" || raw === "true" || raw === "on";
|
|
22855
|
+
}
|
|
22856
|
+
function buildRuntimeObserverBus(options = {}) {
|
|
22857
|
+
const steering = options.steeringQueue ? [
|
|
22858
|
+
{
|
|
22859
|
+
id: "steering-observer",
|
|
22860
|
+
priority: 20,
|
|
22861
|
+
failureMode: "warn",
|
|
22862
|
+
observer: new SteeringObserver(options.steeringQueue)
|
|
22863
|
+
}
|
|
22864
|
+
] : [];
|
|
22865
|
+
if (!runtimeObserversEnabled()) {
|
|
22866
|
+
return steering.length > 0 ? new ObserverBus(steering) : void 0;
|
|
22867
|
+
}
|
|
22868
|
+
const descriptors = [
|
|
22869
|
+
...steering,
|
|
22870
|
+
{
|
|
22871
|
+
id: "repetition-guard",
|
|
22872
|
+
priority: 30,
|
|
22873
|
+
failureMode: "warn",
|
|
22874
|
+
observer: new RepetitionGuard()
|
|
22875
|
+
},
|
|
22876
|
+
{
|
|
22877
|
+
id: "failure-signature-guard",
|
|
22878
|
+
priority: 30,
|
|
22879
|
+
failureMode: "warn",
|
|
22880
|
+
observer: new FailureSignatureGuard()
|
|
22881
|
+
},
|
|
22882
|
+
{
|
|
22883
|
+
id: "duplicate-search-guard",
|
|
22884
|
+
priority: 30,
|
|
22885
|
+
failureMode: "warn",
|
|
22886
|
+
observer: new DuplicateSearchGuard()
|
|
22887
|
+
},
|
|
22888
|
+
{
|
|
22889
|
+
id: "no-progress-guard",
|
|
22890
|
+
priority: 30,
|
|
22891
|
+
failureMode: "warn",
|
|
22892
|
+
observer: new NoProgressGuard()
|
|
22893
|
+
},
|
|
22894
|
+
{
|
|
22895
|
+
id: "reasoning-watchdog",
|
|
22896
|
+
priority: 30,
|
|
22897
|
+
failureMode: "warn",
|
|
22898
|
+
observer: new ReasoningWatchdog()
|
|
22899
|
+
},
|
|
22900
|
+
{
|
|
22901
|
+
id: "trace-observer",
|
|
22902
|
+
priority: 80,
|
|
22903
|
+
failureMode: "warn",
|
|
22904
|
+
observer: new TraceObserver()
|
|
22905
|
+
},
|
|
22906
|
+
{
|
|
22907
|
+
id: "metrics-observer",
|
|
22908
|
+
priority: 90,
|
|
22909
|
+
failureMode: "ignore",
|
|
22910
|
+
observer: new MetricsObserver()
|
|
22911
|
+
}
|
|
22912
|
+
];
|
|
22913
|
+
if (runRecordEnabled()) {
|
|
22914
|
+
const recorder = new RunRecorder({
|
|
22915
|
+
runsDir: options.runsDir ?? join2(process.cwd(), ".zelari", "runs"),
|
|
22916
|
+
runId: options.runId ?? newRunId()
|
|
22917
|
+
});
|
|
22918
|
+
descriptors.push({
|
|
22919
|
+
id: "run-recorder",
|
|
22920
|
+
priority: 85,
|
|
22921
|
+
failureMode: "warn",
|
|
22922
|
+
observer: createRecorderObserver(recorder)
|
|
22923
|
+
});
|
|
22924
|
+
}
|
|
22925
|
+
return new ObserverBus(descriptors);
|
|
22926
|
+
}
|
|
22927
|
+
var ObserverBus;
|
|
22928
|
+
var init_ObserverBus = __esm({
|
|
22929
|
+
"packages/core/dist/runtime/observers/ObserverBus.js"() {
|
|
22930
|
+
"use strict";
|
|
22931
|
+
init_types2();
|
|
22932
|
+
init_resolve();
|
|
22933
|
+
init_RepetitionGuard();
|
|
22934
|
+
init_FailureSignatureGuard();
|
|
22935
|
+
init_DuplicateSearchGuard();
|
|
22936
|
+
init_NoProgressGuard();
|
|
22937
|
+
init_ReasoningWatchdog();
|
|
22938
|
+
init_TraceObserver();
|
|
22939
|
+
init_MetricsObserver();
|
|
22940
|
+
init_RunRecorder();
|
|
22941
|
+
init_recorderObserver();
|
|
22942
|
+
init_SteeringObserver();
|
|
22943
|
+
ObserverBus = class {
|
|
22944
|
+
descriptors;
|
|
22945
|
+
logger;
|
|
22946
|
+
constructor(descriptors = [], options = {}) {
|
|
22947
|
+
this.descriptors = [...descriptors].sort((a, b) => a.priority - b.priority);
|
|
22948
|
+
this.logger = options.logger ?? (() => {
|
|
22949
|
+
});
|
|
22950
|
+
}
|
|
22951
|
+
get size() {
|
|
22952
|
+
return this.descriptors.length;
|
|
22953
|
+
}
|
|
22954
|
+
async emit(hook, event) {
|
|
22955
|
+
const results = [];
|
|
22956
|
+
for (const descriptor of this.descriptors) {
|
|
22957
|
+
const callback = descriptor.observer[hook];
|
|
22958
|
+
if (typeof callback !== "function")
|
|
22959
|
+
continue;
|
|
22960
|
+
try {
|
|
22961
|
+
const result = await callback.call(descriptor.observer, event);
|
|
22962
|
+
results.push(result ?? CONTINUE);
|
|
22963
|
+
} catch (err) {
|
|
22964
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
22965
|
+
if (descriptor.failureMode === "fail-closed") {
|
|
22966
|
+
results.push({
|
|
22967
|
+
action: "stop",
|
|
22968
|
+
reason: `observer "${descriptor.id}" failed: ${message}`,
|
|
22969
|
+
code: "OBSERVER_FAIL_CLOSED"
|
|
22970
|
+
});
|
|
22971
|
+
} else {
|
|
22972
|
+
if (descriptor.failureMode === "warn") {
|
|
22973
|
+
this.logger(`[observers] ${descriptor.id} (${String(hook)}) failed: ${message}`);
|
|
22974
|
+
}
|
|
22975
|
+
results.push(CONTINUE);
|
|
22976
|
+
}
|
|
22977
|
+
}
|
|
22978
|
+
}
|
|
22979
|
+
return results;
|
|
22980
|
+
}
|
|
22981
|
+
async emitResolved(hook, event) {
|
|
22982
|
+
return resolveInterventions(await this.emit(hook, event));
|
|
22983
|
+
}
|
|
22984
|
+
};
|
|
22985
|
+
}
|
|
22986
|
+
});
|
|
22987
|
+
|
|
21838
22988
|
// packages/core/dist/core/AgentHarness.js
|
|
21839
22989
|
function hashToolCall(toolName, args) {
|
|
21840
22990
|
const canonical = stableStringify2(args);
|
|
@@ -22078,6 +23228,7 @@ var init_AgentHarness = __esm({
|
|
|
22078
23228
|
init_contextGrowth();
|
|
22079
23229
|
init_requestSnapshot();
|
|
22080
23230
|
init_textLoopDetect();
|
|
23231
|
+
init_ObserverBus();
|
|
22081
23232
|
init_textLoopDetect();
|
|
22082
23233
|
BUILD_LIVENESS_RECOVERY_PROMPT = "[build-liveness] The requested task requires an on-disk implementation, but no successful project mutation has occurred yet. Continue working. Inspect only as needed, then make the required change with an available mutating tool. Do not merely describe a patch or claim completion.";
|
|
22083
23234
|
AgentHarness = class {
|
|
@@ -22105,6 +23256,14 @@ var init_AgentHarness = __esm({
|
|
|
22105
23256
|
* model must change approach instead of soft-replaying forever.
|
|
22106
23257
|
*/
|
|
22107
23258
|
toolCallCounts = /* @__PURE__ */ new Map();
|
|
23259
|
+
/**
|
|
23260
|
+
* Frontier PHASE 1: observer bus, or `null` when observers are off. Every
|
|
23261
|
+
* hook site guards on `this.observerBus` so the off-path stays identical
|
|
23262
|
+
* to the pre-observer loop.
|
|
23263
|
+
*/
|
|
23264
|
+
observerBus;
|
|
23265
|
+
/** Coarse turn counter attached to observer events (per run, 0-based). */
|
|
23266
|
+
observerTurn = 0;
|
|
22108
23267
|
/**
|
|
22109
23268
|
* How many times this run re-entered the provider because the model emitted
|
|
22110
23269
|
* tool calls as a `---TOOLS---` text block (fallback format) instead of native
|
|
@@ -22132,6 +23291,7 @@ var init_AgentHarness = __esm({
|
|
|
22132
23291
|
const soft = this.maxToolLoopIterations;
|
|
22133
23292
|
const hardCfg = config2.maxToolLoopHardCap;
|
|
22134
23293
|
this.maxToolLoopHardCap = typeof hardCfg === "number" && hardCfg > 0 ? Math.max(soft, hardCfg) : Math.max(soft * 3, soft + 60);
|
|
23294
|
+
this.observerBus = config2.observers?.length ? new ObserverBus(config2.observers) : buildRuntimeObserverBus({ steeringQueue: config2.controlQueue }) ?? null;
|
|
22135
23295
|
}
|
|
22136
23296
|
/**
|
|
22137
23297
|
* Snapshot of the live transcript (`this.config.messages`) as mutated
|
|
@@ -22227,6 +23387,57 @@ var init_AgentHarness = __esm({
|
|
|
22227
23387
|
return { allowed: true };
|
|
22228
23388
|
}
|
|
22229
23389
|
}
|
|
23390
|
+
/** Base fields shared by every observer event this harness emits. */
|
|
23391
|
+
observerEventBase(turn) {
|
|
23392
|
+
return {
|
|
23393
|
+
id: crypto.randomUUID(),
|
|
23394
|
+
ts: Date.now(),
|
|
23395
|
+
turn,
|
|
23396
|
+
identity: {
|
|
23397
|
+
runId: this.sessionId,
|
|
23398
|
+
agentId: this.sessionId,
|
|
23399
|
+
role: this.config.memberId ? "council" : "lead",
|
|
23400
|
+
mode: this.config.memberId ? "council" : "kraken",
|
|
23401
|
+
model: this.config.model,
|
|
23402
|
+
provider: this.config.provider
|
|
23403
|
+
}
|
|
23404
|
+
};
|
|
23405
|
+
}
|
|
23406
|
+
/**
|
|
23407
|
+
* Frontier PHASE 1: observer pre-dispatch gate, consulted after the host
|
|
23408
|
+
* resource gate on EVERY registry dispatch (native + text paths).
|
|
23409
|
+
* `deny_tool` blocks the call with a model-visible reason; `stop` is a
|
|
23410
|
+
* cooperative cancel (agent_end reason 'cancelled'); `inject` appends a
|
|
23411
|
+
* user/system message at the next safe boundary (the in-flight provider
|
|
23412
|
+
* request is never mutated). `retry`/`replace` are not yet honored at
|
|
23413
|
+
* this hook and fall through as continue.
|
|
23414
|
+
*/
|
|
23415
|
+
async checkObserverToolGate(toolCallId, toolName, args) {
|
|
23416
|
+
const bus = this.observerBus;
|
|
23417
|
+
if (!bus)
|
|
23418
|
+
return { allowed: true };
|
|
23419
|
+
const result = await bus.emitResolved("onToolCall", {
|
|
23420
|
+
...this.observerEventBase(this.observerTurn),
|
|
23421
|
+
toolCallId,
|
|
23422
|
+
toolName,
|
|
23423
|
+
args
|
|
23424
|
+
});
|
|
23425
|
+
if (result.action === "deny_tool") {
|
|
23426
|
+
return { allowed: false, reason: result.reason };
|
|
23427
|
+
}
|
|
23428
|
+
if (result.action === "stop") {
|
|
23429
|
+
this.cancel();
|
|
23430
|
+
return { allowed: false, reason: result.reason };
|
|
23431
|
+
}
|
|
23432
|
+
if (result.action === "inject") {
|
|
23433
|
+
this.config.messages.push({
|
|
23434
|
+
role: result.message.role === "system" ? "system" : "user",
|
|
23435
|
+
content: result.message.content
|
|
23436
|
+
});
|
|
23437
|
+
return { allowed: true };
|
|
23438
|
+
}
|
|
23439
|
+
return { allowed: true };
|
|
23440
|
+
}
|
|
22230
23441
|
async executePendingTools(pending, maxToolCalls) {
|
|
22231
23442
|
const out = new Array(pending.length);
|
|
22232
23443
|
const maxParallel = Math.max(1, Number.parseInt(process.env.ZELARI_MAX_PARALLEL_TOOLS ?? "6", 10) || 6);
|
|
@@ -22247,6 +23458,14 @@ var init_AgentHarness = __esm({
|
|
|
22247
23458
|
durationMs: 0
|
|
22248
23459
|
};
|
|
22249
23460
|
}
|
|
23461
|
+
const observerGate = await this.checkObserverToolGate(p3.toolCallId, p3.toolName, p3.args);
|
|
23462
|
+
if (!observerGate.allowed) {
|
|
23463
|
+
return {
|
|
23464
|
+
content: `[observers] ${observerGate.reason ?? "denied by observer policy"}`,
|
|
23465
|
+
isError: true,
|
|
23466
|
+
durationMs: 0
|
|
23467
|
+
};
|
|
23468
|
+
}
|
|
22250
23469
|
const callKey = hashToolCall(p3.toolName, p3.args);
|
|
22251
23470
|
const nextCount = (this.toolCallCounts.get(callKey) ?? 0) + 1;
|
|
22252
23471
|
this.toolCallCounts.set(callKey, nextCount);
|
|
@@ -22429,6 +23648,12 @@ ${shared2.content}`,
|
|
|
22429
23648
|
recoveries: 0
|
|
22430
23649
|
};
|
|
22431
23650
|
const memoryWarning = await this.prepareMemoryContext();
|
|
23651
|
+
this.observerTurn = 0;
|
|
23652
|
+
if (this.observerBus) {
|
|
23653
|
+
const start = await this.observerBus.emitResolved("onRunStart", this.observerEventBase(0));
|
|
23654
|
+
if (start.action === "stop")
|
|
23655
|
+
this.cancel();
|
|
23656
|
+
}
|
|
22432
23657
|
const startEvent = createBrainEvent("agent_start", this.sessionId, {
|
|
22433
23658
|
model: this.config.model,
|
|
22434
23659
|
provider: this.config.provider,
|
|
@@ -22638,6 +23863,22 @@ ${shared2.content}`,
|
|
|
22638
23863
|
});
|
|
22639
23864
|
this.emit(growthEvent);
|
|
22640
23865
|
yield growthEvent;
|
|
23866
|
+
if (this.observerBus) {
|
|
23867
|
+
const endReason = hadError ? "error" : this.cancelled ? "cancelled" : "completed";
|
|
23868
|
+
try {
|
|
23869
|
+
if (endReason === "cancelled") {
|
|
23870
|
+
await this.observerBus.emitResolved("onCancelled", {
|
|
23871
|
+
...this.observerEventBase(this.observerTurn),
|
|
23872
|
+
reason: "cancelled"
|
|
23873
|
+
});
|
|
23874
|
+
}
|
|
23875
|
+
await this.observerBus.emitResolved("onRunEnd", {
|
|
23876
|
+
...this.observerEventBase(this.observerTurn),
|
|
23877
|
+
reason: endReason
|
|
23878
|
+
});
|
|
23879
|
+
} catch {
|
|
23880
|
+
}
|
|
23881
|
+
}
|
|
22641
23882
|
const agentEnd = createBrainEvent("agent_end", this.sessionId, {
|
|
22642
23883
|
reason: hadError ? "error" : this.cancelled ? "cancelled" : "completed",
|
|
22643
23884
|
durationMs: Date.now() - startTime,
|
|
@@ -22922,6 +24163,21 @@ ${cached2}`
|
|
|
22922
24163
|
executedAny = true;
|
|
22923
24164
|
continue;
|
|
22924
24165
|
}
|
|
24166
|
+
const observerGate = await this.checkObserverToolGate(toolCallId, tt.name, tt.args);
|
|
24167
|
+
if (!observerGate.allowed) {
|
|
24168
|
+
const denied = `[observers] ${observerGate.reason ?? "denied by observer policy"}`;
|
|
24169
|
+
const denyEv = createBrainEvent("tool_execution_end", this.sessionId, {
|
|
24170
|
+
toolCallId,
|
|
24171
|
+
result: denied,
|
|
24172
|
+
isError: true,
|
|
24173
|
+
durationMs: 0
|
|
24174
|
+
});
|
|
24175
|
+
this.emit(denyEv);
|
|
24176
|
+
yield denyEv;
|
|
24177
|
+
turnToolResults.push({ toolCallId, content: denied });
|
|
24178
|
+
executedAny = true;
|
|
24179
|
+
continue;
|
|
24180
|
+
}
|
|
22925
24181
|
let resultStr = "";
|
|
22926
24182
|
let isError = false;
|
|
22927
24183
|
const startMs = Date.now();
|
|
@@ -22981,6 +24237,21 @@ ${cached2}`
|
|
|
22981
24237
|
yield truncErr;
|
|
22982
24238
|
finishRef.value = "stop";
|
|
22983
24239
|
}
|
|
24240
|
+
if (this.observerBus) {
|
|
24241
|
+
this.observerTurn += 1;
|
|
24242
|
+
try {
|
|
24243
|
+
const turnEnd = await this.observerBus.emitResolved("onTurnEnd", this.observerEventBase(this.observerTurn));
|
|
24244
|
+
if (turnEnd.action === "inject") {
|
|
24245
|
+
this.config.messages.push({
|
|
24246
|
+
role: turnEnd.message.role === "system" ? "system" : "user",
|
|
24247
|
+
content: turnEnd.message.content
|
|
24248
|
+
});
|
|
24249
|
+
} else if (turnEnd.action === "stop") {
|
|
24250
|
+
this.cancel();
|
|
24251
|
+
}
|
|
24252
|
+
} catch {
|
|
24253
|
+
}
|
|
24254
|
+
}
|
|
22984
24255
|
if (turnToolCalls.length > 0 || turnText.length > 0 || turnReasoning.length > 0) {
|
|
22985
24256
|
this.config.messages.push({
|
|
22986
24257
|
role: "assistant",
|
|
@@ -23384,7 +24655,7 @@ function hookMatches(hook, event, toolName) {
|
|
|
23384
24655
|
return true;
|
|
23385
24656
|
}
|
|
23386
24657
|
var TOOL_ALIASES;
|
|
23387
|
-
var
|
|
24658
|
+
var init_types3 = __esm({
|
|
23388
24659
|
"packages/core/dist/core/hooks/types.js"() {
|
|
23389
24660
|
"use strict";
|
|
23390
24661
|
TOOL_ALIASES = {
|
|
@@ -23429,7 +24700,7 @@ var DEFAULT_TIMEOUT_MS, LifecycleHookRunner;
|
|
|
23429
24700
|
var init_lifecycleHookRunner = __esm({
|
|
23430
24701
|
"packages/core/dist/core/hooks/lifecycleHookRunner.js"() {
|
|
23431
24702
|
"use strict";
|
|
23432
|
-
|
|
24703
|
+
init_types3();
|
|
23433
24704
|
DEFAULT_TIMEOUT_MS = 5e3;
|
|
23434
24705
|
LifecycleHookRunner = class {
|
|
23435
24706
|
hooks = [];
|
|
@@ -23634,7 +24905,7 @@ var init_lifecycleHookRunner = __esm({
|
|
|
23634
24905
|
var init_hooks = __esm({
|
|
23635
24906
|
"packages/core/dist/core/hooks/index.js"() {
|
|
23636
24907
|
"use strict";
|
|
23637
|
-
|
|
24908
|
+
init_types3();
|
|
23638
24909
|
init_lifecycleHookRunner();
|
|
23639
24910
|
}
|
|
23640
24911
|
});
|
|
@@ -24161,7 +25432,7 @@ var init_parseCssMotion = __esm({
|
|
|
24161
25432
|
|
|
24162
25433
|
// packages/core/dist/council/verification/citeVerify.js
|
|
24163
25434
|
import { existsSync as existsSync6, readFileSync as readFileSync6 } from "node:fs";
|
|
24164
|
-
import { join } from "node:path";
|
|
25435
|
+
import { join as join3 } from "node:path";
|
|
24165
25436
|
function extractCitations(text) {
|
|
24166
25437
|
const out = [];
|
|
24167
25438
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -24183,7 +25454,7 @@ function verifyCitations(projectRoot, synthesisText) {
|
|
|
24183
25454
|
return [];
|
|
24184
25455
|
const results = [];
|
|
24185
25456
|
for (const cite of extractCitations(synthesisText)) {
|
|
24186
|
-
const abs =
|
|
25457
|
+
const abs = join3(projectRoot, cite.file);
|
|
24187
25458
|
if (!existsSync6(abs)) {
|
|
24188
25459
|
results.push({
|
|
24189
25460
|
id: "synthesis.cite-invalid",
|
|
@@ -24461,9 +25732,9 @@ var init_synthesisAudit = __esm({
|
|
|
24461
25732
|
|
|
24462
25733
|
// packages/core/dist/council/verification/runChecks.js
|
|
24463
25734
|
import { existsSync as existsSync7, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "node:fs";
|
|
24464
|
-
import { join as
|
|
25735
|
+
import { join as join4 } from "node:path";
|
|
24465
25736
|
function loadNfrSpec(zelariRoot) {
|
|
24466
|
-
const path72 =
|
|
25737
|
+
const path72 = join4(zelariRoot, "nfr-spec.json");
|
|
24467
25738
|
if (!existsSync7(path72))
|
|
24468
25739
|
return null;
|
|
24469
25740
|
try {
|
|
@@ -24478,11 +25749,11 @@ function loadNfrSpec(zelariRoot) {
|
|
|
24478
25749
|
function resolveTargets(projectRoot, spec) {
|
|
24479
25750
|
const found = [];
|
|
24480
25751
|
for (const rel2 of spec.targets) {
|
|
24481
|
-
if (existsSync7(
|
|
25752
|
+
if (existsSync7(join4(projectRoot, rel2))) {
|
|
24482
25753
|
found.push(rel2);
|
|
24483
25754
|
}
|
|
24484
25755
|
}
|
|
24485
|
-
if (found.length === 0 && existsSync7(
|
|
25756
|
+
if (found.length === 0 && existsSync7(join4(projectRoot, "index.html"))) {
|
|
24486
25757
|
return ["index.html"];
|
|
24487
25758
|
}
|
|
24488
25759
|
return found;
|
|
@@ -24537,7 +25808,7 @@ function checkDeadCssHooks(html, relFile) {
|
|
|
24537
25808
|
return results;
|
|
24538
25809
|
}
|
|
24539
25810
|
function checkPlanReality(projectRoot, zelariRoot, targets, keywords) {
|
|
24540
|
-
const planPath =
|
|
25811
|
+
const planPath = join4(zelariRoot, "plan.json");
|
|
24541
25812
|
if (!existsSync7(planPath) || keywords.length === 0)
|
|
24542
25813
|
return [];
|
|
24543
25814
|
let plan;
|
|
@@ -24548,7 +25819,7 @@ function checkPlanReality(projectRoot, zelariRoot, targets, keywords) {
|
|
|
24548
25819
|
}
|
|
24549
25820
|
const milestoneText = (plan.milestones ?? []).map((m) => `${m.name ?? ""} ${m.description ?? ""}`).join(" ").toLowerCase();
|
|
24550
25821
|
const results = [];
|
|
24551
|
-
const targetContent = targets.map((t) => readFileSync7(
|
|
25822
|
+
const targetContent = targets.map((t) => readFileSync7(join4(projectRoot, t), "utf8").toLowerCase()).join("\n");
|
|
24552
25823
|
for (const kw of keywords) {
|
|
24553
25824
|
const low = kw.toLowerCase();
|
|
24554
25825
|
if (!milestoneText.includes(low))
|
|
@@ -24577,11 +25848,11 @@ function checkPlanReality(projectRoot, zelariRoot, targets, keywords) {
|
|
|
24577
25848
|
return results;
|
|
24578
25849
|
}
|
|
24579
25850
|
function checkReadmeStale(projectRoot, targets) {
|
|
24580
|
-
const readmePath =
|
|
25851
|
+
const readmePath = join4(projectRoot, "README.md");
|
|
24581
25852
|
if (!existsSync7(readmePath) || targets.length === 0)
|
|
24582
25853
|
return [];
|
|
24583
25854
|
const readme = readFileSync7(readmePath, "utf8");
|
|
24584
|
-
const htmlPath =
|
|
25855
|
+
const htmlPath = join4(projectRoot, targets[0]);
|
|
24585
25856
|
if (!existsSync7(htmlPath))
|
|
24586
25857
|
return [];
|
|
24587
25858
|
const html = readFileSync7(htmlPath, "utf8");
|
|
@@ -24622,7 +25893,7 @@ function runImplementationVerification(input) {
|
|
|
24622
25893
|
forbidLayoutProps: anim.forbidLayoutProps ?? true
|
|
24623
25894
|
};
|
|
24624
25895
|
for (const rel2 of targets) {
|
|
24625
|
-
const html = readFileSync7(
|
|
25896
|
+
const html = readFileSync7(join4(input.projectRoot, rel2), "utf8");
|
|
24626
25897
|
for (const v of scanKeyframesViolations(html, scanOpts)) {
|
|
24627
25898
|
results.push({
|
|
24628
25899
|
id: "motion.keyframes",
|
|
@@ -24678,7 +25949,7 @@ function runImplementationVerification(input) {
|
|
|
24678
25949
|
};
|
|
24679
25950
|
}
|
|
24680
25951
|
function writeVerificationReport(zelariRoot, report) {
|
|
24681
|
-
const outPath =
|
|
25952
|
+
const outPath = join4(zelariRoot, "verification-report.json");
|
|
24682
25953
|
writeFileSync5(outPath, JSON.stringify(report, null, 2), "utf8");
|
|
24683
25954
|
return outPath;
|
|
24684
25955
|
}
|
|
@@ -24709,7 +25980,7 @@ var init_runChecks = __esm({
|
|
|
24709
25980
|
|
|
24710
25981
|
// packages/core/dist/council/verification/microGate.js
|
|
24711
25982
|
import { existsSync as existsSync8, readFileSync as readFileSync8 } from "node:fs";
|
|
24712
|
-
import { join as
|
|
25983
|
+
import { join as join5 } from "node:path";
|
|
24713
25984
|
function checkDeadHooksInHtml(html) {
|
|
24714
25985
|
const warnings = [];
|
|
24715
25986
|
const scripts = [];
|
|
@@ -24737,7 +26008,7 @@ function checkDeadHooksInHtml(html) {
|
|
|
24737
26008
|
return warnings;
|
|
24738
26009
|
}
|
|
24739
26010
|
function runMicroVerificationOnFile(projectRoot, relPath, zelariRoot) {
|
|
24740
|
-
const abs =
|
|
26011
|
+
const abs = join5(projectRoot, relPath);
|
|
24741
26012
|
if (!existsSync8(abs) || !/\.html?$/i.test(relPath))
|
|
24742
26013
|
return [];
|
|
24743
26014
|
const spec = (zelariRoot ? loadNfrSpec(zelariRoot) : null) ?? DEFAULT_NFR_SPEC;
|
|
@@ -25103,7 +26374,7 @@ var init_implementationDelivery = __esm({
|
|
|
25103
26374
|
|
|
25104
26375
|
// packages/core/dist/council/verification/inlineJsAutofix.js
|
|
25105
26376
|
import { readFileSync as readFileSync9, writeFileSync as writeFileSync6 } from "node:fs";
|
|
25106
|
-
import { join as
|
|
26377
|
+
import { join as join6 } from "node:path";
|
|
25107
26378
|
function minifyInlineJs(js) {
|
|
25108
26379
|
let out = js.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
25109
26380
|
out = out.split("\n").map((line) => line.replace(/\/\/.*$/, "").trimEnd()).filter((line) => line.trim().length > 0).join("\n");
|
|
@@ -25146,7 +26417,7 @@ function applyInlineJsAutofix(projectRoot, report) {
|
|
|
25146
26417
|
const fixes = [];
|
|
25147
26418
|
for (const r of fails) {
|
|
25148
26419
|
const rel2 = r.file ?? "index.html";
|
|
25149
|
-
const abs =
|
|
26420
|
+
const abs = join6(projectRoot, rel2);
|
|
25150
26421
|
let html;
|
|
25151
26422
|
try {
|
|
25152
26423
|
html = readFileSync9(abs, "utf8");
|
|
@@ -25183,7 +26454,7 @@ var init_inlineJsAutofix = __esm({
|
|
|
25183
26454
|
|
|
25184
26455
|
// packages/core/dist/agents/councilApi.js
|
|
25185
26456
|
import { existsSync as existsSync9 } from "node:fs";
|
|
25186
|
-
import { join as
|
|
26457
|
+
import { join as join7 } from "node:path";
|
|
25187
26458
|
function extractBalancedJsonObject(s) {
|
|
25188
26459
|
const start = s.indexOf("{");
|
|
25189
26460
|
if (start < 0)
|
|
@@ -25810,7 +27081,7 @@ async function* runCouncilPure(userMessage, config2, callbacks = {}) {
|
|
|
25810
27081
|
const zelariRoot = `${chairmanProjectRoot}/.zelari`;
|
|
25811
27082
|
const spec = loadNfrSpec(zelariRoot) ?? DEFAULT_NFR_SPEC;
|
|
25812
27083
|
for (const rel2 of spec.targets) {
|
|
25813
|
-
if (!existsSync9(
|
|
27084
|
+
if (!existsSync9(join7(chairmanProjectRoot, rel2)))
|
|
25814
27085
|
continue;
|
|
25815
27086
|
changedTargetFiles.add(rel2);
|
|
25816
27087
|
for (const w of runChairmanMicroGate({ projectRoot: chairmanProjectRoot, relPath: rel2, zelariRoot })) {
|
|
@@ -25830,7 +27101,7 @@ async function* runCouncilPure(userMessage, config2, callbacks = {}) {
|
|
|
25830
27101
|
const zelariRootReplay = `${chairmanProjectRoot}/.zelari`;
|
|
25831
27102
|
const specReplay = loadNfrSpec(zelariRootReplay) ?? DEFAULT_NFR_SPEC;
|
|
25832
27103
|
for (const rel2 of specReplay.targets) {
|
|
25833
|
-
if (!existsSync9(
|
|
27104
|
+
if (!existsSync9(join7(chairmanProjectRoot, rel2)))
|
|
25834
27105
|
continue;
|
|
25835
27106
|
changedTargetFiles.add(rel2);
|
|
25836
27107
|
for (const w of runChairmanMicroGate({
|
|
@@ -26541,7 +27812,7 @@ var init_missionBrief = __esm({
|
|
|
26541
27812
|
});
|
|
26542
27813
|
|
|
26543
27814
|
// packages/core/dist/council/verification/types.js
|
|
26544
|
-
var
|
|
27815
|
+
var init_types4 = __esm({
|
|
26545
27816
|
"packages/core/dist/council/verification/types.js"() {
|
|
26546
27817
|
"use strict";
|
|
26547
27818
|
}
|
|
@@ -26549,7 +27820,7 @@ var init_types3 = __esm({
|
|
|
26549
27820
|
|
|
26550
27821
|
// packages/core/dist/council/verification/motionAutofix.js
|
|
26551
27822
|
import { readFileSync as readFileSync10, writeFileSync as writeFileSync7 } from "node:fs";
|
|
26552
|
-
import { join as
|
|
27823
|
+
import { join as join8 } from "node:path";
|
|
26553
27824
|
function sanitizeTransitionPart(part) {
|
|
26554
27825
|
const tokens = part.trim().split(/\s+/);
|
|
26555
27826
|
if (tokens.length === 0)
|
|
@@ -26624,7 +27895,7 @@ function applyMotionAutofix(projectRoot, report) {
|
|
|
26624
27895
|
forbidLayoutProps: DEFAULT_NFR_SPEC.animation?.forbidLayoutProps ?? true
|
|
26625
27896
|
};
|
|
26626
27897
|
for (const rel2 of targets) {
|
|
26627
|
-
const abs =
|
|
27898
|
+
const abs = join8(projectRoot, rel2);
|
|
26628
27899
|
let html;
|
|
26629
27900
|
try {
|
|
26630
27901
|
html = readFileSync10(abs, "utf8");
|
|
@@ -26700,7 +27971,7 @@ var init_motionAutofix = __esm({
|
|
|
26700
27971
|
|
|
26701
27972
|
// packages/core/dist/council/verification/autofix.js
|
|
26702
27973
|
import { readFileSync as readFileSync11, writeFileSync as writeFileSync8 } from "node:fs";
|
|
26703
|
-
import { join as
|
|
27974
|
+
import { join as join9 } from "node:path";
|
|
26704
27975
|
function applyDeterministicAutofix(projectRoot, report) {
|
|
26705
27976
|
const motion = applyMotionAutofix(projectRoot, report);
|
|
26706
27977
|
const inlineJs = applyInlineJsAutofix(projectRoot, report);
|
|
@@ -26714,7 +27985,7 @@ function applyDeterministicAutofix(projectRoot, report) {
|
|
|
26714
27985
|
const m = r.evidence?.match(/classList\.add\(\s*['"]([\w-]+)['"]\s*\)/);
|
|
26715
27986
|
if (!m || m[1] === "rm")
|
|
26716
27987
|
continue;
|
|
26717
|
-
const abs =
|
|
27988
|
+
const abs = join9(projectRoot, rel2);
|
|
26718
27989
|
let html = readFileSync11(abs, "utf8");
|
|
26719
27990
|
const snippet = m[0];
|
|
26720
27991
|
if (!html.includes(snippet))
|
|
@@ -26745,7 +28016,7 @@ var init_autofix = __esm({
|
|
|
26745
28016
|
var init_verification = __esm({
|
|
26746
28017
|
"packages/core/dist/council/verification/index.js"() {
|
|
26747
28018
|
"use strict";
|
|
26748
|
-
|
|
28019
|
+
init_types4();
|
|
26749
28020
|
init_runChecks();
|
|
26750
28021
|
init_honesty();
|
|
26751
28022
|
init_parseCssMotion();
|
|
@@ -26763,7 +28034,7 @@ var init_verification = __esm({
|
|
|
26763
28034
|
});
|
|
26764
28035
|
|
|
26765
28036
|
// packages/core/dist/council/lessons/types.js
|
|
26766
|
-
var
|
|
28037
|
+
var init_types5 = __esm({
|
|
26767
28038
|
"packages/core/dist/council/lessons/types.js"() {
|
|
26768
28039
|
"use strict";
|
|
26769
28040
|
}
|
|
@@ -26771,9 +28042,9 @@ var init_types4 = __esm({
|
|
|
26771
28042
|
|
|
26772
28043
|
// packages/core/dist/council/lessons/io.js
|
|
26773
28044
|
import { readFileSync as readFileSync12 } from "node:fs";
|
|
26774
|
-
import { join as
|
|
28045
|
+
import { join as join10 } from "node:path";
|
|
26775
28046
|
function readLessonsDeduped(zelariRoot) {
|
|
26776
|
-
const path72 =
|
|
28047
|
+
const path72 = join10(zelariRoot, LESSONS_FILE);
|
|
26777
28048
|
try {
|
|
26778
28049
|
const raw = readFileSync12(path72, "utf8");
|
|
26779
28050
|
const byId = /* @__PURE__ */ new Map();
|
|
@@ -26855,8 +28126,8 @@ function jaccardSimilarity(a, b) {
|
|
|
26855
28126
|
return union2 === 0 ? 0 : inter / union2;
|
|
26856
28127
|
}
|
|
26857
28128
|
function normalizeForSignature(checkId, message) {
|
|
26858
|
-
const
|
|
26859
|
-
return [...tokenizeForSignature(
|
|
28129
|
+
const base2 = `${checkId} ${message}`.toLowerCase().replace(/[A-Za-z]:\\[^\s]+/g, "path").replace(/\/[\w./-]+/g, "path").replace(/l\d{1,6}/gi, "line").replace(/\d+/g, "n");
|
|
28130
|
+
return [...tokenizeForSignature(base2)].sort().join(" ");
|
|
26860
28131
|
}
|
|
26861
28132
|
var init_signatures = __esm({
|
|
26862
28133
|
"packages/core/dist/council/lessons/signatures.js"() {
|
|
@@ -26866,7 +28137,7 @@ var init_signatures = __esm({
|
|
|
26866
28137
|
|
|
26867
28138
|
// packages/core/dist/council/lessons/recordFailure.js
|
|
26868
28139
|
import { appendFileSync } from "node:fs";
|
|
26869
|
-
import { join as
|
|
28140
|
+
import { join as join11 } from "node:path";
|
|
26870
28141
|
function methodologyFor(check2) {
|
|
26871
28142
|
return METHODOLOGY[check2.id] ?? `When ${check2.id} fails, fix the underlying issue and cite grep/tool evidence before claiming PASS.`;
|
|
26872
28143
|
}
|
|
@@ -26876,7 +28147,7 @@ function keywordsFrom(check2, signature) {
|
|
|
26876
28147
|
return [.../* @__PURE__ */ new Set([...fromId, ...words])].slice(0, 12);
|
|
26877
28148
|
}
|
|
26878
28149
|
function writeLesson(zelariRoot, lesson) {
|
|
26879
|
-
const path72 =
|
|
28150
|
+
const path72 = join11(zelariRoot, LESSONS_FILE);
|
|
26880
28151
|
appendFileSync(path72, `${JSON.stringify(lesson)}
|
|
26881
28152
|
`, "utf8");
|
|
26882
28153
|
}
|
|
@@ -27016,7 +28287,7 @@ var init_recallLessons = __esm({
|
|
|
27016
28287
|
var init_lessons = __esm({
|
|
27017
28288
|
"packages/core/dist/council/lessons/index.js"() {
|
|
27018
28289
|
"use strict";
|
|
27019
|
-
|
|
28290
|
+
init_types5();
|
|
27020
28291
|
init_io();
|
|
27021
28292
|
init_isAnswerLeak();
|
|
27022
28293
|
init_signatures();
|
|
@@ -27026,7 +28297,7 @@ var init_lessons = __esm({
|
|
|
27026
28297
|
});
|
|
27027
28298
|
|
|
27028
28299
|
// packages/core/dist/council/completion/types.js
|
|
27029
|
-
var
|
|
28300
|
+
var init_types6 = __esm({
|
|
27030
28301
|
"packages/core/dist/council/completion/types.js"() {
|
|
27031
28302
|
"use strict";
|
|
27032
28303
|
}
|
|
@@ -27034,7 +28305,7 @@ var init_types5 = __esm({
|
|
|
27034
28305
|
|
|
27035
28306
|
// packages/core/dist/council/completion/buildCompletion.js
|
|
27036
28307
|
import { writeFileSync as writeFileSync9 } from "node:fs";
|
|
27037
|
-
import { join as
|
|
28308
|
+
import { join as join12 } from "node:path";
|
|
27038
28309
|
function openFailsFromReport(report) {
|
|
27039
28310
|
if (!report)
|
|
27040
28311
|
return [];
|
|
@@ -27093,7 +28364,7 @@ function buildCouncilCompletion(input) {
|
|
|
27093
28364
|
};
|
|
27094
28365
|
}
|
|
27095
28366
|
function writeCouncilCompletion(zelariRoot, completion) {
|
|
27096
|
-
const outPath =
|
|
28367
|
+
const outPath = join12(zelariRoot, "completion.json");
|
|
27097
28368
|
writeFileSync9(outPath, JSON.stringify(completion, null, 2), "utf8");
|
|
27098
28369
|
return outPath;
|
|
27099
28370
|
}
|
|
@@ -27107,7 +28378,7 @@ var init_buildCompletion = __esm({
|
|
|
27107
28378
|
var init_completion2 = __esm({
|
|
27108
28379
|
"packages/core/dist/council/completion/index.js"() {
|
|
27109
28380
|
"use strict";
|
|
27110
|
-
|
|
28381
|
+
init_types6();
|
|
27111
28382
|
init_buildCompletion();
|
|
27112
28383
|
}
|
|
27113
28384
|
});
|
|
@@ -27428,7 +28699,7 @@ var init_council = __esm({
|
|
|
27428
28699
|
|
|
27429
28700
|
// packages/core/dist/memory/types.js
|
|
27430
28701
|
var MEMORY_SCHEMA_VERSION, MEMORY_KINDS, MEMORY_STATUSES, MEMORY_RELATIONS, MEMORY_VISIBILITIES;
|
|
27431
|
-
var
|
|
28702
|
+
var init_types7 = __esm({
|
|
27432
28703
|
"packages/core/dist/memory/types.js"() {
|
|
27433
28704
|
"use strict";
|
|
27434
28705
|
MEMORY_SCHEMA_VERSION = 1;
|
|
@@ -27479,7 +28750,7 @@ var init_schemas3 = __esm({
|
|
|
27479
28750
|
"packages/core/dist/memory/schemas.js"() {
|
|
27480
28751
|
"use strict";
|
|
27481
28752
|
init_zod();
|
|
27482
|
-
|
|
28753
|
+
init_types7();
|
|
27483
28754
|
isoDate = external_exports.string().datetime({ offset: true });
|
|
27484
28755
|
unit = external_exports.number().finite().min(0).max(1);
|
|
27485
28756
|
metadata = external_exports.record(external_exports.string(), external_exports.unknown()).refine((value) => {
|
|
@@ -28455,18 +29726,18 @@ var init_service = __esm({
|
|
|
28455
29726
|
};
|
|
28456
29727
|
}
|
|
28457
29728
|
async doctor() {
|
|
28458
|
-
const
|
|
29729
|
+
const base2 = await (this.backend.doctor?.() ?? Promise.resolve({
|
|
28459
29730
|
ok: true,
|
|
28460
29731
|
backend: "custom",
|
|
28461
29732
|
checks: [{ name: "backend", ok: true, detail: "No diagnostic API exposed." }]
|
|
28462
29733
|
}));
|
|
28463
29734
|
if (!this.semantic)
|
|
28464
|
-
return
|
|
29735
|
+
return base2;
|
|
28465
29736
|
const semantic = await this.semantic.status();
|
|
28466
29737
|
return {
|
|
28467
|
-
...
|
|
29738
|
+
...base2,
|
|
28468
29739
|
checks: [
|
|
28469
|
-
...
|
|
29740
|
+
...base2.checks,
|
|
28470
29741
|
{
|
|
28471
29742
|
name: "semantic",
|
|
28472
29743
|
ok: semantic.state !== "degraded",
|
|
@@ -28770,7 +30041,7 @@ var init_noop = __esm({
|
|
|
28770
30041
|
var init_memory = __esm({
|
|
28771
30042
|
"packages/core/dist/memory/index.js"() {
|
|
28772
30043
|
"use strict";
|
|
28773
|
-
|
|
30044
|
+
init_types7();
|
|
28774
30045
|
init_schemas3();
|
|
28775
30046
|
init_scoring();
|
|
28776
30047
|
init_policies();
|
|
@@ -29287,10 +30558,10 @@ function extractRequirementsBlock(text) {
|
|
|
29287
30558
|
}
|
|
29288
30559
|
}
|
|
29289
30560
|
function parsePersonaVerdict(text) {
|
|
29290
|
-
const
|
|
30561
|
+
const base2 = parseVerifyVerdict(text);
|
|
29291
30562
|
return {
|
|
29292
|
-
verdict:
|
|
29293
|
-
findings:
|
|
30563
|
+
verdict: base2.verdict,
|
|
30564
|
+
findings: base2.findings,
|
|
29294
30565
|
requirements: extractRequirementsBlock(text),
|
|
29295
30566
|
// Bennett's weakness = "how little the reviewer's free text asserts"
|
|
29296
30567
|
// (arXiv:2301.12987). `weaknessScoreFromText` is the weakness form
|
|
@@ -29492,7 +30763,7 @@ var init_personas = __esm({
|
|
|
29492
30763
|
|
|
29493
30764
|
// packages/core/dist/kraken/runtime/types.js
|
|
29494
30765
|
var PlanError;
|
|
29495
|
-
var
|
|
30766
|
+
var init_types8 = __esm({
|
|
29496
30767
|
"packages/core/dist/kraken/runtime/types.js"() {
|
|
29497
30768
|
"use strict";
|
|
29498
30769
|
PlanError = class extends Error {
|
|
@@ -29590,7 +30861,7 @@ var MAX_BUNDLE_BYTES, FORBIDDEN_TOKENS;
|
|
|
29590
30861
|
var init_sandbox = __esm({
|
|
29591
30862
|
"packages/core/dist/kraken/runtime/sandbox.js"() {
|
|
29592
30863
|
"use strict";
|
|
29593
|
-
|
|
30864
|
+
init_types8();
|
|
29594
30865
|
MAX_BUNDLE_BYTES = 256 * 1024;
|
|
29595
30866
|
FORBIDDEN_TOKENS = [
|
|
29596
30867
|
/\bprocess\b/,
|
|
@@ -29653,7 +30924,7 @@ var init_runner = __esm({
|
|
|
29653
30924
|
"use strict";
|
|
29654
30925
|
init_verdict();
|
|
29655
30926
|
init_personas();
|
|
29656
|
-
|
|
30927
|
+
init_types8();
|
|
29657
30928
|
DEFAULT_MAX_TENTACLES = 200;
|
|
29658
30929
|
DEFAULT_PLAN_TIMEOUT_MS = 30 * 6e4;
|
|
29659
30930
|
ScriptRunner = class {
|
|
@@ -29837,7 +31108,7 @@ var init_runner = __esm({
|
|
|
29837
31108
|
var init_runtime = __esm({
|
|
29838
31109
|
"packages/core/dist/kraken/runtime/index.js"() {
|
|
29839
31110
|
"use strict";
|
|
29840
|
-
|
|
31111
|
+
init_types8();
|
|
29841
31112
|
init_sandbox();
|
|
29842
31113
|
init_runner();
|
|
29843
31114
|
}
|
|
@@ -29858,7 +31129,7 @@ var init_kraken = __esm({
|
|
|
29858
31129
|
|
|
29859
31130
|
// packages/core/dist/session/types.js
|
|
29860
31131
|
var SESSION_SCHEMA_VERSION, SessionActorSchema, SESSION_EVENT_KINDS, SessionEventEnvelopeSchema, ACTOR_USER, ACTOR_AGENT, ACTOR_SYSTEM;
|
|
29861
|
-
var
|
|
31132
|
+
var init_types9 = __esm({
|
|
29862
31133
|
"packages/core/dist/session/types.js"() {
|
|
29863
31134
|
"use strict";
|
|
29864
31135
|
init_zod();
|
|
@@ -30422,7 +31693,7 @@ var SessionLogLockedError, DEFAULT_STALE_LOCK_MS, SessionLogWriter;
|
|
|
30422
31693
|
var init_writer = __esm({
|
|
30423
31694
|
"packages/core/dist/session/writer.js"() {
|
|
30424
31695
|
"use strict";
|
|
30425
|
-
|
|
31696
|
+
init_types9();
|
|
30426
31697
|
SessionLogLockedError = class extends Error {
|
|
30427
31698
|
sessionPath;
|
|
30428
31699
|
owner;
|
|
@@ -30734,7 +32005,7 @@ function buildProjection(events, issues = []) {
|
|
|
30734
32005
|
var init_replay = __esm({
|
|
30735
32006
|
"packages/core/dist/session/replay.js"() {
|
|
30736
32007
|
"use strict";
|
|
30737
|
-
|
|
32008
|
+
init_types9();
|
|
30738
32009
|
init_modelSurface();
|
|
30739
32010
|
init_recovery();
|
|
30740
32011
|
}
|
|
@@ -30759,7 +32030,7 @@ var init_store = __esm({
|
|
|
30759
32030
|
"use strict";
|
|
30760
32031
|
init_writer();
|
|
30761
32032
|
init_replay();
|
|
30762
|
-
|
|
32033
|
+
init_types9();
|
|
30763
32034
|
SessionStore = class _SessionStore {
|
|
30764
32035
|
baseDir;
|
|
30765
32036
|
constructor(baseDir) {
|
|
@@ -30915,7 +32186,7 @@ async function lineageOf(store6, sessionId2) {
|
|
|
30915
32186
|
var init_lineage = __esm({
|
|
30916
32187
|
"packages/core/dist/session/lineage.js"() {
|
|
30917
32188
|
"use strict";
|
|
30918
|
-
|
|
32189
|
+
init_types9();
|
|
30919
32190
|
init_replay();
|
|
30920
32191
|
init_recovery();
|
|
30921
32192
|
}
|
|
@@ -31398,7 +32669,7 @@ var init_taskContract = __esm({
|
|
|
31398
32669
|
var init_session = __esm({
|
|
31399
32670
|
"packages/core/dist/session/index.js"() {
|
|
31400
32671
|
"use strict";
|
|
31401
|
-
|
|
32672
|
+
init_types9();
|
|
31402
32673
|
init_modelSurface();
|
|
31403
32674
|
init_compaction();
|
|
31404
32675
|
init_agentAdapter();
|
|
@@ -31734,7 +33005,7 @@ var init_worktreeWorkspace = __esm({
|
|
|
31734
33005
|
});
|
|
31735
33006
|
|
|
31736
33007
|
// packages/core/dist/runtime/profiles.js
|
|
31737
|
-
import { createHash as
|
|
33008
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
31738
33009
|
function resolveProfile(id3) {
|
|
31739
33010
|
const profile = BUILT_IN_PROFILES[id3];
|
|
31740
33011
|
if (!profile)
|
|
@@ -31743,10 +33014,10 @@ function resolveProfile(id3) {
|
|
|
31743
33014
|
}
|
|
31744
33015
|
function toolManifestHash(tools) {
|
|
31745
33016
|
const manifest = [...tools].sort().join(",");
|
|
31746
|
-
return
|
|
33017
|
+
return createHash5("sha256").update(manifest).digest("hex");
|
|
31747
33018
|
}
|
|
31748
33019
|
function profileHash(profile) {
|
|
31749
|
-
return
|
|
33020
|
+
return createHash5("sha256").update(stableStringify(profile)).digest("hex");
|
|
31750
33021
|
}
|
|
31751
33022
|
var ProfileSchema, MINIMAL_TOOLS, MINIMAL_V1, KRAKEN_V1, COUNCIL_V1, MISSION_V1, BUILT_IN_PROFILES, UnknownProfileError;
|
|
31752
33023
|
var init_profiles = __esm({
|
|
@@ -31832,7 +33103,7 @@ function hashHarnessManifest(manifest) {
|
|
|
31832
33103
|
function harnessInputHash(value) {
|
|
31833
33104
|
return sha256Hex(stableStringify(value));
|
|
31834
33105
|
}
|
|
31835
|
-
function collectPaths2(
|
|
33106
|
+
function collectPaths2(base2, a, b, out, depth = 0) {
|
|
31836
33107
|
if (depth > 6)
|
|
31837
33108
|
return;
|
|
31838
33109
|
if (stableStringify(a) === stableStringify(b))
|
|
@@ -31841,11 +33112,11 @@ function collectPaths2(base, a, b, out, depth = 0) {
|
|
|
31841
33112
|
const objB = b && typeof b === "object" && !Array.isArray(b) ? b : null;
|
|
31842
33113
|
if (objA && objB) {
|
|
31843
33114
|
for (const key of [.../* @__PURE__ */ new Set([...Object.keys(objA), ...Object.keys(objB)])].sort()) {
|
|
31844
|
-
collectPaths2(
|
|
33115
|
+
collectPaths2(base2 ? `${base2}.${key}` : key, objA[key], objB[key], out, depth + 1);
|
|
31845
33116
|
}
|
|
31846
33117
|
return;
|
|
31847
33118
|
}
|
|
31848
|
-
out.push(
|
|
33119
|
+
out.push(base2);
|
|
31849
33120
|
}
|
|
31850
33121
|
function diffHarnessManifest(oldManifest, newManifest) {
|
|
31851
33122
|
const changed = [];
|
|
@@ -32005,12 +33276,12 @@ var init_executionContext = __esm({
|
|
|
32005
33276
|
});
|
|
32006
33277
|
|
|
32007
33278
|
// packages/core/dist/runtime/resourcePolicy.js
|
|
32008
|
-
import { createHash as
|
|
33279
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
32009
33280
|
function defaultResourcePolicy(profileId) {
|
|
32010
33281
|
return PROFILE_RESOURCE_POLICIES[profileId] ?? PROFILE_RESOURCE_POLICIES["kraken/v1"];
|
|
32011
33282
|
}
|
|
32012
33283
|
function resourcePolicyHash(policy) {
|
|
32013
|
-
return
|
|
33284
|
+
return createHash6("sha256").update(stableStringify(ResourcePolicySchema.parse(policy))).digest("hex");
|
|
32014
33285
|
}
|
|
32015
33286
|
var BudgetPressureSchema, ResourceStageSchema, PressureThresholdsSchema, DEFAULT_PRESSURE_THRESHOLDS, ResourcePolicySchema, PROFILE_RESOURCE_POLICIES;
|
|
32016
33287
|
var init_resourcePolicy = __esm({
|
|
@@ -32155,6 +33426,257 @@ var init_resourceBudget = __esm({
|
|
|
32155
33426
|
}
|
|
32156
33427
|
});
|
|
32157
33428
|
|
|
33429
|
+
// packages/core/dist/runtime/observers/composeObservers.js
|
|
33430
|
+
function composeObservers(observers) {
|
|
33431
|
+
const composed = {};
|
|
33432
|
+
for (const hook of HOOKS) {
|
|
33433
|
+
composed[hook] = async (event) => {
|
|
33434
|
+
const results = [];
|
|
33435
|
+
for (const observer of observers) {
|
|
33436
|
+
const callback = observer[hook];
|
|
33437
|
+
if (typeof callback === "function") {
|
|
33438
|
+
results.push(await callback(event) ?? CONTINUE);
|
|
33439
|
+
}
|
|
33440
|
+
}
|
|
33441
|
+
return resolveInterventions(results);
|
|
33442
|
+
};
|
|
33443
|
+
}
|
|
33444
|
+
return composed;
|
|
33445
|
+
}
|
|
33446
|
+
var HOOKS;
|
|
33447
|
+
var init_composeObservers = __esm({
|
|
33448
|
+
"packages/core/dist/runtime/observers/composeObservers.js"() {
|
|
33449
|
+
"use strict";
|
|
33450
|
+
init_types2();
|
|
33451
|
+
init_resolve();
|
|
33452
|
+
HOOKS = [
|
|
33453
|
+
"onRunStart",
|
|
33454
|
+
"onModelAttempt",
|
|
33455
|
+
"onModelDelta",
|
|
33456
|
+
"onModelResponse",
|
|
33457
|
+
"onToolCall",
|
|
33458
|
+
"onToolResult",
|
|
33459
|
+
"onTurnEnd",
|
|
33460
|
+
"onRunEnd",
|
|
33461
|
+
"onCancelled"
|
|
33462
|
+
];
|
|
33463
|
+
}
|
|
33464
|
+
});
|
|
33465
|
+
|
|
33466
|
+
// packages/core/dist/runtime/observers/index.js
|
|
33467
|
+
var init_observers = __esm({
|
|
33468
|
+
"packages/core/dist/runtime/observers/index.js"() {
|
|
33469
|
+
"use strict";
|
|
33470
|
+
init_types2();
|
|
33471
|
+
init_resolve();
|
|
33472
|
+
init_ObserverBus();
|
|
33473
|
+
init_composeObservers();
|
|
33474
|
+
init_TraceObserver();
|
|
33475
|
+
init_MetricsObserver();
|
|
33476
|
+
}
|
|
33477
|
+
});
|
|
33478
|
+
|
|
33479
|
+
// packages/core/dist/runtime/guards/index.js
|
|
33480
|
+
var init_guards = __esm({
|
|
33481
|
+
"packages/core/dist/runtime/guards/index.js"() {
|
|
33482
|
+
"use strict";
|
|
33483
|
+
init_RepetitionGuard();
|
|
33484
|
+
init_FailureSignatureGuard();
|
|
33485
|
+
init_DuplicateSearchGuard();
|
|
33486
|
+
init_NoProgressGuard();
|
|
33487
|
+
init_ReasoningWatchdog();
|
|
33488
|
+
}
|
|
33489
|
+
});
|
|
33490
|
+
|
|
33491
|
+
// packages/core/dist/runtime/recorder/retention.js
|
|
33492
|
+
import { readdir, readFile, rm, stat } from "node:fs/promises";
|
|
33493
|
+
import { join as join13 } from "node:path";
|
|
33494
|
+
function runRetentionFromEnv() {
|
|
33495
|
+
const parseDays = Number(process.env.ZELARI_RUN_RETENTION_DAYS);
|
|
33496
|
+
const parseMb = Number(process.env.ZELARI_RUN_RETENTION_MAX_MB);
|
|
33497
|
+
return {
|
|
33498
|
+
maxAgeDays: Number.isFinite(parseDays) && parseDays > 0 ? parseDays : DEFAULT_RUN_RETENTION_DAYS,
|
|
33499
|
+
maxTotalBytes: Number.isFinite(parseMb) && parseMb > 0 ? Math.round(parseMb * 1024 * 1024) : DEFAULT_RUN_RETENTION_MAX_MB * 1024 * 1024
|
|
33500
|
+
};
|
|
33501
|
+
}
|
|
33502
|
+
async function dirSize(path72) {
|
|
33503
|
+
let total = 0;
|
|
33504
|
+
let entries;
|
|
33505
|
+
try {
|
|
33506
|
+
entries = await readdir(path72, { withFileTypes: true });
|
|
33507
|
+
} catch {
|
|
33508
|
+
return 0;
|
|
33509
|
+
}
|
|
33510
|
+
for (const entry of entries) {
|
|
33511
|
+
const child = join13(path72, entry.name);
|
|
33512
|
+
if (entry.isDirectory())
|
|
33513
|
+
total += await dirSize(child);
|
|
33514
|
+
else {
|
|
33515
|
+
try {
|
|
33516
|
+
total += (await stat(child)).size;
|
|
33517
|
+
} catch {
|
|
33518
|
+
}
|
|
33519
|
+
}
|
|
33520
|
+
}
|
|
33521
|
+
return total;
|
|
33522
|
+
}
|
|
33523
|
+
async function enforceRunRetention(runsDir, options = {}) {
|
|
33524
|
+
const now = options.now ?? Date.now;
|
|
33525
|
+
const maxAgeDays = options.maxAgeDays ?? DEFAULT_RUN_RETENTION_DAYS;
|
|
33526
|
+
const maxTotalBytes = options.maxTotalBytes ?? DEFAULT_RUN_RETENTION_MAX_MB * 1024 * 1024;
|
|
33527
|
+
const result = { deleted: [], freedBytes: 0, kept: 0 };
|
|
33528
|
+
let entries;
|
|
33529
|
+
try {
|
|
33530
|
+
entries = await readdir(runsDir, { withFileTypes: true });
|
|
33531
|
+
} catch {
|
|
33532
|
+
return result;
|
|
33533
|
+
}
|
|
33534
|
+
const infos = [];
|
|
33535
|
+
for (const entry of entries) {
|
|
33536
|
+
if (!entry.isDirectory())
|
|
33537
|
+
continue;
|
|
33538
|
+
const path72 = join13(runsDir, entry.name);
|
|
33539
|
+
let startedAt = 0;
|
|
33540
|
+
let endedAt;
|
|
33541
|
+
let completed = false;
|
|
33542
|
+
try {
|
|
33543
|
+
const manifest = JSON.parse(await readFile(join13(path72, "manifest.json"), "utf8"));
|
|
33544
|
+
startedAt = manifest.startedAt ?? 0;
|
|
33545
|
+
endedAt = manifest.endedAt;
|
|
33546
|
+
completed = Boolean(endedAt) && manifest.status !== "running";
|
|
33547
|
+
} catch {
|
|
33548
|
+
completed = false;
|
|
33549
|
+
}
|
|
33550
|
+
infos.push({ name: entry.name, path: path72, startedAt, endedAt, completed, bytes: await dirSize(path72) });
|
|
33551
|
+
}
|
|
33552
|
+
const remove = async (info) => {
|
|
33553
|
+
await rm(info.path, { recursive: true, force: true });
|
|
33554
|
+
result.deleted.push(info.name);
|
|
33555
|
+
result.freedBytes += info.bytes;
|
|
33556
|
+
};
|
|
33557
|
+
const ageCutoffMs = maxAgeDays * 24 * 60 * 60 * 1e3;
|
|
33558
|
+
const expired = infos.filter((info) => info.completed && info.startedAt > 0 && now() - info.startedAt > ageCutoffMs).sort((a, b) => a.startedAt - b.startedAt);
|
|
33559
|
+
for (const info of expired)
|
|
33560
|
+
await remove(info);
|
|
33561
|
+
const survivors = infos.filter((info) => !result.deleted.includes(info.name));
|
|
33562
|
+
let totalBytes = survivors.reduce((sum, info) => sum + info.bytes, 0);
|
|
33563
|
+
const byOldest = survivors.filter((info) => info.completed).sort((a, b) => a.startedAt - b.startedAt);
|
|
33564
|
+
for (const info of byOldest) {
|
|
33565
|
+
if (totalBytes <= maxTotalBytes)
|
|
33566
|
+
break;
|
|
33567
|
+
totalBytes -= info.bytes;
|
|
33568
|
+
await remove(info);
|
|
33569
|
+
}
|
|
33570
|
+
result.kept = infos.filter((info) => !result.deleted.includes(info.name)).length;
|
|
33571
|
+
return result;
|
|
33572
|
+
}
|
|
33573
|
+
var DEFAULT_RUN_RETENTION_DAYS, DEFAULT_RUN_RETENTION_MAX_MB;
|
|
33574
|
+
var init_retention = __esm({
|
|
33575
|
+
"packages/core/dist/runtime/recorder/retention.js"() {
|
|
33576
|
+
"use strict";
|
|
33577
|
+
DEFAULT_RUN_RETENTION_DAYS = 30;
|
|
33578
|
+
DEFAULT_RUN_RETENTION_MAX_MB = 2048;
|
|
33579
|
+
}
|
|
33580
|
+
});
|
|
33581
|
+
|
|
33582
|
+
// packages/core/dist/runtime/recorder/index.js
|
|
33583
|
+
var init_recorder = __esm({
|
|
33584
|
+
"packages/core/dist/runtime/recorder/index.js"() {
|
|
33585
|
+
"use strict";
|
|
33586
|
+
init_Redactor();
|
|
33587
|
+
init_RunRecorder();
|
|
33588
|
+
init_recorderObserver();
|
|
33589
|
+
init_retention();
|
|
33590
|
+
}
|
|
33591
|
+
});
|
|
33592
|
+
|
|
33593
|
+
// packages/core/dist/runtime/controls/types.js
|
|
33594
|
+
function isSteerControlEvent(event) {
|
|
33595
|
+
return event.type === "steer";
|
|
33596
|
+
}
|
|
33597
|
+
function isFollowUpControlEvent(event) {
|
|
33598
|
+
return event.type === "follow_up";
|
|
33599
|
+
}
|
|
33600
|
+
function isCancelControlEvent(event) {
|
|
33601
|
+
return event.type === "cancel";
|
|
33602
|
+
}
|
|
33603
|
+
var init_types10 = __esm({
|
|
33604
|
+
"packages/core/dist/runtime/controls/types.js"() {
|
|
33605
|
+
"use strict";
|
|
33606
|
+
}
|
|
33607
|
+
});
|
|
33608
|
+
|
|
33609
|
+
// packages/core/dist/runtime/controls/RuntimeControlQueue.js
|
|
33610
|
+
var RuntimeControlQueue;
|
|
33611
|
+
var init_RuntimeControlQueue = __esm({
|
|
33612
|
+
"packages/core/dist/runtime/controls/RuntimeControlQueue.js"() {
|
|
33613
|
+
"use strict";
|
|
33614
|
+
RuntimeControlQueue = class {
|
|
33615
|
+
items = [];
|
|
33616
|
+
/**
|
|
33617
|
+
* Optional drain listener (CLI control bridge, §24): fired synchronously
|
|
33618
|
+
* whenever a drain* method actually removes events, with the exact events
|
|
33619
|
+
* consumed — lets the host emit `control_applied` at the true boundary.
|
|
33620
|
+
*/
|
|
33621
|
+
onDrained;
|
|
33622
|
+
enqueue(event) {
|
|
33623
|
+
this.items.push(event);
|
|
33624
|
+
}
|
|
33625
|
+
/** Next event in arrival order, without removing it. */
|
|
33626
|
+
peek() {
|
|
33627
|
+
return this.items[0];
|
|
33628
|
+
}
|
|
33629
|
+
get size() {
|
|
33630
|
+
return this.items.length;
|
|
33631
|
+
}
|
|
33632
|
+
/**
|
|
33633
|
+
* Remove a not-yet-applied control by id (Desktop queue UI, §32: removal
|
|
33634
|
+
* stays possible until `control_applied`). Returns true when removed.
|
|
33635
|
+
*/
|
|
33636
|
+
remove(controlId) {
|
|
33637
|
+
const index = this.items.findIndex((event) => event.id === controlId);
|
|
33638
|
+
if (index === -1)
|
|
33639
|
+
return false;
|
|
33640
|
+
this.items.splice(index, 1);
|
|
33641
|
+
return true;
|
|
33642
|
+
}
|
|
33643
|
+
clear() {
|
|
33644
|
+
this.items = [];
|
|
33645
|
+
}
|
|
33646
|
+
/** All pending steers in arrival order; removes them from the queue. */
|
|
33647
|
+
drainSteers() {
|
|
33648
|
+
return this.drainByType("steer");
|
|
33649
|
+
}
|
|
33650
|
+
/** All pending follow-ups in arrival order; removes them from the queue. */
|
|
33651
|
+
drainFollowUps() {
|
|
33652
|
+
return this.drainByType("follow_up");
|
|
33653
|
+
}
|
|
33654
|
+
/** All pending cancels in arrival order; removes them from the queue. */
|
|
33655
|
+
drainCancels() {
|
|
33656
|
+
return this.drainByType("cancel");
|
|
33657
|
+
}
|
|
33658
|
+
drainByType(type) {
|
|
33659
|
+
const matched = this.items.filter((event) => event.type === type);
|
|
33660
|
+
if (matched.length > 0) {
|
|
33661
|
+
this.items = this.items.filter((event) => event.type !== type);
|
|
33662
|
+
this.onDrained?.(matched);
|
|
33663
|
+
}
|
|
33664
|
+
return matched;
|
|
33665
|
+
}
|
|
33666
|
+
};
|
|
33667
|
+
}
|
|
33668
|
+
});
|
|
33669
|
+
|
|
33670
|
+
// packages/core/dist/runtime/controls/index.js
|
|
33671
|
+
var init_controls = __esm({
|
|
33672
|
+
"packages/core/dist/runtime/controls/index.js"() {
|
|
33673
|
+
"use strict";
|
|
33674
|
+
init_types10();
|
|
33675
|
+
init_RuntimeControlQueue();
|
|
33676
|
+
init_SteeringObserver();
|
|
33677
|
+
}
|
|
33678
|
+
});
|
|
33679
|
+
|
|
32158
33680
|
// packages/core/dist/runtime/index.js
|
|
32159
33681
|
var init_runtime2 = __esm({
|
|
32160
33682
|
"packages/core/dist/runtime/index.js"() {
|
|
@@ -32168,6 +33690,295 @@ var init_runtime2 = __esm({
|
|
|
32168
33690
|
init_executionContext();
|
|
32169
33691
|
init_resourcePolicy();
|
|
32170
33692
|
init_resourceBudget();
|
|
33693
|
+
init_observers();
|
|
33694
|
+
init_guards();
|
|
33695
|
+
init_recorder();
|
|
33696
|
+
init_controls();
|
|
33697
|
+
}
|
|
33698
|
+
});
|
|
33699
|
+
|
|
33700
|
+
// packages/core/dist/context/ContextPolicy.js
|
|
33701
|
+
function contextPolicyForRole(role) {
|
|
33702
|
+
return ROLE_POLICIES[role] ?? DEFAULT_CONTEXT_POLICY;
|
|
33703
|
+
}
|
|
33704
|
+
var KRAKEN_LEAD_POLICY, KRAKEN_EXPLORE_POLICY, KRAKEN_GENERAL_POLICY, KRAKEN_VERIFY_POLICY, DEFAULT_CONTEXT_POLICY, ROLE_POLICIES, CONTEXT_POLICY_VERSION;
|
|
33705
|
+
var init_ContextPolicy = __esm({
|
|
33706
|
+
"packages/core/dist/context/ContextPolicy.js"() {
|
|
33707
|
+
"use strict";
|
|
33708
|
+
KRAKEN_LEAD_POLICY = {
|
|
33709
|
+
history: "recent",
|
|
33710
|
+
includeParentSummary: false,
|
|
33711
|
+
includeDurableState: true,
|
|
33712
|
+
includeGraphState: true,
|
|
33713
|
+
includeVerificationState: true,
|
|
33714
|
+
toolResults: "projected"
|
|
33715
|
+
};
|
|
33716
|
+
KRAKEN_EXPLORE_POLICY = {
|
|
33717
|
+
history: "summary",
|
|
33718
|
+
includeParentSummary: true,
|
|
33719
|
+
includeDurableState: true,
|
|
33720
|
+
includeGraphState: false,
|
|
33721
|
+
includeVerificationState: false,
|
|
33722
|
+
toolResults: "projected"
|
|
33723
|
+
};
|
|
33724
|
+
KRAKEN_GENERAL_POLICY = {
|
|
33725
|
+
history: "summary",
|
|
33726
|
+
includeParentSummary: true,
|
|
33727
|
+
includeDurableState: true,
|
|
33728
|
+
includeGraphState: true,
|
|
33729
|
+
includeVerificationState: false,
|
|
33730
|
+
toolResults: "projected"
|
|
33731
|
+
};
|
|
33732
|
+
KRAKEN_VERIFY_POLICY = {
|
|
33733
|
+
history: "summary",
|
|
33734
|
+
includeParentSummary: true,
|
|
33735
|
+
includeDurableState: false,
|
|
33736
|
+
includeGraphState: true,
|
|
33737
|
+
includeVerificationState: true,
|
|
33738
|
+
toolResults: "projected"
|
|
33739
|
+
};
|
|
33740
|
+
DEFAULT_CONTEXT_POLICY = {
|
|
33741
|
+
history: "recent",
|
|
33742
|
+
includeParentSummary: false,
|
|
33743
|
+
includeDurableState: false,
|
|
33744
|
+
includeGraphState: false,
|
|
33745
|
+
includeVerificationState: false,
|
|
33746
|
+
toolResults: "projected"
|
|
33747
|
+
};
|
|
33748
|
+
ROLE_POLICIES = {
|
|
33749
|
+
lead: KRAKEN_LEAD_POLICY,
|
|
33750
|
+
explore: KRAKEN_EXPLORE_POLICY,
|
|
33751
|
+
general: KRAKEN_GENERAL_POLICY,
|
|
33752
|
+
verify: KRAKEN_VERIFY_POLICY,
|
|
33753
|
+
council: DEFAULT_CONTEXT_POLICY,
|
|
33754
|
+
mission: DEFAULT_CONTEXT_POLICY
|
|
33755
|
+
};
|
|
33756
|
+
CONTEXT_POLICY_VERSION = 1;
|
|
33757
|
+
}
|
|
33758
|
+
});
|
|
33759
|
+
|
|
33760
|
+
// packages/core/dist/context/ContextProjector.js
|
|
33761
|
+
function groupTurnUnits(history2) {
|
|
33762
|
+
const units = [];
|
|
33763
|
+
let i = 0;
|
|
33764
|
+
while (i < history2.length) {
|
|
33765
|
+
const msg = history2[i];
|
|
33766
|
+
if (msg.role === "assistant") {
|
|
33767
|
+
const unit2 = [msg];
|
|
33768
|
+
i++;
|
|
33769
|
+
while (i < history2.length && history2[i].role === "tool") {
|
|
33770
|
+
unit2.push(history2[i]);
|
|
33771
|
+
i++;
|
|
33772
|
+
}
|
|
33773
|
+
units.push({ messages: unit2, kind: "assistant" });
|
|
33774
|
+
} else if (msg.role === "tool") {
|
|
33775
|
+
units.push({ messages: [msg], kind: "orphan-tool" });
|
|
33776
|
+
i++;
|
|
33777
|
+
} else {
|
|
33778
|
+
units.push({ messages: [msg], kind: msg.role === "user" ? "user" : "other" });
|
|
33779
|
+
i++;
|
|
33780
|
+
}
|
|
33781
|
+
}
|
|
33782
|
+
return units;
|
|
33783
|
+
}
|
|
33784
|
+
function firstLine(text, max) {
|
|
33785
|
+
const line = text.split("\n", 1)[0] ?? "";
|
|
33786
|
+
return line.length > max ? `${line.slice(0, max)}\u2026` : line;
|
|
33787
|
+
}
|
|
33788
|
+
function renderHistoryDigest(units) {
|
|
33789
|
+
const lines = units.map((unit2) => {
|
|
33790
|
+
const head = unit2.messages[0];
|
|
33791
|
+
if (unit2.kind === "user")
|
|
33792
|
+
return `- user: ${firstLine(head.content, 120)}`;
|
|
33793
|
+
if (unit2.kind === "assistant") {
|
|
33794
|
+
const tools = head.toolCalls?.map((t) => t.name).join(", ");
|
|
33795
|
+
return tools ? `- assistant (tools: ${tools})` : `- assistant: ${firstLine(head.content, 120)}`;
|
|
33796
|
+
}
|
|
33797
|
+
if (unit2.kind === "orphan-tool")
|
|
33798
|
+
return `- tool result ${head.toolCallId ?? "?"}: omitted`;
|
|
33799
|
+
return `- ${head.role}: ${firstLine(head.content, 120)}`;
|
|
33800
|
+
});
|
|
33801
|
+
return `[Context digest \u2014 earlier turns omitted]
|
|
33802
|
+
${lines.join("\n")}`;
|
|
33803
|
+
}
|
|
33804
|
+
function truncateProjected(content, maxChars) {
|
|
33805
|
+
if (content.length <= maxChars)
|
|
33806
|
+
return content;
|
|
33807
|
+
const markerLen = TRUNCATION_MARKER.length;
|
|
33808
|
+
const budget = Math.max(maxChars - markerLen, HEAD_TAIL_MIN * 2);
|
|
33809
|
+
const head = Math.floor(budget / 2);
|
|
33810
|
+
const tail2 = budget - head;
|
|
33811
|
+
return `${content.slice(0, head)}${TRUNCATION_MARKER}${content.slice(-tail2)}`;
|
|
33812
|
+
}
|
|
33813
|
+
function summarizeToolResult(content) {
|
|
33814
|
+
const line = firstLine(content, 200);
|
|
33815
|
+
return `[tool result \u2014 ${content.length} chars, first line] ${line}`;
|
|
33816
|
+
}
|
|
33817
|
+
function applyToolResultPolicy(messages, policy) {
|
|
33818
|
+
if (policy.toolResults === "full")
|
|
33819
|
+
return { messages, truncated: 0 };
|
|
33820
|
+
const maxChars = policy.maxToolResultChars ?? DEFAULT_MAX_TOOL_RESULT_CHARS;
|
|
33821
|
+
let truncated = 0;
|
|
33822
|
+
const out = messages.map((msg) => {
|
|
33823
|
+
if (msg.role !== "tool")
|
|
33824
|
+
return msg;
|
|
33825
|
+
if (policy.toolResults === "summary-only") {
|
|
33826
|
+
truncated++;
|
|
33827
|
+
return { ...msg, content: summarizeToolResult(msg.content) };
|
|
33828
|
+
}
|
|
33829
|
+
if (msg.content.length > maxChars)
|
|
33830
|
+
truncated++;
|
|
33831
|
+
return { ...msg, content: truncateProjected(msg.content, maxChars) };
|
|
33832
|
+
});
|
|
33833
|
+
return { messages: out, truncated };
|
|
33834
|
+
}
|
|
33835
|
+
function estimateTokens(messages) {
|
|
33836
|
+
let chars = 0;
|
|
33837
|
+
for (const m of messages) {
|
|
33838
|
+
chars += m.content.length;
|
|
33839
|
+
if (m.toolCalls)
|
|
33840
|
+
chars += JSON.stringify(m.toolCalls).length;
|
|
33841
|
+
if (m.reasoningContent)
|
|
33842
|
+
chars += m.reasoningContent.length;
|
|
33843
|
+
}
|
|
33844
|
+
return Math.ceil(chars / 4);
|
|
33845
|
+
}
|
|
33846
|
+
function projectContext(transcript, policy) {
|
|
33847
|
+
const system = transcript.filter((m) => m.role === "system");
|
|
33848
|
+
const body = transcript.filter((m) => m.role !== "system");
|
|
33849
|
+
let lastUserIdx = -1;
|
|
33850
|
+
for (let i = body.length - 1; i >= 0; i--) {
|
|
33851
|
+
if (body[i].role === "user") {
|
|
33852
|
+
lastUserIdx = i;
|
|
33853
|
+
break;
|
|
33854
|
+
}
|
|
33855
|
+
}
|
|
33856
|
+
const history2 = lastUserIdx >= 0 ? body.slice(0, lastUserIdx) : body.slice();
|
|
33857
|
+
const tail2 = lastUserIdx >= 0 ? body.slice(lastUserIdx) : [];
|
|
33858
|
+
const units = groupTurnUnits(history2);
|
|
33859
|
+
const maxTurns = policy.maxHistoryTurns ?? DEFAULT_MAX_HISTORY_TURNS;
|
|
33860
|
+
let selected = [];
|
|
33861
|
+
let digest = false;
|
|
33862
|
+
let includedUnits = 0;
|
|
33863
|
+
if (policy.history === "full") {
|
|
33864
|
+
selected = history2.slice();
|
|
33865
|
+
includedUnits = units.length;
|
|
33866
|
+
} else if (policy.history === "recent") {
|
|
33867
|
+
const keep = units.slice(-maxTurns);
|
|
33868
|
+
includedUnits = keep.length;
|
|
33869
|
+
selected = keep.flatMap((u) => u.messages);
|
|
33870
|
+
} else if (policy.history === "summary") {
|
|
33871
|
+
const recentUnits = units.slice(-2);
|
|
33872
|
+
includedUnits = recentUnits.length;
|
|
33873
|
+
selected = recentUnits.flatMap((u) => u.messages);
|
|
33874
|
+
if (units.length > recentUnits.length) {
|
|
33875
|
+
digest = true;
|
|
33876
|
+
selected.unshift({
|
|
33877
|
+
role: "user",
|
|
33878
|
+
content: renderHistoryDigest(units.slice(0, units.length - recentUnits.length))
|
|
33879
|
+
});
|
|
33880
|
+
}
|
|
33881
|
+
}
|
|
33882
|
+
const includedMessages = selected.length + tail2.length + system.length;
|
|
33883
|
+
const assembled = [...system, ...selected, ...tail2];
|
|
33884
|
+
const { messages, truncated } = applyToolResultPolicy(assembled, policy);
|
|
33885
|
+
return {
|
|
33886
|
+
messages,
|
|
33887
|
+
stats: {
|
|
33888
|
+
estimatedTokens: estimateTokens(messages),
|
|
33889
|
+
includedMessages,
|
|
33890
|
+
omittedMessages: Math.max(0, history2.length - selected.length - (digest ? 1 : 0)),
|
|
33891
|
+
truncatedToolResults: truncated,
|
|
33892
|
+
digest
|
|
33893
|
+
}
|
|
33894
|
+
};
|
|
33895
|
+
}
|
|
33896
|
+
var DEFAULT_MAX_TOOL_RESULT_CHARS, DEFAULT_MAX_HISTORY_TURNS, TRUNCATION_MARKER, HEAD_TAIL_MIN;
|
|
33897
|
+
var init_ContextProjector = __esm({
|
|
33898
|
+
"packages/core/dist/context/ContextProjector.js"() {
|
|
33899
|
+
"use strict";
|
|
33900
|
+
DEFAULT_MAX_TOOL_RESULT_CHARS = 12e3;
|
|
33901
|
+
DEFAULT_MAX_HISTORY_TURNS = 20;
|
|
33902
|
+
TRUNCATION_MARKER = "\n[\u2026tool output truncated by context projection\u2026]\n";
|
|
33903
|
+
HEAD_TAIL_MIN = 200;
|
|
33904
|
+
}
|
|
33905
|
+
});
|
|
33906
|
+
|
|
33907
|
+
// packages/core/dist/context/parentContext.js
|
|
33908
|
+
function renderCompact(m) {
|
|
33909
|
+
if (m.role === "user") {
|
|
33910
|
+
const text2 = m.content.trim();
|
|
33911
|
+
return text2 ? `user \u2014 ${text2}` : null;
|
|
33912
|
+
}
|
|
33913
|
+
if (m.role === "assistant") {
|
|
33914
|
+
const tools = m.toolCalls?.length ? ` (requested: ${m.toolCalls.map((t) => t.name).join(", ")})` : "";
|
|
33915
|
+
const text2 = m.content.trim();
|
|
33916
|
+
return text2 ? `assistant${tools} \u2014 ${text2}` : tools ? `assistant${tools}` : null;
|
|
33917
|
+
}
|
|
33918
|
+
if (m.role === "tool") {
|
|
33919
|
+
const text2 = m.content.trim();
|
|
33920
|
+
return text2 ? `tool result \u2014 ${text2}` : null;
|
|
33921
|
+
}
|
|
33922
|
+
const text = m.content.trim();
|
|
33923
|
+
return text ? `${m.role} \u2014 ${text}` : null;
|
|
33924
|
+
}
|
|
33925
|
+
function parentContextForRole(role, transcript, opts) {
|
|
33926
|
+
const policy = contextPolicyForRole(role);
|
|
33927
|
+
const body = transcript.filter((m) => m.role !== "system");
|
|
33928
|
+
if (!policy.includeParentSummary || body.length === 0)
|
|
33929
|
+
return null;
|
|
33930
|
+
const projected = projectContext([...body], {
|
|
33931
|
+
...policy,
|
|
33932
|
+
history: "summary",
|
|
33933
|
+
toolResults: "summary-only"
|
|
33934
|
+
});
|
|
33935
|
+
const lines = [];
|
|
33936
|
+
for (const m of projected.messages) {
|
|
33937
|
+
const line = renderCompact(m);
|
|
33938
|
+
if (line)
|
|
33939
|
+
lines.push(line);
|
|
33940
|
+
}
|
|
33941
|
+
if (lines.length === 0)
|
|
33942
|
+
return null;
|
|
33943
|
+
const maxChars = opts?.maxBlockChars ?? DEFAULT_MAX_BLOCK_CHARS;
|
|
33944
|
+
let body_ = lines.join("\n");
|
|
33945
|
+
let truncated = false;
|
|
33946
|
+
if (body_.length > maxChars) {
|
|
33947
|
+
body_ = body_.slice(0, maxChars) + TRUNCATION_TAIL;
|
|
33948
|
+
truncated = true;
|
|
33949
|
+
}
|
|
33950
|
+
const header = truncated ? "[Parent agent context \u2014 projected summary, full transcript not shared]" : "[Parent agent context \u2014 projected summary]";
|
|
33951
|
+
return {
|
|
33952
|
+
block: `---
|
|
33953
|
+
${header}
|
|
33954
|
+
|
|
33955
|
+
${body_}
|
|
33956
|
+
---`,
|
|
33957
|
+
stats: {
|
|
33958
|
+
estimatedTokens: Math.ceil(body_.length / 4),
|
|
33959
|
+
sourceMessages: body.length,
|
|
33960
|
+
digest: projected.stats.digest
|
|
33961
|
+
}
|
|
33962
|
+
};
|
|
33963
|
+
}
|
|
33964
|
+
var DEFAULT_MAX_BLOCK_CHARS, TRUNCATION_TAIL;
|
|
33965
|
+
var init_parentContext = __esm({
|
|
33966
|
+
"packages/core/dist/context/parentContext.js"() {
|
|
33967
|
+
"use strict";
|
|
33968
|
+
init_ContextPolicy();
|
|
33969
|
+
init_ContextProjector();
|
|
33970
|
+
DEFAULT_MAX_BLOCK_CHARS = 6e3;
|
|
33971
|
+
TRUNCATION_TAIL = "\n[\u2026parent context truncated to fit the role budget\u2026]";
|
|
33972
|
+
}
|
|
33973
|
+
});
|
|
33974
|
+
|
|
33975
|
+
// packages/core/dist/context/index.js
|
|
33976
|
+
var init_context3 = __esm({
|
|
33977
|
+
"packages/core/dist/context/index.js"() {
|
|
33978
|
+
"use strict";
|
|
33979
|
+
init_ContextPolicy();
|
|
33980
|
+
init_ContextProjector();
|
|
33981
|
+
init_parentContext();
|
|
32171
33982
|
}
|
|
32172
33983
|
});
|
|
32173
33984
|
|
|
@@ -32178,7 +33989,7 @@ function isEventBackedEvidence(ref) {
|
|
|
32178
33989
|
return typeof ref.seq === "number" && ref.seq > 0;
|
|
32179
33990
|
}
|
|
32180
33991
|
var CriterionSourceSchema, CommandCheckSchema, FileExistsCheckSchema, FileContainsCheckSchema, FileAbsentCheckSchema, NoneCheckSchema, DeterministicCheckSchema, CriterionSchema, EvidenceTierSchema, EvidenceRefSchema, EVENT_BACKED_EVIDENCE_TIERS, VerificationStatusSchema, VerificationSourceSchema, VerificationResultSchema;
|
|
32181
|
-
var
|
|
33992
|
+
var init_types11 = __esm({
|
|
32182
33993
|
"packages/core/dist/verification/types.js"() {
|
|
32183
33994
|
"use strict";
|
|
32184
33995
|
init_zod();
|
|
@@ -32344,9 +34155,9 @@ var init_scopeDiscipline = __esm({
|
|
|
32344
34155
|
});
|
|
32345
34156
|
|
|
32346
34157
|
// packages/core/dist/verification/engine.js
|
|
32347
|
-
import { createHash as
|
|
34158
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
32348
34159
|
function defaultSha256(input) {
|
|
32349
|
-
return
|
|
34160
|
+
return createHash7("sha256").update(input).digest("hex");
|
|
32350
34161
|
}
|
|
32351
34162
|
function tail(text, max = 400) {
|
|
32352
34163
|
return text.length > max ? `\u2026${text.slice(text.length - max)}` : text;
|
|
@@ -32419,13 +34230,13 @@ var init_engine = __esm({
|
|
|
32419
34230
|
}
|
|
32420
34231
|
async evaluateOne(criterion, scope) {
|
|
32421
34232
|
const started = this.options.now?.() ?? Date.now();
|
|
32422
|
-
const
|
|
34233
|
+
const base2 = {
|
|
32423
34234
|
criterionId: criterion.id,
|
|
32424
34235
|
source: "deterministic-engine",
|
|
32425
34236
|
evaluatedAt: started
|
|
32426
34237
|
};
|
|
32427
34238
|
const done = (patch) => ({
|
|
32428
|
-
...
|
|
34239
|
+
...base2,
|
|
32429
34240
|
...patch,
|
|
32430
34241
|
durationMs: Math.max(0, (this.options.now?.() ?? Date.now()) - started)
|
|
32431
34242
|
});
|
|
@@ -32649,7 +34460,7 @@ var STRICT_ALL_POLICY, DETERMINISTIC_EVIDENCE_TIERS, STRICT_BUILD_POLICY, strict
|
|
|
32649
34460
|
var init_completionPolicy = __esm({
|
|
32650
34461
|
"packages/core/dist/verification/completionPolicy.js"() {
|
|
32651
34462
|
"use strict";
|
|
32652
|
-
|
|
34463
|
+
init_types11();
|
|
32653
34464
|
STRICT_ALL_POLICY = { mode: "strict", required: "*" };
|
|
32654
34465
|
DETERMINISTIC_EVIDENCE_TIERS = [
|
|
32655
34466
|
"tool-output",
|
|
@@ -32922,9 +34733,9 @@ var init_verifier = __esm({
|
|
|
32922
34733
|
/** Review a claimed completion. Degrades to a declared discrete fallback. */
|
|
32923
34734
|
async reviewCompletion(request) {
|
|
32924
34735
|
const effective = this.effectiveModel(request.session);
|
|
32925
|
-
const
|
|
34736
|
+
const base2 = { effectiveModel: effective, usedLogprobs: false };
|
|
32926
34737
|
if (!this.config.enabled) {
|
|
32927
|
-
return { ...
|
|
34738
|
+
return { ...base2, verdict: "unknown", fallback: "discrete", rationale: "verifier disabled" };
|
|
32928
34739
|
}
|
|
32929
34740
|
let response;
|
|
32930
34741
|
try {
|
|
@@ -32941,7 +34752,7 @@ var init_verifier = __esm({
|
|
|
32941
34752
|
});
|
|
32942
34753
|
} catch (err) {
|
|
32943
34754
|
const review2 = {
|
|
32944
|
-
...
|
|
34755
|
+
...base2,
|
|
32945
34756
|
verdict: "unknown",
|
|
32946
34757
|
fallback: "discrete",
|
|
32947
34758
|
rationale: `verifier call failed: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -32952,7 +34763,7 @@ var init_verifier = __esm({
|
|
|
32952
34763
|
const parsed = ReviewOutputSchema.safeParse(extractJson(response.text));
|
|
32953
34764
|
if (!parsed.success) {
|
|
32954
34765
|
const review2 = {
|
|
32955
|
-
...
|
|
34766
|
+
...base2,
|
|
32956
34767
|
verdict: "unknown",
|
|
32957
34768
|
fallback: "discrete",
|
|
32958
34769
|
rationale: "verifier output unparseable \u2014 declared discrete fallback",
|
|
@@ -32967,7 +34778,7 @@ var init_verifier = __esm({
|
|
|
32967
34778
|
}
|
|
32968
34779
|
const blockedByDeterministic = request.results.some((r) => r.status === "fail" && parsed.data.verdict === "confirmed");
|
|
32969
34780
|
const review = {
|
|
32970
|
-
...
|
|
34781
|
+
...base2,
|
|
32971
34782
|
verdict: blockedByDeterministic ? "unknown" : parsed.data.verdict,
|
|
32972
34783
|
score: parsed.data.score,
|
|
32973
34784
|
rationale: blockedByDeterministic ? "cannot confirm while a deterministic check failed \u2014 downgraded to unknown" : parsed.data.rationale,
|
|
@@ -33141,7 +34952,7 @@ __export(verification_exports, {
|
|
|
33141
34952
|
var init_verification2 = __esm({
|
|
33142
34953
|
"packages/core/dist/verification/index.js"() {
|
|
33143
34954
|
"use strict";
|
|
33144
|
-
|
|
34955
|
+
init_types11();
|
|
33145
34956
|
init_engine();
|
|
33146
34957
|
init_completionPolicy();
|
|
33147
34958
|
init_sessionEvidence();
|
|
@@ -33216,12 +35027,12 @@ function requiredBlockers(progress) {
|
|
|
33216
35027
|
}
|
|
33217
35028
|
function evaluateMissionContinuation(input) {
|
|
33218
35029
|
const { progress, verifier, budget, userSteer } = input;
|
|
33219
|
-
const
|
|
35030
|
+
const base2 = { goalRewrite: false, doneByScore: false };
|
|
33220
35031
|
const trend = verifier ? { tier: verifier.tier, value: verifier.value } : void 0;
|
|
33221
35032
|
const blockers = requiredBlockers(progress);
|
|
33222
35033
|
if (userSteer === "stop") {
|
|
33223
35034
|
return {
|
|
33224
|
-
...
|
|
35035
|
+
...base2,
|
|
33225
35036
|
recommendation: "wind-down",
|
|
33226
35037
|
rationale: "user steer: explicit stop \u2014 winding down without claiming done",
|
|
33227
35038
|
blockers,
|
|
@@ -33230,7 +35041,7 @@ function evaluateMissionContinuation(input) {
|
|
|
33230
35041
|
}
|
|
33231
35042
|
if (userSteer === "continue") {
|
|
33232
35043
|
return {
|
|
33233
|
-
...
|
|
35044
|
+
...base2,
|
|
33234
35045
|
recommendation: "continue",
|
|
33235
35046
|
rationale: "user steer: explicit continue \u2014 overrides any trend-derived advice",
|
|
33236
35047
|
blockers,
|
|
@@ -33239,7 +35050,7 @@ function evaluateMissionContinuation(input) {
|
|
|
33239
35050
|
}
|
|
33240
35051
|
if (budget && budget.iterationsUsed >= budget.iterationsMax) {
|
|
33241
35052
|
return {
|
|
33242
|
-
...
|
|
35053
|
+
...base2,
|
|
33243
35054
|
recommendation: "hold-for-user",
|
|
33244
35055
|
rationale: `iteration budget exhausted (${budget.iterationsUsed}/${budget.iterationsMax}) \u2014 operator decides: raise budget or hand off`,
|
|
33245
35056
|
blockers,
|
|
@@ -33249,7 +35060,7 @@ function evaluateMissionContinuation(input) {
|
|
|
33249
35060
|
if (blockers.length > 0) {
|
|
33250
35061
|
const trendNote = verifier ? ` \xB7 verifier trend recorded as context only (tier ${verifier.tier}${verifier.value === null ? "" : `, ${verifier.value.toFixed(2)}`}) \u2014 trend is never authority` : "";
|
|
33251
35062
|
return {
|
|
33252
|
-
...
|
|
35063
|
+
...base2,
|
|
33253
35064
|
recommendation: "continue",
|
|
33254
35065
|
rationale: `required criteria incomplete \u2192 no early-stop${trendNote}`,
|
|
33255
35066
|
blockers,
|
|
@@ -33260,7 +35071,7 @@ function evaluateMissionContinuation(input) {
|
|
|
33260
35071
|
const rejected = verifier?.verdict === "rejected" || blended !== null && blended <= REJECTED_BLEND;
|
|
33261
35072
|
if (rejected) {
|
|
33262
35073
|
return {
|
|
33263
|
-
...
|
|
35074
|
+
...base2,
|
|
33264
35075
|
recommendation: "hold-for-user",
|
|
33265
35076
|
rationale: "deterministic evidence is complete and PASSing, but the verifier flags risk \u2014 attention requested; the deterministic verdict stands untouched",
|
|
33266
35077
|
blockers: [],
|
|
@@ -33269,7 +35080,7 @@ function evaluateMissionContinuation(input) {
|
|
|
33269
35080
|
}
|
|
33270
35081
|
const confirmed = verifier?.verdict === "confirmed" || blended !== null && blended >= CONFIRMED_BLEND;
|
|
33271
35082
|
return {
|
|
33272
|
-
...
|
|
35083
|
+
...base2,
|
|
33273
35084
|
recommendation: "wind-down",
|
|
33274
35085
|
rationale: confirmed ? "required criteria pass with evidence and the verifier confirms \u2014 candidate done (final say: driver + CompletionPolicy)" : "required criteria pass with evidence \u2014 candidate done on deterministic evidence (final say: driver + CompletionPolicy)",
|
|
33275
35086
|
blockers: [],
|
|
@@ -33287,14 +35098,14 @@ var init_continuationPolicy = __esm({
|
|
|
33287
35098
|
|
|
33288
35099
|
// packages/core/dist/mission/budgetContinuation.js
|
|
33289
35100
|
function evaluateBudgetContinuation(input) {
|
|
33290
|
-
const
|
|
35101
|
+
const base2 = { passByBudget: false };
|
|
33291
35102
|
const { verdict, budget, pressure, latestGapKey, repairHistory } = input;
|
|
33292
35103
|
if (verdict === "PASS") {
|
|
33293
|
-
return { ...
|
|
35104
|
+
return { ...base2, decision: "complete", rationale: "deterministic PASS \u2014 complete without spending residual budget" };
|
|
33294
35105
|
}
|
|
33295
35106
|
if (pressure === "critical" && budget.toolCalls.remaining <= budget.reserve.verification) {
|
|
33296
35107
|
return {
|
|
33297
|
-
...
|
|
35108
|
+
...base2,
|
|
33298
35109
|
decision: "hold",
|
|
33299
35110
|
rationale: `critical pressure (${budget.toolCalls.remaining}/${budget.toolCalls.limit} left, reserve ${budget.reserve.verification} protected) \u2014 hold for operator instead of a doomed repair`
|
|
33300
35111
|
};
|
|
@@ -33303,11 +35114,11 @@ function evaluateBudgetContinuation(input) {
|
|
|
33303
35114
|
if (sameGapRepairs >= MAX_SAME_GAP_REPAIRS) {
|
|
33304
35115
|
const canPivot = budget.toolCalls.remaining - budget.reserve.verification >= 3;
|
|
33305
35116
|
return canPivot ? {
|
|
33306
|
-
...
|
|
35117
|
+
...base2,
|
|
33307
35118
|
decision: "pivot",
|
|
33308
35119
|
rationale: `gap "${latestGapKey}" unchanged after ${sameGapRepairs} repairs \u2014 pivot approach while budget remains`
|
|
33309
35120
|
} : {
|
|
33310
|
-
...
|
|
35121
|
+
...base2,
|
|
33311
35122
|
decision: "hold",
|
|
33312
35123
|
rationale: `gap "${latestGapKey}" unchanged after ${sameGapRepairs} repairs and no headroom to pivot \u2014 hold`
|
|
33313
35124
|
};
|
|
@@ -33315,19 +35126,19 @@ function evaluateBudgetContinuation(input) {
|
|
|
33315
35126
|
const repairHeadroom = budget.toolCalls.remaining - budget.reserve.verification;
|
|
33316
35127
|
if (repairHeadroom > 0) {
|
|
33317
35128
|
return {
|
|
33318
|
-
...
|
|
35129
|
+
...base2,
|
|
33319
35130
|
decision: "repair",
|
|
33320
35131
|
rationale: `${repairHeadroom} spendable tool calls (pressure ${pressure}) \u2014 targeted repair on the known gap`
|
|
33321
35132
|
};
|
|
33322
35133
|
}
|
|
33323
35134
|
if (budget.toolCalls.remaining > 0) {
|
|
33324
35135
|
return {
|
|
33325
|
-
...
|
|
35136
|
+
...base2,
|
|
33326
35137
|
decision: "hold",
|
|
33327
35138
|
rationale: "only the protected verification reserve remains \u2014 verify/finalize or hold, no further repair"
|
|
33328
35139
|
};
|
|
33329
35140
|
}
|
|
33330
|
-
return { ...
|
|
35141
|
+
return { ...base2, decision: "hold", rationale: "budget exhausted \u2014 hold (BLOCKED, never a false done)" };
|
|
33331
35142
|
}
|
|
33332
35143
|
var MAX_SAME_GAP_REPAIRS;
|
|
33333
35144
|
var init_budgetContinuation = __esm({
|
|
@@ -33357,7 +35168,7 @@ var init_version = __esm({
|
|
|
33357
35168
|
});
|
|
33358
35169
|
|
|
33359
35170
|
// packages/core/dist/runtime/fingerprints.js
|
|
33360
|
-
import { createHash as
|
|
35171
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
33361
35172
|
function toolFingerprintHash(tools) {
|
|
33362
35173
|
const canonical = [...tools].map((t) => ({
|
|
33363
35174
|
name: t.name,
|
|
@@ -33366,7 +35177,7 @@ function toolFingerprintHash(tools) {
|
|
|
33366
35177
|
...t.outputContractVersion !== void 0 ? { outputContractVersion: t.outputContractVersion } : {},
|
|
33367
35178
|
...t.capabilityFlags !== void 0 ? { capabilityFlags: [...t.capabilityFlags].sort() } : {}
|
|
33368
35179
|
})).sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
33369
|
-
return
|
|
35180
|
+
return createHash8("sha256").update(stableStringify(canonical)).digest("hex");
|
|
33370
35181
|
}
|
|
33371
35182
|
function skillFingerprintHash(skills) {
|
|
33372
35183
|
const canonical = [...skills].map((s) => ({
|
|
@@ -33374,7 +35185,7 @@ function skillFingerprintHash(skills) {
|
|
|
33374
35185
|
...s.version !== void 0 ? { version: s.version } : {},
|
|
33375
35186
|
...s.contentDigest !== void 0 ? { contentDigest: s.contentDigest } : {}
|
|
33376
35187
|
})).sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
|
|
33377
|
-
return
|
|
35188
|
+
return createHash8("sha256").update(stableStringify(canonical)).digest("hex");
|
|
33378
35189
|
}
|
|
33379
35190
|
var init_fingerprints = __esm({
|
|
33380
35191
|
"packages/core/dist/runtime/fingerprints.js"() {
|
|
@@ -33405,17 +35216,22 @@ __export(dist_exports, {
|
|
|
33405
35216
|
CODING_SKILL_CATALOG: () => CODING_SKILL_CATALOG,
|
|
33406
35217
|
COLLABORATION_DIRECTIVE: () => COLLABORATION_DIRECTIVE,
|
|
33407
35218
|
COMPOSITOR_ONLY_PROPS: () => COMPOSITOR_ONLY_PROPS,
|
|
35219
|
+
CONTEXT_POLICY_VERSION: () => CONTEXT_POLICY_VERSION,
|
|
35220
|
+
CONTINUE: () => CONTINUE,
|
|
33408
35221
|
CORE_VERSION: () => CORE_VERSION,
|
|
33409
35222
|
COUNCIL_V1: () => COUNCIL_V1,
|
|
33410
35223
|
CommandCheckSchema: () => CommandCheckSchema,
|
|
33411
35224
|
CriterionSchema: () => CriterionSchema,
|
|
33412
35225
|
CriterionSourceSchema: () => CriterionSourceSchema,
|
|
35226
|
+
DEFAULT_CONTEXT_POLICY: () => DEFAULT_CONTEXT_POLICY,
|
|
33413
35227
|
DEFAULT_MAX_NODES: () => DEFAULT_MAX_NODES,
|
|
33414
35228
|
DEFAULT_MAX_TENTACLES: () => DEFAULT_MAX_TENTACLES,
|
|
33415
35229
|
DEFAULT_MEMORY_SCORING_WEIGHTS: () => DEFAULT_MEMORY_SCORING_WEIGHTS,
|
|
33416
35230
|
DEFAULT_NFR_SPEC: () => DEFAULT_NFR_SPEC,
|
|
33417
35231
|
DEFAULT_PLAN_TIMEOUT_MS: () => DEFAULT_PLAN_TIMEOUT_MS,
|
|
33418
35232
|
DEFAULT_PRESSURE_THRESHOLDS: () => DEFAULT_PRESSURE_THRESHOLDS,
|
|
35233
|
+
DEFAULT_RUN_RETENTION_DAYS: () => DEFAULT_RUN_RETENTION_DAYS,
|
|
35234
|
+
DEFAULT_RUN_RETENTION_MAX_MB: () => DEFAULT_RUN_RETENTION_MAX_MB,
|
|
33419
35235
|
DEFAULT_VERIFIER_CONFIG: () => DEFAULT_VERIFIER_CONFIG,
|
|
33420
35236
|
DEGRADED_RUN_BANNER: () => DEGRADED_RUN_BANNER,
|
|
33421
35237
|
DESIGN_PHASE_MODE_BANNER: () => DESIGN_PHASE_MODE_BANNER,
|
|
@@ -33426,12 +35242,15 @@ __export(dist_exports, {
|
|
|
33426
35242
|
DefaultMemorySanitizer: () => DefaultMemorySanitizer,
|
|
33427
35243
|
DefaultMemoryService: () => DefaultMemoryService,
|
|
33428
35244
|
DeterministicCheckSchema: () => DeterministicCheckSchema,
|
|
35245
|
+
DuplicateSearchGuard: () => DuplicateSearchGuard,
|
|
33429
35246
|
EPHEMERAL_TAIL_EVENT_KINDS: () => EPHEMERAL_TAIL_EVENT_KINDS,
|
|
33430
35247
|
EVENT_BACKED_EVIDENCE_TIERS: () => EVENT_BACKED_EVIDENCE_TIERS,
|
|
33431
35248
|
EXPERIMENTAL_FLAGS: () => EXPERIMENTAL_FLAGS,
|
|
33432
35249
|
EventBus: () => EventBus,
|
|
33433
35250
|
EvidenceRefSchema: () => EvidenceRefSchema,
|
|
33434
35251
|
EvidenceTierSchema: () => EvidenceTierSchema,
|
|
35252
|
+
FILE_WRITING_TOOLS: () => FILE_WRITING_TOOLS,
|
|
35253
|
+
FailureSignatureGuard: () => FailureSignatureGuard,
|
|
33435
35254
|
FileAbsentCheckSchema: () => FileAbsentCheckSchema,
|
|
33436
35255
|
FileContainsCheckSchema: () => FileContainsCheckSchema,
|
|
33437
35256
|
FileExistsCheckSchema: () => FileExistsCheckSchema,
|
|
@@ -33442,10 +35261,14 @@ __export(dist_exports, {
|
|
|
33442
35261
|
IMPLEMENTATION_IMPLEMENTER_BANNER: () => IMPLEMENTATION_IMPLEMENTER_BANNER,
|
|
33443
35262
|
IMPLEMENTATION_MODE_BANNER: () => IMPLEMENTATION_MODE_BANNER,
|
|
33444
35263
|
IMPLEMENTATION_WRITE_REQUIREMENTS: () => IMPLEMENTATION_WRITE_REQUIREMENTS,
|
|
35264
|
+
KRAKEN_EXPLORE_POLICY: () => KRAKEN_EXPLORE_POLICY,
|
|
35265
|
+
KRAKEN_GENERAL_POLICY: () => KRAKEN_GENERAL_POLICY,
|
|
33445
35266
|
KRAKEN_IDENTITY_MODULE: () => KRAKEN_IDENTITY_MODULE,
|
|
33446
35267
|
KRAKEN_LEAD_PLAYBOOK_MODULE: () => KRAKEN_LEAD_PLAYBOOK_MODULE,
|
|
35268
|
+
KRAKEN_LEAD_POLICY: () => KRAKEN_LEAD_POLICY,
|
|
33447
35269
|
KRAKEN_SELECTION_PLAYBOOK_MODULE: () => KRAKEN_SELECTION_PLAYBOOK_MODULE,
|
|
33448
35270
|
KRAKEN_V1: () => KRAKEN_V1,
|
|
35271
|
+
KRAKEN_VERIFY_POLICY: () => KRAKEN_VERIFY_POLICY,
|
|
33449
35272
|
LANGUAGE_POLICY_MODULE_TYPE: () => LANGUAGE_POLICY_MODULE_TYPE,
|
|
33450
35273
|
LATEST_ONLY_SURFACE_KINDS: () => LATEST_ONLY_SURFACE_KINDS,
|
|
33451
35274
|
LAYOUT_MOTION_PROPS: () => LAYOUT_MOTION_PROPS,
|
|
@@ -33479,17 +35302,20 @@ __export(dist_exports, {
|
|
|
33479
35302
|
MemorySourceSchema: () => MemorySourceSchema,
|
|
33480
35303
|
MemoryStatusSchema: () => MemoryStatusSchema,
|
|
33481
35304
|
MemoryVisibilitySchema: () => MemoryVisibilitySchema,
|
|
35305
|
+
MetricsObserver: () => MetricsObserver,
|
|
33482
35306
|
ModelSelectionSchema: () => ModelSelectionSchema,
|
|
33483
35307
|
NATIVE_TOOL_PROTOCOL_MODULE: () => NATIVE_TOOL_PROTOCOL_MODULE,
|
|
33484
35308
|
NFR_KEYWORDS: () => NFR_KEYWORDS,
|
|
33485
35309
|
NON_RETRY_AGENTS: () => NON_RETRY_AGENTS,
|
|
33486
35310
|
NOOP_SUBAGENT_PROVIDER: () => NOOP_SUBAGENT_PROVIDER,
|
|
35311
|
+
NoProgressGuard: () => NoProgressGuard,
|
|
33487
35312
|
NodeFsProvider: () => NodeFsProvider,
|
|
33488
35313
|
NodeShellProvider: () => NodeShellProvider,
|
|
33489
35314
|
NoneCheckSchema: () => NoneCheckSchema,
|
|
33490
35315
|
NoopMemoryService: () => NoopMemoryService,
|
|
33491
35316
|
NoopSubagentProvider: () => NoopSubagentProvider,
|
|
33492
35317
|
OUTPUT_QUALITY_DIRECTIVE: () => OUTPUT_QUALITY_DIRECTIVE,
|
|
35318
|
+
ObserverBus: () => ObserverBus,
|
|
33493
35319
|
PROFILE_RESOURCE_POLICIES: () => PROFILE_RESOURCE_POLICIES,
|
|
33494
35320
|
PROMPT_MODULES: () => PROMPT_MODULES,
|
|
33495
35321
|
PROPRIETARY_REFUSAL_TEXT: () => PROPRIETARY_REFUSAL_TEXT,
|
|
@@ -33498,8 +35324,14 @@ __export(dist_exports, {
|
|
|
33498
35324
|
PlanError: () => PlanError,
|
|
33499
35325
|
PressureThresholdsSchema: () => PressureThresholdsSchema,
|
|
33500
35326
|
ProfileSchema: () => ProfileSchema,
|
|
35327
|
+
REDACTED: () => REDACTED,
|
|
35328
|
+
ReasoningWatchdog: () => ReasoningWatchdog,
|
|
35329
|
+
RepetitionGuard: () => RepetitionGuard,
|
|
33501
35330
|
ResourcePolicySchema: () => ResourcePolicySchema,
|
|
33502
35331
|
ResourceStageSchema: () => ResourceStageSchema,
|
|
35332
|
+
RunRecorder: () => RunRecorder,
|
|
35333
|
+
RuntimeControlQueue: () => RuntimeControlQueue,
|
|
35334
|
+
SEARCH_TOOLS: () => SEARCH_TOOLS,
|
|
33503
35335
|
SESSION_EVENT_KINDS: () => SESSION_EVENT_KINDS,
|
|
33504
35336
|
SESSION_EXPORT_FORMAT: () => SESSION_EXPORT_FORMAT,
|
|
33505
35337
|
SESSION_EXPORT_VERSION: () => SESSION_EXPORT_VERSION,
|
|
@@ -33517,6 +35349,7 @@ __export(dist_exports, {
|
|
|
33517
35349
|
SessionLogLockedError: () => SessionLogLockedError,
|
|
33518
35350
|
SessionLogWriter: () => SessionLogWriter,
|
|
33519
35351
|
SessionStore: () => SessionStore,
|
|
35352
|
+
SteeringObserver: () => SteeringObserver,
|
|
33520
35353
|
TERMINAL_STATUSES: () => TERMINAL_STATUSES,
|
|
33521
35354
|
TEXT_LOOP_RECOVERY_SYSTEM: () => TEXT_LOOP_RECOVERY_SYSTEM,
|
|
33522
35355
|
TEXT_LOOP_RECOVERY_USER_PROMPT: () => TEXT_LOOP_RECOVERY_USER_PROMPT,
|
|
@@ -33528,6 +35361,7 @@ __export(dist_exports, {
|
|
|
33528
35361
|
TaskContractConflictError: () => TaskContractConflictError,
|
|
33529
35362
|
TaskContractSchema: () => TaskContractSchema,
|
|
33530
35363
|
TaskCriterionSchema: () => TaskCriterionSchema,
|
|
35364
|
+
TraceObserver: () => TraceObserver,
|
|
33531
35365
|
UnknownMemberError: () => UnknownMemberError,
|
|
33532
35366
|
UnknownProfileError: () => UnknownProfileError,
|
|
33533
35367
|
VAULT_TOOL_DEFINITIONS: () => VAULT_TOOL_DEFINITIONS,
|
|
@@ -33566,6 +35400,7 @@ __export(dist_exports, {
|
|
|
33566
35400
|
buildMotionFixPrompt: () => buildMotionFixPrompt,
|
|
33567
35401
|
buildProjection: () => buildProjection,
|
|
33568
35402
|
buildRetryPrompt: () => buildRetryPrompt,
|
|
35403
|
+
buildRuntimeObserverBus: () => buildRuntimeObserverBus,
|
|
33569
35404
|
buildSkillDefinition: () => buildSkillDefinition,
|
|
33570
35405
|
buildSystemPrompt: () => buildSystemPrompt,
|
|
33571
35406
|
buildSystemPromptSplit: () => buildSystemPromptSplit,
|
|
@@ -33590,10 +35425,12 @@ __export(dist_exports, {
|
|
|
33590
35425
|
codingCriteriaPack: () => codingCriteriaPack,
|
|
33591
35426
|
collapseLoopedAssistantText: () => collapseLoopedAssistantText,
|
|
33592
35427
|
compareReplayPrefix: () => compareReplayPrefix,
|
|
35428
|
+
composeObservers: () => composeObservers,
|
|
33593
35429
|
computeAgentSkills: () => computeAgentSkills,
|
|
33594
35430
|
computeAgentTools: () => computeAgentTools,
|
|
33595
35431
|
computeBudget: () => computeBudget,
|
|
33596
35432
|
computeFalseDoneRate: () => computeFalseDoneRate,
|
|
35433
|
+
contextPolicyForRole: () => contextPolicyForRole,
|
|
33597
35434
|
contractToCompactionFields: () => contractToCompactionFields,
|
|
33598
35435
|
costPerVerifiedSolve: () => costPerVerifiedSolve,
|
|
33599
35436
|
councilModeBanner: () => councilModeBanner,
|
|
@@ -33605,6 +35442,7 @@ __export(dist_exports, {
|
|
|
33605
35442
|
createDefaultSystemPromptConfig: () => createDefaultSystemPromptConfig,
|
|
33606
35443
|
createExecutionContext: () => createExecutionContext,
|
|
33607
35444
|
createGraph: () => createGraph,
|
|
35445
|
+
createRecorderObserver: () => createRecorderObserver,
|
|
33608
35446
|
createRoutedRequestSnapshot: () => createRoutedRequestSnapshot,
|
|
33609
35447
|
defaultPersonaParse: () => defaultPersonaParse,
|
|
33610
35448
|
defaultResourcePolicy: () => defaultResourcePolicy,
|
|
@@ -33620,6 +35458,7 @@ __export(dist_exports, {
|
|
|
33620
35458
|
disjointScopeSets: () => disjointScopeSets,
|
|
33621
35459
|
emptyContextGrowthStats: () => emptyContextGrowthStats,
|
|
33622
35460
|
enforceDesignPhaseToolEmissions: () => enforceDesignPhaseToolEmissions,
|
|
35461
|
+
enforceRunRetention: () => enforceRunRetention,
|
|
33623
35462
|
evaluateBudgetContinuation: () => evaluateBudgetContinuation,
|
|
33624
35463
|
evaluateCompletion: () => evaluateCompletion,
|
|
33625
35464
|
evaluateMissionContinuation: () => evaluateMissionContinuation,
|
|
@@ -33629,6 +35468,7 @@ __export(dist_exports, {
|
|
|
33629
35468
|
exportSessionJson: () => exportSessionJson,
|
|
33630
35469
|
extractCitations: () => extractCitations,
|
|
33631
35470
|
extractRequirementsBlock: () => extractRequirementsBlock,
|
|
35471
|
+
extractSearchQuery: () => extractSearchQuery,
|
|
33632
35472
|
extractTaskScope: () => extractTaskScope,
|
|
33633
35473
|
failedNodeIds: () => failedNodeIds,
|
|
33634
35474
|
filterByWeakness: () => filterByWeakness,
|
|
@@ -33685,15 +35525,19 @@ __export(dist_exports, {
|
|
|
33685
35525
|
isBrainToolExecutionEndEvent: () => isBrainToolExecutionEndEvent,
|
|
33686
35526
|
isBrainToolExecutionStartEvent: () => isBrainToolExecutionStartEvent,
|
|
33687
35527
|
isBrainToolExecutionUpdateEvent: () => isBrainToolExecutionUpdateEvent,
|
|
35528
|
+
isCancelControlEvent: () => isCancelControlEvent,
|
|
33688
35529
|
isConverged: () => isConverged,
|
|
33689
35530
|
isEventBackedEvidence: () => isEventBackedEvidence,
|
|
33690
35531
|
isExperimentalEnabled: () => isExperimentalEnabled,
|
|
35532
|
+
isFollowUpControlEvent: () => isFollowUpControlEvent,
|
|
33691
35533
|
isGeneratedPath: () => isGeneratedPath,
|
|
33692
35534
|
isModelSurfaceEvent: () => isModelSurfaceEvent,
|
|
33693
35535
|
isReviewerKind: () => isReviewerKind,
|
|
35536
|
+
isSearchTool: () => isSearchTool,
|
|
33694
35537
|
isSeqShadowed: () => isSeqShadowed,
|
|
33695
35538
|
isSettled: () => isSettled,
|
|
33696
35539
|
isStatusTheaterUnit: () => isStatusTheaterUnit,
|
|
35540
|
+
isSteerControlEvent: () => isSteerControlEvent,
|
|
33697
35541
|
isValidTool: () => isValidTool,
|
|
33698
35542
|
isVerificationReserveProtected: () => isVerificationReserveProtected,
|
|
33699
35543
|
isVerifyToolCheckSkipped: () => isVerifyToolCheckSkipped,
|
|
@@ -33713,15 +35557,19 @@ __export(dist_exports, {
|
|
|
33713
35557
|
memorySimilarity: () => memorySimilarity,
|
|
33714
35558
|
memoryTokens: () => memoryTokens,
|
|
33715
35559
|
missionSnapshot: () => missionSnapshot,
|
|
35560
|
+
newRunId: () => newRunId,
|
|
35561
|
+
normalizeFailureTail: () => normalizeFailureTail,
|
|
33716
35562
|
normalizeForSignature: () => normalizeForSignature,
|
|
33717
35563
|
normalizeLoopUnit: () => normalizeLoopUnit,
|
|
33718
35564
|
normalizeMemoryContent: () => normalizeMemoryContent,
|
|
35565
|
+
normalizeQuery: () => normalizeQuery,
|
|
33719
35566
|
normalizeScopePath: () => normalizeScopePath,
|
|
33720
35567
|
normalizeTags: () => normalizeTags,
|
|
33721
35568
|
normalizeTextToolArgs: () => normalizeTextToolArgs,
|
|
33722
35569
|
normalizeToolName: () => normalizeToolName,
|
|
33723
35570
|
normalizedMemoryKey: () => normalizedMemoryKey,
|
|
33724
35571
|
pairToolCalls: () => pairToolCalls,
|
|
35572
|
+
parentContextForRole: () => parentContextForRole,
|
|
33725
35573
|
parseClarificationRequest: () => parseClarificationRequest,
|
|
33726
35574
|
parseCompactedEvent: () => parseCompactedEvent,
|
|
33727
35575
|
parseEvidenceTier: () => parseEvidenceTier,
|
|
@@ -33737,7 +35585,9 @@ __export(dist_exports, {
|
|
|
33737
35585
|
pathsOverlap: () => pathsOverlap,
|
|
33738
35586
|
pickWeakest: () => pickWeakest,
|
|
33739
35587
|
profileHash: () => profileHash,
|
|
35588
|
+
projectContext: () => projectContext,
|
|
33740
35589
|
promoteMember: () => promoteMember,
|
|
35590
|
+
queryJaccard: () => queryJaccard,
|
|
33741
35591
|
rankByWeakness: () => rankByWeakness,
|
|
33742
35592
|
rankMemoryCandidates: () => rankMemoryCandidates,
|
|
33743
35593
|
readLessonsDeduped: () => readLessonsDeduped,
|
|
@@ -33748,14 +35598,19 @@ __export(dist_exports, {
|
|
|
33748
35598
|
recordRequest: () => recordRequest,
|
|
33749
35599
|
recordToolResult: () => recordToolResult,
|
|
33750
35600
|
recordUsage: () => recordUsage,
|
|
35601
|
+
redactRuntimePayload: () => redactRuntimePayload,
|
|
35602
|
+
redactString: () => redactString,
|
|
33751
35603
|
registerCodingSkill: () => registerCodingSkill,
|
|
33752
35604
|
registerCustomTool: () => registerCustomTool,
|
|
33753
35605
|
registerPersona: () => registerPersona,
|
|
33754
35606
|
registerSkill: () => registerSkill,
|
|
35607
|
+
renderHistoryDigest: () => renderHistoryDigest,
|
|
33755
35608
|
renderSkillMarkdown: () => renderSkillMarkdown,
|
|
35609
|
+
renderSteers: () => renderSteers,
|
|
33756
35610
|
replayChairmanTextTools: () => replayChairmanTextTools,
|
|
33757
35611
|
resolveAgentSkills: () => resolveAgentSkills,
|
|
33758
35612
|
resolveCouncilRunMode: () => resolveCouncilRunMode,
|
|
35613
|
+
resolveInterventions: () => resolveInterventions,
|
|
33759
35614
|
resolveJailed: () => resolveJailed,
|
|
33760
35615
|
resolveMaxTentacles: () => resolveMaxTentacles,
|
|
33761
35616
|
resolvePlanTimeoutMs: () => resolvePlanTimeoutMs,
|
|
@@ -33776,7 +35631,10 @@ __export(dist_exports, {
|
|
|
33776
35631
|
runImplementationVerification: () => runImplementationVerification,
|
|
33777
35632
|
runInSandbox: () => runInSandbox,
|
|
33778
35633
|
runMicroVerificationOnFile: () => runMicroVerificationOnFile,
|
|
35634
|
+
runRecordEnabled: () => runRecordEnabled,
|
|
35635
|
+
runRetentionFromEnv: () => runRetentionFromEnv,
|
|
33779
35636
|
runRetryTurnForMember: () => runRetryTurnForMember,
|
|
35637
|
+
runtimeObserversEnabled: () => runtimeObserversEnabled,
|
|
33780
35638
|
sanitizeMemoryMetadata: () => sanitizeMemoryMetadata,
|
|
33781
35639
|
scanForFootguns: () => scanForFootguns,
|
|
33782
35640
|
scanKeyframesViolations: () => scanKeyframesViolations,
|
|
@@ -33795,12 +35653,14 @@ __export(dist_exports, {
|
|
|
33795
35653
|
specificityFromAssumptions: () => specificityFromAssumptions,
|
|
33796
35654
|
stableStringify: () => stableStringify,
|
|
33797
35655
|
strictBuildGate: () => strictBuildGate,
|
|
35656
|
+
stripAnsi: () => stripAnsi,
|
|
33798
35657
|
stripClarificationProtocol: () => stripClarificationProtocol,
|
|
33799
35658
|
swapMembers: () => swapMembers,
|
|
33800
35659
|
systemMessagesFromSplit: () => systemMessagesFromSplit,
|
|
33801
35660
|
taskMatchesNfrKeywords: () => taskMatchesNfrKeywords,
|
|
33802
35661
|
tierAtLeast: () => tierAtLeast,
|
|
33803
35662
|
tokenizeForSignature: () => tokenizeForSignature,
|
|
35663
|
+
toolCallFingerprint: () => toolCallFingerprint,
|
|
33804
35664
|
toolFingerprintHash: () => toolFingerprintHash,
|
|
33805
35665
|
toolManifestHash: () => toolManifestHash,
|
|
33806
35666
|
toolMatches: () => toolMatches,
|
|
@@ -33837,6 +35697,7 @@ var init_dist = __esm({
|
|
|
33837
35697
|
init_kraken();
|
|
33838
35698
|
init_session();
|
|
33839
35699
|
init_runtime2();
|
|
35700
|
+
init_context3();
|
|
33840
35701
|
init_verification2();
|
|
33841
35702
|
init_mission2();
|
|
33842
35703
|
init_experimental();
|
|
@@ -33902,8 +35763,8 @@ function formatKrakenGraphDigest(graph, opts = {}) {
|
|
|
33902
35763
|
if (!n) continue;
|
|
33903
35764
|
const took = durations[id3] !== void 0 ? `, ${formatDuration2(durations[id3])}` : "";
|
|
33904
35765
|
const detail = n.status === "error" ? n.error : n.result;
|
|
33905
|
-
const
|
|
33906
|
-
const body =
|
|
35766
|
+
const firstLine3 = (detail ?? "").trim().split("\n")[0] ?? "";
|
|
35767
|
+
const body = firstLine3.length > maxChars ? `${firstLine3.slice(0, maxChars)}\u2026` : firstLine3;
|
|
33907
35768
|
lines.push(
|
|
33908
35769
|
`[${STATUS_ICON[n.status]}] ${n.id} (${n.kind}${took})${body ? ` \u2014 ${body}` : ""}`
|
|
33909
35770
|
);
|
|
@@ -35561,18 +37422,18 @@ var init_observationStore = __esm({
|
|
|
35561
37422
|
});
|
|
35562
37423
|
|
|
35563
37424
|
// packages/core/dist/core/tools/toolOutputSpill.js
|
|
35564
|
-
import { createHash as
|
|
37425
|
+
import { createHash as createHash9, randomBytes as randomBytes3 } from "node:crypto";
|
|
35565
37426
|
import { existsSync as existsSync13, mkdirSync as mkdirSync6, writeFileSync as writeFileSync11 } from "node:fs";
|
|
35566
37427
|
import { homedir as homedir3, tmpdir } from "node:os";
|
|
35567
|
-
import { join as
|
|
37428
|
+
import { join as join14 } from "node:path";
|
|
35568
37429
|
function resolveToolOutputDir() {
|
|
35569
37430
|
const fromEnv = process.env.ZELARI_TOOL_OUTPUT_DIR?.trim();
|
|
35570
37431
|
if (fromEnv)
|
|
35571
37432
|
return fromEnv;
|
|
35572
37433
|
try {
|
|
35573
|
-
return
|
|
37434
|
+
return join14(homedir3(), ".tmp", "zelari-code", "tool-output");
|
|
35574
37435
|
} catch {
|
|
35575
|
-
return
|
|
37436
|
+
return join14(tmpdir(), "zelari-code", "tool-output");
|
|
35576
37437
|
}
|
|
35577
37438
|
}
|
|
35578
37439
|
function isToolSpillEnabled() {
|
|
@@ -35591,12 +37452,12 @@ function spillToolOutput(fullText, meta3) {
|
|
|
35591
37452
|
if (!existsSync13(dir)) {
|
|
35592
37453
|
mkdirSync6(dir, { recursive: true });
|
|
35593
37454
|
}
|
|
35594
|
-
const hash3 =
|
|
37455
|
+
const hash3 = createHash9("sha256").update(fullText).digest("hex").slice(0, 12);
|
|
35595
37456
|
const stamp = Date.now().toString(36);
|
|
35596
|
-
const rnd =
|
|
37457
|
+
const rnd = randomBytes3(3).toString("hex");
|
|
35597
37458
|
const safeTool = (meta3?.toolName ?? "tool").replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 32);
|
|
35598
37459
|
const file2 = `${stamp}-${safeTool}-${hash3}-${rnd}.txt`;
|
|
35599
|
-
const path72 =
|
|
37460
|
+
const path72 = join14(dir, file2);
|
|
35600
37461
|
writeFileSync11(path72, fullText, "utf8");
|
|
35601
37462
|
return path72;
|
|
35602
37463
|
} catch {
|
|
@@ -36308,7 +38169,7 @@ import { execFile as execFile2 } from "node:child_process";
|
|
|
36308
38169
|
import { existsSync as existsSync16, mkdirSync as mkdirSync8, rmSync } from "node:fs";
|
|
36309
38170
|
import path29 from "node:path";
|
|
36310
38171
|
import { promisify } from "node:util";
|
|
36311
|
-
import { randomBytes as
|
|
38172
|
+
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
36312
38173
|
function isKrakenWorktreeEnabled(env = process.env) {
|
|
36313
38174
|
const v = (env.ZELARI_KRAKEN_WORKTREE ?? "").trim().toLowerCase();
|
|
36314
38175
|
return v === "1" || v === "true" || v === "yes" || v === "on";
|
|
@@ -36351,7 +38212,7 @@ async function createKrakenWorktree(cwd, label) {
|
|
|
36351
38212
|
if (!repoRoot) return null;
|
|
36352
38213
|
const head = await git2(repoRoot, ["rev-parse", "HEAD"]);
|
|
36353
38214
|
const baseSha = head.ok ? head.stdout.trim() : void 0;
|
|
36354
|
-
const id3 = `${Date.now().toString(36)}-${
|
|
38215
|
+
const id3 = `${Date.now().toString(36)}-${randomBytes4(3).toString("hex")}`;
|
|
36355
38216
|
const slug = (label ?? "task").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 24) || "task";
|
|
36356
38217
|
const branch = `kraken/${slug}-${id3}`;
|
|
36357
38218
|
const wtRoot = path29.join(repoRoot, ".zelari", "worktrees");
|
|
@@ -36862,6 +38723,7 @@ var init_metrics2 = __esm({
|
|
|
36862
38723
|
});
|
|
36863
38724
|
|
|
36864
38725
|
// src/cli/tools/taskTool.ts
|
|
38726
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
36865
38727
|
function resetTaskSpawnCount() {
|
|
36866
38728
|
const g = globalThis;
|
|
36867
38729
|
g.__zelariTaskSpawnCount = 0;
|
|
@@ -36958,6 +38820,9 @@ async function runSubAgent(harness, opts = {}) {
|
|
|
36958
38820
|
...toolTrace.length > 0 ? { toolTrace } : {}
|
|
36959
38821
|
};
|
|
36960
38822
|
}
|
|
38823
|
+
if (opts.onEvent && (ev.type === "agent_start" || ev.type === "agent_end" || ev.type === "tool_execution_start" || ev.type === "tool_execution_update" || ev.type === "tool_execution_end")) {
|
|
38824
|
+
opts.onEvent(ev);
|
|
38825
|
+
}
|
|
36961
38826
|
if (ev.type === "tool_execution_start") {
|
|
36962
38827
|
pendingTools.set(ev.toolCallId, { tool: ev.toolName, command: toolCommandHint(ev.args) });
|
|
36963
38828
|
} else if (ev.type === "tool_execution_end") {
|
|
@@ -37044,6 +38909,20 @@ async function runTentacle(opts) {
|
|
|
37044
38909
|
...opts.graphId ? { graphId: opts.graphId } : {},
|
|
37045
38910
|
...opts.nodeId ? { nodeId: opts.nodeId } : {}
|
|
37046
38911
|
});
|
|
38912
|
+
const emitActivity = (ev) => {
|
|
38913
|
+
deps.onTentacleEvent?.({ ...ev, id: randomUUID2(), sessionId: sessionId2 });
|
|
38914
|
+
};
|
|
38915
|
+
const endTentacle = (id3, info) => {
|
|
38916
|
+
krakenTentacleEnd(id3, info);
|
|
38917
|
+
emitActivity({
|
|
38918
|
+
type: "agent_ended",
|
|
38919
|
+
agentId: id3,
|
|
38920
|
+
reason: info.detail ?? (info.ok === false ? "failed" : "completed"),
|
|
38921
|
+
ok: info.ok !== false,
|
|
38922
|
+
durationMs: info.durationMs ?? 0,
|
|
38923
|
+
ts: Date.now()
|
|
38924
|
+
});
|
|
38925
|
+
};
|
|
37047
38926
|
let sub;
|
|
37048
38927
|
try {
|
|
37049
38928
|
sub = await deps.createSubAgentContext({
|
|
@@ -37061,7 +38940,7 @@ async function runTentacle(opts) {
|
|
|
37061
38940
|
ok: false,
|
|
37062
38941
|
durationMs: Date.now() - started
|
|
37063
38942
|
});
|
|
37064
|
-
|
|
38943
|
+
endTentacle(liveId, { ok: false, durationMs: Date.now() - started });
|
|
37065
38944
|
return {
|
|
37066
38945
|
ok: false,
|
|
37067
38946
|
agent,
|
|
@@ -37078,18 +38957,34 @@ async function runTentacle(opts) {
|
|
|
37078
38957
|
ok: false,
|
|
37079
38958
|
durationMs: Date.now() - started
|
|
37080
38959
|
});
|
|
37081
|
-
|
|
38960
|
+
endTentacle(liveId, { ok: false, durationMs: Date.now() - started });
|
|
37082
38961
|
return {
|
|
37083
38962
|
ok: false,
|
|
37084
38963
|
agent,
|
|
37085
38964
|
error: "task: no provider configured for the sub-agent (set an API key / run /login)."
|
|
37086
38965
|
};
|
|
37087
38966
|
}
|
|
37088
|
-
|
|
38967
|
+
emitActivity({
|
|
38968
|
+
type: "agent_spawned",
|
|
38969
|
+
agentId: liveId,
|
|
38970
|
+
role: agent,
|
|
38971
|
+
title: args.description,
|
|
38972
|
+
...sub.model ? { model: sub.model } : {},
|
|
38973
|
+
...sub.provider ? { provider: sub.provider } : {},
|
|
38974
|
+
...args.scope && args.scope.length > 0 ? { scope: args.scope } : {},
|
|
38975
|
+
...worktree ? { worktree: worktree.path } : {},
|
|
38976
|
+
ts: Date.now()
|
|
38977
|
+
});
|
|
38978
|
+
emitActivity({ type: "agent_status", agentId: liveId, status: "running", ts: Date.now() });
|
|
38979
|
+
const taskUserContent = buildTaskUserPrompt({
|
|
37089
38980
|
prompt: args.prompt,
|
|
37090
38981
|
scope: args.scope,
|
|
37091
38982
|
acceptance: withKrakenRequiredChecks(agent, args.acceptance)
|
|
37092
38983
|
});
|
|
38984
|
+
const parentBlock = parentContextForRole(agent, opts.parentTranscript ?? []);
|
|
38985
|
+
const userContent = parentBlock ? `${parentBlock.block}
|
|
38986
|
+
|
|
38987
|
+
${taskUserContent}` : taskUserContent;
|
|
37093
38988
|
const maxToolCalls = maxToolCallsForThoroughness(thoroughness, agent);
|
|
37094
38989
|
const runCwd = sub.cwd || effectiveCwd;
|
|
37095
38990
|
const config2 = {
|
|
@@ -37112,7 +39007,7 @@ async function runTentacle(opts) {
|
|
|
37112
39007
|
...deps.memoryService ? {
|
|
37113
39008
|
memoryService: deps.memoryService,
|
|
37114
39009
|
memoryQuery: `${args.description}
|
|
37115
|
-
${
|
|
39010
|
+
${taskUserContent}`,
|
|
37116
39011
|
memoryContextChars: 2400
|
|
37117
39012
|
} : {}
|
|
37118
39013
|
};
|
|
@@ -37126,15 +39021,24 @@ ${userContent}`,
|
|
|
37126
39021
|
}
|
|
37127
39022
|
} catch (err) {
|
|
37128
39023
|
if (worktree) await cleanupKrakenWorktree(worktree);
|
|
37129
|
-
|
|
39024
|
+
endTentacle(liveId, { ok: false, durationMs: Date.now() - started });
|
|
37130
39025
|
return {
|
|
37131
39026
|
ok: false,
|
|
37132
39027
|
agent,
|
|
37133
39028
|
error: `task: failed to start sub-agent \u2014 ${err instanceof Error ? err.message : String(err)}`
|
|
37134
39029
|
};
|
|
37135
39030
|
}
|
|
39031
|
+
const startedTools = /* @__PURE__ */ new Map();
|
|
37136
39032
|
const { result, error: error51, aborted: aborted2, usage, toolTrace } = await runSubAgent(harness, {
|
|
37137
|
-
...opts.signal ? { signal: opts.signal } : {}
|
|
39033
|
+
...opts.signal ? { signal: opts.signal } : {},
|
|
39034
|
+
onEvent: (ev) => {
|
|
39035
|
+
if (ev.type === "tool_execution_start") {
|
|
39036
|
+
startedTools.set(ev.toolCallId, ev.toolName);
|
|
39037
|
+
emitActivity({ type: "agent_tool", agentId: liveId, toolCallId: ev.toolCallId, tool: ev.toolName, status: "started", ...ev.args ? { summary: toolCommandHint(ev.args) } : {}, ts: Date.now() });
|
|
39038
|
+
} else if (ev.type === "tool_execution_end") {
|
|
39039
|
+
emitActivity({ type: "agent_tool", agentId: liveId, toolCallId: ev.toolCallId, tool: startedTools.get(ev.toolCallId) ?? "unknown", status: ev.isError ? "failed" : "completed", durationMs: ev.durationMs, ts: Date.now() });
|
|
39040
|
+
}
|
|
39041
|
+
}
|
|
37138
39042
|
});
|
|
37139
39043
|
const durationMs = Date.now() - started;
|
|
37140
39044
|
if (aborted2) {
|
|
@@ -37150,7 +39054,7 @@ ${userContent}`,
|
|
|
37150
39054
|
durationMs,
|
|
37151
39055
|
ok: false
|
|
37152
39056
|
});
|
|
37153
|
-
|
|
39057
|
+
endTentacle(liveId, {
|
|
37154
39058
|
ok: false,
|
|
37155
39059
|
model: sub.model,
|
|
37156
39060
|
detail: "cancelled",
|
|
@@ -37171,7 +39075,7 @@ ${userContent}`,
|
|
|
37171
39075
|
durationMs,
|
|
37172
39076
|
ok: false
|
|
37173
39077
|
});
|
|
37174
|
-
|
|
39078
|
+
endTentacle(liveId, { ok: false, model: sub.model, detail: error51, durationMs });
|
|
37175
39079
|
return {
|
|
37176
39080
|
ok: false,
|
|
37177
39081
|
agent,
|
|
@@ -37210,7 +39114,7 @@ ${formatWorktreeFooter(worktree, { kept, merge: merge2 })}`;
|
|
|
37210
39114
|
${verifyHintForGeneral(args.acceptance)}`;
|
|
37211
39115
|
g.__zelariLastGeneralAt = Date.now();
|
|
37212
39116
|
}
|
|
37213
|
-
|
|
39117
|
+
endTentacle(liveId, {
|
|
37214
39118
|
ok: true,
|
|
37215
39119
|
model: sub.model,
|
|
37216
39120
|
detail: result.slice(0, 160),
|
|
@@ -37393,6 +39297,7 @@ var init_taskTool = __esm({
|
|
|
37393
39297
|
"src/cli/tools/taskTool.ts"() {
|
|
37394
39298
|
"use strict";
|
|
37395
39299
|
init_zod();
|
|
39300
|
+
init_context3();
|
|
37396
39301
|
init_toolTypes();
|
|
37397
39302
|
init_krakenRadio();
|
|
37398
39303
|
init_krakenWorktree();
|
|
@@ -37849,14 +39754,14 @@ var init_askUser = __esm({
|
|
|
37849
39754
|
|
|
37850
39755
|
// src/cli/skillsMd.ts
|
|
37851
39756
|
import { existsSync as existsSync17, readdirSync as readdirSync3, readFileSync as readFileSync15 } from "node:fs";
|
|
37852
|
-
import { join as
|
|
39757
|
+
import { join as join15 } from "node:path";
|
|
37853
39758
|
import { homedir as homedir4 } from "node:os";
|
|
37854
39759
|
function skillMdSearchDirs(projectRoot = process.cwd()) {
|
|
37855
39760
|
return [
|
|
37856
|
-
|
|
37857
|
-
|
|
37858
|
-
|
|
37859
|
-
|
|
39761
|
+
join15(projectRoot, ".zelari", "skills"),
|
|
39762
|
+
join15(projectRoot, ".claude", "skills"),
|
|
39763
|
+
join15(projectRoot, ".opencode", "skills"),
|
|
39764
|
+
join15(homedir4(), ".zelari-code", "skills")
|
|
37860
39765
|
];
|
|
37861
39766
|
}
|
|
37862
39767
|
function parseSkillMd(content, sourcePath) {
|
|
@@ -37922,7 +39827,7 @@ function loadSkillMdSkills(projectRoot = process.cwd(), options = {}) {
|
|
|
37922
39827
|
continue;
|
|
37923
39828
|
}
|
|
37924
39829
|
for (const entry of entries) {
|
|
37925
|
-
const skillPath =
|
|
39830
|
+
const skillPath = join15(dir, entry, "SKILL.md");
|
|
37926
39831
|
if (!existsSync17(skillPath)) continue;
|
|
37927
39832
|
try {
|
|
37928
39833
|
const parsed = parseSkillMd(readFileSync15(skillPath, "utf8"), skillPath);
|
|
@@ -38103,13 +40008,13 @@ import {
|
|
|
38103
40008
|
constants,
|
|
38104
40009
|
realpathSync
|
|
38105
40010
|
} from "node:fs";
|
|
38106
|
-
import { join as
|
|
40011
|
+
import { join as join16, basename } from "node:path";
|
|
38107
40012
|
import { homedir as homedir5 } from "node:os";
|
|
38108
|
-
import { createHash as
|
|
40013
|
+
import { createHash as createHash10 } from "node:crypto";
|
|
38109
40014
|
function resolveWorkspaceRoot(projectRoot = process.cwd()) {
|
|
38110
40015
|
const candidates = [
|
|
38111
|
-
|
|
38112
|
-
|
|
40016
|
+
join16(projectRoot, ".zelari"),
|
|
40017
|
+
join16(homedir5(), ".zelari-code", "workspace", hashProject(projectRoot))
|
|
38113
40018
|
];
|
|
38114
40019
|
for (const candidate of candidates) {
|
|
38115
40020
|
if (isWritableDir(projectRoot) || candidate !== candidates[0]) {
|
|
@@ -38121,7 +40026,7 @@ function resolveWorkspaceRoot(projectRoot = process.cwd()) {
|
|
|
38121
40026
|
return candidates[0];
|
|
38122
40027
|
}
|
|
38123
40028
|
function hashProject(projectPath) {
|
|
38124
|
-
return
|
|
40029
|
+
return createHash10("sha1").update(realpathSync(projectPath)).digest("hex").slice(0, 12);
|
|
38125
40030
|
}
|
|
38126
40031
|
function isWritableDir(dir) {
|
|
38127
40032
|
try {
|
|
@@ -38134,8 +40039,8 @@ function isWritableDir(dir) {
|
|
|
38134
40039
|
}
|
|
38135
40040
|
function ensureWorkspaceDir(workspaceDir) {
|
|
38136
40041
|
mkdirSync9(workspaceDir, { recursive: true });
|
|
38137
|
-
if (workspaceDir.endsWith("/.zelari") && existsSync18(
|
|
38138
|
-
const gitignorePath =
|
|
40042
|
+
if (workspaceDir.endsWith("/.zelari") && existsSync18(join16(workspaceDir, "..", ".git"))) {
|
|
40043
|
+
const gitignorePath = join16(workspaceDir, ".gitignore");
|
|
38139
40044
|
if (!existsSync18(gitignorePath)) {
|
|
38140
40045
|
writeFileSync12(gitignorePath, "*\n!.gitignore\n");
|
|
38141
40046
|
}
|
|
@@ -38144,15 +40049,15 @@ function ensureWorkspaceDir(workspaceDir) {
|
|
|
38144
40049
|
function workspaceFile(rootDir, kind2) {
|
|
38145
40050
|
switch (kind2) {
|
|
38146
40051
|
case "plan":
|
|
38147
|
-
return
|
|
40052
|
+
return join16(rootDir, "plan.md");
|
|
38148
40053
|
case "risks":
|
|
38149
|
-
return
|
|
40054
|
+
return join16(rootDir, "risks.md");
|
|
38150
40055
|
case "index":
|
|
38151
|
-
return
|
|
40056
|
+
return join16(rootDir, "workspace.json");
|
|
38152
40057
|
}
|
|
38153
40058
|
}
|
|
38154
40059
|
function workspaceArtifact(rootDir, subdir, slug) {
|
|
38155
|
-
return
|
|
40060
|
+
return join16(rootDir, subdir, `${slug}.md`);
|
|
38156
40061
|
}
|
|
38157
40062
|
function projectName(projectRoot = process.cwd()) {
|
|
38158
40063
|
return basename(realpathSync(projectRoot));
|
|
@@ -38181,7 +40086,7 @@ import {
|
|
|
38181
40086
|
readdirSync as readdirSync4,
|
|
38182
40087
|
renameSync
|
|
38183
40088
|
} from "node:fs";
|
|
38184
|
-
import { dirname as dirname2, join as
|
|
40089
|
+
import { dirname as dirname2, join as join17 } from "node:path";
|
|
38185
40090
|
function parseFrontmatter(md) {
|
|
38186
40091
|
const m = FRONTMATTER_RE.exec(md);
|
|
38187
40092
|
if (!m) return { meta: {}, body: md };
|
|
@@ -38461,7 +40366,7 @@ var init_storage = __esm({
|
|
|
38461
40366
|
/** List all .md files in a directory (non-recursive). */
|
|
38462
40367
|
listMarkdown(dir) {
|
|
38463
40368
|
if (!existsSync19(dir)) return [];
|
|
38464
|
-
return readdirSync4(dir).filter((f) => f.endsWith(".md") && !f.startsWith(".")).map((f) =>
|
|
40369
|
+
return readdirSync4(dir).filter((f) => f.endsWith(".md") && !f.startsWith(".")).map((f) => join17(dir, f));
|
|
38465
40370
|
}
|
|
38466
40371
|
};
|
|
38467
40372
|
KeyedMutex = class {
|
|
@@ -38499,7 +40404,7 @@ import {
|
|
|
38499
40404
|
renameSync as renameSync2,
|
|
38500
40405
|
writeFileSync as writeFileSync14
|
|
38501
40406
|
} from "node:fs";
|
|
38502
|
-
import { dirname as dirname3, join as
|
|
40407
|
+
import { dirname as dirname3, join as join18 } from "node:path";
|
|
38503
40408
|
async function withPlanStore(projectRoot, fn) {
|
|
38504
40409
|
const rootDir = resolveWorkspaceRoot(projectRoot);
|
|
38505
40410
|
return workspaceMutex.run(`${rootDir}:plan`, () => {
|
|
@@ -38518,7 +40423,7 @@ function nextPlanTaskId(store6) {
|
|
|
38518
40423
|
return `t${store6.counter}`;
|
|
38519
40424
|
}
|
|
38520
40425
|
function writePlanTaskArtifact(rootDir, task) {
|
|
38521
|
-
const path72 =
|
|
40426
|
+
const path72 = join18(rootDir, "plan-tasks", `${task.id}.md`);
|
|
38522
40427
|
mkdirSync11(dirname3(path72), { recursive: true });
|
|
38523
40428
|
const meta3 = {
|
|
38524
40429
|
kind: "task",
|
|
@@ -38543,7 +40448,7 @@ function writePlanTaskArtifact(rootDir, task) {
|
|
|
38543
40448
|
new Storage().write(path72, meta3, body);
|
|
38544
40449
|
}
|
|
38545
40450
|
function loadHandle(rootDir) {
|
|
38546
|
-
const jsonPath =
|
|
40451
|
+
const jsonPath = join18(rootDir, "plan.json");
|
|
38547
40452
|
if (!existsSync20(jsonPath)) {
|
|
38548
40453
|
return { rootDir, tasks: [], counter: 0, rootFields: {} };
|
|
38549
40454
|
}
|
|
@@ -38577,7 +40482,7 @@ function saveHandle(rootDir, handle) {
|
|
|
38577
40482
|
"PLAN_TOO_MANY_TASKS"
|
|
38578
40483
|
);
|
|
38579
40484
|
}
|
|
38580
|
-
const jsonPath =
|
|
40485
|
+
const jsonPath = join18(rootDir, "plan.json");
|
|
38581
40486
|
mkdirSync11(rootDir, { recursive: true });
|
|
38582
40487
|
if (existsSync20(jsonPath)) {
|
|
38583
40488
|
copyFileSync(jsonPath, `${jsonPath}.bak`);
|
|
@@ -38939,7 +40844,7 @@ var init_inspectTypecheckSafety = __esm({
|
|
|
38939
40844
|
|
|
38940
40845
|
// src/cli/tools/inspectCommand.ts
|
|
38941
40846
|
import { spawn as spawn8 } from "node:child_process";
|
|
38942
|
-
import { createHash as
|
|
40847
|
+
import { createHash as createHash11 } from "node:crypto";
|
|
38943
40848
|
import { existsSync as existsSync21, promises as fs16 } from "node:fs";
|
|
38944
40849
|
import os7 from "node:os";
|
|
38945
40850
|
import path31 from "node:path";
|
|
@@ -39026,7 +40931,7 @@ function buildInspectCommand(op, ctx) {
|
|
|
39026
40931
|
}
|
|
39027
40932
|
case "typecheck": {
|
|
39028
40933
|
const project = path31.resolve(ctx.cwd, op.project ?? "tsconfig.json");
|
|
39029
|
-
const hash3 =
|
|
40934
|
+
const hash3 = createHash11("sha256").update(project).digest("hex").slice(0, 16);
|
|
39030
40935
|
const tsBuildInfoFile = path31.join(os7.tmpdir(), "zelari-inspect", `${hash3}.tsbuildinfo`);
|
|
39031
40936
|
return {
|
|
39032
40937
|
ok: true,
|
|
@@ -40184,7 +42089,7 @@ var init_manager = __esm({
|
|
|
40184
42089
|
});
|
|
40185
42090
|
|
|
40186
42091
|
// src/cli/ast/engine.ts
|
|
40187
|
-
import { readFile } from "node:fs/promises";
|
|
42092
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
40188
42093
|
import path33 from "node:path";
|
|
40189
42094
|
function loadTs() {
|
|
40190
42095
|
if (!tsPromise) {
|
|
@@ -40218,7 +42123,7 @@ async function parseFileSymbolsDiag(file2, cwd) {
|
|
|
40218
42123
|
}
|
|
40219
42124
|
let text;
|
|
40220
42125
|
try {
|
|
40221
|
-
text = await
|
|
42126
|
+
text = await readFile2(resolvedPath, "utf8");
|
|
40222
42127
|
} catch (err) {
|
|
40223
42128
|
const code = err?.code;
|
|
40224
42129
|
if (code === "ENOENT") {
|
|
@@ -40465,9 +42370,9 @@ var init_store2 = __esm({
|
|
|
40465
42370
|
import { promises as fs17, existsSync as existsSync22, readFileSync as readFileSync19 } from "node:fs";
|
|
40466
42371
|
import { homedir as homedir6 } from "node:os";
|
|
40467
42372
|
import path34 from "node:path";
|
|
40468
|
-
import { createHash as
|
|
42373
|
+
import { createHash as createHash12 } from "node:crypto";
|
|
40469
42374
|
function getIndexPath(root) {
|
|
40470
|
-
const hash3 =
|
|
42375
|
+
const hash3 = createHash12("sha1").update(path34.resolve(root)).digest("hex").slice(0, 16);
|
|
40471
42376
|
return process.env.ZELARI_SEMANTIC_FILE ?? path34.join(homedir6(), ".tmp", "zelari-code", "semantic", `${hash3}.json`);
|
|
40472
42377
|
}
|
|
40473
42378
|
async function collectSourceFiles(root, maxFiles = 1500) {
|
|
@@ -41479,10 +43384,10 @@ function asPlaywright(mod) {
|
|
|
41479
43384
|
return null;
|
|
41480
43385
|
}
|
|
41481
43386
|
async function loadPlaywright(cwd) {
|
|
41482
|
-
const
|
|
41483
|
-
if (
|
|
43387
|
+
const base2 = cwd && cwd.length > 0 ? path36.resolve(cwd) : void 0;
|
|
43388
|
+
if (base2) {
|
|
41484
43389
|
try {
|
|
41485
|
-
const req = createRequire2(path36.join(
|
|
43390
|
+
const req = createRequire2(path36.join(base2, "package.json"));
|
|
41486
43391
|
const resolved = req.resolve("playwright");
|
|
41487
43392
|
const mod = await import(pathToFileURL(resolved).href);
|
|
41488
43393
|
const pw = asPlaywright(mod);
|
|
@@ -41533,12 +43438,12 @@ async function runBrowserCheck(options, loader) {
|
|
|
41533
43438
|
const pageErrors = [];
|
|
41534
43439
|
const failedRequests = [];
|
|
41535
43440
|
const evaluateResults = [];
|
|
41536
|
-
const
|
|
43441
|
+
const base2 = { ok: false, consoleErrors, pageErrors, failedRequests };
|
|
41537
43442
|
const resolve7 = loader ?? (() => loadPlaywright(options.cwd ?? process.cwd()));
|
|
41538
43443
|
const pw = await resolve7();
|
|
41539
43444
|
if (!pw) {
|
|
41540
43445
|
return {
|
|
41541
|
-
...
|
|
43446
|
+
...base2,
|
|
41542
43447
|
error: "browser automation unavailable \u2014 Playwright is not installed in this workspace. Install it with: `zelari-code --plugins-install playwright --cwd .` (or Desktop banner \u201CInstall\u201D, or CLI `/plugins install playwright`, or `npm i -D playwright && npx playwright install chromium`). Then re-run browser_check."
|
|
41543
43448
|
};
|
|
41544
43449
|
}
|
|
@@ -41678,7 +43583,7 @@ async function runBrowserCheck(options, loader) {
|
|
|
41678
43583
|
...screenshotPath ? { screenshotPath } : {}
|
|
41679
43584
|
};
|
|
41680
43585
|
} catch (err) {
|
|
41681
|
-
return { ...
|
|
43586
|
+
return { ...base2, error: err instanceof Error ? err.message : String(err) };
|
|
41682
43587
|
} finally {
|
|
41683
43588
|
try {
|
|
41684
43589
|
await browser?.close();
|
|
@@ -41813,14 +43718,14 @@ import {
|
|
|
41813
43718
|
readFileSync as readFileSync20,
|
|
41814
43719
|
writeFileSync as writeFileSync15
|
|
41815
43720
|
} from "node:fs";
|
|
41816
|
-
import { dirname as dirname4, join as
|
|
43721
|
+
import { dirname as dirname4, join as join19 } from "node:path";
|
|
41817
43722
|
import { homedir as homedir7 } from "node:os";
|
|
41818
43723
|
import { spawn as spawn10 } from "node:child_process";
|
|
41819
43724
|
function getSshTargetsPath() {
|
|
41820
|
-
return
|
|
43725
|
+
return join19(homedir7(), ".zelari-code", "ssh-targets.json");
|
|
41821
43726
|
}
|
|
41822
43727
|
function getSshSecretsPath() {
|
|
41823
|
-
return
|
|
43728
|
+
return join19(homedir7(), ".zelari-code", "ssh-secrets.json");
|
|
41824
43729
|
}
|
|
41825
43730
|
function normalizeAuth(auth) {
|
|
41826
43731
|
if (auth === "keyPath") return "keyPath";
|
|
@@ -41993,16 +43898,16 @@ function buildSshBaseArgs(target) {
|
|
|
41993
43898
|
return args;
|
|
41994
43899
|
}
|
|
41995
43900
|
function ensureAskpassHelper() {
|
|
41996
|
-
const dir =
|
|
43901
|
+
const dir = join19(homedir7(), ".zelari-code", "ssh-helpers");
|
|
41997
43902
|
mkdirSync12(dir, { recursive: true });
|
|
41998
|
-
const cjs =
|
|
43903
|
+
const cjs = join19(dir, "askpass.cjs");
|
|
41999
43904
|
writeFileSync15(
|
|
42000
43905
|
cjs,
|
|
42001
43906
|
"process.stdout.write(process.env.ZELARI_SSH_ASKPASS_PASS || '');\n",
|
|
42002
43907
|
"utf8"
|
|
42003
43908
|
);
|
|
42004
43909
|
if (process.platform === "win32") {
|
|
42005
|
-
const cmd =
|
|
43910
|
+
const cmd = join19(dir, "askpass.cmd");
|
|
42006
43911
|
writeFileSync15(
|
|
42007
43912
|
cmd,
|
|
42008
43913
|
`@echo off\r
|
|
@@ -42012,7 +43917,7 @@ node "%~dp0askpass.cjs"\r
|
|
|
42012
43917
|
);
|
|
42013
43918
|
return cmd;
|
|
42014
43919
|
}
|
|
42015
|
-
const sh =
|
|
43920
|
+
const sh = join19(dir, "askpass.sh");
|
|
42016
43921
|
writeFileSync15(
|
|
42017
43922
|
sh,
|
|
42018
43923
|
`#!/bin/sh
|
|
@@ -42757,8 +44662,8 @@ function anthropicMessagesProvider(config2) {
|
|
|
42757
44662
|
if (t.degraded) console.warn(`[thinking] ${t.note ?? "unsupported"} \u2014 falling back to provider default.`);
|
|
42758
44663
|
else Object.assign(body, t.patch);
|
|
42759
44664
|
}
|
|
42760
|
-
const
|
|
42761
|
-
const url2 = `${
|
|
44665
|
+
const base2 = config2.baseUrl.replace(/\/$/, "").replace(/\/v1$/, "");
|
|
44666
|
+
const url2 = `${base2}/v1/messages`;
|
|
42762
44667
|
let response;
|
|
42763
44668
|
try {
|
|
42764
44669
|
response = await fetch(url2, {
|
|
@@ -42969,8 +44874,8 @@ function chatgptResponsesProvider(config2) {
|
|
|
42969
44874
|
if (t.degraded) console.warn(`[thinking] ${t.note ?? "unsupported"} \u2014 falling back to provider default.`);
|
|
42970
44875
|
else Object.assign(body, t.patch);
|
|
42971
44876
|
}
|
|
42972
|
-
const
|
|
42973
|
-
const url2 = `${
|
|
44877
|
+
const base2 = config2.baseUrl.replace(/\/$/, "");
|
|
44878
|
+
const url2 = `${base2}/responses`;
|
|
42974
44879
|
let response;
|
|
42975
44880
|
try {
|
|
42976
44881
|
response = await fetch(url2, {
|
|
@@ -43293,13 +45198,13 @@ var init_folderTrust = __esm({
|
|
|
43293
45198
|
|
|
43294
45199
|
// src/cli/safety/lifecycleHooks.ts
|
|
43295
45200
|
import { homedir as homedir9 } from "node:os";
|
|
43296
|
-
import { join as
|
|
45201
|
+
import { join as join20 } from "node:path";
|
|
43297
45202
|
import { readdirSync as readdirSync5, statSync as statSync3 } from "node:fs";
|
|
43298
45203
|
function globalHooksDir() {
|
|
43299
|
-
return
|
|
45204
|
+
return join20(homedir9(), ".zelari-code", "hooks");
|
|
43300
45205
|
}
|
|
43301
45206
|
function projectHooksDir(projectRoot) {
|
|
43302
|
-
return
|
|
45207
|
+
return join20(projectRoot, ".zelari", "hooks");
|
|
43303
45208
|
}
|
|
43304
45209
|
function fingerprintHookDirs(dirs) {
|
|
43305
45210
|
const parts = [];
|
|
@@ -43320,7 +45225,7 @@ function fingerprintHookDirs(dirs) {
|
|
|
43320
45225
|
continue;
|
|
43321
45226
|
}
|
|
43322
45227
|
for (const name of names) {
|
|
43323
|
-
const full =
|
|
45228
|
+
const full = join20(dir, name);
|
|
43324
45229
|
try {
|
|
43325
45230
|
const st = statSync3(full);
|
|
43326
45231
|
parts.push(`${full}:${st.mtimeMs}:${st.size}`);
|
|
@@ -43361,7 +45266,7 @@ var init_lifecycleHooks = __esm({
|
|
|
43361
45266
|
});
|
|
43362
45267
|
|
|
43363
45268
|
// src/cli/toolResultCache.ts
|
|
43364
|
-
import { createHash as
|
|
45269
|
+
import { createHash as createHash13 } from "node:crypto";
|
|
43365
45270
|
import { promises as fs19 } from "node:fs";
|
|
43366
45271
|
import path40 from "node:path";
|
|
43367
45272
|
function isToolCacheEnabled() {
|
|
@@ -43374,7 +45279,7 @@ function resolveToolCacheTtlMs() {
|
|
|
43374
45279
|
return Number.isFinite(n) && n >= 0 ? n : TOOL_CACHE_DEFAULT_TTL_MS;
|
|
43375
45280
|
}
|
|
43376
45281
|
function hashKey(parts) {
|
|
43377
|
-
return
|
|
45282
|
+
return createHash13("sha256").update(JSON.stringify(parts), "utf8").digest("hex");
|
|
43378
45283
|
}
|
|
43379
45284
|
function resultBytes(result) {
|
|
43380
45285
|
try {
|
|
@@ -43774,7 +45679,8 @@ function createBuiltinToolRegistry(options = {}) {
|
|
|
43774
45679
|
...options.subAgentModel ? { model: options.subAgentModel } : {}
|
|
43775
45680
|
}),
|
|
43776
45681
|
...options.memoryService ? { memoryService: options.memoryService } : {},
|
|
43777
|
-
...options.memoryAutoWrite !== void 0 ? { memoryAutoWrite: options.memoryAutoWrite } : {}
|
|
45682
|
+
...options.memoryAutoWrite !== void 0 ? { memoryAutoWrite: options.memoryAutoWrite } : {},
|
|
45683
|
+
...options.onTentacleEvent ? { onTentacleEvent: options.onTentacleEvent } : {}
|
|
43778
45684
|
},
|
|
43779
45685
|
options.planMode === true ? { allowedAgents: ["explore"] } : void 0
|
|
43780
45686
|
);
|
|
@@ -44219,8 +46125,8 @@ var init_metrics3 = __esm({
|
|
|
44219
46125
|
maybeRotate() {
|
|
44220
46126
|
if (!existsSync25(this.file)) return;
|
|
44221
46127
|
try {
|
|
44222
|
-
const
|
|
44223
|
-
if (
|
|
46128
|
+
const stat2 = statSync4(this.file);
|
|
46129
|
+
if (stat2.size >= METRICS_ROTATE_BYTES) {
|
|
44224
46130
|
const rotated = this.file.replace(/\.jsonl$/, ".1.jsonl");
|
|
44225
46131
|
renameSync3(this.file, rotated);
|
|
44226
46132
|
}
|
|
@@ -44233,11 +46139,11 @@ var init_metrics3 = __esm({
|
|
|
44233
46139
|
});
|
|
44234
46140
|
|
|
44235
46141
|
// src/cli/state/fileStateStore.ts
|
|
44236
|
-
import { createHash as
|
|
46142
|
+
import { createHash as createHash15, randomUUID as randomUUID3 } from "node:crypto";
|
|
44237
46143
|
import { promises as fs21 } from "node:fs";
|
|
44238
46144
|
import * as path43 from "node:path";
|
|
44239
46145
|
function shortId() {
|
|
44240
|
-
return
|
|
46146
|
+
return randomUUID3().replace(/-/g, "").slice(0, 12);
|
|
44241
46147
|
}
|
|
44242
46148
|
async function writeJsonAtomic(filePath, data) {
|
|
44243
46149
|
await fs21.mkdir(path43.dirname(filePath), { recursive: true });
|
|
@@ -44285,7 +46191,7 @@ async function getStateStore(projectRoot, env = process.env) {
|
|
|
44285
46191
|
}
|
|
44286
46192
|
}
|
|
44287
46193
|
function hashStablePrompt(stable) {
|
|
44288
|
-
return
|
|
46194
|
+
return createHash15("sha256").update(stable, "utf8").digest("hex").slice(0, 16);
|
|
44289
46195
|
}
|
|
44290
46196
|
var DEFAULT_MATERIALIZE_CHARS, FileDurableStateStore, NoopDurableStateStore;
|
|
44291
46197
|
var init_fileStateStore = __esm({
|
|
@@ -44931,9 +46837,9 @@ function compactHistoryDetailed(messages, opts) {
|
|
|
44931
46837
|
);
|
|
44932
46838
|
}
|
|
44933
46839
|
async function compactHistoryAsync(messages, opts) {
|
|
44934
|
-
const
|
|
44935
|
-
if (!
|
|
44936
|
-
const cut =
|
|
46840
|
+
const base2 = compactHistoryDetailed(messages, opts);
|
|
46841
|
+
if (!base2.compacted || base2.messagesRemoved === 0) return base2;
|
|
46842
|
+
const cut = base2.messagesRemoved;
|
|
44937
46843
|
const droppedMsgs = messages.slice(0, cut);
|
|
44938
46844
|
const extractive = extractiveHistorySummary(droppedMsgs);
|
|
44939
46845
|
let summaryText = extractive;
|
|
@@ -45050,7 +46956,7 @@ __export(conversationContext_exports, {
|
|
|
45050
46956
|
setLastClarification: () => setLastClarification
|
|
45051
46957
|
});
|
|
45052
46958
|
import { existsSync as existsSync26 } from "node:fs";
|
|
45053
|
-
import { join as
|
|
46959
|
+
import { join as join22 } from "node:path";
|
|
45054
46960
|
function getHistory() {
|
|
45055
46961
|
return history;
|
|
45056
46962
|
}
|
|
@@ -45059,7 +46965,7 @@ function setHistory(messages) {
|
|
|
45059
46965
|
history = projected === messages ? [...messages] : projected;
|
|
45060
46966
|
}
|
|
45061
46967
|
function compactInPlace(cwd = process.cwd()) {
|
|
45062
|
-
const durableStatePresent = existsSync26(
|
|
46968
|
+
const durableStatePresent = existsSync26(join22(cwd, ".zelari", "state", "HEAD.json"));
|
|
45063
46969
|
history = applySessionSurface(compactHistory(history, { durableStatePresent }));
|
|
45064
46970
|
}
|
|
45065
46971
|
function appendMessages(msgs) {
|
|
@@ -46102,11 +48008,11 @@ var init_claudeProvider = __esm({
|
|
|
46102
48008
|
});
|
|
46103
48009
|
|
|
46104
48010
|
// src/cli/memory/legacyImport.ts
|
|
46105
|
-
import { createHash as
|
|
48011
|
+
import { createHash as createHash16 } from "node:crypto";
|
|
46106
48012
|
import { promises as fs22 } from "node:fs";
|
|
46107
48013
|
import * as path44 from "node:path";
|
|
46108
48014
|
function sourceId(fact, line) {
|
|
46109
|
-
return `jsonl:${fact.id ??
|
|
48015
|
+
return `jsonl:${fact.id ?? createHash16("sha256").update(line).digest("hex")}`;
|
|
46110
48016
|
}
|
|
46111
48017
|
function kind(metadata2) {
|
|
46112
48018
|
const raw = metadata2.memoryKind;
|
|
@@ -46604,7 +48510,7 @@ WHERE NOT EXISTS (SELECT 1 FROM memory_fts f WHERE f.node_id = n.id);
|
|
|
46604
48510
|
});
|
|
46605
48511
|
|
|
46606
48512
|
// src/cli/memory/sqliteBackend.ts
|
|
46607
|
-
import { createHash as
|
|
48513
|
+
import { createHash as createHash17, randomUUID as randomUUID4 } from "node:crypto";
|
|
46608
48514
|
import { promises as fs23 } from "node:fs";
|
|
46609
48515
|
import * as path46 from "node:path";
|
|
46610
48516
|
function boundedLimit(value, fallback = 50) {
|
|
@@ -46619,7 +48525,7 @@ function withOptional(target, key, value) {
|
|
|
46619
48525
|
return { ...target, [key]: value };
|
|
46620
48526
|
}
|
|
46621
48527
|
function contentHash(content) {
|
|
46622
|
-
return
|
|
48528
|
+
return createHash17("sha256").update(content).digest("hex");
|
|
46623
48529
|
}
|
|
46624
48530
|
var NODE_COLUMNS, INSERT_NODE_SQL, SOURCE_COLUMNS, SQLiteMemoryBackend;
|
|
46625
48531
|
var init_sqliteBackend = __esm({
|
|
@@ -46679,9 +48585,9 @@ VALUES (${Array.from({ length: 19 }, () => "?").join(",")})`;
|
|
|
46679
48585
|
const zelariDirectory = path46.join(resolved, ".zelari");
|
|
46680
48586
|
const directory = path46.join(zelariDirectory, "memory");
|
|
46681
48587
|
for (const candidate of [zelariDirectory, directory]) {
|
|
46682
|
-
let
|
|
48588
|
+
let stat2;
|
|
46683
48589
|
try {
|
|
46684
|
-
|
|
48590
|
+
stat2 = await fs23.lstat(candidate);
|
|
46685
48591
|
} catch (error51) {
|
|
46686
48592
|
if (error51.code !== "ENOENT") throw error51;
|
|
46687
48593
|
try {
|
|
@@ -46689,9 +48595,9 @@ VALUES (${Array.from({ length: 19 }, () => "?").join(",")})`;
|
|
|
46689
48595
|
} catch (mkdirError) {
|
|
46690
48596
|
if (mkdirError.code !== "EEXIST") throw mkdirError;
|
|
46691
48597
|
}
|
|
46692
|
-
|
|
48598
|
+
stat2 = await fs23.lstat(candidate);
|
|
46693
48599
|
}
|
|
46694
|
-
if (
|
|
48600
|
+
if (stat2.isSymbolicLink() || !stat2.isDirectory()) {
|
|
46695
48601
|
throw new Error(`Memory directory is not a real directory: ${candidate}`);
|
|
46696
48602
|
}
|
|
46697
48603
|
}
|
|
@@ -46727,7 +48633,7 @@ VALUES (${Array.from({ length: 19 }, () => "?").join(",")})`;
|
|
|
46727
48633
|
const createdAt = input.createdAt ?? now;
|
|
46728
48634
|
const recordedAt = input.recordedAt ?? createdAt;
|
|
46729
48635
|
const node = MemoryNodeSchema.parse({
|
|
46730
|
-
id: input.id ?? `mem_${
|
|
48636
|
+
id: input.id ?? `mem_${randomUUID4()}`,
|
|
46731
48637
|
schemaVersion: 1,
|
|
46732
48638
|
projectId: input.projectId,
|
|
46733
48639
|
kind: input.kind,
|
|
@@ -46753,7 +48659,7 @@ VALUES (${Array.from({ length: 19 }, () => "?").join(",")})`;
|
|
|
46753
48659
|
(version_id, memory_id, revision, snapshot_json, recorded_at, actor, reason)
|
|
46754
48660
|
VALUES (?, ?, 1, ?, ?, ?, ?)`,
|
|
46755
48661
|
params: [
|
|
46756
|
-
`ver_${
|
|
48662
|
+
`ver_${randomUUID4()}`,
|
|
46757
48663
|
node.id,
|
|
46758
48664
|
JSON.stringify(node),
|
|
46759
48665
|
recordedAt,
|
|
@@ -46814,7 +48720,7 @@ VALUES (${Array.from({ length: 19 }, () => "?").join(",")})`;
|
|
|
46814
48720
|
(version_id, memory_id, revision, snapshot_json, recorded_at, actor, reason)
|
|
46815
48721
|
VALUES (?, ?, (SELECT COALESCE(MAX(revision), 0) + 1 FROM memory_versions WHERE memory_id=?), ?, ?, ?, ?)`,
|
|
46816
48722
|
params: [
|
|
46817
|
-
`ver_${
|
|
48723
|
+
`ver_${randomUUID4()}`,
|
|
46818
48724
|
updated.id,
|
|
46819
48725
|
updated.id,
|
|
46820
48726
|
JSON.stringify(updated),
|
|
@@ -47048,7 +48954,7 @@ VALUES (${Array.from({ length: 19 }, () => "?").join(",")})`;
|
|
|
47048
48954
|
if (decoded) return decoded;
|
|
47049
48955
|
const edge = MemoryEdgeSchema.parse({
|
|
47050
48956
|
...input,
|
|
47051
|
-
id: input.id ?? `edge_${
|
|
48957
|
+
id: input.id ?? `edge_${randomUUID4()}`,
|
|
47052
48958
|
strength: input.strength ?? 1,
|
|
47053
48959
|
confidence: input.confidence ?? 0.8,
|
|
47054
48960
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -47232,7 +49138,7 @@ __export(serviceFactory_exports, {
|
|
|
47232
49138
|
isMemorySemanticEnabled: () => isMemorySemanticEnabled,
|
|
47233
49139
|
isMemoryV2Enabled: () => isMemoryV2Enabled
|
|
47234
49140
|
});
|
|
47235
|
-
import { createHash as
|
|
49141
|
+
import { createHash as createHash18 } from "node:crypto";
|
|
47236
49142
|
import { promises as fs24 } from "node:fs";
|
|
47237
49143
|
import * as path47 from "node:path";
|
|
47238
49144
|
function isMemoryV2Enabled(env = process.env) {
|
|
@@ -47259,7 +49165,7 @@ async function canonicalProjectId(projectRoot) {
|
|
|
47259
49165
|
}
|
|
47260
49166
|
canonical = canonical.replace(/\\/g, "/").replace(/\/$/, "");
|
|
47261
49167
|
if (process.platform === "win32") canonical = canonical.toLocaleLowerCase("en-US");
|
|
47262
|
-
return `project_${
|
|
49168
|
+
return `project_${createHash18("sha256").update(canonical).digest("hex").slice(0, 24)}`;
|
|
47263
49169
|
}
|
|
47264
49170
|
async function getMemoryService(projectRoot, env = process.env, options = {}) {
|
|
47265
49171
|
const projectId2 = await canonicalProjectId(projectRoot);
|
|
@@ -47324,10 +49230,10 @@ var init_serviceFactory = __esm({
|
|
|
47324
49230
|
|
|
47325
49231
|
// src/cli/workspace/projectInstructions.ts
|
|
47326
49232
|
import { existsSync as existsSync28, readFileSync as readFileSync23 } from "node:fs";
|
|
47327
|
-
import { join as
|
|
49233
|
+
import { join as join26 } from "node:path";
|
|
47328
49234
|
function loadProjectInstructions(projectRoot = process.cwd(), maxChars = MAX_CHARS) {
|
|
47329
49235
|
for (const name of CANDIDATES) {
|
|
47330
|
-
const full =
|
|
49236
|
+
const full = join26(projectRoot, name);
|
|
47331
49237
|
if (!existsSync28(full)) continue;
|
|
47332
49238
|
try {
|
|
47333
49239
|
let raw = readFileSync23(full, "utf8");
|
|
@@ -47375,7 +49281,7 @@ __export(workspaceSummary_exports, {
|
|
|
47375
49281
|
buildZelariReadHint: () => buildZelariReadHint
|
|
47376
49282
|
});
|
|
47377
49283
|
import { existsSync as existsSync29, readFileSync as readFileSync24, readdirSync as readdirSync6, statSync as statSync5 } from "node:fs";
|
|
47378
|
-
import { join as
|
|
49284
|
+
import { join as join27, relative as relative2 } from "node:path";
|
|
47379
49285
|
function buildWorkspaceSummary(projectRoot = process.cwd(), options = {}) {
|
|
47380
49286
|
const { maxEntries = 30, maxChars = 3500, maxDeps = 24, maxScripts = 16 } = options;
|
|
47381
49287
|
const name = safeProjectName(projectRoot);
|
|
@@ -47408,7 +49314,7 @@ function formatTaskLine(t) {
|
|
|
47408
49314
|
}
|
|
47409
49315
|
function buildPlanSummary(projectRoot = process.cwd(), options) {
|
|
47410
49316
|
const zelariRoot = resolveWorkspaceRoot(projectRoot);
|
|
47411
|
-
const planPath =
|
|
49317
|
+
const planPath = join27(zelariRoot, "plan.json");
|
|
47412
49318
|
if (!existsSync29(planPath)) return null;
|
|
47413
49319
|
let plan;
|
|
47414
49320
|
try {
|
|
@@ -47551,7 +49457,7 @@ function pickNextTask(open) {
|
|
|
47551
49457
|
)[0];
|
|
47552
49458
|
}
|
|
47553
49459
|
function buildZelariReadHint(projectRoot = process.cwd()) {
|
|
47554
|
-
const planPath =
|
|
49460
|
+
const planPath = join27(resolveWorkspaceRoot(projectRoot), "plan.json");
|
|
47555
49461
|
if (!existsSync29(planPath)) return "";
|
|
47556
49462
|
return [
|
|
47557
49463
|
"# Council workspace detected (.zelari/) \u2014 DRAFT vault",
|
|
@@ -47567,7 +49473,7 @@ function safeProjectName(root) {
|
|
|
47567
49473
|
}
|
|
47568
49474
|
}
|
|
47569
49475
|
function readPackageJson(projectRoot) {
|
|
47570
|
-
const p3 =
|
|
49476
|
+
const p3 = join27(projectRoot, "package.json");
|
|
47571
49477
|
if (!existsSync29(p3)) return null;
|
|
47572
49478
|
try {
|
|
47573
49479
|
return JSON.parse(readFileSync24(p3, "utf8"));
|
|
@@ -47620,11 +49526,11 @@ function listShallow(projectRoot, maxEntries) {
|
|
|
47620
49526
|
out.push(`\u2026 (+${top.length - count} more)`);
|
|
47621
49527
|
break;
|
|
47622
49528
|
}
|
|
47623
|
-
const rel2 = relative2(projectRoot,
|
|
49529
|
+
const rel2 = relative2(projectRoot, join27(projectRoot, entry.name));
|
|
47624
49530
|
if (entry.isDirectory()) {
|
|
47625
49531
|
let inner = "";
|
|
47626
49532
|
try {
|
|
47627
|
-
const sub = readdirSync6(
|
|
49533
|
+
const sub = readdirSync6(join27(projectRoot, entry.name), {
|
|
47628
49534
|
withFileTypes: true
|
|
47629
49535
|
}).filter((e) => !e.name.startsWith(".")).slice(0, 4).map((e) => e.name);
|
|
47630
49536
|
if (sub.length > 0)
|
|
@@ -47673,11 +49579,11 @@ var init_workspaceSummary = __esm({
|
|
|
47673
49579
|
|
|
47674
49580
|
// src/cli/workspace/buildLessonsSummary.ts
|
|
47675
49581
|
import { existsSync as existsSync30 } from "node:fs";
|
|
47676
|
-
import { join as
|
|
49582
|
+
import { join as join28 } from "node:path";
|
|
47677
49583
|
function buildLessonsSummary(projectRoot = process.cwd(), taskText) {
|
|
47678
49584
|
if (process.env["ZELARI_LESSONS"] === "0") return null;
|
|
47679
49585
|
const zelariRoot = resolveWorkspaceRoot(projectRoot);
|
|
47680
|
-
if (!existsSync30(
|
|
49586
|
+
if (!existsSync30(join28(zelariRoot, "lessons.jsonl"))) return null;
|
|
47681
49587
|
const lessons = recallLessons(zelariRoot, {
|
|
47682
49588
|
maxLessons: 5,
|
|
47683
49589
|
maxBytes: 2048,
|
|
@@ -47699,7 +49605,7 @@ __export(composeContext_exports, {
|
|
|
47699
49605
|
composeProjectContext: () => composeProjectContext
|
|
47700
49606
|
});
|
|
47701
49607
|
import { existsSync as existsSync31, readdirSync as readdirSync7, readFileSync as readFileSync25 } from "node:fs";
|
|
47702
|
-
import { join as
|
|
49608
|
+
import { join as join29 } from "node:path";
|
|
47703
49609
|
function cap2(text, max, label) {
|
|
47704
49610
|
if (!text || text.length <= max) return { text: text || "", truncated: false };
|
|
47705
49611
|
return {
|
|
@@ -47716,7 +49622,7 @@ function buildDesignIndex(projectRoot, maxChars) {
|
|
|
47716
49622
|
"# Design vault index (.zelari/) \u2014 HYPOTHESES only",
|
|
47717
49623
|
"Full design docs are NOT product source of truth. Open with list_files / read_file / searchDocuments if needed."
|
|
47718
49624
|
];
|
|
47719
|
-
const docsDir =
|
|
49625
|
+
const docsDir = join29(root, "docs");
|
|
47720
49626
|
if (existsSync31(docsDir)) {
|
|
47721
49627
|
try {
|
|
47722
49628
|
const docs = readdirSync7(docsDir).filter((n) => n.endsWith(".md")).slice(0, 12);
|
|
@@ -47731,11 +49637,11 @@ function buildDesignIndex(projectRoot, maxChars) {
|
|
|
47731
49637
|
}
|
|
47732
49638
|
}
|
|
47733
49639
|
for (const name of ["risks.md", "plan.json", "nfr-spec.json"]) {
|
|
47734
|
-
if (existsSync31(
|
|
49640
|
+
if (existsSync31(join29(root, name))) {
|
|
47735
49641
|
lines.push(`- .zelari/${name} present`);
|
|
47736
49642
|
}
|
|
47737
49643
|
}
|
|
47738
|
-
const decisionsDir =
|
|
49644
|
+
const decisionsDir = join29(root, "decisions");
|
|
47739
49645
|
if (existsSync31(decisionsDir)) {
|
|
47740
49646
|
try {
|
|
47741
49647
|
const n = readdirSync7(decisionsDir).filter((f) => f.endsWith(".md")).length;
|
|
@@ -47837,14 +49743,14 @@ function composeProjectContext(input) {
|
|
|
47837
49743
|
}
|
|
47838
49744
|
function readDurableHeadSync(projectRoot) {
|
|
47839
49745
|
try {
|
|
47840
|
-
const headPath =
|
|
49746
|
+
const headPath = join29(projectRoot, ".zelari", "state", "HEAD.json");
|
|
47841
49747
|
if (!existsSync31(headPath)) return "";
|
|
47842
49748
|
const head = JSON.parse(readFileSync25(headPath, "utf8"));
|
|
47843
49749
|
if (!head?.id) return "";
|
|
47844
|
-
const metaPath =
|
|
49750
|
+
const metaPath = join29(projectRoot, ".zelari", "state", "commits", `${head.id}.json`);
|
|
47845
49751
|
if (!existsSync31(metaPath)) return "";
|
|
47846
49752
|
const meta3 = JSON.parse(readFileSync25(metaPath, "utf8"));
|
|
47847
|
-
const discPath = meta3.artifactDir ?
|
|
49753
|
+
const discPath = meta3.artifactDir ? join29(projectRoot, ".zelari", "state", meta3.artifactDir, "discoveries.json") : join29(projectRoot, ".zelari", "state", "artifacts", head.id, "discoveries.json");
|
|
47848
49754
|
let discoveries = [];
|
|
47849
49755
|
if (existsSync31(discPath)) {
|
|
47850
49756
|
discoveries = JSON.parse(readFileSync25(discPath, "utf8"));
|
|
@@ -47881,9 +49787,9 @@ __export(planDetect_exports, {
|
|
|
47881
49787
|
hasWorkspacePlan: () => hasWorkspacePlan
|
|
47882
49788
|
});
|
|
47883
49789
|
import { existsSync as existsSync32, readFileSync as readFileSync26 } from "node:fs";
|
|
47884
|
-
import { join as
|
|
49790
|
+
import { join as join30 } from "node:path";
|
|
47885
49791
|
function hasWorkspacePlan(projectRoot = process.cwd()) {
|
|
47886
|
-
const planPath =
|
|
49792
|
+
const planPath = join30(resolveWorkspaceRoot(projectRoot), "plan.json");
|
|
47887
49793
|
if (!existsSync32(planPath)) return false;
|
|
47888
49794
|
try {
|
|
47889
49795
|
const parsed = JSON.parse(readFileSync26(planPath, "utf8"));
|
|
@@ -47952,7 +49858,7 @@ import {
|
|
|
47952
49858
|
mkdirSync as mkdirSync15,
|
|
47953
49859
|
renameSync as renameSync4
|
|
47954
49860
|
} from "node:fs";
|
|
47955
|
-
import { join as
|
|
49861
|
+
import { join as join31, basename as basename3, dirname as dirname8, relative as relative3 } from "node:path";
|
|
47956
49862
|
function createWorkspaceContext(projectRoot = process.cwd()) {
|
|
47957
49863
|
const rootDir = resolveWorkspaceRoot(projectRoot);
|
|
47958
49864
|
return {
|
|
@@ -47962,7 +49868,7 @@ function createWorkspaceContext(projectRoot = process.cwd()) {
|
|
|
47962
49868
|
};
|
|
47963
49869
|
}
|
|
47964
49870
|
function planJsonPath(ctx) {
|
|
47965
|
-
return
|
|
49871
|
+
return join31(ctx.rootDir, "plan.json");
|
|
47966
49872
|
}
|
|
47967
49873
|
function readPlan(ctx) {
|
|
47968
49874
|
const jsonPath = planJsonPath(ctx);
|
|
@@ -48075,7 +49981,7 @@ function renderPlanBody(summary) {
|
|
|
48075
49981
|
return lines.join("\n");
|
|
48076
49982
|
}
|
|
48077
49983
|
function nextAdrId(ctx) {
|
|
48078
|
-
const decisionsDir =
|
|
49984
|
+
const decisionsDir = join31(ctx.rootDir, "decisions");
|
|
48079
49985
|
if (!existsSync33(decisionsDir)) return "001";
|
|
48080
49986
|
const existing = readdirSync8(decisionsDir).filter((f) => f.endsWith(".md")).map((f) => f.match(/^(\d+)-/)).filter((m) => !!m).map((m) => parseInt(m[1], 10));
|
|
48081
49987
|
const max = existing.length === 0 ? 0 : Math.max(...existing);
|
|
@@ -48118,7 +50024,7 @@ function addTaskRecord(ctx, summary, phaseId, t, options) {
|
|
|
48118
50024
|
status: "pending",
|
|
48119
50025
|
priority: t.priority
|
|
48120
50026
|
});
|
|
48121
|
-
const taskPath =
|
|
50027
|
+
const taskPath = join31(ctx.rootDir, "plan-tasks", `${id3}.md`);
|
|
48122
50028
|
const meta3 = {
|
|
48123
50029
|
kind: "task",
|
|
48124
50030
|
id: id3,
|
|
@@ -48160,7 +50066,7 @@ function addMilestoneRecord(ctx, summary, input) {
|
|
|
48160
50066
|
dueDate: input.dueDate,
|
|
48161
50067
|
targetVersion: version2
|
|
48162
50068
|
});
|
|
48163
|
-
const path72 =
|
|
50069
|
+
const path72 = join31(ctx.rootDir, "milestones", `${id3}.md`);
|
|
48164
50070
|
const meta3 = {
|
|
48165
50071
|
kind: "milestone",
|
|
48166
50072
|
id: id3,
|
|
@@ -48458,7 +50364,7 @@ function createNfrSpecStub(ctx) {
|
|
|
48458
50364
|
},
|
|
48459
50365
|
planFeatureKeywords: Array.isArray(args["planFeatureKeywords"]) ? args["planFeatureKeywords"] : void 0
|
|
48460
50366
|
};
|
|
48461
|
-
const outPath =
|
|
50367
|
+
const outPath = join31(ctx.rootDir, "nfr-spec.json");
|
|
48462
50368
|
writeFileSync17(outPath, JSON.stringify(spec, null, 2), "utf8");
|
|
48463
50369
|
return `NFR spec written to nfr-spec.json (${targets.length} target(s)).`;
|
|
48464
50370
|
});
|
|
@@ -48522,11 +50428,11 @@ function searchDocumentsStub(ctx) {
|
|
|
48522
50428
|
(w) => w.length >= 3 && w !== "or" && w !== "and" && w !== "the"
|
|
48523
50429
|
);
|
|
48524
50430
|
const files = [
|
|
48525
|
-
...ctx.storage.listMarkdown(
|
|
48526
|
-
...ctx.storage.listMarkdown(
|
|
48527
|
-
...ctx.storage.listMarkdown(
|
|
48528
|
-
...ctx.storage.listMarkdown(
|
|
48529
|
-
...ctx.storage.listMarkdown(
|
|
50431
|
+
...ctx.storage.listMarkdown(join31(ctx.rootDir, "decisions")),
|
|
50432
|
+
...ctx.storage.listMarkdown(join31(ctx.rootDir, "docs")),
|
|
50433
|
+
...ctx.storage.listMarkdown(join31(ctx.rootDir, "reviews")),
|
|
50434
|
+
...ctx.storage.listMarkdown(join31(ctx.rootDir, "plan-tasks")),
|
|
50435
|
+
...ctx.storage.listMarkdown(join31(ctx.rootDir, "milestones")),
|
|
48530
50436
|
workspaceFile(ctx.rootDir, "plan"),
|
|
48531
50437
|
workspaceFile(ctx.rootDir, "risks")
|
|
48532
50438
|
];
|
|
@@ -48584,9 +50490,9 @@ function linkDocumentsStub(ctx) {
|
|
|
48584
50490
|
const toId = args["toId"] ?? args["targetId"] ?? args["targetPathOrTitle"];
|
|
48585
50491
|
if (!fromId || !toId) return "linkDocuments requires fromId and toId.";
|
|
48586
50492
|
const allFiles = [
|
|
48587
|
-
...ctx.storage.listMarkdown(
|
|
48588
|
-
...ctx.storage.listMarkdown(
|
|
48589
|
-
...ctx.storage.listMarkdown(
|
|
50493
|
+
...ctx.storage.listMarkdown(join31(ctx.rootDir, "decisions")),
|
|
50494
|
+
...ctx.storage.listMarkdown(join31(ctx.rootDir, "docs")),
|
|
50495
|
+
...ctx.storage.listMarkdown(join31(ctx.rootDir, "reviews"))
|
|
48590
50496
|
];
|
|
48591
50497
|
const source2 = allFiles.find((f) => {
|
|
48592
50498
|
try {
|
|
@@ -48617,9 +50523,9 @@ function getDocumentBacklinksStub(ctx) {
|
|
|
48617
50523
|
const targetId = args["targetId"] ?? args["id"];
|
|
48618
50524
|
if (!targetId) return "getDocumentBacklinks requires targetId.";
|
|
48619
50525
|
const allFiles = [
|
|
48620
|
-
...ctx.storage.listMarkdown(
|
|
48621
|
-
...ctx.storage.listMarkdown(
|
|
48622
|
-
...ctx.storage.listMarkdown(
|
|
50526
|
+
...ctx.storage.listMarkdown(join31(ctx.rootDir, "decisions")),
|
|
50527
|
+
...ctx.storage.listMarkdown(join31(ctx.rootDir, "docs")),
|
|
50528
|
+
...ctx.storage.listMarkdown(join31(ctx.rootDir, "reviews"))
|
|
48623
50529
|
];
|
|
48624
50530
|
const backlinks = [];
|
|
48625
50531
|
for (const file2 of allFiles) {
|
|
@@ -48875,15 +50781,15 @@ import {
|
|
|
48875
50781
|
readFileSync as readFileSync28,
|
|
48876
50782
|
writeFileSync as writeFileSync18
|
|
48877
50783
|
} from "node:fs";
|
|
48878
|
-
import { dirname as dirname9, join as
|
|
50784
|
+
import { dirname as dirname9, join as join32 } from "node:path";
|
|
48879
50785
|
import { homedir as homedir10 } from "node:os";
|
|
48880
50786
|
function getUserMcpPath() {
|
|
48881
|
-
return
|
|
50787
|
+
return join32(homedir10(), ".zelari-code", "mcp.json");
|
|
48882
50788
|
}
|
|
48883
50789
|
function getProjectMcpPath(projectRoot) {
|
|
48884
|
-
return
|
|
50790
|
+
return join32(projectRoot, ".zelari", "mcp.json");
|
|
48885
50791
|
}
|
|
48886
|
-
function
|
|
50792
|
+
function readFile4(path72) {
|
|
48887
50793
|
if (!existsSync34(path72)) return {};
|
|
48888
50794
|
try {
|
|
48889
50795
|
const parsed = JSON.parse(readFileSync28(path72, "utf8"));
|
|
@@ -48902,7 +50808,7 @@ function readFile3(path72) {
|
|
|
48902
50808
|
return {};
|
|
48903
50809
|
}
|
|
48904
50810
|
}
|
|
48905
|
-
function
|
|
50811
|
+
function writeFile2(path72, servers) {
|
|
48906
50812
|
mkdirSync16(dirname9(path72), { recursive: true });
|
|
48907
50813
|
const body = { mcpServers: servers };
|
|
48908
50814
|
writeFileSync18(path72, `${JSON.stringify(body, null, 2)}
|
|
@@ -48910,9 +50816,9 @@ function writeFile(path72, servers) {
|
|
|
48910
50816
|
}
|
|
48911
50817
|
function listMcpServers(projectRoot) {
|
|
48912
50818
|
const userPath = getUserMcpPath();
|
|
48913
|
-
const userServers =
|
|
50819
|
+
const userServers = readFile4(userPath);
|
|
48914
50820
|
const projectPath = projectRoot && projectRoot.trim() ? getProjectMcpPath(projectRoot.trim()) : null;
|
|
48915
|
-
const projectServers = projectPath ?
|
|
50821
|
+
const projectServers = projectPath ? readFile4(projectPath) : {};
|
|
48916
50822
|
const servers = [];
|
|
48917
50823
|
for (const [name, cfg] of Object.entries(userServers)) {
|
|
48918
50824
|
servers.push({ name, ...cfg, scope: "user", path: userPath });
|
|
@@ -48951,14 +50857,14 @@ function upsertMcpServer(opts) {
|
|
|
48951
50857
|
}
|
|
48952
50858
|
path72 = getProjectMcpPath(root);
|
|
48953
50859
|
}
|
|
48954
|
-
const current =
|
|
50860
|
+
const current = readFile4(path72);
|
|
48955
50861
|
current[name] = {
|
|
48956
50862
|
command: opts.config.command.trim(),
|
|
48957
50863
|
args: opts.config.args,
|
|
48958
50864
|
env: opts.config.env,
|
|
48959
50865
|
enabled: opts.config.enabled !== false
|
|
48960
50866
|
};
|
|
48961
|
-
|
|
50867
|
+
writeFile2(path72, current);
|
|
48962
50868
|
return { ok: true, path: path72 };
|
|
48963
50869
|
}
|
|
48964
50870
|
function removeMcpServer(opts) {
|
|
@@ -48966,12 +50872,12 @@ function removeMcpServer(opts) {
|
|
|
48966
50872
|
if (!path72) {
|
|
48967
50873
|
return { ok: false, error: "projectRoot required for project scope" };
|
|
48968
50874
|
}
|
|
48969
|
-
const current =
|
|
50875
|
+
const current = readFile4(path72);
|
|
48970
50876
|
if (!(opts.name in current)) {
|
|
48971
50877
|
return { ok: false, error: `Server "${opts.name}" not found in ${path72}` };
|
|
48972
50878
|
}
|
|
48973
50879
|
delete current[opts.name];
|
|
48974
|
-
|
|
50880
|
+
writeFile2(path72, current);
|
|
48975
50881
|
return { ok: true, path: path72 };
|
|
48976
50882
|
}
|
|
48977
50883
|
var init_mcpConfigIo = __esm({
|
|
@@ -49115,16 +51021,16 @@ __export(mcpManager_exports, {
|
|
|
49115
51021
|
registerMcpTools: () => registerMcpTools
|
|
49116
51022
|
});
|
|
49117
51023
|
import { existsSync as existsSync35, readFileSync as readFileSync29 } from "node:fs";
|
|
49118
|
-
import { join as
|
|
51024
|
+
import { join as join33 } from "node:path";
|
|
49119
51025
|
import { homedir as homedir11 } from "node:os";
|
|
49120
51026
|
function readMcpConfig(projectRoot = process.cwd(), opts) {
|
|
49121
51027
|
const merged = {};
|
|
49122
51028
|
const paths = [];
|
|
49123
51029
|
if (process.env["ZELARI_MCP_USER"] !== "0") {
|
|
49124
|
-
paths.push(
|
|
51030
|
+
paths.push(join33(homedir11(), ".zelari-code", "mcp.json"));
|
|
49125
51031
|
}
|
|
49126
51032
|
if (!opts?.skipProjectMcp) {
|
|
49127
|
-
paths.push(
|
|
51033
|
+
paths.push(join33(projectRoot, ".zelari", "mcp.json"));
|
|
49128
51034
|
}
|
|
49129
51035
|
for (const p3 of paths) {
|
|
49130
51036
|
if (!existsSync35(p3)) continue;
|
|
@@ -49143,7 +51049,7 @@ async function ensureLoaded(projectRoot) {
|
|
|
49143
51049
|
if (state2.loaded) return;
|
|
49144
51050
|
state2.loaded = true;
|
|
49145
51051
|
const trusted = isFolderTrusted(projectRoot);
|
|
49146
|
-
if (!trusted && existsSync35(
|
|
51052
|
+
if (!trusted && existsSync35(join33(projectRoot, ".zelari", "mcp.json"))) {
|
|
49147
51053
|
state2.warnings.push(
|
|
49148
51054
|
"[mcp] project .zelari/mcp.json ignored \u2014 folder not trusted (run /trust or `zelari-code --trust` to enable project MCP)"
|
|
49149
51055
|
);
|
|
@@ -49369,14 +51275,14 @@ __export(agentsMd_exports, {
|
|
|
49369
51275
|
updateAgentsMd: () => updateAgentsMd
|
|
49370
51276
|
});
|
|
49371
51277
|
import { existsSync as existsSync36, readFileSync as readFileSync30, writeFileSync as writeFileSync19 } from "node:fs";
|
|
49372
|
-
import { createHash as
|
|
49373
|
-
import { join as
|
|
49374
|
-
import { readFile as
|
|
51278
|
+
import { createHash as createHash19 } from "node:crypto";
|
|
51279
|
+
import { join as join34 } from "node:path";
|
|
51280
|
+
import { readFile as readFile5 } from "node:fs/promises";
|
|
49375
51281
|
async function readPackageJson2(projectRoot) {
|
|
49376
|
-
const path72 =
|
|
51282
|
+
const path72 = join34(projectRoot, "package.json");
|
|
49377
51283
|
if (!existsSync36(path72)) return null;
|
|
49378
51284
|
try {
|
|
49379
|
-
return JSON.parse(await
|
|
51285
|
+
return JSON.parse(await readFile5(path72, "utf8"));
|
|
49380
51286
|
} catch {
|
|
49381
51287
|
return null;
|
|
49382
51288
|
}
|
|
@@ -49398,7 +51304,7 @@ async function genTechStack(ctx) {
|
|
|
49398
51304
|
].join("\n");
|
|
49399
51305
|
}
|
|
49400
51306
|
async function genDecisions(ctx) {
|
|
49401
|
-
const decisionsDir =
|
|
51307
|
+
const decisionsDir = join34(ctx.rootDir, "decisions");
|
|
49402
51308
|
if (!existsSync36(decisionsDir)) return "_No ADRs yet._";
|
|
49403
51309
|
const files = ctx.storage.listMarkdown(decisionsDir).sort();
|
|
49404
51310
|
const accepted = [];
|
|
@@ -49424,7 +51330,7 @@ async function genDecisions(ctx) {
|
|
|
49424
51330
|
}
|
|
49425
51331
|
async function genConventions(ctx) {
|
|
49426
51332
|
const lines = [];
|
|
49427
|
-
const claudeMd =
|
|
51333
|
+
const claudeMd = join34(ctx.projectRoot, "CLAUDE.MD");
|
|
49428
51334
|
if (existsSync36(claudeMd)) {
|
|
49429
51335
|
const content = readFileSync30(claudeMd, "utf8");
|
|
49430
51336
|
const match = content.match(/## Architecture rules[\s\S]+?(?=\n## |\n*$)/);
|
|
@@ -49458,7 +51364,7 @@ async function genBuild(ctx) {
|
|
|
49458
51364
|
].join("\n");
|
|
49459
51365
|
}
|
|
49460
51366
|
async function genOpenQuestions(ctx) {
|
|
49461
|
-
const path72 =
|
|
51367
|
+
const path72 = join34(ctx.rootDir, "risks.md");
|
|
49462
51368
|
if (!existsSync36(path72)) return "_No open questions._";
|
|
49463
51369
|
const content = readFileSync30(path72, "utf8");
|
|
49464
51370
|
const lines = content.split("\n");
|
|
@@ -49534,7 +51440,7 @@ function titleCase(id3) {
|
|
|
49534
51440
|
return id3.split("-").map((w) => w[0].toUpperCase() + w.slice(1)).join(" ");
|
|
49535
51441
|
}
|
|
49536
51442
|
async function updateAgentsMd(ctx, projectRoot) {
|
|
49537
|
-
const agentsPath =
|
|
51443
|
+
const agentsPath = join34(projectRoot, "AGENTS.MD");
|
|
49538
51444
|
if (existsSync36(agentsPath)) {
|
|
49539
51445
|
const content = readFileSync30(agentsPath, "utf8");
|
|
49540
51446
|
const hasAnyMarker = AUTO_SECTIONS.some((id3) => content.includes(MARKER_OPEN(id3)));
|
|
@@ -49584,7 +51490,7 @@ async function updateAgentsMd(ctx, projectRoot) {
|
|
|
49584
51490
|
return { changed: true, sections: changedSections };
|
|
49585
51491
|
}
|
|
49586
51492
|
function hash2(s) {
|
|
49587
|
-
return
|
|
51493
|
+
return createHash19("sha256").update(s).digest("hex").slice(0, 16);
|
|
49588
51494
|
}
|
|
49589
51495
|
var AUTO_SECTIONS, MARKER_OPEN, MARKER_CLOSE, GENERATORS;
|
|
49590
51496
|
var init_agentsMd = __esm({
|
|
@@ -49706,11 +51612,11 @@ var init_completeDesign = __esm({
|
|
|
49706
51612
|
|
|
49707
51613
|
// src/cli/workspace/planDriftCheck.ts
|
|
49708
51614
|
import { existsSync as existsSync37, readFileSync as readFileSync31, readdirSync as readdirSync9, statSync as statSync6, writeFileSync as writeFileSync20 } from "node:fs";
|
|
49709
|
-
import { join as
|
|
51615
|
+
import { join as join35 } from "node:path";
|
|
49710
51616
|
function findCanonicalDoc(rootDir) {
|
|
49711
|
-
const docsDir =
|
|
51617
|
+
const docsDir = join35(rootDir, "docs");
|
|
49712
51618
|
if (!existsSync37(docsDir)) return null;
|
|
49713
|
-
const candidates = readdirSync9(docsDir).filter((f) => /^plan-canonical.*\.md$/i.test(f)).map((f) => ({ f, mtime: statSync6(
|
|
51619
|
+
const candidates = readdirSync9(docsDir).filter((f) => /^plan-canonical.*\.md$/i.test(f)).map((f) => ({ f, mtime: statSync6(join35(docsDir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
|
|
49714
51620
|
return candidates.length > 0 ? candidates[0].f : null;
|
|
49715
51621
|
}
|
|
49716
51622
|
function parseCanonicalDoc(text) {
|
|
@@ -49745,7 +51651,7 @@ async function runPlanDriftCheck(rootDir) {
|
|
|
49745
51651
|
if (process.env["ZELARI_DRIFT_CHECK"] === "0") {
|
|
49746
51652
|
return { ran: false, reason: "ZELARI_DRIFT_CHECK=0 (disabled)" };
|
|
49747
51653
|
}
|
|
49748
|
-
const planPath =
|
|
51654
|
+
const planPath = join35(rootDir, "plan.json");
|
|
49749
51655
|
if (!existsSync37(planPath)) {
|
|
49750
51656
|
return { ran: false, reason: ".zelari/plan.json missing (not design-phase)" };
|
|
49751
51657
|
}
|
|
@@ -49761,7 +51667,7 @@ async function runPlanDriftCheck(rootDir) {
|
|
|
49761
51667
|
const milestones = Array.isArray(plan.milestones) ? plan.milestones : [];
|
|
49762
51668
|
const phaseIds = new Set(phases.map((p3) => typeof p3.id === "string" ? p3.id : "").filter(Boolean));
|
|
49763
51669
|
const canonicalName = findCanonicalDoc(rootDir);
|
|
49764
|
-
const canonicalText = canonicalName ? readFileSyncSafe(
|
|
51670
|
+
const canonicalText = canonicalName ? readFileSyncSafe(join35(rootDir, "docs", canonicalName)) : null;
|
|
49765
51671
|
if (canonicalText !== null) {
|
|
49766
51672
|
const { activePhases, blockedPrefixes } = parseCanonicalDoc(canonicalText);
|
|
49767
51673
|
for (const id3 of activePhases) {
|
|
@@ -49840,7 +51746,7 @@ async function runPlanDriftCheck(rootDir) {
|
|
|
49840
51746
|
const canonicalParsed = canonicalName !== null && canonicalText !== null;
|
|
49841
51747
|
let reportPath;
|
|
49842
51748
|
try {
|
|
49843
|
-
reportPath =
|
|
51749
|
+
reportPath = join35(rootDir, "drift-report.json");
|
|
49844
51750
|
writeFileSync20(
|
|
49845
51751
|
reportPath,
|
|
49846
51752
|
JSON.stringify(
|
|
@@ -49878,7 +51784,7 @@ var init_planDriftCheck = __esm({
|
|
|
49878
51784
|
// src/cli/workspace/projectSmoke.ts
|
|
49879
51785
|
import { spawn as spawn14 } from "node:child_process";
|
|
49880
51786
|
import { existsSync as existsSync38, readFileSync as readFileSync32 } from "node:fs";
|
|
49881
|
-
import { join as
|
|
51787
|
+
import { join as join36 } from "node:path";
|
|
49882
51788
|
function pickSmokeScript(scripts) {
|
|
49883
51789
|
if (!scripts) return null;
|
|
49884
51790
|
for (const name of SMOKE_SCRIPT_PRIORITY) {
|
|
@@ -49890,7 +51796,7 @@ async function runProjectSmoke(projectRoot, timeoutMs2 = DEFAULT_TIMEOUT_MS3) {
|
|
|
49890
51796
|
if (process.env["ZELARI_SMOKE"] === "0") {
|
|
49891
51797
|
return { ran: false, reason: "ZELARI_SMOKE=0 (disabled)" };
|
|
49892
51798
|
}
|
|
49893
|
-
const pkgPath =
|
|
51799
|
+
const pkgPath = join36(projectRoot, "package.json");
|
|
49894
51800
|
if (!existsSync38(pkgPath)) {
|
|
49895
51801
|
return { ran: false, reason: "no package.json (skipped)" };
|
|
49896
51802
|
}
|
|
@@ -49985,7 +51891,7 @@ __export(postCouncilHook_exports, {
|
|
|
49985
51891
|
});
|
|
49986
51892
|
import { spawn as spawn15 } from "node:child_process";
|
|
49987
51893
|
import { existsSync as existsSync39, readFileSync as readFileSync33 } from "node:fs";
|
|
49988
|
-
import { join as
|
|
51894
|
+
import { join as join37 } from "node:path";
|
|
49989
51895
|
async function runCompleteDesignPostProcessor(ctx, options) {
|
|
49990
51896
|
if (options?.runMode === "implementation") {
|
|
49991
51897
|
return {
|
|
@@ -49996,8 +51902,8 @@ async function runCompleteDesignPostProcessor(ctx, options) {
|
|
|
49996
51902
|
if (process.env["ZELARI_COMPLETE_DESIGN"] === "0") {
|
|
49997
51903
|
return { ran: false, reason: "ZELARI_COMPLETE_DESIGN=0 (disabled)" };
|
|
49998
51904
|
}
|
|
49999
|
-
const planJsonPath2 =
|
|
50000
|
-
const scriptPath =
|
|
51905
|
+
const planJsonPath2 = join37(ctx.rootDir, "plan.json");
|
|
51906
|
+
const scriptPath = join37(ctx.projectRoot, "complete-design.mjs");
|
|
50001
51907
|
if (!existsSync39(planJsonPath2)) {
|
|
50002
51908
|
return {
|
|
50003
51909
|
ran: false,
|
|
@@ -50431,7 +52337,7 @@ import { promisify as promisify2 } from "node:util";
|
|
|
50431
52337
|
import { mkdtempSync, rmSync as rmSync2 } from "node:fs";
|
|
50432
52338
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
50433
52339
|
import path49 from "node:path";
|
|
50434
|
-
import { randomUUID as
|
|
52340
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
50435
52341
|
async function git3(cwd, args, env) {
|
|
50436
52342
|
const { stdout } = await execFileAsync2("git", ["-C", cwd, ...args], {
|
|
50437
52343
|
maxBuffer: 64 * 1024 * 1024,
|
|
@@ -50474,7 +52380,7 @@ async function createCheckpoint(cwd, label = "checkpoint") {
|
|
|
50474
52380
|
}
|
|
50475
52381
|
try {
|
|
50476
52382
|
const { tree, head } = await snapshotTree(cwd);
|
|
50477
|
-
const id3 =
|
|
52383
|
+
const id3 = randomUUID5().slice(0, 8);
|
|
50478
52384
|
const createdAt = Date.now();
|
|
50479
52385
|
const message = `zelari-checkpoint ${id3}: ${label}`;
|
|
50480
52386
|
const commitArgs = ["commit-tree", tree, "-m", message];
|
|
@@ -50641,7 +52547,7 @@ __export(fileBackend_exports, {
|
|
|
50641
52547
|
getMemoryBackend: () => getMemoryBackend,
|
|
50642
52548
|
isMemoryEnabled: () => isMemoryEnabled
|
|
50643
52549
|
});
|
|
50644
|
-
import { randomUUID as
|
|
52550
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
50645
52551
|
import { promises as fs26 } from "node:fs";
|
|
50646
52552
|
import * as path50 from "node:path";
|
|
50647
52553
|
function tokenize(text) {
|
|
@@ -50700,7 +52606,7 @@ var init_fileBackend = __esm({
|
|
|
50700
52606
|
}
|
|
50701
52607
|
async add(content, metadata2 = {}, graph) {
|
|
50702
52608
|
const fact = {
|
|
50703
|
-
id:
|
|
52609
|
+
id: randomUUID6(),
|
|
50704
52610
|
content,
|
|
50705
52611
|
metadata: metadata2,
|
|
50706
52612
|
...graph ? { graph } : {},
|
|
@@ -50808,7 +52714,7 @@ __export(zelariMission_exports, {
|
|
|
50808
52714
|
resolveMaxTokens: () => resolveMaxTokens,
|
|
50809
52715
|
runZelariMission: () => runZelariMission
|
|
50810
52716
|
});
|
|
50811
|
-
import { randomUUID as
|
|
52717
|
+
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
50812
52718
|
import { promises as fs28 } from "node:fs";
|
|
50813
52719
|
import * as path52 from "node:path";
|
|
50814
52720
|
function resolveMaxIterations(env = process.env) {
|
|
@@ -50905,7 +52811,7 @@ async function runZelariMission(userMessage, brief, deps) {
|
|
|
50905
52811
|
const maxStall = resolveMaxStall(deps.env);
|
|
50906
52812
|
const maxCost = resolveMaxCost(deps.env);
|
|
50907
52813
|
const maxTokens = resolveMaxTokens(deps.env);
|
|
50908
|
-
const missionId = deps.missionId ?? `m_${
|
|
52814
|
+
const missionId = deps.missionId ?? `m_${randomUUID7().slice(0, 8)}`;
|
|
50909
52815
|
const startedAt = now().toISOString();
|
|
50910
52816
|
const state3 = {
|
|
50911
52817
|
missionId,
|
|
@@ -52174,11 +54080,11 @@ ${prompt.trim()}`];
|
|
|
52174
54080
|
parts.push("", "Return ONLY the JSON object described in the system prompt.");
|
|
52175
54081
|
return parts.join("\n");
|
|
52176
54082
|
}
|
|
52177
|
-
function uniqueId(
|
|
52178
|
-
if (!existing.has(
|
|
54083
|
+
function uniqueId(base2, existing) {
|
|
54084
|
+
if (!existing.has(base2)) return base2;
|
|
52179
54085
|
let i = 2;
|
|
52180
|
-
while (existing.has(`${
|
|
52181
|
-
return `${
|
|
54086
|
+
while (existing.has(`${base2}-${i}`)) i += 1;
|
|
54087
|
+
return `${base2}-${i}`;
|
|
52182
54088
|
}
|
|
52183
54089
|
function buildAutoVerifyPrompt(general) {
|
|
52184
54090
|
const taskPrompt = general.prompt.length > MAX_VERIFY_TASK_PROMPT_CHARS ? `${general.prompt.slice(0, MAX_VERIFY_TASK_PROMPT_CHARS)}
|
|
@@ -52987,7 +54893,7 @@ ${body}`);
|
|
|
52987
54893
|
function thoroughnessForKind(kind2) {
|
|
52988
54894
|
return kind2 === "general" || kind2 === "fix" ? "deep" : "medium";
|
|
52989
54895
|
}
|
|
52990
|
-
function
|
|
54896
|
+
function firstLine2(text, maxChars = 160) {
|
|
52991
54897
|
const line = text.trim().split("\n").find((l) => l.trim() !== "")?.trim() ?? "";
|
|
52992
54898
|
return line.length > maxChars ? `${line.slice(0, maxChars)}\u2026` : line;
|
|
52993
54899
|
}
|
|
@@ -53743,7 +55649,7 @@ ${upstream}` : node.prompt,
|
|
|
53743
55649
|
});
|
|
53744
55650
|
writer.result = `${writer.result ?? ""}
|
|
53745
55651
|
|
|
53746
|
-
[accepted with unresolved verify findings from ` + `"${verify.label}"]${findings ? `: ${
|
|
55652
|
+
[accepted with unresolved verify findings from ` + `"${verify.label}"]${findings ? `: ${firstLine2(findings)}` : ""}`.trim();
|
|
53747
55653
|
this.radio("node_end", {
|
|
53748
55654
|
description: writer.label,
|
|
53749
55655
|
agent: writer.kind,
|
|
@@ -56702,7 +58608,7 @@ import {
|
|
|
56702
58608
|
rmSync as rmSync4,
|
|
56703
58609
|
writeFileSync as writeFileSync24
|
|
56704
58610
|
} from "node:fs";
|
|
56705
|
-
import { dirname as dirname13, join as
|
|
58611
|
+
import { dirname as dirname13, join as join45 } from "node:path";
|
|
56706
58612
|
import { homedir as homedir12 } from "node:os";
|
|
56707
58613
|
function ensureBuiltinSkillsLoadedSync() {
|
|
56708
58614
|
if (builtinsLoaded) return;
|
|
@@ -56714,13 +58620,13 @@ function ensureBuiltinSkillsLoadedSync() {
|
|
|
56714
58620
|
}
|
|
56715
58621
|
}
|
|
56716
58622
|
function getUserSkillsDir() {
|
|
56717
|
-
return
|
|
58623
|
+
return join45(homedir12(), ".zelari-code", "skills");
|
|
56718
58624
|
}
|
|
56719
58625
|
function getProjectSkillsDir(projectRoot) {
|
|
56720
|
-
return
|
|
58626
|
+
return join45(projectRoot, ".zelari", "skills");
|
|
56721
58627
|
}
|
|
56722
58628
|
function skillFilePath(dir, name) {
|
|
56723
|
-
return
|
|
58629
|
+
return join45(dir, name, "SKILL.md");
|
|
56724
58630
|
}
|
|
56725
58631
|
function classifyScope(skillPath, projectRoot) {
|
|
56726
58632
|
const userDir = getUserSkillsDir().replace(/\\/g, "/");
|
|
@@ -56796,9 +58702,9 @@ function listSkillsSnapshot(projectRoot) {
|
|
|
56796
58702
|
const skills = [];
|
|
56797
58703
|
const seen = /* @__PURE__ */ new Set();
|
|
56798
58704
|
if (root) {
|
|
56799
|
-
scanSkillsDir(
|
|
56800
|
-
scanSkillsDir(
|
|
56801
|
-
scanSkillsDir(
|
|
58705
|
+
scanSkillsDir(join45(root, ".zelari", "skills"), root, seen, skills);
|
|
58706
|
+
scanSkillsDir(join45(root, ".claude", "skills"), root, seen, skills);
|
|
58707
|
+
scanSkillsDir(join45(root, ".opencode", "skills"), root, seen, skills);
|
|
56802
58708
|
}
|
|
56803
58709
|
scanSkillsDir(userSkillsDir, root, seen, skills);
|
|
56804
58710
|
for (const s of listCodingSkills()) {
|
|
@@ -56896,7 +58802,7 @@ function removeSkill(opts) {
|
|
|
56896
58802
|
}
|
|
56897
58803
|
dir = getProjectSkillsDir(root);
|
|
56898
58804
|
}
|
|
56899
|
-
const skillDir =
|
|
58805
|
+
const skillDir = join45(dir, name);
|
|
56900
58806
|
const path72 = skillFilePath(dir, name);
|
|
56901
58807
|
if (!existsSync49(path72) && !existsSync49(skillDir)) {
|
|
56902
58808
|
return { ok: false, error: `Skill "${name}" not found in ${dir}` };
|
|
@@ -57437,7 +59343,7 @@ var init_mcpCli = __esm({
|
|
|
57437
59343
|
|
|
57438
59344
|
// src/cli/mcp/mcpPermissionServer.ts
|
|
57439
59345
|
import { createInterface as createInterface2 } from "node:readline";
|
|
57440
|
-
import { randomUUID as
|
|
59346
|
+
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
57441
59347
|
function startPermissionMcpServer(opts) {
|
|
57442
59348
|
const socketPath = opts.socketPath.trim();
|
|
57443
59349
|
const requestTimeoutMs = opts.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
|
|
@@ -57533,7 +59439,7 @@ function startPermissionMcpServer(opts) {
|
|
|
57533
59439
|
socketPath,
|
|
57534
59440
|
{
|
|
57535
59441
|
t: "ask",
|
|
57536
|
-
id:
|
|
59442
|
+
id: randomUUID9(),
|
|
57537
59443
|
kind: "permission",
|
|
57538
59444
|
tool: toolName,
|
|
57539
59445
|
input: input2,
|
|
@@ -57572,7 +59478,7 @@ function startPermissionMcpServer(opts) {
|
|
|
57572
59478
|
socketPath,
|
|
57573
59479
|
{
|
|
57574
59480
|
t: "ask",
|
|
57575
|
-
id:
|
|
59481
|
+
id: randomUUID9(),
|
|
57576
59482
|
kind: "question",
|
|
57577
59483
|
question,
|
|
57578
59484
|
choices,
|
|
@@ -57708,17 +59614,17 @@ import {
|
|
|
57708
59614
|
readFileSync as readFileSync39,
|
|
57709
59615
|
writeFileSync as writeFileSync25
|
|
57710
59616
|
} from "node:fs";
|
|
57711
|
-
import { join as
|
|
59617
|
+
import { join as join46 } from "node:path";
|
|
57712
59618
|
import { homedir as homedir13 } from "node:os";
|
|
57713
|
-
import { createHash as
|
|
59619
|
+
import { createHash as createHash20, randomBytes as randomBytes6, timingSafeEqual } from "node:crypto";
|
|
57714
59620
|
function getZelariHome() {
|
|
57715
|
-
return
|
|
59621
|
+
return join46(homedir13(), ".zelari-code");
|
|
57716
59622
|
}
|
|
57717
59623
|
function getCompanionConfigPath() {
|
|
57718
|
-
return
|
|
59624
|
+
return join46(getZelariHome(), "companion.json");
|
|
57719
59625
|
}
|
|
57720
59626
|
function getCompanionTokenPath() {
|
|
57721
|
-
return
|
|
59627
|
+
return join46(getZelariHome(), "companion.token");
|
|
57722
59628
|
}
|
|
57723
59629
|
function ensureHome() {
|
|
57724
59630
|
const home = getZelariHome();
|
|
@@ -57775,7 +59681,7 @@ function loadOrCreateToken(explicit) {
|
|
|
57775
59681
|
const t = readFileSync39(path72, "utf8").trim();
|
|
57776
59682
|
if (t) return { token: t, created: false };
|
|
57777
59683
|
}
|
|
57778
|
-
const token =
|
|
59684
|
+
const token = randomBytes6(24).toString("base64url");
|
|
57779
59685
|
writeFileSync25(path72, token + "\n", "utf8");
|
|
57780
59686
|
try {
|
|
57781
59687
|
const fs42 = __require("node:fs");
|
|
@@ -57786,8 +59692,8 @@ function loadOrCreateToken(explicit) {
|
|
|
57786
59692
|
}
|
|
57787
59693
|
function tokenMatches(expected, provided) {
|
|
57788
59694
|
if (!provided) return false;
|
|
57789
|
-
const a =
|
|
57790
|
-
const b =
|
|
59695
|
+
const a = createHash20("sha256").update(expected).digest();
|
|
59696
|
+
const b = createHash20("sha256").update(provided).digest();
|
|
57791
59697
|
try {
|
|
57792
59698
|
return timingSafeEqual(a, b);
|
|
57793
59699
|
} catch {
|
|
@@ -57795,8 +59701,8 @@ function tokenMatches(expected, provided) {
|
|
|
57795
59701
|
}
|
|
57796
59702
|
}
|
|
57797
59703
|
function slugFromPath(p3) {
|
|
57798
|
-
const
|
|
57799
|
-
return
|
|
59704
|
+
const base2 = p3.replace(/[/\\]+$/, "").split(/[/\\]/).pop() || "project";
|
|
59705
|
+
return base2.toLowerCase().replace(/[^a-z0-9-_]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48) || "project";
|
|
57800
59706
|
}
|
|
57801
59707
|
function mergeProjects(cfg, extraPaths) {
|
|
57802
59708
|
const byId = /* @__PURE__ */ new Map();
|
|
@@ -57864,9 +59770,9 @@ var init_config = __esm({
|
|
|
57864
59770
|
// src/cli/companion/runManager.ts
|
|
57865
59771
|
import { spawn as spawn17 } from "node:child_process";
|
|
57866
59772
|
import { createInterface as createInterface3 } from "node:readline";
|
|
57867
|
-
import { randomUUID as
|
|
59773
|
+
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
57868
59774
|
import { writeFileSync as writeFileSync26, unlinkSync as unlinkSync3 } from "node:fs";
|
|
57869
|
-
import { join as
|
|
59775
|
+
import { join as join47 } from "node:path";
|
|
57870
59776
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
57871
59777
|
var RunManager;
|
|
57872
59778
|
var init_runManager = __esm({
|
|
@@ -57933,7 +59839,7 @@ var init_runManager = __esm({
|
|
|
57933
59839
|
}
|
|
57934
59840
|
const prompt = args.prompt?.trim();
|
|
57935
59841
|
if (!prompt) return { ok: false, error: "prompt is required" };
|
|
57936
|
-
const id3 =
|
|
59842
|
+
const id3 = randomUUID10();
|
|
57937
59843
|
const mode = (args.mode || "kraken").toLowerCase();
|
|
57938
59844
|
const phase2 = (args.phase || "build").toLowerCase();
|
|
57939
59845
|
const run = {
|
|
@@ -57970,7 +59876,7 @@ var init_runManager = __esm({
|
|
|
57970
59876
|
}
|
|
57971
59877
|
let historyFile;
|
|
57972
59878
|
if (args.history && Array.isArray(args.history) && args.history.length > 0) {
|
|
57973
|
-
historyFile =
|
|
59879
|
+
historyFile = join47(tmpdir3(), `zelari-companion-hist-${id3}.json`);
|
|
57974
59880
|
try {
|
|
57975
59881
|
writeFileSync26(historyFile, JSON.stringify(args.history), "utf8");
|
|
57976
59882
|
argv.push("--history-file", historyFile);
|
|
@@ -62401,12 +64307,12 @@ init_completionGate();
|
|
|
62401
64307
|
// src/cli/kraken/verificationBridge.ts
|
|
62402
64308
|
init_candidateRegistry();
|
|
62403
64309
|
init_completionGate();
|
|
62404
|
-
import { createHash as
|
|
64310
|
+
import { createHash as createHash14 } from "node:crypto";
|
|
62405
64311
|
|
|
62406
64312
|
// src/cli/kraken/nativeVerification.ts
|
|
62407
64313
|
init_runtime2();
|
|
62408
64314
|
init_verification2();
|
|
62409
|
-
import { readFile as
|
|
64315
|
+
import { readFile as readFile3 } from "node:fs/promises";
|
|
62410
64316
|
import path42 from "node:path";
|
|
62411
64317
|
function nativePackEnabled(env = process.env) {
|
|
62412
64318
|
const v = env.ZELARI_VERIFY_PACK?.toLowerCase();
|
|
@@ -62434,7 +64340,7 @@ function packTimeoutMs(env = process.env) {
|
|
|
62434
64340
|
}
|
|
62435
64341
|
async function readPackageScripts(cwd = process.cwd()) {
|
|
62436
64342
|
try {
|
|
62437
|
-
const raw = await
|
|
64343
|
+
const raw = await readFile3(path42.join(cwd, "package.json"), "utf-8");
|
|
62438
64344
|
const parsed = JSON.parse(raw);
|
|
62439
64345
|
if (parsed && typeof parsed === "object" && typeof parsed.scripts === "object") {
|
|
62440
64346
|
return parsed.scripts;
|
|
@@ -62528,7 +64434,7 @@ function krakenResultsToContract(requiredChecks, results, now = Date.now()) {
|
|
|
62528
64434
|
return { criteria, results: verifications };
|
|
62529
64435
|
}
|
|
62530
64436
|
function sha256Hex2(input) {
|
|
62531
|
-
return
|
|
64437
|
+
return createHash14("sha256").update(input).digest("hex");
|
|
62532
64438
|
}
|
|
62533
64439
|
function matchNoteToToolTrace(note, trace) {
|
|
62534
64440
|
const n = normalize5(note);
|
|
@@ -62867,17 +64773,17 @@ function mergeCompactRange(into, r) {
|
|
|
62867
64773
|
if (r.strategy === "llm") into.strategy = "llm";
|
|
62868
64774
|
else if (r.strategy && !into.strategy) into.strategy = r.strategy;
|
|
62869
64775
|
}
|
|
62870
|
-
function
|
|
64776
|
+
function estimateTokens2(text) {
|
|
62871
64777
|
if (!text) return 0;
|
|
62872
64778
|
return Math.max(1, Math.ceil(text.length / 4));
|
|
62873
64779
|
}
|
|
62874
64780
|
function estimateHistoryTokens(messages) {
|
|
62875
64781
|
let n = 0;
|
|
62876
64782
|
for (const m of messages) {
|
|
62877
|
-
n +=
|
|
64783
|
+
n += estimateTokens2(m.content);
|
|
62878
64784
|
if (m.toolCalls) {
|
|
62879
64785
|
for (const tc of m.toolCalls) {
|
|
62880
|
-
n +=
|
|
64786
|
+
n += estimateTokens2(tc.name) + estimateTokens2(JSON.stringify(tc.args ?? {}));
|
|
62881
64787
|
}
|
|
62882
64788
|
}
|
|
62883
64789
|
}
|
|
@@ -66241,8 +68147,8 @@ async function promoteMemoryToAgentsMd(projectRoot, node) {
|
|
|
66241
68147
|
const root = await fs29.realpath(projectRoot).catch(() => path54.resolve(projectRoot));
|
|
66242
68148
|
const target = path54.join(root, "AGENTS.md");
|
|
66243
68149
|
try {
|
|
66244
|
-
const
|
|
66245
|
-
if (
|
|
68150
|
+
const stat2 = await fs29.lstat(target);
|
|
68151
|
+
if (stat2.isSymbolicLink() || !stat2.isFile()) throw new Error("AGENTS.md must be a regular project file.");
|
|
66246
68152
|
} catch (error51) {
|
|
66247
68153
|
if (error51.code !== "ENOENT") throw error51;
|
|
66248
68154
|
}
|
|
@@ -66321,8 +68227,8 @@ async function safeExportPath(cwd, requested) {
|
|
|
66321
68227
|
for (const segment of relativeParent.split(path55.sep).filter(Boolean)) {
|
|
66322
68228
|
cursor = path55.join(cursor, segment);
|
|
66323
68229
|
try {
|
|
66324
|
-
const
|
|
66325
|
-
if (
|
|
68230
|
+
const stat2 = await fs30.lstat(cursor);
|
|
68231
|
+
if (stat2.isSymbolicLink()) {
|
|
66326
68232
|
throw new Error("Export path must not traverse a symbolic link.");
|
|
66327
68233
|
}
|
|
66328
68234
|
} catch (error51) {
|
|
@@ -66690,7 +68596,7 @@ init_zod();
|
|
|
66690
68596
|
init_taskTool();
|
|
66691
68597
|
import { promises as fs33 } from "node:fs";
|
|
66692
68598
|
import path59 from "node:path";
|
|
66693
|
-
import { randomBytes as
|
|
68599
|
+
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
66694
68600
|
var CsvFanoutArgsSchema = external_exports.object({
|
|
66695
68601
|
csv_path: external_exports.string().min(1),
|
|
66696
68602
|
id_column: external_exports.string().min(1),
|
|
@@ -66861,7 +68767,7 @@ async function runCsvFanout(args, deps, opts) {
|
|
|
66861
68767
|
};
|
|
66862
68768
|
}
|
|
66863
68769
|
async function atomicWrite(file2, contents) {
|
|
66864
|
-
const tmp = `${file2}.${process.pid}.${Date.now()}.${
|
|
68770
|
+
const tmp = `${file2}.${process.pid}.${Date.now()}.${randomBytes5(6).toString("hex")}.tmp`;
|
|
66865
68771
|
await fs33.writeFile(tmp, contents, "utf8");
|
|
66866
68772
|
await fs33.rename(tmp, file2);
|
|
66867
68773
|
}
|
|
@@ -67160,9 +69066,9 @@ async function handleKrakenWorkbench(ctx) {
|
|
|
67160
69066
|
for (const f of files) {
|
|
67161
69067
|
if (!f.startsWith("workbench-") || !f.endsWith(".md")) continue;
|
|
67162
69068
|
const full = path60.join(dir, f);
|
|
67163
|
-
const
|
|
67164
|
-
if (
|
|
67165
|
-
latestMtime =
|
|
69069
|
+
const stat2 = await fs35.stat(full);
|
|
69070
|
+
if (stat2.mtimeMs > latestMtime) {
|
|
69071
|
+
latestMtime = stat2.mtimeMs;
|
|
67166
69072
|
latest = full;
|
|
67167
69073
|
}
|
|
67168
69074
|
}
|
|
@@ -69525,7 +71431,7 @@ init_taskTool();
|
|
|
69525
71431
|
init_sessionTodos();
|
|
69526
71432
|
import { promises as fs41 } from "node:fs";
|
|
69527
71433
|
import path68 from "node:path";
|
|
69528
|
-
import { randomUUID as
|
|
71434
|
+
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
69529
71435
|
|
|
69530
71436
|
// src/cli/kraken/verifierLifecycle.ts
|
|
69531
71437
|
init_verification2();
|
|
@@ -69615,6 +71521,215 @@ async function runAdvisoryVerifierReview(evaluation, deps = {}) {
|
|
|
69615
71521
|
// src/cli/runHeadless.ts
|
|
69616
71522
|
init_metrics3();
|
|
69617
71523
|
init_headlessSpine();
|
|
71524
|
+
init_runtime2();
|
|
71525
|
+
|
|
71526
|
+
// src/cli/headless/controlReader.ts
|
|
71527
|
+
var CONTROL_TYPES = /* @__PURE__ */ new Set([
|
|
71528
|
+
"steer",
|
|
71529
|
+
"follow_up",
|
|
71530
|
+
"cancel",
|
|
71531
|
+
"pause",
|
|
71532
|
+
"resume"
|
|
71533
|
+
]);
|
|
71534
|
+
function parseControlEvent(raw) {
|
|
71535
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
71536
|
+
return { ok: false, id: "", reason: "control event must be a JSON object" };
|
|
71537
|
+
}
|
|
71538
|
+
const candidate = raw;
|
|
71539
|
+
const type = candidate["type"];
|
|
71540
|
+
if (typeof type !== "string" || !CONTROL_TYPES.has(type)) {
|
|
71541
|
+
return {
|
|
71542
|
+
ok: false,
|
|
71543
|
+
id: typeof candidate["id"] === "string" ? candidate["id"] : "",
|
|
71544
|
+
reason: `unknown control type: ${String(type)}`
|
|
71545
|
+
};
|
|
71546
|
+
}
|
|
71547
|
+
if (typeof candidate["id"] !== "string" || candidate["id"].length === 0) {
|
|
71548
|
+
return { ok: false, id: "", reason: "missing control id" };
|
|
71549
|
+
}
|
|
71550
|
+
if (type === "steer" || type === "follow_up") {
|
|
71551
|
+
if (typeof candidate["text"] !== "string" || candidate["text"].trim().length === 0) {
|
|
71552
|
+
return {
|
|
71553
|
+
ok: false,
|
|
71554
|
+
id: candidate["id"],
|
|
71555
|
+
reason: `${type} requires a non-empty "text" field`
|
|
71556
|
+
};
|
|
71557
|
+
}
|
|
71558
|
+
}
|
|
71559
|
+
if (type === "cancel" && "reason" in candidate && candidate["reason"] !== void 0 && typeof candidate["reason"] !== "string") {
|
|
71560
|
+
return {
|
|
71561
|
+
ok: false,
|
|
71562
|
+
id: candidate["id"],
|
|
71563
|
+
reason: "cancel reason must be a string"
|
|
71564
|
+
};
|
|
71565
|
+
}
|
|
71566
|
+
return {
|
|
71567
|
+
ok: true,
|
|
71568
|
+
event: {
|
|
71569
|
+
...candidate,
|
|
71570
|
+
ts: typeof candidate["ts"] === "number" ? candidate["ts"] : Date.now()
|
|
71571
|
+
}
|
|
71572
|
+
};
|
|
71573
|
+
}
|
|
71574
|
+
function parseControlLine(line) {
|
|
71575
|
+
const trimmed = line.trim();
|
|
71576
|
+
if (trimmed.length === 0) return null;
|
|
71577
|
+
try {
|
|
71578
|
+
return parseControlEvent(JSON.parse(trimmed));
|
|
71579
|
+
} catch (e) {
|
|
71580
|
+
return { ok: false, id: "", reason: `malformed JSON: ${e.message}` };
|
|
71581
|
+
}
|
|
71582
|
+
}
|
|
71583
|
+
function startControlReader(input, onLine) {
|
|
71584
|
+
let buffer = "";
|
|
71585
|
+
const onData = (chunk) => {
|
|
71586
|
+
buffer += typeof chunk === "string" ? chunk : chunk.toString("utf8");
|
|
71587
|
+
let newlineIndex = buffer.indexOf("\n");
|
|
71588
|
+
while (newlineIndex !== -1) {
|
|
71589
|
+
const line = buffer.slice(0, newlineIndex);
|
|
71590
|
+
buffer = buffer.slice(newlineIndex + 1);
|
|
71591
|
+
if (line.trim().length > 0) onLine(line.replace(/\r$/, ""));
|
|
71592
|
+
newlineIndex = buffer.indexOf("\n");
|
|
71593
|
+
}
|
|
71594
|
+
};
|
|
71595
|
+
input.on("data", onData);
|
|
71596
|
+
return () => {
|
|
71597
|
+
input.removeListener("data", onData);
|
|
71598
|
+
buffer = "";
|
|
71599
|
+
};
|
|
71600
|
+
}
|
|
71601
|
+
|
|
71602
|
+
// src/cli/headless/protocol.ts
|
|
71603
|
+
var HEADLESS_PROTOCOL_VERSION = 2;
|
|
71604
|
+
var HEADLESS_PROTOCOL_CAPABILITIES = [
|
|
71605
|
+
"stdin-control",
|
|
71606
|
+
"steer",
|
|
71607
|
+
"follow_up",
|
|
71608
|
+
"cancel"
|
|
71609
|
+
];
|
|
71610
|
+
function protocolInfoEvent() {
|
|
71611
|
+
return {
|
|
71612
|
+
type: "protocol_info",
|
|
71613
|
+
version: HEADLESS_PROTOCOL_VERSION,
|
|
71614
|
+
capabilities: HEADLESS_PROTOCOL_CAPABILITIES,
|
|
71615
|
+
ts: Date.now()
|
|
71616
|
+
};
|
|
71617
|
+
}
|
|
71618
|
+
function controlAcceptedEvent(controlId, controlType) {
|
|
71619
|
+
return {
|
|
71620
|
+
type: "control_accepted",
|
|
71621
|
+
controlId,
|
|
71622
|
+
controlType,
|
|
71623
|
+
ts: Date.now()
|
|
71624
|
+
};
|
|
71625
|
+
}
|
|
71626
|
+
function controlAppliedEvent(controlId, controlType, boundary) {
|
|
71627
|
+
return {
|
|
71628
|
+
type: "control_applied",
|
|
71629
|
+
controlId,
|
|
71630
|
+
controlType,
|
|
71631
|
+
boundary,
|
|
71632
|
+
ts: Date.now()
|
|
71633
|
+
};
|
|
71634
|
+
}
|
|
71635
|
+
function controlRejectedEvent(controlId, reason) {
|
|
71636
|
+
return {
|
|
71637
|
+
type: "control_rejected",
|
|
71638
|
+
controlId,
|
|
71639
|
+
reason,
|
|
71640
|
+
ts: Date.now()
|
|
71641
|
+
};
|
|
71642
|
+
}
|
|
71643
|
+
|
|
71644
|
+
// src/cli/headless/controlBridge.ts
|
|
71645
|
+
var APPLIED_BOUNDARY = {
|
|
71646
|
+
steer: "turn-end",
|
|
71647
|
+
follow_up: "run-end",
|
|
71648
|
+
cancel: "cancel"
|
|
71649
|
+
};
|
|
71650
|
+
function attachControlPlane(opts) {
|
|
71651
|
+
const { input, queue, emit, onCancel } = opts;
|
|
71652
|
+
let finalized = false;
|
|
71653
|
+
queue.onDrained = (events) => {
|
|
71654
|
+
for (const event of events) {
|
|
71655
|
+
emit(
|
|
71656
|
+
controlAppliedEvent(
|
|
71657
|
+
event.id,
|
|
71658
|
+
event.type,
|
|
71659
|
+
APPLIED_BOUNDARY[event.type] ?? "unknown"
|
|
71660
|
+
)
|
|
71661
|
+
);
|
|
71662
|
+
}
|
|
71663
|
+
const cancels = events.filter((e) => e.type === "cancel");
|
|
71664
|
+
if (cancels.length > 0 && onCancel) {
|
|
71665
|
+
const last = cancels[cancels.length - 1];
|
|
71666
|
+
onCancel(last.type === "cancel" ? last.reason : void 0);
|
|
71667
|
+
}
|
|
71668
|
+
};
|
|
71669
|
+
const disposeReader = startControlReader(input, (line) => {
|
|
71670
|
+
const outcome = parseControlLine(line);
|
|
71671
|
+
if (outcome === null) return;
|
|
71672
|
+
if (!outcome.ok) {
|
|
71673
|
+
emit(controlRejectedEvent(outcome.id, outcome.reason));
|
|
71674
|
+
return;
|
|
71675
|
+
}
|
|
71676
|
+
const event = outcome.event;
|
|
71677
|
+
if (event.type === "pause" || event.type === "resume") {
|
|
71678
|
+
emit(
|
|
71679
|
+
controlRejectedEvent(event.id, `${event.type} is not supported yet`)
|
|
71680
|
+
);
|
|
71681
|
+
return;
|
|
71682
|
+
}
|
|
71683
|
+
if (finalized) {
|
|
71684
|
+
if (event.type === "steer") {
|
|
71685
|
+
const converted = toFollowUp(event);
|
|
71686
|
+
queue.enqueue(converted);
|
|
71687
|
+
emit(controlAppliedEvent(event.id, "steer", "converted-to-follow-up"));
|
|
71688
|
+
emit(controlAcceptedEvent(converted.id, "follow_up"));
|
|
71689
|
+
} else if (event.type === "follow_up") {
|
|
71690
|
+
queue.enqueue(event);
|
|
71691
|
+
emit(controlAcceptedEvent(event.id, "follow_up"));
|
|
71692
|
+
} else {
|
|
71693
|
+
emit(controlRejectedEvent(event.id, "run already finished"));
|
|
71694
|
+
}
|
|
71695
|
+
return;
|
|
71696
|
+
}
|
|
71697
|
+
queue.enqueue(event);
|
|
71698
|
+
emit(controlAcceptedEvent(event.id, event.type));
|
|
71699
|
+
});
|
|
71700
|
+
return {
|
|
71701
|
+
dispose() {
|
|
71702
|
+
disposeReader();
|
|
71703
|
+
queue.onDrained = void 0;
|
|
71704
|
+
},
|
|
71705
|
+
finalize() {
|
|
71706
|
+
finalized = true;
|
|
71707
|
+
const lateSteers = queue.drainSteers();
|
|
71708
|
+
for (const steer of lateSteers) {
|
|
71709
|
+
queue.enqueue(toFollowUp(steer));
|
|
71710
|
+
emit(controlAppliedEvent(steer.id, "steer", "converted-to-follow-up"));
|
|
71711
|
+
}
|
|
71712
|
+
const followUps = queue.drainFollowUps();
|
|
71713
|
+
for (const followUp of followUps) {
|
|
71714
|
+
emit(controlAppliedEvent(followUp.id, "follow_up", "run-end"));
|
|
71715
|
+
}
|
|
71716
|
+
return followUps.map((f) => f.text);
|
|
71717
|
+
},
|
|
71718
|
+
get finalized() {
|
|
71719
|
+
return finalized;
|
|
71720
|
+
}
|
|
71721
|
+
};
|
|
71722
|
+
}
|
|
71723
|
+
function toFollowUp(steer) {
|
|
71724
|
+
return {
|
|
71725
|
+
type: "follow_up",
|
|
71726
|
+
id: `fu-${steer.id}`,
|
|
71727
|
+
text: steer.text,
|
|
71728
|
+
ts: steer.ts
|
|
71729
|
+
};
|
|
71730
|
+
}
|
|
71731
|
+
|
|
71732
|
+
// src/cli/runHeadless.ts
|
|
69618
71733
|
async function runHeadless(opts) {
|
|
69619
71734
|
resetTaskSpawnCount();
|
|
69620
71735
|
if (opts.todos && opts.todos.length > 0) {
|
|
@@ -69822,7 +71937,7 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
69822
71937
|
});
|
|
69823
71938
|
log(formatKrakenGraphAscii2(graph));
|
|
69824
71939
|
if (opts.planOnly) {
|
|
69825
|
-
const planId =
|
|
71940
|
+
const planId = randomUUID8();
|
|
69826
71941
|
const planDir = path68.join(cwd, ".zelari", "radio");
|
|
69827
71942
|
const planPath = path68.join(planDir, `plan-${planId}.json`);
|
|
69828
71943
|
await fs41.mkdir(planDir, { recursive: true });
|
|
@@ -69949,7 +72064,19 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
69949
72064
|
const memoryFactory = await Promise.resolve().then(() => (init_serviceFactory(), serviceFactory_exports));
|
|
69950
72065
|
const nativeMemory = memoryFactory.isMemoryV2Enabled() ? await memoryFactory.getMemoryService(process.cwd(), process.env) : void 0;
|
|
69951
72066
|
const memoryAutoWrite = memoryFactory.isMemoryAutoWriteEnabled();
|
|
72067
|
+
const controlQueue = new RuntimeControlQueue();
|
|
72068
|
+
const harnessHolder = {};
|
|
72069
|
+
const controlPlane = opts.output === "json" && process.stdin.isTTY !== true ? (() => {
|
|
72070
|
+
emitEvent(protocolInfoEvent());
|
|
72071
|
+
return attachControlPlane({
|
|
72072
|
+
input: process.stdin,
|
|
72073
|
+
queue: controlQueue,
|
|
72074
|
+
emit: emitEvent,
|
|
72075
|
+
onCancel: () => harnessHolder.cancel?.()
|
|
72076
|
+
});
|
|
72077
|
+
})() : void 0;
|
|
69952
72078
|
const { registry: toolRegistry } = createBuiltinToolRegistry({
|
|
72079
|
+
onTentacleEvent: (ev) => emitEvent(ev),
|
|
69953
72080
|
planMode: planModeFromOpts(opts),
|
|
69954
72081
|
gauntletParent: Boolean(opts.gauntlet) && !planModeFromOpts(opts),
|
|
69955
72082
|
// Fase 1 (ADR-0020): anchor tentacles to the provider/model THIS run
|
|
@@ -70168,12 +72295,15 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
70168
72295
|
// command is a test/typecheck/build/git-diff line.
|
|
70169
72296
|
toolCallGate: (name, args) => spine.gateResourceToolCall(name, args) ?? { allowed: true },
|
|
70170
72297
|
maxToolLoopIterations: maxToolLoop,
|
|
72298
|
+
// PHASE 2: control queue — SteeringObserver drains it at turn ends.
|
|
72299
|
+
controlQueue,
|
|
70171
72300
|
...nativeMemory ? {
|
|
70172
72301
|
memoryService: nativeMemory,
|
|
70173
72302
|
memoryQuery: opts.task,
|
|
70174
72303
|
memoryContextChars: 2e3
|
|
70175
72304
|
} : {}
|
|
70176
72305
|
});
|
|
72306
|
+
harnessHolder.cancel = () => harness.cancel();
|
|
70177
72307
|
const readBuildProgress = () => {
|
|
70178
72308
|
const getter = harness.getBuildProgress;
|
|
70179
72309
|
return typeof getter === "function" ? getter.call(harness) : { mutationsAttempted: 0, mutationsSucceeded: 0 };
|
|
@@ -70390,6 +72520,11 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
70390
72520
|
}
|
|
70391
72521
|
}
|
|
70392
72522
|
await nativeMemory?.close().catch(() => void 0);
|
|
72523
|
+
const pendingFollowUps = controlPlane?.finalize() ?? [];
|
|
72524
|
+
for (const followUp of pendingFollowUps) {
|
|
72525
|
+
emitEvent({ type: "log", message: `follow_up_queued: ${followUp.slice(0, 500)}` });
|
|
72526
|
+
}
|
|
72527
|
+
controlPlane?.dispose();
|
|
70393
72528
|
if (pass.finalReason === "error") return 3;
|
|
70394
72529
|
if (strictExit !== 0) return strictExit;
|
|
70395
72530
|
return pass.exitCode;
|