@vortex-os/memory-extended 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. package/README.md +244 -0
  2. package/dist/consolidate/index.d.ts +7 -0
  3. package/dist/consolidate/index.d.ts.map +1 -0
  4. package/dist/consolidate/index.js +4 -0
  5. package/dist/consolidate/index.js.map +1 -0
  6. package/dist/consolidate/proposer.d.ts +43 -0
  7. package/dist/consolidate/proposer.d.ts.map +1 -0
  8. package/dist/consolidate/proposer.js +276 -0
  9. package/dist/consolidate/proposer.js.map +1 -0
  10. package/dist/consolidate/query.d.ts +32 -0
  11. package/dist/consolidate/query.d.ts.map +1 -0
  12. package/dist/consolidate/query.js +40 -0
  13. package/dist/consolidate/query.js.map +1 -0
  14. package/dist/consolidate/store.d.ts +21 -0
  15. package/dist/consolidate/store.d.ts.map +1 -0
  16. package/dist/consolidate/store.js +91 -0
  17. package/dist/consolidate/store.js.map +1 -0
  18. package/dist/consolidate/types.d.ts +68 -0
  19. package/dist/consolidate/types.d.ts.map +1 -0
  20. package/dist/consolidate/types.js +2 -0
  21. package/dist/consolidate/types.js.map +1 -0
  22. package/dist/index.d.ts +7 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +7 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/internal/frontmatter.d.ts +6 -0
  27. package/dist/internal/frontmatter.d.ts.map +1 -0
  28. package/dist/internal/frontmatter.js +38 -0
  29. package/dist/internal/frontmatter.js.map +1 -0
  30. package/dist/internal/proactive-curator-helpers.d.ts +171 -0
  31. package/dist/internal/proactive-curator-helpers.d.ts.map +1 -0
  32. package/dist/internal/proactive-curator-helpers.js +162 -0
  33. package/dist/internal/proactive-curator-helpers.js.map +1 -0
  34. package/dist/mcp/document-tools.d.ts +144 -0
  35. package/dist/mcp/document-tools.d.ts.map +1 -0
  36. package/dist/mcp/document-tools.js +319 -0
  37. package/dist/mcp/document-tools.js.map +1 -0
  38. package/dist/mcp/index.d.ts +34 -0
  39. package/dist/mcp/index.d.ts.map +1 -0
  40. package/dist/mcp/index.js +29 -0
  41. package/dist/mcp/index.js.map +1 -0
  42. package/dist/mcp/install.d.ts +72 -0
  43. package/dist/mcp/install.d.ts.map +1 -0
  44. package/dist/mcp/install.js +92 -0
  45. package/dist/mcp/install.js.map +1 -0
  46. package/dist/mcp/memory-tools.d.ts +101 -0
  47. package/dist/mcp/memory-tools.d.ts.map +1 -0
  48. package/dist/mcp/memory-tools.js +105 -0
  49. package/dist/mcp/memory-tools.js.map +1 -0
  50. package/dist/mcp/recall-tool.d.ts +52 -0
  51. package/dist/mcp/recall-tool.d.ts.map +1 -0
  52. package/dist/mcp/recall-tool.js +60 -0
  53. package/dist/mcp/recall-tool.js.map +1 -0
  54. package/dist/mcp/server.d.ts +32 -0
  55. package/dist/mcp/server.d.ts.map +1 -0
  56. package/dist/mcp/server.js +113 -0
  57. package/dist/mcp/server.js.map +1 -0
  58. package/dist/recall/engine.d.ts +38 -0
  59. package/dist/recall/engine.d.ts.map +1 -0
  60. package/dist/recall/engine.js +113 -0
  61. package/dist/recall/engine.js.map +1 -0
  62. package/dist/recall/index.d.ts +22 -0
  63. package/dist/recall/index.d.ts.map +1 -0
  64. package/dist/recall/index.js +20 -0
  65. package/dist/recall/index.js.map +1 -0
  66. package/dist/recall/intent.d.ts +24 -0
  67. package/dist/recall/intent.d.ts.map +1 -0
  68. package/dist/recall/intent.js +95 -0
  69. package/dist/recall/intent.js.map +1 -0
  70. package/dist/recall/render.d.ts +11 -0
  71. package/dist/recall/render.d.ts.map +1 -0
  72. package/dist/recall/render.js +23 -0
  73. package/dist/recall/render.js.map +1 -0
  74. package/dist/recall/types.d.ts +72 -0
  75. package/dist/recall/types.d.ts.map +1 -0
  76. package/dist/recall/types.js +2 -0
  77. package/dist/recall/types.js.map +1 -0
  78. package/dist/sessionArchive/adapters/claude-code.d.ts +3 -0
  79. package/dist/sessionArchive/adapters/claude-code.d.ts.map +1 -0
  80. package/dist/sessionArchive/adapters/claude-code.js +276 -0
  81. package/dist/sessionArchive/adapters/claude-code.js.map +1 -0
  82. package/dist/sessionArchive/adapters/claude-desktop.d.ts +3 -0
  83. package/dist/sessionArchive/adapters/claude-desktop.d.ts.map +1 -0
  84. package/dist/sessionArchive/adapters/claude-desktop.js +234 -0
  85. package/dist/sessionArchive/adapters/claude-desktop.js.map +1 -0
  86. package/dist/sessionArchive/adapters/codex.d.ts +3 -0
  87. package/dist/sessionArchive/adapters/codex.d.ts.map +1 -0
  88. package/dist/sessionArchive/adapters/codex.js +322 -0
  89. package/dist/sessionArchive/adapters/codex.js.map +1 -0
  90. package/dist/sessionArchive/adapters/gemini.d.ts +3 -0
  91. package/dist/sessionArchive/adapters/gemini.d.ts.map +1 -0
  92. package/dist/sessionArchive/adapters/gemini.js +248 -0
  93. package/dist/sessionArchive/adapters/gemini.js.map +1 -0
  94. package/dist/sessionArchive/adapters/index.d.ts +5 -0
  95. package/dist/sessionArchive/adapters/index.d.ts.map +1 -0
  96. package/dist/sessionArchive/adapters/index.js +5 -0
  97. package/dist/sessionArchive/adapters/index.js.map +1 -0
  98. package/dist/sessionArchive/index.d.ts +9 -0
  99. package/dist/sessionArchive/index.d.ts.map +1 -0
  100. package/dist/sessionArchive/index.js +6 -0
  101. package/dist/sessionArchive/index.js.map +1 -0
  102. package/dist/sessionArchive/ingest.d.ts +68 -0
  103. package/dist/sessionArchive/ingest.d.ts.map +1 -0
  104. package/dist/sessionArchive/ingest.js +134 -0
  105. package/dist/sessionArchive/ingest.js.map +1 -0
  106. package/dist/sessionArchive/normalize.d.ts +15 -0
  107. package/dist/sessionArchive/normalize.d.ts.map +1 -0
  108. package/dist/sessionArchive/normalize.js +40 -0
  109. package/dist/sessionArchive/normalize.js.map +1 -0
  110. package/dist/sessionArchive/store.d.ts +118 -0
  111. package/dist/sessionArchive/store.d.ts.map +1 -0
  112. package/dist/sessionArchive/store.js +491 -0
  113. package/dist/sessionArchive/store.js.map +1 -0
  114. package/dist/sessionArchive/types.d.ts +124 -0
  115. package/dist/sessionArchive/types.d.ts.map +1 -0
  116. package/dist/sessionArchive/types.js +24 -0
  117. package/dist/sessionArchive/types.js.map +1 -0
  118. package/dist/sqlite/drift.d.ts +22 -0
  119. package/dist/sqlite/drift.d.ts.map +1 -0
  120. package/dist/sqlite/drift.js +69 -0
  121. package/dist/sqlite/drift.js.map +1 -0
  122. package/dist/sqlite/index.d.ts +22 -0
  123. package/dist/sqlite/index.d.ts.map +1 -0
  124. package/dist/sqlite/index.js +4 -0
  125. package/dist/sqlite/index.js.map +1 -0
  126. package/dist/sqlite/rebuild.d.ts +32 -0
  127. package/dist/sqlite/rebuild.d.ts.map +1 -0
  128. package/dist/sqlite/rebuild.js +80 -0
  129. package/dist/sqlite/rebuild.js.map +1 -0
  130. package/dist/sqlite/schema.d.ts +15 -0
  131. package/dist/sqlite/schema.d.ts.map +1 -0
  132. package/dist/sqlite/schema.js +41 -0
  133. package/dist/sqlite/schema.js.map +1 -0
  134. package/dist/sqlite/store.d.ts +49 -0
  135. package/dist/sqlite/store.d.ts.map +1 -0
  136. package/dist/sqlite/store.js +179 -0
  137. package/dist/sqlite/store.js.map +1 -0
  138. package/dist/sqlite/types.d.ts +57 -0
  139. package/dist/sqlite/types.d.ts.map +1 -0
  140. package/dist/sqlite/types.js +2 -0
  141. package/dist/sqlite/types.js.map +1 -0
  142. package/dist/vector/backend-brute.d.ts +38 -0
  143. package/dist/vector/backend-brute.d.ts.map +1 -0
  144. package/dist/vector/backend-brute.js +112 -0
  145. package/dist/vector/backend-brute.js.map +1 -0
  146. package/dist/vector/embedder.d.ts +59 -0
  147. package/dist/vector/embedder.d.ts.map +1 -0
  148. package/dist/vector/embedder.js +47 -0
  149. package/dist/vector/embedder.js.map +1 -0
  150. package/dist/vector/index.d.ts +24 -0
  151. package/dist/vector/index.d.ts.map +1 -0
  152. package/dist/vector/index.js +7 -0
  153. package/dist/vector/index.js.map +1 -0
  154. package/dist/vector/math.d.ts +21 -0
  155. package/dist/vector/math.d.ts.map +1 -0
  156. package/dist/vector/math.js +34 -0
  157. package/dist/vector/math.js.map +1 -0
  158. package/dist/vector/schema.d.ts +14 -0
  159. package/dist/vector/schema.d.ts.map +1 -0
  160. package/dist/vector/schema.js +24 -0
  161. package/dist/vector/schema.js.map +1 -0
  162. package/dist/vector/segment.d.ts +65 -0
  163. package/dist/vector/segment.d.ts.map +1 -0
  164. package/dist/vector/segment.js +72 -0
  165. package/dist/vector/segment.js.map +1 -0
  166. package/dist/vector/session.d.ts +90 -0
  167. package/dist/vector/session.d.ts.map +1 -0
  168. package/dist/vector/session.js +242 -0
  169. package/dist/vector/session.js.map +1 -0
  170. package/dist/vector/store.d.ts +69 -0
  171. package/dist/vector/store.d.ts.map +1 -0
  172. package/dist/vector/store.js +131 -0
  173. package/dist/vector/store.js.map +1 -0
  174. package/dist/vector/types.d.ts +109 -0
  175. package/dist/vector/types.d.ts.map +1 -0
  176. package/dist/vector/types.js +24 -0
  177. package/dist/vector/types.js.map +1 -0
  178. package/package.json +96 -0
  179. package/scripts/mcp-stdio.mjs +143 -0
  180. package/scripts/rebuild-memory-sqlite.mjs +39 -0
  181. package/scripts/rebuild-memory-vector.mjs +64 -0
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Pull the recently-ingested sessions together with their event bodies.
3
+ * Sessions with zero text events are dropped — they cannot drive a memory
4
+ * proposal, and feeding them to the LLM only wastes tokens.
5
+ */
6
+ export function collectRecentSessions(store, options) {
7
+ const metas = store.listSessions({
8
+ ...(options?.sinceMs !== undefined ? { sinceMs: options.sinceMs } : {}),
9
+ ...(options?.limit !== undefined ? { limit: options.limit } : {}),
10
+ });
11
+ const out = [];
12
+ for (const m of metas) {
13
+ const events = store.readSessionEvents(m.host, m.sessionId);
14
+ if (events.some((e) => (e.text ?? "").trim().length > 0)) {
15
+ out.push({ metadata: m, events });
16
+ }
17
+ }
18
+ return out;
19
+ }
20
+ /**
21
+ * Render an archived session as a compact transcript for an LLM prompt.
22
+ * Empty / tool-call-only events are dropped (they rarely carry the kind
23
+ * of insight worth promoting to memory); the remaining events are joined
24
+ * with `[<role>]` prefixes for the LLM to follow turn boundaries.
25
+ */
26
+ export function renderSessionForPrompt(session) {
27
+ const lines = [];
28
+ const header = session.metadata.startedAt
29
+ ? `Session ${session.metadata.host}/${session.metadata.sessionId} (started ${session.metadata.startedAt})`
30
+ : `Session ${session.metadata.host}/${session.metadata.sessionId}`;
31
+ lines.push(`# ${header}`);
32
+ for (const ev of session.events) {
33
+ const text = (ev.text ?? "").trim();
34
+ if (!text)
35
+ continue;
36
+ lines.push(`[${ev.kind}#${ev.idx}] ${text}`);
37
+ }
38
+ return lines.join("\n");
39
+ }
40
+ //# sourceMappingURL=query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/consolidate/query.ts"],"names":[],"mappings":"AAyBA;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAA0B,EAC1B,OAAgC;IAEhC,MAAM,KAAK,GAAG,KAAK,CAAC,YAAY,CAAC;QAC/B,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,GAAG,CAAC,OAAO,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClE,CAAC,CAAC;IACH,MAAM,GAAG,GAAsB,EAAE,CAAC;IAClC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;QAC5D,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;YACzD,GAAG,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAwB;IAC7D,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,SAAS;QACvC,CAAC,CAAC,WAAW,OAAO,CAAC,QAAQ,CAAC,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC,SAAS,aAAa,OAAO,CAAC,QAAQ,CAAC,SAAS,GAAG;QAC1G,CAAC,CAAC,WAAW,OAAO,CAAC,QAAQ,CAAC,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;IACrE,KAAK,CAAC,IAAI,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC;IAC1B,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACpC,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,21 @@
1
+ export interface RejectedEntry {
2
+ readonly rejectedAt: string;
3
+ /** Memory candidate name at the time of rejection — for audit display only. */
4
+ readonly candidateName: string;
5
+ readonly expiresAt: string;
6
+ }
7
+ export declare function loadRejectedFingerprints(cwd: string, now: Date): Promise<ReadonlySet<string>>;
8
+ export declare function recordRejection(cwd: string, args: {
9
+ readonly fingerprint: string;
10
+ readonly candidateName: string;
11
+ readonly now: Date;
12
+ readonly expiryDays?: number;
13
+ }): Promise<void>;
14
+ export declare function recordAcceptance(cwd: string, args: {
15
+ readonly fingerprint: string;
16
+ readonly candidateName: string;
17
+ readonly writtenPath: string;
18
+ readonly now: Date;
19
+ }): Promise<void>;
20
+ export declare function resetRejected(cwd: string): Promise<void>;
21
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/consolidate/store.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,+EAA+E;IAC/E,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAMD,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,IAAI,GACR,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAU9B;AAED,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IACJ,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;IACnB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B,GACA,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IACJ,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;CACpB,GACA,OAAO,CAAC,IAAI,CAAC,CASf;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI9D"}
@@ -0,0 +1,91 @@
1
+ import { existsSync } from "node:fs";
2
+ import { appendFile, mkdir, readFile, writeFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ /**
5
+ * Persistence for the consolidate namespace — mirrors the
6
+ * proactive-curator decline store but lives under its own directory so
7
+ * the two surfaces never collide on a fingerprint.
8
+ *
9
+ * Layout under `<cwd>/data/_session-archive/consolidate/`:
10
+ * rejected.json — keyed by candidate fingerprint; expires after N days
11
+ * accepted.log — JSONL audit trail of accepted candidates
12
+ */
13
+ const STORE_DIR = "data/_session-archive/consolidate";
14
+ const REJECTED_FILE = "rejected.json";
15
+ const ACCEPTED_LOG = "accepted.log";
16
+ const DEFAULT_EXPIRY_DAYS = 30;
17
+ export async function loadRejectedFingerprints(cwd, now) {
18
+ const parsed = await readRejectedFile(cwd);
19
+ if (!parsed)
20
+ return new Set();
21
+ const active = new Set();
22
+ const nowMs = now.getTime();
23
+ for (const [fp, entry] of Object.entries(parsed)) {
24
+ const expiresMs = new Date(entry.expiresAt).getTime();
25
+ if (Number.isFinite(expiresMs) && expiresMs > nowMs)
26
+ active.add(fp);
27
+ }
28
+ return active;
29
+ }
30
+ export async function recordRejection(cwd, args) {
31
+ await ensureStoreDir(cwd);
32
+ const existing = (await readRejectedFile(cwd)) ?? {};
33
+ const expiryDays = args.expiryDays ?? DEFAULT_EXPIRY_DAYS;
34
+ const expiresAt = new Date(args.now.getTime() + expiryDays * 24 * 60 * 60 * 1000).toISOString();
35
+ const updated = purgeExpired(existing, args.now);
36
+ updated[args.fingerprint] = {
37
+ rejectedAt: args.now.toISOString(),
38
+ candidateName: args.candidateName,
39
+ expiresAt,
40
+ };
41
+ await writeFile(join(cwd, STORE_DIR, REJECTED_FILE), JSON.stringify(updated, null, 2) + "\n", "utf8");
42
+ }
43
+ export async function recordAcceptance(cwd, args) {
44
+ await ensureStoreDir(cwd);
45
+ const line = JSON.stringify({
46
+ acceptedAt: args.now.toISOString(),
47
+ fingerprint: args.fingerprint,
48
+ candidateName: args.candidateName,
49
+ writtenPath: args.writtenPath,
50
+ });
51
+ await appendFile(join(cwd, STORE_DIR, ACCEPTED_LOG), line + "\n", "utf8");
52
+ }
53
+ export async function resetRejected(cwd) {
54
+ const file = join(cwd, STORE_DIR, REJECTED_FILE);
55
+ if (!existsSync(file))
56
+ return;
57
+ await writeFile(file, JSON.stringify({}, null, 2) + "\n", "utf8");
58
+ }
59
+ // Fingerprints are file-derived keys parsed from JSON on disk; a crafted file
60
+ // could carry `__proto__`/`constructor`/`prototype` keys. Build the accumulator
61
+ // with a null prototype and skip those keys — belt-and-suspenders against
62
+ // prototype pollution when rebuilding the store.
63
+ const DANGEROUS_KEYS = new Set(["__proto__", "constructor", "prototype"]);
64
+ function purgeExpired(entries, now) {
65
+ const out = Object.create(null);
66
+ const nowMs = now.getTime();
67
+ for (const [fp, entry] of Object.entries(entries)) {
68
+ if (DANGEROUS_KEYS.has(fp))
69
+ continue;
70
+ const expiresMs = new Date(entry.expiresAt).getTime();
71
+ if (Number.isFinite(expiresMs) && expiresMs > nowMs)
72
+ out[fp] = entry;
73
+ }
74
+ return out;
75
+ }
76
+ async function readRejectedFile(cwd) {
77
+ const file = join(cwd, STORE_DIR, REJECTED_FILE);
78
+ if (!existsSync(file))
79
+ return null;
80
+ try {
81
+ const raw = await readFile(file, "utf8");
82
+ return JSON.parse(raw);
83
+ }
84
+ catch {
85
+ return null;
86
+ }
87
+ }
88
+ async function ensureStoreDir(cwd) {
89
+ await mkdir(join(cwd, STORE_DIR), { recursive: true });
90
+ }
91
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/consolidate/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ import type { AcceptResult, Proposal, ProposalAction } from "../internal/proactive-curator-helpers.js";
2
+ /**
3
+ * Memory candidate extracted from past sessions. Mirrors the `_memory/*.md`
4
+ * frontmatter shape so the accepted candidate can be written through the
5
+ * base `memorySystem` API without further transformation.
6
+ *
7
+ * `sourceExcerptIds` carries the (host, sessionId, eventIdx) triples that
8
+ * justified the proposal. The host displays these so the operator can
9
+ * verify the source before accepting.
10
+ */
11
+ export interface MemoryCandidate {
12
+ /** Slug-safe name — becomes `_memory/<name>.md`. */
13
+ readonly name: string;
14
+ /** One-line description for the memory's frontmatter `description` field. */
15
+ readonly description: string;
16
+ /** Memory type: "user" | "feedback" | "project" | "reference". */
17
+ readonly type: string;
18
+ /** Body content (markdown, no frontmatter — the writer adds the header). */
19
+ readonly body: string;
20
+ /** Source events that justified this candidate (audit trail). */
21
+ readonly sourceExcerptIds: readonly SourceExcerptId[];
22
+ }
23
+ /**
24
+ * Identifier of a single event inside a session — the smallest addressable
25
+ * unit a consolidate proposal can cite. Sticking to (host, sessionId,
26
+ * eventIdx) keeps the citation stable across re-ingest as long as the
27
+ * source files have not been deleted from `_session-archive/normalized/`.
28
+ */
29
+ export interface SourceExcerptId {
30
+ readonly host: string;
31
+ readonly sessionId: string;
32
+ readonly eventIdx: number;
33
+ }
34
+ /**
35
+ * Consolidate proposal — the proactive-curator `Proposal` shape specialized
36
+ * for the consolidate kind. `action` is always `create-file` with
37
+ * `folderPath: "_memory"` and `filename: "<candidate.name>.md"`; this lets
38
+ * the same `/curate`-style host UX render the proposal without a separate
39
+ * code path.
40
+ */
41
+ export interface ConsolidateProposal extends Proposal {
42
+ readonly kind: "consolidate-memory";
43
+ readonly action: Extract<ProposalAction, {
44
+ kind: "create-file";
45
+ }>;
46
+ /** Full candidate — kept on the proposal so hosts can show structured info beyond `preview`. */
47
+ readonly candidate: MemoryCandidate;
48
+ }
49
+ /**
50
+ * Result returned by a consolidate proposal's `onAccept`.
51
+ */
52
+ export interface ConsolidateAcceptResult extends AcceptResult {
53
+ readonly actionApplied: "create-file";
54
+ }
55
+ /**
56
+ * Options accepted by {@link Consolidator}. All fields are optional.
57
+ */
58
+ export interface ConsolidatorOptions {
59
+ /** Look back this many days when no explicit `sinceMs` is provided. Default 7. */
60
+ readonly defaultLookbackDays?: number;
61
+ /** Cap the number of sessions fed into one LLM call. Default 20. */
62
+ readonly maxSessionsPerRun?: number;
63
+ /** Cap the number of candidates the LLM may propose per run. Default 5. */
64
+ readonly maxCandidatesPerRun?: number;
65
+ /** Days after which a rejected candidate becomes eligible to re-surface. Default 30. */
66
+ readonly rejectionExpiryDays?: number;
67
+ }
68
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/consolidate/types.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,YAAY,EACZ,QAAQ,EACR,cAAc,EACf,MAAM,0CAA0C,CAAC;AAElD;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B,oDAAoD;IACpD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,QAAQ,CAAC,gBAAgB,EAAE,SAAS,eAAe,EAAE,CAAC;CACvD;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,mBAAoB,SAAQ,QAAQ;IACnD,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,cAAc,EAAE;QAAE,IAAI,EAAE,aAAa,CAAA;KAAE,CAAC,CAAC;IAClE,gGAAgG;IAChG,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,uBAAwB,SAAQ,YAAY;IAC3D,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;CACvC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,kFAAkF;IAClF,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,oEAAoE;IACpE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,2EAA2E;IAC3E,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,wFAAwF;IACxF,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;CACvC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/consolidate/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ export * as sessionArchive from "./sessionArchive/index.js";
2
+ export * as consolidate from "./consolidate/index.js";
3
+ export * as sqlite from "./sqlite/index.js";
4
+ export * as vector from "./vector/index.js";
5
+ export * as recall from "./recall/index.js";
6
+ export * as mcp from "./mcp/index.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,cAAc,MAAM,2BAA2B,CAAC;AAC5D,OAAO,KAAK,WAAW,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export * as sessionArchive from "./sessionArchive/index.js";
2
+ export * as consolidate from "./consolidate/index.js";
3
+ export * as sqlite from "./sqlite/index.js";
4
+ export * as vector from "./vector/index.js";
5
+ export * as recall from "./recall/index.js";
6
+ export * as mcp from "./mcp/index.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,cAAc,MAAM,2BAA2B,CAAC;AAC5D,OAAO,KAAK,WAAW,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface FrontmatterDoc<T> {
2
+ readonly frontmatter: T;
3
+ readonly body: string;
4
+ }
5
+ export declare function parseFrontmatter<T = Record<string, unknown>>(source: string): FrontmatterDoc<T>;
6
+ //# sourceMappingURL=frontmatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../../src/internal/frontmatter.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,gBAAgB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1D,MAAM,EAAE,MAAM,GACb,cAAc,CAAC,CAAC,CAAC,CAkBnB"}
@@ -0,0 +1,38 @@
1
+ import { parse as parseYaml } from "yaml";
2
+ /**
3
+ * Inlined YAML-frontmatter parser (Phase 11c follow-up, 2026-05-29).
4
+ *
5
+ * memory-extended ships as a public add-on (`base` + add-ons is the intended
6
+ * public surface). It previously imported `parseFrontmatter` from the
7
+ * internal `@vortex-os/core` package, which forced `core` onto the public
8
+ * registry just to satisfy the import. To keep `core` private, the single
9
+ * helper memory-extended needs is inlined here — the add-on is now
10
+ * self-contained (only `yaml` is an external dependency).
11
+ *
12
+ * Behavior mirrors `@vortex-os/core`'s `parseFrontmatter`: BOM-safe, returns
13
+ * empty frontmatter + the source unchanged when no fence is present, and
14
+ * tolerates a malformed fence by treating it as no frontmatter.
15
+ */
16
+ const FENCE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
17
+ const BOM = "";
18
+ export function parseFrontmatter(source) {
19
+ const cleaned = source.startsWith(BOM) ? source.slice(1) : source;
20
+ const match = cleaned.match(FENCE);
21
+ if (!match) {
22
+ return { frontmatter: {}, body: cleaned };
23
+ }
24
+ const yaml = match[1] ?? "";
25
+ const body = cleaned.slice(match[0].length);
26
+ let parsed;
27
+ try {
28
+ parsed = (parseYaml(yaml) ?? {});
29
+ }
30
+ catch {
31
+ // Fence present but its YAML body did not parse (copy/paste artifacts,
32
+ // a stray mid-document `---`, etc.). Treat as no frontmatter so callers
33
+ // can still read the body; the fence content is discarded.
34
+ parsed = {};
35
+ }
36
+ return { frontmatter: parsed, body };
37
+ }
38
+ //# sourceMappingURL=frontmatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../src/internal/frontmatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAE1C;;;;;;;;;;;;;GAaG;AACH,MAAM,KAAK,GAAG,mCAAmC,CAAC;AAClD,MAAM,GAAG,GAAG,GAAG,CAAC;AAOhB,MAAM,UAAU,gBAAgB,CAC9B,MAAc;IAEd,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAClE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACnC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,WAAW,EAAE,EAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACjD,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5B,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC5C,IAAI,MAAS,CAAC;IACd,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAAM,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,uEAAuE;QACvE,wEAAwE;QACxE,2DAA2D;QAC3D,MAAM,GAAG,EAAO,CAAC;IACnB,CAAC;IACD,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AACvC,CAAC"}
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Inlined proactive-curator helpers (self-contained add-on, 2026-05-31).
3
+ *
4
+ * memory-extended ships as a public add-on (`base` + add-ons is the intended
5
+ * public surface). The `consolidate` namespace and the `mcp` document tools
6
+ * previously reached into the private `@vortex-os/proactive-curator` package
7
+ * — `consolidate` for its proposal/judge TYPES, the document tools for its
8
+ * stateless decline-store FUNCTIONS — which forced `proactive-curator` onto
9
+ * the public registry just to satisfy those imports. To keep that package
10
+ * private, the small surface memory-extended actually uses is inlined here.
11
+ * The add-on stays standalone-capable: nothing here depends on a separately
12
+ * published `@vortex-os/proactive-curator`, and the only runtime imports are
13
+ * Node builtins (`node:fs`, `node:path`).
14
+ *
15
+ * Mirrors the precedent in `internal/frontmatter.ts`, which inlined the one
16
+ * `@vortex-os/core` helper this package needed for the same reason.
17
+ *
18
+ * Two parts:
19
+ * (1) Type/interface definitions — structurally identical to the curator's
20
+ * (`Proposal`, `ProposalAction`, `AcceptResult`, `LLMJudge`,
21
+ * `ExpectedShape`). TypeScript is structural, so a host that holds the
22
+ * real curator objects stays assignable to these copies and vice-versa.
23
+ * (2) The decline store — `loadDeclinedFingerprints` / `recordDecline` /
24
+ * `recordAcceptance`. These are stateless and idempotent (no in-memory
25
+ * state; each call reads/writes `data/_proactive-curator/` afresh), so a
26
+ * one-shot MCP tool can call them directly. Behavior is copied verbatim
27
+ * from the curator, including the prototype-pollution guard and the
28
+ * expire-on-read / purge-on-write semantics. Only the three functions
29
+ * memory-extended uses are inlined; the curator's `resetDeclined` and
30
+ * its insight/hub proposers are deliberately NOT brought along.
31
+ */
32
+ /**
33
+ * Host-supplied LLM adapter. Single-shot: a prompt plus a JSON-shaped
34
+ * expected answer in, a structured (runtime-validated) answer out. Structural
35
+ * copy of the curator's `LLMJudge` so a host's real judge stays compatible.
36
+ */
37
+ export interface LLMJudge {
38
+ readonly host: string;
39
+ ask(prompt: string, expected: ExpectedShape): Promise<unknown>;
40
+ }
41
+ /**
42
+ * Shape descriptor for the expected LLM response. `"string"` for a free-form
43
+ * answer; `"json"` for a JSON value matching a best-effort `schema` descriptor
44
+ * (the caller still runtime-validates). Structural copy of the curator type.
45
+ */
46
+ export type ExpectedShape = {
47
+ readonly shape: "string";
48
+ } | {
49
+ readonly shape: "json";
50
+ readonly schema: unknown;
51
+ };
52
+ /**
53
+ * Placement action chosen by a proposer. Four kinds cover the capture
54
+ * lifecycle. All paths are `data/`-relative so proposals never embed absolute
55
+ * paths. Structural copy of the curator's `ProposalAction` union.
56
+ */
57
+ export type ProposalAction = {
58
+ readonly kind: "create-folder";
59
+ readonly folderPath: string;
60
+ readonly filename: string;
61
+ readonly body: string;
62
+ } | {
63
+ readonly kind: "create-file";
64
+ readonly folderPath: string;
65
+ readonly filename: string;
66
+ readonly body: string;
67
+ } | {
68
+ readonly kind: "append-section";
69
+ readonly filePath: string;
70
+ readonly sectionHeader: string;
71
+ readonly body: string;
72
+ } | {
73
+ readonly kind: "update-file";
74
+ readonly filePath: string;
75
+ readonly body: string;
76
+ readonly reason: string;
77
+ };
78
+ /**
79
+ * A single proposal handed to the host for the user to accept or decline.
80
+ * `onAccept` / `onDecline` are thunks captured at evaluation time. Structural
81
+ * copy of the curator's `Proposal`; the consolidate namespace specializes it.
82
+ */
83
+ export interface Proposal {
84
+ readonly kind: string;
85
+ readonly fingerprint: string;
86
+ readonly action: ProposalAction;
87
+ readonly preview: string;
88
+ readonly rationale: string;
89
+ readonly sourceRefs: readonly string[];
90
+ readonly onAccept: () => Promise<AcceptResult>;
91
+ readonly onDecline: () => Promise<void>;
92
+ }
93
+ /**
94
+ * Result returned by {@link Proposal.onAccept}. Structural copy of the
95
+ * curator's `AcceptResult`.
96
+ */
97
+ export interface AcceptResult {
98
+ readonly writtenPath: string;
99
+ readonly actionApplied: ProposalAction["kind"];
100
+ readonly nextActionHint?: string;
101
+ }
102
+ /**
103
+ * Proposal kinds tracked in the declined-file structure. `capture-insight` and
104
+ * `create-hub` are the curator's own kinds; `mcp-document` is the document
105
+ * tools' kind. All three are persisted AND read back by
106
+ * {@link loadDeclinedFingerprints} so a recorded decline actually suppresses a
107
+ * later matching suggestion for the expiry window.
108
+ *
109
+ * (Historically `mcp-document` was written but never read back — see FIX M3 —
110
+ * which silently broke the document-tool 30-day suppression. It is now a
111
+ * first-class tracked kind.)
112
+ */
113
+ export type ProposalKind = "capture-insight" | "create-hub" | "mcp-document";
114
+ export interface DeclinedEntry {
115
+ /** ISO-8601 timestamp of when the user declined. */
116
+ readonly declinedAt: string;
117
+ /** Topic slug at decline time (audit trail; not part of the fingerprint). */
118
+ readonly topic: string;
119
+ /** ISO-8601 timestamp after which this entry is eligible for re-evaluation. */
120
+ readonly expiresAt: string;
121
+ /** The action the user declined — `create-file`, `append-section`, etc. */
122
+ readonly actionKind: ProposalAction["kind"];
123
+ /** Target path the declined action would have written/touched (data-relative). */
124
+ readonly targetPath: string;
125
+ /** Hub proposals only — the source-doc cluster that triggered this proposal. */
126
+ readonly sourceDocs?: readonly string[];
127
+ }
128
+ /**
129
+ * Load the active (un-expired) declined fingerprints. Missing or corrupt store
130
+ * files return an empty set rather than throwing.
131
+ */
132
+ export declare function loadDeclinedFingerprints(cwd: string, now: Date): Promise<ReadonlySet<string>>;
133
+ /**
134
+ * Persist a decline. Purges expired entries from disk in the same write so the
135
+ * store does not grow unbounded.
136
+ */
137
+ export declare function recordDecline(cwd: string, args: {
138
+ readonly kind: ProposalKind;
139
+ readonly fingerprint: string;
140
+ readonly topic: string;
141
+ readonly actionKind: ProposalAction["kind"];
142
+ readonly targetPath: string;
143
+ readonly sourceDocs?: readonly string[];
144
+ readonly now: Date;
145
+ readonly expiryDays?: number;
146
+ }): Promise<void>;
147
+ /**
148
+ * Append an acceptance record to the audit trail. Newline-delimited JSON so
149
+ * the file is grep-/tail-friendly without a parser.
150
+ */
151
+ export declare function recordAcceptance(cwd: string, args: {
152
+ readonly kind: ProposalKind;
153
+ readonly fingerprint: string;
154
+ readonly topic: string;
155
+ readonly actionKind: ProposalAction["kind"];
156
+ readonly writtenPath: string;
157
+ readonly now: Date;
158
+ }): Promise<void>;
159
+ /**
160
+ * Assert that `name` is a safe plain basename: non-empty, not "." or "..", and
161
+ * free of path separators, control characters, and Windows-reserved characters.
162
+ *
163
+ * Used at write boundaries where the destination FOLDER is a trusted constant
164
+ * (e.g. consolidate's fixed `_memory/` dir, which the canonical path gate
165
+ * rejects as a system dir, so containment relies on the basename instead). A
166
+ * denylist, not an ASCII allowlist, so non-Latin names (e.g. Korean) still
167
+ * pass. Throws a clear Error. Inlined here to keep the add-on standalone — see
168
+ * the file header.
169
+ */
170
+ export declare function assertSafeBasename(name: string): void;
171
+ //# sourceMappingURL=proactive-curator-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proactive-curator-helpers.d.ts","sourceRoot":"","sources":["../../src/internal/proactive-curator-helpers.ts"],"names":[],"mappings":"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"}