zelari-code 2.34.1 → 2.35.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/browser/tools.js +23 -1
- package/dist/cli/browser/tools.js.map +1 -1
- package/dist/cli/main.bundled.js +536 -420
- package/dist/cli/main.bundled.js.map +4 -4
- package/dist/cli/provider/openai-compatible.js +53 -24
- package/dist/cli/provider/openai-compatible.js.map +1 -1
- package/dist/cli/toolRegistry.js +12 -0
- package/dist/cli/toolRegistry.js.map +1 -1
- package/dist/cli/tools/screenshotTool.js +111 -0
- package/dist/cli/tools/screenshotTool.js.map +1 -0
- package/package.json +2 -2
package/dist/cli/main.bundled.js
CHANGED
|
@@ -3414,10 +3414,10 @@ function mergeDefs(...defs) {
|
|
|
3414
3414
|
function cloneDef(schema) {
|
|
3415
3415
|
return mergeDefs(schema._zod.def);
|
|
3416
3416
|
}
|
|
3417
|
-
function getElementAtPath(obj,
|
|
3418
|
-
if (!
|
|
3417
|
+
function getElementAtPath(obj, path100) {
|
|
3418
|
+
if (!path100)
|
|
3419
3419
|
return obj;
|
|
3420
|
-
return
|
|
3420
|
+
return path100.reduce((acc, key) => acc?.[key], obj);
|
|
3421
3421
|
}
|
|
3422
3422
|
function promiseAllObject(promisesObj) {
|
|
3423
3423
|
const keys = Object.keys(promisesObj);
|
|
@@ -3745,11 +3745,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
3745
3745
|
}
|
|
3746
3746
|
return false;
|
|
3747
3747
|
}
|
|
3748
|
-
function prefixIssues(
|
|
3748
|
+
function prefixIssues(path100, issues) {
|
|
3749
3749
|
return issues.map((iss) => {
|
|
3750
3750
|
var _a3;
|
|
3751
3751
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
3752
|
-
iss.path.unshift(
|
|
3752
|
+
iss.path.unshift(path100);
|
|
3753
3753
|
return iss;
|
|
3754
3754
|
});
|
|
3755
3755
|
}
|
|
@@ -3967,16 +3967,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
3967
3967
|
}
|
|
3968
3968
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
3969
3969
|
const fieldErrors = { _errors: [] };
|
|
3970
|
-
const processError = (error52,
|
|
3970
|
+
const processError = (error52, path100 = []) => {
|
|
3971
3971
|
for (const issue2 of error52.issues) {
|
|
3972
3972
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
3973
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
3973
|
+
issue2.errors.map((issues) => processError({ issues }, [...path100, ...issue2.path]));
|
|
3974
3974
|
} else if (issue2.code === "invalid_key") {
|
|
3975
|
-
processError({ issues: issue2.issues }, [...
|
|
3975
|
+
processError({ issues: issue2.issues }, [...path100, ...issue2.path]);
|
|
3976
3976
|
} else if (issue2.code === "invalid_element") {
|
|
3977
|
-
processError({ issues: issue2.issues }, [...
|
|
3977
|
+
processError({ issues: issue2.issues }, [...path100, ...issue2.path]);
|
|
3978
3978
|
} else {
|
|
3979
|
-
const fullpath = [...
|
|
3979
|
+
const fullpath = [...path100, ...issue2.path];
|
|
3980
3980
|
if (fullpath.length === 0) {
|
|
3981
3981
|
fieldErrors._errors.push(mapper(issue2));
|
|
3982
3982
|
} else {
|
|
@@ -4003,17 +4003,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
4003
4003
|
}
|
|
4004
4004
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
4005
4005
|
const result = { errors: [] };
|
|
4006
|
-
const processError = (error52,
|
|
4006
|
+
const processError = (error52, path100 = []) => {
|
|
4007
4007
|
var _a3, _b;
|
|
4008
4008
|
for (const issue2 of error52.issues) {
|
|
4009
4009
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
4010
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
4010
|
+
issue2.errors.map((issues) => processError({ issues }, [...path100, ...issue2.path]));
|
|
4011
4011
|
} else if (issue2.code === "invalid_key") {
|
|
4012
|
-
processError({ issues: issue2.issues }, [...
|
|
4012
|
+
processError({ issues: issue2.issues }, [...path100, ...issue2.path]);
|
|
4013
4013
|
} else if (issue2.code === "invalid_element") {
|
|
4014
|
-
processError({ issues: issue2.issues }, [...
|
|
4014
|
+
processError({ issues: issue2.issues }, [...path100, ...issue2.path]);
|
|
4015
4015
|
} else {
|
|
4016
|
-
const fullpath = [...
|
|
4016
|
+
const fullpath = [...path100, ...issue2.path];
|
|
4017
4017
|
if (fullpath.length === 0) {
|
|
4018
4018
|
result.errors.push(mapper(issue2));
|
|
4019
4019
|
continue;
|
|
@@ -4045,8 +4045,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
4045
4045
|
}
|
|
4046
4046
|
function toDotPath(_path) {
|
|
4047
4047
|
const segs = [];
|
|
4048
|
-
const
|
|
4049
|
-
for (const seg of
|
|
4048
|
+
const path100 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
4049
|
+
for (const seg of path100) {
|
|
4050
4050
|
if (typeof seg === "number")
|
|
4051
4051
|
segs.push(`[${seg}]`);
|
|
4052
4052
|
else if (typeof seg === "symbol")
|
|
@@ -17549,13 +17549,13 @@ function resolveRef(ref, ctx) {
|
|
|
17549
17549
|
if (!ref.startsWith("#")) {
|
|
17550
17550
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
17551
17551
|
}
|
|
17552
|
-
const
|
|
17553
|
-
if (
|
|
17552
|
+
const path100 = ref.slice(1).split("/").filter(Boolean);
|
|
17553
|
+
if (path100.length === 0) {
|
|
17554
17554
|
return ctx.rootSchema;
|
|
17555
17555
|
}
|
|
17556
17556
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
17557
|
-
if (
|
|
17558
|
-
const key =
|
|
17557
|
+
if (path100[0] === defsKey) {
|
|
17558
|
+
const key = path100[1];
|
|
17559
17559
|
if (!key || !ctx.defs[key]) {
|
|
17560
17560
|
throw new Error(`Reference not found: ${ref}`);
|
|
17561
17561
|
}
|
|
@@ -18327,7 +18327,9 @@ var init_zod = __esm({
|
|
|
18327
18327
|
});
|
|
18328
18328
|
|
|
18329
18329
|
// packages/core/dist/core/tools/toolTypes.js
|
|
18330
|
-
function typedOk(value, meta3) {
|
|
18330
|
+
function typedOk(value, meta3, images) {
|
|
18331
|
+
if (images && images.length > 0)
|
|
18332
|
+
return { ok: true, value, meta: meta3, images };
|
|
18331
18333
|
return meta3 ? { ok: true, value, meta: meta3 } : { ok: true, value };
|
|
18332
18334
|
}
|
|
18333
18335
|
function typedErr(error51, meta3) {
|
|
@@ -18387,17 +18389,17 @@ var init_newlines = __esm({
|
|
|
18387
18389
|
});
|
|
18388
18390
|
|
|
18389
18391
|
// packages/core/dist/core/tools/builtin/fileEvents.js
|
|
18390
|
-
function fileReadEvent(
|
|
18391
|
-
return { kind: "file.read", actor: { type: "tool" }, data: { path:
|
|
18392
|
+
function fileReadEvent(path100, snapshotId) {
|
|
18393
|
+
return { kind: "file.read", actor: { type: "tool" }, data: { path: path100, snapshotId } };
|
|
18392
18394
|
}
|
|
18393
|
-
function fileAppliedEvent(
|
|
18394
|
-
return { kind: "file.applied", actor: { type: "tool" }, data: { path:
|
|
18395
|
+
function fileAppliedEvent(path100, snapshotId, bytes) {
|
|
18396
|
+
return { kind: "file.applied", actor: { type: "tool" }, data: { path: path100, snapshotId, bytes } };
|
|
18395
18397
|
}
|
|
18396
|
-
function fileRejectedEvent(
|
|
18398
|
+
function fileRejectedEvent(path100, reason, hint) {
|
|
18397
18399
|
return {
|
|
18398
18400
|
kind: "file.rejected",
|
|
18399
18401
|
actor: { type: "tool" },
|
|
18400
|
-
data: hint === void 0 ? { path:
|
|
18402
|
+
data: hint === void 0 ? { path: path100, reason } : { path: path100, reason, hint }
|
|
18401
18403
|
};
|
|
18402
18404
|
}
|
|
18403
18405
|
function reReadHint(reject) {
|
|
@@ -19313,8 +19315,8 @@ async function searchFile(absPath, relPath, regex, contextLines, remainingSlots)
|
|
|
19313
19315
|
}
|
|
19314
19316
|
async function isDirectory(p3) {
|
|
19315
19317
|
try {
|
|
19316
|
-
const
|
|
19317
|
-
return
|
|
19318
|
+
const stat8 = await fs7.stat(p3);
|
|
19319
|
+
return stat8.isDirectory();
|
|
19318
19320
|
} catch {
|
|
19319
19321
|
return false;
|
|
19320
19322
|
}
|
|
@@ -20266,11 +20268,11 @@ var init_tools = __esm({
|
|
|
20266
20268
|
if (!ctx.addDocument)
|
|
20267
20269
|
return "Knowledge vault tool not available.";
|
|
20268
20270
|
const title = args["title"] || "New Document";
|
|
20269
|
-
const
|
|
20271
|
+
const path100 = args["path"] || `notes/${title.toLowerCase().replace(/[^a-z0-9]+/g, "-")}`;
|
|
20270
20272
|
const content = args["content"] || "";
|
|
20271
20273
|
const tags = args["tags"] || [];
|
|
20272
20274
|
ctx.addDocument({
|
|
20273
|
-
path:
|
|
20275
|
+
path: path100,
|
|
20274
20276
|
title,
|
|
20275
20277
|
content,
|
|
20276
20278
|
format: "markdown",
|
|
@@ -20279,7 +20281,7 @@ var init_tools = __esm({
|
|
|
20279
20281
|
workspaceId: ctx.workspaceId
|
|
20280
20282
|
});
|
|
20281
20283
|
ctx.addActivity("vault", "created document", title);
|
|
20282
|
-
return `Document "${title}" created at "${
|
|
20284
|
+
return `Document "${title}" created at "${path100}".`;
|
|
20283
20285
|
}
|
|
20284
20286
|
}
|
|
20285
20287
|
];
|
|
@@ -25104,16 +25106,16 @@ function runRetentionFromEnv() {
|
|
|
25104
25106
|
maxTotalBytes: Number.isFinite(parseMb) && parseMb > 0 ? Math.round(parseMb * 1024 * 1024) : DEFAULT_RUN_RETENTION_MAX_MB * 1024 * 1024
|
|
25105
25107
|
};
|
|
25106
25108
|
}
|
|
25107
|
-
async function dirSize(
|
|
25109
|
+
async function dirSize(path100) {
|
|
25108
25110
|
let total = 0;
|
|
25109
25111
|
let entries;
|
|
25110
25112
|
try {
|
|
25111
|
-
entries = await readdir(
|
|
25113
|
+
entries = await readdir(path100, { withFileTypes: true });
|
|
25112
25114
|
} catch {
|
|
25113
25115
|
return 0;
|
|
25114
25116
|
}
|
|
25115
25117
|
for (const entry of entries) {
|
|
25116
|
-
const child = join3(
|
|
25118
|
+
const child = join3(path100, entry.name);
|
|
25117
25119
|
if (entry.isDirectory())
|
|
25118
25120
|
total += await dirSize(child);
|
|
25119
25121
|
else {
|
|
@@ -25140,19 +25142,19 @@ async function enforceRunRetention(runsDir, options = {}) {
|
|
|
25140
25142
|
for (const entry of entries) {
|
|
25141
25143
|
if (!entry.isDirectory())
|
|
25142
25144
|
continue;
|
|
25143
|
-
const
|
|
25145
|
+
const path100 = join3(runsDir, entry.name);
|
|
25144
25146
|
let startedAt = 0;
|
|
25145
25147
|
let endedAt;
|
|
25146
25148
|
let completed = false;
|
|
25147
25149
|
try {
|
|
25148
|
-
const manifest = JSON.parse(await readFile(join3(
|
|
25150
|
+
const manifest = JSON.parse(await readFile(join3(path100, "manifest.json"), "utf8"));
|
|
25149
25151
|
startedAt = manifest.startedAt ?? 0;
|
|
25150
25152
|
endedAt = manifest.endedAt;
|
|
25151
25153
|
completed = Boolean(endedAt) && manifest.status !== "running";
|
|
25152
25154
|
} catch {
|
|
25153
25155
|
completed = false;
|
|
25154
25156
|
}
|
|
25155
|
-
infos.push({ name: entry.name, path:
|
|
25157
|
+
infos.push({ name: entry.name, path: path100, startedAt, endedAt, completed, bytes: await dirSize(path100) });
|
|
25156
25158
|
}
|
|
25157
25159
|
const remove = async (info) => {
|
|
25158
25160
|
await rm(info.path, { recursive: true, force: true });
|
|
@@ -25639,12 +25641,12 @@ var init_engine = __esm({
|
|
|
25639
25641
|
* content digest) and the returned ref carries the event seq when the
|
|
25640
25642
|
* emitter resolved one.
|
|
25641
25643
|
*/
|
|
25642
|
-
async fsEvidence(observation,
|
|
25644
|
+
async fsEvidence(observation, path100, sha256, content, extra = {}) {
|
|
25643
25645
|
const digest = sha256 && content !== void 0 ? sha256(content) : void 0;
|
|
25644
|
-
const seq = await this.emitEvidence({ observation, path:
|
|
25646
|
+
const seq = await this.emitEvidence({ observation, path: path100, ...extra, ...digest ? { digest } : {} });
|
|
25645
25647
|
return {
|
|
25646
25648
|
tier: "fs-observation",
|
|
25647
|
-
ref:
|
|
25649
|
+
ref: path100,
|
|
25648
25650
|
capturedAt: Date.now(),
|
|
25649
25651
|
...digest ? { digest } : {},
|
|
25650
25652
|
...seq !== void 0 ? { seq } : {}
|
|
@@ -29106,7 +29108,8 @@ ${shared.content}`,
|
|
|
29106
29108
|
return {
|
|
29107
29109
|
content: resultStr,
|
|
29108
29110
|
isError: !result.ok,
|
|
29109
|
-
durationMs: Date.now() - startMs
|
|
29111
|
+
durationMs: Date.now() - startMs,
|
|
29112
|
+
...result.ok && result.images && result.images.length > 0 ? { images: result.images } : {}
|
|
29110
29113
|
};
|
|
29111
29114
|
})();
|
|
29112
29115
|
inflight.set(callKey, prom);
|
|
@@ -29127,7 +29130,8 @@ ${shared.content}`,
|
|
|
29127
29130
|
toolCallId: p3.toolCallId,
|
|
29128
29131
|
content: r.content,
|
|
29129
29132
|
isError: r.isError,
|
|
29130
|
-
endEvent
|
|
29133
|
+
endEvent,
|
|
29134
|
+
...r.images ? { images: r.images } : {}
|
|
29131
29135
|
// Cache already written in invokeOne; no need to re-set.
|
|
29132
29136
|
};
|
|
29133
29137
|
};
|
|
@@ -29679,7 +29683,8 @@ ${cached2}`
|
|
|
29679
29683
|
yield item.endEvent;
|
|
29680
29684
|
turnToolResults.push({
|
|
29681
29685
|
toolCallId: item.toolCallId,
|
|
29682
|
-
content: item.content
|
|
29686
|
+
content: item.content,
|
|
29687
|
+
...item.images ? { images: item.images } : {}
|
|
29683
29688
|
});
|
|
29684
29689
|
if (item.cacheKey && item.content && !item.isError) {
|
|
29685
29690
|
this.toolCallCache.set(item.cacheKey, item.content);
|
|
@@ -29859,7 +29864,8 @@ ${cached2}`
|
|
|
29859
29864
|
this.config.messages.push({
|
|
29860
29865
|
role: "tool",
|
|
29861
29866
|
toolCallId: tr.toolCallId,
|
|
29862
|
-
content: tr.content
|
|
29867
|
+
content: tr.content,
|
|
29868
|
+
...tr.images ? { images: tr.images } : {}
|
|
29863
29869
|
});
|
|
29864
29870
|
}
|
|
29865
29871
|
if (truncatedToolCall) {
|
|
@@ -31660,11 +31666,11 @@ var init_synthesisAudit = __esm({
|
|
|
31660
31666
|
import { existsSync as existsSync10, readFileSync as readFileSync9, writeFileSync as writeFileSync6 } from "node:fs";
|
|
31661
31667
|
import { join as join5 } from "node:path";
|
|
31662
31668
|
function loadNfrSpec(zelariRoot) {
|
|
31663
|
-
const
|
|
31664
|
-
if (!existsSync10(
|
|
31669
|
+
const path100 = join5(zelariRoot, "nfr-spec.json");
|
|
31670
|
+
if (!existsSync10(path100))
|
|
31665
31671
|
return null;
|
|
31666
31672
|
try {
|
|
31667
|
-
const raw = JSON.parse(readFileSync9(
|
|
31673
|
+
const raw = JSON.parse(readFileSync9(path100, "utf8"));
|
|
31668
31674
|
if (raw.version !== 1 || !Array.isArray(raw.targets))
|
|
31669
31675
|
return null;
|
|
31670
31676
|
return raw;
|
|
@@ -34047,9 +34053,9 @@ var init_types9 = __esm({
|
|
|
34047
34053
|
import { readFileSync as readFileSync14 } from "node:fs";
|
|
34048
34054
|
import { join as join11 } from "node:path";
|
|
34049
34055
|
function readLessonsDeduped(zelariRoot) {
|
|
34050
|
-
const
|
|
34056
|
+
const path100 = join11(zelariRoot, LESSONS_FILE);
|
|
34051
34057
|
try {
|
|
34052
|
-
const raw = readFileSync14(
|
|
34058
|
+
const raw = readFileSync14(path100, "utf8");
|
|
34053
34059
|
const byId = /* @__PURE__ */ new Map();
|
|
34054
34060
|
for (const line of raw.split(/\r?\n/)) {
|
|
34055
34061
|
if (!line.trim())
|
|
@@ -34150,8 +34156,8 @@ function keywordsFrom(check2, signature) {
|
|
|
34150
34156
|
return [.../* @__PURE__ */ new Set([...fromId, ...words])].slice(0, 12);
|
|
34151
34157
|
}
|
|
34152
34158
|
function writeLesson(zelariRoot, lesson) {
|
|
34153
|
-
const
|
|
34154
|
-
appendFileSync(
|
|
34159
|
+
const path100 = join12(zelariRoot, LESSONS_FILE);
|
|
34160
|
+
appendFileSync(path100, `${JSON.stringify(lesson)}
|
|
34155
34161
|
`, "utf8");
|
|
34156
34162
|
}
|
|
34157
34163
|
function findSimilar(lessons, signature) {
|
|
@@ -36118,9 +36124,9 @@ function findCycle(nodes) {
|
|
|
36118
36124
|
if (color.get(start) !== WHITE)
|
|
36119
36125
|
continue;
|
|
36120
36126
|
const stack = [[start, 0]];
|
|
36121
|
-
const
|
|
36127
|
+
const path100 = [];
|
|
36122
36128
|
color.set(start, GRAY);
|
|
36123
|
-
|
|
36129
|
+
path100.push(start);
|
|
36124
36130
|
while (stack.length > 0) {
|
|
36125
36131
|
const top = stack[stack.length - 1];
|
|
36126
36132
|
const [id3, idx] = top;
|
|
@@ -36133,17 +36139,17 @@ function findCycle(nodes) {
|
|
|
36133
36139
|
continue;
|
|
36134
36140
|
const c = color.get(dep);
|
|
36135
36141
|
if (c === GRAY) {
|
|
36136
|
-
const at =
|
|
36137
|
-
return [...
|
|
36142
|
+
const at = path100.indexOf(dep);
|
|
36143
|
+
return [...path100.slice(at), dep];
|
|
36138
36144
|
}
|
|
36139
36145
|
if (c === WHITE) {
|
|
36140
36146
|
color.set(dep, GRAY);
|
|
36141
|
-
|
|
36147
|
+
path100.push(dep);
|
|
36142
36148
|
stack.push([dep, 0]);
|
|
36143
36149
|
}
|
|
36144
36150
|
} else {
|
|
36145
36151
|
color.set(id3, BLACK);
|
|
36146
|
-
|
|
36152
|
+
path100.pop();
|
|
36147
36153
|
stack.pop();
|
|
36148
36154
|
}
|
|
36149
36155
|
}
|
|
@@ -37063,8 +37069,8 @@ var init_runner = __esm({
|
|
|
37063
37069
|
failed: [...this.tentaclesById.values()].filter((r) => r.status === "error"),
|
|
37064
37070
|
pending: []
|
|
37065
37071
|
};
|
|
37066
|
-
const
|
|
37067
|
-
this.host.log(`checkpoint: ${label ?? "auto"} \u2192 ${
|
|
37072
|
+
const path100 = await this.host.saveSnapshot(snapshot, ".zelari/kraken/snapshots");
|
|
37073
|
+
this.host.log(`checkpoint: ${label ?? "auto"} \u2192 ${path100}`);
|
|
37068
37074
|
return snapshot;
|
|
37069
37075
|
}
|
|
37070
37076
|
callLog(msg, data) {
|
|
@@ -38215,7 +38221,7 @@ var CORE_VERSION;
|
|
|
38215
38221
|
var init_version = __esm({
|
|
38216
38222
|
"packages/core/dist/version.js"() {
|
|
38217
38223
|
"use strict";
|
|
38218
|
-
CORE_VERSION = "2.
|
|
38224
|
+
CORE_VERSION = "2.35.0";
|
|
38219
38225
|
}
|
|
38220
38226
|
});
|
|
38221
38227
|
|
|
@@ -40673,9 +40679,9 @@ function spillToolOutput(fullText, meta3) {
|
|
|
40673
40679
|
const rnd = randomBytes3(3).toString("hex");
|
|
40674
40680
|
const safeTool = (meta3?.toolName ?? "tool").replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 32);
|
|
40675
40681
|
const file2 = `${stamp}-${safeTool}-${hash3}-${rnd}.txt`;
|
|
40676
|
-
const
|
|
40677
|
-
writeFileSync12(
|
|
40678
|
-
return
|
|
40682
|
+
const path100 = join14(dir, file2);
|
|
40683
|
+
writeFileSync12(path100, fullText, "utf8");
|
|
40684
|
+
return path100;
|
|
40679
40685
|
} catch {
|
|
40680
40686
|
return null;
|
|
40681
40687
|
}
|
|
@@ -40721,10 +40727,10 @@ function truncateToolResult(text, capOrOpts = TOOL_RESULT_LINE_CAP) {
|
|
|
40721
40727
|
${tail2}`;
|
|
40722
40728
|
}
|
|
40723
40729
|
if (doSpill) {
|
|
40724
|
-
const
|
|
40725
|
-
if (
|
|
40730
|
+
const path100 = spillToolOutput(text, { toolName: opts.toolName });
|
|
40731
|
+
if (path100) {
|
|
40726
40732
|
const spillNote = `
|
|
40727
|
-
\u2026 [full output spilled to: ${
|
|
40733
|
+
\u2026 [full output spilled to: ${path100} \u2014 re-read with read_file if you need the complete text] \u2026`;
|
|
40728
40734
|
if (preview.includes("] \u2026\n")) {
|
|
40729
40735
|
preview = preview.replace("] \u2026\n", `] \u2026${spillNote}
|
|
40730
40736
|
`);
|
|
@@ -41495,28 +41501,28 @@ var init_storage = __esm({
|
|
|
41495
41501
|
VALID_SCALARS = /^(true|false|null|~)$/i;
|
|
41496
41502
|
Storage = class {
|
|
41497
41503
|
/** Read a Markdown file with frontmatter. Throws if not found. */
|
|
41498
|
-
read(
|
|
41499
|
-
if (!existsSync19(
|
|
41500
|
-
throw new Error(`File not found: ${
|
|
41504
|
+
read(path100) {
|
|
41505
|
+
if (!existsSync19(path100)) {
|
|
41506
|
+
throw new Error(`File not found: ${path100}`);
|
|
41501
41507
|
}
|
|
41502
|
-
const md = readFileSync17(
|
|
41508
|
+
const md = readFileSync17(path100, "utf8");
|
|
41503
41509
|
return parseFrontmatter(md);
|
|
41504
41510
|
}
|
|
41505
41511
|
/** Read a Markdown file; returns null if not found. */
|
|
41506
|
-
readIfExists(
|
|
41507
|
-
if (!existsSync19(
|
|
41508
|
-
return this.read(
|
|
41512
|
+
readIfExists(path100) {
|
|
41513
|
+
if (!existsSync19(path100)) return null;
|
|
41514
|
+
return this.read(path100);
|
|
41509
41515
|
}
|
|
41510
41516
|
/**
|
|
41511
41517
|
* Write a Markdown file atomically (tmp + rename). Creates parent dirs.
|
|
41512
41518
|
* The meta object is serialized as YAML frontmatter; body as Markdown.
|
|
41513
41519
|
*/
|
|
41514
|
-
write(
|
|
41515
|
-
mkdirSync10(dirname2(
|
|
41516
|
-
const tmp =
|
|
41520
|
+
write(path100, meta3, body) {
|
|
41521
|
+
mkdirSync10(dirname2(path100), { recursive: true });
|
|
41522
|
+
const tmp = path100 + ".tmp-" + process.pid;
|
|
41517
41523
|
const md = serializeFrontmatter(meta3, body);
|
|
41518
41524
|
writeFileSync14(tmp, md, "utf8");
|
|
41519
|
-
renameSync2(tmp,
|
|
41525
|
+
renameSync2(tmp, path100);
|
|
41520
41526
|
}
|
|
41521
41527
|
/** List all .md files in a directory (non-recursive). */
|
|
41522
41528
|
listMarkdown(dir) {
|
|
@@ -41591,8 +41597,8 @@ function nextPlanTaskId(store6) {
|
|
|
41591
41597
|
return `t${store6.counter}`;
|
|
41592
41598
|
}
|
|
41593
41599
|
function writePlanTaskArtifact(rootDir, task) {
|
|
41594
|
-
const
|
|
41595
|
-
mkdirSync11(dirname3(
|
|
41600
|
+
const path100 = join17(rootDir, "plan-tasks", `${task.id}.md`);
|
|
41601
|
+
mkdirSync11(dirname3(path100), { recursive: true });
|
|
41596
41602
|
const meta3 = {
|
|
41597
41603
|
kind: "task",
|
|
41598
41604
|
id: task.id,
|
|
@@ -41613,7 +41619,7 @@ function writePlanTaskArtifact(rootDir, task) {
|
|
|
41613
41619
|
task.notes?.trim() ? task.notes.trim() : "_(no notes)_",
|
|
41614
41620
|
""
|
|
41615
41621
|
].filter((l) => l !== null).join("\n");
|
|
41616
|
-
new Storage().write(
|
|
41622
|
+
new Storage().write(path100, meta3, body);
|
|
41617
41623
|
}
|
|
41618
41624
|
function loadHandle(rootDir) {
|
|
41619
41625
|
const jsonPath = join17(rootDir, "plan.json");
|
|
@@ -50815,12 +50821,9 @@ function backoffDelay(attempt, retryAfterHeader) {
|
|
|
50815
50821
|
}
|
|
50816
50822
|
return Math.min(BACKOFF_BASE_MS * 2 ** attempt, BACKOFF_CAP_MS);
|
|
50817
50823
|
}
|
|
50818
|
-
function modelSupportsVision(
|
|
50824
|
+
function modelSupportsVision(_model) {
|
|
50819
50825
|
const force = process.env.ZELARI_VISION;
|
|
50820
|
-
|
|
50821
|
-
if (force === "0" || force === "false" || force === "off") return false;
|
|
50822
|
-
const m = model.toLowerCase();
|
|
50823
|
-
return VISION_MODEL_HINTS.some((hint) => m.includes(hint));
|
|
50826
|
+
return !(force === "0" || force === "false" || force === "off");
|
|
50824
50827
|
}
|
|
50825
50828
|
function dataUriFromImage(img) {
|
|
50826
50829
|
return `data:${img.mime};base64,${img.dataBase64}`;
|
|
@@ -50915,6 +50918,22 @@ ${notes}
|
|
|
50915
50918
|
}
|
|
50916
50919
|
return { role: m.role, content: m.content };
|
|
50917
50920
|
}
|
|
50921
|
+
function imagesFollowUpMessage(images) {
|
|
50922
|
+
const labels = images.map((img) => img.alt ?? img.mime).join(", ");
|
|
50923
|
+
return {
|
|
50924
|
+
role: "user",
|
|
50925
|
+
content: [
|
|
50926
|
+
{
|
|
50927
|
+
type: "text",
|
|
50928
|
+
text: `[Immagine(i) dal tool: ${labels} \u2014 usa questi pixel per l'analisi visiva.]`
|
|
50929
|
+
},
|
|
50930
|
+
...images.map((img) => ({
|
|
50931
|
+
type: "image_url",
|
|
50932
|
+
image_url: { url: dataUriFromImage(img) }
|
|
50933
|
+
}))
|
|
50934
|
+
]
|
|
50935
|
+
};
|
|
50936
|
+
}
|
|
50918
50937
|
function positiveEnvInt(name) {
|
|
50919
50938
|
const raw = process.env[name];
|
|
50920
50939
|
if (!raw) return void 0;
|
|
@@ -50925,15 +50944,27 @@ function openaiCompatibleProvider(config2) {
|
|
|
50925
50944
|
return async function* (params) {
|
|
50926
50945
|
const capabilities = capabilitiesFor(params.model, config2.providerId);
|
|
50927
50946
|
const vision = modelSupportsVision(params.model);
|
|
50928
|
-
const
|
|
50947
|
+
const msgsIn = params.messages;
|
|
50948
|
+
let toolRunImages = [];
|
|
50949
|
+
const messages = msgsIn.flatMap((m, i) => {
|
|
50929
50950
|
const cacheable = !(m.role === "user" && m.images && m.images.length > 0);
|
|
50930
50951
|
if (cacheable) {
|
|
50931
50952
|
const cached2 = messageMappingCache.get(m);
|
|
50932
|
-
if (cached2) return cached2;
|
|
50953
|
+
if (cached2) return [cached2];
|
|
50933
50954
|
}
|
|
50934
50955
|
const mapped = mapAgentMessage(m, vision);
|
|
50935
50956
|
if (cacheable) messageMappingCache.set(m, mapped);
|
|
50936
|
-
|
|
50957
|
+
if (m.role === "tool") {
|
|
50958
|
+
if (m.images && m.images.length > 0) toolRunImages.push(...m.images);
|
|
50959
|
+
const next = msgsIn[i + 1];
|
|
50960
|
+
const runEnds = !next || next.role !== "tool";
|
|
50961
|
+
if (runEnds && vision && toolRunImages.length > 0) {
|
|
50962
|
+
const followUp = imagesFollowUpMessage(toolRunImages);
|
|
50963
|
+
toolRunImages = [];
|
|
50964
|
+
return [mapped, followUp];
|
|
50965
|
+
}
|
|
50966
|
+
}
|
|
50967
|
+
return [mapped];
|
|
50937
50968
|
});
|
|
50938
50969
|
const generation = params.generation;
|
|
50939
50970
|
const body = {
|
|
@@ -51257,7 +51288,7 @@ async function providerConfigFor(providerId) {
|
|
|
51257
51288
|
...extraFromStored(providerId)
|
|
51258
51289
|
};
|
|
51259
51290
|
}
|
|
51260
|
-
var RETRYABLE_STATUSES, MAX_RETRIES, BACKOFF_BASE_MS, BACKOFF_CAP_MS, PROVIDER_CONNECT_TIMEOUT_MS, PROVIDER_STREAM_IDLE_MS, PROVIDER_STREAM_MAX_MS,
|
|
51291
|
+
var RETRYABLE_STATUSES, MAX_RETRIES, BACKOFF_BASE_MS, BACKOFF_CAP_MS, PROVIDER_CONNECT_TIMEOUT_MS, PROVIDER_STREAM_IDLE_MS, PROVIDER_STREAM_MAX_MS, PROVIDER_ENDPOINTS, messageMappingCache;
|
|
51261
51292
|
var init_openai_compatible = __esm({
|
|
51262
51293
|
"src/cli/provider/openai-compatible.ts"() {
|
|
51263
51294
|
"use strict";
|
|
@@ -51288,33 +51319,6 @@ var init_openai_compatible = __esm({
|
|
|
51288
51319
|
const n = raw ? Number.parseInt(raw, 10) : 18e5;
|
|
51289
51320
|
return Number.isFinite(n) && n >= 6e4 ? n : 18e5;
|
|
51290
51321
|
})();
|
|
51291
|
-
VISION_MODEL_HINTS = [
|
|
51292
|
-
"grok-4",
|
|
51293
|
-
"grok-3",
|
|
51294
|
-
"grok-2-vision",
|
|
51295
|
-
"grok-vision",
|
|
51296
|
-
"glm-4v",
|
|
51297
|
-
"glm-4.5v",
|
|
51298
|
-
"glm-4.1v",
|
|
51299
|
-
"glm-5v",
|
|
51300
|
-
"qwen-vl",
|
|
51301
|
-
"qwen2-vl",
|
|
51302
|
-
"qwen2.5-vl",
|
|
51303
|
-
"qwen3-vl",
|
|
51304
|
-
"gpt-4o",
|
|
51305
|
-
"gpt-4.1",
|
|
51306
|
-
"gpt-4.5",
|
|
51307
|
-
"gpt-4-vision",
|
|
51308
|
-
"gpt-5",
|
|
51309
|
-
"claude-3",
|
|
51310
|
-
"claude-4",
|
|
51311
|
-
"gemini-",
|
|
51312
|
-
"gemini/",
|
|
51313
|
-
"minimax-m1",
|
|
51314
|
-
"minimax-m2",
|
|
51315
|
-
"minimax-m3",
|
|
51316
|
-
"deepseek-vl"
|
|
51317
|
-
];
|
|
51318
51322
|
PROVIDER_ENDPOINTS = {
|
|
51319
51323
|
"openai-compatible": "https://api.x.ai/v1",
|
|
51320
51324
|
"minimax": "https://api.minimax.io/v1",
|
|
@@ -51709,6 +51713,16 @@ var init_driver = __esm({
|
|
|
51709
51713
|
// src/cli/browser/tools.ts
|
|
51710
51714
|
import path56 from "node:path";
|
|
51711
51715
|
import os3 from "node:os";
|
|
51716
|
+
import { readFile as readFile7 } from "node:fs/promises";
|
|
51717
|
+
async function loadImageBlock(filePath) {
|
|
51718
|
+
try {
|
|
51719
|
+
const buf = await readFile7(filePath);
|
|
51720
|
+
if (buf.byteLength > SCREENSHOT_MAX_BYTES) return void 0;
|
|
51721
|
+
return { mime: "image/png", dataBase64: buf.toString("base64"), alt: path56.basename(filePath) };
|
|
51722
|
+
} catch {
|
|
51723
|
+
return void 0;
|
|
51724
|
+
}
|
|
51725
|
+
}
|
|
51712
51726
|
function createBrowserTool(deps = {}) {
|
|
51713
51727
|
return {
|
|
51714
51728
|
name: "browser_check",
|
|
@@ -51761,17 +51775,23 @@ function createBrowserTool(deps = {}) {
|
|
|
51761
51775
|
note: "Weak smoke only: no selector/text/evaluate assertions. No console/page errors is necessary but not sufficient to claim a logic fix. Add waitForSelector, waitForText, or evaluate (DOM/read hooks) for stronger evidence.",
|
|
51762
51776
|
smokeStrength: "weak"
|
|
51763
51777
|
} : { smokeStrength: "asserted" }
|
|
51764
|
-
});
|
|
51778
|
+
}, void 0, await toolImages(result.screenshotPath));
|
|
51765
51779
|
}
|
|
51766
51780
|
};
|
|
51767
51781
|
}
|
|
51768
|
-
|
|
51782
|
+
async function toolImages(screenshotPath) {
|
|
51783
|
+
if (!screenshotPath) return void 0;
|
|
51784
|
+
const image = await loadImageBlock(screenshotPath);
|
|
51785
|
+
return image ? [image] : void 0;
|
|
51786
|
+
}
|
|
51787
|
+
var SCREENSHOT_MAX_BYTES, ActionSchema;
|
|
51769
51788
|
var init_tools5 = __esm({
|
|
51770
51789
|
"src/cli/browser/tools.ts"() {
|
|
51771
51790
|
"use strict";
|
|
51772
51791
|
init_zod();
|
|
51773
51792
|
init_toolTypes();
|
|
51774
51793
|
init_driver();
|
|
51794
|
+
SCREENSHOT_MAX_BYTES = 8 * 1024 * 1024;
|
|
51775
51795
|
ActionSchema = external_exports.discriminatedUnion("type", [
|
|
51776
51796
|
external_exports.object({ type: external_exports.literal("click"), selector: external_exports.string().min(1) }),
|
|
51777
51797
|
external_exports.object({ type: external_exports.literal("fill"), selector: external_exports.string().min(1), value: external_exports.string() }),
|
|
@@ -51796,6 +51816,92 @@ var init_tools5 = __esm({
|
|
|
51796
51816
|
}
|
|
51797
51817
|
});
|
|
51798
51818
|
|
|
51819
|
+
// src/cli/tools/screenshotTool.ts
|
|
51820
|
+
import { execFile as execFile5 } from "node:child_process";
|
|
51821
|
+
import { mkdir as mkdir3, readFile as readFile8, stat as stat7 } from "node:fs/promises";
|
|
51822
|
+
import path57 from "node:path";
|
|
51823
|
+
import { promisify as promisify4 } from "node:util";
|
|
51824
|
+
async function captureWindows(target) {
|
|
51825
|
+
const script = `Add-Type -AssemblyName System.Windows.Forms,System.Drawing;$b=[System.Windows.Forms.SystemInformation]::VirtualScreen;$bmp=New-Object System.Drawing.Bitmap $b.Width,$b.Height;$g=[System.Drawing.Graphics]::FromImage($bmp);$g.CopyFromScreen($b.Left,$b.Top,0,0,$bmp.Size);$g.Dispose(); $bmp.Save('${target.replace(/'/g, "''")}'); $bmp.Dispose();`;
|
|
51826
|
+
await execFileAsync4("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", script], {
|
|
51827
|
+
timeout: 12e3,
|
|
51828
|
+
windowsHide: true
|
|
51829
|
+
});
|
|
51830
|
+
}
|
|
51831
|
+
async function captureUnixLike(target) {
|
|
51832
|
+
const attempts = process.platform === "darwin" ? [["screencapture", ["-x", target]]] : [
|
|
51833
|
+
["gnome-screenshot", ["-f", target]],
|
|
51834
|
+
["scrot", [target]],
|
|
51835
|
+
["import", ["-window", "root", target]]
|
|
51836
|
+
];
|
|
51837
|
+
let lastErr = null;
|
|
51838
|
+
for (const [bin, args] of attempts) {
|
|
51839
|
+
try {
|
|
51840
|
+
await execFileAsync4(bin, args, { timeout: 12e3 });
|
|
51841
|
+
return;
|
|
51842
|
+
} catch (e) {
|
|
51843
|
+
lastErr = e;
|
|
51844
|
+
}
|
|
51845
|
+
}
|
|
51846
|
+
throw lastErr ?? new Error("no screen-capture utility available");
|
|
51847
|
+
}
|
|
51848
|
+
function createScreenshotTool(deps = {}) {
|
|
51849
|
+
return {
|
|
51850
|
+
name: "screenshot",
|
|
51851
|
+
description: "Capture a screenshot of the user screen(s) as PNG. Use it when the user asks to see/check something on screen (running app, game, dialog, error window) or when you need to LOOK at the current UI state to debug it. The image is returned to you as pixels (vision) and saved to disk; give the path back to the user so they can open it.",
|
|
51852
|
+
permissions: ["ui"],
|
|
51853
|
+
timeoutMs: 2e4,
|
|
51854
|
+
inputSchema: external_exports.object({
|
|
51855
|
+
note: external_exports.string().max(200).optional().describe("Why you are capturing (shown to the user with the permission prompt).")
|
|
51856
|
+
}),
|
|
51857
|
+
execute: async (args, ctx) => {
|
|
51858
|
+
const a = args;
|
|
51859
|
+
const dir = deps.outDir ?? path57.join(ctx.cwd ?? process.cwd(), ".zelari", "screenshots");
|
|
51860
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
51861
|
+
const target = path57.join(dir, `screenshot-${stamp}.png`);
|
|
51862
|
+
const capture = deps.capture ?? (process.platform === "win32" ? captureWindows : captureUnixLike);
|
|
51863
|
+
try {
|
|
51864
|
+
await mkdir3(dir, { recursive: true });
|
|
51865
|
+
await capture(target);
|
|
51866
|
+
const meta3 = await stat7(target);
|
|
51867
|
+
if (meta3.size === 0) return typedErr(`capture produced an empty file: ${target}`);
|
|
51868
|
+
const buf = await readFile8(target);
|
|
51869
|
+
const image = {
|
|
51870
|
+
mime: "image/png",
|
|
51871
|
+
dataBase64: buf.toString("base64"),
|
|
51872
|
+
alt: path57.basename(target)
|
|
51873
|
+
};
|
|
51874
|
+
const attachable = meta3.size <= SCREENSHOT_MAX_BYTES2;
|
|
51875
|
+
return typedOk(
|
|
51876
|
+
{
|
|
51877
|
+
ok: true,
|
|
51878
|
+
path: target,
|
|
51879
|
+
bytes: meta3.size,
|
|
51880
|
+
...a.note ? { note: a.note } : {},
|
|
51881
|
+
...attachable ? {} : { warning: "PNG over 8MB: pixels not attached to the model context; open the path instead." }
|
|
51882
|
+
},
|
|
51883
|
+
void 0,
|
|
51884
|
+
attachable ? [image] : void 0
|
|
51885
|
+
);
|
|
51886
|
+
} catch (e) {
|
|
51887
|
+
return typedErr(
|
|
51888
|
+
`screen capture failed on ${process.platform}: ${e instanceof Error ? e.message : String(e)}`
|
|
51889
|
+
);
|
|
51890
|
+
}
|
|
51891
|
+
}
|
|
51892
|
+
};
|
|
51893
|
+
}
|
|
51894
|
+
var execFileAsync4, SCREENSHOT_MAX_BYTES2;
|
|
51895
|
+
var init_screenshotTool = __esm({
|
|
51896
|
+
"src/cli/tools/screenshotTool.ts"() {
|
|
51897
|
+
"use strict";
|
|
51898
|
+
init_zod();
|
|
51899
|
+
init_toolTypes();
|
|
51900
|
+
execFileAsync4 = promisify4(execFile5);
|
|
51901
|
+
SCREENSHOT_MAX_BYTES2 = 8 * 1024 * 1024;
|
|
51902
|
+
}
|
|
51903
|
+
});
|
|
51904
|
+
|
|
51799
51905
|
// src/cli/ssh/targets.ts
|
|
51800
51906
|
var targets_exports = {};
|
|
51801
51907
|
__export(targets_exports, {
|
|
@@ -51837,21 +51943,21 @@ function normalizeAuth(auth) {
|
|
|
51837
51943
|
return "agent";
|
|
51838
51944
|
}
|
|
51839
51945
|
function readSecrets() {
|
|
51840
|
-
const
|
|
51841
|
-
if (!existsSync30(
|
|
51946
|
+
const path100 = getSshSecretsPath();
|
|
51947
|
+
if (!existsSync30(path100)) return {};
|
|
51842
51948
|
try {
|
|
51843
|
-
return JSON.parse(readFileSync22(
|
|
51949
|
+
return JSON.parse(readFileSync22(path100, "utf8"));
|
|
51844
51950
|
} catch {
|
|
51845
51951
|
return {};
|
|
51846
51952
|
}
|
|
51847
51953
|
}
|
|
51848
51954
|
function writeSecrets(data) {
|
|
51849
|
-
const
|
|
51850
|
-
mkdirSync13(dirname4(
|
|
51851
|
-
writeFileSync16(
|
|
51955
|
+
const path100 = getSshSecretsPath();
|
|
51956
|
+
mkdirSync13(dirname4(path100), { recursive: true });
|
|
51957
|
+
writeFileSync16(path100, `${JSON.stringify(data, null, 2)}
|
|
51852
51958
|
`, "utf8");
|
|
51853
51959
|
try {
|
|
51854
|
-
chmodSync(
|
|
51960
|
+
chmodSync(path100, 384);
|
|
51855
51961
|
} catch {
|
|
51856
51962
|
}
|
|
51857
51963
|
}
|
|
@@ -51880,10 +51986,10 @@ function deleteSshPassword(id3) {
|
|
|
51880
51986
|
writeSecrets({ passwords });
|
|
51881
51987
|
}
|
|
51882
51988
|
function readStore2() {
|
|
51883
|
-
const
|
|
51884
|
-
if (!existsSync30(
|
|
51989
|
+
const path100 = getSshTargetsPath();
|
|
51990
|
+
if (!existsSync30(path100)) return [];
|
|
51885
51991
|
try {
|
|
51886
|
-
const parsed = JSON.parse(readFileSync22(
|
|
51992
|
+
const parsed = JSON.parse(readFileSync22(path100, "utf8"));
|
|
51887
51993
|
const list = Array.isArray(parsed.targets) ? parsed.targets : [];
|
|
51888
51994
|
return list.filter(
|
|
51889
51995
|
(t) => t && typeof t.id === "string" && typeof t.host === "string" && typeof t.user === "string"
|
|
@@ -51898,11 +52004,11 @@ function readStore2() {
|
|
|
51898
52004
|
}
|
|
51899
52005
|
}
|
|
51900
52006
|
function writeStore2(targets) {
|
|
51901
|
-
const
|
|
51902
|
-
mkdirSync13(dirname4(
|
|
52007
|
+
const path100 = getSshTargetsPath();
|
|
52008
|
+
mkdirSync13(dirname4(path100), { recursive: true });
|
|
51903
52009
|
const clean = targets.map(({ hasPassword: _hp, ...t }) => t);
|
|
51904
52010
|
writeFileSync16(
|
|
51905
|
-
|
|
52011
|
+
path100,
|
|
51906
52012
|
`${JSON.stringify({ targets: clean }, null, 2)}
|
|
51907
52013
|
`,
|
|
51908
52014
|
"utf8"
|
|
@@ -52148,11 +52254,11 @@ function formatSshTargetsForPrompt() {
|
|
|
52148
52254
|
];
|
|
52149
52255
|
for (const t of targets) {
|
|
52150
52256
|
const tags = t.tags?.length ? ` tags=[${t.tags.join(",")}]` : "";
|
|
52151
|
-
const
|
|
52257
|
+
const path100 = t.defaultRemotePath ? ` remotePath=${t.defaultRemotePath}` : "";
|
|
52152
52258
|
const allow = t.allowedCommands?.length ? ` allowed=${t.allowedCommands.join("|")}` : " allowed=status-only";
|
|
52153
52259
|
const auth = t.auth === "password" ? " auth=password" : t.auth === "keyPath" ? " auth=key" : " auth=agent";
|
|
52154
52260
|
lines.push(
|
|
52155
|
-
`- id=${t.id} name=${t.name} ${t.user}@${t.host}:${t.port ?? 22}${auth}${
|
|
52261
|
+
`- id=${t.id} name=${t.name} ${t.user}@${t.host}:${t.port ?? 22}${auth}${path100}${tags}${allow}`
|
|
52156
52262
|
);
|
|
52157
52263
|
}
|
|
52158
52264
|
return lines.join("\n");
|
|
@@ -53138,12 +53244,12 @@ __export(folderTrust_exports, {
|
|
|
53138
53244
|
untrustFolder: () => untrustFolder
|
|
53139
53245
|
});
|
|
53140
53246
|
import { existsSync as existsSync31, mkdirSync as mkdirSync14, readFileSync as readFileSync23, writeFileSync as writeFileSync17 } from "node:fs";
|
|
53141
|
-
import
|
|
53247
|
+
import path58 from "node:path";
|
|
53142
53248
|
function trustStorePath() {
|
|
53143
53249
|
return _overrideStorePath ?? trustConfigPath();
|
|
53144
53250
|
}
|
|
53145
53251
|
function normalize6(p3) {
|
|
53146
|
-
const resolved =
|
|
53252
|
+
const resolved = path58.resolve(p3);
|
|
53147
53253
|
return process.platform === "win32" ? resolved.toLowerCase() : resolved;
|
|
53148
53254
|
}
|
|
53149
53255
|
function readStore3() {
|
|
@@ -53159,7 +53265,7 @@ function readStore3() {
|
|
|
53159
53265
|
function writeStore3(store6) {
|
|
53160
53266
|
const p3 = trustStorePath();
|
|
53161
53267
|
try {
|
|
53162
|
-
mkdirSync14(
|
|
53268
|
+
mkdirSync14(path58.dirname(p3), { recursive: true });
|
|
53163
53269
|
writeFileSync17(p3, JSON.stringify(store6, null, 2), "utf8");
|
|
53164
53270
|
} catch (err) {
|
|
53165
53271
|
throw new Error(
|
|
@@ -53185,7 +53291,7 @@ function isFolderTrusted(folderPath) {
|
|
|
53185
53291
|
}
|
|
53186
53292
|
function trustFolder(folderPath) {
|
|
53187
53293
|
const store6 = readStore3();
|
|
53188
|
-
const normalized =
|
|
53294
|
+
const normalized = path58.resolve(folderPath);
|
|
53189
53295
|
if (!store6.folders.some((f) => normalize6(f.path) === normalize6(normalized))) {
|
|
53190
53296
|
store6.folders.push({ path: normalized, trustedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
53191
53297
|
writeStore3(store6);
|
|
@@ -53311,7 +53417,7 @@ var init_lifecycleHooks = __esm({
|
|
|
53311
53417
|
|
|
53312
53418
|
// src/cli/safety/astGate.ts
|
|
53313
53419
|
import { promises as fs23 } from "node:fs";
|
|
53314
|
-
import
|
|
53420
|
+
import path59 from "node:path";
|
|
53315
53421
|
function astGateEnabled() {
|
|
53316
53422
|
return process.env.ZELARI_AST_GATE !== "0";
|
|
53317
53423
|
}
|
|
@@ -53346,9 +53452,9 @@ function wrapWithAstGate(original, opts) {
|
|
|
53346
53452
|
const containedPathOf = (args) => {
|
|
53347
53453
|
const raw = args["path"];
|
|
53348
53454
|
if (typeof raw !== "string" || raw.length === 0) return null;
|
|
53349
|
-
const absPath =
|
|
53350
|
-
const rel2 =
|
|
53351
|
-
if (rel2.startsWith("..") ||
|
|
53455
|
+
const absPath = path59.isAbsolute(raw) ? raw : path59.join(opts.root, raw);
|
|
53456
|
+
const rel2 = path59.relative(opts.root, absPath);
|
|
53457
|
+
if (rel2.startsWith("..") || path59.isAbsolute(rel2)) return null;
|
|
53352
53458
|
return absPath;
|
|
53353
53459
|
};
|
|
53354
53460
|
return {
|
|
@@ -53373,7 +53479,7 @@ function wrapWithAstGate(original, opts) {
|
|
|
53373
53479
|
if (!result.ok) return result;
|
|
53374
53480
|
if (gateTarget !== null && !isAstSupported(gateTarget)) {
|
|
53375
53481
|
process.stderr.write(
|
|
53376
|
-
`[ast_gate] LOUD SKIP (unsupported-extension): ${original.name} ${gateTarget} \u2014 ${
|
|
53482
|
+
`[ast_gate] LOUD SKIP (unsupported-extension): ${original.name} ${gateTarget} \u2014 ${path59.extname(gateTarget) || "(no extension)"} is outside the AST surface; write KEPT, NOT syntax-gated.
|
|
53377
53483
|
`
|
|
53378
53484
|
);
|
|
53379
53485
|
return result;
|
|
@@ -53390,7 +53496,7 @@ function wrapWithAstGate(original, opts) {
|
|
|
53390
53496
|
return result;
|
|
53391
53497
|
}
|
|
53392
53498
|
const post = await fs23.readFile(absPath, "utf8");
|
|
53393
|
-
const syntaxError = firstSyntaxError(ts,
|
|
53499
|
+
const syntaxError = firstSyntaxError(ts, path59.basename(absPath), post);
|
|
53394
53500
|
if (!syntaxError) return result;
|
|
53395
53501
|
const parseError = `${syntaxError.message} (line ${syntaxError.line}, col ${syntaxError.character})`;
|
|
53396
53502
|
let revertedTo;
|
|
@@ -53401,7 +53507,7 @@ function wrapWithAstGate(original, opts) {
|
|
|
53401
53507
|
await fs23.writeFile(absPath, preContent, "utf8");
|
|
53402
53508
|
revertedTo = snapshotIdOf(preContent);
|
|
53403
53509
|
}
|
|
53404
|
-
const relLabel =
|
|
53510
|
+
const relLabel = path59.relative(opts.root, absPath) || path59.basename(absPath);
|
|
53405
53511
|
return typedErr(
|
|
53406
53512
|
`[ast_gate_reverted] ${original.name}: ${absPath} written but the file no longer parses \u2014 write REVERTED (revertedTo=${revertedTo}). ${parseError}. Fix the syntax and re-apply (read_file first for a fresh snapshotId).`,
|
|
53407
53513
|
{
|
|
@@ -53826,7 +53932,7 @@ var init_resourceClaims = __esm({
|
|
|
53826
53932
|
// src/cli/toolResultCache.ts
|
|
53827
53933
|
import { createHash as createHash15 } from "node:crypto";
|
|
53828
53934
|
import { promises as fs24 } from "node:fs";
|
|
53829
|
-
import
|
|
53935
|
+
import path60 from "node:path";
|
|
53830
53936
|
function isToolCacheEnabled() {
|
|
53831
53937
|
const raw = process.env.ZELARI_TOOL_CACHE;
|
|
53832
53938
|
return raw !== "0" && raw !== "false" && raw !== "off";
|
|
@@ -53911,7 +54017,7 @@ async function statKey(toolName, input, ctx) {
|
|
|
53911
54017
|
if (!input || typeof input !== "object") return null;
|
|
53912
54018
|
const rawPath = input.path;
|
|
53913
54019
|
if (typeof rawPath !== "string" || rawPath.length === 0) return null;
|
|
53914
|
-
const abs =
|
|
54020
|
+
const abs = path60.isAbsolute(rawPath) ? rawPath : path60.join(ctx.cwd, rawPath);
|
|
53915
54021
|
try {
|
|
53916
54022
|
const st = await fs24.stat(abs);
|
|
53917
54023
|
return hashKey({
|
|
@@ -53967,7 +54073,7 @@ __export(toolRegistry_exports, {
|
|
|
53967
54073
|
wrapWithSandbox: () => wrapWithSandbox
|
|
53968
54074
|
});
|
|
53969
54075
|
import { existsSync as existsSync32 } from "node:fs";
|
|
53970
|
-
import
|
|
54076
|
+
import path61 from "node:path";
|
|
53971
54077
|
function createBuiltinToolRegistry(options = {}) {
|
|
53972
54078
|
const root = options.root ?? process.cwd();
|
|
53973
54079
|
const audit = options.audit ?? new AuditLogger();
|
|
@@ -54192,6 +54298,15 @@ function createBuiltinToolRegistry(options = {}) {
|
|
|
54192
54298
|
permissions: browserTool.permissions ?? []
|
|
54193
54299
|
});
|
|
54194
54300
|
}
|
|
54301
|
+
if (!readOnly && !gauntletParent && process.env.ZELARI_SCREENSHOT !== "0") {
|
|
54302
|
+
const screenshotTool = createScreenshotTool();
|
|
54303
|
+
registry4.register(screenshotTool);
|
|
54304
|
+
tools.push({
|
|
54305
|
+
name: screenshotTool.name,
|
|
54306
|
+
description: screenshotTool.description,
|
|
54307
|
+
permissions: screenshotTool.permissions ?? []
|
|
54308
|
+
});
|
|
54309
|
+
}
|
|
54195
54310
|
if (!readOnly && !gauntletParent && process.env.ZELARI_SSH !== "0") {
|
|
54196
54311
|
for (const t of createSshTools()) {
|
|
54197
54312
|
registry4.register(t);
|
|
@@ -54576,14 +54691,14 @@ function wrapWithDiagnostics(original, root, runner) {
|
|
|
54576
54691
|
function claimedSourcePath(token, args, root) {
|
|
54577
54692
|
const cleaned = token.replace(/^["']|["']$/g, "");
|
|
54578
54693
|
if (!cleaned || cleaned.startsWith("-")) return null;
|
|
54579
|
-
if (!DIAG_SOURCE_EXTENSIONS.has(
|
|
54694
|
+
if (!DIAG_SOURCE_EXTENSIONS.has(path61.extname(cleaned).toLowerCase())) return null;
|
|
54580
54695
|
const bases = [root];
|
|
54581
54696
|
const cwd = args["cwd"];
|
|
54582
54697
|
if (typeof cwd === "string" && cwd.length > 0) {
|
|
54583
|
-
bases.unshift(
|
|
54698
|
+
bases.unshift(path61.isAbsolute(cwd) ? cwd : path61.resolve(root, cwd));
|
|
54584
54699
|
}
|
|
54585
54700
|
for (const base2 of bases) {
|
|
54586
|
-
const candidate =
|
|
54701
|
+
const candidate = path61.isAbsolute(cleaned) ? path61.normalize(cleaned) : path61.resolve(base2, cleaned);
|
|
54587
54702
|
try {
|
|
54588
54703
|
const contained = resolveSandboxedPath(candidate, { root });
|
|
54589
54704
|
if (existsSync32(contained)) return contained;
|
|
@@ -54853,6 +54968,7 @@ var init_toolRegistry = __esm({
|
|
|
54853
54968
|
init_tools3();
|
|
54854
54969
|
init_tools4();
|
|
54855
54970
|
init_tools5();
|
|
54971
|
+
init_screenshotTool();
|
|
54856
54972
|
init_tools6();
|
|
54857
54973
|
init_worldModel();
|
|
54858
54974
|
init_openai_compatible();
|
|
@@ -54899,7 +55015,7 @@ var init_toolRegistry = __esm({
|
|
|
54899
55015
|
|
|
54900
55016
|
// src/cli/metrics.ts
|
|
54901
55017
|
import { promises as fs25, existsSync as existsSync33, statSync as statSync4, renameSync as renameSync4, appendFileSync as appendFileSync3, mkdirSync as mkdirSync15 } from "node:fs";
|
|
54902
|
-
import
|
|
55018
|
+
import path62 from "node:path";
|
|
54903
55019
|
async function readMetrics(file2) {
|
|
54904
55020
|
let raw = "";
|
|
54905
55021
|
try {
|
|
@@ -54949,7 +55065,7 @@ var init_metrics3 = __esm({
|
|
|
54949
55065
|
writeQueue = Promise.resolve();
|
|
54950
55066
|
constructor(file2) {
|
|
54951
55067
|
this.file = file2 ?? metricsPath();
|
|
54952
|
-
mkdirSync15(
|
|
55068
|
+
mkdirSync15(path62.dirname(this.file), { recursive: true });
|
|
54953
55069
|
}
|
|
54954
55070
|
/** Metrics file path — doctor/summary readers use this. */
|
|
54955
55071
|
get filePath() {
|
|
@@ -54986,8 +55102,8 @@ var init_metrics3 = __esm({
|
|
|
54986
55102
|
maybeRotate() {
|
|
54987
55103
|
if (!existsSync33(this.file)) return;
|
|
54988
55104
|
try {
|
|
54989
|
-
const
|
|
54990
|
-
if (
|
|
55105
|
+
const stat8 = statSync4(this.file);
|
|
55106
|
+
if (stat8.size >= METRICS_ROTATE_BYTES) {
|
|
54991
55107
|
const rotated = this.file.replace(/\.jsonl$/, ".1.jsonl");
|
|
54992
55108
|
renameSync4(this.file, rotated);
|
|
54993
55109
|
}
|
|
@@ -55281,15 +55397,15 @@ __export(completionProofProbe_exports, {
|
|
|
55281
55397
|
gatherGitAttestation: () => gatherGitAttestation,
|
|
55282
55398
|
harnessManifest: () => harnessManifest
|
|
55283
55399
|
});
|
|
55284
|
-
import { execFile as
|
|
55285
|
-
import { promisify as
|
|
55400
|
+
import { execFile as execFile6 } from "node:child_process";
|
|
55401
|
+
import { promisify as promisify5 } from "node:util";
|
|
55286
55402
|
async function readHarnessVersion() {
|
|
55287
55403
|
if (cachedHarnessVersion !== null) return cachedHarnessVersion;
|
|
55288
55404
|
try {
|
|
55289
|
-
const { readFile:
|
|
55405
|
+
const { readFile: readFile11 } = await import("node:fs/promises");
|
|
55290
55406
|
const { fileURLToPath: fileURLToPath4 } = await import("node:url");
|
|
55291
55407
|
const pkgPath = fileURLToPath4(new URL("../../../package.json", import.meta.url));
|
|
55292
|
-
const parsed = JSON.parse(await
|
|
55408
|
+
const parsed = JSON.parse(await readFile11(pkgPath, "utf8"));
|
|
55293
55409
|
if (typeof parsed.version === "string" && parsed.version.length > 0) {
|
|
55294
55410
|
return cachedHarnessVersion = parsed.version;
|
|
55295
55411
|
}
|
|
@@ -55313,7 +55429,7 @@ async function harnessManifest(env = process.env) {
|
|
|
55313
55429
|
}
|
|
55314
55430
|
async function git5(cwd, args) {
|
|
55315
55431
|
try {
|
|
55316
|
-
const { stdout } = await
|
|
55432
|
+
const { stdout } = await execFileAsync5("git", ["-C", cwd, ...args], {
|
|
55317
55433
|
maxBuffer: 32 * 1024 * 1024,
|
|
55318
55434
|
windowsHide: true
|
|
55319
55435
|
});
|
|
@@ -55355,7 +55471,7 @@ function activeTaskContractSnapshot() {
|
|
|
55355
55471
|
return void 0;
|
|
55356
55472
|
}
|
|
55357
55473
|
}
|
|
55358
|
-
var HARNESS_VERSION_FALLBACK, ADAPTER_IDS, cachedHarnessVersion,
|
|
55474
|
+
var HARNESS_VERSION_FALLBACK, ADAPTER_IDS, cachedHarnessVersion, execFileAsync5;
|
|
55359
55475
|
var init_completionProofProbe = __esm({
|
|
55360
55476
|
"src/cli/kraken/completionProofProbe.ts"() {
|
|
55361
55477
|
"use strict";
|
|
@@ -55363,7 +55479,7 @@ var init_completionProofProbe = __esm({
|
|
|
55363
55479
|
HARNESS_VERSION_FALLBACK = "2.13.0";
|
|
55364
55480
|
ADAPTER_IDS = ["node", "python", "rust", "go", "java", "dotnet"];
|
|
55365
55481
|
cachedHarnessVersion = null;
|
|
55366
|
-
|
|
55482
|
+
execFileAsync5 = promisify5(execFile6);
|
|
55367
55483
|
}
|
|
55368
55484
|
});
|
|
55369
55485
|
|
|
@@ -55467,7 +55583,7 @@ var init_completionProofAttestation = __esm({
|
|
|
55467
55583
|
// src/cli/kraken/completionProofPersist.ts
|
|
55468
55584
|
import { open, rename as rename2, rm as rm2 } from "node:fs/promises";
|
|
55469
55585
|
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
55470
|
-
import
|
|
55586
|
+
import path63 from "node:path";
|
|
55471
55587
|
function isTruthyFlag2(v) {
|
|
55472
55588
|
const n = v?.trim().toLowerCase();
|
|
55473
55589
|
return n === "1" || n === "true" || n === "yes" || n === "on";
|
|
@@ -55509,8 +55625,8 @@ function isWindowsRenameBlock(err) {
|
|
|
55509
55625
|
return code === "EPERM" || code === "ENOTEMPTY" || code === "EEXIST";
|
|
55510
55626
|
}
|
|
55511
55627
|
async function writeFileAtomic(target, data) {
|
|
55512
|
-
const dir =
|
|
55513
|
-
const tmp =
|
|
55628
|
+
const dir = path63.dirname(target);
|
|
55629
|
+
const tmp = path63.join(dir, `.${path63.basename(target)}.${randomBytes5(6).toString("hex")}.tmp`);
|
|
55514
55630
|
let fh = null;
|
|
55515
55631
|
try {
|
|
55516
55632
|
fh = await open(tmp, "w");
|
|
@@ -55555,8 +55671,8 @@ var init_completionProofPersist = __esm({
|
|
|
55555
55671
|
});
|
|
55556
55672
|
|
|
55557
55673
|
// src/cli/kraken/completionProof.ts
|
|
55558
|
-
import { mkdir as
|
|
55559
|
-
import
|
|
55674
|
+
import { mkdir as mkdir4 } from "node:fs/promises";
|
|
55675
|
+
import path64 from "node:path";
|
|
55560
55676
|
function verdictOf(evaluation) {
|
|
55561
55677
|
return evaluation.evaluation?.verdict ?? (evaluation.blocked ? "BLOCKED" : "PASS");
|
|
55562
55678
|
}
|
|
@@ -55701,8 +55817,8 @@ async function writeCompletionProofDetailed(evaluation, options = {}) {
|
|
|
55701
55817
|
const mode = options.persistenceMode ?? activeProofPersistenceMode();
|
|
55702
55818
|
try {
|
|
55703
55819
|
const baseDir = options.baseDir ?? process.cwd();
|
|
55704
|
-
const dir =
|
|
55705
|
-
await
|
|
55820
|
+
const dir = path64.join(baseDir, ".zelari");
|
|
55821
|
+
await mkdir4(dir, { recursive: true });
|
|
55706
55822
|
const requested = options.attestation ?? {};
|
|
55707
55823
|
const plan = requested.skipProbes || requested.verificationPlan !== void 0 ? void 0 : await defaultVerificationPlanSnapshot(baseDir);
|
|
55708
55824
|
const wrapper = await buildAttestedWrapper(
|
|
@@ -55721,8 +55837,8 @@ async function writeCompletionProofDetailed(evaluation, options = {}) {
|
|
|
55721
55837
|
baseDir
|
|
55722
55838
|
);
|
|
55723
55839
|
const rendered = renderCompletionProof(evaluation, options.meta ?? {}, wrapper.attestation);
|
|
55724
|
-
const markdownPath =
|
|
55725
|
-
const jsonPath =
|
|
55840
|
+
const markdownPath = path64.join(dir, "completion-proof.md");
|
|
55841
|
+
const jsonPath = path64.join(dir, "completion-proof.json");
|
|
55726
55842
|
await writeFileAtomic(markdownPath, rendered.markdown);
|
|
55727
55843
|
await writeFileAtomic(jsonPath, rendered.json);
|
|
55728
55844
|
return { paths: { markdownPath, jsonPath }, mode, requiredBlockReason: null };
|
|
@@ -55832,12 +55948,12 @@ var init_askUserTimeout = __esm({
|
|
|
55832
55948
|
// src/cli/state/fileStateStore.ts
|
|
55833
55949
|
import { createHash as createHash17, randomUUID as randomUUID5 } from "node:crypto";
|
|
55834
55950
|
import { promises as fs26 } from "node:fs";
|
|
55835
|
-
import * as
|
|
55951
|
+
import * as path65 from "node:path";
|
|
55836
55952
|
function shortId() {
|
|
55837
55953
|
return randomUUID5().replace(/-/g, "").slice(0, 12);
|
|
55838
55954
|
}
|
|
55839
55955
|
async function writeJsonAtomic(filePath, data) {
|
|
55840
|
-
await fs26.mkdir(
|
|
55956
|
+
await fs26.mkdir(path65.dirname(filePath), { recursive: true });
|
|
55841
55957
|
const tmp = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
55842
55958
|
await fs26.writeFile(tmp, JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
55843
55959
|
await fs26.rename(tmp, filePath);
|
|
@@ -55898,11 +56014,11 @@ var init_fileStateStore = __esm({
|
|
|
55898
56014
|
indexPath = "";
|
|
55899
56015
|
async init(projectRoot) {
|
|
55900
56016
|
this.root = projectRoot;
|
|
55901
|
-
this.stateDir =
|
|
55902
|
-
this.commitsDir =
|
|
55903
|
-
this.artifactsDir =
|
|
55904
|
-
this.headPath =
|
|
55905
|
-
this.indexPath =
|
|
56017
|
+
this.stateDir = path65.join(projectRoot, ".zelari", "state");
|
|
56018
|
+
this.commitsDir = path65.join(this.stateDir, "commits");
|
|
56019
|
+
this.artifactsDir = path65.join(this.stateDir, "artifacts");
|
|
56020
|
+
this.headPath = path65.join(this.stateDir, "HEAD.json");
|
|
56021
|
+
this.indexPath = path65.join(this.stateDir, "index.jsonl");
|
|
55906
56022
|
await fs26.mkdir(this.commitsDir, { recursive: true });
|
|
55907
56023
|
await fs26.mkdir(this.artifactsDir, { recursive: true });
|
|
55908
56024
|
}
|
|
@@ -55915,13 +56031,13 @@ var init_fileStateStore = __esm({
|
|
|
55915
56031
|
const discoveries = input.discoveries ?? [];
|
|
55916
56032
|
const parent = await this.head();
|
|
55917
56033
|
const id3 = shortId();
|
|
55918
|
-
const artifactRel =
|
|
55919
|
-
const artifactAbs =
|
|
56034
|
+
const artifactRel = path65.join("artifacts", id3);
|
|
56035
|
+
const artifactAbs = path65.join(this.artifactsDir, id3);
|
|
55920
56036
|
await fs26.mkdir(artifactAbs, { recursive: true });
|
|
55921
56037
|
const summary = defaultSummary(input, discoveries);
|
|
55922
|
-
await fs26.writeFile(
|
|
55923
|
-
await writeJsonAtomic(
|
|
55924
|
-
await writeJsonAtomic(
|
|
56038
|
+
await fs26.writeFile(path65.join(artifactAbs, "summary.md"), summary + "\n", "utf8");
|
|
56039
|
+
await writeJsonAtomic(path65.join(artifactAbs, "discoveries.json"), discoveries);
|
|
56040
|
+
await writeJsonAtomic(path65.join(artifactAbs, "verification.json"), input.verification);
|
|
55925
56041
|
const meta3 = {
|
|
55926
56042
|
id: id3,
|
|
55927
56043
|
parentId: parent?.id ?? null,
|
|
@@ -55933,14 +56049,14 @@ var init_fileStateStore = __esm({
|
|
|
55933
56049
|
workspaceCheckpointId: input.workspaceCheckpointId,
|
|
55934
56050
|
verification: {
|
|
55935
56051
|
...input.verification,
|
|
55936
|
-
reportPath: input.verification.reportPath ??
|
|
56052
|
+
reportPath: input.verification.reportPath ?? path65.join(".zelari", "state", artifactRel, "verification.json").replace(/\\/g, "/")
|
|
55937
56053
|
},
|
|
55938
56054
|
changedPaths: input.changedPaths ?? [],
|
|
55939
56055
|
stablePromptHash: input.stablePromptHash,
|
|
55940
56056
|
discoveryCount: discoveries.length,
|
|
55941
56057
|
artifactDir: artifactRel.replace(/\\/g, "/")
|
|
55942
56058
|
};
|
|
55943
|
-
await writeJsonAtomic(
|
|
56059
|
+
await writeJsonAtomic(path65.join(this.commitsDir, `${id3}.json`), meta3);
|
|
55944
56060
|
await writeJsonAtomic(this.headPath, { id: id3, updatedAt: meta3.createdAt });
|
|
55945
56061
|
await fs26.appendFile(this.indexPath, JSON.stringify({ id: id3, createdAt: meta3.createdAt, label: meta3.label }) + "\n", "utf8");
|
|
55946
56062
|
return stripStored(meta3);
|
|
@@ -55951,7 +56067,7 @@ var init_fileStateStore = __esm({
|
|
|
55951
56067
|
return this.get(head.id);
|
|
55952
56068
|
}
|
|
55953
56069
|
async get(id3) {
|
|
55954
|
-
const stored = await readJsonFile(
|
|
56070
|
+
const stored = await readJsonFile(path65.join(this.commitsDir, `${id3}.json`));
|
|
55955
56071
|
return stored ? stripStored(stored) : null;
|
|
55956
56072
|
}
|
|
55957
56073
|
async list(limit = 20) {
|
|
@@ -55990,9 +56106,9 @@ var init_fileStateStore = __esm({
|
|
|
55990
56106
|
async loadDiscoveries(id3) {
|
|
55991
56107
|
const meta3 = id3 ? await this.get(id3) : await this.head();
|
|
55992
56108
|
if (!meta3) return [];
|
|
55993
|
-
const stored = await readJsonFile(
|
|
56109
|
+
const stored = await readJsonFile(path65.join(this.commitsDir, `${meta3.id}.json`));
|
|
55994
56110
|
if (!stored?.artifactDir) return [];
|
|
55995
|
-
const discPath =
|
|
56111
|
+
const discPath = path65.join(this.stateDir, stored.artifactDir, "discoveries.json");
|
|
55996
56112
|
return await readJsonFile(discPath) ?? [];
|
|
55997
56113
|
}
|
|
55998
56114
|
async materializeContext(id3, maxChars = DEFAULT_MATERIALIZE_CHARS) {
|
|
@@ -56595,10 +56711,10 @@ var init_mode = __esm({
|
|
|
56595
56711
|
|
|
56596
56712
|
// src/cli/headless.ts
|
|
56597
56713
|
import { readFileSync as readFileSync24 } from "node:fs";
|
|
56598
|
-
import
|
|
56714
|
+
import path66 from "node:path";
|
|
56599
56715
|
function resolveHeadlessCwd(opts) {
|
|
56600
56716
|
const raw = typeof opts.cwd === "string" ? opts.cwd.trim() : "";
|
|
56601
|
-
return
|
|
56717
|
+
return path66.resolve(raw.length > 0 ? raw : process.cwd());
|
|
56602
56718
|
}
|
|
56603
56719
|
function defaultProfileForMode(mode) {
|
|
56604
56720
|
switch (mode) {
|
|
@@ -57700,7 +57816,7 @@ var init_planDetect = __esm({
|
|
|
57700
57816
|
// src/cli/memory/legacyImport.ts
|
|
57701
57817
|
import { createHash as createHash18 } from "node:crypto";
|
|
57702
57818
|
import { promises as fs27 } from "node:fs";
|
|
57703
|
-
import * as
|
|
57819
|
+
import * as path67 from "node:path";
|
|
57704
57820
|
function sourceId(fact, line) {
|
|
57705
57821
|
return `jsonl:${fact.id ?? createHash18("sha256").update(line).digest("hex")}`;
|
|
57706
57822
|
}
|
|
@@ -57718,7 +57834,7 @@ function timestamp(value) {
|
|
|
57718
57834
|
}
|
|
57719
57835
|
async function importLegacyMemoryLog(backend, service) {
|
|
57720
57836
|
const result = { found: 0, imported: 0, skipped: 0, corrupt: 0 };
|
|
57721
|
-
const logPath =
|
|
57837
|
+
const logPath = path67.join(path67.dirname(backend.databasePath), "log.jsonl");
|
|
57722
57838
|
let raw;
|
|
57723
57839
|
try {
|
|
57724
57840
|
raw = await fs27.readFile(logPath, "utf8");
|
|
@@ -57901,7 +58017,7 @@ var init_sqliteCodec = __esm({
|
|
|
57901
58017
|
// src/cli/memory/sqliteRpc.ts
|
|
57902
58018
|
import { existsSync as existsSync36 } from "node:fs";
|
|
57903
58019
|
import { fileURLToPath as fileURLToPath2, pathToFileURL as pathToFileURL2 } from "node:url";
|
|
57904
|
-
import * as
|
|
58020
|
+
import * as path68 from "node:path";
|
|
57905
58021
|
import { Worker } from "node:worker_threads";
|
|
57906
58022
|
function isBusy(error51) {
|
|
57907
58023
|
const candidate = error51;
|
|
@@ -57910,10 +58026,10 @@ function isBusy(error51) {
|
|
|
57910
58026
|
);
|
|
57911
58027
|
}
|
|
57912
58028
|
function resolveWorkerUrl() {
|
|
57913
|
-
const here =
|
|
57914
|
-
const direct =
|
|
58029
|
+
const here = path68.dirname(fileURLToPath2(import.meta.url));
|
|
58030
|
+
const direct = path68.join(here, "sqliteWorker.mjs");
|
|
57915
58031
|
if (existsSync36(direct)) return pathToFileURL2(direct);
|
|
57916
|
-
return pathToFileURL2(
|
|
58032
|
+
return pathToFileURL2(path68.join(here, "memory", "sqliteWorker.mjs"));
|
|
57917
58033
|
}
|
|
57918
58034
|
var SqliteWorkerRpc;
|
|
57919
58035
|
var init_sqliteRpc = __esm({
|
|
@@ -58202,7 +58318,7 @@ WHERE NOT EXISTS (SELECT 1 FROM memory_fts f WHERE f.node_id = n.id);
|
|
|
58202
58318
|
// src/cli/memory/sqliteBackend.ts
|
|
58203
58319
|
import { createHash as createHash19, randomUUID as randomUUID6 } from "node:crypto";
|
|
58204
58320
|
import { promises as fs28 } from "node:fs";
|
|
58205
|
-
import * as
|
|
58321
|
+
import * as path69 from "node:path";
|
|
58206
58322
|
function boundedLimit(value, fallback = 50) {
|
|
58207
58323
|
return Math.max(1, Math.min(Math.floor(value ?? fallback), 1e5));
|
|
58208
58324
|
}
|
|
@@ -58264,20 +58380,20 @@ VALUES (${Array.from({ length: 19 }, () => "?").join(",")})`;
|
|
|
58264
58380
|
try {
|
|
58265
58381
|
resolved = await fs28.realpath(projectRoot);
|
|
58266
58382
|
} catch {
|
|
58267
|
-
resolved =
|
|
58383
|
+
resolved = path69.resolve(projectRoot);
|
|
58268
58384
|
}
|
|
58269
58385
|
if (this.initialized && resolved === this.projectRoot) return;
|
|
58270
58386
|
if (this.initialized) await this.close();
|
|
58271
58387
|
const filename = this.options.filename ?? "memory.db";
|
|
58272
|
-
if (
|
|
58388
|
+
if (path69.basename(filename) !== filename || filename === "." || filename === "..") {
|
|
58273
58389
|
throw new Error("SQLite memory filename must not contain a path.");
|
|
58274
58390
|
}
|
|
58275
|
-
const zelariDirectory =
|
|
58276
|
-
const directory =
|
|
58391
|
+
const zelariDirectory = path69.join(resolved, ".zelari");
|
|
58392
|
+
const directory = path69.join(zelariDirectory, "memory");
|
|
58277
58393
|
for (const candidate of [zelariDirectory, directory]) {
|
|
58278
|
-
let
|
|
58394
|
+
let stat8;
|
|
58279
58395
|
try {
|
|
58280
|
-
|
|
58396
|
+
stat8 = await fs28.lstat(candidate);
|
|
58281
58397
|
} catch (error51) {
|
|
58282
58398
|
if (error51.code !== "ENOENT") throw error51;
|
|
58283
58399
|
try {
|
|
@@ -58285,19 +58401,19 @@ VALUES (${Array.from({ length: 19 }, () => "?").join(",")})`;
|
|
|
58285
58401
|
} catch (mkdirError) {
|
|
58286
58402
|
if (mkdirError.code !== "EEXIST") throw mkdirError;
|
|
58287
58403
|
}
|
|
58288
|
-
|
|
58404
|
+
stat8 = await fs28.lstat(candidate);
|
|
58289
58405
|
}
|
|
58290
|
-
if (
|
|
58406
|
+
if (stat8.isSymbolicLink() || !stat8.isDirectory()) {
|
|
58291
58407
|
throw new Error(`Memory directory is not a real directory: ${candidate}`);
|
|
58292
58408
|
}
|
|
58293
58409
|
}
|
|
58294
58410
|
const canonicalDirectory = await fs28.realpath(directory);
|
|
58295
|
-
const relativeDirectory =
|
|
58296
|
-
if (relativeDirectory.startsWith("..") ||
|
|
58411
|
+
const relativeDirectory = path69.relative(resolved, canonicalDirectory);
|
|
58412
|
+
if (relativeDirectory.startsWith("..") || path69.isAbsolute(relativeDirectory)) {
|
|
58297
58413
|
throw new Error("SQLite memory directory resolves outside the active project.");
|
|
58298
58414
|
}
|
|
58299
58415
|
this.projectRoot = resolved;
|
|
58300
|
-
this.databasePath =
|
|
58416
|
+
this.databasePath = path69.join(canonicalDirectory, filename);
|
|
58301
58417
|
const opened = await this.rpc.open({
|
|
58302
58418
|
dbPath: this.databasePath,
|
|
58303
58419
|
schemaSql: SQLITE_MEMORY_BASE_SCHEMA,
|
|
@@ -58830,7 +58946,7 @@ __export(serviceFactory_exports, {
|
|
|
58830
58946
|
});
|
|
58831
58947
|
import { createHash as createHash20 } from "node:crypto";
|
|
58832
58948
|
import { promises as fs29 } from "node:fs";
|
|
58833
|
-
import * as
|
|
58949
|
+
import * as path70 from "node:path";
|
|
58834
58950
|
function isMemoryV2Enabled(env = process.env) {
|
|
58835
58951
|
if (env.ZELARI_MEMORY === "0") return false;
|
|
58836
58952
|
if (env.ZELARI_MEMORY_BACKEND === "file" || env.ZELARI_MEMORY_BACKEND === "jsonl") return false;
|
|
@@ -58851,7 +58967,7 @@ async function canonicalProjectId(projectRoot) {
|
|
|
58851
58967
|
try {
|
|
58852
58968
|
canonical = await fs29.realpath(projectRoot);
|
|
58853
58969
|
} catch {
|
|
58854
|
-
canonical =
|
|
58970
|
+
canonical = path70.resolve(projectRoot);
|
|
58855
58971
|
}
|
|
58856
58972
|
canonical = canonical.replace(/\\/g, "/").replace(/\/$/, "");
|
|
58857
58973
|
if (process.platform === "win32") canonical = canonical.toLocaleLowerCase("en-US");
|
|
@@ -59553,8 +59669,8 @@ function readPlan(ctx) {
|
|
|
59553
59669
|
} catch {
|
|
59554
59670
|
}
|
|
59555
59671
|
}
|
|
59556
|
-
const
|
|
59557
|
-
const doc = ctx.storage.readIfExists(
|
|
59672
|
+
const path100 = workspaceFile(ctx.rootDir, "plan");
|
|
59673
|
+
const doc = ctx.storage.readIfExists(path100);
|
|
59558
59674
|
if (!doc) return { phases: [], tasks: [], milestones: [] };
|
|
59559
59675
|
const meta3 = doc.meta;
|
|
59560
59676
|
return {
|
|
@@ -59735,7 +59851,7 @@ function addMilestoneRecord(ctx, summary, input) {
|
|
|
59735
59851
|
dueDate: input.dueDate,
|
|
59736
59852
|
targetVersion: version2
|
|
59737
59853
|
});
|
|
59738
|
-
const
|
|
59854
|
+
const path100 = join31(ctx.rootDir, "milestones", `${id3}.md`);
|
|
59739
59855
|
const meta3 = {
|
|
59740
59856
|
kind: "milestone",
|
|
59741
59857
|
id: id3,
|
|
@@ -59752,7 +59868,7 @@ function addMilestoneRecord(ctx, summary, input) {
|
|
|
59752
59868
|
`Target version: ${version2}`,
|
|
59753
59869
|
""
|
|
59754
59870
|
].join("\n");
|
|
59755
|
-
ctx.storage.write(
|
|
59871
|
+
ctx.storage.write(path100, meta3, body);
|
|
59756
59872
|
return { id: id3, created: true };
|
|
59757
59873
|
}
|
|
59758
59874
|
function readPlanSummary(ctx) {
|
|
@@ -59956,7 +60072,7 @@ function addIdeaStub(ctx) {
|
|
|
59956
60072
|
const tags = args["tags"] ?? [];
|
|
59957
60073
|
const category = args["category"] ?? "General";
|
|
59958
60074
|
const id3 = `${nextAdrId(ctx)}-${slugify3(title)}`;
|
|
59959
|
-
const
|
|
60075
|
+
const path100 = workspaceArtifact(ctx.rootDir, "decisions", id3);
|
|
59960
60076
|
const meta3 = {
|
|
59961
60077
|
kind: "adr",
|
|
59962
60078
|
status: "proposed",
|
|
@@ -59982,7 +60098,7 @@ function addIdeaStub(ctx) {
|
|
|
59982
60098
|
...consequences.map((c) => `- ${c}`),
|
|
59983
60099
|
""
|
|
59984
60100
|
].join("\n");
|
|
59985
|
-
ctx.storage.write(
|
|
60101
|
+
ctx.storage.write(path100, meta3, body);
|
|
59986
60102
|
return `ADR ${id3} created: "${title}". Status: proposed. Promote to accepted via /update ADR or manual edit.`;
|
|
59987
60103
|
});
|
|
59988
60104
|
}
|
|
@@ -60064,14 +60180,14 @@ function createDocumentStub(ctx) {
|
|
|
60064
60180
|
ctx.storage.write(risksPath, riskMeta, content);
|
|
60065
60181
|
return `Document "${title}" created at risks.md (workspace root).`;
|
|
60066
60182
|
}
|
|
60067
|
-
const
|
|
60183
|
+
const path100 = workspaceArtifact(ctx.rootDir, "docs", slug);
|
|
60068
60184
|
const meta3 = {
|
|
60069
60185
|
kind: "doc",
|
|
60070
60186
|
id: slug,
|
|
60071
60187
|
date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
|
|
60072
60188
|
tags
|
|
60073
60189
|
};
|
|
60074
|
-
ctx.storage.write(
|
|
60190
|
+
ctx.storage.write(path100, meta3, content);
|
|
60075
60191
|
return `Document "${title}" created at docs/${slug}.md.`;
|
|
60076
60192
|
});
|
|
60077
60193
|
}
|
|
@@ -60696,10 +60812,10 @@ function getUserMcpPath() {
|
|
|
60696
60812
|
function getProjectMcpPath(projectRoot) {
|
|
60697
60813
|
return join32(projectRoot, ".zelari", "mcp.json");
|
|
60698
60814
|
}
|
|
60699
|
-
function
|
|
60700
|
-
if (!existsSync42(
|
|
60815
|
+
function readFile9(path100) {
|
|
60816
|
+
if (!existsSync42(path100)) return {};
|
|
60701
60817
|
try {
|
|
60702
|
-
const parsed = JSON.parse(readFileSync30(
|
|
60818
|
+
const parsed = JSON.parse(readFileSync30(path100, "utf8"));
|
|
60703
60819
|
const out = {};
|
|
60704
60820
|
for (const [name, cfg] of Object.entries(parsed.mcpServers ?? {})) {
|
|
60705
60821
|
const hasCommand = !!cfg && typeof cfg.command === "string" && !!cfg.command.trim();
|
|
@@ -60721,17 +60837,17 @@ function readFile7(path99) {
|
|
|
60721
60837
|
return {};
|
|
60722
60838
|
}
|
|
60723
60839
|
}
|
|
60724
|
-
function writeFile3(
|
|
60725
|
-
mkdirSync17(dirname9(
|
|
60840
|
+
function writeFile3(path100, servers) {
|
|
60841
|
+
mkdirSync17(dirname9(path100), { recursive: true });
|
|
60726
60842
|
const body = { mcpServers: servers };
|
|
60727
|
-
writeFileSync19(
|
|
60843
|
+
writeFileSync19(path100, `${JSON.stringify(body, null, 2)}
|
|
60728
60844
|
`, "utf8");
|
|
60729
60845
|
}
|
|
60730
60846
|
function listMcpServers(projectRoot) {
|
|
60731
60847
|
const userPath = getUserMcpPath();
|
|
60732
|
-
const userServers =
|
|
60848
|
+
const userServers = readFile9(userPath);
|
|
60733
60849
|
const projectPath = projectRoot && projectRoot.trim() ? getProjectMcpPath(projectRoot.trim()) : null;
|
|
60734
|
-
const projectServers = projectPath ?
|
|
60850
|
+
const projectServers = projectPath ? readFile9(projectPath) : {};
|
|
60735
60851
|
const servers = [];
|
|
60736
60852
|
for (const [name, cfg] of Object.entries(userServers)) {
|
|
60737
60853
|
servers.push({ name, ...cfg, scope: "user", path: userPath });
|
|
@@ -60762,9 +60878,9 @@ function upsertMcpServer(opts) {
|
|
|
60762
60878
|
error: "either command (stdio) or url (http) is required"
|
|
60763
60879
|
};
|
|
60764
60880
|
}
|
|
60765
|
-
let
|
|
60881
|
+
let path100;
|
|
60766
60882
|
if (opts.scope === "user") {
|
|
60767
|
-
|
|
60883
|
+
path100 = getUserMcpPath();
|
|
60768
60884
|
} else {
|
|
60769
60885
|
const root = opts.projectRoot?.trim();
|
|
60770
60886
|
if (!root) {
|
|
@@ -60773,9 +60889,9 @@ function upsertMcpServer(opts) {
|
|
|
60773
60889
|
error: "projectRoot required for project scope (Open Folder first)"
|
|
60774
60890
|
};
|
|
60775
60891
|
}
|
|
60776
|
-
|
|
60892
|
+
path100 = getProjectMcpPath(root);
|
|
60777
60893
|
}
|
|
60778
|
-
const current =
|
|
60894
|
+
const current = readFile9(path100);
|
|
60779
60895
|
current[name] = {
|
|
60780
60896
|
command: hasCommand ? opts.config.command.trim() : void 0,
|
|
60781
60897
|
args: opts.config.args,
|
|
@@ -60786,21 +60902,21 @@ function upsertMcpServer(opts) {
|
|
|
60786
60902
|
serial: opts.config.serial,
|
|
60787
60903
|
enabled: opts.config.enabled !== false
|
|
60788
60904
|
};
|
|
60789
|
-
writeFile3(
|
|
60790
|
-
return { ok: true, path:
|
|
60905
|
+
writeFile3(path100, current);
|
|
60906
|
+
return { ok: true, path: path100 };
|
|
60791
60907
|
}
|
|
60792
60908
|
function removeMcpServer(opts) {
|
|
60793
|
-
const
|
|
60794
|
-
if (!
|
|
60909
|
+
const path100 = opts.scope === "user" ? getUserMcpPath() : opts.projectRoot ? getProjectMcpPath(opts.projectRoot) : null;
|
|
60910
|
+
if (!path100) {
|
|
60795
60911
|
return { ok: false, error: "projectRoot required for project scope" };
|
|
60796
60912
|
}
|
|
60797
|
-
const current =
|
|
60913
|
+
const current = readFile9(path100);
|
|
60798
60914
|
if (!(opts.name in current)) {
|
|
60799
|
-
return { ok: false, error: `Server "${opts.name}" not found in ${
|
|
60915
|
+
return { ok: false, error: `Server "${opts.name}" not found in ${path100}` };
|
|
60800
60916
|
}
|
|
60801
60917
|
delete current[opts.name];
|
|
60802
|
-
writeFile3(
|
|
60803
|
-
return { ok: true, path:
|
|
60918
|
+
writeFile3(path100, current);
|
|
60919
|
+
return { ok: true, path: path100 };
|
|
60804
60920
|
}
|
|
60805
60921
|
var init_mcpConfigIo = __esm({
|
|
60806
60922
|
"src/cli/mcp/mcpConfigIo.ts"() {
|
|
@@ -61269,12 +61385,12 @@ __export(agentsMd_exports, {
|
|
|
61269
61385
|
import { existsSync as existsSync44, readFileSync as readFileSync32, writeFileSync as writeFileSync20 } from "node:fs";
|
|
61270
61386
|
import { createHash as createHash21 } from "node:crypto";
|
|
61271
61387
|
import { join as join34 } from "node:path";
|
|
61272
|
-
import { readFile as
|
|
61388
|
+
import { readFile as readFile10 } from "node:fs/promises";
|
|
61273
61389
|
async function readPackageJson3(projectRoot) {
|
|
61274
|
-
const
|
|
61275
|
-
if (!existsSync44(
|
|
61390
|
+
const path100 = join34(projectRoot, "package.json");
|
|
61391
|
+
if (!existsSync44(path100)) return null;
|
|
61276
61392
|
try {
|
|
61277
|
-
return JSON.parse(await
|
|
61393
|
+
return JSON.parse(await readFile10(path100, "utf8"));
|
|
61278
61394
|
} catch {
|
|
61279
61395
|
return null;
|
|
61280
61396
|
}
|
|
@@ -61356,9 +61472,9 @@ async function genBuild(ctx) {
|
|
|
61356
61472
|
].join("\n");
|
|
61357
61473
|
}
|
|
61358
61474
|
async function genOpenQuestions(ctx) {
|
|
61359
|
-
const
|
|
61360
|
-
if (!existsSync44(
|
|
61361
|
-
const content = readFileSync32(
|
|
61475
|
+
const path100 = join34(ctx.rootDir, "risks.md");
|
|
61476
|
+
if (!existsSync44(path100)) return "_No open questions._";
|
|
61477
|
+
const content = readFileSync32(path100, "utf8");
|
|
61362
61478
|
const lines = content.split("\n");
|
|
61363
61479
|
const questions = [];
|
|
61364
61480
|
let currentTitle = "";
|
|
@@ -61632,9 +61748,9 @@ function versionKey(value) {
|
|
|
61632
61748
|
function firstString2(v) {
|
|
61633
61749
|
return typeof v === "string" && v.trim().length > 0 ? v : null;
|
|
61634
61750
|
}
|
|
61635
|
-
function readFileSyncSafe(
|
|
61751
|
+
function readFileSyncSafe(path100) {
|
|
61636
61752
|
try {
|
|
61637
|
-
return readFileSync33(
|
|
61753
|
+
return readFileSync33(path100, "utf8");
|
|
61638
61754
|
} catch {
|
|
61639
61755
|
return null;
|
|
61640
61756
|
}
|
|
@@ -61882,7 +61998,7 @@ __export(evidenceFromSpine_exports, {
|
|
|
61882
61998
|
evidenceRefsFromEventLines: () => evidenceRefsFromEventLines
|
|
61883
61999
|
});
|
|
61884
62000
|
import { existsSync as existsSync47, readFileSync as readFileSync35 } from "node:fs";
|
|
61885
|
-
import
|
|
62001
|
+
import path71 from "node:path";
|
|
61886
62002
|
function asRecord2(v) {
|
|
61887
62003
|
return v && typeof v === "object" && !Array.isArray(v) ? v : void 0;
|
|
61888
62004
|
}
|
|
@@ -61920,7 +62036,7 @@ function evidenceRefsFromEventLines(lines) {
|
|
|
61920
62036
|
}
|
|
61921
62037
|
function collectSessionEvidenceRefs(sessionId2) {
|
|
61922
62038
|
try {
|
|
61923
|
-
const file2 =
|
|
62039
|
+
const file2 = path71.join(sessionsDir(), sessionId2, "events.jsonl");
|
|
61924
62040
|
if (!existsSync47(file2)) return [];
|
|
61925
62041
|
return evidenceRefsFromEventLines(readFileSync35(file2, "utf8").split("\n"));
|
|
61926
62042
|
} catch {
|
|
@@ -62170,8 +62286,8 @@ async function runPostCouncilHook(ctx, options) {
|
|
|
62170
62286
|
sources: scope.sources
|
|
62171
62287
|
} : void 0
|
|
62172
62288
|
});
|
|
62173
|
-
const
|
|
62174
|
-
completionHook = { ran: true, path:
|
|
62289
|
+
const path100 = writeCouncilCompletion(ctx.rootDir, completion);
|
|
62290
|
+
completionHook = { ran: true, path: path100, completion };
|
|
62175
62291
|
} catch (err) {
|
|
62176
62292
|
completionHook = {
|
|
62177
62293
|
ran: true,
|
|
@@ -62216,7 +62332,7 @@ import {
|
|
|
62216
62332
|
writeFileSync as writeFileSync22,
|
|
62217
62333
|
mkdirSync as mkdirSync18
|
|
62218
62334
|
} from "node:fs";
|
|
62219
|
-
import
|
|
62335
|
+
import path72 from "node:path";
|
|
62220
62336
|
var FeedbackStore;
|
|
62221
62337
|
var init_councilFeedback = __esm({
|
|
62222
62338
|
"src/cli/councilFeedback.ts"() {
|
|
@@ -62333,7 +62449,7 @@ var init_councilFeedback = __esm({
|
|
|
62333
62449
|
}
|
|
62334
62450
|
}
|
|
62335
62451
|
save() {
|
|
62336
|
-
mkdirSync18(
|
|
62452
|
+
mkdirSync18(path72.dirname(this.file), { recursive: true });
|
|
62337
62453
|
writeFileSync22(
|
|
62338
62454
|
this.file,
|
|
62339
62455
|
JSON.stringify({ entries: this.entries }, null, 2),
|
|
@@ -62408,12 +62524,12 @@ __export(ledger_exports, {
|
|
|
62408
62524
|
readLedger: () => readLedger
|
|
62409
62525
|
});
|
|
62410
62526
|
import { appendFileSync as appendFileSync4, existsSync as existsSync50, mkdirSync as mkdirSync19, readFileSync as readFileSync38 } from "node:fs";
|
|
62411
|
-
import
|
|
62527
|
+
import path73 from "node:path";
|
|
62412
62528
|
function evolutionMode(env = process.env) {
|
|
62413
62529
|
return env[EVOLUTION_ENV] === "shadow" ? "shadow" : "0";
|
|
62414
62530
|
}
|
|
62415
62531
|
function ledgerPath(cwd) {
|
|
62416
|
-
return
|
|
62532
|
+
return path73.join(cwd, LEDGER_REL);
|
|
62417
62533
|
}
|
|
62418
62534
|
function appendLedgerEntry(cwd, entry) {
|
|
62419
62535
|
if (evolutionMode() === "0") {
|
|
@@ -62421,7 +62537,7 @@ function appendLedgerEntry(cwd, entry) {
|
|
|
62421
62537
|
}
|
|
62422
62538
|
try {
|
|
62423
62539
|
const file2 = ledgerPath(cwd);
|
|
62424
|
-
mkdirSync19(
|
|
62540
|
+
mkdirSync19(path73.dirname(file2), { recursive: true });
|
|
62425
62541
|
appendFileSync4(file2, `${JSON.stringify(entry)}
|
|
62426
62542
|
`, "utf8");
|
|
62427
62543
|
return { written: true, path: file2 };
|
|
@@ -62522,7 +62638,7 @@ var init_ledger = __esm({
|
|
|
62522
62638
|
"src/cli/evolution/ledger.ts"() {
|
|
62523
62639
|
"use strict";
|
|
62524
62640
|
EVOLUTION_ENV = "ZELARI_EVOLUTION";
|
|
62525
|
-
LEDGER_REL =
|
|
62641
|
+
LEDGER_REL = path73.join(".zelari", "evolution", "ledger.jsonl");
|
|
62526
62642
|
TIER_WEIGHTS = {
|
|
62527
62643
|
build: 1,
|
|
62528
62644
|
"tool-output": 1,
|
|
@@ -62664,7 +62780,7 @@ __export(fileBackend_exports, {
|
|
|
62664
62780
|
});
|
|
62665
62781
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
62666
62782
|
import { promises as fs31 } from "node:fs";
|
|
62667
|
-
import * as
|
|
62783
|
+
import * as path74 from "node:path";
|
|
62668
62784
|
function tokenize2(text) {
|
|
62669
62785
|
return text.toLowerCase().split(/[^\p{L}\p{N}]+/u).filter((t) => t.length >= 3);
|
|
62670
62786
|
}
|
|
@@ -62717,8 +62833,8 @@ var init_fileBackend = __esm({
|
|
|
62717
62833
|
logPath = "";
|
|
62718
62834
|
memoryDir = "";
|
|
62719
62835
|
async init(projectRoot) {
|
|
62720
|
-
this.memoryDir =
|
|
62721
|
-
this.logPath =
|
|
62836
|
+
this.memoryDir = path74.join(projectRoot, ".zelari", "memory");
|
|
62837
|
+
this.logPath = path74.join(this.memoryDir, "log.jsonl");
|
|
62722
62838
|
await fs31.mkdir(this.memoryDir, { recursive: true });
|
|
62723
62839
|
}
|
|
62724
62840
|
async add(content, metadata2 = {}, graph) {
|
|
@@ -62791,12 +62907,12 @@ var init_fileBackend = __esm({
|
|
|
62791
62907
|
|
|
62792
62908
|
// src/cli/traceStore.ts
|
|
62793
62909
|
import { promises as fs32 } from "node:fs";
|
|
62794
|
-
import * as
|
|
62910
|
+
import * as path75 from "node:path";
|
|
62795
62911
|
function traceDir(projectRoot) {
|
|
62796
|
-
return
|
|
62912
|
+
return path75.join(projectRoot, ".zelari", "trace");
|
|
62797
62913
|
}
|
|
62798
62914
|
function tracePath(projectRoot, missionId) {
|
|
62799
|
-
return
|
|
62915
|
+
return path75.join(traceDir(projectRoot), `${missionId}.json`);
|
|
62800
62916
|
}
|
|
62801
62917
|
async function saveTrace(projectRoot, missionId, entries) {
|
|
62802
62918
|
const dir = traceDir(projectRoot);
|
|
@@ -62833,7 +62949,7 @@ __export(zelariMission_exports, {
|
|
|
62833
62949
|
});
|
|
62834
62950
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
62835
62951
|
import { promises as fs33 } from "node:fs";
|
|
62836
|
-
import * as
|
|
62952
|
+
import * as path76 from "node:path";
|
|
62837
62953
|
function resolveMaxIterations(env = process.env) {
|
|
62838
62954
|
const raw = env.ZELARI_MISSION_MAX_ITER;
|
|
62839
62955
|
const n = raw ? Number.parseInt(raw, 10) : DEFAULT_MAX_ITER;
|
|
@@ -62876,10 +62992,10 @@ function isMissionAutoStart(env = process.env) {
|
|
|
62876
62992
|
return env.ZELARI_MISSION_AUTO === "1";
|
|
62877
62993
|
}
|
|
62878
62994
|
async function writeMissionState(projectRoot, state3) {
|
|
62879
|
-
const dir =
|
|
62995
|
+
const dir = path76.join(projectRoot, ".zelari");
|
|
62880
62996
|
await fs33.mkdir(dir, { recursive: true });
|
|
62881
62997
|
await fs33.writeFile(
|
|
62882
|
-
|
|
62998
|
+
path76.join(dir, "mission-state.json"),
|
|
62883
62999
|
JSON.stringify(state3, null, 2) + "\n",
|
|
62884
63000
|
"utf8"
|
|
62885
63001
|
);
|
|
@@ -63568,7 +63684,7 @@ function safeSocketPath(socketPath) {
|
|
|
63568
63684
|
return socketPath.trim();
|
|
63569
63685
|
}
|
|
63570
63686
|
function startPermissionBroker(socketPath, handlers, opts) {
|
|
63571
|
-
const
|
|
63687
|
+
const path100 = safeSocketPath(socketPath);
|
|
63572
63688
|
const requestTimeoutMs = opts?.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
|
|
63573
63689
|
const sockets = /* @__PURE__ */ new Set();
|
|
63574
63690
|
const server = createServer2((socket) => {
|
|
@@ -63668,10 +63784,10 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
63668
63784
|
return new Promise((resolve9, reject) => {
|
|
63669
63785
|
const onError = (err) => reject(err);
|
|
63670
63786
|
server.once("error", onError);
|
|
63671
|
-
server.listen(
|
|
63787
|
+
server.listen(path100, () => {
|
|
63672
63788
|
server.removeListener("error", onError);
|
|
63673
63789
|
resolve9({
|
|
63674
|
-
socketPath:
|
|
63790
|
+
socketPath: path100,
|
|
63675
63791
|
stop: () => new Promise((res) => {
|
|
63676
63792
|
for (const s of sockets) s.destroy();
|
|
63677
63793
|
sockets.clear();
|
|
@@ -63682,7 +63798,7 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
63682
63798
|
if (done) return;
|
|
63683
63799
|
done = true;
|
|
63684
63800
|
if (process.platform !== "win32") {
|
|
63685
|
-
unlink(
|
|
63801
|
+
unlink(path100, () => res());
|
|
63686
63802
|
} else {
|
|
63687
63803
|
res();
|
|
63688
63804
|
}
|
|
@@ -63695,11 +63811,11 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
63695
63811
|
});
|
|
63696
63812
|
}
|
|
63697
63813
|
function requestBrokerAsk(socketPath, ask, opts) {
|
|
63698
|
-
const
|
|
63814
|
+
const path100 = safeSocketPath(socketPath);
|
|
63699
63815
|
const requestTimeoutMs = opts?.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
|
|
63700
63816
|
const connectTimeoutMs = opts?.connectTimeoutMs ?? PERMISSION_BROKER_DEFAULT_CONNECT_TIMEOUT_MS;
|
|
63701
63817
|
return new Promise((resolve9, reject) => {
|
|
63702
|
-
const socket = connect(
|
|
63818
|
+
const socket = connect(path100);
|
|
63703
63819
|
let buffer = "";
|
|
63704
63820
|
let settled = false;
|
|
63705
63821
|
const settle = (fn) => {
|
|
@@ -63714,7 +63830,7 @@ function requestBrokerAsk(socketPath, ask, opts) {
|
|
|
63714
63830
|
settle(
|
|
63715
63831
|
() => reject(
|
|
63716
63832
|
new Error(
|
|
63717
|
-
`permission broker unavailable at "${
|
|
63833
|
+
`permission broker unavailable at "${path100}" (connect timed out after ${connectTimeoutMs}ms)`
|
|
63718
63834
|
)
|
|
63719
63835
|
)
|
|
63720
63836
|
);
|
|
@@ -64903,7 +65019,7 @@ var init_prereqChecks = __esm({
|
|
|
64903
65019
|
|
|
64904
65020
|
// src/cli/plugins/prefs.ts
|
|
64905
65021
|
import { existsSync as existsSync53, readFileSync as readFileSync40, writeFileSync as writeFileSync23, mkdirSync as mkdirSync20 } from "node:fs";
|
|
64906
|
-
import
|
|
65022
|
+
import path82 from "node:path";
|
|
64907
65023
|
function getPluginPrefsPath() {
|
|
64908
65024
|
return pluginsPrefsPath();
|
|
64909
65025
|
}
|
|
@@ -64926,7 +65042,7 @@ function getPluginPrefs() {
|
|
|
64926
65042
|
}
|
|
64927
65043
|
function writePluginPrefs(prefs) {
|
|
64928
65044
|
const file2 = getPluginPrefsPath();
|
|
64929
|
-
mkdirSync20(
|
|
65045
|
+
mkdirSync20(path82.dirname(file2), { recursive: true });
|
|
64930
65046
|
writeFileSync23(file2, JSON.stringify(prefs, null, 2), {
|
|
64931
65047
|
encoding: "utf-8",
|
|
64932
65048
|
mode: 384
|
|
@@ -64964,7 +65080,7 @@ __export(registry_exports, {
|
|
|
64964
65080
|
isBinaryOnPath: () => isBinaryOnPath
|
|
64965
65081
|
});
|
|
64966
65082
|
import { existsSync as existsSync54 } from "node:fs";
|
|
64967
|
-
import
|
|
65083
|
+
import path83 from "node:path";
|
|
64968
65084
|
function detectLocalBin(bin) {
|
|
64969
65085
|
return (cwd) => {
|
|
64970
65086
|
try {
|
|
@@ -64982,7 +65098,7 @@ function isBinaryOnPath(bin, opts = {}) {
|
|
|
64982
65098
|
const platform = opts.platform ?? process.platform;
|
|
64983
65099
|
const exists = opts.exists ?? existsSync54;
|
|
64984
65100
|
const pathEnv = opts.pathEnv ?? process.env.PATH ?? "";
|
|
64985
|
-
const pathMod = platform === "win32" ?
|
|
65101
|
+
const pathMod = platform === "win32" ? path83.win32 : path83.posix;
|
|
64986
65102
|
const sep4 = platform === "win32" ? ";" : ":";
|
|
64987
65103
|
const dirs = pathEnv.split(sep4).filter((d) => d.length > 0);
|
|
64988
65104
|
const candidates = [bin];
|
|
@@ -66077,7 +66193,7 @@ var init_policy = __esm({
|
|
|
66077
66193
|
|
|
66078
66194
|
// src/cli/orchestration/facts.ts
|
|
66079
66195
|
import { promises as fs43 } from "node:fs";
|
|
66080
|
-
import
|
|
66196
|
+
import path87 from "node:path";
|
|
66081
66197
|
async function collectRepoFileCount(root = process.cwd()) {
|
|
66082
66198
|
try {
|
|
66083
66199
|
await fs43.readdir(root);
|
|
@@ -66097,7 +66213,7 @@ async function collectRepoFileCount(root = process.cwd()) {
|
|
|
66097
66213
|
}
|
|
66098
66214
|
for (const e of entries) {
|
|
66099
66215
|
if (e.isDirectory()) {
|
|
66100
|
-
if (!SKIP_DIRS.has(e.name)) queue.push(
|
|
66216
|
+
if (!SKIP_DIRS.has(e.name)) queue.push(path87.join(dir, e.name));
|
|
66101
66217
|
} else if (e.isFile()) {
|
|
66102
66218
|
count++;
|
|
66103
66219
|
if (count > MAX_WALK_FILES) return count;
|
|
@@ -66195,7 +66311,7 @@ var init_streamScrub = __esm({
|
|
|
66195
66311
|
});
|
|
66196
66312
|
|
|
66197
66313
|
// src/cli/harnessState.ts
|
|
66198
|
-
import
|
|
66314
|
+
import path88 from "node:path";
|
|
66199
66315
|
function asString4(v) {
|
|
66200
66316
|
return typeof v === "string" ? v : "";
|
|
66201
66317
|
}
|
|
@@ -66370,7 +66486,7 @@ function contractFor(t) {
|
|
|
66370
66486
|
};
|
|
66371
66487
|
}
|
|
66372
66488
|
async function readHarnessState(sessionDir) {
|
|
66373
|
-
const report = await readSessionLog(
|
|
66489
|
+
const report = await readSessionLog(path88.join(sessionDir, "events.jsonl"));
|
|
66374
66490
|
return deriveHarnessState(report.events);
|
|
66375
66491
|
}
|
|
66376
66492
|
var init_harnessState = __esm({
|
|
@@ -66381,12 +66497,12 @@ var init_harnessState = __esm({
|
|
|
66381
66497
|
});
|
|
66382
66498
|
|
|
66383
66499
|
// src/cli/headless/harnessStateEmit.ts
|
|
66384
|
-
import
|
|
66500
|
+
import path89 from "node:path";
|
|
66385
66501
|
async function emitHarnessStateEvent(opts) {
|
|
66386
66502
|
if (opts.output !== "json") return;
|
|
66387
66503
|
try {
|
|
66388
66504
|
const sessionsDir2 = resolveSessionsDir({ workspaceRoot: opts.workspaceRoot });
|
|
66389
|
-
const state3 = await readHarnessState(
|
|
66505
|
+
const state3 = await readHarnessState(path89.join(sessionsDir2, opts.spine.sessionId));
|
|
66390
66506
|
opts.emitEvent({ type: "harness_state", ...state3 });
|
|
66391
66507
|
} catch (err) {
|
|
66392
66508
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -66943,13 +67059,13 @@ var init_verifierLifecycle = __esm({
|
|
|
66943
67059
|
|
|
66944
67060
|
// src/cli/extensions/sandboxedFs.ts
|
|
66945
67061
|
import { promises as fsp } from "node:fs";
|
|
66946
|
-
import
|
|
67062
|
+
import path90 from "node:path";
|
|
66947
67063
|
function errText(prefix, p3, err) {
|
|
66948
67064
|
const msg = err instanceof Error ? err.message : String(err);
|
|
66949
67065
|
return `[extension-fs] ${prefix} "${p3}": ${msg}`;
|
|
66950
67066
|
}
|
|
66951
67067
|
function bindSandboxedFs(root) {
|
|
66952
|
-
const resolvedRoot =
|
|
67068
|
+
const resolvedRoot = path90.resolve(root);
|
|
66953
67069
|
return {
|
|
66954
67070
|
root: resolvedRoot,
|
|
66955
67071
|
async readFile(relativePath) {
|
|
@@ -66965,7 +67081,7 @@ function bindSandboxedFs(root) {
|
|
|
66965
67081
|
try {
|
|
66966
67082
|
const target = resolveSandboxedPath(relativePath, { root: resolvedRoot });
|
|
66967
67083
|
verifyContainment(target, { root: resolvedRoot });
|
|
66968
|
-
await fsp.mkdir(
|
|
67084
|
+
await fsp.mkdir(path90.dirname(target), { recursive: true });
|
|
66969
67085
|
await fsp.writeFile(target, data, "utf8");
|
|
66970
67086
|
return typedOk({ path: target });
|
|
66971
67087
|
} catch (err) {
|
|
@@ -67150,7 +67266,7 @@ var init_loader = __esm({
|
|
|
67150
67266
|
|
|
67151
67267
|
// src/cli/headless/runOneTurn.ts
|
|
67152
67268
|
import { promises as fs44 } from "node:fs";
|
|
67153
|
-
import
|
|
67269
|
+
import path91 from "node:path";
|
|
67154
67270
|
function planModeFromOpts(opts) {
|
|
67155
67271
|
return (opts.phase ?? "build") === "plan";
|
|
67156
67272
|
}
|
|
@@ -67717,7 +67833,7 @@ async function runOneTurn(opts, provider, model, providerStream, extras) {
|
|
|
67717
67833
|
if (json3) {
|
|
67718
67834
|
if (opts.exportSessionPath === "-") process.stdout.write(json3 + "\n");
|
|
67719
67835
|
else {
|
|
67720
|
-
await fs44.mkdir(
|
|
67836
|
+
await fs44.mkdir(path91.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
67721
67837
|
await fs44.writeFile(opts.exportSessionPath, json3, "utf8");
|
|
67722
67838
|
}
|
|
67723
67839
|
}
|
|
@@ -68696,9 +68812,9 @@ __export(triggerLock_exports, {
|
|
|
68696
68812
|
releaseLock: () => releaseLock
|
|
68697
68813
|
});
|
|
68698
68814
|
import { promises as fs45 } from "node:fs";
|
|
68699
|
-
import * as
|
|
68815
|
+
import * as path92 from "node:path";
|
|
68700
68816
|
function lockPath(projectRoot) {
|
|
68701
|
-
return
|
|
68817
|
+
return path92.join(projectRoot, ".zelari", "trigger.lock");
|
|
68702
68818
|
}
|
|
68703
68819
|
function isPidAlive(pid) {
|
|
68704
68820
|
try {
|
|
@@ -68711,7 +68827,7 @@ function isPidAlive(pid) {
|
|
|
68711
68827
|
}
|
|
68712
68828
|
async function acquireLock(projectRoot, now = () => /* @__PURE__ */ new Date()) {
|
|
68713
68829
|
const lp = lockPath(projectRoot);
|
|
68714
|
-
const dir =
|
|
68830
|
+
const dir = path92.dirname(lp);
|
|
68715
68831
|
await fs45.mkdir(dir, { recursive: true });
|
|
68716
68832
|
try {
|
|
68717
68833
|
const raw = await fs45.readFile(lp, "utf8");
|
|
@@ -68743,7 +68859,7 @@ var init_triggerLock = __esm({
|
|
|
68743
68859
|
|
|
68744
68860
|
// src/cli/runHeadless.ts
|
|
68745
68861
|
import { promises as fs46 } from "node:fs";
|
|
68746
|
-
import
|
|
68862
|
+
import path93 from "node:path";
|
|
68747
68863
|
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
68748
68864
|
async function runHeadless(opts) {
|
|
68749
68865
|
resetTaskSpawnCount();
|
|
@@ -68987,7 +69103,7 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
68987
69103
|
try {
|
|
68988
69104
|
let preflightGraph;
|
|
68989
69105
|
if (opts.runPlan && opts.runPlan.trim() !== "") {
|
|
68990
|
-
const planPath =
|
|
69106
|
+
const planPath = path93.join(cwd, ".zelari", "radio", `plan-${opts.runPlan}.json`);
|
|
68991
69107
|
log(`loading pre-flight plan: ${planPath}`);
|
|
68992
69108
|
let raw;
|
|
68993
69109
|
try {
|
|
@@ -69030,8 +69146,8 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
69030
69146
|
log(formatKrakenGraphAscii2(graph));
|
|
69031
69147
|
if (opts.planOnly) {
|
|
69032
69148
|
const planId = randomUUID10();
|
|
69033
|
-
const planDir =
|
|
69034
|
-
const planPath =
|
|
69149
|
+
const planDir = path93.join(cwd, ".zelari", "radio");
|
|
69150
|
+
const planPath = path93.join(planDir, `plan-${planId}.json`);
|
|
69035
69151
|
await fs46.mkdir(planDir, { recursive: true });
|
|
69036
69152
|
await fs46.writeFile(
|
|
69037
69153
|
planPath,
|
|
@@ -69409,7 +69525,7 @@ async function runHeadlessCouncilBody(opts, provider, model, providerStream, ext
|
|
|
69409
69525
|
if (json3) {
|
|
69410
69526
|
if (opts.exportSessionPath === "-") process.stdout.write(json3 + "\n");
|
|
69411
69527
|
else {
|
|
69412
|
-
await fs46.mkdir(
|
|
69528
|
+
await fs46.mkdir(path93.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
69413
69529
|
await fs46.writeFile(opts.exportSessionPath, json3, "utf8");
|
|
69414
69530
|
}
|
|
69415
69531
|
}
|
|
@@ -69860,7 +69976,7 @@ ${ragContext}` : slicePrompt;
|
|
|
69860
69976
|
if (json3) {
|
|
69861
69977
|
if (opts.exportSessionPath === "-") process.stdout.write(json3 + "\n");
|
|
69862
69978
|
else {
|
|
69863
|
-
await fs46.mkdir(
|
|
69979
|
+
await fs46.mkdir(path93.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
69864
69980
|
await fs46.writeFile(opts.exportSessionPath, json3, "utf8");
|
|
69865
69981
|
}
|
|
69866
69982
|
}
|
|
@@ -70473,7 +70589,7 @@ function upsertSkill(opts) {
|
|
|
70473
70589
|
}
|
|
70474
70590
|
dir = getProjectSkillsDir(root);
|
|
70475
70591
|
}
|
|
70476
|
-
const
|
|
70592
|
+
const path100 = skillFilePath(dir, name);
|
|
70477
70593
|
const content = serializeSkillMd({
|
|
70478
70594
|
name,
|
|
70479
70595
|
description,
|
|
@@ -70482,13 +70598,13 @@ function upsertSkill(opts) {
|
|
|
70482
70598
|
tools: opts.tools,
|
|
70483
70599
|
cost: opts.cost
|
|
70484
70600
|
});
|
|
70485
|
-
const parsed = parseSkillMd(content,
|
|
70601
|
+
const parsed = parseSkillMd(content, path100);
|
|
70486
70602
|
if (!parsed) {
|
|
70487
70603
|
return { ok: false, error: "Generated SKILL.md failed validation" };
|
|
70488
70604
|
}
|
|
70489
|
-
mkdirSync23(dirname13(
|
|
70490
|
-
writeFileSync25(
|
|
70491
|
-
return { ok: true, path:
|
|
70605
|
+
mkdirSync23(dirname13(path100), { recursive: true });
|
|
70606
|
+
writeFileSync25(path100, content, "utf8");
|
|
70607
|
+
return { ok: true, path: path100 };
|
|
70492
70608
|
}
|
|
70493
70609
|
function removeSkill(opts) {
|
|
70494
70610
|
const name = opts.name.trim().toLowerCase();
|
|
@@ -70506,8 +70622,8 @@ function removeSkill(opts) {
|
|
|
70506
70622
|
dir = getProjectSkillsDir(root);
|
|
70507
70623
|
}
|
|
70508
70624
|
const skillDir = join46(dir, name);
|
|
70509
|
-
const
|
|
70510
|
-
if (!existsSync59(
|
|
70625
|
+
const path100 = skillFilePath(dir, name);
|
|
70626
|
+
if (!existsSync59(path100) && !existsSync59(skillDir)) {
|
|
70511
70627
|
return { ok: false, error: `Skill "${name}" not found in ${dir}` };
|
|
70512
70628
|
}
|
|
70513
70629
|
try {
|
|
@@ -70518,7 +70634,7 @@ function removeSkill(opts) {
|
|
|
70518
70634
|
error: err instanceof Error ? err.message : String(err)
|
|
70519
70635
|
};
|
|
70520
70636
|
}
|
|
70521
|
-
return { ok: true, path:
|
|
70637
|
+
return { ok: true, path: path100 };
|
|
70522
70638
|
}
|
|
70523
70639
|
var NAME_RE, BUILTIN_SKILL_MODULES, builtinsLoaded;
|
|
70524
70640
|
var init_skillConfigIo = __esm({
|
|
@@ -70639,7 +70755,7 @@ var init_jsonApi = __esm({
|
|
|
70639
70755
|
});
|
|
70640
70756
|
|
|
70641
70757
|
// src/cli/memory/mcpAdapter.ts
|
|
70642
|
-
import * as
|
|
70758
|
+
import * as path94 from "node:path";
|
|
70643
70759
|
var id2, projectId, source, SearchSchema, AddSchema, LinkSchema, RetractSchema, MEMORY_MCP_TOOLS, MemoryMcpAdapter;
|
|
70644
70760
|
var init_mcpAdapter = __esm({
|
|
70645
70761
|
"src/cli/memory/mcpAdapter.ts"() {
|
|
@@ -70809,8 +70925,8 @@ var init_mcpAdapter = __esm({
|
|
|
70809
70925
|
this.takeWrite();
|
|
70810
70926
|
const externalFile = args.source?.file;
|
|
70811
70927
|
if (externalFile) {
|
|
70812
|
-
const normalized =
|
|
70813
|
-
if (
|
|
70928
|
+
const normalized = path94.normalize(externalFile);
|
|
70929
|
+
if (path94.isAbsolute(normalized) || normalized === ".." || normalized.startsWith(`..${path94.sep}`)) {
|
|
70814
70930
|
throw new Error("source.file must be project-relative and cannot escape the project");
|
|
70815
70931
|
}
|
|
70816
70932
|
}
|
|
@@ -71337,12 +71453,12 @@ function ensureHome() {
|
|
|
71337
71453
|
}
|
|
71338
71454
|
}
|
|
71339
71455
|
function loadCompanionConfig() {
|
|
71340
|
-
const
|
|
71341
|
-
if (!existsSync60(
|
|
71456
|
+
const path100 = getCompanionConfigPath();
|
|
71457
|
+
if (!existsSync60(path100)) {
|
|
71342
71458
|
return { projects: [] };
|
|
71343
71459
|
}
|
|
71344
71460
|
try {
|
|
71345
|
-
const raw = JSON.parse(readFileSync45(
|
|
71461
|
+
const raw = JSON.parse(readFileSync45(path100, "utf8"));
|
|
71346
71462
|
const projects = Array.isArray(raw.projects) ? raw.projects.filter(
|
|
71347
71463
|
(p3) => p3 && typeof p3.path === "string" && p3.path.trim() && typeof (p3.id ?? p3.name) === "string"
|
|
71348
71464
|
).map((p3) => ({
|
|
@@ -71380,16 +71496,16 @@ function loadOrCreateToken(explicit) {
|
|
|
71380
71496
|
return { token: explicit.trim(), created: false };
|
|
71381
71497
|
}
|
|
71382
71498
|
ensureHome();
|
|
71383
|
-
const
|
|
71384
|
-
if (existsSync60(
|
|
71385
|
-
const t = readFileSync45(
|
|
71499
|
+
const path100 = getCompanionTokenPath();
|
|
71500
|
+
if (existsSync60(path100)) {
|
|
71501
|
+
const t = readFileSync45(path100, "utf8").trim();
|
|
71386
71502
|
if (t) return { token: t, created: false };
|
|
71387
71503
|
}
|
|
71388
71504
|
const token = randomBytes7(24).toString("base64url");
|
|
71389
|
-
writeFileSync26(
|
|
71505
|
+
writeFileSync26(path100, token + "\n", "utf8");
|
|
71390
71506
|
try {
|
|
71391
71507
|
const fs48 = __require("node:fs");
|
|
71392
|
-
fs48.chmodSync?.(
|
|
71508
|
+
fs48.chmodSync?.(path100, 384);
|
|
71393
71509
|
} catch {
|
|
71394
71510
|
}
|
|
71395
71511
|
return { token, created: true };
|
|
@@ -71414,17 +71530,17 @@ function mergeProjects(cfg, extraPaths) {
|
|
|
71414
71530
|
byId.set(p3.id, p3);
|
|
71415
71531
|
}
|
|
71416
71532
|
for (const raw of extraPaths) {
|
|
71417
|
-
const
|
|
71418
|
-
if (!
|
|
71419
|
-
let id3 = slugFromPath(
|
|
71533
|
+
const path100 = raw.trim();
|
|
71534
|
+
if (!path100) continue;
|
|
71535
|
+
let id3 = slugFromPath(path100);
|
|
71420
71536
|
let n = 2;
|
|
71421
|
-
while (byId.has(id3) && byId.get(id3).path !==
|
|
71422
|
-
id3 = `${slugFromPath(
|
|
71537
|
+
while (byId.has(id3) && byId.get(id3).path !== path100) {
|
|
71538
|
+
id3 = `${slugFromPath(path100)}-${n++}`;
|
|
71423
71539
|
}
|
|
71424
71540
|
byId.set(id3, {
|
|
71425
71541
|
id: id3,
|
|
71426
|
-
name: slugFromPath(
|
|
71427
|
-
path:
|
|
71542
|
+
name: slugFromPath(path100),
|
|
71543
|
+
path: path100
|
|
71428
71544
|
});
|
|
71429
71545
|
}
|
|
71430
71546
|
return [...byId.values()];
|
|
@@ -71667,7 +71783,7 @@ var init_askUserBridge = __esm({
|
|
|
71667
71783
|
|
|
71668
71784
|
// src/cli/serve/spineLockSweep.ts
|
|
71669
71785
|
import { promises as fs47 } from "node:fs";
|
|
71670
|
-
import
|
|
71786
|
+
import path95 from "node:path";
|
|
71671
71787
|
async function sweepOrphanSpineLocks(sessionsDir2, options = {}) {
|
|
71672
71788
|
const dir = sessionsDir2 ?? resolveSessionsDir();
|
|
71673
71789
|
const onSwept = options.onSwept ?? ((sessionId2, reason) => {
|
|
@@ -71685,7 +71801,7 @@ async function sweepOrphanSpineLocks(sessionsDir2, options = {}) {
|
|
|
71685
71801
|
return result;
|
|
71686
71802
|
}
|
|
71687
71803
|
for (const sessionId2 of entries) {
|
|
71688
|
-
const lockPath2 =
|
|
71804
|
+
const lockPath2 = path95.join(dir, sessionId2, "writer.lock");
|
|
71689
71805
|
try {
|
|
71690
71806
|
const raw = await fs47.readFile(lockPath2, "utf-8");
|
|
71691
71807
|
let lockInfo = {};
|
|
@@ -72682,9 +72798,9 @@ async function runCompanionServe(opts = {}) {
|
|
|
72682
72798
|
return;
|
|
72683
72799
|
}
|
|
72684
72800
|
const url2 = parseUrl(req);
|
|
72685
|
-
const
|
|
72801
|
+
const path100 = url2.pathname.replace(/\/+$/, "") || "/";
|
|
72686
72802
|
try {
|
|
72687
|
-
if (req.method === "GET" && (
|
|
72803
|
+
if (req.method === "GET" && (path100 === "/health" || path100 === "/v1/health")) {
|
|
72688
72804
|
sendJson2(res, 200, {
|
|
72689
72805
|
ok: true,
|
|
72690
72806
|
service: "zelari-companion",
|
|
@@ -72696,18 +72812,18 @@ async function runCompanionServe(opts = {}) {
|
|
|
72696
72812
|
});
|
|
72697
72813
|
return;
|
|
72698
72814
|
}
|
|
72699
|
-
if (
|
|
72815
|
+
if (path100.startsWith("/v1")) {
|
|
72700
72816
|
if (!tokenMatches(token, getBearer(req))) {
|
|
72701
72817
|
sendJson2(res, 401, { ok: false, error: "unauthorized" });
|
|
72702
72818
|
return;
|
|
72703
72819
|
}
|
|
72704
72820
|
}
|
|
72705
|
-
if (req.method === "GET" &&
|
|
72821
|
+
if (req.method === "GET" && path100 === "/v1/config") {
|
|
72706
72822
|
const snap = buildDesktopConfigSnapshot();
|
|
72707
72823
|
sendJson2(res, 200, { ok: true, ...snap });
|
|
72708
72824
|
return;
|
|
72709
72825
|
}
|
|
72710
|
-
if (req.method === "GET" &&
|
|
72826
|
+
if (req.method === "GET" && path100 === "/v1/projects") {
|
|
72711
72827
|
sendJson2(res, 200, {
|
|
72712
72828
|
ok: true,
|
|
72713
72829
|
projects: projects.map((p3) => ({
|
|
@@ -72718,7 +72834,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
72718
72834
|
});
|
|
72719
72835
|
return;
|
|
72720
72836
|
}
|
|
72721
|
-
if (req.method === "GET" &&
|
|
72837
|
+
if (req.method === "GET" && path100 === "/v1/runs") {
|
|
72722
72838
|
sendJson2(res, 200, {
|
|
72723
72839
|
ok: true,
|
|
72724
72840
|
active: runs.getActive(),
|
|
@@ -72736,7 +72852,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
72736
72852
|
});
|
|
72737
72853
|
return;
|
|
72738
72854
|
}
|
|
72739
|
-
if (req.method === "POST" &&
|
|
72855
|
+
if (req.method === "POST" && path100 === "/v1/runs") {
|
|
72740
72856
|
const raw = await readBody(req);
|
|
72741
72857
|
let body = {};
|
|
72742
72858
|
try {
|
|
@@ -72784,7 +72900,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
72784
72900
|
});
|
|
72785
72901
|
return;
|
|
72786
72902
|
}
|
|
72787
|
-
const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(
|
|
72903
|
+
const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(path100);
|
|
72788
72904
|
if (req.method === "GET" && eventsMatch) {
|
|
72789
72905
|
const runId = eventsMatch[1];
|
|
72790
72906
|
const run = runs.getRun(runId);
|
|
@@ -72849,7 +72965,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
72849
72965
|
}, 500);
|
|
72850
72966
|
return;
|
|
72851
72967
|
}
|
|
72852
|
-
const cancelMatch = /^\/v1\/runs\/([^/]+)\/cancel$/.exec(
|
|
72968
|
+
const cancelMatch = /^\/v1\/runs\/([^/]+)\/cancel$/.exec(path100);
|
|
72853
72969
|
if (req.method === "POST" && cancelMatch) {
|
|
72854
72970
|
const runId = cancelMatch[1];
|
|
72855
72971
|
const result = runs.cancel(runId);
|
|
@@ -72860,7 +72976,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
72860
72976
|
sendJson2(res, 200, { ok: true, cancelled: runId });
|
|
72861
72977
|
return;
|
|
72862
72978
|
}
|
|
72863
|
-
const steerMatch = /^\/v1\/runs\/([^/]+)\/steer$/.exec(
|
|
72979
|
+
const steerMatch = /^\/v1\/runs\/([^/]+)\/steer$/.exec(path100);
|
|
72864
72980
|
if (req.method === "POST" && steerMatch) {
|
|
72865
72981
|
const runId = steerMatch[1];
|
|
72866
72982
|
const raw = await readBody(req);
|
|
@@ -73029,11 +73145,11 @@ import { execSync as execSync2 } from "node:child_process";
|
|
|
73029
73145
|
import { existsSync as existsSync62, readFileSync as readFileSync46, readlinkSync, statSync as statSync10 } from "node:fs";
|
|
73030
73146
|
import { createRequire as createRequire3 } from "node:module";
|
|
73031
73147
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
73032
|
-
import
|
|
73148
|
+
import path96 from "node:path";
|
|
73033
73149
|
function findPackageRoot(start) {
|
|
73034
73150
|
let dir = start;
|
|
73035
73151
|
for (let i = 0; i < 6; i += 1) {
|
|
73036
|
-
const candidate =
|
|
73152
|
+
const candidate = path96.join(dir, "package.json");
|
|
73037
73153
|
if (existsSync62(candidate)) {
|
|
73038
73154
|
try {
|
|
73039
73155
|
const pkg = JSON.parse(readFileSync46(candidate, "utf8"));
|
|
@@ -73041,11 +73157,11 @@ function findPackageRoot(start) {
|
|
|
73041
73157
|
} catch {
|
|
73042
73158
|
}
|
|
73043
73159
|
}
|
|
73044
|
-
const parent =
|
|
73160
|
+
const parent = path96.dirname(dir);
|
|
73045
73161
|
if (parent === dir) break;
|
|
73046
73162
|
dir = parent;
|
|
73047
73163
|
}
|
|
73048
|
-
return
|
|
73164
|
+
return path96.resolve(__dirname3, "..", "..", "..");
|
|
73049
73165
|
}
|
|
73050
73166
|
function tryExec(cmd) {
|
|
73051
73167
|
try {
|
|
@@ -73059,7 +73175,7 @@ function tryExec(cmd) {
|
|
|
73059
73175
|
}
|
|
73060
73176
|
function readPackageJson4() {
|
|
73061
73177
|
try {
|
|
73062
|
-
const pkgPath =
|
|
73178
|
+
const pkgPath = path96.join(packageRoot, "package.json");
|
|
73063
73179
|
return JSON.parse(readFileSync46(pkgPath, "utf8"));
|
|
73064
73180
|
} catch {
|
|
73065
73181
|
return null;
|
|
@@ -73071,7 +73187,7 @@ function getGlobalPrefix() {
|
|
|
73071
73187
|
return (process.env.npm_config_prefix || process.env.NPM_CONFIG_PREFIX || "").trim();
|
|
73072
73188
|
}
|
|
73073
73189
|
function isSourceCheckout() {
|
|
73074
|
-
return existsSync62(
|
|
73190
|
+
return existsSync62(path96.join(packageRoot, "src", "cli", "main.ts")) && existsSync62(path96.join(packageRoot, "apps", "desktop", "package.json"));
|
|
73075
73191
|
}
|
|
73076
73192
|
function checkShim(pkgName) {
|
|
73077
73193
|
const prefix = getGlobalPrefix();
|
|
@@ -73080,9 +73196,9 @@ function checkShim(pkgName) {
|
|
|
73080
73196
|
}
|
|
73081
73197
|
const isWin = process.platform === "win32";
|
|
73082
73198
|
const shimName = isWin ? "zelari-code.cmd" : "zelari-code";
|
|
73083
|
-
const shimPath =
|
|
73199
|
+
const shimPath = path96.join(prefix, shimName);
|
|
73084
73200
|
if (!existsSync62(shimPath)) {
|
|
73085
|
-
const localBin =
|
|
73201
|
+
const localBin = path96.join(packageRoot, "bin", "zelari-code.js");
|
|
73086
73202
|
if (isSourceCheckout() && existsSync62(localBin)) {
|
|
73087
73203
|
return WARN(
|
|
73088
73204
|
`global shim not found at ${shimPath}
|
|
@@ -73116,8 +73232,8 @@ function checkShim(pkgName) {
|
|
|
73116
73232
|
fix: npm install -g ${pkgName}@latest --force`
|
|
73117
73233
|
);
|
|
73118
73234
|
}
|
|
73119
|
-
const resolved =
|
|
73120
|
-
const expected =
|
|
73235
|
+
const resolved = path96.resolve(path96.dirname(shimPath), target);
|
|
73236
|
+
const expected = path96.join(
|
|
73121
73237
|
prefix,
|
|
73122
73238
|
"node_modules",
|
|
73123
73239
|
pkgName,
|
|
@@ -73159,7 +73275,7 @@ function checkNode(pkg) {
|
|
|
73159
73275
|
return OK(`node ${raw} (engines.node ${enginesNode ?? ">= 20.0.0"})`);
|
|
73160
73276
|
}
|
|
73161
73277
|
function checkBundle() {
|
|
73162
|
-
const bundle =
|
|
73278
|
+
const bundle = path96.join(packageRoot, "dist", "cli", "main.bundled.js");
|
|
73163
73279
|
if (!existsSync62(bundle)) {
|
|
73164
73280
|
return FAIL(
|
|
73165
73281
|
`dist/cli/main.bundled.js missing at ${bundle}
|
|
@@ -73180,7 +73296,7 @@ function checkRuntimeDeps() {
|
|
|
73180
73296
|
const missing = [];
|
|
73181
73297
|
for (const dep of required2) {
|
|
73182
73298
|
try {
|
|
73183
|
-
const localReq = createRequire3(
|
|
73299
|
+
const localReq = createRequire3(path96.join(packageRoot, "package.json"));
|
|
73184
73300
|
localReq.resolve(dep);
|
|
73185
73301
|
} catch {
|
|
73186
73302
|
missing.push(dep);
|
|
@@ -73457,7 +73573,7 @@ var init_doctor = __esm({
|
|
|
73457
73573
|
init_metrics3();
|
|
73458
73574
|
init_contextGrowthSummary();
|
|
73459
73575
|
require3 = createRequire3(import.meta.url);
|
|
73460
|
-
__dirname3 =
|
|
73576
|
+
__dirname3 = path96.dirname(fileURLToPath3(import.meta.url));
|
|
73461
73577
|
packageRoot = findPackageRoot(__dirname3);
|
|
73462
73578
|
OK = (message) => ({
|
|
73463
73579
|
ok: true,
|
|
@@ -73566,7 +73682,7 @@ __export(userSettings_exports, {
|
|
|
73566
73682
|
settingsOverrides: () => settingsOverrides
|
|
73567
73683
|
});
|
|
73568
73684
|
import { existsSync as existsSync63, readFileSync as readFileSync47 } from "node:fs";
|
|
73569
|
-
import
|
|
73685
|
+
import path97 from "node:path";
|
|
73570
73686
|
function parseBool(raw) {
|
|
73571
73687
|
const v = raw.trim().toLowerCase();
|
|
73572
73688
|
if (["1", "true", "yes", "on"].includes(v)) return true;
|
|
@@ -73633,8 +73749,8 @@ function envValueFor(key, env) {
|
|
|
73633
73749
|
function resolveUserSettings(opts = {}) {
|
|
73634
73750
|
const cwd = opts.cwd ?? process.cwd();
|
|
73635
73751
|
const env = opts.env ?? process.env;
|
|
73636
|
-
const userPath =
|
|
73637
|
-
const projectPath =
|
|
73752
|
+
const userPath = path97.join(zelariHome(), SETTINGS_FILE_NAME);
|
|
73753
|
+
const projectPath = path97.join(cwd, ".zelari", SETTINGS_FILE_NAME);
|
|
73638
73754
|
const warnings = [];
|
|
73639
73755
|
const userLayer = loadFileLayer(userPath, "user", warnings);
|
|
73640
73756
|
const projectLayer = loadFileLayer(projectPath, "project", warnings);
|
|
@@ -73848,7 +73964,7 @@ __export(inspectSession_exports, {
|
|
|
73848
73964
|
renderInspectReport: () => renderInspectReport,
|
|
73849
73965
|
runInspectSession: () => runInspectSession
|
|
73850
73966
|
});
|
|
73851
|
-
import
|
|
73967
|
+
import path98 from "node:path";
|
|
73852
73968
|
import { existsSync as existsSync64 } from "node:fs";
|
|
73853
73969
|
function formatLimit(limit) {
|
|
73854
73970
|
return `${Math.round(limit / 1e3)}k`;
|
|
@@ -73882,8 +73998,8 @@ function renderInspectReport(state3) {
|
|
|
73882
73998
|
}
|
|
73883
73999
|
async function runInspectSession(opts) {
|
|
73884
74000
|
const sessionsDir2 = resolveSessionsDir({ workspaceRoot: opts.cwd ?? process.cwd() });
|
|
73885
|
-
const sessionDir =
|
|
73886
|
-
const eventsPath =
|
|
74001
|
+
const sessionDir = path98.join(sessionsDir2, opts.sessionId);
|
|
74002
|
+
const eventsPath = path98.join(sessionDir, "events.jsonl");
|
|
73887
74003
|
if (!existsSync64(sessionDir)) {
|
|
73888
74004
|
console.error(`zelari-code inspect: no session directory at ${sessionDir}`);
|
|
73889
74005
|
return 1;
|
|
@@ -73917,14 +74033,14 @@ __export(inspect_exports, {
|
|
|
73917
74033
|
collectInspectReport: () => collectInspectReport,
|
|
73918
74034
|
runInspect: () => runInspect
|
|
73919
74035
|
});
|
|
73920
|
-
import
|
|
74036
|
+
import path99 from "node:path";
|
|
73921
74037
|
import { existsSync as existsSync65, readFileSync as readFileSync48, readdirSync as readdirSync13 } from "node:fs";
|
|
73922
74038
|
async function collectInspectReport(cwd = process.cwd()) {
|
|
73923
74039
|
ensureBuiltinSkillsLoadedSync();
|
|
73924
74040
|
const snap = listSkillsSnapshot(cwd);
|
|
73925
74041
|
const mcp = listMcpServers(cwd);
|
|
73926
|
-
const userMcpPath =
|
|
73927
|
-
const projectMcpPath =
|
|
74042
|
+
const userMcpPath = path99.join(zelariHome(), "mcp.json");
|
|
74043
|
+
const projectMcpPath = path99.join(cwd, ".zelari", "mcp.json");
|
|
73928
74044
|
const globalHooks = globalHooksDir();
|
|
73929
74045
|
const projectHooks = projectHooksDir(cwd);
|
|
73930
74046
|
const projectTrusted = isFolderTrusted(cwd);
|
|
@@ -73952,9 +74068,9 @@ async function collectInspectReport(cwd = process.cwd()) {
|
|
|
73952
74068
|
configSources: [
|
|
73953
74069
|
{ path: userMcpPath, exists: existsSync65(userMcpPath) },
|
|
73954
74070
|
{ path: projectMcpPath, exists: existsSync65(projectMcpPath) },
|
|
73955
|
-
{ path:
|
|
73956
|
-
{ path:
|
|
73957
|
-
{ path:
|
|
74071
|
+
{ path: path99.join(zelariHome(), "provider.json"), exists: existsSync65(path99.join(zelariHome(), "provider.json")) },
|
|
74072
|
+
{ path: path99.join(cwd, ".zelari", "AGENTS.md"), exists: existsSync65(path99.join(cwd, ".zelari", "AGENTS.md")) },
|
|
74073
|
+
{ path: path99.join(cwd, "AGENTS.md"), exists: existsSync65(path99.join(cwd, "AGENTS.md")) }
|
|
73958
74074
|
],
|
|
73959
74075
|
skills: {
|
|
73960
74076
|
total: snap.skills.length,
|
|
@@ -73994,8 +74110,8 @@ function listJsonFiles(dir) {
|
|
|
73994
74110
|
}
|
|
73995
74111
|
function findAgentsMd(cwd) {
|
|
73996
74112
|
const candidates = [
|
|
73997
|
-
|
|
73998
|
-
|
|
74113
|
+
path99.join(cwd, "AGENTS.md"),
|
|
74114
|
+
path99.join(cwd, ".zelari", "AGENTS.md")
|
|
73999
74115
|
];
|
|
74000
74116
|
const found = [];
|
|
74001
74117
|
for (const c of candidates) {
|
|
@@ -79250,10 +79366,10 @@ init_ledger();
|
|
|
79250
79366
|
|
|
79251
79367
|
// src/cli/evolution/proposals.ts
|
|
79252
79368
|
import { existsSync as existsSync51, readFileSync as readFileSync39 } from "node:fs";
|
|
79253
|
-
import
|
|
79254
|
-
var PROPOSALS_REL =
|
|
79369
|
+
import path77 from "node:path";
|
|
79370
|
+
var PROPOSALS_REL = path77.join(".zelari", "evolution", "proposals.jsonl");
|
|
79255
79371
|
function proposalsPath(cwd) {
|
|
79256
|
-
return
|
|
79372
|
+
return path77.join(cwd, PROPOSALS_REL);
|
|
79257
79373
|
}
|
|
79258
79374
|
function readProposalStore(cwd) {
|
|
79259
79375
|
const file2 = proposalsPath(cwd);
|
|
@@ -80345,11 +80461,11 @@ function handleCacheStats(ctx) {
|
|
|
80345
80461
|
init_messageHelpers();
|
|
80346
80462
|
init_serviceFactory();
|
|
80347
80463
|
import { promises as fs35 } from "node:fs";
|
|
80348
|
-
import * as
|
|
80464
|
+
import * as path79 from "node:path";
|
|
80349
80465
|
|
|
80350
80466
|
// src/cli/memory/promotion.ts
|
|
80351
80467
|
import { promises as fs34 } from "node:fs";
|
|
80352
|
-
import * as
|
|
80468
|
+
import * as path78 from "node:path";
|
|
80353
80469
|
var START = "<!-- zelari:memory-promotions:start -->";
|
|
80354
80470
|
var END = "<!-- zelari:memory-promotions:end -->";
|
|
80355
80471
|
var DURABLE_KINDS = /* @__PURE__ */ new Set(["fact", "decision", "constraint", "preference", "procedure"]);
|
|
@@ -80360,16 +80476,16 @@ function lineFor(node) {
|
|
|
80360
80476
|
}
|
|
80361
80477
|
async function promoteMemoryToAgentsMd(projectRoot, node) {
|
|
80362
80478
|
if (node.status !== "active") {
|
|
80363
|
-
return { added: false, path:
|
|
80479
|
+
return { added: false, path: path78.join(projectRoot, "AGENTS.md"), reason: `memory is ${node.status}` };
|
|
80364
80480
|
}
|
|
80365
80481
|
if (!DURABLE_KINDS.has(node.kind)) {
|
|
80366
|
-
return { added: false, path:
|
|
80482
|
+
return { added: false, path: path78.join(projectRoot, "AGENTS.md"), reason: `${node.kind} is not a durable instruction kind` };
|
|
80367
80483
|
}
|
|
80368
|
-
const root = await fs34.realpath(projectRoot).catch(() =>
|
|
80369
|
-
const target =
|
|
80484
|
+
const root = await fs34.realpath(projectRoot).catch(() => path78.resolve(projectRoot));
|
|
80485
|
+
const target = path78.join(root, "AGENTS.md");
|
|
80370
80486
|
try {
|
|
80371
|
-
const
|
|
80372
|
-
if (
|
|
80487
|
+
const stat8 = await fs34.lstat(target);
|
|
80488
|
+
if (stat8.isSymbolicLink() || !stat8.isFile()) throw new Error("AGENTS.md must be a regular project file.");
|
|
80373
80489
|
} catch (error51) {
|
|
80374
80490
|
if (error51.code !== "ENOENT") throw error51;
|
|
80375
80491
|
}
|
|
@@ -80431,25 +80547,25 @@ function sourceLine(source2) {
|
|
|
80431
80547
|
return entries.length ? entries.map(([key, value]) => `${key}=${value}`).join(" \xB7 ") : "unknown";
|
|
80432
80548
|
}
|
|
80433
80549
|
function isInside(root, target) {
|
|
80434
|
-
const relative6 =
|
|
80435
|
-
return relative6 === "" || !relative6.startsWith("..") && !
|
|
80550
|
+
const relative6 = path79.relative(root, target);
|
|
80551
|
+
return relative6 === "" || !relative6.startsWith("..") && !path79.isAbsolute(relative6);
|
|
80436
80552
|
}
|
|
80437
80553
|
async function safeExportPath(cwd, requested) {
|
|
80438
|
-
const lexicalRoot =
|
|
80554
|
+
const lexicalRoot = path79.resolve(cwd);
|
|
80439
80555
|
const root = await fs35.realpath(lexicalRoot).catch(() => lexicalRoot);
|
|
80440
|
-
const fallback =
|
|
80441
|
-
const target = requested?.trim() ?
|
|
80556
|
+
const fallback = path79.join(root, ".zelari", "memory", `export-${Date.now()}.json`);
|
|
80557
|
+
const target = requested?.trim() ? path79.resolve(root, requested.trim()) : fallback;
|
|
80442
80558
|
if (!isInside(root, target)) {
|
|
80443
80559
|
throw new Error("Export path must stay inside the active project.");
|
|
80444
80560
|
}
|
|
80445
|
-
const parent =
|
|
80446
|
-
const relativeParent =
|
|
80561
|
+
const parent = path79.dirname(target);
|
|
80562
|
+
const relativeParent = path79.relative(root, parent);
|
|
80447
80563
|
let cursor = root;
|
|
80448
|
-
for (const segment of relativeParent.split(
|
|
80449
|
-
cursor =
|
|
80564
|
+
for (const segment of relativeParent.split(path79.sep).filter(Boolean)) {
|
|
80565
|
+
cursor = path79.join(cursor, segment);
|
|
80450
80566
|
try {
|
|
80451
|
-
const
|
|
80452
|
-
if (
|
|
80567
|
+
const stat8 = await fs35.lstat(cursor);
|
|
80568
|
+
if (stat8.isSymbolicLink()) {
|
|
80453
80569
|
throw new Error("Export path must not traverse a symbolic link.");
|
|
80454
80570
|
}
|
|
80455
80571
|
} catch (error51) {
|
|
@@ -80618,9 +80734,9 @@ ${message}` : message
|
|
|
80618
80734
|
}
|
|
80619
80735
|
case "export": {
|
|
80620
80736
|
const target = await safeExportPath(ctx.cwd, args.join(" ").trim() || void 0);
|
|
80621
|
-
await fs35.mkdir(
|
|
80622
|
-
const root = await fs35.realpath(ctx.cwd).catch(() =>
|
|
80623
|
-
const realParent = await fs35.realpath(
|
|
80737
|
+
await fs35.mkdir(path79.dirname(target), { recursive: true });
|
|
80738
|
+
const root = await fs35.realpath(ctx.cwd).catch(() => path79.resolve(ctx.cwd));
|
|
80739
|
+
const realParent = await fs35.realpath(path79.dirname(target));
|
|
80624
80740
|
if (!isInside(root, realParent)) {
|
|
80625
80741
|
throw new Error("Export path resolves outside the active project.");
|
|
80626
80742
|
}
|
|
@@ -80835,7 +80951,7 @@ import { promises as fs37 } from "node:fs";
|
|
|
80835
80951
|
init_zod();
|
|
80836
80952
|
init_taskTool();
|
|
80837
80953
|
import { promises as fs36 } from "node:fs";
|
|
80838
|
-
import
|
|
80954
|
+
import path80 from "node:path";
|
|
80839
80955
|
import { randomBytes as randomBytes6 } from "node:crypto";
|
|
80840
80956
|
var CsvFanoutArgsSchema = external_exports.object({
|
|
80841
80957
|
csv_path: external_exports.string().min(1),
|
|
@@ -80929,8 +81045,8 @@ function resolveMaxConcurrency(env = process.env) {
|
|
|
80929
81045
|
}
|
|
80930
81046
|
async function runCsvFanout(args, deps, opts) {
|
|
80931
81047
|
const start = Date.now();
|
|
80932
|
-
const absCsv =
|
|
80933
|
-
const absOut =
|
|
81048
|
+
const absCsv = path80.isAbsolute(args.csv_path) ? args.csv_path : path80.join(opts.parentCwd, args.csv_path);
|
|
81049
|
+
const absOut = path80.isAbsolute(args.output_csv_path) ? args.output_csv_path : path80.join(opts.parentCwd, args.output_csv_path);
|
|
80934
81050
|
const { headers: headers2, rows } = await readCsv(absCsv);
|
|
80935
81051
|
if (headers2.length === 0) {
|
|
80936
81052
|
throw new Error(`kraken_csv_fanout: ${absCsv} is empty`);
|
|
@@ -80986,7 +81102,7 @@ async function runCsvFanout(args, deps, opts) {
|
|
|
80986
81102
|
errored += 1;
|
|
80987
81103
|
errors.push(`${row[args.id_column] ?? i}: ${res.error}`);
|
|
80988
81104
|
}
|
|
80989
|
-
await fs36.mkdir(
|
|
81105
|
+
await fs36.mkdir(path80.dirname(absOut), { recursive: true });
|
|
80990
81106
|
await queueWrite(serializeCsv(outHeaders, outputRecords));
|
|
80991
81107
|
}
|
|
80992
81108
|
}
|
|
@@ -81181,7 +81297,7 @@ function splitArgs(s) {
|
|
|
81181
81297
|
// src/cli/slashHandlers/krakenWorkbench.ts
|
|
81182
81298
|
init_messageHelpers();
|
|
81183
81299
|
import { promises as fs38 } from "node:fs";
|
|
81184
|
-
import
|
|
81300
|
+
import path81 from "node:path";
|
|
81185
81301
|
|
|
81186
81302
|
// src/cli/kraken/workbenchView.ts
|
|
81187
81303
|
var EMPTY = {
|
|
@@ -81298,17 +81414,17 @@ function formatWorkbenchForTerminal(p3) {
|
|
|
81298
81414
|
|
|
81299
81415
|
// src/cli/slashHandlers/krakenWorkbench.ts
|
|
81300
81416
|
async function handleKrakenWorkbench(ctx) {
|
|
81301
|
-
const dir =
|
|
81417
|
+
const dir = path81.join(ctx.cwd, ".zelari", "radio");
|
|
81302
81418
|
let latest = null;
|
|
81303
81419
|
let latestMtime = 0;
|
|
81304
81420
|
try {
|
|
81305
81421
|
const files = await fs38.readdir(dir);
|
|
81306
81422
|
for (const f of files) {
|
|
81307
81423
|
if (!f.startsWith("workbench-") || !f.endsWith(".md")) continue;
|
|
81308
|
-
const full =
|
|
81309
|
-
const
|
|
81310
|
-
if (
|
|
81311
|
-
latestMtime =
|
|
81424
|
+
const full = path81.join(dir, f);
|
|
81425
|
+
const stat8 = await fs38.stat(full);
|
|
81426
|
+
if (stat8.mtimeMs > latestMtime) {
|
|
81427
|
+
latestMtime = stat8.mtimeMs;
|
|
81312
81428
|
latest = full;
|
|
81313
81429
|
}
|
|
81314
81430
|
}
|
|
@@ -81322,10 +81438,10 @@ async function handleKrakenWorkbench(ctx) {
|
|
|
81322
81438
|
const parsed = parseWorkbench(content);
|
|
81323
81439
|
const rendered = formatWorkbenchForTerminal(parsed);
|
|
81324
81440
|
if (!rendered.trim()) {
|
|
81325
|
-
appendSystem(ctx.setMessages, `[kraken workbench] ${
|
|
81441
|
+
appendSystem(ctx.setMessages, `[kraken workbench] ${path81.basename(latest)}: (no nodes / no events yet)`);
|
|
81326
81442
|
return;
|
|
81327
81443
|
}
|
|
81328
|
-
appendSystem(ctx.setMessages, `[kraken workbench] ${
|
|
81444
|
+
appendSystem(ctx.setMessages, `[kraken workbench] ${path81.basename(latest)}:
|
|
81329
81445
|
${rendered}`);
|
|
81330
81446
|
}
|
|
81331
81447
|
|
|
@@ -81633,14 +81749,14 @@ ${result.output.split("\n").slice(-8).join("\n")}` : "";
|
|
|
81633
81749
|
init_messageHelpers();
|
|
81634
81750
|
init_paths();
|
|
81635
81751
|
import { promises as fs39 } from "node:fs";
|
|
81636
|
-
import
|
|
81752
|
+
import path84 from "node:path";
|
|
81637
81753
|
async function handlePromoteMember(ctx, memberId) {
|
|
81638
81754
|
try {
|
|
81639
81755
|
const { promoteMember: promoteMember2 } = await Promise.resolve().then(() => (init_council(), council_exports));
|
|
81640
81756
|
const { skill, markdown } = promoteMember2(memberId);
|
|
81641
81757
|
const skillDir = skillsDir();
|
|
81642
81758
|
await fs39.mkdir(skillDir, { recursive: true });
|
|
81643
|
-
const filePath =
|
|
81759
|
+
const filePath = path84.join(skillDir, `${skill.id}.md`);
|
|
81644
81760
|
const previous = await fs39.readFile(filePath, "utf8").catch(() => null);
|
|
81645
81761
|
const { createHash: createHash24 } = await import("node:crypto");
|
|
81646
81762
|
const sha = (s) => createHash24("sha256").update(s, "utf8").digest("hex");
|
|
@@ -81666,7 +81782,7 @@ ${lineage}
|
|
|
81666
81782
|
// src/cli/branchManager.ts
|
|
81667
81783
|
init_paths();
|
|
81668
81784
|
import { promises as fs40, existsSync as existsSync55, readFileSync as readFileSync41, writeFileSync as writeFileSync24, mkdirSync as mkdirSync21, statSync as statSync7, rmSync as rmSync3 } from "node:fs";
|
|
81669
|
-
import
|
|
81785
|
+
import path85 from "node:path";
|
|
81670
81786
|
var META_FILENAME = "meta.json";
|
|
81671
81787
|
var SESSIONS_SUBDIR = "sessions";
|
|
81672
81788
|
function getBranchesBaseDir() {
|
|
@@ -81676,13 +81792,13 @@ function getSessionsBaseDir() {
|
|
|
81676
81792
|
return sessionsDir();
|
|
81677
81793
|
}
|
|
81678
81794
|
function branchPathFor(name, baseDir) {
|
|
81679
|
-
return
|
|
81795
|
+
return path85.join(baseDir, name);
|
|
81680
81796
|
}
|
|
81681
81797
|
function metaPathFor(name, baseDir) {
|
|
81682
|
-
return
|
|
81798
|
+
return path85.join(baseDir, name, META_FILENAME);
|
|
81683
81799
|
}
|
|
81684
81800
|
function sessionsPathFor(name, baseDir) {
|
|
81685
|
-
return
|
|
81801
|
+
return path85.join(baseDir, name, SESSIONS_SUBDIR);
|
|
81686
81802
|
}
|
|
81687
81803
|
function readBranchMeta(name, baseDir) {
|
|
81688
81804
|
const metaPath = metaPathFor(name, baseDir);
|
|
@@ -81707,7 +81823,7 @@ function readBranchMeta(name, baseDir) {
|
|
|
81707
81823
|
}
|
|
81708
81824
|
function writeBranchMeta(name, baseDir, meta3) {
|
|
81709
81825
|
const metaPath = metaPathFor(name, baseDir);
|
|
81710
|
-
mkdirSync21(
|
|
81826
|
+
mkdirSync21(path85.dirname(metaPath), { recursive: true });
|
|
81711
81827
|
writeFileSync24(metaPath, JSON.stringify(meta3, null, 2), "utf-8");
|
|
81712
81828
|
}
|
|
81713
81829
|
async function countSessions(name, baseDir) {
|
|
@@ -81758,14 +81874,14 @@ async function createBranch(name, fromSessionId, baseDir = getBranchesBaseDir(),
|
|
|
81758
81874
|
if (branchExists(name, baseDir)) {
|
|
81759
81875
|
throw new BranchAlreadyExistsError(name);
|
|
81760
81876
|
}
|
|
81761
|
-
const sourcePath =
|
|
81877
|
+
const sourcePath = path85.join(sessionsBaseDir, `${fromSessionId}.jsonl`);
|
|
81762
81878
|
if (!existsSync55(sourcePath)) {
|
|
81763
81879
|
throw new SessionNotFoundError(`Source session "${fromSessionId}" not found at ${sourcePath}`);
|
|
81764
81880
|
}
|
|
81765
81881
|
const branchPath = branchPathFor(name, baseDir);
|
|
81766
81882
|
const branchSessionsPath = sessionsPathFor(name, baseDir);
|
|
81767
81883
|
mkdirSync21(branchSessionsPath, { recursive: true });
|
|
81768
|
-
const destPath =
|
|
81884
|
+
const destPath = path85.join(branchSessionsPath, `${fromSessionId}.jsonl`);
|
|
81769
81885
|
await fs40.copyFile(sourcePath, destPath);
|
|
81770
81886
|
const meta3 = {
|
|
81771
81887
|
name,
|
|
@@ -81869,14 +81985,14 @@ async function handleBranchCheckout(ctx, branchName) {
|
|
|
81869
81985
|
// src/cli/slashHandlers/workspace.ts
|
|
81870
81986
|
init_messageHelpers();
|
|
81871
81987
|
import { promises as fs41 } from "node:fs";
|
|
81872
|
-
import
|
|
81988
|
+
import path86 from "node:path";
|
|
81873
81989
|
async function handleWorkspaceShow(ctx, what) {
|
|
81874
81990
|
try {
|
|
81875
|
-
const zelari =
|
|
81991
|
+
const zelari = path86.join(process.cwd(), ".zelari");
|
|
81876
81992
|
let content;
|
|
81877
81993
|
switch (what) {
|
|
81878
81994
|
case "plan": {
|
|
81879
|
-
const planPath =
|
|
81995
|
+
const planPath = path86.join(zelari, "plan.md");
|
|
81880
81996
|
try {
|
|
81881
81997
|
content = await fs41.readFile(planPath, "utf-8");
|
|
81882
81998
|
} catch {
|
|
@@ -81885,7 +82001,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
81885
82001
|
break;
|
|
81886
82002
|
}
|
|
81887
82003
|
case "decisions": {
|
|
81888
|
-
const decisionsDir =
|
|
82004
|
+
const decisionsDir = path86.join(zelari, "decisions");
|
|
81889
82005
|
try {
|
|
81890
82006
|
const files = (await fs41.readdir(decisionsDir)).filter((f) => f.endsWith(".md")).sort();
|
|
81891
82007
|
if (files.length === 0) {
|
|
@@ -81895,7 +82011,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
81895
82011
|
`];
|
|
81896
82012
|
const { parseFrontmatter: parseFrontmatter2 } = await Promise.resolve().then(() => (init_storage(), storage_exports));
|
|
81897
82013
|
for (const f of files) {
|
|
81898
|
-
const raw = await fs41.readFile(
|
|
82014
|
+
const raw = await fs41.readFile(path86.join(decisionsDir, f), "utf-8");
|
|
81899
82015
|
const { meta: meta3, body } = parseFrontmatter2(raw);
|
|
81900
82016
|
const title = meta3.title ?? body.split("\n")[0]?.replace(/^#\s*/, "").trim() ?? f;
|
|
81901
82017
|
lines.push(`- **${f.replace(/\.md$/, "")}** [${meta3.status ?? "unknown"}] ${title}`);
|
|
@@ -81908,7 +82024,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
81908
82024
|
break;
|
|
81909
82025
|
}
|
|
81910
82026
|
case "risks": {
|
|
81911
|
-
const risksPath =
|
|
82027
|
+
const risksPath = path86.join(zelari, "risks.md");
|
|
81912
82028
|
try {
|
|
81913
82029
|
content = await fs41.readFile(risksPath, "utf-8");
|
|
81914
82030
|
} catch {
|
|
@@ -81917,7 +82033,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
81917
82033
|
break;
|
|
81918
82034
|
}
|
|
81919
82035
|
case "agents": {
|
|
81920
|
-
const agentsPath =
|
|
82036
|
+
const agentsPath = path86.join(process.cwd(), "AGENTS.MD");
|
|
81921
82037
|
try {
|
|
81922
82038
|
content = await fs41.readFile(agentsPath, "utf-8");
|
|
81923
82039
|
} catch {
|
|
@@ -81926,7 +82042,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
81926
82042
|
break;
|
|
81927
82043
|
}
|
|
81928
82044
|
case "docs": {
|
|
81929
|
-
const docsDir =
|
|
82045
|
+
const docsDir = path86.join(zelari, "docs");
|
|
81930
82046
|
try {
|
|
81931
82047
|
const files = (await fs41.readdir(docsDir)).filter((f) => f.endsWith(".md")).sort();
|
|
81932
82048
|
content = files.length ? `# Docs (${files.length})
|
|
@@ -81968,7 +82084,7 @@ async function handleWorkspaceReset(ctx, force) {
|
|
|
81968
82084
|
return;
|
|
81969
82085
|
}
|
|
81970
82086
|
try {
|
|
81971
|
-
const target =
|
|
82087
|
+
const target = path86.join(process.cwd(), ".zelari");
|
|
81972
82088
|
await fs41.rm(target, { recursive: true, force: true });
|
|
81973
82089
|
appendSystem(ctx.setMessages, "[workspace] .zelari/ removed");
|
|
81974
82090
|
} catch (err) {
|
|
@@ -83851,8 +83967,8 @@ function normalizeDraft(raw, sourceUrl, provider, model) {
|
|
|
83851
83967
|
let name = String(o.name ?? "").trim().toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64);
|
|
83852
83968
|
if (!name || !/^[a-z0-9][a-z0-9-]{0,63}$/.test(name)) {
|
|
83853
83969
|
try {
|
|
83854
|
-
const
|
|
83855
|
-
name =
|
|
83970
|
+
const path100 = new URL(sourceUrl).pathname.split("/").filter(Boolean).pop()?.replace(/\.[a-z0-9]+$/i, "").toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48);
|
|
83971
|
+
name = path100 && /^[a-z0-9]/.test(path100) ? path100 : "imported-skill";
|
|
83856
83972
|
} catch {
|
|
83857
83973
|
name = "imported-skill";
|
|
83858
83974
|
}
|