Four-layer long-term memory (L0 Conversation → L1 Atom → L2 Scene → L3 Persona) for Claude Code, inspired by Tencent/TencentDB-Agent-Memory. Fully local — no external Gateway, no paid API, no Python.
FAQ
tencentdb-agent-memory is a Claude Code plugin with 8 hand-picked skills for development work, indexed on Flowy. Install it with the command on its page. It includes contrib-consolidate, contrib-ingest, contrib-profile. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.
> /plugin marketplace add baodq97/tencentdb-agent-memory> /plugin install tencentdb-agent-memory@tencentdb-agent-memory
Repo: baodq97/tencentdb-agent-memory
Four-layer long-term memory (L0 Conversation → L1 Atom → L2 Scene → L3 Persona) for Claude Code, inspired by Tencent/TencentDB-Agent-Memory.
Fully local — no external Gateway, no paid API, no Python. All extraction and consolidation is done by the Claude agent itself.
# Add marketplace
claude plugin marketplace add https://github.com/baodq97/tencentdb-agent-memory
# Install plugin
claude plugin install tencentdb-agent-memory
# Inside Claude Code:
/memory-init
# → installs deps, links tmem CLI, creates store
# → hints: "ask me to seed memories"
# then say "seed memories" → agent extracts L1 atoms
# then say "consolidate memories" → agent builds scenes + persona
# done — hybrid recall is now active automatically
| Hook | Action |
|---|---|
SessionStart | Inject the tier-0 persona core once per session (<persona-core>) + keep the global tmem shim current |
UserPromptSubmit | Hybrid recall (FTS5 + vector + RRF) + L2 scene-navigation index → inject <memory-context> |
Stop | Auto-capture turn + background consolidation after N turns |
SessionEnd | Mark session as pending for later seeding |
Hooks never block — failures degrade to no injection.
Each turn, the UserPromptSubmit hook builds a <memory-context> block from three layers:
conditional persona bullets this prompt actually reaches for, plus a short always-on insurance line (see How the persona reaches the agent).tmem scene <name> (progressive disclosure — cheap always-on index, full read only when needed).Tune the scene-navigation budget with tmem config scene-max-tokens N (0 disables it).
A consolidated persona grows well past what any per-turn budget can carry (~39k chars here). Rather than truncate it, each bullet is classified by duty and delivered on the channel that duty needs:
| Duty | Tier | Channel | Budget |
|---|---|---|---|
always | 0 | SessionStart hook → <persona-core>, once per session | persona-max-tokens (default 1200) |
conditional | 1 | UserPromptSubmit recall → <persona>, query-matched per turn | ~105 tokens |
reference | 2 | on demand — tmem persona --section <name> | none (never injected) |
Tier 0 is paid once per session, not per turn, which is what makes a budget that size affordable. The tier-0 block also carries a one-line index of every section name — including sections it delivered nothing from — so the tier-2 pointer is something the agent can actually act on.
Tier 0 delivers a bullet whole or not at all — bullets over 600 chars are skipped, never truncated. A rule cut before its exceptions reads as a different, stricter rule, which is worse than its absence. Tier 1 still truncates, deliberately: tier 1 is cover, tier 0 is contract. Write persona bullets one rule at a time, operative clause first.
Inspect the split with tmem persona --sections; tune tier 0 with tmem config persona-max-tokens N (0 is rejected — trimming is fine, switching persona conditioning off silently is not).
This does not fully solve persona delivery. On a 39k-char / 81-bullet persona, tier 0 delivers 13 of the 47 always-duty bullets — the always class alone is ~22k source chars against a 4,800-char budget, and 11 of those bullets are over the 600-char eligibility threshold. Closing that needs a synthesised core section on the consolidator side, which is not built yet.
tmem view)tmem view # start a session-keyed localhost server, print the URL
tmem view --query "<q>" # preselect the Context lens with a recall query
tmem view --snapshot # export the payload JSON once and exit (before/after measurement)
A read-only lens on the store, answering "does the agent actually know me?" — which persona bullets reach the agent, on which tier, and what the store's health gaps are. It opens every database with DatabaseSync(..., { readOnly: true }), so "never writes" is enforced by SQLite rather than by discipline.
The URL carries a per-session key and is required verbatim: the page renders raw captured prompts from every project, so localhost alone is not the boundary. Session output goes to <root>/view/, never inside a repo. Use --static to pin the numbers while you read them.
| Type | Name | Purpose |
|---|---|---|
| Command | /memory-init | Install deps, link tmem CLI, init store |
| Command | /contrib | Contributor intelligence (see below) |
| Skill | memory-seed | Agent extracts L1 atoms from conversation history |
| Skill | memory-consolidate | Agent builds L2 scenes + L3 persona |
| Skill | memory-view | Opens the tmem view visualiser and reads the feedback back |
| Skill | tmem-cli | CLI reference for memory inspection/management |
| Skill | contrib-profile | Orchestrates the /contrib pipeline end to end |
| Skill | contrib-ingest / contrib-consolidate / contrib-synthesize | Internal /contrib phases (not user-invocable) |
| Agent | memory-consolidator | Background worker dispatched by asyncRewake |
| Module | scripts/persona_projection.js | Pure persona duty classification + tier 0/1 projection; shared by the hook, the CLI and the visualiser |
| Module | scripts/scene_nav.js | Pure <scene-navigation> renderer + budget arithmetic; shared by recall and the visualiser |
The two Module rows are shared pure cores (no require, no I/O). They exist because recall and the visualiser must agree on the same arithmetic, and the visualiser cannot import the recall path — doing so would pull node:sqlite into a layer whose contract is that it does no I/O (a test enforces it). One renderer, one projection, two callers.
Installed automatically by /memory-init. Available in terminal and used by skills.
tmem status Memory stats
tmem search <query> FTS5 keyword search (global + current project)
tmem search <query> --all Cross-project: search every project store, labelled by store
tmem projects List all memory stores (slug, records, scenes)
tmem migrate-fragments [--apply] Collapse legacy cwd-keyed fragment stores into their project root
tmem recall <query> Hybrid recall (FTS5 + vector + RRF) + L2 scene-navigation
tmem persona Show persona
tmem persona --sections List persona sections (bullets + always/conditional/reference split)
tmem persona --section <name> Print one persona section on demand (tier 2)
tmem view [--query <q>] Open the memory visualiser (session-keyed localhost server)
tmem view --snapshot [--stdout] Export the visualiser payload JSON once and exit
tmem scenes list List scene blocks
tmem scene <name> Print one full scene block (project-first, then global)
tmem scenes dedup [--dry-run] Remove duplicate scenes
tmem changelog [--last N] Recent memory changes
tmem sync [--full] Embed missing vectors (delta); --full rebuilds
tmem atoms [global|project|all] Dump L1 atoms as JSON
tmem sessions List pending sessions
tmem init Initialize memory store
tmem mark-done Mark consolidation complete
tmem config consolidate-every N Set consolidation threshold (default 20)
tmem config scene-max-tokens N Set L2 scene-navigation token budget (default 200, 0 disables)
tmem config persona-max-tokens N Set the tier-0 persona budget (default 1200; 0 rejected)
tmem config recall [on|off] Toggle per-turn recall injection for this project
tmem daemon start Warm + serve the embed daemon (foreground, like `ollama serve`)
tmem daemon status Health-ping the daemon (ready/warming/failed/down + pid)
tmem daemon stop Stop the daemon + clear its pidfile
/contrib)Profile how a top GitHub engineer works — and learn from them.
Prerequisite: an authenticated gh CLI (gh auth login). All data lives in
<global>/contributors/ — the self-memory feature is never touched.
Paste a GitHub link (or a handle) and say what you want — the contrib-profile skill takes it A→Z for you:
"Analyze how this engineer works: https://github.com/sindresorhus/ky" "Profile https://github.com/torvalds and show me the playbook"
It resolves the target (picks the right repo if you only give a user), runs the whole pipeline, and hands back the persona + learnable playbook. Prefer to drive it yourself? Ask "how do I use /contrib" and it guides you through the steps below instead.
/contrib add <user> <owner/repo>
gh fetches their PRs, commits (all
branches), review threads and issues, then the agent classifies it into
evidence-linked atoms across the 11 dimensions. Incremental by default
(--full to refetch):
/contrib ingest <user>@<repo>
/contrib build <user>@<repo>
/contrib persona <user>@<repo> # the full dossier (11 dimensions + evidence)
/contrib playbook <user>@<repo> # emulable heuristics you can copy
/contrib compare <user>@<repo> # you (your existing self-persona) vs this role model
/contrib add <user2> <org2/repo2> ; /contrib ingest <user2>@<repo2> ; /contrib build <user2>@<repo2>
/contrib capabilities
/contrib compare <a> <b> (per-dimension, side by side)./contrib trajectory <id> (per-year cadence + commit-style arc)./contrib team add <teamId> <id...> then /contrib team capabilities <teamId>./contrib search "<query>" (keyword; vector too if the embed daemon
is warm — run /contrib sync once to index).Activity is classified into 11 dimensions across 3 clusters — Technical Craft
(idea/plan/solve/craft), Collaboration & Influence (comms/mentor/conflict),
and Outcomes & Ownership (scope/ownership/execution). Every atom and persona
claim is evidence-linked to a PR or commit. v0.3.0 measures cadence/style, not
PR diff size (the GitHub search API omits it).
~/.memory-tencentdb/
├── global/ index.db (FTS5) + vectors.db (sqlite-vec) + persona.md
│ ├── records/ raw L1 atoms, one JSONL per day
│ ├── scene_blocks/ L2 scene markdown
│ └── contributors/ /contrib store (isolated from self-memory)
├── projects/{hash}/ index.db + vectors.db + records/ + scene_blocks/
├── view/ `tmem view` session + snapshot output (never inside a repo)
├── config.json consolidate-every, scene-max-tokens, persona-max-tokens, per-project recall
└── models/ embeddinggemma-300m (~80MB, downloaded on first init)
node:sqlite (built-in)node-llama-cpp (npm, ~80MB model)tmem daemon start|status|stopSee CHANGELOG.md for per-version history.
Plugin: MIT. Upstream inspiration: MIT (c) TencentDB Agent Memory Team.
.claude-plugin/
marketplace.json
plugin.json
.gitignore
agents/
memory-consolidator.md
CHANGELOG.md
commands/
contrib.md
memory-init.md
EVALUATION.md
hooks/
hooks.json
scripts/
_common.js
on_session_end.js
on_session_start.js
on_stop.js
on_user_prompt.js
LICENSE
package-lock.json
package.json
README.md
scripts/
benchmark.js
cli.js
constants.js
contrib_config.js
contrib_ingest.js
contrib_store.js
embed_client.js
embed_daemon.js
embedding_service.js
eval_runner.js
grounding.js
low_signal.js
memory_auto_capture.js
memory_init.js
memory_pipeline.js
memory_reader.js
memory_recall.js
memory_store.js
memory_writer.js
persona_projection.js
scene_nav.js
tmem.js
vector_store.js
view/
contract.js
extract.js
serve.js
shell.html
transform.js
skills/
contrib-consolidate/
references/
persona-guide.md
SKILL.md
contrib-ingest/
references/
dimensions.md
SKILL.md
contrib-profile/
SKILL.md
contrib-synthesize/
references/
synthesis-guide.md
SKILL.md
memory-consolidate/
SKILL.md
memory-seed/
references/
extraction-guide.md
SKILL.md
memory-view/
SKILL.md
tmem-cli/
SKILL.md
test/
cli_drift.test.js
contrib_config.test.js
contrib_e2e.test.js
contrib_ingest.test.js
contrib_isolation.test.js
contrib_store.test.js
cross_project_search.test.js
eval_isolation.test.js
fixtures/
contrib/
commits.json
prs.json
grounding.test.js
launcher_selfheal.test.js
memory_store.test.js
migrate_fragments.test.js
noise_gate.test.js
persona_project_scope.test.js
persona_projection.test.js
project_root_keying.test.js
recall_log.test.js
recall_toggle.test.js
scene_nav_rank.test.js
session_start_hint.test.js
tmem_launcher.test.js
view_extract.test.js
view_transform.test.js© 2026 Flowy · Free and open source
Built for Claude Code · Not affiliated with Anthropic