@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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +16 -0
- package/README.ja.md +310 -0
- package/README.md +246 -99
- package/dist/cli.js +1 -1
- package/dist/core/installer/codex.js +76 -5
- package/hooks/hooks.codex.json +37 -0
- package/hooks/hooks.json +3 -3
- package/package.json +4 -2
|
@@ -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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
4
|
-
No daemon, no Python, no external vector DB.
|
|
3
|
+
**English** | [日本語](README.ja.md)
|
|
5
4
|
|
|
6
|
-
|
|
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
|
-
- **
|
|
9
|
-
|
|
10
|
-
- **
|
|
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
|
-
|
|
13
|
-
separate from any other app.
|
|
104
|
+
---
|
|
14
105
|
|
|
15
|
-
##
|
|
106
|
+
## Installation guide
|
|
16
107
|
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
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
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
135
|
+
No manual config. To verify, run `/mcp` and look for `claw-memory`.
|
|
39
136
|
|
|
40
|
-
|
|
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
|
|
44
|
-
# + memory-recall skill + AGENTS.md recall instruction
|
|
163
|
+
claw-memory install --codex
|
|
45
164
|
```
|
|
46
165
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
(
|
|
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
|
-
|
|
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
|
|
63
|
-
npm run build
|
|
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-
|
|
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
|
|
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
|
|
77
|
-
| `memory_forget(ids)` | Soft-delete chunks (hidden from search/recall/viewer) |
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
`~/.claude/projects` and `~/.codex/sessions` directly.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
|
89
|
-
| `codex-sdk` | Codex CLI login (ChatGPT/Codex plan) | `@openai/codex-sdk
|
|
90
|
-
| `anthropic` | `ANTHROPIC_API_KEY`
|
|
91
|
-
| `openai-compatible` | `CLAW_MEMORY_OPENAI_API_KEY` + `
|
|
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
|
|
237
|
+
export CLAW_MEMORY_LLM_BACKEND=codex-sdk # distill using the Codex subscription
|
|
95
238
|
```
|
|
96
239
|
|
|
97
|
-
|
|
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
|
-
|
|
242
|
+
## CLI reference
|
|
104
243
|
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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
|
-
|
|
142
|
-
|
|
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
|
-
|
|
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
|
|
153
|
-
|
|
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
|
-
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## Uninstall
|
|
156
297
|
|
|
157
298
|
```bash
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
33
|
-
|
|
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
|
-
|
|
66
|
+
return {};
|
|
37
67
|
}
|
|
38
|
-
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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.
|
|
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"
|