@aligndottech/cli 0.49.0 → 0.50.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 (622) hide show
  1. package/README.md +4 -3
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +26 -8
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/agents.d.ts.map +1 -1
  6. package/dist/commands/agents.js +4 -1
  7. package/dist/commands/agents.js.map +1 -1
  8. package/dist/commands/check.d.ts.map +1 -1
  9. package/dist/commands/check.js +18 -2
  10. package/dist/commands/check.js.map +1 -1
  11. package/dist/commands/connect.d.ts +5 -0
  12. package/dist/commands/connect.d.ts.map +1 -1
  13. package/dist/commands/connect.js +24 -0
  14. package/dist/commands/connect.js.map +1 -1
  15. package/dist/commands/import/confluence.d.ts.map +1 -1
  16. package/dist/commands/import/confluence.js +24 -5
  17. package/dist/commands/import/confluence.js.map +1 -1
  18. package/dist/commands/import/docs.js +2 -2
  19. package/dist/commands/import/git.d.ts.map +1 -1
  20. package/dist/commands/import/git.js +15 -5
  21. package/dist/commands/import/git.js.map +1 -1
  22. package/dist/commands/import/github.d.ts.map +1 -1
  23. package/dist/commands/import/github.js +34 -7
  24. package/dist/commands/import/github.js.map +1 -1
  25. package/dist/commands/import/gitlab.d.ts.map +1 -1
  26. package/dist/commands/import/gitlab.js +10 -5
  27. package/dist/commands/import/gitlab.js.map +1 -1
  28. package/dist/commands/import/jira.d.ts.map +1 -1
  29. package/dist/commands/import/jira.js +10 -5
  30. package/dist/commands/import/jira.js.map +1 -1
  31. package/dist/commands/import/linear.d.ts.map +1 -1
  32. package/dist/commands/import/linear.js +10 -5
  33. package/dist/commands/import/linear.js.map +1 -1
  34. package/dist/commands/import/notion.d.ts.map +1 -1
  35. package/dist/commands/import/notion.js +10 -5
  36. package/dist/commands/import/notion.js.map +1 -1
  37. package/dist/commands/import/sessions.js +2 -2
  38. package/dist/commands/import/slack.d.ts.map +1 -1
  39. package/dist/commands/import/slack.js +12 -7
  40. package/dist/commands/import/slack.js.map +1 -1
  41. package/dist/commands/import/teams.d.ts.map +1 -1
  42. package/dist/commands/import/teams.js +10 -5
  43. package/dist/commands/import/teams.js.map +1 -1
  44. package/dist/commands/import/zoom.d.ts.map +1 -1
  45. package/dist/commands/import/zoom.js +10 -5
  46. package/dist/commands/import/zoom.js.map +1 -1
  47. package/dist/commands/import.d.ts.map +1 -1
  48. package/dist/commands/import.js +43 -1
  49. package/dist/commands/import.js.map +1 -1
  50. package/dist/commands/local.d.ts.map +1 -1
  51. package/dist/commands/local.js +76 -4
  52. package/dist/commands/local.js.map +1 -1
  53. package/dist/commands/mark.d.ts +37 -0
  54. package/dist/commands/mark.d.ts.map +1 -0
  55. package/dist/commands/mark.js +105 -0
  56. package/dist/commands/mark.js.map +1 -0
  57. package/dist/commands/mcp.d.ts +141 -2
  58. package/dist/commands/mcp.d.ts.map +1 -1
  59. package/dist/commands/mcp.js +72 -14
  60. package/dist/commands/mcp.js.map +1 -1
  61. package/dist/commands/registry.d.ts.map +1 -1
  62. package/dist/commands/registry.js +8 -2
  63. package/dist/commands/registry.js.map +1 -1
  64. package/dist/commands/setup.d.ts +39 -0
  65. package/dist/commands/setup.d.ts.map +1 -1
  66. package/dist/commands/setup.js +65 -50
  67. package/dist/commands/setup.js.map +1 -1
  68. package/dist/commands/share.d.ts +7 -0
  69. package/dist/commands/share.d.ts.map +1 -0
  70. package/dist/commands/share.js +60 -0
  71. package/dist/commands/share.js.map +1 -0
  72. package/dist/commands/sync.d.ts +55 -0
  73. package/dist/commands/sync.d.ts.map +1 -0
  74. package/dist/commands/sync.js +278 -0
  75. package/dist/commands/sync.js.map +1 -0
  76. package/dist/commands/telemetry.d.ts +3 -3
  77. package/dist/commands/telemetry.js +6 -6
  78. package/dist/commands/telemetry.js.map +1 -1
  79. package/dist/commands/why.d.ts.map +1 -1
  80. package/dist/commands/why.js +6 -1
  81. package/dist/commands/why.js.map +1 -1
  82. package/dist/index.d.ts +2 -0
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +2 -0
  85. package/dist/index.js.map +1 -1
  86. package/dist/lib/backfill-state.d.ts +116 -0
  87. package/dist/lib/backfill-state.d.ts.map +1 -0
  88. package/dist/lib/backfill-state.js +342 -0
  89. package/dist/lib/backfill-state.js.map +1 -0
  90. package/dist/lib/backup-copy.d.ts +17 -0
  91. package/dist/lib/backup-copy.d.ts.map +1 -0
  92. package/dist/lib/backup-copy.js +13 -0
  93. package/dist/lib/backup-copy.js.map +1 -0
  94. package/dist/lib/capture-report.d.ts +22 -18
  95. package/dist/lib/capture-report.d.ts.map +1 -1
  96. package/dist/lib/capture-report.js +64 -2
  97. package/dist/lib/capture-report.js.map +1 -1
  98. package/dist/lib/config.d.ts +31 -0
  99. package/dist/lib/config.d.ts.map +1 -1
  100. package/dist/lib/config.js +139 -0
  101. package/dist/lib/config.js.map +1 -1
  102. package/dist/lib/confirm-timeout.d.ts +8 -0
  103. package/dist/lib/confirm-timeout.d.ts.map +1 -0
  104. package/dist/lib/confirm-timeout.js +18 -0
  105. package/dist/lib/confirm-timeout.js.map +1 -0
  106. package/dist/lib/curation/check-marks.d.ts +48 -0
  107. package/dist/lib/curation/check-marks.d.ts.map +1 -0
  108. package/dist/lib/curation/check-marks.js +81 -0
  109. package/dist/lib/curation/check-marks.js.map +1 -0
  110. package/dist/lib/curation/guardrail.d.ts +39 -0
  111. package/dist/lib/curation/guardrail.d.ts.map +1 -0
  112. package/dist/lib/curation/guardrail.js +93 -0
  113. package/dist/lib/curation/guardrail.js.map +1 -0
  114. package/dist/lib/curation/judge.d.ts +3 -0
  115. package/dist/lib/curation/judge.d.ts.map +1 -0
  116. package/dist/lib/curation/judge.js +9 -0
  117. package/dist/lib/curation/judge.js.map +1 -0
  118. package/dist/lib/curation/judgements-db.d.ts +96 -0
  119. package/dist/lib/curation/judgements-db.d.ts.map +1 -0
  120. package/dist/lib/curation/judgements-db.js +200 -0
  121. package/dist/lib/curation/judgements-db.js.map +1 -0
  122. package/dist/lib/curation/last-check.d.ts +32 -0
  123. package/dist/lib/curation/last-check.d.ts.map +1 -0
  124. package/dist/lib/curation/last-check.js +81 -0
  125. package/dist/lib/curation/last-check.js.map +1 -0
  126. package/dist/lib/curation/mark.d.ts +76 -0
  127. package/dist/lib/curation/mark.d.ts.map +1 -0
  128. package/dist/lib/curation/mark.js +359 -0
  129. package/dist/lib/curation/mark.js.map +1 -0
  130. package/dist/lib/curation/text.d.ts +6 -0
  131. package/dist/lib/curation/text.d.ts.map +1 -0
  132. package/dist/lib/curation/text.js +35 -0
  133. package/dist/lib/curation/text.js.map +1 -0
  134. package/dist/lib/fetchers/capture.d.ts +49 -2
  135. package/dist/lib/fetchers/capture.d.ts.map +1 -1
  136. package/dist/lib/fetchers/capture.js +7 -1
  137. package/dist/lib/fetchers/capture.js.map +1 -1
  138. package/dist/lib/fetchers/confluence.d.ts +2 -2
  139. package/dist/lib/fetchers/confluence.d.ts.map +1 -1
  140. package/dist/lib/fetchers/confluence.js.map +1 -1
  141. package/dist/lib/fetchers/git.d.ts +1 -0
  142. package/dist/lib/fetchers/git.d.ts.map +1 -1
  143. package/dist/lib/fetchers/git.js +3 -1
  144. package/dist/lib/fetchers/git.js.map +1 -1
  145. package/dist/lib/fetchers/github.d.ts +44 -5
  146. package/dist/lib/fetchers/github.d.ts.map +1 -1
  147. package/dist/lib/fetchers/github.js +122 -5
  148. package/dist/lib/fetchers/github.js.map +1 -1
  149. package/dist/lib/fetchers/gitlab.d.ts +2 -2
  150. package/dist/lib/fetchers/gitlab.d.ts.map +1 -1
  151. package/dist/lib/fetchers/gitlab.js.map +1 -1
  152. package/dist/lib/fetchers/jira.d.ts +2 -2
  153. package/dist/lib/fetchers/jira.d.ts.map +1 -1
  154. package/dist/lib/fetchers/jira.js.map +1 -1
  155. package/dist/lib/fetchers/linear.d.ts +2 -2
  156. package/dist/lib/fetchers/linear.d.ts.map +1 -1
  157. package/dist/lib/fetchers/linear.js.map +1 -1
  158. package/dist/lib/fetchers/notion.d.ts +2 -2
  159. package/dist/lib/fetchers/notion.d.ts.map +1 -1
  160. package/dist/lib/fetchers/notion.js.map +1 -1
  161. package/dist/lib/fetchers/slack.d.ts +2 -3
  162. package/dist/lib/fetchers/slack.d.ts.map +1 -1
  163. package/dist/lib/fetchers/slack.js.map +1 -1
  164. package/dist/lib/fetchers/teams.d.ts +2 -2
  165. package/dist/lib/fetchers/teams.d.ts.map +1 -1
  166. package/dist/lib/fetchers/teams.js.map +1 -1
  167. package/dist/lib/fetchers/zoom.d.ts +2 -2
  168. package/dist/lib/fetchers/zoom.d.ts.map +1 -1
  169. package/dist/lib/fetchers/zoom.js.map +1 -1
  170. package/dist/lib/gateway-client.d.ts +34 -0
  171. package/dist/lib/gateway-client.d.ts.map +1 -1
  172. package/dist/lib/gateway-client.js +19 -1
  173. package/dist/lib/gateway-client.js.map +1 -1
  174. package/dist/lib/github-text.d.ts +3 -0
  175. package/dist/lib/github-text.d.ts.map +1 -0
  176. package/dist/lib/github-text.js +18 -0
  177. package/dist/lib/github-text.js.map +1 -0
  178. package/dist/lib/hook-context.d.ts +10 -0
  179. package/dist/lib/hook-context.d.ts.map +1 -1
  180. package/dist/lib/hook-context.js +14 -0
  181. package/dist/lib/hook-context.js.map +1 -1
  182. package/dist/lib/import-defaults.d.ts +39 -23
  183. package/dist/lib/import-defaults.d.ts.map +1 -1
  184. package/dist/lib/import-defaults.js +28 -26
  185. package/dist/lib/import-defaults.js.map +1 -1
  186. package/dist/lib/launch/adapters/aider.d.ts +17 -0
  187. package/dist/lib/launch/adapters/aider.d.ts.map +1 -0
  188. package/dist/lib/launch/adapters/aider.js +30 -0
  189. package/dist/lib/launch/adapters/aider.js.map +1 -0
  190. package/dist/lib/launch/adapters/auggie.d.ts +18 -0
  191. package/dist/lib/launch/adapters/auggie.d.ts.map +1 -0
  192. package/dist/lib/launch/adapters/auggie.js +34 -0
  193. package/dist/lib/launch/adapters/auggie.js.map +1 -0
  194. package/dist/lib/launch/adapters/cline.d.ts +10 -0
  195. package/dist/lib/launch/adapters/cline.d.ts.map +1 -0
  196. package/dist/lib/launch/adapters/cline.js +41 -0
  197. package/dist/lib/launch/adapters/cline.js.map +1 -0
  198. package/dist/lib/launch/adapters/continue.d.ts +22 -0
  199. package/dist/lib/launch/adapters/continue.d.ts.map +1 -0
  200. package/dist/lib/launch/adapters/continue.js +46 -0
  201. package/dist/lib/launch/adapters/continue.js.map +1 -0
  202. package/dist/lib/launch/adapters/gemini-cli.d.ts +13 -14
  203. package/dist/lib/launch/adapters/gemini-cli.d.ts.map +1 -1
  204. package/dist/lib/launch/adapters/gemini-cli.js +38 -53
  205. package/dist/lib/launch/adapters/gemini-cli.js.map +1 -1
  206. package/dist/lib/launch/adapters/goose.d.ts +20 -0
  207. package/dist/lib/launch/adapters/goose.d.ts.map +1 -0
  208. package/dist/lib/launch/adapters/goose.js +47 -0
  209. package/dist/lib/launch/adapters/goose.js.map +1 -0
  210. package/dist/lib/launch/adapters/notes.d.ts +7 -0
  211. package/dist/lib/launch/adapters/notes.d.ts.map +1 -0
  212. package/dist/lib/launch/adapters/notes.js +5 -0
  213. package/dist/lib/launch/adapters/notes.js.map +1 -0
  214. package/dist/lib/launch/agents.d.ts +2 -0
  215. package/dist/lib/launch/agents.d.ts.map +1 -1
  216. package/dist/lib/launch/agents.js +3 -1
  217. package/dist/lib/launch/agents.js.map +1 -1
  218. package/dist/lib/launch/auggie-state.d.ts +25 -0
  219. package/dist/lib/launch/auggie-state.d.ts.map +1 -0
  220. package/dist/lib/launch/auggie-state.js +74 -0
  221. package/dist/lib/launch/auggie-state.js.map +1 -0
  222. package/dist/lib/launch/cline-state.d.ts +32 -0
  223. package/dist/lib/launch/cline-state.d.ts.map +1 -0
  224. package/dist/lib/launch/cline-state.js +108 -0
  225. package/dist/lib/launch/cline-state.js.map +1 -0
  226. package/dist/lib/launch/config-writes.d.ts +4 -0
  227. package/dist/lib/launch/config-writes.d.ts.map +1 -1
  228. package/dist/lib/launch/config-writes.js +8 -3
  229. package/dist/lib/launch/config-writes.js.map +1 -1
  230. package/dist/lib/launch/continue-state.d.ts +41 -0
  231. package/dist/lib/launch/continue-state.d.ts.map +1 -0
  232. package/dist/lib/launch/continue-state.js +142 -0
  233. package/dist/lib/launch/continue-state.js.map +1 -0
  234. package/dist/lib/launch/detect.d.ts.map +1 -1
  235. package/dist/lib/launch/detect.js +3 -1
  236. package/dist/lib/launch/detect.js.map +1 -1
  237. package/dist/lib/launch/gemini-state.d.ts +26 -20
  238. package/dist/lib/launch/gemini-state.d.ts.map +1 -1
  239. package/dist/lib/launch/gemini-state.js +95 -37
  240. package/dist/lib/launch/gemini-state.js.map +1 -1
  241. package/dist/lib/launch/gemini-system-file.d.ts +17 -0
  242. package/dist/lib/launch/gemini-system-file.d.ts.map +1 -0
  243. package/dist/lib/launch/gemini-system-file.js +55 -0
  244. package/dist/lib/launch/gemini-system-file.js.map +1 -0
  245. package/dist/lib/launch/gemini-trust.d.ts +3 -1
  246. package/dist/lib/launch/gemini-trust.d.ts.map +1 -1
  247. package/dist/lib/launch/gemini-trust.js +10 -3
  248. package/dist/lib/launch/gemini-trust.js.map +1 -1
  249. package/dist/lib/launch/goose-state.d.ts +53 -0
  250. package/dist/lib/launch/goose-state.d.ts.map +1 -0
  251. package/dist/lib/launch/goose-state.js +137 -0
  252. package/dist/lib/launch/goose-state.js.map +1 -0
  253. package/dist/lib/launch/launch-files.d.ts.map +1 -1
  254. package/dist/lib/launch/launch-files.js +3 -2
  255. package/dist/lib/launch/launch-files.js.map +1 -1
  256. package/dist/lib/launch/launch.d.ts +17 -2
  257. package/dist/lib/launch/launch.d.ts.map +1 -1
  258. package/dist/lib/launch/launch.js +36 -3
  259. package/dist/lib/launch/launch.js.map +1 -1
  260. package/dist/lib/launch/mcp-child-env.d.ts +30 -0
  261. package/dist/lib/launch/mcp-child-env.d.ts.map +1 -0
  262. package/dist/lib/launch/mcp-child-env.js +151 -0
  263. package/dist/lib/launch/mcp-child-env.js.map +1 -0
  264. package/dist/lib/launch/pick-agent.d.ts.map +1 -1
  265. package/dist/lib/launch/pick-agent.js +4 -4
  266. package/dist/lib/launch/pick-agent.js.map +1 -1
  267. package/dist/lib/launch/picker-options.d.ts.map +1 -1
  268. package/dist/lib/launch/picker-options.js +7 -2
  269. package/dist/lib/launch/picker-options.js.map +1 -1
  270. package/dist/lib/launch/registry/agents/aider.d.ts +3 -0
  271. package/dist/lib/launch/registry/agents/aider.d.ts.map +1 -0
  272. package/dist/lib/launch/registry/agents/aider.js +13 -0
  273. package/dist/lib/launch/registry/agents/aider.js.map +1 -0
  274. package/dist/lib/launch/registry/agents/auggie.d.ts +3 -0
  275. package/dist/lib/launch/registry/agents/auggie.d.ts.map +1 -0
  276. package/dist/lib/launch/registry/agents/auggie.js +11 -0
  277. package/dist/lib/launch/registry/agents/auggie.js.map +1 -0
  278. package/dist/lib/launch/registry/agents/cline.d.ts +3 -0
  279. package/dist/lib/launch/registry/agents/cline.d.ts.map +1 -0
  280. package/dist/lib/launch/registry/agents/cline.js +19 -0
  281. package/dist/lib/launch/registry/agents/cline.js.map +1 -0
  282. package/dist/lib/launch/registry/agents/continue.d.ts +3 -0
  283. package/dist/lib/launch/registry/agents/continue.d.ts.map +1 -0
  284. package/dist/lib/launch/registry/agents/continue.js +20 -0
  285. package/dist/lib/launch/registry/agents/continue.js.map +1 -0
  286. package/dist/lib/launch/registry/agents/gemini-cli.js +2 -2
  287. package/dist/lib/launch/registry/agents/gemini-cli.js.map +1 -1
  288. package/dist/lib/launch/registry/agents/goose.d.ts +3 -0
  289. package/dist/lib/launch/registry/agents/goose.d.ts.map +1 -0
  290. package/dist/lib/launch/registry/agents/goose.js +20 -0
  291. package/dist/lib/launch/registry/agents/goose.js.map +1 -0
  292. package/dist/lib/launch/registry/index.d.ts +1 -1
  293. package/dist/lib/launch/registry/index.d.ts.map +1 -1
  294. package/dist/lib/launch/registry/index.js +7 -2
  295. package/dist/lib/launch/registry/index.js.map +1 -1
  296. package/dist/lib/launch/registry/types.d.ts +12 -1
  297. package/dist/lib/launch/registry/types.d.ts.map +1 -1
  298. package/dist/lib/launch/strict-entry.d.ts +22 -2
  299. package/dist/lib/launch/strict-entry.d.ts.map +1 -1
  300. package/dist/lib/launch/strict-entry.js +80 -2
  301. package/dist/lib/launch/strict-entry.js.map +1 -1
  302. package/dist/lib/launch/yaml-scan.d.ts +59 -0
  303. package/dist/lib/launch/yaml-scan.d.ts.map +1 -0
  304. package/dist/lib/launch/yaml-scan.js +275 -0
  305. package/dist/lib/launch/yaml-scan.js.map +1 -0
  306. package/dist/lib/local-db-epoch.d.ts +4 -0
  307. package/dist/lib/local-db-epoch.d.ts.map +1 -0
  308. package/dist/lib/local-db-epoch.js +19 -0
  309. package/dist/lib/local-db-epoch.js.map +1 -0
  310. package/dist/lib/local-db-migrate.d.ts +85 -0
  311. package/dist/lib/local-db-migrate.d.ts.map +1 -0
  312. package/dist/lib/local-db-migrate.js +484 -0
  313. package/dist/lib/local-db-migrate.js.map +1 -0
  314. package/dist/lib/local-db-v10.d.ts +28 -0
  315. package/dist/lib/local-db-v10.d.ts.map +1 -0
  316. package/dist/lib/local-db-v10.js +49 -0
  317. package/dist/lib/local-db-v10.js.map +1 -0
  318. package/dist/lib/local-db-v11.d.ts +24 -0
  319. package/dist/lib/local-db-v11.d.ts.map +1 -0
  320. package/dist/lib/local-db-v11.js +25 -0
  321. package/dist/lib/local-db-v11.js.map +1 -0
  322. package/dist/lib/local-db-v7.d.ts +30 -0
  323. package/dist/lib/local-db-v7.d.ts.map +1 -0
  324. package/dist/lib/local-db-v7.js +285 -0
  325. package/dist/lib/local-db-v7.js.map +1 -0
  326. package/dist/lib/local-db-v8.d.ts +22 -0
  327. package/dist/lib/local-db-v8.d.ts.map +1 -0
  328. package/dist/lib/local-db-v8.js +33 -0
  329. package/dist/lib/local-db-v8.js.map +1 -0
  330. package/dist/lib/local-db-v9.d.ts +10 -0
  331. package/dist/lib/local-db-v9.d.ts.map +1 -0
  332. package/dist/lib/local-db-v9.js +8 -0
  333. package/dist/lib/local-db-v9.js.map +1 -0
  334. package/dist/lib/local-db.d.ts +61 -11
  335. package/dist/lib/local-db.d.ts.map +1 -1
  336. package/dist/lib/local-db.js +186 -371
  337. package/dist/lib/local-db.js.map +1 -1
  338. package/dist/lib/local-embeddings.d.ts.map +1 -1
  339. package/dist/lib/local-embeddings.js +2 -2
  340. package/dist/lib/local-embeddings.js.map +1 -1
  341. package/dist/lib/local-gateway-client.d.ts +30 -87
  342. package/dist/lib/local-gateway-client.d.ts.map +1 -1
  343. package/dist/lib/local-gateway-client.js +182 -171
  344. package/dist/lib/local-gateway-client.js.map +1 -1
  345. package/dist/lib/local-ingest.d.ts +129 -0
  346. package/dist/lib/local-ingest.d.ts.map +1 -0
  347. package/dist/lib/local-ingest.js +81 -0
  348. package/dist/lib/local-ingest.js.map +1 -0
  349. package/dist/lib/local-link-pass.d.ts +15 -0
  350. package/dist/lib/local-link-pass.d.ts.map +1 -0
  351. package/dist/lib/local-link-pass.js +61 -0
  352. package/dist/lib/local-link-pass.js.map +1 -0
  353. package/dist/lib/local-mode.d.ts +4 -1
  354. package/dist/lib/local-mode.d.ts.map +1 -1
  355. package/dist/lib/local-mode.js +16 -1
  356. package/dist/lib/local-mode.js.map +1 -1
  357. package/dist/lib/local-provenance.d.ts +14 -0
  358. package/dist/lib/local-provenance.d.ts.map +1 -0
  359. package/dist/lib/local-provenance.js +14 -0
  360. package/dist/lib/local-provenance.js.map +1 -0
  361. package/dist/lib/local-thresholds.d.ts +70 -0
  362. package/dist/lib/local-thresholds.d.ts.map +1 -0
  363. package/dist/lib/local-thresholds.js +79 -0
  364. package/dist/lib/local-thresholds.js.map +1 -0
  365. package/dist/lib/mcp/mark-tool.d.ts +27 -0
  366. package/dist/lib/mcp/mark-tool.d.ts.map +1 -0
  367. package/dist/lib/mcp/mark-tool.js +103 -0
  368. package/dist/lib/mcp/mark-tool.js.map +1 -0
  369. package/dist/lib/mcp/share-tool.d.ts +46 -0
  370. package/dist/lib/mcp/share-tool.d.ts.map +1 -0
  371. package/dist/lib/mcp/share-tool.js +68 -0
  372. package/dist/lib/mcp/share-tool.js.map +1 -0
  373. package/dist/lib/mcp/tool-rules.d.ts +30 -0
  374. package/dist/lib/mcp/tool-rules.d.ts.map +1 -0
  375. package/dist/lib/mcp/tool-rules.js +84 -0
  376. package/dist/lib/mcp/tool-rules.js.map +1 -0
  377. package/dist/lib/mcp-backfill.d.ts +89 -0
  378. package/dist/lib/mcp-backfill.d.ts.map +1 -0
  379. package/dist/lib/mcp-backfill.js +194 -0
  380. package/dist/lib/mcp-backfill.js.map +1 -0
  381. package/dist/lib/mcp-scope.d.ts +90 -0
  382. package/dist/lib/mcp-scope.d.ts.map +1 -0
  383. package/dist/lib/mcp-scope.js +125 -0
  384. package/dist/lib/mcp-scope.js.map +1 -0
  385. package/dist/lib/mcp-sync.d.ts +64 -0
  386. package/dist/lib/mcp-sync.d.ts.map +1 -0
  387. package/dist/lib/mcp-sync.js +183 -0
  388. package/dist/lib/mcp-sync.js.map +1 -0
  389. package/dist/lib/personal-import.d.ts +7 -0
  390. package/dist/lib/personal-import.d.ts.map +1 -1
  391. package/dist/lib/personal-import.js +13 -1
  392. package/dist/lib/personal-import.js.map +1 -1
  393. package/dist/lib/safe-config-write.d.ts.map +1 -1
  394. package/dist/lib/safe-config-write.js +39 -2
  395. package/dist/lib/safe-config-write.js.map +1 -1
  396. package/dist/lib/scope-choices.d.ts +51 -0
  397. package/dist/lib/scope-choices.d.ts.map +1 -0
  398. package/dist/lib/scope-choices.js +193 -0
  399. package/dist/lib/scope-choices.js.map +1 -0
  400. package/dist/lib/scope-connect.d.ts +82 -0
  401. package/dist/lib/scope-connect.d.ts.map +1 -0
  402. package/dist/lib/scope-connect.js +258 -0
  403. package/dist/lib/scope-connect.js.map +1 -0
  404. package/dist/lib/scope-defaults.d.ts +3 -0
  405. package/dist/lib/scope-defaults.d.ts.map +1 -0
  406. package/dist/lib/scope-defaults.js +42 -0
  407. package/dist/lib/scope-defaults.js.map +1 -0
  408. package/dist/lib/scope-real.d.ts +223 -0
  409. package/dist/lib/scope-real.d.ts.map +1 -0
  410. package/dist/lib/scope-real.js +58 -0
  411. package/dist/lib/scope-real.js.map +1 -0
  412. package/dist/lib/scope-values.d.ts +76 -0
  413. package/dist/lib/scope-values.d.ts.map +1 -0
  414. package/dist/lib/scope-values.js +169 -0
  415. package/dist/lib/scope-values.js.map +1 -0
  416. package/dist/lib/scope.d.ts +161 -0
  417. package/dist/lib/scope.d.ts.map +1 -0
  418. package/dist/lib/scope.js +323 -0
  419. package/dist/lib/scope.js.map +1 -0
  420. package/dist/lib/share/command.d.ts +32 -0
  421. package/dist/lib/share/command.d.ts.map +1 -0
  422. package/dist/lib/share/command.js +136 -0
  423. package/dist/lib/share/command.js.map +1 -0
  424. package/dist/lib/share/ledger.d.ts +59 -0
  425. package/dist/lib/share/ledger.d.ts.map +1 -0
  426. package/dist/lib/share/ledger.js +135 -0
  427. package/dist/lib/share/ledger.js.map +1 -0
  428. package/dist/lib/share/payload.d.ts +92 -0
  429. package/dist/lib/share/payload.d.ts.map +1 -0
  430. package/dist/lib/share/payload.js +138 -0
  431. package/dist/lib/share/payload.js.map +1 -0
  432. package/dist/lib/share/pending.d.ts +48 -0
  433. package/dist/lib/share/pending.d.ts.map +1 -0
  434. package/dist/lib/share/pending.js +130 -0
  435. package/dist/lib/share/pending.js.map +1 -0
  436. package/dist/lib/share/preview.d.ts +18 -0
  437. package/dist/lib/share/preview.d.ts.map +1 -0
  438. package/dist/lib/share/preview.js +72 -0
  439. package/dist/lib/share/preview.js.map +1 -0
  440. package/dist/lib/share/run.d.ts +115 -0
  441. package/dist/lib/share/run.d.ts.map +1 -0
  442. package/dist/lib/share/run.js +261 -0
  443. package/dist/lib/share/run.js.map +1 -0
  444. package/dist/lib/share/salt.d.ts +2 -0
  445. package/dist/lib/share/salt.d.ts.map +1 -0
  446. package/dist/lib/share/salt.js +44 -0
  447. package/dist/lib/share/salt.js.map +1 -0
  448. package/dist/lib/share/secret-patterns.json +100 -0
  449. package/dist/lib/share/secret-scan.d.ts +19 -0
  450. package/dist/lib/share/secret-scan.d.ts.map +1 -0
  451. package/dist/lib/share/secret-scan.js +75 -0
  452. package/dist/lib/share/secret-scan.js.map +1 -0
  453. package/dist/lib/share/tty.d.ts +4 -0
  454. package/dist/lib/share/tty.d.ts.map +1 -0
  455. package/dist/lib/share/tty.js +57 -0
  456. package/dist/lib/share/tty.js.map +1 -0
  457. package/dist/lib/share/visible.d.ts +4 -0
  458. package/dist/lib/share/visible.d.ts.map +1 -0
  459. package/dist/lib/share/visible.js +30 -0
  460. package/dist/lib/share/visible.js.map +1 -0
  461. package/dist/lib/share/wire.d.ts +98 -0
  462. package/dist/lib/share/wire.d.ts.map +1 -0
  463. package/dist/lib/share/wire.js +43 -0
  464. package/dist/lib/share/wire.js.map +1 -0
  465. package/dist/lib/similarity/embedding-matrix.d.ts +64 -0
  466. package/dist/lib/similarity/embedding-matrix.d.ts.map +1 -0
  467. package/dist/lib/similarity/embedding-matrix.js +119 -0
  468. package/dist/lib/similarity/embedding-matrix.js.map +1 -0
  469. package/dist/lib/since-flag.d.ts +11 -0
  470. package/dist/lib/since-flag.d.ts.map +1 -0
  471. package/dist/lib/since-flag.js +24 -0
  472. package/dist/lib/since-flag.js.map +1 -0
  473. package/dist/lib/since.d.ts +59 -0
  474. package/dist/lib/since.d.ts.map +1 -0
  475. package/dist/lib/since.js +86 -0
  476. package/dist/lib/since.js.map +1 -0
  477. package/dist/lib/source-key.d.ts +13 -0
  478. package/dist/lib/source-key.d.ts.map +1 -0
  479. package/dist/lib/source-key.js +60 -0
  480. package/dist/lib/source-key.js.map +1 -0
  481. package/dist/lib/source-sync-state.d.ts +12 -0
  482. package/dist/lib/source-sync-state.d.ts.map +1 -0
  483. package/dist/lib/source-sync-state.js +43 -0
  484. package/dist/lib/source-sync-state.js.map +1 -0
  485. package/dist/lib/startup-backfill-track.d.ts +2 -0
  486. package/dist/lib/startup-backfill-track.d.ts.map +1 -0
  487. package/dist/lib/startup-backfill-track.js +6 -0
  488. package/dist/lib/startup-backfill-track.js.map +1 -0
  489. package/dist/lib/startup-xdg.d.ts +2 -0
  490. package/dist/lib/startup-xdg.d.ts.map +1 -0
  491. package/dist/lib/startup-xdg.js +9 -0
  492. package/dist/lib/startup-xdg.js.map +1 -0
  493. package/dist/lib/sync/after-connect.d.ts +2 -0
  494. package/dist/lib/sync/after-connect.d.ts.map +1 -0
  495. package/dist/lib/sync/after-connect.js +18 -0
  496. package/dist/lib/sync/after-connect.js.map +1 -0
  497. package/dist/lib/sync/bg-claim.d.ts +14 -0
  498. package/dist/lib/sync/bg-claim.d.ts.map +1 -0
  499. package/dist/lib/sync/bg-claim.js +97 -0
  500. package/dist/lib/sync/bg-claim.js.map +1 -0
  501. package/dist/lib/sync/blocked.d.ts +8 -0
  502. package/dist/lib/sync/blocked.d.ts.map +1 -0
  503. package/dist/lib/sync/blocked.js +44 -0
  504. package/dist/lib/sync/blocked.js.map +1 -0
  505. package/dist/lib/sync/classify.d.ts +34 -0
  506. package/dist/lib/sync/classify.d.ts.map +1 -0
  507. package/dist/lib/sync/classify.js +91 -0
  508. package/dist/lib/sync/classify.js.map +1 -0
  509. package/dist/lib/sync/drain.d.ts +16 -0
  510. package/dist/lib/sync/drain.d.ts.map +1 -0
  511. package/dist/lib/sync/drain.js +33 -0
  512. package/dist/lib/sync/drain.js.map +1 -0
  513. package/dist/lib/sync/forget.d.ts +12 -0
  514. package/dist/lib/sync/forget.d.ts.map +1 -0
  515. package/dist/lib/sync/forget.js +32 -0
  516. package/dist/lib/sync/forget.js.map +1 -0
  517. package/dist/lib/sync/launch-hook.d.ts +42 -0
  518. package/dist/lib/sync/launch-hook.d.ts.map +1 -0
  519. package/dist/lib/sync/launch-hook.js +117 -0
  520. package/dist/lib/sync/launch-hook.js.map +1 -0
  521. package/dist/lib/sync/lock.d.ts +35 -0
  522. package/dist/lib/sync/lock.d.ts.map +1 -0
  523. package/dist/lib/sync/lock.js +175 -0
  524. package/dist/lib/sync/lock.js.map +1 -0
  525. package/dist/lib/sync/purge.d.ts +38 -0
  526. package/dist/lib/sync/purge.d.ts.map +1 -0
  527. package/dist/lib/sync/purge.js +61 -0
  528. package/dist/lib/sync/purge.js.map +1 -0
  529. package/dist/lib/sync/real-env.d.ts +208 -0
  530. package/dist/lib/sync/real-env.d.ts.map +1 -0
  531. package/dist/lib/sync/real-env.js +47 -0
  532. package/dist/lib/sync/real-env.js.map +1 -0
  533. package/dist/lib/sync/relink.d.ts +14 -0
  534. package/dist/lib/sync/relink.d.ts.map +1 -0
  535. package/dist/lib/sync/relink.js +36 -0
  536. package/dist/lib/sync/relink.js.map +1 -0
  537. package/dist/lib/sync/report.d.ts +3 -0
  538. package/dist/lib/sync/report.d.ts.map +1 -0
  539. package/dist/lib/sync/report.js +54 -0
  540. package/dist/lib/sync/report.js.map +1 -0
  541. package/dist/lib/sync/run-all.d.ts +23 -0
  542. package/dist/lib/sync/run-all.d.ts.map +1 -0
  543. package/dist/lib/sync/run-all.js +30 -0
  544. package/dist/lib/sync/run-all.js.map +1 -0
  545. package/dist/lib/sync/run-source.d.ts +73 -0
  546. package/dist/lib/sync/run-source.d.ts.map +1 -0
  547. package/dist/lib/sync/run-source.js +262 -0
  548. package/dist/lib/sync/run-source.js.map +1 -0
  549. package/dist/lib/sync/safe-read.d.ts +4 -0
  550. package/dist/lib/sync/safe-read.d.ts.map +1 -0
  551. package/dist/lib/sync/safe-read.js +40 -0
  552. package/dist/lib/sync/safe-read.js.map +1 -0
  553. package/dist/lib/sync/should-background-sync.d.ts +31 -0
  554. package/dist/lib/sync/should-background-sync.d.ts.map +1 -0
  555. package/dist/lib/sync/should-background-sync.js +69 -0
  556. package/dist/lib/sync/should-background-sync.js.map +1 -0
  557. package/dist/lib/sync/source-ids.d.ts +10 -0
  558. package/dist/lib/sync/source-ids.d.ts.map +1 -0
  559. package/dist/lib/sync/source-ids.js +9 -0
  560. package/dist/lib/sync/source-ids.js.map +1 -0
  561. package/dist/lib/sync/sources.d.ts +33 -0
  562. package/dist/lib/sync/sources.d.ts.map +1 -0
  563. package/dist/lib/sync/sources.js +37 -0
  564. package/dist/lib/sync/sources.js.map +1 -0
  565. package/dist/lib/sync/spawn-background.d.ts +27 -0
  566. package/dist/lib/sync/spawn-background.d.ts.map +1 -0
  567. package/dist/lib/sync/spawn-background.js +66 -0
  568. package/dist/lib/sync/spawn-background.js.map +1 -0
  569. package/dist/lib/sync/status.d.ts +57 -0
  570. package/dist/lib/sync/status.d.ts.map +1 -0
  571. package/dist/lib/sync/status.js +166 -0
  572. package/dist/lib/sync/status.js.map +1 -0
  573. package/dist/lib/sync/summary-read.d.ts +19 -0
  574. package/dist/lib/sync/summary-read.d.ts.map +1 -0
  575. package/dist/lib/sync/summary-read.js +39 -0
  576. package/dist/lib/sync/summary-read.js.map +1 -0
  577. package/dist/lib/sync/summary.d.ts +10 -0
  578. package/dist/lib/sync/summary.d.ts.map +1 -0
  579. package/dist/lib/sync/summary.js +80 -0
  580. package/dist/lib/sync/summary.js.map +1 -0
  581. package/dist/lib/sync/sync-state.d.ts +128 -0
  582. package/dist/lib/sync/sync-state.d.ts.map +1 -0
  583. package/dist/lib/sync/sync-state.js +253 -0
  584. package/dist/lib/sync/sync-state.js.map +1 -0
  585. package/dist/lib/sync/telemetry.d.ts +20 -0
  586. package/dist/lib/sync/telemetry.d.ts.map +1 -0
  587. package/dist/lib/sync/telemetry.js +31 -0
  588. package/dist/lib/sync/telemetry.js.map +1 -0
  589. package/dist/lib/sync/threads.d.ts +48 -0
  590. package/dist/lib/sync/threads.d.ts.map +1 -0
  591. package/dist/lib/sync/threads.js +82 -0
  592. package/dist/lib/sync/threads.js.map +1 -0
  593. package/dist/lib/sync/window.d.ts +72 -0
  594. package/dist/lib/sync/window.d.ts.map +1 -0
  595. package/dist/lib/sync/window.js +112 -0
  596. package/dist/lib/sync/window.js.map +1 -0
  597. package/dist/lib/team-cta.d.ts +11 -0
  598. package/dist/lib/team-cta.d.ts.map +1 -0
  599. package/dist/lib/team-cta.js +16 -0
  600. package/dist/lib/team-cta.js.map +1 -0
  601. package/dist/lib/telemetry-ci.d.ts +2 -0
  602. package/dist/lib/telemetry-ci.d.ts.map +1 -0
  603. package/dist/lib/telemetry-ci.js +21 -0
  604. package/dist/lib/telemetry-ci.js.map +1 -0
  605. package/dist/lib/telemetry-consent.d.ts +44 -23
  606. package/dist/lib/telemetry-consent.d.ts.map +1 -1
  607. package/dist/lib/telemetry-consent.js +74 -35
  608. package/dist/lib/telemetry-consent.js.map +1 -1
  609. package/dist/lib/telemetry-env.d.ts +1 -1
  610. package/dist/lib/usage-telemetry.d.ts +87 -22
  611. package/dist/lib/usage-telemetry.d.ts.map +1 -1
  612. package/dist/lib/usage-telemetry.js +263 -74
  613. package/dist/lib/usage-telemetry.js.map +1 -1
  614. package/dist/lib/xdg.d.ts +27 -0
  615. package/dist/lib/xdg.d.ts.map +1 -0
  616. package/dist/lib/xdg.js +56 -0
  617. package/dist/lib/xdg.js.map +1 -0
  618. package/package.json +3 -2
  619. package/dist/commands/push.d.ts +0 -25
  620. package/dist/commands/push.d.ts.map +0 -1
  621. package/dist/commands/push.js +0 -98
  622. package/dist/commands/push.js.map +0 -1
@@ -0,0 +1,32 @@
1
+ /**
2
+ * L5: what `align local forget <source>` does to the graph, beside dropping the token.
3
+ * Without `--purge`: the source's sync rows and item state go (its window and watermark mean nothing
4
+ * without a token) and the imported items stay; the caller is told how many. With `--purge`: the
5
+ * items nobody has vouched for go too (purge.ts says which are kept and why).
6
+ *
7
+ * ONE transaction: a failure leaves the graph as it was, and the caller drops the token only after
8
+ * this returns, so a failed forget never leaves a token-less source with half its state.
9
+ */
10
+ import fs from 'node:fs';
11
+ import { createLocalDb } from '../local-db.js';
12
+ import { isPurgeable, previewIn, purgeIn } from './purge.js';
13
+ import { transact } from './sync-state.js';
14
+ export function forgetSourceData(dbPath, source, o) {
15
+ // A graph that does not exist has nothing to forget, and opening it would create it.
16
+ if (dbPath === undefined || !fs.existsSync(dbPath))
17
+ return { syncRowsRemoved: 0, staying: 0, ...(o.purge ? { purged: { deleted: 0, kept: 0 } } : {}) };
18
+ if (o.purge && !isPurgeable(source))
19
+ throw new Error(`"${source.slice(0, 24)}" is not a connector source, so nothing was purged.`);
20
+ // Opening through the one opener migrates an older file (the tables below exist) and refuses a newer one.
21
+ createLocalDb(dbPath).close();
22
+ return transact(dbPath, (db) => {
23
+ const syncRowsRemoved = Number(db.prepare('DELETE FROM source_sync WHERE source_id = ?').run(source).changes);
24
+ db.prepare('DELETE FROM sync_item_state WHERE platform = ?').run(source);
25
+ if (o.purge) {
26
+ const purged = purgeIn(db, source);
27
+ return { syncRowsRemoved, purged, staying: purged.kept };
28
+ }
29
+ return { syncRowsRemoved, staying: previewIn(db, source).total };
30
+ });
31
+ }
32
+ //# sourceMappingURL=forget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forget.js","sourceRoot":"","sources":["../../../src/lib/sync/forget.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAoB,MAAM,YAAY,CAAC;AAC/E,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAU3C,MAAM,UAAU,gBAAgB,CAAC,MAA0B,EAAE,MAAc,EAAE,CAAqB;IAChG,qFAAqF;IACrF,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,eAAe,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACvJ,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,qDAAqD,CAAC,CAAC;IACnI,0GAA0G;IAC1G,aAAa,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC;IAC9B,OAAO,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE;QAC7B,MAAM,eAAe,GAAG,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,6CAA6C,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC;QAC9G,EAAE,CAAC,OAAO,CAAC,gDAAgD,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACzE,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YACZ,MAAM,MAAM,GAAG,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YACnC,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;QAC3D,CAAC;QACD,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,42 @@
1
+ import { type SyncSummary } from './summary-read.js';
2
+ export declare const BACKGROUND_SYNC_NOTICE = "Align refreshes your connected sources in the background when you start it, at most every 15 minutes per source. Turn off: align sync --off";
3
+ export interface BackgroundSyncConfig {
4
+ isBackgroundSyncOff?(): boolean;
5
+ backgroundSyncNoticeShown?(): boolean;
6
+ markBackgroundSyncNoticeShown?(at: string): void;
7
+ getReauthLineShownAt?(): string | undefined;
8
+ markReauthLineShown?(at: string): void;
9
+ }
10
+ /** The parts that touch the disk or start a process. Tests replace them; the defaults are rooted at the host's env and home. */
11
+ export interface BackgroundSyncIo {
12
+ readSummary(): SyncSummary | undefined;
13
+ /** Is a sync or a backfill running for this source right now? */
14
+ busy(source: string): boolean;
15
+ inCi(): boolean;
16
+ /**
17
+ * Take the per-source claim for this interval, atomically (an exclusive create). False when another launch holds a
18
+ * fresh one, or the claim cannot be written: then nothing starts for that source. Concurrent launches inside the child's
19
+ * 20 s delay therefore start ONE child, not one each.
20
+ */
21
+ claim(source: string): boolean;
22
+ releaseClaim(source: string): void;
23
+ /** Fire and forget. The launcher never awaits what this returns. */
24
+ start(sources: string[]): unknown;
25
+ nowMs(): number;
26
+ }
27
+ export interface BackgroundSyncHost {
28
+ env: Record<string, string | undefined>;
29
+ home: string;
30
+ platform: string;
31
+ isTTY: boolean;
32
+ config: BackgroundSyncConfig;
33
+ err(line: string): void;
34
+ io?: Partial<BackgroundSyncIo>;
35
+ }
36
+ export interface BackgroundPlan {
37
+ sources: string[];
38
+ reauth: string[];
39
+ }
40
+ export declare function planBackgroundSync(h: BackgroundSyncHost): BackgroundPlan;
41
+ export declare function applyBackgroundPlan(plan: BackgroundPlan, h: BackgroundSyncHost): void;
42
+ //# sourceMappingURL=launch-hook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launch-hook.d.ts","sourceRoot":"","sources":["../../../src/lib/sync/launch-hook.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAElE,eAAO,MAAM,sBAAsB,gJAC4G,CAAC;AAEhJ,MAAM,WAAW,oBAAoB;IACnC,mBAAmB,CAAC,IAAI,OAAO,CAAC;IAChC,yBAAyB,CAAC,IAAI,OAAO,CAAC;IACtC,6BAA6B,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACjD,oBAAoB,CAAC,IAAI,MAAM,GAAG,SAAS,CAAC;IAC5C,mBAAmB,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;CACxC;AAED,gIAAgI;AAChI,MAAM,WAAW,gBAAgB;IAC/B,WAAW,IAAI,WAAW,GAAG,SAAS,CAAC;IACvC,iEAAiE;IACjE,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9B,IAAI,IAAI,OAAO,CAAC;IAChB;;;;OAIG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,oEAAoE;IACpE,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAClC,KAAK,IAAI,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,oBAAoB,CAAC;IAC7B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,EAAE,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,cAAc;IAAG,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE;AA2BvE,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,kBAAkB,GAAG,cAAc,CAuBxE;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,cAAc,EAAE,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAkCrF"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * L6: the launch-time background refresh (Decisions 8, 9, 23). Called from launchIfChosen in two
3
+ * halves so the launch cost line stays honest:
4
+ *
5
+ * - `planBackgroundSync` DECIDES. Read-only: one small JSON file, a lock file per due source, nothing
6
+ * else. It runs before the overhead trace line, so its time is in the number the budget gates.
7
+ * - `applyBackgroundPlan` ACTS: prints the two lines, records that it did, and starts the detached
8
+ * child without waiting for it. It runs only after the dry-run exit, because a dry run measures
9
+ * and must not change the machine.
10
+ *
11
+ * Imports are deliberately small (no database layer, no fetcher, no setup.ts):
12
+ * launch-path-imports.test.ts walks them. Nothing here throws into the launcher: a failure to
13
+ * decide or to start means no refresh this time, and the agent opens exactly as it would have.
14
+ */
15
+ import path from 'node:path';
16
+ import { alignStateDirPath, liveBackfills, pidAlive } from '../backfill-state.js';
17
+ import { inCi } from '../telemetry-ci.js';
18
+ import { claimInForce, releaseClaim, takeClaim } from './bg-claim.js';
19
+ import { lockHolder } from './lock.js';
20
+ import { BACKGROUND_LAUNCH_DELAY_SECONDS, REAUTH_LINE_INTERVAL_MS, reauthSources, shouldBackgroundSync, SYNC_MIN_INTERVAL_MS } from './should-background-sync.js';
21
+ import { startSyncChild } from './spawn-background.js';
22
+ import { readSummary } from './summary-read.js';
23
+ export const BACKGROUND_SYNC_NOTICE = 'Align refreshes your connected sources in the background when you start it, at most every 15 minutes per source. Turn off: align sync --off';
24
+ const EMPTY = { sources: [], reauth: [] };
25
+ const set = (v) => v !== undefined && v !== '';
26
+ function defaultIo(h) {
27
+ const stateDir = alignStateDirPath(h.env, h.home, h.platform);
28
+ // Read once per launch, however many sources are due.
29
+ let backfills;
30
+ const runningBackfills = () => (backfills ??= liveBackfills(path.join(stateDir, 'backfill'), pidAlive));
31
+ return {
32
+ readSummary: () => readSummary(stateDir),
33
+ busy: (source) => lockHolder(`sync-${source}`, { dir: stateDir }) !== undefined
34
+ || runningBackfills().some((s) => s.source === source)
35
+ || claimInForce(stateDir, source, Date.now(), SYNC_MIN_INTERVAL_MS),
36
+ inCi: () => inCi(h.env),
37
+ // Skip, never block: a claim that cannot be recorded (an object in the way, an unwritable directory) means no start for that source,
38
+ // and `align sync --status` says why.
39
+ claim: (source) => takeClaim(stateDir, source, Date.now(), SYNC_MIN_INTERVAL_MS).ok,
40
+ releaseClaim: (source) => releaseClaim(stateDir, source, Date.now(), SYNC_MIN_INTERVAL_MS),
41
+ start: (sources) => startSyncChild(sources, { delaySeconds: BACKGROUND_LAUNCH_DELAY_SECONDS, env: h.env, caller: 'launcher' }),
42
+ nowMs: () => Date.now(),
43
+ };
44
+ }
45
+ const ioOf = (h) => ({ ...defaultIo(h), ...h.io });
46
+ export function planBackgroundSync(h) {
47
+ try {
48
+ // The cheap gates first: most launches outside a terminal, or with the switch set, read nothing.
49
+ if (!h.isTTY || set(h.env['ALIGN_WRAPPED']) || set(h.env['ALIGN_NO_SYNC']))
50
+ return EMPTY;
51
+ if (h.config.isBackgroundSyncOff?.() === true)
52
+ return EMPTY;
53
+ const io = ioOf(h);
54
+ const summary = io.readSummary();
55
+ if (summary === undefined)
56
+ return EMPTY;
57
+ const now = io.nowMs();
58
+ const gates = { isTty: h.isTTY, wrapped: false, noSync: false, disabled: false, summary, now };
59
+ // `ci` is asked only when something is due, and `busy` only for what is due.
60
+ let sources = shouldBackgroundSync({ ...gates, ci: false, minIntervalMs: SYNC_MIN_INTERVAL_MS });
61
+ if (sources.length > 0) {
62
+ const busy = new Set(sources.filter((s) => io.busy(s)));
63
+ sources = io.inCi() ? [] : shouldBackgroundSync({ ...gates, ci: false, minIntervalMs: SYNC_MIN_INTERVAL_MS, busy });
64
+ }
65
+ let reauth = reauthSources({ ...gates, ci: false, lastShownAt: h.config.getReauthLineShownAt?.(), intervalMs: REAUTH_LINE_INTERVAL_MS });
66
+ if (reauth.length > 0 && io.inCi())
67
+ reauth = [];
68
+ return { sources, reauth };
69
+ }
70
+ catch {
71
+ return EMPTY;
72
+ }
73
+ }
74
+ export function applyBackgroundPlan(plan, h) {
75
+ try {
76
+ const io = ioOf(h);
77
+ const stamp = () => new Date(io.nowMs()).toISOString();
78
+ // Mark first and print only if the mark held: a config that cannot be written would otherwise repeat the line every launch.
79
+ if (plan.reauth.length > 0) {
80
+ try {
81
+ h.config.markReauthLineShown?.(stamp());
82
+ const s = plan.reauth.length === 1;
83
+ h.err(`Align cannot refresh ${plan.reauth.join(', ')}: ${s ? 'its' : 'their'} saved login stopped working. Reconnect: align connect ${plan.reauth[0]}`);
84
+ }
85
+ catch { /* an unwritable config: no line this time, and no repeat */ }
86
+ }
87
+ if (plan.sources.length === 0)
88
+ return;
89
+ if (h.config.backgroundSyncNoticeShown?.() !== true) {
90
+ try {
91
+ h.config.markBackgroundSyncNoticeShown?.(stamp());
92
+ }
93
+ catch {
94
+ return; // the first-use line cannot be recorded, so it is not shown and nothing starts undisclosed
95
+ }
96
+ h.err(BACKGROUND_SYNC_NOTICE);
97
+ }
98
+ // Only the sources whose claim THIS launch took: a concurrent launch already started those.
99
+ const claimed = plan.sources.filter((s) => io.claim(s));
100
+ if (claimed.length === 0)
101
+ return;
102
+ // Not awaited: the agent must not wait for a process to be confirmed. A start that fails gives the claim back.
103
+ const release = () => { for (const s of claimed)
104
+ io.releaseClaim(s); };
105
+ try {
106
+ void Promise.resolve(io.start(claimed)).then((r) => { if (r?.ok === false)
107
+ release(); }, release);
108
+ }
109
+ catch {
110
+ release();
111
+ }
112
+ }
113
+ catch {
114
+ // No refresh this time; the launch goes on.
115
+ }
116
+ }
117
+ //# sourceMappingURL=launch-hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launch-hook.js","sourceRoot":"","sources":["../../../src/lib/sync/launch-hook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ export declare const LOCK_STALE_MS: number;
2
+ export interface LockBody {
3
+ pid: number;
4
+ started_at: string;
5
+ at: number;
6
+ nonce: string;
7
+ }
8
+ export type Lock = {
9
+ ok: true; /** Is the lock file still mine? False after a takeover or a release. */
10
+ owned(): boolean;
11
+ touch(): void;
12
+ release(): void;
13
+ }
14
+ /** `holder` is absent when the lock could not be taken for a reason that names no process. */
15
+ | {
16
+ ok: false;
17
+ holder?: {
18
+ pid: number;
19
+ started_at: string;
20
+ };
21
+ };
22
+ export interface LockOptions {
23
+ dir?: string;
24
+ pid?: number;
25
+ now?: () => number;
26
+ alive?: (pid: number) => boolean;
27
+ }
28
+ export declare function lockFile(dir: string, name: string): string;
29
+ export declare function acquireLock(name: string, o?: LockOptions): Lock;
30
+ /** Who holds this lock right now (a live pid, touched within 30 minutes), or undefined. Reads only: it never takes the lock. */
31
+ export declare function lockHolder(name: string, o?: LockOptions): {
32
+ pid: number;
33
+ started_at: string;
34
+ } | undefined;
35
+ //# sourceMappingURL=lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../../src/lib/sync/lock.ts"],"names":[],"mappings":"AA0BA,eAAO,MAAM,aAAa,QAAc,CAAC;AAKzC,MAAM,WAAW,QAAQ;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AAExF,MAAM,MAAM,IAAI,GACZ;IAAE,EAAE,EAAE,IAAI,CAAC,CAAC,wEAAwE;IAAC,KAAK,IAAI,OAAO,CAAC;IAAC,KAAK,IAAI,IAAI,CAAC;IAAC,OAAO,IAAI,IAAI,CAAA;CAAE;AACzI,8FAA8F;GAC5F;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC;AAEhE,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CAClC;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAG1D;AAuCD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,GAAE,WAAgB,GAAG,IAAI,CAkEnE;AAED,gIAAgI;AAChI,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,GAAE,WAAgB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAO7G"}
@@ -0,0 +1,175 @@
1
+ /**
2
+ * L5: the sync lock. One writer per source, across processes, on every OS.
3
+ *
4
+ * A lock is a small file created ATOMICALLY WITH ITS CONTENT: the body is written to a private
5
+ * temp file and hard-linked into place, and link fails if the name exists, so a reader never sees a
6
+ * half-written lock and two processes cannot both create it. (A filesystem without hard links
7
+ * falls back to the exclusive-create flag.) It holds the pid, the start time and a nonce. It is
8
+ * STALE when its pid is gone or it has not been touched for 30 minutes (a pid can be reused, and a
9
+ * run quiet for half an hour has stopped). A lock file that cannot be read is NOT stale until its
10
+ * own modified time is 30 minutes old: a corrupt file is more likely a peer mid-write than a corpse.
11
+ *
12
+ * Takeover is serialised by a guard file (`<lock>.takeover`, exclusive create): one process at a
13
+ * time judges a lock stale, removes it and creates its own, and it re-reads the lock after taking
14
+ * the guard so it removes only the lock it judged. A second process arriving meanwhile is told the
15
+ * lock is held, which is the safe answer.
16
+ *
17
+ * A holder can still lose its lock (a laptop asleep past 30 minutes, then a peer took over). The
18
+ * holder therefore asks `owned()` before every batch it commits and before it records its result,
19
+ * and stops if the answer is no: at worst one batch of idempotent upserts overlaps.
20
+ */
21
+ import { randomBytes } from 'node:crypto';
22
+ import fs from 'node:fs';
23
+ import path from 'node:path';
24
+ import { alignStateDir, pidAlive } from '../backfill-state.js';
25
+ import { readRegularFile } from './safe-read.js';
26
+ export const LOCK_STALE_MS = 30 * 60_000;
27
+ /** A takeover guard is held for microseconds; one older than this is a corpse. */
28
+ const GUARD_STALE_MS = 10_000;
29
+ const NAME = /^[a-z0-9][a-z0-9-]*$/;
30
+ export function lockFile(dir, name) {
31
+ if (!NAME.test(name))
32
+ throw new Error(`Not a valid lock name: ${JSON.stringify(name.slice(0, 40))}`);
33
+ return path.join(dir, `${name}.lock`);
34
+ }
35
+ function read(file) {
36
+ const raw = readRegularFile(file, 4096);
37
+ if (raw === undefined)
38
+ return undefined;
39
+ try {
40
+ const b = JSON.parse(raw);
41
+ if (Number.isInteger(b.pid) && typeof b.at === 'number' && typeof b.started_at === 'string' && typeof b.nonce === 'string')
42
+ return { raw, body: b };
43
+ }
44
+ catch { /* not a lock body */ }
45
+ return { raw, body: undefined };
46
+ }
47
+ function ageOf(file, now) {
48
+ try {
49
+ return now - fs.statSync(file).mtimeMs;
50
+ }
51
+ catch {
52
+ return Number.POSITIVE_INFINITY;
53
+ }
54
+ }
55
+ /** Create `file` holding `body` in one atomic step, or report that it exists. */
56
+ function createWhole(file, body, tag) {
57
+ const tmp = `${file}.tmp.${tag}`;
58
+ fs.writeFileSync(tmp, body, { mode: 0o600 });
59
+ try {
60
+ fs.linkSync(tmp, file);
61
+ return true;
62
+ }
63
+ catch (e) {
64
+ const code = e.code;
65
+ if (code === 'EEXIST')
66
+ return false;
67
+ // No hard links here (some network and FAT filesystems): the exclusive-create flag is the next best atomic.
68
+ try {
69
+ fs.writeFileSync(file, body, { flag: 'wx', mode: 0o600 });
70
+ return true;
71
+ }
72
+ catch (e2) {
73
+ if (e2.code === 'EEXIST')
74
+ return false;
75
+ throw e2;
76
+ }
77
+ }
78
+ finally {
79
+ fs.rmSync(tmp, { force: true });
80
+ }
81
+ }
82
+ export function acquireLock(name, o = {}) {
83
+ const dir = o.dir ?? alignStateDir();
84
+ if (dir === null)
85
+ return { ok: false };
86
+ const file = lockFile(dir, name);
87
+ const pid = o.pid ?? process.pid;
88
+ const now = o.now ?? Date.now;
89
+ const alive = o.alive ?? pidAlive;
90
+ const mine = { pid, started_at: new Date(now()).toISOString(), at: now(), nonce: randomBytes(8).toString('hex') };
91
+ const create = () => createWhole(file, JSON.stringify(mine), `${pid}.${mine.nonce}`);
92
+ const held = (seen) => (seen?.body ? { ok: false, holder: { pid: seen.body.pid, started_at: seen.body.started_at } } : { ok: false });
93
+ /** Is what we read a lock somebody may still be using? */
94
+ const live = (seen) => seen.body !== undefined ? alive(seen.body.pid) && now() - seen.body.at <= LOCK_STALE_MS : ageOf(file, now()) <= LOCK_STALE_MS;
95
+ if (!create()) {
96
+ const seen = read(file);
97
+ if (seen === undefined) {
98
+ // Gone between our create and our read: its holder just released it. One more try decides.
99
+ if (!create())
100
+ return { ok: false };
101
+ }
102
+ else if (live(seen)) {
103
+ return held(seen);
104
+ }
105
+ else {
106
+ const guard = `${file}.takeover`;
107
+ const guardBody = JSON.stringify({ pid, at: now() });
108
+ let guarded = false;
109
+ for (let attempt = 0; attempt < 2 && !guarded; attempt++) {
110
+ try {
111
+ fs.writeFileSync(guard, guardBody, { flag: 'wx', mode: 0o600 });
112
+ guarded = true;
113
+ }
114
+ catch (e) {
115
+ if (e.code !== 'EEXIST')
116
+ throw e;
117
+ if (ageOf(guard, now()) <= GUARD_STALE_MS)
118
+ return { ok: false }; // somebody is taking it over right now
119
+ fs.rmSync(guard, { force: true });
120
+ }
121
+ }
122
+ if (!guarded)
123
+ return { ok: false };
124
+ try {
125
+ const again = read(file);
126
+ // Only the lock we judged stale may be removed. Anything else is a peer's: leave it.
127
+ if (again !== undefined && again.raw !== seen.raw)
128
+ return held(again);
129
+ if (again !== undefined)
130
+ fs.rmSync(file, { force: true });
131
+ if (!create())
132
+ return { ok: false };
133
+ }
134
+ finally {
135
+ fs.rmSync(guard, { force: true });
136
+ }
137
+ }
138
+ }
139
+ const ownsIt = () => read(file)?.body?.nonce === mine.nonce;
140
+ return {
141
+ ok: true,
142
+ owned: ownsIt,
143
+ touch() {
144
+ if (!ownsIt())
145
+ return;
146
+ const tmp = `${file}.touch.${pid}.${mine.nonce}`;
147
+ try {
148
+ fs.writeFileSync(tmp, JSON.stringify({ ...mine, at: now() }), { mode: 0o600 });
149
+ fs.renameSync(tmp, file);
150
+ }
151
+ catch {
152
+ fs.rmSync(tmp, { force: true }); /* the next touch will try again */
153
+ }
154
+ },
155
+ release() {
156
+ if (!ownsIt())
157
+ return;
158
+ try {
159
+ fs.rmSync(file, { force: true });
160
+ }
161
+ catch { /* a stale lock is taken over after 30 minutes */ }
162
+ },
163
+ };
164
+ }
165
+ /** Who holds this lock right now (a live pid, touched within 30 minutes), or undefined. Reads only: it never takes the lock. */
166
+ export function lockHolder(name, o = {}) {
167
+ const dir = o.dir ?? alignStateDir();
168
+ if (dir === null)
169
+ return undefined;
170
+ const body = read(lockFile(dir, name))?.body;
171
+ const now = o.now ?? Date.now;
172
+ const alive = o.alive ?? pidAlive;
173
+ return body !== undefined && alive(body.pid) && now() - body.at <= LOCK_STALE_MS ? { pid: body.pid, started_at: body.started_at } : undefined;
174
+ }
175
+ //# sourceMappingURL=lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock.js","sourceRoot":"","sources":["../../../src/lib/sync/lock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * L5: `align local forget <source> --purge`. Forgetting a source drops its token and its sync rows
3
+ * and keeps what it imported; `--purge` also deletes the imported items, but only ones nobody has
4
+ * put their name to or ever handled.
5
+ *
6
+ * What may be purged: a row of a CONNECTOR source (never git, docs, sessions, cli or anything
7
+ * else) that carries a `source_key`, which only a connector import ever sets. A row captured by
8
+ * hand (`align capture <PR url>`, a plain-text capture) has none, so it cannot be purged even when
9
+ * its platform says `github`. Note that `decider_kind` cannot separate imports from captures:
10
+ * every connector import is derived `human` (decider-kind.ts), so it is not used here.
11
+ *
12
+ * Kept whatever the platform says: a ratified row, a confirmed row, a row with ANY audit act on it
13
+ * (a `capture_seen` note is one: somebody captured it by hand after the import; only the notes the
14
+ * system writes about its own text revisions and classification attempts are not acts), a row a
15
+ * local judgement names as target or counterpart, and a row a promotion records (`promotions.local_id`).
16
+ *
17
+ * Every purged row is copied to `decisions_purged_backup` (with its vector and refs) in the same
18
+ * transaction, so a purge can be undone by copying them back. Its links and sync-item state go with it.
19
+ */
20
+ import type { DatabaseSync } from 'node:sqlite';
21
+ /** Audit rows the system writes about itself. They are not acts. `capture_seen` is NOT here: it is a person's act. */
22
+ export declare const SYSTEM_AUDIT_ACTIONS: readonly ["text_revision_pending", "sync_classified"];
23
+ /** The only names `--purge` accepts: sources a connector import fills. */
24
+ export declare const PURGEABLE_SOURCES: readonly string[];
25
+ export declare const isPurgeable: (name: string) => boolean;
26
+ export interface PurgeResult {
27
+ deleted: number;
28
+ kept: number;
29
+ }
30
+ export declare function previewIn(db: DatabaseSync, platform: string): PurgeResult & {
31
+ total: number;
32
+ };
33
+ /** Copy, then delete, inside the caller's transaction. */
34
+ export declare function purgeIn(db: DatabaseSync, platform: string): PurgeResult;
35
+ /** How many rows of this platform a purge would delete and keep. Reads only; refuses a name that is not a connector. */
36
+ export declare function purgePreview(dbPath: string, platform: string): PurgeResult;
37
+ export declare function purgePlatform(dbPath: string, platform: string): PurgeResult;
38
+ //# sourceMappingURL=purge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"purge.d.ts","sourceRoot":"","sources":["../../../src/lib/sync/purge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAOhD,sHAAsH;AACtH,eAAO,MAAM,oBAAoB,uDAAwD,CAAC;AAE1F,0EAA0E;AAC1E,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAAkC,CAAC;AAClF,eAAO,MAAM,WAAW,GAAI,MAAM,MAAM,KAAG,OAA2C,CAAC;AAEvF,MAAM,WAAW,WAAW;IAAG,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AAyB9D,wBAAgB,SAAS,CAAC,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAI7F;AAED,0DAA0D;AAC1D,wBAAgB,OAAO,CAAC,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,CAYvE;AAED,wHAAwH;AACxH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,CAI1E;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,CAG3E"}
@@ -0,0 +1,61 @@
1
+ import { copyRowsToBackup } from '../backup-copy.js';
2
+ import { createLocalDb } from '../local-db.js';
3
+ import { deleteDecisionWithDependents } from '../local-db-migrate.js';
4
+ import { BACKFILL_SOURCES } from '../mcp-backfill.js';
5
+ import { transact } from './sync-state.js';
6
+ /** Audit rows the system writes about itself. They are not acts. `capture_seen` is NOT here: it is a person's act. */
7
+ export const SYSTEM_AUDIT_ACTIONS = ['text_revision_pending', 'sync_classified'];
8
+ /** The only names `--purge` accepts: sources a connector import fills. */
9
+ export const PURGEABLE_SOURCES = [...BACKFILL_SOURCES, 'zoom'];
10
+ export const isPurgeable = (name) => PURGEABLE_SOURCES.includes(name);
11
+ const hasTable = (db, name) => db.prepare(`SELECT 1 AS hit FROM sqlite_master WHERE type = 'table' AND name = ?`).get(name) !== undefined;
12
+ /** A WHERE fragment over `decisions d` selecting the rows a purge of one platform may delete. Binds the platform once. */
13
+ function disposableWhere(db) {
14
+ const marks = SYSTEM_AUDIT_ACTIONS.map((a) => `'${a}'`).join(', ');
15
+ const parts = [
16
+ 'd.platform = ?',
17
+ 'd.source_key IS NOT NULL',
18
+ `d.platform NOT IN ('cli', 'agent-session')`,
19
+ 'd.ratified_at IS NULL',
20
+ 'd.confirmed_at IS NULL',
21
+ `NOT EXISTS (SELECT 1 FROM decision_audit a WHERE a.decision_id = d.id AND a.action NOT IN (${marks}))`,
22
+ ];
23
+ if (hasTable(db, 'local_judgements')) {
24
+ parts.push('NOT EXISTS (SELECT 1 FROM local_judgements j WHERE j.decision_id = d.id OR j.counterpart_id = d.id)');
25
+ }
26
+ if (hasTable(db, 'promotions')) {
27
+ parts.push('NOT EXISTS (SELECT 1 FROM promotions p WHERE p.local_id = d.id)');
28
+ }
29
+ return parts.join(' AND ');
30
+ }
31
+ export function previewIn(db, platform) {
32
+ const total = db.prepare('SELECT COUNT(*) AS n FROM decisions WHERE platform = ?').get(platform).n;
33
+ const deletable = isPurgeable(platform) ? db.prepare(`SELECT COUNT(*) AS n FROM decisions d WHERE ${disposableWhere(db)}`).get(platform).n : 0;
34
+ return { deleted: deletable, kept: total - deletable, total };
35
+ }
36
+ /** Copy, then delete, inside the caller's transaction. */
37
+ export function purgeIn(db, platform) {
38
+ if (!isPurgeable(platform))
39
+ throw new Error(`"${platform.slice(0, 24)}" is not a connector source, so nothing was purged.`);
40
+ const { total } = previewIn(db, platform);
41
+ const ids = db.prepare(`SELECT d.id AS id FROM decisions d WHERE ${disposableWhere(db)}`).all(platform).map((r) => r.id);
42
+ for (const id of ids) {
43
+ copyRowsToBackup(db, 'decisions', 'decisions_purged_backup', 'id', id);
44
+ copyRowsToBackup(db, 'decision_embeddings', 'decision_embeddings_purged_backup', 'decision_id', id);
45
+ copyRowsToBackup(db, 'decision_refs', 'decision_refs_purged_backup', 'decision_id', id);
46
+ deleteDecisionWithDependents(db, id);
47
+ db.prepare('DELETE FROM sync_item_state WHERE decision_id = ?').run(id);
48
+ }
49
+ return { deleted: ids.length, kept: total - ids.length };
50
+ }
51
+ /** How many rows of this platform a purge would delete and keep. Reads only; refuses a name that is not a connector. */
52
+ export function purgePreview(dbPath, platform) {
53
+ createLocalDb(dbPath).close(); // migrates an older file, refuses a newer one
54
+ const r = transact(dbPath, (db) => previewIn(db, platform));
55
+ return { deleted: r.deleted, kept: r.kept };
56
+ }
57
+ export function purgePlatform(dbPath, platform) {
58
+ createLocalDb(dbPath).close();
59
+ return transact(dbPath, (db) => purgeIn(db, platform));
60
+ }
61
+ //# sourceMappingURL=purge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"purge.js","sourceRoot":"","sources":["../../../src/lib/sync/purge.ts"],"names":[],"mappings":"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"}