memhook 0.2.2 → 0.4.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.
Files changed (59) hide show
  1. package/CHANGELOG.md +30 -72
  2. package/README.md +158 -69
  3. package/dist/bin/memhook.d.ts +11 -6
  4. package/dist/bin/memhook.d.ts.map +1 -1
  5. package/dist/bin/memhook.js +208 -21
  6. package/dist/bin/memhook.js.map +1 -1
  7. package/dist/src/ansi.d.ts +71 -0
  8. package/dist/src/ansi.d.ts.map +1 -0
  9. package/dist/src/ansi.js +100 -0
  10. package/dist/src/ansi.js.map +1 -0
  11. package/dist/src/backup.d.ts +10 -0
  12. package/dist/src/backup.d.ts.map +1 -0
  13. package/dist/src/backup.js +17 -0
  14. package/dist/src/backup.js.map +1 -0
  15. package/dist/src/cache.d.ts.map +1 -1
  16. package/dist/src/cache.js +14 -7
  17. package/dist/src/cache.js.map +1 -1
  18. package/dist/src/config.d.ts +11 -0
  19. package/dist/src/config.d.ts.map +1 -1
  20. package/dist/src/config.js +6 -0
  21. package/dist/src/config.js.map +1 -1
  22. package/dist/src/configFile.d.ts +6 -0
  23. package/dist/src/configFile.d.ts.map +1 -1
  24. package/dist/src/configFile.js.map +1 -1
  25. package/dist/src/index.d.ts +6 -0
  26. package/dist/src/index.d.ts.map +1 -1
  27. package/dist/src/index.js +6 -0
  28. package/dist/src/index.js.map +1 -1
  29. package/dist/src/init.d.ts +48 -0
  30. package/dist/src/init.d.ts.map +1 -0
  31. package/dist/src/init.js +327 -0
  32. package/dist/src/init.js.map +1 -0
  33. package/dist/src/install.d.ts +87 -0
  34. package/dist/src/install.d.ts.map +1 -0
  35. package/dist/src/install.js +124 -0
  36. package/dist/src/install.js.map +1 -0
  37. package/dist/src/router.d.ts +22 -0
  38. package/dist/src/router.d.ts.map +1 -1
  39. package/dist/src/router.js +113 -8
  40. package/dist/src/router.js.map +1 -1
  41. package/dist/src/skills.d.ts +68 -0
  42. package/dist/src/skills.d.ts.map +1 -0
  43. package/dist/src/skills.js +73 -0
  44. package/dist/src/skills.js.map +1 -0
  45. package/dist/src/skillsCmd.d.ts +51 -0
  46. package/dist/src/skillsCmd.d.ts.map +1 -0
  47. package/dist/src/skillsCmd.js +273 -0
  48. package/dist/src/skillsCmd.js.map +1 -0
  49. package/dist/src/tail.d.ts +76 -0
  50. package/dist/src/tail.d.ts.map +1 -0
  51. package/dist/src/tail.js +280 -0
  52. package/dist/src/tail.js.map +1 -0
  53. package/dist/src/version.d.ts +1 -1
  54. package/dist/src/version.js +1 -1
  55. package/package.json +9 -2
  56. package/skills/curate/SKILL.md +181 -0
  57. package/skills/curate/reference.md +105 -0
  58. package/skills/relay/SKILL.md +162 -0
  59. package/skills/wrap/SKILL.md +173 -0
package/CHANGELOG.md CHANGED
@@ -5,6 +5,30 @@ All notable changes to memhook are documented here.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.4.0](https://github.com/utilia-ai-wox/memhook/compare/v0.3.0...v0.4.0) (2026-06-02)
9
+
10
+
11
+ ### Features
12
+
13
+ * companion skills (/wrap /curate /relay) + installer + nudge ([#32](https://github.com/utilia-ai-wox/memhook/issues/32)) ([3ede75d](https://github.com/utilia-ai-wox/memhook/commit/3ede75dd94cd5383a54dd0540b34b308e649a696))
14
+
15
+ ## [0.3.0](https://github.com/utilia-ai-wox/memhook/compare/v0.2.2...v0.3.0) (2026-06-02)
16
+
17
+
18
+ ### Features
19
+
20
+ * add init/uninstall setup + tail live monitor ([#29](https://github.com/utilia-ai-wox/memhook/issues/29)) ([e895c9a](https://github.com/utilia-ai-wox/memhook/commit/e895c9a44fb46a141a20f1716999be3a0208bb89))
21
+
22
+
23
+ ### Bug Fixes
24
+
25
+ * harden hook path against file-system races and stdin errors ([#30](https://github.com/utilia-ai-wox/memhook/issues/30)) ([8a0f10e](https://github.com/utilia-ai-wox/memhook/commit/8a0f10e1d7a7184b7cc5fdcb4eb20ae4be516b0d))
26
+
27
+
28
+ ### Documentation
29
+
30
+ * refresh all docs for v0.2.2 and revamp the README ([#27](https://github.com/utilia-ai-wox/memhook/issues/27)) ([ad1106a](https://github.com/utilia-ai-wox/memhook/commit/ad1106a3a0cea47ce75201a781fdf5eda80324b2))
31
+
8
32
  ## [0.2.2](https://github.com/utilia-ai-wox/memhook/compare/v0.2.1...v0.2.2) (2026-06-02)
9
33
 
10
34
 
@@ -45,75 +69,9 @@ and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.
45
69
 
46
70
  * graduate release line to clean 0.2.0 ([f0a07e5](https://github.com/utilia-ai-wox/memhook/commit/f0a07e51fe5792df4efd7af9d59452d97603b675))
47
71
 
48
- ## [Unreleased]
49
-
50
- ### Added
51
-
52
- - **OpenAI provider** (`MEMHOOK_PROVIDER=openai`) Chat Completions API,
53
- `Authorization: Bearer`, catalog as the leading system message so OpenAI's
54
- automatic prompt caching can engage. Default model `gpt-4o-mini`.
55
- - **Ollama local provider** (`MEMHOOK_PROVIDER=ollama`) — native `/api/chat`
56
- endpoint, no API key, `stream:false` + `format:"json"`. Default model
57
- `llama3.1`, with a 30s default timeout to absorb cold model loads.
58
- - **YAML config file** (`config.yaml`) — optional, opt-in, read from
59
- `$MEMHOOK_CONFIG` or `~/.config/memhook/config.yaml`. Precedence is
60
- env var > YAML > default. A missing or malformed file is ignored
61
- (fail-soft to defaults). See `config.example.yaml`.
62
- - `src/providers/factory.ts` — `createProvider()` selects the adapter from
63
- `config.provider.type` with compile-time exhaustiveness.
64
- - `src/providers/http.ts` — single shared `postJsonWithRetry` transport
65
- (timeout + single retry) used by all providers.
66
- - `MEMHOOK_PROVIDER` and `MEMHOOK_CONFIG` env vars; per-provider defaults for
67
- model / API-key env var / timeout.
68
- - Hardening pre-publish (CI, CHANGELOG, CONTRIBUTING, `.env.example`)
69
-
70
- ### Changed
71
-
72
- - The provider interface is now provider-agnostic: Anthropic-specific
73
- `betaHeaders` and `cacheControlTtl` moved off the shared `SelectionRequest`
74
- into `AnthropicProviderOptions`. `ProviderConfig.apiKey` is now optional
75
- (local providers need none).
76
- - Cache key now includes the provider identity (`type:model`) so switching
77
- provider or model never serves a selection made by a different model.
78
- - The two hardcoded version strings (`config.ts`, `bin/memhook.ts`) are
79
- centralised in `src/version.ts`.
80
-
81
- ### Note
82
-
83
- - Adding `openai` / `ollama` introduces opt-in outbound calls to
84
- `api.openai.com` / `localhost:11434`. The default remains Anthropic-only;
85
- `api.anthropic.com` is still the sole endpoint for an unconfigured user. No
86
- telemetry, no phone-home.
87
- - First runtime dependency: `yaml` (zero sub-dependencies).
88
-
89
- ## [0.1.0-preview.0] — 2026-05-28
90
-
91
- Initial public preview.
92
-
93
- ### Added
94
-
95
- - `src/router.ts` — UserPromptSubmit hook entry point with cap-A1 projection
96
- fix (skip a file pre-injection if its content would push the cumulated
97
- injection past `maxAdditionalChars`, while always allowing at least one).
98
- - `src/catalog.ts` — catalog builder with Q4 title-only reduction for
99
- non-CWD zones (~50% size cut on a typical 3-repo layout).
100
- - `src/cache.ts` — local LRU cache keyed on
101
- `sha256(prompt + catalog_mtime + cwd + script_version)`. Stored as
102
- per-key JSON files. 60-min TTL by default, 7-day eviction floor.
103
- - `src/preFilter.ts` — trivial-prompt pre-filter loaded from
104
- `~/.config/memhook/trivial-words.txt` with a sensible default list.
105
- - `src/providers/anthropic.ts` — provider implementation for Anthropic
106
- Messages API. Uses `ephemeral` `1h` cache control on the system prompt
107
- (GA in 2026, no beta header) so the catalog sits in cache (10× cheaper
108
- writes amortised across the hour).
109
- - `src/config.ts` — env-driven config loader. No YAML in v0.1; deferred to
110
- v0.2.
111
- - `bin/memhook.ts` — CLI with `run`, `build-catalog`, `version`, `help`.
112
- - JSONL observability log at `~/.claude/logs/memhook.log` including
113
- `additional_size_chars` + `additional_size_tokens_est` so users can audit
114
- the actual size of the injected `additionalContext` over time.
115
- - 18 unit tests covering the router pipeline, pre-filter normalisation, and
116
- cache key derivation / TTL / eviction.
117
-
118
- [Unreleased]: https://github.com/utilia-ai-wox/memhook/compare/v0.1.0-preview.0...HEAD
119
- [0.1.0-preview.0]: https://github.com/utilia-ai-wox/memhook/releases/tag/v0.1.0-preview.0
72
+ ## [0.1.0-preview.0](https://github.com/utilia-ai-wox/memhook/releases/tag/v0.1.0-preview.0) (2026-05-28)
73
+
74
+ Initial public preview: Anthropic Haiku provider, fail-soft pipeline, cap-A1
75
+ projection fix, JSONL observability log, catalog builder, local LRU cache,
76
+ trivial-prompt pre-filter, and the `memhook run | build-catalog | version`
77
+ CLI.
package/README.md CHANGED
@@ -1,91 +1,129 @@
1
+ <div align="center">
2
+
1
3
  # memhook
2
4
 
3
- > Semantic memory router for Claude Code picks the relevant feedbacks &
4
- > rules for each prompt via Haiku, injects them as `additionalContext`.
5
+ **Stop loading every memory file on every prompt. memhook routes only the relevant ones.**
5
6
 
6
- **Status**: `v0.1.0-preview` — extracted from a private hook used daily across
7
- 3 large repos. API surface and naming may shift before `v1.0.0`.
7
+ <p align="center">
8
+ <a href="https://www.npmjs.com/package/memhook"><img src="https://img.shields.io/npm/v/memhook?color=cb3837&logo=npm" alt="npm version"></a>
9
+ <a href="https://www.npmjs.com/package/memhook"><img src="https://img.shields.io/npm/dm/memhook?color=cb3837" alt="npm downloads"></a>
10
+ <a href="https://github.com/utilia-ai-wox/memhook/actions/workflows/ci.yml"><img src="https://github.com/utilia-ai-wox/memhook/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
11
+ <a href="https://github.com/utilia-ai-wox/memhook/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/memhook?color=blue" alt="License: MIT"></a>
12
+ <img src="https://img.shields.io/node/v/memhook" alt="Node version">
13
+ <a href="https://github.com/utilia-ai-wox/memhook/stargazers"><img src="https://img.shields.io/github/stars/utilia-ai-wox/memhook?style=social" alt="GitHub stars"></a>
14
+ </p>
8
15
 
9
- ## Why
16
+ A semantic memory router for [Claude Code](https://claude.com/claude-code) — a
17
+ `UserPromptSubmit` hook that picks the relevant `feedback_*.md` & `rule_*.md`
18
+ files for each prompt and injects them as `additionalContext`.
10
19
 
11
- Claude Code's `~/.claude/` directory accumulates a growing set of
12
- `feedback_*.md` (behavioural corrections) and `rule_*.md` (project doctrine)
13
- files. Loading all of them on every prompt is wasteful (10–14k tokens of
14
- catalog overhead, most of it irrelevant to the current question).
20
+ </div>
15
21
 
16
- memhook uses **Haiku 4.5** as a cheap router: each user prompt is matched
17
- against a one-line catalog of all available memory files, and only the 0–5
18
- most relevant ones are read and injected into `additionalContext`. The rest
19
- sit on disk, invisible to Claude until they matter.
22
+ <!-- TODO(demo): record an asciinema of `tail -f ~/.claude/logs/memhook.log`
23
+ while prompting Claude Code it shows the router picking files live.
24
+ Embed: [![asciicast](https://asciinema.org/a/XXXXX.svg)](https://asciinema.org/a/XXXXX) -->
20
25
 
21
- ## How it works
26
+ ## Features
22
27
 
23
- ```
24
- UserPromptSubmit hook
25
-
26
-
27
- ┌────────────────────────────────────────┐
28
- │ 1. Pre-filter trivial prompts │ ── "ok" / "merci" skip LLM
29
- 2. Check local LRU cache ── identical prompt < 60min hit
30
- 3. Call Haiku with catalog as system │ ── ephemeral 1h cache control
31
- 4. Parse JSON array of basenames │ ── ["feedback_X.md", "rule_Y.md"]
32
- │ 5. Read files, cap by token budget │ ── max 9.5k chars or 5 files
33
- │ 6. Emit additionalContext │
34
- └────────────────────────────────────────┘
35
- ```
28
+ - 🎯 **Relevant-only injection** — a cheap model picks the 0–5 memory files that matter for _this_ prompt.
29
+ - 💸 **Token-frugal** — skips the 10–14k-token catalog dump; injects ~2k tokens of signal.
30
+ - 🛡️ **Fail-soft** — never blocks Claude Code; every error path falls back to empty context.
31
+ - 🔌 **Multi-provider** — Anthropic (default), OpenAI, or local Ollama. Your key, your endpoint.
32
+ - 🤫 **Zero telemetry** — the only outbound call is the LLM endpoint _you_ chose.
33
+ - 🪶 **One dependency** `yaml`, with zero sub-deps.
34
+ - **Cached & pre-filtered** — an LRU cache + a trivial-prompt skip keep latency near zero.
35
+ - 🧰 **One-command setup** `memhook init` wires the hooks (with backup); `memhook tail` shows routing live.
36
+ - 🧩 **Companion skills** optional `/wrap`, `/curate`, `/relay` to capture, tidy, and hand off your memory.
36
37
 
37
- ## Install
38
+ ## 🤔 Why
38
39
 
39
- ```bash
40
- npm install -g memhook # not yet published — see "From source" below
41
- ```
40
+ Claude Code's `~/.claude/` directory accumulates a growing set of
41
+ `feedback_*.md` (behavioural corrections) and `rule_*.md` (project doctrine)
42
+ files. Loading all of them on every prompt is wasteful — most of it is
43
+ irrelevant to the question at hand.
44
+
45
+ memhook uses a cheap router model (**Haiku 4.5** by default) to match each
46
+ prompt against a one-line catalog of all your memory files, and injects only
47
+ the most relevant ones. The rest sit on disk, invisible until they matter.
48
+
49
+ | Approach | Tokens / prompt | Relevance |
50
+ | --------------------- | --------------- | ----------------- |
51
+ | Load all memory files | 10–14k | mostly irrelevant |
52
+ | **memhook** | ~2k | only what matches |
42
53
 
43
- ### From source (preview)
54
+ ## 🚀 Quick start
44
55
 
45
56
  ```bash
46
- git clone https://github.com/utilia-ai-wox/memhook.git
47
- cd memhook
48
- bun install
49
- bun run build
50
- npm link
57
+ npm install -g memhook
58
+ export ANTHROPIC_API_KEY=sk-ant-… # or see Providers for OpenAI / Ollama
59
+ memhook init
51
60
  ```
52
61
 
53
- ## Setup
54
-
55
- 1. **Set your API key**
62
+ `memhook init` detects your Claude Code config, wires the two hooks into
63
+ `~/.claude/settings.json` (backing it up first, never clobbering existing
64
+ hooks), and builds the initial catalog. It is idempotent and supports
65
+ `--dry-run`. Restart Claude Code and you're done — then watch it work live
66
+ with [`memhook tail`](#-observability).
56
67
 
57
- ```bash
58
- export ANTHROPIC_API_KEY=sk-ant-…
59
- ```
68
+ <details>
69
+ <summary>Manual setup (what <code>init</code> automates)</summary>
60
70
 
61
- 2. **Build the initial catalog**
71
+ 1. **Build the initial catalog**
62
72
 
63
73
  ```bash
64
74
  memhook build-catalog
65
75
  # → ~/.claude/cache/memory-catalog.txt
66
76
  ```
67
77
 
68
- 3. **Wire the hooks** in `~/.claude/settings.json`:
78
+ 2. **Wire the hooks** in `~/.claude/settings.json`:
69
79
 
70
80
  ```json
71
81
  {
72
82
  "hooks": {
73
83
  "UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "memhook run" }] }],
74
- "SessionStart": [
75
- {
76
- "hooks": [{ "type": "command", "command": "memhook build-catalog" }]
77
- }
78
- ]
84
+ "SessionStart": [{ "hooks": [{ "type": "command", "command": "memhook build-catalog" }] }]
79
85
  }
80
86
  }
81
87
  ```
82
88
 
83
- ## Configuration
89
+ Remove it all later with `memhook uninstall` (also backs up first).
90
+
91
+ </details>
92
+
93
+ <details>
94
+ <summary>From source (for contributors)</summary>
95
+
96
+ ```bash
97
+ git clone https://github.com/utilia-ai-wox/memhook.git
98
+ cd memhook
99
+ bun install
100
+ bun run build
101
+ npm link
102
+ ```
103
+
104
+ </details>
105
+
106
+ ## 🔍 How it works
107
+
108
+ ```
109
+ UserPromptSubmit hook
110
+
111
+
112
+ ┌────────────────────────────────────────┐
113
+ │ 1. Pre-filter trivial prompts │ ── "ok" / "merci" → skip LLM
114
+ │ 2. Check local LRU cache │ ── identical prompt < 60min → hit
115
+ │ 3. Call the router with catalog │ ── ephemeral 1h cache control
116
+ │ 4. Parse JSON array of basenames │ ── ["feedback_X.md", "rule_Y.md"]
117
+ │ 5. Read files, cap by token budget │ ── max 9.5k chars or 5 files
118
+ │ 6. Emit additionalContext │
119
+ └────────────────────────────────────────┘
120
+ ```
121
+
122
+ ## ⚙️ Configuration
84
123
 
85
- Every knob is an env var, and (since `v0.2`) optionally a YAML file.
86
- Precedence per key is **env var > YAML file > built-in default**, so an
87
- env-var-only setup behaves exactly as before. Sensible defaults work for most
88
- users.
124
+ Every knob is an env var, and optionally a YAML file. Precedence per key is
125
+ **env var > YAML file > built-in default**, so an env-var-only setup behaves
126
+ exactly as before. Sensible defaults work for most users.
89
127
 
90
128
  | Variable | Default | Purpose |
91
129
  | -------------------------------- | ------------------------------- | -------------------------------------- |
@@ -119,7 +157,7 @@ selection:
119
157
  maxFiles: 5
120
158
  ```
121
159
 
122
- ## Providers
160
+ ## 🔌 Providers
123
161
 
124
162
  The default provider is **Anthropic** — with no `MEMHOOK_PROVIDER` set, the
125
163
  only outbound call memhook ever makes is to `api.anthropic.com`, using your own
@@ -141,7 +179,7 @@ LLM endpoint _you_ choose to route through.
141
179
  the native `/api/chat` endpoint with `stream:false`; the timeout defaults to
142
180
  30s to absorb cold model loads.
143
181
 
144
- ## Observability
182
+ ## 📊 Observability
145
183
 
146
184
  Every invocation appends one JSON line to `~/.claude/logs/memhook.log`:
147
185
 
@@ -157,18 +195,34 @@ Every invocation appends one JSON line to `~/.claude/logs/memhook.log`:
157
195
  "cache_read": 13398,
158
196
  "additional_size_chars": 20225,
159
197
  "additional_size_tokens_est": 5056,
160
- "status": "ok"
198
+ "status": "ok",
199
+ "model": "claude-haiku-4-5"
161
200
  }
162
201
  ```
163
202
 
164
- Useful one-liner to inspect the last 7 days:
203
+ ### Live view `memhook tail`
204
+
205
+ Watch routing decisions as they happen, in colour:
206
+
207
+ ```bash
208
+ memhook tail # follow live (Ctrl-C to quit)
209
+ memhook tail --no-follow # print recent log + summary, then exit
210
+ memhook tail --status ok,cache_hit # filter by status
211
+ memhook tail -n 50 # show more history first
212
+ ```
213
+
214
+ Each row shows the time, status, prompt preview, latency, and model, plus the
215
+ memories that were injected; a summary line reports the cache-hit rate and
216
+ p50/p95 latency. Colour degrades to plain text when piped or under `NO_COLOR`.
217
+ `tail` only reads the log, so it can never affect the hook. For raw analysis,
218
+ the log is plain JSONL — e.g. the last 7 days by status:
165
219
 
166
220
  ```bash
167
221
  jq -c 'select((.ts | fromdateiso8601) > (now - 7*86400)) | .status' \
168
222
  ~/.claude/logs/memhook.log | sort | uniq -c
169
223
  ```
170
224
 
171
- ## Status values
225
+ ### Status values
172
226
 
173
227
  | `status` | Meaning |
174
228
  | ---------------------- | ----------------------------------------------------- |
@@ -184,20 +238,55 @@ jq -c 'select((.ts | fromdateiso8601) > (now - 7*86400)) | .status' \
184
238
  | `api_no_content` | API returned 200 but no text |
185
239
  | `parse_invalid` | Response wasn't a valid JSON array |
186
240
 
187
- ## Fail-soft
241
+ ## 🧩 Companion skills
242
+
243
+ Routing only works well when your memory stays healthy. memhook ships three
244
+ optional Claude Code skills for that — install them with one command:
245
+
246
+ ```bash
247
+ memhook skills install # copy them into ~/.claude/skills
248
+ memhook skills list # show install status
249
+ memhook skills uninstall # remove them (backs up any edits first)
250
+ ```
251
+
252
+ `memhook init` also offers to install them.
253
+
254
+ | Skill | What it does |
255
+ | --------- | ---------------------------------------------------------------------------------------------------------------------------- |
256
+ | `/wrap` | End-of-session wrap-up — captures the session's lessons into memory + a dated journal entry. Proposes; never writes unasked. |
257
+ | `/curate` | Memory hygiene — dedupes, fixes the `MEMORY.md` index, splits oversized files, then rebuilds the catalog. |
258
+ | `/relay` | Generates a self-contained prompt to resume work in a fresh session. Read-only. |
259
+
260
+ They're standalone skills, so you invoke them directly as `/wrap`, `/curate`,
261
+ `/relay`. They are user-invoked only — Claude won't trigger them on its own.
262
+
263
+ When your catalog grows large, memhook also adds a one-line reminder to run
264
+ `/curate` (a local-only `systemMessage`, 7-day cooldown — toggle with
265
+ `MEMHOOK_CURATE_NUDGE`).
266
+
267
+ ## 🛡️ Fail-soft
188
268
 
189
269
  memhook never blocks Claude Code. On any error — missing key, network
190
270
  timeout, malformed JSON, broken filesystem — it emits an empty
191
- `additionalContext` and logs the status. Your prompt always reaches the
192
- model, just without injected memories for that turn.
271
+ `additionalContext` and logs the status. **Your prompt always reaches the
272
+ model**, just without injected memories for that turn.
273
+
274
+ ## 🗺️ Roadmap
275
+
276
+ - `v0.2` ✅ — YAML config file, OpenAI provider, Ollama local provider (published on npm)
277
+ - `v0.3` ✅ — `memhook init` / `memhook uninstall` setup wizard + zero-dep live monitor (`memhook tail`)
278
+ - `v0.4` ✅ — Companion skills (`/wrap`, `/curate`, `/relay`) + `memhook skills` installer + `/curate` nudge
279
+ - `v1.0` — API frozen, cross-platform validated, listed on awesome-lists
280
+
281
+ ## 🤝 Contributing
193
282
 
194
- ## Roadmap
283
+ Contributions welcome — please read [CONTRIBUTING.md](CONTRIBUTING.md) first.
284
+ The hook contract (fail-soft, no telemetry, strict TypeScript) is
285
+ non-negotiable; the [`failsoft-auditor`](.claude/agents/failsoft-auditor.md)
286
+ agent guards it on every PR.
195
287
 
196
- - `v0.2` ✅ — YAML config file, OpenAI provider, Ollama local provider
197
- - `v0.3`TUI live monitor (`memhook tail`)
198
- - `v0.4` — Companion skills (`/wrap`, `/curate`, `/relay`)
199
- - `v0.5` — Auto-bootstrap (`memhook init` detects empty memory dirs)
200
- - `v1.0` — Cross-platform validated, published to npm
288
+ > [!TIP]
289
+ > If memhook saves you tokens, **star the repo** it helps other Claude Code users find it.
201
290
 
202
291
  ## License
203
292
 
@@ -1,16 +1,21 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * memhook CLI — three commands shipped in v0.1 preview:
3
+ * memhook CLI.
4
4
  *
5
5
  * memhook run Read stdin (Claude Code hook JSON), write hook output
6
6
  * memhook build-catalog Rebuild ~/.claude/cache/memory-catalog.txt
7
+ * memhook init Wire memhook into ~/.claude/settings.json (interactive)
8
+ * memhook uninstall Remove memhook's hooks from ~/.claude/settings.json
9
+ * memhook tail Pretty live view of the JSONL routing log
7
10
  * memhook version Print package version
8
11
  *
9
- * Designed to be wired into ~/.claude/settings.json hooks:
10
- * "UserPromptSubmit": [{ "hooks": [{ "type": "command",
11
- * "command": "memhook run" }] }]
12
- * "SessionStart": [{ "hooks": [{ "type": "command",
13
- * "command": "memhook build-catalog" }] }]
12
+ * Only `run` obeys the fail-soft hook contract (never throws, never exits
13
+ * non-zero). The interactive commands (`init`/`uninstall`/`tail`) may exit
14
+ * non-zero on user error and are free to use the TTY — docs/SPECIFICATION.md §9.
15
+ *
16
+ * Wired into ~/.claude/settings.json hooks (see `memhook init`):
17
+ * "UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "memhook run" }] }]
18
+ * "SessionStart": [{ "hooks": [{ "type": "command", "command": "memhook build-catalog" }] }]
14
19
  */
15
20
  export {};
16
21
  //# sourceMappingURL=memhook.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"memhook.d.ts","sourceRoot":"","sources":["../../bin/memhook.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;GAYG"}
1
+ {"version":3,"file":"memhook.d.ts","sourceRoot":"","sources":["../../bin/memhook.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;GAiBG"}