zelari-code 1.36.0 → 1.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.
@@ -1532,6 +1532,112 @@ var init_keyStore = __esm({
1532
1532
  }
1533
1533
  });
1534
1534
 
1535
+ // src/cli/thinking.ts
1536
+ function thinkingCapabilityFor(id) {
1537
+ return PROVIDER_THINKING_CAPABILITY[id] ?? {};
1538
+ }
1539
+ function stringifyThinkingSpec(spec) {
1540
+ if (spec === "auto") return "auto";
1541
+ if (spec.kind === "off") return "off";
1542
+ if (spec.kind === "effort") return spec.effort;
1543
+ return `budget:${spec.budgetTokens}`;
1544
+ }
1545
+ function parseThinkingSpec(raw) {
1546
+ const s = (raw ?? "").trim().toLowerCase();
1547
+ if (!s || s === "auto") return "auto";
1548
+ if (s === "off") return { kind: "off" };
1549
+ if (s === "low" || s === "medium" || s === "high") return { kind: "effort", effort: s };
1550
+ const m = /^budget:(\d+)$/.exec(s);
1551
+ if (m) {
1552
+ const n = Number.parseInt(m[1], 10);
1553
+ if (Number.isFinite(n) && n > 0) return { kind: "budget", budgetTokens: n };
1554
+ }
1555
+ return "auto";
1556
+ }
1557
+ function isValidThinkingInput(raw) {
1558
+ const s = raw.trim().toLowerCase();
1559
+ if (s === "auto" || s === "off" || s === "low" || s === "medium" || s === "high") return true;
1560
+ return /^budget:\d+$/.test(s) && Number.parseInt(s.slice(7), 10) > 0;
1561
+ }
1562
+ function degrade(note) {
1563
+ return { patch: {}, degraded: true, note };
1564
+ }
1565
+ function translateOpenAiCompatibleThinking(providerId, spec) {
1566
+ if (spec === "auto") return { patch: {}, degraded: false };
1567
+ const cap3 = thinkingCapabilityFor(providerId);
1568
+ switch (spec.kind) {
1569
+ case "off":
1570
+ if (providerId === "deepseek" || providerId === "glm") {
1571
+ return { patch: { thinking: { type: "disabled" } }, degraded: false };
1572
+ }
1573
+ if (cap3.effort) return { patch: { reasoning_effort: "low" }, degraded: false };
1574
+ return degrade(`thinking 'off' is not supported for provider "${providerId}"`);
1575
+ case "effort":
1576
+ if (!cap3.effort) {
1577
+ return degrade(`thinking 'effort' is not supported for provider "${providerId}"`);
1578
+ }
1579
+ if (providerId === "deepseek") {
1580
+ return {
1581
+ patch: {
1582
+ thinking: { type: "enabled" },
1583
+ reasoning_effort: spec.effort === "high" ? "max" : "high"
1584
+ },
1585
+ degraded: false
1586
+ };
1587
+ }
1588
+ return { patch: { reasoning_effort: spec.effort }, degraded: false };
1589
+ case "budget":
1590
+ if (!cap3.budget) {
1591
+ return degrade(`thinking 'budget' is not supported for provider "${providerId}"`);
1592
+ }
1593
+ return {
1594
+ patch: { thinking: { type: "enabled", budget_tokens: spec.budgetTokens } },
1595
+ degraded: false
1596
+ };
1597
+ }
1598
+ }
1599
+ function translateResponsesThinking(spec) {
1600
+ if (spec === "auto") return { patch: {}, degraded: false };
1601
+ switch (spec.kind) {
1602
+ case "off":
1603
+ return { patch: { reasoning: { effort: "minimal" } }, degraded: false };
1604
+ case "effort":
1605
+ return { patch: { reasoning: { effort: spec.effort } }, degraded: false };
1606
+ case "budget":
1607
+ return degrade('thinking "budget" is not supported for chatgpt \u2014 use low/medium/high');
1608
+ }
1609
+ }
1610
+ function translateAnthropicThinking(spec) {
1611
+ if (spec === "auto") return { patch: {}, degraded: false };
1612
+ switch (spec.kind) {
1613
+ case "off":
1614
+ return { patch: { thinking: { type: "disabled" } }, degraded: false };
1615
+ case "budget":
1616
+ return {
1617
+ patch: { thinking: { type: "enabled", budget_tokens: spec.budgetTokens } },
1618
+ degraded: false
1619
+ };
1620
+ case "effort":
1621
+ return degrade('thinking "effort" is not supported for anthropic \u2014 use budget:N');
1622
+ }
1623
+ }
1624
+ var PROVIDER_THINKING_CAPABILITY;
1625
+ var init_thinking = __esm({
1626
+ "src/cli/thinking.ts"() {
1627
+ "use strict";
1628
+ PROVIDER_THINKING_CAPABILITY = {
1629
+ "openai-compatible": { effort: true },
1630
+ "grok": { effort: true },
1631
+ "chatgpt": { effort: true },
1632
+ "anthropic": { budget: true },
1633
+ "glm": { budget: true },
1634
+ "deepseek": { effort: true },
1635
+ "minimax": { effort: true },
1636
+ "custom": { effort: true }
1637
+ };
1638
+ }
1639
+ });
1640
+
1535
1641
  // src/cli/providerConfig.ts
1536
1642
  var providerConfig_exports = {};
1537
1643
  __export(providerConfig_exports, {
@@ -1542,10 +1648,12 @@ __export(providerConfig_exports, {
1542
1648
  getModelForProvider: () => getModelForProvider,
1543
1649
  getProviderConfig: () => getProviderConfig,
1544
1650
  getProviderConfigPath: () => getProviderConfigPath,
1651
+ getThinkingForProvider: () => getThinkingForProvider,
1545
1652
  loadProviderConfig: () => loadProviderConfig,
1546
1653
  setActiveProviderId: () => setActiveProviderId,
1547
1654
  setCustomEndpoint: () => setCustomEndpoint,
1548
- setModelForProvider: () => setModelForProvider
1655
+ setModelForProvider: () => setModelForProvider,
1656
+ setThinkingForProvider: () => setThinkingForProvider
1549
1657
  });
1550
1658
  import { promises as fs2, existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "node:fs";
1551
1659
  import path4 from "node:path";
@@ -1566,6 +1674,7 @@ function getProviderConfig() {
1566
1674
  stored = {
1567
1675
  activeProviderId: parsed.activeProviderId,
1568
1676
  modelByProvider: { ...DEFAULTS.modelByProvider, ...parsed.modelByProvider },
1677
+ thinkingByProvider: { ...DEFAULTS.thinkingByProvider, ...parsed.thinkingByProvider },
1569
1678
  customEndpoints: mergeCustomEndpoints(parsed.customEndpoints)
1570
1679
  };
1571
1680
  }
@@ -1575,6 +1684,7 @@ function getProviderConfig() {
1575
1684
  const base = stored ?? {
1576
1685
  ...DEFAULTS,
1577
1686
  modelByProvider: { ...DEFAULTS.modelByProvider },
1687
+ thinkingByProvider: { ...DEFAULTS.thinkingByProvider },
1578
1688
  customEndpoints: { ...DEFAULTS.customEndpoints }
1579
1689
  };
1580
1690
  if (envActive && PROVIDERS.some((p3) => p3.id === envActive)) {
@@ -1662,6 +1772,19 @@ function getModelForProvider(id) {
1662
1772
  const config2 = getProviderConfig();
1663
1773
  return config2.modelByProvider[id] ?? DEFAULTS.modelByProvider[id] ?? "";
1664
1774
  }
1775
+ function getThinkingForProvider(id) {
1776
+ const config2 = getProviderConfig();
1777
+ return parseThinkingSpec(config2.thinkingByProvider[id]);
1778
+ }
1779
+ function setThinkingForProvider(id, spec) {
1780
+ const found = PROVIDERS.find((p3) => p3.id === id);
1781
+ if (!found) {
1782
+ throw new Error(`Unknown provider id: "${id}". Available: ${PROVIDERS.map((p3) => p3.id).join(", ")}`);
1783
+ }
1784
+ const config2 = getProviderConfig();
1785
+ config2.thinkingByProvider[id] = stringifyThinkingSpec(spec);
1786
+ writeProviderConfig(config2);
1787
+ }
1665
1788
  function getActiveProvider() {
1666
1789
  const config2 = getProviderConfig();
1667
1790
  const spec = PROVIDERS.find((p3) => p3.id === config2.activeProviderId);
@@ -1681,6 +1804,7 @@ async function loadProviderConfig() {
1681
1804
  return {
1682
1805
  activeProviderId: parsed.activeProviderId,
1683
1806
  modelByProvider: { ...DEFAULTS.modelByProvider, ...parsed.modelByProvider },
1807
+ thinkingByProvider: { ...DEFAULTS.thinkingByProvider, ...parsed.thinkingByProvider },
1684
1808
  customEndpoints: mergeCustomEndpoints(parsed.customEndpoints)
1685
1809
  };
1686
1810
  }
@@ -1689,6 +1813,7 @@ async function loadProviderConfig() {
1689
1813
  return {
1690
1814
  ...DEFAULTS,
1691
1815
  modelByProvider: { ...DEFAULTS.modelByProvider },
1816
+ thinkingByProvider: { ...DEFAULTS.thinkingByProvider },
1692
1817
  customEndpoints: { ...DEFAULTS.customEndpoints }
1693
1818
  };
1694
1819
  }
@@ -1697,6 +1822,7 @@ var init_providerConfig = __esm({
1697
1822
  "src/cli/providerConfig.ts"() {
1698
1823
  "use strict";
1699
1824
  init_keyStore();
1825
+ init_thinking();
1700
1826
  DEFAULTS = {
1701
1827
  activeProviderId: "openai-compatible",
1702
1828
  modelByProvider: {
@@ -1710,6 +1836,16 @@ var init_providerConfig = __esm({
1710
1836
  "anthropic": "claude-sonnet-4-5",
1711
1837
  "custom": ""
1712
1838
  },
1839
+ thinkingByProvider: {
1840
+ "openai-compatible": "auto",
1841
+ "minimax": "auto",
1842
+ "glm": "auto",
1843
+ "grok": "auto",
1844
+ "deepseek": "auto",
1845
+ "chatgpt": "auto",
1846
+ "anthropic": "auto",
1847
+ "custom": "auto"
1848
+ },
1713
1849
  customEndpoints: {}
1714
1850
  };
1715
1851
  }
@@ -28027,10 +28163,18 @@ function openaiCompatibleProvider(config2) {
28027
28163
  // the harness will fall back to the ~4-char/token approximation.
28028
28164
  stream_options: { include_usage: true }
28029
28165
  };
28030
- if (config2.providerId === "deepseek") {
28166
+ const thinkingSpec = config2.thinking ?? "auto";
28167
+ if (config2.providerId === "deepseek" && thinkingSpec === "auto") {
28031
28168
  const thinking = resolveDeepSeekThinking();
28032
28169
  if (thinking.thinking) body.thinking = { type: thinking.thinking };
28033
28170
  if (thinking.reasoningEffort) body.reasoning_effort = thinking.reasoningEffort;
28171
+ } else if (thinkingSpec !== "auto") {
28172
+ const t = translateOpenAiCompatibleThinking(config2.providerId, thinkingSpec);
28173
+ if (t.degraded) {
28174
+ console.warn(`[thinking] ${t.note ?? "unsupported"} \u2014 falling back to provider default.`);
28175
+ } else {
28176
+ Object.assign(body, t.patch);
28177
+ }
28034
28178
  }
28035
28179
  if (params.tools && params.tools.length > 0) {
28036
28180
  const orderedTools = [...params.tools].sort(
@@ -28281,6 +28425,7 @@ async function providerFromEnv() {
28281
28425
  baseUrl: resolveBaseUrl(providerId),
28282
28426
  model: getModelForProvider(providerId),
28283
28427
  providerId,
28428
+ thinking: getThinkingForProvider(providerId),
28284
28429
  ...extraFromStored(providerId)
28285
28430
  };
28286
28431
  }
@@ -28292,6 +28437,7 @@ async function providerConfigFor(providerId) {
28292
28437
  baseUrl: resolveBaseUrl(providerId),
28293
28438
  model: getModelForProvider(providerId),
28294
28439
  providerId,
28440
+ thinking: getThinkingForProvider(providerId),
28295
28441
  ...extraFromStored(providerId)
28296
28442
  };
28297
28443
  }
@@ -28301,6 +28447,7 @@ var init_openai_compatible = __esm({
28301
28447
  "use strict";
28302
28448
  init_keyStore();
28303
28449
  init_providerConfig();
28450
+ init_thinking();
28304
28451
  RETRYABLE_STATUSES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
28305
28452
  MAX_RETRIES = (() => {
28306
28453
  const raw = process.env.ZELARI_PROVIDER_MAX_RETRIES;
@@ -28554,6 +28701,12 @@ function anthropicMessagesProvider(config2) {
28554
28701
  input_schema: t.parameters
28555
28702
  }));
28556
28703
  }
28704
+ const thinkingSpec = config2.thinking ?? "auto";
28705
+ if (thinkingSpec !== "auto") {
28706
+ const t = translateAnthropicThinking(thinkingSpec);
28707
+ if (t.degraded) console.warn(`[thinking] ${t.note ?? "unsupported"} \u2014 falling back to provider default.`);
28708
+ else Object.assign(body, t.patch);
28709
+ }
28557
28710
  const base = config2.baseUrl.replace(/\/$/, "").replace(/\/v1$/, "");
28558
28711
  const url2 = `${base}/v1/messages`;
28559
28712
  let response;
@@ -28692,6 +28845,7 @@ var init_anthropic = __esm({
28692
28845
  "src/cli/provider/anthropic.ts"() {
28693
28846
  "use strict";
28694
28847
  init_chatStats();
28848
+ init_thinking();
28695
28849
  ANTHROPIC_VERSION = "2023-06-01";
28696
28850
  ANTHROPIC_BETA = "oauth-2025-04-20";
28697
28851
  ANTHROPIC_BETA_EXTENDED_CACHE_TTL = "extended-cache-ttl-2025-04-11";
@@ -28759,6 +28913,12 @@ function chatgptResponsesProvider(config2) {
28759
28913
  parameters: t.parameters
28760
28914
  }));
28761
28915
  }
28916
+ const thinkingSpec = config2.thinking ?? "auto";
28917
+ if (thinkingSpec !== "auto") {
28918
+ const t = translateResponsesThinking(thinkingSpec);
28919
+ if (t.degraded) console.warn(`[thinking] ${t.note ?? "unsupported"} \u2014 falling back to provider default.`);
28920
+ else Object.assign(body, t.patch);
28921
+ }
28762
28922
  const base = config2.baseUrl.replace(/\/$/, "");
28763
28923
  const url2 = `${base}/responses`;
28764
28924
  let response;
@@ -28873,6 +29033,7 @@ function chatgptResponsesProvider(config2) {
28873
29033
  var init_chatgpt = __esm({
28874
29034
  "src/cli/provider/chatgpt.ts"() {
28875
29035
  "use strict";
29036
+ init_thinking();
28876
29037
  }
28877
29038
  });
28878
29039
 
@@ -42545,6 +42706,8 @@ var init_oauthDesktop = __esm({
42545
42706
  var provider_exports = {};
42546
42707
  __export(provider_exports, {
42547
42708
  buildModelPickerItems: () => buildModelPickerItems,
42709
+ handleEffortSet: () => handleEffortSet,
42710
+ handleEffortShow: () => handleEffortShow,
42548
42711
  handleLoginKey: () => handleLoginKey,
42549
42712
  handleLoginOAuth: () => handleLoginOAuth,
42550
42713
  handleLoginOAuthGrok: () => handleLoginOAuthGrok,
@@ -42792,6 +42955,39 @@ function handleModelSet(ctx, model) {
42792
42955
  appendSystem(ctx.setMessages, `[model error] ${err instanceof Error ? err.message : String(err)}`);
42793
42956
  }
42794
42957
  }
42958
+ function handleEffortShow(ctx) {
42959
+ const id = ctx.activeProviderSpec.id;
42960
+ const cap3 = thinkingCapabilityFor(id);
42961
+ const current = stringifyThinkingSpec(getThinkingForProvider(id));
42962
+ const options = [
42963
+ "auto",
42964
+ "off",
42965
+ ...cap3.effort ? ["low", "medium", "high"] : [],
42966
+ ...cap3.budget ? ["budget:<tokens>"] : []
42967
+ ];
42968
+ appendSystem(
42969
+ ctx.setMessages,
42970
+ `[effort] ${ctx.activeProviderSpec.displayName}: ${current} \u2014 options: ${options.join(", ")}`
42971
+ );
42972
+ }
42973
+ function handleEffortSet(ctx, raw) {
42974
+ const id = ctx.activeProviderSpec.id;
42975
+ if (!isValidThinkingInput(raw)) {
42976
+ appendSystem(
42977
+ ctx.setMessages,
42978
+ `[effort] invalid spec "${raw}" \u2014 use auto | off | low | medium | high | budget:<tokens>`
42979
+ );
42980
+ return;
42981
+ }
42982
+ const spec = parseThinkingSpec(raw);
42983
+ try {
42984
+ setThinkingForProvider(id, spec);
42985
+ ctx.setProviderConfig(getProviderConfig());
42986
+ appendSystem(ctx.setMessages, `[effort] ${ctx.activeProviderSpec.displayName} \u2192 ${stringifyThinkingSpec(spec)}`);
42987
+ } catch (err) {
42988
+ appendSystem(ctx.setMessages, `[effort error] ${err instanceof Error ? err.message : String(err)}`);
42989
+ }
42990
+ }
42795
42991
  function buildModelPickerItems(models, activeModel, defaultModel) {
42796
42992
  const items = models.map((m) => ({
42797
42993
  value: m.id,
@@ -42895,6 +43091,7 @@ var init_provider2 = __esm({
42895
43091
  init_refreshRegistry();
42896
43092
  init_keyValidator();
42897
43093
  init_providerConfig();
43094
+ init_thinking();
42898
43095
  init_modelDiscovery();
42899
43096
  init_messageHelpers();
42900
43097
  init_duration();
@@ -43238,6 +43435,7 @@ function parseSetConfigFlags(argv) {
43238
43435
  let provider;
43239
43436
  let model;
43240
43437
  let endpoint;
43438
+ let thinking;
43241
43439
  let endpointClear = false;
43242
43440
  for (let i = 0; i < argv.length; i++) {
43243
43441
  const arg = argv[i];
@@ -43250,14 +43448,17 @@ function parseSetConfigFlags(argv) {
43250
43448
  } else if (arg === "--endpoint") {
43251
43449
  endpoint = argv[i + 1];
43252
43450
  i++;
43451
+ } else if (arg === "--thinking") {
43452
+ thinking = argv[i + 1];
43453
+ i++;
43253
43454
  } else if (arg === "--endpoint-clear") {
43254
43455
  endpointClear = true;
43255
43456
  }
43256
43457
  }
43257
- if (!provider && !model && !endpoint && !endpointClear) {
43458
+ if (!provider && !model && !endpoint && !endpointClear && !thinking) {
43258
43459
  return {
43259
43460
  request: null,
43260
- error: "--set-config requires --provider, --model, --endpoint, and/or --endpoint-clear"
43461
+ error: "--set-config requires --provider, --model, --endpoint, --thinking, and/or --endpoint-clear"
43261
43462
  };
43262
43463
  }
43263
43464
  if (provider !== void 0 && provider.trim().length === 0) {
@@ -43272,12 +43473,16 @@ function parseSetConfigFlags(argv) {
43272
43473
  if (endpoint && endpointClear) {
43273
43474
  return { request: null, error: "--endpoint and --endpoint-clear conflict" };
43274
43475
  }
43476
+ if (thinking !== void 0 && !isValidThinkingInput(thinking)) {
43477
+ return { request: null, error: `invalid --thinking value '${thinking}'` };
43478
+ }
43275
43479
  return {
43276
43480
  request: {
43277
43481
  provider: provider?.trim(),
43278
43482
  model: model?.trim(),
43279
43483
  endpoint: endpoint?.trim(),
43280
- endpointClear: endpointClear || void 0
43484
+ endpointClear: endpointClear || void 0,
43485
+ thinking: thinking?.trim().toLowerCase()
43281
43486
  }
43282
43487
  };
43283
43488
  }
@@ -43352,7 +43557,9 @@ function buildDesktopConfigSnapshot() {
43352
43557
  authKind: !hasKey ? "none" : oauth ? "oauth" : "api_key",
43353
43558
  expiresAt: stored?.expiresAt ?? null,
43354
43559
  hasRefreshToken: Boolean(stored?.refreshToken),
43355
- oauthSupported: isOAuthProvider(p3.id)
43560
+ oauthSupported: isOAuthProvider(p3.id),
43561
+ thinking: config2.thinkingByProvider[p3.id] ?? "auto",
43562
+ thinkingCapability: thinkingCapabilityFor(p3.id)
43356
43563
  };
43357
43564
  });
43358
43565
  return {
@@ -43394,6 +43601,9 @@ function applySetConfig(req) {
43394
43601
  if (req.model) {
43395
43602
  setModelForProvider(targetProvider, req.model);
43396
43603
  }
43604
+ if (req.thinking) {
43605
+ setThinkingForProvider(targetProvider, parseThinkingSpec(req.thinking));
43606
+ }
43397
43607
  const after = getProviderConfig();
43398
43608
  const ep = getCustomEndpoint(after.activeProviderId);
43399
43609
  return {
@@ -43470,6 +43680,7 @@ var init_desktopConfig = __esm({
43470
43680
  init_providerConfig();
43471
43681
  init_modelDiscovery();
43472
43682
  init_updater();
43683
+ init_thinking();
43473
43684
  DISCOVERABLE = [
43474
43685
  "grok",
43475
43686
  "glm",
@@ -50629,6 +50840,13 @@ ${formatSkillList(availableSkills)}`
50629
50840
  }
50630
50841
  return { handled: true, kind: "provider_set", provider: subcommand };
50631
50842
  }
50843
+ case "effort": {
50844
+ const spec = args[0];
50845
+ if (!spec || spec === "show") {
50846
+ return { handled: true, kind: "effort_show" };
50847
+ }
50848
+ return { handled: true, kind: "effort_set", effortSpec: spec };
50849
+ }
50632
50850
  case "branch": {
50633
50851
  const name = args[0];
50634
50852
  if (!name) {
@@ -53122,6 +53340,16 @@ function useSlashDispatch(params) {
53122
53340
  setInput("");
53123
53341
  return;
53124
53342
  }
53343
+ if (result.kind === "effort_set" && result.effortSpec) {
53344
+ handleEffortSet(providerCtx, result.effortSpec);
53345
+ setInput("");
53346
+ return;
53347
+ }
53348
+ if (result.kind === "effort_show") {
53349
+ handleEffortShow(providerCtx);
53350
+ setInput("");
53351
+ return;
53352
+ }
53125
53353
  if (result.kind === "models_list") {
53126
53354
  handleModelsList(providerCtx);
53127
53355
  setInput("");
@@ -56186,7 +56414,7 @@ function pickRootComponent() {
56186
56414
  }
56187
56415
  if (argv.includes("--help") || argv.includes("-h")) {
56188
56416
  console.log(
56189
- "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 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 --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 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 --print-config Print provider/model config as JSON (no secrets)\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 --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 (required)\n --args <json> JSON array of args (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 --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 ANATHEMA_DEV=1 Disable background update check + preflight\n"
56417
+ "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 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 --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 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 --print-config Print provider/model config as JSON (no secrets)\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 (required)\n --args <json> JSON array of args (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 --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 ANATHEMA_DEV=1 Disable background update check + preflight\n"
56190
56418
  );
56191
56419
  process.exit(0);
56192
56420
  }