@aiwayds/dsh-tui-pi 1.0.0 → 1.0.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.
- package/README.md +106 -429
- package/README.zh-CN.md +105 -409
- package/cordis.patch.yml +11 -0
- package/lib/index.js +0 -22
- package/lib/index.js.map +1 -1
- package/package.json +2 -1
- package/lib/model-sync.d.ts +0 -122
- package/lib/model-sync.js +0 -256
- package/lib/model-sync.js.map +0 -1
package/README.zh-CN.md
CHANGED
|
@@ -1,222 +1,109 @@
|
|
|
1
|
-
English | [简体中文](README.zh-CN.md)
|
|
1
|
+
[English](README.md) | [简体中文](README.zh-CN.md)
|
|
2
2
|
|
|
3
3
|
# dsh-tui-pi
|
|
4
4
|
|
|
5
|
-
[DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(dsh)的 pi 风格终端 UI
|
|
5
|
+
面向 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(dsh)的 pi 风格终端 UI——一套把 dsh 变成 pi 式编码代理体验的插件套件:pi-tui 的外观与交互、dsh 斜杠命令、GitHub 明/暗主题和 powerline 状态栏。
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
`executeCommand()` 兼容 shim(`src/commands.ts`),在运行时探测
|
|
9
|
-
`dsh-commands` 的 `execute()` 参数个数——同时支持 rc.8 之前的 3 参形式
|
|
10
|
-
`(agent, line, signal)` 与当前的 4 参形式 `(agent, line, images, signal)`
|
|
11
|
-
(自 `0.1.0-rc.8` 起未再变化)。经单元测试与 tmux 真机 e2e 冒烟验证。
|
|
12
|
-
|
|
13
|
-
> 中文说明:本文件为英文 [README.md](README.md) 的简体中文翻译。
|
|
14
|
-
|
|
15
|
-
## 截图
|
|
7
|
+
**兼容性**:已针对 dsh `0.1.1-rc.2` 测试;斜杠命令在 `dsh-commands` 的 `execute()` 签名变更(rc.8 之前的 3 参 → 当前的 4 参)下依然可用。
|
|
16
8
|
|
|
17
9
|
https://github.com/user-attachments/assets/6a7e00bb-1fd0-4bc5-9070-457f1e9fa54d
|
|
18
10
|
|
|
19
|
-
|
|
20
|
-
([asciinema 交互播放](https://asciinema.org/a/BE212ZO8x1zEZyZn))
|
|
11
|
+
*一次真实 session 的实况录制(MP4,1.5× 速度)——todos、运行中的 subagents、think/tool 面板和 powerline footer 的实际效果。*
|
|
21
12
|
|
|
22
|
-
|
|
13
|
+
## ✨ 功能亮点
|
|
23
14
|
|
|
24
|
-
|
|
25
|
-
┌─────────────────────────────────────────────────────────────────────┐
|
|
26
|
-
│ Transcript(可滚动对话区) │
|
|
27
|
-
│ ┌─────────────────────────────────────────────────────────────┐ │
|
|
28
|
-
│ │ 💭 thinking — reasoning in progress │ │
|
|
29
|
-
│ └─────────────────────────────────────────────────────────────┘ │
|
|
30
|
-
│ ⚙ bash python scripts/demo.py … ✔ bash │
|
|
31
|
-
│ ↳ 生成 2 个 todo, 每个 todo 起一个 10s 的 subagent │
|
|
32
|
-
│ ↳ ⠼ Workhorse 10s 任务 · 1.2k token · 19.0s │
|
|
33
|
-
└─────────────────────────────────────────────────────────────────────┘
|
|
34
|
-
┌─ ● Todos (0/8) ────────────────────────────────────────────────────┐
|
|
35
|
-
│ ├─ ☑ 调研 dsh-tui-pi 斜杠命令/补全机制 │
|
|
36
|
-
│ ├─ ◐ 调研 harness ctx.skills API │
|
|
37
|
-
│ └─ ☐ 实现 /skill:<name> 补全并触发 skill │
|
|
38
|
-
└─────────────────────────────────────────────────────────────────────┘
|
|
39
|
-
∴ working… │
|
|
40
|
-
~/github (Full access) │ ⎇ main │
|
|
41
|
-
[ 请输入指令… ] │
|
|
42
|
-
↳ 第一 打slash 命令的时候 显示 /skill:<skill name> 选择后使用 │
|
|
43
|
-
↳ ⠼ 牛马狗 · 1.5m/1m · 635.7s │
|
|
44
|
-
dsh ▸ volc-ark-plan ▸ deepseek-v4-flash ▸ high ▸ 48.7k/1.0M(4.6%) │
|
|
45
|
-
▸ ⚡ CH85.4% ▸ 15 msgs ▸ 11 tools 00:02:13 │
|
|
46
|
-
Esc ×2: stop · Ctrl+C ×2: quit · Ctrl+G: subagents · ↑↓: history │
|
|
47
|
-
└─────────────────────────────────────────────────────────────────────┘
|
|
48
|
-
│ │ │
|
|
49
|
-
│ │ └─ Footer(powerline 状态栏)
|
|
50
|
-
│ └─ 运行中的 subagent(last-request 区域)
|
|
51
|
-
└─ Todos 面板(有边框,固定在编辑器上方)
|
|
52
|
-
```
|
|
15
|
+
> 每一项都链接到下文对应小节——一句话讲清楚它能给你什么。
|
|
53
16
|
|
|
54
|
-
|
|
17
|
+
- [**Footer——会话实时总览**](#footer-状态栏) — provider/model、上下文压力与会话缓存命中率一眼看清,始终在视线内。
|
|
18
|
+
- [**Think 与 Tool 面板**](#think-与-tool-面板) — 推理和工具活动不进对话记录,对话读起来干净清爽。
|
|
19
|
+
- [**Subagents 子代理**](#subagents-子代理) — 每个运行中的 subagent 都有一行状态;实时观看并操控它。
|
|
20
|
+
- [**Ask User Question**](#ask-user-question-向用户提问) — 模型可以暂停下来向你提结构化问题,无需离开 TUI 即可作答。
|
|
21
|
+
- [**飞书集成演示**](#飞书集成演示) — 桌面上的 dsh-tui-pi 与手机上的飞书/Lark 驱动(并代答)同一个 dsh session。
|
|
22
|
+
- [**Dynamic context pruning (DCP)**](#dynamic-context-pruning-dcp) — 上下文自动保持在限制内,零 LLM 调用。
|
|
23
|
+
- [**Persistent context 持久上下文**](#persistent-context-持久上下文) — 你的基本规则随每次请求生效,热应用无需重启。
|
|
24
|
+
- [**模型 profile 与收藏**](#模型-profile-与收藏) — 按项目整体切换一套模型配置,并让选择器保持精简。
|
|
25
|
+
- [**Sessions 会话与恢复**](#sessions-会话与恢复) — 会话自动保持整洁,几次按键即可恢复。
|
|
26
|
+
- [**Themes 主题**](#themes-主题) — GitHub 明/暗配色,热切换;`auto` 跟随你的终端。
|
|
55
27
|
|
|
56
|
-
|
|
28
|
+
---
|
|
57
29
|
|
|
58
|
-
|
|
30
|
+
## Footer 状态栏
|
|
59
31
|
|
|
60
|
-
|
|
32
|
+
一个 session 所有关键数字——provider/model 路由、推理等级、上下文占用、消息与工具计数,外加实时时钟——都收在钉于屏幕底部的同一条 powerline 状态栏里,编辑器顶部边框则显示你的工作目录和 git 分支。不用离开终端,就能看到成本压力(context %、cache-hit %)和实时活动。
|
|
61
33
|
|
|
62
34
|
```
|
|
63
35
|
dsh ▸ volc-ark-plan ▸ deepseek-v4-flash ▸ high ▸ 48.7k/1.0M(4.6%) ▸ ⚡ CH85.4% ▸ 15 msgs ▸ 11 tools 00:02:13
|
|
64
36
|
```
|
|
65
37
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
| 分段 | 内容 |
|
|
69
|
-
|---|---|
|
|
70
|
-
| **Provider** | 当前 `provider/model` 路由 |
|
|
71
|
-
| **Model** | 模型简称 |
|
|
72
|
-
| **Thinking** | 推理强度等级(`off` / `high` / `max`) |
|
|
73
|
-
| **Context** | `已用 / 上限 (百分比%)` |
|
|
74
|
-
| **Cache-hit** | `CHxx%` —— prompt 缓存命中率 |
|
|
75
|
-
| **Messages** | user + assistant 消息总数 |
|
|
76
|
-
| **Tools** | 工具调用总数 |
|
|
77
|
-
| **Clock** | 右对齐实时 HH:MM:SS(每秒刷新) |
|
|
78
|
-
|
|
79
|
-
分段用 [U+E0B0](https://www.nerdfonts.com/cheat-sheet) powerline 箭头渲染;配色随当前主题热切换。
|
|
80
|
-
|
|
81
|
-
编辑器顶部边框显示工作目录和 git 分支:
|
|
82
|
-
|
|
83
|
-
```
|
|
84
|
-
~/github (Full access) │ ⎇ main
|
|
85
|
-
```
|
|
38
|
+
**Cache-hit(`CHxx%`)** 是会话的缓存命中率——会话全部计费输入流量中由 prompt 缓存供给的占比。它按整个 session 累计(切换 provider/model 不会重置),并且只有会话实际计费过缓存 token 后才会显示。(布局见 [ARCHITECTURE.md](ARCHITECTURE.md)。)
|
|
86
39
|
|
|
87
40
|
---
|
|
88
41
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
进行中的思考和工具调用渲染为**固定面板,钉在聊天输入框上方**(永远不会出现在可滚动的 transcript 里):
|
|
42
|
+
## Think 与 Tool 面板
|
|
92
43
|
|
|
93
|
-
|
|
94
|
-
┌─ 💭 thinking ──────────────────────────────────────────────┐
|
|
95
|
-
│ Actually, I can check list_agents or wait… │
|
|
96
|
-
└────────────────────────────────────────────────────────────┘
|
|
97
|
-
⚙ bash python scripts/demo.py … ✔ bash
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
行为要点:
|
|
101
|
-
|
|
102
|
-
- **每种类型只有一个面板** —— 整个运行期间只有一个 `ThinkPanel` 和一个 `ToolPanel`;每个事件原地刷新面板,不会刷屏 transcript。
|
|
103
|
-
- **空 = 隐藏** —— 无活动时面板渲染 0 行并消失。
|
|
104
|
-
- **`dsh-tui.panelHeight`**(默认 `1`):一行无边框(块 id + 耗时 + 最后一行内容,右截断);`5`/`7`/`10` 渲染带边框面板;`all` 输出完整内容。
|
|
105
|
-
- **委派类工具**(`use_agent`、`subagent`、`workflow`、`ralph`)不打开工具面板——它们的子任务以运行中 agent 行的形式显示(见 Subagents)。
|
|
44
|
+
实时推理和工具调用渲染为**钉在聊天输入框上方**的固定面板,而不是滚进对话记录,因此对话线程始终可读。面板只在有活动时才出现,高度可配置(`dsh-tui.panelHeight`:`1` 行,`5`/`7`/`10` 行带边框,或 `all`)。
|
|
106
45
|
|
|
107
46
|
---
|
|
108
47
|
|
|
109
|
-
|
|
48
|
+
## Subagents 子代理
|
|
110
49
|
|
|
111
|
-
运行中的 subagent
|
|
112
|
-
|
|
113
|
-
```
|
|
114
|
-
↳ 创建 2 个 todo, 每个 todo 起一个 10s 的 subagent
|
|
115
|
-
↳ ⠼ Subagent A 10s 任务 · 1.2k token · 19.0s
|
|
116
|
-
↳ ⠼ Subagent B 10s 任务 · 562 token · 6.0s
|
|
117
|
-
```
|
|
50
|
+
运行中的 subagent 以紧凑的单行状态显示在编辑器下方——名称、上下文占用、rounds、已耗时——不用打开任何东西就能看到委派情况。`Ctrl+G`(或 `/subagents`)打开实时 transcript 查看器;在查看器内按 `Enter` 即可给子代理发消息 steer。`● Todos` 面板把你的任务树钉在输入框上方。上限(`maxAgents`、`maxRounds`,经 `/agents` → `l` 配置)防止委派失控。
|
|
118
51
|
|
|
119
|
-
|
|
52
|
+
---
|
|
120
53
|
|
|
121
|
-
|
|
54
|
+
## Ask User Question 向用户提问
|
|
122
55
|
|
|
123
|
-
|
|
56
|
+
模型在一轮回答进行到一半时可以暂停,通过 `ask_user_question` 工具向你提结构化问题;应答侧是停靠在输入框上方的面板——不用来回切换窗口。一次一个问题,其余收进标签页;`Ctrl+T` 把面板折叠起来,双击 `Esc` 拒绝作答。自由文本、多选、多问题确认页、bracket-paste,以及右键 / `Ctrl+Shift+C` 从系统剪贴板粘贴,全都支持。
|
|
124
57
|
|
|
125
|
-
|
|
58
|
+
看看 ask-question 流程的实际效果:
|
|
126
59
|
|
|
127
|
-
|
|
128
|
-
┌─ ● Todos (0/8) ──────────────────────────────────────────┐
|
|
129
|
-
│ ├─ ☑ Todo 1: research subagent spawn API │
|
|
130
|
-
│ ├─ ◐ Todo 2: implement /skill:<name> autocomplete │
|
|
131
|
-
│ └─ ☐ Todo 3: add settings panel skills branch │
|
|
132
|
-
└───────────────────────────────────────────────────────────┘
|
|
133
|
-
```
|
|
60
|
+
https://github.com/user-attachments/assets/aa36be36-a508-4f53-ba85-efe0394dab11
|
|
134
61
|
|
|
135
|
-
|
|
62
|
+
---
|
|
136
63
|
|
|
137
|
-
|
|
64
|
+
## 飞书集成演示
|
|
138
65
|
|
|
139
|
-
|
|
66
|
+
桌面上的 dsh-tui-pi 与手机上的飞书/Lark 驱动(并代答)同一个 dsh session:
|
|
140
67
|
|
|
141
|
-
|
|
68
|
+
https://github.com/user-attachments/assets/177e8839-523b-487e-b3d1-6d725cd8aba5
|
|
142
69
|
|
|
143
|
-
|
|
70
|
+
https://github.com/user-attachments/assets/c0d7092f-deda-4443-b75a-2bc93bd30d86
|
|
144
71
|
|
|
145
|
-
-
|
|
146
|
-
- **`maxRounds`**(默认 75,`0` = 无限制)—— 子代理的 assistant 消息数(每次 LLM 往返计一条,即"rounds")达到上限后,TUI 注入一条收尾指令且从不强制终止:运行中的子代理在其下一个 step 边界收到(`steer` —— 即下一次 LLM 往返),空闲的子代理作为自己的下一个 turn 收到。注入是可见的:紧凑行、Ctrl+G 选择器行和查看器头部都会显示 `⚡` 标记,transcript 把注入的消息渲染为 `⚡ <文本>`——这样就能区分子代理 LLM 无视了收尾指令与注入从未发生这两种情况。
|
|
72
|
+
演示来自 [dsh-feishu Demos issue](https://github.com/fan56/dsh-feishu/issues/1)。
|
|
147
73
|
|
|
148
74
|
---
|
|
149
75
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
[DCP](https://github.com/fan56/dsh-dcp) 是 dsh 的独立零 LLM 压缩(compaction)插件——自动修剪上下文以保持在限制内,无需调用 LLM 做摘要。
|
|
76
|
+
## Dynamic context pruning (DCP)
|
|
153
77
|
|
|
154
|
-
|
|
78
|
+
上下文自动保持在模型窗口内:[dsh-dcp](https://github.com/fan56/dsh-dcp) 压缩 session **无需调用 LLM 做摘要**。挂载一次即透明运行——footer 的 context 段随压缩回落;在 subagent 内部,每次提交的压缩都会在查看器中以 `🧹` 提示显示。
|
|
155
79
|
|
|
156
80
|
```sh
|
|
157
81
|
dsh plugin --profile tui add @aiwayds/dsh-dcp
|
|
158
82
|
```
|
|
159
83
|
|
|
160
|
-
挂载后 DCP 在后台透明运行。footer 的 **Context** 分段计算的是当前占用——最近一次请求的 billed context 加上其后消息的 CJK 估算——所以压缩之后下一次请求会变小,显示随之回落(百分比封顶 100,窗口是硬上限)。**Cache-hit** 分段反映当前 provider/model 路由的缓存复用率——命中率按路由分段分别计算,provider 或 model 变化时归零(在下一条 billed 消息到来前隐藏)。
|
|
161
|
-
|
|
162
|
-
在 subagent 内部,已提交的压缩同样可见:DCP 在子代理自己的日志里为每次压缩追加一行 `user/message` **notice**,Ctrl+G 的 transcript 用 `🧹` 标记渲染它(区别于通用的 `ⓘ`),选择器行的描述里带有该子代理的压缩次数(描述中的 `🧹 N×`)。DCP 的 `roundInterval` 与 TUI 的 `maxRounds` 数的是**同一样东西**——`assistant/message` 事件,每次 LLM 往返计一条——但行为不同:子代理计数达到 `maxRounds` 时 TUI 排队发一个收尾请求;会话计数达到 `roundInterval` 后 DCP 在下一个空闲边界执行压缩(修剪上下文)。一个触发工作,一个释放上下文。
|
|
163
|
-
|
|
164
84
|
---
|
|
165
85
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
一份用户可编辑的 markdown 文件,其内容会追加到**本 TUI 创建的主 agent 的 system prompt 末尾**——借鉴 pi 的 `~/.pi/agent/APPEND_SYSTEM.md` 约定,dsh 侧对应 `$DSH_HOME/APPEND_SYSTEM.md`(默认 `~/.dsh/APPEND_SYSTEM.md`,沿用 dsh 其余部分共用的 `$DSH_HOME` 覆盖机制)。
|
|
169
|
-
|
|
170
|
-
- **热应用** —— section 提供者在每次组装 prompt 时读盘,改完文件**下一次请求**即生效:无需重启、无需 watcher、无需 `/reload`。
|
|
171
|
-
- **首次运行自动播种** —— 文件不存在时,TUI 启动时一次性从随包模板 `templates/APPEND_SYSTEM.md` 创建(英文版 orchestrator 身份模板:身份、核心规则、执行工作流——含「subagent 仅指已注册 subagents」的用语规则)。已有文件归用户所有——TUI 永远不会覆盖用户内容;只在文件尚未包含带标记的 todo-lifecycle section 时追加该段,以及(按短语匹配、幂等地)在尚未出现 subagents 规则措辞时追加之。
|
|
172
|
-
- **TUI 自有 section** —— 一个带标记的 block(`<!-- dsh-tui-pi:todo-lifecycle -->`)只追加一次,之后幂等维护,确保模型在所有条目完成时清空自己的 `todo/write` 列表。已带标记的文件后续启动保持逐字节不变。
|
|
173
|
-
- **旧版迁移** —— 同一段 todo block 过去是通过 `~/.dsh/AGENTS.md` 下发的。启动时 TUI 一次性把它剥掉(不存在时 no-op),避免重复下发。
|
|
174
|
-
- **空 / 读不到 = 无 section** —— 文件缺失或读不了时该 section 被静默丢弃。无报错,不影响 TUI 启动。
|
|
175
|
-
|
|
176
|
-
#### 作用范围:仅主 agent
|
|
86
|
+
## Persistent context 持久上下文
|
|
177
87
|
|
|
178
|
-
|
|
88
|
+
`$DSH_HOME/APPEND_SYSTEM.md`(默认 `~/.dsh/APPEND_SYSTEM.md`,pi 约定)会追加到**主 agent** 的 system prompt 末尾并热应用——编辑文件后下一条请求就能看到,无需重启。TUI 首次运行时从模板播种该文件,幂等维护其带标记的 todo-lifecycle 段,并且绝不覆盖你的内容。子代理被刻意排除在外。
|
|
179
89
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
```sh
|
|
183
|
-
# 首次启动从 templates/APPEND_SYSTEM.md 自动播种 —— 打开直接编辑即可。
|
|
184
|
-
$EDITOR ~/.dsh/APPEND_SYSTEM.md
|
|
90
|
+
---
|
|
185
91
|
|
|
186
|
-
|
|
187
|
-
# todo-lifecycle section —— 缺失时会重新追加)。
|
|
188
|
-
cat > ~/.dsh/APPEND_SYSTEM.md <<'EOF'
|
|
189
|
-
# Project ground rules
|
|
92
|
+
## 模型 profile 与收藏
|
|
190
93
|
|
|
191
|
-
-
|
|
192
|
-
- Prefer dispatching `workhorse` for multi-step investigations.
|
|
193
|
-
EOF
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
没有开关此功能的斜杠命令——它始终开启,完全由文件内容控制。
|
|
94
|
+
`/profile-switch` 一次选择切换整套配置——默认模型、推理等级、以及每个 subagent 的模型;`p` 把某个 profile 钉到当前目录,该目录树下的每个新 session 都会加载它。`/model` 的收藏与隐藏列表让选择器保持精简。用 `/profile-cfg` 管理 profile(名录、编辑、保存当前、重命名、删除)。
|
|
197
95
|
|
|
198
96
|
---
|
|
199
97
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
模型在一轮回答中途可以暂停下来,通过 `ask_user_question` 工具向你提出结构化问题(`@deepseek-ai/dsh-tool-ask-user`,由本 profile 的 bundle patch 挂载)。TUI 承载应答侧:一个有边框的面板钉在聊天输入框正上方(Todos 面板的槽位——不是浮动的 popup),打开期间接管键盘,工具调用保持 pending 直到你作答,你的答案作为普通的 tool result 流回模型。
|
|
98
|
+
## Sessions 会话与恢复
|
|
203
99
|
|
|
204
|
-
|
|
100
|
+
`/resume` 用几次按键恢复任意最近的 session(按最后更新排序),`/new` 开启新会话,`/export` 把会话日志写成 JSONL(`~/Downloads/dsh-session-<id>.jsonl`)。启动清理器(`dsh-tui.retention.*`)修剪旧的会话日志,存储不会无界增长;resume 选择器只显示工作集(`dsh-tui.resume.*`)。两者都可在 `~/.dsh/settings.yaml` 配置,并带环境变量覆盖。
|
|
205
101
|
|
|
206
|
-
|
|
102
|
+
---
|
|
207
103
|
|
|
208
|
-
|
|
209
|
-
- **Ctrl+T 把面板折叠成 3 行小条** —— 你思考问题时,questions 面板可能挡住叠在其下的 transcript;Ctrl+T 把它折叠成边框 + 一行摘要(阶段、tab 位置、已答数量、如何展开),同一按键再次展开。折叠期间只有切换键和 Esc 链生效;编辑中途折叠会像 ↑↓ 离开一样提交缓冲区。
|
|
210
|
-
- **单问题快速通道** —— 孤立的单选问题在 Enter 时立即提交:选选项或输入自由文本回车都会立刻提交(无选项的问题靠打字即可作答)。孤立的多选问题则会得到一个 `⏎ Confirm answers` 行,让你先勾选多个选项再提交。
|
|
211
|
-
- **多问题确认页** —— ≥ 2 个问题时出现 `⏎ Confirm answers` 行,跳转到列出全部答案的 review 页,每一行都可原位编辑(跳回去会把焦点切回那个问题的 tab);`Submit answers` 提交(有答案缺失时在其上按 Enter 会闪烁提示而不是静默失败)。
|
|
212
|
-
- **双击 Esc 表示拒绝作答** —— 200ms 内两次 Esc 返回 declined envelope(模型读到的是一条正常的回复,表示未给出答案);长按不会误触发(低于最小间隔的按键自动重复被忽略);工具调用被中止时也按 declined 结算。面板打开期间像打开的 overlay 一样独占键盘:Esc 永远不会进入运行任务的停止链,app 快捷键(Ctrl+L/G/O、Tab)也让位于面板。
|
|
213
|
-
- **节制使用引导** —— 一段 system-prompt 引导模型只在真正需要你时才提问(1–3 个问题,每个 2–4 个选项),避免 TUI 变成问卷调查。
|
|
214
|
-
- **键盘操作** —— `←→` 切换问题标签 · `↑↓` 导航 · `Enter` 选择/勾选/确认 · 在 sentinel 行打字输入自由文本 · `Ctrl+T` 折叠/展开面板 · 连按两次 `Esc` 拒绝作答。
|
|
215
|
-
- **向 sentinel 粘贴内容(bracket-paste)** —— 开启了 `?2004` 的终端会把多行剪贴板内容作为一个 bracket-paste 块一次性送入;sentinel 会把 `CR`/`LF`/`CRLF` 的任何连续折成单个空格、丢弃 C0/C1 控制字节、把 tab 展开为四个空格、缓冲上限 16 KiB —— 一段粘进去的段落会变成一串空格分隔的 run,绝不会出现一堆换行符。
|
|
216
|
-
- **编辑中右键 = 直接从系统剪贴板粘贴** —— TUI 在 SGR 右键 press 抵达 pi-tui 之前就把它截走(pi-tui 否则会开始一次选中拖拽),然后通过 `wl-paste`/`xclip`/`xsel`/`pbpaste`/PowerShell 把系统剪贴板内容塞进 sentinel 缓冲区;该辅助是 fire-and-forget,缺剪贴板工具就静默 no-op,同时 OSC 52 写回并行运行,使宿主终端自带的 paste 在本地工具缺失时也能工作。
|
|
217
|
-
- **`Ctrl+Shift+C` 把 sentinel 缓冲区复制到系统剪贴板** —— kitty-CSI-u 编码 `\x1b[<codepoint>;<modifier>u`(modifier 6 = ctrl+shift+1)会通过 OSC 52 *和* `pbcopy`/`wl-copy`/`xclip`/`xsel`/`clip` 并行写入;面板下方会出现一个短暂的 `Copied` 提示以示确认;空缓冲区是静默 no-op。*已知限制:* Apple Terminal 会把 `Ctrl+Shift+C` 映射成它自己的复制动作,kitty 序列根本到不了我们这里,结果就是 app 内复制被当成普通 `Ctrl+C` = 退出编辑;在 tmux 下需要 `set-clipboard on`(配合对应的 `set-option` 让 pane 也通过),OSC 52 序列才能透传到宿主终端。
|
|
104
|
+
## Themes 主题
|
|
218
105
|
|
|
219
|
-
|
|
106
|
+
GitHub 明/暗配色,`/theme` 热切换;`auto` 检测你的终端并跟随实时的明/暗切换。`DSH_TUI_THEME=light|dark` 钉选一套配色,`DSH_TUI_TRANSPARENT=1` 让画布透出终端背景,`DSH_TUI_MOUSE=buttons|all|off` 调节鼠标追踪。
|
|
220
107
|
|
|
221
108
|
---
|
|
222
109
|
|
|
@@ -224,26 +111,31 @@ https://github.com/user-attachments/assets/aa36be36-a508-4f53-ba85-efe0394dab11
|
|
|
224
111
|
|
|
225
112
|
| 命令 | 功能 |
|
|
226
113
|
|---|---|
|
|
227
|
-
| `/model` | 两阶段 provider/model
|
|
228
|
-
| `/think` |
|
|
229
|
-
| `/session` |
|
|
230
|
-
| `/resume` |
|
|
231
|
-
| `/new` | 分离当前 session
|
|
232
|
-
| `/settings` | 文本式设置浏览器(命名空间、schema
|
|
233
|
-
| `/export` |
|
|
114
|
+
| `/model` | 两阶段 provider/model 选择器 + 推理等级;`f` 收藏、`h` 隐藏、`/` 过滤(持久化)。 |
|
|
115
|
+
| `/think` | 推理强度选择器(`Off`/`High`/`Max`)。 |
|
|
116
|
+
| `/session` | 只读信息:id、cwd、model、token 用量、事件数。 |
|
|
117
|
+
| `/resume` | 选择持久化的 session(新的在前),校验日志后恢复。 |
|
|
118
|
+
| `/new` | 分离当前 session;下一条 prompt 开启新会话。 |
|
|
119
|
+
| `/settings` | 文本式设置浏览器(命名空间、schema 遍历、密钥脱敏)。 |
|
|
120
|
+
| `/export` | 把当前会话日志写成 JSONL。 |
|
|
234
121
|
| `/permission` | 权限预设选择器(read-only / workspace-write / danger-full-access)。 |
|
|
235
|
-
| `/theme` |
|
|
236
|
-
| `/preset` | agent preset 选择器;`<name>` 直接切换,`next`
|
|
237
|
-
| `/profile-switch` |
|
|
238
|
-
| `/profile-cfg` |
|
|
122
|
+
| `/theme` | 配色选择器(`auto`/`light`/`dark`),立即生效。 |
|
|
123
|
+
| `/preset` | agent preset 选择器;`<name>` 直接切换,`next` 循环(同 `Tab`)。 |
|
|
124
|
+
| `/profile-switch` | 把模型 profile 应用到当前选择、持久化默认值和 agent 文件;`p` 钉住当前目录。 |
|
|
125
|
+
| `/profile-cfg` | 管理 profile:编辑默认模型 / think / 各 agent 模型,`s` 保存当前,`n` 新建,`r` 重命名,`d` 删除。 |
|
|
239
126
|
| `/agents` | 管理 agent markdown 文件 + subagent 上限(`maxAgents`、`maxRounds`)。 |
|
|
240
|
-
| `/subagents` | 选择运行中/最近的 subagent 并观看其实时 transcript
|
|
241
|
-
| `/
|
|
242
|
-
| `/
|
|
243
|
-
| `/
|
|
244
|
-
| `/
|
|
127
|
+
| `/subagents` | 选择运行中/最近的 subagent 并观看其实时 transcript;`Enter` steer。 |
|
|
128
|
+
| `/skills` | 管理用户 skills(已安装与可用)。 |
|
|
129
|
+
| `/reload` | `pnpm build` 后从源码热重载插件。 |
|
|
130
|
+
| `/login` | 登录 provider(或 `/login openai`);**Custom provider…** 添加任意 OpenAI/Anthropic 兼容网关。 |
|
|
131
|
+
| `/logout` | 删除 provider 的已存 key 与 profile。 |
|
|
132
|
+
| `/hotkeys` | 快捷键浏览器与实时编辑器。 |
|
|
133
|
+
|
|
134
|
+
手工声明(baseURL)provider 的模型列表自动同步不再是内置命令:由独立的
|
|
135
|
+
`@aiwayds/dsh-model-sync` 插件(本包的默认依赖)按自己的节奏保持这些路由的
|
|
136
|
+
模型列表最新。
|
|
245
137
|
|
|
246
|
-
|
|
138
|
+
其余内容作为普通 prompt 落给模型;dsh 原生命令(`plan`、`compact`、`feedback`、`goal`……)原样可用。
|
|
247
139
|
|
|
248
140
|
---
|
|
249
141
|
|
|
@@ -252,216 +144,60 @@ https://github.com/user-attachments/assets/aa36be36-a508-4f53-ba85-efe0394dab11
|
|
|
252
144
|
| 按键 | 功能 |
|
|
253
145
|
|---|---|
|
|
254
146
|
| `Enter` | 发送 prompt |
|
|
255
|
-
| `Esc` |
|
|
256
|
-
| `Ctrl+C` |
|
|
147
|
+
| `Esc` | **双击停止**(单击进入待发状态;有 popup 打开时改为关闭它) |
|
|
148
|
+
| `Ctrl+C` | 对话中:第一次取消当前轮次,第二次退出;空闲时:清空编辑器 / 退出。长按自动重复绝不会触发退出。 |
|
|
257
149
|
| `Ctrl+D` | 退出(仅在编辑器为空时) |
|
|
258
150
|
| `Ctrl+L` | 打开 model/think 选择器 |
|
|
259
|
-
| `Ctrl+G` | 打开 subagent
|
|
260
|
-
| `
|
|
261
|
-
|
|
|
262
|
-
|
|
263
|
-
### 自定义快捷键
|
|
264
|
-
|
|
265
|
-
通过 `~/.dsh/keybindings.json` 重映射任意 app 按键——一个部分 JSON 映射表,键为 app 按键、值为按键 id(`ctrl+letter`、`alt+letter`、命名键)。可手动编辑,或用 `/hotkeys` 交互式修改(实时生效,无需重启)。
|
|
266
|
-
|
|
267
|
-
---
|
|
268
|
-
|
|
269
|
-
## Agent presets
|
|
270
|
-
|
|
271
|
-
部署提供了 `standard` agent preset 时,TUI 启动即选中它;否则选中扫描到的第一项。这只是本地选择:在你操作 `/preset` 或按 `Tab` 之前,创建 session 时不会发送任何 `meta.agentPreset`,因此仍由服务端默认值(`agent-presets.default`)决定。footer 品牌段反映本地选择(`dsh(<name>)`);一次切换在下一个空白 session 生效。
|
|
272
|
-
|
|
273
|
-
---
|
|
274
|
-
|
|
275
|
-
## 主题
|
|
276
|
-
|
|
277
|
-
GitHub light / GitHub dark 配色,运行时热切换:
|
|
278
|
-
|
|
279
|
-
- `/theme` —— 实时选择器;整个屏幕重绘(含背景)。
|
|
280
|
-
- `DSH_TUI_THEME=light|dark` —— 环境变量钉选,优先于偏好设置。
|
|
281
|
-
- `DSH_TUI_TRANSPARENT=1` —— 透明画布(终端背景透出)。
|
|
282
|
-
- `DSH_TUI_MOUSE=buttons|all|off` —— 终端鼠标追踪模式(默认 `buttons`:点击/滚轮/拖选继续可用,空闲指针移动不上报;`all` = pi-tui 的全动作追踪,cmux 下其事件突发可能漏进编辑器;`off` = 关闭鼠标)。
|
|
283
|
-
- `auto` 模式检测终端并跟随实时的明暗切换。
|
|
151
|
+
| `Ctrl+G` | 打开 subagent 选择器(查看器内 `Enter` 打开 steer) |
|
|
152
|
+
| `Ctrl+O` | 待发消息队列(`s` 立即 steer · `d` 移除) |
|
|
153
|
+
| `Tab` | 循环切换 agent preset |
|
|
154
|
+
| `↑` / `↓` | 浏览已提交消息历史 |
|
|
284
155
|
|
|
285
|
-
|
|
156
|
+
通过 `~/.dsh/keybindings.json`(部分 JSON 映射,实时应用)或 `/hotkeys` 交互式重映射任意 app 按键。
|
|
286
157
|
|
|
287
158
|
---
|
|
288
159
|
|
|
289
|
-
##
|
|
160
|
+
## 配置
|
|
290
161
|
|
|
291
|
-
|
|
292
|
-
(`~/.dsh/settings.yaml`),各配一个环境变量逃生口:
|
|
162
|
+
会话存储相关的旋钮位于 `~/.dsh/settings.yaml` 的 `dsh-tui` settings 命名空间下(每个也都有环境变量覆盖,`DSH_TUI_RETENTION_*` / `DSH_TUI_RESUME_*`;优先级:settings.yaml > env > 默认值):
|
|
293
163
|
|
|
294
164
|
```yaml
|
|
295
165
|
dsh-tui:
|
|
296
|
-
# ~/.dsh/sessions
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
# /resume 显示过滤器 —— 只隐藏选择器行,从不删除。
|
|
304
|
-
# 每次打开选择器时重新解析(改设置对下一次 /resume 生效,
|
|
305
|
-
# 无需重启)。
|
|
306
|
-
resume:
|
|
307
|
-
maxAgeDays: 7 # 只显示日志活动在此窗口内的 session(> 0)
|
|
308
|
-
minBytes: 20480 # 一行的最小压缩后日志大小(>= 0)
|
|
166
|
+
retention: # ~/.dsh/sessions 的启动清理器——删除旧日志。每次启动跑一次。
|
|
167
|
+
maxCount: 100 # <= 0 关闭清理器
|
|
168
|
+
maxAgeDays: 7
|
|
169
|
+
minIdleHours: 24
|
|
170
|
+
resume: # /resume 显示过滤器——只隐藏选择器行,从不删除。
|
|
171
|
+
maxAgeDays: 7
|
|
172
|
+
minBytes: 20480
|
|
309
173
|
```
|
|
310
174
|
|
|
311
|
-
|
|
312
|
-
/ `DSH_TUI_RETENTION_MAX_AGE_DAYS` / `DSH_TUI_RETENTION_MIN_IDLE_HOURS`
|
|
313
|
-
与 `DSH_TUI_RESUME_MAX_AGE_DAYS` / `DSH_TUI_RESUME_MIN_BYTES`
|
|
314
|
-
环境变量 > 上述默认值。非法的 settings 值经由共享 notice bridge 弹出一条瞬态提示
|
|
315
|
-
(没有注册 TUI sink 时被静默丢弃——headless 运行永不打印)并回落到下一层;
|
|
316
|
-
非法的环境变量值则静默回落——一个 typo 既不会扩大也不会架空策略。`maxCount`
|
|
317
|
-
与 `minBytes` 在每一层都必须是整数(小数的上限或字节门槛是垃圾数据,
|
|
318
|
-
不是窗口)。
|
|
319
|
-
|
|
320
|
-
**完全关闭 retention** —— 对于要 read-attach 旧 session 的常驻进程
|
|
321
|
-
(远程 bridge、headless cron 运行),默认窗口会把它们裁掉:
|
|
322
|
-
|
|
323
|
-
```yaml
|
|
324
|
-
dsh-tui:
|
|
325
|
-
retention:
|
|
326
|
-
maxCount: 0 # 或:DSH_TUI_RETENTION_MAX_COUNT=0
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
时机:**retention 只在启动时跑一次**(从不在会话中途;`/reload`
|
|
330
|
-
不会重跑它——下一次冷启动才会),而 **resume 过滤器在每次 `/resume`
|
|
331
|
-
打开时生效**。两处 `7` 默认出自同一个「一周即工作集」决策,
|
|
332
|
-
但服务对象不同——retention 删除日志,resume 过滤器只隐藏行。
|
|
175
|
+
其他旋钮:`dsh-tui.panelHeight`(think/tool 面板高度)、`dsh-tui.iconSet`(`auto`/`nerdfont`/`plain`——powerline 字形自适应你的字体;用 `node scripts/install-font.mjs` 安装 Nerd Font)、`~/.dsh/keybindings.json`(按键重映射)。
|
|
333
176
|
|
|
334
177
|
---
|
|
335
178
|
|
|
336
|
-
##
|
|
337
|
-
|
|
338
|
-
TUI 唯一的私有区(PUA)字形是 footer 的 powerline 分隔符(U+E0B0)——
|
|
339
|
-
没有哪个默认终端字体自带它,没装 Nerd/Powerline 字体的终端会显示豆腐块。
|
|
340
|
-
`dsh-tui.iconSet` 设置(`auto` | `nerdfont` | `plain`,默认 `auto`)让危险字形
|
|
341
|
-
(U+E0B0、⏹、⭘)自适应终端:
|
|
342
|
-
|
|
343
|
-
- `auto` —— 启动时探测到 Nerd/Powerline 字体就用 powerline 字形,
|
|
344
|
-
否则用安全的 Unicode 替代(`▸ ■ ●`)。
|
|
345
|
-
- `nerdfont` —— 始终用 powerline 字形(你已经设好字体了)。
|
|
346
|
-
- `plain` —— 始终用安全替代,无需任何字体。
|
|
347
|
-
|
|
348
|
-
**一键安装内置字体**(安装 + 把终端指过去,保留你的字号):
|
|
349
|
-
|
|
350
|
-
```sh
|
|
351
|
-
node scripts/install-font.mjs
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
脚本把 `assets/fonts/dsh-tui-pi-nerd.ttf`(约 170KB 的子集:ASCII +
|
|
355
|
-
U+E0B0 + TUI 渲染的每一个符号)拷进用户字体目录,并尽力翻转终端设置:
|
|
356
|
-
macOS iTerm2(PlistBuddy,默认 bookmark)、Linux GNOME Terminal
|
|
357
|
-
(gsettings)以及 kitty/alacritty/wezterm(改配置文件,先备份)。
|
|
358
|
-
Terminal.app 被刻意跳过(它的字体是二进制 blob)——请手动设置。
|
|
359
|
-
每一步都有防护:失败只记录警告并继续,绝不破坏性地改动你的配置。
|
|
360
|
-
|
|
361
|
-
**或者手动设置终端字体** —— 任意 Nerd Font 家族设为终端主字体即可
|
|
362
|
-
(如 JetBrainsMono Nerd Font、Hack Nerd Font,或安装后的内置
|
|
363
|
-
`DSH TUI Nerd`):iTerm2 → Settings → Profiles → Text → Font;
|
|
364
|
-
Terminal.app → Settings → Profiles → Text;kitty → `font_family`;
|
|
365
|
-
alacritty → `[font] family`;wezterm → `wezterm.font("…")`。
|
|
366
|
-
下次启动时 `auto` 就会解析成 powerline 字形。
|
|
367
|
-
|
|
368
|
-
---
|
|
369
|
-
|
|
370
|
-
## 安装(本地)
|
|
371
|
-
|
|
372
|
-
`tui` profile 从 npm registry 安装本插件——profile 的 `package.json`
|
|
373
|
-
钉住 `"@aiwayds/dsh-tui-pi": "<version>"`,由 pnpm 像普通依赖一样解析。
|
|
374
|
-
发版后升级 profile:
|
|
375
|
-
|
|
376
|
-
```sh
|
|
377
|
-
node scripts/dev-upgrade.mjs # 最新版
|
|
378
|
-
node scripts/dev-upgrade.mjs 0.15.1 --dry-run # 先预览执行计划
|
|
379
|
-
```
|
|
380
|
-
|
|
381
|
-
脚本先在 registry 校验版本存在,然后只更新
|
|
382
|
-
`~/.dsh/profiles/tui/package.json` 里的 `"@aiwayds/dsh-tui-pi"` 一个键
|
|
383
|
-
(保格式的 read-modify-write),在该目录执行 `pnpm install`,最后校验
|
|
384
|
-
安装副本报告的版本与目标一致。绝不碰 `~/.dsh/settings.yaml` 或
|
|
385
|
-
`.credentials.yaml`。重启 dsh(或在 TUI 内 `/reload`)加载新副本。
|
|
386
|
-
|
|
387
|
-
## 安装(npm)
|
|
388
|
-
|
|
389
|
-
在全新 profile 里安装完整的 dsh 插件套件:
|
|
179
|
+
## 安装与启用
|
|
390
180
|
|
|
391
181
|
```sh
|
|
392
182
|
dsh plugin --profile tui add @aiwayds/dsh-tui-pi
|
|
393
|
-
dsh plugin --profile tui add @aiwayds/dsh-subagent-registry
|
|
394
|
-
dsh plugin --profile tui add @aiwayds/dsh-dcp
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
然后启动:
|
|
398
|
-
|
|
399
|
-
```sh
|
|
400
|
-
dsh --profile tui
|
|
183
|
+
dsh plugin --profile tui add @aiwayds/dsh-subagent-registry # optional
|
|
184
|
+
dsh plugin --profile tui add @aiwayds/dsh-dcp # optional
|
|
185
|
+
dsh --profile tui # 启动(或:dsh-tui-pi)
|
|
401
186
|
```
|
|
402
187
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
- dsh 通过 `reconcilePlugins` 把三个插件注册进 `dsh.profile.bundles`。
|
|
406
|
-
- dsh 在 profile 的 `pnpm-workspace.yaml` 里设置 `autoInstallPeers: false`。
|
|
407
|
-
- 首次启动时 dsh 调用 `healProfilesModuleFallback`,在
|
|
408
|
-
`~/.dsh/profiles/node_modules/@deepseek-ai/*` 下创建软链指向全局 dsh
|
|
409
|
-
闭包(`$(which dsh)/../../node_modules/@deepseek-ai`)。这让所有插件共享
|
|
410
|
-
同一个 `@deepseek-ai/cordis` 实例——无需手动搭建闭包。
|
|
411
|
-
- `compaction-basic` 被 `@aiwayds/dsh-dcp` 的补丁禁用;dsh-dcp 接管成为
|
|
412
|
-
compaction 后端。
|
|
413
|
-
|
|
414
|
-
**不会自动发生的事:**
|
|
415
|
-
|
|
416
|
-
- 不再有补丁相关的事:自 0.8.0 起,仓库和 npm 包运行同一个原版
|
|
417
|
-
`@earendil-works/pi-tui`——画布背景由我们自己的写流装饰器(BCE)
|
|
418
|
-
绘制,随包内置,消费方 profile 不需要任何 `pnpm-workspace.yaml` 条目。
|
|
419
|
-
|
|
420
|
-
### 故障排查
|
|
421
|
-
|
|
422
|
-
| 症状 | 原因 | 修复 |
|
|
423
|
-
|---|---|---|
|
|
424
|
-
| `Cannot find package '<name>' imported from ~/.dsh/profiles/...` | 某 bundle 的 `cordis.patch.yml` 的 `name` 字段与 scoped 包名不匹配。 | 更新插件;所有 `@aiwayds/*` 插件的补丁现在都用 `name: '@aiwayds/<pkg>'`。 |
|
|
425
|
-
| npm 安装的 dsh 报 `Cannot find package '@deepseek-ai/dsh-client-schema-form'` | npm 分发的 dsh 闭包缺这个包(上游打包缺口——[deepseek-harness discussion #3471](https://github.com/deepseek-ai/deepseek-harness/discussions/3471))。 | 本插件自 0.8.1 起已修(辅助函数 vendored,不再 import 缺失的包)。需要它的其他插件:`cd ~/.dsh/profiles/<profile> && pnpm add @deepseek-ai/dsh-client-schema-form@next`。 |
|
|
426
|
-
| `Cannot read properties of undefined (reading 'prepare')` | 出现重复的 `@deepseek-ai/cordis` 模块实例(profile 树里有两份物理副本)。 | 见 AGENTS.md 铁律 8。删除物理副本 `~/.dsh/profiles/tui/node_modules/@deepseek-ai` 并让 dsh heal 兜底:`rm -rf ~/.dsh/profiles/tui/node_modules/@deepseek-ai && dsh --profile tui`(heal 会重建为软链)。 |
|
|
427
|
-
| pnpm 提示 `Peer dependencies that should be installed: @deepseek-ai/...` | 某插件把 `@deepseek-ai/*` 放进了普通 `dependencies` 而非 `peerDependencies`。 | 更新插件(所有 `@aiwayds/*` dsh 插件都用 optional peerDeps)。警告无害——pnpm 不会自动安装 optional peers。 |
|
|
428
|
-
| pnpm 提示 `Ignored build scripts: @aiwayds/dsh-tui-pi@...` | pnpm 10 默认阻止 build 脚本,tui-pi 的 postinstall(`link-dsh-closure.mjs`)被跳过。 | 这是预期且**无害**的——postinstall 只影响仓库开发流,不影响 npm 消费者。闭包链接由 dsh 的 `healProfilesModuleFallback` 处理。 |
|
|
429
|
-
|
|
430
|
-
---
|
|
431
|
-
|
|
432
|
-
## 使用
|
|
188
|
+
过去需要手工 patch 的一切——画布背景、`@deepseek-ai` 模块闭包、compaction 后端——现在都自动完成。发版后升级现有 profile:
|
|
433
189
|
|
|
434
190
|
```sh
|
|
435
|
-
|
|
191
|
+
node scripts/dev-upgrade.mjs # 最新版
|
|
192
|
+
node scripts/dev-upgrade.mjs 1.0.2 --dry-run # 先预览执行计划
|
|
436
193
|
```
|
|
437
194
|
|
|
438
195
|
---
|
|
439
196
|
|
|
440
|
-
## Companion plugins
|
|
441
|
-
|
|
442
|
-
- **[@aiwayds/dsh-ask-router](https://www.npmjs.com/package/@aiwayds/dsh-ask-router)**
|
|
443
|
-
(作为默认依赖附带)。独占唯一的 `ctx.userQuestions` provider 槽位,
|
|
444
|
-
把每个 `ask_user_question` 扇出到绑定到提问 session 的各个交互面——
|
|
445
|
-
第一个答案获胜,落败的交互面自动关闭。激活方式是在 profile 的 `bundles`
|
|
446
|
-
里把 `@aiwayds/dsh-ask-router` 列在**任何 UI bundle 之前**;没有它时
|
|
447
|
-
TUI 面板独自接管问题。
|
|
448
|
-
- **[@aiwayds/dsh-feishu](https://github.com/fan56/dsh-feishu)**(可选)。
|
|
449
|
-
用手机上的飞书/Lark 驱动已有的 dsh session:轮次卡片、交互式 `/resume`
|
|
450
|
-
选择器,以及加入 router 扇出的 ask-user **卡片面**——桌面上提问,
|
|
451
|
-
手机上作答,或两边同时呈现而第一个答案获胜。想要手机侧参与时装进同一
|
|
452
|
-
profile;纯桌面环境可跳过。绝不把 router 装进 **web** profile
|
|
453
|
-
(上游 web apiproxy 注册自己的 provider,不容忍重复)。
|
|
454
|
-
|
|
455
|
-
### 飞书集成演示
|
|
197
|
+
## Companion plugins 伴生插件
|
|
456
198
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
https://github.com/user-attachments/assets/177e8839-523b-487e-b3d1-6d725cd8aba5
|
|
461
|
-
|
|
462
|
-
https://github.com/user-attachments/assets/c0d7092f-deda-4443-b75a-2bc93bd30d86
|
|
463
|
-
|
|
464
|
-
演示来自 [dsh-feishu Demos issue](https://github.com/fan56/dsh-feishu/issues/1)。
|
|
199
|
+
- [@aiwayds/dsh-ask-router](https://www.npmjs.com/package/@aiwayds/dsh-ask-router) —— 作为默认依赖附带;把每个 `ask_user_question` 扇出到所有应答面(TUI 面板、飞书卡片),第一个答案获胜。把它加进 profile 的 `bundles`,放在任何 UI bundle 之前即可激活。
|
|
200
|
+
- [@aiwayds/dsh-feishu](https://github.com/fan56/dsh-feishu) —— 可选;用手机上的飞书/Lark 驱动同一个 dsh session,包括 ask-user 卡片面。想手机侧参与就装进同一个 profile。
|
|
465
201
|
|
|
466
202
|
---
|
|
467
203
|
|
|
@@ -470,63 +206,23 @@ https://github.com/user-attachments/assets/c0d7092f-deda-4443-b75a-2bc93bd30d86
|
|
|
470
206
|
```sh
|
|
471
207
|
pnpm check # tsc --noEmit
|
|
472
208
|
pnpm build # 输出 lib/
|
|
473
|
-
pnpm test # 单元测试,node --test 对 lib/ 执行(
|
|
209
|
+
pnpm test # 单元测试,node --test 对 lib/ 执行(pretest 构建;55 个文件共 1020 个测试)
|
|
474
210
|
```
|
|
475
211
|
|
|
476
|
-
|
|
477
|
-
dsh 闭包(`/opt/homebrew/lib/node_modules/@deepseek-ai/dsh/node_modules`);
|
|
478
|
-
这些 symlink 不会打入任何 tarball。`scripts/link-dsh-closure.mjs`
|
|
479
|
-
(包的 `postinstall`)在每次 `pnpm install` 后重建所有链接。
|
|
480
|
-
|
|
481
|
-
**pi-tui**:npm 上的原版 `@earendil-works/pi-tui` 0.84.2——无补丁、
|
|
482
|
-
无 fork。全屏画布背景由我们自己的写流装饰器实现
|
|
483
|
-
(`src/canvas-terminal.ts`,BCE)。
|
|
484
|
-
|
|
485
|
-
---
|
|
486
|
-
|
|
487
|
-
## 目录结构
|
|
488
|
-
|
|
489
|
-
```
|
|
490
|
-
bin/dsh-tui-pi launcher shim(exec dsh --profile tui)
|
|
491
|
-
cordis.patch.yml bundle patch:将插件挂载为 `tui-pi`
|
|
492
|
-
src/
|
|
493
|
-
index.ts cordis plugin 入口:命令注册、footer、
|
|
494
|
-
git watcher、时钟、bridge、主题热切换、shutdown
|
|
495
|
-
tui.ts alt-screen 树、transcript ScrollView、dock、canvas 背景
|
|
496
|
-
session.ts DshSessionBridge:agent 创建、followup、resume、
|
|
497
|
-
O(1) 增量统计、subagent tracker
|
|
498
|
-
live-widgets.ts Todos 面板 + 运行中 agent 活动行
|
|
499
|
-
messages.ts TranscriptRenderer:session 事件 → pi-tui 组件、
|
|
500
|
-
流式 setText、高度可配置面板
|
|
501
|
-
footer.ts PowerlineFooter(7 分段 + 时钟)
|
|
502
|
-
editor.ts CwdBorderEditor(顶部边框:cwd + git 分支)
|
|
503
|
-
subagent-policy.ts maxAgents 守卫 + maxRounds 收尾注入
|
|
504
|
-
(运行中走 steer;⚡ 标记,查看器可见)
|
|
505
|
-
subagent-viewer.ts Ctrl+G 选择器 + 实时 transcript 面板 + Enter steer 注入
|
|
506
|
-
ask-user.ts Ask User Question 停靠面板:纯状态 reducer +
|
|
507
|
-
带边框 overlay UI + ctx.userQuestions provider
|
|
508
|
-
steer-flow.ts Steer / follow-up 决策层:带竞态兜底的路由投递、
|
|
509
|
-
队列操作(remove / promote)、通知
|
|
510
|
-
route-dialog.ts 提交路由对话框(排队为 follow-up 还是立即 steer):
|
|
511
|
-
纯 key reducer + 带边框 overlay
|
|
512
|
-
queue-panel.ts Ctrl+O 待发消息队列:d remove · s steer now,
|
|
513
|
-
实时刷新 overlay
|
|
514
|
-
theme/ GitHub light/dark 配色 + 终端检测
|
|
515
|
-
test/*.test.mjs 单元测试(757 个,覆盖 44 个文件)
|
|
516
|
-
```
|
|
212
|
+
`pi-tui` 从 npm 原样运行——无补丁、无 fork。铁律与质量门禁见 [AGENTS.md](AGENTS.md)。
|
|
517
213
|
|
|
518
214
|
---
|
|
519
215
|
|
|
520
|
-
##
|
|
216
|
+
## 文档索引
|
|
521
217
|
|
|
522
|
-
|
|
218
|
+
- [ARCHITECTURE.md](ARCHITECTURE.md) —— 完整设计:进程模型、分层、数据流。
|
|
219
|
+
- [HANDOFF.md](HANDOFF.md) —— 会话历史与当前状态(中文)。
|
|
220
|
+
- [CHANGELOG.md](CHANGELOG.md) —— 发布历史。
|
|
221
|
+
- [AGENTS.md](AGENTS.md) —— 贡献者的工作约定与质量门禁。
|
|
222
|
+
- [docs/](docs/) —— 设计笔记(steer/follow-up 流程、showcase 草稿……)。
|
|
523
223
|
|
|
524
224
|
---
|
|
525
225
|
|
|
526
226
|
## 致谢
|
|
527
227
|
|
|
528
|
-
|
|
529
|
-
[juicesharp/rpiv-ask-user-question](https://github.com/juicesharp/rpiv-ask-user-question) ——
|
|
530
|
-
其交互设计(编号选项列表 + 自由文本 sentinel、多问题 review 页、拒绝手势;
|
|
531
|
-
后来又重构为一次一个问题的 tab 视图加可折叠小条)被适配到了本 TUI 的
|
|
532
|
-
停靠面板架构与 dsh `userQuestions` provider 架构上。这里的全部代码均为原创。
|
|
228
|
+
[Ask User Question](#ask-user-question-向用户提问) 交互的灵感来自 [juicesharp/rpiv-ask-user-question](https://github.com/juicesharp/rpiv-ask-user-question)(改编自本 TUI 的停靠面板与 dsh `userQuestions` provider 架构;这里的全部代码均为原创)。
|