jinzd-ai-cli 0.1.16 → 0.1.17

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 (3) hide show
  1. package/CLAUDE.md +18 -1
  2. package/dist/index.js +11 -5
  3. package/package.json +1 -1
package/CLAUDE.md CHANGED
@@ -303,8 +303,25 @@ const stdinLines = Array.isArray(rawStdin) ? rawStdin.map(String)
303
303
 
304
304
  - [x] **MCP 协议支持**(2026-02-23):轻量级 MCP 客户端(不依赖 SDK),STDIO 传输 + JSON-RPC 2.0 通信。`src/mcp/` 模块:`types.ts`(协议类型)、`client.ts`(单服务器连接)、`manager.ts`(多服务器管理 + Tool 转换)。配置兼容 Claude Desktop(`config.json` 的 `mcpServers` 字段)。启动自动连接、发现工具并注册到 ToolRegistry,工具名格式 `mcp__<serverId>__<toolName>`。新增 `/mcp` REPL 命令查看连接状态和工具列表。
305
305
 
306
- ### 下一步待实现
306
+ ### P0 — 核心竞争力缺口(下一步最先实现)
307
+ - [ ] **`/compact` 上下文压缩**:调用当前 provider 生成对话摘要,替换 session.messages 前 N 条为单条 summary,保留最近 K 条。长对话必需。
308
+ - [ ] **Headless 非交互模式(`-p` flag)**:`echo "..." | aicli -p "review"` 单轮对话后退出,支持 `--json` 输出,解锁 CI/CD 脚本场景。
309
+ - [ ] **Plan Mode 规划模式**:`/plan` 进入只读规划(AI 只能用 read/list/grep 工具),输出计划后 `/plan execute` 切回正常模式执行。
310
+ - [ ] **Sub-agents 系统**:`spawn_agent` 工具在子进程中运行独立 agentic 循环,支持并行任务分解。
311
+
312
+ ### P1 — 重要差距
307
313
  - [ ] **Agent Skills 系统**:可复用的专业技能包(`.aicli/skills/`)
314
+ - [ ] **`/init` 项目初始化**:扫描项目结构自动生成 `AICLI.md`
315
+ - [ ] **`/copy` 剪贴板支持**:将最后回答复制到系统剪贴板
316
+ - [ ] **多文件编辑预览**:diff preview + 批量 apply/reject
317
+ - [ ] **Token 用量统计 `/cost`**:实时显示 input/output token 数,累计 session 用量
318
+
319
+ ### P2 — 增强功能
320
+ - [ ] **Hooks 系统**:pre/post tool execution hooks
321
+ - [ ] **Permission Rules**:基于规则的工具权限控制
322
+ - [ ] **Checkpointing**:会话检查点,可回退到任意历史点
323
+ - [ ] **`/review` 代码审查**:集成 git diff,输出结构化审查意见
324
+ - [ ] **Custom Commands**:用户自定义 REPL 命令(`~/.aicli/commands/`)
308
325
 
309
326
  ## 已知待改进项
310
327
 
package/dist/index.js CHANGED
@@ -129,7 +129,7 @@ var EnvLoader = class {
129
129
  };
130
130
 
131
131
  // src/core/constants.ts
132
- var VERSION = "0.1.16";
132
+ var VERSION = "0.1.17";
133
133
  var APP_NAME = "ai-cli";
134
134
  var CONFIG_DIR_NAME = ".aicli";
135
135
  var CONFIG_FILE_NAME = "config.json";
@@ -822,6 +822,7 @@ var OpenAICompatibleProvider = class extends BaseProvider {
822
822
  inputTokens: response.usage.prompt_tokens,
823
823
  outputTokens: response.usage.completion_tokens
824
824
  } : void 0;
825
+ const reasoningContent = message.reasoning_content;
825
826
  if (message.tool_calls && message.tool_calls.length > 0) {
826
827
  const toolCalls = message.tool_calls.map((tc) => {
827
828
  const rawArgs = tc.function.arguments || "{}";
@@ -844,7 +845,7 @@ var OpenAICompatibleProvider = class extends BaseProvider {
844
845
  arguments: parsedArgs
845
846
  };
846
847
  });
847
- return { toolCalls, usage };
848
+ return { toolCalls, usage, reasoningContent };
848
849
  }
849
850
  return { content: message.content ?? "", usage };
850
851
  } catch (err) {
@@ -854,7 +855,7 @@ var OpenAICompatibleProvider = class extends BaseProvider {
854
855
  /**
855
856
  * 将工具结果作为 tool_call 消息追加,供下一轮使用
856
857
  */
857
- buildToolResultMessages(assistantToolCalls, results) {
858
+ buildToolResultMessages(assistantToolCalls, results, reasoningContent) {
858
859
  const assistantMsg = {
859
860
  role: "assistant",
860
861
  content: null,
@@ -867,6 +868,9 @@ var OpenAICompatibleProvider = class extends BaseProvider {
867
868
  }
868
869
  }))
869
870
  };
871
+ if (reasoningContent !== void 0) {
872
+ assistantMsg.reasoning_content = reasoningContent;
873
+ }
870
874
  const resultMsgs = results.map((r) => ({
871
875
  role: "tool",
872
876
  tool_call_id: r.callId,
@@ -5932,7 +5936,8 @@ ${memory.content}`);
5932
5936
  content: tc.name === "save_last_response" ? `File saved: ${saveToFile} (${lines} lines, ${bytes} bytes)` : `[skipped: file already saved by tee streaming]`,
5933
5937
  isError: false
5934
5938
  }));
5935
- const newMsgs2 = provider.buildToolResultMessages(result.toolCalls, syntheticResults);
5939
+ const reasoningContent2 = "reasoningContent" in result ? result.reasoningContent : void 0;
5940
+ const newMsgs2 = provider.buildToolResultMessages(result.toolCalls, syntheticResults, reasoningContent2);
5936
5941
  extraMessages.push(...newMsgs2);
5937
5942
  if (roundUsage.inputTokens > 0 || roundUsage.outputTokens > 0) {
5938
5943
  this.sessionTokenUsage.inputTokens += roundUsage.inputTokens;
@@ -5955,7 +5960,8 @@ ${memory.content}`);
5955
5960
  streamToFileContext.temperature = modelParams.temperature;
5956
5961
  streamToFileContext.timeout = modelParams.timeout;
5957
5962
  const toolResults = await this.toolExecutor.executeAll(result.toolCalls);
5958
- const newMsgs = provider.buildToolResultMessages(result.toolCalls, toolResults);
5963
+ const reasoningContent = "reasoningContent" in result ? result.reasoningContent : void 0;
5964
+ const newMsgs = provider.buildToolResultMessages(result.toolCalls, toolResults, reasoningContent);
5959
5965
  extraMessages.push(...newMsgs);
5960
5966
  const nextRound = round + 2;
5961
5967
  spinner.start(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jinzd-ai-cli",
3
- "version": "0.1.16",
3
+ "version": "0.1.17",
4
4
  "description": "Cross-platform REPL-style AI CLI with multi-provider support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",