jinzd-ai-cli 0.1.62 → 0.1.63

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.
package/CLAUDE.md CHANGED
@@ -6,7 +6,14 @@
6
6
  带有 **AI 工具调用(Agentic)** 能力,支持执行 bash 命令、读写文件、运行交互式程序、流式生成大文档。
7
7
  代理支持(`proxy` 配置字段 + 环境变量),Gemini 完整支持(2.5 Pro/Flash,array items schema 修复)。
8
8
  **MCP 协议支持**:可接入外部 MCP 服务器,自动发现并注册工具,无缝融入 agentic 循环。
9
- 设计上可扩展至 Electron/Tauri 桌面 GUI。
9
+ 设计上可扩展至 Electron/Tauri 桌面 GUI。
10
+
11
+ > 当前代码基线(2026-03-12):
12
+ > - 版本:`v0.1.62`
13
+ > - 默认 REPL 命令:35 个
14
+ > - 当前注册的内置工具:17 个
15
+ > - `stream_to_file` 已正式接入 `ToolRegistry`
16
+ > - `ora` 依赖已从 `package.json` 移除,spinner 使用 `src/repl/renderer.ts` 中的自实现版本
10
17
 
11
18
  ## 技术栈
12
19
 
@@ -41,7 +48,7 @@ src/
41
48
  │ ├── session.ts # Session(addMessage / clear / compact / fork / toJSON / fromJSON)
42
49
  │ └── session-manager.ts # CRUD + forkSession for ~/.aicli/history/*.json
43
50
  ├── repl/
44
- │ ├── repl.ts # 主 REPL 循环(MAX_TOOL_ROUNDS=20,handleChatWithTools agentic loop)
51
+ │ ├── repl.ts # 主 REPL 循环(MAX_TOOL_ROUNDS=25,handleChatWithTools agentic loop)
45
52
  │ ├── renderer.ts # 终端输出(renderStream / renderResponse 均不加前置 \n)
46
53
  │ ├── theme.ts # 集中式主题系统(dark/light/custom 主题 + 语义色槽 Proxy 导出)
47
54
  │ ├── dev-state.ts # 开发状态交接(provider/model 切换时快照生成、save/load/clear)
@@ -58,7 +65,7 @@ src/
58
65
  │ └── manager.ts # McpManager(多服务器管理,工具发现与注册,MCP→Tool 转换)
59
66
  └── tools/
60
67
  ├── types.ts # ToolDefinition / ToolCall / ToolResult / DangerLevel / getDangerLevel / isFileWriteTool
61
- ├── registry.ts # ToolRegistry(注册全部内置工具,共15个)
68
+ ├── registry.ts # ToolRegistry(注册全部内置工具,共17个)
62
69
  ├── hooks.ts # 工具执行钩子(runHook,shell 命令模板替换 + execSync)
63
70
  ├── permissions.ts # 基于规则的工具权限控制(checkPermission,首匹配规则)
64
71
  ├── executor.ts # ToolExecutor(确认逻辑 + 批量文件写入预览 + batchConfirm + hooks + permissions)
@@ -71,8 +78,9 @@ src/
71
78
  ├── ask-user.ts # ask_user 工具(agentic 循环中向用户提问,等待文本回答)
72
79
  ├── write-todos.ts # write_todos 工具(任务拆解与进度跟踪,终端实时渲染)
73
80
  ├── google-search.ts # google_search 工具(Google Custom Search API 搜索网页)
74
- ├── spawn-agent.ts # spawn_agent 工具(独立子代理 agentic 循环 + SubAgentExecutor)
75
- └── run-tests.ts # run_tests 工具(自动检测项目类型、运行测试、JUnit XML 解析、结构化报告)
81
+ ├── stream-to-file.ts # stream_to_file 工具(流式生成大文档并直接写入文件)
82
+ ├── spawn-agent.ts # spawn_agent 工具(独立子代理 agentic 循环 + SubAgentExecutor)
83
+ └── run-tests.ts # run_tests 工具(自动检测项目类型、运行测试、JUnit XML 解析、结构化报告)
76
84
  ```
77
85
 
78
86
  ## 常用命令
@@ -120,7 +128,7 @@ npm run pack:all # 同时打包所有平台
120
128
  - **持久记忆**: `~/.aicli/memory.md`(AI 通过 `save_memory` 工具写入,跨会话自动加载)
121
129
  - **开发状态快照**: `~/.aicli/dev-state.md`(provider/model 切换时由前一 AI 自动生成,新模型启动后注入 system prompt)
122
130
  - **对话历史**: `~/.aicli/history/*.json`
123
- - **插件目录**: `~/.aicli/plugins/`(暂未实现)
131
+ - **插件目录**: `~/.aicli/plugins/`(已实现,默认关闭,需 `allowPlugins: true` 显式启用)
124
132
 
125
133
  当前已配置(用户机器):
126
134
  ```json
@@ -210,9 +218,10 @@ AICLI_NO_STREAM 设为 1 禁用流式输出
210
218
  | `grep_files` | safe | 正则搜索文件内容 |
211
219
  | `glob_files` | safe | 按 glob 模式匹配文件路径 |
212
220
  | `run_interactive` | safe | spawn 直连可执行文件 + stdin_lines 依次输入,用于交互式程序(猜数游戏等) |
213
- | `web_fetch` | safe | 抓取网页内容并转为 Markdown(含私有 IP 防 SSRF) |
214
- | `save_last_response` | write(需确认) | 保存上一次 AI 回答到文件(tee 流式写盘) |
215
- | `save_memory` | safe | 将重要信息追加到 `~/.aicli/memory.md`,跨会话持久化,启动时自动注入 system prompt |
221
+ | `web_fetch` | safe | 抓取网页内容并转为 Markdown(含私有 IP 防 SSRF) |
222
+ | `save_last_response` | write(需确认) | 保存上一次 AI 回答到文件(tee 流式写盘) |
223
+ | `stream_to_file` | write(需确认) | 流式生成大文档并直接写入文件,规避长文本被 token 截断 |
224
+ | `save_memory` | safe | 将重要信息追加到 `~/.aicli/memory.md`,跨会话持久化,启动时自动注入 system prompt |
216
225
  | `ask_user` | safe | AI 在 agentic 循环中向用户提问,等待文本回答后继续执行 |
217
226
  | `write_todos` | safe | AI 拆解复杂任务为子任务列表,终端实时渲染进度(pending/in_progress/completed) |
218
227
  | `google_search` | safe | Google Custom Search API 搜索网页,需配置 API Key + Search Engine ID (cx) |
@@ -232,7 +241,7 @@ AICLI_NO_STREAM 设为 1 禁用流式输出
232
241
  ```
233
242
  用户输入 → rl.pause() + rl.output=null(静默 readline)
234
243
  → chatWithTools(messages + toolDefs) → AI 返回 { toolCalls } 或 { content }
235
- → 若 toolCalls:executor.executeAll() → buildToolResultMessages() → 下一轮(最多 20 轮)
244
+ → 若 toolCalls:executor.executeAll() → buildToolResultMessages() → 下一轮(最多 25 轮)
236
245
  → 若 content:renderResponse() → rl.output=savedOutput + rl.resume() + showPrompt()
237
246
  ```
238
247
 
@@ -82,7 +82,7 @@ var AGENTIC_BEHAVIOR_GUIDELINE = `# \u91CD\u8981\u884C\u4E3A\u51C6\u5219
82
82
  var AUTHOR = "\u664B\u6B63\u4E1C";
83
83
  var AUTHOR_EMAIL = "zhengdong.jin@gmail.com";
84
84
  var DESCRIPTION = "\u8DE8\u5E73\u53F0 REPL \u98CE\u683C AI \u5BF9\u8BDD\u5DE5\u5177\uFF0C\u652F\u6301\u591A Provider \u4E0E Agentic \u5DE5\u5177\u8C03\u7528";
85
- var REPO_URL = "https://gitee.com/jinzhengdong/ai-courses";
85
+ var REPO_URL = "https://github.com/jinzhengdong/ai-cli";
86
86
 
87
87
  // src/tools/builtin/run-tests.ts
88
88
  var IS_WINDOWS = platform() === "win32";
package/dist/index.js CHANGED
@@ -30,7 +30,7 @@ import {
30
30
  SUBAGENT_MAX_ROUNDS_LIMIT,
31
31
  VERSION,
32
32
  runTestsTool
33
- } from "./chunk-LPE66KZ3.js";
33
+ } from "./chunk-J6WSEEPI.js";
34
34
 
35
35
  // src/index.ts
36
36
  import { program } from "commander";
@@ -369,7 +369,7 @@ var BaseProvider = class {
369
369
 
370
370
  // src/tools/types.ts
371
371
  function isFileWriteTool(name) {
372
- return name === "write_file" || name === "edit_file";
372
+ return name === "write_file" || name === "edit_file" || name === "stream_to_file";
373
373
  }
374
374
  function getDangerLevel(toolName, args) {
375
375
  if (toolName.startsWith("mcp__")) return "safe";
@@ -387,6 +387,7 @@ function getDangerLevel(toolName, args) {
387
387
  if (toolName === "write_file") return "write";
388
388
  if (toolName === "edit_file") return "write";
389
389
  if (toolName === "save_last_response") return "write";
390
+ if (toolName === "stream_to_file") return "write";
390
391
  if (toolName === "run_interactive") {
391
392
  const exe = String(args["executable"] ?? "").toLowerCase();
392
393
  if (/\b(rm|rmdir|del|format|mkfs|Remove-Item)\b/i.test(exe)) return "destructive";
@@ -2325,7 +2326,7 @@ var SessionManager = class {
2325
2326
  // src/repl/repl.ts
2326
2327
  import * as readline from "readline";
2327
2328
  import { existsSync as existsSync19, readFileSync as readFileSync12, readdirSync as readdirSync11, statSync as statSync9 } from "fs";
2328
- import { join as join14, resolve as resolve5, extname as extname4, dirname as dirname6, basename as basename6 } from "path";
2329
+ import { join as join14, resolve as resolve5, extname as extname4, dirname as dirname7, basename as basename6 } from "path";
2329
2330
  import chalk9 from "chalk";
2330
2331
 
2331
2332
  // src/repl/renderer.ts
@@ -2527,7 +2528,7 @@ var Renderer = class {
2527
2528
  console.log(theme.dim(" Gemini (Google) \xB7 \u667A\u8C31\u6E05\u8A00 \xB7 \u81EA\u5B9A\u4E49 OpenAI \u517C\u5BB9"));
2528
2529
  console.log(HR);
2529
2530
  const mcpToolCount = mcpInfo?.tools ?? 0;
2530
- const toolTotal = 16 + pluginCount + mcpToolCount;
2531
+ const toolTotal = 17 + pluginCount + mcpToolCount;
2531
2532
  const extras = [];
2532
2533
  if (pluginCount > 0) extras.push(`${pluginCount} \u4E2A\u63D2\u4EF6`);
2533
2534
  if (mcpToolCount > 0) extras.push(`${mcpToolCount} \u4E2A MCP`);
@@ -2544,6 +2545,7 @@ var Renderer = class {
2544
2545
  console.log(tool("web_fetch", "\u6293\u53D6\u7F51\u9875\u5185\u5BB9\uFF08\u8F6C Markdown\uFF09"));
2545
2546
  console.log(tool("google_search", "Google \u641C\u7D22\uFF08\u9700\u914D\u7F6E API Key + CX\uFF09"));
2546
2547
  console.log(tool("save_last_response", "\u4FDD\u5B58 AI \u56DE\u7B54\u5230\u6587\u4EF6\uFF08tee \u6D41\u5F0F\u5199\u76D8\uFF09"));
2548
+ console.log(tool("stream_to_file", "\u6D41\u5F0F\u751F\u6210\u5927\u6587\u6863\u5E76\u76F4\u63A5\u5199\u5165\u6587\u4EF6\uFF08\u89C4\u907F token \u622A\u65AD\uFF09"));
2547
2549
  console.log(tool("save_memory", "\u5C06\u91CD\u8981\u4FE1\u606F\u6301\u4E45\u5316\u5230 ~/.aicli/memory.md\uFF0C\u8DE8\u4F1A\u8BDD\u81EA\u52A8\u6CE8\u5165"));
2548
2550
  console.log(tool("ask_user", "\u5411\u7528\u6237\u63D0\u95EE\u5E76\u7B49\u5F85\u56DE\u7B54\uFF08agentic \u5FAA\u73AF\u4E2D\u8BF7\u6C42\u6F84\u6E05\uFF09"));
2549
2551
  console.log(tool("write_todos", "\u62C6\u89E3\u4EFB\u52A1\u4E3A\u5B50\u4EFB\u52A1\u5217\u8868\uFF0C\u5B9E\u65F6\u663E\u793A\u8FDB\u5EA6"));
@@ -4597,7 +4599,7 @@ ${hint}` : "")
4597
4599
  description: "Run project tests and show structured report",
4598
4600
  usage: "/test [command|filter]",
4599
4601
  async execute(args, _ctx) {
4600
- const { executeTests } = await import("./run-tests-YGTHER7T.js");
4602
+ const { executeTests } = await import("./run-tests-77ZV7BUW.js");
4601
4603
  const argStr = args.join(" ").trim();
4602
4604
  let testArgs = {};
4603
4605
  if (argStr) {
@@ -6625,8 +6627,110 @@ var saveLastResponseTool = {
6625
6627
  }
6626
6628
  };
6627
6629
 
6630
+ // src/tools/builtin/stream-to-file.ts
6631
+ import { createWriteStream as createWriteStream2, mkdirSync as mkdirSync7 } from "fs";
6632
+ import { dirname as dirname6 } from "path";
6633
+ var streamToFileContext = {
6634
+ provider: null,
6635
+ model: "",
6636
+ systemPrompt: void 0,
6637
+ messages: [],
6638
+ extraMessages: []
6639
+ };
6640
+ var streamToFileTool = {
6641
+ definition: {
6642
+ name: "stream_to_file",
6643
+ description: `\u5C06\u5927\u578B\u5185\u5BB9\uFF08\u8D85\u8FC7 5KB \u6216 300 \u884C\u7684\u8BD5\u5377\u3001\u62A5\u544A\u7B49\uFF09\u76F4\u63A5\u4EE5\u6D41\u5F0F\u65B9\u5F0F\u751F\u6210\u5E76\u4FDD\u5B58\u5230\u6587\u4EF6\u3002
6644
+ \u9002\u7528\u573A\u666F\uFF1A\u5F53\u4F60\u9700\u8981\u751F\u6210\u5B8C\u6574\u7684\u6A21\u8003\u8BD5\u9898\uFF08600-700\u884C\uFF09\u3001\u957F\u7BC7\u62A5\u544A\u7B49\u5927\u6587\u6863\u65F6\uFF0C\u5FC5\u987B\u4F7F\u7528\u6B64\u5DE5\u5177\uFF0C
6645
+ \u4E0D\u8981\u5148\u5728\u5BF9\u8BDD\u4E2D\u8F93\u51FA\u518D\u4FDD\u5B58\uFF08\u90A3\u6837\u4F1A\u88AB maxTokens \u622A\u65AD\uFF09\u3002
6646
+ \u4F7F\u7528\u65B9\u6CD5\uFF1A\u4F20\u5165\u76EE\u6807\u6587\u4EF6\u8DEF\u5F84\u548C\u751F\u6210\u6307\u4EE4\uFF0C\u5DE5\u5177\u4F1A\u81EA\u52A8\u5411 AI \u53D1\u8D77\u6D41\u5F0F\u8BF7\u6C42\u5E76\u5C06\u5185\u5BB9\u5B9E\u65F6\u5199\u5165\u6587\u4EF6\u3002
6647
+ \u6CE8\u610F\uFF1Aprompt \u53C2\u6570\u5E94\u5305\u542B\u5B8C\u6574\u7684\u751F\u6210\u6307\u4EE4\uFF0C\u5982"\u8BF7\u751F\u6210\u4E00\u4EFD\u91D1\u6807\u98CE\u683C\u8FDB\u9636\u96BE\u5EA6\u7684\u5B8C\u6574\u6A21\u8003\u8BD5\u9898\uFF0C\u5305\u542B\u6240\u6709\u9898\u76EE\u548C\u53C2\u8003\u7B54\u6848"\u3002`,
6648
+ parameters: {
6649
+ path: {
6650
+ type: "string",
6651
+ description: "\u4FDD\u5B58\u6587\u4EF6\u7684\u8DEF\u5F84\uFF08\u542B\u6587\u4EF6\u540D\uFF09\uFF0C\u5982 exam_papers/20260221-01-\u6A21\u8003-\u8FDB\u9636.md",
6652
+ required: true
6653
+ },
6654
+ prompt: {
6655
+ type: "string",
6656
+ description: "\u751F\u6210\u5185\u5BB9\u7684\u5B8C\u6574\u6307\u4EE4\uFF08\u4F1A\u643A\u5E26\u5F53\u524D\u5BF9\u8BDD\u5386\u53F2\u4F5C\u4E3A\u4E0A\u4E0B\u6587\uFF09",
6657
+ required: true
6658
+ }
6659
+ },
6660
+ dangerous: false
6661
+ },
6662
+ async execute(args) {
6663
+ const filePath = String(args["path"] ?? "");
6664
+ const prompt = String(args["prompt"] ?? "");
6665
+ if (!filePath) throw new Error("path is required");
6666
+ if (!prompt) throw new Error("prompt is required");
6667
+ const ctx = streamToFileContext;
6668
+ if (!ctx.provider) {
6669
+ throw new Error("stream_to_file: provider not initialized");
6670
+ }
6671
+ const requestMessages = [
6672
+ ...ctx.messages,
6673
+ { role: "user", content: prompt, timestamp: /* @__PURE__ */ new Date() }
6674
+ ];
6675
+ undoStack.push(filePath, `stream_to_file: ${filePath}`);
6676
+ mkdirSync7(dirname6(filePath), { recursive: true });
6677
+ const writeStream = createWriteStream2(filePath, { encoding: "utf-8" });
6678
+ let streamError = null;
6679
+ writeStream.on("error", (err) => {
6680
+ streamError = err;
6681
+ });
6682
+ let totalBytes = 0;
6683
+ let totalChars = 0;
6684
+ const startTime = Date.now();
6685
+ let lastProgressAt = 0;
6686
+ const showProgress = (done) => {
6687
+ const now = Date.now();
6688
+ if (!done && now - lastProgressAt < 200) return;
6689
+ lastProgressAt = now;
6690
+ const elapsed = ((now - startTime) / 1e3).toFixed(1);
6691
+ const kb = (totalBytes / 1024).toFixed(1);
6692
+ process.stdout.write(`\r \u270D Writing ${filePath} ... ${kb} KB (${elapsed}s)`);
6693
+ };
6694
+ try {
6695
+ const stream = ctx.provider.chatStream({
6696
+ messages: requestMessages,
6697
+ model: ctx.model,
6698
+ systemPrompt: ctx.systemPrompt,
6699
+ stream: true,
6700
+ temperature: ctx.temperature,
6701
+ maxTokens: 32768,
6702
+ // 大文档专用,放宽到 32K tokens(约 24000 汉字)
6703
+ timeout: ctx.timeout ?? 3e5,
6704
+ ...ctx.extraMessages.length > 0 ? { _extraMessages: ctx.extraMessages } : {}
6705
+ });
6706
+ for await (const chunk of stream) {
6707
+ if (chunk.delta) {
6708
+ const bytes = Buffer.byteLength(chunk.delta, "utf-8");
6709
+ totalBytes += bytes;
6710
+ totalChars += chunk.delta.length;
6711
+ writeStream.write(chunk.delta);
6712
+ showProgress(false);
6713
+ }
6714
+ }
6715
+ if (streamError) throw streamError;
6716
+ await new Promise((resolve6, reject) => {
6717
+ writeStream.end((err) => {
6718
+ if (err) reject(err);
6719
+ else resolve6();
6720
+ });
6721
+ });
6722
+ process.stdout.write("\r\x1B[2K");
6723
+ const lines = totalChars > 0 ? Math.round(totalChars / 40) : 0;
6724
+ return `File saved: ${filePath} (~${lines} lines, ${(totalBytes / 1024).toFixed(1)} KB)`;
6725
+ } catch (err) {
6726
+ writeStream.destroy();
6727
+ throw err;
6728
+ }
6729
+ }
6730
+ };
6731
+
6628
6732
  // src/tools/builtin/save-memory.ts
6629
- import { existsSync as existsSync13, statSync as statSync8, appendFileSync as appendFileSync3, mkdirSync as mkdirSync7 } from "fs";
6733
+ import { existsSync as existsSync13, statSync as statSync8, appendFileSync as appendFileSync3, mkdirSync as mkdirSync8 } from "fs";
6630
6734
  import { join as join9 } from "path";
6631
6735
  import { homedir as homedir3 } from "os";
6632
6736
  function getMemoryFilePath() {
@@ -6656,7 +6760,7 @@ var saveMemoryTool = {
6656
6760
  const memoryPath = getMemoryFilePath();
6657
6761
  const configDir = join9(homedir3(), CONFIG_DIR_NAME);
6658
6762
  if (!existsSync13(configDir)) {
6659
- mkdirSync7(configDir, { recursive: true });
6763
+ mkdirSync8(configDir, { recursive: true });
6660
6764
  }
6661
6765
  const timestamp = formatTimestamp();
6662
6766
  const entry = `
@@ -7212,7 +7316,7 @@ var spawnAgentTool = {
7212
7316
 
7213
7317
  // src/tools/registry.ts
7214
7318
  import { pathToFileURL } from "url";
7215
- import { existsSync as existsSync14, mkdirSync as mkdirSync8, readdirSync as readdirSync8 } from "fs";
7319
+ import { existsSync as existsSync14, mkdirSync as mkdirSync9, readdirSync as readdirSync8 } from "fs";
7216
7320
  import { join as join10 } from "path";
7217
7321
  var ToolRegistry = class {
7218
7322
  tools = /* @__PURE__ */ new Map();
@@ -7229,6 +7333,7 @@ var ToolRegistry = class {
7229
7333
  this.register(runInteractiveTool);
7230
7334
  this.register(webFetchTool);
7231
7335
  this.register(saveLastResponseTool);
7336
+ this.register(streamToFileTool);
7232
7337
  this.register(saveMemoryTool);
7233
7338
  this.register(askUserTool);
7234
7339
  this.register(writeTodosTool);
@@ -7288,7 +7393,7 @@ var ToolRegistry = class {
7288
7393
  async loadPlugins(pluginsDir, allowPlugins = false) {
7289
7394
  if (!existsSync14(pluginsDir)) {
7290
7395
  try {
7291
- mkdirSync8(pluginsDir, { recursive: true });
7396
+ mkdirSync9(pluginsDir, { recursive: true });
7292
7397
  } catch {
7293
7398
  }
7294
7399
  return 0;
@@ -7806,15 +7911,6 @@ var ToolExecutor = class {
7806
7911
  }
7807
7912
  };
7808
7913
 
7809
- // src/tools/builtin/stream-to-file.ts
7810
- var streamToFileContext = {
7811
- provider: null,
7812
- model: "",
7813
- systemPrompt: void 0,
7814
- messages: [],
7815
- extraMessages: []
7816
- };
7817
-
7818
7914
  // src/repl/setup-wizard.ts
7819
7915
  import { password, select, input } from "@inquirer/prompts";
7820
7916
  var PROVIDERS = [
@@ -8043,7 +8139,7 @@ Managing ${displayName} API Key`);
8043
8139
  };
8044
8140
 
8045
8141
  // src/repl/custom-commands.ts
8046
- import { existsSync as existsSync16, readFileSync as readFileSync10, readdirSync as readdirSync9, mkdirSync as mkdirSync9 } from "fs";
8142
+ import { existsSync as existsSync16, readFileSync as readFileSync10, readdirSync as readdirSync9, mkdirSync as mkdirSync10 } from "fs";
8047
8143
  import { join as join11, extname as extname3 } from "path";
8048
8144
  import { execSync as execSync7 } from "child_process";
8049
8145
 
@@ -8152,7 +8248,7 @@ var CustomCommandManager = class {
8152
8248
  loadCommands() {
8153
8249
  this.commands.clear();
8154
8250
  if (!existsSync16(this.commandsDir)) {
8155
- mkdirSync9(this.commandsDir, { recursive: true });
8251
+ mkdirSync10(this.commandsDir, { recursive: true });
8156
8252
  return 0;
8157
8253
  }
8158
8254
  let count = 0;
@@ -8175,7 +8271,7 @@ var CustomCommandManager = class {
8175
8271
  };
8176
8272
 
8177
8273
  // src/repl/dev-state.ts
8178
- import { existsSync as existsSync17, readFileSync as readFileSync11, writeFileSync as writeFileSync8, unlinkSync as unlinkSync3, mkdirSync as mkdirSync10 } from "fs";
8274
+ import { existsSync as existsSync17, readFileSync as readFileSync11, writeFileSync as writeFileSync8, unlinkSync as unlinkSync3, mkdirSync as mkdirSync11 } from "fs";
8179
8275
  import { join as join12 } from "path";
8180
8276
  import { homedir as homedir4 } from "os";
8181
8277
  var DEV_STATE_MAX_CHARS = 6e3;
@@ -8235,7 +8331,7 @@ function getDevStatePath() {
8235
8331
  function saveDevState(content) {
8236
8332
  const configDir = join12(homedir4(), CONFIG_DIR_NAME);
8237
8333
  if (!existsSync17(configDir)) {
8238
- mkdirSync10(configDir, { recursive: true });
8334
+ mkdirSync11(configDir, { recursive: true });
8239
8335
  }
8240
8336
  let trimmed = content.trim();
8241
8337
  if (trimmed.length > DEV_STATE_MAX_CHARS) {
@@ -8762,7 +8858,7 @@ var McpManager = class {
8762
8858
  };
8763
8859
 
8764
8860
  // src/skills/manager.ts
8765
- import { existsSync as existsSync18, readdirSync as readdirSync10, mkdirSync as mkdirSync11 } from "fs";
8861
+ import { existsSync as existsSync18, readdirSync as readdirSync10, mkdirSync as mkdirSync12 } from "fs";
8766
8862
  import { join as join13 } from "path";
8767
8863
  var SKILL_CONTENT_WARN_CHARS = 5e3;
8768
8864
  var SkillManager = class {
@@ -8777,7 +8873,7 @@ var SkillManager = class {
8777
8873
  this.skills.clear();
8778
8874
  if (!existsSync18(this.skillsDir)) {
8779
8875
  try {
8780
- mkdirSync11(this.skillsDir, { recursive: true });
8876
+ mkdirSync12(this.skillsDir, { recursive: true });
8781
8877
  } catch {
8782
8878
  }
8783
8879
  return 0;
@@ -10061,7 +10157,7 @@ Session '${this.resumeSessionId}' not found.
10061
10157
  completeFilePath(partial) {
10062
10158
  try {
10063
10159
  const normalized = partial.replace(/\\/g, "/");
10064
- const dir = normalized.includes("/") ? dirname6(normalized) : ".";
10160
+ const dir = normalized.includes("/") ? dirname7(normalized) : ".";
10065
10161
  const prefix = normalized.includes("/") ? basename6(normalized) : normalized;
10066
10162
  const absDir = resolve5(process.cwd(), dir);
10067
10163
  if (!existsSync19(absDir)) return [];
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  executeTests,
4
4
  runTestsTool
5
- } from "./chunk-LPE66KZ3.js";
5
+ } from "./chunk-J6WSEEPI.js";
6
6
  export {
7
7
  executeTests,
8
8
  runTestsTool
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jinzd-ai-cli",
3
- "version": "0.1.62",
3
+ "version": "0.1.63",
4
4
  "description": "Cross-platform REPL-style AI CLI with multi-provider support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -71,7 +71,6 @@
71
71
  "marked": "^15.0.0",
72
72
  "marked-terminal": "^7.3.0",
73
73
  "openai": "^4.77.0",
74
- "ora": "^8.2.0",
75
74
  "undici": "^7.22.0",
76
75
  "uuid": "^11.0.5",
77
76
  "zod": "^3.24.1"