Skip to content
/

cc-memory (skymanbp)

cc-memory · skymanbp/cc-memory · ★ 2 · last commit 2026-05-25

SQLite memory with anti-patch upsert_smart (MERGE/SUPERSEDE/INSERT via trigram-Jaccard), forced PROGRESS.md handoff via <system-reminder>, PreCompact extraction, and plan tracking with plan-refiner/plan-guardian subagents.

Best whenForced reads via <system-reminder> tags are more reliable than instructed reads; anti-patch writes prevent duplicate stacking that plagues append-only memory…
Skip ifAppend-only memory (creates duplicate stacking), Relying on Stop-only hooks (misses PreCompact window)
vs seeds
ccmemory(patrickkidd, seed) in philosophy (executive oversight, PreCompact hook, Stop hook) but uses SQLite instead of Neo4j, el…
Primitive shape 18 total
Commands 1 Skills 2 Subagents 2 Hooks 5 MCP tools 8
00

Summary

cc-memory (skymanbp) — Summary

cc-memory is a Claude Code plugin (Python) providing persistent memory via SQLite with AI-judged extraction using Haiku plus local Ollama fallback. At v2.2, it features an "anti-patch reconcile-on-write" system where memory saves use trigram-Jaccard similarity to MERGE, SUPERSEDE (with archive link), or INSERT — preventing duplicate stacking. The signature innovation is forced session handoff: memory/PROGRESS.md is always full-rewritten from SQL state at every Stop+PreCompact boundary, and the next session's SessionStart hook emits a <system-reminder> block requiring the agent to read PROGRESS.md before responding. v2.2 adds a live plan anchor (memory/PLAN.md) with ExitPlanMode capture, two subagents (plan-refiner, plan-guardian), an FTS5 search CLI, a Tkinter GUI dashboard, and a browser-based web viewer. Compared to seeds, it is closest to ccmemory (patrickkidd) in hook architecture and philosophy but uses SQLite instead of Neo4j and adds forced PROGRESS.md handoff, anti-patch writes, and plan tracking.

01

Overview

cc-memory (skymanbp) — Overview

Origin

Created by skymanbp. Started as a simpler memory plugin, grew to v2.2 with significant engineering investment. 2 GitHub stars but active development (last commit 2026-05-25).

Philosophy

Context loss at compaction and session end is the core problem. The design solves it with two complementary mechanisms:

  1. Anti-patch writes: Memory never duplicates. Each save goes through upsert_smart which uses trigram-Jaccard similarity to choose MERGE (overwrite similar in-place), SUPERSEDE (archive old, link new via supersedes_id), or INSERT. This eliminates stacked duplicates.

  2. Forced PROGRESS.md handoff: A single progress SQL row is the source of truth. PROGRESS.md is a full-rewrite artifact from that row, never appended. The next session's hook emits a <system-reminder> forcing the agent to read it before responding — not optional, forced.

v2.2 Key Quote (from README)

Live plan anchor (memory/PLAN.md). Captures ExitPlanMode output (or user-supplied
raw plans) into a structured, step-tracked document that survives session boundaries.
TodoWrite syncs step statuses mechanically; sensitive Bash calls (git push, deploys, ...)
flag drift. See docs/PLAN_PROTOCOL.md.

Memory Categories

Category Importance What
decision 3 Explicit choices, design changes
result 3 Measured outcomes with numbers
config 2 Hyperparameters, env vars, constants
bug 4 Identified+fixed problems, "NEVER do X"
task 2 Pending/blocked work items
arch 3 Module/pipeline structure, data flow
note 1 Everything else above noise

Importance scale: 1=noise ... 5=critical (never forget).

02

Architecture

cc-memory (skymanbp) — Architecture

Distribution

Claude Code plugin (Python). Install via marketplace or locally.

Install

# Via marketplace
claude /plugin marketplace add skymanbp/cc-memory
claude /plugin install cc-memory

# From source
git clone https://github.com/skymanbp/cc-memory.git
python cc-memory/cc_memory/ui/installer.py        # GUI installer
python cc-memory/cc_memory/ui/installer.py --cli  # CLI installer

# Windows standalone
# Download cc-memory-installer.exe from Releases

The installer:

  1. Copies package tree to ~/.claude/hooks/cc-memory/
  2. Adds 5 hook entries to ~/.claude/settings.json
  3. Auto-detects and upgrades v2.0 flat-layout installs

Directory Structure (source)

cc_memory/
├── core/           # db.py, upsert_smart, schema
├── hooks/          # Hook scripts (pre_compact.py, session_start.py, stop.py, post_tool_use.py, user_prompt.py)
├── llm/            # memory_writer.upsert_smart, Haiku extraction
├── cli/            # mem.py CLI (cc-mem subcommands)
├── mcp/            # server.py (8 MCP tools)
└── ui/             # installer.py + Tkinter GUI + web viewer
agents/
├── plan-refiner.md
└── plan-guardian.md
skills/
├── ccm-load/SKILL.md
└── save-memories/SKILL.md
commands/
└── cc-mem.md

State Storage (per project)

<project>/memory/
├── memory.db           # SQLite WAL (all memory types)
├── MEMORY.md           # Auto-generated index (refreshed every write)
├── PROGRESS.md         # Full-rewrite from `progress` SQL row
├── PLAN.md             # Live plan anchor (v2.2)
├── .last_save.json     # Status from last PreCompact
├── .gitignore          # Excludes DB + sessions
├── sessions/YYYY/MM/   # Per-session archives
└── topics/             # Reserved for future per-topic exports

Required Runtime

  • Python 3.8+
  • Claude Code
  • Optional: Ollama (local LLM fallback for Haiku extraction)
03

Components

cc-memory (skymanbp) — Components

Lifecycle Hooks (5)

Hook Action
UserPromptSubmit Turn count tracking + first-prompt seeding of PROGRESS.md; auto-init memory/ on first contact
PostToolUse Insert one observation row per tool call (no LLM — fast)
Stop Haiku observer extracts memories from this turn; patch_progress(files_touched=...); idle reorg every 5 turns
PreCompact Haiku extracts memories from full transcript; ALL writes through upsert_smart; FULL-REWRITE memory/PROGRESS.md from SQL row; archive session; regen MEMORY.md; maybe LLM-consolidate
SessionStart Inject context (topics + critical + timeline + PROGRESS preview); emit FORCED <system-reminder>: "Read PROGRESS.md FIRST"; retroactive save of unsaved prior JSONLs

MCP Tools (8, via cc_memory/mcp/server.py)

Tool Purpose
memory_search FTS5 search (compact results)
memory_get_details Batch fetch full details by IDs
memory_add Add via anti-patch upsert
memory_stats Project statistics
memory_topics List topic summaries
memory_recent Recent memories with filters
progress_get Read PROGRESS.md state (structured fields)
progress_regenerate Force-rewrite memory/PROGRESS.md from SQL state

Skills (2)

Skill Purpose
ccm-load Verify plugin activation, auto-initialize memory/, seed PROGRESS.md, run health check
save-memories Explicit memory save skill

Subagents (2)

Agent Purpose
plan-refiner Normalize raw plan to canonical JSON schema (uses Haiku, runs once per plan)
plan-guardian Check alignment when drift counters trip (called when plan-refiner's changes drift)

Commands (1)

Command Subcommands
/cc-mem status, stats, list decisions, search, topics, progress, supersedes, consolidate, cleanup, add, dashboard, serve, plan-status, plan-show, plan-set, plan-check, plan-replan, plan-clear

CLI (mem.py)

Full-featured CLI equivalent of /cc-mem commands, usable outside Claude Code.

Visual Dashboard (2)

  • Tkinter GUI: /cc-mem dashboard — cross-platform desktop app
  • Web viewer: /cc-mem serve — browser-based web viewer
05

Prompts

cc-memory (skymanbp) — Prompts

plan-refiner agent (verbatim)

---
name: plan-refiner
description: Normalise a raw plan (markdown or freeform text from ExitPlanMode or a user)
into the canonical cc-memory JSON schema. Use this exactly once per new plan; do not invoke
for re-syncing TodoWrite (that's mechanical) or for drift checks (use plan-guardian instead).
tools: Read, Grep, Bash
model: haiku
---

You are the plan refiner for the cc-memory plugin.

Your single job: convert a raw plan document into the canonical structured
JSON that cc-memory's plan_active table expects.

## Output schema (STRICT)

Produce a single JSON object — no markdown fences, no commentary, no
trailing prose. Stdout must parse with json.loads() directly:

{
  "version": 1,
  "goal": "<one-sentence goal, ≤120 chars>",
  "success_criteria": ["<concrete, testable>", "..."],
  "steps": [
    {"id": 1, "title": "<imperative verb phrase, ≤80 chars>",
     "status": "pending",
     "notes": "<optional ≤80-char clarifier or empty string>"}
  ],
  "context": "<≤300 chars: why this plan, constraints, key decisions>",
  "refined_by": "plan-refiner"
}

## Rules

1. Status defaults to pending unless raw document explicitly marks done
2. Steps are imperative: "Wire up token refresh", not "Token refresh needs to be wired up"
3. Merge near-duplicate steps
4. Drop fluff: "Plan ready for review", meta-comments about plan mode
5. Success criteria must be testable: "All routes return 401 without token" ✅; "Auth works well" ❌
6. No fewer than 1 step, no more than 12

Prompting technique: Strict output schema contract. The schema is specified as parse-with-json.loads() directly — no markdown, no commentary. This is a pure transformation agent with deterministic output format.

SessionStart System Reminder (from hooks architecture)

<system-reminder>
IMPORTANT: Read memory/PROGRESS.md FIRST before responding to this message.
This file contains critical context from the previous session including
current status, recent changes, and next steps.
</system-reminder>

Prompting technique: Forced read via <system-reminder> tag. Unlike "please read" instructions, this leverages Claude's special-tag processing to make the read mandatory before any response.

09

Uniqueness

cc-memory (skymanbp) — Uniqueness

Differs From Seeds

Closest to ccmemory (patrickkidd, seed) in hook architecture and executive-oversight philosophy. The key deltas: (1) SQLite replaces Neo4j, eliminating Docker/Ollama infrastructure; (2) The upsert_smart anti-patch write system prevents duplicate stacking, which neither ccmemory nor any other system in this batch has; (3) Forced PROGRESS.md handoff via <system-reminder> tag is stronger than ccmemory's passive injection (it prevents the agent from responding before reading context); (4) v2.2 adds plan tracking with two subagents, which no other memory system in this batch includes.

Distinctive Features

  1. Anti-patch writes (upsert_smart): Trigram-Jaccard similarity → MERGE/SUPERSEDE/INSERT decision on every save. Prevents duplicate stacking, the most common failure mode in file-based memory systems.
  2. Forced PROGRESS.md read: <system-reminder> tag in SessionStart is the strongest handoff enforcement mechanism in this batch — not advice, not instruction, but a tag that prevents response before read.
  3. Plan lifecycle subagents: plan-refiner + plan-guardian are purpose-built micro-agents for plan normalization and drift detection. No other memory system in this batch tracks plans structurally.
  4. PreCompact hook: Explicit handling of Claude Code's context compression event — extracts memories before compression destroys them. Most systems use Stop but miss the PreCompact window.
  5. SUPERSEDES chain: supersedes_id foreign key creates a traceable chain of superseded decisions — less sophisticated than ccmemory's graph but provides basic causal tracing.

Observable Failure Modes

  1. Haiku dependency: Extraction quality depends on Haiku API access; local Ollama fallback may produce lower quality extractions.
  2. Project-scoped only: No cross-project search or global memory.
  3. Python 3.8+ required: Windows users need standalone installer.
  4. Plan drift detection latency: drift counters activate plan-guardian after N turns, not immediately — important plans can drift before correction.
04

Workflow

cc-memory (skymanbp) — Workflow

Session Lifecycle

SessionStart → inject context (topics + critical + timeline)
             → emit <system-reminder>: "Read PROGRESS.md FIRST"
             → retroactive JSONL saves
↓
UserPromptSubmit → turn counting + first-prompt PROGRESS.md seeding
                 → auto-init memory/ on first contact
↓
PostToolUse → insert observation row (no LLM, fast)
↓
Stop → Haiku extracts memories from this turn
     → patch_progress(files_touched)
     → idle reorg every 5 turns
↓
PreCompact → Haiku extracts from full transcript
           → ALL writes via upsert_smart (MERGE/SUPERSEDE/INSERT)
           → FULL-REWRITE memory/PROGRESS.md from SQL row
           → archive session
           → regen MEMORY.md

Anti-Patch Write Protocol

Every memory save goes through upsert_smart which:

  1. Computes trigram-Jaccard similarity against existing memories
  2. If similarity > threshold → MERGE (overwrite in-place)
  3. If high similarity to decision-class → SUPERSEDE (archive old, link new via supersedes_id)
  4. Otherwise → INSERT new

Plan Lifecycle (v2.2)

User enters plan mode → ExitPlanMode tool → plan-refiner agent
                     → normalized JSON → stored in plan_active table
                     → PLAN.md generated

TodoWrite → syncs step statuses mechanically
Sensitive Bash → flags drift
drift counter trips → plan-guardian agent checks alignment

/cc-mem plan-show → regenerate + print PLAN.md
/cc-mem plan-check → reset counters + emit guardian hint

Phases + Artifacts

Phase Artifact
First contact memory/ initialized with DB + PROGRESS.md + MEMORY.md
PostToolUse Observation row in SQLite
Stop Extracted memories in SQLite; patched PROGRESS.md
PreCompact Full-rewritten PROGRESS.md; session archive; updated MEMORY.md
ExitPlanMode PLAN.md (step-tracked, survives session boundaries)

Approval Gates

None. All operations are automatic.

06

Memory Context

cc-memory (skymanbp) — Memory & Context

Memory Type

sqlite — SQLite WAL database at <project>/memory/memory.db.

Persistence Scope

project — Memory lives in <project>/memory/ directory.

State Files

File Content Update Frequency
memory/memory.db All memories, observations, progress row, plan Every Stop/PreCompact
memory/MEMORY.md Auto-generated index of all memories Every write
memory/PROGRESS.md Full-rewrite from progress SQL row Every Stop + PreCompact
memory/PLAN.md Live plan anchor from ExitPlanMode (v2.2) On plan changes
memory/.last_save.json Status from last PreCompact Every PreCompact
memory/sessions/YYYY/MM/ Per-session archives Per session

Anti-Patch Write Protocol

The upsert_smart function is the core innovation:

# Pseudocode
def upsert_smart(new_memory):
    similarity = max(trigram_jaccard(new_memory, m) for m in existing)
    if similarity > merge_threshold:
        overwrite_in_place(most_similar)  # MERGE
    elif similarity > supersede_threshold and is_decision_class:
        archive_old(most_similar)
        insert_new(new_memory, supersedes_id=old_id)  # SUPERSEDE
    else:
        insert(new_memory)  # INSERT

This eliminates the "stacked duplicates" failure mode where repeated saves create redundant entries.

Search Mechanism

full-text — FTS5 search via SQLite full-text extension. Available via memory_search MCP tool and /cc-mem search CLI.

Context Compaction Strategy

Explicit design around compaction:

  • PreCompact hook triggers before Claude's native context compression
  • Extracts memories from the about-to-be-compressed transcript (Haiku)
  • ALL writes go through upsert_smart to prevent duplication
  • FULL-REWRITES memory/PROGRESS.md from SQL state
  • Archives session before compaction

Forced Handoff Protocol

The SessionStart hook emits a <system-reminder> block that forces the next session to read PROGRESS.md before responding. This is not optional advice — it leverages Claude's special-tag processing.

Cross-Session Handoffs

yes — via forced PROGRESS.md read at SessionStart.

Plan State (v2.2)

memory/PLAN.md tracks:

  • Goal (one sentence, ≤120 chars)
  • Success criteria (concrete, testable)
  • Steps with status (pending/in_progress/done/blocked/skipped)
  • Context and constraints
  • Drift counter for plan-guardian activation
07

Orchestration

cc-memory (skymanbp) — Orchestration

Multi-Agent

Yes — 2 subagents (plan-refiner, plan-guardian). Both are triggered automatically by the plan lifecycle, not manually.

Orchestration Pattern

sequential — plan-refiner runs once to normalize a raw plan; plan-guardian runs when drift is detected. The two never run simultaneously.

Isolation

none — In-place project directory.

Multi-Model

Yes (implicit). The extraction uses Haiku by default with local Ollama as fallback. This is role-specific model selection: Haiku for lightweight extraction tasks, not full-session work.

Execution Mode

event-driven — All activity driven by Claude Code lifecycle hooks.

Subagent Definition Format

persona-md — Both subagents are Markdown files in agents/ with name, description, tools, and model frontmatter.

Notes

The plan-refiner/plan-guardian pattern is a specialized micro-orchestration: one agent refines (transforms raw → structured), another guards (validates alignment). This is the only in-batch example of two purpose-built subagents with explicit handoff between them.

08

Ui Cli Surface

cc-memory (skymanbp) — UI & CLI Surface

Dedicated CLI Binary

python mem.py (via ~/.claude/hooks/cc-memory/cc_memory/cli/mem.py). Inside Claude Code, use /cc-mem command.

Subcommands: status, stats, list, search, topics, progress, supersedes, consolidate, cleanup, add, dashboard, serve, plan-status, plan-show, plan-set, plan-check, plan-replan, plan-clear

Local Web Dashboard (2 interfaces)

Tkinter GUI

  • /cc-mem dashboard — cross-platform desktop GUI
  • Memory browsing, filtering, stats

Web Viewer

  • /cc-mem serve — browser-based web viewer

IDE Integration

Claude Code plugin via /plugin marketplace. Hooks registered in ~/.claude/settings.json.

Observability

  • /cc-mem status — full health check
  • /cc-mem stats — memory + supersede-chain counts
  • Session archives in memory/sessions/YYYY/MM/
  • .last_save.json — status from last PreCompact
  • MEMORY.md — auto-generated human-readable index

Windows Support

Standalone installer executable (cc-memory-installer.exe) for Windows users who cannot run Python directly.

Installation Modes

Mode Command
Marketplace /plugin marketplace add skymanbp/cc-memory && /plugin install cc-memory
Local source GUI python cc-memory/cc_memory/ui/installer.py
Local source CLI python cc-memory/cc_memory/ui/installer.py --cli
Windows standalone cc-memory-installer.exe

Related frameworks

same archetype · same primary tool · same memory type

MemPalace ★ 53k

Verbatim local-first AI memory with 96.6% R@5 retrieval on LongMemEval using zero API calls — structured into a palace hierarchy…

Beads (Yegge) ★ 24k

Dolt-powered distributed graph issue tracker where AI agents track tasks with hierarchical IDs and dependency edges, claim work…

deepagents (LangChain) ★ 23k

Opinionated Python agent harness on top of LangGraph with sub-agents, filesystem, memory, and context compaction bundled in

agentmemory ★ 18k

Persistent, searchable memory for AI coding agents that captures every tool interaction, compresses it via LLM, and injects…

Open Multi-Agent ★ 6.3k

Give a natural-language goal to a coordinator agent and get a dynamically decomposed, parallelized task DAG executed by…

Basic Memory ★ 3.1k

Gives AI agents a persistent, human-readable knowledge graph of project decisions, observations, and relations stored as plain…