@peaske7/readit 0.3.0-rc.0 → 0.3.0-rc.2

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 (374) hide show
  1. package/README.md +3 -3
  2. package/dist/.vite/manifest.json +1111 -0
  3. package/dist/assets/_basePickBy-BMMA4Tou.js +1 -0
  4. package/dist/assets/_baseUniq-D40qku1I.js +1 -0
  5. package/dist/assets/arc-Ckg65iy8.js +1 -0
  6. package/dist/assets/architecture-YZFGNWBL-Dv3EY0zV.js +1 -0
  7. package/dist/assets/architectureDiagram-Q4EWVU46-DQnkwSaB.js +36 -0
  8. package/dist/assets/array-Bjz-wYpJ.js +1 -0
  9. package/dist/assets/blockDiagram-DXYQGD6D-UB6_S1lm.js +132 -0
  10. package/dist/assets/c4Diagram-AHTNJAMY-sn3k2GND.js +10 -0
  11. package/dist/assets/channel-D9wPw2fQ.js +1 -0
  12. package/dist/assets/chunk-2KRD3SAO-DaFfaCGO.js +1 -0
  13. package/dist/assets/chunk-336JU56O-C8siO5Of.js +2 -0
  14. package/dist/assets/chunk-426QAEUC-BB478m3j.js +1 -0
  15. package/dist/assets/chunk-4BX2VUAB-DRuTD7x5.js +1 -0
  16. package/dist/assets/chunk-4TB4RGXK-_l6jvVAY.js +206 -0
  17. package/dist/assets/chunk-55IACEB6-BExiaAoD.js +1 -0
  18. package/dist/assets/chunk-5FUZZQ4R-HOSFTxuG.js +62 -0
  19. package/dist/assets/chunk-5PVQY5BW-BRVNNRAX.js +2 -0
  20. package/dist/assets/chunk-67CJDMHE-DMt8LNEX.js +1 -0
  21. package/dist/assets/chunk-7N4EOEYR-CzLGefVf.js +1 -0
  22. package/dist/assets/chunk-AA7GKIK3-B6GFAk4U.js +1 -0
  23. package/dist/assets/chunk-BSJP7CBP-BK29yehL.js +1 -0
  24. package/dist/assets/chunk-CIAEETIT-D7hBXImP.js +1 -0
  25. package/dist/assets/chunk-Dlc7tRH4.js +1 -0
  26. package/dist/assets/chunk-EDXVE4YY-CSvKh9DT.js +1 -0
  27. package/dist/assets/chunk-ENJZ2VHE-QApb5cYr.js +10 -0
  28. package/dist/assets/chunk-FMBD7UC4-2FWyCCAV.js +15 -0
  29. package/dist/assets/chunk-FOC6F5B3-DKFHrt4K.js +1 -0
  30. package/dist/assets/chunk-ICPOFSXX-agBjBxsW.js +122 -0
  31. package/dist/assets/chunk-K5T4RW27-D51O7IkG.js +94 -0
  32. package/dist/assets/chunk-KGLVRYIC-DMHSCH4T.js +1 -0
  33. package/dist/assets/chunk-LIHQZDEY-C2aANxt9.js +1 -0
  34. package/dist/assets/chunk-ORNJ4GCN-Db_37NRX.js +1 -0
  35. package/dist/assets/chunk-OYMX7WX6-HGUtT2Q9.js +231 -0
  36. package/dist/assets/chunk-QZHKN3VN-8Lcg9gti.js +1 -0
  37. package/dist/assets/chunk-U2HBQHQK-BFYYQeuC.js +70 -0
  38. package/dist/assets/chunk-X2U36JSP-p8ehTP6s.js +1 -0
  39. package/dist/assets/chunk-XPW4576I-Bqbompq4.js +32 -0
  40. package/dist/assets/chunk-YZCP3GAM-HIMez9pG.js +1 -0
  41. package/dist/assets/chunk-ZZ45TVLE-DRIE_0bu.js +1 -0
  42. package/dist/assets/classDiagram-6PBFFD2Q-BawhEeUl.js +1 -0
  43. package/dist/assets/classDiagram-v2-HSJHXN6E-CLNjgH9n.js +1 -0
  44. package/dist/assets/clone-BBjvuERA.js +1 -0
  45. package/dist/assets/cose-bilkent-S5V4N54A-q90QeGKv.js +1 -0
  46. package/dist/assets/cytoscape.esm-BfXff3fb.js +321 -0
  47. package/dist/assets/dagre-Dxbob2Lr.js +1 -0
  48. package/dist/assets/dagre-KV5264BT-BuvpNxMw.js +4 -0
  49. package/dist/assets/defaultLocale-BwmRmqJp.js +1 -0
  50. package/dist/assets/diagram-5BDNPKRD-DQLsxwwt.js +10 -0
  51. package/dist/assets/diagram-G4DWMVQ6-Jv9Eefw4.js +24 -0
  52. package/dist/assets/diagram-MMDJMWI5-D-0YgNhU.js +43 -0
  53. package/dist/assets/diagram-TYMM5635-BHwO7zQG.js +24 -0
  54. package/dist/assets/dist-BNz65Ibc.js +1 -0
  55. package/dist/assets/erDiagram-SMLLAGMA-BjZGGBJz.js +85 -0
  56. package/dist/assets/flowDiagram-DWJPFMVM-CFbFUm_m.js +162 -0
  57. package/dist/assets/ganttDiagram-T4ZO3ILL-CXk4TcBi.js +292 -0
  58. package/dist/assets/gitGraph-7Q5UKJZL-BGFRt2qs.js +1 -0
  59. package/dist/assets/gitGraphDiagram-UUTBAWPF-C8yZOxjo.js +106 -0
  60. package/dist/assets/graphlib-DGcD9J2L.js +1 -0
  61. package/dist/assets/index-D-m0LiFI.js +14 -0
  62. package/dist/assets/index-DANHO6J0.css +2 -0
  63. package/dist/assets/info-OMHHGYJF-DI6-Z9vh.js +1 -0
  64. package/dist/assets/infoDiagram-42DDH7IO-p-PXDra2.js +2 -0
  65. package/dist/assets/init-TPm5RB77.js +1 -0
  66. package/dist/assets/isArrayLikeObject-69BLnVNM.js +1 -0
  67. package/dist/assets/isEmpty-DUS28g5f.js +1 -0
  68. package/dist/assets/ishikawaDiagram-UXIWVN3A-BrIoEvtb.js +70 -0
  69. package/dist/assets/journeyDiagram-VCZTEJTY-aZpvKa9g.js +139 -0
  70. package/dist/assets/kanban-definition-6JOO6SKY-CoOAY9ji.js +89 -0
  71. package/dist/assets/katex-5SGEXwpi.js +261 -0
  72. package/dist/assets/line-4MF1lR4d.js +1 -0
  73. package/dist/assets/linear-CXMqTN8N.js +1 -0
  74. package/dist/assets/mermaid-config-C8a4L22x.js +1 -0
  75. package/dist/assets/mermaid-parser.core-DREsY2u4.js +4 -0
  76. package/dist/assets/mermaid.core-8ysLpTJi.js +11 -0
  77. package/dist/assets/mindmap-definition-QFDTVHPH-CsqUJCMn.js +96 -0
  78. package/dist/assets/ordinal-D7l-8DAO.js +1 -0
  79. package/dist/assets/packet-4T2RLAQJ-DidW3JFc.js +1 -0
  80. package/dist/assets/path-BVpCanzE.js +1 -0
  81. package/dist/assets/pie-ZZUOXDRM-Bff2e5hg.js +1 -0
  82. package/dist/assets/pieDiagram-DEJITSTG-k0Br4NDS.js +30 -0
  83. package/dist/assets/quadrantDiagram-34T5L4WZ-Be9oCSza.js +7 -0
  84. package/dist/assets/radar-PYXPWWZC-CsdZBH3M.js +1 -0
  85. package/dist/assets/requirementDiagram-MS252O5E-8ECT7dEs.js +84 -0
  86. package/dist/assets/rough.esm-BoTisKeL.js +1 -0
  87. package/dist/assets/sankeyDiagram-XADWPNL6-CoKpeJJ0.js +10 -0
  88. package/dist/assets/sequenceDiagram-FGHM5R23-BTT2fFxG.js +157 -0
  89. package/dist/assets/src-CrmkjRpa.js +1 -0
  90. package/dist/assets/stateDiagram-FHFEXIEX-CIF47NYe.js +1 -0
  91. package/dist/assets/stateDiagram-v2-QKLJ7IA2-Cy1rmPfG.js +1 -0
  92. package/dist/assets/timeline-definition-GMOUNBTQ-Bes4B58n.js +120 -0
  93. package/dist/assets/treeView-SZITEDCU-DPKseaET.js +1 -0
  94. package/dist/assets/treemap-W4RFUUIX-DH-7GZe_.js +1 -0
  95. package/dist/assets/vennDiagram-DHZGUBPP-3wx2huKk.js +34 -0
  96. package/dist/assets/wardley-RL74JXVD-AgyXyBN5.js +1 -0
  97. package/dist/assets/wardleyDiagram-NUSXRM2D-DzViT1Yx.js +20 -0
  98. package/dist/assets/xychartDiagram-5P7HB3ND-BO_dbU0r.js +7 -0
  99. package/{index.html → dist/index.html} +2 -1
  100. package/dist/index.js +2625 -0
  101. package/package.json +11 -1
  102. package/.agents/skills/remotion-best-practices/SKILL.md +0 -61
  103. package/.agents/skills/remotion-best-practices/rules/3d.md +0 -86
  104. package/.agents/skills/remotion-best-practices/rules/animations.md +0 -27
  105. package/.agents/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx +0 -178
  106. package/.agents/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +0 -100
  107. package/.agents/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +0 -108
  108. package/.agents/skills/remotion-best-practices/rules/assets.md +0 -78
  109. package/.agents/skills/remotion-best-practices/rules/audio-visualization.md +0 -198
  110. package/.agents/skills/remotion-best-practices/rules/audio.md +0 -169
  111. package/.agents/skills/remotion-best-practices/rules/calculate-metadata.md +0 -134
  112. package/.agents/skills/remotion-best-practices/rules/can-decode.md +0 -75
  113. package/.agents/skills/remotion-best-practices/rules/charts.md +0 -120
  114. package/.agents/skills/remotion-best-practices/rules/compositions.md +0 -154
  115. package/.agents/skills/remotion-best-practices/rules/display-captions.md +0 -184
  116. package/.agents/skills/remotion-best-practices/rules/extract-frames.md +0 -229
  117. package/.agents/skills/remotion-best-practices/rules/ffmpeg.md +0 -38
  118. package/.agents/skills/remotion-best-practices/rules/fonts.md +0 -152
  119. package/.agents/skills/remotion-best-practices/rules/get-audio-duration.md +0 -58
  120. package/.agents/skills/remotion-best-practices/rules/get-video-dimensions.md +0 -68
  121. package/.agents/skills/remotion-best-practices/rules/get-video-duration.md +0 -60
  122. package/.agents/skills/remotion-best-practices/rules/gifs.md +0 -141
  123. package/.agents/skills/remotion-best-practices/rules/images.md +0 -134
  124. package/.agents/skills/remotion-best-practices/rules/import-srt-captions.md +0 -69
  125. package/.agents/skills/remotion-best-practices/rules/light-leaks.md +0 -73
  126. package/.agents/skills/remotion-best-practices/rules/lottie.md +0 -70
  127. package/.agents/skills/remotion-best-practices/rules/maps.md +0 -412
  128. package/.agents/skills/remotion-best-practices/rules/measuring-dom-nodes.md +0 -34
  129. package/.agents/skills/remotion-best-practices/rules/measuring-text.md +0 -140
  130. package/.agents/skills/remotion-best-practices/rules/parameters.md +0 -109
  131. package/.agents/skills/remotion-best-practices/rules/sequencing.md +0 -118
  132. package/.agents/skills/remotion-best-practices/rules/sfx.md +0 -26
  133. package/.agents/skills/remotion-best-practices/rules/subtitles.md +0 -36
  134. package/.agents/skills/remotion-best-practices/rules/tailwind.md +0 -11
  135. package/.agents/skills/remotion-best-practices/rules/text-animations.md +0 -20
  136. package/.agents/skills/remotion-best-practices/rules/timing.md +0 -179
  137. package/.agents/skills/remotion-best-practices/rules/transcribe-captions.md +0 -70
  138. package/.agents/skills/remotion-best-practices/rules/transitions.md +0 -197
  139. package/.agents/skills/remotion-best-practices/rules/transparent-videos.md +0 -106
  140. package/.agents/skills/remotion-best-practices/rules/trimming.md +0 -51
  141. package/.agents/skills/remotion-best-practices/rules/videos.md +0 -171
  142. package/.agents/skills/remotion-best-practices/rules/voiceover.md +0 -99
  143. package/.agents/skills/simple/SKILL.md +0 -52
  144. package/.agents/skills/vercel-react-best-practices/AGENTS.md +0 -3254
  145. package/.agents/skills/vercel-react-best-practices/README.md +0 -123
  146. package/.agents/skills/vercel-react-best-practices/SKILL.md +0 -141
  147. package/.agents/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +0 -55
  148. package/.agents/skills/vercel-react-best-practices/rules/advanced-init-once.md +0 -42
  149. package/.agents/skills/vercel-react-best-practices/rules/advanced-use-latest.md +0 -39
  150. package/.agents/skills/vercel-react-best-practices/rules/async-api-routes.md +0 -38
  151. package/.agents/skills/vercel-react-best-practices/rules/async-defer-await.md +0 -80
  152. package/.agents/skills/vercel-react-best-practices/rules/async-dependencies.md +0 -51
  153. package/.agents/skills/vercel-react-best-practices/rules/async-parallel.md +0 -28
  154. package/.agents/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +0 -99
  155. package/.agents/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +0 -59
  156. package/.agents/skills/vercel-react-best-practices/rules/bundle-conditional.md +0 -31
  157. package/.agents/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +0 -49
  158. package/.agents/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +0 -35
  159. package/.agents/skills/vercel-react-best-practices/rules/bundle-preload.md +0 -50
  160. package/.agents/skills/vercel-react-best-practices/rules/client-event-listeners.md +0 -74
  161. package/.agents/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +0 -71
  162. package/.agents/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +0 -48
  163. package/.agents/skills/vercel-react-best-practices/rules/client-swr-dedup.md +0 -56
  164. package/.agents/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +0 -107
  165. package/.agents/skills/vercel-react-best-practices/rules/js-cache-function-results.md +0 -80
  166. package/.agents/skills/vercel-react-best-practices/rules/js-cache-property-access.md +0 -28
  167. package/.agents/skills/vercel-react-best-practices/rules/js-cache-storage.md +0 -70
  168. package/.agents/skills/vercel-react-best-practices/rules/js-combine-iterations.md +0 -32
  169. package/.agents/skills/vercel-react-best-practices/rules/js-early-exit.md +0 -50
  170. package/.agents/skills/vercel-react-best-practices/rules/js-flatmap-filter.md +0 -60
  171. package/.agents/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +0 -45
  172. package/.agents/skills/vercel-react-best-practices/rules/js-index-maps.md +0 -37
  173. package/.agents/skills/vercel-react-best-practices/rules/js-length-check-first.md +0 -49
  174. package/.agents/skills/vercel-react-best-practices/rules/js-min-max-loop.md +0 -82
  175. package/.agents/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +0 -24
  176. package/.agents/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +0 -57
  177. package/.agents/skills/vercel-react-best-practices/rules/rendering-activity.md +0 -26
  178. package/.agents/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
  179. package/.agents/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +0 -40
  180. package/.agents/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +0 -38
  181. package/.agents/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +0 -46
  182. package/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
  183. package/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +0 -30
  184. package/.agents/skills/vercel-react-best-practices/rules/rendering-resource-hints.md +0 -85
  185. package/.agents/skills/vercel-react-best-practices/rules/rendering-script-defer-async.md +0 -68
  186. package/.agents/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +0 -28
  187. package/.agents/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +0 -75
  188. package/.agents/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +0 -39
  189. package/.agents/skills/vercel-react-best-practices/rules/rerender-dependencies.md +0 -45
  190. package/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +0 -40
  191. package/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state.md +0 -29
  192. package/.agents/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +0 -74
  193. package/.agents/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +0 -58
  194. package/.agents/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +0 -38
  195. package/.agents/skills/vercel-react-best-practices/rules/rerender-memo.md +0 -44
  196. package/.agents/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +0 -45
  197. package/.agents/skills/vercel-react-best-practices/rules/rerender-no-inline-components.md +0 -82
  198. package/.agents/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +0 -35
  199. package/.agents/skills/vercel-react-best-practices/rules/rerender-transitions.md +0 -40
  200. package/.agents/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +0 -73
  201. package/.agents/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +0 -73
  202. package/.agents/skills/vercel-react-best-practices/rules/server-auth-actions.md +0 -96
  203. package/.agents/skills/vercel-react-best-practices/rules/server-cache-lru.md +0 -41
  204. package/.agents/skills/vercel-react-best-practices/rules/server-cache-react.md +0 -76
  205. package/.agents/skills/vercel-react-best-practices/rules/server-dedup-props.md +0 -65
  206. package/.agents/skills/vercel-react-best-practices/rules/server-hoist-static-io.md +0 -142
  207. package/.agents/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +0 -83
  208. package/.agents/skills/vercel-react-best-practices/rules/server-serialization.md +0 -38
  209. package/.claude/CLAUDE.md +0 -184
  210. package/.claude/commands/review.md +0 -120
  211. package/.claude/commands/sync-docs.md +0 -71
  212. package/.claude/roadmap.md +0 -121
  213. package/.claude/rules/style-guide.md +0 -830
  214. package/.claude/settings.json +0 -18
  215. package/.claude/user-stories.md +0 -333
  216. package/AGENTS.md +0 -68
  217. package/Makefile +0 -32
  218. package/biome.json +0 -79
  219. package/bun.lock +0 -854
  220. package/bunfig.toml +0 -2
  221. package/docs/design.md +0 -563
  222. package/docs/perf-baseline.md +0 -130
  223. package/docs/plans/2026-03-13-client-mode-design.md +0 -86
  224. package/docs/plans/2026-03-13-client-mode-plan.md +0 -605
  225. package/docs/plans/2026-03-13-keyboard-shortcuts-design.md +0 -129
  226. package/docs/plans/2026-03-13-keyboard-shortcuts-plan.md +0 -1471
  227. package/docs/plans/2026-03-13-multi-document-design.md +0 -183
  228. package/docs/plans/2026-03-13-performance-benchmarks-design.md +0 -121
  229. package/docs/superpowers/plans/2026-03-26-surgical-pruning.md +0 -1176
  230. package/docs/superpowers/specs/2026-03-27-go-server-rewrite-design.md +0 -284
  231. package/e2e/comments.spec.ts +0 -81
  232. package/e2e/document-load.spec.ts +0 -32
  233. package/e2e/export.spec.ts +0 -58
  234. package/e2e/fixtures/sample.md +0 -7
  235. package/e2e/perf/add-comment.spec.ts +0 -116
  236. package/e2e/perf/fixtures/generate.ts +0 -327
  237. package/e2e/perf/initial-load.spec.ts +0 -49
  238. package/e2e/perf/perf.setup.ts +0 -23
  239. package/e2e/perf/perf.teardown.ts +0 -9
  240. package/e2e/perf/screenshot-final.png +0 -0
  241. package/e2e/perf/scroll.spec.ts +0 -39
  242. package/e2e/perf/tab-switch.spec.ts +0 -69
  243. package/e2e/perf/text-selection.spec.ts +0 -119
  244. package/e2e/perf/utils/metrics.ts +0 -350
  245. package/e2e/perf/utils/perf-cli.ts +0 -86
  246. package/e2e/persistence-file.spec.ts +0 -357
  247. package/e2e/utils/cli.ts +0 -84
  248. package/e2e/utils/selection.ts +0 -79
  249. package/go/cmd/readit/main.go +0 -416
  250. package/go/go.mod +0 -20
  251. package/go/go.sum +0 -41
  252. package/go/internal/server/anchor.go +0 -302
  253. package/go/internal/server/anchor_test.go +0 -111
  254. package/go/internal/server/comments.go +0 -390
  255. package/go/internal/server/documents.go +0 -113
  256. package/go/internal/server/embed.go +0 -17
  257. package/go/internal/server/headings.go +0 -33
  258. package/go/internal/server/headings_test.go +0 -75
  259. package/go/internal/server/htmltext.go +0 -123
  260. package/go/internal/server/markdown.go +0 -157
  261. package/go/internal/server/markdown_bench_test.go +0 -42
  262. package/go/internal/server/markdown_test.go +0 -79
  263. package/go/internal/server/server.go +0 -453
  264. package/go/internal/server/server_bench_test.go +0 -122
  265. package/go/internal/server/settings.go +0 -110
  266. package/go/internal/server/sse.go +0 -140
  267. package/go/internal/server/storage.go +0 -275
  268. package/go/internal/server/storage_test.go +0 -152
  269. package/go/internal/server/template.go +0 -66
  270. package/go/internal/server/types.go +0 -101
  271. package/go/internal/server/watcher.go +0 -74
  272. package/lefthook.yml +0 -8
  273. package/nvim-readit/lua/readit/health.lua +0 -64
  274. package/nvim-readit/lua/readit/init.lua +0 -463
  275. package/nvim-readit/plugin/readit.lua +0 -19
  276. package/playwright.config.ts +0 -34
  277. package/skills-lock.json +0 -20
  278. package/src/App.svelte +0 -890
  279. package/src/cli.ts +0 -881
  280. package/src/components/ActionsMenu.svelte +0 -95
  281. package/src/components/CommentBadge.svelte +0 -67
  282. package/src/components/CommentErrorBanner.svelte +0 -33
  283. package/src/components/CommentInput.svelte +0 -75
  284. package/src/components/CommentListItem.svelte +0 -95
  285. package/src/components/CommentManager.svelte +0 -129
  286. package/src/components/CommentNav.svelte +0 -109
  287. package/src/components/DocumentViewer.svelte +0 -233
  288. package/src/components/FloatingComment.svelte +0 -107
  289. package/src/components/Header.svelte +0 -76
  290. package/src/components/InlineEditor.svelte +0 -72
  291. package/src/components/MarginNote.svelte +0 -167
  292. package/src/components/MarginNotesContainer.svelte +0 -33
  293. package/src/components/MermaidEnhancer.svelte +0 -218
  294. package/src/components/MermaidModal.svelte +0 -67
  295. package/src/components/RawModal.svelte +0 -126
  296. package/src/components/ReanchorConfirm.svelte +0 -30
  297. package/src/components/SettingsModal.svelte +0 -220
  298. package/src/components/ShortcutCapture.svelte +0 -82
  299. package/src/components/ShortcutList.svelte +0 -145
  300. package/src/components/TabBar.svelte +0 -52
  301. package/src/components/TableOfContents.svelte +0 -125
  302. package/src/components/ui/ActionLink.svelte +0 -40
  303. package/src/components/ui/Button.svelte +0 -53
  304. package/src/components/ui/Dialog.svelte +0 -97
  305. package/src/components/ui/DropdownMenu.svelte +0 -85
  306. package/src/components/ui/DropdownMenuItem.svelte +0 -38
  307. package/src/components/ui/DropdownMenuSeparator.svelte +0 -11
  308. package/src/components/ui/Text.svelte +0 -42
  309. package/src/env.d.ts +0 -6
  310. package/src/index.css +0 -859
  311. package/src/lib/__fixtures__/bench-data.ts +0 -114
  312. package/src/lib/anchor.bench.ts +0 -91
  313. package/src/lib/anchor.test.ts +0 -527
  314. package/src/lib/anchor.ts +0 -381
  315. package/src/lib/comment-storage.bench.ts +0 -49
  316. package/src/lib/comment-storage.test.ts +0 -694
  317. package/src/lib/comment-storage.ts +0 -226
  318. package/src/lib/export.bench.ts +0 -21
  319. package/src/lib/export.ts +0 -36
  320. package/src/lib/fetch-or-throw.test.ts +0 -59
  321. package/src/lib/fetch-or-throw.ts +0 -12
  322. package/src/lib/headings.test.ts +0 -103
  323. package/src/lib/headings.ts +0 -44
  324. package/src/lib/highlight/core.test.ts +0 -93
  325. package/src/lib/highlight/dom.ts +0 -187
  326. package/src/lib/highlight/highlight-registry.ts +0 -221
  327. package/src/lib/highlight/highlight.bench.ts +0 -92
  328. package/src/lib/highlight/highlighter.ts +0 -247
  329. package/src/lib/highlight/resolver.ts +0 -38
  330. package/src/lib/highlight/types.ts +0 -17
  331. package/src/lib/html-text.test.ts +0 -162
  332. package/src/lib/html-text.ts +0 -161
  333. package/src/lib/i18n/en.ts +0 -124
  334. package/src/lib/i18n/index.ts +0 -3
  335. package/src/lib/i18n/ja.ts +0 -126
  336. package/src/lib/i18n/translations.ts +0 -27
  337. package/src/lib/i18n/types.ts +0 -130
  338. package/src/lib/key-lock.test.ts +0 -104
  339. package/src/lib/key-lock.ts +0 -23
  340. package/src/lib/margin-layout.bench.ts +0 -61
  341. package/src/lib/margin-layout.ts +0 -71
  342. package/src/lib/markdown-renderer.test.ts +0 -154
  343. package/src/lib/markdown-renderer.ts +0 -178
  344. package/src/lib/mermaid-config.ts +0 -38
  345. package/src/lib/mermaid-renderer.ts +0 -162
  346. package/src/lib/mermaid-worker.ts +0 -60
  347. package/src/lib/positions.ts +0 -157
  348. package/src/lib/shortcut-registry.ts +0 -244
  349. package/src/lib/utils.ts +0 -15
  350. package/src/main.ts +0 -16
  351. package/src/schema.ts +0 -92
  352. package/src/server.ts +0 -1216
  353. package/src/stores/app.svelte.ts +0 -231
  354. package/src/stores/locale.svelte.ts +0 -46
  355. package/src/stores/settings.svelte.ts +0 -90
  356. package/src/stores/shortcuts.svelte.ts +0 -104
  357. package/src/stores/ui.svelte.ts +0 -12
  358. package/src/template.ts +0 -104
  359. package/src/test-setup.ts +0 -48
  360. package/svelte.config.js +0 -5
  361. package/test.md +0 -74
  362. package/tsconfig.cli.json +0 -12
  363. package/tsconfig.json +0 -20
  364. package/vite.config.ts +0 -47
  365. package/vitest.config.ts +0 -15
  366. package/vscode-readit/.mcp.json +0 -7
  367. package/vscode-readit/.vscodeignore +0 -7
  368. package/vscode-readit/bun.lock +0 -78
  369. package/vscode-readit/icon.svg +0 -10
  370. package/vscode-readit/package.json +0 -110
  371. package/vscode-readit/src/extension.ts +0 -117
  372. package/vscode-readit/src/server-manager.ts +0 -272
  373. package/vscode-readit/src/webview-provider.ts +0 -204
  374. package/vscode-readit/tsconfig.json +0 -20
package/bunfig.toml DELETED
@@ -1,2 +0,0 @@
1
- [test]
2
- root = "src"
package/docs/design.md DELETED
@@ -1,563 +0,0 @@
1
- # Comment Storage Design
2
-
3
- This document describes the design for storing highlights, comments, and document state in plain markdown files instead of localStorage.
4
-
5
- ## Design Goals
6
-
7
- | Priority | Goal | Description |
8
- |----------|------|-------------|
9
- | 1 | **Hackability** | Simple, understandable, editable with any text editor |
10
- | 2 | **Simplicity** | Minimal complexity, easy to implement |
11
- | 3 | **Versioning** | Git-native, full history support |
12
- | 4 | **Diffing** | Human-readable, line-based diffs |
13
- | 5 | **Performance** | Fast reads/writes for typical use cases |
14
-
15
- ---
16
-
17
- ## Current State (localStorage)
18
-
19
- The current implementation uses browser localStorage:
20
-
21
- ```typescript
22
- interface Comment {
23
- id: string; // UUID
24
- selectedText: string; // Highlighted text
25
- comment: string; // User's comment
26
- createdAt: string; // ISO 8601 timestamp
27
- startOffset: number; // Character offset (start)
28
- endOffset: number; // Character offset (end)
29
- }
30
- ```
31
-
32
- **Storage key**: `readit-comments-{filePath}`
33
-
34
- ### Limitations
35
-
36
- 1. **Browser-only**: Comments don't persist across devices
37
- 2. **No versioning**: No history, no git integration
38
- 3. **Offset fragility**: Character offsets break when document changes
39
- 4. **Not shareable**: Manual export required to share reviews
40
-
41
- ---
42
-
43
- ## Storage Location
44
-
45
- ### Global Home Directory: `~/.readit/`
46
-
47
- readit is a global CLI tool. All comment files are stored in a single location:
48
-
49
- ```
50
- ~/.readit/
51
- └── comments/
52
- └── {path-based-structure}/
53
- └── {filename}.comments.md
54
- ```
55
-
56
- ### Why Global `~/.readit/`?
57
-
58
- | Concern | Solution |
59
- |---------|----------|
60
- | No scattered `.readit/` folders | Single location for all comments |
61
- | Easy to find | `~/.readit/comments/` contains everything |
62
- | Easy to backup | Copy one directory |
63
- | Cross-project | Works the same for any file, anywhere |
64
- | Precedent | Similar to `~/.ssh/`, `~/.config/`, `~/.docker/` |
65
-
66
- ### Path Structure
67
-
68
- Comments are stored using the **absolute path** of the source file, converted to a directory structure:
69
-
70
- ```
71
- Source file: /home/user/projects/app/README.md
72
- Comment file: ~/.readit/comments/home/user/projects/app/README.comments.md
73
-
74
- Source file: /Users/jay/docs/design.md
75
- Comment file: ~/.readit/comments/Users/jay/docs/design.comments.md
76
- ```
77
-
78
- ### Path Resolution Algorithm
79
-
80
- ```typescript
81
- import * as path from 'path';
82
- import * as os from 'os';
83
-
84
- function getCommentPath(sourcePath: string): string {
85
- // Resolve to absolute path
86
- const absolute = path.resolve(sourcePath);
87
-
88
- // Remove leading slash and drive letter (Windows)
89
- const normalized = absolute.replace(/^\//, '').replace(/^[A-Z]:/, '');
90
-
91
- // Get filename without extension
92
- const ext = path.extname(normalized);
93
- const withoutExt = normalized.slice(0, -ext.length);
94
-
95
- // Construct comment file path
96
- return path.join(
97
- os.homedir(),
98
- '.readit',
99
- 'comments',
100
- `${withoutExt}.comments.md`
101
- );
102
- }
103
- ```
104
-
105
- ### Examples
106
-
107
- | Source Path | Comment File Path |
108
- |-------------|-------------------|
109
- | `./README.md` (from `/home/user/project`) | `~/.readit/comments/home/user/project/README.comments.md` |
110
- | `/tmp/notes.md` | `~/.readit/comments/tmp/notes.comments.md` |
111
- | `../shared/doc.md` (from `/home/user/project`) | `~/.readit/comments/home/user/shared/doc.comments.md` |
112
- | `~/Desktop/review.html` | `~/.readit/comments/Users/jay/Desktop/review.comments.md` |
113
-
114
- ### Edge Cases
115
-
116
- **Same filename, different directories**: No collision—absolute paths differ.
117
-
118
- ```
119
- /home/user/project-a/README.md → ~/.readit/comments/home/user/project-a/README.comments.md
120
- /home/user/project-b/README.md → ~/.readit/comments/home/user/project-b/README.comments.md
121
- ```
122
-
123
- **Relative paths from different CWDs**: Resolve to same absolute path → same comment file.
124
-
125
- ```bash
126
- # From /project/src/
127
- readit ../README.md # → /project/README.md
128
-
129
- # From /project/src/deep/
130
- readit ../../README.md # → /project/README.md (same file, same comments)
131
- ```
132
-
133
- ---
134
-
135
- ## File Format
136
-
137
- ```markdown
138
- ---
139
- source: /home/user/project/README.md
140
- hash: e3b0c44298fc1c14
141
- version: 1
142
- ---
143
-
144
- <!-- c:550e8400|L42|2025-12-24T10:30:00+09:00 -->
145
- > the exact selected text from the document
146
-
147
- My review comment here. Full markdown supported.
148
- Can span multiple paragraphs.
149
-
150
- ---
151
-
152
- <!-- c:660f9511|L57-59|2025-12-24T11:00:00+09:00 -->
153
- > another piece of selected text
154
- > that spans multiple lines
155
-
156
- Another comment with my thoughts.
157
-
158
- ---
159
- ```
160
-
161
- ### Format Breakdown
162
-
163
- #### 1. YAML Front Matter
164
-
165
- ```yaml
166
- ---
167
- source: /home/user/project/README.md # Absolute path to source file
168
- hash: e3b0c44298fc1c14 # SHA-256 prefix (16 chars) of source content
169
- version: 1 # Format version for future compatibility
170
- ---
171
- ```
172
-
173
- **Purpose**: Document-level metadata for validation and future-proofing.
174
-
175
- #### 2. Comment Metadata (HTML Comment)
176
-
177
- ```html
178
- <!-- c:550e8400|L42|2025-12-24T10:30:00+09:00 -->
179
- ```
180
-
181
- **Format**: `c:{id}|{line-hint}|{timestamp}`
182
-
183
- | Field | Description | Example |
184
- |-------|-------------|---------|
185
- | `id` | UUID prefix (8 chars) | `550e8400` |
186
- | `line-hint` | Line number(s) in source | `L42` or `L42-45` |
187
- | `timestamp` | ISO 8601 with timezone | `2025-12-24T10:30:00+09:00` |
188
-
189
- **Why HTML comment?**
190
-
191
- - Invisible when rendered in markdown viewers
192
- - Single line = clean git diffs
193
- - Grep-friendly for tooling
194
-
195
- #### 3. Selected Text (Blockquote)
196
-
197
- ```markdown
198
- > the exact selected text from the document
199
- ```
200
-
201
- **Purpose**: Primary anchor for matching. The text itself is the anchor.
202
-
203
- **Multi-line selections**:
204
-
205
- ```markdown
206
- > first line of selection
207
- > second line of selection
208
- > third line of selection
209
- ```
210
-
211
- #### 4. Comment Body (Plain Text)
212
-
213
- ```markdown
214
- My review comment here. Full markdown supported.
215
- Can span multiple paragraphs.
216
-
217
- - Lists work
218
- - **Bold** and *italic* work
219
- - `code` works
220
- ```
221
-
222
- #### 5. Separator
223
-
224
- ```markdown
225
- ---
226
- ```
227
-
228
- **Purpose**: Visual separation between comments, easy parsing boundary.
229
-
230
- ---
231
-
232
- ## Anchoring Strategy
233
-
234
- ### The Problem
235
-
236
- Character offsets are fragile. When the source document changes:
237
-
238
- - Insertions shift all following offsets
239
- - Deletions shift all following offsets
240
- - Even whitespace changes break anchors
241
-
242
- ### The Solution: Text-First Anchoring
243
-
244
- **Primary anchor**: The selected text itself
245
- **Secondary hint**: Line number for fast lookup
246
-
247
- ### Matching Algorithm
248
-
249
- ```
250
- findAnchor(source, selectedText, lineHint):
251
- 1. Fast path: Search near line hint (±500 chars)
252
- - If found, return position
253
-
254
- 2. Fallback: Global search in document
255
- - If found, return position
256
-
257
- 3. Fuzzy: Levenshtein distance matching (optional)
258
- - For handling minor edits to selected text
259
-
260
- 4. Fail: Return null, show warning in UI
261
- ```
262
-
263
- ### Resilience
264
-
265
- | Document Change | Effect on Anchors |
266
- |-----------------|-------------------|
267
- | Insert text before selection | Line hint shifts, text match still works |
268
- | Insert text after selection | No effect |
269
- | Edit unrelated text | No effect |
270
- | Edit selected text | Fuzzy match or manual re-anchor |
271
- | Delete selected text | Anchor fails, user notified |
272
-
273
- ---
274
-
275
- ## Edge Cases
276
-
277
- ### Same text appears multiple times
278
-
279
- ```markdown
280
- > the
281
- ```
282
-
283
- **Solution**: Line hint disambiguates. Take the match closest to the hinted line.
284
-
285
- ### Selected text was edited
286
-
287
- **Solution**:
288
-
289
- 1. Fuzzy matching with Levenshtein distance
290
- 2. Show "anchor uncertain" warning
291
- 3. User can re-anchor manually
292
-
293
- ### Document hash mismatch
294
-
295
- **UI Warning**:
296
-
297
- ```
298
- Document has changed since review.
299
- Some comments may be misaligned.
300
- ```
301
-
302
- ### Empty selection or whitespace-only
303
-
304
- **Prevention**: Reject selections that are empty or whitespace-only at input time.
305
-
306
- ### Very long selections
307
-
308
- **Practical limit**: Store full text up to 1000 chars. Beyond that, store first 500 + `...` + last 500.
309
-
310
- ---
311
-
312
- ## Known Limitations
313
-
314
- ### Single-Tab Per File
315
-
316
- readit does not support multiple browser tabs reviewing the same file simultaneously.
317
- If two tabs edit comments for the same file, the last write wins and earlier changes may be lost.
318
-
319
- **Workaround**: Close other tabs before starting a new review session.
320
-
321
- ### Cross-Machine Path Differences
322
-
323
- Comments are stored using absolute paths. If you sync `~/.readit/` across machines
324
- with different path structures (e.g., `/Users/jay/` on Mac vs `/home/jay/` on Linux),
325
- comments will not be associated with the same source files.
326
-
327
- **Workaround**: Use readit on a single machine, or ensure identical absolute paths.
328
-
329
- ### Export is a Transform
330
-
331
- Export (JSON, prompt format) is a transformation of in-memory comments, not a storage format.
332
- The canonical format is `.comments.md`.
333
-
334
- ---
335
-
336
- ## Storage Protocol
337
-
338
- ### Data Types
339
-
340
- ```typescript
341
- interface CommentFile {
342
- source: string; // Absolute path to source file
343
- hash: string; // SHA-256 prefix (16 chars) of source content
344
- version: number; // Format version
345
- comments: Comment[];
346
- }
347
-
348
- interface Comment {
349
- id: string; // Full UUID (stored as 8-char prefix in file)
350
- selectedText: string; // Primary anchor (the quoted text)
351
- lineHint: string; // "L42" or "L42-45"
352
- createdAt: string; // ISO 8601 with timezone
353
- body: string; // Comment text (markdown)
354
- }
355
- ```
356
-
357
- ### Read Protocol
358
-
359
- ```
360
- 1. Resolve source path to absolute path
361
- 2. Compute comment file path: ~/.readit/comments/{path}.comments.md
362
- 3. Check if comment file exists (no file = no comments)
363
- 4. Parse YAML front matter
364
- 5. Verify source path matches (warn if different)
365
- 6. Compare hash with current source content (warn if mismatch)
366
- 7. Split body by "---" separator
367
- 8. For each block:
368
- a. Extract metadata from HTML comment
369
- b. Extract selected text from blockquote
370
- c. Extract body (remaining text)
371
- 9. Resolve anchors to character offsets using text matching
372
- 10. Return resolved comments for rendering
373
- ```
374
-
375
- ### Write Protocol
376
-
377
- ```
378
- 1. Resolve source path to absolute path
379
- 2. Compute comment file path: ~/.readit/comments/{path}.comments.md
380
- 3. Ensure parent directories exist (mkdir -p)
381
- 4. Compute source content hash (SHA-256, take first 16 chars)
382
- 5. Generate YAML front matter with source, hash, version
383
- 6. For each comment:
384
- a. Compute current line number for selected text
385
- b. Format metadata as HTML comment
386
- c. Format selected text as blockquote (prefix each line with "> ")
387
- d. Append comment body
388
- e. Add "---" separator
389
- 7. Write to temp file
390
- 8. Atomic rename to final path
391
- ```
392
-
393
- ### Sync on Source Change
394
-
395
- ```
396
- On source file load:
397
- 1. Compute current source hash
398
- 2. Compare with stored hash in comment file
399
- 3. If different:
400
- - Re-run anchor matching for all comments
401
- - Update line hints to current positions
402
- - Flag any unresolved anchors
403
- - Update stored hash
404
- - Save updated comment file
405
- ```
406
-
407
- ---
408
-
409
- ## CLI Integration
410
-
411
- ### Commands
412
-
413
- ```bash
414
- # Review a file (opens browser UI)
415
- readit <file>
416
-
417
- # Review with options
418
- readit <file> --port 3000 # Custom port
419
- readit <file> --no-open # Don't auto-open browser
420
- readit <file> --clean # Clear existing comments for this file
421
-
422
- # List all commented files
423
- readit list
424
-
425
- # Show comments for a file (without opening UI)
426
- readit show <file>
427
-
428
- # Export comments
429
- readit export <file> --format json
430
- readit export <file> --format prompt
431
- ```
432
-
433
- ### Server API
434
-
435
- The Express server provides endpoints for the browser UI:
436
-
437
- ```
438
- GET /api/comments # Get comments for current file
439
- POST /api/comments # Add a new comment
440
- PUT /api/comments/:id # Update a comment
441
- DELETE /api/comments/:id # Delete a comment
442
- GET /api/source # Get source file info (path, hash)
443
- ```
444
-
445
- ---
446
-
447
- ## Performance
448
-
449
- | Operation | Complexity | Notes |
450
- |-----------|------------|-------|
451
- | Load comments | O(n) | Parse markdown once, n = number of comments |
452
- | Find anchor | O(1) avg | Line hint + local text search |
453
- | Save comments | O(n) | Full file rewrite |
454
- | Add comment | O(n) | Append + rewrite |
455
-
456
- For typical use (<100 comments per file), all operations are instantaneous.
457
-
458
- ### File System Considerations
459
-
460
- - Comment files are small (typically <100KB)
461
- - Directory structure mirrors source paths (may be deep)
462
- - Atomic writes via temp file + rename
463
-
464
- ---
465
-
466
- ## Migration from localStorage
467
-
468
- ### Strategy
469
-
470
- 1. On app load, check for localStorage data for current file
471
- 2. If localStorage has data and no comment file exists:
472
- - Prompt user to migrate
473
- - Convert comments to new format
474
- - Write to `~/.readit/comments/...`
475
- - Optionally clear localStorage
476
- 3. If both exist:
477
- - Prefer file-based (authoritative)
478
- - Warn about localStorage orphan
479
-
480
- ### Conversion
481
-
482
- ```typescript
483
- function migrateComment(old: OldComment, sourceContent: string): NewComment {
484
- return {
485
- id: old.id.slice(0, 8),
486
- selectedText: old.selectedText,
487
- lineHint: `L${getLineNumber(sourceContent, old.startOffset)}`,
488
- createdAt: old.createdAt,
489
- body: old.comment,
490
- };
491
- }
492
-
493
- function getLineNumber(content: string, offset: number): number {
494
- return content.slice(0, offset).split('\n').length;
495
- }
496
- ```
497
-
498
- ---
499
-
500
- ## Future Considerations
501
-
502
- ### Local `.readit/` Override
503
-
504
- For projects that want to commit comments with the source code:
505
-
506
- ```bash
507
- # Initialize local .readit/ in current directory
508
- readit init --local
509
-
510
- # Now comments for files in this directory tree use local storage
511
- ./project/.readit/comments/README.comments.md
512
- ```
513
-
514
- **Lookup order** (future):
515
-
516
- 1. Check for `.readit/` in source file's directory (or ancestors)
517
- 2. If found, use local storage
518
- 3. Otherwise, use global `~/.readit/`
519
-
520
- ### Potential Extensions
521
-
522
- 1. **Author field**: `<!-- c:abc123|L42|2025-12-24|@username -->`
523
- 2. **Status/resolution**: Resolved, won't fix, etc.
524
- 3. **Replies**: Nested comments (threaded discussion)
525
- 4. **Tags/categories**: Bug, question, suggestion, etc.
526
-
527
- ### Format Versioning
528
-
529
- The `version: 1` field in front matter allows future format changes:
530
-
531
- ```yaml
532
- ---
533
- version: 2
534
- # New fields in v2...
535
- ---
536
- ```
537
-
538
- Parser can handle multiple versions for backwards compatibility.
539
-
540
- ---
541
-
542
- ## Decision Log
543
-
544
- | Date | Decision | Rationale |
545
- |------|----------|-----------|
546
- | 2025-12-24 | Global `~/.readit/` storage | readit is a global CLI; avoids scattered `.readit/` folders |
547
- | 2025-12-24 | Path-based directory structure | Intuitive mapping from source path to comment file |
548
- | 2025-12-24 | Absolute path in front matter | Self-documenting, enables validation |
549
- | 2025-12-24 | Text-based anchoring over offsets | Resilient to document changes |
550
- | 2025-12-24 | Markdown format over YAML/JSON | Human-readable, hackable, editable |
551
- | 2025-12-24 | HTML comments for metadata | Invisible in viewers, clean git diffs |
552
- | 2025-12-24 | Blockquotes for selected text | Standard markdown, visually distinct |
553
- | 2025-12-24 | 8-char UUID prefix | Collision-resistant, grep-friendly |
554
- | 2025-12-24 | Local `.readit/` as future option | Deferred to keep v1 simple |
555
-
556
- ---
557
-
558
- ## References
559
-
560
- - Original localStorage implementation: `src/hooks/useComments.ts`
561
- - Current types: `src/types/index.ts`
562
- - Export utilities: `src/lib/export.ts`
563
- - Inspiration: [difit](https://github.com/yoshiko-pg/difit) - local code review for AI era
@@ -1,130 +0,0 @@
1
- # Performance Baseline
2
-
3
- Captured: 2026-03-27
4
- Machine: Darwin 25.3.0 (Apple Silicon)
5
- Runtime: Bun
6
- Build: production (`bun run build`)
7
-
8
- ## E2E Metrics (Playwright, Chromium)
9
-
10
- ### Initial Load
11
-
12
- | Tier | Lines | Comments | FCP | DCL | All Highlights Painted | Highlights Found |
13
- |------|-------|----------|-----|-----|------------------------|------------------|
14
- | medium | 1,000 | 100 | 112ms | 74ms | **886ms** | 100 |
15
- | large | 3,000 | 200 | 368ms | 22ms | **3,247ms** | 193 |
16
-
17
- ### Interactions
18
-
19
- | Metric | Tier | Result |
20
- |--------|------|--------|
21
- | Add comment (time to new highlight) | medium | **98ms** |
22
- | Text selection (median of 5) | medium | **9ms** |
23
- | Tab switch (medium → medium-b, 100 → 100 comments) | medium | **414ms** |
24
-
25
- ### Scroll Performance
26
-
27
- | Tier | Total Scroll Time | Long Tasks (>50ms) | P50 | P95 | P99 |
28
- |------|-------------------|-------------------|-----|-----|-----|
29
- | medium (1000 lines, 100 comments) | 8,953ms | 0 | 0ms | 0ms | 0ms |
30
- | large (3000 lines, 200 comments) | 25,912ms | 3 | 106ms | 121ms | 121ms |
31
-
32
- ## Bundle Size
33
-
34
- | Asset | Raw | Gzipped |
35
- |-------|-----|---------|
36
- | Main JS (index-*.js) | 667 KB | 206 KB |
37
- | Total dist/assets/ | 6.5 MB | — |
38
- | CSS (index-*.css) | 45 KB | — |
39
- | CLI (cli.js) | 51 KB | — |
40
-
41
- ### Top chunks by size
42
-
43
- | Chunk | Size | Purpose |
44
- |-------|------|---------|
45
- | index-DCIQ7W07.js | 652 KB | Main app bundle |
46
- | chunk-XZSTWKYB.js | 426 KB | Mermaid core |
47
- | cytoscape.esm.js | 424 KB | Mermaid dependency |
48
- | katex.js | 250 KB | Math rendering (mermaid) |
49
- | prism.js | 146 KB | Syntax highlighter |
50
- | architectureDiagram.js | 143 KB | Mermaid architecture |
51
- | chunk-7R4GIKGN.js | 124 KB | Mermaid support |
52
- | esm.js | 112 KB | Mermaid support |
53
-
54
- ## Vitest Bench (Server-side Operations)
55
-
56
- > Run with: `bun run bench`
57
-
58
- ### Anchor Resolution
59
-
60
- | Benchmark | ops/sec | Mean | p99 |
61
- |-----------|---------|------|-----|
62
- | findAnchor — exact, medium doc | 340,789 | 0.003ms | 0.006ms |
63
- | findAnchor — exact, large doc | 348,679 | 0.003ms | 0.006ms |
64
- | findAnchorNormalized — large doc | 10,414 | 0.096ms | 0.406ms |
65
- | findAnchorFuzzy — mutated text, large doc | 163 | **6.13ms** | 6.41ms |
66
- | findAnchorWithFallback — 1 comment | 101 | **9.86ms** | 10.27ms |
67
- | findAnchorWithFallback — 10 comments | 39 | **25.66ms** | 26.10ms |
68
- | findAnchorWithFallback — 50 comments | 3 | **313.30ms** | 640.60ms |
69
-
70
- ### Comment Storage
71
-
72
- | Benchmark | ops/sec | Mean | p99 |
73
- |-----------|---------|------|-----|
74
- | parseCommentFile — 1 comment | 881,595 | 0.001ms | 0.003ms |
75
- | parseCommentFile — 10 comments | 165,610 | 0.006ms | 0.009ms |
76
- | parseCommentFile — 50 comments | 34,588 | 0.029ms | 0.045ms |
77
- | serializeComments — 1 comment | 2,011,903 | 0.0005ms | 0.001ms |
78
- | serializeComments — 10 comments | 286,303 | 0.004ms | 0.005ms |
79
- | serializeComments — 50 comments | 59,027 | 0.017ms | 0.029ms |
80
- | computeHash — 300 lines | 169,082 | 0.006ms | 0.009ms |
81
-
82
- ### Margin Layout
83
-
84
- | Benchmark | ops/sec | Mean | p99 |
85
- |-----------|---------|------|-----|
86
- | well-spaced — 1 comment | 6,192,537 | 0.0002ms | 0.0002ms |
87
- | well-spaced — 10 comments | 942,048 | 0.001ms | 0.002ms |
88
- | well-spaced — 50 comments | 167,170 | 0.006ms | 0.009ms |
89
- | clustered — 10 comments | 932,383 | 0.001ms | 0.002ms |
90
- | clustered — 50 comments | 165,792 | 0.006ms | 0.009ms |
91
- | with input zone — 50 comments | 143,787 | 0.007ms | 0.010ms |
92
-
93
- ### Export
94
-
95
- | Benchmark | ops/sec | Mean |
96
- |-----------|---------|------|
97
- | formatComment — single | 17,270,891 | 0.00006ms |
98
- | generatePrompt — 10 comments | 927,600 | 0.001ms |
99
- | generatePrompt — 50 comments | 189,187 | 0.005ms |
100
-
101
- ### Highlight System (DOM Operations) — *the optimization target*
102
-
103
- | Benchmark | ops/sec | Mean | p99 |
104
- |-----------|---------|------|-----|
105
- | findTextPosition — 1 comment | 61,802 | 0.016ms | 0.033ms |
106
- | findTextPosition — 10 comments | 17,713 | 0.057ms | 0.116ms |
107
- | findTextPosition — 50 comments | 4,555 | 0.220ms | 0.634ms |
108
- | getDOMTextContent — medium doc | 40,004 | 0.025ms | 0.055ms |
109
- | getDOMTextContent — large doc | 17,498 | 0.057ms | 0.222ms |
110
- | collectTextNodes — medium doc | 41,437 | 0.024ms | 0.070ms |
111
- | collectTextNodes — large doc | 21,645 | 0.046ms | 0.113ms |
112
- | **applyBatch + clear — 10 highlights, medium** | **2,308** | **0.433ms** | **2.156ms** |
113
- | **applyBatch + clear — 50 highlights, large** | **660** | **1.515ms** | **5.350ms** |
114
-
115
- ## Key Bottlenecks (from analysis)
116
-
117
- 1. **All Highlights Painted** is the critical metric: 886ms (medium), 3,247ms (large)
118
- - Dominated by: react-markdown parse → React reconcile → rAF → TreeWalker → Worker → TreeWalker → DOM surgery
119
- 2. **Tab switch** (414ms) is highlight re-application on a new document
120
- 3. **Large doc scroll** shows 3 long tasks (106-121ms) — likely margin note position recalculation or highlight intersection
121
- 4. **Bundle**: 667KB main + lazy mermaid (1MB+) means slow cold loads on constrained networks
122
-
123
- ## Optimization Targets
124
-
125
- | Change | Metric to Watch | Current | Goal |
126
- |--------|----------------|---------|------|
127
- | Server-side MD rendering | FCP, All Highlights Painted | 886ms / 3,247ms | <100ms / <500ms |
128
- | CSS Custom Highlight API | All Highlights Painted, Add Comment | 886ms / 98ms | <100ms / <20ms |
129
- | Eliminate SPA waterfall | FCP | 112ms / 368ms | <30ms |
130
- | Drop heavy client deps | Bundle size (main JS) | 667KB | <50KB |