Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
111 commits
Select commit Hold shift + click to select a range
43d6e7a
refactor: compress to rule them all
spoons-and-mirrors Feb 9, 2026
7e3fbed
tweaks
spoons-and-mirrors Feb 9, 2026
00ae4b4
3.0 release image
spoons-and-mirrors Feb 10, 2026
55f4f5f
prompt rewrite
spoons-and-mirrors Feb 10, 2026
8c28716
feat: annotate tool outputs with token counts
spoons-and-mirrors Feb 11, 2026
553ca89
pull prompts from dev for ref
spoons-and-mirrors Feb 11, 2026
6bdbd95
remove uid refs
spoons-and-mirrors Feb 11, 2026
8d21d58
refine tool format
spoons-and-mirrors Feb 11, 2026
15e4f17
prompts
spoons-and-mirrors Feb 11, 2026
a65d5db
rm dev prompts
spoons-and-mirrors Feb 11, 2026
9cffd3c
nudge
spoons-and-mirrors Feb 11, 2026
90318ce
changin token count wording
spoons-and-mirrors Feb 11, 2026
4c6b024
prompts: preserving user intent
spoons-and-mirrors Feb 11, 2026
1132af4
nudgeGap
spoons-and-mirrors Feb 12, 2026
da56861
feat: cLog
spoons-and-mirrors Feb 11, 2026
e391a8f
summary searching sucks
Tarquinen Feb 12, 2026
7741734
nudge
spoons-and-mirrors Feb 12, 2026
7a48c26
prompts
spoons-and-mirrors Feb 12, 2026
9b40772
cleanup context-limit hint injection architecture
Tarquinen Feb 12, 2026
ffc340d
token counts targets
spoons-and-mirrors Feb 12, 2026
701088b
range chronology badgering
spoons-and-mirrors Feb 12, 2026
13d622a
tool inputs badger
spoons-and-mirrors Feb 12, 2026
48d4729
refactor context-limit anchor lifecycle
Tarquinen Feb 12, 2026
eea6067
rename
Tarquinen Feb 12, 2026
3b19bb8
cleanup
Tarquinen Feb 12, 2026
e2b2797
cleanup
Tarquinen Feb 12, 2026
4025efe
cleanup
Tarquinen Feb 12, 2026
7608931
bargraph: v1
spoons-and-mirrors Feb 12, 2026
63bd217
bargraph v2
spoons-and-mirrors Feb 12, 2026
5c8e9b7
different shading for "new stuff since last compress use"
spoons-and-mirrors Feb 12, 2026
07eb6b5
cleanup
Tarquinen Feb 12, 2026
aa60c0d
remath proportional bargraph display
spoons-and-mirrors Feb 12, 2026
12c763a
cleanup
Tarquinen Feb 12, 2026
fca89fb
Merge branch 'refactor/one-tool-to-rule-them-all' into cleanup/contex…
Tarquinen Feb 12, 2026
83907c2
cleanup
Tarquinen Feb 12, 2026
38dc7f4
Merge pull request #386 from Opencode-DCP/cleanup/context-limit-hints
Tarquinen Feb 12, 2026
ed7e66f
use real nudge prompt
Tarquinen Feb 12, 2026
96e5b2e
add system prompt to bargraph session representation and use full bra…
spoons-and-mirrors Feb 12, 2026
96062b0
differentiate system prompt char
spoons-and-mirrors Feb 12, 2026
d4d637f
refactor: derive compress graph from token buckets
Tarquinen Feb 13, 2026
94f97bd
remove: unused contextPressure and compressContext config options
Tarquinen Feb 13, 2026
6c9c795
remove: unused nudgeEnabled and nudgeFrequency config options
Tarquinen Feb 13, 2026
bffa213
refactor: rename limitNudgeInterval to nudgeGap
Tarquinen Feb 13, 2026
e18f764
cleanup: remove dead prune/distill refs from prompts
Tarquinen Feb 13, 2026
acd72b9
cleanup: remove prune/distill remnants
spoons-and-mirrors Feb 13, 2026
7de0666
cleanup: simplify prompts to compress-only
Tarquinen Feb 13, 2026
8896aaa
cleanup: remove ToolFlags, simplify renderSystemPrompt
Tarquinen Feb 13, 2026
2399d1f
fix: fallback token accounting when api tokens missing
spoons-and-mirrors Feb 13, 2026
eaf25eb
cleanup: remove prompt loading indirection
Tarquinen Feb 13, 2026
43497b1
cleanup: rename applyAnchoredHints to applyAnchoredNudge
Tarquinen Feb 13, 2026
3684485
cleanup: remove unused nudgeCounter
Tarquinen Feb 13, 2026
e2cb885
cleanup: remove unused lastToolPrune
Tarquinen Feb 13, 2026
6ab7f24
feat(ui): render positional compress graph
Tarquinen Feb 13, 2026
65b016c
fix(compress): reject ambiguous summary matches
Tarquinen Feb 13, 2026
8af64d1
feat(ui): restore strict bargraph v2 compress map
Tarquinen Feb 13, 2026
0bdce2e
cleanup(ui): remove unused compression graph helpers
Tarquinen Feb 13, 2026
a600a10
cleanup: don't search reasoning parts for compress strings
Tarquinen Feb 13, 2026
65dcd21
chore: default nudgeGap to 5
Tarquinen Feb 13, 2026
302e901
format
Tarquinen Feb 13, 2026
53dee49
Merge pull request #381 from misterdas/fix/critical-bugs-and-improvem…
Tarquinen Feb 14, 2026
6ce2fb4
Merge remote-tracking branch 'origin/dev' into refactor/one-tool-to-r…
Tarquinen Feb 14, 2026
1394615
refactor: rework compress flow with block placeholders
Tarquinen Feb 15, 2026
3d867b3
docs: clarify compress placeholder guidance
Tarquinen Feb 15, 2026
80c8fd0
prompt: removing macro scale, try and force the model to compress sho…
spoons-and-mirrors Feb 15, 2026
8f57ea3
Merge branch 'refactor/one-tool-to-rule-them-all' into feat/compress-…
Tarquinen Feb 15, 2026
fd233eb
refactor: migrate scripts to OpenCode session API
Tarquinen Feb 15, 2026
eddf269
feat: migrate compress to injected ID boundaries
Tarquinen Feb 16, 2026
7b0dfea
Merge pull request #392 from Opencode-DCP/feat/compress-block-placeho…
Tarquinen Feb 16, 2026
385f361
refactor: migrate compress boundary resolution to injected IDs
Tarquinen Feb 17, 2026
27ed0b1
docs: update compress boundary guidance
Tarquinen Feb 17, 2026
0bd9771
refactor: inject assistant message IDs into last tool output
Tarquinen Feb 17, 2026
e59e216
docs: clarify dcp message-id metadata tags in prompts
Tarquinen Feb 17, 2026
66f4e66
refactor: inject IDs after compress
Tarquinen Feb 17, 2026
362352d
refactor: align compress blocks with bN metadata and placeholders
Tarquinen Feb 17, 2026
3c9ce68
docs: simplify and align compress/system ID guidance
Tarquinen Feb 17, 2026
12dc48c
refactor: make synthetic injection IDs deterministic
Tarquinen Feb 17, 2026
298d3eb
refactor: rename nudgeGap to nudgeFrequency and fix config inconsiste…
Tarquinen Feb 17, 2026
47017dc
refactor: remove tools.settings.protectedTools
Tarquinen Feb 18, 2026
e8e29e7
fix: preserve compress input schema when pruning
Tarquinen Feb 18, 2026
73220ff
refactor: gate ID injection on compress permission
Tarquinen Feb 18, 2026
2348e75
cleanup
Tarquinen Feb 18, 2026
3142eb9
feat: migrate opencode scripts from API to sqlite
Tarquinen Feb 18, 2026
506da6c
refactor: move inject helpers to messages utils
Tarquinen Feb 18, 2026
1a7442d
feat: add soft nudge anchors for context reminders
Tarquinen Feb 19, 2026
ea36818
refactor: stop generating non-system prompts from markdown
Tarquinen Feb 19, 2026
c75edaa
fix: guard malformed compress summaries
Tarquinen Feb 19, 2026
0752119
Merge branch 'dev' into refactor/one-tool-to-rule-them-all, resolving…
Tarquinen Feb 19, 2026
90889d0
refactor: simplify compress notification summary and rename header wr…
Tarquinen Feb 19, 2026
2fa382f
refactor: remove compress wrappers
Tarquinen Feb 19, 2026
ba4e7d4
fix(utils): skip thought signature validator for google and vertex mo…
Tarquinen Feb 21, 2026
c8d3404
feat(utils): add system note to synthetic tool part
Tarquinen Feb 21, 2026
f81d135
feat(utils): format synthetic tool system note as xml
Tarquinen Feb 21, 2026
418533b
feat(scripts): add summary statistics to session timeline
Tarquinen Feb 21, 2026
c9a8239
feat(logger): include tool title and metadata in context logs
Tarquinen Feb 21, 2026
9433f63
refactor(utils): replace claude check with text-part capability helper
Tarquinen Feb 21, 2026
7f86002
chore(prune): stop rewriting compress summaries
Tarquinen Feb 21, 2026
cd5bc53
refactor: rename remaining soft nudge references to turn nudge
Tarquinen Feb 22, 2026
fe92176
ui: expand compress progress bar to 75 chars and reposition
Tarquinen Feb 22, 2026
592cebf
refactor: remove redundant isIgnoredUserMessage check
Tarquinen Feb 22, 2026
66f5e3e
fix: strip hallucinated message-id and turn-nudge blocks
Tarquinen Feb 22, 2026
377ad29
feat: add iteration nudges and consolidate nudge state
Tarquinen Feb 22, 2026
dfa1f7a
refactor(config): flatten compress settings into top-level config
Tarquinen Feb 22, 2026
e80fc54
refactor(nudges): centralize anchored nudge application
Tarquinen Feb 22, 2026
b902968
ui: reduce compress progress bar to 50 chars
Tarquinen Feb 22, 2026
cdabdb7
fix(context): correct tool counts with compressed ranges
Tarquinen Feb 22, 2026
29f42b1
fix(nudges): anchor turn nudges to user messages
Tarquinen Feb 22, 2026
3b17792
fix(manual): skip nudge injection in manual mode
Tarquinen Feb 22, 2026
0aa9750
prompt wording
Tarquinen Feb 22, 2026
dbd00f5
v2.2.0-beta0 - Bump version
Tarquinen Feb 22, 2026
8bc4f6c
docs(readme): add beta notice
Tarquinen Feb 22, 2026
be1e68f
docs(readme): restore config collapse text
Tarquinen Feb 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ Thumbs.db
# OpenCode
.opencode/

# Python cache
__pycache__/
*.py[cod]
*$py.class

# Generated prompt files (from scripts/generate-prompts.ts)
lib/prompts/**/*.generated.ts

Expand All @@ -40,4 +45,4 @@ test-update.ts
docs/
SCHEMA_NOTES.md

repomix-output.xml
repomix-output.xml
5 changes: 4 additions & 1 deletion .repomixignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ dist/
repomix-output.xml
bun.lock
package-lock.jsonc
LICENCE
LICENSE
scripts/
tests/
README.md
211 changes: 100 additions & 111 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,22 @@ Using `@latest` ensures you always get the newest version automatically when Ope

Restart OpenCode. The plugin will automatically start optimizing your sessions.

## Beta Notice (v2.2.0-beta0)

- Strategy shift to a single user-facing context tool: `compress`.
- Context management is now less surgical and more focused on preserving high-signal work grouped by task.

## How Pruning Works

DCP uses multiple tools and strategies to reduce context size:
DCP uses one user-facing tool and strategies to reduce context size:

### Tools
For model-facing behavior (prompts and tool calls), this capability is always addressed as `compress`.

**Distill** — Exposes a `distill` tool that the AI can call to distill valuable context into concise summaries before removing the tool content.
### Tool

**Compress** — Exposes a `compress` tool that the AI can call to collapse a large section of conversation (messages and tools) into a single summary.
**Compress** — Exposes a single `compress` tool with one method: select a conversation range using injected `startId` and `endId` (`mNNNN` or `bN`), then replace it with a technical summary.

**Prune** — Exposes a `prune` tool that the AI can call to remove completed or noisy tool content from context.
The model can use that same method at different scales: tiny ranges for noise cleanup, focused ranges for preserving key findings, and full chapters for completed work.

### Strategies

Expand Down Expand Up @@ -69,108 +74,93 @@ DCP uses its own config file:
- Custom config directory: `$OPENCODE_CONFIG_DIR/dcp.jsonc` (or `dcp.json`), if `OPENCODE_CONFIG_DIR` is set
- Project: `.opencode/dcp.jsonc` (or `dcp.json`) in your project's `.opencode` directory

> <details>
> <summary><strong>Default Configuration</strong> (click to expand)</summary>
>
> ```jsonc
> {
> "$schema": "https://raw.githubusercontent.com/Opencode-DCP/opencode-dynamic-context-pruning/master/dcp.schema.json",
> // Enable or disable the plugin
> "enabled": true,
> // Enable debug logging to ~/.config/opencode/logs/dcp/
> "debug": false,
> // Notification display: "off", "minimal", or "detailed"
> "pruneNotification": "detailed",
> // Notification type: "chat" (in-conversation) or "toast" (system toast)
> "pruneNotificationType": "chat",
> // Slash commands configuration
> "commands": {
> "enabled": true,
> // Additional tools to protect from pruning via commands (e.g., /dcp sweep)
> "protectedTools": [],
> },
> // Manual mode: disables autonomous context management,
> // tools only run when explicitly triggered via /dcp commands
> "manualMode": {
> "enabled": false,
> // When true, automatic strategies (deduplication, supersedeWrites, purgeErrors)
> // still run even in manual mode
> "automaticStrategies": true,
> },
> // Protect from pruning for <turns> message turns past tool invocation
> "turnProtection": {
> "enabled": false,
> "turns": 4,
> },
> // Protect file operations from pruning via glob patterns
> // Patterns match tool parameters.filePath (e.g. read/write/edit)
> "protectedFilePatterns": [],
> // LLM-driven context pruning tools
> "tools": {
> // Shared settings for all prune tools
> "settings": {
> // Nudge the LLM to use prune tools (every <nudgeFrequency> tool results)
> "nudgeEnabled": true,
> "nudgeFrequency": 10,
> // Token limit at which the model compresses session context
> // to keep the model in the "smart zone" (not a hard limit)
> // Accepts: number or "X%" (percentage of model's context window)
> "contextLimit": 100000,
> // Optional per-model overrides by exact providerID/modelID
> // Accepts: number or "X%"
> // Example:
> // "modelLimits": {
> // "openai/gpt-5": 120000,
> // "anthropic/claude-3-7-sonnet": "80%"
> // },
> // Additional tools to protect from pruning
> "protectedTools": [],
> },
> // Distills key findings into preserved knowledge before removing raw content
> "distill": {
> // Permission mode: "allow" (no prompt), "ask" (prompt), "deny" (tool not registered)
> "permission": "allow",
> // Show distillation content as an ignored message notification
> "showDistillation": false,
> },
> // Collapses a range of conversation content into a single summary
> "compress": {
> // Permission mode: "deny" (tool not registered), "ask" (prompt), "allow" (no prompt)
> "permission": "deny",
> // Show summary content as an ignored message notification
> "showCompression": false,
> },
> // Removes tool content from context without preservation (for completed tasks or noise)
> "prune": {
> // Permission mode: "allow" (no prompt), "ask" (prompt), "deny" (tool not registered)
> "permission": "allow",
> },
> },
> // Automatic pruning strategies
> "strategies": {
> // Remove duplicate tool calls (same tool with same arguments)
> "deduplication": {
> "enabled": true,
> // Additional tools to protect from pruning
> "protectedTools": [],
> },
> // Prune write tool inputs when the file has been subsequently read
> "supersedeWrites": {
> "enabled": true,
> },
> // Prune tool inputs for errored tools after X turns
> "purgeErrors": {
> "enabled": true,
> // Number of turns before errored tool inputs are pruned
> "turns": 4,
> // Additional tools to protect from pruning
> "protectedTools": [],
> },
> },
> }
> ```
>
> </details>
> [!IMPORTANT]
> Defaults are applied automatically. Expand this if you want to review or override settings.

<details>
<summary><strong>Default Configuration</strong> (click to expand)</summary>

```jsonc
{
"$schema": "https://raw.githubusercontent.com/Opencode-DCP/opencode-dynamic-context-pruning/master/dcp.schema.json",
// Enable or disable the plugin
"enabled": true,
// Enable debug logging to ~/.config/opencode/logs/dcp/
"debug": false,
// Notification display: "off", "minimal", or "detailed"
"pruneNotification": "detailed",
// Notification type: "chat" (in-conversation) or "toast" (system toast)
"pruneNotificationType": "chat",
// Slash commands configuration
"commands": {
"enabled": true,
// Additional tools to protect from pruning via commands (e.g., /dcp sweep)
"protectedTools": [],
},
// Manual mode: disables autonomous context management,
// tools only run when explicitly triggered via /dcp commands
"manualMode": {
"enabled": false,
// When true, automatic strategies (deduplication, supersedeWrites, purgeErrors)
// still run even in manual mode
"automaticStrategies": true,
},
// Protect from pruning for <turns> message turns past tool invocation
"turnProtection": {
"enabled": false,
"turns": 4,
},
// Protect file operations from pruning via glob patterns
// Patterns match tool parameters.filePath (e.g. read/write/edit)
"protectedFilePatterns": [],
// Unified context compression tool and behavior settings
"compress": {
// Permission mode: "allow" (no prompt), "ask" (prompt), "deny" (tool not registered)
"permission": "allow",
// Show summary content in a chat notification
"showCompression": false,
// Token limit at which the model compresses session context
// to keep the model in the "smart zone" (not a hard limit)
// Accepts: number or "X%" (percentage of model's context window)
"contextLimit": 100000,
// Optional per-model overrides by exact providerID/modelID
// Accepts: number or "X%"
// Example:
// "modelLimits": {
// "openai/gpt-5": 120000,
// "anthropic/claude-3-7-sonnet": "80%"
// },
// How often the context-limit nudge fires (1 = every fetch, 5 = every 5th)
"nudgeFrequency": 5,
// Start iteration nudges after this many messages
// have occurred since the last user message
"iterationNudgeThreshold": 15,
},
// Automatic pruning strategies
"strategies": {
// Remove duplicate tool calls (same tool with same arguments)
"deduplication": {
"enabled": true,
// Additional tools to protect from pruning
"protectedTools": [],
},
// Prune write tool inputs when the file has been subsequently read
"supersedeWrites": {
"enabled": true,
},
// Prune tool inputs for errored tools after X turns
"purgeErrors": {
"enabled": true,
// Number of turns before errored tool inputs are pruned
"turns": 4,
// Additional tools to protect from pruning
"protectedTools": [],
},
},
}
```

</details>

### Commands

Expand All @@ -181,16 +171,15 @@ DCP provides a `/dcp` slash command:
- `/dcp stats` — Shows cumulative pruning statistics across all sessions.
- `/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`.
- `/dcp manual [on|off]` — Toggle manual mode or set explicit state. When on, the AI will not autonomously use context management tools.
- `/dcp prune [focus]` — Trigger a single prune tool execution. Optional focus text directs the AI's pruning decisions.
- `/dcp distill [focus]` — Trigger a single distill tool execution. Optional focus text directs what to distill.

- `/dcp compress [focus]` — Trigger a single compress tool execution. Optional focus text directs what range to compress.

### Protected Tools

By default, these tools are always protected from pruning:
`task`, `todowrite`, `todoread`, `distill`, `compress`, `prune`, `batch`, `plan_enter`, `plan_exit`
`task`, `todowrite`, `todoread`, `compress`, `batch`, `plan_enter`, `plan_exit`

The `protectedTools` arrays in each section add to this default list.
The `protectedTools` arrays in `commands` and `strategies` add to this default list.

### Config Precedence

Expand Down
Binary file added assets/images/3.0 release.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading