jinzd-ai-cli 0.4.226 → 0.4.228

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 (31) hide show
  1. package/dist/{batch-IJ6X3SWP.js → batch-K6IRL6TU.js} +2 -2
  2. package/dist/{chunk-KDJEFBOS.js → chunk-32LTIQQN.js} +4 -4
  3. package/dist/{chunk-HZC6JFPM.js → chunk-4GF47FW3.js} +4 -4
  4. package/dist/{chunk-D5A2K4AO.js → chunk-ACO2RJY3.js} +1 -1
  5. package/dist/{chunk-PUBCJF7E.js → chunk-EEQHP4GK.js} +19 -5
  6. package/dist/{chunk-NQYNIK4C.js → chunk-JGQ3TULW.js} +31 -31
  7. package/dist/{chunk-55NPPWBW.js → chunk-JO2CAKHA.js} +1 -1
  8. package/dist/{chunk-QNIFXUKV.js → chunk-JZNKM3RV.js} +1 -1
  9. package/dist/{chunk-SHJL3ZEA.js → chunk-LDWTVCE5.js} +1 -1
  10. package/dist/{chunk-GOMPGWWO.js → chunk-MQVC7FJH.js} +9 -9
  11. package/dist/{chunk-PEUYYZQU.js → chunk-NI34BUBR.js} +1 -1
  12. package/dist/{chunk-2X2DOHA6.js → chunk-NR5U6LVG.js} +21 -3
  13. package/dist/{chunk-XPBEJB27.js → chunk-ODYTXQ26.js} +37 -0
  14. package/dist/{chunk-XN24Y4OZ.js → chunk-VSEXYCEE.js} +2 -2
  15. package/dist/{chunk-CITDVXXM.js → chunk-YVMACMXW.js} +30 -1
  16. package/dist/{ci-7SRQSN7E.js → ci-D35MUGEH.js} +6 -6
  17. package/dist/{ci-format-FM52GDQG.js → ci-format-EQ4HGHXR.js} +2 -2
  18. package/dist/{constants-LX5P32PH.js → constants-F2LRIWV2.js} +1 -1
  19. package/dist/{doctor-cli-6KSSI65N.js → doctor-cli-R3AH5CLF.js} +6 -6
  20. package/dist/electron-server.js +92 -41
  21. package/dist/{hub-AWY3NZUF.js → hub-AAYGBUDA.js} +3 -3
  22. package/dist/{hub-server-XX36DX7O.js → hub-server-XA7HTVLD.js} +1 -1
  23. package/dist/index.js +27 -26
  24. package/dist/{pr-IO56XB47.js → pr-HX6V63FO.js} +6 -6
  25. package/dist/{run-tests-FKBEUFKX.js → run-tests-5QHWA4MF.js} +2 -2
  26. package/dist/{run-tests-NQWCJSZX.js → run-tests-7SGHDDHL.js} +1 -1
  27. package/dist/{server-I2RRWW7W.js → server-E5XTQG7W.js} +5 -5
  28. package/dist/{server-Y7YXAYF3.js → server-O2YK3VWK.js} +10 -10
  29. package/dist/{task-orchestrator-CODR7HC6.js → task-orchestrator-T2LUS5ZQ.js} +7 -6
  30. package/dist/{usage-6H5AIUZM.js → usage-AIHU5PIY.js} +3 -3
  31. package/package.json +1 -1
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ConfigManager
4
- } from "./chunk-NQYNIK4C.js";
4
+ } from "./chunk-JGQ3TULW.js";
5
5
  import "./chunk-5ULLIOVC.js";
6
- import "./chunk-QNIFXUKV.js";
6
+ import "./chunk-JZNKM3RV.js";
7
7
  import {
8
8
  atomicWriteFileSync
9
9
  } from "./chunk-IW3Q7AE5.js";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  evaluateCiGate,
4
4
  normalizeCiThresholds
5
- } from "./chunk-55NPPWBW.js";
5
+ } from "./chunk-JO2CAKHA.js";
6
6
  import {
7
7
  buildReviewPrompt,
8
8
  buildSecurityReviewPrompt,
@@ -10,13 +10,13 @@ import {
10
10
  } from "./chunk-HLWUDRBO.js";
11
11
  import {
12
12
  ProviderRegistry
13
- } from "./chunk-PUBCJF7E.js";
13
+ } from "./chunk-EEQHP4GK.js";
14
14
  import {
15
15
  ConfigManager
16
- } from "./chunk-NQYNIK4C.js";
16
+ } from "./chunk-JGQ3TULW.js";
17
17
  import {
18
18
  VERSION
19
- } from "./chunk-QNIFXUKV.js";
19
+ } from "./chunk-JZNKM3RV.js";
20
20
 
21
21
  // src/cli/ci.ts
22
22
  import { execFileSync } from "child_process";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ProviderRegistry
4
- } from "./chunk-PUBCJF7E.js";
4
+ } from "./chunk-EEQHP4GK.js";
5
5
  import {
6
6
  getActivePluginAssets,
7
7
  getPendingHookTrust,
@@ -11,10 +11,10 @@ import {
11
11
  listHooks,
12
12
  listInstalledPlugins,
13
13
  resetStats
14
- } from "./chunk-D5A2K4AO.js";
14
+ } from "./chunk-ACO2RJY3.js";
15
15
  import {
16
16
  ConfigManager
17
- } from "./chunk-NQYNIK4C.js";
17
+ } from "./chunk-JGQ3TULW.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-QNIFXUKV.js";
29
+ } from "./chunk-JZNKM3RV.js";
30
30
 
31
31
  // src/diagnostics/doctor-report.ts
32
32
  import { existsSync as existsSync3, statSync as statSync2 } from "fs";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  CONFIG_DIR_NAME,
4
4
  PLUGINS_DIR_NAME
5
- } from "./chunk-QNIFXUKV.js";
5
+ } from "./chunk-JZNKM3RV.js";
6
6
  import {
7
7
  atomicWriteFileSync
8
8
  } from "./chunk-IW3Q7AE5.js";
@@ -3,7 +3,7 @@ import {
3
3
  detectsHallucinatedFileOp,
4
4
  repairToolCallArguments,
5
5
  schemaToJsonSchema
6
- } from "./chunk-XPBEJB27.js";
6
+ } from "./chunk-ODYTXQ26.js";
7
7
  import {
8
8
  AuthError,
9
9
  ProviderError,
@@ -2250,18 +2250,32 @@ var ProviderRegistry = class {
2250
2250
  configDir;
2251
2251
  async initialize(getApiKey, getOptions, customProviderConfigs, configDir) {
2252
2252
  this.configDir = configDir;
2253
- for (const ProviderClass of BUILT_IN_PROVIDERS) {
2253
+ const initTasks = BUILT_IN_PROVIDERS.map(async (ProviderClass) => {
2254
2254
  const provider = new ProviderClass();
2255
2255
  const apiKey = getApiKey(provider.info.id);
2256
2256
  if (apiKey || !provider.info.requiresApiKey) {
2257
2257
  const options = getOptions?.(provider.info.id) ?? {};
2258
+ const pInit = provider.initialize(apiKey ?? "", options);
2259
+ return { provider, pInit, requiresApiKey: !!provider.info.requiresApiKey };
2260
+ }
2261
+ return null;
2262
+ });
2263
+ const settled = await Promise.allSettled(
2264
+ initTasks.map(async (task) => {
2265
+ const result = await task;
2266
+ if (!result) return;
2267
+ const { provider, pInit, requiresApiKey } = result;
2258
2268
  try {
2259
- await provider.initialize(apiKey ?? "", options);
2269
+ await pInit;
2260
2270
  this.providers.set(provider.info.id, provider);
2261
2271
  } catch (err) {
2262
- if (provider.info.requiresApiKey) throw err;
2272
+ if (requiresApiKey) throw err;
2263
2273
  }
2264
- }
2274
+ })
2275
+ );
2276
+ const keyErrors = settled.filter((r) => r.status === "rejected").map((r) => r.reason);
2277
+ if (keyErrors.length > 0) {
2278
+ throw keyErrors[0];
2265
2279
  }
2266
2280
  this.customConfigs = customProviderConfigs ?? [];
2267
2281
  for (const cfg of this.customConfigs) {
@@ -8,7 +8,7 @@ import {
8
8
  CONFIG_FILE_NAME,
9
9
  HISTORY_DIR_NAME,
10
10
  PLUGINS_DIR_NAME
11
- } from "./chunk-QNIFXUKV.js";
11
+ } from "./chunk-JZNKM3RV.js";
12
12
  import {
13
13
  atomicWriteFileSync
14
14
  } from "./chunk-IW3Q7AE5.js";
@@ -21,22 +21,22 @@ import { homedir } from "os";
21
21
  // src/config/schema.ts
22
22
  import { z } from "zod";
23
23
  var CustomModelSchema = z.object({
24
- id: z.string(),
25
- displayName: z.string().optional(),
24
+ id: z.string().max(100),
25
+ displayName: z.string().max(200).optional(),
26
26
  contextWindow: z.number().optional()
27
27
  });
28
28
  var CustomProviderConfigSchema = z.object({
29
- id: z.string(),
29
+ id: z.string().max(100),
30
30
  // 唯一 ID,不能与内置 provider 重名
31
- displayName: z.string(),
31
+ displayName: z.string().max(200),
32
32
  // 显示名称
33
- apiKey: z.string().optional(),
33
+ apiKey: z.string().max(4e3).optional(),
34
34
  // 可选:直接在此写 key(也可通过 apiKeys 字段或环境变量提供)
35
- baseUrl: z.string(),
35
+ baseUrl: z.string().max(2e3),
36
36
  // OpenAI 兼容 API 的 base URL(必填)
37
- defaultModel: z.string(),
37
+ defaultModel: z.string().max(200),
38
38
  // 默认使用的模型 ID
39
- models: z.array(CustomModelSchema).default([]),
39
+ models: z.array(CustomModelSchema).max(100).default([]),
40
40
  timeout: z.number().optional()
41
41
  // 请求超时(ms),覆盖全局默认值
42
42
  });
@@ -51,19 +51,19 @@ var ModelParamsSchema = z.object({
51
51
  });
52
52
  var UserProfileSchema = z.object({
53
53
  /** 真实姓名(如 "Jin Zhengdong") */
54
- name: z.string().optional(),
54
+ name: z.string().max(100).optional(),
55
55
  /** 昵称/称呼偏好(如 "东叔"),AI 会以此称呼你 */
56
- nickname: z.string().optional(),
56
+ nickname: z.string().max(100).optional(),
57
57
  /** 职业角色(如 "Full-stack developer"、"Data scientist") */
58
- role: z.string().optional(),
58
+ role: z.string().max(200).optional(),
59
59
  /** 个人简介 / 专长描述(1-3 句话) */
60
- bio: z.string().optional(),
60
+ bio: z.string().max(1e4).optional(),
61
61
  /** 兴趣领域或技术栈(如 ["TypeScript", "Rust", "AI/ML"]) */
62
- interests: z.array(z.string()).default([]),
62
+ interests: z.array(z.string()).max(100).default([]),
63
63
  /** 语言偏好(如 "zh-CN"、"en"),AI 将据此选择交流语言 */
64
- locale: z.string().optional(),
64
+ locale: z.string().max(20).optional(),
65
65
  /** 自定义人设补充(自由格式,直接注入 system prompt) */
66
- extra: z.string().optional()
66
+ extra: z.string().max(5e3).optional()
67
67
  }).default({});
68
68
  var ConfigSchema = z.object({
69
69
  version: z.string().default("1.0.0"),
@@ -85,7 +85,7 @@ var ConfigSchema = z.object({
85
85
  // HTTP/HTTPS 代理地址(Node.js 不自动使用系统代理,需显式配置)
86
86
  // 例:http://127.0.0.1:10809
87
87
  // 也可通过环境变量 HTTPS_PROXY / HTTP_PROXY 覆盖
88
- proxy: z.string().optional(),
88
+ proxy: z.string().max(500).optional(),
89
89
  // 自定义 Provider 列表(OpenAI 兼容接口,无需改代码)
90
90
  customProviders: z.array(CustomProviderConfigSchema).default([]),
91
91
  // 按模型 ID 存储的推理参数(key 为模型 ID,如 "deepseek-chat")
@@ -119,7 +119,7 @@ var ConfigSchema = z.object({
119
119
  session: z.object({
120
120
  autoSave: z.boolean().default(true),
121
121
  maxHistoryDays: z.number().default(30),
122
- systemPrompt: z.string().optional()
122
+ systemPrompt: z.string().max(1e5).optional()
123
123
  }).default({}),
124
124
  // 项目上下文文件配置
125
125
  // 启动时自动读取并注入 system prompt,类似 Claude Code 的 CLAUDE.md / Codex AGENTS.md 机制
@@ -127,14 +127,14 @@ var ConfigSchema = z.object({
127
127
  // 设为 false 可禁用此功能;指定字符串时仅加载 cwd 下的该文件
128
128
  contextFile: z.union([z.string(), z.literal(false)]).default("auto"),
129
129
  context: z.object({
130
- projectDocFallbackFilenames: z.array(z.string()).default([]),
130
+ projectDocFallbackFilenames: z.array(z.string().max(500)).max(20).default([]),
131
131
  projectDocMaxBytes: z.number().int().positive().default(32 * 1024),
132
132
  showLoadedContextSources: z.boolean().default(false)
133
133
  }).default({}),
134
134
  // Google Custom Search API 的 Search Engine ID (cx 参数)
135
135
  // API Key 通过 apiKeys['google-search'] 或 AICLI_API_KEY_GOOGLESEARCH 环境变量配置
136
136
  // CX 也可通过 AICLI_GOOGLE_CX 环境变量覆盖
137
- googleSearchEngineId: z.string().optional(),
137
+ googleSearchEngineId: z.string().max(200).optional(),
138
138
  // google_search 工具的安全开关(v0.4.135+)
139
139
  // 默认 disabled。这个工具调用 Google Custom Search API,没有原生 daily-spend cap——
140
140
  // 业内有多起 key 被盗后产生数万美元账单的真实案例。现在内置 web_search 工具走 Bing/Google
@@ -152,10 +152,10 @@ var ConfigSchema = z.object({
152
152
  // 配置格式兼容 Claude Desktop(command + args + env)
153
153
  // 示例:{ "filesystem": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path"] } }
154
154
  mcpServers: z.record(z.object({
155
- command: z.string(),
156
- args: z.array(z.string()).default([]),
155
+ command: z.string().max(500),
156
+ args: z.array(z.string()).max(100).default([]),
157
157
  env: z.record(z.string()).optional(),
158
- timeout: z.number().default(3e4)
158
+ timeout: z.number().int().min(100).max(3e5).default(3e4)
159
159
  })).default({}),
160
160
  // Hooks 生命周期(v0.4.212+):兼容旧 pre/post 字符串,同时支持 events.<EventName> 结构化 JSON hook。
161
161
  hooks: z.object({
@@ -189,8 +189,8 @@ var ConfigSchema = z.object({
189
189
  networkPolicy: z.object({
190
190
  enabled: z.boolean().default(false),
191
191
  defaultAction: z.enum(["allow", "confirm", "deny"]).default("confirm"),
192
- allowDomains: z.array(z.string()).default([]),
193
- denyDomains: z.array(z.string()).default([]),
192
+ allowDomains: z.array(z.string().max(500)).max(100).default([]),
193
+ denyDomains: z.array(z.string().max(500)).max(100).default([]),
194
194
  allowPorts: z.array(z.number().int().min(1).max(65535)).default([]),
195
195
  denyPorts: z.array(z.number().int().min(1).max(65535)).default([]),
196
196
  allowPrivateNetwork: z.boolean().default(false),
@@ -204,7 +204,7 @@ var ConfigSchema = z.object({
204
204
  }).default({ enabled: false, defaultAction: "confirm", allowDomains: [], denyDomains: [], allowPorts: [], denyPorts: [], allowPrivateNetwork: false, tools: {} }),
205
205
  // 权限 Profile(v0.4.211+):legacy 保持旧行为;其余 profile 提供更清晰的安全边界。
206
206
  defaultPermissionProfile: z.enum(["legacy", "read-only", "workspace-write", "danger-full-access"]).default("legacy"),
207
- allowedPermissionProfiles: z.array(z.string()).default(["legacy", "read-only", "workspace-write", "danger-full-access"]),
207
+ allowedPermissionProfiles: z.array(z.string().max(50)).max(20).default(["legacy", "read-only", "workspace-write", "danger-full-access"]),
208
208
  permissionProfiles: z.record(z.object({
209
209
  extends: z.enum(["legacy", "read-only", "workspace-write", "danger-full-access"]).optional(),
210
210
  defaultAction: z.enum(["auto-approve", "deny", "confirm"]).optional(),
@@ -221,7 +221,7 @@ var ConfigSchema = z.object({
221
221
  })).default({}),
222
222
  // 工具权限规则(按顺序匹配第一个生效;作为当前权限 Profile 内的细粒度规则)
223
223
  permissionRules: z.array(z.object({
224
- tool: z.string(),
224
+ tool: z.string().max(100),
225
225
  action: z.enum(["auto-approve", "deny", "confirm"]),
226
226
  when: z.object({
227
227
  dangerLevel: z.enum(["safe", "write", "destructive"]).optional(),
@@ -279,7 +279,7 @@ var ConfigSchema = z.object({
279
279
  redactOnSave: z.boolean().default(true),
280
280
  redactOnSend: z.boolean().default(false),
281
281
  mode: z.enum(["default", "strict", "off"]).default("default"),
282
- customPatterns: z.array(z.string()).default([])
282
+ customPatterns: z.array(z.string().max(200)).max(50).default([])
283
283
  }).default({}),
284
284
  // 智能模型路由(v0.4.68+)
285
285
  // 按用户每轮输入的内容/标签/长度动态选择模型,在同一 provider 内切换,
@@ -291,13 +291,13 @@ var ConfigSchema = z.object({
291
291
  enabled: z.boolean().default(false),
292
292
  rules: z.array(z.object({
293
293
  match: z.object({
294
- contains: z.array(z.string()).optional(),
294
+ contains: z.array(z.string().max(200)).max(50).optional(),
295
295
  maxLength: z.number().int().positive().optional(),
296
296
  minLength: z.number().int().positive().optional(),
297
297
  tag: z.string().optional()
298
298
  }),
299
299
  model: z.string(),
300
- name: z.string().optional()
300
+ name: z.string().max(100).optional()
301
301
  })).default([]),
302
302
  fallback: z.string().optional()
303
303
  }).default({ enabled: false, rules: [] }),
@@ -317,7 +317,7 @@ var ConfigSchema = z.object({
317
317
  maxBackoffMs: z.number().int().positive().default(8e3),
318
318
  /** 兜底 provider 链,每个 entry 仅尝试 1 次。model 省略则使用 provider 的 defaultModel。 */
319
319
  chain: z.array(z.object({
320
- provider: z.string(),
320
+ provider: z.string().max(100),
321
321
  model: z.string().optional()
322
322
  })).default([])
323
323
  }).default({ enabled: false, retries: 2, initialBackoffMs: 500, maxBackoffMs: 8e3, chain: [] })
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  VERSION
4
- } from "./chunk-QNIFXUKV.js";
4
+ } from "./chunk-JZNKM3RV.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
 
3
3
  // src/core/constants.ts
4
- var VERSION = "0.4.226";
4
+ var VERSION = "0.4.228";
5
5
  var APP_NAME = "ai-cli";
6
6
  var CONFIG_DIR_NAME = ".aicli";
7
7
  var CONFIG_FILE_NAME = "config.json";
@@ -6,7 +6,7 @@ import { platform } from "os";
6
6
  import chalk from "chalk";
7
7
 
8
8
  // src/core/constants.ts
9
- var VERSION = "0.4.226";
9
+ var VERSION = "0.4.228";
10
10
  var APP_NAME = "ai-cli";
11
11
  var CONFIG_DIR_NAME = ".aicli";
12
12
  var CONFIG_FILE_NAME = "config.json";
@@ -14,12 +14,12 @@ import {
14
14
  runHook,
15
15
  runLifecycleHooks,
16
16
  runTool
17
- } from "./chunk-D5A2K4AO.js";
17
+ } from "./chunk-ACO2RJY3.js";
18
18
  import {
19
19
  getDangerLevel,
20
20
  isFileWriteTool,
21
21
  runLeanAgentLoop
22
- } from "./chunk-XPBEJB27.js";
22
+ } from "./chunk-ODYTXQ26.js";
23
23
  import {
24
24
  EnvLoader,
25
25
  NetworkError,
@@ -33,7 +33,7 @@ import {
33
33
  } from "./chunk-4BKXL7SM.js";
34
34
  import {
35
35
  runTestsTool
36
- } from "./chunk-PEUYYZQU.js";
36
+ } from "./chunk-NI34BUBR.js";
37
37
  import {
38
38
  CONFIG_DIR_NAME,
39
39
  DEFAULT_MAX_TOOL_OUTPUT_CHARS_CAP,
@@ -43,7 +43,7 @@ import {
43
43
  SUBAGENT_ALLOWED_TOOLS,
44
44
  SUBAGENT_DEFAULT_MAX_ROUNDS,
45
45
  SUBAGENT_MAX_ROUNDS_LIMIT
46
- } from "./chunk-QNIFXUKV.js";
46
+ } from "./chunk-JZNKM3RV.js";
47
47
  import {
48
48
  loadChatIndex,
49
49
  searchChatMemory
@@ -1185,7 +1185,7 @@ var readFileTool = {
1185
1185
  dangerous: false
1186
1186
  },
1187
1187
  async execute(args) {
1188
- const filePath = String(args["path"] ?? "");
1188
+ const filePath = String(args["path"] ?? args["file"] ?? "");
1189
1189
  const encoding = args["encoding"] ?? "utf-8";
1190
1190
  const rawOffset = args["offset"];
1191
1191
  const rawLimit = args["limit"];
@@ -2835,7 +2835,7 @@ Do NOT split a long document into many write_file(append=true) calls. That patte
2835
2835
  // executor 会将 write_file 标记为 'write' 级别
2836
2836
  },
2837
2837
  async execute(args) {
2838
- const filePath = String(args["path"] ?? "");
2838
+ const filePath = String(args["path"] ?? args["file"] ?? "");
2839
2839
  const content = String(args["content"] ?? "");
2840
2840
  const encoding = args["encoding"] ?? "utf-8";
2841
2841
  const appendMode = String(args["append"] ?? "false").toLowerCase() === "true";
@@ -3227,7 +3227,7 @@ Note: Path can be absolute or relative to cwd.`,
3227
3227
  // executor 中 edit_file 按 write 级别处理
3228
3228
  },
3229
3229
  async execute(args) {
3230
- const filePath = String(args["path"] ?? "");
3230
+ const filePath = String(args["path"] ?? args["file"] ?? "");
3231
3231
  const encoding = args["encoding"] ?? "utf-8";
3232
3232
  if (!filePath) throw new ToolError("edit_file", "path is required");
3233
3233
  if (!existsSync6(filePath)) throw new ToolError("edit_file", `File not found: ${filePath}`);
@@ -4628,7 +4628,7 @@ Any of these triggers means use save_last_response, NOT write_file:
4628
4628
  // getDangerLevel 中标记为 write
4629
4629
  },
4630
4630
  async execute(args) {
4631
- const filePath = String(args["path"] ?? "");
4631
+ const filePath = String(args["path"] ?? args["file"] ?? "");
4632
4632
  if (!filePath) throw new ToolError("save_last_response", "path is required");
4633
4633
  const content = lastResponseStore.content;
4634
4634
  if (!content) {
@@ -6314,7 +6314,7 @@ var notebookEditTool = {
6314
6314
  dangerous: false
6315
6315
  },
6316
6316
  async execute(args) {
6317
- const filePath = String(args["path"] ?? "");
6317
+ const filePath = String(args["path"] ?? args["file"] ?? "");
6318
6318
  const action = String(args["action"] ?? "");
6319
6319
  const cellIndexRaw = Number(args["cell_index"]);
6320
6320
  const content = args["content"] != null ? String(args["content"]) : "";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  TEST_TIMEOUT
4
- } from "./chunk-QNIFXUKV.js";
4
+ } from "./chunk-JZNKM3RV.js";
5
5
 
6
6
  // src/tools/builtin/run-tests.ts
7
7
  import { execSync, spawnSync } from "child_process";
@@ -14,13 +14,31 @@ var ROLE_COLORS = [
14
14
  chalk.rgb(148, 103, 189)
15
15
  // purple
16
16
  ];
17
+ var CHALK_COLOR_NAMES = {
18
+ red: chalk.red,
19
+ green: chalk.green,
20
+ blue: chalk.blue,
21
+ yellow: chalk.yellow,
22
+ magenta: chalk.magenta,
23
+ cyan: chalk.cyan,
24
+ white: chalk.white,
25
+ gray: chalk.gray,
26
+ grey: chalk.grey,
27
+ black: chalk.black,
28
+ redBright: chalk.redBright,
29
+ greenBright: chalk.greenBright,
30
+ blueBright: chalk.blueBright,
31
+ yellowBright: chalk.yellowBright,
32
+ magentaBright: chalk.magentaBright,
33
+ cyanBright: chalk.cyanBright,
34
+ whiteBright: chalk.whiteBright
35
+ };
17
36
  var colorMap = /* @__PURE__ */ new Map();
18
37
  function assignRoleColors(roles) {
19
38
  colorMap.clear();
20
- const chalkColors = chalk;
21
39
  roles.forEach((role, i) => {
22
- if (role.color && chalkColors[role.color]) {
23
- colorMap.set(role.id, chalkColors[role.color]);
40
+ if (role.color && CHALK_COLOR_NAMES[role.color]) {
41
+ colorMap.set(role.id, CHALK_COLOR_NAMES[role.color]);
24
42
  } else {
25
43
  colorMap.set(role.id, ROLE_COLORS[i % ROLE_COLORS.length]);
26
44
  }
@@ -99,7 +99,44 @@ var HALLUCINATION_PATTERNS = [
99
99
  // “以下是图片的内容:”“以下是修改后的内容:”这类描述/对话。
100
100
  /以下是[^\n。.!!??]*?(?:教案|试卷|讲义|课件|课程|文件|文档|脚本|配置|程序|报告|表格|清单)[^\n。.!!??]{0,8}(?:内容)?[::]/
101
101
  ];
102
+ var QUICK_WRITE_KEYWORDS = [
103
+ // 中文写入动作
104
+ "\u5DF2\u4FDD\u5B58",
105
+ "\u5DF2\u5199\u5165",
106
+ "\u5DF2\u521B\u5EFA",
107
+ "\u5DF2\u751F\u6210",
108
+ "\u751F\u6210\u5B8C\u6210",
109
+ "\u4FDD\u5B58",
110
+ "\u5199\u5165",
111
+ "\u521B\u5EFA",
112
+ "\u751F\u6210",
113
+ // 中文文档名
114
+ "\u6587\u4EF6",
115
+ "\u6559\u6848",
116
+ "\u8BD5\u5377",
117
+ "\u8BB2\u4E49",
118
+ "\u8BFE\u4EF6",
119
+ "\u6587\u6863",
120
+ "\u811A\u672C",
121
+ "\u914D\u7F6E",
122
+ "\u7A0B\u5E8F",
123
+ "\u62A5\u544A",
124
+ "\u8868\u683C",
125
+ "\u6E05\u5355",
126
+ "\u7B14\u8BB0",
127
+ // 英文写入动作
128
+ "saved",
129
+ "written",
130
+ "created",
131
+ "File",
132
+ "file",
133
+ // emoji 勾选标记
134
+ "\u2705"
135
+ ];
102
136
  function detectsHallucinatedFileOp(content) {
137
+ if (!QUICK_WRITE_KEYWORDS.some((kw) => content.includes(kw))) {
138
+ return false;
139
+ }
103
140
  return HALLUCINATION_PATTERNS.some((pattern) => pattern.test(content));
104
141
  }
105
142
  function hadPreviousWriteToolCalls(extraMessages) {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  truncateForPersist
4
- } from "./chunk-GOMPGWWO.js";
4
+ } from "./chunk-MQVC7FJH.js";
5
5
  import {
6
6
  APP_NAME,
7
7
  CONFIG_DIR_NAME,
@@ -11,7 +11,7 @@ import {
11
11
  MCP_PROTOCOL_VERSION,
12
12
  MCP_TOOL_PREFIX,
13
13
  VERSION
14
- } from "./chunk-QNIFXUKV.js";
14
+ } from "./chunk-JZNKM3RV.js";
15
15
  import {
16
16
  atomicWriteFileSync
17
17
  } from "./chunk-IW3Q7AE5.js";
@@ -10,14 +10,18 @@ import {
10
10
  // src/core/cost-tracker.ts
11
11
  import { existsSync, readFileSync } from "fs";
12
12
  import { join } from "path";
13
- var CostTracker = class {
13
+ var CostTracker = class _CostTracker {
14
14
  filePath;
15
15
  records = [];
16
16
  dirty = false;
17
+ /** P2-PERF-04: debounce timer to batch rapid addCost() calls into a single save. */
18
+ _saveTimer;
17
19
  constructor(configDir) {
18
20
  this.filePath = join(configDir, "cost-history.json");
19
21
  this.load();
20
22
  }
23
+ /** P2-PERF-04: debounce interval (ms) — coalesces multiple rapid addCost calls. */
24
+ static SAVE_DEBOUNCE_MS = 2e3;
21
25
  load() {
22
26
  try {
23
27
  if (existsSync(this.filePath)) {
@@ -42,6 +46,10 @@ var CostTracker = class {
42
46
  */
43
47
  save() {
44
48
  if (!this.dirty) return;
49
+ if (this._saveTimer) {
50
+ clearTimeout(this._saveTimer);
51
+ this._saveTimer = void 0;
52
+ }
45
53
  const snapshot = {
46
54
  version: 1,
47
55
  records: [...this.records]
@@ -81,6 +89,15 @@ var CostTracker = class {
81
89
  m.cacheReadTokens += usage.cacheReadTokens ?? 0;
82
90
  m.calls += 1;
83
91
  this.dirty = true;
92
+ if (!this._saveTimer) {
93
+ this._saveTimer = setTimeout(() => {
94
+ this._saveTimer = void 0;
95
+ this.save();
96
+ }, _CostTracker.SAVE_DEBOUNCE_MS);
97
+ if (this._saveTimer && typeof this._saveTimer === "object" && "unref" in this._saveTimer) {
98
+ this._saveTimer.unref();
99
+ }
100
+ }
84
101
  if (this.records.length > 90) {
85
102
  this.records = this.records.slice(-90);
86
103
  }
@@ -222,6 +239,18 @@ var CostTracker = class {
222
239
  lines.push(`Last 7 days: ${last7.join(" ")}`);
223
240
  return lines.join("\n");
224
241
  }
242
+ /**
243
+ * P2-PERF-04: flush pending cost records to disk immediately.
244
+ * Call this before process exit or before reading cost data for display
245
+ * to ensure the in-memory buffer is reflected on disk.
246
+ */
247
+ flush() {
248
+ if (this._saveTimer) {
249
+ clearTimeout(this._saveTimer);
250
+ this._saveTimer = void 0;
251
+ }
252
+ this.save();
253
+ }
225
254
  };
226
255
 
227
256
  export {
@@ -3,14 +3,14 @@ import {
3
3
  CI_COMMENT_MARKER,
4
4
  countSeverity,
5
5
  runCi
6
- } from "./chunk-KDJEFBOS.js";
7
- import "./chunk-55NPPWBW.js";
6
+ } from "./chunk-32LTIQQN.js";
7
+ import "./chunk-JO2CAKHA.js";
8
8
  import "./chunk-HLWUDRBO.js";
9
- import "./chunk-PUBCJF7E.js";
10
- import "./chunk-XPBEJB27.js";
11
- import "./chunk-NQYNIK4C.js";
9
+ import "./chunk-EEQHP4GK.js";
10
+ import "./chunk-ODYTXQ26.js";
11
+ import "./chunk-JGQ3TULW.js";
12
12
  import "./chunk-5ULLIOVC.js";
13
- import "./chunk-QNIFXUKV.js";
13
+ import "./chunk-JZNKM3RV.js";
14
14
  import "./chunk-IW3Q7AE5.js";
15
15
  export {
16
16
  CI_COMMENT_MARKER,
@@ -6,8 +6,8 @@ import {
6
6
  formatCiResult,
7
7
  formatCiSarif,
8
8
  normalizeCiThresholds
9
- } from "./chunk-55NPPWBW.js";
10
- import "./chunk-QNIFXUKV.js";
9
+ } from "./chunk-JO2CAKHA.js";
10
+ import "./chunk-JZNKM3RV.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-QNIFXUKV.js";
41
+ } from "./chunk-JZNKM3RV.js";
42
42
  export {
43
43
  AGENTIC_BEHAVIOR_GUIDELINE,
44
44
  APP_NAME,
@@ -2,14 +2,14 @@
2
2
  import {
3
3
  formatDoctorReport,
4
4
  runDoctorCli
5
- } from "./chunk-HZC6JFPM.js";
6
- import "./chunk-PUBCJF7E.js";
7
- import "./chunk-D5A2K4AO.js";
8
- import "./chunk-XPBEJB27.js";
9
- import "./chunk-NQYNIK4C.js";
5
+ } from "./chunk-4GF47FW3.js";
6
+ import "./chunk-EEQHP4GK.js";
7
+ import "./chunk-ACO2RJY3.js";
8
+ import "./chunk-ODYTXQ26.js";
9
+ import "./chunk-JGQ3TULW.js";
10
10
  import "./chunk-5ULLIOVC.js";
11
11
  import "./chunk-HOSJZMQS.js";
12
- import "./chunk-QNIFXUKV.js";
12
+ import "./chunk-JZNKM3RV.js";
13
13
  import "./chunk-IW3Q7AE5.js";
14
14
  export {
15
15
  formatDoctorReport,