Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,18 @@
- [ ] `docs/ARCHITECTURE.md` updated if module structure or counts changed (incl. version header)
- [ ] `docs/api/API_REFERENCE.md` updated if MCP / HTTP / CLI surface changed (incl. version header)
- [ ] `README.md` updated if user-facing features / install / Smart Mode framing changed
- [ ] README locales (de / vi / th / pt / ja / ko / zh-CN / zh-TW / es / fr) re-synced if `README.md` changed
- [ ] Version files (`package.json` + `.claude-plugin/plugin.json` + `.claude-plugin/marketplace.json`) bumped consistently if any version-bumping
- [ ] README locales (`README.de.md` / `README.zh-TW.md`) re-synced if `README.md` changed
- [ ] Version anchors listed in `CONTRIBUTING.md` updated consistently if bumping a version
- [ ] `dist/skills-manifest.json` regenerated via `npm run build` (required after ANY change to `.claude-plugin/`, `scripts/hooks/`, `skills/`, or version files)
- [ ] `memesh doctor` reports `Overall: PASS` (or `PASS_WITH_CONCERNS` only when the WARN is `Update status` — that's expected for an unreleased local version)

## Verification

<!-- Concrete evidence that the change works. Cite specific commands / outputs / screenshots. Lower the trust bar — say what you actually ran, not what should happen. -->

- [ ] `npx tsc --noEmit` clean
- [ ] `npm run typecheck` clean
- [ ] `npm run build` clean
- [ ] `npm test -- --run` passing (state count vs baseline if changed)
- [ ] `node scripts/run-tests-isolated.mjs` passing (report the actual exit code)
- [ ] If hooks were touched: full hook protocol run (real Claude Code Stop / PreToolUse / etc. payload, `memesh doctor` hook-activity check post-install green)
- [ ] If LLM flows were touched: `memesh telemetry` shows the new flow's rows after a manual run

Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ side of it.

Do not report a test result, a CI status or a benchmark number you did not
produce in this session. Paste the runner's actual output. `npm run verify:release` is the same gate the publish path runs, and
`scripts/check-doc-claims.mjs` — which it calls — checks every claim the public
documents make about the code.
`scripts/check-doc-claims.mjs` — which it calls — checks selected source-derived
documentation claims. Other descriptions still need source-backed review.

**Read the exit code, not a grep of the output.** `cmd 2>&1 | grep …` returns
*grep's* status and hides every line the pattern misses. Vitest prints
Expand Down
14 changes: 7 additions & 7 deletions CODEMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ docs/ # ARCHITECTURE.md, api/API_REFERENCE.md
### Recall / search (the LLM-free hot path)
- Ranking / scoring weights → `src/core/scoring.ts` (`rankEntities`)
- FTS5 + sqlite-vec query, access tracking → `src/knowledge-graph.ts`
- Recall operation (cross_project / namespace / include_archived) → `src/core/operations.ts` (`recallEnhanced`)
- Shared transport recall operation (cross_project / namespace / include_archived) → `src/core/operations.ts` (`recallWithConflicts`, backed by `recallEnhanced`)
- Vector index / embedding dimension / migration → `src/db.ts`, `src/core/embedder.ts`

### Write flows (remember / forget / learn / pin)
Expand All @@ -84,13 +84,13 @@ docs/ # ARCHITECTURE.md, api/API_REFERENCE.md

### Project identity + tags
- `getProjectName()` (git-remote-slug → repo-root → cwd-basename, cached) → `src/core/paths.ts`
(mirrored in `scripts/hooks/_shared.js` — F5 boundary; kept in sync by `tests/core/project-identity.test.ts`)
(shared through build-generated `scripts/hooks/_generated/core-paths.js`, imported by `_shared.js`)
- List / merge / rename `project:*` tags → `src/core/project-tags.ts` (backs `memesh kg rename-project`)
- Heuristic relation backfill (orphan connector) → `src/core/kg-backfill.ts`

### Config / capabilities / self-update
- Config read/write + capability detection + env auto-detect → `src/core/config.ts`
- Path resolution (HOME-first) → `src/core/paths.ts`
- Path resolution (explicit `MEMESH_DIR` / `MEMESH_DB_PATH` overrides, then HOME defaults) → `src/core/paths.ts`
- `memesh doctor` health check + real probes → `src/core/doctor.ts`
- npm version check / self-update → `src/core/version-check.ts`, `src/core/updater.ts`, `src/core/install-channel.ts`, `src/core/install-hooks.ts`

Expand All @@ -114,7 +114,7 @@ docs/ # ARCHITECTURE.md, api/API_REFERENCE.md
| `session-start.js` | SessionStart | inject top-N memories (additionalContext), banner, lesson warnings, auto-update |
| `pre-edit-recall.js` | PreToolUse Edit/Write | inject file-relevant memories |
| `guard-check.js` | PreToolUse Bash | enforce accepted lesson guards before risky repeats |
| `src/host-runtime/codex-session.ts` | SessionStart | register the exact configured Codex thread for metadata-only wakeups |
| `src/host-runtime/codex-session.ts` | SessionStart | register the exact configured Codex thread for bounded full-message native delivery |
| `session-summary.js` | Stop | auto-capture, LLM failure analysis, dream auto-trigger |
| `pre-compact.js` | PreCompact | end-of-context save |
| `post-commit.js` | PostToolUse Bash | git commit tracking |
Expand All @@ -130,7 +130,7 @@ is invoked by the session-start flow rather than registered directly in the mani

```
transport (cli/http/mcp) → validate (transports/schemas.ts, Zod)
→ operations.recallEnhanced()
→ operations.recallWithConflicts() → recallEnhanced()
→ knowledge-graph FTS5 + sqlite-vec → scoring.rankEntities()
→ conflict detection (storage/conflicts.ts) → result
```
Expand All @@ -141,7 +141,7 @@ The same `operations.ts` memory functions run identically from all three transpo

## Tests & docs

- Tests: `tests/` mirrors `src/`. Run `npm test -- --run` (pool: forks, not threads — native modules).
- Tests: `tests/` mirrors `src/`. Run `node scripts/run-tests-isolated.mjs` (throwaway HOME; forks pool, one worker).
Cross-hook contract gate: `tests/hooks/hook-output-contract.test.ts` (validates every hook's stdout against the real Claude Code contract).
- Owner-run live checks (never CI): `scripts/qa/live-journey.mjs` — `npm run qa:live-journey -- --host codex|claude`
drives a real Codex thread or an interactive Claude channel session and requires model-visible proof.
Expand All @@ -163,4 +163,4 @@ The same `operations.ts` memory functions run identically from all three transpo
than merely available. After publishing, `npm run qa:post-release`
(`scripts/qa/post-release.mjs`) checks registry acceptance, a fresh install from the registry,
and whether this machine is on the release — read-only, printing fixes rather than running them.
- Version anchors that must agree on a bump: `package.json`, both root entries in `package-lock.json`, `.claude-plugin/plugin.json`, `.claude-plugin/marketplace.json`, `herdr-plugin.toml`, `CHANGELOG.md`, `CODEMAP.md`, `docs/ARCHITECTURE.md`, and `docs/api/API_REFERENCE.md`. Run `npm run build` after to regenerate `dist/skills-manifest.json`.
- Version anchors that must agree on a bump: `package.json`, both root entries in `package-lock.json`, `.claude-plugin/plugin.json`, `.codex-plugin/plugin.json`, `.claude-plugin/marketplace.json`, `herdr-plugin.toml`, `CHANGELOG.md`, `CODEMAP.md`, `docs/ARCHITECTURE.md`, and `docs/api/API_REFERENCE.md`. Run `npm run build` after to regenerate `dist/skills-manifest.json`.
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ MeMesh is intentionally small. Changes should preserve that shape: a minimal MCP

## Prerequisites

- Node.js 22.5 or newer (`package.json` `engines.node`; Node 20 reached end of life on 2026-03-24)
- Node.js 22.13.0 or newer (see `package.json` `engines.node`)
- npm

## Local Setup
Expand All @@ -13,7 +13,7 @@ MeMesh is intentionally small. Changes should preserve that shape: a minimal MCP
npm install
npm run typecheck
npm run build
npm test -- --run
node scripts/run-tests-isolated.mjs
npm run test:packaged
```

Expand All @@ -27,7 +27,7 @@ Documentation is part of the change, not follow-up work. The CI's `Version coher
- Update `docs/api/API_REFERENCE.md` when the MCP / HTTP / CLI surface changes (and bump its `**Version**: ` line on a release).
- Update `docs/ARCHITECTURE.md` when module structure, storage behavior, or packaging flow changes (and bump its `**Version**: ` line on a release).
- Read `DESIGN.md` before any dashboard change that touches colour, type, spacing or an interaction, and update it when a token or rule changes. It is derived from `dashboard/src/styles/global.css`; when the two disagree the CSS is what ships, so fix whichever is wrong rather than leaving them apart.
- Keep version metadata coherent: `package.json` + **`package-lock.json` (both the root `version` and `packages[""].version`)** + `.claude-plugin/plugin.json` + `.claude-plugin/marketplace.json` `plugins[].version` + `CHANGELOG.md` `## [X.Y.Z]` header + the two `**Version**:` lines above must all match. The `node scripts/check-version-coherence.mjs` check (run as a CI step) catches partial bumps. `package-lock.json` is called out because it is the one that drifted silently across four releases (4.2.6 through 4.2.10) while every other anchor stayed correct — `npm version` updates it, hand-editing `package.json` does not.
- Keep version metadata coherent: `package.json`, both the root `version` and `packages[""].version` in `package-lock.json`, `.claude-plugin/plugin.json`, `.codex-plugin/plugin.json`, `.claude-plugin/marketplace.json` `plugins[].version`, `herdr-plugin.toml`, the `CHANGELOG.md` release header, and the `**Version**:` lines in `CODEMAP.md`, `docs/ARCHITECTURE.md`, and `docs/api/API_REFERENCE.md`. Run `node scripts/check-version-coherence.mjs` to check these anchors. `npm version` updates the lockfile; hand-editing `package.json` does not.
- After ANY change to `.claude-plugin/`, `scripts/hooks/`, `skills/`, or version files, run `npm run build` so `dist/skills-manifest.json` regenerates. Otherwise `memesh doctor` reports `Skills + hooks integrity FAIL` and users see "memesh setup is incomplete" in their dashboard. CI's `Doctor` step catches this before merge.

`CLAUDE.md` carries the same rules in the form an AI coding assistant reads. It is a pointer file — this document is the source of truth for anything that applies to a human contributor.
Expand Down
34 changes: 18 additions & 16 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The package is intentionally local-first and inspectable:
- one SQLite database under the user's control
- no cloud service required
- Claude Code hook integration for session-start, pre-edit recall, user-prompt-intent detection, post-commit capture, session-summary learning, and pre-compact save
- optional smarter retrieval and extraction when an LLM is configured
- optional semantic retrieval when an embedding provider is configured, and extraction when an LLM is configured

This repository is the standalone local package. Hosted workspace and enterprise operating-system products are intentionally out of scope for this package architecture.

Expand Down Expand Up @@ -218,7 +218,7 @@ Thin adapter: imports shared Zod schemas from `transports/schemas.ts`, validates
| Tool | Schema | Handler |
|------|--------|---------|
| `remember` | RememberSchema | Delegates to `operations.remember()` |
| `recall` | RecallSchema | Delegates to `operations.recallEnhanced()` |
| `recall` | RecallSchema | Delegates to `operations.recallWithConflicts()` |
| `forget` | ForgetSchema | Delegates to `operations.forget()` |
| `export` | ExportSchema | Delegates to `operations.exportMemories()` |
| `import` | ImportSchema | Delegates to `operations.importMemories()` |
Expand All @@ -231,7 +231,7 @@ Thin adapter: imports shared Zod schemas from `transports/schemas.ts`, validates

### transports/http/server.ts -- HTTP REST API Server

Express server exposed via `memesh serve` (default port 3737; the endpoint count is stated once, in the module list above, and checked against `server.ts` by `scripts/check-doc-claims.mjs`). Delegates all operations to `core/operations`. Includes `GET /v1/analytics` for computed health score, 30-day timeline, value metrics, and cleanup suggestions. See [HTTP REST API](#http-rest-api) in the API Reference.
Express server exposed via `memesh serve` (default port 3737; the endpoint count is stated once, in the module list above, and checked against `server.ts` by `scripts/check-doc-claims.mjs`). Delegates memory operations to `core/operations` and message actions to `transports/agent-messaging`. Includes `GET /v1/analytics` for computed health score, 30-day timeline, value metrics, and cleanup suggestions. See [HTTP REST API](api/API_REFERENCE.md#http-rest-api) in the API Reference.

### transports/cli/cli.ts -- CLI

Expand Down Expand Up @@ -307,12 +307,12 @@ not a second durable registry, and the read creates no message or receipt facts.
```
Tool call: recall({query, tag, limit})
-> Zod validation (RecallSchema)
-> recallEnhanced() in core/operations
-> recallWithConflicts() in core/operations, backed by recallEnhanced()
-> KnowledgeGraph.search() — FTS5 keyword match
-> supplementWithVectors() — sqlite-vec embedding similarity merge
-> rankEntities() applies multi-factor scoring (relevance, recency, frequency, confidence, impact)
-> KnowledgeGraph.findConflicts() checks for contradicts relations among results
-> If conflicts: return {entities, conflicts}; else return Entity[]
-> Return {entities, retrieval, conflicts?}; omit conflicts when empty
```

### Mine memory from transcripts (`dream run --from-transcripts`)
Expand All @@ -332,17 +332,19 @@ memesh dream run --from-transcripts (current project only)
-> accept creates the entity AND embeds it, so the next run recognises it
```

### Delete knowledge (forget)
### Archive knowledge or remove an observation (forget)

```
Tool call: forget({name})
Tool call: forget({name, observation?})
-> Zod validation (ForgetSchema)
-> KnowledgeGraph.deleteEntity(name)
-> SELECT entity by name (return false if not found)
-> SELECT all observations for entity (needed for FTS5 delete)
-> Delete FTS5 entry (contentless delete requires original indexed values)
-> DELETE FROM entities (CASCADE handles observations, relations, tags)
-> Return {deleted: true/false}
-> operations.forget()
-> With observation: KnowledgeGraph.removeObservation()
-> Return {observation_removed, name, observation,
remaining_observations, entity_found}
-> Without observation: KnowledgeGraph.archiveEntity()
-> Remove entity from search indexes and set status = 'archived'
in one transaction; preserve observations, relations, and tags
-> Return {archived: true, name}, or {archived: false, message}
```

---
Expand Down Expand Up @@ -424,7 +426,7 @@ Hooks are defined in `hooks/hooks.json` and executed by Claude Code at specific

- **Trigger**: `Stop` event (when Claude finishes responding)
- **Matcher**: `*` (all sessions)
- **Behavior**: Extracts session knowledge (files edited, errors fixed, decisions made) and stores it as entities in the knowledge graph. When LLM is configured (Level 1), additionally runs failure analysis to create structured `lesson_learned` entities from session errors. Also reads `~/.memesh/last-session-injected.json` to track recall effectiveness — updates `recall_hits` (entity name found in transcript) or `recall_misses` (not found). Opt-out via `MEMESH_AUTO_CAPTURE=false`
- **Behavior**: Extracts session knowledge (files edited, errors fixed, decisions made) and stores it as entities in the knowledge graph. When LLM is configured (Level 1), additionally runs failure analysis to create structured `lesson_learned` entities from session errors. Also reads matching session-injection records under the database directory's `sessions/` folder: explicit `[mem:id]` citations for injected memories increment `recall_hits`, after excluding hook-output echoes; `recall_misses` remains unchanged. Opt-out via `MEMESH_AUTO_CAPTURE=false`

### Pre-Compact (`scripts/hooks/pre-compact.js`)

Expand Down Expand Up @@ -470,7 +472,7 @@ MeMesh supports three integration tiers:
| | Custom apps | Direct stdio MCP connection |
| **HTTP API** | Custom apps/scripts | HTTP REST API (`memesh serve`, 37 endpoints) |

See [docs/platforms/](../platforms/) for platform-specific integration guides.
See [docs/platforms/](platforms/) for platform-specific integration guides.

### Anthropic API Feature Alignment

Expand Down Expand Up @@ -593,7 +595,7 @@ Session with errors

```
type: "lesson_learned"
name: "lesson-{project}-{errorPattern}" (upsert-safe; explicit `learn` without errorPattern → "lesson-{project}-{error-slug}")
name: "lesson-{project}-{errorPattern}" (upsert-safe; explicit `learn` without errorPattern → "lesson-{project}-{readable-prefix}-{digest}")
observations:
- "Error: <what went wrong>"
- "Root cause: <why>"
Expand Down
Loading