@hir4ta/memoria 0.11.1 → 0.11.3

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.
@@ -1,18 +1,12 @@
1
1
  {
2
2
  "name": "memoria",
3
3
  "description": "A plugin that provides long-term memory for Claude Code. It automatically saves context lost during auto-compact, offering features for session restoration, recording technical decisions, and learning developer patterns.",
4
- "version": "0.11.1",
4
+ "version": "0.11.3",
5
5
  "author": {
6
6
  "name": "hir4ta"
7
7
  },
8
8
  "homepage": "https://github.com/hir4ta/memoria",
9
9
  "repository": "https://github.com/hir4ta/memoria",
10
10
  "license": "MIT",
11
- "keywords": [
12
- "memory",
13
- "sessions",
14
- "decisions",
15
- "patterns",
16
- "dashboard"
17
- ]
18
- }
11
+ "keywords": ["memory", "sessions", "decisions", "patterns", "dashboard"]
12
+ }
package/README.ja.md CHANGED
@@ -2,13 +2,12 @@
2
2
 
3
3
  Claude Codeの長期記憶を実現するプラグイン
4
4
 
5
- セッションのリアルタイム保存、技術的な判断の記録、Webダッシュボードでの管理を提供します。
5
+ セッションの自動保存、技術的な判断の記録、Webダッシュボードでの管理を提供します。
6
6
 
7
7
  ## 機能
8
8
 
9
9
  ### コア機能
10
- - **明示的セッション保存**: `/memoria:save` または「セッション保存して」で保存
11
- - **APIフォールバック**: Auto-Compact前とセッション終了時にOpenAI APIで自動保存
10
+ - **自動保存**: Claudeの返信ごとにセッションを自動保存(設定不要)
12
11
  - **セッション再開**: `/memoria:resume` で過去のセッションを再開
13
12
  - **技術的な判断の記録**: `/memoria:decision` で判断を記録
14
13
  - **ルールベースレビュー**: `dev-rules.json` / `review-guidelines.json` に基づくレビュー
@@ -96,47 +95,23 @@ Claude Codeを再起動
96
95
 
97
96
  これによりClaude Code起動時に自動でアップデートされます
98
97
 
99
- ## 設定(オプション)
100
-
101
- APIフォールバックによる自動セッション保存を有効にするには、`/memoria:init` を実行するか、手動で `~/.claude/memoria.json` を作成してください:
102
-
103
- ```json
104
- {
105
- "openai_api_key": "sk-...",
106
- "model": "gpt-5-mini"
107
- }
108
- ```
109
-
110
- | フィールド | 必須 | デフォルト | 説明 |
111
- |-----------|------|-----------|------|
112
- | `openai_api_key` | いいえ | - | 設定すると自動保存が有効になる |
113
- | `model` | いいえ | `gpt-5-mini` | 使用するモデル(gpt-5-mini, gpt-5, gpt-5.2など) |
114
-
115
- **`openai_api_key` なし**: `/memoria:save` での手動保存のみ。
116
-
117
- **`openai_api_key` あり**: 自動保存が有効になり、以下のタイミングで保存:
118
- - Auto-Compact前(status: `draft`)
119
- - セッション終了時(status: `complete`)
120
-
121
98
  ## 使い方
122
99
 
123
- ### セッション保存
100
+ ### セッション自動保存
124
101
 
125
- | 方法 | タイミング | ステータス |
126
- |------|----------|-----------|
127
- | **明示的保存** | `/memoria:save` または「セッション保存して」 | `complete` |
128
- | **PreCompact** | Auto-Compact前(API) | `draft` |
129
- | **SessionEnd** | セッション終了時(API) | `complete` |
102
+ セッションは**Claudeの返信ごとに自動保存**されます。設定不要。
130
103
 
131
- **注意**: PreCompact/SessionEnd のAPIフォールバックには `~/.claude/memoria.json` の設定が必要です。
104
+ 各返信時に以下が更新されます:
105
+ - `interactions`: チャット形式の会話ログ
106
+ - `summary`: タイトル、目的、結果、説明
107
+ - `metrics`: ファイル数、決定数、エラー数
132
108
 
133
109
  ### コマンド
134
110
 
135
111
  | コマンド | 説明 |
136
112
  | --------- | ------ |
137
- | `/memoria:init` | 設定ファイルを初期化(`~/.claude/memoria.json`) |
138
113
  | `/memoria:resume [id]` | セッションを再開(ID省略で一覧表示) |
139
- | `/memoria:save` | セッション保存 + 会話からルール抽出 |
114
+ | `/memoria:save` | ルール抽出 + 手動更新 |
140
115
  | `/memoria:decision "タイトル"` | 技術的な判断を記録 |
141
116
  | `/memoria:search "クエリ"` | セッション・判断記録を検索 |
142
117
  | `/memoria:review [--staged\|--all\|--diff=branch\|--full]` | ルールに基づくレビュー(--fullで二段階) |
@@ -183,46 +158,47 @@ npx @hir4ta/memoria --dashboard --port 8080
183
158
 
184
159
  ```mermaid
185
160
  flowchart TB
186
- subgraph realtime [リアルタイム更新]
187
- A[意味のある変化] --> B[セッションJSONを更新]
188
- B --> C[interactions配列]
161
+ subgraph autosave [自動保存]
162
+ A[Claudeの返信] --> B[Stopフック]
163
+ B --> C[セッションJSON更新]
164
+ C --> D[interactions + summary + metrics]
189
165
  end
190
166
 
191
167
  subgraph manual [手動操作]
192
- D["memoria:save"] --> E[セッションを強制保存]
193
- F["memoria:decision"] --> G[判断を明示的に記録]
168
+ E["memoria:save"] --> F[ルール抽出 + 強制更新]
169
+ G["memoria:decision"] --> H[判断を明示的に記録]
194
170
  end
195
171
 
196
172
  subgraph resume [セッション再開]
197
- H["memoria:resume"] --> I[一覧から選択]
198
- I --> J[過去の文脈を復元]
173
+ I["memoria:resume"] --> J[一覧から選択]
174
+ J --> K[過去の文脈を復元]
199
175
  end
200
176
 
201
177
  subgraph search [検索]
202
- K["memoria:search"] --> L[セッションと判断を検索]
178
+ L["memoria:search"] --> M[セッションと判断を検索]
203
179
  end
204
180
 
205
181
  subgraph review [レビュー]
206
- P["memoria:review"] --> Q[ルールに基づく指摘]
207
- Q --> R[レビュー結果を保存]
182
+ N["memoria:review"] --> O[ルールに基づく指摘]
183
+ O --> P[レビュー結果を保存]
208
184
  end
209
185
 
210
186
  subgraph report [週次レポート]
211
- S["memoria:report"] --> T[レビュー集計レポート]
187
+ Q["memoria:report"] --> R[レビュー集計レポート]
212
188
  end
213
189
 
214
190
  subgraph dashboard [ダッシュボード]
215
- M["npx @hir4ta/memoria -d"] --> N[ブラウザで表示]
216
- N --> O[閲覧・編集・削除]
191
+ S["npx @hir4ta/memoria -d"] --> T[ブラウザで表示]
192
+ T --> U[閲覧・編集・削除]
217
193
  end
218
194
 
219
- B --> H
220
- E --> H
221
- G --> K
222
- B --> R
223
- R --> T
224
- B --> M
225
- G --> M
195
+ D --> I
196
+ F --> I
197
+ H --> L
198
+ D --> P
199
+ P --> R
200
+ D --> S
201
+ H --> S
226
202
  ```
227
203
 
228
204
  ## データ保存
@@ -243,8 +219,6 @@ Gitでバージョン管理可能です。`.gitignore` に追加するかはプ
243
219
 
244
220
  ### セッションJSONスキーマ
245
221
 
246
- セッションは **分析向け** のスキーマを使用します。定量データ(metrics)と定性データ(summary)を分離し、files/decisions/errorsを独立配列として集計可能にしています。
247
-
248
222
  ```json
249
223
  {
250
224
  "id": "abc12345",
@@ -262,8 +236,15 @@ Gitでバージョン管理可能です。`.gitignore` に追加するかはプ
262
236
  "outcome": "success",
263
237
  "description": "RS256署名でJWT認証を実装"
264
238
  },
239
+ "interactions": [
240
+ {
241
+ "timestamp": "2026-01-27T10:15:00Z",
242
+ "user": "認証機能を実装して",
243
+ "assistant": "RS256署名でJWT認証を実装しました",
244
+ "toolsUsed": ["Read", "Edit", "Write"]
245
+ }
246
+ ],
265
247
  "metrics": {
266
- "durationMinutes": 120,
267
248
  "filesCreated": 2,
268
249
  "filesModified": 1,
269
250
  "decisionsCount": 2,
@@ -299,21 +280,6 @@ Gitでバージョン管理可能です。`.gitignore` に追加するかはプ
299
280
  }
300
281
  ```
301
282
 
302
- ### 更新トリガー
303
-
304
- Claude Code は意味のある変化があった時にセッションJSONを更新します:
305
-
306
- | トリガー | 更新内容 |
307
- |---------|---------|
308
- | セッションの目的が明確になった | `summary.title`, `summary.goal`, `sessionType` |
309
- | ファイルを変更した | `files` に追加、`metrics` 更新 |
310
- | 技術的決定を下した | `decisions` に追加 |
311
- | エラーに遭遇・解決した | `errors` に追加 |
312
- | URLを参照した | `webLinks` |
313
- | 新しいキーワードが出現 | `tags`(tags.jsonを参照) |
314
-
315
- **注意**: 明示的に `/memoria:save` を実行するか、APIフォールバックが発動するまでセッションは保存されません。
316
-
317
283
  ### セッションタイプ
318
284
 
319
285
  `sessionType` フィールドはセッションの種類を分類します。
package/README.md CHANGED
@@ -2,13 +2,12 @@
2
2
 
3
3
  Long-term memory plugin for Claude Code
4
4
 
5
- Provides explicit session saving with API fallback, technical decision recording, and web dashboard management.
5
+ Provides automatic session saving, technical decision recording, and web dashboard management.
6
6
 
7
7
  ## Features
8
8
 
9
9
  ### Core Features
10
- - **Explicit Session Saving**: Save with `/memoria:save` or "save session" request
11
- - **API Fallback**: Auto-save via OpenAI API before Auto-Compact and at session end
10
+ - **Auto-save**: Sessions saved automatically on every Claude response (no configuration needed)
12
11
  - **Session Resume**: Resume past sessions with `/memoria:resume`
13
12
  - **Technical Decision Recording**: Record decisions with `/memoria:decision`
14
13
  - **Rule-based Review**: Code review based on `dev-rules.json` / `review-guidelines.json`
@@ -96,47 +95,23 @@ Restart Claude Code.
96
95
 
97
96
  This will auto-update on Claude Code startup.
98
97
 
99
- ## Configuration (Optional)
100
-
101
- To enable API fallback for automatic session saving, run `/memoria:init` or manually create `~/.claude/memoria.json`:
102
-
103
- ```json
104
- {
105
- "openai_api_key": "sk-...",
106
- "model": "gpt-5-mini"
107
- }
108
- ```
109
-
110
- | Field | Required | Default | Description |
111
- |-------|----------|---------|-------------|
112
- | `openai_api_key` | No | - | Enables auto-save at PreCompact/SessionEnd |
113
- | `model` | No | `gpt-5-mini` | Model to use (gpt-5-mini, gpt-5, gpt-5.2, etc.) |
114
-
115
- **Without `openai_api_key`**: Sessions are only saved when you explicitly use `/memoria:save`.
116
-
117
- **With `openai_api_key`**: Auto-save is enabled. Sessions are automatically saved:
118
- - Before Auto-Compact (status: `draft`)
119
- - At session end (status: `complete`)
120
-
121
98
  ## Usage
122
99
 
123
- ### Session Saving
100
+ ### Session Auto-Save
124
101
 
125
- | Method | When | Status |
126
- |--------|------|--------|
127
- | **Explicit** | `/memoria:save` or "save session" | `complete` |
128
- | **PreCompact** | Before Auto-Compact (API) | `draft` |
129
- | **SessionEnd** | Session end (API) | `complete` |
102
+ Sessions are saved **automatically on every Claude response**. No configuration needed.
130
103
 
131
- **Note**: PreCompact/SessionEnd API fallback requires `~/.claude/memoria.json` configuration.
104
+ On each response, Claude updates:
105
+ - `interactions`: Chat-style conversation log
106
+ - `summary`: Title, goal, outcome, description
107
+ - `metrics`: File counts, decision counts, error counts
132
108
 
133
109
  ### Commands
134
110
 
135
111
  | Command | Description |
136
112
  |---------|-------------|
137
- | `/memoria:init` | Initialize config file (`~/.claude/memoria.json`) |
138
113
  | `/memoria:resume [id]` | Resume session (show list if ID omitted) |
139
- | `/memoria:save` | Save session + extract rules from conversation |
114
+ | `/memoria:save` | Extract rules from conversation + manual update |
140
115
  | `/memoria:decision "title"` | Record a technical decision |
141
116
  | `/memoria:search "query"` | Search sessions and decisions |
142
117
  | `/memoria:review [--staged\|--all\|--diff=branch\|--full]` | Rule-based code review (--full for two-stage) |
@@ -183,46 +158,47 @@ npx @hir4ta/memoria --dashboard --port 8080
183
158
 
184
159
  ```mermaid
185
160
  flowchart TB
186
- subgraph realtime [Real-time Updates]
187
- A[Meaningful Change] --> B[Update Session JSON]
188
- B --> C[interactions array]
161
+ subgraph autosave [Auto-Save]
162
+ A[Claude Response] --> B[Stop Hook]
163
+ B --> C[Update Session JSON]
164
+ C --> D[interactions + summary + metrics]
189
165
  end
190
166
 
191
167
  subgraph manual [Manual Actions]
192
- D["memoria:save"] --> E[Force flush session]
193
- F["memoria:decision"] --> G[Record decision explicitly]
168
+ E["memoria:save"] --> F[Extract rules + force update]
169
+ G["memoria:decision"] --> H[Record decision explicitly]
194
170
  end
195
171
 
196
172
  subgraph resume [Session Resume]
197
- H["memoria:resume"] --> I[Select from list]
198
- I --> J[Restore past context]
173
+ I["memoria:resume"] --> J[Select from list]
174
+ J --> K[Restore past context]
199
175
  end
200
176
 
201
177
  subgraph search [Search]
202
- K["memoria:search"] --> L[Search sessions and decisions]
178
+ L["memoria:search"] --> M[Search sessions and decisions]
203
179
  end
204
180
 
205
181
  subgraph review [Review]
206
- P["memoria:review"] --> Q[Rule-based findings]
207
- Q --> R[Save review results]
182
+ N["memoria:review"] --> O[Rule-based findings]
183
+ O --> P[Save review results]
208
184
  end
209
185
 
210
186
  subgraph report [Weekly Report]
211
- S["memoria:report"] --> T[Review summary report]
187
+ Q["memoria:report"] --> R[Review summary report]
212
188
  end
213
189
 
214
190
  subgraph dashboard [Dashboard]
215
- M["npx @hir4ta/memoria -d"] --> N[Open in browser]
216
- N --> O[View, edit, delete]
191
+ S["npx @hir4ta/memoria -d"] --> T[Open in browser]
192
+ T --> U[View, edit, delete]
217
193
  end
218
194
 
219
- B --> H
220
- E --> H
221
- G --> K
222
- B --> R
223
- R --> T
224
- B --> M
225
- G --> M
195
+ D --> I
196
+ F --> I
197
+ H --> L
198
+ D --> P
199
+ P --> R
200
+ D --> S
201
+ H --> S
226
202
  ```
227
203
 
228
204
  ## Data Storage
@@ -243,8 +219,6 @@ Git-manageable. Add to `.gitignore` based on your project needs.
243
219
 
244
220
  ### Session JSON Schema
245
221
 
246
- Sessions use an **analysis-friendly** schema. Quantitative data (metrics) and qualitative data (summary) are separated, with files/decisions/errors as independent arrays for easy aggregation.
247
-
248
222
  ```json
249
223
  {
250
224
  "id": "abc12345",
@@ -262,8 +236,15 @@ Sessions use an **analysis-friendly** schema. Quantitative data (metrics) and qu
262
236
  "outcome": "success",
263
237
  "description": "Implemented JWT auth with RS256 signing"
264
238
  },
239
+ "interactions": [
240
+ {
241
+ "timestamp": "2026-01-27T10:15:00Z",
242
+ "user": "Implement authentication",
243
+ "assistant": "Implemented JWT auth with RS256 signing",
244
+ "toolsUsed": ["Read", "Edit", "Write"]
245
+ }
246
+ ],
265
247
  "metrics": {
266
- "durationMinutes": 120,
267
248
  "filesCreated": 2,
268
249
  "filesModified": 1,
269
250
  "decisionsCount": 2,
@@ -299,19 +280,6 @@ Sessions use an **analysis-friendly** schema. Quantitative data (metrics) and qu
299
280
  }
300
281
  ```
301
282
 
302
- ### Update Triggers
303
-
304
- Claude Code updates session JSON when meaningful changes occur:
305
-
306
- | Trigger | Update |
307
- |---------|--------|
308
- | Session purpose becomes clear | `summary.title`, `summary.goal`, `sessionType` |
309
- | File modified | Add to `files`, update `metrics` |
310
- | Technical decision made | Add to `decisions` |
311
- | Error encountered/resolved | Add to `errors` |
312
- | URL referenced | `webLinks` |
313
- | New keyword appears | `tags` (reference tags.json) |
314
-
315
283
  ### Session Types
316
284
 
317
285
  The `sessionType` field classifies the session type.
@@ -195,7 +195,7 @@ if (isMain && process.argv.length > 2) {
195
195
  const args = process.argv.slice(2);
196
196
  const queryIndex = args.indexOf("--query");
197
197
  const query = queryIndex !== -1 ? args[queryIndex + 1] : "";
198
- const memoriaDir = process.cwd() + "/.memoria";
198
+ const memoriaDir = `${process.cwd()}/.memoria`;
199
199
  if (!query) {
200
200
  console.error(JSON.stringify({ success: false, error: "Missing --query" }));
201
201
  process.exit(0);
@@ -88,11 +88,7 @@ function aggregateReviewFindings(reviews, minOccurrences = 3) {
88
88
  }
89
89
  async function learnPatterns(memoriaDir, options = {}) {
90
90
  const patterns = [];
91
- const {
92
- analyzeCommits = true,
93
- analyzeReviews = true,
94
- analyzeCoChanges = true
95
- } = options;
91
+ const { analyzeReviews = true } = options;
96
92
  if (analyzeReviews) {
97
93
  const reviewsDir = path2.join(memoriaDir, "reviews");
98
94
  const reviewFiles = findJsonFiles(reviewsDir);
@@ -120,7 +116,7 @@ async function learnPatterns(memoriaDir, options = {}) {
120
116
  var isMain = process.argv[1]?.endsWith("pattern-learner.js") || process.argv[1]?.endsWith("pattern-learner.ts");
121
117
  if (isMain && process.argv.length > 2) {
122
118
  const args = process.argv.slice(2);
123
- const memoriaDir = process.cwd() + "/.memoria";
119
+ const memoriaDir = `${process.cwd()}/.memoria`;
124
120
  learnPatterns(memoriaDir, {
125
121
  analyzeCommits: args.includes("--analyze-commits"),
126
122
  analyzeReviews: args.includes("--analyze-reviews"),
@@ -87,7 +87,7 @@ async function buildContinueContext(memoriaDir, tasksPath) {
87
87
  }
88
88
  var isMain = process.argv[1]?.endsWith("session-continuity.js") || process.argv[1]?.endsWith("session-continuity.ts");
89
89
  if (isMain && process.argv.length > 2) {
90
- const memoriaDir = process.cwd() + "/.memoria";
90
+ const memoriaDir = `${process.cwd()}/.memoria`;
91
91
  buildContinueContext(memoriaDir).then((context) => {
92
92
  console.log(JSON.stringify({ success: true, context }));
93
93
  }).catch((error) => {
package/dist/lib/utils.js CHANGED
@@ -9,6 +9,20 @@ function safeReadJson(filePath, fallback) {
9
9
  return fallback;
10
10
  }
11
11
  }
12
+ function safeReadJsonWithSchema(filePath, schema, fallback) {
13
+ try {
14
+ const content = fs.readFileSync(filePath, "utf-8");
15
+ const data = JSON.parse(content);
16
+ const result = schema.safeParse(data);
17
+ if (result.success) {
18
+ return result.data;
19
+ }
20
+ console.warn(`Validation failed for ${filePath}: ${result.error.message}`);
21
+ return fallback;
22
+ } catch {
23
+ return fallback;
24
+ }
25
+ }
12
26
  function safeWriteJson(filePath, data) {
13
27
  const dir = path.dirname(filePath);
14
28
  if (!fs.existsSync(dir)) {
@@ -43,5 +57,6 @@ export {
43
57
  findJsonFiles,
44
58
  nowISO,
45
59
  safeReadJson,
60
+ safeReadJsonWithSchema,
46
61
  safeWriteJson
47
62
  };