mnemon-mcp 1.0.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 (104) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/CONTRIBUTING.md +59 -0
  3. package/LICENSE +21 -0
  4. package/README.md +434 -0
  5. package/SECURITY.md +29 -0
  6. package/config.example.json +52 -0
  7. package/dist/.tsbuildinfo +1 -0
  8. package/dist/db.d.ts +16 -0
  9. package/dist/db.d.ts.map +1 -0
  10. package/dist/db.js +360 -0
  11. package/dist/db.js.map +1 -0
  12. package/dist/embedder.d.ts +22 -0
  13. package/dist/embedder.d.ts.map +1 -0
  14. package/dist/embedder.js +109 -0
  15. package/dist/embedder.js.map +1 -0
  16. package/dist/import/cli.d.ts +12 -0
  17. package/dist/import/cli.d.ts.map +1 -0
  18. package/dist/import/cli.js +105 -0
  19. package/dist/import/cli.js.map +1 -0
  20. package/dist/import/config-loader.d.ts +29 -0
  21. package/dist/import/config-loader.d.ts.map +1 -0
  22. package/dist/import/config-loader.js +140 -0
  23. package/dist/import/config-loader.js.map +1 -0
  24. package/dist/import/kb-config.d.ts +27 -0
  25. package/dist/import/kb-config.d.ts.map +1 -0
  26. package/dist/import/kb-config.js +10 -0
  27. package/dist/import/kb-config.js.map +1 -0
  28. package/dist/import/kb-import.d.ts +45 -0
  29. package/dist/import/kb-import.d.ts.map +1 -0
  30. package/dist/import/kb-import.js +285 -0
  31. package/dist/import/kb-import.js.map +1 -0
  32. package/dist/import/md-parser.d.ts +35 -0
  33. package/dist/import/md-parser.d.ts.map +1 -0
  34. package/dist/import/md-parser.js +104 -0
  35. package/dist/import/md-parser.js.map +1 -0
  36. package/dist/index-http.d.ts +12 -0
  37. package/dist/index-http.d.ts.map +1 -0
  38. package/dist/index-http.js +202 -0
  39. package/dist/index-http.js.map +1 -0
  40. package/dist/index.d.ts +9 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +56 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/server.d.ts +16 -0
  45. package/dist/server.d.ts.map +1 -0
  46. package/dist/server.js +341 -0
  47. package/dist/server.js.map +1 -0
  48. package/dist/stemmer.d.ts +29 -0
  49. package/dist/stemmer.d.ts.map +1 -0
  50. package/dist/stemmer.js +68 -0
  51. package/dist/stemmer.js.map +1 -0
  52. package/dist/stop-words.d.ts +12 -0
  53. package/dist/stop-words.d.ts.map +1 -0
  54. package/dist/stop-words.js +112 -0
  55. package/dist/stop-words.js.map +1 -0
  56. package/dist/tools/memory-add.d.ts +15 -0
  57. package/dist/tools/memory-add.d.ts.map +1 -0
  58. package/dist/tools/memory-add.js +120 -0
  59. package/dist/tools/memory-add.js.map +1 -0
  60. package/dist/tools/memory-delete.d.ts +10 -0
  61. package/dist/tools/memory-delete.d.ts.map +1 -0
  62. package/dist/tools/memory-delete.js +39 -0
  63. package/dist/tools/memory-delete.js.map +1 -0
  64. package/dist/tools/memory-export.d.ts +10 -0
  65. package/dist/tools/memory-export.d.ts.map +1 -0
  66. package/dist/tools/memory-export.js +102 -0
  67. package/dist/tools/memory-export.js.map +1 -0
  68. package/dist/tools/memory-health.d.ts +11 -0
  69. package/dist/tools/memory-health.d.ts.map +1 -0
  70. package/dist/tools/memory-health.js +79 -0
  71. package/dist/tools/memory-health.js.map +1 -0
  72. package/dist/tools/memory-inspect.d.ts +10 -0
  73. package/dist/tools/memory-inspect.d.ts.map +1 -0
  74. package/dist/tools/memory-inspect.js +139 -0
  75. package/dist/tools/memory-inspect.js.map +1 -0
  76. package/dist/tools/memory-search.d.ts +16 -0
  77. package/dist/tools/memory-search.d.ts.map +1 -0
  78. package/dist/tools/memory-search.js +459 -0
  79. package/dist/tools/memory-search.js.map +1 -0
  80. package/dist/tools/memory-update.d.ts +11 -0
  81. package/dist/tools/memory-update.d.ts.map +1 -0
  82. package/dist/tools/memory-update.js +142 -0
  83. package/dist/tools/memory-update.js.map +1 -0
  84. package/dist/tools/style-extract.d.ts +40 -0
  85. package/dist/tools/style-extract.d.ts.map +1 -0
  86. package/dist/tools/style-extract.js +43 -0
  87. package/dist/tools/style-extract.js.map +1 -0
  88. package/dist/tools/utils.d.ts +28 -0
  89. package/dist/tools/utils.d.ts.map +1 -0
  90. package/dist/tools/utils.js +33 -0
  91. package/dist/tools/utils.js.map +1 -0
  92. package/dist/types.d.ts +216 -0
  93. package/dist/types.d.ts.map +1 -0
  94. package/dist/types.js +6 -0
  95. package/dist/types.js.map +1 -0
  96. package/dist/validation.d.ts +122 -0
  97. package/dist/validation.d.ts.map +1 -0
  98. package/dist/validation.js +96 -0
  99. package/dist/validation.js.map +1 -0
  100. package/dist/vector.d.ts +30 -0
  101. package/dist/vector.d.ts.map +1 -0
  102. package/dist/vector.js +90 -0
  103. package/dist/vector.js.map +1 -0
  104. package/package.json +75 -0
@@ -0,0 +1,285 @@
1
+ /**
2
+ * KB import pipeline — reads markdown files from mnemon-kb, splits into memories,
3
+ * and inserts into mnemon-mcp SQLite database.
4
+ *
5
+ * Idempotent: uses import_log + file_hash for dedup.
6
+ * Superseding: re-import of changed files supersedes old memories via source_file.
7
+ */
8
+ import { readFileSync, existsSync } from "node:fs";
9
+ import { basename, join, relative, resolve } from "node:path";
10
+ import { homedir } from "node:os";
11
+ import { globSync } from "node:fs";
12
+ import { openDatabase } from "../db.js";
13
+ import { memoryAdd } from "../tools/memory-add.js";
14
+ import { loadConfig } from "./config-loader.js";
15
+ import { parseFile, splitByHeading, extractDateFromFilename, } from "./md-parser.js";
16
+ /** Expand ~ in paths */
17
+ function expandHome(p) {
18
+ return p.startsWith("~") ? p.replace("~", homedir()) : p;
19
+ }
20
+ /** Resolve glob patterns against a base path */
21
+ function resolveGlob(pattern, basePath) {
22
+ const fullPattern = join(basePath, pattern);
23
+ try {
24
+ return globSync(fullPattern);
25
+ }
26
+ catch {
27
+ return [];
28
+ }
29
+ }
30
+ /** Check if file hash already exists in import_log (unchanged file) */
31
+ function isAlreadyImported(db, sourcePath, hash) {
32
+ const row = db
33
+ .prepare(`SELECT id FROM import_log WHERE source_path = ? AND file_hash = ?`)
34
+ .get(sourcePath, hash);
35
+ return row !== undefined;
36
+ }
37
+ /** Log import to import_log table */
38
+ function logImport(db, sourcePath, sourceType, hash, created, updated, status, errors = []) {
39
+ db.prepare(`INSERT OR REPLACE INTO import_log (source_path, source_type, file_hash, memories_created, memories_updated, status, errors)
40
+ VALUES (?, ?, ?, ?, ?, ?, ?)`).run(sourcePath, sourceType, hash, created, updated, status, JSON.stringify(errors));
41
+ }
42
+ /** Build MemoryAddInput from a section + mapping config */
43
+ function buildMemoryInput(section, fullContent, mapping, sourcePath, filename, description) {
44
+ // Prepend file stem (e.g. "human-design") + description for FTS discoverability
45
+ // File stem helps find files by name (e.g. query "Human Design" matches "human-design")
46
+ const fileStem = basename(filename, ".md");
47
+ const descPrefix = section && description ? `[${description}]\n\n` : "";
48
+ const fileTag = `[file: ${fileStem}] `;
49
+ const content = section
50
+ ? `${fileTag}${descPrefix}## ${section.title}\n\n${section.content}`
51
+ : `${fileTag}${fullContent}`;
52
+ const title = section?.title ?? basename(filename, ".md");
53
+ let entityName = mapping.entity_name;
54
+ if (entityName === "from-heading" && section) {
55
+ // Extract first meaningful part of heading (before —, (, etc.)
56
+ entityName = section.title.split(/\s*[—\-(|]/)[0].trim();
57
+ }
58
+ else if (entityName === "from-heading") {
59
+ entityName = undefined;
60
+ }
61
+ const eventAt = mapping.layer === "episodic" ? extractDateFromFilename(filename) : undefined;
62
+ // source_file includes section title for per-section superseding
63
+ const sourceFile = section ? `${sourcePath}#${section.title}` : sourcePath;
64
+ return {
65
+ content,
66
+ layer: mapping.layer,
67
+ title,
68
+ entity_type: mapping.entity_type,
69
+ ...(entityName ? { entity_name: entityName } : {}),
70
+ importance: mapping.importance,
71
+ confidence: mapping.confidence,
72
+ source: "import:kb",
73
+ source_file: sourceFile,
74
+ scope: mapping.scope ?? "global",
75
+ ...(eventAt ? { event_at: eventAt } : {}),
76
+ meta: { imported_from: sourcePath },
77
+ };
78
+ }
79
+ /** Process a single file with its mapping */
80
+ export function processFile(db, filePath, mapping, kbPath, dryRun, verbose, force = false) {
81
+ const sourcePath = filePath.startsWith(kbPath)
82
+ ? relative(kbPath, filePath)
83
+ : filePath;
84
+ let raw;
85
+ try {
86
+ raw = readFileSync(filePath, "utf8");
87
+ }
88
+ catch (err) {
89
+ return { sections: 0, created: 0, superseded: 0, status: "error", error: `Read error: ${err}` };
90
+ }
91
+ const parsed = parseFile(raw);
92
+ // Use frontmatter layer override if present
93
+ const effectiveMapping = { ...mapping };
94
+ if (parsed.frontmatter.layer && ["episodic", "semantic", "procedural", "resource"].includes(parsed.frontmatter.layer)) {
95
+ effectiveMapping.layer = parsed.frontmatter.layer;
96
+ }
97
+ // Check if already imported with same hash
98
+ if (!force && isAlreadyImported(db, sourcePath, parsed.hash)) {
99
+ if (verbose)
100
+ console.log(` SKIP (unchanged): ${sourcePath}`);
101
+ return { sections: 0, created: 0, superseded: 0, status: "skipped" };
102
+ }
103
+ const filename = basename(filePath);
104
+ let created = 0;
105
+ let superseded = 0;
106
+ // Prepend frontmatter description to body so it gets indexed in FTS5 (T-093)
107
+ const descriptionPrefix = parsed.frontmatter.description
108
+ ? `${parsed.frontmatter.description}\n\n`
109
+ : "";
110
+ const bodyWithDescription = descriptionPrefix + parsed.body;
111
+ try {
112
+ if (effectiveMapping.split === "whole") {
113
+ // Import as single memory
114
+ const input = buildMemoryInput(null, bodyWithDescription, effectiveMapping, sourcePath, filename);
115
+ if (dryRun) {
116
+ if (verbose)
117
+ console.log(` DRY: ${sourcePath} → 1 record (whole), layer=${input.layer}`);
118
+ return { sections: 1, created: 1, superseded: 0, status: "imported" };
119
+ }
120
+ const result = memoryAdd(db, input);
121
+ created = 1;
122
+ superseded = result.superseded_ids?.length ?? 0;
123
+ }
124
+ else {
125
+ // Split by heading
126
+ const level = effectiveMapping.split === "h2" ? 2 : 3;
127
+ const sections = splitByHeading(parsed.body, level);
128
+ const fmDescription = typeof parsed.frontmatter.description === "string"
129
+ ? parsed.frontmatter.description : undefined;
130
+ if (sections.length === 0) {
131
+ // File has no headings at the specified level — import as whole
132
+ const input = buildMemoryInput(null, bodyWithDescription, effectiveMapping, sourcePath, filename);
133
+ if (dryRun) {
134
+ if (verbose)
135
+ console.log(` DRY: ${sourcePath} → 1 record (no headings), layer=${input.layer}`);
136
+ return { sections: 1, created: 1, superseded: 0, status: "imported" };
137
+ }
138
+ const result = memoryAdd(db, input);
139
+ created = 1;
140
+ superseded = result.superseded_ids?.length ?? 0;
141
+ }
142
+ else {
143
+ for (const section of sections) {
144
+ if (!section.content.trim())
145
+ continue;
146
+ const input = buildMemoryInput(section, "", effectiveMapping, sourcePath, filename, fmDescription);
147
+ if (dryRun) {
148
+ if (verbose)
149
+ console.log(` DRY: ${sourcePath}#${section.title} → layer=${input.layer}`);
150
+ created++;
151
+ continue;
152
+ }
153
+ const result = memoryAdd(db, input);
154
+ created++;
155
+ superseded += result.superseded_ids?.length ?? 0;
156
+ }
157
+ }
158
+ }
159
+ }
160
+ catch (err) {
161
+ const errMsg = err instanceof Error ? err.message : String(err);
162
+ if (verbose)
163
+ console.error(` ERROR: ${sourcePath}: ${errMsg}`);
164
+ return { sections: 0, created: 0, superseded: 0, status: "error", error: errMsg };
165
+ }
166
+ if (!dryRun) {
167
+ logImport(db, sourcePath, "kb-markdown", parsed.hash, created, superseded, "success");
168
+ if (verbose)
169
+ console.log(` OK: ${sourcePath} → ${created} records, ${superseded} superseded`);
170
+ }
171
+ return {
172
+ sections: created,
173
+ created,
174
+ superseded,
175
+ status: superseded > 0 ? "updated" : "imported",
176
+ };
177
+ }
178
+ /** Main import function */
179
+ export function runImport(options) {
180
+ const kbPath = resolve(expandHome(options.kbPath));
181
+ const dryRun = options.dryRun ?? false;
182
+ const verbose = options.verbose ?? false;
183
+ const force = options.force ?? false;
184
+ if (!existsSync(kbPath)) {
185
+ throw new Error(`KB path does not exist: ${kbPath}`);
186
+ }
187
+ const config = loadConfig(options.configPath);
188
+ const db = dryRun ? openDatabase(":memory:") : openDatabase();
189
+ const result = {
190
+ filesProcessed: 0,
191
+ filesSkipped: 0,
192
+ memoriesCreated: 0,
193
+ memoriesSuperseded: 0,
194
+ errors: [],
195
+ details: [],
196
+ };
197
+ // Single file mode
198
+ if (options.singleFile) {
199
+ const filePath = resolve(expandHome(options.singleFile));
200
+ if (!existsSync(filePath)) {
201
+ throw new Error(`File does not exist: ${filePath}`);
202
+ }
203
+ // Find matching mapping or use provided layer
204
+ let mapping;
205
+ const relPath = filePath.startsWith(kbPath) ? relative(kbPath, filePath) : filePath;
206
+ for (const dirMapping of config.mappings) {
207
+ const matches = resolveGlob(dirMapping.glob, kbPath);
208
+ if (matches.includes(filePath)) {
209
+ mapping = dirMapping;
210
+ break;
211
+ }
212
+ }
213
+ if (!mapping && options.singleLayer) {
214
+ mapping = {
215
+ layer: options.singleLayer,
216
+ entity_type: "concept",
217
+ importance: 0.5,
218
+ confidence: 0.8,
219
+ split: "h2",
220
+ };
221
+ }
222
+ if (!mapping) {
223
+ throw new Error(`No mapping found for ${relPath}. Use --layer to specify.`);
224
+ }
225
+ const fileResult = processFile(db, filePath, mapping, kbPath, dryRun, verbose, force);
226
+ result.filesProcessed = 1;
227
+ result.memoriesCreated = fileResult.created;
228
+ result.memoriesSuperseded = fileResult.superseded;
229
+ result.details.push({ file: relPath, sections: fileResult.sections, status: fileResult.status });
230
+ if (fileResult.error) {
231
+ result.errors.push({ file: relPath, error: fileResult.error });
232
+ }
233
+ db.close();
234
+ return result;
235
+ }
236
+ // Full KB import
237
+ for (const dirMapping of config.mappings) {
238
+ const files = resolveGlob(dirMapping.glob, kbPath);
239
+ for (const filePath of files) {
240
+ const filename = basename(filePath);
241
+ // Apply file filter if defined
242
+ if (dirMapping.fileFilter && !dirMapping.fileFilter(filename))
243
+ continue;
244
+ result.filesProcessed++;
245
+ const relPath = relative(kbPath, filePath);
246
+ const fileResult = processFile(db, filePath, dirMapping, kbPath, dryRun, verbose, force);
247
+ if (fileResult.status === "skipped") {
248
+ result.filesSkipped++;
249
+ }
250
+ else {
251
+ result.memoriesCreated += fileResult.created;
252
+ result.memoriesSuperseded += fileResult.superseded;
253
+ }
254
+ result.details.push({ file: relPath, sections: fileResult.sections, status: fileResult.status });
255
+ if (fileResult.error) {
256
+ result.errors.push({ file: relPath, error: fileResult.error });
257
+ }
258
+ }
259
+ }
260
+ // External files
261
+ for (const ext of config.externalFiles) {
262
+ const filePath = resolve(expandHome(ext.path));
263
+ if (!existsSync(filePath)) {
264
+ if (verbose)
265
+ console.log(` SKIP (not found): ${ext.path}`);
266
+ continue;
267
+ }
268
+ result.filesProcessed++;
269
+ const fileResult = processFile(db, filePath, ext.mapping, kbPath, dryRun, verbose, force);
270
+ if (fileResult.status === "skipped") {
271
+ result.filesSkipped++;
272
+ }
273
+ else {
274
+ result.memoriesCreated += fileResult.created;
275
+ result.memoriesSuperseded += fileResult.superseded;
276
+ }
277
+ result.details.push({ file: ext.path, sections: fileResult.sections, status: fileResult.status });
278
+ if (fileResult.error) {
279
+ result.errors.push({ file: ext.path, error: fileResult.error });
280
+ }
281
+ }
282
+ db.close();
283
+ return result;
284
+ }
285
+ //# sourceMappingURL=kb-import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kb-import.js","sourceRoot":"","sources":["../../src/import/kb-import.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Markdown parser — frontmatter extraction, heading-based splitting, hashing.
3
+ */
4
+ export interface Frontmatter {
5
+ [key: string]: unknown;
6
+ layer?: string;
7
+ last_updated?: string;
8
+ description?: string;
9
+ tags?: string[];
10
+ importance?: number;
11
+ }
12
+ export interface Section {
13
+ title: string;
14
+ level: number;
15
+ content: string;
16
+ }
17
+ export interface ParsedFile {
18
+ frontmatter: Frontmatter;
19
+ body: string;
20
+ hash: string;
21
+ }
22
+ /** Parse YAML frontmatter delimited by --- */
23
+ export declare function parseFrontmatter(raw: string): {
24
+ frontmatter: Frontmatter;
25
+ body: string;
26
+ };
27
+ /** Split markdown by heading level (H2 or H3) into sections */
28
+ export declare function splitByHeading(body: string, level: 2 | 3): Section[];
29
+ /** Extract date from filename: 2026-03-05.md, 2025-q1.md, 2024.md → ISO string */
30
+ export declare function extractDateFromFilename(filename: string): string | null;
31
+ /** Compute SHA-256 hash of content */
32
+ export declare function computeHash(content: string): string;
33
+ /** Full parse: frontmatter + body + hash */
34
+ export declare function parseFile(raw: string): ParsedFile;
35
+ //# sourceMappingURL=md-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"md-parser.d.ts","sourceRoot":"","sources":["../../src/import/md-parser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,WAAW,WAAW;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,WAAW,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,8CAA8C;AAC9C,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,WAAW,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CA2CxF;AAED,+DAA+D;AAC/D,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,OAAO,EAAE,CAiCpE;AAED,kFAAkF;AAClF,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiBvE;AAED,sCAAsC;AACtC,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,4CAA4C;AAC5C,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAIjD"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Markdown parser — frontmatter extraction, heading-based splitting, hashing.
3
+ */
4
+ import { createHash } from "node:crypto";
5
+ /** Parse YAML frontmatter delimited by --- */
6
+ export function parseFrontmatter(raw) {
7
+ const match = raw.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
8
+ if (!match) {
9
+ return { frontmatter: {}, body: raw };
10
+ }
11
+ const yamlBlock = match[1];
12
+ const body = match[2];
13
+ const frontmatter = {};
14
+ for (const line of yamlBlock.split("\n")) {
15
+ const kv = line.match(/^(\w[\w_-]*)\s*:\s*(.+)$/);
16
+ if (!kv)
17
+ continue;
18
+ const key = kv[1];
19
+ let value = kv[2].trim();
20
+ let wasQuoted = false;
21
+ // Strip surrounding quotes (YAML-style) — quoted values stay as strings
22
+ if (typeof value === "string" && value.length >= 2) {
23
+ if ((value.startsWith('"') && value.endsWith('"')) ||
24
+ (value.startsWith("'") && value.endsWith("'"))) {
25
+ value = value.slice(1, -1);
26
+ wasQuoted = true;
27
+ }
28
+ }
29
+ // Parse arrays: [a, b, c]
30
+ if (typeof value === "string" && value.startsWith("[") && value.endsWith("]")) {
31
+ value = value
32
+ .slice(1, -1)
33
+ .split(",")
34
+ .map((s) => s.trim());
35
+ }
36
+ // Parse numbers — only for unquoted values (quoted "0012" stays "0012")
37
+ else if (!wasQuoted && typeof value === "string" && /^\d+(\.\d+)?$/.test(value)) {
38
+ value = parseFloat(value);
39
+ }
40
+ frontmatter[key] = value;
41
+ }
42
+ return { frontmatter, body };
43
+ }
44
+ /** Split markdown by heading level (H2 or H3) into sections */
45
+ export function splitByHeading(body, level) {
46
+ const prefix = "#".repeat(level) + " ";
47
+ const lines = body.split("\n");
48
+ const sections = [];
49
+ let currentTitle = "";
50
+ let currentLines = [];
51
+ for (const line of lines) {
52
+ if (line.startsWith(prefix)) {
53
+ // Save previous section (skip prelude content before first heading)
54
+ if (currentTitle) {
55
+ const content = currentLines.join("\n").trim();
56
+ if (content) {
57
+ sections.push({ title: currentTitle, level, content });
58
+ }
59
+ }
60
+ currentTitle = line.slice(prefix.length).trim();
61
+ currentLines = [];
62
+ }
63
+ else {
64
+ currentLines.push(line);
65
+ }
66
+ }
67
+ // Last section (skip if no heading was encountered)
68
+ if (currentTitle) {
69
+ const content = currentLines.join("\n").trim();
70
+ if (content) {
71
+ sections.push({ title: currentTitle, level, content });
72
+ }
73
+ }
74
+ return sections;
75
+ }
76
+ /** Extract date from filename: 2026-03-05.md, 2025-q1.md, 2024.md → ISO string */
77
+ export function extractDateFromFilename(filename) {
78
+ // Daily: 2026-03-05.md
79
+ const daily = filename.match(/(\d{4}-\d{2}-\d{2})/);
80
+ if (daily)
81
+ return `${daily[1]}T00:00:00Z`;
82
+ // Quarterly: 2025-q1.md → first day of quarter
83
+ const quarterly = filename.match(/(\d{4})-q([1-4])/i);
84
+ if (quarterly) {
85
+ const month = String([1, 4, 7, 10][(+quarterly[2] - 1)]).padStart(2, "0");
86
+ return `${quarterly[1]}-${month}-01T00:00:00Z`;
87
+ }
88
+ // Yearly: 2024.md
89
+ const yearly = filename.match(/^(\d{4})\.md$/);
90
+ if (yearly)
91
+ return `${yearly[1]}-01-01T00:00:00Z`;
92
+ return null;
93
+ }
94
+ /** Compute SHA-256 hash of content */
95
+ export function computeHash(content) {
96
+ return createHash("sha256").update(content, "utf8").digest("hex");
97
+ }
98
+ /** Full parse: frontmatter + body + hash */
99
+ export function parseFile(raw) {
100
+ const { frontmatter, body } = parseFrontmatter(raw);
101
+ const hash = computeHash(raw);
102
+ return { frontmatter, body, hash };
103
+ }
104
+ //# sourceMappingURL=md-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"md-parser.js","sourceRoot":"","sources":["../../src/import/md-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * mnemon-mcp: HTTP transport entry point.
3
+ *
4
+ * Exposes the same tools as index.ts via StreamableHTTP transport.
5
+ * Use for remote / multi-server deployments instead of stdio.
6
+ *
7
+ * Environment variables:
8
+ * MNEMON_PORT - Listening port (default: 3000)
9
+ * MNEMON_AUTH_TOKEN - Bearer token for all requests (optional but recommended)
10
+ */
11
+ export {};
12
+ //# sourceMappingURL=index-http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-http.d.ts","sourceRoot":"","sources":["../src/index-http.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}