jinzd-ai-cli 0.4.309 → 0.4.311

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 (33) hide show
  1. package/dist/{batch-H4WWSZQ3.js → batch-ZGRYELZQ.js} +2 -2
  2. package/dist/{chunk-2E5W2E64.js → chunk-2PDBRPNS.js} +1 -1
  3. package/dist/{chunk-IW6Q66WS.js → chunk-2XI6LXBY.js} +4 -4
  4. package/dist/{chunk-EHMMBIZT.js → chunk-3L3PKTSK.js} +111 -2
  5. package/dist/{chunk-EAVX3RLD.js → chunk-7B2KVTGQ.js} +1 -1
  6. package/dist/{chunk-4BXTGXZ6.js → chunk-EHACKFNT.js} +1 -1
  7. package/dist/{chunk-K4F7QEGW.js → chunk-EWWHG3CR.js} +1 -1
  8. package/dist/{chunk-3GEO2LPO.js → chunk-IVHG47FR.js} +1 -1
  9. package/dist/{chunk-RBCKX2FZ.js → chunk-IXR2P7WK.js} +1 -1
  10. package/dist/{chunk-T42GXE7Y.js → chunk-K2VL22AX.js} +7 -7
  11. package/dist/{chunk-O7MMYJAD.js → chunk-L4VU5F7P.js} +19 -7
  12. package/dist/{chunk-RLERORUI.js → chunk-PWN7QNDK.js} +1 -1
  13. package/dist/{chunk-HXINWG37.js → chunk-ROUVNUZZ.js} +1 -1
  14. package/dist/{chunk-SCG2VBPB.js → chunk-UZIXHKF7.js} +4 -4
  15. package/dist/{chunk-3CNPJLVI.js → chunk-ZX4L2ZYI.js} +1 -1
  16. package/dist/{ci-H6GPHG4T.js → ci-FJR4SB57.js} +5 -5
  17. package/dist/{ci-format-U47GSGYU.js → ci-format-PZNBZT55.js} +2 -2
  18. package/dist/{constants-GYJTB6KI.js → constants-OV7XBTZI.js} +1 -1
  19. package/dist/{constants-SNJR6546.js → constants-RBP6YR3H.js} +1 -1
  20. package/dist/{doctor-cli-J6LAQ5LU.js → doctor-cli-GE4TWAXT.js} +5 -5
  21. package/dist/electron-server.js +136 -15
  22. package/dist/{hub-G5FMMTVZ.js → hub-TAGD646P.js} +1 -1
  23. package/dist/index.js +44 -24
  24. package/dist/{persistent-memory-EXJBXL33.js → persistent-memory-4JGH2RSD.js} +2 -2
  25. package/dist/{persistent-memory-LEE454DW.js → persistent-memory-Z5HYYVXL.js} +2 -2
  26. package/dist/{pr-6PUHVJ6K.js → pr-WQMSMNBR.js} +5 -5
  27. package/dist/{run-tests-33ZVQE3Q.js → run-tests-JZDYMCHO.js} +2 -2
  28. package/dist/{run-tests-2C7MWZBN.js → run-tests-NJMCA7A5.js} +2 -2
  29. package/dist/{server-AJH5TBVO.js → server-KOFF5RTB.js} +14 -14
  30. package/dist/{server-CYAB56O3.js → server-ORHXQROL.js} +5 -5
  31. package/dist/{task-orchestrator-HNRV3YUD.js → task-orchestrator-JS6JGL3N.js} +5 -5
  32. package/dist/{usage-ZN5DU6Z7.js → usage-TVBY2BCQ.js} +2 -2
  33. package/package.json +2 -2
@@ -55,7 +55,7 @@ import {
55
55
  touchMemoryReferences,
56
56
  updateMemoryApproval,
57
57
  updateMemoryEntry
58
- } from "./chunk-2E5W2E64.js";
58
+ } from "./chunk-2PDBRPNS.js";
59
59
  import {
60
60
  DEFAULT_PATTERNS,
61
61
  redactJson,
@@ -80,7 +80,7 @@ import {
80
80
  recoverGbkMojibake,
81
81
  runTestsTool,
82
82
  shellInvocation
83
- } from "./chunk-RLERORUI.js";
83
+ } from "./chunk-PWN7QNDK.js";
84
84
  import {
85
85
  getCurrentSessionKey,
86
86
  getExecutionConfigDir,
@@ -122,7 +122,7 @@ import {
122
122
  SUBAGENT_MAX_ROUNDS_LIMIT,
123
123
  VERSION,
124
124
  buildUserIdentityPrompt
125
- } from "./chunk-EAVX3RLD.js";
125
+ } from "./chunk-7B2KVTGQ.js";
126
126
 
127
127
  // src/web/access.ts
128
128
  import { randomBytes, timingSafeEqual } from "crypto";
@@ -4596,6 +4596,44 @@ var OPENROUTER_CONFIG = {
4596
4596
  var OpenRouterProvider = createStaticProviderClass(OPENROUTER_CONFIG);
4597
4597
 
4598
4598
  // src/providers/ollama.ts
4599
+ function resolveOllamaContextWindow(input) {
4600
+ if (isPositiveInt(input.runningContext)) {
4601
+ return { contextWindow: input.runningContext, source: "running" };
4602
+ }
4603
+ const numCtx = parseNumCtx(input.show?.parameters);
4604
+ if (numCtx !== void 0) return { contextWindow: numCtx, source: "modelfile" };
4605
+ const modelMax = readModelMaxContext(input.show?.model_info);
4606
+ if (modelMax !== void 0) return { contextWindow: modelMax, source: "model-max" };
4607
+ return { contextWindow: input.fallback, source: "estimate" };
4608
+ }
4609
+ function isPositiveInt(n) {
4610
+ return typeof n === "number" && Number.isInteger(n) && n > 0;
4611
+ }
4612
+ function parseNumCtx(parameters) {
4613
+ if (!parameters) return void 0;
4614
+ let found;
4615
+ for (const line of parameters.split("\n")) {
4616
+ const m = /^\s*num_ctx\s+(\d+)\s*$/.exec(line);
4617
+ if (m) found = Number(m[1]);
4618
+ }
4619
+ return isPositiveInt(found) ? found : void 0;
4620
+ }
4621
+ function readModelMaxContext(modelInfo) {
4622
+ if (!modelInfo) return void 0;
4623
+ const arch3 = modelInfo["general.architecture"];
4624
+ if (typeof arch3 === "string") {
4625
+ const v = modelInfo[`${arch3}.context_length`];
4626
+ if (isPositiveInt(v)) return v;
4627
+ }
4628
+ for (const [k, v] of Object.entries(modelInfo)) {
4629
+ if (k.endsWith(".context_length") && isPositiveInt(v)) return v;
4630
+ }
4631
+ return void 0;
4632
+ }
4633
+ function ollamaNativeBaseUrl(openAiBaseUrl) {
4634
+ return openAiBaseUrl.replace(/\/+$/, "").replace(/\/v1$/, "");
4635
+ }
4636
+ var NATIVE_API_TIMEOUT_MS = 3e3;
4599
4637
  var OllamaProvider = class extends OpenAICompatibleProvider {
4600
4638
  // 用 127.0.0.1 而非 localhost:Node.js 18+ 在 Windows 上优先解析 localhost 为 IPv6 (::1),
4601
4639
  // 但 Ollama 默认只监听 IPv4,导致连接失败。
@@ -4604,6 +4642,8 @@ var OllamaProvider = class extends OpenAICompatibleProvider {
4604
4642
  // 本地推理可能较慢,默认 2 分钟
4605
4643
  /** 动态模型列表 */
4606
4644
  dynamicModels = [];
4645
+ /** 原生 API 根地址(`/api/show`、`/api/ps`),initialize 时由 baseUrl 推出 */
4646
+ nativeBaseUrl = ollamaNativeBaseUrl(this.defaultBaseUrl);
4607
4647
  info = {
4608
4648
  id: "ollama",
4609
4649
  displayName: "Ollama (Local)",
@@ -4615,6 +4655,7 @@ var OllamaProvider = class extends OpenAICompatibleProvider {
4615
4655
  };
4616
4656
  async initialize(apiKey, options) {
4617
4657
  const baseUrl = options?.baseUrl ?? this.defaultBaseUrl;
4658
+ this.nativeBaseUrl = ollamaNativeBaseUrl(baseUrl);
4618
4659
  await super.initialize(apiKey || "ollama", { ...options, baseUrl });
4619
4660
  await this.tryConnect(true);
4620
4661
  }
@@ -4632,10 +4673,11 @@ var OllamaProvider = class extends OpenAICompatibleProvider {
4632
4673
  if (modelIds.length === 0) {
4633
4674
  return false;
4634
4675
  }
4676
+ const contextWindows = await this.detectContextWindows(modelIds);
4635
4677
  this.dynamicModels = modelIds.map((id) => ({
4636
4678
  id,
4637
4679
  displayName: id,
4638
- contextWindow: this.estimateContextWindow(id),
4680
+ contextWindow: contextWindows.get(id) ?? this.estimateContextWindow(id),
4639
4681
  supportsStreaming: true,
4640
4682
  supportsThinking: false
4641
4683
  }));
@@ -4656,7 +4698,74 @@ var OllamaProvider = class extends OpenAICompatibleProvider {
4656
4698
  return false;
4657
4699
  }
4658
4700
  }
4659
- /** 根据模型名估算上下文窗口 */
4701
+ /**
4702
+ * 经原生 API 查每个模型的 contextWindow(规则见 resolveOllamaContextWindow)。
4703
+ * 任何一步失败都只影响该模型、退回按名字猜,绝不让模型列表整体失败——
4704
+ * 模型列表拿到了就说明服务是通的,上下文探测只是锦上添花。
4705
+ */
4706
+ async detectContextWindows(modelIds) {
4707
+ const result = /* @__PURE__ */ new Map();
4708
+ const [running, digests] = await Promise.all([this.fetchRunningContexts(), this.fetchDigests()]);
4709
+ await Promise.all(modelIds.map(async (id) => {
4710
+ const show = await this.fetchNative("/api/show", { model: id });
4711
+ if (running.size === 0 && !show) return;
4712
+ const digest = digests.get(id);
4713
+ const { contextWindow } = resolveOllamaContextWindow({
4714
+ runningContext: digest && running.get(digest) || running.get(id),
4715
+ show,
4716
+ fallback: this.estimateContextWindow(id)
4717
+ });
4718
+ result.set(id, contextWindow);
4719
+ }));
4720
+ return result;
4721
+ }
4722
+ /** `/api/ps`:已加载模型的名字与 digest → 实际上下文窗口。未加载的模型不在其中。 */
4723
+ async fetchRunningContexts() {
4724
+ const running = /* @__PURE__ */ new Map();
4725
+ const ps = await this.fetchNative("/api/ps");
4726
+ for (const m of ps?.models ?? []) {
4727
+ if (!isPositiveInt(m.context_length)) continue;
4728
+ for (const key of [m.digest, m.name, m.model]) {
4729
+ if (key) running.set(key, m.context_length);
4730
+ }
4731
+ }
4732
+ return running;
4733
+ }
4734
+ /** `/api/tags`:模型名 → digest,用于把别名对到 /api/ps 里以原名加载的同一模型 */
4735
+ async fetchDigests() {
4736
+ const digests = /* @__PURE__ */ new Map();
4737
+ const tags = await this.fetchNative("/api/tags");
4738
+ for (const m of tags?.models ?? []) {
4739
+ if (!m.digest) continue;
4740
+ for (const name of [m.name, m.model]) {
4741
+ if (name) digests.set(name, m.digest);
4742
+ }
4743
+ }
4744
+ return digests;
4745
+ }
4746
+ /**
4747
+ * 调 Ollama 原生 API,失败一律返回 undefined。
4748
+ * 本地地址必须显式走直连 Agent:setupProxy() 装的全局 ProxyAgent 不认 localhost 例外,
4749
+ * 裸 fetch 会把 127.0.0.1:11434 发给代理(同 isLoopbackBaseUrl 那次的坑)。
4750
+ */
4751
+ async fetchNative(path3, body) {
4752
+ try {
4753
+ const { Agent: Agent2, fetch: undiciFetch } = await import("undici");
4754
+ const url = `${this.nativeBaseUrl}${path3}`;
4755
+ const init = {
4756
+ method: body ? "POST" : "GET",
4757
+ headers: body ? { "content-type": "application/json" } : void 0,
4758
+ body: body ? JSON.stringify(body) : void 0,
4759
+ signal: AbortSignal.timeout(NATIVE_API_TIMEOUT_MS)
4760
+ };
4761
+ const res = isLoopbackBaseUrl(url) ? await undiciFetch(url, { ...init, dispatcher: new Agent2() }) : await undiciFetch(url, init);
4762
+ if (!res.ok) return void 0;
4763
+ return await res.json();
4764
+ } catch {
4765
+ return void 0;
4766
+ }
4767
+ }
4768
+ /** 根据模型名估算上下文窗口(原生 API 不可用时的兜底) */
4660
4769
  estimateContextWindow(modelName) {
4661
4770
  const name = modelName.toLowerCase();
4662
4771
  if (name.includes("llama3") || name.includes("llama-3")) return 131072;
@@ -7091,9 +7200,10 @@ ${err.message}`;
7091
7200
  }
7092
7201
  if (BINARY_EXTENSIONS.has(ext)) {
7093
7202
  if (IMAGE_EXTENSIONS.has(ext)) {
7203
+ const ref = /\s/.test(filePath) ? `@"${filePath}"` : `@${filePath}`;
7094
7204
  return `[Image file: ${filePath} (${ext})]
7095
7205
  read_file cannot return image content \u2014 tool results are text-only, so no tool can put an image into your context.
7096
- To have an image looked at, ask the USER to reference it from their input line with @${filePath} (they can use a glob for a batch, e.g. @dir/*.png, up to ${MAX_GLOB_MATCHES} at a time). A vision-capable model must be active, or the reference is rejected.
7206
+ To have an image looked at, ask the USER to reference it from their input line with ${ref} (quote the path exactly like that when it contains spaces; they can use a glob for a batch, e.g. @dir/*.png, up to ${MAX_GLOB_MATCHES} at a time). A vision-capable model must be active, or the reference is rejected.
7097
7207
  Do NOT claim you inspected this image \u2014 you have not seen it.`;
7098
7208
  }
7099
7209
  return `[Binary file: ${filePath} (${ext})]
@@ -8830,6 +8940,16 @@ function norm(p) {
8830
8940
  }
8831
8941
  return process.platform === "win32" ? abs.toLowerCase() : abs;
8832
8942
  }
8943
+ function systemPathCandidates(p) {
8944
+ const out = /* @__PURE__ */ new Set([norm(p), resolve5(p)]);
8945
+ if (process.platform === "darwin") {
8946
+ for (const c of [...out]) {
8947
+ const m = /^\/private(\/(?:etc|var|tmp)(?:\/|$).*)$/.exec(c);
8948
+ if (m) out.add(m[1]);
8949
+ }
8950
+ }
8951
+ return [...out];
8952
+ }
8833
8953
  function homeRel(p) {
8834
8954
  const abs = norm(p);
8835
8955
  const h = norm(home);
@@ -8893,10 +9013,11 @@ function classifyWritePath(path3) {
8893
9013
  if (abs.includes(`${sep2}.git${sep2}config`) || abs.includes(`${sep2}.git${sep2}config`.toLowerCase())) {
8894
9014
  return { sensitive: true, reason: ".git/config \u2014 repository identity" };
8895
9015
  }
9016
+ const sysCandidates = process.platform === "win32" ? [abs] : systemPathCandidates(path3);
8896
9017
  if (process.platform !== "win32") {
8897
9018
  const sysPrefixes = ["/etc/", "/usr/bin/", "/usr/sbin/", "/bin/", "/sbin/", "/boot/"];
8898
9019
  for (const pre of sysPrefixes) {
8899
- if (abs.startsWith(pre)) return { sensitive: true, reason: `system path (${pre})` };
9020
+ if (sysCandidates.some((c) => c.startsWith(pre))) return { sensitive: true, reason: `system path (${pre})` };
8900
9021
  }
8901
9022
  } else {
8902
9023
  const winSys = ["c:\\windows\\system32\\", "c:\\windows\\syswow64\\", "c:\\program files\\", "c:\\program files (x86)\\"];
@@ -8904,7 +9025,7 @@ function classifyWritePath(path3) {
8904
9025
  if (abs.startsWith(pre)) return { sensitive: true, reason: `system path (${pre})` };
8905
9026
  }
8906
9027
  }
8907
- if (abs.includes(`${sep2}cron.d${sep2}`) || abs.startsWith("/etc/cron") || abs.startsWith("/var/spool/cron/")) {
9028
+ if (abs.includes(`${sep2}cron.d${sep2}`) || sysCandidates.some((c) => c.startsWith("/etc/cron") || c.startsWith("/var/spool/cron/"))) {
8908
9029
  return { sensitive: true, reason: "cron scheduling" };
8909
9030
  }
8910
9031
  if (rel && (rel.startsWith("Library/LaunchAgents/") || rel.startsWith("Library/LaunchDaemons/"))) {
@@ -17258,7 +17379,7 @@ Cache: write=${cacheCreate} read=${cacheRead}` : "";
17258
17379
  Cost: ${formatCost(cost)}` : "";
17259
17380
  let memoryLine = "";
17260
17381
  try {
17261
- const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-EXJBXL33.js");
17382
+ const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-4JGH2RSD.js");
17262
17383
  const pending = countPendingMemories2(ctx.config.getConfigDir());
17263
17384
  if (pending > 0) memoryLine = `
17264
17385
  Memory: \u26A0 ${pending} pending approval \u2014 see the Memory panel or /memory`;
@@ -18246,7 +18367,7 @@ async function handleTest(args, ctx) {
18246
18367
  const isCommand = argStr.includes(" ") || /^(mvn|gradle|npm|pytest|cargo|go)\b/.test(argStr);
18247
18368
  testArgs = isCommand ? { command: argStr } : { filter: argStr };
18248
18369
  }
18249
- const runTests = ctx.runTests ?? (await import("./run-tests-2C7MWZBN.js")).executeTests;
18370
+ const runTests = ctx.runTests ?? (await import("./run-tests-NJMCA7A5.js")).executeTests;
18250
18371
  const report = await runTests(testArgs);
18251
18372
  ctx.send({ type: "info", message: report });
18252
18373
  } catch (err) {
@@ -18637,7 +18758,7 @@ async function handleMemory(args, ctx) {
18637
18758
  }
18638
18759
  if (intent.kind === "status") {
18639
18760
  const { getChatIndexStatus: getChatIndexStatus2 } = await import("./chat-index-RLVLQRRC.js");
18640
- const { listMemoryEntries: listMemoryEntries2, isMemoryExpired: isMemoryExpired2, formatMemoryForPrompt: formatMemoryForPrompt2 } = await import("./persistent-memory-EXJBXL33.js");
18761
+ const { listMemoryEntries: listMemoryEntries2, isMemoryExpired: isMemoryExpired2, formatMemoryForPrompt: formatMemoryForPrompt2 } = await import("./persistent-memory-4JGH2RSD.js");
18641
18762
  const memories = listMemoryEntries2(configDir, { includeExpired: true, includeRejected: true });
18642
18763
  const injected = formatMemoryForPrompt2(configDir, process.cwd(), ctx.config.get("memory")?.maxChars);
18643
18764
  const view = buildMemoryStatusView({
@@ -18660,7 +18781,7 @@ async function handleMemory(args, ctx) {
18660
18781
  return;
18661
18782
  }
18662
18783
  if (intent.kind === "recall") {
18663
- const { searchPersistentMemories: searchPersistentMemories2, touchMemoryReferences: touchMemoryReferences2 } = await import("./persistent-memory-EXJBXL33.js");
18784
+ const { searchPersistentMemories: searchPersistentMemories2, touchMemoryReferences: touchMemoryReferences2 } = await import("./persistent-memory-4JGH2RSD.js");
18664
18785
  const { searchChatMemory: searchChatMemory2 } = await import("./chat-index-RLVLQRRC.js");
18665
18786
  const persistentHits = searchPersistentMemories2(configDir, intent.query, process.cwd(), 3);
18666
18787
  if (persistentHits.length > 0) {
@@ -18781,7 +18902,7 @@ async function handleMemory(args, ctx) {
18781
18902
  ctx.handleMemoryManage(intent.action, args[1], intent.action === "expire" ? args[2] : void 0);
18782
18903
  } else if (intent.kind === "export") {
18783
18904
  if (args[1] === "md") {
18784
- const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-EXJBXL33.js");
18905
+ const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-4JGH2RSD.js");
18785
18906
  ctx.send({
18786
18907
  type: "export_data",
18787
18908
  format: "md",
@@ -19786,7 +19907,7 @@ No tools match "${filter}".
19786
19907
  const { join: join26 } = await import("path");
19787
19908
  const { existsSync: existsSync32 } = await import("fs");
19788
19909
  const { getGitRoot: getGitRoot2 } = await import("./git-context-VNCA2GU7.js");
19789
- const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-GYJTB6KI.js");
19910
+ const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-OV7XBTZI.js");
19790
19911
  const { approveProject, hashMcpFile } = await import("./project-trust-6CJB5ZMX.js");
19791
19912
  const cwd = process.cwd();
19792
19913
  const projectRoot = getGitRoot2(cwd) ?? cwd;
@@ -20705,7 +20826,7 @@ function createReviewCommands() {
20705
20826
  usage: "/test [command|filter]",
20706
20827
  async execute(args, ctx) {
20707
20828
  try {
20708
- const { executeTests } = await import("./run-tests-2C7MWZBN.js");
20829
+ const { executeTests } = await import("./run-tests-NJMCA7A5.js");
20709
20830
  const argStr = args.join(" ").trim();
20710
20831
  let testArgs = {};
20711
20832
  if (argStr) {
@@ -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-HNRV3YUD.js");
161
+ const { TaskOrchestrator } = await import("./task-orchestrator-JS6JGL3N.js");
162
162
  const orchestrator = new TaskOrchestrator(config, providers, configManager);
163
163
  let interrupted = false;
164
164
  const onSigint = () => {
package/dist/index.js CHANGED
@@ -24,7 +24,7 @@ import {
24
24
  setupProxy,
25
25
  snapshotFile,
26
26
  stripRoutingTags
27
- } from "./chunk-T42GXE7Y.js";
27
+ } from "./chunk-K2VL22AX.js";
28
28
  import {
29
29
  CostTracker,
30
30
  getPricing,
@@ -47,7 +47,7 @@ import {
47
47
  setMaxOutputCap,
48
48
  spawnAgentContext,
49
49
  undoStack
50
- } from "./chunk-O7MMYJAD.js";
50
+ } from "./chunk-L4VU5F7P.js";
51
51
  import "./chunk-HLWUDRBO.js";
52
52
  import {
53
53
  NO_THINKING,
@@ -60,7 +60,7 @@ import {
60
60
  countPendingMemories,
61
61
  detectStaleLegacyMarkdownEdit,
62
62
  formatMemoryForPrompt
63
- } from "./chunk-HXINWG37.js";
63
+ } from "./chunk-ROUVNUZZ.js";
64
64
  import "./chunk-RWRZVQCB.js";
65
65
  import "./chunk-B3MPYI4E.js";
66
66
  import "./chunk-M6HLYG33.js";
@@ -81,22 +81,22 @@ import {
81
81
  import {
82
82
  loadContextFiles,
83
83
  writeCrashLog
84
- } from "./chunk-SCG2VBPB.js";
84
+ } from "./chunk-UZIXHKF7.js";
85
85
  import {
86
86
  getActivePluginAssets,
87
87
  getPendingHookTrust,
88
88
  installFlushOnExit,
89
89
  mergePluginHooks,
90
90
  runLifecycleHooks
91
- } from "./chunk-4BXTGXZ6.js";
91
+ } from "./chunk-EHACKFNT.js";
92
92
  import "./chunk-RS7SKYTS.js";
93
93
  import {
94
94
  ProviderRegistry,
95
95
  listBuiltInProviderMetadata
96
- } from "./chunk-EHMMBIZT.js";
96
+ } from "./chunk-3L3PKTSK.js";
97
97
  import {
98
98
  ConfigManager
99
- } from "./chunk-RBCKX2FZ.js";
99
+ } from "./chunk-IXR2P7WK.js";
100
100
  import {
101
101
  CONTENT_ONLY_STREAM_REMINDER,
102
102
  TEE_FINAL_USER_NUDGE,
@@ -134,7 +134,7 @@ import {
134
134
  isInterrupted,
135
135
  requestInterrupt,
136
136
  resetInterrupt
137
- } from "./chunk-3GEO2LPO.js";
137
+ } from "./chunk-IVHG47FR.js";
138
138
  import {
139
139
  AGENTIC_BEHAVIOR_GUIDELINE,
140
140
  AUTHOR,
@@ -152,7 +152,7 @@ import {
152
152
  SKILLS_DIR_NAME,
153
153
  VERSION,
154
154
  buildUserIdentityPrompt
155
- } from "./chunk-3CNPJLVI.js";
155
+ } from "./chunk-ZX4L2ZYI.js";
156
156
  import "./chunk-SXIJLSVF.js";
157
157
 
158
158
  // src/index.ts
@@ -1125,21 +1125,41 @@ function expandGlob(rawPath, cwd) {
1125
1125
  return { kind: "ok", files };
1126
1126
  }
1127
1127
  var MAX_PATH_SPACE_TOKENS = 8;
1128
+ function stripQuoteChars(s) {
1129
+ return s.replace(/["']/g, "");
1130
+ }
1131
+ function quotesBalanced(s) {
1132
+ const dq = (s.match(/"/g) ?? []).length;
1133
+ const sq = (s.match(/'/g) ?? []).length;
1134
+ return dq % 2 === 0 && sq % 2 === 0 && (dq > 0 || sq > 0);
1135
+ }
1128
1136
  function expandUnquotedPath(input, pathStart, rawPath, cwd) {
1129
- const plain = { raw: rawPath, consumed: rawPath.length };
1137
+ const plain = { text: rawPath, path: rawPath, consumed: rawPath.length };
1130
1138
  if (existsSync2(resolve(cwd, rawPath))) return plain;
1131
1139
  let acc = rawPath;
1132
1140
  let consumed = rawPath.length;
1133
1141
  let rest = input.slice(pathStart + rawPath.length);
1142
+ let balancedFallback = null;
1143
+ const dequoted = stripQuoteChars(acc);
1144
+ if (dequoted !== acc && existsSync2(resolve(cwd, dequoted))) {
1145
+ return { text: acc, path: dequoted, consumed };
1146
+ }
1134
1147
  for (let i = 0; i < MAX_PATH_SPACE_TOKENS; i++) {
1135
1148
  const next = /^([ \t]+)(\S+)/.exec(rest);
1136
1149
  if (!next) break;
1137
1150
  acc += next[1] + next[2];
1138
1151
  consumed += next[0].length;
1139
1152
  rest = rest.slice(next[0].length);
1140
- if (existsSync2(resolve(cwd, acc))) return { raw: acc, consumed };
1153
+ if (existsSync2(resolve(cwd, acc))) return { text: acc, path: acc, consumed };
1154
+ const candidate = stripQuoteChars(acc);
1155
+ if (candidate !== acc) {
1156
+ if (existsSync2(resolve(cwd, candidate))) return { text: acc, path: candidate, consumed };
1157
+ if (balancedFallback === null && quotesBalanced(acc)) {
1158
+ balancedFallback = { text: acc, path: candidate, consumed };
1159
+ }
1160
+ }
1141
1161
  }
1142
- return plain;
1162
+ return balancedFallback ?? plain;
1143
1163
  }
1144
1164
  function parseAtReferences(input, cwd) {
1145
1165
  const atPattern = /@(?:"([^"]+)"|'([^']+)'|(\S+))/g;
@@ -1153,9 +1173,9 @@ function parseAtReferences(input, cwd) {
1153
1173
  if (match[3] !== void 0) {
1154
1174
  const pathStart = match.index + 1;
1155
1175
  const expanded = expandUnquotedPath(input, pathStart, rawPath, cwd);
1156
- if (expanded.consumed > rawPath.length) {
1157
- rawPath = expanded.raw;
1158
- matchedText = "@" + expanded.raw;
1176
+ if (expanded.consumed > rawPath.length || expanded.path !== rawPath) {
1177
+ rawPath = expanded.path;
1178
+ matchedText = "@" + expanded.text;
1159
1179
  atPattern.lastIndex = pathStart + expanded.consumed;
1160
1180
  }
1161
1181
  }
@@ -4068,7 +4088,7 @@ program.command("web").description("Start Web UI server with browser-based chat
4068
4088
  console.error("Error: Invalid port number. Must be between 1 and 65535.");
4069
4089
  process.exit(1);
4070
4090
  }
4071
- const { startWebServer } = await import("./server-AJH5TBVO.js");
4091
+ const { startWebServer } = await import("./server-KOFF5RTB.js");
4072
4092
  await startWebServer({ port, host: options.host, externalOrigin: options.externalOrigin });
4073
4093
  });
4074
4094
  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) => {
@@ -4235,11 +4255,11 @@ program.command("sessions").description("List recent conversation sessions").opt
4235
4255
  console.log(footer + "\n");
4236
4256
  });
4237
4257
  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) => {
4238
- const { runUsageCli } = await import("./usage-ZN5DU6Z7.js");
4258
+ const { runUsageCli } = await import("./usage-TVBY2BCQ.js");
4239
4259
  await runUsageCli(options);
4240
4260
  });
4241
4261
  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) => {
4242
- const { runDoctorCli } = await import("./doctor-cli-J6LAQ5LU.js");
4262
+ const { runDoctorCli } = await import("./doctor-cli-GE4TWAXT.js");
4243
4263
  const argv = process.argv.slice(2);
4244
4264
  await runDoctorCli({
4245
4265
  json: !!options.json || argv.includes("--json"),
@@ -4248,7 +4268,7 @@ program.command("doctor").description("Health check: API keys, config, MCP, rece
4248
4268
  });
4249
4269
  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) => {
4250
4270
  try {
4251
- const batch = await import("./batch-H4WWSZQ3.js");
4271
+ const batch = await import("./batch-ZGRYELZQ.js");
4252
4272
  switch (action) {
4253
4273
  case "submit":
4254
4274
  if (!arg) {
@@ -4291,7 +4311,7 @@ program.command("batch <action> [arg] [arg2]").description("Anthropic Message Ba
4291
4311
  }
4292
4312
  });
4293
4313
  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) => {
4294
- const { startMcpServer } = await import("./server-CYAB56O3.js");
4314
+ const { startMcpServer } = await import("./server-ORHXQROL.js");
4295
4315
  await startMcpServer({
4296
4316
  allowDestructive: !!options.allowDestructive,
4297
4317
  allowOutsideCwd: !!options.allowOutsideCwd,
@@ -4304,7 +4324,7 @@ program.command("pr <action> [target]").description("PR review helpers: review |
4304
4324
  console.error(`Unknown pr action: ${action}. Use review | security-review | summarize.`);
4305
4325
  process.exit(1);
4306
4326
  }
4307
- const { runPrCli } = await import("./pr-6PUHVJ6K.js");
4327
+ const { runPrCli } = await import("./pr-WQMSMNBR.js");
4308
4328
  const result = await runPrCli({
4309
4329
  action,
4310
4330
  target,
@@ -4324,8 +4344,8 @@ program.command("pr <action> [target]").description("PR review helpers: review |
4324
4344
  process.exit(result.exitCode);
4325
4345
  });
4326
4346
  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) => {
4327
- const { runCi } = await import("./ci-H6GPHG4T.js");
4328
- const { formatCiResult } = await import("./ci-format-U47GSGYU.js");
4347
+ const { runCi } = await import("./ci-FJR4SB57.js");
4348
+ const { formatCiResult } = await import("./ci-format-PZNBZT55.js");
4329
4349
  const formats = [options.json, options.markdown, options.sarif].filter(Boolean).length;
4330
4350
  if (formats > 1) {
4331
4351
  console.error("Choose only one output format: --json, --markdown, or --sarif.");
@@ -4484,7 +4504,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
4484
4504
  config.get("customProviders"),
4485
4505
  config.getConfigDir()
4486
4506
  );
4487
- const { startHub } = await import("./hub-G5FMMTVZ.js");
4507
+ const { startHub } = await import("./hub-TAGD646P.js");
4488
4508
  await startHub(
4489
4509
  {
4490
4510
  topic: topic ?? "",
@@ -27,11 +27,11 @@ import {
27
27
  touchMemoryReferences,
28
28
  updateMemoryApproval,
29
29
  updateMemoryEntry
30
- } from "./chunk-2E5W2E64.js";
30
+ } from "./chunk-2PDBRPNS.js";
31
31
  import "./chunk-FSC6KEWU.js";
32
32
  import "./chunk-2XMUCC42.js";
33
33
  import "./chunk-CGLYJRFA.js";
34
- import "./chunk-EAVX3RLD.js";
34
+ import "./chunk-7B2KVTGQ.js";
35
35
  export {
36
36
  addMemoryEntry,
37
37
  backupMemoryStore,
@@ -28,11 +28,11 @@ import {
28
28
  touchMemoryReferences,
29
29
  updateMemoryApproval,
30
30
  updateMemoryEntry
31
- } from "./chunk-HXINWG37.js";
31
+ } from "./chunk-ROUVNUZZ.js";
32
32
  import "./chunk-3FEZSLGI.js";
33
33
  import "./chunk-HOSJZMQS.js";
34
34
  import "./chunk-BMLQPSHP.js";
35
- import "./chunk-3CNPJLVI.js";
35
+ import "./chunk-ZX4L2ZYI.js";
36
36
  export {
37
37
  addMemoryEntry,
38
38
  backupMemoryStore,
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  countSeverity,
4
4
  runCi
5
- } from "./chunk-IW6Q66WS.js";
6
- import "./chunk-K4F7QEGW.js";
5
+ } from "./chunk-2XI6LXBY.js";
6
+ import "./chunk-EWWHG3CR.js";
7
7
  import {
8
8
  buildReviewPrompt,
9
9
  buildSecurityReviewPrompt,
@@ -14,16 +14,16 @@ import {
14
14
  } from "./chunk-6YZEZFX5.js";
15
15
  import {
16
16
  ProviderRegistry
17
- } from "./chunk-EHMMBIZT.js";
17
+ } from "./chunk-3L3PKTSK.js";
18
18
  import {
19
19
  ConfigManager
20
- } from "./chunk-RBCKX2FZ.js";
20
+ } from "./chunk-IXR2P7WK.js";
21
21
  import "./chunk-RMEJR3AW.js";
22
22
  import "./chunk-TU3L3PW7.js";
23
23
  import "./chunk-BMLQPSHP.js";
24
24
  import {
25
25
  VERSION
26
- } from "./chunk-3CNPJLVI.js";
26
+ } from "./chunk-ZX4L2ZYI.js";
27
27
 
28
28
  // src/cli/pr.ts
29
29
  import { execFileSync } from "child_process";
@@ -3,8 +3,8 @@ import {
3
3
  executeTests,
4
4
  runTestProcess,
5
5
  runTestsTool
6
- } from "./chunk-3GEO2LPO.js";
7
- import "./chunk-3CNPJLVI.js";
6
+ } from "./chunk-IVHG47FR.js";
7
+ import "./chunk-ZX4L2ZYI.js";
8
8
  import "./chunk-SXIJLSVF.js";
9
9
  export {
10
10
  executeTests,
@@ -2,9 +2,9 @@ import {
2
2
  executeTests,
3
3
  runTestProcess,
4
4
  runTestsTool
5
- } from "./chunk-RLERORUI.js";
5
+ } from "./chunk-PWN7QNDK.js";
6
6
  import "./chunk-QMFMST2T.js";
7
- import "./chunk-EAVX3RLD.js";
7
+ import "./chunk-7B2KVTGQ.js";
8
8
  export {
9
9
  executeTests,
10
10
  runTestProcess,