jinzd-ai-cli 0.4.201 → 0.4.203

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.
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ConfigManager
4
- } from "./chunk-QT5SGLTM.js";
4
+ } from "./chunk-EOYN2PCH.js";
5
5
  import "./chunk-TZQHYZKT.js";
6
- import "./chunk-SDT4DCNX.js";
6
+ import "./chunk-RFWBHCDC.js";
7
7
  import {
8
8
  atomicWriteFileSync
9
9
  } from "./chunk-IW3Q7AE5.js";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  CONFIG_DIR_NAME,
4
4
  VERSION
5
- } from "./chunk-SDT4DCNX.js";
5
+ } from "./chunk-RFWBHCDC.js";
6
6
 
7
7
  // src/diagnostics/crash-log.ts
8
8
  import {
@@ -5,15 +5,15 @@ import {
5
5
  } from "./chunk-T2NL5ZIA.js";
6
6
  import {
7
7
  runTestsTool
8
- } from "./chunk-C46JMUDC.js";
8
+ } from "./chunk-VYCSZBII.js";
9
9
  import {
10
10
  runTool
11
- } from "./chunk-YUA2KL7W.js";
11
+ } from "./chunk-ZEDQBXVK.js";
12
12
  import {
13
13
  getDangerLevel,
14
14
  isFileWriteTool,
15
15
  runLeanAgentLoop
16
- } from "./chunk-5UR6ZOF4.js";
16
+ } from "./chunk-SMFRJCXB.js";
17
17
  import {
18
18
  EnvLoader,
19
19
  NetworkError,
@@ -26,7 +26,7 @@ import {
26
26
  SUBAGENT_ALLOWED_TOOLS,
27
27
  SUBAGENT_DEFAULT_MAX_ROUNDS,
28
28
  SUBAGENT_MAX_ROUNDS_LIMIT
29
- } from "./chunk-SDT4DCNX.js";
29
+ } from "./chunk-RFWBHCDC.js";
30
30
  import {
31
31
  fileCheckpoints
32
32
  } from "./chunk-4BKXL7SM.js";
@@ -8,7 +8,7 @@ import {
8
8
  CONFIG_FILE_NAME,
9
9
  HISTORY_DIR_NAME,
10
10
  PLUGINS_DIR_NAME
11
- } from "./chunk-SDT4DCNX.js";
11
+ } from "./chunk-RFWBHCDC.js";
12
12
 
13
13
  // src/config/config-manager.ts
14
14
  import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
@@ -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.201";
9
+ var VERSION = "0.4.203";
10
10
  var APP_NAME = "ai-cli";
11
11
  var CONFIG_DIR_NAME = ".aicli";
12
12
  var CONFIG_FILE_NAME = "config.json";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/core/constants.ts
4
- var VERSION = "0.4.201";
4
+ var VERSION = "0.4.203";
5
5
  var APP_NAME = "ai-cli";
6
6
  var CONFIG_DIR_NAME = ".aicli";
7
7
  var CONFIG_FILE_NAME = "config.json";
@@ -484,6 +484,12 @@ function isCleanDocumentBody(content) {
484
484
  if (detectPseudoToolCalls(content)) return false;
485
485
  return looksLikeDocumentBody(content);
486
486
  }
487
+ function stripOuterCodeFence(content) {
488
+ const trimmed = content.trim();
489
+ const m = trimmed.match(/^```[^\n`]*\n([\s\S]*?)\n```\s*$/);
490
+ if (m) return m[1];
491
+ return content;
492
+ }
487
493
  function teeFileStats(content) {
488
494
  return { lines: content.split("\n").length, bytes: Buffer.byteLength(content, "utf-8") };
489
495
  }
@@ -1062,6 +1068,7 @@ export {
1062
1068
  TEE_FINAL_USER_NUDGE,
1063
1069
  CONTENT_ONLY_STREAM_REMINDER,
1064
1070
  isCleanDocumentBody,
1071
+ stripOuterCodeFence,
1065
1072
  freshPriorContent,
1066
1073
  evaluateTeeContent,
1067
1074
  buildDeferredSaveInstruction,
@@ -3,7 +3,7 @@ import {
3
3
  detectsHallucinatedFileOp,
4
4
  repairToolCallArguments,
5
5
  schemaToJsonSchema
6
- } from "./chunk-5UR6ZOF4.js";
6
+ } from "./chunk-SMFRJCXB.js";
7
7
  import {
8
8
  AuthError,
9
9
  ProviderError,
@@ -925,6 +925,18 @@ function toUsage(u) {
925
925
  if (cached > 0) usage.cacheReadTokens = cached;
926
926
  return usage;
927
927
  }
928
+ function isLoopbackBaseUrl(baseUrl) {
929
+ if (!baseUrl) return false;
930
+ let host;
931
+ try {
932
+ host = new URL(baseUrl).hostname;
933
+ } catch {
934
+ return false;
935
+ }
936
+ host = host.replace(/^\[|\]$/g, "").toLowerCase();
937
+ if (host === "localhost" || host === "::1" || host === "0.0.0.0") return true;
938
+ return /^127(?:\.\d{1,3}){3}$/.test(host);
939
+ }
928
940
  var OpenAICompatibleProvider = class extends BaseProvider {
929
941
  client;
930
942
  defaultTimeout = 6e4;
@@ -940,7 +952,7 @@ var OpenAICompatibleProvider = class extends BaseProvider {
940
952
  baseURL: options?.baseUrl ?? this.defaultBaseUrl,
941
953
  timeout: this.defaultTimeout
942
954
  };
943
- const proxyUrl = options?.proxy;
955
+ const proxyUrl = isLoopbackBaseUrl(clientOptions.baseURL) ? void 0 : options?.proxy;
944
956
  try {
945
957
  const { Agent, ProxyAgent, fetch: undiciFetch } = await import("undici");
946
958
  const STREAM_BODY_TIMEOUT = 30 * 60 * 1e3;
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  TEST_TIMEOUT
4
- } from "./chunk-SDT4DCNX.js";
4
+ } from "./chunk-RFWBHCDC.js";
5
5
 
6
6
  // src/tools/builtin/run-tests.ts
7
7
  import { execSync, spawnSync } from "child_process";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  truncateForPersist
4
- } from "./chunk-HLOHSMTT.js";
4
+ } from "./chunk-742TILCK.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-SDT4DCNX.js";
14
+ } from "./chunk-RFWBHCDC.js";
15
15
 
16
16
  // src/mcp/client.ts
17
17
  import { spawn } from "child_process";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CONFIG_DIR_NAME
4
- } from "./chunk-SDT4DCNX.js";
4
+ } from "./chunk-RFWBHCDC.js";
5
5
  import {
6
6
  atomicWriteFileSync
7
7
  } from "./chunk-IW3Q7AE5.js";
@@ -6,15 +6,15 @@ import {
6
6
  } from "./chunk-HLWUDRBO.js";
7
7
  import {
8
8
  ProviderRegistry
9
- } from "./chunk-JP6ESDV7.js";
10
- import "./chunk-5UR6ZOF4.js";
9
+ } from "./chunk-UZISJ3KZ.js";
10
+ import "./chunk-SMFRJCXB.js";
11
11
  import {
12
12
  ConfigManager
13
- } from "./chunk-QT5SGLTM.js";
13
+ } from "./chunk-EOYN2PCH.js";
14
14
  import "./chunk-TZQHYZKT.js";
15
15
  import {
16
16
  VERSION
17
- } from "./chunk-SDT4DCNX.js";
17
+ } from "./chunk-RFWBHCDC.js";
18
18
 
19
19
  // src/cli/ci.ts
20
20
  import { execFileSync, execSync } from "child_process";
@@ -36,7 +36,7 @@ import {
36
36
  TEST_TIMEOUT,
37
37
  VERSION,
38
38
  buildUserIdentityPrompt
39
- } from "./chunk-SDT4DCNX.js";
39
+ } from "./chunk-RFWBHCDC.js";
40
40
  export {
41
41
  AGENTIC_BEHAVIOR_GUIDELINE,
42
42
  APP_NAME,
@@ -2,26 +2,26 @@
2
2
  import {
3
3
  getConfigDirUsage,
4
4
  listRecentCrashes
5
- } from "./chunk-IAWXC2SO.js";
5
+ } from "./chunk-2V4QG75U.js";
6
6
  import {
7
7
  ProviderRegistry
8
- } from "./chunk-JP6ESDV7.js";
8
+ } from "./chunk-UZISJ3KZ.js";
9
9
  import {
10
10
  getStatsSnapshot,
11
11
  getTopFailingTools,
12
12
  getTopUsedTools,
13
13
  resetStats
14
- } from "./chunk-YUA2KL7W.js";
15
- import "./chunk-5UR6ZOF4.js";
14
+ } from "./chunk-ZEDQBXVK.js";
15
+ import "./chunk-SMFRJCXB.js";
16
16
  import {
17
17
  ConfigManager
18
- } from "./chunk-QT5SGLTM.js";
18
+ } from "./chunk-EOYN2PCH.js";
19
19
  import "./chunk-TZQHYZKT.js";
20
20
  import {
21
21
  DEV_STATE_FILE_NAME,
22
22
  MEMORY_FILE_NAME,
23
23
  VERSION
24
- } from "./chunk-SDT4DCNX.js";
24
+ } from "./chunk-RFWBHCDC.js";
25
25
  import "./chunk-IW3Q7AE5.js";
26
26
 
27
27
  // src/diagnostics/doctor-cli.ts
@@ -36,7 +36,7 @@ import {
36
36
  VERSION,
37
37
  buildUserIdentityPrompt,
38
38
  runTestsTool
39
- } from "./chunk-WFGCP2GF.js";
39
+ } from "./chunk-EZR7NIC5.js";
40
40
  import {
41
41
  hasSemanticIndex,
42
42
  semanticSearch
@@ -1986,6 +1986,12 @@ function isCleanDocumentBody(content) {
1986
1986
  if (detectPseudoToolCalls(content)) return false;
1987
1987
  return looksLikeDocumentBody(content);
1988
1988
  }
1989
+ function stripOuterCodeFence(content) {
1990
+ const trimmed = content.trim();
1991
+ const m = trimmed.match(/^```[^\n`]*\n([\s\S]*?)\n```\s*$/);
1992
+ if (m) return m[1];
1993
+ return content;
1994
+ }
1989
1995
  function teeFileStats(content) {
1990
1996
  return { lines: content.split("\n").length, bytes: Buffer.byteLength(content, "utf-8") };
1991
1997
  }
@@ -2563,6 +2569,18 @@ function toUsage(u) {
2563
2569
  if (cached > 0) usage.cacheReadTokens = cached;
2564
2570
  return usage;
2565
2571
  }
2572
+ function isLoopbackBaseUrl(baseUrl) {
2573
+ if (!baseUrl) return false;
2574
+ let host;
2575
+ try {
2576
+ host = new URL(baseUrl).hostname;
2577
+ } catch {
2578
+ return false;
2579
+ }
2580
+ host = host.replace(/^\[|\]$/g, "").toLowerCase();
2581
+ if (host === "localhost" || host === "::1" || host === "0.0.0.0") return true;
2582
+ return /^127(?:\.\d{1,3}){3}$/.test(host);
2583
+ }
2566
2584
  var OpenAICompatibleProvider = class extends BaseProvider {
2567
2585
  client;
2568
2586
  defaultTimeout = 6e4;
@@ -2578,7 +2596,7 @@ var OpenAICompatibleProvider = class extends BaseProvider {
2578
2596
  baseURL: options?.baseUrl ?? this.defaultBaseUrl,
2579
2597
  timeout: this.defaultTimeout
2580
2598
  };
2581
- const proxyUrl = options?.proxy;
2599
+ const proxyUrl = isLoopbackBaseUrl(clientOptions.baseURL) ? void 0 : options?.proxy;
2582
2600
  try {
2583
2601
  const { Agent: Agent2, ProxyAgent, fetch: undiciFetch } = await import("undici");
2584
2602
  const STREAM_BODY_TIMEOUT = 30 * 60 * 1e3;
@@ -13012,10 +13030,11 @@ Try: /compact to reduce context, /clear to reset, or switch to a larger-context
13012
13030
  if (pendingTeeSave && isCleanDocumentBody(content)) {
13013
13031
  try {
13014
13032
  mkdirSync10(dirname5(pendingTeeSave), { recursive: true });
13015
- writeFileSync7(pendingTeeSave, content, "utf-8");
13033
+ const bodyToSave = stripOuterCodeFence(content);
13034
+ writeFileSync7(pendingTeeSave, bodyToSave, "utf-8");
13016
13035
  undoStack.push(pendingTeeSave, `save_last_response (deferred): ${pendingTeeSave}`);
13017
- const lines = content.split("\n").length;
13018
- this.send({ type: "info", message: `\u2705 Saved (from reply): ${pendingTeeSave} (${lines} lines, ${content.length} chars)` });
13036
+ const lines = bodyToSave.split("\n").length;
13037
+ this.send({ type: "info", message: `\u2705 Saved (from reply): ${pendingTeeSave} (${lines} lines, ${bodyToSave.length} chars)` });
13019
13038
  } catch (saveErr) {
13020
13039
  this.send({ type: "info", message: `\u2717 Could not save to ${pendingTeeSave}: ${saveErr.message ?? saveErr}` });
13021
13040
  }
@@ -14292,7 +14311,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
14292
14311
  case "test": {
14293
14312
  this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
14294
14313
  try {
14295
- const { executeTests } = await import("./run-tests-T4NPP36U.js");
14314
+ const { executeTests } = await import("./run-tests-DOBBUV45.js");
14296
14315
  const argStr = args.join(" ").trim();
14297
14316
  let testArgs = {};
14298
14317
  if (argStr) {
@@ -154,7 +154,7 @@ ${content}`);
154
154
  }
155
155
  }
156
156
  async function runTaskMode(config, providers, configManager, topic) {
157
- const { TaskOrchestrator } = await import("./task-orchestrator-BS2FKLGM.js");
157
+ const { TaskOrchestrator } = await import("./task-orchestrator-6FD2AXLQ.js");
158
158
  const orchestrator = new TaskOrchestrator(config, providers, configManager);
159
159
  let interrupted = false;
160
160
  const onSigint = () => {
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  saveDevState,
16
16
  sessionHasMeaningfulContent,
17
17
  setupProxy
18
- } from "./chunk-3UWMMYCQ.js";
18
+ } from "./chunk-YG5CA4ZA.js";
19
19
  import {
20
20
  ToolExecutor,
21
21
  ToolRegistry,
@@ -35,10 +35,10 @@ import {
35
35
  spawnAgentContext,
36
36
  theme,
37
37
  undoStack
38
- } from "./chunk-HLOHSMTT.js";
38
+ } from "./chunk-742TILCK.js";
39
39
  import "./chunk-T2NL5ZIA.js";
40
40
  import "./chunk-BXP6YZ2P.js";
41
- import "./chunk-C46JMUDC.js";
41
+ import "./chunk-VYCSZBII.js";
42
42
  import {
43
43
  SessionManager,
44
44
  getContentText
@@ -55,16 +55,16 @@ import {
55
55
  getConfigDirUsage,
56
56
  listRecentCrashes,
57
57
  writeCrashLog
58
- } from "./chunk-IAWXC2SO.js";
58
+ } from "./chunk-2V4QG75U.js";
59
59
  import {
60
60
  ProviderRegistry
61
- } from "./chunk-JP6ESDV7.js";
61
+ } from "./chunk-UZISJ3KZ.js";
62
62
  import {
63
63
  getStatsSnapshot,
64
64
  getTopFailingTools,
65
65
  getTopUsedTools,
66
66
  installFlushOnExit
67
- } from "./chunk-YUA2KL7W.js";
67
+ } from "./chunk-ZEDQBXVK.js";
68
68
  import {
69
69
  CONTENT_ONLY_STREAM_REMINDER,
70
70
  TEE_FINAL_USER_NUDGE,
@@ -80,12 +80,13 @@ import {
80
80
  freshPriorContent,
81
81
  isCleanDocumentBody,
82
82
  runAgentLoop,
83
+ stripOuterCodeFence,
83
84
  stripToolCallReminder,
84
85
  teeStreamErrorSummary
85
- } from "./chunk-5UR6ZOF4.js";
86
+ } from "./chunk-SMFRJCXB.js";
86
87
  import {
87
88
  ConfigManager
88
- } from "./chunk-QT5SGLTM.js";
89
+ } from "./chunk-EOYN2PCH.js";
89
90
  import {
90
91
  AuthError,
91
92
  ProviderError,
@@ -112,7 +113,7 @@ import {
112
113
  SKILLS_DIR_NAME,
113
114
  VERSION,
114
115
  buildUserIdentityPrompt
115
- } from "./chunk-SDT4DCNX.js";
116
+ } from "./chunk-RFWBHCDC.js";
116
117
  import {
117
118
  formatGitContextForPrompt,
118
119
  getGitContext,
@@ -1827,7 +1828,7 @@ No tools match "${filter}".
1827
1828
  const { join: join5 } = await import("path");
1828
1829
  const { existsSync: existsSync5 } = await import("fs");
1829
1830
  const { getGitRoot: getGitRoot2 } = await import("./git-context-EXOEHQSF.js");
1830
- const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-QUKKMYWZ.js");
1831
+ const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-PN4X2MIK.js");
1831
1832
  const { approveProject, hashMcpFile } = await import("./project-trust-NKYHL3VZ.js");
1832
1833
  const cwd = process.cwd();
1833
1834
  const projectRoot = getGitRoot2(cwd) ?? cwd;
@@ -2888,7 +2889,7 @@ ${hint}` : "")
2888
2889
  usage: "/test [command|filter]",
2889
2890
  async execute(args, ctx) {
2890
2891
  try {
2891
- const { executeTests } = await import("./run-tests-OEPVJDXJ.js");
2892
+ const { executeTests } = await import("./run-tests-ADASGIJE.js");
2892
2893
  const argStr = args.join(" ").trim();
2893
2894
  let testArgs = {};
2894
2895
  if (argStr) {
@@ -6640,12 +6641,13 @@ ${decision.displayMessage}
6640
6641
  if (pendingTeeSave && isCleanDocumentBody(content)) {
6641
6642
  try {
6642
6643
  mkdirSync4(dirname3(pendingTeeSave), { recursive: true });
6643
- writeFileSync2(pendingTeeSave, content, "utf-8");
6644
+ const bodyToSave = stripOuterCodeFence(content);
6645
+ writeFileSync2(pendingTeeSave, bodyToSave, "utf-8");
6644
6646
  undoStack.push(pendingTeeSave, `save_last_response (deferred): ${pendingTeeSave}`);
6645
- const lines = content.split("\n").length;
6647
+ const lines = bodyToSave.split("\n").length;
6646
6648
  process.stdout.write(theme.success(
6647
6649
  `
6648
- \u2705 Saved (from your reply): ${pendingTeeSave} (${lines} lines, ${content.length} chars)
6650
+ \u2705 Saved (from your reply): ${pendingTeeSave} (${lines} lines, ${bodyToSave.length} chars)
6649
6651
 
6650
6652
  `
6651
6653
  ));
@@ -7265,7 +7267,7 @@ program.command("web").description("Start Web UI server with browser-based chat
7265
7267
  console.error("Error: Invalid port number. Must be between 1 and 65535.");
7266
7268
  process.exit(1);
7267
7269
  }
7268
- const { startWebServer } = await import("./server-NBPF74CY.js");
7270
+ const { startWebServer } = await import("./server-FLDRVPXJ.js");
7269
7271
  await startWebServer({ port, host: options.host });
7270
7272
  });
7271
7273
  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) => {
@@ -7432,16 +7434,16 @@ program.command("sessions").description("List recent conversation sessions").opt
7432
7434
  console.log(footer + "\n");
7433
7435
  });
7434
7436
  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) => {
7435
- const { runUsageCli } = await import("./usage-DPM6T4ZZ.js");
7437
+ const { runUsageCli } = await import("./usage-NDMBSGG6.js");
7436
7438
  await runUsageCli(options);
7437
7439
  });
7438
7440
  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) => {
7439
- const { runDoctorCli } = await import("./doctor-cli-6XY3PJM5.js");
7441
+ const { runDoctorCli } = await import("./doctor-cli-YPL3XCBU.js");
7440
7442
  await runDoctorCli({ json: !!options.json, resetStats: !!options.resetStats });
7441
7443
  });
7442
7444
  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) => {
7443
7445
  try {
7444
- const batch = await import("./batch-SWBDLVZO.js");
7446
+ const batch = await import("./batch-PRC75BKT.js");
7445
7447
  switch (action) {
7446
7448
  case "submit":
7447
7449
  if (!arg) {
@@ -7484,7 +7486,7 @@ program.command("batch <action> [arg] [arg2]").description("Anthropic Message Ba
7484
7486
  }
7485
7487
  });
7486
7488
  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) => {
7487
- const { startMcpServer } = await import("./server-TZDUN5V3.js");
7489
+ const { startMcpServer } = await import("./server-WBIQCV6B.js");
7488
7490
  await startMcpServer({
7489
7491
  allowDestructive: !!options.allowDestructive,
7490
7492
  allowOutsideCwd: !!options.allowOutsideCwd,
@@ -7493,7 +7495,7 @@ program.command("mcp-serve").description("Start an MCP server over STDIO, exposi
7493
7495
  });
7494
7496
  });
7495
7497
  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; diff fetched via `gh pr diff <num>`", (v) => parseInt(v, 10)).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)").action(async (options) => {
7496
- const { runCi } = await import("./ci-O3JM5YAA.js");
7498
+ const { runCi } = await import("./ci-OZ4EB52Y.js");
7497
7499
  const result = await runCi({
7498
7500
  pr: options.pr,
7499
7501
  base: options.base,
@@ -7639,7 +7641,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
7639
7641
  }),
7640
7642
  config.get("customProviders")
7641
7643
  );
7642
- const { startHub } = await import("./hub-HJTJM2RT.js");
7644
+ const { startHub } = await import("./hub-PKFAPVXM.js");
7643
7645
  await startHub(
7644
7646
  {
7645
7647
  topic: topic ?? "",
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  executeTests,
4
4
  runTestsTool
5
- } from "./chunk-C46JMUDC.js";
6
- import "./chunk-SDT4DCNX.js";
5
+ } from "./chunk-VYCSZBII.js";
6
+ import "./chunk-RFWBHCDC.js";
7
7
  export {
8
8
  executeTests,
9
9
  runTestsTool
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  executeTests,
3
3
  runTestsTool
4
- } from "./chunk-WFGCP2GF.js";
4
+ } from "./chunk-EZR7NIC5.js";
5
5
  export {
6
6
  executeTests,
7
7
  runTestsTool
@@ -19,7 +19,7 @@ import {
19
19
  loadDevState,
20
20
  persistToolRound,
21
21
  setupProxy
22
- } from "./chunk-3UWMMYCQ.js";
22
+ } from "./chunk-YG5CA4ZA.js";
23
23
  import {
24
24
  ToolExecutor,
25
25
  ToolRegistry,
@@ -38,10 +38,10 @@ import {
38
38
  spawnAgentContext,
39
39
  truncateOutput,
40
40
  undoStack
41
- } from "./chunk-HLOHSMTT.js";
41
+ } from "./chunk-742TILCK.js";
42
42
  import "./chunk-T2NL5ZIA.js";
43
43
  import "./chunk-BXP6YZ2P.js";
44
- import "./chunk-C46JMUDC.js";
44
+ import "./chunk-VYCSZBII.js";
45
45
  import {
46
46
  SessionManager,
47
47
  getContentText
@@ -52,10 +52,10 @@ import {
52
52
  } from "./chunk-E44DTERW.js";
53
53
  import {
54
54
  ProviderRegistry
55
- } from "./chunk-JP6ESDV7.js";
55
+ } from "./chunk-UZISJ3KZ.js";
56
56
  import {
57
57
  runTool
58
- } from "./chunk-YUA2KL7W.js";
58
+ } from "./chunk-ZEDQBXVK.js";
59
59
  import {
60
60
  CONTENT_ONLY_STREAM_REMINDER,
61
61
  TEE_FINAL_USER_NUDGE,
@@ -68,12 +68,13 @@ import {
68
68
  getDangerLevel,
69
69
  isCleanDocumentBody,
70
70
  runAgentLoop,
71
+ stripOuterCodeFence,
71
72
  stripToolCallReminder,
72
73
  teeStreamErrorSummary
73
- } from "./chunk-5UR6ZOF4.js";
74
+ } from "./chunk-SMFRJCXB.js";
74
75
  import {
75
76
  ConfigManager
76
- } from "./chunk-QT5SGLTM.js";
77
+ } from "./chunk-EOYN2PCH.js";
77
78
  import "./chunk-TZQHYZKT.js";
78
79
  import {
79
80
  AGENTIC_BEHAVIOR_GUIDELINE,
@@ -93,7 +94,7 @@ import {
93
94
  SKILLS_DIR_NAME,
94
95
  VERSION,
95
96
  buildUserIdentityPrompt
96
- } from "./chunk-SDT4DCNX.js";
97
+ } from "./chunk-RFWBHCDC.js";
97
98
  import {
98
99
  formatGitContextForPrompt,
99
100
  getGitContext,
@@ -1174,10 +1175,11 @@ Try: /compact to reduce context, /clear to reset, or switch to a larger-context
1174
1175
  if (pendingTeeSave && isCleanDocumentBody(content)) {
1175
1176
  try {
1176
1177
  mkdirSync(dirname(pendingTeeSave), { recursive: true });
1177
- writeFileSync(pendingTeeSave, content, "utf-8");
1178
+ const bodyToSave = stripOuterCodeFence(content);
1179
+ writeFileSync(pendingTeeSave, bodyToSave, "utf-8");
1178
1180
  undoStack.push(pendingTeeSave, `save_last_response (deferred): ${pendingTeeSave}`);
1179
- const lines = content.split("\n").length;
1180
- this.send({ type: "info", message: `\u2705 Saved (from reply): ${pendingTeeSave} (${lines} lines, ${content.length} chars)` });
1181
+ const lines = bodyToSave.split("\n").length;
1182
+ this.send({ type: "info", message: `\u2705 Saved (from reply): ${pendingTeeSave} (${lines} lines, ${bodyToSave.length} chars)` });
1181
1183
  } catch (saveErr) {
1182
1184
  this.send({ type: "info", message: `\u2717 Could not save to ${pendingTeeSave}: ${saveErr.message ?? saveErr}` });
1183
1185
  }
@@ -2454,7 +2456,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
2454
2456
  case "test": {
2455
2457
  this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
2456
2458
  try {
2457
- const { executeTests } = await import("./run-tests-OEPVJDXJ.js");
2459
+ const { executeTests } = await import("./run-tests-ADASGIJE.js");
2458
2460
  const argStr = args.join(" ").trim();
2459
2461
  let testArgs = {};
2460
2462
  if (argStr) {
@@ -1,21 +1,21 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ToolRegistry
4
- } from "./chunk-HLOHSMTT.js";
4
+ } from "./chunk-742TILCK.js";
5
5
  import "./chunk-T2NL5ZIA.js";
6
6
  import "./chunk-BXP6YZ2P.js";
7
- import "./chunk-C46JMUDC.js";
7
+ import "./chunk-VYCSZBII.js";
8
8
  import {
9
9
  runTool
10
- } from "./chunk-YUA2KL7W.js";
10
+ } from "./chunk-ZEDQBXVK.js";
11
11
  import {
12
12
  getDangerLevel,
13
13
  schemaToJsonSchema
14
- } from "./chunk-5UR6ZOF4.js";
14
+ } from "./chunk-SMFRJCXB.js";
15
15
  import "./chunk-TZQHYZKT.js";
16
16
  import {
17
17
  VERSION
18
- } from "./chunk-SDT4DCNX.js";
18
+ } from "./chunk-RFWBHCDC.js";
19
19
  import "./chunk-4BKXL7SM.js";
20
20
  import "./chunk-TB4W4Y4T.js";
21
21
  import "./chunk-KHYD3WXE.js";
@@ -26,7 +26,7 @@ import "./chunk-IW3Q7AE5.js";
26
26
 
27
27
  // src/mcp/server.ts
28
28
  import { createInterface } from "readline";
29
- import { resolve } from "path";
29
+ import { resolve, dirname, basename } from "path";
30
30
  import { realpathSync } from "fs";
31
31
  var STDIN_TOOLS = /* @__PURE__ */ new Set(["ask_user", "spawn_agent"]);
32
32
  function looksLikePath(s) {
@@ -62,6 +62,21 @@ var TOOL_PATH_ARGS = {
62
62
  bash: ["cwd"],
63
63
  run_interactive: ["cwd"]
64
64
  };
65
+ function realpathExistingPrefix(abs) {
66
+ let current = abs;
67
+ const tail = [];
68
+ for (; ; ) {
69
+ try {
70
+ const real = realpathSync(current);
71
+ return tail.length ? resolve(real, ...tail) : real;
72
+ } catch {
73
+ const parent = dirname(current);
74
+ if (parent === current) return abs;
75
+ tail.unshift(basename(current));
76
+ current = parent;
77
+ }
78
+ }
79
+ }
65
80
  var McpServer = class {
66
81
  registry;
67
82
  opts;
@@ -243,10 +258,12 @@ var McpServer = class {
243
258
  * Validate that every known path-bearing argument of `toolName` resolves
244
259
  * inside the sandbox root. Returns an error message on violation, else undef.
245
260
  *
246
- * We do NOT realpath() per-call: write_file targets may not exist yet, and
247
- * realpath on every call is a syscall per arg. The root itself is realpath'd
248
- * once at construction, which stops the "sandbox root is a symlink pointing
249
- * elsewhere" class of attack. Symlinks inside the tree are allowed.
261
+ * Each candidate is canonicalized via {@link realpathExistingPrefix} before the
262
+ * containment check so symlinks in the existing prefix (notably the sandbox root
263
+ * itself `/var`→`/private/var` on macOS) match the realpath'd root. write_file
264
+ * targets that don't exist yet are handled by realpath-ing only the existing
265
+ * ancestor. The root is also realpath'd once at construction, stopping the
266
+ * "sandbox root is a symlink pointing elsewhere" class of attack.
250
267
  */
251
268
  validatePathArgs(toolName, args) {
252
269
  if (this.opts.allowOutsideCwd) return void 0;
@@ -258,7 +275,7 @@ var McpServer = class {
258
275
  const list = Array.isArray(value) ? value : [value];
259
276
  for (const entry of list) {
260
277
  if (typeof entry !== "string" || entry.length === 0) continue;
261
- const abs = resolve(this.sandboxRoot, entry);
278
+ const abs = realpathExistingPrefix(resolve(this.sandboxRoot, entry));
262
279
  if (!this.isInsideSandbox(abs)) {
263
280
  return `Path '${entry}' escapes sandbox root '${this.sandboxRoot}'. Pass --allow-outside-cwd to permit.`;
264
281
  }
@@ -270,7 +287,7 @@ var McpServer = class {
270
287
  if (knownKeys.has(k)) continue;
271
288
  if (typeof v !== "string" || v.length === 0) continue;
272
289
  if (!looksLikePath(v)) continue;
273
- const abs = resolve(this.sandboxRoot, v);
290
+ const abs = realpathExistingPrefix(resolve(this.sandboxRoot, v));
274
291
  if (!this.isInsideSandbox(abs)) {
275
292
  return `Path-like argument '${k}=${v}' escapes sandbox root '${this.sandboxRoot}'. Pass --allow-outside-cwd to permit.`;
276
293
  }
@@ -3,21 +3,21 @@ import {
3
3
  ToolRegistry,
4
4
  googleSearchContext,
5
5
  truncateOutput
6
- } from "./chunk-HLOHSMTT.js";
6
+ } from "./chunk-742TILCK.js";
7
7
  import "./chunk-T2NL5ZIA.js";
8
8
  import "./chunk-BXP6YZ2P.js";
9
- import "./chunk-C46JMUDC.js";
9
+ import "./chunk-VYCSZBII.js";
10
10
  import {
11
11
  runTool
12
- } from "./chunk-YUA2KL7W.js";
12
+ } from "./chunk-ZEDQBXVK.js";
13
13
  import {
14
14
  getDangerLevel,
15
15
  runLeanAgentLoop
16
- } from "./chunk-5UR6ZOF4.js";
16
+ } from "./chunk-SMFRJCXB.js";
17
17
  import "./chunk-TZQHYZKT.js";
18
18
  import {
19
19
  SUBAGENT_ALLOWED_TOOLS
20
- } from "./chunk-SDT4DCNX.js";
20
+ } from "./chunk-RFWBHCDC.js";
21
21
  import "./chunk-4BKXL7SM.js";
22
22
  import "./chunk-TB4W4Y4T.js";
23
23
  import "./chunk-KHYD3WXE.js";
@@ -8,9 +8,9 @@ import {
8
8
  } from "./chunk-E44DTERW.js";
9
9
  import {
10
10
  ConfigManager
11
- } from "./chunk-QT5SGLTM.js";
11
+ } from "./chunk-EOYN2PCH.js";
12
12
  import "./chunk-TZQHYZKT.js";
13
- import "./chunk-SDT4DCNX.js";
13
+ import "./chunk-RFWBHCDC.js";
14
14
  import "./chunk-IW3Q7AE5.js";
15
15
 
16
16
  // src/cli/usage.ts
package/package.json CHANGED
@@ -1,176 +1,176 @@
1
- {
2
- "name": "jinzd-ai-cli",
3
- "version": "0.4.201",
4
- "description": "Cross-platform REPL-style AI CLI with multi-provider support",
5
- "type": "module",
6
- "main": "./dist/index.js",
7
- "bin": {
8
- "aicli": "dist/index.js"
9
- },
10
- "publishConfig": {
11
- "access": "public",
12
- "registry": "https://registry.npmjs.org/"
13
- },
14
- "exports": {
15
- ".": "./dist/index.js",
16
- "./core": "./dist/core/types.js",
17
- "./providers": "./dist/providers/base.js"
18
- },
19
- "scripts": {
20
- "build": "tsup",
21
- "dev": "tsx src/index.ts",
22
- "test": "vitest run",
23
- "test:watch": "vitest",
24
- "test:coverage": "vitest run --coverage",
25
- "lint": "eslint src",
26
- "prepublishOnly": "npm run build",
27
- "patch": "node scripts/patch-sqlite.mjs",
28
- "pack:win": "npm run build && npm run patch && npx pkg dist-cjs/index.cjs --target node22-win-x64 --output release/ai-cli-win.exe --compress GZip --options no-deprecation",
29
- "pack:mac": "npm run build && npm run patch && npx pkg dist-cjs/index.cjs --target node22-macos-arm64 --output release/ai-cli-mac --compress GZip --options no-deprecation",
30
- "pack:mac-x64": "npm run build && npm run patch && npx pkg dist-cjs/index.cjs --target node22-macos-x64 --output release/ai-cli-mac-x64 --compress GZip --options no-deprecation",
31
- "pack:linux": "npm run build && npm run patch && npx pkg dist-cjs/index.cjs --target node22-linux-x64 --output release/ai-cli-linux --compress GZip --options no-deprecation",
32
- "pack:all": "npm run build && npm run patch && npx pkg dist-cjs/index.cjs --target node22-win-x64,node22-macos-arm64,node22-linux-x64 --out-path release --compress GZip --options no-deprecation",
33
- "electron": "npm run build && electron electron/main.cjs",
34
- "electron:dev": "electron electron/main.cjs",
35
- "electron:build-win": "npm run build && electron-builder --win",
36
- "electron:build-mac": "npm run build && electron-builder --mac",
37
- "electron:build-linux": "npm run build && electron-builder --linux",
38
- "electron:build-all": "npm run build && electron-builder --win --mac --linux",
39
- "release": "node scripts/release.mjs",
40
- "test:e2e-web": "playwright test"
41
- },
42
- "pkg": {
43
- "scripts": "dist-cjs/index.cjs",
44
- "assets": [
45
- "dist/wasm/**/*"
46
- ],
47
- "targets": [
48
- "node22-win-x64",
49
- "node22-macos-arm64",
50
- "node22-linux-x64"
51
- ],
52
- "outputPath": "release",
53
- "options": "no-deprecation"
54
- },
55
- "engines": {
56
- "node": ">=20.0.0"
57
- },
58
- "files": [
59
- "dist/*.js",
60
- "dist/web/",
61
- "dist/wasm/",
62
- "README.md"
63
- ],
64
- "keywords": [
65
- "ai",
66
- "cli",
67
- "claude",
68
- "gemini",
69
- "deepseek",
70
- "kimi",
71
- "chatbot",
72
- "repl"
73
- ],
74
- "repository": {
75
- "type": "git",
76
- "url": "git+https://github.com/jinzhengdong/ai-cli.git"
77
- },
78
- "bugs": {
79
- "url": "https://github.com/jinzhengdong/ai-cli/issues"
80
- },
81
- "homepage": "https://github.com/jinzhengdong/ai-cli#readme",
82
- "license": "MIT",
83
- "dependencies": {
84
- "@anthropic-ai/sdk": "^0.39.0",
85
- "@google/generative-ai": "^0.24.0",
86
- "@huggingface/transformers": "^4.1.0",
87
- "@inquirer/prompts": "^7.0.0",
88
- "chalk": "^5.4.1",
89
- "commander": "^13.0.0",
90
- "express": "^5.2.1",
91
- "openai": "^4.77.0",
92
- "tree-sitter-cpp": "^0.23.4",
93
- "tree-sitter-go": "^0.25.0",
94
- "tree-sitter-java": "^0.23.5",
95
- "tree-sitter-javascript": "^0.25.0",
96
- "tree-sitter-python": "^0.25.0",
97
- "tree-sitter-rust": "^0.24.0",
98
- "tree-sitter-typescript": "^0.23.2",
99
- "undici": "^7.24.0",
100
- "uuid": "^14.0.0",
101
- "web-tree-sitter": "^0.26.8",
102
- "ws": "^8.19.0",
103
- "zod": "^3.24.1"
104
- },
105
- "devDependencies": {
106
- "@playwright/test": "^1.60.0",
107
- "@types/express": "^5.0.6",
108
- "@types/node": "^22.10.0",
109
- "@types/uuid": "^10.0.0",
110
- "@types/ws": "^8.18.1",
111
- "@typescript-eslint/eslint-plugin": "^8.13.0",
112
- "@typescript-eslint/parser": "^8.13.0",
113
- "@yao-pkg/pkg": "^6.14.0",
114
- "electron": "^41.4.0",
115
- "electron-builder": "^26.0.0",
116
- "eslint": "^9.13.0",
117
- "tsup": "^8.3.5",
118
- "tsx": "^4.19.2",
119
- "typescript": "^5.7.3",
120
- "vitest": "^3.2.4"
121
- },
122
- "author": "jinzd",
123
- "build": {
124
- "appId": "com.jinzd.ai-cli",
125
- "productName": "ai-cli",
126
- "artifactName": "ai-cli-${os}-${arch}.${ext}",
127
- "extraMetadata": {
128
- "main": "electron/main.cjs"
129
- },
130
- "npmRebuild": false,
131
- "files": [
132
- "dist/**/*",
133
- "electron/**/*.cjs"
134
- ],
135
- "extraResources": [
136
- {
137
- "from": "dist/web/client",
138
- "to": "web-client"
139
- }
140
- ],
141
- "asar": true,
142
- "asarUnpack": [
143
- "dist/electron-server.js",
144
- "dist/chunk-*.js"
145
- ],
146
- "forceCodeSigning": false,
147
- "win": {
148
- "target": [
149
- "nsis",
150
- "portable"
151
- ],
152
- "icon": "src/web/client/icon-512.png",
153
- "signAndEditExecutable": false
154
- },
155
- "mac": {
156
- "target": [
157
- "dmg",
158
- "zip"
159
- ],
160
- "category": "public.app-category.developer-tools",
161
- "icon": "src/web/client/icon-512.png"
162
- },
163
- "linux": {
164
- "target": [
165
- "AppImage",
166
- "deb"
167
- ],
168
- "icon": "src/web/client/icon-512.png",
169
- "category": "Development"
170
- },
171
- "nsis": {
172
- "oneClick": false,
173
- "allowToChangeInstallationDirectory": true
174
- }
175
- }
176
- }
1
+ {
2
+ "name": "jinzd-ai-cli",
3
+ "version": "0.4.203",
4
+ "description": "Cross-platform REPL-style AI CLI with multi-provider support",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "bin": {
8
+ "aicli": "dist/index.js"
9
+ },
10
+ "publishConfig": {
11
+ "access": "public",
12
+ "registry": "https://registry.npmjs.org/"
13
+ },
14
+ "exports": {
15
+ ".": "./dist/index.js",
16
+ "./core": "./dist/core/types.js",
17
+ "./providers": "./dist/providers/base.js"
18
+ },
19
+ "scripts": {
20
+ "build": "tsup",
21
+ "dev": "tsx src/index.ts",
22
+ "test": "vitest run",
23
+ "test:watch": "vitest",
24
+ "test:coverage": "vitest run --coverage",
25
+ "lint": "eslint src",
26
+ "prepublishOnly": "npm run build",
27
+ "patch": "node scripts/patch-sqlite.mjs",
28
+ "pack:win": "npm run build && npm run patch && npx pkg dist-cjs/index.cjs --target node22-win-x64 --output release/ai-cli-win.exe --compress GZip --options no-deprecation",
29
+ "pack:mac": "npm run build && npm run patch && npx pkg dist-cjs/index.cjs --target node22-macos-arm64 --output release/ai-cli-mac --compress GZip --options no-deprecation",
30
+ "pack:mac-x64": "npm run build && npm run patch && npx pkg dist-cjs/index.cjs --target node22-macos-x64 --output release/ai-cli-mac-x64 --compress GZip --options no-deprecation",
31
+ "pack:linux": "npm run build && npm run patch && npx pkg dist-cjs/index.cjs --target node22-linux-x64 --output release/ai-cli-linux --compress GZip --options no-deprecation",
32
+ "pack:all": "npm run build && npm run patch && npx pkg dist-cjs/index.cjs --target node22-win-x64,node22-macos-arm64,node22-linux-x64 --out-path release --compress GZip --options no-deprecation",
33
+ "electron": "npm run build && electron electron/main.cjs",
34
+ "electron:dev": "electron electron/main.cjs",
35
+ "electron:build-win": "npm run build && electron-builder --win",
36
+ "electron:build-mac": "npm run build && electron-builder --mac",
37
+ "electron:build-linux": "npm run build && electron-builder --linux",
38
+ "electron:build-all": "npm run build && electron-builder --win --mac --linux",
39
+ "release": "node scripts/release.mjs",
40
+ "test:e2e-web": "playwright test"
41
+ },
42
+ "pkg": {
43
+ "scripts": "dist-cjs/index.cjs",
44
+ "assets": [
45
+ "dist/wasm/**/*"
46
+ ],
47
+ "targets": [
48
+ "node22-win-x64",
49
+ "node22-macos-arm64",
50
+ "node22-linux-x64"
51
+ ],
52
+ "outputPath": "release",
53
+ "options": "no-deprecation"
54
+ },
55
+ "engines": {
56
+ "node": ">=20.0.0"
57
+ },
58
+ "files": [
59
+ "dist/*.js",
60
+ "dist/web/",
61
+ "dist/wasm/",
62
+ "README.md"
63
+ ],
64
+ "keywords": [
65
+ "ai",
66
+ "cli",
67
+ "claude",
68
+ "gemini",
69
+ "deepseek",
70
+ "kimi",
71
+ "chatbot",
72
+ "repl"
73
+ ],
74
+ "repository": {
75
+ "type": "git",
76
+ "url": "git+https://github.com/jinzhengdong/ai-cli.git"
77
+ },
78
+ "bugs": {
79
+ "url": "https://github.com/jinzhengdong/ai-cli/issues"
80
+ },
81
+ "homepage": "https://github.com/jinzhengdong/ai-cli#readme",
82
+ "license": "MIT",
83
+ "dependencies": {
84
+ "@anthropic-ai/sdk": "^0.39.0",
85
+ "@google/generative-ai": "^0.24.0",
86
+ "@huggingface/transformers": "^4.1.0",
87
+ "@inquirer/prompts": "^7.0.0",
88
+ "chalk": "^5.4.1",
89
+ "commander": "^13.0.0",
90
+ "express": "^5.2.1",
91
+ "openai": "^4.77.0",
92
+ "tree-sitter-cpp": "^0.23.4",
93
+ "tree-sitter-go": "^0.25.0",
94
+ "tree-sitter-java": "^0.23.5",
95
+ "tree-sitter-javascript": "^0.25.0",
96
+ "tree-sitter-python": "^0.25.0",
97
+ "tree-sitter-rust": "^0.24.0",
98
+ "tree-sitter-typescript": "^0.23.2",
99
+ "undici": "^7.24.0",
100
+ "uuid": "^14.0.0",
101
+ "web-tree-sitter": "^0.26.8",
102
+ "ws": "^8.19.0",
103
+ "zod": "^3.24.1"
104
+ },
105
+ "devDependencies": {
106
+ "@playwright/test": "^1.60.0",
107
+ "@types/express": "^5.0.6",
108
+ "@types/node": "^22.10.0",
109
+ "@types/uuid": "^10.0.0",
110
+ "@types/ws": "^8.18.1",
111
+ "@typescript-eslint/eslint-plugin": "^8.13.0",
112
+ "@typescript-eslint/parser": "^8.13.0",
113
+ "@yao-pkg/pkg": "^6.14.0",
114
+ "electron": "^41.4.0",
115
+ "electron-builder": "^26.0.0",
116
+ "eslint": "^9.13.0",
117
+ "tsup": "^8.3.5",
118
+ "tsx": "^4.19.2",
119
+ "typescript": "^5.7.3",
120
+ "vitest": "^3.2.4"
121
+ },
122
+ "author": "jinzd",
123
+ "build": {
124
+ "appId": "com.jinzd.ai-cli",
125
+ "productName": "ai-cli",
126
+ "artifactName": "ai-cli-${os}-${arch}.${ext}",
127
+ "extraMetadata": {
128
+ "main": "electron/main.cjs"
129
+ },
130
+ "npmRebuild": false,
131
+ "files": [
132
+ "dist/**/*",
133
+ "electron/**/*.cjs"
134
+ ],
135
+ "extraResources": [
136
+ {
137
+ "from": "dist/web/client",
138
+ "to": "web-client"
139
+ }
140
+ ],
141
+ "asar": true,
142
+ "asarUnpack": [
143
+ "dist/electron-server.js",
144
+ "dist/chunk-*.js"
145
+ ],
146
+ "forceCodeSigning": false,
147
+ "win": {
148
+ "target": [
149
+ "nsis",
150
+ "portable"
151
+ ],
152
+ "icon": "src/web/client/icon-512.png",
153
+ "signAndEditExecutable": false
154
+ },
155
+ "mac": {
156
+ "target": [
157
+ "dmg",
158
+ "zip"
159
+ ],
160
+ "category": "public.app-category.developer-tools",
161
+ "icon": "src/web/client/icon-512.png"
162
+ },
163
+ "linux": {
164
+ "target": [
165
+ "AppImage",
166
+ "deb"
167
+ ],
168
+ "icon": "src/web/client/icon-512.png",
169
+ "category": "Development"
170
+ },
171
+ "nsis": {
172
+ "oneClick": false,
173
+ "allowToChangeInstallationDirectory": true
174
+ }
175
+ }
176
+ }