@moxxy/plugin-memory 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/LICENSE +21 -0
  2. package/dist/consolidate.d.ts +62 -0
  3. package/dist/consolidate.d.ts.map +1 -0
  4. package/dist/consolidate.js +417 -0
  5. package/dist/consolidate.js.map +1 -0
  6. package/dist/embedding-cache.d.ts +32 -0
  7. package/dist/embedding-cache.d.ts.map +1 -0
  8. package/dist/embedding-cache.js +146 -0
  9. package/dist/embedding-cache.js.map +1 -0
  10. package/dist/index.d.ts +31 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +217 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/parse.d.ts +5 -0
  15. package/dist/parse.d.ts.map +1 -0
  16. package/dist/parse.js +9 -0
  17. package/dist/parse.js.map +1 -0
  18. package/dist/stm.d.ts +20 -0
  19. package/dist/stm.d.ts.map +1 -0
  20. package/dist/stm.js +38 -0
  21. package/dist/stm.js.map +1 -0
  22. package/dist/store/io.d.ts +13 -0
  23. package/dist/store/io.d.ts.map +1 -0
  24. package/dist/store/io.js +124 -0
  25. package/dist/store/io.js.map +1 -0
  26. package/dist/store/search.d.ts +10 -0
  27. package/dist/store/search.d.ts.map +1 -0
  28. package/dist/store/search.js +160 -0
  29. package/dist/store/search.js.map +1 -0
  30. package/dist/store/types.d.ts +33 -0
  31. package/dist/store/types.d.ts.map +1 -0
  32. package/dist/store/types.js +11 -0
  33. package/dist/store/types.js.map +1 -0
  34. package/dist/store.d.ts +95 -0
  35. package/dist/store.d.ts.map +1 -0
  36. package/dist/store.js +220 -0
  37. package/dist/store.js.map +1 -0
  38. package/dist/tfidf.d.ts +29 -0
  39. package/dist/tfidf.d.ts.map +1 -0
  40. package/dist/tfidf.js +103 -0
  41. package/dist/tfidf.js.map +1 -0
  42. package/package.json +62 -0
  43. package/src/consolidate-nudge.test.ts +98 -0
  44. package/src/consolidate.test.ts +328 -0
  45. package/src/consolidate.ts +535 -0
  46. package/src/discovery.test.ts +33 -0
  47. package/src/embedding-cache.test.ts +268 -0
  48. package/src/embedding-cache.ts +156 -0
  49. package/src/index.test.ts +67 -0
  50. package/src/index.ts +247 -0
  51. package/src/parse.ts +12 -0
  52. package/src/stm.test.ts +69 -0
  53. package/src/stm.ts +48 -0
  54. package/src/store/io.test.ts +100 -0
  55. package/src/store/io.ts +138 -0
  56. package/src/store/search.test.ts +185 -0
  57. package/src/store/search.ts +197 -0
  58. package/src/store/types.ts +23 -0
  59. package/src/store.test.ts +186 -0
  60. package/src/store.ts +292 -0
  61. package/src/tfidf.test.ts +59 -0
  62. package/src/tfidf.ts +105 -0
  63. package/src/vector-recall.test.ts +88 -0
@@ -0,0 +1,146 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { promises as fs } from 'node:fs';
3
+ import * as path from 'node:path';
4
+ import { writeFileAtomic } from '@moxxy/sdk/server';
5
+ const INDEX_FILE = '.embeddings.json';
6
+ const INDEX_VERSION = 1;
7
+ /**
8
+ * Persists computed embeddings to `<memoryDir>/.embeddings.json` keyed by
9
+ * content hash. The cache is invalidated when the embedder name OR its
10
+ * dimensionality changes — a name alone is too coarse (e.g. the OpenAI embedder
11
+ * reports a fixed name across models/`dimensions` settings, so a 1536→3072
12
+ * model switch must invalidate on the dim mismatch or recall compares
13
+ * incomparable vectors).
14
+ */
15
+ export class EmbeddingIndex {
16
+ dir;
17
+ embedderName;
18
+ dim;
19
+ cache = new Map();
20
+ dirty = false;
21
+ loaded = false;
22
+ constructor(dir, embedderName, dim) {
23
+ this.dir = dir;
24
+ this.embedderName = embedderName;
25
+ this.dim = dim;
26
+ }
27
+ static hash(text) {
28
+ return createHash('sha256').update(text).digest('hex').slice(0, 24);
29
+ }
30
+ get filePath() {
31
+ return path.join(this.dir, INDEX_FILE);
32
+ }
33
+ async load() {
34
+ // Read the on-disk cache at most once per instance. The store memoizes this
35
+ // index for its lifetime and is the single writer (flush() keeps disk in
36
+ // sync for our own writes), so re-reading + re-parsing the whole file on
37
+ // every recall is pure overhead — the in-memory Map is already authoritative.
38
+ if (this.loaded)
39
+ return;
40
+ let raw;
41
+ try {
42
+ raw = await fs.readFile(this.filePath, 'utf8');
43
+ }
44
+ catch (err) {
45
+ if (!isEnoent(err))
46
+ throw err;
47
+ // No file on disk yet — still treat as loaded so subsequent recalls don't
48
+ // re-stat. This process is the single writer; flush() creates the file.
49
+ this.loaded = true;
50
+ return;
51
+ }
52
+ // The cache is a pure optimization: a corrupt/garbled/half-synced file
53
+ // (truncated JSON, manual edit, partial cloud-drive sync, schema drift) must
54
+ // degrade to a COLD cache, never permanently break every recall. Parse and
55
+ // shape-check defensively; on any failure, log and start empty.
56
+ this.loaded = true;
57
+ let parsed;
58
+ try {
59
+ parsed = JSON.parse(raw);
60
+ }
61
+ catch (err) {
62
+ console.warn(`[plugin-memory] ignoring corrupt embedding cache (${this.filePath}): ${String(err)}`);
63
+ return;
64
+ }
65
+ if (!isValidIndexFile(parsed))
66
+ return; // malformed shape → cold cache
67
+ if (parsed.version !== INDEX_VERSION)
68
+ return; // unknown format, ignore
69
+ if (parsed.embedder !== this.embedderName)
70
+ return; // embedder changed, invalidate
71
+ // Dim mismatch (incl. an old file written before dim was tracked) → the
72
+ // vectors are a different dimensionality; invalidate rather than mix them.
73
+ if (this.dim !== undefined && parsed.dim !== this.dim)
74
+ return;
75
+ for (const [name, entry] of Object.entries(parsed.entries)) {
76
+ if (isValidIndexEntry(entry))
77
+ this.cache.set(name, entry);
78
+ }
79
+ }
80
+ /**
81
+ * For a `(name, body)` pair, return either the cached vector (if the body
82
+ * hash matches) or `null` (miss). Callers re-embed the misses and call
83
+ * `set()` with the fresh vectors.
84
+ */
85
+ lookup(name, body) {
86
+ const entry = this.cache.get(name);
87
+ if (!entry)
88
+ return null;
89
+ if (entry.hash !== EmbeddingIndex.hash(body))
90
+ return null;
91
+ return entry.vector;
92
+ }
93
+ set(name, body, vector) {
94
+ const hash = EmbeddingIndex.hash(body);
95
+ const existing = this.cache.get(name);
96
+ if (existing && existing.hash === hash)
97
+ return;
98
+ this.cache.set(name, { hash, vector });
99
+ this.dirty = true;
100
+ }
101
+ /** Drop entries that no longer correspond to existing memories. */
102
+ prune(currentNames) {
103
+ const wanted = new Set(currentNames);
104
+ for (const name of [...this.cache.keys()]) {
105
+ if (!wanted.has(name)) {
106
+ this.cache.delete(name);
107
+ this.dirty = true;
108
+ }
109
+ }
110
+ }
111
+ async flush() {
112
+ if (!this.dirty)
113
+ return;
114
+ const data = {
115
+ version: INDEX_VERSION,
116
+ embedder: this.embedderName,
117
+ ...(this.dim !== undefined ? { dim: this.dim } : {}),
118
+ entries: Object.fromEntries(this.cache),
119
+ };
120
+ await writeFileAtomic(this.filePath, JSON.stringify(data), { mode: 0o600 });
121
+ this.dirty = false;
122
+ }
123
+ get size() {
124
+ return this.cache.size;
125
+ }
126
+ }
127
+ function isEnoent(err) {
128
+ return err instanceof Error && 'code' in err && err.code === 'ENOENT';
129
+ }
130
+ /** Structural guard so a valid-JSON-but-wrong-shape file (e.g. a missing
131
+ * `entries`) degrades to a cold cache instead of throwing in load(). */
132
+ function isValidIndexFile(value) {
133
+ if (typeof value !== 'object' || value === null)
134
+ return false;
135
+ const v = value;
136
+ return typeof v.entries === 'object' && v.entries !== null;
137
+ }
138
+ function isValidIndexEntry(value) {
139
+ if (typeof value !== 'object' || value === null)
140
+ return false;
141
+ const e = value;
142
+ return (typeof e.hash === 'string' &&
143
+ Array.isArray(e.vector) &&
144
+ e.vector.every((n) => typeof n === 'number'));
145
+ }
146
+ //# sourceMappingURL=embedding-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding-cache.js","sourceRoot":"","sources":["../src/embedding-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { type Plugin } from '@moxxy/sdk';
2
+ import { MemoryStore, type MemoryStoreOptions } from './store.js';
3
+ export { MemoryStore, memoryTypeSchema, memoryFrontmatterSchema, defaultMemoryDir, type MemoryEntry, type MemoryFrontmatter, type MemoryStoreOptions, type MemoryType, type RankedMemory, type RecallMode, } from './store.js';
4
+ export { parseMdFile, parseFrontmatter, renderFrontmatter } from './parse.js';
5
+ export { recentExchanges, summarizeSession, type SessionFact } from './stm.js';
6
+ export { TfIdfEmbedder, cosineSimilarity, tokenize } from './tfidf.js';
7
+ export { EmbeddingIndex } from './embedding-cache.js';
8
+ export { planConsolidation, consolidateMemory, buildMemoryConsolidatePlugin, memoryConsolidatePlugin, type ConsolidatePlan, type ConsolidateOptions, type ConsolidationOutcome, } from './consolidate.js';
9
+ export interface BuildMemoryPluginOptions extends MemoryStoreOptions {
10
+ }
11
+ export declare function buildMemoryPlugin(opts?: BuildMemoryPluginOptions): {
12
+ plugin: Plugin;
13
+ store: MemoryStore;
14
+ };
15
+ /**
16
+ * Discovery-loadable instance: the WHOLE memory feature (long-term store +
17
+ * memory_save/recall/… tools + the tfidf embedder + memory_consolidate and
18
+ * its nudge hooks) as ONE plugin, so the package unbundles cleanly — the
19
+ * loader takes a single default export per package. Composition over the
20
+ * existing builders:
21
+ * - the store's embedder resolves LAZILY from the host-published
22
+ * 'embedders' registry service (captured in onInit, read on first
23
+ * recall), replacing the bootstrap closure the CLI used to inject;
24
+ * - our onInit registers the 'memory' service FIRST, then runs
25
+ * consolidate's onInit, which resolves it — same ordering the two
26
+ * separate builtin entries relied on.
27
+ * `buildMemoryPlugin` stays for hosts/tests that inject their own store.
28
+ */
29
+ export declare const memoryPlugin: Plugin;
30
+ export default memoryPlugin;
31
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+C,KAAK,MAAM,EAAE,MAAM,YAAY,CAAC;AACtF,OAAO,EAAE,WAAW,EAAoB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGpF,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,uBAAuB,EACvB,gBAAgB,EAChB,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,UAAU,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,4BAA4B,EAC5B,uBAAuB,EACvB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,GAC1B,MAAM,kBAAkB,CAAC;AAG1B,MAAM,WAAW,wBAAyB,SAAQ,kBAAkB;CAAG;AAEvE,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,wBAA6B,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,CAuK7G;AAGD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,YAAY,EAAE,MA0BvB,CAAC;AAGL,eAAe,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,217 @@
1
+ import { defineTool, defineEmbedder, definePlugin, z } from '@moxxy/sdk';
2
+ import { MemoryStore, memoryTypeSchema } from './store.js';
3
+ import { TfIdfEmbedder } from './tfidf.js';
4
+ export { MemoryStore, memoryTypeSchema, memoryFrontmatterSchema, defaultMemoryDir, } from './store.js';
5
+ export { parseMdFile, parseFrontmatter, renderFrontmatter } from './parse.js';
6
+ export { recentExchanges, summarizeSession } from './stm.js';
7
+ export { TfIdfEmbedder, cosineSimilarity, tokenize } from './tfidf.js';
8
+ export { EmbeddingIndex } from './embedding-cache.js';
9
+ export { planConsolidation, consolidateMemory, buildMemoryConsolidatePlugin, memoryConsolidatePlugin, } from './consolidate.js';
10
+ import { memoryConsolidatePlugin as memoryConsolidatePluginRef } from './consolidate.js';
11
+ export function buildMemoryPlugin(opts = {}) {
12
+ const store = new MemoryStore(opts);
13
+ const plugin = definePlugin({
14
+ name: '@moxxy/plugin-memory',
15
+ version: '0.0.0',
16
+ // Publish the long-term store on the inter-plugin service registry so the
17
+ // sibling @moxxy/memory-consolidate plugin can resolve it in its own onInit
18
+ // instead of being hand-built with the store — the seam that lets both be
19
+ // discovery-loaded. memory-consolidate is registered after this plugin, so
20
+ // this onInit runs first.
21
+ hooks: {
22
+ onInit: (ctx) => {
23
+ ctx.services.register('memory', store);
24
+ },
25
+ },
26
+ // The zero-dep TF-IDF embedder, contributed as a selectable embedder so it
27
+ // sits in the same registry as openai/transformers/custom ones.
28
+ embedders: [
29
+ defineEmbedder({
30
+ name: 'tfidf',
31
+ displayName: 'TF-IDF (built-in, zero-dep)',
32
+ createClient: () => new TfIdfEmbedder(),
33
+ }),
34
+ ],
35
+ tools: [
36
+ defineTool({
37
+ name: 'memory_save',
38
+ description: 'Persist a memory to long-term storage. Use sparingly — only for facts/preferences/' +
39
+ 'project context that would help you in future sessions. Keep the body terse.',
40
+ inputSchema: z.object({
41
+ name: z.string().min(1).regex(/^[a-z0-9][a-z0-9-]*$/, 'name must be slug-like'),
42
+ type: memoryTypeSchema,
43
+ description: z.string().min(1).max(280),
44
+ body: z.string().min(1).max(4000),
45
+ tags: z.array(z.string().min(1)).optional(),
46
+ }),
47
+ permission: { action: 'prompt' },
48
+ isolation: {
49
+ capabilities: {
50
+ fs: { read: ['~/.moxxy/memory/**'], write: ['~/.moxxy/memory/**'] },
51
+ net: { mode: 'none' },
52
+ timeMs: 5_000,
53
+ },
54
+ },
55
+ handler: async ({ name, type, description, body, tags }) => {
56
+ const saved = await store.save({ name, type, description, body, tags });
57
+ const cap = await store.capStatus();
58
+ return {
59
+ name: saved.frontmatter.name,
60
+ path: saved.path,
61
+ // Warn-only soft cap: the save succeeded, but tell the model the
62
+ // store is overgrown so it consolidates / forgets stale entries.
63
+ ...(cap.over
64
+ ? {
65
+ warning: `memory store holds ${cap.count} entries (soft cap ${cap.max}). ` +
66
+ `Nothing was evicted — consider consolidating related memories or using memory_forget on stale ones.`,
67
+ }
68
+ : {}),
69
+ };
70
+ },
71
+ }),
72
+ defineTool({
73
+ name: 'memory_recall',
74
+ description: 'Search long-term memory by free-text query. Uses vector similarity (TF-IDF by default, ' +
75
+ 'or a configured EmbeddingProvider) when mode is "auto" or "vector". Returns the most ' +
76
+ 'relevant entries with their full bodies.',
77
+ inputSchema: z.object({
78
+ query: z.string().min(1),
79
+ limit: z.number().int().min(1).max(20).optional().default(5),
80
+ type: memoryTypeSchema.optional(),
81
+ mode: z.enum(['auto', 'vector', 'keyword']).optional().default('auto'),
82
+ }),
83
+ isolation: {
84
+ capabilities: {
85
+ fs: { read: ['~/.moxxy/memory/**'] },
86
+ // Vector recall may call out to an EmbeddingProvider (OpenAI,
87
+ // local transformers, …). The inproc isolator can't enforce
88
+ // this; a stronger isolator should constrain to the actual
89
+ // configured embedder's host.
90
+ net: { mode: 'any' },
91
+ timeMs: 15_000,
92
+ },
93
+ },
94
+ handler: async ({ query, limit, type, mode }) => {
95
+ const matches = await store.recall(query, { limit, type, mode });
96
+ return matches.map(({ entry, score }) => ({
97
+ name: entry.frontmatter.name,
98
+ type: entry.frontmatter.type,
99
+ description: entry.frontmatter.description,
100
+ body: entry.body,
101
+ score,
102
+ }));
103
+ },
104
+ }),
105
+ defineTool({
106
+ name: 'memory_list',
107
+ description: 'List all stored memories (name + type + description, no body).',
108
+ inputSchema: z.object({ type: memoryTypeSchema.optional() }),
109
+ isolation: {
110
+ capabilities: {
111
+ fs: { read: ['~/.moxxy/memory/**'] },
112
+ net: { mode: 'none' },
113
+ timeMs: 5_000,
114
+ },
115
+ },
116
+ handler: async ({ type }) => {
117
+ const entries = await store.list(type);
118
+ return entries.map((e) => ({
119
+ name: e.frontmatter.name,
120
+ type: e.frontmatter.type,
121
+ description: e.frontmatter.description,
122
+ tags: e.frontmatter.tags ?? [],
123
+ }));
124
+ },
125
+ }),
126
+ defineTool({
127
+ name: 'memory_forget',
128
+ description: 'Delete a memory by name. Use only when the memory is incorrect or no longer relevant.',
129
+ // Slug-only name: the inproc isolator does NOT enforce the fs.write glob,
130
+ // so this Zod guard is the sole defense against a path-traversal `name`
131
+ // (e.g. '../../vault') reaching fs.unlink. Mirror memory_save's regex.
132
+ inputSchema: z.object({
133
+ name: z.string().min(1).max(120).regex(/^[a-z0-9][a-z0-9-]*$/, 'name must be slug-like'),
134
+ }),
135
+ permission: { action: 'prompt' },
136
+ isolation: {
137
+ capabilities: {
138
+ fs: { read: ['~/.moxxy/memory/**'], write: ['~/.moxxy/memory/**'] },
139
+ net: { mode: 'none' },
140
+ timeMs: 5_000,
141
+ },
142
+ },
143
+ handler: async ({ name }) => {
144
+ const removed = await store.forget(name);
145
+ return removed ? `forgot ${name}` : `not found: ${name}`;
146
+ },
147
+ }),
148
+ defineTool({
149
+ name: 'memory_update',
150
+ description: 'Update an existing memory in place. createdAt is preserved; updatedAt bumps.',
151
+ inputSchema: z.object({
152
+ // Slug-only: see memory_forget — the schema is the only traversal guard.
153
+ name: z.string().min(1).max(120).regex(/^[a-z0-9][a-z0-9-]*$/, 'name must be slug-like'),
154
+ description: z.string().min(1).max(280).optional(),
155
+ body: z.string().min(1).max(4000).optional(),
156
+ tags: z.array(z.string().min(1)).optional(),
157
+ }),
158
+ permission: { action: 'prompt' },
159
+ isolation: {
160
+ capabilities: {
161
+ fs: { read: ['~/.moxxy/memory/**'], write: ['~/.moxxy/memory/**'] },
162
+ net: { mode: 'none' },
163
+ timeMs: 5_000,
164
+ },
165
+ },
166
+ handler: async ({ name, description, body, tags }) => {
167
+ const updated = await store.update(name, { description, body, tags });
168
+ if (!updated)
169
+ throw new Error(`memory '${name}' not found`);
170
+ return { name: updated.frontmatter.name, updatedAt: updated.frontmatter.updatedAt };
171
+ },
172
+ }),
173
+ ],
174
+ });
175
+ return { plugin, store };
176
+ }
177
+ /**
178
+ * Discovery-loadable instance: the WHOLE memory feature (long-term store +
179
+ * memory_save/recall/… tools + the tfidf embedder + memory_consolidate and
180
+ * its nudge hooks) as ONE plugin, so the package unbundles cleanly — the
181
+ * loader takes a single default export per package. Composition over the
182
+ * existing builders:
183
+ * - the store's embedder resolves LAZILY from the host-published
184
+ * 'embedders' registry service (captured in onInit, read on first
185
+ * recall), replacing the bootstrap closure the CLI used to inject;
186
+ * - our onInit registers the 'memory' service FIRST, then runs
187
+ * consolidate's onInit, which resolves it — same ordering the two
188
+ * separate builtin entries relied on.
189
+ * `buildMemoryPlugin` stays for hosts/tests that inject their own store.
190
+ */
191
+ export const memoryPlugin = (() => {
192
+ let embeddersReg = null;
193
+ const { plugin: base } = buildMemoryPlugin({
194
+ // The registry hands back an EmbedderClient-compatible instance; the
195
+ // structural cast keeps this file free of a core import.
196
+ embedder: () => (embeddersReg?.tryGetActive() ?? null),
197
+ });
198
+ const consolidate = memoryConsolidatePluginRef;
199
+ return definePlugin({
200
+ name: '@moxxy/plugin-memory',
201
+ version: '0.0.0',
202
+ ...(base.embedders ? { embedders: base.embedders } : {}),
203
+ tools: [...(base.tools ?? []), ...(consolidate.tools ?? [])],
204
+ hooks: {
205
+ ...consolidate.hooks,
206
+ onInit: async (ctx) => {
207
+ embeddersReg =
208
+ ctx.services.get('embedders') ?? null;
209
+ await base.hooks?.onInit?.(ctx);
210
+ await consolidate.hooks?.onInit?.(ctx);
211
+ },
212
+ },
213
+ });
214
+ })();
215
+ // Discovery entry: `createPluginLoader` requires a default Plugin export.
216
+ export default memoryPlugin;
217
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { parseFrontmatterFile, type ParsedFrontmatter } from '@moxxy/sdk';
2
+ export type ParsedFile = ParsedFrontmatter;
3
+ export declare const parseMdFile: typeof parseFrontmatterFile;
4
+ export { parseFrontmatter, renderFrontmatter } from '@moxxy/sdk';
5
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,oBAAoB,EAAE,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE1E,MAAM,MAAM,UAAU,GAAG,iBAAiB,CAAC;AAE3C,eAAO,MAAM,WAAW,6BAAuB,CAAC;AAEhD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC"}
package/dist/parse.js ADDED
@@ -0,0 +1,9 @@
1
+ // The MD+frontmatter parser now lives canonically in @moxxy/sdk
2
+ // (`parseFrontmatterFile`/`parseFrontmatter`/`renderFrontmatter`), shared with
3
+ // @moxxy/core so the previously-copy-pasted copies can't diverge. This module
4
+ // keeps the historical `parseMdFile`/`ParsedFile` names as thin re-exports.
5
+ // (The plugin already depends on @moxxy/sdk, so this stays leaf-only.)
6
+ import { parseFrontmatterFile } from '@moxxy/sdk';
7
+ export const parseMdFile = parseFrontmatterFile;
8
+ export { parseFrontmatter, renderFrontmatter } from '@moxxy/sdk';
9
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,+EAA+E;AAC/E,8EAA8E;AAC9E,4EAA4E;AAC5E,uEAAuE;AACvE,OAAO,EAAE,oBAAoB,EAA0B,MAAM,YAAY,CAAC;AAI1E,MAAM,CAAC,MAAM,WAAW,GAAG,oBAAoB,CAAC;AAEhD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC"}
package/dist/stm.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ import type { EventLogReader } from '@moxxy/sdk';
2
+ export interface SessionFact {
3
+ readonly turnId: string;
4
+ readonly seq: number;
5
+ readonly source: 'user' | 'assistant';
6
+ readonly text: string;
7
+ }
8
+ /**
9
+ * Short-term memory helpers. STM is the event log itself — these selectors
10
+ * just project a useful view over it.
11
+ */
12
+ export declare function recentExchanges(log: EventLogReader, n?: number): ReadonlyArray<SessionFact>;
13
+ export declare function summarizeSession(log: EventLogReader): {
14
+ turns: number;
15
+ toolCalls: number;
16
+ errors: number;
17
+ skillsCreated: number;
18
+ pluginsLoaded: number;
19
+ };
20
+ //# sourceMappingURL=stm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stm.d.ts","sourceRoot":"","sources":["../src/stm.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AAEH,wBAAgB,eAAe,CAAC,GAAG,EAAE,cAAc,EAAE,CAAC,SAAI,GAAG,aAAa,CAAC,WAAW,CAAC,CAUtF;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB,CAeA"}
package/dist/stm.js ADDED
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Short-term memory helpers. STM is the event log itself — these selectors
3
+ * just project a useful view over it.
4
+ */
5
+ export function recentExchanges(log, n = 5) {
6
+ const out = [];
7
+ for (const e of log.slice()) {
8
+ if (e.type === 'user_prompt') {
9
+ out.push({ turnId: e.turnId, seq: e.seq, source: 'user', text: e.text });
10
+ }
11
+ else if (e.type === 'assistant_message') {
12
+ out.push({ turnId: e.turnId, seq: e.seq, source: 'assistant', text: e.content });
13
+ }
14
+ }
15
+ return out.slice(-n);
16
+ }
17
+ export function summarizeSession(log) {
18
+ const seenTurns = new Set();
19
+ let toolCalls = 0;
20
+ let errors = 0;
21
+ let skillsCreated = 0;
22
+ let pluginsLoaded = 0;
23
+ for (const e of log.slice()) {
24
+ seenTurns.add(e.turnId);
25
+ if (e.type === 'tool_call_requested')
26
+ toolCalls += 1;
27
+ if (e.type === 'error')
28
+ errors += 1;
29
+ if (e.type === 'skill_created')
30
+ skillsCreated += 1;
31
+ if (e.type === 'plugin_registered')
32
+ pluginsLoaded += 1;
33
+ if (e.type === 'plugin_unregistered')
34
+ pluginsLoaded -= 1;
35
+ }
36
+ return { turns: seenTurns.size, toolCalls, errors, skillsCreated, pluginsLoaded };
37
+ }
38
+ //# sourceMappingURL=stm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stm.js","sourceRoot":"","sources":["../src/stm.ts"],"names":[],"mappings":"AASA;;;GAGG;AAEH,MAAM,UAAU,eAAe,CAAC,GAAmB,EAAE,CAAC,GAAG,CAAC;IACxD,MAAM,GAAG,GAAkB,EAAE,CAAC;IAC9B,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC;QAC5B,IAAI,CAAC,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YAC7B,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3E,CAAC;aAAM,IAAI,CAAC,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;YAC1C,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAmB;IAOlD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC;QAC5B,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACxB,IAAI,CAAC,CAAC,IAAI,KAAK,qBAAqB;YAAE,SAAS,IAAI,CAAC,CAAC;QACrD,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO;YAAE,MAAM,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,CAAC,IAAI,KAAK,eAAe;YAAE,aAAa,IAAI,CAAC,CAAC;QACnD,IAAI,CAAC,CAAC,IAAI,KAAK,mBAAmB;YAAE,aAAa,IAAI,CAAC,CAAC;QACvD,IAAI,CAAC,CAAC,IAAI,KAAK,qBAAqB;YAAE,aAAa,IAAI,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC;AACpF,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { type MemoryEntry, type MemoryFrontmatter, type MemoryType } from './types.js';
2
+ export declare function safeRead(filePath: string): Promise<{
3
+ frontmatter: MemoryFrontmatter;
4
+ body: string;
5
+ } | null>;
6
+ export declare function isEnoent(err: unknown): boolean;
7
+ export declare function listEntries(dir: string, filterType?: MemoryType): Promise<ReadonlyArray<MemoryEntry>>;
8
+ export declare function readEntry(filePath: string): Promise<MemoryEntry | null>;
9
+ /** What the MEMORY.md index needs per entry — no body, so the incremental
10
+ * index cache in MemoryStore can feed it without re-reading entry files. */
11
+ export type IndexRow = Pick<MemoryEntry, 'frontmatter' | 'path'>;
12
+ export declare function writeIndex(dir: string, entries: ReadonlyArray<IndexRow>): Promise<void>;
13
+ //# sourceMappingURL=io.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../src/store/io.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,UAAU,EAChB,MAAM,YAAY,CAAC;AAEpB,wBAAsB,QAAQ,CAC5B,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,WAAW,EAAE,iBAAiB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAelE;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAE9C;AAWD,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,EACX,UAAU,CAAC,EAAE,UAAU,GACtB,OAAO,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAmDrC;AAED,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAW7E;AAED;6EAC6E;AAC7E,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,aAAa,GAAG,MAAM,CAAC,CAAC;AAEjE,wBAAsB,UAAU,CAC9B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC,GAC/B,OAAO,CAAC,IAAI,CAAC,CAkBf"}