claude-memory-admin 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +111 -9
- package/package.json +8 -2
- package/public/app.mjs +633 -362
- package/public/graph.mjs +32 -76
- package/public/index.html +34 -29
- package/public/markdown.mjs +74 -0
- package/public/styles.css +2 -402
- package/public/ui.mjs +291 -0
- package/server.mjs +61 -20
- package/src/instructions.mjs +423 -0
- package/src/model.mjs +44 -11
- package/src/mutate.mjs +17 -23
- package/src/pathcache.mjs +93 -0
- package/src/projects.mjs +120 -34
- package/src/search.mjs +13 -11
- package/src/settings.mjs +151 -0
- package/src/stats.mjs +105 -12
- package/src/stores.mjs +146 -0
package/README.md
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
[](https://github.com/linkdotnet/claude-memory-admin/actions/workflows/ci.yml)
|
|
4
4
|
[](https://www.npmjs.com/package/claude-memory-admin)
|
|
5
5
|
|
|
6
|
-
Browse, audit and prune the
|
|
6
|
+
Browse, audit and prune the memory Claude Code writes for itself: the **auto
|
|
7
|
+
memory** kept per project, and the **subagent memory** kept per agent.
|
|
7
8
|
|
|
8
9
|
```bash
|
|
9
10
|
npm install -g claude-memory-admin
|
|
@@ -13,6 +14,11 @@ claude-memory-admin
|
|
|
13
14
|
It opens `http://localhost:4173` and reads `~/.claude/projects/*/memory/`.
|
|
14
15
|
Nothing leaves your machine; the server binds `127.0.0.1` only.
|
|
15
16
|
|
|
17
|
+
This project is built heavily with AI tooling: most of the code, the tests
|
|
18
|
+
and this README were written by Claude Code, with a human directing the design
|
|
19
|
+
and reviewing what landed. Fitting for a tool about what Claude writes for
|
|
20
|
+
itself, and worth saying out loud.
|
|
21
|
+
|
|
16
22
|
<sub>Brought to you by [BitSpire](https://bitspire.ch/).</sub>
|
|
17
23
|
|
|
18
24
|
---
|
|
@@ -37,6 +43,21 @@ Claude Code keeps two kinds of memory. This tool is about the second one:
|
|
|
37
43
|
| Lives in | `./CLAUDE.md`, `~/.claude/CLAUDE.md` | `~/.claude/projects/<project>/memory/` |
|
|
38
44
|
| Contains | rules and instructions | learnings Claude picked up |
|
|
39
45
|
|
|
46
|
+
Subagents declaring `memory:` in their frontmatter get their own directories,
|
|
47
|
+
which hold exactly the same thing under a different name, so they are shown
|
|
48
|
+
alongside the projects:
|
|
49
|
+
|
|
50
|
+
| Scope | Lives in |
|
|
51
|
+
| --- | --- |
|
|
52
|
+
| `user` | `~/.claude/agent-memory/<agent>/` |
|
|
53
|
+
| `project` | `<repo>/.claude/agent-memory/<agent>/` |
|
|
54
|
+
| `local` | `<repo>/.claude/agent-memory-local/<agent>/` |
|
|
55
|
+
|
|
56
|
+
The project-scoped ones are found under the repositories this tool already
|
|
57
|
+
resolved from your session transcripts, so it never goes looking through
|
|
58
|
+
directories it has no reason to believe in. A `project`-scoped store is checked
|
|
59
|
+
into git, and the app says so before you delete anything from one.
|
|
60
|
+
|
|
40
61
|
The auto memory directory holds `MEMORY.md` (a concise index) plus one topic
|
|
41
62
|
file per memory, cross-linked with `[[wikilinks]]`.
|
|
42
63
|
|
|
@@ -51,8 +72,23 @@ project is to the cliff, and makes it quick to get back under it.
|
|
|
51
72
|
(`-Users-me-repos-Blog`) and the slugification is lossy. The true path is
|
|
52
73
|
recovered from the `cwd` field in the session transcripts stored next to each
|
|
53
74
|
memory directory; anything that cannot be confirmed is shown as the raw slug
|
|
54
|
-
rather than a plausible guess.
|
|
55
|
-
|
|
75
|
+
rather than a plausible guess. Claude Code keys the store on the git
|
|
76
|
+
repository, so one memory directory serves every worktree and subdirectory of
|
|
77
|
+
a repo: when the transcripts disagree, the repository root wins and the other
|
|
78
|
+
directories are listed under the project name.
|
|
79
|
+
- **A store keeps its name after its evidence expires.** Claude Code sweeps
|
|
80
|
+
session transcripts on a retention period but never touches `memory/`, so a
|
|
81
|
+
project eventually loses the only proof of what it was called. **Remember
|
|
82
|
+
path** records one you confirm, and is the single thing this app writes
|
|
83
|
+
outside a `memory/` directory.
|
|
84
|
+
- **Where the store is** is read the way Claude Code reads it: `autoMemoryDirectory`
|
|
85
|
+
from any settings layer, managed policy through project and local, not just
|
|
86
|
+
`~/.claude/settings.json`. A value that is neither absolute nor `~/`-prefixed
|
|
87
|
+
is reported rather than quietly ignored.
|
|
88
|
+
- **Whether Claude is still writing.** A project with `autoMemoryEnabled` off, or
|
|
89
|
+
`CLAUDE_CODE_DISABLE_AUTO_MEMORY` set, has a store that will never grow again,
|
|
90
|
+
which on disk is indistinguishable from one Claude has not learned anything
|
|
91
|
+
about yet. The project header says which it is, and names the file that decided.
|
|
56
92
|
- **Search across every project**: names, descriptions, bodies and index hooks,
|
|
57
93
|
with snippets and match highlighting. Press `/` to jump to it.
|
|
58
94
|
- **Read each memory** with its frontmatter as structured metadata and
|
|
@@ -62,8 +98,19 @@ project is to the cliff, and makes it quick to get back under it.
|
|
|
62
98
|
a neighbour, which is the only practical way to read a dense cluster.
|
|
63
99
|
- **Health**: orphans, dangling pointers, broken wikilinks, files linked only
|
|
64
100
|
mid-sentence, `name` fields that disagree with the filename.
|
|
101
|
+
- **Dates you can trust.** Claude Code stamps `modified` into frontmatter, but
|
|
102
|
+
only on files that already have some, and never adds frontmatter to a file
|
|
103
|
+
without it. Anything falling back to the file's mtime is labelled, because
|
|
104
|
+
mtime is reset by any copy or restore.
|
|
105
|
+
- **Context**: what a session starting in this project would load as
|
|
106
|
+
*instructions*, which is the other half of the startup budget (see below).
|
|
65
107
|
- **Delete with cascade**, always reversible.
|
|
66
108
|
|
|
109
|
+
Everything above works the same on both kinds of store. The load meter, graph,
|
|
110
|
+
health checks and trash never needed to know which they were reading: a subagent
|
|
111
|
+
memory directory is a `MEMORY.md` index plus topic files under the same 200-line
|
|
112
|
+
/ 25KB limit.
|
|
113
|
+
|
|
67
114
|
## Keeping MEMORY.md small
|
|
68
115
|
|
|
69
116
|
The **Prune** tab exists because a bloated index costs tokens on every single
|
|
@@ -72,6 +119,14 @@ session and, past the limit, silently stops loading.
|
|
|
72
119
|
- **Load meter**. How much of the 200-line / 25KB budget the index uses, and
|
|
73
120
|
which of the two is binding. Frontmatter and HTML comments are excluded,
|
|
74
121
|
because Claude Code strips those before loading.
|
|
122
|
+
- **The cutoff, drawn where it falls**. Past the limit, the MEMORY.md tab rules a
|
|
123
|
+
line across the file and dims everything below it, and Prune names the memories
|
|
124
|
+
that stopped being loaded. Because the stripping shifts every line, the cutoff
|
|
125
|
+
is mapped back to real line numbers rather than counted in the loaded text. The
|
|
126
|
+
tab reads the index either **rendered** — headings, lists and clickable entries,
|
|
127
|
+
with pointers to files that do not exist struck through — or as **source**, with
|
|
128
|
+
line numbers. Either way the cutoff is drawn in the same place. The choice is
|
|
129
|
+
remembered.
|
|
75
130
|
- **Long hooks**. The hook is the text after the dash in `MEMORY.md`. A
|
|
76
131
|
400-character hook can cost more than the memory it points at, and shortening
|
|
77
132
|
it is the cheapest win available.
|
|
@@ -84,6 +139,36 @@ session and, past the limit, silently stops loading.
|
|
|
84
139
|
Anthropic's own guidance for the index: one line per entry, detail in the topic
|
|
85
140
|
files, merge or drop stale entries.
|
|
86
141
|
|
|
142
|
+
## The other half of the budget
|
|
143
|
+
|
|
144
|
+
`MEMORY.md` is not the only thing loaded at the start of every session. The
|
|
145
|
+
**Context** tab resolves what else is, in load order: managed policy, your
|
|
146
|
+
`~/.claude/CLAUDE.md` and `~/.claude/rules/`, every `CLAUDE.md` and
|
|
147
|
+
`CLAUDE.local.md` from the filesystem root down to the project, `.claude/CLAUDE.md`,
|
|
148
|
+
and `.claude/rules/`, with `@path` imports expanded and `claudeMdExcludes` applied.
|
|
149
|
+
|
|
150
|
+
Unlike `MEMORY.md`, none of it is truncated: `CLAUDE.md` files load in full
|
|
151
|
+
however long they are. So the tab reports cost rather than a cliff, and separates
|
|
152
|
+
what every session pays for from the path-scoped rules that only load on a match.
|
|
153
|
+
|
|
154
|
+
It also finds the failures that leave a file silently doing nothing:
|
|
155
|
+
|
|
156
|
+
- Imports that do not resolve, chains past the four-hop maximum, and cycles.
|
|
157
|
+
- Imports resolving outside the project, which Claude Code asks you to approve
|
|
158
|
+
once and which stay disabled if you decline.
|
|
159
|
+
- A `paths:` glob with a `[` that cannot be read as a bracket expression. It is
|
|
160
|
+
invalid, so it matches nothing and the rule never applies.
|
|
161
|
+
- Brace expansion past the 1,000-pattern budget, where the pattern is used
|
|
162
|
+
unexpanded and its literal braces match no file either.
|
|
163
|
+
- An `AGENTS.md` that no `CLAUDE.md` imports. Claude Code reads `CLAUDE.md`.
|
|
164
|
+
|
|
165
|
+
Backticks are respected, so a `` `@README` `` in your prose is not reported as an
|
|
166
|
+
import, and neither is an email address.
|
|
167
|
+
|
|
168
|
+
This is re-derived from the documented resolution rules rather than reported by
|
|
169
|
+
Claude Code, and the tab says so. Run `/context` in a session for the ground
|
|
170
|
+
truth, or the `InstructionsLoaded` hook to log exactly what loaded and why.
|
|
171
|
+
|
|
87
172
|
## Deleting is reversible
|
|
88
173
|
|
|
89
174
|
Delete shows a preview first: the exact lines that will go, the prose mentions it
|
|
@@ -127,6 +212,10 @@ claude-memory-admin --root /tmp/memory-snapshot
|
|
|
127
212
|
- Binds `127.0.0.1`; no telemetry, no network calls.
|
|
128
213
|
- Every write target must resolve to a plain `.md` file inside that project's own
|
|
129
214
|
`memory/` directory. `..`, absolute paths and subdirectories are refused.
|
|
215
|
+
- One exception, and only when you ask for it: **Remember path** writes
|
|
216
|
+
`~/.claude-memory-admin/paths.json`. It holds folder slugs and the directory
|
|
217
|
+
paths you confirmed, never memory content, and forgetting the last entry
|
|
218
|
+
deletes the file. Nothing creates it until you use the action.
|
|
130
219
|
- `MEMORY.md` is replaced atomically (temp file, `fsync`, `rename`) with a backup
|
|
131
220
|
restored if anything throws.
|
|
132
221
|
- A test asserts that parsing and rewriting every real `MEMORY.md` with no
|
|
@@ -141,26 +230,39 @@ cd claude-memory-admin
|
|
|
141
230
|
npm install
|
|
142
231
|
npm start # or: node server.mjs
|
|
143
232
|
npm test # runs on a throwaway copy of your real store
|
|
233
|
+
npm run dev:css # only when editing styles/app.css
|
|
144
234
|
```
|
|
145
235
|
|
|
146
|
-
No bundler and no build step: the backend is `node:http` plus `node:fs`,
|
|
147
|
-
frontend is plain ES modules the browser loads directly. Two runtime
|
|
148
|
-
`marked` and `dompurify`, both only for rendering memory bodies safely.
|
|
236
|
+
No bundler and no build step to run it: the backend is `node:http` plus `node:fs`,
|
|
237
|
+
and the frontend is plain ES modules the browser loads directly. Two runtime
|
|
238
|
+
dependencies, `marked` and `dompurify`, both only for rendering memory bodies safely.
|
|
239
|
+
|
|
240
|
+
Styling is the one thing that is compiled. `styles/app.css` is the Tailwind v4
|
|
241
|
+
source and `public/styles.css` is its committed output, so an installed copy is
|
|
242
|
+
ready to serve and never builds anything. After editing the source, run
|
|
243
|
+
`npm run build:css` and commit the result — CI rebuilds it and fails on drift.
|
|
149
244
|
|
|
150
245
|
| Path | Purpose |
|
|
151
246
|
| --- | --- |
|
|
152
247
|
| `bin/claude-memory-admin.mjs` | CLI entry point and argument parsing |
|
|
153
248
|
| `server.mjs` | HTTP server: static files + JSON API |
|
|
154
249
|
| `src/projects.mjs` | Project discovery, slug → real path resolution |
|
|
250
|
+
| `src/settings.mjs` | Layered reads of Claude Code's settings files |
|
|
251
|
+
| `src/pathcache.mjs` | The opt-in record of confirmed project paths |
|
|
252
|
+
| `src/stores.mjs` | Store discovery: auto memory and the three agent scopes |
|
|
253
|
+
| `src/instructions.mjs` | CLAUDE.md chain, `@` imports and rules resolution |
|
|
155
254
|
| `src/parse.mjs` | `MEMORY.md` and frontmatter parsers, wikilinks |
|
|
156
255
|
| `src/model.mjs` | Joins index, files, graph and health into one model |
|
|
157
256
|
| `src/stats.mjs` | Load-limit accounting and overlap detection |
|
|
158
|
-
| `src/search.mjs` | Full-text search across
|
|
257
|
+
| `src/search.mjs` | Full-text search across every store |
|
|
159
258
|
| `src/mutate.mjs` | Delete / restore / unlink, the only code that writes |
|
|
259
|
+
| `styles/app.css` | Tailwind source, compiled to `public/styles.css` |
|
|
160
260
|
| `public/` | Frontend |
|
|
161
261
|
|
|
162
|
-
Tests run against
|
|
163
|
-
|
|
262
|
+
Tests run against committed fixtures under `test/fixtures/`: a projects store
|
|
263
|
+
encoding the awkward shapes real memory directories contain, including one index
|
|
264
|
+
deliberately past the load limit, an `agents/` tree covering all three subagent
|
|
265
|
+
scopes, and an `instructions/` tree covering the import and glob edge cases. Your own
|
|
164
266
|
`~/.claude/projects` is additionally checked when it exists, always on a
|
|
165
267
|
throwaway copy.
|
|
166
268
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-memory-admin",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Browse, audit and prune the auto memory Claude Code keeps under ~/.claude/projects",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
|
@@ -54,10 +54,16 @@
|
|
|
54
54
|
},
|
|
55
55
|
"scripts": {
|
|
56
56
|
"start": "node bin/claude-memory-admin.mjs",
|
|
57
|
-
"test": "node --test test/*.test.mjs"
|
|
57
|
+
"test": "node --test test/*.test.mjs",
|
|
58
|
+
"build:css": "tailwindcss -i styles/app.css -o public/styles.css --minify",
|
|
59
|
+
"dev:css": "tailwindcss -i styles/app.css -o public/styles.css --watch",
|
|
60
|
+
"prepublishOnly": "npm run build:css"
|
|
58
61
|
},
|
|
59
62
|
"dependencies": {
|
|
60
63
|
"dompurify": "^3.2.7",
|
|
61
64
|
"marked": "^16.4.0"
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@tailwindcss/cli": "^4.3.3"
|
|
62
68
|
}
|
|
63
69
|
}
|