@tznthou/ccrecall 0.4.8 → 0.5.1

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.
Files changed (49) hide show
  1. package/README.md +28 -52
  2. package/README_ZH.md +28 -53
  3. package/dist/api/routes.d.ts +0 -10
  4. package/dist/api/routes.d.ts.map +1 -1
  5. package/dist/api/routes.js +4 -354
  6. package/dist/api/routes.js.map +1 -1
  7. package/dist/api/server.js +3 -3
  8. package/dist/api/server.js.map +1 -1
  9. package/dist/core/database.d.ts +14 -49
  10. package/dist/core/database.d.ts.map +1 -1
  11. package/dist/core/database.js +104 -225
  12. package/dist/core/database.js.map +1 -1
  13. package/dist/core/indexer.d.ts.map +1 -1
  14. package/dist/core/indexer.js +0 -1
  15. package/dist/core/indexer.js.map +1 -1
  16. package/dist/core/maintenance-coordinator.d.ts +3 -9
  17. package/dist/core/maintenance-coordinator.d.ts.map +1 -1
  18. package/dist/core/maintenance-coordinator.js +4 -24
  19. package/dist/core/maintenance-coordinator.js.map +1 -1
  20. package/dist/core/summarizer.d.ts.map +1 -1
  21. package/dist/core/summarizer.js +0 -22
  22. package/dist/core/summarizer.js.map +1 -1
  23. package/dist/core/types.d.ts +0 -87
  24. package/dist/core/types.d.ts.map +1 -1
  25. package/dist/core/types.js.map +1 -1
  26. package/dist/index.js +0 -16
  27. package/dist/index.js.map +1 -1
  28. package/hooks/README.md +2 -2
  29. package/package.json +2 -1
  30. package/scripts/backfill-memory-topics.ts +29 -0
  31. package/scripts/extraction-prompt.md +96 -0
  32. package/scripts/post-session-extract.sh +290 -0
  33. package/scripts/recall-hit-rate-report.ts +91 -0
  34. package/dist/cli/journal.d.ts +0 -11
  35. package/dist/cli/journal.d.ts.map +0 -1
  36. package/dist/cli/journal.js +0 -111
  37. package/dist/cli/journal.js.map +0 -1
  38. package/dist/core/lint.d.ts +0 -17
  39. package/dist/core/lint.d.ts.map +0 -1
  40. package/dist/core/lint.js +0 -51
  41. package/dist/core/lint.js.map +0 -1
  42. package/dist/core/outcome-extractor.d.ts +0 -6
  43. package/dist/core/outcome-extractor.d.ts.map +0 -1
  44. package/dist/core/outcome-extractor.js +0 -39
  45. package/dist/core/outcome-extractor.js.map +0 -1
  46. package/dist/core/outcome-scorer.d.ts +0 -8
  47. package/dist/core/outcome-scorer.d.ts.map +0 -1
  48. package/dist/core/outcome-scorer.js +0 -103
  49. package/dist/core/outcome-scorer.js.map +0 -1
package/README.md CHANGED
@@ -11,13 +11,9 @@ A local memory service for Claude Code — indexes your conversation history, re
11
11
 
12
12
  ---
13
13
 
14
- > 📐 **v0.3.0 — Trust split (breaking change for harvest write path)**
14
+ > 📐 **v0.5.0 — The knife-field release: one pipeline, nothing dead**
15
15
  >
16
- > The SessionEnd hook now writes to a low-trust `session_journal` table instead of `memories`. Journal entries are scored, surfaced via `/health` (`journalPendingCount`), and **do not appear in `recall_query` / `recall_context` results** until you run `ccmem promote <id>`. Manual `recall_save` is unchanged — it still writes directly to high-trust `memories`.
17
- >
18
- > The rule scorer is no longer on the persistence gate; it informs trust grade and promotion priority instead. Background reasoning at [issue #21](https://github.com/tznthou/ccRecall/issues/21).
19
- >
20
- > Pre-0.3.0 memories stay queryable as-is. The v22 schema migration runs automatically on first daemon startup; existing rows are not touched. New harvest goes to journal from now on.
16
+ > Post-session extraction via Haiku (~$0.001/session) has been the primary memory write path since v0.4.1, hardened across v0.4.2–v0.4.8. v0.5.0 removes everything that pipeline made obsolete — the journal review queue (zero promotions in its entire history), the rule scorer, checkpoints, and 8 caller-less HTTP endpoints — and rebuilds the replay-dedup registry as compact 64-bit hashes (database: 114MB → 42MB measured). Manual `recall_save` remains available for in-session saves.
21
17
 
22
18
  ---
23
19
 
@@ -41,9 +37,8 @@ ccRecall is the "memory" counterpart to [ccRewind](https://github.com/tznthou/cc
41
37
  | **FTS5 full-text search** | Sub-100ms keyword search across all conversation history, fast enough for hook injection |
42
38
  | **CJK / mixed-script search** | Trigram tokenizer indexes Chinese / Japanese / Korean text; per-token AND LIKE fallback handles short queries like `UI 記憶` that trigram alone can't match |
43
39
  | **Incremental indexing** | Only re-indexes sessions that changed (mtime diffing), handles resumed sessions via UUID dedup |
44
- | **Metacognition** | `knowledge_map` aggregates topic mentions from sessions + memories. Depth derived from mention count (shallow / medium / deep). Exposed via `/metacognition/check` and MCP `recall_context` |
40
+ | **Metacognition** | `knowledge_map` aggregates topic mentions from sessions + memories. Depth derived from mention count (shallow / medium / deep). Exposed via MCP `recall_context` |
45
41
  | **Forgetting curve** | Memories compress over time: raw → summary → one-liner → deleted. Confidence decays on unused memories. Background maintenance tick runs every 5 min |
46
- | **Trust two-tier** (v0.3.0) | Hooks write to a low-trust `session_journal` (reviewable, never recalled directly); manual `recall_save` writes high-trust `memories`. Promote candidates with `ccmem promote <id>`; rejected entries auto-clear after 7 days |
47
42
  | **Cross-project memory** (v0.4.1) | Memories surface across projects via topic intersection — if two projects share a `knowledge_map` topic, high-confidence memories from one appear in the other's startup injection (max 3 rows, confidence ≥ 0.8 gate) |
48
43
  | **Watch mode** | chokidar-based JSONL watcher picks up new sessions within 2 s; periodic 10 min full-resync covers missed filesystem events |
49
44
  | **Rescue reindex** | `/session/end` and `/session/last` both retry a reindex on miss, and `/session/last` staleness-gates via `notBefore` — no fresh-session race between the hook, the wrapper, and the daemon |
@@ -66,7 +61,7 @@ flowchart TB
66
61
  Parser["Parser<br/>parse conversations"]
67
62
  Summarizer["Summarizer<br/>rule-based extraction"]
68
63
  DB[("SQLite + FTS5<br/>index & search")]
69
- API["HTTP API<br/>13 endpoints"]
64
+ API["HTTP API<br/>5 endpoints"]
70
65
  end
71
66
 
72
67
  subgraph Consumers["Consumers"]
@@ -77,7 +72,7 @@ flowchart TB
77
72
 
78
73
  JSONL --> Watcher --> Scanner --> Parser --> Summarizer --> DB
79
74
  DB <--> API
80
- Hook -->|"inject / journal"| API
75
+ Hook -->|"inject / end-confirm"| API
81
76
  Wrapper -->|"GET /session/last"| API
82
77
  MCP <-->|"shared SQLite via WAL"| DB
83
78
  ```
@@ -109,7 +104,7 @@ sequenceDiagram
109
104
  rect rgb(255, 244, 235)
110
105
  Note over CC,X: Session end
111
106
  CC->>H: SessionEnd
112
- H->>R: POST /session/end (low-trust journal)
107
+ H->>R: POST /session/end (index confirm + rescue)
113
108
  W->>R: GET /session/last?notBefore=launch_ts
114
109
  R-->>W: sessionId (staleness-gated, subagent-filtered)
115
110
  W->>X: text-only transcript
@@ -130,7 +125,7 @@ The `notBefore` gate keeps a stale session from being extracted twice; the subag
130
125
  | FTS5 | Full-text search | Built into SQLite, trigram tokenizer with LIKE fallback for short CJK / mixed-script queries |
131
126
  | Native `http` | HTTP server | No Express — minimal surface, localhost only |
132
127
  | chokidar | Filesystem watcher | Cross-platform JSONL change detection with 2 s debounce + single-flight |
133
- | vitest | Testing | 629 tests across 39 files, integration-style |
128
+ | vitest | Testing | 524 tests across 34 files, integration-style |
134
129
  | `@modelcontextprotocol/sdk` | MCP server | stdio transport, shared SQLite via WAL |
135
130
 
136
131
  ---
@@ -172,20 +167,17 @@ curl "http://127.0.0.1:7749/memory/query?q=authentication&limit=5"
172
167
 
173
168
  ## API Endpoints
174
169
 
175
- | Endpoint | Method | Description | Status |
170
+ Five endpoints, each with a live caller — v0.5.0 removed the other eight
171
+ (`/journal/*`, `/memory/save`, `/memory/context`, `/metacognition/check`,
172
+ `/session/checkpoint`, `/lint/warnings`); they now return 404.
173
+
174
+ | Endpoint | Method | Description | Caller |
176
175
  |----------|--------|-------------|--------|
177
- | `/health` | GET | Service health + DB stats + integrity check status + `journalPendingCount` (since v0.3.0) | Live |
178
- | `/memory/query?q=...&limit=...&project=...` | GET | FTS5 search across memories with optional project filter (journal entries excluded by design) | Live |
179
- | `/memory/save` | POST | Save a memory entry (origin-checked) | Live |
180
- | `/session/end` | POST | Harvest a finished session into `session_journal` (idempotent; was `memories` pre-0.3.0) | Live |
181
- | `/journal/pending` | GET | List journal entries awaiting promotion review | Live (v0.3.0) |
182
- | `/journal/promote` | POST | Atomically promote a journal entry into `memories` | Live (v0.3.0) |
183
- | `/journal/reject` | POST | Soft-delete a journal entry (cleared after 7-day TTL by decay sweep) | Live (v0.3.0) |
184
- | `/memory/context?session_id=...` | GET | Session context lookup | Stub |
185
- | `/metacognition/check?projectId=...[&topic=...]` | GET | Knowledge map: summary (top/recent/stale topics + counts) or topic detail (memories + related topics) | Live |
186
- | `/session/checkpoint` | POST | Mid-session snapshot into dedicated `session_checkpoints` table (not harvested as memory) | Live |
187
- | `/lint/warnings` | GET | Lint report: orphan (session deleted) + stale (low-confidence, long-idle) memory warnings | Live |
188
- | `/session/last?cwd=...` | GET | Most recent session metadata for a project path (used by post-session extraction wrapper) | Live (v0.4.1) |
176
+ | `/health` | GET | Service health + DB stats + integrity check status | CLI, extraction wrapper |
177
+ | `/memory/startup?project=...` | GET | SessionStart-tier retrieval: cold + recent-confidence + FTS fallback, token-budgeted | SessionStart hook |
178
+ | `/memory/query?q=...&limit=...&project=...` | GET | FTS5 search across memories with optional project filter | SessionStart hook (keyword tier) |
179
+ | `/session/end` | POST | Confirm the just-ended session is indexed (rescue reindex on miss) | SessionEnd hook |
180
+ | `/session/last?cwd=...` | GET | Most recent session metadata for a project path (staleness-gated via `notBefore`) | Extraction wrapper |
189
181
 
190
182
  ## MCP Tools
191
183
 
@@ -237,21 +229,10 @@ Daemon and hook lifecycle (macOS):
237
229
  | `ccmem uninstall-daemon` | Stop and remove the LaunchAgent |
238
230
  | `ccmem install-hooks` | Merge SessionStart / SessionEnd entries into `~/.claude/settings.json` |
239
231
  | `ccmem uninstall-hooks` | Remove ccRecall's hook entries (other hooks untouched) |
232
+ | `ccmem cleanup --orphans` | List (and with `--yes`, delete) memories whose session rows are gone |
240
233
 
241
- Journal review (since v0.3.0):
242
-
243
- | Command | Purpose |
244
- |---------|---------|
245
- | `ccmem promote <id>` | Promote a journal entry into `memories`. Optional `--type` (default `discovery`) and `--confidence` (default `0.7`) |
246
- | `ccmem reject <id>` | Soft-delete a journal entry; cleaned up after the 7-day TTL by the decay sweep |
247
-
248
- Surface pending candidates:
249
-
250
- ```bash
251
- curl http://127.0.0.1:7749/journal/pending
252
- # or just check the count
253
- curl http://127.0.0.1:7749/health | jq .journalPendingCount
254
- ```
234
+ `ccmem promote` / `ccmem reject` were removed in v0.5.0 along with the
235
+ journal pipeline they reviewed.
255
236
 
256
237
  ---
257
238
 
@@ -272,8 +253,6 @@ ccRecall lives alongside Claude Code's built-in auto memory (`~/.claude/projects
272
253
 
273
254
  ccRecall's value is the long tail that auto memory can't cover (nobody hand-curates 500 sessions of notes). If Claude defaults to both, auto memory wins because it's already loaded and curated. ccRecall earns its keep when the curated index misses.
274
255
 
275
- **Within ccRecall there's now a second trust split** (since v0.3.0). The SessionEnd hook writes to a low-trust `session_journal` table that `recall_query` does **not** read. Promote a candidate to high-trust `memories` with `ccmem promote <id>` to make it queryable. Manual `recall_save` skips the journal entirely — it writes straight to memories. The point is to let the harvester record broadly while keeping recall results clean.
276
-
277
256
  ---
278
257
 
279
258
  ## Running as a service (macOS)
@@ -305,7 +284,7 @@ Full manual-install, troubleshooting, and uninstall docs:
305
284
  [docs/launchd.md](docs/launchd.md).
306
285
 
307
286
  Linux/Windows equivalents (systemd unit, Windows service) are planned for
308
- Phase 5. For now, run under `nohup` or your process manager of choice.
287
+ a future release. For now, run under `nohup` or your process manager of choice.
309
288
 
310
289
  ---
311
290
 
@@ -355,8 +334,7 @@ ccRecall/
355
334
  │ │ ├── indexer.ts # Indexing pipeline orchestrator
356
335
  │ │ ├── memory-service.ts # Memory lifecycle (touch / delete / update)
357
336
  │ │ ├── compression.ts # L0→L1→L2→delete state machine
358
- │ │ ├── lint.ts # Orphan / stale memory detection
359
- │ │ ├── maintenance-coordinator.ts # Background compression tick + journal decay sweep
337
+ │ │ ├── maintenance-coordinator.ts # Background compression tick
360
338
  │ │ ├── watcher.ts # chokidar JSONL watcher (Phase 4e)
361
339
  │ │ └── log-safe.ts # scrubErrorMessage — log-injection defence
362
340
  │ ├── api/
@@ -366,8 +344,7 @@ ccRecall/
366
344
  │ │ ├── server.ts # MCP stdio server entry (shebang bin)
367
345
  │ │ └── tools.ts # recall_query + recall_context + recall_save
368
346
  │ ├── cli/
369
- │ │ ├── daemon.ts # install-daemon / uninstall-daemon (macOS)
370
- │ │ └── journal.ts # ccmem promote / reject (since v0.3.0)
347
+ │ │ └── daemon.ts # install-daemon / uninstall-daemon (macOS)
371
348
  │ └── index.ts # HTTP entry point + subcommand dispatch
372
349
  ├── hooks/
373
350
  │ ├── session-start.mjs # Inject memories on SessionStart (stdout)
@@ -377,11 +354,10 @@ ccRecall/
377
354
  │ ├── tutorial.md # End-user walkthrough (install → MCP → usage)
378
355
  │ ├── architecture.md # Daemon design rationale (contributor-oriented)
379
356
  │ └── launchd.md # macOS LaunchAgent install/troubleshoot
380
- ├── tests/ # 629 tests across 39 files (parser, scanner,
357
+ ├── tests/ # 524 tests across 34 files (parser, scanner,
381
358
  │ │ # summarizer, database, indexer, e2e, MCP,
382
359
  │ │ # memories, hooks, watcher, CLI, migrations,
383
- │ │ # FTS5 CJK edge cases, integrity monitor,
384
- │ │ # session_journal DAO, promote+reject, sweep, ...)
360
+ │ │ # FTS5 CJK edge cases, integrity monitor, ...)
385
361
  │ └── fixtures/ # Sample JSONL + shared test helpers
386
362
  ├── .mcp.json.example # MCP client config template
387
363
  └── NOTICE / SECURITY.md / CONTRIBUTING.md / CODE_OF_CONDUCT.md
@@ -432,9 +408,9 @@ The real trigger was simpler: I kept re-explaining the same architecture to Clau
432
408
  | Version | Theme | Status |
433
409
  |---------|-------|--------|
434
410
  | **v0.3.x** | Manual save, automatic recall — memories come from explicit `recall_save` calls; SessionStart hook and MCP tools inject them into future sessions | Released |
435
- | **v0.4.0** | Startup-v1 default + tool description hardening | Released |
436
- | **v0.4.1** | Key-based upsert dedup, post-session memory extraction via Haiku, cross-project memory visibility via topic intersection | Released |
437
- | **v0.5+** | Scorer/journal/harvester deprecation, L1 keyword injection, memory lifecycle history | Planned |
411
+ | **v0.4.x** | Post-session extraction via Haiku, cross-project memory via topic intersection, extraction pipeline hardening (race gates, compression integrity, subagent filtering, security) | Released |
412
+ | **v0.5.0** | The knife field: journal/scorer/harvester pipelines removed (zero promotions ever), endpoints 13 → 5, `message_uuids` dual-hash rebuild (DB 114MB → 42MB) | Released |
413
+ | **v0.5+** | CJK-aware topic extraction (`\p{Script=Han}` tokenizer + Chinese stopwords), L1 keyword injection, README → manifesto | Planned |
438
414
 
439
415
  Tracked in [GitHub Issues](https://github.com/tznthou/ccRecall/issues).
440
416
 
package/README_ZH.md CHANGED
@@ -11,13 +11,9 @@ Claude Code 的本地記憶服務——索引你的對話歷史,按需召回
11
11
 
12
12
  ---
13
13
 
14
- > 📐 **v0.3.0 — Trust 二層拆分(harvest 寫入路徑 breaking change)**
14
+ > 📐 **v0.5.0 — 砍刀場版本:一條管線,零死代碼**
15
15
  >
16
- > SessionEnd hook 改寫到新建的 low-trust `session_journal` 表,不再寫 `memories`。Journal 條目會評分、透過 `/health` 的 `journalPendingCount` 露出,**`recall_query` / `recall_context` 不會直接召回 journal 條目**,需要先 `ccmem promote <id>` 升級。Manual `recall_save` 不變——仍直寫 high-trust `memories`。
17
- >
18
- > Rule scorer 不再卡在 persistence gate;改成提供 trust grade 與 promote 優先序。完整 rationale 見 [issue #21](https://github.com/tznthou/ccRecall/issues/21)。
19
- >
20
- > 0.3.0 之前的 memories 仍可正常查詢。v22 schema migration 在 daemon 第一次啟動時自動跑,既有 row 不會被動。新 harvest 從現在起寫 journal。
16
+ > Post-session extraction via Haiku(約 $0.001/session)自 v0.4.1 起就是主要記憶寫入路徑,v0.4.2–v0.4.8 逐版強化。v0.5.0 把這條管線淘汰掉的東西一次清完——journal 審閱佇列(史上零 promotion)、規則 scorer、checkpoints、8 個零 caller 的 HTTP endpoint——並把 replay 去重登記表重建為精巧的 64-bit hash(資料庫實測 114MB → 42MB)。Manual `recall_save` 仍可用於 session 中即時存記憶。
21
17
 
22
18
  ---
23
19
 
@@ -41,9 +37,8 @@ ccRecall 是 [ccRewind](https://github.com/tznthou/ccRewind)(對話回放 GUI
41
37
  | **FTS5 全文搜尋** | 所有對話歷史的關鍵詞搜尋 <100ms,快到可以在 hook 中注入 |
42
38
  | **CJK / 中英混合搜尋** | Trigram tokenizer 索引中日韓文字;短 token 查詢(如 `UI 記憶`)以 per-token AND LIKE fallback 補齊,避開 trigram 對 <3 字 token 的盲區 |
43
39
  | **增量索引** | 只重新索引有變動的 session(mtime 比對),透過 UUID 去重處理接續 session |
44
- | **元認知** | `knowledge_map` 聚合 session + memory 的主題提及。由 mention count 衍生深度(shallow / medium / deep)。透過 `/metacognition/check` 與 MCP `recall_context` 暴露 |
40
+ | **元認知** | `knowledge_map` 聚合 session + memory 的主題提及。由 mention count 衍生深度(shallow / medium / deep)。透過 MCP `recall_context` 暴露 |
45
41
  | **遺忘曲線** | 記憶隨時間壓縮:原始→摘要→一行結論→刪除。未使用的記憶信心衰減。背景維護 tick 每 5 分鐘跑一次 |
46
- | **Trust 二層**(v0.3.0) | Hook 寫入 low-trust `session_journal`(可審閱、不被 recall);manual `recall_save` 寫 high-trust `memories`。用 `ccmem promote <id>` 升級候選;reject 後 7 天 TTL 自動清 |
47
42
  | **跨專案記憶**(v0.4.1) | 記憶透過 topic intersection 跨專案浮出——若兩個專案的 `knowledge_map` 有共同 topic,高信心記憶會出現在另一個專案的 startup injection(最多 3 條,confidence ≥ 0.8 gate) |
48
43
  | **Watch mode** | 基於 chokidar 的 JSONL watcher 在 2 秒內偵測新 session;每 10 分鐘 full-resync 補救 FS 事件漏接 |
49
44
  | **Rescue reindex** | `/session/end` 和 `/session/last` 都會在 miss 時重 index 再試一次,`/session/last` 另有 `notBefore` staleness gate——hook、wrapper、daemon 三方不會有 fresh-session race |
@@ -66,7 +61,7 @@ flowchart TB
66
61
  Parser["Parser<br/>解析對話"]
67
62
  Summarizer["Summarizer<br/>規則式萃取"]
68
63
  DB[("SQLite + FTS5<br/>索引與搜尋")]
69
- API["HTTP API<br/>13 個端點"]
64
+ API["HTTP API<br/>5 個端點"]
70
65
  end
71
66
 
72
67
  subgraph Consumers["使用端"]
@@ -77,7 +72,7 @@ flowchart TB
77
72
 
78
73
  JSONL --> Watcher --> Scanner --> Parser --> Summarizer --> DB
79
74
  DB <--> API
80
- Hook -->|"注入 / journal"| API
75
+ Hook -->|"注入 / 收尾確認"| API
81
76
  Wrapper -->|"GET /session/last"| API
82
77
  MCP <-->|"WAL 模式共用 SQLite"| DB
83
78
  ```
@@ -109,7 +104,7 @@ sequenceDiagram
109
104
  rect rgb(255, 244, 235)
110
105
  Note over CC,X: Session 結束
111
106
  CC->>H: SessionEnd
112
- H->>R: POST /session/end(低信任 journal)
107
+ H->>R: POST /session/end(確認已索引 + rescue)
113
108
  W->>R: GET /session/last?notBefore=launch_ts
114
109
  R-->>W: sessionId(過 staleness gate、濾掉 subagent)
115
110
  W->>X: 純文字 transcript
@@ -130,7 +125,7 @@ sequenceDiagram
130
125
  | FTS5 | 全文搜尋 | SQLite 內建、trigram tokenizer,短 token / 中英混合查詢透過 LIKE fallback 補齊 |
131
126
  | 原生 `http` | HTTP 伺服器 | 不用 Express——最小表面積、僅 localhost |
132
127
  | chokidar | 檔案系統 watcher | 跨平台 JSONL 變動偵測,2 秒 debounce + single-flight |
133
- | vitest | 測試 | 629 個測試(39 檔案)、整合式風格 |
128
+ | vitest | 測試 | 524 個測試(34 檔案)、整合式風格 |
134
129
  | `@modelcontextprotocol/sdk` | MCP server | stdio transport,透過 WAL 共用 SQLite |
135
130
 
136
131
  ---
@@ -172,20 +167,17 @@ curl "http://127.0.0.1:7749/memory/query?q=authentication&limit=5"
172
167
 
173
168
  ## API 端點
174
169
 
175
- | 端點 | 方法 | 說明 | 狀態 |
176
- |------|------|------|------|
177
- | `/health` | GET | 服務健康 + DB 統計 + integrity 檢查狀態 + `journalPendingCount`(v0.3.0 新增) | 已上線 |
178
- | `/memory/query?q=...&limit=...&project=...` | GET | FTS5 跨 session 搜尋,可選 project 過濾(journal 條目 by design 不含) | 已上線 |
179
- | `/memory/save` | POST | 儲存記憶條目(Origin 驗證) | 已上線 |
180
- | `/session/end` | POST | 把結束的 session 寫入 `session_journal`(idempotent;0.3.0 前是寫 `memories`) | 已上線 |
181
- | `/journal/pending` | GET | 列出待 promote 審閱的 journal 條目 | 已上線(v0.3.0) |
182
- | `/journal/promote` | POST | atomic 把 journal 條目升級到 `memories` | 已上線(v0.3.0) |
183
- | `/journal/reject` | POST | soft-delete journal 條目(7 天 TTL,由 decay sweep 清理) | 已上線(v0.3.0) |
184
- | `/memory/context?session_id=...` | GET | Session context 查詢 | Stub |
185
- | `/metacognition/check?projectId=...[&topic=...]` | GET | 知識地圖:summary(top/recent/stale topics + counts)或 topic detail(memories + related topics) | 已上線 |
186
- | `/session/checkpoint` | POST | 會話中途快照寫入獨立 `session_checkpoints` 表(不會被 harvest 成 memory) | 已上線 |
187
- | `/lint/warnings` | GET | Lint 報告:orphan(session 已刪)+ stale(低信心、長期未用)記憶警告 | 已上線 |
188
- | `/session/last?cwd=...` | GET | 回傳專案路徑的最新 session metadata(post-session extraction wrapper 使用) | 已上線(v0.4.1) |
170
+ 五個端點,每個都有活的 caller——v0.5.0 移除了其餘八個
171
+ (`/journal/*`、`/memory/save`、`/memory/context`、`/metacognition/check`、
172
+ `/session/checkpoint`、`/lint/warnings`),現在一律回 404。
173
+
174
+ | 端點 | 方法 | 說明 | Caller |
175
+ |------|------|------|--------|
176
+ | `/health` | GET | 服務健康 + DB 統計 + integrity 檢查狀態 | CLI、extraction wrapper |
177
+ | `/memory/startup?project=...` | GET | SessionStart 級檢索:cold + recent-confidence + FTS fallback,帶 token 預算 | SessionStart hook |
178
+ | `/memory/query?q=...&limit=...&project=...` | GET | FTS5 跨記憶搜尋,可選 project 過濾 | SessionStart hook(keyword 層) |
179
+ | `/session/end` | POST | 確認剛結束的 session 已被索引(miss 時 rescue reindex) | SessionEnd hook |
180
+ | `/session/last?cwd=...` | GET | 回傳專案路徑的最新 session metadata(`notBefore` staleness gate) | Extraction wrapper |
189
181
 
190
182
  ## MCP 工具
191
183
 
@@ -235,21 +227,9 @@ Daemon 與 hook 生命週期(macOS):
235
227
  | `ccmem uninstall-daemon` | 停掉並移除 LaunchAgent |
236
228
  | `ccmem install-hooks` | 把 SessionStart / SessionEnd 條目合併進 `~/.claude/settings.json` |
237
229
  | `ccmem uninstall-hooks` | 移除 ccRecall 自己的 hook 條目(其他 hook 不動) |
230
+ | `ccmem cleanup --orphans` | 列出(加 `--yes` 則刪除)session 已消失的 orphan 記憶 |
238
231
 
239
- Journal 審閱(v0.3.0 新增):
240
-
241
- | 指令 | 用途 |
242
- |------|------|
243
- | `ccmem promote <id>` | 把 journal 條目升級到 `memories`。可選 `--type`(預設 `discovery`)、`--confidence`(預設 `0.7`) |
244
- | `ccmem reject <id>` | soft-delete journal 條目;7 天 TTL 後由 decay sweep 清掉 |
245
-
246
- 查待 promote 候選:
247
-
248
- ```bash
249
- curl http://127.0.0.1:7749/journal/pending
250
- # 或只看計數
251
- curl http://127.0.0.1:7749/health | jq .journalPendingCount
252
- ```
232
+ `ccmem promote` / `ccmem reject` 已於 v0.5.0 隨 journal 管線一併移除。
253
233
 
254
234
  ---
255
235
 
@@ -270,8 +250,6 @@ ccRecall 和 Claude Code 內建的 auto memory(`~/.claude/projects/*/memory/`
270
250
 
271
251
  ccRecall 的價值在長尾——幾百個 session 不可能全手工整理。如果 Claude 兩邊都試,auto memory 永遠會贏(本來就在 context 裡而且已經被策展)。ccRecall 存在的意義是:策展索引漏掉時,長尾那堆還在資料庫裡可以撈出來。
272
252
 
273
- **ccRecall 內部從 v0.3.0 起多了一層 trust 拆分。** SessionEnd hook 寫到 low-trust `session_journal` 表——`recall_query` 不會去讀那裡。要讓某筆候選進到查詢結果,跑 `ccmem promote <id>` 升級到 high-trust `memories`。Manual `recall_save` 完全不經 journal——直接寫 memories。設計目的:讓 harvester 廣捕,但 recall 結果保持乾淨。
274
-
275
253
  ---
276
254
 
277
255
  ## 作為服務運行(macOS)
@@ -300,7 +278,7 @@ installer 的行為:
300
278
 
301
279
  完整手動安裝、troubleshooting、uninstall 文件:[docs/launchd.md](docs/launchd.md)。
302
280
 
303
- Linux/Windows 對應版本(systemd unit、Windows service)列在 Phase 5。目前
281
+ Linux/Windows 對應版本(systemd unit、Windows service)列在未來版本。目前
304
282
  Linux 可用 `nohup` 或自選 process manager。
305
283
 
306
284
  ---
@@ -348,8 +326,7 @@ ccRecall/
348
326
  │ │ ├── indexer.ts # 索引 pipeline 調度
349
327
  │ │ ├── memory-service.ts # 記憶生命週期(touch / delete / update)
350
328
  │ │ ├── compression.ts # L0→L1→L2→delete 狀態機
351
- │ │ ├── lint.ts # Orphan / stale 記憶偵測
352
- │ │ ├── maintenance-coordinator.ts # 背景壓縮 tick + journal decay sweep
329
+ │ │ ├── maintenance-coordinator.ts # 背景壓縮 tick
353
330
  │ │ ├── watcher.ts # chokidar JSONL watcher(Phase 4e)
354
331
  │ │ └── log-safe.ts # scrubErrorMessage — log-injection 防護
355
332
  │ ├── api/
@@ -359,8 +336,7 @@ ccRecall/
359
336
  │ │ ├── server.ts # MCP stdio server 入口(含 shebang)
360
337
  │ │ └── tools.ts # recall_query + recall_context + recall_save
361
338
  │ ├── cli/
362
- │ │ ├── daemon.ts # install-daemon / uninstall-daemon(macOS)
363
- │ │ └── journal.ts # ccmem promote / reject(v0.3.0 新增)
339
+ │ │ └── daemon.ts # install-daemon / uninstall-daemon(macOS)
364
340
  │ └── index.ts # HTTP 入口 + 子指令分派
365
341
  ├── hooks/
366
342
  │ ├── session-start.mjs # SessionStart 注入記憶(stdout)
@@ -370,11 +346,10 @@ ccRecall/
370
346
  │ ├── tutorial_zh.md # 使用者教學(安裝 → MCP → 日常使用)
371
347
  │ ├── architecture_zh.md # Daemon 設計取捨(給 contributor 看)
372
348
  │ └── launchd.md # macOS LaunchAgent 安裝/troubleshoot
373
- ├── tests/ # 629 個測試橫跨 39 檔案(parser、scanner、
349
+ ├── tests/ # 524 個測試橫跨 34 檔案(parser、scanner、
374
350
  │ │ # summarizer、database、indexer、e2e、MCP、
375
351
  │ │ # memories、hooks、watcher、CLI、migrations、
376
- │ │ # FTS5 CJK edge cases、integrity monitor、
377
- │ │ # session_journal DAO、promote+reject、sweep 等)
352
+ │ │ # FTS5 CJK edge cases、integrity monitor 等)
378
353
  │ └── fixtures/ # 測試用 JSONL + 共用 helpers
379
354
  ├── .mcp.json.example # MCP client 設定範本
380
355
  └── NOTICE / SECURITY.md / CONTRIBUTING.md / CODE_OF_CONDUCT.md
@@ -425,9 +400,9 @@ Anthropic Claude Code 團隊的 Thariq 在 2026 年 4 月[發表了 context 管
425
400
  | 版本 | 主題 | 狀態 |
426
401
  |------|------|------|
427
402
  | **v0.3.x** | 手動存、自動召回——記憶來自明確的 `recall_save` 呼叫;SessionStart hook 和 MCP 工具在未來 session 注入 | 已釋出 |
428
- | **v0.4.0** | Startup-v1 預設 + tool description 強化 | 已釋出 |
429
- | **v0.4.1** | Key-based upsert dedup、post-session memory extraction via Haiku、跨專案 topic intersection 記憶可見性 | 已釋出 |
430
- | **v0.5+** | Scorer/journal/harvester 降級、L1 keyword injection、memory lifecycle history | 規劃中 |
403
+ | **v0.4.x** | Post-session extraction via Haiku、跨專案 topic intersection 記憶、萃取管線強化(race gate、壓縮完整性、subagent 過濾、安全性) | 已釋出 |
404
+ | **v0.5.0** | 砍刀場:journal/scorer/harvester 管線移除(史上零 promotion)、端點 13 → 5、`message_uuids` 雙 hash 重建(DB 114MB → 42MB) | 已釋出 |
405
+ | **v0.5+** | CJK topic 抽取(`\p{Script=Han}` tokenizer + 中文 stopwords)、L1 keyword injection、README → manifesto | 規劃中 |
431
406
 
432
407
  追蹤於 [GitHub Issues](https://github.com/tznthou/ccRecall/issues)。
433
408
 
@@ -1,16 +1,6 @@
1
1
  import http from 'node:http';
2
2
  import type { Database } from '../core/database.js';
3
- import type { SessionMeta, OutcomeStatus, JournalEntryInput } from '../core/types.js';
4
3
  import type { IntegrityCheckRecord } from '../core/integrity-monitor.js';
5
- export declare function inferConfidence(outcome: OutcomeStatus): number;
6
- /** P1 (#21): hook auto-harvester 改寫 session_journal 不寫 memories;
7
- * manual recall_save 仍直寫 memories。promote 路徑 (C4) 會把 journal entry
8
- * 搬到 memories table 並設 confidence。
9
- *
10
- * Score 重算: summarizer 已用 scorer 過 noise/process-report hard floor,
11
- * 但 score + reasons metadata 沒儲在 sessions.harvest_text。重算成本低
12
- * (regex 對 <2KB 文字),換 schema 不變的代價可接受。 */
13
- export declare function buildJournalCandidate(session: SessionMeta): JournalEntryInput | null;
14
4
  /** Coalesces concurrent rescue calls onto one underlying run. The SessionEnd
15
5
  * hook (/session/end) and the extraction wrapper (/session/last) both fire
16
6
  * within the same session close — without this each miss stacks its own full
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/api/routes.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,WAAW,CAAA;AAG5B,OAAO,KAAK,EAAE,QAAQ,EAAe,MAAM,qBAAqB,CAAA;AAOhE,OAAO,KAAK,EACwB,WAAW,EAAE,aAAa,EAE5D,iBAAiB,EAClB,MAAM,kBAAkB,CAAA;AAEzB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AA6DxE,wBAAgB,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAI9D;AAED;;;;;;2CAM2C;AAC3C,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,GAAG,iBAAiB,GAAG,IAAI,CAcpF;AAgED;;;;;gCAKgC;AAChC,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAM5E;AAED,MAAM,WAAW,qBAAqB;IACpC;;mDAE+C;IAC/C,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACnC;;gFAE4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;6EAEyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;4EAEwE;IACxE,gBAAgB,CAAC,EAAE;QAAE,aAAa,IAAI,oBAAoB,GAAG,IAAI,CAAA;KAAE,CAAA;CACpE;AAED,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,QAAQ,EACZ,IAAI,GAAE,qBAA0B,IAI9B,KAAK,IAAI,CAAC,eAAe,EACzB,KAAK,IAAI,CAAC,cAAc,KACvB,OAAO,CAAC,IAAI,CAAC,CA6djB"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/api/routes.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,WAAW,CAAA;AAG5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAMnD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AAqCxE;;;;;gCAKgC;AAChC,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAM5E;AAED,MAAM,WAAW,qBAAqB;IACpC;;mDAE+C;IAC/C,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACnC;;gFAE4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;6EAEyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;4EAEwE;IACxE,gBAAgB,CAAC,EAAE;QAAE,aAAa,IAAI,oBAAoB,GAAG,IAAI,CAAA;KAAE,CAAA;CACpE;AAED,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,QAAQ,EACZ,IAAI,GAAE,qBAA0B,IAI9B,KAAK,IAAI,CAAC,eAAe,EACzB,KAAK,IAAI,CAAC,cAAc,KACvB,OAAO,CAAC,IAAI,CAAC,CA8NjB"}