@ai-zen/cli 0.1.0-alpha.2

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 (99) hide show
  1. package/README.md +319 -0
  2. package/README.zh.md +319 -0
  3. package/dist/agent-creator.d.ts +17 -0
  4. package/dist/agent-creator.d.ts.map +1 -0
  5. package/dist/agent-creator.js +112 -0
  6. package/dist/agent-creator.js.map +1 -0
  7. package/dist/config-wizard.d.ts +6 -0
  8. package/dist/config-wizard.d.ts.map +1 -0
  9. package/dist/config-wizard.js +46 -0
  10. package/dist/config-wizard.js.map +1 -0
  11. package/dist/config.d.ts +68 -0
  12. package/dist/config.d.ts.map +1 -0
  13. package/dist/config.js +111 -0
  14. package/dist/config.js.map +1 -0
  15. package/dist/conversation-commands/back.d.ts +3 -0
  16. package/dist/conversation-commands/back.d.ts.map +1 -0
  17. package/dist/conversation-commands/back.js +144 -0
  18. package/dist/conversation-commands/back.js.map +1 -0
  19. package/dist/conversation-commands/clear.d.ts +3 -0
  20. package/dist/conversation-commands/clear.d.ts.map +1 -0
  21. package/dist/conversation-commands/clear.js +8 -0
  22. package/dist/conversation-commands/clear.js.map +1 -0
  23. package/dist/conversation-commands/editor.d.ts +3 -0
  24. package/dist/conversation-commands/editor.d.ts.map +1 -0
  25. package/dist/conversation-commands/editor.js +15 -0
  26. package/dist/conversation-commands/editor.js.map +1 -0
  27. package/dist/conversation-commands/exit.d.ts +3 -0
  28. package/dist/conversation-commands/exit.d.ts.map +1 -0
  29. package/dist/conversation-commands/exit.js +39 -0
  30. package/dist/conversation-commands/exit.js.map +1 -0
  31. package/dist/conversation-commands/help.d.ts +3 -0
  32. package/dist/conversation-commands/help.d.ts.map +1 -0
  33. package/dist/conversation-commands/help.js +12 -0
  34. package/dist/conversation-commands/help.js.map +1 -0
  35. package/dist/conversation-commands/index.d.ts +15 -0
  36. package/dist/conversation-commands/index.d.ts.map +1 -0
  37. package/dist/conversation-commands/index.js +63 -0
  38. package/dist/conversation-commands/index.js.map +1 -0
  39. package/dist/conversation-commands/new.d.ts +3 -0
  40. package/dist/conversation-commands/new.d.ts.map +1 -0
  41. package/dist/conversation-commands/new.js +47 -0
  42. package/dist/conversation-commands/new.js.map +1 -0
  43. package/dist/conversation-commands/save.d.ts +3 -0
  44. package/dist/conversation-commands/save.d.ts.map +1 -0
  45. package/dist/conversation-commands/save.js +34 -0
  46. package/dist/conversation-commands/save.js.map +1 -0
  47. package/dist/conversation-runner.d.ts +17 -0
  48. package/dist/conversation-runner.d.ts.map +1 -0
  49. package/dist/conversation-runner.js +212 -0
  50. package/dist/conversation-runner.js.map +1 -0
  51. package/dist/delta-renderer.d.ts +33 -0
  52. package/dist/delta-renderer.d.ts.map +1 -0
  53. package/dist/delta-renderer.js +117 -0
  54. package/dist/delta-renderer.js.map +1 -0
  55. package/dist/format-time.d.ts +38 -0
  56. package/dist/format-time.d.ts.map +1 -0
  57. package/dist/format-time.js +66 -0
  58. package/dist/format-time.js.map +1 -0
  59. package/dist/hook.d.ts +3 -0
  60. package/dist/hook.d.ts.map +1 -0
  61. package/dist/hook.js +83 -0
  62. package/dist/hook.js.map +1 -0
  63. package/dist/index.d.ts +3 -0
  64. package/dist/index.d.ts.map +1 -0
  65. package/dist/index.js +47 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/menus/agents.d.ts +5 -0
  68. package/dist/menus/agents.d.ts.map +1 -0
  69. package/dist/menus/agents.js +219 -0
  70. package/dist/menus/agents.js.map +1 -0
  71. package/dist/menus/common.d.ts +41 -0
  72. package/dist/menus/common.d.ts.map +1 -0
  73. package/dist/menus/common.js +104 -0
  74. package/dist/menus/common.js.map +1 -0
  75. package/dist/menus/config-display.d.ts +2 -0
  76. package/dist/menus/config-display.d.ts.map +1 -0
  77. package/dist/menus/config-display.js +69 -0
  78. package/dist/menus/config-display.js.map +1 -0
  79. package/dist/menus/config.d.ts +8 -0
  80. package/dist/menus/config.d.ts.map +1 -0
  81. package/dist/menus/config.js +407 -0
  82. package/dist/menus/config.js.map +1 -0
  83. package/dist/menus/conversations.d.ts +20 -0
  84. package/dist/menus/conversations.d.ts.map +1 -0
  85. package/dist/menus/conversations.js +74 -0
  86. package/dist/menus/conversations.js.map +1 -0
  87. package/dist/menus/index.d.ts +5 -0
  88. package/dist/menus/index.d.ts.map +1 -0
  89. package/dist/menus/index.js +63 -0
  90. package/dist/menus/index.js.map +1 -0
  91. package/dist/menus/start-conversation.d.ts +16 -0
  92. package/dist/menus/start-conversation.d.ts.map +1 -0
  93. package/dist/menus/start-conversation.js +176 -0
  94. package/dist/menus/start-conversation.js.map +1 -0
  95. package/dist/types.d.ts +20 -0
  96. package/dist/types.d.ts.map +1 -0
  97. package/dist/types.js +8 -0
  98. package/dist/types.js.map +1 -0
  99. package/package.json +53 -0
package/README.md ADDED
@@ -0,0 +1,319 @@
1
+ # @ai-zen/cli
2
+
3
+ A command-line interface for AI agents, built on `@ai-zen/agents-sdk` and `@ai-zen/agents-core`. Provides an interactive conversation terminal with built-in file system tools, sub-agent orchestration, and skill management.
4
+
5
+ ## Installation
6
+
7
+ ### Global Install
8
+
9
+ ```bash
10
+ npm install -g @ai-zen/cli
11
+ ```
12
+
13
+ ### Build from Source
14
+
15
+ ```bash
16
+ git clone git@github.com:ai-zen/cli.git
17
+ cd cli
18
+ pnpm install
19
+ pnpm build
20
+ npm install -g .
21
+ ```
22
+
23
+ ## Quick Start
24
+
25
+ ```bash
26
+ # Interactive main menu
27
+ zen
28
+
29
+ # Quick chat (pass message as argument)
30
+ zen Hello, introduce yourself.
31
+ ```
32
+
33
+ ## Main Menu
34
+
35
+ Run `zen` to enter the main menu:
36
+
37
+ ```
38
+ 🤖 Welcome to AI-Zen CLI
39
+
40
+ ? Select an action:
41
+ ▶️ Continue last unfinished conversation (if draft exists)
42
+ 💬 Start a new conversation
43
+ 📂 Continue a saved conversation
44
+ 📋 Manage saved conversations
45
+ 🤖 Manage Agents
46
+ ⚙️ Configuration
47
+ ❌ Exit
48
+ ```
49
+
50
+ ### Draft Recovery
51
+
52
+ If you exit a conversation without saving (or the process is killed), the conversation is **automatically saved as a draft**. Next time you start `zen`, you'll see:
53
+
54
+ ```
55
+ ▶️ Continue last unfinished conversation (12 messages, 2025/1/1 12:00:00)
56
+ 💬 Start a new conversation (discard draft)
57
+ ```
58
+
59
+ ### Conversation Commands
60
+
61
+ While in a conversation, all commands start with `/`:
62
+
63
+ | Command | Description |
64
+ |---------|-------------|
65
+ | `/exit` `/quit` | Exit the conversation (prompts to save) |
66
+ | `/save` | Save the current conversation |
67
+ | `/new` | Reset the conversation (clear history) |
68
+ | `/back` | Undo messages (roll back to a specific point and resend) |
69
+ | `/editor` | Open system editor for long-form input |
70
+ | `/clear` | Clear the screen |
71
+ | `/help` | Show available commands |
72
+
73
+ ### Conversation Migration
74
+
75
+ When the API response's `usage.prompt_tokens` exceeds the model's `maxContextTokens`, the system automatically generates a **handover document** summarizing completed tasks, pending items, and key decisions. A new conversation session is created with this document as context, ensuring seamless continuation.
76
+
77
+ The migration prompt template includes:
78
+ - **Conversation Breakpoint** — Last user/AI exchange verbatim
79
+ - **Completed Tasks** — Task titles and output paths
80
+ - **Pending Tasks** — Description, progress, next steps
81
+ - **Important Notes** — Technical preferences, lessons learned, architecture decisions
82
+ - **File Index** — Key files with descriptions
83
+ - **Handover Instructions** — SOP for the relay agent (read files first, verify state, then act)
84
+
85
+ ### Shell Fallback Hook
86
+
87
+ When you type an unrecognized command in your terminal, it can be automatically forwarded to AI for processing:
88
+
89
+ ```bash
90
+ # Install the hook
91
+ zen hook install
92
+
93
+ # After that, try typing something random:
94
+ > what's the weather today?
95
+ # This will be forwarded to AI instead of showing "command not found"
96
+
97
+ # Uninstall
98
+ zen hook uninstall
99
+ ```
100
+
101
+ ## Configuration
102
+
103
+ Configuration is stored in `~/.ai-zen/cli/config.json` (or `$AI_ZEN_DIR/cli/config.json` if set). The `maxContextTokens` field on each model sets the migration threshold (typically ~25% of the model's actual context window, e.g. 250,000 for a 1M-token model).
104
+
105
+ ```jsonc
106
+ {
107
+ "endpoints": [
108
+ {
109
+ "id": "openai",
110
+ "name": "OpenAI",
111
+ "apiKey": "sk-xxx",
112
+ "baseUrl": "https://api.openai.com/v1"
113
+ }
114
+ ],
115
+ "models": [
116
+ {
117
+ "id": "gpt-5.5",
118
+ "name": "GPT-5.5",
119
+ "endpointId": "openai",
120
+ "modelName": "gpt-5.5",
121
+ "maxContextTokens": 250000
122
+ }
123
+ ],
124
+ "imageModels": [
125
+ {
126
+ "id": "cogview-3",
127
+ "name": "CogView-3",
128
+ "endpointId": "bigmodelcn",
129
+ "modelName": "cogview-3",
130
+ "defaultSize": "1024x1024"
131
+ }
132
+ ],
133
+ "defaultModel": "deepseek-v4-flash",
134
+ "defaultImageModel": "cogview-3",
135
+ "defaultAgent": "default",
136
+ "defaultMigrationModel": "deepseek-v4-flash"
137
+ }
138
+ ```
139
+
140
+ ### Environment Variable
141
+
142
+ - `AI_ZEN_DIR` — Override the shared root directory (default: `~/.ai-zen`). CLI runtime data goes to `$AI_ZEN_DIR/cli/`, and shared resources (agents, skills, tools, MCP, etc.) go to `$AI_ZEN_DIR/`.
143
+
144
+ ## Filesystem Layout
145
+
146
+ ```
147
+ ~/.ai-zen/ ← Shared root (AI_ZEN_DIR)
148
+ ├── cli/ ← CLI runtime data
149
+ │ ├── config.json ← CLI endpoints, models
150
+ │ ├── conversations/ ← CLI conversations
151
+ │ └── drafts/ ← CLI drafts
152
+ ├── agents/ ← Agent definitions (shared)
153
+ │ ├── default.json ← Default agent (created on first run)
154
+ │ └── my-custom-agent.json
155
+ ├── sub-agents/ ← SubAgent definitions (shared)
156
+ │ ├── general-assistant.json ← Default sub-agent (created on first run)
157
+ │ └── my-coder.json
158
+ ├── skills/ ← Skill directory (shared)
159
+ │ └── my-skill/
160
+ │ └── SKILL.md
161
+ ├── tools/ ← User-defined tools (shared)
162
+ │ └── my-tool.js
163
+ ├── mcp.json ← MCP config (shared)
164
+ └── mcp-oauth/ ← MCP OAuth tokens (shared)
165
+
166
+ /path/to/project/
167
+ ├── .mcp.json ← Project-shared MCP config (committable)
168
+ └── .ai-zen/
169
+ ├── mcp.json ← Project-personal MCP config (not committed)
170
+ ├── skills/ ← Project Skill directory
171
+ │ └── my-skill/
172
+ │ └── SKILL.md
173
+ ├── tools/ ← Project tool directory
174
+ │ └── my-tool.js
175
+ ├── sub-agents/ ← Project SubAgent directory
176
+ │ └── project-helper.json
177
+ └── agents/ ← Project Agent directory (overrides user-level)
178
+ └── project-agent.json
179
+ ```
180
+
181
+ ### MCP Config Merge Priority
182
+
183
+ MCP server configurations are merged from multiple sources (high to low priority):
184
+
185
+ 1. Project personal `.ai-zen/mcp.json` (collected from cwd up to git root)
186
+ 2. Project shared `.mcp.json` (same)
187
+ 3. User-level `~/.ai-zen/mcp.json`
188
+
189
+ Same-named servers in higher priority override lower ones.
190
+
191
+ ## Built-in Tools
192
+
193
+ The CLI provides 16 built-in file system tools, implemented by `@ai-zen/agents-sdk`:
194
+
195
+ | Tool | Description |
196
+ |------|-------------|
197
+ | `cwd` | Get current working directory |
198
+ | `readFile` | Read file contents |
199
+ | `writeFile` | Write content to file |
200
+ | `edit` | Replace text in files (single replacement) |
201
+ | `batchEdit` | Batch replace text in files |
202
+ | `mkdir` | Create directories |
203
+ | `rm` | Delete files or directories |
204
+ | `glob` | Scan files with glob patterns |
205
+ | `ls` | List directory contents |
206
+ | `exist` | Check if path exists |
207
+ | `exec` | Execute shell commands |
208
+ | `findText` | Search text in files |
209
+ | `downloadFile` | Download file from URL |
210
+ | `generateImage` | Generate images from text |
211
+ | `rename` | Rename or move files |
212
+ | `copy` | Copy files or directories |
213
+
214
+ ### Dynamic Tools
215
+
216
+ In addition to built-in tools, the SDK provides 5 dynamic loading tools that are registered based on available resources and permissions:
217
+
218
+ | Tool | Purpose |
219
+ |------|---------|
220
+ | `load_skill` | Load a Skill document into context (idempotent, repeated calls skip re-injection) |
221
+ | `call_skill_sub_agent` | Delegate a task to a Skill sub-agent (only works for Skills with `sub-agent: true` in frontmatter) |
222
+ | `load_mcp` | Connect to an MCP server and list its tools (idempotent, repeated calls skip reconnection) |
223
+ | `call_mcp_tool` | Call a tool on a connected MCP server |
224
+ | `read_mcp_resource` | Read a resource from a connected MCP server |
225
+
226
+ ## Tool Assembly Pipeline
227
+
228
+ Tools are assembled in three phases by the SDK's `Capabilities` class:
229
+
230
+ 1. **Discovery** — Scan filesystem for built-in tools, user tools, SubAgents, Skills, and MCP servers
231
+ 2. **Filtering** — Apply permissions (`allow`/`deny`) and security exclusions (recursion protection)
232
+ 3. **Instantiation** — Map filtered names to `Tool` instances and register dynamic loaders
233
+
234
+ Each Agent has independent permissions — no inheritance between parent Agent and SubAgent. The only exception is the temporary Skill sub-agent (created by `call_skill_sub_agent`), which inherits the caller's permissions as a transient conversation proxy rather than an independent entity.
235
+
236
+ ## Permission Model
237
+
238
+ ```typescript
239
+ interface AgentPermissions {
240
+ tools?: { allow: string[] } | { deny: string[] };
241
+ skills?: { allow: string[] } | { deny: string[] };
242
+ mcps?: { allow: string[] } | { deny: string[] };
243
+ subagents?: { allow: string[] } | { deny: string[] };
244
+ }
245
+ ```
246
+
247
+ - Missing `permissions` field = all dimensions denied (`deny: ["*"]`)
248
+ - Each dimension uses either `allow` (whitelist) or `deny` (blacklist), mutually exclusive
249
+ - `"*"` wildcard matches any name
250
+ - Denied resources are fully invisible to the LLM (not just blocked)
251
+
252
+ ## MCP Server Support
253
+
254
+ MCP servers are configured in `mcp.json` files:
255
+
256
+ ```json
257
+ {
258
+ "servers": {
259
+ "my-server": {
260
+ "transport": "stdio",
261
+ "command": "node",
262
+ "args": ["server.js"],
263
+ "env": {
264
+ "API_KEY": "xxx"
265
+ }
266
+ }
267
+ }
268
+ }
269
+ ```
270
+
271
+ Connection lifecycle (connect, reconnect with exponential backoff, idle timeout) is fully managed by the SDK's `McpConnectionManager`.
272
+
273
+ ### OAuth (HTTP transport only) — 暂不支持
274
+
275
+ OAuth 2.0 授权流程(`mcp.json` 中的 `oauth` 字段)已定义类型和预留 `mcp-oauth/` 存储目录,但尚未实现。目前配置了 `oauth` 的 HTTP MCP 服务器将因缺少 token 而连接失败。
276
+
277
+ ## Preset Endpoints
278
+
279
+ | ID | Name | Default Base URL |
280
+ |----|------|-----------------|
281
+ | `openai` | OpenAI | `https://api.openai.com/v1` |
282
+ | `bigmodelcn` | BigModelCN (ZhipuAI) | `https://open.bigmodel.cn/api/paas/v4` |
283
+ | `deepseek` | DeepSeek | `https://api.deepseek.com/v1` |
284
+
285
+ ## Preset Models
286
+
287
+ | ID | Name | Endpoint |
288
+ |----|------|----------|
289
+ | `gpt-5.5` | GPT-5.5 | OpenAI |
290
+ | `glm-5.2` | GLM-5.2 | ZhipuAI |
291
+ | `glm-5.1` | GLM-5.1 | ZhipuAI |
292
+ | `glm-5` | GLM-5 | ZhipuAI |
293
+ | `glm-5-turbo` | GLM-5-Turbo | ZhipuAI |
294
+ | `glm-5v-turbo` | GLM-5V-Turbo | ZhipuAI |
295
+ | `glm-4.7-flash` | GLM-4.7-Flash | ZhipuAI |
296
+ | `deepseek-v4-pro` | DeepSeek-V4-Pro | DeepSeek |
297
+ | `deepseek-v4-flash` | DeepSeek-V4-Flash | DeepSeek (**default**) |
298
+
299
+ ## Development
300
+
301
+ ```bash
302
+ pnpm install
303
+ pnpm build
304
+ pnpm start
305
+ ```
306
+
307
+ ## Testing
308
+
309
+ ```bash
310
+ # Unit tests
311
+ pnpm test
312
+
313
+ # E2E tests (requires API key in .env.local)
314
+ pnpm test -- src/__tests__/e2e.test.ts
315
+ ```
316
+
317
+ ## License
318
+
319
+ ISC
package/README.zh.md ADDED
@@ -0,0 +1,319 @@
1
+ # @ai-zen/cli
2
+
3
+ AI Agent 命令行界面,基于 `@ai-zen/agents-sdk` 和 `@ai-zen/agents-core` 构建。提供交互式对话终端,内置文件系统操作工具,支持 MCP 协议集成外部工具、子 Agent 编排和 Skill 管理。
4
+
5
+ ## 安装
6
+
7
+ ### 全局安装
8
+
9
+ ```bash
10
+ npm install -g @ai-zen/cli
11
+ ```
12
+
13
+ ### 从源码构建
14
+
15
+ ```bash
16
+ git clone git@github.com:ai-zen/cli.git
17
+ cd cli
18
+ pnpm install
19
+ pnpm build
20
+ npm install -g .
21
+ ```
22
+
23
+ ## 快速使用
24
+
25
+ ```bash
26
+ # 交互式主菜单
27
+ zen
28
+
29
+ # 快速对话(参数作为初始消息)
30
+ zen 你好,请介绍一下你自己。
31
+ ```
32
+
33
+ ## 主菜单
34
+
35
+ 运行 `zen` 进入主菜单:
36
+
37
+ ```
38
+ 🤖 欢迎使用 AI-Zen CLI
39
+
40
+ ? 请选择操作:
41
+ ▶️ 继续上次未完成的对话 (如有草稿)
42
+ 💬 开始新对话
43
+ 📂 继续已保存的对话
44
+ 📋 管理已保存的对话
45
+ 🤖 管理 Agents
46
+ ⚙️ 配置管理
47
+ ❌ 退出
48
+ ```
49
+
50
+ ### 草稿恢复
51
+
52
+ 如果退出对话时没有保存(或进程被强制杀死),对话内容会**自动保存为草稿**。下次启动 `zen` 时会看到:
53
+
54
+ ```
55
+ ▶️ 继续上次未完成的对话 (12 条消息, 2025/1/1 12:00:00)
56
+ 💬 开始新对话(放弃草稿)
57
+ ```
58
+
59
+ ### 对话命令
60
+
61
+ 对话中输入的所有命令以 `/` 开头:
62
+
63
+ | 命令 | 说明 |
64
+ |------|------|
65
+ | `/exit` `/quit` | 退出对话(会提示是否保存) |
66
+ | `/save` | 保存当前对话 |
67
+ | `/new` | 重置会话(清空历史) |
68
+ | `/back` | 撤回消息(回退到指定位置并可编辑后重发) |
69
+ | `/editor` | 使用系统编辑器(vim/nano)输入长消息 |
70
+ | `/clear` | 清屏 |
71
+ | `/help` | 显示可用命令 |
72
+
73
+ ### 任务迁移
74
+
75
+ 当 API 响应中的 `usage.prompt_tokens` 超过模型的 `maxContextTokens` 时,系统会自动生成**交接文档**,汇总已完成任务、待办事项和关键决策,然后创建新会话并将交接文档注入为上下文,实现无缝衔接。
76
+
77
+ 迁移提示词模板包含:
78
+ - **对话断点** — 最后一段对话原文引用
79
+ - **已完成的任务** — 任务标题和产出路径
80
+ - **未完成的任务** — 描述、进度、下一步
81
+ - **重要记忆** — 技术偏好、踩坑记录、架构决策
82
+ - **文件索引** — 关键文件及用途说明
83
+ - **接手指令** — 先读文件验真、再对状态、后行动的 SOP
84
+
85
+ ### Shell 兜底钩子
86
+
87
+ 当你在终端输入一个不存在的命令时,自动转发给 AI 处理:
88
+
89
+ ```bash
90
+ # 安装钩子
91
+ zen hook install
92
+
93
+ # 之后随便输入点什么:
94
+ > 今天天气怎么样?
95
+ # 这条消息会被转发给 AI,而不是显示 "command not found"
96
+
97
+ # 卸载钩子
98
+ zen hook uninstall
99
+ ```
100
+
101
+ ## 配置管理
102
+
103
+ 配置文件存储在 `~/.ai-zen/cli/config.json`(或 `$AI_ZEN_DIR/cli/config.json`)。其中 `maxContextTokens` 是迁移触发阈值(通常设为模型实际上下文窗口的约 25%,例如 1M tokens 的模型设为 250,000)。
104
+
105
+ ```jsonc
106
+ {
107
+ "endpoints": [
108
+ {
109
+ "id": "openai",
110
+ "name": "OpenAI",
111
+ "apiKey": "sk-xxx",
112
+ "baseUrl": "https://api.openai.com/v1"
113
+ }
114
+ ],
115
+ "models": [
116
+ {
117
+ "id": "gpt-5.5",
118
+ "name": "GPT-5.5",
119
+ "endpointId": "openai",
120
+ "modelName": "gpt-5.5",
121
+ "maxContextTokens": 250000
122
+ }
123
+ ],
124
+ "imageModels": [
125
+ {
126
+ "id": "cogview-3",
127
+ "name": "CogView-3",
128
+ "endpointId": "bigmodelcn",
129
+ "modelName": "cogview-3",
130
+ "defaultSize": "1024x1024"
131
+ }
132
+ ],
133
+ "defaultModel": "deepseek-v4-flash",
134
+ "defaultImageModel": "cogview-3",
135
+ "defaultAgent": "default",
136
+ "defaultMigrationModel": "deepseek-v4-flash"
137
+ }
138
+ ```
139
+
140
+ ### 环境变量
141
+
142
+ - `AI_ZEN_DIR` — 覆盖共享根目录(默认 `~/.ai-zen`)。CLI 运行时数据在 `$AI_ZEN_DIR/cli/`,共享资源(agents、skills、tools、MCP 等)在 `$AI_ZEN_DIR/`。
143
+
144
+ ## 文件系统布局
145
+
146
+ ```
147
+ ~/.ai-zen/ ← 共享根(AI_ZEN_DIR)
148
+ ├── cli/ ← CLI 运行时数据
149
+ │ ├── config.json ← CLI 的端点、模型配置
150
+ │ ├── conversations/ ← CLI 对话记录
151
+ │ └── drafts/ ← CLI 草稿
152
+ ├── agents/ ← Agent 定义(共享)
153
+ │ ├── default.json ← 默认 Agent(首次运行自动创建)
154
+ │ └── my-custom-agent.json
155
+ ├── sub-agents/ ← SubAgent 定义(共享)
156
+ │ ├── general-assistant.json ← 默认 SubAgent(首次运行自动创建)
157
+ │ └── my-coder.json
158
+ ├── skills/ ← Skill 目录(共享)
159
+ │ └── my-skill/
160
+ │ └── SKILL.md
161
+ ├── tools/ ← 用户自定义工具(共享)
162
+ │ └── my-tool.js
163
+ ├── mcp.json ← MCP 配置(共享)
164
+ └── mcp-oauth/ ← MCP OAuth 令牌(共享)
165
+
166
+ /path/to/project/
167
+ ├── .mcp.json ← 项目共享 MCP 配置(可提交 git)
168
+ └── .ai-zen/
169
+ ├── mcp.json ← 项目个人 MCP 配置(不提交)
170
+ ├── skills/ ← 项目 Skill 目录
171
+ │ └── my-skill/
172
+ │ └── SKILL.md
173
+ ├── tools/ ← 项目工具目录
174
+ │ └── my-tool.js
175
+ ├── sub-agents/ ← 项目 SubAgent 目录
176
+ │ └── project-helper.json
177
+ └── agents/ ← 项目 Agent 目录(覆盖用户级)
178
+ └── project-agent.json
179
+ ```
180
+
181
+ ### MCP 配置合并优先级
182
+
183
+ MCP 服务器配置从多个来源合并(优先级从高到低):
184
+
185
+ 1. 项目个人 `.ai-zen/mcp.json`(从 cwd 向上到 git root 沿途收集)
186
+ 2. 项目共享 `.mcp.json`(同上)
187
+ 3. 用户级 `~/.ai-zen/mcp.json`
188
+
189
+ 同名 server 高优先级覆盖低优先级。
190
+
191
+ ## 内置工具
192
+
193
+ CLI 提供 16 个内置文件系统工具,由 `@ai-zen/agents-sdk` 实现:
194
+
195
+ | 工具 | 说明 |
196
+ |------|------|
197
+ | `cwd` | 获取当前工作目录 |
198
+ | `readFile` | 读取文件内容 |
199
+ | `writeFile` | 写入文件 |
200
+ | `edit` | 替换文件中的文本(单次替换) |
201
+ | `batchEdit` | 批量编辑文本 |
202
+ | `mkdir` | 创建目录 |
203
+ | `rm` | 删除文件或目录 |
204
+ | `glob` | 通配符扫描文件 |
205
+ | `ls` | 列出目录 |
206
+ | `exist` | 检查路径是否存在 |
207
+ | `exec` | 执行 shell 命令 |
208
+ | `findText` | 在文件中查找文本 |
209
+ | `downloadFile` | 从 URL 下载文件 |
210
+ | `generateImage` | 根据描述生成图片 |
211
+ | `rename` | 重命名或移动文件 |
212
+ | `copy` | 复制文件或目录 |
213
+
214
+ ### 动态工具
215
+
216
+ 除内置工具外,SDK 还提供 5 个动态加载工具,根据可用资源和权限按需注册:
217
+
218
+ | 工具 | 用途 |
219
+ |------|------|
220
+ | `load_skill` | 加载 Skill 文档到上下文(幂等,重复加载不重复注入) |
221
+ | `call_skill_sub_agent` | 将任务委派给 Skill 子 Agent(仅对 frontmatter 声明了 `sub-agent: true` 的 Skill 有效) |
222
+ | `load_mcp` | 连接 MCP 服务器并列出其工具(幂等,重复连接不重建) |
223
+ | `call_mcp_tool` | 调用已连接 MCP 服务器上的工具 |
224
+ | `read_mcp_resource` | 读取已连接 MCP 服务器上的资源 |
225
+
226
+ ## 工具装配流程
227
+
228
+ 工具装配由 SDK 的 `Capabilities` 类管理,分为三个阶段:
229
+
230
+ 1. **发现** — 扫描文件系统获取内置工具、用户工具、SubAgent、Skill 和 MCP 服务器
231
+ 2. **过滤** — 应用权限(`allow`/`deny`)和安全排除(递归保护)
232
+ 3. **实例化** — 将过滤后的名称映射为 `Tool` 实例,注册动态加载器
233
+
234
+ 每个 Agent 拥有独立的权限配置,父 Agent 与 SubAgent 之间不继承权限。唯一的例外是 `call_skill_sub_agent` 创建的临时 Skill 子 Agent——它是临时的对话分身而非独立实体,因此继承调用者的权限。
235
+
236
+ ## 权限模型
237
+
238
+ ```typescript
239
+ interface AgentPermissions {
240
+ tools?: { allow: string[] } | { deny: string[] };
241
+ skills?: { allow: string[] } | { deny: string[] };
242
+ mcps?: { allow: string[] } | { deny: string[] };
243
+ subagents?: { allow: string[] } | { deny: string[] };
244
+ }
245
+ ```
246
+
247
+ - 缺少 `permissions` 字段 = 所有维度拒绝(`deny: ["*"]`)
248
+ - 每个维度使用 `allow`(白名单)或 `deny`(黑名单),互斥
249
+ - `"*"` 通配符匹配任意名称
250
+ - 被拒绝的资源对 LLM 完全不可见(不仅执行阻断)
251
+
252
+ ## MCP 服务器支持
253
+
254
+ MCP 服务器配置在 `mcp.json` 文件中:
255
+
256
+ ```json
257
+ {
258
+ "servers": {
259
+ "my-server": {
260
+ "transport": "stdio",
261
+ "command": "node",
262
+ "args": ["server.js"],
263
+ "env": {
264
+ "API_KEY": "xxx"
265
+ }
266
+ }
267
+ }
268
+ }
269
+ ```
270
+
271
+ 连接生命周期(连接、指数退避重连、空闲超时断开)由 SDK 的 `McpConnectionManager` 全权管理。
272
+
273
+ ### OAuth(仅 HTTP 传输类型)— 暂不支持
274
+
275
+ OAuth 2.0 授权流程(`mcp.json` 中的 `oauth` 字段)已定义类型和预留 `mcp-oauth/` 存储目录,但尚未实现。目前配置了 `oauth` 的 HTTP MCP 服务器将因缺少 token 而连接失败。
276
+
277
+ ## 预置端点
278
+
279
+ | ID | 名称 | 默认 Base URL |
280
+ |----|------|--------------|
281
+ | `openai` | OpenAI | `https://api.openai.com/v1` |
282
+ | `bigmodelcn` | BigModelCN (智谱AI) | `https://open.bigmodel.cn/api/paas/v4` |
283
+ | `deepseek` | DeepSeek | `https://api.deepseek.com/v1` |
284
+
285
+ ## 预置模型
286
+
287
+ | ID | 名称 | 端点 |
288
+ |----|------|------|
289
+ | `gpt-5.5` | GPT-5.5 | OpenAI |
290
+ | `glm-5.2` | GLM-5.2 | 智谱AI |
291
+ | `glm-5.1` | GLM-5.1 | 智谱AI |
292
+ | `glm-5` | GLM-5 | 智谱AI |
293
+ | `glm-5-turbo` | GLM-5-Turbo | 智谱AI |
294
+ | `glm-5v-turbo` | GLM-5V-Turbo | 智谱AI |
295
+ | `glm-4.7-flash` | GLM-4.7-Flash | 智谱AI |
296
+ | `deepseek-v4-pro` | DeepSeek-V4-Pro | DeepSeek |
297
+ | `deepseek-v4-flash` | DeepSeek-V4-Flash | DeepSeek(**默认模型**) |
298
+
299
+ ## 开发
300
+
301
+ ```bash
302
+ pnpm install
303
+ pnpm build
304
+ pnpm start
305
+ ```
306
+
307
+ ## 测试
308
+
309
+ ```bash
310
+ # 单元测试
311
+ pnpm test
312
+
313
+ # 端到端测试(需在 .env.local 中配置 API Key)
314
+ pnpm test -- src/__tests__/e2e.test.ts
315
+ ```
316
+
317
+ ## 许可
318
+
319
+ ISC
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Agent 创建 — CLI 层
3
+ *
4
+ * 委托给 @ai-zen/agents-sdk 的 Provider + Capabilities。
5
+ * CLI 层负责:组装路径、构建 Provider 单例、注册默认插件。
6
+ */
7
+ import { Provider, SdkAgent } from "@ai-zen/agents-sdk";
8
+ import type { AgentNS } from "@ai-zen/agents-core";
9
+ export declare function getProvider(): Provider;
10
+ export declare function resetProvider(): void;
11
+ export interface CreateAgentOptions {
12
+ messages?: AgentNS.Message[];
13
+ agentId?: string;
14
+ }
15
+ export declare function createAgent(options: CreateAgentOptions): SdkAgent;
16
+ export declare function createMigrationAgent(modelId: string): SdkAgent;
17
+ //# sourceMappingURL=agent-creator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-creator.d.ts","sourceRoot":"","sources":["../src/agent-creator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EACL,QAAQ,EAER,QAAQ,EAIT,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAoDnD,wBAAgB,WAAW,IAAI,QAAQ,CAwBtC;AAED,wBAAgB,aAAa,IAAI,IAAI,CAGpC;AAID,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,QAAQ,CAajE;AAID,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAkB9D"}