@bd7pil/opencode-deep-memory 0.8.7 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,17 +1,8 @@
1
1
  # opencode-deep-memory
2
2
 
3
- > Persistent memory, checkpoint resilience, and deterministic context compression for [OpenCode](https://github.com/anomalyco/opencode) — zero runtime dependencies.
3
+ > Persistent cross-session memory for [OpenCode](https://github.com/anomalyco/opencode) — zero runtime dependencies.
4
4
 
5
- ## What it does
6
-
7
- OpenCode sessions are stateless. Every restart is a cold start. Native compaction
8
- destroys conversation content. **deep-memory** adds three layers:
9
-
10
- | Layer | What survives | How |
11
- |-------|--------------|-----|
12
- | **Remember** | Decisions, constraints, gotchas | `memory_search` / `memory_store` — BM25 + CJK search across sessions |
13
- | **Recover** | Full conversation context | Checkpoint captures before compaction; resume injection on new session |
14
- | **Compress** | Token budget | Deterministic stripping + pressure-triggered deep compression — no LLM calls |
5
+ V4 architecture. Built on research from 7 production coding agents, 30+ memory systems, and 5 academic papers. Eliminates the two independent LLM output degradation paths found in V2: volatile system-prompt injection and post-hoc tool output compression.
15
6
 
16
7
  ## Quick start
17
8
 
@@ -25,211 +16,191 @@ destroys conversation content. **deep-memory** adds three layers:
25
16
  }
26
17
  ```
27
18
 
28
- OpenCode auto-installs on startup. Memory appears at `.deep-memory/` in your project root.
19
+ Memory lives at `.deep-memory/` in your project root.
29
20
 
30
- ## How it works
21
+ ## What it does
31
22
 
32
- ```
33
- ┌─────────────────────────────────────────────────────────────────┐
34
- │ messages.transform (every turn)
35
- │ ├─ Strip reasoning/thinking parts (physical removal) │
36
- │ ├─ Remove system-injected messages (physical removal) │
37
- │ ├─ Truncate old tool errors │
38
- │ └─ Deep compress: dedup / tool output / JSON / assistant text │
39
- └─────────────────────────────────────────────────────────────────┘
40
-
41
- ┌─────────────────────────────────────────────────────────────────┐
42
- │ system.transform (every turn) │
43
- │ ├─ Inject stable: MEMORY.md constraints + tool hint (cache hit)│
44
- │ └─ Inject volatile: BM25 search results + repo map symbols │
45
- └─────────────────────────────────────────────────────────────────┘
46
-
47
- ┌─────────────────────────────────────────────────────────────────┐
48
- │ compacting (before OpenCode destroys messages) │
49
- │ ├─ Capture raw messages → checkpoint.raw.json │
50
- │ ├─ Extract knowledge → checkpoint.md │
51
- │ └─ Inject structured handoff prompt for LLM │
52
- └─────────────────────────────────────────────────────────────────┘
53
-
54
- ┌─────────────────────────────────────────────────────────────────┐
55
- │ events │
56
- │ ├─ session.created → resume + dream schedule │
57
- │ ├─ session.idle → enrichment │
58
- │ └─ session.compacted → pressure calibration │
59
- └─────────────────────────────────────────────────────────────────┘
60
- ```
23
+ | Capability | How |
24
+ |---|---|
25
+ | **Remember** decisions, constraints, gotchas, facts | `memory_store` → BM25-indexed `MEMORY.md` (200 line cap) |
26
+ | **Retrieve** across sessions | `memory_search` — BM25 + CJK bigram |
27
+ | **Forget** stale entries | `memory_forget` — by query + confirmation |
28
+ | **Recover** compressed content | `deep_expand` / `memory_expand` — SHA-256 CCR, 30min cache |
29
+ | **Compress** on demand | `context_compress` agent-initiated, originals recoverable |
30
+ | **Deduplicate** on compaction | SIMHash dedup of MEMORY.md (synchronous, no LLM) |
61
31
 
62
- ## Context compression
32
+ ## 6-Layer architecture
63
33
 
64
- Three layers, fully automatic, no LLM calls.
34
+ All six layers are backed by production evidence — not theory.
65
35
 
66
- ### Layer 1: Deterministic stripping (always active)
36
+ ### Layer 1: Capture-time tool output limiting
67
37
 
68
- | Target | Action |
69
- |--------|--------|
70
- | Old reasoning/thinking parts | Physical removal |
71
- | System injections (`<system-reminder>`, etc.) | Physical removal |
72
- | Tool errors >100 chars (older than 4 turns) | Truncate |
73
- | Inline `<thinking>` tags | Regex strip |
38
+ Tool outputs are capped once at capture time, not post-hoc mid-conversation.
74
39
 
75
- No marker pollution old content is physically removed, not replaced with `[cleared]` or `[stripped]`. This prevents [context confusion](https://www.philschmid.de/context-engineering-part-2).
40
+ | Tool | Default cap | Strategy |
41
+ |---|---|---|
42
+ | `bash` | 48K chars | Head + error lines + tail 200 + recovery hint |
43
+ | `read` | 50K chars | Head + tail + key lines + re-read hint |
44
+ | `grep`/`search` | 20 files × 5 matches | Group by file, top matches |
45
+ | `task`/`background_output` | 30K chars | Headers + code fences + key lines |
46
+ | `webfetch` | 20K chars | Head + headings + tail |
76
47
 
77
- ### Layer 2: Deep compression (pressure-triggered)
48
+ Recovery hint tells the LLM how to get more detail (re-read with offset, grep with pattern), not a dead-end marker.
78
49
 
79
- | Pressure | Threshold | Actions |
80
- |----------|-----------|---------|
81
- | **always** | every turn | tool dedup + error purge + tool output compress + JSON crush + assistant text compress |
82
- | **medium** | ≥ 50K tokens | + memory nudge (prompts LLM to use `memory_store`) |
83
- | **high** | ≥ 150K tokens | + pressure nudge (prompts LLM to summarize old tasks) |
50
+ **Evidence**: Cline source (`output-limits.ts`: bash 48K, read 50K). Aider and Cody: no post-hoc compression at all.
84
51
 
85
- Thresholds are absolute, not percentage-based — they work consistently across 200K and 1M+ context windows. Based on [Focus Agent](https://arxiv.org/html/2601.07190v1) research.
52
+ ### Layer 2: Stale-read rewriting
86
53
 
87
- | Target | Strategy | Source |
88
- |--------|----------|--------|
89
- | Duplicate tool calls | Signature matching | [DCP][] |
90
- | Old error inputs | Purge after 4 turns | [DCP][] |
91
- | File reads | Keep head + key lines + tail | [Edgee][] |
92
- | Command outputs | Keep errors + tail | [Edgee][] |
93
- | Search results | Keep top-20, group by file | [Edgee][] |
94
- | JSON arrays | Head + dedup middle + tail | [Headroom][] |
95
- | Subagent output | Headers + key lines + tail with [ccr:] preservation | [Claude Code][] |
96
- | Skill output | Frontmatter + MUST rules + structure headers | [Claude Code][] |
97
- | Nested JSON objects | Compress child arrays >30 items | This project |
98
- | Old assistant text | Preserve structure, compress prose | [LLMLingua][] |
54
+ When the same tool is called multiple times with identical input+output, older copies are marked `[OUTDATED — superseded by newer identical call]`. The LLM sees a useful signal instead of a meaningless placeholder that it may mimic in output.
99
55
 
100
- All compressed content is **reversible** via CCR (Compress-Cache-Retrieve) originals cached for 30 minutes with SHA-256 hash, retrievable via `deep_expand` tool.
56
+ **Replaces**: `[superseded by duplicate call]` placeholder (V2) and `[context-stripped]` orphan repair both known to cause the LLM to produce placeholder-style output.
101
57
 
102
- **No compression** on protected tools: `question`, `edit`, `write`, `todowrite`, `memory_*`, `deep_expand`, `task`, `skill`. These tools' outputs contain verification data (LSP diagnostics, subagent decisions) essential for the agent to function correctly.
58
+ ### Layer 3: Static memory file (byte-stable system prompt)
103
59
 
104
- **Post-compression re-read**: after compression modifies content, recent modified files are listed in a `<dm-nudge>` so the agent can re-verify if needed inspired by Claude Code's `onCompact` callback.
60
+ The system prompt is frozen across turns TOOL_HINT + MEMORY.md content are injected once and only change when `memory_store` writes to MEMORY.md (mtime cache). No volatile BM25 results, no per-turn search, no repomap in the system prompt.
105
61
 
106
- ## Memory nudge
62
+ ```
63
+ Position 0 (frozen): TOOL_HINT — ~150 tokens, byte-identical every turn
64
+ Position 0 (cached): MEMORY.md — up to 200 lines / 25KB, cached by mtime
65
+ ```
107
66
 
108
- Detects decisions, constraints, and fixes in conversation nudges the LLM to persist them.
67
+ When MEMORY.md hasn't changed: 100% byte-stable system prompt across turns.
109
68
 
110
- | Pattern | Example | Nudge |
111
- |---------|---------|-------|
112
- | Decision | "我决定用 PostgreSQL" / "I'll use PostgreSQL" | `memory_store(type="decision")` |
113
- | Constraint | "不能用 eval()" / "must not use eval()" | `memory_store(type="constraint")` |
114
- | Error fix | "修复了权限问题" / "fixed the permission error" | `memory_store(type="gotcha")` |
69
+ **Key difference from V2**: V2 injected BM25 search results (560–2720 tokens) into `system[1]` every turn, changing content per-turn. This violated the consensus that system prompts should be byte-stable (Cognee, Aider, Copilot all inject dynamic content in user message, not system prompt). Context Rot research (Chroma 2025) confirmed all 18 tested models degrade with per-turn mutation.
115
70
 
116
- English + Chinese. Pressure nudge and memory nudge have independent cooldowns.
71
+ ### Layer 4: Hybrid retrieval (one-time auto-search)
117
72
 
118
- ## Tools
73
+ Pure pull-based retrieval doesn't work reliably — When2Tool (arxiv 2605.09252) shows LLMs know when to retrieve (hidden-state AUROC 0.89) but fail to act during generation. V4 uses a hybrid:
119
74
 
120
- | Tool | Purpose |
121
- |------|---------|
122
- | `memory_search` | Search persistent memory (BM25 + CJK bigram) |
123
- | `memory_store` | Store decisions, constraints, gotchas, facts, notes |
124
- | `memory_forget` | Remove stale memory entries |
125
- | `memory_expand` | Retrieve original content of a compressed message |
126
- | `deep_expand` | Retrieve original content via CCR hash |
75
+ - **First turn only**: quiet `memory_search(userQuery)` runs. If top-1 BM25 score ≥ 2.0, a ≤30-token whisper is appended: `[memory hint: N relevant entries ...]`
76
+ - **Turns 2+**: system prompt is byte-stable. Zero whisper overhead.
77
+ - **On demand**: `memory_search` tool is always available.
127
78
 
128
- ## Compaction
79
+ ### Layer 5: Synchronous consolidation (no background)
129
80
 
130
- When OpenCode compacts a session:
81
+ V2's dream/distill used `client.session.promptAsync` fire-and-forget — it never worked because the main process doesn't persist for 7-day cycles. V4 consolidation is strictly synchronous, runs inside hooks:
131
82
 
132
- 1. **Capture** raw messages to `checkpoint.raw.json`
133
- 2. **Extract** knowledge via 5 heuristic extractors
134
- 3. **Write** structured `checkpoint.md`
135
- 4. **Inject** Hermes-8 structured prompt + Codex-style handoff prefix
83
+ | Trigger | Action | Duration |
84
+ |---|---|---|
85
+ | `session.compacting` hook | SIMHash dedup of MEMORY.md (≥0.92 similarity threshold) | <100ms |
86
+ | `/checkpoint` command | Manual memory capture + dedup | <200ms |
87
+ | `memory_store` after 200 lines | Overflow to MEMORY-archive.md | <10ms |
136
88
 
137
- The LLM produces: Task Overview Progress Key Decisions Constraints → Files Modified → Errors → Next Steps → Critical Context
89
+ No `promptAsync`, no `setInterval`, no child sessions, no LLM calls in consolidation.
138
90
 
139
- ## Memory consolidation
91
+ ### Layer 6: Agent-initiated compression
140
92
 
141
- | Cycle | Trigger | Action |
142
- |-------|---------|--------|
143
- | **Auto-dream** | 7 days or notes.md >20 lines | Consolidate notes + checkpoints → MEMORY.md |
144
- | **Auto-distill** | 30 days | Package recurring workflows → skill candidates |
145
- | **Enrichment** | Session idle after compaction | LLM enriches checkpoint with cross-references |
93
+ When the LLM feels context is bloated, it calls `context_compress(keep_recent=8)`. This sets a flag consumed by the next `messages.transform`, which replaces old tool outputs with head/tail summaries. Originals stored in CCR — `deep_expand` retrieves them.
146
94
 
147
- New projects: MEMORY.md auto-bootstraps from notes.md. Both agents have `memory_forget` enabled.
95
+ CCR markers are actionable: `[compressed call deep_expand("hash") to restore original]` instead of V2's dead-end `[ccr:hash]`.
148
96
 
149
- ## Configuration
97
+ ## Tools
150
98
 
151
- | Variable | Default | Purpose |
152
- |----------|---------|---------|
153
- | `DEEP_MEMORY_DEBUG` | off | `1` = debug log, `trace` = +hook I/O |
154
- | `DEEP_MEMORY_PROJECT_SUBDIR` | `.deep-memory` | Memory directory name |
155
- | `DEEP_MEMORY_GLOBAL_ROOT` | `~/.local/share/opencode/deep-memory` | Cross-project memory |
99
+ | Tool | Purpose |
100
+ |---|---|
101
+ | `memory_search` | BM25 + CJK bigram search across project and global memory |
102
+ | `memory_store` | Store one entry (decision/constraint/gotcha/fact/note) |
103
+ | `memory_forget` | Find matching entries and remove them |
104
+ | `memory_expand` | Restore original content from compressed conversation messages |
105
+ | `deep_expand` | Restore original content from CCR-compressed tool output |
106
+ | `context_compress` | Request compression of old tool outputs on next turn |
107
+
108
+ ## Commands
109
+
110
+ - `/checkpoint` — capture session state + consolidate MEMORY.md (SIMHash dedup)
111
+
112
+ ## Compaction
113
+
114
+ When OpenCode compacts a session:
115
+ 1. Capture raw messages to `checkpoint.md` via 5 heuristic extractors
116
+ 2. Deduplicate MEMORY.md via SIMHash (acquired via file lock, zero race conditions)
117
+ 3. Inject structured handoff prompt for LLM
118
+
119
+ No background LLM sessions, no `client.session.promptAsync`, no dream/distill.
156
120
 
157
121
  ## Storage
158
122
 
159
123
  ```
160
124
  <project>/.deep-memory/
161
- ├── MEMORY.md persistent decisions/constraints/gotchas
162
- ├── notes.md keyword captures
163
- ├── checkpoint.md last compaction extraction
164
- ├── checkpoint.raw.json raw messages dump
165
- ├── .schedule.json dream/distill state
166
- ├── .compaction-log.jsonl compaction audit trail
167
- └── sessions/<sid>/ per-session archive
125
+ ├── MEMORY.md persistent memory (200 line cap, user curated)
126
+ ├── MEMORY-archive.md overflow when cap is reached
127
+ ├── checkpoint.md last compaction extraction
128
+ ├── .compaction-log.jsonl compaction audit trail
129
+ └── .index-state.json BM25 index mtime tracker
168
130
  ```
169
131
 
170
- ## Commands
132
+ ## Configuration
171
133
 
172
- - `/checkpoint` manually capture session state
173
- - `/dream` — consolidate notes into persistent memory
174
- - `/distill` package recurring workflows into skills
134
+ | Variable | Default | Purpose |
135
+ |---|---|---|
136
+ | `DEEP_MEMORY_DEBUG` | off | `1` = debug log, `trace` = +hook I/O |
137
+ | `DEEP_MEMORY_PROJECT_SUBDIR` | `.deep-memory` | Memory directory name |
138
+ | `DEEP_MEMORY_GLOBAL_ROOT` | `~/.local/share/opencode/deep-memory` | Cross-project memory |
175
139
 
176
140
  ## Development
177
141
 
178
142
  ```bash
179
143
  npm install
180
- npm run verify # typecheck + test (363) + build + smoke (49)
144
+ npm run verify # typecheck + test + build + smoke
181
145
  ```
182
146
 
183
- ## Acknowledgments
184
-
185
- **[DCP][]** Dynamic Context Pruning for OpenCode. Tool dedup, error purge, and nudge system.
186
-
187
- **[Headroom][]** JSON array crush and CCR (Compress-Cache-Retrieve).
188
-
189
- **[Edgee][]** Per-tool compression strategies (read, bash, grep, glob).
190
-
191
- **[Contextomizer][]** Content type detection pipeline.
192
-
193
- **[Focus Agent][]** Absolute token thresholds and assistant text compression research.
194
-
195
- **[LLMLingua][]** — Selective compression: preserve structure, compress prose.
196
-
197
- **[Codex CLI][]** — Handoff prefix pattern for compaction continuity.
198
-
199
- **[Google ADK][]** — Append-only event compaction architecture.
200
-
201
- **[Hermes][]** — 8-section structured compaction prompt design.
202
-
203
- **[MiMo-Code][]** — Terminal-native AI coding assistant with persistent memory.
204
-
205
- **[Magic Context][]** Unbounded context for coding agents.
206
-
207
- **[Aider][]** AI pair programming in your terminal.
208
-
209
- **[Roo Code][]** A whole dev team of AI agents in your code editor.
210
-
211
- **[Continue][]** — Pioneering open-source coding agent.
212
-
213
- **[OpenHands][]** — Code Less, Make More.
214
-
215
- **[Plandex][]** — AI coding agent for large tasks and real world projects.
216
-
217
- [DCP]: https://github.com/Opencode-DCP/opencode-dynamic-context-pruning
218
- [Headroom]: https://github.com/chopratejas/headroom
219
- [Edgee]: https://github.com/edgee-ai/edgee
220
- [Contextomizer]: https://github.com/GandalFran/contextomizer
221
- [Focus Agent]: https://arxiv.org/html/2601.07190v1
222
- [LLMLingua]: https://github.com/microsoft/LLMLingua
223
- [Codex CLI]: https://github.com/openai/codex
224
- [Google ADK]: https://github.com/google/adk-python
225
- [Hermes]: https://github.com/NousResearch/hermes-agent
226
- [MiMo-Code]: https://github.com/XiaomiMiMo/MiMo-Code
227
- [Magic Context]: https://github.com/cortexkit/magic-context
228
- [Aider]: https://github.com/Aider-AI/aider
229
- [Roo Code]: https://github.com/RooCodeInc/Roo-Code
230
- [Continue]: https://github.com/continuedev/continue
231
- [OpenHands]: https://github.com/All-Hands-AI/OpenHands
232
- [Plandex]: https://github.com/plandex-ai/plandex
147
+ ## What V4 removed (and why)
148
+
149
+ | Feature | Failure mode | Replacement |
150
+ |---|---|---|
151
+ | Volatile BM25 injection in system prompt | Per-turn mutation degrades quality (Context Rot, 18 models) | Frozen TOOL_HINT + mtime-cached MEMORY.md |
152
+ | Dream/distill auto-generation | `promptAsync` fire-and-forget never worked (3 independent failure layers) | User-curated MEMORY.md + sync consolidation |
153
+ | Post-hoc tool output compression | Middle content lost mid-conversation | Capture-time caps (Cline pattern) |
154
+ | `[superseded by duplicate call]` | LLM mimics placeholder in output | `[OUTDATED]` signal |
155
+ | `[context-stripped]` orphan repair | Same | Removed entirely |
156
+ | `[ccr:<hash>]` dead-end markers | Stored but unretrievable | Actionable hint + working deep_expand |
157
+ | Memory nudge / pressure nudge XML | Contradicts pull-based model | Agent-initiated `context_compress` |
158
+ | Tier-based memory rendering (P1-P5) | Unnecessary complexity | Full MEMORY.md injected verbatim |
159
+
160
+ ## Evidence base
161
+
162
+ V4 was designed through 3 rounds of research against production systems and academic literature.
163
+
164
+ ### Production coding agents (7)
165
+
166
+ | Agent | Key insight borrowed |
167
+ |---|---|
168
+ | **Claude Code** | CLAUDE.md verbatim injection, user-curated, never auto-generated; 200-line/25KB hard cap |
169
+ | **Cline** | Capture-time tool output caps (bash 48K, read 50K); stale-read rewriting; 90% compaction trigger |
170
+ | **Aider** | No post-hoc tool compression; background recursive summarization |
171
+ | **Cursor** | Same-model self-summarization preserves quality |
172
+ | **Cody** | No compression at all — pure retrieval |
173
+ | **Copilot** | 4 cache-control breakpoints 94% cache hit rate |
174
+ | **Continue** | Context-aware truncation direction |
175
+
176
+ ### Memory systems surveyed (30+)
177
+
178
+ - **Mem0** — pull-based search, no auto-injection
179
+ - **Letta** — fixed-size memory blocks, agent-managed content mutation
180
+ - **Magic Context** — cache-stable deferred mutation; zero per-turn change
181
+ - **A-Mem** — proactive dedup/update prevents stale context accumulation
182
+ - **Cognee** — injects memory in user message, not system prompt (keeps prefix stable)
183
+ - **DCP** — LLM-initiated compress tool (model decides what to compress)
184
+ - **Headroom** — CCR store with lossless recovery
185
+ - **LLMLingua** — token-level perplexity compression (avoided: too aggressive for code)
186
+ - **Focus Agent** — agent-initiated `consolidate_learning` + persistent Knowledge block
187
+ - **Edgee** — protected-content patterns
188
+
189
+ ### Academic papers
190
+
191
+ - [Lost in the Middle](https://arxiv.org/abs/2307.03172) — 20%+ accuracy drop for mid-prompt content (Liu et al., TACL 2024)
192
+ - [Context Rot](https://www.trychroma.com/research/context-rot) — all 18 tested models degrade with prompt length (Chroma 2025)
193
+ - [When2Tool](https://arxiv.org/abs/2605.09252) — LLMs know when to retrieve (AUROC 0.89-0.96) but fail to act; pure pull not viable (arxiv 2605.09252)
194
+ - [Self-RAG](https://arxiv.org/abs/2310.11511) — adaptive retrieval requires fine-tuning (arxiv 2310.11511)
195
+ - [Focus Agent](https://arxiv.org/html/2601.07190v1) — 22.7% token reduction, no accuracy loss (arxiv 2601.07190)
196
+
197
+ ### Design decisions (stored in project memory)
198
+
199
+ - [V4 prohibits background/fire-and-forget patterns — dream/distill failure post-mortem]
200
+ - [6-layer architecture — all layers have production evidence]
201
+ - [D1: MEMORY.md 200 lines / 25KB — Claude Code source-enforced]
202
+ - [D3: capture-time caps, Cline defaults, configurable]
203
+ - [D5: MEMORY.md in system.transform with mtime caching — SDK constraint: messages.transform has no sessionID]
233
204
 
234
205
  ## License
235
206
 
@@ -0,0 +1,12 @@
1
+ /* opencode-deep-memory — zero runtime dependencies */
2
+ import {
3
+ ccrInjectMarker,
4
+ ccrRetrieve,
5
+ ccrStore
6
+ } from "./chunk-FUQATBWM.js";
7
+ export {
8
+ ccrInjectMarker,
9
+ ccrRetrieve,
10
+ ccrStore
11
+ };
12
+ //# sourceMappingURL=ccr-REOCHH53.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,43 @@
1
+ /* opencode-deep-memory — zero runtime dependencies */
2
+ var __defProp = Object.defineProperty;
3
+ var __export = (target, all) => {
4
+ for (var name in all)
5
+ __defProp(target, name, { get: all[name], enumerable: true });
6
+ };
7
+
8
+ // src/compress/ccr.ts
9
+ import { createHash } from "crypto";
10
+ var CCR_TTL_MS = 30 * 60 * 1e3;
11
+ function ccrStore(state, original, compressed, toolName, callID) {
12
+ const hash = sha256(original).slice(0, 24);
13
+ state.ccStore(hash, {
14
+ hash,
15
+ original,
16
+ compressed,
17
+ createdAt: Date.now(),
18
+ toolName,
19
+ callID
20
+ });
21
+ return hash;
22
+ }
23
+ function ccrRetrieve(state, hash) {
24
+ const entry = state.ccrGet(hash);
25
+ if (!entry) return void 0;
26
+ if (Date.now() - entry.createdAt > CCR_TTL_MS) return void 0;
27
+ return entry.original;
28
+ }
29
+ function ccrInjectMarker(compressed, hash) {
30
+ return `${compressed}
31
+ [compressed \u2014 call deep_expand("${hash}") to restore original]`;
32
+ }
33
+ function sha256(data) {
34
+ return createHash("sha256").update(data).digest("hex");
35
+ }
36
+
37
+ export {
38
+ __export,
39
+ ccrStore,
40
+ ccrRetrieve,
41
+ ccrInjectMarker
42
+ };
43
+ //# sourceMappingURL=chunk-FUQATBWM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/compress/ccr.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport type { PluginState } from \"../hooks/shared-state.js\";\n\nconst CCR_TTL_MS = 30 * 60 * 1000;\n\nexport function ccrStore(\n state: PluginState,\n original: string,\n compressed: string,\n toolName?: string,\n callID?: string,\n): string {\n const hash = sha256(original).slice(0, 24);\n state.ccStore(hash, {\n hash,\n original,\n compressed,\n createdAt: Date.now(),\n toolName,\n callID,\n });\n return hash;\n}\n\nexport function ccrRetrieve(state: PluginState, hash: string): string | undefined {\n const entry = state.ccrGet(hash);\n if (!entry) return undefined;\n if (Date.now() - entry.createdAt > CCR_TTL_MS) return undefined;\n return entry.original;\n}\n\nexport function ccrInjectMarker(compressed: string, hash: string): string {\n return `${compressed}\\n[compressed — call deep_expand(\"${hash}\") to restore original]`;\n}\n\nfunction sha256(data: string): string {\n return createHash(\"sha256\").update(data).digest(\"hex\");\n}\n"],"mappings":";;;;;;;;AAAA,SAAS,kBAAkB;AAG3B,IAAM,aAAa,KAAK,KAAK;AAEtB,SAAS,SACd,OACA,UACA,YACA,UACA,QACQ;AACR,QAAM,OAAO,OAAO,QAAQ,EAAE,MAAM,GAAG,EAAE;AACzC,QAAM,QAAQ,MAAM;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,KAAK,IAAI;AAAA,IACpB;AAAA,IACA;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAEO,SAAS,YAAY,OAAoB,MAAkC;AAChF,QAAM,QAAQ,MAAM,OAAO,IAAI;AAC/B,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,KAAK,IAAI,IAAI,MAAM,YAAY,WAAY,QAAO;AACtD,SAAO,MAAM;AACf;AAEO,SAAS,gBAAgB,YAAoB,MAAsB;AACxE,SAAO,GAAG,UAAU;AAAA,uCAAqC,IAAI;AAC/D;AAEA,SAAS,OAAO,MAAsB;AACpC,SAAO,WAAW,QAAQ,EAAE,OAAO,IAAI,EAAE,OAAO,KAAK;AACvD;","names":[]}
package/dist/index.d.ts CHANGED
@@ -5,10 +5,9 @@ import { Plugin, PluginModule } from '@opencode-ai/plugin';
5
5
  *
6
6
  * Wires together all hooks and tools:
7
7
  * - chat.params: record sessionID → agent map
8
- * - chat.message: capture keyword-matching user messages to notes.md
9
- * - experimental.chat.system.transform: adaptive memory injection
10
- * - event: session.created resume detection + auto-dream scheduling
11
- * - tool: memory_search / memory_store / memory_forget
8
+ * - experimental.chat.system.transform: V4 frozen TOOL_HINT + mtime-cached MEMORY.md
9
+ * - event: session.compacted pressure calibration + audit log
10
+ * - tool: memory_search / memory_store / memory_forget / memory_expand / context_compress
12
11
  *
13
12
  * Storage: <data>/local-memory/{global,projects/<hash>}/...
14
13
  * See DESIGN.md for full architecture.