@shahmilsaari/memory-core 1.0.16 → 1.0.18

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
@@ -393,22 +393,22 @@ When `--path` is provided, it must point to the project root (the directory cont
393
393
  ### `check` — Manual check (for CI)
394
394
 
395
395
  ```bash
396
- npx @shahmilsaari/memory-core check --staged # check staged files
397
- npx @shahmilsaari/memory-core check --staged --fast # deterministic-only staged check
398
- npx @shahmilsaari/memory-core check --staged --verbose # with extra detail
399
- npx @shahmilsaari/memory-core check --staged --debug # show prompt, diff, and raw model output
400
- npx @shahmilsaari/memory-core check --ci # CI mode using memories.json
401
- npx @shahmilsaari/memory-core check --all # scan all tracked source files (not just staged changes)
402
- npx @shahmilsaari/memory-core check --all --path src/ # scan only tracked files under src/
396
+ npx @shahmilsaari/memory-core check --staged # check staged files
397
+ npx @shahmilsaari/memory-core check --staged --fast # deterministic-only staged check
398
+ npx @shahmilsaari/memory-core check --staged --verbose # with extra detail
399
+ npx @shahmilsaari/memory-core check --staged --debug # show prompt, diff, and raw model output
400
+ npx @shahmilsaari/memory-core check --commit-msg # check .git/COMMIT_EDITMSG
401
+ npx @shahmilsaari/memory-core check --commit-msg <file> # check a specific message file
402
+ npx @shahmilsaari/memory-core check --ci # CI mode using memories.json
403
+ npx @shahmilsaari/memory-core check --all # scan all tracked source files
404
+ npx @shahmilsaari/memory-core check --all --path src/ # scan only tracked files under src/
403
405
  ```
404
406
 
405
- `--staged` is the same path used by the pre-commit hook. Add `--fast` to skip AI and memory retrieval when you need a low-latency deterministic check. `--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.
406
- `--all` runs a full tracked-file snapshot check and exits non-zero if violations are found.
407
- `--all` and `--ci` are mutually exclusive in the same command.
407
+ `--staged` is the same path used by the pre-commit hook. Add `--fast` to skip AI and memory retrieval for a low-latency deterministic check. `--commit-msg` validates a commit message file against `commitRules` this is called automatically by the `commit-msg` hook. `--ci` reads `memories.json` with no database or Ollama required. `--all` and `--ci` are mutually exclusive.
408
408
 
409
409
  ---
410
410
 
411
- ### `hook install` — Install the pre-commit hook
411
+ ### `hook install` — Install hooks
412
412
 
413
413
  ```bash
414
414
  npx @shahmilsaari/memory-core hook install # advisory mode (default)
@@ -417,38 +417,32 @@ npx @shahmilsaari/memory-core hook install --strict # blocks commits on viola
417
417
  npx @shahmilsaari/memory-core hook install --fast # deterministic-only hook
418
418
  ```
419
419
 
420
- Installs a git pre-commit hook in the current project. Every time you run `git commit`, your code is checked against your architecture rules.
420
+ Installs **two** git hooks:
421
+ - `.git/hooks/pre-commit` — checks staged code against architecture rules.
422
+ - `.git/hooks/commit-msg` — checks commit messages against `commitRules` (see `commit-rules` command).
421
423
 
422
- Add `--fast` to make the hook skip AI and memory retrieval for lower latency.
424
+ **Advisory mode (default):** violations are logged but the commit always goes through.
423
425
 
424
- **Advisory mode (default):** violations are logged so you can see them, but the commit always goes through. Useful for getting used to the rules without disrupting your flow.
425
-
426
- **Strict mode:** violations block the commit entirely. You see exactly what's wrong and how to fix it:
426
+ **Strict mode:** violations block the commit. You see exactly what's wrong:
427
427
 
428
428
  ```
429
429
  ✗ 2 rule violations found — commit blocked
430
430
 
431
- [1] src/controllers/user.ts:32
432
- Rule: Thin controllers business logic belongs in services
433
- Why: Logic in controllers cannot be reused from other entry points
434
- — it gets siloed and duplicated across handlers
435
- Issue: Password validation logic inside route handler
436
- Fix: Move to UserService.validateCredentials()
431
+ [1] Thin controllers ×2
432
+ src/controllers/user.ts:32 Password validation in route handler
433
+ src/controllers/auth.ts:18 DB query inside controller
437
434
 
438
435
  [2] src/domain/user.entity.ts:5
439
436
  Rule: Domain has zero external imports
440
- Why: Framework imports tie business logic to infrastructure
441
437
  Issue: Imports 'typeorm' directly
442
438
  Fix: Define IUserRepository interface in domain/
443
439
 
444
- To bypass: git commit --no-verify
445
- To save as memory: memory-core remember "<lesson>"
440
+ To bypass: MEMORY_CORE_SKIP_HOOK=1 git commit
441
+ Manage rules: memory-core commit-rules --list
446
442
  ```
447
443
 
448
- The hook mode is chosen during `init` — no separate step needed unless you want to change it later.
449
-
450
444
  ```bash
451
- npx @shahmilsaari/memory-core hook uninstall # remove the hook
445
+ npx @shahmilsaari/memory-core hook uninstall # remove both hooks
452
446
  ```
453
447
 
454
448
  ---
@@ -582,6 +576,28 @@ Stores lightweight per-project allowlist strings in `.memory-core.json`. Hook an
582
576
 
583
577
  ---
584
578
 
579
+ ### `commit-rules` — Enforce commit message format
580
+
581
+ ```bash
582
+ npx @shahmilsaari/memory-core commit-rules "^(feat|fix|chore)" --message "Use conventional commits"
583
+ npx @shahmilsaari/memory-core commit-rules "^WIP" --message "Don't commit WIP" --negate
584
+ npx @shahmilsaari/memory-core commit-rules "PROJ-\d+" --message "Reference a JIRA ticket" --advisory
585
+ npx @shahmilsaari/memory-core commit-rules --list
586
+ npx @shahmilsaari/memory-core commit-rules --remove "^WIP"
587
+ ```
588
+
589
+ Stores regex-based rules in `.memory-core.json` under `commitRules`. The `commit-msg` git hook (installed by `hook install`) validates every commit message against these rules before the commit is accepted.
590
+
591
+ | Flag | What it does |
592
+ |---|---|
593
+ | `--message <msg>` | Required. Error message shown on violation. |
594
+ | `--negate` | Pattern must NOT match (default: must match) |
595
+ | `--advisory` | Warn only — do not block the commit |
596
+ | `--list` | Show all saved commit rules |
597
+ | `--remove <pattern>` | Remove a rule by pattern |
598
+
599
+ ---
600
+
585
601
  ### `ci-setup` — GitHub Actions integration
586
602
 
587
603
  ```bash
@@ -596,13 +612,33 @@ Generates `.github/workflows/memory-core.yml`. Adds a PR check that runs `npx @s
596
612
 
597
613
  ```bash
598
614
  npx @shahmilsaari/memory-core stats
615
+ npx @shahmilsaari/memory-core stats --tune
599
616
  npx @shahmilsaari/memory-core stats --reset
600
617
  ```
601
618
 
602
- Shows which rules fire most often and which files have the most violations.
603
- - If live watch state exists, `stats` shows current live counters.
604
- - Otherwise it shows historical counters recorded over time.
605
- - Use `--reset` to clear counters and recent violation history.
619
+ Shows which rules fire most often and which files have the most violations. Each rule shows hit count and false-positive rate where available.
620
+
621
+ - `--tune` shows only noisy rules (>40% false-positive rate) with their exact disable commands.
622
+ - `--reset` clears all counters and recent violation history.
623
+ - Live watch-state counters are shown when available.
624
+
625
+ ---
626
+
627
+ ### `tune` — Silence noisy rules
628
+
629
+ ```bash
630
+ npx @shahmilsaari/memory-core tune
631
+ npx @shahmilsaari/memory-core tune --threshold 30
632
+ npx @shahmilsaari/memory-core tune --yes
633
+ ```
634
+
635
+ Interactively reviews rules with a high false-positive rate and adds them to `allowPatterns` in `.memory-core.json`.
636
+
637
+ | Flag | What it does |
638
+ |---|---|
639
+ | `--threshold <n>` | False-positive % cutoff (default `40`) |
640
+ | `--min-count <n>` | Minimum hits required (default `5`) |
641
+ | `--yes` | Silence all qualifying rules without prompting |
606
642
 
607
643
  ---
608
644
 
@@ -856,20 +892,24 @@ npm run smoke:npx
856
892
  | ✓ | NestJS profile and 39 rules |
857
893
  | ✓ | Hook auto-prompt — hook mode offered during init, no separate step needed |
858
894
  | ✓ | CI/CD — `ci-setup` generates GitHub Actions workflow for PR enforcement |
859
- | ✓ | Violation stats — see which rules fire most and which files break most |
860
895
  | ✓ | Agent selection — choose which agents to generate files for during init |
861
896
  | ✓ | Auto-sync — memory-changing commands refresh selected agent files by default |
862
897
  | ✓ | Export / import — portable memories.json for version control and team sharing |
863
898
  | ✓ | List / remove / edit — full CRUD for stored memories |
864
- | ✓ | False positive tagging — `ignore` command saves exceptions for hook and watcher |
865
- | ✓ | Cleanup commands — `reset` regenerates/reinitializes files; `uninstall` removes memory-core from a project |
866
- | ✓ | Test suite — smoke tests for all core commands and providers |
899
+ | ✓ | False positive tagging — `ignore` and `allow` save exceptions for hook and watcher |
900
+ | ✓ | Cleanup commands — `reset` regenerates/reinitializes files; `uninstall` removes memory-core |
901
+ | ✓ | Test suite — 94 tests using Node.js built-in `node:test` |
867
902
  | ✓ | Multi-provider code checking — Ollama, OpenAI, Anthropic, MiniMax |
868
903
  | ✓ | Context-aware retrieval — surface the most relevant rules for the file being edited |
869
904
  | ✓ | Setup management — `status`, `provider set`, `model set`, `model doctor` |
870
905
  | ✓ | `--debug` flag — verbose output for diagnosing hook and watcher issues |
871
- | ✓ | Local Svelte dashboard — WebSocket live feed, runtime status, stats, and architecture-filtered rules |
872
- | ✓ | Live config reload dashboard updates when `.env`, `.memory-core.env`, project config, or stats change |
906
+ | ✓ | Local Svelte dashboard — WebSocket live feed, runtime status, stats, and rules browser |
907
+ | ✓ | Rule cache5-min TTL cache, invalidated by config or DB version change |
908
+ | ✓ | Batch suppression — same rule ≥3× on same file auto-suppressed with a notice |
909
+ | ✓ | False-positive tracking — `{ count, falsePositives }` stored per rule in stats |
910
+ | ✓ | Violation clustering — violations grouped by rule, compact multi-location display |
911
+ | ✓ | Auto-tuning — `memory-core tune` silences noisy rules interactively |
912
+ | ✓ | Commit message linting — `commit-rules` + `commit-msg` git hook |
873
913
  | | Model guidance during init — recommend a model based on machine specs |
874
914
  | | Violation → rule pipeline — auto-suggest a new rule when the same violation repeats |
875
915
  | | Team sync — shared database so the whole team works from the same rule set |
@@ -124,7 +124,8 @@ function getChatConfig() {
124
124
  provider,
125
125
  model,
126
126
  ollamaUrl: process.env.OLLAMA_URL ?? "http://localhost:11434",
127
- apiKey: process.env.CHAT_API_KEY ?? ""
127
+ apiKey: process.env.CHAT_API_KEY ?? "",
128
+ baseUrl: process.env.CHAT_BASE_URL ?? ""
128
129
  };
129
130
  }
130
131
  function getDefaultTimeoutMs() {
@@ -158,8 +159,9 @@ async function callOllama(cfg, messages, options = {}) {
158
159
  const data = await res.json();
159
160
  return data.message.content.trim();
160
161
  }
161
- async function callOpenAI(cfg, messages, options = {}) {
162
- const res = await fetch("https://api.openai.com/v1/chat/completions", {
162
+ async function callOpenAICompat(cfg, messages, options = {}) {
163
+ const base = (cfg.baseUrl ?? "").replace(/\/$/, "") || "https://api.openai.com/v1";
164
+ const res = await fetch(`${base}/chat/completions`, {
163
165
  method: "POST",
164
166
  headers: {
165
167
  "Content-Type": "application/json",
@@ -221,7 +223,8 @@ async function callChatModel(messages, options = {}) {
221
223
  try {
222
224
  switch (cfg.provider) {
223
225
  case "openai":
224
- return await callOpenAI(cfg, messages, options);
226
+ case "openai-compatible":
227
+ return await callOpenAICompat(cfg, messages, options);
225
228
  case "anthropic":
226
229
  return await callAnthropic(cfg, messages, options);
227
230
  case "minimax":
@@ -236,6 +239,10 @@ async function callChatModel(messages, options = {}) {
236
239
  function getChatProviderLabel() {
237
240
  const cfg = getChatConfig();
238
241
  if (cfg.provider === "ollama") return `ollama (${cfg.model})`;
242
+ if (cfg.provider === "openai-compatible") {
243
+ const host = cfg.baseUrl ? new URL(cfg.baseUrl).hostname : "custom";
244
+ return `openai-compat/${host} (${cfg.model})`;
245
+ }
239
246
  return `${cfg.provider} (${cfg.model})`;
240
247
  }
241
248