ContextPocket
Health Warn
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 6 GitHub stars
Code Fail
- fs module — File system access in lib/bootstrap.js
- fs module — File system access in lib/core.js
- fs module — File system access in lib/distill.js
- fs.rmSync — Destructive file system operation in lib/hooks.js
- fs module — File system access in lib/hooks.js
- fs module — File system access in lib/importer.js
- fs module — File system access in lib/indexer.js
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
辅助上下文记忆:把每轮开发对话记成项目本地的纯 Markdown,跨对话、跨 Agent 都能接着读。零依赖 · MCP · 不联网。
ContextPocket
SKILL docs are split into 3 files: SKILL.md (daily-read main) · SKILL-advanced.md (templates / archive / edge cases) · SKILL-reference.md (Layout + per-file templates + log.md T-block spec).
📌 When it helps
- Switching agents or models? A new session may start without the context from the last one.
- Long session hit the token limit? Earlier details can be compressed or lost.
- Inheriting an AI-assisted project? It can be hard to tell what has already been done.
✨ What ContextPocket does
- With a compatible agent configured, records development turns in your project's
ContextPocket/folder. - Gives the next session a concise project record to continue from.
- Keeps requirements, code changes, decisions, pitfalls, and preferences in plain Markdown.
- Connects turns, files, and decisions, so
recall --with-contextcan show what happened around a turn — not just what it said.
Handoff, not just memory. The pocket doubles as a plain-Markdown handoff protocol: a different Agent, model, or teammate can read back the T-block timeline, decisions and open threads in about five minutes — no vendor lock-in, no database.
ContextPocket 2.6 and ContextPocket Lite 2.8
ContextPocket 2.6 keeps sourced multi-hop graph context and historical validity filtering (search <kw> --expand 2, why <file> --expand 2, --as-of <T>), and now derives a byte-identical link graph to Lite (6 node types / 10 edge types) with faster exact T<n> lookup. It keeps the full 28-command CLI / MCP toolset for larger, long-lived project memories. New in 2.6: a three-tier handoff view with sourced node chains, current-only decisions and SECURITY.md.
ContextPocket Lite 2.8 shares the same pocket format and temporal graph fields, but simplifies the read/write path for small projects and everyday conversation memory: five core Markdown files, eleven CLI commands / MCP tools, search that always scans the markdown, and a link graph derived at runtime — no search index, no graph cache, nothing to rebuild. New in 2.8: the same three-tier handoff, sourced node chains and current-only decisions, generated byte-identically by both packages. Also ships token-saving output tiers (--brief / --full, --json always complete) on top of log amend, diff, handoff and --expand multi-hop context.
| Edition | Best for | Context graph | Footprint |
|---|---|---|---|
| 2.6 | Larger, long-running projects | Cached multi-hop graph context with historical validity filtering | 10 core files · 28 commands / tools |
| 2.8 Lite | Small projects and everyday conversation memory | Runtime-derived multi-hop links; no cache | 5 core files · 11 commands / tools |
Which version should I download?
Download the latest stable Release — it is what the main branch and the version badge above track (package.json = 2.6).
| Edition | Stable version | Download |
|---|---|---|
| Full | 2.6 |
ContextPocket-2.6.zip |
| Lite | 2.8-lite |
ContextPocket-2.8-Lite.zip |
Each archive includes its package.json, README and license; no npm registry release is involved. Between stable releases, development lands on main under preview version tags — clone the repo (see Quick Start) to try it early.
🚀 Getting started
- Install — choose one of the three methods in Quick Start: a CLI command, a direct Node.js script call, or a skill-directory copy.
- Activate — a compatible agent can initialize the pocket when you first use it; no setup command is needed in the conversation.
- Work normally — the configured agent records the work, and a later session can continue from the same project files.
🚀 Quick Start
1. Install
Three modes available — auto-detected, no extra config needed.
| Mode | Requirements | Reliability | Best for |
|---|---|---|---|
| MCP mode | MCP-compatible agent (Trae, Claude Desktop) | ⭐⭐⭐⭐⭐ 10/10 | Best experience |
| CLI mode | Node.js 14+ (zero extra deps) | ⭐⭐⭐⭐ 9.5/10 | Most developers |
| Skill-only | Nothing, just the folder | ⭐⭐⭐⭐ 8/10 | Compatibility fallback |
Fetch the code first — method (b) can point at any folder that holds these files:
git clone https://github.com/Wink305/ContextPocket.git
cd ContextPocket
Then pick one of the three install methods below.
(a) Install it as a command — context-pocket on your PATH
This is the only method that makes the bare context-pocket <cmd> form used across this README work.
From a clone — works today (package.json is in the repo, so npm link registers the CLI globally from your local directory):
# macOS / Linux / Windows (PowerShell or cmd) — run inside the cloned repo
npm link
Or install it globally from the local folder instead:
npm install -g .
From the registry — not published yet. npm install -g context-pocket is the intended final form, but the package has never been published to the npm registry: every release so far ships only via a GitHub Release or a git clone, and npm view context-pocket returning 404 is expected. Use one of the clone-based commands above until the first publish lands. The publish checklist (login + 2FA → npm publish → replace this paragraph) is in CONTRIBUTING.md under "发布流程(维护者)".
package.json declares two binaries, so linking installs both:
| Command | Entry point | What it is |
|---|---|---|
context-pocket |
bin/context-pocket.js |
the CLI |
context-pocket-mcp |
mcp-server.js |
the MCP stdio server |
Verify:
context-pocket help
Windows note: npm link generates context-pocket.cmd / context-pocket-mcp.cmd shims, so the commands work in PowerShell and cmd unchanged. Remove later with npm uninstall -g context-pocket.
(b) No install at all — call the script with node
Nothing is registered anywhere; this works on any machine with Node.js 14+ and only needs the files on disk. Replace the path with where you actually put the repo:
# POSIX (bash / zsh)
node /path/to/ContextPocket/bin/context-pocket.js status --dir /path/to/your/project
# Windows / PowerShell
node C:\Users\<you>\ContextPocket\bin\context-pocket.js status --dir C:\path\to\your\project
Every context-pocket <cmd> in this README or in docs/FAQ.md can be run this way by swapping the prefix for node <path>/bin/context-pocket.js.
(c) Skill-directory copy — no Node.js needed at all
If your agent loads skills from a folder (MiniMax Code, Claude Code, Cursor, Continue), copying the folder in is enough: the agent reads the SKILL docs and drives the same subcommands for you, and the skill-only mode above works even with no Node.js installed.
POSIX (bash / zsh):
# MiniMax Code / Claude Code / similar
cp -r . ~/.minimax/skills/context-pocket/
# Cursor / Continue / IDE plugins
cp -r . ~/.cursor/skills/context-pocket/
Windows / PowerShell:
# MiniMax Code / Claude Code / similar
Copy-Item -Recurse -Force . "$env:USERPROFILE\.minimax\skills\context-pocket"
# Cursor / Continue / IDE plugins
Copy-Item -Recurse -Force . "$env:USERPROFILE\.cursor\skills\context-pocket"
Windows / cmd.exe:
xcopy . "%USERPROFILE%\.cursor\skills\context-pocket\" /E /I /Y
⚠️ Method (c) alone does not put
context-pocketon your PATH. Combine it with (a) or (b) if you also want to run the CLI yourself.
For MCP mode: add this to your MCP config (works with every install method — point args at the absolute path of mcp-server.js):
{
"mcpServers": {
"context-pocket": {
"command": "node",
"args": ["/absolute/path/to/ContextPocket/mcp-server.js"]
}
}
}
On Windows, either use forward slashes or escape the backslashes in the JSON string:
{
"mcpServers": {
"context-pocket": {
"command": "node",
"args": ["C:\\Users\\<you>\\ContextPocket\\mcp-server.js"]
}
}
}
After install method (a) you may instead use the installed bin directly: "command": "context-pocket-mcp" with "args": [].
See docs/COMPATIBILITY.md for the full list of supported agents.
2. Activate
Activation is automatic — there is no command to type in the conversation. In a project without a ContextPocket/ folder, the agent offers to initialize one on the first substantive turn; if one already exists, it reads index.md and state.md before continuing.
The agent will automatically:
- Create a
ContextPocket/folder at the project root - From CLI/MCP mode: run
bootstrapto auto-detect project type, scan directory tree, copy all templates fromtemplates/, and pre-fillcode-map.mdandstate.md - Start auto-recording
3. Work normally
With ContextPocket configured, the agent automatically appends a T<n> block to log.md for each recorded development turn, including:
- What you said (User)
- What the agent did (Action — with specific file paths)
- Code changes / decisions made
No extra step is needed during normal work.
4. Switch / Hand off
When switching agents or models, have the new session read the pocket:
Read ContextPocket/index.md
The new agent can read the pocket and continue recording from there.
⚡ Quick responses
There are no slash commands to memorize. Say what you want in plain language — the agent infers the intent and runs the right context-pocket subcommand or MCP tool, then answers in one line. The full intent → action mapping lives in SKILL.md.
| Intent | The agent runs | It replies |
|---|---|---|
| First time in this project | bootstrap (idempotent) |
✅ ContextPocket ready, auto-recording on |
| Current status | status |
One-line summary |
| Mark something as an absolute rule | absolute add |
Written to absolute.md, never compressed |
| Hand off to another agent or model | handoff |
handoff.md generated |
| Check for missing or malformed records | verify |
Pass — or each issue with a runnable fix command |
| Check whether changed code went unrecorded | verify --drift |
The files whose mtime is later than the last record (works without git; never blocks a commit) |
| Fill in a missing turn | log amend |
T7 filled in |
| Record an explicit time for a turn | log append --when / log amend <Tn> --when |
The turn's time line, echoed back as ⏱ <date> 09:00 → <date> 11:30 — a day it only knows as a day stays (day), and the stated wording stays verbatim |
| Find who changed a file | why <path> (--expand <1–3> for graph context; --as-of <T> for a historical slice) |
Matching turns labelled by evidence, plus related graph nodes when requested |
| Find an earlier turn by keyword or window | search <keyword> (--expand <1–3> for graph context) |
The matching T-blocks; graph context does not alter match order |
| Recall one turn | recall T<n> |
The full T-block |
| Recall one turn with its surroundings | recall T<n> --with-context |
The turn plus its inbound context: who referenced it, later changes to the same files, related ADRs |
| List turns inside a window | recall --from … --to … / recall --since T5 --until T9 |
The turns in that window, oldest first |
| Compare two turns | diff Ta Tb |
The delta |
| List open questions | Reads the ❓ lines directly (no tool) |
The list, then "Confirm one by one?" |
| Check for contradictions | check-conflicts |
Severity-ranked result |
| Inspect the shape of the project | graph [--type <type>] [--json] |
Nodes and edges derived from the pocket — turns ↔ files ↔ ADRs ↔ tags ↔ requirements, each edge naming its source |
| Repair duplicated or stale T-numbers | repair --dry-run first |
The renumber plan + the prose still naming an old id |
| Check for commits that went unrecorded | sync (--auto to write) |
How many turns were backfilled |
| Import an earlier session | import |
How many turns were imported |
| Distill older turns | distill |
The report; the agent then merges it by hand |
| Export a snapshot for a teammate | the agent writes the file itself | The file path |
| Archive and start over | archive --keep-last N |
Confirm with the user first |
| Explain how this works | Answers inline — never "see README.md" | An inline answer |
💡 Prefer the plain phrasing; it reads better than a command name. Naming the subcommand explicitly (
context-pocket verify) also works if you want zero ambiguity.
The graph layer. recall --with-context and graph read a derived link graph — turns ↔ files ↔ ADRs ↔ tags ↔ requirements — from the pocket sources. search <kw> --expand 2 and why <file> --expand 2 add up to two hops of sourced graph context without changing the order of the original text matches; --as-of <T> filters that context to facts valid at a past T-id. Explicit Corrects T<n> and ADR Supersedes links close the old fact's validity interval. Every edge retains its source. Reach for it when the question is about relationships ("what happened around this turn?", "which decisions touched this file?"); skip it when the question is about content ("what did T7 say?"), where plain recall / search are faster and already complete.
💻 CLI Commands (Node.js Required)
All commands below work via CLI when Node.js 14+ is available. Type context-pocket … if you used install method (a); otherwise prefix with node <path>/ContextPocket/bin/context-pocket.js — install method (b). Pass --dir <project-root> to target a project.
| Command | What it does |
|---|---|
context-pocket bootstrap --dir <root> |
Auto-detect project type, scan tree, copy templates, pre-fill code-map & state. Registers the project in ~/.contextpocket/hub.json; add --no-hub (MCP noHub: true) to build the pocket without touching the hub |
context-pocket verify --dir <root> |
15-check health check: files, IDs, refs, index consistency, 🔒 integrity, log size vs archive_at, credential/PII shapes in the markdown (vendor keys = error and block the pre-commit hook; personal data = warning only), attachment existence (a ### Attachments line naming a file that is not on disk is an error — placeholders, URLs, absolute paths and entries already marked [missing: …] are skipped), and — as a warning that never blocks a commit — a data format left behind the registry (lib/validator.js:74) |
context-pocket verify --drift --dir <root> |
Add the two tree-scanning drift checks: cognition drift (paths in recent T-blocks vs working tree) + code-newer-than-log (files modified after the last record; works without git). Add --drift-last-n <N> to tune lookback |
context-pocket status --dir <root> |
One-line summary (T-range, reqs, ADRs, ❓, archive status) |
context-pocket recall <T-id> --dir <root> |
View full details of one T-block |
context-pocket recall --dir <root> --since <T> [--until <T>] [--from <YYYY-MM-DD>] [--to <YYYY-MM-DD>] [--limit N] [--offset N] |
Window mode: no T-id, at least one window flag — list turns when you have no keyword to search for. Same window semantics as search (see "Time windows" below). Oldest first, archived turns included and marked; --limit 0 = all. A T-id and a window cannot be combined. MCP: context_pocket_recall without tId, with sinceT / untilT / fromDate / toDate |
context-pocket diff <Ta> <Tb> --dir <root> |
Compare two turns: req changes, ADR additions, file changes |
context-pocket search <keyword> --dir <root> [--limit N] [--offset N] [--no-index] |
Keyword search over the whole history: T-blocks (gist, tags, every section, archived turns included), ADRs, requirements and preferences. Auto-uses the assets/search-index.json index; --no-index scans the markdown instead — both paths match and order identically, so --limit/--offset page the same list (--limit 0 = all). Matching: latin words split on separators, Chinese is indexed as adjacent two-character pairs, and every query term must hit. A phrase inside a longer Chinese run therefore works (时间分页 finds 「给搜索加时间分页」) and a reordered one does not (分页时间); one lone Chinese character only matches where that character stands alone |
context-pocket why <file-path> --dir <root> |
Reverse lookup: which T-blocks mention this file, split by evidence — [changed] (path in that turn's Action section) vs [mentioned only] (elsewhere: Uncertain / Attachments / Conflicts / Pitfalls …). Changed turns are listed first, so --limit drops the weak ones, never the real edits (Inspired by ThoughtDAG) |
context-pocket check-conflicts --dir <root> |
6-dimension conflict scan with severity (critical / warning / info) |
context-pocket graph --dir <root> [--type <t>] [--limit <N>] |
View the derived link graph (T ↔ file ↔ ADR ↔ tag ↔ requirement; edges: modifies / mentions / references / decided-in / supersedes / last-changed / tagged / opened-in / completed-in / implements, each citing source + T-id). graph rebuild rewrites the assets/graph.jsonl cache byte-identically from the markdown; graph verify reports cache-vs-source drift |
context-pocket log append --dir <root> --gist "..." --tags "..." [--when "..."] [--author "..."] |
Append one T-block to log.md (pass --user "<what the user asked>" — a block without it fails verify and blocks commits). --when is optional: the block is stamped with the moment you record it, and --when only overrides that when the turn actually happened at another time. --author "<who is recording>" signs the turn in a ### Author section — use it when several agents share one pocket; omit it and the block simply has no author, the tool never guesses one. Every append also compares this turn against what the pocket already says and writes what it newly collides with into the block's ### Conflicts section prefixed [auto] (--no-conflict-check opts out and the tool says so). The scan reports, it never blocks the record |
context-pocket log amend <Tn> --dir <root> --user "..." [--when "..."] [--author "..."] |
Fill in sections missing from an existing T-block. Never overwrites existing content — --when will add a missing time line or sharpen a day-only one, but refuses to rewrite a moment that was already recorded, and --author only adds a missing ### Author section |
context-pocket absolute add --dir <root> --text "..." [--gist "..."] |
Append a 🔒 red-line entry to absolute.md (verbatim, never compressed) |
context-pocket req add --dir <root> --text "..." |
Add a requirement (auto-assigns next R-id) |
context-pocket decision add --dir <root> --title "..." |
Add an ADR |
context-pocket handoff --dir <root> |
Generate handoff.md summary |
context-pocket state update --dir <root> --summary "..." |
Update current state |
context-pocket preferences update --dir <root> --key "..." --value "..." |
Update a preference |
context-pocket code-map update --dir <root> |
Rescan project directory, update code-map.md |
context-pocket archive --dir <root> [--keep-last N] [--dry-run] |
Archive old T-blocks (you trigger it; it is never automatic) with verify → archive → verify → rollback. --keep-last defaults to recent_keep in config.md (30) |
context-pocket migrate --dir <root> [--to v<N>|latest] [--dry-run] [--list] |
Format migration along the registered hop chain (v1 → v2 → v3 in one call; --to accepts v2 / 2 / latest). Backs up first, verifies before each hop, restores the backup if any hop or the post-check fails. Two hops are registered: v1 → v1 (a no-op format self-check) and v1 → v2, which really rewrites content — every T-block in log.md / log-archive.md gets a --- WHEN: <date> (day) --- line from the SESSION date above it, a block with no date above it is left untouched, and blocks that already have a line are skipped so re-running changes nothing. A v1 folder shows one format-upgrade WARNING in verify until you run it — a warning, so the commit hook never blocks on it |
context-pocket repair --dir <root> [--dry-run] [--apply-refs] [--author "..."] |
Renumber T-ids that collide after two agents wrote the same turn number (the write lock is per-machine — see "Will multiple users/agents conflict?"). The colliding block and every block after it shift up one, so ids keep increasing with file order, because log.md is append-only. Prose is never rewritten: every line still naming an old number is listed (that number can point at either of the two colliding blocks — only a reader knows which), and --apply-refs is what actually substitutes them, in one simultaneous pass so a T3→T4 + T4→T5 cascade cannot move one reference twice. Only a standalone T<n> is a reference — GPT4 / RTX4090 / UTF8 are words that contain the shape, not ids — and attachment file names (T04-diagram.png, assets/T04-diagram.png) are never rewritten even under --apply-refs: renaming a file is two halves (mv, then edit the text) and doing only the second leaves a broken link plus lost zero-padding, so those are listed in fileNames with the exact mv command to run. Derived counters (the · T<n> header of state/requirements/decisions/preferences/code-map/handoff, and index.md) are realigned automatically; log-archive.md is reported but never touched (it declares itself read-only). The move itself becomes an [auto] T-block, and if verify comes out worse the whole repair rolls back |
context-pocket sync --dir <root> [--auto] [--dry-run] [--last-n <N>] [--quiet] |
Git safety net: detect staged changes unrecorded in recent T-blocks (hook uses --auto). Coverage needs strong evidence — the path in a turn's Action section; a file only named in Uncertain / Attachments / Conflicts still counts as unrecorded, and the report says which turn mentioned it so you can log amend instead of getting a fresh [auto] block |
context-pocket install-hook --dir <root> |
Install Git pre-commit hook (v3: skip when no pocket → auto-fill missed → verify) |
context-pocket uninstall-hook --dir <root> |
Remove our pre-commit hook, preserve other hooks |
context-pocket index --dir <root> [--rebuild] |
Build / refresh the search index (assets/search-index.json). Markdown files are always the source of truth; the index is a derived cache |
context-pocket distill --dir <root> [--dry-run] |
Distill old turns: emit a digest-<date>.md report listing decisions / pitfalls / preferences worth merging back into the living docs (inspired by Basic Memory) |
context-pocket import --dir <root> --file <session.jsonl> [--source auto|claude-code|codex] |
Import a past agent session as [imported] T-blocks so a mid-stream adoption doesn't lose history |
context-pocket hub [list|pref|remove] --dir <root> |
User-level hub: list registered projects / read+write global prefs / unregister this project |
context-pocket help [--json] |
Show all commands. With --json the same table comes back as one line of {groups:[{group,commands:[{command,summary}]}]}, so an agent can discover the command surface without parsing colored text |
💡 In MCP mode, each CLI command has an equivalent MCP tool (e.g.
context_pocket_bootstrap).💡 Every command accepts
--json: stdout becomes exactly one parseable line ({"ok":true,…}, or{"ok":false,"error":"…"}with a non-zero exit) instead of formatted text — that is what the agent/hook side should read.💡 One concept, one name on both sides: MCP
tId⇄ CLI--t-id(diffusestA/tB⇄--t-a/--t-b, MCPfilePath⇄ CLI--file-path). The positional form (context-pocket recall 3) is the canonical way to write it;--t,--id,--file,-fstay accepted as aliases, so a plausible guess never comes back as "T-id is required".💡 A flag with no value counts as not given.
context-pocket state update --summary --jsonwrites nothing and exits 1 instead of storing the wordtrueinstate.md— the same rule the writer applies to--gist, now shared by both entry points (lib/fields.jstextOption).💡
--no-indexsits on both ends of the cache and is safe on both: onsearchit means "ignore the cache for this query", onlog append/log amendit means "don't refresh the cache after this write". Markdown stays the source of truth either way, so the next search rebuilds the cache and returns the very same hits — including archived turns, measured to come back in the same order on both paths. Bulk loops use it to skip a refresh per turn, and the size of that saving depends on scale: ≈15 ms/turn at 30 turns (a bare CLI call already costs ≈112 ms of Node startup), ≈0.18 s/turn at 800 turns — so it pays off mainly in the resident MCP server or a long append loop, not in one-shot CLI use (log append --help).💡
context-pocket --version(also accepted:-v,context-pocket version) prints the number straight out ofpackage.json— it needs noContextPocket/folder and writes nothing. An MCP client reads the same number frominitialize'sserverInfo.version; both entry points go throughlib/version.js, sopackage.jsonis the only place a version is written.
⏱ Time windows
search and recall share one window vocabulary (filterByTime in lib/query.js), so a turn inside the window for one is inside it for the other:
| Flag | MCP parameter | Keeps turns with |
|---|---|---|
--since <T> |
sinceT |
T-id >= <T> |
--until <T> |
untilT |
T-id <= <T> |
--from <YYYY-MM-DD> |
fromDate |
WHEN date >= this day |
--to <YYYY-MM-DD> |
toDate |
WHEN date <= this day |
Both are closed intervals, can be mixed, and a junk value (--since abc, --from oops) counts as "not given" rather than an error. A date window excludes turns with no --- WHEN: … line (v1 pockets, blocks written by hand); a T-id window still includes them — the number exists even when the time is missing. In search, FIX / ADR / R / preference documents follow the same rule (a FIX inherits the time of the turn it corrects); recall's window lists T-blocks only, and corrections come back inside recall T<n>.
search still needs a keyword. Use recall window mode when the question is "what happened between X and Y" and there is nothing to search for. Both commands apply --limit / --offset after filtering, so total is the real number of matching turns (--limit 0 = all).
context-pocket search 登录 --since 12 --until 40 --json
context-pocket recall --from 2026-11-01 --to 2026-11-07 --limit 0 --json
📋 Use Cases
| Scenario | Pain point | How ContextPocket solves it |
|---|---|---|
| Switch agent platforms | New agent knows nothing | Read ContextPocket/ and continue |
| Switch model versions | Conversation history disappears | Same — data is model-agnostic |
| Long session token overflow | History gets compressed/lost | Critical content is already on disk |
| Multi-agent collaboration | Agents have inconsistent state | Share one ContextPocket/; concurrent writers on one machine are serialized by the write lock, cross-machine merges are settled by repair, and log append --author says who recorded what |
| Inherit someone else's project | Don't know what was done before | Read handoff.md, 5 min onboarding |
| Trace a decision through time | "Who touched this file after that call?" | recall --with-context and graph follow turns ↔ files ↔ decisions |
📁 File Structure
project-root/
└── ContextPocket/
├── readme.md # Project identity card + format version
├── index.md # Lightweight index (~20 lines)
├── state.md # Current state + next steps + run commands + pitfalls
├── requirements.md # Requirements list (R-ids, with impl references)
├── preferences.md # Dev preferences
├── decisions.md # Architecture Decision Records (ADRs)
├── code-map.md # Detailed code/module map
├── log.md # Conversation timeline (one T-block per turn)
├── log-archive.md # Archive (created when log.md > archive_at lines)
├── absolute.md # 🔒 Never-compressed absolute-keep area
├── handoff.md # Handoff summary (generated by the handoff step)
├── config.md # Optional: custom configuration
├── pocket-snapshot-*.md # Snapshot files (max 3 kept)
└── assets/
├── search-index.json # Search index (auto-generated, safe to delete + rebuild)
├── graph.jsonl # Link-graph cache (derived; `graph rebuild` reproduces it byte for byte)
└── archive/ # Archived attachments (moved here on archive)
T-block structure
The canonical shape of a T-block. Everything in <…> is a placeholder — the tool
never invents content for it. Sections marked omit are written only when they have
something to say; verify reports a block that is missing ### User or### Action, and treats the rest as optional.
## T<n> · <one-line gist> · [tag] [tag]
--- WHEN: <YYYY-MM-DD HH:mm> ---
### Author
- <who recorded this turn> (omit when unsigned)
### User
- <the request, every part and every condition>
### Action
- <operation> <file path> — <what changed>
### Decisions & Constraints
- <why this approach> (non-trivial → also an ADR in decisions.md)
### Uncertain
- ❓ <inferred, not confirmed>
Full field reference, including the sections this example leaves out: SKILL-reference.md.
The --- WHEN: … --- line (format v2, right under the heading) is when that turn happened. log append writes the moment you record it; pass --when when the user said something else — --when "09:00 → 11:30" for a stretch of time, --when "<YYYY-MM-DD>" when only the day is known (it stores (day), never a fake midnight), --when "<the user's own words>" to keep them verbatim. recall shows it, and a folder still on v1 simply has no such line until migrate --to latest — passing --when there still records the turn (log.md is P0) but says why the time did not land (whenSkipped in --json), rather than swallowing it.
### Author is there only when someone was told who wrote the turn (log append --author). It is a section like any other, not a structural line, so it changed nothing about the format version: a v1 folder may already have one, and a block without it is not incomplete — the tool never fills in a name it was not given.
🎯 Design Principles
| Principle | Meaning |
|---|---|
| Completeness > Brevity | Better to over-record than miss — a missed turn breaks the handoff chain |
| Always P0: log.md | Even under token pressure, the conversation timeline must never stop |
| T-numbers monotonically increase | T1, T2, T3... never reset, fully traceable |
| 🔒 red-line confirmation | When user says "must", the agent asks "mark as 🔒?" |
| Conflicts visible, never silently overwritten | When contradictions appear, keep both, mark superseded |
| Agent-agnostic | All files are pure-text Markdown, readable by any agent |
🗂 Project Type Templates
On first activation, the agent asks (or auto-detects) the project type and pre-fills different fields:
| Type | Focus areas |
|---|---|
| frontend | bundler, framework, state management, design tokens, build config |
| backend | API style, auth scheme, DB + migrations dir, cache, queue/worker |
| fullstack | Both above + API boundary, shared types location, proxy config |
| data | data sources, pipeline steps, schedule, notebook env, output storage |
| mobile | platform, min SDK/OS, build target, store/CDN, deep links |
🔧 Advanced Configuration (Optional)
Create ContextPocket/config.md to customize behavior:
# Config
- project_type: fullstack
- mode: full # full = 10 core files (+2 created on demand); lite = 5 core files only
- archive_at: 800 # log.md line count at which status/verify say "archive is due" (archiving itself is never automatic)
- recent_keep: 30 # how many recent full T-blocks archive keeps in log.md (override per run with --keep-last)
- language: en # recording language (zh / en / follow user)
- quiet: true # true = one-line confirmation per turn
- secret_scan: true # verify scans the pocket's markdown for credential/PII shapes (sk-ant-…, AKIA…, private-key
# blocks, JWT, ID numbers, card numbers, `password: xxxx`). Vendor-shaped keys are an ERROR —
# i.e. they block the pre-commit hook; personal data is a WARNING and never blocks. Set to
# false only when the pocket is *supposed* to hold such strings (a key-rotation runbook)
- gitignore: true # value used at initialization (bootstrap --gitignore false records false
# and leaves ContextPocket/ out of .gitignore). Editing it later does NOT
# rewrite .gitignore — edit that file yourself
- tags_default: [requirement-change, code-logic, arch-decision, bug, preference, dependency, test, ui, api, deploy, docs, pitfall, conflict, correction]
Lite mode in the full package: For scripts/small projects — creates only the 5 core files; others are created on demand. For the standalone ContextPocket Lite 2.8 package, which shares the temporal graph schema and simplifies read/write for small projects and daily conversation memory, see lite/.
🛡 Privacy & Security
ContextPocket/is pure-text Markdown, no executable code- Auto-ignored in
.gitignore(project-local data; manually push if desired) - No upload, no network — everything stays in your project directory
absolute.md(🔒 area) replaces on-device encryption — relies on discipline, not technology, to prevent compression- See SECURITY.md for supported versions, private vulnerability reporting and the security model.
🌐 User-level Hub (cross-project registry)
Each project has its own ContextPocket/, but you probably want one place that knows about every project you've enabled ContextPocket on — plus a cross-project set of preferences that follow you.
- Location:
~/.contextpocket/hub.json(a small JSON, indexed by project path) - Contents: registered projects (path → name / type / latest T / last-active) + user-level global preferences
- Design: the hub is only a registry. Project data always lives inside each project's
ContextPocket/. A hub failure (full disk, permission denied) will not affect normal recording. - Two ways to share across machines:
- Env var:
export CONTEXTPOCKET_HOME=/path/to/synced/folder(point it at a cloud drive / Dropbox / iCloud / git bare repo). All machines share onehub.json. - Git into the repo: at
bootstrapadd--gitignore: false(or the MCP equivalentgitignore: false) to commit the entireContextPocket/directory, including project-local preferences.
- Env var:
- Commands:
context-pocket hub list·context-pocket hub pref --key <k> --value <v>·context-pocket hub remove - Opting out of the registry:
bootstrap --no-hub(MCPnoHub: true) creates the pocket and writes nothing underCONTEXTPOCKET_HOME. Use it for throwaway projects, CI jobs and scripted one-shot bootstraps, so the hub keeps only the projects you actually work in. The pocket itself is complete and fully usable;hub listjust won't show it. Register it later by running the same command without--no-hub(bootstrap is idempotent — it re-registers and leaves your recorded history untouched).
🆚 Comparison with Alternatives
| Tool | Characteristic | ContextPocket advantage |
|---|---|---|
| Agent built-in memory | Lost across models | ✅ Model-agnostic |
| Manual notes | Easy to miss | ✅ Auto-captured |
| Git commit messages | Code-only | ✅ Records intent + decisions + traps |
| Obsidian/Notion | External, out of sync | ✅ Lives with the project |
| Custom scripts | High maintenance | ✅ Out-of-the-box |
❓ FAQ
Q: Do I have to use MiniMax Code?
No. Any agent that supports skill loading works (Claude Code / Cursor / Continue, etc.). All files are plain Markdown, readable in any text editor. See docs/COMPATIBILITY.md for the full list.
Q: What if my project is already in progress when I start using this?
Fully compatible. The first activation (bootstrap) scans the existing project, builds the code map, and starts recording from T1. Past conversations won't be "back-filled" (the agent has no memory of them), but the code state will continue.
Q: I started using this mid-project — can I recover the conversations I had with Claude Code / Codex?
Yes. Find the session file (~/.claude/projects/<project>/<session>.jsonl or ~/.codex/sessions/<id>.jsonl) and ask the agent to import it — it runs:
context-pocket import --file ~/.claude/projects/<project>/<session>.jsonl --dir <root>
It continues numbering from your current latest T, tags every imported block [imported], and writes them into log.md. Tool noise is skipped automatically. Source type is auto-detected; force a specific source with --source claude-code or --source codex. --limit N caps how many turns get imported (default 100), --truncate N caps each field (default 400).
Q: Will multiple users/agents conflict?
Two different situations, and the answer is different for each:
- Several agents on one machine — writing at the same time is safe. Every write takes a lock
before it reads the latest T and appends (withPocketLockinlib/io.js), so concurrent
agents queue and each gets its own T-id. The lock file lives inos.tmpdir()keyed by the
pocket path, so its scope is exactly one machine. - Several machines sharing one
ContextPocket/through git — still designed for serial
handoff: one agent works → commits → the next pulls. Two clones writing at the same moment
each computelatestT + 1from their own copy and both write, say,T9; after the mergelog.mdcontains two## T9blocks.verifyflags that as an error and names the fix, andcontext-pocket repair --dry-run→context-pocket repairrenumbers the colliding block (and
everything after it) back into a legal sequence, lists the prose that still names the old
numbers, and records the move as an[auto]T-block. Two things it deliberately never rewrites:
a reference has to be a standaloneT<n>, so words that merely contain the shape (GPT4,RTX4090,UTF8) stay untouched; and attachment file names (assets/T04-diagram.png) are not
references — renaming one ismvplus a text edit, and doing only the text half would leave a
broken link and drop the zero-padding, so repair lists them separately with the exactmv
command instead. The prose references themselves are not rewritten
unless you add--apply-refs, because a line sayingT9may have meant either block, and
only a reader knows which.
Either way, sign the turn when more than one agent shares a pocket: log append --author agent-A
puts the writer in the block's ### Author section. And since every append already compares the
turn against what the pocket says, a second agent contradicting the first one shows up in that
block's ### Conflicts section prefixed [auto] — the disagreement becomes part of the history
instead of silently overwriting it.
Q: What happens under tight token budgets?
Degrade in P0→P6 priority: log.md always writes, index.md last. See SKILL.md "Per-turn rules" for details.
More questions: see docs/FAQ.md.
🧩 Contributing
PRs welcome! See CONTRIBUTING.md.
Local development
git clone https://github.com/Wink305/ContextPocket.git
cd context-pocket
npm link # gives you the `context-pocket` command from this checkout
# edit templates/ or SKILL.md
# when submitting a PR, include project type + size you tested with
npm scripts (all zero-dependency):
| Script | Command it runs | Notes |
|---|---|---|
npm run lint |
node --check over every .js file in the repo |
Walks bin/, lib/, scripts/, root; no test runner, no glob library |
npm run smoke |
node mcp-smoke.js |
Drives the MCP server over stdio. With no argument it bootstraps a throwaway pocket in your OS temp dir, isolates CONTEXTPOCKET_HOME there and deletes it on exit, so it runs standalone. Target a specific project with npm run smoke -- /path/to/project (then set CONTEXTPOCKET_HOME=<hub-dir> unless you want the hub writes to land in your real ~/.contextpocket) |
npm test |
node tests/run.js |
Requires the test runner under tests/ |
Adding a new template
Add a .md file under templates/, ensuring:
- Placeholders wrapped in
<...>for easy identification - Add a row to the "Bootstrapping from templates" table in SKILL-advanced.md
- Pre-fill for at least one project type
📄 License
MIT © 2024 ContextPocket Contributors
🙏 Acknowledgments
- T-block format inspired by Conventional Comments
- Project born from pain points with various agent built-in memory systems
- Thanks to all contributors and early users
⭐ If this project helped you, a Star would be appreciated!
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found