@runminton/pi-tidy-tools 0.1.3 → 0.2.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 +40 -11
- package/README.zh-CN.md +40 -11
- package/package.json +2 -3
- package/tidy-tools.ts +150 -33
- package/CHANGELOG.md +0 -16
package/README.md
CHANGED
|
@@ -2,31 +2,44 @@
|
|
|
2
2
|
|
|
3
3
|
A tidy tool-rendering extension for [Pi](https://github.com/earendil-works/pi-mono) (the pi-coding-agent TUI). It overrides the rendering of `bash`, `edit` and `write`: compact summaries by default, full official rendering when you need it.
|
|
4
4
|
|
|
5
|
+
> Display layer only. Tool execution is fully delegated to Pi's official implementations — parameters, behavior and results are untouched; the extension only decides how many rows to draw and in which colors.
|
|
6
|
+
|
|
5
7
|
[中文版](README.zh-CN.md)
|
|
6
8
|
|
|
7
9
|
## Default view
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
All three tools start **Collapsed**:
|
|
10
12
|
|
|
11
|
-
| Tool |
|
|
13
|
+
| Tool | Collapsed summary | Expanded |
|
|
12
14
|
|---|---|---|
|
|
13
|
-
| `bash` |
|
|
14
|
-
| `edit` |
|
|
15
|
-
| `write` |
|
|
15
|
+
| `bash` | `$ command` plus one output line, with an inline `... (N more lines)` suffix when truncated | complete output |
|
|
16
|
+
| `edit` | `edit path (N blocks)` + `applied +a -b` | Pi's official renderer: path, block count, live diff preview, native layout |
|
|
17
|
+
| `write` | `write path (N lines)` + `done` | Pi's official renderer: path, line count, syntax-highlighted content |
|
|
18
|
+
|
|
19
|
+
Collapsed summaries are single-line per slot: one command line plus one output line (the count suffix is inline at the end of the output line).
|
|
20
|
+
|
|
21
|
+
## Modes
|
|
16
22
|
|
|
17
|
-
|
|
23
|
+
| Mode | Behavior |
|
|
24
|
+
|---|---|
|
|
25
|
+
| compact (default) | all three tools collapsed |
|
|
26
|
+
| markdown (`/tidy-markdown` toggles) | `edit`/`write` on Markdown files (`.md`, `.mdx`, `.markdown`) expand to full content; everything else stays collapsed |
|
|
27
|
+
|
|
28
|
+
Switching modes clears per-tool manual toggles and re-renders existing rows. The mode is not persisted across restarts.
|
|
18
29
|
|
|
19
30
|
## Shortcuts
|
|
20
31
|
|
|
21
|
-
|
|
32
|
+
On Mac press `Command+Option+letter` (verified; maps to the registered `Ctrl+Alt+letter`. Other platforms press `Ctrl+Alt+letter`):
|
|
33
|
+
|
|
34
|
+
| Shortcut (Mac) | Tool | Toggles between |
|
|
22
35
|
|---|---|---|
|
|
23
|
-
| `
|
|
24
|
-
| `
|
|
25
|
-
| `
|
|
36
|
+
| `Command+Option+B` | `bash` | collapsed summary ↔ **one-key full output** |
|
|
37
|
+
| `Command+Option+E` | `edit` | official rendering ↔ collapsed summary |
|
|
38
|
+
| `Command+Option+W` | `write` | official rendering ↔ collapsed summary |
|
|
26
39
|
|
|
27
40
|
A notification shows the current state on each toggle; press again to switch back.
|
|
28
41
|
|
|
29
|
-
`bash`
|
|
42
|
+
`bash` and `write` expand to the **complete output** in one keypress — they skip Pi's built-in previews (bash's 5-line tail preview, write's 10-line preview). `edit` expands to Pi's **official rendering** (it has no preview state). The global `Ctrl+O` tool expansion does not affect these three tools.
|
|
30
43
|
|
|
31
44
|
## Commands
|
|
32
45
|
|
|
@@ -37,6 +50,7 @@ Use these commands when terminal shortcuts conflict or are not delivered:
|
|
|
37
50
|
| `/tidy-bash` | Toggle `bash` output |
|
|
38
51
|
| `/tidy-edit` | Toggle `edit` output |
|
|
39
52
|
| `/tidy-write` | Toggle `write` output |
|
|
53
|
+
| `/tidy-markdown` | Toggle markdown mode (edit/write expand for Markdown files) |
|
|
40
54
|
|
|
41
55
|
## Usage
|
|
42
56
|
|
|
@@ -73,6 +87,21 @@ If a shortcut still does nothing on your machine, check:
|
|
|
73
87
|
3. **Custom keys.** The bindings are registered in `tidy-tools.ts` via `pi.registerShortcut(...)` — edit the key strings there to rebind. Pi's built-in global expansion (`Ctrl+O`, `app.tools.expand`) is configured separately via `~/.pi/agent/keybindings.json`.
|
|
74
88
|
4. **Inspect the input.** Run `/tidy-key-debug`, then press one target shortcut. Pi shows the received bytes and any rewrite. If no notification appears, the terminal or input method consumed the key before Pi received it.
|
|
75
89
|
|
|
90
|
+
## Changelog
|
|
91
|
+
|
|
92
|
+
### 0.2.0
|
|
93
|
+
|
|
94
|
+
- All three tools collapsed by default (edit/write used to expand)
|
|
95
|
+
- New `/tidy-markdown`: edit/write on Markdown files auto-expand to full content, the rest stays collapsed; switching modes clears manual toggles
|
|
96
|
+
- Write expansion skips the official 10-line preview and shows full content; global `Ctrl+O` no longer affects any of the three tools
|
|
97
|
+
- Bash collapsed output is 2 rows with the count suffix inline, including error output
|
|
98
|
+
- Fixed tab-width overflow wrapping collapsed bash output on narrow terminals; fixed doubled edit padding from a nested render shell
|
|
99
|
+
|
|
100
|
+
### 0.1.3
|
|
101
|
+
|
|
102
|
+
- New `/tidy-bash`, `/tidy-edit`, `/tidy-write`, `/tidy-key-debug` commands
|
|
103
|
+
- Normalized the legacy `ESC` + control-character shortcut form
|
|
104
|
+
|
|
76
105
|
## Development
|
|
77
106
|
|
|
78
107
|
```bash
|
package/README.zh-CN.md
CHANGED
|
@@ -2,31 +2,44 @@
|
|
|
2
2
|
|
|
3
3
|
为 [Pi](https://github.com/earendil-works/pi-mono)(pi-coding-agent 的 TUI)打造的工具渲染精简扩展。它覆盖了 `bash`、`edit`、`write` 的渲染:默认呈现紧凑摘要,需要时切换为官方完整渲染。
|
|
4
4
|
|
|
5
|
+
> 只动显示层,不动执行层。三个工具的执行完全委托 Pi 官方实现,参数、行为、结果一字不差;插件只决定屏幕上画几行、用什么颜色。
|
|
6
|
+
|
|
5
7
|
[English](README.md)
|
|
6
8
|
|
|
7
9
|
## 默认视图
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
三个工具默认**全部折叠**:
|
|
10
12
|
|
|
11
|
-
| 工具 |
|
|
13
|
+
| 工具 | 折叠摘要 | 展开 |
|
|
12
14
|
|---|---|---|
|
|
13
|
-
| `bash` |
|
|
14
|
-
| `edit` |
|
|
15
|
-
| `write` |
|
|
15
|
+
| `bash` | `$ command` 加一行输出预览,计数后缀 `... (N more lines)` 内联在行尾 | 完整输出 |
|
|
16
|
+
| `edit` | `edit 路径(N blocks)` + `applied +a -b` | Pi 官方渲染:路径、修改块数、实时 diff 预览、原生布局 |
|
|
17
|
+
| `write` | `write 路径(N lines)` + `done` | Pi 官方渲染:路径、行数、语法高亮内容 |
|
|
18
|
+
|
|
19
|
+
折叠摘要每槽单行:命令 1 行加输出 1 行(计数后缀内联在输出行尾)。
|
|
20
|
+
|
|
21
|
+
## 模式
|
|
16
22
|
|
|
17
|
-
|
|
23
|
+
| 模式 | 行为 |
|
|
24
|
+
|---|---|
|
|
25
|
+
| compact(默认) | 三工具全折叠 |
|
|
26
|
+
| markdown(`/tidy-markdown` 切换) | Markdown 文件(`.md`、`.mdx`、`.markdown`)的 `edit`/`write` 展开全文,其余照样折叠 |
|
|
27
|
+
|
|
28
|
+
切换模式会清空各工具的手动钉选并重渲染已有行。模式不持久化,重启后回到 compact。
|
|
18
29
|
|
|
19
30
|
## 快捷键
|
|
20
31
|
|
|
21
|
-
|
|
32
|
+
Mac 上按 `Command+Option+字母`(实测有效,对应插件注册的 `Ctrl+Alt+字母`;其他平台按 `Ctrl+Alt+字母`):
|
|
33
|
+
|
|
34
|
+
| 快捷键(Mac) | 工具 | 切换内容 |
|
|
22
35
|
|---|---|---|
|
|
23
|
-
| `
|
|
24
|
-
| `
|
|
25
|
-
| `
|
|
36
|
+
| `Command+Option+B` | `bash` | 折叠摘要 ↔ **一键完整输出** |
|
|
37
|
+
| `Command+Option+E` | `edit` | 官方渲染 ↔ 折叠摘要 |
|
|
38
|
+
| `Command+Option+W` | `write` | 官方渲染 ↔ 折叠摘要 |
|
|
26
39
|
|
|
27
40
|
每次切换会弹出通知提示当前状态;再按一次切回。
|
|
28
41
|
|
|
29
|
-
`bash` 展开时**一次按键直接显示完整输出**——跳过 Pi
|
|
42
|
+
`bash` 和 `write` 展开时**一次按键直接显示完整输出**——跳过 Pi 内置预览(bash 的 5 行尾部预览、write 的 10 行预览)。`edit` 展开时使用 Pi **官方渲染**(它没有预览态)。全局 `Ctrl+O` 对这三个工具均无效。
|
|
30
43
|
|
|
31
44
|
## 命令
|
|
32
45
|
|
|
@@ -37,6 +50,7 @@
|
|
|
37
50
|
| `/tidy-bash` | 切换 `bash` 输出 |
|
|
38
51
|
| `/tidy-edit` | 切换 `edit` 输出 |
|
|
39
52
|
| `/tidy-write` | 切换 `write` 输出 |
|
|
53
|
+
| `/tidy-markdown` | 切换 Markdown 模式(Markdown 文件的 edit/write 展开) |
|
|
40
54
|
|
|
41
55
|
## 使用方法
|
|
42
56
|
|
|
@@ -73,6 +87,21 @@ Pi 会在终端支持时协商 [Kitty 键盘协议](https://sw.kovidgoyal.net/ki
|
|
|
73
87
|
3. **自定义按键。** 绑定在 `tidy-tools.ts` 里通过 `pi.registerShortcut(...)` 注册——改那里的按键字符串即可重新绑定。Pi 内置的全局展开(`Ctrl+O`,即 `app.tools.expand`)则单独通过 `~/.pi/agent/keybindings.json` 配置。
|
|
74
88
|
4. **检查输入。** 执行 `/tidy-key-debug`,再按一次目标快捷键。Pi 会显示收到的字节和改写结果。若没有通知,终端或输入法在 Pi 收到按键前已拦截它。
|
|
75
89
|
|
|
90
|
+
## 更新日志
|
|
91
|
+
|
|
92
|
+
### 0.2.0 - 2026-09-05
|
|
93
|
+
|
|
94
|
+
- 默认三工具全折叠(edit/write 原默认展开)
|
|
95
|
+
- 新增 `/tidy-markdown`:Markdown 文件的 edit/write 自动展开全文,其余照样折叠;切模式清空手动钉选
|
|
96
|
+
- write 展开跳过官方 10 行预览,直接全文;全局 `Ctrl+O` 对三工具失效
|
|
97
|
+
- bash 折叠压成 2 行:计数后缀内联到输出行尾,失败输出(红色)同样单行
|
|
98
|
+
- 修 tab 宽度导致的窄终端折行;修 edit 双层外框多出的 padding
|
|
99
|
+
|
|
100
|
+
### 0.1.3
|
|
101
|
+
|
|
102
|
+
- 新增 `/tidy-bash`、`/tidy-edit`、`/tidy-write`、`/tidy-key-debug` 命令
|
|
103
|
+
- 修传统 `ESC` + 控制字符形式的快捷键归一化
|
|
104
|
+
|
|
76
105
|
## 开发
|
|
77
106
|
|
|
78
107
|
```bash
|
package/package.json
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runminton/pi-tidy-tools",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Collapse bash/edit/write into one-line summaries in the pi TUI; expand the official rendering per tool with Ctrl+Alt+B/W/E.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"files": [
|
|
8
8
|
"tidy-tools.ts",
|
|
9
9
|
"README.md",
|
|
10
|
-
"README.zh-CN.md"
|
|
11
|
-
"CHANGELOG.md"
|
|
10
|
+
"README.zh-CN.md"
|
|
12
11
|
],
|
|
13
12
|
"pi": {
|
|
14
13
|
"extensions": [
|
package/tidy-tools.ts
CHANGED
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
* - Expanded: Ctrl+Alt+E (edit), Ctrl+Alt+W (write), Ctrl+Alt+B (bash)
|
|
8
8
|
* toggle each tool between collapsed and fully expanded rendering.
|
|
9
9
|
* - The global Ctrl+O tool expansion does not affect these three tools.
|
|
10
|
+
* - Modes: compact (default, all three collapsed) and markdown
|
|
11
|
+
* (`/tidy-markdown` toggles; edit/write on Markdown files expand,
|
|
12
|
+
* the rest stays collapsed). Not persisted across restarts.
|
|
10
13
|
*
|
|
11
14
|
* Usage:
|
|
12
15
|
* pi -e ./tidy-tools.ts
|
|
@@ -32,8 +35,8 @@ import {
|
|
|
32
35
|
|
|
33
36
|
const MAX_COLLAPSED_COMMAND_LINES = 1;
|
|
34
37
|
const MAX_COLLAPSED_CONTENT_LINES = 3;
|
|
35
|
-
// bash
|
|
36
|
-
const MAX_COLLAPSED_BASH_OUTPUT_LINES =
|
|
38
|
+
// bash 折叠输出:预览与计数后缀合并为 1 行(命令 1 行 + 输出 1 行)。
|
|
39
|
+
const MAX_COLLAPSED_BASH_OUTPUT_LINES = 1;
|
|
37
40
|
|
|
38
41
|
/**
|
|
39
42
|
* Truncate rendered rows to at most maxLines, keeping the beginning.
|
|
@@ -65,6 +68,14 @@ function firstLine(text: string | undefined): string {
|
|
|
65
68
|
return line.length > 80 ? `${line.slice(0, 77)}...` : line;
|
|
66
69
|
}
|
|
67
70
|
|
|
71
|
+
// 终端 tab 按 8 的倍数对齐,pi-tui 按 3 列计算。不展开 tab 会导致
|
|
72
|
+
// 行宽估算小于终端实际渲染,窄终端下折成两行。与官方 replaceTabs
|
|
73
|
+
// 保持一致:tab 展开为 3 个空格。
|
|
74
|
+
|
|
75
|
+
function expandTabs(text: string): string {
|
|
76
|
+
return text.replace(/\t/g, " ");
|
|
77
|
+
}
|
|
78
|
+
|
|
68
79
|
function errorText(result: { content: { type: string; text?: string }[] }): string {
|
|
69
80
|
return result.content
|
|
70
81
|
.filter((c) => c.type === "text")
|
|
@@ -119,6 +130,46 @@ class LimitedLinesText implements Component {
|
|
|
119
130
|
}
|
|
120
131
|
}
|
|
121
132
|
|
|
133
|
+
class CollapsedBashOutput implements Component {
|
|
134
|
+
// 首行预览 + 计数后缀合并为 1 行,后缀常显。预览放不下时截断并加省略标记。
|
|
135
|
+
constructor(
|
|
136
|
+
private readonly preview: string,
|
|
137
|
+
private readonly suffix: string,
|
|
138
|
+
private readonly truncatedMarker: string,
|
|
139
|
+
) {}
|
|
140
|
+
|
|
141
|
+
render(width: number): string[] {
|
|
142
|
+
if (!this.suffix) {
|
|
143
|
+
return truncateRows(
|
|
144
|
+
wrapTextWithAnsi(this.preview, Math.max(1, width)),
|
|
145
|
+
MAX_COLLAPSED_BASH_OUTPUT_LINES,
|
|
146
|
+
this.truncatedMarker,
|
|
147
|
+
width,
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
const suffixWidth = visibleWidth(this.suffix);
|
|
151
|
+
if (suffixWidth >= width) {
|
|
152
|
+
return [sliceByColumn(this.suffix, 0, Math.max(1, width), true)];
|
|
153
|
+
}
|
|
154
|
+
const previewBudget = width - suffixWidth - 1;
|
|
155
|
+
if (visibleWidth(this.preview) <= previewBudget) {
|
|
156
|
+
return [`${this.preview} ${this.suffix}`];
|
|
157
|
+
}
|
|
158
|
+
const markerWidth = visibleWidth(this.truncatedMarker);
|
|
159
|
+
const preview = sliceByColumn(
|
|
160
|
+
this.preview,
|
|
161
|
+
0,
|
|
162
|
+
Math.max(0, previewBudget - markerWidth),
|
|
163
|
+
true,
|
|
164
|
+
);
|
|
165
|
+
const row = `${preview}${this.truncatedMarker} ${this.suffix}`;
|
|
166
|
+
// 极窄宽度下省略标记本身都放不下时做最终钳制,保证恒为 1 行。
|
|
167
|
+
return [visibleWidth(row) > width ? sliceByColumn(row, 0, width, true) : row];
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
invalidate(): void {}
|
|
171
|
+
}
|
|
172
|
+
|
|
122
173
|
class CollapsedToolShell extends Box {
|
|
123
174
|
private callComponent?: Component;
|
|
124
175
|
private resultComponent?: Component;
|
|
@@ -160,13 +211,37 @@ function getCollapsedBackground(isPartial: boolean, isError: boolean): string {
|
|
|
160
211
|
return isError ? "toolErrorBg" : "toolSuccessBg";
|
|
161
212
|
}
|
|
162
213
|
|
|
163
|
-
//
|
|
164
|
-
//
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
214
|
+
// 显示模式:compact 下三工具默认全折叠;markdown 模式下 edit/write 遇到
|
|
215
|
+
// Markdown 文件默认展开全文,其余照样折叠。默认 compact,不持久化。
|
|
216
|
+
let markdownMode = false;
|
|
217
|
+
// 手动钉选:Ctrl+Alt+? 或 /tidy-<tool> 设置,优先于模式默认;切换模式时清空。
|
|
218
|
+
const manualExpanded = new Map<string, boolean>();
|
|
219
|
+
|
|
220
|
+
function isMarkdownPath(value: unknown): boolean {
|
|
221
|
+
if (typeof value !== "string") return false;
|
|
222
|
+
return /\.(md|mdx|markdown)$/i.test(value.trim());
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function toolArgsMarkdown(args: any): boolean {
|
|
226
|
+
return isMarkdownPath(args?.path) || isMarkdownPath(args?.file_path);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// 不带文件上下文的工具级基准(用于翻转手动钉选):compact 下全 false;
|
|
230
|
+
// markdown 模式下 edit/write 为 true(具体到文件时再按后缀细化)。
|
|
231
|
+
function modeBaseExpanded(name: string): boolean {
|
|
232
|
+
if (!markdownMode) return false;
|
|
233
|
+
return name === "edit" || name === "write";
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function modeDefaultExpanded(name: string, args: any): boolean {
|
|
237
|
+
if (!markdownMode) return false;
|
|
238
|
+
if (name === "edit" || name === "write") return toolArgsMarkdown(args);
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function isToolExpanded(name: string, args: any): boolean {
|
|
243
|
+
return manualExpanded.get(name) ?? modeDefaultExpanded(name, args);
|
|
244
|
+
}
|
|
170
245
|
|
|
171
246
|
// Some terminals (Kitty keyboard protocol flag-1 mode) encode Ctrl+letter as
|
|
172
247
|
// a CSI-u sequence using the control character code without a Ctrl modifier
|
|
@@ -201,14 +276,18 @@ function convertCtrlAltSequence(data: string): string | undefined {
|
|
|
201
276
|
return `\x1b[${key.charCodeAt(0)};7${eventSuffix}u`; // 7 = Ctrl|Alt (1-indexed)
|
|
202
277
|
}
|
|
203
278
|
|
|
204
|
-
function
|
|
205
|
-
toolExpanded.set(name, !(toolExpanded.get(name) ?? false));
|
|
279
|
+
function refreshToolRows(ctx: ExtensionContext): void {
|
|
206
280
|
const globalExpanded = ctx.ui.getToolsExpanded();
|
|
207
281
|
// Force every tool row to re-render. The global value is restored
|
|
208
282
|
// immediately, so only the rows' renderers refresh, not the global state.
|
|
209
283
|
ctx.ui.setToolsExpanded(!globalExpanded);
|
|
210
284
|
ctx.ui.setToolsExpanded(globalExpanded);
|
|
211
|
-
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function toggleToolExpanded(ctx: ExtensionContext, name: string): void {
|
|
288
|
+
manualExpanded.set(name, !(manualExpanded.get(name) ?? modeBaseExpanded(name)));
|
|
289
|
+
refreshToolRows(ctx);
|
|
290
|
+
ctx.ui.notify(`${name}: ${manualExpanded.get(name) ? "expanded" : "collapsed"}`, "info");
|
|
212
291
|
}
|
|
213
292
|
|
|
214
293
|
// Cache the official tool implementation by working directory, as pi may run
|
|
@@ -244,6 +323,9 @@ function registerCollapsibleTool(
|
|
|
244
323
|
getDef: (cwd: string) => ToolDefinition<any, any, any>,
|
|
245
324
|
collapsedCall: (args: any, theme: any) => Component,
|
|
246
325
|
collapsedResult: (result: any, options: any, theme: any, context: any) => Component,
|
|
326
|
+
// 跳过官方预览态,展开即全文(bash 行为)。为 false 时保留官方默认视图,
|
|
327
|
+
// 其内部预览 / 全文仍由全局 Ctrl+O 决定。
|
|
328
|
+
forceFullExpansion = false,
|
|
247
329
|
) {
|
|
248
330
|
const def = getDef(process.cwd());
|
|
249
331
|
const usesSelfShell = def.renderShell === "self";
|
|
@@ -256,8 +338,11 @@ function registerCollapsibleTool(
|
|
|
256
338
|
parameters: def.parameters,
|
|
257
339
|
prepareArguments: def.prepareArguments,
|
|
258
340
|
constrainedSampling: def.constrainedSampling,
|
|
259
|
-
//
|
|
260
|
-
//
|
|
341
|
+
// Mirror the official renderShell. Omitting it falls back to
|
|
342
|
+
// "default", which double-wraps "self" tools like edit in an
|
|
343
|
+
// extra Box: one extra padding line on top and bottom when
|
|
344
|
+
// expanded, and a Box-in-Box when collapsed.
|
|
345
|
+
...(usesSelfShell ? { renderShell: "self" as const } : {}),
|
|
261
346
|
|
|
262
347
|
async execute(toolCallId, params, signal, onUpdate, ctx) {
|
|
263
348
|
return getDef(ctx.cwd).execute(toolCallId, params, signal, onUpdate, ctx);
|
|
@@ -265,11 +350,17 @@ function registerCollapsibleTool(
|
|
|
265
350
|
|
|
266
351
|
renderCall(args, theme, context) {
|
|
267
352
|
const def = getDef(context.cwd);
|
|
268
|
-
if (
|
|
353
|
+
if (isToolExpanded(def.name, args) && def.renderCall) {
|
|
269
354
|
return def.renderCall(
|
|
270
355
|
args as never,
|
|
271
356
|
theme as never,
|
|
272
|
-
|
|
357
|
+
// One-key full expansion: skip the official preview so
|
|
358
|
+
// the per-tool shortcut always shows complete output.
|
|
359
|
+
{
|
|
360
|
+
...context,
|
|
361
|
+
...(forceFullExpansion ? { expanded: true } : {}),
|
|
362
|
+
lastComponent: undefined,
|
|
363
|
+
} as never,
|
|
273
364
|
);
|
|
274
365
|
}
|
|
275
366
|
const component = collapsedCall(args, theme);
|
|
@@ -286,10 +377,10 @@ function registerCollapsibleTool(
|
|
|
286
377
|
|
|
287
378
|
renderResult(result, options, theme, context) {
|
|
288
379
|
const def = getDef(context.cwd);
|
|
289
|
-
if (
|
|
380
|
+
if (isToolExpanded(def.name, context.args) && def.renderResult) {
|
|
290
381
|
return def.renderResult(
|
|
291
382
|
result as never,
|
|
292
|
-
options as never,
|
|
383
|
+
{ ...options, ...(forceFullExpansion ? { expanded: true } : {}) } as never,
|
|
293
384
|
theme as never,
|
|
294
385
|
{ ...context, lastComponent: undefined } as never,
|
|
295
386
|
);
|
|
@@ -345,7 +436,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
345
436
|
},
|
|
346
437
|
|
|
347
438
|
renderCall(args, theme, context) {
|
|
348
|
-
if (
|
|
439
|
+
if (isToolExpanded("bash", args)) {
|
|
349
440
|
const def = getBashDef(context.cwd);
|
|
350
441
|
if (def.renderCall) {
|
|
351
442
|
return def.renderCall(
|
|
@@ -358,7 +449,8 @@ export default function (pi: ExtensionAPI) {
|
|
|
358
449
|
}
|
|
359
450
|
}
|
|
360
451
|
|
|
361
|
-
const
|
|
452
|
+
const rawCommand = args.command || "...";
|
|
453
|
+
const command = typeof rawCommand === "string" ? expandTabs(rawCommand) : "...";
|
|
362
454
|
const timeout = args.timeout as number | undefined;
|
|
363
455
|
const timeoutSuffix = timeout ? theme.fg("muted", ` (timeout ${timeout}s)`) : "";
|
|
364
456
|
const renderedCommand = theme.fg("toolTitle", theme.bold(`$ ${command}`)) + timeoutSuffix;
|
|
@@ -371,7 +463,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
371
463
|
},
|
|
372
464
|
|
|
373
465
|
renderResult(result, options, theme, context) {
|
|
374
|
-
if (
|
|
466
|
+
if (isToolExpanded("bash", context.args)) {
|
|
375
467
|
const def = getBashDef(context.cwd);
|
|
376
468
|
if (def.renderResult) {
|
|
377
469
|
return def.renderResult(
|
|
@@ -385,26 +477,40 @@ export default function (pi: ExtensionAPI) {
|
|
|
385
477
|
}
|
|
386
478
|
}
|
|
387
479
|
|
|
388
|
-
const output = errorText(result).trim().replace(/\r/g, "");
|
|
480
|
+
const output = expandTabs(errorText(result).trim().replace(/\r/g, ""));
|
|
481
|
+
const allLines = output.split("\n");
|
|
482
|
+
const first = allLines[0] ?? "";
|
|
483
|
+
const moreSuffix =
|
|
484
|
+
allLines.length > 1
|
|
485
|
+
? theme.fg("muted", `... (${allLines.length - 1} more lines)`)
|
|
486
|
+
: "";
|
|
487
|
+
// 失败输出同样压成 1 行:红色首行 + 内联计数,与成功态同形。
|
|
389
488
|
if (context.isError) {
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
489
|
+
if (!first) {
|
|
490
|
+
return new CollapsedBashOutput(
|
|
491
|
+
theme.fg("error", "failed"),
|
|
492
|
+
"",
|
|
493
|
+
theme.fg("muted", "..."),
|
|
494
|
+
);
|
|
495
|
+
}
|
|
496
|
+
return new CollapsedBashOutput(
|
|
497
|
+
theme.fg("error", first),
|
|
498
|
+
moreSuffix,
|
|
393
499
|
theme.fg("muted", "..."),
|
|
394
500
|
);
|
|
395
501
|
}
|
|
396
502
|
// Preview only the first line. Wrapping the full output on every
|
|
397
503
|
// frame is what made the TUI lag with large outputs.
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
theme.fg("muted",
|
|
504
|
+
if (!first) {
|
|
505
|
+
return new CollapsedBashOutput(
|
|
506
|
+
theme.fg("muted", "(no output)"),
|
|
507
|
+
"",
|
|
508
|
+
theme.fg("muted", "..."),
|
|
403
509
|
);
|
|
404
510
|
}
|
|
405
|
-
return new
|
|
406
|
-
|
|
407
|
-
|
|
511
|
+
return new CollapsedBashOutput(
|
|
512
|
+
theme.fg("toolOutput", first),
|
|
513
|
+
moreSuffix,
|
|
408
514
|
theme.fg("muted", "..."),
|
|
409
515
|
);
|
|
410
516
|
},
|
|
@@ -462,6 +568,8 @@ export default function (pi: ExtensionAPI) {
|
|
|
462
568
|
}
|
|
463
569
|
return new Text(theme.fg("success", "done"), 0, 0);
|
|
464
570
|
},
|
|
571
|
+
// 展开即全文,跳过官方 10 行预览:三工具统一两档,Ctrl+O 彻底失效。
|
|
572
|
+
true,
|
|
465
573
|
);
|
|
466
574
|
|
|
467
575
|
pi.registerCommand("tidy-bash", {
|
|
@@ -476,6 +584,15 @@ export default function (pi: ExtensionAPI) {
|
|
|
476
584
|
description: "Toggle write output expansion",
|
|
477
585
|
handler: async (_args, ctx) => toggleToolExpanded(ctx, "write"),
|
|
478
586
|
});
|
|
587
|
+
pi.registerCommand("tidy-markdown", {
|
|
588
|
+
description: "Toggle markdown mode (edit/write expand for Markdown files)",
|
|
589
|
+
handler: async (_args, ctx) => {
|
|
590
|
+
markdownMode = !markdownMode;
|
|
591
|
+
manualExpanded.clear();
|
|
592
|
+
refreshToolRows(ctx);
|
|
593
|
+
ctx.ui.notify(`markdown mode: ${markdownMode ? "on" : "off"}`, "info");
|
|
594
|
+
},
|
|
595
|
+
});
|
|
479
596
|
pi.registerCommand("tidy-key-debug", {
|
|
480
597
|
description: "Show the next raw terminal key sequence",
|
|
481
598
|
handler: async (_args, ctx) => {
|
package/CHANGELOG.md
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
## [0.1.3] - 2026-08-27
|
|
4
|
-
|
|
5
|
-
### Added
|
|
6
|
-
|
|
7
|
-
- Added `/tidy-bash`, `/tidy-edit`, and `/tidy-write` commands for toggling tool output.
|
|
8
|
-
- Added `/tidy-key-debug` to inspect the next terminal key sequence.
|
|
9
|
-
|
|
10
|
-
### Fixed
|
|
11
|
-
|
|
12
|
-
- Normalized the legacy `ESC` + control-character form of `Ctrl+Alt+letter` shortcuts.
|
|
13
|
-
|
|
14
|
-
### Documentation
|
|
15
|
-
|
|
16
|
-
- Documented the new commands and keyboard input debugging steps.
|