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.
- package/CHANGELOG.md +30 -72
- package/README.md +158 -69
- package/dist/bin/memhook.d.ts +11 -6
- package/dist/bin/memhook.d.ts.map +1 -1
- package/dist/bin/memhook.js +208 -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/backup.d.ts +10 -0
- package/dist/src/backup.d.ts.map +1 -0
- package/dist/src/backup.js +17 -0
- package/dist/src/backup.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/config.d.ts +11 -0
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +6 -0
- package/dist/src/config.js.map +1 -1
- package/dist/src/configFile.d.ts +6 -0
- package/dist/src/configFile.d.ts.map +1 -1
- package/dist/src/configFile.js.map +1 -1
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +6 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/init.d.ts +48 -0
- package/dist/src/init.d.ts.map +1 -0
- package/dist/src/init.js +327 -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 +22 -0
- package/dist/src/router.d.ts.map +1 -1
- package/dist/src/router.js +113 -8
- package/dist/src/router.js.map +1 -1
- package/dist/src/skills.d.ts +68 -0
- package/dist/src/skills.d.ts.map +1 -0
- package/dist/src/skills.js +73 -0
- package/dist/src/skills.js.map +1 -0
- package/dist/src/skillsCmd.d.ts +51 -0
- package/dist/src/skillsCmd.d.ts.map +1 -0
- package/dist/src/skillsCmd.js +273 -0
- package/dist/src/skillsCmd.js.map +1 -0
- 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 +9 -2
- package/skills/curate/SKILL.md +181 -0
- package/skills/curate/reference.md +105 -0
- package/skills/relay/SKILL.md +162 -0
- 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
|
-
## [
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
-
|
|
53
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
38
|
+
## 🤔 Why
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
54
|
+
## 🚀 Quick start
|
|
44
55
|
|
|
45
56
|
```bash
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
58
|
-
|
|
59
|
-
```
|
|
68
|
+
<details>
|
|
69
|
+
<summary>Manual setup (what <code>init</code> automates)</summary>
|
|
60
70
|
|
|
61
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
197
|
-
|
|
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
|
|
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"}
|