@heyhuynhgiabuu/pi-pretty 0.6.4 → 0.6.6
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/CHANGELOG.md +29 -0
- package/dist/autocomplete.d.ts +10 -0
- package/dist/autocomplete.d.ts.map +1 -0
- package/dist/autocomplete.js +64 -0
- package/dist/autocomplete.js.map +1 -0
- package/dist/config.d.ts +33 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +225 -0
- package/dist/config.js.map +1 -0
- package/dist/fff-helpers.d.ts +25 -0
- package/dist/fff-helpers.d.ts.map +1 -0
- package/dist/fff-helpers.js +83 -0
- package/dist/fff-helpers.js.map +1 -0
- package/dist/fff.d.ts +37 -0
- package/dist/fff.d.ts.map +1 -0
- package/dist/fff.js +135 -0
- package/dist/fff.js.map +1 -0
- package/dist/helpers.d.ts +21 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +133 -0
- package/dist/helpers.js.map +1 -0
- package/dist/image.d.ts +24 -0
- package/dist/image.d.ts.map +1 -0
- package/dist/image.js +144 -0
- package/dist/image.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +227 -0
- package/dist/index.js.map +1 -0
- package/dist/multi-grep-fallback.d.ts +30 -0
- package/dist/multi-grep-fallback.d.ts.map +1 -0
- package/dist/multi-grep-fallback.js +205 -0
- package/dist/multi-grep-fallback.js.map +1 -0
- package/dist/notices.d.ts +3 -0
- package/dist/notices.d.ts.map +1 -0
- package/dist/notices.js +6 -0
- package/dist/notices.js.map +1 -0
- package/dist/render.d.ts +25 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +366 -0
- package/dist/render.js.map +1 -0
- package/dist/tools/bash.d.ts +6 -0
- package/dist/tools/bash.d.ts.map +1 -0
- package/dist/tools/bash.js +101 -0
- package/dist/tools/bash.js.map +1 -0
- package/dist/tools/find.d.ts +6 -0
- package/dist/tools/find.d.ts.map +1 -0
- package/dist/tools/find.js +109 -0
- package/dist/tools/find.js.map +1 -0
- package/dist/tools/grep.d.ts +6 -0
- package/dist/tools/grep.d.ts.map +1 -0
- package/dist/tools/grep.js +122 -0
- package/dist/tools/grep.js.map +1 -0
- package/dist/tools/ls.d.ts +6 -0
- package/dist/tools/ls.d.ts.map +1 -0
- package/dist/tools/ls.js +63 -0
- package/dist/tools/ls.js.map +1 -0
- package/dist/tools/metrics.d.ts +10 -0
- package/dist/tools/metrics.d.ts.map +1 -0
- package/dist/tools/metrics.js +34 -0
- package/dist/tools/metrics.js.map +1 -0
- package/dist/tools/multi-grep.d.ts +7 -0
- package/dist/tools/multi-grep.d.ts.map +1 -0
- package/dist/tools/multi-grep.js +198 -0
- package/dist/tools/multi-grep.js.map +1 -0
- package/dist/tools/read.d.ts +6 -0
- package/dist/tools/read.d.ts.map +1 -0
- package/dist/tools/read.js +125 -0
- package/dist/tools/read.js.map +1 -0
- package/dist/types.d.ts +168 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +32 -26
- package/src/index.ts +30 -22
- package/src/notices.ts +3 -0
- package/src/tools/find.ts +2 -1
- package/src/tools/grep.ts +2 -1
- package/src/tools/multi-grep.ts +2 -1
- package/biome.json +0 -22
- package/bun.lock +0 -598
- package/media/bash-and-read.png +0 -0
- package/media/icons-and-grep.png +0 -0
- package/media/inline-image.png +0 -0
- package/pi-pretty.example.json +0 -6
- package/release-notes/v0.3.2.md +0 -34
- package/release-notes/v0.3.3.md +0 -48
- package/release-notes/v0.4.0.md +0 -58
- package/release-notes/v0.4.1.md +0 -28
- package/release-notes/v0.4.2.md +0 -36
- package/release-notes/v0.4.4.md +0 -28
- package/release-notes/v0.5.3.md +0 -29
- package/test/bash-rendering.test.ts +0 -269
- package/test/fff-integration.test.ts +0 -800
- package/test/image-rendering.test.ts +0 -153
- package/tsconfig.json +0 -19
package/media/bash-and-read.png
DELETED
|
Binary file
|
package/media/icons-and-grep.png
DELETED
|
Binary file
|
package/media/inline-image.png
DELETED
|
Binary file
|
package/pi-pretty.example.json
DELETED
package/release-notes/v0.3.2.md
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# pi-pretty v0.3.2
|
|
2
|
-
|
|
3
|
-
## Summary
|
|
4
|
-
This patch release fixes inline image rendering reliability when running `pi-pretty` inside `tmux`.
|
|
5
|
-
|
|
6
|
-
## What changed
|
|
7
|
-
- Fixed terminal detection in tmux for:
|
|
8
|
-
- Kitty (`KITTY_WINDOW_ID`, `KITTY_PID`)
|
|
9
|
-
- WezTerm (`WEZTERM_EXECUTABLE`, `WEZTERM_CONFIG_DIR`, `WEZTERM_CONFIG_FILE`)
|
|
10
|
-
- Added tmux fallback detection via:
|
|
11
|
-
- `tmux display-message -p "#{client_termname}"`
|
|
12
|
-
- Replaced static tmux detection with runtime detection to avoid stale module-load state.
|
|
13
|
-
- Added explicit warning when tmux passthrough is disabled:
|
|
14
|
-
- `tmux allow-passthrough is off. Run: tmux set -g allow-passthrough on`
|
|
15
|
-
- Added non-PNG warning for Kitty/Ghostty image rendering path.
|
|
16
|
-
- Added test coverage for image protocol detection and tmux passthrough warning behavior.
|
|
17
|
-
- Updated README with tmux passthrough setup instructions.
|
|
18
|
-
|
|
19
|
-
## Files
|
|
20
|
-
- `src/index.ts`
|
|
21
|
-
- `test/image-rendering.test.ts`
|
|
22
|
-
- `README.md`
|
|
23
|
-
|
|
24
|
-
## Verification
|
|
25
|
-
- `npm run typecheck` ✅
|
|
26
|
-
- `npm test` ✅ (46 tests)
|
|
27
|
-
- `npm run lint` ⚠️ fails due to existing Biome diagnostics in legacy code paths (pre-existing, not introduced in this patch).
|
|
28
|
-
|
|
29
|
-
## Upgrade notes
|
|
30
|
-
When using `tmux`, enable passthrough:
|
|
31
|
-
|
|
32
|
-
```tmux
|
|
33
|
-
set -g allow-passthrough on
|
|
34
|
-
```
|
package/release-notes/v0.3.3.md
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
# pi-pretty v0.3.3
|
|
2
|
-
|
|
3
|
-
## Summary
|
|
4
|
-
This patch release combines the recent rendering and FFF-path fixes into a single `v0.3.3` release.
|
|
5
|
-
|
|
6
|
-
## What changed
|
|
7
|
-
- Fixed themed tool background rendering so `toolSuccessBg` and `toolErrorBg` fill the full rendered width for core tool output.
|
|
8
|
-
- Preserved the active tool background across ANSI reset sequences to avoid broken background bands inside highlighted output.
|
|
9
|
-
- Kept error rendering on `theme.fg("error", ...)` while switching error panels to `toolErrorBg`.
|
|
10
|
-
- Moved pi-pretty FFF data from:
|
|
11
|
-
- `~/.pi/agent/fff`
|
|
12
|
-
- To:
|
|
13
|
-
- `~/.pi/agent/pi-pretty/fff`
|
|
14
|
-
- Added a helper to resolve the pi-pretty-specific FFF directory under `getAgentDir()`.
|
|
15
|
-
- Updated README to document the pi-pretty-owned FFF data location.
|
|
16
|
-
- Added a test that verifies the generated frecency/history DB paths use the new per-extension location.
|
|
17
|
-
|
|
18
|
-
## Files
|
|
19
|
-
- `src/index.ts`
|
|
20
|
-
- `test/fff-integration.test.ts`
|
|
21
|
-
- `README.md`
|
|
22
|
-
- `package.json`
|
|
23
|
-
- `package-lock.json`
|
|
24
|
-
|
|
25
|
-
## Verification
|
|
26
|
-
- `npm run typecheck` ✅
|
|
27
|
-
- `npm test` ✅ (47 tests)
|
|
28
|
-
- `npm run lint` ⚠️ still reports pre-existing Biome diagnostics in legacy code paths; no new release-blocking failure was introduced for this patch.
|
|
29
|
-
|
|
30
|
-
## Upgrade notes
|
|
31
|
-
If your Pi theme defines:
|
|
32
|
-
|
|
33
|
-
```json
|
|
34
|
-
{
|
|
35
|
-
"toolSuccessBg": "#1e2e1e",
|
|
36
|
-
"toolErrorBg": "#2e1e1e"
|
|
37
|
-
}
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
core tool panels now render those backgrounds across the full line width instead of only behind printed characters.
|
|
41
|
-
|
|
42
|
-
When FFF is available, pi-pretty now stores frecency/history data under:
|
|
43
|
-
|
|
44
|
-
```text
|
|
45
|
-
~/.pi/agent/pi-pretty/fff/
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
Existing data under `~/.pi/agent/fff` is not migrated automatically by this release.
|
package/release-notes/v0.4.0.md
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
# pi-pretty v0.4.0
|
|
2
|
-
|
|
3
|
-
## Summary
|
|
4
|
-
This release makes bundled FFF search the primary product direction for `pi-pretty`.
|
|
5
|
-
|
|
6
|
-
`pi-pretty` now owns the built-in `find` / `grep` experience directly via `@ff-labs/fff-node`, includes `multi_grep`, and documents the bundled workflow end-to-end.
|
|
7
|
-
|
|
8
|
-
## What changed
|
|
9
|
-
- Bundled `@ff-labs/fff-node` as a normal dependency instead of an optional coexistence path.
|
|
10
|
-
- Restored bundled FFF-backed behavior for:
|
|
11
|
-
- `find`
|
|
12
|
-
- `grep`
|
|
13
|
-
- `multi_grep`
|
|
14
|
-
- `/fff-health`
|
|
15
|
-
- `/fff-rescan`
|
|
16
|
-
- Kept the pi-pretty-specific FFF data directory:
|
|
17
|
-
- `~/.pi/agent/pi-pretty/fff/`
|
|
18
|
-
- Updated README to document:
|
|
19
|
-
- bundled FFF ownership
|
|
20
|
-
- install/use flow
|
|
21
|
-
- `multi_grep` examples
|
|
22
|
-
- FFF maintenance commands
|
|
23
|
-
- the requirement not to co-load `pi-fff`
|
|
24
|
-
- Tightened FFF/runtime typing:
|
|
25
|
-
- typed `CursorStore` and `fffFormatGrepText()` against `@ff-labs/fff-node`
|
|
26
|
-
- replaced remaining `src/index.ts` explicit `any` usage in tool wrappers with SDK/FFF-backed types
|
|
27
|
-
- typed `find`, `grep`, and `multi_grep` params/results/render paths against Pi tool inputs and FFF result interfaces
|
|
28
|
-
- removed several dead imports/constants and a non-null assertion in renderer code
|
|
29
|
-
|
|
30
|
-
## Files
|
|
31
|
-
- `src/index.ts`
|
|
32
|
-
- `src/fff-helpers.ts`
|
|
33
|
-
- `test/fff-integration.test.ts`
|
|
34
|
-
- `test/image-rendering.test.ts`
|
|
35
|
-
- `README.md`
|
|
36
|
-
- `package.json`
|
|
37
|
-
- `package-lock.json`
|
|
38
|
-
|
|
39
|
-
## Verification
|
|
40
|
-
- `npm run typecheck` ✅
|
|
41
|
-
- `npm test` ✅ (47 tests)
|
|
42
|
-
- `npm run lint -- --max-diagnostics=120` ✅
|
|
43
|
-
- `rg "\\bany\\b" src/index.ts src/fff-helpers.ts` ✅ no matches
|
|
44
|
-
|
|
45
|
-
## Upgrade notes
|
|
46
|
-
- Use only `pi-pretty` for bundled FFF mode:
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
pi install npm:@heyhuynhgiabuu/pi-pretty
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
- Do **not** also load `pi-fff` in the same Pi setup.
|
|
53
|
-
- To inspect or refresh the bundled index inside Pi, use:
|
|
54
|
-
|
|
55
|
-
```text
|
|
56
|
-
/fff-health
|
|
57
|
-
/fff-rescan
|
|
58
|
-
```
|
package/release-notes/v0.4.1.md
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# pi-pretty v0.4.1
|
|
2
|
-
|
|
3
|
-
## Summary
|
|
4
|
-
This patch release prevents `grep` from aborting Pi when FFF 0.5.2 indexes Unicode filenames and the grep call includes a `path` or `glob` constraint.
|
|
5
|
-
|
|
6
|
-
## What changed
|
|
7
|
-
- Constrained `grep` calls now bypass native FFF and use the SDK fallback path.
|
|
8
|
-
- Unconstrained `grep` still uses FFF for the fast path.
|
|
9
|
-
- Added regression tests for both `path` and `glob` constrained grep bypass behavior.
|
|
10
|
-
|
|
11
|
-
## Why
|
|
12
|
-
`@ff-labs/fff-node@0.5.2` can panic inside native Rust constraint matching when a byte-based slice lands inside a multi-byte UTF-8 character in an indexed filename, such as an en dash (`–`). Because that panic happens across FFI, JavaScript cannot catch it; the whole `pi` process aborts.
|
|
13
|
-
|
|
14
|
-
This release avoids the crash-prone native constraint path until upstream FFF ships the Unicode boundary fix.
|
|
15
|
-
|
|
16
|
-
## Files
|
|
17
|
-
- `src/index.ts`
|
|
18
|
-
- `test/fff-integration.test.ts`
|
|
19
|
-
- `package.json`
|
|
20
|
-
- `package-lock.json`
|
|
21
|
-
|
|
22
|
-
## Verification
|
|
23
|
-
- `npm run typecheck` ✅
|
|
24
|
-
- `npm run lint` ✅
|
|
25
|
-
- `npm test` ✅ (48 tests)
|
|
26
|
-
|
|
27
|
-
## Upgrade notes
|
|
28
|
-
No configuration changes required. After updating, file- or glob-scoped `grep` calls will prefer the SDK fallback for stability; broad unconstrained grep remains FFF-backed.
|
package/release-notes/v0.4.2.md
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# pi-pretty 0.4.2
|
|
2
|
-
|
|
3
|
-
## Summary
|
|
4
|
-
This patch release merges the reviewed `customizations` PR into `main` and ships safer `multi_grep` fallback behavior, improved theme resolution, normalized output handling, and clearer bash command rendering.
|
|
5
|
-
|
|
6
|
-
## What changed
|
|
7
|
-
- `multi_grep` now preserves constrained searches by routing them through a dedicated ripgrep fallback instead of silently dropping complex constraints.
|
|
8
|
-
- Complex constraint expressions such as `*.ts !test/` are converted into ripgrep `--glob` filters, while invalid constraint syntax now returns an error instead of being ignored.
|
|
9
|
-
- Constrained `grep` safety from `0.4.1` remains intact: `path`/`glob` constrained searches still avoid native FFF.
|
|
10
|
-
- pi-pretty now reads `~/.pi/agent/settings.json` theme settings by default, while `PRETTY_THEME` continues to override explicitly.
|
|
11
|
-
- Expanded bash tool rendering so expanded tool calls show the full command instead of the truncated preview.
|
|
12
|
-
- Normalized read/grep output handling and tightened single-line-safe FFF grep record formatting.
|
|
13
|
-
- Added test coverage for bash rendering, constrained grep and multi_grep fallback behavior, CRLF handling, and ripgrep constraint preservation.
|
|
14
|
-
|
|
15
|
-
## Files
|
|
16
|
-
- `src/index.ts`
|
|
17
|
-
- `src/fff-helpers.ts`
|
|
18
|
-
- `src/multi-grep-fallback.ts`
|
|
19
|
-
- `test/bash-rendering.test.ts`
|
|
20
|
-
- `test/fff-integration.test.ts`
|
|
21
|
-
- `README.md`
|
|
22
|
-
- `package.json`
|
|
23
|
-
- `package-lock.json`
|
|
24
|
-
|
|
25
|
-
## Verification
|
|
26
|
-
- `npm run typecheck` ✅
|
|
27
|
-
- `npm run lint` ✅
|
|
28
|
-
- `npm test` ✅ (67 tests)
|
|
29
|
-
|
|
30
|
-
## Upgrade notes
|
|
31
|
-
No configuration changes are required.
|
|
32
|
-
|
|
33
|
-
After updating:
|
|
34
|
-
- constrained `grep` and `multi_grep` searches prefer safe fallback paths instead of unsafe native constrained matching
|
|
35
|
-
- complex `multi_grep` constraints are preserved instead of being widened silently
|
|
36
|
-
- theme selection can follow Pi settings automatically unless `PRETTY_THEME` is set
|
package/release-notes/v0.4.4.md
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# pi-pretty 0.4.4
|
|
2
|
-
|
|
3
|
-
## Summary
|
|
4
|
-
This patch release fixes terminal background tearing/misaligned cells by enforcing the pi-tui line-width contract for background-filled tool output.
|
|
5
|
-
|
|
6
|
-
## What changed
|
|
7
|
-
- Clamp every background-filled tool line to the active terminal width before adding background padding.
|
|
8
|
-
- Use `@mariozechner/pi-tui` `truncateToWidth()` and `visibleWidth()` so ANSI escapes and wide Unicode cells are measured correctly.
|
|
9
|
-
- Preserve the configured tool background after ANSI reset sequences even when truncation occurs.
|
|
10
|
-
- Remove the 80-column minimum width floor so narrow terminals do not receive over-wide rendered lines.
|
|
11
|
-
- Replace custom read-output truncation with pi-tui's ANSI-aware truncation helper.
|
|
12
|
-
- Add regression coverage for expanded ANSI tool headers, wide characters, and narrow terminal widths.
|
|
13
|
-
|
|
14
|
-
## Files
|
|
15
|
-
- `src/index.ts`
|
|
16
|
-
- `test/bash-rendering.test.ts`
|
|
17
|
-
- `package.json`
|
|
18
|
-
- `package-lock.json`
|
|
19
|
-
|
|
20
|
-
## Verification
|
|
21
|
-
- `npm run lint` ✅
|
|
22
|
-
- `npm run typecheck` ✅
|
|
23
|
-
- `npm test` ✅ (69 tests)
|
|
24
|
-
|
|
25
|
-
## Upgrade notes
|
|
26
|
-
No configuration changes are required.
|
|
27
|
-
|
|
28
|
-
This release specifically follows the pi-tui requirement that rendered component lines must not exceed the available width, preventing terminal auto-wrap artifacts in red/error and themed tool backgrounds.
|
package/release-notes/v0.5.3.md
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
# pi-pretty 0.5.3
|
|
2
|
-
|
|
3
|
-
## Summary
|
|
4
|
-
This release adds user-configurable tool output backgrounds via a `pi-pretty.json` config file, replacing the previous hardcoded theme-only dependency. It also fixes error tool background misalignment where the padding area showed the wrong background color.
|
|
5
|
-
|
|
6
|
-
## What changed
|
|
7
|
-
- Add `pi-pretty.json` config file support (loaded from `~/.pi/agent/pi-pretty.json` alongside `settings.json`).
|
|
8
|
-
- Config fields: `background.tool` (normal tool output bg, hex) and `background.error` (error tool output bg, hex, defaults to tool bg).
|
|
9
|
-
- Config values take priority over theme-provided backgrounds (`toolBg` / `toolErrorBg`).
|
|
10
|
-
- Add `PRETTY_CONFIG_DIR` env var to override the config directory.
|
|
11
|
-
- Fix: `fillToolBackground()` now uses a per-line RST matching the line's background color, fixing a visible color seam where padding showed `BG_BASE` instead of `BG_ERROR` on error tool output.
|
|
12
|
-
- Fix: `renderToolError()` restores top spacing and applies two-space left padding to every line of multi-line error output.
|
|
13
|
-
- Fix: `multi_grep` error path now uses `renderToolError()` instead of raw text without background fill.
|
|
14
|
-
- Add `hexToAnsiBg()` converter and `PrettyConfig` exported interface.
|
|
15
|
-
- Add `pi-pretty.example.json` in the project root.
|
|
16
|
-
- Update README with configuration documentation.
|
|
17
|
-
|
|
18
|
-
## Files
|
|
19
|
-
- `src/index.ts`
|
|
20
|
-
- `pi-pretty.example.json`
|
|
21
|
-
- `README.md`
|
|
22
|
-
|
|
23
|
-
## Verification
|
|
24
|
-
- `npm run typecheck` ✅
|
|
25
|
-
- `npm run lint` ✅ (no new issues)
|
|
26
|
-
- `npm test` ✅ (74 tests)
|
|
27
|
-
|
|
28
|
-
## Upgrade notes
|
|
29
|
-
No configuration changes are required. Existing behavior is unchanged — config is optional. To customize backgrounds, create `~/.pi/agent/pi-pretty.json` with the `background` fields.
|
|
@@ -1,269 +0,0 @@
|
|
|
1
|
-
import { visibleWidth } from "@earendil-works/pi-tui";
|
|
2
|
-
import { describe, expect, it } from "vitest";
|
|
3
|
-
|
|
4
|
-
import piPrettyExtension from "../src/index.js";
|
|
5
|
-
|
|
6
|
-
class MockText {
|
|
7
|
-
private text = "";
|
|
8
|
-
constructor(_text = "", _x = 0, _y = 0) {}
|
|
9
|
-
setText(value: string) {
|
|
10
|
-
this.text = value;
|
|
11
|
-
}
|
|
12
|
-
getText() {
|
|
13
|
-
return this.text;
|
|
14
|
-
}
|
|
15
|
-
render(_width: number) {
|
|
16
|
-
return this.text.split("\n");
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const mockTheme = {
|
|
21
|
-
fg: (_key: string, text: string) => text,
|
|
22
|
-
bold: (text: string) => text,
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const ansiMockTheme = {
|
|
26
|
-
fg: (_key: string, text: string) => `\x1b[31m${text}\x1b[0m`,
|
|
27
|
-
bold: (text: string) => `\x1b[1m${text}\x1b[22m`,
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
function mockToolFactory(exec: any) {
|
|
31
|
-
return (_cwd: string) => ({
|
|
32
|
-
name: "mock",
|
|
33
|
-
description: "mock",
|
|
34
|
-
parameters: { type: "object", properties: {} },
|
|
35
|
-
execute: exec,
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function stripAnsi(text: string): string {
|
|
40
|
-
return text.replace(/\x1b\[[0-9;]*m/g, "");
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function withStdoutColumns<T>(columns: number, fn: () => T): T {
|
|
44
|
-
const descriptor = Object.getOwnPropertyDescriptor(process.stdout, "columns");
|
|
45
|
-
Object.defineProperty(process.stdout, "columns", { configurable: true, value: columns });
|
|
46
|
-
try {
|
|
47
|
-
return fn();
|
|
48
|
-
} finally {
|
|
49
|
-
if (descriptor) {
|
|
50
|
-
Object.defineProperty(process.stdout, "columns", descriptor);
|
|
51
|
-
} else {
|
|
52
|
-
delete (process.stdout as NodeJS.WriteStream & { columns?: number }).columns;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function loadBashTool() {
|
|
58
|
-
const noopExec = async () => ({ content: [{ type: "text", text: "" }] });
|
|
59
|
-
const tools = new Map<string, any>();
|
|
60
|
-
const pi = {
|
|
61
|
-
registerTool: (tool: any) => tools.set(tool.name, tool),
|
|
62
|
-
registerCommand: () => {},
|
|
63
|
-
on: () => {},
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
piPrettyExtension(pi, {
|
|
67
|
-
sdk: {
|
|
68
|
-
createReadToolDefinition: mockToolFactory(noopExec),
|
|
69
|
-
createBashToolDefinition: mockToolFactory(noopExec),
|
|
70
|
-
createLsToolDefinition: mockToolFactory(noopExec),
|
|
71
|
-
createFindToolDefinition: mockToolFactory(noopExec),
|
|
72
|
-
createGrepToolDefinition: mockToolFactory(noopExec),
|
|
73
|
-
getAgentDir: () => "/tmp/pi-pretty-test",
|
|
74
|
-
},
|
|
75
|
-
TextComponent: MockText,
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
return tools.get("bash");
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
describe("bash renderCall expansion", () => {
|
|
82
|
-
it("truncates long commands when collapsed", () => {
|
|
83
|
-
const bashTool = loadBashTool();
|
|
84
|
-
const command = `printf '${"x".repeat(120)}'`;
|
|
85
|
-
|
|
86
|
-
const rendered = bashTool.renderCall({ command }, mockTheme, {
|
|
87
|
-
lastComponent: new MockText(),
|
|
88
|
-
isError: false,
|
|
89
|
-
state: {},
|
|
90
|
-
expanded: false,
|
|
91
|
-
invalidate: () => {},
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
expect(rendered.getText()).toContain("bash");
|
|
95
|
-
expect(rendered.getText()).toContain("…");
|
|
96
|
-
expect(rendered.getText()).not.toContain(command);
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it("shows the full command when expanded", () => {
|
|
100
|
-
const bashTool = loadBashTool();
|
|
101
|
-
const command = `printf '${"x".repeat(120)}'`;
|
|
102
|
-
|
|
103
|
-
const rendered = bashTool.renderCall({ command }, mockTheme, {
|
|
104
|
-
lastComponent: new MockText(),
|
|
105
|
-
isError: false,
|
|
106
|
-
state: {},
|
|
107
|
-
expanded: true,
|
|
108
|
-
invalidate: () => {},
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
expect(rendered.getText()).toContain(command);
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it("preserves timeout text in both collapsed and expanded states", () => {
|
|
115
|
-
const bashTool = loadBashTool();
|
|
116
|
-
const command = `printf '${"x".repeat(120)}'`;
|
|
117
|
-
|
|
118
|
-
const collapsed = bashTool.renderCall({ command, timeout: 5 }, mockTheme, {
|
|
119
|
-
lastComponent: new MockText(),
|
|
120
|
-
isError: false,
|
|
121
|
-
state: {},
|
|
122
|
-
expanded: false,
|
|
123
|
-
invalidate: () => {},
|
|
124
|
-
});
|
|
125
|
-
const expanded = bashTool.renderCall({ command, timeout: 5 }, mockTheme, {
|
|
126
|
-
lastComponent: new MockText(),
|
|
127
|
-
isError: false,
|
|
128
|
-
state: {},
|
|
129
|
-
expanded: true,
|
|
130
|
-
invalidate: () => {},
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
expect(collapsed.getText()).toContain("(timeout 5s)");
|
|
134
|
-
expect(expanded.getText()).toContain("(timeout 5s)");
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
it("truncates ANSI tool headers that exceed the terminal width", () => {
|
|
138
|
-
withStdoutColumns(84, () => {
|
|
139
|
-
const bashTool = loadBashTool();
|
|
140
|
-
const command = `printf '${"界".repeat(120)}'`;
|
|
141
|
-
|
|
142
|
-
const rendered = bashTool.renderCall({ command }, ansiMockTheme, {
|
|
143
|
-
lastComponent: new MockText(),
|
|
144
|
-
isError: false,
|
|
145
|
-
state: {},
|
|
146
|
-
expanded: true,
|
|
147
|
-
invalidate: () => {},
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
for (const line of rendered.getText().split("\n")) {
|
|
151
|
-
expect(visibleWidth(line)).toBeLessThanOrEqual(84);
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
it("does not exceed narrow terminal widths", () => {
|
|
157
|
-
withStdoutColumns(24, () => {
|
|
158
|
-
const bashTool = loadBashTool();
|
|
159
|
-
const command = `printf '${"x".repeat(120)}'`;
|
|
160
|
-
|
|
161
|
-
const rendered = bashTool.renderCall({ command }, ansiMockTheme, {
|
|
162
|
-
lastComponent: new MockText(),
|
|
163
|
-
isError: false,
|
|
164
|
-
state: {},
|
|
165
|
-
expanded: true,
|
|
166
|
-
invalidate: () => {},
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
for (const line of rendered.getText().split("\n")) {
|
|
170
|
-
expect(visibleWidth(line)).toBeLessThanOrEqual(24);
|
|
171
|
-
}
|
|
172
|
-
});
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
it("does not add extra internal padding to the bash title in error state", () => {
|
|
176
|
-
withStdoutColumns(48, () => {
|
|
177
|
-
const bashTool = loadBashTool();
|
|
178
|
-
const rendered = bashTool.renderCall({ command: "false" }, mockTheme, {
|
|
179
|
-
lastComponent: new MockText(),
|
|
180
|
-
isError: true,
|
|
181
|
-
state: {},
|
|
182
|
-
expanded: false,
|
|
183
|
-
invalidate: () => {},
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
const lines = stripAnsi(rendered.getText()).split("\n");
|
|
187
|
-
expect(lines[1]).toMatch(/^ \$ false/);
|
|
188
|
-
});
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
it("pads every line of multi-line tool errors", () => {
|
|
192
|
-
withStdoutColumns(48, () => {
|
|
193
|
-
const bashTool = loadBashTool();
|
|
194
|
-
const rendered = bashTool.renderResult(
|
|
195
|
-
{ content: [{ type: "text", text: "\nfirst error\n\n\nsecond error\n" }] },
|
|
196
|
-
{},
|
|
197
|
-
ansiMockTheme,
|
|
198
|
-
{
|
|
199
|
-
lastComponent: new MockText(),
|
|
200
|
-
isError: true,
|
|
201
|
-
state: {},
|
|
202
|
-
expanded: false,
|
|
203
|
-
invalidate: () => {},
|
|
204
|
-
},
|
|
205
|
-
);
|
|
206
|
-
|
|
207
|
-
const lines = stripAnsi(rendered.getText()).split("\n");
|
|
208
|
-
expect(lines[0]).toContain("✗ exit 1");
|
|
209
|
-
expect(lines[1]).toMatch(/^─+$/);
|
|
210
|
-
expect(lines[2]).toMatch(/^ first error/);
|
|
211
|
-
expect(lines[3]).toMatch(/^ /);
|
|
212
|
-
expect(lines[3].trim()).toBe("");
|
|
213
|
-
expect(lines[4]).toMatch(/^ second error/);
|
|
214
|
-
});
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
it("applies tool background correctly to bash results without unnecessary resets", () => {
|
|
218
|
-
withStdoutColumns(64, () => {
|
|
219
|
-
const bashTool = loadBashTool();
|
|
220
|
-
const rendered = bashTool.renderResult(
|
|
221
|
-
{
|
|
222
|
-
content: [{ type: "text", text: "output" }],
|
|
223
|
-
details: { _type: "bashResult", text: "output", exitCode: 1, command: "test" },
|
|
224
|
-
},
|
|
225
|
-
{},
|
|
226
|
-
ansiMockTheme,
|
|
227
|
-
{
|
|
228
|
-
lastComponent: new MockText(),
|
|
229
|
-
isError: true,
|
|
230
|
-
state: { _tw: "64" },
|
|
231
|
-
expanded: false,
|
|
232
|
-
invalidate: () => {},
|
|
233
|
-
},
|
|
234
|
-
);
|
|
235
|
-
|
|
236
|
-
expect(rendered.getText()).toMatch(/\x1b\[48;/); // tool background is applied
|
|
237
|
-
expect(rendered.getText()).not.toContain("\x1b[0m");
|
|
238
|
-
expect(rendered.getText()).not.toContain("\x1b[49m");
|
|
239
|
-
for (const line of rendered.getText().split("\n")) {
|
|
240
|
-
expect(visibleWidth(line)).toBeLessThanOrEqual(64);
|
|
241
|
-
}
|
|
242
|
-
});
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
it("renders bash results using the component render width instead of stdout columns", () => {
|
|
246
|
-
withStdoutColumns(120, () => {
|
|
247
|
-
const bashTool = loadBashTool();
|
|
248
|
-
const rendered = bashTool.renderResult(
|
|
249
|
-
{ content: [{ type: "text", text: "hello world" }], details: { _type: "bashResult", text: "hello world", exitCode: 0, command: "echo hi" } },
|
|
250
|
-
{},
|
|
251
|
-
mockTheme,
|
|
252
|
-
{
|
|
253
|
-
lastComponent: new MockText(),
|
|
254
|
-
isError: false,
|
|
255
|
-
state: {},
|
|
256
|
-
expanded: false,
|
|
257
|
-
invalidate: () => {},
|
|
258
|
-
},
|
|
259
|
-
);
|
|
260
|
-
|
|
261
|
-
rendered.render(80);
|
|
262
|
-
const lines = stripAnsi(rendered.getText()).split("\n");
|
|
263
|
-
expect(lines.some((line) => /^─{80}$/.test(line))).toBe(true);
|
|
264
|
-
for (const line of rendered.getText().split("\n")) {
|
|
265
|
-
expect(visibleWidth(line)).toBeLessThanOrEqual(80);
|
|
266
|
-
}
|
|
267
|
-
});
|
|
268
|
-
});
|
|
269
|
-
});
|