hypomnema 1.4.0 → 1.4.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/README.ko.md +151 -153
- package/README.md +121 -123
- package/commands/audit.md +4 -4
- package/commands/crystallize.md +18 -5
- package/commands/doctor.md +3 -3
- package/commands/feedback.md +5 -3
- package/commands/graph.md +3 -3
- package/commands/ingest.md +6 -4
- package/commands/init.md +5 -3
- package/commands/lint.md +3 -3
- package/commands/query.md +3 -3
- package/commands/rename.md +4 -4
- package/commands/resume.md +4 -2
- package/commands/stats.md +3 -3
- package/commands/upgrade.md +4 -4
- package/commands/verify.md +3 -3
- package/docs/CONTRIBUTING.md +95 -11
- package/package.json +6 -1
- package/scripts/check-bilingual.mjs +49 -11
- package/scripts/check-tracker-ids.mjs +60 -1
- package/scripts/crystallize.mjs +30 -2
- package/scripts/lib/changelog-classify.mjs +216 -0
- package/scripts/lib/check-bilingual.mjs +125 -22
- package/scripts/lib/check-tracker-ids.mjs +19 -0
- package/scripts/weekly-report.mjs +9 -3
- package/skills/crystallize/SKILL.md +21 -1
- package/templates/hypo-config.md +1 -1
- package/scripts/bump-version.mjs +0 -77
- package/scripts/smoke-pack.mjs +0 -261
- package/scripts/smoke-plugin.mjs +0 -194
package/README.md
CHANGED
|
@@ -13,33 +13,34 @@ English | [한국어](README.ko.md)
|
|
|
13
13
|
[](https://github.com/sk-lim19f/Hypomnema/actions/workflows/ci.yml)
|
|
14
14
|
[](https://github.com/sk-lim19f/Hypomnema/stargazers)
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
LLM-native personal wiki for Claude Code. Knowledge that compounds.
|
|
17
17
|
|
|
18
|
-
_Make Claude take notes
|
|
18
|
+
_Make Claude take notes, and measure whether it actually does._
|
|
19
19
|
|
|
20
20
|
[Quick Start](#quick-start) • [How It Compares](#how-it-compares) • [Design Decisions](#design-decisions) • [Features](#features) • [Architecture](docs/ARCHITECTURE.md) • [Contributing](docs/CONTRIBUTING.md)
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
Inspired by Andrej Karpathy's "LLM-native wiki" sketch, shaped by ten months of personal AI-workflow experiments and a month of dogfooding before the public release. Hypomnema ships the full lifecycle, from capturing a source to synthesizing, retrieving, and resuming a paused session, as Claude Code commands and lifecycle hooks.
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
New to the terms below? Keep the [Term decoder](#term-decoder) open in another tab. It defines frontmatter, wikilink, projection, hook, `hot.md`, and `session-state.md`, one line each.
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
26
|
+
### Where automation stands today
|
|
27
|
+
|
|
28
|
+
The current release is v1.4.1. Wiki work (ingest, query, session-close) still runs on explicit `/hypo:*` commands. The v2 goal is full autonomy: Claude reading, writing, and synthesizing the wiki without being asked, which is the direction this is heading. v1.1.0 shipped the observability score that measures how often the wiki is actually used per session. v1.2.0 added four autonomous lanes on top:
|
|
29
|
+
|
|
30
|
+
- Edit feedback in one place and the rest follows. `pages/feedback/` is the single source of truth for behavior corrections, and Hypomnema derives `MEMORY.md` and the `<learned_behaviors>` block inside `~/.claude/CLAUDE.md` from it automatically.
|
|
31
|
+
- Extensions sync alongside. Anything under `~/hypomnema/extensions/{agents,commands,hooks,skills}/` is mirrored into `~/.claude/` automatically. The `--codex` flag also mirrors `hooks` and `commands` into `~/.codex/`; `agents` and `skills` are Claude-only and skipped on purpose.
|
|
32
|
+
- Auto-project creation. When you `cd` into a git repo with a project marker (`package.json`, `Cargo.toml`, etc.) and no matching wiki project exists, Hypomnema offers to scaffold one.
|
|
33
|
+
- Session-close cleanup and `/clear` recovery. After a non-trivial session, a "save a minimal session-close note?" prompt appears automatically; a `/clear` after a forgotten close is detected and recovered at the next session start.
|
|
34
|
+
|
|
35
|
+
What changed per version lives in the [CHANGELOG](CHANGELOG.md). One policy worth knowing up front: `hypomnema upgrade --apply` never overwrites a `SCHEMA.md` you have edited. When the schema bumps, upgrade writes a migration report into the wiki root and leaves the actual changes for you to apply (the policy the code calls _Option C_).
|
|
35
36
|
|
|
36
37
|
---
|
|
37
38
|
|
|
38
39
|
## Quick Start
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
There are two install paths. Either one ends up with the same wiki, hooks, and `/hypo:*` slash commands.
|
|
41
42
|
|
|
42
|
-
### Path A
|
|
43
|
+
### Path A: Claude Code plugin (recommended)
|
|
43
44
|
|
|
44
45
|
Inside Claude Code:
|
|
45
46
|
|
|
@@ -51,7 +52,7 @@ Inside Claude Code:
|
|
|
51
52
|
|
|
52
53
|
The plugin install registers `/hypo:*` commands from the package's `commands/` directory; `/hypo:init` then scaffolds the wiki and merges hooks into `~/.claude/settings.json`.
|
|
53
54
|
|
|
54
|
-
### Path B
|
|
55
|
+
### Path B: npm CLI
|
|
55
56
|
|
|
56
57
|
In your shell:
|
|
57
58
|
|
|
@@ -60,7 +61,7 @@ npm install -g hypomnema
|
|
|
60
61
|
hypomnema
|
|
61
62
|
```
|
|
62
63
|
|
|
63
|
-
`hypomnema` (or `hypomnema --help` for flags) scaffolds the wiki
|
|
64
|
+
`hypomnema` (or `hypomnema --help` for flags) scaffolds the wiki and installs hooks. It also copies the slash command files to `~/.claude/commands/hypo/`, so `/hypo:*` works inside Claude Code afterwards. Later `hypomnema upgrade` runs use per-file SHA tracking, so anything you hand-edited stays put.
|
|
64
65
|
|
|
65
66
|
> Either path: restart Claude Code (or open a new session) after the first run so the new hooks and slash commands are picked up.
|
|
66
67
|
|
|
@@ -72,25 +73,25 @@ hypomnema
|
|
|
72
73
|
/hypo:feedback "always include test commands when explaining a fix"
|
|
73
74
|
```
|
|
74
75
|
|
|
75
|
-
Hooks handle the rest
|
|
76
|
+
Hooks handle the rest: auto-staging, auto-commit/push, session-state injection, and lookup signals.
|
|
76
77
|
|
|
77
|
-
>
|
|
78
|
+
> Sync across machines: the wiki is already a git repo. Add a remote, push once, and the `Stop` hook keeps every machine in sync afterwards.
|
|
78
79
|
|
|
79
80
|
---
|
|
80
81
|
|
|
81
82
|
## Why Hypomnema
|
|
82
83
|
|
|
83
|
-
Personal knowledge tools fall into five buckets
|
|
84
|
+
Personal knowledge tools fall into five buckets. Each breaks at a different place.
|
|
84
85
|
|
|
85
86
|
| | Pain | Why it doesn't compound |
|
|
86
87
|
|---|---|---|
|
|
87
|
-
|
|
|
88
|
-
|
|
|
89
|
-
|
|
|
90
|
-
|
|
|
91
|
-
|
|
|
88
|
+
| Note vaults (markdown-based, local-first) | Manual capture, manual linking, manual rereading | Each note stays independent; no synthesis |
|
|
89
|
+
| Cloud knowledge platforms (page/database hybrids) | Fast capture, slow retrieval | Search is keyword-first; LLM has no native access |
|
|
90
|
+
| RAG / vector-search stacks | Pipelines, embeddings, chunking | Returns chunks, not synthesized knowledge; chunks multiply forever |
|
|
91
|
+
| AI-native notebooks (proprietary "second brain" apps) | Feels magical at first | Closed format, no git, opaque retrieval logic, vendor lock-in |
|
|
92
|
+
| Code-only wikis (auto-generated from a repo) | Zero manual effort | Limited to code; can't capture decisions, research, AI behavior corrections |
|
|
92
93
|
|
|
93
|
-
Hypomnema lives in the gap between them:
|
|
94
|
+
Hypomnema lives in the gap between them: structured synthesis on top of plain markdown, driven by Claude Code's lifecycle, version-controlled by git, local-first by default.
|
|
94
95
|
|
|
95
96
|
```
|
|
96
97
|
Note vaults ───► store everything, synthesize nothing
|
|
@@ -106,106 +107,105 @@ Hypomnema ───► synthesis · markdown · git · hooks · local
|
|
|
106
107
|
|
|
107
108
|
## How It Compares
|
|
108
109
|
|
|
109
|
-
| |
|
|
110
|
+
| | Hypomnema | Note vault | Cloud platform | RAG / vector DB | AI notebook | Code wiki |
|
|
110
111
|
|---|---|---|---|---|---|---|
|
|
111
|
-
|
|
|
112
|
-
|
|
|
113
|
-
|
|
|
114
|
-
|
|
|
115
|
-
|
|
|
116
|
-
|
|
|
117
|
-
|
|
|
118
|
-
|
|
|
119
|
-
|
|
|
120
|
-
|
|
|
121
|
-
|
|
|
122
|
-
| **Lock-in** | Zero (markdown + git) | Low | High | Medium | High | Medium |
|
|
112
|
+
| Capture effort | Paste a URL → done | Manual typing | Manual typing | Upload + embed pipeline | Paste / chat | Auto from repo |
|
|
113
|
+
| Storage unit | Synthesized page | Note | Page / block | Vector chunk | Opaque memory | Code symbol |
|
|
114
|
+
| Knowledge growth | New sources update existing pages | Each note stays independent | Each page stays independent | Chunks multiply forever | Black box | Fixed by repo |
|
|
115
|
+
| Retrieval | LLM synthesizes a grounded answer | Full-text / backlinks | Keyword search | Nearest-neighbour chunks | Opaque | Code search |
|
|
116
|
+
| Session continuity | Auto-resume via `hot.md` + `session-state.md` | None | None | None | Sometimes | None |
|
|
117
|
+
| Workflow integration | Native to Claude Code | Separate app | Separate app / browser tab | Separate service | Separate app | Separate site |
|
|
118
|
+
| Format | Plain markdown + frontmatter | Markdown | Proprietary | Vector store | Proprietary | HTML |
|
|
119
|
+
| Behavior tuning | `/hypo:feedback` → permanent rules | None | None | None | Sometimes | None |
|
|
120
|
+
| Auto-behavior | `/hypo:*` triggers + observability score (v1.1) + four autonomous lanes (v1.2); v2 target = fully autonomous | None | None | None | Black box | None |
|
|
121
|
+
| Setup cost | One command | One install | Sign-up | Pipeline build | Sign-up | Repo connect |
|
|
122
|
+
| Lock-in | Zero (markdown + git) | Low | High | Medium | High | Medium |
|
|
123
123
|
|
|
124
124
|
### What this trade-off buys you
|
|
125
125
|
|
|
126
|
-
-
|
|
127
|
-
-
|
|
128
|
-
-
|
|
129
|
-
-
|
|
126
|
+
- Synthesis over storage. You don't end up with a graveyard of half-read articles. Each `/hypo:ingest` produces a structured page, and the next ingest on the same topic updates that page instead of adding a new one.
|
|
127
|
+
- Compounding density. A wiki with 100 sources should not be 100 disconnected pages. After a few months of real use, page count grows sub-linearly while cross-links grow faster.
|
|
128
|
+
- No context switch. You're already in Claude Code. The wiki is one slash command away, with no extra tab, app, or login.
|
|
129
|
+
- Future-proof storage. Plain markdown + git will still be readable in 20 years, greps offline, moves to another tool anytime, and stays usable by AI assistants that don't exist yet, with no conversion needed.
|
|
130
130
|
|
|
131
131
|
---
|
|
132
132
|
|
|
133
133
|
## Term decoder
|
|
134
134
|
|
|
135
|
-
|
|
135
|
+
These are the recurring terms used in the rest of the README. Keep this table open in another tab while you skim.
|
|
136
136
|
|
|
137
137
|
| Term | Meaning in Hypomnema |
|
|
138
138
|
|---|---|
|
|
139
|
-
|
|
|
140
|
-
|
|
|
141
|
-
|
|
|
142
|
-
|
|
|
143
|
-
|
|
|
144
|
-
|
|
|
145
|
-
|
|
|
146
|
-
|
|
|
147
|
-
|
|
|
148
|
-
|
|
|
149
|
-
|
|
|
150
|
-
|
|
|
151
|
-
|
|
|
152
|
-
|
|
|
153
|
-
|
|
|
154
|
-
|
|
|
155
|
-
|
|
|
156
|
-
|
|
|
157
|
-
|
|
158
|
-
If a term you hit later in the README is missing here, that is a documentation bug
|
|
139
|
+
| frontmatter | The YAML block at the top of a markdown page: `title`, `type`, `tags`, etc. |
|
|
140
|
+
| wikilink | A `[[page-slug]]` cross-reference between pages; resolved at lint time |
|
|
141
|
+
| ADR | "Architecture Decision Record": a short markdown page recording _why_ a non-obvious design choice was made |
|
|
142
|
+
| schema | The type taxonomy and required-field rules in `SCHEMA.md`: what makes a page valid |
|
|
143
|
+
| lint | A read-only validator (`hypomnema lint`) that checks frontmatter, wikilinks, and schema |
|
|
144
|
+
| projection | A one-way automatic derivation: `pages/feedback/*.md` → `MEMORY.md` and CLAUDE.md `<learned_behaviors>` |
|
|
145
|
+
| SoT ("source of truth") | The single file you edit; projections derive from it, never the other way around |
|
|
146
|
+
| hook | A script Claude Code runs automatically on a lifecycle event (e.g. `SessionStart`, `Stop`) |
|
|
147
|
+
| lifecycle event | A point Claude Code surfaces to plugins: session opens, prompt submitted, tool used, compact requested, session ends, etc. |
|
|
148
|
+
| `hot.md` | Per-project cache: "what just happened" (most recent session highlights) |
|
|
149
|
+
| `session-state.md` | Per-project cache: "what's next" (the resume payload for the next session) |
|
|
150
|
+
| `.hypoignore` | Glob patterns that exclude paths from every content-injection hook and from `ingest` |
|
|
151
|
+
| observability score | A per-session metric (ingest / query / session-close / citation rates) that measures whether the wiki is actually being used |
|
|
152
|
+
| manifest | A small JSON the install scripts write to track exactly which files were installed and at what SHA |
|
|
153
|
+
| `additionalContext` | The Claude Code hook field that injects extra context into the prompt: where content-injection hooks emit |
|
|
154
|
+
| byte-equal | A file that comes out of `--apply` bit-for-bit identical to before: the strongest "we did not touch this" guarantee |
|
|
155
|
+
| BM25 | A classic full-text ranking algorithm; powers the `/hypo:query` MISS-resistant lookup |
|
|
156
|
+
| Option C | The policy that `hypomnema upgrade --apply` never overwrites your `SCHEMA.md`: it only writes a migration report you apply by hand |
|
|
157
|
+
|
|
158
|
+
If a term you hit later in the README is missing here, that is a documentation bug. Please open an issue.
|
|
159
159
|
|
|
160
160
|
---
|
|
161
161
|
|
|
162
162
|
## Design Decisions
|
|
163
163
|
|
|
164
|
-
Why each choice looks the way it does
|
|
164
|
+
Why each choice looks the way it does.
|
|
165
165
|
|
|
166
|
-
### 1. Why
|
|
166
|
+
### 1. Why synthesis instead of RAG over chunks
|
|
167
167
|
|
|
168
|
-
RAG is excellent for
|
|
168
|
+
RAG is excellent for _unfamiliar_ corpora: give it a million-page legal archive and it will find relevant fragments. For _personal_ knowledge, the failure mode is the opposite.
|
|
169
169
|
|
|
170
|
-
- The corpus is small but
|
|
171
|
-
- The user wants a
|
|
170
|
+
- The corpus is small but highly redundant (3 articles on the same topic).
|
|
171
|
+
- The user wants a point of view, not a passage.
|
|
172
172
|
- Chunk count grows linearly with capture, even when knowledge doesn't.
|
|
173
173
|
|
|
174
|
-
Hypomnema treats the page
|
|
174
|
+
Hypomnema treats the page, not the chunk, as the unit of knowledge. A new source updates the relevant page if one exists and creates a new one if not. The result reads like a wiki article, because that's what it is.
|
|
175
175
|
|
|
176
|
-
### 2. Why
|
|
176
|
+
### 2. Why markdown + git instead of a proprietary store
|
|
177
177
|
|
|
178
|
-
A personal knowledge base
|
|
178
|
+
A personal knowledge base has to outlive any single tool. Markdown survives. Git survives. Both are LLM-native (every model can read them), both run offline, and both have 30 years of tooling behind them. We picked the boring stack on purpose, because the interesting part is _what Claude does with it_.
|
|
179
179
|
|
|
180
|
-
### 3. Why
|
|
180
|
+
### 3. Why lifecycle hooks instead of manual commands
|
|
181
181
|
|
|
182
|
-
Friction
|
|
182
|
+
Friction kills personal knowledge systems. If saving a thought takes three clicks, you stop saving thoughts. Hypomnema piggybacks on events Claude Code already emits.
|
|
183
183
|
|
|
184
|
-
| Event | What you'd otherwise do
|
|
184
|
+
| Event | What you'd otherwise do by hand |
|
|
185
185
|
|---|---|
|
|
186
|
-
| `SessionStart` | "Where did I leave off?"
|
|
187
|
-
| `UserPromptSubmit` | "Do I already know this?"
|
|
188
|
-
| `PreCompact` | "Did I
|
|
186
|
+
| `SessionStart` | "Where did I leave off?" reading `hot.md` / `session-state.md` |
|
|
187
|
+
| `UserPromptSubmit` | "Do I already know this?" a BM25 lookup, top-3 inject |
|
|
188
|
+
| `PreCompact` | "Did I close the session?" the checklist guard |
|
|
189
189
|
| `PostToolUse` (Write/Edit) | `git add` |
|
|
190
190
|
| `Stop` | `git pull --rebase && git commit && git push` |
|
|
191
191
|
|
|
192
|
-
Once installed, you stop
|
|
192
|
+
Once installed, you stop _managing_ the wiki. It just accumulates.
|
|
193
193
|
|
|
194
|
-
### 4. Why a
|
|
194
|
+
### 4. Why a `hot.md` cache for resume
|
|
195
195
|
|
|
196
|
-
The most expensive
|
|
196
|
+
The most expensive part of a paused project isn't redoing the work, it's rebuilding context. Reading `session-log/` from scratch costs minutes and tokens; reading a one-page `hot.md` costs neither. So we cache the most recent state explicitly, rebuild it on `Stop`, and inject it on `SessionStart`. Resume is O(1).
|
|
197
197
|
|
|
198
|
-
### 5. Why a
|
|
198
|
+
### 5. Why a feedback → behavior pipeline
|
|
199
199
|
|
|
200
|
-
Most AI tools
|
|
200
|
+
Most AI tools take corrections _for the current conversation only_. They never persist. Hypomnema funnels every `/hypo:feedback` into `pages/feedback/`, and durable rules are promoted into the `<learned_behaviors>` block in `CLAUDE.md`, where they survive every future session, on every machine that pulls the wiki.
|
|
201
201
|
|
|
202
|
-
### 6. Why
|
|
202
|
+
### 6. Why no API keys, no vector DB, no service
|
|
203
203
|
|
|
204
|
-
Every external dependency is a future
|
|
204
|
+
Every external dependency is a future failure: it breaks, gets bought, gets deprecated, or leaks credentials. Hypomnema is a Node.js script + markdown files + git. That's the whole stack. The only "AI" piece is Claude itself, which you're running anyway.
|
|
205
205
|
|
|
206
|
-
### 7. Why
|
|
206
|
+
### 7. Why `.hypoignore` instead of a privacy mode flag
|
|
207
207
|
|
|
208
|
-
|
|
208
|
+
v1.0 had a `personal / shared / public` mode matrix. It didn't survive contact with reality: every privacy decision turned out to be a per-path question, and a single file (`.hypoignore`) handles per-path decisions natively. v1.1 deleted the mode concept entirely. One file, one source of truth.
|
|
209
209
|
|
|
210
210
|
---
|
|
211
211
|
|
|
@@ -213,18 +213,18 @@ We tried a `personal / shared / public` mode matrix in v1.0. It didn't survive c
|
|
|
213
213
|
|
|
214
214
|
### Synthesis primitives
|
|
215
215
|
|
|
216
|
-
|
|
216
|
+
Nine commands cover the full capture → retrieval → consolidation cycle.
|
|
217
217
|
|
|
218
218
|
| Command | What it does | When to reach for it |
|
|
219
219
|
|---|---|---|
|
|
220
|
-
| `/hypo:ingest` | Saves the raw source under `sources/`; Claude synthesizes a structured page under `pages/`. The shell helper (`scripts/ingest.mjs`) is read-only
|
|
220
|
+
| `/hypo:ingest` | Saves the raw source under `sources/`; Claude synthesizes a structured page under `pages/`. The shell helper (`scripts/ingest.mjs`) is read-only and only _lists_ pending sources | Anytime you read something worth keeping |
|
|
221
221
|
| `/hypo:query` | BM25 retrieval + LLM synthesis with `[[wikilink]]` citations | When you need an answer grounded in your own notes |
|
|
222
222
|
| `/hypo:crystallize` | Runs the session-close checklist (steps 1~6) and, on request, synthesizes drafts (steps 7~11) | End of a non-trivial session |
|
|
223
223
|
| `/hypo:resume` | Loads the most recent session state for an active project | Coming back to a paused project |
|
|
224
|
-
| `/hypo:feedback` | Records an AI behavior correction; eligible for promotion to permanent rules |
|
|
224
|
+
| `/hypo:feedback` | Records an AI behavior correction; eligible for promotion to permanent rules | When Claude gets something wrong, or gets it exactly right |
|
|
225
225
|
| `/hypo:verify` | Audits pages with `verify_by` frontmatter | When time-bound knowledge might have aged out |
|
|
226
226
|
| `/hypo:lint` | Validates frontmatter, wikilinks, schema | Before commits, in CI |
|
|
227
|
-
| `/hypo:graph` | Generates a wikilink dependency graph | When you want to see
|
|
227
|
+
| `/hypo:graph` | Generates a wikilink dependency graph | When you want to see how the structure grew |
|
|
228
228
|
| `/hypo:rename` | Renames a page or directory and rewrites inbound `[[wikilinks]]` | When a page or project folder needs a new name |
|
|
229
229
|
|
|
230
230
|
### Lifecycle hooks (14)
|
|
@@ -236,7 +236,7 @@ Eight commands cover the full capture → retrieval → consolidation cycle.
|
|
|
236
236
|
| `hypo-lookup.mjs` | `UserPromptSubmit` | BM25 top-3 HIT inject / MISS → closest-slug signal |
|
|
237
237
|
| `hypo-compact-guard.mjs` | `UserPromptSubmit` | Detect `/compact` → enforce session-close checklist |
|
|
238
238
|
| `hypo-cwd-change.mjs` | `CwdChanged` | Inject the matching project's `hot.md` |
|
|
239
|
-
| `hypo-file-watch.mjs` | `FileChanged` | Notify on wiki-file changes (honors `.hypoignore
|
|
239
|
+
| `hypo-file-watch.mjs` | `FileChanged` | Notify on wiki-file changes (honors `.hypoignore`; matched paths are never re-emitted into LLM context) |
|
|
240
240
|
| `hypo-auto-stage.mjs` | `PostToolUse(Write/Edit)` | Auto-stage wiki-file edits |
|
|
241
241
|
| `hypo-auto-commit.mjs` | `Stop` | Auto commit + pull + push |
|
|
242
242
|
| `hypo-hot-rebuild.mjs` | `Stop` | Rebuild `hot.md` |
|
|
@@ -248,9 +248,7 @@ Eight commands cover the full capture → retrieval → consolidation cycle.
|
|
|
248
248
|
|
|
249
249
|
All hooks resolve the wiki root via `HYPO_DIR` env → `hypo-config.md` scan → `~/hypomnema` default, and share `hypo-shared.mjs` (declared via `hooks.json`'s `shared` field).
|
|
250
250
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
For fix-level v1.3 detail beyond the lanes above (session-close lint scoped to touched files so `/compact` is no longer blocked by unrelated debt, the `feedback` scope validator accepting cwd-derived project ids, and the stable lint warning IDs `W1`/`W2`/`W4` that `--strict` promotes to errors while `W3`, auto-repaired by `--fix`, stays a warning), see [`CHANGELOG.md`](CHANGELOG.md). **v1.3.1** is a fixes-only patch: update-notifier banners now actually reach the user via the top-level `systemMessage` channel instead of an invisible stderr write, `/hypo:upgrade` no longer double-registers core hooks for plugin or dual (manual + plugin) installs, and session-close no longer false-blocks a completed close when two projects share the latest date. **v1.3.2** adds a first-class log-only session-close path, so a non-project (tooling or wiki-only) session closes cleanly without being forced onto an unrelated project, plus a `rename` helper that rewrites the eligible inbound wikilinks when you rename a page (ambiguous or append-only references are reported, not rewritten). It also tightens the session-close gate (every project with activity today is gated, the per-session marker and `/compact` share one gate, and the derivable root `log.md` entry auto-derives) and the linter (`--json` no longer truncates on a pipe, and vault-convention wikilinks resolve instead of being false-flagged). **v1.3.3** hardens the session-close gate against accidental triggers: the model can no longer mark a session closed without a real user close signal, reading close-related text no longer false-blocks the turn, `--apply-session-close` commits its payload and writes the marker in one step on a close that carries a user close signal, and routine tracker bookkeeping no longer cross-blocks an unrelated project's `/compact`. It also extends `rename` to move a whole directory subtree (with a `/hypo:rename` command and a merge/renumber collision report when a destination already exists). **v1.3.4** is a fixes-only patch for wiki hygiene: `init` no longer drops a duplicate stock page next to a known hand-authored equivalent (when it sees `wiki-automation.md` or `wiki-help.md` it keeps that page and skips the stock `hypo-*` one, with a loud merge notice), and regenerable report output at the vault root (the upgrade `MIGRATION-v*.md` report, plus the reserved `GRAPH_REPORT.md` name) is excluded from the catalog scans while staying fully committable. **v1.4.0** adds an optional `failure_type` classification to feedback pages (one of eight values, surfaced as per-type counts by `hypomnema stats`) so recurring mistake types become visible — the `SCHEMA` moves to 2.1 as an additive, optional field that leaves any page not using it untouched (a page that already carried a hand-written free-text `failure_type` must be relabeled to one of the eight values). It also makes an auto-commit that hits a merge conflict abort cleanly instead of leaving a half-merged vault, stops `lint` from silently green-passing invalid YAML frontmatter (an unquoted `: ` value or a duplicate top-level key), and prevents a nested mapping key from shadowing the page `type`. Under the hood the release pipeline now also gates the Claude Code plugin channel (version consistency, a network-free plugin smoke check, and a README-version floor) and a shared `lib/wikilink.mjs` resolver consolidates the page-walking logic across `lint`, `rename`, `graph`, and `crystallize`.
|
|
251
|
+
The `SessionStart` hook also runs a non-blocking background check against npm and the Claude Code plugin marketplace, and prints an "Update available!" banner the next time a newer version has been published. Opt out with `HYPO_NO_UPDATE_CHECK=1`, `NO_UPDATE_NOTIFIER=1`, or by running under `CI=true`.
|
|
254
252
|
|
|
255
253
|
### Setup & maintenance
|
|
256
254
|
|
|
@@ -265,32 +263,32 @@ For fix-level v1.3 detail beyond the lanes above (session-close lint scoped to t
|
|
|
265
263
|
|
|
266
264
|
### Claude Agent Skills
|
|
267
265
|
|
|
268
|
-
The synthesis-heavy commands (`ingest`, `query`, `crystallize`, `lint`, `verify`, `graph`) are also exposed as
|
|
266
|
+
The synthesis-heavy commands (`ingest`, `query`, `crystallize`, `lint`, `verify`, `graph`) are also exposed as Claude Agent Skills in `skills/<name>/SKILL.md`, so they auto-trigger when the conversation matches their description, with no slash command required.
|
|
269
267
|
|
|
270
268
|
---
|
|
271
269
|
|
|
272
270
|
## Scenarios
|
|
273
271
|
|
|
274
|
-
|
|
272
|
+
A. Learning a new technology.
|
|
275
273
|
You're reading Kubernetes docs and blog posts. Drop each URL into `/hypo:ingest`. By the third article, Claude is updating your existing `kubernetes-networking.md` rather than creating another page. A week later, `/hypo:query "how does pod CIDR allocation work?"` returns a synthesized answer citing your own notes.
|
|
276
274
|
|
|
277
|
-
|
|
278
|
-
Before merging a significant change, run `/hypo:ingest` on the design doc or PR description. Claude
|
|
275
|
+
B. Tracking engineering decisions.
|
|
276
|
+
Before merging a significant change, run `/hypo:ingest` on the design doc or PR description. Claude writes an ADR-style page with context, tradeoffs, and the decision. Future `[[wikilink]]` references pull the rationale directly into any prompt that asks about it.
|
|
279
277
|
|
|
280
|
-
|
|
281
|
-
You
|
|
278
|
+
C. Research accumulation.
|
|
279
|
+
You work through papers on a topic over several weeks. Each `/hypo:ingest` synthesizes the paper and cross-links it. At any point, `/hypo:query` returns a literature-review-style summary grounded in your own notes.
|
|
282
280
|
|
|
283
|
-
|
|
284
|
-
Run `/hypo:feedback` whenever Claude
|
|
281
|
+
D. Tuning AI behavior.
|
|
282
|
+
Run `/hypo:feedback` whenever Claude gets something wrong, or gets it exactly right. The correction is stored in `pages/feedback/` and injected at session start, so the same mistake doesn't happen twice. It carries across sessions, not just within one conversation.
|
|
285
283
|
|
|
286
|
-
|
|
287
|
-
You put a project down for three weeks. At the next session start, `hypo-session-start.mjs` reads `projects/<name>/session-state.md` and injects "next tasks" and recent decisions
|
|
284
|
+
E. Resuming a paused project.
|
|
285
|
+
You put a project down for three weeks. At the next session start, `hypo-session-start.mjs` reads `projects/<name>/session-state.md` and injects "next tasks" and recent decisions into context. You're back up to speed before you type the first prompt.
|
|
288
286
|
|
|
289
287
|
---
|
|
290
288
|
|
|
291
289
|
## What goes in your wiki
|
|
292
290
|
|
|
293
|
-
|
|
291
|
+
Store here:
|
|
294
292
|
|
|
295
293
|
- Synthesized knowledge from external sources (docs, papers, talks)
|
|
296
294
|
- Architecture decisions and their rationale
|
|
@@ -298,13 +296,13 @@ You put a project down for three weeks. At the next session start, `hypo-session
|
|
|
298
296
|
- Project context that doesn't belong in git (stakeholder constraints, open questions, background)
|
|
299
297
|
- Research findings and cross-source comparisons
|
|
300
298
|
|
|
301
|
-
|
|
299
|
+
Do not store here:
|
|
302
300
|
|
|
303
|
-
- Raw source material
|
|
304
|
-
- Credentials, tokens, or secrets
|
|
305
|
-
- Transient task lists for the current session
|
|
306
|
-
- Code patterns derivable from the repo itself
|
|
307
|
-
- Information with a canonical owner elsewhere (Jira, Confluence, API docs)
|
|
301
|
+
- Raw source material: it goes in `sources/` automatically, unedited
|
|
302
|
+
- Credentials, tokens, or secrets: use `.hypoignore` to exclude sensitive paths
|
|
303
|
+
- Transient task lists for the current session: use the conversation's task list
|
|
304
|
+
- Code patterns derivable from the repo itself: `git log` and `grep` are already authoritative
|
|
305
|
+
- Information with a canonical owner elsewhere (Jira, Confluence, API docs): ingest a _synthesis_, not a mirror
|
|
308
306
|
|
|
309
307
|
---
|
|
310
308
|
|
|
@@ -345,11 +343,11 @@ The wiki path is resolved in this order (see `scripts/lib/hypo-root.mjs`):
|
|
|
345
343
|
|
|
346
344
|
Place a `hypo-config.md` at the wiki root to make it portable across machines without setting environment variables.
|
|
347
345
|
|
|
348
|
-
`.hypoignore` controls which paths the hooks ignore (default: `*.pdf`, `*.zip`, `*.pem`, `*.env`, …). Edit it directly
|
|
346
|
+
`.hypoignore` controls which paths the hooks ignore (default: `*.pdf`, `*.zip`, `*.pem`, `*.env`, …). Edit it directly; there is no privacy mode flag. One file, one source of truth.
|
|
349
347
|
|
|
350
|
-
>
|
|
348
|
+
> Provider transmission disclaimer: Hypomnema hooks emit wiki content into Claude Code's `additionalContext`, which is transmitted to the Claude model provider as part of the prompt. `.hypoignore` is enforced at every content-injection hook (`hypo-file-watch`, `hypo-session-start`, `hypo-cwd-change`, `hypo-lookup`) and at `ingest`, but any file _not_ matched by `.hypoignore` is fair game for transmission. (`hypo-auto-stage` and `hypo-auto-commit` are git-staging hooks, not injection points, and also honor `.hypoignore` for their staging decisions.) Keep secrets out of the wiki, and review `.hypoignore` patterns before storing anything sensitive under `HYPO_DIR`.
|
|
351
349
|
|
|
352
|
-
>
|
|
350
|
+
> Scope of git sync: Hypomnema git-syncs only the `~/hypomnema/` wiki itself. `init` / `upgrade` do install and SHA-track a defined surface inside `~/.claude/` (Hypomnema's own hooks at `~/.claude/hooks/`, slash commands at `~/.claude/commands/hypo/`, and `settings.json` registrations), plus, via v1.2.0 extensions companion sync, any `agents/` · `commands/` · `hooks/` · `skills/` you ship inside `~/hypomnema/extensions/` (and with `--codex`, the `hooks` + `commands` subset into `~/.codex/`). Anything _outside_ that defined surface in `~/.claude/` is intentionally not managed by Hypomnema. For general cross-machine sync of Claude Code config (other agents/skills not staged via the wiki, machine-specific `settings.local.json`, etc.), use a separate dotfiles manager such as [chezmoi](https://www.chezmoi.io/).
|
|
353
351
|
|
|
354
352
|
### Where do `/hypo:*` commands live?
|
|
355
353
|
|
|
@@ -362,8 +360,8 @@ Place a `hypo-config.md` at the wiki root to make it portable across machines wi
|
|
|
362
360
|
|
|
363
361
|
## Requirements
|
|
364
362
|
|
|
365
|
-
-
|
|
366
|
-
-
|
|
363
|
+
- Node.js ≥ 18 (tested on 18 / 20 / 22)
|
|
364
|
+
- Claude Code CLI
|
|
367
365
|
|
|
368
366
|
No external services. No API keys. No vector databases.
|
|
369
367
|
|
|
@@ -371,17 +369,17 @@ No external services. No API keys. No vector databases.
|
|
|
371
369
|
|
|
372
370
|
## Status
|
|
373
371
|
|
|
374
|
-
-
|
|
375
|
-
-
|
|
376
|
-
-
|
|
372
|
+
- Tests: see `npm test`. Exact totals shift as lanes ship, so the runner is the source of truth
|
|
373
|
+
- CI: 7 independent jobs (test matrix, lint, init/upgrade snapshots, replay, hypo-absent, uninstall-smoke)
|
|
374
|
+
- Release: `npm publish --provenance` on `v*` tag push
|
|
377
375
|
|
|
378
376
|
---
|
|
379
377
|
|
|
380
378
|
## Docs
|
|
381
379
|
|
|
382
|
-
- [ARCHITECTURE.md](docs/ARCHITECTURE.md)
|
|
383
|
-
- [CONTRIBUTING.md](docs/CONTRIBUTING.md)
|
|
384
|
-
- [CHANGELOG.md](CHANGELOG.md)
|
|
380
|
+
- [ARCHITECTURE.md](docs/ARCHITECTURE.md): internals, component map, data flows
|
|
381
|
+
- [CONTRIBUTING.md](docs/CONTRIBUTING.md): development setup, conventions, PR process
|
|
382
|
+
- [CHANGELOG.md](CHANGELOG.md): release history
|
|
385
383
|
|
|
386
384
|
---
|
|
387
385
|
|
package/commands/audit.md
CHANGED
|
@@ -14,9 +14,9 @@ Definition: [[pages/observability/_index]].
|
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
17
|
-
## Step 1 —
|
|
17
|
+
## Step 1 — Run script
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
The script path below resolves via `${CLAUDE_PLUGIN_ROOT}`, which the plugin harness expands to this package's absolute path before you see it, so run it as written. If it appears unexpanded (a literal `${CLAUDE_PLUGIN_ROOT}`), read the package root from the `hypo@hypomnema` installPath in `~/.claude/plugins/installed_plugins.json` rather than guessing from the cache layout.
|
|
20
20
|
|
|
21
21
|
If the user specified a Hypomnema directory, pass it as `--hypo-dir="<path>"`. Otherwise omit the flag.
|
|
22
22
|
|
|
@@ -26,11 +26,11 @@ If the user specified a Hypomnema directory, pass it as `--hypo-dir="<path>"`. O
|
|
|
26
26
|
|
|
27
27
|
- **Per-session view (default)** — show recent sessions with metrics + classification:
|
|
28
28
|
```bash
|
|
29
|
-
node
|
|
29
|
+
node ${CLAUDE_PLUGIN_ROOT}/scripts/session-audit.mjs [--hypo-dir="<path>"] [--limit=20]
|
|
30
30
|
```
|
|
31
31
|
- **Weekly report (when the user asks for "weekly", "score", or names a week)** — write the report to `journal/weekly/<YYYY-Www>.md` (spec §6.4 SoT):
|
|
32
32
|
```bash
|
|
33
|
-
node
|
|
33
|
+
node ${CLAUDE_PLUGIN_ROOT}/scripts/weekly-report.mjs [--hypo-dir="<path>"] [--week=YYYY-Www] --write
|
|
34
34
|
```
|
|
35
35
|
- **JSON for tooling** — append `--json` to either script.
|
|
36
36
|
|
package/commands/crystallize.md
CHANGED
|
@@ -75,8 +75,10 @@ Content guidance for each slot:
|
|
|
75
75
|
|
|
76
76
|
## Step 3 — Apply the payload
|
|
77
77
|
|
|
78
|
+
The script paths in this command resolve via `${CLAUDE_PLUGIN_ROOT}`, which the plugin harness expands to this package's absolute path before you see it, so run them as written. If one appears unexpanded (a literal `${CLAUDE_PLUGIN_ROOT}`), read the package root from the `hypo@hypomnema` installPath in `~/.claude/plugins/installed_plugins.json` rather than guessing from the cache layout.
|
|
79
|
+
|
|
78
80
|
```bash
|
|
79
|
-
node
|
|
81
|
+
node ${CLAUDE_PLUGIN_ROOT}/scripts/crystallize.mjs \
|
|
80
82
|
--apply-session-close \
|
|
81
83
|
--payload=/tmp/hypo-session-close-<YYYY-MM-DD>.json \
|
|
82
84
|
--session-id=<current-session-id> \
|
|
@@ -93,6 +95,14 @@ Stop-chain Layer 3 hook (`hypo-auto-minimal-crystallize`) the session is closed,
|
|
|
93
95
|
so it stops re-prompting. Omit it only when running crystallize purely for
|
|
94
96
|
synthesis (no session-close intent) — the marker is then simply not written.
|
|
95
97
|
|
|
98
|
+
> **Source rule for `--session-id`:** use only the main conversation's session id
|
|
99
|
+
> (the id shown in the `[WIKI_AUTOCLOSE]` block reason, or `$CLAUDE_SESSION_ID`).
|
|
100
|
+
> Do NOT extract it from a background task output path or Agent thread (e.g.,
|
|
101
|
+
> `/tmp/.../<uuid>/tasks/...`). A UUID from such a path is a background task id,
|
|
102
|
+
> not the main conversation id. Passing it causes `markerSkipReason:
|
|
103
|
+
> "transcript-unresolved"` or `"no-user-close-signal"` and leaves the Stop-chain
|
|
104
|
+
> open, even though `ok: true`.
|
|
105
|
+
|
|
96
106
|
**Behavior (option D + lint gates):**
|
|
97
107
|
|
|
98
108
|
| Invocation | Behavior |
|
|
@@ -132,8 +142,11 @@ Once `ok: true`, report:
|
|
|
132
142
|
- ✓ open-questions applied (or skipped if unchanged)
|
|
133
143
|
- ✓ log.md entry appended
|
|
134
144
|
- ✓ post-apply lint clean
|
|
145
|
+
- **marker written?** (required check): if `markerWritten: true`, report "session-close marker written"; if `markerWritten: false`, report "session-close marker NOT written (reason: `<markerSkipReason>`)" and do NOT declare the session "closed" or "complete". A missing marker means the Stop-chain is still open. Instruct the user to re-run with the correct main-conversation `--session-id`.
|
|
146
|
+
|
|
147
|
+
If `markerWritten: true` (or `--session-id` was not passed): ask: "Session closed. Would you like to also run knowledge synthesis now, or stop here?"
|
|
135
148
|
|
|
136
|
-
|
|
149
|
+
If `markerWritten: false`: do NOT say "session closed." Say instead: "Files applied and verified (ok: true), but the session-close marker was not written (reason: `<markerSkipReason>`). The Stop-chain is still active. To fully close: re-run with the correct main-conversation `--session-id`."
|
|
137
150
|
|
|
138
151
|
If the user says stop, end here. Otherwise continue to Step 5.
|
|
139
152
|
|
|
@@ -141,10 +154,10 @@ If the user says stop, end here. Otherwise continue to Step 5.
|
|
|
141
154
|
|
|
142
155
|
## Step 5 — Surface synthesis candidates
|
|
143
156
|
|
|
144
|
-
|
|
157
|
+
The script path below resolves via `${CLAUDE_PLUGIN_ROOT}`, which the plugin harness expands to this package's absolute path before you see it, so run it as written. If it appears unexpanded (a literal `${CLAUDE_PLUGIN_ROOT}`), read the package root from the `hypo@hypomnema` installPath in `~/.claude/plugins/installed_plugins.json` rather than guessing from the cache layout.
|
|
145
158
|
|
|
146
159
|
```bash
|
|
147
|
-
node
|
|
160
|
+
node ${CLAUDE_PLUGIN_ROOT}/scripts/crystallize.mjs [--hypo-dir="<path>"] [--min-group=2]
|
|
148
161
|
```
|
|
149
162
|
|
|
150
163
|
Show the output to the user. If no candidates are found, tell them Hypomnema looks well-connected and no crystallization is needed.
|
|
@@ -217,7 +230,7 @@ Show what was created or modified, and offer to run `/hypo:lint` to verify all n
|
|
|
217
230
|
`--check-session-close` (read-only strict gate, same check PreCompact runs) is still supported as a probe-only verification. Use it when you only want to verify that today's session-close is complete without applying anything:
|
|
218
231
|
|
|
219
232
|
```bash
|
|
220
|
-
node
|
|
233
|
+
node ${CLAUDE_PLUGIN_ROOT}/scripts/crystallize.mjs --check-session-close [--hypo-dir="<path>"]
|
|
221
234
|
```
|
|
222
235
|
|
|
223
236
|
It reports any file as `missing` or `stale`. For an actual close, prefer `--apply-session-close --payload=<path>` (Step 3) — it bundles freshness + lint into one gate and is the documented dogfood path. (`parseArgs` only accepts the `--payload=<path>` spelling; a space-separated `--payload <path>` is silently ignored and triggers "payload is required".)
|
package/commands/doctor.md
CHANGED
|
@@ -16,9 +16,9 @@ You are running `/hypo:doctor`. Verify the health of the current Hypomnema wiki
|
|
|
16
16
|
|
|
17
17
|
---
|
|
18
18
|
|
|
19
|
-
## Step 1 —
|
|
19
|
+
## Step 1 — Resolve Hypomnema directory
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
The script path below resolves via `${CLAUDE_PLUGIN_ROOT}`, which the plugin harness expands to this package's absolute path before you see it, so run it as written. If it appears unexpanded (a literal `${CLAUDE_PLUGIN_ROOT}`), read the package root from the `hypo@hypomnema` installPath in `~/.claude/plugins/installed_plugins.json` rather than guessing from the cache layout.
|
|
22
22
|
|
|
23
23
|
If the user specified a Hypomnema directory, pass it as `--hypo-dir="<path>"`. Otherwise omit the flag and the script resolves the Hypomnema root automatically: `HYPO_DIR` env → `hypo-config.md` scan → `~/hypomnema` default.
|
|
24
24
|
|
|
@@ -27,7 +27,7 @@ If the user specified a Hypomnema directory, pass it as `--hypo-dir="<path>"`. O
|
|
|
27
27
|
## Step 2 — Run the doctor script
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
|
-
node
|
|
30
|
+
node ${CLAUDE_PLUGIN_ROOT}/scripts/doctor.mjs [--hypo-dir="<path>"] [--json]
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
- `--hypo-dir=<path>` — override Hypomnema root (takes precedence over `HYPO_DIR` env and auto-scan)
|
package/commands/feedback.md
CHANGED
|
@@ -36,10 +36,12 @@ If **claude-learned** is among the targets, the page must be `scope: global` + `
|
|
|
36
36
|
|
|
37
37
|
## Step 2 — List existing feedback (optional)
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
The script path below resolves via `${CLAUDE_PLUGIN_ROOT}`, which the plugin harness expands to this package's absolute path before you see it, so run it as written. If it appears unexpanded (a literal `${CLAUDE_PLUGIN_ROOT}`), read the package root from the `hypo@hypomnema` installPath in `~/.claude/plugins/installed_plugins.json` rather than guessing from the cache layout.
|
|
40
|
+
|
|
41
|
+
To check for an existing topic, run:
|
|
40
42
|
|
|
41
43
|
```bash
|
|
42
|
-
node
|
|
44
|
+
node ${CLAUDE_PLUGIN_ROOT}/scripts/feedback.mjs --list [--hypo-dir="<path>"]
|
|
43
45
|
```
|
|
44
46
|
|
|
45
47
|
If a matching topic exists, appending adds a dated entry and bumps `updated:` (classification frontmatter is preserved).
|
|
@@ -51,7 +53,7 @@ If a matching topic exists, appending adds a dated entry and bumps `updated:` (c
|
|
|
51
53
|
Run with `--dry-run` first to preview the generated page, then without it to write. Pass every collected field:
|
|
52
54
|
|
|
53
55
|
```bash
|
|
54
|
-
node
|
|
56
|
+
node ${CLAUDE_PLUGIN_ROOT}/scripts/feedback.mjs \
|
|
55
57
|
--topic="<slug>" \
|
|
56
58
|
--entry="<one-line rule>" \
|
|
57
59
|
--scope="global|project:<project-id>" \
|