@lossless-claude/lcm 0.5.0 → 0.7.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 (182) hide show
  1. package/.claude-plugin/commands/lcm-compact.md +10 -0
  2. package/.claude-plugin/commands/lcm-curate.md +16 -6
  3. package/.claude-plugin/commands/lcm-diagnose.md +10 -0
  4. package/.claude-plugin/commands/lcm-doctor.md +1 -1
  5. package/.claude-plugin/commands/lcm-dogfood.md +1 -1
  6. package/.claude-plugin/commands/lcm-import.md +10 -0
  7. package/.claude-plugin/commands/lcm-promote.md +10 -0
  8. package/.claude-plugin/commands/lcm-sensitive.md +10 -0
  9. package/.claude-plugin/commands/lcm-stats.md +1 -1
  10. package/.claude-plugin/commands/lcm-status.md +10 -0
  11. package/.claude-plugin/hooks/README.md +1 -1
  12. package/.claude-plugin/marketplace.json +1 -1
  13. package/.claude-plugin/plugin.json +14 -2
  14. package/.claude-plugin/skills/lcm-context/SKILL.md +10 -0
  15. package/.claude-plugin/skills/lcm-dogfood/SKILL.md +1 -1
  16. package/.claude-plugin/skills/lcm-dogfood/references/checks.md +1 -1
  17. package/README.md +2 -2
  18. package/dist/bin/lcm.js +828 -474
  19. package/dist/bin/lcm.js.map +1 -1
  20. package/dist/installer/install.d.ts +6 -5
  21. package/dist/installer/install.js +116 -108
  22. package/dist/installer/install.js.map +1 -1
  23. package/dist/src/batch-compact.d.ts +7 -1
  24. package/dist/src/batch-compact.js +80 -6
  25. package/dist/src/batch-compact.js.map +1 -1
  26. package/dist/src/bootstrap.d.ts +24 -0
  27. package/dist/src/bootstrap.js +76 -0
  28. package/dist/src/bootstrap.js.map +1 -0
  29. package/dist/src/cli/pipeline-runner.d.ts +47 -0
  30. package/dist/src/cli/pipeline-runner.js +106 -0
  31. package/dist/src/cli/pipeline-runner.js.map +1 -0
  32. package/dist/src/cli/pipeline-step.d.ts +20 -0
  33. package/dist/src/cli/pipeline-step.js +6 -0
  34. package/dist/src/cli/pipeline-step.js.map +1 -0
  35. package/dist/src/cli/progress-state.d.ts +61 -0
  36. package/dist/src/cli/progress-state.js +16 -0
  37. package/dist/src/cli/progress-state.js.map +1 -0
  38. package/dist/src/cli/render-frame.d.ts +26 -0
  39. package/dist/src/cli/render-frame.js +153 -0
  40. package/dist/src/cli/render-frame.js.map +1 -0
  41. package/dist/src/cli/render-summary.d.ts +8 -0
  42. package/dist/src/cli/render-summary.js +79 -0
  43. package/dist/src/cli/render-summary.js.map +1 -0
  44. package/dist/src/cli-help.js +15 -9
  45. package/dist/src/cli-help.js.map +1 -1
  46. package/dist/src/codex-transcript.d.ts +50 -0
  47. package/dist/src/codex-transcript.js +207 -0
  48. package/dist/src/codex-transcript.js.map +1 -0
  49. package/dist/src/daemon/auth.d.ts +2 -0
  50. package/dist/src/daemon/auth.js +40 -0
  51. package/dist/src/daemon/auth.js.map +1 -0
  52. package/dist/src/daemon/client.d.ts +5 -1
  53. package/dist/src/daemon/client.js +21 -2
  54. package/dist/src/daemon/client.js.map +1 -1
  55. package/dist/src/daemon/config.d.ts +15 -0
  56. package/dist/src/daemon/config.js +33 -8
  57. package/dist/src/daemon/config.js.map +1 -1
  58. package/dist/src/daemon/content-fence.d.ts +7 -0
  59. package/dist/src/daemon/content-fence.js +14 -0
  60. package/dist/src/daemon/content-fence.js.map +1 -0
  61. package/dist/src/daemon/lifecycle.js +5 -0
  62. package/dist/src/daemon/lifecycle.js.map +1 -1
  63. package/dist/src/daemon/orientation.d.ts +1 -0
  64. package/dist/src/daemon/orientation.js +35 -6
  65. package/dist/src/daemon/orientation.js.map +1 -1
  66. package/dist/src/daemon/project.d.ts +1 -0
  67. package/dist/src/daemon/project.js +95 -3
  68. package/dist/src/daemon/project.js.map +1 -1
  69. package/dist/src/daemon/routes/compact.js +41 -10
  70. package/dist/src/daemon/routes/compact.js.map +1 -1
  71. package/dist/src/daemon/routes/describe.js +12 -1
  72. package/dist/src/daemon/routes/describe.js.map +1 -1
  73. package/dist/src/daemon/routes/expand.js +12 -1
  74. package/dist/src/daemon/routes/expand.js.map +1 -1
  75. package/dist/src/daemon/routes/grep.js +11 -2
  76. package/dist/src/daemon/routes/grep.js.map +1 -1
  77. package/dist/src/daemon/routes/ingest.js +36 -8
  78. package/dist/src/daemon/routes/ingest.js.map +1 -1
  79. package/dist/src/daemon/routes/promote-events.d.ts +3 -0
  80. package/dist/src/daemon/routes/promote-events.js +180 -0
  81. package/dist/src/daemon/routes/promote-events.js.map +1 -0
  82. package/dist/src/daemon/routes/promote.js +18 -3
  83. package/dist/src/daemon/routes/promote.js.map +1 -1
  84. package/dist/src/daemon/routes/prompt-search.js +11 -2
  85. package/dist/src/daemon/routes/prompt-search.js.map +1 -1
  86. package/dist/src/daemon/routes/recent.js +11 -2
  87. package/dist/src/daemon/routes/recent.js.map +1 -1
  88. package/dist/src/daemon/routes/restore.js +117 -69
  89. package/dist/src/daemon/routes/restore.js.map +1 -1
  90. package/dist/src/daemon/routes/search.js +12 -1
  91. package/dist/src/daemon/routes/search.js.map +1 -1
  92. package/dist/src/daemon/routes/session-complete.d.ts +2 -0
  93. package/dist/src/daemon/routes/session-complete.js +36 -0
  94. package/dist/src/daemon/routes/session-complete.js.map +1 -0
  95. package/dist/src/daemon/routes/status.js +77 -64
  96. package/dist/src/daemon/routes/status.js.map +1 -1
  97. package/dist/src/daemon/routes/store.d.ts +2 -1
  98. package/dist/src/daemon/routes/store.js +42 -8
  99. package/dist/src/daemon/routes/store.js.map +1 -1
  100. package/dist/src/daemon/safe-error.d.ts +5 -0
  101. package/dist/src/daemon/safe-error.js +15 -0
  102. package/dist/src/daemon/safe-error.js.map +1 -0
  103. package/dist/src/daemon/server.d.ts +3 -1
  104. package/dist/src/daemon/server.js +37 -17
  105. package/dist/src/daemon/server.js.map +1 -1
  106. package/dist/src/daemon/validate-cwd.d.ts +5 -0
  107. package/dist/src/daemon/validate-cwd.js +38 -0
  108. package/dist/src/daemon/validate-cwd.js.map +1 -0
  109. package/dist/src/daemon/version.d.ts +10 -0
  110. package/dist/src/daemon/version.js +31 -0
  111. package/dist/src/daemon/version.js.map +1 -0
  112. package/dist/src/db/events-path.d.ts +2 -0
  113. package/dist/src/db/events-path.js +11 -0
  114. package/dist/src/db/events-path.js.map +1 -0
  115. package/dist/src/db/events-stats.d.ts +29 -0
  116. package/dist/src/db/events-stats.js +107 -0
  117. package/dist/src/db/events-stats.js.map +1 -0
  118. package/dist/src/db/migration.js +8 -0
  119. package/dist/src/db/migration.js.map +1 -1
  120. package/dist/src/diagnose.js +14 -1
  121. package/dist/src/diagnose.js.map +1 -1
  122. package/dist/src/doctor/doctor.d.ts +1 -1
  123. package/dist/src/doctor/doctor.js +184 -15
  124. package/dist/src/doctor/doctor.js.map +1 -1
  125. package/dist/src/hooks/auto-heal.js +24 -1
  126. package/dist/src/hooks/auto-heal.js.map +1 -1
  127. package/dist/src/hooks/compact.js +7 -0
  128. package/dist/src/hooks/compact.js.map +1 -1
  129. package/dist/src/hooks/dispatch.d.ts +1 -1
  130. package/dist/src/hooks/dispatch.js +19 -1
  131. package/dist/src/hooks/dispatch.js.map +1 -1
  132. package/dist/src/hooks/events-db.d.ts +41 -0
  133. package/dist/src/hooks/events-db.js +190 -0
  134. package/dist/src/hooks/events-db.js.map +1 -0
  135. package/dist/src/hooks/extractors.d.ts +17 -0
  136. package/dist/src/hooks/extractors.js +198 -0
  137. package/dist/src/hooks/extractors.js.map +1 -0
  138. package/dist/src/hooks/hook-errors.d.ts +14 -0
  139. package/dist/src/hooks/hook-errors.js +56 -0
  140. package/dist/src/hooks/hook-errors.js.map +1 -0
  141. package/dist/src/hooks/post-tool.d.ts +4 -0
  142. package/dist/src/hooks/post-tool.js +43 -0
  143. package/dist/src/hooks/post-tool.js.map +1 -0
  144. package/dist/src/hooks/restore.js +31 -1
  145. package/dist/src/hooks/restore.js.map +1 -1
  146. package/dist/src/hooks/session-end.d.ts +3 -0
  147. package/dist/src/hooks/session-end.js +68 -5
  148. package/dist/src/hooks/session-end.js.map +1 -1
  149. package/dist/src/hooks/session-snapshot.d.ts +12 -0
  150. package/dist/src/hooks/session-snapshot.js +100 -0
  151. package/dist/src/hooks/session-snapshot.js.map +1 -0
  152. package/dist/src/hooks/user-prompt.js +44 -5
  153. package/dist/src/hooks/user-prompt.js.map +1 -1
  154. package/dist/src/import-summary.d.ts +4 -0
  155. package/dist/src/import-summary.js +34 -0
  156. package/dist/src/import-summary.js.map +1 -0
  157. package/dist/src/import.d.ts +11 -1
  158. package/dist/src/import.js +218 -88
  159. package/dist/src/import.js.map +1 -1
  160. package/dist/src/installer/settings.d.ts +5 -0
  161. package/dist/src/installer/settings.js +74 -0
  162. package/dist/src/installer/settings.js.map +1 -0
  163. package/dist/src/mcp/server.d.ts +15 -0
  164. package/dist/src/mcp/server.js +83 -6
  165. package/dist/src/mcp/server.js.map +1 -1
  166. package/dist/src/promotion/detector.js +19 -5
  167. package/dist/src/promotion/detector.js.map +1 -1
  168. package/dist/src/scrub.js +26 -0
  169. package/dist/src/scrub.js.map +1 -1
  170. package/dist/src/stats.d.ts +4 -0
  171. package/dist/src/stats.js +23 -0
  172. package/dist/src/stats.js.map +1 -1
  173. package/dist/src/store/conversation-store.js +2 -1
  174. package/dist/src/store/conversation-store.js.map +1 -1
  175. package/dist/src/store/regex-safety.d.ts +1 -0
  176. package/dist/src/store/regex-safety.js +22 -0
  177. package/dist/src/store/regex-safety.js.map +1 -0
  178. package/dist/src/store/summary-store.js +2 -1
  179. package/dist/src/store/summary-store.js.map +1 -1
  180. package/docs/passive-learning.md +138 -0
  181. package/lcm.mjs +20 -1
  182. package/package.json +5 -2
@@ -9,6 +9,8 @@ import { sendJson } from "../server.js";
9
9
  import { runLcmMigrations } from "../../db/migration.js";
10
10
  import { PromotedStore } from "../../db/promoted.js";
11
11
  import { justCompactedMap, JUST_COMPACTED_TTL_MS } from "./compact.js";
12
+ import { fenceContent } from "../content-fence.js";
13
+ import { validateCwd } from "../validate-cwd.js";
12
14
  function readClaudeMdFiles(cwd) {
13
15
  const paths = [
14
16
  { label: "~/.claude/CLAUDE.md", path: join(homedir(), ".claude", "CLAUDE.md") },
@@ -29,92 +31,138 @@ function readClaudeMdFiles(cwd) {
29
31
  }
30
32
  export function createRestoreHandler(config) {
31
33
  return async (_req, res, body) => {
32
- const input = JSON.parse(body || "{}");
33
- const { session_id, cwd, source } = input;
34
- const orientation = buildOrientationPrompt();
35
- // Post-compaction detection
36
- const isPostCompact = source === "compact" ||
37
- (justCompactedMap.has(session_id) && Date.now() - justCompactedMap.get(session_id) < JUST_COMPACTED_TTL_MS);
38
- // Query session_instructions for compact/resume paths
39
- let instructionsContext = "";
40
- if (cwd) {
41
- const dbPath = projectDbPath(cwd);
42
- if (existsSync(dbPath)) {
34
+ try {
35
+ const input = JSON.parse(body || "{}");
36
+ const { session_id, source } = input;
37
+ let cwd;
38
+ if (input.cwd) {
43
39
  try {
44
- const db = new DatabaseSync(dbPath);
40
+ cwd = validateCwd(input.cwd);
41
+ }
42
+ catch (err) {
43
+ sendJson(res, 400, { error: err instanceof Error ? err.message : "invalid cwd" });
44
+ return;
45
+ }
46
+ }
47
+ const orientation = buildOrientationPrompt();
48
+ // Post-compaction detection
49
+ const isPostCompact = source === "compact" ||
50
+ (justCompactedMap.has(session_id) && Date.now() - justCompactedMap.get(session_id) < JUST_COMPACTED_TTL_MS);
51
+ // Query session_instructions for compact/resume paths
52
+ let instructionsContext = "";
53
+ if (cwd) {
54
+ const dbPath = projectDbPath(cwd);
55
+ if (existsSync(dbPath)) {
45
56
  try {
46
- runLcmMigrations(db);
47
- const row = db
48
- .prepare(`SELECT content, content_hash, updated_at FROM session_instructions WHERE id = 1`)
49
- .get();
50
- if (row) {
51
- instructionsContext = `<project-instructions>\n${row.content}\n</project-instructions>`;
57
+ const db = new DatabaseSync(dbPath);
58
+ try {
59
+ runLcmMigrations(db);
60
+ const row = db
61
+ .prepare(`SELECT content, content_hash, updated_at FROM session_instructions WHERE id = 1`)
62
+ .get();
63
+ if (row) {
64
+ instructionsContext = `<project-instructions>\n${row.content}\n</project-instructions>`;
65
+ }
66
+ }
67
+ finally {
68
+ db.close();
52
69
  }
53
70
  }
54
- finally {
55
- db.close();
56
- }
71
+ catch { /* non-fatal */ }
57
72
  }
58
- catch { /* non-fatal */ }
59
73
  }
60
- }
61
- if (isPostCompact) {
62
- const context = [orientation, instructionsContext].filter(Boolean).join("\n\n");
63
- sendJson(res, 200, { context });
64
- return;
65
- }
66
- let episodicContext = "";
67
- let promotedContext = "";
68
- // Episodic: query recent summaries from project SQLite DB
69
- // Also capture CLAUDE.md files on startup
70
- if (cwd) {
71
- const dbPath = projectDbPath(cwd);
72
- mkdirSync(dirname(dbPath), { recursive: true });
73
- const db = new DatabaseSync(dbPath);
74
- try {
75
- runLcmMigrations(db);
76
- const rows = db.prepare(`SELECT s.content FROM summaries s
77
- JOIN conversations c ON s.conversation_id = c.conversation_id
78
- WHERE c.session_id = ?
79
- ORDER BY s.depth DESC, s.created_at DESC
80
- LIMIT ?`).all(session_id, config.restoration.recentSummaries);
81
- if (rows.length > 0) {
82
- episodicContext = `<recent-session-context>\n${rows.map((r) => r.content).join("\n\n")}\n</recent-session-context>`;
83
- }
84
- // Promoted: cross-session knowledge from SQLite
74
+ if (isPostCompact) {
75
+ const context = [orientation, instructionsContext].filter(Boolean).join("\n\n");
76
+ sendJson(res, 200, { context });
77
+ return;
78
+ }
79
+ let episodicContext = "";
80
+ let promotedContext = "";
81
+ // Episodic: query recent summaries from project SQLite DB
82
+ // Also capture CLAUDE.md files on startup
83
+ if (cwd) {
84
+ const dbPath = projectDbPath(cwd);
85
+ mkdirSync(dirname(dbPath), { recursive: true });
86
+ const db = new DatabaseSync(dbPath);
85
87
  try {
86
- const promotedStore = new PromotedStore(db);
87
- const results = promotedStore.search(`project context ${cwd}`, 5);
88
- if (results.length > 0) {
89
- promotedContext = `<project-knowledge>\n${results.map((r) => r.content).join("\n\n")}\n</project-knowledge>`;
88
+ runLcmMigrations(db);
89
+ const rows = db.prepare(`SELECT s.content FROM summaries s
90
+ JOIN conversations c ON s.conversation_id = c.conversation_id
91
+ WHERE c.session_id = ?
92
+ ORDER BY s.depth DESC, s.created_at DESC
93
+ LIMIT ?`).all(session_id, config.restoration.recentSummaries);
94
+ if (rows.length > 0) {
95
+ episodicContext = fenceContent(rows.map((r) => r.content).join("\n\n"), "recent-session-context");
90
96
  }
97
+ // Promoted: cross-session knowledge from SQLite
98
+ try {
99
+ const promotedStore = new PromotedStore(db);
100
+ const results = promotedStore.search(`project context ${cwd}`, 5);
101
+ if (results.length > 0) {
102
+ promotedContext = fenceContent(results.map((r) => r.content).join("\n\n"), "project-knowledge");
103
+ }
104
+ }
105
+ catch { /* non-fatal */ }
106
+ // Capture CLAUDE.md files and upsert into session_instructions if changed
107
+ try {
108
+ const claudeMdContent = readClaudeMdFiles(cwd);
109
+ if (claudeMdContent) {
110
+ const hash = createHash("sha256").update(claudeMdContent).digest("hex");
111
+ const existing = db
112
+ .prepare(`SELECT content_hash FROM session_instructions WHERE id = 1`)
113
+ .get();
114
+ if (!existing || existing.content_hash !== hash) {
115
+ db.prepare(`INSERT INTO session_instructions (id, content, content_hash, updated_at)
116
+ VALUES (1, ?, ?, datetime('now'))
117
+ ON CONFLICT(id) DO UPDATE SET
118
+ content = excluded.content,
119
+ content_hash = excluded.content_hash,
120
+ updated_at = excluded.updated_at`).run(claudeMdContent, hash);
121
+ }
122
+ }
123
+ }
124
+ catch { /* non-fatal */ }
125
+ db.close();
91
126
  }
92
127
  catch { /* non-fatal */ }
93
- // Capture CLAUDE.md files and upsert into session_instructions if changed
128
+ }
129
+ // Query passive-capture insights from promoted store
130
+ let insights = [];
131
+ if (cwd) {
94
132
  try {
95
- const claudeMdContent = readClaudeMdFiles(cwd);
96
- if (claudeMdContent) {
97
- const hash = createHash("sha256").update(claudeMdContent).digest("hex");
98
- const existing = db
99
- .prepare(`SELECT content_hash FROM session_instructions WHERE id = 1`)
100
- .get();
101
- if (!existing || existing.content_hash !== hash) {
102
- db.prepare(`INSERT INTO session_instructions (id, content, content_hash, updated_at)
103
- VALUES (1, ?, ?, datetime('now'))
104
- ON CONFLICT(id) DO UPDATE SET
105
- content = excluded.content,
106
- content_hash = excluded.content_hash,
107
- updated_at = excluded.updated_at`).run(claudeMdContent, hash);
133
+ const dbPath = projectDbPath(cwd);
134
+ if (existsSync(dbPath)) {
135
+ const insightsDb = new DatabaseSync(dbPath);
136
+ try {
137
+ runLcmMigrations(insightsDb);
138
+ const insightsStore = new PromotedStore(insightsDb);
139
+ const thresholds = config.compaction.promotionThresholds;
140
+ const minConfidence = thresholds.eventConfidence?.pattern ?? 0.3;
141
+ const maxAgeDays = thresholds.insightsMaxAgeDays ?? 90;
142
+ const cutoffMs = Date.now() - maxAgeDays * 24 * 60 * 60 * 1000;
143
+ insights = insightsStore
144
+ .search("source passive capture", 10, ["source:passive-capture"])
145
+ .filter((r) => r.confidence >= minConfidence && (!r.createdAt || Date.parse(r.createdAt) >= cutoffMs))
146
+ .slice(0, 5)
147
+ .map((r) => ({ content: r.content, confidence: r.confidence, tags: r.tags }));
148
+ }
149
+ finally {
150
+ insightsDb.close();
108
151
  }
109
152
  }
110
153
  }
111
154
  catch { /* non-fatal */ }
112
- db.close();
113
155
  }
114
- catch { /* non-fatal */ }
156
+ const context = [orientation, episodicContext, promotedContext, instructionsContext].filter(Boolean).join("\n\n");
157
+ const responseBody = { context };
158
+ if (insights.length > 0) {
159
+ responseBody.insights = insights;
160
+ }
161
+ sendJson(res, 200, responseBody);
162
+ }
163
+ catch (err) {
164
+ sendJson(res, 500, { error: err instanceof Error ? err.message : "restore failed" });
115
165
  }
116
- const context = [orientation, episodicContext, promotedContext, instructionsContext].filter(Boolean).join("\n\n");
117
- sendJson(res, 200, { context });
118
166
  };
119
167
  }
120
168
  //# sourceMappingURL=restore.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"restore.js","sourceRoot":"","sources":["../../../../src/daemon/routes/restore.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"restore.js","sourceRoot":"","sources":["../../../../src/daemon/routes/restore.ts"],"names":[],"mappings":"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"}
@@ -8,16 +8,27 @@ import { ConversationStore } from "../../store/conversation-store.js";
8
8
  import { SummaryStore } from "../../store/summary-store.js";
9
9
  import { RetrievalEngine } from "../../retrieval.js";
10
10
  import { PromotedStore } from "../../db/promoted.js";
11
+ import { validateCwd } from "../validate-cwd.js";
11
12
  export function createSearchHandler() {
12
13
  return async (_req, res, body) => {
13
14
  const input = JSON.parse(body || "{}");
14
- const { query, limit = 5, layers, tags, cwd } = input;
15
+ const { query, limit = 5, layers, tags } = input;
15
16
  const activeLayers = layers ?? ["episodic", "promoted"];
16
17
  const filterTags = Array.isArray(tags) && tags.length > 0 ? tags : undefined;
17
18
  if (!query) {
18
19
  sendJson(res, 400, { error: "query is required" });
19
20
  return;
20
21
  }
22
+ let cwd;
23
+ if (input.cwd) {
24
+ try {
25
+ cwd = validateCwd(input.cwd);
26
+ }
27
+ catch (err) {
28
+ sendJson(res, 400, { error: err instanceof Error ? err.message : "invalid cwd" });
29
+ return;
30
+ }
31
+ }
21
32
  let episodic = [];
22
33
  let promoted = [];
23
34
  if (cwd) {
@@ -1 +1 @@
1
- {"version":3,"file":"search.js","sourceRoot":"","sources":["../../../../src/daemon/routes/search.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../../../src/daemon/routes/search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { RouteHandler } from "../server.js";
2
+ export declare function createSessionCompleteHandler(): RouteHandler;
@@ -0,0 +1,36 @@
1
+ import { DatabaseSync } from "node:sqlite";
2
+ import { projectDbPath, ensureProjectDir } from "../project.js";
3
+ import { sendJson } from "../server.js";
4
+ import { runLcmMigrations } from "../../db/migration.js";
5
+ import { validateCwd } from "../validate-cwd.js";
6
+ export function createSessionCompleteHandler() {
7
+ return async (_req, res, body) => {
8
+ const input = JSON.parse(body || "{}");
9
+ const { session_id, message_count } = input;
10
+ if (!session_id || !input.cwd) {
11
+ sendJson(res, 400, { error: "session_id and cwd required" });
12
+ return;
13
+ }
14
+ let cwd;
15
+ try {
16
+ cwd = validateCwd(input.cwd);
17
+ }
18
+ catch (err) {
19
+ sendJson(res, 400, { error: err instanceof Error ? err.message : "invalid cwd" });
20
+ return;
21
+ }
22
+ ensureProjectDir(cwd);
23
+ const db = new DatabaseSync(projectDbPath(cwd));
24
+ try {
25
+ db.exec("PRAGMA busy_timeout = 5000");
26
+ runLcmMigrations(db);
27
+ db.prepare("INSERT INTO session_ingest_log (session_id, message_count) VALUES (?, ?) " +
28
+ "ON CONFLICT(session_id) DO UPDATE SET message_count = excluded.message_count").run(session_id, message_count ?? 0);
29
+ sendJson(res, 200, { recorded: true });
30
+ }
31
+ finally {
32
+ db.close();
33
+ }
34
+ };
35
+ }
36
+ //# sourceMappingURL=session-complete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-complete.js","sourceRoot":"","sources":["../../../../src/daemon/routes/session-complete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,UAAU,4BAA4B;IAC1C,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,UAAU,EAAE,aAAa,EAAE,GAAG,KAAK,CAAC;QAC5C,IAAI,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YAC9B,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAC,CAAC;YAC7D,OAAO;QACT,CAAC;QACD,IAAI,GAAW,CAAC;QAChB,IAAI,CAAC;YACH,GAAG,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC;YAClF,OAAO;QACT,CAAC;QACD,gBAAgB,CAAC,GAAG,CAAC,CAAC;QACtB,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;QAChD,IAAI,CAAC;YACH,EAAE,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;YACtC,gBAAgB,CAAC,EAAE,CAAC,CAAC;YACrB,EAAE,CAAC,OAAO,CACR,2EAA2E;gBACzE,8EAA8E,CACjF,CAAC,GAAG,CAAC,UAAU,EAAE,aAAa,IAAI,CAAC,CAAC,CAAC;YACtC,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,CAAC;gBAAS,CAAC;YACT,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -3,78 +3,91 @@ import { DatabaseSync } from "node:sqlite";
3
3
  import { projectDbPath, projectMetaPath } from "../project.js";
4
4
  import { sendJson } from "../server.js";
5
5
  import { PKG_VERSION } from "../server.js";
6
+ import { validateCwd } from "../validate-cwd.js";
6
7
  export function createStatusHandler(config, startTime, actualPort) {
7
8
  return async (_req, res, body) => {
8
- const input = JSON.parse(body || "{}");
9
- const { cwd } = input;
10
- if (!cwd) {
11
- sendJson(res, 400, { error: "cwd is required" });
12
- return;
13
- }
14
- // Calculate daemon uptime in seconds
15
- const uptime = Math.floor((Date.now() - startTime) / 1000);
16
- // Use actual port if provided, otherwise fall back to config port
17
- const port = actualPort ?? config.daemon.port;
18
- // Query project database for stats
19
- let messageCount = 0;
20
- let summaryCount = 0;
21
- let promotedCount = 0;
22
- const dbPath = projectDbPath(cwd);
23
- if (existsSync(dbPath)) {
24
- const db = new DatabaseSync(dbPath);
25
- try {
26
- db.exec("PRAGMA busy_timeout = 5000");
27
- // Count messages
28
- const msgResult = db.prepare("SELECT COUNT(*) as count FROM messages").get();
29
- messageCount = msgResult?.count ?? 0;
30
- // Count summaries
31
- const sumResult = db.prepare("SELECT COUNT(*) as count FROM summaries").get();
32
- summaryCount = sumResult?.count ?? 0;
33
- // Count promoted
34
- const promResult = db.prepare("SELECT COUNT(*) as count FROM promoted").get();
35
- promotedCount = promResult?.count ?? 0;
9
+ try {
10
+ const input = JSON.parse(body || "{}");
11
+ if (!input.cwd) {
12
+ sendJson(res, 400, { error: "cwd is required" });
13
+ return;
36
14
  }
37
- catch {
38
- // If database query fails, return zeros
39
- messageCount = 0;
40
- summaryCount = 0;
41
- promotedCount = 0;
15
+ let cwd;
16
+ try {
17
+ cwd = validateCwd(input.cwd);
42
18
  }
43
- finally {
44
- db.close();
19
+ catch (err) {
20
+ sendJson(res, 400, { error: err instanceof Error ? err.message : "invalid cwd" });
21
+ return;
45
22
  }
46
- }
47
- // Read meta.json for timestamps
48
- let lastIngest = null;
49
- let lastCompact = null;
50
- let lastPromote = null;
51
- const metaPath = projectMetaPath(cwd);
52
- if (existsSync(metaPath)) {
53
- try {
54
- const meta = JSON.parse(readFileSync(metaPath, "utf-8"));
55
- lastIngest = meta.lastIngest ?? null;
56
- lastCompact = meta.lastCompact ?? null;
57
- lastPromote = meta.lastPromote ?? null;
23
+ // Calculate daemon uptime in seconds
24
+ const uptime = Math.floor((Date.now() - startTime) / 1000);
25
+ // Use actual port if provided, otherwise fall back to config port
26
+ const port = actualPort ?? config.daemon.port;
27
+ // Query project database for stats
28
+ let messageCount = 0;
29
+ let summaryCount = 0;
30
+ let promotedCount = 0;
31
+ const dbPath = projectDbPath(cwd);
32
+ if (existsSync(dbPath)) {
33
+ const db = new DatabaseSync(dbPath);
34
+ try {
35
+ db.exec("PRAGMA busy_timeout = 5000");
36
+ // Count messages
37
+ const msgResult = db.prepare("SELECT COUNT(*) as count FROM messages").get();
38
+ messageCount = msgResult?.count ?? 0;
39
+ // Count summaries
40
+ const sumResult = db.prepare("SELECT COUNT(*) as count FROM summaries").get();
41
+ summaryCount = sumResult?.count ?? 0;
42
+ // Count promoted
43
+ const promResult = db.prepare("SELECT COUNT(*) as count FROM promoted").get();
44
+ promotedCount = promResult?.count ?? 0;
45
+ }
46
+ catch {
47
+ // If database query fails, return zeros
48
+ messageCount = 0;
49
+ summaryCount = 0;
50
+ promotedCount = 0;
51
+ }
52
+ finally {
53
+ db.close();
54
+ }
58
55
  }
59
- catch {
60
- // If meta.json parse fails, keep timestamps as null
56
+ // Read meta.json for timestamps
57
+ let lastIngest = null;
58
+ let lastCompact = null;
59
+ let lastPromote = null;
60
+ const metaPath = projectMetaPath(cwd);
61
+ if (existsSync(metaPath)) {
62
+ try {
63
+ const meta = JSON.parse(readFileSync(metaPath, "utf-8"));
64
+ lastIngest = meta.lastIngest ?? null;
65
+ lastCompact = meta.lastCompact ?? null;
66
+ lastPromote = meta.lastPromote ?? null;
67
+ }
68
+ catch {
69
+ // If meta.json parse fails, keep timestamps as null
70
+ }
61
71
  }
72
+ sendJson(res, 200, {
73
+ daemon: {
74
+ version: PKG_VERSION,
75
+ uptime,
76
+ port,
77
+ },
78
+ project: {
79
+ messageCount,
80
+ summaryCount,
81
+ promotedCount,
82
+ lastIngest,
83
+ lastCompact,
84
+ lastPromote,
85
+ },
86
+ });
87
+ }
88
+ catch (err) {
89
+ sendJson(res, 500, { error: err instanceof Error ? err.message : "status failed" });
62
90
  }
63
- sendJson(res, 200, {
64
- daemon: {
65
- version: PKG_VERSION,
66
- uptime,
67
- port,
68
- },
69
- project: {
70
- messageCount,
71
- summaryCount,
72
- promotedCount,
73
- lastIngest,
74
- lastCompact,
75
- lastPromote,
76
- },
77
- });
78
91
  };
79
92
  }
80
93
  //# sourceMappingURL=status.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../../src/daemon/routes/status.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../../src/daemon/routes/status.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,3 @@
1
1
  import type { RouteHandler } from "../server.js";
2
- export declare function createStoreHandler(): RouteHandler;
2
+ import type { DaemonConfig } from "../config.js";
3
+ export declare function createStoreHandler(config: DaemonConfig): RouteHandler;
@@ -1,32 +1,66 @@
1
- import { mkdirSync } from "node:fs";
1
+ import { mkdirSync, statSync } from "node:fs";
2
2
  import { dirname } from "node:path";
3
3
  import { DatabaseSync } from "node:sqlite";
4
- import { projectDbPath } from "../project.js";
4
+ import { projectDbPath, projectDir } from "../project.js";
5
5
  import { sendJson } from "../server.js";
6
+ import { sanitizeError } from "../safe-error.js";
6
7
  import { runLcmMigrations } from "../../db/migration.js";
7
8
  import { PromotedStore } from "../../db/promoted.js";
8
- export function createStoreHandler() {
9
+ import { ScrubEngine } from "../../scrub.js";
10
+ import { validateCwd } from "../validate-cwd.js";
11
+ const SCRUB_CACHE_MAX = 100;
12
+ const scrubCache = new Map();
13
+ async function getScrubEngine(config, projDir) {
14
+ const patternsFile = `${projDir}/sensitive-patterns.txt`;
15
+ let mtime = 0;
16
+ try {
17
+ mtime = statSync(patternsFile).mtimeMs;
18
+ }
19
+ catch { /* file absent — mtime stays 0 */ }
20
+ const cached = scrubCache.get(projDir);
21
+ if (cached && cached.mtime === mtime)
22
+ return cached.engine;
23
+ const engine = await ScrubEngine.forProject(config.security?.sensitivePatterns ?? [], projDir);
24
+ // Evict oldest entry when at capacity (simple LRU via insertion-order Map)
25
+ if (scrubCache.size >= SCRUB_CACHE_MAX) {
26
+ scrubCache.delete(scrubCache.keys().next().value);
27
+ }
28
+ scrubCache.set(projDir, { engine, mtime });
29
+ return engine;
30
+ }
31
+ export function createStoreHandler(config) {
9
32
  return async (_req, res, body) => {
10
33
  const input = JSON.parse(body || "{}");
11
- const { text, tags = [], metadata = {}, cwd } = input;
34
+ const { text, tags = [], metadata = {} } = input;
12
35
  if (!text) {
13
36
  sendJson(res, 400, { error: "text is required" });
14
37
  return;
15
38
  }
16
- const projectPath = cwd || metadata.projectPath || "";
17
- if (!projectPath) {
39
+ const rawProjectPath = input.cwd || metadata.projectPath || "";
40
+ if (!rawProjectPath) {
18
41
  sendJson(res, 400, { error: "cwd or metadata.projectPath is required" });
19
42
  return;
20
43
  }
44
+ let projectPath;
45
+ try {
46
+ projectPath = validateCwd(rawProjectPath);
47
+ }
48
+ catch (err) {
49
+ sendJson(res, 400, { error: err instanceof Error ? err.message : "invalid cwd" });
50
+ return;
51
+ }
52
+ const scrubber = await getScrubEngine(config, projectDir(projectPath));
53
+ const scrubbedText = scrubber.scrub(text);
21
54
  const dbPath = projectDbPath(projectPath);
22
55
  mkdirSync(dirname(dbPath), { recursive: true });
23
56
  const db = new DatabaseSync(dbPath);
24
57
  try {
25
58
  // Core: write to SQLite promoted table
59
+ db.exec("PRAGMA busy_timeout = 5000");
26
60
  runLcmMigrations(db);
27
61
  const store = new PromotedStore(db);
28
62
  const id = store.insert({
29
- content: text,
63
+ content: scrubbedText,
30
64
  tags,
31
65
  projectId: metadata.projectId ?? "manual",
32
66
  sessionId: metadata.sessionId ?? "manual",
@@ -36,7 +70,7 @@ export function createStoreHandler() {
36
70
  sendJson(res, 200, { stored: true, id });
37
71
  }
38
72
  catch (err) {
39
- sendJson(res, 500, { error: err instanceof Error ? err.message : "store failed" });
73
+ sendJson(res, 500, { error: sanitizeError(err instanceof Error ? err.message : "store failed") });
40
74
  }
41
75
  finally {
42
76
  db.close();
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../../src/daemon/routes/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,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,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,UAAU,kBAAkB;IAChC,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,IAAI,EAAE,IAAI,GAAG,EAAE,EAAE,QAAQ,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;QAEtD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAClD,OAAO;QACT,CAAC;QAED,MAAM,WAAW,GAAG,GAAG,IAAI,QAAQ,CAAC,WAAW,IAAI,EAAE,CAAC;QACtD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,yCAAyC,EAAE,CAAC,CAAC;YACzE,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;QAC1C,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;QACpC,IAAI,CAAC;YACH,uCAAuC;YACvC,gBAAgB,CAAC,EAAE,CAAC,CAAC;YACrB,MAAM,KAAK,GAAG,IAAI,aAAa,CAAC,EAAE,CAAC,CAAC;YAEpC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC;gBACtB,OAAO,EAAE,IAAI;gBACb,IAAI;gBACJ,SAAS,EAAE,QAAQ,CAAC,SAAS,IAAI,QAAQ;gBACzC,SAAS,EAAE,QAAQ,CAAC,SAAS,IAAI,QAAQ;gBACzC,KAAK,EAAE,QAAQ,CAAC,KAAK,IAAI,CAAC;gBAC1B,UAAU,EAAE,GAAG;aAChB,CAAC,CAAC;YAEH,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC;QACrF,CAAC;gBAAS,CAAC;YACT,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../../src/daemon/routes/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Sanitizes error messages for HTTP responses to prevent leaking
3
+ * internal file paths, stack traces, or database schema details.
4
+ */
5
+ export declare function sanitizeError(message: string): string;