Skip to content
Merged
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
16 changes: 16 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "recall-marketplace",
"owner": {
"name": "edheltzel"
},
"description": "Persistent memory for AI coding agents",
"plugins": [
{
"name": "recall",
"source": "./plugins/recall-claude",
"description": "Persistent SQLite memory and retrieval tools for Claude Code",
"category": "productivity",
"tags": ["memory", "sqlite", "mcp"]
}
]
}
6 changes: 3 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Top-level directories, by purpose (one line each — not a file enumeration):
- `tests/` — `bun:test` suite mirroring source areas, plus install-lifecycle tests
- `benchmarks/` — wake-up context-efficiency benchmark harness
- `agent-skills/` — Agent Skills (SKILL.md, one per skill dir) installed to `~/.claude/skills`, `~/.pi/agent/skills`, `~/.omp/agent/skills` — the single `recall-*` command surface (the former `/Recall:*` slash commands, #228)
- `plugins/` — native host plugin bundles; Codex packages MCP plus generated host-adapted skills in `plugins/recall/`
- `plugins/` — native host plugin bundles, one per host: Codex in `plugins/recall/`, Claude Code in `plugins/recall-claude/`, each packaging MCP plus its own skill payload
- `docs/` — user-facing published docs + ADRs (`docs/adr/`) + agent skill docs (`docs/agents/`)
- `lib/` — shared bash for the install / update / uninstall lifecycle scripts
- `opencode/` — OpenCode host integration (plugins / hooks / guide)
Expand Down Expand Up @@ -131,7 +131,7 @@ Before adding code or content, search for an existing definition and extend it.
- **Modify extraction**: Edit `hooks/RecallExtract.ts` (self-contained, no build step)
- **Add a hook helper**: Create `hooks/lib/foo.ts` — kept standalone so hooks don't import from `src/`
- **Edit lifecycle scripts**: `install.sh`, `update.sh`, and `uninstall.sh` share `lib/install-lib.sh` — put shared bash functions there, not duplicated across scripts. Validate each with `bash -n`.
- **Add an Agent Skill**: Create `agent-skills/<name>/SKILL.md` — the install/update/uninstall scripts pick it up automatically (canonical copy under `$RECALL_SHARED_SKILLS_DIR`, per-file symlinks into `~/.claude/skills`, `~/.pi/agent/skills`, `~/.omp/agent/skills`). Also add `<name>` to `RECALL_SKILL_NAMES` in `uninstall.sh` so uninstall removes it.
- **Add an Agent Skill**: Create `agent-skills/<name>/SKILL.md` — the install/update/uninstall scripts pick it up automatically (canonical copy under `$RECALL_SHARED_SKILLS_DIR`, per-file symlinks into `~/.claude/skills`, `~/.pi/agent/skills`, `~/.omp/agent/skills`). Also add `<name>` to `RECALL_SKILL_NAMES` in `uninstall.sh` so uninstall removes it, and regenerate the native plugin bundles with `bun run build:codex-plugin` and `bun run build:claude-plugin` (their tests fail on drift).
- **Update the Claude guide**: Edit `FOR_CLAUDE.md` (installer copies it to `~/.claude/Recall_GUIDE.md`). Keep `FOR_OPENCODE.md` and `FOR_PI.md` in sync if lifecycle commands change.
- **Cut a release**: See `docs/releasing.md` for the tag → GitHub release flow.

Expand Down Expand Up @@ -175,7 +175,7 @@ Child AGENTS.md files own domain-specific local rules. Read the applicable one b
- [`benchmarks/AGENTS.md`](benchmarks/AGENTS.md) — wake-up context-efficiency benchmark harness
- [`docs/AGENTS.md`](docs/AGENTS.md) — user-facing published docs, ADRs, agent skill docs (never plans/specs)
- [`agent-skills/AGENTS.md`](agent-skills/AGENTS.md) — `recall-*` Agent Skill definitions
- [`plugins/AGENTS.md`](plugins/AGENTS.md) — native host plugin manifests, MCP registration, and generated adapters
- [`plugins/AGENTS.md`](plugins/AGENTS.md) — per-host native plugin manifests, MCP registration, and generated skill payloads

Owned at root (no child doc): lifecycle scripts (`install.sh`, `update.sh`, `uninstall.sh`) + their shared `lib/install-lib.sh`; platform guides (`FOR_CLAUDE.md`, `FOR_OPENCODE.md`, `FOR_PI.md`); `CONTEXT.md`; and `assets/` (banner + VHS demo tapes/gifs).

Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ Restart your agent (Claude Code, Pi, or OpenCode) to load the MCP server and hoo

Codex uses its native plugin marketplace instead of the lifecycle installer; see [Codex Integration](docs/CODEX_INTEGRATION.md).

Claude Code can additionally install Recall as a native plugin, which takes over the nine `recall-*` skills and the `recall-memory` MCP server while the installer keeps owning the lifecycle hooks. Existing installs need one reconciliation step — see [Claude Integration](docs/CLAUDE_INTEGRATION.md).

### First run: set your identity

Recall's tiered RecallStart injects a small identity file at the top
Expand Down Expand Up @@ -305,6 +307,7 @@ If you're an AI agent reading this repository:
| What you need | Where to find it |
| -------------------------------------------------------------- | ------------------------------------ |
| **Using Recall from Claude Code** (MCP tools, CLI, core rules) | [`FOR_CLAUDE.md`](FOR_CLAUDE.md) |
| **Installing the Claude Code plugin** | [`docs/CLAUDE_INTEGRATION.md`](docs/CLAUDE_INTEGRATION.md) |
| **Using Recall from OpenCode** | [`FOR_OPENCODE.md`](FOR_OPENCODE.md) |
| **Using Recall from Pi** | [`FOR_PI.md`](FOR_PI.md) |
| **Using Recall from Codex** | [`docs/CODEX_INTEGRATION.md`](docs/CODEX_INTEGRATION.md) |
Expand All @@ -316,7 +319,7 @@ Recall is built around two integration surfaces: **MCP** (memory search and add,

| Agent | MCP | Lifecycle hooks | Status |
| ------------------------------------------------------------- | :-: | :--------------------------------------------------------: | ------------------------------------- |
| [**Claude Code**](https://claude.com/claude-code) | ✅ | ✅ Stop · SessionStart · PreCompact | **Stable** — reference implementation |
| [**Claude Code**](https://claude.com/claude-code) | ✅ | ✅ Stop · SessionStart · PreCompact | **Stable** — reference implementation; native plugin ships skills + MCP |
| [**Pi**](https://pi.dev/) | ✅ | ⚠ Beta — `recall-compaction` + `recall-extract` extensions | In progress |
| [**OpenCode**](https://opencode.ai/) | ✅ | ⚠ Alpha — `recall-extract` plugin | In progress |
| [**Codex CLI**](https://github.com/openai/codex) | ✅ | — native plugin, explicit dump only | MCP + skills available |
Expand All @@ -338,6 +341,7 @@ Have an agent you'd like to see supported? [Open an issue](https://github.com/ed
| Codebase Map (local) | Interactive visual map at `.agents/atlas/artifacts/2026-06-10-recall-codebase-map.html` — generated from the codegraph index, not committed (`.agents/` is gitignored) |
| [Agent Skills](docs/agent-skills.md) | `recall-*` skills for Claude Code, Pi, and omp |
| [Codex Integration](docs/CODEX_INTEGRATION.md) | Native plugin install, MCP coverage, and lifecycle limits |
| [Claude Integration](docs/CLAUDE_INTEGRATION.md) | Native plugin install, plugin/installer ownership split, migration |
| [Upgrading](docs/upgrading.md) | Update, backup, migration system |
| [Troubleshooting](docs/troubleshooting.md) | Common issues and fixes |
| [Changelog](CHANGELOG.md) | Release notes and breaking changes |
Expand Down
3 changes: 2 additions & 1 deletion docs/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ User-facing published documentation: installation, CLI / MCP / agent-skill refer

## Ownership

- Reference & guides — `installation.md`, `cli-reference.md`, `mcp-tools.md`, `agent-skills.md`, `architecture.md`, `troubleshooting.md`, `releasing.md`, `upgrading.md`, `OPENCODE_INTEGRATION.md`, `PI_INTEGRATION.md`, `CODEX_INTEGRATION.md`
- Reference & guides — `installation.md`, `cli-reference.md`, `mcp-tools.md`, `agent-skills.md`, `architecture.md`, `troubleshooting.md`, `releasing.md`, `upgrading.md`, `OPENCODE_INTEGRATION.md`, `PI_INTEGRATION.md`, `CODEX_INTEGRATION.md`, `CLAUDE_INTEGRATION.md`
- `adr/` — architectural decision records
- `agents/` — agent skill docs (`issue-tracker.md`, `triage-labels.md`, `board-status.md`, `domain.md`, `worker-flow.md`, `dox-framework.md`)

Expand All @@ -18,6 +18,7 @@ User-facing published documentation: installation, CLI / MCP / agent-skill refer
- ADRs are numbered and append-only: change a decision by adding a new `NNNN-*.md`; don't rewrite a past ADR's decision.
- Keep docs in sync with behavior — a command, MCP, or lifecycle change must update the matching reference (`cli-reference`, `mcp-tools`, `agent-skills`, `installation`, `upgrading`).
- Host integration guides stay aligned with their root counterparts (`FOR_OPENCODE.md`, `FOR_PI.md`). Codex's canonical guide is `CODEX_INTEGRATION.md` because its native plugin is repository-distributed rather than lifecycle-installed.
- `CLAUDE_INTEGRATION.md` covers Claude's native plugin and how it divides ownership with the lifecycle installer (plugin: skills + MCP; installer: hooks). `FOR_CLAUDE.md` stays the agent-facing usage guide — keep the split, don't merge them.

## Work Guidance

Expand Down
125 changes: 125 additions & 0 deletions docs/CLAUDE_INTEGRATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# Claude Code Integration

[Back to README](../README.md)

Recall ships two Claude Code surfaces, and they own different things:

- The **lifecycle installer** (`install.sh`) owns hooks — `Stop`, `SessionStart`, `PreCompact` — which is how Recall captures sessions automatically and injects the tiered L0/L1 context block.
- The **native plugin** owns the nine `recall-*` skills and the `recall-memory` MCP server, packaged behind one manifest instead of user-level configuration.

The checked-in marketplace manifest is `.claude-plugin/marketplace.json`, and the plugin bundle is `plugins/recall-claude/`.

Running only the installer is still fully supported; the plugin is additive.

## Install

Install Recall first so `recall-mcp` is on `PATH`:

```bash
bun install -g recall-memory
recall init
```

Then add this repository as a marketplace and install its plugin:

```bash
claude plugin marketplace add /absolute/path/to/Recall
claude plugin install recall@recall-marketplace
```

The repository path is deliberate for the current checked-in marketplace. A future remote marketplace can remove that local-clone prerequisite after its distribution and update policy are defined.

## What MCP covers

MCP is the primary cross-host seam.

The plugin exposes all nine Recall operations: `memory_search`, `memory_hybrid_search`, `memory_recall`, `context_for_agent`, `memory_add`, `memory_stats`, `loa_show`, `memory_dump`, and `decision_update`.

They query and write the same SQLite store as the CLI.

The bundled `.mcp.json` carries no `env` block, so the server resolves its database from `RECALL_DB_PATH` in Claude's environment, falling back to `~/.agents/Recall/recall.db`. Export `RECALL_DB_PATH` in your shell when the store lives elsewhere.

## Migrating an existing install

An existing Recall install keeps working. It also keeps its own copies of what the plugin now ships, and Claude does **not** resolve that for you:

- **Skills.** `~/.claude/skills/recall-*` and the plugin's nine skills both load.
- **MCP.** Claude namespaces plugin components, so the plugin registers as `plugin:recall:recall-memory` while a user-scope `recall-memory` keeps its own name. Both connect, and the same nine tools are exposed twice from two processes.

Claude collapses the two MCP entries only when they resolve to an identical command and environment. `install.sh` writes `bun run <path>` plus an `env` block, so a real existing install always duplicates.

`install.sh` and `update.sh` reconcile this, and both are idempotent — run either after installing the plugin:

```bash
./update.sh
```

With the plugin active they:

1. Remove the `~/.claude/skills/recall-*` symlinks that point into `~/.agents/Recall/shared/skills/`. Only Recall-owned symlinks are removed; real files, user-authored skills, and other tools' links are left alone, and a skill directory is deleted only when it is already empty.
2. Remove the user-scope `recall-memory` MCP registration, so the plugin's is the only one left.
3. Leave hooks and canonical files untouched.

Skill canonicals under `~/.agents/Recall/shared/skills/` are still refreshed, because Pi, omp, and `recall doctor` read them.

**A registration pinned to a non-default database is kept, not removed.** The plugin's bundled config cannot carry your custom path, so deleting the entry would silently repoint Recall at the default file and your history would read as empty.

Custom-database installs therefore keep both surfaces by design, and re-running `update.sh` will not change that — the decision is made from the path stored in the entry, which stays custom. Collapsing them is a deliberate manual step, because only you can confirm the environment Claude actually launches with:

```bash
export RECALL_DB_PATH=/path/to/your/recall.db # where you launch Claude from
claude mcp list # confirm plugin:recall:recall-memory connects
claude mcp remove recall-memory -s user # then drop the duplicate
```

`recall doctor` reports the state under **Claude native plugin**: `PASS` when the plugin is the sole owner, `WARN` listing the duplicates when a legacy copy is still present, `INFO` when the plugin is absent or disabled.

Uninstalling is a separate, user-owned action — `uninstall.sh` does not remove the plugin:

```bash
claude plugin uninstall recall@recall-marketplace
./install.sh # restores the lifecycle-owned skills and MCP registration
```

## What the plugin does not cover

**Lifecycle hooks are not in the bundle.** Plugin hooks *merge* with `settings.json` hooks rather than replacing them, so shipping `Stop`/`SessionStart`/`PreCompact` in the plugin would run every capture twice for anyone who also ran `install.sh` — duplicate extractions into the same database. Auto-capture, tiered L0/L1 injection, and pre-compaction flushing therefore remain lifecycle-installed.

This is the one place where the plugin is deliberately not self-sufficient: a plugin-only user gets skills and MCP, not automatic capture.

## Differences from the Codex package

Named explicitly rather than assumed away, because identical `SKILL.md` bytes do not imply identical behavior across hosts:

| | Codex (`plugins/recall/`) | Claude (`plugins/recall-claude/`) |
| --- | --- | --- |
| Manifest | `.codex-plugin/plugin.json` | `.claude-plugin/plugin.json` |
| Marketplace | `.agents/plugins/marketplace.json` | `.claude-plugin/marketplace.json` |
| Skill payload | Generated adapters with a Codex routing preamble | Byte-verbatim copies of `agent-skills/` |
| `disable-model-invocation` | Stripped; replaced by `agents/openai.yaml` because Codex does not interpret it | Kept — it is Claude's own frontmatter contract |
| MCP naming | `recall-memory` | `plugin:recall:recall-memory` (namespaced) |
| Pre-existing install to reconcile | None — Codex had no lifecycle installer | Nine skill symlinks and a user-scope MCP entry |
| Lifecycle capture | Not implemented on any surface | Implemented, but by the installer's hooks — not the plugin |

The Claude bundle needs no routing preamble because `agent-skills/` is already authored against Claude's frontmatter. Rewriting the bodies would change behavior relative to the skills users already have, which is the opposite of a safe migration.

Skills are copied rather than symlinked into the bundle. Claude drops symlinks that leave the plugin root when a plugin is installed from a local path, and a checkout with `core.symlinks=false` would degrade the payload silently.

## Current boundaries

The following are unresolved rather than guessed:

- **End-to-end enforcement of `disable-model-invocation` for plugin-shipped skills is unverified.** The installed CLI carries the runtime enforcement for the field, and the bundle ships it unchanged, but confirming that a plugin-loaded `recall-dump` is explicit-only needs an authenticated session — and `claude plugin validate --strict` does not inspect skill frontmatter at all, so passing validation is not evidence.
- Skill *invocation* names under a plugin. `claude plugin details` lists all nine by their canonical names; the namespacing observed for MCP was not separately confirmed for skills.
- Remote marketplace publication, update, and release ownership.
- The installed plugin-cache path as a durable runtime dependency.

None of these block the nine MCP operations or the skill surface.

## Development verification

`bun run build:claude-plugin` regenerates the bundle's skills from the canonical `agent-skills/` sources.

`bun test tests/plugins/claude-plugin.test.ts` asserts one plugin identity across the manifests, that the checked-in skills are byte-identical to their canonical sources, and that no hooks ship in the bundle.

`bun run test:e2e:claude-plugin` builds Recall, then against the **current local Claude CLI**: validates both manifests in strict mode, installs the plugin into a disposable `HOME`, asserts nine skills and the MCP server load from the bundle, seeds a legacy install and proves the migration removes both duplicates twice over without touching a user-authored skill, exercises all nine MCP tools against a disposable `RECALL_DB_PATH`, and verifies that neither the production database nor the real `~/.claude` changed.
Loading