@tuanhung303/opencode-dcp 2.0.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 (159) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +249 -0
  3. package/dist/index.d.ts +4 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +71 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/lib/commands/context.d.ts +49 -0
  8. package/dist/lib/commands/context.d.ts.map +1 -0
  9. package/dist/lib/commands/context.js +191 -0
  10. package/dist/lib/commands/context.js.map +1 -0
  11. package/dist/lib/commands/help.d.ts +15 -0
  12. package/dist/lib/commands/help.d.ts.map +1 -0
  13. package/dist/lib/commands/help.js +26 -0
  14. package/dist/lib/commands/help.js.map +1 -0
  15. package/dist/lib/commands/stats.d.ts +15 -0
  16. package/dist/lib/commands/stats.d.ts.map +1 -0
  17. package/dist/lib/commands/stats.js +44 -0
  18. package/dist/lib/commands/stats.js.map +1 -0
  19. package/dist/lib/commands/sweep.d.ts +23 -0
  20. package/dist/lib/commands/sweep.d.ts.map +1 -0
  21. package/dist/lib/commands/sweep.js +191 -0
  22. package/dist/lib/commands/sweep.js.map +1 -0
  23. package/dist/lib/config.d.ts +69 -0
  24. package/dist/lib/config.d.ts.map +1 -0
  25. package/dist/lib/config.js +754 -0
  26. package/dist/lib/config.js.map +1 -0
  27. package/dist/lib/hooks.d.ts +17 -0
  28. package/dist/lib/hooks.d.ts.map +1 -0
  29. package/dist/lib/hooks.js +121 -0
  30. package/dist/lib/hooks.js.map +1 -0
  31. package/dist/lib/logger.d.ts +31 -0
  32. package/dist/lib/logger.d.ts.map +1 -0
  33. package/dist/lib/logger.js +189 -0
  34. package/dist/lib/logger.js.map +1 -0
  35. package/dist/lib/messages/index.d.ts +3 -0
  36. package/dist/lib/messages/index.d.ts.map +1 -0
  37. package/dist/lib/messages/index.js +3 -0
  38. package/dist/lib/messages/index.js.map +1 -0
  39. package/dist/lib/messages/inject.d.ts +5 -0
  40. package/dist/lib/messages/inject.d.ts.map +1 -0
  41. package/dist/lib/messages/inject.js +127 -0
  42. package/dist/lib/messages/inject.js.map +1 -0
  43. package/dist/lib/messages/prune.d.ts +5 -0
  44. package/dist/lib/messages/prune.d.ts.map +1 -0
  45. package/dist/lib/messages/prune.js +86 -0
  46. package/dist/lib/messages/prune.js.map +1 -0
  47. package/dist/lib/messages/utils.d.ts +31 -0
  48. package/dist/lib/messages/utils.d.ts.map +1 -0
  49. package/dist/lib/messages/utils.js +228 -0
  50. package/dist/lib/messages/utils.js.map +1 -0
  51. package/dist/lib/prompts/discard-tool-spec.d.ts +2 -0
  52. package/dist/lib/prompts/discard-tool-spec.d.ts.map +1 -0
  53. package/dist/lib/prompts/discard-tool-spec.js +41 -0
  54. package/dist/lib/prompts/discard-tool-spec.js.map +1 -0
  55. package/dist/lib/prompts/extract-tool-spec.d.ts +2 -0
  56. package/dist/lib/prompts/extract-tool-spec.d.ts.map +1 -0
  57. package/dist/lib/prompts/extract-tool-spec.js +48 -0
  58. package/dist/lib/prompts/extract-tool-spec.js.map +1 -0
  59. package/dist/lib/prompts/index.d.ts +2 -0
  60. package/dist/lib/prompts/index.d.ts.map +1 -0
  61. package/dist/lib/prompts/index.js +34 -0
  62. package/dist/lib/prompts/index.js.map +1 -0
  63. package/dist/lib/prompts/nudge/both.d.ts +2 -0
  64. package/dist/lib/prompts/nudge/both.d.ts.map +1 -0
  65. package/dist/lib/prompts/nudge/both.js +11 -0
  66. package/dist/lib/prompts/nudge/both.js.map +1 -0
  67. package/dist/lib/prompts/nudge/discard.d.ts +2 -0
  68. package/dist/lib/prompts/nudge/discard.d.ts.map +1 -0
  69. package/dist/lib/prompts/nudge/discard.js +10 -0
  70. package/dist/lib/prompts/nudge/discard.js.map +1 -0
  71. package/dist/lib/prompts/nudge/extract.d.ts +2 -0
  72. package/dist/lib/prompts/nudge/extract.d.ts.map +1 -0
  73. package/dist/lib/prompts/nudge/extract.js +10 -0
  74. package/dist/lib/prompts/nudge/extract.js.map +1 -0
  75. package/dist/lib/prompts/system/both.d.ts +2 -0
  76. package/dist/lib/prompts/system/both.d.ts.map +1 -0
  77. package/dist/lib/prompts/system/both.js +61 -0
  78. package/dist/lib/prompts/system/both.js.map +1 -0
  79. package/dist/lib/prompts/system/discard.d.ts +2 -0
  80. package/dist/lib/prompts/system/discard.d.ts.map +1 -0
  81. package/dist/lib/prompts/system/discard.js +52 -0
  82. package/dist/lib/prompts/system/discard.js.map +1 -0
  83. package/dist/lib/prompts/system/extract.d.ts +2 -0
  84. package/dist/lib/prompts/system/extract.d.ts.map +1 -0
  85. package/dist/lib/prompts/system/extract.js +52 -0
  86. package/dist/lib/prompts/system/extract.js.map +1 -0
  87. package/dist/lib/protected-file-patterns.d.ts +12 -0
  88. package/dist/lib/protected-file-patterns.d.ts.map +1 -0
  89. package/dist/lib/protected-file-patterns.js +69 -0
  90. package/dist/lib/protected-file-patterns.js.map +1 -0
  91. package/dist/lib/shared-utils.d.ts +4 -0
  92. package/dist/lib/shared-utils.d.ts.map +1 -0
  93. package/dist/lib/shared-utils.js +14 -0
  94. package/dist/lib/shared-utils.js.map +1 -0
  95. package/dist/lib/state/index.d.ts +4 -0
  96. package/dist/lib/state/index.d.ts.map +1 -0
  97. package/dist/lib/state/index.js +4 -0
  98. package/dist/lib/state/index.js.map +1 -0
  99. package/dist/lib/state/persistence.d.ts +22 -0
  100. package/dist/lib/state/persistence.d.ts.map +1 -0
  101. package/dist/lib/state/persistence.js +107 -0
  102. package/dist/lib/state/persistence.js.map +1 -0
  103. package/dist/lib/state/state.d.ts +8 -0
  104. package/dist/lib/state/state.d.ts.map +1 -0
  105. package/dist/lib/state/state.js +115 -0
  106. package/dist/lib/state/state.js.map +1 -0
  107. package/dist/lib/state/tool-cache.d.ts +13 -0
  108. package/dist/lib/state/tool-cache.d.ts.map +1 -0
  109. package/dist/lib/state/tool-cache.js +77 -0
  110. package/dist/lib/state/tool-cache.js.map +1 -0
  111. package/dist/lib/state/types.d.ts +33 -0
  112. package/dist/lib/state/types.d.ts.map +1 -0
  113. package/dist/lib/state/types.js +2 -0
  114. package/dist/lib/state/types.js.map +1 -0
  115. package/dist/lib/state/utils.d.ts +2 -0
  116. package/dist/lib/state/utils.d.ts.map +1 -0
  117. package/dist/lib/state/utils.js +10 -0
  118. package/dist/lib/state/utils.js.map +1 -0
  119. package/dist/lib/strategies/deduplication.d.ts +10 -0
  120. package/dist/lib/strategies/deduplication.d.ts.map +1 -0
  121. package/dist/lib/strategies/deduplication.js +94 -0
  122. package/dist/lib/strategies/deduplication.js.map +1 -0
  123. package/dist/lib/strategies/index.d.ts +7 -0
  124. package/dist/lib/strategies/index.d.ts.map +1 -0
  125. package/dist/lib/strategies/index.js +7 -0
  126. package/dist/lib/strategies/index.js.map +1 -0
  127. package/dist/lib/strategies/placeholder-compression.d.ts +5 -0
  128. package/dist/lib/strategies/placeholder-compression.d.ts.map +1 -0
  129. package/dist/lib/strategies/placeholder-compression.js +148 -0
  130. package/dist/lib/strategies/placeholder-compression.js.map +1 -0
  131. package/dist/lib/strategies/prune-thinking.d.ts +15 -0
  132. package/dist/lib/strategies/prune-thinking.d.ts.map +1 -0
  133. package/dist/lib/strategies/prune-thinking.js +79 -0
  134. package/dist/lib/strategies/prune-thinking.js.map +1 -0
  135. package/dist/lib/strategies/purge-errors.d.ts +13 -0
  136. package/dist/lib/strategies/purge-errors.d.ts.map +1 -0
  137. package/dist/lib/strategies/purge-errors.js +59 -0
  138. package/dist/lib/strategies/purge-errors.js.map +1 -0
  139. package/dist/lib/strategies/supersede-writes.d.ts +13 -0
  140. package/dist/lib/strategies/supersede-writes.d.ts.map +1 -0
  141. package/dist/lib/strategies/supersede-writes.js +84 -0
  142. package/dist/lib/strategies/supersede-writes.js.map +1 -0
  143. package/dist/lib/strategies/tools.d.ts +14 -0
  144. package/dist/lib/strategies/tools.d.ts.map +1 -0
  145. package/dist/lib/strategies/tools.js +135 -0
  146. package/dist/lib/strategies/tools.js.map +1 -0
  147. package/dist/lib/strategies/utils.d.ts +11 -0
  148. package/dist/lib/strategies/utils.d.ts.map +1 -0
  149. package/dist/lib/strategies/utils.js +75 -0
  150. package/dist/lib/strategies/utils.js.map +1 -0
  151. package/dist/lib/ui/notification.d.ts +9 -0
  152. package/dist/lib/ui/notification.d.ts.map +1 -0
  153. package/dist/lib/ui/notification.js +77 -0
  154. package/dist/lib/ui/notification.js.map +1 -0
  155. package/dist/lib/ui/utils.d.ts +10 -0
  156. package/dist/lib/ui/utils.d.ts.map +1 -0
  157. package/dist/lib/ui/utils.js +87 -0
  158. package/dist/lib/ui/utils.js.map +1 -0
  159. package/package.json +63 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 tarquinen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,249 @@
1
+ # Dynamic Context Pruning Plugin (Aggressive Fork)
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@tarquinen/opencode-dcp.svg)](https://www.npmjs.com/package/@tarquinen/opencode-dcp)
4
+
5
+ Automatically reduces token usage in OpenCode by removing obsolete tools from conversation history.
6
+
7
+ > **⚡ This is an aggressive fork** with more aggressive default settings and two new pruning strategies: **Prune Thinking** and **Placeholder Compression**.
8
+
9
+ ![DCP in action](dcp-demo5.png)
10
+
11
+ ## Installation
12
+
13
+ Add to your OpenCode config:
14
+
15
+ ```jsonc
16
+ // opencode.jsonc
17
+ {
18
+ "plugin": ["@tarquinen/opencode-dcp@latest"],
19
+ }
20
+ ```
21
+
22
+ Using `@latest` ensures you always get the newest version automatically when OpenCode starts.
23
+
24
+ Restart OpenCode. The plugin will automatically start optimizing your sessions.
25
+
26
+ ## How Pruning Works
27
+
28
+ DCP uses multiple tools and strategies to reduce context size:
29
+
30
+ ### Tools
31
+
32
+ **Discard** — Exposes a `discard` tool that the AI can call to remove completed or noisy tool content from context.
33
+
34
+ **Extract** — Exposes an `extract` tool that the AI can call to distill valuable context into concise summaries before removing the tool content.
35
+
36
+ ### Strategies
37
+
38
+ **Deduplication** — Identifies repeated tool calls (e.g., reading the same file multiple times) and keeps only the most recent output. Runs automatically on every request with zero LLM cost.
39
+
40
+ **Supersede Writes** — Prunes write tool inputs for files that have subsequently been read. When a file is written and later read, the original write content becomes redundant since the current file state is captured in the read result. Runs automatically on every request with zero LLM cost. **⚡ Enabled by default in this fork.**
41
+
42
+ **Purge Errors** — Prunes tool inputs for tools that returned errors after a configurable number of turns (default: 2). Error messages are preserved for context, but the potentially large input content is removed. Runs automatically on every request with zero LLM cost. **⚡ Reduced from 4 to 2 turns in this fork.**
43
+
44
+ **Prune Thinking** ⚡ NEW — Removes extended thinking tokens (`<thinking>` blocks, OpenAI reasoning fields) from older assistant messages. Thinking tokens consume significant context but provide no utility after the response is generated. Preserves recent turns for cache efficiency. Runs automatically with zero LLM cost.
45
+
46
+ **Placeholder Compression** ⚡ NEW — Replaces verbose tool outputs with actionable placeholder hints while preserving the tool call structure (name + input) as breadcrumbs. This allows the agent to see what actions were taken and re-execute if needed, while dramatically reducing context size. Based on [Escaping Context Amnesia](https://www.hadijaveed.me/2025/11/26/escaping-context-amnesia-ai-agents/).
47
+
48
+ Example:
49
+ ```
50
+ Before: [1000 tokens of file content]
51
+ After: [File read previously. Read again if needed: /path/to/file.ts]
52
+ ```
53
+
54
+ Your session history is never modified—DCP replaces pruned content with placeholders before sending requests to your LLM.
55
+
56
+ ## Changes from Upstream
57
+
58
+ | Setting | Upstream | This Fork | Rationale |
59
+ |---------|----------|-----------|-----------|
60
+ | `purgeErrors.turns` | 4 | **2** | Errors rarely useful after 2 turns |
61
+ | `nudgeFrequency` | 10 | **5** | More frequent prune reminders |
62
+ | `supersedeWrites.enabled` | false | **true** | Safe with read-after-write pattern |
63
+ | `pruneThinking.enabled` | N/A | **true** | Strip ephemeral thinking tokens |
64
+ | `placeholderCompression.enabled` | N/A | **true** | Compress verbose outputs, keep breadcrumbs |
65
+
66
+ ## Impact on Prompt Caching
67
+
68
+ LLM providers like Anthropic and OpenAI cache prompts based on exact prefix matching. When DCP prunes a tool output, it changes the message content, which invalidates cached prefixes from that point forward.
69
+
70
+ **Trade-off:** You lose some cache read benefits but gain larger token savings from reduced context size and performance improvements through reduced context poisoning. In most cases, the token savings outweigh the cache miss cost—especially in long sessions where context bloat becomes significant.
71
+
72
+ > **Note:** In testing, cache hit rates were approximately 65% with DCP enabled vs 85% without.
73
+
74
+ **Best use case:** Providers that count usage in requests, such as Github Copilot and Google Antigravity have no negative price impact.
75
+
76
+ ## Configuration
77
+
78
+ DCP uses its own config file:
79
+
80
+ - Global: `~/.config/opencode/dcp.jsonc` (or `dcp.json`), created automatically on first run
81
+ - Custom config directory: `$OPENCODE_CONFIG_DIR/dcp.jsonc` (or `dcp.json`), if `OPENCODE_CONFIG_DIR` is set
82
+ - Project: `.opencode/dcp.jsonc` (or `dcp.json`) in your project's `.opencode` directory
83
+
84
+ <details>
85
+ <summary><strong>Default Configuration</strong> (click to expand)</summary>
86
+
87
+ ```jsonc
88
+ {
89
+ "$schema": "https://raw.githubusercontent.com/Opencode-DCP/opencode-dynamic-context-pruning/master/dcp.schema.json",
90
+ // Enable or disable the plugin
91
+ "enabled": true,
92
+ // Enable debug logging to ~/.config/opencode/logs/dcp/
93
+ "debug": false,
94
+ // Notification display: "off", "minimal", or "detailed"
95
+ "pruneNotification": "detailed",
96
+ // Slash commands configuration
97
+ "commands": {
98
+ "enabled": true,
99
+ // Additional tools to protect from pruning via commands (e.g., /dcp sweep)
100
+ "protectedTools": [],
101
+ },
102
+ // Protect from pruning for <turns> message turns
103
+ "turnProtection": {
104
+ "enabled": false,
105
+ "turns": 4,
106
+ },
107
+ // Protect file operations from pruning via glob patterns
108
+ // Patterns match tool parameters.filePath (e.g. read/write/edit)
109
+ "protectedFilePatterns": [],
110
+ // LLM-driven context pruning tools
111
+ "tools": {
112
+ // Shared settings for all prune tools
113
+ "settings": {
114
+ // Nudge the LLM to use prune tools (every <nudgeFrequency> tool results)
115
+ "nudgeEnabled": true,
116
+ "nudgeFrequency": 5, // ⚡ Changed from 10
117
+ // Additional tools to protect from pruning
118
+ "protectedTools": [],
119
+ },
120
+ // Removes tool content from context without preservation (for completed tasks or noise)
121
+ "discard": {
122
+ "enabled": true,
123
+ },
124
+ // Distills key findings into preserved knowledge before removing raw content
125
+ "extract": {
126
+ "enabled": true,
127
+ // Show distillation content as an ignored message notification
128
+ "showDistillation": false,
129
+ },
130
+ },
131
+ // Automatic pruning strategies
132
+ "strategies": {
133
+ // Remove duplicate tool calls (same tool with same arguments)
134
+ "deduplication": {
135
+ "enabled": true,
136
+ // Additional tools to protect from pruning
137
+ "protectedTools": [],
138
+ },
139
+ // Prune write tool inputs when the file has been subsequently read
140
+ "supersedeWrites": {
141
+ "enabled": true, // ⚡ Changed from false
142
+ },
143
+ // Prune tool inputs for errored tools after X turns
144
+ "purgeErrors": {
145
+ "enabled": true,
146
+ // Number of turns before errored tool inputs are pruned
147
+ "turns": 2, // ⚡ Changed from 4
148
+ // Additional tools to protect from pruning
149
+ "protectedTools": [],
150
+ },
151
+ // ⚡ NEW: Remove extended thinking tokens from older messages
152
+ "pruneThinking": {
153
+ "enabled": true,
154
+ // Turns to wait before pruning (preserves cache)
155
+ "delayTurns": 1,
156
+ },
157
+ // ⚡ NEW: Replace verbose tool outputs with actionable placeholders
158
+ "placeholderCompression": {
159
+ "enabled": true,
160
+ // Turns to wait before compressing
161
+ "delayTurns": 2,
162
+ // Only compress outputs larger than this token count
163
+ "minOutputTokens": 100,
164
+ // Additional tools to protect from compression
165
+ "protectedTools": [],
166
+ },
167
+ },
168
+ }
169
+ ```
170
+
171
+ </details>
172
+
173
+ ### New Strategy: Prune Thinking
174
+
175
+ Removes extended thinking content from assistant messages after a configurable delay:
176
+
177
+ - **Anthropic**: Removes `type: "thinking"` content blocks
178
+ - **OpenAI**: Removes `reasoning` field from messages
179
+ - **Fallback**: Strips `<thinking>...</thinking>` tags from text
180
+
181
+ ```jsonc
182
+ "pruneThinking": {
183
+ "enabled": true,
184
+ "delayTurns": 1 // Keep current turn for cache, prune older
185
+ }
186
+ ```
187
+
188
+ ### New Strategy: Placeholder Compression
189
+
190
+ Replaces verbose tool outputs with actionable hints while preserving breadcrumbs:
191
+
192
+ | Tool | Placeholder Example |
193
+ |------|---------------------|
194
+ | `read` | `[File read previously. Read again if needed: /path/to/file.ts]` |
195
+ | `grep` | `[Content search completed for: pattern. Search again if needed]` |
196
+ | `bash` | `[Command executed: npm test. Re-run if needed]` |
197
+ | `webfetch` | `[URL fetched: https://example.com. Fetch again if needed]` |
198
+
199
+ **Protected tools** (never compressed): `write`, `edit`, `todowrite`, `todoread`, `discard`, `extract`, `task`, `question`, `batch`, `skill`
200
+
201
+ ```jsonc
202
+ "placeholderCompression": {
203
+ "enabled": true,
204
+ "delayTurns": 2, // Wait 2 turns before compressing
205
+ "minOutputTokens": 100, // Only compress large outputs
206
+ "protectedTools": [] // Add custom protected tools
207
+ }
208
+ ```
209
+
210
+ ### Commands
211
+
212
+ DCP provides a `/dcp` slash command:
213
+
214
+ - `/dcp` — Shows available DCP commands
215
+ - `/dcp context` — Shows a breakdown of your current session's token usage by category (system, user, assistant, tools, etc.) and how much has been saved through pruning.
216
+ - `/dcp stats` — Shows cumulative pruning statistics across all sessions.
217
+ - `/dcp sweep` — Prunes all tools since the last user message. Accepts an optional count: `/dcp sweep 10` prunes the last 10 tools. Respects `commands.protectedTools`.
218
+
219
+ ### Turn Protection
220
+
221
+ When enabled, turn protection prevents tool outputs from being pruned for a configurable number of message turns. This gives the AI time to reference recent tool outputs before they become prunable. Applies to both `discard` and `extract` tools, as well as automatic strategies.
222
+
223
+ ### Protected Tools
224
+
225
+ By default, these tools are always protected from pruning across all strategies:
226
+ `task`, `todowrite`, `todoread`, `discard`, `extract`, `batch`, `write`, `edit`
227
+
228
+ The `protectedTools` arrays in each section add to this default list.
229
+
230
+ ### Config Precedence
231
+
232
+ Settings are merged in order:
233
+ Defaults → Global (`~/.config/opencode/dcp.jsonc`) → Config Dir (`$OPENCODE_CONFIG_DIR/dcp.jsonc`) → Project (`.opencode/dcp.jsonc`).
234
+ Each level overrides the previous, so project settings take priority over config-dir and global, which take priority over defaults.
235
+
236
+ Restart OpenCode after making config changes.
237
+
238
+ ## Limitations
239
+
240
+ **Subagents** — DCP is disabled for subagents. Subagents are not designed to be token efficient; what matters is that the final message returned to the main agent is a concise summary of findings. DCP's pruning could interfere with this summarization behavior.
241
+
242
+ ## References
243
+
244
+ - [Escaping Context Amnesia in AI Agents](https://www.hadijaveed.me/2025/11/26/escaping-context-amnesia-ai-agents/) - Inspiration for placeholder compression strategy
245
+ - [Original DCP Repository](https://github.com/Opencode-DCP/opencode-dynamic-context-pruning)
246
+
247
+ ## License
248
+
249
+ MIT
@@ -0,0 +1,4 @@
1
+ import type { Plugin } from "@opencode-ai/plugin";
2
+ declare const plugin: Plugin;
3
+ export default plugin;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAWjD,QAAA,MAAM,MAAM,EAAE,MA0FK,CAAA;AAEnB,eAAe,MAAM,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,71 @@
1
+ import { getConfig } from "./lib/config";
2
+ import { Logger } from "./lib/logger";
3
+ import { createSessionState } from "./lib/state";
4
+ import { createDiscardTool, createExtractTool } from "./lib/strategies";
5
+ import { createChatMessageTransformHandler, createCommandExecuteHandler, createSystemPromptHandler, } from "./lib/hooks";
6
+ const plugin = (async (ctx) => {
7
+ const config = getConfig(ctx);
8
+ if (!config.enabled) {
9
+ return {};
10
+ }
11
+ const logger = new Logger(config.debug);
12
+ const state = createSessionState();
13
+ logger.info("DCP initialized", {
14
+ strategies: config.strategies,
15
+ });
16
+ return {
17
+ "experimental.chat.system.transform": createSystemPromptHandler(state, logger, config),
18
+ "experimental.chat.messages.transform": createChatMessageTransformHandler(ctx.client, state, logger, config),
19
+ "chat.message": async (input, _output) => {
20
+ // Cache variant from real user messages (not synthetic)
21
+ // This avoids scanning all messages to find variant
22
+ state.variant = input.variant;
23
+ logger.debug("Cached variant from chat.message hook", { variant: input.variant });
24
+ },
25
+ "command.execute.before": createCommandExecuteHandler(ctx.client, state, logger, config, ctx.directory),
26
+ tool: {
27
+ ...(config.tools.discard.enabled && {
28
+ discard: createDiscardTool({
29
+ client: ctx.client,
30
+ state,
31
+ logger,
32
+ config,
33
+ workingDirectory: ctx.directory,
34
+ }),
35
+ }),
36
+ ...(config.tools.extract.enabled && {
37
+ extract: createExtractTool({
38
+ client: ctx.client,
39
+ state,
40
+ logger,
41
+ config,
42
+ workingDirectory: ctx.directory,
43
+ }),
44
+ }),
45
+ },
46
+ config: async (opencodeConfig) => {
47
+ if (config.commands.enabled) {
48
+ opencodeConfig.command ??= {};
49
+ opencodeConfig.command["dcp"] = {
50
+ template: "",
51
+ description: "Show available DCP commands",
52
+ };
53
+ }
54
+ const toolsToAdd = [];
55
+ if (config.tools.discard.enabled)
56
+ toolsToAdd.push("discard");
57
+ if (config.tools.extract.enabled)
58
+ toolsToAdd.push("extract");
59
+ if (toolsToAdd.length > 0) {
60
+ const existingPrimaryTools = opencodeConfig.experimental?.primary_tools ?? [];
61
+ opencodeConfig.experimental = {
62
+ ...opencodeConfig.experimental,
63
+ primary_tools: [...existingPrimaryTools, ...toolsToAdd],
64
+ };
65
+ logger.info(`Added ${toolsToAdd.map((t) => `'${t}'`).join(" and ")} to experimental.primary_tools via config mutation`);
66
+ }
67
+ },
68
+ };
69
+ });
70
+ export default plugin;
71
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * DCP Context Command
3
+ * Shows a visual breakdown of token usage in the current session.
4
+ *
5
+ * TOKEN CALCULATION STRATEGY
6
+ * ==========================
7
+ * We minimize tokenizer estimation by leveraging API-reported values wherever possible.
8
+ *
9
+ * WHAT WE GET FROM THE API (exact):
10
+ * - tokens.input : Input tokens for each assistant response
11
+ * - tokens.output : Output tokens generated (includes text + tool calls)
12
+ * - tokens.reasoning: Reasoning tokens used
13
+ * - tokens.cache : Cache read/write tokens
14
+ *
15
+ * HOW WE CALCULATE EACH CATEGORY:
16
+ *
17
+ * SYSTEM = firstAssistant.input + cache.read - tokenizer(firstUserMessage)
18
+ * The first response's input contains system + first user message.
19
+ *
20
+ * TOOLS = tokenizer(toolInputs + toolOutputs) - prunedTokens
21
+ * We must tokenize tools anyway for pruning decisions.
22
+ *
23
+ * USER = tokenizer(all user messages)
24
+ * User messages are typically small, so estimation is acceptable.
25
+ *
26
+ * ASSISTANT = total - system - user - tools
27
+ * Calculated as residual. This absorbs:
28
+ * - Assistant text output tokens
29
+ * - Reasoning tokens (if persisted by the model)
30
+ * - Any estimation errors
31
+ *
32
+ * TOTAL = input + output + reasoning + cache.read + cache.write
33
+ * Matches opencode's UI display.
34
+ *
35
+ * WHY ASSISTANT IS THE RESIDUAL:
36
+ * If reasoning tokens persist in context (model-dependent), they semantically
37
+ * belong with "Assistant" since reasoning IS assistant-generated content.
38
+ */
39
+ import type { Logger } from "../logger";
40
+ import type { SessionState, WithParts } from "../state";
41
+ export interface ContextCommandContext {
42
+ client: any;
43
+ state: SessionState;
44
+ logger: Logger;
45
+ sessionId: string;
46
+ messages: WithParts[];
47
+ }
48
+ export declare function handleContextCommand(ctx: ContextCommandContext): Promise<void>;
49
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../lib/commands/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAQvD,MAAM,WAAW,qBAAqB;IAClC,MAAM,EAAE,GAAG,CAAA;IACX,KAAK,EAAE,YAAY,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,SAAS,EAAE,CAAA;CACxB;AAuLD,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CASpF"}
@@ -0,0 +1,191 @@
1
+ /**
2
+ * DCP Context Command
3
+ * Shows a visual breakdown of token usage in the current session.
4
+ *
5
+ * TOKEN CALCULATION STRATEGY
6
+ * ==========================
7
+ * We minimize tokenizer estimation by leveraging API-reported values wherever possible.
8
+ *
9
+ * WHAT WE GET FROM THE API (exact):
10
+ * - tokens.input : Input tokens for each assistant response
11
+ * - tokens.output : Output tokens generated (includes text + tool calls)
12
+ * - tokens.reasoning: Reasoning tokens used
13
+ * - tokens.cache : Cache read/write tokens
14
+ *
15
+ * HOW WE CALCULATE EACH CATEGORY:
16
+ *
17
+ * SYSTEM = firstAssistant.input + cache.read - tokenizer(firstUserMessage)
18
+ * The first response's input contains system + first user message.
19
+ *
20
+ * TOOLS = tokenizer(toolInputs + toolOutputs) - prunedTokens
21
+ * We must tokenize tools anyway for pruning decisions.
22
+ *
23
+ * USER = tokenizer(all user messages)
24
+ * User messages are typically small, so estimation is acceptable.
25
+ *
26
+ * ASSISTANT = total - system - user - tools
27
+ * Calculated as residual. This absorbs:
28
+ * - Assistant text output tokens
29
+ * - Reasoning tokens (if persisted by the model)
30
+ * - Any estimation errors
31
+ *
32
+ * TOTAL = input + output + reasoning + cache.read + cache.write
33
+ * Matches opencode's UI display.
34
+ *
35
+ * WHY ASSISTANT IS THE RESIDUAL:
36
+ * If reasoning tokens persist in context (model-dependent), they semantically
37
+ * belong with "Assistant" since reasoning IS assistant-generated content.
38
+ */
39
+ import { sendIgnoredMessage } from "../ui/notification";
40
+ import { formatTokenCount } from "../ui/utils";
41
+ import { isMessageCompacted } from "../shared-utils";
42
+ import { isIgnoredUserMessage } from "../messages/utils";
43
+ import { countTokens, getCurrentParams } from "../strategies/utils";
44
+ function analyzeTokens(state, messages) {
45
+ const breakdown = {
46
+ system: 0,
47
+ user: 0,
48
+ assistant: 0,
49
+ tools: 0,
50
+ toolCount: 0,
51
+ prunedTokens: state.stats.totalPruneTokens,
52
+ prunedCount: state.prune.toolIds.length,
53
+ total: 0,
54
+ };
55
+ let firstAssistant;
56
+ for (const msg of messages) {
57
+ if (msg.info.role === "assistant") {
58
+ const assistantInfo = msg.info;
59
+ if (assistantInfo.tokens?.input > 0 || assistantInfo.tokens?.cache?.read > 0) {
60
+ firstAssistant = assistantInfo;
61
+ break;
62
+ }
63
+ }
64
+ }
65
+ let lastAssistant;
66
+ for (let i = messages.length - 1; i >= 0; i--) {
67
+ const msg = messages[i];
68
+ if (msg.info.role === "assistant") {
69
+ const assistantInfo = msg.info;
70
+ if (assistantInfo.tokens?.output > 0) {
71
+ lastAssistant = assistantInfo;
72
+ break;
73
+ }
74
+ }
75
+ }
76
+ const apiInput = lastAssistant?.tokens?.input || 0;
77
+ const apiOutput = lastAssistant?.tokens?.output || 0;
78
+ const apiReasoning = lastAssistant?.tokens?.reasoning || 0;
79
+ const apiCacheRead = lastAssistant?.tokens?.cache?.read || 0;
80
+ const apiCacheWrite = lastAssistant?.tokens?.cache?.write || 0;
81
+ breakdown.total = apiInput + apiOutput + apiReasoning + apiCacheRead + apiCacheWrite;
82
+ const userTextParts = [];
83
+ const toolInputParts = [];
84
+ const toolOutputParts = [];
85
+ let firstUserText = "";
86
+ let foundFirstUser = false;
87
+ for (const msg of messages) {
88
+ if (isMessageCompacted(state, msg))
89
+ continue;
90
+ if (msg.info.role === "user" && isIgnoredUserMessage(msg))
91
+ continue;
92
+ const parts = Array.isArray(msg.parts) ? msg.parts : [];
93
+ for (const part of parts) {
94
+ if (part.type === "text" && msg.info.role === "user") {
95
+ const textPart = part;
96
+ const text = textPart.text || "";
97
+ userTextParts.push(text);
98
+ if (!foundFirstUser) {
99
+ firstUserText += text;
100
+ }
101
+ }
102
+ else if (part.type === "tool") {
103
+ const toolPart = part;
104
+ breakdown.toolCount++;
105
+ if (toolPart.state?.input) {
106
+ const inputStr = typeof toolPart.state.input === "string"
107
+ ? toolPart.state.input
108
+ : JSON.stringify(toolPart.state.input);
109
+ toolInputParts.push(inputStr);
110
+ }
111
+ if (toolPart.state?.status === "completed" && toolPart.state?.output) {
112
+ const outputStr = typeof toolPart.state.output === "string"
113
+ ? toolPart.state.output
114
+ : JSON.stringify(toolPart.state.output);
115
+ toolOutputParts.push(outputStr);
116
+ }
117
+ }
118
+ }
119
+ if (msg.info.role === "user" && !isIgnoredUserMessage(msg) && !foundFirstUser) {
120
+ foundFirstUser = true;
121
+ }
122
+ }
123
+ const firstUserTokens = countTokens(firstUserText);
124
+ breakdown.user = countTokens(userTextParts.join("\n"));
125
+ const toolInputTokens = countTokens(toolInputParts.join("\n"));
126
+ const toolOutputTokens = countTokens(toolOutputParts.join("\n"));
127
+ if (firstAssistant) {
128
+ const firstInput = (firstAssistant.tokens?.input || 0) + (firstAssistant.tokens?.cache?.read || 0);
129
+ breakdown.system = Math.max(0, firstInput - firstUserTokens);
130
+ }
131
+ breakdown.tools = Math.max(0, toolInputTokens + toolOutputTokens - breakdown.prunedTokens);
132
+ breakdown.assistant = Math.max(0, breakdown.total - breakdown.system - breakdown.user - breakdown.tools);
133
+ return breakdown;
134
+ }
135
+ function createBar(value, maxValue, width, char = "█") {
136
+ if (maxValue === 0)
137
+ return "";
138
+ const filled = Math.round((value / maxValue) * width);
139
+ const bar = char.repeat(Math.max(0, filled));
140
+ return bar;
141
+ }
142
+ function formatContextMessage(breakdown) {
143
+ const lines = [];
144
+ const barWidth = 30;
145
+ const toolsInContext = breakdown.toolCount - breakdown.prunedCount;
146
+ const toolsLabel = `Tools (${toolsInContext})`;
147
+ const categories = [
148
+ { label: "System", value: breakdown.system, char: "█" },
149
+ { label: "User", value: breakdown.user, char: "▓" },
150
+ { label: "Assistant", value: breakdown.assistant, char: "▒" },
151
+ { label: toolsLabel, value: breakdown.tools, char: "░" },
152
+ ];
153
+ const maxLabelLen = Math.max(...categories.map((c) => c.label.length));
154
+ lines.push("╭───────────────────────────────────────────────────────────╮");
155
+ lines.push("│ DCP Context Analysis │");
156
+ lines.push("╰───────────────────────────────────────────────────────────╯");
157
+ lines.push("");
158
+ lines.push("Session Context Breakdown:");
159
+ lines.push("─".repeat(60));
160
+ lines.push("");
161
+ for (const cat of categories) {
162
+ const bar = createBar(cat.value, breakdown.total, barWidth, cat.char);
163
+ const percentage = breakdown.total > 0 ? ((cat.value / breakdown.total) * 100).toFixed(1) : "0.0";
164
+ const labelWithPct = `${cat.label.padEnd(maxLabelLen)} ${percentage.padStart(5)}% `;
165
+ const valueStr = formatTokenCount(cat.value).padStart(13);
166
+ lines.push(`${labelWithPct}│${bar.padEnd(barWidth)}│${valueStr}`);
167
+ }
168
+ lines.push("");
169
+ lines.push("─".repeat(60));
170
+ lines.push("");
171
+ lines.push("Summary:");
172
+ if (breakdown.prunedTokens > 0) {
173
+ const withoutPruning = breakdown.total + breakdown.prunedTokens;
174
+ lines.push(` Pruned: ${breakdown.prunedCount} tools (~${formatTokenCount(breakdown.prunedTokens)})`);
175
+ lines.push(` Current context: ~${formatTokenCount(breakdown.total)}`);
176
+ lines.push(` Without DCP: ~${formatTokenCount(withoutPruning)}`);
177
+ }
178
+ else {
179
+ lines.push(` Current context: ~${formatTokenCount(breakdown.total)}`);
180
+ }
181
+ lines.push("");
182
+ return lines.join("\n");
183
+ }
184
+ export async function handleContextCommand(ctx) {
185
+ const { client, state, logger, sessionId, messages } = ctx;
186
+ const breakdown = analyzeTokens(state, messages);
187
+ const message = formatContextMessage(breakdown);
188
+ const params = getCurrentParams(state, messages, logger);
189
+ await sendIgnoredMessage(client, sessionId, message, params, logger);
190
+ }
191
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../lib/commands/context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * DCP Help command handler.
3
+ * Shows available DCP commands and their descriptions.
4
+ */
5
+ import type { Logger } from "../logger";
6
+ import type { SessionState, WithParts } from "../state";
7
+ export interface HelpCommandContext {
8
+ client: any;
9
+ state: SessionState;
10
+ logger: Logger;
11
+ sessionId: string;
12
+ messages: WithParts[];
13
+ }
14
+ export declare function handleHelpCommand(ctx: HelpCommandContext): Promise<void>;
15
+ //# sourceMappingURL=help.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../../lib/commands/help.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAIvD,MAAM,WAAW,kBAAkB;IAC/B,MAAM,EAAE,GAAG,CAAA;IACX,KAAK,EAAE,YAAY,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,SAAS,EAAE,CAAA;CACxB;AAiBD,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAS9E"}