xuanzhu 0.1.3 → 0.1.4
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/LICENSE +1 -0
- package/README.md +57 -25
- package/dist/cli.js +1 -1
- package/package.json +13 -4
package/LICENSE
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
3
|
Copyright (c) 2026 Oyinlola Olasunkanmi Raymond
|
|
4
|
+
Copyright (c) 2026 amble311 (玄猪 XuanZhu 的改造与衍生部分)
|
|
4
5
|
|
|
5
6
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
7
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -2,8 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
> 专为终端打造的 AI 编码 Agent —— 一条 `xzh` 命令,把 AI 编程助手带进你的终端。
|
|
4
4
|
|
|
5
|
+
## 快速上手
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm i -g xuanzhu # 安装(需要 Node.js ≥ 18)
|
|
9
|
+
xzh model # 配置模型:选服务商、填 API Key
|
|
10
|
+
xzh # 启动
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## 简介
|
|
14
|
+
|
|
5
15
|
玄猪是一个运行在终端里的全屏 AI Agent:它能读懂你的代码库、直接读写文件、执行命令、运行测试,
|
|
6
|
-
并用流式输出向你展示它的每一步思考与工具调用。内核采用了codebuddy的开源代码。
|
|
16
|
+
并用流式输出向你展示它的每一步思考与工具调用。内核采用了 codebuddy 的开源代码。
|
|
7
17
|
|
|
8
18
|
```
|
|
9
19
|
╭──────────────────────────────────────────────╮
|
|
@@ -27,33 +37,35 @@
|
|
|
27
37
|
|
|
28
38
|
## 安装
|
|
29
39
|
|
|
30
|
-
###
|
|
40
|
+
### 方式一:npm(推荐)
|
|
31
41
|
|
|
32
|
-
|
|
42
|
+
```bash
|
|
43
|
+
npm i -g xuanzhu # 全局安装
|
|
44
|
+
xzh # 启动
|
|
45
|
+
```
|
|
33
46
|
|
|
34
|
-
|
|
35
|
-
因此**不要求包已发布到 npm**:
|
|
47
|
+
不想全局安装,也可以免安装试用:
|
|
36
48
|
|
|
37
49
|
```bash
|
|
38
|
-
|
|
39
|
-
./install.sh
|
|
50
|
+
npx xuanzhu
|
|
40
51
|
```
|
|
41
52
|
|
|
42
|
-
|
|
53
|
+
> 若安装后提示 `xzh: command not found`,说明 npm 的全局 `bin` 目录不在 `PATH` 中,
|
|
54
|
+
> 见下方「PATH 配置」。
|
|
43
55
|
|
|
44
|
-
|
|
56
|
+
### 方式二:一键脚本
|
|
45
57
|
|
|
46
|
-
|
|
47
|
-
# Linux / macOS
|
|
48
|
-
curl -fsSL https://raw.githubusercontent.com/<owner>/<repo>/main/install.sh | sh
|
|
58
|
+
**Linux / macOS**
|
|
49
59
|
|
|
50
|
-
|
|
51
|
-
|
|
60
|
+
```bash
|
|
61
|
+
curl -fsSL https://raw.githubusercontent.com/amble311/xuanzhu/main/install.sh | sh
|
|
52
62
|
```
|
|
53
63
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
64
|
+
**Windows(PowerShell)**
|
|
65
|
+
|
|
66
|
+
```powershell
|
|
67
|
+
iex (irm https://raw.githubusercontent.com/amble311/xuanzhu/main/install.ps1)
|
|
68
|
+
```
|
|
57
69
|
|
|
58
70
|
脚本会检查 Node.js 版本、全局安装 `xzh`,并在需要时提示补充 PATH。
|
|
59
71
|
|
|
@@ -64,7 +76,7 @@ iex (irm https://raw.githubusercontent.com/<owner>/<repo>/main/install.ps1)
|
|
|
64
76
|
npm config set prefix ~/.npm-global # 然后确保 ~/.npm-global/bin 在 PATH 中
|
|
65
77
|
```
|
|
66
78
|
|
|
67
|
-
|
|
79
|
+
**脚本支持的环境变量**
|
|
68
80
|
|
|
69
81
|
| 变量 | 作用 |
|
|
70
82
|
| --- | --- |
|
|
@@ -73,23 +85,29 @@ npm config set prefix ~/.npm-global # 然后确保 ~/.npm-global/bin 在 PATH
|
|
|
73
85
|
| `XZH_NPM_ARGS` | 追加给 npm 的参数,如国内镜像 `--registry=https://registry.npmmirror.com` |
|
|
74
86
|
| `XZH_DRY_RUN=1` | 只打印将要执行的命令,不真正安装 |
|
|
75
87
|
|
|
76
|
-
###
|
|
88
|
+
### 方式三:从源码安装(开发用)
|
|
77
89
|
|
|
78
90
|
```bash
|
|
79
|
-
|
|
91
|
+
git clone https://github.com/amble311/xuanzhu.git
|
|
92
|
+
cd xuanzhu
|
|
80
93
|
npm install
|
|
81
94
|
npm run build
|
|
82
|
-
|
|
83
|
-
# 全局链接,使 xzh 命令可用
|
|
84
|
-
npm link
|
|
95
|
+
npm link # 使 xzh 命令指向本地源码
|
|
85
96
|
```
|
|
86
97
|
|
|
87
|
-
|
|
98
|
+
改动源码后执行 `npm run build` 即生效(`npm link` 建立的是软链)。
|
|
99
|
+
想切回正式发布的版本:
|
|
88
100
|
|
|
89
101
|
```bash
|
|
90
|
-
|
|
102
|
+
npm unlink -g xuanzhu && npm i -g xuanzhu
|
|
91
103
|
```
|
|
92
104
|
|
|
105
|
+
### 环境要求
|
|
106
|
+
|
|
107
|
+
- **Node.js ≥ 18**
|
|
108
|
+
- **真实终端**:TUI 需要交互式终端,在管道、CI 或部分编辑器内置终端中无法运行
|
|
109
|
+
- 首次运行会在**当前工作目录**创建 `.xuanzhu/`(项目记忆与规则),建议写入 `.gitignore`
|
|
110
|
+
|
|
93
111
|
## 快速开始
|
|
94
112
|
|
|
95
113
|
```bash
|
|
@@ -467,6 +485,20 @@ npm run typecheck # 类型检查
|
|
|
467
485
|
node bin/xzh.js # 本地运行
|
|
468
486
|
```
|
|
469
487
|
|
|
488
|
+
## 致谢
|
|
489
|
+
|
|
490
|
+
本项目站在前人的开源工作上,特别感谢:
|
|
491
|
+
|
|
492
|
+
- **[CodeBuddy](https://github.com/olasunkanmi-SE/codebuddy)** —— 作者
|
|
493
|
+
[Oyinlola Olasunkanmi Raymond](https://github.com/olasunkanmi-SE)。
|
|
494
|
+
玄猪由该项目改造而来(移除编辑器依赖、改为纯粹的终端形态),
|
|
495
|
+
并依 MIT 许可**保留其原始版权声明**。
|
|
496
|
+
- **[Playwright](https://github.com/microsoft/playwright)** —— 由 Microsoft 开源。
|
|
497
|
+
内置的 `playwright` 技能基于它实现浏览器自动化与端到端测试。
|
|
498
|
+
|
|
499
|
+
同时也感谢所有直接与间接依赖的开源项目,以及 npm 生态中的众多工具
|
|
500
|
+
(完整清单见 `package.json`)。
|
|
501
|
+
|
|
470
502
|
## License
|
|
471
503
|
|
|
472
504
|
MIT
|
package/dist/cli.js
CHANGED
|
@@ -128,7 +128,7 @@ ${e.trim()}`),o}var Lr=1500;function Qn(n){let e="\n\n## \u9879\u76EE\u8BB0\u5FC
|
|
|
128
128
|
${s}`}return e}var he=x(require("path")),es=new Set(["read_file","list_dir","glob","grep"]),ts=/(^|\/)(\.env(\..+)?|\.npmrc|\.netrc|\.git-credentials|\.ssh|\.aws|\.gnupg|\.kube|\.docker|\.xzh|\.xuanzhu|credentials|secrets?)(\/|$)|\.(pem|key|p12|pfx|jks)$|(^|\/)id_(rsa|dsa|ecdsa|ed25519)(\.|$)/i,Dr=400,rs=.5,ns=3,We=class{provider;config;cwd;events;systemPrompt;warnedTightContext=!1;history=[];activeModel;constructor(e,r,s,i,o){this.provider=e,this.config=r,this.cwd=s,this.events=i,this.activeModel=o??Q(r),this.systemPrompt=this.composeSystemPrompt()}getActiveModel(){return this.activeModel}composeSystemPrompt(){return Or(this.cwd,this.config.systemPromptExtra,hr(this.cwd),Ne(this.cwd))}get messages(){return this.history}reset(){this.history=[]}get messageCount(){return this.history.length}getCwd(){return this.cwd}setCwd(e){this.cwd=e,this.systemPrompt=this.composeSystemPrompt()}async run(e,r){let s=e;if(!this.warnedTightContext&&at(this.activeModel?.contextWindow,this.activeModel?.model??"",this.systemPrompt)&&(this.warnedTightContext=!0,this.events.onNotice?.("\u5F53\u524D\u6A21\u578B\u53EF\u7528\u4E0A\u4E0B\u6587\u8FC7\u5C0F\uFF1A\u7CFB\u7EDF\u63D0\u793A\u8BCD\u5DF2\u5360\u53BB\u7EDD\u5927\u90E8\u5206\u7A97\u53E3\uFF0C\u5386\u53F2\u4E0E\u5DE5\u5177\u8F93\u51FA\u5C06\u65E0\u6CD5\u53D1\u9001\u3002\u53EF\u7CBE\u7B80\u9879\u76EE\u89C4\u5219\uFF08.xuanzhu/rules.md\uFF09\u6216 systemPromptExtra\uFF0C\u6216\u6539\u7528\u7A97\u53E3\u66F4\u5927\u7684\u6A21\u578B\uFF08xzh model context <id> <\u5927\u5C0F>\uFF09\u3002")),this.config.intent?.enabled){this.events.onStatus("\u5206\u6790\u610F\u56FE\u4E2D");let c=await this.analyzeIntent(e,r);if(r?.aborted){this.events.onStatus("\u5DF2\u4E2D\u65AD");return}c?(s=c,this.events.onIntent?.(c,e)):this.events.onNotice?.("\u610F\u56FE\u5206\u6790\u672A\u8FD4\u56DE\u5185\u5BB9\uFF0C\u5DF2\u6309\u539F\u59CB\u8F93\u5165\u7EE7\u7EED\u3002")}let i=[{role:"user",content:s}],o=Math.max(1,Math.floor(this.config.maxToolRounds)||1),a=()=>{for(let c of i)this.history.push(c);this.trimHistory()},l=()=>{let c=[];for(let u=0;u<i.length;u++){let d=i[u];if(c.push(d),d.role!=="assistant"||!d.toolCalls?.length)continue;let h=d.toolCalls.length,m=0;for(let p=u+1;p<i.length&&m<h;p++)i[p].role==="tool"&&m++;if(m<h){c.pop();break}}if(c.length>1){for(let u of c)this.history.push(u);this.trimHistory()}};try{for(let c=0;c<o;c++){if(r?.aborted){l(),this.events.onStatus("\u5DF2\u4E2D\u65AD");return}this.trimHistory(),this.events.onStatus("\u601D\u8003\u4E2D",`\u7B2C ${c+1} \u8F6E`);let{text:u,toolCalls:d}=await this.streamAssistant(r,0,new Set,i);if(r?.aborted){l(),this.events.onStatus("\u5DF2\u4E2D\u65AD");return}if(i.push({role:"assistant",content:u,toolCalls:d.length>0?d:void 0}),d.length===0){a(),this.events.onStatus("\u5C31\u7EEA");return}for(let h of d){let m=await this.runTool(h,r);if(i.push({role:"tool",content:m.content,toolCallId:h.id,name:h.name}),this.events.onToolEnd(h,m),r?.aborted){l(),this.events.onStatus("\u5DF2\u4E2D\u65AD");return}}}a(),this.events.onStatus("\u5DF2\u8FBE\u5DE5\u5177\u8C03\u7528\u4E0A\u9650",`\u6700\u591A ${o} \u8F6E`)}catch(c){if(l(),r?.aborted){this.events.onStatus("\u5DF2\u4E2D\u65AD");return}throw c}}async analyzeIntent(e,r){let s=this.config.intent?.prompt?.trim()||Pt,i=At(s,e),o="";try{let l=this.provider.chat({messages:[{role:"user",content:i}],tools:[],temperature:this.config.temperature,signal:r});for await(let c of l)c.type==="text"&&(o+=c.text)}catch(l){return r?.aborted||this.events.onNotice?.(`\u610F\u56FE\u5206\u6790\u8BF7\u6C42\u5931\u8D25\uFF08${H(l).split(`
|
|
129
129
|
`)[0]}\uFF09\uFF0C\u5DF2\u6309\u539F\u59CB\u8F93\u5165\u7EE7\u7EED\u3002`),null}let a=o.trim();return a.length>0?a:null}async streamAssistant(e,r=0,s=new Set,i=[],o=1){this.activeModel&&s.add(this.activeModel.id);let a=[{role:"system",content:this.systemPrompt},...this.buildConversation(i,o)],l="",c=[],u=!1;try{let d=this.provider.chat({messages:a,tools:Ar(),temperature:this.config.temperature,signal:e,onRetry:(h,m,p)=>{this.events.onStatus(`\u7F51\u7EDC\u4E2D\u65AD\uFF0C\u6B63\u5728\u91CD\u8BD5 (${h}/${m})`,H(p).split(`
|
|
130
130
|
`)[0])}});for await(let h of d){if(e?.aborted)break;switch(u=!0,h.type){case"text":l+=h.text,this.events.onText(h.text);break;case"reasoning":this.events.onReasoning?.(h.text);break;case"tool_call":c.push(h.toolCall);break;case"done":break}}return{text:l,toolCalls:c}}catch(d){if(e?.aborted)throw d;if(!u&&!e?.aborted&&o>=1&&Ee(d))return this.events.onStatus("\u4E0A\u4E0B\u6587\u8D85\u9650","\u5DF2\u6536\u655B\u5386\u53F2\uFF0C\u6B63\u5728\u91CD\u8BD5"),this.streamAssistant(e,r,s,i,rs);if(this.handleModelFailure(d,s,!u)&&r<ns)return this.streamAssistant(e,r+1,s,i,o);throw d}}handleModelFailure(e,r,s=!0){let i=this.activeModel;if(!i)return!1;let o=H(e).split(`
|
|
131
|
-
`)[0];if(Qe(e))return this.events.onNotice?.(`\u26A0 \u6A21\u578B ${i.id} \u7684\u914D\u7F6E\u53EF\u80FD\u6709\u8BEF\uFF08${o}\uFF09\u3002\u5DF2\u8DF3\u8FC7\u6743\u91CD\u8870\u51CF \u2014\u2014 \u8BF7\u68C0\u67E5 provider\u3001API Key \u4E0E baseUrl\u3002`),!1;let a=Lt(this.config,i.id);if(!a||(this.persistConfig(),a.reset?(this.events.onNotice?.(`\u26A0 \u6A21\u578B ${i.id} \u8C03\u7528\u5931\u8D25\uFF08${o}\uFF09\uFF1B\u6240\u6709\u6A21\u578B\u6743\u91CD\u5747\u5DF2\u8017\u5C3D\uFF0C\u5DF2\u628A\u5168\u90E8\u6743\u91CD\u91CD\u7F6E\u4E3A ${T}\u3002`),this.events.onStatus("\u6743\u91CD\u5DF2\u91CD\u7F6E")):this.events.onNotice?.(`\u26A0 \u6A21\u578B ${i.id} \u8C03\u7528\u5931\u8D25\uFF08${o}\uFF09\uFF0C\u6743\u91CD\u964D\u4E3A ${a.weight}\u3002`),this.events.onModelChange?.({provider:i.provider,model:i.model,weight:a.reset?T:a.weight,reason:"\u8C03\u7528\u5931\u8D25\u964D\u6743"}),!s))return!1;let l=Q(this.config,r);if(!l||l.id===i.id)return l&&(this.activeModel=l),!1;try{return this.provider=Ie(this.config,l),this.activeModel=l,this.events.onNotice?.(`\u21BB \u5DF2\u5207\u6362\u5230\u6A21\u578B ${l.id}\uFF08\u6743\u91CD ${l.weight}\uFF09\u91CD\u8BD5\u3002`),this.events.onModelChange?.({provider:l.provider,model:l.model,weight:l.weight,reason:"\u8C03\u7528\u5931\u8D25\u964D\u7EA7"}),!0}catch(c){return this.events.onNotice?.(`\u5207\u6362\u6A21\u578B\u5931\u8D25\uFF1A${H(c)}`),!1}}persistConfig(){try{k(this.config)}catch{}}touchesSensitivePath(e,r){if(!es.has(e))return!1;let s="";try{let a=JSON.parse(r);typeof a.path=="string"&&(s=a.path)}catch{return!1}if(!s)return!1;let i=he.resolve(this.cwd,F(s)),o=he.relative(this.cwd,i);return o&&(o.startsWith("..")||he.isAbsolute(o))?!0:ts.test(i)}async runTool(e,r){let s=$t(e.name);if(!s)return{ok:!1,content:`\u9519\u8BEF\uFF1A\u672A\u77E5\u5DE5\u5177 "${e.name}"`};if(this.touchesSensitivePath(s.name,e.arguments)||!!s.requiresConfirmation&&!this.config.autoApprove){let a=e.arguments;try{a=JSON.stringify(JSON.parse(e.arguments),null,2)}catch{}if(!await this.events.confirm({tool:e.name,title:`\u6267\u884C\u5DE5\u5177\uFF1A${e.name}`,detail:a,danger:!!s.danger}))return{ok:!1,denied:!0,content:"\u7528\u6237\u62D2\u7EDD\u4E86\u6B64\u64CD\u4F5C\u3002"}}if(r?.aborted)return{ok:!1,content:"\u64CD\u4F5C\u5DF2\u88AB\u4E2D\u65AD\u3002"};this.events.onToolStart(e);let o={cwd:this.cwd,autoApprove:this.config.autoApprove,emit:a=>this.events.onNotice?.(a),confirm:a=>this.events.confirm(a),signal:r};return Ir(e.name,e.arguments,o)}conversationBudget(){return ot(this.activeModel?.contextWindow,this.activeModel?.model??"",this.systemPrompt)}buildConversation(e,r=1){let s=[...this.history,...e],i=s.length>Dr?s.slice(-Dr):s,o=Math.max(1,Math.floor(this.conversationBudget()*r));return Pe(i,o)}trimHistory(){let e=Pe(this.history,this.conversationBudget());if(e.length===this.history.length)return 0;let r=this.history.length-e.length;return this.history=e,r}};var we="0.1.
|
|
131
|
+
`)[0];if(Qe(e))return this.events.onNotice?.(`\u26A0 \u6A21\u578B ${i.id} \u7684\u914D\u7F6E\u53EF\u80FD\u6709\u8BEF\uFF08${o}\uFF09\u3002\u5DF2\u8DF3\u8FC7\u6743\u91CD\u8870\u51CF \u2014\u2014 \u8BF7\u68C0\u67E5 provider\u3001API Key \u4E0E baseUrl\u3002`),!1;let a=Lt(this.config,i.id);if(!a||(this.persistConfig(),a.reset?(this.events.onNotice?.(`\u26A0 \u6A21\u578B ${i.id} \u8C03\u7528\u5931\u8D25\uFF08${o}\uFF09\uFF1B\u6240\u6709\u6A21\u578B\u6743\u91CD\u5747\u5DF2\u8017\u5C3D\uFF0C\u5DF2\u628A\u5168\u90E8\u6743\u91CD\u91CD\u7F6E\u4E3A ${T}\u3002`),this.events.onStatus("\u6743\u91CD\u5DF2\u91CD\u7F6E")):this.events.onNotice?.(`\u26A0 \u6A21\u578B ${i.id} \u8C03\u7528\u5931\u8D25\uFF08${o}\uFF09\uFF0C\u6743\u91CD\u964D\u4E3A ${a.weight}\u3002`),this.events.onModelChange?.({provider:i.provider,model:i.model,weight:a.reset?T:a.weight,reason:"\u8C03\u7528\u5931\u8D25\u964D\u6743"}),!s))return!1;let l=Q(this.config,r);if(!l||l.id===i.id)return l&&(this.activeModel=l),!1;try{return this.provider=Ie(this.config,l),this.activeModel=l,this.events.onNotice?.(`\u21BB \u5DF2\u5207\u6362\u5230\u6A21\u578B ${l.id}\uFF08\u6743\u91CD ${l.weight}\uFF09\u91CD\u8BD5\u3002`),this.events.onModelChange?.({provider:l.provider,model:l.model,weight:l.weight,reason:"\u8C03\u7528\u5931\u8D25\u964D\u7EA7"}),!0}catch(c){return this.events.onNotice?.(`\u5207\u6362\u6A21\u578B\u5931\u8D25\uFF1A${H(c)}`),!1}}persistConfig(){try{k(this.config)}catch{}}touchesSensitivePath(e,r){if(!es.has(e))return!1;let s="";try{let a=JSON.parse(r);typeof a.path=="string"&&(s=a.path)}catch{return!1}if(!s)return!1;let i=he.resolve(this.cwd,F(s)),o=he.relative(this.cwd,i);return o&&(o.startsWith("..")||he.isAbsolute(o))?!0:ts.test(i)}async runTool(e,r){let s=$t(e.name);if(!s)return{ok:!1,content:`\u9519\u8BEF\uFF1A\u672A\u77E5\u5DE5\u5177 "${e.name}"`};if(this.touchesSensitivePath(s.name,e.arguments)||!!s.requiresConfirmation&&!this.config.autoApprove){let a=e.arguments;try{a=JSON.stringify(JSON.parse(e.arguments),null,2)}catch{}if(!await this.events.confirm({tool:e.name,title:`\u6267\u884C\u5DE5\u5177\uFF1A${e.name}`,detail:a,danger:!!s.danger}))return{ok:!1,denied:!0,content:"\u7528\u6237\u62D2\u7EDD\u4E86\u6B64\u64CD\u4F5C\u3002"}}if(r?.aborted)return{ok:!1,content:"\u64CD\u4F5C\u5DF2\u88AB\u4E2D\u65AD\u3002"};this.events.onToolStart(e);let o={cwd:this.cwd,autoApprove:this.config.autoApprove,emit:a=>this.events.onNotice?.(a),confirm:a=>this.events.confirm(a),signal:r};return Ir(e.name,e.arguments,o)}conversationBudget(){return ot(this.activeModel?.contextWindow,this.activeModel?.model??"",this.systemPrompt)}buildConversation(e,r=1){let s=[...this.history,...e],i=s.length>Dr?s.slice(-Dr):s,o=Math.max(1,Math.floor(this.conversationBudget()*r));return Pe(i,o)}trimHistory(){let e=Pe(this.history,this.conversationBudget());if(e.length===this.history.length)return 0;let r=this.history.length-e.length;return this.history=e,r}};var we="0.1.4";var t={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",italic:"\x1B[3m",underline:"\x1B[4m",inverse:"\x1B[7m",black:"\x1B[30m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",magenta:"\x1B[35m",cyan:"\x1B[36m",white:"\x1B[37m",gray:"\x1B[90m",brightRed:"\x1B[91m",brightGreen:"\x1B[92m",brightYellow:"\x1B[93m",brightBlue:"\x1B[94m",brightMagenta:"\x1B[95m",brightCyan:"\x1B[96m",brightWhite:"\x1B[97m",bgRed:"\x1B[41m",bgGreen:"\x1B[42m",bgYellow:"\x1B[43m",bgBlue:"\x1B[44m",bgMagenta:"\x1B[45m",bgCyan:"\x1B[46m",bgGray:"\x1B[100m"},N={hide:"\x1B[?25l",show:"\x1B[?25h",up:(n=1)=>`\x1B[${n}A`,down:(n=1)=>`\x1B[${n}B`,right:(n=1)=>`\x1B[${n}C`,left:(n=1)=>`\x1B[${n}D`,to:(n,e)=>`\x1B[${n};${e}H`,col:n=>`\x1B[${n}G`,clearLine:"\x1B[2K",clearToEnd:"\x1B[0K",clearScreen:"\x1B[2J"},Fe={enterAlt:"\x1B[?1049h",exitAlt:"\x1B[?1049l",save:"\x1B[s",restore:"\x1B[u"};function ss(n){return n>=4352&&n<=4447||n>=11904&&n<=12350||n>=12353&&n<=13311||n>=13312&&n<=19903||n>=19968&&n<=40959||n>=40960&&n<=42191||n>=44032&&n<=55203||n>=63744&&n<=64255||n>=65072&&n<=65103||n>=65280&&n<=65376||n>=65504&&n<=65510||n>=127744&&n<=129791||n>=131072&&n<=262141}function P(n){let e=0;for(let r=0;r<n.length;r++){let s=n.codePointAt(r);if(s!==void 0){if(s===27){let i=/^\x1b\[[0-9;?]*[ -/]*[@-~]/.exec(n.slice(r));if(i){r+=i[0].length-1;continue}let o=/^\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)?/.exec(n.slice(r));if(o){r+=o[0].length-1;continue}}if(s>65535&&r++,s===9){e+=8-e%8;continue}s<32||s>=768&&s<=879||s>=8400&&s<=8447||s>=65024&&s<=65039||(e+=ss(s)?2:1)}}return e}function ve(n,e){let r=[];for(let s of n.split(`
|
|
132
132
|
`)){if(s===""){r.push("");continue}let i="",o=0,a=s.match(/\x1b\[[0-9;?]*[A-Za-z]|./gu)??[];for(let l of a){let c=P(l);o+c>e&&i!==""&&(r.push(i),i="",o=0),i+=l,o+=c}r.push(i)}return r}function K(n,e){if(P(n)<=e)return n;let r=n.match(/\x1b\[[0-9;?]*[A-Za-z]|[\s\S]/gu)??[],s="",i=0,o=Math.max(0,e-1);for(let a of r){let l=P(a);if(i+l>o)break;s+=a,i+=l}return`${s}${t.reset}\u2026`}function Nr(n,e){let r=P(n);return n+" ".repeat(Math.max(0,e-r))}function me(n){return n&&n.replace(/\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)?/g,"").replace(/\x1b\[[0-9;?]*[ -/]*[@-~]/g,"").replace(/\x1b[@-Z\\-_]/g,"").replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g,"")}var ze=class{buffer="";inCodeBlock=!1;codeLang="";push(e){this.buffer+=e;let r=[],s=this.buffer.indexOf(`
|
|
133
133
|
`);for(;s!==-1;){let i=this.buffer.slice(0,s);this.buffer=this.buffer.slice(s+1),r.push(this.renderLine(i)),s=this.buffer.indexOf(`
|
|
134
134
|
`)}return r}peek(){return this.buffer?this.inCodeBlock?`${t.cyan}${this.buffer}${t.reset}`:this.buffer:""}flush(){if(this.buffer.length===0)return this.inCodeBlock=!1,this.codeLang="",[];let e=this.buffer;this.buffer="";let r=this.renderLine(e);return this.inCodeBlock=!1,this.codeLang="",[r]}renderLine(e){let r=e.replace(/\r$/,""),s=r.trimStart();if(s.startsWith("```")){if(!this.inCodeBlock){this.inCodeBlock=!0,this.codeLang=s.slice(3).trim();let a=this.codeLang?` ${this.codeLang} `:"";return`${t.gray}\u250C\u2500${a}${"\u2500".repeat(Math.max(0,6-a.length))}${t.reset}`}return this.inCodeBlock=!1,this.codeLang="",`${t.gray}\u2514\u2500\u2500${t.reset}`}if(this.inCodeBlock)return`${t.cyan}${r}${t.reset}`;let i=/^(#{1,6})\s+(.*)$/.exec(s);if(i){let a=i[2];return i[1].length<=2?`${t.bold}${t.brightWhite}${a}${t.reset}`:`${t.bold}${a}${t.reset}`}if(s.startsWith("> "))return`${t.gray}\u2502 ${s.slice(2)}${t.reset}`;let o=/^(\s*)([-*+]|\d+\.)\s+(.*)$/.exec(r);return o?`${o[1]}${t.blue}${o[2]}${t.reset} ${o[3]}`:/^(-{3,}|\*{3,}|_{3,})$/.test(s)?`${t.gray}${"\u2500".repeat(20)}${t.reset}`:this.renderInline(r)}renderInline(e){let r=e;return r=r.replace(/`([^`]+)`/g,(s,i)=>`${t.cyan}${i}${t.reset}`),r=r.replace(/\*\*([^*]+)\*\*/g,(s,i)=>`${t.bold}${i}${t.reset}`),r=r.replace(/(^|\s)\*([^*\s][^*]*)\*(?=\s|$)/g,"$1$2"),r}};var Br=require("child_process"),pe=x(require("fs")),qe=x(require("os")),U=x(require("path"));var Kr=2e3,is=8192,os=1200,He=class{lines=[];partial="";running;killTimer;cwd;onChange;parseState="text";parseSeq="";constructor(e,r){this.cwd=e,this.onChange=r,this.pushLine(`${t.gray}\u7EC8\u7AEF\u5C31\u7EEA \xB7 \u547D\u4EE4\u5728\u5F53\u524D\u9879\u76EE\u76EE\u5F55\u4E0B\u6267\u884C${t.reset}`)}getCwd(){return this.cwd}isRunning(){return this.running!==void 0}setCwd(e){this.cwd=e,this.pushLine(`${t.gray}\u2500\u2500 \u5DE5\u4F5C\u76EE\u5F55\u5DF2\u5207\u6362\uFF1A${e}${t.reset}`),this.onChange()}clear(){this.lines=[],this.partial="",this.onChange()}notice(e){this.pushLine(e),this.onChange()}visibleLines(){return this.partial?[...this.lines,this.partial]:this.lines}run(e){let r=e.trim();if(!r)return;if(this.running){this.pushLine(`${t.yellow}\u26A0 \u4E0A\u4E00\u6761\u547D\u4EE4\u4ECD\u5728\u8FD0\u884C\uFF0C\u8BF7\u5148 Ctrl+C \u4E2D\u65AD${t.reset}`),this.onChange();return}if(r==="clear"||r==="cls"){this.clear();return}if(this.handleCd(r))return;this.flushPartial(),this.pushLine(`${t.brightGreen}\u276F${t.reset} ${t.bold}${r}${t.reset}`);let s=process.env.SHELL||"/bin/bash",i;try{i=(0,Br.spawn)(s,["-c",r],{cwd:this.cwd,env:{...process.env,TERM:"xterm-256color",CLICOLOR_FORCE:"1",FORCE_COLOR:"1"},stdio:["ignore","pipe","pipe"],detached:!0})}catch(a){this.pushLine(`${t.red}\u2717 \u542F\u52A8\u5931\u8D25\uFF1A${a instanceof Error?a.message:String(a)}${t.reset}`),this.onChange();return}this.running=i;let o=a=>this.feed(a.toString("utf8"));i.stdout?.on("data",o),i.stderr?.on("data",o),i.on("error",a=>{this.flushPartial(),this.pushLine(`${t.red}\u2717 \u6267\u884C\u51FA\u9519\uFF1A${a.message}${t.reset}`),this.running=void 0,this.onChange()}),i.on("close",(a,l)=>{this.flushPartial(),l?this.pushLine(`${t.yellow}\u23F9 \u5DF2\u4E2D\u65AD\uFF08${l}\uFF09${t.reset}`):a===0?this.pushLine(`${t.gray}\u2713 \u5B8C\u6210${t.reset}`):this.pushLine(`${t.red}\u2717 \u9000\u51FA\u7801 ${a}${t.reset}`),this.running=void 0,this.onChange()}),this.onChange()}interrupt(){let e=this.running;if(!e||e.pid===void 0)return;let r=e.pid,s=i=>{try{process.kill(-r,i)}catch{try{e.kill(i)}catch{}}};s("SIGINT"),this.killTimer&&clearTimeout(this.killTimer),this.killTimer=setTimeout(()=>{this.killTimer=void 0,this.running===e&&s("SIGKILL")},os)}dispose(){this.killTimer&&(clearTimeout(this.killTimer),this.killTimer=void 0);let e=this.running;if(this.running=void 0,!(!e||e.pid===void 0))try{process.kill(-e.pid,"SIGKILL")}catch{try{e.kill("SIGKILL")}catch{}}}handleCd(e){let r=/^cd(?:\s+([\s\S]*))?$/.exec(e);if(!r)return!1;let s=(r[1]??"").trim().replace(/^['"]|['"]$/g,""),i;if(!s||s==="~")i=qe.homedir();else{let o=s.startsWith("~/")?U.join(qe.homedir(),s.slice(2)):s;i=U.isAbsolute(o)?o:U.resolve(this.cwd,o)}try{if(!pe.statSync(i).isDirectory())return this.pushLine(`${t.red}cd: \u4E0D\u662F\u76EE\u5F55\uFF1A${i}${t.reset}`),this.onChange(),!0}catch{return this.pushLine(`${t.red}cd: \u76EE\u5F55\u4E0D\u5B58\u5728\uFF1A${i}${t.reset}`),this.onChange(),!0}return this.cwd=i,this.flushPartial(),this.pushLine(`${t.gray}cd ${this.cwd}${t.reset}`),this.onChange(),!0}feed(e){let r=e.replace(/\r\n/g,`
|
package/package.json
CHANGED
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xuanzhu",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "玄猪(XuanZhu)— 专为终端打造的 AI 编码 Agent",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
7
7
|
"agent",
|
|
8
|
-
"terminal",
|
|
9
|
-
"tui",
|
|
10
8
|
"cli",
|
|
11
|
-
"
|
|
9
|
+
"tui",
|
|
10
|
+
"coding-assistant",
|
|
11
|
+
"llm",
|
|
12
|
+
"terminal"
|
|
12
13
|
],
|
|
13
14
|
"license": "MIT",
|
|
14
15
|
"author": "amble311",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/amble311/xuanzhu.git"
|
|
19
|
+
},
|
|
20
|
+
"homepage": "https://github.com/amble311/xuanzhu#readme",
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/amble311/xuanzhu/issues"
|
|
23
|
+
},
|
|
15
24
|
"main": "./dist/cli.js",
|
|
16
25
|
"bin": {
|
|
17
26
|
"xzh": "bin/xzh.js"
|