zelari-code 2.17.0 → 2.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands/inspectSession.js +86 -0
- package/dist/cli/commands/inspectSession.js.map +1 -0
- package/dist/cli/main.bundled.js +470 -205
- package/dist/cli/main.bundled.js.map +4 -4
- package/dist/cli/main.js +15 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/runHeadless.js +53 -0
- package/dist/cli/runHeadless.js.map +1 -1
- package/dist/cli/sessionSpine.js +32 -0
- package/dist/cli/sessionSpine.js.map +1 -1
- package/package.json +2 -2
package/dist/cli/main.bundled.js
CHANGED
|
@@ -3288,10 +3288,10 @@ function mergeDefs(...defs) {
|
|
|
3288
3288
|
function cloneDef(schema) {
|
|
3289
3289
|
return mergeDefs(schema._zod.def);
|
|
3290
3290
|
}
|
|
3291
|
-
function getElementAtPath(obj,
|
|
3292
|
-
if (!
|
|
3291
|
+
function getElementAtPath(obj, path91) {
|
|
3292
|
+
if (!path91)
|
|
3293
3293
|
return obj;
|
|
3294
|
-
return
|
|
3294
|
+
return path91.reduce((acc, key) => acc?.[key], obj);
|
|
3295
3295
|
}
|
|
3296
3296
|
function promiseAllObject(promisesObj) {
|
|
3297
3297
|
const keys = Object.keys(promisesObj);
|
|
@@ -3619,11 +3619,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
3619
3619
|
}
|
|
3620
3620
|
return false;
|
|
3621
3621
|
}
|
|
3622
|
-
function prefixIssues(
|
|
3622
|
+
function prefixIssues(path91, issues) {
|
|
3623
3623
|
return issues.map((iss) => {
|
|
3624
3624
|
var _a3;
|
|
3625
3625
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
3626
|
-
iss.path.unshift(
|
|
3626
|
+
iss.path.unshift(path91);
|
|
3627
3627
|
return iss;
|
|
3628
3628
|
});
|
|
3629
3629
|
}
|
|
@@ -3841,16 +3841,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
3841
3841
|
}
|
|
3842
3842
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
3843
3843
|
const fieldErrors = { _errors: [] };
|
|
3844
|
-
const processError = (error52,
|
|
3844
|
+
const processError = (error52, path91 = []) => {
|
|
3845
3845
|
for (const issue2 of error52.issues) {
|
|
3846
3846
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
3847
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
3847
|
+
issue2.errors.map((issues) => processError({ issues }, [...path91, ...issue2.path]));
|
|
3848
3848
|
} else if (issue2.code === "invalid_key") {
|
|
3849
|
-
processError({ issues: issue2.issues }, [...
|
|
3849
|
+
processError({ issues: issue2.issues }, [...path91, ...issue2.path]);
|
|
3850
3850
|
} else if (issue2.code === "invalid_element") {
|
|
3851
|
-
processError({ issues: issue2.issues }, [...
|
|
3851
|
+
processError({ issues: issue2.issues }, [...path91, ...issue2.path]);
|
|
3852
3852
|
} else {
|
|
3853
|
-
const fullpath = [...
|
|
3853
|
+
const fullpath = [...path91, ...issue2.path];
|
|
3854
3854
|
if (fullpath.length === 0) {
|
|
3855
3855
|
fieldErrors._errors.push(mapper(issue2));
|
|
3856
3856
|
} else {
|
|
@@ -3877,17 +3877,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
3877
3877
|
}
|
|
3878
3878
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
3879
3879
|
const result = { errors: [] };
|
|
3880
|
-
const processError = (error52,
|
|
3880
|
+
const processError = (error52, path91 = []) => {
|
|
3881
3881
|
var _a3, _b;
|
|
3882
3882
|
for (const issue2 of error52.issues) {
|
|
3883
3883
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
3884
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
3884
|
+
issue2.errors.map((issues) => processError({ issues }, [...path91, ...issue2.path]));
|
|
3885
3885
|
} else if (issue2.code === "invalid_key") {
|
|
3886
|
-
processError({ issues: issue2.issues }, [...
|
|
3886
|
+
processError({ issues: issue2.issues }, [...path91, ...issue2.path]);
|
|
3887
3887
|
} else if (issue2.code === "invalid_element") {
|
|
3888
|
-
processError({ issues: issue2.issues }, [...
|
|
3888
|
+
processError({ issues: issue2.issues }, [...path91, ...issue2.path]);
|
|
3889
3889
|
} else {
|
|
3890
|
-
const fullpath = [...
|
|
3890
|
+
const fullpath = [...path91, ...issue2.path];
|
|
3891
3891
|
if (fullpath.length === 0) {
|
|
3892
3892
|
result.errors.push(mapper(issue2));
|
|
3893
3893
|
continue;
|
|
@@ -3919,8 +3919,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
3919
3919
|
}
|
|
3920
3920
|
function toDotPath(_path) {
|
|
3921
3921
|
const segs = [];
|
|
3922
|
-
const
|
|
3923
|
-
for (const seg of
|
|
3922
|
+
const path91 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
3923
|
+
for (const seg of path91) {
|
|
3924
3924
|
if (typeof seg === "number")
|
|
3925
3925
|
segs.push(`[${seg}]`);
|
|
3926
3926
|
else if (typeof seg === "symbol")
|
|
@@ -17423,13 +17423,13 @@ function resolveRef(ref, ctx) {
|
|
|
17423
17423
|
if (!ref.startsWith("#")) {
|
|
17424
17424
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
17425
17425
|
}
|
|
17426
|
-
const
|
|
17427
|
-
if (
|
|
17426
|
+
const path91 = ref.slice(1).split("/").filter(Boolean);
|
|
17427
|
+
if (path91.length === 0) {
|
|
17428
17428
|
return ctx.rootSchema;
|
|
17429
17429
|
}
|
|
17430
17430
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
17431
|
-
if (
|
|
17432
|
-
const key =
|
|
17431
|
+
if (path91[0] === defsKey) {
|
|
17432
|
+
const key = path91[1];
|
|
17433
17433
|
if (!key || !ctx.defs[key]) {
|
|
17434
17434
|
throw new Error(`Reference not found: ${ref}`);
|
|
17435
17435
|
}
|
|
@@ -18777,11 +18777,18 @@ function filterByInclude(entries, include) {
|
|
|
18777
18777
|
if (include.length === 0 || include.length === 1 && include[0] === "*") {
|
|
18778
18778
|
return entries.filter((e) => e.type === "file");
|
|
18779
18779
|
}
|
|
18780
|
-
const
|
|
18780
|
+
const pathRegexes = [];
|
|
18781
|
+
const baseRegexes = [];
|
|
18782
|
+
for (const g of include) {
|
|
18783
|
+
(g.includes("/") || g.includes("**") ? pathRegexes : baseRegexes).push(globToRegex(g));
|
|
18784
|
+
}
|
|
18781
18785
|
return entries.filter((e) => {
|
|
18782
18786
|
if (e.type !== "file")
|
|
18783
18787
|
return false;
|
|
18784
|
-
|
|
18788
|
+
if (pathRegexes.some((re) => re.test(e.name)))
|
|
18789
|
+
return true;
|
|
18790
|
+
const base2 = e.name.slice(e.name.lastIndexOf("/") + 1);
|
|
18791
|
+
return baseRegexes.some((re) => re.test(base2));
|
|
18785
18792
|
});
|
|
18786
18793
|
}
|
|
18787
18794
|
var REGEX_ESCAPE, DEFAULT_EXCLUDES;
|
|
@@ -18828,8 +18835,8 @@ function coerceStringList(value, fallback) {
|
|
|
18828
18835
|
}
|
|
18829
18836
|
return fallback;
|
|
18830
18837
|
}
|
|
18831
|
-
function
|
|
18832
|
-
return include.some((g) => g.includes("**"));
|
|
18838
|
+
function hasPathAnchoredGlob(include) {
|
|
18839
|
+
return include.some((g) => g.includes("/") || g.includes("**"));
|
|
18833
18840
|
}
|
|
18834
18841
|
function scopeWarnings(allEntries, include, matched) {
|
|
18835
18842
|
const warnings = [];
|
|
@@ -18837,15 +18844,17 @@ function scopeWarnings(allEntries, include, matched) {
|
|
|
18837
18844
|
if (filesWalked === 0)
|
|
18838
18845
|
return warnings;
|
|
18839
18846
|
if (matched === 0) {
|
|
18840
|
-
|
|
18847
|
+
const cause = hasPathAnchoredGlob(include) ? `path-anchored globs (with '/') match the relative path at exactly that level; use '**/<glob>' for recursive matching` : `flat globs ('*.ts') match the basename at any depth, so no file with these names/extensions exists in the walked tree`;
|
|
18848
|
+
warnings.push(`SEARCH_EMPTY_SCOPE: include globs matched 0 of ${filesWalked} files walked \u2014 ${cause}. Do not interpret this result as "pattern not found".`);
|
|
18841
18849
|
return warnings;
|
|
18842
18850
|
}
|
|
18843
|
-
if (
|
|
18851
|
+
if (!hasPathAnchoredGlob(include) || matched >= filesWalked)
|
|
18844
18852
|
return warnings;
|
|
18845
|
-
const
|
|
18853
|
+
const anchored = include.filter((g) => g.includes("/") || g.includes("**"));
|
|
18854
|
+
const recursiveRegexes = compileGlobs(anchored.map((g) => `**/${g}`));
|
|
18846
18855
|
const wouldMatch = allEntries.filter((e) => e.type === "file" && matchesAnyCompiled(e.name, recursiveRegexes)).length;
|
|
18847
18856
|
if (wouldMatch > matched) {
|
|
18848
|
-
warnings.push(`include globs matched ${matched} of ${filesWalked} files walked \u2014 '
|
|
18857
|
+
warnings.push(`include globs matched ${matched} of ${filesWalked} files walked \u2014 a path-anchored glob ('${anchored[0]}') matches only that exact level; a '**/${anchored[0]}'-style recursive glob would have matched ${wouldMatch - matched} more file(s) in subdirectories`);
|
|
18849
18858
|
}
|
|
18850
18859
|
return warnings;
|
|
18851
18860
|
}
|
|
@@ -18912,7 +18921,10 @@ var init_search = __esm({
|
|
|
18912
18921
|
/**
|
|
18913
18922
|
* Glob pattern(s) to INCLUDE when path is a directory.
|
|
18914
18923
|
* Accepts a string OR string[] (models often emit a bare string).
|
|
18915
|
-
*
|
|
18924
|
+
* A glob without '/' (e.g. '*.ts') matches the file basename at any depth
|
|
18925
|
+
* (grep --include style); a glob with '/' (e.g. 'src/*.ts') matches the
|
|
18926
|
+
* relative path at exactly that level. Default ['*'] = all files.
|
|
18927
|
+
* Ignored when path is a file.
|
|
18916
18928
|
*/
|
|
18917
18929
|
include: stringOrStringArray.optional().default(["*"]),
|
|
18918
18930
|
/**
|
|
@@ -18925,7 +18937,7 @@ var init_search = __esm({
|
|
|
18925
18937
|
});
|
|
18926
18938
|
grepContentTool = {
|
|
18927
18939
|
name: "grep_content",
|
|
18928
|
-
description:
|
|
18940
|
+
description: `Regex search for content in a file OR recursively in a directory. When path is a directory, include/exclude globs filter which files are searched (default: all files, excluding node_modules/dist/.git/etc.). Glob semantics (grep --include style): a glob without '/' (e.g. "*.md") matches the file basename at ANY depth; a glob with '/' (e.g. "src/*.ts") matches the relative path at exactly that level; "**" is explicit recursion ("**/*.ts" matches at any depth, same as the bare form). include/exclude accept a single glob string (e.g. "*.ts") OR an array of globs. Returns matches with line numbers and context, plus filesWalked/filesInTree counts and a warning when the include globs matched suspiciously few files.`,
|
|
18929
18941
|
permissions: ["read"],
|
|
18930
18942
|
sideEffect: "none",
|
|
18931
18943
|
timeoutMs: 3e4,
|
|
@@ -19875,11 +19887,11 @@ var init_tools = __esm({
|
|
|
19875
19887
|
if (!ctx.addDocument)
|
|
19876
19888
|
return "Knowledge vault tool not available.";
|
|
19877
19889
|
const title = args["title"] || "New Document";
|
|
19878
|
-
const
|
|
19890
|
+
const path91 = args["path"] || `notes/${title.toLowerCase().replace(/[^a-z0-9]+/g, "-")}`;
|
|
19879
19891
|
const content = args["content"] || "";
|
|
19880
19892
|
const tags = args["tags"] || [];
|
|
19881
19893
|
ctx.addDocument({
|
|
19882
|
-
path:
|
|
19894
|
+
path: path91,
|
|
19883
19895
|
title,
|
|
19884
19896
|
content,
|
|
19885
19897
|
format: "markdown",
|
|
@@ -19888,7 +19900,7 @@ var init_tools = __esm({
|
|
|
19888
19900
|
workspaceId: ctx.workspaceId
|
|
19889
19901
|
});
|
|
19890
19902
|
ctx.addActivity("vault", "created document", title);
|
|
19891
|
-
return `Document "${title}" created at "${
|
|
19903
|
+
return `Document "${title}" created at "${path91}".`;
|
|
19892
19904
|
}
|
|
19893
19905
|
}
|
|
19894
19906
|
];
|
|
@@ -23096,6 +23108,9 @@ var init_ObserverBus = __esm({
|
|
|
23096
23108
|
});
|
|
23097
23109
|
|
|
23098
23110
|
// packages/core/dist/core/AgentHarness.js
|
|
23111
|
+
function gateAdvice(hardLimit) {
|
|
23112
|
+
return hardLimit ? "Finalize now with the evidence already collected; no further tool calls will run this turn." : "Prioritize verification/repair actions (test, typecheck, build, read failures) or finalize honestly.";
|
|
23113
|
+
}
|
|
23099
23114
|
function hashToolCall(toolName, args) {
|
|
23100
23115
|
const canonical = stableStringify2(args);
|
|
23101
23116
|
return `${toolName}::${canonical}`;
|
|
@@ -23127,10 +23142,18 @@ function normalizeTextToolArgs(name, args) {
|
|
|
23127
23142
|
}
|
|
23128
23143
|
return out;
|
|
23129
23144
|
}
|
|
23130
|
-
function
|
|
23145
|
+
function parseTextToolCallsDetailed(text) {
|
|
23146
|
+
let truncatedBlock = false;
|
|
23147
|
+
let rawBody = null;
|
|
23131
23148
|
const m = /---TOOLS---\s*([\s\S]*?)---END---/.exec(text);
|
|
23132
23149
|
if (m?.[1]) {
|
|
23133
|
-
|
|
23150
|
+
rawBody = m[1];
|
|
23151
|
+
} else if (text.includes("---TOOLS---")) {
|
|
23152
|
+
rawBody = text.slice(text.indexOf("---TOOLS---") + "---TOOLS---".length);
|
|
23153
|
+
truncatedBlock = true;
|
|
23154
|
+
}
|
|
23155
|
+
if (rawBody !== null) {
|
|
23156
|
+
let body = rawBody.trim();
|
|
23134
23157
|
body = body.replace(/^```(?:json)?\s*/i, "").replace(/\s*```$/i, "").trim();
|
|
23135
23158
|
const candidates = [body];
|
|
23136
23159
|
if (/\]\s*\[/.test(body)) {
|
|
@@ -23145,7 +23168,7 @@ function parseTextToolCalls(text) {
|
|
|
23145
23168
|
for (const cand of candidates) {
|
|
23146
23169
|
const items = tryParseToolArray(cand);
|
|
23147
23170
|
if (items.length > 0)
|
|
23148
|
-
return items;
|
|
23171
|
+
return { calls: items, truncatedBlock };
|
|
23149
23172
|
}
|
|
23150
23173
|
const arrays = extractJsonArrays(body);
|
|
23151
23174
|
if (arrays.length > 1) {
|
|
@@ -23154,16 +23177,19 @@ function parseTextToolCalls(text) {
|
|
|
23154
23177
|
merged.push(...tryParseToolArray(a));
|
|
23155
23178
|
}
|
|
23156
23179
|
if (merged.length > 0)
|
|
23157
|
-
return merged;
|
|
23180
|
+
return { calls: merged, truncatedBlock };
|
|
23158
23181
|
}
|
|
23159
23182
|
const objs = extractToolObjects(body);
|
|
23160
23183
|
if (objs.length > 0)
|
|
23161
|
-
return objs;
|
|
23184
|
+
return { calls: objs, truncatedBlock };
|
|
23162
23185
|
}
|
|
23163
23186
|
const mini = parseMinimaxStyleToolCalls(text);
|
|
23164
23187
|
if (mini.length > 0)
|
|
23165
|
-
return mini;
|
|
23166
|
-
return [];
|
|
23188
|
+
return { calls: mini, truncatedBlock };
|
|
23189
|
+
return { calls: [], truncatedBlock };
|
|
23190
|
+
}
|
|
23191
|
+
function parseTextToolCalls(text) {
|
|
23192
|
+
return parseTextToolCallsDetailed(text).calls;
|
|
23167
23193
|
}
|
|
23168
23194
|
function parseMinimaxStyleToolCalls(text) {
|
|
23169
23195
|
const out = [];
|
|
@@ -23310,25 +23336,63 @@ function extractJsonArrays(text) {
|
|
|
23310
23336
|
}
|
|
23311
23337
|
return out;
|
|
23312
23338
|
}
|
|
23339
|
+
function findBalancedBrace(text, openIdx) {
|
|
23340
|
+
let depth = 0;
|
|
23341
|
+
let inStr = false;
|
|
23342
|
+
let esc2 = false;
|
|
23343
|
+
for (let j = openIdx; j < text.length; j++) {
|
|
23344
|
+
const c = text[j];
|
|
23345
|
+
if (inStr) {
|
|
23346
|
+
if (esc2)
|
|
23347
|
+
esc2 = false;
|
|
23348
|
+
else if (c === "\\")
|
|
23349
|
+
esc2 = true;
|
|
23350
|
+
else if (c === '"')
|
|
23351
|
+
inStr = false;
|
|
23352
|
+
continue;
|
|
23353
|
+
}
|
|
23354
|
+
if (c === '"') {
|
|
23355
|
+
inStr = true;
|
|
23356
|
+
continue;
|
|
23357
|
+
}
|
|
23358
|
+
if (c === "{")
|
|
23359
|
+
depth++;
|
|
23360
|
+
else if (c === "}") {
|
|
23361
|
+
depth--;
|
|
23362
|
+
if (depth === 0)
|
|
23363
|
+
return j;
|
|
23364
|
+
}
|
|
23365
|
+
}
|
|
23366
|
+
return -1;
|
|
23367
|
+
}
|
|
23313
23368
|
function extractToolObjects(text) {
|
|
23314
23369
|
const out = [];
|
|
23315
|
-
const
|
|
23370
|
+
const headRe = /\{\s*"name"\s*:\s*"([^"]+)"\s*,\s*"args"\s*:\s*/g;
|
|
23316
23371
|
let match;
|
|
23317
|
-
while ((match =
|
|
23372
|
+
while ((match = headRe.exec(text)) !== null) {
|
|
23318
23373
|
const name = match[1];
|
|
23374
|
+
const argsStart = match.index + match[0].length;
|
|
23319
23375
|
let args = {};
|
|
23320
|
-
|
|
23321
|
-
const
|
|
23322
|
-
if (
|
|
23323
|
-
|
|
23376
|
+
if (text[argsStart] === "{") {
|
|
23377
|
+
const end = findBalancedBrace(text, argsStart);
|
|
23378
|
+
if (end === -1)
|
|
23379
|
+
continue;
|
|
23380
|
+
try {
|
|
23381
|
+
const parsed = JSON.parse(text.slice(argsStart, end + 1));
|
|
23382
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
23383
|
+
args = parsed;
|
|
23384
|
+
} else {
|
|
23385
|
+
continue;
|
|
23386
|
+
}
|
|
23387
|
+
} catch {
|
|
23388
|
+
continue;
|
|
23324
23389
|
}
|
|
23325
|
-
} catch {
|
|
23326
23390
|
}
|
|
23327
23391
|
out.push({ name, args });
|
|
23328
23392
|
}
|
|
23329
23393
|
return out;
|
|
23330
23394
|
}
|
|
23331
|
-
var BUILD_LIVENESS_RECOVERY_PROMPT, AgentHarness, DOOM_LOOP_THRESHOLD;
|
|
23395
|
+
var TOOL_CALL_TRUNCATED_RECOVERY_MARKER, TOOL_CALL_TRUNCATED_RECOVERY_USER, TEXT_TOOLS_FAILED_MARKER, TEXT_TOOLS_FAILED_USER, TEXT_TOOLS_PARTIAL_MARKER, TEXT_TOOLS_PARTIAL_USER, BUILD_LIVENESS_RECOVERY_PROMPT, AgentHarness, DOOM_LOOP_THRESHOLD;
|
|
23332
23396
|
var init_AgentHarness = __esm({
|
|
23333
23397
|
"packages/core/dist/core/AgentHarness.js"() {
|
|
23334
23398
|
"use strict";
|
|
@@ -23340,6 +23404,12 @@ var init_AgentHarness = __esm({
|
|
|
23340
23404
|
init_textLoopDetect();
|
|
23341
23405
|
init_ObserverBus();
|
|
23342
23406
|
init_textLoopDetect();
|
|
23407
|
+
TOOL_CALL_TRUNCATED_RECOVERY_MARKER = "[harness] Previous tool call was truncated";
|
|
23408
|
+
TOOL_CALL_TRUNCATED_RECOVERY_USER = `${TOOL_CALL_TRUNCATED_RECOVERY_MARKER} by the provider before completion (finish_reason=tool_calls but no complete tool_call arrived). Retry with a shorter payload or split the work into smaller tool calls.`;
|
|
23409
|
+
TEXT_TOOLS_FAILED_MARKER = "[harness] Your ---TOOLS--- block did not run";
|
|
23410
|
+
TEXT_TOOLS_FAILED_USER = `${TEXT_TOOLS_FAILED_MARKER}: no call parsed (malformed, or truncated by the provider before ---END---). Re-emit the calls with native tool_call, or ONE valid ---TOOLS--- JSON array \u2014 smaller payloads if the block was cut off.`;
|
|
23411
|
+
TEXT_TOOLS_PARTIAL_MARKER = "[harness] Your ---TOOLS--- block was cut off";
|
|
23412
|
+
TEXT_TOOLS_PARTIAL_USER = `${TEXT_TOOLS_PARTIAL_MARKER} by the provider before ---END---: only the complete leading call(s) ran \u2014 the incomplete tail was dropped. Re-emit the remaining work with native tool_call or smaller payloads.`;
|
|
23343
23413
|
BUILD_LIVENESS_RECOVERY_PROMPT = "[build-liveness] The requested task requires an on-disk implementation, but no successful project mutation has occurred yet. Continue working. Inspect only as needed, then make the required change with an available mutating tool. Do not merely describe a patch or claim completion.";
|
|
23344
23414
|
AgentHarness = class {
|
|
23345
23415
|
config;
|
|
@@ -23569,7 +23639,7 @@ var init_AgentHarness = __esm({
|
|
|
23569
23639
|
const gate = this.checkToolCallGate(p3.toolName, p3.args);
|
|
23570
23640
|
if (!gate.allowed) {
|
|
23571
23641
|
return {
|
|
23572
|
-
content: `[resource-gate] ${gate.reason ?? "denied by resource policy"}
|
|
23642
|
+
content: `[resource-gate] ${gate.reason ?? "denied by resource policy"} ` + gateAdvice(gate.hardLimit),
|
|
23573
23643
|
isError: true,
|
|
23574
23644
|
durationMs: 0
|
|
23575
23645
|
};
|
|
@@ -23834,6 +23904,8 @@ ${shared.content}`,
|
|
|
23834
23904
|
return null;
|
|
23835
23905
|
if (this.buildProgress.recoveries >= maxBuildRecoveries)
|
|
23836
23906
|
return null;
|
|
23907
|
+
if (!this.checkToolCallGate("edit_file", {}).allowed)
|
|
23908
|
+
return null;
|
|
23837
23909
|
this.buildProgress.recoveries += 1;
|
|
23838
23910
|
this.config.messages.push({ role: "user", content: BUILD_LIVENESS_RECOVERY_PROMPT });
|
|
23839
23911
|
return {
|
|
@@ -24230,7 +24302,8 @@ ${cached2}`
|
|
|
24230
24302
|
finishRef.value = "stop";
|
|
24231
24303
|
finishRef.clarificationRequested = true;
|
|
24232
24304
|
}
|
|
24233
|
-
const
|
|
24305
|
+
const textParse = clarificationPause ? { calls: [], truncatedBlock: false } : parseTextToolCallsDetailed(turnText);
|
|
24306
|
+
const textTools = textParse.calls;
|
|
24234
24307
|
const toolsToRun = textTools.filter((tt) => {
|
|
24235
24308
|
const key = hashToolCall(tt.name, tt.args);
|
|
24236
24309
|
return !turnToolCalls.some((n) => hashToolCall(n.name, n.args) === key);
|
|
@@ -24238,12 +24311,21 @@ ${cached2}`
|
|
|
24238
24311
|
if (!clarificationPause && (/---TOOLS---/.test(turnText) || /<\/?minimax:tool_call\b/i.test(turnText) || /invoke\s+name\s*=/i.test(turnText) || /\]\s*<\s*\]\s*minimax\s*\[/i.test(turnText)) && textTools.length === 0) {
|
|
24239
24312
|
const parseErr = createBrainEvent("error", this.sessionId, {
|
|
24240
24313
|
severity: "recoverable",
|
|
24241
|
-
message: "Found text-format tool block but parse failed; tool calls were not executed. Prefer native tool_call, or ---TOOLS--- with ONE valid JSON array.",
|
|
24314
|
+
message: textParse.truncatedBlock ? "Found text-format tool block but parse failed; the block is TRUNCATED (no ---END--- marker \u2014 the provider cut the response mid-block). Tool calls were not executed. Re-emit with native tool_call or smaller payloads." : "Found text-format tool block but parse failed; tool calls were not executed. Prefer native tool_call, or ---TOOLS--- with ONE valid JSON array.",
|
|
24242
24315
|
code: "text_tools_parse_failed"
|
|
24243
24316
|
});
|
|
24244
24317
|
this.emit(parseErr);
|
|
24245
24318
|
yield parseErr;
|
|
24246
24319
|
}
|
|
24320
|
+
if (!clarificationPause && textParse.truncatedBlock && textTools.length > 0) {
|
|
24321
|
+
const partial2 = createBrainEvent("error", this.sessionId, {
|
|
24322
|
+
severity: "recoverable",
|
|
24323
|
+
message: `Text-format tool block was truncated (missing ---END---): recovered ${textTools.length} complete call(s); the incomplete tail was dropped.`,
|
|
24324
|
+
code: "text_tools_truncated"
|
|
24325
|
+
});
|
|
24326
|
+
this.emit(partial2);
|
|
24327
|
+
yield partial2;
|
|
24328
|
+
}
|
|
24247
24329
|
if (!clarificationPause && toolsToRun.length > 0 && this.config.toolRegistry && !this.cancelled && this.textToolReentries < 4) {
|
|
24248
24330
|
let executedAny = false;
|
|
24249
24331
|
for (let ti = 0; ti < toolsToRun.length; ti++) {
|
|
@@ -24266,7 +24348,7 @@ ${cached2}`
|
|
|
24266
24348
|
yield startEv;
|
|
24267
24349
|
const gate = this.checkToolCallGate(tt.name, tt.args);
|
|
24268
24350
|
if (!gate.allowed) {
|
|
24269
|
-
const denied = `[resource-gate] ${gate.reason ?? "denied by resource policy"}
|
|
24351
|
+
const denied = `[resource-gate] ${gate.reason ?? "denied by resource policy"} ` + gateAdvice(gate.hardLimit);
|
|
24270
24352
|
const denyEv = createBrainEvent("tool_execution_end", this.sessionId, {
|
|
24271
24353
|
toolCallId,
|
|
24272
24354
|
result: denied,
|
|
@@ -24343,7 +24425,8 @@ ${cached2}`
|
|
|
24343
24425
|
if (turnToolResults.length > 0) {
|
|
24344
24426
|
finishRef.value = "tool_calls";
|
|
24345
24427
|
}
|
|
24346
|
-
|
|
24428
|
+
const truncatedToolCall = finishRef.value === "tool_calls" && turnToolCalls.length === 0 && turnToolResults.length === 0;
|
|
24429
|
+
if (truncatedToolCall) {
|
|
24347
24430
|
const truncErr = createBrainEvent("error", this.sessionId, {
|
|
24348
24431
|
severity: "recoverable",
|
|
24349
24432
|
message: "Tool call was truncated (finish_reason=tool_calls but no complete tool_call received). The provider cut the response mid-arguments. Retry with a shorter payload or split the work.",
|
|
@@ -24383,6 +24466,24 @@ ${cached2}`
|
|
|
24383
24466
|
content: tr.content
|
|
24384
24467
|
});
|
|
24385
24468
|
}
|
|
24469
|
+
if (truncatedToolCall) {
|
|
24470
|
+
const last = this.config.messages[this.config.messages.length - 1];
|
|
24471
|
+
if (!(last?.role === "user" && typeof last.content === "string" && last.content.includes(TOOL_CALL_TRUNCATED_RECOVERY_MARKER))) {
|
|
24472
|
+
this.config.messages.push({
|
|
24473
|
+
role: "user",
|
|
24474
|
+
content: TOOL_CALL_TRUNCATED_RECOVERY_USER
|
|
24475
|
+
});
|
|
24476
|
+
}
|
|
24477
|
+
}
|
|
24478
|
+
if (!clarificationPause) {
|
|
24479
|
+
const feedbackText = textParse.truncatedBlock && textTools.length > 0 ? TEXT_TOOLS_PARTIAL_USER : /---TOOLS---/.test(turnText) && textTools.length === 0 ? TEXT_TOOLS_FAILED_USER : null;
|
|
24480
|
+
if (feedbackText) {
|
|
24481
|
+
const last = this.config.messages[this.config.messages.length - 1];
|
|
24482
|
+
if (!(last?.role === "user" && typeof last.content === "string" && (last.content.includes(TEXT_TOOLS_PARTIAL_MARKER) || last.content.includes(TEXT_TOOLS_FAILED_MARKER)))) {
|
|
24483
|
+
this.config.messages.push({ role: "user", content: feedbackText });
|
|
24484
|
+
}
|
|
24485
|
+
}
|
|
24486
|
+
}
|
|
24386
24487
|
break;
|
|
24387
24488
|
} else if (delta.kind === "error") {
|
|
24388
24489
|
finishRef.providerError = true;
|
|
@@ -25317,6 +25418,12 @@ __export(harness_exports, {
|
|
|
25317
25418
|
SessionJsonlWriter: () => SessionJsonlWriter,
|
|
25318
25419
|
TEXT_LOOP_RECOVERY_SYSTEM: () => TEXT_LOOP_RECOVERY_SYSTEM,
|
|
25319
25420
|
TEXT_LOOP_RECOVERY_USER_PROMPT: () => TEXT_LOOP_RECOVERY_USER_PROMPT,
|
|
25421
|
+
TEXT_TOOLS_FAILED_MARKER: () => TEXT_TOOLS_FAILED_MARKER,
|
|
25422
|
+
TEXT_TOOLS_FAILED_USER: () => TEXT_TOOLS_FAILED_USER,
|
|
25423
|
+
TEXT_TOOLS_PARTIAL_MARKER: () => TEXT_TOOLS_PARTIAL_MARKER,
|
|
25424
|
+
TEXT_TOOLS_PARTIAL_USER: () => TEXT_TOOLS_PARTIAL_USER,
|
|
25425
|
+
TOOL_CALL_TRUNCATED_RECOVERY_MARKER: () => TOOL_CALL_TRUNCATED_RECOVERY_MARKER,
|
|
25426
|
+
TOOL_CALL_TRUNCATED_RECOVERY_USER: () => TOOL_CALL_TRUNCATED_RECOVERY_USER,
|
|
25320
25427
|
canonicalTools: () => canonicalTools,
|
|
25321
25428
|
collapseLoopedAssistantText: () => collapseLoopedAssistantText,
|
|
25322
25429
|
compareReplayPrefix: () => compareReplayPrefix,
|
|
@@ -25334,6 +25441,7 @@ __export(harness_exports, {
|
|
|
25334
25441
|
normalizeToolName: () => normalizeToolName,
|
|
25335
25442
|
parseMinimaxStyleToolCalls: () => parseMinimaxStyleToolCalls,
|
|
25336
25443
|
parseTextToolCalls: () => parseTextToolCalls,
|
|
25444
|
+
parseTextToolCallsDetailed: () => parseTextToolCallsDetailed,
|
|
25337
25445
|
readSession: () => readSession,
|
|
25338
25446
|
recordRequest: () => recordRequest,
|
|
25339
25447
|
recordToolResult: () => recordToolResult,
|
|
@@ -26138,11 +26246,11 @@ var init_synthesisAudit = __esm({
|
|
|
26138
26246
|
import { existsSync as existsSync7, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "node:fs";
|
|
26139
26247
|
import { join as join4 } from "node:path";
|
|
26140
26248
|
function loadNfrSpec(zelariRoot) {
|
|
26141
|
-
const
|
|
26142
|
-
if (!existsSync7(
|
|
26249
|
+
const path91 = join4(zelariRoot, "nfr-spec.json");
|
|
26250
|
+
if (!existsSync7(path91))
|
|
26143
26251
|
return null;
|
|
26144
26252
|
try {
|
|
26145
|
-
const raw = JSON.parse(readFileSync7(
|
|
26253
|
+
const raw = JSON.parse(readFileSync7(path91, "utf8"));
|
|
26146
26254
|
if (raw.version !== 1 || !Array.isArray(raw.targets))
|
|
26147
26255
|
return null;
|
|
26148
26256
|
return raw;
|
|
@@ -28448,9 +28556,9 @@ var init_types5 = __esm({
|
|
|
28448
28556
|
import { readFileSync as readFileSync12 } from "node:fs";
|
|
28449
28557
|
import { join as join10 } from "node:path";
|
|
28450
28558
|
function readLessonsDeduped(zelariRoot) {
|
|
28451
|
-
const
|
|
28559
|
+
const path91 = join10(zelariRoot, LESSONS_FILE);
|
|
28452
28560
|
try {
|
|
28453
|
-
const raw = readFileSync12(
|
|
28561
|
+
const raw = readFileSync12(path91, "utf8");
|
|
28454
28562
|
const byId = /* @__PURE__ */ new Map();
|
|
28455
28563
|
for (const line of raw.split(/\r?\n/)) {
|
|
28456
28564
|
if (!line.trim())
|
|
@@ -28551,8 +28659,8 @@ function keywordsFrom(check2, signature) {
|
|
|
28551
28659
|
return [.../* @__PURE__ */ new Set([...fromId, ...words])].slice(0, 12);
|
|
28552
28660
|
}
|
|
28553
28661
|
function writeLesson(zelariRoot, lesson) {
|
|
28554
|
-
const
|
|
28555
|
-
appendFileSync(
|
|
28662
|
+
const path91 = join11(zelariRoot, LESSONS_FILE);
|
|
28663
|
+
appendFileSync(path91, `${JSON.stringify(lesson)}
|
|
28556
28664
|
`, "utf8");
|
|
28557
28665
|
}
|
|
28558
28666
|
function findSimilar(lessons, signature) {
|
|
@@ -30515,9 +30623,9 @@ function findCycle(nodes) {
|
|
|
30515
30623
|
if (color.get(start) !== WHITE)
|
|
30516
30624
|
continue;
|
|
30517
30625
|
const stack = [[start, 0]];
|
|
30518
|
-
const
|
|
30626
|
+
const path91 = [];
|
|
30519
30627
|
color.set(start, GRAY);
|
|
30520
|
-
|
|
30628
|
+
path91.push(start);
|
|
30521
30629
|
while (stack.length > 0) {
|
|
30522
30630
|
const top = stack[stack.length - 1];
|
|
30523
30631
|
const [id3, idx] = top;
|
|
@@ -30530,17 +30638,17 @@ function findCycle(nodes) {
|
|
|
30530
30638
|
continue;
|
|
30531
30639
|
const c = color.get(dep);
|
|
30532
30640
|
if (c === GRAY) {
|
|
30533
|
-
const at =
|
|
30534
|
-
return [...
|
|
30641
|
+
const at = path91.indexOf(dep);
|
|
30642
|
+
return [...path91.slice(at), dep];
|
|
30535
30643
|
}
|
|
30536
30644
|
if (c === WHITE) {
|
|
30537
30645
|
color.set(dep, GRAY);
|
|
30538
|
-
|
|
30646
|
+
path91.push(dep);
|
|
30539
30647
|
stack.push([dep, 0]);
|
|
30540
30648
|
}
|
|
30541
30649
|
} else {
|
|
30542
30650
|
color.set(id3, BLACK);
|
|
30543
|
-
|
|
30651
|
+
path91.pop();
|
|
30544
30652
|
stack.pop();
|
|
30545
30653
|
}
|
|
30546
30654
|
}
|
|
@@ -31460,8 +31568,8 @@ var init_runner = __esm({
|
|
|
31460
31568
|
failed: [...this.tentaclesById.values()].filter((r) => r.status === "error"),
|
|
31461
31569
|
pending: []
|
|
31462
31570
|
};
|
|
31463
|
-
const
|
|
31464
|
-
this.host.log(`checkpoint: ${label ?? "auto"} \u2192 ${
|
|
31571
|
+
const path91 = await this.host.saveSnapshot(snapshot, ".zelari/kraken/snapshots");
|
|
31572
|
+
this.host.log(`checkpoint: ${label ?? "auto"} \u2192 ${path91}`);
|
|
31465
31573
|
return snapshot;
|
|
31466
31574
|
}
|
|
31467
31575
|
callLog(msg, data) {
|
|
@@ -31587,6 +31695,15 @@ var init_types9 = __esm({
|
|
|
31587
31695
|
"resource.reserve_entered",
|
|
31588
31696
|
// 2.6.1 (closure plan §9): hard-limit overrun telemetry — state-only.
|
|
31589
31697
|
"resource.overrun",
|
|
31698
|
+
// ADR-0024 v1.1 (amended 2026-08-30): per-node ENVELOPE for kraken-graph
|
|
31699
|
+
// runs — written by the HOST (the sole spine writer) around the executor's
|
|
31700
|
+
// tentacle-run seam. State-only (never model-surface): data = {nodeId,
|
|
31701
|
+
// agent, graphId?, ok?, cancelled?, durationMs?}; node labels, prompts and
|
|
31702
|
+
// turn output stay on the kraken radio JSONL. One pair per attempt.
|
|
31703
|
+
// ADR-0021 schema review: additive state kinds need no SCHEMA_VERSION bump —
|
|
31704
|
+
// older readers skip them via the tolerant replay (schema-mismatch issues).
|
|
31705
|
+
"graph.node_started",
|
|
31706
|
+
"graph.node_ended",
|
|
31590
31707
|
"note"
|
|
31591
31708
|
];
|
|
31592
31709
|
SessionEventEnvelopeSchema = external_exports.object({
|
|
@@ -33912,16 +34029,16 @@ function runRetentionFromEnv() {
|
|
|
33912
34029
|
maxTotalBytes: Number.isFinite(parseMb) && parseMb > 0 ? Math.round(parseMb * 1024 * 1024) : DEFAULT_RUN_RETENTION_MAX_MB * 1024 * 1024
|
|
33913
34030
|
};
|
|
33914
34031
|
}
|
|
33915
|
-
async function dirSize(
|
|
34032
|
+
async function dirSize(path91) {
|
|
33916
34033
|
let total = 0;
|
|
33917
34034
|
let entries;
|
|
33918
34035
|
try {
|
|
33919
|
-
entries = await readdir(
|
|
34036
|
+
entries = await readdir(path91, { withFileTypes: true });
|
|
33920
34037
|
} catch {
|
|
33921
34038
|
return 0;
|
|
33922
34039
|
}
|
|
33923
34040
|
for (const entry of entries) {
|
|
33924
|
-
const child = join13(
|
|
34041
|
+
const child = join13(path91, entry.name);
|
|
33925
34042
|
if (entry.isDirectory())
|
|
33926
34043
|
total += await dirSize(child);
|
|
33927
34044
|
else {
|
|
@@ -33948,19 +34065,19 @@ async function enforceRunRetention(runsDir, options = {}) {
|
|
|
33948
34065
|
for (const entry of entries) {
|
|
33949
34066
|
if (!entry.isDirectory())
|
|
33950
34067
|
continue;
|
|
33951
|
-
const
|
|
34068
|
+
const path91 = join13(runsDir, entry.name);
|
|
33952
34069
|
let startedAt = 0;
|
|
33953
34070
|
let endedAt;
|
|
33954
34071
|
let completed = false;
|
|
33955
34072
|
try {
|
|
33956
|
-
const manifest = JSON.parse(await readFile(join13(
|
|
34073
|
+
const manifest = JSON.parse(await readFile(join13(path91, "manifest.json"), "utf8"));
|
|
33957
34074
|
startedAt = manifest.startedAt ?? 0;
|
|
33958
34075
|
endedAt = manifest.endedAt;
|
|
33959
34076
|
completed = Boolean(endedAt) && manifest.status !== "running";
|
|
33960
34077
|
} catch {
|
|
33961
34078
|
completed = false;
|
|
33962
34079
|
}
|
|
33963
|
-
infos.push({ name: entry.name, path:
|
|
34080
|
+
infos.push({ name: entry.name, path: path91, startedAt, endedAt, completed, bytes: await dirSize(path91) });
|
|
33964
34081
|
}
|
|
33965
34082
|
const remove = async (info) => {
|
|
33966
34083
|
await rm(info.path, { recursive: true, force: true });
|
|
@@ -34732,12 +34849,12 @@ var init_engine = __esm({
|
|
|
34732
34849
|
* content digest) and the returned ref carries the event seq when the
|
|
34733
34850
|
* emitter resolved one.
|
|
34734
34851
|
*/
|
|
34735
|
-
async fsEvidence(observation,
|
|
34852
|
+
async fsEvidence(observation, path91, sha256, content, extra = {}) {
|
|
34736
34853
|
const digest = sha256 && content !== void 0 ? sha256(content) : void 0;
|
|
34737
|
-
const seq = await this.emitEvidence({ observation, path:
|
|
34854
|
+
const seq = await this.emitEvidence({ observation, path: path91, ...extra, ...digest ? { digest } : {} });
|
|
34738
34855
|
return {
|
|
34739
34856
|
tier: "fs-observation",
|
|
34740
|
-
ref:
|
|
34857
|
+
ref: path91,
|
|
34741
34858
|
capturedAt: Date.now(),
|
|
34742
34859
|
...digest ? { digest } : {},
|
|
34743
34860
|
...seq !== void 0 ? { seq } : {}
|
|
@@ -35776,7 +35893,13 @@ __export(dist_exports, {
|
|
|
35776
35893
|
TERMINAL_STATUSES: () => TERMINAL_STATUSES,
|
|
35777
35894
|
TEXT_LOOP_RECOVERY_SYSTEM: () => TEXT_LOOP_RECOVERY_SYSTEM,
|
|
35778
35895
|
TEXT_LOOP_RECOVERY_USER_PROMPT: () => TEXT_LOOP_RECOVERY_USER_PROMPT,
|
|
35896
|
+
TEXT_TOOLS_FAILED_MARKER: () => TEXT_TOOLS_FAILED_MARKER,
|
|
35897
|
+
TEXT_TOOLS_FAILED_USER: () => TEXT_TOOLS_FAILED_USER,
|
|
35898
|
+
TEXT_TOOLS_PARTIAL_MARKER: () => TEXT_TOOLS_PARTIAL_MARKER,
|
|
35899
|
+
TEXT_TOOLS_PARTIAL_USER: () => TEXT_TOOLS_PARTIAL_USER,
|
|
35779
35900
|
TIER_RANK: () => TIER_RANK,
|
|
35901
|
+
TOOL_CALL_TRUNCATED_RECOVERY_MARKER: () => TOOL_CALL_TRUNCATED_RECOVERY_MARKER,
|
|
35902
|
+
TOOL_CALL_TRUNCATED_RECOVERY_USER: () => TOOL_CALL_TRUNCATED_RECOVERY_USER,
|
|
35780
35903
|
TOOL_DEFINITIONS: () => TOOL_DEFINITIONS,
|
|
35781
35904
|
TOOL_USE_PROTOCOL_DIRECTIVE: () => TOOL_USE_PROTOCOL_DIRECTIVE,
|
|
35782
35905
|
TURN_COMPLETION_MODULE: () => TURN_COMPLETION_MODULE,
|
|
@@ -36003,6 +36126,7 @@ __export(dist_exports, {
|
|
|
36003
36126
|
parsePersonaVerdict: () => parsePersonaVerdict,
|
|
36004
36127
|
parseProjectRootFromWorkspaceContext: () => parseProjectRootFromWorkspaceContext,
|
|
36005
36128
|
parseTextToolCalls: () => parseTextToolCalls,
|
|
36129
|
+
parseTextToolCallsDetailed: () => parseTextToolCallsDetailed,
|
|
36006
36130
|
parseThinking: () => parseThinking,
|
|
36007
36131
|
parseVerificationRunPayload: () => parseVerificationRunPayload,
|
|
36008
36132
|
parseVerificationTable: () => parseVerificationTable,
|
|
@@ -37078,6 +37202,29 @@ function mapBrainEventToSpine(ev) {
|
|
|
37078
37202
|
...ev.memberName ? { member: ev.memberName } : {}
|
|
37079
37203
|
}
|
|
37080
37204
|
};
|
|
37205
|
+
case "error":
|
|
37206
|
+
if (ev.code === "tool_call_truncated") {
|
|
37207
|
+
return {
|
|
37208
|
+
kind: "user.message",
|
|
37209
|
+
actor: ACTOR_USER,
|
|
37210
|
+
data: { text: TOOL_CALL_TRUNCATED_RECOVERY_USER }
|
|
37211
|
+
};
|
|
37212
|
+
}
|
|
37213
|
+
if (ev.code === "text_tools_parse_failed") {
|
|
37214
|
+
return {
|
|
37215
|
+
kind: "user.message",
|
|
37216
|
+
actor: ACTOR_USER,
|
|
37217
|
+
data: { text: TEXT_TOOLS_FAILED_USER }
|
|
37218
|
+
};
|
|
37219
|
+
}
|
|
37220
|
+
if (ev.code === "text_tools_truncated") {
|
|
37221
|
+
return {
|
|
37222
|
+
kind: "user.message",
|
|
37223
|
+
actor: ACTOR_USER,
|
|
37224
|
+
data: { text: TEXT_TOOLS_PARTIAL_USER }
|
|
37225
|
+
};
|
|
37226
|
+
}
|
|
37227
|
+
return null;
|
|
37081
37228
|
default:
|
|
37082
37229
|
return null;
|
|
37083
37230
|
}
|
|
@@ -37134,6 +37281,7 @@ var MAX_STREAM_BUFFERS, SessionSpineMirror, SpineMirroringWriter;
|
|
|
37134
37281
|
var init_sessionSpine = __esm({
|
|
37135
37282
|
"src/cli/sessionSpine.ts"() {
|
|
37136
37283
|
"use strict";
|
|
37284
|
+
init_harness();
|
|
37137
37285
|
init_session();
|
|
37138
37286
|
init_session();
|
|
37139
37287
|
init_verification2();
|
|
@@ -37880,9 +38028,9 @@ function spillToolOutput(fullText, meta3) {
|
|
|
37880
38028
|
const rnd = randomBytes3(3).toString("hex");
|
|
37881
38029
|
const safeTool = (meta3?.toolName ?? "tool").replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 32);
|
|
37882
38030
|
const file2 = `${stamp}-${safeTool}-${hash3}-${rnd}.txt`;
|
|
37883
|
-
const
|
|
37884
|
-
writeFileSync11(
|
|
37885
|
-
return
|
|
38031
|
+
const path91 = join14(dir, file2);
|
|
38032
|
+
writeFileSync11(path91, fullText, "utf8");
|
|
38033
|
+
return path91;
|
|
37886
38034
|
} catch {
|
|
37887
38035
|
return null;
|
|
37888
38036
|
}
|
|
@@ -37928,10 +38076,10 @@ function truncateToolResult(text, capOrOpts = TOOL_RESULT_LINE_CAP) {
|
|
|
37928
38076
|
${tail2}`;
|
|
37929
38077
|
}
|
|
37930
38078
|
if (doSpill) {
|
|
37931
|
-
const
|
|
37932
|
-
if (
|
|
38079
|
+
const path91 = spillToolOutput(text, { toolName: opts.toolName });
|
|
38080
|
+
if (path91) {
|
|
37933
38081
|
const spillNote = `
|
|
37934
|
-
\u2026 [full output spilled to: ${
|
|
38082
|
+
\u2026 [full output spilled to: ${path91} \u2014 re-read with read_file if you need the complete text] \u2026`;
|
|
37935
38083
|
if (preview.includes("] \u2026\n")) {
|
|
37936
38084
|
preview = preview.replace("] \u2026\n", `] \u2026${spillNote}
|
|
37937
38085
|
`);
|
|
@@ -41044,28 +41192,28 @@ var init_storage = __esm({
|
|
|
41044
41192
|
VALID_SCALARS = /^(true|false|null|~)$/i;
|
|
41045
41193
|
Storage = class {
|
|
41046
41194
|
/** Read a Markdown file with frontmatter. Throws if not found. */
|
|
41047
|
-
read(
|
|
41048
|
-
if (!existsSync19(
|
|
41049
|
-
throw new Error(`File not found: ${
|
|
41195
|
+
read(path91) {
|
|
41196
|
+
if (!existsSync19(path91)) {
|
|
41197
|
+
throw new Error(`File not found: ${path91}`);
|
|
41050
41198
|
}
|
|
41051
|
-
const md = readFileSync16(
|
|
41199
|
+
const md = readFileSync16(path91, "utf8");
|
|
41052
41200
|
return parseFrontmatter(md);
|
|
41053
41201
|
}
|
|
41054
41202
|
/** Read a Markdown file; returns null if not found. */
|
|
41055
|
-
readIfExists(
|
|
41056
|
-
if (!existsSync19(
|
|
41057
|
-
return this.read(
|
|
41203
|
+
readIfExists(path91) {
|
|
41204
|
+
if (!existsSync19(path91)) return null;
|
|
41205
|
+
return this.read(path91);
|
|
41058
41206
|
}
|
|
41059
41207
|
/**
|
|
41060
41208
|
* Write a Markdown file atomically (tmp + rename). Creates parent dirs.
|
|
41061
41209
|
* The meta object is serialized as YAML frontmatter; body as Markdown.
|
|
41062
41210
|
*/
|
|
41063
|
-
write(
|
|
41064
|
-
mkdirSync10(dirname2(
|
|
41065
|
-
const tmp =
|
|
41211
|
+
write(path91, meta3, body) {
|
|
41212
|
+
mkdirSync10(dirname2(path91), { recursive: true });
|
|
41213
|
+
const tmp = path91 + ".tmp-" + process.pid;
|
|
41066
41214
|
const md = serializeFrontmatter(meta3, body);
|
|
41067
41215
|
writeFileSync13(tmp, md, "utf8");
|
|
41068
|
-
renameSync(tmp,
|
|
41216
|
+
renameSync(tmp, path91);
|
|
41069
41217
|
}
|
|
41070
41218
|
/** List all .md files in a directory (non-recursive). */
|
|
41071
41219
|
listMarkdown(dir) {
|
|
@@ -41127,8 +41275,8 @@ function nextPlanTaskId(store6) {
|
|
|
41127
41275
|
return `t${store6.counter}`;
|
|
41128
41276
|
}
|
|
41129
41277
|
function writePlanTaskArtifact(rootDir, task) {
|
|
41130
|
-
const
|
|
41131
|
-
mkdirSync11(dirname3(
|
|
41278
|
+
const path91 = join18(rootDir, "plan-tasks", `${task.id}.md`);
|
|
41279
|
+
mkdirSync11(dirname3(path91), { recursive: true });
|
|
41132
41280
|
const meta3 = {
|
|
41133
41281
|
kind: "task",
|
|
41134
41282
|
id: task.id,
|
|
@@ -41149,7 +41297,7 @@ function writePlanTaskArtifact(rootDir, task) {
|
|
|
41149
41297
|
task.notes?.trim() ? task.notes.trim() : "_(no notes)_",
|
|
41150
41298
|
""
|
|
41151
41299
|
].filter((l) => l !== null).join("\n");
|
|
41152
|
-
new Storage().write(
|
|
41300
|
+
new Storage().write(path91, meta3, body);
|
|
41153
41301
|
}
|
|
41154
41302
|
function loadHandle(rootDir) {
|
|
41155
41303
|
const jsonPath = join18(rootDir, "plan.json");
|
|
@@ -44930,21 +45078,21 @@ function normalizeAuth(auth) {
|
|
|
44930
45078
|
return "agent";
|
|
44931
45079
|
}
|
|
44932
45080
|
function readSecrets() {
|
|
44933
|
-
const
|
|
44934
|
-
if (!existsSync25(
|
|
45081
|
+
const path91 = getSshSecretsPath();
|
|
45082
|
+
if (!existsSync25(path91)) return {};
|
|
44935
45083
|
try {
|
|
44936
|
-
return JSON.parse(readFileSync20(
|
|
45084
|
+
return JSON.parse(readFileSync20(path91, "utf8"));
|
|
44937
45085
|
} catch {
|
|
44938
45086
|
return {};
|
|
44939
45087
|
}
|
|
44940
45088
|
}
|
|
44941
45089
|
function writeSecrets(data) {
|
|
44942
|
-
const
|
|
44943
|
-
mkdirSync12(dirname4(
|
|
44944
|
-
writeFileSync15(
|
|
45090
|
+
const path91 = getSshSecretsPath();
|
|
45091
|
+
mkdirSync12(dirname4(path91), { recursive: true });
|
|
45092
|
+
writeFileSync15(path91, `${JSON.stringify(data, null, 2)}
|
|
44945
45093
|
`, "utf8");
|
|
44946
45094
|
try {
|
|
44947
|
-
chmodSync(
|
|
45095
|
+
chmodSync(path91, 384);
|
|
44948
45096
|
} catch {
|
|
44949
45097
|
}
|
|
44950
45098
|
}
|
|
@@ -44973,10 +45121,10 @@ function deleteSshPassword(id3) {
|
|
|
44973
45121
|
writeSecrets({ passwords });
|
|
44974
45122
|
}
|
|
44975
45123
|
function readStore2() {
|
|
44976
|
-
const
|
|
44977
|
-
if (!existsSync25(
|
|
45124
|
+
const path91 = getSshTargetsPath();
|
|
45125
|
+
if (!existsSync25(path91)) return [];
|
|
44978
45126
|
try {
|
|
44979
|
-
const parsed = JSON.parse(readFileSync20(
|
|
45127
|
+
const parsed = JSON.parse(readFileSync20(path91, "utf8"));
|
|
44980
45128
|
const list = Array.isArray(parsed.targets) ? parsed.targets : [];
|
|
44981
45129
|
return list.filter(
|
|
44982
45130
|
(t) => t && typeof t.id === "string" && typeof t.host === "string" && typeof t.user === "string"
|
|
@@ -44991,11 +45139,11 @@ function readStore2() {
|
|
|
44991
45139
|
}
|
|
44992
45140
|
}
|
|
44993
45141
|
function writeStore2(targets) {
|
|
44994
|
-
const
|
|
44995
|
-
mkdirSync12(dirname4(
|
|
45142
|
+
const path91 = getSshTargetsPath();
|
|
45143
|
+
mkdirSync12(dirname4(path91), { recursive: true });
|
|
44996
45144
|
const clean = targets.map(({ hasPassword: _hp, ...t }) => t);
|
|
44997
45145
|
writeFileSync15(
|
|
44998
|
-
|
|
45146
|
+
path91,
|
|
44999
45147
|
`${JSON.stringify({ targets: clean }, null, 2)}
|
|
45000
45148
|
`,
|
|
45001
45149
|
"utf8"
|
|
@@ -45241,11 +45389,11 @@ function formatSshTargetsForPrompt() {
|
|
|
45241
45389
|
];
|
|
45242
45390
|
for (const t of targets) {
|
|
45243
45391
|
const tags = t.tags?.length ? ` tags=[${t.tags.join(",")}]` : "";
|
|
45244
|
-
const
|
|
45392
|
+
const path91 = t.defaultRemotePath ? ` remotePath=${t.defaultRemotePath}` : "";
|
|
45245
45393
|
const allow = t.allowedCommands?.length ? ` allowed=${t.allowedCommands.join("|")}` : " allowed=status-only";
|
|
45246
45394
|
const auth = t.auth === "password" ? " auth=password" : t.auth === "keyPath" ? " auth=key" : " auth=agent";
|
|
45247
45395
|
lines.push(
|
|
45248
|
-
`- id=${t.id} name=${t.name} ${t.user}@${t.host}:${t.port ?? 22}${auth}${
|
|
45396
|
+
`- id=${t.id} name=${t.name} ${t.user}@${t.host}:${t.port ?? 22}${auth}${path91}${tags}${allow}`
|
|
45249
45397
|
);
|
|
45250
45398
|
}
|
|
45251
45399
|
return lines.join("\n");
|
|
@@ -54236,8 +54384,8 @@ function readPlan(ctx) {
|
|
|
54236
54384
|
} catch {
|
|
54237
54385
|
}
|
|
54238
54386
|
}
|
|
54239
|
-
const
|
|
54240
|
-
const doc = ctx.storage.readIfExists(
|
|
54387
|
+
const path91 = workspaceFile(ctx.rootDir, "plan");
|
|
54388
|
+
const doc = ctx.storage.readIfExists(path91);
|
|
54241
54389
|
if (!doc) return { phases: [], tasks: [], milestones: [] };
|
|
54242
54390
|
const meta3 = doc.meta;
|
|
54243
54391
|
return {
|
|
@@ -54415,7 +54563,7 @@ function addMilestoneRecord(ctx, summary, input) {
|
|
|
54415
54563
|
dueDate: input.dueDate,
|
|
54416
54564
|
targetVersion: version2
|
|
54417
54565
|
});
|
|
54418
|
-
const
|
|
54566
|
+
const path91 = join31(ctx.rootDir, "milestones", `${id3}.md`);
|
|
54419
54567
|
const meta3 = {
|
|
54420
54568
|
kind: "milestone",
|
|
54421
54569
|
id: id3,
|
|
@@ -54432,7 +54580,7 @@ function addMilestoneRecord(ctx, summary, input) {
|
|
|
54432
54580
|
`Target version: ${version2}`,
|
|
54433
54581
|
""
|
|
54434
54582
|
].join("\n");
|
|
54435
|
-
ctx.storage.write(
|
|
54583
|
+
ctx.storage.write(path91, meta3, body);
|
|
54436
54584
|
return { id: id3, created: true };
|
|
54437
54585
|
}
|
|
54438
54586
|
function readPlanSummary(ctx) {
|
|
@@ -54636,7 +54784,7 @@ function addIdeaStub(ctx) {
|
|
|
54636
54784
|
const tags = args["tags"] ?? [];
|
|
54637
54785
|
const category = args["category"] ?? "General";
|
|
54638
54786
|
const id3 = `${nextAdrId(ctx)}-${slugify3(title)}`;
|
|
54639
|
-
const
|
|
54787
|
+
const path91 = workspaceArtifact(ctx.rootDir, "decisions", id3);
|
|
54640
54788
|
const meta3 = {
|
|
54641
54789
|
kind: "adr",
|
|
54642
54790
|
status: "proposed",
|
|
@@ -54662,7 +54810,7 @@ function addIdeaStub(ctx) {
|
|
|
54662
54810
|
...consequences.map((c) => `- ${c}`),
|
|
54663
54811
|
""
|
|
54664
54812
|
].join("\n");
|
|
54665
|
-
ctx.storage.write(
|
|
54813
|
+
ctx.storage.write(path91, meta3, body);
|
|
54666
54814
|
return `ADR ${id3} created: "${title}". Status: proposed. Promote to accepted via /update ADR or manual edit.`;
|
|
54667
54815
|
});
|
|
54668
54816
|
}
|
|
@@ -54744,14 +54892,14 @@ function createDocumentStub(ctx) {
|
|
|
54744
54892
|
ctx.storage.write(risksPath, riskMeta, content);
|
|
54745
54893
|
return `Document "${title}" created at risks.md (workspace root).`;
|
|
54746
54894
|
}
|
|
54747
|
-
const
|
|
54895
|
+
const path91 = workspaceArtifact(ctx.rootDir, "docs", slug);
|
|
54748
54896
|
const meta3 = {
|
|
54749
54897
|
kind: "doc",
|
|
54750
54898
|
id: slug,
|
|
54751
54899
|
date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
|
|
54752
54900
|
tags
|
|
54753
54901
|
};
|
|
54754
|
-
ctx.storage.write(
|
|
54902
|
+
ctx.storage.write(path91, meta3, content);
|
|
54755
54903
|
return `Document "${title}" created at docs/${slug}.md.`;
|
|
54756
54904
|
});
|
|
54757
54905
|
}
|
|
@@ -55138,10 +55286,10 @@ function getUserMcpPath() {
|
|
|
55138
55286
|
function getProjectMcpPath(projectRoot) {
|
|
55139
55287
|
return join32(projectRoot, ".zelari", "mcp.json");
|
|
55140
55288
|
}
|
|
55141
|
-
function readFile6(
|
|
55142
|
-
if (!existsSync37(
|
|
55289
|
+
function readFile6(path91) {
|
|
55290
|
+
if (!existsSync37(path91)) return {};
|
|
55143
55291
|
try {
|
|
55144
|
-
const parsed = JSON.parse(readFileSync29(
|
|
55292
|
+
const parsed = JSON.parse(readFileSync29(path91, "utf8"));
|
|
55145
55293
|
const out = {};
|
|
55146
55294
|
for (const [name, cfg] of Object.entries(parsed.mcpServers ?? {})) {
|
|
55147
55295
|
if (!cfg || typeof cfg.command !== "string" || !cfg.command.trim()) continue;
|
|
@@ -55157,10 +55305,10 @@ function readFile6(path90) {
|
|
|
55157
55305
|
return {};
|
|
55158
55306
|
}
|
|
55159
55307
|
}
|
|
55160
|
-
function writeFile2(
|
|
55161
|
-
mkdirSync16(dirname9(
|
|
55308
|
+
function writeFile2(path91, servers) {
|
|
55309
|
+
mkdirSync16(dirname9(path91), { recursive: true });
|
|
55162
55310
|
const body = { mcpServers: servers };
|
|
55163
|
-
writeFileSync18(
|
|
55311
|
+
writeFileSync18(path91, `${JSON.stringify(body, null, 2)}
|
|
55164
55312
|
`, "utf8");
|
|
55165
55313
|
}
|
|
55166
55314
|
function listMcpServers(projectRoot) {
|
|
@@ -55193,9 +55341,9 @@ function upsertMcpServer(opts) {
|
|
|
55193
55341
|
if (!opts.config.command?.trim()) {
|
|
55194
55342
|
return { ok: false, error: "command is required" };
|
|
55195
55343
|
}
|
|
55196
|
-
let
|
|
55344
|
+
let path91;
|
|
55197
55345
|
if (opts.scope === "user") {
|
|
55198
|
-
|
|
55346
|
+
path91 = getUserMcpPath();
|
|
55199
55347
|
} else {
|
|
55200
55348
|
const root = opts.projectRoot?.trim();
|
|
55201
55349
|
if (!root) {
|
|
@@ -55204,30 +55352,30 @@ function upsertMcpServer(opts) {
|
|
|
55204
55352
|
error: "projectRoot required for project scope (Open Folder first)"
|
|
55205
55353
|
};
|
|
55206
55354
|
}
|
|
55207
|
-
|
|
55355
|
+
path91 = getProjectMcpPath(root);
|
|
55208
55356
|
}
|
|
55209
|
-
const current = readFile6(
|
|
55357
|
+
const current = readFile6(path91);
|
|
55210
55358
|
current[name] = {
|
|
55211
55359
|
command: opts.config.command.trim(),
|
|
55212
55360
|
args: opts.config.args,
|
|
55213
55361
|
env: opts.config.env,
|
|
55214
55362
|
enabled: opts.config.enabled !== false
|
|
55215
55363
|
};
|
|
55216
|
-
writeFile2(
|
|
55217
|
-
return { ok: true, path:
|
|
55364
|
+
writeFile2(path91, current);
|
|
55365
|
+
return { ok: true, path: path91 };
|
|
55218
55366
|
}
|
|
55219
55367
|
function removeMcpServer(opts) {
|
|
55220
|
-
const
|
|
55221
|
-
if (!
|
|
55368
|
+
const path91 = opts.scope === "user" ? getUserMcpPath() : opts.projectRoot ? getProjectMcpPath(opts.projectRoot) : null;
|
|
55369
|
+
if (!path91) {
|
|
55222
55370
|
return { ok: false, error: "projectRoot required for project scope" };
|
|
55223
55371
|
}
|
|
55224
|
-
const current = readFile6(
|
|
55372
|
+
const current = readFile6(path91);
|
|
55225
55373
|
if (!(opts.name in current)) {
|
|
55226
|
-
return { ok: false, error: `Server "${opts.name}" not found in ${
|
|
55374
|
+
return { ok: false, error: `Server "${opts.name}" not found in ${path91}` };
|
|
55227
55375
|
}
|
|
55228
55376
|
delete current[opts.name];
|
|
55229
|
-
writeFile2(
|
|
55230
|
-
return { ok: true, path:
|
|
55377
|
+
writeFile2(path91, current);
|
|
55378
|
+
return { ok: true, path: path91 };
|
|
55231
55379
|
}
|
|
55232
55380
|
var init_mcpConfigIo = __esm({
|
|
55233
55381
|
"src/cli/mcp/mcpConfigIo.ts"() {
|
|
@@ -55628,10 +55776,10 @@ import { createHash as createHash20 } from "node:crypto";
|
|
|
55628
55776
|
import { join as join34 } from "node:path";
|
|
55629
55777
|
import { readFile as readFile7 } from "node:fs/promises";
|
|
55630
55778
|
async function readPackageJson3(projectRoot) {
|
|
55631
|
-
const
|
|
55632
|
-
if (!existsSync39(
|
|
55779
|
+
const path91 = join34(projectRoot, "package.json");
|
|
55780
|
+
if (!existsSync39(path91)) return null;
|
|
55633
55781
|
try {
|
|
55634
|
-
return JSON.parse(await readFile7(
|
|
55782
|
+
return JSON.parse(await readFile7(path91, "utf8"));
|
|
55635
55783
|
} catch {
|
|
55636
55784
|
return null;
|
|
55637
55785
|
}
|
|
@@ -55713,9 +55861,9 @@ async function genBuild(ctx) {
|
|
|
55713
55861
|
].join("\n");
|
|
55714
55862
|
}
|
|
55715
55863
|
async function genOpenQuestions(ctx) {
|
|
55716
|
-
const
|
|
55717
|
-
if (!existsSync39(
|
|
55718
|
-
const content = readFileSync31(
|
|
55864
|
+
const path91 = join34(ctx.rootDir, "risks.md");
|
|
55865
|
+
if (!existsSync39(path91)) return "_No open questions._";
|
|
55866
|
+
const content = readFileSync31(path91, "utf8");
|
|
55719
55867
|
const lines = content.split("\n");
|
|
55720
55868
|
const questions = [];
|
|
55721
55869
|
let currentTitle = "";
|
|
@@ -55989,9 +56137,9 @@ function versionKey(value) {
|
|
|
55989
56137
|
function firstString2(v) {
|
|
55990
56138
|
return typeof v === "string" && v.trim().length > 0 ? v : null;
|
|
55991
56139
|
}
|
|
55992
|
-
function readFileSyncSafe(
|
|
56140
|
+
function readFileSyncSafe(path91) {
|
|
55993
56141
|
try {
|
|
55994
|
-
return readFileSync32(
|
|
56142
|
+
return readFileSync32(path91, "utf8");
|
|
55995
56143
|
} catch {
|
|
55996
56144
|
return null;
|
|
55997
56145
|
}
|
|
@@ -56454,8 +56602,8 @@ async function runPostCouncilHook(ctx, options) {
|
|
|
56454
56602
|
sources: scope.sources
|
|
56455
56603
|
} : void 0
|
|
56456
56604
|
});
|
|
56457
|
-
const
|
|
56458
|
-
completionHook = { ran: true, path:
|
|
56605
|
+
const path91 = writeCouncilCompletion(ctx.rootDir, completion);
|
|
56606
|
+
completionHook = { ran: true, path: path91, completion };
|
|
56459
56607
|
} catch (err) {
|
|
56460
56608
|
completionHook = {
|
|
56461
56609
|
ran: true,
|
|
@@ -57791,7 +57939,7 @@ function safeSocketPath(socketPath) {
|
|
|
57791
57939
|
return socketPath.trim();
|
|
57792
57940
|
}
|
|
57793
57941
|
function startPermissionBroker(socketPath, handlers, opts) {
|
|
57794
|
-
const
|
|
57942
|
+
const path91 = safeSocketPath(socketPath);
|
|
57795
57943
|
const requestTimeoutMs = opts?.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
|
|
57796
57944
|
const sockets = /* @__PURE__ */ new Set();
|
|
57797
57945
|
const server = createServer2((socket) => {
|
|
@@ -57891,10 +58039,10 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
57891
58039
|
return new Promise((resolve9, reject) => {
|
|
57892
58040
|
const onError = (err) => reject(err);
|
|
57893
58041
|
server.once("error", onError);
|
|
57894
|
-
server.listen(
|
|
58042
|
+
server.listen(path91, () => {
|
|
57895
58043
|
server.removeListener("error", onError);
|
|
57896
58044
|
resolve9({
|
|
57897
|
-
socketPath:
|
|
58045
|
+
socketPath: path91,
|
|
57898
58046
|
stop: () => new Promise((res) => {
|
|
57899
58047
|
for (const s of sockets) s.destroy();
|
|
57900
58048
|
sockets.clear();
|
|
@@ -57905,7 +58053,7 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
57905
58053
|
if (done) return;
|
|
57906
58054
|
done = true;
|
|
57907
58055
|
if (process.platform !== "win32") {
|
|
57908
|
-
unlink(
|
|
58056
|
+
unlink(path91, () => res());
|
|
57909
58057
|
} else {
|
|
57910
58058
|
res();
|
|
57911
58059
|
}
|
|
@@ -57918,11 +58066,11 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
57918
58066
|
});
|
|
57919
58067
|
}
|
|
57920
58068
|
function requestBrokerAsk(socketPath, ask, opts) {
|
|
57921
|
-
const
|
|
58069
|
+
const path91 = safeSocketPath(socketPath);
|
|
57922
58070
|
const requestTimeoutMs = opts?.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
|
|
57923
58071
|
const connectTimeoutMs = opts?.connectTimeoutMs ?? PERMISSION_BROKER_DEFAULT_CONNECT_TIMEOUT_MS;
|
|
57924
58072
|
return new Promise((resolve9, reject) => {
|
|
57925
|
-
const socket = connect(
|
|
58073
|
+
const socket = connect(path91);
|
|
57926
58074
|
let buffer = "";
|
|
57927
58075
|
let settled = false;
|
|
57928
58076
|
const settle = (fn) => {
|
|
@@ -57937,7 +58085,7 @@ function requestBrokerAsk(socketPath, ask, opts) {
|
|
|
57937
58085
|
settle(
|
|
57938
58086
|
() => reject(
|
|
57939
58087
|
new Error(
|
|
57940
|
-
`permission broker unavailable at "${
|
|
58088
|
+
`permission broker unavailable at "${path91}" (connect timed out after ${connectTimeoutMs}ms)`
|
|
57941
58089
|
)
|
|
57942
58090
|
)
|
|
57943
58091
|
);
|
|
@@ -58843,6 +58991,12 @@ var init_graphMemory = __esm({
|
|
|
58843
58991
|
});
|
|
58844
58992
|
|
|
58845
58993
|
// src/cli/kraken/tentacle.ts
|
|
58994
|
+
var tentacle_exports = {};
|
|
58995
|
+
__export(tentacle_exports, {
|
|
58996
|
+
TASK_TOOL_TIMEOUT_MS: () => TASK_TOOL_TIMEOUT_MS,
|
|
58997
|
+
runSubAgent: () => runSubAgent,
|
|
58998
|
+
runTentacle: () => runTentacle
|
|
58999
|
+
});
|
|
58846
59000
|
var init_tentacle = __esm({
|
|
58847
59001
|
"src/cli/kraken/tentacle.ts"() {
|
|
58848
59002
|
"use strict";
|
|
@@ -65742,6 +65896,7 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
65742
65896
|
return exitCode;
|
|
65743
65897
|
}
|
|
65744
65898
|
const audit = new AuditLogger2();
|
|
65899
|
+
const { runTentacle: runTentacle2 } = await Promise.resolve().then(() => (init_tentacle(), tentacle_exports));
|
|
65745
65900
|
const executor = new KrakenGraphExecutor2({
|
|
65746
65901
|
taskToolDeps: {
|
|
65747
65902
|
createSubAgentContext: createKrakenSubAgentContextFactory2({
|
|
@@ -65774,7 +65929,11 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
65774
65929
|
parentCwd: cwd,
|
|
65775
65930
|
sessionId: sessionId2,
|
|
65776
65931
|
goal: prompt,
|
|
65777
|
-
signal: abort.signal
|
|
65932
|
+
signal: abort.signal,
|
|
65933
|
+
// ADR-0024 v1.1: same delegate (`runTentacle`), wrapped so each node
|
|
65934
|
+
// turn leaves a graph.node_started / graph.node_ended envelope pair on
|
|
65935
|
+
// the spine. The executor owns scheduling; the HOST owns the spine.
|
|
65936
|
+
runTentacleFn: (runOpts) => nodeSpineEnvelopeRun(spine, runOpts, () => runTentacle2(runOpts))
|
|
65778
65937
|
});
|
|
65779
65938
|
const summary = await executor.execute(graph);
|
|
65780
65939
|
if (summary.cancelled) log("graph cancelled \u2014 partial results below");
|
|
@@ -65819,6 +65978,37 @@ ${formatKrakenGraphDigest2(
|
|
|
65819
65978
|
await emitHarnessStateEvent({ spine, workspaceRoot: cwd, output: opts.output, emitEvent });
|
|
65820
65979
|
}
|
|
65821
65980
|
}
|
|
65981
|
+
function nodeSpineEnvelopeRun(spine, runOpts, run) {
|
|
65982
|
+
const startedAt = Date.now();
|
|
65983
|
+
const noteNode = (kind2, extra) => {
|
|
65984
|
+
if (!runOpts.nodeId) return;
|
|
65985
|
+
void spine.appendEvent({
|
|
65986
|
+
kind: kind2,
|
|
65987
|
+
actor: { type: "system" },
|
|
65988
|
+
data: {
|
|
65989
|
+
nodeId: runOpts.nodeId,
|
|
65990
|
+
agent: runOpts.agent,
|
|
65991
|
+
...runOpts.graphId ? { graphId: runOpts.graphId } : {},
|
|
65992
|
+
...extra
|
|
65993
|
+
}
|
|
65994
|
+
});
|
|
65995
|
+
};
|
|
65996
|
+
noteNode("graph.node_started");
|
|
65997
|
+
return run().then(
|
|
65998
|
+
(res) => {
|
|
65999
|
+
noteNode("graph.node_ended", {
|
|
66000
|
+
ok: res.ok,
|
|
66001
|
+
...!res.ok && res.cancelled ? { cancelled: true } : {},
|
|
66002
|
+
durationMs: Date.now() - startedAt
|
|
66003
|
+
});
|
|
66004
|
+
return res;
|
|
66005
|
+
},
|
|
66006
|
+
(err) => {
|
|
66007
|
+
noteNode("graph.node_ended", { ok: false, durationMs: Date.now() - startedAt });
|
|
66008
|
+
throw err;
|
|
66009
|
+
}
|
|
66010
|
+
);
|
|
66011
|
+
}
|
|
65822
66012
|
async function buildCouncilToolRegistry(planMode, opts, memoryService, memoryAutoWrite = false, extras) {
|
|
65823
66013
|
const cwd = opts ? resolveHeadlessCwd(opts) : process.cwd();
|
|
65824
66014
|
const { registry: toolRegistry } = createBuiltinToolRegistry({
|
|
@@ -67062,7 +67252,7 @@ function upsertSkill(opts) {
|
|
|
67062
67252
|
}
|
|
67063
67253
|
dir = getProjectSkillsDir(root);
|
|
67064
67254
|
}
|
|
67065
|
-
const
|
|
67255
|
+
const path91 = skillFilePath(dir, name);
|
|
67066
67256
|
const content = serializeSkillMd({
|
|
67067
67257
|
name,
|
|
67068
67258
|
description,
|
|
@@ -67071,13 +67261,13 @@ function upsertSkill(opts) {
|
|
|
67071
67261
|
tools: opts.tools,
|
|
67072
67262
|
cost: opts.cost
|
|
67073
67263
|
});
|
|
67074
|
-
const parsed = parseSkillMd(content,
|
|
67264
|
+
const parsed = parseSkillMd(content, path91);
|
|
67075
67265
|
if (!parsed) {
|
|
67076
67266
|
return { ok: false, error: "Generated SKILL.md failed validation" };
|
|
67077
67267
|
}
|
|
67078
|
-
mkdirSync21(dirname13(
|
|
67079
|
-
writeFileSync24(
|
|
67080
|
-
return { ok: true, path:
|
|
67268
|
+
mkdirSync21(dirname13(path91), { recursive: true });
|
|
67269
|
+
writeFileSync24(path91, content, "utf8");
|
|
67270
|
+
return { ok: true, path: path91 };
|
|
67081
67271
|
}
|
|
67082
67272
|
function removeSkill(opts) {
|
|
67083
67273
|
const name = opts.name.trim().toLowerCase();
|
|
@@ -67095,8 +67285,8 @@ function removeSkill(opts) {
|
|
|
67095
67285
|
dir = getProjectSkillsDir(root);
|
|
67096
67286
|
}
|
|
67097
67287
|
const skillDir = join46(dir, name);
|
|
67098
|
-
const
|
|
67099
|
-
if (!existsSync52(
|
|
67288
|
+
const path91 = skillFilePath(dir, name);
|
|
67289
|
+
if (!existsSync52(path91) && !existsSync52(skillDir)) {
|
|
67100
67290
|
return { ok: false, error: `Skill "${name}" not found in ${dir}` };
|
|
67101
67291
|
}
|
|
67102
67292
|
try {
|
|
@@ -67107,7 +67297,7 @@ function removeSkill(opts) {
|
|
|
67107
67297
|
error: err instanceof Error ? err.message : String(err)
|
|
67108
67298
|
};
|
|
67109
67299
|
}
|
|
67110
|
-
return { ok: true, path:
|
|
67300
|
+
return { ok: true, path: path91 };
|
|
67111
67301
|
}
|
|
67112
67302
|
var NAME_RE, BUILTIN_SKILL_MODULES, builtinsLoaded;
|
|
67113
67303
|
var init_skillConfigIo = __esm({
|
|
@@ -67925,12 +68115,12 @@ function ensureHome() {
|
|
|
67925
68115
|
}
|
|
67926
68116
|
}
|
|
67927
68117
|
function loadCompanionConfig() {
|
|
67928
|
-
const
|
|
67929
|
-
if (!existsSync53(
|
|
68118
|
+
const path91 = getCompanionConfigPath();
|
|
68119
|
+
if (!existsSync53(path91)) {
|
|
67930
68120
|
return { projects: [] };
|
|
67931
68121
|
}
|
|
67932
68122
|
try {
|
|
67933
|
-
const raw = JSON.parse(readFileSync41(
|
|
68123
|
+
const raw = JSON.parse(readFileSync41(path91, "utf8"));
|
|
67934
68124
|
const projects = Array.isArray(raw.projects) ? raw.projects.filter(
|
|
67935
68125
|
(p3) => p3 && typeof p3.path === "string" && p3.path.trim() && typeof (p3.id ?? p3.name) === "string"
|
|
67936
68126
|
).map((p3) => ({
|
|
@@ -67968,16 +68158,16 @@ function loadOrCreateToken(explicit) {
|
|
|
67968
68158
|
return { token: explicit.trim(), created: false };
|
|
67969
68159
|
}
|
|
67970
68160
|
ensureHome();
|
|
67971
|
-
const
|
|
67972
|
-
if (existsSync53(
|
|
67973
|
-
const t = readFileSync41(
|
|
68161
|
+
const path91 = getCompanionTokenPath();
|
|
68162
|
+
if (existsSync53(path91)) {
|
|
68163
|
+
const t = readFileSync41(path91, "utf8").trim();
|
|
67974
68164
|
if (t) return { token: t, created: false };
|
|
67975
68165
|
}
|
|
67976
68166
|
const token = randomBytes7(24).toString("base64url");
|
|
67977
|
-
writeFileSync25(
|
|
68167
|
+
writeFileSync25(path91, token + "\n", "utf8");
|
|
67978
68168
|
try {
|
|
67979
68169
|
const fs45 = __require("node:fs");
|
|
67980
|
-
fs45.chmodSync?.(
|
|
68170
|
+
fs45.chmodSync?.(path91, 384);
|
|
67981
68171
|
} catch {
|
|
67982
68172
|
}
|
|
67983
68173
|
return { token, created: true };
|
|
@@ -68002,17 +68192,17 @@ function mergeProjects(cfg, extraPaths) {
|
|
|
68002
68192
|
byId.set(p3.id, p3);
|
|
68003
68193
|
}
|
|
68004
68194
|
for (const raw of extraPaths) {
|
|
68005
|
-
const
|
|
68006
|
-
if (!
|
|
68007
|
-
let id3 = slugFromPath(
|
|
68195
|
+
const path91 = raw.trim();
|
|
68196
|
+
if (!path91) continue;
|
|
68197
|
+
let id3 = slugFromPath(path91);
|
|
68008
68198
|
let n = 2;
|
|
68009
|
-
while (byId.has(id3) && byId.get(id3).path !==
|
|
68010
|
-
id3 = `${slugFromPath(
|
|
68199
|
+
while (byId.has(id3) && byId.get(id3).path !== path91) {
|
|
68200
|
+
id3 = `${slugFromPath(path91)}-${n++}`;
|
|
68011
68201
|
}
|
|
68012
68202
|
byId.set(id3, {
|
|
68013
68203
|
id: id3,
|
|
68014
|
-
name: slugFromPath(
|
|
68015
|
-
path:
|
|
68204
|
+
name: slugFromPath(path91),
|
|
68205
|
+
path: path91
|
|
68016
68206
|
});
|
|
68017
68207
|
}
|
|
68018
68208
|
return [...byId.values()];
|
|
@@ -68987,9 +69177,9 @@ async function runCompanionServe(opts = {}) {
|
|
|
68987
69177
|
return;
|
|
68988
69178
|
}
|
|
68989
69179
|
const url2 = parseUrl(req);
|
|
68990
|
-
const
|
|
69180
|
+
const path91 = url2.pathname.replace(/\/+$/, "") || "/";
|
|
68991
69181
|
try {
|
|
68992
|
-
if (req.method === "GET" && (
|
|
69182
|
+
if (req.method === "GET" && (path91 === "/health" || path91 === "/v1/health")) {
|
|
68993
69183
|
sendJson2(res, 200, {
|
|
68994
69184
|
ok: true,
|
|
68995
69185
|
service: "zelari-companion",
|
|
@@ -69001,18 +69191,18 @@ async function runCompanionServe(opts = {}) {
|
|
|
69001
69191
|
});
|
|
69002
69192
|
return;
|
|
69003
69193
|
}
|
|
69004
|
-
if (
|
|
69194
|
+
if (path91.startsWith("/v1")) {
|
|
69005
69195
|
if (!tokenMatches(token, getBearer(req))) {
|
|
69006
69196
|
sendJson2(res, 401, { ok: false, error: "unauthorized" });
|
|
69007
69197
|
return;
|
|
69008
69198
|
}
|
|
69009
69199
|
}
|
|
69010
|
-
if (req.method === "GET" &&
|
|
69200
|
+
if (req.method === "GET" && path91 === "/v1/config") {
|
|
69011
69201
|
const snap = buildDesktopConfigSnapshot();
|
|
69012
69202
|
sendJson2(res, 200, { ok: true, ...snap });
|
|
69013
69203
|
return;
|
|
69014
69204
|
}
|
|
69015
|
-
if (req.method === "GET" &&
|
|
69205
|
+
if (req.method === "GET" && path91 === "/v1/projects") {
|
|
69016
69206
|
sendJson2(res, 200, {
|
|
69017
69207
|
ok: true,
|
|
69018
69208
|
projects: projects.map((p3) => ({
|
|
@@ -69023,7 +69213,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
69023
69213
|
});
|
|
69024
69214
|
return;
|
|
69025
69215
|
}
|
|
69026
|
-
if (req.method === "GET" &&
|
|
69216
|
+
if (req.method === "GET" && path91 === "/v1/runs") {
|
|
69027
69217
|
sendJson2(res, 200, {
|
|
69028
69218
|
ok: true,
|
|
69029
69219
|
active: runs.getActive(),
|
|
@@ -69041,7 +69231,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
69041
69231
|
});
|
|
69042
69232
|
return;
|
|
69043
69233
|
}
|
|
69044
|
-
if (req.method === "POST" &&
|
|
69234
|
+
if (req.method === "POST" && path91 === "/v1/runs") {
|
|
69045
69235
|
const raw = await readBody(req);
|
|
69046
69236
|
let body = {};
|
|
69047
69237
|
try {
|
|
@@ -69089,7 +69279,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
69089
69279
|
});
|
|
69090
69280
|
return;
|
|
69091
69281
|
}
|
|
69092
|
-
const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(
|
|
69282
|
+
const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(path91);
|
|
69093
69283
|
if (req.method === "GET" && eventsMatch) {
|
|
69094
69284
|
const runId = eventsMatch[1];
|
|
69095
69285
|
const run = runs.getRun(runId);
|
|
@@ -69154,7 +69344,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
69154
69344
|
}, 500);
|
|
69155
69345
|
return;
|
|
69156
69346
|
}
|
|
69157
|
-
const cancelMatch = /^\/v1\/runs\/([^/]+)\/cancel$/.exec(
|
|
69347
|
+
const cancelMatch = /^\/v1\/runs\/([^/]+)\/cancel$/.exec(path91);
|
|
69158
69348
|
if (req.method === "POST" && cancelMatch) {
|
|
69159
69349
|
const runId = cancelMatch[1];
|
|
69160
69350
|
const result = runs.cancel(runId);
|
|
@@ -69165,7 +69355,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
69165
69355
|
sendJson2(res, 200, { ok: true, cancelled: runId });
|
|
69166
69356
|
return;
|
|
69167
69357
|
}
|
|
69168
|
-
const steerMatch = /^\/v1\/runs\/([^/]+)\/steer$/.exec(
|
|
69358
|
+
const steerMatch = /^\/v1\/runs\/([^/]+)\/steer$/.exec(path91);
|
|
69169
69359
|
if (req.method === "POST" && steerMatch) {
|
|
69170
69360
|
const runId = steerMatch[1];
|
|
69171
69361
|
const raw = await readBody(req);
|
|
@@ -69845,21 +70035,88 @@ var init_fixBudget = __esm({
|
|
|
69845
70035
|
}
|
|
69846
70036
|
});
|
|
69847
70037
|
|
|
70038
|
+
// src/cli/commands/inspectSession.ts
|
|
70039
|
+
var inspectSession_exports = {};
|
|
70040
|
+
__export(inspectSession_exports, {
|
|
70041
|
+
renderInspectReport: () => renderInspectReport,
|
|
70042
|
+
runInspectSession: () => runInspectSession
|
|
70043
|
+
});
|
|
70044
|
+
import path89 from "node:path";
|
|
70045
|
+
import { existsSync as existsSync56 } from "node:fs";
|
|
70046
|
+
function renderInspectReport(state3) {
|
|
70047
|
+
const lines = [
|
|
70048
|
+
`session ${state3.session.sessionId} status=${state3.session.status} turns=${state3.execution.turnsTotal}`
|
|
70049
|
+
];
|
|
70050
|
+
const contractByTurn = new Map(state3.execution.contracts.map((c) => [c.turn, c]));
|
|
70051
|
+
for (const turn of state3.turns) {
|
|
70052
|
+
const contract = contractByTurn.get(turn.index);
|
|
70053
|
+
const verification = turn.verification ? `${turn.verification.verdict}${turn.verification.strict ? "" : " (non-strict)"}` : "unknown";
|
|
70054
|
+
const blockers = contract?.blockers ?? [];
|
|
70055
|
+
const completion = contract?.complete ? "complete" : blockers.length > 0 ? `incomplete \u2014 ${blockers.length} blockers: ${blockers.join(", ")}` : "incomplete";
|
|
70056
|
+
lines.push(
|
|
70057
|
+
` turn ${turn.index} [${turn.outcome}] verification: ${verification} contract: ${completion}`
|
|
70058
|
+
);
|
|
70059
|
+
}
|
|
70060
|
+
lines.push("");
|
|
70061
|
+
lines.push("support lens:");
|
|
70062
|
+
const projections = state3.support.contextProjections;
|
|
70063
|
+
const last = projections[projections.length - 1];
|
|
70064
|
+
lines.push(
|
|
70065
|
+
` context projections: ${projections.length}` + (last ? ` (last: ${last.contextChars} chars \u2192 ${last.returnedCount} items)` : "")
|
|
70066
|
+
);
|
|
70067
|
+
lines.push(` memory events: ${state3.support.memoryEvents}`);
|
|
70068
|
+
const saved = state3.support.tokensSavedByCompaction;
|
|
70069
|
+
lines.push(
|
|
70070
|
+
` compactions: ${state3.support.compactions}${saved !== void 0 ? ` (${saved} tokens saved)` : ""}`
|
|
70071
|
+
);
|
|
70072
|
+
return lines.join("\n");
|
|
70073
|
+
}
|
|
70074
|
+
async function runInspectSession(opts) {
|
|
70075
|
+
const sessionsDir = resolveSessionsDir({ workspaceRoot: opts.cwd ?? process.cwd() });
|
|
70076
|
+
const sessionDir = path89.join(sessionsDir, opts.sessionId);
|
|
70077
|
+
const eventsPath = path89.join(sessionDir, "events.jsonl");
|
|
70078
|
+
if (!existsSync56(sessionDir)) {
|
|
70079
|
+
console.error(`zelari-code inspect: no session directory at ${sessionDir}`);
|
|
70080
|
+
return 1;
|
|
70081
|
+
}
|
|
70082
|
+
if (!existsSync56(eventsPath)) {
|
|
70083
|
+
console.error(`zelari-code inspect: session directory has no events.jsonl at ${eventsPath}`);
|
|
70084
|
+
return 1;
|
|
70085
|
+
}
|
|
70086
|
+
let state3;
|
|
70087
|
+
try {
|
|
70088
|
+
state3 = await readHarnessState(sessionDir);
|
|
70089
|
+
} catch (err) {
|
|
70090
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
70091
|
+
console.error(`zelari-code inspect: cannot read session at ${sessionDir}: ${msg}`);
|
|
70092
|
+
return 1;
|
|
70093
|
+
}
|
|
70094
|
+
console.log(opts.json ? JSON.stringify(state3, null, 2) : renderInspectReport(state3));
|
|
70095
|
+
return 0;
|
|
70096
|
+
}
|
|
70097
|
+
var init_inspectSession = __esm({
|
|
70098
|
+
"src/cli/commands/inspectSession.ts"() {
|
|
70099
|
+
"use strict";
|
|
70100
|
+
init_session();
|
|
70101
|
+
init_harnessState();
|
|
70102
|
+
}
|
|
70103
|
+
});
|
|
70104
|
+
|
|
69848
70105
|
// src/cli/commands/inspect.ts
|
|
69849
70106
|
var inspect_exports = {};
|
|
69850
70107
|
__export(inspect_exports, {
|
|
69851
70108
|
collectInspectReport: () => collectInspectReport,
|
|
69852
70109
|
runInspect: () => runInspect
|
|
69853
70110
|
});
|
|
69854
|
-
import
|
|
69855
|
-
import { existsSync as
|
|
70111
|
+
import path90 from "node:path";
|
|
70112
|
+
import { existsSync as existsSync57, readFileSync as readFileSync43, readdirSync as readdirSync12 } from "node:fs";
|
|
69856
70113
|
import { homedir as homedir17 } from "node:os";
|
|
69857
70114
|
async function collectInspectReport(cwd = process.cwd()) {
|
|
69858
70115
|
ensureBuiltinSkillsLoadedSync();
|
|
69859
70116
|
const snap = listSkillsSnapshot(cwd);
|
|
69860
70117
|
const mcp = listMcpServers(cwd);
|
|
69861
|
-
const userMcpPath =
|
|
69862
|
-
const projectMcpPath =
|
|
70118
|
+
const userMcpPath = path90.join(homedir17(), ".zelari-code", "mcp.json");
|
|
70119
|
+
const projectMcpPath = path90.join(cwd, ".zelari", "mcp.json");
|
|
69863
70120
|
const globalHooks = globalHooksDir();
|
|
69864
70121
|
const projectHooks = projectHooksDir(cwd);
|
|
69865
70122
|
const projectTrusted = isFolderTrusted(cwd);
|
|
@@ -69885,11 +70142,11 @@ async function collectInspectReport(cwd = process.cwd()) {
|
|
|
69885
70142
|
folders: listTrustedFolders()
|
|
69886
70143
|
},
|
|
69887
70144
|
configSources: [
|
|
69888
|
-
{ path: userMcpPath, exists:
|
|
69889
|
-
{ path: projectMcpPath, exists:
|
|
69890
|
-
{ path:
|
|
69891
|
-
{ path:
|
|
69892
|
-
{ path:
|
|
70145
|
+
{ path: userMcpPath, exists: existsSync57(userMcpPath) },
|
|
70146
|
+
{ path: projectMcpPath, exists: existsSync57(projectMcpPath) },
|
|
70147
|
+
{ path: path90.join(homedir17(), ".zelari-code", "provider.json"), exists: existsSync57(path90.join(homedir17(), ".zelari-code", "provider.json")) },
|
|
70148
|
+
{ path: path90.join(cwd, ".zelari", "AGENTS.md"), exists: existsSync57(path90.join(cwd, ".zelari", "AGENTS.md")) },
|
|
70149
|
+
{ path: path90.join(cwd, "AGENTS.md"), exists: existsSync57(path90.join(cwd, "AGENTS.md")) }
|
|
69893
70150
|
],
|
|
69894
70151
|
skills: {
|
|
69895
70152
|
total: snap.skills.length,
|
|
@@ -69902,7 +70159,7 @@ async function collectInspectReport(cwd = process.cwd()) {
|
|
|
69902
70159
|
user: mcp.servers.filter((s) => s.scope === "user").map((s) => ({ name: s.name, enabled: s.enabled !== false })),
|
|
69903
70160
|
project: mcp.servers.filter((s) => s.scope === "project").map((s) => ({ name: s.name, enabled: s.enabled !== false })),
|
|
69904
70161
|
projectTrusted,
|
|
69905
|
-
projectConfigExists:
|
|
70162
|
+
projectConfigExists: existsSync57(projectMcpPath)
|
|
69906
70163
|
},
|
|
69907
70164
|
hooks: {
|
|
69908
70165
|
global: {
|
|
@@ -69929,12 +70186,12 @@ function listJsonFiles(dir) {
|
|
|
69929
70186
|
}
|
|
69930
70187
|
function findAgentsMd(cwd) {
|
|
69931
70188
|
const candidates = [
|
|
69932
|
-
|
|
69933
|
-
|
|
70189
|
+
path90.join(cwd, "AGENTS.md"),
|
|
70190
|
+
path90.join(cwd, ".zelari", "AGENTS.md")
|
|
69934
70191
|
];
|
|
69935
70192
|
const found = [];
|
|
69936
70193
|
for (const c of candidates) {
|
|
69937
|
-
if (
|
|
70194
|
+
if (existsSync57(c)) {
|
|
69938
70195
|
try {
|
|
69939
70196
|
const text = readFileSync43(c, "utf8");
|
|
69940
70197
|
found.push(`${c} (${text.length} bytes)`);
|
|
@@ -79561,8 +79818,8 @@ function normalizeDraft(raw, sourceUrl, provider, model) {
|
|
|
79561
79818
|
let name = String(o.name ?? "").trim().toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64);
|
|
79562
79819
|
if (!name || !/^[a-z0-9][a-z0-9-]{0,63}$/.test(name)) {
|
|
79563
79820
|
try {
|
|
79564
|
-
const
|
|
79565
|
-
name =
|
|
79821
|
+
const path91 = new URL(sourceUrl).pathname.split("/").filter(Boolean).pop()?.replace(/\.[a-z0-9]+$/i, "").toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48);
|
|
79822
|
+
name = path91 && /^[a-z0-9]/.test(path91) ? path91 : "imported-skill";
|
|
79566
79823
|
} catch {
|
|
79567
79824
|
name = "imported-skill";
|
|
79568
79825
|
}
|
|
@@ -79897,6 +80154,14 @@ function pickRootComponent() {
|
|
|
79897
80154
|
process.exit(1);
|
|
79898
80155
|
}
|
|
79899
80156
|
if (argv.includes("--inspect") || argv.includes("inspect")) {
|
|
80157
|
+
const inspectAt = argv.findIndex((a) => a === "inspect" || a === "--inspect");
|
|
80158
|
+
const sessionId2 = inspectAt >= 0 ? argv.slice(inspectAt + 1).find((a) => !a.startsWith("-")) : void 0;
|
|
80159
|
+
if (sessionId2) {
|
|
80160
|
+
const { runInspectSession: runInspectSession2 } = (init_inspectSession(), __toCommonJS(inspectSession_exports));
|
|
80161
|
+
const json4 = argv.includes("--json");
|
|
80162
|
+
void runInspectSession2({ sessionId: sessionId2, json: json4 }).then((code) => process.exit(code));
|
|
80163
|
+
return { kind: "done" };
|
|
80164
|
+
}
|
|
79900
80165
|
const { runInspect: runInspect2 } = (init_inspect(), __toCommonJS(inspect_exports));
|
|
79901
80166
|
const json3 = argv.includes("--json");
|
|
79902
80167
|
void runInspect2({ json: json3 }).then((code) => process.exit(code));
|