xuanzhu 0.4.4 → 0.5.0

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/README.md CHANGED
@@ -1,7 +1,5 @@
1
1
  # 玄猪 XuanZhu
2
2
 
3
- [English](https://github.com/amble311/xuanzhu/blob/main/docs/README.en.md) | **中文**
4
-
5
3
  > 专为终端打造的 AI 编码 Agent —— 一条 `xzh` 命令,把 AI 编程助手带进你的终端。
6
4
 
7
5
  ## 快速上手
@@ -32,6 +30,8 @@ xzh # 启动
32
30
  - **默认全自动**:`autoApprove` 默认为 `true`,**所有工具都直接执行、不做任何确认** —— 包括写文件、执行命令、读取工作区之外的文件,以及读取凭据类文件(`~/.ssh`、`.env`、`~/.xzh/config.json` 等)。开箱即用,不打断。`/auto off` 可切换为写文件与执行命令逐项确认。
33
31
  - 如果希望读取凭据类文件时确认一次(防止密钥被读进上下文后转交给模型服务商),把 `confirmSensitiveRead` 设为 `true`,默认关闭。
34
32
  - **多轮自主执行**:自动串联工具调用完成任务,可随时 `Ctrl+C` 中断。
33
+ - **目标模式(`/goal`)**:设一个目标,玄猪会持续自动推进(每轮答复后立刻继续),
34
+ 直到它调用 `goal_complete` 声明完成 —— 中途不需要你再发「继续」(见「目标模式」)。
35
35
  - **任务拆分**:3 步以上的复杂任务会先用 `todo_write` 列出计划并逐步更新,
36
36
  顶部信息区实时显示进度条(`任务 2/5` 与当前进行项)。
37
37
  - **子代理协作(可并行)**:需要大范围调研(跨多个文件 / 目录 / 命名约定)时,用 `task`
@@ -166,6 +166,9 @@ xzh
166
166
  | `xzh skill list` | 列出全部技能(来源与状态,含已禁用项) |
167
167
  | `xzh skill enable/disable <名称>` | 启用 / 禁用技能 |
168
168
  | `xzh skill delete <名称> [--yes]` | 删除技能(仅限用户技能;内置技能请用 disable) |
169
+ | `xzh errors` | 查看玄猪自动记录的错误报告(`~/.xzh/errors/`) |
170
+ | `xzh errors show <序号\|签名>` | 查看一份报告的完整内容(JSON) |
171
+ | `xzh errors clear [--yes]` | 清空错误报告 |
169
172
  | `xzh device connect <手机IP>` | 连接手机上的 AutoJs6(服务器模式)并常驻 |
170
173
  | `xzh device serve` | 反向:等手机上的 AutoX.js 连过来 |
171
174
  | `xzh device run <文件>` | 把脚本推到手机并运行(`push` 则只保存不运行) |
@@ -198,6 +201,8 @@ XZH_HOME=/path/to/dir xzh # 改用 /path/to/dir/config.json
198
201
  "temperature": 0.2,
199
202
  "maxToolRounds": 200,
200
203
  "autoApprove": true,
204
+ "mouseCapture": true,
205
+ "confirmSensitiveRead": false,
201
206
  "memoryMaxChars": 12000,
202
207
  "maxParallelAgents": 4,
203
208
  "intent": { "enabled": false },
@@ -210,6 +215,21 @@ XZH_HOME=/path/to/dir xzh # 改用 /path/to/dir/config.json
210
215
  }
211
216
  ```
212
217
 
218
+ | 字段 | 默认 | 说明 |
219
+ | --- | --- | --- |
220
+ | `provider` / `model` | — | 「上次使用」的模型(每次切换由玄猪写回) |
221
+ | `models` | `[]` | 已配置模型,**顺序即回退优先级** |
222
+ | `temperature` | `0.2` | 采样温度 |
223
+ | `maxToolRounds` | `200` | 单轮任务内工具调用轮数上限(用尽时询问是否追加) |
224
+ | `autoApprove` | `true` | 自动批准工具(`false` 时写文件/执行命令前询问) |
225
+ | `mouseCapture` | `true` | 接管鼠标:滚轮滚动 + 输出区拖拽选中复制(`/mouse` 切换) |
226
+ | `confirmSensitiveRead` | `false` | 读取凭据类文件(`.env`、`~/.ssh`、`config.json` 等)时是否确认 |
227
+ | `memoryMaxChars` | `12000` | 长期记忆字符上限,超出即自动精简(`0` = 不限制长度,仍去重) |
228
+ | `maxParallelAgents` | `4` | 并行子代理数量上限(`1` = 串行,硬上限 16) |
229
+ | `intent.enabled` | `false` | 意图分析(每条消息先分析再处理) |
230
+ | `intent.prompt` | 内置模板 | 意图分析模板,占位符 `{{'用户发送过来的消息'}}` |
231
+ | `systemPromptExtra` | — | 追加到系统提示词的额外内容 |
232
+
213
233
  > 旧版配置(只有 `provider` / `model`、没有 `models`)依然可用:会被视为唯一的一个模型。
214
234
  > 旧配置里的 `weight` / `decayed` 字段已废弃,读取时会被忽略、下次保存时自动清掉。
215
235
 
@@ -244,7 +264,7 @@ xzh model remove openai/gpt-4o # 删除(id / 模型名 / 序号均可
244
264
  想让某个模型**不参与回退**,直接 `xzh model remove` 删掉即可。当前使用的模型显示在界面顶部与状态栏,
245
265
  发生回退时输出区会给出提示;想临时换一个用,直接在对话里 `/model` 选(`xzh model` 仍是增删改的入口)。
246
266
 
247
- > ⚠️ `xzh model add` 的位置参数自 v0.5 起**整体前移一位**(原来的 `[权重]` 已取消):
267
+ > ⚠️ `xzh model add` 的位置参数自 **0.4.2** 起**整体前移一位**(原来的 `[权重]` 已取消):
248
268
  > 现在是 `add <provider> <model> [上下文窗口] [on|off]`。
249
269
 
250
270
  ### 上下文窗口的作用
@@ -341,6 +361,7 @@ API Key 也可以来自环境变量,优先级低于配置文件:
341
361
  | `memory_write` | 写入项目记忆(长期记忆 / 当日日志),长期记忆超限时自动精简 | 否 |
342
362
  | `memory_compact` | 用精简后的完整内容重写长期记忆(把新结论并入主题小节 / 语义压缩) | 否 |
343
363
  | `todo_write` | 创建 / 更新任务列表(每次提交完整列表) | 否 |
364
+ | `goal_complete` | 目标模式(`/goal`)下声明目标已全部完成(仅主代理可用) | 否 |
344
365
  | `task` | 派生子代理(默认 `code-explorer`)执行子任务,只返回结论;一轮内多个调用**并行**执行 | 否 |
345
366
  | `read_file` | 读取文件(带行号,支持偏移与行数限制) | 否 |
346
367
  | `list_dir` | 列出目录内容 | 否 |
@@ -354,6 +375,8 @@ API Key 也可以来自环境变量,优先级低于配置文件:
354
375
  | `device_run` | 把脚本推到手机并立即运行 | 是 |
355
376
  | `device_stop` | 停止手机上的脚本(默认全部) | 是 |
356
377
  | `device_logs` | 读取手机上的脚本日志 | 否 |
378
+ | `device_read_screen` | 读取手机当前界面(包名 / 控件文本与位置),**以文字返回** | 否 |
379
+ | `device_screenshot` | 截取手机屏幕,**图片随结果附给模型**(控件读不到时用它,再按坐标点击) | 否 |
357
380
 
358
381
  ## 任务拆分与子代理
359
382
 
@@ -372,11 +395,12 @@ API Key 也可以来自环境变量,优先级低于配置文件:
372
395
  > 只有声明了 `parallelSafe` 的工具会进入并行批次(目前仅 `task`)。写文件、编辑、
373
396
  > 执行命令这类工具有副作用且可能互相依赖,始终按顺序串行执行,不会被并行化。
374
397
 
375
- 内置一个子代理,通过 `subagent_name` 指定(默认即它):
398
+ 内置两个子代理,通过 `subagent_name` 指定(默认 `code-explorer`):
376
399
 
377
400
  | 子代理 | 能力 | 何时用 |
378
401
  | --- | --- | --- |
379
402
  | `code-explorer` | **只读**(`read_file` / `list_dir` / `glob` / `grep` / `list_skills` / `load_skill`) | 跨多个文件、目录或命名约定的搜索;单次 `read_file` / `grep` 覆盖不了的探索 |
403
+ | `test-runner` | **只运行、不修改**(`bash` + 读取类工具):跑全量或指定测试,汇报通过/失败清单、失败原因与可复跑命令 | 测试输出会很长时;改完代码想确认是否全绿;只想拿到「哪几条挂了、为什么」而不想自己翻日志 |
380
404
 
381
405
  `task` 的参数:
382
406
 
@@ -386,8 +410,8 @@ API Key 也可以来自环境变量,优先级低于配置文件:
386
410
  | `prompt` | 交给子代理的完整任务描述。**子代理看不到主对话**,必须自包含;`code-explorer` 还应在其中写明探索力度(`quick` / `medium` / `very thorough`) |
387
411
  | `subagent_name` | 要派生的子代理名称,默认 `code-explorer` |
388
412
 
389
- 约束:子代理恒不提供 `task`(禁止无界递归)、`todo_write` 与 `memory_write` / `memory_compact`
390
- (任务列表与记忆由主代理统一维护)。它的工具活动以 `[code-explorer: <任务说明>]` 前缀显示在
413
+ 约束:子代理恒不提供 `task`(禁止无界递归)、`todo_write`、`goal_complete` 与
414
+ `memory_write` / `memory_compact`(任务列表、目标与记忆由主代理统一维护)。它的工具活动以 `[code-explorer: <任务说明>]` 前缀显示在
391
415
  输出区 —— 并行时会交错,前缀里的任务说明用于区分是谁在输出;危险操作确认仍会转发给你
392
416
  (并行时多个确认会**排队**逐个弹出,不会互相覆盖)。
393
417
 
@@ -419,6 +443,33 @@ API Key 也可以来自环境变量,优先级低于配置文件:
419
443
  `memory_compact` 做语义压缩:`memory_write` 的返回里会直接给出提示,系统提示词也会带
420
444
  「⚠ 长期记忆仍然过长」段落。
421
445
 
446
+ ## 目标模式(`/goal`)
447
+
448
+ `/goal <目标>` 让玄猪进入**目标模式**:设定之后它会**持续自动推进**,每轮给出答复后立刻继续,
449
+ 直到它调用 `goal_complete` 声明目标完成 —— 不需要你再发「继续」。
450
+
451
+ ```
452
+ /goal 把项目里所有 console.log 换成统一 logger,并跑通测试
453
+ ```
454
+
455
+ | 命令 | 说明 |
456
+ | --- | --- |
457
+ | `/goal <目标>` | 设定目标并**立即开始**自动执行(重复使用会替换原目标) |
458
+ | `/goal` / `/goal status` | 查看当前目标、状态(执行中 / 已暂停 / 已完成)与已执行轮数 |
459
+ | `/goal continue` | 继续一个已暂停的目标(别名 `resume` / `go`) |
460
+ | `/goal off` | 清除目标(别名 `stop` / `clear` / `cancel`) |
461
+
462
+ - **何时结束**:模型调用 `goal_complete`(要求说明做了什么、如何验证)。目标确实做不下去时
463
+ (缺凭据、外部依赖不可用)它也应当调用它并写明阻塞原因,而不是无限空转。
464
+ - **随时可停**:`Ctrl+C`(或 `Ctrl+D`)中断当前轮并暂停循环,**目标会保留**;
465
+ 输入 `/goal continue` 接着跑,`/goal off` 清除。
466
+ - **进度可见**:顶部信息区与状态栏显示 `◎goal`、目标与当前轮次;多步任务仍由 `todo_write`
467
+ 维护清单,自动继续时会带着清单提示模型「从没做完的地方接着做」。
468
+ - **安全阀**:最多自动继续 40 轮,到上限会暂停并提示(避免目标本身含糊时无限烧 token)。
469
+ - **确认框仍然生效**:目标模式**不会**自动打开 `/auto`。未开启自动批准时,写文件 / 执行命令
470
+ 仍会弹确认,确认后循环继续;想全程无人值守请先 `/auto on`。
471
+ - `/reset`、`/resume`、`/switch` 会清掉当前目标(它们替换了目标所依赖的对话上下文)。
472
+
422
473
  ## 图片输入(Ctrl+V)
423
474
 
424
475
  在输入框按 **Ctrl+V**(或 `/image`、`/paste`)会把**系统剪贴板里的图片**加为本轮附件,
@@ -664,12 +715,17 @@ description: 一句话说明该技能的用途与适用场景
664
715
  | `Shift+Tab` | 切换焦点(对话 ⇄ 右侧终端) |
665
716
  | 鼠标点击 | 焦点跟随点击的栏 |
666
717
  | 鼠标滚轮 | 按区域滚动(左:对话区;右:终端输出) |
718
+ | `Ctrl+A` / `Ctrl+E` | 光标移到行首 / 行尾 |
667
719
  | `Ctrl+C` | 中断当前任务 / 清空输入 / 退出(空闲且输入为空时退出) |
668
720
  | `Ctrl+D` | 结束本轮正在进行的对话(**任何情况下都不会退出玄猪**);终端面板内为中断运行中的命令 |
669
721
  | `Ctrl+L` | 清屏(终端面板内为清空命令输出) |
670
722
 
671
723
  > `Ctrl+D` 只做「结束本轮对话」这一件事:没有对话在进行时按它不会有任何反应,也**永远不会退出界面**。
672
724
  > 退出请用 `Ctrl+C`(空闲且输入为空时)或 `/exit`。
725
+ >
726
+ > **SSH 断线 / 进程被终止**:sshd 关闭终端时会发 `SIGHUP`,玄猪按正常流程退出 ——
727
+ > 右侧终端里在运行的命令会一并终止(不会留成孤儿进程);若当时这一轮还没答完,
728
+ > 会在会话文件里补一条「上一轮已中止」的说明,重连后 `/resume` 不会把半截任务当成仍在进行。
673
729
 
674
730
  ### 让 Ctrl+Enter / Shift+Enter 生效
675
731
 
@@ -694,7 +750,7 @@ description: 一句话说明该技能的用途与适用场景
694
750
  kitty / Ghostty 会把该 xterm 兼容序列映射成「所有按键都用转义码上报」而破坏普通输入,
695
751
  故玄猪对这两类终端不发送请求,请改用 `Alt+Enter` 或在终端侧自行配置。
696
752
 
697
- 界面内命令:`/help`、`/clear`、`/tools`、`/image`、`/copy [N|all]`、`/mouse`、`/reset`、`/cwd`、`/switch <目录>`、`/term`、`/model [编号|id|模型名]`、`/auto [on|off]`、`/intent [on|off]`、`/exit`。
753
+ 界面内命令:`/help`、`/clear`、`/tools`、`/device`、`/image`(`/paste`)、`/copy [N|A-B|last|all]`、`/mouse`、`/reset`、`/undo`、`/resume [编号]`、`/cwd`、`/switch <目录>`、`/term`、`/model [编号|id|模型名]`、`/goal <目标>`(`/goal [status|continue|off]`)、`/auto [on|off]`、`/intent [on|off]`、`/exit`。
698
754
 
699
755
  ### 选中与复制
700
756
 
@@ -760,21 +816,48 @@ XZH_KITTY_KEYS=1 xzh
760
816
  (会话文件也随之换到该项目名下;当前对话已存档在原项目,切回后 `/resume` 可找回)。
761
817
  若该项目还没有历史会话,则是全新开局。
762
818
 
819
+ ## 遇到问题(错误报告)
820
+
821
+ 玄猪会在**出现异常时自动留一份现场**,方便你反馈 bug:
822
+
823
+ | 触发 | 行为 |
824
+ | --- | --- |
825
+ | 未捕获异常 / 未处理的 Promise 拒绝 | 退出前记录(同时写 `crash.log`) |
826
+ | 工具实现抛异常 | 该工具返回失败、对话继续,同时留一份报告 |
827
+ | 整轮对话失败(回退链走完仍失败) | 界面上提示「已记录错误报告:…」 |
828
+
829
+ 报告存放在 `~/.xzh/errors/`,每份包含:版本 / Node / 平台 / 项目目录 / 当前模型与 provider /
830
+ 错误消息与堆栈 / 最近几条消息(均截断)。写入前会**对常见密钥格式脱敏**
831
+ (`sk-*`、`AIza*`、`gh*_`、`Bearer …`、`api_key=` 等),但发到公开 issue 前仍建议自己扫一眼。
832
+ 同一类错误只保留一份并累加次数,最多 50 份。
833
+
834
+ ```bash
835
+ xzh errors # 列表:时间 / 次数 / 类别 / 摘要
836
+ xzh errors show 1 # 第 1 份的完整 JSON
837
+ xzh errors path # 报告目录
838
+ xzh errors clear --yes # 清空
839
+ ```
840
+
841
+ 反馈时把 `xzh errors show <序号>` 的输出(或整个 `~/.xzh/errors/` 目录)附上即可。
842
+
763
843
  ## 项目结构
764
844
 
765
845
  ```
766
846
  src/
767
- ├── cli/ 命令行入口与命令
768
- ├── core/ Agent 循环与提示词
769
- ├── llm/ LLM Provider 抽象与实现
770
- ├── tools/ 终端工具集(含 list_skills / load_skill)
771
- ├── skills/ 技能发现与加载
772
- ├── tui/ 全屏终端界面
773
- ├── config/ 配置读写
774
- └── utils/ ANSI 与路径工具
847
+ ├── cli/ 命令行入口与子命令(model / config / skill / device / setup)
848
+ ├── core/ Agent 循环、系统提示词、会话持久化
849
+ ├── llm/ LLM Provider 抽象与实现、上下文裁剪、token 校正
850
+ ├── tools/ 终端工具集(文件 / bash / 记忆 / 技能 / 任务列表 / 子代理 / 设备桥)
851
+ ├── subagents/ 子代理注册表(code-explorer / test-runner)
852
+ ├── device/ 手机设备桥(AutoJs6 协议、服务端、APK 探测、截图、界面树)
853
+ ├── skills/ 技能发现、依赖检测与安装
854
+ ├── tui/ 全屏终端界面
855
+ ├── workspace/ 项目级工作区(.xuanzhu:记忆 + 规则)
856
+ ├── config/ 配置读写
857
+ └── utils/ ANSI / 备份 / 剪贴板 / 并发 / 崩溃诊断 / 路径
775
858
  ```
776
859
 
777
- 详见 [docs/ARCHITECTURE.md](https://github.com/amble311/xuanzhu/blob/main/docs/ARCHITECTURE.md)。
860
+ 架构说明与设计取舍由开发者**本地维护**(`AGENTS.md` 与 `docs/`),**不随包分发、也不在 GitHub 仓库中**。
778
861
 
779
862
  ## 开发
780
863
 
@@ -791,12 +874,13 @@ node bin/xzh.js # 本地运行
791
874
  ```bash
792
875
  ./release.sh # 版本尾号 +1(0.1.4 → 0.1.5)
793
876
  ./release.sh minor # 0.1.4 → 0.2.0
794
- ./release.sh 1.0.0 # 指定版本
877
+ ./release.sh major # 0.1.4 → 1.0.0
878
+ ./release.sh 1.2.3 # 指定版本
795
879
  XZH_RELEASE_DRY_RUN=1 ./release.sh # 先演练一遍,不做任何写入
796
880
  ```
797
881
 
798
- 脚本会依次完成:**版本号 +1 → `npm publish` → 等待 registry 同步 → 提交并推送 GitHub
799
- → 更新本机全局安装**。
882
+ 脚本会依次完成:**bump 版本号(含 lock)→ 把 `CHANGELOG.md` 的 `[未发布]` 段收成本次版本
883
+ → `npm publish` → 等待 registry 同步 → `git add -A` + 提交 + 推送 GitHub → 更新本机全局安装**。
800
884
 
801
885
  之所以需要脚本,是因为这条链路有几个反直觉的地方:`npm publish` 返回成功**不等于**
802
886
  registry 已可见(npm 有 staging 阶段,期间 `npm view` / `npm install` 会报 `notarget`),
@@ -808,7 +892,8 @@ registry 已可见(npm 有 staging 阶段,期间 `npm view` / `npm install`
808
892
  | `XZH_RELEASE_YES=1` | 跳过发布前的确认提示 |
809
893
  | `XZH_RELEASE_SKIP_GIT=1` | 不推送 GitHub |
810
894
  | `XZH_RELEASE_SKIP_LOCAL=1` | 不更新本机全局安装 |
811
- | `XZH_RELEASE_WAIT=<秒>` | 等待 registry 同步的上限(默认 300) |
895
+ | `XZH_RELEASE_WAIT=<秒>` | 等待 registry 同步的上限(默认 300;超时后仍可手工 `npm i -g xuanzhu@<版本>`) |
896
+ | `NO_COLOR=1` | 输出不带颜色(适合日志 / CI) |
812
897
 
813
898
  ## 致谢
814
899