linksee-memory 0.11.0 → 0.11.2

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
@@ -6,7 +6,7 @@
6
6
  >
7
7
  > Underneath sits a local-first cross-LLM memory MCP — one SQLite file that **Claude Code, Cursor, Windsurf, OpenAI Codex, and Gemini CLI** all read from. Not just "what happened" but **WHY**: 6-layer structured memory with precision recall and an AST-aware diff cache (50–99% token savings on re-reads).
8
8
  >
9
- > `npx linksee-memory-setup` — one command, done.
9
+ > `npx -y linksee-memory setup` — one command, done.
10
10
 
11
11
  [![npm](https://img.shields.io/npm/v/linksee-memory.svg)](https://www.npmjs.com/package/linksee-memory)
12
12
  [![license](https://img.shields.io/npm/l/linksee-memory.svg)](./LICENSE)
@@ -14,17 +14,34 @@
14
14
  [![glama-score](https://glama.ai/mcp/servers/michielinksee/linksee-memory/badges/score.svg)](https://glama.ai/mcp/servers/michielinksee/linksee-memory)
15
15
 
16
16
  🌐 **Landing page**: [linksee-site.vercel.app](https://linksee-site.vercel.app) (includes non-developer onboarding for Claude Desktop / Cursor / Claude Code / OpenAI Codex / Gemini CLI)
17
+ 📖 **Docs**: [docs.linksee.app](https://docs.linksee.app) — full reference: the product map & drift, install, and all 11 tools
17
18
 
18
19
  ## 🪄 Three spells to remember
19
20
 
20
21
  | Say this | What happens |
21
22
  |---|---|
22
- | **"use linksee"** ・「リンクシーして」 | Recalls relevant memories before acting |
23
- | **"linksee this"** ・「これ覚えて」 | Saves the decision / lesson right now |
24
- | **"what's drifting?"** ・「ズレてない?」 | Reconciles reality against your locked decisions |
23
+ | **"use linksee"** | Recalls relevant memories before acting |
24
+ | **"linksee this"** | Saves the decision / lesson right now |
25
+ | **"what's drifting?"** | Reconciles reality against your locked decisions |
25
26
 
26
27
  > Make it automatic: add **"Use Linksee Memory"** to your system prompt / `CLAUDE.md`.
27
28
 
29
+ ## 🗺️ Not just memory — a product map
30
+
31
+ Memory is the entry point. Tie it to a `map.yaml` of how your product fits together, and the `linksee-memory map` CLI catches drift with file:line evidence:
32
+
33
+ ![linksee-memory-map catching doc/code drift in 30 seconds](demo/where-demo.gif)
34
+
35
+ **The 30-second demo above:** the README says `--export`. The code doesn't. Linksee catches it — and shows what else a change would touch.
36
+
37
+ ```bash
38
+ npx -y linksee-memory map where README.md # this file belongs to the README node — and what it touches
39
+ npx -y linksee-memory map explain readme # README promises --export; the code doesn't implement it — drift, with evidence
40
+ npx -y linksee-memory map affects readme # changing the README also touches docs, the CLI help, and the npm listing
41
+ ```
42
+
43
+ → see [The Map](#the-map) for the full flow.
44
+
28
45
  ## 📣 As featured on
29
46
 
30
47
  - **Zenn**: [あなたの Claude Code、 実は前回のセッションを完全に忘れている](https://zenn.dev/kanseilink/articles/linksee-memory-claude-code-recall-20260508) — 73 ♡ on Zenn, **165+ users on Hatena Bookmark**, picked up by tech blogs + YouTube shorts (May 2026)
@@ -121,7 +138,7 @@ Anchors are classified into four species with different display formats:
121
138
 
122
139
  <a id="the-map"></a>
123
140
 
124
- ## 🗺️ The Map — `linksee-memory-map`
141
+ ## 🗺️ The Map — `linksee-memory map`
125
142
 
126
143
  Drift detection (above) checks individual anchors. The **Map** lifts it to the whole product: a `map.yaml` describing how value reaches your user (`discover → understand → try → adopt → retain → monetize → expand`), with typed dependencies between the pieces — README, npm listing, onboarding, the engine that powers them. The reconciler checks that map against your real code, and the CLI answers the question an engineer actually has:
127
144
 
@@ -130,7 +147,7 @@ Drift detection (above) checks individual anchors. The **Map** lifts it to the w
130
147
  **1. Where am I?** — locate a file (or, with no argument, infer from your recent edits):
131
148
 
132
149
  ```
133
- $ linksee-memory-map where README.md
150
+ $ npx -y linksee-memory map where README.md
134
151
  "README.md" belongs to this Map node:
135
152
 
136
153
  readme [understand] convergence
@@ -145,7 +162,7 @@ The blast radius is **graded** — `must fix together` vs `should align` vs `fyi
145
162
  **2. Why is it in this state?** — the diagnosis, with file:line evidence:
146
163
 
147
164
  ```
148
- $ linksee-memory-map explain readme
165
+ $ npx -y linksee-memory map explain readme
149
166
 
150
167
  STATUS
151
168
  declared: healthy (active)
@@ -159,7 +176,7 @@ EVIDENCE
159
176
 
160
177
  Declared state and the reality verdict are shown **separately** — a hand-declared `suspect` the scanner refutes reads as *"declared suspect, refuted by reality (→ convergence)"*, not a confusing mix.
161
178
 
162
- **3. Whole-project triage:** `linksee-memory-map status` — a health %, what is *fixable now in code* vs *external checks*, and any deferral with no expiry (so "accounted-for" can't quietly become a drift graveyard).
179
+ **3. Whole-project triage:** `npx -y linksee-memory map status` — a health %, what is *fixable now in code* vs *external checks*, and any deferral with no expiry (so "accounted-for" can't quietly become a drift graveyard).
163
180
 
164
181
  **How it works**
165
182
  - **`map.yaml`** (repo root) is the desired-state source of truth: a journey spine × surface/implementation layers × typed edges (`must-stay-consistent-with` / `should-align-with` / `realizes`).
@@ -187,7 +204,7 @@ It is **fail-open by construction**: any parse / DB / logic error surfaces nothi
187
204
 
188
205
  ### Enable it
189
206
 
190
- `npx linksee-memory-setup` offers to wire this into your **project's** `.claude/settings.json` (Step 4). To do it by hand, drop this block into `.claude/settings.json` at your project root — it points at the globally-installed `linksee-memory-guard` bin, so no build step is needed:
207
+ `npx -y linksee-memory setup` offers to wire this into your **project's** `.claude/settings.json` (Step 4). To do it by hand, drop this block into `.claude/settings.json` at your project root — it points at the globally-installed `linksee-memory-guard` bin, so no build step is needed:
191
208
 
192
209
  ```json
193
210
  {
@@ -196,7 +213,7 @@ It is **fail-open by construction**: any parse / DB / logic error surfaces nothi
196
213
  {
197
214
  "matcher": "startup|resume|compact",
198
215
  "hooks": [
199
- { "type": "command", "command": "npx -y linksee-memory-guard", "timeout": 15 }
216
+ { "type": "command", "command": "npx -y linksee-memory guard", "timeout": 15 }
200
217
  ]
201
218
  }
202
219
  ],
@@ -204,7 +221,7 @@ It is **fail-open by construction**: any parse / DB / logic error surfaces nothi
204
221
  {
205
222
  "matcher": "Edit|Write|Bash",
206
223
  "hooks": [
207
- { "type": "command", "command": "npx -y linksee-memory-guard", "timeout": 8 }
224
+ { "type": "command", "command": "npx -y linksee-memory guard", "timeout": 8 }
208
225
  ]
209
226
  }
210
227
  ]
@@ -214,7 +231,7 @@ It is **fail-open by construction**: any parse / DB / logic error surfaces nothi
214
231
 
215
232
  It's **project-scoped on purpose** — the guard enforces *this* repo's decisions, and you opt in per project rather than letting it deny tool calls everywhere (the Stop hook from setup, by contrast, is user-global). Declare what it should watch with `declare_anchor(...)`; set `card_policy.gate_mode:'hard'` on an anchor to make a contradiction **block** instead of just warn (the soft default only re-injects). Anchors that are stale (`at_risk`), superseded, or card-disabled never gate.
216
233
 
217
- > Developing linksee-memory itself? The repo dogfoods the guard via a (gitignored) `.claude/settings.json` that points at the local build (`node ${CLAUDE_PROJECT_DIR}/dist/bin/guard-hook.js`) so it runs against your uncommitted changes. End-user projects should use the published `npx -y linksee-memory-guard` form above.
234
+ > Developing linksee-memory itself? The repo dogfoods the guard via a (gitignored) `.claude/settings.json` that points at the local build (`node ${CLAUDE_PROJECT_DIR}/dist/bin/guard-hook.js`) so it runs against your uncommitted changes. End-user projects should use the published `npx -y linksee-memory guard` form above.
218
235
 
219
236
  ---
220
237
 
@@ -270,7 +287,7 @@ Every memory is tagged with **exactly one layer**. `caveat`-layer entries are pr
270
287
  ## Quick Start — One Command
271
288
 
272
289
  ```bash
273
- npx linksee-memory-setup
290
+ npx -y linksee-memory setup
274
291
  ```
275
292
 
276
293
  This does everything:
@@ -297,7 +314,7 @@ Tools appear as `mcp__linksee__remember`, `mcp__linksee__recall`, `mcp__linksee_
297
314
  **Install the skill (auto-invocation):**
298
315
 
299
316
  ```bash
300
- npx -y linksee-memory-install-skill
317
+ npx -y linksee-memory install-skill
301
318
  ```
302
319
 
303
320
  Copies `SKILL.md` to `~/.claude/skills/linksee-memory/`. Agent auto-fires on phrases like "前に…", "また同じエラー", "覚えておいて", new task starts, file edits, etc.
@@ -313,7 +330,7 @@ Add to `~/.claude/settings.json`:
313
330
  {
314
331
  "matcher": "",
315
332
  "hooks": [
316
- { "type": "command", "command": "npx -y linksee-memory-sync" }
333
+ { "type": "command", "command": "npx -y linksee-memory sync" }
317
334
  ]
318
335
  }
319
336
  ]
@@ -371,20 +388,15 @@ Add to `~/.codeium/windsurf/mcp_config.json`:
371
388
  <summary><strong>OpenAI Codex CLI</strong></summary>
372
389
 
373
390
  ```bash
374
- codex --mcp-server "npx -y linksee-memory"
391
+ codex mcp add linksee -- npx -y linksee-memory
375
392
  ```
376
393
 
377
- Or add to `~/.codex/config.json`:
394
+ Or add to `~/.codex/config.toml`:
378
395
 
379
- ```json
380
- {
381
- "mcpServers": {
382
- "linksee": {
383
- "command": "npx",
384
- "args": ["-y", "linksee-memory"]
385
- }
386
- }
387
- }
396
+ ```toml
397
+ [mcp_servers.linksee]
398
+ command = "npx"
399
+ args = ["-y", "linksee-memory"]
388
400
  ```
389
401
 
390
402
  </details>
@@ -413,6 +425,23 @@ All editors share the same `~/.linksee-memory/memory.db`. A decision made in Cla
413
425
 
414
426
  Default: `~/.linksee-memory/memory.db`. Override with `LINKSEE_MEMORY_DIR` env var.
415
427
 
428
+ ### Uninstall
429
+
430
+ ```bash
431
+ # 1. Remove the MCP server registration
432
+ claude mcp remove linksee
433
+
434
+ # 2. Remove the hooks from settings.json (edit the file, delete the linksee entries):
435
+ # ~/.claude/settings.json → the Stop hook running "npx -y linksee-memory sync"
436
+ # <project>/.claude/settings.json → the SessionStart/PreToolUse hooks running "npx -y linksee-memory guard"
437
+
438
+ # 3. Remove the installed skill and all local memory (optional)
439
+ rm -rf ~/.claude/skills/linksee-memory
440
+ rm -rf ~/.linksee-memory # deletes all stored memory — nothing is kept anywhere else
441
+ ```
442
+
443
+ Nothing ever leaves your machine, so step 3 fully erases everything Linksee stored.
444
+
416
445
  ## What's new in v0.9
417
446
 
418
447
  | Feature | Detail |
@@ -447,7 +476,7 @@ Default: `~/.linksee-memory/memory.db`. Override with `LINKSEE_MEMORY_DIR` env v
447
476
 
448
477
  | Feature | Detail |
449
478
  |---|---|
450
- | **One-command setup** | `npx linksee-memory-setup` — registers MCP server, installs skill, configures auto-capture hook. One command instead of three. |
479
+ | **One-command setup** | `npx -y linksee-memory setup` — registers MCP server, installs skill, configures auto-capture hook. One command instead of three. |
451
480
  | **Structured memory v2** | 3-axis classification (altitude × type × state) for every memory. Auto-extraction from sessions produces machine-scannable JSON, not raw chat dumps. |
452
481
  | **Precision recall guide** | SKILL.md now teaches agents HOW to write effective queries, WHEN to recall vs skip, and WHEN to proactively surface caveats before risky actions. |
453
482
  | **Five MCP Blocks** | Tools + Resources + Prompts + Sampling + Roots + Elicitation. Most MCP servers expose only Tools; linksee-memory implements all five primitives. |
@@ -488,13 +517,13 @@ Previous versions exposed 3 tools — v0.8.0 added 4 drift tools that let agents
488
517
 
489
518
  | Command | Purpose |
490
519
  |---|---|
491
- | `npx linksee-memory-setup` | One-command setup: MCP server + skill + Stop hook, then offers to wire the re-injection guard into this project. Idempotent — skips what's already done. |
520
+ | `npx -y linksee-memory setup` | One-command setup: MCP server + skill + Stop hook, then offers to wire the re-injection guard into this project. Idempotent — skips what's already done. |
492
521
  | `npx linksee-memory` | MCP server (stdio) |
493
- | `npx linksee-memory-sync` | Claude Code Stop-hook entry point |
494
- | `npx linksee-memory-guard` | Re-injection guard hook: `PreToolUse` gate (`Edit`/`Write`/`Bash`) + `SessionStart` boot digest. Wired per-project (see [Re-injection Guard](#reinjection-guard)); fail-open. |
495
- | `npx linksee-memory-import` | Batch-import Claude Code session JSONL history |
496
- | `npx linksee-memory-install-skill` | Install the Claude Code Skill that teaches the agent when to call recall/remember/read_smart |
497
- | `npx linksee-memory-stats` | Summary of the local DB (entity count / layer breakdown / top entities / top edited files). Add `--json` for machine-readable output. |
522
+ | `npx -y linksee-memory sync` | Claude Code Stop-hook entry point |
523
+ | `npx -y linksee-memory guard` | Re-injection guard hook: `PreToolUse` gate (`Edit`/`Write`/`Bash`) + `SessionStart` boot digest. Wired per-project (see [Re-injection Guard](#reinjection-guard)); fail-open. |
524
+ | `npx -y linksee-memory import` | Batch-import Claude Code session JSONL history |
525
+ | `npx -y linksee-memory install-skill` | Install the Claude Code Skill that teaches the agent when to call recall/remember/read_smart |
526
+ | `npx -y linksee-memory stats` | Summary of the local DB (entity count / layer breakdown / top entities / top edited files). Add `--json` for machine-readable output. |
498
527
 
499
528
  ## The 6 memory layers
500
529
 
@@ -544,7 +573,7 @@ The conversation↔file linkage is the key. Every file edit captured by the Stop
544
573
  - ✅ Five MCP Blocks (Tools + Resources + Prompts + Sampling + Roots + Elicitation)
545
574
  - ✅ Stop-hook auto-capture for Claude Code
546
575
  - ✅ JP/EN trigram FTS5
547
- - ✅ One-command setup (`npx linksee-memory-setup`)
576
+ - ✅ One-command setup (`npx -y linksee-memory setup`)
548
577
  - ✅ Structured memory v2 (3-axis classification: altitude × type × state)
549
578
  - ✅ Cross-LLM: Claude Code, Cursor, Windsurf, OpenAI Codex, Gemini CLI
550
579
  - ✅ Landing page ([linksee-site.vercel.app](https://linksee-site.vercel.app))
@@ -621,7 +650,7 @@ No account, no credit card, no API key. Just install and use.
621
650
  ```bash
622
651
  ls ~/.claude/skills/linksee-memory/SKILL.md
623
652
  ```
624
- If absent, run `npx -y linksee-memory-install-skill`.
653
+ If absent, run `npx -y linksee-memory install-skill`.
625
654
  2. Restart Claude Code. Skills are indexed on session start.
626
655
  3. Check that the MCP is registered under the name `linksee` (the skill expects `mcp__linksee__*` tool names):
627
656
  ```bash
@@ -636,9 +665,9 @@ No account, no credit card, no API key. Just install and use.
636
665
  1. Check the hook log: `cat ~/.linksee-memory/hook.log`
637
666
  2. Run a manual test:
638
667
  ```bash
639
- echo '{"session_id":"test","transcript_path":"/path/to/some.jsonl"}' | npx linksee-memory-sync
668
+ echo '{"session_id":"test","transcript_path":"/path/to/some.jsonl"}' | npx -y linksee-memory sync
640
669
  ```
641
- 3. Make sure the `Stop` hook in `~/.claude/settings.json` points to `npx -y linksee-memory-sync` (not the old `-import`).
670
+ 3. Make sure the `Stop` hook in `~/.claude/settings.json` points to `npx -y linksee-memory sync` (not the old `-import`).
642
671
  </details>
643
672
 
644
673
  <details>
@@ -647,7 +676,7 @@ No account, no credit card, no API key. Just install and use.
647
676
  v0.0.6+ fixed the entity detection bug that collapsed all memories into the session's starting cwd. To re-index existing history with correct project attribution, run:
648
677
 
649
678
  ```bash
650
- npx linksee-memory-import --all
679
+ npx -y linksee-memory import --all
651
680
  ```
652
681
 
653
682
  The importer is idempotent (wipes existing session data before re-inserting). Typical runtime: a few minutes for hundreds of sessions. Expect a dramatic improvement in `recall` precision afterward.
@@ -775,12 +804,23 @@ After install, in a new Claude session ask: *"Can you remember that I prefer Typ
775
804
 
776
805
  ## Changelog
777
806
 
778
- ### v0.11.0The Map: `where_am_i` + `linksee-memory-map` (2026-06-15)
807
+ ### v0.11.2More cold-start hardening (2026-06-16)
808
+
809
+ - **`stats` works on a fresh database** instead of crashing with `no such table` — it ensures the schema exists first (it may be the first command a new user runs).
810
+ - **`map --help`** prints usage instead of trying to import a map.
811
+
812
+ ### v0.11.1 — Cold-start fixes (2026-06-16)
813
+
814
+ - **Run any CLI through the package name:** `npx -y linksee-memory setup` (and `map`, `sync`, `guard`, `stats`, `import`, `install-skill`). A fresh user couldn't reach the standalone bins (`linksee-memory-setup`, …) via `npx` — npx resolves package names, not sibling bin names — so the one-command install 404'd. The main bin now dispatches subcommands; the standalone bins remain as aliases.
815
+ - **`map` exits gracefully** with a next-step message when there's no `map.yaml` yet (was a raw stack trace — the exact state of a first-time user).
816
+ - **serverInfo** now reports the real package version (was pinned to an old string).
817
+
818
+ ### v0.11.0 — The Map: `where_am_i` + `linksee-memory map` (2026-06-15)
779
819
 
780
820
  **Memory is the entry point; the product map is the new surface.** Drift detection grows up from individual anchors into a whole-product map you navigate from the CLI.
781
821
 
782
822
  - **`where_am_i`** (11th MCP tool) — locate the current topic/file on the Current Truth Map and get its blast radius. Call it with no args to auto-locate from your recent edits.
783
- - **`linksee-memory-map`** CLI — `where` · `affects` · `explain` · `status` · `next` · `reconcile` · `inspect --json` · `blueprint`. A `map.yaml` (git source of truth) describes how value reaches your user; the reconciler checks it against your code with file:line evidence. Bilingual: add `--lang ja`.
823
+ - **`linksee-memory map`** CLI — `where` · `affects` · `explain` · `status` · `next` · `reconcile` · `inspect --json` · `blueprint`. A `map.yaml` (git source of truth) describes how value reaches your user; the reconciler checks it against your code with file:line evidence. Bilingual: add `--lang ja`.
784
824
  - Graded blast radius (`must fix together` / `should align` / `fyi`), declared-vs-reality verdicts, and an anti-graveyard guard for accounted-for drift.
785
825
  - Per-project keys so the Map handles many projects at once.
786
826
 
@@ -884,7 +924,7 @@ Based on one week of dogfooding, here's what changed:
884
924
  **New tools**
885
925
  - `update_memory` — atomic edit with preserved `memory_id`. Solves the "forget+remember breaks session_file_edits links" bug.
886
926
  - `list_entities` — fast "what do I know about?" primitive for session init. Supports `kind`/`min_memories` filters and returns layer breakdown.
887
- - `npx linksee-memory-stats` — local DB summary CLI.
927
+ - `npx -y linksee-memory stats` — local DB summary CLI.
888
928
 
889
929
  **`recall` enhancements**
890
930
  - `match_reasons` array on each memory: e.g. `["content_match_fts", "heat:hot", "pinned"]`.
@@ -15,6 +15,7 @@
15
15
  // linksee-memory-map blueprint # stage×node board (colors reflect the live verdict)
16
16
  // linksee-memory-map [--file map.yaml] [--root <repo>]
17
17
  import { join } from 'node:path';
18
+ import { existsSync } from 'node:fs';
18
19
  import { openDb, runMigrations } from '../db/migrate.js';
19
20
  import { parseMapFile, importMap } from '../lib/map-import.js';
20
21
  import { blastRadius, getSuspects, getBlueprint, getNode, getProjectMeta, whereAmI } from '../lib/map-view.js';
@@ -38,8 +39,38 @@ for (let i = 0; i < argv.length; i++) {
38
39
  const sub = positionals[0] ?? 'import';
39
40
  const arg1 = positionals[1]; // the node-id / file / topic for explain|blast|affects|where
40
41
  const mapPath = flagValue(argv, 'file', join(process.cwd(), 'map.yaml'));
42
+ if (argv.includes('--help') || argv.includes('-h') || sub === 'help') {
43
+ process.stdout.write(`linksee-memory map — navigate your product map (map.yaml) and catch drift\n\n` +
44
+ `Usage: npx -y linksee-memory map <command> [args]\n\n` +
45
+ ` where [<file>] where am I? (no arg = infer from recent edits) → node + what it affects\n` +
46
+ ` explain <node> why this status? — declared vs reality + file:line evidence + fix\n` +
47
+ ` affects <node> what to change together if you touch this node\n` +
48
+ ` status whole-project health % + what needs attention\n` +
49
+ ` next the prioritized next fix candidate(s)\n` +
50
+ ` reconcile re-check the map against the real code/files\n` +
51
+ ` inspect --json machine-readable dump (CI / tooling)\n` +
52
+ ` blueprint stage x node board (colors = live verdict)\n\n` +
53
+ `Flags: --file <map.yaml> --root <repo> --lang ja\n`);
54
+ process.exit(0);
55
+ }
41
56
  const db = openDb();
42
57
  runMigrations(db);
58
+ // Graceful exit when there's no map yet (the cold-user state) — never a raw stack trace.
59
+ if (!existsSync(mapPath)) {
60
+ const ja = flagValue(argv, 'lang', 'en') === 'ja';
61
+ process.stderr.write(ja
62
+ ? `map.yaml が見つかりません(探した場所: ${mapPath})\n\n` +
63
+ `プロダクトMapは手書き(またはスキャン生成)の map.yaml で、git が正本です。\n` +
64
+ `リポジトリのルートに作成してから、もう一度実行してください:\n` +
65
+ ` npx -y linksee-memory map status\n\n` +
66
+ `書式と例: https://docs.linksee.app/concepts/product-map\n`
67
+ : `No map.yaml found (looked in: ${mapPath})\n\n` +
68
+ `The product map is a map.yaml you hand-write (or scan-generate); git is the source of truth.\n` +
69
+ `Create one in your repo root, then run:\n` +
70
+ ` npx -y linksee-memory map status\n\n` +
71
+ `Format & examples: https://docs.linksee.app/concepts/product-map\n`);
72
+ process.exit(1);
73
+ }
43
74
  const map = parseMapFile(mapPath);
44
75
  // Always (re)import first so reads reflect the file — map.yaml is authoritative.
45
76
  const res = importMap(db, map);
package/dist/bin/setup.js CHANGED
@@ -2,9 +2,9 @@
2
2
  // setup: One-command setup for Linksee Memory — the "Use Linksee" installer.
3
3
  //
4
4
  // Usage:
5
- // npx linksee-memory-setup (interactive setup)
6
- // npx linksee-memory-setup --yes (accept all defaults, no prompts)
7
- // npx linksee-memory-setup --dry-run
5
+ // npx linksee-memory setup (interactive setup)
6
+ // npx linksee-memory setup --yes (accept all defaults, no prompts)
7
+ // npx linksee-memory setup --dry-run
8
8
  //
9
9
  // Does four things:
10
10
  // 1. Registers the MCP server with Claude Code
@@ -35,9 +35,9 @@ if (showHelp) {
35
35
  console.log(`linksee-memory-setup — One-command setup for Linksee Memory
36
36
 
37
37
  Usage:
38
- npx linksee-memory-setup Interactive setup
39
- npx linksee-memory-setup --yes Accept all defaults, no prompts
40
- npx linksee-memory-setup --dry-run Show what would happen
38
+ npx linksee-memory setup Interactive setup
39
+ npx linksee-memory setup --yes Accept all defaults, no prompts
40
+ npx linksee-memory setup --dry-run Show what would happen
41
41
 
42
42
  What it does:
43
43
  1. Registers linksee-memory MCP server with Claude Code
@@ -59,12 +59,14 @@ const __filename = fileURLToPath(import.meta.url);
59
59
  const SKILL_SRC = join(dirname(__filename), '..', 'skill', 'SKILL.md');
60
60
  const SERVER_NAME = 'linksee';
61
61
  const MCP_COMMAND = `claude mcp add -s user ${SERVER_NAME} -- npx -y linksee-memory`;
62
- const HOOK_COMMAND = 'npx -y linksee-memory-sync';
62
+ // Subcommand form (npx -y linksee-memory <sub>) so the hooks resolve for a cold user —
63
+ // npx can resolve the package name, but not sibling bin names like linksee-memory-sync.
64
+ const HOOK_COMMAND = 'npx -y linksee-memory sync';
63
65
  // Re-injection guard — wired into the PROJECT (not user-global) settings, because it enforces THIS
64
66
  // project's accepted decisions. Mirrors the dogfood wiring's ${CLAUDE_PROJECT_DIR}/dist/bin path, but
65
67
  // points at the globally-installed `linksee-memory-guard` bin so it ships without a build step. Shell
66
68
  // form (resolved at run time) survives npx-cache eviction; a baked dist path would not.
67
- const GUARD_COMMAND = 'npx -y linksee-memory-guard';
69
+ const GUARD_COMMAND = 'npx -y linksee-memory guard';
68
70
  const PROJECT_DIR = process.cwd();
69
71
  const PROJECT_CLAUDE_DIR = join(PROJECT_DIR, '.claude');
70
72
  const PROJECT_SETTINGS_PATH = join(PROJECT_CLAUDE_DIR, 'settings.json');
@@ -293,7 +295,7 @@ console.log('How it works:');
293
295
  console.log(` ${DIM}• Every session is auto-captured (decisions, caveats, learnings)${RESET}`);
294
296
  console.log(` ${DIM}• Agent auto-recalls past context when starting a task${RESET}`);
295
297
  console.log(` ${DIM}• Memory is local-first (nothing leaves your machine)${RESET}`);
296
- console.log(` ${DIM}• Works across Claude Code, Cursor, ChatGPT (cross-LLM)${RESET}`);
298
+ console.log(` ${DIM}• Works across Claude Code, Cursor, Windsurf, Codex, Gemini (cross-agent)${RESET}`);
297
299
  if (guardConfigured) {
298
300
  console.log(` ${DIM}• Re-injection guard re-surfaces this project's accepted decisions before edits${RESET}`);
299
301
  }
package/dist/bin/stats.js CHANGED
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  // linksee-memory-stats — summary of the local memory DB.
3
3
  // Usage:
4
- // npx linksee-memory-stats
5
- // npx linksee-memory-stats --json
6
- // npx linksee-memory-stats --per-entity 10
4
+ // npx -y linksee-memory stats
5
+ // npx -y linksee-memory stats --json
6
+ // npx -y linksee-memory stats --per-entity 10
7
7
  //
8
8
  // Safe to run anytime (read-only).
9
9
  import { statSync } from 'node:fs';
10
- import { openDb, getDbPath } from '../db/migrate.js';
10
+ import { openDb, runMigrations, getDbPath } from '../db/migrate.js';
11
11
  function parseArgs() {
12
12
  const argv = process.argv.slice(2);
13
13
  const a = { json: false, perEntity: 5, help: false };
@@ -68,6 +68,7 @@ function main() {
68
68
  }
69
69
  catch { /* no db yet */ }
70
70
  const db = openDb();
71
+ runMigrations(db); // ensure schema exists — `stats` may be the first command a fresh user runs
71
72
  const counts = {
72
73
  entities: db.prepare('SELECT COUNT(*) as c FROM entities').get().c,
73
74
  memories: db.prepare('SELECT COUNT(*) as c FROM memories').get().c,
@@ -24,7 +24,49 @@ import { getTruthView, getDecisionDetail, resolveDrift } from '../lib/truth-engi
24
24
  import { declareAnchor, setNodeFields } from '../lib/drift-anchors.js';
25
25
  import { getReinjectionFriction, setGateMode } from '../lib/guard.js';
26
26
  import { whereAmI } from '../lib/map-view.js';
27
- const SERVER_VERSION = '0.10.0';
27
+ import { readFileSync, existsSync } from 'node:fs';
28
+ import { fileURLToPath } from 'node:url';
29
+ import { dirname, join } from 'node:path';
30
+ import { spawnSync } from 'node:child_process';
31
+ // Single source of truth: read our own version from package.json so the MCP
32
+ // serverInfo can never drift from the published package version. (We catch
33
+ // doc/code drift for a living — our own version string shouldn't drift.)
34
+ function readServerVersion() {
35
+ try {
36
+ const here = fileURLToPath(import.meta.url);
37
+ // dist/mcp/server.js → ../../package.json
38
+ const pkgPath = join(dirname(dirname(dirname(here))), 'package.json');
39
+ if (existsSync(pkgPath)) {
40
+ return String(JSON.parse(readFileSync(pkgPath, 'utf8')).version || '0.0.0');
41
+ }
42
+ }
43
+ catch { /* fall through */ }
44
+ return '0.0.0';
45
+ }
46
+ const SERVER_VERSION = readServerVersion();
47
+ // ── Subcommand dispatch ───────────────────────────────────────────────────────
48
+ // Each CLI ships as its own bin (linksee-memory-setup, …) AND as a subcommand of
49
+ // the main bin, so `npx -y linksee-memory <sub>` works for a cold user: npx can
50
+ // only resolve the package name (linksee-memory), not sibling bin names like
51
+ // linksee-memory-setup. Run as the MCP server (no subcommand / stdio) → skip this.
52
+ const SUBCOMMANDS = {
53
+ setup: 'setup.js',
54
+ map: 'map-import.js',
55
+ sync: 'sync-session.js',
56
+ guard: 'guard-hook.js',
57
+ stats: 'stats.js',
58
+ import: 'import-sessions.js',
59
+ 'install-skill': 'install-skill.js',
60
+ declare: 'declare-anchor.js',
61
+ detect: 'detect-drift.js',
62
+ };
63
+ const subcommand = process.argv[2];
64
+ if (subcommand && Object.prototype.hasOwnProperty.call(SUBCOMMANDS, subcommand)) {
65
+ // Spawn the target bin as a child (shebang-safe, argv/stdio correct) and exit with its code.
66
+ const binPath = join(dirname(fileURLToPath(import.meta.url)), '..', 'bin', SUBCOMMANDS[subcommand]);
67
+ const r = spawnSync(process.execPath, [binPath, ...process.argv.slice(3)], { stdio: 'inherit' });
68
+ process.exit(r.status ?? (r.signal ? 1 : 0));
69
+ }
28
70
  const db = openDb();
29
71
  runMigrations(db);
30
72
  // Auto-maintenance: consolidate stale memories on startup (non-blocking)
@@ -161,7 +203,7 @@ const TOOLS = [
161
203
  },
162
204
  {
163
205
  name: 'where_am_i',
164
- description: 'Locate the current topic on the Current Truth Map and report "you are here" + blast radius — the per-turn re-anchor.\n\nReturns the matching Map node(s) + journey stage (発見→…→拡張), the BLAST RADIUS (what becomes suspect if you change this — the must-stay-consistent-with / should-align-with / realizes dependents; e.g. editing the README implicates the LP), and the decision behind the node (linked anchor), if any.\n\nThree ways to call:\n• NO ARGS → auto-locates from the files you JUST edited this session (the zero-effort re-anchor — call it freely as you work).\n• query: "<topic>" → lexical locate by topic.\n• node_id: "<id>" → exact node.\n\nThis is how you avoid optimizing one node while silently breaking its neighbors (change the spec → npm/Docs/LP must move too). Matching is lexical (no embeddings).\n\nWHEN TO CALL:\n• Right after editing files — call with no args to see what you just touched + its blast radius.\n• When the topic shifts — re-anchor to the new node.\n• When the user asks "what does changing X affect?" / "where does this fit?"',
206
+ description: 'Locate the current topic on the Current Truth Map and report "you are here" + blast radius — the per-turn re-anchor.\n\nReturns the matching Map node(s) + journey stage (discover → … → expand), the BLAST RADIUS (what becomes suspect if you change this — the must-stay-consistent-with / should-align-with / realizes dependents; e.g. editing the README implicates the LP), and the decision behind the node (linked anchor), if any.\n\nThree ways to call:\n• NO ARGS → auto-locates from the files you JUST edited this session (the zero-effort re-anchor — call it freely as you work).\n• query: "<topic>" → lexical locate by topic.\n• node_id: "<id>" → exact node.\n\nThis is how you avoid optimizing one node while silently breaking its neighbors (change the spec → npm/Docs/LP must move too). Matching is lexical (no embeddings).\n\nWHEN TO CALL:\n• Right after editing files — call with no args to see what you just touched + its blast radius.\n• When the topic shifts — re-anchor to the new node.\n• When the user asks "what does changing X affect?" / "where does this fit?"',
165
207
  inputSchema: {
166
208
  type: 'object',
167
209
  properties: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "linksee-memory",
3
- "version": "0.11.0",
3
+ "version": "0.11.2",
4
4
  "mcpName": "io.github.michielinksee/linksee-memory",
5
5
  "description": "Local-first agent memory MCP — cross-agent brain with drift detection, 6-layer structured memory + token-saving file diff cache",
6
6
  "type": "module",