memhook 0.2.0 → 0.3.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/CHANGELOG.md +37 -72
- package/README.md +130 -68
- package/dist/bin/memhook.d.ts +11 -6
- package/dist/bin/memhook.d.ts.map +1 -1
- package/dist/bin/memhook.js +157 -21
- package/dist/bin/memhook.js.map +1 -1
- package/dist/src/ansi.d.ts +71 -0
- package/dist/src/ansi.d.ts.map +1 -0
- package/dist/src/ansi.js +100 -0
- package/dist/src/ansi.js.map +1 -0
- package/dist/src/cache.d.ts.map +1 -1
- package/dist/src/cache.js +14 -7
- package/dist/src/cache.js.map +1 -1
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/init.d.ts +47 -0
- package/dist/src/init.d.ts.map +1 -0
- package/dist/src/init.js +283 -0
- package/dist/src/init.js.map +1 -0
- package/dist/src/install.d.ts +87 -0
- package/dist/src/install.d.ts.map +1 -0
- package/dist/src/install.js +124 -0
- package/dist/src/install.js.map +1 -0
- package/dist/src/router.d.ts.map +1 -1
- package/dist/src/router.js +34 -7
- package/dist/src/router.js.map +1 -1
- package/dist/src/tail.d.ts +76 -0
- package/dist/src/tail.d.ts.map +1 -0
- package/dist/src/tail.js +280 -0
- package/dist/src/tail.js.map +1 -0
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/package.json +5 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,37 @@ 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.3.0](https://github.com/utilia-ai-wox/memhook/compare/v0.2.2...v0.3.0) (2026-06-02)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* 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))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
* 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))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Documentation
|
|
22
|
+
|
|
23
|
+
* 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))
|
|
24
|
+
|
|
25
|
+
## [0.2.2](https://github.com/utilia-ai-wox/memhook/compare/v0.2.1...v0.2.2) (2026-06-02)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Bug Fixes
|
|
29
|
+
|
|
30
|
+
* **ci:** use npm install in publish job (repo ships no lockfile) ([#25](https://github.com/utilia-ai-wox/memhook/issues/25)) ([b12f873](https://github.com/utilia-ai-wox/memhook/commit/b12f873c2a83c9656134910a2971117687992f1e))
|
|
31
|
+
|
|
32
|
+
## [0.2.1](https://github.com/utilia-ai-wox/memhook/compare/v0.2.0...v0.2.1) (2026-06-02)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
### Bug Fixes
|
|
36
|
+
|
|
37
|
+
* clean dist before build to avoid shipping stale artifacts ([#23](https://github.com/utilia-ai-wox/memhook/issues/23)) ([e34e7ad](https://github.com/utilia-ai-wox/memhook/commit/e34e7ad08688f7d687dd2e42ebe62b52bbbac660))
|
|
38
|
+
|
|
8
39
|
## [0.2.0](https://github.com/utilia-ai-wox/memhook/compare/v0.1.0-preview.0...v0.2.0) (2026-06-02)
|
|
9
40
|
|
|
10
41
|
|
|
@@ -31,75 +62,9 @@ and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.
|
|
|
31
62
|
|
|
32
63
|
* graduate release line to clean 0.2.0 ([f0a07e5](https://github.com/utilia-ai-wox/memhook/commit/f0a07e51fe5792df4efd7af9d59452d97603b675))
|
|
33
64
|
|
|
34
|
-
## [
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
-
|
|
39
|
-
|
|
40
|
-
automatic prompt caching can engage. Default model `gpt-4o-mini`.
|
|
41
|
-
- **Ollama local provider** (`MEMHOOK_PROVIDER=ollama`) — native `/api/chat`
|
|
42
|
-
endpoint, no API key, `stream:false` + `format:"json"`. Default model
|
|
43
|
-
`llama3.1`, with a 30s default timeout to absorb cold model loads.
|
|
44
|
-
- **YAML config file** (`config.yaml`) — optional, opt-in, read from
|
|
45
|
-
`$MEMHOOK_CONFIG` or `~/.config/memhook/config.yaml`. Precedence is
|
|
46
|
-
env var > YAML > default. A missing or malformed file is ignored
|
|
47
|
-
(fail-soft to defaults). See `config.example.yaml`.
|
|
48
|
-
- `src/providers/factory.ts` — `createProvider()` selects the adapter from
|
|
49
|
-
`config.provider.type` with compile-time exhaustiveness.
|
|
50
|
-
- `src/providers/http.ts` — single shared `postJsonWithRetry` transport
|
|
51
|
-
(timeout + single retry) used by all providers.
|
|
52
|
-
- `MEMHOOK_PROVIDER` and `MEMHOOK_CONFIG` env vars; per-provider defaults for
|
|
53
|
-
model / API-key env var / timeout.
|
|
54
|
-
- Hardening pre-publish (CI, CHANGELOG, CONTRIBUTING, `.env.example`)
|
|
55
|
-
|
|
56
|
-
### Changed
|
|
57
|
-
|
|
58
|
-
- The provider interface is now provider-agnostic: Anthropic-specific
|
|
59
|
-
`betaHeaders` and `cacheControlTtl` moved off the shared `SelectionRequest`
|
|
60
|
-
into `AnthropicProviderOptions`. `ProviderConfig.apiKey` is now optional
|
|
61
|
-
(local providers need none).
|
|
62
|
-
- Cache key now includes the provider identity (`type:model`) so switching
|
|
63
|
-
provider or model never serves a selection made by a different model.
|
|
64
|
-
- The two hardcoded version strings (`config.ts`, `bin/memhook.ts`) are
|
|
65
|
-
centralised in `src/version.ts`.
|
|
66
|
-
|
|
67
|
-
### Note
|
|
68
|
-
|
|
69
|
-
- Adding `openai` / `ollama` introduces opt-in outbound calls to
|
|
70
|
-
`api.openai.com` / `localhost:11434`. The default remains Anthropic-only;
|
|
71
|
-
`api.anthropic.com` is still the sole endpoint for an unconfigured user. No
|
|
72
|
-
telemetry, no phone-home.
|
|
73
|
-
- First runtime dependency: `yaml` (zero sub-dependencies).
|
|
74
|
-
|
|
75
|
-
## [0.1.0-preview.0] — 2026-05-28
|
|
76
|
-
|
|
77
|
-
Initial public preview.
|
|
78
|
-
|
|
79
|
-
### Added
|
|
80
|
-
|
|
81
|
-
- `src/router.ts` — UserPromptSubmit hook entry point with cap-A1 projection
|
|
82
|
-
fix (skip a file pre-injection if its content would push the cumulated
|
|
83
|
-
injection past `maxAdditionalChars`, while always allowing at least one).
|
|
84
|
-
- `src/catalog.ts` — catalog builder with Q4 title-only reduction for
|
|
85
|
-
non-CWD zones (~50% size cut on a typical 3-repo layout).
|
|
86
|
-
- `src/cache.ts` — local LRU cache keyed on
|
|
87
|
-
`sha256(prompt + catalog_mtime + cwd + script_version)`. Stored as
|
|
88
|
-
per-key JSON files. 60-min TTL by default, 7-day eviction floor.
|
|
89
|
-
- `src/preFilter.ts` — trivial-prompt pre-filter loaded from
|
|
90
|
-
`~/.config/memhook/trivial-words.txt` with a sensible default list.
|
|
91
|
-
- `src/providers/anthropic.ts` — provider implementation for Anthropic
|
|
92
|
-
Messages API. Uses `ephemeral` `1h` cache control on the system prompt
|
|
93
|
-
(GA in 2026, no beta header) so the catalog sits in cache (10× cheaper
|
|
94
|
-
writes amortised across the hour).
|
|
95
|
-
- `src/config.ts` — env-driven config loader. No YAML in v0.1; deferred to
|
|
96
|
-
v0.2.
|
|
97
|
-
- `bin/memhook.ts` — CLI with `run`, `build-catalog`, `version`, `help`.
|
|
98
|
-
- JSONL observability log at `~/.claude/logs/memhook.log` including
|
|
99
|
-
`additional_size_chars` + `additional_size_tokens_est` so users can audit
|
|
100
|
-
the actual size of the injected `additionalContext` over time.
|
|
101
|
-
- 18 unit tests covering the router pipeline, pre-filter normalisation, and
|
|
102
|
-
cache key derivation / TTL / eviction.
|
|
103
|
-
|
|
104
|
-
[Unreleased]: https://github.com/utilia-ai-wox/memhook/compare/v0.1.0-preview.0...HEAD
|
|
105
|
-
[0.1.0-preview.0]: https://github.com/utilia-ai-wox/memhook/releases/tag/v0.1.0-preview.0
|
|
65
|
+
## [0.1.0-preview.0](https://github.com/utilia-ai-wox/memhook/releases/tag/v0.1.0-preview.0) (2026-05-28)
|
|
66
|
+
|
|
67
|
+
Initial public preview: Anthropic Haiku provider, fail-soft pipeline, cap-A1
|
|
68
|
+
projection fix, JSONL observability log, catalog builder, local LRU cache,
|
|
69
|
+
trivial-prompt pre-filter, and the `memhook run | build-catalog | version`
|
|
70
|
+
CLI.
|
package/README.md
CHANGED
|
@@ -1,91 +1,128 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
1
3
|
# memhook
|
|
2
4
|
|
|
3
|
-
|
|
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
|
-
|
|
7
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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: [](https://asciinema.org/a/XXXXX) -->
|
|
20
25
|
|
|
21
|
-
##
|
|
26
|
+
## ✨ Features
|
|
22
27
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
36
|
|
|
37
|
-
##
|
|
37
|
+
## 🤔 Why
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
Claude Code's `~/.claude/` directory accumulates a growing set of
|
|
40
|
+
`feedback_*.md` (behavioural corrections) and `rule_*.md` (project doctrine)
|
|
41
|
+
files. Loading all of them on every prompt is wasteful — most of it is
|
|
42
|
+
irrelevant to the question at hand.
|
|
43
|
+
|
|
44
|
+
memhook uses a cheap router model (**Haiku 4.5** by default) to match each
|
|
45
|
+
prompt against a one-line catalog of all your memory files, and injects only
|
|
46
|
+
the most relevant ones. The rest sit on disk, invisible until they matter.
|
|
42
47
|
|
|
43
|
-
|
|
48
|
+
| Approach | Tokens / prompt | Relevance |
|
|
49
|
+
| --------------------- | --------------- | ----------------- |
|
|
50
|
+
| Load all memory files | 10–14k | mostly irrelevant |
|
|
51
|
+
| **memhook** | ~2k | only what matches |
|
|
52
|
+
|
|
53
|
+
## 🚀 Quick start
|
|
44
54
|
|
|
45
55
|
```bash
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
bun run build
|
|
50
|
-
npm link
|
|
56
|
+
npm install -g memhook
|
|
57
|
+
export ANTHROPIC_API_KEY=sk-ant-… # or see Providers for OpenAI / Ollama
|
|
58
|
+
memhook init
|
|
51
59
|
```
|
|
52
60
|
|
|
53
|
-
|
|
61
|
+
`memhook init` detects your Claude Code config, wires the two hooks into
|
|
62
|
+
`~/.claude/settings.json` (backing it up first, never clobbering existing
|
|
63
|
+
hooks), and builds the initial catalog. It is idempotent and supports
|
|
64
|
+
`--dry-run`. Restart Claude Code and you're done — then watch it work live
|
|
65
|
+
with [`memhook tail`](#-observability).
|
|
54
66
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
export ANTHROPIC_API_KEY=sk-ant-…
|
|
59
|
-
```
|
|
67
|
+
<details>
|
|
68
|
+
<summary>Manual setup (what <code>init</code> automates)</summary>
|
|
60
69
|
|
|
61
|
-
|
|
70
|
+
1. **Build the initial catalog**
|
|
62
71
|
|
|
63
72
|
```bash
|
|
64
73
|
memhook build-catalog
|
|
65
74
|
# → ~/.claude/cache/memory-catalog.txt
|
|
66
75
|
```
|
|
67
76
|
|
|
68
|
-
|
|
77
|
+
2. **Wire the hooks** in `~/.claude/settings.json`:
|
|
69
78
|
|
|
70
79
|
```json
|
|
71
80
|
{
|
|
72
81
|
"hooks": {
|
|
73
82
|
"UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "memhook run" }] }],
|
|
74
|
-
"SessionStart": [
|
|
75
|
-
{
|
|
76
|
-
"hooks": [{ "type": "command", "command": "memhook build-catalog" }]
|
|
77
|
-
}
|
|
78
|
-
]
|
|
83
|
+
"SessionStart": [{ "hooks": [{ "type": "command", "command": "memhook build-catalog" }] }]
|
|
79
84
|
}
|
|
80
85
|
}
|
|
81
86
|
```
|
|
82
87
|
|
|
83
|
-
|
|
88
|
+
Remove it all later with `memhook uninstall` (also backs up first).
|
|
89
|
+
|
|
90
|
+
</details>
|
|
84
91
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
92
|
+
<details>
|
|
93
|
+
<summary>From source (for contributors)</summary>
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
git clone https://github.com/utilia-ai-wox/memhook.git
|
|
97
|
+
cd memhook
|
|
98
|
+
bun install
|
|
99
|
+
bun run build
|
|
100
|
+
npm link
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
</details>
|
|
104
|
+
|
|
105
|
+
## 🔍 How it works
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
UserPromptSubmit hook
|
|
109
|
+
│
|
|
110
|
+
▼
|
|
111
|
+
┌────────────────────────────────────────┐
|
|
112
|
+
│ 1. Pre-filter trivial prompts │ ── "ok" / "merci" → skip LLM
|
|
113
|
+
│ 2. Check local LRU cache │ ── identical prompt < 60min → hit
|
|
114
|
+
│ 3. Call the router with catalog │ ── ephemeral 1h cache control
|
|
115
|
+
│ 4. Parse JSON array of basenames │ ── ["feedback_X.md", "rule_Y.md"]
|
|
116
|
+
│ 5. Read files, cap by token budget │ ── max 9.5k chars or 5 files
|
|
117
|
+
│ 6. Emit additionalContext │
|
|
118
|
+
└────────────────────────────────────────┘
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## ⚙️ Configuration
|
|
122
|
+
|
|
123
|
+
Every knob is an env var, and optionally a YAML file. Precedence per key is
|
|
124
|
+
**env var > YAML file > built-in default**, so an env-var-only setup behaves
|
|
125
|
+
exactly as before. Sensible defaults work for most users.
|
|
89
126
|
|
|
90
127
|
| Variable | Default | Purpose |
|
|
91
128
|
| -------------------------------- | ------------------------------- | -------------------------------------- |
|
|
@@ -119,7 +156,7 @@ selection:
|
|
|
119
156
|
maxFiles: 5
|
|
120
157
|
```
|
|
121
158
|
|
|
122
|
-
## Providers
|
|
159
|
+
## 🔌 Providers
|
|
123
160
|
|
|
124
161
|
The default provider is **Anthropic** — with no `MEMHOOK_PROVIDER` set, the
|
|
125
162
|
only outbound call memhook ever makes is to `api.anthropic.com`, using your own
|
|
@@ -141,7 +178,7 @@ LLM endpoint _you_ choose to route through.
|
|
|
141
178
|
the native `/api/chat` endpoint with `stream:false`; the timeout defaults to
|
|
142
179
|
30s to absorb cold model loads.
|
|
143
180
|
|
|
144
|
-
## Observability
|
|
181
|
+
## 📊 Observability
|
|
145
182
|
|
|
146
183
|
Every invocation appends one JSON line to `~/.claude/logs/memhook.log`:
|
|
147
184
|
|
|
@@ -157,18 +194,34 @@ Every invocation appends one JSON line to `~/.claude/logs/memhook.log`:
|
|
|
157
194
|
"cache_read": 13398,
|
|
158
195
|
"additional_size_chars": 20225,
|
|
159
196
|
"additional_size_tokens_est": 5056,
|
|
160
|
-
"status": "ok"
|
|
197
|
+
"status": "ok",
|
|
198
|
+
"model": "claude-haiku-4-5"
|
|
161
199
|
}
|
|
162
200
|
```
|
|
163
201
|
|
|
164
|
-
|
|
202
|
+
### Live view — `memhook tail`
|
|
203
|
+
|
|
204
|
+
Watch routing decisions as they happen, in colour:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
memhook tail # follow live (Ctrl-C to quit)
|
|
208
|
+
memhook tail --no-follow # print recent log + summary, then exit
|
|
209
|
+
memhook tail --status ok,cache_hit # filter by status
|
|
210
|
+
memhook tail -n 50 # show more history first
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Each row shows the time, status, prompt preview, latency, and model, plus the
|
|
214
|
+
memories that were injected; a summary line reports the cache-hit rate and
|
|
215
|
+
p50/p95 latency. Colour degrades to plain text when piped or under `NO_COLOR`.
|
|
216
|
+
`tail` only reads the log, so it can never affect the hook. For raw analysis,
|
|
217
|
+
the log is plain JSONL — e.g. the last 7 days by status:
|
|
165
218
|
|
|
166
219
|
```bash
|
|
167
220
|
jq -c 'select((.ts | fromdateiso8601) > (now - 7*86400)) | .status' \
|
|
168
221
|
~/.claude/logs/memhook.log | sort | uniq -c
|
|
169
222
|
```
|
|
170
223
|
|
|
171
|
-
|
|
224
|
+
### Status values
|
|
172
225
|
|
|
173
226
|
| `status` | Meaning |
|
|
174
227
|
| ---------------------- | ----------------------------------------------------- |
|
|
@@ -184,20 +237,29 @@ jq -c 'select((.ts | fromdateiso8601) > (now - 7*86400)) | .status' \
|
|
|
184
237
|
| `api_no_content` | API returned 200 but no text |
|
|
185
238
|
| `parse_invalid` | Response wasn't a valid JSON array |
|
|
186
239
|
|
|
187
|
-
## Fail-soft
|
|
240
|
+
## 🛡️ Fail-soft
|
|
188
241
|
|
|
189
242
|
memhook never blocks Claude Code. On any error — missing key, network
|
|
190
243
|
timeout, malformed JSON, broken filesystem — it emits an empty
|
|
191
|
-
`additionalContext` and logs the status. Your prompt always reaches the
|
|
192
|
-
model
|
|
244
|
+
`additionalContext` and logs the status. **Your prompt always reaches the
|
|
245
|
+
model**, just without injected memories for that turn.
|
|
193
246
|
|
|
194
|
-
## Roadmap
|
|
247
|
+
## 🗺️ Roadmap
|
|
195
248
|
|
|
196
|
-
- `v0.2` ✅ — YAML config file, OpenAI provider, Ollama local provider
|
|
197
|
-
- `v0.3` —
|
|
249
|
+
- `v0.2` ✅ — YAML config file, OpenAI provider, Ollama local provider (published on npm)
|
|
250
|
+
- `v0.3` — `memhook init` / `memhook uninstall` setup wizard + zero-dep live monitor (`memhook tail`)
|
|
198
251
|
- `v0.4` — Companion skills (`/wrap`, `/curate`, `/relay`)
|
|
199
|
-
- `
|
|
200
|
-
|
|
252
|
+
- `v1.0` — API frozen, cross-platform validated, listed on awesome-lists
|
|
253
|
+
|
|
254
|
+
## 🤝 Contributing
|
|
255
|
+
|
|
256
|
+
Contributions welcome — please read [CONTRIBUTING.md](CONTRIBUTING.md) first.
|
|
257
|
+
The hook contract (fail-soft, no telemetry, strict TypeScript) is
|
|
258
|
+
non-negotiable; the [`failsoft-auditor`](.claude/agents/failsoft-auditor.md)
|
|
259
|
+
agent guards it on every PR.
|
|
260
|
+
|
|
261
|
+
> [!TIP]
|
|
262
|
+
> ⭐ If memhook saves you tokens, **star the repo** — it helps other Claude Code users find it.
|
|
201
263
|
|
|
202
264
|
## License
|
|
203
265
|
|
package/dist/bin/memhook.d.ts
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* memhook CLI
|
|
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
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
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
|
|
1
|
+
{"version":3,"file":"memhook.d.ts","sourceRoot":"","sources":["../../bin/memhook.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;GAiBG"}
|