fastrmemory 0.5.0 → 0.6.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 (128) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +2 -2
  3. package/.cursor/skills/skills.json +1 -1
  4. package/README.md +40 -30
  5. package/dist/bin/fastr.js +122 -14
  6. package/dist/bin/fastr.js.map +1 -1
  7. package/dist/src/bench/harness.d.ts.map +1 -1
  8. package/dist/src/bench/harness.js +4 -0
  9. package/dist/src/bench/harness.js.map +1 -1
  10. package/dist/src/bench/marker-corpus.d.ts +98 -0
  11. package/dist/src/bench/marker-corpus.d.ts.map +1 -0
  12. package/dist/src/bench/marker-corpus.js +306 -0
  13. package/dist/src/bench/marker-corpus.js.map +1 -0
  14. package/dist/src/bench/mcp-stdio.d.ts +55 -0
  15. package/dist/src/bench/mcp-stdio.d.ts.map +1 -0
  16. package/dist/src/bench/mcp-stdio.js +146 -0
  17. package/dist/src/bench/mcp-stdio.js.map +1 -0
  18. package/dist/src/bench/public-datasets.d.ts +2 -0
  19. package/dist/src/bench/public-datasets.d.ts.map +1 -1
  20. package/dist/src/bench/public-datasets.js +2 -1
  21. package/dist/src/bench/public-datasets.js.map +1 -1
  22. package/dist/src/bench/public-harness.d.ts +14 -0
  23. package/dist/src/bench/public-harness.d.ts.map +1 -1
  24. package/dist/src/bench/public-harness.js +83 -8
  25. package/dist/src/bench/public-harness.js.map +1 -1
  26. package/dist/src/bench/public-pins.js +5 -5
  27. package/dist/src/bench/public-pins.js.map +1 -1
  28. package/dist/src/bench/split.d.ts +33 -0
  29. package/dist/src/bench/split.d.ts.map +1 -0
  30. package/dist/src/bench/split.js +56 -0
  31. package/dist/src/bench/split.js.map +1 -0
  32. package/dist/src/bench/stats.d.ts +40 -0
  33. package/dist/src/bench/stats.d.ts.map +1 -0
  34. package/dist/src/bench/stats.js +99 -0
  35. package/dist/src/bench/stats.js.map +1 -0
  36. package/dist/src/bench/vs-engines.d.ts +51 -0
  37. package/dist/src/bench/vs-engines.d.ts.map +1 -0
  38. package/dist/src/bench/vs-engines.js +121 -0
  39. package/dist/src/bench/vs-engines.js.map +1 -0
  40. package/dist/src/config.d.ts +33 -0
  41. package/dist/src/config.d.ts.map +1 -1
  42. package/dist/src/config.js +84 -1
  43. package/dist/src/config.js.map +1 -1
  44. package/dist/src/db/doctor.d.ts +8 -0
  45. package/dist/src/db/doctor.d.ts.map +1 -1
  46. package/dist/src/db/doctor.js +65 -1
  47. package/dist/src/db/doctor.js.map +1 -1
  48. package/dist/src/db/fts-queue.d.ts +35 -0
  49. package/dist/src/db/fts-queue.d.ts.map +1 -0
  50. package/dist/src/db/fts-queue.js +78 -0
  51. package/dist/src/db/fts-queue.js.map +1 -0
  52. package/dist/src/db/repository.d.ts +63 -1
  53. package/dist/src/db/repository.d.ts.map +1 -1
  54. package/dist/src/db/repository.js +244 -50
  55. package/dist/src/db/repository.js.map +1 -1
  56. package/dist/src/db/schema.d.ts +1 -1
  57. package/dist/src/db/schema.d.ts.map +1 -1
  58. package/dist/src/db/schema.js +63 -2
  59. package/dist/src/db/schema.js.map +1 -1
  60. package/dist/src/installer/copilot.d.ts +21 -0
  61. package/dist/src/installer/copilot.d.ts.map +1 -1
  62. package/dist/src/installer/copilot.js +72 -1
  63. package/dist/src/installer/copilot.js.map +1 -1
  64. package/dist/src/installer/gemini.d.ts +13 -0
  65. package/dist/src/installer/gemini.d.ts.map +1 -1
  66. package/dist/src/installer/gemini.js +64 -1
  67. package/dist/src/installer/gemini.js.map +1 -1
  68. package/dist/src/installer/hooks.d.ts +42 -5
  69. package/dist/src/installer/hooks.d.ts.map +1 -1
  70. package/dist/src/installer/hooks.js +270 -62
  71. package/dist/src/installer/hooks.js.map +1 -1
  72. package/dist/src/installer/json-config.d.ts +25 -1
  73. package/dist/src/installer/json-config.d.ts.map +1 -1
  74. package/dist/src/installer/json-config.js +95 -2
  75. package/dist/src/installer/json-config.js.map +1 -1
  76. package/dist/src/installer/mcp-init.d.ts.map +1 -1
  77. package/dist/src/installer/mcp-init.js +5 -6
  78. package/dist/src/installer/mcp-init.js.map +1 -1
  79. package/dist/src/installer/opencode.d.ts +18 -0
  80. package/dist/src/installer/opencode.d.ts.map +1 -1
  81. package/dist/src/installer/opencode.js +81 -1
  82. package/dist/src/installer/opencode.js.map +1 -1
  83. package/dist/src/installer/setup.d.ts +7 -0
  84. package/dist/src/installer/setup.d.ts.map +1 -1
  85. package/dist/src/installer/setup.js +32 -0
  86. package/dist/src/installer/setup.js.map +1 -1
  87. package/dist/src/mcp/profiles.d.ts +9 -6
  88. package/dist/src/mcp/profiles.d.ts.map +1 -1
  89. package/dist/src/mcp/profiles.js +12 -9
  90. package/dist/src/mcp/profiles.js.map +1 -1
  91. package/dist/src/mcp/server.d.ts +1 -1
  92. package/dist/src/mcp/server.d.ts.map +1 -1
  93. package/dist/src/mcp/server.js +80 -0
  94. package/dist/src/mcp/server.js.map +1 -1
  95. package/dist/src/search/aggregate.d.ts +24 -0
  96. package/dist/src/search/aggregate.d.ts.map +1 -0
  97. package/dist/src/search/aggregate.js +59 -0
  98. package/dist/src/search/aggregate.js.map +1 -0
  99. package/dist/src/search/backfill.d.ts.map +1 -1
  100. package/dist/src/search/backfill.js +7 -2
  101. package/dist/src/search/backfill.js.map +1 -1
  102. package/dist/src/search/budget.d.ts +2 -0
  103. package/dist/src/search/budget.d.ts.map +1 -1
  104. package/dist/src/search/budget.js.map +1 -1
  105. package/dist/src/search/embeddings.d.ts +35 -2
  106. package/dist/src/search/embeddings.d.ts.map +1 -1
  107. package/dist/src/search/embeddings.js +128 -5
  108. package/dist/src/search/embeddings.js.map +1 -1
  109. package/dist/src/search/hybrid-rrf.d.ts +45 -0
  110. package/dist/src/search/hybrid-rrf.d.ts.map +1 -1
  111. package/dist/src/search/hybrid-rrf.js +212 -56
  112. package/dist/src/search/hybrid-rrf.js.map +1 -1
  113. package/dist/src/search/static-model-install.d.ts +43 -0
  114. package/dist/src/search/static-model-install.d.ts.map +1 -0
  115. package/dist/src/search/static-model-install.js +112 -0
  116. package/dist/src/search/static-model-install.js.map +1 -0
  117. package/dist/src/search/static-model.d.ts +63 -0
  118. package/dist/src/search/static-model.d.ts.map +1 -0
  119. package/dist/src/search/static-model.js +244 -0
  120. package/dist/src/search/static-model.js.map +1 -0
  121. package/dist/src/search/temporal.d.ts +32 -0
  122. package/dist/src/search/temporal.d.ts.map +1 -0
  123. package/dist/src/search/temporal.js +164 -0
  124. package/dist/src/search/temporal.js.map +1 -0
  125. package/llms-install.md +3 -3
  126. package/package.json +5 -1
  127. package/server.json +1 -1
  128. package/skills/skills.json +1 -1
@@ -8,7 +8,7 @@
8
8
  "name": "fastrmemory",
9
9
  "source": "./",
10
10
  "description": "Local-first agent memory for Claude Code: MCP server plus Agent Skills for pre-edit trap checks, recall, trap logging, curation, and session handoffs.",
11
- "version": "0.5.0"
11
+ "version": "0.6.0"
12
12
  }
13
13
  ]
14
14
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fastrmemory",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Local-first agent memory for Claude Code: MCP server plus Agent Skills for pre-edit trap checks, recall, trap logging, curation, and session handoffs.",
5
5
  "author": {
6
6
  "name": "Fastrsoft"
@@ -12,7 +12,7 @@
12
12
  "mcpServers": {
13
13
  "fastrmemory": {
14
14
  "command": "npx",
15
- "args": ["-y", "fastrmemory@0.5.0", "mcp"]
15
+ "args": ["-y", "fastrmemory@0.6.0", "mcp"]
16
16
  }
17
17
  }
18
18
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://skills.sh/schema/v1.json",
3
3
  "name": "fastrmemory-skills",
4
- "version": "0.5.0",
4
+ "version": "0.6.0",
5
5
  "description": "Agent Skills that teach coding agents when to recall, log traps, curate, and commit FastrMemory.",
6
6
  "author": "Fastrsoft",
7
7
  "license": "Apache-2.0",
package/README.md CHANGED
@@ -10,11 +10,11 @@
10
10
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg?style=flat-square)](LICENSE)
11
11
  [![Node](https://img.shields.io/badge/Node-%3E%3D22.16.0-339933?style=flat-square&logo=node.js&logoColor=white)](https://nodejs.org)
12
12
  [![Protocol](https://img.shields.io/badge/Protocol-MCP%20v2-7C3AED?style=flat-square)](https://modelcontextprotocol.io)
13
- [![Tests](https://img.shields.io/badge/Tests-297%20Passed-brightgreen?style=flat-square)](tests/)
13
+ [![Tests](https://img.shields.io/badge/Tests-388%20Passed-brightgreen?style=flat-square)](tests/)
14
14
  [![MCP Setup](https://img.shields.io/badge/MCP%20Setup-fastr%20mcp%20init-7C3AED?style=flat-square)](#-one-click-agent-mcp-configuration)
15
15
  [![Architecture](https://img.shields.io/badge/Architecture-Zero--Daemon%20WAL-orange?style=flat-square)](#-architecture)
16
16
 
17
- > **Status (2026-10-23):** **`fastrmemory@0.4.0` is published and is `latest`.** Evidence: `npm view fastrmemory version` -> `0.4.0`; `npm view fastrmemory dist-tags --json` -> `{"latest":"0.4.0"}`; tag `v0.4.0` (`bb365c2`); published 2026-10-23 07:32 UTC via GitHub Actions OIDC with npm provenance; release workflow run `39918288792` passed the full gate, clean tarball install, registry verification, and GitHub Release upload; GitHub Release tarball SHA-256 `b784e3e12b8a50deaee3b38dbc1f45c756bc37462f2d40433fdda5288cf554ad`; `npm install -g fastrmemory@0.4.0` + `fastr --version` -> `0.4.0`; `npm audit signatures` reports 5 verified registry signatures and 4 verified attestations. Caveat: Node.js >=22.16.0; `0.3.1` remains published historical and `0.3.0` remains historical. This release adds `fastr mcp init` and LF checkout enforcement, with no schema migration. The old scoped npm entries (`@atifjubaer/fastrmemory` and `fastrmemory@0.0.0-stage`) were removed on 2026-10-23; the GitHub `v0.2.1` tag and release remain as history. This README tracks current `main`. Current `main` is **`0.5.0`** and adds `fastr mcp init --source local`; it has **297 tests / 53 files**. `0.5.0` is prepared but not yet published, so `--source local` remains unavailable from npm `latest` until the `v0.5.0` release workflow completes. Until then, use the exact `0.4.0` version for reproducibility. CI run `39935705994` at `6c2a53a` passed all six matrix jobs on 2026-10-23, including Windows Node `22.x` and `24.x`; the `0.4.0` release commit `bb365c2` passed run `39879913968`. The release post for 0.2.1 remains at [docs/blog/2026-10-21-fastrmemory-0.2.1.md](docs/blog/2026-10-21-fastrmemory-0.2.1.md). The exact release surface is in [CHANGELOG.md](CHANGELOG.md). The headline benchmark uses **240 deterministic synthetic cases with a 20% holdout**, not SWE-bench or LongMemEval. Public LongMemEval, LoCoMo, and self-repository retrieval-only results plus pinned external baselines are in [BENCHMARKS.md](BENCHMARKS.md); no QA-leaderboard parity is claimed. Performance, packaging, and retrieval claims are tracked in [CLAIMS.md](CLAIMS.md); every README section is mapped to claim IDs in the README claim trace at the end of that ledger. Methodology, caveats, and raw JSON are in [BENCHMARKS.md](BENCHMARKS.md).
17
+ > **Status (2026-10-23):** **`fastrmemory@0.5.0` is published and is `latest`.** Evidence: `npm view fastrmemory version` -> `0.5.0`; `npm view fastrmemory dist-tags --json` -> `{"latest":"0.5.0"}`; tag `v0.5.0` (`54a79ab`); published 2026-10-23 15:20 UTC via GitHub Actions OIDC with npm provenance; release workflow run `39977196250` passed the full gate, clean tarball install, registry verification, and GitHub Release upload; GitHub Release tarball SHA-256 `10420ed6c70e6db52984ad6b895949f0f1d849dff06e2cb9227b7b56540cfb0e`; `npm install -g fastrmemory@0.5.0` + `fastr --version` -> `0.5.0`; `npm audit signatures` reports 5 verified registry signatures and 4 verified attestations. Caveat: Node.js >=22.16.0; `0.4.0` remains published historical, `0.3.1` remains published historical, and `0.3.0` remains historical. This release adds `fastr mcp init --source local`, with no schema migration. The old scoped npm entries (`@atifjubaer/fastrmemory` and `fastrmemory@0.0.0-stage`) were removed on 2026-10-23; the GitHub `v0.2.1` tag and release remain as history. This README tracks current `main`. Current `main` is **`0.5.0`** and has **388 tests / 61 files**; `--source local` is available from published `0.5.0`. Use the exact `0.5.0` version for reproducibility. CI run `39935705994` at `6c2a53a` passed all six matrix jobs on 2026-10-23, including Windows Node `22.x` and `24.x`; the `0.5.0` release commit `54a79ab` passed run `39977196250`, and the historical `0.4.0` release commit `bb365c2` passed run `39879913968`. The release post for 0.2.1 remains at [docs/blog/2026-10-21-fastrmemory-0.2.1.md](docs/blog/2026-10-21-fastrmemory-0.2.1.md). The exact release surface is in [CHANGELOG.md](CHANGELOG.md). The headline benchmark uses **240 deterministic synthetic cases with a 20% holdout**, not SWE-bench or LongMemEval. Public LongMemEval, LoCoMo, and self-repository retrieval-only results plus pinned external baselines are in [BENCHMARKS.md](BENCHMARKS.md); no QA-leaderboard parity is claimed. Performance, packaging, and retrieval claims are tracked in [CLAIMS.md](CLAIMS.md); every README section is mapped to claim IDs in the README claim trace at the end of that ledger. Methodology, caveats, and raw JSON are in [BENCHMARKS.md](BENCHMARKS.md).
18
18
 
19
19
  <p align="center">
20
20
  <a href="#-overview">Overview</a> &bull;
@@ -39,10 +39,10 @@
39
39
 
40
40
  | Claim | Current result | Evidence |
41
41
  |---|---|---|
42
- | Install path | Published `fastrmemory@0.4.0` | `npm view fastrmemory version` -> `0.4.0`; `npm view fastrmemory dist-tags --json` -> `{"latest":"0.4.0"}`; `npm install -g fastrmemory@0.4.0`; `fastr --version` -> `0.4.0`; GitHub Release tarball SHA-256 `b784e3e1...`; old scoped npm entries removed |
42
+ | Install path | Published `fastrmemory@0.5.0` | `npm view fastrmemory version` -> `0.5.0`; `npm view fastrmemory dist-tags --json` -> `{"latest":"0.5.0"}`; `npm install -g fastrmemory@0.5.0`; `fastr --version` -> `0.5.0`; GitHub Release tarball SHA-256 `10420ed6...`; old scoped npm entries removed |
43
43
  | Synthetic retrieval (optional MiniLM) | Holdout `95.8%` Hit@1, `100%` Hit@5, MRR `0.969` | `npx tsx scripts/eval-bench.ts --split all --embeddings minilm --out bench/results/minilm.json` |
44
- | Test suite | `297` tests across `53` files on current `main` (`0.5.0`); published `0.4.0` is `293` / `53`; `0.3.1` is `282` / `52`; v0.2.1 is `235` / `43` | `npm test`; `npm run check:ci` |
45
- | MCP setup | `fastr mcp init` merges portable registry configs or active-CLI local configs for 9 JSON clients and prints a Codex TOML snippet; `--source local` ships in `0.5.0` (prepared; `0.4.0` remains published until `v0.5.0`) | `npm test -- tests/mcp-init.test.ts` -> `15 passed`; `fastr mcp init --client claude --source local --dry-run --json` -> `node .../dist/bin/fastr.js mcp --project ...` |
44
+ | Test suite | `354` tests across `59` files on current `main`; published `0.5.0` is `297` / `53`; historical `0.4.0` is `293` / `53`; `0.3.1` is `282` / `52`; v0.2.1 is `235` / `43` | `npm test`; `npm run check:ci` |
45
+ | MCP setup | `fastr mcp init` merges portable registry configs or active-CLI local configs for 9 JSON clients and prints a Codex TOML snippet; `--source local` ships in published `0.5.0` | `npm test -- tests/mcp-init.test.ts` -> `15 passed`; `fastr mcp init --client claude --source local --dry-run --json` -> `node .../dist/bin/fastr.js mcp --project ...` |
46
46
  | Crash safety | 10/10 runs, 0 lost, 0 duplicate ids/titles | `npm run test:crash`; `bench/results/crash-test.json` |
47
47
  | Public retrieval (0.3.0) | LongMemEval `+10.4pp` / `+11.0pp` Hit@5; LoCoMo `+4.4pp` / `+2.3pp` (target missed) | [docs/EXTERNAL_BASELINE.md](docs/EXTERNAL_BASELINE.md) |
48
48
  | Release score | Provisional `9.4 / 10`; `9.2` target met; Retrieval remains Partial | [SCORECARD.md](SCORECARD.md) |
@@ -77,7 +77,7 @@ Never deletes facts during consolidation (there is no destructive sleep step). R
77
77
  <td width="33%" align="center">
78
78
 
79
79
  ### 🎯 Triple-Stream RRF ($k=20$)
80
- Fuses FTS5 BM25 + optional local embeddings + file-graph links. Error traps receive a **conditional 2.0x boost** only for trap-intent or file-scoped queries, with per-ID outcome feedback (+0.2 / -0.5). Three consecutive bad outcomes move a memory to dormant; confidence tiers are `high`, `medium`, `low`, `dormant`, and `superseded`.
80
+ Fuses FTS5 BM25 + optional local embeddings + file-graph links. Error traps receive a **conditional 2.0x boost** only for trap-intent or file-scoped queries, with per-ID outcome feedback (+0.2 / -0.5). Three consecutive bad outcomes move a memory to dormant; confidence tiers are `high`, `medium`, `low`, `dormant`, and `superseded`. Counting questions ("how many projects have I led?") additionally run an aggregate-coverage pass: a second lexical query over their content terms, fused with the original, returning up to 20 rows so the caller can count. `retrieval.temporalFilter` adds opt-in date windows ("past two weeks", "this year") parsed against the question date.
81
81
 
82
82
  </td>
83
83
  </tr>
@@ -110,38 +110,38 @@ Clients commonly used with FastrMemory include Codex CLI, Gemini CLI, OpenCode,
110
110
 
111
111
  ### ⚡ Run Without a Global Install
112
112
 
113
- The canonical package target is unscoped `fastrmemory@0.4.0`. `0.3.1` remains published historical. The old scoped npm entries were removed on 2026-10-23.
113
+ The canonical package target is unscoped `fastrmemory@0.5.0`. `0.4.0` and `0.3.1` remain published historical. The old scoped npm entries were removed on 2026-10-23.
114
114
 
115
115
  ```bash
116
116
  # Canonical one-shot (pins the exact release):
117
- npx -y fastrmemory@0.4.0 setup
117
+ npx -y fastrmemory@0.5.0 setup
118
118
 
119
119
  # Or launch the local Web UI:
120
- npx -y fastrmemory@0.4.0 ui
120
+ npx -y fastrmemory@0.5.0 ui
121
121
  ```
122
122
 
123
- The GitHub source path remains available for development only: `npx github:atifjubaer/fastrmemory setup`. For a reproducible source install, pin the tag: `npx github:atifjubaer/fastrmemory#v0.4.0 setup`. Do not use either GitHub form in generated MCP or hook configs; those must use the npm package. The default `latest` channel tracks new releases, and `--channel pinned` records the exact version for reproducibility.
123
+ The GitHub source path remains available for development only: `npx github:atifjubaer/fastrmemory setup`. For a reproducible source install, pin the tag: `npx github:atifjubaer/fastrmemory#v0.5.0 setup`. Do not use either GitHub form in generated MCP or hook configs; those must use the npm package. The default `latest` channel tracks new releases, and `--channel pinned` records the exact version for reproducibility.
124
124
 
125
125
  ---
126
126
 
127
127
  ### Install from npm
128
128
 
129
129
  ```bash
130
- # Canonical install (latest is 0.4.0):
130
+ # Canonical install (latest is 0.5.0):
131
131
  npm install -g fastrmemory
132
132
  fastr --version
133
133
 
134
134
  # Exact release:
135
- npm install -g fastrmemory@0.4.0
135
+ npm install -g fastrmemory@0.5.0
136
136
  ```
137
137
 
138
138
  For a one-shot run without a global install:
139
139
 
140
140
  ```bash
141
- npx -y fastrmemory@0.4.0 --version
141
+ npx -y fastrmemory@0.5.0 --version
142
142
  ```
143
143
 
144
- `0.4.0` is built from tag `v0.4.0` by `.github/workflows/release.yml`, which runs the full gate, publishes with npm provenance, and attaches the same tarball to the GitHub Release. Verify the registry result with `npm view fastrmemory@0.4.0 version` and `npm view fastrmemory dist-tags --json`; a first E404 for a few minutes is registry propagation, not a failed publish. The old scoped npm entries remain removed. Do not republish `0.3.0`. `0.3.1` remains published historical.
144
+ `0.5.0` is built from tag `v0.5.0` by `.github/workflows/release.yml`, which runs the full gate, publishes with npm provenance, and attaches the same tarball to the GitHub Release. Verify the registry result with `npm view fastrmemory@0.5.0 version` and `npm view fastrmemory dist-tags --json`; a first E404 for a few minutes is registry propagation, not a failed publish. The old scoped npm entries remain removed. Do not republish `0.3.0`. `0.4.0` and `0.3.1` remain published historical.
145
145
 
146
146
  ### Update an Existing Install
147
147
 
@@ -201,7 +201,7 @@ yarn dlx fastrmemory@latest mcp init --client claude
201
201
  bunx fastrmemory@latest mcp init --client claude
202
202
  ```
203
203
 
204
- The default `--channel latest` writes `fastrmemory@latest`, so a client restart picks up the newest npm release. Use `--channel pinned` for a reproducible config containing the exact version that ran the command; on current `main` that writes `fastrmemory@0.5.0` (pending publication). `--runner pnpm|yarn|bunx` changes the generated runner, `--profile core` selects the 12-tool surface, `--dry-run` prints targets without writing, and `--scope user` writes user-level configs with an explicit `--project /absolute/path` so the server always opens the intended database. Codex prints a `[mcp_servers.fastrmemory]` TOML block for `~/.codex/config.toml` instead of rewriting a user-owned TOML file.
204
+ The default `--channel latest` writes `fastrmemory@latest`, so a client restart picks up the newest npm release. Use `--channel pinned` for a reproducible config containing the exact version that ran the command; on current `main` that writes `fastrmemory@0.5.0`. `--runner pnpm|yarn|bunx` changes the generated runner, `--profile full` selects the 43-tool surface (the default is the 12-tool core profile), `--dry-run` prints targets without writing, and `--scope user` writes user-level configs with an explicit `--project /absolute/path` so the server always opens the intended database. Codex prints a `[mcp_servers.fastrmemory]` TOML block for `~/.codex/config.toml` instead of rewriting a user-owned TOML file.
205
205
 
206
206
  For a globally installed CLI, use `--source local` to write the active CLI path instead of an npx command. It always appends an absolute `--project`, so the config is machine-specific but starts without an npx cold start:
207
207
 
@@ -211,31 +211,31 @@ fastr mcp init --client all --scope user --source local --profile core
211
211
 
212
212
  Updating the global package updates the server; rerun the command only if the CLI path changes. Use the default `--source registry` for portable project configs that are committed and shared across machines.
213
213
 
214
- > `--source local` ships in `0.5.0`. Until the `v0.5.0` release workflow completes, published `0.4.0` remains the install target; use `fastr setup` on `0.4.0` for an installed-CLI config.
214
+ > `--source local` ships in published `0.5.0`; `0.4.0` remains published historical. On `0.4.0`, use `fastr setup` for an installed-CLI config.
215
215
 
216
- > `mcp init` ships in `0.4.0`; `npx fastrmemory@latest mcp init ...` now resolves to published `0.4.0`. If you need the previous release, use `fastr setup` or pin `fastrmemory@0.3.1`.
216
+ > `mcp init` ships in `0.4.0` and later; `npx fastrmemory@latest mcp init ...` now resolves to published `0.5.0`. If you need the previous release, use `fastr setup` or pin `fastrmemory@0.3.1`.
217
217
 
218
218
  ### Install from GitHub
219
219
 
220
220
  For a one-shot source run, pin the release tag:
221
221
 
222
222
  ```bash
223
- npx --yes github:atifjubaer/fastrmemory#v0.4.0 --version
224
- npx --yes github:atifjubaer/fastrmemory#v0.4.0 setup
223
+ npx --yes github:atifjubaer/fastrmemory#v0.5.0 --version
224
+ npx --yes github:atifjubaer/fastrmemory#v0.5.0 setup
225
225
  ```
226
226
 
227
227
  For a global CLI without npm's Git resolver, download the release tarball:
228
228
 
229
229
  ```bash
230
- curl -L -o fastrmemory-0.4.0.tgz \
231
- https://github.com/atifjubaer/fastrmemory/releases/download/v0.4.0/fastrmemory-0.4.0.tgz
232
- npm install -g ./fastrmemory-0.4.0.tgz
230
+ curl -L -o fastrmemory-0.5.0.tgz \
231
+ https://github.com/atifjubaer/fastrmemory/releases/download/v0.5.0/fastrmemory-0.5.0.tgz
232
+ npm install -g ./fastrmemory-0.5.0.tgz
233
233
  fastr --version
234
234
  ```
235
235
 
236
- On Windows, download the same URL with `Invoke-WebRequest` or a browser, then run `npm install -g .\fastrmemory-0.4.0.tgz`. For a local project install, use `npm install --no-save ./fastrmemory-0.4.0.tgz` instead of the global flag.
236
+ On Windows, download the same URL with `Invoke-WebRequest` or a browser, then run `npm install -g .\fastrmemory-0.5.0.tgz`. For a local project install, use `npm install --no-save ./fastrmemory-0.5.0.tgz` instead of the global flag.
237
237
 
238
- > Git installs build from source and are slower than the npm tarball; for a global CLI, prefer the npm package or the release tarball above. `npm install -g git+https://...` is not recommended with npm 11 because the `prepare` build does not receive dev dependencies. Both `fastrmemory` and `fastr` (short alias) are executable after installation. The canonical package is unscoped `fastrmemory@0.4.0`; the old scoped npm entries are gone. Use npm for generated MCP and hook configs so installs stay reproducible.
238
+ > Git installs build from source and are slower than the npm tarball; for a global CLI, prefer the npm package or the release tarball above. `npm install -g git+https://...` is not recommended with npm 11 because the `prepare` build does not receive dev dependencies. Both `fastrmemory` and `fastr` (short alias) are executable after installation. The canonical package is unscoped `fastrmemory@0.5.0`; the old scoped npm entries are gone. Use npm for generated MCP and hook configs so installs stay reproducible.
239
239
 
240
240
  ### 2. Verify Database Health
241
241
 
@@ -373,17 +373,23 @@ fastrmemory vision search "modal error 401"
373
373
 
374
374
  # Pre-merge CI/CD gate checking PR diffs against active error traps:
375
375
  fastrmemory guard --strict
376
+
377
+ # Optional 30 MB static semantic model (never downloaded implicitly):
378
+ fastrmemory model status
379
+ fastrmemory model install
376
380
  ```
377
381
 
378
382
  `fastrmemory hygiene` reports orphaned file links, conflict rows, and feedback rows; duplicate active memories by normalized title or exact content; and stale unpinned active memories (default 90 days since the last recall or creation). `npm run check:hygiene` runs the same inspector against a deterministic fixture inside `check:ci`; it does not mutate a project database. Use `--fail-on-issues` when a script should exit nonzero on findings.
379
383
 
384
+ `fastrmemory model install` fetches `minishlab/potion-base-8M` (256-dim, 30,236,760 bytes), verifies both files against pinned SHA-256 hashes, and stores them under `~/.fastr/models/`. The tier is a bounded reranker over BM25 candidates: it fixes 1 case and breaks 1 across the 120-case LongMemEval slice, so it is documented as non-regressive, not as an accuracy win. Default recall is BM25-only until the asset is installed and backfill has produced vectors.
385
+
380
386
  ---
381
387
 
382
388
  ## 🔌 One-Click Agent MCP Configuration
383
389
 
384
390
  `fastr mcp init` is the one-command path for MCP-only wiring. By default it uses `--source registry` and writes the platform-correct portable runner (`npx`, `pnpm dlx`, `yarn dlx`, or `bunx`; `cmd /c ...` on native Windows). Pass `--source local` to write the active CLI path plus an absolute `--project`, which is useful for a globally installed CLI but makes the config machine-specific. It preserves unrelated config keys and is idempotent. `fastr setup` remains the full installer for `.fastr/`, `AGENTS.md`, MCP configs, and skills; `fastr hook install` adds lifecycle hooks plus MCP configs for Claude Code, Cursor, Gemini CLI, Copilot CLI, and OpenCode.
385
391
 
386
- `fastr hook install` merges lifecycle hooks for Claude Code, Cursor, Gemini CLI, GitHub Copilot CLI, and OpenCode, and writes the OpenCode context/compaction plugin. Gemini CLI requires strict JSON on hook stdout; Copilot returns `permissionDecision: "ask"` for an active trap because it has no model-facing advisory field for `preToolUse`.
392
+ `fastr hook install` merges lifecycle hooks for Claude Code, Cursor, Gemini CLI, GitHub Copilot CLI, and OpenCode, and writes the OpenCode context/compaction plugin. `fastr hook uninstall` removes exactly what install wrote — the `fastrmemory` MCP entry, the hook commands, the managed OpenCode plugin, and the `AGENTS.md` discipline block — while leaving every user entry in the same files untouched. Both commands are idempotent, accept `--client <ids|all>`, `--project <dir>`, `--no-agents-md`, and `--json`, and are covered by [docs/CLIENT_SUPPORT.md](docs/CLIENT_SUPPORT.md). Gemini CLI requires strict JSON on hook stdout; Copilot returns `permissionDecision: "ask"` for an active trap because it has no model-facing advisory field for `preToolUse`.
387
393
 
388
394
  | Client | Project config | User config | JSON key |
389
395
  | :--- | :--- | :--- | :--- |
@@ -413,7 +419,7 @@ Example POSIX project config generated by `fastr mcp init --client cursor` (Wind
413
419
 
414
420
  VS Code uses `servers` instead of `mcpServers`; OpenCode uses `mcp.servers` with a command array and `"type": "local"`. Existing `opencode.json(c)` settings are preserved, but a JSONC config is reported for manual wiring rather than rewritten. Codex is always printed as a `[mcp_servers.fastrmemory]` TOML block because rewriting a user-owned TOML file safely requires a dedicated parser.
415
421
 
416
- For user-scoped clients, the generated entry includes `--project /absolute/path/to/repo`; this prevents the client's launch directory from selecting the wrong database. `fastr setup` also writes the absolute `node` path and is the recommended path when the client cannot launch package-runner shims. `--source local` is the `mcp init` equivalent for an installed CLI: it writes the active CLI path and an absolute `--project`; use `--source registry` (the default) when the config will be committed or shared. `--source local` ships in `0.5.0`; on published `0.4.0`, use `fastr setup` for an installed-CLI config. On native Windows, `fastr mcp init` automatically emits `"command": "cmd"` with `"/c"` and the runner, so manual `npx.cmd` fixes are not needed.
422
+ For user-scoped clients, the generated entry includes `--project /absolute/path/to/repo`; this prevents the client's launch directory from selecting the wrong database. `fastr setup` also writes the absolute `node` path and is the recommended path when the client cannot launch package-runner shims. `--source local` is the `mcp init` equivalent for an installed CLI: it writes the active CLI path and an absolute `--project`; use `--source registry` (the default) when the config will be committed or shared. `--source local` ships in published `0.5.0`; on `0.4.0`, use `fastr setup` for an installed-CLI config. On native Windows, `fastr mcp init` automatically emits `"command": "cmd"` with `"/c"` and the runner, so manual `npx.cmd` fixes are not needed.
417
423
 
418
424
  `--client all --scope project` covers the six project-scoped clients in the table. `--client all --scope user` covers the eight user-scoped clients; OpenCode and Copilot CLI are project-only, while Codex prints a TOML block for manual insertion. User-scoped entries pin one `--project` database, so use project scope when each developer may open a different checkout.
419
425
 
@@ -423,9 +429,9 @@ For user-scoped clients, the generated entry includes `--project /absolute/path/
423
429
 
424
430
  Built using the official **v2 `@modelcontextprotocol/server`** SDK. The tool list below describes **0.5.0** (tool surface unchanged from 0.4.0); the v0.2.1 release has 4 resources.
425
431
 
426
- ### 41 MCP Tools
432
+ ### 43 MCP Tools
427
433
 
428
- The default **full profile** exposes all 41 tools. For a smaller schema, start the **core profile** with `fastrmemory mcp --profile core` or `FASTR_MCP_PROFILE=core`; it exposes the 12-tool daily loop: `fastr_recall`, `fastr_remember`, `fastr_handoff`, `fastr_trap_recall`, `fastr_trap_log`, `fastr_status`, `fastr_get`, `fastr_timeline`, `fastr_diff`, `fastr_replay`, `fastr_compress`, and `fastr_diagnose`. Resources and prompts are the same in both profiles. Pass `--project /absolute/path/to/repo` when the host starts the server outside the repository, so memory is written to the intended `.fastr/fastr.db`.
434
+ The default **core profile** exposes 12 tools: the daily loop (`fastr_recall`, `fastr_remember`, `fastr_handoff`, `fastr_trap_recall`, `fastr_trap_log`, `fastr_status`, `fastr_get`, `fastr_replay`, `fastr_compress`, `fastr_diagnose`) plus `fastr_tools` for discovery and `fastr_call` for dispatch. Its `tools/list` payload is 8,715 bytes (~2,179 tokens). The **full profile** exposes all 43 tools; start it with `fastrmemory mcp --profile full` or `FASTR_MCP_PROFILE=full`. Every full-profile tool stays reachable from the core profile through `fastr_call`. Resources and prompts are the same in both profiles. Pass `--project /absolute/path/to/repo` when the host starts the server outside the repository, so memory is written to the intended `.fastr/fastr.db`.
429
435
 
430
436
  #### Cognitive Retrieval & Memory Core
431
437
  1. `fastr_recall`: Triple-stream hybrid search (BM25 + Vector + Spreading Activation Graph) with progressive L0–L3 token budgeting and air-gapped offline vector fallback.
@@ -488,6 +494,10 @@ The default **full profile** exposes all 41 tools. For a smaller schema, start t
488
494
  40. `fastr_vision_tag`: Tags screenshots, UI diagrams, and wireframes with OCR and semantic descriptions with 384-dim embeddings.
489
495
  41. `fastr_vision_search`: Hybrid vector and keyword search across stored visual assets for multimodal coding agents.
490
496
 
497
+ #### Tool Discovery & Dispatch
498
+ 42. `fastr_tools`: Lists every tool the server can run, with its JSON input schema, filtered by name or description. Part of the core profile.
499
+ 43. `fastr_call`: Runs any tool from `fastr_tools` by name after validating arguments against that tool's schema. Part of the core profile.
500
+
491
501
  ### 2 MCP Prompt Templates
492
502
 
493
503
  - `pre-edit-check`: Given file paths, instructs the agent to check traps and relevant rules before editing.
@@ -586,7 +596,7 @@ flowchart TD
586
596
 
587
597
  subgraph Protocol["4. Official MCP Protocol"]
588
598
  Budget --> MCPServer["Official MCP v2 Server\n(@modelcontextprotocol/server)"]
589
- MCPServer --> Tools["41 tools • 2 prompts • 5 resources"]
599
+ MCPServer --> Tools["43 tools • 2 prompts • 5 resources"]
590
600
  Tools --> Agent
591
601
  end
592
602
  ```
@@ -601,7 +611,7 @@ Run the comprehensive unit test suite:
601
611
  npm test
602
612
  ```
603
613
 
604
- All **297 tests pass** across **53 test files** on current `main` (`0.5.0`); published `0.4.0` has **293 tests / 53 files**, `0.3.1` has **282 / 52**, and v0.2.1 has **235 / 43**. Coverage includes database schema, WAL locking, offline spooling, bi-temporal supersession, secret scrubbing, two-zone rendering, automated benchmarks, snapshots/rollback, branch merge conflict reports, replay/diff, memory envelopes, confidence tiers and 3-bad dormancy, memory hygiene checks, Memory CI, conflict-aware recall, portable backup manifests and verified restore, local rule import, OpenCode V2, Gemini CLI, and Copilot CLI wiring, git-learner, cognitive blame, commit synthesis, hybrid background daemon, token compression, self-healing doctor, multimodal vision, web dashboard server, pre-merge trap guardian, UI loopback security boundaries, atomic installer configuration safety, and shadcn-style `mcp init` client config merges, including local-source entries.
614
+ All **388 tests pass** across **61 test files** on current `main`; published `0.5.0` has **297 tests / 53 files**, historical `0.4.0` has **293 tests / 53 files**, `0.3.1` has **282 / 52**, and v0.2.1 has **235 / 43**. Coverage includes database schema, WAL locking, offline spooling, bi-temporal supersession, secret scrubbing, two-zone rendering, automated benchmarks, snapshots/rollback, branch merge conflict reports, replay/diff, memory envelopes, confidence tiers and 3-bad dormancy, memory hygiene checks, Memory CI, conflict-aware recall, portable backup manifests and verified restore, local rule import, OpenCode V2, Gemini CLI, and Copilot CLI wiring, git-learner, cognitive blame, commit synthesis, hybrid background daemon, token compression, self-healing doctor, multimodal vision, web dashboard server, pre-merge trap guardian, UI loopback security boundaries, atomic installer configuration safety, and shadcn-style `mcp init` client config merges, including local-source entries.
605
615
 
606
616
  **CI performance gates:** `check:query-plans`, `check:recall-latency`, and `check:install-size` run inside `check:ci`. CI executes them on the canonical Ubuntu/Node 24 job; other matrix jobs set `FASTR_PERF_GATE=0` because timing is runner-sensitive, while functional tests still run on every matrix entry.
607
617
 
package/dist/bin/fastr.js CHANGED
@@ -9,7 +9,8 @@ import { scrubSecrets } from '../src/privacy/scrubber.js';
9
9
  import { runInteractiveSetup } from '../src/installer/setup.js';
10
10
  import { formatBenchmarkMarkdown } from '../src/bench/benchmark.js';
11
11
  import { startUiServer } from '../src/ui/server.js';
12
- import { installAgentHooks } from '../src/installer/hooks.js';
12
+ import { installHookClients, parseHookClients, uninstallHookClients } from '../src/installer/hooks.js';
13
+ import { installStaticModel, removeStaticModel, staticModelStatus } from '../src/search/static-model-install.js';
13
14
  import { formatMcpInitResult, initMcpClients, parseMcpChannel, parseMcpClients, parseMcpProfile, parseMcpRunner, parseMcpScope, parseMcpSource, } from '../src/installer/mcp-init.js';
14
15
  import { learnFromGitHistory } from '../src/learn/git-learner.js';
15
16
  import { exportToObsidianVault } from '../src/export/obsidian.js';
@@ -68,7 +69,7 @@ program
68
69
  const mcpCmd = program
69
70
  .command('mcp')
70
71
  .description('Run FastrMemory as an MCP stdio server')
71
- .option('--profile <profile>', 'Tool surface: full (default) or core (12 tools)')
72
+ .option('--profile <profile>', 'Tool surface: core (default, 12 tools) or full')
72
73
  .option('--project <path>', 'Project root for memory storage (defaults to cwd)')
73
74
  .action(async (options) => {
74
75
  try {
@@ -86,7 +87,7 @@ mcpCmd
86
87
  .option('--scope <scope>', 'project or user', 'project')
87
88
  .option('--channel <channel>', 'latest (auto-update) or pinned (exact version)', 'latest')
88
89
  .option('--runner <runner>', 'npx, pnpm, yarn, or bunx', 'npx')
89
- .option('--profile <profile>', 'Tool surface: full or core', 'full')
90
+ .option('--profile <profile>', 'Tool surface: core (default, 12 tools) or full', 'core')
90
91
  .option('--source <source>', 'registry (portable npx) or local (active CLI)', 'registry')
91
92
  .option('--project <path>', 'Project root for user-scoped configs', process.cwd())
92
93
  .option('--dry-run', 'Print the target files without writing', false)
@@ -743,15 +744,51 @@ program
743
744
  const hookCmd = program.command('hook').description('Autonomous agent lifecycle hook management');
744
745
  hookCmd
745
746
  .command('install')
746
- .description('Install FastrMemory MCP and hooks into Claude Code, Cursor, Gemini CLI, Copilot CLI, OpenCode, and AGENTS.md')
747
- .action(() => {
748
- const ctx = createFastrServerContext();
749
- const res = installAgentHooks(ctx.config.projectRoot);
750
- console.log(`\n=== FastrMemory Autonomous Hook Installation ===`);
751
- for (const d of res.details) {
752
- console.log(`- ${d}`);
747
+ .description('Install FastrMemory MCP and hooks into Claude Code, Cursor, Gemini CLI, Copilot CLI, and OpenCode')
748
+ .option('--client <clients>', 'Comma-separated client ids, or all', 'all')
749
+ .option('--project <path>', 'Project root (defaults to the current directory)')
750
+ .option('--no-agents-md', 'Do not touch AGENTS.md')
751
+ .option('--json', 'Print a machine-readable result', false)
752
+ .action((opts) => {
753
+ const projectRoot = path.resolve(opts.project ?? process.cwd());
754
+ const clients = parseHookClients(opts.client);
755
+ const res = installHookClients(projectRoot, clients, { agentsMd: opts.agentsMd });
756
+ if (opts.json) {
757
+ console.log(JSON.stringify({ projectRoot, clients: res.clients, agentsMdUpdated: res.agentsMdUpdated }, null, 2));
758
+ }
759
+ else {
760
+ console.log(`\n=== FastrMemory Autonomous Hook Installation ===`);
761
+ console.log(`Project: ${projectRoot}`);
762
+ for (const d of res.details)
763
+ console.log(`- ${d}`);
764
+ console.log(`\nAgent autonomous discipline active.\n`);
765
+ }
766
+ if (res.clients.some((client) => client.status === 'error'))
767
+ process.exitCode = 1;
768
+ });
769
+ hookCmd
770
+ .command('uninstall')
771
+ .description('Remove the FastrMemory MCP entries, hooks, OpenCode plugin, and AGENTS.md block this installer added')
772
+ .option('--client <clients>', 'Comma-separated client ids, or all', 'all')
773
+ .option('--project <path>', 'Project root (defaults to the current directory)')
774
+ .option('--no-agents-md', 'Do not touch AGENTS.md')
775
+ .option('--json', 'Print a machine-readable result', false)
776
+ .action((opts) => {
777
+ const projectRoot = path.resolve(opts.project ?? process.cwd());
778
+ const clients = parseHookClients(opts.client);
779
+ const res = uninstallHookClients(projectRoot, clients, { agentsMd: opts.agentsMd });
780
+ if (opts.json) {
781
+ console.log(JSON.stringify({ projectRoot, changed: res.changed, clients: res.clients, agentsMdRemoved: res.agentsMdRemoved }, null, 2));
782
+ }
783
+ else {
784
+ console.log(`\n=== FastrMemory Hook Removal ===`);
785
+ console.log(`Project: ${projectRoot}`);
786
+ for (const d of res.details)
787
+ console.log(`- ${d}`);
788
+ console.log(res.changed ? `\nFastrMemory integration removed.\n` : `\nNothing to remove.\n`);
753
789
  }
754
- console.log(`\nAgent autonomous discipline active.\n`);
790
+ if (res.clients.some((client) => client.status === 'error'))
791
+ process.exitCode = 1;
755
792
  });
756
793
  hookCmd
757
794
  .command('run <event>')
@@ -1033,10 +1070,17 @@ program
1033
1070
  // 18. Diagnose command
1034
1071
  program
1035
1072
  .command('diagnose')
1073
+ .alias('doctor')
1036
1074
  .description('Run deep health check across SQLite, FTS5 indices, file links, and task DAGs')
1037
- .action(() => {
1075
+ .option('--drain-conflicts', 'Drain the deferred conflict queue before reporting', false)
1076
+ .action((opts = {}) => {
1038
1077
  try {
1039
1078
  const ctx = createFastrServerContext();
1079
+ if (opts.drainConflicts) {
1080
+ const drained = healDatabase(ctx.db, ctx.config.projectId, { drainConflicts: true });
1081
+ console.log(`\nDrained ${drained.conflictsDrained ?? 0} queued conflict check(s); recorded ${drained.conflictsCreated ?? 0} conflict(s); ` +
1082
+ `extracted entities for ${drained.entitiesDrained ?? 0} memory(ies).`);
1083
+ }
1040
1084
  const report = diagnoseDatabase(ctx.db, ctx.config.projectId);
1041
1085
  console.log(`\n=== FastrMemory Health Diagnostic ===`);
1042
1086
  console.log(`Status: ${report.healthy ? '✅ HEALTHY' : '⚠️ ISSUES DETECTED'}`);
@@ -1045,6 +1089,8 @@ program
1045
1089
  console.log(`FTS5 Rows: ${report.metrics.ftsRowCount}`);
1046
1090
  console.log(`Links: ${report.metrics.fileLinkCount}`);
1047
1091
  console.log(`Actions: ${report.metrics.actionCount}`);
1092
+ console.log(`Conflicts: ${report.metrics.pendingConflicts} queued`);
1093
+ console.log(`FTS queue: ${report.metrics.pendingFts} pending`);
1048
1094
  console.log(`Mode: ${report.metrics.walMode}`);
1049
1095
  if (report.issues.length > 0) {
1050
1096
  console.log(`\nIssues List:`);
@@ -1115,16 +1161,32 @@ program
1115
1161
  // 19. Heal command
1116
1162
  program
1117
1163
  .command('heal')
1118
- .description('Auto-repair database indices, orphaned file links, and WAL fragmentation')
1164
+ .description('Auto-repair database indices, orphaned file links, WAL fragmentation, and the deferred conflict queue')
1119
1165
  .option('-d, --dry-run', 'Preview repairs without modifying database', false)
1166
+ .option('--drain-conflicts', 'Run every queued deferred conflict check now', false)
1167
+ .option('--conflict-batch-size <n>', 'Conflict queue rows per transaction', '20')
1120
1168
  .action((opts) => {
1121
1169
  try {
1122
1170
  const ctx = createFastrServerContext();
1123
- const res = healDatabase(ctx.db, ctx.config.projectId, { dryRun: opts.dryRun });
1171
+ const batchSize = Number.parseInt(opts.conflictBatchSize, 10);
1172
+ const res = healDatabase(ctx.db, ctx.config.projectId, {
1173
+ dryRun: opts.dryRun,
1174
+ drainConflicts: opts.drainConflicts,
1175
+ conflictBatchSize: Number.isFinite(batchSize) && batchSize > 0 ? batchSize : 20
1176
+ });
1124
1177
  console.log(`\n=== FastrMemory Self-Healing Doctor ===`);
1125
1178
  console.log(`Mode: ${res.dryRun ? '🔍 DRY RUN' : '⚡ LIVE REPAIR'}`);
1126
1179
  console.log(`Fixed: ${res.fixedCount} issue(s)`);
1127
1180
  console.log(`Remaining: ${res.remainingIssues} issue(s)`);
1181
+ if (res.conflictsDrained !== undefined) {
1182
+ console.log(`Conflicts: drained ${res.conflictsDrained} queued check(s), recorded ${res.conflictsCreated ?? 0}`);
1183
+ }
1184
+ if (res.entitiesDrained !== undefined) {
1185
+ console.log(`Entities: extracted for ${res.entitiesDrained} queued memory(ies)`);
1186
+ }
1187
+ if (res.ftsDrained !== undefined) {
1188
+ console.log(`FTS index: ${res.ftsDrained} queued row(s) indexed`);
1189
+ }
1128
1190
  if (res.actionsTaken.length > 0) {
1129
1191
  console.log(`\nActions:`);
1130
1192
  for (const a of res.actionsTaken) {
@@ -1232,5 +1294,51 @@ program
1232
1294
  process.exit(1);
1233
1295
  }
1234
1296
  });
1297
+ // 22. Optional static semantic model (30 MB, never downloaded implicitly)
1298
+ const modelCmd = program
1299
+ .command('model')
1300
+ .description('Manage the optional static semantic model (30 MB, opt-in)');
1301
+ modelCmd
1302
+ .command('status')
1303
+ .description('Show whether the static semantic model is installed')
1304
+ .action(() => {
1305
+ const status = staticModelStatus();
1306
+ console.log(`Static model: ${status.installed ? 'installed' : 'not installed'}`);
1307
+ console.log(`Directory: ${status.dir}`);
1308
+ if (status.installed) {
1309
+ console.log(`Size: ${(status.bytes / 1_000_000).toFixed(1)} MB`);
1310
+ console.log(`Vector mode: semantic (model id 3, 256-dim)`);
1311
+ }
1312
+ else {
1313
+ console.log(`Missing: ${status.missing.join(', ')}`);
1314
+ console.log(`Install with: fastr model install`);
1315
+ }
1316
+ });
1317
+ modelCmd
1318
+ .command('install')
1319
+ .description('Download and verify the static semantic model')
1320
+ .option('-f, --force', 'Re-download even when a verified copy exists', false)
1321
+ .action(async (opts) => {
1322
+ try {
1323
+ const result = await installStaticModel({
1324
+ force: opts.force,
1325
+ onProgress: (message) => console.log(message)
1326
+ });
1327
+ console.log(result.alreadyPresent
1328
+ ? `\nModel already present in ${result.dir}`
1329
+ : `\nInstalled to ${result.dir}`);
1330
+ console.log('Recall now uses the semantic tier automatically when vectors exist.');
1331
+ }
1332
+ catch (err) {
1333
+ console.error(`Model install failed: ${err.message}`);
1334
+ process.exit(1);
1335
+ }
1336
+ });
1337
+ modelCmd
1338
+ .command('remove')
1339
+ .description('Delete the installed static semantic model')
1340
+ .action(() => {
1341
+ console.log(removeStaticModel() ? 'Static model removed.' : 'Static model is not installed.');
1342
+ });
1235
1343
  program.parse(process.argv);
1236
1344
  //# sourceMappingURL=fastr.js.map