@ai-zen/cli 0.9.0 → 1.0.0-alpha.10
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/CHANGELOG.md +199 -1
- package/README.md +115 -62
- package/README.zh.md +115 -62
- package/dist/agent-creator.d.ts +18 -1
- package/dist/agent-creator.d.ts.map +1 -1
- package/dist/agent-creator.js +36 -12
- package/dist/agent-creator.js.map +1 -1
- package/dist/agents-store.d.ts +33 -0
- package/dist/agents-store.d.ts.map +1 -0
- package/dist/agents-store.js +50 -0
- package/dist/agents-store.js.map +1 -0
- package/dist/auto-migrate-confirm.d.ts +43 -0
- package/dist/auto-migrate-confirm.d.ts.map +1 -0
- package/dist/auto-migrate-confirm.js +46 -0
- package/dist/auto-migrate-confirm.js.map +1 -0
- package/dist/config-editor.d.ts +201 -0
- package/dist/config-editor.d.ts.map +1 -0
- package/dist/config-editor.js +511 -0
- package/dist/config-editor.js.map +1 -0
- package/dist/config.d.ts +55 -16
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +46 -29
- package/dist/config.js.map +1 -1
- package/dist/conversation-commands/registry.d.ts +4 -5
- package/dist/conversation-commands/registry.d.ts.map +1 -1
- package/dist/conversation-commands/registry.js +11 -7
- package/dist/conversation-commands/registry.js.map +1 -1
- package/dist/conversation-persist-plugin.d.ts +25 -0
- package/dist/conversation-persist-plugin.d.ts.map +1 -0
- package/dist/conversation-persist-plugin.js +44 -0
- package/dist/conversation-persist-plugin.js.map +1 -0
- package/dist/conversation-repository.d.ts +19 -2
- package/dist/conversation-repository.d.ts.map +1 -1
- package/dist/conversation-repository.js +48 -5
- package/dist/conversation-repository.js.map +1 -1
- package/dist/format-time.d.ts +2 -2
- package/dist/format-time.js +2 -2
- package/dist/handoff-service.d.ts +19 -0
- package/dist/handoff-service.d.ts.map +1 -0
- package/dist/handoff-service.js +87 -0
- package/dist/handoff-service.js.map +1 -0
- package/dist/hook.d.ts.map +1 -1
- package/dist/hook.js +58 -46
- package/dist/hook.js.map +1 -1
- package/dist/index.js +82 -35
- package/dist/index.js.map +1 -1
- package/dist/mode.d.ts +56 -0
- package/dist/mode.d.ts.map +1 -0
- package/dist/mode.js +83 -0
- package/dist/mode.js.map +1 -0
- package/dist/session-pointer.d.ts +35 -0
- package/dist/session-pointer.d.ts.map +1 -0
- package/dist/session-pointer.js +81 -0
- package/dist/session-pointer.js.map +1 -0
- package/dist/stdio-runner.d.ts +34 -0
- package/dist/stdio-runner.d.ts.map +1 -0
- package/dist/stdio-runner.js +161 -0
- package/dist/stdio-runner.js.map +1 -0
- package/dist/tui/chat-session.d.ts +106 -0
- package/dist/tui/chat-session.d.ts.map +1 -0
- package/dist/tui/chat-session.js +299 -0
- package/dist/tui/chat-session.js.map +1 -0
- package/dist/tui/components.d.ts +47 -0
- package/dist/tui/components.d.ts.map +1 -0
- package/dist/tui/components.js +62 -0
- package/dist/tui/components.js.map +1 -0
- package/dist/tui/config-wizard/detail.d.ts +51 -0
- package/dist/tui/config-wizard/detail.d.ts.map +1 -0
- package/dist/tui/config-wizard/detail.js +273 -0
- package/dist/tui/config-wizard/detail.js.map +1 -0
- package/dist/tui/config-wizard/engine.d.ts +36 -0
- package/dist/tui/config-wizard/engine.d.ts.map +1 -0
- package/dist/tui/config-wizard/engine.js +187 -0
- package/dist/tui/config-wizard/engine.js.map +1 -0
- package/dist/tui/config-wizard/fields.d.ts +24 -0
- package/dist/tui/config-wizard/fields.d.ts.map +1 -0
- package/dist/tui/config-wizard/fields.js +411 -0
- package/dist/tui/config-wizard/fields.js.map +1 -0
- package/dist/tui/config-wizard/frame.d.ts +27 -0
- package/dist/tui/config-wizard/frame.d.ts.map +1 -0
- package/dist/tui/config-wizard/frame.js +28 -0
- package/dist/tui/config-wizard/frame.js.map +1 -0
- package/dist/tui/config-wizard/index.d.ts +6 -0
- package/dist/tui/config-wizard/index.d.ts.map +1 -0
- package/dist/tui/config-wizard/index.js +7 -0
- package/dist/tui/config-wizard/index.js.map +1 -0
- package/dist/tui/config-wizard/kv-editor.d.ts +18 -0
- package/dist/tui/config-wizard/kv-editor.d.ts.map +1 -0
- package/dist/tui/config-wizard/kv-editor.js +116 -0
- package/dist/tui/config-wizard/kv-editor.js.map +1 -0
- package/dist/tui/config-wizard/list.d.ts +13 -0
- package/dist/tui/config-wizard/list.d.ts.map +1 -0
- package/dist/tui/config-wizard/list.js +29 -0
- package/dist/tui/config-wizard/list.js.map +1 -0
- package/dist/tui/config-wizard/mcp-helpers.d.ts +9 -0
- package/dist/tui/config-wizard/mcp-helpers.d.ts.map +1 -0
- package/dist/tui/config-wizard/mcp-helpers.js +19 -0
- package/dist/tui/config-wizard/mcp-helpers.js.map +1 -0
- package/dist/tui/config-wizard/menu.d.ts +18 -0
- package/dist/tui/config-wizard/menu.d.ts.map +1 -0
- package/dist/tui/config-wizard/menu.js +70 -0
- package/dist/tui/config-wizard/menu.js.map +1 -0
- package/dist/tui/config-wizard/prompt-editor.d.ts +24 -0
- package/dist/tui/config-wizard/prompt-editor.d.ts.map +1 -0
- package/dist/tui/config-wizard/prompt-editor.js +83 -0
- package/dist/tui/config-wizard/prompt-editor.js.map +1 -0
- package/dist/tui/config-wizard/prompt.d.ts +57 -0
- package/dist/tui/config-wizard/prompt.d.ts.map +1 -0
- package/dist/tui/config-wizard/prompt.js +130 -0
- package/dist/tui/config-wizard/prompt.js.map +1 -0
- package/dist/tui/config-wizard/step-agents.d.ts +4 -0
- package/dist/tui/config-wizard/step-agents.d.ts.map +1 -0
- package/dist/tui/config-wizard/step-agents.js +110 -0
- package/dist/tui/config-wizard/step-agents.js.map +1 -0
- package/dist/tui/config-wizard/step-defaults.d.ts +4 -0
- package/dist/tui/config-wizard/step-defaults.d.ts.map +1 -0
- package/dist/tui/config-wizard/step-defaults.js +76 -0
- package/dist/tui/config-wizard/step-defaults.js.map +1 -0
- package/dist/tui/config-wizard/step-endpoints.d.ts +4 -0
- package/dist/tui/config-wizard/step-endpoints.d.ts.map +1 -0
- package/dist/tui/config-wizard/step-endpoints.js +43 -0
- package/dist/tui/config-wizard/step-endpoints.js.map +1 -0
- package/dist/tui/config-wizard/step-mcp.d.ts +4 -0
- package/dist/tui/config-wizard/step-mcp.d.ts.map +1 -0
- package/dist/tui/config-wizard/step-mcp.js +97 -0
- package/dist/tui/config-wizard/step-mcp.js.map +1 -0
- package/dist/tui/config-wizard/step-menu.d.ts +4 -0
- package/dist/tui/config-wizard/step-menu.d.ts.map +1 -0
- package/dist/tui/config-wizard/step-menu.js +28 -0
- package/dist/tui/config-wizard/step-menu.js.map +1 -0
- package/dist/tui/config-wizard/step-models.d.ts +4 -0
- package/dist/tui/config-wizard/step-models.d.ts.map +1 -0
- package/dist/tui/config-wizard/step-models.js +114 -0
- package/dist/tui/config-wizard/step-models.js.map +1 -0
- package/dist/tui/config-wizard/step-new-endpoint.d.ts +4 -0
- package/dist/tui/config-wizard/step-new-endpoint.d.ts.map +1 -0
- package/dist/tui/config-wizard/step-new-endpoint.js +54 -0
- package/dist/tui/config-wizard/step-new-endpoint.js.map +1 -0
- package/dist/tui/config-wizard/step-simple.d.ts +4 -0
- package/dist/tui/config-wizard/step-simple.d.ts.map +1 -0
- package/dist/tui/config-wizard/step-simple.js +55 -0
- package/dist/tui/config-wizard/step-simple.js.map +1 -0
- package/dist/tui/config-wizard/types.d.ts +147 -0
- package/dist/tui/config-wizard/types.d.ts.map +1 -0
- package/dist/tui/config-wizard/types.js +12 -0
- package/dist/tui/config-wizard/types.js.map +1 -0
- package/dist/tui/config-wizard/wizard.d.ts +9 -0
- package/dist/tui/config-wizard/wizard.d.ts.map +1 -0
- package/dist/tui/config-wizard/wizard.js +34 -0
- package/dist/tui/config-wizard/wizard.js.map +1 -0
- package/dist/tui/highlight.d.ts +35 -0
- package/dist/tui/highlight.d.ts.map +1 -0
- package/dist/tui/highlight.js +117 -0
- package/dist/tui/highlight.js.map +1 -0
- package/dist/tui/index.d.ts +34 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +265 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/tui/screens/chat-commands.d.ts +35 -0
- package/dist/tui/screens/chat-commands.d.ts.map +1 -0
- package/dist/tui/screens/chat-commands.js +214 -0
- package/dist/tui/screens/chat-commands.js.map +1 -0
- package/dist/tui/screens/chat.d.ts +21 -0
- package/dist/tui/screens/chat.d.ts.map +1 -0
- package/dist/tui/screens/chat.js +563 -0
- package/dist/tui/screens/chat.js.map +1 -0
- package/dist/tui/screens/frame-buffer.d.ts +47 -0
- package/dist/tui/screens/frame-buffer.d.ts.map +1 -0
- package/dist/tui/screens/frame-buffer.js +78 -0
- package/dist/tui/screens/frame-buffer.js.map +1 -0
- package/dist/tui/screens/index.d.ts +13 -0
- package/dist/tui/screens/index.d.ts.map +1 -0
- package/dist/tui/screens/index.js +14 -0
- package/dist/tui/screens/index.js.map +1 -0
- package/dist/tui/screens/input.d.ts +29 -0
- package/dist/tui/screens/input.d.ts.map +1 -0
- package/dist/tui/screens/input.js +54 -0
- package/dist/tui/screens/input.js.map +1 -0
- package/dist/tui/screens/layout.d.ts +44 -0
- package/dist/tui/screens/layout.d.ts.map +1 -0
- package/dist/tui/screens/layout.js +40 -0
- package/dist/tui/screens/layout.js.map +1 -0
- package/dist/tui/screens/lines.d.ts +42 -0
- package/dist/tui/screens/lines.d.ts.map +1 -0
- package/dist/tui/screens/lines.js +190 -0
- package/dist/tui/screens/lines.js.map +1 -0
- package/dist/tui/screens/messages-view.d.ts +10 -0
- package/dist/tui/screens/messages-view.d.ts.map +1 -0
- package/dist/tui/screens/messages-view.js +115 -0
- package/dist/tui/screens/messages-view.js.map +1 -0
- package/dist/tui/screens/notice.d.ts +32 -0
- package/dist/tui/screens/notice.d.ts.map +1 -0
- package/dist/tui/screens/notice.js +46 -0
- package/dist/tui/screens/notice.js.map +1 -0
- package/dist/tui/screens/overlays.d.ts +12 -0
- package/dist/tui/screens/overlays.d.ts.map +1 -0
- package/dist/tui/screens/overlays.js +34 -0
- package/dist/tui/screens/overlays.js.map +1 -0
- package/dist/tui/screens/render.d.ts +7 -0
- package/dist/tui/screens/render.d.ts.map +1 -0
- package/dist/tui/screens/render.js +61 -0
- package/dist/tui/screens/render.js.map +1 -0
- package/dist/tui/screens/splash.d.ts +5 -0
- package/dist/tui/screens/splash.d.ts.map +1 -0
- package/dist/tui/screens/splash.js +51 -0
- package/dist/tui/screens/splash.js.map +1 -0
- package/dist/tui/text.d.ts +76 -0
- package/dist/tui/text.d.ts.map +1 -0
- package/dist/tui/text.js +198 -0
- package/dist/tui/text.js.map +1 -0
- package/dist/tui/theme.d.ts +68 -0
- package/dist/tui/theme.d.ts.map +1 -0
- package/dist/tui/theme.js +132 -0
- package/dist/tui/theme.js.map +1 -0
- package/dist/types.d.ts +7 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/package.json +12 -7
- package/dist/auto-migrate-confirm-plugin.d.ts +0 -58
- package/dist/auto-migrate-confirm-plugin.d.ts.map +0 -1
- package/dist/auto-migrate-confirm-plugin.js +0 -79
- package/dist/auto-migrate-confirm-plugin.js.map +0 -1
- package/dist/config-wizard.d.ts +0 -6
- package/dist/config-wizard.d.ts.map +0 -1
- package/dist/config-wizard.js +0 -46
- package/dist/config-wizard.js.map +0 -1
- package/dist/conversation-commands/back.d.ts +0 -3
- package/dist/conversation-commands/back.d.ts.map +0 -1
- package/dist/conversation-commands/back.js +0 -144
- package/dist/conversation-commands/back.js.map +0 -1
- package/dist/conversation-commands/clear.d.ts +0 -3
- package/dist/conversation-commands/clear.d.ts.map +0 -1
- package/dist/conversation-commands/clear.js +0 -8
- package/dist/conversation-commands/clear.js.map +0 -1
- package/dist/conversation-commands/editor.d.ts +0 -3
- package/dist/conversation-commands/editor.d.ts.map +0 -1
- package/dist/conversation-commands/editor.js +0 -15
- package/dist/conversation-commands/editor.js.map +0 -1
- package/dist/conversation-commands/exit.d.ts +0 -3
- package/dist/conversation-commands/exit.d.ts.map +0 -1
- package/dist/conversation-commands/exit.js +0 -37
- package/dist/conversation-commands/exit.js.map +0 -1
- package/dist/conversation-commands/help.d.ts +0 -3
- package/dist/conversation-commands/help.d.ts.map +0 -1
- package/dist/conversation-commands/help.js +0 -10
- package/dist/conversation-commands/help.js.map +0 -1
- package/dist/conversation-commands/index.d.ts +0 -13
- package/dist/conversation-commands/index.d.ts.map +0 -1
- package/dist/conversation-commands/index.js +0 -66
- package/dist/conversation-commands/index.js.map +0 -1
- package/dist/conversation-commands/migrate.d.ts +0 -12
- package/dist/conversation-commands/migrate.d.ts.map +0 -1
- package/dist/conversation-commands/migrate.js +0 -56
- package/dist/conversation-commands/migrate.js.map +0 -1
- package/dist/conversation-commands/new.d.ts +0 -3
- package/dist/conversation-commands/new.d.ts.map +0 -1
- package/dist/conversation-commands/new.js +0 -45
- package/dist/conversation-commands/new.js.map +0 -1
- package/dist/conversation-commands/save.d.ts +0 -3
- package/dist/conversation-commands/save.d.ts.map +0 -1
- package/dist/conversation-commands/save.js +0 -32
- package/dist/conversation-commands/save.js.map +0 -1
- package/dist/conversation-runner.d.ts +0 -17
- package/dist/conversation-runner.d.ts.map +0 -1
- package/dist/conversation-runner.js +0 -176
- package/dist/conversation-runner.js.map +0 -1
- package/dist/delta-renderer.d.ts +0 -33
- package/dist/delta-renderer.d.ts.map +0 -1
- package/dist/delta-renderer.js +0 -120
- package/dist/delta-renderer.js.map +0 -1
- package/dist/draft-plugin.d.ts +0 -19
- package/dist/draft-plugin.d.ts.map +0 -1
- package/dist/draft-plugin.js +0 -30
- package/dist/draft-plugin.js.map +0 -1
- package/dist/draft-repository.d.ts +0 -34
- package/dist/draft-repository.d.ts.map +0 -1
- package/dist/draft-repository.js +0 -64
- package/dist/draft-repository.js.map +0 -1
- package/dist/menus/agents.d.ts +0 -5
- package/dist/menus/agents.d.ts.map +0 -1
- package/dist/menus/agents.js +0 -219
- package/dist/menus/agents.js.map +0 -1
- package/dist/menus/common.d.ts +0 -41
- package/dist/menus/common.d.ts.map +0 -1
- package/dist/menus/common.js +0 -104
- package/dist/menus/common.js.map +0 -1
- package/dist/menus/config-display.d.ts +0 -2
- package/dist/menus/config-display.d.ts.map +0 -1
- package/dist/menus/config-display.js +0 -82
- package/dist/menus/config-display.js.map +0 -1
- package/dist/menus/config.d.ts +0 -8
- package/dist/menus/config.d.ts.map +0 -1
- package/dist/menus/config.js +0 -407
- package/dist/menus/config.js.map +0 -1
- package/dist/menus/conversations.d.ts +0 -20
- package/dist/menus/conversations.d.ts.map +0 -1
- package/dist/menus/conversations.js +0 -83
- package/dist/menus/conversations.js.map +0 -1
- package/dist/menus/index.d.ts +0 -5
- package/dist/menus/index.d.ts.map +0 -1
- package/dist/menus/index.js +0 -59
- package/dist/menus/index.js.map +0 -1
- package/dist/menus/start-conversation.d.ts +0 -16
- package/dist/menus/start-conversation.d.ts.map +0 -1
- package/dist/menus/start-conversation.js +0 -176
- package/dist/menus/start-conversation.js.map +0 -1
- package/dist/migration-service.d.ts +0 -13
- package/dist/migration-service.d.ts.map +0 -1
- package/dist/migration-service.js +0 -56
- package/dist/migration-service.js.map +0 -1
- package/dist/slash-hint-prompt.d.ts +0 -41
- package/dist/slash-hint-prompt.d.ts.map +0 -1
- package/dist/slash-hint-prompt.js +0 -92
- package/dist/slash-hint-prompt.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,202 @@
|
|
|
1
|
-
|
|
1
|
+
## [1.0.0-alpha.10] - 2026-10-20
|
|
2
|
+
|
|
3
|
+
### 💥 变更
|
|
4
|
+
|
|
5
|
+
- **交接与迁移拆成两条命令**(语义唯一,命名与实现对齐):
|
|
6
|
+
- **`/handoff`** —— 原 agent 停手、核实状态、把交接文档写到 `<项目>/.ai-zen/handoffs/`,**会话照旧**(不弹确认,可反复执行;交接回合留在 `agent.messages` 里,可继续要求细化同一份文档);
|
|
7
|
+
- **`/migrate`**(别名 `/migration`)—— 同一次交接 + 清历史 + 开新会话(需确认)。
|
|
8
|
+
- 两条都支持 `self` / `summary` 参数(如 `/handoff summary`、`/migrate self`)跳过默认选择。
|
|
9
|
+
- **自动迁移改为「执行者三选一」选择器**:上下文超阈值时不再只问「是否迁移」,而是选择 **原 agent 自交接(默认高亮,保真)/ 独立摘要(便宜)/ 跳过本次**。选择器复用既有 picker 浮层(`setPickerState`)。非交互环境(管道、重定向、e2e)无选择通道,按默认执行者迁移,不阻塞、不额外输出。
|
|
10
|
+
- **交接文档目录**:新增 `PROJECT_HANDOFFS_DIR = <cwd>/.ai-zen/handoffs`,交接文档落在项目内,可随仓库共享/评审。
|
|
11
|
+
|
|
12
|
+
### ♻️ 重构
|
|
13
|
+
|
|
14
|
+
- **`src/migration-service.ts` → `src/handoff-service.ts`**:`createMigrationService` → `createHandoffService`,钩子从 `onBeforeMigrate` / `onMigrated` 改为 `onBeforeHandoff` / `onHandoff` / `onMigrated`。存档旧会话移到 `onHandoff`(此时已包含交接回合,归档可审计);`/handoff` 不切换会话也因此不需要额外存档(`ConversationPersistPlugin` 每轮已落盘)。
|
|
15
|
+
- **`src/auto-migrate-confirm-plugin.ts` → `src/auto-migrate-confirm.ts`**:`AutoMigrateConfirmPlugin`(继承 + 重写 `onAfterSend`)退化为 `createAutoMigratePlugin()` 工厂——「何时迁移」仍在 SDK 插件里,「用谁交接」通过 SDK 新增的 `resolveMode` 回调注入,不再重复实现阈值判断。
|
|
16
|
+
- `src/agent-creator.ts` 抽出并导出 `listSkillDirs()`:Scope 装配与交接服务(读取 `handoff` Skill 正文)共用同一份目录优先级,避免两处各算一遍。
|
|
17
|
+
- `ChatSessionOptions.requestConfirm` → `requestMode`(返回 `HandoffMode | null`);`ChatSession.migrate()` / `handoff()` 返回文档路径;`ConversationContext.migrationService` → `handoffService`。
|
|
18
|
+
- `ContextGuardPlugin` 接线 `isSuspended: () => handoffService.busy`:交接回合护栏从 `× 1.5` 放宽到 `× 2`。
|
|
19
|
+
- 斜杠命令解析支持参数:命令名取首个 token(`/migrate summary` 不再被当成未知命令)。
|
|
20
|
+
|
|
21
|
+
### ⚠️ 依赖
|
|
22
|
+
|
|
23
|
+
- `@ai-zen/agents-sdk` `1.0.0-alpha.9 → 1.0.0-alpha.10`(`TaskMigrationService` → `HandoffService` 为破坏性变更)。
|
|
24
|
+
|
|
25
|
+
### ✅ 测试
|
|
26
|
+
|
|
27
|
+
- 新增 `src/handoff-service.test.ts`(迁移清 `lastUsage` / 新会话落盘 / `/handoff` 不切会话)、`src/auto-migrate-confirm.test.ts`(非交互默认值、选择透传、取消跳过、busy 让行)。全量 **17 文件 / 229 用例**通过,`tsc --noEmit`(含测试工程)与 `build` 零错误。
|
|
28
|
+
|
|
29
|
+
### 📄 文档
|
|
30
|
+
|
|
31
|
+
- `docs/{en,zh}/migration.md` 重写为「任务交接与迁移」:两条命令的差异、两种执行者的取舍、自交接的代码级保障(守卫/放宽/防递归)、文档位置与命名、模板由 `handoff` Skill 承载(`metadata.custom: "true"` 退出同步、可项目级覆盖)、成本说明。网站镜像同步。
|
|
32
|
+
- `README.md` / `README.zh.md` 命令表与「任务交接与迁移」章节、`docs/{en,zh}/index.md` 特性与导航同步。
|
|
33
|
+
|
|
34
|
+
## [1.0.0-alpha.9] - 2026-10-14
|
|
35
|
+
|
|
36
|
+
### 🔧 修复
|
|
37
|
+
|
|
38
|
+
- **自动迁移与 CLI 的交互适配(两处)**:
|
|
39
|
+
- **迁移期间输入框未真正拦住** —— 主输入 `useInput` 的 `isActive` 此前只挡「确认框 / 选择器 / 配置向导」,未挡「生成中」态。自动迁移在 `send()` 内 `await onAfterSend` 执行(`busy` 为真、输入框已被 Spinner 顶替),但按键仍会被静默吞进隐藏的输入缓冲、待本轮结束才浮现。现令主输入在 `busy` 时整体失活,另设「忙碌期」处理器仅放行 `Ctrl+C` 中止 / `Ctrl+D` 退出 / `PgUp`·`Shift+↑↓` 回看;`/migrate` 手动迁移同样纳入 `busy`。
|
|
40
|
+
- **迁移完成后仍被总上下文护栏拦截** —— 迁移(prune)会物理重置上下文,却遗留 `agent.lastUsage`(迁移前那一次请求的 `prompt_tokens`)。`ContextGuardPlugin`(`onInnerLoopStart`,硬上限 `maxTokens × 1.5`)据此误判,迁移后第一条消息即被 `ContextOverflowError` 中断。现于迁移后清空 `agent.lastUsage`,护栏首轮无据可查而放行,待下一次响应以真实用量回填。
|
|
41
|
+
|
|
42
|
+
### ✅ 测试
|
|
43
|
+
|
|
44
|
+
- 新增 `src/migration-service.test.ts`:断言迁移后 `agent.lastUsage` 被清空(移除修复后该用例确会失败)。全量单测 **17 文件 / 227 用例**通过,`tsc --noEmit` 与 `pnpm build` 零错误。
|
|
45
|
+
|
|
46
|
+
## [1.0.0-alpha.8] - 2026-10-14
|
|
47
|
+
|
|
48
|
+
### 🔧 修复
|
|
49
|
+
|
|
50
|
+
- **修复长时间 TUI 会话内存无界增长导致的 OOM(崩溃)** —— CLI 入口此前从未设定 `NODE_ENV`,React 因而按 `process.env.NODE_ENV !== "production"` 载入 **development** 版 `react-reconciler`;该开发构建每次渲染都会调用 `performance.measure()`(User Timing API),而 Node 的 performance 条目缓冲**无上限、从不逐出**,长时间流式会话下条目持续累积,约 55 分钟即将堆顶到 `heap_size_limit`(本机 ~1GB)触发 OOM。现于 `src/index.ts` 顶部设 `process.env.NODE_ENV ||= "production"`;因 ESM 静态 `import` 会被提升到模块体之前执行,对 TUI 入口 `./tui/index.js` 改用动态 `import()`,确保 React/Ink 在 `NODE_ENV` 设定**之后**才被求值,从而加载 production 版 reconciler(该版不调用 `performance.measure`)。显式 `NODE_ENV=development` 仍保留开发构建,便于排查。
|
|
51
|
+
|
|
52
|
+
### ✅ 测试
|
|
53
|
+
|
|
54
|
+
- **端到端实证** —— 真实 ESM 下经入口加载 Ink 并连续重渲染 300 次:修复后 `performance.measure` 条目 **0 → 0**(production reconciler),显式 `NODE_ENV=development` 对照组 **0 → 905**(dev 埋点仍在)。全量单测 **16 文件 / 226 用例**通过,`tsc --noEmit` 与 `pnpm build` 零错误。
|
|
55
|
+
|
|
56
|
+
## [1.0.0-alpha.7] - 2026-10-14
|
|
57
|
+
|
|
58
|
+
### 📄 文档
|
|
59
|
+
|
|
60
|
+
- **状态栏 token 用量纳入文档** —— `docs/zh|en/index.md` 的「主要特性」补上「状态栏实时展示 模型 · Agent · 本轮/累计 token 用量 · 生成状态」(此前仅在 README 提及),累计口径为 `sumUsage(agent.messages)`(含所有层级的子 Agent)。
|
|
61
|
+
- 修正 `TODO.md` 中已过时的路径引用(`src/tui/config-wizard.tsx` → 目录 `src/tui/config-wizard/`)。
|
|
62
|
+
|
|
63
|
+
### ⚠️ 依赖
|
|
64
|
+
|
|
65
|
+
- `@ai-zen/agents-core` `^4.5.0 → ^4.5.1`、`@ai-zen/agents-sdk` `1.0.0-alpha.8 → 1.0.0-alpha.9`
|
|
66
|
+
|
|
67
|
+
> 纯文档修正,无代码变更。
|
|
68
|
+
|
|
69
|
+
## [1.0.0-alpha.6] - 2026-10-14
|
|
70
|
+
|
|
71
|
+
### ♻️ 重构
|
|
72
|
+
|
|
73
|
+
- **累计用量改用 SDK 的 `sumUsage`,移除 CLI 自建的内存累加器** —— 依赖 `@ai-zen/agents-sdk` `1.0.0-alpha.8` / `@ai-zen/agents-core` `4.5.0`:除助手消息的 `usage` 外,委派产生的用量现由 core 在委派边界钉到工具消息的 `subAgentUsage` 上。故 `ChatSession.totalUsage` 直接 `sumUsage(agent.messages)` 即可(含所有层级的子 Agent),删掉 `src/usage.ts` 与 `onSubAgentEnd` 内存回灌——子 Agent 开销随消息持久化,续接 / `/load` 亦不丢,且不再有双重计数风险。
|
|
74
|
+
|
|
75
|
+
### ⚠️ 依赖
|
|
76
|
+
|
|
77
|
+
- `@ai-zen/agents-sdk` `1.0.0-alpha.7 → 1.0.0-alpha.8`、`@ai-zen/agents-core` `^4.4.0 → ^4.5.0`
|
|
78
|
+
|
|
79
|
+
### ✅ 测试
|
|
80
|
+
|
|
81
|
+
- 移除 `src/usage.test.ts`(逻辑下沉 core,已由 core 覆盖);`chat-session.test.ts` 的 `totalUsage` 用例改为覆盖「assistant 的 usage + 工具消息的 subAgentUsage」求和。全量单测 **16 文件 / 226 用例**通过,`tsc --noEmit` 与 `npm run build` 零错误。
|
|
82
|
+
|
|
83
|
+
## [1.0.0-alpha.5] - 2026-10-14
|
|
84
|
+
|
|
85
|
+
### 🚀 新功能
|
|
86
|
+
|
|
87
|
+
- **状态栏展示 token 累计消耗** —— 依托 `@ai-zen/agents-sdk` `1.0.0-alpha.7` / `@ai-zen/agents-core` `4.4.0` 为每条 assistant 消息钉上的 `usage`,新增 `src/usage.ts`(`addUsage` / `sumMessagesUsage` 纯函数)与 `ChatSession.totalUsage`:对本会话全部 assistant 消息的 `usage` 求和即计费口径的累计消耗;子 Agent 的 messages 不在父 Agent 中,故在 `onSubAgentEnd` 单独累加并入、`/new` 时归零。状态栏由「`{tokens} tok`」升级为「`本轮 x · 累计 y tok`」(本轮 = `lastUsage.total_tokens`,累计 = `totalUsage.total_tokens`)。
|
|
88
|
+
- **依赖升级** —— `@ai-zen/agents-sdk` `1.0.0-alpha.6 → 1.0.0-alpha.7`、`@ai-zen/agents-core` `^4.3.2 → ^4.4.0`(后者新增 `AgentNS.Message.usage` 逐条 token 用量)。
|
|
89
|
+
|
|
90
|
+
### ✅ 测试
|
|
91
|
+
|
|
92
|
+
- 新增 `src/usage.test.ts`(4 例);`chat-session.test.ts` 增补 `totalUsage` 求和用例;`screens.test.tsx` 的 `StatusBar` 用例更新。全量单测 **17 文件 / 230 用例**通过,`tsc --noEmit` 与 `npm run build` 零错误。
|
|
93
|
+
|
|
94
|
+
## [1.0.0-alpha.4] - 2026-10-13
|
|
95
|
+
|
|
96
|
+
### ♻️ 重构
|
|
97
|
+
|
|
98
|
+
- **TUI 渲染直接以 `agent.messages` 为唯一数据源** —— 移除 `ChatEvent` / `chatReducer` / `LiveAssistant` / `Block` / `messagesToBlocks` 等自定义中间模型。SDK 在流式期间会**实时更新 `agent.messages`**(`Agent.parseStreamData` 把每个 delta 增量写进当前那条 message),因此跨消息顺序(数组序)与单条 assistant 内部顺序(`思考 → 工具 → 正文`)天然保持,直接渲染即可,杜绝「第二套真相」的失真与维护负担。已完成消息的折行 / 高亮按「消息 + 列宽 + 内容签名」缓存(`cachedMessageToLines`),流式中那条靠内容签名自动失效。
|
|
99
|
+
- **notice / error 改为独立栏位** —— 系统级提示(命令反馈 / 迁移进度 / 报错)不再混入对话转录,也**绝不写进 `agent.messages`**(那会被 `formatHistory()` 原样发给模型、污染上下文);改在输入框上方的独立一行渲染(`src/tui/screens/notice.ts`)。
|
|
100
|
+
|
|
101
|
+
### 🎯 优化
|
|
102
|
+
|
|
103
|
+
- **流式增量渲染**:Ink 开启 `incrementalRendering` —— 从「每帧 erase 整屏 + 重写整屏」(`createStandard`)切到「只重绘变化的行」(`createIncremental`),每帧输出量由 O(屏幕大小) 降到 O(变化量),SSH / 弱网下流式更稳。
|
|
104
|
+
- **流式合帧**(`src/tui/screens/frame-buffer.ts`):内容变更先攒入缓冲,按 60ms(约 16fps,低于 Ink 默认 30fps 输出节流)批量触发重渲染,把上屏频率从「每个 delta 一次」降到固定帧率。
|
|
105
|
+
- **渲染缓存**:长对话下历史消息的折行 / 高亮免于每帧重算,成本不再随对话增长而恶化。
|
|
106
|
+
- **思考与工具调用之间补一个空行**,排版更清晰。
|
|
107
|
+
|
|
108
|
+
### ✅ 测试
|
|
109
|
+
|
|
110
|
+
- 新增 `frame-buffer.test.ts`、`notice.test.ts`;`screens.test.tsx` 重写为基于 `messageToLines` / `transcriptLines` / `computeChatLayout(transcript)`。
|
|
111
|
+
- `tsc` 零错误;全量单测 **16 文件 / 225 用例**通过;`npm run build` 通过。
|
|
112
|
+
- 真机(pty)验证:SSH / 弱网下流式稳定,长对话滚动流畅。
|
|
113
|
+
|
|
114
|
+
## [1.0.0-alpha.3] - 2026-10-13
|
|
115
|
+
|
|
116
|
+
### 💥 破坏性变更
|
|
117
|
+
|
|
118
|
+
- **内置工具改名(统一 `snake_case`:多词收敛、单词简化)** —— 随 `@ai-zen/agents-sdk` `1.0.0-alpha.6` 落地:SDK 将内置工具名统一为 `snake_case`,并把单词工具简化为单词 —— `readFile` → `read`、`writeFile` → `write`、`exec_async` → `spawn`、`findText` → `find_text`、`batchEdit` → `batch_edit`、`inspectFile` → `inspect_file`、`downloadFile` → `download_file`、`generateImage` → `generate_image`、`viewImage` → `view_image`、`indexedSearch` → `indexed_search`;工具类名同步为 `ReadTool` / `WriteTool` / `SpawnTool`。**若你在 Agent 定义、权限白名单(`tools.allow` / `tools.deny`)或自定义提示词里引用了旧工具名,请同步更新为 `snake_case` 新名**(旧名仅保留在 CHANGELOG 历史条目中)。
|
|
119
|
+
|
|
120
|
+
### 🚀 新功能
|
|
121
|
+
|
|
122
|
+
- **正文 / 思考按 Markdown 源码着色** —— AI 回答本身即 Markdown,现交给 `highlight.js` 的 `markdown` 词法着色:标题(`#`)、粗体、斜体、行内代码、列表、引用、链接各有配色;**围栏代码块保留围栏行**(开 / 闭围栏以低调暗灰渲染)并继续按标注语言做语法高亮。标记符(`#` / `**` / 反引号 等)**原样保留、只染色**(源码着色,非语义渲染)。正文用**空格优先折行**,避免把英文单词从中间切断。
|
|
123
|
+
|
|
124
|
+
### 🎯 优化
|
|
125
|
+
|
|
126
|
+
- **正文默认文本色改用终端默认前景色** —— 此前正文基础色写死近白 `#e2e8f0`,在**亮色主题终端**里会「白底白字」看不见。现正文(含未指定颜色的默认分段)一律回落**终端默认前景色**,绝对色只留给标题 / 代码等强调项;同步移除语法色板里两处近白 token 色(`variable` / `params`)。
|
|
127
|
+
|
|
128
|
+
### ⚠️ 依赖升级
|
|
129
|
+
|
|
130
|
+
- **`@ai-zen/agents-core` 升至 `^4.3.2`、`@ai-zen/agents-sdk` 升至 `1.0.0-alpha.6`** ——
|
|
131
|
+
- core `4.3.1`:**中断的并行工具轮次归一化** —— 一轮回复里并行调用的多个工具若被中断(`Ctrl+C`),未完成的工具结果会在历史里被补齐 / 归一,避免下一轮因 `tool_calls` 数量与实际工具结果数量不匹配而被服务端拒绝(默认 `fill`:保留 assistant 正文并补齐未完成结果)。
|
|
132
|
+
- core `4.3.2` / sdk `1.0.0-alpha.4…6`:内置工具统一 `snake_case` + 单词简化、`exec_async` → `spawn`、类名对齐(见「破坏性变更」)。
|
|
133
|
+
- CLI 侧仅同步工具名(文档 / 测试 fixture / 提示语),运行时行为全量委托 SDK,无需其它适配。
|
|
134
|
+
|
|
135
|
+
### ✅ 测试
|
|
136
|
+
|
|
137
|
+
- `tsc --noEmit`(`tsconfig.test.json`)零错误;全量单测 **15 文件 / 235 用例**通过
|
|
138
|
+
- 修复 `config-wizard.test.tsx` 两个预存失败:为向导注入终端尺寸(新增可选 `terminalSize` prop),消除 `ink-testing-library` 假 stdout 缺 `rows` 时 `terminal-size` 探测本机行数、把吸底帧撑到 38 行的干扰
|
|
139
|
+
- 渲染核验:标题 / 粗体 / 行内代码 / 列表 / 引用 / 链接与围栏代码块均按预期着色,普通正文无颜色(回落终端默认)
|
|
140
|
+
|
|
141
|
+
## [1.0.0-alpha.2] - 2026-10-03
|
|
142
|
+
|
|
143
|
+
### ⚠️ 依赖升级
|
|
144
|
+
|
|
145
|
+
- **`@ai-zen/agents-sdk` 升至 `1.0.0-alpha.3`** — 拉取 SDK 对内置工具 `generateImage` 参数描述的修正。原描述写着「配置中的图片模型可通过 `aiz config show` 查看」,等于**指路让模型去执行宿主 CLI 命令**;而**工具描述会随每次请求的 `tools` 字段进入每一层 agent 的上下文**——模型据此 `exec("aiz config show")`,CLI 又把这条命令解析为**纯 stdio 模式**、以 `config show` 为提示词**再拉起一个 agent**,其工具描述里又是同一句指引,遂形成**自指型递归**(每层都真连 API,越套越深)。SDK 现已把该描述改为「若指定的模型不存在,本工具会返回当前可用的模型列表」,与 `call()` 的实际行为一致,且不再引导模型去执行宿主 CLI。该版本**无破坏性变更**,CLI 源码无需适配(类型 / 默认配置全量委托 SDK,版本横幅由实际安装版本读取,工具清单由 SDK 静态注册表自动发现)。
|
|
146
|
+
|
|
147
|
+
### 📝 文档
|
|
148
|
+
|
|
149
|
+
- `docs/zh|en/getting-started.md`:运行时依赖版本同步为 `@ai-zen/agents-sdk` `1.0.0-alpha.3`
|
|
150
|
+
- `docs/manifest.json`:版本号同步为 `1.0.0-alpha.2`
|
|
151
|
+
- 中英 README 启动横幅示例版本同步为 `v1.0.0-alpha.2`
|
|
152
|
+
|
|
153
|
+
### ✅ 测试
|
|
154
|
+
|
|
155
|
+
- `tsc --noEmit`(`tsconfig.test.json`)与 `npm run build` 零错误
|
|
156
|
+
- 全量单测 13 文件 / 224 用例通过
|
|
157
|
+
|
|
158
|
+
## [1.0.0-alpha.1] - 2026-09-30
|
|
159
|
+
|
|
160
|
+
> 本版本汇总**相对上一发布版本 `0.9.0`** 的全部变化。
|
|
161
|
+
|
|
162
|
+
### 💥 破坏性变更
|
|
163
|
+
|
|
164
|
+
- **启动命令由 `aiz` / `zen` 改为 `ai`** —— `package.json` 的 `bin` 改为 `{ "ai", "aiz", "zen" }`;`aiz` / `zen` 作为**过渡别名**保留,未来版本移除。
|
|
165
|
+
- **引入双模式运行,两种模式互不混合** —— 带位置参数、或 stdin/stdout 非 TTY(管道 / 重定向 / CI)时启用**纯 stdio 模式**:无任何额外交互,最终 assistant 文本以纯文本写入 `stdout`(零 ANSI / emoji 前缀 / spinner),日志、进度、工具过程与错误摘要一律走 `stderr`,成功退出码 `0`、失败非 `0`、默认不落盘;仅在**无参数且 stdin/stdout 均为 TTY** 时进入 **TUI 模式**。
|
|
166
|
+
- **交互界面整体重写为 Ink(React)全屏 TUI** —— 取代原 inquirer 行式对话;随之**移除主菜单**(`/menu` 与 `src/menus/*`)以及 `inquirer` / `@types/inquirer` / `chalk` 依赖。
|
|
167
|
+
|
|
168
|
+
### ✨ 新增
|
|
169
|
+
|
|
170
|
+
- **TUI 全屏交互界面(Ink + React)**:
|
|
171
|
+
- 动画渐变 ASCII 启动界面,结束后直接进入对话(有上一轮会话则自动续接);
|
|
172
|
+
- 对话区**吸底**(分隔线 / 输入行 / 状态栏固定底部,整帧高度恒为「终端行数 − 1」以避开 Ink 全屏分支);
|
|
173
|
+
- 流式输出(思考 / 正文 / 工具调用分行)、历史按行裁剪自底滚动;
|
|
174
|
+
- **多行输入**(`Enter` 发送、`Ctrl+N` / `Ctrl+J` 换行)与**光标编辑**(`←`/`→`/`Home`/`End`/`Backspace`/`Delete`,`Ctrl`/`Meta` + `←`/`→` 跨词,反显光标 + 硬件光标同步);
|
|
175
|
+
- **应用内翻页**(`PgUp`/`PgDn` 翻页、`Shift`/`Alt` + `↑`/`↓` 单行滚动、发送自动回底);
|
|
176
|
+
- 输入历史、内联 `/` 命令菜单、状态栏、确认框。
|
|
177
|
+
- **语法高亮**:工具调用参数按 **JSON** 高亮、正文与思考里的**围栏代码块**按语言高亮。高亮**数据**委托 `highlight.js`(经 `lowlight` 产出 hast),CLI 仅把 `hljs-*` scope 映射为 Ink `<Text>` 颜色 —— 与同为 Ink/React 的 Google Gemini CLI 做法一致。
|
|
178
|
+
- **对话内命令**:`/help`、`/load`、`/clear`、`/new`、`/save`、`/config`、`/key`、`/migrate`、`/back`、`/editor`、`/exit`(`registry.ts` 为命令清单唯一来源,`/help` 与输入补全自动同步)。
|
|
179
|
+
- **首启凭据引导 + 配置中心(Ink 原生)**:端点缺 API Key 时先弹凭据设置屏;`/config` 配置中心管理端点、模型、图片模型、默认项(默认模型 / 图片模型 / Agent / 迁移模型)、工具输出上限、**MCP 服务器**(全局 / 项目作用域)与 **Agent 定义**(顶层 Agent + Sub-agent,含四维权限);编辑「出厂托管」条目自动转 `custom: true`,危险操作二次确认并做引用守卫。
|
|
180
|
+
- **多行文本走系统编辑器**:Agent 提示词、Sub-agent 函数说明 / 参数 schema 等多行字段按 `Enter` 调起 `$EDITOR`(Windows 默认 `notepad`);参数 schema 以 `.json` 打开并即时校验。
|
|
181
|
+
- **会话持久化改革:会话即文件 + 单指针** —— 每轮结束落盘、`cli/last-session.json` 记录上一轮会话 id、首条消息后才落盘、`/save` 幂等;继续 / 加载时按消息重建历史。
|
|
182
|
+
- **纯 stdio 模式配套**:`ai --help` / `-h`、`ai --version` / `-v`、`ai --save`;SDK 日志与 `console.log` 统一改道 `stderr` 以保证 stdout 纯净。
|
|
183
|
+
- **IME 候选框跟随光标**:用 Ink `useCursor()` 把硬件光标同步到编辑光标,中文输入法候选框正确定位。
|
|
184
|
+
|
|
185
|
+
### 🔧 变更
|
|
186
|
+
|
|
187
|
+
- **依赖**:新增 `ink` / `react`(运行时)、`ink-testing-library` / `@types/react`(开发);新增语法高亮 `highlight.js` / `lowlight`(运行时)与 `@types/hast`(开发);**移除** `inquirer` / `@types/inquirer` / `chalk`。
|
|
188
|
+
- **升级 `@ai-zen/agents-sdk`**:`1.0.0-alpha.0` → `1.0.0-alpha.1` → `1.0.0-alpha.2`(出厂模型目录刷新、模型清单托管、默认 `mcp.json` 增补 `chrome-devtools` 等;CLI 侧代码零改动)。
|
|
189
|
+
- **TUI 输出统一走 Ink**:迁移进度、会话落盘失败等提示不再 `console.log` / `console.warn` 直写终端(会撕裂 Ink 帧),改为经回调渲染为 notice 块;启动 Logo 渐变也改为 Ink 逐字符 `<Text color>`。
|
|
190
|
+
- **配置向导 / 覆盖层统一「吸底」布局**,列表项与键位提示裁成**严格单行**,修复 VS Code 终端里内容被裁切的问题。
|
|
191
|
+
- **终端状态安全与干净退出**:`SIGINT` / `SIGTERM` / 未捕获异常均卸载 Ink、恢复 raw mode 与光标;`Ctrl+C` 语义为「忙时取消本轮、空闲时退出」;退出显式暂停 stdin 并终止进程(`farewell()`)。
|
|
192
|
+
- **移除旧行式链路(死代码)**:`src/conversation-runner.ts`、`src/slash-hint-prompt.ts`、`src/delta-renderer.ts`、inquirer 版 `src/config-wizard.ts`、`src/draft-*.ts` 等;新增 `src/mode.ts` / `src/stdio-runner.ts` / `src/session-pointer.ts` / `src/conversation-persist-plugin.ts` / `src/config-editor.ts` 与 `src/tui/*` 新实现。
|
|
193
|
+
- 文档:中英 README 与 `docs/zh|en/*` 同步(运行模式、`ai` 命令名、配置中心、多行编辑器等),`docs/manifest.json` 同步。
|
|
194
|
+
|
|
195
|
+
### ✅ 测试
|
|
196
|
+
|
|
197
|
+
- 全量单测 **13 文件 / 224 例**,`tsc --noEmit` 与 `npm run build` 零错误;e2e **12 例**真连 DeepSeek API(覆盖双模式、stdio 纯净性、退出码、`--save` 落盘)。
|
|
198
|
+
- 新增测试文件:`mode.test.ts`、`stdio-runner.test.ts`、`theme.test.ts`、`screens.test.tsx`、`tui/config-wizard.test.tsx`、`tui/agent-prompt.test.tsx`、`tui/highlight.test.ts`、`sub-agent-guard-plugin.test.ts`、`auto-migrate-confirm-plugin.test.ts`、`conversation-commands/registry.test.ts`。
|
|
199
|
+
- 真实 PTY 实测:启动 → 对话 → 流式 → `/load` → `/clear` → 退出交还 shell;首启凭据链路;配置中心各子屏。
|
|
2
200
|
|
|
3
201
|
## [0.9.0] - 2026-09-30
|
|
4
202
|
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @ai-zen/cli
|
|
2
2
|
|
|
3
|
-
A command-line interface for AI agents, built on `@ai-zen/agents-sdk` and `@ai-zen/agents-core`.
|
|
3
|
+
A command-line interface for AI agents, built on `@ai-zen/agents-sdk` and `@ai-zen/agents-core`. It runs in **two modes**: an interactive terminal (TUI) for conversations with the AI, and a pure stdio mode for scripts, pipes, and the shell fallback hook. It ships built-in file system tools and supports MCP integration, sub-agent orchestration, and skill management.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -20,42 +20,78 @@ pnpm build
|
|
|
20
20
|
npm install -g .
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
## Run Modes
|
|
24
|
+
|
|
25
|
+
The CLI has two **non-mixing** run modes, chosen automatically from the launch arguments and the terminal environment:
|
|
26
|
+
|
|
27
|
+
| Mode | Trigger | Audience | Behavior |
|
|
28
|
+
|------|---------|----------|----------|
|
|
29
|
+
| **Pure stdio** | Arguments present, **or** stdin/stdout is not a TTY (pipe, redirect, CI) | Scripts, pipes, shell fallback hook | No extra interaction; reads input and writes the **final answer as plain text to stdout** |
|
|
30
|
+
| **TUI** | No arguments and both stdin/stdout are TTYs | Human users | Interactive chat UI |
|
|
31
|
+
|
|
32
|
+
In pure stdio mode, logs / progress / tool activity / error summaries all go to **stderr**; stdout carries the result only (no ANSI, no emoji prefix, no spinner). Exit code is `0` on success and non-zero on failure. Nothing is persisted by default (no conversation archive).
|
|
33
|
+
|
|
23
34
|
## Quick Start
|
|
24
35
|
|
|
25
36
|
```bash
|
|
26
|
-
#
|
|
27
|
-
|
|
37
|
+
# TUI: no arguments, interactive terminal
|
|
38
|
+
ai
|
|
39
|
+
|
|
40
|
+
# Pure stdio: argument is the prompt, result goes to stdout
|
|
41
|
+
ai Hello, introduce yourself.
|
|
28
42
|
|
|
29
|
-
#
|
|
30
|
-
|
|
43
|
+
# Pipe: stdin is the content, the argument is the instruction
|
|
44
|
+
cat README.md | ai "summarize in three sentences"
|
|
45
|
+
|
|
46
|
+
# Persist: off by default, opt in with --save
|
|
47
|
+
ai --save "name this function for me"
|
|
48
|
+
|
|
49
|
+
# Help / version
|
|
50
|
+
ai --help
|
|
51
|
+
ai --version
|
|
31
52
|
```
|
|
32
53
|
|
|
33
|
-
|
|
54
|
+
> The legacy command names `aiz` / `zen` still work as transition aliases in this version and will be removed in a future release.
|
|
55
|
+
|
|
56
|
+
## Interface (TUI)
|
|
34
57
|
|
|
35
|
-
|
|
58
|
+
When run with no arguments on an interactive terminal, the CLI opens a full-screen interface built with **Ink (React)**. It starts with an animated, gradient ASCII splash:
|
|
36
59
|
|
|
37
60
|
```
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
❌ Exit
|
|
61
|
+
█████╗ ██╗ ███████╗███████╗███╗ ██╗
|
|
62
|
+
██╔══██╗██║ ╚══███╔╝██╔════╝████╗ ██║
|
|
63
|
+
███████║██║ ███╔╝ █████╗ ██╔██╗ ██║
|
|
64
|
+
██╔══██║██║ ███╔╝ ██╔══╝ ██║╚██╗██║
|
|
65
|
+
██║ ██║██║ ███████╗███████╗██║ ╚████║
|
|
66
|
+
╚═╝ ╚═╝╚═╝ ╚══════╝╚══════╝╚═╝ ╚═══╝
|
|
67
|
+
|
|
68
|
+
AI workbench in your terminal
|
|
69
|
+
v1.0.0-alpha.10 · sdk x · core y
|
|
48
70
|
```
|
|
49
71
|
|
|
50
|
-
|
|
72
|
+
After the splash, you land **directly in the chat screen** (resuming the last session if there is one, otherwise starting a new conversation). The chat screen is **bottom-pinned**: a divider, the input line, and the status bar (model · agent · this-round / cumulative tokens · generating) always sit at the bottom of the terminal, while the conversation scrolls above them. While generating, the spinner replaces the input line.
|
|
73
|
+
|
|
74
|
+
The chat screen provides a streaming output area (reasoning / answer / tool calls on separate lines), a multiline input (`Enter` sends; `Ctrl+N` inserts a newline; `← →` move the cursor, `Ctrl+← →` by word), and an inline `/` command menu (↑↓ to choose, `Tab` to complete). Tool calls render as `⚙ name(args)` with **JSON syntax highlighting**; the answer / reasoning is **Markdown-source-colored** (headings, bold, italic, inline code, lists, quotes, links), and fenced code blocks are **syntax-highlighted by language with the fence markers kept** (highlight data from `highlight.js` via `lowlight`). `Ctrl+C` cancels the current request while generating, and exits when idle.
|
|
75
|
+
|
|
76
|
+
### First-run setup (API Key)
|
|
51
77
|
|
|
52
|
-
|
|
78
|
+
On first launch, if the endpoint bound to the selected model has no API Key yet, a **credential screen** appears instead of an error:
|
|
53
79
|
|
|
54
80
|
```
|
|
55
|
-
|
|
56
|
-
|
|
81
|
+
? First-run setup · Set the API Key for DeepSeek
|
|
82
|
+
Endpoint: DeepSeek · https://api.deepseek.com/v1
|
|
83
|
+
Current: not set
|
|
84
|
+
Get a key at: https://platform.deepseek.com/api_keys
|
|
85
|
+
Saving enters the chat immediately (Esc aborts and exits).
|
|
86
|
+
❯ ▏
|
|
57
87
|
```
|
|
58
88
|
|
|
89
|
+
`Enter` saves it (to `~/.ai-zen/config.json`) and drops you straight into the chat; `Tab` toggles plaintext, `Esc` aborts. Inside the chat, `/key` changes the **current endpoint's** key (the session is rebuilt on save, so it applies immediately) and `/config` opens the configuration center (default model / endpoint management: a list of [add endpoint] plus each endpoint; select one to edit its API key / base URL in place).
|
|
90
|
+
|
|
91
|
+
### Session Recovery
|
|
92
|
+
|
|
93
|
+
Every conversation is persisted directly as its own file (`cli/conversations/<id>.json`) while you chat — there is no separate draft store. A single pointer (`cli/last-session.json`) remembers the **last session id**; next time you start `ai`, that session is **resumed automatically** so you pick up where you left off.
|
|
94
|
+
|
|
59
95
|
### Conversation Commands
|
|
60
96
|
|
|
61
97
|
While in a conversation, all commands start with `/`. Typing `/` lists the available commands, with descriptions, right below the input line; typing more characters narrows the candidates by prefix:
|
|
@@ -65,54 +101,67 @@ While in a conversation, all commands start with `/`. Typing `/` lists the avail
|
|
|
65
101
|
/back Undo messages (roll back to a specific point and resend)
|
|
66
102
|
```
|
|
67
103
|
|
|
68
|
-
>
|
|
104
|
+
> Typing `/` lists candidate commands below the input line (↑↓ to choose, `Tab` to complete, `Enter` to submit/run). Commands are matched by their full names; an unrecognized `/xxx` reports "Unknown command".
|
|
69
105
|
|
|
70
106
|
| Command | Description |
|
|
71
107
|
|---------|-------------|
|
|
72
|
-
| `/exit` `/quit` | Exit the conversation
|
|
73
|
-
| `/save` | Save the current conversation |
|
|
108
|
+
| `/exit` `/quit` | Exit the conversation |
|
|
109
|
+
| `/save` | Save the current conversation (it is already flushed on every turn) |
|
|
110
|
+
| `/load` | Load a saved conversation (replaces the current session) |
|
|
74
111
|
| `/new` | Reset the conversation (clear history) |
|
|
75
112
|
| `/back` | Undo messages (roll back to a specific point and resend) |
|
|
76
113
|
| `/editor` | Open system editor for long-form input |
|
|
77
114
|
| `/clear` | Clear the screen |
|
|
78
|
-
| `/
|
|
115
|
+
| `/config` | Open the configuration center (endpoints / models / image models / MCP servers / agent definitions / defaults / tool-output cap) |
|
|
116
|
+
| `/key` | Set the API Key of the current endpoint (rebuilds the session on save) |
|
|
117
|
+
| `/handoff` | Write a handoff document only (session keeps running; no confirmation) |
|
|
118
|
+
| `/migrate` `/migration` | Handoff + start a new session (discards history; asks for confirmation) |
|
|
79
119
|
| `/help` | Show available commands |
|
|
80
120
|
|
|
81
|
-
###
|
|
121
|
+
### Task Handoff & Migration
|
|
82
122
|
|
|
83
|
-
|
|
123
|
+
Two related commands, one pipeline:
|
|
84
124
|
|
|
85
|
-
|
|
125
|
+
- **`/handoff`** — the original agent stops what it is doing and writes a handoff document to `<project>/.ai-zen/handoffs/<timestamp>-<conversation id>.md`, using its own tools to verify the real state (branch, uncommitted changes, tests, ports). The session keeps running, so you can keep refining the document.
|
|
126
|
+
- **`/migrate`** — the same handoff, then history is cleared and a new session starts from the document (the breakpoint message carries only the path; the new agent reads it).
|
|
86
127
|
|
|
87
|
-
|
|
128
|
+
Two executors: `self` (default — the original agent writes it in-session, highest fidelity) and `summary` (a single independent model call, cheap but lossy). `self` degrades to `summary` one-way on failure. Pass it explicitly with `/handoff summary` or `/migrate self`.
|
|
129
|
+
|
|
130
|
+
When `usage.prompt_tokens` exceeds the model's `maxContextTokens`, an interactive terminal shows a three-way picker (self / summary / skip); non-interactive pipes migrate with the default executor without blocking.
|
|
88
131
|
|
|
89
|
-
The migration
|
|
90
|
-
- **Conversation Breakpoint** — Last user/AI exchange verbatim
|
|
91
|
-
- **Completed Tasks** — Task titles and output paths
|
|
92
|
-
- **Pending Tasks** — Description, progress, next steps
|
|
93
|
-
- **Important Notes** — Technical preferences, lessons learned, architecture decisions
|
|
94
|
-
- **File Index** — Key files with descriptions
|
|
95
|
-
- **Handover Instructions** — SOP for the relay agent (read files first, verify state, then act)
|
|
132
|
+
The document template is not hard-coded: it comes from the `handoff` Skill (`~/.ai-zen/skills/handoff/SKILL.md`, released and synced by the SDK; mark `metadata.custom: "true"` to keep your own version, or override per project). See [Task Handoff & Migration](./docs/en/migration.md) for the full chain, cost notes, and the template sections.
|
|
96
133
|
|
|
134
|
+
The same context guard also applies to **sub-agents**: at each delegation boundary (`onSubAgentStart`) the CLI installs the same `ContextGuardPlugin` (same `maxTokens`) onto the newly built sub-agent, so a delegated sub-agent (including the Skill sub-agent created by `call_skill_sub_agent`) is interrupted as soon as its context exceeds the hard limit. This is transparent — a normally-running sub-agent is unaffected.
|
|
97
135
|
### Shell Fallback Hook
|
|
98
136
|
|
|
99
137
|
When you type an unrecognized command in your terminal, it can be automatically forwarded to AI for processing:
|
|
100
138
|
|
|
101
139
|
```bash
|
|
102
140
|
# Install the hook
|
|
103
|
-
|
|
141
|
+
ai hook install
|
|
104
142
|
|
|
105
143
|
# After that, try typing something random:
|
|
106
144
|
> what's the weather today?
|
|
107
145
|
# This will be forwarded to AI instead of showing "command not found"
|
|
108
146
|
|
|
109
147
|
# Uninstall
|
|
110
|
-
|
|
148
|
+
ai hook uninstall
|
|
111
149
|
```
|
|
112
150
|
|
|
151
|
+
The hook calls `ai "$@"` (pure stdio mode) so the answer is printed in your current shell session. If you previously installed the legacy `aiz` hook, re-running `ai hook install` upgrades it automatically; you can also run `ai hook uninstall` first.
|
|
152
|
+
|
|
113
153
|
## Configuration
|
|
114
154
|
|
|
115
|
-
Configuration is stored in `~/.ai-zen/config.json` (or `$AI_ZEN_DIR/config.json` if set), shared with other AI-Zen clients
|
|
155
|
+
Configuration is stored in `~/.ai-zen/config.json` (or `$AI_ZEN_DIR/config.json` if set), shared with other AI-Zen clients and used as the **single source of truth**. The TUI can edit the common fields for you:
|
|
156
|
+
|
|
157
|
+
| Scenario | How |
|
|
158
|
+
|----------|-----|
|
|
159
|
+
| First launch, endpoint has no key | The **credential screen** appears automatically |
|
|
160
|
+
| Change the current model's endpoint key | `/key` in the chat (session rebuilt on save) |
|
|
161
|
+
| Endpoints / models / image models, MCP servers, agent definitions (incl. sub-agents), defaults, tool-output cap | `/config` (the configuration center — full management) |
|
|
162
|
+
| Other advanced fields (skills / user tools, …) | Edit the files under `~/.ai-zen/` manually |
|
|
163
|
+
|
|
164
|
+
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).
|
|
116
165
|
|
|
117
166
|
```jsonc
|
|
118
167
|
{
|
|
@@ -126,11 +175,12 @@ Configuration is stored in `~/.ai-zen/config.json` (or `$AI_ZEN_DIR/config.json`
|
|
|
126
175
|
],
|
|
127
176
|
"models": [
|
|
128
177
|
{
|
|
129
|
-
"id": "gpt-
|
|
130
|
-
"name": "GPT-
|
|
178
|
+
"id": "gpt-6.1-sol",
|
|
179
|
+
"name": "GPT-6.1 Sol",
|
|
131
180
|
"endpointId": "openai",
|
|
132
|
-
"modelName": "gpt-
|
|
133
|
-
"maxContextTokens": 250000
|
|
181
|
+
"modelName": "gpt-6.1-sol",
|
|
182
|
+
"maxContextTokens": 250000,
|
|
183
|
+
"custom": true
|
|
134
184
|
}
|
|
135
185
|
],
|
|
136
186
|
"imageModels": [
|
|
@@ -142,13 +192,15 @@ Configuration is stored in `~/.ai-zen/config.json` (or `$AI_ZEN_DIR/config.json`
|
|
|
142
192
|
"defaultSize": "1024x1024"
|
|
143
193
|
}
|
|
144
194
|
],
|
|
145
|
-
"defaultModel": "deepseek-
|
|
195
|
+
"defaultModel": "deepseek-flash",
|
|
146
196
|
"defaultImageModel": "cogview-4",
|
|
147
197
|
"defaultAgent": "default",
|
|
148
|
-
"defaultMigrationModel": "deepseek-
|
|
198
|
+
"defaultMigrationModel": "deepseek-flash"
|
|
149
199
|
}
|
|
150
200
|
```
|
|
151
201
|
|
|
202
|
+
> Note: entries in `models` / `imageModels` **without `custom: true`** are **factory-managed** — on every launch they are reconciled with (and replaced by) the SDK factory catalog; add `"custom": true` for your own entries. `endpoints` are never managed and always keep your configuration.
|
|
203
|
+
|
|
152
204
|
### Environment Variable
|
|
153
205
|
|
|
154
206
|
- `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/`.
|
|
@@ -160,7 +212,7 @@ Configuration is stored in `~/.ai-zen/config.json` (or `$AI_ZEN_DIR/config.json`
|
|
|
160
212
|
├── config.json ← Endpoints & models (shared with other AI-Zen clients)
|
|
161
213
|
├── cli/ ← CLI runtime data
|
|
162
214
|
│ ├── conversations/ ← CLI conversations
|
|
163
|
-
│ └──
|
|
215
|
+
│ └── last-session.json ← Pointer to the last session id
|
|
164
216
|
├── agents/ ← Agent definitions (shared)
|
|
165
217
|
│ ├── default.json ← Default agent (created on first run)
|
|
166
218
|
│ └── my-custom-agent.json
|
|
@@ -209,25 +261,25 @@ The CLI provides 20 built-in tools, implemented by `@ai-zen/agents-sdk`. Tool av
|
|
|
209
261
|
| Tool | Description |
|
|
210
262
|
|------|-------------|
|
|
211
263
|
| `cwd` | Get current working directory |
|
|
212
|
-
| `
|
|
213
|
-
| `
|
|
214
|
-
| `
|
|
264
|
+
| `read` | Read file contents (supports `range` for partial reads) |
|
|
265
|
+
| `inspect_file` | Inspect file structure (lines, chars, column widths, line-ending style) without reading content |
|
|
266
|
+
| `write` | Write content to file |
|
|
215
267
|
| `edit` | Replace text in files (single replacement) |
|
|
216
|
-
| `
|
|
268
|
+
| `batch_edit` | Batch replace text in files |
|
|
217
269
|
| `exec` | Execute shell commands |
|
|
218
|
-
| `
|
|
270
|
+
| `spawn` | Execute a shell command asynchronously (returns immediately) |
|
|
219
271
|
| `mkdir` | Create directories |
|
|
220
272
|
| `rm` | Delete files or directories |
|
|
221
273
|
| `glob` | Scan files with glob patterns |
|
|
222
274
|
| `ls` | List directory contents |
|
|
223
275
|
| `exist` | Check if path exists |
|
|
224
|
-
| `
|
|
225
|
-
| `
|
|
276
|
+
| `find_text` | Search text in files |
|
|
277
|
+
| `download_file` | Download file from URL |
|
|
226
278
|
| `rename` | Rename or move files |
|
|
227
279
|
| `copy` | Copy files or directories |
|
|
228
280
|
| `sleep` | Wait for a specified number of milliseconds |
|
|
229
|
-
| `
|
|
230
|
-
| `
|
|
281
|
+
| `view_image` | View/analyze an image — vision models only (`Model.vision`). A network URL is returned as an `image_url` content block; a local path is auto-uploaded via the Files API and returned as a `file` content block |
|
|
282
|
+
| `generate_image` | Generate images from text — requires `defaultImageModel`; always returns a plain string (JSON with the image URLs plus `view_image` / `download_file` hints) instead of forcing image content blocks |
|
|
231
283
|
|
|
232
284
|
### Dynamic Tools
|
|
233
285
|
|
|
@@ -246,7 +298,7 @@ In addition to built-in tools, the SDK provides 5 dynamic loading tools that are
|
|
|
246
298
|
Tools are assembled in three phases by the SDK's `Scope` capability pipeline:
|
|
247
299
|
|
|
248
300
|
1. **Discovery** — Scan filesystem for built-in tools, user tools, SubAgents, Skills, and MCP servers. All 20 built-in tools are discovered unconditionally (no filtering at this stage)
|
|
249
|
-
2. **Filtering** — Apply permissions (`allow`/`deny`), security exclusions (recursion protection), and each tool's self-declared `isAvailable(config, definition)` (availability is decided at build time when the model is known; e.g. `
|
|
301
|
+
2. **Filtering** — Apply permissions (`allow`/`deny`), security exclusions (recursion protection), and each tool's self-declared `isAvailable(config, definition)` (availability is decided at build time when the model is known; e.g. `view_image` only for vision models, `generate_image` requires `defaultImageModel`)
|
|
250
302
|
3. **Instantiation** — Map filtered names to `Tool` instances and register dynamic loaders
|
|
251
303
|
|
|
252
304
|
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 reuses the caller's tool set without a second permission pass, as a transient conversation proxy rather than an independent entity.
|
|
@@ -304,13 +356,14 @@ The OAuth 2.0 authorization flow (the `oauth` field in `mcp.json`) has its types
|
|
|
304
356
|
|
|
305
357
|
| ID | Name | Endpoint |
|
|
306
358
|
|----|------|----------|
|
|
307
|
-
| `gpt-
|
|
308
|
-
| `
|
|
309
|
-
| `
|
|
359
|
+
| `gpt-6-astra` | GPT-6 Astra | OpenAI |
|
|
360
|
+
| `gpt-6.1-sol` | GPT-6.1 Sol | OpenAI |
|
|
361
|
+
| `gpt-6-luna` | GPT-6 Luna | OpenAI |
|
|
362
|
+
| `glm-5.3` | GLM-5.3 | ZhipuAI |
|
|
363
|
+
| `glm-5.3-flash` | GLM-5.3-Flash (vision) | ZhipuAI |
|
|
364
|
+
| `glm-5.3-flashx` | GLM-5.3-FlashX (vision) | ZhipuAI |
|
|
310
365
|
| `glm-4.7-flash` | GLM-4.7-Flash | ZhipuAI |
|
|
311
|
-
| `deepseek-
|
|
312
|
-
| `deepseek-v4-flash` | DeepSeek-V4-Flash | DeepSeek (**default**) |
|
|
313
|
-
| `deepseek-v4-flash-vision-exp` | DeepSeek-V4-Flash-Vision-Exp (vision) | DeepSeek |
|
|
366
|
+
| `deepseek-flash` | DeepSeek-V4.1-Flash (vision) | DeepSeek (**default**) |
|
|
314
367
|
|
|
315
368
|
## Development
|
|
316
369
|
|