@lossless-claude/lcm 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (292) hide show
  1. package/.claude-plugin/commands/lcm-compact.md +31 -0
  2. package/.claude-plugin/commands/lcm-curate.md +31 -0
  3. package/.claude-plugin/commands/lcm-diagnose.md +29 -0
  4. package/.claude-plugin/commands/lcm-doctor.md +23 -0
  5. package/.claude-plugin/commands/lcm-dogfood.md +101 -0
  6. package/.claude-plugin/commands/lcm-import.md +48 -0
  7. package/.claude-plugin/commands/lcm-promote.md +29 -0
  8. package/.claude-plugin/commands/lcm-sensitive.md +55 -0
  9. package/.claude-plugin/commands/lcm-stats.md +19 -0
  10. package/.claude-plugin/commands/lcm-status.md +27 -0
  11. package/.claude-plugin/hooks/README.md +47 -0
  12. package/.claude-plugin/marketplace.json +20 -0
  13. package/.claude-plugin/mcp.mjs +12 -0
  14. package/.claude-plugin/plugin.json +46 -0
  15. package/.claude-plugin/skills/lcm-context/SKILL.md +107 -0
  16. package/.claude-plugin/skills/lcm-dogfood/SKILL.md +102 -0
  17. package/.claude-plugin/skills/lcm-dogfood/references/checks.md +239 -0
  18. package/.claude-plugin/skills/lcm-dogfood/references/known-issues.md +11 -0
  19. package/.claude-plugin/skills/lcm-dogfood/scripts/db-integrity.js +40 -0
  20. package/.claude-plugin/skills/lcm-dogfood/scripts/prompt-search-test.js +35 -0
  21. package/.claude-plugin/skills/lcm-e2e/SKILL.md +61 -0
  22. package/.claude-plugin/skills/lcm-e2e/checklist.md +367 -0
  23. package/.claude-plugin/skills/lossless-claude-upgrade/SKILL.md +47 -0
  24. package/LICENSE +21 -0
  25. package/README.md +231 -0
  26. package/dist/bin/lcm.d.ts +2 -0
  27. package/dist/bin/lcm.js +461 -0
  28. package/dist/bin/lcm.js.map +1 -0
  29. package/dist/installer/dry-run-deps.d.ts +23 -0
  30. package/dist/installer/dry-run-deps.js +66 -0
  31. package/dist/installer/dry-run-deps.js.map +1 -0
  32. package/dist/installer/install.d.ts +39 -0
  33. package/dist/installer/install.js +236 -0
  34. package/dist/installer/install.js.map +1 -0
  35. package/dist/installer/uninstall.d.ts +11 -0
  36. package/dist/installer/uninstall.js +80 -0
  37. package/dist/installer/uninstall.js.map +1 -0
  38. package/dist/src/batch-compact.d.ts +16 -0
  39. package/dist/src/batch-compact.js +121 -0
  40. package/dist/src/batch-compact.js.map +1 -0
  41. package/dist/src/compaction.d.ts +198 -0
  42. package/dist/src/compaction.js +964 -0
  43. package/dist/src/compaction.js.map +1 -0
  44. package/dist/src/connectors/constants.d.ts +5 -0
  45. package/dist/src/connectors/constants.js +6 -0
  46. package/dist/src/connectors/constants.js.map +1 -0
  47. package/dist/src/connectors/installer.d.ts +16 -0
  48. package/dist/src/connectors/installer.js +200 -0
  49. package/dist/src/connectors/installer.js.map +1 -0
  50. package/dist/src/connectors/registry.d.ts +4 -0
  51. package/dist/src/connectors/registry.js +264 -0
  52. package/dist/src/connectors/registry.js.map +1 -0
  53. package/dist/src/connectors/template-service.d.ts +5 -0
  54. package/dist/src/connectors/template-service.js +54 -0
  55. package/dist/src/connectors/template-service.js.map +1 -0
  56. package/dist/src/connectors/templates/base.md +1 -0
  57. package/dist/src/connectors/templates/mcp-base.md +1 -0
  58. package/dist/src/connectors/templates/sections/command-reference.md +15 -0
  59. package/dist/src/connectors/templates/sections/mcp-workflow.md +18 -0
  60. package/dist/src/connectors/templates/sections/workflow.md +29 -0
  61. package/dist/src/connectors/templates/skill/SKILL.md +74 -0
  62. package/dist/src/connectors/types.d.ts +19 -0
  63. package/dist/src/connectors/types.js +10 -0
  64. package/dist/src/connectors/types.js.map +1 -0
  65. package/dist/src/daemon/client.d.ts +9 -0
  66. package/dist/src/daemon/client.js +28 -0
  67. package/dist/src/daemon/client.js.map +1 -0
  68. package/dist/src/daemon/config.d.ts +48 -0
  69. package/dist/src/daemon/config.js +67 -0
  70. package/dist/src/daemon/config.js.map +1 -0
  71. package/dist/src/daemon/lifecycle.d.ts +19 -0
  72. package/dist/src/daemon/lifecycle.js +102 -0
  73. package/dist/src/daemon/lifecycle.js.map +1 -0
  74. package/dist/src/daemon/orientation.d.ts +1 -0
  75. package/dist/src/daemon/orientation.js +9 -0
  76. package/dist/src/daemon/orientation.js.map +1 -0
  77. package/dist/src/daemon/project-queue.d.ts +1 -0
  78. package/dist/src/daemon/project-queue.js +17 -0
  79. package/dist/src/daemon/project-queue.js.map +1 -0
  80. package/dist/src/daemon/project.d.ts +7 -0
  81. package/dist/src/daemon/project.js +25 -0
  82. package/dist/src/daemon/project.js.map +1 -0
  83. package/dist/src/daemon/proxy-manager.d.ts +21 -0
  84. package/dist/src/daemon/proxy-manager.js +205 -0
  85. package/dist/src/daemon/proxy-manager.js.map +1 -0
  86. package/dist/src/daemon/routes/compact.d.ts +13 -0
  87. package/dist/src/daemon/routes/compact.js +195 -0
  88. package/dist/src/daemon/routes/compact.js.map +1 -0
  89. package/dist/src/daemon/routes/describe.d.ts +3 -0
  90. package/dist/src/daemon/routes/describe.js +39 -0
  91. package/dist/src/daemon/routes/describe.js.map +1 -0
  92. package/dist/src/daemon/routes/expand.d.ts +3 -0
  93. package/dist/src/daemon/routes/expand.js +41 -0
  94. package/dist/src/daemon/routes/expand.js.map +1 -0
  95. package/dist/src/daemon/routes/grep.d.ts +3 -0
  96. package/dist/src/daemon/routes/grep.js +43 -0
  97. package/dist/src/daemon/routes/grep.js.map +1 -0
  98. package/dist/src/daemon/routes/ingest.d.ts +3 -0
  99. package/dist/src/daemon/routes/ingest.js +101 -0
  100. package/dist/src/daemon/routes/ingest.js.map +1 -0
  101. package/dist/src/daemon/routes/promote.d.ts +4 -0
  102. package/dist/src/daemon/routes/promote.js +104 -0
  103. package/dist/src/daemon/routes/promote.js.map +1 -0
  104. package/dist/src/daemon/routes/prompt-search.d.ts +3 -0
  105. package/dist/src/daemon/routes/prompt-search.js +65 -0
  106. package/dist/src/daemon/routes/prompt-search.js.map +1 -0
  107. package/dist/src/daemon/routes/recent.d.ts +3 -0
  108. package/dist/src/daemon/routes/recent.js +37 -0
  109. package/dist/src/daemon/routes/recent.js.map +1 -0
  110. package/dist/src/daemon/routes/restore.d.ts +3 -0
  111. package/dist/src/daemon/routes/restore.js +120 -0
  112. package/dist/src/daemon/routes/restore.js.map +1 -0
  113. package/dist/src/daemon/routes/search.d.ts +2 -0
  114. package/dist/src/daemon/routes/search.js +66 -0
  115. package/dist/src/daemon/routes/search.js.map +1 -0
  116. package/dist/src/daemon/routes/status.d.ts +3 -0
  117. package/dist/src/daemon/routes/status.js +80 -0
  118. package/dist/src/daemon/routes/status.js.map +1 -0
  119. package/dist/src/daemon/routes/store.d.ts +2 -0
  120. package/dist/src/daemon/routes/store.js +46 -0
  121. package/dist/src/daemon/routes/store.js.map +1 -0
  122. package/dist/src/daemon/server.d.ts +19 -0
  123. package/dist/src/daemon/server.js +183 -0
  124. package/dist/src/daemon/server.js.map +1 -0
  125. package/dist/src/daemon/summarizer.d.ts +11 -0
  126. package/dist/src/daemon/summarizer.js +51 -0
  127. package/dist/src/daemon/summarizer.js.map +1 -0
  128. package/dist/src/db/config.d.ts +31 -0
  129. package/dist/src/db/config.js +83 -0
  130. package/dist/src/db/config.js.map +1 -0
  131. package/dist/src/db/connection.d.ts +3 -0
  132. package/dist/src/db/connection.js +62 -0
  133. package/dist/src/db/connection.js.map +1 -0
  134. package/dist/src/db/features.d.ts +11 -0
  135. package/dist/src/db/features.js +36 -0
  136. package/dist/src/db/features.js.map +1 -0
  137. package/dist/src/db/migration.d.ts +4 -0
  138. package/dist/src/db/migration.js +499 -0
  139. package/dist/src/db/migration.js.map +1 -0
  140. package/dist/src/db/promoted.d.ts +47 -0
  141. package/dist/src/db/promoted.js +96 -0
  142. package/dist/src/db/promoted.js.map +1 -0
  143. package/dist/src/db/redaction-stats.d.ts +6 -0
  144. package/dist/src/db/redaction-stats.js +16 -0
  145. package/dist/src/db/redaction-stats.js.map +1 -0
  146. package/dist/src/diagnose.d.ts +39 -0
  147. package/dist/src/diagnose.js +432 -0
  148. package/dist/src/diagnose.js.map +1 -0
  149. package/dist/src/doctor/doctor.d.ts +4 -0
  150. package/dist/src/doctor/doctor.js +378 -0
  151. package/dist/src/doctor/doctor.js.map +1 -0
  152. package/dist/src/doctor/types.d.ts +24 -0
  153. package/dist/src/doctor/types.js +2 -0
  154. package/dist/src/doctor/types.js.map +1 -0
  155. package/dist/src/expansion.d.ts +100 -0
  156. package/dist/src/expansion.js +268 -0
  157. package/dist/src/expansion.js.map +1 -0
  158. package/dist/src/hooks/auto-heal.d.ts +12 -0
  159. package/dist/src/hooks/auto-heal.js +49 -0
  160. package/dist/src/hooks/auto-heal.js.map +1 -0
  161. package/dist/src/hooks/compact.d.ts +5 -0
  162. package/dist/src/hooks/compact.js +22 -0
  163. package/dist/src/hooks/compact.js.map +1 -0
  164. package/dist/src/hooks/dispatch.d.ts +7 -0
  165. package/dist/src/hooks/dispatch.js +36 -0
  166. package/dist/src/hooks/dispatch.js.map +1 -0
  167. package/dist/src/hooks/probe-precompact.d.ts +2 -0
  168. package/dist/src/hooks/probe-precompact.js +17 -0
  169. package/dist/src/hooks/probe-precompact.js.map +1 -0
  170. package/dist/src/hooks/probe-sessionstart.d.ts +2 -0
  171. package/dist/src/hooks/probe-sessionstart.js +18 -0
  172. package/dist/src/hooks/probe-sessionstart.js.map +1 -0
  173. package/dist/src/hooks/restore.d.ts +5 -0
  174. package/dist/src/hooks/restore.js +19 -0
  175. package/dist/src/hooks/restore.js.map +1 -0
  176. package/dist/src/hooks/session-end.d.ts +16 -0
  177. package/dist/src/hooks/session-end.js +73 -0
  178. package/dist/src/hooks/session-end.js.map +1 -0
  179. package/dist/src/hooks/user-prompt.d.ts +5 -0
  180. package/dist/src/hooks/user-prompt.js +31 -0
  181. package/dist/src/hooks/user-prompt.js.map +1 -0
  182. package/dist/src/import.d.ts +24 -0
  183. package/dist/src/import.js +119 -0
  184. package/dist/src/import.js.map +1 -0
  185. package/dist/src/large-files.d.ts +28 -0
  186. package/dist/src/large-files.js +413 -0
  187. package/dist/src/large-files.js.map +1 -0
  188. package/dist/src/llm/anthropic.d.ts +9 -0
  189. package/dist/src/llm/anthropic.js +54 -0
  190. package/dist/src/llm/anthropic.js.map +1 -0
  191. package/dist/src/llm/claude-process.d.ts +2 -0
  192. package/dist/src/llm/claude-process.js +55 -0
  193. package/dist/src/llm/claude-process.js.map +1 -0
  194. package/dist/src/llm/codex-process.d.ts +15 -0
  195. package/dist/src/llm/codex-process.js +142 -0
  196. package/dist/src/llm/codex-process.js.map +1 -0
  197. package/dist/src/llm/mock-summarizer.d.ts +9 -0
  198. package/dist/src/llm/mock-summarizer.js +17 -0
  199. package/dist/src/llm/mock-summarizer.js.map +1 -0
  200. package/dist/src/llm/openai.d.ts +10 -0
  201. package/dist/src/llm/openai.js +52 -0
  202. package/dist/src/llm/openai.js.map +1 -0
  203. package/dist/src/llm/types.d.ts +6 -0
  204. package/dist/src/llm/types.js +2 -0
  205. package/dist/src/llm/types.js.map +1 -0
  206. package/dist/src/mcp/server.d.ts +9 -0
  207. package/dist/src/mcp/server.js +128 -0
  208. package/dist/src/mcp/server.js.map +1 -0
  209. package/dist/src/mcp/tools/lcm-describe.d.ts +14 -0
  210. package/dist/src/mcp/tools/lcm-describe.js +12 -0
  211. package/dist/src/mcp/tools/lcm-describe.js.map +1 -0
  212. package/dist/src/mcp/tools/lcm-doctor.d.ts +8 -0
  213. package/dist/src/mcp/tools/lcm-doctor.js +9 -0
  214. package/dist/src/mcp/tools/lcm-doctor.js.map +1 -0
  215. package/dist/src/mcp/tools/lcm-expand.d.ts +18 -0
  216. package/dist/src/mcp/tools/lcm-expand.js +13 -0
  217. package/dist/src/mcp/tools/lcm-expand.js.map +1 -0
  218. package/dist/src/mcp/tools/lcm-grep.d.ts +27 -0
  219. package/dist/src/mcp/tools/lcm-grep.js +15 -0
  220. package/dist/src/mcp/tools/lcm-grep.js.map +1 -0
  221. package/dist/src/mcp/tools/lcm-search.d.ts +33 -0
  222. package/dist/src/mcp/tools/lcm-search.js +15 -0
  223. package/dist/src/mcp/tools/lcm-search.js.map +1 -0
  224. package/dist/src/mcp/tools/lcm-stats.d.ts +14 -0
  225. package/dist/src/mcp/tools/lcm-stats.js +11 -0
  226. package/dist/src/mcp/tools/lcm-stats.js.map +1 -0
  227. package/dist/src/mcp/tools/lcm-store.d.ts +26 -0
  228. package/dist/src/mcp/tools/lcm-store.js +22 -0
  229. package/dist/src/mcp/tools/lcm-store.js.map +1 -0
  230. package/dist/src/memory/index.d.ts +22 -0
  231. package/dist/src/memory/index.js +21 -0
  232. package/dist/src/memory/index.js.map +1 -0
  233. package/dist/src/promotion/dedup.d.ts +19 -0
  234. package/dist/src/promotion/dedup.js +42 -0
  235. package/dist/src/promotion/dedup.js.map +1 -0
  236. package/dist/src/promotion/detector.d.ts +15 -0
  237. package/dist/src/promotion/detector.js +31 -0
  238. package/dist/src/promotion/detector.js.map +1 -0
  239. package/dist/src/prompts/condensed-d1.yaml +38 -0
  240. package/dist/src/prompts/condensed-d2.yaml +32 -0
  241. package/dist/src/prompts/condensed-d3plus.yaml +32 -0
  242. package/dist/src/prompts/leaf-aggressive.yaml +34 -0
  243. package/dist/src/prompts/leaf-normal.yaml +34 -0
  244. package/dist/src/prompts/loader.d.ts +9 -0
  245. package/dist/src/prompts/loader.js +37 -0
  246. package/dist/src/prompts/loader.js.map +1 -0
  247. package/dist/src/prompts/promoted-merge.yaml +18 -0
  248. package/dist/src/prompts/system.yaml +5 -0
  249. package/dist/src/retrieval.d.ts +122 -0
  250. package/dist/src/retrieval.js +214 -0
  251. package/dist/src/retrieval.js.map +1 -0
  252. package/dist/src/scrub.d.ts +46 -0
  253. package/dist/src/scrub.js +184 -0
  254. package/dist/src/scrub.js.map +1 -0
  255. package/dist/src/sensitive.d.ts +4 -0
  256. package/dist/src/sensitive.js +258 -0
  257. package/dist/src/sensitive.js.map +1 -0
  258. package/dist/src/stats.d.ts +34 -0
  259. package/dist/src/stats.js +260 -0
  260. package/dist/src/stats.js.map +1 -0
  261. package/dist/src/store/conversation-store.d.ts +115 -0
  262. package/dist/src/store/conversation-store.js +447 -0
  263. package/dist/src/store/conversation-store.js.map +1 -0
  264. package/dist/src/store/fts5-sanitize.d.ts +23 -0
  265. package/dist/src/store/fts5-sanitize.js +30 -0
  266. package/dist/src/store/fts5-sanitize.js.map +1 -0
  267. package/dist/src/store/full-text-fallback.d.ts +16 -0
  268. package/dist/src/store/full-text-fallback.js +60 -0
  269. package/dist/src/store/full-text-fallback.js.map +1 -0
  270. package/dist/src/store/index.d.ts +4 -0
  271. package/dist/src/store/index.js +3 -0
  272. package/dist/src/store/index.js.map +1 -0
  273. package/dist/src/store/summary-store.d.ts +118 -0
  274. package/dist/src/store/summary-store.js +570 -0
  275. package/dist/src/store/summary-store.js.map +1 -0
  276. package/dist/src/summarize.d.ts +59 -0
  277. package/dist/src/summarize.js +619 -0
  278. package/dist/src/summarize.js.map +1 -0
  279. package/dist/src/transcript.d.ts +7 -0
  280. package/dist/src/transcript.js +51 -0
  281. package/dist/src/transcript.js.map +1 -0
  282. package/dist/src/types.d.ts +116 -0
  283. package/dist/src/types.js +8 -0
  284. package/dist/src/types.js.map +1 -0
  285. package/docs/agent-tools.md +187 -0
  286. package/docs/architecture.md +224 -0
  287. package/docs/configuration.md +168 -0
  288. package/docs/fts5.md +161 -0
  289. package/docs/hook-protocol.md +41 -0
  290. package/docs/privacy.md +101 -0
  291. package/mcp.mjs +17 -0
  292. package/package.json +79 -0
@@ -0,0 +1,367 @@
1
+ # lcm E2E Validation Checklist
2
+
3
+ > **Note:** Some flows reference planned CLI flags (e.g., `--cwd`, `hook` subcommand) and MCP tools not yet implemented. These serve as a roadmap for future coverage.
4
+
5
+ All flows run against an isolated temp directory. No user project data is touched.
6
+
7
+ ---
8
+
9
+ ## Setup
10
+
11
+ Before any flow, create the temp working directory:
12
+
13
+ ```bash
14
+ LCME2E_DIR=$(mktemp -d /tmp/lcm-e2e-test-XXXXXX)
15
+ echo "Test dir: $LCME2E_DIR"
16
+ ```
17
+
18
+ All subsequent commands are run with `--cwd $LCME2E_DIR` or `cd $LCME2E_DIR &&` as appropriate.
19
+
20
+ ---
21
+
22
+ ## Flow 1 — Environment
23
+
24
+ **Goal:** Verify lcm binary is installed and daemon is reachable.
25
+
26
+ | Step | Command | Expected |
27
+ |------|---------|----------|
28
+ | 1.1 | `lcm --version` | Prints version string (e.g. `lcm 0.x.y`) |
29
+ | 1.2 | `lcm status --json` | JSON with `daemon: "running"` or attempt start |
30
+ | 1.3 | `lcm daemon start --detach` (if 1.2 failed) | Daemon starts, PID file created |
31
+ | 1.4 | `lcm status --json` | JSON with `daemon: "running"` |
32
+
33
+ **Pass criteria:** lcm binary found, daemon running after step 1.4.
34
+
35
+ ---
36
+
37
+ ## Flow 2 — Import
38
+
39
+ **Goal:** Ingest a synthetic transcript into the isolated project.
40
+
41
+ ```bash
42
+ cat > $LCME2E_DIR/e2e-session.jsonl << 'FIXTURE'
43
+ {"type":"human","message":{"role":"user","content":[{"type":"text","text":"What database should we use for the project?"}]},"timestamp":"2024-01-01T00:00:00Z"}
44
+ {"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"We decided to use SQLite instead of PostgreSQL because it requires zero infrastructure. The ConversationStore class in src/store/conversation-store.ts handles all CRUD operations."}]},"timestamp":"2024-01-01T00:01:00Z"}
45
+ {"type":"human","message":{"role":"user","content":[{"type":"text","text":"What should the API authentication strategy be?"}]},"timestamp":"2024-01-01T00:02:00Z"}
46
+ {"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"We agreed on JWT tokens with 24-hour expiry. The AuthMiddleware in src/middleware/auth.ts validates every request. API keys are stored hashed with bcrypt, never in plaintext."}]},"timestamp":"2024-01-01T00:03:00Z"}
47
+ {"type":"human","message":{"role":"user","content":[{"type":"text","text":"How should we handle errors globally?"}]},"timestamp":"2024-01-01T00:04:00Z"}
48
+ {"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"All unhandled errors go through the ErrorHandler class in src/middleware/error-handler.ts. It logs to stderr and returns a structured JSON response with code, message, and request ID."}]},"timestamp":"2024-01-01T00:05:00Z"}
49
+ {"type":"human","message":{"role":"user","content":[{"type":"text","text":"What test framework are we using?"}]},"timestamp":"2024-01-01T00:06:00Z"}
50
+ {"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"We chose Vitest over Jest because it's faster with native ESM support. Test files live in src/__tests__/ with .test.ts suffix. Coverage threshold is 80%."}]},"timestamp":"2024-01-01T00:07:00Z"}
51
+ {"type":"human","message":{"role":"user","content":[{"type":"text","text":"How do we deploy?"}]},"timestamp":"2024-01-01T00:08:00Z"}
52
+ {"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"Docker containers pushed to ECR, deployed via ECS Fargate. The Dockerfile uses multi-stage builds: builder stage compiles TypeScript, runtime stage copies dist/ only. No Node dev dependencies in production image."}]},"timestamp":"2024-01-01T00:09:00Z"}
53
+ {"type":"human","message":{"role":"user","content":[{"type":"text","text":"What's the branching strategy?"}]},"timestamp":"2024-01-01T00:10:00Z"}
54
+ {"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"Trunk-based development: main is always deployable. Feature branches merge via PR. We use conventional commits (feat:, fix:, chore:) enforced by commitlint. Semantic-release handles versioning automatically."}]},"timestamp":"2024-01-01T00:11:00Z"}
55
+ FIXTURE
56
+ ```
57
+
58
+ | Step | Command | Expected |
59
+ |------|---------|----------|
60
+ | 2.1 | Create fixture file (above) | File `$LCME2E_DIR/e2e-session.jsonl` exists |
61
+ | 2.2 | `lcm import $LCME2E_DIR/e2e-session.jsonl --cwd $LCME2E_DIR` | Exit 0, prints imported message count |
62
+ | 2.3 | `lcm status --json --cwd $LCME2E_DIR` | JSON contains `conversations` count ≥ 1 |
63
+
64
+ **Pass criteria:** Import exits 0, at least 1 conversation recorded.
65
+
66
+ ---
67
+
68
+ ## Flow 3 — Idempotent Re-import
69
+
70
+ **Goal:** Re-running import on the same file produces no duplicate records.
71
+
72
+ | Step | Command | Expected |
73
+ |------|---------|----------|
74
+ | 3.1 | `lcm status --json --cwd $LCME2E_DIR` (capture baseline count) | Record baseline `conversations` value |
75
+ | 3.2 | `lcm import $LCME2E_DIR/e2e-session.jsonl --cwd $LCME2E_DIR` | Exit 0, prints "0 new" or "already imported" |
76
+ | 3.3 | `lcm status --json --cwd $LCME2E_DIR` | `conversations` count unchanged from 3.1 |
77
+
78
+ **Pass criteria:** Count after re-import equals count before re-import.
79
+
80
+ ---
81
+
82
+ ## Flow 4 — Subagent Import
83
+
84
+ **Goal:** Ingest a subagent transcript and verify it is stored separately.
85
+
86
+ ```bash
87
+ cat > $LCME2E_DIR/e2e-subagent.jsonl << 'FIXTURE'
88
+ {"type":"human","message":{"role":"user","content":[{"type":"text","text":"Subagent task: analyze the database schema"}]},"timestamp":"2024-01-02T00:00:00Z","subagent":true}
89
+ {"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"Schema analysis complete. Found 3 tables: users, sessions, memories. The memories table has a full-text search index on the content column. Foreign key from sessions to users is indexed."}]},"timestamp":"2024-01-02T00:01:00Z","subagent":true}
90
+ FIXTURE
91
+ ```
92
+
93
+ | Step | Command | Expected |
94
+ |------|---------|----------|
95
+ | 4.1 | Create subagent fixture (above) | File exists |
96
+ | 4.2 | `lcm import $LCME2E_DIR/e2e-subagent.jsonl --cwd $LCME2E_DIR` | Exit 0 |
97
+ | 4.3 | `lcm status --json --cwd $LCME2E_DIR` | `conversations` count increased by 1 |
98
+
99
+ **Pass criteria:** Subagent data ingested, total count incremented.
100
+
101
+ ---
102
+
103
+ ## Flow 5 — Compact
104
+
105
+ **Goal:** Run compaction and verify DAG memory nodes are created.
106
+
107
+ | Step | Command | Expected |
108
+ |------|---------|----------|
109
+ | 5.1 | `lcm compact --all --cwd $LCME2E_DIR` | Exit 0, prints nodes created count |
110
+ | 5.2 | `lcm status --json --cwd $LCME2E_DIR` | JSON contains `memories` or `nodes` count ≥ 1 |
111
+
112
+ **Pass criteria:** Compact exits 0, at least 1 memory node exists.
113
+
114
+ ---
115
+
116
+ ## Flow 6 — Promote
117
+
118
+ **Goal:** Run promotion and verify promoted memories exist.
119
+
120
+ | Step | Command | Expected |
121
+ |------|---------|----------|
122
+ | 6.1 | `lcm promote --cwd $LCME2E_DIR` | Exit 0, prints promoted count |
123
+ | 6.2 | `lcm status --json --cwd $LCME2E_DIR` | JSON contains `promoted` count ≥ 1 |
124
+
125
+ **Pass criteria:** Promote exits 0, at least 1 promoted memory.
126
+
127
+ ---
128
+
129
+ ## Flow 7 — Curate (Full Pipeline)
130
+
131
+ **Goal:** Verify the full import → compact → promote pipeline works end-to-end.
132
+
133
+ ```bash
134
+ cat > $LCME2E_DIR/e2e-curate.jsonl << 'FIXTURE'
135
+ {"type":"human","message":{"role":"user","content":[{"type":"text","text":"What logging library should we use?"}]},"timestamp":"2024-01-03T00:00:00Z"}
136
+ {"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"We chose pino over winston for structured logging. It outputs JSON by default and is 5x faster. The LoggerService in src/services/logger.ts wraps pino and adds request-id correlation."}]},"timestamp":"2024-01-03T00:01:00Z"}
137
+ FIXTURE
138
+ ```
139
+
140
+ | Step | Command | Expected |
141
+ |------|---------|----------|
142
+ | 7.1 | Create curate fixture (above) | File exists |
143
+ | 7.2 | `lcm import $LCME2E_DIR/e2e-curate.jsonl --cwd $LCME2E_DIR` | Exit 0 |
144
+ | 7.3 | `lcm compact --all --cwd $LCME2E_DIR` | Exit 0 |
145
+ | 7.4 | `lcm promote --cwd $LCME2E_DIR` | Exit 0 |
146
+ | 7.5 | `lcm status --json --cwd $LCME2E_DIR` | `promoted` count ≥ previous flow value |
147
+
148
+ **Pass criteria:** All three stages exit 0, promoted count non-decreasing.
149
+
150
+ ---
151
+
152
+ ## Flow 8 — Retrieval
153
+
154
+ **Goal:** Verify search, grep, expand, and describe operations return relevant results.
155
+
156
+ | Step | Command | Expected |
157
+ |------|---------|----------|
158
+ | 8.1 | `lcm search "SQLite database" --cwd $LCME2E_DIR` | Returns ≥ 1 result mentioning SQLite |
159
+ | 8.2 | `lcm search "JWT authentication" --cwd $LCME2E_DIR` | Returns ≥ 1 result mentioning JWT |
160
+ | 8.3 | `lcm search "nonexistent-xyzzy-term" --cwd $LCME2E_DIR` | Returns 0 results or empty (no crash) |
161
+ | 8.4 | `lcm search "SQLite" --format json --cwd $LCME2E_DIR` | Valid JSON array output |
162
+
163
+ **Pass criteria:** Steps 8.1 and 8.2 return results; 8.3 does not crash; 8.4 produces valid JSON.
164
+
165
+ ---
166
+
167
+ ## Flow 9 — Restore (SessionStart Hook)
168
+
169
+ **Goal:** Verify the SessionStart hook returns context for a new session.
170
+
171
+ | Step | Command | Expected |
172
+ |------|---------|----------|
173
+ | 9.1 | `lcm hook session-start --cwd $LCME2E_DIR` | Exit 0, returns context JSON or markdown block |
174
+ | 9.2 | Output contains memory content | Response references at least one stored memory |
175
+
176
+ **Pass criteria:** Hook exits 0, returns non-empty context referencing prior conversations.
177
+
178
+ ---
179
+
180
+ ## Flow 10 — UserPromptSubmit Hook
181
+
182
+ **Goal:** Verify the UserPromptSubmit hook returns memory hints for a relevant prompt.
183
+
184
+ | Step | Command | Expected |
185
+ |------|---------|----------|
186
+ | 10.1 | `lcm hook user-prompt-submit --prompt "What database are we using?" --cwd $LCME2E_DIR` | Exit 0, returns hint about SQLite |
187
+ | 10.2 | `lcm hook user-prompt-submit --prompt "xyzzy irrelevant" --cwd $LCME2E_DIR` | Exit 0, returns empty or minimal hint (no crash) |
188
+
189
+ **Pass criteria:** Both commands exit 0; 10.1 returns relevant hint.
190
+
191
+ ---
192
+
193
+ ## Flow 11 — MCP Transport
194
+
195
+ **Goal:** Verify all 7 MCP tools respond without error.
196
+
197
+ | Step | Command | Expected |
198
+ |------|---------|----------|
199
+ | 11.1 | `lcm mcp ping` | Exit 0, returns `pong` or health OK |
200
+ | 11.2 | `lcm mcp list-tools` | Lists ≥ 7 tool names |
201
+ | 11.3 | `lcm mcp call lcm_search '{"query":"SQLite"}' --cwd $LCME2E_DIR` | Returns result JSON |
202
+ | 11.4 | `lcm mcp call lcm_status '{}' --cwd $LCME2E_DIR` | Returns status JSON |
203
+ | 11.5 | `lcm mcp call lcm_compact '{}' --cwd $LCME2E_DIR` | Exit 0 |
204
+ | 11.6 | `lcm mcp call lcm_promote '{}' --cwd $LCME2E_DIR` | Exit 0 |
205
+ | 11.7 | `lcm mcp call lcm_doctor '{}' --cwd $LCME2E_DIR` | Returns health report |
206
+
207
+ **Pass criteria:** All 7 MCP calls exit 0 and return non-empty output.
208
+
209
+ ---
210
+
211
+ ## Flow 12 — Doctor
212
+
213
+ **Goal:** `lcm doctor` reports all checks healthy.
214
+
215
+ | Step | Command | Expected |
216
+ |------|---------|----------|
217
+ | 12.1 | `lcm doctor` | Exit 0 |
218
+ | 12.2 | Output contains no FAIL or ERROR lines | Zero failures in report |
219
+ | 12.3 | Daemon check | Shows daemon as running |
220
+ | 12.4 | Hooks check | Shows hooks as registered |
221
+ | 12.5 | MCP check | Shows MCP server as reachable |
222
+
223
+ **Pass criteria:** Exit 0, no FAIL/ERROR in output, all subsystems healthy.
224
+
225
+ ---
226
+
227
+ ## Flow 13 — Teardown
228
+
229
+ **Goal:** Remove temp directory and associated project data. Always runs at end of full suite.
230
+
231
+ | Step | Command | Expected |
232
+ |------|---------|----------|
233
+ | 13.1 | `PROJECT_HASH=$(lcm status --json --cwd $LCME2E_DIR \| jq -r '.projectHash // empty')` | Hash extracted or empty |
234
+ | 13.2 | `rm -rf $LCME2E_DIR` | Temp dir removed |
235
+ | 13.3 | `[ -n "$PROJECT_HASH" ] && rm -rf ~/.lossless-claude/projects/$PROJECT_HASH` | Project data removed (if hash known) |
236
+ | 13.4 | `ls /tmp/lcm-e2e-test-* 2>/dev/null` | No lcm-e2e-test dirs remain |
237
+
238
+ **Pass criteria:** Temp dir gone, project data cleaned up.
239
+
240
+ ---
241
+
242
+ ## Flow 14 — SessionEnd Hook
243
+
244
+ **Goal:** Verify the SessionEnd hook ingests session data via hook trigger.
245
+
246
+ | Step | Command | Expected |
247
+ |------|---------|----------|
248
+ | 14.1 | Create a fresh temp dir: `HOOK_DIR=$(mktemp -d /tmp/lcm-e2e-test-XXXXXX)` | Dir created |
249
+ | 14.2 | `lcm hook session-end --transcript '{"messages":[{"role":"user","content":"hook test"},{"role":"assistant","content":"hook response stored"}]}' --cwd $HOOK_DIR` | Exit 0 |
250
+ | 14.3 | `lcm status --json --cwd $HOOK_DIR` | `conversations` count ≥ 1 |
251
+ | 14.4 | `rm -rf $HOOK_DIR` | Cleanup |
252
+
253
+ **Pass criteria:** Hook exits 0, conversation recorded in isolated project.
254
+
255
+ ---
256
+
257
+ ## Flow 15 — PreCompact Hook
258
+
259
+ **Goal:** Verify the PreCompact hook returns exit code 2 to signal Claude to proceed.
260
+
261
+ | Step | Command | Expected |
262
+ |------|---------|----------|
263
+ | 15.1 | `lcm hook pre-compact --cwd $LCME2E_DIR` | Exit code 2 (not 0 or 1) |
264
+ | 15.2 | Output contains memory summary or context | Non-empty stdout |
265
+
266
+ **Pass criteria:** Exit code is exactly 2, stdout is non-empty.
267
+
268
+ ---
269
+
270
+ ## Flow 16 — Auto-heal (Read-only in Live Mode)
271
+
272
+ **Goal:** Verify hooks are registered in Claude Code config. READ-ONLY — does not modify hooks.
273
+
274
+ | Step | Command | Expected |
275
+ |------|---------|----------|
276
+ | 16.1 | `lcm hooks list` | Lists registered hooks |
277
+ | 16.2 | Output contains `session-start` | SessionStart hook present |
278
+ | 16.3 | Output contains `session-end` | SessionEnd hook present |
279
+ | 16.4 | Output contains `pre-compact` | PreCompact hook present |
280
+ | 16.5 | Output contains `user-prompt-submit` | UserPromptSubmit hook present |
281
+
282
+ **Pass criteria:** All 4 hook types are registered. No modifications made.
283
+
284
+ ---
285
+
286
+ ## Flow 17 — Scrubbing
287
+
288
+ **Goal:** Verify sensitive patterns are redacted before storage.
289
+
290
+ ```bash
291
+ cat > $LCME2E_DIR/e2e-sensitive.jsonl << 'FIXTURE'
292
+ {"type":"human","message":{"role":"user","content":[{"type":"text","text":"The API key is sk-1234567890abcdef and the password is hunter2. Connect via postgres://admin:secret@localhost/db"}]},"timestamp":"2024-01-04T00:00:00Z"}
293
+ {"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"I'll help you configure the connection. I've noted the credentials."}]},"timestamp":"2024-01-04T00:01:00Z"}
294
+ FIXTURE
295
+ ```
296
+
297
+ | Step | Command | Expected |
298
+ |------|---------|----------|
299
+ | 17.1 | Create sensitive fixture (above) | File created |
300
+ | 17.2 | `lcm import $LCME2E_DIR/e2e-sensitive.jsonl --cwd $LCME2E_DIR` | Exit 0 |
301
+ | 17.3 | `lcm search "sk-1234" --cwd $LCME2E_DIR` | Returns 0 results (key redacted) |
302
+ | 17.4 | `lcm search "hunter2" --cwd $LCME2E_DIR` | Returns 0 results (password redacted) |
303
+ | 17.5 | `lcm search "postgres://admin" --cwd $LCME2E_DIR` | Returns 0 results (connection string redacted) |
304
+
305
+ **Pass criteria:** None of the 3 sensitive patterns are findable via search.
306
+
307
+ ---
308
+
309
+ ## Flow 18 — Daemon-down Resilience
310
+
311
+ **Goal:** Hooks fail gracefully when daemon is not running.
312
+
313
+ | Step | Command | Expected |
314
+ |------|---------|----------|
315
+ | 18.1 | `lcm daemon stop` | Daemon stops (or already stopped) |
316
+ | 18.2 | `lcm hook session-start --cwd $LCME2E_DIR` | Exits non-zero OR exits 0 with empty/fallback context (no crash/hang) |
317
+ | 18.3 | `lcm hook user-prompt-submit --prompt "test" --cwd $LCME2E_DIR` | Exits non-zero OR exits 0 with empty hint (no crash/hang) |
318
+ | 18.4 | `lcm daemon start --detach` | Daemon restarts successfully |
319
+ | 18.5 | `lcm status --json` | Daemon running again |
320
+
321
+ **Pass criteria:** Hooks do not crash or hang when daemon is down; daemon restarts cleanly.
322
+
323
+ ---
324
+
325
+ ## Flow 19 — Status
326
+
327
+ **Goal:** `lcm status` returns correct state fields.
328
+
329
+ | Step | Command | Expected |
330
+ |------|---------|----------|
331
+ | 19.1 | `lcm status` | Exit 0, human-readable output |
332
+ | 19.2 | `lcm status --json` | Exit 0, valid JSON |
333
+ | 19.3 | JSON contains `daemon` field | `daemon` is `"running"` |
334
+ | 19.4 | JSON contains `version` field | Non-empty version string |
335
+ | 19.5 | JSON contains `projects` or `projectCount` field | Numeric value ≥ 0 |
336
+
337
+ **Pass criteria:** Both plain and JSON output succeed, all expected fields present.
338
+
339
+ ---
340
+
341
+ ## Summary Table
342
+
343
+ Fill in ✓ (pass) or ✗ (fail) after running each flow. Add notes for any failures.
344
+
345
+ | Flow | Status | Notes |
346
+ |------|--------|-------|
347
+ | 1 — Environment | ✓ / ✗ | |
348
+ | 2 — Import | ✓ / ✗ | |
349
+ | 3 — Idempotent re-import | ✓ / ✗ | |
350
+ | 4 — Subagent import | ✓ / ✗ | |
351
+ | 5 — Compact | ✓ / ✗ | |
352
+ | 6 — Promote | ✓ / ✗ | |
353
+ | 7 — Curate | ✓ / ✗ | |
354
+ | 8 — Retrieval | ✓ / ✗ | |
355
+ | 9 — Restore (SessionStart) | ✓ / ✗ | |
356
+ | 10 — UserPromptSubmit | ✓ / ✗ | |
357
+ | 11 — MCP transport | ✓ / ✗ | |
358
+ | 12 — Doctor | ✓ / ✗ | |
359
+ | 13 — Teardown | ✓ / ✗ | |
360
+ | 14 — SessionEnd hook | ✓ / ✗ | |
361
+ | 15 — PreCompact hook | ✓ / ✗ | |
362
+ | 16 — Auto-heal | ✓ / ✗ | |
363
+ | 17 — Scrubbing | ✓ / ✗ | |
364
+ | 18 — Daemon-down resilience | ✓ / ✗ | |
365
+ | 19 — Status | ✓ / ✗ | |
366
+
367
+ **Result:** _N/19 flows passed_
@@ -0,0 +1,47 @@
1
+ ---
2
+ name: lossless-claude-upgrade
3
+ description: |
4
+ Rebuild, reinstall, and restart lossless-claude from source.
5
+ Fixes hooks, restarts daemon, runs diagnostics.
6
+ Trigger: /lossless-claude:upgrade
7
+ user-invocable: true
8
+ ---
9
+
10
+ # lossless-claude Upgrade (lcm)
11
+
12
+ Rebuild from source, restart daemon, and verify installation.
13
+
14
+ ## Instructions
15
+
16
+ 1. Derive the **repo root** from this skill's base directory (go up 3 levels — remove `/skills/lossless-claude-upgrade` from the path, then remove `.claude-plugin`).
17
+ 2. Run with Bash:
18
+ ```
19
+ cd <REPO_ROOT> && npm run build && npm link
20
+ ```
21
+ 3. Restart daemon with Bash:
22
+ ```
23
+ PID_FILE="$HOME/.lossless-claude/daemon.pid"
24
+ if [ -f "$PID_FILE" ]; then
25
+ PID=$(cat "$PID_FILE")
26
+ if ps -p "$PID" -o args= 2>/dev/null | grep -q 'lcm.*daemon'; then
27
+ kill "$PID" 2>/dev/null
28
+ fi
29
+ rm -f "$PID_FILE"
30
+ fi
31
+ lcm daemon start --detach
32
+ ```
33
+ 4. Run doctor with Bash:
34
+ ```
35
+ lcm doctor
36
+ ```
37
+ 5. **IMPORTANT**: After all Bash commands complete, re-display key results as markdown text directly in the conversation. Format as:
38
+ ```
39
+ ## lossless-claude upgrade
40
+ - [x] Built from source
41
+ - [x] npm linked globally
42
+ - [x] Daemon restarted (PID XXXX)
43
+ - [x] Hooks configured
44
+ - [x] Doctor: all checks PASS
45
+ ```
46
+ Use `[x]` for success, `[ ]` for failure. Show actual version and any warnings.
47
+ Tell the user to **restart their Claude Code session** to pick up the new version.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Josh Lehman / Martian Engineering
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,231 @@
1
+ <p align="center">
2
+ <strong>lossless-claude</strong><br>
3
+ Shared memory infrastructure for Claude Code
4
+ </p>
5
+
6
+ <p align="center">
7
+ DAG-based summarization, SQLite-backed message persistence, promoted long-term memory, MCP retrieval tools
8
+ </p>
9
+
10
+ <p align="center">
11
+ <a href="https://www.npmjs.com/package/@lossless-claude/lcm"><img src="https://img.shields.io/npm/v/@lossless-claude/lcm" alt="npm"></a>
12
+ <a href="LICENSE"><img src="https://img.shields.io/github/license/lossless-claude/lcm" alt="License: MIT"></a>
13
+ <a href="package.json"><img src="https://img.shields.io/node/v/@lossless-claude/lcm" alt="Node"></a>
14
+ <a href="https://github.com/anthropics/claude-code"><img src="https://img.shields.io/badge/Claude_Code-hooks%20%2B%20MCP-7c3aed" alt="Claude Code"></a>
15
+ </p>
16
+
17
+ <p align="center">
18
+ <a href="https://lossless-claude.com">Website</a> &bull;
19
+ <a href="#runtime-model">Runtime Model</a> &bull;
20
+ <a href="#installation">Installation</a> &bull;
21
+ <a href="#mcp-tools">MCP Tools</a> &bull;
22
+ <a href="#development">Development</a>
23
+ </p>
24
+
25
+ ---
26
+
27
+ `lossless-claude` replaces sliding-window forgetfulness with a persistent memory runtime for both humans and agents.
28
+
29
+ - Every message is stored in a project SQLite database.
30
+ - Older context is compacted into a DAG of summaries instead of being dropped.
31
+ - Durable decisions and findings are promoted into cross-session memory.
32
+ - Claude Code reads and writes project memory across sessions.
33
+
34
+ Humans and agents use the same backend. The integration surface differs by client, but the memory model is shared.
35
+
36
+ This repo started as a fork of [lossless-claw](https://github.com/Martian-Engineering/lossless-claude) by [Martian Engineering](https://martian.engineering), adapted for Claude Code. The LCM model and DAG architecture originate from the [Voltropy paper](https://papers.voltropy.com/LCM).
37
+
38
+ ## Runtime Model
39
+
40
+ ```mermaid
41
+ flowchart LR
42
+ subgraph Clients["Clients"]
43
+ CC["Claude Code<br/>hooks + MCP"]
44
+ end
45
+
46
+ CC --> D["lossless-claude daemon"]
47
+
48
+ D --> DB[("project SQLite DAG")]
49
+ D --> PM[("promoted memory FTS5")]
50
+ D --> TOOLS["MCP tools<br/>search / grep / expand / describe / store / stats / doctor"]
51
+ ```
52
+
53
+ ### Capabilities by integration path
54
+
55
+ | Path | Restore | Prompt hints | Turn writeback | Automatic compaction | Notes |
56
+ |---|---|---|---|---|---|
57
+ | Claude Code | Yes | Yes | Yes, via transcript/hooks | Yes | Primary hook-based integration |
58
+
59
+ ## LCM Model
60
+
61
+ | Phase | What happens |
62
+ |---|---|
63
+ | Persist | Raw messages are stored in SQLite per conversation |
64
+ | Summarize | Older messages are grouped into leaf summaries |
65
+ | Condense | Summaries roll up into higher-level DAG nodes |
66
+ | Promote | Durable insights are copied into cross-session memory |
67
+ | Restore | New sessions recover context from summaries and promoted memory |
68
+ | Recall | Agents query, expand, and inspect memory on demand |
69
+
70
+ Nothing is dropped. Raw messages remain in the database. Summaries point back to their sources. Promoted memory remains searchable across sessions.
71
+
72
+ ```mermaid
73
+ flowchart TD
74
+ A["conversation / tool output"] --> B["persist raw messages"]
75
+ B --> C["compact into leaf summaries"]
76
+ C --> D["condense into deeper DAG nodes"]
77
+ C --> E["promote durable insights"]
78
+ D --> F["restore future context"]
79
+ E --> F
80
+ F --> G["search / grep / describe / expand / store"]
81
+ ```
82
+
83
+ ## Installation
84
+
85
+ ### Prerequisites
86
+
87
+ - Node.js 22+
88
+ - Claude Code for hook-based Claude integration
89
+
90
+ ### Claude Code
91
+
92
+ Install the `lcm` binary first:
93
+
94
+ ```bash
95
+ npm install -g @lossless-claude/lcm # provides the `lcm` command
96
+ ```
97
+
98
+ ```bash
99
+ claude plugin add github:lossless-claude/lcm
100
+ lcm install
101
+ ```
102
+
103
+ `lcm install` writes config, registers hooks, installs slash commands, registers MCP, and verifies the daemon.
104
+
105
+ ## Hooks
106
+
107
+ Claude Code uses four hooks. All hooks auto-heal: each validates that all required entries remain registered and repairs missing entries before continuing.
108
+
109
+ | Hook | Command | Purpose |
110
+ |---|---|---|
111
+ | `PreCompact` | `lcm compact` | Intercepts compaction and writes DAG summaries |
112
+ | `SessionStart` | `lcm restore` | Restores project context, recent summaries, and promoted memory |
113
+ | `SessionEnd` | `lcm session-end` | Ingests the completed Claude transcript |
114
+ | `UserPromptSubmit` | `lcm user-prompt` | Searches memory and injects prompt-time hints |
115
+
116
+ ```mermaid
117
+ flowchart LR
118
+ SS["SessionStart"] --> CONV["Conversation"]
119
+ CONV --> UP["UserPromptSubmit<br/>(each prompt)"]
120
+ UP --> CONV
121
+ CONV --> PC["PreCompact<br/>(if context fills)"]
122
+ PC --> CONV
123
+ CONV --> SE["SessionEnd"]
124
+ ```
125
+
126
+ ## MCP Tools
127
+
128
+ | Tool | Purpose |
129
+ |---|---|
130
+ | `lcm_search` | Search episodic and promoted knowledge |
131
+ | `lcm_grep` | Regex or full-text search across stored history |
132
+ | `lcm_expand` | Recover deeper detail from compacted history |
133
+ | `lcm_describe` | Inspect a stored summary or file by id |
134
+ | `lcm_store` | Persist durable memory manually |
135
+ | `lcm_stats` | Inspect memory coverage, DAG depth, and compression |
136
+ | `lcm_doctor` | Diagnose daemon, hooks, MCP registration, and summarizer setup |
137
+
138
+ ## CLI
139
+
140
+ ```bash
141
+ lcm install # setup wizard
142
+ lcm doctor # diagnostics
143
+ lcm stats # memory and compression overview
144
+ lcm stats -v # per-conversation breakdown
145
+ lcm status # daemon + summarizer mode
146
+ lcm daemon start --detach # start daemon in background
147
+ lcm compact # PreCompact hook handler
148
+ lcm restore # SessionStart hook handler
149
+ lcm session-end # SessionEnd hook handler
150
+ lcm user-prompt # UserPromptSubmit hook handler
151
+ lcm mcp # MCP server
152
+ lcm -v # version
153
+ ```
154
+
155
+ ## Configuration
156
+
157
+ All environment variables are optional. The default summarizer mode is `auto`.
158
+
159
+ | Variable | Default | Description |
160
+ |---|---|---|
161
+ | `LCM_SUMMARY_PROVIDER` | `auto` | `auto`, `claude-process`, `codex-process`, `anthropic`, `openai`, or `disabled` |
162
+ | `LCM_SUMMARY_MODEL` | unset | Optional model override for the selected summarizer provider |
163
+ | `LCM_CONTEXT_THRESHOLD` | `0.75` | Context fill ratio that triggers compaction |
164
+ | `LCM_FRESH_TAIL_COUNT` | `32` | Most recent raw messages protected from compaction |
165
+ | `LCM_LEAF_MIN_FANOUT` | `8` | Minimum raw messages per leaf summary |
166
+ | `LCM_CONDENSED_MIN_FANOUT` | `4` | Minimum summaries per condensed node |
167
+ | `LCM_INCREMENTAL_MAX_DEPTH` | `0` | Automatic condensation depth |
168
+ | `LCM_LEAF_CHUNK_TOKENS` | `20000` | Maximum source tokens per leaf compaction pass |
169
+ | `LCM_LEAF_TARGET_TOKENS` | `1200` | Target size for leaf summaries |
170
+ | `LCM_CONDENSED_TARGET_TOKENS` | `2000` | Target size for condensed summaries |
171
+
172
+ `auto` resolves per caller:
173
+
174
+ - `lcm` -> `claude-process`
175
+ - explicit config or `LCM_SUMMARY_PROVIDER` override always takes precedence
176
+
177
+ See [`docs/configuration.md`](docs/configuration.md) for tuning notes and deeper operational guidance.
178
+
179
+ ## Development
180
+
181
+ ```bash
182
+ npm install
183
+ npm run build
184
+ npx vitest
185
+ npx tsc --noEmit
186
+ ```
187
+
188
+ ### Repository layout
189
+
190
+ ```text
191
+ bin/
192
+ lcm.ts CLI entry point (binary: lcm)
193
+ src/
194
+ compaction.ts DAG compaction engine
195
+ connectors/ client integration adapters
196
+ daemon/ HTTP daemon, lifecycle, config, routes
197
+ db/ SQLite schema + promoted memory
198
+ hooks/ Claude hook handlers + auto-heal
199
+ llm/ summarizer backends
200
+ mcp/ MCP server + tool definitions
201
+ store/ conversation and summary persistence
202
+ installer/
203
+ install.ts setup wizard
204
+ uninstall.ts cleanup
205
+ test/
206
+ ... Vitest suites
207
+ ```
208
+
209
+ ## Privacy
210
+
211
+ All conversation data is stored locally in `~/.lossless-claude/`. Nothing is sent to any lossless-claude server.
212
+
213
+ If you configure an external summarizer (`claude-process`, `anthropic`, `openai`, etc.), messages are sent to that provider for summarization — after built-in secret redaction. lossless-claude scrubs common secret patterns (API keys, tokens, passwords) from message content before writing to SQLite and before sending to the summarizer.
214
+
215
+ Add project-specific patterns with `lcm sensitive add "MY_PATTERN"`. See [docs/privacy.md](docs/privacy.md) for full details.
216
+
217
+ ## Technical Notes
218
+
219
+ - Claude Code integration is hook-first.
220
+ - The daemon is shared; the memory backend is client-agnostic.
221
+ - The repo carries the original lossless-claw lineage; the current runtime is Claude Code oriented.
222
+
223
+ ## Acknowledgments
224
+
225
+ `lossless-claude` stands on the shoulders of [lossless-claw](https://github.com/Martian-Engineering/lossless-claude), the original implementation by [Martian Engineering](https://martian.engineering). The DAG-based compaction architecture, the LCM memory model, and the foundational design decisions all originate there.
226
+
227
+ The underlying theory comes from the [LCM paper](https://papers.voltropy.com/LCM) by [Voltropy](https://x.com/Voltropy).
228
+
229
+ ## License
230
+
231
+ MIT
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};