# opencode-dcp/opencode-dynamic-context-pruning architecture

> Architecture diagram of the GitHub repository opencode-dcp/opencode-dynamic-context-pruning, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-26). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/opencode-dcp/opencode-dynamic-context-pruning
- Repository: https://github.com/opencode-dcp/opencode-dynamic-context-pruning

## Overview

1. **What this repo is**
   - This is a TypeScript plugin for OpenCode that manages conversation context by pruning, compressing, and summarizing messages before they are sent to the model.
   - The core architectural boundary is between **OpenCode’s session/message stream** and DCP’s **context-management layer**, which rewrites context in a way that preserves session history semantics without deleting the original conversation.

2. **Entry points and plugin wiring**
   - `index.ts` and `tui.tsx` are the main package entry surfaces.
   - `lib/hooks.ts` is the runtime integration point where DCP attaches to OpenCode lifecycle events.
   - `lib/commands/*` registers slash commands and manual controls, while `lib/tui/*` provides the interactive panel shown by `/dcp`.

3. **Context-management pipeline**
   - The main pruning/compression flow lives under `lib/compress/`.
   - `pipeline.ts` orchestrates the overall pass: inspect session state, choose targets, apply strategies, generate summaries, and emit replacements/placeholders.
   - Supporting modules split the work into range selection, message lookup, protected content handling, timing, and state reconstruction.

4. **Two compression modes**
   - The repo supports **range mode** and **message mode**.
   - Range mode compresses contiguous spans of conversation into summaries; message mode compresses individual messages independently.
   - This choice affects the shape of data that flows through the compression pipeline and how placeholders and nested summaries are produced.

5. **Message model and transformation layer**
   - `lib/messages/*` contains the data-shaping logic that understands OpenCode message types, priorities, queries, pruning markers, sync behavior, and injected subagent results.
   - This layer is responsible for turning raw session messages into DCP’s internal compression/pruning representation and back into the form OpenCode can consume.

6. **Automatic pruning strategies**
   - `lib/strategies/` contains non-compression cleanup passes such as **deduplication** and **purge-errors**.
   - These are recalculated on compression-triggering events, so the pruning model is “recompute from session state” rather than incrementally mutating historical data.
   - The readme’s “automatic cleanup” corresponds to this subsystem.

7. **State, persistence, and caching**
   - `lib/state/` tracks plugin runtime state, persistent configuration-derived state, and tool/result caches.
   - This is where DCP remembers prior compression state, active summaries, and any bookkeeping needed across turns or restarts.
   - The plugin appears designed to regenerate derived pruning results from durable state rather than relying only on in-memory history.

8. **Configuration and policy boundaries**
   - `lib/config.ts` loads and merges config from global, custom, and project scopes described in the readme.
   - `dcp.schema.json` defines the configuration schema used for validation and editor support.
   - Policy modules such as `lib/host-permissions.ts`, `lib/compress-permission.ts`, and `lib/auth.ts` gate whether actions are allowed, need approval, or should be hidden entirely.

9. **Prompt generation and override system**
   - `lib/prompts/` holds the system prompt and the specialized prompts used for compression nudges and summaries.
   - Prompt files are treated as first-class behavior inputs: the plugin can emit prompt text to steer the model toward compression at the right time.
   - `lib/prompts/store.ts` plus the prompt override feature in the readme indicate a managed-defaults + user-overrides model.

10. **Nudging and timing**
   - `lib/compress/timing.ts`, `lib/messages/priority.ts`, and the prompt modules work together to decide when the model should be reminded to compress.
   - This is how DCP implements soft context thresholds, iteration-based nudges, and turn-based reminders rather than relying only on hard context limits.
   - The result is proactive behavior: the model is encouraged to compress before the session becomes too large.

11. **User interface and observability**
   - `lib/tui/` implements the DCP panel: context view, stats, dialogs, and manual-mode controls.
   - `lib/ui/notification.ts` and `lib/logger.ts` handle user-facing feedback and debug output.
   - The UI is a control/visibility layer only; the actual pruning decisions still come from the compression and strategy subsystems.

12. **Utilities, update path, and external behavior**
   - `lib/update.ts` supports auto-update behavior mentioned in the config.
   - `lib/token-utils.ts` and related utilities support token counting and context-limit calculations.
   - The `scripts/` directory provides operational tooling for inspecting sessions, token usage, and cached DCP state, which is useful for debugging and validating the pruning behavior.

13. **Tests as architecture clues**
   - The `tests/` suite covers compression behavior, placeholder behavior, permissions, prompt generation, message IDs, token counting, and update logic.
   - This strongly suggests the repo’s critical correctness boundary is deterministic transformation of session data, not network I/O or persistent server state.

14. **Overall data flow**
   - OpenCode emits session events and tool calls.
   - DCP hooks inspect those events, apply permissions and config, then run strategies and/or compression.
   - The result is a rewritten context package with placeholders, summaries, and protected content preserved, plus optional notifications and TUI updates.
   - The original session remains intact; DCP only changes what gets forwarded to the model.

15. **Main architectural boundary to diagram**
   - The key box to draw is a middleware-like plugin layer sitting between **OpenCode session history** and **LLM request context**.
   - Around that core are three supporting rings: **policy/config**, **prompt/UI**, and **state/strategy** subsystems.

Main entry points: [`lib/compress/pipeline.ts`](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/compress/pipeline.ts) (Pipeline), [`lib/hooks.ts`](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/hooks.ts) (Hooks), [`lib/messages/index.ts`](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/messages/index.ts) (Message model), [`lib/tui/ui.tsx`](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/tui/ui.tsx) (TUI)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_entry["Entry points"]
  node_opencode(("OpenCode<br/>session stream"))
  node_index["index.ts<br/>package entry<br/>[index.ts]"]
  node_tui_entry["tui.tsx<br/>tui entry<br/>[tui.tsx]"]
  node_hooks["Hooks<br/>runtime integration<br/>[hooks.ts]"]
end

subgraph group_core["Context pruning"]
  node_pipeline["Pipeline<br/>compression orchestrator<br/>[pipeline.ts]"]
  node_range_mode["Range mode<br/>contiguous compression<br/>[range.ts]"]
  node_message_mode["Message mode<br/>per-message compression<br/>[message.ts]"]
  node_selectors["Selection<br/>range and search<br/>[search.ts]"]
  node_protected["Protected content<br/>safety filters"]
  node_msgmodel["Message model<br/>message shaping<br/>[index.ts]"]
  node_inject["Injection<br/>subagent results<br/>[inject.ts]"]
  node_prune["Pruning rules<br/>message rules<br/>[prune.ts]"]
  node_strategies["Strategies<br/>cleanup passes<br/>[index.ts]"]
end

subgraph group_policy["Policy and config"]
  node_config["Config<br/>merged settings<br/>[config.ts]"]
  node_permissions["Permissions<br/>policy gates"]
  node_prompts["Prompts<br/>prompt store<br/>[index.ts]"]
end

subgraph group_ui["UI and controls"]
  node_commands["Commands<br/>[index.ts]"]
  node_tui["TUI<br/>interactive panel<br/>[ui.tsx]"]
  node_notify["Notify<br/>feedback<br/>[notification.ts]"]
end

subgraph group_state["State and ops"]
  node_state[("State<br/>[index.ts]")]
  node_token_utils["Token utils<br/>context sizing<br/>[token-utils.ts]"]
  node_update["Update<br/>[update.ts]"]
end

node_opencode -->|"session events"| node_hooks
node_index -->|"wire runtime"| node_hooks
node_tui_entry -->|"mount UI"| node_tui
node_hooks -->|"load policy"| node_config
node_hooks -->|"gate actions"| node_permissions
node_hooks -->|"read/write"| node_state
node_hooks -->|"trigger compression"| node_pipeline
node_pipeline -->|"pick targets"| node_selectors
node_pipeline -->|"preserve content"| node_protected
node_pipeline -->|"range flow"| node_range_mode
node_pipeline -->|"message flow"| node_message_mode
node_pipeline -->|"shape data"| node_msgmodel
node_msgmodel -->|"handle injections"| node_inject
node_msgmodel -->|"normalize markers"| node_prune
node_msgmodel -->|"cleanup passes"| node_strategies
node_strategies -->|"derive state"| node_state
node_config -->|"select text"| node_prompts
node_prompts -->|"nudge model"| node_pipeline
node_token_utils -->|"thresholds"| node_prompts
node_token_utils -->|"size context"| node_pipeline
node_commands -->|"manual control"| node_pipeline
node_commands -->|"open panel"| node_tui
node_tui -->|"inspect state"| node_state
node_tui -->|"surface feedback"| node_notify
node_state -.->|"support ops"| node_update

click node_index "https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/index.ts"
click node_tui_entry "https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/tui.tsx"
click node_hooks "https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/hooks.ts"
click node_pipeline "https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/compress/pipeline.ts"
click node_range_mode "https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/compress/range.ts"
click node_message_mode "https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/compress/message.ts"
click node_selectors "https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/compress/search.ts"
click node_protected "https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/compress/protected-content.ts"
click node_msgmodel "https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/messages/index.ts"
click node_inject "https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/messages/inject/inject.ts"
click node_prune "https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/messages/prune.ts"
click node_strategies "https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/strategies/index.ts"
click node_config "https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/config.ts"
click node_permissions "https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/compress-permission.ts"
click node_prompts "https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/prompts/index.ts"
click node_state "https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/state/index.ts"
click node_token_utils "https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/token-utils.ts"
click node_commands "https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/commands/index.ts"
click node_tui "https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/tui/ui.tsx"
click node_notify "https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/ui/notification.ts"
click node_update "https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/update.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_opencode,node_index,node_tui_entry,node_hooks toneBlue
class node_pipeline,node_range_mode,node_message_mode,node_selectors,node_protected,node_msgmodel,node_inject,node_prune,node_strategies toneAmber
class node_config,node_permissions,node_prompts toneMint
class node_commands,node_tui,node_notify toneRose
class node_state,node_token_utils,node_update toneIndigo
```

## Components

### Entry points

Package surfaces and runtime wiring

- **OpenCode**: session stream · Host session history and model-request context that DCP intercepts
- [index.ts](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/index.ts): package entry · Main package entry surface · `index.ts`
- [tui.tsx](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/tui.tsx): tui entry · Standalone TUI entry surface · `tui.tsx`
- [Hooks](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/hooks.ts): runtime integration · Attaches DCP to OpenCode lifecycle events · `lib/hooks.ts`

### Context pruning

Compression pipeline and message transformation

- [Pipeline](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/compress/pipeline.ts): compression orchestrator · Coordinates inspection, target selection, strategy application, and replacement emission · `lib/compress/pipeline.ts`
- [Range mode](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/compress/range.ts): contiguous compression · Compresses spans of conversation into summaries and placeholders · `lib/compress/range.ts`
- [Message mode](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/compress/message.ts): per-message compression · Compresses individual messages independently · `lib/compress/message.ts`
- [Selection](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/compress/search.ts): range and search · Finds targets, ranges, and message matches for compression · `lib/compress/search.ts`
- [Protected content](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/compress/protected-content.ts): safety filters · Preserves pinned or protected material during rewriting · `lib/compress/protected-content.ts`
- [Message model](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/messages/index.ts): message shaping · Transforms OpenCode messages into DCP compression and pruning structures · `lib/messages/index.ts`
- [Injection](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/messages/inject/inject.ts): subagent results · Handles injected tool and subagent results in the message stream · `lib/messages/inject/inject.ts`
- [Pruning rules](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/messages/prune.ts): message rules · Normalizes priorities, queries, sync markers, and prune markers · `lib/messages/prune.ts`
- [Strategies](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/strategies/index.ts): cleanup passes · Recomputed automatic cleanup such as deduplication and error purging · `lib/strategies/index.ts`

### Policy and config

Configuration, permissions, and prompt inputs

- [Config](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/config.ts): merged settings · Loads and merges global, project, and custom configuration · `lib/config.ts`
- [Permissions](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/compress-permission.ts): policy gates · Decides whether compression and host actions are allowed or hidden · `lib/compress-permission.ts`
- [Prompts](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/prompts/index.ts): prompt store · System prompt, compression nudges, and overrideable prompt text · `lib/prompts/index.ts`

### UI and controls

Interactive panel, commands, and feedback

- [Commands](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/commands/index.ts): slash commands · Registers manual controls for compression, stats, sweep, and help · `lib/commands/index.ts`
- [TUI](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/tui/ui.tsx): interactive panel · DCP panel, dialogs, stats, and manual-mode controls · `lib/tui/ui.tsx`
- [Notify](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/ui/notification.ts): feedback · User-facing notifications and debug logging · `lib/ui/notification.ts`

### State and ops

Persistence, caches, utilities, and update support

- [State](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/state/index.ts): runtime state · Persistent compression state, bookkeeping, and caches · `lib/state/index.ts`
- [Token utils](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/token-utils.ts): context sizing · Token counting and context-limit calculations · `lib/token-utils.ts`
- [Update](https://github.com/opencode-dcp/opencode-dynamic-context-pruning/blob/master/lib/update.ts): auto-update · Supports plugin update behavior and release checks · `lib/update.ts`

## Connections

- OpenCode → Hooks: session events · OpenCode lifecycle events are intercepted by the plugin
- index.ts → Hooks: wire runtime · Main package entry initializes hook integration
- tui.tsx → TUI: mount UI · Standalone TUI entry loads the interactive panel
- Hooks → Config: load policy · Runtime decisions use merged configuration
- Hooks → Permissions: gate actions · Compression and host actions are checked against policy
- Hooks → State: read/write · Plugin state and caches are updated across turns
- Hooks → Pipeline: trigger compression · Compression runs when session events require rewriting
- Pipeline → Selection: pick targets · Pipeline identifies spans or messages to compress
- Pipeline → Protected content: preserve content · Protected content is excluded from destructive rewriting
- Pipeline → Range mode: range flow · Contiguous spans are summarized in range mode
- Pipeline → Message mode: message flow · Independent messages are summarized in message mode
- Pipeline → Message model: shape data · Pipeline converts raw session messages into DCP structures
- Message model → Injection: handle injections · Injected tool and subagent outputs are normalized
- Message model → Pruning rules: normalize markers · Priority, query, sync, and prune metadata are interpreted
- Message model → Strategies: cleanup passes · Message-level cleanup can be recomputed from session state
- Strategies → State: derive state · Cleanup results are recalculated from durable state
- Config → Prompts: select text · Configuration controls prompt defaults and overrides
- Prompts → Pipeline: nudge model · Prompt text steers the model toward timely compression
- Token utils → Prompts: thresholds · Token sizing and context limits inform nudge timing
- Token utils → Pipeline: size context · Compression decisions consider context budget
- Commands → Pipeline: manual control · Slash commands can trigger recompress, decompress, sweep, and stats
- Commands → TUI: open panel · Manual controls are exposed in the interactive UI
- TUI → State: inspect state · Panel renders current compression state and cached results
- TUI → Notify: surface feedback · UI actions produce notifications and logs
- State → Update: support ops · Runtime state includes update-related behavior and bookkeeping
