@scitrera/memorylayer-opencode-plugin 0.1.22
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 +178 -0
- package/dist/src/hooks/event.d.ts +15 -0
- package/dist/src/hooks/event.d.ts.map +1 -0
- package/dist/src/hooks/event.js +53 -0
- package/dist/src/hooks/event.js.map +1 -0
- package/dist/src/hooks/message.d.ts +20 -0
- package/dist/src/hooks/message.d.ts.map +1 -0
- package/dist/src/hooks/message.js +128 -0
- package/dist/src/hooks/message.js.map +1 -0
- package/dist/src/hooks/session.d.ts +20 -0
- package/dist/src/hooks/session.d.ts.map +1 -0
- package/dist/src/hooks/session.js +121 -0
- package/dist/src/hooks/session.js.map +1 -0
- package/dist/src/hooks/tool.d.ts +23 -0
- package/dist/src/hooks/tool.d.ts.map +1 -0
- package/dist/src/hooks/tool.js +168 -0
- package/dist/src/hooks/tool.js.map +1 -0
- package/dist/src/index.d.ts +31 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +176 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/shared/client.d.ts +27 -0
- package/dist/src/shared/client.d.ts.map +1 -0
- package/dist/src/shared/client.js +69 -0
- package/dist/src/shared/client.js.map +1 -0
- package/dist/src/shared/formatters.d.ts +33 -0
- package/dist/src/shared/formatters.d.ts.map +1 -0
- package/dist/src/shared/formatters.js +187 -0
- package/dist/src/shared/formatters.js.map +1 -0
- package/dist/src/shared/observation.d.ts +59 -0
- package/dist/src/shared/observation.d.ts.map +1 -0
- package/dist/src/shared/observation.js +406 -0
- package/dist/src/shared/observation.js.map +1 -0
- package/dist/src/shared/state.d.ts +66 -0
- package/dist/src/shared/state.d.ts.map +1 -0
- package/dist/src/shared/state.js +144 -0
- package/dist/src/shared/state.js.map +1 -0
- package/dist/src/shared/types.d.ts +141 -0
- package/dist/src/shared/types.d.ts.map +1 -0
- package/dist/src/shared/types.js +9 -0
- package/dist/src/shared/types.js.map +1 -0
- package/opencode.example.json +15 -0
- package/package.json +52 -0
- package/src/commands/recall.md +55 -0
- package/src/commands/remember.md +37 -0
- package/src/commands/setup.md +47 -0
- package/src/commands/status.md +59 -0
- package/src/hooks/event.ts +63 -0
- package/src/hooks/message.ts +147 -0
- package/src/hooks/session.ts +127 -0
- package/src/hooks/tool.ts +207 -0
- package/src/index.ts +197 -0
- package/src/shared/client.ts +73 -0
- package/src/shared/formatters.ts +237 -0
- package/src/shared/observation.ts +447 -0
- package/src/shared/state.ts +159 -0
- package/src/shared/types.ts +144 -0
- package/tsconfig.json +24 -0
package/README.md
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# MemoryLayer OpenCode Plugin
|
|
2
|
+
|
|
3
|
+
Persistent memory for [OpenCode](https://github.com/sst/opencode) sessions. Gives your AI coding agent long-term memory that survives context compaction and persists across sessions.
|
|
4
|
+
|
|
5
|
+
## What It Does
|
|
6
|
+
|
|
7
|
+
This plugin integrates [MemoryLayer](https://memorylayer.ai) into OpenCode via two mechanisms:
|
|
8
|
+
|
|
9
|
+
1. **MCP Tools** (25 default / 38 in `full`) — The MemoryLayer MCP server gives the LLM direct access to remember, recall, reflect, manage sessions, drive the context sandbox / RLM, and work with chat threads, skills, and MCP-server registry entries.
|
|
10
|
+
|
|
11
|
+
2. **Proactive Hooks** — The plugin automatically:
|
|
12
|
+
- Injects workspace briefing and user directives at session start
|
|
13
|
+
- Recalls relevant memories when you ask preference/convention questions
|
|
14
|
+
- Captures tool observations (file edits, searches, commands) as working memory
|
|
15
|
+
- Commits working memory before context compaction
|
|
16
|
+
- Cleans up sessions on exit
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
### 1. Install the MemoryLayer server
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install memorylayer-server
|
|
24
|
+
memorylayer serve
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Or with Docker:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
docker run -d -p 61001:61001 -v memorylayer-data:/data scitrera/memorylayer-server
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 2. Configure OpenCode
|
|
34
|
+
|
|
35
|
+
Add to your `opencode.json`:
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"mcp": {
|
|
40
|
+
"memorylayer": {
|
|
41
|
+
"type": "local",
|
|
42
|
+
"command": ["npx", "@scitrera/memorylayer-mcp-server"],
|
|
43
|
+
"environment": {
|
|
44
|
+
"MEMORYLAYER_URL": "{env:MEMORYLAYER_URL}",
|
|
45
|
+
"MEMORYLAYER_API_KEY": "{env:MEMORYLAYER_API_KEY}"
|
|
46
|
+
},
|
|
47
|
+
"enabled": true
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"plugin": ["@scitrera/memorylayer-opencode-plugin"]
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 3. Set environment variables (optional)
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
export MEMORYLAYER_URL=http://localhost:61001 # default
|
|
58
|
+
export MEMORYLAYER_API_KEY=your-key # optional, for authenticated servers
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 4. Verify
|
|
62
|
+
|
|
63
|
+
Start OpenCode and run `/memorylayer-status` to check the connection.
|
|
64
|
+
|
|
65
|
+
## Slash Commands
|
|
66
|
+
|
|
67
|
+
| Command | Description |
|
|
68
|
+
|---------|-------------|
|
|
69
|
+
| `/memorylayer-remember <content>` | Store a memory with auto-detected type and importance |
|
|
70
|
+
| `/memorylayer-recall <query>` | Search memories by semantic query |
|
|
71
|
+
| `/memorylayer-status` | Check connection status and workspace info |
|
|
72
|
+
| `/memorylayer-setup` | Guided setup and verification |
|
|
73
|
+
|
|
74
|
+
## How Hooks Work
|
|
75
|
+
|
|
76
|
+
### Session Start (`experimental.chat.system.transform`)
|
|
77
|
+
On first interaction, loads workspace briefing, user directives, and any existing sandbox state into the system prompt.
|
|
78
|
+
|
|
79
|
+
### User Messages (`chat.message`)
|
|
80
|
+
Detects 5 pattern categories in user messages and performs targeted recall:
|
|
81
|
+
- **Preference**: "which X should we use", "what's our convention"
|
|
82
|
+
- **Recall**: "remember", "what did we", "remind me"
|
|
83
|
+
- **Analysis**: "review", "analyze", "status"
|
|
84
|
+
- **Implementation**: "implement", "build", "fix"
|
|
85
|
+
- **Error**: "error", "bug", "broken"
|
|
86
|
+
|
|
87
|
+
### Tool Execution (`tool.execute.before` / `tool.execute.after`)
|
|
88
|
+
- **Before**: Injects recalled context for edit/write and task/delegation tools
|
|
89
|
+
- **After**: Silently captures observations (files, facts, concepts, intent) as working memory
|
|
90
|
+
|
|
91
|
+
### Context Compaction (`experimental.session.compacting`)
|
|
92
|
+
Commits working memory to long-term storage and checkpoints server-side sandbox state before the context window is trimmed.
|
|
93
|
+
|
|
94
|
+
### Shell Environment (`shell.env`)
|
|
95
|
+
Propagates `MEMORYLAYER_URL` and `MEMORYLAYER_API_KEY` to shell commands.
|
|
96
|
+
|
|
97
|
+
## Configuration
|
|
98
|
+
|
|
99
|
+
### Environment Variables
|
|
100
|
+
|
|
101
|
+
| Variable | Default | Description |
|
|
102
|
+
|----------|---------|-------------|
|
|
103
|
+
| `MEMORYLAYER_URL` | `http://localhost:61001` | MemoryLayer server URL |
|
|
104
|
+
| `MEMORYLAYER_API_KEY` | — | API key (optional for local servers) |
|
|
105
|
+
| `MEMORYLAYER_WORKSPACE_ID` | auto-detected | Workspace identifier (auto-detected from git repo name) |
|
|
106
|
+
|
|
107
|
+
### Workspace Auto-Detection
|
|
108
|
+
|
|
109
|
+
The workspace ID is automatically detected from:
|
|
110
|
+
1. Git remote origin repository name
|
|
111
|
+
2. Git root directory name
|
|
112
|
+
3. Current working directory name
|
|
113
|
+
|
|
114
|
+
Override with the `MEMORYLAYER_WORKSPACE_ID` environment variable.
|
|
115
|
+
|
|
116
|
+
## Memory Types
|
|
117
|
+
|
|
118
|
+
| Type | Description | Importance |
|
|
119
|
+
|------|-------------|------------|
|
|
120
|
+
| `semantic` | Facts, concepts, knowledge | 0.5-0.9 |
|
|
121
|
+
| `procedural` | How-to, solutions, patterns | 0.5-0.8 |
|
|
122
|
+
| `episodic` | Events, what happened | 0.5-0.7 |
|
|
123
|
+
| `working` | Current task context (auto-expires) | 0.3-0.6 |
|
|
124
|
+
|
|
125
|
+
### Common Subtypes
|
|
126
|
+
|
|
127
|
+
`directive`, `decision`, `fix`, `solution`, `code_pattern`, `error`, `workflow`, `preference`, `problem`
|
|
128
|
+
|
|
129
|
+
## Architecture
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
OpenCode
|
|
133
|
+
├── MCP Server (@scitrera/memorylayer-mcp-server)
|
|
134
|
+
│ └── 25 memory tools by default (38 in `full` profile)
|
|
135
|
+
│
|
|
136
|
+
├── Plugin Hooks (@scitrera/memorylayer-opencode-plugin)
|
|
137
|
+
│ ├── system.transform → session briefing injection
|
|
138
|
+
│ ├── chat.message → pattern-based recall
|
|
139
|
+
│ ├── tool.before → pre-tool context injection
|
|
140
|
+
│ ├── tool.after → observation capture
|
|
141
|
+
│ ├── session.compacting → working memory commit
|
|
142
|
+
│ └── shell.env → env var propagation
|
|
143
|
+
│
|
|
144
|
+
└── MemoryLayer Server (memorylayer-server)
|
|
145
|
+
├── Memory storage (SQLite + vector search)
|
|
146
|
+
├── Knowledge graph (associations)
|
|
147
|
+
├── Working memory (sessions)
|
|
148
|
+
└── Context sandbox (Python execution)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Troubleshooting
|
|
152
|
+
|
|
153
|
+
### Server not reachable
|
|
154
|
+
```bash
|
|
155
|
+
# Check if server is running
|
|
156
|
+
curl http://localhost:61001/health
|
|
157
|
+
|
|
158
|
+
# Start the server
|
|
159
|
+
memorylayer serve
|
|
160
|
+
|
|
161
|
+
# Or with Docker
|
|
162
|
+
docker run -d -p 61001:61001 -v memorylayer-data:/data scitrera/memorylayer-server
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### MCP tools not available
|
|
166
|
+
Verify `opencode.json` has the `mcp.memorylayer` configuration. Restart OpenCode after configuration changes.
|
|
167
|
+
|
|
168
|
+
### Plugin not loading
|
|
169
|
+
Ensure the plugin is listed in `opencode.json`:
|
|
170
|
+
```json
|
|
171
|
+
{
|
|
172
|
+
"plugin": ["@scitrera/memorylayer-opencode-plugin"]
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## License
|
|
177
|
+
|
|
178
|
+
Apache-2.0
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event hook for MemoryLayer OpenCode plugin.
|
|
3
|
+
*
|
|
4
|
+
* Handles context compaction by preserving critical memory state
|
|
5
|
+
* and committing working memory before context is lost.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Handle session compacting — commit working memory and checkpoint sandbox.
|
|
9
|
+
*
|
|
10
|
+
* OpenCode's `experimental.session.compacting` hook is the equivalent
|
|
11
|
+
* of Claude Code's PreCompact. We commit working memory and return
|
|
12
|
+
* context strings that survive the compaction.
|
|
13
|
+
*/
|
|
14
|
+
export declare function handleCompacting(_sessionID: string): Promise<string[]>;
|
|
15
|
+
//# sourceMappingURL=event.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../../src/hooks/event.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA8C5E"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event hook for MemoryLayer OpenCode plugin.
|
|
3
|
+
*
|
|
4
|
+
* Handles context compaction by preserving critical memory state
|
|
5
|
+
* and committing working memory before context is lost.
|
|
6
|
+
*/
|
|
7
|
+
import { getClient, checkHealth } from "../shared/client.js";
|
|
8
|
+
/**
|
|
9
|
+
* Handle session compacting — commit working memory and checkpoint sandbox.
|
|
10
|
+
*
|
|
11
|
+
* OpenCode's `experimental.session.compacting` hook is the equivalent
|
|
12
|
+
* of Claude Code's PreCompact. We commit working memory and return
|
|
13
|
+
* context strings that survive the compaction.
|
|
14
|
+
*/
|
|
15
|
+
export async function handleCompacting(_sessionID) {
|
|
16
|
+
const context = [];
|
|
17
|
+
const healthy = await checkHealth();
|
|
18
|
+
if (!healthy)
|
|
19
|
+
return context;
|
|
20
|
+
const client = getClient();
|
|
21
|
+
const clientSessionId = client.getSessionId();
|
|
22
|
+
if (clientSessionId) {
|
|
23
|
+
// Commit working memory to long-term storage before compaction
|
|
24
|
+
try {
|
|
25
|
+
await client.commitSession(clientSessionId, { importance_threshold: 0.3 });
|
|
26
|
+
context.push("[MemoryLayer] Working memory committed to long-term storage before compaction. " +
|
|
27
|
+
"Use `memory_recall` to retrieve prior context. " +
|
|
28
|
+
"Use `memory_context_inspect` to check server-side sandbox variables.");
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// Commit may fail, but we should still try to preserve context
|
|
32
|
+
}
|
|
33
|
+
// Checkpoint sandbox state if active
|
|
34
|
+
try {
|
|
35
|
+
const status = await client.contextStatus();
|
|
36
|
+
if (status.exists && (status.variable_count ?? 0) > 0) {
|
|
37
|
+
await client.contextCheckpoint();
|
|
38
|
+
context.push("[MemoryLayer] Server-side sandbox state checkpointed. " +
|
|
39
|
+
"Variables persist across compaction — use `memory_context_inspect` to re-orient.");
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// Sandbox checkpoint is best-effort
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Always include recovery instructions
|
|
47
|
+
if (context.length === 0) {
|
|
48
|
+
context.push("[MemoryLayer] Context compaction occurred. Use `memory_recall` to retrieve " +
|
|
49
|
+
"prior context and `memory_context_inspect` to check sandbox state.");
|
|
50
|
+
}
|
|
51
|
+
return context;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=event.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event.js","sourceRoot":"","sources":["../../../src/hooks/event.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAE7D;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,UAAkB;IACvD,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,MAAM,OAAO,GAAG,MAAM,WAAW,EAAE,CAAC;IACpC,IAAI,CAAC,OAAO;QAAE,OAAO,OAAO,CAAC;IAE7B,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,eAAe,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;IAE9C,IAAI,eAAe,EAAE,CAAC;QACpB,+DAA+D;QAC/D,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,aAAa,CAAC,eAAe,EAAE,EAAE,oBAAoB,EAAE,GAAG,EAAE,CAAC,CAAC;YAC3E,OAAO,CAAC,IAAI,CACV,iFAAiF;gBACjF,iDAAiD;gBACjD,sEAAsE,CACvE,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,+DAA+D;QACjE,CAAC;QAED,qCAAqC;QACrC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,EAAmD,CAAC;YAC7F,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;gBACtD,MAAM,MAAM,CAAC,iBAAiB,EAAE,CAAC;gBACjC,OAAO,CAAC,IAAI,CACV,wDAAwD;oBACxD,kFAAkF,CACnF,CAAC;YACJ,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,oCAAoC;QACtC,CAAC;IACH,CAAC;IAED,uCAAuC;IACvC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,IAAI,CACV,6EAA6E;YAC7E,oEAAoE,CACrE,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User message hook for MemoryLayer OpenCode plugin.
|
|
3
|
+
*
|
|
4
|
+
* Detects patterns in user messages and performs intelligent recall
|
|
5
|
+
* to inject relevant memories into the conversation context.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Extract user message text from message parts.
|
|
9
|
+
*/
|
|
10
|
+
export declare function extractMessageText(parts: Array<{
|
|
11
|
+
type: string;
|
|
12
|
+
text?: string;
|
|
13
|
+
}>): string;
|
|
14
|
+
/**
|
|
15
|
+
* Handle a new user message — detect patterns and recall relevant memories.
|
|
16
|
+
*
|
|
17
|
+
* Returns additional context text to inject, or null if no recall needed.
|
|
18
|
+
*/
|
|
19
|
+
export declare function handleUserMessage(messageText: string): Promise<string | null>;
|
|
20
|
+
//# sourceMappingURL=message.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../src/hooks/message.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAmFH;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,MAAM,CAKxF;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA2CnF"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User message hook for MemoryLayer OpenCode plugin.
|
|
3
|
+
*
|
|
4
|
+
* Detects patterns in user messages and performs intelligent recall
|
|
5
|
+
* to inject relevant memories into the conversation context.
|
|
6
|
+
*/
|
|
7
|
+
import { getClient, checkHealth } from "../shared/client.js";
|
|
8
|
+
import { formatRecallResult } from "../shared/formatters.js";
|
|
9
|
+
import { wasRecallDoneThisTurn, markRecallDone, resetRecallStatus, setCurrentTopic, setCurrentPrompt, } from "../shared/state.js";
|
|
10
|
+
/** Pattern categories and their recall queries */
|
|
11
|
+
const PATTERNS = {
|
|
12
|
+
preference: {
|
|
13
|
+
regex: /\b(which\s+\w+\s+should|should\s+we\s+use|what\s+do\s+we\s+use|how\s+do\s+we|what'?s\s+our|preferred|convention|do\s+we\s+have\s+a|what'?s\s+the\s+(default|standard|preferred))\b/i,
|
|
14
|
+
queries: ["directive", "preference", "convention"],
|
|
15
|
+
},
|
|
16
|
+
recall: {
|
|
17
|
+
regex: /\b(remember|recall|what did we|how did we|remind me|what was the|what were the|what do you (know|remember))\b/i,
|
|
18
|
+
queries: ["context", "history", "decision"],
|
|
19
|
+
},
|
|
20
|
+
analysis: {
|
|
21
|
+
regex: /\b(review|assess|analyze|evaluate|audit|investigate|explore|research|compare|status|state of|readiness|gap analysis)\b/i,
|
|
22
|
+
queries: ["status", "assessment", "gaps", "problems"],
|
|
23
|
+
},
|
|
24
|
+
implementation: {
|
|
25
|
+
regex: /\b(implement|build|create|add|fix|refactor|update|change|modify)\b/i,
|
|
26
|
+
queries: ["patterns", "solutions", "issues"],
|
|
27
|
+
},
|
|
28
|
+
error: {
|
|
29
|
+
regex: /\b(error|bug|issue|broken|failing|crash|exception|doesn't work|not working)\b/i,
|
|
30
|
+
queries: ["fix", "error", "solution"],
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Detect which pattern category matches the prompt
|
|
35
|
+
*/
|
|
36
|
+
function detectPattern(prompt) {
|
|
37
|
+
for (const [category, config] of Object.entries(PATTERNS)) {
|
|
38
|
+
if (config.regex.test(prompt)) {
|
|
39
|
+
return category;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Extract key terms from the prompt for recall query
|
|
46
|
+
*/
|
|
47
|
+
function extractKeyTerms(prompt) {
|
|
48
|
+
const stopWords = new Set([
|
|
49
|
+
"the", "a", "an", "is", "are", "was", "were", "be", "been",
|
|
50
|
+
"have", "has", "had", "do", "does", "did", "will", "would",
|
|
51
|
+
"could", "should", "may", "might", "must", "can", "this",
|
|
52
|
+
"that", "these", "those", "i", "you", "we", "they", "it",
|
|
53
|
+
"my", "your", "our", "their", "its", "please", "help", "me",
|
|
54
|
+
"want", "need", "like", "to", "for", "with", "on", "in", "at",
|
|
55
|
+
]);
|
|
56
|
+
const words = prompt.toLowerCase()
|
|
57
|
+
.replace(/[^\w\s]/g, " ")
|
|
58
|
+
.split(/\s+/)
|
|
59
|
+
.filter(w => w.length > 2 && !stopWords.has(w));
|
|
60
|
+
return words.slice(0, 5).join(" ");
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get guidance text for each pattern type
|
|
64
|
+
*/
|
|
65
|
+
function getPatternGuidance(pattern) {
|
|
66
|
+
const guidance = {
|
|
67
|
+
preference: "This is a preference/convention question. Relevant directives and decisions found:",
|
|
68
|
+
recall: "Recalled memories matching this request:",
|
|
69
|
+
analysis: "This request involves analysis/research. Relevant prior context found:",
|
|
70
|
+
implementation: "This request involves implementation. Relevant patterns/solutions found:",
|
|
71
|
+
error: "This request mentions an error/bug. Relevant prior fixes found:",
|
|
72
|
+
};
|
|
73
|
+
return guidance[pattern] || "Relevant memories found:";
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Extract user message text from message parts.
|
|
77
|
+
*/
|
|
78
|
+
export function extractMessageText(parts) {
|
|
79
|
+
return parts
|
|
80
|
+
.filter(p => p.type === "text" && p.text)
|
|
81
|
+
.map(p => p.text)
|
|
82
|
+
.join("\n");
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Handle a new user message — detect patterns and recall relevant memories.
|
|
86
|
+
*
|
|
87
|
+
* Returns additional context text to inject, or null if no recall needed.
|
|
88
|
+
*/
|
|
89
|
+
export async function handleUserMessage(messageText) {
|
|
90
|
+
if (!messageText)
|
|
91
|
+
return null;
|
|
92
|
+
// Reset recall status for new user turn
|
|
93
|
+
resetRecallStatus();
|
|
94
|
+
// Persist the user's prompt for intent detection in tool hooks
|
|
95
|
+
setCurrentPrompt(messageText);
|
|
96
|
+
// Skip if recall was already done this turn
|
|
97
|
+
if (wasRecallDoneThisTurn())
|
|
98
|
+
return null;
|
|
99
|
+
// Check server health
|
|
100
|
+
const healthy = await checkHealth();
|
|
101
|
+
if (!healthy)
|
|
102
|
+
return null;
|
|
103
|
+
// Store the user's topic for cross-hook context
|
|
104
|
+
const keyTerms = extractKeyTerms(messageText);
|
|
105
|
+
if (keyTerms) {
|
|
106
|
+
setCurrentTopic(keyTerms);
|
|
107
|
+
}
|
|
108
|
+
// Detect pattern category
|
|
109
|
+
const pattern = detectPattern(messageText);
|
|
110
|
+
if (!pattern)
|
|
111
|
+
return null;
|
|
112
|
+
try {
|
|
113
|
+
const patternQueries = PATTERNS[pattern].queries;
|
|
114
|
+
const query = `${keyTerms} ${patternQueries[0]}`.trim();
|
|
115
|
+
const client = getClient();
|
|
116
|
+
const result = await client.recall({ query, limit: 10 });
|
|
117
|
+
markRecallDone(query);
|
|
118
|
+
if (result.memories.length === 0)
|
|
119
|
+
return null;
|
|
120
|
+
const guidance = getPatternGuidance(pattern);
|
|
121
|
+
const recallOutput = formatRecallResult(result, query);
|
|
122
|
+
return `${guidance}\n\n${recallOutput}`;
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message.js","sourceRoot":"","sources":["../../../src/hooks/message.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session lifecycle hooks for MemoryLayer OpenCode plugin.
|
|
3
|
+
*
|
|
4
|
+
* Handles session initialization (briefing, directives, sandbox state)
|
|
5
|
+
* and session teardown (commit working memory, end session).
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Initialize a MemoryLayer session and return formatted context for system prompt injection.
|
|
9
|
+
*
|
|
10
|
+
* Called from the `experimental.chat.system.transform` hook on the first message
|
|
11
|
+
* of a session, or from the `event` hook on session start.
|
|
12
|
+
*/
|
|
13
|
+
export declare function initializeSession(topic?: string): Promise<string | null>;
|
|
14
|
+
/**
|
|
15
|
+
* Finalize the MemoryLayer session — commit working memory and end session.
|
|
16
|
+
*
|
|
17
|
+
* Called when the OpenCode session ends. Best-effort: never throws.
|
|
18
|
+
*/
|
|
19
|
+
export declare function finalizeSession(): Promise<void>;
|
|
20
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/hooks/session.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAsBH;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA0D9E;AAED;;;;GAIG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CA4BrD"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session lifecycle hooks for MemoryLayer OpenCode plugin.
|
|
3
|
+
*
|
|
4
|
+
* Handles session initialization (briefing, directives, sandbox state)
|
|
5
|
+
* and session teardown (commit working memory, end session).
|
|
6
|
+
*/
|
|
7
|
+
import { getClient, checkHealth } from "../shared/client.js";
|
|
8
|
+
import { formatSessionStart } from "../shared/formatters.js";
|
|
9
|
+
import { markRecallDone, resetRecallStatus, updateSessionInfo } from "../shared/state.js";
|
|
10
|
+
/**
|
|
11
|
+
* Check for existing sandbox state from a prior session or pre-compaction.
|
|
12
|
+
*/
|
|
13
|
+
async function checkSandboxState(client) {
|
|
14
|
+
try {
|
|
15
|
+
const status = await client.contextStatus();
|
|
16
|
+
if (status.exists && (status.variable_count ?? 0) > 0) {
|
|
17
|
+
return await client.contextInspect({});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
// Context environment may not be available
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Initialize a MemoryLayer session and return formatted context for system prompt injection.
|
|
27
|
+
*
|
|
28
|
+
* Called from the `experimental.chat.system.transform` hook on the first message
|
|
29
|
+
* of a session, or from the `event` hook on session start.
|
|
30
|
+
*/
|
|
31
|
+
export async function initializeSession(topic) {
|
|
32
|
+
const healthy = await checkHealth();
|
|
33
|
+
if (!healthy) {
|
|
34
|
+
return "MemoryLayer server not reachable. Memory features unavailable this session.";
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const client = getClient();
|
|
38
|
+
// Start server session
|
|
39
|
+
let sessionId;
|
|
40
|
+
try {
|
|
41
|
+
const sessionResult = await client.startSession({ ttl_seconds: 3600 });
|
|
42
|
+
sessionId = sessionResult.session_id;
|
|
43
|
+
const workspaceId = client.getWorkspaceId();
|
|
44
|
+
if (workspaceId) {
|
|
45
|
+
updateSessionInfo(workspaceId, sessionId);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Session start failed, continue without session management
|
|
50
|
+
}
|
|
51
|
+
// Reset recall status for new session
|
|
52
|
+
resetRecallStatus();
|
|
53
|
+
// Run briefing, directive recall, and sandbox check in parallel
|
|
54
|
+
const [briefingResult, directiveResult, sandboxResult] = await Promise.allSettled([
|
|
55
|
+
client.getBriefing({ limit: 10, includeMemories: false }),
|
|
56
|
+
client.recall({
|
|
57
|
+
query: "user directives and preferences",
|
|
58
|
+
subtypes: ["directive", "preference"],
|
|
59
|
+
limit: 10,
|
|
60
|
+
}),
|
|
61
|
+
checkSandboxState(client),
|
|
62
|
+
]);
|
|
63
|
+
const briefing = briefingResult.status === "fulfilled" ? briefingResult.value : null;
|
|
64
|
+
const directives = directiveResult.status === "fulfilled"
|
|
65
|
+
? directiveResult.value.memories
|
|
66
|
+
: [];
|
|
67
|
+
const sandboxState = sandboxResult.status === "fulfilled" ? sandboxResult.value : null;
|
|
68
|
+
// If there's a topic, recall for it too
|
|
69
|
+
let topicRecall = null;
|
|
70
|
+
if (topic) {
|
|
71
|
+
try {
|
|
72
|
+
topicRecall = await client.recall({ query: topic, limit: 10, detail_level: "abstract" });
|
|
73
|
+
markRecallDone(topic);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// Topic recall is optional
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return formatSessionStart(briefing, directives, topicRecall, topic, sandboxState);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
return `MemoryLayer session error: ${error instanceof Error ? error.message : error}`;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Finalize the MemoryLayer session — commit working memory and end session.
|
|
87
|
+
*
|
|
88
|
+
* Called when the OpenCode session ends. Best-effort: never throws.
|
|
89
|
+
*/
|
|
90
|
+
export async function finalizeSession() {
|
|
91
|
+
const healthy = await checkHealth();
|
|
92
|
+
if (!healthy)
|
|
93
|
+
return;
|
|
94
|
+
const client = getClient();
|
|
95
|
+
const sessionId = client.getSessionId();
|
|
96
|
+
if (!sessionId)
|
|
97
|
+
return;
|
|
98
|
+
try {
|
|
99
|
+
// Commit working memory to long-term storage
|
|
100
|
+
try {
|
|
101
|
+
await client.commitSession(sessionId, { importance_threshold: 0.5 });
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// Commit may fail if session expired
|
|
105
|
+
}
|
|
106
|
+
// End the server session
|
|
107
|
+
try {
|
|
108
|
+
await client.endSession(sessionId, {
|
|
109
|
+
commit: true,
|
|
110
|
+
importance_threshold: 0.5,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// Session may already be ended
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
// Best-effort — don't fail on shutdown
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/hooks/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool execution hooks for MemoryLayer OpenCode plugin.
|
|
3
|
+
*
|
|
4
|
+
* Before-tool: Injects relevant memory context for write/delegation tools.
|
|
5
|
+
* After-tool: Silently captures tool observations as working memory.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Handle before-tool execution.
|
|
9
|
+
*
|
|
10
|
+
* In OpenCode's hook system, this is called via "tool.execute.before" with
|
|
11
|
+
* (input, output) where we can mutate output.args. We use the return value
|
|
12
|
+
* pattern here and let the entry point handle injection.
|
|
13
|
+
*
|
|
14
|
+
* Returns additional context text, or null.
|
|
15
|
+
*/
|
|
16
|
+
export declare function handleToolBefore(toolName: string, toolArgs: Record<string, unknown>): Promise<string | null>;
|
|
17
|
+
/**
|
|
18
|
+
* Handle after-tool execution — capture observations as working memory.
|
|
19
|
+
*
|
|
20
|
+
* Returns additional context guidance for significant events, or null.
|
|
21
|
+
*/
|
|
22
|
+
export declare function handleToolAfter(toolName: string, toolArgs: Record<string, unknown>, toolOutput: string): Promise<string | null>;
|
|
23
|
+
//# sourceMappingURL=tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../../src/hooks/tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoFH;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAcxB;AAyDD;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyBxB"}
|