@shahmilsaari/memory-core 0.2.15 → 0.2.16

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.
package/README.md CHANGED
@@ -8,7 +8,7 @@ You decide the architecture. memory-core remembers it. Every AI tool — Copilot
8
8
  npx @shahmilsaari/memory-core init
9
9
  ```
10
10
 
11
- Fully local or cloud — your choice. **v0.2.13**
11
+ Fully local or cloud — your choice. **v0.2.16**
12
12
 
13
13
  ---
14
14
 
@@ -133,6 +133,7 @@ CREATE TABLE IF NOT EXISTS memories (
133
133
  title TEXT,
134
134
  content TEXT NOT NULL,
135
135
  reason TEXT,
136
+ context JSONB NOT NULL DEFAULT '{}',
136
137
  tags TEXT[] DEFAULT '{}',
137
138
  embedding vector(768),
138
139
  created_at TIMESTAMP DEFAULT now()
@@ -240,6 +241,9 @@ npx @shahmilsaari/memory-core remember "Use DTOs for all API responses" \
240
241
  --type rule \
241
242
  --scope global \
242
243
  --reason "Raw DB entities expose internal schema and sensitive fields" \
244
+ --applies-to "controllers,API responses" \
245
+ --avoid-when "internal domain transformations" \
246
+ --example "return UserResponseDto instead of UserEntity" \
243
247
  --tags "api,dto"
244
248
  ```
245
249
 
@@ -248,8 +252,14 @@ npx @shahmilsaari/memory-core remember "Use DTOs for all API responses" \
248
252
  | `--type` | `decision` `rule` `pattern` `note` | `decision` |
249
253
  | `--scope` | `global` `project` | `project` |
250
254
  | `--reason` | any text | asked interactively |
255
+ | `--applies-to` | comma-separated use cases | none |
256
+ | `--avoid-when` | comma-separated exceptions | none |
257
+ | `--example` | comma-separated examples | none |
258
+ | `--source` | source note, ticket, or review | none |
251
259
  | `--tags` | comma-separated | none |
252
260
 
261
+ Structured context is stored in the database as JSON and rendered into generated agent files as `Why`, `Use when`, `Avoid when`, and `Examples`, which gives AI agents clearer guidance than a flat rule sentence.
262
+
253
263
  ---
254
264
 
255
265
  ### `search` — Find a rule or decision
@@ -306,6 +316,7 @@ Options:
306
316
  ```bash
307
317
  npx @shahmilsaari/memory-core watch --path src/ # watch a specific folder only
308
318
  npx @shahmilsaari/memory-core watch --verbose # show extra details
319
+ npx @shahmilsaari/memory-core watch --debug # show prompt, diff, and raw model output
309
320
  ```
310
321
 
311
322
  Only checks source files — ignores `node_modules`, `dist`, config files, JSON, etc.
@@ -317,9 +328,11 @@ Only checks source files — ignores `node_modules`, `dist`, config files, JSON,
317
328
  ```bash
318
329
  npx @shahmilsaari/memory-core check --staged # check staged files
319
330
  npx @shahmilsaari/memory-core check --staged --verbose # with extra detail
331
+ npx @shahmilsaari/memory-core check --staged --debug # show prompt, diff, and raw model output
332
+ npx @shahmilsaari/memory-core check --ci # CI mode using memories.json
320
333
  ```
321
334
 
322
- Same as the pre-commit hook. Use this in CI/CD pipelines.
335
+ `--staged` is the same path used by the pre-commit hook. `--ci` reads `memories.json` and uses a deterministic CI-friendly diff check, so pull requests can enforce rules without a local database or Ollama setup.
323
336
 
324
337
  ---
325
338
 
@@ -398,19 +411,41 @@ npx @shahmilsaari/memory-core list --limit 50
398
411
 
399
412
  ```bash
400
413
  npx @shahmilsaari/memory-core remove <id>
414
+ npx @shahmilsaari/memory-core remove <id> --no-sync
401
415
  ```
402
416
 
403
417
  Deletes a memory by its ID. Get the ID from `list` or `search`.
404
418
 
405
419
  ---
406
420
 
421
+ ### `forget` — Bulk-delete memories
422
+
423
+ ```bash
424
+ npx @shahmilsaari/memory-core forget --tag nextjs --scope global
425
+ npx @shahmilsaari/memory-core forget --type ignore
426
+ npx @shahmilsaari/memory-core forget --arch nuxt
427
+ ```
428
+
429
+ Deletes memories by filter. At least one filter is required, so an empty `forget` command cannot wipe the database by accident.
430
+
431
+ | Flag | What it does |
432
+ |---|---|
433
+ | `--tag <tag>` | Delete memories with a tag |
434
+ | `--scope <scope>` | Filter by scope: `global` `project` |
435
+ | `--type <type>` | Filter by type |
436
+ | `--arch <architecture>` | Filter by architecture profile |
437
+ | `--no-sync` | Skip automatic agent file regeneration |
438
+
439
+ ---
440
+
407
441
  ### `edit` — Edit a memory
408
442
 
409
443
  ```bash
410
444
  npx @shahmilsaari/memory-core edit <id>
445
+ npx @shahmilsaari/memory-core edit <id> --no-sync
411
446
  ```
412
447
 
413
- Opens the memory interactively so you can update its content, reason, tags, type, or scope.
448
+ Opens the memory interactively so you can update its content, reason, structured context, tags, type, or scope.
414
449
 
415
450
  ---
416
451
 
@@ -431,6 +466,7 @@ Exports all memories from the database to `memories.json` in the project root (o
431
466
  npx @shahmilsaari/memory-core import
432
467
  npx @shahmilsaari/memory-core import --file path/to/my-rules.json
433
468
  npx @shahmilsaari/memory-core import --url https://example.com/team-rules.json
469
+ npx @shahmilsaari/memory-core import --no-sync
434
470
  ```
435
471
 
436
472
  Imports memories into the local database. Skips duplicates by content hash — safe to run more than once.
@@ -439,6 +475,7 @@ Imports memories into the local database. Skips duplicates by content hash — s
439
475
  |---|---|
440
476
  | `--file <path>` | Import from a custom local file path |
441
477
  | `--url <url>` | Import from a remote URL |
478
+ | `--no-sync` | Skip automatic agent file regeneration |
442
479
 
443
480
  ---
444
481
 
@@ -453,8 +490,21 @@ Saves a pattern so the hook and watcher never flag it again. Useful for intentio
453
490
  ```bash
454
491
  npx @shahmilsaari/memory-core ignore --list # show all saved ignore patterns
455
492
  npx @shahmilsaari/memory-core ignore --remove <id> # delete an ignore pattern
493
+ npx @shahmilsaari/memory-core ignore "..." --no-sync # save without regenerating agent files
494
+ ```
495
+
496
+ ---
497
+
498
+ ### `allow` — Allow intentional project patterns
499
+
500
+ ```bash
501
+ npx @shahmilsaari/memory-core allow "generated by sqlc"
502
+ npx @shahmilsaari/memory-core allow --list
503
+ npx @shahmilsaari/memory-core allow --remove "generated by sqlc"
456
504
  ```
457
505
 
506
+ Stores lightweight per-project allowlist strings in `.memory-core.json`. Hook and watch checks treat these patterns as intentional before surfacing violations.
507
+
458
508
  ---
459
509
 
460
510
  ### `ci-setup` — GitHub Actions integration
@@ -463,7 +513,7 @@ npx @shahmilsaari/memory-core ignore --remove <id> # delete an ignore pattern
463
513
  npx @shahmilsaari/memory-core ci-setup
464
514
  ```
465
515
 
466
- Generates `.github/workflows/memory-core.yml`. Adds a PR check that runs your architecture rules on every pull request same checks as the local hook, enforced in CI.
516
+ Generates `.github/workflows/memory-core.yml`. Adds a PR check that runs `npx @shahmilsaari/memory-core check --ci`, using `memories.json` so CI can enforce architecture rules without a project-local database.
467
517
 
468
518
  ---
469
519
 
@@ -28,6 +28,7 @@ async function runMigrations() {
28
28
  await client.query("BEGIN");
29
29
  await client.query(`ALTER TABLE memories ADD COLUMN IF NOT EXISTS reason TEXT`);
30
30
  await client.query(`ALTER TABLE memories ADD COLUMN IF NOT EXISTS content_hash TEXT`);
31
+ await client.query(`ALTER TABLE memories ADD COLUMN IF NOT EXISTS context JSONB NOT NULL DEFAULT '{}'::jsonb`);
31
32
  await client.query(
32
33
  `UPDATE memories
33
34
  SET content_hash = md5(trim(content))
@@ -45,12 +46,24 @@ async function runMigrations() {
45
46
  }
46
47
  async function saveMemory(memory) {
47
48
  await runMigrations();
48
- const { type, scope, architecture, projectName, title, content, reason, tags, embedding } = memory;
49
+ const { type, scope, architecture, projectName, title, content, reason, context, tags, embedding } = memory;
49
50
  const contentHash = hashMemoryContent(content);
50
51
  await getPool().query(
51
- `INSERT INTO memories (type, scope, architecture, project_name, title, content, reason, tags, embedding, content_hash)
52
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)`,
53
- [type, scope, architecture ?? null, projectName ?? null, title ?? null, content, reason ?? null, tags ?? [], `[${embedding.join(",")}]`, contentHash]
52
+ `INSERT INTO memories (type, scope, architecture, project_name, title, content, reason, context, tags, embedding, content_hash)
53
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8::jsonb, $9, $10, $11)`,
54
+ [
55
+ type,
56
+ scope,
57
+ architecture ?? null,
58
+ projectName ?? null,
59
+ title ?? null,
60
+ content,
61
+ reason ?? null,
62
+ JSON.stringify(context ?? {}),
63
+ tags ?? [],
64
+ `[${embedding.join(",")}]`,
65
+ contentHash
66
+ ]
54
67
  );
55
68
  }
56
69
  async function upsertMemory(memory) {
@@ -101,7 +114,7 @@ async function listMemories(filters = {}) {
101
114
  const limit = filters.limit ?? 200;
102
115
  params.push(limit);
103
116
  const result = await getPool().query(
104
- `SELECT id, type, scope, architecture, project_name, title, content, reason, tags, content_hash
117
+ `SELECT id, type, scope, architecture, project_name, title, content, reason, context, tags, content_hash
105
118
  FROM memories
106
119
  ${where.length ? `WHERE ${where.join(" AND ")}` : ""}
107
120
  ORDER BY id ASC
@@ -113,7 +126,7 @@ async function listMemories(filters = {}) {
113
126
  async function getMemory(id) {
114
127
  await runMigrations();
115
128
  const result = await getPool().query(
116
- `SELECT id, type, scope, architecture, project_name, title, content, reason, tags, content_hash
129
+ `SELECT id, type, scope, architecture, project_name, title, content, reason, context, tags, content_hash
117
130
  FROM memories
118
131
  WHERE id = $1`,
119
132
  [id]
@@ -173,11 +186,12 @@ async function updateMemory(id, patch) {
173
186
  title = $4,
174
187
  content = $5,
175
188
  reason = $6,
176
- tags = $7,
177
- content_hash = $8,
178
- embedding = COALESCE($9::vector, embedding)
189
+ context = $7::jsonb,
190
+ tags = $8,
191
+ content_hash = $9,
192
+ embedding = COALESCE($10::vector, embedding)
179
193
  WHERE id = $1
180
- RETURNING id, type, scope, architecture, project_name, title, content, reason, tags, content_hash`,
194
+ RETURNING id, type, scope, architecture, project_name, title, content, reason, context, tags, content_hash`,
181
195
  [
182
196
  id,
183
197
  patch.type ?? current.type,
@@ -185,6 +199,7 @@ async function updateMemory(id, patch) {
185
199
  patch.title ?? current.title ?? null,
186
200
  content,
187
201
  patch.reason ?? current.reason ?? null,
202
+ JSON.stringify(patch.context ?? current.context ?? {}),
188
203
  patch.tags ?? current.tags ?? [],
189
204
  contentHash,
190
205
  embedding
@@ -211,7 +226,7 @@ async function searchMemories(embedding, architectures, limit = 10) {
211
226
  await client.query("BEGIN");
212
227
  await client.query("SET LOCAL ivfflat.probes = 10");
213
228
  const result = await client.query(
214
- `SELECT id, type, scope, architecture, project_name, title, content, reason, tags,
229
+ `SELECT id, type, scope, architecture, project_name, title, content, reason, context, tags,
215
230
  1 - (embedding <=> $1) AS similarity
216
231
  FROM memories
217
232
  ${whereClause}
package/dist/cli.js CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  searchMemories,
15
15
  updateMemory,
16
16
  upsertMemory
17
- } from "./chunk-DUUQHRIB.js";
17
+ } from "./chunk-WUL7HLAA.js";
18
18
  import "./chunk-KSLFLWB4.js";
19
19
 
20
20
  // src/cli.ts
@@ -307,6 +307,23 @@ Handlebars.registerHelper(
307
307
  (arr) => Array.isArray(arr) ? arr.map((i, idx) => `${idx + 1}. ${i}`).join("\n") : ""
308
308
  );
309
309
  Handlebars.registerHelper("json", (val) => JSON.stringify(val, null, 2));
310
+ Handlebars.registerHelper("memoryBlock", (memory) => {
311
+ const meta = [memory.type, memory.architecture].filter(Boolean).join(" \xB7 ");
312
+ const label = memory.title ? `${memory.title}: ${memory.content}` : memory.content;
313
+ const lines = [`- [${meta || "memory"}] ${label}`];
314
+ if (memory.reason) lines.push(` Why: ${memory.reason}`);
315
+ if (memory.context?.appliesTo?.length) lines.push(` Use when: ${memory.context.appliesTo.join("; ")}`);
316
+ if (memory.context?.avoidWhen?.length) lines.push(` Avoid when: ${memory.context.avoidWhen.join("; ")}`);
317
+ if (memory.context?.examples?.length) {
318
+ lines.push(" Examples:");
319
+ for (const example of memory.context.examples) lines.push(` - ${example}`);
320
+ }
321
+ if (memory.tags?.length) lines.push(` Tags: ${memory.tags.join(", ")}`);
322
+ if (memory.project_name || memory.context?.source) {
323
+ lines.push(` Source: ${memory.context?.source ?? memory.project_name}`);
324
+ }
325
+ return new Handlebars.SafeString(lines.join("\n"));
326
+ });
310
327
  function loadProfile(name) {
311
328
  const profilePath = join2(PKG_ROOT, "profiles", `${name}.yml`);
312
329
  if (!existsSync2(profilePath)) throw new Error(`Profile not found: ${name}`);
@@ -919,9 +936,28 @@ function toPortableMemory(memory) {
919
936
  title: memory.title,
920
937
  content: memory.content,
921
938
  reason: memory.reason,
939
+ context: memory.context,
922
940
  tags: memory.tags ?? []
923
941
  };
924
942
  }
943
+ function normalizeStringArray(value) {
944
+ if (!Array.isArray(value)) return void 0;
945
+ const entries = value.filter((entry) => typeof entry === "string" && entry.trim() !== "");
946
+ return entries.length ? entries : void 0;
947
+ }
948
+ function parseContext(value) {
949
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
950
+ const record = value;
951
+ const context = {};
952
+ const appliesTo = normalizeStringArray(record.appliesTo);
953
+ const avoidWhen = normalizeStringArray(record.avoidWhen);
954
+ const examples = normalizeStringArray(record.examples);
955
+ if (appliesTo) context.appliesTo = appliesTo;
956
+ if (avoidWhen) context.avoidWhen = avoidWhen;
957
+ if (examples) context.examples = examples;
958
+ if (typeof record.source === "string" && record.source.trim() !== "") context.source = record.source;
959
+ return Object.keys(context).length ? context : void 0;
960
+ }
925
961
  function writeMemoryFile(memories, cwd = process.cwd()) {
926
962
  const path = join3(cwd, MEMORY_FILE);
927
963
  writeFileSync2(path, JSON.stringify(memories, null, 2) + "\n", "utf-8");
@@ -960,6 +996,7 @@ function parseMemoryFile(raw) {
960
996
  title: typeof record.title === "string" ? record.title : void 0,
961
997
  content: record.content,
962
998
  reason: typeof record.reason === "string" ? record.reason : void 0,
999
+ context: parseContext(record.context),
963
1000
  tags: Array.isArray(record.tags) ? record.tags.filter((tag) => typeof tag === "string") : []
964
1001
  };
965
1002
  });
@@ -1018,7 +1055,7 @@ async function promptToSaveViolations(violations) {
1018
1055
  default: selected.reason ?? selected.issue ?? ""
1019
1056
  });
1020
1057
  const { embed: embed2 } = await import("./embedding-PAYD2JYW.js");
1021
- const { upsertMemory: upsertMemory2 } = await import("./db-VLOR7L6Q.js");
1058
+ const { upsertMemory: upsertMemory2 } = await import("./db-MF3VKVKH.js");
1022
1059
  await upsertMemory2({
1023
1060
  type: "rule",
1024
1061
  scope: "project",
@@ -1035,7 +1072,7 @@ async function promptToSaveViolations(violations) {
1035
1072
  }
1036
1073
  async function loadIgnorePatterns() {
1037
1074
  try {
1038
- const { listMemories: listMemories2, closePool: closePool2 } = await import("./db-VLOR7L6Q.js");
1075
+ const { listMemories: listMemories2, closePool: closePool2 } = await import("./db-MF3VKVKH.js");
1039
1076
  const ignores = await listMemories2({ type: "ignore", limit: 1e3 });
1040
1077
  await closePool2();
1041
1078
  return ignores.map((ignore) => ignore.content);
@@ -1661,7 +1698,7 @@ ${JSON.stringify(violations, null, 2)}`;
1661
1698
  }
1662
1699
  async function loadIgnorePatterns2() {
1663
1700
  try {
1664
- const { listMemories: listMemories2, closePool: closePool2 } = await import("./db-VLOR7L6Q.js");
1701
+ const { listMemories: listMemories2, closePool: closePool2 } = await import("./db-MF3VKVKH.js");
1665
1702
  const ignores = await listMemories2({ type: "ignore", limit: 1e3 });
1666
1703
  await closePool2();
1667
1704
  return ignores.map((ignore) => ignore.content);
@@ -2131,6 +2168,21 @@ function updateProjectConfig(mutator) {
2131
2168
  function parseTags(tags) {
2132
2169
  return tags ? tags.split(",").map((t) => t.trim()).filter(Boolean) : [];
2133
2170
  }
2171
+ function parseList(value) {
2172
+ const entries = value?.split(",").map((entry) => entry.trim()).filter(Boolean) ?? [];
2173
+ return entries.length ? entries : void 0;
2174
+ }
2175
+ function buildMemoryContext(opts) {
2176
+ const context = {};
2177
+ const appliesTo = parseList(opts.appliesTo);
2178
+ const avoidWhen = parseList(opts.avoidWhen);
2179
+ const examples = parseList(opts.example);
2180
+ if (appliesTo) context.appliesTo = appliesTo;
2181
+ if (avoidWhen) context.avoidWhen = avoidWhen;
2182
+ if (examples) context.examples = examples;
2183
+ if (opts.source?.trim()) context.source = opts.source.trim();
2184
+ return Object.keys(context).length ? context : void 0;
2185
+ }
2134
2186
  function truncate(value, length) {
2135
2187
  if (!value) return "";
2136
2188
  return value.length > length ? `${value.slice(0, Math.max(0, length - 1))}\u2026` : value;
@@ -2734,7 +2786,7 @@ program.command("auto-sync [mode]").description("Show or change automatic agent
2734
2786
  console.log(chalk3.green(`Auto-sync ${enabled ? "enabled" : "disabled"}`));
2735
2787
  console.log(chalk3.gray(" Manual sync is always available: memory-core sync"));
2736
2788
  });
2737
- program.command("remember <text>").description("Save a new memory to the central database").option("-t, --type <type>", "Memory type (decision|rule|pattern|note)", "decision").option("-s, --scope <scope>", "Scope (global|project)", "project").option("--tags <tags>", "Comma-separated tags").option("-r, --reason <reason>", "Why this rule exists \u2014 helps agents understand intent and debug violations").option("--no-sync", "Skip automatic agent file sync after saving").action(async (text, opts) => {
2789
+ program.command("remember <text>").description("Save a new memory to the central database").option("-t, --type <type>", "Memory type (decision|rule|pattern|note)", "decision").option("-s, --scope <scope>", "Scope (global|project)", "project").option("--tags <tags>", "Comma-separated tags").option("-r, --reason <reason>", "Why this rule exists \u2014 helps agents understand intent and debug violations").option("--applies-to <items>", "Comma-separated situations where this memory applies").option("--avoid-when <items>", "Comma-separated situations where this memory should not be used").option("--example <items>", "Comma-separated examples that teach agents how to apply this memory").option("--source <source>", "Human-readable source for this memory").option("--no-sync", "Skip automatic agent file sync after saving").action(async (text, opts) => {
2738
2790
  const config = readProjectConfig();
2739
2791
  let reason = opts.reason;
2740
2792
  if (!reason) {
@@ -2753,7 +2805,8 @@ program.command("remember <text>").description("Save a new memory to the central
2753
2805
  projectName: config?.projectName,
2754
2806
  content: text,
2755
2807
  reason: reason || void 0,
2756
- tags: opts.tags ? opts.tags.split(",").map((t) => t.trim()) : [],
2808
+ context: buildMemoryContext(opts),
2809
+ tags: parseTags(opts.tags),
2757
2810
  embedding
2758
2811
  });
2759
2812
  const reasonLine = reason ? chalk3.gray(`
@@ -2787,6 +2840,10 @@ program.command("search <query>").description("Search memories using semantic si
2787
2840
  const sim = m.similarity ? chalk3.gray(` (${(m.similarity * 100).toFixed(0)}% match)`) : "";
2788
2841
  console.log(chalk3.cyan(` ${i + 1}. [${m.type}] ${m.title ?? ""}`));
2789
2842
  console.log(chalk3.white(` ${m.content}`) + sim);
2843
+ if (m.reason) console.log(chalk3.gray(` why: ${m.reason}`));
2844
+ if (m.context?.appliesTo?.length) console.log(chalk3.gray(` use when: ${m.context.appliesTo.join("; ")}`));
2845
+ if (m.context?.avoidWhen?.length) console.log(chalk3.gray(` avoid when: ${m.context.avoidWhen.join("; ")}`));
2846
+ if (m.context?.examples?.length) console.log(chalk3.gray(` examples: ${m.context.examples.join("; ")}`));
2790
2847
  if (m.tags?.length) console.log(chalk3.gray(` tags: ${m.tags.join(", ")}`));
2791
2848
  console.log();
2792
2849
  });
@@ -2832,6 +2889,7 @@ program.command("import").description(`Import memories from ${MEMORY_FILE}`).opt
2832
2889
  title: memory.title,
2833
2890
  content: memory.content,
2834
2891
  reason: memory.reason,
2892
+ context: memory.context,
2835
2893
  tags: memory.tags,
2836
2894
  embedding
2837
2895
  });
@@ -2925,6 +2983,10 @@ program.command("edit <id>").description("Edit a memory interactively").option("
2925
2983
  const title = await input({ message: "Title?", default: existing.title ?? "" });
2926
2984
  const content = await input({ message: "Content?", default: existing.content });
2927
2985
  const reason = await input({ message: "Reason?", default: existing.reason ?? "" });
2986
+ const appliesTo = await input({ message: "Applies to? (comma-separated)", default: existing.context?.appliesTo?.join(",") ?? "" });
2987
+ const avoidWhen = await input({ message: "Avoid when? (comma-separated)", default: existing.context?.avoidWhen?.join(",") ?? "" });
2988
+ const examples = await input({ message: "Examples? (comma-separated)", default: existing.context?.examples?.join(",") ?? "" });
2989
+ const source = await input({ message: "Source?", default: existing.context?.source ?? "" });
2928
2990
  const tags = await input({ message: "Tags?", default: existing.tags.join(",") });
2929
2991
  const embedding = content === existing.content ? void 0 : await embed(content);
2930
2992
  await updateMemory(memoryId, {
@@ -2933,6 +2995,7 @@ program.command("edit <id>").description("Edit a memory interactively").option("
2933
2995
  title: title || void 0,
2934
2996
  content,
2935
2997
  reason: reason || void 0,
2998
+ context: buildMemoryContext({ appliesTo, avoidWhen, example: examples, source }),
2936
2999
  tags: parseTags(tags),
2937
3000
  embedding
2938
3001
  });
@@ -12,7 +12,7 @@ import {
12
12
  searchMemories,
13
13
  updateMemory,
14
14
  upsertMemory
15
- } from "./chunk-DUUQHRIB.js";
15
+ } from "./chunk-WUL7HLAA.js";
16
16
  import "./chunk-KSLFLWB4.js";
17
17
  export {
18
18
  closePool,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shahmilsaari/memory-core",
3
- "version": "0.2.15",
3
+ "version": "0.2.16",
4
4
  "description": "Universal AI memory core — generate AI context files from architecture profiles with RAG support",
5
5
  "type": "module",
6
6
  "bin": {
@@ -19,7 +19,7 @@
19
19
  "smoke:npx": "node scripts/npx-init-smoke.mjs",
20
20
  "dev": "tsx src/cli.ts",
21
21
  "start": "node dist/cli.js",
22
- "test": "node --import tsx --test test/**/*.test.ts"
22
+ "test": "node --import tsx --test test/*.test.ts"
23
23
  },
24
24
  "dependencies": {
25
25
  "@inquirer/prompts": "^5.0.0",
@@ -31,7 +31,7 @@
31
31
  ---
32
32
  ## Relevant Memory from Previous Projects
33
33
  {{#each memories}}
34
- - [{{type}}{{#if this.architecture}} · {{this.architecture}}{{/if}}] {{content}}
34
+ {{memoryBlock this}}
35
35
  {{/each}}
36
36
  {{/if}}
37
37
  {{#if caveman.enabled}}
@@ -27,8 +27,7 @@ These rules apply to ALL AI agents in this project.
27
27
  ---
28
28
  ## Relevant Inherited Decisions
29
29
  {{#each memories}}
30
- {{@index}}. **[{{type}}]** {{content}}
31
- {{#if tags.length}}_tags: {{join tags ", "}}_{{/if}}
30
+ {{memoryBlock this}}
32
31
  {{/each}}
33
32
  {{/if}}
34
33
  {{#if caveman.enabled}}
@@ -46,6 +46,6 @@
46
46
  ---
47
47
  ## Architectural Decisions
48
48
  {{#each memories}}
49
- > **[{{type}}]** {{content}}
49
+ {{memoryBlock this}}
50
50
  {{/each}}
51
51
  {{/if}}
@@ -41,7 +41,7 @@
41
41
  ---
42
42
  ## Relevant Memories
43
43
  {{#each memories}}
44
- - [{{type}}] {{content}}{{#if tags.length}} _({{join tags ", "}})_{{/if}}
44
+ {{memoryBlock this}}
45
45
  {{/each}}
46
46
  {{/if}}
47
47
  {{#if caveman.enabled}}
@@ -16,7 +16,7 @@
16
16
 
17
17
  ## Project Memory
18
18
  {{#each memories}}
19
- - [{{type}}] {{content}}
19
+ {{memoryBlock this}}
20
20
  {{/each}}
21
21
  {{/if}}
22
22
  {{#if caveman.enabled}}
@@ -9,10 +9,7 @@ Stack: {{language}}
9
9
  _Pulled from central memory via semantic search on "{{architecture}} {{language}}"_
10
10
 
11
11
  {{#each memories}}
12
- ### {{@index}}. [{{type}}] {{#if title}}{{title}}{{/if}}
13
- {{content}}
14
- {{#if tags.length}}_Tags: {{join tags ", "}}_{{/if}}
15
- {{#if this.project_name}}_Source: {{this.project_name}}_{{/if}}
12
+ {{memoryBlock this}}
16
13
 
17
14
  {{/each}}
18
15
  {{else}}
@@ -16,7 +16,7 @@ Stack: {{language}}
16
16
 
17
17
  ## Memory
18
18
  {{#each memories}}
19
- - {{content}}
19
+ {{memoryBlock this}}
20
20
  {{/each}}
21
21
  {{/if}}
22
22
  {{#if caveman.enabled}}
@@ -16,7 +16,7 @@ Stack: {{language}}
16
16
 
17
17
  ## Memories
18
18
  {{#each memories}}
19
- - {{content}}
19
+ {{memoryBlock this}}
20
20
  {{/each}}
21
21
  {{/if}}
22
22
  {{#if caveman.enabled}}
@@ -22,7 +22,7 @@ Project: **{{projectName}}** · Type: **{{projectType}}** · Language: **{{langu
22
22
 
23
23
  ## Project Memory
24
24
  {{#each memories}}
25
- - [{{type}}] {{content}}
25
+ {{memoryBlock this}}
26
26
  {{/each}}
27
27
  {{/if}}
28
28
  {{#if caveman.enabled}}
@@ -22,7 +22,7 @@ Type: {{projectType}} | Language: {{language}}
22
22
 
23
23
  ## Memory
24
24
  {{#each memories}}
25
- - {{content}}
25
+ {{memoryBlock this}}
26
26
  {{/each}}
27
27
  {{/if}}
28
28
  {{#if caveman.enabled}}
@@ -18,7 +18,7 @@ Type: {{projectType}} | Language: {{language}}
18
18
 
19
19
  ## Memory
20
20
  {{#each memories}}
21
- - {{content}}
21
+ {{memoryBlock this}}
22
22
  {{/each}}
23
23
  {{/if}}
24
24
  {{#if caveman.enabled}}
@@ -16,7 +16,7 @@ Stack: {{language}}
16
16
 
17
17
  ## Memories
18
18
  {{#each memories}}
19
- - [{{type}}] {{content}}
19
+ {{memoryBlock this}}
20
20
  {{/each}}
21
21
  {{/if}}
22
22
  {{#if caveman.enabled}}
@@ -16,7 +16,7 @@ Stack: {{language}}
16
16
 
17
17
  ## Memory
18
18
  {{#each memories}}
19
- - {{content}}
19
+ {{memoryBlock this}}
20
20
  {{/each}}
21
21
  {{/if}}
22
22
  {{#if caveman.enabled}}
@@ -19,7 +19,7 @@ Stack: {{language}}
19
19
 
20
20
  ## Memories
21
21
  {{#each memories}}
22
- - [{{type}}] {{content}}
22
+ {{memoryBlock this}}
23
23
  {{/each}}
24
24
  {{/if}}
25
25
  {{#if caveman.enabled}}
@@ -16,7 +16,7 @@ Stack: {{language}}
16
16
 
17
17
  ## Inherited Memory
18
18
  {{#each memories}}
19
- - [{{type}}] {{content}}
19
+ {{memoryBlock this}}
20
20
  {{/each}}
21
21
  {{/if}}
22
22
  {{#if caveman.enabled}}