jinzd-ai-cli 0.4.310 → 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-O5SXWZ4D.js → batch-ZGRYELZQ.js} +2 -2
  2. package/dist/{chunk-QGOHEDYN.js → chunk-2PDBRPNS.js} +1 -1
  3. package/dist/{chunk-5J4KKOEK.js → chunk-2XI6LXBY.js} +4 -4
  4. package/dist/{chunk-EHMMBIZT.js → chunk-3L3PKTSK.js} +111 -2
  5. package/dist/{chunk-TSACXF4M.js → chunk-7B2KVTGQ.js} +1 -1
  6. package/dist/{chunk-WKAILZFD.js → chunk-EHACKFNT.js} +1 -1
  7. package/dist/{chunk-A7WJGEXR.js → chunk-EWWHG3CR.js} +1 -1
  8. package/dist/{chunk-WKNVMMCN.js → chunk-IVHG47FR.js} +1 -1
  9. package/dist/{chunk-LCVJYA32.js → chunk-IXR2P7WK.js} +1 -1
  10. package/dist/{chunk-MKQZEKX5.js → chunk-K2VL22AX.js} +7 -7
  11. package/dist/{chunk-WKPPGB7V.js → chunk-L4VU5F7P.js} +17 -6
  12. package/dist/{chunk-3YEUWSKJ.js → chunk-PWN7QNDK.js} +1 -1
  13. package/dist/{chunk-3YZGQIDN.js → chunk-ROUVNUZZ.js} +1 -1
  14. package/dist/{chunk-TF5343WH.js → chunk-UZIXHKF7.js} +4 -4
  15. package/dist/{chunk-SXWQKEU4.js → chunk-ZX4L2ZYI.js} +1 -1
  16. package/dist/{ci-M4K3JCYV.js → ci-FJR4SB57.js} +5 -5
  17. package/dist/{ci-format-EHIWLOUS.js → ci-format-PZNBZT55.js} +2 -2
  18. package/dist/{constants-5H5VNSST.js → constants-OV7XBTZI.js} +1 -1
  19. package/dist/{constants-RCFLPOBR.js → constants-RBP6YR3H.js} +1 -1
  20. package/dist/{doctor-cli-GMM6AOFR.js → doctor-cli-GE4TWAXT.js} +5 -5
  21. package/dist/electron-server.js +134 -14
  22. package/dist/{hub-55SCA6IZ.js → hub-TAGD646P.js} +1 -1
  23. package/dist/index.js +18 -18
  24. package/dist/{persistent-memory-GKL3V6OV.js → persistent-memory-4JGH2RSD.js} +2 -2
  25. package/dist/{persistent-memory-WV7EXQKP.js → persistent-memory-Z5HYYVXL.js} +2 -2
  26. package/dist/{pr-ROHHZXSS.js → pr-WQMSMNBR.js} +5 -5
  27. package/dist/{run-tests-EI4HRC7T.js → run-tests-JZDYMCHO.js} +2 -2
  28. package/dist/{run-tests-RGDSMN5K.js → run-tests-NJMCA7A5.js} +2 -2
  29. package/dist/{server-4YPZGX3J.js → server-KOFF5RTB.js} +14 -14
  30. package/dist/{server-HONA3NPQ.js → server-ORHXQROL.js} +5 -5
  31. package/dist/{task-orchestrator-IC5WWIY3.js → task-orchestrator-JS6JGL3N.js} +5 -5
  32. package/dist/{usage-J2ALUUKQ.js → usage-TVBY2BCQ.js} +2 -2
  33. package/package.json +2 -2
@@ -4,12 +4,12 @@ import {
4
4
  } from "./chunk-RS7SKYTS.js";
5
5
  import {
6
6
  ConfigManager
7
- } from "./chunk-LCVJYA32.js";
7
+ } from "./chunk-IXR2P7WK.js";
8
8
  import "./chunk-TU3L3PW7.js";
9
9
  import {
10
10
  atomicWriteFileSync
11
11
  } from "./chunk-BMLQPSHP.js";
12
- import "./chunk-SXWQKEU4.js";
12
+ import "./chunk-ZX4L2ZYI.js";
13
13
 
14
14
  // src/cli/batch.ts
15
15
  import Anthropic from "@anthropic-ai/sdk";
@@ -12,7 +12,7 @@ import {
12
12
  MEMORY_FILE_NAME,
13
13
  MEMORY_MAX_CHARS,
14
14
  MEMORY_STORE_FILE_NAME
15
- } from "./chunk-TSACXF4M.js";
15
+ } from "./chunk-7B2KVTGQ.js";
16
16
 
17
17
  // src/memory/persistent-memory.ts
18
18
  import { copyFileSync, existsSync, mkdirSync, readFileSync, statSync } from "fs";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  evaluateCiGate,
4
4
  normalizeCiThresholds
5
- } from "./chunk-A7WJGEXR.js";
5
+ } from "./chunk-EWWHG3CR.js";
6
6
  import {
7
7
  buildReviewPrompt,
8
8
  buildSecurityReviewPrompt,
@@ -13,13 +13,13 @@ import {
13
13
  } from "./chunk-6YZEZFX5.js";
14
14
  import {
15
15
  ProviderRegistry
16
- } from "./chunk-EHMMBIZT.js";
16
+ } from "./chunk-3L3PKTSK.js";
17
17
  import {
18
18
  ConfigManager
19
- } from "./chunk-LCVJYA32.js";
19
+ } from "./chunk-IXR2P7WK.js";
20
20
  import {
21
21
  VERSION
22
- } from "./chunk-SXWQKEU4.js";
22
+ } from "./chunk-ZX4L2ZYI.js";
23
23
 
24
24
  // src/cli/ci.ts
25
25
  import { execFileSync } from "child_process";
@@ -2082,6 +2082,44 @@ var OPENROUTER_CONFIG = {
2082
2082
  var OpenRouterProvider = createStaticProviderClass(OPENROUTER_CONFIG);
2083
2083
 
2084
2084
  // src/providers/ollama.ts
2085
+ function resolveOllamaContextWindow(input) {
2086
+ if (isPositiveInt(input.runningContext)) {
2087
+ return { contextWindow: input.runningContext, source: "running" };
2088
+ }
2089
+ const numCtx = parseNumCtx(input.show?.parameters);
2090
+ if (numCtx !== void 0) return { contextWindow: numCtx, source: "modelfile" };
2091
+ const modelMax = readModelMaxContext(input.show?.model_info);
2092
+ if (modelMax !== void 0) return { contextWindow: modelMax, source: "model-max" };
2093
+ return { contextWindow: input.fallback, source: "estimate" };
2094
+ }
2095
+ function isPositiveInt(n) {
2096
+ return typeof n === "number" && Number.isInteger(n) && n > 0;
2097
+ }
2098
+ function parseNumCtx(parameters) {
2099
+ if (!parameters) return void 0;
2100
+ let found;
2101
+ for (const line of parameters.split("\n")) {
2102
+ const m = /^\s*num_ctx\s+(\d+)\s*$/.exec(line);
2103
+ if (m) found = Number(m[1]);
2104
+ }
2105
+ return isPositiveInt(found) ? found : void 0;
2106
+ }
2107
+ function readModelMaxContext(modelInfo) {
2108
+ if (!modelInfo) return void 0;
2109
+ const arch = modelInfo["general.architecture"];
2110
+ if (typeof arch === "string") {
2111
+ const v = modelInfo[`${arch}.context_length`];
2112
+ if (isPositiveInt(v)) return v;
2113
+ }
2114
+ for (const [k, v] of Object.entries(modelInfo)) {
2115
+ if (k.endsWith(".context_length") && isPositiveInt(v)) return v;
2116
+ }
2117
+ return void 0;
2118
+ }
2119
+ function ollamaNativeBaseUrl(openAiBaseUrl) {
2120
+ return openAiBaseUrl.replace(/\/+$/, "").replace(/\/v1$/, "");
2121
+ }
2122
+ var NATIVE_API_TIMEOUT_MS = 3e3;
2085
2123
  var OllamaProvider = class extends OpenAICompatibleProvider {
2086
2124
  // 用 127.0.0.1 而非 localhost:Node.js 18+ 在 Windows 上优先解析 localhost 为 IPv6 (::1),
2087
2125
  // 但 Ollama 默认只监听 IPv4,导致连接失败。
@@ -2090,6 +2128,8 @@ var OllamaProvider = class extends OpenAICompatibleProvider {
2090
2128
  // 本地推理可能较慢,默认 2 分钟
2091
2129
  /** 动态模型列表 */
2092
2130
  dynamicModels = [];
2131
+ /** 原生 API 根地址(`/api/show`、`/api/ps`),initialize 时由 baseUrl 推出 */
2132
+ nativeBaseUrl = ollamaNativeBaseUrl(this.defaultBaseUrl);
2093
2133
  info = {
2094
2134
  id: "ollama",
2095
2135
  displayName: "Ollama (Local)",
@@ -2101,6 +2141,7 @@ var OllamaProvider = class extends OpenAICompatibleProvider {
2101
2141
  };
2102
2142
  async initialize(apiKey, options) {
2103
2143
  const baseUrl = options?.baseUrl ?? this.defaultBaseUrl;
2144
+ this.nativeBaseUrl = ollamaNativeBaseUrl(baseUrl);
2104
2145
  await super.initialize(apiKey || "ollama", { ...options, baseUrl });
2105
2146
  await this.tryConnect(true);
2106
2147
  }
@@ -2118,10 +2159,11 @@ var OllamaProvider = class extends OpenAICompatibleProvider {
2118
2159
  if (modelIds.length === 0) {
2119
2160
  return false;
2120
2161
  }
2162
+ const contextWindows = await this.detectContextWindows(modelIds);
2121
2163
  this.dynamicModels = modelIds.map((id) => ({
2122
2164
  id,
2123
2165
  displayName: id,
2124
- contextWindow: this.estimateContextWindow(id),
2166
+ contextWindow: contextWindows.get(id) ?? this.estimateContextWindow(id),
2125
2167
  supportsStreaming: true,
2126
2168
  supportsThinking: false
2127
2169
  }));
@@ -2142,7 +2184,74 @@ var OllamaProvider = class extends OpenAICompatibleProvider {
2142
2184
  return false;
2143
2185
  }
2144
2186
  }
2145
- /** 根据模型名估算上下文窗口 */
2187
+ /**
2188
+ * 经原生 API 查每个模型的 contextWindow(规则见 resolveOllamaContextWindow)。
2189
+ * 任何一步失败都只影响该模型、退回按名字猜,绝不让模型列表整体失败——
2190
+ * 模型列表拿到了就说明服务是通的,上下文探测只是锦上添花。
2191
+ */
2192
+ async detectContextWindows(modelIds) {
2193
+ const result = /* @__PURE__ */ new Map();
2194
+ const [running, digests] = await Promise.all([this.fetchRunningContexts(), this.fetchDigests()]);
2195
+ await Promise.all(modelIds.map(async (id) => {
2196
+ const show = await this.fetchNative("/api/show", { model: id });
2197
+ if (running.size === 0 && !show) return;
2198
+ const digest = digests.get(id);
2199
+ const { contextWindow } = resolveOllamaContextWindow({
2200
+ runningContext: digest && running.get(digest) || running.get(id),
2201
+ show,
2202
+ fallback: this.estimateContextWindow(id)
2203
+ });
2204
+ result.set(id, contextWindow);
2205
+ }));
2206
+ return result;
2207
+ }
2208
+ /** `/api/ps`:已加载模型的名字与 digest → 实际上下文窗口。未加载的模型不在其中。 */
2209
+ async fetchRunningContexts() {
2210
+ const running = /* @__PURE__ */ new Map();
2211
+ const ps = await this.fetchNative("/api/ps");
2212
+ for (const m of ps?.models ?? []) {
2213
+ if (!isPositiveInt(m.context_length)) continue;
2214
+ for (const key of [m.digest, m.name, m.model]) {
2215
+ if (key) running.set(key, m.context_length);
2216
+ }
2217
+ }
2218
+ return running;
2219
+ }
2220
+ /** `/api/tags`:模型名 → digest,用于把别名对到 /api/ps 里以原名加载的同一模型 */
2221
+ async fetchDigests() {
2222
+ const digests = /* @__PURE__ */ new Map();
2223
+ const tags = await this.fetchNative("/api/tags");
2224
+ for (const m of tags?.models ?? []) {
2225
+ if (!m.digest) continue;
2226
+ for (const name of [m.name, m.model]) {
2227
+ if (name) digests.set(name, m.digest);
2228
+ }
2229
+ }
2230
+ return digests;
2231
+ }
2232
+ /**
2233
+ * 调 Ollama 原生 API,失败一律返回 undefined。
2234
+ * 本地地址必须显式走直连 Agent:setupProxy() 装的全局 ProxyAgent 不认 localhost 例外,
2235
+ * 裸 fetch 会把 127.0.0.1:11434 发给代理(同 isLoopbackBaseUrl 那次的坑)。
2236
+ */
2237
+ async fetchNative(path, body) {
2238
+ try {
2239
+ const { Agent, fetch: undiciFetch } = await import("undici");
2240
+ const url = `${this.nativeBaseUrl}${path}`;
2241
+ const init = {
2242
+ method: body ? "POST" : "GET",
2243
+ headers: body ? { "content-type": "application/json" } : void 0,
2244
+ body: body ? JSON.stringify(body) : void 0,
2245
+ signal: AbortSignal.timeout(NATIVE_API_TIMEOUT_MS)
2246
+ };
2247
+ const res = isLoopbackBaseUrl(url) ? await undiciFetch(url, { ...init, dispatcher: new Agent() }) : await undiciFetch(url, init);
2248
+ if (!res.ok) return void 0;
2249
+ return await res.json();
2250
+ } catch {
2251
+ return void 0;
2252
+ }
2253
+ }
2254
+ /** 根据模型名估算上下文窗口(原生 API 不可用时的兜底) */
2146
2255
  estimateContextWindow(modelName) {
2147
2256
  const name = modelName.toLowerCase();
2148
2257
  if (name.includes("llama3") || name.includes("llama-3")) return 131072;
@@ -1,5 +1,5 @@
1
1
  // src/core/constants.ts
2
- var VERSION = "0.4.310";
2
+ var VERSION = "0.4.311";
3
3
  var APP_NAME = "ai-cli";
4
4
  var CONFIG_DIR_NAME = ".aicli";
5
5
  var CONFIG_FILE_NAME = "config.json";
@@ -8,7 +8,7 @@ import {
8
8
  import {
9
9
  CONFIG_DIR_NAME,
10
10
  PLUGINS_DIR_NAME
11
- } from "./chunk-SXWQKEU4.js";
11
+ } from "./chunk-ZX4L2ZYI.js";
12
12
 
13
13
  // src/diagnostics/tool-stats.ts
14
14
  import { mkdirSync } from "fs";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  VERSION
4
- } from "./chunk-SXWQKEU4.js";
4
+ } from "./chunk-ZX4L2ZYI.js";
5
5
 
6
6
  // src/cli/ci-format.ts
7
7
  var DEFAULT_CI_THRESHOLDS = {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  TEST_TIMEOUT
4
- } from "./chunk-SXWQKEU4.js";
4
+ } from "./chunk-ZX4L2ZYI.js";
5
5
  import {
6
6
  getExecutionConfigDir,
7
7
  getExecutionSignal
@@ -11,7 +11,7 @@ import {
11
11
  CONFIG_FILE_NAME,
12
12
  HISTORY_DIR_NAME,
13
13
  PLUGINS_DIR_NAME
14
- } from "./chunk-SXWQKEU4.js";
14
+ } from "./chunk-ZX4L2ZYI.js";
15
15
 
16
16
  // src/config/config-manager.ts
17
17
  import { readFileSync, existsSync, mkdirSync } from "fs";
@@ -16,7 +16,7 @@ import {
16
16
  setPreferredAgentName,
17
17
  truncateForPersist,
18
18
  undoStack
19
- } from "./chunk-WKPPGB7V.js";
19
+ } from "./chunk-L4VU5F7P.js";
20
20
  import {
21
21
  buildReviewPrompt,
22
22
  buildSecurityReviewPrompt
@@ -51,7 +51,7 @@ import {
51
51
  touchMemoryReferences,
52
52
  updateMemoryApproval,
53
53
  updateMemoryEntry
54
- } from "./chunk-3YZGQIDN.js";
54
+ } from "./chunk-ROUVNUZZ.js";
55
55
  import {
56
56
  theme
57
57
  } from "./chunk-5C76XDDF.js";
@@ -65,7 +65,7 @@ import {
65
65
  import {
66
66
  buildDoctorReport,
67
67
  formatDoctorReport
68
- } from "./chunk-TF5343WH.js";
68
+ } from "./chunk-UZIXHKF7.js";
69
69
  import {
70
70
  describePlugin,
71
71
  getActivePluginAssets,
@@ -80,7 +80,7 @@ import {
80
80
  trustHook,
81
81
  trustPlugin,
82
82
  untrustHook
83
- } from "./chunk-WKAILZFD.js";
83
+ } from "./chunk-EHACKFNT.js";
84
84
  import {
85
85
  isCleanDocumentBody,
86
86
  stripOuterCodeFence
@@ -109,7 +109,7 @@ import {
109
109
  MCP_TOOL_PREFIX,
110
110
  REPO_URL,
111
111
  VERSION
112
- } from "./chunk-SXWQKEU4.js";
112
+ } from "./chunk-ZX4L2ZYI.js";
113
113
 
114
114
  // src/skills/manager.ts
115
115
  import { existsSync, readdirSync, mkdirSync, statSync } from "fs";
@@ -2426,7 +2426,7 @@ No tools match "${filter}".
2426
2426
  const { join: join6 } = await import("path");
2427
2427
  const { existsSync: existsSync6 } = await import("fs");
2428
2428
  const { getGitRoot } = await import("./git-context-EXOEHQSF.js");
2429
- const { MCP_PROJECT_CONFIG_NAME } = await import("./constants-RCFLPOBR.js");
2429
+ const { MCP_PROJECT_CONFIG_NAME } = await import("./constants-RBP6YR3H.js");
2430
2430
  const { approveProject, hashMcpFile } = await import("./project-trust-KGG2BWKC.js");
2431
2431
  const cwd = process.cwd();
2432
2432
  const projectRoot = getGitRoot(cwd) ?? cwd;
@@ -3534,7 +3534,7 @@ function createReviewCommands() {
3534
3534
  usage: "/test [command|filter]",
3535
3535
  async execute(args, ctx) {
3536
3536
  try {
3537
- const { executeTests } = await import("./run-tests-EI4HRC7T.js");
3537
+ const { executeTests } = await import("./run-tests-JZDYMCHO.js");
3538
3538
  const argStr = args.join(" ").trim();
3539
3539
  let testArgs = {};
3540
3540
  if (argStr) {
@@ -11,7 +11,7 @@ import {
11
11
  searchPersistentMemories,
12
12
  touchMemoryReferences,
13
13
  updateMemoryEntry
14
- } from "./chunk-3YZGQIDN.js";
14
+ } from "./chunk-ROUVNUZZ.js";
15
15
  import {
16
16
  indexProject
17
17
  } from "./chunk-RWRZVQCB.js";
@@ -30,7 +30,7 @@ import {
30
30
  runHook,
31
31
  runLifecycleHooks,
32
32
  runTool
33
- } from "./chunk-WKAILZFD.js";
33
+ } from "./chunk-EHACKFNT.js";
34
34
  import {
35
35
  buildTruncatedArgumentsError,
36
36
  getDangerLevel,
@@ -63,7 +63,7 @@ import {
63
63
  recoverGbkMojibake,
64
64
  runTestsTool,
65
65
  shellInvocation
66
- } from "./chunk-WKNVMMCN.js";
66
+ } from "./chunk-IVHG47FR.js";
67
67
  import {
68
68
  CONFIG_DIR_NAME,
69
69
  DEFAULT_MAX_TOOL_OUTPUT_CHARS_CAP,
@@ -72,7 +72,7 @@ import {
72
72
  SUBAGENT_ALLOWED_TOOLS,
73
73
  SUBAGENT_DEFAULT_MAX_ROUNDS,
74
74
  SUBAGENT_MAX_ROUNDS_LIMIT
75
- } from "./chunk-SXWQKEU4.js";
75
+ } from "./chunk-ZX4L2ZYI.js";
76
76
  import {
77
77
  getCurrentSessionKey,
78
78
  getExecutionConfigDir,
@@ -2893,6 +2893,16 @@ function norm(p) {
2893
2893
  }
2894
2894
  return process.platform === "win32" ? abs.toLowerCase() : abs;
2895
2895
  }
2896
+ function systemPathCandidates(p) {
2897
+ const out = /* @__PURE__ */ new Set([norm(p), resolve5(p)]);
2898
+ if (process.platform === "darwin") {
2899
+ for (const c of [...out]) {
2900
+ const m = /^\/private(\/(?:etc|var|tmp)(?:\/|$).*)$/.exec(c);
2901
+ if (m) out.add(m[1]);
2902
+ }
2903
+ }
2904
+ return [...out];
2905
+ }
2896
2906
  function homeRel(p) {
2897
2907
  const abs = norm(p);
2898
2908
  const h = norm(home);
@@ -2956,10 +2966,11 @@ function classifyWritePath(path3) {
2956
2966
  if (abs.includes(`${sep2}.git${sep2}config`) || abs.includes(`${sep2}.git${sep2}config`.toLowerCase())) {
2957
2967
  return { sensitive: true, reason: ".git/config \u2014 repository identity" };
2958
2968
  }
2969
+ const sysCandidates = process.platform === "win32" ? [abs] : systemPathCandidates(path3);
2959
2970
  if (process.platform !== "win32") {
2960
2971
  const sysPrefixes = ["/etc/", "/usr/bin/", "/usr/sbin/", "/bin/", "/sbin/", "/boot/"];
2961
2972
  for (const pre of sysPrefixes) {
2962
- if (abs.startsWith(pre)) return { sensitive: true, reason: `system path (${pre})` };
2973
+ if (sysCandidates.some((c) => c.startsWith(pre))) return { sensitive: true, reason: `system path (${pre})` };
2963
2974
  }
2964
2975
  } else {
2965
2976
  const winSys = ["c:\\windows\\system32\\", "c:\\windows\\syswow64\\", "c:\\program files\\", "c:\\program files (x86)\\"];
@@ -2967,7 +2978,7 @@ function classifyWritePath(path3) {
2967
2978
  if (abs.startsWith(pre)) return { sensitive: true, reason: `system path (${pre})` };
2968
2979
  }
2969
2980
  }
2970
- if (abs.includes(`${sep2}cron.d${sep2}`) || abs.startsWith("/etc/cron") || abs.startsWith("/var/spool/cron/")) {
2981
+ if (abs.includes(`${sep2}cron.d${sep2}`) || sysCandidates.some((c) => c.startsWith("/etc/cron") || c.startsWith("/var/spool/cron/"))) {
2971
2982
  return { sensitive: true, reason: "cron scheduling" };
2972
2983
  }
2973
2984
  if (rel && (rel.startsWith("Library/LaunchAgents/") || rel.startsWith("Library/LaunchDaemons/"))) {
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-QMFMST2T.js";
5
5
  import {
6
6
  TEST_TIMEOUT
7
- } from "./chunk-TSACXF4M.js";
7
+ } from "./chunk-7B2KVTGQ.js";
8
8
 
9
9
  // src/tools/builtin/run-tests.ts
10
10
  import { spawn as spawn2 } from "child_process";
@@ -13,7 +13,7 @@ import {
13
13
  MEMORY_FILE_NAME,
14
14
  MEMORY_MAX_CHARS,
15
15
  MEMORY_STORE_FILE_NAME
16
- } from "./chunk-SXWQKEU4.js";
16
+ } from "./chunk-ZX4L2ZYI.js";
17
17
 
18
18
  // src/memory/persistent-memory.ts
19
19
  import { copyFileSync, existsSync, mkdirSync, readFileSync, statSync } from "fs";
@@ -8,13 +8,13 @@ import {
8
8
  listHooks,
9
9
  listInstalledPlugins,
10
10
  resetStats
11
- } from "./chunk-WKAILZFD.js";
11
+ } from "./chunk-EHACKFNT.js";
12
12
  import {
13
13
  ProviderRegistry
14
- } from "./chunk-EHMMBIZT.js";
14
+ } from "./chunk-3L3PKTSK.js";
15
15
  import {
16
16
  ConfigManager
17
- } from "./chunk-LCVJYA32.js";
17
+ } from "./chunk-IXR2P7WK.js";
18
18
  import {
19
19
  getGitRoot
20
20
  } from "./chunk-HOSJZMQS.js";
@@ -26,7 +26,7 @@ import {
26
26
  MCP_PROJECT_CONFIG_NAME,
27
27
  MEMORY_FILE_NAME,
28
28
  VERSION
29
- } from "./chunk-SXWQKEU4.js";
29
+ } from "./chunk-ZX4L2ZYI.js";
30
30
 
31
31
  // src/diagnostics/doctor-report.ts
32
32
  import { existsSync as existsSync3, statSync as statSync2 } from "fs";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/core/constants.ts
4
- var VERSION = "0.4.310";
4
+ var VERSION = "0.4.311";
5
5
  var APP_NAME = "ai-cli";
6
6
  var CONFIG_DIR_NAME = ".aicli";
7
7
  var CONFIG_FILE_NAME = "config.json";
@@ -3,16 +3,16 @@ import {
3
3
  CI_COMMENT_MARKER,
4
4
  countSeverity,
5
5
  runCi
6
- } from "./chunk-5J4KKOEK.js";
7
- import "./chunk-A7WJGEXR.js";
6
+ } from "./chunk-2XI6LXBY.js";
7
+ import "./chunk-EWWHG3CR.js";
8
8
  import "./chunk-HLWUDRBO.js";
9
9
  import "./chunk-6YZEZFX5.js";
10
- import "./chunk-EHMMBIZT.js";
11
- import "./chunk-LCVJYA32.js";
10
+ import "./chunk-3L3PKTSK.js";
11
+ import "./chunk-IXR2P7WK.js";
12
12
  import "./chunk-RMEJR3AW.js";
13
13
  import "./chunk-TU3L3PW7.js";
14
14
  import "./chunk-BMLQPSHP.js";
15
- import "./chunk-SXWQKEU4.js";
15
+ import "./chunk-ZX4L2ZYI.js";
16
16
  export {
17
17
  CI_COMMENT_MARKER,
18
18
  countSeverity,
@@ -6,8 +6,8 @@ import {
6
6
  formatCiResult,
7
7
  formatCiSarif,
8
8
  normalizeCiThresholds
9
- } from "./chunk-A7WJGEXR.js";
10
- import "./chunk-SXWQKEU4.js";
9
+ } from "./chunk-EWWHG3CR.js";
10
+ import "./chunk-ZX4L2ZYI.js";
11
11
  export {
12
12
  DEFAULT_CI_THRESHOLDS,
13
13
  detectCiGateSignals,
@@ -38,7 +38,7 @@ import {
38
38
  TEST_TIMEOUT,
39
39
  VERSION,
40
40
  buildUserIdentityPrompt
41
- } from "./chunk-TSACXF4M.js";
41
+ } from "./chunk-7B2KVTGQ.js";
42
42
  export {
43
43
  AGENTIC_BEHAVIOR_GUIDELINE,
44
44
  APP_NAME,
@@ -39,7 +39,7 @@ import {
39
39
  TEST_TIMEOUT,
40
40
  VERSION,
41
41
  buildUserIdentityPrompt
42
- } from "./chunk-SXWQKEU4.js";
42
+ } from "./chunk-ZX4L2ZYI.js";
43
43
  export {
44
44
  AGENTIC_BEHAVIOR_GUIDELINE,
45
45
  APP_NAME,
@@ -2,16 +2,16 @@
2
2
  import {
3
3
  formatDoctorReport,
4
4
  runDoctorCli
5
- } from "./chunk-TF5343WH.js";
6
- import "./chunk-WKAILZFD.js";
5
+ } from "./chunk-UZIXHKF7.js";
6
+ import "./chunk-EHACKFNT.js";
7
7
  import "./chunk-RS7SKYTS.js";
8
- import "./chunk-EHMMBIZT.js";
9
- import "./chunk-LCVJYA32.js";
8
+ import "./chunk-3L3PKTSK.js";
9
+ import "./chunk-IXR2P7WK.js";
10
10
  import "./chunk-RMEJR3AW.js";
11
11
  import "./chunk-TU3L3PW7.js";
12
12
  import "./chunk-HOSJZMQS.js";
13
13
  import "./chunk-BMLQPSHP.js";
14
- import "./chunk-SXWQKEU4.js";
14
+ import "./chunk-ZX4L2ZYI.js";
15
15
  export {
16
16
  formatDoctorReport,
17
17
  runDoctorCli
@@ -55,7 +55,7 @@ import {
55
55
  touchMemoryReferences,
56
56
  updateMemoryApproval,
57
57
  updateMemoryEntry
58
- } from "./chunk-QGOHEDYN.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-3YEUWSKJ.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-TSACXF4M.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;
@@ -8831,6 +8940,16 @@ function norm(p) {
8831
8940
  }
8832
8941
  return process.platform === "win32" ? abs.toLowerCase() : abs;
8833
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
+ }
8834
8953
  function homeRel(p) {
8835
8954
  const abs = norm(p);
8836
8955
  const h = norm(home);
@@ -8894,10 +9013,11 @@ function classifyWritePath(path3) {
8894
9013
  if (abs.includes(`${sep2}.git${sep2}config`) || abs.includes(`${sep2}.git${sep2}config`.toLowerCase())) {
8895
9014
  return { sensitive: true, reason: ".git/config \u2014 repository identity" };
8896
9015
  }
9016
+ const sysCandidates = process.platform === "win32" ? [abs] : systemPathCandidates(path3);
8897
9017
  if (process.platform !== "win32") {
8898
9018
  const sysPrefixes = ["/etc/", "/usr/bin/", "/usr/sbin/", "/bin/", "/sbin/", "/boot/"];
8899
9019
  for (const pre of sysPrefixes) {
8900
- 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})` };
8901
9021
  }
8902
9022
  } else {
8903
9023
  const winSys = ["c:\\windows\\system32\\", "c:\\windows\\syswow64\\", "c:\\program files\\", "c:\\program files (x86)\\"];
@@ -8905,7 +9025,7 @@ function classifyWritePath(path3) {
8905
9025
  if (abs.startsWith(pre)) return { sensitive: true, reason: `system path (${pre})` };
8906
9026
  }
8907
9027
  }
8908
- 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/"))) {
8909
9029
  return { sensitive: true, reason: "cron scheduling" };
8910
9030
  }
8911
9031
  if (rel && (rel.startsWith("Library/LaunchAgents/") || rel.startsWith("Library/LaunchDaemons/"))) {
@@ -17259,7 +17379,7 @@ Cache: write=${cacheCreate} read=${cacheRead}` : "";
17259
17379
  Cost: ${formatCost(cost)}` : "";
17260
17380
  let memoryLine = "";
17261
17381
  try {
17262
- const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-GKL3V6OV.js");
17382
+ const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-4JGH2RSD.js");
17263
17383
  const pending = countPendingMemories2(ctx.config.getConfigDir());
17264
17384
  if (pending > 0) memoryLine = `
17265
17385
  Memory: \u26A0 ${pending} pending approval \u2014 see the Memory panel or /memory`;
@@ -18247,7 +18367,7 @@ async function handleTest(args, ctx) {
18247
18367
  const isCommand = argStr.includes(" ") || /^(mvn|gradle|npm|pytest|cargo|go)\b/.test(argStr);
18248
18368
  testArgs = isCommand ? { command: argStr } : { filter: argStr };
18249
18369
  }
18250
- const runTests = ctx.runTests ?? (await import("./run-tests-RGDSMN5K.js")).executeTests;
18370
+ const runTests = ctx.runTests ?? (await import("./run-tests-NJMCA7A5.js")).executeTests;
18251
18371
  const report = await runTests(testArgs);
18252
18372
  ctx.send({ type: "info", message: report });
18253
18373
  } catch (err) {
@@ -18638,7 +18758,7 @@ async function handleMemory(args, ctx) {
18638
18758
  }
18639
18759
  if (intent.kind === "status") {
18640
18760
  const { getChatIndexStatus: getChatIndexStatus2 } = await import("./chat-index-RLVLQRRC.js");
18641
- const { listMemoryEntries: listMemoryEntries2, isMemoryExpired: isMemoryExpired2, formatMemoryForPrompt: formatMemoryForPrompt2 } = await import("./persistent-memory-GKL3V6OV.js");
18761
+ const { listMemoryEntries: listMemoryEntries2, isMemoryExpired: isMemoryExpired2, formatMemoryForPrompt: formatMemoryForPrompt2 } = await import("./persistent-memory-4JGH2RSD.js");
18642
18762
  const memories = listMemoryEntries2(configDir, { includeExpired: true, includeRejected: true });
18643
18763
  const injected = formatMemoryForPrompt2(configDir, process.cwd(), ctx.config.get("memory")?.maxChars);
18644
18764
  const view = buildMemoryStatusView({
@@ -18661,7 +18781,7 @@ async function handleMemory(args, ctx) {
18661
18781
  return;
18662
18782
  }
18663
18783
  if (intent.kind === "recall") {
18664
- const { searchPersistentMemories: searchPersistentMemories2, touchMemoryReferences: touchMemoryReferences2 } = await import("./persistent-memory-GKL3V6OV.js");
18784
+ const { searchPersistentMemories: searchPersistentMemories2, touchMemoryReferences: touchMemoryReferences2 } = await import("./persistent-memory-4JGH2RSD.js");
18665
18785
  const { searchChatMemory: searchChatMemory2 } = await import("./chat-index-RLVLQRRC.js");
18666
18786
  const persistentHits = searchPersistentMemories2(configDir, intent.query, process.cwd(), 3);
18667
18787
  if (persistentHits.length > 0) {
@@ -18782,7 +18902,7 @@ async function handleMemory(args, ctx) {
18782
18902
  ctx.handleMemoryManage(intent.action, args[1], intent.action === "expire" ? args[2] : void 0);
18783
18903
  } else if (intent.kind === "export") {
18784
18904
  if (args[1] === "md") {
18785
- const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-GKL3V6OV.js");
18905
+ const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-4JGH2RSD.js");
18786
18906
  ctx.send({
18787
18907
  type: "export_data",
18788
18908
  format: "md",
@@ -19787,7 +19907,7 @@ No tools match "${filter}".
19787
19907
  const { join: join26 } = await import("path");
19788
19908
  const { existsSync: existsSync32 } = await import("fs");
19789
19909
  const { getGitRoot: getGitRoot2 } = await import("./git-context-VNCA2GU7.js");
19790
- const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-5H5VNSST.js");
19910
+ const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-OV7XBTZI.js");
19791
19911
  const { approveProject, hashMcpFile } = await import("./project-trust-6CJB5ZMX.js");
19792
19912
  const cwd = process.cwd();
19793
19913
  const projectRoot = getGitRoot2(cwd) ?? cwd;
@@ -20706,7 +20826,7 @@ function createReviewCommands() {
20706
20826
  usage: "/test [command|filter]",
20707
20827
  async execute(args, ctx) {
20708
20828
  try {
20709
- const { executeTests } = await import("./run-tests-RGDSMN5K.js");
20829
+ const { executeTests } = await import("./run-tests-NJMCA7A5.js");
20710
20830
  const argStr = args.join(" ").trim();
20711
20831
  let testArgs = {};
20712
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-IC5WWIY3.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-MKQZEKX5.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-WKPPGB7V.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-3YZGQIDN.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-TF5343WH.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-WKAILZFD.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-LCVJYA32.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-WKNVMMCN.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-SXWQKEU4.js";
155
+ } from "./chunk-ZX4L2ZYI.js";
156
156
  import "./chunk-SXIJLSVF.js";
157
157
 
158
158
  // src/index.ts
@@ -4088,7 +4088,7 @@ program.command("web").description("Start Web UI server with browser-based chat
4088
4088
  console.error("Error: Invalid port number. Must be between 1 and 65535.");
4089
4089
  process.exit(1);
4090
4090
  }
4091
- const { startWebServer } = await import("./server-4YPZGX3J.js");
4091
+ const { startWebServer } = await import("./server-KOFF5RTB.js");
4092
4092
  await startWebServer({ port, host: options.host, externalOrigin: options.externalOrigin });
4093
4093
  });
4094
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) => {
@@ -4255,11 +4255,11 @@ program.command("sessions").description("List recent conversation sessions").opt
4255
4255
  console.log(footer + "\n");
4256
4256
  });
4257
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) => {
4258
- const { runUsageCli } = await import("./usage-J2ALUUKQ.js");
4258
+ const { runUsageCli } = await import("./usage-TVBY2BCQ.js");
4259
4259
  await runUsageCli(options);
4260
4260
  });
4261
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) => {
4262
- const { runDoctorCli } = await import("./doctor-cli-GMM6AOFR.js");
4262
+ const { runDoctorCli } = await import("./doctor-cli-GE4TWAXT.js");
4263
4263
  const argv = process.argv.slice(2);
4264
4264
  await runDoctorCli({
4265
4265
  json: !!options.json || argv.includes("--json"),
@@ -4268,7 +4268,7 @@ program.command("doctor").description("Health check: API keys, config, MCP, rece
4268
4268
  });
4269
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) => {
4270
4270
  try {
4271
- const batch = await import("./batch-O5SXWZ4D.js");
4271
+ const batch = await import("./batch-ZGRYELZQ.js");
4272
4272
  switch (action) {
4273
4273
  case "submit":
4274
4274
  if (!arg) {
@@ -4311,7 +4311,7 @@ program.command("batch <action> [arg] [arg2]").description("Anthropic Message Ba
4311
4311
  }
4312
4312
  });
4313
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) => {
4314
- const { startMcpServer } = await import("./server-HONA3NPQ.js");
4314
+ const { startMcpServer } = await import("./server-ORHXQROL.js");
4315
4315
  await startMcpServer({
4316
4316
  allowDestructive: !!options.allowDestructive,
4317
4317
  allowOutsideCwd: !!options.allowOutsideCwd,
@@ -4324,7 +4324,7 @@ program.command("pr <action> [target]").description("PR review helpers: review |
4324
4324
  console.error(`Unknown pr action: ${action}. Use review | security-review | summarize.`);
4325
4325
  process.exit(1);
4326
4326
  }
4327
- const { runPrCli } = await import("./pr-ROHHZXSS.js");
4327
+ const { runPrCli } = await import("./pr-WQMSMNBR.js");
4328
4328
  const result = await runPrCli({
4329
4329
  action,
4330
4330
  target,
@@ -4344,8 +4344,8 @@ program.command("pr <action> [target]").description("PR review helpers: review |
4344
4344
  process.exit(result.exitCode);
4345
4345
  });
4346
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) => {
4347
- const { runCi } = await import("./ci-M4K3JCYV.js");
4348
- const { formatCiResult } = await import("./ci-format-EHIWLOUS.js");
4347
+ const { runCi } = await import("./ci-FJR4SB57.js");
4348
+ const { formatCiResult } = await import("./ci-format-PZNBZT55.js");
4349
4349
  const formats = [options.json, options.markdown, options.sarif].filter(Boolean).length;
4350
4350
  if (formats > 1) {
4351
4351
  console.error("Choose only one output format: --json, --markdown, or --sarif.");
@@ -4504,7 +4504,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
4504
4504
  config.get("customProviders"),
4505
4505
  config.getConfigDir()
4506
4506
  );
4507
- const { startHub } = await import("./hub-55SCA6IZ.js");
4507
+ const { startHub } = await import("./hub-TAGD646P.js");
4508
4508
  await startHub(
4509
4509
  {
4510
4510
  topic: topic ?? "",
@@ -27,11 +27,11 @@ import {
27
27
  touchMemoryReferences,
28
28
  updateMemoryApproval,
29
29
  updateMemoryEntry
30
- } from "./chunk-QGOHEDYN.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-TSACXF4M.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-3YZGQIDN.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-SXWQKEU4.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-5J4KKOEK.js";
6
- import "./chunk-A7WJGEXR.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-LCVJYA32.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-SXWQKEU4.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-WKNVMMCN.js";
7
- import "./chunk-SXWQKEU4.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-3YEUWSKJ.js";
5
+ } from "./chunk-PWN7QNDK.js";
6
6
  import "./chunk-QMFMST2T.js";
7
- import "./chunk-TSACXF4M.js";
7
+ import "./chunk-7B2KVTGQ.js";
8
8
  export {
9
9
  executeTests,
10
10
  runTestProcess,
@@ -86,7 +86,7 @@ import {
86
86
  skillHistoryNote,
87
87
  snapshotFile,
88
88
  stripRoutingTags
89
- } from "./chunk-MKQZEKX5.js";
89
+ } from "./chunk-K2VL22AX.js";
90
90
  import {
91
91
  CNY_PER_USD,
92
92
  CostTracker,
@@ -130,7 +130,7 @@ import {
130
130
  spawnAgentContext,
131
131
  truncateOutput,
132
132
  undoStack
133
- } from "./chunk-WKPPGB7V.js";
133
+ } from "./chunk-L4VU5F7P.js";
134
134
  import {
135
135
  buildReviewPrompt,
136
136
  buildSecurityReviewPrompt
@@ -157,7 +157,7 @@ import {
157
157
  restoreMemoryEntries,
158
158
  updateMemoryApproval,
159
159
  updateMemoryEntry
160
- } from "./chunk-3YZGQIDN.js";
160
+ } from "./chunk-ROUVNUZZ.js";
161
161
  import "./chunk-RWRZVQCB.js";
162
162
  import "./chunk-B3MPYI4E.js";
163
163
  import "./chunk-M6HLYG33.js";
@@ -176,7 +176,7 @@ import {
176
176
  buildDoctorReport,
177
177
  formatDoctorReport,
178
178
  loadContextFiles
179
- } from "./chunk-TF5343WH.js";
179
+ } from "./chunk-UZIXHKF7.js";
180
180
  import {
181
181
  describePlugin,
182
182
  getActivePluginAssets,
@@ -191,14 +191,14 @@ import {
191
191
  runTool,
192
192
  setPluginEnabled,
193
193
  trustPlugin
194
- } from "./chunk-WKAILZFD.js";
194
+ } from "./chunk-EHACKFNT.js";
195
195
  import "./chunk-RS7SKYTS.js";
196
196
  import {
197
197
  ProviderRegistry
198
- } from "./chunk-EHMMBIZT.js";
198
+ } from "./chunk-3L3PKTSK.js";
199
199
  import {
200
200
  ConfigManager
201
- } from "./chunk-LCVJYA32.js";
201
+ } from "./chunk-IXR2P7WK.js";
202
202
  import {
203
203
  CONTENT_ONLY_STREAM_REMINDER,
204
204
  TEE_FINAL_USER_NUDGE,
@@ -231,7 +231,7 @@ import {
231
231
  import {
232
232
  assertReadablePath
233
233
  } from "./chunk-JJFJWD35.js";
234
- import "./chunk-WKNVMMCN.js";
234
+ import "./chunk-IVHG47FR.js";
235
235
  import {
236
236
  AGENTIC_BEHAVIOR_GUIDELINE,
237
237
  AUTHOR,
@@ -247,7 +247,7 @@ import {
247
247
  SKILLS_DIR_NAME,
248
248
  VERSION,
249
249
  buildUserIdentityPrompt
250
- } from "./chunk-SXWQKEU4.js";
250
+ } from "./chunk-ZX4L2ZYI.js";
251
251
  import {
252
252
  runWithExecutionContext,
253
253
  runWithSessionKey
@@ -978,7 +978,7 @@ Cache: write=${cacheCreate} read=${cacheRead}` : "";
978
978
  Cost: ${formatCost(cost)}` : "";
979
979
  let memoryLine = "";
980
980
  try {
981
- const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-WV7EXQKP.js");
981
+ const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-Z5HYYVXL.js");
982
982
  const pending = countPendingMemories2(ctx.config.getConfigDir());
983
983
  if (pending > 0) memoryLine = `
984
984
  Memory: \u26A0 ${pending} pending approval \u2014 see the Memory panel or /memory`;
@@ -1907,7 +1907,7 @@ async function handleTest(args, ctx) {
1907
1907
  const isCommand = argStr.includes(" ") || /^(mvn|gradle|npm|pytest|cargo|go)\b/.test(argStr);
1908
1908
  testArgs = isCommand ? { command: argStr } : { filter: argStr };
1909
1909
  }
1910
- const runTests = ctx.runTests ?? (await import("./run-tests-EI4HRC7T.js")).executeTests;
1910
+ const runTests = ctx.runTests ?? (await import("./run-tests-JZDYMCHO.js")).executeTests;
1911
1911
  const report = await runTests(testArgs);
1912
1912
  ctx.send({ type: "info", message: report });
1913
1913
  } catch (err) {
@@ -2183,7 +2183,7 @@ async function handleMemory(args, ctx) {
2183
2183
  }
2184
2184
  if (intent.kind === "status") {
2185
2185
  const { getChatIndexStatus } = await import("./chat-index-7CLR4CBG.js");
2186
- const { listMemoryEntries: listMemoryEntries2, isMemoryExpired: isMemoryExpired2, formatMemoryForPrompt: formatMemoryForPrompt2 } = await import("./persistent-memory-WV7EXQKP.js");
2186
+ const { listMemoryEntries: listMemoryEntries2, isMemoryExpired: isMemoryExpired2, formatMemoryForPrompt: formatMemoryForPrompt2 } = await import("./persistent-memory-Z5HYYVXL.js");
2187
2187
  const memories = listMemoryEntries2(configDir, { includeExpired: true, includeRejected: true });
2188
2188
  const injected = formatMemoryForPrompt2(configDir, process.cwd(), ctx.config.get("memory")?.maxChars);
2189
2189
  const view = buildMemoryStatusView({
@@ -2206,7 +2206,7 @@ async function handleMemory(args, ctx) {
2206
2206
  return;
2207
2207
  }
2208
2208
  if (intent.kind === "recall") {
2209
- const { searchPersistentMemories, touchMemoryReferences } = await import("./persistent-memory-WV7EXQKP.js");
2209
+ const { searchPersistentMemories, touchMemoryReferences } = await import("./persistent-memory-Z5HYYVXL.js");
2210
2210
  const { searchChatMemory } = await import("./chat-index-7CLR4CBG.js");
2211
2211
  const persistentHits = searchPersistentMemories(configDir, intent.query, process.cwd(), 3);
2212
2212
  if (persistentHits.length > 0) {
@@ -2327,7 +2327,7 @@ async function handleMemory(args, ctx) {
2327
2327
  ctx.handleMemoryManage(intent.action, args[1], intent.action === "expire" ? args[2] : void 0);
2328
2328
  } else if (intent.kind === "export") {
2329
2329
  if (args[1] === "md") {
2330
- const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-WV7EXQKP.js");
2330
+ const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-Z5HYYVXL.js");
2331
2331
  ctx.send({
2332
2332
  type: "export_data",
2333
2333
  format: "md",
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ToolRegistry
4
- } from "./chunk-WKPPGB7V.js";
4
+ } from "./chunk-L4VU5F7P.js";
5
5
  import "./chunk-6JHACXB3.js";
6
- import "./chunk-3YZGQIDN.js";
6
+ import "./chunk-ROUVNUZZ.js";
7
7
  import "./chunk-RWRZVQCB.js";
8
8
  import "./chunk-B3MPYI4E.js";
9
9
  import "./chunk-M6HLYG33.js";
@@ -14,7 +14,7 @@ import "./chunk-JL44HGZC.js";
14
14
  import "./chunk-3FEZSLGI.js";
15
15
  import {
16
16
  runTool
17
- } from "./chunk-WKAILZFD.js";
17
+ } from "./chunk-EHACKFNT.js";
18
18
  import "./chunk-RS7SKYTS.js";
19
19
  import {
20
20
  getDangerLevel,
@@ -24,10 +24,10 @@ import "./chunk-TU3L3PW7.js";
24
24
  import "./chunk-HOSJZMQS.js";
25
25
  import "./chunk-BMLQPSHP.js";
26
26
  import "./chunk-JJFJWD35.js";
27
- import "./chunk-WKNVMMCN.js";
27
+ import "./chunk-IVHG47FR.js";
28
28
  import {
29
29
  VERSION
30
- } from "./chunk-SXWQKEU4.js";
30
+ } from "./chunk-ZX4L2ZYI.js";
31
31
  import "./chunk-SXIJLSVF.js";
32
32
 
33
33
  // src/mcp/server.ts
@@ -4,9 +4,9 @@ import {
4
4
  googleSearchContext,
5
5
  isToolCapableProvider,
6
6
  truncateOutput
7
- } from "./chunk-WKPPGB7V.js";
7
+ } from "./chunk-L4VU5F7P.js";
8
8
  import "./chunk-6JHACXB3.js";
9
- import "./chunk-3YZGQIDN.js";
9
+ import "./chunk-ROUVNUZZ.js";
10
10
  import "./chunk-RWRZVQCB.js";
11
11
  import "./chunk-B3MPYI4E.js";
12
12
  import "./chunk-M6HLYG33.js";
@@ -17,7 +17,7 @@ import "./chunk-JL44HGZC.js";
17
17
  import "./chunk-3FEZSLGI.js";
18
18
  import {
19
19
  runTool
20
- } from "./chunk-WKAILZFD.js";
20
+ } from "./chunk-EHACKFNT.js";
21
21
  import "./chunk-RS7SKYTS.js";
22
22
  import {
23
23
  getDangerLevel,
@@ -29,10 +29,10 @@ import {
29
29
  atomicWriteFileSync
30
30
  } from "./chunk-BMLQPSHP.js";
31
31
  import "./chunk-JJFJWD35.js";
32
- import "./chunk-WKNVMMCN.js";
32
+ import "./chunk-IVHG47FR.js";
33
33
  import {
34
34
  SUBAGENT_ALLOWED_TOOLS
35
- } from "./chunk-SXWQKEU4.js";
35
+ } from "./chunk-ZX4L2ZYI.js";
36
36
  import "./chunk-SXIJLSVF.js";
37
37
 
38
38
  // src/hub/task-orchestrator.ts
@@ -9,10 +9,10 @@ import {
9
9
  import "./chunk-RS7SKYTS.js";
10
10
  import {
11
11
  ConfigManager
12
- } from "./chunk-LCVJYA32.js";
12
+ } from "./chunk-IXR2P7WK.js";
13
13
  import "./chunk-TU3L3PW7.js";
14
14
  import "./chunk-BMLQPSHP.js";
15
- import "./chunk-SXWQKEU4.js";
15
+ import "./chunk-ZX4L2ZYI.js";
16
16
 
17
17
  // src/cli/usage.ts
18
18
  function classifyRowCost(row) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jinzd-ai-cli",
3
- "version": "0.4.310",
3
+ "version": "0.4.311",
4
4
  "description": "Cross-platform REPL-style AI CLI with multi-provider support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -130,7 +130,7 @@
130
130
  "vitest": "3.2.7"
131
131
  },
132
132
  "overrides": {
133
- "adm-zip": "0.6.0",
133
+ "adm-zip": "0.6.1",
134
134
  "esbuild": "0.28.1",
135
135
  "fast-uri": "3.1.7",
136
136
  "js-yaml": "4.3.2",