zelari-code 2.34.1 → 2.36.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/anthropicOAuth.js +1 -1
- package/dist/cli/anthropicOAuth.js.map +1 -1
- package/dist/cli/browser/tools.js +23 -1
- package/dist/cli/browser/tools.js.map +1 -1
- package/dist/cli/desktopConfig.js +18 -3
- package/dist/cli/desktopConfig.js.map +1 -1
- package/dist/cli/hooks/useSlashDispatch.js +1 -0
- package/dist/cli/hooks/useSlashDispatch.js.map +1 -1
- package/dist/cli/keyStore.js +3 -7
- package/dist/cli/keyStore.js.map +1 -1
- package/dist/cli/main.bundled.js +933 -465
- package/dist/cli/main.bundled.js.map +4 -4
- package/dist/cli/provider/chatgpt.js +1 -1
- package/dist/cli/provider/chatgpt.js.map +1 -1
- package/dist/cli/provider/openai-compatible.js +53 -24
- package/dist/cli/provider/openai-compatible.js.map +1 -1
- package/dist/cli/provider/resolveStream.js +8 -0
- package/dist/cli/provider/resolveStream.js.map +1 -1
- package/dist/cli/provider/responsesApi.js +281 -0
- package/dist/cli/provider/responsesApi.js.map +1 -0
- package/dist/cli/providerConfig.js +49 -0
- package/dist/cli/providerConfig.js.map +1 -1
- package/dist/cli/refreshRegistry.js +78 -0
- package/dist/cli/refreshRegistry.js.map +1 -1
- package/dist/cli/slashCommands.js +18 -0
- package/dist/cli/slashCommands.js.map +1 -1
- package/dist/cli/slashHandlers/provider.js +11 -1
- package/dist/cli/slashHandlers/provider.js.map +1 -1
- package/dist/cli/thinking.js +5 -4
- package/dist/cli/thinking.js.map +1 -1
- package/dist/cli/thinkingCapability.js +7 -2
- package/dist/cli/thinkingCapability.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
|
@@ -1473,7 +1473,7 @@ var init_anthropicOAuth = __esm({
|
|
|
1473
1473
|
init_grokOAuth();
|
|
1474
1474
|
DEFAULT_ANTHROPIC_CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
|
|
1475
1475
|
ANTHROPIC_AUTHORIZE_URL = "https://claude.ai/oauth/authorize";
|
|
1476
|
-
ANTHROPIC_TOKEN_URL = "https://
|
|
1476
|
+
ANTHROPIC_TOKEN_URL = "https://platform.claude.com/v1/oauth/token";
|
|
1477
1477
|
ANTHROPIC_REDIRECT_URI = "https://console.anthropic.com/oauth/code/callback";
|
|
1478
1478
|
ANTHROPIC_SCOPE = "org:create_api_key user:profile user:inference";
|
|
1479
1479
|
AnthropicOAuthError = class extends Error {
|
|
@@ -1495,7 +1495,35 @@ function registerDefaultRefreshImpls() {
|
|
|
1495
1495
|
if (!registry.has("chatgpt")) registry.set("chatgpt", chatgptRefreshAdapter);
|
|
1496
1496
|
if (!registry.has("anthropic")) registry.set("anthropic", anthropicRefreshAdapter);
|
|
1497
1497
|
}
|
|
1498
|
-
|
|
1498
|
+
function normalizeRefreshError(providerId, err) {
|
|
1499
|
+
const code = err?.code;
|
|
1500
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1501
|
+
if (code === "invalid_grant" || message.includes("invalid_grant")) {
|
|
1502
|
+
return new RefreshRejectedError(
|
|
1503
|
+
`${providerId}: refresh token rejected (invalid_grant) \u2014 run /login ${providerId} to re-authenticate`,
|
|
1504
|
+
providerId,
|
|
1505
|
+
err
|
|
1506
|
+
);
|
|
1507
|
+
}
|
|
1508
|
+
return err;
|
|
1509
|
+
}
|
|
1510
|
+
async function runRefreshImpl(id3, refreshToken) {
|
|
1511
|
+
const existing = inflightRefresh.get(id3);
|
|
1512
|
+
if (existing) return existing;
|
|
1513
|
+
const impl = getRefreshImpl(id3);
|
|
1514
|
+
if (!impl) {
|
|
1515
|
+
throw new Error(`No refresh impl registered for provider "${id3}"`);
|
|
1516
|
+
}
|
|
1517
|
+
const run = Promise.resolve().then(() => impl(id3, refreshToken)).catch((err) => {
|
|
1518
|
+
throw normalizeRefreshError(id3, err);
|
|
1519
|
+
});
|
|
1520
|
+
inflightRefresh.set(id3, run);
|
|
1521
|
+
void run.finally(() => {
|
|
1522
|
+
if (inflightRefresh.get(id3) === run) inflightRefresh.delete(id3);
|
|
1523
|
+
}).catch(() => void 0);
|
|
1524
|
+
return run;
|
|
1525
|
+
}
|
|
1526
|
+
var registry, grokRefreshAdapter, chatgptRefreshAdapter, anthropicRefreshAdapter, RefreshRejectedError, inflightRefresh;
|
|
1499
1527
|
var init_refreshRegistry = __esm({
|
|
1500
1528
|
"src/cli/refreshRegistry.ts"() {
|
|
1501
1529
|
"use strict";
|
|
@@ -1514,6 +1542,17 @@ var init_refreshRegistry = __esm({
|
|
|
1514
1542
|
anthropicRefreshAdapter = async (_providerId, refreshToken) => {
|
|
1515
1543
|
return refreshAnthropicToken({ refreshToken });
|
|
1516
1544
|
};
|
|
1545
|
+
RefreshRejectedError = class extends Error {
|
|
1546
|
+
constructor(message, providerId, cause) {
|
|
1547
|
+
super(message);
|
|
1548
|
+
this.providerId = providerId;
|
|
1549
|
+
this.cause = cause;
|
|
1550
|
+
this.name = "RefreshRejectedError";
|
|
1551
|
+
}
|
|
1552
|
+
/** Marker callers can check without importing the class. */
|
|
1553
|
+
reloginRequired = true;
|
|
1554
|
+
};
|
|
1555
|
+
inflightRefresh = /* @__PURE__ */ new Map();
|
|
1517
1556
|
}
|
|
1518
1557
|
});
|
|
1519
1558
|
|
|
@@ -1742,11 +1781,7 @@ var init_keyStore = __esm({
|
|
|
1742
1781
|
"anthropic"
|
|
1743
1782
|
];
|
|
1744
1783
|
defaultRefreshImpl = async (providerId, refreshToken) => {
|
|
1745
|
-
|
|
1746
|
-
if (!impl) {
|
|
1747
|
-
throw new Error(`No refresh impl registered for provider "${providerId}"`);
|
|
1748
|
-
}
|
|
1749
|
-
return impl(providerId, refreshToken);
|
|
1784
|
+
return runRefreshImpl(providerId, refreshToken);
|
|
1750
1785
|
};
|
|
1751
1786
|
}
|
|
1752
1787
|
});
|
|
@@ -1767,10 +1802,11 @@ function effortLevelsFor(id3, model) {
|
|
|
1767
1802
|
const m = (model ?? "").trim();
|
|
1768
1803
|
switch (id3) {
|
|
1769
1804
|
case "grok":
|
|
1770
|
-
case "openai-compatible":
|
|
1771
|
-
case "custom":
|
|
1772
1805
|
if (grokHasXhigh(m)) return [...BASE_EFFORTS, "xhigh"];
|
|
1773
1806
|
return [...BASE_EFFORTS];
|
|
1807
|
+
case "openai-compatible":
|
|
1808
|
+
case "custom":
|
|
1809
|
+
return [...BASE_EFFORTS, "xhigh", "max"];
|
|
1774
1810
|
case "chatgpt":
|
|
1775
1811
|
if (gptHasMax(m)) return [...BASE_EFFORTS, "xhigh", "max"];
|
|
1776
1812
|
if (gptHasXhigh(m)) return [...BASE_EFFORTS, "xhigh"];
|
|
@@ -1983,13 +2019,14 @@ function translateOpenAiCompatibleThinking(providerId, spec, model) {
|
|
|
1983
2019
|
};
|
|
1984
2020
|
}
|
|
1985
2021
|
}
|
|
1986
|
-
function translateResponsesThinking(spec, model) {
|
|
2022
|
+
function translateResponsesThinking(spec, model, providerId) {
|
|
1987
2023
|
if (spec === "auto") return { patch: {}, degraded: false };
|
|
2024
|
+
const id3 = providerId ?? "chatgpt";
|
|
1988
2025
|
switch (spec.kind) {
|
|
1989
2026
|
case "off":
|
|
1990
2027
|
return { patch: { reasoning: { effort: "minimal" } }, degraded: false };
|
|
1991
2028
|
case "effort": {
|
|
1992
|
-
const resolved = clampEffort(
|
|
2029
|
+
const resolved = clampEffort(id3, model, spec.effort);
|
|
1993
2030
|
return withClampNote(
|
|
1994
2031
|
{ reasoning: { effort: resolved.effort } },
|
|
1995
2032
|
resolved.clamped,
|
|
@@ -1997,7 +2034,7 @@ function translateResponsesThinking(spec, model) {
|
|
|
1997
2034
|
);
|
|
1998
2035
|
}
|
|
1999
2036
|
case "budget":
|
|
2000
|
-
return degrade(
|
|
2037
|
+
return degrade(`thinking "budget" is not supported on the Responses API for "${id3}" \u2014 use low/medium/high/xhigh/max`);
|
|
2001
2038
|
}
|
|
2002
2039
|
}
|
|
2003
2040
|
function translateAnthropicThinking(spec, model) {
|
|
@@ -2046,6 +2083,7 @@ __export(providerConfig_exports, {
|
|
|
2046
2083
|
clearKrakenVerifier: () => clearKrakenVerifier,
|
|
2047
2084
|
getActiveModel: () => getActiveModel,
|
|
2048
2085
|
getActiveProvider: () => getActiveProvider,
|
|
2086
|
+
getApiStyleFor: () => getApiStyleFor,
|
|
2049
2087
|
getCustomEndpoint: () => getCustomEndpoint,
|
|
2050
2088
|
getKrakenVerifierOverride: () => getKrakenVerifierOverride,
|
|
2051
2089
|
getModelForProvider: () => getModelForProvider,
|
|
@@ -2054,6 +2092,7 @@ __export(providerConfig_exports, {
|
|
|
2054
2092
|
getThinkingForProvider: () => getThinkingForProvider,
|
|
2055
2093
|
loadProviderConfig: () => loadProviderConfig,
|
|
2056
2094
|
setActiveProviderId: () => setActiveProviderId,
|
|
2095
|
+
setApiStyleFor: () => setApiStyleFor,
|
|
2057
2096
|
setCustomEndpoint: () => setCustomEndpoint,
|
|
2058
2097
|
setKrakenVerifier: () => setKrakenVerifier,
|
|
2059
2098
|
setModelForProvider: () => setModelForProvider,
|
|
@@ -2071,6 +2110,7 @@ function mergeStoredProviderConfig(parsed) {
|
|
|
2071
2110
|
modelByProvider: { ...DEFAULTS.modelByProvider, ...parsed.modelByProvider },
|
|
2072
2111
|
thinkingByProvider: { ...DEFAULTS.thinkingByProvider, ...parsed.thinkingByProvider },
|
|
2073
2112
|
customEndpoints: mergeCustomEndpoints(parsed.customEndpoints),
|
|
2113
|
+
apiStyleByProvider: mergeApiStyles(parsed.apiStyleByProvider),
|
|
2074
2114
|
krakenVerifier: mergeKrakenVerifier(parsed.krakenVerifier)
|
|
2075
2115
|
};
|
|
2076
2116
|
}
|
|
@@ -2084,6 +2124,17 @@ function cloneDefaults() {
|
|
|
2084
2124
|
customEndpoints: { ...DEFAULTS.customEndpoints }
|
|
2085
2125
|
};
|
|
2086
2126
|
}
|
|
2127
|
+
function mergeApiStyles(raw) {
|
|
2128
|
+
if (!raw || typeof raw !== "object") return {};
|
|
2129
|
+
const result = {};
|
|
2130
|
+
const validIds = new Set(PROVIDERS.map((p3) => p3.id));
|
|
2131
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
2132
|
+
if (!validIds.has(key)) continue;
|
|
2133
|
+
if (value !== "responses") continue;
|
|
2134
|
+
result[key] = "responses";
|
|
2135
|
+
}
|
|
2136
|
+
return result;
|
|
2137
|
+
}
|
|
2087
2138
|
function applyEnvOverrides(config2) {
|
|
2088
2139
|
const envActive = process.env.ANATHEMA_ACTIVE_PROVIDER;
|
|
2089
2140
|
const envModel = process.env.OPENAI_MODEL;
|
|
@@ -2155,6 +2206,23 @@ function clearCustomEndpoint(id3) {
|
|
|
2155
2206
|
delete config2.customEndpoints[id3];
|
|
2156
2207
|
writeProviderConfig(config2);
|
|
2157
2208
|
}
|
|
2209
|
+
function getApiStyleFor(id3) {
|
|
2210
|
+
return getProviderConfig().apiStyleByProvider?.[id3] === "responses" ? "responses" : "chat";
|
|
2211
|
+
}
|
|
2212
|
+
function setApiStyleFor(id3, style) {
|
|
2213
|
+
const spec = PROVIDERS.find((p3) => p3.id === id3);
|
|
2214
|
+
if (!spec) {
|
|
2215
|
+
throw new Error(`Unknown provider id: "${id3}". Available: ${PROVIDERS.map((p3) => p3.id).join(", ")}`);
|
|
2216
|
+
}
|
|
2217
|
+
if (style !== "chat" && style !== "responses") {
|
|
2218
|
+
throw new Error(`Invalid api style: "${style}". Use 'chat' or 'responses'.`);
|
|
2219
|
+
}
|
|
2220
|
+
const config2 = getProviderConfig();
|
|
2221
|
+
if (!config2.apiStyleByProvider) config2.apiStyleByProvider = {};
|
|
2222
|
+
if (style === "chat") delete config2.apiStyleByProvider[id3];
|
|
2223
|
+
else config2.apiStyleByProvider[id3] = "responses";
|
|
2224
|
+
writeProviderConfig(config2);
|
|
2225
|
+
}
|
|
2158
2226
|
function mergeKrakenVerifier(raw) {
|
|
2159
2227
|
if (!raw || typeof raw !== "object") return void 0;
|
|
2160
2228
|
const provider = typeof raw.provider === "string" ? raw.provider.trim() : "";
|
|
@@ -2362,23 +2430,23 @@ async function resolveAuthToken(provider, options) {
|
|
|
2362
2430
|
return resolved?.apiKey;
|
|
2363
2431
|
}
|
|
2364
2432
|
async function resolveDiscoveryHeaders(provider, authToken) {
|
|
2365
|
-
const
|
|
2366
|
-
if (!authToken) return
|
|
2433
|
+
const headers3 = { Accept: "application/json" };
|
|
2434
|
+
if (!authToken) return headers3;
|
|
2367
2435
|
if (provider === "anthropic") {
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
return
|
|
2436
|
+
headers3.Authorization = `Bearer ${authToken}`;
|
|
2437
|
+
headers3["x-api-key"] = authToken;
|
|
2438
|
+
headers3["anthropic-version"] = "2023-06-01";
|
|
2439
|
+
headers3["anthropic-beta"] = "oauth-2025-04-20";
|
|
2440
|
+
return headers3;
|
|
2373
2441
|
}
|
|
2374
|
-
|
|
2442
|
+
headers3.Authorization = `Bearer ${authToken}`;
|
|
2375
2443
|
if (provider === "chatgpt") {
|
|
2376
2444
|
const { getOAuthToken: getOAuthToken2 } = await Promise.resolve().then(() => (init_keyStore(), keyStore_exports));
|
|
2377
2445
|
const accountId = getOAuthToken2("chatgpt")?.accountId;
|
|
2378
|
-
if (accountId)
|
|
2379
|
-
|
|
2446
|
+
if (accountId) headers3["ChatGPT-Account-Id"] = accountId;
|
|
2447
|
+
headers3["OpenAI-Beta"] = "responses=experimental";
|
|
2380
2448
|
}
|
|
2381
|
-
return
|
|
2449
|
+
return headers3;
|
|
2382
2450
|
}
|
|
2383
2451
|
function parseAnthropicModelsResponse(json3) {
|
|
2384
2452
|
if (!json3 || typeof json3 !== "object") return [];
|
|
@@ -2430,8 +2498,8 @@ async function discoverModelsForProvider(provider, options = {}) {
|
|
|
2430
2498
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
2431
2499
|
let response;
|
|
2432
2500
|
try {
|
|
2433
|
-
const
|
|
2434
|
-
response = await fetchImpl(url2, { method: "GET", headers:
|
|
2501
|
+
const headers3 = await resolveDiscoveryHeaders(provider, authToken);
|
|
2502
|
+
response = await fetchImpl(url2, { method: "GET", headers: headers3 });
|
|
2435
2503
|
} catch (err) {
|
|
2436
2504
|
throw new ModelDiscoveryError(
|
|
2437
2505
|
`Network error contacting ${url2}: ${err instanceof Error ? err.message : String(err)}`,
|
|
@@ -3414,10 +3482,10 @@ function mergeDefs(...defs) {
|
|
|
3414
3482
|
function cloneDef(schema) {
|
|
3415
3483
|
return mergeDefs(schema._zod.def);
|
|
3416
3484
|
}
|
|
3417
|
-
function getElementAtPath(obj,
|
|
3418
|
-
if (!
|
|
3485
|
+
function getElementAtPath(obj, path100) {
|
|
3486
|
+
if (!path100)
|
|
3419
3487
|
return obj;
|
|
3420
|
-
return
|
|
3488
|
+
return path100.reduce((acc, key) => acc?.[key], obj);
|
|
3421
3489
|
}
|
|
3422
3490
|
function promiseAllObject(promisesObj) {
|
|
3423
3491
|
const keys = Object.keys(promisesObj);
|
|
@@ -3745,11 +3813,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
3745
3813
|
}
|
|
3746
3814
|
return false;
|
|
3747
3815
|
}
|
|
3748
|
-
function prefixIssues(
|
|
3816
|
+
function prefixIssues(path100, issues) {
|
|
3749
3817
|
return issues.map((iss) => {
|
|
3750
3818
|
var _a3;
|
|
3751
3819
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
3752
|
-
iss.path.unshift(
|
|
3820
|
+
iss.path.unshift(path100);
|
|
3753
3821
|
return iss;
|
|
3754
3822
|
});
|
|
3755
3823
|
}
|
|
@@ -3967,16 +4035,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
3967
4035
|
}
|
|
3968
4036
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
3969
4037
|
const fieldErrors = { _errors: [] };
|
|
3970
|
-
const processError = (error52,
|
|
4038
|
+
const processError = (error52, path100 = []) => {
|
|
3971
4039
|
for (const issue2 of error52.issues) {
|
|
3972
4040
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
3973
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
4041
|
+
issue2.errors.map((issues) => processError({ issues }, [...path100, ...issue2.path]));
|
|
3974
4042
|
} else if (issue2.code === "invalid_key") {
|
|
3975
|
-
processError({ issues: issue2.issues }, [...
|
|
4043
|
+
processError({ issues: issue2.issues }, [...path100, ...issue2.path]);
|
|
3976
4044
|
} else if (issue2.code === "invalid_element") {
|
|
3977
|
-
processError({ issues: issue2.issues }, [...
|
|
4045
|
+
processError({ issues: issue2.issues }, [...path100, ...issue2.path]);
|
|
3978
4046
|
} else {
|
|
3979
|
-
const fullpath = [...
|
|
4047
|
+
const fullpath = [...path100, ...issue2.path];
|
|
3980
4048
|
if (fullpath.length === 0) {
|
|
3981
4049
|
fieldErrors._errors.push(mapper(issue2));
|
|
3982
4050
|
} else {
|
|
@@ -4003,17 +4071,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
4003
4071
|
}
|
|
4004
4072
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
4005
4073
|
const result = { errors: [] };
|
|
4006
|
-
const processError = (error52,
|
|
4074
|
+
const processError = (error52, path100 = []) => {
|
|
4007
4075
|
var _a3, _b;
|
|
4008
4076
|
for (const issue2 of error52.issues) {
|
|
4009
4077
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
4010
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
4078
|
+
issue2.errors.map((issues) => processError({ issues }, [...path100, ...issue2.path]));
|
|
4011
4079
|
} else if (issue2.code === "invalid_key") {
|
|
4012
|
-
processError({ issues: issue2.issues }, [...
|
|
4080
|
+
processError({ issues: issue2.issues }, [...path100, ...issue2.path]);
|
|
4013
4081
|
} else if (issue2.code === "invalid_element") {
|
|
4014
|
-
processError({ issues: issue2.issues }, [...
|
|
4082
|
+
processError({ issues: issue2.issues }, [...path100, ...issue2.path]);
|
|
4015
4083
|
} else {
|
|
4016
|
-
const fullpath = [...
|
|
4084
|
+
const fullpath = [...path100, ...issue2.path];
|
|
4017
4085
|
if (fullpath.length === 0) {
|
|
4018
4086
|
result.errors.push(mapper(issue2));
|
|
4019
4087
|
continue;
|
|
@@ -4045,8 +4113,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
4045
4113
|
}
|
|
4046
4114
|
function toDotPath(_path) {
|
|
4047
4115
|
const segs = [];
|
|
4048
|
-
const
|
|
4049
|
-
for (const seg of
|
|
4116
|
+
const path100 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
4117
|
+
for (const seg of path100) {
|
|
4050
4118
|
if (typeof seg === "number")
|
|
4051
4119
|
segs.push(`[${seg}]`);
|
|
4052
4120
|
else if (typeof seg === "symbol")
|
|
@@ -17549,13 +17617,13 @@ function resolveRef(ref, ctx) {
|
|
|
17549
17617
|
if (!ref.startsWith("#")) {
|
|
17550
17618
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
17551
17619
|
}
|
|
17552
|
-
const
|
|
17553
|
-
if (
|
|
17620
|
+
const path100 = ref.slice(1).split("/").filter(Boolean);
|
|
17621
|
+
if (path100.length === 0) {
|
|
17554
17622
|
return ctx.rootSchema;
|
|
17555
17623
|
}
|
|
17556
17624
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
17557
|
-
if (
|
|
17558
|
-
const key =
|
|
17625
|
+
if (path100[0] === defsKey) {
|
|
17626
|
+
const key = path100[1];
|
|
17559
17627
|
if (!key || !ctx.defs[key]) {
|
|
17560
17628
|
throw new Error(`Reference not found: ${ref}`);
|
|
17561
17629
|
}
|
|
@@ -18327,7 +18395,9 @@ var init_zod = __esm({
|
|
|
18327
18395
|
});
|
|
18328
18396
|
|
|
18329
18397
|
// packages/core/dist/core/tools/toolTypes.js
|
|
18330
|
-
function typedOk(value, meta3) {
|
|
18398
|
+
function typedOk(value, meta3, images) {
|
|
18399
|
+
if (images && images.length > 0)
|
|
18400
|
+
return { ok: true, value, meta: meta3, images };
|
|
18331
18401
|
return meta3 ? { ok: true, value, meta: meta3 } : { ok: true, value };
|
|
18332
18402
|
}
|
|
18333
18403
|
function typedErr(error51, meta3) {
|
|
@@ -18387,17 +18457,17 @@ var init_newlines = __esm({
|
|
|
18387
18457
|
});
|
|
18388
18458
|
|
|
18389
18459
|
// packages/core/dist/core/tools/builtin/fileEvents.js
|
|
18390
|
-
function fileReadEvent(
|
|
18391
|
-
return { kind: "file.read", actor: { type: "tool" }, data: { path:
|
|
18460
|
+
function fileReadEvent(path100, snapshotId) {
|
|
18461
|
+
return { kind: "file.read", actor: { type: "tool" }, data: { path: path100, snapshotId } };
|
|
18392
18462
|
}
|
|
18393
|
-
function fileAppliedEvent(
|
|
18394
|
-
return { kind: "file.applied", actor: { type: "tool" }, data: { path:
|
|
18463
|
+
function fileAppliedEvent(path100, snapshotId, bytes) {
|
|
18464
|
+
return { kind: "file.applied", actor: { type: "tool" }, data: { path: path100, snapshotId, bytes } };
|
|
18395
18465
|
}
|
|
18396
|
-
function fileRejectedEvent(
|
|
18466
|
+
function fileRejectedEvent(path100, reason, hint) {
|
|
18397
18467
|
return {
|
|
18398
18468
|
kind: "file.rejected",
|
|
18399
18469
|
actor: { type: "tool" },
|
|
18400
|
-
data: hint === void 0 ? { path:
|
|
18470
|
+
data: hint === void 0 ? { path: path100, reason } : { path: path100, reason, hint }
|
|
18401
18471
|
};
|
|
18402
18472
|
}
|
|
18403
18473
|
function reReadHint(reject) {
|
|
@@ -19313,8 +19383,8 @@ async function searchFile(absPath, relPath, regex, contextLines, remainingSlots)
|
|
|
19313
19383
|
}
|
|
19314
19384
|
async function isDirectory(p3) {
|
|
19315
19385
|
try {
|
|
19316
|
-
const
|
|
19317
|
-
return
|
|
19386
|
+
const stat8 = await fs7.stat(p3);
|
|
19387
|
+
return stat8.isDirectory();
|
|
19318
19388
|
} catch {
|
|
19319
19389
|
return false;
|
|
19320
19390
|
}
|
|
@@ -20266,11 +20336,11 @@ var init_tools = __esm({
|
|
|
20266
20336
|
if (!ctx.addDocument)
|
|
20267
20337
|
return "Knowledge vault tool not available.";
|
|
20268
20338
|
const title = args["title"] || "New Document";
|
|
20269
|
-
const
|
|
20339
|
+
const path100 = args["path"] || `notes/${title.toLowerCase().replace(/[^a-z0-9]+/g, "-")}`;
|
|
20270
20340
|
const content = args["content"] || "";
|
|
20271
20341
|
const tags = args["tags"] || [];
|
|
20272
20342
|
ctx.addDocument({
|
|
20273
|
-
path:
|
|
20343
|
+
path: path100,
|
|
20274
20344
|
title,
|
|
20275
20345
|
content,
|
|
20276
20346
|
format: "markdown",
|
|
@@ -20279,7 +20349,7 @@ var init_tools = __esm({
|
|
|
20279
20349
|
workspaceId: ctx.workspaceId
|
|
20280
20350
|
});
|
|
20281
20351
|
ctx.addActivity("vault", "created document", title);
|
|
20282
|
-
return `Document "${title}" created at "${
|
|
20352
|
+
return `Document "${title}" created at "${path100}".`;
|
|
20283
20353
|
}
|
|
20284
20354
|
}
|
|
20285
20355
|
];
|
|
@@ -25104,16 +25174,16 @@ function runRetentionFromEnv() {
|
|
|
25104
25174
|
maxTotalBytes: Number.isFinite(parseMb) && parseMb > 0 ? Math.round(parseMb * 1024 * 1024) : DEFAULT_RUN_RETENTION_MAX_MB * 1024 * 1024
|
|
25105
25175
|
};
|
|
25106
25176
|
}
|
|
25107
|
-
async function dirSize(
|
|
25177
|
+
async function dirSize(path100) {
|
|
25108
25178
|
let total = 0;
|
|
25109
25179
|
let entries;
|
|
25110
25180
|
try {
|
|
25111
|
-
entries = await readdir(
|
|
25181
|
+
entries = await readdir(path100, { withFileTypes: true });
|
|
25112
25182
|
} catch {
|
|
25113
25183
|
return 0;
|
|
25114
25184
|
}
|
|
25115
25185
|
for (const entry of entries) {
|
|
25116
|
-
const child = join3(
|
|
25186
|
+
const child = join3(path100, entry.name);
|
|
25117
25187
|
if (entry.isDirectory())
|
|
25118
25188
|
total += await dirSize(child);
|
|
25119
25189
|
else {
|
|
@@ -25140,19 +25210,19 @@ async function enforceRunRetention(runsDir, options = {}) {
|
|
|
25140
25210
|
for (const entry of entries) {
|
|
25141
25211
|
if (!entry.isDirectory())
|
|
25142
25212
|
continue;
|
|
25143
|
-
const
|
|
25213
|
+
const path100 = join3(runsDir, entry.name);
|
|
25144
25214
|
let startedAt = 0;
|
|
25145
25215
|
let endedAt;
|
|
25146
25216
|
let completed = false;
|
|
25147
25217
|
try {
|
|
25148
|
-
const manifest = JSON.parse(await readFile(join3(
|
|
25218
|
+
const manifest = JSON.parse(await readFile(join3(path100, "manifest.json"), "utf8"));
|
|
25149
25219
|
startedAt = manifest.startedAt ?? 0;
|
|
25150
25220
|
endedAt = manifest.endedAt;
|
|
25151
25221
|
completed = Boolean(endedAt) && manifest.status !== "running";
|
|
25152
25222
|
} catch {
|
|
25153
25223
|
completed = false;
|
|
25154
25224
|
}
|
|
25155
|
-
infos.push({ name: entry.name, path:
|
|
25225
|
+
infos.push({ name: entry.name, path: path100, startedAt, endedAt, completed, bytes: await dirSize(path100) });
|
|
25156
25226
|
}
|
|
25157
25227
|
const remove = async (info) => {
|
|
25158
25228
|
await rm(info.path, { recursive: true, force: true });
|
|
@@ -25639,12 +25709,12 @@ var init_engine = __esm({
|
|
|
25639
25709
|
* content digest) and the returned ref carries the event seq when the
|
|
25640
25710
|
* emitter resolved one.
|
|
25641
25711
|
*/
|
|
25642
|
-
async fsEvidence(observation,
|
|
25712
|
+
async fsEvidence(observation, path100, sha256, content, extra = {}) {
|
|
25643
25713
|
const digest = sha256 && content !== void 0 ? sha256(content) : void 0;
|
|
25644
|
-
const seq = await this.emitEvidence({ observation, path:
|
|
25714
|
+
const seq = await this.emitEvidence({ observation, path: path100, ...extra, ...digest ? { digest } : {} });
|
|
25645
25715
|
return {
|
|
25646
25716
|
tier: "fs-observation",
|
|
25647
|
-
ref:
|
|
25717
|
+
ref: path100,
|
|
25648
25718
|
capturedAt: Date.now(),
|
|
25649
25719
|
...digest ? { digest } : {},
|
|
25650
25720
|
...seq !== void 0 ? { seq } : {}
|
|
@@ -29106,7 +29176,8 @@ ${shared.content}`,
|
|
|
29106
29176
|
return {
|
|
29107
29177
|
content: resultStr,
|
|
29108
29178
|
isError: !result.ok,
|
|
29109
|
-
durationMs: Date.now() - startMs
|
|
29179
|
+
durationMs: Date.now() - startMs,
|
|
29180
|
+
...result.ok && result.images && result.images.length > 0 ? { images: result.images } : {}
|
|
29110
29181
|
};
|
|
29111
29182
|
})();
|
|
29112
29183
|
inflight.set(callKey, prom);
|
|
@@ -29127,7 +29198,8 @@ ${shared.content}`,
|
|
|
29127
29198
|
toolCallId: p3.toolCallId,
|
|
29128
29199
|
content: r.content,
|
|
29129
29200
|
isError: r.isError,
|
|
29130
|
-
endEvent
|
|
29201
|
+
endEvent,
|
|
29202
|
+
...r.images ? { images: r.images } : {}
|
|
29131
29203
|
// Cache already written in invokeOne; no need to re-set.
|
|
29132
29204
|
};
|
|
29133
29205
|
};
|
|
@@ -29679,7 +29751,8 @@ ${cached2}`
|
|
|
29679
29751
|
yield item.endEvent;
|
|
29680
29752
|
turnToolResults.push({
|
|
29681
29753
|
toolCallId: item.toolCallId,
|
|
29682
|
-
content: item.content
|
|
29754
|
+
content: item.content,
|
|
29755
|
+
...item.images ? { images: item.images } : {}
|
|
29683
29756
|
});
|
|
29684
29757
|
if (item.cacheKey && item.content && !item.isError) {
|
|
29685
29758
|
this.toolCallCache.set(item.cacheKey, item.content);
|
|
@@ -29859,7 +29932,8 @@ ${cached2}`
|
|
|
29859
29932
|
this.config.messages.push({
|
|
29860
29933
|
role: "tool",
|
|
29861
29934
|
toolCallId: tr.toolCallId,
|
|
29862
|
-
content: tr.content
|
|
29935
|
+
content: tr.content,
|
|
29936
|
+
...tr.images ? { images: tr.images } : {}
|
|
29863
29937
|
});
|
|
29864
29938
|
}
|
|
29865
29939
|
if (truncatedToolCall) {
|
|
@@ -31660,11 +31734,11 @@ var init_synthesisAudit = __esm({
|
|
|
31660
31734
|
import { existsSync as existsSync10, readFileSync as readFileSync9, writeFileSync as writeFileSync6 } from "node:fs";
|
|
31661
31735
|
import { join as join5 } from "node:path";
|
|
31662
31736
|
function loadNfrSpec(zelariRoot) {
|
|
31663
|
-
const
|
|
31664
|
-
if (!existsSync10(
|
|
31737
|
+
const path100 = join5(zelariRoot, "nfr-spec.json");
|
|
31738
|
+
if (!existsSync10(path100))
|
|
31665
31739
|
return null;
|
|
31666
31740
|
try {
|
|
31667
|
-
const raw = JSON.parse(readFileSync9(
|
|
31741
|
+
const raw = JSON.parse(readFileSync9(path100, "utf8"));
|
|
31668
31742
|
if (raw.version !== 1 || !Array.isArray(raw.targets))
|
|
31669
31743
|
return null;
|
|
31670
31744
|
return raw;
|
|
@@ -34047,9 +34121,9 @@ var init_types9 = __esm({
|
|
|
34047
34121
|
import { readFileSync as readFileSync14 } from "node:fs";
|
|
34048
34122
|
import { join as join11 } from "node:path";
|
|
34049
34123
|
function readLessonsDeduped(zelariRoot) {
|
|
34050
|
-
const
|
|
34124
|
+
const path100 = join11(zelariRoot, LESSONS_FILE);
|
|
34051
34125
|
try {
|
|
34052
|
-
const raw = readFileSync14(
|
|
34126
|
+
const raw = readFileSync14(path100, "utf8");
|
|
34053
34127
|
const byId = /* @__PURE__ */ new Map();
|
|
34054
34128
|
for (const line of raw.split(/\r?\n/)) {
|
|
34055
34129
|
if (!line.trim())
|
|
@@ -34150,8 +34224,8 @@ function keywordsFrom(check2, signature) {
|
|
|
34150
34224
|
return [.../* @__PURE__ */ new Set([...fromId, ...words])].slice(0, 12);
|
|
34151
34225
|
}
|
|
34152
34226
|
function writeLesson(zelariRoot, lesson) {
|
|
34153
|
-
const
|
|
34154
|
-
appendFileSync(
|
|
34227
|
+
const path100 = join12(zelariRoot, LESSONS_FILE);
|
|
34228
|
+
appendFileSync(path100, `${JSON.stringify(lesson)}
|
|
34155
34229
|
`, "utf8");
|
|
34156
34230
|
}
|
|
34157
34231
|
function findSimilar(lessons, signature) {
|
|
@@ -36118,9 +36192,9 @@ function findCycle(nodes) {
|
|
|
36118
36192
|
if (color.get(start) !== WHITE)
|
|
36119
36193
|
continue;
|
|
36120
36194
|
const stack = [[start, 0]];
|
|
36121
|
-
const
|
|
36195
|
+
const path100 = [];
|
|
36122
36196
|
color.set(start, GRAY);
|
|
36123
|
-
|
|
36197
|
+
path100.push(start);
|
|
36124
36198
|
while (stack.length > 0) {
|
|
36125
36199
|
const top = stack[stack.length - 1];
|
|
36126
36200
|
const [id3, idx] = top;
|
|
@@ -36133,17 +36207,17 @@ function findCycle(nodes) {
|
|
|
36133
36207
|
continue;
|
|
36134
36208
|
const c = color.get(dep);
|
|
36135
36209
|
if (c === GRAY) {
|
|
36136
|
-
const at =
|
|
36137
|
-
return [...
|
|
36210
|
+
const at = path100.indexOf(dep);
|
|
36211
|
+
return [...path100.slice(at), dep];
|
|
36138
36212
|
}
|
|
36139
36213
|
if (c === WHITE) {
|
|
36140
36214
|
color.set(dep, GRAY);
|
|
36141
|
-
|
|
36215
|
+
path100.push(dep);
|
|
36142
36216
|
stack.push([dep, 0]);
|
|
36143
36217
|
}
|
|
36144
36218
|
} else {
|
|
36145
36219
|
color.set(id3, BLACK);
|
|
36146
|
-
|
|
36220
|
+
path100.pop();
|
|
36147
36221
|
stack.pop();
|
|
36148
36222
|
}
|
|
36149
36223
|
}
|
|
@@ -37063,8 +37137,8 @@ var init_runner = __esm({
|
|
|
37063
37137
|
failed: [...this.tentaclesById.values()].filter((r) => r.status === "error"),
|
|
37064
37138
|
pending: []
|
|
37065
37139
|
};
|
|
37066
|
-
const
|
|
37067
|
-
this.host.log(`checkpoint: ${label ?? "auto"} \u2192 ${
|
|
37140
|
+
const path100 = await this.host.saveSnapshot(snapshot, ".zelari/kraken/snapshots");
|
|
37141
|
+
this.host.log(`checkpoint: ${label ?? "auto"} \u2192 ${path100}`);
|
|
37068
37142
|
return snapshot;
|
|
37069
37143
|
}
|
|
37070
37144
|
callLog(msg, data) {
|
|
@@ -38215,7 +38289,7 @@ var CORE_VERSION;
|
|
|
38215
38289
|
var init_version = __esm({
|
|
38216
38290
|
"packages/core/dist/version.js"() {
|
|
38217
38291
|
"use strict";
|
|
38218
|
-
CORE_VERSION = "2.
|
|
38292
|
+
CORE_VERSION = "2.36.0";
|
|
38219
38293
|
}
|
|
38220
38294
|
});
|
|
38221
38295
|
|
|
@@ -40673,9 +40747,9 @@ function spillToolOutput(fullText, meta3) {
|
|
|
40673
40747
|
const rnd = randomBytes3(3).toString("hex");
|
|
40674
40748
|
const safeTool = (meta3?.toolName ?? "tool").replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 32);
|
|
40675
40749
|
const file2 = `${stamp}-${safeTool}-${hash3}-${rnd}.txt`;
|
|
40676
|
-
const
|
|
40677
|
-
writeFileSync12(
|
|
40678
|
-
return
|
|
40750
|
+
const path100 = join14(dir, file2);
|
|
40751
|
+
writeFileSync12(path100, fullText, "utf8");
|
|
40752
|
+
return path100;
|
|
40679
40753
|
} catch {
|
|
40680
40754
|
return null;
|
|
40681
40755
|
}
|
|
@@ -40721,10 +40795,10 @@ function truncateToolResult(text, capOrOpts = TOOL_RESULT_LINE_CAP) {
|
|
|
40721
40795
|
${tail2}`;
|
|
40722
40796
|
}
|
|
40723
40797
|
if (doSpill) {
|
|
40724
|
-
const
|
|
40725
|
-
if (
|
|
40798
|
+
const path100 = spillToolOutput(text, { toolName: opts.toolName });
|
|
40799
|
+
if (path100) {
|
|
40726
40800
|
const spillNote = `
|
|
40727
|
-
\u2026 [full output spilled to: ${
|
|
40801
|
+
\u2026 [full output spilled to: ${path100} \u2014 re-read with read_file if you need the complete text] \u2026`;
|
|
40728
40802
|
if (preview.includes("] \u2026\n")) {
|
|
40729
40803
|
preview = preview.replace("] \u2026\n", `] \u2026${spillNote}
|
|
40730
40804
|
`);
|
|
@@ -41495,28 +41569,28 @@ var init_storage = __esm({
|
|
|
41495
41569
|
VALID_SCALARS = /^(true|false|null|~)$/i;
|
|
41496
41570
|
Storage = class {
|
|
41497
41571
|
/** Read a Markdown file with frontmatter. Throws if not found. */
|
|
41498
|
-
read(
|
|
41499
|
-
if (!existsSync19(
|
|
41500
|
-
throw new Error(`File not found: ${
|
|
41572
|
+
read(path100) {
|
|
41573
|
+
if (!existsSync19(path100)) {
|
|
41574
|
+
throw new Error(`File not found: ${path100}`);
|
|
41501
41575
|
}
|
|
41502
|
-
const md = readFileSync17(
|
|
41576
|
+
const md = readFileSync17(path100, "utf8");
|
|
41503
41577
|
return parseFrontmatter(md);
|
|
41504
41578
|
}
|
|
41505
41579
|
/** Read a Markdown file; returns null if not found. */
|
|
41506
|
-
readIfExists(
|
|
41507
|
-
if (!existsSync19(
|
|
41508
|
-
return this.read(
|
|
41580
|
+
readIfExists(path100) {
|
|
41581
|
+
if (!existsSync19(path100)) return null;
|
|
41582
|
+
return this.read(path100);
|
|
41509
41583
|
}
|
|
41510
41584
|
/**
|
|
41511
41585
|
* Write a Markdown file atomically (tmp + rename). Creates parent dirs.
|
|
41512
41586
|
* The meta object is serialized as YAML frontmatter; body as Markdown.
|
|
41513
41587
|
*/
|
|
41514
|
-
write(
|
|
41515
|
-
mkdirSync10(dirname2(
|
|
41516
|
-
const tmp =
|
|
41588
|
+
write(path100, meta3, body) {
|
|
41589
|
+
mkdirSync10(dirname2(path100), { recursive: true });
|
|
41590
|
+
const tmp = path100 + ".tmp-" + process.pid;
|
|
41517
41591
|
const md = serializeFrontmatter(meta3, body);
|
|
41518
41592
|
writeFileSync14(tmp, md, "utf8");
|
|
41519
|
-
renameSync2(tmp,
|
|
41593
|
+
renameSync2(tmp, path100);
|
|
41520
41594
|
}
|
|
41521
41595
|
/** List all .md files in a directory (non-recursive). */
|
|
41522
41596
|
listMarkdown(dir) {
|
|
@@ -41591,8 +41665,8 @@ function nextPlanTaskId(store6) {
|
|
|
41591
41665
|
return `t${store6.counter}`;
|
|
41592
41666
|
}
|
|
41593
41667
|
function writePlanTaskArtifact(rootDir, task) {
|
|
41594
|
-
const
|
|
41595
|
-
mkdirSync11(dirname3(
|
|
41668
|
+
const path100 = join17(rootDir, "plan-tasks", `${task.id}.md`);
|
|
41669
|
+
mkdirSync11(dirname3(path100), { recursive: true });
|
|
41596
41670
|
const meta3 = {
|
|
41597
41671
|
kind: "task",
|
|
41598
41672
|
id: task.id,
|
|
@@ -41613,7 +41687,7 @@ function writePlanTaskArtifact(rootDir, task) {
|
|
|
41613
41687
|
task.notes?.trim() ? task.notes.trim() : "_(no notes)_",
|
|
41614
41688
|
""
|
|
41615
41689
|
].filter((l) => l !== null).join("\n");
|
|
41616
|
-
new Storage().write(
|
|
41690
|
+
new Storage().write(path100, meta3, body);
|
|
41617
41691
|
}
|
|
41618
41692
|
function loadHandle(rootDir) {
|
|
41619
41693
|
const jsonPath = join17(rootDir, "plan.json");
|
|
@@ -50815,12 +50889,9 @@ function backoffDelay(attempt, retryAfterHeader) {
|
|
|
50815
50889
|
}
|
|
50816
50890
|
return Math.min(BACKOFF_BASE_MS * 2 ** attempt, BACKOFF_CAP_MS);
|
|
50817
50891
|
}
|
|
50818
|
-
function modelSupportsVision(
|
|
50892
|
+
function modelSupportsVision(_model) {
|
|
50819
50893
|
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));
|
|
50894
|
+
return !(force === "0" || force === "false" || force === "off");
|
|
50824
50895
|
}
|
|
50825
50896
|
function dataUriFromImage(img) {
|
|
50826
50897
|
return `data:${img.mime};base64,${img.dataBase64}`;
|
|
@@ -50915,6 +50986,22 @@ ${notes}
|
|
|
50915
50986
|
}
|
|
50916
50987
|
return { role: m.role, content: m.content };
|
|
50917
50988
|
}
|
|
50989
|
+
function imagesFollowUpMessage(images) {
|
|
50990
|
+
const labels = images.map((img) => img.alt ?? img.mime).join(", ");
|
|
50991
|
+
return {
|
|
50992
|
+
role: "user",
|
|
50993
|
+
content: [
|
|
50994
|
+
{
|
|
50995
|
+
type: "text",
|
|
50996
|
+
text: `[Immagine(i) dal tool: ${labels} \u2014 usa questi pixel per l'analisi visiva.]`
|
|
50997
|
+
},
|
|
50998
|
+
...images.map((img) => ({
|
|
50999
|
+
type: "image_url",
|
|
51000
|
+
image_url: { url: dataUriFromImage(img) }
|
|
51001
|
+
}))
|
|
51002
|
+
]
|
|
51003
|
+
};
|
|
51004
|
+
}
|
|
50918
51005
|
function positiveEnvInt(name) {
|
|
50919
51006
|
const raw = process.env[name];
|
|
50920
51007
|
if (!raw) return void 0;
|
|
@@ -50925,15 +51012,27 @@ function openaiCompatibleProvider(config2) {
|
|
|
50925
51012
|
return async function* (params) {
|
|
50926
51013
|
const capabilities = capabilitiesFor(params.model, config2.providerId);
|
|
50927
51014
|
const vision = modelSupportsVision(params.model);
|
|
50928
|
-
const
|
|
51015
|
+
const msgsIn = params.messages;
|
|
51016
|
+
let toolRunImages = [];
|
|
51017
|
+
const messages = msgsIn.flatMap((m, i) => {
|
|
50929
51018
|
const cacheable = !(m.role === "user" && m.images && m.images.length > 0);
|
|
50930
51019
|
if (cacheable) {
|
|
50931
51020
|
const cached2 = messageMappingCache.get(m);
|
|
50932
|
-
if (cached2) return cached2;
|
|
51021
|
+
if (cached2) return [cached2];
|
|
50933
51022
|
}
|
|
50934
51023
|
const mapped = mapAgentMessage(m, vision);
|
|
50935
51024
|
if (cacheable) messageMappingCache.set(m, mapped);
|
|
50936
|
-
|
|
51025
|
+
if (m.role === "tool") {
|
|
51026
|
+
if (m.images && m.images.length > 0) toolRunImages.push(...m.images);
|
|
51027
|
+
const next = msgsIn[i + 1];
|
|
51028
|
+
const runEnds = !next || next.role !== "tool";
|
|
51029
|
+
if (runEnds && vision && toolRunImages.length > 0) {
|
|
51030
|
+
const followUp = imagesFollowUpMessage(toolRunImages);
|
|
51031
|
+
toolRunImages = [];
|
|
51032
|
+
return [mapped, followUp];
|
|
51033
|
+
}
|
|
51034
|
+
}
|
|
51035
|
+
return [mapped];
|
|
50937
51036
|
});
|
|
50938
51037
|
const generation = params.generation;
|
|
50939
51038
|
const body = {
|
|
@@ -50985,7 +51084,7 @@ function openaiCompatibleProvider(config2) {
|
|
|
50985
51084
|
const forceRecoveryTool = generation?.toolChoice === "required" && capabilities.buildRecovery.forceToolChoice && recoveryAttempt <= capabilities.buildRecovery.maxForcedTurns;
|
|
50986
51085
|
body.tool_choice = forceRecoveryTool ? "required" : "auto";
|
|
50987
51086
|
}
|
|
50988
|
-
const
|
|
51087
|
+
const headers3 = {
|
|
50989
51088
|
"Content-Type": "application/json",
|
|
50990
51089
|
Authorization: `Bearer ${config2.apiKey}`,
|
|
50991
51090
|
...config2.extraHeaders ?? {}
|
|
@@ -50993,7 +51092,7 @@ function openaiCompatibleProvider(config2) {
|
|
|
50993
51092
|
const affinityHeader = capabilities.promptCache.conversationAffinityHeader;
|
|
50994
51093
|
const conversationId = params.conversationId?.trim();
|
|
50995
51094
|
if (affinityHeader && conversationId && conversationId.length <= 256 && !/[\u0000-\u001f\u007f]/.test(conversationId)) {
|
|
50996
|
-
|
|
51095
|
+
headers3[affinityHeader] = conversationId;
|
|
50997
51096
|
}
|
|
50998
51097
|
let response;
|
|
50999
51098
|
let lastErrText = "";
|
|
@@ -51018,7 +51117,7 @@ function openaiCompatibleProvider(config2) {
|
|
|
51018
51117
|
try {
|
|
51019
51118
|
response = await fetch(`${config2.baseUrl}/chat/completions`, {
|
|
51020
51119
|
method: "POST",
|
|
51021
|
-
headers:
|
|
51120
|
+
headers: headers3,
|
|
51022
51121
|
body: JSON.stringify(body),
|
|
51023
51122
|
// Cancel aborts the HTTP request; stream idle is enforced below
|
|
51024
51123
|
// per-chunk so active multi-minute streams are not killed.
|
|
@@ -51257,7 +51356,7 @@ async function providerConfigFor(providerId) {
|
|
|
51257
51356
|
...extraFromStored(providerId)
|
|
51258
51357
|
};
|
|
51259
51358
|
}
|
|
51260
|
-
var RETRYABLE_STATUSES, MAX_RETRIES, BACKOFF_BASE_MS, BACKOFF_CAP_MS, PROVIDER_CONNECT_TIMEOUT_MS, PROVIDER_STREAM_IDLE_MS, PROVIDER_STREAM_MAX_MS,
|
|
51359
|
+
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
51360
|
var init_openai_compatible = __esm({
|
|
51262
51361
|
"src/cli/provider/openai-compatible.ts"() {
|
|
51263
51362
|
"use strict";
|
|
@@ -51288,33 +51387,6 @@ var init_openai_compatible = __esm({
|
|
|
51288
51387
|
const n = raw ? Number.parseInt(raw, 10) : 18e5;
|
|
51289
51388
|
return Number.isFinite(n) && n >= 6e4 ? n : 18e5;
|
|
51290
51389
|
})();
|
|
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
51390
|
PROVIDER_ENDPOINTS = {
|
|
51319
51391
|
"openai-compatible": "https://api.x.ai/v1",
|
|
51320
51392
|
"minimax": "https://api.minimax.io/v1",
|
|
@@ -51709,6 +51781,16 @@ var init_driver = __esm({
|
|
|
51709
51781
|
// src/cli/browser/tools.ts
|
|
51710
51782
|
import path56 from "node:path";
|
|
51711
51783
|
import os3 from "node:os";
|
|
51784
|
+
import { readFile as readFile7 } from "node:fs/promises";
|
|
51785
|
+
async function loadImageBlock(filePath) {
|
|
51786
|
+
try {
|
|
51787
|
+
const buf = await readFile7(filePath);
|
|
51788
|
+
if (buf.byteLength > SCREENSHOT_MAX_BYTES) return void 0;
|
|
51789
|
+
return { mime: "image/png", dataBase64: buf.toString("base64"), alt: path56.basename(filePath) };
|
|
51790
|
+
} catch {
|
|
51791
|
+
return void 0;
|
|
51792
|
+
}
|
|
51793
|
+
}
|
|
51712
51794
|
function createBrowserTool(deps = {}) {
|
|
51713
51795
|
return {
|
|
51714
51796
|
name: "browser_check",
|
|
@@ -51761,17 +51843,23 @@ function createBrowserTool(deps = {}) {
|
|
|
51761
51843
|
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
51844
|
smokeStrength: "weak"
|
|
51763
51845
|
} : { smokeStrength: "asserted" }
|
|
51764
|
-
});
|
|
51846
|
+
}, void 0, await toolImages(result.screenshotPath));
|
|
51765
51847
|
}
|
|
51766
51848
|
};
|
|
51767
51849
|
}
|
|
51768
|
-
|
|
51850
|
+
async function toolImages(screenshotPath) {
|
|
51851
|
+
if (!screenshotPath) return void 0;
|
|
51852
|
+
const image = await loadImageBlock(screenshotPath);
|
|
51853
|
+
return image ? [image] : void 0;
|
|
51854
|
+
}
|
|
51855
|
+
var SCREENSHOT_MAX_BYTES, ActionSchema;
|
|
51769
51856
|
var init_tools5 = __esm({
|
|
51770
51857
|
"src/cli/browser/tools.ts"() {
|
|
51771
51858
|
"use strict";
|
|
51772
51859
|
init_zod();
|
|
51773
51860
|
init_toolTypes();
|
|
51774
51861
|
init_driver();
|
|
51862
|
+
SCREENSHOT_MAX_BYTES = 8 * 1024 * 1024;
|
|
51775
51863
|
ActionSchema = external_exports.discriminatedUnion("type", [
|
|
51776
51864
|
external_exports.object({ type: external_exports.literal("click"), selector: external_exports.string().min(1) }),
|
|
51777
51865
|
external_exports.object({ type: external_exports.literal("fill"), selector: external_exports.string().min(1), value: external_exports.string() }),
|
|
@@ -51796,6 +51884,92 @@ var init_tools5 = __esm({
|
|
|
51796
51884
|
}
|
|
51797
51885
|
});
|
|
51798
51886
|
|
|
51887
|
+
// src/cli/tools/screenshotTool.ts
|
|
51888
|
+
import { execFile as execFile5 } from "node:child_process";
|
|
51889
|
+
import { mkdir as mkdir3, readFile as readFile8, stat as stat7 } from "node:fs/promises";
|
|
51890
|
+
import path57 from "node:path";
|
|
51891
|
+
import { promisify as promisify4 } from "node:util";
|
|
51892
|
+
async function captureWindows(target) {
|
|
51893
|
+
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();`;
|
|
51894
|
+
await execFileAsync4("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", script], {
|
|
51895
|
+
timeout: 12e3,
|
|
51896
|
+
windowsHide: true
|
|
51897
|
+
});
|
|
51898
|
+
}
|
|
51899
|
+
async function captureUnixLike(target) {
|
|
51900
|
+
const attempts = process.platform === "darwin" ? [["screencapture", ["-x", target]]] : [
|
|
51901
|
+
["gnome-screenshot", ["-f", target]],
|
|
51902
|
+
["scrot", [target]],
|
|
51903
|
+
["import", ["-window", "root", target]]
|
|
51904
|
+
];
|
|
51905
|
+
let lastErr = null;
|
|
51906
|
+
for (const [bin, args] of attempts) {
|
|
51907
|
+
try {
|
|
51908
|
+
await execFileAsync4(bin, args, { timeout: 12e3 });
|
|
51909
|
+
return;
|
|
51910
|
+
} catch (e) {
|
|
51911
|
+
lastErr = e;
|
|
51912
|
+
}
|
|
51913
|
+
}
|
|
51914
|
+
throw lastErr ?? new Error("no screen-capture utility available");
|
|
51915
|
+
}
|
|
51916
|
+
function createScreenshotTool(deps = {}) {
|
|
51917
|
+
return {
|
|
51918
|
+
name: "screenshot",
|
|
51919
|
+
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.",
|
|
51920
|
+
permissions: ["ui"],
|
|
51921
|
+
timeoutMs: 2e4,
|
|
51922
|
+
inputSchema: external_exports.object({
|
|
51923
|
+
note: external_exports.string().max(200).optional().describe("Why you are capturing (shown to the user with the permission prompt).")
|
|
51924
|
+
}),
|
|
51925
|
+
execute: async (args, ctx) => {
|
|
51926
|
+
const a = args;
|
|
51927
|
+
const dir = deps.outDir ?? path57.join(ctx.cwd ?? process.cwd(), ".zelari", "screenshots");
|
|
51928
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
51929
|
+
const target = path57.join(dir, `screenshot-${stamp}.png`);
|
|
51930
|
+
const capture = deps.capture ?? (process.platform === "win32" ? captureWindows : captureUnixLike);
|
|
51931
|
+
try {
|
|
51932
|
+
await mkdir3(dir, { recursive: true });
|
|
51933
|
+
await capture(target);
|
|
51934
|
+
const meta3 = await stat7(target);
|
|
51935
|
+
if (meta3.size === 0) return typedErr(`capture produced an empty file: ${target}`);
|
|
51936
|
+
const buf = await readFile8(target);
|
|
51937
|
+
const image = {
|
|
51938
|
+
mime: "image/png",
|
|
51939
|
+
dataBase64: buf.toString("base64"),
|
|
51940
|
+
alt: path57.basename(target)
|
|
51941
|
+
};
|
|
51942
|
+
const attachable = meta3.size <= SCREENSHOT_MAX_BYTES2;
|
|
51943
|
+
return typedOk(
|
|
51944
|
+
{
|
|
51945
|
+
ok: true,
|
|
51946
|
+
path: target,
|
|
51947
|
+
bytes: meta3.size,
|
|
51948
|
+
...a.note ? { note: a.note } : {},
|
|
51949
|
+
...attachable ? {} : { warning: "PNG over 8MB: pixels not attached to the model context; open the path instead." }
|
|
51950
|
+
},
|
|
51951
|
+
void 0,
|
|
51952
|
+
attachable ? [image] : void 0
|
|
51953
|
+
);
|
|
51954
|
+
} catch (e) {
|
|
51955
|
+
return typedErr(
|
|
51956
|
+
`screen capture failed on ${process.platform}: ${e instanceof Error ? e.message : String(e)}`
|
|
51957
|
+
);
|
|
51958
|
+
}
|
|
51959
|
+
}
|
|
51960
|
+
};
|
|
51961
|
+
}
|
|
51962
|
+
var execFileAsync4, SCREENSHOT_MAX_BYTES2;
|
|
51963
|
+
var init_screenshotTool = __esm({
|
|
51964
|
+
"src/cli/tools/screenshotTool.ts"() {
|
|
51965
|
+
"use strict";
|
|
51966
|
+
init_zod();
|
|
51967
|
+
init_toolTypes();
|
|
51968
|
+
execFileAsync4 = promisify4(execFile5);
|
|
51969
|
+
SCREENSHOT_MAX_BYTES2 = 8 * 1024 * 1024;
|
|
51970
|
+
}
|
|
51971
|
+
});
|
|
51972
|
+
|
|
51799
51973
|
// src/cli/ssh/targets.ts
|
|
51800
51974
|
var targets_exports = {};
|
|
51801
51975
|
__export(targets_exports, {
|
|
@@ -51837,21 +52011,21 @@ function normalizeAuth(auth) {
|
|
|
51837
52011
|
return "agent";
|
|
51838
52012
|
}
|
|
51839
52013
|
function readSecrets() {
|
|
51840
|
-
const
|
|
51841
|
-
if (!existsSync30(
|
|
52014
|
+
const path100 = getSshSecretsPath();
|
|
52015
|
+
if (!existsSync30(path100)) return {};
|
|
51842
52016
|
try {
|
|
51843
|
-
return JSON.parse(readFileSync22(
|
|
52017
|
+
return JSON.parse(readFileSync22(path100, "utf8"));
|
|
51844
52018
|
} catch {
|
|
51845
52019
|
return {};
|
|
51846
52020
|
}
|
|
51847
52021
|
}
|
|
51848
52022
|
function writeSecrets(data) {
|
|
51849
|
-
const
|
|
51850
|
-
mkdirSync13(dirname4(
|
|
51851
|
-
writeFileSync16(
|
|
52023
|
+
const path100 = getSshSecretsPath();
|
|
52024
|
+
mkdirSync13(dirname4(path100), { recursive: true });
|
|
52025
|
+
writeFileSync16(path100, `${JSON.stringify(data, null, 2)}
|
|
51852
52026
|
`, "utf8");
|
|
51853
52027
|
try {
|
|
51854
|
-
chmodSync(
|
|
52028
|
+
chmodSync(path100, 384);
|
|
51855
52029
|
} catch {
|
|
51856
52030
|
}
|
|
51857
52031
|
}
|
|
@@ -51880,10 +52054,10 @@ function deleteSshPassword(id3) {
|
|
|
51880
52054
|
writeSecrets({ passwords });
|
|
51881
52055
|
}
|
|
51882
52056
|
function readStore2() {
|
|
51883
|
-
const
|
|
51884
|
-
if (!existsSync30(
|
|
52057
|
+
const path100 = getSshTargetsPath();
|
|
52058
|
+
if (!existsSync30(path100)) return [];
|
|
51885
52059
|
try {
|
|
51886
|
-
const parsed = JSON.parse(readFileSync22(
|
|
52060
|
+
const parsed = JSON.parse(readFileSync22(path100, "utf8"));
|
|
51887
52061
|
const list = Array.isArray(parsed.targets) ? parsed.targets : [];
|
|
51888
52062
|
return list.filter(
|
|
51889
52063
|
(t) => t && typeof t.id === "string" && typeof t.host === "string" && typeof t.user === "string"
|
|
@@ -51898,11 +52072,11 @@ function readStore2() {
|
|
|
51898
52072
|
}
|
|
51899
52073
|
}
|
|
51900
52074
|
function writeStore2(targets) {
|
|
51901
|
-
const
|
|
51902
|
-
mkdirSync13(dirname4(
|
|
52075
|
+
const path100 = getSshTargetsPath();
|
|
52076
|
+
mkdirSync13(dirname4(path100), { recursive: true });
|
|
51903
52077
|
const clean = targets.map(({ hasPassword: _hp, ...t }) => t);
|
|
51904
52078
|
writeFileSync16(
|
|
51905
|
-
|
|
52079
|
+
path100,
|
|
51906
52080
|
`${JSON.stringify({ targets: clean }, null, 2)}
|
|
51907
52081
|
`,
|
|
51908
52082
|
"utf8"
|
|
@@ -52148,11 +52322,11 @@ function formatSshTargetsForPrompt() {
|
|
|
52148
52322
|
];
|
|
52149
52323
|
for (const t of targets) {
|
|
52150
52324
|
const tags = t.tags?.length ? ` tags=[${t.tags.join(",")}]` : "";
|
|
52151
|
-
const
|
|
52325
|
+
const path100 = t.defaultRemotePath ? ` remotePath=${t.defaultRemotePath}` : "";
|
|
52152
52326
|
const allow = t.allowedCommands?.length ? ` allowed=${t.allowedCommands.join("|")}` : " allowed=status-only";
|
|
52153
52327
|
const auth = t.auth === "password" ? " auth=password" : t.auth === "keyPath" ? " auth=key" : " auth=agent";
|
|
52154
52328
|
lines.push(
|
|
52155
|
-
`- id=${t.id} name=${t.name} ${t.user}@${t.host}:${t.port ?? 22}${auth}${
|
|
52329
|
+
`- id=${t.id} name=${t.name} ${t.user}@${t.host}:${t.port ?? 22}${auth}${path100}${tags}${allow}`
|
|
52156
52330
|
);
|
|
52157
52331
|
}
|
|
52158
52332
|
return lines.join("\n");
|
|
@@ -52852,6 +53026,244 @@ var init_chatgpt = __esm({
|
|
|
52852
53026
|
}
|
|
52853
53027
|
});
|
|
52854
53028
|
|
|
53029
|
+
// src/cli/provider/responsesApi.ts
|
|
53030
|
+
function backoffDelay2(attempt, retryAfterHeader) {
|
|
53031
|
+
if (retryAfterHeader) {
|
|
53032
|
+
const seconds = Number.parseFloat(retryAfterHeader);
|
|
53033
|
+
if (Number.isFinite(seconds) && seconds >= 0) {
|
|
53034
|
+
return Math.min(seconds * 1e3, BACKOFF_CAP_MS2);
|
|
53035
|
+
}
|
|
53036
|
+
}
|
|
53037
|
+
return Math.min(BACKOFF_BASE_MS2 * 2 ** attempt, BACKOFF_CAP_MS2);
|
|
53038
|
+
}
|
|
53039
|
+
function abortableSleep2(ms, signal) {
|
|
53040
|
+
return new Promise((resolve9) => {
|
|
53041
|
+
if (signal?.aborted) return resolve9();
|
|
53042
|
+
const t = setTimeout(resolve9, ms);
|
|
53043
|
+
signal?.addEventListener(
|
|
53044
|
+
"abort",
|
|
53045
|
+
() => {
|
|
53046
|
+
clearTimeout(t);
|
|
53047
|
+
resolve9();
|
|
53048
|
+
},
|
|
53049
|
+
{ once: true }
|
|
53050
|
+
);
|
|
53051
|
+
});
|
|
53052
|
+
}
|
|
53053
|
+
function headers2(config2) {
|
|
53054
|
+
const h = {
|
|
53055
|
+
"Content-Type": "application/json",
|
|
53056
|
+
Accept: "text/event-stream",
|
|
53057
|
+
Authorization: `Bearer ${config2.apiKey}`
|
|
53058
|
+
};
|
|
53059
|
+
if (config2.extraHeaders) Object.assign(h, config2.extraHeaders);
|
|
53060
|
+
return h;
|
|
53061
|
+
}
|
|
53062
|
+
function responsesApiProvider(config2) {
|
|
53063
|
+
return async function* (params) {
|
|
53064
|
+
const capabilities = capabilitiesFor(params.model, config2.providerId);
|
|
53065
|
+
const { instructions, input } = toInput(params.messages);
|
|
53066
|
+
const body = {
|
|
53067
|
+
model: params.model,
|
|
53068
|
+
stream: true,
|
|
53069
|
+
input
|
|
53070
|
+
};
|
|
53071
|
+
if (instructions) body.instructions = instructions;
|
|
53072
|
+
if (params.tools && params.tools.length > 0) {
|
|
53073
|
+
body.tools = params.tools.map((t) => ({
|
|
53074
|
+
type: "function",
|
|
53075
|
+
name: t.name,
|
|
53076
|
+
description: t.description,
|
|
53077
|
+
parameters: t.parameters
|
|
53078
|
+
}));
|
|
53079
|
+
}
|
|
53080
|
+
const generation = params.generation;
|
|
53081
|
+
body.temperature = generation?.temperature ?? capabilities.sampling.temperature;
|
|
53082
|
+
const maxTokens = generation?.maxTokens ?? capabilities.maxOutputTokens;
|
|
53083
|
+
if (typeof maxTokens === "number" && maxTokens > 0) {
|
|
53084
|
+
body.max_output_tokens = maxTokens;
|
|
53085
|
+
}
|
|
53086
|
+
const thinkingSpec = config2.thinking ?? "auto";
|
|
53087
|
+
if (thinkingSpec !== "auto") {
|
|
53088
|
+
const t = translateResponsesThinking(thinkingSpec, config2.model, config2.providerId);
|
|
53089
|
+
if (t.degraded) {
|
|
53090
|
+
console.warn(`[thinking] ${t.note ?? "unsupported"} \u2014 falling back to provider default.`);
|
|
53091
|
+
} else {
|
|
53092
|
+
Object.assign(body, t.patch);
|
|
53093
|
+
}
|
|
53094
|
+
}
|
|
53095
|
+
const base2 = config2.baseUrl.replace(/\/$/, "");
|
|
53096
|
+
const url2 = `${base2}/responses`;
|
|
53097
|
+
let response;
|
|
53098
|
+
let lastStatus = 0;
|
|
53099
|
+
let lastErrText = "";
|
|
53100
|
+
for (let attempt = 0; ; attempt++) {
|
|
53101
|
+
const connectController = new AbortController();
|
|
53102
|
+
const connectTimer = setTimeout(
|
|
53103
|
+
() => connectController.abort(
|
|
53104
|
+
new Error(
|
|
53105
|
+
`Provider connect timeout after ${Math.round(PROVIDER_CONNECT_TIMEOUT_MS / 1e3)}s (no response headers). Override ZELARI_PROVIDER_CONNECT_TIMEOUT_MS.`
|
|
53106
|
+
)
|
|
53107
|
+
),
|
|
53108
|
+
PROVIDER_CONNECT_TIMEOUT_MS
|
|
53109
|
+
);
|
|
53110
|
+
const signals = [connectController.signal];
|
|
53111
|
+
if (params.signal) signals.push(params.signal);
|
|
53112
|
+
try {
|
|
53113
|
+
response = await fetch(url2, {
|
|
53114
|
+
method: "POST",
|
|
53115
|
+
headers: headers2(config2),
|
|
53116
|
+
body: JSON.stringify(body),
|
|
53117
|
+
signal: signals.length === 1 ? signals[0] : AbortSignal.any(signals)
|
|
53118
|
+
});
|
|
53119
|
+
} catch (err) {
|
|
53120
|
+
lastStatus = 0;
|
|
53121
|
+
lastErrText = err instanceof Error ? err.message : String(err);
|
|
53122
|
+
if (params.signal?.aborted) {
|
|
53123
|
+
yield { kind: "error", message: "aborted" };
|
|
53124
|
+
return;
|
|
53125
|
+
}
|
|
53126
|
+
if (attempt < MAX_RETRIES2) {
|
|
53127
|
+
await abortableSleep2(backoffDelay2(attempt, null), params.signal);
|
|
53128
|
+
continue;
|
|
53129
|
+
}
|
|
53130
|
+
yield { kind: "error", message: `Network error: ${lastErrText}` };
|
|
53131
|
+
return;
|
|
53132
|
+
} finally {
|
|
53133
|
+
clearTimeout(connectTimer);
|
|
53134
|
+
}
|
|
53135
|
+
if (response.ok && response.body) break;
|
|
53136
|
+
lastStatus = response.status;
|
|
53137
|
+
lastErrText = await response.text().catch(() => "");
|
|
53138
|
+
if (!RETRYABLE_STATUSES2.has(response.status) || attempt >= MAX_RETRIES2) break;
|
|
53139
|
+
await abortableSleep2(backoffDelay2(attempt, response.headers.get("retry-after")), params.signal);
|
|
53140
|
+
if (params.signal?.aborted) {
|
|
53141
|
+
yield { kind: "error", message: "aborted" };
|
|
53142
|
+
return;
|
|
53143
|
+
}
|
|
53144
|
+
}
|
|
53145
|
+
if (!response || !response.ok || !response.body) {
|
|
53146
|
+
const msg = lastStatus === 0 ? `Network error: ${lastErrText}` : `HTTP ${lastStatus}: ${lastErrText.slice(0, 240)}`;
|
|
53147
|
+
yield { kind: "error", message: msg };
|
|
53148
|
+
return;
|
|
53149
|
+
}
|
|
53150
|
+
const reader = response.body.getReader();
|
|
53151
|
+
const decoder = new TextDecoder();
|
|
53152
|
+
let buffer = "";
|
|
53153
|
+
const tools = /* @__PURE__ */ new Map();
|
|
53154
|
+
let emittedTool = false;
|
|
53155
|
+
const flush = function* (id3) {
|
|
53156
|
+
const t = tools.get(id3);
|
|
53157
|
+
if (!t?.name) return;
|
|
53158
|
+
let args = {};
|
|
53159
|
+
try {
|
|
53160
|
+
args = JSON.parse(t.argsJson || "{}");
|
|
53161
|
+
} catch {
|
|
53162
|
+
args = {};
|
|
53163
|
+
}
|
|
53164
|
+
tools.delete(id3);
|
|
53165
|
+
emittedTool = true;
|
|
53166
|
+
yield { kind: "tool_call", toolCallId: t.id, toolName: t.name, args };
|
|
53167
|
+
};
|
|
53168
|
+
const streamStartedAt = Date.now();
|
|
53169
|
+
let lastUsefulAt = streamStartedAt;
|
|
53170
|
+
const streamDeadline = streamStartedAt + PROVIDER_STREAM_MAX_MS;
|
|
53171
|
+
try {
|
|
53172
|
+
while (true) {
|
|
53173
|
+
const { value, done } = await readChunkWithTimeout(reader, {
|
|
53174
|
+
idleMs: PROVIDER_STREAM_IDLE_MS,
|
|
53175
|
+
deadlineMs: streamDeadline,
|
|
53176
|
+
signal: params.signal,
|
|
53177
|
+
lastUsefulAt: () => lastUsefulAt
|
|
53178
|
+
});
|
|
53179
|
+
if (done) break;
|
|
53180
|
+
buffer += decoder.decode(value, { stream: true });
|
|
53181
|
+
const lines = buffer.split("\n");
|
|
53182
|
+
buffer = lines.pop() ?? "";
|
|
53183
|
+
for (const line of lines) {
|
|
53184
|
+
const trimmed = line.trim();
|
|
53185
|
+
if (!trimmed.startsWith("data:")) continue;
|
|
53186
|
+
const data = trimmed.slice(5).trim();
|
|
53187
|
+
if (!data || data === "[DONE]") continue;
|
|
53188
|
+
let ev;
|
|
53189
|
+
try {
|
|
53190
|
+
ev = JSON.parse(data);
|
|
53191
|
+
} catch {
|
|
53192
|
+
continue;
|
|
53193
|
+
}
|
|
53194
|
+
const type = typeof ev.type === "string" ? ev.type : "";
|
|
53195
|
+
if (type) lastUsefulAt = Date.now();
|
|
53196
|
+
if (type === "response.output_text.delta" && typeof ev.delta === "string") {
|
|
53197
|
+
yield { kind: "text", delta: ev.delta };
|
|
53198
|
+
} else if (type === "response.reasoning_text.delta" && typeof ev.delta === "string") {
|
|
53199
|
+
yield { kind: "thinking", delta: ev.delta };
|
|
53200
|
+
} else if (type === "response.output_item.added") {
|
|
53201
|
+
const item = ev.item;
|
|
53202
|
+
if (item?.type === "function_call") {
|
|
53203
|
+
const id3 = String(item.call_id ?? item.id ?? `fc-${tools.size}`);
|
|
53204
|
+
tools.set(id3, {
|
|
53205
|
+
id: id3,
|
|
53206
|
+
name: typeof item.name === "string" ? item.name : "",
|
|
53207
|
+
argsJson: typeof item.arguments === "string" ? item.arguments : ""
|
|
53208
|
+
});
|
|
53209
|
+
}
|
|
53210
|
+
} else if (type === "response.function_call_arguments.delta") {
|
|
53211
|
+
const itemId = String(ev.item_id ?? ev.call_id ?? "");
|
|
53212
|
+
const existing = itemId ? tools.get(itemId) : [...tools.values()].at(-1);
|
|
53213
|
+
if (existing && typeof ev.delta === "string") existing.argsJson += ev.delta;
|
|
53214
|
+
} else if (type === "response.output_item.done") {
|
|
53215
|
+
const item = ev.item;
|
|
53216
|
+
if (item?.type === "function_call") {
|
|
53217
|
+
const id3 = String(item.call_id ?? item.id ?? "");
|
|
53218
|
+
if (id3) yield* flush(id3);
|
|
53219
|
+
}
|
|
53220
|
+
} else if (type === "response.completed") {
|
|
53221
|
+
const usage = ev.response?.usage;
|
|
53222
|
+
if (usage) {
|
|
53223
|
+
yield {
|
|
53224
|
+
kind: "usage",
|
|
53225
|
+
usage: {
|
|
53226
|
+
promptTokens: usage.input_tokens ?? usage.prompt_tokens ?? 0,
|
|
53227
|
+
completionTokens: usage.output_tokens ?? usage.completion_tokens ?? 0,
|
|
53228
|
+
totalTokens: usage.total_tokens ?? (usage.input_tokens ?? 0) + (usage.output_tokens ?? 0)
|
|
53229
|
+
}
|
|
53230
|
+
};
|
|
53231
|
+
}
|
|
53232
|
+
yield { kind: "finish", reason: emittedTool ? "tool_calls" : "stop" };
|
|
53233
|
+
return;
|
|
53234
|
+
} else if (type === "response.failed" || type === "error") {
|
|
53235
|
+
const msg = typeof ev.message === "string" ? ev.message : JSON.stringify(ev.error ?? ev).slice(0, 200);
|
|
53236
|
+
yield { kind: "error", message: msg };
|
|
53237
|
+
return;
|
|
53238
|
+
}
|
|
53239
|
+
}
|
|
53240
|
+
}
|
|
53241
|
+
for (const id3 of [...tools.keys()]) yield* flush(id3);
|
|
53242
|
+
yield { kind: "finish", reason: emittedTool ? "tool_calls" : "stop" };
|
|
53243
|
+
} finally {
|
|
53244
|
+
reader.releaseLock();
|
|
53245
|
+
}
|
|
53246
|
+
};
|
|
53247
|
+
}
|
|
53248
|
+
var RETRYABLE_STATUSES2, MAX_RETRIES2, BACKOFF_BASE_MS2, BACKOFF_CAP_MS2;
|
|
53249
|
+
var init_responsesApi = __esm({
|
|
53250
|
+
"src/cli/provider/responsesApi.ts"() {
|
|
53251
|
+
"use strict";
|
|
53252
|
+
init_openai_compatible();
|
|
53253
|
+
init_chatgpt();
|
|
53254
|
+
init_thinking();
|
|
53255
|
+
init_capabilities();
|
|
53256
|
+
RETRYABLE_STATUSES2 = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
53257
|
+
MAX_RETRIES2 = (() => {
|
|
53258
|
+
const raw = process.env.ZELARI_PROVIDER_MAX_RETRIES;
|
|
53259
|
+
const n = raw ? Number.parseInt(raw, 10) : 3;
|
|
53260
|
+
return Number.isFinite(n) && n >= 0 ? n : 3;
|
|
53261
|
+
})();
|
|
53262
|
+
BACKOFF_BASE_MS2 = 500;
|
|
53263
|
+
BACKOFF_CAP_MS2 = 8e3;
|
|
53264
|
+
}
|
|
53265
|
+
});
|
|
53266
|
+
|
|
52855
53267
|
// src/cli/provider/resolveStream.ts
|
|
52856
53268
|
var resolveStream_exports = {};
|
|
52857
53269
|
__export(resolveStream_exports, {
|
|
@@ -52860,6 +53272,9 @@ __export(resolveStream_exports, {
|
|
|
52860
53272
|
function buildProviderStream(config2) {
|
|
52861
53273
|
if (config2.providerId === "anthropic") return anthropicMessagesProvider(config2);
|
|
52862
53274
|
if (config2.providerId === "chatgpt") return chatgptResponsesProvider(config2);
|
|
53275
|
+
if (getApiStyleFor(config2.providerId) === "responses") {
|
|
53276
|
+
return responsesApiProvider(config2);
|
|
53277
|
+
}
|
|
52863
53278
|
return openaiCompatibleProvider(config2);
|
|
52864
53279
|
}
|
|
52865
53280
|
var init_resolveStream = __esm({
|
|
@@ -52868,6 +53283,8 @@ var init_resolveStream = __esm({
|
|
|
52868
53283
|
init_openai_compatible();
|
|
52869
53284
|
init_anthropic();
|
|
52870
53285
|
init_chatgpt();
|
|
53286
|
+
init_responsesApi();
|
|
53287
|
+
init_providerConfig();
|
|
52871
53288
|
}
|
|
52872
53289
|
});
|
|
52873
53290
|
|
|
@@ -53138,12 +53555,12 @@ __export(folderTrust_exports, {
|
|
|
53138
53555
|
untrustFolder: () => untrustFolder
|
|
53139
53556
|
});
|
|
53140
53557
|
import { existsSync as existsSync31, mkdirSync as mkdirSync14, readFileSync as readFileSync23, writeFileSync as writeFileSync17 } from "node:fs";
|
|
53141
|
-
import
|
|
53558
|
+
import path58 from "node:path";
|
|
53142
53559
|
function trustStorePath() {
|
|
53143
53560
|
return _overrideStorePath ?? trustConfigPath();
|
|
53144
53561
|
}
|
|
53145
53562
|
function normalize6(p3) {
|
|
53146
|
-
const resolved =
|
|
53563
|
+
const resolved = path58.resolve(p3);
|
|
53147
53564
|
return process.platform === "win32" ? resolved.toLowerCase() : resolved;
|
|
53148
53565
|
}
|
|
53149
53566
|
function readStore3() {
|
|
@@ -53159,7 +53576,7 @@ function readStore3() {
|
|
|
53159
53576
|
function writeStore3(store6) {
|
|
53160
53577
|
const p3 = trustStorePath();
|
|
53161
53578
|
try {
|
|
53162
|
-
mkdirSync14(
|
|
53579
|
+
mkdirSync14(path58.dirname(p3), { recursive: true });
|
|
53163
53580
|
writeFileSync17(p3, JSON.stringify(store6, null, 2), "utf8");
|
|
53164
53581
|
} catch (err) {
|
|
53165
53582
|
throw new Error(
|
|
@@ -53185,7 +53602,7 @@ function isFolderTrusted(folderPath) {
|
|
|
53185
53602
|
}
|
|
53186
53603
|
function trustFolder(folderPath) {
|
|
53187
53604
|
const store6 = readStore3();
|
|
53188
|
-
const normalized =
|
|
53605
|
+
const normalized = path58.resolve(folderPath);
|
|
53189
53606
|
if (!store6.folders.some((f) => normalize6(f.path) === normalize6(normalized))) {
|
|
53190
53607
|
store6.folders.push({ path: normalized, trustedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
53191
53608
|
writeStore3(store6);
|
|
@@ -53311,7 +53728,7 @@ var init_lifecycleHooks = __esm({
|
|
|
53311
53728
|
|
|
53312
53729
|
// src/cli/safety/astGate.ts
|
|
53313
53730
|
import { promises as fs23 } from "node:fs";
|
|
53314
|
-
import
|
|
53731
|
+
import path59 from "node:path";
|
|
53315
53732
|
function astGateEnabled() {
|
|
53316
53733
|
return process.env.ZELARI_AST_GATE !== "0";
|
|
53317
53734
|
}
|
|
@@ -53346,9 +53763,9 @@ function wrapWithAstGate(original, opts) {
|
|
|
53346
53763
|
const containedPathOf = (args) => {
|
|
53347
53764
|
const raw = args["path"];
|
|
53348
53765
|
if (typeof raw !== "string" || raw.length === 0) return null;
|
|
53349
|
-
const absPath =
|
|
53350
|
-
const rel2 =
|
|
53351
|
-
if (rel2.startsWith("..") ||
|
|
53766
|
+
const absPath = path59.isAbsolute(raw) ? raw : path59.join(opts.root, raw);
|
|
53767
|
+
const rel2 = path59.relative(opts.root, absPath);
|
|
53768
|
+
if (rel2.startsWith("..") || path59.isAbsolute(rel2)) return null;
|
|
53352
53769
|
return absPath;
|
|
53353
53770
|
};
|
|
53354
53771
|
return {
|
|
@@ -53373,7 +53790,7 @@ function wrapWithAstGate(original, opts) {
|
|
|
53373
53790
|
if (!result.ok) return result;
|
|
53374
53791
|
if (gateTarget !== null && !isAstSupported(gateTarget)) {
|
|
53375
53792
|
process.stderr.write(
|
|
53376
|
-
`[ast_gate] LOUD SKIP (unsupported-extension): ${original.name} ${gateTarget} \u2014 ${
|
|
53793
|
+
`[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
53794
|
`
|
|
53378
53795
|
);
|
|
53379
53796
|
return result;
|
|
@@ -53390,7 +53807,7 @@ function wrapWithAstGate(original, opts) {
|
|
|
53390
53807
|
return result;
|
|
53391
53808
|
}
|
|
53392
53809
|
const post = await fs23.readFile(absPath, "utf8");
|
|
53393
|
-
const syntaxError = firstSyntaxError(ts,
|
|
53810
|
+
const syntaxError = firstSyntaxError(ts, path59.basename(absPath), post);
|
|
53394
53811
|
if (!syntaxError) return result;
|
|
53395
53812
|
const parseError = `${syntaxError.message} (line ${syntaxError.line}, col ${syntaxError.character})`;
|
|
53396
53813
|
let revertedTo;
|
|
@@ -53401,7 +53818,7 @@ function wrapWithAstGate(original, opts) {
|
|
|
53401
53818
|
await fs23.writeFile(absPath, preContent, "utf8");
|
|
53402
53819
|
revertedTo = snapshotIdOf(preContent);
|
|
53403
53820
|
}
|
|
53404
|
-
const relLabel =
|
|
53821
|
+
const relLabel = path59.relative(opts.root, absPath) || path59.basename(absPath);
|
|
53405
53822
|
return typedErr(
|
|
53406
53823
|
`[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
53824
|
{
|
|
@@ -53826,7 +54243,7 @@ var init_resourceClaims = __esm({
|
|
|
53826
54243
|
// src/cli/toolResultCache.ts
|
|
53827
54244
|
import { createHash as createHash15 } from "node:crypto";
|
|
53828
54245
|
import { promises as fs24 } from "node:fs";
|
|
53829
|
-
import
|
|
54246
|
+
import path60 from "node:path";
|
|
53830
54247
|
function isToolCacheEnabled() {
|
|
53831
54248
|
const raw = process.env.ZELARI_TOOL_CACHE;
|
|
53832
54249
|
return raw !== "0" && raw !== "false" && raw !== "off";
|
|
@@ -53911,7 +54328,7 @@ async function statKey(toolName, input, ctx) {
|
|
|
53911
54328
|
if (!input || typeof input !== "object") return null;
|
|
53912
54329
|
const rawPath = input.path;
|
|
53913
54330
|
if (typeof rawPath !== "string" || rawPath.length === 0) return null;
|
|
53914
|
-
const abs =
|
|
54331
|
+
const abs = path60.isAbsolute(rawPath) ? rawPath : path60.join(ctx.cwd, rawPath);
|
|
53915
54332
|
try {
|
|
53916
54333
|
const st = await fs24.stat(abs);
|
|
53917
54334
|
return hashKey({
|
|
@@ -53967,7 +54384,7 @@ __export(toolRegistry_exports, {
|
|
|
53967
54384
|
wrapWithSandbox: () => wrapWithSandbox
|
|
53968
54385
|
});
|
|
53969
54386
|
import { existsSync as existsSync32 } from "node:fs";
|
|
53970
|
-
import
|
|
54387
|
+
import path61 from "node:path";
|
|
53971
54388
|
function createBuiltinToolRegistry(options = {}) {
|
|
53972
54389
|
const root = options.root ?? process.cwd();
|
|
53973
54390
|
const audit = options.audit ?? new AuditLogger();
|
|
@@ -54192,6 +54609,15 @@ function createBuiltinToolRegistry(options = {}) {
|
|
|
54192
54609
|
permissions: browserTool.permissions ?? []
|
|
54193
54610
|
});
|
|
54194
54611
|
}
|
|
54612
|
+
if (!readOnly && !gauntletParent && process.env.ZELARI_SCREENSHOT !== "0") {
|
|
54613
|
+
const screenshotTool = createScreenshotTool();
|
|
54614
|
+
registry4.register(screenshotTool);
|
|
54615
|
+
tools.push({
|
|
54616
|
+
name: screenshotTool.name,
|
|
54617
|
+
description: screenshotTool.description,
|
|
54618
|
+
permissions: screenshotTool.permissions ?? []
|
|
54619
|
+
});
|
|
54620
|
+
}
|
|
54195
54621
|
if (!readOnly && !gauntletParent && process.env.ZELARI_SSH !== "0") {
|
|
54196
54622
|
for (const t of createSshTools()) {
|
|
54197
54623
|
registry4.register(t);
|
|
@@ -54576,14 +55002,14 @@ function wrapWithDiagnostics(original, root, runner) {
|
|
|
54576
55002
|
function claimedSourcePath(token, args, root) {
|
|
54577
55003
|
const cleaned = token.replace(/^["']|["']$/g, "");
|
|
54578
55004
|
if (!cleaned || cleaned.startsWith("-")) return null;
|
|
54579
|
-
if (!DIAG_SOURCE_EXTENSIONS.has(
|
|
55005
|
+
if (!DIAG_SOURCE_EXTENSIONS.has(path61.extname(cleaned).toLowerCase())) return null;
|
|
54580
55006
|
const bases = [root];
|
|
54581
55007
|
const cwd = args["cwd"];
|
|
54582
55008
|
if (typeof cwd === "string" && cwd.length > 0) {
|
|
54583
|
-
bases.unshift(
|
|
55009
|
+
bases.unshift(path61.isAbsolute(cwd) ? cwd : path61.resolve(root, cwd));
|
|
54584
55010
|
}
|
|
54585
55011
|
for (const base2 of bases) {
|
|
54586
|
-
const candidate =
|
|
55012
|
+
const candidate = path61.isAbsolute(cleaned) ? path61.normalize(cleaned) : path61.resolve(base2, cleaned);
|
|
54587
55013
|
try {
|
|
54588
55014
|
const contained = resolveSandboxedPath(candidate, { root });
|
|
54589
55015
|
if (existsSync32(contained)) return contained;
|
|
@@ -54853,6 +55279,7 @@ var init_toolRegistry = __esm({
|
|
|
54853
55279
|
init_tools3();
|
|
54854
55280
|
init_tools4();
|
|
54855
55281
|
init_tools5();
|
|
55282
|
+
init_screenshotTool();
|
|
54856
55283
|
init_tools6();
|
|
54857
55284
|
init_worldModel();
|
|
54858
55285
|
init_openai_compatible();
|
|
@@ -54899,7 +55326,7 @@ var init_toolRegistry = __esm({
|
|
|
54899
55326
|
|
|
54900
55327
|
// src/cli/metrics.ts
|
|
54901
55328
|
import { promises as fs25, existsSync as existsSync33, statSync as statSync4, renameSync as renameSync4, appendFileSync as appendFileSync3, mkdirSync as mkdirSync15 } from "node:fs";
|
|
54902
|
-
import
|
|
55329
|
+
import path62 from "node:path";
|
|
54903
55330
|
async function readMetrics(file2) {
|
|
54904
55331
|
let raw = "";
|
|
54905
55332
|
try {
|
|
@@ -54949,7 +55376,7 @@ var init_metrics3 = __esm({
|
|
|
54949
55376
|
writeQueue = Promise.resolve();
|
|
54950
55377
|
constructor(file2) {
|
|
54951
55378
|
this.file = file2 ?? metricsPath();
|
|
54952
|
-
mkdirSync15(
|
|
55379
|
+
mkdirSync15(path62.dirname(this.file), { recursive: true });
|
|
54953
55380
|
}
|
|
54954
55381
|
/** Metrics file path — doctor/summary readers use this. */
|
|
54955
55382
|
get filePath() {
|
|
@@ -54986,8 +55413,8 @@ var init_metrics3 = __esm({
|
|
|
54986
55413
|
maybeRotate() {
|
|
54987
55414
|
if (!existsSync33(this.file)) return;
|
|
54988
55415
|
try {
|
|
54989
|
-
const
|
|
54990
|
-
if (
|
|
55416
|
+
const stat8 = statSync4(this.file);
|
|
55417
|
+
if (stat8.size >= METRICS_ROTATE_BYTES) {
|
|
54991
55418
|
const rotated = this.file.replace(/\.jsonl$/, ".1.jsonl");
|
|
54992
55419
|
renameSync4(this.file, rotated);
|
|
54993
55420
|
}
|
|
@@ -55281,15 +55708,15 @@ __export(completionProofProbe_exports, {
|
|
|
55281
55708
|
gatherGitAttestation: () => gatherGitAttestation,
|
|
55282
55709
|
harnessManifest: () => harnessManifest
|
|
55283
55710
|
});
|
|
55284
|
-
import { execFile as
|
|
55285
|
-
import { promisify as
|
|
55711
|
+
import { execFile as execFile6 } from "node:child_process";
|
|
55712
|
+
import { promisify as promisify5 } from "node:util";
|
|
55286
55713
|
async function readHarnessVersion() {
|
|
55287
55714
|
if (cachedHarnessVersion !== null) return cachedHarnessVersion;
|
|
55288
55715
|
try {
|
|
55289
|
-
const { readFile:
|
|
55716
|
+
const { readFile: readFile11 } = await import("node:fs/promises");
|
|
55290
55717
|
const { fileURLToPath: fileURLToPath4 } = await import("node:url");
|
|
55291
55718
|
const pkgPath = fileURLToPath4(new URL("../../../package.json", import.meta.url));
|
|
55292
|
-
const parsed = JSON.parse(await
|
|
55719
|
+
const parsed = JSON.parse(await readFile11(pkgPath, "utf8"));
|
|
55293
55720
|
if (typeof parsed.version === "string" && parsed.version.length > 0) {
|
|
55294
55721
|
return cachedHarnessVersion = parsed.version;
|
|
55295
55722
|
}
|
|
@@ -55313,7 +55740,7 @@ async function harnessManifest(env = process.env) {
|
|
|
55313
55740
|
}
|
|
55314
55741
|
async function git5(cwd, args) {
|
|
55315
55742
|
try {
|
|
55316
|
-
const { stdout } = await
|
|
55743
|
+
const { stdout } = await execFileAsync5("git", ["-C", cwd, ...args], {
|
|
55317
55744
|
maxBuffer: 32 * 1024 * 1024,
|
|
55318
55745
|
windowsHide: true
|
|
55319
55746
|
});
|
|
@@ -55355,7 +55782,7 @@ function activeTaskContractSnapshot() {
|
|
|
55355
55782
|
return void 0;
|
|
55356
55783
|
}
|
|
55357
55784
|
}
|
|
55358
|
-
var HARNESS_VERSION_FALLBACK, ADAPTER_IDS, cachedHarnessVersion,
|
|
55785
|
+
var HARNESS_VERSION_FALLBACK, ADAPTER_IDS, cachedHarnessVersion, execFileAsync5;
|
|
55359
55786
|
var init_completionProofProbe = __esm({
|
|
55360
55787
|
"src/cli/kraken/completionProofProbe.ts"() {
|
|
55361
55788
|
"use strict";
|
|
@@ -55363,7 +55790,7 @@ var init_completionProofProbe = __esm({
|
|
|
55363
55790
|
HARNESS_VERSION_FALLBACK = "2.13.0";
|
|
55364
55791
|
ADAPTER_IDS = ["node", "python", "rust", "go", "java", "dotnet"];
|
|
55365
55792
|
cachedHarnessVersion = null;
|
|
55366
|
-
|
|
55793
|
+
execFileAsync5 = promisify5(execFile6);
|
|
55367
55794
|
}
|
|
55368
55795
|
});
|
|
55369
55796
|
|
|
@@ -55467,7 +55894,7 @@ var init_completionProofAttestation = __esm({
|
|
|
55467
55894
|
// src/cli/kraken/completionProofPersist.ts
|
|
55468
55895
|
import { open, rename as rename2, rm as rm2 } from "node:fs/promises";
|
|
55469
55896
|
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
55470
|
-
import
|
|
55897
|
+
import path63 from "node:path";
|
|
55471
55898
|
function isTruthyFlag2(v) {
|
|
55472
55899
|
const n = v?.trim().toLowerCase();
|
|
55473
55900
|
return n === "1" || n === "true" || n === "yes" || n === "on";
|
|
@@ -55509,8 +55936,8 @@ function isWindowsRenameBlock(err) {
|
|
|
55509
55936
|
return code === "EPERM" || code === "ENOTEMPTY" || code === "EEXIST";
|
|
55510
55937
|
}
|
|
55511
55938
|
async function writeFileAtomic(target, data) {
|
|
55512
|
-
const dir =
|
|
55513
|
-
const tmp =
|
|
55939
|
+
const dir = path63.dirname(target);
|
|
55940
|
+
const tmp = path63.join(dir, `.${path63.basename(target)}.${randomBytes5(6).toString("hex")}.tmp`);
|
|
55514
55941
|
let fh = null;
|
|
55515
55942
|
try {
|
|
55516
55943
|
fh = await open(tmp, "w");
|
|
@@ -55555,8 +55982,8 @@ var init_completionProofPersist = __esm({
|
|
|
55555
55982
|
});
|
|
55556
55983
|
|
|
55557
55984
|
// src/cli/kraken/completionProof.ts
|
|
55558
|
-
import { mkdir as
|
|
55559
|
-
import
|
|
55985
|
+
import { mkdir as mkdir4 } from "node:fs/promises";
|
|
55986
|
+
import path64 from "node:path";
|
|
55560
55987
|
function verdictOf(evaluation) {
|
|
55561
55988
|
return evaluation.evaluation?.verdict ?? (evaluation.blocked ? "BLOCKED" : "PASS");
|
|
55562
55989
|
}
|
|
@@ -55701,8 +56128,8 @@ async function writeCompletionProofDetailed(evaluation, options = {}) {
|
|
|
55701
56128
|
const mode = options.persistenceMode ?? activeProofPersistenceMode();
|
|
55702
56129
|
try {
|
|
55703
56130
|
const baseDir = options.baseDir ?? process.cwd();
|
|
55704
|
-
const dir =
|
|
55705
|
-
await
|
|
56131
|
+
const dir = path64.join(baseDir, ".zelari");
|
|
56132
|
+
await mkdir4(dir, { recursive: true });
|
|
55706
56133
|
const requested = options.attestation ?? {};
|
|
55707
56134
|
const plan = requested.skipProbes || requested.verificationPlan !== void 0 ? void 0 : await defaultVerificationPlanSnapshot(baseDir);
|
|
55708
56135
|
const wrapper = await buildAttestedWrapper(
|
|
@@ -55721,8 +56148,8 @@ async function writeCompletionProofDetailed(evaluation, options = {}) {
|
|
|
55721
56148
|
baseDir
|
|
55722
56149
|
);
|
|
55723
56150
|
const rendered = renderCompletionProof(evaluation, options.meta ?? {}, wrapper.attestation);
|
|
55724
|
-
const markdownPath =
|
|
55725
|
-
const jsonPath =
|
|
56151
|
+
const markdownPath = path64.join(dir, "completion-proof.md");
|
|
56152
|
+
const jsonPath = path64.join(dir, "completion-proof.json");
|
|
55726
56153
|
await writeFileAtomic(markdownPath, rendered.markdown);
|
|
55727
56154
|
await writeFileAtomic(jsonPath, rendered.json);
|
|
55728
56155
|
return { paths: { markdownPath, jsonPath }, mode, requiredBlockReason: null };
|
|
@@ -55832,12 +56259,12 @@ var init_askUserTimeout = __esm({
|
|
|
55832
56259
|
// src/cli/state/fileStateStore.ts
|
|
55833
56260
|
import { createHash as createHash17, randomUUID as randomUUID5 } from "node:crypto";
|
|
55834
56261
|
import { promises as fs26 } from "node:fs";
|
|
55835
|
-
import * as
|
|
56262
|
+
import * as path65 from "node:path";
|
|
55836
56263
|
function shortId() {
|
|
55837
56264
|
return randomUUID5().replace(/-/g, "").slice(0, 12);
|
|
55838
56265
|
}
|
|
55839
56266
|
async function writeJsonAtomic(filePath, data) {
|
|
55840
|
-
await fs26.mkdir(
|
|
56267
|
+
await fs26.mkdir(path65.dirname(filePath), { recursive: true });
|
|
55841
56268
|
const tmp = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
55842
56269
|
await fs26.writeFile(tmp, JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
55843
56270
|
await fs26.rename(tmp, filePath);
|
|
@@ -55898,11 +56325,11 @@ var init_fileStateStore = __esm({
|
|
|
55898
56325
|
indexPath = "";
|
|
55899
56326
|
async init(projectRoot) {
|
|
55900
56327
|
this.root = projectRoot;
|
|
55901
|
-
this.stateDir =
|
|
55902
|
-
this.commitsDir =
|
|
55903
|
-
this.artifactsDir =
|
|
55904
|
-
this.headPath =
|
|
55905
|
-
this.indexPath =
|
|
56328
|
+
this.stateDir = path65.join(projectRoot, ".zelari", "state");
|
|
56329
|
+
this.commitsDir = path65.join(this.stateDir, "commits");
|
|
56330
|
+
this.artifactsDir = path65.join(this.stateDir, "artifacts");
|
|
56331
|
+
this.headPath = path65.join(this.stateDir, "HEAD.json");
|
|
56332
|
+
this.indexPath = path65.join(this.stateDir, "index.jsonl");
|
|
55906
56333
|
await fs26.mkdir(this.commitsDir, { recursive: true });
|
|
55907
56334
|
await fs26.mkdir(this.artifactsDir, { recursive: true });
|
|
55908
56335
|
}
|
|
@@ -55915,13 +56342,13 @@ var init_fileStateStore = __esm({
|
|
|
55915
56342
|
const discoveries = input.discoveries ?? [];
|
|
55916
56343
|
const parent = await this.head();
|
|
55917
56344
|
const id3 = shortId();
|
|
55918
|
-
const artifactRel =
|
|
55919
|
-
const artifactAbs =
|
|
56345
|
+
const artifactRel = path65.join("artifacts", id3);
|
|
56346
|
+
const artifactAbs = path65.join(this.artifactsDir, id3);
|
|
55920
56347
|
await fs26.mkdir(artifactAbs, { recursive: true });
|
|
55921
56348
|
const summary = defaultSummary(input, discoveries);
|
|
55922
|
-
await fs26.writeFile(
|
|
55923
|
-
await writeJsonAtomic(
|
|
55924
|
-
await writeJsonAtomic(
|
|
56349
|
+
await fs26.writeFile(path65.join(artifactAbs, "summary.md"), summary + "\n", "utf8");
|
|
56350
|
+
await writeJsonAtomic(path65.join(artifactAbs, "discoveries.json"), discoveries);
|
|
56351
|
+
await writeJsonAtomic(path65.join(artifactAbs, "verification.json"), input.verification);
|
|
55925
56352
|
const meta3 = {
|
|
55926
56353
|
id: id3,
|
|
55927
56354
|
parentId: parent?.id ?? null,
|
|
@@ -55933,14 +56360,14 @@ var init_fileStateStore = __esm({
|
|
|
55933
56360
|
workspaceCheckpointId: input.workspaceCheckpointId,
|
|
55934
56361
|
verification: {
|
|
55935
56362
|
...input.verification,
|
|
55936
|
-
reportPath: input.verification.reportPath ??
|
|
56363
|
+
reportPath: input.verification.reportPath ?? path65.join(".zelari", "state", artifactRel, "verification.json").replace(/\\/g, "/")
|
|
55937
56364
|
},
|
|
55938
56365
|
changedPaths: input.changedPaths ?? [],
|
|
55939
56366
|
stablePromptHash: input.stablePromptHash,
|
|
55940
56367
|
discoveryCount: discoveries.length,
|
|
55941
56368
|
artifactDir: artifactRel.replace(/\\/g, "/")
|
|
55942
56369
|
};
|
|
55943
|
-
await writeJsonAtomic(
|
|
56370
|
+
await writeJsonAtomic(path65.join(this.commitsDir, `${id3}.json`), meta3);
|
|
55944
56371
|
await writeJsonAtomic(this.headPath, { id: id3, updatedAt: meta3.createdAt });
|
|
55945
56372
|
await fs26.appendFile(this.indexPath, JSON.stringify({ id: id3, createdAt: meta3.createdAt, label: meta3.label }) + "\n", "utf8");
|
|
55946
56373
|
return stripStored(meta3);
|
|
@@ -55951,7 +56378,7 @@ var init_fileStateStore = __esm({
|
|
|
55951
56378
|
return this.get(head.id);
|
|
55952
56379
|
}
|
|
55953
56380
|
async get(id3) {
|
|
55954
|
-
const stored = await readJsonFile(
|
|
56381
|
+
const stored = await readJsonFile(path65.join(this.commitsDir, `${id3}.json`));
|
|
55955
56382
|
return stored ? stripStored(stored) : null;
|
|
55956
56383
|
}
|
|
55957
56384
|
async list(limit = 20) {
|
|
@@ -55990,9 +56417,9 @@ var init_fileStateStore = __esm({
|
|
|
55990
56417
|
async loadDiscoveries(id3) {
|
|
55991
56418
|
const meta3 = id3 ? await this.get(id3) : await this.head();
|
|
55992
56419
|
if (!meta3) return [];
|
|
55993
|
-
const stored = await readJsonFile(
|
|
56420
|
+
const stored = await readJsonFile(path65.join(this.commitsDir, `${meta3.id}.json`));
|
|
55994
56421
|
if (!stored?.artifactDir) return [];
|
|
55995
|
-
const discPath =
|
|
56422
|
+
const discPath = path65.join(this.stateDir, stored.artifactDir, "discoveries.json");
|
|
55996
56423
|
return await readJsonFile(discPath) ?? [];
|
|
55997
56424
|
}
|
|
55998
56425
|
async materializeContext(id3, maxChars = DEFAULT_MATERIALIZE_CHARS) {
|
|
@@ -56595,10 +57022,10 @@ var init_mode = __esm({
|
|
|
56595
57022
|
|
|
56596
57023
|
// src/cli/headless.ts
|
|
56597
57024
|
import { readFileSync as readFileSync24 } from "node:fs";
|
|
56598
|
-
import
|
|
57025
|
+
import path66 from "node:path";
|
|
56599
57026
|
function resolveHeadlessCwd(opts) {
|
|
56600
57027
|
const raw = typeof opts.cwd === "string" ? opts.cwd.trim() : "";
|
|
56601
|
-
return
|
|
57028
|
+
return path66.resolve(raw.length > 0 ? raw : process.cwd());
|
|
56602
57029
|
}
|
|
56603
57030
|
function defaultProfileForMode(mode) {
|
|
56604
57031
|
switch (mode) {
|
|
@@ -57700,7 +58127,7 @@ var init_planDetect = __esm({
|
|
|
57700
58127
|
// src/cli/memory/legacyImport.ts
|
|
57701
58128
|
import { createHash as createHash18 } from "node:crypto";
|
|
57702
58129
|
import { promises as fs27 } from "node:fs";
|
|
57703
|
-
import * as
|
|
58130
|
+
import * as path67 from "node:path";
|
|
57704
58131
|
function sourceId(fact, line) {
|
|
57705
58132
|
return `jsonl:${fact.id ?? createHash18("sha256").update(line).digest("hex")}`;
|
|
57706
58133
|
}
|
|
@@ -57718,7 +58145,7 @@ function timestamp(value) {
|
|
|
57718
58145
|
}
|
|
57719
58146
|
async function importLegacyMemoryLog(backend, service) {
|
|
57720
58147
|
const result = { found: 0, imported: 0, skipped: 0, corrupt: 0 };
|
|
57721
|
-
const logPath =
|
|
58148
|
+
const logPath = path67.join(path67.dirname(backend.databasePath), "log.jsonl");
|
|
57722
58149
|
let raw;
|
|
57723
58150
|
try {
|
|
57724
58151
|
raw = await fs27.readFile(logPath, "utf8");
|
|
@@ -57901,7 +58328,7 @@ var init_sqliteCodec = __esm({
|
|
|
57901
58328
|
// src/cli/memory/sqliteRpc.ts
|
|
57902
58329
|
import { existsSync as existsSync36 } from "node:fs";
|
|
57903
58330
|
import { fileURLToPath as fileURLToPath2, pathToFileURL as pathToFileURL2 } from "node:url";
|
|
57904
|
-
import * as
|
|
58331
|
+
import * as path68 from "node:path";
|
|
57905
58332
|
import { Worker } from "node:worker_threads";
|
|
57906
58333
|
function isBusy(error51) {
|
|
57907
58334
|
const candidate = error51;
|
|
@@ -57910,10 +58337,10 @@ function isBusy(error51) {
|
|
|
57910
58337
|
);
|
|
57911
58338
|
}
|
|
57912
58339
|
function resolveWorkerUrl() {
|
|
57913
|
-
const here =
|
|
57914
|
-
const direct =
|
|
58340
|
+
const here = path68.dirname(fileURLToPath2(import.meta.url));
|
|
58341
|
+
const direct = path68.join(here, "sqliteWorker.mjs");
|
|
57915
58342
|
if (existsSync36(direct)) return pathToFileURL2(direct);
|
|
57916
|
-
return pathToFileURL2(
|
|
58343
|
+
return pathToFileURL2(path68.join(here, "memory", "sqliteWorker.mjs"));
|
|
57917
58344
|
}
|
|
57918
58345
|
var SqliteWorkerRpc;
|
|
57919
58346
|
var init_sqliteRpc = __esm({
|
|
@@ -58202,7 +58629,7 @@ WHERE NOT EXISTS (SELECT 1 FROM memory_fts f WHERE f.node_id = n.id);
|
|
|
58202
58629
|
// src/cli/memory/sqliteBackend.ts
|
|
58203
58630
|
import { createHash as createHash19, randomUUID as randomUUID6 } from "node:crypto";
|
|
58204
58631
|
import { promises as fs28 } from "node:fs";
|
|
58205
|
-
import * as
|
|
58632
|
+
import * as path69 from "node:path";
|
|
58206
58633
|
function boundedLimit(value, fallback = 50) {
|
|
58207
58634
|
return Math.max(1, Math.min(Math.floor(value ?? fallback), 1e5));
|
|
58208
58635
|
}
|
|
@@ -58264,20 +58691,20 @@ VALUES (${Array.from({ length: 19 }, () => "?").join(",")})`;
|
|
|
58264
58691
|
try {
|
|
58265
58692
|
resolved = await fs28.realpath(projectRoot);
|
|
58266
58693
|
} catch {
|
|
58267
|
-
resolved =
|
|
58694
|
+
resolved = path69.resolve(projectRoot);
|
|
58268
58695
|
}
|
|
58269
58696
|
if (this.initialized && resolved === this.projectRoot) return;
|
|
58270
58697
|
if (this.initialized) await this.close();
|
|
58271
58698
|
const filename = this.options.filename ?? "memory.db";
|
|
58272
|
-
if (
|
|
58699
|
+
if (path69.basename(filename) !== filename || filename === "." || filename === "..") {
|
|
58273
58700
|
throw new Error("SQLite memory filename must not contain a path.");
|
|
58274
58701
|
}
|
|
58275
|
-
const zelariDirectory =
|
|
58276
|
-
const directory =
|
|
58702
|
+
const zelariDirectory = path69.join(resolved, ".zelari");
|
|
58703
|
+
const directory = path69.join(zelariDirectory, "memory");
|
|
58277
58704
|
for (const candidate of [zelariDirectory, directory]) {
|
|
58278
|
-
let
|
|
58705
|
+
let stat8;
|
|
58279
58706
|
try {
|
|
58280
|
-
|
|
58707
|
+
stat8 = await fs28.lstat(candidate);
|
|
58281
58708
|
} catch (error51) {
|
|
58282
58709
|
if (error51.code !== "ENOENT") throw error51;
|
|
58283
58710
|
try {
|
|
@@ -58285,19 +58712,19 @@ VALUES (${Array.from({ length: 19 }, () => "?").join(",")})`;
|
|
|
58285
58712
|
} catch (mkdirError) {
|
|
58286
58713
|
if (mkdirError.code !== "EEXIST") throw mkdirError;
|
|
58287
58714
|
}
|
|
58288
|
-
|
|
58715
|
+
stat8 = await fs28.lstat(candidate);
|
|
58289
58716
|
}
|
|
58290
|
-
if (
|
|
58717
|
+
if (stat8.isSymbolicLink() || !stat8.isDirectory()) {
|
|
58291
58718
|
throw new Error(`Memory directory is not a real directory: ${candidate}`);
|
|
58292
58719
|
}
|
|
58293
58720
|
}
|
|
58294
58721
|
const canonicalDirectory = await fs28.realpath(directory);
|
|
58295
|
-
const relativeDirectory =
|
|
58296
|
-
if (relativeDirectory.startsWith("..") ||
|
|
58722
|
+
const relativeDirectory = path69.relative(resolved, canonicalDirectory);
|
|
58723
|
+
if (relativeDirectory.startsWith("..") || path69.isAbsolute(relativeDirectory)) {
|
|
58297
58724
|
throw new Error("SQLite memory directory resolves outside the active project.");
|
|
58298
58725
|
}
|
|
58299
58726
|
this.projectRoot = resolved;
|
|
58300
|
-
this.databasePath =
|
|
58727
|
+
this.databasePath = path69.join(canonicalDirectory, filename);
|
|
58301
58728
|
const opened = await this.rpc.open({
|
|
58302
58729
|
dbPath: this.databasePath,
|
|
58303
58730
|
schemaSql: SQLITE_MEMORY_BASE_SCHEMA,
|
|
@@ -58830,7 +59257,7 @@ __export(serviceFactory_exports, {
|
|
|
58830
59257
|
});
|
|
58831
59258
|
import { createHash as createHash20 } from "node:crypto";
|
|
58832
59259
|
import { promises as fs29 } from "node:fs";
|
|
58833
|
-
import * as
|
|
59260
|
+
import * as path70 from "node:path";
|
|
58834
59261
|
function isMemoryV2Enabled(env = process.env) {
|
|
58835
59262
|
if (env.ZELARI_MEMORY === "0") return false;
|
|
58836
59263
|
if (env.ZELARI_MEMORY_BACKEND === "file" || env.ZELARI_MEMORY_BACKEND === "jsonl") return false;
|
|
@@ -58851,7 +59278,7 @@ async function canonicalProjectId(projectRoot) {
|
|
|
58851
59278
|
try {
|
|
58852
59279
|
canonical = await fs29.realpath(projectRoot);
|
|
58853
59280
|
} catch {
|
|
58854
|
-
canonical =
|
|
59281
|
+
canonical = path70.resolve(projectRoot);
|
|
58855
59282
|
}
|
|
58856
59283
|
canonical = canonical.replace(/\\/g, "/").replace(/\/$/, "");
|
|
58857
59284
|
if (process.platform === "win32") canonical = canonical.toLocaleLowerCase("en-US");
|
|
@@ -59553,8 +59980,8 @@ function readPlan(ctx) {
|
|
|
59553
59980
|
} catch {
|
|
59554
59981
|
}
|
|
59555
59982
|
}
|
|
59556
|
-
const
|
|
59557
|
-
const doc = ctx.storage.readIfExists(
|
|
59983
|
+
const path100 = workspaceFile(ctx.rootDir, "plan");
|
|
59984
|
+
const doc = ctx.storage.readIfExists(path100);
|
|
59558
59985
|
if (!doc) return { phases: [], tasks: [], milestones: [] };
|
|
59559
59986
|
const meta3 = doc.meta;
|
|
59560
59987
|
return {
|
|
@@ -59735,7 +60162,7 @@ function addMilestoneRecord(ctx, summary, input) {
|
|
|
59735
60162
|
dueDate: input.dueDate,
|
|
59736
60163
|
targetVersion: version2
|
|
59737
60164
|
});
|
|
59738
|
-
const
|
|
60165
|
+
const path100 = join31(ctx.rootDir, "milestones", `${id3}.md`);
|
|
59739
60166
|
const meta3 = {
|
|
59740
60167
|
kind: "milestone",
|
|
59741
60168
|
id: id3,
|
|
@@ -59752,7 +60179,7 @@ function addMilestoneRecord(ctx, summary, input) {
|
|
|
59752
60179
|
`Target version: ${version2}`,
|
|
59753
60180
|
""
|
|
59754
60181
|
].join("\n");
|
|
59755
|
-
ctx.storage.write(
|
|
60182
|
+
ctx.storage.write(path100, meta3, body);
|
|
59756
60183
|
return { id: id3, created: true };
|
|
59757
60184
|
}
|
|
59758
60185
|
function readPlanSummary(ctx) {
|
|
@@ -59956,7 +60383,7 @@ function addIdeaStub(ctx) {
|
|
|
59956
60383
|
const tags = args["tags"] ?? [];
|
|
59957
60384
|
const category = args["category"] ?? "General";
|
|
59958
60385
|
const id3 = `${nextAdrId(ctx)}-${slugify3(title)}`;
|
|
59959
|
-
const
|
|
60386
|
+
const path100 = workspaceArtifact(ctx.rootDir, "decisions", id3);
|
|
59960
60387
|
const meta3 = {
|
|
59961
60388
|
kind: "adr",
|
|
59962
60389
|
status: "proposed",
|
|
@@ -59982,7 +60409,7 @@ function addIdeaStub(ctx) {
|
|
|
59982
60409
|
...consequences.map((c) => `- ${c}`),
|
|
59983
60410
|
""
|
|
59984
60411
|
].join("\n");
|
|
59985
|
-
ctx.storage.write(
|
|
60412
|
+
ctx.storage.write(path100, meta3, body);
|
|
59986
60413
|
return `ADR ${id3} created: "${title}". Status: proposed. Promote to accepted via /update ADR or manual edit.`;
|
|
59987
60414
|
});
|
|
59988
60415
|
}
|
|
@@ -60064,14 +60491,14 @@ function createDocumentStub(ctx) {
|
|
|
60064
60491
|
ctx.storage.write(risksPath, riskMeta, content);
|
|
60065
60492
|
return `Document "${title}" created at risks.md (workspace root).`;
|
|
60066
60493
|
}
|
|
60067
|
-
const
|
|
60494
|
+
const path100 = workspaceArtifact(ctx.rootDir, "docs", slug);
|
|
60068
60495
|
const meta3 = {
|
|
60069
60496
|
kind: "doc",
|
|
60070
60497
|
id: slug,
|
|
60071
60498
|
date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
|
|
60072
60499
|
tags
|
|
60073
60500
|
};
|
|
60074
|
-
ctx.storage.write(
|
|
60501
|
+
ctx.storage.write(path100, meta3, content);
|
|
60075
60502
|
return `Document "${title}" created at docs/${slug}.md.`;
|
|
60076
60503
|
});
|
|
60077
60504
|
}
|
|
@@ -60324,11 +60751,11 @@ var init_httpTransport = __esm({
|
|
|
60324
60751
|
const sid = this.sessionId;
|
|
60325
60752
|
this.sessionId = null;
|
|
60326
60753
|
if (!sid) return;
|
|
60327
|
-
const
|
|
60754
|
+
const headers3 = {
|
|
60328
60755
|
...this.opts.headers ?? {},
|
|
60329
60756
|
"mcp-session-id": sid
|
|
60330
60757
|
};
|
|
60331
|
-
void fetch(this.opts.url, { method: "DELETE", headers:
|
|
60758
|
+
void fetch(this.opts.url, { method: "DELETE", headers: headers3 }).catch(() => {
|
|
60332
60759
|
});
|
|
60333
60760
|
}
|
|
60334
60761
|
// ── internals ────────────────────────────────────────────────────────
|
|
@@ -60338,15 +60765,15 @@ var init_httpTransport = __esm({
|
|
|
60338
60765
|
const timer = setTimeout(() => ac.abort(), timeoutMs2 + ABORT_GRACE_MS);
|
|
60339
60766
|
const hadSession = this.sessionId !== null;
|
|
60340
60767
|
try {
|
|
60341
|
-
const
|
|
60768
|
+
const headers3 = {
|
|
60342
60769
|
"content-type": "application/json",
|
|
60343
60770
|
accept: "application/json, text/event-stream",
|
|
60344
60771
|
...this.opts.headers ?? {}
|
|
60345
60772
|
};
|
|
60346
|
-
if (this.sessionId)
|
|
60773
|
+
if (this.sessionId) headers3["mcp-session-id"] = this.sessionId;
|
|
60347
60774
|
const res = await fetch(this.opts.url, {
|
|
60348
60775
|
method: "POST",
|
|
60349
|
-
headers:
|
|
60776
|
+
headers: headers3,
|
|
60350
60777
|
signal: ac.signal,
|
|
60351
60778
|
body: JSON.stringify({ jsonrpc: "2.0", ...msg })
|
|
60352
60779
|
});
|
|
@@ -60696,10 +61123,10 @@ function getUserMcpPath() {
|
|
|
60696
61123
|
function getProjectMcpPath(projectRoot) {
|
|
60697
61124
|
return join32(projectRoot, ".zelari", "mcp.json");
|
|
60698
61125
|
}
|
|
60699
|
-
function
|
|
60700
|
-
if (!existsSync42(
|
|
61126
|
+
function readFile9(path100) {
|
|
61127
|
+
if (!existsSync42(path100)) return {};
|
|
60701
61128
|
try {
|
|
60702
|
-
const parsed = JSON.parse(readFileSync30(
|
|
61129
|
+
const parsed = JSON.parse(readFileSync30(path100, "utf8"));
|
|
60703
61130
|
const out = {};
|
|
60704
61131
|
for (const [name, cfg] of Object.entries(parsed.mcpServers ?? {})) {
|
|
60705
61132
|
const hasCommand = !!cfg && typeof cfg.command === "string" && !!cfg.command.trim();
|
|
@@ -60721,17 +61148,17 @@ function readFile7(path99) {
|
|
|
60721
61148
|
return {};
|
|
60722
61149
|
}
|
|
60723
61150
|
}
|
|
60724
|
-
function writeFile3(
|
|
60725
|
-
mkdirSync17(dirname9(
|
|
61151
|
+
function writeFile3(path100, servers) {
|
|
61152
|
+
mkdirSync17(dirname9(path100), { recursive: true });
|
|
60726
61153
|
const body = { mcpServers: servers };
|
|
60727
|
-
writeFileSync19(
|
|
61154
|
+
writeFileSync19(path100, `${JSON.stringify(body, null, 2)}
|
|
60728
61155
|
`, "utf8");
|
|
60729
61156
|
}
|
|
60730
61157
|
function listMcpServers(projectRoot) {
|
|
60731
61158
|
const userPath = getUserMcpPath();
|
|
60732
|
-
const userServers =
|
|
61159
|
+
const userServers = readFile9(userPath);
|
|
60733
61160
|
const projectPath = projectRoot && projectRoot.trim() ? getProjectMcpPath(projectRoot.trim()) : null;
|
|
60734
|
-
const projectServers = projectPath ?
|
|
61161
|
+
const projectServers = projectPath ? readFile9(projectPath) : {};
|
|
60735
61162
|
const servers = [];
|
|
60736
61163
|
for (const [name, cfg] of Object.entries(userServers)) {
|
|
60737
61164
|
servers.push({ name, ...cfg, scope: "user", path: userPath });
|
|
@@ -60762,9 +61189,9 @@ function upsertMcpServer(opts) {
|
|
|
60762
61189
|
error: "either command (stdio) or url (http) is required"
|
|
60763
61190
|
};
|
|
60764
61191
|
}
|
|
60765
|
-
let
|
|
61192
|
+
let path100;
|
|
60766
61193
|
if (opts.scope === "user") {
|
|
60767
|
-
|
|
61194
|
+
path100 = getUserMcpPath();
|
|
60768
61195
|
} else {
|
|
60769
61196
|
const root = opts.projectRoot?.trim();
|
|
60770
61197
|
if (!root) {
|
|
@@ -60773,9 +61200,9 @@ function upsertMcpServer(opts) {
|
|
|
60773
61200
|
error: "projectRoot required for project scope (Open Folder first)"
|
|
60774
61201
|
};
|
|
60775
61202
|
}
|
|
60776
|
-
|
|
61203
|
+
path100 = getProjectMcpPath(root);
|
|
60777
61204
|
}
|
|
60778
|
-
const current =
|
|
61205
|
+
const current = readFile9(path100);
|
|
60779
61206
|
current[name] = {
|
|
60780
61207
|
command: hasCommand ? opts.config.command.trim() : void 0,
|
|
60781
61208
|
args: opts.config.args,
|
|
@@ -60786,21 +61213,21 @@ function upsertMcpServer(opts) {
|
|
|
60786
61213
|
serial: opts.config.serial,
|
|
60787
61214
|
enabled: opts.config.enabled !== false
|
|
60788
61215
|
};
|
|
60789
|
-
writeFile3(
|
|
60790
|
-
return { ok: true, path:
|
|
61216
|
+
writeFile3(path100, current);
|
|
61217
|
+
return { ok: true, path: path100 };
|
|
60791
61218
|
}
|
|
60792
61219
|
function removeMcpServer(opts) {
|
|
60793
|
-
const
|
|
60794
|
-
if (!
|
|
61220
|
+
const path100 = opts.scope === "user" ? getUserMcpPath() : opts.projectRoot ? getProjectMcpPath(opts.projectRoot) : null;
|
|
61221
|
+
if (!path100) {
|
|
60795
61222
|
return { ok: false, error: "projectRoot required for project scope" };
|
|
60796
61223
|
}
|
|
60797
|
-
const current =
|
|
61224
|
+
const current = readFile9(path100);
|
|
60798
61225
|
if (!(opts.name in current)) {
|
|
60799
|
-
return { ok: false, error: `Server "${opts.name}" not found in ${
|
|
61226
|
+
return { ok: false, error: `Server "${opts.name}" not found in ${path100}` };
|
|
60800
61227
|
}
|
|
60801
61228
|
delete current[opts.name];
|
|
60802
|
-
writeFile3(
|
|
60803
|
-
return { ok: true, path:
|
|
61229
|
+
writeFile3(path100, current);
|
|
61230
|
+
return { ok: true, path: path100 };
|
|
60804
61231
|
}
|
|
60805
61232
|
var init_mcpConfigIo = __esm({
|
|
60806
61233
|
"src/cli/mcp/mcpConfigIo.ts"() {
|
|
@@ -61269,12 +61696,12 @@ __export(agentsMd_exports, {
|
|
|
61269
61696
|
import { existsSync as existsSync44, readFileSync as readFileSync32, writeFileSync as writeFileSync20 } from "node:fs";
|
|
61270
61697
|
import { createHash as createHash21 } from "node:crypto";
|
|
61271
61698
|
import { join as join34 } from "node:path";
|
|
61272
|
-
import { readFile as
|
|
61699
|
+
import { readFile as readFile10 } from "node:fs/promises";
|
|
61273
61700
|
async function readPackageJson3(projectRoot) {
|
|
61274
|
-
const
|
|
61275
|
-
if (!existsSync44(
|
|
61701
|
+
const path100 = join34(projectRoot, "package.json");
|
|
61702
|
+
if (!existsSync44(path100)) return null;
|
|
61276
61703
|
try {
|
|
61277
|
-
return JSON.parse(await
|
|
61704
|
+
return JSON.parse(await readFile10(path100, "utf8"));
|
|
61278
61705
|
} catch {
|
|
61279
61706
|
return null;
|
|
61280
61707
|
}
|
|
@@ -61356,9 +61783,9 @@ async function genBuild(ctx) {
|
|
|
61356
61783
|
].join("\n");
|
|
61357
61784
|
}
|
|
61358
61785
|
async function genOpenQuestions(ctx) {
|
|
61359
|
-
const
|
|
61360
|
-
if (!existsSync44(
|
|
61361
|
-
const content = readFileSync32(
|
|
61786
|
+
const path100 = join34(ctx.rootDir, "risks.md");
|
|
61787
|
+
if (!existsSync44(path100)) return "_No open questions._";
|
|
61788
|
+
const content = readFileSync32(path100, "utf8");
|
|
61362
61789
|
const lines = content.split("\n");
|
|
61363
61790
|
const questions = [];
|
|
61364
61791
|
let currentTitle = "";
|
|
@@ -61632,9 +62059,9 @@ function versionKey(value) {
|
|
|
61632
62059
|
function firstString2(v) {
|
|
61633
62060
|
return typeof v === "string" && v.trim().length > 0 ? v : null;
|
|
61634
62061
|
}
|
|
61635
|
-
function readFileSyncSafe(
|
|
62062
|
+
function readFileSyncSafe(path100) {
|
|
61636
62063
|
try {
|
|
61637
|
-
return readFileSync33(
|
|
62064
|
+
return readFileSync33(path100, "utf8");
|
|
61638
62065
|
} catch {
|
|
61639
62066
|
return null;
|
|
61640
62067
|
}
|
|
@@ -61882,7 +62309,7 @@ __export(evidenceFromSpine_exports, {
|
|
|
61882
62309
|
evidenceRefsFromEventLines: () => evidenceRefsFromEventLines
|
|
61883
62310
|
});
|
|
61884
62311
|
import { existsSync as existsSync47, readFileSync as readFileSync35 } from "node:fs";
|
|
61885
|
-
import
|
|
62312
|
+
import path71 from "node:path";
|
|
61886
62313
|
function asRecord2(v) {
|
|
61887
62314
|
return v && typeof v === "object" && !Array.isArray(v) ? v : void 0;
|
|
61888
62315
|
}
|
|
@@ -61920,7 +62347,7 @@ function evidenceRefsFromEventLines(lines) {
|
|
|
61920
62347
|
}
|
|
61921
62348
|
function collectSessionEvidenceRefs(sessionId2) {
|
|
61922
62349
|
try {
|
|
61923
|
-
const file2 =
|
|
62350
|
+
const file2 = path71.join(sessionsDir(), sessionId2, "events.jsonl");
|
|
61924
62351
|
if (!existsSync47(file2)) return [];
|
|
61925
62352
|
return evidenceRefsFromEventLines(readFileSync35(file2, "utf8").split("\n"));
|
|
61926
62353
|
} catch {
|
|
@@ -62170,8 +62597,8 @@ async function runPostCouncilHook(ctx, options) {
|
|
|
62170
62597
|
sources: scope.sources
|
|
62171
62598
|
} : void 0
|
|
62172
62599
|
});
|
|
62173
|
-
const
|
|
62174
|
-
completionHook = { ran: true, path:
|
|
62600
|
+
const path100 = writeCouncilCompletion(ctx.rootDir, completion);
|
|
62601
|
+
completionHook = { ran: true, path: path100, completion };
|
|
62175
62602
|
} catch (err) {
|
|
62176
62603
|
completionHook = {
|
|
62177
62604
|
ran: true,
|
|
@@ -62216,7 +62643,7 @@ import {
|
|
|
62216
62643
|
writeFileSync as writeFileSync22,
|
|
62217
62644
|
mkdirSync as mkdirSync18
|
|
62218
62645
|
} from "node:fs";
|
|
62219
|
-
import
|
|
62646
|
+
import path72 from "node:path";
|
|
62220
62647
|
var FeedbackStore;
|
|
62221
62648
|
var init_councilFeedback = __esm({
|
|
62222
62649
|
"src/cli/councilFeedback.ts"() {
|
|
@@ -62333,7 +62760,7 @@ var init_councilFeedback = __esm({
|
|
|
62333
62760
|
}
|
|
62334
62761
|
}
|
|
62335
62762
|
save() {
|
|
62336
|
-
mkdirSync18(
|
|
62763
|
+
mkdirSync18(path72.dirname(this.file), { recursive: true });
|
|
62337
62764
|
writeFileSync22(
|
|
62338
62765
|
this.file,
|
|
62339
62766
|
JSON.stringify({ entries: this.entries }, null, 2),
|
|
@@ -62408,12 +62835,12 @@ __export(ledger_exports, {
|
|
|
62408
62835
|
readLedger: () => readLedger
|
|
62409
62836
|
});
|
|
62410
62837
|
import { appendFileSync as appendFileSync4, existsSync as existsSync50, mkdirSync as mkdirSync19, readFileSync as readFileSync38 } from "node:fs";
|
|
62411
|
-
import
|
|
62838
|
+
import path73 from "node:path";
|
|
62412
62839
|
function evolutionMode(env = process.env) {
|
|
62413
62840
|
return env[EVOLUTION_ENV] === "shadow" ? "shadow" : "0";
|
|
62414
62841
|
}
|
|
62415
62842
|
function ledgerPath(cwd) {
|
|
62416
|
-
return
|
|
62843
|
+
return path73.join(cwd, LEDGER_REL);
|
|
62417
62844
|
}
|
|
62418
62845
|
function appendLedgerEntry(cwd, entry) {
|
|
62419
62846
|
if (evolutionMode() === "0") {
|
|
@@ -62421,7 +62848,7 @@ function appendLedgerEntry(cwd, entry) {
|
|
|
62421
62848
|
}
|
|
62422
62849
|
try {
|
|
62423
62850
|
const file2 = ledgerPath(cwd);
|
|
62424
|
-
mkdirSync19(
|
|
62851
|
+
mkdirSync19(path73.dirname(file2), { recursive: true });
|
|
62425
62852
|
appendFileSync4(file2, `${JSON.stringify(entry)}
|
|
62426
62853
|
`, "utf8");
|
|
62427
62854
|
return { written: true, path: file2 };
|
|
@@ -62522,7 +62949,7 @@ var init_ledger = __esm({
|
|
|
62522
62949
|
"src/cli/evolution/ledger.ts"() {
|
|
62523
62950
|
"use strict";
|
|
62524
62951
|
EVOLUTION_ENV = "ZELARI_EVOLUTION";
|
|
62525
|
-
LEDGER_REL =
|
|
62952
|
+
LEDGER_REL = path73.join(".zelari", "evolution", "ledger.jsonl");
|
|
62526
62953
|
TIER_WEIGHTS = {
|
|
62527
62954
|
build: 1,
|
|
62528
62955
|
"tool-output": 1,
|
|
@@ -62664,7 +63091,7 @@ __export(fileBackend_exports, {
|
|
|
62664
63091
|
});
|
|
62665
63092
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
62666
63093
|
import { promises as fs31 } from "node:fs";
|
|
62667
|
-
import * as
|
|
63094
|
+
import * as path74 from "node:path";
|
|
62668
63095
|
function tokenize2(text) {
|
|
62669
63096
|
return text.toLowerCase().split(/[^\p{L}\p{N}]+/u).filter((t) => t.length >= 3);
|
|
62670
63097
|
}
|
|
@@ -62717,8 +63144,8 @@ var init_fileBackend = __esm({
|
|
|
62717
63144
|
logPath = "";
|
|
62718
63145
|
memoryDir = "";
|
|
62719
63146
|
async init(projectRoot) {
|
|
62720
|
-
this.memoryDir =
|
|
62721
|
-
this.logPath =
|
|
63147
|
+
this.memoryDir = path74.join(projectRoot, ".zelari", "memory");
|
|
63148
|
+
this.logPath = path74.join(this.memoryDir, "log.jsonl");
|
|
62722
63149
|
await fs31.mkdir(this.memoryDir, { recursive: true });
|
|
62723
63150
|
}
|
|
62724
63151
|
async add(content, metadata2 = {}, graph) {
|
|
@@ -62791,12 +63218,12 @@ var init_fileBackend = __esm({
|
|
|
62791
63218
|
|
|
62792
63219
|
// src/cli/traceStore.ts
|
|
62793
63220
|
import { promises as fs32 } from "node:fs";
|
|
62794
|
-
import * as
|
|
63221
|
+
import * as path75 from "node:path";
|
|
62795
63222
|
function traceDir(projectRoot) {
|
|
62796
|
-
return
|
|
63223
|
+
return path75.join(projectRoot, ".zelari", "trace");
|
|
62797
63224
|
}
|
|
62798
63225
|
function tracePath(projectRoot, missionId) {
|
|
62799
|
-
return
|
|
63226
|
+
return path75.join(traceDir(projectRoot), `${missionId}.json`);
|
|
62800
63227
|
}
|
|
62801
63228
|
async function saveTrace(projectRoot, missionId, entries) {
|
|
62802
63229
|
const dir = traceDir(projectRoot);
|
|
@@ -62833,7 +63260,7 @@ __export(zelariMission_exports, {
|
|
|
62833
63260
|
});
|
|
62834
63261
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
62835
63262
|
import { promises as fs33 } from "node:fs";
|
|
62836
|
-
import * as
|
|
63263
|
+
import * as path76 from "node:path";
|
|
62837
63264
|
function resolveMaxIterations(env = process.env) {
|
|
62838
63265
|
const raw = env.ZELARI_MISSION_MAX_ITER;
|
|
62839
63266
|
const n = raw ? Number.parseInt(raw, 10) : DEFAULT_MAX_ITER;
|
|
@@ -62876,10 +63303,10 @@ function isMissionAutoStart(env = process.env) {
|
|
|
62876
63303
|
return env.ZELARI_MISSION_AUTO === "1";
|
|
62877
63304
|
}
|
|
62878
63305
|
async function writeMissionState(projectRoot, state3) {
|
|
62879
|
-
const dir =
|
|
63306
|
+
const dir = path76.join(projectRoot, ".zelari");
|
|
62880
63307
|
await fs33.mkdir(dir, { recursive: true });
|
|
62881
63308
|
await fs33.writeFile(
|
|
62882
|
-
|
|
63309
|
+
path76.join(dir, "mission-state.json"),
|
|
62883
63310
|
JSON.stringify(state3, null, 2) + "\n",
|
|
62884
63311
|
"utf8"
|
|
62885
63312
|
);
|
|
@@ -63568,7 +63995,7 @@ function safeSocketPath(socketPath) {
|
|
|
63568
63995
|
return socketPath.trim();
|
|
63569
63996
|
}
|
|
63570
63997
|
function startPermissionBroker(socketPath, handlers, opts) {
|
|
63571
|
-
const
|
|
63998
|
+
const path100 = safeSocketPath(socketPath);
|
|
63572
63999
|
const requestTimeoutMs = opts?.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
|
|
63573
64000
|
const sockets = /* @__PURE__ */ new Set();
|
|
63574
64001
|
const server = createServer2((socket) => {
|
|
@@ -63668,10 +64095,10 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
63668
64095
|
return new Promise((resolve9, reject) => {
|
|
63669
64096
|
const onError = (err) => reject(err);
|
|
63670
64097
|
server.once("error", onError);
|
|
63671
|
-
server.listen(
|
|
64098
|
+
server.listen(path100, () => {
|
|
63672
64099
|
server.removeListener("error", onError);
|
|
63673
64100
|
resolve9({
|
|
63674
|
-
socketPath:
|
|
64101
|
+
socketPath: path100,
|
|
63675
64102
|
stop: () => new Promise((res) => {
|
|
63676
64103
|
for (const s of sockets) s.destroy();
|
|
63677
64104
|
sockets.clear();
|
|
@@ -63682,7 +64109,7 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
63682
64109
|
if (done) return;
|
|
63683
64110
|
done = true;
|
|
63684
64111
|
if (process.platform !== "win32") {
|
|
63685
|
-
unlink(
|
|
64112
|
+
unlink(path100, () => res());
|
|
63686
64113
|
} else {
|
|
63687
64114
|
res();
|
|
63688
64115
|
}
|
|
@@ -63695,11 +64122,11 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
63695
64122
|
});
|
|
63696
64123
|
}
|
|
63697
64124
|
function requestBrokerAsk(socketPath, ask, opts) {
|
|
63698
|
-
const
|
|
64125
|
+
const path100 = safeSocketPath(socketPath);
|
|
63699
64126
|
const requestTimeoutMs = opts?.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
|
|
63700
64127
|
const connectTimeoutMs = opts?.connectTimeoutMs ?? PERMISSION_BROKER_DEFAULT_CONNECT_TIMEOUT_MS;
|
|
63701
64128
|
return new Promise((resolve9, reject) => {
|
|
63702
|
-
const socket = connect(
|
|
64129
|
+
const socket = connect(path100);
|
|
63703
64130
|
let buffer = "";
|
|
63704
64131
|
let settled = false;
|
|
63705
64132
|
const settle = (fn) => {
|
|
@@ -63714,7 +64141,7 @@ function requestBrokerAsk(socketPath, ask, opts) {
|
|
|
63714
64141
|
settle(
|
|
63715
64142
|
() => reject(
|
|
63716
64143
|
new Error(
|
|
63717
|
-
`permission broker unavailable at "${
|
|
64144
|
+
`permission broker unavailable at "${path100}" (connect timed out after ${connectTimeoutMs}ms)`
|
|
63718
64145
|
)
|
|
63719
64146
|
)
|
|
63720
64147
|
);
|
|
@@ -64903,7 +65330,7 @@ var init_prereqChecks = __esm({
|
|
|
64903
65330
|
|
|
64904
65331
|
// src/cli/plugins/prefs.ts
|
|
64905
65332
|
import { existsSync as existsSync53, readFileSync as readFileSync40, writeFileSync as writeFileSync23, mkdirSync as mkdirSync20 } from "node:fs";
|
|
64906
|
-
import
|
|
65333
|
+
import path82 from "node:path";
|
|
64907
65334
|
function getPluginPrefsPath() {
|
|
64908
65335
|
return pluginsPrefsPath();
|
|
64909
65336
|
}
|
|
@@ -64926,7 +65353,7 @@ function getPluginPrefs() {
|
|
|
64926
65353
|
}
|
|
64927
65354
|
function writePluginPrefs(prefs) {
|
|
64928
65355
|
const file2 = getPluginPrefsPath();
|
|
64929
|
-
mkdirSync20(
|
|
65356
|
+
mkdirSync20(path82.dirname(file2), { recursive: true });
|
|
64930
65357
|
writeFileSync23(file2, JSON.stringify(prefs, null, 2), {
|
|
64931
65358
|
encoding: "utf-8",
|
|
64932
65359
|
mode: 384
|
|
@@ -64964,7 +65391,7 @@ __export(registry_exports, {
|
|
|
64964
65391
|
isBinaryOnPath: () => isBinaryOnPath
|
|
64965
65392
|
});
|
|
64966
65393
|
import { existsSync as existsSync54 } from "node:fs";
|
|
64967
|
-
import
|
|
65394
|
+
import path83 from "node:path";
|
|
64968
65395
|
function detectLocalBin(bin) {
|
|
64969
65396
|
return (cwd) => {
|
|
64970
65397
|
try {
|
|
@@ -64982,7 +65409,7 @@ function isBinaryOnPath(bin, opts = {}) {
|
|
|
64982
65409
|
const platform = opts.platform ?? process.platform;
|
|
64983
65410
|
const exists = opts.exists ?? existsSync54;
|
|
64984
65411
|
const pathEnv = opts.pathEnv ?? process.env.PATH ?? "";
|
|
64985
|
-
const pathMod = platform === "win32" ?
|
|
65412
|
+
const pathMod = platform === "win32" ? path83.win32 : path83.posix;
|
|
64986
65413
|
const sep4 = platform === "win32" ? ";" : ":";
|
|
64987
65414
|
const dirs = pathEnv.split(sep4).filter((d) => d.length > 0);
|
|
64988
65415
|
const candidates = [bin];
|
|
@@ -65378,6 +65805,16 @@ function handleProviderPicker(ctx, openPicker) {
|
|
|
65378
65805
|
function handleProviderCustom(ctx, opts) {
|
|
65379
65806
|
const id3 = ctx.activeProviderSpec.id;
|
|
65380
65807
|
try {
|
|
65808
|
+
if (opts.apiStyle) {
|
|
65809
|
+
if (id3 === "chatgpt" || id3 === "anthropic") {
|
|
65810
|
+
appendSystem(ctx.setMessages, `[provider] ${id3} has a fixed transport \u2014 nothing to select.`);
|
|
65811
|
+
return;
|
|
65812
|
+
}
|
|
65813
|
+
setApiStyleFor(id3, opts.apiStyle);
|
|
65814
|
+
const target = opts.apiStyle === "responses" ? "POST /responses" : "POST /chat/completions";
|
|
65815
|
+
appendSystem(ctx.setMessages, `[provider] ${id3} endpoint style set to ${opts.apiStyle} (${target})`);
|
|
65816
|
+
return;
|
|
65817
|
+
}
|
|
65381
65818
|
if (opts.clear) {
|
|
65382
65819
|
clearCustomEndpoint(id3);
|
|
65383
65820
|
appendSystem(ctx.setMessages, `[provider] cleared custom endpoint for ${id3} \u2014 falling back to default`);
|
|
@@ -66077,7 +66514,7 @@ var init_policy = __esm({
|
|
|
66077
66514
|
|
|
66078
66515
|
// src/cli/orchestration/facts.ts
|
|
66079
66516
|
import { promises as fs43 } from "node:fs";
|
|
66080
|
-
import
|
|
66517
|
+
import path87 from "node:path";
|
|
66081
66518
|
async function collectRepoFileCount(root = process.cwd()) {
|
|
66082
66519
|
try {
|
|
66083
66520
|
await fs43.readdir(root);
|
|
@@ -66097,7 +66534,7 @@ async function collectRepoFileCount(root = process.cwd()) {
|
|
|
66097
66534
|
}
|
|
66098
66535
|
for (const e of entries) {
|
|
66099
66536
|
if (e.isDirectory()) {
|
|
66100
|
-
if (!SKIP_DIRS.has(e.name)) queue.push(
|
|
66537
|
+
if (!SKIP_DIRS.has(e.name)) queue.push(path87.join(dir, e.name));
|
|
66101
66538
|
} else if (e.isFile()) {
|
|
66102
66539
|
count++;
|
|
66103
66540
|
if (count > MAX_WALK_FILES) return count;
|
|
@@ -66195,7 +66632,7 @@ var init_streamScrub = __esm({
|
|
|
66195
66632
|
});
|
|
66196
66633
|
|
|
66197
66634
|
// src/cli/harnessState.ts
|
|
66198
|
-
import
|
|
66635
|
+
import path88 from "node:path";
|
|
66199
66636
|
function asString4(v) {
|
|
66200
66637
|
return typeof v === "string" ? v : "";
|
|
66201
66638
|
}
|
|
@@ -66370,7 +66807,7 @@ function contractFor(t) {
|
|
|
66370
66807
|
};
|
|
66371
66808
|
}
|
|
66372
66809
|
async function readHarnessState(sessionDir) {
|
|
66373
|
-
const report = await readSessionLog(
|
|
66810
|
+
const report = await readSessionLog(path88.join(sessionDir, "events.jsonl"));
|
|
66374
66811
|
return deriveHarnessState(report.events);
|
|
66375
66812
|
}
|
|
66376
66813
|
var init_harnessState = __esm({
|
|
@@ -66381,12 +66818,12 @@ var init_harnessState = __esm({
|
|
|
66381
66818
|
});
|
|
66382
66819
|
|
|
66383
66820
|
// src/cli/headless/harnessStateEmit.ts
|
|
66384
|
-
import
|
|
66821
|
+
import path89 from "node:path";
|
|
66385
66822
|
async function emitHarnessStateEvent(opts) {
|
|
66386
66823
|
if (opts.output !== "json") return;
|
|
66387
66824
|
try {
|
|
66388
66825
|
const sessionsDir2 = resolveSessionsDir({ workspaceRoot: opts.workspaceRoot });
|
|
66389
|
-
const state3 = await readHarnessState(
|
|
66826
|
+
const state3 = await readHarnessState(path89.join(sessionsDir2, opts.spine.sessionId));
|
|
66390
66827
|
opts.emitEvent({ type: "harness_state", ...state3 });
|
|
66391
66828
|
} catch (err) {
|
|
66392
66829
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -66943,13 +67380,13 @@ var init_verifierLifecycle = __esm({
|
|
|
66943
67380
|
|
|
66944
67381
|
// src/cli/extensions/sandboxedFs.ts
|
|
66945
67382
|
import { promises as fsp } from "node:fs";
|
|
66946
|
-
import
|
|
67383
|
+
import path90 from "node:path";
|
|
66947
67384
|
function errText(prefix, p3, err) {
|
|
66948
67385
|
const msg = err instanceof Error ? err.message : String(err);
|
|
66949
67386
|
return `[extension-fs] ${prefix} "${p3}": ${msg}`;
|
|
66950
67387
|
}
|
|
66951
67388
|
function bindSandboxedFs(root) {
|
|
66952
|
-
const resolvedRoot =
|
|
67389
|
+
const resolvedRoot = path90.resolve(root);
|
|
66953
67390
|
return {
|
|
66954
67391
|
root: resolvedRoot,
|
|
66955
67392
|
async readFile(relativePath) {
|
|
@@ -66965,7 +67402,7 @@ function bindSandboxedFs(root) {
|
|
|
66965
67402
|
try {
|
|
66966
67403
|
const target = resolveSandboxedPath(relativePath, { root: resolvedRoot });
|
|
66967
67404
|
verifyContainment(target, { root: resolvedRoot });
|
|
66968
|
-
await fsp.mkdir(
|
|
67405
|
+
await fsp.mkdir(path90.dirname(target), { recursive: true });
|
|
66969
67406
|
await fsp.writeFile(target, data, "utf8");
|
|
66970
67407
|
return typedOk({ path: target });
|
|
66971
67408
|
} catch (err) {
|
|
@@ -67150,7 +67587,7 @@ var init_loader = __esm({
|
|
|
67150
67587
|
|
|
67151
67588
|
// src/cli/headless/runOneTurn.ts
|
|
67152
67589
|
import { promises as fs44 } from "node:fs";
|
|
67153
|
-
import
|
|
67590
|
+
import path91 from "node:path";
|
|
67154
67591
|
function planModeFromOpts(opts) {
|
|
67155
67592
|
return (opts.phase ?? "build") === "plan";
|
|
67156
67593
|
}
|
|
@@ -67717,7 +68154,7 @@ async function runOneTurn(opts, provider, model, providerStream, extras) {
|
|
|
67717
68154
|
if (json3) {
|
|
67718
68155
|
if (opts.exportSessionPath === "-") process.stdout.write(json3 + "\n");
|
|
67719
68156
|
else {
|
|
67720
|
-
await fs44.mkdir(
|
|
68157
|
+
await fs44.mkdir(path91.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
67721
68158
|
await fs44.writeFile(opts.exportSessionPath, json3, "utf8");
|
|
67722
68159
|
}
|
|
67723
68160
|
}
|
|
@@ -68696,9 +69133,9 @@ __export(triggerLock_exports, {
|
|
|
68696
69133
|
releaseLock: () => releaseLock
|
|
68697
69134
|
});
|
|
68698
69135
|
import { promises as fs45 } from "node:fs";
|
|
68699
|
-
import * as
|
|
69136
|
+
import * as path92 from "node:path";
|
|
68700
69137
|
function lockPath(projectRoot) {
|
|
68701
|
-
return
|
|
69138
|
+
return path92.join(projectRoot, ".zelari", "trigger.lock");
|
|
68702
69139
|
}
|
|
68703
69140
|
function isPidAlive(pid) {
|
|
68704
69141
|
try {
|
|
@@ -68711,7 +69148,7 @@ function isPidAlive(pid) {
|
|
|
68711
69148
|
}
|
|
68712
69149
|
async function acquireLock(projectRoot, now = () => /* @__PURE__ */ new Date()) {
|
|
68713
69150
|
const lp = lockPath(projectRoot);
|
|
68714
|
-
const dir =
|
|
69151
|
+
const dir = path92.dirname(lp);
|
|
68715
69152
|
await fs45.mkdir(dir, { recursive: true });
|
|
68716
69153
|
try {
|
|
68717
69154
|
const raw = await fs45.readFile(lp, "utf8");
|
|
@@ -68743,7 +69180,7 @@ var init_triggerLock = __esm({
|
|
|
68743
69180
|
|
|
68744
69181
|
// src/cli/runHeadless.ts
|
|
68745
69182
|
import { promises as fs46 } from "node:fs";
|
|
68746
|
-
import
|
|
69183
|
+
import path93 from "node:path";
|
|
68747
69184
|
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
68748
69185
|
async function runHeadless(opts) {
|
|
68749
69186
|
resetTaskSpawnCount();
|
|
@@ -68987,7 +69424,7 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
68987
69424
|
try {
|
|
68988
69425
|
let preflightGraph;
|
|
68989
69426
|
if (opts.runPlan && opts.runPlan.trim() !== "") {
|
|
68990
|
-
const planPath =
|
|
69427
|
+
const planPath = path93.join(cwd, ".zelari", "radio", `plan-${opts.runPlan}.json`);
|
|
68991
69428
|
log(`loading pre-flight plan: ${planPath}`);
|
|
68992
69429
|
let raw;
|
|
68993
69430
|
try {
|
|
@@ -69030,8 +69467,8 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
69030
69467
|
log(formatKrakenGraphAscii2(graph));
|
|
69031
69468
|
if (opts.planOnly) {
|
|
69032
69469
|
const planId = randomUUID10();
|
|
69033
|
-
const planDir =
|
|
69034
|
-
const planPath =
|
|
69470
|
+
const planDir = path93.join(cwd, ".zelari", "radio");
|
|
69471
|
+
const planPath = path93.join(planDir, `plan-${planId}.json`);
|
|
69035
69472
|
await fs46.mkdir(planDir, { recursive: true });
|
|
69036
69473
|
await fs46.writeFile(
|
|
69037
69474
|
planPath,
|
|
@@ -69409,7 +69846,7 @@ async function runHeadlessCouncilBody(opts, provider, model, providerStream, ext
|
|
|
69409
69846
|
if (json3) {
|
|
69410
69847
|
if (opts.exportSessionPath === "-") process.stdout.write(json3 + "\n");
|
|
69411
69848
|
else {
|
|
69412
|
-
await fs46.mkdir(
|
|
69849
|
+
await fs46.mkdir(path93.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
69413
69850
|
await fs46.writeFile(opts.exportSessionPath, json3, "utf8");
|
|
69414
69851
|
}
|
|
69415
69852
|
}
|
|
@@ -69860,7 +70297,7 @@ ${ragContext}` : slicePrompt;
|
|
|
69860
70297
|
if (json3) {
|
|
69861
70298
|
if (opts.exportSessionPath === "-") process.stdout.write(json3 + "\n");
|
|
69862
70299
|
else {
|
|
69863
|
-
await fs46.mkdir(
|
|
70300
|
+
await fs46.mkdir(path93.dirname(opts.exportSessionPath), { recursive: true }).catch(() => void 0);
|
|
69864
70301
|
await fs46.writeFile(opts.exportSessionPath, json3, "utf8");
|
|
69865
70302
|
}
|
|
69866
70303
|
}
|
|
@@ -69979,6 +70416,7 @@ function parseSetConfigFlags(argv) {
|
|
|
69979
70416
|
let model;
|
|
69980
70417
|
let endpoint;
|
|
69981
70418
|
let thinking;
|
|
70419
|
+
let apiStyle;
|
|
69982
70420
|
let endpointClear = false;
|
|
69983
70421
|
let verifierProvider;
|
|
69984
70422
|
let verifierModel;
|
|
@@ -69997,6 +70435,9 @@ function parseSetConfigFlags(argv) {
|
|
|
69997
70435
|
} else if (arg === "--thinking") {
|
|
69998
70436
|
thinking = argv[i + 1];
|
|
69999
70437
|
i++;
|
|
70438
|
+
} else if (arg === "--api-style") {
|
|
70439
|
+
apiStyle = argv[i + 1];
|
|
70440
|
+
i++;
|
|
70000
70441
|
} else if (arg === "--endpoint-clear") {
|
|
70001
70442
|
endpointClear = true;
|
|
70002
70443
|
} else if (arg === "--verifier-provider") {
|
|
@@ -70009,7 +70450,7 @@ function parseSetConfigFlags(argv) {
|
|
|
70009
70450
|
verifierClear = true;
|
|
70010
70451
|
}
|
|
70011
70452
|
}
|
|
70012
|
-
if (!provider && !model && !endpoint && !endpointClear && !thinking && !verifierProvider && !verifierModel && !verifierClear) {
|
|
70453
|
+
if (!provider && !model && !endpoint && !endpointClear && !thinking && !apiStyle && !verifierProvider && !verifierModel && !verifierClear) {
|
|
70013
70454
|
return {
|
|
70014
70455
|
request: null,
|
|
70015
70456
|
error: "--set-config: nothing to update \u2014 provide at least one of --provider, --model, --endpoint, --thinking, --verifier-provider + --verifier-model, --verifier-clear, or --endpoint-clear"
|
|
@@ -70024,6 +70465,9 @@ function parseSetConfigFlags(argv) {
|
|
|
70024
70465
|
if (endpoint !== void 0 && endpoint.trim().length === 0) {
|
|
70025
70466
|
return { request: null, error: "--endpoint cannot be empty" };
|
|
70026
70467
|
}
|
|
70468
|
+
if (apiStyle !== void 0 && apiStyle !== "chat" && apiStyle !== "responses") {
|
|
70469
|
+
return { request: null, error: "invalid --api-style " + apiStyle + " (use chat or responses)" };
|
|
70470
|
+
}
|
|
70027
70471
|
if (verifierClear && (verifierProvider || verifierModel)) {
|
|
70028
70472
|
return { request: null, error: "--verifier-clear conflicts with --verifier-provider/--verifier-model" };
|
|
70029
70473
|
}
|
|
@@ -70048,6 +70492,7 @@ function parseSetConfigFlags(argv) {
|
|
|
70048
70492
|
model: model?.trim(),
|
|
70049
70493
|
endpoint: endpoint?.trim(),
|
|
70050
70494
|
endpointClear: endpointClear || void 0,
|
|
70495
|
+
apiStyle,
|
|
70051
70496
|
thinking: thinking?.trim().toLowerCase(),
|
|
70052
70497
|
verifierProvider: verifierProvider?.trim(),
|
|
70053
70498
|
verifierModel: verifierModel?.trim(),
|
|
@@ -70127,6 +70572,7 @@ function buildDesktopConfigSnapshot() {
|
|
|
70127
70572
|
models,
|
|
70128
70573
|
defaultModel,
|
|
70129
70574
|
endpoint: custom2 ?? null,
|
|
70575
|
+
apiStyle: p3.id === "anthropic" || p3.id === "chatgpt" ? void 0 : getApiStyleFor(p3.id),
|
|
70130
70576
|
baseUrl: custom2 ?? builtin,
|
|
70131
70577
|
authKind: !hasKey ? "none" : oauth ? "oauth" : "api_key",
|
|
70132
70578
|
expiresAt: stored?.expiresAt ?? null,
|
|
@@ -70173,6 +70619,9 @@ function applySetConfig(req) {
|
|
|
70173
70619
|
if (req.endpoint) {
|
|
70174
70620
|
setCustomEndpoint(targetProvider, req.endpoint);
|
|
70175
70621
|
}
|
|
70622
|
+
if (req.apiStyle) {
|
|
70623
|
+
setApiStyleFor(targetProvider, req.apiStyle);
|
|
70624
|
+
}
|
|
70176
70625
|
if (req.model) {
|
|
70177
70626
|
setModelForProvider(targetProvider, req.model);
|
|
70178
70627
|
}
|
|
@@ -70473,7 +70922,7 @@ function upsertSkill(opts) {
|
|
|
70473
70922
|
}
|
|
70474
70923
|
dir = getProjectSkillsDir(root);
|
|
70475
70924
|
}
|
|
70476
|
-
const
|
|
70925
|
+
const path100 = skillFilePath(dir, name);
|
|
70477
70926
|
const content = serializeSkillMd({
|
|
70478
70927
|
name,
|
|
70479
70928
|
description,
|
|
@@ -70482,13 +70931,13 @@ function upsertSkill(opts) {
|
|
|
70482
70931
|
tools: opts.tools,
|
|
70483
70932
|
cost: opts.cost
|
|
70484
70933
|
});
|
|
70485
|
-
const parsed = parseSkillMd(content,
|
|
70934
|
+
const parsed = parseSkillMd(content, path100);
|
|
70486
70935
|
if (!parsed) {
|
|
70487
70936
|
return { ok: false, error: "Generated SKILL.md failed validation" };
|
|
70488
70937
|
}
|
|
70489
|
-
mkdirSync23(dirname13(
|
|
70490
|
-
writeFileSync25(
|
|
70491
|
-
return { ok: true, path:
|
|
70938
|
+
mkdirSync23(dirname13(path100), { recursive: true });
|
|
70939
|
+
writeFileSync25(path100, content, "utf8");
|
|
70940
|
+
return { ok: true, path: path100 };
|
|
70492
70941
|
}
|
|
70493
70942
|
function removeSkill(opts) {
|
|
70494
70943
|
const name = opts.name.trim().toLowerCase();
|
|
@@ -70506,8 +70955,8 @@ function removeSkill(opts) {
|
|
|
70506
70955
|
dir = getProjectSkillsDir(root);
|
|
70507
70956
|
}
|
|
70508
70957
|
const skillDir = join46(dir, name);
|
|
70509
|
-
const
|
|
70510
|
-
if (!existsSync59(
|
|
70958
|
+
const path100 = skillFilePath(dir, name);
|
|
70959
|
+
if (!existsSync59(path100) && !existsSync59(skillDir)) {
|
|
70511
70960
|
return { ok: false, error: `Skill "${name}" not found in ${dir}` };
|
|
70512
70961
|
}
|
|
70513
70962
|
try {
|
|
@@ -70518,7 +70967,7 @@ function removeSkill(opts) {
|
|
|
70518
70967
|
error: err instanceof Error ? err.message : String(err)
|
|
70519
70968
|
};
|
|
70520
70969
|
}
|
|
70521
|
-
return { ok: true, path:
|
|
70970
|
+
return { ok: true, path: path100 };
|
|
70522
70971
|
}
|
|
70523
70972
|
var NAME_RE, BUILTIN_SKILL_MODULES, builtinsLoaded;
|
|
70524
70973
|
var init_skillConfigIo = __esm({
|
|
@@ -70639,7 +71088,7 @@ var init_jsonApi = __esm({
|
|
|
70639
71088
|
});
|
|
70640
71089
|
|
|
70641
71090
|
// src/cli/memory/mcpAdapter.ts
|
|
70642
|
-
import * as
|
|
71091
|
+
import * as path94 from "node:path";
|
|
70643
71092
|
var id2, projectId, source, SearchSchema, AddSchema, LinkSchema, RetractSchema, MEMORY_MCP_TOOLS, MemoryMcpAdapter;
|
|
70644
71093
|
var init_mcpAdapter = __esm({
|
|
70645
71094
|
"src/cli/memory/mcpAdapter.ts"() {
|
|
@@ -70809,8 +71258,8 @@ var init_mcpAdapter = __esm({
|
|
|
70809
71258
|
this.takeWrite();
|
|
70810
71259
|
const externalFile = args.source?.file;
|
|
70811
71260
|
if (externalFile) {
|
|
70812
|
-
const normalized =
|
|
70813
|
-
if (
|
|
71261
|
+
const normalized = path94.normalize(externalFile);
|
|
71262
|
+
if (path94.isAbsolute(normalized) || normalized === ".." || normalized.startsWith(`..${path94.sep}`)) {
|
|
70814
71263
|
throw new Error("source.file must be project-relative and cannot escape the project");
|
|
70815
71264
|
}
|
|
70816
71265
|
}
|
|
@@ -71337,12 +71786,12 @@ function ensureHome() {
|
|
|
71337
71786
|
}
|
|
71338
71787
|
}
|
|
71339
71788
|
function loadCompanionConfig() {
|
|
71340
|
-
const
|
|
71341
|
-
if (!existsSync60(
|
|
71789
|
+
const path100 = getCompanionConfigPath();
|
|
71790
|
+
if (!existsSync60(path100)) {
|
|
71342
71791
|
return { projects: [] };
|
|
71343
71792
|
}
|
|
71344
71793
|
try {
|
|
71345
|
-
const raw = JSON.parse(readFileSync45(
|
|
71794
|
+
const raw = JSON.parse(readFileSync45(path100, "utf8"));
|
|
71346
71795
|
const projects = Array.isArray(raw.projects) ? raw.projects.filter(
|
|
71347
71796
|
(p3) => p3 && typeof p3.path === "string" && p3.path.trim() && typeof (p3.id ?? p3.name) === "string"
|
|
71348
71797
|
).map((p3) => ({
|
|
@@ -71380,16 +71829,16 @@ function loadOrCreateToken(explicit) {
|
|
|
71380
71829
|
return { token: explicit.trim(), created: false };
|
|
71381
71830
|
}
|
|
71382
71831
|
ensureHome();
|
|
71383
|
-
const
|
|
71384
|
-
if (existsSync60(
|
|
71385
|
-
const t = readFileSync45(
|
|
71832
|
+
const path100 = getCompanionTokenPath();
|
|
71833
|
+
if (existsSync60(path100)) {
|
|
71834
|
+
const t = readFileSync45(path100, "utf8").trim();
|
|
71386
71835
|
if (t) return { token: t, created: false };
|
|
71387
71836
|
}
|
|
71388
71837
|
const token = randomBytes7(24).toString("base64url");
|
|
71389
|
-
writeFileSync26(
|
|
71838
|
+
writeFileSync26(path100, token + "\n", "utf8");
|
|
71390
71839
|
try {
|
|
71391
71840
|
const fs48 = __require("node:fs");
|
|
71392
|
-
fs48.chmodSync?.(
|
|
71841
|
+
fs48.chmodSync?.(path100, 384);
|
|
71393
71842
|
} catch {
|
|
71394
71843
|
}
|
|
71395
71844
|
return { token, created: true };
|
|
@@ -71414,17 +71863,17 @@ function mergeProjects(cfg, extraPaths) {
|
|
|
71414
71863
|
byId.set(p3.id, p3);
|
|
71415
71864
|
}
|
|
71416
71865
|
for (const raw of extraPaths) {
|
|
71417
|
-
const
|
|
71418
|
-
if (!
|
|
71419
|
-
let id3 = slugFromPath(
|
|
71866
|
+
const path100 = raw.trim();
|
|
71867
|
+
if (!path100) continue;
|
|
71868
|
+
let id3 = slugFromPath(path100);
|
|
71420
71869
|
let n = 2;
|
|
71421
|
-
while (byId.has(id3) && byId.get(id3).path !==
|
|
71422
|
-
id3 = `${slugFromPath(
|
|
71870
|
+
while (byId.has(id3) && byId.get(id3).path !== path100) {
|
|
71871
|
+
id3 = `${slugFromPath(path100)}-${n++}`;
|
|
71423
71872
|
}
|
|
71424
71873
|
byId.set(id3, {
|
|
71425
71874
|
id: id3,
|
|
71426
|
-
name: slugFromPath(
|
|
71427
|
-
path:
|
|
71875
|
+
name: slugFromPath(path100),
|
|
71876
|
+
path: path100
|
|
71428
71877
|
});
|
|
71429
71878
|
}
|
|
71430
71879
|
return [...byId.values()];
|
|
@@ -71667,7 +72116,7 @@ var init_askUserBridge = __esm({
|
|
|
71667
72116
|
|
|
71668
72117
|
// src/cli/serve/spineLockSweep.ts
|
|
71669
72118
|
import { promises as fs47 } from "node:fs";
|
|
71670
|
-
import
|
|
72119
|
+
import path95 from "node:path";
|
|
71671
72120
|
async function sweepOrphanSpineLocks(sessionsDir2, options = {}) {
|
|
71672
72121
|
const dir = sessionsDir2 ?? resolveSessionsDir();
|
|
71673
72122
|
const onSwept = options.onSwept ?? ((sessionId2, reason) => {
|
|
@@ -71685,7 +72134,7 @@ async function sweepOrphanSpineLocks(sessionsDir2, options = {}) {
|
|
|
71685
72134
|
return result;
|
|
71686
72135
|
}
|
|
71687
72136
|
for (const sessionId2 of entries) {
|
|
71688
|
-
const lockPath2 =
|
|
72137
|
+
const lockPath2 = path95.join(dir, sessionId2, "writer.lock");
|
|
71689
72138
|
try {
|
|
71690
72139
|
const raw = await fs47.readFile(lockPath2, "utf-8");
|
|
71691
72140
|
let lockInfo = {};
|
|
@@ -72682,9 +73131,9 @@ async function runCompanionServe(opts = {}) {
|
|
|
72682
73131
|
return;
|
|
72683
73132
|
}
|
|
72684
73133
|
const url2 = parseUrl(req);
|
|
72685
|
-
const
|
|
73134
|
+
const path100 = url2.pathname.replace(/\/+$/, "") || "/";
|
|
72686
73135
|
try {
|
|
72687
|
-
if (req.method === "GET" && (
|
|
73136
|
+
if (req.method === "GET" && (path100 === "/health" || path100 === "/v1/health")) {
|
|
72688
73137
|
sendJson2(res, 200, {
|
|
72689
73138
|
ok: true,
|
|
72690
73139
|
service: "zelari-companion",
|
|
@@ -72696,18 +73145,18 @@ async function runCompanionServe(opts = {}) {
|
|
|
72696
73145
|
});
|
|
72697
73146
|
return;
|
|
72698
73147
|
}
|
|
72699
|
-
if (
|
|
73148
|
+
if (path100.startsWith("/v1")) {
|
|
72700
73149
|
if (!tokenMatches(token, getBearer(req))) {
|
|
72701
73150
|
sendJson2(res, 401, { ok: false, error: "unauthorized" });
|
|
72702
73151
|
return;
|
|
72703
73152
|
}
|
|
72704
73153
|
}
|
|
72705
|
-
if (req.method === "GET" &&
|
|
73154
|
+
if (req.method === "GET" && path100 === "/v1/config") {
|
|
72706
73155
|
const snap = buildDesktopConfigSnapshot();
|
|
72707
73156
|
sendJson2(res, 200, { ok: true, ...snap });
|
|
72708
73157
|
return;
|
|
72709
73158
|
}
|
|
72710
|
-
if (req.method === "GET" &&
|
|
73159
|
+
if (req.method === "GET" && path100 === "/v1/projects") {
|
|
72711
73160
|
sendJson2(res, 200, {
|
|
72712
73161
|
ok: true,
|
|
72713
73162
|
projects: projects.map((p3) => ({
|
|
@@ -72718,7 +73167,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
72718
73167
|
});
|
|
72719
73168
|
return;
|
|
72720
73169
|
}
|
|
72721
|
-
if (req.method === "GET" &&
|
|
73170
|
+
if (req.method === "GET" && path100 === "/v1/runs") {
|
|
72722
73171
|
sendJson2(res, 200, {
|
|
72723
73172
|
ok: true,
|
|
72724
73173
|
active: runs.getActive(),
|
|
@@ -72736,7 +73185,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
72736
73185
|
});
|
|
72737
73186
|
return;
|
|
72738
73187
|
}
|
|
72739
|
-
if (req.method === "POST" &&
|
|
73188
|
+
if (req.method === "POST" && path100 === "/v1/runs") {
|
|
72740
73189
|
const raw = await readBody(req);
|
|
72741
73190
|
let body = {};
|
|
72742
73191
|
try {
|
|
@@ -72784,7 +73233,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
72784
73233
|
});
|
|
72785
73234
|
return;
|
|
72786
73235
|
}
|
|
72787
|
-
const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(
|
|
73236
|
+
const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(path100);
|
|
72788
73237
|
if (req.method === "GET" && eventsMatch) {
|
|
72789
73238
|
const runId = eventsMatch[1];
|
|
72790
73239
|
const run = runs.getRun(runId);
|
|
@@ -72849,7 +73298,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
72849
73298
|
}, 500);
|
|
72850
73299
|
return;
|
|
72851
73300
|
}
|
|
72852
|
-
const cancelMatch = /^\/v1\/runs\/([^/]+)\/cancel$/.exec(
|
|
73301
|
+
const cancelMatch = /^\/v1\/runs\/([^/]+)\/cancel$/.exec(path100);
|
|
72853
73302
|
if (req.method === "POST" && cancelMatch) {
|
|
72854
73303
|
const runId = cancelMatch[1];
|
|
72855
73304
|
const result = runs.cancel(runId);
|
|
@@ -72860,7 +73309,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
72860
73309
|
sendJson2(res, 200, { ok: true, cancelled: runId });
|
|
72861
73310
|
return;
|
|
72862
73311
|
}
|
|
72863
|
-
const steerMatch = /^\/v1\/runs\/([^/]+)\/steer$/.exec(
|
|
73312
|
+
const steerMatch = /^\/v1\/runs\/([^/]+)\/steer$/.exec(path100);
|
|
72864
73313
|
if (req.method === "POST" && steerMatch) {
|
|
72865
73314
|
const runId = steerMatch[1];
|
|
72866
73315
|
const raw = await readBody(req);
|
|
@@ -73029,11 +73478,11 @@ import { execSync as execSync2 } from "node:child_process";
|
|
|
73029
73478
|
import { existsSync as existsSync62, readFileSync as readFileSync46, readlinkSync, statSync as statSync10 } from "node:fs";
|
|
73030
73479
|
import { createRequire as createRequire3 } from "node:module";
|
|
73031
73480
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
73032
|
-
import
|
|
73481
|
+
import path96 from "node:path";
|
|
73033
73482
|
function findPackageRoot(start) {
|
|
73034
73483
|
let dir = start;
|
|
73035
73484
|
for (let i = 0; i < 6; i += 1) {
|
|
73036
|
-
const candidate =
|
|
73485
|
+
const candidate = path96.join(dir, "package.json");
|
|
73037
73486
|
if (existsSync62(candidate)) {
|
|
73038
73487
|
try {
|
|
73039
73488
|
const pkg = JSON.parse(readFileSync46(candidate, "utf8"));
|
|
@@ -73041,11 +73490,11 @@ function findPackageRoot(start) {
|
|
|
73041
73490
|
} catch {
|
|
73042
73491
|
}
|
|
73043
73492
|
}
|
|
73044
|
-
const parent =
|
|
73493
|
+
const parent = path96.dirname(dir);
|
|
73045
73494
|
if (parent === dir) break;
|
|
73046
73495
|
dir = parent;
|
|
73047
73496
|
}
|
|
73048
|
-
return
|
|
73497
|
+
return path96.resolve(__dirname3, "..", "..", "..");
|
|
73049
73498
|
}
|
|
73050
73499
|
function tryExec(cmd) {
|
|
73051
73500
|
try {
|
|
@@ -73059,7 +73508,7 @@ function tryExec(cmd) {
|
|
|
73059
73508
|
}
|
|
73060
73509
|
function readPackageJson4() {
|
|
73061
73510
|
try {
|
|
73062
|
-
const pkgPath =
|
|
73511
|
+
const pkgPath = path96.join(packageRoot, "package.json");
|
|
73063
73512
|
return JSON.parse(readFileSync46(pkgPath, "utf8"));
|
|
73064
73513
|
} catch {
|
|
73065
73514
|
return null;
|
|
@@ -73071,7 +73520,7 @@ function getGlobalPrefix() {
|
|
|
73071
73520
|
return (process.env.npm_config_prefix || process.env.NPM_CONFIG_PREFIX || "").trim();
|
|
73072
73521
|
}
|
|
73073
73522
|
function isSourceCheckout() {
|
|
73074
|
-
return existsSync62(
|
|
73523
|
+
return existsSync62(path96.join(packageRoot, "src", "cli", "main.ts")) && existsSync62(path96.join(packageRoot, "apps", "desktop", "package.json"));
|
|
73075
73524
|
}
|
|
73076
73525
|
function checkShim(pkgName) {
|
|
73077
73526
|
const prefix = getGlobalPrefix();
|
|
@@ -73080,9 +73529,9 @@ function checkShim(pkgName) {
|
|
|
73080
73529
|
}
|
|
73081
73530
|
const isWin = process.platform === "win32";
|
|
73082
73531
|
const shimName = isWin ? "zelari-code.cmd" : "zelari-code";
|
|
73083
|
-
const shimPath =
|
|
73532
|
+
const shimPath = path96.join(prefix, shimName);
|
|
73084
73533
|
if (!existsSync62(shimPath)) {
|
|
73085
|
-
const localBin =
|
|
73534
|
+
const localBin = path96.join(packageRoot, "bin", "zelari-code.js");
|
|
73086
73535
|
if (isSourceCheckout() && existsSync62(localBin)) {
|
|
73087
73536
|
return WARN(
|
|
73088
73537
|
`global shim not found at ${shimPath}
|
|
@@ -73116,8 +73565,8 @@ function checkShim(pkgName) {
|
|
|
73116
73565
|
fix: npm install -g ${pkgName}@latest --force`
|
|
73117
73566
|
);
|
|
73118
73567
|
}
|
|
73119
|
-
const resolved =
|
|
73120
|
-
const expected =
|
|
73568
|
+
const resolved = path96.resolve(path96.dirname(shimPath), target);
|
|
73569
|
+
const expected = path96.join(
|
|
73121
73570
|
prefix,
|
|
73122
73571
|
"node_modules",
|
|
73123
73572
|
pkgName,
|
|
@@ -73159,7 +73608,7 @@ function checkNode(pkg) {
|
|
|
73159
73608
|
return OK(`node ${raw} (engines.node ${enginesNode ?? ">= 20.0.0"})`);
|
|
73160
73609
|
}
|
|
73161
73610
|
function checkBundle() {
|
|
73162
|
-
const bundle =
|
|
73611
|
+
const bundle = path96.join(packageRoot, "dist", "cli", "main.bundled.js");
|
|
73163
73612
|
if (!existsSync62(bundle)) {
|
|
73164
73613
|
return FAIL(
|
|
73165
73614
|
`dist/cli/main.bundled.js missing at ${bundle}
|
|
@@ -73180,7 +73629,7 @@ function checkRuntimeDeps() {
|
|
|
73180
73629
|
const missing = [];
|
|
73181
73630
|
for (const dep of required2) {
|
|
73182
73631
|
try {
|
|
73183
|
-
const localReq = createRequire3(
|
|
73632
|
+
const localReq = createRequire3(path96.join(packageRoot, "package.json"));
|
|
73184
73633
|
localReq.resolve(dep);
|
|
73185
73634
|
} catch {
|
|
73186
73635
|
missing.push(dep);
|
|
@@ -73457,7 +73906,7 @@ var init_doctor = __esm({
|
|
|
73457
73906
|
init_metrics3();
|
|
73458
73907
|
init_contextGrowthSummary();
|
|
73459
73908
|
require3 = createRequire3(import.meta.url);
|
|
73460
|
-
__dirname3 =
|
|
73909
|
+
__dirname3 = path96.dirname(fileURLToPath3(import.meta.url));
|
|
73461
73910
|
packageRoot = findPackageRoot(__dirname3);
|
|
73462
73911
|
OK = (message) => ({
|
|
73463
73912
|
ok: true,
|
|
@@ -73566,7 +74015,7 @@ __export(userSettings_exports, {
|
|
|
73566
74015
|
settingsOverrides: () => settingsOverrides
|
|
73567
74016
|
});
|
|
73568
74017
|
import { existsSync as existsSync63, readFileSync as readFileSync47 } from "node:fs";
|
|
73569
|
-
import
|
|
74018
|
+
import path97 from "node:path";
|
|
73570
74019
|
function parseBool(raw) {
|
|
73571
74020
|
const v = raw.trim().toLowerCase();
|
|
73572
74021
|
if (["1", "true", "yes", "on"].includes(v)) return true;
|
|
@@ -73633,8 +74082,8 @@ function envValueFor(key, env) {
|
|
|
73633
74082
|
function resolveUserSettings(opts = {}) {
|
|
73634
74083
|
const cwd = opts.cwd ?? process.cwd();
|
|
73635
74084
|
const env = opts.env ?? process.env;
|
|
73636
|
-
const userPath =
|
|
73637
|
-
const projectPath =
|
|
74085
|
+
const userPath = path97.join(zelariHome(), SETTINGS_FILE_NAME);
|
|
74086
|
+
const projectPath = path97.join(cwd, ".zelari", SETTINGS_FILE_NAME);
|
|
73638
74087
|
const warnings = [];
|
|
73639
74088
|
const userLayer = loadFileLayer(userPath, "user", warnings);
|
|
73640
74089
|
const projectLayer = loadFileLayer(projectPath, "project", warnings);
|
|
@@ -73848,7 +74297,7 @@ __export(inspectSession_exports, {
|
|
|
73848
74297
|
renderInspectReport: () => renderInspectReport,
|
|
73849
74298
|
runInspectSession: () => runInspectSession
|
|
73850
74299
|
});
|
|
73851
|
-
import
|
|
74300
|
+
import path98 from "node:path";
|
|
73852
74301
|
import { existsSync as existsSync64 } from "node:fs";
|
|
73853
74302
|
function formatLimit(limit) {
|
|
73854
74303
|
return `${Math.round(limit / 1e3)}k`;
|
|
@@ -73882,8 +74331,8 @@ function renderInspectReport(state3) {
|
|
|
73882
74331
|
}
|
|
73883
74332
|
async function runInspectSession(opts) {
|
|
73884
74333
|
const sessionsDir2 = resolveSessionsDir({ workspaceRoot: opts.cwd ?? process.cwd() });
|
|
73885
|
-
const sessionDir =
|
|
73886
|
-
const eventsPath =
|
|
74334
|
+
const sessionDir = path98.join(sessionsDir2, opts.sessionId);
|
|
74335
|
+
const eventsPath = path98.join(sessionDir, "events.jsonl");
|
|
73887
74336
|
if (!existsSync64(sessionDir)) {
|
|
73888
74337
|
console.error(`zelari-code inspect: no session directory at ${sessionDir}`);
|
|
73889
74338
|
return 1;
|
|
@@ -73917,14 +74366,14 @@ __export(inspect_exports, {
|
|
|
73917
74366
|
collectInspectReport: () => collectInspectReport,
|
|
73918
74367
|
runInspect: () => runInspect
|
|
73919
74368
|
});
|
|
73920
|
-
import
|
|
74369
|
+
import path99 from "node:path";
|
|
73921
74370
|
import { existsSync as existsSync65, readFileSync as readFileSync48, readdirSync as readdirSync13 } from "node:fs";
|
|
73922
74371
|
async function collectInspectReport(cwd = process.cwd()) {
|
|
73923
74372
|
ensureBuiltinSkillsLoadedSync();
|
|
73924
74373
|
const snap = listSkillsSnapshot(cwd);
|
|
73925
74374
|
const mcp = listMcpServers(cwd);
|
|
73926
|
-
const userMcpPath =
|
|
73927
|
-
const projectMcpPath =
|
|
74375
|
+
const userMcpPath = path99.join(zelariHome(), "mcp.json");
|
|
74376
|
+
const projectMcpPath = path99.join(cwd, ".zelari", "mcp.json");
|
|
73928
74377
|
const globalHooks = globalHooksDir();
|
|
73929
74378
|
const projectHooks = projectHooksDir(cwd);
|
|
73930
74379
|
const projectTrusted = isFolderTrusted(cwd);
|
|
@@ -73952,9 +74401,9 @@ async function collectInspectReport(cwd = process.cwd()) {
|
|
|
73952
74401
|
configSources: [
|
|
73953
74402
|
{ path: userMcpPath, exists: existsSync65(userMcpPath) },
|
|
73954
74403
|
{ path: projectMcpPath, exists: existsSync65(projectMcpPath) },
|
|
73955
|
-
{ path:
|
|
73956
|
-
{ path:
|
|
73957
|
-
{ path:
|
|
74404
|
+
{ path: path99.join(zelariHome(), "provider.json"), exists: existsSync65(path99.join(zelariHome(), "provider.json")) },
|
|
74405
|
+
{ path: path99.join(cwd, ".zelari", "AGENTS.md"), exists: existsSync65(path99.join(cwd, ".zelari", "AGENTS.md")) },
|
|
74406
|
+
{ path: path99.join(cwd, "AGENTS.md"), exists: existsSync65(path99.join(cwd, "AGENTS.md")) }
|
|
73958
74407
|
],
|
|
73959
74408
|
skills: {
|
|
73960
74409
|
total: snap.skills.length,
|
|
@@ -73994,8 +74443,8 @@ function listJsonFiles(dir) {
|
|
|
73994
74443
|
}
|
|
73995
74444
|
function findAgentsMd(cwd) {
|
|
73996
74445
|
const candidates = [
|
|
73997
|
-
|
|
73998
|
-
|
|
74446
|
+
path99.join(cwd, "AGENTS.md"),
|
|
74447
|
+
path99.join(cwd, ".zelari", "AGENTS.md")
|
|
73999
74448
|
];
|
|
74000
74449
|
const found = [];
|
|
74001
74450
|
for (const c of candidates) {
|
|
@@ -79250,10 +79699,10 @@ init_ledger();
|
|
|
79250
79699
|
|
|
79251
79700
|
// src/cli/evolution/proposals.ts
|
|
79252
79701
|
import { existsSync as existsSync51, readFileSync as readFileSync39 } from "node:fs";
|
|
79253
|
-
import
|
|
79254
|
-
var PROPOSALS_REL =
|
|
79702
|
+
import path77 from "node:path";
|
|
79703
|
+
var PROPOSALS_REL = path77.join(".zelari", "evolution", "proposals.jsonl");
|
|
79255
79704
|
function proposalsPath(cwd) {
|
|
79256
|
-
return
|
|
79705
|
+
return path77.join(cwd, PROPOSALS_REL);
|
|
79257
79706
|
}
|
|
79258
79707
|
function readProposalStore(cwd) {
|
|
79259
79708
|
const file2 = proposalsPath(cwd);
|
|
@@ -79541,6 +79990,24 @@ ${formatSkillList(availableSkills)}`
|
|
|
79541
79990
|
customEndpoint: url2
|
|
79542
79991
|
};
|
|
79543
79992
|
}
|
|
79993
|
+
if (subcommand === "api") {
|
|
79994
|
+
const target = args[1];
|
|
79995
|
+
if (!target || target === "show") {
|
|
79996
|
+
return {
|
|
79997
|
+
handled: true,
|
|
79998
|
+
kind: "provider_custom",
|
|
79999
|
+
message: "Usage: /provider api chat \u2014 POST /chat/completions (default)\n /provider api responses \u2014 POST /responses (OpenAI Responses API)\nApplies to the active provider; chatgpt/anthropic have a fixed transport."
|
|
80000
|
+
};
|
|
80001
|
+
}
|
|
80002
|
+
if (target !== "chat" && target !== "responses") {
|
|
80003
|
+
return {
|
|
80004
|
+
handled: true,
|
|
80005
|
+
kind: "provider_custom",
|
|
80006
|
+
message: `[provider] unknown api style: ${target}. Use: chat | responses`
|
|
80007
|
+
};
|
|
80008
|
+
}
|
|
80009
|
+
return { handled: true, kind: "provider_custom", apiStyle: target };
|
|
80010
|
+
}
|
|
79544
80011
|
const providerId = subcommand;
|
|
79545
80012
|
const sub = args[1];
|
|
79546
80013
|
if (sub === "refresh") {
|
|
@@ -80345,11 +80812,11 @@ function handleCacheStats(ctx) {
|
|
|
80345
80812
|
init_messageHelpers();
|
|
80346
80813
|
init_serviceFactory();
|
|
80347
80814
|
import { promises as fs35 } from "node:fs";
|
|
80348
|
-
import * as
|
|
80815
|
+
import * as path79 from "node:path";
|
|
80349
80816
|
|
|
80350
80817
|
// src/cli/memory/promotion.ts
|
|
80351
80818
|
import { promises as fs34 } from "node:fs";
|
|
80352
|
-
import * as
|
|
80819
|
+
import * as path78 from "node:path";
|
|
80353
80820
|
var START = "<!-- zelari:memory-promotions:start -->";
|
|
80354
80821
|
var END = "<!-- zelari:memory-promotions:end -->";
|
|
80355
80822
|
var DURABLE_KINDS = /* @__PURE__ */ new Set(["fact", "decision", "constraint", "preference", "procedure"]);
|
|
@@ -80360,16 +80827,16 @@ function lineFor(node) {
|
|
|
80360
80827
|
}
|
|
80361
80828
|
async function promoteMemoryToAgentsMd(projectRoot, node) {
|
|
80362
80829
|
if (node.status !== "active") {
|
|
80363
|
-
return { added: false, path:
|
|
80830
|
+
return { added: false, path: path78.join(projectRoot, "AGENTS.md"), reason: `memory is ${node.status}` };
|
|
80364
80831
|
}
|
|
80365
80832
|
if (!DURABLE_KINDS.has(node.kind)) {
|
|
80366
|
-
return { added: false, path:
|
|
80833
|
+
return { added: false, path: path78.join(projectRoot, "AGENTS.md"), reason: `${node.kind} is not a durable instruction kind` };
|
|
80367
80834
|
}
|
|
80368
|
-
const root = await fs34.realpath(projectRoot).catch(() =>
|
|
80369
|
-
const target =
|
|
80835
|
+
const root = await fs34.realpath(projectRoot).catch(() => path78.resolve(projectRoot));
|
|
80836
|
+
const target = path78.join(root, "AGENTS.md");
|
|
80370
80837
|
try {
|
|
80371
|
-
const
|
|
80372
|
-
if (
|
|
80838
|
+
const stat8 = await fs34.lstat(target);
|
|
80839
|
+
if (stat8.isSymbolicLink() || !stat8.isFile()) throw new Error("AGENTS.md must be a regular project file.");
|
|
80373
80840
|
} catch (error51) {
|
|
80374
80841
|
if (error51.code !== "ENOENT") throw error51;
|
|
80375
80842
|
}
|
|
@@ -80431,25 +80898,25 @@ function sourceLine(source2) {
|
|
|
80431
80898
|
return entries.length ? entries.map(([key, value]) => `${key}=${value}`).join(" \xB7 ") : "unknown";
|
|
80432
80899
|
}
|
|
80433
80900
|
function isInside(root, target) {
|
|
80434
|
-
const relative6 =
|
|
80435
|
-
return relative6 === "" || !relative6.startsWith("..") && !
|
|
80901
|
+
const relative6 = path79.relative(root, target);
|
|
80902
|
+
return relative6 === "" || !relative6.startsWith("..") && !path79.isAbsolute(relative6);
|
|
80436
80903
|
}
|
|
80437
80904
|
async function safeExportPath(cwd, requested) {
|
|
80438
|
-
const lexicalRoot =
|
|
80905
|
+
const lexicalRoot = path79.resolve(cwd);
|
|
80439
80906
|
const root = await fs35.realpath(lexicalRoot).catch(() => lexicalRoot);
|
|
80440
|
-
const fallback =
|
|
80441
|
-
const target = requested?.trim() ?
|
|
80907
|
+
const fallback = path79.join(root, ".zelari", "memory", `export-${Date.now()}.json`);
|
|
80908
|
+
const target = requested?.trim() ? path79.resolve(root, requested.trim()) : fallback;
|
|
80442
80909
|
if (!isInside(root, target)) {
|
|
80443
80910
|
throw new Error("Export path must stay inside the active project.");
|
|
80444
80911
|
}
|
|
80445
|
-
const parent =
|
|
80446
|
-
const relativeParent =
|
|
80912
|
+
const parent = path79.dirname(target);
|
|
80913
|
+
const relativeParent = path79.relative(root, parent);
|
|
80447
80914
|
let cursor = root;
|
|
80448
|
-
for (const segment of relativeParent.split(
|
|
80449
|
-
cursor =
|
|
80915
|
+
for (const segment of relativeParent.split(path79.sep).filter(Boolean)) {
|
|
80916
|
+
cursor = path79.join(cursor, segment);
|
|
80450
80917
|
try {
|
|
80451
|
-
const
|
|
80452
|
-
if (
|
|
80918
|
+
const stat8 = await fs35.lstat(cursor);
|
|
80919
|
+
if (stat8.isSymbolicLink()) {
|
|
80453
80920
|
throw new Error("Export path must not traverse a symbolic link.");
|
|
80454
80921
|
}
|
|
80455
80922
|
} catch (error51) {
|
|
@@ -80618,9 +81085,9 @@ ${message}` : message
|
|
|
80618
81085
|
}
|
|
80619
81086
|
case "export": {
|
|
80620
81087
|
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(
|
|
81088
|
+
await fs35.mkdir(path79.dirname(target), { recursive: true });
|
|
81089
|
+
const root = await fs35.realpath(ctx.cwd).catch(() => path79.resolve(ctx.cwd));
|
|
81090
|
+
const realParent = await fs35.realpath(path79.dirname(target));
|
|
80624
81091
|
if (!isInside(root, realParent)) {
|
|
80625
81092
|
throw new Error("Export path resolves outside the active project.");
|
|
80626
81093
|
}
|
|
@@ -80835,7 +81302,7 @@ import { promises as fs37 } from "node:fs";
|
|
|
80835
81302
|
init_zod();
|
|
80836
81303
|
init_taskTool();
|
|
80837
81304
|
import { promises as fs36 } from "node:fs";
|
|
80838
|
-
import
|
|
81305
|
+
import path80 from "node:path";
|
|
80839
81306
|
import { randomBytes as randomBytes6 } from "node:crypto";
|
|
80840
81307
|
var CsvFanoutArgsSchema = external_exports.object({
|
|
80841
81308
|
csv_path: external_exports.string().min(1),
|
|
@@ -80897,27 +81364,27 @@ function parseCsv(text) {
|
|
|
80897
81364
|
records.pop();
|
|
80898
81365
|
}
|
|
80899
81366
|
if (records.length === 0) return { headers: [], rows: [] };
|
|
80900
|
-
const
|
|
81367
|
+
const headers3 = records[0];
|
|
80901
81368
|
const rows = records.slice(1).map((r) => {
|
|
80902
81369
|
const obj = {};
|
|
80903
|
-
for (let i = 0; i <
|
|
81370
|
+
for (let i = 0; i < headers3.length; i++) obj[headers3[i]] = r[i] ?? "";
|
|
80904
81371
|
return obj;
|
|
80905
81372
|
});
|
|
80906
|
-
return { headers:
|
|
81373
|
+
return { headers: headers3, rows };
|
|
80907
81374
|
}
|
|
80908
81375
|
function applyTemplate(template, row) {
|
|
80909
81376
|
return template.replace(/\{([a-zA-Z_][\w-]*)\}/g, (_, k) => row[k] ?? "");
|
|
80910
81377
|
}
|
|
80911
|
-
function serializeCsv(
|
|
81378
|
+
function serializeCsv(headers3, rows) {
|
|
80912
81379
|
const escape = (v) => {
|
|
80913
81380
|
if (v.includes(",") || v.includes("\n") || v.includes('"')) {
|
|
80914
81381
|
return `"${v.replace(/"/g, '""')}"`;
|
|
80915
81382
|
}
|
|
80916
81383
|
return v;
|
|
80917
81384
|
};
|
|
80918
|
-
const out = [
|
|
81385
|
+
const out = [headers3.map(escape).join(",")];
|
|
80919
81386
|
for (const row of rows) {
|
|
80920
|
-
out.push(
|
|
81387
|
+
out.push(headers3.map((h) => escape(row[h] ?? "")).join(","));
|
|
80921
81388
|
}
|
|
80922
81389
|
return out.join("\n") + "\n";
|
|
80923
81390
|
}
|
|
@@ -80929,23 +81396,23 @@ function resolveMaxConcurrency(env = process.env) {
|
|
|
80929
81396
|
}
|
|
80930
81397
|
async function runCsvFanout(args, deps, opts) {
|
|
80931
81398
|
const start = Date.now();
|
|
80932
|
-
const absCsv =
|
|
80933
|
-
const absOut =
|
|
80934
|
-
const { headers:
|
|
80935
|
-
if (
|
|
81399
|
+
const absCsv = path80.isAbsolute(args.csv_path) ? args.csv_path : path80.join(opts.parentCwd, args.csv_path);
|
|
81400
|
+
const absOut = path80.isAbsolute(args.output_csv_path) ? args.output_csv_path : path80.join(opts.parentCwd, args.output_csv_path);
|
|
81401
|
+
const { headers: headers3, rows } = await readCsv(absCsv);
|
|
81402
|
+
if (headers3.length === 0) {
|
|
80936
81403
|
throw new Error(`kraken_csv_fanout: ${absCsv} is empty`);
|
|
80937
81404
|
}
|
|
80938
81405
|
if (!args.id_column) {
|
|
80939
81406
|
throw new Error("kraken_csv_fanout: id_column is required");
|
|
80940
81407
|
}
|
|
80941
|
-
if (!
|
|
80942
|
-
throw new Error(`kraken_csv_fanout: id_column "${args.id_column}" not in CSV header [${
|
|
81408
|
+
if (!headers3.includes(args.id_column)) {
|
|
81409
|
+
throw new Error(`kraken_csv_fanout: id_column "${args.id_column}" not in CSV header [${headers3.join(", ")}]`);
|
|
80943
81410
|
}
|
|
80944
81411
|
const concurrency = args.max_concurrency ?? resolveMaxConcurrency();
|
|
80945
81412
|
opts.onLog?.(`csv fanout: ${rows.length} rows \xD7 ${args.agent_kind} @ concurrency=${concurrency}`);
|
|
80946
81413
|
const perRowMs = args.max_runtime_seconds !== void 0 ? args.max_runtime_seconds * 1e3 : args.agent_kind === "general" ? TASK_TOOL_TIMEOUT_MS : 3e5;
|
|
80947
81414
|
const outputRecords = rows.map((r) => ({ ...r, status: "pending", result: "", error: "" }));
|
|
80948
|
-
const outHeaders = [...
|
|
81415
|
+
const outHeaders = [...headers3, "status", "result", "error"];
|
|
80949
81416
|
let writeChain2 = Promise.resolve();
|
|
80950
81417
|
function queueWrite(contents) {
|
|
80951
81418
|
const next = writeChain2.then(() => atomicWrite(absOut, contents));
|
|
@@ -80986,7 +81453,7 @@ async function runCsvFanout(args, deps, opts) {
|
|
|
80986
81453
|
errored += 1;
|
|
80987
81454
|
errors.push(`${row[args.id_column] ?? i}: ${res.error}`);
|
|
80988
81455
|
}
|
|
80989
|
-
await fs36.mkdir(
|
|
81456
|
+
await fs36.mkdir(path80.dirname(absOut), { recursive: true });
|
|
80990
81457
|
await queueWrite(serializeCsv(outHeaders, outputRecords));
|
|
80991
81458
|
}
|
|
80992
81459
|
}
|
|
@@ -81181,7 +81648,7 @@ function splitArgs(s) {
|
|
|
81181
81648
|
// src/cli/slashHandlers/krakenWorkbench.ts
|
|
81182
81649
|
init_messageHelpers();
|
|
81183
81650
|
import { promises as fs38 } from "node:fs";
|
|
81184
|
-
import
|
|
81651
|
+
import path81 from "node:path";
|
|
81185
81652
|
|
|
81186
81653
|
// src/cli/kraken/workbenchView.ts
|
|
81187
81654
|
var EMPTY = {
|
|
@@ -81298,17 +81765,17 @@ function formatWorkbenchForTerminal(p3) {
|
|
|
81298
81765
|
|
|
81299
81766
|
// src/cli/slashHandlers/krakenWorkbench.ts
|
|
81300
81767
|
async function handleKrakenWorkbench(ctx) {
|
|
81301
|
-
const dir =
|
|
81768
|
+
const dir = path81.join(ctx.cwd, ".zelari", "radio");
|
|
81302
81769
|
let latest = null;
|
|
81303
81770
|
let latestMtime = 0;
|
|
81304
81771
|
try {
|
|
81305
81772
|
const files = await fs38.readdir(dir);
|
|
81306
81773
|
for (const f of files) {
|
|
81307
81774
|
if (!f.startsWith("workbench-") || !f.endsWith(".md")) continue;
|
|
81308
|
-
const full =
|
|
81309
|
-
const
|
|
81310
|
-
if (
|
|
81311
|
-
latestMtime =
|
|
81775
|
+
const full = path81.join(dir, f);
|
|
81776
|
+
const stat8 = await fs38.stat(full);
|
|
81777
|
+
if (stat8.mtimeMs > latestMtime) {
|
|
81778
|
+
latestMtime = stat8.mtimeMs;
|
|
81312
81779
|
latest = full;
|
|
81313
81780
|
}
|
|
81314
81781
|
}
|
|
@@ -81322,10 +81789,10 @@ async function handleKrakenWorkbench(ctx) {
|
|
|
81322
81789
|
const parsed = parseWorkbench(content);
|
|
81323
81790
|
const rendered = formatWorkbenchForTerminal(parsed);
|
|
81324
81791
|
if (!rendered.trim()) {
|
|
81325
|
-
appendSystem(ctx.setMessages, `[kraken workbench] ${
|
|
81792
|
+
appendSystem(ctx.setMessages, `[kraken workbench] ${path81.basename(latest)}: (no nodes / no events yet)`);
|
|
81326
81793
|
return;
|
|
81327
81794
|
}
|
|
81328
|
-
appendSystem(ctx.setMessages, `[kraken workbench] ${
|
|
81795
|
+
appendSystem(ctx.setMessages, `[kraken workbench] ${path81.basename(latest)}:
|
|
81329
81796
|
${rendered}`);
|
|
81330
81797
|
}
|
|
81331
81798
|
|
|
@@ -81633,14 +82100,14 @@ ${result.output.split("\n").slice(-8).join("\n")}` : "";
|
|
|
81633
82100
|
init_messageHelpers();
|
|
81634
82101
|
init_paths();
|
|
81635
82102
|
import { promises as fs39 } from "node:fs";
|
|
81636
|
-
import
|
|
82103
|
+
import path84 from "node:path";
|
|
81637
82104
|
async function handlePromoteMember(ctx, memberId) {
|
|
81638
82105
|
try {
|
|
81639
82106
|
const { promoteMember: promoteMember2 } = await Promise.resolve().then(() => (init_council(), council_exports));
|
|
81640
82107
|
const { skill, markdown } = promoteMember2(memberId);
|
|
81641
82108
|
const skillDir = skillsDir();
|
|
81642
82109
|
await fs39.mkdir(skillDir, { recursive: true });
|
|
81643
|
-
const filePath =
|
|
82110
|
+
const filePath = path84.join(skillDir, `${skill.id}.md`);
|
|
81644
82111
|
const previous = await fs39.readFile(filePath, "utf8").catch(() => null);
|
|
81645
82112
|
const { createHash: createHash24 } = await import("node:crypto");
|
|
81646
82113
|
const sha = (s) => createHash24("sha256").update(s, "utf8").digest("hex");
|
|
@@ -81666,7 +82133,7 @@ ${lineage}
|
|
|
81666
82133
|
// src/cli/branchManager.ts
|
|
81667
82134
|
init_paths();
|
|
81668
82135
|
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
|
|
82136
|
+
import path85 from "node:path";
|
|
81670
82137
|
var META_FILENAME = "meta.json";
|
|
81671
82138
|
var SESSIONS_SUBDIR = "sessions";
|
|
81672
82139
|
function getBranchesBaseDir() {
|
|
@@ -81676,13 +82143,13 @@ function getSessionsBaseDir() {
|
|
|
81676
82143
|
return sessionsDir();
|
|
81677
82144
|
}
|
|
81678
82145
|
function branchPathFor(name, baseDir) {
|
|
81679
|
-
return
|
|
82146
|
+
return path85.join(baseDir, name);
|
|
81680
82147
|
}
|
|
81681
82148
|
function metaPathFor(name, baseDir) {
|
|
81682
|
-
return
|
|
82149
|
+
return path85.join(baseDir, name, META_FILENAME);
|
|
81683
82150
|
}
|
|
81684
82151
|
function sessionsPathFor(name, baseDir) {
|
|
81685
|
-
return
|
|
82152
|
+
return path85.join(baseDir, name, SESSIONS_SUBDIR);
|
|
81686
82153
|
}
|
|
81687
82154
|
function readBranchMeta(name, baseDir) {
|
|
81688
82155
|
const metaPath = metaPathFor(name, baseDir);
|
|
@@ -81707,7 +82174,7 @@ function readBranchMeta(name, baseDir) {
|
|
|
81707
82174
|
}
|
|
81708
82175
|
function writeBranchMeta(name, baseDir, meta3) {
|
|
81709
82176
|
const metaPath = metaPathFor(name, baseDir);
|
|
81710
|
-
mkdirSync21(
|
|
82177
|
+
mkdirSync21(path85.dirname(metaPath), { recursive: true });
|
|
81711
82178
|
writeFileSync24(metaPath, JSON.stringify(meta3, null, 2), "utf-8");
|
|
81712
82179
|
}
|
|
81713
82180
|
async function countSessions(name, baseDir) {
|
|
@@ -81758,14 +82225,14 @@ async function createBranch(name, fromSessionId, baseDir = getBranchesBaseDir(),
|
|
|
81758
82225
|
if (branchExists(name, baseDir)) {
|
|
81759
82226
|
throw new BranchAlreadyExistsError(name);
|
|
81760
82227
|
}
|
|
81761
|
-
const sourcePath =
|
|
82228
|
+
const sourcePath = path85.join(sessionsBaseDir, `${fromSessionId}.jsonl`);
|
|
81762
82229
|
if (!existsSync55(sourcePath)) {
|
|
81763
82230
|
throw new SessionNotFoundError(`Source session "${fromSessionId}" not found at ${sourcePath}`);
|
|
81764
82231
|
}
|
|
81765
82232
|
const branchPath = branchPathFor(name, baseDir);
|
|
81766
82233
|
const branchSessionsPath = sessionsPathFor(name, baseDir);
|
|
81767
82234
|
mkdirSync21(branchSessionsPath, { recursive: true });
|
|
81768
|
-
const destPath =
|
|
82235
|
+
const destPath = path85.join(branchSessionsPath, `${fromSessionId}.jsonl`);
|
|
81769
82236
|
await fs40.copyFile(sourcePath, destPath);
|
|
81770
82237
|
const meta3 = {
|
|
81771
82238
|
name,
|
|
@@ -81869,14 +82336,14 @@ async function handleBranchCheckout(ctx, branchName) {
|
|
|
81869
82336
|
// src/cli/slashHandlers/workspace.ts
|
|
81870
82337
|
init_messageHelpers();
|
|
81871
82338
|
import { promises as fs41 } from "node:fs";
|
|
81872
|
-
import
|
|
82339
|
+
import path86 from "node:path";
|
|
81873
82340
|
async function handleWorkspaceShow(ctx, what) {
|
|
81874
82341
|
try {
|
|
81875
|
-
const zelari =
|
|
82342
|
+
const zelari = path86.join(process.cwd(), ".zelari");
|
|
81876
82343
|
let content;
|
|
81877
82344
|
switch (what) {
|
|
81878
82345
|
case "plan": {
|
|
81879
|
-
const planPath =
|
|
82346
|
+
const planPath = path86.join(zelari, "plan.md");
|
|
81880
82347
|
try {
|
|
81881
82348
|
content = await fs41.readFile(planPath, "utf-8");
|
|
81882
82349
|
} catch {
|
|
@@ -81885,7 +82352,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
81885
82352
|
break;
|
|
81886
82353
|
}
|
|
81887
82354
|
case "decisions": {
|
|
81888
|
-
const decisionsDir =
|
|
82355
|
+
const decisionsDir = path86.join(zelari, "decisions");
|
|
81889
82356
|
try {
|
|
81890
82357
|
const files = (await fs41.readdir(decisionsDir)).filter((f) => f.endsWith(".md")).sort();
|
|
81891
82358
|
if (files.length === 0) {
|
|
@@ -81895,7 +82362,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
81895
82362
|
`];
|
|
81896
82363
|
const { parseFrontmatter: parseFrontmatter2 } = await Promise.resolve().then(() => (init_storage(), storage_exports));
|
|
81897
82364
|
for (const f of files) {
|
|
81898
|
-
const raw = await fs41.readFile(
|
|
82365
|
+
const raw = await fs41.readFile(path86.join(decisionsDir, f), "utf-8");
|
|
81899
82366
|
const { meta: meta3, body } = parseFrontmatter2(raw);
|
|
81900
82367
|
const title = meta3.title ?? body.split("\n")[0]?.replace(/^#\s*/, "").trim() ?? f;
|
|
81901
82368
|
lines.push(`- **${f.replace(/\.md$/, "")}** [${meta3.status ?? "unknown"}] ${title}`);
|
|
@@ -81908,7 +82375,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
81908
82375
|
break;
|
|
81909
82376
|
}
|
|
81910
82377
|
case "risks": {
|
|
81911
|
-
const risksPath =
|
|
82378
|
+
const risksPath = path86.join(zelari, "risks.md");
|
|
81912
82379
|
try {
|
|
81913
82380
|
content = await fs41.readFile(risksPath, "utf-8");
|
|
81914
82381
|
} catch {
|
|
@@ -81917,7 +82384,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
81917
82384
|
break;
|
|
81918
82385
|
}
|
|
81919
82386
|
case "agents": {
|
|
81920
|
-
const agentsPath =
|
|
82387
|
+
const agentsPath = path86.join(process.cwd(), "AGENTS.MD");
|
|
81921
82388
|
try {
|
|
81922
82389
|
content = await fs41.readFile(agentsPath, "utf-8");
|
|
81923
82390
|
} catch {
|
|
@@ -81926,7 +82393,7 @@ async function handleWorkspaceShow(ctx, what) {
|
|
|
81926
82393
|
break;
|
|
81927
82394
|
}
|
|
81928
82395
|
case "docs": {
|
|
81929
|
-
const docsDir =
|
|
82396
|
+
const docsDir = path86.join(zelari, "docs");
|
|
81930
82397
|
try {
|
|
81931
82398
|
const files = (await fs41.readdir(docsDir)).filter((f) => f.endsWith(".md")).sort();
|
|
81932
82399
|
content = files.length ? `# Docs (${files.length})
|
|
@@ -81968,7 +82435,7 @@ async function handleWorkspaceReset(ctx, force) {
|
|
|
81968
82435
|
return;
|
|
81969
82436
|
}
|
|
81970
82437
|
try {
|
|
81971
|
-
const target =
|
|
82438
|
+
const target = path86.join(process.cwd(), ".zelari");
|
|
81972
82439
|
await fs41.rm(target, { recursive: true, force: true });
|
|
81973
82440
|
appendSystem(ctx.setMessages, "[workspace] .zelari/ removed");
|
|
81974
82441
|
} catch (err) {
|
|
@@ -82306,6 +82773,7 @@ function useSlashDispatch(params) {
|
|
|
82306
82773
|
handleProviderCustom(providerCtx, {
|
|
82307
82774
|
endpoint: result.customEndpoint,
|
|
82308
82775
|
clear: result.customClear,
|
|
82776
|
+
apiStyle: result.apiStyle,
|
|
82309
82777
|
message: result.message
|
|
82310
82778
|
});
|
|
82311
82779
|
setInput("");
|
|
@@ -83851,8 +84319,8 @@ function normalizeDraft(raw, sourceUrl, provider, model) {
|
|
|
83851
84319
|
let name = String(o.name ?? "").trim().toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64);
|
|
83852
84320
|
if (!name || !/^[a-z0-9][a-z0-9-]{0,63}$/.test(name)) {
|
|
83853
84321
|
try {
|
|
83854
|
-
const
|
|
83855
|
-
name =
|
|
84322
|
+
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);
|
|
84323
|
+
name = path100 && /^[a-z0-9]/.test(path100) ? path100 : "imported-skill";
|
|
83856
84324
|
} catch {
|
|
83857
84325
|
name = "imported-skill";
|
|
83858
84326
|
}
|