@aexol/spectral 0.9.184 → 0.9.186

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 (60) hide show
  1. package/dist/agent/index.d.ts.map +1 -1
  2. package/dist/agent/index.js +8 -2
  3. package/dist/memory/branch.d.ts +13 -0
  4. package/dist/memory/branch.d.ts.map +1 -1
  5. package/dist/memory/branch.js +100 -0
  6. package/dist/memory/hooks/compaction-hook.d.ts.map +1 -1
  7. package/dist/memory/hooks/compaction-hook.js +43 -1
  8. package/dist/memory/hooks/observer-trigger.d.ts.map +1 -1
  9. package/dist/memory/hooks/observer-trigger.js +9 -3
  10. package/dist/memory/index.d.ts +13 -0
  11. package/dist/memory/index.d.ts.map +1 -1
  12. package/dist/memory/index.js +17 -26
  13. package/dist/memory/project-observation-memory.d.ts +16 -0
  14. package/dist/memory/project-observation-memory.d.ts.map +1 -0
  15. package/dist/memory/project-observation-memory.js +27 -0
  16. package/dist/memory/project-observations-store.d.ts +8 -0
  17. package/dist/memory/project-observations-store.d.ts.map +1 -1
  18. package/dist/memory/project-observations-store.js +5 -0
  19. package/dist/memory/prompts.d.ts +2 -2
  20. package/dist/memory/prompts.d.ts.map +1 -1
  21. package/dist/memory/prompts.js +1 -1
  22. package/dist/memory/session-memory.d.ts +21 -0
  23. package/dist/memory/session-memory.d.ts.map +1 -0
  24. package/dist/memory/session-memory.js +33 -0
  25. package/dist/memory/tool-output-compressor.d.ts +0 -1
  26. package/dist/memory/tool-output-compressor.d.ts.map +1 -1
  27. package/dist/memory/tool-output-compressor.js +0 -1
  28. package/dist/memory/tools/compact-context.d.ts +31 -0
  29. package/dist/memory/tools/compact-context.d.ts.map +1 -1
  30. package/dist/memory/tools/compact-context.js +224 -23
  31. package/dist/memory/tools/read-project-observations.d.ts.map +1 -1
  32. package/dist/memory/tools/read-project-observations.js +6 -3
  33. package/dist/memory/tools/recall-observation.d.ts.map +1 -1
  34. package/dist/memory/tools/recall-observation.js +18 -4
  35. package/dist/memory/tools/receive-agent-observations.d.ts.map +1 -1
  36. package/dist/memory/tools/receive-agent-observations.js +4 -2
  37. package/dist/memory/tools/share-project-observation.d.ts.map +1 -1
  38. package/dist/memory/tools/share-project-observation.js +5 -3
  39. package/dist/memory/tools/write-project-observation.d.ts.map +1 -1
  40. package/dist/memory/tools/write-project-observation.js +16 -3
  41. package/dist/sdk/coding-agent/core/agent-session.d.ts.map +1 -1
  42. package/dist/sdk/coding-agent/core/agent-session.js +0 -1
  43. package/dist/sdk/coding-agent/core/compaction/compaction.d.ts +11 -0
  44. package/dist/sdk/coding-agent/core/compaction/compaction.d.ts.map +1 -1
  45. package/dist/sdk/coding-agent/core/compaction/compaction.js +15 -2
  46. package/dist/sdk/coding-agent/core/compaction/policy.d.ts +22 -4
  47. package/dist/sdk/coding-agent/core/compaction/policy.d.ts.map +1 -1
  48. package/dist/sdk/coding-agent/core/compaction/policy.js +39 -6
  49. package/dist/server/inter-agent-broker.d.ts +12 -7
  50. package/dist/server/inter-agent-broker.d.ts.map +1 -1
  51. package/dist/server/inter-agent-broker.js +12 -7
  52. package/dist/server/session-stream.d.ts.map +1 -1
  53. package/dist/server/session-stream.js +6 -4
  54. package/dist/server/sqlite-adapter.d.ts +11 -8
  55. package/dist/server/sqlite-adapter.d.ts.map +1 -1
  56. package/dist/server/sqlite-adapter.js +195 -44
  57. package/dist/server/storage.d.ts +22 -5
  58. package/dist/server/storage.d.ts.map +1 -1
  59. package/dist/server/storage.js +52 -6
  60. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agent/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAIX,SAAS,EAET,MAAM,4BAA4B,CAAC;AASpC,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EACN,KAAK,WAAW,EAKhB,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAQrD,OAAO,KAAK,EAAE,gBAAgB,IAAI,oBAAoB,EAAE,MAAM,8CAA8C,CAAC;AAuG7G;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACxC,gBAAgB,EAAE,MAAM,GAAG,SAAS,EACpC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,GAAG,cAAc,GAAG,OAAO,GAAG,QAAQ,CAAC,GACpF,MAAM,CAYR;AA0JD;;;GAGG;AACH,wBAAgB,oCAAoC,CACnD,cAAc,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,GAChD,IAAI,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,EAAE,WAAW,CAAC,CAK3D;AAoBD,wBAAgB,oBAAoB,CACnC,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,YAAY,EACjB,GAAG,EAAE,gBAAgB,GACnB,SAAS,EAAE,CAoCb;AA6bD,MAAM,CAAC,OAAO,UAAU,iBAAiB,CACxC,GAAG,EAAE,YAAY,EACjB,IAAI,CAAC,EAAE;IACN,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB,GACC,IAAI,CAgaN"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agent/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAIX,SAAS,EAET,MAAM,4BAA4B,CAAC;AAUpC,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EACN,KAAK,WAAW,EAKhB,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAQrD,OAAO,KAAK,EAAE,gBAAgB,IAAI,oBAAoB,EAAE,MAAM,8CAA8C,CAAC;AAuG7G;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACxC,gBAAgB,EAAE,MAAM,GAAG,SAAS,EACpC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,GAAG,cAAc,GAAG,OAAO,GAAG,QAAQ,CAAC,GACpF,MAAM,CAYR;AA0JD;;;GAGG;AACH,wBAAgB,oCAAoC,CACnD,cAAc,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,GAChD,IAAI,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,EAAE,WAAW,CAAC,CAK3D;AAoBD,wBAAgB,oBAAoB,CACnC,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,YAAY,EACjB,GAAG,EAAE,gBAAgB,GACnB,SAAS,EAAE,CAoCb;AAycD,MAAM,CAAC,OAAO,UAAU,iBAAiB,CACxC,GAAG,EAAE,YAAY,EACjB,IAAI,CAAC,EAAE;IACN,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB,GACC,IAAI,CAgaN"}
@@ -25,7 +25,7 @@
25
25
  * - Access to observational memory via the recall tool
26
26
  */
27
27
  import { agentLoop } from "../sdk/agent-core/index.js";
28
- import { buildIsolatedRequestTimePrunedMessages, COMPACT_CONTEXT_TOOL_NAME, } from "../memory/tools/compact-context.js";
28
+ import { buildIsolatedRequestTimePrunedMessagesResult, COMPACT_CONTEXT_TOOL_NAME, } from "../memory/tools/compact-context.js";
29
29
  import { StringEnum } from "../sdk/ai/index.js";
30
30
  import { mutateSystemPrompt } from "../sdk/coding-agent/core/system-prompt-mutator.js";
31
31
  import { Type } from "typebox";
@@ -445,6 +445,10 @@ async function runSingleAgent(defaultCwd, agents, agentName, task, cwd, step, si
445
445
  // Accumulated thinking deltas for the live subagent sheet. This stays outside
446
446
  // final `SingleResult` so the public subagent tool_result contract is unchanged.
447
447
  let thinkingText = "";
448
+ // Per-run frozen DCP-lite cut for the isolated subagent loop. Reusing the
449
+ // same summary + anchor across provider requests keeps the subagent prompt
450
+ // prefix byte-stable within a single run.
451
+ let isolatedPruneFrozen = null;
448
452
  // Responses API reasoning metadata that lets the UI classify accumulated
449
453
  // subagent thinking as activity (mirrors the main-session thinking metadata).
450
454
  let thinkingMetadata;
@@ -474,7 +478,9 @@ async function runSingleAgent(defaultCwd, agents, agentName, task, cwd, step, si
474
478
  // Pure request-time DCP adapter: policy-derived, invocation-local, and
475
479
  // never connected to the parent Runtime or SessionManager.
476
480
  try {
477
- return buildIsolatedRequestTimePrunedMessages(messages);
481
+ const pruned = buildIsolatedRequestTimePrunedMessagesResult(messages, undefined, undefined, isolatedPruneFrozen, model.contextWindow);
482
+ isolatedPruneFrozen = pruned.frozen;
483
+ return pruned.messages;
478
484
  }
479
485
  catch {
480
486
  return messages;
@@ -121,4 +121,17 @@ export interface MemoryState {
121
121
  pendingObs: ObservationRecord[];
122
122
  }
123
123
  export declare function getMemoryState(entries: Entry[]): MemoryState;
124
+ /**
125
+ * Build a synthetic branch entry array that is sufficient for
126
+ * `recallMemorySources` to recover the same memory id outside of its original
127
+ * session/branch.
128
+ *
129
+ * This is the cross-session recall archive unit: it contains only the source
130
+ * entries referenced by the requested observation/reflection, the observation
131
+ * entries needed to resolve direct and supporting observations, and (for
132
+ * reflections) a restored-memory snapshot entry carrying the reflection
133
+ * provenance. It is deliberately keyed by memory id so it can be persisted in
134
+ * the project-scoped store without dragging the whole branch along.
135
+ */
136
+ export declare function buildRecallSourceArchiveEntries(entries: Entry[], memoryState: Pick<MemoryState, "reflections" | "committedObs" | "pendingObs">, memoryId: string): Entry[] | undefined;
124
137
  //# sourceMappingURL=branch.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"branch.d.ts","sourceRoot":"","sources":["../../src/memory/branch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"branch.d.ts","sourceRoot":"","sources":["../../src/memory/branch.ts"],"names":[],"mappings":"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"}
@@ -468,3 +468,103 @@ export function getMemoryState(entries) {
468
468
  pendingObs: pendingData.flatMap((d) => d.records),
469
469
  };
470
470
  }
471
+ /**
472
+ * Build a synthetic branch entry array that is sufficient for
473
+ * `recallMemorySources` to recover the same memory id outside of its original
474
+ * session/branch.
475
+ *
476
+ * This is the cross-session recall archive unit: it contains only the source
477
+ * entries referenced by the requested observation/reflection, the observation
478
+ * entries needed to resolve direct and supporting observations, and (for
479
+ * reflections) a restored-memory snapshot entry carrying the reflection
480
+ * provenance. It is deliberately keyed by memory id so it can be persisted in
481
+ * the project-scoped store without dragging the whole branch along.
482
+ */
483
+ export function buildRecallSourceArchiveEntries(entries, memoryState, memoryId) {
484
+ const allObservations = [...memoryState.committedObs, ...memoryState.pendingObs];
485
+ const selectedObservationRecords = [];
486
+ const seenObservationKeys = new Set();
487
+ const recordKey = (observation) => [
488
+ observation.id,
489
+ observation.content,
490
+ observation.timestamp,
491
+ observation.relevance,
492
+ JSON.stringify(observation.sourceEntryIds ?? null),
493
+ ].join("\u0000");
494
+ const addObservation = (observation) => {
495
+ const key = recordKey(observation);
496
+ if (seenObservationKeys.has(key))
497
+ return;
498
+ seenObservationKeys.add(key);
499
+ selectedObservationRecords.push(observation);
500
+ };
501
+ for (const observation of allObservations) {
502
+ if (observation.id === memoryId)
503
+ addObservation(observation);
504
+ }
505
+ const reflections = [];
506
+ for (const reflection of memoryState.reflections) {
507
+ if (!isReflectionRecord(reflection) || reflection.id !== memoryId)
508
+ continue;
509
+ reflections.push(reflection);
510
+ for (const observationId of reflection.supportingObservationIds) {
511
+ for (const observation of allObservations) {
512
+ if (observation.id === observationId)
513
+ addObservation(observation);
514
+ }
515
+ }
516
+ }
517
+ if (reflections.length === 0 && selectedObservationRecords.length === 0) {
518
+ return undefined;
519
+ }
520
+ const sourceEntryIds = new Set();
521
+ for (const observation of selectedObservationRecords) {
522
+ for (const sourceEntryId of observation.sourceEntryIds ?? []) {
523
+ sourceEntryIds.add(sourceEntryId);
524
+ }
525
+ }
526
+ const sourceEntries = entries.filter((entry) => {
527
+ if (!isSourceEntry(entry))
528
+ return false;
529
+ for (const requestedId of sourceEntryIds) {
530
+ if (sourceEntryMatchesRequestedId(entry, requestedId))
531
+ return true;
532
+ }
533
+ return false;
534
+ });
535
+ const archiveEntries = [...sourceEntries];
536
+ let observationEntryIndex = 0;
537
+ for (const observation of selectedObservationRecords) {
538
+ archiveEntries.push({
539
+ type: "custom",
540
+ id: `recall-archive-observation:${memoryId}:${observationEntryIndex++}`,
541
+ customType: OBSERVATION_CUSTOM_TYPE,
542
+ data: {
543
+ records: [observation],
544
+ coversFromId: "",
545
+ coversUpToId: "",
546
+ tokenCount: 0,
547
+ },
548
+ });
549
+ }
550
+ if (reflections.length > 0) {
551
+ archiveEntries.push({
552
+ type: "custom",
553
+ id: `recall-archive-snapshot:${memoryId}`,
554
+ customType: OBSERVATIONAL_MEMORY_SNAPSHOT_CUSTOM_TYPE,
555
+ data: {
556
+ type: "observational-memory-snapshot",
557
+ version: 1,
558
+ coveredSourceCount: sourceEntries.length,
559
+ summary: "",
560
+ details: {
561
+ type: "observational-memory",
562
+ version: 4,
563
+ observations: selectedObservationRecords,
564
+ reflections,
565
+ },
566
+ },
567
+ });
568
+ }
569
+ return archiveEntries;
570
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"compaction-hook.d.ts","sourceRoot":"","sources":["../../../src/memory/hooks/compaction-hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAA+C,MAAM,iCAAiC,CAAC;AAajH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAiB7C,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CA0MhF"}
1
+ {"version":3,"file":"compaction-hook.d.ts","sourceRoot":"","sources":["../../../src/memory/hooks/compaction-hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAA+C,MAAM,iCAAiC,CAAC;AAejH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAkB7C,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAkPhF"}
@@ -1,8 +1,9 @@
1
1
  import { debugLog, withDebugLogContext } from "../debug-log.js";
2
2
  import { getProjectObsStore } from "../project-observations-store.js";
3
3
  import { relayProjectObservations } from "../inter-agent-relay.js";
4
- import { collectObservationsByCoverage, findLastCompactionIndex, getMemoryState, } from "../branch.js";
4
+ import { buildRecallSourceArchiveEntries, collectObservationsByCoverage, findLastCompactionIndex, getMemoryState, } from "../branch.js";
5
5
  import { migrateLegacyReflections, renderSummary, } from "../compaction.js";
6
+ import { reflectionId, } from "../types.js";
6
7
  import { deterministicPrune } from "../deterministic-pruner.js";
7
8
  function plural(count, singular, pluralForm = `${singular}s`) {
8
9
  return `${count.toLocaleString()} ${count === 1 ? singular : pluralForm}`;
@@ -89,6 +90,7 @@ export function registerCompactionHook(ext, runtime) {
89
90
  if (hasUI)
90
91
  ui?.notify(`Observational memory: no new observations — carrying forward ${memoryState.committedObs.length} observation${memoryState.committedObs.length === 1 ? "" : "s"}, ${workingReflections.length} reflection${workingReflections.length === 1 ? "" : "s"}`, "info");
91
92
  persistProjectObservations(ctx, workingReflections);
93
+ persistProjectRecallSources(ctx, entries, memoryState.committedObs, workingReflections);
92
94
  return {
93
95
  compaction: {
94
96
  summary,
@@ -158,6 +160,7 @@ export function registerCompactionHook(ext, runtime) {
158
160
  if (hasUI)
159
161
  ui?.notify(`Observational memory: compaction assembled — ${finalObservations.length} observation${finalObservations.length === 1 ? "" : "s"}, ${finalReflections.length} reflection${finalReflections.length === 1 ? "" : "s"}`, "info");
160
162
  persistProjectObservations(ctx, finalReflections);
163
+ persistProjectRecallSources(ctx, entries, finalObservations, finalReflections);
161
164
  return {
162
165
  compaction: {
163
166
  summary,
@@ -197,4 +200,43 @@ export function registerCompactionHook(ext, runtime) {
197
200
  });
198
201
  relayProjectObservations(ctx.cwd, projectId, sessionId, projectObs, "reflection");
199
202
  }
203
+ function persistProjectRecallSources(ctx, entries, observations, reflections) {
204
+ const store = getProjectObsStore();
205
+ if (!store)
206
+ return;
207
+ const projectId = store.getProjectByCwd(ctx.cwd);
208
+ if (!projectId)
209
+ return;
210
+ const sessionId = ctx.sessionManager.getSessionId?.();
211
+ if (!sessionId)
212
+ return;
213
+ const memoryIds = new Set();
214
+ for (const observation of observations)
215
+ memoryIds.add(observation.id);
216
+ for (const reflection of reflections) {
217
+ const id = reflectionId(reflection);
218
+ if (id)
219
+ memoryIds.add(id);
220
+ }
221
+ if (memoryIds.size === 0)
222
+ return;
223
+ const memoryState = { reflections, committedObs: observations, pendingObs: [] };
224
+ let persisted = 0;
225
+ for (const memoryId of memoryIds) {
226
+ const existing = store.getProjectRecallSource?.(projectId, memoryId);
227
+ if (existing && existing.length > 0)
228
+ continue;
229
+ const archiveEntries = buildRecallSourceArchiveEntries(entries, memoryState, memoryId);
230
+ if (!archiveEntries || archiveEntries.length === 0)
231
+ continue;
232
+ store.upsertProjectRecallSource?.(projectId, memoryId, archiveEntries);
233
+ persisted += 1;
234
+ }
235
+ debugLog("compaction.project_recall_sources", {
236
+ projectId,
237
+ sessionId,
238
+ candidates: memoryIds.size,
239
+ persisted,
240
+ });
241
+ }
200
242
  }
@@ -1 +1 @@
1
- {"version":3,"file":"observer-trigger.d.ts","sourceRoot":"","sources":["../../../src/memory/hooks/observer-trigger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAWpE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAY7C,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CA8KjF"}
1
+ {"version":3,"file":"observer-trigger.d.ts","sourceRoot":"","sources":["../../../src/memory/hooks/observer-trigger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAapE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAY7C,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAmLjF"}
@@ -1,6 +1,6 @@
1
1
  import { debugLog, withDebugLogContext } from "../debug-log.js";
2
2
  import { resolveTurnLimits } from "../config.js";
3
- import { firstRawIdAfter, getMemoryState, lastObservationCoverEndIdx, rawTailEntriesBetween, rawTokensSinceLastBound, } from "../branch.js";
3
+ import { buildRecallSourceArchiveEntries, firstRawIdAfter, getMemoryState, lastObservationCoverEndIdx, rawTailEntriesBetween, rawTokensSinceLastBound, } from "../branch.js";
4
4
  import { observationsToPromptLines, runObserver } from "../observer.js";
5
5
  import { serializeSourceAddressedBranchEntries } from "../serialize.js";
6
6
  import { estimateEntryTokens, estimateStringTokens } from "../tokens.js";
@@ -153,7 +153,7 @@ export function registerObserverTrigger(ext, runtime) {
153
153
  records,
154
154
  });
155
155
  ext.appendEntry(OBSERVATION_CUSTOM_TYPE, data);
156
- relayObservationRecords(cwd, ctx.sessionManager.getSessionId?.(), records);
156
+ relayObservationRecords(cwd, ctx.sessionManager.getSessionId?.(), records, chunkEntries);
157
157
  debugLog("observer.appended", { count: records.length, tokenCount: observationTokens, coversFromId, coversUpToId: effectiveCoversUpToId });
158
158
  if (hasUI && ui)
159
159
  ui.notify(`Observational memory: ${records.length} observation${records.length === 1 ? "" : "s"} recorded (~${observationTokens.toLocaleString()} tokens)`, "info");
@@ -165,7 +165,7 @@ export function registerObserverTrigger(ext, runtime) {
165
165
  }));
166
166
  });
167
167
  }
168
- function relayObservationRecords(cwd, sessionId, records) {
168
+ function relayObservationRecords(cwd, sessionId, records, sourceEntries) {
169
169
  if (!sessionId || records.length === 0)
170
170
  return;
171
171
  const store = getProjectObsStore();
@@ -174,5 +174,11 @@ function relayObservationRecords(cwd, sessionId, records) {
174
174
  const projectId = store.getProjectByCwd(cwd);
175
175
  if (!projectId)
176
176
  return;
177
+ for (const record of records) {
178
+ const archiveEntries = buildRecallSourceArchiveEntries(sourceEntries, { reflections: [], committedObs: [record], pendingObs: [] }, record.id);
179
+ if (!archiveEntries || archiveEntries.length === 0)
180
+ continue;
181
+ store.upsertProjectRecallSource?.(projectId, record.id, archiveEntries);
182
+ }
177
183
  relayProjectObservations(cwd, projectId, sessionId, records, "observation");
178
184
  }
@@ -1,3 +1,16 @@
1
1
  import type { ExtensionAPI } from "../sdk/coding-agent/index.js";
2
+ /**
3
+ * Observational memory extension entry point.
4
+ *
5
+ * The extension is composed of two independent layers:
6
+ * - `session-memory.ts`: session/branch-scoped memory (observer,
7
+ * deterministic prune, summary render, session snapshot persistence).
8
+ * - `project-observation-memory.ts`: per-machine + per-cwd, cross-session
9
+ * project observations (write/read/recall/share/receive tools plus
10
+ * inter-agent broker wiring).
11
+ *
12
+ * This default export keeps the original registration contract so it is still
13
+ * registered exactly once as `observationalMemory(ext)`.
14
+ */
2
15
  export default function observationalMemory(ext: ExtensionAPI): void;
3
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/memory/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAgBjE,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAAC,GAAG,EAAE,YAAY,QAqB5D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/memory/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAKjE;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAAC,GAAG,EAAE,YAAY,QAQ5D"}
@@ -1,32 +1,23 @@
1
- import { registerStatusCommand } from "./commands/status.js";
2
- import { registerViewCommand } from "./commands/view.js";
3
- import { registerCompactionHook } from "./hooks/compaction-hook.js";
4
- import { registerCompactionTrigger } from "./hooks/compaction-trigger.js";
5
- import { registerInterAgentReceiver } from "./hooks/inter-agent-receiver.js";
6
- import { registerObserverTrigger } from "./hooks/observer-trigger.js";
7
1
  import { Runtime } from "./runtime.js";
8
- import { registerToolOutputCompressor } from "./tool-output-compressor.js";
9
- import { registerCompactContextTool } from "./tools/compact-context.js";
10
- import { registerRecallTool } from "./tools/recall-observation.js";
11
- import { registerReadProjectObservationsTool } from "./tools/read-project-observations.js";
12
- import { registerReceiveAgentObservationsTool } from "./tools/receive-agent-observations.js";
13
- import { registerShareProjectObservationTool } from "./tools/share-project-observation.js";
14
- import { registerWriteProjectObservationTool } from "./tools/write-project-observation.js";
2
+ import { registerProjectObservationMemory } from "./project-observation-memory.js";
3
+ import { registerSessionMemory } from "./session-memory.js";
4
+ /**
5
+ * Observational memory extension entry point.
6
+ *
7
+ * The extension is composed of two independent layers:
8
+ * - `session-memory.ts`: session/branch-scoped memory (observer,
9
+ * deterministic prune, summary render, session snapshot persistence).
10
+ * - `project-observation-memory.ts`: per-machine + per-cwd, cross-session
11
+ * project observations (write/read/recall/share/receive tools plus
12
+ * inter-agent broker wiring).
13
+ *
14
+ * This default export keeps the original registration contract so it is still
15
+ * registered exactly once as `observationalMemory(ext)`.
16
+ */
15
17
  export default function observationalMemory(ext) {
16
18
  const runtime = new Runtime();
17
19
  // Log extension load so we can confirm it's running in serve mode.
18
20
  process.stderr.write("[obs-mem] extension loaded\n");
19
- registerObserverTrigger(ext, runtime);
20
- registerCompactContextTool(ext, runtime);
21
- registerCompactionTrigger(ext, runtime);
22
- registerCompactionHook(ext, runtime);
23
- registerToolOutputCompressor(ext, runtime);
24
- registerStatusCommand(ext, runtime);
25
- registerViewCommand(ext, runtime);
26
- registerRecallTool(ext);
27
- registerReadProjectObservationsTool(ext);
28
- registerWriteProjectObservationTool(ext);
29
- registerShareProjectObservationTool(ext);
30
- registerReceiveAgentObservationsTool(ext);
31
- registerInterAgentReceiver(ext);
21
+ registerSessionMemory(ext, runtime);
22
+ registerProjectObservationMemory(ext);
32
23
  }
@@ -0,0 +1,16 @@
1
+ import type { ExtensionAPI } from "../sdk/coding-agent/index.js";
2
+ /**
3
+ * Project-observation memory layer.
4
+ *
5
+ * This layer owns the five project-observation tools
6
+ * (`write_project_observation`, `read_project_observations`, `recall`,
7
+ * `share_project_observation`, `receive_agent_observations`) plus the
8
+ * `project-observations-store.ts` shim and the inter-agent broker wiring.
9
+ *
10
+ * Storage is per-machine + per-cwd + cross-session: observations are keyed by
11
+ * the local project resolved from the absolute working directory and persisted
12
+ * in the same-machine SQLite store. There is no cloud/team sync and no
13
+ * cross-machine fan-out.
14
+ */
15
+ export declare function registerProjectObservationMemory(ext: ExtensionAPI): void;
16
+ //# sourceMappingURL=project-observation-memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-observation-memory.d.ts","sourceRoot":"","sources":["../../src/memory/project-observation-memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAQjE;;;;;;;;;;;;GAYG;AACH,wBAAgB,gCAAgC,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CAQxE"}
@@ -0,0 +1,27 @@
1
+ import { registerInterAgentReceiver } from "./hooks/inter-agent-receiver.js";
2
+ import { registerRecallTool } from "./tools/recall-observation.js";
3
+ import { registerReadProjectObservationsTool } from "./tools/read-project-observations.js";
4
+ import { registerReceiveAgentObservationsTool } from "./tools/receive-agent-observations.js";
5
+ import { registerShareProjectObservationTool } from "./tools/share-project-observation.js";
6
+ import { registerWriteProjectObservationTool } from "./tools/write-project-observation.js";
7
+ /**
8
+ * Project-observation memory layer.
9
+ *
10
+ * This layer owns the five project-observation tools
11
+ * (`write_project_observation`, `read_project_observations`, `recall`,
12
+ * `share_project_observation`, `receive_agent_observations`) plus the
13
+ * `project-observations-store.ts` shim and the inter-agent broker wiring.
14
+ *
15
+ * Storage is per-machine + per-cwd + cross-session: observations are keyed by
16
+ * the local project resolved from the absolute working directory and persisted
17
+ * in the same-machine SQLite store. There is no cloud/team sync and no
18
+ * cross-machine fan-out.
19
+ */
20
+ export function registerProjectObservationMemory(ext) {
21
+ registerRecallTool(ext);
22
+ registerReadProjectObservationsTool(ext);
23
+ registerWriteProjectObservationTool(ext);
24
+ registerShareProjectObservationTool(ext);
25
+ registerReceiveAgentObservationsTool(ext);
26
+ registerInterAgentReceiver(ext);
27
+ }
@@ -3,8 +3,14 @@
3
3
  * memory extension so the `read_project_observations` tool can query
4
4
  * cross-session observations.
5
5
  *
6
+ * Storage is per-machine + per-cwd: observations are keyed by the local
7
+ * project resolved from the absolute working directory and persisted in the
8
+ * same-machine SQLite store. They are shared across sessions on this machine
9
+ * but are NOT synced across machines or teams.
10
+ *
6
11
  * Set once by the SessionStreamManager at startup. Read by tools at runtime.
7
12
  */
13
+ import type { Entry } from "./branch.js";
8
14
  export interface ProjectObservationsStore {
9
15
  insertProjectObservations(projectId: string, sessionId: string, observations: Array<{
10
16
  id: string;
@@ -25,6 +31,8 @@ export interface ProjectObservationsStore {
25
31
  sessionId: string;
26
32
  } | null;
27
33
  getProjectByCwd(cwd: string): string | null;
34
+ upsertProjectRecallSource?(projectId: string, memoryId: string, entries: Entry[]): void;
35
+ getProjectRecallSource?(projectId: string, memoryId: string): Entry[] | null;
28
36
  }
29
37
  export declare function setProjectObsStore(store: ProjectObservationsStore): void;
30
38
  export declare function getProjectObsStore(): ProjectObservationsStore | null;
@@ -1 +1 @@
1
- {"version":3,"file":"project-observations-store.d.ts","sourceRoot":"","sources":["../../src/memory/project-observations-store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,wBAAwB;IACxC,yBAAyB,CACxB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,EACvE,SAAS,EAAE,MAAM,GACf,IAAI,CAAC;IACR,yBAAyB,CACxB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,MAAM,GACZ,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvF,yBAAyB,CACxB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,GACnB;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACnG,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CAC5C;AAID,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,wBAAwB,GAAG,IAAI,CAExE;AAED,wBAAgB,kBAAkB,IAAI,wBAAwB,GAAG,IAAI,CAEpE"}
1
+ {"version":3,"file":"project-observations-store.d.ts","sourceRoot":"","sources":["../../src/memory/project-observations-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,WAAW,wBAAwB;IACxC,yBAAyB,CACxB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,EACvE,SAAS,EAAE,MAAM,GACf,IAAI,CAAC;IACR,yBAAyB,CACxB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,MAAM,GACZ,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvF,yBAAyB,CACxB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,GACnB;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACnG,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC5C,yBAAyB,CAAC,CACzB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,KAAK,EAAE,GACd,IAAI,CAAC;IACR,sBAAsB,CAAC,CACtB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACd,KAAK,EAAE,GAAG,IAAI,CAAC;CAClB;AAID,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,wBAAwB,GAAG,IAAI,CAExE;AAED,wBAAgB,kBAAkB,IAAI,wBAAwB,GAAG,IAAI,CAEpE"}
@@ -3,6 +3,11 @@
3
3
  * memory extension so the `read_project_observations` tool can query
4
4
  * cross-session observations.
5
5
  *
6
+ * Storage is per-machine + per-cwd: observations are keyed by the local
7
+ * project resolved from the absolute working directory and persisted in the
8
+ * same-machine SQLite store. They are shared across sessions on this machine
9
+ * but are NOT synced across machines or teams.
10
+ *
6
11
  * Set once by the SessionStreamManager at startup. Read by tools at runtime.
7
12
  */
8
13
  let _store = null;
@@ -1,7 +1,7 @@
1
1
  export declare const MEMORY_STAKES = "These records are the ONLY information the assistant will have about past interactions once the raw conversation is compacted out of context. Anything you do not capture here will be forgotten. Anything you distort here will be remembered wrong. Take this seriously.";
2
- export declare const OBSERVATION_CONTENT_RULES = "Observation content rules:\n\nFormat.\n- Single line of plain prose. No markdown, no bullets, no code fences, no XML/HTML tags, no emojis.\n- Do NOT include the timestamp or relevance inside the content string \u2014 those are separate fields.\n- No structured fields embedded in the text (no \"key: value\" lines, no JSON).\n\nPreserve user assertions exactly.\nWhen the user TELLS you something about themselves, their project, or their environment, capture it as an assertion. When the user ASKS something, capture it as a question. Assertions are authoritative \u2014 a later question on the same topic does not invalidate them.\n BAD: User wondered if they have two kids.\n GOOD: User stated they have two kids.\n BAD: User discussed auth middleware.\n GOOD: User asked how to configure JWT auth middleware.\nWhy this matters: if the user says \"I use Postgres\" and later asks \"what db am I on?\", downstream agents must treat the assertion as the answer, not the question.\n\nPreserve unusual phrasing.\nWhen the user uses non-standard terminology, quote their exact words so future runs can recognize the term.\n BAD: User exercised yesterday.\n GOOD: User stated they did a \"movement session\" (their term) yesterday.\n\nUse precise action verbs. Replace vague verbs with ones that clarify the nature of the action.\n BAD: User got a new subscription.\n GOOD: User subscribed to the Pro plan.\n BAD: User stopped getting the newsletter.\n GOOD: User unsubscribed from the newsletter.\n BAD: User got the library.\n GOOD: User installed the zod package via pnpm.\n\nFrame state changes as supersession so the old state is explicit.\n BAD: User prefers React Query now.\n GOOD: User will use React Query (switching from SWR).\nWhy this matters: without supersession framing, the reflector may crystallize both the old and the new as equally valid preferences.\n\nMark concrete completions explicitly.\nUse \"completed:\", \"resolved:\", \"confirmed working\", or similar phrasing so future runs know not to redo the work.\n BAD: Wrote the login handler.\n GOOD: completed: implemented login handler at src/auth/login.ts; user confirmed tests pass.\nWhy this matters: without a completion marker, a later assistant may re-implement work that is already done, wasting the user's time and risking regressions.\n\nSplit compound statements into separate observations.\nIf a single message contains multiple independent facts, intents, or events, emit one observation per fact. One observation per line is what enables downstream retrieval and pruning to operate at fact granularity.\n BAD: User will visit their parents this weekend and needs to clean the garage.\n GOOD: User will visit their parents this weekend. + User stated they need to clean the garage this weekend.\n BAD: User started a new job and is moving to a new apartment next week.\n GOOD: User started a new job. + User will move to a new apartment next week.\n BAD: Assistant recommended Lucia, NextAuth, and Clerk for auth, and user chose Lucia.\n GOOD: Assistant recommended auth libraries: Lucia (session-based, minimal), NextAuth (OAuth-heavy, Next-native), Clerk (hosted, paid). + User chose Lucia.\nWhy this matters: a future query like \"which auth library did the user pick?\" can match a single-fact observation cleanly; a compound observation hides the decision inside a recommendation list.\n\nGroup repeated similar tool calls into a single observation rather than one per call.\n BAD: Agent viewed src/auth.ts. Agent viewed src/users.ts. Agent viewed src/routes.ts.\n GOOD: Agent surveyed auth-related files (src/auth.ts, src/users.ts, src/routes.ts) and located token validation in src/auth.ts:45.";
2
+ export declare const OBSERVATION_CONTENT_RULES = "Observation content rules:\n\nFormat.\n- Single line of plain prose. No markdown, no bullets, no code fences, no XML/HTML tags, no emojis.\n- Do NOT include the timestamp or relevance inside the content string \u2014 those are separate fields.\n- No structured fields embedded in the text (no \"key: value\" lines, no JSON).\n\nPreserve user assertions exactly.\nWhen the user TELLS you something about themselves, their project, or their environment, capture it as an assertion. When the user ASKS something, capture it as a question. Assertions are authoritative \u2014 a later question on the same topic does not invalidate them.\n BAD: User wondered if they have two kids.\n GOOD: User stated they have two kids.\n BAD: User discussed auth middleware.\n GOOD: User asked how to configure JWT auth middleware.\nWhy this matters: if the user says \"I use Postgres\" and later asks \"what db am I on?\", downstream agents must treat the assertion as the answer, not the question.\n\nPreserve unusual phrasing.\nWhen the user uses non-standard terminology, quote their exact words so future runs can recognize the term.\n BAD: User exercised yesterday.\n GOOD: User stated they did a \"movement session\" (their term) yesterday.\n\nUse precise action verbs. Replace vague verbs with ones that clarify the nature of the action.\n BAD: User got a new subscription.\n GOOD: User subscribed to the Pro plan.\n BAD: User stopped getting the newsletter.\n GOOD: User unsubscribed from the newsletter.\n BAD: User got the library.\n GOOD: User installed the zod package via pnpm.\n\nFrame state changes as supersession so the old state is explicit.\n BAD: User prefers React Query now.\n GOOD: User will use React Query (switching from SWR).\nWhy this matters: without supersession framing, later reflection may crystallize both the old and the new as equally valid preferences.\n\nMark concrete completions explicitly.\nUse \"completed:\", \"resolved:\", \"confirmed working\", or similar phrasing so future runs know not to redo the work.\n BAD: Wrote the login handler.\n GOOD: completed: implemented login handler at src/auth/login.ts; user confirmed tests pass.\nWhy this matters: without a completion marker, a later assistant may re-implement work that is already done, wasting the user's time and risking regressions.\n\nSplit compound statements into separate observations.\nIf a single message contains multiple independent facts, intents, or events, emit one observation per fact. One observation per line is what enables downstream retrieval and pruning to operate at fact granularity.\n BAD: User will visit their parents this weekend and needs to clean the garage.\n GOOD: User will visit their parents this weekend. + User stated they need to clean the garage this weekend.\n BAD: User started a new job and is moving to a new apartment next week.\n GOOD: User started a new job. + User will move to a new apartment next week.\n BAD: Assistant recommended Lucia, NextAuth, and Clerk for auth, and user chose Lucia.\n GOOD: Assistant recommended auth libraries: Lucia (session-based, minimal), NextAuth (OAuth-heavy, Next-native), Clerk (hosted, paid). + User chose Lucia.\nWhy this matters: a future query like \"which auth library did the user pick?\" can match a single-fact observation cleanly; a compound observation hides the decision inside a recommendation list.\n\nGroup repeated similar tool calls into a single observation rather than one per call.\n BAD: Agent viewed src/auth.ts. Agent viewed src/users.ts. Agent viewed src/routes.ts.\n GOOD: Agent surveyed auth-related files (src/auth.ts, src/users.ts, src/routes.ts) and located token validation in src/auth.ts:45.";
3
3
  export declare const DETAIL_PRESERVATION_SCHEMA = "Detail preservation. When an observation references specific things, preserve the distinguishing details so future queries can still find them:\n\n- File/location: full path + line number when relevant (src/auth.ts:45, not \"the auth file\").\n- Identifiers and names: package names, function names, variable names, handles, ticket ids, commit SHAs, error codes. Keep them verbatim.\n- Error messages: quote verbatim.\n BAD: Build failed with a type error.\n GOOD: Build failed: TS2322: Type 'string | undefined' is not assignable to type 'string' at src/auth.ts:47.\n- Numerical results: exact values, units, and direction.\n BAD: Optimization made it faster.\n GOOD: Optimization reduced p95 latency from 420ms to 180ms (57% faster).\n- Quantities and counts: \"3 failing tests (auth.test.ts, users.test.ts, routes.test.ts)\" not \"some failing tests\".\n- Recommendation or decision lists: preserve the distinguishing attribute per item.\n BAD: Assistant recommended 3 auth libraries.\n GOOD: Assistant recommended auth libraries: Lucia (session-based, minimal), NextAuth (OAuth-heavy, Next-native), Clerk (hosted, paid).\n- Role / participation: capture the user's role at an event, not just attendance.\n BAD: User worked on the migration.\n GOOD: User led the migration from MySQL to Postgres.\n\nIf a detail is non-obvious from the code or git history, it belongs in the observation. If it is trivially re-derivable, it does not.";
4
4
  export declare const RELEVANCE_RUBRIC = "Relevance levels (pick one per observation; this field drives future pruning):\n\n- critical: user assertions about identity, role, or persistent preferences; explicit corrections (\"no, don't do X\"); concrete completions that future runs MUST NOT redo. These are load-bearing and will NEVER be dropped. Why this matters: if a \"critical\" item is lost, the assistant may redo finished work, contradict a correction, or misrepresent who the user is.\n- high: non-trivial technical decisions, architectural direction, unresolved blockers, key constraints. Worth keeping across many compactions.\n- medium: task-level context that helps within the current work but isn't durable. The default when you are unsure between medium and high.\n- low: routine tool-call acks, repetitive status updates, content trivially re-derivable from recent messages. The pruner will drop these first.\n\nDo NOT default to \"critical\" or \"high\". Most observations are medium or low. Reserve \"critical\" for things that would cause real damage if forgotten.\n\n BAD: relevance=critical for \"Agent ran tests and they passed.\"\n GOOD: relevance=low for \"Agent ran tests and they passed.\" (routine; captured by a completion observation if it matters)\n\n BAD: relevance=medium for \"User said they are colorblind; red/green indicators do not work for them.\"\n GOOD: relevance=critical for \"User said they are colorblind; red/green indicators do not work for them.\" (persistent constraint; forgetting it causes real harm)";
5
- export declare const OBSERVER_SYSTEM = "You are the observation agent for a coding assistant.\n\nThese records are the ONLY information the assistant will have about past interactions once the raw conversation is compacted out of context. Anything you do not capture here will be forgotten. Anything you distort here will be remembered wrong. Take this seriously.\n\nYour job is to compress a chunk of recent conversation into timestamped, rated observations by calling the record_observations tool. The observations you emit \u2014 together with the reflections crystallized from them \u2014 are the assistant's ONLY memory of this session after the raw conversation falls out of context.\n\nYou receive:\n- Current reflections (long-lived facts already crystallized).\n- Current observations (already-recorded observations, each shown as \"[`id`] YYYY-MM-DD HH:MM [relevance] content\").\n- A new chunk of conversation with source entry labels and inline message timestamps. Each source block starts with \"[Source entry id: <id>]\" followed by content formatted as \"[User @ YYYY-MM-DD HH:MM]:\", \"[Assistant @ ...]:\", \"[Tool result for <name> @ ...]:\", custom messages, or branch summaries.\n- A current local time fallback for observations that have no obvious message timestamp.\n\nHow you work:\n1. Read reflections and current observations so you know what is already captured.\n2. Read the conversation chunk and identify what new information it contains.\n3. Call record_observations with a batch covering part (or all) of the chunk.\n4. Read the progress receipt. If content remains uncovered, call again. You may call the tool many times.\n5. When the chunk is fully covered, STOP calling the tool and reply with a brief plain-text confirmation (one short sentence). That ends the run.\n\nWhat to emit:\n- Produce NEW observations for the new chunk only. Do not restate facts already present in reflections or current observations unless something has materially changed.\n- Use the timestamp from the relevant conversation message. Fall back to current local time ONLY when no message timestamp applies.\n- For every observation, include sourceEntryIds: the smallest exact set of \"[Source entry id: ...]\" ids that directly support the observation.\n- Never invent source entry ids. Use only ids printed in the chunk. If an observation spans multiple turns or tool results, include every supporting source entry id.\n- Observations with missing, empty, or invalid sourceEntryIds will be rejected and not recorded, so do not call record_observations until you can cite valid source ids.\n- Group repeated similar tool calls into a single observation rather than one per call.\n- Skip routine, low-information events. It is fine to emit zero observations if the chunk carries no new information \u2014 in that case, simply do not call the tool and end with a plain-text confirmation.\n\nObservation content rules:\n\nFormat.\n- Single line of plain prose. No markdown, no bullets, no code fences, no XML/HTML tags, no emojis.\n- Do NOT include the timestamp or relevance inside the content string \u2014 those are separate fields.\n- No structured fields embedded in the text (no \"key: value\" lines, no JSON).\n\nPreserve user assertions exactly.\nWhen the user TELLS you something about themselves, their project, or their environment, capture it as an assertion. When the user ASKS something, capture it as a question. Assertions are authoritative \u2014 a later question on the same topic does not invalidate them.\n BAD: User wondered if they have two kids.\n GOOD: User stated they have two kids.\n BAD: User discussed auth middleware.\n GOOD: User asked how to configure JWT auth middleware.\nWhy this matters: if the user says \"I use Postgres\" and later asks \"what db am I on?\", downstream agents must treat the assertion as the answer, not the question.\n\nPreserve unusual phrasing.\nWhen the user uses non-standard terminology, quote their exact words so future runs can recognize the term.\n BAD: User exercised yesterday.\n GOOD: User stated they did a \"movement session\" (their term) yesterday.\n\nUse precise action verbs. Replace vague verbs with ones that clarify the nature of the action.\n BAD: User got a new subscription.\n GOOD: User subscribed to the Pro plan.\n BAD: User stopped getting the newsletter.\n GOOD: User unsubscribed from the newsletter.\n BAD: User got the library.\n GOOD: User installed the zod package via pnpm.\n\nFrame state changes as supersession so the old state is explicit.\n BAD: User prefers React Query now.\n GOOD: User will use React Query (switching from SWR).\nWhy this matters: without supersession framing, the reflector may crystallize both the old and the new as equally valid preferences.\n\nMark concrete completions explicitly.\nUse \"completed:\", \"resolved:\", \"confirmed working\", or similar phrasing so future runs know not to redo the work.\n BAD: Wrote the login handler.\n GOOD: completed: implemented login handler at src/auth/login.ts; user confirmed tests pass.\nWhy this matters: without a completion marker, a later assistant may re-implement work that is already done, wasting the user's time and risking regressions.\n\nSplit compound statements into separate observations.\nIf a single message contains multiple independent facts, intents, or events, emit one observation per fact. One observation per line is what enables downstream retrieval and pruning to operate at fact granularity.\n BAD: User will visit their parents this weekend and needs to clean the garage.\n GOOD: User will visit their parents this weekend. + User stated they need to clean the garage this weekend.\n BAD: User started a new job and is moving to a new apartment next week.\n GOOD: User started a new job. + User will move to a new apartment next week.\n BAD: Assistant recommended Lucia, NextAuth, and Clerk for auth, and user chose Lucia.\n GOOD: Assistant recommended auth libraries: Lucia (session-based, minimal), NextAuth (OAuth-heavy, Next-native), Clerk (hosted, paid). + User chose Lucia.\nWhy this matters: a future query like \"which auth library did the user pick?\" can match a single-fact observation cleanly; a compound observation hides the decision inside a recommendation list.\n\nGroup repeated similar tool calls into a single observation rather than one per call.\n BAD: Agent viewed src/auth.ts. Agent viewed src/users.ts. Agent viewed src/routes.ts.\n GOOD: Agent surveyed auth-related files (src/auth.ts, src/users.ts, src/routes.ts) and located token validation in src/auth.ts:45.\n\nDetail preservation. When an observation references specific things, preserve the distinguishing details so future queries can still find them:\n\n- File/location: full path + line number when relevant (src/auth.ts:45, not \"the auth file\").\n- Identifiers and names: package names, function names, variable names, handles, ticket ids, commit SHAs, error codes. Keep them verbatim.\n- Error messages: quote verbatim.\n BAD: Build failed with a type error.\n GOOD: Build failed: TS2322: Type 'string | undefined' is not assignable to type 'string' at src/auth.ts:47.\n- Numerical results: exact values, units, and direction.\n BAD: Optimization made it faster.\n GOOD: Optimization reduced p95 latency from 420ms to 180ms (57% faster).\n- Quantities and counts: \"3 failing tests (auth.test.ts, users.test.ts, routes.test.ts)\" not \"some failing tests\".\n- Recommendation or decision lists: preserve the distinguishing attribute per item.\n BAD: Assistant recommended 3 auth libraries.\n GOOD: Assistant recommended auth libraries: Lucia (session-based, minimal), NextAuth (OAuth-heavy, Next-native), Clerk (hosted, paid).\n- Role / participation: capture the user's role at an event, not just attendance.\n BAD: User worked on the migration.\n GOOD: User led the migration from MySQL to Postgres.\n\nIf a detail is non-obvious from the code or git history, it belongs in the observation. If it is trivially re-derivable, it does not.\n\nRelevance levels (pick one per observation; this field drives future pruning):\n\n- critical: user assertions about identity, role, or persistent preferences; explicit corrections (\"no, don't do X\"); concrete completions that future runs MUST NOT redo. These are load-bearing and will NEVER be dropped. Why this matters: if a \"critical\" item is lost, the assistant may redo finished work, contradict a correction, or misrepresent who the user is.\n- high: non-trivial technical decisions, architectural direction, unresolved blockers, key constraints. Worth keeping across many compactions.\n- medium: task-level context that helps within the current work but isn't durable. The default when you are unsure between medium and high.\n- low: routine tool-call acks, repetitive status updates, content trivially re-derivable from recent messages. The pruner will drop these first.\n\nDo NOT default to \"critical\" or \"high\". Most observations are medium or low. Reserve \"critical\" for things that would cause real damage if forgotten.\n\n BAD: relevance=critical for \"Agent ran tests and they passed.\"\n GOOD: relevance=low for \"Agent ran tests and they passed.\" (routine; captured by a completion observation if it matters)\n\n BAD: relevance=medium for \"User said they are colorblind; red/green indicators do not work for them.\"\n GOOD: relevance=critical for \"User said they are colorblind; red/green indicators do not work for them.\" (persistent constraint; forgetting it causes real harm)\n\nTimestamp format: \"YYYY-MM-DD HH:MM\" (local time, 24-hour, to the minute). This goes in the timestamp field, not the content.\n\nRemember: these observations are the assistant's ONLY memory of this chunk once the raw messages fall out of context. Make them count.";
5
+ export declare const OBSERVER_SYSTEM = "You are the observation agent for a coding assistant.\n\nThese records are the ONLY information the assistant will have about past interactions once the raw conversation is compacted out of context. Anything you do not capture here will be forgotten. Anything you distort here will be remembered wrong. Take this seriously.\n\nYour job is to compress a chunk of recent conversation into timestamped, rated observations by calling the record_observations tool. The observations you emit \u2014 together with the reflections crystallized from them \u2014 are the assistant's ONLY memory of this session after the raw conversation falls out of context.\n\nYou receive:\n- Current reflections (long-lived facts already crystallized).\n- Current observations (already-recorded observations, each shown as \"[`id`] YYYY-MM-DD HH:MM [relevance] content\").\n- A new chunk of conversation with source entry labels and inline message timestamps. Each source block starts with \"[Source entry id: <id>]\" followed by content formatted as \"[User @ YYYY-MM-DD HH:MM]:\", \"[Assistant @ ...]:\", \"[Tool result for <name> @ ...]:\", custom messages, or branch summaries.\n- A current local time fallback for observations that have no obvious message timestamp.\n\nHow you work:\n1. Read reflections and current observations so you know what is already captured.\n2. Read the conversation chunk and identify what new information it contains.\n3. Call record_observations with a batch covering part (or all) of the chunk.\n4. Read the progress receipt. If content remains uncovered, call again. You may call the tool many times.\n5. When the chunk is fully covered, STOP calling the tool and reply with a brief plain-text confirmation (one short sentence). That ends the run.\n\nWhat to emit:\n- Produce NEW observations for the new chunk only. Do not restate facts already present in reflections or current observations unless something has materially changed.\n- Use the timestamp from the relevant conversation message. Fall back to current local time ONLY when no message timestamp applies.\n- For every observation, include sourceEntryIds: the smallest exact set of \"[Source entry id: ...]\" ids that directly support the observation.\n- Never invent source entry ids. Use only ids printed in the chunk. If an observation spans multiple turns or tool results, include every supporting source entry id.\n- Observations with missing, empty, or invalid sourceEntryIds will be rejected and not recorded, so do not call record_observations until you can cite valid source ids.\n- Group repeated similar tool calls into a single observation rather than one per call.\n- Skip routine, low-information events. It is fine to emit zero observations if the chunk carries no new information \u2014 in that case, simply do not call the tool and end with a plain-text confirmation.\n\nObservation content rules:\n\nFormat.\n- Single line of plain prose. No markdown, no bullets, no code fences, no XML/HTML tags, no emojis.\n- Do NOT include the timestamp or relevance inside the content string \u2014 those are separate fields.\n- No structured fields embedded in the text (no \"key: value\" lines, no JSON).\n\nPreserve user assertions exactly.\nWhen the user TELLS you something about themselves, their project, or their environment, capture it as an assertion. When the user ASKS something, capture it as a question. Assertions are authoritative \u2014 a later question on the same topic does not invalidate them.\n BAD: User wondered if they have two kids.\n GOOD: User stated they have two kids.\n BAD: User discussed auth middleware.\n GOOD: User asked how to configure JWT auth middleware.\nWhy this matters: if the user says \"I use Postgres\" and later asks \"what db am I on?\", downstream agents must treat the assertion as the answer, not the question.\n\nPreserve unusual phrasing.\nWhen the user uses non-standard terminology, quote their exact words so future runs can recognize the term.\n BAD: User exercised yesterday.\n GOOD: User stated they did a \"movement session\" (their term) yesterday.\n\nUse precise action verbs. Replace vague verbs with ones that clarify the nature of the action.\n BAD: User got a new subscription.\n GOOD: User subscribed to the Pro plan.\n BAD: User stopped getting the newsletter.\n GOOD: User unsubscribed from the newsletter.\n BAD: User got the library.\n GOOD: User installed the zod package via pnpm.\n\nFrame state changes as supersession so the old state is explicit.\n BAD: User prefers React Query now.\n GOOD: User will use React Query (switching from SWR).\nWhy this matters: without supersession framing, later reflection may crystallize both the old and the new as equally valid preferences.\n\nMark concrete completions explicitly.\nUse \"completed:\", \"resolved:\", \"confirmed working\", or similar phrasing so future runs know not to redo the work.\n BAD: Wrote the login handler.\n GOOD: completed: implemented login handler at src/auth/login.ts; user confirmed tests pass.\nWhy this matters: without a completion marker, a later assistant may re-implement work that is already done, wasting the user's time and risking regressions.\n\nSplit compound statements into separate observations.\nIf a single message contains multiple independent facts, intents, or events, emit one observation per fact. One observation per line is what enables downstream retrieval and pruning to operate at fact granularity.\n BAD: User will visit their parents this weekend and needs to clean the garage.\n GOOD: User will visit their parents this weekend. + User stated they need to clean the garage this weekend.\n BAD: User started a new job and is moving to a new apartment next week.\n GOOD: User started a new job. + User will move to a new apartment next week.\n BAD: Assistant recommended Lucia, NextAuth, and Clerk for auth, and user chose Lucia.\n GOOD: Assistant recommended auth libraries: Lucia (session-based, minimal), NextAuth (OAuth-heavy, Next-native), Clerk (hosted, paid). + User chose Lucia.\nWhy this matters: a future query like \"which auth library did the user pick?\" can match a single-fact observation cleanly; a compound observation hides the decision inside a recommendation list.\n\nGroup repeated similar tool calls into a single observation rather than one per call.\n BAD: Agent viewed src/auth.ts. Agent viewed src/users.ts. Agent viewed src/routes.ts.\n GOOD: Agent surveyed auth-related files (src/auth.ts, src/users.ts, src/routes.ts) and located token validation in src/auth.ts:45.\n\nDetail preservation. When an observation references specific things, preserve the distinguishing details so future queries can still find them:\n\n- File/location: full path + line number when relevant (src/auth.ts:45, not \"the auth file\").\n- Identifiers and names: package names, function names, variable names, handles, ticket ids, commit SHAs, error codes. Keep them verbatim.\n- Error messages: quote verbatim.\n BAD: Build failed with a type error.\n GOOD: Build failed: TS2322: Type 'string | undefined' is not assignable to type 'string' at src/auth.ts:47.\n- Numerical results: exact values, units, and direction.\n BAD: Optimization made it faster.\n GOOD: Optimization reduced p95 latency from 420ms to 180ms (57% faster).\n- Quantities and counts: \"3 failing tests (auth.test.ts, users.test.ts, routes.test.ts)\" not \"some failing tests\".\n- Recommendation or decision lists: preserve the distinguishing attribute per item.\n BAD: Assistant recommended 3 auth libraries.\n GOOD: Assistant recommended auth libraries: Lucia (session-based, minimal), NextAuth (OAuth-heavy, Next-native), Clerk (hosted, paid).\n- Role / participation: capture the user's role at an event, not just attendance.\n BAD: User worked on the migration.\n GOOD: User led the migration from MySQL to Postgres.\n\nIf a detail is non-obvious from the code or git history, it belongs in the observation. If it is trivially re-derivable, it does not.\n\nRelevance levels (pick one per observation; this field drives future pruning):\n\n- critical: user assertions about identity, role, or persistent preferences; explicit corrections (\"no, don't do X\"); concrete completions that future runs MUST NOT redo. These are load-bearing and will NEVER be dropped. Why this matters: if a \"critical\" item is lost, the assistant may redo finished work, contradict a correction, or misrepresent who the user is.\n- high: non-trivial technical decisions, architectural direction, unresolved blockers, key constraints. Worth keeping across many compactions.\n- medium: task-level context that helps within the current work but isn't durable. The default when you are unsure between medium and high.\n- low: routine tool-call acks, repetitive status updates, content trivially re-derivable from recent messages. The pruner will drop these first.\n\nDo NOT default to \"critical\" or \"high\". Most observations are medium or low. Reserve \"critical\" for things that would cause real damage if forgotten.\n\n BAD: relevance=critical for \"Agent ran tests and they passed.\"\n GOOD: relevance=low for \"Agent ran tests and they passed.\" (routine; captured by a completion observation if it matters)\n\n BAD: relevance=medium for \"User said they are colorblind; red/green indicators do not work for them.\"\n GOOD: relevance=critical for \"User said they are colorblind; red/green indicators do not work for them.\" (persistent constraint; forgetting it causes real harm)\n\nTimestamp format: \"YYYY-MM-DD HH:MM\" (local time, 24-hour, to the minute). This goes in the timestamp field, not the content.\n\nRemember: these observations are the assistant's ONLY memory of this chunk once the raw messages fall out of context. Make them count.";
6
6
  export declare const CONTEXT_USAGE_INSTRUCTIONS = "These are condensed memories from earlier in this session.\n\n- Reflections: stable, long-lived facts about the user, project, decisions, and constraints. New reflection lines may include ids in brackets wrapped in backticks.\n- Observations: timestamped events from the conversation history, in chronological order. Observation lines include ids in brackets wrapped in backticks.\n\nTreat these as past records. When entries conflict, the most recent observation reflects the latest known state. Work that prior observations describe as completed should not be redone unless the user explicitly asks to revisit it.\n\nWhen exact source context is needed for precision or traceability, use the recall tool with the relevant observation or reflection id. This is especially useful when a reflection materially affects a decision or is too compressed to continue confidently. Do not use recall as broad search or inject raw source unless it is needed.";
7
7
  //# sourceMappingURL=prompts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/memory/prompts.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,+QAA+Q,CAAC;AAE1S,eAAO,MAAM,yBAAyB,6oHAmD+F,CAAC;AAEtI,eAAO,MAAM,0BAA0B,67CAkB+F,CAAC;AAEvI,eAAO,MAAM,gBAAgB,8+CAasI,CAAC;AAEpK,eAAO,MAAM,eAAe,knTAoC2G,CAAC;AAExI,eAAO,MAAM,0BAA0B,07BAOoS,CAAC"}
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/memory/prompts.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,+QAA+Q,CAAC;AAE1S,eAAO,MAAM,yBAAyB,gpHAmD+F,CAAC;AAEtI,eAAO,MAAM,0BAA0B,67CAkB+F,CAAC;AAEvI,eAAO,MAAM,gBAAgB,8+CAasI,CAAC;AAEpK,eAAO,MAAM,eAAe,qnTAoC2G,CAAC;AAExI,eAAO,MAAM,0BAA0B,07BAOoS,CAAC"}
@@ -30,7 +30,7 @@ Use precise action verbs. Replace vague verbs with ones that clarify the nature
30
30
  Frame state changes as supersession so the old state is explicit.
31
31
  BAD: User prefers React Query now.
32
32
  GOOD: User will use React Query (switching from SWR).
33
- Why this matters: without supersession framing, the reflector may crystallize both the old and the new as equally valid preferences.
33
+ Why this matters: without supersession framing, later reflection may crystallize both the old and the new as equally valid preferences.
34
34
 
35
35
  Mark concrete completions explicitly.
36
36
  Use "completed:", "resolved:", "confirmed working", or similar phrasing so future runs know not to redo the work.
@@ -0,0 +1,21 @@
1
+ import type { ExtensionAPI } from "../sdk/coding-agent/index.js";
2
+ import { Runtime } from "./runtime.js";
3
+ /**
4
+ * Session/branch memory layer.
5
+ *
6
+ * This layer owns the branch-scoped observational-memory pipeline:
7
+ * - the observer (`observer.ts` via `observer-trigger.ts`) extracts
8
+ * observations from new conversation turns;
9
+ * - the deterministic pruner (`deterministic-pruner.ts` via
10
+ * `compaction-hook.ts`) drops low-value observations at compaction time;
11
+ * - the summary render path (`compaction.ts`) produces the compacted memory
12
+ * that is persisted into `session_memory_snapshots`;
13
+ * - the snapshot persistence hooks (`compaction-hook.ts`,
14
+ * `compaction-trigger.ts`, `observer-trigger.ts`) keep that session memory
15
+ * alive across compactions.
16
+ *
17
+ * It is intentionally separate from `project-observation-memory.ts`, which
18
+ * owns the per-machine + per-cwd, cross-session project observation store.
19
+ */
20
+ export declare function registerSessionMemory(ext: ExtensionAPI, runtime: Runtime): void;
21
+ //# sourceMappingURL=session-memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-memory.d.ts","sourceRoot":"","sources":["../../src/memory/session-memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAMjE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAIvC;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAS/E"}