opencode-working-memory 1.0.0 โ†’ 1.0.1

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
@@ -18,11 +18,9 @@ Stop losing context across compactions. Stop watching your agent repeat the same
18
18
 
19
19
  ## Installation
20
20
 
21
- ### For Humans
21
+ **Option A: Let an AI agent do it**
22
22
 
23
- **Option A: Let an LLM do it**
24
-
25
- Paste this into Claude Code, Cursor, or any AI agent:
23
+ Paste this into any AI agent:
26
24
 
27
25
  ```
28
26
  Install opencode-working-memory plugin by following:
@@ -31,7 +29,7 @@ https://raw.githubusercontent.com/sdwolf4103/opencode-working-memory/main/docs/i
31
29
 
32
30
  **Option B: Manual setup**
33
31
 
34
- 1. Add to your `~/.config/opencode/opencode.json`:
32
+ Add to your `~/.config/opencode/opencode.json`:
35
33
 
36
34
  ```json
37
35
  {
@@ -39,42 +37,33 @@ https://raw.githubusercontent.com/sdwolf4103/opencode-working-memory/main/docs/i
39
37
  }
40
38
  ```
41
39
 
42
- 2. Restart OpenCode
43
-
44
- That's it! The plugin is now active.
40
+ Restart OpenCode. The plugin is downloaded and installed automatically.
45
41
 
46
42
  ### For LLM Agents
47
43
 
48
- 1. Read the OpenCode configuration file at `~/.config/opencode/opencode.json`
44
+ 1. Edit `~/.config/opencode/opencode.json`
49
45
  2. Add `"opencode-working-memory"` to the `plugin` array
50
- 3. Verify installation by checking the config file
46
+ 3. Verify the config file was saved correctly
51
47
 
52
48
  ## Quick Start
53
49
 
54
50
  The plugin works automatically once installed. No configuration needed.
55
51
 
56
- **Use the tools:**
57
-
58
- ```bash
59
- # Update persistent memory
60
- opencode run "use core_memory_update to set my goal"
52
+ **Try telling your agent:**
61
53
 
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
54
  ```
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
55
+ Use core_memory_update to set my current goal
56
+ ```
57
+ ```
58
+ Use core_memory_read to show me what you remember
59
+ ```
60
+ ```
61
+ Use working_memory_add to remember this file path
62
+ ```
74
63
 
75
64
  ## Features
76
65
 
77
- ### ๐Ÿง  Core Memory (Phase 1)
66
+ ### ๐Ÿง  Core Memory
78
67
 
79
68
  Persistent blocks that survive conversation resets:
80
69
 
@@ -82,7 +71,7 @@ Persistent blocks that survive conversation resets:
82
71
  - **progress** (2000 chars) - What's done, in-progress, next steps
83
72
  - **context** (1500 chars) - Key file paths, conventions, patterns
84
73
 
85
- ### ๐Ÿ’ก Working Memory (Phase 3)
74
+ ### ๐Ÿ’ก Working Memory
86
75
 
87
76
  Auto-extracts and ranks important information:
88
77
 
@@ -91,7 +80,7 @@ Auto-extracts and ranks important information:
91
80
  - Exponential decay keeps memory fresh
92
81
  - FIFO limits prevent bloat
93
82
 
94
- ### ๐ŸŽฏ Memory Pressure Monitoring (Phase 4)
83
+ ### ๐ŸŽฏ Memory Pressure Monitoring
95
84
 
96
85
  Real-time token tracking from session database:
97
86
 
@@ -99,16 +88,15 @@ Real-time token tracking from session database:
99
88
  - Proactive intervention messages when pressure is high
100
89
  - Pressure-aware smart pruning (adapts compression based on pressure)
101
90
 
102
- ### ๐Ÿงน Storage Governance (Phase 5)
91
+ ### ๐Ÿงน Storage Governance
103
92
 
104
93
  Prevents unbounded disk growth:
105
94
 
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
95
+ - Auto-cleanup on session deletion (all artifacts removed)
96
+ - Active cache management (max 300 files/session, 7-day TTL)
109
97
  - Silent background operation
110
98
 
111
- ### ๐Ÿ“Š Smart Pruning (Phase 2)
99
+ ### ๐Ÿ“Š Smart Pruning
112
100
 
113
101
  Intelligent tool output compression:
114
102
 
@@ -190,28 +178,7 @@ The plugin exposes these tools to your OpenCode agent:
190
178
 
191
179
  ## Configuration (Optional)
192
180
 
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.
181
+ The plugin works great with zero configuration. To customize behavior, modify the constants at the top of `index.ts`. See the [Configuration Guide](docs/configuration.md) for all tunable options.
215
182
 
216
183
  ## Requirements
217
184
 
@@ -223,20 +190,17 @@ See [Configuration Guide](docs/configuration.md) for all options.
223
190
 
224
191
  MIT License - see [LICENSE](LICENSE) file for details.
225
192
 
226
- ## Contributing
227
-
228
- Contributions welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) first.
229
-
230
193
  ## Support
231
194
 
232
195
  - ๐Ÿ“– [Documentation](docs/)
233
196
  - ๐Ÿ› [Report Issues](https://github.com/sdwolf4103/opencode-working-memory/issues)
234
- - ๐Ÿ’ฌ [Discussions](https://github.com/sdwolf4103/opencode-working-memory/discussions)
235
197
 
236
198
  ## Credits
237
199
 
238
200
  Inspired by the needs of real-world OpenCode usage and built to solve actual pain points in AI-assisted development.
239
201
 
202
+ > This project is not affiliated with or endorsed by the OpenCode team.
203
+
240
204
  ---
241
205
 
242
206
  **Made with โค๏ธ for the OpenCode community**
@@ -68,9 +68,8 @@ const POOL_MAX_ITEMS = 50; // Hard limit on pool size
68
68
 
69
69
  ```typescript
70
70
  const PRESSURE_THRESHOLDS = {
71
- moderate: 70, // Warning appears in system prompt
72
- high: 85, // Aggressive pruning activates
73
- critical: 95, // Intervention sent to agent
71
+ moderate: 75, // Warning appears in system prompt
72
+ high: 90, // Aggressive pruning activates + intervention sent
74
73
  };
75
74
  ```
76
75
 
@@ -1,90 +1,34 @@
1
1
  # Installation Guide
2
2
 
3
- ## Prerequisites
3
+ ## Quick Install
4
4
 
5
- - **OpenCode** 1.0.0 or higher
6
- - **Node.js** 18+ (for development only)
7
-
8
- ## Quick Install (For Users)
9
-
10
- ### Option 1: Install from npm (Recommended)
11
-
12
- ```bash
13
- npm install opencode-working-memory
14
- ```
15
-
16
- Then add to your `.opencode/package.json`:
17
-
18
- ```json
19
- {
20
- "plugins": [
21
- "opencode-working-memory"
22
- ]
23
- }
24
- ```
25
-
26
- ### Option 2: Install from GitHub
27
-
28
- Add to your `.opencode/package.json`:
5
+ Add to your `~/.config/opencode/opencode.json`:
29
6
 
30
7
  ```json
31
8
  {
32
- "dependencies": {
33
- "opencode-working-memory": "github:sdwolf4103/opencode-working-memory"
34
- },
35
- "plugins": [
36
- "opencode-working-memory"
37
- ]
9
+ "plugin": ["opencode-working-memory"]
38
10
  }
39
11
  ```
40
12
 
41
- Then run:
42
-
43
- ```bash
44
- cd .opencode
45
- npm install
46
- ```
47
-
48
- ### Option 3: Local Development Install
49
-
50
- Clone the repository:
13
+ Restart OpenCode. The plugin is downloaded and installed automatically โ€” no `npm install` needed.
51
14
 
52
- ```bash
53
- git clone https://github.com/sdwolf4103/opencode-working-memory.git
54
- cd opencode-working-memory
55
- npm install
56
- ```
15
+ > **Note**: The correct key is `plugin` (singular), not `plugins`.
57
16
 
58
- Link to your OpenCode project:
17
+ ## For LLM Agents
59
18
 
60
- ```bash
61
- cd /path/to/your/project/.opencode
62
- npm link /path/to/opencode-working-memory
63
- ```
64
-
65
- Add to `.opencode/package.json`:
66
-
67
- ```json
68
- {
69
- "plugins": [
70
- "opencode-working-memory"
71
- ]
72
- }
73
- ```
19
+ 1. Edit `~/.config/opencode/opencode.json`
20
+ 2. Add `"opencode-working-memory"` to the `plugin` array
21
+ 3. Verify the config file was saved correctly
74
22
 
75
23
  ## Verification
76
24
 
77
- After installation, start an OpenCode session and run:
25
+ After restarting OpenCode, ask your agent:
78
26
 
79
27
  ```
80
- core_memory_update goal "Test installation"
28
+ Use core_memory_read to show me what you remember
81
29
  ```
82
30
 
83
- You should see a success message. Check `.opencode/memory-core/` for the session file.
84
-
85
- ## Configuration
86
-
87
- The plugin works out-of-the-box with sensible defaults. For advanced configuration, see [configuration.md](./configuration.md).
31
+ If the tool responds, the plugin is active.
88
32
 
89
33
  ## Troubleshooting
90
34
 
@@ -92,10 +36,10 @@ The plugin works out-of-the-box with sensible defaults. For advanced configurati
92
36
 
93
37
  **Symptom**: No `core_memory_update` tool available
94
38
 
95
- **Solution**:
96
- 1. Check `.opencode/package.json` includes plugin in `"plugins": []` array
97
- 2. Verify `npm install` completed successfully
98
- 3. Restart OpenCode session
39
+ **Solution**:
40
+ 1. Check `~/.config/opencode/opencode.json` uses `"plugin"` (not `"plugins"`)
41
+ 2. Restart OpenCode to trigger automatic installation
42
+ 3. Check OpenCode logs for any download errors
99
43
 
100
44
  ### Memory Files Not Created
101
45
 
@@ -103,26 +47,22 @@ The plugin works out-of-the-box with sensible defaults. For advanced configurati
103
47
 
104
48
  **Solution**:
105
49
  1. Ensure OpenCode has write permissions in project directory
106
- 2. Check plugin hooks are registered (look for "Working Memory Plugin" in session logs)
107
- 3. Trigger memory operations (e.g., use `core_memory_update` tool)
50
+ 2. Trigger memory operations (e.g., use `core_memory_update` tool)
108
51
 
109
52
  ### Type Errors During Development
110
53
 
111
- **Symptom**: TypeScript errors when modifying plugin
54
+ **Symptom**: TypeScript errors when modifying the plugin source
112
55
 
113
56
  **Solution**:
114
- 1. Ensure `@opencode-ai/plugin` is installed: `npm install @opencode-ai/plugin`
115
- 2. Run type checking: `npx tsc --noEmit`
57
+ 1. Run `npm install` to install dev dependencies
58
+ 2. Run `npm run typecheck` to check for errors
116
59
  3. See [AGENTS.md](../AGENTS.md) for code style guidelines
117
60
 
118
61
  ## Uninstallation
119
62
 
120
- ```bash
121
- cd .opencode
122
- npm uninstall opencode-working-memory
123
- ```
63
+ Remove `"opencode-working-memory"` from the `plugin` array in `~/.config/opencode/opencode.json`.
124
64
 
125
- Remove from `.opencode/package.json` plugins array. Memory files in `.opencode/memory-*` will persist unless manually deleted.
65
+ Memory files in `.opencode/memory-*` will persist unless manually deleted.
126
66
 
127
67
  ## Next Steps
128
68
 
package/index.ts CHANGED
@@ -1,16 +1,11 @@
1
1
  /**
2
2
  * Working Memory Plugin for OpenCode
3
- *
4
- * Provides a three-tier memory system to delay/avoid compaction:
3
+ *
4
+ * Four-tier memory architecture:
5
5
  * 1. Core Memory - Persistent goal/progress/context blocks (always in-context)
6
6
  * 2. Working Memory - Auto-managed session-relevant information
7
7
  * 3. Smart Pruning - Content-aware tool output compression
8
8
  * 4. Memory Pressure Monitoring - Context usage tracking with adaptive warnings
9
- *
10
- * Phase 1: Core Memory Foundation (MVP) - โœ… COMPLETED
11
- * Phase 2: Smart Pruning System - โœ… COMPLETED
12
- * Phase 3: Working Memory Auto-Management - โœ… COMPLETED
13
- * Phase 4: Memory Pressure Monitoring - โœ… COMPLETED
14
9
  */
15
10
 
16
11
  import type { Plugin } from "@opencode-ai/plugin";
@@ -46,7 +41,7 @@ const CORE_MEMORY_LIMITS = {
46
41
  };
47
42
 
48
43
  // ============================================================================
49
- // Phase 2: Smart Pruning Types
44
+ // Smart Pruning Types
50
45
  // ============================================================================
51
46
 
52
47
  type PruningStrategy =
@@ -72,7 +67,7 @@ type CachedToolOutput = {
72
67
  };
73
68
 
74
69
  // ============================================================================
75
- // Phase 3: Working Memory Types (Slot-based Architecture)
70
+ // Working Memory Types (Slot-based Architecture)
76
71
  // ============================================================================
77
72
 
78
73
  type WorkingMemory = {
@@ -128,7 +123,7 @@ const WORKING_MEMORY_LIMITS = {
128
123
  };
129
124
 
130
125
  // ============================================================================
131
- // Storage Governance (Layer 1 + Layer 2)
126
+ // Storage Governance
132
127
  // ============================================================================
133
128
 
134
129
  const STORAGE_GOVERNANCE = {
@@ -138,7 +133,7 @@ const STORAGE_GOVERNANCE = {
138
133
  };
139
134
 
140
135
  // ============================================================================
141
- // Phase 4: Memory Pressure Monitoring
136
+ // Memory Pressure Monitoring
142
137
  // ============================================================================
143
138
 
144
139
  type PressureLevel = "safe" | "moderate" | "high";
@@ -169,7 +164,6 @@ type ModelPressureInfo = {
169
164
  updatedAt: string;
170
165
  };
171
166
 
172
- // Compaction tracking (preserved from Phase 4 initial work)
173
167
  type CompactionLog = {
174
168
  sessionID: string;
175
169
  compactionCount: number;
@@ -501,12 +495,11 @@ async function updateCoreMemoryBlock(
501
495
  }
502
496
 
503
497
  // ============================================================================
504
- // Storage Governance Functions (Layer 1 + Layer 2)
498
+ // Storage Governance Functions
505
499
  // ============================================================================
506
500
 
507
501
  /**
508
- * Layer 1: Clean up all artifacts for a deleted session
509
- * Called when session.deleted event is received
502
+ * Clean up all artifacts for a deleted session.
510
503
  */
511
504
  async function cleanupSessionArtifacts(
512
505
  directory: string,
@@ -532,9 +525,9 @@ async function cleanupSessionArtifacts(
532
525
  }
533
526
 
534
527
  /**
535
- * Layer 2: Sweep tool-output cache for a session
536
- * Remove files older than TTL and enforce max file count
537
- * Returns number of files deleted
528
+ * Sweep tool-output cache for a session.
529
+ * Removes files older than TTL and enforces max file count.
530
+ * Returns number of files deleted.
538
531
  */
539
532
  async function sweepToolOutputCache(
540
533
  directory: string,
@@ -606,7 +599,7 @@ async function sweepToolOutputCache(
606
599
  }
607
600
 
608
601
  // ============================================================================
609
- // Phase 2: Smart Pruning System
602
+ // Smart Pruning System
610
603
  // ============================================================================
611
604
 
612
605
  /**
@@ -775,7 +768,7 @@ async function getCachedToolOutput(
775
768
  }
776
769
 
777
770
  // ============================================================================
778
- // Phase 3: Working Memory Auto-Management
771
+ // Working Memory Auto-Management
779
772
  // ============================================================================
780
773
 
781
774
  /**
@@ -1057,9 +1050,7 @@ function getTopItemsForPrompt(
1057
1050
  }
1058
1051
 
1059
1052
  /**
1060
- * Compress file paths to save space in system prompt
1061
- * /Users/sd_wo/opencode/packages/opencode/src/foo.ts โ†’ ~/opencode/pkg/opencode/src/foo.ts
1062
- * /Users/sd_wo/work/opencode-plugins/.opencode/plugins/foo.ts โ†’ ~/work/oc-plugins/.opencode/plugins/foo.ts
1053
+ * Compress file paths to save space in system prompt.
1063
1054
  */
1064
1055
  function compressPath(content: string): string {
1065
1056
  const homeDir = process.env.HOME || '/Users/' + (process.env.USER || 'user');
@@ -1145,7 +1136,7 @@ function getWorkingMemoryItemCount(memory: WorkingMemory): number {
1145
1136
  }
1146
1137
 
1147
1138
  // ============================================================================
1148
- // Phase 4: Compaction Tracking and State Preservation
1139
+ // Compaction Tracking
1149
1140
  // ============================================================================
1150
1141
 
1151
1142
  /**
@@ -1207,14 +1198,13 @@ async function recordCompaction(
1207
1198
  // ============================================================================
1208
1199
 
1209
1200
  /**
1210
- * Calculate usable tokens using OpenCode's exact compaction formula
1211
- * Reference: packages/opencode/src/session/compaction.ts:32-48
1201
+ * Calculate usable tokens using OpenCode's compaction formula.
1212
1202
  */
1213
1203
  function calculateUsableTokens(model: {
1214
1204
  limit: { context: number; input?: number; output: number };
1215
1205
  }): number {
1216
- const OUTPUT_TOKEN_MAX = 32_000; // From transform.ts:21
1217
- const COMPACTION_BUFFER = 20_000; // From compaction.ts:33
1206
+ const OUTPUT_TOKEN_MAX = 32_000;
1207
+ const COMPACTION_BUFFER = 20_000;
1218
1208
 
1219
1209
  const maxOutputTokens = Math.min(
1220
1210
  model.limit.output || OUTPUT_TOKEN_MAX,
@@ -1222,7 +1212,6 @@ function calculateUsableTokens(model: {
1222
1212
  );
1223
1213
  const reserved = Math.min(COMPACTION_BUFFER, maxOutputTokens);
1224
1214
 
1225
- // Match compaction.ts:42-47
1226
1215
  const usable = model.limit.input
1227
1216
  ? model.limit.input - reserved
1228
1217
  : model.limit.context - maxOutputTokens;
@@ -1231,11 +1220,7 @@ function calculateUsableTokens(model: {
1231
1220
  }
1232
1221
 
1233
1222
  /**
1234
- * Calculate pressure level based on current tokens and usable limit
1235
- *
1236
- * Thresholds:
1237
- * - 0.75 (75%): moderate - show reminder in prompt
1238
- * - 0.9 (90%): high - send intervention message
1223
+ * Calculate pressure level based on current tokens and usable limit.
1239
1224
  */
1240
1225
  function calculatePressureLevel(
1241
1226
  currentTokens: number,
@@ -1334,18 +1319,14 @@ async function loadModelPressureInfo(
1334
1319
  }
1335
1320
 
1336
1321
  /**
1337
- * Calculate total tokens by querying OpenCode's session database
1338
- * This is more reliable than relying on hook-provided messages
1339
- *
1340
- * Note: Only looks at last 10 messages to avoid stale data from before compaction
1322
+ * Calculate total tokens by querying OpenCode's session database.
1341
1323
  */
1342
1324
  async function calculateTotalTokensFromDB(sessionID: string): Promise<number> {
1343
1325
  try {
1344
1326
  const { execSync } = await import("child_process");
1345
1327
  const dbPath = join(process.env.HOME || "~", ".local/share/opencode/opencode.db");
1346
1328
 
1347
- // Get tokens.total from most recent assistant message (last 10 to be safe)
1348
- // Use MAX to handle edge cases, but limit to recent messages to avoid stale pre-compaction data
1329
+ // Get tokens.total from most recent assistant message
1349
1330
  const query = `
1350
1331
  SELECT json_extract(data, '$.tokens.total') as total
1351
1332
  FROM message
@@ -1365,11 +1346,7 @@ async function calculateTotalTokensFromDB(sessionID: string): Promise<number> {
1365
1346
  }
1366
1347
 
1367
1348
  /**
1368
- * Generate pressure warning text for system prompt injection
1369
- *
1370
- * Design principles:
1371
- * - MODERATE (75%): gentle nudge, no interruption
1372
- * - HIGH (90%): actionable commands, pause and persist state
1349
+ * Generate pressure warning text for system prompt injection.
1373
1350
  */
1374
1351
  function generatePressureWarning(info: ModelPressureInfo): string {
1375
1352
  const { current, calculated } = info;
@@ -1387,13 +1364,8 @@ function generatePressureWarning(info: ModelPressureInfo): string {
1387
1364
  }
1388
1365
 
1389
1366
  /**
1390
- * Send proactive intervention message when HIGH pressure detected (90%)
1391
- *
1392
- * This sends an independent system message to the session immediately, so the agent
1393
- * receives the task in the queue without interrupting current work. The agent will
1394
- * process it automatically when available.
1395
- *
1396
- * Design: Use promptAsync() which returns 204 immediately, non-blocking.
1367
+ * Send a proactive intervention message when HIGH pressure (90%) is detected.
1368
+ * Uses promptAsync() which returns immediately (non-blocking).
1397
1369
  */
1398
1370
  async function sendPressureInterventionMessage(
1399
1371
  client: any,
@@ -1421,17 +1393,14 @@ REQUIRED ACTIONS:
1421
1393
  After completing these actions, you may resume your current task.`;
1422
1394
 
1423
1395
  try {
1424
- // Use promptAsync to send message without waiting for response
1425
1396
  await client.session.promptAsync({
1426
1397
  path: { id: sessionID },
1427
1398
  body: {
1428
1399
  parts: [{
1429
1400
  type: "text",
1430
- // Send actionable content directly (not log-style placeholder)
1431
1401
  text: systemPrompt,
1432
1402
  }],
1433
- // Keep system unset so the intervention is visible as a normal prompt
1434
- noReply: false, // We want agent to respond with actions
1403
+ noReply: false,
1435
1404
  },
1436
1405
  });
1437
1406
  } catch (error) {
@@ -1440,36 +1409,32 @@ After completing these actions, you may resume your current task.`;
1440
1409
  }
1441
1410
 
1442
1411
  /**
1443
- * Get pressure-aware pruning config based on current memory pressure
1444
- * HYPER-AGGRESSIVE MODE: pressure >= 0.90 enforces strict limits
1412
+ * Get pressure-aware pruning config based on current memory pressure.
1445
1413
  */
1446
1414
  function getPressureAwarePruningConfig(pressure: number): {
1447
1415
  maxLines: number;
1448
1416
  maxChars: number;
1449
1417
  aggressiveTruncation: boolean;
1450
1418
  } {
1451
- // HIGH (>= 90%): Hyper-Aggressive Mode
1452
1419
  if (pressure >= 0.90) {
1453
1420
  return {
1454
- maxLines: 2000, // Hard limit: 2000 lines max
1455
- maxChars: 100_000, // ~25k tokens max per tool output
1456
- aggressiveTruncation: true, // Force truncation, no exceptions
1421
+ maxLines: 2000,
1422
+ maxChars: 100_000,
1423
+ aggressiveTruncation: true,
1457
1424
  };
1458
1425
  }
1459
1426
 
1460
- // MODERATE (>= 75%): Aggressive Mode
1461
1427
  if (pressure >= 0.75) {
1462
1428
  return {
1463
1429
  maxLines: 5000,
1464
- maxChars: 200_000, // ~50k tokens max
1430
+ maxChars: 200_000,
1465
1431
  aggressiveTruncation: true,
1466
1432
  };
1467
1433
  }
1468
1434
 
1469
- // SAFE (< 75%): Normal Mode
1470
1435
  return {
1471
1436
  maxLines: 10_000,
1472
- maxChars: 400_000, // ~100k tokens max
1437
+ maxChars: 400_000,
1473
1438
  aggressiveTruncation: false,
1474
1439
  };
1475
1440
  }
@@ -1524,34 +1489,14 @@ export default async function WorkingMemoryPlugin(
1524
1489
  const { directory, client } = input;
1525
1490
 
1526
1491
  return {
1527
- // ========================================================================
1528
- // Phase 1: Inject Core Memory and Working Memory into System Prompt
1529
- // Phase 4: Inject Memory Pressure Warnings & Calculate Tokens from DB
1530
- // Phase 4.5: Proactive Pressure Intervention (NEW)
1531
- // Phase 5: Core Memory Usage Guidelines (AGENTS.md Enhancement)
1532
- //
1533
- // Dual-System Approach:
1534
- // 1. PASSIVE WARNING (existing): Injected into next turn's system prompt
1535
- // - Always present as reminder in system context
1536
- // - 1-turn delay but persistent
1537
- //
1538
- // 2. PROACTIVE INTERVENTION (new): Immediate async message sent to queue
1539
- // - No delay, sent immediately when HIGH (90%) detected
1540
- // - Agent processes when available (non-blocking)
1541
- // - Only sent when pressure level increases (avoids spam)
1542
- //
1543
- // 3. USAGE GUIDELINES (new): Injected after AGENTS.md, before core_memory
1544
- // - Teaches agent how to use core_memory blocks correctly
1545
- // - Prevents storing API docs/type definitions in memory
1546
- // - Ensures goal/progress/context stay focused on current task
1547
- // ========================================================================
1492
+ // Inject core memory usage guidelines, pressure warnings, core memory,
1493
+ // and working memory into the system prompt each turn.
1548
1494
  "experimental.chat.system.transform": async (hookInput, output) => {
1549
1495
  const { sessionID, model } = hookInput;
1550
1496
  if (!sessionID) return;
1551
1497
 
1552
- // Phase 5: Inject Core Memory Usage Guidelines
1553
- // This enhances AGENTS.md (if exists) with plugin-specific instructions
1554
- // Inserted early so it's read before agent sees <core_memory> block
1498
+ // Inject core memory usage guidelines.
1499
+ // Inserted before <core_memory> so the agent reads guidance first.
1555
1500
  const coreMemoryGuidelines = `
1556
1501
  # Core Memory Usage Guidelines
1557
1502
 
@@ -1613,8 +1558,8 @@ The Working Memory Plugin provides persistent core_memory blocks. **USE THEM COR
1613
1558
 
1614
1559
  output.system.push(coreMemoryGuidelines);
1615
1560
 
1616
- // Phase 4: Check for memory pressure and inject warning
1617
- // Skip warning if model just changed (avoids false alarms with different limits)
1561
+ // Check for memory pressure and inject warning into system prompt.
1562
+ // Skip if model just changed (avoids false alarms with different limits).
1618
1563
  const prevPressure = await loadModelPressureInfo(directory, sessionID);
1619
1564
  const modelChanged = model && prevPressure && prevPressure.modelID !== model.id;
1620
1565
 
@@ -1625,7 +1570,7 @@ The Working Memory Plugin provides persistent core_memory blocks. **USE THEM COR
1625
1570
  }
1626
1571
  }
1627
1572
 
1628
- // Phase 4: Calculate current token usage from DB and update pressure
1573
+ // Calculate current token usage from DB and update pressure info.
1629
1574
  if (model) {
1630
1575
  const totalTokens = await calculateTotalTokensFromDB(sessionID);
1631
1576
 
@@ -1640,14 +1585,12 @@ The Working Memory Plugin provides persistent core_memory blocks. **USE THEM COR
1640
1585
  totalTokens
1641
1586
  );
1642
1587
 
1643
- // Save for next turn's warning injection
1588
+ // Save for next turn's warning injection.
1644
1589
  await saveModelPressureInfo(directory, updatedPressure);
1645
1590
 
1646
- // Phase 4.5: Proactive Intervention - Send immediate message if HIGH (90%)
1647
- // This is better than waiting for next turn's passive warning
1648
- // The message goes into the queue and agent processes it when available
1591
+ // Send proactive intervention if pressure just crossed into HIGH.
1649
1592
  if (updatedPressure.current.level === "high") {
1650
- // Only send if pressure increased from previous level (avoid spam)
1593
+ // Only send if pressure just escalated (avoid repeated spam).
1651
1594
  const shouldSend = !prevPressure ||
1652
1595
  prevPressure.current.level === "safe" ||
1653
1596
  prevPressure.current.level === "moderate";
@@ -1658,7 +1601,7 @@ The Working Memory Plugin provides persistent core_memory blocks. **USE THEM COR
1658
1601
  }
1659
1602
  }
1660
1603
 
1661
- // Phase 1: Core memory
1604
+ // Core memory
1662
1605
  const coreMemory = await loadCoreMemory(directory, sessionID);
1663
1606
  if (coreMemory) {
1664
1607
  const hasContent =
@@ -1672,7 +1615,7 @@ The Working Memory Plugin provides persistent core_memory blocks. **USE THEM COR
1672
1615
  }
1673
1616
  }
1674
1617
 
1675
- // Phase 1: Working memory
1618
+ // Working memory
1676
1619
  const workingMemory = await loadWorkingMemory(directory, sessionID);
1677
1620
  if (workingMemory && getWorkingMemoryItemCount(workingMemory) > 0) {
1678
1621
  const workingPrompt = renderWorkingMemoryPrompt(workingMemory);
@@ -1682,15 +1625,11 @@ The Working Memory Plugin provides persistent core_memory blocks. **USE THEM COR
1682
1625
  }
1683
1626
  },
1684
1627
 
1685
- // ========================================================================
1686
- // Phase 2 & 3: Cache Tool Outputs and Auto-Extract to Working Memory
1687
- // Storage Governance Layer 2: Tool Output Cache Sweep Trigger
1688
- // ========================================================================
1628
+ // Cache tool outputs, auto-extract to working memory, and sweep cache periodically.
1689
1629
  "tool.execute.after": async (hookInput, hookOutput) => {
1690
1630
  const { sessionID, callID, tool: toolName, args } = hookInput;
1691
1631
  const { output: toolOutput } = hookOutput;
1692
1632
 
1693
- // Phase 2: Cache the full output for later smart pruning
1694
1633
  await cacheToolOutput(directory, {
1695
1634
  callID,
1696
1635
  sessionID,
@@ -1699,22 +1638,19 @@ The Working Memory Plugin provides persistent core_memory blocks. **USE THEM COR
1699
1638
  timestamp: Date.now(),
1700
1639
  });
1701
1640
 
1702
- // Phase 3: Auto-extract to working memory
1703
1641
  const extractedItems = extractFromToolOutput(toolName, toolOutput);
1704
1642
  for (const item of extractedItems) {
1705
1643
  await addToWorkingMemory(directory, sessionID, item);
1706
1644
  }
1707
1645
 
1708
- // Storage Governance Layer 2: Sweep tool-output cache every N calls
1646
+ // Sweep tool-output cache every N tool calls.
1709
1647
  const memory = await loadWorkingMemory(directory, sessionID);
1710
1648
  if (memory && memory.eventCounter % STORAGE_GOVERNANCE.sweepInterval === 0) {
1711
1649
  await sweepToolOutputCache(directory, sessionID);
1712
1650
  }
1713
1651
  },
1714
1652
 
1715
- // ========================================================================
1716
- // Phase 2: Apply Smart Pruning to Messages (Pressure-Aware)
1717
- // ========================================================================
1653
+ // Apply smart pruning to compacted tool outputs (pressure-aware).
1718
1654
  "experimental.chat.messages.transform": async (hookInput, output) => {
1719
1655
  const sessionID = output.messages[0]?.info?.sessionID || "";
1720
1656
 
@@ -1754,11 +1690,8 @@ The Working Memory Plugin provides persistent core_memory blocks. **USE THEM COR
1754
1690
  }
1755
1691
  },
1756
1692
 
1757
- // ========================================================================
1758
- // Storage Governance Layer 1: Session Deletion Event Handler
1759
- // ========================================================================
1693
+ // Clean up all session artifacts on session deletion.
1760
1694
  event: async ({ event }) => {
1761
- // Listen for session.deleted events and cleanup all artifacts
1762
1695
  if (event.type === "session.deleted") {
1763
1696
  const sessionID = event.properties?.info?.id;
1764
1697
  if (sessionID) {
@@ -1767,9 +1700,7 @@ The Working Memory Plugin provides persistent core_memory blocks. **USE THEM COR
1767
1700
  }
1768
1701
  },
1769
1702
 
1770
- // ========================================================================
1771
- // Phase 4: Preserve State Before Compaction
1772
- // ========================================================================
1703
+ // Preserve working memory state before compaction.
1773
1704
  "experimental.session.compacting": async (hookInput, output) => {
1774
1705
  const { sessionID } = hookInput;
1775
1706
 
@@ -1808,7 +1739,7 @@ The Working Memory Plugin provides persistent core_memory blocks. **USE THEM COR
1808
1739
  }
1809
1740
  }
1810
1741
 
1811
- // SSOT Bridge: Inject OpenCode native Todos from DB into compaction context
1742
+ // Inject pending OpenCode todos into compaction context.
1812
1743
  try {
1813
1744
  const { execSync } = await import("child_process");
1814
1745
  const dbPath = join(process.env.HOME || "~", ".local/share/opencode/opencode.db");
@@ -1849,9 +1780,7 @@ The Working Memory Plugin provides persistent core_memory blocks. **USE THEM COR
1849
1780
  }
1850
1781
  },
1851
1782
 
1852
- // ========================================================================
1853
1783
  // Tools
1854
- // ========================================================================
1855
1784
  tool: {
1856
1785
  core_memory_update: tool({
1857
1786
  description: `Update persistent core memory blocks that survive compaction.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-working-memory",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Advanced four-tier memory architecture for OpenCode with intelligent pressure monitoring and auto-storage governance",
5
5
  "type": "module",
6
6
  "main": "index.ts",