@nogataka/claw-memory 0.1.0 → 0.1.2

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.
@@ -3,14 +3,14 @@
3
3
  "owner": { "name": "nogataka" },
4
4
  "metadata": {
5
5
  "description": "claw-memory: local semantic memory + raw-log search for Claude Code",
6
- "version": "0.1.0"
6
+ "version": "0.1.2"
7
7
  },
8
8
  "plugins": [
9
9
  {
10
10
  "name": "claw-memory",
11
11
  "source": "./",
12
12
  "description": "Local semantic memory: auto-distill, recall injection, and raw Claude Code + Codex transcript search.",
13
- "version": "0.1.0"
13
+ "version": "0.1.2"
14
14
  }
15
15
  ]
16
16
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claw-memory",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Local semantic memory for Claude Code: auto-distills sessions, injects relevant past context, and searches raw Claude Code + Codex transcripts. sqlite-vec + local embeddings, no daemon, no Python.",
5
5
  "author": { "name": "nogataka" },
6
6
  "repository": "https://github.com/nogataka/claw-memory",
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "claw-memory",
3
+ "version": "0.1.2",
4
+ "description": "Local semantic memory for Codex: auto-distills sessions, injects relevant past context via hooks, and searches raw Codex + Claude Code transcripts. sqlite-vec + local embeddings, no daemon, no Python.",
5
+ "skills": "./skills/",
6
+ "mcpServers": "./.mcp.json",
7
+ "hooks": "./hooks/hooks.codex.json",
8
+ "interface": {
9
+ "displayName": "claw-memory",
10
+ "shortDescription": "Local semantic memory + transcript search for Codex",
11
+ "longDescription": "Auto-distills finished sessions into a local sqlite-vec store, injects relevant preferences and past-conversation context at session start via hooks, and exposes memory_recall / memory_search / memory_search_logs MCP tools. Runs fully local with Xenova e5 embeddings — no daemon, no Python.",
12
+ "developerName": "nogataka",
13
+ "category": "productivity",
14
+ "capabilities": ["memory", "context", "search"]
15
+ }
16
+ }
package/README.ja.md ADDED
@@ -0,0 +1,310 @@
1
+ # claw-memory
2
+
3
+ [English](README.md) | **日本語**
4
+
5
+ **AI コーディングエージェント(Claude Code / Codex)のためのローカル完結型・長期記憶。**
6
+ エージェントが過去のセッション・あなたの好み・以前の決定事項を記憶し、記録済みの全
7
+ トランスクリプトを横断検索できます。デーモン不要、Python 不要、外部ベクトル DB 不要。
8
+ データは一切マシン外に出ません(セッションを要約する LLM 呼び出しのみ外部で、これも
9
+ あなたが選択・制御します)。
10
+
11
+ ```bash
12
+ npm install -g @nogataka/claw-memory
13
+ ```
14
+
15
+ - **ストレージ**: `better-sqlite3` + `sqlite-vec` — ベクトルを 1 つの SQLite ファイル内に格納
16
+ - **埋め込み**: ローカルの `Xenova/multilingual-e5-small`(384次元・多言語・オフライン)
17
+ - **2 つの記憶ソース**: 蒸留済みのセマンティック DB と、Claude Code / Codex の生ログ全文検索
18
+ - **自動取り込み**: フックで終了済みセッションを蒸留し、新しいセッションへ関連記憶を注入
19
+ - **差し替え可能な LLM**: Claude / Codex のサブスクリプション(API キー不要)、または任意の
20
+ Anthropic / OpenAI 互換エンドポイントで蒸留
21
+
22
+ ---
23
+
24
+ ## 目次
25
+
26
+ - [機能](#機能)
27
+ - [インストールガイド](#インストールガイド)
28
+ - [MCP ツール](#mcp-ツール)
29
+ - [設定(環境変数)](#設定環境変数)
30
+ - [CLI リファレンス](#cli-リファレンス)
31
+ - [仕組み](#仕組み)
32
+ - [メモリビューア](#メモリビューア)
33
+ - [アンインストール](#アンインストール)
34
+ - [補足](#補足)
35
+
36
+ ---
37
+
38
+ ## 機能
39
+
40
+ ### 1. 2 つの独立した記憶ソース
41
+
42
+ | ソース | 内容 | ツール |
43
+ |--------|------|--------|
44
+ | **蒸留 DB** | LLM がセッションを要約 → 要約・好み・構造化メタデータ付きの埋め込みチャンク。セマンティック検索可能。 | `memory_recall`, `memory_search`, `memory_get` |
45
+ | **生ログ検索** | 実際の Claude Code(`~/.claude/projects`)/ Codex(`~/.codex/sessions`)ログを全文検索。蒸留していないセッションも対象。 | `memory_search_logs` |
46
+
47
+ 蒸留 DB は整理済みで高速に想起でき、生ログ検索は claw-memory 導入前を含め「いつか話した
48
+ こと」を必ず見つけられるセーフティネットです。
49
+
50
+ ### 2. 自動取り込み(distill)
51
+
52
+ セッション終了時、トランスクリプトを次の形に蒸留します。
53
+
54
+ - **構造化要約**(`### 依頼 / 調査・判明 / 完了 / 次の一手`)
55
+ - **ユーザーの好み**(言語・回答スタイル・フレームワーク・口調 など)を常時適用コンテキストとして保存
56
+ - **会話チャンク**をセマンティック検索用に埋め込み。各チャンクには
57
+ **observation type**(`discovery` / `bugfix` / `feature` / `decision` / `change`)、
58
+ **concepts**、**読んだ/編集したファイル** を付与
59
+
60
+ 蒸留は **増分的**(watermark で新規内容のないセッションをスキップ)かつ **冪等**
61
+ (再蒸留は置換であり重複しない)。クロスセッションの重複チャンクも排除します。
62
+
63
+ ### 3. 自動 recall 注入
64
+
65
+ セッション開始時(および各プロンプト時)に記憶ブロックを注入します。
66
+
67
+ - **好み** は `instruction="always-apply"` — エージェントが必ず従います。
68
+ - **直近の要約 + 類似する過去会話** は `instruction="reference-only"` — 背景として扱い、
69
+ 不必要に蒸し返しません。
70
+
71
+ これにより、文脈を再説明しなくても続きから作業できます。
72
+
73
+ ### 4. 構造化されたフィルタ検索
74
+
75
+ `memory_search` はトークン軽量なインデックス(id + タイトル + 日付 + type)を返します。
76
+ `type` / `concept` / `file` / 日付範囲で絞り込み、必要なものだけ `memory_get` で本文取得 —
77
+ コンテキスト消費を最小化します。
78
+
79
+ ### 5. プライバシーと安全性(設計段階から)
80
+
81
+ - **完全ローカル**: ストレージと埋め込みはマシン外に出ません。`distill` のみ LLM を呼び、
82
+ どの LLM を使うかはあなたが選択します。
83
+ - **`<private>…</private>`** で囲んだ区間は、保存・LLM 送信の前に除去されます。
84
+ - **`CLAW_MEMORY_EXCLUDED_PROJECTS`**: 指定パスは記録も想起もしません。
85
+ - **`memory_forget`**: チャンクをソフト削除。検索・recall・ビューアから消えます。
86
+
87
+ ### 6. 差し替え可能な LLM バックエンド(distill のみ)
88
+
89
+ サブスクリプションログイン(API キー不要)や任意の HTTP エンドポイントを利用できます
90
+ ([設定](#設定環境変数)参照)。tier ルーティングで、高頻度な distill を安価なモデルに
91
+ 振り分けられます。
92
+
93
+ ### 7. オンデマンドな Web ビューア
94
+
95
+ ビルド不要・読み取り専用のビューア(`claw-memory ui`)。プロジェクト・要約・チャンク
96
+ (メタデータ付き)・好みを閲覧でき、生ログ検索も実行できます。SSE で開いている間は自動
97
+ 更新。起動した時だけ動きます。
98
+
99
+ ---
100
+
101
+ ## インストールガイド
102
+
103
+ ### 前提条件
104
+
105
+ - **Node.js 20 以上**
106
+ - サブスクリプション LLM バックエンドを使う場合: **Claude Code CLI**(ログイン済み)/ **Codex CLI**(ログイン済み)
107
+ - 初回 `distill` 時に埋め込みモデル(約 100 MB、`~/.cache` にキャッシュ)をダウンロード
108
+
109
+ ### 手順 1 — パッケージをグローバルインストール
110
+
111
+ ```bash
112
+ npm install -g @nogataka/claw-memory
113
+ ```
114
+
115
+ グローバル導入によりフックと MCP サーバーが即座に起動します(未導入時はプラグインが
116
+ `npx -y @nogataka/claw-memory@latest` にフォールバックし、初回が遅くなります)。
117
+
118
+ ### 手順 2a — Claude Code(プラグイン、推奨)
119
+
120
+ ```text
121
+ /plugin marketplace add nogataka/claw-memory
122
+ /plugin install claw-memory
123
+ ```
124
+
125
+ Claude Code を再起動してください。次が自動登録されます。
126
+
127
+ - **MCP サーバー**(8 つの記憶ツール)
128
+ - **フック**: `SessionStart` / `UserPromptSubmit` → recall 注入、`Stop` → 自動 distill
129
+
130
+ 手動設定は不要です。確認は `/mcp` で `claw-memory` が見えるかどうかで行えます。
131
+
132
+ > **プラグインを使わない場合**: `claw-memory install --claude-code` で MCP サーバーと
133
+ > フックを `~/.claude/settings.json` にマージできます(冪等・バックアップ付き)。
134
+
135
+ ### 手順 2b — Codex(プラグイン)
136
+
137
+ Codex は Claude Code と同じプラグイン形式に対応しています。claw-memory は
138
+ `.codex-plugin/plugin.json` を同梱しているため、Codex プラグインとして導入すると
139
+ MCP サーバーと**ライフサイクル hooks の両方**が登録され、Claude Code と同等になります。
140
+
141
+ ```
142
+ codex
143
+ /plugins
144
+ ```
145
+
146
+ プラグインは Codex が互換提供する `${CLAUDE_PLUGIN_ROOT}` を介して次を登録します。
147
+
148
+ - `claw-memory` MCP サーバー(`.mcp.json`)
149
+ - `SessionStart` / `UserPromptSubmit` → **recall 自動注入**(memory ブロックを developer context として)
150
+ - `Stop` → 最近の Codex セッションの**自動 distill**(watermark 重複回避・非同期)
151
+ - `memory-recall` skill
152
+
153
+ ### 手順 2b(代替)— Codex(インストーラ/マーケット非経由)
154
+
155
+ マーケットプレイスではなく npm から導入する場合は CLI で登録します。
156
+
157
+ ```bash
158
+ claw-memory install --codex
159
+ ```
160
+
161
+ これは冪等に次を行います。
162
+
163
+ - `~/.codex/config.toml` に `[mcp_servers.claw-memory]` を追記(`config.toml.bak` にバックアップ)
164
+ - `~/.codex/hooks.json` に recall/distill hooks をマージ(バックアップあり・既存 hook は保全)
165
+ - `memory-recall` skill を配置
166
+ - `AGENTS.md` に「セッション冒頭で `memory_recall` を呼ぶ」指示を追記
167
+
168
+ Codex を再起動してください。**recall 注入・自動 distill は hooks で自動実行**され、手動操作は不要です。
169
+ 必要に応じて手動バックフィルも可能です。
170
+
171
+ ```bash
172
+ claw-memory distill-codex --recent # 最近の Codex セッションを蒸留(watermark で重複回避)
173
+ claw-memory distill-codex --all # 全件バックフィル
174
+ ```
175
+
176
+ ### 手順 2c — ソースから(開発)
177
+
178
+ ```bash
179
+ git clone https://github.com/nogataka/claw-memory
180
+ cd claw-memory
181
+ npm install # ネイティブの better-sqlite3 / sqlite-vec をビルド
182
+ npm run build # tsc -> dist/
183
+ npm link # 任意: `claw-memory` バイナリを公開
184
+ ```
185
+
186
+ ---
187
+
188
+ ## MCP ツール
189
+
190
+ | ツール | 用途 |
191
+ |--------|------|
192
+ | `memory_recall(query, cwd?, topK?)` | すぐ読めるコンテキストブロック: 好み + 直近要約 + 類似する過去会話。タスク開始時に呼ぶ。 |
193
+ | `memory_search(query, cwd?, limit?, type?, concept?, file?, dateFrom?, dateTo?)` | トークン軽量なヒットインデックス(id + タイトル + 日付 + type)。メタデータで絞り込み。 |
194
+ | `memory_get(ids)` | 指定 id の本文 + メタデータを取得。 |
195
+ | `memory_remember(text, cwd?, sessionId?)` | フリーテキストのメモを永続保存。 |
196
+ | `memory_distill(cwd, sessionId? \| transcriptPath?)` | セッションを要約して記憶化(LLM バックエンドが必要)。 |
197
+ | `memory_get_preferences(cwd?)` | プロジェクトの保存済み好みを一覧。 |
198
+ | `memory_search_logs(query, sources?, projectPath?, startDate?, endDate?, limit?, offset?)` | Claude Code + Codex の生ログを全文検索。 |
199
+ | `memory_forget(ids)` | チャンクをソフト削除(検索 / recall / ビューアから除外)。 |
200
+
201
+ `memory_distill`(LLM)と `memory_search_logs`(`~/.claude/projects`・`~/.codex/sessions`
202
+ を直接読む)以外は完全ローカルで動作します。
203
+
204
+ ---
205
+
206
+ ## 設定(環境変数)
207
+
208
+ | 変数 | 既定値 | 用途 |
209
+ |------|--------|------|
210
+ | `CLAW_MEMORY_DIR` | `~/.claw-memory` | データディレクトリ(`memory.db` と `logs/`)。 |
211
+ | `CLAW_MEMORY_LLM_BACKEND` | `agent-sdk` | `agent-sdk` \| `codex-sdk` \| `anthropic` \| `openai-compatible`。 |
212
+ | `CLAW_MEMORY_MODEL` / `AGENT_SDK_MODEL` | `claude-sonnet-4-5` | 既定の distill モデル(agent-sdk / anthropic)。 |
213
+ | `CLAW_MEMORY_TIER_SMART` / `_SUMMARY` / `_SIMPLE` | — | tier 別モデル上書き(安価モデルを単純作業へ)。 |
214
+ | `CLAW_MEMORY_CODEX_MODEL` | Codex 既定 | `codex-sdk` バックエンドのモデル。 |
215
+ | `CLAW_MEMORY_CODEX_API_KEY` | — | 任意。未設定なら Codex CLI のログインを使用。 |
216
+ | `ANTHROPIC_API_KEY` / `ANTHROPIC_BASE_URL` | — | `anthropic` バックエンド用。 |
217
+ | `CLAW_MEMORY_OPENAI_API_KEY` / `CLAW_MEMORY_OPENAI_BASE_URL` | — | `openai-compatible` 用(Gemini / OpenRouter / LM Studio)。 |
218
+ | `CLAW_MEMORY_EXCLUDED_PROJECTS` | — | 記録・想起しないパス部分文字列(カンマ/コロン区切り)。 |
219
+ | `MEMORY_SIMILARITY_MAX_DISTANCE` | `0.6` | セマンティックヒットの最大コサイン距離(小さいほど厳格)。 |
220
+ | `CLAW_MEMORY_UI_PORT` | `4319` | ビューアのポート。 |
221
+
222
+ ### LLM バックエンド
223
+
224
+ | バックエンド | 認証 | 備考 |
225
+ |--------------|------|------|
226
+ | `agent-sdk`(既定) | Claude CLI ログイン(Pro/Max/Team/Enterprise) | ゼロ設定・API キー不要 |
227
+ | `codex-sdk` | Codex CLI ログイン(ChatGPT/Codex プラン) | `@openai/codex-sdk`。read-only・ツール無効で実行 |
228
+ | `anthropic` | `ANTHROPIC_API_KEY` | fetch ベースの Messages API |
229
+ | `openai-compatible` | `CLAW_MEMORY_OPENAI_API_KEY` + ベース URL + `CLAW_MEMORY_MODEL` | Gemini / OpenRouter / LM Studio |
230
+
231
+ ```bash
232
+ export CLAW_MEMORY_LLM_BACKEND=codex-sdk # Codex サブスクリプションで distill
233
+ ```
234
+
235
+ ---
236
+
237
+ ## CLI リファレンス
238
+
239
+ ```bash
240
+ claw-memory mcp # stdio MCP サーバー(エージェントが起動するもの)
241
+ claw-memory ui [--port N] [--open] # 読み取り専用 Web ビューア
242
+ claw-memory distill --cwd P --session ID [--path FILE] [--if-stale]
243
+ claw-memory distill-codex [--recent] [--limit N] [--all]
244
+ claw-memory remember --cwd P "メモ"
245
+ claw-memory search-logs "クエリ" [--source claude-code,codex] [--project P]
246
+ [--start ISO] [--end ISO] [--limit N] [--offset N]
247
+ claw-memory hook <recall|distill> # ライフサイクルフック(JSON を stdin で受領)
248
+ claw-memory install [--codex | --claude-code] # MCP + フックを登録(既定: codex)
249
+ claw-memory uninstall [--codex | --claude-code]
250
+ ```
251
+
252
+ ---
253
+
254
+ ## 仕組み
255
+
256
+ ```
257
+ [書き込み側] [読み出し側]
258
+ セッション終了 (Stop フック / distill-codex) セッション開始 (SessionStart フック / memory_recall)
259
+ └ distill └ buildMemoryBlock
260
+ ├ 要約 ───────────────► session_summaries ──► <previous-session-summaries>
261
+ ├ 好み ───────────────► user_preferences ───► <user-preferences>(always-apply)
262
+ └ チャンク(埋込+メタ) ─► vec_chunks + ────────► <relevant-past-conversations>
263
+ conversation_chunks (コサイン KNN・プロジェクト/メタ絞り込み)
264
+
265
+ [別ソース] 生ログ (~/.claude/projects, ~/.codex/sessions) ──► memory_search_logs
266
+ ```
267
+
268
+ - **単一の SQLite ファイル** `~/.claw-memory/memory.db`。`sqlite-vec` が 384 次元ベクトルを
269
+ 内包し、メタデータは並列テーブル、FTS5 がキーワード fallback を提供。
270
+ - **埋め込み** はローカルの `Xenova/multilingual-e5-small`(多言語・オフライン・e5 の
271
+ `query:`/`passage:` プレフィックス遵守)。モデルは MCP プロセスごとに 1 回ロード。
272
+ - **検索** はハイブリッド: コサイン KNN(プロジェクト + メタデータで絞り込み)を FTS5 の
273
+ キーワードヒットで補強し、重複排除して距離順にソート。
274
+ - 構造化された日次ログを `~/.claw-memory/logs/` に出力。
275
+
276
+ ---
277
+
278
+ ## メモリビューア
279
+
280
+ ```bash
281
+ claw-memory ui --open # http://localhost:4319
282
+ ```
283
+
284
+ 読み取り専用。プロジェクト・要約・会話チャンク(type / concepts / files 付き)・好みを
285
+ 閲覧でき、**🔎 ログ検索** で Claude Code + Codex の生ログを全文検索できます。開いている間
286
+ は SSE で自動更新。それ以外はバックグラウンドで何も動きません — 確認したい時だけ起動して
287
+ ください。
288
+
289
+ ---
290
+
291
+ ## アンインストール
292
+
293
+ ```bash
294
+ claw-memory uninstall --codex # config.toml ブロック + hooks + skill + AGENTS 記述を除去
295
+ claw-memory uninstall --claude-code # settings.json から mcp + フックを除去
296
+ # Claude Code プラグイン: /plugin uninstall claw-memory
297
+ npm uninstall -g @nogataka/claw-memory
298
+ ```
299
+
300
+ メモリ DB は残ります。完全に消す場合は `~/.claw-memory` を削除してください。
301
+
302
+ ---
303
+
304
+ ## 補足
305
+
306
+ - `better-sqlite3` / `sqlite-vec` はネイティブモジュールです。Node の ABI 変更後は `npm rebuild` を実行してください。
307
+ - MCP サーバーはエージェントセッションごとに常駐するため、埋め込みモデルは 1 回だけロードされます。
308
+ - ビューアと MCP は同時実行できます(SQLite WAL が並行読み書きを処理)。
309
+ - インストール時、依存は `legacy-peer-deps=true` で解決されます(同梱 SDK 間の zod の
310
+ peer 範囲の重なりによるもの)。`.npmrc` に設定済みで無害です。
package/README.md CHANGED
@@ -1,168 +1,315 @@
1
1
  # claw-memory
2
2
 
3
- Independent, **in-process** semantic memory for any MCP-capable agent (Claude Code, Codex, …).
4
- No daemon, no Python, no external vector DB.
3
+ **English** | [日本語](README.ja.md)
5
4
 
6
- - **Storage**: `better-sqlite3` + `sqlite-vec` (vectors live *inside* the SQLite file)
5
+ **Local, in-process long-term memory for AI coding agents (Claude Code & Codex).**
6
+ Your agent remembers past sessions, your preferences, and prior decisions — and can
7
+ search every raw transcript you've ever recorded. No daemon, no Python, no external
8
+ vector database, no data leaving your machine (except the LLM call that summarizes a
9
+ session, which you control).
10
+
11
+ ```bash
12
+ npm install -g @nogataka/claw-memory
13
+ ```
14
+
15
+ - **Storage**: `better-sqlite3` + `sqlite-vec` — vectors live *inside* one SQLite file
7
16
  - **Embeddings**: local `Xenova/multilingual-e5-small` (384-dim, multilingual, offline)
8
- - **Search**: semantic (cosine KNN, per-project metadata filter) + FTS5 keyword fallback
9
- - **Write**: LLM distillation of session transcripts → summary + preferences + chunks
10
- - **Viewer**: optional, on-demand lightweight web UI (no framework, no build)
17
+ - **Two memory sources**: a distilled semantic DB **and** full-text search over raw
18
+ Claude Code + Codex transcripts
19
+ - **Auto-capture**: lifecycle hooks distill finished sessions and inject relevant memory
20
+ back into new ones
21
+ - **Pluggable LLM**: distill via your Claude or Codex subscription (no API key), or any
22
+ Anthropic / OpenAI-compatible endpoint
23
+
24
+ ---
25
+
26
+ ## Table of contents
27
+
28
+ - [Features](#features)
29
+ - [Installation guide](#installation-guide)
30
+ - [MCP tools](#mcp-tools)
31
+ - [Configuration](#configuration-environment-variables)
32
+ - [CLI reference](#cli-reference)
33
+ - [How it works](#how-it-works)
34
+ - [Memory viewer](#memory-viewer)
35
+ - [Uninstall](#uninstall)
36
+ - [Notes](#notes)
37
+
38
+ ---
39
+
40
+ ## Features
41
+
42
+ ### 1. Two independent memory sources
43
+
44
+ | Source | What it is | Tooling |
45
+ |--------|-----------|---------|
46
+ | **Distilled DB** | LLM-summarized sessions → summaries, preferences, and embedded conversation chunks with structured metadata. Semantically searchable. | `memory_recall`, `memory_search`, `memory_get` |
47
+ | **Raw transcript search** | Full-text grep over your *actual* Claude Code (`~/.claude/projects`) and Codex (`~/.codex/sessions`) logs — including sessions that were never distilled. | `memory_search_logs` |
48
+
49
+ The distilled DB is curated and fast to recall; raw search is a safety net that finds
50
+ anything you ever discussed, even before claw-memory was installed.
51
+
52
+ ### 2. Automatic capture (distill)
53
+
54
+ When a session ends, claw-memory distills the transcript into:
55
+
56
+ - a **structured summary** (`### 依頼 / 調査・判明 / 完了 / 次の一手`),
57
+ - **user preferences** (language, response style, frameworks, tone, …) applied as
58
+ always-on context,
59
+ - **conversation chunks** embedded for semantic search, each tagged with an
60
+ **observation type** (`discovery` / `bugfix` / `feature` / `decision` / `change`),
61
+ **concepts**, and **files read / modified**.
62
+
63
+ Distillation is **incremental** (a watermark skips sessions with no new content) and
64
+ **idempotent** (re-distilling a session replaces, never duplicates). Cross-session
65
+ duplicate chunks are dropped.
66
+
67
+ ### 3. Automatic recall injection
68
+
69
+ At the start of a session (and on each prompt), claw-memory injects a memory block:
70
+
71
+ - **Preferences** as `instruction="always-apply"` — the agent follows them.
72
+ - **Recent summaries + semantically similar past conversations** as
73
+ `instruction="reference-only"` — used as background, not parroted back.
74
+
75
+ This means the agent picks up where you left off without you re-explaining context.
76
+
77
+ ### 4. Structured, filterable search
78
+
79
+ `memory_search` returns a token-light index (id + title + date + type). Filter by
80
+ `type`, `concept`, `file`, or date range, then pull full bodies with `memory_get` only
81
+ for what you need — keeping context usage minimal.
82
+
83
+ ### 5. Privacy & safety, by design
84
+
85
+ - **Fully local**: storage and embeddings never leave your machine. Only `distill`
86
+ calls an LLM, and you choose which one.
87
+ - **`<private>…</private>`** spans are stripped before anything is persisted or sent
88
+ to the LLM.
89
+ - **`CLAW_MEMORY_EXCLUDED_PROJECTS`**: never record or recall listed paths.
90
+ - **`memory_forget`**: soft-delete chunks; they vanish from search, recall, and the viewer.
91
+
92
+ ### 6. Pluggable LLM backend (distill only)
93
+
94
+ Use a subscription login (no API key) or any HTTP endpoint — see
95
+ [Configuration](#configuration-environment-variables). Tier routing lets cheap models
96
+ handle the high-frequency distill work.
97
+
98
+ ### 7. On-demand web viewer
99
+
100
+ A zero-build, read-only viewer (`claw-memory ui`) to browse projects, summaries,
101
+ chunks (with their metadata), preferences, and to run raw-log search — with live
102
+ updates via SSE. It runs only when you start it.
11
103
 
12
- Data lives at `~/.claw-memory/memory.db` (override with `CLAW_MEMORY_DIR`). Completely
13
- separate from any other app.
104
+ ---
14
105
 
15
- ## Install
106
+ ## Installation guide
16
107
 
17
- Published as `@nogataka/claw-memory`. Install once globally so hooks/MCP resolve fast
18
- (otherwise they fall back to `npx`):
108
+ ### Prerequisites
109
+
110
+ - **Node.js ≥ 20**
111
+ - For the subscription LLM backends: **Claude Code CLI** (logged in) and/or **Codex CLI** (logged in)
112
+ - First `distill` downloads the embedding model (~100 MB, cached under `~/.cache`)
113
+
114
+ ### Step 1 — install the package globally
19
115
 
20
116
  ```bash
21
117
  npm install -g @nogataka/claw-memory
22
118
  ```
23
119
 
24
- First run downloads the e5 model (~100 MB, cached in `~/.cache`).
120
+ Installing globally makes hooks and the MCP server start instantly. (Without it, the
121
+ plugin falls back to `npx -y @nogataka/claw-memory@latest`, which is slower on first run.)
25
122
 
26
- ### Claude Code (plugin)
123
+ ### Step 2a — Claude Code (plugin, recommended)
27
124
 
28
- ```
125
+ ```text
29
126
  /plugin marketplace add nogataka/claw-memory
30
127
  /plugin install claw-memory
31
128
  ```
32
129
 
33
- Restart Claude Code. This auto-registers the MCP server and the hooks
34
- (SessionStart/UserPromptSubmit → recall injection, Stop → auto-distill).
35
- No manual setup. (Not using the plugin? Run `claw-memory install --claude-code`
36
- to merge the MCP server + hooks into `~/.claude/settings.json`.)
130
+ Restart Claude Code. This auto-registers:
131
+
132
+ - the **MCP server** (8 memory tools), and
133
+ - the **hooks**: `SessionStart` / `UserPromptSubmit` recall injection, `Stop` → auto-distill.
37
134
 
38
- ### Codex (installer)
135
+ No manual config. To verify, run `/mcp` and look for `claw-memory`.
39
136
 
40
- Codex has no third-party plugin marketplace, so register via the installer:
137
+ > **Not using the plugin?** Run `claw-memory install --claude-code` to merge the MCP
138
+ > server and hooks into `~/.claude/settings.json` (idempotent, backs up the file).
139
+
140
+ ### Step 2b — Codex (plugin)
141
+
142
+ Codex supports the same plugin format as Claude Code. claw-memory ships a
143
+ `.codex-plugin/plugin.json` manifest, so installing it as a Codex plugin wires up
144
+ the MCP server **and** the lifecycle hooks — full parity with Claude Code:
145
+
146
+ ```
147
+ codex
148
+ /plugins
149
+ ```
150
+
151
+ The plugin registers, via Codex's `${CLAUDE_PLUGIN_ROOT}` (provided for compatibility):
152
+
153
+ - the `claw-memory` MCP server (`.mcp.json`),
154
+ - `SessionStart` / `UserPromptSubmit` → **auto recall injection** (memory block as developer context),
155
+ - `Stop` → **auto distill** of recent Codex sessions (watermark-deduped, async), and
156
+ - the `memory-recall` skill.
157
+
158
+ ### Step 2b (alt) — Codex (installer, no marketplace)
159
+
160
+ If you install from npm instead of the plugin marketplace, register via the CLI:
41
161
 
42
162
  ```bash
43
- claw-memory install --codex # adds [mcp_servers.claw-memory] to ~/.codex/config.toml
44
- # + memory-recall skill + AGENTS.md recall instruction
163
+ claw-memory install --codex
45
164
  ```
46
165
 
47
- Restart Codex. Recall is available via the `memory_recall` MCP tool (the AGENTS.md
48
- note tells the agent to call it at session start). **Auto-distill is manual on Codex**
49
- (no notify hook); run periodically:
166
+ This idempotently:
167
+
168
+ - adds `[mcp_servers.claw-memory]` to `~/.codex/config.toml` (backed up to `config.toml.bak`),
169
+ - merges recall/distill hooks into `~/.codex/hooks.json` (backed up; your own hooks are preserved),
170
+ - installs the `memory-recall` skill, and
171
+ - appends an `AGENTS.md` instruction telling the agent to call `memory_recall` at session start.
172
+
173
+ Restart Codex. **Recall injection and auto-distill now run via hooks** — no manual step needed.
174
+ You can still backfill on demand:
50
175
 
51
176
  ```bash
52
177
  claw-memory distill-codex --recent # distill recent Codex sessions (watermark-deduped)
53
178
  claw-memory distill-codex --all # backfill everything
54
179
  ```
55
180
 
56
- Remove with `claw-memory uninstall --codex` (or `--claude-code`).
57
-
58
- ### From source
181
+ ### Step 2c from source (development)
59
182
 
60
183
  ```bash
184
+ git clone https://github.com/nogataka/claw-memory
61
185
  cd claw-memory
62
- npm install # builds native better-sqlite3 / sqlite-vec
63
- npm run build # tsc -> dist/
186
+ npm install # builds native better-sqlite3 / sqlite-vec
187
+ npm run build # tsc -> dist/
188
+ npm link # optional: expose the `claw-memory` binary
64
189
  ```
65
190
 
191
+ ---
192
+
66
193
  ## MCP tools
67
194
 
68
195
  | Tool | Purpose |
69
196
  |------|---------|
70
- | `memory_recall(query, cwd?, topK?)` | Ready-to-read context block: preferences + summaries + similar past conversations |
71
- | `memory_search(query, cwd?, limit?)` | Token-efficient hit index (id + title + date) |
72
- | `memory_get(ids)` | Full text for given chunk ids |
73
- | `memory_remember(text, cwd?, sessionId?)` | Store a free-text note |
74
- | `memory_distill(cwd, sessionId? \| transcriptPath?)` | Summarize a session into memory (needs LLM creds) |
75
- | `memory_get_preferences(cwd?)` | List stored preferences |
76
- | `memory_search_logs(query, sources?, projectPath?, startDate?, endDate?, limit?, offset?)` | Full-text search over RAW Claude Code + Codex transcripts (second memory source; finds undistilled history) |
77
- | `memory_forget(ids)` | Soft-delete chunks (hidden from search/recall/viewer) |
78
-
79
- `memory_distill` uses an LLM (see *LLM backend* below). `memory_search_logs` reads
80
- `~/.claude/projects` and `~/.codex/sessions` directly. All other tools are fully local.
81
-
82
- ## LLM backend (distill only)
83
-
84
- distill needs a single tool-less completion, selectable via `CLAW_MEMORY_LLM_BACKEND`:
197
+ | `memory_recall(query, cwd?, topK?)` | Ready-to-read context block: preferences + recent summaries + similar past conversations. Call at the start of a task. |
198
+ | `memory_search(query, cwd?, limit?, type?, concept?, file?, dateFrom?, dateTo?)` | Token-light hit index (id + title + date + type), with metadata filters. |
199
+ | `memory_get(ids)` | Full text + metadata for given chunk ids. |
200
+ | `memory_remember(text, cwd?, sessionId?)` | Store a durable free-text note. |
201
+ | `memory_distill(cwd, sessionId? \| transcriptPath?)` | Summarize a session into memory (needs an LLM backend). |
202
+ | `memory_get_preferences(cwd?)` | List stored preferences for the project. |
203
+ | `memory_search_logs(query, sources?, projectPath?, startDate?, endDate?, limit?, offset?)` | Full-text search over RAW Claude Code + Codex transcripts. |
204
+ | `memory_forget(ids)` | Soft-delete chunks (hidden from search / recall / viewer). |
205
+
206
+ All tools are fully local except `memory_distill` (LLM) and `memory_search_logs`
207
+ (reads `~/.claude/projects` and `~/.codex/sessions` directly).
208
+
209
+ ---
210
+
211
+ ## Configuration (environment variables)
212
+
213
+ | Variable | Default | Purpose |
214
+ |----------|---------|---------|
215
+ | `CLAW_MEMORY_DIR` | `~/.claw-memory` | Data directory (holds `memory.db` and `logs/`). |
216
+ | `CLAW_MEMORY_LLM_BACKEND` | `agent-sdk` | `agent-sdk` \| `codex-sdk` \| `anthropic` \| `openai-compatible`. |
217
+ | `CLAW_MEMORY_MODEL` / `AGENT_SDK_MODEL` | `claude-sonnet-4-5` | Default distill model (agent-sdk / anthropic). |
218
+ | `CLAW_MEMORY_TIER_SMART` / `_SUMMARY` / `_SIMPLE` | — | Per-tier model override (route cheap models to simple work). |
219
+ | `CLAW_MEMORY_CODEX_MODEL` | Codex default | Model for the `codex-sdk` backend. |
220
+ | `CLAW_MEMORY_CODEX_API_KEY` | — | Optional; otherwise the Codex CLI login is used. |
221
+ | `ANTHROPIC_API_KEY` / `ANTHROPIC_BASE_URL` | — | For the `anthropic` backend. |
222
+ | `CLAW_MEMORY_OPENAI_API_KEY` / `CLAW_MEMORY_OPENAI_BASE_URL` | — | For the `openai-compatible` backend (Gemini / OpenRouter / LM Studio). |
223
+ | `CLAW_MEMORY_EXCLUDED_PROJECTS` | — | Comma/colon-separated path substrings to never record or recall. |
224
+ | `MEMORY_SIMILARITY_MAX_DISTANCE` | `0.6` | Max cosine distance for a semantic hit (lower = stricter). |
225
+ | `CLAW_MEMORY_UI_PORT` | `4319` | Viewer port. |
226
+
227
+ ### LLM backends
85
228
 
86
229
  | Backend | Auth | Notes |
87
230
  |---------|------|-------|
88
- | `agent-sdk` (default) | Claude Code CLI login (Claude Pro/Max/Team/Enterprise) | zero-config, no API key |
89
- | `codex-sdk` | Codex CLI login (ChatGPT/Codex plan) | `@openai/codex-sdk`, no API key; requires Codex CLI. Model via `CLAW_MEMORY_CODEX_MODEL` |
90
- | `anthropic` | `ANTHROPIC_API_KEY` (`ANTHROPIC_BASE_URL` optional) | plain Messages API |
91
- | `openai-compatible` | `CLAW_MEMORY_OPENAI_API_KEY` + `CLAW_MEMORY_OPENAI_BASE_URL` | Gemini / OpenRouter / LM Studio (set `CLAW_MEMORY_MODEL`) |
231
+ | `agent-sdk` (default) | Claude CLI login (Pro/Max/Team/Enterprise) | zero-config, no API key |
232
+ | `codex-sdk` | Codex CLI login (ChatGPT/Codex plan) | `@openai/codex-sdk`; runs read-only, no tools |
233
+ | `anthropic` | `ANTHROPIC_API_KEY` | plain Messages API over fetch |
234
+ | `openai-compatible` | `CLAW_MEMORY_OPENAI_API_KEY` + base URL + `CLAW_MEMORY_MODEL` | Gemini / OpenRouter / LM Studio |
92
235
 
93
236
  ```bash
94
- export CLAW_MEMORY_LLM_BACKEND=codex-sdk # use the Codex subscription for distill
237
+ export CLAW_MEMORY_LLM_BACKEND=codex-sdk # distill using the Codex subscription
95
238
  ```
96
239
 
97
- Both SDK backends reuse a subscription login (no API key). Tier routing (cheap models for
98
- simple work): `CLAW_MEMORY_TIER_SMART` / `_SUMMARY` / `_SIMPLE`, else `AGENT_SDK_MODEL` /
99
- `CLAW_MEMORY_MODEL` (agent-sdk/anthropic default `claude-sonnet-4-5`; codex-sdk uses the Codex default).
100
-
101
- ## Automatic capture & recall (Claude Code hooks)
240
+ ---
102
241
 
103
- No daemon — hooks spawn the CLI per event. Register in `~/.claude/settings.json`:
242
+ ## CLI reference
104
243
 
105
- ```json
106
- {
107
- "hooks": {
108
- "SessionStart": [{ "hooks": [{ "type": "command", "command": "/Volumes/Data/dev/claw-memory/hooks/claw-hook.sh recall" }] }],
109
- "UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "/Volumes/Data/dev/claw-memory/hooks/claw-hook.sh recall" }] }],
110
- "Stop": [{ "hooks": [{ "type": "command", "command": "/Volumes/Data/dev/claw-memory/hooks/claw-hook.sh distill" }] }]
111
- }
112
- }
244
+ ```bash
245
+ claw-memory mcp # stdio MCP server (what agents spawn)
246
+ claw-memory ui [--port N] [--open] # read-only web viewer
247
+ claw-memory distill --cwd P --session ID [--path FILE] [--if-stale]
248
+ claw-memory distill-codex [--recent] [--limit N] [--all]
249
+ claw-memory remember --cwd P "a note"
250
+ claw-memory search-logs "query" [--source claude-code,codex] [--project P]
251
+ [--start ISO] [--end ISO] [--limit N] [--offset N]
252
+ claw-memory hook <recall|distill> # lifecycle hook (reads JSON on stdin)
253
+ claw-memory install [--codex | --claude-code] # register MCP + hooks (default: codex)
254
+ claw-memory uninstall [--codex | --claude-code]
113
255
  ```
114
256
 
115
- - **recall** (SessionStart / UserPromptSubmit): prints the memory block to stdout → injected into context. Preferences + recent summaries, plus semantically similar past conversations when the prompt is present.
116
- - **distill** (Stop): detached, fire-and-forget. Incremental via a watermark (skips sessions with no new content). Honors `CLAW_MEMORY_EXCLUDED_PROJECTS` and `<private>…</private>`.
257
+ ---
117
258
 
118
- ## Register with an agent
259
+ ## How it works
119
260
 
120
- ### Claude Code — `.mcp.json` (project root) or `~/.claude.json`
121
-
122
- ```json
123
- {
124
- "mcpServers": {
125
- "memory": {
126
- "command": "node",
127
- "args": ["/Volumes/Data/dev/claw-memory/dist/cli.js", "mcp"]
128
- }
129
- }
130
- }
131
261
  ```
132
-
133
- ### Codex `~/.codex/config.toml`
134
-
135
- ```toml
136
- [mcp_servers.memory]
137
- command = "node"
138
- args = ["/Volumes/Data/dev/claw-memory/dist/cli.js", "mcp"]
262
+ [write path] [read path]
263
+ session ends (Stop hook / distill-codex) session starts (SessionStart hook / memory_recall)
264
+ └ distill └ buildMemoryBlock
265
+ ├ summary ───────────► session_summaries ──► <previous-session-summaries>
266
+ ├ preferences ────────► user_preferences ───► <user-preferences> (always-apply)
267
+ chunks (embed+meta) ─► vec_chunks + ────────► <relevant-past-conversations>
268
+ conversation_chunks (cosine KNN, per-project, filtered)
269
+
270
+ [separate source] raw logs (~/.claude/projects, ~/.codex/sessions) ──► memory_search_logs
139
271
  ```
140
272
 
141
- Then add to your `CLAUDE.md` / `AGENTS.md`:
142
- > 会話の冒頭で `memory_recall` を呼び、過去の文脈と好みを取得すること。
273
+ - **One SQLite file** at `~/.claw-memory/memory.db`. `sqlite-vec` stores 384-dim vectors
274
+ inside it; metadata lives in a parallel table; FTS5 provides a keyword fallback.
275
+ - **Embeddings** run locally via `Xenova/multilingual-e5-small` (multilingual, offline,
276
+ e5 `query:`/`passage:` prefixing). The model loads once per MCP process.
277
+ - **Search** is hybrid: cosine KNN (filtered by project + metadata) augmented with FTS5
278
+ keyword hits, de-duplicated and distance-sorted.
279
+ - Daily structured logs are written to `~/.claw-memory/logs/`.
280
+
281
+ ---
143
282
 
144
283
  ## Memory viewer
145
284
 
146
285
  ```bash
147
- npm run ui # http://localhost:4319 , opens browser
148
- # or
149
- node dist/cli.js ui --port 4319 --open
286
+ claw-memory ui --open # http://localhost:4319
150
287
  ```
151
288
 
152
- Read-only. Browse projects, session summaries, conversation chunks and preferences.
153
- Start it only when you want to inspect; nothing runs in the background otherwise.
289
+ Read-only. Browse projects, session summaries, conversation chunks (with type /
290
+ concepts / files), and preferences; toggle **🔎 ログ検索** to full-text search raw
291
+ Claude Code + Codex transcripts. Live-updates via SSE while open. Nothing runs in the
292
+ background otherwise — start it only when you want to inspect.
154
293
 
155
- ## CLI
294
+ ---
295
+
296
+ ## Uninstall
156
297
 
157
298
  ```bash
158
- node dist/cli.js mcp # stdio MCP server
159
- node dist/cli.js ui [--port N] [--open] # viewer
160
- node dist/cli.js distill --cwd <dir> --session <id> # distill a CC session
161
- node dist/cli.js remember --cwd <dir> "a note" # store a note
299
+ claw-memory uninstall --codex # remove config.toml block + hooks + skill + AGENTS note
300
+ claw-memory uninstall --claude-code # remove mcp + hooks from settings.json
301
+ # Claude Code plugin: /plugin uninstall claw-memory
302
+ npm uninstall -g @nogataka/claw-memory
162
303
  ```
163
304
 
305
+ Your memory database is left untouched; delete `~/.claw-memory` to wipe it.
306
+
307
+ ---
308
+
164
309
  ## Notes
165
310
 
166
- - `better-sqlite3` / `sqlite-vec` are native; rebuild on Node ABI changes (`npm rebuild`).
311
+ - `better-sqlite3` / `sqlite-vec` are native modules; run `npm rebuild` after a Node ABI change.
167
312
  - The MCP server is long-lived per agent session, so the embedding model loads once.
168
- - Viewer + MCP can run simultaneously (SQLite WAL handles concurrent read/write).
313
+ - Viewer + MCP can run simultaneously SQLite WAL handles concurrent read/write.
314
+ - On install, dependencies resolve with `legacy-peer-deps=true` (a zod peer-range overlap
315
+ between bundled SDKs); this is configured in `.npmrc` and is harmless.
package/dist/cli.js CHANGED
@@ -88,7 +88,7 @@ async function main() {
88
88
  if (target === "codex") {
89
89
  const { installCodex } = await import("./core/installer/codex.js");
90
90
  console.log("claw-memory installed for Codex:\n " + installCodex().join("\n "));
91
- console.log("\n注意: Codex を再起動してください。自動 distill は手動 (`claw-memory distill-codex --recent`)。");
91
+ console.log("\n注意: Codex を再起動してください。recall 注入・自動 distill hooks で自動実行されます。");
92
92
  }
93
93
  else {
94
94
  const { installClaude } = await import("./core/installer/claude.js");
@@ -13,7 +13,17 @@ import { readFileSync, writeFileSync, existsSync, mkdirSync, copyFileSync, rmSyn
13
13
  const CODEX_DIR = join(homedir(), ".codex");
14
14
  const CONFIG = join(CODEX_DIR, "config.toml");
15
15
  const AGENTS = join(CODEX_DIR, "AGENTS.md");
16
+ const HOOKS = join(CODEX_DIR, "hooks.json");
16
17
  const SKILL_DIR = join(CODEX_DIR, "skills", "memory-recall");
18
+ // Codex lifecycle hooks for the manual (non-plugin) install path. Mirrors the
19
+ // Claude Code hook wiring: recall on session start / prompt, distill on stop.
20
+ // Codex Stop carries no Claude-format transcript, so distill scans recent Codex
21
+ // session files (watermark-guarded) instead of a single transcript_path.
22
+ const HOOK_EVENTS = [
23
+ ["SessionStart", "hook recall", false],
24
+ ["UserPromptSubmit", "hook recall", false],
25
+ ["Stop", "distill-codex --limit 5", true],
26
+ ];
17
27
  const BEGIN = "# >>> claw-memory >>>";
18
28
  const END = "# <<< claw-memory <<<";
19
29
  const A_BEGIN = "<!-- >>> claw-memory >>> -->";
@@ -24,18 +34,73 @@ function tomlStr(s) {
24
34
  }
25
35
  /** Prefer a globally installed `claw-memory`; otherwise run via npx. */
26
36
  function resolveCommand() {
37
+ const bin = resolveBin();
38
+ return bin
39
+ ? { command: bin, args: ["mcp"] }
40
+ : { command: "npx", args: ["-y", "@nogataka/claw-memory@latest", "mcp"] };
41
+ }
42
+ /** Absolute path to a globally installed `claw-memory`, or null. */
43
+ function resolveBin() {
27
44
  try {
28
45
  const found = execFileSync("command", ["-v", "claw-memory"], {
29
46
  shell: "/bin/bash",
30
47
  encoding: "utf-8",
31
- }).trim();
32
- if (found)
33
- return { command: found.split("\n")[0], args: ["mcp"] };
48
+ }).trim().split("\n")[0];
49
+ return found || null;
50
+ }
51
+ catch {
52
+ return null;
53
+ }
54
+ }
55
+ /** How to invoke the CLI from a hook command line. */
56
+ function cliInvoker() {
57
+ return resolveBin() ?? "npx -y @nogataka/claw-memory@latest";
58
+ }
59
+ function readHooks() {
60
+ if (!existsSync(HOOKS))
61
+ return {};
62
+ try {
63
+ return JSON.parse(readFileSync(HOOKS, "utf-8"));
34
64
  }
35
65
  catch {
36
- // not on PATH
66
+ return {};
37
67
  }
38
- return { command: "npx", args: ["-y", "@nogataka/claw-memory@latest", "mcp"] };
68
+ }
69
+ /** A hook command is ours if it runs the claw-memory CLI recall/distill subcommand. */
70
+ function isOurHook(cmd) {
71
+ return cmd.includes("claw-memory") && (cmd.includes("hook recall") || cmd.includes("distill-codex"));
72
+ }
73
+ /** Merge our recall/distill hooks into ~/.codex/hooks.json, replacing stale ones. */
74
+ function installHooks() {
75
+ const cli = cliInvoker();
76
+ const f = readHooks();
77
+ f.hooks = f.hooks ?? {};
78
+ for (const [event, sub, isAsync] of HOOK_EVENTS) {
79
+ const list = (f.hooks[event] ?? []).filter((g) => !g.hooks?.some((h) => isOurHook(h.command)));
80
+ list.push({ hooks: [{ type: "command", command: `${cli} ${sub}`, async: isAsync }] });
81
+ f.hooks[event] = list;
82
+ }
83
+ if (existsSync(HOOKS))
84
+ copyFileSync(HOOKS, HOOKS + ".bak");
85
+ writeFileSync(HOOKS, JSON.stringify(f, null, 2) + "\n");
86
+ }
87
+ /** Remove our hooks from ~/.codex/hooks.json, preserving the user's own. */
88
+ function removeHooks() {
89
+ if (!existsSync(HOOKS))
90
+ return false;
91
+ const f = readHooks();
92
+ if (!f.hooks)
93
+ return false;
94
+ for (const event of Object.keys(f.hooks)) {
95
+ f.hooks[event] = f.hooks[event]
96
+ .map((g) => ({ ...g, hooks: (g.hooks ?? []).filter((h) => !isOurHook(h.command)) }))
97
+ .filter((g) => g.hooks.length > 0);
98
+ if (f.hooks[event].length === 0)
99
+ delete f.hooks[event];
100
+ }
101
+ copyFileSync(HOOKS, HOOKS + ".bak");
102
+ writeFileSync(HOOKS, JSON.stringify(f, null, 2) + "\n");
103
+ return true;
39
104
  }
40
105
  /** Insert or replace the marker-delimited block in `content`. */
41
106
  function upsertBlock(content, begin, end, block) {
@@ -98,6 +163,9 @@ export function installCodex() {
98
163
  const agentsPrev = existsSync(AGENTS) ? readFileSync(AGENTS, "utf-8") : "";
99
164
  writeFileSync(AGENTS, upsertBlock(agentsPrev, A_BEGIN, A_END, agentsBlock));
100
165
  done.push("AGENTS.md: recall instruction");
166
+ // 4) lifecycle hooks: auto recall (SessionStart/UserPromptSubmit) + auto distill (Stop)
167
+ installHooks();
168
+ done.push("hooks.json: SessionStart/UserPromptSubmit→recall, Stop→distill-codex");
101
169
  return done;
102
170
  }
103
171
  export function uninstallCodex() {
@@ -111,6 +179,9 @@ export function uninstallCodex() {
111
179
  writeFileSync(AGENTS, removeBlock(readFileSync(AGENTS, "utf-8"), A_BEGIN, A_END));
112
180
  done.push("AGENTS.md: removed claw-memory block");
113
181
  }
182
+ if (removeHooks()) {
183
+ done.push("hooks.json: removed claw-memory hooks");
184
+ }
114
185
  try {
115
186
  rmSync(SKILL_DIR, { recursive: true, force: true });
116
187
  done.push("skill: removed");
@@ -0,0 +1,37 @@
1
+ {
2
+ "hooks": {
3
+ "SessionStart": [
4
+ {
5
+ "hooks": [
6
+ {
7
+ "type": "command",
8
+ "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd\" claw-hook.sh hook recall",
9
+ "async": false
10
+ }
11
+ ]
12
+ }
13
+ ],
14
+ "UserPromptSubmit": [
15
+ {
16
+ "hooks": [
17
+ {
18
+ "type": "command",
19
+ "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd\" claw-hook.sh hook recall",
20
+ "async": false
21
+ }
22
+ ]
23
+ }
24
+ ],
25
+ "Stop": [
26
+ {
27
+ "hooks": [
28
+ {
29
+ "type": "command",
30
+ "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd\" claw-hook.sh distill-codex --limit 5",
31
+ "async": true
32
+ }
33
+ ]
34
+ }
35
+ ]
36
+ }
37
+ }
package/hooks/hooks.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "hooks": [
6
6
  {
7
7
  "type": "command",
8
- "command": "'${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd' claw-hook.sh hook recall",
8
+ "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd\" claw-hook.sh hook recall",
9
9
  "async": false
10
10
  }
11
11
  ]
@@ -16,7 +16,7 @@
16
16
  "hooks": [
17
17
  {
18
18
  "type": "command",
19
- "command": "'${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd' claw-hook.sh hook recall",
19
+ "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd\" claw-hook.sh hook recall",
20
20
  "async": false
21
21
  }
22
22
  ]
@@ -27,7 +27,7 @@
27
27
  "hooks": [
28
28
  {
29
29
  "type": "command",
30
- "command": "'${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd' claw-hook.sh hook distill",
30
+ "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd\" claw-hook.sh hook distill",
31
31
  "async": true
32
32
  }
33
33
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nogataka/claw-memory",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "description": "Independent, in-process semantic memory MCP server (sqlite-vec + local Xenova e5) with a lightweight web viewer. No daemon, no Python. Installable as a Claude Code plugin and a Codex MCP server.",
6
6
  "license": "MIT",
@@ -26,8 +26,10 @@
26
26
  "hooks",
27
27
  "skills",
28
28
  ".claude-plugin",
29
+ ".codex-plugin",
29
30
  ".mcp.json",
30
- "README.md"
31
+ "README.md",
32
+ "README.ja.md"
31
33
  ],
32
34
  "engines": {
33
35
  "node": ">=20.0.0"