@intentface/latch-memory 0.9.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 (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +163 -0
  3. package/dist/extraction-key.d.ts +20 -0
  4. package/dist/extraction-key.d.ts.map +1 -0
  5. package/dist/extraction-key.js +43 -0
  6. package/dist/extraction-key.js.map +1 -0
  7. package/dist/index-file.d.ts +77 -0
  8. package/dist/index-file.d.ts.map +1 -0
  9. package/dist/index-file.js +169 -0
  10. package/dist/index-file.js.map +1 -0
  11. package/dist/index.d.ts +23 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +23 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/jobs/types.d.ts +133 -0
  16. package/dist/jobs/types.d.ts.map +1 -0
  17. package/dist/jobs/types.js +12 -0
  18. package/dist/jobs/types.js.map +1 -0
  19. package/dist/prompts/consolidator.d.ts +18 -0
  20. package/dist/prompts/consolidator.d.ts.map +1 -0
  21. package/dist/prompts/consolidator.js +76 -0
  22. package/dist/prompts/consolidator.js.map +1 -0
  23. package/dist/prompts/extractor.d.ts +34 -0
  24. package/dist/prompts/extractor.d.ts.map +1 -0
  25. package/dist/prompts/extractor.js +60 -0
  26. package/dist/prompts/extractor.js.map +1 -0
  27. package/dist/prompts/inject.d.ts +20 -0
  28. package/dist/prompts/inject.d.ts.map +1 -0
  29. package/dist/prompts/inject.js +58 -0
  30. package/dist/prompts/inject.js.map +1 -0
  31. package/dist/provider.d.ts +47 -0
  32. package/dist/provider.d.ts.map +1 -0
  33. package/dist/provider.js +101 -0
  34. package/dist/provider.js.map +1 -0
  35. package/dist/sanitize.d.ts +29 -0
  36. package/dist/sanitize.d.ts.map +1 -0
  37. package/dist/sanitize.js +88 -0
  38. package/dist/sanitize.js.map +1 -0
  39. package/dist/schema.d.ts +60 -0
  40. package/dist/schema.d.ts.map +1 -0
  41. package/dist/schema.js +144 -0
  42. package/dist/schema.js.map +1 -0
  43. package/dist/scope.d.ts +62 -0
  44. package/dist/scope.d.ts.map +1 -0
  45. package/dist/scope.js +136 -0
  46. package/dist/scope.js.map +1 -0
  47. package/dist/search-evidence.d.ts +34 -0
  48. package/dist/search-evidence.d.ts.map +1 -0
  49. package/dist/search-evidence.js +40 -0
  50. package/dist/search-evidence.js.map +1 -0
  51. package/dist/store/loredex.d.ts +61 -0
  52. package/dist/store/loredex.d.ts.map +1 -0
  53. package/dist/store/loredex.js +558 -0
  54. package/dist/store/loredex.js.map +1 -0
  55. package/dist/store/memory.d.ts +31 -0
  56. package/dist/store/memory.d.ts.map +1 -0
  57. package/dist/store/memory.js +156 -0
  58. package/dist/store/memory.js.map +1 -0
  59. package/dist/tools.d.ts +91 -0
  60. package/dist/tools.d.ts.map +1 -0
  61. package/dist/tools.js +389 -0
  62. package/dist/tools.js.map +1 -0
  63. package/dist/types.d.ts +130 -0
  64. package/dist/types.d.ts.map +1 -0
  65. package/dist/types.js +13 -0
  66. package/dist/types.js.map +1 -0
  67. package/package.json +60 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-evidence.js","sourceRoot":"","sources":["../src/search-evidence.ts"],"names":[],"mappings":"AAkBA,iEAAiE;AACjE,MAAM,CAAC,MAAM,aAAa,GAAkC;IAC1D,aAAa,EAAE,CAAC;IAChB,WAAW,EAAE,CAAC;IACd,IAAI,EAAE,CAAC;CACR,CAAC;AAEF,qEAAqE;AACrE,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AAC1E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAC3B,KAAa,EACb,KAA2C;IAE3C,MAAM,CAAC,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;IACnC,IAAI,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACzB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,aAAa,CAAC;IAChF,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,aAAa,CAAC;IACrF,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,QAAkC;IAC/D,IAAI,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC;QAAE,OAAO,QAAQ,CAAC;IACtD,IAAI,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC;QAAE,OAAO,UAAU,CAAC;IACxD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,61 @@
1
+ import type { ConnectionRegistry } from "@intentface/latch-core";
2
+ import type { MemoryStore } from "../types.js";
3
+ /**
4
+ * MemoryStore over a Loredex MCP connection.
5
+ *
6
+ * Every operation opens the connection fresh (`hostFor([conn]).open(principal)`),
7
+ * calls the namespaced tools programmatically, and closes — the same pattern
8
+ * platform read-tools use. It deliberately does NOT share the agent turn's
9
+ * opened connection set: that would couple the store to the turn lifecycle for
10
+ * one saved round-trip.
11
+ *
12
+ * Loredex tool shapes this store relies on (verified against the live server;
13
+ * override names via `toolNames` if a workspace exposes variants):
14
+ * - `read_file { fileId }` — path-addressable reads.
15
+ * - `create { type, name, folderId?, parentId?, content?, summary? }` — files
16
+ * and folders; there is no overwrite. Folder creates are NOT idempotent:
17
+ * a repeat call with the same name+parent inserts a DUPLICATE sibling rather
18
+ * than erroring, so `ensureFolders` probes before it creates. For `.md`,
19
+ * `summary` is injected as YAML frontmatter into the stored file — so the
20
+ * bytes on disk are never quite the `content` we handed over.
21
+ * - `edit_file { fileId, replacements: [{ oldContent, newContent }] }` —
22
+ * search-and-replace only; a full rewrite replaces the whole previous text.
23
+ * For `.md` it splits frontmatter off and matches the BODY ALONE, so
24
+ * `oldContent` must never include the frontmatter (see `splitFrontmatter`).
25
+ * - `search { query, folderId?, limit?, mode? }` — BM25, folder-scopable.
26
+ *
27
+ * There is no delete/move tool, so nothing here ever destroys content: index
28
+ * rewrites snapshot the previous version into `archive/index-snapshots/`.
29
+ */
30
+ export interface LoredexToolNames {
31
+ read: string;
32
+ create: string;
33
+ edit: string;
34
+ search: string;
35
+ }
36
+ /**
37
+ * Split a leading `---\n…\n---` frontmatter block off a file's text.
38
+ *
39
+ * Loredex OWNS that block on `.md` files, and both halves of the rewrite depend
40
+ * on it: `create` injects the `summary` we pass into frontmatter, and `edit_file`
41
+ * splits frontmatter off and runs replacements against the BODY ALONE. So the
42
+ * index file we read back is `frontmatter + body` while the text `edit_file` can
43
+ * actually match is `body` — handing the whole read back as `oldContent` matches
44
+ * nothing, forever, from the second consolidation onward. The store therefore
45
+ * owns the body and leaves the frontmatter to Loredex.
46
+ *
47
+ * Structural, exactly like the server's own `splitFrontmatter`: the block is
48
+ * located by its `---` delimiters and never YAML-parsed, so a malformed-but-
49
+ * delimited block is still recognized (and left alone) rather than leaking into
50
+ * the body, where it would put bytes into `oldContent` that `edit_file` cannot
51
+ * see.
52
+ */
53
+ export declare function splitFrontmatter(text: string): {
54
+ frontmatter: string;
55
+ body: string;
56
+ };
57
+ export declare function createLoredexStore<P>(opts: {
58
+ connections: ConnectionRegistry<P>;
59
+ toolNames?: Partial<LoredexToolNames>;
60
+ }): MemoryStore<P>;
61
+ //# sourceMappingURL=loredex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loredex.d.ts","sourceRoot":"","sources":["../../src/store/loredex.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAgC,WAAW,EAAY,MAAM,aAAa,CAAC;AAUvF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAgFD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAUpF;AAcD,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,IAAI,EAAE;IAC1C,WAAW,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACvC,GAAG,WAAW,CAAC,CAAC,CAAC,CA+XjB"}
@@ -0,0 +1,558 @@
1
+ import { MemoryStoreUnreachableError } from "../types.js";
2
+ import { isUnderScopeRoot, LOREDEX_PRIVATE_ROOT, LOREDEX_SHARED_ROOT } from "../scope.js";
3
+ import { IndexValidationError, MEMORY_INDEX_FILENAME, memoryIdsIn, validateIndexRewrite, } from "../index-file.js";
4
+ const DEFAULT_TOOL_NAMES = {
5
+ read: "read_file",
6
+ create: "create",
7
+ edit: "edit_file",
8
+ search: "search",
9
+ };
10
+ /**
11
+ * Loredex auto-creates this file inside every folder it makes, so reading it is
12
+ * how `ensureFolders` asks "does this folder exist?" without a folder-stat tool.
13
+ */
14
+ const FOLDER_INDEX_FILENAME = "index.md";
15
+ /** Flatten an MCP CallToolResult (or any tool return) to text. */
16
+ function textOf(result) {
17
+ if (result == null)
18
+ return "";
19
+ if (typeof result === "string")
20
+ return result;
21
+ const r = result;
22
+ if (Array.isArray(r.content)) {
23
+ return r.content
24
+ .map((c) => typeof c === "string" ? c : (c.text ?? ""))
25
+ .join("\n");
26
+ }
27
+ try {
28
+ return JSON.stringify(result);
29
+ }
30
+ catch {
31
+ return String(result);
32
+ }
33
+ }
34
+ function isErrorResult(result) {
35
+ return !!result?.isError;
36
+ }
37
+ /**
38
+ * `read_file` output → the file's body.
39
+ *
40
+ * Loredex does NOT return the body: it returns a JSON envelope
41
+ * (`{ file, content, totalLines, linksTo, … }`) whose `content` carries every
42
+ * line prefixed with its number — server-side, literally
43
+ * `lines.map((line, i) => \`${i + 1}|${line}\`).join("\n")`. Un-numbering is
44
+ * therefore exact and round-trips to the stored bytes, which `writeIndex`
45
+ * depends on: it hands the previous body straight back as `edit_file`'s
46
+ * `oldContent`, and a JSON envelope matches nothing in the file.
47
+ *
48
+ * Tolerant on purpose: a non-JSON result, a shape without a string `content`,
49
+ * or content that isn't line-numbered passes through untouched, so a plain-text
50
+ * server (or the range form, which we never ask for) still reads sensibly.
51
+ *
52
+ * Caveat: for `.md` reads Loredex renders insight blocks and strips ai-block
53
+ * config comments before numbering, so a body containing those markers decodes
54
+ * to the RENDERED text, not the stored bytes. Memory files are consolidator-
55
+ * authored and carry neither.
56
+ */
57
+ function decodeFileRead(text) {
58
+ let content;
59
+ try {
60
+ content = JSON.parse(text).content;
61
+ }
62
+ catch {
63
+ return text;
64
+ }
65
+ if (typeof content !== "string")
66
+ return text;
67
+ if (content === "")
68
+ return "";
69
+ const lines = content.split("\n");
70
+ // All lines or none: a partial match means this isn't a numbered body, and
71
+ // stripping the prefixes that happen to be there would corrupt the rest.
72
+ if (!lines.every((line) => /^\d+\|/.test(line)))
73
+ return text;
74
+ return lines.map((line) => line.replace(/^\d+\|/, "")).join("\n");
75
+ }
76
+ /**
77
+ * Split a leading `---\n…\n---` frontmatter block off a file's text.
78
+ *
79
+ * Loredex OWNS that block on `.md` files, and both halves of the rewrite depend
80
+ * on it: `create` injects the `summary` we pass into frontmatter, and `edit_file`
81
+ * splits frontmatter off and runs replacements against the BODY ALONE. So the
82
+ * index file we read back is `frontmatter + body` while the text `edit_file` can
83
+ * actually match is `body` — handing the whole read back as `oldContent` matches
84
+ * nothing, forever, from the second consolidation onward. The store therefore
85
+ * owns the body and leaves the frontmatter to Loredex.
86
+ *
87
+ * Structural, exactly like the server's own `splitFrontmatter`: the block is
88
+ * located by its `---` delimiters and never YAML-parsed, so a malformed-but-
89
+ * delimited block is still recognized (and left alone) rather than leaking into
90
+ * the body, where it would put bytes into `oldContent` that `edit_file` cannot
91
+ * see.
92
+ */
93
+ export function splitFrontmatter(text) {
94
+ const trimmed = text.trimStart();
95
+ if (!trimmed.startsWith("---"))
96
+ return { frontmatter: "", body: text };
97
+ const end = trimmed.indexOf("\n---", 3);
98
+ if (end === -1)
99
+ return { frontmatter: "", body: text };
100
+ const offset = text.length - trimmed.length;
101
+ return {
102
+ frontmatter: text.slice(0, offset + end + 4),
103
+ body: text.slice(offset + end + 4).replace(/^\n/, ""),
104
+ };
105
+ }
106
+ /**
107
+ * Does this tool error definitively mean "the file isn't there"?
108
+ *
109
+ * Loredex answers an unresolvable read with `File not found: <ref>` on every
110
+ * path (bad id, unresolvable path, missing row). Everything else — tool
111
+ * unavailable, transport failure, an out-of-scope folder — leaves existence
112
+ * UNKNOWN, and `ensureFolders` must not create on an unknown.
113
+ */
114
+ function isDefinitelyMissing(error) {
115
+ return /not found/i.test(error);
116
+ }
117
+ export function createLoredexStore(opts) {
118
+ const names = { ...DEFAULT_TOOL_NAMES, ...opts.toolNames };
119
+ // Folder prefixes confirmed to exist this process lifetime (`<scope key>:<path>`),
120
+ // so repeat writes skip the existence probe. Correctness never depends on it:
121
+ // a cold cache (every serverless start) just re-probes.
122
+ const ensuredFolders = new Set();
123
+ /**
124
+ * Ensures currently in flight, keyed the same way. Without this, two
125
+ * concurrent writes for one scope (a turn running `memory_write` and
126
+ * `memory_index` in parallel) both probe a missing folder, both see it
127
+ * absent, and both create it — the duplicate this store exists to avoid.
128
+ *
129
+ * In-process only. Two instances racing can still duplicate, which is why
130
+ * the server-side idempotent create matters (Intentface/loredex#149).
131
+ */
132
+ const ensuringFolders = new Map();
133
+ /** Open the scope's connection, run `fn` with a tool caller, always close. */
134
+ async function withConnection(principal, scope, fn) {
135
+ let opened;
136
+ try {
137
+ opened = await opts.connections.hostFor([scope.connection]).open(principal);
138
+ }
139
+ catch {
140
+ return undefined;
141
+ }
142
+ try {
143
+ const call = async (tool, input) => {
144
+ const t = opened.tools[`${scope.connection}_${tool}`];
145
+ if (!t || typeof t.execute !== "function") {
146
+ return { ok: false, unavailable: true, error: `tool not available: ${tool}` };
147
+ }
148
+ try {
149
+ const result = await t.execute(input, {
150
+ toolCallId: `memory_${Math.random().toString(36).slice(2, 10)}`,
151
+ messages: [],
152
+ });
153
+ const text = textOf(result);
154
+ if (isErrorResult(result))
155
+ return { ok: false, error: text };
156
+ return { ok: true, text };
157
+ }
158
+ catch (error) {
159
+ return { ok: false, error: String(error) };
160
+ }
161
+ };
162
+ return await fn(call);
163
+ }
164
+ finally {
165
+ await opened.close().catch(() => { });
166
+ }
167
+ }
168
+ /**
169
+ * Create the folder chain for `path` (workspace-relative), skipping segments
170
+ * that already exist.
171
+ *
172
+ * Loredex's folder `create` does NOT reject a duplicate name: it inserts a
173
+ * second sibling with the same name, and path resolution then silently
174
+ * resolves to whichever the traversal reaches first — so a blind re-create
175
+ * leaves a trail of empty shadow folders (each with just its auto `index.md`)
176
+ * that nothing can delete, since there is no delete tool. So probe first.
177
+ *
178
+ * The probe reads the segment's auto-created `index.md`: folders themselves
179
+ * aren't addressable by `read_file`, but every Loredex folder has that file.
180
+ *
181
+ * Caching is per PREFIX, not per full path — `writeIndex` ensures `root`
182
+ * while `writeEpisode` ensures `root/episodes`, so a whole-path key made the
183
+ * second call re-walk (and, before the probe, re-create) every shared
184
+ * ancestor.
185
+ */
186
+ async function ensureFolders(call, scopeKey, path) {
187
+ const parts = path.split("/").filter(Boolean);
188
+ // The workspace root folders always exist (Loredex provisions them) and
189
+ // must never be created here — a `create` for either name would mint a
190
+ // stray top-level folder shadowing it. Start below them; descendants then
191
+ // inherit the root's visibility (`private` under the caller's private
192
+ // root, `shared` under the workspace-shared root).
193
+ const first = parts[0] === LOREDEX_PRIVATE_ROOT || parts[0] === LOREDEX_SHARED_ROOT ? 1 : 0;
194
+ for (let i = first; i < parts.length; i++) {
195
+ const cacheKey = `${scopeKey}:${parts.slice(0, i + 1).join("/")}`;
196
+ if (ensuredFolders.has(cacheKey))
197
+ continue;
198
+ // Share an in-flight ensure rather than racing it. Deleted on settle so a
199
+ // failed attempt is retried by the next write instead of being awaited
200
+ // forever.
201
+ let pending = ensuringFolders.get(cacheKey);
202
+ if (!pending) {
203
+ pending = ensureOneFolder(call, cacheKey, parts, i).finally(() => {
204
+ ensuringFolders.delete(cacheKey);
205
+ });
206
+ ensuringFolders.set(cacheKey, pending);
207
+ }
208
+ await pending;
209
+ }
210
+ }
211
+ /** One segment of `ensureFolders`: probe `parts[i]`, create it if truly absent. */
212
+ async function ensureOneFolder(call, cacheKey, parts, i) {
213
+ const prefix = parts.slice(0, i + 1).join("/");
214
+ const probe = await call(names.read, {
215
+ fileId: `${prefix}/${FOLDER_INDEX_FILENAME}`,
216
+ });
217
+ if (probe.ok) {
218
+ ensuredFolders.add(cacheKey);
219
+ return;
220
+ }
221
+ // Only a definitive "not found" licenses a create. Any other failure —
222
+ // tool unavailable, transport error, an out-of-scope folder — leaves
223
+ // existence unknown, and creating on a guess is precisely how the shadow
224
+ // folders appeared. Bail instead: the write that follows surfaces the real
225
+ // error, and the next run re-probes. Guessing wrong here is unrecoverable
226
+ // (no delete tool); guessing "exists" costs one retry.
227
+ if (!isDefinitelyMissing(probe.error))
228
+ return;
229
+ const parentId = parts.slice(0, i).join("/") || undefined;
230
+ const created = await call(names.create, {
231
+ type: "folder",
232
+ name: parts[i],
233
+ ...(parentId ? { parentId } : {}),
234
+ });
235
+ // Only remember what we know exists: a failed create must be retried on
236
+ // the next write, not cached as done.
237
+ if (created.ok)
238
+ ensuredFolders.add(cacheKey);
239
+ }
240
+ function indexPath(scope) {
241
+ return `${scope.root}/${MEMORY_INDEX_FILENAME}`;
242
+ }
243
+ /**
244
+ * The index's BODY — Loredex's frontmatter stripped. That is the text every
245
+ * consumer wants (entry lines, not a `summary:` block the provider would
246
+ * otherwise inject into the agent's instructions), and it is the only text
247
+ * `edit_file` can match.
248
+ */
249
+ async function readIndexWith(call, scope) {
250
+ const res = await call(names.read, { fileId: indexPath(scope) });
251
+ if (!res.ok)
252
+ return undefined;
253
+ return splitFrontmatter(decodeFileRead(res.text)).body;
254
+ }
255
+ return {
256
+ async available(principal, scope) {
257
+ const probe = await withConnection(principal, scope, async (call) => {
258
+ const res = await call(names.search, { query: "memory", folderId: scope.root, limit: 1 });
259
+ return !("unavailable" in res && res.unavailable);
260
+ });
261
+ return probe ?? false;
262
+ },
263
+ async readIndex(principal, scope) {
264
+ return withConnection(principal, scope, (call) => readIndexWith(call, scope));
265
+ },
266
+ async writeIndex(principal, scope, text) {
267
+ // Unreachable store (open failed / tools absent) → MemoryStoreUnreachableError
268
+ // ("retry later"); a rejected rewrite → IndexValidationError ("fix content").
269
+ const fail = (what, res) => {
270
+ if (res.unavailable)
271
+ throw new MemoryStoreUnreachableError(`memory store unreachable (${res.error})`);
272
+ throw new Error(`${what}: ${res.error}`);
273
+ };
274
+ // What we write is the BODY. A consolidator that read the index saw the
275
+ // frontmatter Loredex injected and routinely echoes it back at the top of
276
+ // its rewrite; keeping it would both duplicate the block on disk and put
277
+ // unmatchable bytes into `oldContent`.
278
+ const body = splitFrontmatter(text).body;
279
+ const result = await withConnection(principal, scope, async (call) => {
280
+ const prev = await readIndexWith(call, scope);
281
+ const problems = validateIndexRewrite(prev, body);
282
+ if (problems.length > 0)
283
+ throw new IndexValidationError(problems);
284
+ if (prev !== undefined && prev.trim().length > 0) {
285
+ // Snapshot BEFORE the rewrite; a failed snapshot aborts the write —
286
+ // never rewrite history we couldn't preserve.
287
+ const stamp = new Date().toISOString().replace(/[:.]/g, "-");
288
+ const snapDir = `${scope.root}/archive/index-snapshots`;
289
+ await ensureFolders(call, scope.key, snapDir);
290
+ const snapshot = (name) => call(names.create, {
291
+ type: "file",
292
+ name,
293
+ folderId: snapDir,
294
+ content: prev,
295
+ summary: "Memory index snapshot (pre-consolidation)",
296
+ });
297
+ let snap = await snapshot(`MEMORY-${stamp}.md`);
298
+ if (!snap.ok && /exist/i.test(snap.error)) {
299
+ // Two rewrites inside the same millisecond collide on the name, and
300
+ // an aborted write here means a consolidation that can never land.
301
+ // Disambiguate once, as `writeEpisode` does.
302
+ snap = await snapshot(`MEMORY-${stamp}-${Math.random().toString(36).slice(2, 6)}.md`);
303
+ }
304
+ if (!snap.ok)
305
+ fail("memory index snapshot failed", snap);
306
+ let edit = await call(names.edit, {
307
+ fileId: indexPath(scope),
308
+ replacements: [{ oldContent: prev, newContent: body }],
309
+ });
310
+ // A match failure means the file changed under us (a concurrent
311
+ // consolidation, a human editing MEMORY.md in Loredex), which Loredex
312
+ // answers with "re-read and try again". Do exactly that, once —
313
+ // re-validating against the CURRENT entries, so an entry added
314
+ // meanwhile can't be dropped either — and reuse the snapshot already
315
+ // taken. One retry, not a loop: a second failure is a real conflict,
316
+ // and each attempt would otherwise leave another undeletable snapshot.
317
+ if (!edit.ok && !("unavailable" in edit)) {
318
+ const fresh = await readIndexWith(call, scope);
319
+ if (fresh !== undefined && fresh !== prev && fresh.trim().length > 0) {
320
+ const freshProblems = validateIndexRewrite(fresh, body);
321
+ if (freshProblems.length > 0)
322
+ throw new IndexValidationError(freshProblems);
323
+ edit = await call(names.edit, {
324
+ fileId: indexPath(scope),
325
+ replacements: [{ oldContent: fresh, newContent: body }],
326
+ });
327
+ }
328
+ }
329
+ if (!edit.ok)
330
+ fail("memory index rewrite failed", edit);
331
+ }
332
+ else {
333
+ // `prev === ""` (the file exists but its body is empty) lands here and
334
+ // fails the create as "already exists" — deliberately loud: `edit_file`
335
+ // rejects an empty `oldContent`, so there is nothing to replace and
336
+ // guessing would mean clobbering a file we can't read.
337
+ await ensureFolders(call, scope.key, scope.root);
338
+ const created = await call(names.create, {
339
+ type: "file",
340
+ name: MEMORY_INDEX_FILENAME,
341
+ folderId: scope.root,
342
+ content: body,
343
+ summary: "Compiled memory index (managed by the memory consolidator)",
344
+ });
345
+ if (!created.ok)
346
+ fail("memory index create failed", created);
347
+ }
348
+ return true;
349
+ });
350
+ if (result === undefined)
351
+ throw new MemoryStoreUnreachableError("memory store unreachable (connection failed)");
352
+ },
353
+ async writeEpisode(principal, scope, episode) {
354
+ return withConnection(principal, scope, async (call) => {
355
+ const dir = `${scope.root}/episodes`;
356
+ await ensureFolders(call, scope.key, dir);
357
+ // Chronologically sortable name — the filename IS the ordering key.
358
+ const stamp = episode.meta.extractedAt.slice(0, 16).replace("T", "-").replace(":", "-");
359
+ const slug = episode.slug
360
+ .replace(/[^a-zA-Z0-9_-]/g, "-")
361
+ .replace(/-{2,}/g, "-")
362
+ .replace(/^-+|-+$/g, "")
363
+ .slice(0, 48) || "note";
364
+ const frontmatter = [
365
+ "---",
366
+ ...(episode.meta.chat ? [`chat: ${episode.meta.chat}`] : []),
367
+ `agent: ${episode.meta.agent}`,
368
+ `extracted_at: ${episode.meta.extractedAt}`,
369
+ `provenance: ${episode.meta.provenance}`,
370
+ ...(episode.meta.aliases?.length
371
+ ? [`aliases: [${episode.meta.aliases.join(", ")}]`]
372
+ : []),
373
+ ...(episode.meta.status ? [`status: ${episode.meta.status}`] : []),
374
+ "---",
375
+ ].join("\n");
376
+ const content = `${frontmatter}\n\n${episode.body.trim()}\n`;
377
+ let name = `${stamp}-${slug}.md`;
378
+ let created = await call(names.create, {
379
+ type: "file",
380
+ name,
381
+ folderId: dir,
382
+ content,
383
+ summary: episode.summary,
384
+ });
385
+ if (!created.ok && /exist/i.test(created.error)) {
386
+ // Same minute + same slug: disambiguate once rather than fail.
387
+ name = `${stamp}-${slug}-${Math.random().toString(36).slice(2, 6)}.md`;
388
+ created = await call(names.create, {
389
+ type: "file",
390
+ name,
391
+ folderId: dir,
392
+ content,
393
+ summary: episode.summary,
394
+ });
395
+ }
396
+ if (!created.ok)
397
+ return undefined;
398
+ return { path: `${dir}/${name}`, name };
399
+ });
400
+ },
401
+ async readEpisodes(principal, scope, paths) {
402
+ // Defense-in-depth: enforce the scope boundary here too, so a future
403
+ // caller that forgets to pre-filter can't read outside the scope root.
404
+ const safePaths = paths.filter((p) => isUnderScopeRoot(scope.root, p));
405
+ const result = await withConnection(principal, scope, async (call) => {
406
+ // Individual reads (not the batch form): per-file failures skip that
407
+ // file instead of poisoning a combined result we'd have to re-split.
408
+ const out = [];
409
+ for (const path of safePaths) {
410
+ const res = await call(names.read, { fileId: path });
411
+ if (res.ok)
412
+ out.push({ path, text: decodeFileRead(res.text) });
413
+ }
414
+ return out;
415
+ });
416
+ return result ?? [];
417
+ },
418
+ async search(principal, scope, query, limit = 6) {
419
+ const result = await withConnection(principal, scope, async (call) => {
420
+ const res = await call(names.search, {
421
+ query,
422
+ folderId: scope.root,
423
+ limit,
424
+ mode: "text",
425
+ });
426
+ if (!res.ok)
427
+ return [];
428
+ return parseSearchHits(res.text, scope, limit);
429
+ });
430
+ return result ?? [];
431
+ },
432
+ async readFile(principal, { connection, path }) {
433
+ // Path-addressed read of a code-owned auxiliary file (e.g. the shared
434
+ // user-level SCHEMA.md). Synthetic scope: withConnection only uses
435
+ // `.connection`; key/root are for the folder-ensure cache, unused here.
436
+ // Same body/frontmatter split as the index: the store owns the BODY,
437
+ // Loredex owns the frontmatter it injects from `summary`.
438
+ const scope = { key: `${connection}:${dirnameOf(path)}`, connection, root: dirnameOf(path) };
439
+ return withConnection(principal, scope, async (call) => {
440
+ const res = await call(names.read, { fileId: path });
441
+ if (!res.ok)
442
+ return undefined;
443
+ return splitFrontmatter(decodeFileRead(res.text)).body;
444
+ });
445
+ },
446
+ async writeFile(principal, { connection, path, content, summary }) {
447
+ const dir = dirnameOf(path);
448
+ // dir === "" for a bare filename — slice(1) would eat the first char.
449
+ const name = dir ? path.slice(dir.length + 1) : path;
450
+ const scope = { key: `${connection}:${dir}`, connection, root: dir };
451
+ // The store owns the BODY only (see writeIndex): `create` injects
452
+ // `summary` as frontmatter, `edit_file` matches the body alone — so
453
+ // strip any frontmatter a caller echoed back, read prev as body, and
454
+ // hand edit_file body-for-body.
455
+ const body = splitFrontmatter(content).body;
456
+ const result = await withConnection(principal, scope, async (call) => {
457
+ const prevRes = await call(names.read, { fileId: path });
458
+ const prev = prevRes.ok ? splitFrontmatter(decodeFileRead(prevRes.text)).body : undefined;
459
+ if (prev !== undefined) {
460
+ if (prev === body)
461
+ return true;
462
+ const edit = await call(names.edit, {
463
+ fileId: path,
464
+ replacements: [{ oldContent: prev, newContent: body }],
465
+ });
466
+ if (!edit.ok) {
467
+ if ("unavailable" in edit && edit.unavailable)
468
+ throw new MemoryStoreUnreachableError(`memory store unreachable (${edit.error})`);
469
+ throw new Error(`memory file rewrite failed: ${edit.error}`);
470
+ }
471
+ return true;
472
+ }
473
+ await ensureFolders(call, scope.key, dir);
474
+ const created = await call(names.create, {
475
+ type: "file",
476
+ name,
477
+ folderId: dir,
478
+ content: body,
479
+ ...(summary ? { summary } : {}),
480
+ });
481
+ if (!created.ok) {
482
+ if ("unavailable" in created && created.unavailable)
483
+ throw new MemoryStoreUnreachableError(`memory store unreachable (${created.error})`);
484
+ throw new Error(`memory file create failed: ${created.error}`);
485
+ }
486
+ return true;
487
+ });
488
+ if (result === undefined)
489
+ throw new MemoryStoreUnreachableError("memory store unreachable (connection failed)");
490
+ },
491
+ };
492
+ }
493
+ /** Workspace-relative dirname ("a/b/c.md" → "a/b"; bare filename → ""). */
494
+ function dirnameOf(path) {
495
+ const i = path.lastIndexOf("/");
496
+ return i === -1 ? "" : path.slice(0, i);
497
+ }
498
+ /**
499
+ * Loredex search output → hits. The result shape isn't pinned by the MCP
500
+ * contract, so parse tolerantly: JSON with a results/hits array when present,
501
+ * otherwise treat the whole text as one hit (still useful to the model; usage
502
+ * tracking degrades to the `[m-…]` ids found in the text).
503
+ */
504
+ function parseSearchHits(text, scope, limit) {
505
+ const trimmed = text.trim();
506
+ if (!trimmed)
507
+ return [];
508
+ try {
509
+ const parsed = JSON.parse(trimmed);
510
+ const arr = Array.isArray(parsed)
511
+ ? parsed
512
+ : (parsed.results ??
513
+ parsed.hits);
514
+ if (Array.isArray(arr)) {
515
+ return arr.slice(0, limit).map((raw) => {
516
+ const r = raw;
517
+ const str = (v) => typeof v === "string" && v.length > 0 ? v : undefined;
518
+ // Loredex (live) returns `{ id: "file_…", title: "<filename>", snippet }`
519
+ // with no path field. A title under the searched scope root is the best
520
+ // file identity available without extra lookups; the opaque id still
521
+ // resolves in read tools, so it is the next fallback — never the bare
522
+ // scope root, which erases the hit's identity for every consumer
523
+ // (ranking evals, episode detection, usage tracking).
524
+ const path = str(r.path) ??
525
+ str(r.file) ??
526
+ str(r.fileId) ??
527
+ (str(r.title) ? `${scope.root}/${str(r.title)}` : undefined) ??
528
+ str(r.id) ??
529
+ // No identity fields at all: keep the hit under the bare root —
530
+ // the same contract as the plain-text fallback below, where
531
+ // `scope.root` means "no per-file identity" (hitIds skips it,
532
+ // evals filter it) but the snippet is still useful to the model.
533
+ scope.root;
534
+ const snippet = str(r.snippet) ?? str(r.content) ?? str(r.text) ?? str(r.title) ?? textOfRaw(r);
535
+ return { path, snippet, memoryIds: hitIds(path, snippet) };
536
+ });
537
+ }
538
+ }
539
+ catch {
540
+ // fall through — plain-text result
541
+ }
542
+ return [{ path: scope.root, snippet: trimmed, memoryIds: hitIds(undefined, trimmed) }];
543
+ }
544
+ function textOfRaw(r) {
545
+ try {
546
+ return JSON.stringify(r);
547
+ }
548
+ catch {
549
+ return String(r);
550
+ }
551
+ }
552
+ function hitIds(path, snippet) {
553
+ const ids = memoryIdsIn(snippet);
554
+ if (path && /\/episodes\//.test(path))
555
+ ids.push(path);
556
+ return Array.from(new Set(ids));
557
+ }
558
+ //# sourceMappingURL=loredex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loredex.js","sourceRoot":"","sources":["../../src/store/loredex.ts"],"names":[],"mappings":"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"}