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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +2 -2
- package/.cursor/skills/skills.json +1 -1
- package/README.md +40 -30
- package/dist/bin/fastr.js +122 -14
- package/dist/bin/fastr.js.map +1 -1
- package/dist/src/bench/harness.d.ts.map +1 -1
- package/dist/src/bench/harness.js +4 -0
- package/dist/src/bench/harness.js.map +1 -1
- package/dist/src/bench/marker-corpus.d.ts +98 -0
- package/dist/src/bench/marker-corpus.d.ts.map +1 -0
- package/dist/src/bench/marker-corpus.js +306 -0
- package/dist/src/bench/marker-corpus.js.map +1 -0
- package/dist/src/bench/mcp-stdio.d.ts +55 -0
- package/dist/src/bench/mcp-stdio.d.ts.map +1 -0
- package/dist/src/bench/mcp-stdio.js +146 -0
- package/dist/src/bench/mcp-stdio.js.map +1 -0
- package/dist/src/bench/public-datasets.d.ts +2 -0
- package/dist/src/bench/public-datasets.d.ts.map +1 -1
- package/dist/src/bench/public-datasets.js +2 -1
- package/dist/src/bench/public-datasets.js.map +1 -1
- package/dist/src/bench/public-harness.d.ts +14 -0
- package/dist/src/bench/public-harness.d.ts.map +1 -1
- package/dist/src/bench/public-harness.js +83 -8
- package/dist/src/bench/public-harness.js.map +1 -1
- package/dist/src/bench/public-pins.js +5 -5
- package/dist/src/bench/public-pins.js.map +1 -1
- package/dist/src/bench/split.d.ts +33 -0
- package/dist/src/bench/split.d.ts.map +1 -0
- package/dist/src/bench/split.js +56 -0
- package/dist/src/bench/split.js.map +1 -0
- package/dist/src/bench/stats.d.ts +40 -0
- package/dist/src/bench/stats.d.ts.map +1 -0
- package/dist/src/bench/stats.js +99 -0
- package/dist/src/bench/stats.js.map +1 -0
- package/dist/src/bench/vs-engines.d.ts +51 -0
- package/dist/src/bench/vs-engines.d.ts.map +1 -0
- package/dist/src/bench/vs-engines.js +121 -0
- package/dist/src/bench/vs-engines.js.map +1 -0
- package/dist/src/config.d.ts +33 -0
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +84 -1
- package/dist/src/config.js.map +1 -1
- package/dist/src/db/doctor.d.ts +8 -0
- package/dist/src/db/doctor.d.ts.map +1 -1
- package/dist/src/db/doctor.js +65 -1
- package/dist/src/db/doctor.js.map +1 -1
- package/dist/src/db/fts-queue.d.ts +35 -0
- package/dist/src/db/fts-queue.d.ts.map +1 -0
- package/dist/src/db/fts-queue.js +78 -0
- package/dist/src/db/fts-queue.js.map +1 -0
- package/dist/src/db/repository.d.ts +63 -1
- package/dist/src/db/repository.d.ts.map +1 -1
- package/dist/src/db/repository.js +244 -50
- package/dist/src/db/repository.js.map +1 -1
- package/dist/src/db/schema.d.ts +1 -1
- package/dist/src/db/schema.d.ts.map +1 -1
- package/dist/src/db/schema.js +63 -2
- package/dist/src/db/schema.js.map +1 -1
- package/dist/src/installer/copilot.d.ts +21 -0
- package/dist/src/installer/copilot.d.ts.map +1 -1
- package/dist/src/installer/copilot.js +72 -1
- package/dist/src/installer/copilot.js.map +1 -1
- package/dist/src/installer/gemini.d.ts +13 -0
- package/dist/src/installer/gemini.d.ts.map +1 -1
- package/dist/src/installer/gemini.js +64 -1
- package/dist/src/installer/gemini.js.map +1 -1
- package/dist/src/installer/hooks.d.ts +42 -5
- package/dist/src/installer/hooks.d.ts.map +1 -1
- package/dist/src/installer/hooks.js +270 -62
- package/dist/src/installer/hooks.js.map +1 -1
- package/dist/src/installer/json-config.d.ts +25 -1
- package/dist/src/installer/json-config.d.ts.map +1 -1
- package/dist/src/installer/json-config.js +95 -2
- package/dist/src/installer/json-config.js.map +1 -1
- package/dist/src/installer/mcp-init.d.ts.map +1 -1
- package/dist/src/installer/mcp-init.js +5 -6
- package/dist/src/installer/mcp-init.js.map +1 -1
- package/dist/src/installer/opencode.d.ts +18 -0
- package/dist/src/installer/opencode.d.ts.map +1 -1
- package/dist/src/installer/opencode.js +81 -1
- package/dist/src/installer/opencode.js.map +1 -1
- package/dist/src/installer/setup.d.ts +7 -0
- package/dist/src/installer/setup.d.ts.map +1 -1
- package/dist/src/installer/setup.js +32 -0
- package/dist/src/installer/setup.js.map +1 -1
- package/dist/src/mcp/profiles.d.ts +9 -6
- package/dist/src/mcp/profiles.d.ts.map +1 -1
- package/dist/src/mcp/profiles.js +12 -9
- package/dist/src/mcp/profiles.js.map +1 -1
- package/dist/src/mcp/server.d.ts +1 -1
- package/dist/src/mcp/server.d.ts.map +1 -1
- package/dist/src/mcp/server.js +80 -0
- package/dist/src/mcp/server.js.map +1 -1
- package/dist/src/search/aggregate.d.ts +24 -0
- package/dist/src/search/aggregate.d.ts.map +1 -0
- package/dist/src/search/aggregate.js +59 -0
- package/dist/src/search/aggregate.js.map +1 -0
- package/dist/src/search/backfill.d.ts.map +1 -1
- package/dist/src/search/backfill.js +7 -2
- package/dist/src/search/backfill.js.map +1 -1
- package/dist/src/search/budget.d.ts +2 -0
- package/dist/src/search/budget.d.ts.map +1 -1
- package/dist/src/search/budget.js.map +1 -1
- package/dist/src/search/embeddings.d.ts +35 -2
- package/dist/src/search/embeddings.d.ts.map +1 -1
- package/dist/src/search/embeddings.js +128 -5
- package/dist/src/search/embeddings.js.map +1 -1
- package/dist/src/search/hybrid-rrf.d.ts +45 -0
- package/dist/src/search/hybrid-rrf.d.ts.map +1 -1
- package/dist/src/search/hybrid-rrf.js +212 -56
- package/dist/src/search/hybrid-rrf.js.map +1 -1
- package/dist/src/search/static-model-install.d.ts +43 -0
- package/dist/src/search/static-model-install.d.ts.map +1 -0
- package/dist/src/search/static-model-install.js +112 -0
- package/dist/src/search/static-model-install.js.map +1 -0
- package/dist/src/search/static-model.d.ts +63 -0
- package/dist/src/search/static-model.d.ts.map +1 -0
- package/dist/src/search/static-model.js +244 -0
- package/dist/src/search/static-model.js.map +1 -0
- package/dist/src/search/temporal.d.ts +32 -0
- package/dist/src/search/temporal.d.ts.map +1 -0
- package/dist/src/search/temporal.js +164 -0
- package/dist/src/search/temporal.js.map +1 -0
- package/llms-install.md +3 -3
- package/package.json +5 -1
- package/server.json +1 -1
- 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.
|
|
11
|
+
"version": "0.6.0"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
14
14
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fastrmemory",
|
|
3
|
-
"version": "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.
|
|
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.
|
|
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)
|
|
11
11
|
[](https://nodejs.org)
|
|
12
12
|
[](https://modelcontextprotocol.io)
|
|
13
|
-
[](tests/)
|
|
14
14
|
[](#-one-click-agent-mcp-configuration)
|
|
15
15
|
[](#-architecture)
|
|
16
16
|
|
|
17
|
-
> **Status (2026-10-23):** **`fastrmemory@0.
|
|
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> •
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
|
|
40
40
|
| Claim | Current result | Evidence |
|
|
41
41
|
|---|---|---|
|
|
42
|
-
| Install path | Published `fastrmemory@0.
|
|
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 | `
|
|
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
|
|
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.
|
|
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.
|
|
117
|
+
npx -y fastrmemory@0.5.0 setup
|
|
118
118
|
|
|
119
119
|
# Or launch the local Web UI:
|
|
120
|
-
npx -y fastrmemory@0.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
141
|
+
npx -y fastrmemory@0.5.0 --version
|
|
142
142
|
```
|
|
143
143
|
|
|
144
|
-
`0.
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
224
|
-
npx --yes github:atifjubaer/fastrmemory#v0.
|
|
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.
|
|
231
|
-
https://github.com/atifjubaer/fastrmemory/releases/download/v0.
|
|
232
|
-
npm install -g ./fastrmemory-0.
|
|
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.
|
|
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.
|
|
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
|
|
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
|
-
###
|
|
432
|
+
### 43 MCP Tools
|
|
427
433
|
|
|
428
|
-
The default **
|
|
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["
|
|
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 **
|
|
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 {
|
|
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:
|
|
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:
|
|
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,
|
|
747
|
-
.
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
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
|
-
|
|
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
|
-
.
|
|
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
|
|
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
|
|
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
|