@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,205 @@
1
+ import { spawn } from "node:child_process";
2
+ import { readFileSync, writeFileSync, unlinkSync, existsSync } from "node:fs";
3
+ import { homedir } from "node:os";
4
+ import { join } from "node:path";
5
+ function sleep(ms) {
6
+ return new Promise((r) => setTimeout(r, ms));
7
+ }
8
+ function isProcessAlive(pid, killCheck) {
9
+ if (killCheck)
10
+ return killCheck(pid);
11
+ try {
12
+ process.kill(pid, 0);
13
+ return true;
14
+ }
15
+ catch {
16
+ return false;
17
+ }
18
+ }
19
+ export function createClaudeCliProxyManager(opts) {
20
+ const port = opts.port;
21
+ const pidFilePath = opts.pidFilePath ?? join(homedir(), ".lossless-claude", "lcm-proxy.pid");
22
+ const healthPollIntervalMs = opts.healthPollIntervalMs ?? 500;
23
+ const healthMonitorIntervalMs = opts.healthMonitorIntervalMs ?? 30_000;
24
+ const maxHealthMisses = opts.maxHealthMisses ?? 3;
25
+ const fetchFn = opts._fetchOverride ?? globalThis.fetch;
26
+ const healthURL = `http://localhost:${port}/health`;
27
+ let child = null;
28
+ let _available = false;
29
+ let monitorTimer = null;
30
+ let hasAttemptedRestart = false;
31
+ let startPromise = null;
32
+ async function checkHealth() {
33
+ try {
34
+ const res = await fetchFn(healthURL);
35
+ if (!res.ok)
36
+ return { ok: false, isClaudeServer: false };
37
+ const body = await res.json();
38
+ const isClaudeServer = body?.service === "claude-server";
39
+ return { ok: true, isClaudeServer };
40
+ }
41
+ catch {
42
+ return { ok: false, isClaudeServer: false };
43
+ }
44
+ }
45
+ async function waitForHealth() {
46
+ const deadline = Date.now() + opts.startupTimeoutMs;
47
+ while (Date.now() < deadline) {
48
+ const { ok, isClaudeServer } = await checkHealth();
49
+ if (ok && isClaudeServer)
50
+ return true;
51
+ if (ok && !isClaudeServer)
52
+ return false; // foreign process on port
53
+ await sleep(healthPollIntervalMs);
54
+ }
55
+ return false;
56
+ }
57
+ function spawnChild() {
58
+ const cp = spawn("claude-server", ["--port", String(port), "--model", opts.model], {
59
+ stdio: ["ignore", "ignore", "pipe"],
60
+ detached: false,
61
+ });
62
+ cp.stderr?.on("data", () => { }); // drain stderr to prevent buffer fill
63
+ cp.unref();
64
+ return cp;
65
+ }
66
+ function writePid(pid) {
67
+ writeFileSync(pidFilePath, String(pid));
68
+ }
69
+ function deletePidFile() {
70
+ try {
71
+ if (existsSync(pidFilePath))
72
+ unlinkSync(pidFilePath);
73
+ }
74
+ catch { /* ignore */ }
75
+ }
76
+ function startHealthMonitor() {
77
+ if (monitorTimer)
78
+ return;
79
+ let consecutiveMisses = 0;
80
+ monitorTimer = setInterval(async () => {
81
+ const { ok, isClaudeServer } = await checkHealth();
82
+ if (ok && isClaudeServer) {
83
+ consecutiveMisses = 0;
84
+ return;
85
+ }
86
+ consecutiveMisses++;
87
+ if (consecutiveMisses >= maxHealthMisses) {
88
+ stopHealthMonitor();
89
+ if (!hasAttemptedRestart) {
90
+ hasAttemptedRestart = true;
91
+ console.warn("[lcm] claude-server health check failed — attempting restart...");
92
+ try {
93
+ await doStart();
94
+ }
95
+ catch {
96
+ console.warn("[lcm] claude-server unavailable. Run 'claude login' to authenticate,\n" +
97
+ " then restart Claude Code. Alternatively, set LCM_SUMMARY_PROVIDER=anthropic\n" +
98
+ " and LCM_SUMMARY_API_KEY=<key> to use the Anthropic API directly.");
99
+ _available = false;
100
+ deletePidFile();
101
+ }
102
+ }
103
+ else {
104
+ console.warn("[lcm] claude-server unavailable after restart attempt. Summarization disabled for this session.");
105
+ _available = false;
106
+ deletePidFile();
107
+ }
108
+ }
109
+ }, healthMonitorIntervalMs);
110
+ }
111
+ function stopHealthMonitor() {
112
+ if (monitorTimer) {
113
+ clearInterval(monitorTimer);
114
+ monitorTimer = null;
115
+ }
116
+ }
117
+ async function _doStartInternal() {
118
+ // Step 1: Check existing PID file
119
+ if (existsSync(pidFilePath)) {
120
+ try {
121
+ const pid = parseInt(readFileSync(pidFilePath, "utf-8").trim(), 10);
122
+ if (!isNaN(pid) && isProcessAlive(pid, opts._killCheck)) {
123
+ // Process alive — check if it's actually claude-server
124
+ const { ok, isClaudeServer } = await checkHealth();
125
+ if (ok && isClaudeServer) {
126
+ _available = true;
127
+ startHealthMonitor();
128
+ return; // reuse existing process
129
+ }
130
+ }
131
+ }
132
+ catch { /* ignore read errors */ }
133
+ // Stale PID or wrong service — clean up
134
+ deletePidFile();
135
+ }
136
+ // Step 2: Spawn new process
137
+ child = spawnChild();
138
+ child.on("error", (err) => {
139
+ console.warn(`[lcm] claude-server spawn error: ${err.message}`);
140
+ _available = false;
141
+ deletePidFile();
142
+ child = null;
143
+ });
144
+ if (child.pid)
145
+ writePid(child.pid);
146
+ // Handle child exit
147
+ child.on("exit", () => {
148
+ child = null;
149
+ });
150
+ // Step 3: Wait for health
151
+ const healthy = await waitForHealth();
152
+ if (healthy) {
153
+ _available = true;
154
+ startHealthMonitor();
155
+ }
156
+ else {
157
+ // Check if it's a foreign process on the port
158
+ const { ok, isClaudeServer } = await checkHealth();
159
+ if (ok && !isClaudeServer) {
160
+ console.warn(`[lcm] Port ${port} is occupied by another service. claude-server cannot start.`);
161
+ }
162
+ else {
163
+ console.warn("[lcm] claude-server unavailable. Run 'claude login' to authenticate,\n" +
164
+ " then restart Claude Code. Alternatively, set LCM_SUMMARY_PROVIDER=anthropic\n" +
165
+ " and LCM_SUMMARY_API_KEY=<key> to use the Anthropic API directly.");
166
+ }
167
+ // Kill the child we spawned since it's not healthy
168
+ if (child) {
169
+ child.kill("SIGTERM");
170
+ child = null;
171
+ }
172
+ _available = false;
173
+ deletePidFile();
174
+ }
175
+ }
176
+ async function doStart() {
177
+ if (startPromise)
178
+ return startPromise;
179
+ startPromise = _doStartInternal().finally(() => { startPromise = null; });
180
+ return startPromise;
181
+ }
182
+ const manager = {
183
+ get port() { return port; },
184
+ get available() { return _available; },
185
+ async start() {
186
+ await doStart();
187
+ },
188
+ async stop() {
189
+ stopHealthMonitor();
190
+ hasAttemptedRestart = false;
191
+ if (child) {
192
+ child.kill("SIGTERM");
193
+ child = null;
194
+ }
195
+ _available = false;
196
+ deletePidFile();
197
+ },
198
+ async isHealthy() {
199
+ const { ok, isClaudeServer } = await checkHealth();
200
+ return ok && isClaudeServer;
201
+ },
202
+ };
203
+ return manager;
204
+ }
205
+ //# sourceMappingURL=proxy-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy-manager.js","sourceRoot":"","sources":["../../../src/daemon/proxy-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { DaemonConfig } from "../config.js";
2
+ import type { RouteHandler } from "../server.js";
3
+ export declare function buildCompactionMessage(p: {
4
+ tokensBefore: number;
5
+ tokensAfter: number;
6
+ messageCount: number;
7
+ summaryCount: number;
8
+ maxDepth: number;
9
+ promotedCount: number;
10
+ }): string;
11
+ export declare const justCompactedMap: Map<string, number>;
12
+ export declare const JUST_COMPACTED_TTL_MS = 30000;
13
+ export declare function createCompactHandler(config: DaemonConfig): RouteHandler;
@@ -0,0 +1,195 @@
1
+ import { readFileSync, writeFileSync, existsSync } from "node:fs";
2
+ import { DatabaseSync } from "node:sqlite";
3
+ import { projectId, projectDbPath, projectDir, projectMetaPath, ensureProjectDir } from "../project.js";
4
+ import { enqueue } from "../project-queue.js";
5
+ import { sendJson } from "../server.js";
6
+ import { runLcmMigrations } from "../../db/migration.js";
7
+ import { upsertRedactionCounts } from "../../db/redaction-stats.js";
8
+ import { ConversationStore } from "../../store/conversation-store.js";
9
+ import { SummaryStore } from "../../store/summary-store.js";
10
+ import { CompactionEngine } from "../../compaction.js";
11
+ import { parseTranscript } from "../../transcript.js";
12
+ import { ScrubEngine } from "../../scrub.js";
13
+ import { resolveEffectiveProvider, createSummarizer } from "../summarizer.js";
14
+ function fmtN(n) {
15
+ if (n >= 1_000_000)
16
+ return (n / 1_000_000).toFixed(1) + "M";
17
+ if (n >= 1_000)
18
+ return (n / 1_000).toFixed(1) + "K";
19
+ return String(n);
20
+ }
21
+ export function buildCompactionMessage(p) {
22
+ const saved = p.tokensBefore - p.tokensAfter;
23
+ const ratio = p.tokensAfter > 0 ? (p.tokensBefore / p.tokensAfter).toFixed(1) : "–";
24
+ const pct = p.tokensBefore > 0
25
+ ? ((1 - p.tokensAfter / p.tokensBefore) * 100).toFixed(1)
26
+ : "0.0";
27
+ const barWidth = 30;
28
+ const filled = p.tokensBefore > 0
29
+ ? Math.round((1 - p.tokensAfter / p.tokensBefore) * barWidth) : 0;
30
+ const bar = "█".repeat(filled) + "░".repeat(barWidth - filled);
31
+ const border = "━".repeat(46);
32
+ const numW = Math.max(String(p.messageCount).length, String(p.summaryCount).length, String(p.maxDepth).length, String(p.promotedCount).length, 1);
33
+ const pad = (n) => String(n).padStart(numW);
34
+ const rows = [
35
+ ` ${pad(p.messageCount)} messages → ${p.summaryCount} summaries`,
36
+ ` ${pad(p.maxDepth)} DAG layers deep`,
37
+ ...(p.promotedCount > 0
38
+ ? [` ${pad(p.promotedCount)} insight${p.promotedCount > 1 ? "s" : ""} promoted to long-term memory`]
39
+ : []),
40
+ ];
41
+ return [
42
+ border,
43
+ ` 🧠 lossless-claude · compaction complete`,
44
+ border,
45
+ ``,
46
+ ` ${fmtN(p.tokensBefore)} ──────────────────────→ ${fmtN(p.tokensAfter)}`,
47
+ ` ${bar} ${pct}% saved`,
48
+ ` ${ratio}× compression · ${fmtN(saved)} tokens freed`,
49
+ ``,
50
+ ...rows,
51
+ ``,
52
+ border,
53
+ ` Nothing was lost. Everything is remembered.`,
54
+ border,
55
+ ].join("\n");
56
+ }
57
+ // In-memory justCompacted map (session_id -> timestamp)
58
+ export const justCompactedMap = new Map();
59
+ export const JUST_COMPACTED_TTL_MS = 30_000;
60
+ // Guard against concurrent compactions for the same session
61
+ const compactingNow = new Set();
62
+ export function createCompactHandler(config) {
63
+ const summarizerCache = new Map();
64
+ const getSummarizer = (provider) => {
65
+ let cached = summarizerCache.get(provider);
66
+ if (!cached) {
67
+ cached = createSummarizer(provider, config);
68
+ summarizerCache.set(provider, cached);
69
+ }
70
+ return cached;
71
+ };
72
+ return async (_req, res, body) => {
73
+ const input = JSON.parse(body || "{}");
74
+ const { session_id, cwd, transcript_path, skip_ingest, client } = input;
75
+ if (!session_id || !cwd) {
76
+ sendJson(res, 400, { error: "session_id and cwd are required" });
77
+ return;
78
+ }
79
+ const summarize = await getSummarizer(resolveEffectiveProvider(config, client));
80
+ if (!summarize) {
81
+ sendJson(res, 200, { summary: "Summarization disabled — no summarizer configured." });
82
+ return;
83
+ }
84
+ if (compactingNow.has(session_id)) {
85
+ sendJson(res, 200, { skipped: true, summary: "Compaction already in progress for this session." });
86
+ return;
87
+ }
88
+ compactingNow.add(session_id);
89
+ try {
90
+ const pid = projectId(cwd);
91
+ const result = await enqueue(pid, async () => {
92
+ const dbPath = projectDbPath(cwd);
93
+ ensureProjectDir(cwd);
94
+ const scrubber = await ScrubEngine.forProject(config.security?.sensitivePatterns ?? [], projectDir(cwd));
95
+ const db = new DatabaseSync(dbPath);
96
+ try {
97
+ db.exec("PRAGMA busy_timeout = 5000");
98
+ runLcmMigrations(db);
99
+ const conversationStore = new ConversationStore(db);
100
+ const summaryStore = new SummaryStore(db);
101
+ const conversation = await conversationStore.getOrCreateConversation(session_id);
102
+ // Ingest new messages from the transcript into the DB.
103
+ if (!skip_ingest && transcript_path && existsSync(transcript_path)) {
104
+ const parsed = parseTranscript(transcript_path);
105
+ const storedCount = await conversationStore.getMessageCount(conversation.conversationId);
106
+ const newMessages = parsed.slice(storedCount);
107
+ if (newMessages.length > 0) {
108
+ const ingestCounts = { builtIn: 0, global: 0, project: 0 };
109
+ const inputs = newMessages.map((m, i) => {
110
+ const { text: scrubbedContent, builtIn, global: globalCount, project } = scrubber.scrubWithCounts(m.content);
111
+ ingestCounts.builtIn += builtIn;
112
+ ingestCounts.global += globalCount;
113
+ ingestCounts.project += project;
114
+ return {
115
+ conversationId: conversation.conversationId,
116
+ seq: storedCount + i,
117
+ role: m.role,
118
+ content: scrubbedContent,
119
+ tokenCount: m.tokenCount,
120
+ };
121
+ });
122
+ await conversationStore.withTransaction(async () => {
123
+ const records = await conversationStore.createMessagesBulk(inputs);
124
+ upsertRedactionCounts(db, pid, ingestCounts);
125
+ await summaryStore.appendContextMessages(conversation.conversationId, records.map((r) => r.messageId));
126
+ });
127
+ }
128
+ }
129
+ // Check if there's anything to compact
130
+ const tokenCount = await summaryStore.getContextTokenCount(conversation.conversationId);
131
+ if (tokenCount === 0) {
132
+ return { summary: "No messages to compact." };
133
+ }
134
+ const engine = new CompactionEngine(conversationStore, summaryStore, {
135
+ contextThreshold: 0.75,
136
+ freshTailCount: 8,
137
+ leafMinFanout: 3,
138
+ condensedMinFanout: 2,
139
+ condensedMinFanoutHard: 1,
140
+ incrementalMaxDepth: 0,
141
+ leafTargetTokens: config.compaction.leafTokens,
142
+ condensedTargetTokens: 900,
143
+ maxRounds: 10,
144
+ scrubber,
145
+ });
146
+ const compactResult = await engine.compact({
147
+ conversationId: conversation.conversationId,
148
+ tokenBudget: 200_000,
149
+ summarize,
150
+ force: true,
151
+ });
152
+ // Gather stats for the compaction message (always, regardless of actionTaken)
153
+ const allSummaries = await summaryStore.getSummariesByConversation(conversation.conversationId);
154
+ const finalMsgCount = await conversationStore.getMessageCount(conversation.conversationId);
155
+ const maxDepth = allSummaries.length > 0 ? Math.max(...allSummaries.map((s) => s.depth)) : 0;
156
+ // Promotion is now handled by the standalone /promote route
157
+ const promotedCount = 0;
158
+ // Update meta.json
159
+ try {
160
+ const metaPath = projectMetaPath(cwd);
161
+ let meta = {};
162
+ if (existsSync(metaPath)) {
163
+ meta = JSON.parse(readFileSync(metaPath, "utf-8"));
164
+ }
165
+ meta.cwd = cwd;
166
+ meta.lastCompact = new Date().toISOString();
167
+ writeFileSync(metaPath, JSON.stringify(meta, null, 2));
168
+ }
169
+ catch { /* non-fatal */ }
170
+ // Set justCompacted flag
171
+ justCompactedMap.set(session_id, Date.now());
172
+ const summaryMsg = compactResult.actionTaken
173
+ ? buildCompactionMessage({
174
+ tokensBefore: compactResult.tokensBefore,
175
+ tokensAfter: compactResult.tokensAfter,
176
+ messageCount: finalMsgCount,
177
+ summaryCount: allSummaries.length,
178
+ maxDepth,
179
+ promotedCount,
180
+ })
181
+ : "No compaction needed.";
182
+ return { summary: summaryMsg };
183
+ }
184
+ finally {
185
+ db.close();
186
+ }
187
+ }); // end enqueue
188
+ sendJson(res, 200, result);
189
+ }
190
+ finally {
191
+ compactingNow.delete(session_id);
192
+ }
193
+ };
194
+ }
195
+ //# sourceMappingURL=compact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compact.js","sourceRoot":"","sources":["../../../../src/daemon/routes/compact.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { DaemonConfig } from "../config.js";
2
+ import type { RouteHandler } from "../server.js";
3
+ export declare function createDescribeHandler(_config: DaemonConfig): RouteHandler;
@@ -0,0 +1,39 @@
1
+ import { existsSync, mkdirSync } from "node:fs";
2
+ import { dirname } from "node:path";
3
+ import { DatabaseSync } from "node:sqlite";
4
+ import { projectDbPath } from "../project.js";
5
+ import { sendJson } from "../server.js";
6
+ import { runLcmMigrations } from "../../db/migration.js";
7
+ import { ConversationStore } from "../../store/conversation-store.js";
8
+ import { SummaryStore } from "../../store/summary-store.js";
9
+ import { RetrievalEngine } from "../../retrieval.js";
10
+ export function createDescribeHandler(_config) {
11
+ return async (_req, res, body) => {
12
+ const input = JSON.parse(body || "{}");
13
+ const { nodeId, cwd } = input;
14
+ if (!nodeId) {
15
+ sendJson(res, 400, { error: "nodeId is required" });
16
+ return;
17
+ }
18
+ if (!cwd || !existsSync(projectDbPath(cwd))) {
19
+ sendJson(res, 200, { node: null });
20
+ return;
21
+ }
22
+ try {
23
+ const dbPath = projectDbPath(cwd);
24
+ mkdirSync(dirname(dbPath), { recursive: true });
25
+ const db = new DatabaseSync(dbPath);
26
+ runLcmMigrations(db);
27
+ const convStore = new ConversationStore(db);
28
+ const summStore = new SummaryStore(db);
29
+ const engine = new RetrievalEngine(convStore, summStore);
30
+ const result = await engine.describe(nodeId);
31
+ db.close();
32
+ sendJson(res, 200, { node: result });
33
+ }
34
+ catch (err) {
35
+ sendJson(res, 200, { node: null, error: err instanceof Error ? err.message : "describe failed" });
36
+ }
37
+ };
38
+ }
39
+ //# sourceMappingURL=describe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describe.js","sourceRoot":"","sources":["../../../../src/daemon/routes/describe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,UAAU,qBAAqB,CAAC,OAAqB;IACzD,OAAO,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;QACvC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;QAE9B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC;YACpD,OAAO;QACT,CAAC;QAED,IAAI,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAC5C,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACnC,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;YAClC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAChD,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;YACpC,gBAAgB,CAAC,EAAE,CAAC,CAAC;YACrB,MAAM,SAAS,GAAG,IAAI,iBAAiB,CAAC,EAAE,CAAC,CAAC;YAC5C,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC,EAAE,CAAC,CAAC;YACvC,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YACzD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC7C,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC;QACpG,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { DaemonConfig } from "../config.js";
2
+ import type { RouteHandler } from "../server.js";
3
+ export declare function createExpandHandler(_config: DaemonConfig): RouteHandler;
@@ -0,0 +1,41 @@
1
+ import { existsSync, mkdirSync } from "node:fs";
2
+ import { dirname } from "node:path";
3
+ import { DatabaseSync } from "node:sqlite";
4
+ import { projectDbPath } from "../project.js";
5
+ import { sendJson } from "../server.js";
6
+ import { runLcmMigrations } from "../../db/migration.js";
7
+ import { ConversationStore } from "../../store/conversation-store.js";
8
+ import { SummaryStore } from "../../store/summary-store.js";
9
+ import { RetrievalEngine } from "../../retrieval.js";
10
+ import { ExpansionOrchestrator } from "../../expansion.js";
11
+ export function createExpandHandler(_config) {
12
+ return async (_req, res, body) => {
13
+ const input = JSON.parse(body || "{}");
14
+ const { nodeId, depth = 1, cwd } = input;
15
+ if (!nodeId) {
16
+ sendJson(res, 400, { error: "nodeId is required" });
17
+ return;
18
+ }
19
+ if (!cwd || !existsSync(projectDbPath(cwd))) {
20
+ sendJson(res, 200, { expanded: null, error: "project not found" });
21
+ return;
22
+ }
23
+ try {
24
+ const dbPath = projectDbPath(cwd);
25
+ mkdirSync(dirname(dbPath), { recursive: true });
26
+ const db = new DatabaseSync(dbPath);
27
+ runLcmMigrations(db);
28
+ const convStore = new ConversationStore(db);
29
+ const summStore = new SummaryStore(db);
30
+ const retrieval = new RetrievalEngine(convStore, summStore);
31
+ const orchestrator = new ExpansionOrchestrator(retrieval);
32
+ const result = await orchestrator.expand({ summaryIds: [nodeId], maxDepth: depth });
33
+ db.close();
34
+ sendJson(res, 200, result);
35
+ }
36
+ catch (err) {
37
+ sendJson(res, 200, { expanded: null, error: err instanceof Error ? err.message : "expansion failed" });
38
+ }
39
+ };
40
+ }
41
+ //# sourceMappingURL=expand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expand.js","sourceRoot":"","sources":["../../../../src/daemon/routes/expand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,MAAM,UAAU,mBAAmB,CAAC,OAAqB;IACvD,OAAO,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;QACvC,MAAM,EAAE,MAAM,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;QAEzC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC;YACpD,OAAO;QACT,CAAC;QAED,IAAI,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAC5C,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;YACnE,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;YAClC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAChD,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;YACpC,gBAAgB,CAAC,EAAE,CAAC,CAAC;YACrB,MAAM,SAAS,GAAG,IAAI,iBAAiB,CAAC,EAAE,CAAC,CAAC;YAC5C,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC,EAAE,CAAC,CAAC;YACvC,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YAC5D,MAAM,YAAY,GAAG,IAAI,qBAAqB,CAAC,SAAS,CAAC,CAAC;YAC1D,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;YACpF,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC;QACzG,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { DaemonConfig } from "../config.js";
2
+ import type { RouteHandler } from "../server.js";
3
+ export declare function createGrepHandler(_config: DaemonConfig): RouteHandler;
@@ -0,0 +1,43 @@
1
+ import { existsSync, mkdirSync } from "node:fs";
2
+ import { dirname } from "node:path";
3
+ import { DatabaseSync } from "node:sqlite";
4
+ import { projectDbPath } from "../project.js";
5
+ import { sendJson } from "../server.js";
6
+ import { runLcmMigrations } from "../../db/migration.js";
7
+ import { ConversationStore } from "../../store/conversation-store.js";
8
+ import { SummaryStore } from "../../store/summary-store.js";
9
+ import { RetrievalEngine } from "../../retrieval.js";
10
+ export function createGrepHandler(_config) {
11
+ return async (_req, res, body) => {
12
+ const input = JSON.parse(body || "{}");
13
+ const { query, scope, mode, since, cwd } = input;
14
+ if (!query) {
15
+ sendJson(res, 400, { error: "query is required" });
16
+ return;
17
+ }
18
+ if (!cwd) {
19
+ sendJson(res, 200, { matches: [] });
20
+ return;
21
+ }
22
+ try {
23
+ const dbPath = projectDbPath(cwd);
24
+ if (!existsSync(dbPath)) {
25
+ sendJson(res, 200, { matches: [] });
26
+ return;
27
+ }
28
+ mkdirSync(dirname(dbPath), { recursive: true });
29
+ const db = new DatabaseSync(dbPath);
30
+ runLcmMigrations(db);
31
+ const convStore = new ConversationStore(db);
32
+ const summStore = new SummaryStore(db);
33
+ const engine = new RetrievalEngine(convStore, summStore);
34
+ const result = await engine.grep({ query, mode: mode ?? "full_text", scope: scope ?? "both", since });
35
+ db.close();
36
+ sendJson(res, 200, result);
37
+ }
38
+ catch (err) {
39
+ sendJson(res, 200, { matches: [] });
40
+ }
41
+ };
42
+ }
43
+ //# sourceMappingURL=grep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grep.js","sourceRoot":"","sources":["../../../../src/daemon/routes/grep.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,UAAU,iBAAiB,CAAC,OAAqB;IACrD,OAAO,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;QACvC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;QAEjD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;YACnD,OAAO;QACT,CAAC;QAED,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;YACpC,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;YAClC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBACxB,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;gBACpC,OAAO;YACT,CAAC;YACD,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAChD,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;YACpC,gBAAgB,CAAC,EAAE,CAAC,CAAC;YACrB,MAAM,SAAS,GAAG,IAAI,iBAAiB,CAAC,EAAE,CAAC,CAAC;YAC5C,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC,EAAE,CAAC,CAAC;YACvC,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YACzD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,IAAI,WAAW,EAAE,KAAK,EAAE,KAAK,IAAI,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YACtG,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QACtC,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { DaemonConfig } from "../config.js";
2
+ import type { RouteHandler } from "../server.js";
3
+ export declare function createIngestHandler(config: DaemonConfig): RouteHandler;