pi-tool-display 0.1.4 → 0.1.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 +15 -0
- package/README.md +150 -63
- package/config/config.example.json +24 -24
- package/package.json +1 -1
- package/src/capabilities.ts +94 -94
- package/src/config-modal.ts +367 -518
- package/src/index.ts +90 -88
- package/src/presets.ts +83 -83
- package/src/thinking-label.ts +171 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.1.6] - 2026-03-04
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- Use absolute GitHub raw URL for README image to fix npm display
|
|
14
|
+
|
|
15
|
+
## [0.1.5] - 2026-03-04
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- Thinking labels feature that prefixes AI reasoning blocks with themed "Thinking:" labels for better readability
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- Rewrote README.md with professional documentation standards
|
|
22
|
+
- Added comprehensive feature documentation, configuration reference, and usage examples
|
|
23
|
+
- Simplified settings modal by removing less-used advanced options (expandedPreviewMaxLines, diffSplitMinWidth, diffCollapsedLines, tool ownership toggles)
|
|
24
|
+
|
|
10
25
|
## [0.1.4] - 2026-03-02
|
|
11
26
|
|
|
12
27
|
### Added
|
package/README.md
CHANGED
|
@@ -1,41 +1,43 @@
|
|
|
1
1
|
# pi-tool-display
|
|
2
2
|
|
|
3
|
-
OpenCode-style tool rendering for the Pi coding agent.
|
|
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` provides compact, expandable tool call/result rendering that keeps your terminal clean while preserving access to full details when needed.
|
|
6
6
|
|
|
7
|
-

|
|
7
|
+

|
|
8
8
|
|
|
9
9
|
## Features
|
|
10
10
|
|
|
11
|
-
- Compact
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
- Presets
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
- Native bordered user message box styling (configurable on/off)
|
|
11
|
+
- **Compact Tool Rendering** — Overrides built-in `read`, `grep`, `find`, `ls`, `bash`, `edit`, and `write` tools with collapsed-by-default output
|
|
12
|
+
- **MCP Tool Support** — Custom rendering for MCP gateway tool calls with configurable verbosity
|
|
13
|
+
- **Rich Diff Display** — Adaptive split/unified diff views with syntax highlighting and inline change emphasis for `edit` and `write` operations
|
|
14
|
+
- **Three Presets** — Quick verbosity profiles: `opencode` (minimal), `balanced` (summaries), `verbose` (previews)
|
|
15
|
+
- **Thinking Labels** — Prefixes AI thinking blocks with themed labels for better readability
|
|
16
|
+
- **Native User Message Box** — Bordered user prompt styling (optional)
|
|
17
|
+
- **Extension Compatibility** — Per-tool ownership toggles to avoid conflicts with other extensions
|
|
18
|
+
- **Capability Detection** — Auto-hides MCP/RTK settings when those features aren't available
|
|
20
19
|
|
|
21
20
|
## Installation
|
|
22
21
|
|
|
23
|
-
### Local
|
|
22
|
+
### Local Extension Folder
|
|
24
23
|
|
|
25
|
-
Place this folder in:
|
|
24
|
+
Place this folder in one of Pi's auto-discovery locations:
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
```text
|
|
27
|
+
# Global (all projects)
|
|
28
|
+
~/.pi/agent/extensions/pi-tool-display
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
# Project-specific
|
|
31
|
+
.pi/extensions/pi-tool-display
|
|
32
|
+
```
|
|
31
33
|
|
|
32
|
-
###
|
|
34
|
+
### npm Package
|
|
33
35
|
|
|
34
36
|
```bash
|
|
35
37
|
pi install npm:pi-tool-display
|
|
36
38
|
```
|
|
37
39
|
|
|
38
|
-
|
|
40
|
+
### Git Repository
|
|
39
41
|
|
|
40
42
|
```bash
|
|
41
43
|
pi install git:github.com/MasuRii/pi-tool-display
|
|
@@ -43,39 +45,88 @@ pi install git:github.com/MasuRii/pi-tool-display
|
|
|
43
45
|
|
|
44
46
|
## Usage
|
|
45
47
|
|
|
46
|
-
|
|
48
|
+
### Interactive Settings
|
|
49
|
+
|
|
50
|
+
Open the settings modal:
|
|
47
51
|
|
|
48
52
|
```text
|
|
49
53
|
/tool-display
|
|
50
54
|
```
|
|
51
55
|
|
|
52
|
-
Direct
|
|
56
|
+
### Direct Commands
|
|
53
57
|
|
|
54
58
|
```text
|
|
55
|
-
/tool-display show
|
|
56
|
-
/tool-display reset
|
|
57
|
-
/tool-display preset opencode
|
|
58
|
-
/tool-display preset balanced
|
|
59
|
-
/tool-display preset verbose
|
|
59
|
+
/tool-display show # Display current configuration
|
|
60
|
+
/tool-display reset # Reset to default settings
|
|
61
|
+
/tool-display preset opencode # Apply opencode preset
|
|
62
|
+
/tool-display preset balanced # Apply balanced preset
|
|
63
|
+
/tool-display preset verbose # Apply verbose preset
|
|
60
64
|
```
|
|
61
65
|
|
|
62
66
|
## Presets
|
|
63
67
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
68
|
+
| Preset | Read Output | Search Output | MCP Output | Preview Lines | Bash Lines |
|
|
69
|
+
|--------|-------------|---------------|------------|---------------|------------|
|
|
70
|
+
| `opencode` | hidden | hidden | hidden | 8 | 10 |
|
|
71
|
+
| `balanced` | summary | count | summary | 8 | 10 |
|
|
72
|
+
| `verbose` | preview | preview | preview | 12 | 20 |
|
|
73
|
+
|
|
74
|
+
**opencode** (default) — Minimal inline-only display; tool results stay collapsed
|
|
75
|
+
**balanced** — Compact summaries showing line counts and match totals
|
|
76
|
+
**verbose** — Expanded previews with more visible content by default
|
|
67
77
|
|
|
68
78
|
## Configuration
|
|
69
79
|
|
|
70
|
-
Runtime
|
|
80
|
+
Runtime configuration is stored at:
|
|
71
81
|
|
|
72
82
|
```text
|
|
73
83
|
~/.pi/agent/extensions/pi-tool-display/config.json
|
|
74
84
|
```
|
|
75
85
|
|
|
76
|
-
A starter
|
|
86
|
+
A starter template is available at `config/config.example.json`.
|
|
87
|
+
|
|
88
|
+
### Configuration Options
|
|
77
89
|
|
|
78
|
-
|
|
90
|
+
| Option | Type | Default | Description |
|
|
91
|
+
|--------|------|---------|-------------|
|
|
92
|
+
| `registerToolOverrides` | object | all `true` | Per-tool ownership flags (see below) |
|
|
93
|
+
| `enableNativeUserMessageBox` | boolean | `true` | Enable bordered user message styling |
|
|
94
|
+
| `readOutputMode` | string | `"hidden"` | `hidden`, `summary`, or `preview` |
|
|
95
|
+
| `searchOutputMode` | string | `"hidden"` | `hidden`, `count`, or `preview` |
|
|
96
|
+
| `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 |
|
|
100
|
+
| `diffViewMode` | string | `"auto"` | `auto`, `split`, or `unified` |
|
|
101
|
+
| `diffSplitMinWidth` | number | `120` | Minimum terminal width for split view |
|
|
102
|
+
| `diffCollapsedLines` | number | `24` | Lines shown in collapsed diff |
|
|
103
|
+
| `diffWordWrap` | boolean | `true` | Wrap long lines in diff view |
|
|
104
|
+
| `showTruncationHints` | boolean | `true` | Show truncation indicators |
|
|
105
|
+
| `showRtkCompactionHints` | boolean | `true` | Show RTK compaction hints |
|
|
106
|
+
|
|
107
|
+
### Tool Override Ownership
|
|
108
|
+
|
|
109
|
+
Control which tools this extension overrides:
|
|
110
|
+
|
|
111
|
+
```json
|
|
112
|
+
{
|
|
113
|
+
"registerToolOverrides": {
|
|
114
|
+
"read": true,
|
|
115
|
+
"grep": true,
|
|
116
|
+
"find": true,
|
|
117
|
+
"ls": true,
|
|
118
|
+
"bash": true,
|
|
119
|
+
"edit": true,
|
|
120
|
+
"write": true
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Set any tool to `false` to leave rendering ownership to another extension.
|
|
126
|
+
|
|
127
|
+
> **Note:** Changes to tool ownership require `/reload` to take effect.
|
|
128
|
+
|
|
129
|
+
### Example Configuration
|
|
79
130
|
|
|
80
131
|
```json
|
|
81
132
|
{
|
|
@@ -88,57 +139,93 @@ Important compatibility config:
|
|
|
88
139
|
"edit": true,
|
|
89
140
|
"write": true
|
|
90
141
|
},
|
|
91
|
-
"enableNativeUserMessageBox": true
|
|
142
|
+
"enableNativeUserMessageBox": true,
|
|
143
|
+
"readOutputMode": "summary",
|
|
144
|
+
"searchOutputMode": "count",
|
|
145
|
+
"mcpOutputMode": "summary",
|
|
146
|
+
"previewLines": 12,
|
|
147
|
+
"expandedPreviewMaxLines": 4000,
|
|
148
|
+
"bashCollapsedLines": 15,
|
|
149
|
+
"diffViewMode": "auto",
|
|
150
|
+
"diffSplitMinWidth": 120,
|
|
151
|
+
"diffCollapsedLines": 24,
|
|
152
|
+
"diffWordWrap": true,
|
|
153
|
+
"showTruncationHints": true,
|
|
154
|
+
"showRtkCompactionHints": true
|
|
92
155
|
}
|
|
93
156
|
```
|
|
94
157
|
|
|
95
|
-
|
|
96
|
-
- Set any tool to `false` to leave ownership to another extension.
|
|
97
|
-
- `enableNativeUserMessageBox` controls whether bordered user prompt rendering is enabled.
|
|
98
|
-
- Changing ownership values requires `/reload` to apply.
|
|
99
|
-
- Legacy `registerReadToolOverride` is still accepted for backward compatibility and maps to `registerToolOverrides.read`.
|
|
100
|
-
- If MCP tooling is unavailable, MCP output controls are hidden and MCP output mode is forced to `hidden`.
|
|
101
|
-
- If RTK optimizer is unavailable, RTK compaction hint controls are hidden and RTK hint rendering is forced off.
|
|
158
|
+
## Capability Detection
|
|
102
159
|
|
|
103
|
-
|
|
160
|
+
The extension automatically detects available capabilities:
|
|
161
|
+
|
|
162
|
+
- **MCP Tooling** — When no MCP tools are available, MCP-related settings are hidden and MCP output mode is forced to `hidden`
|
|
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
|
|
164
|
+
|
|
165
|
+
This prevents confusion from settings that have no effect in your environment.
|
|
104
166
|
|
|
105
167
|
## Troubleshooting
|
|
106
168
|
|
|
107
|
-
|
|
169
|
+
### Tool Ownership Conflicts
|
|
170
|
+
|
|
171
|
+
If another extension owns a tool and you see rendering conflicts:
|
|
172
|
+
|
|
173
|
+
1. Set the corresponding `registerToolOverrides.<tool>` to `false` in your config
|
|
174
|
+
2. Run `/reload` in Pi
|
|
175
|
+
3. Verify with `/tool-display show` that the ownership reflects expected `off` values
|
|
108
176
|
|
|
109
|
-
|
|
110
|
-
2. Run `/reload` in Pi.
|
|
111
|
-
3. Verify with `/tool-display show` that `owners={...}` reflects the expected `off` values.
|
|
177
|
+
### Configuration Not Loading
|
|
112
178
|
|
|
113
|
-
|
|
179
|
+
If settings aren't applying:
|
|
114
180
|
|
|
115
|
-
|
|
181
|
+
1. Check the config file exists at `~/.pi/agent/extensions/pi-tool-display/config.json`
|
|
182
|
+
2. Verify JSON syntax is valid
|
|
183
|
+
3. Run `/tool-display show` to see current effective configuration
|
|
184
|
+
|
|
185
|
+
## Project Structure
|
|
186
|
+
|
|
187
|
+
```text
|
|
188
|
+
pi-tool-display/
|
|
189
|
+
├── index.ts # Extension entrypoint (Pi auto-discovery)
|
|
190
|
+
├── src/
|
|
191
|
+
│ ├── index.ts # Extension bootstrap and registration
|
|
192
|
+
│ ├── tool-overrides.ts # Built-in and MCP renderer overrides
|
|
193
|
+
│ ├── diff-renderer.ts # Edit/write diff rendering engine
|
|
194
|
+
│ ├── config-modal.ts # /tool-display settings UI
|
|
195
|
+
│ ├── capabilities.ts # MCP/RTK capability detection
|
|
196
|
+
│ ├── config-store.ts # Config load/save and normalization
|
|
197
|
+
│ ├── presets.ts # Preset definitions and matching
|
|
198
|
+
│ ├── render-utils.ts # Shared rendering helpers
|
|
199
|
+
│ ├── thinking-label.ts # Thinking block label formatting
|
|
200
|
+
│ ├── user-message-box-native.ts # User message border styling
|
|
201
|
+
│ ├── types.ts # TypeScript type definitions
|
|
202
|
+
│ └── zellij-modal.ts # Modal UI primitives
|
|
203
|
+
├── config/
|
|
204
|
+
│ └── config.example.json # Starter config template
|
|
205
|
+
└── assets/
|
|
206
|
+
└── pi-tool-display.png # README screenshot
|
|
207
|
+
```
|
|
116
208
|
|
|
117
209
|
## Development
|
|
118
210
|
|
|
119
211
|
```bash
|
|
212
|
+
# Type check
|
|
120
213
|
npm run build
|
|
214
|
+
|
|
215
|
+
# Lint (same as build)
|
|
121
216
|
npm run lint
|
|
217
|
+
|
|
218
|
+
# Run tests
|
|
122
219
|
npm run test
|
|
220
|
+
|
|
221
|
+
# Full check
|
|
123
222
|
npm run check
|
|
124
223
|
```
|
|
125
224
|
|
|
126
|
-
##
|
|
127
|
-
|
|
128
|
-
-
|
|
129
|
-
- `src/index.ts` - extension bootstrap and registration
|
|
130
|
-
- `src/tool-overrides.ts` - built-in and MCP renderer overrides
|
|
131
|
-
- `src/diff-renderer.ts` - edit/write diff rendering engine
|
|
132
|
-
- `src/config-modal.ts` - `/tool-display` settings UI
|
|
133
|
-
- `src/capabilities.ts` - MCP/RTK capability detection and runtime config guards
|
|
134
|
-
- `src/config-store.ts` - config load/save and normalization
|
|
135
|
-
- `src/presets.ts` - preset definitions and matching
|
|
136
|
-
- `src/render-utils.ts` - shared rendering helpers
|
|
137
|
-
- `src/user-message-box-native.ts` - user message border patch
|
|
138
|
-
- `src/zellij-modal.ts` - vendored modal UI primitives used by settings UI
|
|
139
|
-
- `config/config.example.json` - starter config template
|
|
140
|
-
- `assets/pi-tool-display.png` - README screenshot asset
|
|
225
|
+
## Related Extensions
|
|
226
|
+
|
|
227
|
+
- [pi-rtk-optimizer](https://github.com/MasuRii/pi-rtk-optimizer) — RTK optimizer for token-efficient source output
|
|
141
228
|
|
|
142
229
|
## License
|
|
143
230
|
|
|
144
|
-
MIT
|
|
231
|
+
[MIT](LICENSE)
|
|
@@ -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
|
+
}
|