@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
@@ -1,357 +0,0 @@
1
- import {
2
- existsSync,
3
- mkdirSync,
4
- readFileSync,
5
- rmSync,
6
- writeFileSync,
7
- } from "node:fs";
8
- import * as os from "node:os";
9
- import { dirname, join, resolve } from "node:path";
10
- import { expect, test } from "@playwright/test";
11
- import { spawnCli } from "./utils/cli";
12
- import { addComment, selectTextInArticle } from "./utils/selection";
13
-
14
- const FIXTURES_DIR = resolve(import.meta.dirname, "fixtures");
15
-
16
- /**
17
- * Get the expected comment file path for a source file.
18
- */
19
- function getCommentPath(sourcePath: string): string {
20
- const absolute = resolve(sourcePath);
21
- const normalized = absolute.replace(/^\//, "").replace(/^[A-Z]:[\\/]/, "");
22
- const ext = normalized.lastIndexOf(".");
23
- const withoutExt = ext > 0 ? normalized.slice(0, ext) : normalized;
24
- return join(os.homedir(), ".readit", "comments", `${withoutExt}.comments.md`);
25
- }
26
-
27
- /**
28
- * Clean up comment file for a source file.
29
- */
30
- function cleanupCommentFile(sourcePath: string): void {
31
- const commentPath = getCommentPath(sourcePath);
32
- if (existsSync(commentPath)) {
33
- rmSync(commentPath);
34
- }
35
- }
36
-
37
- test.describe("File-Based Comment Persistence", () => {
38
- const sampleMdPath = resolve(FIXTURES_DIR, "sample.md");
39
-
40
- test.beforeEach(() => {
41
- // Clean up any existing comment file before each test
42
- cleanupCommentFile(sampleMdPath);
43
- });
44
-
45
- test.afterEach(() => {
46
- // Clean up after each test
47
- cleanupCommentFile(sampleMdPath);
48
- });
49
-
50
- test("comments are saved to markdown file", async ({ page }) => {
51
- const { url, cleanup } = await spawnCli(sampleMdPath, {
52
- port: 4590,
53
- clean: false,
54
- });
55
-
56
- try {
57
- await page.goto(url);
58
-
59
- // Wait for document to load
60
- const article = page.locator("article#document-content");
61
- await expect(article).toBeVisible();
62
-
63
- // Add a comment
64
- const textToSelect = "testing text selection";
65
- await selectTextInArticle(page, textToSelect);
66
-
67
- const commentText = "This is a test comment for file persistence";
68
- await addComment(page, commentText);
69
-
70
- // Wait for comment to be visible in UI
71
- await expect(page.locator("body")).toContainText(commentText);
72
-
73
- // Give time for the file to be written
74
- await page.waitForTimeout(500);
75
-
76
- // Verify the comment file was created
77
- const commentPath = getCommentPath(sampleMdPath);
78
- expect(existsSync(commentPath)).toBe(true);
79
-
80
- // Verify the file contains the comment
81
- const fileContent = readFileSync(commentPath, "utf-8");
82
- expect(fileContent).toContain(textToSelect);
83
- expect(fileContent).toContain(commentText);
84
- expect(fileContent).toContain("version: 1");
85
- } finally {
86
- await cleanup();
87
- }
88
- });
89
-
90
- test("comments persist across page reload", async ({ page }) => {
91
- const { url, cleanup } = await spawnCli(sampleMdPath, {
92
- port: 4591,
93
- clean: false,
94
- });
95
-
96
- try {
97
- await page.goto(url);
98
-
99
- const article = page.locator("article#document-content");
100
- await expect(article).toBeVisible();
101
-
102
- // Add a comment
103
- const textToSelect = "testing text selection";
104
- await selectTextInArticle(page, textToSelect);
105
-
106
- const commentText = "Persistent comment test";
107
- await addComment(page, commentText);
108
-
109
- // Wait for comment to appear
110
- await expect(page.locator("body")).toContainText(commentText);
111
-
112
- // Reload the page
113
- await page.reload();
114
-
115
- // Wait for document to reload
116
- await expect(article).toBeVisible();
117
-
118
- // Verify comment still exists after reload
119
- await expect(page.locator("body")).toContainText(commentText);
120
-
121
- // Verify highlight still exists
122
- await page.waitForFunction(
123
- () => {
124
- const h = (window as unknown as Record<string, unknown>)
125
- .__readitHighlights as { commentIds: string[] } | undefined;
126
- return h && h.commentIds.length > 0;
127
- },
128
- { timeout: 10_000 },
129
- );
130
- } finally {
131
- await cleanup();
132
- }
133
- });
134
-
135
- test("comments persist across server restart", async ({ page }) => {
136
- const PORT = 4592;
137
-
138
- // First session: add a comment
139
- const { url: url1, cleanup: cleanup1 } = await spawnCli(sampleMdPath, {
140
- port: PORT,
141
- clean: false,
142
- });
143
-
144
- const commentText = "Comment that survives restart";
145
-
146
- try {
147
- await page.goto(url1);
148
-
149
- const article = page.locator("article#document-content");
150
- await expect(article).toBeVisible();
151
-
152
- await selectTextInArticle(page, "testing text selection");
153
- await addComment(page, commentText);
154
-
155
- // Wait for comment to appear
156
- await expect(page.locator("body")).toContainText(commentText);
157
- } finally {
158
- await cleanup1();
159
- }
160
-
161
- // Wait for server to fully shut down
162
- await page.waitForTimeout(1000);
163
-
164
- // Second session: verify comment persists
165
- const { url: url2, cleanup: cleanup2 } = await spawnCli(sampleMdPath, {
166
- port: PORT,
167
- clean: false,
168
- });
169
-
170
- try {
171
- await page.goto(url2);
172
-
173
- const article = page.locator("article#document-content");
174
- await expect(article).toBeVisible();
175
-
176
- // Comment should still exist from previous session
177
- await expect(page.locator("body")).toContainText(commentText);
178
-
179
- // Highlight should still exist
180
- await page.waitForFunction(
181
- () => {
182
- const h = (window as unknown as Record<string, unknown>)
183
- .__readitHighlights as { commentIds: string[] } | undefined;
184
- return h && h.commentIds.length > 0;
185
- },
186
- { timeout: 10_000 },
187
- );
188
- } finally {
189
- await cleanup2();
190
- }
191
- });
192
-
193
- test("--clean flag deletes comment file", async ({ page }) => {
194
- const PORT = 4593;
195
-
196
- // First, create a comment file manually
197
- const commentPath = getCommentPath(sampleMdPath);
198
- const commentDir = dirname(commentPath);
199
- mkdirSync(commentDir, { recursive: true });
200
- writeFileSync(
201
- commentPath,
202
- `---
203
- source: ${sampleMdPath}
204
- hash: abc123
205
- version: 1
206
- ---
207
-
208
- <!-- c:12345678|L5|2024-12-24T10:00:00Z -->
209
- > testing text selection
210
-
211
- Pre-existing comment to be cleared.
212
-
213
- ---
214
- `,
215
- "utf-8",
216
- );
217
-
218
- expect(existsSync(commentPath)).toBe(true);
219
-
220
- // Start server with --clean flag
221
- const { url, cleanup } = await spawnCli(sampleMdPath, {
222
- port: PORT,
223
- clean: true,
224
- });
225
-
226
- try {
227
- await page.goto(url);
228
-
229
- const article = page.locator("article#document-content");
230
- await expect(article).toBeVisible();
231
-
232
- // Wait for clean operation to complete
233
- await page.waitForTimeout(500);
234
-
235
- // Verify no highlights via observability hook
236
- const highlightCount = await page.evaluate(() => {
237
- const h = (window as unknown as Record<string, unknown>)
238
- .__readitHighlights as { commentIds: string[] } | undefined;
239
- return h?.commentIds?.length ?? 0;
240
- });
241
- expect(highlightCount).toBe(0);
242
- } finally {
243
- await cleanup();
244
- }
245
- });
246
-
247
- test("edit updates the comment file", async ({ page }) => {
248
- const { url, cleanup } = await spawnCli(sampleMdPath, {
249
- port: 4594,
250
- clean: false,
251
- });
252
-
253
- try {
254
- await page.goto(url);
255
-
256
- const article = page.locator("article#document-content");
257
- await expect(article).toBeVisible();
258
-
259
- // Add initial comment
260
- const textToSelect = "testing text selection";
261
- await selectTextInArticle(page, textToSelect);
262
- const initialComment = "Initial comment text";
263
- await addComment(page, initialComment);
264
-
265
- await expect(page.locator("body")).toContainText(initialComment);
266
-
267
- // Wait for file to be written
268
- await page.waitForTimeout(500);
269
-
270
- // Verify initial comment in file
271
- const commentPath = getCommentPath(sampleMdPath);
272
- let fileContent = readFileSync(commentPath, "utf-8");
273
- expect(fileContent).toContain(initialComment);
274
-
275
- // Find the margin note by data-comment-id (first one)
276
- const marginNote = page.locator("[data-comment-id]").first();
277
-
278
- // Force-click edit button (may be hidden behind opacity-0 group-hover)
279
- const editButton = marginNote.getByText("Edit").first();
280
- await editButton.click({ force: true });
281
-
282
- // Wait for edit mode — find textarea globally since hasText filter breaks in edit mode
283
- const textarea = page.locator("[data-comment-id] textarea");
284
- await expect(textarea).toBeVisible();
285
-
286
- // Clear and type new text
287
- await textarea.fill("Updated comment text");
288
-
289
- // Save edit
290
- const saveButton = page
291
- .locator("[data-comment-id]")
292
- .getByText("Save")
293
- .first();
294
- await saveButton.click();
295
-
296
- // Wait for file to be updated
297
- await page.waitForTimeout(500);
298
-
299
- // Verify updated comment in file
300
- fileContent = readFileSync(commentPath, "utf-8");
301
- expect(fileContent).toContain("Updated comment text");
302
- } finally {
303
- await cleanup();
304
- }
305
- });
306
-
307
- test("delete removes comment from file", async ({ page }) => {
308
- const { url, cleanup } = await spawnCli(sampleMdPath, {
309
- port: 4595,
310
- clean: false,
311
- });
312
-
313
- try {
314
- await page.goto(url);
315
-
316
- const article = page.locator("article#document-content");
317
- await expect(article).toBeVisible();
318
-
319
- // Add a comment
320
- await selectTextInArticle(page, "testing text selection");
321
- const commentText = "Comment to be deleted";
322
- await addComment(page, commentText);
323
-
324
- await expect(page.locator("body")).toContainText(commentText);
325
-
326
- // Wait for file to be written
327
- await page.waitForTimeout(500);
328
-
329
- // Verify comment in file
330
- const commentPath = getCommentPath(sampleMdPath);
331
- let fileContent = readFileSync(commentPath, "utf-8");
332
- expect(fileContent).toContain(commentText);
333
-
334
- // Find the margin note containing the comment
335
- const marginNote = page
336
- .locator(".group")
337
- .filter({ hasText: commentText })
338
- .first();
339
- await marginNote.hover();
340
-
341
- // Click delete button
342
- const deleteButton = marginNote.locator('button:has-text("Delete")');
343
- await deleteButton.click();
344
-
345
- // Wait for file to be updated
346
- await page.waitForTimeout(500);
347
-
348
- // Verify comment removed from file (file may be deleted if no comments left)
349
- if (existsSync(commentPath)) {
350
- fileContent = readFileSync(commentPath, "utf-8");
351
- expect(fileContent).not.toContain(commentText);
352
- }
353
- } finally {
354
- await cleanup();
355
- }
356
- });
357
- });
package/e2e/utils/cli.ts DELETED
@@ -1,84 +0,0 @@
1
- import type { ChildProcess } from "node:child_process";
2
- import { spawn } from "node:child_process";
3
- import { resolve } from "node:path";
4
-
5
- interface SpawnCliResult {
6
- url: string;
7
- process: ChildProcess;
8
- cleanup: () => Promise<void>;
9
- }
10
-
11
- interface SpawnCliOptions {
12
- port?: number;
13
- clean?: boolean;
14
- }
15
-
16
- const CLI_PATH = resolve(import.meta.dirname, "../../dist/index.js");
17
-
18
- export async function spawnCli(
19
- fixturePath: string,
20
- options: SpawnCliOptions = {},
21
- ): Promise<SpawnCliResult> {
22
- const { port = 4567, clean = true } = options;
23
-
24
- const args = [CLI_PATH, fixturePath, "--no-open", "--port", String(port)];
25
- if (clean) {
26
- args.push("--clean");
27
- }
28
-
29
- const cliProcess = spawn("bun", args, {
30
- cwd: resolve(import.meta.dirname, "../.."),
31
- stdio: ["pipe", "pipe", "pipe"],
32
- });
33
-
34
- const url = await waitForServerReady(cliProcess);
35
-
36
- return {
37
- url,
38
- process: cliProcess,
39
- cleanup: async () => {
40
- cliProcess.kill("SIGTERM");
41
- await new Promise<void>((resolve) => {
42
- cliProcess.once("exit", () => resolve());
43
- setTimeout(resolve, 1000); // Fallback timeout
44
- });
45
- },
46
- };
47
- }
48
-
49
- function waitForServerReady(cliProcess: ChildProcess): Promise<string> {
50
- return new Promise((resolve, reject) => {
51
- let output = "";
52
-
53
- const timeout = setTimeout(() => {
54
- reject(new Error("Server did not start within timeout"));
55
- }, 10_000);
56
-
57
- cliProcess.stdout?.on("data", (data: Buffer) => {
58
- output += data.toString();
59
-
60
- // Look for "URL: http://..." in output
61
- const urlMatch = output.match(/URL:\s+(http:\/\/[^\s]+)/);
62
- if (urlMatch) {
63
- clearTimeout(timeout);
64
- resolve(urlMatch[1]);
65
- }
66
- });
67
-
68
- cliProcess.stderr?.on("data", (data: Buffer) => {
69
- console.error("[CLI stderr]", data.toString());
70
- });
71
-
72
- cliProcess.on("error", (err) => {
73
- clearTimeout(timeout);
74
- reject(err);
75
- });
76
-
77
- cliProcess.on("exit", (code) => {
78
- if (code !== 0 && code !== null) {
79
- clearTimeout(timeout);
80
- reject(new Error(`CLI exited with code ${code}: ${output}`));
81
- }
82
- });
83
- });
84
- }
@@ -1,79 +0,0 @@
1
- import type { Page } from "@playwright/test";
2
-
3
- /**
4
- * Wait for the Svelte app to be fully mounted and interactive.
5
- * The app sets data-readit-ready="true" on <html> after onMount.
6
- */
7
- export async function waitForAppReady(page: Page): Promise<void> {
8
- await page.waitForFunction(
9
- () => document.documentElement.dataset.readitReady === "true",
10
- { timeout: 10_000 },
11
- );
12
- }
13
-
14
- /**
15
- * Select text within an article element (for markdown documents)
16
- * Uses custom event to trigger selection handler (workaround for Playwright mouse issues)
17
- */
18
- export async function selectTextInArticle(
19
- page: Page,
20
- textToSelect: string,
21
- ): Promise<void> {
22
- // Ensure the Svelte app is fully mounted before dispatching events
23
- await waitForAppReady(page);
24
-
25
- // Find text and calculate offsets, then dispatch custom event
26
- await page.evaluate((text) => {
27
- const article = document.querySelector("article#document-content");
28
- if (!article) throw new Error("Article element not found");
29
-
30
- const walker = document.createTreeWalker(article, NodeFilter.SHOW_TEXT);
31
- let currentOffset = 0;
32
-
33
- while (walker.nextNode()) {
34
- const textNode = walker.currentNode as Text;
35
- const content = textNode.textContent || "";
36
- const index = content.indexOf(text);
37
-
38
- if (index !== -1) {
39
- const startOffset = currentOffset + index;
40
- const endOffset = startOffset + text.length;
41
-
42
- // Dispatch custom event that DocumentViewer listens for
43
- const event = new CustomEvent("test:select-text", {
44
- detail: { text, startOffset, endOffset },
45
- });
46
- window.dispatchEvent(event);
47
- return;
48
- }
49
-
50
- currentOffset += content.length;
51
- }
52
-
53
- throw new Error(`Text "${text}" not found in article`);
54
- }, textToSelect);
55
-
56
- // Wait for Svelte to process the selection
57
- await page.waitForTimeout(100);
58
- }
59
-
60
- /**
61
- * Add a comment to the current selection
62
- * Assumes CommentInputArea is visible
63
- */
64
- export async function addComment(
65
- page: Page,
66
- commentText: string,
67
- ): Promise<void> {
68
- const textarea = page.locator('textarea[placeholder="Add your comment..."]');
69
- await textarea.waitFor({ state: "visible", timeout: 10000 });
70
-
71
- // Fill in the comment
72
- await textarea.fill(commentText);
73
-
74
- // Click the Add button
75
- await page.getByRole("button", { name: "Add" }).click();
76
-
77
- // Wait for the textarea to disappear (comment submitted)
78
- await textarea.waitFor({ state: "hidden", timeout: 5000 });
79
- }