8000 GitHub - anortham/goldfish: Developer memory system for Claude Code: project-local markdown checkpoints, cross-project recall, and plan tracking — no database, just files. · GitHub
[go: up one dir, main page]

Skip to content
anorthamPublic

About

Developer memory system for Claude Code: project-local markdown checkpoints, cross-project recall, and plan tracking — no database, just files.

Resources

Contributing

Stars

3 stars

Watchers

2 watching

Forks

Latest commit

 

History

347 Commits

Folders and files

Repository files navigation

Goldfish 🐠

Website: anortham.github.io/goldfish

An evidence ledger for AI coding sessions. Checkpoints capture what changed and why; briefs hold durable strategic direction; recall pulls both back when the next session needs context. Everything lives as markdown in your repo, so it travels with the code, diffs in PRs, and outlasts any single harness.

Goldfish is a cross-client MCP memory system. Claude Code, Codex, and Cursor can install it as a plugin — tools, skills, and a session-start hook that loads Goldfish's guidance into each new session. OpenCode and Antigravity can discover repo-local Goldfish skills from .agents/skills, and VS Code with GitHub Copilot can use the MCP server plus repo instructions.

Version 8.0.10 -- Checkpoint description files are now restricted to the selected workspace. See CHANGELOG.md for details.


Why Goldfish?

Coding harnesses already plan, summarize, and recover from compaction. What they don't do is keep a durable record of why a project moved the way it did, in a place the next session (or the next harness) can read.

Goldfish is git for intent: a source-controlled, harness-agnostic ledger of decisions, milestones, and direction. Three MCP tools (checkpoint, recall, brief) and skills for common workflows, with markdown as the source of truth.


Client Setup

Prerequisites: Bun runtime (v1.0+)

Start by cloning the repository and installing dependencies:

git clone https://github.com/anortham/goldfish.git
cd goldfish
bun install

Claude Code

Claude Code is the fullest adapter today. You get MCP tools, slash-command skills (/checkpoint, /recall, /brief, /brief-status, /handoff, /report-issue, /standup), and a session-start hook that loads Goldfish's memory guidance into each new session.

Install from the marketplace:

# Add the Goldfish repository as a plugin marketplace
/plugin marketplace add anortham/goldfish

# Install the plugin for your user
/plugin install goldfish@goldfish

# Or scope it to the current project
/plugin install goldfish@goldfish --scope project

Install from a local clone:

claude plugin install /path/to/goldfish

For development, load the plugin from the local dir 8000 ectory each time:

claude --plugin-dir /path/to/goldfish

The session-start hook. The plugin registers a SessionStart hook that injects Goldfish's usage guidance (checkpoint triggers, tool reference, brief lifecycle) at the start of each session — this is what keeps agents checkpointing even when tool descriptions are deferred. It fires once at session start (and again after /clear or a context compaction), prints static text, makes no tool calls, and writes no state. It needs no setup: sessions started after the plugin is installed (or updated to 7.5+) pick it up automatically. You can inspect it anytime with /hooks.

Once the plugin is loaded, Goldfish works through manual invocation and agent-driven calls:

  1. Session starts -- run /recall (or let the agent call recall({ workspace: "/absolute/path/to/project" })) to restore recent checkpoints and the active brief
  2. You work -- checkpoint with /checkpoint at meaningful milestones
  3. Direction persists -- save a brief with /brief when goals, constraints, or success criteria should survive the session
  4. Next session -- recall replays the same context

Cursor

Cursor runs Goldfish as a native Cursor Plugin. The bundle includes the MCP server, the skills listed below, and a native hook (sessionStart). Cursor discovers the repo-local .agents/skills/ mirror too, so the skills can be invoked with /brief, /brief-status, /checkpoint, /handoff, /recall, /report-issue, and /standup when the client is using repo-local skill discovery.

To test the local plugin, place the repository at ~/.cursor/plugins/local/goldfish with a symlink on macOS/Linux, a junction on Windows, or a full copy on either platform.

On macOS/Linux, create a symlink from the absolute Goldfish checkout:

mkdir -p ~/.cursor/plugins/local
ln -s /absolute/path/to/goldfish ~/.cursor/plugins/local/goldfish

On Windows PowerShell, create a junction:

$cursorLocal = Join-Path $env:USERPROFILE ".cursor\plugins\local"
$pluginPath = Join-Path $cursorLocal "goldfish"
New-Item -ItemType Directory -Force -Path $cursorLocal | Out-Null
New-Item -ItemType Junction -Path $pluginPath -Target "C:\path\to\goldfish"
# Or copy instead of creating the junction:
# Copy-Item -Recurse -Force "C:\path\to\goldfish" $pluginPath

Restart Cursor or run Developer: Reload Window, then open Customize and verify that Goldfish appears as an installed plugin. The native assets are .cursor-plugin/plugin.json, mcp.json, skills/, and hooks/cursor-hooks.json.

For a user-level Cursor registration, pass workspace as the conversation's host-native absolute project root on every checkpoint, brief, and current-project recall call. Omission and "current" work only when a fixed absolute GOLDFISH_WORKSPACE or supported legacy Roots binds the server. Cwd, registry, and parent-walk candidates are suggestions only. If Goldfish reports an unbound workspace, retry with {"workspace":"<absolute-project-root>"}.

For a fixed project-level binding, use the project .cursor/mcp.json configuration:

{
  "mcpServers": {
    "goldfish": {
      "type": "stdio",
      "command": "bun",
      "args": ["run", "/absolute/path/to/goldfish/src/server.ts"],
      "env": { "GOLDFISH_WORKSPACE": "${workspaceFolder}" }
    }
  }
}

Add that to the project .cursor/mcp.json (or user config scoped to the project) before using mutating tools. Keep the absolute path to src/server.ts; ${workspaceFolder} binds the server to the open project.

Codex CLI / Desktop

Recommended: install the plugin. Goldfish ships a Codex plugin manifest (.codex-plugin/plugin.json) that delivers everything in one install — the MCP server (tools), the skills listed below, and a SessionStart hook that loads Goldfish's memory guidance into each new session.

codex plugin marketplace add anortham/goldfish
codex plugin add goldfish@goldfish

This same install covers the Codex desktop app: restart it after installing and it picks up the plugin.

Updating. codex plugin remove deletes the installed copy but keeps the marketplace snapshot, so a plain remove-and-add reinstalls the same version. Refresh the snapshot first:

codex plugin marketplace upgrade
codex plugin remove goldfish@goldfish
codex plugin add goldfish@goldfish

One-time hook trust review. Installing or enabling a plugin does not automatically trust its hooks — Codex skips them until you approve. Run codex, open /hooks, review and trust Goldfish's SessionStart hook, then start a new thread. Until you do, tools and skills work but the session-start guidance stays silent.

The hook is deliberately minimal: it fires once at session start (and after /clear or a compact), prints static guidance, makes no tool calls, and writes no state.

Manual alternative: .codex/config.toml. If you would rather not install the plugin, register the server yourself. Codex shares MCP configuration between the CLI and the IDE extension through ~/.codex/config.toml, and it discovers repo-local skills from .agents/skills.

Codex Desktop does not send MCP roots. With a user-level registration, pass workspace as the conversation's host-native absolute project root on every checkpoint, brief, and current-project recall call. For a project-level registration, set a fixed absolute GOLDFISH_WORKSPACE in that project's .codex/config.toml.

Add Goldfish to a trusted project-local .codex/config.toml:

[mcp_servers.goldfish]
command = "bun"
args = ["run", "/absolute/path/to/goldfish/src/server.ts"]
cwd = "/absolute/path/to/your/project"
env = { GOLDFISH_WORKSPACE = "/absolute/path/to/your/project" }

You can put Goldfish in ~/.codex/config.toml too, but that pins GOLDFISH_WORKSPACE to one repo. For Codex Desktop across multiple repos, keep the server entry in each project's .codex/config.toml.

Goldfish skills in .agents/skills are discovered automatically when you launch Codex inside the repository; use their discovered names directly when your Codex client exposes slash commands.

OpenCode

OpenCode loads local MCP servers from opencode.json and can also discover repo-local skills from .agents/skills.

Add Goldfish to your opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "goldfish": {
      "type": "local",
      "command": ["bun", "run", "/absolute/path/to/goldfish/src/server.ts"],
      "enabled": true
    }
  }
}

OpenCode walks up the repository and loads matching .agents/skills/*/SKILL.md, so the checked-in Goldfish skills are available without extra copying.

This repository ships a working opencode.json (paths relative to the repo root) you can copy as a starting point.

Antigravity

Antigravity (Google Antigravity CLI and IDE) loads MCP servers from ~/.gemini/config/mcp_config.json and automatically discovers repo rules (AGENTS.md) and repo-local skills from .agents/skills.

Add Goldfish to your ~/.gemini/config/mcp_config.json:

{
  "mcpServers": {
    "goldfish": {
      "command": "bun",
      "args": ["run", "/absolute/path/to/goldfish/src/server.ts"]
    }
  }
}

Or add it using the Antigravity CLI:

agy mcp add goldfish bun run /absolute/path/to/goldfish/src/server.ts

Antigravity walks up from your current working directory to the repository root and discovers .agents/skills/*/SKILL.md when working inside this repository. To use the skills listed below (/brief, /brief-status, /checkpoint, /handoff, /recall, /report-issue, /standup) across all your projects, register them in ~/.gemini/config/skills.json:

{
  "entries": [
    {
      "path": "/absolute/path/to/goldfish/skills"
    }
  ]
}

With a user-level Antigravity registration, pass workspace as the conversation's host-native absolute project root on every checkpoint, brief, and current-project recall call: recall({ workspace: "/absolute/path/to/project" }).

VS Code with GitHub Copilot

VS Code supports project-level MCP config in .vscode/mcp.json, supports the full MCP feature set, and can pair Goldfish with repo instructions for better memory habits.

This repository ships a working .vscode/mcp.json you can copy. To create your own:

mkdir -p .vscode

Create .vscode/mcp.json:

{
  "servers": {
    "Goldfish": {
      "type": "stdio",
      "command": "bun",
      "args": ["run", "/absolute/path/to/goldfish/src/server.ts"]
    }
  }
}

With a user-level VS Code registration, pass workspace as the conversation's host-native absolute project root on every checkpoint, brief, and current-project recall call. A project-level registration may omit it when GOLDFISH_WORKSPACE is fixed to an absolute path or a supported legacy Roots binding supplies it. Set it explicitly when the client does not provide Roots:

{
  "servers": {
    "Goldfish": {
      "type": "stdio",
      "command": "bun",
      "args": ["run", "/absolute/path/to/goldfish/src/server.ts"],
      "env": {
        "GOLDFISH_WORKSPACE": "${workspaceFolder}"
      }
    }
  }
}

If you want Copilot to consistently checkpoint and recall with Goldfish, copy docs/goldfish-checkpoint.instructions-vs-code.md into your repo's .github/instructions/ folder (or adapt it to your preferred instructions layout). That file gives VS Code users a ready-made Goldfish instruction set instead of starting from a blank page.

If you want the closer Claude-style experience, VS Code's agent plugins preview can also load Claude-format plugins. Goldfish already ships .claude-plugin/plugin.json, which VS Code can detect for plugin skills.

Two ways to wire that up:

  • Register a local Goldfish clone with the chat.pluginLocations setting in settings.json
  • Add a marketplace with chat.plugins.marketplaces if you want shared discovery instead of a direct local path

Use .vscode/mcp.json when you only want the MCP tools. Use the plugin path when you want skills as well.

Any MCP Client

Goldfish is a standard MCP server, so any client that can launch a local stdio server can use the three core tools (checkpoint, recall, brief) and the server instructions.

Goldfish 7.7.0 uses the split MCP TypeScript SDK v2 and serves both protocol eras through the same stdio command:

  • Legacy 2025-era clients keep working, including roots discovery for clients that still provide it.
  • Modern stateless 2026-07-28 clients require the workspace tool argument as a host-native absolute project root for user-level calls. A project-level server may use a fixed absolute GOLDFISH_WORKSPACE; process cwd, registry, and parent-walk results never authorize access.

What varies by client:

  • Skills depend on whether the harness reads repo-local skill files such as .agents/skills
  • Workspace binding is per-call for user-level registrations. Pass the conversation's host-native absolute project root on every checkpoint, brief, and current-project recall call. Omission and "current" are not user-level identity.
  • Cross-project recall uses recall({ workspace: "all" }) only when requested explicitly. It is never a fallback for missing current-project identity, and "all" is invalid for checkpoint and brief.

Instruction-Only Harnesses (Zed, Amp, Jules, Cursor rules, Windsurf, Cline, Kiro, ...)

Many harnesses read a repo instruction file (AGENTS.md, .cursor/rules/, .windsurf/rules/, .clinerules/, .kiro/steering/) but never surface MCP server instructions. For those, copy the generated usage ruleset docs/agent-instructions/goldfish-usage.md into your repo's instruction surface.

Honest caveat: this gives the agent Goldfish behavior rules only. The checkpoint/recall/brief tools still need the MCP server registered in that harness (see the sections above); without it the rules have nothing to call.

The full support matrix, including what was deliberately not built and why, lives in docs/agent-portability.md.


How It Works

Checkpoint -- Save Progress

Checkpoints capture what you did, why, and how. They're saved as individual markdown files with YAML frontmatter.

You: "Fix the authentication timeout bug"

Claude: [works on the bug]
Claude: [checkpoints: "Fixed JWT timeout by implementing refresh token rotation.
         Root cause was single-use token with no re
8BD0
newal path. Added
         RefreshTokenStore with 7-day expiry. Auth tests passing."]

[Session crashes or compacts]

You: [new session]
Claude: [auto-recalls checkpoint, picks up where it left off]

Saved to: {project}/.memories/2026-02-14/143022_a1b2.md

Recall -- Restore Context

Recall returns recent checkpoints, the active brief, and optional cross-project summaries. Agents call it when resuming prior work or when earlier decisions matter; users can run /recall for targeted queries.

recall({ workspace: "/absolute/path/to/project" })                              # Last 5 checkpoints, no date window
recall({ workspace: "/absolute/path/to/project", since: "2h" })                 # Last 2 hours
recall({ workspace: "/absolute/path/to/project", search: "auth bug" })          # BM25 search across descriptions
recall({ workspace: "/absolute/path/to/project", days: 7, limit: 20, full: true }) # Extended history with metadata
recall({ workspace: "all", days: 1 })       # Cross-project (for standups)
recall({ workspace: "/absolute/path/to/project", file: "workspace.ts" })            # Intent-blame: who touched this file?
recall({ workspace: "/absolute/path/to/project", symbol: "resolveWorkspace" })      # Intent-blame: who touched this symbol?
recall({ workspace: "/absolute/path/to/project", limit: 0 })                         # Active brief only

When you search with recall({ workspace: "/absolute/path/to/project", search: "..." }), results are compact by default so agents get dense, low-token snippets. Pass full: true to return full descriptions and metadata instead.

Brief -- Track Durable Direction

Briefs are compact strategic markdown documents that survive across sessions. They appear at the top of every recall response.

---
id: auth-system-redesign
title: Auth System Redesign
status: active
created: 2026-02-10T10:00:00.000Z
updated: 2026-02-14T14:30:00.000Z
tags: [auth, architecture, security]
---

## Goal

Redesign auth around durable refresh-token sessions.

## Why Now

Timeout bugs and session drift keep burning time across sessions.

## Constraints

- Keep one-release compatibility for existing auth clients
- Do not break admin SSO

## Success Criteria

- Recall and checkpoint evidence line up with the new auth direction
- Standup reports stay consistent with the brief and recent checkpoints

## References

- docs/plans/2026-02-14-auth-system-redesign.md

Saved to: {project}/.memories/briefs/auth-system-redesign.md


Skills

Goldfish ships 7 skills, listed below. Claude Code, Codex, and Cursor plugin installs expose them directly; OpenCode and Antigravity (and Codex or Cursor without the plugin) discover the same skill content from .agents/skills/.

Skill What It Does
/brief Create and manage durable strategic briefs
/brief-status Assess progress against the active brief
/checkpoint Save a checkpoint with rich description and tags
/handoff Produce a structured session-resumption summary for a returning or different agent
/recall Restore context from recent checkpoints and the active brief
/report-issue File a GitHub issue against Goldfish with versions and recent server errors, after you approve the text
/standup Generate a cross-project standup report

skills/ is the canonical source. .agents/skills/ is a checked-in mirror for clients that scan repo-local skills.


Storage Format

Markdown in .memories/ is the source of truth. Goldfish writes no derived state to disk. Small in-memory caches reuse parsed checkpoints and search indexes only while source directory fingerprints match; no cache or index is persisted.

Because every checkpoint and brief is plain markdown with YAML frontmatter, .memories/ also works with generic markdown-database tools. For example, open your project in Obsidian and point a Base at .memories/ to browse checkpoints as a sortable, filterable table — no Goldfish code involved.

Project-Level Storage

your-project/
  .memories/
    2026-02-13/
      091500_a1b2.md          # Individual checkpoint (YAML frontmatter + markdown)
      143022_c3d4.md
    2026-02-14/
      101530_e5f6.md
    razorback-review.md       # Ordinary report; Goldfish recall does not index this root-level file
    briefs/
      auth-system-redesign.md  # Brief (YAML frontmatter + markdown body)
      api-v2-migration.md
    .active-brief              # Contains the active brief ID

Legacy .memories/plans/ and .active-plan paths are still read so older repos keep working, but new writes land in the brief paths above.

Goldfish recall searches checkpoints in date-named directories and the active brief; it does not index arbitrary Markdown files at the .memories/ root. Another tool can keep a detailed report at .memories/razorback-review.md and save a normal checkpoint that points to it:

checkpoint({
  workspace: "/absolute/path/to/project",
  description: "## What\nRazorback review completed; full report: `.memories/razorback-review.md`.\n\n## Why\nThe findings need follow-up.\n\n## How\nThe report contains the supporting evidence.\n\n## Impact\nThe pointer makes the handoff searchable.",
  next: "Read `.memories/razorback-review.md` and address its findings."
})

The explicit workspace is the project root. The checkpoint's description and next field make the report discoverable through normal recall while the detailed report remains an ordinary file.

Checkpoint File Format

---
id: checkpoint_a1b2c3d4
timestamp: 2026-02-14T14:30:22.000Z
tags:
  - bug-fix
  - auth
git:
  branch: fix/jwt-timeout
  commit: abc1234
  files:
    - src/auth/jwt.ts
    - tests/auth.test.ts
actor:
  harness: claude-code
  model: claude-opus-4
  session: 7f3a2c
  user: murphy
  git_user: Murphy
  git_email: murphy@example.com
summary: Fixed JWT timeout bug with refresh token rotation
---

Fixed JWT validation bug where expired tokens were accepted. Root cause
was inverted expiry check in validateToken(). Added test coverage for
the edge case and verified the fix prevents token reuse attacks.

Git context comes from the workspace path of the call. When you work in a git worktree, pass the worktree path: the checkpoint lands in that worktree's .memories/ and records the worktree branch. Older checkpoints may carry a git.worktree field; new saves do not write it.

actor records who and what saved the checkpoint, observed by the server itself — never from tool arguments. GOLDFISH_HARNESS, GOLDFISH_MODEL, and GOLDFISH_SESSION env vars beat MCP-observed values; user is the OS username; git_user and git_email come from git config in the workspace. Fields that cannot be observed are omitted, and the block disappears entirely when nothing is observable.

Cross-Project Registry

~/.goldfish/
  registry.json              # Auto-populated list of projects using Goldfish

The registry tracks which projects have .memories/ directories. It is populated automatically on checkpoint save and used by cross-project recall for standup reports.


Cross-Project Features

Standup Reports

Standup reports are built from briefs and checkpoints, not docs/plans/.

The /standup skill aggregates work across all registered projects:

## Standup -- February 14, 2026

### goldfish
- Brief says the current push is cross-client portability for Goldfish
- Checkpoints show roots support landed and repo-local skill mirroring landed

> **Next:** Finish client docs and keep standup scoped to memory evidence

### api-gateway
- Fixed rate limiter race condition in Redis cluster mode

> **Blocked:** Waiting on DevOps for staging Redis cluster provisioning

Cross-project recall uses ~/.goldfish/registry.json to discover projects, then reads each project's .memories/ directory.

Each registered worktree is a separate workspace. A committed checkpoint shared by several worktrees can therefore appear more than once, and duplicates can use slots in a bounded result window. Recall does not deduplicate those matches. Use a specific workspace when duplicates crowd unique project history out of the results. Reconsider deduplication only if repeated real standups lose unique project history to duplicate slots.


Architecture Decisions

This is iteration #5 of a developer memory system. Each iteration taught something:

  1. Original Goldfish (TypeScript) -- Good concepts, critical bugs: race conditions, date handling
  2. Tusk (Bun + SQLite) -- Fixed bugs, added complexity, hook spam disaster
  3. .NET rewrite -- Over-engineered, never finished
  4. Goldfish 4.0 (Bun + Markdown) -- Radical simplicity, centralized ~/.goldfish/ storage, proved the markdown-only approach
  5. Goldfish 5.x-6.x -- Claude Code plugin, project-local .memories/, hybrid semantic recall, consolidation, hooks
  6. Goldfish 7.0 -- Subtract sprint: removed hooks, semantic stack, consolidation, and the plan tool; settled on Orama BM25 over markdown and brief-first storage

Foundational decisions (load-bearing since v5):

Decision Rationale
Markdown storage, no database Human-readable, git-friendly, transparent
Project-local .memories/ Git-committable, travels with the codebase
Individual checkpoint files No merge conflicts, no corruption from concurrent writes
Atomic file operations Write-to-temp then rename prevents corruption on crash
UTC timestamps everywhere No timezone bugs (learned the hard way in v1)
Quality-focused behavioral language Directive about checkpoint quality, restrained about frequency
Evidence-based features only Complexity is added only when real usage demands it

What v7 subtracted, and why:

Decision Rationale
Orama BM25 over hybrid fuse + embeddings LLM-issued queries are well-formed; relevance ranking matters more than typo tolerance, and BM25 is a fraction of the runtime weight
No hooks (reversed in 7.5, narrowly) The spam came from recurring hooks, and those stay banned. When harness changes capped server instructions at 2k and deferred tool descriptions out of sight, a SessionStart-only static hook became the fix, not the disease — see docs/agent-portability.md
No consolidation Token math was net-negative; reading consolidated digests cost more than reading checkpoints directly
Briefs replace plans Harnesses own session execution planning; Goldfish owns durable strategic context that outlasts a session
3 tools, not more Checkpoint, recall, brief cover all use cases without bloat
Skills over slash commands Plugin-native, no manual bun setup step

Repository Structure

goldfish/
  .agents/
    skills/               # Repo-local skill mirror for Codex/OpenCode/Antigravity
  .claude-plugin/
    plugin.json           # Claude Code plugin manifest
  .codex-plugin/
    plugin.json           # Codex plugin manifest (tools + skills + hooks)
  .mcp.json               # Canonical Codex MCP server map
  .cursor-plugin/
    plugin.json           # Native Cursor plugin manifest
  mcp.json                # Cursor stdio MCP server map
  hooks/
    goldfish-hooks.json   # SessionStart hook map, shared by both manifests
    session-start.ts      # Prints the session guidance to stdout
    cursor-hooks.json     # Native Cursor sessionStart hook map
    cursor-session-start.ts # Prints Cursor additional_context JSON
  skills/
    brief/SKILL.md        # Canonical brief skill
    brief-status/SKILL.md # Canonical brief-status skill
    checkpoint/SKILL.md   # Canonical checkpoint skill
    handoff/SKILL.md      # Canonical handoff skill
    recall/SKILL.md       # Canonical recall skill
    report-issue/SKILL.md # Canonical report-issue skill
    standup/SKILL.md      # Canonical standup skill
  src/
    server.ts             # MCP server entry point
    tools.ts              # Tool definitions (checkpoint, recall, brief)
    instructions.ts       # Server behavioral instructions
    types.ts              # TypeScript interfaces
    checkpoints.ts        # Checkpoint storage and retrieval
    briefs.ts             # Brief storage and activation
    recall.ts             # Recall aggregation across date ranges and workspaces
    ranking.ts            # Orama BM25 search ranking
    digests.ts            # Compact retrieval/search digests
    file-io.ts            # Atomic write helpers
    logger.ts             # File-based logging
    registry.ts           # Cross-project registry (~/.goldfish/registry.json)
    workspace.ts          # Workspace detection and normalization
    git.ts                # Git context capture
    lock.ts               # File locking for concurrent writes
    summary.ts            # Auto-summary generation
    emoji.ts              # Emoji utilities
    handlers/             # Tool handler implementations (checkpoint, recall, brief)
  tests/                  # Test files

Development

This is a TDD project. Tests are written before implementation. No exceptions.

# Run all tests
bun test

# Watch mode (recommended during development)
bun test --watch

# Run a specific test file
bun test tests/checkpoints.test.ts

# Run with coverage
bun test --coverage

# Type check
bun run typecheck

Stats

  • Storage: markdown source of truth in .memories/; cross-project registry at ~/.goldfish/registry.json
  • Runtime dependencies: @modelcontextprotocol/server, @orama/orama, yaml
  • Protocol-test dependency: @modelcontextprotocol/client

TDD Workflow

  1. Write test first (watch it fail)
  2. Implement minimum code to pass
  3. Refactor if needed (keep tests green)
  4. Commit test + implementation together

See CONTRIBUTING.md for detailed development patterns.


Performance

Operation Target Actual
Checkpoint save < 50ms ~10ms
Recall (7 days, single project) < 100ms ~30ms
Recall (7 days, all projects) < 500ms ~150ms
BM25 search (100 checkpoints) < 50ms ~15ms

Benchmarked on Apple Silicon (M-series).


Troubleshooting

Plugin not loading

  1. Verify the plugin is installed: claude plugin list
  2. Ensure Bun is installed and available in your PATH
  3. Restart Claude Code (plugins load at startup)
  4. Codex: run codex plugin list, review /hooks and trust Goldfish's SessionStart hook, then start a new thread
  5. Cursor: verify Goldfish under Customize; restart Cursor or run Developer: Reload Window after changing the local plugin copy

Cursor writes are refused

If Goldfish refuses a Cursor write because no workspace is bound, pass the conversation's host-native absolute project root as workspace on the call. For a project-level server, add the type: "stdio" entry with the absolute Bun server path and GOLDFISH_WORKSPACE: "${workspaceFolder}" to the project .cursor/mcp.json, then reload the window. Registry and parent-walk candidates are suggestions only and never authorize writes.

Checkpoints not saving

  1. Check that .memories/ is writable in your project directory
  2. Run bun run src/server.ts directly to see error output
  3. Each checkpoint is ~1KB -- disk space is rarely an issue

Recall returns nothing

  1. Checkpoints are per-project: each project has its own .memories/ directory
  2. Default recall returns last 5 checkpoints regardless of age -- try recall({ workspace: "/absolute/path/to/project", days: 7 }) for date-windowed history
  3. Verify checkpoints exist: ls .memories/ in your project root

Cross-project recall is empty

  1. The registry at ~/.goldfish/registry.json must have entries
  2. Projects are auto-registered on first checkpoint save
  3. Check that listed projects still have .memories/ directories

Session-start guidance not appearing

  1. The hook fires only in sessions started after the plugin was installed or updated -- start a new session
  2. Claude Code: check /hooks for Goldfish's SessionStart entry; verify the plugin is enabled (claude plugin list)
  3. Codex: plugin hooks stay silent until trusted -- run /hooks, review and trust the Goldfish SessionStart hook, then start a new thread
  4. Cursor: verify the native sessionStart hook under Customize, then restart or run Developer: Reload Window and start a new conversation
  5. The hook runs bun, so Bun must be on your PATH (already true if the MCP tools work)

Documentation

File Audience Content
README.md Users This file -- overview, installation, usage
CLAUDE.md AI agents (developing Goldfish) TDD rules, architecture, coding patterns
CONTRIBUTING.md Contributors Detailed development guide
docs/IMPLEMENTATION.md Contributors Technical specification
docs/agent-portability.md Contributors Per-harness support tiers, deliberate non-support, drift guards

License

MIT


Fifth time's the charm.

About

Developer memory system for Claude Code: project-local markdown checkpoints, cross-project recall, and plan tracking — no database, just files.

Resources

Contributing

Stars

3 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages

0