decorated-pi 0.5.5 → 0.7.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.
Files changed (70) hide show
  1. package/README.md +69 -71
  2. package/commands/dp-model.ts +23 -0
  3. package/commands/dp-settings.ts +28 -0
  4. package/commands/mcp-status.ts +62 -0
  5. package/commands/retry.ts +19 -0
  6. package/commands/usage.ts +544 -0
  7. package/hooks/compaction.ts +204 -0
  8. package/hooks/externalize.ts +70 -0
  9. package/hooks/image-vision.ts +132 -0
  10. package/hooks/inject-agents-md.ts +164 -0
  11. package/hooks/mcp.ts +392 -0
  12. package/hooks/normalize-codeblocks.ts +88 -0
  13. package/hooks/pi-tool-filter.ts +28 -0
  14. package/{extensions/safety → hooks/redact}/types.ts +1 -8
  15. package/hooks/redact.ts +104 -0
  16. package/{extensions → hooks}/rtk.ts +92 -115
  17. package/hooks/session-title.ts +78 -0
  18. package/hooks/skeleton.ts +212 -0
  19. package/hooks/smart-at.ts +318 -0
  20. package/{extensions/file-times.ts → hooks/track-mtime.ts} +40 -38
  21. package/{extensions → hooks}/wakatime.ts +120 -122
  22. package/index.ts +166 -1
  23. package/package.json +8 -6
  24. package/settings.ts +341 -0
  25. package/tools/ask/index.ts +93 -0
  26. package/{extensions → tools}/lsp/client.ts +0 -25
  27. package/{extensions → tools}/lsp/format.ts +2 -99
  28. package/{extensions → tools}/lsp/index.ts +1 -1
  29. package/{extensions → tools}/lsp/servers.ts +1 -1
  30. package/{extensions → tools}/lsp/tools.ts +1 -66
  31. package/{extensions → tools}/lsp/types.ts +0 -11
  32. package/tools/mcp/builtin/codegraph.ts +21 -0
  33. package/tools/mcp/builtin/context7.ts +10 -0
  34. package/tools/mcp/builtin/exa.ts +10 -0
  35. package/tools/mcp/builtin/index.ts +19 -0
  36. package/tools/mcp/cache.ts +124 -0
  37. package/{extensions → tools}/mcp/client.ts +2 -2
  38. package/tools/mcp/config.ts +288 -0
  39. package/tools/mcp/index.ts +44 -0
  40. package/tools/mcp/tool-definition.ts +112 -0
  41. package/{extensions/patch.ts → tools/patch/core.ts} +135 -43
  42. package/{extensions/io.ts → tools/patch/index.ts} +24 -206
  43. package/tsconfig.json +10 -1
  44. package/ui/ask.ts +443 -0
  45. package/ui/mcp-status.ts +202 -0
  46. package/ui/model-picker.ts +162 -0
  47. package/ui/module-settings.ts +188 -0
  48. package/ui/usage.ts +396 -0
  49. package/extensions/index.ts +0 -154
  50. package/extensions/io-tool-output.ts +0 -33
  51. package/extensions/mcp/builtin.ts +0 -376
  52. package/extensions/mcp/index.ts +0 -435
  53. package/extensions/model-integration.ts +0 -531
  54. package/extensions/providers/ark-coding.ts +0 -75
  55. package/extensions/providers/index.ts +0 -9
  56. package/extensions/providers/ollama-cloud.ts +0 -101
  57. package/extensions/providers/qianfan-coding.ts +0 -71
  58. package/extensions/safety/index.ts +0 -102
  59. package/extensions/session-title.ts +0 -65
  60. package/extensions/settings.ts +0 -170
  61. package/extensions/slash.ts +0 -458
  62. package/extensions/smart-at.ts +0 -481
  63. package/extensions/subdir-agents.ts +0 -151
  64. /package/{extensions/safety → hooks/redact}/detect.ts +0 -0
  65. /package/{extensions/safety → hooks/redact}/entropy.ts +0 -0
  66. /package/{extensions/safety → hooks/redact}/patterns.ts +0 -0
  67. /package/{extensions → tools}/lsp/env.ts +0 -0
  68. /package/{extensions → tools}/lsp/manager.ts +0 -0
  69. /package/{extensions → tools}/lsp/prompt.ts +0 -0
  70. /package/{extensions → tools}/lsp/protocol.ts +0 -0
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) — smarter tools that are token efficient and cache friendly.
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. Patch Tool
15
+ ### 1. Token Efficiency
16
16
 
17
- Replaces Pi's built-in `edit` with a stronger `patch` tool that adds unique safety and usability improvements on top of the native tools.
17
+ Multiple layers of token savings that compound across every session. **All integrated CLI tools only require installing their respective CLIs zero config**.
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
- ### 2. Smarter `@` File Search
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
- ### 3. Secret redaction
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.
58
+ #### LSP support
55
59
 
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.
66
-
67
- - When reading or editing a file, discovers `AGENTS.md` / `CLAUDE.md` in that file's directory and ancestor directories
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
- ### 7. Built-in MCP Client
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/mcp.json` (global). Project overrides global. Tool prompts and schemas are cached locally so MCP tools are available immediately on startup.
90
77
 
91
78
  ```json
92
79
  {
@@ -108,45 +95,56 @@ 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 registered tools.
98
+ Use `/mcp` to view connection status and toggle servers.
112
99
 
113
- ### 8. Extend Providers
100
+ ### 4. Secret Redaction
114
101
 
115
- Extend providers are registered via `/login` "Use a subscription":
116
-
117
- | Provider | Base URL |
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
- ### 9. Other
104
+ Example redaction on a `read` / `bash` output:
124
105
 
125
- - **RTK** — integrates [RTK](https://github.com/rtk-ai/rtk) for token-efficient command output.
126
- - **WakaTime** — tracks coding activity via [WakaTime](https://wakatime.com).
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
- ## Configuration
116
+ > `*` = known pattern, `#` = config key regex, `?` = entropy heuristic.
129
117
 
130
- Runtime settings are stored in:
118
+ ### 5. Other
131
119
 
132
- ```text
133
- ~/.pi/agent/decorated-pi.json
134
- ```
120
+ - `/usage` — token stats with cache‑hit rate, per‑model breakdown (Session / Today / This Week / This Month / All Time)
121
+ - `/retry` — continue after interruption
122
+ - Progressive context — supports subdirectory `AGENTS.md` / `CLAUDE.md` discovery and injection
123
+ - **WakaTime** — coding activity tracking via [WakaTime](https://wakatime.com)
135
124
 
136
- ### Module Loading
125
+ ## Configuration
137
126
 
138
- Modules can be toggled on/off by `/dp-settings`. Changes take effect after `/reload`.
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
  {
142
131
  "modules": {
143
- "patch": true,
144
- "safety": true,
145
- "rtk": true,
146
- "lsp": true,
147
- "smart-at": true,
148
- "mcp": true,
149
- "wakatime": true
132
+ "tools": {
133
+ "patchOverrideEdit": true,
134
+ "ask": true,
135
+ "lsp": true,
136
+ "mcp": true
137
+ },
138
+ "hooks": {
139
+ "secretRedaction": true,
140
+ "rtk": true,
141
+ "wakatime": true
142
+ },
143
+ "commands": {
144
+ "atOverride": true,
145
+ "retry": true,
146
+ "usage": true
147
+ }
150
148
  }
151
149
  }
152
150
  ```
@@ -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,28 @@
1
+ /**
2
+ * /dp-settings — toggle module on/off.
3
+ */
4
+
5
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
6
+ import { moduleSnapshotChanged } from "../settings.js";
7
+ import { ModuleSettingsComponent } from "../ui/module-settings.js";
8
+
9
+ export function registerDpSettingsCommand(pi: ExtensionAPI): void {
10
+ pi.registerCommand("dp-settings", {
11
+ description: "Toggle decorated-pi modules on/off",
12
+ handler: async (_args, ctx) => {
13
+ if (ctx.hasUI) {
14
+ await ctx.ui.custom<void>(
15
+ (tui, theme, _kb, done) =>
16
+ new ModuleSettingsComponent(tui, theme, () => done(undefined))
17
+ );
18
+ // Only prompt for reload when the effective settings differ from
19
+ // the snapshot taken when pi loaded the extension.
20
+ if (moduleSnapshotChanged()) {
21
+ ctx.ui.notify("Module settings updated. /reload to apply.", "warning");
22
+ }
23
+ return;
24
+ }
25
+ ctx.ui.notify("dp-settings requires interactive mode.", "warning");
26
+ },
27
+ });
28
+ }
@@ -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
+ }