@philogag/pi-tui-fold-blocks 0.1.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 +99 -0
- package/dist/config.d.ts +20 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +61 -0
- package/dist/config.js.map +1 -0
- package/dist/folders/command.d.ts +5 -0
- package/dist/folders/command.d.ts.map +1 -0
- package/dist/folders/command.js +21 -0
- package/dist/folders/command.js.map +1 -0
- package/dist/folders/path.d.ts +7 -0
- package/dist/folders/path.d.ts.map +1 -0
- package/dist/folders/path.js +25 -0
- package/dist/folders/path.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/mode.d.ts +10 -0
- package/dist/mode.d.ts.map +1 -0
- package/dist/mode.js +12 -0
- package/dist/mode.js.map +1 -0
- package/dist/overrides.d.ts +31 -0
- package/dist/overrides.d.ts.map +1 -0
- package/dist/overrides.js +50 -0
- package/dist/overrides.js.map +1 -0
- package/dist/render.d.ts +55 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +307 -0
- package/dist/render.js.map +1 -0
- package/dist/settings.d.ts +9 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +64 -0
- package/dist/settings.js.map +1 -0
- package/package.json +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# @philogag/pi-tui-fold-blocks
|
|
2
|
+
|
|
3
|
+
pi TUI 插件:折叠 / 隐藏工具调用块,让对话更清爽。**只改渲染,不改 session**——所有内容仍完整保留在会话里。
|
|
4
|
+
|
|
5
|
+
## 特性
|
|
6
|
+
|
|
7
|
+
- **三态模式**:`native`(原生)/ `fold`(折叠成一行)/ `hide`(完全不渲染)
|
|
8
|
+
- **单行左右对齐**:左侧概要 + 右侧统计,不占纵向空间
|
|
9
|
+
- **状态背景色**:
|
|
10
|
+
- 文件操作块(read / edit / write):恒绿
|
|
11
|
+
- bash 块:运行中(黄)/ 失败(红)/ 成功(绿),颜色随状态实时变化
|
|
12
|
+
- **智能 bash 摘要**:自动剥离 `cd ... &&` / `source ... &&` 前缀,提取关键命令
|
|
13
|
+
- **路径样式可选**:`relative` / `absolute` / `basename`;git worktree 路径自动折叠
|
|
14
|
+
- **nerd font 图标**:默认开启,可关闭(兼容无 nerd font 字体的终端)
|
|
15
|
+
- **非侵入**:`execute` 原样委托给内置工具,不改变任何行为
|
|
16
|
+
|
|
17
|
+
## 安装
|
|
18
|
+
|
|
19
|
+
扩展放在自动发现的扩展目录中:
|
|
20
|
+
|
|
21
|
+
| 位置 | 作用域 |
|
|
22
|
+
| --- | --- |
|
|
23
|
+
| `~/.pi/agent/extensions/` | 全局(所有项目) |
|
|
24
|
+
| `.pi/extensions/` | 项目级(需先信任项目) |
|
|
25
|
+
|
|
26
|
+
把仓库内 `packages/pi-tui-fold-blocks/` 复制(或链接)到上述任一目录的 `pi-tui-fold-blocks/` 子目录即可,如:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
mkdir -p ~/.pi/agent/extensions
|
|
30
|
+
ln -s "$PWD/packages/pi-tui-fold-blocks" ~/.pi/agent/extensions/pi-tui-fold-blocks
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
或在 `~/.pi/settings.json` 的 `extensions` 数组中追加包目录的绝对路径。
|
|
34
|
+
|
|
35
|
+
> 也可使用 `pi -e ./packages/pi-tui-fold-blocks/src/index.ts` 快速体验。
|
|
36
|
+
|
|
37
|
+
改动扩展后执行 `/reload` 热重载,无需重启 pi。
|
|
38
|
+
|
|
39
|
+
## 使用
|
|
40
|
+
|
|
41
|
+
## Settings
|
|
42
|
+
|
|
43
|
+
Run `/tui-fold-blocks` to open the settings page. The page follows pi's
|
|
44
|
+
native settings interaction:
|
|
45
|
+
|
|
46
|
+
- Single select list with all options (Mode, Nerd font icons, Path style,
|
|
47
|
+
Fold git worktree, Bash smart detection, Show status hints).
|
|
48
|
+
- `↑`/`↓` to navigate, `Space` to cycle the selected option's value
|
|
49
|
+
(booleans cycle `on`/`off`, enums cycle their choices).
|
|
50
|
+
- Changes are saved to `settings.json` immediately.
|
|
51
|
+
- `Esc` closes the page.
|
|
52
|
+
|
|
53
|
+
### 手动配置
|
|
54
|
+
|
|
55
|
+
直接在 `settings.json` 中写入即可(扩展启动时读取):
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"@philogag/pi-tui-fold-blocks": {
|
|
60
|
+
"mode": "fold",
|
|
61
|
+
"nerdFont": true,
|
|
62
|
+
"fileBlocks": {
|
|
63
|
+
"collapse": true,
|
|
64
|
+
"pathStyle": "relative",
|
|
65
|
+
"foldGitWorktree": true
|
|
66
|
+
},
|
|
67
|
+
"bashBlocks": {
|
|
68
|
+
"collapse": true,
|
|
69
|
+
"smart": true,
|
|
70
|
+
"showStatus": true
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## 工作原理
|
|
77
|
+
|
|
78
|
+
- 在 `session_start` 事件中检测 `ctx.mode === "tui"`,**仅当 pi 运行于 TUI 模式时**才注册渲染钩子与命令(print / json / rpc 模式零注册,互不影响)。
|
|
79
|
+
- 通过 `pi.registerTool()` 以 `renderShell: "self"` 覆盖内置 `read` / `bash` / `edit` / `write` 的 `renderCall` / `renderResult`,`execute` 保持原样委托。
|
|
80
|
+
- 折叠内容全部由 `renderResult` 单次渲染(`renderCall` 返回空 `Text`),保证布局一致。
|
|
81
|
+
- 模式切换通过跨块重渲染(`invalidate`)实时生效,无需重启。
|
|
82
|
+
|
|
83
|
+
## 开发
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
pnpm install # 安装依赖(弱依赖来自宿主 pi,devDeps 供本地构建)
|
|
87
|
+
pnpm --filter @philogag/pi-tui-fold-blocks test # 24 个测试
|
|
88
|
+
pnpm --filter @philogag/pi-tui-fold-blocks typecheck
|
|
89
|
+
pnpm --filter @philogag/pi-tui-fold-blocks build # 产出 dist/
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 依赖说明
|
|
93
|
+
|
|
94
|
+
运行时依赖(`@earendil-works/pi-coding-agent` / `@earendil-works/pi-tui` / `typebox`)声明为 **peerDependencies(弱依赖)**:宿主 pi 环境已内置这些包,插件不重复打包;`devDependencies` 中保留同名依赖供本地 typecheck / test。
|
|
95
|
+
|
|
96
|
+
## 已知限制
|
|
97
|
+
|
|
98
|
+
- `native` 模式下渲染委托给内置渲染(不叠加状态色框)——保留原生外观,换取模式切换的即时性。
|
|
99
|
+
- 仅覆盖 `read` / `bash` / `edit` / `write` 四个高频工具;`grep` / `find` / `ls` 等保持原生渲染。
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type Mode = "native" | "fold" | "hide";
|
|
2
|
+
export interface FoldBlocksConfig {
|
|
3
|
+
mode: Mode;
|
|
4
|
+
nerdFont: boolean;
|
|
5
|
+
fileBlocks: {
|
|
6
|
+
collapse: boolean;
|
|
7
|
+
pathStyle: "absolute" | "relative" | "basename";
|
|
8
|
+
foldGitWorktree: boolean;
|
|
9
|
+
};
|
|
10
|
+
bashBlocks: {
|
|
11
|
+
collapse: boolean;
|
|
12
|
+
smart: boolean;
|
|
13
|
+
showStatus: boolean;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export declare const DEFAULT_CONFIG: FoldBlocksConfig;
|
|
17
|
+
export declare function loadConfig(settingsPath?: string): FoldBlocksConfig;
|
|
18
|
+
export declare function saveConfig(cfg: FoldBlocksConfig, settingsPath?: string): void;
|
|
19
|
+
export declare function setMode(cfg: FoldBlocksConfig, mode: Mode): FoldBlocksConfig;
|
|
20
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,IAAI,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AAE9C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE;QACV,QAAQ,EAAE,OAAO,CAAC;QAClB,SAAS,EAAE,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC;QAChD,eAAe,EAAE,OAAO,CAAC;KAC1B,CAAC;IACF,UAAU,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,CAAC;CACxE;AAED,eAAO,MAAM,cAAc,EAAE,gBAK5B,CAAC;AAyBF,wBAAgB,UAAU,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,gBAAgB,CASlE;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,gBAAgB,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAS7E;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,IAAI,GAAG,gBAAgB,CAE3E"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// packages/pi-tui-fold-blocks/src/config.ts
|
|
2
|
+
import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
5
|
+
export const DEFAULT_CONFIG = {
|
|
6
|
+
mode: "fold",
|
|
7
|
+
nerdFont: true,
|
|
8
|
+
fileBlocks: { collapse: true, pathStyle: "relative", foldGitWorktree: true },
|
|
9
|
+
bashBlocks: { collapse: true, smart: true, showStatus: true },
|
|
10
|
+
};
|
|
11
|
+
const PACKAGE_KEY = "@philogag/pi-tui-fold-blocks";
|
|
12
|
+
function sanitize(raw) {
|
|
13
|
+
if (typeof raw !== "object" || raw === null)
|
|
14
|
+
return DEFAULT_CONFIG;
|
|
15
|
+
const r = raw;
|
|
16
|
+
return {
|
|
17
|
+
mode: r.mode === "native" || r.mode === "hide" ? r.mode : r.mode === "fold" ? "fold" : DEFAULT_CONFIG.mode,
|
|
18
|
+
nerdFont: typeof r.nerdFont === "boolean" ? r.nerdFont : DEFAULT_CONFIG.nerdFont,
|
|
19
|
+
fileBlocks: {
|
|
20
|
+
collapse: typeof r.fileBlocks?.collapse === "boolean" ? r.fileBlocks.collapse : DEFAULT_CONFIG.fileBlocks.collapse,
|
|
21
|
+
pathStyle: ["absolute", "relative", "basename"].includes(r.fileBlocks?.pathStyle)
|
|
22
|
+
? r.fileBlocks.pathStyle
|
|
23
|
+
: DEFAULT_CONFIG.fileBlocks.pathStyle,
|
|
24
|
+
foldGitWorktree: typeof r.fileBlocks?.foldGitWorktree === "boolean" ? r.fileBlocks.foldGitWorktree : DEFAULT_CONFIG.fileBlocks.foldGitWorktree,
|
|
25
|
+
},
|
|
26
|
+
bashBlocks: {
|
|
27
|
+
collapse: typeof r.bashBlocks?.collapse === "boolean" ? r.bashBlocks.collapse : DEFAULT_CONFIG.bashBlocks.collapse,
|
|
28
|
+
smart: typeof r.bashBlocks?.smart === "boolean" ? r.bashBlocks.smart : DEFAULT_CONFIG.bashBlocks.smart,
|
|
29
|
+
showStatus: typeof r.bashBlocks?.showStatus === "boolean" ? r.bashBlocks.showStatus : DEFAULT_CONFIG.bashBlocks.showStatus,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export function loadConfig(settingsPath) {
|
|
34
|
+
const path = settingsPath ?? findSettingsPath();
|
|
35
|
+
try {
|
|
36
|
+
const text = readFileSync(path, "utf8");
|
|
37
|
+
const json = JSON.parse(text);
|
|
38
|
+
return sanitize(json[PACKAGE_KEY]);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return { ...DEFAULT_CONFIG, fileBlocks: { ...DEFAULT_CONFIG.fileBlocks }, bashBlocks: { ...DEFAULT_CONFIG.bashBlocks } };
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export function saveConfig(cfg, settingsPath) {
|
|
45
|
+
const path = settingsPath ?? findSettingsPath();
|
|
46
|
+
let json = {};
|
|
47
|
+
try {
|
|
48
|
+
json = JSON.parse(readFileSync(path, "utf8"));
|
|
49
|
+
}
|
|
50
|
+
catch { /* 新建 */ }
|
|
51
|
+
json[PACKAGE_KEY] = cfg;
|
|
52
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
53
|
+
writeFileSync(path, JSON.stringify(json, null, 2), "utf8");
|
|
54
|
+
}
|
|
55
|
+
export function setMode(cfg, mode) {
|
|
56
|
+
return { ...cfg, mode, fileBlocks: { ...cfg.fileBlocks }, bashBlocks: { ...cfg.bashBlocks } };
|
|
57
|
+
}
|
|
58
|
+
function findSettingsPath() {
|
|
59
|
+
return join(getAgentDir(), "settings.json");
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/folders/command.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,OAAO,CAAC;CAChB;AAID,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,MAAM,CAc1E"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const WRAP_PREFIX = /^(?:cd\s+\S+\s*&&|source\s+\S+\s*&&|export\s+[^=]+=\S*\s*&&)\s*/;
|
|
2
|
+
export function foldCommand(command, opts) {
|
|
3
|
+
const trimmed = command.trim();
|
|
4
|
+
if (!trimmed)
|
|
5
|
+
return trimmed;
|
|
6
|
+
if (opts.smart) {
|
|
7
|
+
// 先把多行命令折叠为单行(保证折叠块只渲染一行),再剥包装前缀:
|
|
8
|
+
// - 反斜杠续行(换行前一个反斜杠)按 shell 语义整体移除(\ + 换行 + 后续缩进),
|
|
9
|
+
// 如 "cd build && \\" 接换行 → "cd build && npm test";
|
|
10
|
+
// - 其余换行以 " ⏎ " 分隔并吞掉下一行缩进,如 for 循环保持可读的单行概要。
|
|
11
|
+
let cur = trimmed.replace(/\\\r?\n\s*/g, "").replace(/\r?\n\s*/g, " ⏎ ");
|
|
12
|
+
let next = cur.replace(WRAP_PREFIX, "");
|
|
13
|
+
while (next !== cur) {
|
|
14
|
+
cur = next;
|
|
15
|
+
next = cur.replace(WRAP_PREFIX, "");
|
|
16
|
+
}
|
|
17
|
+
return cur;
|
|
18
|
+
}
|
|
19
|
+
return trimmed.split(/\s+/)[0] ?? trimmed;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/folders/command.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,GAAG,iEAAiE,CAAC;AAEtF,MAAM,UAAU,WAAW,CAAC,OAAe,EAAE,IAAqB;IAChE,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAC/B,IAAI,CAAC,OAAO;QAAE,OAAO,OAAO,CAAC;IAC7B,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,kCAAkC;QAClC,oDAAoD;QACpD,uDAAuD;QACvD,gDAAgD;QAChD,IAAI,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QACzE,IAAI,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACxC,OAAO,IAAI,KAAK,GAAG,EAAE,CAAC;YAAC,GAAG,GAAG,IAAI,CAAC;YAAC,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAAC,CAAC;QACzE,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/folders/path.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC;IAC5C,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,MAAM,CAsBjE"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { relative, basename, isAbsolute, sep } from "node:path";
|
|
2
|
+
export function foldPath(path, opts) {
|
|
3
|
+
let p = path;
|
|
4
|
+
if (opts.foldGitWorktree) {
|
|
5
|
+
const idx = p.indexOf(`${sep}.git${sep}worktrees${sep}`);
|
|
6
|
+
if (idx !== -1) {
|
|
7
|
+
const wtRoot = p.slice(0, idx);
|
|
8
|
+
const rest = p.slice(idx + (`.git${sep}worktrees${sep}`.length + 1)); // 跳过 <wtName>/ 段
|
|
9
|
+
const restNoName = rest.split(sep).slice(1).join(sep);
|
|
10
|
+
p = wtRoot.endsWith(sep) ? wtRoot + restNoName : `${wtRoot}${sep}${restNoName}`;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
switch (opts.style) {
|
|
14
|
+
case "absolute":
|
|
15
|
+
return isAbsolute(p) ? p : `${opts.cwd}${sep}${p}`;
|
|
16
|
+
case "basename":
|
|
17
|
+
return basename(p);
|
|
18
|
+
case "relative":
|
|
19
|
+
default: {
|
|
20
|
+
const rel = relative(opts.cwd, p);
|
|
21
|
+
return rel && !rel.startsWith("..") ? rel : p;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path.js","sourceRoot":"","sources":["../../src/folders/path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAQhE,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,IAAkB;IACvD,IAAI,CAAC,GAAG,IAAI,CAAC;IACb,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,GAAG,OAAO,GAAG,YAAY,GAAG,EAAE,CAAC,CAAC;QACzD,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YAC/B,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,GAAG,YAAY,GAAG,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB;YACvF,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACtD,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,GAAG,GAAG,UAAU,EAAE,CAAC;QAClF,CAAC;IACH,CAAC;IACD,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;QACnB,KAAK,UAAU;YACb,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC;QACrD,KAAK,UAAU;YACb,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC;QACrB,KAAK,UAAU,CAAC;QAChB,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAClC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAA2B,MAAM,iCAAiC,CAAC;AAM7F,MAAM,CAAC,OAAO,WAAW,EAAE,EAAE,YAAY,GAAG,IAAI,CAgC/C"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { loadConfig, saveConfig, setMode } from "./config.js";
|
|
2
|
+
import { createModeState } from "./mode.js";
|
|
3
|
+
import { registerOverrides } from "./overrides.js";
|
|
4
|
+
import { openSettings } from "./settings.js";
|
|
5
|
+
export default function (pi) {
|
|
6
|
+
let config = loadConfig();
|
|
7
|
+
const modeState = createModeState(config.mode, () => {
|
|
8
|
+
config = setMode(config, modeState.mode);
|
|
9
|
+
});
|
|
10
|
+
const cwd = process.cwd();
|
|
11
|
+
// 用 getter 把活 config 暴露给 overrides —— 让设置保存后立刻生效(P1-1 修复)
|
|
12
|
+
const getConfig = () => config;
|
|
13
|
+
// registerTool 的渲染钩子必须在工具执行前就位:session_start 事件触发时首帧渲染可能已完成,
|
|
14
|
+
// 在事件 handler 中注册会导致 read/bash/edit/write 的折叠渲染不生效。故放顶层无条件注册。
|
|
15
|
+
registerOverrides(pi, cwd, getConfig);
|
|
16
|
+
// 命令仅 TUI 模式需要(依赖 ctx.ui 打开设置页),且 ExtensionAPI 工厂入参无 mode 字段,
|
|
17
|
+
// 需在事件 handler 中经 ctx.mode 判断(官方文档: Use ctx.mode === "tui" to guard
|
|
18
|
+
// terminal-only features)。registered 标志保证 session_start 多次触发时只注册一次。
|
|
19
|
+
let commandRegistered = false;
|
|
20
|
+
pi.on("session_start", (_event, ctx) => {
|
|
21
|
+
if (ctx.mode !== "tui" || commandRegistered)
|
|
22
|
+
return;
|
|
23
|
+
commandRegistered = true;
|
|
24
|
+
pi.registerCommand("tui-fold-blocks", {
|
|
25
|
+
description: "Open tui-fold-blocks settings page",
|
|
26
|
+
handler: async (args, ctx) => {
|
|
27
|
+
await openSettings(ctx.ui, config, (next) => {
|
|
28
|
+
config = next;
|
|
29
|
+
if (next.mode !== modeState.mode)
|
|
30
|
+
modeState.setMode(next.mode); // 模式字段实时同步,触发 rerenderAll
|
|
31
|
+
saveConfig(config);
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAyB,MAAM,aAAa,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,CAAC,OAAO,WAAW,EAAgB;IACvC,IAAI,MAAM,GAAG,UAAU,EAAE,CAAC;IAC1B,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;QAClD,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IACH,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,0DAA0D;IAC1D,MAAM,SAAS,GAAG,GAAqB,EAAE,CAAC,MAAM,CAAC;IAEjD,6DAA6D;IAC7D,8DAA8D;IAC9D,iBAAiB,CAAC,EAAE,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC;IAEtC,8DAA8D;IAC9D,oEAAoE;IACpE,oEAAoE;IACpE,IAAI,iBAAiB,GAAG,KAAK,CAAC;IAC9B,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;QACrC,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK,IAAI,iBAAiB;YAAE,OAAO;QACpD,iBAAiB,GAAG,IAAI,CAAC;QAEzB,EAAE,CAAC,eAAe,CAAC,iBAAiB,EAAE;YACpC,WAAW,EAAE,oCAAoC;YACjD,OAAO,EAAE,KAAK,EAAE,IAAY,EAAE,GAA4B,EAAE,EAAE;gBAC5D,MAAM,YAAY,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;oBAC1C,MAAM,GAAG,IAAI,CAAC;oBACd,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI;wBAAE,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,0BAA0B;oBAC1F,UAAU,CAAC,MAAM,CAAC,CAAC;gBACrB,CAAC,CAAC,CAAC;YACL,CAAC;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/mode.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Mode } from "./config.js";
|
|
2
|
+
export interface ModeState {
|
|
3
|
+
mode: Mode;
|
|
4
|
+
setMode(m: Mode): void;
|
|
5
|
+
addInvalidator(toolCallId: string, inv: () => void): void;
|
|
6
|
+
removeInvalidator(toolCallId: string): void;
|
|
7
|
+
rerenderAll(): void;
|
|
8
|
+
}
|
|
9
|
+
export declare function createModeState(initial: Mode, onModeChange: () => void): ModeState;
|
|
10
|
+
//# sourceMappingURL=mode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mode.d.ts","sourceRoot":"","sources":["../src/mode.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACvB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC1D,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,WAAW,IAAI,IAAI,CAAC;CACrB;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,IAAI,GAAG,SAAS,CAUlF"}
|
package/dist/mode.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function createModeState(initial, onModeChange) {
|
|
2
|
+
let mode = initial;
|
|
3
|
+
const invalidators = new Map();
|
|
4
|
+
return {
|
|
5
|
+
get mode() { return mode; },
|
|
6
|
+
setMode(m) { mode = m; onModeChange(); invalidators.forEach((inv) => inv()); },
|
|
7
|
+
addInvalidator(id, inv) { invalidators.set(id, inv); },
|
|
8
|
+
removeInvalidator(id) { invalidators.delete(id); },
|
|
9
|
+
rerenderAll() { onModeChange(); invalidators.forEach((inv) => inv()); },
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=mode.js.map
|
package/dist/mode.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mode.js","sourceRoot":"","sources":["../src/mode.ts"],"names":[],"mappings":"AAWA,MAAM,UAAU,eAAe,CAAC,OAAa,EAAE,YAAwB;IACrE,IAAI,IAAI,GAAS,OAAO,CAAC;IACzB,MAAM,YAAY,GAAG,IAAI,GAAG,EAAsB,CAAC;IACnD,OAAO;QACL,IAAI,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;QAC3B,OAAO,CAAC,CAAO,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QACpF,cAAc,CAAC,EAAE,EAAE,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACtD,iBAAiB,CAAC,EAAE,IAAI,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAClD,WAAW,KAAK,YAAY,EAAE,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;KACxE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import type { Component } from "@earendil-works/pi-tui";
|
|
3
|
+
import type { FoldBlocksConfig } from "./config.js";
|
|
4
|
+
export interface ToolRenderContext<TState = any, TArgs = any> {
|
|
5
|
+
/** Current tool call arguments. Shared across call/result renders for the same tool call. */
|
|
6
|
+
args: TArgs;
|
|
7
|
+
/** Unique id for this tool execution. Stable across call/result renders for the same tool call. */
|
|
8
|
+
toolCallId: string;
|
|
9
|
+
/** Invalidate just this tool execution component for redraw. */
|
|
10
|
+
invalidate: () => void;
|
|
11
|
+
/** Previously returned component for this render slot, if any. */
|
|
12
|
+
lastComponent: Component | undefined;
|
|
13
|
+
/** Shared renderer state for this tool row. Initialized by tool-execution.ts. */
|
|
14
|
+
state: TState;
|
|
15
|
+
/** Working directory for this tool execution. */
|
|
16
|
+
cwd: string;
|
|
17
|
+
/** Whether the tool execution has started. */
|
|
18
|
+
executionStarted: boolean;
|
|
19
|
+
/** Whether the tool call arguments are complete. */
|
|
20
|
+
argsComplete: boolean;
|
|
21
|
+
/** Whether the tool result is partial/streaming. */
|
|
22
|
+
isPartial: boolean;
|
|
23
|
+
/** Whether the result view is expanded. */
|
|
24
|
+
expanded: boolean;
|
|
25
|
+
/** Whether inline images are currently shown in the TUI. */
|
|
26
|
+
showImages: boolean;
|
|
27
|
+
/** Whether the current result is an error. */
|
|
28
|
+
isError: boolean;
|
|
29
|
+
}
|
|
30
|
+
export declare function registerOverrides(pi: ExtensionAPI, cwd: string, cfgGetter: () => FoldBlocksConfig): void;
|
|
31
|
+
//# sourceMappingURL=overrides.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overrides.d.ts","sourceRoot":"","sources":["../src/overrides.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAkB,MAAM,iCAAiC,CAAC;AAEpF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAMpD,MAAM,WAAW,iBAAiB,CAAC,MAAM,GAAG,GAAG,EAAE,KAAK,GAAG,GAAG;IAC3D,6FAA6F;IAC7F,IAAI,EAAE,KAAK,CAAC;IACZ,mGAAmG;IACnG,UAAU,EAAE,MAAM,CAAC;IACnB,gEAAgE;IAChE,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,kEAAkE;IAClE,aAAa,EAAE,SAAS,GAAG,SAAS,CAAC;IACrC,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,8CAA8C;IAC9C,gBAAgB,EAAE,OAAO,CAAC;IAC1B,oDAAoD;IACpD,YAAY,EAAE,OAAO,CAAC;IACtB,oDAAoD;IACpD,SAAS,EAAE,OAAO,CAAC;IACnB,2CAA2C;IAC3C,QAAQ,EAAE,OAAO,CAAC;IAClB,4DAA4D;IAC5D,UAAU,EAAE,OAAO,CAAC;IACpB,8CAA8C;IAC9C,OAAO,EAAE,OAAO,CAAC;CACjB;AA0DD,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,gBAAgB,GAAG,IAAI,CAKxG"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createReadToolDefinition, createBashToolDefinition, createEditToolDefinition, createWriteToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { Text } from "@earendil-works/pi-tui";
|
|
3
|
+
import { renderBlock } from "./render.js";
|
|
4
|
+
function override(pi, name, cwd, factory, cfgGetter) {
|
|
5
|
+
const original = factory(cwd);
|
|
6
|
+
const renderCall = (args, theme, context) => {
|
|
7
|
+
const config = cfgGetter();
|
|
8
|
+
if (config.mode === "native") {
|
|
9
|
+
return original.renderCall?.(args, theme, context) ?? new Text("", 0, 0);
|
|
10
|
+
}
|
|
11
|
+
return renderBlock(context, {
|
|
12
|
+
name: name,
|
|
13
|
+
stage: "call",
|
|
14
|
+
args: context.args,
|
|
15
|
+
result: undefined,
|
|
16
|
+
cwd: context.cwd,
|
|
17
|
+
config: config,
|
|
18
|
+
theme: theme,
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
const renderResult = (result, options, theme, context) => {
|
|
22
|
+
const config = cfgGetter();
|
|
23
|
+
if (config.mode === "native") {
|
|
24
|
+
return original.renderResult?.(result, options, theme, context) ?? new Text("", 0, 0);
|
|
25
|
+
}
|
|
26
|
+
return renderBlock(context, {
|
|
27
|
+
name: name,
|
|
28
|
+
stage: "result",
|
|
29
|
+
args: context.args,
|
|
30
|
+
result,
|
|
31
|
+
cwd: context.cwd,
|
|
32
|
+
config: config,
|
|
33
|
+
theme: theme,
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
pi.registerTool({
|
|
37
|
+
...original,
|
|
38
|
+
renderShell: "self",
|
|
39
|
+
execute: original.execute, // 原样委托,行为不变(D1/D8)
|
|
40
|
+
renderCall: renderCall,
|
|
41
|
+
renderResult: renderResult,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
export function registerOverrides(pi, cwd, cfgGetter) {
|
|
45
|
+
override(pi, "read", cwd, createReadToolDefinition, cfgGetter);
|
|
46
|
+
override(pi, "write", cwd, createWriteToolDefinition, cfgGetter);
|
|
47
|
+
override(pi, "edit", cwd, createEditToolDefinition, cfgGetter);
|
|
48
|
+
override(pi, "bash", cwd, createBashToolDefinition, cfgGetter);
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=overrides.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overrides.js","sourceRoot":"","sources":["../src/overrides.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAE1J,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAG9C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAkC1C,SAAS,QAAQ,CACf,EAAgB,EAChB,IAAY,EACZ,GAAW,EACX,OAAmB,EACnB,SAAiC;IAEjC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAE9B,MAAM,UAAU,GAAG,CAAC,IAAa,EAAE,KAAY,EAAE,OAA0B,EAAa,EAAE;QACxF,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7B,OAAQ,QAAQ,CAAC,UAAU,EAAE,CAAC,IAAa,EAAE,KAAc,EAAE,OAAO,CAAe,IAAI,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5G,CAAC;QACD,OAAO,WAAW,CAAC,OAAO,EAAE;YAC1B,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,MAAM;YACb,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,MAAM,EAAE,SAAS;YACjB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,MAAM,EAAE,MAAM;YACd,KAAK,EAAE,KAAK;SACb,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,CACnB,MAAe,EACf,OAAkD,EAClD,KAAY,EACZ,OAA0B,EACf,EAAE;QACb,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7B,OAAQ,QAAQ,CAAC,YAAY,EAAE,CAAC,MAAe,EAAE,OAAgB,EAAE,KAAc,EAAE,OAAO,CAAe,IAAI,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAClI,CAAC;QACD,OAAO,WAAW,CAAC,OAAO,EAAE;YAC1B,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,QAAQ;YACf,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,MAAM;YACN,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,MAAM,EAAE,MAAM;YACd,KAAK,EAAE,KAAK;SACb,CAAC,CAAC;IACL,CAAC,CAAC;IACF,EAAE,CAAC,YAAY,CAAC;QACd,GAAG,QAAQ;QACX,WAAW,EAAE,MAAM;QACnB,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,mBAAmB;QAC9C,UAAU,EAAE,UAAmB;QAC/B,YAAY,EAAE,YAAqB;KACpC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,EAAgB,EAAE,GAAW,EAAE,SAAiC;IAChG,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,wBAAiC,EAAE,SAAS,CAAC,CAAC;IACxE,QAAQ,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,yBAAkC,EAAE,SAAS,CAAC,CAAC;IAC1E,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,wBAAiC,EAAE,SAAS,CAAC,CAAC;IACxE,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,wBAAiC,EAAE,SAAS,CAAC,CAAC;AAC1E,CAAC"}
|
package/dist/render.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type Component } from "@earendil-works/pi-tui";
|
|
2
|
+
import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
import type { FoldBlocksConfig } from "./config.js";
|
|
4
|
+
import type { ToolRenderContext } from "./overrides.js";
|
|
5
|
+
export interface RenderBlockOpts {
|
|
6
|
+
name: string;
|
|
7
|
+
stage: "call" | "result";
|
|
8
|
+
args: unknown;
|
|
9
|
+
result?: unknown;
|
|
10
|
+
cwd: string;
|
|
11
|
+
config: FoldBlocksConfig;
|
|
12
|
+
theme: Theme;
|
|
13
|
+
}
|
|
14
|
+
export interface LineContext {
|
|
15
|
+
icon?: string;
|
|
16
|
+
tool: string;
|
|
17
|
+
shown: string;
|
|
18
|
+
tips?: string;
|
|
19
|
+
result?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function buildReadBlockText(ctx: ToolRenderContext, opts: RenderBlockOpts): LineContext;
|
|
22
|
+
export declare function buildWriteBlockText(ctx: ToolRenderContext, opts: RenderBlockOpts): LineContext;
|
|
23
|
+
export declare function buildEditBlockText(ctx: ToolRenderContext, opts: RenderBlockOpts): LineContext;
|
|
24
|
+
export declare function buildGrepBlockText(ctx: ToolRenderContext, opts: RenderBlockOpts): LineContext;
|
|
25
|
+
export declare function buildLsBlockText(ctx: ToolRenderContext, opts: RenderBlockOpts): LineContext;
|
|
26
|
+
/** 从 AgentToolResult.content 提取退出码(形如 "exit code N");提取失败返回 undefined。 */
|
|
27
|
+
export declare function contentExitCode(result: unknown): number | undefined;
|
|
28
|
+
/** 从 AgentToolResult.content 统计输出行数(含空行);result 缺失/为空 → 0。
|
|
29
|
+
* 末尾 "\n" 不计独立行,这是文本文件/管道输出的常见约定("a\nb\n" = 2 行而非 3)。 */
|
|
30
|
+
export declare function contentLineCount(result: unknown): number;
|
|
31
|
+
export declare function buildBashBlockText(ctx: ToolRenderContext, opts: RenderBlockOpts): LineContext;
|
|
32
|
+
/**
|
|
33
|
+
* 构造单行块组件树,交给 pi-tui 布局系统随终端宽度实时重算,不再在构造时用
|
|
34
|
+
* process.stdout.columns 预拼字符串(旧 buildBlockText 的 resize 不刷新问题即来源于此)。
|
|
35
|
+
*
|
|
36
|
+
* 结构:
|
|
37
|
+
* BgPaddedBox(padX=1, padY=1, bgFn) ← 左右/上下留白 + 全行 reBg(含右 padding)
|
|
38
|
+
* └ HStack(gap=1) ← 左右布局,宽度随 render(width) 实时重算
|
|
39
|
+
* ├ BgTruncatedText(left) grow:1 shrink:1 minSize:0 ← 占满剩余宽度,过长截断(不换行)
|
|
40
|
+
* ├ BgTruncatedText(tips) grow:0 shrink:0 ← 完整保留,不被截断
|
|
41
|
+
* └ BgTruncatedText(right) grow:0 shrink:0 ← 自然宽度,贴右
|
|
42
|
+
*
|
|
43
|
+
* tips 独立成段(grow:0 shrink:0):空间不足时只有 left 的 shown 被截断,tips(如行号范围)
|
|
44
|
+
* 始终完整显示。HStack gap=1 保证 left 与 right 之间留 1 字符 padding。
|
|
45
|
+
*
|
|
46
|
+
* HStack.render(width) 先测各子组件 intrinsic 宽度(Intrinsic = render(safeWidth) 的可见宽,
|
|
47
|
+
* 但 BgTruncatedText 输出恒 pad 到 width → intrinsic 恒等于 safeWidth,会误导分配),
|
|
48
|
+
* 改指定 basis = 内容自然可见宽度,让 allocateStackSizes 跳过 intrinsic、以 basis 为起点:
|
|
49
|
+
* - 左槽 grow:1 shrink:1 → 填满 contentSize - rightW;溢出时回退到 minSize:0;
|
|
50
|
+
* - 右槽 shrink:0 grow:0 → 恒为自身可见宽度,贴右边。
|
|
51
|
+
* thus 左截断、右贴边,每次 render 都以传入 width 重算,resize 即时生效。
|
|
52
|
+
*/
|
|
53
|
+
export declare function buildBlockComponent(text: LineContext, bgFn: (line: string) => string): Component;
|
|
54
|
+
export declare function renderBlock(ctx: ToolRenderContext, opts: RenderBlockOpts): Component;
|
|
55
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AACA,OAAO,EAA+C,KAAK,SAAS,EAAmB,MAAM,wBAAwB,CAAC;AACtH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,gBAAgB,CAAC;IACzB,KAAK,EAAE,KAAK,CAAC;CACd;AAMD,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAOD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,iBAAiB,EAAE,IAAI,EAAE,eAAe,GAAG,WAAW,CAiB7F;AAMD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,iBAAiB,EAAE,IAAI,EAAE,eAAe,GAAG,WAAW,CAa9F;AAMD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,iBAAiB,EAAE,IAAI,EAAE,eAAe,GAAG,WAAW,CAe7F;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,iBAAiB,EAAE,IAAI,EAAE,eAAe,GAAG,WAAW,CAU7F;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,iBAAiB,EAAE,IAAI,EAAE,eAAe,GAAG,WAAW,CAU3F;AAMD,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAMnE;AACD;yDACyD;AACzD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAOxD;AACD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,iBAAiB,EAAE,IAAI,EAAE,eAAe,GAAG,WAAW,CAuB7F;AA6FD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,WAAW,EACjB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAC7B,SAAS,CAiBX;AASD,wBAAgB,WAAW,CAAC,GAAG,EAAE,iBAAiB,EAAE,IAAI,EAAE,eAAe,GAAG,SAAS,CA0BpF"}
|
package/dist/render.js
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
// packages/pi-tui-fold-blocks/src/render.ts
|
|
2
|
+
import { Text, HStack, visibleWidth, truncateToWidth } from "@earendil-works/pi-tui";
|
|
3
|
+
import { foldPath } from "./folders/path.js";
|
|
4
|
+
import { foldCommand } from "./folders/command.js";
|
|
5
|
+
function countRows(content) {
|
|
6
|
+
return content.split("\n").reduce((n, v) => v.trim() ? n + 1 : n, 0);
|
|
7
|
+
}
|
|
8
|
+
export function buildReadBlockText(ctx, opts) {
|
|
9
|
+
const args = ctx.args;
|
|
10
|
+
const shown = foldPath(args.path ?? "", { cwd: opts.cwd, style: opts.config.fileBlocks.pathStyle, foldGitWorktree: opts.config.fileBlocks.foldGitWorktree });
|
|
11
|
+
const startLine = args.offset ?? 1;
|
|
12
|
+
const endLine = args.limit !== undefined ? startLine + args.limit - 1 : "?";
|
|
13
|
+
// 默认读整文件(offset 缺省 + limit 缺省)→ 显示为 "1-?",纯噪声,隐藏。
|
|
14
|
+
// 显式 offset=1 同样落到 1-?,一并隐藏(等价于不写 offset)。
|
|
15
|
+
const tips = (startLine === 1 && endLine === "?") ? "" : `[ ${startLine} - ${endLine} ]`;
|
|
16
|
+
return {
|
|
17
|
+
icon: opts.config.nerdFont ? "\udb85\uddd6" : "",
|
|
18
|
+
tool: "read",
|
|
19
|
+
shown: shown,
|
|
20
|
+
tips: tips,
|
|
21
|
+
result: opts.stage === "call" ? ""
|
|
22
|
+
: ctx.isError ? "FAILED"
|
|
23
|
+
: "SUCCESS"
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export function buildWriteBlockText(ctx, opts) {
|
|
27
|
+
const args = ctx.args;
|
|
28
|
+
const shown = foldPath(args.path ?? "", { cwd: opts.cwd, style: opts.config.fileBlocks.pathStyle, foldGitWorktree: opts.config.fileBlocks.foldGitWorktree });
|
|
29
|
+
const rowCount = countRows(args.content);
|
|
30
|
+
return {
|
|
31
|
+
icon: opts.config.nerdFont ? "\ue27c" : "",
|
|
32
|
+
tool: "write",
|
|
33
|
+
shown: shown,
|
|
34
|
+
tips: `[ +${rowCount} ]`,
|
|
35
|
+
result: opts.stage === "call" ? ""
|
|
36
|
+
: ctx.isError ? "FAILED"
|
|
37
|
+
: "SUCCESS"
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export function buildEditBlockText(ctx, opts) {
|
|
41
|
+
const args = ctx.args;
|
|
42
|
+
const shown = foldPath(args.path ?? "", { cwd: opts.cwd, style: opts.config.fileBlocks.pathStyle, foldGitWorktree: opts.config.fileBlocks.foldGitWorktree });
|
|
43
|
+
const countOldRows = args.edits.reduce((n, v) => n + countRows(v.oldText), 0);
|
|
44
|
+
const countNewRows = args.edits.reduce((n, v) => n + countRows(v.newText), 0);
|
|
45
|
+
return {
|
|
46
|
+
icon: opts.config.nerdFont ? "\uF044" : "",
|
|
47
|
+
tool: "write",
|
|
48
|
+
shown: shown,
|
|
49
|
+
tips: `[ -${countOldRows}, +${countNewRows} ]`,
|
|
50
|
+
result: opts.stage === "call" ? ""
|
|
51
|
+
: ctx.isError ? "FAILED"
|
|
52
|
+
: "SUCCESS"
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export function buildGrepBlockText(ctx, opts) {
|
|
56
|
+
return {
|
|
57
|
+
icon: opts.config.nerdFont ? "\udb83\udc7c" : "",
|
|
58
|
+
tool: "grep",
|
|
59
|
+
shown: "",
|
|
60
|
+
tips: "",
|
|
61
|
+
result: opts.stage === "call" ? ""
|
|
62
|
+
: ctx.isError ? "FAILED"
|
|
63
|
+
: "SUCCESS"
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export function buildLsBlockText(ctx, opts) {
|
|
67
|
+
return {
|
|
68
|
+
icon: opts.config.nerdFont ? "\uf07c" : "",
|
|
69
|
+
tool: "ls",
|
|
70
|
+
shown: "",
|
|
71
|
+
tips: "",
|
|
72
|
+
result: opts.stage === "call" ? ""
|
|
73
|
+
: ctx.isError ? "FAILED"
|
|
74
|
+
: "SUCCESS"
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/** 从 AgentToolResult.content 提取退出码(形如 "exit code N");提取失败返回 undefined。 */
|
|
78
|
+
export function contentExitCode(result) {
|
|
79
|
+
const content = result?.content;
|
|
80
|
+
if (!Array.isArray(content))
|
|
81
|
+
return undefined;
|
|
82
|
+
const text = content.map((c) => c.text ?? "").join("\n");
|
|
83
|
+
const m = /exit code (\d+)/i.exec(text);
|
|
84
|
+
return m ? Number(m[1]) : undefined;
|
|
85
|
+
}
|
|
86
|
+
/** 从 AgentToolResult.content 统计输出行数(含空行);result 缺失/为空 → 0。
|
|
87
|
+
* 末尾 "\n" 不计独立行,这是文本文件/管道输出的常见约定("a\nb\n" = 2 行而非 3)。 */
|
|
88
|
+
export function contentLineCount(result) {
|
|
89
|
+
const content = result?.content;
|
|
90
|
+
if (!Array.isArray(content) || content.length === 0)
|
|
91
|
+
return 0;
|
|
92
|
+
const text = content.map((c) => c.text ?? "").join("");
|
|
93
|
+
if (text === "")
|
|
94
|
+
return 0;
|
|
95
|
+
const lines = text.split("\n");
|
|
96
|
+
return lines[lines.length - 1] === "" ? lines.length - 1 : lines.length;
|
|
97
|
+
}
|
|
98
|
+
export function buildBashBlockText(ctx, opts) {
|
|
99
|
+
const args = ctx.args;
|
|
100
|
+
const shown = foldCommand(args.command, { smart: opts.config.bashBlocks.smart });
|
|
101
|
+
// 仅在 result 阶段提取统计量:call 阶段 opts.result 尚未就绪,提取无意义。
|
|
102
|
+
const errorCode = opts.stage === "result" ? contentExitCode(opts.result) : undefined;
|
|
103
|
+
const lineCount = opts.stage === "result" ? contentLineCount(opts.result) : undefined;
|
|
104
|
+
// tips 仅在确有信息时显示,各段用 ", " 拼接。
|
|
105
|
+
// 行数:output 行数(含空行);0 行不显示(空输出挂个 [ 0 lines ] 是噪声)。
|
|
106
|
+
// exit 码:仅 failed 时显示,与 result 的 FAILED(M) 互补。
|
|
107
|
+
const tipParts = [];
|
|
108
|
+
if (args.timeout !== undefined)
|
|
109
|
+
tipParts.push(`${args.timeout}s`);
|
|
110
|
+
if (lineCount !== undefined && lineCount > 0)
|
|
111
|
+
tipParts.push(`${lineCount} lines`);
|
|
112
|
+
if (ctx.isError && errorCode !== undefined && errorCode !== 0)
|
|
113
|
+
tipParts.push(`exit ${errorCode}`);
|
|
114
|
+
const tips = tipParts.length > 0 ? `[ ${tipParts.join(", ")} ]` : "";
|
|
115
|
+
return {
|
|
116
|
+
icon: opts.config.nerdFont ? "\uf489" : "",
|
|
117
|
+
tool: "exec",
|
|
118
|
+
shown: shown,
|
|
119
|
+
tips: tips,
|
|
120
|
+
result: opts.stage === "call" ? ""
|
|
121
|
+
: ctx.isError ? (errorCode !== undefined ? `FAILED(${errorCode})` : "FAILED")
|
|
122
|
+
: "SUCCESS"
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/** 左半段:icon + tool + shown(tips 独立成段,保证折叠时不丢失)。 */
|
|
126
|
+
function buildLeft(text) {
|
|
127
|
+
return `${text.icon ?? ""} ${text.tool} - ${text.shown}`.trim();
|
|
128
|
+
}
|
|
129
|
+
/** 右半段:result / 退出码。 */
|
|
130
|
+
function buildRight(text) {
|
|
131
|
+
return (text.result ?? "").trim();
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* 自带背景的截断文本(替代 TruncatedText:后者没有 customBgFn,无法上色)。
|
|
135
|
+
*
|
|
136
|
+
* 为什么不直接用 Box 整行套 bg:pi-tui 的 `theme.bg(color, text)` 形如 `${ansi}${text}\x1b[49m`,
|
|
137
|
+
* 只在首尾包一次。而 HStack.render 的 compositeTuiLine 会在每段子组件之间插入
|
|
138
|
+
* `SEGMENT_RESET = "\x1b[0m\x1b]8;;\x07"`,其中 `\x1b[0m` 是全量重置 → 会清掉已在行的 bg,
|
|
139
|
+
* 之后不再重建,导致 Box 的单次包裹只覆盖到首个 segment 边界。同理 truncateToWidth 在
|
|
140
|
+
* 截断省略号前也会插入 `\x1b[0m`,使 `...` 丢色。
|
|
141
|
+
*
|
|
142
|
+
* 修法:让每个子组件自带 bg,且把行按 `\x1b[0m` 分片、每片重新套 bg —— 这样任何
|
|
143
|
+
* reset 之后紧跟的下一个可见片段都会重新建立 bg,跨 segment 边界 / 省略号都能连续着色。
|
|
144
|
+
* (\x1b[0m 本身零宽,不会产生可见空隙。)
|
|
145
|
+
*/
|
|
146
|
+
class BgTruncatedText {
|
|
147
|
+
text;
|
|
148
|
+
bgFn;
|
|
149
|
+
constructor(text, bgFn) {
|
|
150
|
+
this.text = text;
|
|
151
|
+
this.bgFn = bgFn;
|
|
152
|
+
}
|
|
153
|
+
invalidate() {
|
|
154
|
+
// 无缓存(每次 render 直接按 width 计算)
|
|
155
|
+
}
|
|
156
|
+
render(width) {
|
|
157
|
+
const w = Math.max(0, Math.floor(width));
|
|
158
|
+
if (w === 0)
|
|
159
|
+
return [];
|
|
160
|
+
// truncateToWidth(maxWidth, "...", pad=true):截断并 pad 到恰好 w 可见宽。空文本 → 全空格。
|
|
161
|
+
const line = truncateToWidth(this.text, w, "...", true);
|
|
162
|
+
return [this.reBg(line)];
|
|
163
|
+
}
|
|
164
|
+
reBg(line) {
|
|
165
|
+
return line.split("\x1b[0m").map((chunk) => this.bgFn(chunk)).join("\x1b[0m");
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* 带 padding + 背景的容器(替代 pi-tui 的 Box:后者 applyBg = `bgFn(line + trailingPad)`
|
|
170
|
+
* 只在最外层包一次,行内一旦出现 `\x1b[0m` 全量重置就把那次包裹清掉,导致 trailing 右 padding
|
|
171
|
+
* 落在最后一个 reset 之后、无 bg)。本容器把 "左 padding + 子组件行 + 右 padding" 拼好后
|
|
172
|
+
* 走 reBg(按 `\x1b[0m` 分片、每片各套 bgFn 再 join),任何 reset 之后紧跟的片段(含右 padding
|
|
173
|
+
* 空格、上下留白行)都会重新建立 bg → 全行连续着色。`\x1b[0m` 本身零宽,不产生可见空隙。
|
|
174
|
+
*/
|
|
175
|
+
class BgPaddedBox {
|
|
176
|
+
child;
|
|
177
|
+
paddingX;
|
|
178
|
+
paddingY;
|
|
179
|
+
bgFn;
|
|
180
|
+
constructor(child, paddingX, paddingY, bgFn) {
|
|
181
|
+
this.child = child;
|
|
182
|
+
this.paddingX = paddingX;
|
|
183
|
+
this.paddingY = paddingY;
|
|
184
|
+
this.bgFn = bgFn;
|
|
185
|
+
}
|
|
186
|
+
invalidate() {
|
|
187
|
+
this.child.invalidate?.();
|
|
188
|
+
}
|
|
189
|
+
render(width) {
|
|
190
|
+
const w = Math.max(0, Math.floor(width));
|
|
191
|
+
if (w === 0)
|
|
192
|
+
return [];
|
|
193
|
+
const padX = Math.min(this.paddingX, Math.max(0, Math.floor((w - 1) / 2)));
|
|
194
|
+
const contentWidth = Math.max(1, w - padX * 2);
|
|
195
|
+
const childLines = this.child.render(contentWidth);
|
|
196
|
+
if (childLines.length === 0) {
|
|
197
|
+
// 仍需输出 paddingY*2+1 行 bg 空行,避免整块高度塌陷导致 SDK 容器重排闪烁
|
|
198
|
+
const empty = this.reBg(" ".repeat(w));
|
|
199
|
+
const rows = [];
|
|
200
|
+
for (let i = 0; i < this.paddingY * 2 + 1; i++)
|
|
201
|
+
rows.push(empty);
|
|
202
|
+
return rows;
|
|
203
|
+
}
|
|
204
|
+
const leftPad = " ".repeat(padX);
|
|
205
|
+
const rows = [];
|
|
206
|
+
// 上留白
|
|
207
|
+
const topEmpty = this.reBg(" ".repeat(w));
|
|
208
|
+
for (let i = 0; i < this.paddingY; i++)
|
|
209
|
+
rows.push(topEmpty);
|
|
210
|
+
// 内容行:左 padding + 子行,再 pad 到 w,整体 reBg
|
|
211
|
+
for (const line of childLines) {
|
|
212
|
+
const withLeft = leftPad + line;
|
|
213
|
+
const vis = visibleWidth(withLeft);
|
|
214
|
+
const rightPad = Math.max(0, w - vis);
|
|
215
|
+
rows.push(this.reBg(withLeft + " ".repeat(rightPad)));
|
|
216
|
+
}
|
|
217
|
+
// 下留白
|
|
218
|
+
for (let i = 0; i < this.paddingY; i++)
|
|
219
|
+
rows.push(topEmpty);
|
|
220
|
+
return rows;
|
|
221
|
+
}
|
|
222
|
+
reBg(line) {
|
|
223
|
+
return line.split("\x1b[0m").map((chunk) => this.bgFn(chunk)).join("\x1b[0m");
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* 构造单行块组件树,交给 pi-tui 布局系统随终端宽度实时重算,不再在构造时用
|
|
228
|
+
* process.stdout.columns 预拼字符串(旧 buildBlockText 的 resize 不刷新问题即来源于此)。
|
|
229
|
+
*
|
|
230
|
+
* 结构:
|
|
231
|
+
* BgPaddedBox(padX=1, padY=1, bgFn) ← 左右/上下留白 + 全行 reBg(含右 padding)
|
|
232
|
+
* └ HStack(gap=1) ← 左右布局,宽度随 render(width) 实时重算
|
|
233
|
+
* ├ BgTruncatedText(left) grow:1 shrink:1 minSize:0 ← 占满剩余宽度,过长截断(不换行)
|
|
234
|
+
* ├ BgTruncatedText(tips) grow:0 shrink:0 ← 完整保留,不被截断
|
|
235
|
+
* └ BgTruncatedText(right) grow:0 shrink:0 ← 自然宽度,贴右
|
|
236
|
+
*
|
|
237
|
+
* tips 独立成段(grow:0 shrink:0):空间不足时只有 left 的 shown 被截断,tips(如行号范围)
|
|
238
|
+
* 始终完整显示。HStack gap=1 保证 left 与 right 之间留 1 字符 padding。
|
|
239
|
+
*
|
|
240
|
+
* HStack.render(width) 先测各子组件 intrinsic 宽度(Intrinsic = render(safeWidth) 的可见宽,
|
|
241
|
+
* 但 BgTruncatedText 输出恒 pad 到 width → intrinsic 恒等于 safeWidth,会误导分配),
|
|
242
|
+
* 改指定 basis = 内容自然可见宽度,让 allocateStackSizes 跳过 intrinsic、以 basis 为起点:
|
|
243
|
+
* - 左槽 grow:1 shrink:1 → 填满 contentSize - rightW;溢出时回退到 minSize:0;
|
|
244
|
+
* - 右槽 shrink:0 grow:0 → 恒为自身可见宽度,贴右边。
|
|
245
|
+
* thus 左截断、右贴边,每次 render 都以传入 width 重算,resize 即时生效。
|
|
246
|
+
*/
|
|
247
|
+
export function buildBlockComponent(text, bgFn) {
|
|
248
|
+
const left = buildLeft(text);
|
|
249
|
+
const tips = (text.tips ?? "").trim();
|
|
250
|
+
const right = buildRight(text);
|
|
251
|
+
const leftW = visibleWidth(left);
|
|
252
|
+
const tipsW = visibleWidth(tips);
|
|
253
|
+
const rightW = visibleWidth(right);
|
|
254
|
+
const children = [
|
|
255
|
+
{ component: new BgTruncatedText(left, bgFn), basis: leftW, grow: 1, shrink: 1, minSize: 0 },
|
|
256
|
+
];
|
|
257
|
+
// tips 为空时不插入中间槽,避免 HStack 对零宽 entry 也加 gap(会导致 left/right 间隙 2 字符)
|
|
258
|
+
if (tipsW > 0) {
|
|
259
|
+
children.push({ component: new BgTruncatedText(tips, bgFn), basis: tipsW, grow: 0, shrink: 0 });
|
|
260
|
+
}
|
|
261
|
+
children.push({ component: new BgTruncatedText(right, bgFn), basis: rightW, grow: 0, shrink: 0 });
|
|
262
|
+
const hstack = new HStack(children, { gap: 1, align: "stretch" });
|
|
263
|
+
return new BgPaddedBox(hstack, 1, 1, bgFn);
|
|
264
|
+
}
|
|
265
|
+
/** 背景:文件块恒绿;bash 按 isPartial(黄)/isError(红)/成功(绿)。 */
|
|
266
|
+
function bgFor(ctx, opts) {
|
|
267
|
+
if (opts.stage === "call")
|
|
268
|
+
return (t) => opts.theme.bg("toolPendingBg", t);
|
|
269
|
+
if (ctx.isError)
|
|
270
|
+
return (t) => opts.theme.bg("toolErrorBg", t);
|
|
271
|
+
return (t) => opts.theme.bg("toolSuccessBg", t);
|
|
272
|
+
}
|
|
273
|
+
export function renderBlock(ctx, opts) {
|
|
274
|
+
if (opts.config.mode === "hide")
|
|
275
|
+
return new Text("", 0, 0); // 空 Text → 0 行 → 块整体消失
|
|
276
|
+
// SDK 的 ToolExecutionComponent.updateDisplay 会把 renderCall 与 renderResult 的返回值
|
|
277
|
+
// 作为两个独立子组件加入同一个容器(call 槽在前,result 槽在后)。若两者都返回可见行,同一个
|
|
278
|
+
// tool call 会被渲染成两行(调用行 + 结果行)。为保持"单行"语义,任意时刻只让一个槽产出可见
|
|
279
|
+
// 行,另一个槽返回 0 行空 Text:
|
|
280
|
+
// - 尚无最终结果(ctx.isPartial === true:调用阶段或 partial 流式)→ call 槽拥有该行;
|
|
281
|
+
// - 最终结果到达(ctx.isPartial === false:tool_execution_end)→ result 槽拥有该行,call 槽退让。
|
|
282
|
+
// isPartial 由 SDK 维护:构造时为 true,tool_execution_end 置 false,partial update 仍为 true。
|
|
283
|
+
// 用 isPartial 而非跨槽 state,是因为 call 槽先于 result 槽执行,无法在单帧内获知 result 槽
|
|
284
|
+
// 是否会运行;isPartial 在帧开始前就已就绪,单帧即可定正确归属,无 flicker、无需 invalidate。
|
|
285
|
+
const ownsLine = opts.stage === "call" ? ctx.isPartial : !ctx.isPartial;
|
|
286
|
+
if (!ownsLine)
|
|
287
|
+
return new Text("", 0, 0);
|
|
288
|
+
var text;
|
|
289
|
+
switch (opts.name) {
|
|
290
|
+
case "read":
|
|
291
|
+
text = buildReadBlockText(ctx, opts);
|
|
292
|
+
break;
|
|
293
|
+
case "write":
|
|
294
|
+
text = buildWriteBlockText(ctx, opts);
|
|
295
|
+
break;
|
|
296
|
+
case "edit":
|
|
297
|
+
text = buildWriteBlockText(ctx, opts);
|
|
298
|
+
break;
|
|
299
|
+
case "bash":
|
|
300
|
+
text = buildBashBlockText(ctx, opts);
|
|
301
|
+
break;
|
|
302
|
+
default:
|
|
303
|
+
return new Text("", 0, 0);
|
|
304
|
+
}
|
|
305
|
+
return buildBlockComponent(text, bgFor(ctx, opts));
|
|
306
|
+
}
|
|
307
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type ExtensionUIContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { type SettingItem } from "@earendil-works/pi-tui";
|
|
3
|
+
import { type FoldBlocksConfig } from "./config.js";
|
|
4
|
+
export declare function boolToCfg(value: boolean): "on" | "off";
|
|
5
|
+
export declare function cfgToBool(value: string): boolean;
|
|
6
|
+
export declare function buildSettingItems(cfg: FoldBlocksConfig): SettingItem[];
|
|
7
|
+
export declare function applySettingChange(cfg: FoldBlocksConfig, id: string, newValue: string): FoldBlocksConfig;
|
|
8
|
+
export declare function openSettings(ui: ExtensionUIContext, config: FoldBlocksConfig, onSave: (cfg: FoldBlocksConfig) => void): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AACA,OAAO,EAAwB,KAAK,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAChG,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAE,KAAK,gBAAgB,EAAa,MAAM,aAAa,CAAC;AAE/D,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,GAAG,KAAK,CAEtD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,gBAAgB,GAAG,WAAW,EAAE,CAStE;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,gBAAgB,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CA2BxG;AAED,wBAAsB,YAAY,CAChC,EAAE,EAAE,kBAAkB,EACtB,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,IAAI,GACtC,OAAO,CAAC,IAAI,CAAC,CAqBf"}
|
package/dist/settings.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// packages/pi-tui-fold-blocks/src/settings.ts
|
|
2
|
+
import { getSettingsListTheme } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
import { SettingsList } from "@earendil-works/pi-tui";
|
|
4
|
+
import {} from "./config.js";
|
|
5
|
+
export function boolToCfg(value) {
|
|
6
|
+
return value ? "on" : "off";
|
|
7
|
+
}
|
|
8
|
+
export function cfgToBool(value) {
|
|
9
|
+
return value === "on";
|
|
10
|
+
}
|
|
11
|
+
export function buildSettingItems(cfg) {
|
|
12
|
+
return [
|
|
13
|
+
{ id: "mode", label: "Fold Mode", currentValue: cfg.mode, values: ["fold", "hide", "native"] },
|
|
14
|
+
{ id: "nerdFont", label: "Nerd font icons", currentValue: boolToCfg(cfg.nerdFont), values: ["on", "off"] },
|
|
15
|
+
{ id: "fileBlocks.pathStyle", label: "Fold path style", currentValue: cfg.fileBlocks.pathStyle, values: ["relative", "absolute", "basename"] },
|
|
16
|
+
{ id: "fileBlocks.foldGitWorktree", label: "Fold git worktree", currentValue: boolToCfg(cfg.fileBlocks.foldGitWorktree), values: ["on", "off"] },
|
|
17
|
+
{ id: "bashBlocks.smart", label: "Fold bash call", currentValue: boolToCfg(cfg.bashBlocks.smart), values: ["on", "off"] },
|
|
18
|
+
{ id: "bashBlocks.showStatus", label: "Show bash status hints", currentValue: boolToCfg(cfg.bashBlocks.showStatus), values: ["on", "off"] },
|
|
19
|
+
];
|
|
20
|
+
}
|
|
21
|
+
export function applySettingChange(cfg, id, newValue) {
|
|
22
|
+
const next = {
|
|
23
|
+
...cfg,
|
|
24
|
+
fileBlocks: { ...cfg.fileBlocks },
|
|
25
|
+
bashBlocks: { ...cfg.bashBlocks },
|
|
26
|
+
};
|
|
27
|
+
switch (id) {
|
|
28
|
+
case "mode":
|
|
29
|
+
next.mode = newValue;
|
|
30
|
+
break;
|
|
31
|
+
case "nerdFont":
|
|
32
|
+
next.nerdFont = cfgToBool(newValue);
|
|
33
|
+
break;
|
|
34
|
+
case "fileBlocks.pathStyle":
|
|
35
|
+
next.fileBlocks.pathStyle = newValue;
|
|
36
|
+
break;
|
|
37
|
+
case "fileBlocks.foldGitWorktree":
|
|
38
|
+
next.fileBlocks.foldGitWorktree = cfgToBool(newValue);
|
|
39
|
+
break;
|
|
40
|
+
case "bashBlocks.smart":
|
|
41
|
+
next.bashBlocks.smart = cfgToBool(newValue);
|
|
42
|
+
break;
|
|
43
|
+
case "bashBlocks.showStatus":
|
|
44
|
+
next.bashBlocks.showStatus = cfgToBool(newValue);
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
return next;
|
|
48
|
+
}
|
|
49
|
+
export async function openSettings(ui, config, onSave) {
|
|
50
|
+
let cfg = config;
|
|
51
|
+
await ui.custom((_tui, _theme, _kb, done) => {
|
|
52
|
+
const items = buildSettingItems(cfg);
|
|
53
|
+
const settingsList = new SettingsList(items, Math.min(items.length + 2, 15), getSettingsListTheme(), (id, newValue) => {
|
|
54
|
+
cfg = applySettingChange(cfg, id, newValue);
|
|
55
|
+
onSave(cfg);
|
|
56
|
+
}, () => done(undefined), { enableSearch: false });
|
|
57
|
+
return {
|
|
58
|
+
render: (w) => settingsList.render(w),
|
|
59
|
+
invalidate: () => settingsList.invalidate(),
|
|
60
|
+
handleInput: (data) => settingsList.handleInput?.(data),
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,OAAO,EAAE,oBAAoB,EAA2B,MAAM,iCAAiC,CAAC;AAChG,OAAO,EAAE,YAAY,EAAoB,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAoC,MAAM,aAAa,CAAC;AAE/D,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,OAAO,KAAK,KAAK,IAAI,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAqB;IACrD,OAAO;QACL,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE;QAC9F,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;QAC1G,EAAE,EAAE,EAAE,sBAAsB,EAAE,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,GAAG,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE;QAC9I,EAAE,EAAE,EAAE,4BAA4B,EAAE,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;QAChJ,EAAE,EAAE,EAAE,kBAAkB,EAAE,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;QACzH,EAAE,EAAE,EAAE,uBAAuB,EAAE,KAAK,EAAE,wBAAwB,EAAE,YAAY,EAAE,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;KAC5I,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAqB,EAAE,EAAU,EAAE,QAAgB;IACpF,MAAM,IAAI,GAAqB;QAC7B,GAAG,GAAG;QACN,UAAU,EAAE,EAAE,GAAG,GAAG,CAAC,UAAU,EAAE;QACjC,UAAU,EAAE,EAAE,GAAG,GAAG,CAAC,UAAU,EAAE;KAClC,CAAC;IACF,QAAQ,EAAE,EAAE,CAAC;QACX,KAAK,MAAM;YACT,IAAI,CAAC,IAAI,GAAG,QAAgB,CAAC;YAC7B,MAAM;QACR,KAAK,UAAU;YACb,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;YACpC,MAAM;QACR,KAAK,sBAAsB;YACzB,IAAI,CAAC,UAAU,CAAC,SAAS,GAAG,QAAuD,CAAC;YACpF,MAAM;QACR,KAAK,4BAA4B;YAC/B,IAAI,CAAC,UAAU,CAAC,eAAe,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;YACtD,MAAM;QACR,KAAK,kBAAkB;YACrB,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM;QACR,KAAK,uBAAuB;YAC1B,IAAI,CAAC,UAAU,CAAC,UAAU,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;YACjD,MAAM;IACV,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,EAAsB,EACtB,MAAwB,EACxB,MAAuC;IAEvC,IAAI,GAAG,GAAG,MAAM,CAAC;IACjB,MAAM,EAAE,CAAC,MAAM,CAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAChD,MAAM,KAAK,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;QACrC,MAAM,YAAY,GAAG,IAAI,YAAY,CACnC,KAAK,EACL,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,EAAE,CAAC,EAC9B,oBAAoB,EAAE,EACtB,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE;YACf,GAAG,GAAG,kBAAkB,CAAC,GAAG,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC;YAC5C,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,EACD,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,EACrB,EAAE,YAAY,EAAE,KAAK,EAAE,CACxB,CAAC;QACF,OAAO;YACL,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;YAC7C,UAAU,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE;YAC3C,WAAW,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC;SAChE,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@philogag/pi-tui-fold-blocks",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "pi extension: fold tool call block into one line in tui",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"keywords": [
|
|
18
|
+
"pi",
|
|
19
|
+
"extension",
|
|
20
|
+
"tui",
|
|
21
|
+
"tool-blocks"
|
|
22
|
+
],
|
|
23
|
+
"dependencies": {},
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"@earendil-works/pi-coding-agent": "^0.84.3",
|
|
26
|
+
"@earendil-works/pi-tui": "latest",
|
|
27
|
+
"typebox": "latest"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@earendil-works/pi-coding-agent": "^0.84.3",
|
|
31
|
+
"@earendil-works/pi-tui": "latest",
|
|
32
|
+
"typebox": "latest",
|
|
33
|
+
"typescript": "^5.6.3",
|
|
34
|
+
"vitest": "latest"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsc -b",
|
|
38
|
+
"typecheck": "tsc -b --noEmit",
|
|
39
|
+
"test": "vitest run",
|
|
40
|
+
"lint": "echo \"no linter configured\""
|
|
41
|
+
}
|
|
42
|
+
}
|