@clauderecallhq/cli 0.0.1 → 0.11.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 (277) hide show
  1. package/LICENSE +33 -0
  2. package/README.md +543 -3
  3. package/README.public.md +523 -0
  4. package/dist/cli.js +354 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/activate.js +69 -0
  7. package/dist/commands/activate.js.map +1 -0
  8. package/dist/commands/audit-secrets.js +103 -0
  9. package/dist/commands/audit-secrets.js.map +1 -0
  10. package/dist/commands/blame.js +35 -0
  11. package/dist/commands/blame.js.map +1 -0
  12. package/dist/commands/config-verification.js +18 -0
  13. package/dist/commands/config-verification.js.map +1 -0
  14. package/dist/commands/context.js +144 -0
  15. package/dist/commands/context.js.map +1 -0
  16. package/dist/commands/correlate.js +70 -0
  17. package/dist/commands/correlate.js.map +1 -0
  18. package/dist/commands/digest.js +78 -0
  19. package/dist/commands/digest.js.map +1 -0
  20. package/dist/commands/health.js +62 -0
  21. package/dist/commands/health.js.map +1 -0
  22. package/dist/commands/index.js +247 -0
  23. package/dist/commands/index.js.map +1 -0
  24. package/dist/commands/install-extension.js +138 -0
  25. package/dist/commands/install-extension.js.map +1 -0
  26. package/dist/commands/license.js +39 -0
  27. package/dist/commands/license.js.map +1 -0
  28. package/dist/commands/list.js +47 -0
  29. package/dist/commands/list.js.map +1 -0
  30. package/dist/commands/mcp.js +29 -0
  31. package/dist/commands/mcp.js.map +1 -0
  32. package/dist/commands/open.js +28 -0
  33. package/dist/commands/open.js.map +1 -0
  34. package/dist/commands/paste.js +154 -0
  35. package/dist/commands/paste.js.map +1 -0
  36. package/dist/commands/projects.js +36 -0
  37. package/dist/commands/projects.js.map +1 -0
  38. package/dist/commands/search.js +67 -0
  39. package/dist/commands/search.js.map +1 -0
  40. package/dist/commands/semantic.js +173 -0
  41. package/dist/commands/semantic.js.map +1 -0
  42. package/dist/commands/show.js +121 -0
  43. package/dist/commands/show.js.map +1 -0
  44. package/dist/commands/start.js +47 -0
  45. package/dist/commands/start.js.map +1 -0
  46. package/dist/commands/stats.js +133 -0
  47. package/dist/commands/stats.js.map +1 -0
  48. package/dist/commands/status.js +45 -0
  49. package/dist/commands/status.js.map +1 -0
  50. package/dist/commands/stop.js +29 -0
  51. package/dist/commands/stop.js.map +1 -0
  52. package/dist/commands/thread.js +396 -0
  53. package/dist/commands/thread.js.map +1 -0
  54. package/dist/context/formatter.js +103 -0
  55. package/dist/context/formatter.js.map +1 -0
  56. package/dist/daemon/auto-tag-config.js +103 -0
  57. package/dist/daemon/auto-tag-config.js.map +1 -0
  58. package/dist/daemon/auto-tag-config.test.js +72 -0
  59. package/dist/daemon/auto-tag-config.test.js.map +1 -0
  60. package/dist/daemon/auto-title-config.js +70 -0
  61. package/dist/daemon/auto-title-config.js.map +1 -0
  62. package/dist/daemon/bulk-title-jobs.js +170 -0
  63. package/dist/daemon/bulk-title-jobs.js.map +1 -0
  64. package/dist/daemon/correlator.js +320 -0
  65. package/dist/daemon/correlator.js.map +1 -0
  66. package/dist/daemon/discover.js +316 -0
  67. package/dist/daemon/discover.js.map +1 -0
  68. package/dist/daemon/editor-detection.js +186 -0
  69. package/dist/daemon/editor-detection.js.map +1 -0
  70. package/dist/daemon/entrypoint.js +55 -0
  71. package/dist/daemon/entrypoint.js.map +1 -0
  72. package/dist/daemon/git-correlator.js +256 -0
  73. package/dist/daemon/git-correlator.js.map +1 -0
  74. package/dist/daemon/mcp-installer.js +108 -0
  75. package/dist/daemon/mcp-installer.js.map +1 -0
  76. package/dist/daemon/onboarding-state.js +140 -0
  77. package/dist/daemon/onboarding-state.js.map +1 -0
  78. package/dist/daemon/pidfile.js +57 -0
  79. package/dist/daemon/pidfile.js.map +1 -0
  80. package/dist/daemon/ports.js +48 -0
  81. package/dist/daemon/ports.js.map +1 -0
  82. package/dist/daemon/scanProgressRegistry.js +62 -0
  83. package/dist/daemon/scanProgressRegistry.js.map +1 -0
  84. package/dist/daemon/server.js +2010 -0
  85. package/dist/daemon/server.js.map +1 -0
  86. package/dist/daemon/tag-scanner/anthropic-client.js +40 -0
  87. package/dist/daemon/tag-scanner/anthropic-client.js.map +1 -0
  88. package/dist/daemon/tag-scanner/autopilot.js +131 -0
  89. package/dist/daemon/tag-scanner/autopilot.js.map +1 -0
  90. package/dist/daemon/tag-scanner/claude-cli-driver.js +250 -0
  91. package/dist/daemon/tag-scanner/claude-cli-driver.js.map +1 -0
  92. package/dist/daemon/tag-scanner/orchestrator.js +88 -0
  93. package/dist/daemon/tag-scanner/orchestrator.js.map +1 -0
  94. package/dist/daemon/tag-scanner/prompt.js +46 -0
  95. package/dist/daemon/tag-scanner/prompt.js.map +1 -0
  96. package/dist/daemon/tag-scanner/prompt.test.js +48 -0
  97. package/dist/daemon/tag-scanner/prompt.test.js.map +1 -0
  98. package/dist/daemon/tag-scanner/scan-state.js +49 -0
  99. package/dist/daemon/tag-scanner/scan-state.js.map +1 -0
  100. package/dist/daemon/tag-scanner/session-fetcher.js +82 -0
  101. package/dist/daemon/tag-scanner/session-fetcher.js.map +1 -0
  102. package/dist/daemon/tag-scanner/session-fetcher.test.js +34 -0
  103. package/dist/daemon/tag-scanner/session-fetcher.test.js.map +1 -0
  104. package/dist/daemon/tag-scanner/validator.js +50 -0
  105. package/dist/daemon/tag-scanner/validator.js.map +1 -0
  106. package/dist/daemon/tag-scanner/validator.test.js +41 -0
  107. package/dist/daemon/tag-scanner/validator.test.js.map +1 -0
  108. package/dist/daemon/terminal-registry.js +443 -0
  109. package/dist/daemon/terminal-registry.js.map +1 -0
  110. package/dist/daemon/ui.js +64 -0
  111. package/dist/daemon/ui.js.map +1 -0
  112. package/dist/daemon/watcher.js +256 -0
  113. package/dist/daemon/watcher.js.map +1 -0
  114. package/dist/db/client.js +22 -0
  115. package/dist/db/client.js.map +1 -0
  116. package/dist/db/schema.js +496 -0
  117. package/dist/db/schema.js.map +1 -0
  118. package/dist/license/api-base.js +13 -0
  119. package/dist/license/api-base.js.map +1 -0
  120. package/dist/license/manager.js +43 -0
  121. package/dist/license/manager.js.map +1 -0
  122. package/dist/license/public-key.js +19 -0
  123. package/dist/license/public-key.js.map +1 -0
  124. package/dist/license/storage.js +27 -0
  125. package/dist/license/storage.js.map +1 -0
  126. package/dist/license/verify.js +23 -0
  127. package/dist/license/verify.js.map +1 -0
  128. package/dist/mcp/audit.js +126 -0
  129. package/dist/mcp/audit.js.map +1 -0
  130. package/dist/mcp/prompts.js +180 -0
  131. package/dist/mcp/prompts.js.map +1 -0
  132. package/dist/mcp/server.js +502 -0
  133. package/dist/mcp/server.js.map +1 -0
  134. package/dist/mcp/thread-tools.js +363 -0
  135. package/dist/mcp/thread-tools.js.map +1 -0
  136. package/dist/mcp/write-tools.js +239 -0
  137. package/dist/mcp/write-tools.js.map +1 -0
  138. package/dist/parser/jsonl.js +150 -0
  139. package/dist/parser/jsonl.js.map +1 -0
  140. package/dist/semantic/chunker.js +47 -0
  141. package/dist/semantic/chunker.js.map +1 -0
  142. package/dist/semantic/config.js +74 -0
  143. package/dist/semantic/config.js.map +1 -0
  144. package/dist/semantic/embedder.js +54 -0
  145. package/dist/semantic/embedder.js.map +1 -0
  146. package/dist/semantic/fusion.js +38 -0
  147. package/dist/semantic/fusion.js.map +1 -0
  148. package/dist/semantic/model-download.js +69 -0
  149. package/dist/semantic/model-download.js.map +1 -0
  150. package/dist/semantic/pipeline.js +375 -0
  151. package/dist/semantic/pipeline.js.map +1 -0
  152. package/dist/semantic/query.js +42 -0
  153. package/dist/semantic/query.js.map +1 -0
  154. package/dist/semantic/worker.js +78 -0
  155. package/dist/semantic/worker.js.map +1 -0
  156. package/dist/stats/backfill.js +151 -0
  157. package/dist/stats/backfill.js.map +1 -0
  158. package/dist/stats/health.js +102 -0
  159. package/dist/stats/health.js.map +1 -0
  160. package/dist/stats/query.js +385 -0
  161. package/dist/stats/query.js.map +1 -0
  162. package/dist/utils/aliases.js +107 -0
  163. package/dist/utils/aliases.js.map +1 -0
  164. package/dist/utils/autoCollections.js +635 -0
  165. package/dist/utils/autoCollections.js.map +1 -0
  166. package/dist/utils/autoTitle.js +348 -0
  167. package/dist/utils/autoTitle.js.map +1 -0
  168. package/dist/utils/collections.js +446 -0
  169. package/dist/utils/collections.js.map +1 -0
  170. package/dist/utils/format.js +46 -0
  171. package/dist/utils/format.js.map +1 -0
  172. package/dist/utils/notes.js +270 -0
  173. package/dist/utils/notes.js.map +1 -0
  174. package/dist/utils/paths.js +50 -0
  175. package/dist/utils/paths.js.map +1 -0
  176. package/dist/utils/pricing.js +257 -0
  177. package/dist/utils/pricing.js.map +1 -0
  178. package/dist/utils/secret-scanner.js +166 -0
  179. package/dist/utils/secret-scanner.js.map +1 -0
  180. package/dist/utils/sessionLabel.js +64 -0
  181. package/dist/utils/sessionLabel.js.map +1 -0
  182. package/dist/utils/tags.js +97 -0
  183. package/dist/utils/tags.js.map +1 -0
  184. package/dist/utils/thread-context.js +129 -0
  185. package/dist/utils/thread-context.js.map +1 -0
  186. package/dist/utils/threadFilter.js +18 -0
  187. package/dist/utils/threadFilter.js.map +1 -0
  188. package/dist/utils/threads-titler.js +298 -0
  189. package/dist/utils/threads-titler.js.map +1 -0
  190. package/dist/utils/threads.js +383 -0
  191. package/dist/utils/threads.js.map +1 -0
  192. package/dist/utils/usage.js +76 -0
  193. package/dist/utils/usage.js.map +1 -0
  194. package/dist/verification/compute.js +88 -0
  195. package/dist/verification/compute.js.map +1 -0
  196. package/dist/verification/config.js +34 -0
  197. package/dist/verification/config.js.map +1 -0
  198. package/dist/web/assets/index-CIr6J4Fw.js +1201 -0
  199. package/dist/web/assets/index-Ctc8g9Jw.css +1 -0
  200. package/dist/web/assets/inter-cyrillic-400-normal-HOLc17fK.woff +0 -0
  201. package/dist/web/assets/inter-cyrillic-400-normal-obahsSVq.woff2 +0 -0
  202. package/dist/web/assets/inter-cyrillic-500-normal-BasfLYem.woff2 +0 -0
  203. package/dist/web/assets/inter-cyrillic-500-normal-CxZf_p3X.woff +0 -0
  204. package/dist/web/assets/inter-cyrillic-600-normal-4D_pXhcN.woff +0 -0
  205. package/dist/web/assets/inter-cyrillic-600-normal-CWCymEST.woff2 +0 -0
  206. package/dist/web/assets/inter-cyrillic-700-normal-CjBOestx.woff2 +0 -0
  207. package/dist/web/assets/inter-cyrillic-700-normal-DrXBdSj3.woff +0 -0
  208. package/dist/web/assets/inter-cyrillic-ext-400-normal-BQZuk6qB.woff2 +0 -0
  209. package/dist/web/assets/inter-cyrillic-ext-400-normal-DQukG94-.woff +0 -0
  210. package/dist/web/assets/inter-cyrillic-ext-500-normal-B0yAr1jD.woff2 +0 -0
  211. package/dist/web/assets/inter-cyrillic-ext-500-normal-BmqWE9Dz.woff +0 -0
  212. package/dist/web/assets/inter-cyrillic-ext-600-normal-Bcila6Z-.woff +0 -0
  213. package/dist/web/assets/inter-cyrillic-ext-600-normal-Dfes3d0z.woff2 +0 -0
  214. package/dist/web/assets/inter-cyrillic-ext-700-normal-BjwYoWNd.woff2 +0 -0
  215. package/dist/web/assets/inter-cyrillic-ext-700-normal-LO58E6JB.woff +0 -0
  216. package/dist/web/assets/inter-greek-400-normal-B4URO6DV.woff2 +0 -0
  217. package/dist/web/assets/inter-greek-400-normal-q2sYcFCs.woff +0 -0
  218. package/dist/web/assets/inter-greek-500-normal-BIZE56-Y.woff2 +0 -0
  219. package/dist/web/assets/inter-greek-500-normal-Xzm54t5V.woff +0 -0
  220. package/dist/web/assets/inter-greek-600-normal-BZpKdvQh.woff +0 -0
  221. package/dist/web/assets/inter-greek-600-normal-plRanbMR.woff2 +0 -0
  222. package/dist/web/assets/inter-greek-700-normal-BUv2fZ6O.woff +0 -0
  223. package/dist/web/assets/inter-greek-700-normal-C3JjAnD8.woff2 +0 -0
  224. package/dist/web/assets/inter-greek-ext-400-normal-DGGRlc-M.woff2 +0 -0
  225. package/dist/web/assets/inter-greek-ext-400-normal-KugGGMne.woff +0 -0
  226. package/dist/web/assets/inter-greek-ext-500-normal-2j5mBUwD.woff +0 -0
  227. package/dist/web/assets/inter-greek-ext-500-normal-C4iEst2y.woff2 +0 -0
  228. package/dist/web/assets/inter-greek-ext-600-normal-B8X0CLgF.woff +0 -0
  229. package/dist/web/assets/inter-greek-ext-600-normal-DRtmH8MT.woff2 +0 -0
  230. package/dist/web/assets/inter-greek-ext-700-normal-BoQ6DsYi.woff +0 -0
  231. package/dist/web/assets/inter-greek-ext-700-normal-qfdV9bQt.woff2 +0 -0
  232. package/dist/web/assets/inter-latin-400-normal-C38fXH4l.woff2 +0 -0
  233. package/dist/web/assets/inter-latin-400-normal-CyCys3Eg.woff +0 -0
  234. package/dist/web/assets/inter-latin-500-normal-BL9OpVg8.woff +0 -0
  235. package/dist/web/assets/inter-latin-500-normal-Cerq10X2.woff2 +0 -0
  236. package/dist/web/assets/inter-latin-600-normal-CiBQ2DWP.woff +0 -0
  237. package/dist/web/assets/inter-latin-600-normal-LgqL8muc.woff2 +0 -0
  238. package/dist/web/assets/inter-latin-700-normal-BLAVimhd.woff +0 -0
  239. package/dist/web/assets/inter-latin-700-normal-Yt3aPRUw.woff2 +0 -0
  240. package/dist/web/assets/inter-latin-ext-400-normal-77YHD8bZ.woff +0 -0
  241. package/dist/web/assets/inter-latin-ext-400-normal-C1nco2VV.woff2 +0 -0
  242. package/dist/web/assets/inter-latin-ext-500-normal-BxGbmqWO.woff +0 -0
  243. package/dist/web/assets/inter-latin-ext-500-normal-CV4jyFjo.woff2 +0 -0
  244. package/dist/web/assets/inter-latin-ext-600-normal-CIVaiw4L.woff +0 -0
  245. package/dist/web/assets/inter-latin-ext-600-normal-D2bJ5OIk.woff2 +0 -0
  246. package/dist/web/assets/inter-latin-ext-700-normal-Ca8adRJv.woff2 +0 -0
  247. package/dist/web/assets/inter-latin-ext-700-normal-TidjK2hL.woff +0 -0
  248. package/dist/web/assets/inter-vietnamese-400-normal-Bbgyi5SW.woff +0 -0
  249. package/dist/web/assets/inter-vietnamese-400-normal-DMkecbls.woff2 +0 -0
  250. package/dist/web/assets/inter-vietnamese-500-normal-DOriooB6.woff2 +0 -0
  251. package/dist/web/assets/inter-vietnamese-500-normal-mJboJaSs.woff +0 -0
  252. package/dist/web/assets/inter-vietnamese-600-normal-BuLX-rYi.woff +0 -0
  253. package/dist/web/assets/inter-vietnamese-600-normal-Cc8MFFhd.woff2 +0 -0
  254. package/dist/web/assets/inter-vietnamese-700-normal-BZaoP0fm.woff +0 -0
  255. package/dist/web/assets/inter-vietnamese-700-normal-DlLaEgI2.woff2 +0 -0
  256. package/dist/web/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
  257. package/dist/web/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
  258. package/dist/web/assets/jetbrains-mono-cyrillic-500-normal-DJqRU3vO.woff +0 -0
  259. package/dist/web/assets/jetbrains-mono-cyrillic-500-normal-DmUKJPL_.woff2 +0 -0
  260. package/dist/web/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
  261. package/dist/web/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
  262. package/dist/web/assets/jetbrains-mono-greek-500-normal-D7SFKleX.woff +0 -0
  263. package/dist/web/assets/jetbrains-mono-greek-500-normal-JpySY46c.woff2 +0 -0
  264. package/dist/web/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
  265. package/dist/web/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
  266. package/dist/web/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
  267. package/dist/web/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff +0 -0
  268. package/dist/web/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
  269. package/dist/web/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
  270. package/dist/web/assets/jetbrains-mono-latin-ext-500-normal-Cut-4mMH.woff2 +0 -0
  271. package/dist/web/assets/jetbrains-mono-latin-ext-500-normal-ckzbgY84.woff +0 -0
  272. package/dist/web/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
  273. package/dist/web/assets/jetbrains-mono-vietnamese-500-normal-DNRqzVM1.woff +0 -0
  274. package/dist/web/favicon.svg +9 -0
  275. package/dist/web/index.html +15 -0
  276. package/package.json +79 -9
  277. package/bin/cli.js +0 -12
@@ -0,0 +1,138 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { readdirSync } from 'node:fs';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { dirname, join, resolve } from 'node:path';
5
+ import { c } from '../utils/format.js';
6
+ const EDITOR_IDS = ['code', 'cursor', 'code-insiders', 'windsurf'];
7
+ const EDITORS = [
8
+ { id: 'code', label: 'VS Code' },
9
+ { id: 'cursor', label: 'Cursor' },
10
+ { id: 'code-insiders', label: 'VS Code Insiders' },
11
+ { id: 'windsurf', label: 'Windsurf' },
12
+ ];
13
+ // Primary Marketplace listing — published by the clauderecallhq publisher.
14
+ // The legacy fibogacci.claude-recall-vscode listing stays live as a defensive
15
+ // holding; we steer new users at the primary one.
16
+ const MARKETPLACE_URL = 'https://marketplace.visualstudio.com/items?itemName=clauderecallhq.clauderecall-vscode';
17
+ function resolveVsixDir() {
18
+ const here = dirname(fileURLToPath(import.meta.url));
19
+ // src/commands (tsx dev) and dist/commands (prod) both sit two levels below
20
+ // the package root where extensions/vscode/ lives.
21
+ return join(here, '..', '..', 'extensions', 'vscode');
22
+ }
23
+ function findLatestVsix() {
24
+ const dir = resolveVsixDir();
25
+ let entries;
26
+ try {
27
+ entries = readdirSync(dir);
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ // Matches both the primary (`clauderecall-vscode-*.vsix`) and legacy
33
+ // (`claude-recall-vscode-*.vsix`) artifact names during the transition.
34
+ const matches = entries.filter((f) => /^(clauderecall|claude-recall)-vscode-.*\.vsix$/i.test(f));
35
+ if (matches.length === 0)
36
+ return null;
37
+ matches.sort((a, b) => b.localeCompare(a, undefined, { numeric: true }));
38
+ return resolve(dir, matches[0]);
39
+ }
40
+ function editorAvailable(id) {
41
+ const result = spawnSync(id, ['--version'], {
42
+ stdio: 'ignore',
43
+ shell: process.platform === 'win32',
44
+ });
45
+ if (result.error)
46
+ return false;
47
+ return result.status === 0;
48
+ }
49
+ function installIntoEditor(id, vsixPath) {
50
+ const result = spawnSync(id, ['--install-extension', vsixPath], {
51
+ stdio: 'pipe',
52
+ encoding: 'utf8',
53
+ shell: process.platform === 'win32',
54
+ });
55
+ if (result.error)
56
+ return { ok: false, message: result.error.message };
57
+ if (result.status !== 0) {
58
+ const stderr = (result.stderr ?? '').trim();
59
+ return { ok: false, message: stderr || `exit code ${result.status ?? 'null'}` };
60
+ }
61
+ return { ok: true, message: '' };
62
+ }
63
+ function printNoVsixError() {
64
+ process.stderr.write(c.err('no bundled .vsix found at extensions/vscode/(clauderecall|claude-recall)-vscode-*.vsix\n'));
65
+ process.stderr.write(c.dim('see PUBLISHING.md for how to build the extension, or run:\n'));
66
+ process.stderr.write(c.dim(' (cd extensions/vscode && npm install && npm run build && npm run package)\n'));
67
+ }
68
+ function isKnownEditor(id) {
69
+ return EDITOR_IDS.includes(id);
70
+ }
71
+ export async function runInstallExtension(opts) {
72
+ if (opts.editor !== undefined && !isKnownEditor(opts.editor)) {
73
+ process.stderr.write(c.err(`unknown --editor target: ${opts.editor}\n`));
74
+ process.stderr.write(c.dim(`valid values: ${EDITOR_IDS.join(', ')}\n`));
75
+ process.exitCode = 1;
76
+ return;
77
+ }
78
+ const vsixPath = findLatestVsix();
79
+ if (opts.printPath) {
80
+ if (!vsixPath) {
81
+ printNoVsixError();
82
+ process.exitCode = 1;
83
+ return;
84
+ }
85
+ process.stdout.write(vsixPath + '\n');
86
+ return;
87
+ }
88
+ if (!vsixPath) {
89
+ printNoVsixError();
90
+ process.exitCode = 1;
91
+ return;
92
+ }
93
+ let targets;
94
+ if (opts.editor) {
95
+ const editorId = opts.editor;
96
+ if (!editorAvailable(editorId)) {
97
+ process.stderr.write(c.err(`editor CLI not found on PATH: ${editorId}\n`));
98
+ process.stderr.write(c.dim('install the editor shell integration, or omit --editor to install into every detected editor.\n'));
99
+ process.stderr.write(c.dim('see PUBLISHING.md for manual install instructions.\n'));
100
+ process.exitCode = 1;
101
+ return;
102
+ }
103
+ const spec = EDITORS.find((e) => e.id === editorId);
104
+ targets = [spec ?? { id: editorId, label: editorId }];
105
+ }
106
+ else {
107
+ targets = EDITORS.filter((e) => editorAvailable(e.id));
108
+ }
109
+ if (targets.length === 0) {
110
+ process.stderr.write(c.err('no supported editor CLI detected on PATH.\n'));
111
+ process.stderr.write(c.dim(`looked for: ${EDITOR_IDS.join(', ')}.\n`));
112
+ process.stderr.write(c.dim('install the editor shell integration and try again.\n'));
113
+ process.stderr.write(c.dim('see PUBLISHING.md for manual install instructions.\n'));
114
+ process.exitCode = 1;
115
+ return;
116
+ }
117
+ process.stderr.write(c.dim(`bundled .vsix: ${vsixPath}\n\n`));
118
+ let anyFailed = false;
119
+ for (const target of targets) {
120
+ const { ok, message } = installIntoEditor(target.id, vsixPath);
121
+ if (ok) {
122
+ process.stderr.write(c.ok(`✓ installed into ${target.label} (${target.id})\n`));
123
+ }
124
+ else {
125
+ anyFailed = true;
126
+ process.stderr.write(c.err(`✗ ${target.label} (${target.id}): ${message}\n`));
127
+ }
128
+ }
129
+ process.stderr.write('\n');
130
+ process.stderr.write(c.bold('next steps:\n'));
131
+ process.stderr.write(' 1. reload the editor window: Cmd/Ctrl+Shift+P then pick "Developer: Reload Window"\n');
132
+ process.stderr.write(' 2. enable the extension: open settings and set "claude-recall.autoAlias" to true\n');
133
+ process.stderr.write('\n');
134
+ process.stderr.write(c.dim(`marketplace install: ${MARKETPLACE_URL}\n`));
135
+ if (anyFailed)
136
+ process.exitCode = 1;
137
+ }
138
+ //# sourceMappingURL=install-extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-extension.js","sourceRoot":"","sources":["../../src/commands/install-extension.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { c } from '../utils/format.js';
2
+ import { getLicenseStatus } from '../license/manager.js';
3
+ import { clearStoredLicense, LICENSE_FILE } from '../license/storage.js';
4
+ export async function runLicenseStatus() {
5
+ const status = await getLicenseStatus();
6
+ console.log();
7
+ if (status.tier === 'free') {
8
+ console.log(c.bold('Tier: Free'));
9
+ console.log(c.dim('Free includes: index, list, show, projects, status, the daemon, and the basic web UI.'));
10
+ if (status.invalid_reason) {
11
+ console.log();
12
+ console.log(c.warn(`Stored license is invalid: ${status.invalid_reason}`));
13
+ }
14
+ console.log();
15
+ console.log('Buy Pro at https://clauderecall.com/pricing');
16
+ console.log('Then run: recall activate <license-key>');
17
+ console.log();
18
+ return;
19
+ }
20
+ console.log(c.bold('Tier: Pro'));
21
+ console.log(` ${c.dim('Key:')} ${status.key_short}`);
22
+ console.log(` ${c.dim('Email:')} ${status.customer_email}`);
23
+ console.log(` ${c.dim('Activated:')} ${status.activated_at}`);
24
+ if (status.expires_at) {
25
+ console.log(` ${c.dim('Expires:')} ${status.expires_at}`);
26
+ }
27
+ if (status.test_mode) {
28
+ console.log(` ${c.warn('Test mode:')} this license was issued in LemonSqueezy test mode.`);
29
+ }
30
+ console.log();
31
+ }
32
+ export function runLicenseDeactivate() {
33
+ clearStoredLicense();
34
+ console.log();
35
+ console.log('License removed from this machine.');
36
+ console.log(c.dim(`(${LICENSE_FILE})`));
37
+ console.log();
38
+ }
39
+ //# sourceMappingURL=license.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"license.js","sourceRoot":"","sources":["../../src/commands/license.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,oBAAoB,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAEzE,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,MAAM,GAAG,MAAM,gBAAgB,EAAE,CAAC;IACxC,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,uFAAuF,CAAC,CAAC,CAAC;QAC5G,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,8BAA8B,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;QAC7E,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;QAC3D,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IACjC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;IAC/D,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,qDAAqD,CAAC,CAAC;IAC9F,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,kBAAkB,EAAE,CAAC;IACrB,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;IAClD,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,YAAY,GAAG,CAAC,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC"}
@@ -0,0 +1,47 @@
1
+ import Table from 'cli-table3';
2
+ import { getDb } from '../db/client.js';
3
+ import { c, shortId, timeAgo, truncate } from '../utils/format.js';
4
+ export function runList(options) {
5
+ const db = getDb();
6
+ const limit = Math.max(1, Math.min(500, parseInt(options.limit ?? '30', 10) || 30));
7
+ const params = { limit };
8
+ let where = '1=1';
9
+ if (options.project) {
10
+ where += ' AND (p.name LIKE @proj OR p.decoded_path LIKE @proj OR p.encoded_path LIKE @proj)';
11
+ params.proj = `%${options.project}%`;
12
+ }
13
+ if (!options.all) {
14
+ where += ' AND s.message_count > 2';
15
+ }
16
+ const rows = db
17
+ .prepare(`SELECT s.id, p.name AS project_name, s.started_at,
18
+ s.message_count, s.first_user_message, s.git_branch
19
+ FROM sessions s
20
+ JOIN projects p ON p.id = s.project_id
21
+ WHERE ${where}
22
+ ORDER BY COALESCE(s.started_at, '') DESC
23
+ LIMIT @limit`)
24
+ .all(params);
25
+ if (rows.length === 0) {
26
+ console.log(c.dim('no sessions found. run `recall index` first.'));
27
+ return;
28
+ }
29
+ const table = new Table({
30
+ head: [c.bold('id'), c.bold('project'), c.bold('when'), c.bold('msgs'), c.bold('opening prompt')],
31
+ colWidths: [10, 22, 14, 6, 70],
32
+ wordWrap: true,
33
+ style: { head: [], border: ['grey'] },
34
+ });
35
+ for (const row of rows) {
36
+ table.push([
37
+ c.accent(shortId(row.id)),
38
+ c.project(truncate(row.project_name, 20)),
39
+ c.dim(timeAgo(row.started_at)),
40
+ String(row.message_count),
41
+ truncate(row.first_user_message, 200),
42
+ ]);
43
+ }
44
+ console.log(table.toString());
45
+ console.log(c.dim(`showing ${rows.length} session${rows.length === 1 ? '' : 's'}. use \`recall show <id>\` to view one.`));
46
+ }
47
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAC;AAC/B,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAiBnE,MAAM,UAAU,OAAO,CAAC,OAAoB;IAC1C,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAK,IAAI,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAEpF,MAAM,MAAM,GAA4B,EAAE,KAAK,EAAE,CAAC;IAClD,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,KAAK,IAAI,oFAAoF,CAAC;QAC9F,MAAM,CAAC,IAAI,GAAG,IAAI,OAAO,CAAC,OAAO,GAAG,CAAC;IACvC,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QACjB,KAAK,IAAI,0BAA0B,CAAC;IACtC,CAAC;IAED,MAAM,IAAI,GAAG,EAAE;SACZ,OAAO,CACN;;;;eAIS,KAAK;;oBAEA,CACf;SACA,GAAG,CAAC,MAAM,CAAiB,CAAC;IAE/B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC,CAAC;QACnE,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC;QACtB,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACjG,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9B,QAAQ,EAAE,IAAI;QACd,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE;KACtC,CAAC,CAAC;IAEH,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC;YACT,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACzB,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;YACzC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC9B,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC;YACzB,QAAQ,CAAC,GAAG,CAAC,kBAAkB,EAAE,GAAG,CAAC;SACtC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9B,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,MAAM,WAAW,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,yCAAyC,CAAC,CAAC,CAAC;AAC7H,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { dirname, join } from 'node:path';
2
+ import { fileURLToPath } from 'node:url';
3
+ import { spawn } from 'node:child_process';
4
+ import { requireProOrExit } from '../license/manager.js';
5
+ export async function runMcp(opts = {}) {
6
+ await requireProOrExit('MCP server');
7
+ const here = dirname(fileURLToPath(import.meta.url));
8
+ const mcpEntry = join(here, '..', 'mcp', 'server.js');
9
+ const env = { ...process.env };
10
+ if (opts.allowWrites) {
11
+ env.RECALL_MCP_ALLOW_WRITES = '1';
12
+ }
13
+ const child = spawn(process.execPath, [mcpEntry], {
14
+ stdio: 'inherit',
15
+ env,
16
+ });
17
+ return new Promise((resolve, reject) => {
18
+ child.on('error', reject);
19
+ child.on('exit', (code, signal) => {
20
+ if (signal) {
21
+ process.kill(process.pid, signal);
22
+ return;
23
+ }
24
+ process.exitCode = code ?? 0;
25
+ resolve();
26
+ });
27
+ });
28
+ }
29
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAWzD,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,OAAsB,EAAE;IACnD,MAAM,gBAAgB,CAAC,YAAY,CAAC,CAAC;IACrC,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;IAEtD,MAAM,GAAG,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC/B,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,GAAG,CAAC,uBAAuB,GAAG,GAAG,CAAC;IACpC,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,EAAE;QAChD,KAAK,EAAE,SAAS;QAChB,GAAG;KACJ,CAAC,CAAC;IAEH,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1B,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;YAChC,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;gBAClC,OAAO;YACT,CAAC;YACD,OAAO,CAAC,QAAQ,GAAG,IAAI,IAAI,CAAC,CAAC;YAC7B,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { platform } from 'node:os';
3
+ import { getRunningDaemon } from '../daemon/pidfile.js';
4
+ import { runStart } from './start.js';
5
+ import { c } from '../utils/format.js';
6
+ function openUrl(url) {
7
+ const cmd = platform() === 'darwin' ? 'open' : platform() === 'win32' ? 'start' : 'xdg-open';
8
+ const args = platform() === 'win32' ? ['', url] : [url];
9
+ const child = spawn(cmd, args, { detached: true, stdio: 'ignore', shell: platform() === 'win32' });
10
+ child.unref();
11
+ }
12
+ export async function runOpen() {
13
+ let info = getRunningDaemon();
14
+ if (!info) {
15
+ console.log(c.dim('daemon not running — starting it…'));
16
+ await runStart();
17
+ info = getRunningDaemon();
18
+ if (!info) {
19
+ console.error(c.err('could not start the daemon. run `recall start` manually and check logs.'));
20
+ process.exitCode = 1;
21
+ return;
22
+ }
23
+ }
24
+ const url = `http://127.0.0.1:${info.port}`;
25
+ console.log(`${c.ok('opening')} ${url}`);
26
+ openUrl(url);
27
+ }
28
+ //# sourceMappingURL=open.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open.js","sourceRoot":"","sources":["../../src/commands/open.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,CAAC,EAAE,MAAM,oBAAoB,CAAC;AAEvC,SAAS,OAAO,CAAC,GAAW;IAC1B,MAAM,GAAG,GAAG,QAAQ,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC;IAC7F,MAAM,IAAI,GAAG,QAAQ,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,OAAO,EAAE,CAAC,CAAC;IACnG,KAAK,CAAC,KAAK,EAAE,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO;IAC3B,IAAI,IAAI,GAAG,gBAAgB,EAAE,CAAC;IAC9B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC,CAAC;QACxD,MAAM,QAAQ,EAAE,CAAC;QACjB,IAAI,GAAG,gBAAgB,EAAE,CAAC;QAC1B,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,yEAAyE,CAAC,CAAC,CAAC;YAChG,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;IACH,CAAC;IACD,MAAM,GAAG,GAAG,oBAAoB,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,CAAC;AACf,CAAC"}
@@ -0,0 +1,154 @@
1
+ import { execSync } from 'node:child_process';
2
+ import { randomUUID } from 'node:crypto';
3
+ import readline from 'node:readline/promises';
4
+ import { getDb } from '../db/client.js';
5
+ import { scanForSecrets } from '../utils/secret-scanner.js';
6
+ import { c, timeAgo } from '../utils/format.js';
7
+ export async function runPaste(options) {
8
+ if (options.list) {
9
+ listPastes();
10
+ return;
11
+ }
12
+ if (options.purge) {
13
+ purgePaste(options.purge);
14
+ return;
15
+ }
16
+ const content = await readContent();
17
+ if (!content) {
18
+ process.stderr.write(c.err('clipboard empty / nothing on stdin\n'));
19
+ process.exit(1);
20
+ }
21
+ const secrets = scanForSecrets(content);
22
+ if (secrets.length > 0 && !options.force) {
23
+ process.stderr.write(c.warn(`⚠ detected ${secrets.length} possible secret${secrets.length === 1 ? '' : 's'} in content:\n`));
24
+ for (const s of secrets.slice(0, 8)) {
25
+ process.stderr.write(` ${c.err(s.pattern)} ${c.dim('→')} ${s.maskedPreview}\n`);
26
+ }
27
+ if (secrets.length > 8) {
28
+ process.stderr.write(c.dim(` … ${secrets.length - 8} more\n`));
29
+ }
30
+ if (options.dryRun) {
31
+ process.stderr.write(c.dim('\n(dry run — nothing archived)\n'));
32
+ process.exit(1);
33
+ }
34
+ if (!process.stdin.isTTY && !process.stderr.isTTY) {
35
+ process.stderr.write(c.err('refusing to archive secret content in non-interactive mode. use --force to override.\n'));
36
+ // Still echo to stdout so the paste pipeline isn't broken.
37
+ if (options.pipe)
38
+ process.stdout.write(content);
39
+ process.exit(1);
40
+ }
41
+ const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
42
+ const answer = await rl.question(c.accent('archive anyway? [y/N] '));
43
+ rl.close();
44
+ if (answer.trim().toLowerCase() !== 'y') {
45
+ process.stderr.write(c.dim('cancelled — nothing archived.\n'));
46
+ if (options.pipe)
47
+ process.stdout.write(content);
48
+ process.exit(0);
49
+ }
50
+ }
51
+ if (options.dryRun) {
52
+ process.stderr.write(c.dim(`(dry run — would archive ${content.length.toLocaleString()} chars)\n`));
53
+ if (options.pipe)
54
+ process.stdout.write(content);
55
+ process.exit(0);
56
+ }
57
+ const id = randomUUID();
58
+ const now = new Date().toISOString();
59
+ getDb()
60
+ .prepare(`INSERT INTO paste_archives (id, created_at, content, size_bytes, source, label)
61
+ VALUES (?, ?, ?, ?, ?, ?)`)
62
+ .run(id, now, content, Buffer.byteLength(content, 'utf8'), options.pipe ? 'cli-piped' : 'cli', options.label ?? null);
63
+ process.stderr.write(c.ok(`✓ archived ${content.length.toLocaleString()} chars as ${id.slice(0, 8)}\n`));
64
+ if (options.label) {
65
+ process.stderr.write(c.dim(` label: ${options.label}\n`));
66
+ }
67
+ process.stderr.write(c.dim(` purge any time with: recall paste --purge ${id.slice(0, 8)}\n`));
68
+ if (options.pipe) {
69
+ process.stdout.write(content);
70
+ }
71
+ }
72
+ function listPastes() {
73
+ const rows = getDb()
74
+ .prepare(`SELECT id, created_at, size_bytes, source, label,
75
+ substr(replace(replace(content, char(10), '↵'), char(13), ''), 1, 80) AS preview
76
+ FROM paste_archives
77
+ ORDER BY created_at DESC
78
+ LIMIT 100`)
79
+ .all();
80
+ if (rows.length === 0) {
81
+ process.stdout.write(c.dim('no pastes archived yet. use `pbpaste | recall paste` to archive.\n'));
82
+ return;
83
+ }
84
+ process.stdout.write(`\n${c.bold(`${rows.length} archived paste${rows.length === 1 ? '' : 's'}`)}\n`);
85
+ process.stdout.write(c.dim('─────────────────────\n'));
86
+ for (const r of rows) {
87
+ const size = r.size_bytes < 1024
88
+ ? `${r.size_bytes}b`
89
+ : r.size_bytes < 1024 * 1024
90
+ ? `${(r.size_bytes / 1024).toFixed(1)}K`
91
+ : `${(r.size_bytes / 1024 / 1024).toFixed(1)}M`;
92
+ const label = r.label ? ` ${c.project(r.label)}` : '';
93
+ process.stdout.write(` ${c.accent(r.id.slice(0, 8))} ${c.dim(timeAgo(r.created_at).padEnd(12))} ${size.padStart(6)}${label} ${c.dim(r.preview)}\n`);
94
+ }
95
+ process.stdout.write(c.dim(`\nshow full content: recall paste --show <id>\n`) +
96
+ c.dim(`purge one (permanent): recall paste --purge <id>\n\n`));
97
+ }
98
+ function purgePaste(idOrPrefix) {
99
+ // Guard against overly-broad prefixes. A single-character "%" expansion
100
+ // could otherwise sweep across many rows; the ambiguity check below
101
+ // already blocks multi-row deletion, but requiring 8 chars up front is
102
+ // cheaper and matches the documented UX ("first 8 of the id").
103
+ if (idOrPrefix.length < 8) {
104
+ process.stderr.write(c.err('provide at least 8 characters of the paste id to purge.\n'));
105
+ process.exit(1);
106
+ }
107
+ const db = getDb();
108
+ const rows = db
109
+ .prepare('SELECT id FROM paste_archives WHERE id = ? OR id LIKE ? LIMIT 2')
110
+ .all(idOrPrefix, `${idOrPrefix}%`);
111
+ if (rows.length === 0) {
112
+ process.stderr.write(c.err(`no paste matches ${idOrPrefix}\n`));
113
+ process.exit(1);
114
+ }
115
+ if (rows.length > 1) {
116
+ process.stderr.write(c.err(`prefix ${idOrPrefix} is ambiguous. be more specific.\n`));
117
+ process.exit(1);
118
+ }
119
+ db.prepare('DELETE FROM paste_archives WHERE id = ?').run(rows[0].id);
120
+ process.stderr.write(c.ok(`✓ purged ${rows[0].id.slice(0, 8)} — content permanently destroyed\n`));
121
+ }
122
+ async function readContent() {
123
+ if (!process.stdin.isTTY) {
124
+ return await readStdin();
125
+ }
126
+ // Read from clipboard
127
+ try {
128
+ return execSync('pbpaste', { encoding: 'utf8', maxBuffer: 16 * 1024 * 1024 });
129
+ }
130
+ catch {
131
+ /* fall through to xclip / powershell */
132
+ }
133
+ try {
134
+ return execSync('xclip -o -selection clipboard', { encoding: 'utf8', maxBuffer: 16 * 1024 * 1024 });
135
+ }
136
+ catch {
137
+ /* ignore */
138
+ }
139
+ try {
140
+ return execSync('powershell.exe -command Get-Clipboard', { encoding: 'utf8', maxBuffer: 16 * 1024 * 1024 });
141
+ }
142
+ catch {
143
+ /* ignore */
144
+ }
145
+ throw new Error('Could not read clipboard. On macOS pbpaste should be built in; on Linux install xclip; on Windows pipe into this command instead.');
146
+ }
147
+ async function readStdin() {
148
+ const chunks = [];
149
+ for await (const chunk of process.stdin) {
150
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
151
+ }
152
+ return Buffer.concat(chunks).toString('utf8');
153
+ }
154
+ //# sourceMappingURL=paste.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paste.js","sourceRoot":"","sources":["../../src/commands/paste.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import Table from 'cli-table3';
2
+ import { getDb } from '../db/client.js';
3
+ import { c, timeAgo, truncate } from '../utils/format.js';
4
+ export function runProjects() {
5
+ const db = getDb();
6
+ const rows = db
7
+ .prepare(`SELECT p.name,
8
+ p.decoded_path,
9
+ COUNT(s.id) AS session_count,
10
+ COALESCE(SUM(s.message_count), 0) AS message_count,
11
+ MAX(s.started_at) AS latest
12
+ FROM projects p
13
+ LEFT JOIN sessions s ON s.project_id = p.id
14
+ GROUP BY p.id
15
+ ORDER BY MAX(COALESCE(s.started_at, '')) DESC`)
16
+ .all();
17
+ if (rows.length === 0) {
18
+ console.log(c.dim('no projects indexed yet.'));
19
+ return;
20
+ }
21
+ const table = new Table({
22
+ head: [c.bold('project'), c.bold('sessions'), c.bold('msgs'), c.bold('latest'), c.bold('path')],
23
+ style: { head: [], border: ['grey'] },
24
+ });
25
+ for (const r of rows) {
26
+ table.push([
27
+ c.project(truncate(r.name, 30)),
28
+ String(r.session_count),
29
+ String(r.message_count),
30
+ c.dim(timeAgo(r.latest)),
31
+ c.dim(truncate(r.decoded_path, 50)),
32
+ ]);
33
+ }
34
+ console.log(table.toString());
35
+ }
36
+ //# sourceMappingURL=projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/commands/projects.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAC;AAC/B,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAU1D,MAAM,UAAU,WAAW;IACzB,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,MAAM,IAAI,GAAG,EAAE;SACZ,OAAO,CACN;;;;;;;;qDAQ+C,CAChD;SACA,GAAG,EAAkB,CAAC;IAEzB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC,CAAC;QAC/C,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC;QACtB,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/F,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE;KACtC,CAAC,CAAC;IACH,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC;YACT,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC/B,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC;YACvB,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC;YACvB,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YACxB,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;SACpC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,67 @@
1
+ import { getDb } from '../db/client.js';
2
+ import { c, highlight, shortId, timeAgo, truncate } from '../utils/format.js';
3
+ import { requireProOrExit } from '../license/manager.js';
4
+ function sanitizeFtsQuery(query) {
5
+ // Wrap each term in quotes for safety; join with AND semantics.
6
+ const terms = query
7
+ .split(/\s+/)
8
+ .filter(Boolean)
9
+ .map((t) => t.replace(/"/g, ''))
10
+ .filter((t) => t.length > 0);
11
+ if (terms.length === 0)
12
+ return '';
13
+ return terms.map((t) => `"${t}"`).join(' ');
14
+ }
15
+ export async function runSearch(query, options) {
16
+ await requireProOrExit('Full-text search');
17
+ const db = getDb();
18
+ const ftsQuery = sanitizeFtsQuery(query);
19
+ if (!ftsQuery) {
20
+ console.log(c.dim('empty query'));
21
+ return;
22
+ }
23
+ const limit = Math.max(1, Math.min(200, parseInt(options.limit ?? '20', 10) || 20));
24
+ const params = { q: ftsQuery, limit };
25
+ let projectFilter = '';
26
+ if (options.project) {
27
+ projectFilter = ' AND (p.name LIKE @proj OR p.decoded_path LIKE @proj) ';
28
+ params.proj = `%${options.project}%`;
29
+ }
30
+ const rows = db
31
+ .prepare(`SELECT m.session_id AS session_id,
32
+ p.name AS project_name,
33
+ s.started_at AS started_at,
34
+ snippet(messages_fts, 0, '<<', '>>', '…', 16) AS snippet,
35
+ m.role AS role,
36
+ m.timestamp AS timestamp
37
+ FROM messages_fts
38
+ JOIN messages m ON m.rowid = messages_fts.rowid
39
+ JOIN sessions s ON s.id = m.session_id
40
+ JOIN projects p ON p.id = s.project_id
41
+ WHERE messages_fts MATCH @q
42
+ ${projectFilter}
43
+ ORDER BY bm25(messages_fts)
44
+ LIMIT @limit`)
45
+ .all(params);
46
+ if (rows.length === 0) {
47
+ console.log(c.dim(`no matches for "${query}"`));
48
+ return;
49
+ }
50
+ console.log(c.dim(`${rows.length} match${rows.length === 1 ? '' : 'es'} for "${query}"`));
51
+ console.log('');
52
+ for (const hit of rows) {
53
+ const snippet = hit.snippet
54
+ .replace(/<<([\s\S]*?)>>/g, (_, s) => highlight(s, s).replace(/\n/g, ' '))
55
+ .replace(/\n/g, ' ');
56
+ const roleTag = hit.role === 'user'
57
+ ? c.user('user')
58
+ : hit.role === 'assistant'
59
+ ? c.assistant('asst')
60
+ : c.dim('----');
61
+ console.log(`${c.accent(shortId(hit.session_id))} ${c.project(truncate(hit.project_name, 20))} ${c.dim(timeAgo(hit.started_at))} ${roleTag}`);
62
+ console.log(` ${truncate(snippet, 200)}`);
63
+ console.log('');
64
+ }
65
+ console.log(c.dim('`recall show <id>` to read any session.'));
66
+ }
67
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"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"}