claude-memory-admin 1.0.0 → 1.0.1
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 +97 -6
- package/package.json +1 -1
- package/public/app.mjs +387 -90
- package/public/styles.css +37 -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,10 @@ 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.
|
|
75
126
|
- **Long hooks**. The hook is the text after the dash in `MEMORY.md`. A
|
|
76
127
|
400-character hook can cost more than the memory it points at, and shortening
|
|
77
128
|
it is the cheapest win available.
|
|
@@ -84,6 +135,36 @@ session and, past the limit, silently stops loading.
|
|
|
84
135
|
Anthropic's own guidance for the index: one line per entry, detail in the topic
|
|
85
136
|
files, merge or drop stale entries.
|
|
86
137
|
|
|
138
|
+
## The other half of the budget
|
|
139
|
+
|
|
140
|
+
`MEMORY.md` is not the only thing loaded at the start of every session. The
|
|
141
|
+
**Context** tab resolves what else is, in load order: managed policy, your
|
|
142
|
+
`~/.claude/CLAUDE.md` and `~/.claude/rules/`, every `CLAUDE.md` and
|
|
143
|
+
`CLAUDE.local.md` from the filesystem root down to the project, `.claude/CLAUDE.md`,
|
|
144
|
+
and `.claude/rules/`, with `@path` imports expanded and `claudeMdExcludes` applied.
|
|
145
|
+
|
|
146
|
+
Unlike `MEMORY.md`, none of it is truncated: `CLAUDE.md` files load in full
|
|
147
|
+
however long they are. So the tab reports cost rather than a cliff, and separates
|
|
148
|
+
what every session pays for from the path-scoped rules that only load on a match.
|
|
149
|
+
|
|
150
|
+
It also finds the failures that leave a file silently doing nothing:
|
|
151
|
+
|
|
152
|
+
- Imports that do not resolve, chains past the four-hop maximum, and cycles.
|
|
153
|
+
- Imports resolving outside the project, which Claude Code asks you to approve
|
|
154
|
+
once and which stay disabled if you decline.
|
|
155
|
+
- A `paths:` glob with a `[` that cannot be read as a bracket expression. It is
|
|
156
|
+
invalid, so it matches nothing and the rule never applies.
|
|
157
|
+
- Brace expansion past the 1,000-pattern budget, where the pattern is used
|
|
158
|
+
unexpanded and its literal braces match no file either.
|
|
159
|
+
- An `AGENTS.md` that no `CLAUDE.md` imports. Claude Code reads `CLAUDE.md`.
|
|
160
|
+
|
|
161
|
+
Backticks are respected, so a `` `@README` `` in your prose is not reported as an
|
|
162
|
+
import, and neither is an email address.
|
|
163
|
+
|
|
164
|
+
This is re-derived from the documented resolution rules rather than reported by
|
|
165
|
+
Claude Code, and the tab says so. Run `/context` in a session for the ground
|
|
166
|
+
truth, or the `InstructionsLoaded` hook to log exactly what loaded and why.
|
|
167
|
+
|
|
87
168
|
## Deleting is reversible
|
|
88
169
|
|
|
89
170
|
Delete shows a preview first: the exact lines that will go, the prose mentions it
|
|
@@ -127,6 +208,10 @@ claude-memory-admin --root /tmp/memory-snapshot
|
|
|
127
208
|
- Binds `127.0.0.1`; no telemetry, no network calls.
|
|
128
209
|
- Every write target must resolve to a plain `.md` file inside that project's own
|
|
129
210
|
`memory/` directory. `..`, absolute paths and subdirectories are refused.
|
|
211
|
+
- One exception, and only when you ask for it: **Remember path** writes
|
|
212
|
+
`~/.claude-memory-admin/paths.json`. It holds folder slugs and the directory
|
|
213
|
+
paths you confirmed, never memory content, and forgetting the last entry
|
|
214
|
+
deletes the file. Nothing creates it until you use the action.
|
|
130
215
|
- `MEMORY.md` is replaced atomically (temp file, `fsync`, `rename`) with a backup
|
|
131
216
|
restored if anything throws.
|
|
132
217
|
- A test asserts that parsing and rewriting every real `MEMORY.md` with no
|
|
@@ -152,15 +237,21 @@ frontend is plain ES modules the browser loads directly. Two runtime dependencie
|
|
|
152
237
|
| `bin/claude-memory-admin.mjs` | CLI entry point and argument parsing |
|
|
153
238
|
| `server.mjs` | HTTP server: static files + JSON API |
|
|
154
239
|
| `src/projects.mjs` | Project discovery, slug → real path resolution |
|
|
240
|
+
| `src/settings.mjs` | Layered reads of Claude Code's settings files |
|
|
241
|
+
| `src/pathcache.mjs` | The opt-in record of confirmed project paths |
|
|
242
|
+
| `src/stores.mjs` | Store discovery: auto memory and the three agent scopes |
|
|
243
|
+
| `src/instructions.mjs` | CLAUDE.md chain, `@` imports and rules resolution |
|
|
155
244
|
| `src/parse.mjs` | `MEMORY.md` and frontmatter parsers, wikilinks |
|
|
156
245
|
| `src/model.mjs` | Joins index, files, graph and health into one model |
|
|
157
246
|
| `src/stats.mjs` | Load-limit accounting and overlap detection |
|
|
158
|
-
| `src/search.mjs` | Full-text search across
|
|
247
|
+
| `src/search.mjs` | Full-text search across every store |
|
|
159
248
|
| `src/mutate.mjs` | Delete / restore / unlink, the only code that writes |
|
|
160
249
|
| `public/` | Frontend |
|
|
161
250
|
|
|
162
|
-
Tests run against
|
|
163
|
-
|
|
251
|
+
Tests run against committed fixtures under `test/fixtures/`: a projects store
|
|
252
|
+
encoding the awkward shapes real memory directories contain, including one index
|
|
253
|
+
deliberately past the load limit, an `agents/` tree covering all three subagent
|
|
254
|
+
scopes, and an `instructions/` tree covering the import and glob edge cases. Your own
|
|
164
255
|
`~/.claude/projects` is additionally checked when it exists, always on a
|
|
165
256
|
throwaway copy.
|
|
166
257
|
|