opencode-working-memory 1.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.
- package/AGENTS.md +340 -0
- package/LICENSE +21 -0
- package/README.md +242 -0
- package/docs/architecture.md +375 -0
- package/docs/configuration.md +376 -0
- package/docs/installation.md +131 -0
- package/index.ts +2080 -0
- package/package.json +40 -0
- package/tsconfig.json +28 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
# AGENTS.md - OpenCode Working Memory Plugin Development Guide
|
|
2
|
+
|
|
3
|
+
## Project Overview
|
|
4
|
+
|
|
5
|
+
The **OpenCode Working Memory Plugin** provides a four-tier memory architecture for AI agents:
|
|
6
|
+
- **Core Memory** - Persistent blocks (goal/progress/context) that survive compaction
|
|
7
|
+
- **Working Memory** - Session-scoped context with slots (error/decision/todo/dependency) and memory pool
|
|
8
|
+
- **Smart Pruning** - Automatic filtering of tool outputs before adding to context
|
|
9
|
+
- **Pressure Monitoring** - Tracks context usage and triggers interventions at thresholds
|
|
10
|
+
|
|
11
|
+
Written in **TypeScript** for the OpenCode agent environment.
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# For development
|
|
17
|
+
git clone https://github.com/sdwolf4103/opencode-working-memory.git
|
|
18
|
+
cd opencode-working-memory
|
|
19
|
+
npm install
|
|
20
|
+
|
|
21
|
+
# For usage (see README.md)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Build & Development Commands
|
|
25
|
+
|
|
26
|
+
### Type Checking
|
|
27
|
+
```bash
|
|
28
|
+
# TypeScript strict mode - fix all type errors before committing
|
|
29
|
+
npx tsc --noEmit
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Testing
|
|
33
|
+
Tests are manually verified through OpenCode sessions:
|
|
34
|
+
```bash
|
|
35
|
+
# 1. Load plugin in OpenCode session
|
|
36
|
+
# 2. Run commands that trigger hooks (e.g., tool execution, compaction)
|
|
37
|
+
# 3. Inspect .opencode/memory-core/ and .opencode/memory-working/
|
|
38
|
+
# 4. Verify memory blocks appear in system prompts
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### File Structure
|
|
42
|
+
```
|
|
43
|
+
opencode-working-memory/
|
|
44
|
+
├── index.ts # Main plugin (1700+ lines)
|
|
45
|
+
├── package.json # Plugin manifest
|
|
46
|
+
├── tsconfig.json # TypeScript config
|
|
47
|
+
├── LICENSE # MIT license
|
|
48
|
+
├── README.md # User documentation
|
|
49
|
+
├── AGENTS.md # This file (developer guide)
|
|
50
|
+
└── docs/ # Detailed documentation
|
|
51
|
+
├── installation.md
|
|
52
|
+
├── architecture.md
|
|
53
|
+
└── configuration.md
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Code Style Guidelines
|
|
57
|
+
|
|
58
|
+
### TypeScript Strict Mode
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
// ✅ REQUIRED: Full type annotations, no implicit any
|
|
62
|
+
async function loadCoreMemory(
|
|
63
|
+
directory: string,
|
|
64
|
+
sessionID: string
|
|
65
|
+
): Promise<CoreMemory | null>
|
|
66
|
+
|
|
67
|
+
// ❌ AVOID: Implicit any types
|
|
68
|
+
async function loadCoreMemory(directory, sessionID) { }
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Type Definitions
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
// ✅ REQUIRED: Define types at module top
|
|
75
|
+
type CoreMemory = {
|
|
76
|
+
sessionID: string;
|
|
77
|
+
blocks: {
|
|
78
|
+
goal: CoreBlock;
|
|
79
|
+
progress: CoreBlock;
|
|
80
|
+
context: CoreBlock;
|
|
81
|
+
};
|
|
82
|
+
updatedAt: string;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// ✅ USE: Union types for variants (not enums)
|
|
86
|
+
type PressureLevel = "safe" | "moderate" | "high" | "critical";
|
|
87
|
+
|
|
88
|
+
// ✅ USE: Record<> for keyed configs
|
|
89
|
+
const SLOT_CONFIG: Record<SlotType, number> = {
|
|
90
|
+
error: 3,
|
|
91
|
+
decision: 5,
|
|
92
|
+
todo: 3,
|
|
93
|
+
dependency: 3,
|
|
94
|
+
};
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Imports & Module Organization
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
// ✅ REQUIRED: Group and order imports
|
|
101
|
+
// 1. Node.js built-ins
|
|
102
|
+
import { existsSync } from "fs";
|
|
103
|
+
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
104
|
+
import { join } from "path";
|
|
105
|
+
|
|
106
|
+
// 2. Third-party (OpenCode SDK)
|
|
107
|
+
import type { Plugin } from "@opencode-ai/plugin";
|
|
108
|
+
import { tool } from "@opencode-ai/plugin";
|
|
109
|
+
|
|
110
|
+
// 3. Local modules (if any)
|
|
111
|
+
// (none currently)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Naming Conventions
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
// ✅ REQUIRED: camelCase for variables & functions
|
|
118
|
+
const maxItems = 50;
|
|
119
|
+
async function loadCoreMemory() { }
|
|
120
|
+
|
|
121
|
+
// ✅ REQUIRED: SCREAMING_SNAKE_CASE for constants
|
|
122
|
+
const CORE_MEMORY_LIMITS = { goal: 1000, progress: 2000, context: 1500 };
|
|
123
|
+
const SLOT_CONFIG = { error: 3, decision: 5, todo: 3, dependency: 3 };
|
|
124
|
+
|
|
125
|
+
// ✅ REQUIRED: PascalCase for types
|
|
126
|
+
type CoreMemory = { ... };
|
|
127
|
+
type WorkingMemoryItem = { ... };
|
|
128
|
+
|
|
129
|
+
// ✅ REQUIRED: get*/set*/load*/save* naming for file operations
|
|
130
|
+
function getCoreMemoryPath(directory: string, sessionID: string): string { }
|
|
131
|
+
async function loadCoreMemory(directory: string, sessionID: string): Promise<CoreMemory | null> { }
|
|
132
|
+
async function saveCoreMemory(directory: string, memory: CoreMemory): Promise<void> { }
|
|
133
|
+
|
|
134
|
+
// ✅ REQUIRED: ensure*/validate* for pre-checks
|
|
135
|
+
async function ensureCoreMemoryDir(directory: string): Promise<void> { }
|
|
136
|
+
|
|
137
|
+
// ✅ REQUIRED: Prefix private/internal functions with _
|
|
138
|
+
function _compressPath(filePath: string): string { }
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Function Signatures & Organization
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
// ✅ REQUIRED: Parameters on separate lines if > 80 chars
|
|
145
|
+
async function loadWorkingMemory(
|
|
146
|
+
directory: string,
|
|
147
|
+
sessionID: string
|
|
148
|
+
): Promise<WorkingMemory | null> {
|
|
149
|
+
// ...
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ✅ REQUIRED: Explicit return types (no inference)
|
|
153
|
+
function getCompactionLogPath(directory: string, sessionID: string): string {
|
|
154
|
+
return join(directory, ".opencode", "memory-working", `${sessionID}_compaction.json`);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// ✅ REQUIRED: Async for file/network I/O
|
|
158
|
+
async function saveCoreMemory(directory: string, memory: CoreMemory): Promise<void> {
|
|
159
|
+
// ...
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Error Handling
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
// ✅ REQUIRED: Try-catch with descriptive console.error
|
|
167
|
+
async function loadCoreMemory(directory: string, sessionID: string): Promise<CoreMemory | null> {
|
|
168
|
+
const path = getCoreMemoryPath(directory, sessionID);
|
|
169
|
+
if (!existsSync(path)) return null;
|
|
170
|
+
|
|
171
|
+
try {
|
|
172
|
+
const content = await readFile(path, "utf-8");
|
|
173
|
+
return JSON.parse(content) as CoreMemory;
|
|
174
|
+
} catch (error) {
|
|
175
|
+
console.error("Failed to load core memory:", error);
|
|
176
|
+
return null; // Graceful degradation
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// ✅ REQUIRED: Type guards for runtime safety
|
|
181
|
+
if (!existsSync(path)) {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// ✅ REQUIRED: Validate JSON before use
|
|
186
|
+
const data = JSON.parse(content);
|
|
187
|
+
const typedData = data as CoreMemory; // Explicit cast after validation
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Comments & Documentation
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
// ✅ REQUIRED: Section headers for major sections
|
|
194
|
+
// ============================================================================
|
|
195
|
+
// Phase 1: Core Memory Foundation
|
|
196
|
+
// ============================================================================
|
|
197
|
+
|
|
198
|
+
// ✅ REQUIRED: Block comments for complex logic
|
|
199
|
+
// Migration: Convert old format (items array) to new format (slots + pool)
|
|
200
|
+
if (data.items && !data.slots) {
|
|
201
|
+
// ... migration logic
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// ✅ USE: Inline comments sparingly
|
|
205
|
+
const gamma = 0.85; // Exponential decay rate (15% per event)
|
|
206
|
+
|
|
207
|
+
// ✅ AVOID: Over-commenting obvious code
|
|
208
|
+
const name = "test"; // Set name to test ❌ (obvious)
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Code Organization
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
// ✅ REQUIRED: Organize plugin file by phase/feature
|
|
215
|
+
// 1. Header & module documentation
|
|
216
|
+
// 2. Imports
|
|
217
|
+
// 3. Types & schemas (grouped by phase)
|
|
218
|
+
// 4. Constants & configs
|
|
219
|
+
// 5. Helper functions (private first, public after)
|
|
220
|
+
// 6. Main plugin export
|
|
221
|
+
// 7. Hook implementations
|
|
222
|
+
|
|
223
|
+
export default {
|
|
224
|
+
// Plugin definition
|
|
225
|
+
} as Plugin;
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Working with OpenCode Plugin SDK
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
// ✅ REQUIRED: Use proper hook signatures
|
|
232
|
+
import { tool, type Plugin } from "@opencode-ai/plugin";
|
|
233
|
+
|
|
234
|
+
export default {
|
|
235
|
+
id: "working-memory",
|
|
236
|
+
name: "Working Memory Plugin",
|
|
237
|
+
|
|
238
|
+
// ✅ Core hooks
|
|
239
|
+
hooks: {
|
|
240
|
+
"tool.execute.after": async (ctx) => {
|
|
241
|
+
// Tool just executed
|
|
242
|
+
},
|
|
243
|
+
"experimental.chat.system.transform": async (ctx) => {
|
|
244
|
+
// Transform system prompt before sending
|
|
245
|
+
},
|
|
246
|
+
"experimental.session.compacting": async (ctx) => {
|
|
247
|
+
// Session is being compacted (clearing old messages)
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
|
|
251
|
+
// ✅ Exposed tools
|
|
252
|
+
tools: [
|
|
253
|
+
tool({
|
|
254
|
+
id: "core_memory_update",
|
|
255
|
+
name: "Update Core Memory",
|
|
256
|
+
description: "Update goal/progress/context blocks",
|
|
257
|
+
// ... schema & execute
|
|
258
|
+
}),
|
|
259
|
+
],
|
|
260
|
+
} as Plugin;
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## Key Implementation Details
|
|
264
|
+
|
|
265
|
+
### Core Memory Files
|
|
266
|
+
- Location: `.opencode/memory-core/<sessionID>.json`
|
|
267
|
+
- Schema: `{ sessionID, blocks: { goal, progress, context }, updatedAt }`
|
|
268
|
+
- Limits: goal (1000 chars), progress (2000 chars), context (1500 chars)
|
|
269
|
+
|
|
270
|
+
### Working Memory Files
|
|
271
|
+
- Location: `.opencode/memory-working/<sessionID>.json`
|
|
272
|
+
- Schema: `{ sessionID, slots, pool, eventCounter, updatedAt }`
|
|
273
|
+
- Slot limits: error (3), decision (5), todo (3), dependency (3)
|
|
274
|
+
- Pool decay: γ=0.85 per event
|
|
275
|
+
|
|
276
|
+
### Pressure Monitoring
|
|
277
|
+
- Triggers at: 70% (safe→moderate), 85% (moderate→high), 95% (high→critical)
|
|
278
|
+
- Files: `.opencode/memory-working/<sessionID>_pressure.json`
|
|
279
|
+
- Intervention: Sends `promptAsync()` with complete visible prompt
|
|
280
|
+
|
|
281
|
+
### Storage Governance (Layer 1 & 2)
|
|
282
|
+
- **Layer 1**: Session deletion cleanup - removes orphaned memory files
|
|
283
|
+
- **Layer 2**: Tool output cache sweep - maintains 300 most recent files, 7-day TTL
|
|
284
|
+
- Triggered at `eventCounter % 500 === 0` (automatic maintenance)
|
|
285
|
+
|
|
286
|
+
## Debugging & Testing
|
|
287
|
+
|
|
288
|
+
### Manual Testing Steps
|
|
289
|
+
1. **Phase 1 (Core Memory)**: Check `.opencode/memory-core/` after `core_memory_update`
|
|
290
|
+
2. **Phase 2 (Smart Pruning)**: Verify tool outputs are filtered before context injection
|
|
291
|
+
3. **Phase 3 (Working Memory)**: Check `.opencode/memory-working/` for slot/pool items
|
|
292
|
+
4. **Phase 4 (Pressure Monitoring)**: Monitor pressure % in system prompts, verify interventions
|
|
293
|
+
5. **Phase 4.5 (Storage Governance)**: Run 500+ events, check sweep logs
|
|
294
|
+
|
|
295
|
+
### Common Issues
|
|
296
|
+
- **File not found**: Ensure `.opencode/` directory exists and is writable
|
|
297
|
+
- **Type errors**: Check all imports use `import type { ... }` for types
|
|
298
|
+
- **Lost memory**: Verify `.opencode/memory-*/` is in `.gitignore` (not committed)
|
|
299
|
+
- **Sweep not running**: Check `eventCounter` in `<sessionID>.json`, should trigger at multiples of 500
|
|
300
|
+
|
|
301
|
+
## Performance Considerations
|
|
302
|
+
|
|
303
|
+
- **Memory budgets**: Core (5.5k chars total), Working (1.6k chars for system prompt)
|
|
304
|
+
- **Pruning**: Hyper-aggressive mode activates at ≥85% pressure
|
|
305
|
+
- **Compaction**: Preserves most recent 10 items when space-constrained
|
|
306
|
+
- **Decay**: Pool items scored by exponential decay (γ=0.85) + mention count
|
|
307
|
+
- **Storage sweep**: Limits cache to 300 files, removes files older than 7 days
|
|
308
|
+
|
|
309
|
+
## File Path References
|
|
310
|
+
|
|
311
|
+
When referencing code locations in documentation/comments, use:
|
|
312
|
+
```
|
|
313
|
+
path/to/file.ts:L123 or path/to/file.ts:Line 123
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
Example: `Function sendPressureInterventionMessage() @ index.ts:L1286`
|
|
317
|
+
|
|
318
|
+
## Contributing
|
|
319
|
+
|
|
320
|
+
1. Fork the repository
|
|
321
|
+
2. Create a feature branch: `git checkout -b feature/my-feature`
|
|
322
|
+
3. Make changes following the code style guidelines above
|
|
323
|
+
4. Test manually in OpenCode session
|
|
324
|
+
5. Commit with descriptive message: `git commit -m "Add feature: ..."`
|
|
325
|
+
6. Push to your fork: `git push origin feature/my-feature`
|
|
326
|
+
7. Open a pull request
|
|
327
|
+
|
|
328
|
+
## Architecture Documentation
|
|
329
|
+
|
|
330
|
+
See `docs/architecture.md` for detailed technical documentation including:
|
|
331
|
+
- Memory tier hierarchy
|
|
332
|
+
- Pruning algorithms
|
|
333
|
+
- Decay formulas
|
|
334
|
+
- Pressure monitoring logic
|
|
335
|
+
- Storage governance policies
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
**Last Updated**: February 2026
|
|
340
|
+
**Plugin Status**: Production (Phases 1-4.5 complete)
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 OpenCode Working Memory Contributors
|
|
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,242 @@
|
|
|
1
|
+
# OpenCode Working Memory Plugin
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/opencode-working-memory)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
|
|
6
|
+
**Advanced four-tier memory architecture that keeps your AI agent sharp, focused, and never forgets what matters.**
|
|
7
|
+
|
|
8
|
+
Stop losing context across compactions. Stop watching your agent repeat the same mistakes. This plugin gives your OpenCode agent a professional-grade memory system that scales with your project complexity.
|
|
9
|
+
|
|
10
|
+
## What You Get
|
|
11
|
+
|
|
12
|
+
- 🧠 **Core Memory** - Persistent goal/progress/context blocks that survive compaction
|
|
13
|
+
- 💡 **Working Memory** - Smart slot-based system (errors, decisions, todos, dependencies)
|
|
14
|
+
- 🎯 **Memory Pressure Monitoring** - Real-time token tracking with automatic interventions
|
|
15
|
+
- 🧹 **Auto Storage Governance** - Prevents unbounded disk growth (300 files/session, 7-day TTL)
|
|
16
|
+
- 📊 **Smart Pruning** - Pressure-aware tool output compression
|
|
17
|
+
- ⚡ **Zero Configuration** - Works out of the box, highly customizable
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
### For Humans
|
|
22
|
+
|
|
23
|
+
**Option A: Let an LLM do it**
|
|
24
|
+
|
|
25
|
+
Paste this into Claude Code, Cursor, or any AI agent:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
Install opencode-working-memory plugin by following:
|
|
29
|
+
https://raw.githubusercontent.com/sdwolf4103/opencode-working-memory/main/docs/installation.md
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Option B: Manual setup**
|
|
33
|
+
|
|
34
|
+
1. Add to your `~/.config/opencode/opencode.json`:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"plugin": ["opencode-working-memory"]
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
2. Restart OpenCode
|
|
43
|
+
|
|
44
|
+
That's it! The plugin is now active.
|
|
45
|
+
|
|
46
|
+
### For LLM Agents
|
|
47
|
+
|
|
48
|
+
1. Read the OpenCode configuration file at `~/.config/opencode/opencode.json`
|
|
49
|
+
2. Add `"opencode-working-memory"` to the `plugin` array
|
|
50
|
+
3. Verify installation by checking the config file
|
|
51
|
+
|
|
52
|
+
## Quick Start
|
|
53
|
+
|
|
54
|
+
The plugin works automatically once installed. No configuration needed.
|
|
55
|
+
|
|
56
|
+
**Use the tools:**
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# Update persistent memory
|
|
60
|
+
opencode run "use core_memory_update to set my goal"
|
|
61
|
+
|
|
62
|
+
# Read current memory state
|
|
63
|
+
opencode run "use core_memory_read to show me what you remember"
|
|
64
|
+
|
|
65
|
+
# Add important items to working memory
|
|
66
|
+
opencode run "use working_memory_add to remember this file path"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**The agent will automatically:**
|
|
70
|
+
- Track memory pressure and warn when approaching compaction
|
|
71
|
+
- Preserve important context during compaction
|
|
72
|
+
- Clean up old tool-output cache files every 20 tool calls
|
|
73
|
+
- Remove artifacts when sessions are deleted
|
|
74
|
+
|
|
75
|
+
## Features
|
|
76
|
+
|
|
77
|
+
### 🧠 Core Memory (Phase 1)
|
|
78
|
+
|
|
79
|
+
Persistent blocks that survive conversation resets:
|
|
80
|
+
|
|
81
|
+
- **goal** (1000 chars) - Current task/objective
|
|
82
|
+
- **progress** (2000 chars) - What's done, in-progress, next steps
|
|
83
|
+
- **context** (1500 chars) - Key file paths, conventions, patterns
|
|
84
|
+
|
|
85
|
+
### 💡 Working Memory (Phase 3)
|
|
86
|
+
|
|
87
|
+
Auto-extracts and ranks important information:
|
|
88
|
+
|
|
89
|
+
- **Slots** (guaranteed visibility): errors, decisions, todos, dependencies
|
|
90
|
+
- **Pool** (ranked by relevance): file paths, recent activity
|
|
91
|
+
- Exponential decay keeps memory fresh
|
|
92
|
+
- FIFO limits prevent bloat
|
|
93
|
+
|
|
94
|
+
### 🎯 Memory Pressure Monitoring (Phase 4)
|
|
95
|
+
|
|
96
|
+
Real-time token tracking from session database:
|
|
97
|
+
|
|
98
|
+
- Monitors context window usage (75% moderate → 90% high)
|
|
99
|
+
- Proactive intervention messages when pressure is high
|
|
100
|
+
- Pressure-aware smart pruning (adapts compression based on pressure)
|
|
101
|
+
|
|
102
|
+
### 🧹 Storage Governance (Phase 5)
|
|
103
|
+
|
|
104
|
+
Prevents unbounded disk growth:
|
|
105
|
+
|
|
106
|
+
- **Layer 1**: Auto-cleanup on session deletion (all artifacts removed)
|
|
107
|
+
- **Layer 2**: Active cache management (max 300 files/session, 7-day TTL)
|
|
108
|
+
- Triggers every 20 tool calls
|
|
109
|
+
- Silent background operation
|
|
110
|
+
|
|
111
|
+
### 📊 Smart Pruning (Phase 2)
|
|
112
|
+
|
|
113
|
+
Intelligent tool output compression:
|
|
114
|
+
|
|
115
|
+
- Per-tool strategies (keep-all, keep-ends, keep-last, discard)
|
|
116
|
+
- Pressure-aware limits (2k/5k/10k lines based on memory pressure)
|
|
117
|
+
- Preserves important context while reducing noise
|
|
118
|
+
|
|
119
|
+
## Documentation
|
|
120
|
+
|
|
121
|
+
- [Installation Guide](docs/installation.md) - Detailed setup instructions
|
|
122
|
+
- [Architecture Overview](docs/architecture.md) - How it works under the hood
|
|
123
|
+
- [Configuration](docs/configuration.md) - Customization options
|
|
124
|
+
- [Agent Developer Guide](AGENTS.md) - For plugin developers
|
|
125
|
+
|
|
126
|
+
## Tools Provided
|
|
127
|
+
|
|
128
|
+
The plugin exposes these tools to your OpenCode agent:
|
|
129
|
+
|
|
130
|
+
- `core_memory_update` - Update goal/progress/context blocks
|
|
131
|
+
- `core_memory_read` - Read current memory state
|
|
132
|
+
- `working_memory_add` - Manually add important items
|
|
133
|
+
- `working_memory_clear` - Clear all working memory
|
|
134
|
+
- `working_memory_clear_slot` - Clear specific slot (errors/decisions)
|
|
135
|
+
- `working_memory_remove` - Remove specific item by content
|
|
136
|
+
|
|
137
|
+
## How It Works
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
┌───────────────────────────────────────────────────────────┐
|
|
141
|
+
│ Core Memory (Always Visible) │
|
|
142
|
+
│ ┌─────────┬──────────┬──────────┐ │
|
|
143
|
+
│ │ Goal │ Progress │ Context │ │
|
|
144
|
+
│ └─────────┴──────────┴──────────┘ │
|
|
145
|
+
└───────────────────────────────────────────────────────────┘
|
|
146
|
+
↓
|
|
147
|
+
┌───────────────────────────────────────────────────────────┐
|
|
148
|
+
│ Working Memory (Auto-Extracted) │
|
|
149
|
+
│ ┌──────────────────┬──────────────────┐ │
|
|
150
|
+
│ │ Slots (FIFO) │ Pool (Ranked) │ │
|
|
151
|
+
│ │ • errors │ • file-paths │ │
|
|
152
|
+
│ │ • decisions │ • recent │ │
|
|
153
|
+
│ │ • todos │ • mentions │ │
|
|
154
|
+
│ │ • dependencies │ • decay score │ │
|
|
155
|
+
│ └──────────────────┴──────────────────┘ │
|
|
156
|
+
└───────────────────────────────────────────────────────────┘
|
|
157
|
+
↓
|
|
158
|
+
┌───────────────────────────────────────────────────────────┐
|
|
159
|
+
│ Memory Pressure Monitor │
|
|
160
|
+
│ • Tracks tokens from session DB │
|
|
161
|
+
│ • Warns at 75% (moderate) / 90% (high) │
|
|
162
|
+
│ • Sends proactive interventions │
|
|
163
|
+
│ • Adjusts pruning aggressiveness │
|
|
164
|
+
└───────────────────────────────────────────────────────────┘
|
|
165
|
+
↓
|
|
166
|
+
┌───────────────────────────────────────────────────────────┐
|
|
167
|
+
│ Storage Governance │
|
|
168
|
+
│ • Session deletion → cleanup all artifacts │
|
|
169
|
+
│ • Every 20 calls → sweep old cache (300 max, 7d TTL) │
|
|
170
|
+
│ • Silent background operation │
|
|
171
|
+
└───────────────────────────────────────────────────────────┘
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Why This Plugin?
|
|
175
|
+
|
|
176
|
+
**Without this plugin:**
|
|
177
|
+
- 🔴 Agent forgets context after compaction
|
|
178
|
+
- 🔴 Repeats resolved errors
|
|
179
|
+
- 🔴 Loses track of project structure
|
|
180
|
+
- 🔴 Context window fills up uncontrollably
|
|
181
|
+
- 🔴 Disk space grows unbounded
|
|
182
|
+
|
|
183
|
+
**With this plugin:**
|
|
184
|
+
- ✅ Persistent memory across compactions
|
|
185
|
+
- ✅ Smart auto-extraction of important info
|
|
186
|
+
- ✅ Real-time pressure monitoring with interventions
|
|
187
|
+
- ✅ Automatic storage cleanup
|
|
188
|
+
- ✅ Pressure-aware compression
|
|
189
|
+
- ✅ Zero configuration, works immediately
|
|
190
|
+
|
|
191
|
+
## Configuration (Optional)
|
|
192
|
+
|
|
193
|
+
The plugin works great with zero configuration. But if you want to customize:
|
|
194
|
+
|
|
195
|
+
Create `~/.config/opencode/working-memory.json`:
|
|
196
|
+
|
|
197
|
+
```json
|
|
198
|
+
{
|
|
199
|
+
"storage_governance": {
|
|
200
|
+
"tool_output_max_files": 300,
|
|
201
|
+
"tool_output_max_age_ms": 604800000,
|
|
202
|
+
"sweep_interval": 20
|
|
203
|
+
},
|
|
204
|
+
"memory_pressure": {
|
|
205
|
+
"thresholds": {
|
|
206
|
+
"moderate": 0.75,
|
|
207
|
+
"high": 0.90,
|
|
208
|
+
"critical": 0.95
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
See [Configuration Guide](docs/configuration.md) for all options.
|
|
215
|
+
|
|
216
|
+
## Requirements
|
|
217
|
+
|
|
218
|
+
- OpenCode >= 1.0.0
|
|
219
|
+
- Node.js >= 18.0.0
|
|
220
|
+
- `@opencode-ai/plugin` >= 1.2.0
|
|
221
|
+
|
|
222
|
+
## License
|
|
223
|
+
|
|
224
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
225
|
+
|
|
226
|
+
## Contributing
|
|
227
|
+
|
|
228
|
+
Contributions welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) first.
|
|
229
|
+
|
|
230
|
+
## Support
|
|
231
|
+
|
|
232
|
+
- 📖 [Documentation](docs/)
|
|
233
|
+
- 🐛 [Report Issues](https://github.com/sdwolf4103/opencode-working-memory/issues)
|
|
234
|
+
- 💬 [Discussions](https://github.com/sdwolf4103/opencode-working-memory/discussions)
|
|
235
|
+
|
|
236
|
+
## Credits
|
|
237
|
+
|
|
238
|
+
Inspired by the needs of real-world OpenCode usage and built to solve actual pain points in AI-assisted development.
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
**Made with ❤️ for the OpenCode community**
|