@fabiofiorita/porcelain 0.63.4 → 0.65.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 (440) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +34 -28
  3. package/bin/porcelain.js +1 -404
  4. package/package.json +15 -21
  5. package/server/drizzle/0000_current-schema.sql +98 -0
  6. package/server/drizzle/0001_light_iceman.sql +9 -0
  7. package/server/drizzle/0002_backfill_comment_authors.sql +25 -0
  8. package/server/drizzle/0003_pairing_and_devices.sql +23 -0
  9. package/server/drizzle/0004_worktrees_from_git.sql +146 -0
  10. package/server/drizzle/0005_names_and_status.sql +31 -0
  11. package/server/drizzle/0006_stale_reviewed_files.sql +1 -0
  12. package/server/drizzle/0007_normalize_comment_messages.sql +66 -0
  13. package/server/drizzle/0008_published_reviews.sql +30 -0
  14. package/server/drizzle/0009_drop_unused_git_action_tables.sql +5 -0
  15. package/server/drizzle/0010_cascade_deletes_through_foreign_keys.sql +207 -0
  16. package/server/drizzle/0011_receipts_per_worktree.sql +35 -0
  17. package/server/drizzle/0012_receipts_as_columns.sql +68 -0
  18. package/server/drizzle/0013_monotonic_comment_revision.sql +21 -0
  19. package/server/drizzle/0014_reviewed_layers_without_stale.sql +1 -0
  20. package/server/drizzle/0015_remote_access.sql +9 -0
  21. package/server/drizzle/0016_reviewed_file_scopes.sql +17 -0
  22. package/server/drizzle/0017_comment_edits.sql +1 -0
  23. package/server/drizzle/0018_reviewed_file_branches.sql +18 -0
  24. package/server/drizzle/0019_review_proof.sql +10 -0
  25. package/server/drizzle/0020_environment_name.sql +5 -0
  26. package/server/drizzle/0021_device_routes.sql +35 -0
  27. package/server/drizzle/0022_lan_network.sql +18 -0
  28. package/server/drizzle/0023_tailnet_serve_target.sql +1 -0
  29. package/server/drizzle/0024_lan_router.sql +2 -0
  30. package/server/drizzle/0025_tailnet_hostname.sql +23 -0
  31. package/server/drizzle/0026_drop_removed_branch_receipts.sql +1 -0
  32. package/server/drizzle/0027_trusted_devices.sql +2 -0
  33. package/server/drizzle/meta/_journal.json +202 -0
  34. package/server/src/cli/main.mjs +32293 -0
  35. package/web/dist/apple-touch-icon.png +0 -0
  36. package/web/dist/assets/_paired-B3CMUVff.js +1 -0
  37. package/web/dist/assets/_paired-B8xCvrtN.js +1 -0
  38. package/web/dist/assets/_paired-DqFYC4oC.css +1 -0
  39. package/web/dist/assets/_paired-YiNqIqrL.js +1 -0
  40. package/web/dist/assets/_paired-rl3uQlkr.js +1 -0
  41. package/web/dist/assets/_section-DJ3o28t3.js +1 -0
  42. package/web/dist/assets/_worktreeId-B3CMUVff.js +1 -0
  43. package/web/dist/assets/_worktreeId-B8xCvrtN.js +1 -0
  44. package/web/dist/assets/_worktreeId-DS7C0JfB.js +1 -0
  45. package/web/dist/assets/_worktreeId-DzWffY3l.js +1 -0
  46. package/web/dist/assets/abap-CLvhMVsD.js +1 -0
  47. package/web/dist/assets/access-yiNkcsHW.js +1 -0
  48. package/web/dist/assets/actionscript-3-Cs6JJXT5.js +1 -0
  49. package/web/dist/assets/ada-C5qYipkI.js +1 -0
  50. package/web/dist/assets/ahk-CA9gdOdF.js +1 -0
  51. package/web/dist/assets/ahk2-_6rzW9BS.js +1 -0
  52. package/web/dist/assets/andromeeda-vGVdxbeo.js +1 -0
  53. package/web/dist/assets/angular-html-B8mrqUL5.js +1 -0
  54. package/web/dist/assets/angular-ts-Bzix210W.js +1 -0
  55. package/web/dist/assets/apache-U0d_L8uA.js +1 -0
  56. package/web/dist/assets/apex-KFGFyKwG.js +1 -0
  57. package/web/dist/assets/apl-Dhin1L29.js +1 -0
  58. package/web/dist/assets/applescript-CCn79oCD.js +1 -0
  59. package/web/dist/assets/ara-4CJ0cIlV.js +1 -0
  60. package/web/dist/assets/asciidoc-SCjQUq34.js +1 -0
  61. package/web/dist/assets/asm-Cmm7eHzH.js +1 -0
  62. package/web/dist/assets/astro-B-4NNgOP.js +1 -0
  63. package/web/dist/assets/aurora-x-CDeNXAV0.js +1 -0
  64. package/web/dist/assets/awk-BWXHIvNe.js +1 -0
  65. package/web/dist/assets/ayu-dark-DluEY0Gj.js +1 -0
  66. package/web/dist/assets/ayu-light-C3h-C4tm.js +1 -0
  67. package/web/dist/assets/ayu-mirage-Bqwy1Gya.js +1 -0
  68. package/web/dist/assets/ballerina-B7ZEbQpA.js +1 -0
  69. package/web/dist/assets/bat-qdxAdBWQ.js +1 -0
  70. package/web/dist/assets/beancount-D-usSTwE.js +1 -0
  71. package/web/dist/assets/berry-DKpUyyne.js +1 -0
  72. package/web/dist/assets/bibtex-Ci_nEsc7.js +1 -0
  73. package/web/dist/assets/bicep-CUHmPFLl.js +1 -0
  74. package/web/dist/assets/bird2-CYIUgYqB.js +1 -0
  75. package/web/dist/assets/blade-C6Gedziy.js +1 -0
  76. package/web/dist/assets/bsl-_VjlB9mv.js +1 -0
  77. package/web/dist/assets/c-iCihek07.js +1 -0
  78. package/web/dist/assets/c3-D0apG41V.js +1 -0
  79. package/web/dist/assets/cadence-CQ2zXKGN.js +1 -0
  80. package/web/dist/assets/cairo-DLTphjLi.js +1 -0
  81. package/web/dist/assets/catppuccin-frappe-C9Q5zVZY.js +1 -0
  82. package/web/dist/assets/catppuccin-latte-CtsyrtPq.js +1 -0
  83. package/web/dist/assets/catppuccin-macchiato-R8nAf1vR.js +1 -0
  84. package/web/dist/assets/catppuccin-mocha-DjuaAJKi.js +1 -0
  85. package/web/dist/assets/chapel-DmtgEXO_.js +1 -0
  86. package/web/dist/assets/clarity-CtfBBspg.js +1 -0
  87. package/web/dist/assets/clojure-DqKBuwfJ.js +1 -0
  88. package/web/dist/assets/cloneFileDiffMetadata-zVRGqYgv.js +1 -0
  89. package/web/dist/assets/cmake-Bj61d0ZC.js +1 -0
  90. package/web/dist/assets/cobol-Cw2-KvLW.js +1 -0
  91. package/web/dist/assets/codeowners-C8r90Shi.js +1 -0
  92. package/web/dist/assets/codeql-oeQT6MSM.js +1 -0
  93. package/web/dist/assets/coffee-CiiSLhB6.js +1 -0
  94. package/web/dist/assets/common-lisp-Cv5bFMCO.js +1 -0
  95. package/web/dist/assets/connected-workspace-HwRJynH2.js +1 -0
  96. package/web/dist/assets/coq-DuBRPxYg.js +1 -0
  97. package/web/dist/assets/cpp-71xkOQct.js +1 -0
  98. package/web/dist/assets/crystal-DGPAtLeY.js +1 -0
  99. package/web/dist/assets/csharp-oqKa8noW.js +1 -0
  100. package/web/dist/assets/css-CNuuLpMC.js +1 -0
  101. package/web/dist/assets/csv-Dx-8-gkx.js +1 -0
  102. package/web/dist/assets/cue-CE9AQfxI.js +1 -0
  103. package/web/dist/assets/cypher-ClKdZ_lG.js +1 -0
  104. package/web/dist/assets/d-qD-0Kul2.js +1 -0
  105. package/web/dist/assets/dark-plus-Cs2F2srj.js +1 -0
  106. package/web/dist/assets/dart-CnvKMtbv.js +1 -0
  107. package/web/dist/assets/dax-BkyTk9wS.js +1 -0
  108. package/web/dist/assets/desktop-Dlh5hvp9.js +1 -0
  109. package/web/dist/assets/desktop-UhAM-aem.js +14 -0
  110. package/web/dist/assets/desktop-actions-_GPqaBVU.js +12 -0
  111. package/web/dist/assets/diff-woXpYk--.js +1 -0
  112. package/web/dist/assets/docker-IyjqRm3v.js +1 -0
  113. package/web/dist/assets/dotenv-_5a1GRtc.js +1 -0
  114. package/web/dist/assets/dracula-BHWKrbxM.js +1 -0
  115. package/web/dist/assets/dracula-soft-5eyTD99u.js +1 -0
  116. package/web/dist/assets/dream-maker-DW3nJb8Q.js +1 -0
  117. package/web/dist/assets/edge-DCY0a-ow.js +1 -0
  118. package/web/dist/assets/edit-file-DOZdUUk9.js +1568 -0
  119. package/web/dist/assets/elixir-DP304Xio.js +1 -0
  120. package/web/dist/assets/elm-o4NJxfws.js +1 -0
  121. package/web/dist/assets/emacs-lisp-c_oH4hRZ.js +1 -0
  122. package/web/dist/assets/erb-C7MPl934.js +1 -0
  123. package/web/dist/assets/erlang-Cphh6RMH.js +1 -0
  124. package/web/dist/assets/everforest-dark-sB-x3p7T.js +1 -0
  125. package/web/dist/assets/everforest-light-Df2xbC6M.js +1 -0
  126. package/web/dist/assets/fennel-DQxkIbk2.js +1 -0
  127. package/web/dist/assets/file-editor-DvHSzrST.js +588 -0
  128. package/web/dist/assets/files-DGG-rGAk.js +4 -0
  129. package/web/dist/assets/fish-BJitypiv.js +1 -0
  130. package/web/dist/assets/fluent-C03EYrpw.js +1 -0
  131. package/web/dist/assets/fortran-fixed-form-DEKoE2YW.js +1 -0
  132. package/web/dist/assets/fortran-free-form-CYNrtFtB.js +1 -0
  133. package/web/dist/assets/fsharp-D13ZGOAj.js +1 -0
  134. package/web/dist/assets/gdresource-xMC7jr7x.js +1 -0
  135. package/web/dist/assets/gdscript-DYvRD3hg.js +1 -0
  136. package/web/dist/assets/gdshader-CBce3t8t.js +1 -0
  137. package/web/dist/assets/genie-CV2tkWYe.js +1 -0
  138. package/web/dist/assets/gherkin-DExj1W_8.js +1 -0
  139. package/web/dist/assets/git-actions-PSyqF5Ms.js +1345 -0
  140. package/web/dist/assets/git-commit-BSykSTBG.js +1 -0
  141. package/web/dist/assets/git-rebase-BDPpS8w6.js +1 -0
  142. package/web/dist/assets/github-dark-C-LZuMrd.js +1 -0
  143. package/web/dist/assets/github-dark-default-DXG-b-1a.js +1 -0
  144. package/web/dist/assets/github-dark-dimmed-Bx1FflLF.js +1 -0
  145. package/web/dist/assets/github-dark-high-contrast-B_tTalzw.js +1 -0
  146. package/web/dist/assets/github-light-EUqPIrTm.js +1 -0
  147. package/web/dist/assets/github-light-default-BXViO-2h.js +1 -0
  148. package/web/dist/assets/github-light-high-contrast-B68TUdTA.js +1 -0
  149. package/web/dist/assets/gleam-CSRkHgEL.js +1 -0
  150. package/web/dist/assets/glimmer-js-BONyzAsu.js +1 -0
  151. package/web/dist/assets/glimmer-ts-f9c0GCOe.js +1 -0
  152. package/web/dist/assets/glsl-D5MA2a_X.js +1 -0
  153. package/web/dist/assets/gn-ilITqXS6.js +1 -0
  154. package/web/dist/assets/gnuplot-7GGW24-e.js +1 -0
  155. package/web/dist/assets/go-rLFTqkRN.js +1 -0
  156. package/web/dist/assets/graphql-Ctjuxyvl.js +1 -0
  157. package/web/dist/assets/groovy-CacY0gHj.js +1 -0
  158. package/web/dist/assets/gruvbox-dark-hard-C820rvS2.js +1 -0
  159. package/web/dist/assets/gruvbox-dark-medium-BPjhmG05.js +1 -0
  160. package/web/dist/assets/gruvbox-dark-soft-MrdJrrXF.js +1 -0
  161. package/web/dist/assets/gruvbox-light-hard-BC_s9l72.js +1 -0
  162. package/web/dist/assets/gruvbox-light-medium-BAWPOn9u.js +1 -0
  163. package/web/dist/assets/gruvbox-light-soft-BSMLrYjP.js +1 -0
  164. package/web/dist/assets/hack-Dh_ZLRbs.js +1 -0
  165. package/web/dist/assets/haml-CwEpbK1d.js +1 -0
  166. package/web/dist/assets/handlebars-ryMP1rBR.js +1 -0
  167. package/web/dist/assets/haskell-D8IpX4py.js +1 -0
  168. package/web/dist/assets/haxe-C8oCnwJJ.js +1 -0
  169. package/web/dist/assets/hcl-Dh228itO.js +1 -0
  170. package/web/dist/assets/hjson-CxZEssPk.js +1 -0
  171. package/web/dist/assets/hlsl-Cvrh5tZx.js +1 -0
  172. package/web/dist/assets/horizon-CE9ld1lL.js +1 -0
  173. package/web/dist/assets/horizon-bright-DSNQnXHK.js +1 -0
  174. package/web/dist/assets/houston-CsvMBhTu.js +1 -0
  175. package/web/dist/assets/html-XwrE-1r6.js +1 -0
  176. package/web/dist/assets/html-derivative-i4STDFnl.js +1 -0
  177. package/web/dist/assets/http-kmH8AyfE.js +1 -0
  178. package/web/dist/assets/hurl-DCZHXKU4.js +1 -0
  179. package/web/dist/assets/hxml-Dcm88srW.js +1 -0
  180. package/web/dist/assets/hy-CZbG8q4J.js +1 -0
  181. package/web/dist/assets/imba-DsUTQ-LC.js +1 -0
  182. package/web/dist/assets/index-Cia9YleJ.js +10 -0
  183. package/web/dist/assets/index-DUPxq0qw.css +2 -0
  184. package/web/dist/assets/ini-B5eOa1yu.js +1 -0
  185. package/web/dist/assets/java-DdHNQ9hk.js +1 -0
  186. package/web/dist/assets/javascript-obGGvMPs.js +1 -0
  187. package/web/dist/assets/jinja-B-tLrNsM.js +1 -0
  188. package/web/dist/assets/jison-CBjhYtSs.js +1 -0
  189. package/web/dist/assets/json-DAgxKhMr.js +1 -0
  190. package/web/dist/assets/json5-BR5RXkoi.js +1 -0
  191. package/web/dist/assets/jsonc-CYpm1nAK.js +1 -0
  192. package/web/dist/assets/jsonl-CmCQp5Yx.js +1 -0
  193. package/web/dist/assets/jsonnet-CJTPZ8u_.js +1 -0
  194. package/web/dist/assets/jssm-DXw9l8Rf.js +1 -0
  195. package/web/dist/assets/jsx-gTgmArGx.js +1 -0
  196. package/web/dist/assets/julia-CXJVy74_.js +1 -0
  197. package/web/dist/assets/just-B9Xn_Dp4.js +1 -0
  198. package/web/dist/assets/kanagawa-dragon-Bozd7klA.js +1 -0
  199. package/web/dist/assets/kanagawa-lotus-BmuOG9ZW.js +1 -0
  200. package/web/dist/assets/kanagawa-wave-BML5mF2J.js +1 -0
  201. package/web/dist/assets/kdl-CsD5j6eV.js +1 -0
  202. package/web/dist/assets/kotlin-DhhofPvG.js +1 -0
  203. package/web/dist/assets/kusto-C7mF5XQf.js +1 -0
  204. package/web/dist/assets/laserwave-C_8bwKvT.js +1 -0
  205. package/web/dist/assets/latex-o9DRzaEe.js +1 -0
  206. package/web/dist/assets/lazyRouteComponent-C0cxtC0x.js +1 -0
  207. package/web/dist/assets/lean-CewbzKMR.js +1 -0
  208. package/web/dist/assets/less-DVTAwKKz.js +1 -0
  209. package/web/dist/assets/light-plus-DVQuIRkW.js +1 -0
  210. package/web/dist/assets/link-Cr7ETqcH.js +1 -0
  211. package/web/dist/assets/liquid-G0MH4h_m.js +1 -0
  212. package/web/dist/assets/llvm-DqHOMS-s.js +1 -0
  213. package/web/dist/assets/log-BNLmms1o.js +1 -0
  214. package/web/dist/assets/logo-Cluzi2Zq.js +1 -0
  215. package/web/dist/assets/lua-FONpmTUP.js +1 -0
  216. package/web/dist/assets/luau-C2pBCSgt.js +1 -0
  217. package/web/dist/assets/make-Dixweg8N.js +1 -0
  218. package/web/dist/assets/markdown-BYOwaDjH.js +1 -0
  219. package/web/dist/assets/marko-DV5GrDmo.js +1 -0
  220. package/web/dist/assets/material-theme-Bm3Qr25_.js +1 -0
  221. package/web/dist/assets/material-theme-darker-2IIEA8gg.js +1 -0
  222. package/web/dist/assets/material-theme-lighter-uhdI0v04.js +1 -0
  223. package/web/dist/assets/material-theme-ocean-CHQ94UKr.js +1 -0
  224. package/web/dist/assets/material-theme-palenight-B5W6OYN7.js +1 -0
  225. package/web/dist/assets/matlab-D7qyCx1q.js +1 -0
  226. package/web/dist/assets/mdc-BKfPFPZw.js +1 -0
  227. package/web/dist/assets/mdx-DQZ5AkYe.js +1 -0
  228. package/web/dist/assets/mermaid-BxpfTIzt.js +1 -0
  229. package/web/dist/assets/min-dark-BSWPekZh.js +1 -0
  230. package/web/dist/assets/min-light-DDpmG2fV.js +1 -0
  231. package/web/dist/assets/mipsasm-BMqwQI7S.js +1 -0
  232. package/web/dist/assets/mojo-fg40_ntQ.js +1 -0
  233. package/web/dist/assets/monokai-B_bV9PQ9.js +1 -0
  234. package/web/dist/assets/moonbit-DgjMoLWr.js +1 -0
  235. package/web/dist/assets/move-BYnGhZoM.js +1 -0
  236. package/web/dist/assets/narrat-_X_XdTYD.js +1 -0
  237. package/web/dist/assets/nextflow-BJtWHP5T.js +1 -0
  238. package/web/dist/assets/nextflow-groovy-DJMQeKeT.js +1 -0
  239. package/web/dist/assets/nginx-BTMw9COX.js +1 -0
  240. package/web/dist/assets/night-owl-DhmEMT88.js +1 -0
  241. package/web/dist/assets/night-owl-light-eJ-hLW7d.js +1 -0
  242. package/web/dist/assets/nim-B6yJ_yaC.js +1 -0
  243. package/web/dist/assets/nix-IvuFDN5E.js +1 -0
  244. package/web/dist/assets/nord-Cb4Vim4T.js +1 -0
  245. package/web/dist/assets/nsis-CjNLYCLg.js +1 -0
  246. package/web/dist/assets/nushell-DHYfO66s.js +1 -0
  247. package/web/dist/assets/objective-c-D1A_Heim.js +1 -0
  248. package/web/dist/assets/objective-cpp-BsSzOQcm.js +1 -0
  249. package/web/dist/assets/ocaml-O90oeIOV.js +1 -0
  250. package/web/dist/assets/odin-B1RWQWA5.js +1 -0
  251. package/web/dist/assets/one-dark-pro-CLwyXe_n.js +1 -0
  252. package/web/dist/assets/one-light-D7Lr4KcI.js +1 -0
  253. package/web/dist/assets/openscad-BUDT5pXO.js +1 -0
  254. package/web/dist/assets/org-Ddi8Gs6E.js +1 -0
  255. package/web/dist/assets/pair-B3CMUVff.js +1 -0
  256. package/web/dist/assets/pair-pADUBfPY.js +1 -0
  257. package/web/dist/assets/pascal-4ZHwLPI5.js +1 -0
  258. package/web/dist/assets/perl-DEgXgjuC.js +1 -0
  259. package/web/dist/assets/php-B9UPq-vz.js +1 -0
  260. package/web/dist/assets/pierre-dark-CpLgRqie.js +1 -0
  261. package/web/dist/assets/pierre-dark-protanopia-deuteranopia-B35FxJx-.js +1 -0
  262. package/web/dist/assets/pierre-dark-soft-kZQmAZld.js +1 -0
  263. package/web/dist/assets/pierre-dark-tritanopia-CpjhbsIL.js +1 -0
  264. package/web/dist/assets/pierre-dark-vibrant-CpQYzh95.js +1 -0
  265. package/web/dist/assets/pierre-light-CoaEpmwp.js +1 -0
  266. package/web/dist/assets/pierre-light-protanopia-deuteranopia-0fSaH845.js +1 -0
  267. package/web/dist/assets/pierre-light-soft-lWLdNTOI.js +1 -0
  268. package/web/dist/assets/pierre-light-tritanopia-CEbqgOJL.js +1 -0
  269. package/web/dist/assets/pierre-light-vibrant-D80Fkn33.js +1 -0
  270. package/web/dist/assets/pkl-ot-7Btpt.js +1 -0
  271. package/web/dist/assets/plastic-DQwYfKfQ.js +1 -0
  272. package/web/dist/assets/plsql-DGHpHOYJ.js +1 -0
  273. package/web/dist/assets/po-BiJDBrnU.js +1 -0
  274. package/web/dist/assets/poimandres-DRFjx7u4.js +1 -0
  275. package/web/dist/assets/polar-C7UOKdEL.js +1 -0
  276. package/web/dist/assets/postcss-BXeXVLqQ.js +1 -0
  277. package/web/dist/assets/powerquery-DNMTfnFr.js +1 -0
  278. package/web/dist/assets/powershell-CCSX75yM.js +1 -0
  279. package/web/dist/assets/preferences-gCf_-ng1.js +1 -0
  280. package/web/dist/assets/preload-helper-Czpn1I53.js +1 -0
  281. package/web/dist/assets/prisma-DMgNhnYS.js +1 -0
  282. package/web/dist/assets/prolog-iXnhIJG7.js +1 -0
  283. package/web/dist/assets/proto-DB4EqR-F.js +1 -0
  284. package/web/dist/assets/pug-DkgDHZci.js +1 -0
  285. package/web/dist/assets/puppet-CDv2pdJW.js +1 -0
  286. package/web/dist/assets/purescript-9MfHhQsQ.js +1 -0
  287. package/web/dist/assets/python-gzcpVVnB.js +1 -0
  288. package/web/dist/assets/qml-_a-QhfPD.js +1 -0
  289. package/web/dist/assets/qmldir-DCQb3MpD.js +1 -0
  290. package/web/dist/assets/qss-Fe1Jh2GI.js +1 -0
  291. package/web/dist/assets/r-BHcO8Vjq.js +1 -0
  292. package/web/dist/assets/racket-DcIDlBhZ.js +1 -0
  293. package/web/dist/assets/raku-B3gFvitq.js +1 -0
  294. package/web/dist/assets/razor-BMJ0eI3p.js +1 -0
  295. package/web/dist/assets/rbs-C0MpOrj4.js +1 -0
  296. package/web/dist/assets/red-DX1BQOs8.js +1 -0
  297. package/web/dist/assets/reg-CRGYupPL.js +1 -0
  298. package/web/dist/assets/regexp-DR20uMnK.js +1 -0
  299. package/web/dist/assets/rel-BtDbiS_P.js +1 -0
  300. package/web/dist/assets/review-diagram-CK76VybL.js +7 -0
  301. package/web/dist/assets/review-diagram-DLioOiRN.css +1 -0
  302. package/web/dist/assets/riscv-Ckw8ddFX.js +1 -0
  303. package/web/dist/assets/rolldown-runtime-hePW80VL.js +1 -0
  304. package/web/dist/assets/ron-VUp2lXgN.js +1 -0
  305. package/web/dist/assets/rose-pine-aMsaMD1D.js +1 -0
  306. package/web/dist/assets/rose-pine-dawn-8PwUyIlP.js +1 -0
  307. package/web/dist/assets/rose-pine-moon-DO-qXg-I.js +1 -0
  308. package/web/dist/assets/rosmsg-CAekHB0j.js +1 -0
  309. package/web/dist/assets/rst-BQCbfb9V.js +1 -0
  310. package/web/dist/assets/ruby-B8JcIHv0.js +1 -0
  311. package/web/dist/assets/rust-Cfkwpbl8.js +1 -0
  312. package/web/dist/assets/sas-CBpMWA2M.js +1 -0
  313. package/web/dist/assets/sass-DXrisJhu.js +1 -0
  314. package/web/dist/assets/scala-BiFt_7mu.js +1 -0
  315. package/web/dist/assets/scheme-DQCgrYNe.js +1 -0
  316. package/web/dist/assets/scss-YesllqfO.js +1 -0
  317. package/web/dist/assets/sdbl-bTVj8UrX.js +1 -0
  318. package/web/dist/assets/search-YI2tNMg7.js +1 -0
  319. package/web/dist/assets/server-CO1nBw31.js +1 -0
  320. package/web/dist/assets/shaderlab-TOUzSsQk.js +1 -0
  321. package/web/dist/assets/shellscript-Da78Ox-3.js +1 -0
  322. package/web/dist/assets/shellsession-CVsQGYfZ.js +1 -0
  323. package/web/dist/assets/slack-dark-DnToyrRv.js +1 -0
  324. package/web/dist/assets/slack-ochin-B2OO5cIa.js +1 -0
  325. package/web/dist/assets/smalltalk-BHpQb5nM.js +1 -0
  326. package/web/dist/assets/smithy-Dgaz7aur.js +1 -0
  327. package/web/dist/assets/snazzy-light-4G7pJPwS.js +1 -0
  328. package/web/dist/assets/solarized-dark-UdsmMDCL.js +1 -0
  329. package/web/dist/assets/solarized-light-C1IUL_tW.js +1 -0
  330. package/web/dist/assets/solidity-Bj7E1mRn.js +1 -0
  331. package/web/dist/assets/soy-DEd-qcad.js +1 -0
  332. package/web/dist/assets/sparql-D_iOobhT.js +1 -0
  333. package/web/dist/assets/splunk-BC2Px7Mm.js +1 -0
  334. package/web/dist/assets/sql-DdD7vxS4.js +1 -0
  335. package/web/dist/assets/ssh-config-BgfXC-Er.js +1 -0
  336. package/web/dist/assets/stata-CMv7m7Gi.js +1 -0
  337. package/web/dist/assets/stylus-B6D30XZt.js +1 -0
  338. package/web/dist/assets/surrealql-BZoq2lXR.js +1 -0
  339. package/web/dist/assets/svelte-Bj3Hmc9F.js +1 -0
  340. package/web/dist/assets/swift-CyEgAFGc.js +1 -0
  341. package/web/dist/assets/synthwave-84-nFMaYfgc.js +1 -0
  342. package/web/dist/assets/system-verilog-Dh5ihWbf.js +1 -0
  343. package/web/dist/assets/systemd-BxMlprV5.js +1 -0
  344. package/web/dist/assets/talonscript-CohzipZa.js +1 -0
  345. package/web/dist/assets/tasl-DMoTqEGO.js +1 -0
  346. package/web/dist/assets/tcl-CZd0xW_V.js +1 -0
  347. package/web/dist/assets/templ-TjxbArHn.js +1 -0
  348. package/web/dist/assets/terraform-DswuEJGm.js +1 -0
  349. package/web/dist/assets/tex-BK-H2Wn4.js +1 -0
  350. package/web/dist/assets/tokyo-night-oM2G3aXe.js +1 -0
  351. package/web/dist/assets/toml-CcmNWLt0.js +1 -0
  352. package/web/dist/assets/ts-tags-Cc5do7zu.js +1 -0
  353. package/web/dist/assets/tsv-sltzmVWM.js +1 -0
  354. package/web/dist/assets/tsx-CUOciP0b.js +1 -0
  355. package/web/dist/assets/turtle-ByJddavk.js +1 -0
  356. package/web/dist/assets/twig-BVSnuTf-.js +1 -0
  357. package/web/dist/assets/typescript-BydbNFcO.js +1 -0
  358. package/web/dist/assets/typespec-BRdr0IET.js +1 -0
  359. package/web/dist/assets/typst-C40W_gC6.js +1 -0
  360. package/web/dist/assets/useRouterState-DpORzQ8V.js +1 -0
  361. package/web/dist/assets/v-DBj4K9d_.js +1 -0
  362. package/web/dist/assets/vala-zf12oZj6.js +1 -0
  363. package/web/dist/assets/vb-DOwzaHZ0.js +1 -0
  364. package/web/dist/assets/verilog-B2gwz-sJ.js +1 -0
  365. package/web/dist/assets/vesper-DdrHHSXu.js +1 -0
  366. package/web/dist/assets/vhdl-BroJfC0k.js +1 -0
  367. package/web/dist/assets/viml-DvXPmvsu.js +1 -0
  368. package/web/dist/assets/vitesse-black-fwtXNY1n.js +1 -0
  369. package/web/dist/assets/vitesse-dark-BZCL-v6S.js +1 -0
  370. package/web/dist/assets/vitesse-light-VbXTXTou.js +1 -0
  371. package/web/dist/assets/vue-BNQF7r6F.js +1 -0
  372. package/web/dist/assets/vue-html-DkKkQnZL.js +1 -0
  373. package/web/dist/assets/vue-vine-DFaKYU4X.js +1 -0
  374. package/web/dist/assets/vyper-CgoNMtux.js +1 -0
  375. package/web/dist/assets/wasm-BnjxR4X6.js +1 -0
  376. package/web/dist/assets/wasm-ByWQv1Qj.js +1 -0
  377. package/web/dist/assets/wenyan-C8pVoKbM.js +1 -0
  378. package/web/dist/assets/wgsl-BsKzXJz4.js +1 -0
  379. package/web/dist/assets/wikitext-ClFFjSW2.js +1 -0
  380. package/web/dist/assets/wit-DdvCle-K.js +1 -0
  381. package/web/dist/assets/wolfram-DLL8P-h_.js +1 -0
  382. package/web/dist/assets/worker-Bs0l0ezO.js +162 -0
  383. package/web/dist/assets/workspace-error-DILP6VTh.js +1 -0
  384. package/web/dist/assets/workspace-pending-6RKmflS9.js +1 -0
  385. package/web/dist/assets/xml-BlnrEAEy.js +1 -0
  386. package/web/dist/assets/xsl-BOPS8gLt.js +1 -0
  387. package/web/dist/assets/yaml-Du_6cdrH.js +1 -0
  388. package/web/dist/assets/zenscript-BnlCZFoB.js +1 -0
  389. package/web/dist/assets/zig-CMLA9XwU.js +1 -0
  390. package/web/dist/favicon-32.png +0 -0
  391. package/web/dist/favicon.ico +0 -0
  392. package/web/dist/icon-192.png +0 -0
  393. package/web/dist/icon-512.png +0 -0
  394. package/web/dist/index.html +33 -0
  395. package/web/dist/manifest.webmanifest +24 -0
  396. package/main/contracts/protocol.js +0 -36
  397. package/main/daemon/server.js +0 -17067
  398. package/renderer/apple-touch-icon.png +0 -0
  399. package/renderer/assets/SymbolsNerdFontMono-Regular-aK5vsLov.woff2 +0 -0
  400. package/renderer/assets/browser-DjHhN4s0.js +0 -8
  401. package/renderer/assets/canvas-view-DhzIJ8ZV.js +0 -1
  402. package/renderer/assets/changeset-view-yBQtdgrZ.js +0 -1
  403. package/renderer/assets/commit-view-Cz3IR74x.js +0 -2
  404. package/renderer/assets/diff-mode-toggle-DTeqhuLC.js +0 -1
  405. package/renderer/assets/diff-view-DqanYaSe.js +0 -1
  406. package/renderer/assets/file-content-BX3OYiQC.js +0 -5
  407. package/renderer/assets/geist-mono-cyrillic-ext-wght-normal-I4S5GZfc.woff2 +0 -0
  408. package/renderer/assets/geist-mono-cyrillic-wght-normal-BmXc_FBt.woff2 +0 -0
  409. package/renderer/assets/geist-mono-latin-ext-wght-normal-DrnZ1wKl.woff2 +0 -0
  410. package/renderer/assets/geist-mono-latin-wght-normal-B_7UjwxQ.woff2 +0 -0
  411. package/renderer/assets/geist-mono-symbols2-wght-normal-GZpp1pK2.woff2 +0 -0
  412. package/renderer/assets/geist-mono-vietnamese-wght-normal-D8KDMBhC.woff2 +0 -0
  413. package/renderer/assets/ghostty-vt-DdA0Zryv.wasm +0 -0
  414. package/renderer/assets/ghostty-write-pty-CVPirtOQ.wasm +0 -0
  415. package/renderer/assets/html-view-BPOrX4do.js +0 -30
  416. package/renderer/assets/hunks-view-CXQMQon9.js +0 -1
  417. package/renderer/assets/index-CS0Dcjbz.css +0 -1
  418. package/renderer/assets/index-CuWbxCsX.js +0 -282
  419. package/renderer/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
  420. package/renderer/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
  421. package/renderer/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  422. package/renderer/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  423. package/renderer/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
  424. package/renderer/assets/line-selection-CDQurM1g.js +0 -3
  425. package/renderer/assets/logo-CUD_B5qJ.png +0 -0
  426. package/renderer/assets/search-view-BDExg3Xl.js +0 -1
  427. package/renderer/assets/surface-BsSU1Fob.js +0 -2
  428. package/renderer/assets/unfold-vertical-CIpACs4g.js +0 -1
  429. package/renderer/assets/virtual-rows-CsZNdhfp.js +0 -1
  430. package/renderer/favicon-16.png +0 -0
  431. package/renderer/favicon-32.png +0 -0
  432. package/renderer/icon-192.png +0 -0
  433. package/renderer/icon-512.png +0 -0
  434. package/renderer/index.html +0 -41
  435. package/renderer/manifest.webmanifest +0 -16
  436. /package/{renderer → web/dist}/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  437. /package/{renderer → web/dist}/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  438. /package/{renderer → web/dist}/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  439. /package/{renderer → web/dist}/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  440. /package/{renderer → web/dist}/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
@@ -0,0 +1,25 @@
1
+ -- Comment messages written before authorship was introduced have no `author`.
2
+ -- Drizzle runs this migration in one transaction. Only the missing field is
3
+ -- added: existing author values, timestamps, anchors and message order remain
4
+ -- untouched, and no timestamp is fabricated for legacy data.
5
+ UPDATE comment_threads
6
+ SET data = json_set(
7
+ data,
8
+ '$.messages',
9
+ (
10
+ SELECT json_group_array(
11
+ CASE
12
+ WHEN json_type(value, '$.author') IS NULL
13
+ THEN json_set(value, '$.author', 'reviewer')
14
+ ELSE value
15
+ END
16
+ ORDER BY CAST(key AS INTEGER)
17
+ )
18
+ FROM json_each(data, '$.messages')
19
+ )
20
+ )
21
+ WHERE EXISTS (
22
+ SELECT 1
23
+ FROM json_each(data, '$.messages')
24
+ WHERE json_type(value, '$.author') IS NULL
25
+ );
@@ -0,0 +1,23 @@
1
+ CREATE TABLE `devices` (
2
+ `id` text PRIMARY KEY NOT NULL,
3
+ `label` text NOT NULL,
4
+ `platform` text NOT NULL,
5
+ `secret_hash` text NOT NULL,
6
+ `created_at` text NOT NULL,
7
+ `last_seen_at` text NOT NULL,
8
+ `last_seen_address` text,
9
+ `revoked_at` text
10
+ );
11
+ --> statement-breakpoint
12
+ CREATE TABLE `pairing_grants` (
13
+ `id` text PRIMARY KEY NOT NULL,
14
+ `label` text NOT NULL,
15
+ `secret_hash` text NOT NULL,
16
+ `addresses` text DEFAULT '[]' NOT NULL,
17
+ `created_at` text NOT NULL,
18
+ `expires_at` text NOT NULL,
19
+ `redeemed_at` text,
20
+ `revoked_at` text
21
+ );
22
+ --> statement-breakpoint
23
+ CREATE INDEX `pairing_grants_expires` ON `pairing_grants` (`expires_at`);
@@ -0,0 +1,146 @@
1
+ -- Worktrees stop being stored: Git lists them and their ids are derived from
2
+ -- the project and the filesystem identity of the administrative Git directory.
3
+ --
4
+ -- Everything here runs in the one transaction Drizzle wraps this file in, so a
5
+ -- crash leaves the old ids intact rather than a half-rewritten database. The
6
+ -- derivation is registered on the connection as `porcelain_worktree_id` before
7
+ -- migrations run; it is the same function the server uses at runtime.
8
+ --
9
+ -- Rows whose old id cannot be mapped keep it. That happens when the worktree
10
+ -- had no recorded identity (it was unavailable at the last refresh) or had
11
+ -- already left the active table, and there is nothing to derive from. They are
12
+ -- not matched by path: a worktree deleted and recreated at the same path is a
13
+ -- different worktree, which is the whole reason ids are derived. They keep
14
+ -- their data. Where the project they belonged to can still be determined they
15
+ -- are seeded into worktree_presence and follow the same observed-absence rule
16
+ -- as everything else; where it cannot, they have no presence row, so nothing
17
+ -- collects them and nothing deletes them with a project. In practice
18
+ -- project_worktrees held a row for every worktree ever listed, so that set
19
+ -- should be empty.
20
+ CREATE TABLE `worktree_presence` (
21
+ `worktree_id` text PRIMARY KEY NOT NULL,
22
+ `project_id` text NOT NULL,
23
+ `missing_since` text,
24
+ FOREIGN KEY (`project_id`) REFERENCES `inventory_projects`(`id`) ON UPDATE no action ON DELETE cascade
25
+ );
26
+ --> statement-breakpoint
27
+ CREATE INDEX `worktree_presence_project` ON `worktree_presence` (`project_id`);
28
+ --> statement-breakpoint
29
+ -- The mapping, computed once from data already stored. No filesystem access.
30
+ CREATE TEMPORARY TABLE `worktree_id_migration` AS
31
+ SELECT
32
+ `id` AS `old_id`,
33
+ `project_id`,
34
+ porcelain_worktree_id(`project_id`, `metadata_identity`) AS `new_id`
35
+ FROM `worktrees`
36
+ WHERE `metadata_identity` IS NOT NULL;
37
+ --> statement-breakpoint
38
+ UPDATE `reviewed_files`
39
+ SET `worktree_id` = (
40
+ SELECT `new_id` FROM `worktree_id_migration` WHERE `old_id` = `reviewed_files`.`worktree_id`
41
+ )
42
+ WHERE `worktree_id` IN (SELECT `old_id` FROM `worktree_id_migration`);
43
+ --> statement-breakpoint
44
+ UPDATE `artifacts`
45
+ SET `worktree_id` = (
46
+ SELECT `new_id` FROM `worktree_id_migration` WHERE `old_id` = `artifacts`.`worktree_id`
47
+ )
48
+ WHERE `worktree_id` IN (SELECT `old_id` FROM `worktree_id_migration`);
49
+ --> statement-breakpoint
50
+ UPDATE `review_layer_sets`
51
+ SET `worktree_id` = (
52
+ SELECT `new_id` FROM `worktree_id_migration` WHERE `old_id` = `review_layer_sets`.`worktree_id`
53
+ )
54
+ WHERE `worktree_id` IN (SELECT `old_id` FROM `worktree_id_migration`);
55
+ --> statement-breakpoint
56
+ -- A comment thread carries its worktree twice: the column it is looked up by
57
+ -- and the id inside the stored thread that is returned to the client.
58
+ UPDATE `comment_threads`
59
+ SET
60
+ `worktree_id` = (
61
+ SELECT `new_id` FROM `worktree_id_migration` WHERE `old_id` = `comment_threads`.`worktree_id`
62
+ ),
63
+ `data` = json_set(
64
+ `data`,
65
+ '$.worktreeId',
66
+ (SELECT `new_id` FROM `worktree_id_migration` WHERE `old_id` = `comment_threads`.`worktree_id`)
67
+ )
68
+ WHERE `worktree_id` IN (SELECT `old_id` FROM `worktree_id_migration`);
69
+ --> statement-breakpoint
70
+ -- Archived layers have no worktree column at all: the source worktree is only
71
+ -- inside the payload, so leaving it would return an id nothing resolves.
72
+ UPDATE `commit_review_layer_sets`
73
+ SET `data` = json_set(
74
+ `data`,
75
+ '$.sourceWorktreeId',
76
+ (
77
+ SELECT `new_id` FROM `worktree_id_migration`
78
+ WHERE `old_id` = json_extract(`commit_review_layer_sets`.`data`, '$.sourceWorktreeId')
79
+ )
80
+ )
81
+ WHERE json_extract(`data`, '$.sourceWorktreeId') IN (SELECT `old_id` FROM `worktree_id_migration`);
82
+ --> statement-breakpoint
83
+ -- An unexpired preparation and a recovered receipt both name their worktree in
84
+ -- a durable value; an upgrade must not strand a Git action in flight.
85
+ UPDATE `git_action_preparations`
86
+ SET `value` = json_set(
87
+ `value`,
88
+ '$.worktreeId',
89
+ (
90
+ SELECT `new_id` FROM `worktree_id_migration`
91
+ WHERE `old_id` = json_extract(`git_action_preparations`.`value`, '$.worktreeId')
92
+ )
93
+ )
94
+ WHERE json_extract(`value`, '$.worktreeId') IN (SELECT `old_id` FROM `worktree_id_migration`);
95
+ --> statement-breakpoint
96
+ UPDATE `git_action_receipts`
97
+ SET `value` = json_set(
98
+ `value`,
99
+ '$.worktreeId',
100
+ (
101
+ SELECT `new_id` FROM `worktree_id_migration`
102
+ WHERE `old_id` = json_extract(`git_action_receipts`.`value`, '$.worktreeId')
103
+ )
104
+ )
105
+ WHERE json_extract(`value`, '$.worktreeId') IN (SELECT `old_id` FROM `worktree_id_migration`);
106
+ --> statement-breakpoint
107
+ -- Presence rows for everything that now has review data, mapped or not. A
108
+ -- worktree present in Git clears `missing_since` on the first listing; one
109
+ -- that is gone has it set by the first listing that succeeds without it.
110
+ INSERT OR IGNORE INTO `worktree_presence` (`worktree_id`, `project_id`, `missing_since`)
111
+ SELECT `worktree_id`, `project_id`, NULL FROM (
112
+ SELECT `worktree_id`, (
113
+ SELECT `project_id` FROM `worktree_id_migration` WHERE `new_id` = `reviewed_files`.`worktree_id`
114
+ UNION ALL
115
+ SELECT `project_id` FROM `project_worktrees` WHERE `worktree_id` = `reviewed_files`.`worktree_id`
116
+ LIMIT 1
117
+ ) AS `project_id` FROM `reviewed_files`
118
+ UNION
119
+ SELECT `worktree_id`, (
120
+ SELECT `project_id` FROM `worktree_id_migration` WHERE `new_id` = `artifacts`.`worktree_id`
121
+ UNION ALL
122
+ SELECT `project_id` FROM `project_worktrees` WHERE `worktree_id` = `artifacts`.`worktree_id`
123
+ LIMIT 1
124
+ ) AS `project_id` FROM `artifacts`
125
+ UNION
126
+ SELECT `worktree_id`, (
127
+ SELECT `project_id` FROM `worktree_id_migration` WHERE `new_id` = `review_layer_sets`.`worktree_id`
128
+ UNION ALL
129
+ SELECT `project_id` FROM `project_worktrees` WHERE `worktree_id` = `review_layer_sets`.`worktree_id`
130
+ LIMIT 1
131
+ ) AS `project_id` FROM `review_layer_sets`
132
+ UNION
133
+ SELECT `worktree_id`, (
134
+ SELECT `project_id` FROM `worktree_id_migration` WHERE `new_id` = `comment_threads`.`worktree_id`
135
+ UNION ALL
136
+ SELECT `project_id` FROM `project_worktrees` WHERE `worktree_id` = `comment_threads`.`worktree_id`
137
+ LIMIT 1
138
+ ) AS `project_id` FROM `comment_threads`
139
+ )
140
+ WHERE `project_id` IS NOT NULL;
141
+ --> statement-breakpoint
142
+ DROP TABLE `worktree_id_migration`;
143
+ --> statement-breakpoint
144
+ DROP TABLE `project_worktrees`;
145
+ --> statement-breakpoint
146
+ DROP TABLE `worktrees`;
@@ -0,0 +1,31 @@
1
+ -- Project names come from `origin`, and each worktree can show a status dot.
2
+ --
3
+ -- Three changes, one transaction:
4
+ --
5
+ -- * `named_by_owner` records who chose a project's name. Every existing name
6
+ -- was derived from a folder, so they all start as not owner-chosen and the
7
+ -- next registration replaces them with the repository's own name.
8
+ -- * `comment_threads` gains a monotonic `revision`, seeded from the sequence
9
+ -- it already had, and `last_agent_revision`, which is that revision when
10
+ -- the last message is the agent's. That is what the yellow dot asks about.
11
+ -- * `comment_reads` records how far the owner has actually seen. It is only
12
+ -- ever advanced by an explicit act, never by a background list.
13
+ ALTER TABLE `inventory_projects` ADD `named_by_owner` integer DEFAULT 0 NOT NULL;
14
+ --> statement-breakpoint
15
+ ALTER TABLE `comment_threads` ADD `revision` integer DEFAULT 0 NOT NULL;
16
+ --> statement-breakpoint
17
+ ALTER TABLE `comment_threads` ADD `last_agent_revision` integer;
18
+ --> statement-breakpoint
19
+ UPDATE `comment_threads` SET `revision` = `sequence`;
20
+ --> statement-breakpoint
21
+ UPDATE `comment_threads`
22
+ SET `last_agent_revision` = `revision`
23
+ WHERE json_extract(
24
+ `data`,
25
+ '$.messages[' || (json_array_length(`data`, '$.messages') - 1) || '].author'
26
+ ) = 'agent';
27
+ --> statement-breakpoint
28
+ CREATE TABLE `comment_reads` (
29
+ `worktree_id` text PRIMARY KEY NOT NULL,
30
+ `seen_through` integer NOT NULL
31
+ );
@@ -0,0 +1 @@
1
+ ALTER TABLE `reviewed_files` ADD `stale` integer DEFAULT 0 NOT NULL;
@@ -0,0 +1,66 @@
1
+ ALTER TABLE `comment_threads` RENAME TO `comment_threads_legacy`;
2
+ --> statement-breakpoint
3
+ CREATE TABLE `comment_threads` (
4
+ `sequence` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
5
+ `id` text NOT NULL,
6
+ `worktree_id` text NOT NULL,
7
+ `anchor` text NOT NULL,
8
+ `resolved` integer NOT NULL,
9
+ `revision` integer NOT NULL,
10
+ `last_agent_revision` integer,
11
+ `size_bytes` integer NOT NULL
12
+ );
13
+ --> statement-breakpoint
14
+ CREATE UNIQUE INDEX `comment_threads_normalized_id_unique` ON `comment_threads` (`id`);
15
+ --> statement-breakpoint
16
+ CREATE INDEX `comment_threads_worktree` ON `comment_threads` (`worktree_id`);
17
+ --> statement-breakpoint
18
+ CREATE TABLE `comment_messages` (
19
+ `sequence` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
20
+ `id` text NOT NULL,
21
+ `thread_id` text NOT NULL,
22
+ `worktree_id` text NOT NULL,
23
+ `body` text NOT NULL,
24
+ `author` text NOT NULL,
25
+ `created_at` text,
26
+ FOREIGN KEY (`thread_id`) REFERENCES `comment_threads`(`id`) ON UPDATE no action ON DELETE cascade
27
+ );
28
+ --> statement-breakpoint
29
+ INSERT INTO `comment_threads` (
30
+ `sequence`, `id`, `worktree_id`, `anchor`, `resolved`, `revision`,
31
+ `last_agent_revision`, `size_bytes`
32
+ )
33
+ SELECT
34
+ `sequence`,
35
+ `id`,
36
+ `worktree_id`,
37
+ json_extract(`data`, '$.anchor'),
38
+ CASE json_extract(`data`, '$.resolved') WHEN 1 THEN 1 ELSE 0 END,
39
+ `revision`,
40
+ `last_agent_revision`,
41
+ length(cast(`data` AS blob)) +
42
+ CASE json_extract(`data`, '$.resolved') WHEN 1 THEN 1 ELSE 0 END
43
+ FROM `comment_threads_legacy`
44
+ ORDER BY `sequence`;
45
+ --> statement-breakpoint
46
+ INSERT INTO `comment_messages` (
47
+ `id`, `thread_id`, `worktree_id`, `body`, `author`, `created_at`
48
+ )
49
+ SELECT
50
+ json_extract(message.value, '$.id'),
51
+ thread.`id`,
52
+ thread.`worktree_id`,
53
+ json_extract(message.value, '$.body'),
54
+ coalesce(json_extract(message.value, '$.author'), 'reviewer'),
55
+ json_extract(message.value, '$.createdAt')
56
+ FROM `comment_threads_legacy` AS thread,
57
+ json_each(thread.`data`, '$.messages') AS message
58
+ ORDER BY thread.`sequence`, cast(message.key AS integer);
59
+ --> statement-breakpoint
60
+ DROP TABLE `comment_threads_legacy`;
61
+ --> statement-breakpoint
62
+ CREATE INDEX `comment_messages_id` ON `comment_messages` (`id`);
63
+ --> statement-breakpoint
64
+ CREATE INDEX `comment_messages_thread` ON `comment_messages` (`thread_id`,`sequence`);
65
+ --> statement-breakpoint
66
+ CREATE INDEX `comment_messages_worktree` ON `comment_messages` (`worktree_id`);
@@ -0,0 +1,30 @@
1
+ CREATE TABLE `reviews` (
2
+ `worktree_id` text PRIMARY KEY NOT NULL,
3
+ `revision` integer NOT NULL,
4
+ `published_at` text NOT NULL,
5
+ `active` integer DEFAULT true NOT NULL,
6
+ `summary_html` text NOT NULL,
7
+ `summary_token` text NOT NULL,
8
+ `summary_secret` text NOT NULL,
9
+ `diagram` text,
10
+ `layers` text NOT NULL
11
+ );
12
+ --> statement-breakpoint
13
+ CREATE UNIQUE INDEX `reviews_summary_token_unique` ON `reviews` (`summary_token`);
14
+ --> statement-breakpoint
15
+ CREATE TABLE `reviewed_layers` (
16
+ `worktree_id` text NOT NULL,
17
+ `layer_id` text NOT NULL,
18
+ `fingerprint` text NOT NULL,
19
+ `reviewed_at` text NOT NULL,
20
+ `stale` integer DEFAULT false NOT NULL,
21
+ PRIMARY KEY(`worktree_id`, `layer_id`)
22
+ );
23
+ --> statement-breakpoint
24
+ CREATE INDEX `reviewed_layers_worktree` ON `reviewed_layers` (`worktree_id`);
25
+ --> statement-breakpoint
26
+ DROP TABLE `artifacts`;
27
+ --> statement-breakpoint
28
+ DROP TABLE `review_layer_sets`;
29
+ --> statement-breakpoint
30
+ DROP TABLE `commit_review_layer_sets`;
@@ -0,0 +1,5 @@
1
+ -- Git actions keep only their receipts; nothing reads or writes blocks or
2
+ -- preparations any more.
3
+ DROP TABLE `git_action_blocks`;
4
+ --> statement-breakpoint
5
+ DROP TABLE `git_action_preparations`;
@@ -0,0 +1,207 @@
1
+ -- Deleting a project or collecting an absent worktree becomes one DELETE: every
2
+ -- row that belongs to a project or a worktree names its parent with a foreign
3
+ -- key that cascades.
4
+ --
5
+ -- * inventory_projects owns worktree_presence, project_file_preferences and
6
+ -- git_action_receipts. Receipts gain a `project_id` column copied from the
7
+ -- stored receipt, because a foreign key needs a column.
8
+ -- * worktree_presence owns everything keyed by worktree: reviews, reviewed
9
+ -- files and layers, comment threads, comment messages and comment reads. It
10
+ -- is the only table that knows which project a worktree belongs to, so a
11
+ -- project removal reaches review data through it.
12
+ --
13
+ -- SQLite cannot add a foreign key to an existing table, so each child is
14
+ -- rebuilt. Migrations run with foreign key enforcement off and a
15
+ -- foreign_key_check before commit, so dropping a parent here cascades nothing.
16
+ -- Rows whose parent no longer exists are deleted: nothing could reach them and
17
+ -- nothing would ever remove them.
18
+ --
19
+ -- inventory_projects is rebuilt too, so its `named_by_owner` column matches the
20
+ -- schema: no default, and the same 0/1 check as the other flags.
21
+ CREATE TABLE `__new_inventory_projects` (
22
+ `id` text PRIMARY KEY NOT NULL,
23
+ `name` text NOT NULL,
24
+ `named_by_owner` integer NOT NULL,
25
+ `common_directory` text NOT NULL,
26
+ `repository_identity` text NOT NULL,
27
+ `available` integer NOT NULL,
28
+ `position` integer NOT NULL,
29
+ CONSTRAINT "project_id_present" CHECK("__new_inventory_projects"."id" IS NOT NULL),
30
+ CONSTRAINT "project_available" CHECK("__new_inventory_projects"."available" IN (0, 1)),
31
+ CONSTRAINT "project_named_by_owner" CHECK("__new_inventory_projects"."named_by_owner" IN (0, 1))
32
+ );
33
+ --> statement-breakpoint
34
+ INSERT INTO `__new_inventory_projects` ("id", "name", "named_by_owner", "common_directory", "repository_identity", "available", "position")
35
+ SELECT "id", "name", "named_by_owner", "common_directory", "repository_identity", "available", "position" FROM `inventory_projects`;
36
+ --> statement-breakpoint
37
+ DROP TABLE `inventory_projects`;
38
+ --> statement-breakpoint
39
+ ALTER TABLE `__new_inventory_projects` RENAME TO `inventory_projects`;
40
+ --> statement-breakpoint
41
+ CREATE UNIQUE INDEX `inventory_projects_repository_identity_unique` ON `inventory_projects` (`repository_identity`);
42
+ --> statement-breakpoint
43
+ DELETE FROM `worktree_presence` WHERE `project_id` NOT IN (SELECT `id` FROM `inventory_projects`);
44
+ --> statement-breakpoint
45
+ CREATE TABLE `__new_project_file_preferences` (
46
+ `project_id` text NOT NULL,
47
+ `path` text NOT NULL,
48
+ `pinned` integer NOT NULL,
49
+ `hidden` integer NOT NULL,
50
+ PRIMARY KEY(`project_id`, `path`),
51
+ FOREIGN KEY (`project_id`) REFERENCES `inventory_projects`(`id`) ON UPDATE no action ON DELETE cascade,
52
+ CONSTRAINT "project_preference_pinned" CHECK("__new_project_file_preferences"."pinned" IN (0, 1)),
53
+ CONSTRAINT "project_preference_hidden" CHECK("__new_project_file_preferences"."hidden" IN (0, 1))
54
+ );
55
+ --> statement-breakpoint
56
+ INSERT INTO `__new_project_file_preferences` ("project_id", "path", "pinned", "hidden")
57
+ SELECT "project_id", "path", "pinned", "hidden" FROM `project_file_preferences`
58
+ WHERE `project_id` IN (SELECT `id` FROM `inventory_projects`);
59
+ --> statement-breakpoint
60
+ DROP TABLE `project_file_preferences`;
61
+ --> statement-breakpoint
62
+ ALTER TABLE `__new_project_file_preferences` RENAME TO `project_file_preferences`;
63
+ --> statement-breakpoint
64
+ CREATE TABLE `__new_git_action_receipts` (
65
+ `request_id` text PRIMARY KEY NOT NULL,
66
+ `project_id` text NOT NULL,
67
+ `value` text NOT NULL,
68
+ FOREIGN KEY (`project_id`) REFERENCES `inventory_projects`(`id`) ON UPDATE no action ON DELETE cascade
69
+ );
70
+ --> statement-breakpoint
71
+ INSERT INTO `__new_git_action_receipts` ("request_id", "project_id", "value")
72
+ SELECT "request_id", json_extract("value", '$.projectId'), "value" FROM `git_action_receipts`
73
+ WHERE json_extract("value", '$.projectId') IN (SELECT `id` FROM `inventory_projects`);
74
+ --> statement-breakpoint
75
+ DROP TABLE `git_action_receipts`;
76
+ --> statement-breakpoint
77
+ ALTER TABLE `__new_git_action_receipts` RENAME TO `git_action_receipts`;
78
+ --> statement-breakpoint
79
+ CREATE INDEX `git_action_receipts_project` ON `git_action_receipts` (`project_id`);
80
+ --> statement-breakpoint
81
+ CREATE TABLE `__new_reviews` (
82
+ `worktree_id` text PRIMARY KEY NOT NULL,
83
+ `revision` integer NOT NULL,
84
+ `published_at` text NOT NULL,
85
+ `active` integer DEFAULT true NOT NULL,
86
+ `summary_html` text NOT NULL,
87
+ `summary_token` text NOT NULL,
88
+ `summary_secret` text NOT NULL,
89
+ `diagram` text,
90
+ `layers` text NOT NULL,
91
+ FOREIGN KEY (`worktree_id`) REFERENCES `worktree_presence`(`worktree_id`) ON UPDATE no action ON DELETE cascade
92
+ );
93
+ --> statement-breakpoint
94
+ INSERT INTO `__new_reviews` ("worktree_id", "revision", "published_at", "active", "summary_html", "summary_token", "summary_secret", "diagram", "layers")
95
+ SELECT "worktree_id", "revision", "published_at", "active", "summary_html", "summary_token", "summary_secret", "diagram", "layers" FROM `reviews`
96
+ WHERE `worktree_id` IN (SELECT `worktree_id` FROM `worktree_presence`);
97
+ --> statement-breakpoint
98
+ DROP TABLE `reviews`;
99
+ --> statement-breakpoint
100
+ ALTER TABLE `__new_reviews` RENAME TO `reviews`;
101
+ --> statement-breakpoint
102
+ CREATE UNIQUE INDEX `reviews_summary_token_unique` ON `reviews` (`summary_token`);
103
+ --> statement-breakpoint
104
+ CREATE TABLE `__new_reviewed_files` (
105
+ `worktree_id` text NOT NULL,
106
+ `path` text NOT NULL,
107
+ `fingerprint` text NOT NULL,
108
+ `reviewed_at` text NOT NULL,
109
+ `stale` integer DEFAULT false NOT NULL,
110
+ PRIMARY KEY(`worktree_id`, `path`),
111
+ FOREIGN KEY (`worktree_id`) REFERENCES `worktree_presence`(`worktree_id`) ON UPDATE no action ON DELETE cascade
112
+ );
113
+ --> statement-breakpoint
114
+ INSERT INTO `__new_reviewed_files` ("worktree_id", "path", "fingerprint", "reviewed_at", "stale")
115
+ SELECT "worktree_id", "path", "fingerprint", "reviewed_at", "stale" FROM `reviewed_files`
116
+ WHERE `worktree_id` IN (SELECT `worktree_id` FROM `worktree_presence`);
117
+ --> statement-breakpoint
118
+ DROP TABLE `reviewed_files`;
119
+ --> statement-breakpoint
120
+ ALTER TABLE `__new_reviewed_files` RENAME TO `reviewed_files`;
121
+ --> statement-breakpoint
122
+ CREATE INDEX `reviewed_files_worktree` ON `reviewed_files` (`worktree_id`);
123
+ --> statement-breakpoint
124
+ CREATE TABLE `__new_reviewed_layers` (
125
+ `worktree_id` text NOT NULL,
126
+ `layer_id` text NOT NULL,
127
+ `fingerprint` text NOT NULL,
128
+ `reviewed_at` text NOT NULL,
129
+ `stale` integer DEFAULT false NOT NULL,
130
+ PRIMARY KEY(`worktree_id`, `layer_id`),
131
+ FOREIGN KEY (`worktree_id`) REFERENCES `worktree_presence`(`worktree_id`) ON UPDATE no action ON DELETE cascade
132
+ );
133
+ --> statement-breakpoint
134
+ INSERT INTO `__new_reviewed_layers` ("worktree_id", "layer_id", "fingerprint", "reviewed_at", "stale")
135
+ SELECT "worktree_id", "layer_id", "fingerprint", "reviewed_at", "stale" FROM `reviewed_layers`
136
+ WHERE `worktree_id` IN (SELECT `worktree_id` FROM `worktree_presence`);
137
+ --> statement-breakpoint
138
+ DROP TABLE `reviewed_layers`;
139
+ --> statement-breakpoint
140
+ ALTER TABLE `__new_reviewed_layers` RENAME TO `reviewed_layers`;
141
+ --> statement-breakpoint
142
+ CREATE INDEX `reviewed_layers_worktree` ON `reviewed_layers` (`worktree_id`);
143
+ --> statement-breakpoint
144
+ CREATE TABLE `__new_comment_threads` (
145
+ `sequence` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
146
+ `id` text NOT NULL,
147
+ `worktree_id` text NOT NULL,
148
+ `anchor` text NOT NULL,
149
+ `resolved` integer NOT NULL,
150
+ `revision` integer NOT NULL,
151
+ `last_agent_revision` integer,
152
+ `size_bytes` integer NOT NULL,
153
+ FOREIGN KEY (`worktree_id`) REFERENCES `worktree_presence`(`worktree_id`) ON UPDATE no action ON DELETE cascade
154
+ );
155
+ --> statement-breakpoint
156
+ INSERT INTO `__new_comment_threads` ("sequence", "id", "worktree_id", "anchor", "resolved", "revision", "last_agent_revision", "size_bytes")
157
+ SELECT "sequence", "id", "worktree_id", "anchor", "resolved", "revision", "last_agent_revision", "size_bytes" FROM `comment_threads`
158
+ WHERE `worktree_id` IN (SELECT `worktree_id` FROM `worktree_presence`);
159
+ --> statement-breakpoint
160
+ DROP TABLE `comment_threads`;
161
+ --> statement-breakpoint
162
+ ALTER TABLE `__new_comment_threads` RENAME TO `comment_threads`;
163
+ --> statement-breakpoint
164
+ CREATE UNIQUE INDEX `comment_threads_normalized_id_unique` ON `comment_threads` (`id`);
165
+ --> statement-breakpoint
166
+ CREATE INDEX `comment_threads_worktree` ON `comment_threads` (`worktree_id`);
167
+ --> statement-breakpoint
168
+ CREATE TABLE `__new_comment_messages` (
169
+ `sequence` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
170
+ `id` text NOT NULL,
171
+ `thread_id` text NOT NULL,
172
+ `worktree_id` text NOT NULL,
173
+ `body` text NOT NULL,
174
+ `author` text NOT NULL,
175
+ `created_at` text,
176
+ FOREIGN KEY (`thread_id`) REFERENCES `comment_threads`(`id`) ON UPDATE no action ON DELETE cascade,
177
+ FOREIGN KEY (`worktree_id`) REFERENCES `worktree_presence`(`worktree_id`) ON UPDATE no action ON DELETE cascade
178
+ );
179
+ --> statement-breakpoint
180
+ INSERT INTO `__new_comment_messages` ("sequence", "id", "thread_id", "worktree_id", "body", "author", "created_at")
181
+ SELECT "sequence", "id", "thread_id", "worktree_id", "body", "author", "created_at" FROM `comment_messages`
182
+ WHERE `thread_id` IN (SELECT `id` FROM `comment_threads`)
183
+ AND `worktree_id` IN (SELECT `worktree_id` FROM `worktree_presence`);
184
+ --> statement-breakpoint
185
+ DROP TABLE `comment_messages`;
186
+ --> statement-breakpoint
187
+ ALTER TABLE `__new_comment_messages` RENAME TO `comment_messages`;
188
+ --> statement-breakpoint
189
+ CREATE INDEX `comment_messages_id` ON `comment_messages` (`id`);
190
+ --> statement-breakpoint
191
+ CREATE INDEX `comment_messages_thread` ON `comment_messages` (`thread_id`,`sequence`);
192
+ --> statement-breakpoint
193
+ CREATE INDEX `comment_messages_worktree` ON `comment_messages` (`worktree_id`);
194
+ --> statement-breakpoint
195
+ CREATE TABLE `__new_comment_reads` (
196
+ `worktree_id` text PRIMARY KEY NOT NULL,
197
+ `seen_through` integer NOT NULL,
198
+ FOREIGN KEY (`worktree_id`) REFERENCES `worktree_presence`(`worktree_id`) ON UPDATE no action ON DELETE cascade
199
+ );
200
+ --> statement-breakpoint
201
+ INSERT INTO `__new_comment_reads` ("worktree_id", "seen_through")
202
+ SELECT "worktree_id", "seen_through" FROM `comment_reads`
203
+ WHERE `worktree_id` IN (SELECT `worktree_id` FROM `worktree_presence`);
204
+ --> statement-breakpoint
205
+ DROP TABLE `comment_reads`;
206
+ --> statement-breakpoint
207
+ ALTER TABLE `__new_comment_reads` RENAME TO `comment_reads`;
@@ -0,0 +1,35 @@
1
+ -- A Git action receipt belongs to its worktree: collecting the worktree
2
+ -- removes it through a foreign key, as it already does for review data.
3
+ --
4
+ -- The worktree id was only inside the stored receipt, so it is copied into a
5
+ -- column. A receipt whose worktree has no presence row yet is not dropped:
6
+ -- its worktree is seeded into worktree_presence under the receipt's project
7
+ -- and follows the same observed-absence rule as every other worktree.
8
+ -- SQLite cannot add a foreign key to an existing table, so the table is
9
+ -- rebuilt, with foreign key enforcement off and a foreign_key_check before
10
+ -- commit as for every migration.
11
+ INSERT OR IGNORE INTO `worktree_presence` (`worktree_id`, `project_id`, `missing_since`)
12
+ SELECT DISTINCT json_extract(`value`, '$.worktreeId'), `project_id`, NULL
13
+ FROM `git_action_receipts`
14
+ WHERE json_type(`value`, '$.worktreeId') = 'text';
15
+ --> statement-breakpoint
16
+ CREATE TABLE `__new_git_action_receipts` (
17
+ `request_id` text PRIMARY KEY NOT NULL,
18
+ `project_id` text NOT NULL,
19
+ `worktree_id` text NOT NULL,
20
+ `value` text NOT NULL,
21
+ FOREIGN KEY (`project_id`) REFERENCES `inventory_projects`(`id`) ON UPDATE no action ON DELETE cascade,
22
+ FOREIGN KEY (`worktree_id`) REFERENCES `worktree_presence`(`worktree_id`) ON UPDATE no action ON DELETE cascade
23
+ );
24
+ --> statement-breakpoint
25
+ INSERT INTO `__new_git_action_receipts` ("request_id", "project_id", "worktree_id", "value")
26
+ SELECT "request_id", "project_id", json_extract("value", '$.worktreeId'), "value" FROM `git_action_receipts`
27
+ WHERE json_type("value", '$.worktreeId') = 'text';
28
+ --> statement-breakpoint
29
+ DROP TABLE `git_action_receipts`;
30
+ --> statement-breakpoint
31
+ ALTER TABLE `__new_git_action_receipts` RENAME TO `git_action_receipts`;
32
+ --> statement-breakpoint
33
+ CREATE INDEX `git_action_receipts_project` ON `git_action_receipts` (`project_id`);
34
+ --> statement-breakpoint
35
+ CREATE INDEX `git_action_receipts_worktree` ON `git_action_receipts` (`worktree_id`);
@@ -0,0 +1,68 @@
1
+ -- A Git action receipt is stored in columns, like every other table: the
2
+ -- fields the store filters and orders by (state, finished_at, dismissed_at)
3
+ -- are queried directly instead of through json_extract, and project_id and
4
+ -- worktree_id are no longer stored twice. Only the nested values stay JSON:
5
+ -- the intent, the expectation, the result and the progress lines.
6
+ --
7
+ -- Every receipt is copied from its stored value. A receipt written before a
8
+ -- field existed takes the value the current code would have read: an action
9
+ -- from its intent, an empty expectation, no progress, and a refresh required,
10
+ -- which is the cautious answer when the outcome is unknown. A value without a
11
+ -- state, an intent or an acceptance time is no receipt at all and is dropped.
12
+ -- SQLite cannot change a column list in place, so the table is rebuilt, with
13
+ -- foreign key enforcement off and a foreign_key_check before commit as for
14
+ -- every migration.
15
+ CREATE TABLE `__new_git_action_receipts` (
16
+ `request_id` text PRIMARY KEY NOT NULL,
17
+ `project_id` text NOT NULL,
18
+ `worktree_id` text NOT NULL,
19
+ `action` text NOT NULL,
20
+ `state` text NOT NULL,
21
+ `reason` text,
22
+ `message` text,
23
+ `refresh_required` integer NOT NULL,
24
+ `accepted_at` text NOT NULL,
25
+ `finished_at` text,
26
+ `dismissed_at` text,
27
+ `intent` text NOT NULL,
28
+ `expected` text NOT NULL,
29
+ `result` text,
30
+ `progress` text NOT NULL,
31
+ FOREIGN KEY (`project_id`) REFERENCES `inventory_projects`(`id`) ON UPDATE no action ON DELETE cascade,
32
+ FOREIGN KEY (`worktree_id`) REFERENCES `worktree_presence`(`worktree_id`) ON UPDATE no action ON DELETE cascade
33
+ );
34
+ --> statement-breakpoint
35
+ INSERT INTO `__new_git_action_receipts` (
36
+ "request_id", "project_id", "worktree_id", "action", "state", "reason",
37
+ "message", "refresh_required", "accepted_at", "finished_at", "dismissed_at",
38
+ "intent", "expected", "result", "progress"
39
+ )
40
+ SELECT
41
+ "request_id",
42
+ "project_id",
43
+ "worktree_id",
44
+ COALESCE(json_extract("value", '$.action'), json_extract("value", '$.intent.action')),
45
+ json_extract("value", '$.state'),
46
+ json_extract("value", '$.reason'),
47
+ json_extract("value", '$.message'),
48
+ COALESCE(json_extract("value", '$.refreshRequired'), 1),
49
+ json_extract("value", '$.acceptedAt'),
50
+ json_extract("value", '$.finishedAt'),
51
+ json_extract("value", '$.dismissedAt'),
52
+ json_extract("value", '$.intent'),
53
+ COALESCE(json_extract("value", '$.expected'), '{}'),
54
+ json_extract("value", '$.result'),
55
+ COALESCE(json_extract("value", '$.progress'), '[]')
56
+ FROM `git_action_receipts`
57
+ WHERE json_type("value", '$.state') = 'text'
58
+ AND json_type("value", '$.intent') = 'object'
59
+ AND json_type("value", '$.intent.action') = 'text'
60
+ AND json_type("value", '$.acceptedAt') = 'text';
61
+ --> statement-breakpoint
62
+ DROP TABLE `git_action_receipts`;
63
+ --> statement-breakpoint
64
+ ALTER TABLE `__new_git_action_receipts` RENAME TO `git_action_receipts`;
65
+ --> statement-breakpoint
66
+ CREATE INDEX `git_action_receipts_project` ON `git_action_receipts` (`project_id`);
67
+ --> statement-breakpoint
68
+ CREATE INDEX `git_action_receipts_worktree` ON `git_action_receipts` (`worktree_id`);
@@ -0,0 +1,21 @@
1
+ -- Comment revisions are handed out from one counter that only grows. The next
2
+ -- revision used to be the highest revision still stored plus one, so deleting
3
+ -- the threads that held it, by collecting a worktree or removing a project,
4
+ -- handed the same numbers out again, and a comments-seen mark or a client that
5
+ -- had seen the old numbers took the new threads for seen.
6
+ --
7
+ -- The counter starts above every revision a thread, an agent reply or a
8
+ -- comments-seen mark still names. Numbers already reused before this migration
9
+ -- cannot be told apart and stay as they are.
10
+ CREATE TABLE `comment_revision` (
11
+ `singleton` integer PRIMARY KEY NOT NULL,
12
+ `revision` integer NOT NULL,
13
+ CONSTRAINT "comment_revision_singleton" CHECK("comment_revision"."singleton" = 1)
14
+ );
15
+ --> statement-breakpoint
16
+ INSERT INTO `comment_revision` (`singleton`, `revision`)
17
+ SELECT 1, MAX(
18
+ COALESCE((SELECT MAX(`revision`) FROM `comment_threads`), 0),
19
+ COALESCE((SELECT MAX(`last_agent_revision`) FROM `comment_threads`), 0),
20
+ COALESCE((SELECT MAX(`seen_through`) FROM `comment_reads`), 0)
21
+ );
@@ -0,0 +1 @@
1
+ ALTER TABLE `reviewed_layers` DROP COLUMN `stale`;