dsh-deja 0.22.2 → 0.23.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.
Files changed (3) hide show
  1. package/index.js +14 -9
  2. package/lib.js +12 -0
  3. package/package.json +2 -2
package/index.js CHANGED
@@ -12,7 +12,7 @@ import { existsSync } from "node:fs";
12
12
  import { homedir } from "node:os";
13
13
  import { join } from "node:path";
14
14
 
15
- import { argv, contributions, exitStatus, guarded, newestEvents, noteBoard, resultText, splitHookReply } from "./lib.js";
15
+ import { argv, contributions, exitStatus, guarded, inert, newestEvents, noteBoard, resultText, splitHookReply } from "./lib.js";
16
16
 
17
17
  const require = createRequire(import.meta.url);
18
18
 
@@ -282,19 +282,20 @@ function autoDigest(ctx, board) {
282
282
  ctx.systemPrompt.context({
283
283
  name: "deja:project",
284
284
  order: 110,
285
+ interpolate: false,
285
286
  text: (assembly) => {
286
287
  const agent = assembly && assembly.agent;
287
288
  if (!agent) return "";
288
289
  const sid = sessionId(agent);
289
290
  if (sid && seen.has(sid)) return "";
290
291
  if (sid) seen.add(sid);
291
- return askHook(
292
+ return inert(askHook(
292
293
  ["hook-context", "--plain"],
293
294
  ["hook-context"],
294
295
  JSON.stringify({ session_id: sid, cwd: sessionCwd(agent), source: "startup", deja_once: true }),
295
296
  sid,
296
297
  board,
297
- );
298
+ ));
298
299
  },
299
300
  }),
300
301
  );
@@ -344,6 +345,7 @@ function autoRecall(ctx, board) {
344
345
  ctx.systemPrompt.context({
345
346
  name: "deja:recall",
346
347
  order: 120,
348
+ interpolate: false,
347
349
  text: (assembly) => {
348
350
  const agent = assembly && assembly.agent;
349
351
  if (!agent) return "";
@@ -360,13 +362,13 @@ function autoRecall(ctx, board) {
360
362
  asked = prompt;
361
363
  askedIn = cwd;
362
364
  askedBy = sid;
363
- recalled = askHook(
365
+ recalled = inert(askHook(
364
366
  ["hook-prompt", "--plain"],
365
367
  ["hook-prompt"],
366
368
  JSON.stringify({ prompt, cwd, session_id: sid }),
367
369
  sid,
368
370
  board,
369
- );
371
+ ));
370
372
  }
371
373
  // Silence is the common case: this speaks only when the history answers.
372
374
  return recalled;
@@ -505,20 +507,23 @@ function toolNotes(ctx) {
505
507
  // be answered with it now rather than twenty minutes from now.
506
508
  function sessionEnds(ctx) {
507
509
  if (typeof ctx.on !== "function") return;
508
- const live = new Set();
510
+ // Each live session with the directory it opened in: the end refreshes that
511
+ // project's start digest, so the next session there sees this one.
512
+ const live = new Map();
509
513
  const end = (sid) => {
510
514
  if (!sid || !live.has(sid)) return;
515
+ const cwd = live.get(sid);
511
516
  live.delete(sid);
512
- run(["hook-session-end"], JSON.stringify({ session_id: sid }));
517
+ run(["hook-session-end"], JSON.stringify({ session_id: sid, cwd }));
513
518
  };
514
519
  try {
515
520
  ctx.on("session/created", (session) => {
516
521
  const sid = bareSessionId(session && session.id);
517
- if (sid) live.add(sid);
522
+ if (sid) live.set(sid, (session.header && session.header.cwd) || process.cwd());
518
523
  });
519
524
  ctx.on("session/disposed", (session) => end(bareSessionId(session && session.id)));
520
525
  process.on("exit", () => {
521
- for (const sid of [...live]) end(sid);
526
+ for (const sid of [...live.keys()]) end(sid);
522
527
  });
523
528
  } catch {}
524
529
  }
package/lib.js CHANGED
@@ -62,6 +62,18 @@ export function exitStatus(text) {
62
62
  return { body: text, failed: false };
63
63
  }
64
64
 
65
+ // inert keeps recalled text out of dsh's prompt templating. dsh reads every
66
+ // {{name}} in a context as a prompt variable and throws on one it does not
67
+ // know, which ends the turn before the model is called. Past sessions quote
68
+ // templates, and that very error, so one recall carrying {{cwd}} broke every
69
+ // turn after it (#5421). `interpolate: false` tells dsh 0.2.1-alpha.2 and later
70
+ // to leave the text alone; older hosts ignore it, and a listener on
71
+ // system-prompt/assemble may drop it, so the braces are split as well:
72
+ // { {cwd} } still reads as braces and holds no {{ to resolve.
73
+ export function inert(text) {
74
+ return String(text || "").replace(/\{(?=\{)/g, "{ ").replace(/\}(?=\})/g, "} ");
75
+ }
76
+
65
77
  // contributions says what this package adds, given what `deja install` already
66
78
  // wrote into DSH_HOME and what the profile turned off. The rule is the same
67
79
  // everywhere: fill the gaps, never repeat the installer.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-deja",
3
- "version": "0.22.2",
3
+ "version": "0.23.0",
4
4
  "description": "deja-vu memory for DeepSeek Harness: the session history of forty-one other coding agents, searchable and recalled before each step — a local index, no LLM.",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -68,7 +68,7 @@
68
68
  }
69
69
  },
70
70
  "dependencies": {
71
- "@vshulcz/deja-vu": "^0.22.2"
71
+ "@vshulcz/deja-vu": "^0.23.0"
72
72
  },
73
73
  "scripts": {
74
74
  "test": "node --test test/*.test.js"