npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

smart-claude-memory-mcp

v2.2.1

Published

Sovereign memory protocol for Claude Code — typed, dual-scope, observability-grade. Bring your own empty Supabase project; the plugin handles the rest.

Readme

Smart Claude Memory

Smart Claude Memory v2.2.1 Master Schematic

Master schematic — the definitive visual reference for the Smart Claude Memory v2.2.x production baseline (v2.2.1 = docs-only patch on the v2.2.0 surface).

Hybrid cloud-local memory for Claude — semantic retrieval instead of context bloat.

TypeScript Node MCP pgvector Ollama License: MIT Version Developer

Developed by NABILNET.AI


The problem

Claude sessions load memory.md, rules.md, cloud.md, and a dozen other context files at startup. Every token you spend on "what does this project do" is a token you can't spend on the actual task. At scale, you end up burning budget re-reading the same notes hundreds of times per week.

What this does

smart-claude-memory is a Model Context Protocol server that replaces "read every .md at startup" with "search them on demand." It chunks your markdown notes, embeds them with a local Ollama model, stores them in Supabase (pgvector), and exposes fifty MCP tools to Claude spanning memory, vision, backlog, hygiene, orchestration, system health, transactional checkpoints (M4), autonomous curriculum (M5), observability + telemetry pruning (M6), human-gated skill graduation to GLOBAL (M7), and a Hybrid-RAG knowledge graph with a browser dashboard (M8). The elevator pitch:

| Tool | Purpose | |---|---| | sync_local_memory | Scan folders → MD5 hash-gate → chunk → embed → bulk upsert. Skips unchanged files. | | search_memory | Semantic search + intent routing (archive / backlog / semantic) | | manage_backlog | Per-project task handover with persistent archive |

See the Toolbox for the complete surface and ARCHITECTURE.md for the request-flow diagram.

Memory is strictly per-project: when you're in project A, Claude cannot see project B's notes. See Multi-project isolation.


Install

Option A — Claude Code plugin (recommended for end users):

/plugin install NABILNET-ORG/Smart-Claude-Memory

Auto-wires the MCP server and the md-policy.py PreToolUse hook via .claude-plugin/plugin.json. Zero manual ~/.claude.json edits.

Option B — npm (for direct use or programmatic embedding):

npm install smart-claude-memory-mcp

Published as smart-claude-memory-mcp (MIT). Exposes a smart-claude-memory-mcp binary you can wire into any MCP-compatible client.

Both paths require an empty Supabase project + a local Ollama install with moondream and nomic-embed-text pulled. See Bootstrap for the three-step setup ritual.


System Architecture

The system operates under the Sovereign Orchestrator pattern with Autonomous Self-Healing. The diagrams below are mirrored from ARCHITECTURE.md, which remains the canonical source of truth.

Two independent planes by design:

  • Local plane — Ollama. Every byte of your notes is embedded on your own machine. Content never leaves your device in plaintext for vectorization. No per-token API fees, no third-party seeing your prompts.
  • Cloud plane — Supabase. Durable storage, indexable across devices, cheap. Only the vectors + the source text live here — and only the text you explicitly choose to sync.

You get the privacy posture of local inference with the durability and cross-machine access of a managed Postgres.

Delegation Flow

flowchart TD
    subgraph ORC["Orchestrator (Main Session) — strategic context only"]
        U[User request]
        D[delegate_task]
        S[sync_artefacts]
        R[Report 2-para synthesis to user]
    end

    subgraph WRK["Background Worker (Isolated context)"]
        E[Edits / Bash / Research]
        G[refactor_guard gate]
        H{Gate OK?}
        HL[Self-Healing Loop]
        RB[refactor_guard rollback]
        SY[Emit 2-para synthesis]
    end

    U --> D
    D -->|canonical worker prompt| E
    E --> G
    G --> H
    H -->|pass| SY
    H -->|fail| HL
    HL -->|healed| G
    HL -->|exhausted| RB
    RB --> SY
    SY -->|only synthesis returns| S
    S --> R

Autonomous Self-Healing Loop

flowchart LR
    G1[refactor_guard gate] -->|pass| DONE([Emit synthesis])
    G1 -->|fail| AR[analyze_regression<br/>file + backups_to_compare]
    AR --> CP[closest_prior backup<br/>smallest edit distance]
    CP --> LF[Minimal local fix<br/>preserves feature intent]
    LF --> G2[refactor_guard gate]
    G2 -->|pass| DONE
    G2 -->|fail and attempts lt max| NEXT[Change hypothesis]
    NEXT --> AR
    G2 -->|attempts equal max| RBK[refactor_guard rollback]
    RBK --> DONE

Multi-Stack Compiler Map

flowchart TB
    P[Project root] --> D{Detect stack}
    D -->|package.json + tsconfig.json| TS[tsc --noEmit]
    D -->|package.json only| NODE[npm run build / lint]
    D -->|pubspec.yaml| FL[flutter analyze / dart analyze]
    D -->|Cargo.toml| RS[cargo check]
    D -->|pyproject.toml| PY[mypy / ruff]
    D -->|go.mod| GO[go vet / go build]
    TS --> OUT[Exit code + summarized output]
    NODE --> OUT
    FL --> OUT
    RS --> OUT
    PY --> OUT
    GO --> OUT

See ARCHITECTURE.md for the full prose + §4 auto-generated file-tree + §5 version history.


Multi-project isolation

Every chunk is tagged with a project_id. The MCP server auto-derives it from the slugified basename of the current working directory at startup:

C:\Users\you\repos\acme-api       → project_id = "acme-api"
~/code/side-projects/note-taker   → project_id = "note-taker"

The SQL function match_memory_chunks enforces the filter at the database layer — not just in application code:

where m.project_id = p_project_id

Concretely: when you cd into acme-api/ and launch Claude, calls to search_memory cannot return rows tagged note-taker. This is verified by scripts/e2e-isolation-test.ts, which seeds both projects with the same file name and proves zero cross-talk.

Need to reach into another project on purpose? Pass project_id explicitly:

search_memory({ query: "auth flow", project_id: "acme-api" })

Toolbox

| Tool | Category | Summary | |---|---|---| | sync_local_memory | Memory | Hash-gated incremental sync of .md files; bulk upsert in 100-chunk batches; force re-embed; auto_purge with dry-run + verify-before-delete | | prune_memory | Memory | Delete memory_chunks rows for explicit on-disk paths whose source files are gone. confirm:false returns a dry-run; inline:* origins and project_id='GLOBAL' are hard-rejected; every delete writes a manifest to ~/.claude-memory/prune-backups/. | | search_memory | Memory | Intent routing — archive > backlog > semantic. Optional metadata_filter (e.g. { "type": "DECISION" }) narrows via the GIN index before vector similarity. Dual-scope by default (v2.0.0-rc1): searches across the current project AND the reserved 'GLOBAL' vault; pass include_global: false to restrict to the current project. Archive tasks never leak into vector results unless requested. | | list_global_patterns | Memory | Browse-only enumeration of the reserved 'GLOBAL' Knowledge Vault. Pure SQL — zero embedding cost. Filter by JSONB containment (same metadata_filter shape as search_memory). Pagination: offset + limit (default 10, max 50), sorted by created_at DESC. Tiered output: default returns a content_preview (≤120 chars); pass include_content: true for the full content. Distinct from search_memory({ include_global: true }) — that's "find by meaning" (semantic), this is "enumerate by attribute" (deterministic). | | save_memory | Memory | Save a typed memory chunk — embed via Ollama, upsert with metadata.type from the Sovereign Taxonomy (DECISION / PATTERN / ERROR / LOG). v2 canonical write path. v2.0.0-rc1: set metadata.is_global: true to route the row to the reserved project_id: 'GLOBAL' vault for cross-project visibility. Sovereign Vetting: when is_global: true, you MUST also supply metadata.global_rationale and the memory must pass the Cross-Project Test (Rule 10). | | summarize_memory_file | Memory | LLM-driven compression of CLAUDE.md / MEMORY.md toward a token target (default 3000) | | manage_backlog | Backlog | add / list / update / prune_done (archives) / archive_list / session_end with Progress Report + resume prompt | | index_image | Vision | Moondream caption → nomic-embed-text embed → upsert. Auto-converts WebP/GIF/BMP via ffmpeg. | | check_code_hygiene | Guardian | 750-line rule with auto-generated file exclusions; N-split refactor plan for oversized files | | check_rule_conflicts | Guardian | Opt-in LLM-based intent conflict detection between a proposed change and retrieved rules | | raise_verification_gate | Guardian | Arm the Hard Stop flag after a risky edit | | confirm_verification | Guardian | Clear or reassert the Hard Stop gate — Claude must call this after manual verification | | check_system_health | Ops | Supabase reachability (memory_chunks count) + Ollama reachability + required-model presence (moondream, nomic-embed-text) + background keep-alive state | | init_project | Ops | Readiness report for a workspace: required env vars, md-policy.py hook, MCP registration in settings, compiled dist. Also runs a smart-scout pass over .claude/rules/*.md and emits a recommendations.hydrate_policies block with batch-hydration candidates when any are found (key omitted entirely otherwise). Returns ready / partial / not_ready with fix instructions per check. | | batch_freeze_patterns | Guardian | Bulk-hydrate the frozen-pattern cache from globs or a ## Frozen Patterns markdown section in a rule file. Strict line-by-line extraction, atomic writes, dedup with first-writer-wins, optional dry_run. | | list_frozen | Guardian | List all frozen pattern entries for the current project (returns pattern, source, added_at). Use before touching any structural-looking file. | | freeze_file | Guardian | Add a path or pattern to the frozen-pattern cache so future Write (full replacement) on matching files is hard-blocked by the hook. | | unfreeze_file | Guardian | Remove a path or pattern from the frozen-pattern cache. | | sweep_legacy_backups | Ops | Move stray backup-* / *.bak artefacts into a timestamped quarantine folder. Defaults to dry_run; HIGH-confidence files only unless aggressive: true. | | refactor_guard | Guardian | Single source of compile truth — auto-detects stack and runs the native gate (tsc --noEmit, flutter analyze, cargo check, …). Also exposes rollback for last-resort recovery. | | analyze_regression | Guardian | Diffs the current file against recent backups and surfaces the closest_prior snapshot to guide the minimal local fix during the self-healing loop. | | delegate_task | Orchestrator | Emit a canonical worker sub-agent prompt — the worker does the edit → refactor_guard gate → up to 3 self-heal attempts → returns only a 2-paragraph synthesis. Backbone of the Sovereign Orchestrator pattern. | | sync_artefacts | Orchestrator | Refresh README.md Recent Progress + the marker-bounded Mermaid block in ARCHITECTURE.md + project_file_architecture.md after a worker reports success. Doc-only subset of manage_backlog({ action: "session_end" }). | | list_graduation_candidates | Graduation | M7 enumeration surface. SELECT from skill_graduations with optional state ∈ {proposed, composed, approved, rejected} and project_id filters. Default limit 10, hard cap 50. Read-only. Use to find graduations awaiting compose or human confirm. See ARCHITECTURE.md §4.9. | | compose_global_rationale | Graduation | M7 race-safe persist of Orchestrator-LLM-drafted Cross-Project Test output to a state='proposed' graduation row. Server-side gates verdict ∈ {pass, fail}, evidence non-empty, model non-empty, and (when verdict='pass') global_rationale.trim().length >= 10. verdict='fail' coerces rationale to NULL. The handler NEVER itself calls an LLM — the Orchestrator passes its output in (mirrors S22-D1 compose_skill_candidate). | | confirm_promotion | Graduation | HUMAN-GATED PROMOTION TO GLOBAL — the sole is_global=true mint path outside of save_memory({is_global:true}). Calls the apply_graduation SQL RPC: atomic INSERT of a GLOBAL agent_skills clone + UPDATE state='approved' in ONE transaction. PostgreSQL now() collapses graduation.decided_at === new_skill.created_at to the microsecond (C4 atomic-tx proof). Source skill UNTOUCHED. | | reject_graduation | Graduation | M7 veto. TS-only UPDATE WHERE state IN ('proposed','composed'). Diverges from reject_curriculum_task: a second reject on an already-rejected row returns ok:false (reason='invalid_state_transition') instead of silently overwriting — GLOBAL rejection reasons carry audit weight. |

Full tool roster — 50 MCP tools by domain (v2.2.0)

The table above documents the canonical headline surface. The complete roster, grouped by subsystem, follows. Each tool is registered in src/index.ts and consumed via the MCP tools/list + tools/call protocol.

| Domain | Tools | Count | |---|---|---| | Memory + Vision | sync_local_memory · search_memory · save_memory · prune_memory · summarize_memory_file · list_global_patterns · index_image | 7 | | Backlog + Living Docs | manage_backlog · sync_artefacts | 2 | | Guardian (hook-bound) | check_code_hygiene · check_rule_conflicts · raise_verification_gate · confirm_verification · refactor_guard · analyze_regression · batch_freeze_patterns · list_frozen · freeze_file · unfreeze_file · sweep_legacy_backups | 11 | | Orchestrator (Sovereign) | delegate_task · upgrade_constitution | 2 | | Ops + Health | init_project · check_system_health · system_dashboard | 3 | | Trajectory (M2 Agent Diet) | compact_trajectory · get_trajectory_summary | 2 | | Skill Vault (M3 Sleep Learning) | compose_skill_candidate · promote_skill_candidate · reject_skill_candidate · list_skill_candidates · package_skill · request_skill | 6 | | Checkpoints (M4 Transactional Workflows) | checkpoint_create · checkpoint_commit · checkpoint_rollback · checkpoint_list | 4 | | Curriculum (M5 Single-Brain Closure) | list_curriculum_tasks · pull_curriculum_task · apply_curriculum_task · reject_curriculum_task | 4 | | Graduation to GLOBAL (M7) | list_graduation_candidates · compose_global_rationale · confirm_promotion · reject_graduation | 4 | | Knowledge Graph (M8.1 Hybrid RAG) | kg_upsert_node · kg_upsert_edge · list_kg_nodes · list_kg_edges · kg_hybrid_search | 5 | | Total | | 50 |

The GUI surface (M8.2, v2.2.0) is not an MCP tool — it's an HTTP server (src/gui/server.ts, npm run gui) that reuses list_kg_nodes/list_kg_edges/list_graduation_candidates etc. as in-process handlers, then renders the SVG Knowledge Graph + M7 graduation curation UI from modular static assets in src/gui/public/. See ARCHITECTURE.md §4.10 / §4.11 for the subsystem design.

Companion hook: hooks/md-policy.py enforces Zero-Local-MD allowlist, 750-line ceiling, frozen-feature patterns, and the Manual Test Gate from the Claude Code PreToolUse layer. Without it the Guardian tools are advisory; with it they are binding.


Living Documentation

manage_backlog({ action: "session_end" }) writes two artefacts into the project on every call, in parallel, so the repo self-documents without manual effort:

1. README progress log → README.md

  1. Archives completed tasks (atomic PL/pgSQL transaction into archive_backlog).
  2. Pulls the last 5 archived rows via listArchive.
  3. Replaces the `### 🚀 Recent Progress
  • [DONE] Idempotency: make migrations 001–018 strictly re-runnable (archived at 2026-05-14).
  • [DONE] Tech-debt: relocate 006_smoke/006_verify out of scripts/, drop loadMigrationFiles denylist (archived at 2026-05-14).
  • [DONE] [OBS-EPIC] Telemetry retention policy (rolling window for daemon_telemetry) (archived at 2026-05-14).
  • [DONE] [OBS-EPIC] Aggregate per-chunk token counters in compactor state for richer telemetry (archived at 2026-05-14).
  • [DONE] [FOUNDATION-FIX] Explicit service_role grants for May 30 Supabase compliance (archived at 2026-05-13).

🚀 Recent Progress

  • [DONE] Fix login form validation (archived at 2026-04-24).
  • [DONE] Add cache invalidation hook (archived at 2026-04-23). ...

### 2. Architecture map → `project_file_architecture.md`

1. Walks the project tree (cwd), ignoring `node_modules`, `.git`, `dist`, `build`, `backups`, and friends.
2. Caps depth at 3 and children per folder at 25; overflows show as `… (N more)`.
3. Renders a Mermaid `flowchart TD` — GitHub renders it natively in the doc.
4. Replaces only the `mermaid` fenced block; any human prose in the file is left intact. Creates the file with a professional header on first run.

### Safety rails (shared)

- If the MCP server's `cwd` slug doesn't match the `session_end` `project_id`, **both syncs are skipped** with an explicit warning — neither artefact is written into the wrong repo.
- Failures surface as `warning` fields in `readme_sync` / `architecture_sync`; the archive + resume-prompt logic always completes.
- Hook allowlist includes `README.md`; `project_file_architecture.md` is not on it — make sure your Zero-Local-MD allowlist covers it too (`CLAUDE_MD_POLICY_ALLOW_ROOT_MD="CLAUDE.md,MEMORY.md,README.md,project_file_architecture.md"`).

Net effect: every session leaves a timestamped handover note and a current file-tree diagram in the repo.

---

## Incremental sync (v0.3.0)

For corpora with thousands of files, re-embedding on every call is wasteful. `sync_local_memory` now runs a **hash-gated** pipeline:

1. Snapshot `Map<file_origin, file_hash>` for the current `project_id` in one paginated SELECT.
2. For each local file, compute MD5 **before** chunking or embedding.
3. If the hash matches the DB, skip — zero Ollama calls, zero writes.
4. If it differs (or is new), chunk + embed and buffer the rows.
5. Flush in batches of 100 chunks per upsert to minimize round-trips.
6. If a file is gone locally but still in the DB, it's reported in `orphan_files` (not auto-pruned — clean it with `prune_memory({ explicit_paths: [...], confirm: true })`).

Measured on this repo's own README (28 chunks, single file):

| Run | Behavior | Time | Ollama calls |
|---|---|---|---|
| Cold sync | Embed + upsert | **~3.7 s** | 28 |
| Unchanged rerun | All skip | **~0.3 s** | **0** |
| One file modified | Skip N−1, re-embed 1 | proportional to the delta | 1 file's worth |

### Output shape

```json
{
  "project_id": "acme-api",
  "force": false,
  "scanned": 812,
  "skipped": 806,
  "added": 3,
  "updated": 3,
  "orphans": 1,
  "orphan_files": ["/abs/path/legacy.md"],
  "chunks_upserted": 47,
  "chunks_deleted": 21,
  "ms": 1840
}

Force re-embed

Pass force: true to bypass the skip gate. Pre-existing files are still correctly classified as updated (not added) and their stale chunks are purged before re-insert — critical when a file shrinks.

sync_local_memory({ force: true })

Verified by scripts/e2e-incremental-test.ts, which walks five phases: cold, rerun, modify+add+delete, force, and row-shape integrity.


Bootstrap (3-step setup, ~5 minutes)

Resolves the #bootstrap anchor referenced from the Install section above. This is the post-install setup ritual — apply once per new Supabase project.

1. Install the plugin from the marketplace

In Claude Code, open the plugin marketplace and install smart-claude-memory (or, while the marketplace listing is being prepared, clone this repo and claude plugin add <path> it locally). The plugin manifest at .claude-plugin/plugin.json auto-wires both the MCP server and the md-policy.py PreToolUse hook. No ~/.claude.json or ~/.claude/settings.json edits required.

2. Create an empty Supabase project + Ollama models

  • Create a free Supabase project at supabase.com.
  • Install Ollama and pull the two required models:
ollama pull moondream
ollama pull nomic-embed-text

3. Set 3 env vars in your project's .env

SUPABASE_URL=https://<your-project-ref>.supabase.co
SUPABASE_SECRET_KEY=<service-role-key>
SUPABASE_POOLER_URL=postgres://postgres:<password>@<pooler-host>:6543/postgres

Then call init_project() from Claude Code. The plugin auto-applies all 21 schema migrations (through scripts/020_knowledge_graph.sql) to your empty DB on the first call, verifies your Ollama models are pulled, and reports overall: pending → healthy within a few minutes. Zero manual npm run schema, zero hand-edited settings.

Optional env vars

| Name | Default | Purpose | |---|---|---| | OLLAMA_HOST | http://localhost:11434 | Ollama endpoint | | OLLAMA_EMBED_MODEL | nomic-embed-text | Embedding model | | EMBED_DIM | 768 | Embedding vector dimension | | MEMORY_ROOTS | (empty) | Semicolon-separated folders to sync |

Why a pooler URL? Supabase's db.<ref>.supabase.co endpoint is IPv6-only on projects created after early 2024. If your network doesn't route public IPv6 (most home/office Windows boxes don't), direct connects fail with ENETUNREACH. The transaction pooler at aws-1-<region>.pooler.supabase.com:6543 is IPv4-reachable and is what the auto-migration loop uses.

First-run index your notes

From a Claude Code session inside the project whose notes you want to offload:

sync_local_memory()

Then free up context by archiving the originals:

npm run backup                                              # dry run
npx tsx scripts/backup-and-remove.ts --confirm-delete       # zip + delete

Usage — every command you'll actually run

The plugin has two surfaces: MCP tools you invoke inside a Claude Code session, and CLI commands you run from your shell. Below is the canonical command cheat sheet, grouped by who you are and what you're doing.

Quick command reference (CLI)

Every command runs from the repo root. None require sudo. None create permanent state outside ~/.claude-memory/ and your Supabase project.

| Command | What it does | When you'd run it | |---|---|---| | npm install | Resolve dependencies | Once after clone / pull | | npm run build | lint:boundariestsccopy:gui chain — produces dist/ (the artefact npm publish ships) | Before publishing or before running npm start | | npm run dev | Run the MCP server via tsx (no compile step, fast iteration) | Editing TypeScript and want hot-feedback | | npm run start | Run the compiled MCP server (node dist/index.js) | Reproducing what an npm consumer sees | | npm run gui | Boot the Sovereign Command Center dashboard at http://127.0.0.1:7788/ (loopback only) | Visual triage of M7 graduations + M8.1 knowledge graph | | npm run test | Run the full 246-case hermetic suite (no live Supabase / Ollama required) | Before committing, before publishing | | npm run lint:boundaries | Statically asserts src/sleep/**, src/curriculum/**, src/graduation/** contain NO LLM imports (Single Brain Boundary) | Runs automatically in build; useful standalone after touching those subsystems | | npm run copy:gui | Mirror src/gui/public/dist/gui/public/ via fs.cpSync (zero-dep) | Runs automatically in build; useful if you edit GUI assets and want them in dist/ without a full rebuild | | npm run schema | Apply pending SQL migrations to your Supabase pooler URL (idempotent — re-runs are no-ops) | Manual recovery only — init_project does this automatically on first boot | | npm run backup | Dry-run scan + zip of every .md file in MEMORY_ROOTS, written to ~/.claude-memory/backups/ | Before deleting any .md you've already indexed | | npm run smoke:m4 | End-to-end smoke for M4 transactional checkpoints | Sanity check after touching src/transactions/ | | npm run smoke:m5-rollback / smoke:m5-stale / smoke:m5-consumer | Smoke each M5 curriculum signal-source | After touching src/curriculum/ | | npm run smoke:m7 | Smoke the full M7 skill graduation lifecycle (propose → compose → confirm/reject) | After touching src/graduation/ |

Quick command reference (MCP — inside Claude Code)

Every MCP tool is invoked the same way: type the tool name with arguments inside your Claude Code chat. Claude routes the call through the MCP server. All 50 tools are documented in the Toolbox. The most-used invocations:

init_project()                                          # boot — readiness + auto-migrate
check_system_health()                                   # Supabase + Ollama + 6 daemons status
search_memory({ query: "...", k: 10 })                  # dual-scope semantic search
search_memory({ query: "...", metadata_filter: { type: "DECISION" } })   # typed filter
save_memory({ content: "...", metadata: { type: "DECISION" } })          # project-scoped
save_memory({ content: "...", metadata: { type: "PATTERN", is_global: true, global_rationale: "..." } })   # GLOBAL vault
list_global_patterns({ metadata_filter: { type: "PATTERN" } })           # browse GLOBAL deterministically
manage_backlog({ action: "add", title: "..." })
manage_backlog({ action: "list" })
manage_backlog({ action: "session_end" })                                # wrap-up ritual
delegate_task({ ... })                                                   # offload research >100 lines
sync_artefacts()                                                         # regen README progress + ARCH file-tree

Daily workflows — by what you're trying to do

"Boot a new session in an existing project":

  1. Open Claude Code in the project directory.
  2. Paste the Golden Startup Prompt as your first message.
  3. Claude runs init_project()search_memory({ query: "Active Backlog" }) and reports state.

"Index a new note I just wrote":

  1. Save the .md somewhere under MEMORY_ROOTS.
  2. From Claude: sync_local_memory() (incremental — only changed files re-embed).
  3. Verify: search_memory({ query: "<a phrase from the note>" }).

"Capture an architectural decision":

save_memory({
  content: "SCM-S<N>-D<i> — <decision> ... \n\nRationale: ...",
  metadata: { type: "DECISION" }
})

The SCM-S<N>-D<i> prefix is the project convention from CLAUDE.md. DECISIONs are project-scoped by default.

"Promote a universal pattern to GLOBAL":

  1. Run the Cross-Project Test: "if this project were deleted tomorrow, would this still be a gold-standard reference for others?"
  2. If yes:
    save_memory({
      content: "PATTERN: ...",
      metadata: {
        type: "PATTERN",
        is_global: true,
        global_rationale: "Universal because ... (one or two sentences)"
      },
      project_id: "GLOBAL"
    })
  3. Verify it landed: list_global_patterns({ limit: 5 }) — your row should be at the top.

"Triage skill graduations in the browser":

  1. Terminal: npm run gui → opens http://127.0.0.1:7788/.
  2. Browse /api/graduations?state=proposed for the queue, click a row to compose, approve/reject from the drawer.
  3. The knowledge-graph panel below renders the typed nodes from kg_nodes + edges from kg_edges (60 nodes default, force-directed SVG).

"End a session cleanly":

manage_backlog({ action: "session_end" })
  • Archives done tasks atomically.
  • Regenerates README "Recent Progress" + ARCHITECTURE auto file-tree.
  • Returns a next_session_command_markdown block — paste it verbatim as your final chat message so the operator can copy it into the next session.

Knowledge Graph operations (M8.1, v2.2.0)

Read-only inspection from Claude Code:

list_kg_nodes({ k: 60, type: "DECISION" })                          # latest 60 DECISION nodes
list_kg_nodes({ k: 60, label_prefix: "src/" })                      # prefix filter
list_kg_edges({ k: 120 })
kg_hybrid_search({ query: "GUI refactor", k: 10 })                  # vector + graph fusion

Curated upsert (manual, e.g., backfilling a typed node from an old chunk):

kg_upsert_node({ type: "FILE", label: "src/gui/server.ts", properties: { ... }, source_chunk_id: 12901 })
kg_upsert_edge({ source_id: 42, target_id: 99, type: "DEPENDS_ON", confidence: 0.95 })

Both upserts are idempotent (UNIQUE on (project_id, type, label) for nodes; full key for edges).

Environment variables (full reference)

Set in your project's .env file or your shell. Documented checks live in src/tools/setup.ts and surface in init_project().

| Variable | Required | Default | Purpose | |---|---|---|---| | SUPABASE_URL | ✅ | — | https://<project-ref>.supabase.co | | SUPABASE_SECRET_KEY | ✅ | — | sb_secret_* service-role key (bypasses RLS) | | SUPABASE_POOLER_URL | ✅ | — | IPv4-reachable pooler URL — init_project's auto-migration loop uses this | | OLLAMA_HOST | — | http://localhost:11434 | Ollama endpoint | | OLLAMA_EMBED_MODEL | — | nomic-embed-text | Embedding model | | EMBED_DIM | — | 768 | Embedding vector dimension (must match the model) | | MEMORY_ROOTS | — | (empty) | Semicolon-separated folders to sync | | SCM_GUI_PORT | — | 7788 | GUI dashboard port (loopback only) | | SCM_GUI_HOST | — | 127.0.0.1 | GUI host — change ONLY if you understand the threat model (service-role key lives in this process) | | SCM_GUI_TOKEN | — | (none) | Optional bearer token gating /api/* mutation routes | | OBS_ERR_RATE_DEGRADED_DEFAULT / _DOWN_DEFAULT / OBS_STALENESS_MULTIPLIER_DEFAULT | — | 0.20 / 0.50 / 2.0 | Per-daemon health-derivation thresholds | | TELEMETRY_PRUNER_INTERVAL_MS / _RETENTION_DAYS | — | 21600000 (6h) / 30 | telemetry_pruner cadence + retention window | | GRAPH_EXTRACTOR_INTERVAL_MS / _BATCH | — | 120000 (2m) / 10 | M8.1 knowledge-graph daemon cadence + per-tick batch |

Quick troubleshooting

| Symptom | First check | |---|---| | init_project returns not_ready with env miss | Set the listed variable; re-run | | npm run schema fails ENETUNREACH | You're using db.<ref>.supabase.co (IPv6-only). Switch to the pooler URL (aws-1-<region>.pooler.supabase.com:6543) | | npm run gui fails EADDRINUSE :7788 | Another GUI process is bound. Set SCM_GUI_PORT=7789 or stop the holder | | check_system_health shows daemon pending | Within 15-min grace window after MCP boot. Re-check after one daemon interval | | Tests fail in tests/migrations.test.ts | A new SQL migration lacks an idempotency guard (OR REPLACE / IF NOT EXISTS) — fix the migration, not the test |


⚡ The Golden Startup Prompt

To ensure a seamless, context-efficient, and secure session in any project using this plugin, copy and paste the following prompt as your very first interaction with the agent.

SYSTEM INITIALIZATION:
I am using the `smart-claude-memory` plugin. Follow these standards:
1. **Check Readiness:** Run `init_project` to verify the workspace and health.
2. **Sync State:** Run `sync_local_memory()` to ensure the vector database is up to date with my local notes.
3. **Operate via Tools:** From now on, do NOT read large `.md` files directly. Use `search_memory()` for context retrieval and respect the `md-policy.py` hook for all writes.
4. **Typed Retrieval (v2):** When saving memories use `save_memory` with `metadata.type` from the Sovereign Taxonomy — `DECISION` (architectural choices + rationale), `PATTERN` (code standards + Rule 5–8 enforcement), `ERROR` (bug post-mortems + fixes), or `LOG` (general session progress). When retrieving, narrow `search_memory` with `metadata_filter` (e.g. `{ "type": "DECISION" }`) so the GIN index pre-filters before vector similarity. After updates, run `sync_artefacts` to keep cloud + local aligned.
5. **MANDATORY DELEGATION:** Any read-heavy investigation touching > 3 files OR resulting in > 100 lines of raw output (Grep / Read / Logcat) MUST be delegated via `delegate_task` to a worker. Never flood the main context. Request only the 2-paragraph synthesis.
6. **Initial Sync (Core 3 Audit):** `init_project` (Rule 1) returns a `core3` block reporting on `CLAUDE.md`, `README.md`, and `ARCHITECTURE.md` — the project's three architectural sources of truth. If any is missing, or if `core3.in_sync` is `false`, immediately `delegate_task` a Core-3 audit BEFORE any other work. Request a 2-paragraph synthesis with the proposed reconciliation. The Architecture Guard treats these three files as load-bearing; nothing else proceeds until they agree.
7. **Modular Diagramming:** Mermaid diagrams in `ARCHITECTURE.md` and `README.md` MUST be split into small per-section blocks — one block per `##` subsystem, ≤ ~40 nodes each. GitHub silently fails to render oversized Mermaid graphs; a single monolithic flowchart will appear blank in the rendered view. Never emit one mega-graph. When `manage_backlog({ action: "session_end" })` regenerates the diagram, it produces one block per logical section, not one giant tree.
8. **Session-End Lock & Handoff:** Before ending the session, call `manage_backlog({ action: "session_end" })` to flush the backlog, regenerate the per-section Mermaid diagrams, and run `sync_artefacts` to push state to the cloud. The response includes a `next_session_command_markdown` field — **POST THAT MARKDOWN BLOCK VERBATIM as your final message to chat.** It is a copy-paste-ready boot command (`init_project` + `search_memory` for the Active Backlog + pointer to `docs/NEXT-SESSION-PROMPT.md`) that the user pastes into the next session. This locks a coherent baseline so the next session opens with the Core 3, the diagrams, and the cloud memory all aligned.
9. **Universal Patterns → GLOBAL (v2.0.0-rc1):** Any pattern, lesson-learned, or architectural decision deemed **universal** — applicable across projects, not just this one — MUST be saved with `metadata.is_global: true`. The row is stored under the reserved `project_id: 'GLOBAL'` and surfaces in dual-scope search across every project. Use this to **immunize future projects against known errors** (a bug fixed once never has to be re-discovered). Inverse: do NOT promote project-local context to GLOBAL — the vault loses signal if it becomes a dumping ground.
10. **Sovereign Vetting:** The GLOBAL vault is a high-signal environment. Every global save must pass the **Cross-Project Test**: *if the current project were deleted tomorrow, would this memory still be a gold-standard reference for others?* If no, keep it local. When `metadata.is_global: true`, you **MUST** also include `metadata.global_rationale` — a one- or two-sentence justification of why this memory is a universal truth (not project-specific). Saves that fail the Cross-Project Test pollute the vault and are forbidden. The agent is its own auditor: only Arch-Patterns that apply to ALL projects (universal architectural decisions, multi-project bug fixes) qualify.

How project_id is derived

src/project.ts:

export function detectProjectId(cwd = process.cwd()): string {
  return slugify(basename(cwd) || "default");
}

Captured once at MCP server startup. Claude Code launches an MCP subprocess per session with cwd set to the workspace root, so basename(cwd) is a stable project identifier for the lifetime of that session.

Collisions are possible if two unrelated projects share a folder name (utils/, backend/, etc.). To harden, override explicitly:

sync_local_memory({ project_id: "acme-backend-prod" })

Database schema

create table memory_chunks (
  id           bigserial primary key,
  content      text not null,
  embedding    vector(768) not null,
  file_origin  text not null,
  chunk_index  int not null default 0,
  content_hash text not null,                  -- MD5 of the chunk text
  file_hash    text,                           -- MD5 of the whole file at last sync (v0.3.0)
  metadata     jsonb not null default '{}'::jsonb,
  project_id   text not null default 'default',
  updated_at   timestamptz not null default now(),
  unique (project_id, file_origin, chunk_index)
);

create index on memory_chunks using hnsw (embedding vector_cosine_ops);
create index on memory_chunks (project_id);
create index on memory_chunks (project_id, file_origin);   -- powers the hash-gate lookup

The current 6-arg RPC match_memory_chunks(query_embedding, p_project_id, match_count, min_similarity, p_metadata_filter, p_include_global) (introduced by migration 008 and patched in 009 to use the planner-friendly IN-form WHERE m.project_id IN (p_project_id, CASE WHEN p_include_global THEN 'GLOBAL' END)) enforces tenancy + the typed-metadata filter + the optional 'GLOBAL' fan-out, all in SQL — before pgvector ranks the candidate set. The legacy 4-arg form from migration 001 is superseded but left intact in the file for historical reference. All chunks from the same file share one file_hash, so the incremental-sync skip check is a single SELECT file_origin, file_hash WHERE project_id = ?. Full schema + RPC definitions in scripts/001_schema.sql, scripts/002_multi_project.sql, scripts/003_file_hash.sql, scripts/007_metadata_typed_retrieval.sql, scripts/008_global_scope.sql, and scripts/009_fix_rpc_dual_scope.sql.


Project layout

src/
├── index.ts              MCP server entry — registers all 22 tools
├── config.ts             Env loader (absolute .env path resolution)
├── project.ts            project_id detection + slugification
├── project-detect.ts     Multi-stack project root detection
├── ollama.ts             POST /api/embed client
├── supabase.ts           Table + RPC wrappers + frozen-pattern cache
├── chunker.ts            Markdown-aware splitter
├── verification-gate.ts  Hard-stop verification flag (PreToolUse blocker)
├── version.ts            Version SSOT — re-exports from package.json
└── tools/
    ├── backlog.ts                manage_backlog (add / list / update / prune_done / archive_list / session_end)
    ├── batch-freeze-patterns.ts  batch_freeze_patterns (bulk-hydrate from globs or rule file)
    ├── conflict.ts               check_rule_conflicts
    ├── frozen-cache.ts           Shared loader for the frozen-pattern cache (atomic writes, dedup)
    ├── health.ts                 check_system_health (Supabase + Ollama + keep-alive + orchestrator)
    ├── hygiene.ts                check_code_hygiene (750-line ceiling, N-split refactor plans)
    ├── image.ts                  index_image (Moondream caption → embed → upsert)
    ├── orchestrator.ts           delegate_task + sync_artefacts (Sovereign Orchestrator pattern)
    ├── policy.ts                 list_frozen / freeze_file / unfreeze_file / sweep_legacy_backups
    ├── refactor.ts               refactor_guard (compile gate) + analyze_regression (backup diff)
    ├── save.ts                   save_memory (typed write path with Sovereign Vetting)
    ├── search.ts                 search_memory (intent routing + dual-scope semantic)
    ├── setup.ts                  init_project (readiness checks + smart-scout)
    ├── sovereign-constitution.ts CLAUDE.md Sovereign-binding template + helper
    ├── summarize.ts              summarize_memory_file
    ├── sync.ts                   sync_local_memory (hash-gated incremental)
    └── verification.ts           raise_verification_gate / confirm_verification

scripts/
├── 001_schema.sql                    base table + HNSW index + base RPCs
├── 002_multi_project.sql             project_id + per-project isolation
├── 003_file_hash.sql                 file_hash column for incremental sync
├── 004_backlog_frozen.sql            cloud_backlog + frozen_patterns tables
├── 005_archive_backlog.sql           archive_backlog history table
├── 006_security_hardening.sql        RLS deny-all + service-role-only access
├── 007_metadata_typed_retrieval.sql  GIN(jsonb_path_ops) + typed-filter match RPC
├── 008_global_scope.sql              'GLOBAL' project_id + 6-arg dual-scope match RPC
├── 009_fix_rpc_dual_scope.sql        IN-form WHERE planner fix (v2.0.0-rc1 hotfix)
├── apply-schema.ts                   `npm run schema` runner
├── backup-and-remove.ts              archive + delete .md files in MEMORY_ROOTS
├── e2e-test.ts                       end-to-end smoke
├── e2e-isolation-test.ts             multi-project isolation gate
├── e2e-incremental-test.ts           hash-gate / force / orphans
├── purge-samia-rules.ts              one-off scrub (legacy)
├── smoke-008.ts                      smoke for 008 dual-scope
├── verify-007.ts                     verifier for 007 typed retrieval
└── verify-008.ts                     verifier for 008 dual-scope

npm scripts

| Command | Purpose | |---|---| | npm run build | Three-step chain: lint:boundariestsccopy:gui. Compiles TypeScript and mirrors src/gui/public/dist/gui/public/ for the modular dashboard (v2.2.0). | | npm run lint:boundaries | Boundary Invariant #1 fence — scans src/sleep, src/curriculum, src/graduation for forbidden LLM imports / endpoints. Runs first in build. | | npm run copy:gui | Zero-dep mirror of src/gui/public/dist/gui/public/ via fs.cpSync (no cpx / fs-extra introduced). Idempotent. | | npm run dev | Run the MCP server via tsx (no build step) | | npm run start | Run the compiled MCP server (node dist/index.js) | | npm run gui | Boot the Sovereign Command Center dashboard standalone on 127.0.0.1:7788 (tsx src/gui/server.ts). Cross-platform ESM entry-point guard (SCM-S37-P1). | | npm run test | Full hermetic suite via node --test — 246/246 as of v2.2.0 (stubbed Supabase + Ollama; no live infra needed) | | npm run schema | Apply 001_schema.sql (or pass -- <file> for another) | | npm run backup | Dry-run backup of all .md in MEMORY_ROOTS | | npm run smoke:m4 / smoke:m5-rollback / smoke:m5-stale / smoke:m5-consumer / smoke:m7 | End-to-end smoke flows per milestone — exercise checkpoints (M4), rollback signals + stale-candidate triage + curriculum consumer (M5), and human-gated graduation (M7). |


Design decisions worth knowing

  • Embedding model is load-bearing. EMBED_DIM must match the model's output. Swapping nomic-embed-text (768) for mxbai-embed-large (1024) means dropping and rebuilding the embedding column. Don't mix dimensions.
  • Service-role key, no RLS. The MCP server runs locally with no user context; it uses sb_secret_* which bypasses RLS. If you expose this server to untrusted callers, add RLS plus a user_id column.
  • Chunking is heading-aware, not token-aware. Sections split on ## / ###; long sections slide-window at CHUNK_SIZE with CHUNK_OVERLAP. Good enough for most prose; swap in a tokenizer-driven chunker if you're indexing code.
  • Sync is incremental by default. Unchanged files are skipped via file_hash comparison; no embedding calls, no writes. Pass force: true to re-embed everything. Chunks are flushed in 100-row batches to minimize Supabase round-trips.
  • Orphans are reported by sync_local_memory and pruned by prune_memory. Files removed from disk stay in the DB and show up in orphan_files. To clean them, call prune_memory({ explicit_paths: [...], confirm: true }) — wildcards are rejected, inline:* synthetic origins from save_memory are always skipped, project_id='GLOBAL' is refused, and every confirmed delete writes a forensic manifest to ~/.claude-memory/prune-backups/<stamp>-<project>/manifest.json. The manifest is the archive — reversal is a re-sync away. This reconciles with the "Archive, never delete" rule (SCM-S17-D1): that rule bans content mutation of immutable HNSW-indexed rows, not row-lifecycle reaping of confirmed orphans.
  • Version is a single source of truth. src/version.ts reads version from package.json via createRequire(import.meta.url) and re-exports it. The MCP server registration in src/index.ts, the check_system_health orchestrator block, and the delegate_task response envelope all import that one constant — no hard-coded literals anywhere. Bumping package.json propagates through the next build with zero drift between npm view and what the tool surface reports.
  • Policy hydration is bulk + idempotent. src/tools/batch-freeze-patterns.ts accepts globs or a markdown rule file, scans only the section under an exact ## Frozen Patterns heading, strips backticks/list markers, and writes through the shared loader at src/tools/frozen-cache.ts. Cache entries are now { pattern, source, added_at } objects (legacy strings are lazily migrated on read), all writes go through <file>.tmp + rename, and dedup is first-writer-wins on trimmed pattern equality — so re-running against the same rule file is a no-op. The source field is what powers smart-scout suppression.

Security

  • .env is git-ignored. Never commit it.
  • Rotate SUPABASE_SECRET_KEY and your database password anytime they touch a log, a terminal history, or a chat transcript.
  • The backup script writes unencrypted .zip files to backups/ (also git-ignored). If your notes are sensitive, encrypt the archive before uploading anywhere.

License

MIT. See LICENSE.


Developer

Built and maintained by NABILNET.AI.

For inquiries, integrations, or sovereign-grade Claude Code tooling, visit nabilnet.ai.

🗺️ File Architecture

Auto-synced at 2026-05-19T08:59:28.227Z for smart-claude-memory.

flowchart TD
  n0["Claude-Memory/"]
  n1[".claude/"]
  n0 --> n1
  n2[".github/"]
  n0 --> n2
  n3["workflows/"]
  n2 --> n3
  n4["ci.yml"]
  n3 --> n4
  n5["docs/"]
  n0 --> n5
  n6["assets/"]
  n5 --> n6
  n7["schematic.png"]
  n6 --> n7
  n8["scm-memory/"]
  n5 --> n8
  n9["legacy_claude.md"]
  n8 --> n9
  n10["legacy_memory.md"]
  n8 --> n10
  n11["session-reports/"]
  n5 --> n11
  n12["SESSION-10-REPORT.md"]
  n11 --> n12
  n13["SESSION-11-REPORT.md"]
  n11 --> n13
  n14["SESSION-12-REPORT.md"]
  n11 --> n14
  n15["SESSION-13-REPORT.md"]
  n11 --> n15
  n16["SESSION-14-REPORT.md"]
  n11 --> n16
  n17["SESSION-15-REPORT.md"]
  n11 --> n17
  n18["SESSION-16-REPORT.md"]
  n11 --> n18
  n19["SESSION-17-REPORT.md"]
  n11 --> n19
  n20["SESSION-18-REPORT.md"]
  n11 --> n20
  n21["SESSION-19-REPORT.md"]
  n11 --> n21
  n22["SESSION-20-REPORT.md"]
  n11 --> n22
  n23["SESSION-21-REPORT.md"]
  n11 --> n23
  n24["SESSION-22-REPORT.md"]
  n11 --> n24
  n25["SESSION-23-REPORT.md"]
  n11 --> n25
  n26["SESSION-24-REPORT.md"]
  n11 --> n26
  n27["SESSION-25-REPORT.md"]
  n11 --> n27
  n28["SESSION-26-REPORT.md"]
  n11 --> n28
  n29["SESSION-27-REPORT.md"]
  n11 --> n29
  n30["SESSION-28-REPORT.md"]
  n11 --> n30
  n31["SESSION-29-REPORT.md"]
  n11 --> n31
  n32["SESSION-30-REPORT.md"]
  n11 --> n32
  n33["SESSION-31-REPORT.md"]
  n11 --> n33
  n34["SESSION-32-REPORT.md"]
  n11 --> n34
  n35["SESSION-33-REPORT.md"]
  n11 --> n35
  n36["SESSION-34-REPORT.md"]
  n11 --> n36
  n37["… (7 more)"]
  n11 --> n37
  n38["specs/"]
  n5 --> n38
  n39["m4-checkpoints-phase-b.md"]
  n38 --> n39
  n40["m5-curriculum-consumer.md"]
  n38 --> n40
  n41["m5-rollback-repro.md"]
  n38 --> n41
  n42["m5-stale-candidates.md"]
  n38 --> n42
  n43["m7-skill-graduation-phase-a.md"]
  n38 --> n43
  n44["prune-memory-tool.md"]
  n38 --> n44
  n45["superpowers/"]
  n5 --> n45
  n46["plans/"]
  n45 --> n46
  n47["2026-05-12-observability-telemetry.md"]
  n46 --> n47
  n48["2026-05-14-marketplace-packaging.md"]
  n46 --> n48
  n49["2026-05-15-v2.1.0-global-vault-ux.md"]
  n46 --> n49
  n50["2026-05-17-agentic-superpowers-integration.md"]
  n46 --> n50
  n51["specs/"]
  n45 --> n51
  n52["2026-05-13-telemetry-retention-design.md"]
  n51 --> n52
  n53["2026-05-14-marketplace-packaging-design.md"]
  n51 --> n53
  n54["IDE-INTEGRATION.md"]
  n5 --> n54
  n55["NEXT-SESSION-PROMPT.md"]
  n5 --> n55
  n56["release-notes-v2.1.0.md"]
  n5 --> n56
  n57["hooks/"]
  n0 --> n57
  n58["md-policy.py"]
  n57 --> n58
  n59["README.md"]
  n57 --> n59
  n60["images/"]
  n0 --> n60
  n61["GPT SMC v2.0-rc1.png"]
  n60 --> n61
  n62["scripts/"]
  n0 --> n62
  n63["001_schema.sql"]
  n62 --> n63
  n64["002_multi_project.sql"]
  n62 --> n64
  n65["003_file_hash.sql"]
  n62 --> n65
  n66["004_backlog_frozen.sql"]
  n62 --> n66
  n67["005_archive_backlog.sql"]
  n62 --> n67
  n68["006_security_hardening.sql"]
  n62 --> n68
  n69["007_metadata_typed_retrieval.sql"]
  n62 --> n69
  n70["008_global_scope.sql"]
  n62 --> n70
  n71["009_fix_rpc_dual_scope.sql"]
  n62 --> n71
  n72["010_agent_skills.sql"]
  n62 --> n72
  n73["011_trajectory_compaction.sql"]
  n62 --> n73
  n74["012_sleep_learning.sql"]
  n62 --> n74
  n75["013_archive_backlog_chunk_link.sql"]
  n62 --> n75
  n76["014_workflow_checkpoints.sql"]
  n62 --> n76
  n77["015_curriculum_tasks.sql"]
  n62 --> n77
  n78["016_daemon_telemetry.sql"]
  n62 --> n78
  n79["017_explicit_service_role_grants.sql"]
  n62 --> n79
  n80["017_skill_graduations.sql"]
  n62 --> n80
  n81["018_telemetry_retention.sql"]
  n62 --> n81
  n82["019_telemetry_graduation_daemon.sql"]
  n62 --> n82
  n83["020_knowledge_graph.sql"]
  n62 --> n83
  n84["apply-schema.ts"]
  n62 --> n84
  n85["backfill-ledger.ts"]
  n62 --> n85
  n86["backup-and-remove.ts"]
  n62 --> n86
  n87["copy-gui-public.ts"]
  n62 --> n87
  n88["… (28 more)"]
  n62 --> n88
  n89["src/"]
  n0 --> n89
  n90["curriculum/"]
  n89 --> n90
  n91["daemon.ts"]
  n90 --> n91
  n92["scanner.ts"]
  n90 --> n92
  n93["graduation/"]
  n89 --> n93
  n94["daemon.ts"]
  n93 --> n94
  n95["scanner.ts"]
  n93 --> n95
  n96["graph/"]
  n89 --> n96
  n97["daemon.ts"]
  n96 --> n97
  n98["extractor.ts"]
  n96 --> n98
  n99["gui/"]
  n89 --> n99
  n100["public/"]
  n99 --> n100
  n101["app.js"]
  n100 --> n101
  n102["index.html"]
  n100 --> n102
  n103["style.css"]
  n100 --> n103
  n104["server.ts"]
  n99 --> n104
  n105["lib/"]
  n89 --> n105
  n106["migrations.ts"]
  n105 --> n106
  n107["sleep/"]
  n89 --> n107
  n108["daemon.ts"]
  n107 --> n108
  n109["miner.ts"]
  n107 --> n109
  n110["telemetry/"]
  n89 --> n110
  n111["emit.ts"]
  n110 --> n111
  n112["pruner.ts"]
  n110 --> n112
  n113["types.ts"]
  n110 --> n113
  n114["tools/"]
  n89 --> n114
  n115["backlog.ts"]
  n114 --> n115
  n116["batch-freeze-patterns.ts"]
  n114 --> n116
  n117["bloat-audit.ts"]
  n114 --> n117
  n118["checkpoint.ts"]
  n114 --> n118
  n119["compact.ts"]
  n114 --> n119
  n120["conflict.ts"]
  n114 --> n120
  n121["curriculum.ts"]
  n114 --> n121
  n122["frozen-cache.ts"]
  n114 --> n122
  n123["graduation.ts"]
  n114 --> n123
  n124["health.ts"]
  n114 --> n124
  n125["hygiene.ts"]
  n114 --> n125
  n126["image.ts"]
  n114 --> n126
  n127["kg.ts"]
  n114 --> n127
  n128["list-global-patterns.ts"]
  n114 --> n128
  n129["orchestrator.ts"]
  n114 --> n129
  n130["policy.ts"]
  n114 --> n130
  n131["prune.ts"]
  n114 --> n131
  n132["refactor.ts"]
  n114 --> n132
  n133["save.ts"]
  n114 --> n133
  n134["search.ts"]
  n114 --> n134
  n135["setup.ts"]
  n114 --> n135
  n136["shared-schemas.ts"]
  n114 --> n136
  n137["skills.ts"]
  n114 --> n137
  n138["sleep.ts"]
  n114 --> n138
  n139["sovereign-constitution.ts"]
  n114 --> n139
  n140["… (4 more)"]
  n114 --> n140
  n141["trajectory/"]
  n89 --> n141
  n142["daemon.ts"]
  n141 --> n142
  n143["stripper.ts"]
  n141 --> n143
  n144["summarizer.ts"]
  n141 --> n144
  n145["transactions/"]
  n89 --> n145
  n146["checkpoint.ts"]
  n145 --> n146
  n147["chunker.ts"]
  n89 --> n147
  n148["config.ts"]
  n89 --> n148
  n149["index.ts"]
  n89 --> n149
  n150["ollama.ts"]
  n89 --> n150
  n151["project-detect.ts"]
  n89 --> n151
  n152["project.ts"]
  n89 --> n152
  n153["supabase.ts"]
  n89 --> n153
  n154["verification-gate.ts"]
  n89 --> n154
  n155["version.ts"]
  n89 --> n155
  n156["tests/"]
  n0 --> n156
  n157["fixtures/"]
  n156 --> n157
  n158["m4.ts"]
  n157 --> n158
  n159["prune.ts"]
  n157 --> n159
  n160["sql_fixtures/"]
  n156 --> n160
  n161["006_smoke.sql"]
  n160 --> n161
  n162["006_verify.sql"]
  n160 --> n162
  n163["capabilities.test.ts"]
  n156 --> n163
  n164["checkpoint.test.ts"]
  n156 --> n164
  n165["curriculum-consumer.test.ts"]
  n156 --> n165
  n166["curriculum-scanner.test.ts"]
  n156 --> n166
  n167["graduation-daemon.test.ts"]
  n156 --> n167
  n168["graduation-handlers.test.ts"]
  n156 --> n168
  n169["graduation-scanner.test.ts"]
  n156 --> n169
  n170["graph-daemon.test.ts"]
  n156 --> n170
  n171["graph-extractor.test.ts"]
  n156 --> n171
  n172["gui-graph.test.ts"]
  n156 --> n172
  n173["gui.test.ts"]
  n156 --> n173
  n174["health.test.ts"]
  n156 --> n174
  n175["kg.test.ts"]
  n156 --> n175
  n176["list-global-patterns.test.ts"]
  n156 --> n176
  n177["migrations.test.ts"]
  n156 --> n177
  n178["orchestrator.test.ts"]
  n156 --> n178
  n179["prune.test.ts"]
  n156 --> n179
  n180["search-graph-rag.test.ts"]
  n156 --> n180
  n181["trajectory-daemon.test.ts"]
  n156 --> n181
  n182["trajectory-stripper.test.ts"]
  n156 --> n182
  n183["trajectory-summarizer.test.ts"]
  n156 --> n183
  n184[".env.example"]
  n0 --> n184
  n185[".gitignore"]
  n0 --> n185
  n186["ARCHITECTURE.md"]
  n0 --> n186
  n187["CHANGELOG.md"]
  n0 --> n187
  n188["CLAUDE.md"]
  n0 --> n188
  n189["LICENSE"]
  n0 --> n189
  n190["marketplace.json"]
  n0 --> n190
  n191["package-lock.json"]
  n0 --> n191
  n192["package.json"]
  n0 --> n192
  n193["project_file_architecture.md"]
  n0 --> n193
  n194["README.md"]
  n0 --> n194
  n195["tsconfig.json"]
  n0 --> n195