opencode-deja 0.21.5 → 0.21.7
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 +1 -1
- package/index.js +24 -7
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
English | [中文](https://github.com/vshulcz/deja-vu/blob/main/extensions/opencode/docs/zh.md)
|
|
4
4
|
|
|
5
5
|
opencode remembers its own sessions. This plugin answers the other question:
|
|
6
|
-
what you did in the thirty-
|
|
6
|
+
what you did in the thirty-seven other coding agents on this machine — Claude Code,
|
|
7
7
|
Codex, Cursor, Gemini and Zed among them — including the months before you
|
|
8
8
|
installed anything.
|
|
9
9
|
|
package/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// opencode-deja — the sessions you already have, inside opencode.
|
|
2
2
|
//
|
|
3
3
|
// opencode remembers its own sessions. This plugin answers the other question:
|
|
4
|
-
// what you did in Claude Code, Codex, Cursor, Gemini and thirty-
|
|
4
|
+
// what you did in Claude Code, Codex, Cursor, Gemini and thirty-four more agents on
|
|
5
5
|
// this machine, including months before deja existed. The index is deja's; this
|
|
6
6
|
// file is the seam: six tools the model can call, plus recall that arrives
|
|
7
7
|
// without being asked for.
|
|
@@ -166,6 +166,8 @@ export const DejaPlugin = async ({ client, directory }, options = {}) => {
|
|
|
166
166
|
// again. Counted, so a store that really is empty is still only asked a few
|
|
167
167
|
// times.
|
|
168
168
|
const empties = new Map()
|
|
169
|
+
// Sessions between their compacting hook and the summary request.
|
|
170
|
+
const compacting = new Set()
|
|
169
171
|
// Every session the per-prompt hook stamped live. opencode never says a
|
|
170
172
|
// session ended, so without ending them here the stamp sat out its whole
|
|
171
173
|
// window and the next session's MCP recall left a finished one out (#4546).
|
|
@@ -204,7 +206,7 @@ export const DejaPlugin = async ({ client, directory }, options = {}) => {
|
|
|
204
206
|
const specs = {
|
|
205
207
|
deja_recall: {
|
|
206
208
|
description:
|
|
207
|
-
"Search this machine's own past AI coding sessions — every agent used on it, including months before deja was installed. Use before debugging an error or re-implementing anything that may already exist. Match on the most specific token available: an exact error string, function name, file path or flag.",
|
|
209
|
+
"Search this machine's own past AI coding sessions — every agent used on it, including months before deja was installed. Use before debugging an error or re-implementing anything that may already exist, and before changing code, config, a dependency or a schedule. Match on the most specific token available: an exact error string, function name, file path or flag.",
|
|
208
210
|
args: {
|
|
209
211
|
query: { type: "string", description: "Specific tokens to match. Several words are ANDed." },
|
|
210
212
|
limit: { type: "number", optional: true, description: "How many sessions to return. Default 5." },
|
|
@@ -281,6 +283,10 @@ export const DejaPlugin = async ({ client, directory }, options = {}) => {
|
|
|
281
283
|
// the same place Claude Code's SessionStart output lands.
|
|
282
284
|
hooks["experimental.chat.system.transform"] = async (input, output) => {
|
|
283
285
|
try {
|
|
286
|
+
// The summary request is the last one a compaction makes, and the digest
|
|
287
|
+
// has no business in it: asked here, deja would hand the summariser the
|
|
288
|
+
// recovery packet meant for the turn after.
|
|
289
|
+
if (input?.sessionID && compacting.delete(input.sessionID)) return
|
|
284
290
|
const key = input?.sessionID || "default"
|
|
285
291
|
if (!digests.has(key)) {
|
|
286
292
|
// The session id, as the plugin `deja install opencode-auto` writes
|
|
@@ -306,7 +312,9 @@ export const DejaPlugin = async ({ client, directory }, options = {}) => {
|
|
|
306
312
|
// opencode sends each entry as its own system message, and a backend
|
|
307
313
|
// whose template allows one (vLLM or SGLang serving Qwen) rejects the
|
|
308
314
|
// request: "System message must be at the beginning." (#4058)
|
|
309
|
-
|
|
315
|
+
// After opencode's own prompt, not before it: that prompt is the same
|
|
316
|
+
// in every session and is what the provider's prompt cache keeps.
|
|
317
|
+
if (output.system.length) output.system[0] = output.system[0] + "\n\n" + context
|
|
310
318
|
else output.system.push(context)
|
|
311
319
|
return
|
|
312
320
|
}
|
|
@@ -335,6 +343,11 @@ export const DejaPlugin = async ({ client, directory }, options = {}) => {
|
|
|
335
343
|
// by what the user just asked. Silent when nothing matches.
|
|
336
344
|
hooks["experimental.chat.messages.transform"] = async (input, output) => {
|
|
337
345
|
try {
|
|
346
|
+
// The compaction's own request runs this transform right after the
|
|
347
|
+
// compacting hook. Recall there would land in the summariser's input and
|
|
348
|
+
// the recovery packet would count as delivered to a turn that never saw it.
|
|
349
|
+
const owner = (output?.messages || []).find((m) => m?.info?.sessionID)?.info?.sessionID
|
|
350
|
+
if (owner && compacting.has(owner)) return
|
|
338
351
|
const { parts, prompt, sessionID } = lastUserText(output?.messages)
|
|
339
352
|
// A turn with no text, an image alone, still goes to hook-prompt: that
|
|
340
353
|
// call is what stamps the session live again after session.idle ended
|
|
@@ -356,11 +369,15 @@ export const DejaPlugin = async ({ client, directory }, options = {}) => {
|
|
|
356
369
|
}
|
|
357
370
|
}
|
|
358
371
|
|
|
359
|
-
// Compaction is about to
|
|
360
|
-
//
|
|
361
|
-
|
|
372
|
+
// Compaction is about to summarise the session away. The turns are still in
|
|
373
|
+
// opencode's store, so deja reads them by the session id and keeps a
|
|
374
|
+
// recovery packet — commands, how they went, what was open — for the next
|
|
375
|
+
// turn, as Claude Code gets through PreCompact.
|
|
376
|
+
hooks["experimental.session.compacting"] = async (input) => {
|
|
362
377
|
try {
|
|
363
|
-
|
|
378
|
+
const sessionID = input?.sessionID || ""
|
|
379
|
+
if (sessionID) compacting.add(sessionID)
|
|
380
|
+
await ask(["hook-precompact"], JSON.stringify({ session_id: sessionID, cwd, harness: "opencode" }), 60000)
|
|
364
381
|
} catch {
|
|
365
382
|
// memory is optional: never break a compaction over it
|
|
366
383
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-deja",
|
|
3
|
-
"version": "0.21.
|
|
4
|
-
"description": "deja-vu memory for opencode: the session history of thirty-
|
|
3
|
+
"version": "0.21.7",
|
|
4
|
+
"description": "deja-vu memory for opencode: the session history of thirty-seven other coding agents, searchable and recalled on every request — a local index, no LLM.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"exports": {
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@opencode-ai/plugin": ">=1.0.0",
|
|
55
|
-
"@vshulcz/deja-vu": "^0.21.
|
|
55
|
+
"@vshulcz/deja-vu": "^0.21.7"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
58
|
"test": "node --test test/*.test.js"
|