pi-tool-display 0.1.5 → 0.1.7
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 +23 -0
- package/README.md +114 -73
- package/config/config.example.json +24 -24
- package/package.json +1 -1
- package/src/capabilities.ts +94 -94
- package/src/config-modal.ts +367 -367
- package/src/diff-renderer.ts +1938 -1923
- package/src/index.ts +90 -90
- package/src/line-width-safety.ts +90 -0
- package/src/presets.ts +83 -83
- package/src/thinking-label.ts +165 -23
- package/src/tool-overrides.ts +1104 -1113
- package/src/types.ts +83 -83
- package/src/user-message-box-markdown.ts +48 -0
- package/src/user-message-box-native.ts +15 -204
- package/src/user-message-box-patch.ts +39 -0
- package/src/user-message-box-renderer.ts +167 -0
- package/src/user-message-box-utils.ts +155 -0
- package/src/write-display-utils.ts +27 -0
- package/src/zellij-modal.ts +1001 -1001
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.1.7] - 2026-03-07
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Added line-width safety utilities for diff rendering so collapsed and expanded diff output can be clamped to the current pane width.
|
|
14
|
+
- Added utility test coverage for write display helpers, native user message box helpers, and narrow-width diff hint behavior.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- Updated README documentation to reflect the current command surface, config model, width-safe diff behavior, native user message box pipeline, and project structure.
|
|
18
|
+
- Refactored native user message box rendering into focused markdown, patching, renderer, and ANSI/background utility modules.
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
- Prevented diff rendering and collapsed diff hints from overflowing narrow terminal widths by progressively shortening hint text and clamping rendered lines.
|
|
22
|
+
- Preserved inline `write` call summaries with line-count and byte-size metadata when content is available.
|
|
23
|
+
- Prevented thinking label presentation changes from leaking into future assistant context by sanitizing stored thinking blocks during the `context` extension event.
|
|
24
|
+
- Hardened thinking label normalization to strip ANSI residue fragments such as `38;5;208m` before display formatting.
|
|
25
|
+
- Restored final-message thinking label persistence on `message_end` so themed labels remain consistent after streaming and across session reloads.
|
|
26
|
+
- Improved native user message box rendering so markdown content, ANSI-only blank lines, and background fill behave more consistently.
|
|
27
|
+
|
|
28
|
+
## [0.1.6] - 2026-03-04
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
- Use absolute GitHub raw URL for README image to fix npm display
|
|
32
|
+
|
|
10
33
|
## [0.1.5] - 2026-03-04
|
|
11
34
|
|
|
12
35
|
### Added
|
package/README.md
CHANGED
|
@@ -2,24 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
OpenCode-style tool rendering for the [Pi coding agent](https://github.com/mariozechner/pi).
|
|
4
4
|
|
|
5
|
-
`pi-tool-display`
|
|
5
|
+
`pi-tool-display` keeps tool calls compact by default, adds richer diff rendering for file edits, and improves a few core chat UI details such as thinking labels and the native user prompt box.
|
|
6
6
|
|
|
7
|
-

|
|
7
|
+

|
|
8
8
|
|
|
9
9
|
## Features
|
|
10
10
|
|
|
11
|
-
- **Compact
|
|
12
|
-
- **MCP
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
15
|
-
- **
|
|
16
|
-
- **
|
|
17
|
-
- **
|
|
18
|
-
- **
|
|
11
|
+
- **Compact built-in tool rendering** for `read`, `grep`, `find`, `ls`, `bash`, `edit`, and `write`
|
|
12
|
+
- **MCP-aware rendering** with hidden, summary, and preview modes
|
|
13
|
+
- **Adaptive edit/write diffs** with split or unified layouts, syntax highlighting, inline emphasis, and narrow-pane width clamping
|
|
14
|
+
- **Progressive collapsed diff hints** that shorten automatically on small terminal widths instead of overflowing
|
|
15
|
+
- **Three presets**: `opencode`, `balanced`, and `verbose`
|
|
16
|
+
- **Thinking labels** during streaming and final message rendering, with context sanitization to avoid leaking presentation labels back into future model turns
|
|
17
|
+
- **Optional native user message box** with markdown-aware rendering and safer ANSI/background handling
|
|
18
|
+
- **Per-tool ownership toggles** so this extension can coexist with other renderer extensions
|
|
19
|
+
- **Capability-aware settings** that automatically hide MCP and RTK-specific controls when those features are unavailable
|
|
19
20
|
|
|
20
21
|
## Installation
|
|
21
22
|
|
|
22
|
-
### Local
|
|
23
|
+
### Local extension folder
|
|
23
24
|
|
|
24
25
|
Place this folder in one of Pi's auto-discovery locations:
|
|
25
26
|
|
|
@@ -31,13 +32,13 @@ Place this folder in one of Pi's auto-discovery locations:
|
|
|
31
32
|
.pi/extensions/pi-tool-display
|
|
32
33
|
```
|
|
33
34
|
|
|
34
|
-
### npm
|
|
35
|
+
### npm package
|
|
35
36
|
|
|
36
37
|
```bash
|
|
37
38
|
pi install npm:pi-tool-display
|
|
38
39
|
```
|
|
39
40
|
|
|
40
|
-
### Git
|
|
41
|
+
### Git repository
|
|
41
42
|
|
|
42
43
|
```bash
|
|
43
44
|
pi install git:github.com/MasuRii/pi-tool-display
|
|
@@ -45,7 +46,7 @@ pi install git:github.com/MasuRii/pi-tool-display
|
|
|
45
46
|
|
|
46
47
|
## Usage
|
|
47
48
|
|
|
48
|
-
### Interactive
|
|
49
|
+
### Interactive settings
|
|
49
50
|
|
|
50
51
|
Open the settings modal:
|
|
51
52
|
|
|
@@ -53,11 +54,24 @@ Open the settings modal:
|
|
|
53
54
|
/tool-display
|
|
54
55
|
```
|
|
55
56
|
|
|
56
|
-
|
|
57
|
+
The modal exposes the day-to-day controls most people change regularly:
|
|
58
|
+
|
|
59
|
+
- preset profile
|
|
60
|
+
- read output mode
|
|
61
|
+
- grep/find/ls output mode
|
|
62
|
+
- MCP output mode (when MCP is available)
|
|
63
|
+
- preview line count
|
|
64
|
+
- bash collapsed line count
|
|
65
|
+
- diff layout mode
|
|
66
|
+
- native user message box toggle
|
|
67
|
+
|
|
68
|
+
Advanced options remain in `config.json`.
|
|
69
|
+
|
|
70
|
+
### Direct commands
|
|
57
71
|
|
|
58
72
|
```text
|
|
59
|
-
/tool-display show #
|
|
60
|
-
/tool-display reset # Reset to default
|
|
73
|
+
/tool-display show # Show the effective config summary
|
|
74
|
+
/tool-display reset # Reset to the default opencode preset
|
|
61
75
|
/tool-display preset opencode # Apply opencode preset
|
|
62
76
|
/tool-display preset balanced # Apply balanced preset
|
|
63
77
|
/tool-display preset verbose # Apply verbose preset
|
|
@@ -71,9 +85,9 @@ Open the settings modal:
|
|
|
71
85
|
| `balanced` | summary | count | summary | 8 | 10 |
|
|
72
86
|
| `verbose` | preview | preview | preview | 12 | 20 |
|
|
73
87
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
88
|
+
- **`opencode`** (default): minimal inline-only display; tool results stay collapsed
|
|
89
|
+
- **`balanced`**: compact summaries with line counts and match totals
|
|
90
|
+
- **`verbose`**: larger previews for read/search/MCP output and more visible bash output
|
|
77
91
|
|
|
78
92
|
## Configuration
|
|
79
93
|
|
|
@@ -83,30 +97,30 @@ Runtime configuration is stored at:
|
|
|
83
97
|
~/.pi/agent/extensions/pi-tool-display/config.json
|
|
84
98
|
```
|
|
85
99
|
|
|
86
|
-
A starter template is
|
|
100
|
+
A starter template is included at `config/config.example.json`.
|
|
87
101
|
|
|
88
|
-
### Configuration
|
|
102
|
+
### Configuration options
|
|
89
103
|
|
|
90
104
|
| Option | Type | Default | Description |
|
|
91
105
|
|--------|------|---------|-------------|
|
|
92
|
-
| `registerToolOverrides` | object | all `true` | Per-tool ownership flags
|
|
93
|
-
| `enableNativeUserMessageBox` | boolean | `true` | Enable bordered user
|
|
106
|
+
| `registerToolOverrides` | object | all `true` | Per-tool ownership flags |
|
|
107
|
+
| `enableNativeUserMessageBox` | boolean | `true` | Enable bordered user prompt rendering |
|
|
94
108
|
| `readOutputMode` | string | `"hidden"` | `hidden`, `summary`, or `preview` |
|
|
95
109
|
| `searchOutputMode` | string | `"hidden"` | `hidden`, `count`, or `preview` |
|
|
96
110
|
| `mcpOutputMode` | string | `"hidden"` | `hidden`, `summary`, or `preview` |
|
|
97
|
-
| `previewLines` | number | `8` | Lines shown in collapsed preview |
|
|
98
|
-
| `expandedPreviewMaxLines` | number | `4000` | Max lines when expanded |
|
|
99
|
-
| `bashCollapsedLines` | number | `10` | Lines shown for bash output |
|
|
111
|
+
| `previewLines` | number | `8` | Lines shown in collapsed preview mode |
|
|
112
|
+
| `expandedPreviewMaxLines` | number | `4000` | Max preview lines when fully expanded |
|
|
113
|
+
| `bashCollapsedLines` | number | `10` | Lines shown for collapsed bash output |
|
|
100
114
|
| `diffViewMode` | string | `"auto"` | `auto`, `split`, or `unified` |
|
|
101
|
-
| `diffSplitMinWidth` | number | `120` | Minimum
|
|
102
|
-
| `diffCollapsedLines` | number | `24` |
|
|
103
|
-
| `diffWordWrap` | boolean | `true` | Wrap long lines
|
|
104
|
-
| `showTruncationHints` | boolean | `true` | Show truncation indicators |
|
|
105
|
-
| `showRtkCompactionHints` | boolean | `true` | Show RTK compaction hints |
|
|
115
|
+
| `diffSplitMinWidth` | number | `120` | Minimum width before auto mode prefers split diffs |
|
|
116
|
+
| `diffCollapsedLines` | number | `24` | Diff lines shown before collapsing |
|
|
117
|
+
| `diffWordWrap` | boolean | `true` | Wrap long diff lines when needed |
|
|
118
|
+
| `showTruncationHints` | boolean | `true` | Show truncation indicators for compacted output |
|
|
119
|
+
| `showRtkCompactionHints` | boolean | `true` | Show RTK compaction hints when RTK metadata exists |
|
|
106
120
|
|
|
107
|
-
### Tool
|
|
121
|
+
### Tool ownership
|
|
108
122
|
|
|
109
|
-
|
|
123
|
+
Use `registerToolOverrides` to control which built-in tools this extension owns:
|
|
110
124
|
|
|
111
125
|
```json
|
|
112
126
|
{
|
|
@@ -122,11 +136,11 @@ Control which tools this extension overrides:
|
|
|
122
136
|
}
|
|
123
137
|
```
|
|
124
138
|
|
|
125
|
-
Set any
|
|
139
|
+
Set any entry to `false` if another extension should handle that tool instead.
|
|
126
140
|
|
|
127
|
-
>
|
|
141
|
+
> Changes to tool ownership take effect after `/reload`.
|
|
128
142
|
|
|
129
|
-
### Example
|
|
143
|
+
### Example config
|
|
130
144
|
|
|
131
145
|
```json
|
|
132
146
|
{
|
|
@@ -155,55 +169,85 @@ Set any tool to `false` to leave rendering ownership to another extension.
|
|
|
155
169
|
}
|
|
156
170
|
```
|
|
157
171
|
|
|
158
|
-
##
|
|
172
|
+
## Rendering notes
|
|
173
|
+
|
|
174
|
+
### Edit and write diffs
|
|
175
|
+
|
|
176
|
+
`edit` and `write` results use the same diff renderer. In `auto` mode the extension chooses split or unified layout based on available width. On narrow panes it clamps rendered lines and shortens collapsed hint text so the diff stays readable instead of spilling past the terminal width.
|
|
177
|
+
|
|
178
|
+
### Write summaries
|
|
179
|
+
|
|
180
|
+
When content is available, `write` call summaries include line count and byte size information inline so you can quickly see the size of the pending write before expanding the result.
|
|
181
|
+
|
|
182
|
+
### Thinking labels
|
|
159
183
|
|
|
160
|
-
|
|
184
|
+
Thinking blocks are labeled during streaming and on final messages. Before the next model turn, the extension sanitizes those presentation labels out of the stored assistant context so they do not accumulate or pollute future prompts.
|
|
161
185
|
|
|
162
|
-
|
|
163
|
-
- **RTK Optimizer** — When [pi-rtk-optimizer](https://github.com/MasuRii/pi-rtk-optimizer) isn't installed, RTK compaction hint settings are hidden and hints are disabled
|
|
186
|
+
### Native user message box
|
|
164
187
|
|
|
165
|
-
|
|
188
|
+
When enabled, user prompts render inside a bordered box using Pi's native user message component. The renderer preserves markdown content more safely and normalizes ANSI/background handling to avoid odd nested background artifacts.
|
|
189
|
+
|
|
190
|
+
## Capability detection
|
|
191
|
+
|
|
192
|
+
The extension checks the current Pi environment and adjusts behavior automatically:
|
|
193
|
+
|
|
194
|
+
- **MCP tooling unavailable**: MCP settings are hidden and MCP output is forced off
|
|
195
|
+
- **RTK optimizer unavailable**: RTK hint settings are hidden and RTK compaction hints are disabled
|
|
196
|
+
|
|
197
|
+
This keeps the UI aligned with what the current environment can actually support.
|
|
166
198
|
|
|
167
199
|
## Troubleshooting
|
|
168
200
|
|
|
169
|
-
### Tool
|
|
201
|
+
### Tool ownership conflicts
|
|
170
202
|
|
|
171
|
-
If another extension
|
|
203
|
+
If another extension is already rendering one of the built-in tools:
|
|
172
204
|
|
|
173
|
-
1. Set
|
|
174
|
-
2. Run `/reload`
|
|
175
|
-
3.
|
|
205
|
+
1. Set `registerToolOverrides.<tool>` to `false`
|
|
206
|
+
2. Run `/reload`
|
|
207
|
+
3. Use `/tool-display show` to confirm the effective ownership state
|
|
176
208
|
|
|
177
|
-
###
|
|
209
|
+
### Config not loading
|
|
178
210
|
|
|
179
|
-
If settings
|
|
211
|
+
If your settings are not being applied:
|
|
180
212
|
|
|
181
|
-
1. Check
|
|
182
|
-
2.
|
|
183
|
-
3. Run `/tool-display show` to
|
|
213
|
+
1. Check that `~/.pi/agent/extensions/pi-tool-display/config.json` exists
|
|
214
|
+
2. Make sure the JSON is valid
|
|
215
|
+
3. Run `/tool-display show` to inspect the effective config summary
|
|
184
216
|
|
|
185
|
-
|
|
217
|
+
### MCP or RTK settings missing
|
|
218
|
+
|
|
219
|
+
Those controls only appear when the corresponding capability is available in the current Pi environment.
|
|
220
|
+
|
|
221
|
+
## Project structure
|
|
186
222
|
|
|
187
223
|
```text
|
|
188
224
|
pi-tool-display/
|
|
189
|
-
├── index.ts
|
|
225
|
+
├── index.ts # Extension entrypoint for Pi auto-discovery
|
|
190
226
|
├── src/
|
|
191
|
-
│ ├── index.ts
|
|
192
|
-
│ ├──
|
|
193
|
-
│ ├──
|
|
194
|
-
│ ├── config-
|
|
195
|
-
│ ├──
|
|
196
|
-
│ ├──
|
|
197
|
-
│ ├── presets.ts
|
|
198
|
-
│ ├── render-utils.ts
|
|
199
|
-
│ ├── thinking-label.ts
|
|
200
|
-
│ ├──
|
|
201
|
-
│ ├── types.ts
|
|
202
|
-
│
|
|
227
|
+
│ ├── index.ts # Bootstrap and extension registration
|
|
228
|
+
│ ├── capabilities.ts # MCP/RTK capability detection
|
|
229
|
+
│ ├── config-modal.ts # /tool-display settings UI and command handling
|
|
230
|
+
│ ├── config-store.ts # Config load/save and normalization
|
|
231
|
+
│ ├── diff-renderer.ts # Edit/write diff rendering engine
|
|
232
|
+
│ ├── line-width-safety.ts # Width clamping helpers for narrow panes
|
|
233
|
+
│ ├── presets.ts # Preset definitions and matching
|
|
234
|
+
│ ├── render-utils.ts # Shared rendering helpers
|
|
235
|
+
│ ├── thinking-label.ts # Thinking label formatting and context sanitization
|
|
236
|
+
│ ├── tool-overrides.ts # Built-in and MCP renderer overrides
|
|
237
|
+
│ ├── types.ts # Shared config and type definitions
|
|
238
|
+
│ ├── user-message-box-markdown.ts # Markdown extraction for user message rendering
|
|
239
|
+
│ ├── user-message-box-native.ts # Native user message box registration
|
|
240
|
+
│ ├── user-message-box-patch.ts # Safe native render patching helpers
|
|
241
|
+
│ ├── user-message-box-renderer.ts # User message border renderer
|
|
242
|
+
│ ├── user-message-box-utils.ts # ANSI/background normalization helpers
|
|
243
|
+
│ ├── write-display-utils.ts # Write summary helpers
|
|
244
|
+
│ └── zellij-modal.ts # Modal UI primitives
|
|
203
245
|
├── config/
|
|
204
|
-
│ └── config.example.json
|
|
246
|
+
│ └── config.example.json # Starter config template
|
|
247
|
+
├── tests/
|
|
248
|
+
│ └── tool-ui-utils.test.ts # Utility tests for user message and diff helpers
|
|
205
249
|
└── assets/
|
|
206
|
-
└── pi-tool-display.png
|
|
250
|
+
└── pi-tool-display.png # README screenshot
|
|
207
251
|
```
|
|
208
252
|
|
|
209
253
|
## Development
|
|
@@ -212,17 +256,14 @@ pi-tool-display/
|
|
|
212
256
|
# Type check
|
|
213
257
|
npm run build
|
|
214
258
|
|
|
215
|
-
# Lint (same as build)
|
|
216
|
-
npm run lint
|
|
217
|
-
|
|
218
259
|
# Run tests
|
|
219
260
|
npm run test
|
|
220
261
|
|
|
221
|
-
# Full
|
|
262
|
+
# Full verification
|
|
222
263
|
npm run check
|
|
223
264
|
```
|
|
224
265
|
|
|
225
|
-
## Related
|
|
266
|
+
## Related extensions
|
|
226
267
|
|
|
227
268
|
- [pi-rtk-optimizer](https://github.com/MasuRii/pi-rtk-optimizer) — RTK optimizer for token-efficient source output
|
|
228
269
|
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
{
|
|
2
|
-
"registerToolOverrides": {
|
|
3
|
-
"read": true,
|
|
4
|
-
"grep": true,
|
|
5
|
-
"find": true,
|
|
6
|
-
"ls": true,
|
|
7
|
-
"bash": true,
|
|
8
|
-
"edit": true,
|
|
9
|
-
"write": true
|
|
10
|
-
},
|
|
11
|
-
"enableNativeUserMessageBox": true,
|
|
12
|
-
"readOutputMode": "hidden",
|
|
13
|
-
"searchOutputMode": "hidden",
|
|
14
|
-
"mcpOutputMode": "hidden",
|
|
15
|
-
"previewLines": 8,
|
|
16
|
-
"expandedPreviewMaxLines": 4000,
|
|
17
|
-
"bashCollapsedLines": 10,
|
|
18
|
-
"diffViewMode": "auto",
|
|
19
|
-
"diffSplitMinWidth": 120,
|
|
20
|
-
"diffCollapsedLines": 24,
|
|
21
|
-
"diffWordWrap": true,
|
|
22
|
-
"showTruncationHints": true,
|
|
23
|
-
"showRtkCompactionHints": true
|
|
24
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"registerToolOverrides": {
|
|
3
|
+
"read": true,
|
|
4
|
+
"grep": true,
|
|
5
|
+
"find": true,
|
|
6
|
+
"ls": true,
|
|
7
|
+
"bash": true,
|
|
8
|
+
"edit": true,
|
|
9
|
+
"write": true
|
|
10
|
+
},
|
|
11
|
+
"enableNativeUserMessageBox": true,
|
|
12
|
+
"readOutputMode": "hidden",
|
|
13
|
+
"searchOutputMode": "hidden",
|
|
14
|
+
"mcpOutputMode": "hidden",
|
|
15
|
+
"previewLines": 8,
|
|
16
|
+
"expandedPreviewMaxLines": 4000,
|
|
17
|
+
"bashCollapsedLines": 10,
|
|
18
|
+
"diffViewMode": "auto",
|
|
19
|
+
"diffSplitMinWidth": 120,
|
|
20
|
+
"diffCollapsedLines": 24,
|
|
21
|
+
"diffWordWrap": true,
|
|
22
|
+
"showTruncationHints": true,
|
|
23
|
+
"showRtkCompactionHints": true
|
|
24
|
+
}
|
package/package.json
CHANGED
package/src/capabilities.ts
CHANGED
|
@@ -1,94 +1,94 @@
|
|
|
1
|
-
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
|
-
import { existsSync } from "node:fs";
|
|
3
|
-
import { homedir } from "node:os";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
import type { ToolDisplayConfig } from "./types.js";
|
|
6
|
-
|
|
7
|
-
export interface ToolDisplayCapabilities {
|
|
8
|
-
hasMcpTooling: boolean;
|
|
9
|
-
hasRtkOptimizer: boolean;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function toRecord(value: unknown): Record<string, unknown> {
|
|
13
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
14
|
-
return {};
|
|
15
|
-
}
|
|
16
|
-
return value as Record<string, unknown>;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function getTextField(value: unknown, field: string): string | undefined {
|
|
20
|
-
const record = toRecord(value);
|
|
21
|
-
const raw = record[field];
|
|
22
|
-
return typeof raw === "string" && raw.trim().length > 0 ? raw.trim() : undefined;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function isMcpToolCandidate(tool: unknown): boolean {
|
|
26
|
-
const name = getTextField(tool, "name");
|
|
27
|
-
if (name === "mcp") {
|
|
28
|
-
return true;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const label = getTextField(tool, "label");
|
|
32
|
-
if (label?.startsWith("MCP ")) {
|
|
33
|
-
return true;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const description = getTextField(tool, "description");
|
|
37
|
-
return typeof description === "string" && /\bmcp\b/i.test(description);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function hasMcpTooling(pi: ExtensionAPI): boolean {
|
|
41
|
-
try {
|
|
42
|
-
const allTools = pi.getAllTools();
|
|
43
|
-
return allTools.some((tool) => isMcpToolCandidate(tool));
|
|
44
|
-
} catch {
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function hasRtkCommand(pi: ExtensionAPI): boolean {
|
|
50
|
-
try {
|
|
51
|
-
const commands = pi.getCommands();
|
|
52
|
-
return commands.some((command) => command.name === "rtk" || command.name.startsWith("rtk-"));
|
|
53
|
-
} catch {
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function hasRtkExtensionPath(cwd: string): boolean {
|
|
59
|
-
const candidates = [
|
|
60
|
-
join(homedir(), ".pi", "agent", "extensions", "pi-rtk-optimizer"),
|
|
61
|
-
join(cwd, ".pi", "extensions", "pi-rtk-optimizer"),
|
|
62
|
-
];
|
|
63
|
-
|
|
64
|
-
for (const candidate of candidates) {
|
|
65
|
-
try {
|
|
66
|
-
if (existsSync(candidate)) {
|
|
67
|
-
return true;
|
|
68
|
-
}
|
|
69
|
-
} catch {
|
|
70
|
-
// Ignore filesystem errors and continue probing other candidates.
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export function detectToolDisplayCapabilities(pi: ExtensionAPI, cwd: string): ToolDisplayCapabilities {
|
|
78
|
-
return {
|
|
79
|
-
hasMcpTooling: hasMcpTooling(pi),
|
|
80
|
-
hasRtkOptimizer: hasRtkCommand(pi) || hasRtkExtensionPath(cwd),
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export function applyCapabilityConfigGuards(
|
|
85
|
-
config: ToolDisplayConfig,
|
|
86
|
-
capabilities: ToolDisplayCapabilities,
|
|
87
|
-
): ToolDisplayConfig {
|
|
88
|
-
return {
|
|
89
|
-
...config,
|
|
90
|
-
registerToolOverrides: { ...config.registerToolOverrides },
|
|
91
|
-
mcpOutputMode: capabilities.hasMcpTooling ? config.mcpOutputMode : "hidden",
|
|
92
|
-
showRtkCompactionHints: capabilities.hasRtkOptimizer ? config.showRtkCompactionHints : false,
|
|
93
|
-
};
|
|
94
|
-
}
|
|
1
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import type { ToolDisplayConfig } from "./types.js";
|
|
6
|
+
|
|
7
|
+
export interface ToolDisplayCapabilities {
|
|
8
|
+
hasMcpTooling: boolean;
|
|
9
|
+
hasRtkOptimizer: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function toRecord(value: unknown): Record<string, unknown> {
|
|
13
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
14
|
+
return {};
|
|
15
|
+
}
|
|
16
|
+
return value as Record<string, unknown>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function getTextField(value: unknown, field: string): string | undefined {
|
|
20
|
+
const record = toRecord(value);
|
|
21
|
+
const raw = record[field];
|
|
22
|
+
return typeof raw === "string" && raw.trim().length > 0 ? raw.trim() : undefined;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function isMcpToolCandidate(tool: unknown): boolean {
|
|
26
|
+
const name = getTextField(tool, "name");
|
|
27
|
+
if (name === "mcp") {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const label = getTextField(tool, "label");
|
|
32
|
+
if (label?.startsWith("MCP ")) {
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const description = getTextField(tool, "description");
|
|
37
|
+
return typeof description === "string" && /\bmcp\b/i.test(description);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function hasMcpTooling(pi: ExtensionAPI): boolean {
|
|
41
|
+
try {
|
|
42
|
+
const allTools = pi.getAllTools();
|
|
43
|
+
return allTools.some((tool) => isMcpToolCandidate(tool));
|
|
44
|
+
} catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function hasRtkCommand(pi: ExtensionAPI): boolean {
|
|
50
|
+
try {
|
|
51
|
+
const commands = pi.getCommands();
|
|
52
|
+
return commands.some((command) => command.name === "rtk" || command.name.startsWith("rtk-"));
|
|
53
|
+
} catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function hasRtkExtensionPath(cwd: string): boolean {
|
|
59
|
+
const candidates = [
|
|
60
|
+
join(homedir(), ".pi", "agent", "extensions", "pi-rtk-optimizer"),
|
|
61
|
+
join(cwd, ".pi", "extensions", "pi-rtk-optimizer"),
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
for (const candidate of candidates) {
|
|
65
|
+
try {
|
|
66
|
+
if (existsSync(candidate)) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
} catch {
|
|
70
|
+
// Ignore filesystem errors and continue probing other candidates.
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function detectToolDisplayCapabilities(pi: ExtensionAPI, cwd: string): ToolDisplayCapabilities {
|
|
78
|
+
return {
|
|
79
|
+
hasMcpTooling: hasMcpTooling(pi),
|
|
80
|
+
hasRtkOptimizer: hasRtkCommand(pi) || hasRtkExtensionPath(cwd),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function applyCapabilityConfigGuards(
|
|
85
|
+
config: ToolDisplayConfig,
|
|
86
|
+
capabilities: ToolDisplayCapabilities,
|
|
87
|
+
): ToolDisplayConfig {
|
|
88
|
+
return {
|
|
89
|
+
...config,
|
|
90
|
+
registerToolOverrides: { ...config.registerToolOverrides },
|
|
91
|
+
mcpOutputMode: capabilities.hasMcpTooling ? config.mcpOutputMode : "hidden",
|
|
92
|
+
showRtkCompactionHints: capabilities.hasRtkOptimizer ? config.showRtkCompactionHints : false,
|
|
93
|
+
};
|
|
94
|
+
}
|