@shahmilsaari/memory-core 0.2.3 → 0.2.5

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 (3) hide show
  1. package/README.md +31 -25
  2. package/dist/cli.js +45 -8
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -18,11 +18,10 @@ Without memory-core, every AI agent starts fresh. It doesn't know you're using C
18
18
 
19
19
  With memory-core:
20
20
 
21
- 1. You run `init` once and answer a few questions about your project
22
- 2. memory-core generates config files for every AI agent you use
23
- 3. Those agents read the files and follow your rules automatically
24
- 4. When you commit code, a hook catches violations before they land in the repo
25
- 5. Watch mode catches violations as you type, not just at commit time
21
+ 1. You run `init` once it verifies your PostgreSQL and Ollama connections, picks your model, and generates config files for every AI agent
22
+ 2. Those agents read the files and follow your rules automatically
23
+ 3. Watch mode catches violations as you type, not just at commit time
24
+ 4. When you commit, Claude Code automatically checks your code before the commit goes through
26
25
 
27
26
  ---
28
27
 
@@ -106,10 +105,10 @@ ollama serve &
106
105
 
107
106
  **Windows** — [download from ollama.com](https://ollama.com/download)
108
107
 
109
- Then pull the two models:
108
+ Pull the embedding model. The code-checking model is chosen during `init`:
110
109
  ```bash
111
- ollama pull nomic-embed-text # used for search
112
- ollama pull llama3.2 # used to check your code
110
+ ollama pull nomic-embed-text # required for search
111
+ ollama pull llama3.2 # or whichever model you plan to use
113
112
  ```
114
113
 
115
114
  ---
@@ -153,14 +152,11 @@ CREATE INDEX IF NOT EXISTS memories_scope_idx ON memories (scope);
153
152
  # 1. Go to your project
154
153
  cd my-api
155
154
 
156
- # 2. Initialize — answers a few questions, generates all config files
155
+ # 2. Initialize — verifies connections, picks your model, generates all config files
157
156
  npx @shahmilsaari/memory-core init
158
157
 
159
158
  # 3. Load 281 predefined best-practice rules
160
159
  npx @shahmilsaari/memory-core seed
161
-
162
- # 4. Install the pre-commit hook (optional but recommended)
163
- npx @shahmilsaari/memory-core hook install
164
160
  ```
165
161
 
166
162
  That's it. Every AI agent in your project now has your rules.
@@ -175,15 +171,18 @@ That's it. Every AI agent in your project now has your rules.
175
171
  npx @shahmilsaari/memory-core init
176
172
  ```
177
173
 
178
- Asks you:
179
- - Project name
180
- - Project type (Backend / Frontend / Fullstack)
181
- - Architecture (Clean Architecture, MVC, React, Vue, etc.)
182
- - Language
174
+ Walks you through:
175
+ - PostgreSQL connection URL — **tested live, retries until connected**
176
+ - Ollama URL **tested live, retries until reachable**
177
+ - Code-checking model **verified to be installed in your Ollama**
178
+ - Project name, type, architecture, language
179
+ - Whether to enable the pre-commit hook (asked during setup — no separate step needed)
183
180
  - Whether to enable caveman mode (optional token saver)
184
181
 
185
182
  Generates config files for every supported AI agent and saves your choices to `.memory-core.json`.
186
183
 
184
+ At the end, the banner shows live ✓/✗ status for PostgreSQL and Ollama so you know everything is working.
185
+
187
186
  ---
188
187
 
189
188
  ### `remember` — Save a decision
@@ -253,7 +252,9 @@ npx @shahmilsaari/memory-core seed --force # re-seed existin
253
252
  npx @shahmilsaari/memory-core hook install
254
253
  ```
255
254
 
256
- Installs a git pre-commit hook. Every time you run `git commit`, your staged files are checked against your architecture rules before the commit goes through.
255
+ Installs a git pre-commit hook in the current project. Every time you run `git commit`, your code is checked against your architecture rules before the commit goes through.
256
+
257
+ > **Note:** If you use Claude Code, the hook is offered automatically during `init` — no separate step needed.
257
258
 
258
259
  When a violation is found, the commit is blocked and you see exactly what's wrong and how to fix it:
259
260
 
@@ -396,7 +397,7 @@ Pick the one that matches how your project is structured.
396
397
  | React | Functional components, hooks, React Query, Zustand |
397
398
  | Vue 3 | Composition API, Pinia, composables |
398
399
  | Angular | Standalone components, signals, OnPush strategy |
399
- | Svelte | Svelte 5 runes, SvelteKit load functions |
400
+ | Svelte | Svelte 5 runes, SvelteKit load functions, snippets |
400
401
  | Nuxt 3 | Fullstack Vue with SSR |
401
402
  | React Native | Mobile apps |
402
403
 
@@ -421,9 +422,8 @@ Cuts AI response length by 65–75% by removing filler words. Opt in during `ini
421
422
  ```bash
422
423
  # Starting a new project
423
424
  cd my-api
424
- npx @shahmilsaari/memory-core init
425
- npx @shahmilsaari/memory-core seed
426
- npx @shahmilsaari/memory-core hook install
425
+ npx @shahmilsaari/memory-core init # verifies connections, picks model, installs hook
426
+ npx @shahmilsaari/memory-core seed # load 281 best-practice rules
427
427
 
428
428
  # Made an architectural decision? Save it.
429
429
  npx @shahmilsaari/memory-core remember "All auth goes through middleware, never in controllers" \
@@ -435,7 +435,7 @@ npx @shahmilsaari/memory-core sync
435
435
  # Not sure how something was decided? Search.
436
436
  npx @shahmilsaari/memory-core search "caching strategy"
437
437
 
438
- # Commit code → hook checks it automatically
438
+ # Commit code → Claude Code checks it automatically before committing
439
439
  git commit -m "add user endpoint"
440
440
  ```
441
441
 
@@ -449,8 +449,8 @@ memory-core creates `.memory-core.env` automatically during `init`. You can also
449
449
  |---|---|---|---|
450
450
  | `DATABASE_URL` | Yes | — | PostgreSQL connection string |
451
451
  | `OLLAMA_URL` | No | `http://localhost:11434` | Where Ollama is running |
452
- | `OLLAMA_MODEL` | No | `nomic-embed-text` | Model used for search |
453
- | `OLLAMA_CHAT_MODEL` | No | `llama3.2` | Model used for code checking |
452
+ | `OLLAMA_MODEL` | No | `nomic-embed-text` | Model used for search (embeddings) |
453
+ | `OLLAMA_CHAT_MODEL` | No | `llama3.2` | Model used for code checking — chosen during `init` |
454
454
 
455
455
  ---
456
456
 
@@ -483,6 +483,10 @@ It won't — the hook only checks source code files: `.ts .tsx .js .jsx .py .php
483
483
  | | Feature |
484
484
  |---|---|
485
485
  | ✓ | Watch mode — real-time violation alerts on save |
486
+ | ✓ | Model picker — choose your Ollama model during init |
487
+ | ✓ | Connection validation — PostgreSQL and Ollama verified during setup |
488
+ | ✓ | Svelte 5 / SvelteKit profile and 37 rules |
489
+ | ✓ | NestJS profile and 39 rules |
486
490
  | | CI/CD — fail PRs that violate your rules |
487
491
  | | Violation memory — auto-save what went wrong as a new rule |
488
492
  | | Rule analytics — see which rules get broken most |
@@ -494,3 +498,5 @@ It won't — the hook only checks source code files: `.ts .tsx .js .jsx .py .php
494
498
  ## License
495
499
 
496
500
  MIT
501
+
502
+ *Built by [Shahmil Saari](https://github.com/shahmilsaari)*
package/dist/cli.js CHANGED
@@ -699,6 +699,20 @@ import { execSync } from "child_process";
699
699
  import { writeFileSync as writeFileSync2, existsSync as existsSync4, unlinkSync, readFileSync as readFileSync3, chmodSync } from "fs";
700
700
  import { join as join4 } from "path";
701
701
  import chalk from "chalk";
702
+ async function resolveModel(ollamaUrl, chatModel) {
703
+ try {
704
+ const res = await fetch(`${ollamaUrl}/api/tags`, { signal: AbortSignal.timeout(3e3) });
705
+ if (!res.ok) return chatModel;
706
+ const data = await res.json();
707
+ const models = data.models ?? [];
708
+ const exact = models.find((m) => m.name === chatModel);
709
+ if (exact) return exact.name;
710
+ const prefixed = models.find((m) => m.name.startsWith(`${chatModel}:`));
711
+ if (prefixed) return prefixed.name;
712
+ } catch {
713
+ }
714
+ return chatModel;
715
+ }
702
716
  var reasonMap = new Map(
703
717
  seeds.filter((s) => s.reason).map((s) => [s.content, s.reason])
704
718
  );
@@ -794,7 +808,7 @@ async function checkStaged(options = {}) {
794
808
  }
795
809
  if (rules.length === 0) return;
796
810
  const ollamaUrl = process.env.OLLAMA_URL ?? "http://localhost:11434";
797
- const chatModel = process.env.OLLAMA_CHAT_MODEL ?? "llama3.2";
811
+ const chatModel = await resolveModel(ollamaUrl, process.env.OLLAMA_CHAT_MODEL ?? "llama3.2");
798
812
  const MAX_DIFF = 8e3;
799
813
  const truncated = diff.length > MAX_DIFF;
800
814
  const diffToSend = truncated ? diff.slice(0, MAX_DIFF) + "\n\n[diff truncated]" : diff;
@@ -918,6 +932,20 @@ import { execSync as execSync2 } from "child_process";
918
932
  import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
919
933
  import { join as join5, relative } from "path";
920
934
  import chalk2 from "chalk";
935
+ async function resolveModel2(ollamaUrl, chatModel) {
936
+ try {
937
+ const res = await fetch(`${ollamaUrl}/api/tags`, { signal: AbortSignal.timeout(3e3) });
938
+ if (!res.ok) return chatModel;
939
+ const data = await res.json();
940
+ const models = data.models ?? [];
941
+ const exact = models.find((m) => m.name === chatModel);
942
+ if (exact) return exact.name;
943
+ const prefixed = models.find((m) => m.name.startsWith(`${chatModel}:`));
944
+ if (prefixed) return prefixed.name;
945
+ } catch {
946
+ }
947
+ return chatModel;
948
+ }
921
949
  function getFileLines(filePath) {
922
950
  try {
923
951
  return readFileSync4(filePath, "utf-8").split("\n");
@@ -993,7 +1021,7 @@ async function checkFile(filePath, cwd, config2, verbose) {
993
1021
  const { rules, avoids } = getProfileRules(config2);
994
1022
  if (rules.length === 0) return;
995
1023
  const ollamaUrl = process.env.OLLAMA_URL ?? "http://localhost:11434";
996
- const chatModel = process.env.OLLAMA_CHAT_MODEL ?? "llama3.2";
1024
+ const chatModel = await resolveModel2(ollamaUrl, process.env.OLLAMA_CHAT_MODEL ?? "llama3.2");
997
1025
  const MAX_DIFF = 6e3;
998
1026
  const truncated = diff.length > MAX_DIFF;
999
1027
  const diffToSend = truncated ? diff.slice(0, MAX_DIFF) + "\n\n[diff truncated]" : diff;
@@ -1092,7 +1120,7 @@ ${diffToSend}` }
1092
1120
  }
1093
1121
  }
1094
1122
  }
1095
- function startWatch(options = {}) {
1123
+ async function startWatch(options = {}) {
1096
1124
  const cwd = process.cwd();
1097
1125
  const config2 = loadConfig(cwd);
1098
1126
  if (!config2) {
@@ -1106,7 +1134,7 @@ function startWatch(options = {}) {
1106
1134
  }
1107
1135
  const watchPath = options.path ?? cwd;
1108
1136
  const ollamaUrl = process.env.OLLAMA_URL ?? "http://localhost:11434";
1109
- const chatModel = process.env.OLLAMA_CHAT_MODEL ?? "llama3.2";
1137
+ const chatModel = await resolveModel2(ollamaUrl, process.env.OLLAMA_CHAT_MODEL ?? "llama3.2");
1110
1138
  console.log(chalk2.cyan("\n archmind watch \u2014 real-time rule enforcement\n"));
1111
1139
  console.log(chalk2.dim(` watching: ${watchPath}`));
1112
1140
  console.log(chalk2.dim(` model: ${chatModel}`));
@@ -1304,10 +1332,12 @@ program.command("init").description("Initialize memory-core in the current proje
1304
1332
  try {
1305
1333
  const res = await fetch(`${ollamaUrl}/api/tags`, { signal: AbortSignal.timeout(5e3) });
1306
1334
  const data = await res.json();
1307
- const installed = (data.models ?? []).some(
1308
- (m) => m.name === chatModel || m.name.startsWith(`${chatModel}:`)
1309
- );
1310
- if (installed) {
1335
+ const models = data.models ?? [];
1336
+ const exact = models.find((m) => m.name === chatModel);
1337
+ const prefixed = models.find((m) => m.name.startsWith(`${chatModel}:`));
1338
+ const match = exact ?? prefixed;
1339
+ if (match) {
1340
+ chatModel = match.name;
1311
1341
  modelSpinner.succeed(chalk3.green(`${chatModel} is installed and ready`));
1312
1342
  break;
1313
1343
  } else {
@@ -1400,6 +1430,10 @@ program.command("init").description("Initialize memory-core in the current proje
1400
1430
  ]
1401
1431
  });
1402
1432
  }
1433
+ const enableHook = await confirm({
1434
+ message: "Enable pre-commit hook? (blocks commits that violate your rules)",
1435
+ default: true
1436
+ });
1403
1437
  const config2 = {
1404
1438
  projectName,
1405
1439
  projectType,
@@ -1438,6 +1472,9 @@ program.command("init").description("Initialize memory-core in the current proje
1438
1472
  );
1439
1473
  writeProjectConfig(config2);
1440
1474
  spinner.succeed(`Generated ${written.length} files`);
1475
+ if (enableHook) {
1476
+ installHook();
1477
+ }
1441
1478
  const status = await checkConnections(
1442
1479
  process.env.DATABASE_URL ?? "",
1443
1480
  process.env.OLLAMA_URL ?? "http://localhost:11434",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shahmilsaari/memory-core",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "Universal AI memory core — generate AI context files from architecture profiles with RAG support",
5
5
  "type": "module",
6
6
  "bin": {