@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,54 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { join, dirname } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { LCM_MARKERS, LCM_TAG } from "./constants.js";
5
+ const __dirname = dirname(fileURLToPath(import.meta.url));
6
+ const TEMPLATES_DIR = join(__dirname, "templates");
7
+ function loadFile(path) {
8
+ return readFileSync(join(TEMPLATES_DIR, path), "utf-8");
9
+ }
10
+ function substituteVariables(template, context) {
11
+ let result = template;
12
+ for (const [key, value] of Object.entries(context)) {
13
+ result = result.replaceAll(`{{${key}}}`, value);
14
+ }
15
+ return result;
16
+ }
17
+ function wrapWithMarkers(content, agentName, header) {
18
+ const parts = [];
19
+ if (header)
20
+ parts.push(header);
21
+ parts.push(LCM_MARKERS.START);
22
+ parts.push(content);
23
+ parts.push('---');
24
+ parts.push(`${LCM_TAG} ${agentName}`);
25
+ parts.push(LCM_MARKERS.END);
26
+ return parts.join('\n');
27
+ }
28
+ export function generateRulesContent(agent) {
29
+ const workflow = loadFile("sections/workflow.md");
30
+ const commandRef = loadFile("sections/command-reference.md");
31
+ const base = loadFile("base.md");
32
+ const content = substituteVariables(base, {
33
+ workflow: substituteVariables(workflow, { command_reference: commandRef }),
34
+ });
35
+ return wrapWithMarkers(content, agent.name, agent.header);
36
+ }
37
+ export function generateMcpContent(agent) {
38
+ const mcpWorkflow = loadFile("sections/mcp-workflow.md");
39
+ const base = loadFile("mcp-base.md");
40
+ const content = substituteVariables(base, { mcp_workflow: mcpWorkflow });
41
+ return wrapWithMarkers(content, agent.name, agent.header);
42
+ }
43
+ export function generateSkillContent(_agent) {
44
+ return loadFile("skill/SKILL.md"); // Skills don't need markers — they're standalone files
45
+ }
46
+ export function generateContent(agent, type) {
47
+ switch (type) {
48
+ case 'rules': return generateRulesContent(agent);
49
+ case 'mcp': return generateMcpContent(agent);
50
+ case 'skill': return generateSkillContent(agent);
51
+ case 'hook': throw new Error('Hook connectors are managed by the plugin system, not the template service');
52
+ }
53
+ }
54
+ //# sourceMappingURL=template-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-service.js","sourceRoot":"","sources":["../../../src/connectors/template-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {{workflow}}
@@ -0,0 +1 @@
1
+ {{mcp_workflow}}
@@ -0,0 +1,15 @@
1
+ ## Available Commands
2
+
3
+ - `lcm search "query"` — Full-text search across memory
4
+ - `lcm grep "pattern"` — Regex search across conversations
5
+ - `lcm expand "topic"` — Expand on a specific memory topic
6
+ - `lcm describe` — Show memory metadata and stats
7
+ - `lcm store "content"` — Persist knowledge to promoted memory
8
+ - `lcm stats` — Show compression ratios and token savings
9
+ - `lcm doctor` — Run diagnostics
10
+ - `lcm diagnose` — Scan recent Claude Code transcripts for hook and MCP issues
11
+ - `lcm import` — Import Claude Code session transcripts into memory
12
+ - `lcm import --all` — Import from all projects
13
+ - `lcm compact --all` — Summarize all uncompacted sessions
14
+
15
+ Run `lcm --help` for all options.
@@ -0,0 +1,18 @@
1
+ # Workflow Instruction
2
+
3
+ You are a coding agent integrated with lossless-claude via MCP (Model Context Protocol).
4
+
5
+ ## Core Rules
6
+
7
+ - Use the `lcm_search` tool to query memory before starting code tasks.
8
+ - Use the `lcm_store` tool to persist important decisions after completing work.
9
+
10
+ ## Tool Usage
11
+
12
+ - `lcm_search` — Full-text search across memory
13
+ - `lcm_grep` — Regex search across conversations
14
+ - `lcm_expand` — Expand on a specific memory topic
15
+ - `lcm_describe` — Show memory metadata
16
+ - `lcm_store` — Persist knowledge to promoted memory
17
+ - `lcm_stats` — Show compression ratios and token savings
18
+ - `lcm_doctor` — Run diagnostics
@@ -0,0 +1,29 @@
1
+ # Workflow Instruction
2
+
3
+ You are a coding agent. Use the lcm CLI to manage persistent memory across sessions.
4
+
5
+ ## Core Rules
6
+
7
+ - **Search first.** Before starting any code task, retrieve relevant context with `lcm search`.
8
+ - **Store what matters.** After completing work, use `lcm store` to persist key decisions and learnings.
9
+
10
+ ## When to Search
11
+
12
+ - Writing, editing, or modifying code in this project
13
+ - Understanding how something works in this codebase
14
+ - Debugging, fixing, or troubleshooting issues
15
+ - Before making architectural or design decisions
16
+
17
+ ## When to Store
18
+
19
+ - Completed a feature, fix, or refactor
20
+ - An architectural decision was made
21
+ - Discovered something non-obvious about the codebase
22
+
23
+ ## When to Skip
24
+
25
+ - General programming concepts (not codebase-specific)
26
+ - Meta tasks: run tests, build, commit, create PR
27
+ - Simple clarifications about a previous response
28
+
29
+ {{command_reference}}
@@ -0,0 +1,74 @@
1
+ ---
2
+ name: lcm-memory
3
+ description: Lossless context management — search and store persistent memory across sessions
4
+ ---
5
+
6
+ # Lossless Context Management
7
+
8
+ > **Before responding to code tasks, check memory first.**
9
+ > Code task? → `lcm search` FIRST. Completed work? → `lcm store` BEFORE done.
10
+
11
+ You have access to a persistent memory system that survives across conversations.
12
+
13
+ ## Workflow
14
+
15
+ Code task received → `lcm search` FIRST → Work → `lcm store` → Done
16
+ Non-code task → Just respond normally
17
+
18
+ ## Commands
19
+
20
+ ### 1. Search Memory
21
+ Retrieve relevant context before starting work.
22
+ ```bash
23
+ lcm search "How is authentication implemented?"
24
+ ```
25
+
26
+ ### 2. Grep Memory
27
+ Regex pattern search for precise matches.
28
+ ```bash
29
+ lcm grep "createDaemon|startMcpServer"
30
+ ```
31
+
32
+ ### 3. Expand Topic
33
+ Get detailed expansion on a memory topic.
34
+ ```bash
35
+ lcm expand "hook auto-heal system"
36
+ ```
37
+
38
+ ### 4. Store Knowledge
39
+ Persist important knowledge after completing work.
40
+ ```bash
41
+ lcm store "Auth middleware uses JWT with 24h expiry. See src/middleware/auth.ts"
42
+ ```
43
+
44
+ ### 5. Describe Memory
45
+ Show metadata about the memory system.
46
+ ```bash
47
+ lcm describe
48
+ ```
49
+
50
+ ### 6. Stats
51
+ Show token savings and compression ratios.
52
+ ```bash
53
+ lcm stats
54
+ ```
55
+
56
+ ## Decision Table
57
+
58
+ | Task Type | Search? | Store? |
59
+ |-----------|---------|--------|
60
+ | Add/create/implement feature | MUST | MUST |
61
+ | Fix/debug/resolve bug | MUST | MUST |
62
+ | Refactor/optimize/move code | MUST | MUST |
63
+ | Write/add tests | MUST | MUST |
64
+ | "How does X work?" (codebase) | MUST | Only if insights |
65
+ | General concept question | NO | NO |
66
+ | Meta task (run tests, build) | NO | NO |
67
+ | Git task (commit, PR, push) | NO | NO |
68
+
69
+ ## Error Handling
70
+
71
+ - If `lcm` is not found: run `npm install -g @lossless-claude/lcm`
72
+ - If daemon is down: run `lcm daemon start --detach`
73
+ - If search returns nothing: memory may be empty — proceed normally
74
+ - Check status: `lcm doctor`
@@ -0,0 +1,19 @@
1
+ export declare const CONNECTOR_TYPES: readonly ["rules", "hook", "mcp", "skill"];
2
+ export type ConnectorType = (typeof CONNECTOR_TYPES)[number];
3
+ export type AgentCategory = 'cli' | 'ai-ide' | 'vscode-ext' | 'other';
4
+ export interface Agent {
5
+ id: string;
6
+ name: string;
7
+ category: AgentCategory;
8
+ defaultType: ConnectorType;
9
+ supportedTypes: ConnectorType[];
10
+ configPaths: Partial<Record<ConnectorType, string>>;
11
+ writeMode?: 'append' | 'overwrite';
12
+ header?: string;
13
+ }
14
+ /**
15
+ * Whether the connector type requires an agent restart to take effect.
16
+ * Rules connectors are passive (agent reads on each prompt).
17
+ * Hook, MCP, and skill connectors need restart.
18
+ */
19
+ export declare function requiresRestart(type: ConnectorType): boolean;
@@ -0,0 +1,10 @@
1
+ export const CONNECTOR_TYPES = ['rules', 'hook', 'mcp', 'skill'];
2
+ /**
3
+ * Whether the connector type requires an agent restart to take effect.
4
+ * Rules connectors are passive (agent reads on each prompt).
5
+ * Hook, MCP, and skill connectors need restart.
6
+ */
7
+ export function requiresRestart(type) {
8
+ return type !== 'rules';
9
+ }
10
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/connectors/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAU,CAAC;AAgB1E;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,IAAmB;IACjD,OAAO,IAAI,KAAK,OAAO,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,9 @@
1
+ export declare class DaemonClient {
2
+ private baseUrl;
3
+ constructor(baseUrl: string);
4
+ health(): Promise<{
5
+ status: string;
6
+ uptime: number;
7
+ } | null>;
8
+ post<T = unknown>(path: string, body: unknown): Promise<T>;
9
+ }
@@ -0,0 +1,28 @@
1
+ export class DaemonClient {
2
+ baseUrl;
3
+ constructor(baseUrl) {
4
+ this.baseUrl = baseUrl;
5
+ }
6
+ async health() {
7
+ try {
8
+ const res = await fetch(`${this.baseUrl}/health`);
9
+ return res.ok ? await res.json() : null;
10
+ }
11
+ catch {
12
+ return null;
13
+ }
14
+ }
15
+ async post(path, body) {
16
+ const res = await fetch(`${this.baseUrl}${path}`, {
17
+ method: "POST",
18
+ headers: { "Content-Type": "application/json" },
19
+ body: JSON.stringify(body),
20
+ });
21
+ if (!res.ok) {
22
+ const err = await res.json().catch(() => ({ error: res.statusText }));
23
+ throw new Error(err.error ?? `HTTP ${res.status}`);
24
+ }
25
+ return await res.json();
26
+ }
27
+ }
28
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/daemon/client.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,YAAY;IACH;IAApB,YAAoB,OAAe;QAAf,YAAO,GAAP,OAAO,CAAQ;IAAG,CAAC;IAEvC,KAAK,CAAC,MAAM;QACV,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,SAAS,CAAC,CAAC;YAClD,OAAO,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,MAAM,GAAG,CAAC,IAAI,EAAyC,CAAC,CAAC,CAAC,IAAI,CAAC;QAClF,CAAC;QAAC,MAAM,CAAC;YAAC,OAAO,IAAI,CAAC;QAAC,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,IAAI,CAAc,IAAY,EAAE,IAAa;QACjD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,EAAE;YAChD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,UAAU,EAAE,CAAC,CAAuB,CAAC;YAC5F,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,MAAM,GAAG,CAAC,IAAI,EAAO,CAAC;IAC/B,CAAC;CACF"}
@@ -0,0 +1,48 @@
1
+ export interface SecurityConfig {
2
+ /** User-defined global regex patterns (plain strings, no /.../ delimiters). */
3
+ sensitivePatterns: string[];
4
+ }
5
+ export type DaemonConfig = {
6
+ version: number;
7
+ daemon: {
8
+ port: number;
9
+ socketPath: string;
10
+ logLevel: string;
11
+ logMaxSizeMB: number;
12
+ logRetentionDays: number;
13
+ idleTimeoutMs: number;
14
+ };
15
+ compaction: {
16
+ leafTokens: number;
17
+ maxDepth: number;
18
+ autoCompactMinTokens: number;
19
+ promotionThresholds: {
20
+ minDepth: number;
21
+ compressionRatio: number;
22
+ keywords: Record<string, string[]>;
23
+ architecturePatterns: string[];
24
+ dedupBm25Threshold: number;
25
+ mergeMaxEntries: number;
26
+ confidenceDecayRate: number;
27
+ };
28
+ };
29
+ restoration: {
30
+ recentSummaries: number;
31
+ promptSearchMinScore: number;
32
+ promptSearchMaxResults: number;
33
+ promptSnippetLength: number;
34
+ recencyHalfLifeHours: number;
35
+ crossSessionAffinity: number;
36
+ };
37
+ llm: {
38
+ provider: "auto" | "claude-process" | "codex-process" | "anthropic" | "openai" | "disabled";
39
+ model: string;
40
+ apiKey?: string;
41
+ baseURL: string;
42
+ };
43
+ summarizer: {
44
+ mock: boolean;
45
+ };
46
+ security: SecurityConfig;
47
+ };
48
+ export declare function loadDaemonConfig(configPath: string, overrides?: any, env?: Record<string, string | undefined>): DaemonConfig;
@@ -0,0 +1,67 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ const DEFAULTS = {
5
+ version: 1,
6
+ daemon: { port: 3737, socketPath: join(homedir(), ".lossless-claude", "daemon.sock"), logLevel: "info", logMaxSizeMB: 10, logRetentionDays: 7, idleTimeoutMs: 1800000 },
7
+ compaction: {
8
+ leafTokens: 1000, maxDepth: 5, autoCompactMinTokens: 10000,
9
+ promotionThresholds: {
10
+ minDepth: 2, compressionRatio: 0.3,
11
+ keywords: { decision: ["decided", "agreed", "will use", "going with", "chosen"], fix: ["fixed", "root cause", "workaround", "resolved"] },
12
+ architecturePatterns: ["src/[\\w/]+\\.ts", "[A-Z][a-zA-Z]+(Engine|Store|Service|Manager|Handler|Client)", "interface [A-Z]", "class [A-Z]"],
13
+ dedupBm25Threshold: 15,
14
+ mergeMaxEntries: 3,
15
+ confidenceDecayRate: 0.1,
16
+ },
17
+ },
18
+ restoration: { recentSummaries: 3, promptSearchMinScore: 2, promptSearchMaxResults: 3, promptSnippetLength: 200, recencyHalfLifeHours: 24, crossSessionAffinity: 0.85 },
19
+ llm: { provider: "auto", model: "", apiKey: "", baseURL: "" },
20
+ summarizer: { mock: false },
21
+ security: {
22
+ sensitivePatterns: [],
23
+ },
24
+ };
25
+ function deepMerge(target, source) {
26
+ if (!source || typeof source !== "object")
27
+ return target;
28
+ const result = { ...target };
29
+ for (const key of Object.keys(source)) {
30
+ if (source[key] !== undefined) {
31
+ result[key] = (typeof source[key] === "object" && !Array.isArray(source[key]) && typeof target[key] === "object")
32
+ ? deepMerge(target[key], source[key]) : source[key];
33
+ }
34
+ }
35
+ return result;
36
+ }
37
+ export function loadDaemonConfig(configPath, overrides, env) {
38
+ const e = env ?? process.env;
39
+ let fileConfig = {};
40
+ try {
41
+ fileConfig = JSON.parse(readFileSync(configPath, "utf-8"));
42
+ }
43
+ catch { }
44
+ const merged = deepMerge(structuredClone(DEFAULTS), deepMerge(fileConfig, overrides));
45
+ if (merged.llm.apiKey)
46
+ merged.llm.apiKey = merged.llm.apiKey.replace(/\$\{(\w+)\}/g, (_, k) => e[k] ?? "");
47
+ // Env var override: LCM_SUMMARY_PROVIDER takes precedence over config
48
+ const VALID_PROVIDERS = new Set(["auto", "claude-process", "codex-process", "anthropic", "openai", "disabled"]);
49
+ if (e.LCM_SUMMARY_PROVIDER) {
50
+ if (!VALID_PROVIDERS.has(e.LCM_SUMMARY_PROVIDER)) {
51
+ throw new Error(`[lcm] Invalid LCM_SUMMARY_PROVIDER="${e.LCM_SUMMARY_PROVIDER}". ` +
52
+ `Valid values: ${[...VALID_PROVIDERS].join(", ")}`);
53
+ }
54
+ merged.llm.provider = e.LCM_SUMMARY_PROVIDER;
55
+ }
56
+ // Anthropic API key fallback from env
57
+ if (!merged.llm.apiKey && merged.llm.provider === "anthropic" && e.ANTHROPIC_API_KEY) {
58
+ merged.llm.apiKey = e.ANTHROPIC_API_KEY;
59
+ }
60
+ // Validate: anthropic provider requires an API key
61
+ if (merged.llm.provider === "anthropic" && !merged.llm.apiKey) {
62
+ throw new Error("[lcm] LCM_SUMMARY_API_KEY is required when using the Anthropic provider. " +
63
+ "Set it in your environment or switch to 'auto', 'claude-process', or another provider.");
64
+ }
65
+ return merged;
66
+ }
67
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/daemon/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { spawn } from "node:child_process";
2
+ export type EnsureDaemonOptions = {
3
+ port: number;
4
+ pidFilePath: string;
5
+ spawnTimeoutMs: number;
6
+ expectedVersion?: string;
7
+ spawnCommand?: string;
8
+ spawnArgs?: string[];
9
+ _skipSpawn?: boolean;
10
+ _spawnOverride?: typeof spawn;
11
+ _skipHealthWait?: boolean;
12
+ _fetchOverride?: typeof globalThis.fetch;
13
+ };
14
+ export type EnsureDaemonResult = {
15
+ connected: boolean;
16
+ port: number;
17
+ spawned: boolean;
18
+ };
19
+ export declare function ensureDaemon(opts: EnsureDaemonOptions): Promise<EnsureDaemonResult>;
@@ -0,0 +1,102 @@
1
+ import { existsSync, readFileSync, writeFileSync, unlinkSync } from "node:fs";
2
+ import { spawn } from "node:child_process";
3
+ function sleep(ms) {
4
+ return new Promise((r) => setTimeout(r, ms));
5
+ }
6
+ function isProcessAlive(pid) {
7
+ try {
8
+ process.kill(pid, 0);
9
+ return true;
10
+ }
11
+ catch {
12
+ return false;
13
+ }
14
+ }
15
+ function cleanStalePid(pidFilePath) {
16
+ try {
17
+ if (existsSync(pidFilePath))
18
+ unlinkSync(pidFilePath);
19
+ }
20
+ catch { /* ignore */ }
21
+ }
22
+ async function checkDaemonHealth(port, fetchFn) {
23
+ try {
24
+ const res = await fetchFn(`http://127.0.0.1:${port}/health`);
25
+ if (!res.ok)
26
+ return null;
27
+ return (await res.json());
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ }
33
+ export async function ensureDaemon(opts) {
34
+ const fetchFn = opts._fetchOverride ?? globalThis.fetch;
35
+ // Step 1: Check if daemon is already running via health check
36
+ const health = await checkDaemonHealth(opts.port, fetchFn);
37
+ if (health?.status === "ok") {
38
+ // Version check — if mismatch, kill and respawn
39
+ if (opts.expectedVersion && health.version && health.version !== opts.expectedVersion) {
40
+ if (existsSync(opts.pidFilePath)) {
41
+ try {
42
+ const pid = parseInt(readFileSync(opts.pidFilePath, "utf-8").trim(), 10);
43
+ if (!isNaN(pid) && isProcessAlive(pid)) {
44
+ process.kill(pid, "SIGTERM");
45
+ await sleep(500);
46
+ }
47
+ }
48
+ catch { /* ignore */ }
49
+ cleanStalePid(opts.pidFilePath);
50
+ }
51
+ // Fall through to spawn
52
+ }
53
+ else {
54
+ return { connected: true, port: opts.port, spawned: false };
55
+ }
56
+ }
57
+ // Step 2: Check PID file for stale process
58
+ if (existsSync(opts.pidFilePath)) {
59
+ try {
60
+ const pid = parseInt(readFileSync(opts.pidFilePath, "utf-8").trim(), 10);
61
+ if (!isNaN(pid) && isProcessAlive(pid)) {
62
+ await sleep(1000);
63
+ const retry = await checkDaemonHealth(opts.port, fetchFn);
64
+ if (retry?.status === "ok") {
65
+ return { connected: true, port: opts.port, spawned: false };
66
+ }
67
+ }
68
+ }
69
+ catch { /* ignore */ }
70
+ cleanStalePid(opts.pidFilePath);
71
+ }
72
+ // Step 3: Spawn daemon (unless skipped for testing)
73
+ if (opts._skipSpawn) {
74
+ return { connected: false, port: opts.port, spawned: false };
75
+ }
76
+ const spawnCommand = opts.spawnCommand ?? process.execPath;
77
+ const spawnArgs = opts.spawnArgs ?? [process.argv[1], "daemon", "start"];
78
+ const spawnImpl = opts._spawnOverride ?? spawn;
79
+ const child = spawnImpl(spawnCommand, spawnArgs, {
80
+ detached: true,
81
+ stdio: "ignore",
82
+ env: { ...process.env },
83
+ });
84
+ child.unref();
85
+ if (child.pid) {
86
+ writeFileSync(opts.pidFilePath, String(child.pid));
87
+ }
88
+ if (opts._skipHealthWait) {
89
+ return { connected: false, port: opts.port, spawned: true };
90
+ }
91
+ // Step 4: Wait for health
92
+ const deadline = Date.now() + opts.spawnTimeoutMs;
93
+ while (Date.now() < deadline) {
94
+ const h = await checkDaemonHealth(opts.port, fetchFn);
95
+ if (h?.status === "ok") {
96
+ return { connected: true, port: opts.port, spawned: true };
97
+ }
98
+ await sleep(300);
99
+ }
100
+ return { connected: false, port: opts.port, spawned: true };
101
+ }
102
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../../src/daemon/lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function buildOrientationPrompt(): string;
@@ -0,0 +1,9 @@
1
+ export function buildOrientationPrompt() {
2
+ return `<memory-orientation>
3
+ Memory system active. Guidelines:
4
+ - lcm_grep / lcm_expand / lcm_describe / lcm_search → conversation history and project memory
5
+ - Do not store directly to any memory system — lossless-claude manages persistence automatically
6
+ - When uncertain what was discussed or decided, use lcm_search before asking the user
7
+ </memory-orientation>`;
8
+ }
9
+ //# sourceMappingURL=orientation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orientation.js","sourceRoot":"","sources":["../../../src/daemon/orientation.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,sBAAsB;IACpC,OAAO;;;;;sBAKa,CAAC;AACvB,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function enqueue<T>(projectId: string, fn: () => Promise<T>): Promise<T>;
@@ -0,0 +1,17 @@
1
+ const queues = new Map();
2
+ export function enqueue(projectId, fn) {
3
+ const entry = queues.get(projectId) ?? { chain: Promise.resolve(), pending: 0 };
4
+ entry.pending++;
5
+ queues.set(projectId, entry);
6
+ const result = entry.chain.then(fn, fn); // run fn regardless of previous result
7
+ entry.chain = result.then(() => { }, () => { }); // swallow for chain continuity
8
+ // Clean up when all pending operations complete (swallow rejection to avoid unhandled promise)
9
+ entry.chain.then(() => {
10
+ entry.pending--;
11
+ if (entry.pending === 0) {
12
+ queues.delete(projectId);
13
+ }
14
+ });
15
+ return result;
16
+ }
17
+ //# sourceMappingURL=project-queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-queue.js","sourceRoot":"","sources":["../../../src/daemon/project-queue.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,GAAG,IAAI,GAAG,EAAqD,CAAA;AAE3E,MAAM,UAAU,OAAO,CAAI,SAAiB,EAAE,EAAoB;IAChE,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAA;IAC/E,KAAK,CAAC,OAAO,EAAE,CAAA;IACf,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;IAE5B,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA,CAAC,uCAAuC;IAC/E,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA,CAAC,+BAA+B;IAE7E,+FAA+F;IAC/F,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE;QACpB,KAAK,CAAC,OAAO,EAAE,CAAA;QACf,IAAI,KAAK,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAC1B,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1,7 @@
1
+ export declare const BASE_DIR: string;
2
+ export declare const projectId: (cwd: string) => string;
3
+ export declare const projectDir: (cwd: string) => string;
4
+ export declare const projectDbPath: (cwd: string) => string;
5
+ export declare const projectMetaPath: (cwd: string) => string;
6
+ /** Ensures the project dir exists and writes cwd to meta.json. */
7
+ export declare const ensureProjectDir: (cwd: string) => string;
@@ -0,0 +1,25 @@
1
+ import { createHash } from "node:crypto";
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
+ import { homedir } from "node:os";
4
+ import { join } from "node:path";
5
+ export const BASE_DIR = join(homedir(), ".lossless-claude");
6
+ export const projectId = (cwd) => createHash("sha256").update(cwd).digest("hex");
7
+ export const projectDir = (cwd) => join(BASE_DIR, "projects", projectId(cwd));
8
+ export const projectDbPath = (cwd) => join(projectDir(cwd), "db.sqlite");
9
+ export const projectMetaPath = (cwd) => join(projectDir(cwd), "meta.json");
10
+ /** Ensures the project dir exists and writes cwd to meta.json. */
11
+ export const ensureProjectDir = (cwd) => {
12
+ const dir = projectDir(cwd);
13
+ mkdirSync(dir, { recursive: true });
14
+ const metaPath = join(dir, "meta.json");
15
+ let meta = { cwd };
16
+ if (existsSync(metaPath)) {
17
+ try {
18
+ meta = { ...JSON.parse(readFileSync(metaPath, "utf-8")), cwd };
19
+ }
20
+ catch { /* keep default */ }
21
+ }
22
+ writeFileSync(metaPath, JSON.stringify(meta, null, 2));
23
+ return dir;
24
+ };
25
+ //# sourceMappingURL=project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../../../src/daemon/project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,kBAAkB,CAAC,CAAC;AAE5D,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,GAAW,EAAU,EAAE,CAC/C,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAEjD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,GAAW,EAAU,EAAE,CAChD,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;AAE7C,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,GAAW,EAAU,EAAE,CACnD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,CAAC;AAErC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAW,EAAU,EAAE,CACrD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,CAAC;AAErC,kEAAkE;AAClE,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,GAAW,EAAU,EAAE;IACtD,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAC5B,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACxC,IAAI,IAAI,GAA4B,EAAE,GAAG,EAAE,CAAC;IAC5C,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,IAAI,CAAC;YAAC,IAAI,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;IACtG,CAAC;IACD,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACvD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC"}
@@ -0,0 +1,21 @@
1
+ export interface ProxyManager {
2
+ start(): Promise<void>;
3
+ stop(): Promise<void>;
4
+ isHealthy(): Promise<boolean>;
5
+ readonly port: number;
6
+ readonly available: boolean;
7
+ }
8
+ export type ProxyManagerOptions = {
9
+ port: number;
10
+ startupTimeoutMs: number;
11
+ model: string;
12
+ pidFilePath?: string;
13
+ healthPollIntervalMs?: number;
14
+ healthMonitorIntervalMs?: number;
15
+ maxHealthMisses?: number;
16
+ /** Override fetch for testing */
17
+ _fetchOverride?: typeof globalThis.fetch;
18
+ /** Override process.kill(pid, 0) check for testing */
19
+ _killCheck?: (pid: number) => boolean;
20
+ };
21
+ export declare function createClaudeCliProxyManager(opts: ProxyManagerOptions): ProxyManager;