zelari-code 2.35.0 → 2.37.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/desktopConfig.js +18 -3
- package/dist/cli/desktopConfig.js.map +1 -1
- package/dist/cli/evolution/ledger.js.map +1 -1
- package/dist/cli/evolution/runTelemetry.js +68 -0
- package/dist/cli/evolution/runTelemetry.js.map +1 -0
- package/dist/cli/headless.js +10 -0
- package/dist/cli/headless.js.map +1 -1
- package/dist/cli/hooks/useChatTurn.js +6 -0
- package/dist/cli/hooks/useChatTurn.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 +682 -80
- package/dist/cli/main.bundled.js.map +4 -4
- package/dist/cli/main.js +2 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/provider/chatgpt.js +1 -1
- package/dist/cli/provider/chatgpt.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/runHeadless.js +32 -1
- package/dist/cli/runHeadless.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/workspace/planStore.js +29 -0
- package/dist/cli/workspace/planStore.js.map +1 -1
- package/dist/cli/zelariMission.js +130 -30
- package/dist/cli/zelariMission.js.map +1 -1
- 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)}`,
|
|
@@ -33786,10 +33854,28 @@ function buildMissionBrief(input) {
|
|
|
33786
33854
|
],
|
|
33787
33855
|
phases,
|
|
33788
33856
|
sliceMvp,
|
|
33789
|
-
slices:
|
|
33857
|
+
slices: buildSlicePlan(sliceMvp, input.planTaskIds, maxTasks),
|
|
33790
33858
|
userPromptOriginal: userMessage
|
|
33791
33859
|
};
|
|
33792
33860
|
}
|
|
33861
|
+
function buildSlicePlan(sliceMvp, planTaskIds, maxTasks) {
|
|
33862
|
+
const ids = Array.isArray(planTaskIds) ? planTaskIds.filter((t) => typeof t === "string" && t) : [];
|
|
33863
|
+
if (ids.length === 0)
|
|
33864
|
+
return [{ ...sliceMvp }];
|
|
33865
|
+
const size = Number.isFinite(maxTasks) && maxTasks > 0 ? Math.floor(maxTasks) : 8;
|
|
33866
|
+
const slices = [];
|
|
33867
|
+
for (let i = 0; i < ids.length; i += size) {
|
|
33868
|
+
const chunk = ids.slice(i, i + size);
|
|
33869
|
+
const index = i / size;
|
|
33870
|
+
slices.push(index === 0 ? { ...sliceMvp, taskIds: chunk, maxTasks: size } : {
|
|
33871
|
+
id: `slice-${index + 1}`,
|
|
33872
|
+
title: `Increment ${index + 1} \u2014 ${chunk.length} plan task(s)`,
|
|
33873
|
+
taskIds: chunk,
|
|
33874
|
+
maxTasks: size
|
|
33875
|
+
});
|
|
33876
|
+
}
|
|
33877
|
+
return slices;
|
|
33878
|
+
}
|
|
33793
33879
|
var STACK_SIGNALS;
|
|
33794
33880
|
var init_missionBrief = __esm({
|
|
33795
33881
|
"packages/core/dist/council/missionBrief.js"() {
|
|
@@ -34614,6 +34700,7 @@ __export(council_exports, {
|
|
|
34614
34700
|
buildMotionFixPrompt: () => buildMotionFixPrompt,
|
|
34615
34701
|
buildRetryPrompt: () => buildRetryPrompt,
|
|
34616
34702
|
buildSkillDefinition: () => buildSkillDefinition,
|
|
34703
|
+
buildSlicePlan: () => buildSlicePlan,
|
|
34617
34704
|
buildSystemPrompt: () => buildSystemPrompt,
|
|
34618
34705
|
buildSystemPromptSplit: () => buildSystemPromptSplit,
|
|
34619
34706
|
captureFailure: () => captureFailure,
|
|
@@ -38221,7 +38308,7 @@ var CORE_VERSION;
|
|
|
38221
38308
|
var init_version = __esm({
|
|
38222
38309
|
"packages/core/dist/version.js"() {
|
|
38223
38310
|
"use strict";
|
|
38224
|
-
CORE_VERSION = "2.
|
|
38311
|
+
CORE_VERSION = "2.37.0";
|
|
38225
38312
|
}
|
|
38226
38313
|
});
|
|
38227
38314
|
|
|
@@ -38471,6 +38558,7 @@ __export(dist_exports, {
|
|
|
38471
38558
|
buildRetryPrompt: () => buildRetryPrompt,
|
|
38472
38559
|
buildRuntimeObserverBus: () => buildRuntimeObserverBus,
|
|
38473
38560
|
buildSkillDefinition: () => buildSkillDefinition,
|
|
38561
|
+
buildSlicePlan: () => buildSlicePlan,
|
|
38474
38562
|
buildSystemPrompt: () => buildSystemPrompt,
|
|
38475
38563
|
buildSystemPromptSplit: () => buildSystemPromptSplit,
|
|
38476
38564
|
canExternalClientMutate: () => canExternalClientMutate,
|
|
@@ -41557,6 +41645,24 @@ var init_storage = __esm({
|
|
|
41557
41645
|
});
|
|
41558
41646
|
|
|
41559
41647
|
// src/cli/workspace/planStore.ts
|
|
41648
|
+
var planStore_exports = {};
|
|
41649
|
+
__export(planStore_exports, {
|
|
41650
|
+
PLAN_FILES_MAX: () => PLAN_FILES_MAX,
|
|
41651
|
+
PLAN_FILE_GLOB_MAX: () => PLAN_FILE_GLOB_MAX,
|
|
41652
|
+
PLAN_MAX_TASKS: () => PLAN_MAX_TASKS,
|
|
41653
|
+
PLAN_NOTES_MAX: () => PLAN_NOTES_MAX,
|
|
41654
|
+
PLAN_SCHEMA_VERSION: () => PLAN_SCHEMA_VERSION,
|
|
41655
|
+
PLAN_TAG_MAX: () => PLAN_TAG_MAX,
|
|
41656
|
+
PLAN_TASK_STATUSES: () => PLAN_TASK_STATUSES,
|
|
41657
|
+
PLAN_TITLE_MAX: () => PLAN_TITLE_MAX,
|
|
41658
|
+
PlanStoreError: () => PlanStoreError,
|
|
41659
|
+
listOpenPlanTaskIds: () => listOpenPlanTaskIds,
|
|
41660
|
+
nextPlanTaskId: () => nextPlanTaskId,
|
|
41661
|
+
normalizePlanTaskFiles: () => normalizePlanTaskFiles,
|
|
41662
|
+
planJsonPathFor: () => planJsonPathFor,
|
|
41663
|
+
withPlanStore: () => withPlanStore,
|
|
41664
|
+
writePlanTaskArtifact: () => writePlanTaskArtifact
|
|
41665
|
+
});
|
|
41560
41666
|
import {
|
|
41561
41667
|
copyFileSync,
|
|
41562
41668
|
existsSync as existsSync20,
|
|
@@ -41579,6 +41685,24 @@ function normalizePlanTaskFiles(values) {
|
|
|
41579
41685
|
function planJsonPathFor(projectRoot = process.cwd()) {
|
|
41580
41686
|
return join17(resolveWorkspaceRoot(projectRoot), "plan.json");
|
|
41581
41687
|
}
|
|
41688
|
+
async function listOpenPlanTaskIds(projectRoot) {
|
|
41689
|
+
try {
|
|
41690
|
+
const jsonPath = planJsonPathFor(projectRoot);
|
|
41691
|
+
if (!existsSync20(jsonPath)) return [];
|
|
41692
|
+
const parsed = JSON.parse(readFileSync18(jsonPath, "utf8"));
|
|
41693
|
+
if (!Array.isArray(parsed.tasks)) return [];
|
|
41694
|
+
const ids = [];
|
|
41695
|
+
for (const raw of parsed.tasks) {
|
|
41696
|
+
if (raw === null || typeof raw !== "object") continue;
|
|
41697
|
+
const t = raw;
|
|
41698
|
+
if (typeof t.id !== "string" || t.id.length === 0) continue;
|
|
41699
|
+
if (t.status === "pending" || t.status === "in_progress") ids.push(t.id);
|
|
41700
|
+
}
|
|
41701
|
+
return ids;
|
|
41702
|
+
} catch {
|
|
41703
|
+
return [];
|
|
41704
|
+
}
|
|
41705
|
+
}
|
|
41582
41706
|
async function withPlanStore(projectRoot, fn) {
|
|
41583
41707
|
const rootDir = resolveWorkspaceRoot(projectRoot);
|
|
41584
41708
|
return workspaceMutex.run(`${rootDir}:plan`, () => {
|
|
@@ -41722,7 +41846,7 @@ function normalizeStatus(raw) {
|
|
|
41722
41846
|
function firstString(v) {
|
|
41723
41847
|
return typeof v === "string" && v.trim().length > 0 ? v : null;
|
|
41724
41848
|
}
|
|
41725
|
-
var PLAN_SCHEMA_VERSION, PLAN_MAX_TASKS, PLAN_TITLE_MAX, PLAN_NOTES_MAX, PLAN_TAG_MAX, PLAN_FILES_MAX, PLAN_FILE_GLOB_MAX, PlanStoreError;
|
|
41849
|
+
var PLAN_SCHEMA_VERSION, PLAN_MAX_TASKS, PLAN_TITLE_MAX, PLAN_NOTES_MAX, PLAN_TAG_MAX, PLAN_TASK_STATUSES, PLAN_FILES_MAX, PLAN_FILE_GLOB_MAX, PlanStoreError;
|
|
41726
41850
|
var init_planStore = __esm({
|
|
41727
41851
|
"src/cli/workspace/planStore.ts"() {
|
|
41728
41852
|
"use strict";
|
|
@@ -41733,6 +41857,13 @@ var init_planStore = __esm({
|
|
|
41733
41857
|
PLAN_TITLE_MAX = 200;
|
|
41734
41858
|
PLAN_NOTES_MAX = 2e3;
|
|
41735
41859
|
PLAN_TAG_MAX = 64;
|
|
41860
|
+
PLAN_TASK_STATUSES = [
|
|
41861
|
+
"pending",
|
|
41862
|
+
"in_progress",
|
|
41863
|
+
"completed",
|
|
41864
|
+
"cancelled",
|
|
41865
|
+
"blocked"
|
|
41866
|
+
];
|
|
41736
41867
|
PLAN_FILES_MAX = 32;
|
|
41737
41868
|
PLAN_FILE_GLOB_MAX = 260;
|
|
41738
41869
|
PlanStoreError = class extends Error {
|
|
@@ -51016,7 +51147,7 @@ function openaiCompatibleProvider(config2) {
|
|
|
51016
51147
|
const forceRecoveryTool = generation?.toolChoice === "required" && capabilities.buildRecovery.forceToolChoice && recoveryAttempt <= capabilities.buildRecovery.maxForcedTurns;
|
|
51017
51148
|
body.tool_choice = forceRecoveryTool ? "required" : "auto";
|
|
51018
51149
|
}
|
|
51019
|
-
const
|
|
51150
|
+
const headers3 = {
|
|
51020
51151
|
"Content-Type": "application/json",
|
|
51021
51152
|
Authorization: `Bearer ${config2.apiKey}`,
|
|
51022
51153
|
...config2.extraHeaders ?? {}
|
|
@@ -51024,7 +51155,7 @@ function openaiCompatibleProvider(config2) {
|
|
|
51024
51155
|
const affinityHeader = capabilities.promptCache.conversationAffinityHeader;
|
|
51025
51156
|
const conversationId = params.conversationId?.trim();
|
|
51026
51157
|
if (affinityHeader && conversationId && conversationId.length <= 256 && !/[\u0000-\u001f\u007f]/.test(conversationId)) {
|
|
51027
|
-
|
|
51158
|
+
headers3[affinityHeader] = conversationId;
|
|
51028
51159
|
}
|
|
51029
51160
|
let response;
|
|
51030
51161
|
let lastErrText = "";
|
|
@@ -51049,7 +51180,7 @@ function openaiCompatibleProvider(config2) {
|
|
|
51049
51180
|
try {
|
|
51050
51181
|
response = await fetch(`${config2.baseUrl}/chat/completions`, {
|
|
51051
51182
|
method: "POST",
|
|
51052
|
-
headers:
|
|
51183
|
+
headers: headers3,
|
|
51053
51184
|
body: JSON.stringify(body),
|
|
51054
51185
|
// Cancel aborts the HTTP request; stream idle is enforced below
|
|
51055
51186
|
// per-chunk so active multi-minute streams are not killed.
|
|
@@ -52958,6 +53089,244 @@ var init_chatgpt = __esm({
|
|
|
52958
53089
|
}
|
|
52959
53090
|
});
|
|
52960
53091
|
|
|
53092
|
+
// src/cli/provider/responsesApi.ts
|
|
53093
|
+
function backoffDelay2(attempt, retryAfterHeader) {
|
|
53094
|
+
if (retryAfterHeader) {
|
|
53095
|
+
const seconds = Number.parseFloat(retryAfterHeader);
|
|
53096
|
+
if (Number.isFinite(seconds) && seconds >= 0) {
|
|
53097
|
+
return Math.min(seconds * 1e3, BACKOFF_CAP_MS2);
|
|
53098
|
+
}
|
|
53099
|
+
}
|
|
53100
|
+
return Math.min(BACKOFF_BASE_MS2 * 2 ** attempt, BACKOFF_CAP_MS2);
|
|
53101
|
+
}
|
|
53102
|
+
function abortableSleep2(ms, signal) {
|
|
53103
|
+
return new Promise((resolve9) => {
|
|
53104
|
+
if (signal?.aborted) return resolve9();
|
|
53105
|
+
const t = setTimeout(resolve9, ms);
|
|
53106
|
+
signal?.addEventListener(
|
|
53107
|
+
"abort",
|
|
53108
|
+
() => {
|
|
53109
|
+
clearTimeout(t);
|
|
53110
|
+
resolve9();
|
|
53111
|
+
},
|
|
53112
|
+
{ once: true }
|
|
53113
|
+
);
|
|
53114
|
+
});
|
|
53115
|
+
}
|
|
53116
|
+
function headers2(config2) {
|
|
53117
|
+
const h = {
|
|
53118
|
+
"Content-Type": "application/json",
|
|
53119
|
+
Accept: "text/event-stream",
|
|
53120
|
+
Authorization: `Bearer ${config2.apiKey}`
|
|
53121
|
+
};
|
|
53122
|
+
if (config2.extraHeaders) Object.assign(h, config2.extraHeaders);
|
|
53123
|
+
return h;
|
|
53124
|
+
}
|
|
53125
|
+
function responsesApiProvider(config2) {
|
|
53126
|
+
return async function* (params) {
|
|
53127
|
+
const capabilities = capabilitiesFor(params.model, config2.providerId);
|
|
53128
|
+
const { instructions, input } = toInput(params.messages);
|
|
53129
|
+
const body = {
|
|
53130
|
+
model: params.model,
|
|
53131
|
+
stream: true,
|
|
53132
|
+
input
|
|
53133
|
+
};
|
|
53134
|
+
if (instructions) body.instructions = instructions;
|
|
53135
|
+
if (params.tools && params.tools.length > 0) {
|
|
53136
|
+
body.tools = params.tools.map((t) => ({
|
|
53137
|
+
type: "function",
|
|
53138
|
+
name: t.name,
|
|
53139
|
+
description: t.description,
|
|
53140
|
+
parameters: t.parameters
|
|
53141
|
+
}));
|
|
53142
|
+
}
|
|
53143
|
+
const generation = params.generation;
|
|
53144
|
+
body.temperature = generation?.temperature ?? capabilities.sampling.temperature;
|
|
53145
|
+
const maxTokens = generation?.maxTokens ?? capabilities.maxOutputTokens;
|
|
53146
|
+
if (typeof maxTokens === "number" && maxTokens > 0) {
|
|
53147
|
+
body.max_output_tokens = maxTokens;
|
|
53148
|
+
}
|
|
53149
|
+
const thinkingSpec = config2.thinking ?? "auto";
|
|
53150
|
+
if (thinkingSpec !== "auto") {
|
|
53151
|
+
const t = translateResponsesThinking(thinkingSpec, config2.model, config2.providerId);
|
|
53152
|
+
if (t.degraded) {
|
|
53153
|
+
console.warn(`[thinking] ${t.note ?? "unsupported"} \u2014 falling back to provider default.`);
|
|
53154
|
+
} else {
|
|
53155
|
+
Object.assign(body, t.patch);
|
|
53156
|
+
}
|
|
53157
|
+
}
|
|
53158
|
+
const base2 = config2.baseUrl.replace(/\/$/, "");
|
|
53159
|
+
const url2 = `${base2}/responses`;
|
|
53160
|
+
let response;
|
|
53161
|
+
let lastStatus = 0;
|
|
53162
|
+
let lastErrText = "";
|
|
53163
|
+
for (let attempt = 0; ; attempt++) {
|
|
53164
|
+
const connectController = new AbortController();
|
|
53165
|
+
const connectTimer = setTimeout(
|
|
53166
|
+
() => connectController.abort(
|
|
53167
|
+
new Error(
|
|
53168
|
+
`Provider connect timeout after ${Math.round(PROVIDER_CONNECT_TIMEOUT_MS / 1e3)}s (no response headers). Override ZELARI_PROVIDER_CONNECT_TIMEOUT_MS.`
|
|
53169
|
+
)
|
|
53170
|
+
),
|
|
53171
|
+
PROVIDER_CONNECT_TIMEOUT_MS
|
|
53172
|
+
);
|
|
53173
|
+
const signals = [connectController.signal];
|
|
53174
|
+
if (params.signal) signals.push(params.signal);
|
|
53175
|
+
try {
|
|
53176
|
+
response = await fetch(url2, {
|
|
53177
|
+
method: "POST",
|
|
53178
|
+
headers: headers2(config2),
|
|
53179
|
+
body: JSON.stringify(body),
|
|
53180
|
+
signal: signals.length === 1 ? signals[0] : AbortSignal.any(signals)
|
|
53181
|
+
});
|
|
53182
|
+
} catch (err) {
|
|
53183
|
+
lastStatus = 0;
|
|
53184
|
+
lastErrText = err instanceof Error ? err.message : String(err);
|
|
53185
|
+
if (params.signal?.aborted) {
|
|
53186
|
+
yield { kind: "error", message: "aborted" };
|
|
53187
|
+
return;
|
|
53188
|
+
}
|
|
53189
|
+
if (attempt < MAX_RETRIES2) {
|
|
53190
|
+
await abortableSleep2(backoffDelay2(attempt, null), params.signal);
|
|
53191
|
+
continue;
|
|
53192
|
+
}
|
|
53193
|
+
yield { kind: "error", message: `Network error: ${lastErrText}` };
|
|
53194
|
+
return;
|
|
53195
|
+
} finally {
|
|
53196
|
+
clearTimeout(connectTimer);
|
|
53197
|
+
}
|
|
53198
|
+
if (response.ok && response.body) break;
|
|
53199
|
+
lastStatus = response.status;
|
|
53200
|
+
lastErrText = await response.text().catch(() => "");
|
|
53201
|
+
if (!RETRYABLE_STATUSES2.has(response.status) || attempt >= MAX_RETRIES2) break;
|
|
53202
|
+
await abortableSleep2(backoffDelay2(attempt, response.headers.get("retry-after")), params.signal);
|
|
53203
|
+
if (params.signal?.aborted) {
|
|
53204
|
+
yield { kind: "error", message: "aborted" };
|
|
53205
|
+
return;
|
|
53206
|
+
}
|
|
53207
|
+
}
|
|
53208
|
+
if (!response || !response.ok || !response.body) {
|
|
53209
|
+
const msg = lastStatus === 0 ? `Network error: ${lastErrText}` : `HTTP ${lastStatus}: ${lastErrText.slice(0, 240)}`;
|
|
53210
|
+
yield { kind: "error", message: msg };
|
|
53211
|
+
return;
|
|
53212
|
+
}
|
|
53213
|
+
const reader = response.body.getReader();
|
|
53214
|
+
const decoder = new TextDecoder();
|
|
53215
|
+
let buffer = "";
|
|
53216
|
+
const tools = /* @__PURE__ */ new Map();
|
|
53217
|
+
let emittedTool = false;
|
|
53218
|
+
const flush = function* (id3) {
|
|
53219
|
+
const t = tools.get(id3);
|
|
53220
|
+
if (!t?.name) return;
|
|
53221
|
+
let args = {};
|
|
53222
|
+
try {
|
|
53223
|
+
args = JSON.parse(t.argsJson || "{}");
|
|
53224
|
+
} catch {
|
|
53225
|
+
args = {};
|
|
53226
|
+
}
|
|
53227
|
+
tools.delete(id3);
|
|
53228
|
+
emittedTool = true;
|
|
53229
|
+
yield { kind: "tool_call", toolCallId: t.id, toolName: t.name, args };
|
|
53230
|
+
};
|
|
53231
|
+
const streamStartedAt = Date.now();
|
|
53232
|
+
let lastUsefulAt = streamStartedAt;
|
|
53233
|
+
const streamDeadline = streamStartedAt + PROVIDER_STREAM_MAX_MS;
|
|
53234
|
+
try {
|
|
53235
|
+
while (true) {
|
|
53236
|
+
const { value, done } = await readChunkWithTimeout(reader, {
|
|
53237
|
+
idleMs: PROVIDER_STREAM_IDLE_MS,
|
|
53238
|
+
deadlineMs: streamDeadline,
|
|
53239
|
+
signal: params.signal,
|
|
53240
|
+
lastUsefulAt: () => lastUsefulAt
|
|
53241
|
+
});
|
|
53242
|
+
if (done) break;
|
|
53243
|
+
buffer += decoder.decode(value, { stream: true });
|
|
53244
|
+
const lines = buffer.split("\n");
|
|
53245
|
+
buffer = lines.pop() ?? "";
|
|
53246
|
+
for (const line of lines) {
|
|
53247
|
+
const trimmed = line.trim();
|
|
53248
|
+
if (!trimmed.startsWith("data:")) continue;
|
|
53249
|
+
const data = trimmed.slice(5).trim();
|
|
53250
|
+
if (!data || data === "[DONE]") continue;
|
|
53251
|
+
let ev;
|
|
53252
|
+
try {
|
|
53253
|
+
ev = JSON.parse(data);
|
|
53254
|
+
} catch {
|
|
53255
|
+
continue;
|
|
53256
|
+
}
|
|
53257
|
+
const type = typeof ev.type === "string" ? ev.type : "";
|
|
53258
|
+
if (type) lastUsefulAt = Date.now();
|
|
53259
|
+
if (type === "response.output_text.delta" && typeof ev.delta === "string") {
|
|
53260
|
+
yield { kind: "text", delta: ev.delta };
|
|
53261
|
+
} else if (type === "response.reasoning_text.delta" && typeof ev.delta === "string") {
|
|
53262
|
+
yield { kind: "thinking", delta: ev.delta };
|
|
53263
|
+
} else if (type === "response.output_item.added") {
|
|
53264
|
+
const item = ev.item;
|
|
53265
|
+
if (item?.type === "function_call") {
|
|
53266
|
+
const id3 = String(item.call_id ?? item.id ?? `fc-${tools.size}`);
|
|
53267
|
+
tools.set(id3, {
|
|
53268
|
+
id: id3,
|
|
53269
|
+
name: typeof item.name === "string" ? item.name : "",
|
|
53270
|
+
argsJson: typeof item.arguments === "string" ? item.arguments : ""
|
|
53271
|
+
});
|
|
53272
|
+
}
|
|
53273
|
+
} else if (type === "response.function_call_arguments.delta") {
|
|
53274
|
+
const itemId = String(ev.item_id ?? ev.call_id ?? "");
|
|
53275
|
+
const existing = itemId ? tools.get(itemId) : [...tools.values()].at(-1);
|
|
53276
|
+
if (existing && typeof ev.delta === "string") existing.argsJson += ev.delta;
|
|
53277
|
+
} else if (type === "response.output_item.done") {
|
|
53278
|
+
const item = ev.item;
|
|
53279
|
+
if (item?.type === "function_call") {
|
|
53280
|
+
const id3 = String(item.call_id ?? item.id ?? "");
|
|
53281
|
+
if (id3) yield* flush(id3);
|
|
53282
|
+
}
|
|
53283
|
+
} else if (type === "response.completed") {
|
|
53284
|
+
const usage = ev.response?.usage;
|
|
53285
|
+
if (usage) {
|
|
53286
|
+
yield {
|
|
53287
|
+
kind: "usage",
|
|
53288
|
+
usage: {
|
|
53289
|
+
promptTokens: usage.input_tokens ?? usage.prompt_tokens ?? 0,
|
|
53290
|
+
completionTokens: usage.output_tokens ?? usage.completion_tokens ?? 0,
|
|
53291
|
+
totalTokens: usage.total_tokens ?? (usage.input_tokens ?? 0) + (usage.output_tokens ?? 0)
|
|
53292
|
+
}
|
|
53293
|
+
};
|
|
53294
|
+
}
|
|
53295
|
+
yield { kind: "finish", reason: emittedTool ? "tool_calls" : "stop" };
|
|
53296
|
+
return;
|
|
53297
|
+
} else if (type === "response.failed" || type === "error") {
|
|
53298
|
+
const msg = typeof ev.message === "string" ? ev.message : JSON.stringify(ev.error ?? ev).slice(0, 200);
|
|
53299
|
+
yield { kind: "error", message: msg };
|
|
53300
|
+
return;
|
|
53301
|
+
}
|
|
53302
|
+
}
|
|
53303
|
+
}
|
|
53304
|
+
for (const id3 of [...tools.keys()]) yield* flush(id3);
|
|
53305
|
+
yield { kind: "finish", reason: emittedTool ? "tool_calls" : "stop" };
|
|
53306
|
+
} finally {
|
|
53307
|
+
reader.releaseLock();
|
|
53308
|
+
}
|
|
53309
|
+
};
|
|
53310
|
+
}
|
|
53311
|
+
var RETRYABLE_STATUSES2, MAX_RETRIES2, BACKOFF_BASE_MS2, BACKOFF_CAP_MS2;
|
|
53312
|
+
var init_responsesApi = __esm({
|
|
53313
|
+
"src/cli/provider/responsesApi.ts"() {
|
|
53314
|
+
"use strict";
|
|
53315
|
+
init_openai_compatible();
|
|
53316
|
+
init_chatgpt();
|
|
53317
|
+
init_thinking();
|
|
53318
|
+
init_capabilities();
|
|
53319
|
+
RETRYABLE_STATUSES2 = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
53320
|
+
MAX_RETRIES2 = (() => {
|
|
53321
|
+
const raw = process.env.ZELARI_PROVIDER_MAX_RETRIES;
|
|
53322
|
+
const n = raw ? Number.parseInt(raw, 10) : 3;
|
|
53323
|
+
return Number.isFinite(n) && n >= 0 ? n : 3;
|
|
53324
|
+
})();
|
|
53325
|
+
BACKOFF_BASE_MS2 = 500;
|
|
53326
|
+
BACKOFF_CAP_MS2 = 8e3;
|
|
53327
|
+
}
|
|
53328
|
+
});
|
|
53329
|
+
|
|
52961
53330
|
// src/cli/provider/resolveStream.ts
|
|
52962
53331
|
var resolveStream_exports = {};
|
|
52963
53332
|
__export(resolveStream_exports, {
|
|
@@ -52966,6 +53335,9 @@ __export(resolveStream_exports, {
|
|
|
52966
53335
|
function buildProviderStream(config2) {
|
|
52967
53336
|
if (config2.providerId === "anthropic") return anthropicMessagesProvider(config2);
|
|
52968
53337
|
if (config2.providerId === "chatgpt") return chatgptResponsesProvider(config2);
|
|
53338
|
+
if (getApiStyleFor(config2.providerId) === "responses") {
|
|
53339
|
+
return responsesApiProvider(config2);
|
|
53340
|
+
}
|
|
52969
53341
|
return openaiCompatibleProvider(config2);
|
|
52970
53342
|
}
|
|
52971
53343
|
var init_resolveStream = __esm({
|
|
@@ -52974,6 +53346,8 @@ var init_resolveStream = __esm({
|
|
|
52974
53346
|
init_openai_compatible();
|
|
52975
53347
|
init_anthropic();
|
|
52976
53348
|
init_chatgpt();
|
|
53349
|
+
init_responsesApi();
|
|
53350
|
+
init_providerConfig();
|
|
52977
53351
|
}
|
|
52978
53352
|
});
|
|
52979
53353
|
|
|
@@ -56744,6 +57118,7 @@ function parseHeadlessFlags(argv) {
|
|
|
56744
57118
|
let once = false;
|
|
56745
57119
|
let profile;
|
|
56746
57120
|
let resumeSessionId;
|
|
57121
|
+
let resumeMission = false;
|
|
56747
57122
|
let exportSessionPath;
|
|
56748
57123
|
let strictDone;
|
|
56749
57124
|
let missionStrict;
|
|
@@ -56890,6 +57265,8 @@ function parseHeadlessFlags(argv) {
|
|
|
56890
57265
|
}
|
|
56891
57266
|
profile = next;
|
|
56892
57267
|
i++;
|
|
57268
|
+
} else if (arg === "--resume-mission") {
|
|
57269
|
+
resumeMission = true;
|
|
56893
57270
|
} else if (arg === "--resume") {
|
|
56894
57271
|
const next = argv[i + 1];
|
|
56895
57272
|
if (!next || next.startsWith("--")) {
|
|
@@ -56963,6 +57340,7 @@ function parseHeadlessFlags(argv) {
|
|
|
56963
57340
|
...history2 && history2.length > 0 ? { history: history2 } : {},
|
|
56964
57341
|
...todos2 && todos2.length > 0 ? { todos: todos2 } : {},
|
|
56965
57342
|
...once ? { once: true } : {},
|
|
57343
|
+
...resumeMission ? { resumeMission: true } : {},
|
|
56966
57344
|
...profile ? { profile } : {},
|
|
56967
57345
|
...resumeSessionId ? { resumeSessionId } : {},
|
|
56968
57346
|
...exportSessionPath ? { exportSessionPath } : {},
|
|
@@ -60440,11 +60818,11 @@ var init_httpTransport = __esm({
|
|
|
60440
60818
|
const sid = this.sessionId;
|
|
60441
60819
|
this.sessionId = null;
|
|
60442
60820
|
if (!sid) return;
|
|
60443
|
-
const
|
|
60821
|
+
const headers3 = {
|
|
60444
60822
|
...this.opts.headers ?? {},
|
|
60445
60823
|
"mcp-session-id": sid
|
|
60446
60824
|
};
|
|
60447
|
-
void fetch(this.opts.url, { method: "DELETE", headers:
|
|
60825
|
+
void fetch(this.opts.url, { method: "DELETE", headers: headers3 }).catch(() => {
|
|
60448
60826
|
});
|
|
60449
60827
|
}
|
|
60450
60828
|
// ── internals ────────────────────────────────────────────────────────
|
|
@@ -60454,15 +60832,15 @@ var init_httpTransport = __esm({
|
|
|
60454
60832
|
const timer = setTimeout(() => ac.abort(), timeoutMs2 + ABORT_GRACE_MS);
|
|
60455
60833
|
const hadSession = this.sessionId !== null;
|
|
60456
60834
|
try {
|
|
60457
|
-
const
|
|
60835
|
+
const headers3 = {
|
|
60458
60836
|
"content-type": "application/json",
|
|
60459
60837
|
accept: "application/json, text/event-stream",
|
|
60460
60838
|
...this.opts.headers ?? {}
|
|
60461
60839
|
};
|
|
60462
|
-
if (this.sessionId)
|
|
60840
|
+
if (this.sessionId) headers3["mcp-session-id"] = this.sessionId;
|
|
60463
60841
|
const res = await fetch(this.opts.url, {
|
|
60464
60842
|
method: "POST",
|
|
60465
|
-
headers:
|
|
60843
|
+
headers: headers3,
|
|
60466
60844
|
signal: ac.signal,
|
|
60467
60845
|
body: JSON.stringify({ jsonrpc: "2.0", ...msg })
|
|
60468
60846
|
});
|
|
@@ -62937,14 +63315,19 @@ var init_traceStore = __esm({
|
|
|
62937
63315
|
// src/cli/zelariMission.ts
|
|
62938
63316
|
var zelariMission_exports = {};
|
|
62939
63317
|
__export(zelariMission_exports, {
|
|
63318
|
+
MissionResumeError: () => MissionResumeError,
|
|
62940
63319
|
formatBriefForChat: () => formatBriefForChat,
|
|
62941
63320
|
isMissionAutoStart: () => isMissionAutoStart,
|
|
63321
|
+
isResumableMission: () => isResumableMission,
|
|
63322
|
+
loadMissionState: () => loadMissionState,
|
|
62942
63323
|
missionGapKey: () => missionGapKey,
|
|
62943
63324
|
missionPressure: () => missionPressure,
|
|
62944
63325
|
resolveMaxCost: () => resolveMaxCost,
|
|
62945
63326
|
resolveMaxIterations: () => resolveMaxIterations,
|
|
62946
63327
|
resolveMaxStall: () => resolveMaxStall,
|
|
62947
63328
|
resolveMaxTokens: () => resolveMaxTokens,
|
|
63329
|
+
resolveMissionSlices: () => resolveMissionSlices,
|
|
63330
|
+
resumeZelariMission: () => resumeZelariMission,
|
|
62948
63331
|
runZelariMission: () => runZelariMission
|
|
62949
63332
|
});
|
|
62950
63333
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
@@ -63006,16 +63389,42 @@ async function writeMissionState(projectRoot, state3) {
|
|
|
63006
63389
|
}
|
|
63007
63390
|
}
|
|
63008
63391
|
}
|
|
63009
|
-
function
|
|
63392
|
+
async function loadMissionState(projectRoot) {
|
|
63393
|
+
try {
|
|
63394
|
+
const raw = await fs33.readFile(
|
|
63395
|
+
path76.join(projectRoot, ".zelari", "mission-state.json"),
|
|
63396
|
+
"utf8"
|
|
63397
|
+
);
|
|
63398
|
+
const parsed = JSON.parse(raw);
|
|
63399
|
+
if (!parsed || typeof parsed.missionId !== "string" || !parsed.brief) return void 0;
|
|
63400
|
+
return parsed;
|
|
63401
|
+
} catch {
|
|
63402
|
+
return void 0;
|
|
63403
|
+
}
|
|
63404
|
+
}
|
|
63405
|
+
function isResumableMission(state3) {
|
|
63406
|
+
return !!state3 && state3.status !== "success";
|
|
63407
|
+
}
|
|
63408
|
+
function resolveMissionSlices(brief) {
|
|
63409
|
+
const slices = Array.isArray(brief.slices) ? brief.slices.filter((s) => s && !!s.id) : [];
|
|
63410
|
+
return slices.length ? slices : [brief.sliceMvp];
|
|
63411
|
+
}
|
|
63412
|
+
function countImplementationSlices(state3) {
|
|
63413
|
+
return Array.isArray(state3.trace) ? state3.trace.filter((t) => t?.runMode === "implementation").length : 0;
|
|
63414
|
+
}
|
|
63415
|
+
function buildSlicePrompt(brief, userMessage, runMode, iteration, slice) {
|
|
63010
63416
|
if (runMode === "design-phase") {
|
|
63011
63417
|
return `${userMessage}
|
|
63012
63418
|
|
|
63013
|
-
[Zelari mission] Produce the design-phase plan for the MVP: ${brief.deliverableThisMission}. Keep the first slice to at most ${
|
|
63419
|
+
[Zelari mission] Produce the design-phase plan for the MVP: ${brief.deliverableThisMission}. Keep the first slice to at most ${slice.maxTasks ?? 8} tasks.`;
|
|
63014
63420
|
}
|
|
63015
63421
|
const fix = iteration > 1 ? " Address any remaining verification failures recorded in .zelari/completion.json." : "";
|
|
63422
|
+
const isMvpSlice = slice.id === resolveMissionSlices(brief)[0].id;
|
|
63423
|
+
const target = isMvpSlice ? "the MVP slice" : `increment "${slice.title}"`;
|
|
63424
|
+
const scope = slice.taskIds?.length ? ` Scope: plan tasks ${slice.taskIds.join(", ")}.` : "";
|
|
63016
63425
|
return `${userMessage}
|
|
63017
63426
|
|
|
63018
|
-
[Zelari mission] Implement
|
|
63427
|
+
[Zelari mission] Implement ${target}: ${brief.deliverableThisMission}.${scope}${fix} You MUST create or modify the real project files with write_file / edit \u2014 not just describe them in prose. A run that claims completion without writing any file is a failed run and will not be accepted.`;
|
|
63019
63428
|
}
|
|
63020
63429
|
function formatBriefForChat(brief) {
|
|
63021
63430
|
const lines = [
|
|
@@ -63035,34 +63444,74 @@ function formatBriefForChat(brief) {
|
|
|
63035
63444
|
lines.push(" out of scope:");
|
|
63036
63445
|
for (const o of brief.outOfScope) lines.push(` - ${o}`);
|
|
63037
63446
|
}
|
|
63447
|
+
const slices = resolveMissionSlices(brief);
|
|
63038
63448
|
lines.push(` MVP slice: ${brief.sliceMvp.title} (\u2264 ${brief.sliceMvp.maxTasks} tasks)`);
|
|
63449
|
+
if (slices.length > 1) {
|
|
63450
|
+
lines.push(` increments: ${slices.length} (gated: slice N+1 starts only when N is green)`);
|
|
63451
|
+
for (const s of slices.slice(1)) lines.push(` - ${s.id}: ${s.title}`);
|
|
63452
|
+
}
|
|
63039
63453
|
return lines.join("\n");
|
|
63040
63454
|
}
|
|
63041
63455
|
async function runZelariMission(userMessage, brief, deps) {
|
|
63042
63456
|
const now = deps.now ?? (() => /* @__PURE__ */ new Date());
|
|
63043
|
-
const maxIter = deps.maxIterations ?? resolveMaxIterations(deps.env);
|
|
63044
|
-
const maxStall = resolveMaxStall(deps.env);
|
|
63045
|
-
const maxCost = resolveMaxCost(deps.env);
|
|
63046
|
-
const maxTokens = resolveMaxTokens(deps.env);
|
|
63047
|
-
const missionId = deps.missionId ?? `m_${randomUUID8().slice(0, 8)}`;
|
|
63048
63457
|
const startedAt = now().toISOString();
|
|
63049
63458
|
const state3 = {
|
|
63050
|
-
missionId,
|
|
63459
|
+
missionId: deps.missionId ?? `m_${randomUUID8().slice(0, 8)}`,
|
|
63051
63460
|
userPrompt: userMessage,
|
|
63052
63461
|
brief,
|
|
63053
63462
|
iteration: 0,
|
|
63054
|
-
currentSliceId: brief.
|
|
63463
|
+
currentSliceId: resolveMissionSlices(brief)[0].id,
|
|
63055
63464
|
status: "running",
|
|
63056
63465
|
lastCompletionOk: false,
|
|
63057
63466
|
startedAt,
|
|
63058
63467
|
updatedAt: startedAt
|
|
63059
63468
|
};
|
|
63469
|
+
return driveMission(userMessage, brief, deps, state3, false);
|
|
63470
|
+
}
|
|
63471
|
+
async function resumeZelariMission(deps) {
|
|
63472
|
+
const loaded = await loadMissionState(deps.projectRoot);
|
|
63473
|
+
if (!loaded) {
|
|
63474
|
+
throw new MissionResumeError(
|
|
63475
|
+
"nessuna missione da riprendere: .zelari/mission-state.json assente o illeggibile."
|
|
63476
|
+
);
|
|
63477
|
+
}
|
|
63478
|
+
if (!isResumableMission(loaded)) {
|
|
63479
|
+
throw new MissionResumeError(
|
|
63480
|
+
`la missione ${loaded.missionId} \xE8 gi\xE0 completata (status=success).`
|
|
63481
|
+
);
|
|
63482
|
+
}
|
|
63483
|
+
const brief = loaded.brief;
|
|
63484
|
+
const userMessage = loaded.userPrompt ?? brief.userPromptOriginal;
|
|
63485
|
+
deps.emit(
|
|
63486
|
+
`[zelari] resume missione ${loaded.missionId} \u2014 step ${loaded.iteration}, slice ${loaded.currentSliceId}, status precedente ${loaded.status}`
|
|
63487
|
+
);
|
|
63488
|
+
return driveMission(userMessage, brief, deps, loaded, true);
|
|
63489
|
+
}
|
|
63490
|
+
async function driveMission(userMessage, brief, deps, state3, resumed) {
|
|
63491
|
+
const now = deps.now ?? (() => /* @__PURE__ */ new Date());
|
|
63492
|
+
const maxIter = deps.maxIterations ?? resolveMaxIterations(deps.env);
|
|
63493
|
+
const maxStall = resolveMaxStall(deps.env);
|
|
63494
|
+
const maxCost = resolveMaxCost(deps.env);
|
|
63495
|
+
const maxTokens = resolveMaxTokens(deps.env);
|
|
63496
|
+
const missionId = state3.missionId;
|
|
63497
|
+
const slices = resolveMissionSlices(brief);
|
|
63498
|
+
let sliceIndex = resumed ? Math.max(
|
|
63499
|
+
0,
|
|
63500
|
+
slices.findIndex((s) => s.id === state3.currentSliceId)
|
|
63501
|
+
) : 0;
|
|
63502
|
+
const currentSlice = () => slices[sliceIndex] ?? slices[0];
|
|
63503
|
+
state3.currentSliceId = currentSlice().id;
|
|
63504
|
+
state3.status = "running";
|
|
63505
|
+
state3.updatedAt = now().toISOString();
|
|
63060
63506
|
await deps.memory.init(deps.projectRoot);
|
|
63061
63507
|
const persist = async () => {
|
|
63062
63508
|
await writeMissionState(deps.projectRoot, state3);
|
|
63063
63509
|
await deps.onStatePersisted?.(state3);
|
|
63064
63510
|
};
|
|
63065
|
-
deps.onMissionPhase?.(
|
|
63511
|
+
deps.onMissionPhase?.(
|
|
63512
|
+
resumed ? "build" : "design",
|
|
63513
|
+
resumed ? "mission-resume" : "mission-start"
|
|
63514
|
+
);
|
|
63066
63515
|
await persist();
|
|
63067
63516
|
const stateStore = deps.stateStore ?? await getStateStore(deps.projectRoot, deps.env ?? process.env);
|
|
63068
63517
|
try {
|
|
@@ -63070,7 +63519,7 @@ async function runZelariMission(userMessage, brief, deps) {
|
|
|
63070
63519
|
} catch {
|
|
63071
63520
|
}
|
|
63072
63521
|
let missionCheckpointId;
|
|
63073
|
-
if ((deps.env ?? process.env).ZELARI_CHECKPOINT !== "0") {
|
|
63522
|
+
if (!resumed && (deps.env ?? process.env).ZELARI_CHECKPOINT !== "0") {
|
|
63074
63523
|
const cp = await createCheckpoint(deps.projectRoot, `zelari mission ${missionId}`);
|
|
63075
63524
|
if (cp.ok) {
|
|
63076
63525
|
missionCheckpointId = cp.value.id;
|
|
@@ -63081,11 +63530,11 @@ async function runZelariMission(userMessage, brief, deps) {
|
|
|
63081
63530
|
}
|
|
63082
63531
|
const designFirst = brief.phases[0]?.mode === "design-phase";
|
|
63083
63532
|
let noWriteStreak = 0;
|
|
63084
|
-
let step = 0;
|
|
63085
|
-
let implStep = 0;
|
|
63086
|
-
let pendingDesign = designFirst;
|
|
63087
|
-
let cumulativeCostUsd = 0;
|
|
63088
|
-
let cumulativeTokens = 0;
|
|
63533
|
+
let step = resumed ? state3.iteration : 0;
|
|
63534
|
+
let implStep = resumed ? countImplementationSlices(state3) : 0;
|
|
63535
|
+
let pendingDesign = designFirst && !resumed;
|
|
63536
|
+
let cumulativeCostUsd = resumed ? state3.cumulativeCostUsd ?? 0 : 0;
|
|
63537
|
+
let cumulativeTokens = resumed ? state3.cumulativeTokens ?? 0 : 0;
|
|
63089
63538
|
const repairHistory = Array.isArray(state3.repairHistory) ? [...state3.repairHistory] : [];
|
|
63090
63539
|
let forcePivot = false;
|
|
63091
63540
|
const missionStartMs = now().getTime();
|
|
@@ -63113,25 +63562,25 @@ async function runZelariMission(userMessage, brief, deps) {
|
|
|
63113
63562
|
});
|
|
63114
63563
|
const ragContext = formatMemoryHits(hits);
|
|
63115
63564
|
const promptIter = runMode === "implementation" ? implStep : 1;
|
|
63116
|
-
const slicePrompt = buildSlicePrompt(brief, userMessage, runMode, promptIter);
|
|
63565
|
+
const slicePrompt = buildSlicePrompt(brief, userMessage, runMode, promptIter, currentSlice());
|
|
63117
63566
|
const implementerRetry = runMode === "implementation" && (implStep > 1 || forcePivot);
|
|
63118
63567
|
const sliceStartedAt = now().toISOString();
|
|
63119
63568
|
const sliceStartMs = now().getTime();
|
|
63120
63569
|
if (runMode === "design-phase") {
|
|
63121
63570
|
deps.emit(
|
|
63122
|
-
`[zelari] design-phase (fuori budget) \xB7 step ${step} \xB7 slice ${
|
|
63571
|
+
`[zelari] design-phase (fuori budget) \xB7 step ${step} \xB7 slice ${currentSlice().id}`
|
|
63123
63572
|
);
|
|
63124
63573
|
} else if (deps.buildViaAgent) {
|
|
63125
63574
|
deps.emit(
|
|
63126
|
-
`[zelari] implementazione ${implStep}/${maxIter} \xB7 step ${step} \xB7 build@agent \xB7 slice ${
|
|
63575
|
+
`[zelari] implementazione ${implStep}/${maxIter} \xB7 step ${step} \xB7 build@agent \xB7 slice ${currentSlice().id}`
|
|
63127
63576
|
);
|
|
63128
63577
|
} else if (implementerRetry) {
|
|
63129
63578
|
deps.emit(
|
|
63130
|
-
`[zelari] implementazione ${implStep}/${maxIter} \xB7 step ${step} \xB7 roster ridotto (Minosse+Lucifero) \xB7 slice ${
|
|
63579
|
+
`[zelari] implementazione ${implStep}/${maxIter} \xB7 step ${step} \xB7 roster ridotto (Minosse+Lucifero) \xB7 slice ${currentSlice().id}`
|
|
63131
63580
|
);
|
|
63132
63581
|
} else {
|
|
63133
63582
|
deps.emit(
|
|
63134
|
-
`[zelari] implementazione ${implStep}/${maxIter} \xB7 step ${step} \xB7 council completo \xB7 slice ${
|
|
63583
|
+
`[zelari] implementazione ${implStep}/${maxIter} \xB7 step ${step} \xB7 council completo \xB7 slice ${currentSlice().id}`
|
|
63135
63584
|
);
|
|
63136
63585
|
}
|
|
63137
63586
|
let result;
|
|
@@ -63173,7 +63622,7 @@ async function runZelariMission(userMessage, brief, deps) {
|
|
|
63173
63622
|
{
|
|
63174
63623
|
projectRoot: deps.projectRoot,
|
|
63175
63624
|
missionId,
|
|
63176
|
-
sliceId:
|
|
63625
|
+
sliceId: currentSlice().id,
|
|
63177
63626
|
source: "council",
|
|
63178
63627
|
iteration: step,
|
|
63179
63628
|
memoryKind: result.completionOk ? "outcome" : runMode === "design-phase" ? "decision" : "episode",
|
|
@@ -63197,7 +63646,7 @@ async function runZelariMission(userMessage, brief, deps) {
|
|
|
63197
63646
|
state3.cumulativeTokens = cumulativeTokens;
|
|
63198
63647
|
if (!state3.trace) state3.trace = [];
|
|
63199
63648
|
state3.trace.push({
|
|
63200
|
-
sliceId:
|
|
63649
|
+
sliceId: currentSlice().id,
|
|
63201
63650
|
iteration: step,
|
|
63202
63651
|
runMode,
|
|
63203
63652
|
completionOk,
|
|
@@ -63222,7 +63671,7 @@ async function runZelariMission(userMessage, brief, deps) {
|
|
|
63222
63671
|
env: deps.env,
|
|
63223
63672
|
mode: "zelari",
|
|
63224
63673
|
layer: hard ? `mission:impl-${implStep}` : `mission:progress-${implStep}`,
|
|
63225
|
-
label: hard ? `zelari ${
|
|
63674
|
+
label: hard ? `zelari ${currentSlice().id} impl ${implStep} verified` : `zelari ${currentSlice().id} progress impl ${implStep}`,
|
|
63226
63675
|
sessionId: missionId,
|
|
63227
63676
|
verification: { ok: hard, ran: result.ran },
|
|
63228
63677
|
force: !hard,
|
|
@@ -63261,12 +63710,24 @@ async function runZelariMission(userMessage, brief, deps) {
|
|
|
63261
63710
|
budget: { iterationsUsed: implStep, iterationsMax: maxIter }
|
|
63262
63711
|
});
|
|
63263
63712
|
deps.onMissionProgress?.(advice, step);
|
|
63713
|
+
if (completionOk && sliceIndex < slices.length - 1) {
|
|
63714
|
+
const doneSlice = currentSlice();
|
|
63715
|
+
sliceIndex += 1;
|
|
63716
|
+
state3.currentSliceId = currentSlice().id;
|
|
63717
|
+
state3.updatedAt = now().toISOString();
|
|
63718
|
+
await persist();
|
|
63719
|
+
deps.emit(
|
|
63720
|
+
`[zelari] \u2713 incremento ${sliceIndex}/${slices.length} verde (${doneSlice.id}) \u2014 avvio ${currentSlice().id}`
|
|
63721
|
+
);
|
|
63722
|
+
continue;
|
|
63723
|
+
}
|
|
63264
63724
|
if (completionOk) {
|
|
63265
63725
|
state3.status = "success";
|
|
63266
63726
|
deps.onMissionPhase?.("done", "mvp-green");
|
|
63267
63727
|
await persist();
|
|
63728
|
+
const sliceLabel = slices.length === 1 ? "slice MVP" : `ultimo incremento (${currentSlice().id})`;
|
|
63268
63729
|
deps.emit(
|
|
63269
|
-
`[zelari] \u2713 missione completata \u2014
|
|
63730
|
+
`[zelari] \u2713 missione completata \u2014 ${sliceLabel} verde all'implementazione ${implStep}/${maxIter} (step ${step}).`
|
|
63270
63731
|
);
|
|
63271
63732
|
return state3;
|
|
63272
63733
|
}
|
|
@@ -63344,7 +63805,7 @@ async function runZelariMission(userMessage, brief, deps) {
|
|
|
63344
63805
|
);
|
|
63345
63806
|
return state3;
|
|
63346
63807
|
}
|
|
63347
|
-
var DEFAULT_MAX_ITER, DEFAULT_MAX_STALL;
|
|
63808
|
+
var DEFAULT_MAX_ITER, DEFAULT_MAX_STALL, MissionResumeError;
|
|
63348
63809
|
var init_zelariMission = __esm({
|
|
63349
63810
|
"src/cli/zelariMission.ts"() {
|
|
63350
63811
|
"use strict";
|
|
@@ -63357,6 +63818,12 @@ var init_zelariMission = __esm({
|
|
|
63357
63818
|
init_traceStore();
|
|
63358
63819
|
DEFAULT_MAX_ITER = 6;
|
|
63359
63820
|
DEFAULT_MAX_STALL = 2;
|
|
63821
|
+
MissionResumeError = class extends Error {
|
|
63822
|
+
constructor(message) {
|
|
63823
|
+
super(message);
|
|
63824
|
+
this.name = "MissionResumeError";
|
|
63825
|
+
}
|
|
63826
|
+
};
|
|
63360
63827
|
}
|
|
63361
63828
|
});
|
|
63362
63829
|
|
|
@@ -65494,6 +65961,16 @@ function handleProviderPicker(ctx, openPicker) {
|
|
|
65494
65961
|
function handleProviderCustom(ctx, opts) {
|
|
65495
65962
|
const id3 = ctx.activeProviderSpec.id;
|
|
65496
65963
|
try {
|
|
65964
|
+
if (opts.apiStyle) {
|
|
65965
|
+
if (id3 === "chatgpt" || id3 === "anthropic") {
|
|
65966
|
+
appendSystem(ctx.setMessages, `[provider] ${id3} has a fixed transport \u2014 nothing to select.`);
|
|
65967
|
+
return;
|
|
65968
|
+
}
|
|
65969
|
+
setApiStyleFor(id3, opts.apiStyle);
|
|
65970
|
+
const target = opts.apiStyle === "responses" ? "POST /responses" : "POST /chat/completions";
|
|
65971
|
+
appendSystem(ctx.setMessages, `[provider] ${id3} endpoint style set to ${opts.apiStyle} (${target})`);
|
|
65972
|
+
return;
|
|
65973
|
+
}
|
|
65497
65974
|
if (opts.clear) {
|
|
65498
65975
|
clearCustomEndpoint(id3);
|
|
65499
65976
|
appendSystem(ctx.setMessages, `[provider] cleared custom endpoint for ${id3} \u2014 falling back to default`);
|
|
@@ -68804,6 +69281,76 @@ var init_run = __esm({
|
|
|
68804
69281
|
}
|
|
68805
69282
|
});
|
|
68806
69283
|
|
|
69284
|
+
// src/cli/evolution/runTelemetry.ts
|
|
69285
|
+
var runTelemetry_exports = {};
|
|
69286
|
+
__export(runTelemetry_exports, {
|
|
69287
|
+
RunTelemetryAccumulator: () => RunTelemetryAccumulator
|
|
69288
|
+
});
|
|
69289
|
+
var RunTelemetryAccumulator;
|
|
69290
|
+
var init_runTelemetry = __esm({
|
|
69291
|
+
"src/cli/evolution/runTelemetry.ts"() {
|
|
69292
|
+
"use strict";
|
|
69293
|
+
RunTelemetryAccumulator = class {
|
|
69294
|
+
constructor(meta3 = {}) {
|
|
69295
|
+
this.meta = meta3;
|
|
69296
|
+
}
|
|
69297
|
+
totals = {
|
|
69298
|
+
inputTokens: 0,
|
|
69299
|
+
outputTokens: 0,
|
|
69300
|
+
cacheHitTokens: 0,
|
|
69301
|
+
toolCalls: 0,
|
|
69302
|
+
usageReports: 0
|
|
69303
|
+
};
|
|
69304
|
+
/** Mirror one dispatch/spine event. Never throws on unknown shapes. */
|
|
69305
|
+
observe(ev) {
|
|
69306
|
+
if (!ev || typeof ev !== "object" || !("type" in ev)) return;
|
|
69307
|
+
const e = ev;
|
|
69308
|
+
if (e["type"] === "tool_execution_end") {
|
|
69309
|
+
this.totals.toolCalls += 1;
|
|
69310
|
+
return;
|
|
69311
|
+
}
|
|
69312
|
+
if (e["type"] !== "message_end") return;
|
|
69313
|
+
const usage = e["usage"];
|
|
69314
|
+
if (!usage || typeof usage !== "object") return;
|
|
69315
|
+
const u = usage;
|
|
69316
|
+
if (typeof u["promptTokens"] === "number") this.totals.inputTokens += u["promptTokens"];
|
|
69317
|
+
if (typeof u["completionTokens"] === "number") this.totals.outputTokens += u["completionTokens"];
|
|
69318
|
+
if (typeof u["cachedPromptTokens"] === "number") this.totals.cacheHitTokens += u["cachedPromptTokens"];
|
|
69319
|
+
this.totals.usageReports += 1;
|
|
69320
|
+
}
|
|
69321
|
+
/** Cumulative totals (defensive copy). */
|
|
69322
|
+
usage() {
|
|
69323
|
+
return { ...this.totals };
|
|
69324
|
+
}
|
|
69325
|
+
/**
|
|
69326
|
+
* Final NDJSON `usage` event for JSON hosts (Desktop, competitive bench,
|
|
69327
|
+
* anchor runner). Emitted once per run, after the dispatch stream ends —
|
|
69328
|
+
* `tools/eval/competitive/adapters.ts#parseZelariUsage` reads exactly this
|
|
69329
|
+
* flat `{ inputTokens, outputTokens, cacheHitTokens, model?, provider? }`
|
|
69330
|
+
* shape, so the bench stops recording `tokens: null` with no bench change.
|
|
69331
|
+
*/
|
|
69332
|
+
usageEvent() {
|
|
69333
|
+
return {
|
|
69334
|
+
type: "usage",
|
|
69335
|
+
...this.usage(),
|
|
69336
|
+
...this.meta.model ? { model: this.meta.model } : {},
|
|
69337
|
+
...this.meta.provider ? { provider: this.meta.provider } : {}
|
|
69338
|
+
};
|
|
69339
|
+
}
|
|
69340
|
+
/**
|
|
69341
|
+
* Ledger projection: toolCalls always (event-countable), token fields ONLY
|
|
69342
|
+
* when backed by ≥1 provider usage report (unknown ≠ estimated ≠ zero).
|
|
69343
|
+
*/
|
|
69344
|
+
ledgerFields() {
|
|
69345
|
+
return {
|
|
69346
|
+
toolCalls: this.totals.toolCalls,
|
|
69347
|
+
...this.totals.usageReports > 0 ? { inputTokens: this.totals.inputTokens, outputTokens: this.totals.outputTokens } : {}
|
|
69348
|
+
};
|
|
69349
|
+
}
|
|
69350
|
+
};
|
|
69351
|
+
}
|
|
69352
|
+
});
|
|
69353
|
+
|
|
68807
69354
|
// src/cli/triggerLock.ts
|
|
68808
69355
|
var triggerLock_exports = {};
|
|
68809
69356
|
__export(triggerLock_exports, {
|
|
@@ -69408,6 +69955,9 @@ async function runHeadlessCouncilBody(opts, provider, model, providerStream, ext
|
|
|
69408
69955
|
const scrub = createStreamScrubber2({ stripQuestion: opts.output !== "json" });
|
|
69409
69956
|
let lastAssistantText = "";
|
|
69410
69957
|
let currentAssistantText = "";
|
|
69958
|
+
const { RunTelemetryAccumulator: RunTelemetryAccumulator2 } = await Promise.resolve().then(() => (init_runTelemetry(), runTelemetry_exports));
|
|
69959
|
+
const telemetry = new RunTelemetryAccumulator2({ model, provider });
|
|
69960
|
+
const councilStartedAt = Date.now();
|
|
69411
69961
|
try {
|
|
69412
69962
|
const { composeProjectContext: composeProjectContext2 } = await Promise.resolve().then(() => (init_composeContext(), composeContext_exports));
|
|
69413
69963
|
const { loadDurableContext: loadDurableContext2 } = await Promise.resolve().then(() => (init_loadDurableContext(), loadDurableContext_exports));
|
|
@@ -69463,6 +70013,7 @@ async function runHeadlessCouncilBody(opts, provider, model, providerStream, ext
|
|
|
69463
70013
|
currentAssistantText = "";
|
|
69464
70014
|
}
|
|
69465
70015
|
spine.observe(event);
|
|
70016
|
+
telemetry.observe(event);
|
|
69466
70017
|
if (event.type === "message_delta" && typeof event.delta === "string") {
|
|
69467
70018
|
const cleanDelta = scrub.push(event.delta);
|
|
69468
70019
|
if (cleanDelta.length > 0) currentAssistantText += cleanDelta;
|
|
@@ -69490,6 +70041,9 @@ async function runHeadlessCouncilBody(opts, provider, model, providerStream, ext
|
|
|
69490
70041
|
}
|
|
69491
70042
|
}
|
|
69492
70043
|
}
|
|
70044
|
+
if (opts.output === "json") {
|
|
70045
|
+
emitEvent(telemetry.usageEvent());
|
|
70046
|
+
}
|
|
69493
70047
|
} catch (err) {
|
|
69494
70048
|
process.stderr.write(
|
|
69495
70049
|
`[zelari-code --headless] council error: ${err instanceof Error ? err.message : String(err)}
|
|
@@ -69513,6 +70067,12 @@ async function runHeadlessCouncilBody(opts, provider, model, providerStream, ext
|
|
|
69513
70067
|
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
69514
70068
|
mode: "shadow",
|
|
69515
70069
|
taskClass: classifyTask2({ prompt: effectiveTask }).taskClass,
|
|
70070
|
+
// Steal #1/#2 wiring: real efficiency + attribution fields — the
|
|
70071
|
+
// ledger schema carried them since ADR-0036, this site never wrote them.
|
|
70072
|
+
latencyMs: Date.now() - councilStartedAt,
|
|
70073
|
+
model,
|
|
70074
|
+
provider,
|
|
70075
|
+
...telemetry.ledgerFields(),
|
|
69516
70076
|
verdict: signal.aborted ? "UNKNOWN" : exitCode === 0 ? "PASS" : exitCode === 3 ? "FAIL" : "UNKNOWN"
|
|
69517
70077
|
});
|
|
69518
70078
|
}
|
|
@@ -69580,14 +70140,17 @@ async function runHeadlessZelariBody(opts, provider, model, providerStream, extr
|
|
|
69580
70140
|
spine.missionPhase("design", "mission-start");
|
|
69581
70141
|
const { buildMissionBrief: buildMissionBrief2 } = await Promise.resolve().then(() => (init_council(), council_exports));
|
|
69582
70142
|
const { hasWorkspacePlan: hasWorkspacePlan2 } = await Promise.resolve().then(() => (init_planDetect(), planDetect_exports));
|
|
70143
|
+
const { listOpenPlanTaskIds: listOpenPlanTaskIds2 } = await Promise.resolve().then(() => (init_planStore(), planStore_exports));
|
|
69583
70144
|
const { getMemoryBackend: getMemoryBackend2 } = await Promise.resolve().then(() => (init_fileBackend(), fileBackend_exports));
|
|
69584
70145
|
const { runZelariMission: runZelariMission2 } = await Promise.resolve().then(() => (init_zelariMission(), zelariMission_exports));
|
|
69585
70146
|
const { dispatchCouncil: dispatchCouncil2 } = await Promise.resolve().then(() => (init_councilDispatcher(), councilDispatcher_exports));
|
|
69586
70147
|
const { FeedbackStore: FeedbackStore2 } = await Promise.resolve().then(() => (init_councilFeedback(), councilFeedback_exports));
|
|
69587
70148
|
const { runPostCouncilHook: runPostCouncilHook2 } = await Promise.resolve().then(() => (init_postCouncilHook(), postCouncilHook_exports));
|
|
70149
|
+
const planTaskIds = await listOpenPlanTaskIds2(projectRoot);
|
|
69588
70150
|
const brief = buildMissionBrief2({
|
|
69589
70151
|
userMessage: opts.task,
|
|
69590
|
-
hasPlan: hasWorkspacePlan2(projectRoot)
|
|
70152
|
+
hasPlan: hasWorkspacePlan2(projectRoot),
|
|
70153
|
+
planTaskIds
|
|
69591
70154
|
});
|
|
69592
70155
|
const memory = await getMemoryBackend2(
|
|
69593
70156
|
projectRoot,
|
|
@@ -69672,7 +70235,9 @@ ${JSON.stringify({ deliverable: brief.deliverableThisMission, mvp: brief.sliceMv
|
|
|
69672
70235
|
}
|
|
69673
70236
|
}
|
|
69674
70237
|
try {
|
|
69675
|
-
const
|
|
70238
|
+
const { resumeZelariMission: resumeZelariMission2 } = await Promise.resolve().then(() => (init_zelariMission(), zelariMission_exports));
|
|
70239
|
+
const runMission = (missionDeps) => opts.resumeMission ? resumeZelariMission2(missionDeps) : runZelariMission2(missionTask, brief, missionDeps);
|
|
70240
|
+
const state3 = await runMission({
|
|
69676
70241
|
projectRoot,
|
|
69677
70242
|
memory,
|
|
69678
70243
|
emit,
|
|
@@ -70095,6 +70660,7 @@ function parseSetConfigFlags(argv) {
|
|
|
70095
70660
|
let model;
|
|
70096
70661
|
let endpoint;
|
|
70097
70662
|
let thinking;
|
|
70663
|
+
let apiStyle;
|
|
70098
70664
|
let endpointClear = false;
|
|
70099
70665
|
let verifierProvider;
|
|
70100
70666
|
let verifierModel;
|
|
@@ -70113,6 +70679,9 @@ function parseSetConfigFlags(argv) {
|
|
|
70113
70679
|
} else if (arg === "--thinking") {
|
|
70114
70680
|
thinking = argv[i + 1];
|
|
70115
70681
|
i++;
|
|
70682
|
+
} else if (arg === "--api-style") {
|
|
70683
|
+
apiStyle = argv[i + 1];
|
|
70684
|
+
i++;
|
|
70116
70685
|
} else if (arg === "--endpoint-clear") {
|
|
70117
70686
|
endpointClear = true;
|
|
70118
70687
|
} else if (arg === "--verifier-provider") {
|
|
@@ -70125,7 +70694,7 @@ function parseSetConfigFlags(argv) {
|
|
|
70125
70694
|
verifierClear = true;
|
|
70126
70695
|
}
|
|
70127
70696
|
}
|
|
70128
|
-
if (!provider && !model && !endpoint && !endpointClear && !thinking && !verifierProvider && !verifierModel && !verifierClear) {
|
|
70697
|
+
if (!provider && !model && !endpoint && !endpointClear && !thinking && !apiStyle && !verifierProvider && !verifierModel && !verifierClear) {
|
|
70129
70698
|
return {
|
|
70130
70699
|
request: null,
|
|
70131
70700
|
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"
|
|
@@ -70140,6 +70709,9 @@ function parseSetConfigFlags(argv) {
|
|
|
70140
70709
|
if (endpoint !== void 0 && endpoint.trim().length === 0) {
|
|
70141
70710
|
return { request: null, error: "--endpoint cannot be empty" };
|
|
70142
70711
|
}
|
|
70712
|
+
if (apiStyle !== void 0 && apiStyle !== "chat" && apiStyle !== "responses") {
|
|
70713
|
+
return { request: null, error: "invalid --api-style " + apiStyle + " (use chat or responses)" };
|
|
70714
|
+
}
|
|
70143
70715
|
if (verifierClear && (verifierProvider || verifierModel)) {
|
|
70144
70716
|
return { request: null, error: "--verifier-clear conflicts with --verifier-provider/--verifier-model" };
|
|
70145
70717
|
}
|
|
@@ -70164,6 +70736,7 @@ function parseSetConfigFlags(argv) {
|
|
|
70164
70736
|
model: model?.trim(),
|
|
70165
70737
|
endpoint: endpoint?.trim(),
|
|
70166
70738
|
endpointClear: endpointClear || void 0,
|
|
70739
|
+
apiStyle,
|
|
70167
70740
|
thinking: thinking?.trim().toLowerCase(),
|
|
70168
70741
|
verifierProvider: verifierProvider?.trim(),
|
|
70169
70742
|
verifierModel: verifierModel?.trim(),
|
|
@@ -70243,6 +70816,7 @@ function buildDesktopConfigSnapshot() {
|
|
|
70243
70816
|
models,
|
|
70244
70817
|
defaultModel,
|
|
70245
70818
|
endpoint: custom2 ?? null,
|
|
70819
|
+
apiStyle: p3.id === "anthropic" || p3.id === "chatgpt" ? void 0 : getApiStyleFor(p3.id),
|
|
70246
70820
|
baseUrl: custom2 ?? builtin,
|
|
70247
70821
|
authKind: !hasKey ? "none" : oauth ? "oauth" : "api_key",
|
|
70248
70822
|
expiresAt: stored?.expiresAt ?? null,
|
|
@@ -70289,6 +70863,9 @@ function applySetConfig(req) {
|
|
|
70289
70863
|
if (req.endpoint) {
|
|
70290
70864
|
setCustomEndpoint(targetProvider, req.endpoint);
|
|
70291
70865
|
}
|
|
70866
|
+
if (req.apiStyle) {
|
|
70867
|
+
setApiStyleFor(targetProvider, req.apiStyle);
|
|
70868
|
+
}
|
|
70292
70869
|
if (req.model) {
|
|
70293
70870
|
setModelForProvider(targetProvider, req.model);
|
|
70294
70871
|
}
|
|
@@ -79074,11 +79651,14 @@ async function dispatchZelariPromptImpl(text, deps, pendingRef) {
|
|
|
79074
79651
|
}
|
|
79075
79652
|
const { buildMissionBrief: buildMissionBrief2 } = await Promise.resolve().then(() => (init_council(), council_exports));
|
|
79076
79653
|
const { hasWorkspacePlan: hasWorkspacePlan2 } = await Promise.resolve().then(() => (init_planDetect(), planDetect_exports));
|
|
79654
|
+
const { listOpenPlanTaskIds: listOpenPlanTaskIds2 } = await Promise.resolve().then(() => (init_planStore(), planStore_exports));
|
|
79077
79655
|
const { formatBriefForChat: formatBriefForChat2, isMissionAutoStart: isMissionAutoStart2 } = await Promise.resolve().then(() => (init_zelariMission(), zelariMission_exports));
|
|
79078
79656
|
const projectRoot = process.cwd();
|
|
79657
|
+
const planTaskIds = await listOpenPlanTaskIds2(projectRoot);
|
|
79079
79658
|
const brief = buildMissionBrief2({
|
|
79080
79659
|
userMessage: text,
|
|
79081
|
-
hasPlan: hasWorkspacePlan2(projectRoot)
|
|
79660
|
+
hasPlan: hasWorkspacePlan2(projectRoot),
|
|
79661
|
+
planTaskIds
|
|
79082
79662
|
});
|
|
79083
79663
|
emit(formatBriefForChat2(brief));
|
|
79084
79664
|
if (isMissionAutoStart2()) {
|
|
@@ -79104,11 +79684,14 @@ async function runZelariMissionInTui(userMessage, deps, emit) {
|
|
|
79104
79684
|
const projectRoot = process.cwd();
|
|
79105
79685
|
const { buildMissionBrief: buildMissionBrief2 } = await Promise.resolve().then(() => (init_council(), council_exports));
|
|
79106
79686
|
const { hasWorkspacePlan: hasWorkspacePlan2 } = await Promise.resolve().then(() => (init_planDetect(), planDetect_exports));
|
|
79687
|
+
const { listOpenPlanTaskIds: listOpenPlanTaskIds2 } = await Promise.resolve().then(() => (init_planStore(), planStore_exports));
|
|
79107
79688
|
const { getMemoryBackend: getMemoryBackend2 } = await Promise.resolve().then(() => (init_fileBackend(), fileBackend_exports));
|
|
79108
79689
|
const { runZelariMission: runZelariMission2 } = await Promise.resolve().then(() => (init_zelariMission(), zelariMission_exports));
|
|
79690
|
+
const planTaskIds = await listOpenPlanTaskIds2(projectRoot);
|
|
79109
79691
|
const brief = buildMissionBrief2({
|
|
79110
79692
|
userMessage,
|
|
79111
|
-
hasPlan: hasWorkspacePlan2(projectRoot)
|
|
79693
|
+
hasPlan: hasWorkspacePlan2(projectRoot),
|
|
79694
|
+
planTaskIds
|
|
79112
79695
|
});
|
|
79113
79696
|
const missionSpineHolder = {
|
|
79114
79697
|
get current() {
|
|
@@ -79657,6 +80240,24 @@ ${formatSkillList(availableSkills)}`
|
|
|
79657
80240
|
customEndpoint: url2
|
|
79658
80241
|
};
|
|
79659
80242
|
}
|
|
80243
|
+
if (subcommand === "api") {
|
|
80244
|
+
const target = args[1];
|
|
80245
|
+
if (!target || target === "show") {
|
|
80246
|
+
return {
|
|
80247
|
+
handled: true,
|
|
80248
|
+
kind: "provider_custom",
|
|
80249
|
+
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."
|
|
80250
|
+
};
|
|
80251
|
+
}
|
|
80252
|
+
if (target !== "chat" && target !== "responses") {
|
|
80253
|
+
return {
|
|
80254
|
+
handled: true,
|
|
80255
|
+
kind: "provider_custom",
|
|
80256
|
+
message: `[provider] unknown api style: ${target}. Use: chat | responses`
|
|
80257
|
+
};
|
|
80258
|
+
}
|
|
80259
|
+
return { handled: true, kind: "provider_custom", apiStyle: target };
|
|
80260
|
+
}
|
|
79660
80261
|
const providerId = subcommand;
|
|
79661
80262
|
const sub = args[1];
|
|
79662
80263
|
if (sub === "refresh") {
|
|
@@ -81013,27 +81614,27 @@ function parseCsv(text) {
|
|
|
81013
81614
|
records.pop();
|
|
81014
81615
|
}
|
|
81015
81616
|
if (records.length === 0) return { headers: [], rows: [] };
|
|
81016
|
-
const
|
|
81617
|
+
const headers3 = records[0];
|
|
81017
81618
|
const rows = records.slice(1).map((r) => {
|
|
81018
81619
|
const obj = {};
|
|
81019
|
-
for (let i = 0; i <
|
|
81620
|
+
for (let i = 0; i < headers3.length; i++) obj[headers3[i]] = r[i] ?? "";
|
|
81020
81621
|
return obj;
|
|
81021
81622
|
});
|
|
81022
|
-
return { headers:
|
|
81623
|
+
return { headers: headers3, rows };
|
|
81023
81624
|
}
|
|
81024
81625
|
function applyTemplate(template, row) {
|
|
81025
81626
|
return template.replace(/\{([a-zA-Z_][\w-]*)\}/g, (_, k) => row[k] ?? "");
|
|
81026
81627
|
}
|
|
81027
|
-
function serializeCsv(
|
|
81628
|
+
function serializeCsv(headers3, rows) {
|
|
81028
81629
|
const escape = (v) => {
|
|
81029
81630
|
if (v.includes(",") || v.includes("\n") || v.includes('"')) {
|
|
81030
81631
|
return `"${v.replace(/"/g, '""')}"`;
|
|
81031
81632
|
}
|
|
81032
81633
|
return v;
|
|
81033
81634
|
};
|
|
81034
|
-
const out = [
|
|
81635
|
+
const out = [headers3.map(escape).join(",")];
|
|
81035
81636
|
for (const row of rows) {
|
|
81036
|
-
out.push(
|
|
81637
|
+
out.push(headers3.map((h) => escape(row[h] ?? "")).join(","));
|
|
81037
81638
|
}
|
|
81038
81639
|
return out.join("\n") + "\n";
|
|
81039
81640
|
}
|
|
@@ -81047,21 +81648,21 @@ async function runCsvFanout(args, deps, opts) {
|
|
|
81047
81648
|
const start = Date.now();
|
|
81048
81649
|
const absCsv = path80.isAbsolute(args.csv_path) ? args.csv_path : path80.join(opts.parentCwd, args.csv_path);
|
|
81049
81650
|
const absOut = path80.isAbsolute(args.output_csv_path) ? args.output_csv_path : path80.join(opts.parentCwd, args.output_csv_path);
|
|
81050
|
-
const { headers:
|
|
81051
|
-
if (
|
|
81651
|
+
const { headers: headers3, rows } = await readCsv(absCsv);
|
|
81652
|
+
if (headers3.length === 0) {
|
|
81052
81653
|
throw new Error(`kraken_csv_fanout: ${absCsv} is empty`);
|
|
81053
81654
|
}
|
|
81054
81655
|
if (!args.id_column) {
|
|
81055
81656
|
throw new Error("kraken_csv_fanout: id_column is required");
|
|
81056
81657
|
}
|
|
81057
|
-
if (!
|
|
81058
|
-
throw new Error(`kraken_csv_fanout: id_column "${args.id_column}" not in CSV header [${
|
|
81658
|
+
if (!headers3.includes(args.id_column)) {
|
|
81659
|
+
throw new Error(`kraken_csv_fanout: id_column "${args.id_column}" not in CSV header [${headers3.join(", ")}]`);
|
|
81059
81660
|
}
|
|
81060
81661
|
const concurrency = args.max_concurrency ?? resolveMaxConcurrency();
|
|
81061
81662
|
opts.onLog?.(`csv fanout: ${rows.length} rows \xD7 ${args.agent_kind} @ concurrency=${concurrency}`);
|
|
81062
81663
|
const perRowMs = args.max_runtime_seconds !== void 0 ? args.max_runtime_seconds * 1e3 : args.agent_kind === "general" ? TASK_TOOL_TIMEOUT_MS : 3e5;
|
|
81063
81664
|
const outputRecords = rows.map((r) => ({ ...r, status: "pending", result: "", error: "" }));
|
|
81064
|
-
const outHeaders = [...
|
|
81665
|
+
const outHeaders = [...headers3, "status", "result", "error"];
|
|
81065
81666
|
let writeChain2 = Promise.resolve();
|
|
81066
81667
|
function queueWrite(contents) {
|
|
81067
81668
|
const next = writeChain2.then(() => atomicWrite(absOut, contents));
|
|
@@ -82422,6 +83023,7 @@ function useSlashDispatch(params) {
|
|
|
82422
83023
|
handleProviderCustom(providerCtx, {
|
|
82423
83024
|
endpoint: result.customEndpoint,
|
|
82424
83025
|
clear: result.customClear,
|
|
83026
|
+
apiStyle: result.apiStyle,
|
|
82425
83027
|
message: result.message
|
|
82426
83028
|
});
|
|
82427
83029
|
setInput("");
|
|
@@ -84381,7 +84983,7 @@ proposals: npm run evolve:propose \u2014 decisions in npm run evolve:decide (P1:
|
|
|
84381
84983
|
}
|
|
84382
84984
|
if (argv.includes("--help") || argv.includes("-h")) {
|
|
84383
84985
|
console.log(
|
|
84384
|
-
"zelari-code \u2014 AI Council coding agent CLI.\n\nUsage: zelari-code [options]\n\nOptions:\n --version, -v Print version and exit\n --help, -h Print this help and exit\n --doctor [--json] Diagnose install health (shim, bundle, PATH, deps,\n node/git/bash in the agent shell)\n --inspect [--json] Unified project inspection (config, skills, MCP,\n hooks, plugins, AGENTS.md, trust status)\n --trust [path] Trust the cwd (or path) so project MCP + hooks load\n --fix-path Add the npm global prefix to the user PATH\n (Windows only; fixes 'command not found' after install)\n --fix-budget Set recommended ZELARI_MAX_TOOL_LOOP_HARD=180,\n ZELARI_MAX_TOOL_LOOP_ITERATIONS=60, ZELARI_CONTEXT_LIMIT=400000\n at User scope (prevents the agent stopping mid-task)\n --permission-mcp <socket> MCP stdio server for external agent permission prompts\n (spawned by claude --permission-prompt-tool)\n --memory-mcp Optional MCP stdio server for project memory\n --cwd <path> Trusted project root (requires ZELARI_MEMORY_MCP=1)\n --client-id <id> Stable local owner identity for private memories\n --memory-json <json> Read-only project-memory bridge for Zelari Desktop\n --skip-checks Skip the boot-time prerequisite check\n (alias for ZELARI_SKIP_PREFLIGHT=1)\n --no-wizard Skip the first-run wizard\n --reset-config Re-run the wizard (clears provider.json on commit)\n --headless Run a single task without mounting the TUI\n --task <text> Task prompt (required in headless mode)\n --output json|plain Output format (default: json)\n --mode kraken|council|zelari Dispatch mode (default: kraken; agent=alias)\n --council Alias for --mode council\n --phase plan|build Work phase (default: build)\n --provider <id> Provider override (default: active)\n --model <id> Model override (default: provider default)\n --profile <id> Capability profile (minimal/v1|kraken/v1|council/v1|mission/v1)\n --resume <id> Continue a 2.0 spine session\n --export-session <path> Write zelari-session-export/1 after the run\n --strict-done Evidence-based BUILD completion gate\n --task-file <path> Read the task prompt from a file (Windows argv cap)\n --once Single-cycle run (cron/git-hook triggers, ADR-0014)\n --kraken-graph <goal> Plan + execute a Kraken task graph\n (variant: --kraken-graph-file <path>; kill-switch\n ZELARI_KRAKEN_GRAPH=0)\n --plan-only Serialize the graph plan to .zelari/radio/ and exit 0\n --run-plan <id> Execute a pre-built .zelari/radio/plan-<id>.json\n --gauntlet Host-driven gauntlet loop (builder/critic tentacles)\n --session-export <id> Print a portable 2.0 session export (no LLM)\n serve Companion host for Android/remote clients (Tailscale)\n --bind <ip> Listen address (default: 127.0.0.1; use Tailscale IP)\n --port <n> Port (default: 7421)\n --token <secret> Bearer token (default: ~/.zelari-code/companion.token)\n --project <path> Allowlisted project root (repeatable)\n --save-projects Persist --project list to companion.json\n --serve-harness Long-lived harness kernel for hosts (NDJSON JSON-RPC\n on stdin/stdout; Desktop/companion transport)\n --print-config Print provider/model config as JSON (no secrets)\n --print-settings Print zelari.config.json values + the origin of\n each (default < user < project < env)\n --permissions <p> Permission preset: strict | standard | yolo \u2014 changes\n category DEFAULTS only (env vars and policy files win)\n --evolve-status Evolution ledger stats (read-only; ADR-0036; the\n ledger is written only when ZELARI_EVOLUTION=shadow)\n --plugins-status JSON status of optional plugins (Playwright, eslint, \u2026)\n --plugins-install <id> Install plugin (playwright also fetches Chromium)\n --cwd <path> Workspace for -D installs (default: process.cwd())\n --set-config Persist provider/model/endpoint\n --provider <id> Set active provider\n --model <id> Set model for that provider\n --endpoint <url> Custom OpenAI-compatible base URL\n --endpoint-clear Remove custom endpoint override\n --thinking <spec> Thinking effort (auto|off|low|medium|high|budget:N)\n --set-key Store an API key (never printed back)\n --provider <id> Provider id (required)\n --key <secret> API key (required)\n --login-oauth Start subscription OAuth (grok, chatgpt, anthropic)\n --provider <id> grok | chatgpt | anthropic\n --code <paste> Anthropic magic-link code (CODE#STATE)\n --no-browser Do not open the system browser\n --refresh-oauth Force-refresh an OAuth access token\n --provider <id> grok | chatgpt | anthropic\n --logout-oauth Clear stored OAuth credentials\n --provider <id> grok | chatgpt | anthropic\n --discover-models Refresh model list for a provider\n --provider <id> Provider (default: active)\n --print-mcp Print MCP server config (user + project)\n --cwd <path> Project root for .zelari/mcp.json\n --set-mcp Add/update an MCP server entry\n --name <id> Server name (required)\n --command <bin> Executable for stdio servers\n --url <endpoint> Streamable HTTP endpoint (e.g. UE 5.8 editor)\n --args <json> JSON array of args (stdio, optional)\n --timeout <ms> Per-server request timeout (http, optional)\n --scope user|project Default: user\n --enabled true|false Default: true\n --cwd <path> Required when scope=project\n --set-mcp-preset Install a named MCP preset (e.g. cua)\n --preset cua Cua Driver desktop computer-use (MCP)\n --preset unreal-mcp Unreal Engine 5.8+ editor (MCP over HTTP)\n --scope user|project Default: user\n --cwd <path> Required when scope=project\n --remove-mcp Remove an MCP server entry\n --name <id> --scope user|project [--cwd <path>]\n --print-skills Print skills (builtin + user + project)\n --cwd <path> Project root for .zelari/skills\n --set-skill Add/update a SKILL.md skill\n --name <id> Skill id (required)\n --description <t> One-line description (required)\n --body <text> Markdown instructions (required)\n --category <c> plan|refactor|debug|review|test|docs|ops|git|db|maint\n --tools <csv> Comma-separated required tools (optional)\n --cost <l> low|medium|high (default: medium)\n --scope user|project Default: user\n --cwd <path> Required when scope=project\n --remove-skill Remove a user/project SKILL.md\n --name <id> --scope user|project [--cwd <path>]\n --generate-skill-from-url Fetch URL + draft skill via model (JSON)\n --url <https://...> Required\n --provider <id> Override active provider\n --model <name> Override model for the selected provider\n --print-ssh-targets Print SSH deploy/monitor targets\n --set-ssh-target Upsert target (--json '{...}' or flags)\n --remove-ssh-target --id <id>\n --test-ssh-target --id <id> (BatchMode ssh true)\n --print-ssh-pubkey --path <private-or-.pub> (display public key)\n\nEnvironment:\n ZELARI_NO_WIZARD=1 Skip the first-run wizard\n ZELARI_SKIP_PREFLIGHT=1 Skip the boot prerequisite check\n ZELARI_NO_PLUGIN_PROMPT=1 Skip the boot plugin-install prompt\n ZELARI_MEMORY_MCP=1 Enable the optional external memory MCP server\n ANATHEMA_DEV=1 Disable background update check + preflight\n"
|
|
84986
|
+
"zelari-code \u2014 AI Council coding agent CLI.\n\nUsage: zelari-code [options]\n\nOptions:\n --version, -v Print version and exit\n --help, -h Print this help and exit\n --doctor [--json] Diagnose install health (shim, bundle, PATH, deps,\n node/git/bash in the agent shell)\n --inspect [--json] Unified project inspection (config, skills, MCP,\n hooks, plugins, AGENTS.md, trust status)\n --trust [path] Trust the cwd (or path) so project MCP + hooks load\n --fix-path Add the npm global prefix to the user PATH\n (Windows only; fixes 'command not found' after install)\n --fix-budget Set recommended ZELARI_MAX_TOOL_LOOP_HARD=180,\n ZELARI_MAX_TOOL_LOOP_ITERATIONS=60, ZELARI_CONTEXT_LIMIT=400000\n at User scope (prevents the agent stopping mid-task)\n --permission-mcp <socket> MCP stdio server for external agent permission prompts\n (spawned by claude --permission-prompt-tool)\n --memory-mcp Optional MCP stdio server for project memory\n --cwd <path> Trusted project root (requires ZELARI_MEMORY_MCP=1)\n --client-id <id> Stable local owner identity for private memories\n --memory-json <json> Read-only project-memory bridge for Zelari Desktop\n --skip-checks Skip the boot-time prerequisite check\n (alias for ZELARI_SKIP_PREFLIGHT=1)\n --no-wizard Skip the first-run wizard\n --reset-config Re-run the wizard (clears provider.json on commit)\n --headless Run a single task without mounting the TUI\n --task <text> Task prompt (required in headless mode)\n --output json|plain Output format (default: json)\n --mode kraken|council|zelari Dispatch mode (default: kraken; agent=alias)\n zelari/mission mode auto-scopes slices from open tasks in .zelari/plan.json\n --council Alias for --mode council\n --phase plan|build Work phase (default: build)\n --provider <id> Provider override (default: active)\n --model <id> Model override (default: provider default)\n --profile <id> Capability profile (minimal/v1|kraken/v1|council/v1|mission/v1)\n --resume <id> Continue a 2.0 spine session\n --resume-mission Resume .zelari/mission-state.json (not the spine)\n --export-session <path> Write zelari-session-export/1 after the run\n --strict-done Evidence-based BUILD completion gate\n --task-file <path> Read the task prompt from a file (Windows argv cap)\n --once Single-cycle run (cron/git-hook triggers, ADR-0014)\n --kraken-graph <goal> Plan + execute a Kraken task graph\n (variant: --kraken-graph-file <path>; kill-switch\n ZELARI_KRAKEN_GRAPH=0)\n --plan-only Serialize the graph plan to .zelari/radio/ and exit 0\n --run-plan <id> Execute a pre-built .zelari/radio/plan-<id>.json\n --gauntlet Host-driven gauntlet loop (builder/critic tentacles)\n --session-export <id> Print a portable 2.0 session export (no LLM)\n serve Companion host for Android/remote clients (Tailscale)\n --bind <ip> Listen address (default: 127.0.0.1; use Tailscale IP)\n --port <n> Port (default: 7421)\n --token <secret> Bearer token (default: ~/.zelari-code/companion.token)\n --project <path> Allowlisted project root (repeatable)\n --save-projects Persist --project list to companion.json\n --serve-harness Long-lived harness kernel for hosts (NDJSON JSON-RPC\n on stdin/stdout; Desktop/companion transport)\n --print-config Print provider/model config as JSON (no secrets)\n --print-settings Print zelari.config.json values + the origin of\n each (default < user < project < env)\n --permissions <p> Permission preset: strict | standard | yolo \u2014 changes\n category DEFAULTS only (env vars and policy files win)\n --evolve-status Evolution ledger stats (read-only; ADR-0036; the\n ledger is written only when ZELARI_EVOLUTION=shadow)\n --plugins-status JSON status of optional plugins (Playwright, eslint, \u2026)\n --plugins-install <id> Install plugin (playwright also fetches Chromium)\n --cwd <path> Workspace for -D installs (default: process.cwd())\n --set-config Persist provider/model/endpoint\n --provider <id> Set active provider\n --model <id> Set model for that provider\n --endpoint <url> Custom OpenAI-compatible base URL\n --endpoint-clear Remove custom endpoint override\n --thinking <spec> Thinking effort (auto|off|low|medium|high|budget:N)\n --set-key Store an API key (never printed back)\n --provider <id> Provider id (required)\n --key <secret> API key (required)\n --login-oauth Start subscription OAuth (grok, chatgpt, anthropic)\n --provider <id> grok | chatgpt | anthropic\n --code <paste> Anthropic magic-link code (CODE#STATE)\n --no-browser Do not open the system browser\n --refresh-oauth Force-refresh an OAuth access token\n --provider <id> grok | chatgpt | anthropic\n --logout-oauth Clear stored OAuth credentials\n --provider <id> grok | chatgpt | anthropic\n --discover-models Refresh model list for a provider\n --provider <id> Provider (default: active)\n --print-mcp Print MCP server config (user + project)\n --cwd <path> Project root for .zelari/mcp.json\n --set-mcp Add/update an MCP server entry\n --name <id> Server name (required)\n --command <bin> Executable for stdio servers\n --url <endpoint> Streamable HTTP endpoint (e.g. UE 5.8 editor)\n --args <json> JSON array of args (stdio, optional)\n --timeout <ms> Per-server request timeout (http, optional)\n --scope user|project Default: user\n --enabled true|false Default: true\n --cwd <path> Required when scope=project\n --set-mcp-preset Install a named MCP preset (e.g. cua)\n --preset cua Cua Driver desktop computer-use (MCP)\n --preset unreal-mcp Unreal Engine 5.8+ editor (MCP over HTTP)\n --scope user|project Default: user\n --cwd <path> Required when scope=project\n --remove-mcp Remove an MCP server entry\n --name <id> --scope user|project [--cwd <path>]\n --print-skills Print skills (builtin + user + project)\n --cwd <path> Project root for .zelari/skills\n --set-skill Add/update a SKILL.md skill\n --name <id> Skill id (required)\n --description <t> One-line description (required)\n --body <text> Markdown instructions (required)\n --category <c> plan|refactor|debug|review|test|docs|ops|git|db|maint\n --tools <csv> Comma-separated required tools (optional)\n --cost <l> low|medium|high (default: medium)\n --scope user|project Default: user\n --cwd <path> Required when scope=project\n --remove-skill Remove a user/project SKILL.md\n --name <id> --scope user|project [--cwd <path>]\n --generate-skill-from-url Fetch URL + draft skill via model (JSON)\n --url <https://...> Required\n --provider <id> Override active provider\n --model <name> Override model for the selected provider\n --print-ssh-targets Print SSH deploy/monitor targets\n --set-ssh-target Upsert target (--json '{...}' or flags)\n --remove-ssh-target --id <id>\n --test-ssh-target --id <id> (BatchMode ssh true)\n --print-ssh-pubkey --path <private-or-.pub> (display public key)\n\nEnvironment:\n ZELARI_NO_WIZARD=1 Skip the first-run wizard\n ZELARI_SKIP_PREFLIGHT=1 Skip the boot prerequisite check\n ZELARI_NO_PLUGIN_PROMPT=1 Skip the boot plugin-install prompt\n ZELARI_MEMORY_MCP=1 Enable the optional external memory MCP server\n ANATHEMA_DEV=1 Disable background update check + preflight\n"
|
|
84385
84987
|
);
|
|
84386
84988
|
process.exit(0);
|
|
84387
84989
|
}
|