jinzd-ai-cli 0.4.269 → 0.4.271

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.
Files changed (72) hide show
  1. package/dist/{batch-HUOYPVJQ.js → batch-FPDT2USZ.js} +2 -2
  2. package/dist/{chunk-AAERHPBN.js → chunk-2RN4T4XD.js} +1 -1
  3. package/dist/{chunk-QPPUYCRF.js → chunk-4UNRDXZV.js} +8 -8
  4. package/dist/{chunk-4HTJMLFY.js → chunk-5JFRM47R.js} +1 -1
  5. package/dist/{chunk-S3F5LOV3.js → chunk-BFPF3JF2.js} +7 -7
  6. package/dist/{chunk-3TOMHXDW.js → chunk-FT3WS5PG.js} +1 -1
  7. package/dist/{chunk-R7GERZDA.js → chunk-JT6UN5C6.js} +26 -5
  8. package/dist/{chunk-V6KQ67VF.js → chunk-OSYK6D4G.js} +1 -1
  9. package/dist/{chunk-5PRWBJCI.js → chunk-PDRAOFGI.js} +4 -4
  10. package/dist/{chunk-6PROC2JO.js → chunk-PG7O7N7D.js} +8 -8
  11. package/dist/{chunk-5IUFUCIT.js → chunk-PMRU2CAF.js} +12 -4
  12. package/dist/{chunk-NVN3FHXI.js → chunk-RLAUMACS.js} +1 -1
  13. package/dist/{chunk-XJAGGJVU.js → chunk-RNDHIERN.js} +3 -3
  14. package/dist/{chunk-DJNGUPM3.js → chunk-V26ZMB3D.js} +11 -11
  15. package/dist/{chunk-KIHNZBEA.js → chunk-VPXNLE7E.js} +1 -1
  16. package/dist/chunk-XNFIYS7G.js +82 -0
  17. package/dist/{ci-4QS2J7BG.js → ci-VPN5RWCO.js} +4 -4
  18. package/dist/{ci-format-6L6M67WC.js → ci-format-GKXVCVME.js} +2 -2
  19. package/dist/config-command-E5DHADEV.js +11 -0
  20. package/dist/{constants-IO5VJLEE.js → constants-Y43DJFGV.js} +1 -1
  21. package/dist/{doctor-cli-ZU4E2DDL.js → doctor-cli-RZGZB2TF.js} +4 -4
  22. package/dist/electron-server.js +146 -30
  23. package/dist/{hub-AMDWXSKZ.js → hub-FJWP6SDG.js} +1 -1
  24. package/dist/index.js +85 -99
  25. package/dist/{persistent-memory-H4DNDIOQ.js → persistent-memory-IR47JCTF.js} +3 -3
  26. package/dist/{persistent-memory-52SE5K44.js → persistent-memory-KX2R67AT.js} +2 -2
  27. package/dist/{pr-Z4O5H6I3.js → pr-NTQ3N4B4.js} +5 -5
  28. package/dist/{run-tests-PYKKYMPA.js → run-tests-25CNXJ4N.js} +2 -2
  29. package/dist/{run-tests-FZSYHWYX.js → run-tests-UTES6HCT.js} +2 -2
  30. package/dist/{server-ZSTVYSYC.js → server-IGCCSX4B.js} +10 -10
  31. package/dist/{server-WTJSM2MT.js → server-R56CVHCM.js} +82 -56
  32. package/dist/{task-orchestrator-PNLI3V36.js → task-orchestrator-MFYEKR2I.js} +12 -12
  33. package/dist/{usage-GVFUVYUG.js → usage-FHX7PQQH.js} +11 -4
  34. package/dist/web/client/actions.js.br +0 -0
  35. package/dist/web/client/actions.js.gz +0 -0
  36. package/dist/web/client/api.js.br +0 -0
  37. package/dist/web/client/api.js.gz +0 -0
  38. package/dist/web/client/app.js +3 -6
  39. package/dist/web/client/app.js.br +0 -0
  40. package/dist/web/client/app.js.gz +0 -0
  41. package/dist/web/client/dom.js.br +0 -0
  42. package/dist/web/client/dom.js.gz +0 -0
  43. package/dist/web/client/icon.svg.br +0 -0
  44. package/dist/web/client/icon.svg.gz +0 -0
  45. package/dist/web/client/index.html.br +0 -0
  46. package/dist/web/client/index.html.gz +0 -0
  47. package/dist/web/client/sidebar-tabs.js.br +0 -0
  48. package/dist/web/client/sidebar-tabs.js.gz +0 -0
  49. package/dist/web/client/state.js.br +0 -0
  50. package/dist/web/client/state.js.gz +0 -0
  51. package/dist/web/client/style.css.br +0 -0
  52. package/dist/web/client/style.css.gz +0 -0
  53. package/dist/web/client/sw.js.br +0 -0
  54. package/dist/web/client/sw.js.gz +0 -0
  55. package/dist/web/client/templates.js.br +0 -0
  56. package/dist/web/client/templates.js.gz +0 -0
  57. package/dist/web/client/util.js +22 -0
  58. package/dist/web/client/util.js.br +0 -0
  59. package/dist/web/client/util.js.gz +0 -0
  60. package/dist/web/client/vendor/daisyui-full.min.css.br +0 -0
  61. package/dist/web/client/vendor/daisyui-full.min.css.gz +0 -0
  62. package/dist/web/client/vendor/github-dark.min.css.br +0 -0
  63. package/dist/web/client/vendor/github-dark.min.css.gz +0 -0
  64. package/dist/web/client/vendor/github.min.css.br +0 -0
  65. package/dist/web/client/vendor/github.min.css.gz +0 -0
  66. package/dist/web/client/vendor/highlight.min.js.br +0 -0
  67. package/dist/web/client/vendor/highlight.min.js.gz +0 -0
  68. package/dist/web/client/vendor/marked.min.js.br +0 -0
  69. package/dist/web/client/vendor/marked.min.js.gz +0 -0
  70. package/dist/web/client/vendor/tailwind.js.br +0 -0
  71. package/dist/web/client/vendor/tailwind.js.gz +0 -0
  72. package/package.json +1 -1
@@ -36,14 +36,14 @@ import {
36
36
  touchMemoryReferences,
37
37
  updateMemoryApproval,
38
38
  updateMemoryEntry
39
- } from "./chunk-KIHNZBEA.js";
39
+ } from "./chunk-VPXNLE7E.js";
40
40
  import {
41
41
  redactJson,
42
42
  scanString
43
43
  } from "./chunk-YVTASHS5.js";
44
44
  import {
45
45
  runTestsTool
46
- } from "./chunk-NVN3FHXI.js";
46
+ } from "./chunk-RLAUMACS.js";
47
47
  import {
48
48
  AGENTIC_BEHAVIOR_GUIDELINE,
49
49
  APP_NAME,
@@ -76,7 +76,7 @@ import {
76
76
  SUBAGENT_MAX_ROUNDS_LIMIT,
77
77
  VERSION,
78
78
  buildUserIdentityPrompt
79
- } from "./chunk-4HTJMLFY.js";
79
+ } from "./chunk-5JFRM47R.js";
80
80
  import {
81
81
  hasSemanticIndex,
82
82
  semanticSearch
@@ -94,8 +94,8 @@ import {
94
94
  import express from "express";
95
95
  import { createServer } from "http";
96
96
  import { WebSocketServer } from "ws";
97
- import { join as join26, dirname as dirname10, resolve as resolve10, relative as relative6, sep as sep4 } from "path";
98
- import { existsSync as existsSync31, readFileSync as readFileSync25, readdirSync as readdirSync15, statSync as statSync14, realpathSync as realpathSync3 } from "fs";
97
+ import { join as join26, dirname as dirname10, resolve as resolve10, relative as relative6, sep as sep4, extname as extname3, resolve as resolvePath } from "path";
98
+ import { existsSync as existsSync31, readFileSync as readFileSync25, readdirSync as readdirSync15, statSync as statSync14, realpathSync as realpathSync3, createReadStream } from "fs";
99
99
  import { networkInterfaces } from "os";
100
100
 
101
101
  // src/config/config-manager.ts
@@ -187,6 +187,14 @@ var ConfigSchema = z.object({
187
187
  wordWrap: z.number().int().min(0).default(0),
188
188
  /** Skill 文件过大警告阈值(字符数)。超过此值的 skill 在启动加载时打印警告。0 = 静默。默认 10000 */
189
189
  skillSizeWarn: z.number().int().min(0).default(1e4),
190
+ /**
191
+ * 成本显示币种:usd(默认)| cny。
192
+ *
193
+ * 只影响**展示**——存储、monthlyBudget、cost-history.json 恒为美元。
194
+ * 人民币按 pricing.ts 的记账汇率换算并在输出里标注,避免造出一个
195
+ * 看起来像实时汇率的假数字(2026-08-14 审计 P3-02)。
196
+ */
197
+ currency: z.enum(["usd", "cny"]).default("usd"),
190
198
  /** 颜色主题:'dark'(默认)| 'light' | 'custom' */
191
199
  theme: z.enum(["dark", "light", "custom"]).default("dark"),
192
200
  /** 自定义颜色覆盖(仅在 theme='custom' 时生效)。值为 chalk 颜色名或 '#hex',支持 'bold.cyan' 组合 */
@@ -717,13 +725,13 @@ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
717
725
  import { join as join2 } from "path";
718
726
 
719
727
  // src/core/pricing.ts
720
- var DEEPSEEK_CNY_PER_USD = 6.9;
728
+ var CNY_PER_USD = 6.9;
721
729
  var DEEPSEEK_TIME_PRICING_EFFECTIVE_AT = /* @__PURE__ */ new Date("2026-08-16T16:00:00.000Z");
722
730
  function deepSeekCnyPricing(cacheRead, input, output) {
723
731
  return {
724
- cacheRead: cacheRead / DEEPSEEK_CNY_PER_USD,
725
- input: input / DEEPSEEK_CNY_PER_USD,
726
- output: output / DEEPSEEK_CNY_PER_USD
732
+ cacheRead: cacheRead / CNY_PER_USD,
733
+ input: input / CNY_PER_USD,
734
+ output: output / CNY_PER_USD
727
735
  };
728
736
  }
729
737
  function getDeepSeekV4Pricing(model, at) {
@@ -851,7 +859,21 @@ function computeCost(provider, model, usage, at = /* @__PURE__ */ new Date()) {
851
859
  const cacheRead = (usage.cacheReadTokens ?? 0) * (p.cacheRead ?? p.input);
852
860
  return (input + output + cacheWrite + cacheRead) / 1e6;
853
861
  }
854
- function formatCost(amount) {
862
+ var displayCurrency = "usd";
863
+ function setCostCurrency(currency) {
864
+ displayCurrency = currency === "cny" ? "cny" : "usd";
865
+ }
866
+ function getCostCurrency() {
867
+ return displayCurrency;
868
+ }
869
+ function formatCost(amount, currency = displayCurrency) {
870
+ if (currency === "cny") {
871
+ const cny = amount * CNY_PER_USD;
872
+ if (cny === 0) return "\xA50.0000";
873
+ if (cny < 0.01) return `\xA5${cny.toFixed(4)}`;
874
+ if (cny < 1) return `\xA5${cny.toFixed(3)}`;
875
+ return `\xA5${cny.toFixed(2)}`;
876
+ }
855
877
  if (amount === 0) return "$0.0000";
856
878
  if (amount < 0.01) return `$${amount.toFixed(4)}`;
857
879
  if (amount < 1) return `$${amount.toFixed(3)}`;
@@ -16017,7 +16039,7 @@ Cache: write=${cacheCreate} read=${cacheRead}` : "";
16017
16039
  Cost: ${formatCost(cost)}` : "";
16018
16040
  let memoryLine = "";
16019
16041
  try {
16020
- const { countPendingMemories } = await import("./persistent-memory-52SE5K44.js");
16042
+ const { countPendingMemories } = await import("./persistent-memory-KX2R67AT.js");
16021
16043
  const pending = countPendingMemories(ctx.config.getConfigDir());
16022
16044
  if (pending > 0) memoryLine = `
16023
16045
  Memory: \u26A0 ${pending} pending approval \u2014 see the Memory panel or /memory`;
@@ -16830,7 +16852,7 @@ async function handleTest(args, ctx) {
16830
16852
  const isCommand = argStr.includes(" ") || /^(mvn|gradle|npm|pytest|cargo|go)\b/.test(argStr);
16831
16853
  testArgs = isCommand ? { command: argStr } : { filter: argStr };
16832
16854
  }
16833
- const runTests = ctx.runTests ?? (await import("./run-tests-PYKKYMPA.js")).executeTests;
16855
+ const runTests = ctx.runTests ?? (await import("./run-tests-25CNXJ4N.js")).executeTests;
16834
16856
  const report = await runTests(testArgs);
16835
16857
  ctx.send({ type: "info", message: report });
16836
16858
  } catch (err) {
@@ -17088,7 +17110,7 @@ async function handleMemory(args, ctx) {
17088
17110
  ctx.handleMemoryManage(sub, args[1], sub === "expire" ? args[2] : void 0);
17089
17111
  } else if (sub === "export") {
17090
17112
  if (args[1] === "md") {
17091
- const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-52SE5K44.js");
17113
+ const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-KX2R67AT.js");
17092
17114
  ctx.send({
17093
17115
  type: "export_data",
17094
17116
  format: "md",
@@ -17253,28 +17275,96 @@ function applyProfileCommand(args, profile) {
17253
17275
  };
17254
17276
  }
17255
17277
 
17278
+ // src/core/config-command.ts
17279
+ var CONFIG_USAGE = "Usage: config [show | get <path> | set <path> <value>]";
17280
+ var FORBIDDEN_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
17281
+ function maskSecret(value) {
17282
+ if (value.length <= 8) return "****";
17283
+ return `${value.slice(0, 4)}****${value.slice(-4)}`;
17284
+ }
17285
+ function maskConfigSecrets(config) {
17286
+ const apiKeys = config["apiKeys"];
17287
+ if (apiKeys && typeof apiKeys === "object") {
17288
+ const keys = apiKeys;
17289
+ for (const k of Object.keys(keys)) {
17290
+ if (typeof keys[k] === "string") keys[k] = maskSecret(keys[k]);
17291
+ }
17292
+ }
17293
+ const custom = config["customProviders"];
17294
+ if (custom && typeof custom === "object") {
17295
+ for (const entry of Object.values(custom)) {
17296
+ if (entry && typeof entry === "object" && typeof entry["apiKey"] === "string") {
17297
+ const e = entry;
17298
+ e["apiKey"] = maskSecret(e["apiKey"]);
17299
+ }
17300
+ }
17301
+ }
17302
+ return config;
17303
+ }
17304
+ function applyConfigCommand(args, target) {
17305
+ const sub = args[0]?.toLowerCase();
17306
+ if (!sub) return { action: "wizard", changed: false, isError: false };
17307
+ if (sub === "show") {
17308
+ return {
17309
+ action: "show",
17310
+ json: JSON.stringify(maskConfigSecrets(target.toJSON()), null, 2),
17311
+ changed: false,
17312
+ isError: false
17313
+ };
17314
+ }
17315
+ if (sub === "get") {
17316
+ const path3 = args[1]?.trim();
17317
+ if (!path3) {
17318
+ return { action: "usage", summary: "Usage: config get <path> (e.g. ui.theme)", changed: false, isError: true };
17319
+ }
17320
+ const value = target.getByPath(path3);
17321
+ const shown = value === void 0 ? "(undefined)" : typeof value === "object" ? JSON.stringify(value) : String(value);
17322
+ return { action: "get", summary: `${path3} = ${shown}`, changed: false, isError: false };
17323
+ }
17324
+ if (sub === "set") {
17325
+ const path3 = args[1]?.trim();
17326
+ const value = args.slice(2).join(" ").trim();
17327
+ if (!path3 || value === "") {
17328
+ return {
17329
+ action: "usage",
17330
+ summary: "Usage: config set <path> <value> (e.g. ui.theme light)",
17331
+ changed: false,
17332
+ isError: true
17333
+ };
17334
+ }
17335
+ if (path3.split(".").some((k) => FORBIDDEN_KEYS.has(k))) {
17336
+ return { action: "set", summary: `Forbidden path segment in "${path3}"`, changed: false, isError: true };
17337
+ }
17338
+ try {
17339
+ target.setByPath(path3, value);
17340
+ } catch (err) {
17341
+ return {
17342
+ action: "set",
17343
+ summary: `Config error: ${err instanceof Error ? err.message : String(err)}`,
17344
+ changed: false,
17345
+ isError: true
17346
+ };
17347
+ }
17348
+ return { action: "set", summary: `Set ${path3} = ${value}`, changed: true, isError: false };
17349
+ }
17350
+ return { action: "usage", summary: CONFIG_USAGE, changed: false, isError: true };
17351
+ }
17352
+
17256
17353
  // src/web/commands/security-commands.ts
17257
17354
  async function handleConfig(args, ctx) {
17258
- const sub = args[0];
17259
- if (sub === "show" || !sub) {
17260
- ctx.send({ type: "info", message: `\u2699\uFE0F Configuration:
17355
+ const outcome = applyConfigCommand(args, ctx.config);
17356
+ if (outcome.action === "show" || outcome.action === "wizard") {
17357
+ const json = outcome.json ?? JSON.stringify(maskConfigSecrets(ctx.config.toJSON()), null, 2);
17358
+ ctx.send({ type: "info", message: `\u2699\uFE0F Configuration (secrets masked):
17261
17359
  \`\`\`json
17262
- ${ctx.config.toFormattedJSON()}
17360
+ ${json}
17263
17361
  \`\`\`` });
17264
- } else if (sub === "get" && args[1]) {
17265
- const val = ctx.config.getByPath(args[1]);
17266
- const display = typeof val === "object" ? JSON.stringify(val, null, 2) : String(val ?? "undefined");
17267
- ctx.send({ type: "info", message: `${args[1]} = ${display}` });
17268
- } else if (sub === "set" && args[1] && args[2] !== void 0) {
17269
- try {
17270
- ctx.config.setByPath(args[1], args.slice(2).join(" "));
17271
- ctx.send({ type: "info", message: `\u2713 ${args[1]} = ${args.slice(2).join(" ")}` });
17272
- } catch (err) {
17273
- ctx.send({ type: "error", message: `Config error: ${err.message}` });
17274
- }
17275
- } else {
17276
- ctx.send({ type: "info", message: "Usage: /config [show] | /config get <key> | /config set <key> <value>" });
17362
+ return;
17277
17363
  }
17364
+ ctx.send({
17365
+ type: outcome.isError ? "error" : "info",
17366
+ message: (outcome.changed ? "\u2713 " : "") + (outcome.summary ?? "")
17367
+ });
17278
17368
  }
17279
17369
  async function handleDoctor(_args, ctx) {
17280
17370
  const report = buildDoctorReport({
@@ -17819,6 +17909,8 @@ var SessionHandler = class {
17819
17909
  permissionProfile: this.config.get("defaultPermissionProfile") ?? "legacy",
17820
17910
  tokenUsage: { ...this.sessionTokenUsage },
17821
17911
  costUsd,
17912
+ costCurrency: getCostCurrency(),
17913
+ costCnyPerUsd: CNY_PER_USD,
17822
17914
  costPricingUnknown,
17823
17915
  providers: providerList,
17824
17916
  branches,
@@ -19619,6 +19711,7 @@ async function startWebServer(options = {}) {
19619
19711
  console.log(` Skills: ${count} available`);
19620
19712
  }
19621
19713
  }
19714
+ setCostCurrency(config.get("ui").currency);
19622
19715
  const shared = {
19623
19716
  config,
19624
19717
  costTracker: new CostTracker(config.getConfigDir()),
@@ -19698,6 +19791,29 @@ async function startWebServer(options = {}) {
19698
19791
  clientDir = join26(process.cwd(), "src", "web", "client");
19699
19792
  }
19700
19793
  console.log(` Static files: ${clientDir}`);
19794
+ const PRECOMPRESSED_TYPES = {
19795
+ ".js": "text/javascript; charset=utf-8",
19796
+ ".css": "text/css; charset=utf-8",
19797
+ ".html": "text/html; charset=utf-8",
19798
+ ".json": "application/json; charset=utf-8",
19799
+ ".svg": "image/svg+xml",
19800
+ ".map": "application/json; charset=utf-8"
19801
+ };
19802
+ app.get(/.*/, (req, res, next) => {
19803
+ const ext = extname3(req.path).toLowerCase();
19804
+ const contentType = PRECOMPRESSED_TYPES[ext];
19805
+ if (!contentType) return next();
19806
+ const accept = String(req.headers["accept-encoding"] ?? "");
19807
+ const encoding = /\bbr\b/.test(accept) ? "br" : /\bgzip\b/.test(accept) ? "gzip" : null;
19808
+ if (!encoding) return next();
19809
+ const target = resolvePath(clientDir, `.${req.path}`) + (encoding === "br" ? ".br" : ".gz");
19810
+ if (!target.startsWith(clientDir) || !existsSync31(target)) return next();
19811
+ res.setHeader("Content-Type", contentType);
19812
+ res.setHeader("Content-Encoding", encoding);
19813
+ res.setHeader("Vary", "Accept-Encoding");
19814
+ if (req.path.startsWith("/vendor/")) res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
19815
+ createReadStream(target).pipe(res);
19816
+ });
19701
19817
  app.use("/vendor", express.static(join26(clientDir, "vendor"), { maxAge: "1y", immutable: true }));
19702
19818
  app.use(express.static(clientDir));
19703
19819
  app.get("/api/status", (_req, res) => {
@@ -158,7 +158,7 @@ ${content}`);
158
158
  }
159
159
  }
160
160
  async function runTaskMode(config, providers, configManager, topic) {
161
- const { TaskOrchestrator } = await import("./task-orchestrator-PNLI3V36.js");
161
+ const { TaskOrchestrator } = await import("./task-orchestrator-MFYEKR2I.js");
162
162
  const orchestrator = new TaskOrchestrator(config, providers, configManager);
163
163
  let interrupted = false;
164
164
  const onSigint = () => {
package/dist/index.js CHANGED
@@ -25,23 +25,14 @@ import {
25
25
  sessionHasMeaningfulContent,
26
26
  setupProxy,
27
27
  stripRoutingTags
28
- } from "./chunk-S3F5LOV3.js";
28
+ } from "./chunk-BFPF3JF2.js";
29
29
  import {
30
30
  CostTracker,
31
31
  computeCost,
32
32
  formatCost,
33
- getPricing
34
- } from "./chunk-R7GERZDA.js";
35
- import {
36
- buildReviewPrompt,
37
- buildSecurityReviewPrompt
38
- } from "./chunk-HLWUDRBO.js";
39
- import {
40
- NO_THINKING,
41
- applyThinkingFlag,
42
- chatParamsFrom,
43
- thinkingParamsFor
44
- } from "./chunk-6YZEZFX5.js";
33
+ getPricing,
34
+ setCostCurrency
35
+ } from "./chunk-JT6UN5C6.js";
45
36
  import {
46
37
  ToolExecutor,
47
38
  ToolRegistry,
@@ -63,7 +54,23 @@ import {
63
54
  setMaxOutputCap,
64
55
  spawnAgentContext,
65
56
  undoStack
66
- } from "./chunk-DJNGUPM3.js";
57
+ } from "./chunk-V26ZMB3D.js";
58
+ import {
59
+ buildReviewPrompt,
60
+ buildSecurityReviewPrompt
61
+ } from "./chunk-HLWUDRBO.js";
62
+ import {
63
+ NO_THINKING,
64
+ applyThinkingFlag,
65
+ chatParamsFrom,
66
+ thinkingParamsFor
67
+ } from "./chunk-6YZEZFX5.js";
68
+ import {
69
+ buildChatIndex,
70
+ clearChatIndex,
71
+ getChatIndexStatus,
72
+ searchChatMemory
73
+ } from "./chunk-6RPGQ5CG.js";
67
74
  import {
68
75
  addMemoryEntry,
69
76
  backupMemoryStore,
@@ -88,11 +95,12 @@ import {
88
95
  touchMemoryReferences,
89
96
  updateMemoryApproval,
90
97
  updateMemoryEntry
91
- } from "./chunk-QPPUYCRF.js";
98
+ } from "./chunk-4UNRDXZV.js";
92
99
  import "./chunk-GLSR2NR3.js";
93
100
  import "./chunk-UUSRWSSX.js";
94
101
  import "./chunk-CKH4KQ4E.js";
95
102
  import "./chunk-BXP6YZ2P.js";
103
+ import "./chunk-KHYD3WXE.js";
96
104
  import {
97
105
  initTheme,
98
106
  theme
@@ -101,19 +109,17 @@ import {
101
109
  SessionManager,
102
110
  getContentText
103
111
  } from "./chunk-OBULDJSU.js";
112
+ import "./chunk-NYNSYLFY.js";
113
+ import {
114
+ DEFAULT_PATTERNS,
115
+ scanString
116
+ } from "./chunk-B5TYJO7V.js";
104
117
  import {
105
118
  buildDoctorReport,
106
119
  formatDoctorReport,
107
120
  loadContextFiles,
108
121
  writeCrashLog
109
- } from "./chunk-6PROC2JO.js";
110
- import {
111
- ProviderRegistry,
112
- listBuiltInProviderMetadata
113
- } from "./chunk-AUEX6RNY.js";
114
- import {
115
- ConfigManager
116
- } from "./chunk-5IUFUCIT.js";
122
+ } from "./chunk-PG7O7N7D.js";
117
123
  import {
118
124
  describePlugin,
119
125
  getActivePluginAssets,
@@ -130,7 +136,14 @@ import {
130
136
  trustHook,
131
137
  trustPlugin,
132
138
  untrustHook
133
- } from "./chunk-5PRWBJCI.js";
139
+ } from "./chunk-PDRAOFGI.js";
140
+ import {
141
+ ProviderRegistry,
142
+ listBuiltInProviderMetadata
143
+ } from "./chunk-AUEX6RNY.js";
144
+ import {
145
+ ConfigManager
146
+ } from "./chunk-PMRU2CAF.js";
134
147
  import {
135
148
  CONTENT_ONLY_STREAM_REMINDER,
136
149
  TEE_FINAL_USER_NUDGE,
@@ -161,10 +174,16 @@ import {
161
174
  getGitContext,
162
175
  getGitRoot
163
176
  } from "./chunk-HOSJZMQS.js";
177
+ import {
178
+ atomicWriteFileSync
179
+ } from "./chunk-IW3Q7AE5.js";
180
+ import {
181
+ applyConfigCommand
182
+ } from "./chunk-XNFIYS7G.js";
164
183
  import {
165
184
  fileCheckpoints
166
185
  } from "./chunk-4BKXL7SM.js";
167
- import "./chunk-V6KQ67VF.js";
186
+ import "./chunk-OSYK6D4G.js";
168
187
  import {
169
188
  AGENTIC_BEHAVIOR_GUIDELINE,
170
189
  AUTHOR,
@@ -182,22 +201,7 @@ import {
182
201
  SKILLS_DIR_NAME,
183
202
  VERSION,
184
203
  buildUserIdentityPrompt
185
- } from "./chunk-3TOMHXDW.js";
186
- import {
187
- buildChatIndex,
188
- clearChatIndex,
189
- getChatIndexStatus,
190
- searchChatMemory
191
- } from "./chunk-6RPGQ5CG.js";
192
- import "./chunk-KHYD3WXE.js";
193
- import "./chunk-NYNSYLFY.js";
194
- import {
195
- DEFAULT_PATTERNS,
196
- scanString
197
- } from "./chunk-B5TYJO7V.js";
198
- import {
199
- atomicWriteFileSync
200
- } from "./chunk-IW3Q7AE5.js";
204
+ } from "./chunk-FT3WS5PG.js";
201
205
 
202
206
  // src/index.ts
203
207
  import { program } from "commander";
@@ -1403,7 +1407,7 @@ No tools match "${filter}".
1403
1407
  const { join: join6 } = await import("path");
1404
1408
  const { existsSync: existsSync6 } = await import("fs");
1405
1409
  const { getGitRoot: getGitRoot2 } = await import("./git-context-EXOEHQSF.js");
1406
- const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-IO5VJLEE.js");
1410
+ const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-Y43DJFGV.js");
1407
1411
  const { approveProject, hashMcpFile } = await import("./project-trust-NKYHL3VZ.js");
1408
1412
  const cwd = process.cwd();
1409
1413
  const projectRoot = getGitRoot2(cwd) ?? cwd;
@@ -1614,57 +1618,24 @@ function createSecurityCommands() {
1614
1618
  description: "Configuration: wizard, get/set values, show all",
1615
1619
  usage: "/config [set <path> <value> | get <path> | show]",
1616
1620
  async execute(args, ctx) {
1617
- const sub = args[0]?.toLowerCase();
1618
- const config = ctx.config;
1619
- if (!sub) {
1621
+ const outcome = applyConfigCommand(args, ctx.config);
1622
+ if (outcome.action === "wizard") {
1620
1623
  await ctx.runSetupWizard();
1621
1624
  return;
1622
1625
  }
1623
- if (sub === "show") {
1624
- const masked = config.toJSON();
1625
- if (masked.apiKeys && typeof masked.apiKeys === "object") {
1626
- const keys = masked.apiKeys;
1627
- for (const key of Object.keys(keys)) {
1628
- const val = keys[key];
1629
- if (typeof val === "string" && val.length > 8) {
1630
- keys[key] = val.slice(0, 4) + "****" + val.slice(-4);
1631
- }
1632
- }
1633
- }
1634
- console.log(JSON.stringify(masked, null, 2));
1626
+ if (outcome.action === "show") {
1627
+ console.log(outcome.json);
1635
1628
  return;
1636
1629
  }
1637
- if (sub === "get") {
1638
- const path = args[1]?.trim();
1639
- if (!path) {
1640
- console.log(theme.warning("Usage: /config get <path> (e.g. ui.theme)"));
1641
- return;
1642
- }
1643
- const val = config.getByPath(path);
1644
- if (val === void 0) {
1645
- console.log(theme.dim(` ${path} = (undefined)`));
1646
- } else {
1647
- console.log(theme.dim(` ${path} = `) + chalk2.white(typeof val === "object" ? JSON.stringify(val) : String(val)));
1648
- }
1630
+ if (outcome.isError) {
1631
+ console.log(theme.warning(` ${outcome.summary}`));
1649
1632
  return;
1650
1633
  }
1651
- if (sub === "set") {
1652
- const path = args[1]?.trim();
1653
- const value = args.slice(2).join(" ").trim();
1654
- if (!path || value === "") {
1655
- console.log(theme.warning("Usage: /config set <path> <value> (e.g. ui.theme light)"));
1656
- return;
1657
- }
1658
- const FORBIDDEN_KEYS = ["__proto__", "constructor", "prototype"];
1659
- if (path.split(".").some((k) => FORBIDDEN_KEYS.includes(k))) {
1660
- console.log(theme.error(` \u2717 Forbidden path segment: ${path}`));
1661
- return;
1662
- }
1663
- config.setByPath(path, value);
1664
- console.log(theme.success(` \u2713 Set ${path} = ${value}`));
1634
+ if (outcome.changed) {
1635
+ console.log(theme.success(` \u2713 ${outcome.summary}`));
1665
1636
  return;
1666
1637
  }
1667
- console.log(theme.warning("Usage: /config [set <path> <value> | get <path> | show]"));
1638
+ console.log(theme.dim(` ${outcome.summary}`));
1668
1639
  }
1669
1640
  },
1670
1641
  {
@@ -2356,7 +2327,7 @@ function createReviewCommands() {
2356
2327
  usage: "/test [command|filter]",
2357
2328
  async execute(args, ctx) {
2358
2329
  try {
2359
- const { executeTests } = await import("./run-tests-FZSYHWYX.js");
2330
+ const { executeTests } = await import("./run-tests-UTES6HCT.js");
2360
2331
  const argStr = args.join(" ").trim();
2361
2332
  let testArgs = {};
2362
2333
  if (argStr) {
@@ -5636,6 +5607,7 @@ Session '${this.resumeSessionId}' not found.
5636
5607
  }
5637
5608
  const cfgOutputCap = this.config.get("maxToolOutputChars");
5638
5609
  if (typeof cfgOutputCap === "number" && cfgOutputCap > 0) setMaxOutputCap(cfgOutputCap);
5610
+ setCostCurrency(this.config.get("ui").currency);
5639
5611
  if (welcomeModelInfo?.contextWindow) setContextWindow(welcomeModelInfo.contextWindow);
5640
5612
  if (this.resumeSessionId) {
5641
5613
  const session = this.sessions.current;
@@ -7519,12 +7491,26 @@ program.option("--provider <name>", `AI provider to use (${builtInProviderIds},
7519
7491
  await startRepl(options);
7520
7492
  }
7521
7493
  });
7522
- program.command("config").description("Configure API keys and preferences").action(async () => {
7494
+ program.command("config [action] [path] [value...]").description("Configure API keys and preferences: wizard (no args) | show | get <path> | set <path> <value>").action(async (action, path, valueParts) => {
7523
7495
  const config = new ConfigManager();
7524
- const { SetupWizard } = await import("./setup-wizard-S55ICNHH.js");
7525
- const wizard = new SetupWizard(config);
7526
- await wizard.runFull();
7527
- console.log("Configuration saved.");
7496
+ if (!action) {
7497
+ const { SetupWizard } = await import("./setup-wizard-S55ICNHH.js");
7498
+ const wizard = new SetupWizard(config);
7499
+ await wizard.runFull();
7500
+ console.log("Configuration saved.");
7501
+ return;
7502
+ }
7503
+ const { applyConfigCommand: applyConfigCommand2 } = await import("./config-command-E5DHADEV.js");
7504
+ const outcome = applyConfigCommand2([action, ...path ? [path] : [], ...valueParts ?? []], config);
7505
+ if (outcome.action === "show") {
7506
+ console.log(outcome.json);
7507
+ return;
7508
+ }
7509
+ if (outcome.isError) {
7510
+ console.error(outcome.summary);
7511
+ process.exit(1);
7512
+ }
7513
+ console.log(outcome.changed ? `\u2713 ${outcome.summary}` : outcome.summary);
7528
7514
  });
7529
7515
  program.command("providers").description("List all AI providers and their configuration status").action(async () => {
7530
7516
  const config = new ConfigManager();
@@ -7560,7 +7546,7 @@ program.command("web").description("Start Web UI server with browser-based chat
7560
7546
  console.error("Error: Invalid port number. Must be between 1 and 65535.");
7561
7547
  process.exit(1);
7562
7548
  }
7563
- const { startWebServer } = await import("./server-WTJSM2MT.js");
7549
+ const { startWebServer } = await import("./server-R56CVHCM.js");
7564
7550
  await startWebServer({ port, host: options.host });
7565
7551
  });
7566
7552
  program.command("user [action] [username]").description("Manage Web UI users (list | create <name> | delete <name> | reset-password <name> | logout-all <name> | migrate <name>)").action(async (action, username) => {
@@ -7727,11 +7713,11 @@ program.command("sessions").description("List recent conversation sessions").opt
7727
7713
  console.log(footer + "\n");
7728
7714
  });
7729
7715
  program.command("usage").description("Show token + cost usage grouped by provider/model (cross-session)").option("--days <n>", "Only the last N days (inclusive of today)").option("--month <ym>", "Only a specific month, format YYYY-MM (e.g. 2026-06)").option("--json", "Output as JSON (for scripting)").action(async (options) => {
7730
- const { runUsageCli } = await import("./usage-GVFUVYUG.js");
7716
+ const { runUsageCli } = await import("./usage-FHX7PQQH.js");
7731
7717
  await runUsageCli(options);
7732
7718
  });
7733
7719
  program.command("doctor").description("Health check: API keys, config, MCP, recent crashes, tool usage, disk usage").option("--json", "Output as JSON (for scripting)").option("--reset-stats", "Reset accumulated tool usage statistics").action(async (options) => {
7734
- const { runDoctorCli } = await import("./doctor-cli-ZU4E2DDL.js");
7720
+ const { runDoctorCli } = await import("./doctor-cli-RZGZB2TF.js");
7735
7721
  const argv = process.argv.slice(2);
7736
7722
  await runDoctorCli({
7737
7723
  json: !!options.json || argv.includes("--json"),
@@ -7740,7 +7726,7 @@ program.command("doctor").description("Health check: API keys, config, MCP, rece
7740
7726
  });
7741
7727
  program.command("batch <action> [arg] [arg2]").description("Anthropic Message Batches: submit | list | status <id> | results <id> [out] | cancel <id>").option("--dry-run", "Parse and validate input without submitting (submit only)").action(async (action, arg, arg2, options) => {
7742
7728
  try {
7743
- const batch = await import("./batch-HUOYPVJQ.js");
7729
+ const batch = await import("./batch-FPDT2USZ.js");
7744
7730
  switch (action) {
7745
7731
  case "submit":
7746
7732
  if (!arg) {
@@ -7783,7 +7769,7 @@ program.command("batch <action> [arg] [arg2]").description("Anthropic Message Ba
7783
7769
  }
7784
7770
  });
7785
7771
  program.command("mcp-serve").description("Start an MCP server over STDIO, exposing aicli's built-in tools to Claude Desktop / Cursor / other MCP clients").option("--allow-destructive", "Allow bash / run_interactive / task_create (always destructive in MCP mode)").option("--allow-outside-cwd", "Allow tool path arguments to escape the sandbox root \u2014 disabled by default").option("--tools <list>", "Comma-separated whitelist of tools to expose (default: all eligible tools)").option("--cwd <path>", "Working directory AND sandbox root (default: current directory)").action(async (options) => {
7786
- const { startMcpServer } = await import("./server-ZSTVYSYC.js");
7772
+ const { startMcpServer } = await import("./server-IGCCSX4B.js");
7787
7773
  await startMcpServer({
7788
7774
  allowDestructive: !!options.allowDestructive,
7789
7775
  allowOutsideCwd: !!options.allowOutsideCwd,
@@ -7796,7 +7782,7 @@ program.command("pr <action> [target]").description("PR review helpers: review |
7796
7782
  console.error(`Unknown pr action: ${action}. Use review | security-review | summarize.`);
7797
7783
  process.exit(1);
7798
7784
  }
7799
- const { runPrCli } = await import("./pr-Z4O5H6I3.js");
7785
+ const { runPrCli } = await import("./pr-NTQ3N4B4.js");
7800
7786
  const result = await runPrCli({
7801
7787
  action,
7802
7788
  target,
@@ -7816,8 +7802,8 @@ program.command("pr <action> [target]").description("PR review helpers: review |
7816
7802
  process.exit(result.exitCode);
7817
7803
  });
7818
7804
  program.command("ci").description("Headless PR review (code + security) \u2014 reads git/gh diff, optionally posts to PR. Designed for GitHub Actions.").option("--pr <num>", "PR number or URL; diff fetched via gh pr diff <value>", (v) => /^#?\d+$/.test(v) ? parseInt(v.replace(/^#/, ""), 10) : v).option("--base <ref>", "Base ref for git diff <ref>...HEAD (ignored when --pr set)").option("--post", "Post review as a PR comment (requires gh CLI + GH_TOKEN, needs --pr)").option("--no-update", "Always create a new comment instead of updating the previous aicli review").option("--skip-code", "Skip the code review section").option("--skip-security", "Skip the security review section").option("--detailed", "Use the detailed code-review prompt").option("--max-diff <n>", "Max diff chars sent to the model (default 30000)", (v) => parseInt(v, 10)).option("--provider <id>", "Override provider (default: config.defaultProvider)").option("--model <id>", "Override model").option("--dry-run", "Print result to stdout instead of posting (overrides --post)").option("--json", "Output a structured JSON report").option("--markdown", "Output Markdown report (default)").option("--sarif", "Output SARIF 2.1.0 for code scanning artifacts").option("--fail-on-security-high", "Fail when the security review contains HIGH/CRITICAL findings (default)").option("--no-fail-on-security-high", "Do not fail on security HIGH/CRITICAL findings").option("--fail-on-test-failure", "Fail when the report mentions test failures (default)").option("--no-fail-on-test-failure", "Do not fail on test failure findings").option("--fail-on-lint-failure", "Fail when the report mentions lint/typecheck failures (default)").option("--no-fail-on-lint-failure", "Do not fail on lint/typecheck failure findings").action(async (options) => {
7819
- const { runCi } = await import("./ci-4QS2J7BG.js");
7820
- const { formatCiResult } = await import("./ci-format-6L6M67WC.js");
7805
+ const { runCi } = await import("./ci-VPN5RWCO.js");
7806
+ const { formatCiResult } = await import("./ci-format-GKXVCVME.js");
7821
7807
  const formats = [options.json, options.markdown, options.sarif].filter(Boolean).length;
7822
7808
  if (formats > 1) {
7823
7809
  console.error("Choose only one output format: --json, --markdown, or --sarif.");
@@ -7975,7 +7961,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
7975
7961
  config.get("customProviders"),
7976
7962
  config.getConfigDir()
7977
7963
  );
7978
- const { startHub } = await import("./hub-AMDWXSKZ.js");
7964
+ const { startHub } = await import("./hub-FJWP6SDG.js");
7979
7965
  await startHub(
7980
7966
  {
7981
7967
  topic: topic ?? "",
@@ -28,11 +28,11 @@ import {
28
28
  touchMemoryReferences,
29
29
  updateMemoryApproval,
30
30
  updateMemoryEntry
31
- } from "./chunk-QPPUYCRF.js";
32
- import "./chunk-HOSJZMQS.js";
33
- import "./chunk-3TOMHXDW.js";
31
+ } from "./chunk-4UNRDXZV.js";
34
32
  import "./chunk-B5TYJO7V.js";
33
+ import "./chunk-HOSJZMQS.js";
35
34
  import "./chunk-IW3Q7AE5.js";
35
+ import "./chunk-FT3WS5PG.js";
36
36
  export {
37
37
  addMemoryEntry,
38
38
  backupMemoryStore,
@@ -27,9 +27,9 @@ import {
27
27
  touchMemoryReferences,
28
28
  updateMemoryApproval,
29
29
  updateMemoryEntry
30
- } from "./chunk-KIHNZBEA.js";
30
+ } from "./chunk-VPXNLE7E.js";
31
31
  import "./chunk-YVTASHS5.js";
32
- import "./chunk-4HTJMLFY.js";
32
+ import "./chunk-5JFRM47R.js";
33
33
  import "./chunk-6BUTA5VW.js";
34
34
  export {
35
35
  addMemoryEntry,