@lossless-claude/lcm 0.5.0 → 0.6.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 (152) 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 +8 -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 +97 -107
  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 +5 -0
  56. package/dist/src/daemon/config.js +23 -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.js +18 -3
  80. package/dist/src/daemon/routes/promote.js.map +1 -1
  81. package/dist/src/daemon/routes/prompt-search.js +11 -2
  82. package/dist/src/daemon/routes/prompt-search.js.map +1 -1
  83. package/dist/src/daemon/routes/recent.js +11 -2
  84. package/dist/src/daemon/routes/recent.js.map +1 -1
  85. package/dist/src/daemon/routes/restore.js +89 -72
  86. package/dist/src/daemon/routes/restore.js.map +1 -1
  87. package/dist/src/daemon/routes/search.js +12 -1
  88. package/dist/src/daemon/routes/search.js.map +1 -1
  89. package/dist/src/daemon/routes/session-complete.d.ts +2 -0
  90. package/dist/src/daemon/routes/session-complete.js +36 -0
  91. package/dist/src/daemon/routes/session-complete.js.map +1 -0
  92. package/dist/src/daemon/routes/status.js +77 -64
  93. package/dist/src/daemon/routes/status.js.map +1 -1
  94. package/dist/src/daemon/routes/store.d.ts +2 -1
  95. package/dist/src/daemon/routes/store.js +42 -8
  96. package/dist/src/daemon/routes/store.js.map +1 -1
  97. package/dist/src/daemon/safe-error.d.ts +5 -0
  98. package/dist/src/daemon/safe-error.js +15 -0
  99. package/dist/src/daemon/safe-error.js.map +1 -0
  100. package/dist/src/daemon/server.d.ts +1 -0
  101. package/dist/src/daemon/server.js +33 -4
  102. package/dist/src/daemon/server.js.map +1 -1
  103. package/dist/src/daemon/validate-cwd.d.ts +5 -0
  104. package/dist/src/daemon/validate-cwd.js +38 -0
  105. package/dist/src/daemon/validate-cwd.js.map +1 -0
  106. package/dist/src/db/migration.js +8 -0
  107. package/dist/src/db/migration.js.map +1 -1
  108. package/dist/src/diagnose.js +14 -1
  109. package/dist/src/diagnose.js.map +1 -1
  110. package/dist/src/doctor/doctor.js +45 -2
  111. package/dist/src/doctor/doctor.js.map +1 -1
  112. package/dist/src/hooks/auto-heal.js +24 -1
  113. package/dist/src/hooks/auto-heal.js.map +1 -1
  114. package/dist/src/hooks/dispatch.d.ts +1 -1
  115. package/dist/src/hooks/dispatch.js +14 -1
  116. package/dist/src/hooks/dispatch.js.map +1 -1
  117. package/dist/src/hooks/session-end.d.ts +2 -0
  118. package/dist/src/hooks/session-end.js +50 -5
  119. package/dist/src/hooks/session-end.js.map +1 -1
  120. package/dist/src/hooks/session-snapshot.d.ts +12 -0
  121. package/dist/src/hooks/session-snapshot.js +88 -0
  122. package/dist/src/hooks/session-snapshot.js.map +1 -0
  123. package/dist/src/hooks/user-prompt.js +17 -5
  124. package/dist/src/hooks/user-prompt.js.map +1 -1
  125. package/dist/src/import-summary.d.ts +4 -0
  126. package/dist/src/import-summary.js +34 -0
  127. package/dist/src/import-summary.js.map +1 -0
  128. package/dist/src/import.d.ts +11 -1
  129. package/dist/src/import.js +218 -88
  130. package/dist/src/import.js.map +1 -1
  131. package/dist/src/installer/settings.d.ts +5 -0
  132. package/dist/src/installer/settings.js +73 -0
  133. package/dist/src/installer/settings.js.map +1 -0
  134. package/dist/src/mcp/server.d.ts +15 -0
  135. package/dist/src/mcp/server.js +78 -5
  136. package/dist/src/mcp/server.js.map +1 -1
  137. package/dist/src/promotion/detector.js +19 -5
  138. package/dist/src/promotion/detector.js.map +1 -1
  139. package/dist/src/scrub.js +26 -0
  140. package/dist/src/scrub.js.map +1 -1
  141. package/dist/src/stats.d.ts +1 -0
  142. package/dist/src/stats.js +5 -0
  143. package/dist/src/stats.js.map +1 -1
  144. package/dist/src/store/conversation-store.js +2 -1
  145. package/dist/src/store/conversation-store.js.map +1 -1
  146. package/dist/src/store/regex-safety.d.ts +1 -0
  147. package/dist/src/store/regex-safety.js +22 -0
  148. package/dist/src/store/regex-safety.js.map +1 -0
  149. package/dist/src/store/summary-store.js +2 -1
  150. package/dist/src/store/summary-store.js.map +1 -1
  151. package/lcm.mjs +20 -1
  152. package/package.json +5 -2
@@ -0,0 +1,34 @@
1
+ import { formatNumber, formatRatio } from "./stats.js";
2
+ export function printImportSummary(result, opts = {}) {
3
+ const sessionsProcessed = result.imported + result.skippedEmpty + result.failed;
4
+ const tokenSuffix = result.totalTokens > 0 ? `, ${formatNumber(result.totalTokens)} tokens` : "";
5
+ console.log(` ${result.imported} sessions imported (${result.totalMessages} messages${tokenSuffix})`);
6
+ if (result.skippedEmpty > 0)
7
+ console.log(` ${result.skippedEmpty} skipped (empty transcript)`);
8
+ if (result.failed > 0)
9
+ console.log(` ${result.failed} failed`);
10
+ if (opts.replay) {
11
+ console.log(" [replay] Sessions compacted sequentially with threaded context.");
12
+ }
13
+ // Show compression summary when tokens were ingested
14
+ if (result.totalTokens > 0) {
15
+ const border = "\u2500".repeat(41);
16
+ console.log();
17
+ console.log(` ${border}`);
18
+ const rows = [
19
+ ["Sessions processed", String(sessionsProcessed)],
20
+ ["Tokens ingested", formatNumber(result.totalTokens)],
21
+ ];
22
+ if (opts.replay && result.totalTokens > result.tokensAfter) {
23
+ const ratio = formatRatio(result.totalTokens, result.tokensAfter);
24
+ const freed = result.totalTokens - result.tokensAfter;
25
+ rows.push(["Tokens after", formatNumber(result.tokensAfter)], ["Compression ratio", `${ratio}\u00d7`], ["Tokens freed", formatNumber(freed)]);
26
+ }
27
+ const labelWidth = Math.max(...rows.map(([l]) => l.length));
28
+ for (const [label, value] of rows) {
29
+ console.log(` ${label.padEnd(labelWidth)} : ${value}`);
30
+ }
31
+ console.log(` ${border}`);
32
+ }
33
+ }
34
+ //# sourceMappingURL=import-summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import-summary.js","sourceRoot":"","sources":["../../src/import-summary.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEvD,MAAM,UAAU,kBAAkB,CAChC,MAAoB,EACpB,OAA6B,EAAE;IAE/B,MAAM,iBAAiB,GAAG,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC;IAChF,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,YAAY,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IACjG,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,QAAQ,uBAAuB,MAAM,CAAC,aAAa,YAAY,WAAW,GAAG,CAAC,CAAC;IACvG,IAAI,MAAM,CAAC,YAAY,GAAG,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,YAAY,6BAA6B,CAAC,CAAC;IAChG,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,MAAM,SAAS,CAAC,CAAC;IAEhE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,mEAAmE,CAAC,CAAC;IACnF,CAAC;IAED,qDAAqD;IACrD,IAAI,MAAM,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACnC,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC;QAE3B,MAAM,IAAI,GAAuB;YAC/B,CAAC,oBAAoB,EAAE,MAAM,CAAC,iBAAiB,CAAC,CAAC;YACjD,CAAC,iBAAiB,EAAE,YAAY,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;SACtD,CAAC;QAEF,IAAI,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;YAC3D,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;YAClE,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;YACtD,IAAI,CAAC,IAAI,CACP,CAAC,cAAc,EAAE,YAAY,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,EAClD,CAAC,mBAAmB,EAAE,GAAG,KAAK,QAAQ,CAAC,EACvC,CAAC,cAAc,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,CACtC,CAAC;QACJ,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAC5D,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;YAClC,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC;QAC1D,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC"}
@@ -1,20 +1,30 @@
1
1
  import type { DaemonClient } from "./daemon/client.js";
2
+ import type { ProgressState } from "./cli/progress-state.js";
3
+ export type ImportProvider = "claude" | "codex" | "all";
2
4
  interface ImportOptions {
3
5
  all?: boolean;
4
6
  verbose?: boolean;
5
7
  dryRun?: boolean;
6
8
  cwd?: string;
7
9
  replay?: boolean;
10
+ /** Which transcript provider to import from (default: "claude") */
11
+ provider?: ImportProvider;
12
+ /** Called with state patches as each session is processed — used by the ninja renderer */
13
+ onProgress?: (patch: Partial<ProgressState>) => void;
8
14
  /** Override ~/.claude/projects path — used in tests only */
9
15
  _claudeProjectsDir?: string;
10
16
  /** Override ~/.lossless-claude path — used in tests only */
11
17
  _lcmDir?: string;
18
+ /** Override ~/.codex path — used in tests only */
19
+ _codexDir?: string;
12
20
  }
13
- interface ImportResult {
21
+ export interface ImportResult {
14
22
  imported: number;
15
23
  skippedEmpty: number;
16
24
  failed: number;
17
25
  totalMessages: number;
26
+ totalTokens: number;
27
+ tokensAfter: number;
18
28
  }
19
29
  export declare function cwdToProjectHash(cwd: string): string;
20
30
  export declare function findSessionFiles(projectDir: string): {
@@ -1,6 +1,10 @@
1
- import { readdirSync, readFileSync, existsSync, statSync } from "node:fs";
1
+ import { readdirSync, readFileSync, existsSync, lstatSync } from "node:fs";
2
2
  import { join, basename } from "node:path";
3
3
  import { homedir } from "node:os";
4
+ import { DatabaseSync } from "node:sqlite";
5
+ import { formatNumber, formatRatio } from "./stats.js";
6
+ import { findAllCodexTranscripts, extractCodexSessionCwd } from "./codex-transcript.js";
7
+ import { projectDbPath, projectId } from "./daemon/project.js";
4
8
  export function cwdToProjectHash(cwd) {
5
9
  // Claude Code uses the cwd with slashes replaced by dashes, keeping the leading dash
6
10
  // e.g. /Users/pedro/Developer/lossless-claude → -Users-pedro-Developer-lossless-claude
@@ -32,30 +36,65 @@ export function findSessionFiles(projectDir) {
32
36
  const files = [];
33
37
  if (!existsSync(projectDir))
34
38
  return files;
39
+ // Track which session IDs have a flat (project-root) transcript so we can
40
+ // deduplicate when the same session also has a nested copy.
41
+ const flatSessionIds = new Set();
35
42
  for (const entry of readdirSync(projectDir, { withFileTypes: true })) {
36
- if (entry.isFile() && entry.name.endsWith('.jsonl')) {
43
+ // Layout B (flat): <projectDir>/<session-id>.jsonl
44
+ if (entry.isFile() && !entry.isSymbolicLink() && entry.name.endsWith('.jsonl')) {
37
45
  try {
46
+ const filePath = join(projectDir, entry.name);
47
+ const st = lstatSync(filePath);
48
+ if (st.isSymbolicLink())
49
+ continue; // skip symlinks
50
+ const sessionId = basename(entry.name, '.jsonl');
38
51
  files.push({
39
- path: join(projectDir, entry.name),
40
- sessionId: basename(entry.name, '.jsonl'),
41
- mtime: statSync(join(projectDir, entry.name)).mtimeMs,
52
+ path: filePath,
53
+ sessionId,
54
+ mtime: st.mtimeMs,
42
55
  });
56
+ flatSessionIds.add(sessionId);
43
57
  }
44
58
  catch {
45
59
  // Skip entries that can't be stat'd (file deleted or permissions issue)
46
60
  continue;
47
61
  }
48
62
  }
49
- if (entry.isDirectory()) {
63
+ if (entry.isDirectory() && !entry.isSymbolicLink()) {
64
+ // Layout A (nested): <projectDir>/<session-id>/<session-id>.jsonl
65
+ const nestedTranscript = join(projectDir, entry.name, `${entry.name}.jsonl`);
66
+ if (existsSync(nestedTranscript)) {
67
+ try {
68
+ const nestedStat = lstatSync(nestedTranscript);
69
+ if (nestedStat.isSymbolicLink()) {
70
+ // skip symlinks
71
+ }
72
+ else if (nestedStat.isFile()) {
73
+ files.push({
74
+ path: nestedTranscript,
75
+ sessionId: entry.name,
76
+ mtime: nestedStat.mtimeMs,
77
+ });
78
+ }
79
+ }
80
+ catch {
81
+ // Skip entries that can't be stat'd
82
+ }
83
+ }
84
+ // Subagent transcripts: <projectDir>/<session-id>/subagents/<agent-id>.jsonl
50
85
  const subagentsDir = join(projectDir, entry.name, 'subagents');
51
86
  if (existsSync(subagentsDir)) {
52
87
  for (const sub of readdirSync(subagentsDir, { withFileTypes: true })) {
53
- if (sub.isFile() && sub.name.endsWith('.jsonl')) {
88
+ if (sub.isFile() && !sub.isSymbolicLink() && sub.name.endsWith('.jsonl')) {
54
89
  try {
90
+ const subPath = join(subagentsDir, sub.name);
91
+ const subSt = lstatSync(subPath);
92
+ if (subSt.isSymbolicLink())
93
+ continue; // skip symlinks
55
94
  files.push({
56
- path: join(subagentsDir, sub.name),
95
+ path: subPath,
57
96
  sessionId: basename(sub.name, '.jsonl'),
58
- mtime: statSync(join(subagentsDir, sub.name)).mtimeMs,
97
+ mtime: subSt.mtimeMs,
59
98
  });
60
99
  }
61
100
  catch {
@@ -67,7 +106,16 @@ export function findSessionFiles(projectDir) {
67
106
  }
68
107
  }
69
108
  }
70
- return files.sort((a, b) => {
109
+ // Deduplicate: when a session has both a flat and nested transcript,
110
+ // keep only the flat file (the canonical source in newer Claude Code versions).
111
+ // Subagent files (inside subagents/) are kept unconditionally because their
112
+ // paths never match the nested transcript pattern below.
113
+ const nestedSuffix = (sid) => join(sid, `${sid}.jsonl`);
114
+ const deduped = files.filter(f => {
115
+ const isNested = f.path.endsWith(nestedSuffix(f.sessionId));
116
+ return !isNested || !flatSessionIds.has(f.sessionId);
117
+ });
118
+ return deduped.sort((a, b) => {
71
119
  const mtimeDiff = a.mtime - b.mtime;
72
120
  if (mtimeDiff !== 0)
73
121
  return mtimeDiff;
@@ -77,97 +125,179 @@ export function findSessionFiles(projectDir) {
77
125
  return a.path.localeCompare(b.path);
78
126
  });
79
127
  }
80
- export async function importSessions(client, options = {}) {
81
- const claudeProjectsDir = options._claudeProjectsDir ?? join(homedir(), '.claude', 'projects');
82
- const result = { imported: 0, skippedEmpty: 0, failed: 0, totalMessages: 0 };
83
- const projectDirs = [];
84
- if (options.all) {
85
- if (!existsSync(claudeProjectsDir))
86
- return result;
87
- const projectMap = buildProjectMap(options._lcmDir);
88
- for (const entry of readdirSync(claudeProjectsDir, { withFileTypes: true })) {
89
- if (!entry.isDirectory())
90
- continue;
91
- const cwd = projectMap.get(entry.name);
92
- if (!cwd)
93
- continue;
94
- projectDirs.push({ dir: join(claudeProjectsDir, entry.name), cwd });
128
+ /**
129
+ * Checks if a session has already been recorded in session_ingest_log,
130
+ * indicating it was fully ingested in a previous run.
131
+ */
132
+ function isSessionAlreadyIngested(cwd, sessionId, lcmDir) {
133
+ try {
134
+ const dbPath = lcmDir
135
+ ? join(lcmDir, "projects", projectId(cwd), "db.sqlite")
136
+ : projectDbPath(cwd);
137
+ if (!existsSync(dbPath)) {
138
+ return false;
95
139
  }
96
- }
97
- else {
98
- const cwd = options.cwd ?? process.cwd();
99
- const hash = cwdToProjectHash(cwd);
100
- const dir = join(claudeProjectsDir, hash);
101
- if (existsSync(dir)) {
102
- projectDirs.push({ dir, cwd });
140
+ const db = new DatabaseSync(dbPath);
141
+ try {
142
+ db.exec("PRAGMA busy_timeout = 5000");
143
+ const row = db.prepare("SELECT 1 FROM session_ingest_log WHERE session_id = ?").get(sessionId);
144
+ return !!row;
145
+ }
146
+ finally {
147
+ db.close();
103
148
  }
104
149
  }
105
- for (const { dir, cwd } of projectDirs) {
106
- const sessionFiles = findSessionFiles(dir);
107
- let previousSummary; // resets per project
108
- for (const { path, sessionId } of sessionFiles) {
109
- if (options.dryRun) {
110
- if (options.verbose) {
111
- const replayNote = options.replay ? " (would compact)" : "";
112
- console.log(` [dry-run] ${sessionId}${replayNote}`);
113
- }
114
- result.imported++;
115
- continue;
150
+ catch {
151
+ // Table may not exist yet or db is inaccessible — proceed with import
152
+ return false;
153
+ }
154
+ }
155
+ async function ingestSessionList(client, sessions, options, result) {
156
+ let previousSummary;
157
+ const total = sessions.length;
158
+ for (const { path, sessionId, cwd } of sessions) {
159
+ if (options.dryRun) {
160
+ if (options.verbose) {
161
+ const replayNote = options.replay ? " (would compact)" : "";
162
+ console.log(` [dry-run] ${sessionId}${replayNote}`);
116
163
  }
117
- try {
118
- const res = await client.post('/ingest', {
119
- session_id: sessionId,
120
- cwd,
121
- transcript_path: path,
122
- });
123
- if (res.ingested === 0 && res.totalTokens === 0) {
124
- result.skippedEmpty++;
125
- if (options.verbose)
126
- console.log(` \u2298 ${sessionId}: empty or already ingested`);
127
- }
128
- else {
129
- result.imported++;
130
- result.totalMessages += res.ingested;
131
- if (options.verbose)
132
- console.log(` \u2713 ${sessionId}: ${res.ingested} messages`);
164
+ result.imported++;
165
+ options.onProgress?.({ completed: result.imported + result.skippedEmpty + result.failed, total, current: { sessionId, messages: 0, tokens: 0, startedAt: Date.now() } });
166
+ continue;
167
+ }
168
+ // Skip sessions already recorded in session_ingest_log (unless in replay mode,
169
+ // where compaction must still run to keep the temporal chain intact).
170
+ if (!options.replay && isSessionAlreadyIngested(cwd, sessionId, options._lcmDir)) {
171
+ result.skippedEmpty++;
172
+ if (options.verbose)
173
+ console.log(` ↩️ ${sessionId}: already fully ingested`);
174
+ options.onProgress?.({ completed: result.imported + result.skippedEmpty + result.failed, total, current: { sessionId, messages: 0, tokens: 0, startedAt: Date.now() } });
175
+ continue;
176
+ }
177
+ try {
178
+ const res = await client.post('/ingest', {
179
+ session_id: sessionId,
180
+ cwd,
181
+ transcript_path: path,
182
+ });
183
+ if (res.ingested === 0 && res.totalTokens === 0) {
184
+ result.skippedEmpty++;
185
+ if (options.verbose)
186
+ console.log(` \u23ed\ufe0f ${sessionId}: empty or already ingested`);
187
+ }
188
+ else {
189
+ result.imported++;
190
+ result.totalMessages += res.ingested;
191
+ // In replay mode, totalTokens is sourced from compact's tokensBefore to avoid
192
+ // double-counting (compact covers already-ingested sessions too).
193
+ if (!options.replay) {
194
+ result.totalTokens += res.totalTokens;
133
195
  }
134
- // Replay: compact immediately after every session (even already-ingested ones)
135
- // so that re-runs are idempotent and the temporal chain stays intact.
136
- if (options.replay) {
137
- try {
138
- const compactRes = await client.post('/compact', {
139
- session_id: sessionId,
140
- cwd,
141
- skip_ingest: true,
142
- client: 'claude',
143
- ...(previousSummary !== undefined ? { previous_summary: previousSummary } : {}),
144
- });
145
- const hadPrevious = previousSummary !== undefined;
146
- if (compactRes.latestSummaryContent !== undefined) {
147
- previousSummary = compactRes.latestSummaryContent;
196
+ if (options.verbose)
197
+ console.log(` \u2705 ${sessionId}: ${res.ingested} messages (${formatNumber(res.totalTokens)} tokens)`);
198
+ }
199
+ // Replay: compact immediately after every session (even already-ingested ones)
200
+ // so that re-runs are idempotent and the temporal chain stays intact.
201
+ if (options.replay) {
202
+ try {
203
+ const compactRes = await client.post('/compact', {
204
+ session_id: sessionId,
205
+ cwd,
206
+ skip_ingest: true,
207
+ client: 'claude',
208
+ ...(previousSummary !== undefined ? { previous_summary: previousSummary } : {}),
209
+ });
210
+ const hadPrevious = previousSummary !== undefined;
211
+ if (compactRes.latestSummaryContent !== undefined) {
212
+ previousSummary = compactRes.latestSummaryContent;
213
+ }
214
+ // Use compact's tokensBefore as the authoritative token count for this session.
215
+ // This avoids under-reporting when /ingest returns totalTokens=0 (already-ingested).
216
+ if (typeof compactRes.tokensBefore === 'number') {
217
+ result.totalTokens += compactRes.tokensBefore;
218
+ }
219
+ if (typeof compactRes.tokensAfter === 'number') {
220
+ result.tokensAfter += compactRes.tokensAfter;
221
+ }
222
+ if (options.verbose) {
223
+ const ctx = hadPrevious ? ' (with prior context)' : '';
224
+ if (typeof compactRes.tokensBefore === 'number' && typeof compactRes.tokensAfter === 'number' && compactRes.tokensAfter < compactRes.tokensBefore) {
225
+ const ratio = formatRatio(compactRes.tokensBefore, compactRes.tokensAfter);
226
+ console.log(` \ud83e\udde0 ${sessionId}: ${formatNumber(compactRes.tokensBefore)} \u2192 ${formatNumber(compactRes.tokensAfter)} (${ratio}\u00d7)${ctx}`);
148
227
  }
149
- if (options.verbose) {
150
- const ctx = hadPrevious ? ' (with prior context)' : '';
228
+ else {
151
229
  console.log(` \ud83e\udde0 ${sessionId}: compacted${ctx}`);
152
230
  }
153
231
  }
154
- catch (err) {
155
- // Non-fatal: import succeeded; compact failure breaks the chain at this link.
156
- previousSummary = undefined;
157
- if (options.verbose) {
158
- console.error(` ⚠ [replay] compact failed for session ${sessionId}: ${err instanceof Error ? err.message : 'unknown error'}`);
159
- }
160
- }
232
+ }
233
+ catch (err) {
234
+ // Non-fatal: import succeeded; compact failure breaks the chain at this link.
235
+ previousSummary = undefined;
236
+ // Always warn on chain breakage so users know the DAG is incomplete,
237
+ // regardless of whether --verbose was passed.
238
+ console.error(` \u26a0\ufe0f [replay] compact failed for session ${sessionId}: ${err instanceof Error ? err.message : 'unknown error'}`);
239
+ // Fall back to ingest's totalTokens so they aren't silently lost.
240
+ result.totalTokens += res.totalTokens;
161
241
  }
162
242
  }
163
- catch (err) {
164
- result.failed++;
165
- if (options.replay)
166
- previousSummary = undefined; // chain broken by ingest failure
167
- if (options.verbose)
168
- console.log(` \u2717 ${sessionId}: ${err instanceof Error ? err.message : "failed"}`);
243
+ options.onProgress?.({ completed: result.imported + result.skippedEmpty + result.failed, total, current: { sessionId, messages: 0, tokens: 0, startedAt: Date.now() } });
244
+ }
245
+ catch (err) {
246
+ result.failed++;
247
+ if (options.replay)
248
+ previousSummary = undefined; // chain broken by ingest failure
249
+ if (options.verbose)
250
+ console.log(` \u274c ${sessionId}: ${err instanceof Error ? err.message : "failed"}`);
251
+ options.onProgress?.({ completed: result.imported + result.skippedEmpty + result.failed, total, current: { sessionId, messages: 0, tokens: 0, startedAt: Date.now() } });
252
+ }
253
+ }
254
+ }
255
+ // ---------------------------------------------------------------------------
256
+ // Public entry point
257
+ // ---------------------------------------------------------------------------
258
+ export async function importSessions(client, options = {}) {
259
+ const provider = options.provider ?? "claude";
260
+ const result = { imported: 0, skippedEmpty: 0, failed: 0, totalMessages: 0, totalTokens: 0, tokensAfter: 0 };
261
+ // --- Claude Code sessions ---
262
+ if (provider === "claude" || provider === "all") {
263
+ const claudeProjectsDir = options._claudeProjectsDir ?? join(homedir(), '.claude', 'projects');
264
+ const projectDirs = [];
265
+ if (options.all) {
266
+ if (existsSync(claudeProjectsDir)) {
267
+ const projectMap = buildProjectMap(options._lcmDir);
268
+ for (const entry of readdirSync(claudeProjectsDir, { withFileTypes: true })) {
269
+ if (!entry.isDirectory())
270
+ continue;
271
+ const cwd = projectMap.get(entry.name);
272
+ if (!cwd)
273
+ continue;
274
+ projectDirs.push({ dir: join(claudeProjectsDir, entry.name), cwd });
275
+ }
276
+ }
277
+ }
278
+ else {
279
+ const cwd = options.cwd ?? process.cwd();
280
+ const hash = cwdToProjectHash(cwd);
281
+ const dir = join(claudeProjectsDir, hash);
282
+ if (existsSync(dir)) {
283
+ projectDirs.push({ dir, cwd });
169
284
  }
170
285
  }
286
+ for (const { dir, cwd } of projectDirs) {
287
+ const sessionFiles = findSessionFiles(dir);
288
+ await ingestSessionList(client, sessionFiles.map(f => ({ ...f, cwd })), options, result);
289
+ }
290
+ }
291
+ // --- Codex CLI sessions ---
292
+ if (provider === "codex" || provider === "all") {
293
+ const codexTranscripts = findAllCodexTranscripts(options._codexDir);
294
+ const codexSessions = codexTranscripts.map(f => ({
295
+ path: f.path,
296
+ sessionId: f.sessionId,
297
+ // Prefer the cwd embedded in the transcript; fall back to process.cwd()
298
+ cwd: extractCodexSessionCwd(f.path) ?? process.cwd(),
299
+ }));
300
+ await ingestSessionList(client, codexSessions, options, result);
171
301
  }
172
302
  return result;
173
303
  }
@@ -1 +1 @@
1
- {"version":3,"file":"import.js","sourceRoot":"","sources":["../../src/import.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"import.js","sourceRoot":"","sources":["../../src/import.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare const REQUIRED_HOOKS: {
2
+ event: string;
3
+ command: string;
4
+ }[];
5
+ export declare function mergeClaudeSettings(existing: any): any;
@@ -0,0 +1,73 @@
1
+ export const REQUIRED_HOOKS = [
2
+ { event: "PreCompact", command: "lcm compact --hook" },
3
+ { event: "SessionStart", command: "lcm restore" },
4
+ { event: "SessionEnd", command: "lcm session-end" },
5
+ { event: "UserPromptSubmit", command: "lcm user-prompt" },
6
+ { event: "Stop", command: "lcm session-snapshot" },
7
+ ];
8
+ export function mergeClaudeSettings(existing) {
9
+ const settings = JSON.parse(JSON.stringify(existing));
10
+ settings.hooks = (settings.hooks && typeof settings.hooks === "object" && !Array.isArray(settings.hooks)) ? settings.hooks : {};
11
+ settings.mcpServers = (settings.mcpServers && typeof settings.mcpServers === "object" && !Array.isArray(settings.mcpServers)) ? settings.mcpServers : {};
12
+ // Migrate old hook commands to current form
13
+ const OLD_TO_NEW = {
14
+ "lossless-claude compact": "lcm compact --hook",
15
+ "lossless-claude restore": "lcm restore",
16
+ "lossless-claude session-end": "lcm session-end",
17
+ "lossless-claude user-prompt": "lcm user-prompt",
18
+ // Migrate pre-#90 direct installs that registered without --hook
19
+ "lcm compact": "lcm compact --hook",
20
+ };
21
+ for (const event of Object.keys(settings.hooks)) {
22
+ if (!Array.isArray(settings.hooks[event]))
23
+ continue;
24
+ for (const entry of settings.hooks[event]) {
25
+ if (!Array.isArray(entry.hooks))
26
+ continue;
27
+ for (const h of entry.hooks) {
28
+ if (h.command && OLD_TO_NEW[h.command]) {
29
+ h.command = OLD_TO_NEW[h.command];
30
+ }
31
+ }
32
+ // Deduplicate commands within each hook entry after migration
33
+ const seen = new Set();
34
+ entry.hooks = entry.hooks.filter((h) => {
35
+ const key = h.command ?? '';
36
+ if (seen.has(key))
37
+ return false;
38
+ seen.add(key);
39
+ return true;
40
+ });
41
+ }
42
+ }
43
+ // Remove legacy MCP server entries
44
+ delete settings.mcpServers["lossless-claude"];
45
+ // Remove lcm hooks from settings.json — plugin.json owns them.
46
+ // Having hooks in both causes double-firing.
47
+ for (const { event, command } of REQUIRED_HOOKS) {
48
+ if (!Array.isArray(settings.hooks[event]))
49
+ continue;
50
+ settings.hooks[event] = settings.hooks[event]
51
+ .map((entry) => {
52
+ if (!Array.isArray(entry.hooks))
53
+ return entry;
54
+ return {
55
+ ...entry,
56
+ hooks: entry.hooks.filter((h) => h.command !== command),
57
+ };
58
+ })
59
+ .filter((entry) => !Array.isArray(entry.hooks) || entry.hooks.length > 0);
60
+ if (settings.hooks[event].length === 0)
61
+ delete settings.hooks[event];
62
+ }
63
+ if (Object.keys(settings.hooks).length === 0)
64
+ delete settings.hooks;
65
+ // MCP server is now owned by settings.json (written by lcm install / doctor)
66
+ // Do NOT delete mcpServers["lcm"] here — it's managed separately from hooks
67
+ // which are plugin-owned. This prevents the auto-heal loop where doctor adds
68
+ // the MCP entry and hooks cleanup removes it.
69
+ if (Object.keys(settings.mcpServers).length === 0)
70
+ delete settings.mcpServers;
71
+ return settings;
72
+ }
73
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/installer/settings.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,5 @@
1
+ import { DaemonClient } from "../daemon/client.js";
2
+ import { ensureDaemon } from "../daemon/lifecycle.js";
1
3
  export declare function getMcpToolDefinitions(): {
2
4
  name: string;
3
5
  description: string;
@@ -6,4 +8,17 @@ export declare function getMcpToolDefinitions(): {
6
8
  properties: {};
7
9
  };
8
10
  }[];
11
+ export type DaemonRequestOpts = {
12
+ port: number;
13
+ pidFilePath: string;
14
+ _ensureDaemon?: typeof ensureDaemon;
15
+ };
16
+ /** Exported for testing. Calls a daemon route with auto-restart + retry on network failure. */
17
+ export declare function handleDaemonRequest(client: Pick<DaemonClient, "post">, route: string, body: Record<string, unknown>, opts: DaemonRequestOpts): Promise<{
18
+ content: Array<{
19
+ type: "text";
20
+ text: string;
21
+ }>;
22
+ isError?: boolean;
23
+ }>;
9
24
  export declare function startMcpServer(): Promise<void>;