decorated-pi 0.5.5 → 0.6.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/.codegraph/daemon.pid +6 -0
- package/AGENTS.md +92 -0
- package/README.md +53 -64
- package/commands/dp-model.ts +23 -0
- package/commands/dp-settings.ts +23 -0
- package/commands/mcp-status.ts +62 -0
- package/commands/retry.ts +19 -0
- package/commands/usage.ts +544 -0
- package/hooks/compaction.ts +204 -0
- package/hooks/externalize.ts +70 -0
- package/hooks/image-vision.ts +132 -0
- package/hooks/inject-agents-md.ts +164 -0
- package/hooks/mcp.ts +340 -0
- package/hooks/normalize-codeblocks.ts +88 -0
- package/hooks/pi-tool-filter.ts +28 -0
- package/{extensions/safety → hooks/redact}/types.ts +1 -8
- package/hooks/redact.ts +104 -0
- package/{extensions → hooks}/rtk.ts +92 -115
- package/{extensions → hooks}/session-title.ts +17 -28
- package/hooks/skeleton.ts +212 -0
- package/hooks/smart-at.ts +318 -0
- package/{extensions/file-times.ts → hooks/track-mtime.ts} +40 -38
- package/{extensions → hooks}/wakatime.ts +120 -122
- package/index.ts +155 -1
- package/package.json +5 -4
- package/{extensions/settings.ts → settings.ts} +32 -0
- package/{extensions → tools}/lsp/client.ts +0 -25
- package/{extensions → tools}/lsp/format.ts +2 -99
- package/{extensions → tools}/lsp/index.ts +1 -1
- package/{extensions → tools}/lsp/servers.ts +1 -1
- package/{extensions → tools}/lsp/tools.ts +1 -66
- package/{extensions → tools}/lsp/types.ts +0 -11
- package/tools/mcp/builtin/codegraph.ts +45 -0
- package/tools/mcp/builtin/context7.ts +10 -0
- package/tools/mcp/builtin/exa.ts +10 -0
- package/tools/mcp/builtin/index.ts +19 -0
- package/tools/mcp/cache.ts +124 -0
- package/{extensions → tools}/mcp/client.ts +2 -2
- package/{extensions/mcp/builtin.ts → tools/mcp/config.ts} +21 -181
- package/tools/mcp/index.ts +44 -0
- package/tools/mcp/tool-definition.ts +112 -0
- package/{extensions/patch.ts → tools/patch/core.ts} +135 -43
- package/{extensions/io.ts → tools/patch/index.ts} +24 -206
- package/tsconfig.json +10 -1
- package/ui/mcp-status.ts +202 -0
- package/ui/model-picker.ts +162 -0
- package/ui/module-settings.ts +83 -0
- package/ui/usage.ts +396 -0
- package/extensions/index.ts +0 -154
- package/extensions/io-tool-output.ts +0 -33
- package/extensions/mcp/index.ts +0 -435
- package/extensions/model-integration.ts +0 -531
- package/extensions/providers/ark-coding.ts +0 -75
- package/extensions/providers/index.ts +0 -9
- package/extensions/providers/ollama-cloud.ts +0 -101
- package/extensions/providers/qianfan-coding.ts +0 -71
- package/extensions/safety/index.ts +0 -102
- package/extensions/slash.ts +0 -458
- package/extensions/smart-at.ts +0 -481
- package/extensions/subdir-agents.ts +0 -151
- /package/{extensions/safety → hooks/redact}/detect.ts +0 -0
- /package/{extensions/safety → hooks/redact}/entropy.ts +0 -0
- /package/{extensions/safety → hooks/redact}/patterns.ts +0 -0
- /package/{extensions → tools}/lsp/env.ts +0 -0
- /package/{extensions → tools}/lsp/manager.ts +0 -0
- /package/{extensions → tools}/lsp/prompt.ts +0 -0
- /package/{extensions → tools}/lsp/protocol.ts +0 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# decorated-pi — pi extension
|
|
2
|
+
|
|
3
|
+
## Architecture
|
|
4
|
+
|
|
5
|
+
### Three top-level categories
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
decorated-pi/
|
|
9
|
+
├── AGENTS.md
|
|
10
|
+
├── package.json
|
|
11
|
+
├── settings.ts # ~/.pi/agent/decorated-pi.json read/write
|
|
12
|
+
├── tools/ # LLM-callable tools
|
|
13
|
+
├── hooks/ # agent-loop event handlers
|
|
14
|
+
├── commands/ # slash commands
|
|
15
|
+
├── providers/ # LLM providers
|
|
16
|
+
└── test/ # vitest specs
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
| Category | Role | Knows about |
|
|
20
|
+
|----------|------|-------------|
|
|
21
|
+
| `tools/` | Endpoints the LLM calls | other modules via import only |
|
|
22
|
+
| `hooks/` | Reacts to agent-loop events | primitives, other hooks via skeleton |
|
|
23
|
+
| `commands/` | User-typed `/...` commands | `settings.ts` only |
|
|
24
|
+
|
|
25
|
+
**Hard rules**:
|
|
26
|
+
- A tool never registers a hook (no `pi.on(...)` in `tools/*.ts`).
|
|
27
|
+
- A hook does not care whether the triggering tool was registered by us or by pi core.
|
|
28
|
+
- A command does not participate in the agent loop. Its only shared state with tools is `settings.ts`.
|
|
29
|
+
- The skeleton (`hooks/skeleton.ts`) is the only place that calls `pi.on(...)` for hooks.
|
|
30
|
+
|
|
31
|
+
### Skeleton — `hooks/skeleton.ts`
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
pi core
|
|
35
|
+
│
|
|
36
|
+
│ events
|
|
37
|
+
▼
|
|
38
|
+
┌──────────────┐
|
|
39
|
+
│ skeleton │ ← only place that calls pi.on(...)
|
|
40
|
+
│ │
|
|
41
|
+
│ · collect │
|
|
42
|
+
│ · order │
|
|
43
|
+
│ · dispatch │
|
|
44
|
+
│ · owns: │
|
|
45
|
+
│ - deps │
|
|
46
|
+
│ - prompt │
|
|
47
|
+
└──────┬───────┘
|
|
48
|
+
│
|
|
49
|
+
▼
|
|
50
|
+
registered hooks
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Rules**:
|
|
54
|
+
- Registration order = execution order.
|
|
55
|
+
- Two handler modes: **parallel** (return values ignored) for lifecycle events; **compose** (next handler sees previous return) for transformation chains (`before_agent_start` mutates `systemPrompt`, `tool_call` mutates `input.command`, `tool_result` mutates `content`).
|
|
56
|
+
- The skeleton also owns dependency checking and system-prompt guideline injection — hooks declare them, skeleton enforces them at the right event.
|
|
57
|
+
|
|
58
|
+
### `dp-settings`
|
|
59
|
+
|
|
60
|
+
The only shared state is `settings.ts`. Commands write; `index.ts` reads on `/reload` to decide which tools to register. Neither side imports the other.
|
|
61
|
+
|
|
62
|
+
### Adding a new feature
|
|
63
|
+
|
|
64
|
+
**New tool**:
|
|
65
|
+
1. `tools/<name>.ts` exporting `register<Name>Tool(pi)`.
|
|
66
|
+
2. In `index.ts`: `if (isModuleEnabled("<name>")) register<Name>Tool(pi);`
|
|
67
|
+
3. *(Optional)* In `commands/dp-settings.ts`: add the module label so users can toggle it via `/dp-settings`. Without this the tool is always on; users would have to edit `settings.json` directly to disable.
|
|
68
|
+
|
|
69
|
+
If the tool has its own state, protocol client, or dynamic sub-tools, organize it as a directory instead of a single file: `tools/<name>/{client,manager,...}.ts` plus `tools/<name>/index.ts` exporting `register<Name>Tools(pi)`. See `tools/mcp/` and `tools/lsp/` for examples.
|
|
70
|
+
|
|
71
|
+
**New hook**:
|
|
72
|
+
1. `hooks/<name>.ts` exporting `<name>Module` and optionally `setup<X>(sk)`.
|
|
73
|
+
2. In `hooks/index.ts`: export the setup wrapper.
|
|
74
|
+
3. In `index.ts`: call `setup<X>(sk)` in the right slot (order = execution order).
|
|
75
|
+
4. Inside the setup, call `sk.declareDependency` / `sk.declareGuideline` if needed.
|
|
76
|
+
|
|
77
|
+
**New command**:
|
|
78
|
+
1. `commands/<name>.ts` exporting `register<Name>Command(pi)`.
|
|
79
|
+
2. In `index.ts`: call `register<Name>Command(pi)`.
|
|
80
|
+
|
|
81
|
+
## Test
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
npm test
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Organization rules:
|
|
88
|
+
|
|
89
|
+
- Tests mirror the source layout one-to-one: `extensions/<area>/<name>.ts` → `test/<name>.test.ts`.
|
|
90
|
+
- All spec files live flat in `test/` (no nested folders). For a tool that is a directory (e.g. `tools/mcp/`), the spec is `test/mcp.test.ts` covering the whole module.
|
|
91
|
+
- Sub-features of the same module may get their own file: `test/mcp-externalize.test.ts` for a specific concern of MCP, `test/patch.test.ts` for the patch tool.
|
|
92
|
+
- Every new feature or bug fix ships with a test — run `npm test` before considering the change done.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# decorated-pi
|
|
2
2
|
|
|
3
|
-
`decorated-pi` is a practical enhancement pack for [Pi](https://github.com/earendil-works/pi) —
|
|
3
|
+
`decorated-pi` is a practical enhancement pack for [Pi](https://github.com/earendil-works/pi) — token-efficient workflow, cache-friendly design, and smarter tools.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -12,21 +12,41 @@ pi install /path/to/decorated-pi
|
|
|
12
12
|
|
|
13
13
|
## Features
|
|
14
14
|
|
|
15
|
-
### 1.
|
|
15
|
+
### 1. Token Efficiency
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
Multiple layers of token savings that compound across every session.
|
|
18
|
+
|
|
19
|
+
**RTK** — integrates [RTK](https://github.com/rtk-ai/rtk) to compress bash output into structured summaries, so the LLM never sees raw noise.
|
|
20
|
+
|
|
21
|
+
**codegraph** — integrates [codegraph](https://github.com/colbymchenry/codegraph) to offer a code map of your project, so the LLM can navigate symbols and call graphs without chaining `ls` → `grep` → `read`.
|
|
22
|
+
|
|
23
|
+
**Auxiliary Models** — offloads heavy-but-dumb tasks to cheaper models so your primary model only pays for the hard work:
|
|
24
|
+
|
|
25
|
+
- **Image read fallback** — detects image type via magic bytes, calls a configured vision-capable model, and injects the analysis text, so your main model never touches image tokens
|
|
26
|
+
- **Compact model** — handles context compaction with a smaller model instead of burning main-model capacity
|
|
27
|
+
|
|
28
|
+
Configured via `/dp-model`.
|
|
29
|
+
|
|
30
|
+
**Cache‑friendly design** — stable system prompt prefix:
|
|
31
|
+
|
|
32
|
+
- tool definitions, guidelines, and skills are sorted alphabetically so the system prompt is identical across sessions
|
|
33
|
+
- volatile elements like `Current date: …` are stripped before prompt assembly
|
|
34
|
+
- MCP tool schemas are persisted to a local cache, so the tool list stays stable regardless of network conditions or server availability
|
|
35
|
+
|
|
36
|
+
### 2. Smarter Tools
|
|
37
|
+
|
|
38
|
+
Drop‑in replacements for Pi's built‑in tools, with better UX and fewer wasted turns.
|
|
39
|
+
|
|
40
|
+
#### Patch Tool
|
|
18
41
|
|
|
19
42
|
| Capability | Pi native `edit` | `patch` |
|
|
20
43
|
| ------ | :---: | :---: |
|
|
21
|
-
| Syntax‑highlighted overwrite | ✅ streaming | ✅ incremental |
|
|
22
44
|
| **Anchor‑based search** | ❌ extending `oldText` for uniqueness | ✅ `anchor` bounds scope for precise matching |
|
|
23
45
|
| **Fuzzy whitespace match** | ❌ only reports "not found" | ✅ auto‑corrects tab↔space / trailing whitespace mismatches |
|
|
24
46
|
| **Edit fault diagnostics** | ❌ only reports "not found" | ✅ pinpoint faults for LLM comprehension |
|
|
25
47
|
| **Stale‑read protection** | ❌ Blind to external changes | ✅ `read` captures mtime, `patch` rejects stale targets |
|
|
26
48
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
Replaces Pi's built-in `@` file completion with smarter matching and noise filtering:
|
|
49
|
+
#### Smarter `@` File Search
|
|
30
50
|
|
|
31
51
|
| Aspect | Pi native `@` | `decorated-pi` |
|
|
32
52
|
| ------ | :---: | :---: |
|
|
@@ -35,48 +55,15 @@ Replaces Pi's built-in `@` file completion with smarter matching and noise filte
|
|
|
35
55
|
| **Default suggestions** | ❌ all files visible on empty query | ✅ only visible project files |
|
|
36
56
|
| **Match precision** | ❌ case‑insensitive simple scoring | ✅ multi‑level case‑sensitive scoring |
|
|
37
57
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
Three-layer detection: high-confidence known-format patterns (AWS, GitHub, OpenAI, etc.), config-key regex matching, and adjusted Shannon entropy heuristics for unknown secret-like values.
|
|
41
|
-
|
|
42
|
-
Example redaction on a `read` / `bash` output:
|
|
43
|
-
|
|
44
|
-
```json
|
|
45
|
-
{
|
|
46
|
-
"aws_access_key_id": "AKI**************PLE",
|
|
47
|
-
"github_token": "ghp***************def",
|
|
48
|
-
"database_password": "Sup#######t99",
|
|
49
|
-
"api_key": "sk_**************f5a",
|
|
50
|
-
"random_secret": "a1b??????5f5"
|
|
51
|
-
}
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
> `*` = known pattern, `#` = config key regex, `?` = entropy heuristic.
|
|
55
|
-
|
|
56
|
-
### 4. Auxiliary Models
|
|
57
|
-
|
|
58
|
-
Offloads auxiliary ops to cheaper models, reducing cost on every session. Configured via `/dp-model`:
|
|
59
|
-
|
|
60
|
-
- **Image read fallback** — when the model reads an image file, detects type via magic bytes, calls a configured vision-capable model, and replaces the read result with image analysis text (jpeg, png, gif, webp)
|
|
61
|
-
- **Compact model** — uses a configured model for context compaction (instead of the main model).
|
|
62
|
-
|
|
63
|
-
### 5. Progressive Context from `AGENTS.md` / `CLAUDE.md`
|
|
64
|
-
|
|
65
|
-
Extension capability: context is disclosed progressively as the agent works across different parts of the project.
|
|
58
|
+
#### LSP support
|
|
66
59
|
|
|
67
|
-
|
|
68
|
-
- Newly discovered guidance is injected into tool results, scoped to the current context
|
|
69
|
-
|
|
70
|
-
### 6. LSP Tool Suite
|
|
71
|
-
|
|
72
|
-
A cleaned-up, minimal LSP toolset. The extension keeps only the two LSP tools that cover the most practical coding workflows: checking diagnostics after edits and inspecting file structure before focused changes.
|
|
60
|
+
Covers what codegraph can't: real-time compiler and lint errors.
|
|
73
61
|
|
|
74
62
|
- **`lsp_diagnostics`** — file diagnostics with severity filtering
|
|
75
|
-
- **`lsp_document_symbols`** — file symbol outline
|
|
76
63
|
|
|
77
64
|
Supported languages: c/cpp, go, java, lua, json, python, ruby, rust, svelte, typescript
|
|
78
65
|
|
|
79
|
-
###
|
|
66
|
+
### 3. MCP Ecosystem
|
|
80
67
|
|
|
81
68
|
Zero-config MCP client with built-in servers:
|
|
82
69
|
|
|
@@ -84,9 +71,9 @@ Zero-config MCP client with built-in servers:
|
|
|
84
71
|
| --- | --- | --- |
|
|
85
72
|
| Context7 | `context7_*` | `https://mcp.context7.com/mcp` |
|
|
86
73
|
| Exa | `exa_*` | `https://mcp.exa.ai/mcp` |
|
|
74
|
+
| codegraph | `codegraph_*` | bundled binary |
|
|
87
75
|
|
|
88
|
-
**Custom servers** in `.pi/agent/mcp.json` (project) or `~/.pi/agent/decorated-pi.json` (global). Project overrides global.
|
|
89
|
-
Tool prompts and schemas are cached locally so MCP tools are available immediately on startup, even before servers connect.
|
|
76
|
+
**Custom servers** in `.pi/agent/mcp.json` (project) or `~/.pi/agent/decorated-pi.json` (global). Project overrides global. Tool prompts and schemas are cached locally so MCP tools are available immediately on startup — no manual `/reload` required even on first install.
|
|
90
77
|
|
|
91
78
|
```json
|
|
92
79
|
{
|
|
@@ -108,34 +95,36 @@ Tool prompts and schemas are cached locally so MCP tools are available immediate
|
|
|
108
95
|
}
|
|
109
96
|
```
|
|
110
97
|
|
|
111
|
-
Use `/mcp` to view connection status and
|
|
112
|
-
|
|
113
|
-
### 8. Extend Providers
|
|
98
|
+
Use `/mcp` to view connection status and toggle servers.
|
|
114
99
|
|
|
115
|
-
|
|
100
|
+
### 4. Secret Redaction
|
|
116
101
|
|
|
117
|
-
|
|
118
|
-
| ---------- | ----------- |
|
|
119
|
-
| Ollama Cloud | `ollama.com/v1` |
|
|
120
|
-
| Baidu Qianfan | `qianfan.baidubce.com/v2/coding` |
|
|
121
|
-
| ARK Coding | `ark.cn-beijing.volces.com/api/coding/v3` |
|
|
102
|
+
Three-layer detection: high-confidence known-format patterns (AWS, GitHub, OpenAI, etc.), config-key regex matching, and adjusted Shannon entropy heuristics for unknown secret-like values.
|
|
122
103
|
|
|
123
|
-
|
|
104
|
+
Example redaction on a `read` / `bash` output:
|
|
124
105
|
|
|
125
|
-
|
|
126
|
-
|
|
106
|
+
```json
|
|
107
|
+
{
|
|
108
|
+
"aws_access_key_id": "AKI**************PLE",
|
|
109
|
+
"github_token": "ghp***************def",
|
|
110
|
+
"database_password": "Sup#######t99",
|
|
111
|
+
"api_key": "sk_**************f5a",
|
|
112
|
+
"random_secret": "a1b??????5f5"
|
|
113
|
+
}
|
|
114
|
+
```
|
|
127
115
|
|
|
128
|
-
|
|
116
|
+
> `*` = known pattern, `#` = config key regex, `?` = entropy heuristic.
|
|
129
117
|
|
|
130
|
-
|
|
118
|
+
### 5. Other
|
|
131
119
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
120
|
+
- `/usage` — token stats with cache‑hit rate, per‑model breakdown (Session / Today / This Week / This Month / All Time)
|
|
121
|
+
- Progressive context — supports subdirectory `AGENTS.md` / `CLAUDE.md` discovery and injection
|
|
122
|
+
- `/retry` — continue after interruption
|
|
123
|
+
- **WakaTime** — coding activity tracking via [WakaTime](https://wakatime.com)
|
|
135
124
|
|
|
136
|
-
|
|
125
|
+
## Configuration
|
|
137
126
|
|
|
138
|
-
Modules can be toggled
|
|
127
|
+
Runtime settings in `~/.pi/agent/decorated-pi.json`. Modules can be toggled via `/dp-settings` (changes take effect after `/reload`).
|
|
139
128
|
|
|
140
129
|
```json
|
|
141
130
|
{
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* /dp-model — pick image / compact model.
|
|
3
|
+
* UI lives in extensions/ui/model-picker.ts (shared with /mcp status etc).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
7
|
+
import { ModelPickerComponent } from "../ui/model-picker.js";
|
|
8
|
+
|
|
9
|
+
export function registerDpModelCommand(pi: ExtensionAPI): void {
|
|
10
|
+
pi.registerCommand("dp-model", {
|
|
11
|
+
description: "Configure image and compact models",
|
|
12
|
+
handler: async (_args, ctx) => {
|
|
13
|
+
if (ctx.hasUI) {
|
|
14
|
+
await ctx.ui.custom<void>(
|
|
15
|
+
(tui, theme, _kb, done) =>
|
|
16
|
+
new ModelPickerComponent(tui, theme, ctx.modelRegistry, () => done(undefined))
|
|
17
|
+
);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
ctx.ui.notify("dp-model requires interactive mode.", "warning");
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* /dp-settings — toggle module on/off.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
6
|
+
import { ModuleSettingsComponent } from "../ui/module-settings.js";
|
|
7
|
+
|
|
8
|
+
export function registerDpSettingsCommand(pi: ExtensionAPI): void {
|
|
9
|
+
pi.registerCommand("dp-settings", {
|
|
10
|
+
description: "Toggle decorated-pi modules on/off",
|
|
11
|
+
handler: async (_args, ctx) => {
|
|
12
|
+
if (ctx.hasUI) {
|
|
13
|
+
await ctx.ui.custom<void>(
|
|
14
|
+
(tui, theme, _kb, done) =>
|
|
15
|
+
new ModuleSettingsComponent(tui, theme, () => done(undefined))
|
|
16
|
+
);
|
|
17
|
+
ctx.ui.notify("Module settings updated. /reload to apply.", "warning");
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
ctx.ui.notify("dp-settings requires interactive mode.", "warning");
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* /mcp — show MCP servers, toggle, refresh.
|
|
3
|
+
*
|
|
4
|
+
* Wires the pure UI component (ui/mcp-status.ts) to the hook layer
|
|
5
|
+
* (hooks/mcp.ts) by injecting callbacks. The UI itself knows nothing
|
|
6
|
+
* about hooks/config persistence.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
10
|
+
import { McpStatusComponent, type McpServerView } from "../ui/mcp-status.js";
|
|
11
|
+
import { getMcpStatus, refreshServerCache, updateConfigEnabled } from "../hooks/mcp.js";
|
|
12
|
+
import { toggleMcpServerEnabled } from "../tools/mcp/config.js";
|
|
13
|
+
|
|
14
|
+
export function registerMcpStatusCommand(pi: ExtensionAPI): void {
|
|
15
|
+
pi.registerCommand("mcp", {
|
|
16
|
+
description: "Show active MCP servers and their tools",
|
|
17
|
+
handler: async (_args, ctx) => {
|
|
18
|
+
if (ctx.hasUI) {
|
|
19
|
+
await ctx.ui.custom<void>(
|
|
20
|
+
(tui, theme, _kb, done) =>
|
|
21
|
+
new McpStatusComponent(tui, theme, {
|
|
22
|
+
read: () => getMcpStatus() as McpServerView[],
|
|
23
|
+
toggle: async (name, enabled) => {
|
|
24
|
+
const scope: "global" | "project" = "global";
|
|
25
|
+
const ok = toggleMcpServerEnabled(name, enabled, scope, ctx.cwd || undefined);
|
|
26
|
+
if (ok) {
|
|
27
|
+
// Await so the connection (if disabling) is fully torn down
|
|
28
|
+
// before /reload. Otherwise teardownMcp() may hang on a
|
|
29
|
+
// zombie conn and stall session_shutdown.
|
|
30
|
+
await updateConfigEnabled(name, enabled);
|
|
31
|
+
}
|
|
32
|
+
return ok;
|
|
33
|
+
},
|
|
34
|
+
refresh: (name) => refreshServerCache(name, ctx.modelRegistry),
|
|
35
|
+
}, done)
|
|
36
|
+
);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const servers = getMcpStatus();
|
|
40
|
+
if (servers.length === 0) {
|
|
41
|
+
ctx.ui.notify("No MCP servers configured.", "info");
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const lines: string[] = [`MCP servers (${servers.length}):`, ""];
|
|
45
|
+
for (const s of servers) {
|
|
46
|
+
lines.push(`• ${s.name} (${s.source})`);
|
|
47
|
+
lines.push(` URL: ${s.url}`);
|
|
48
|
+
if (s.state === "connecting") lines.push(` Status: connecting...`);
|
|
49
|
+
else if (s.state === "failed") lines.push(` Status: failed — ${s.error ?? "unknown error"}`);
|
|
50
|
+
else {
|
|
51
|
+
lines.push(` Tools: ${s.toolCount}`);
|
|
52
|
+
for (const tool of s.tools) {
|
|
53
|
+
const desc = tool.description ? ` — ${tool.description.slice(0, 60)}` : "";
|
|
54
|
+
lines.push(` - ${tool.name}${desc}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
lines.push("");
|
|
58
|
+
}
|
|
59
|
+
pi.sendMessage({ customType: "mcp-status", content: lines.join("\n"), display: true }, { triggerTurn: false });
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* /retry — continue after interruption.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
6
|
+
|
|
7
|
+
export function registerRetryCommand(pi: ExtensionAPI): void {
|
|
8
|
+
let retryInProgress = false;
|
|
9
|
+
pi.registerCommand("retry", {
|
|
10
|
+
description: "Continue after interruption",
|
|
11
|
+
handler: async (_args, ctx) => {
|
|
12
|
+
if (retryInProgress) { ctx.ui.notify("Retry is already in progress", "warning"); return; }
|
|
13
|
+
if (!ctx.isIdle()) ctx.abort();
|
|
14
|
+
retryInProgress = true;
|
|
15
|
+
pi.sendMessage({ customType: "retry-trigger", content: "Continue.", display: false }, { triggerTurn: true });
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
pi.on("agent_start", () => { retryInProgress = false; });
|
|
19
|
+
}
|