@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,86 +0,0 @@
1
- # Client Mode: `readit open`
2
-
3
- ## Problem
4
-
5
- readit starts a long-running server per invocation. When used as a Claude Code PostToolUse hook, every Write/Edit on a `.md` file would spawn a new server instance. We need a way to send files to an already-running server.
6
-
7
- ## Design
8
-
9
- ### Overview
10
-
11
- Add a `readit open <files...>` CLI command that hot-adds files to a running readit server via HTTP, or starts a new server if none exists. Uses a PID file for server discovery and the existing SSE infrastructure for browser notifications.
12
-
13
- ### 1. PID File (`~/.readit/server.json`)
14
-
15
- **On server start** (in `startServer`):
16
- ```json
17
- { "port": 4567, "pid": 12345 }
18
- ```
19
-
20
- **On shutdown** (SIGINT handler): delete the file.
21
-
22
- **Client discovery:**
23
- 1. Read `~/.readit/server.json`
24
- 2. Verify PID is alive (`process.kill(pid, 0)`)
25
- 3. Confirm via `GET /api/health`
26
- 4. Any failure → treat as no server running
27
-
28
- ### 2. Server Endpoint: `POST /api/files`
29
-
30
- Request body: `{ "path": "/absolute/path/to/file.md" }`
31
-
32
- Behavior:
33
- - **File already loaded** → re-read from disk, update `fileMap` content, broadcast SSE `{ type: "update", path }`
34
- - **New file** → validate type, read content, add to `fileMap` + `fileOrder`, set up file watcher, broadcast SSE `{ type: "file-added", path, fileName, fileType }`
35
-
36
- Response: `200 { path, fileName, type }`
37
-
38
- ### 3. Frontend: Handle `file-added` SSE Event
39
-
40
- The Zustand store's SSE listener handles a new event type:
41
- - `file-added` → add document to store, render new tab (lazy content fetch via existing pattern)
42
-
43
- ### 4. CLI Command: `readit open`
44
-
45
- ```
46
- readit open <files...> # Add files to running server or start new one
47
- ```
48
-
49
- Logic:
50
- 1. Resolve and validate file paths (must exist, must be supported type)
51
- 2. Discover running server via PID file + health check
52
- 3. If server found → `POST /api/files` for each file
53
- 4. If no server → start server in foreground with the given files (same as default command)
54
-
55
- ### 5. Hook Configuration
56
-
57
- ```json
58
- {
59
- "PostToolUse": [
60
- {
61
- "matcher": "Write|Edit",
62
- "hooks": [
63
- {
64
- "type": "command",
65
- "command": "bash -c 'FILE=$(cat | jq -r \".tool_input.file_path\"); if [[ \"$FILE\" == *.md ]]; then bunx readit open \"$FILE\"; fi; exit 0'"
66
- }
67
- ]
68
- }
69
- ]
70
- }
71
- ```
72
-
73
- ## Files to Modify
74
-
75
- - `src/server/index.ts` — PID file write/cleanup, `POST /api/files` endpoint, file watcher setup for hot-added files
76
- - `src/cli/index.ts` — new `open` subcommand with server discovery logic
77
- - Frontend store — handle `file-added` SSE event type
78
-
79
- ## Verification
80
-
81
- 1. Start `readit test.md`
82
- 2. Run `readit open other.md` in another terminal
83
- 3. Confirm new tab appears in browser with `other.md`
84
- 4. Edit `other.md` on disk → confirm live reload works
85
- 5. Kill server, run `readit open test.md` → confirm new server starts
86
- 6. Run `readit open test.md` again (already loaded) → confirm content refreshes without duplicate tab
@@ -1,605 +0,0 @@
1
- # Client Mode (`readit open`) Implementation Plan
2
-
3
- > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
4
-
5
- **Goal:** Add a `readit open` CLI command that hot-adds files to a running readit server, or starts a new one if none exists.
6
-
7
- **Architecture:** PID file (`~/.readit/server.json`) for server discovery. New `POST /api/files` endpoint on the existing Bun.serve() for hot-adding files. Existing SSE infrastructure broadcasts `file-added` events to the frontend. Extract `getFileType` to shared lib to avoid duplication.
8
-
9
- **Tech Stack:** Bun, Commander.js, existing SSE, Zustand store
10
-
11
- ---
12
-
13
- ### Task 1: Extract `getFileType` to shared lib
14
-
15
- `getFileType` is currently defined in `src/cli/index.ts` and will be needed in both CLI and server code.
16
-
17
- **Files:**
18
- - Modify: `src/lib/utils.ts`
19
- - Modify: `src/cli/index.ts`
20
-
21
- **Step 1: Add `getFileType` to `src/lib/utils.ts`**
22
-
23
- ```ts
24
- import type { DocumentType } from "../types";
25
-
26
- export function getFileType(filePath: string): DocumentType | null {
27
- if (filePath.endsWith(".md") || filePath.endsWith(".markdown")) {
28
- return "markdown";
29
- }
30
- if (filePath.endsWith(".html") || filePath.endsWith(".htm")) {
31
- return "html";
32
- }
33
- return null;
34
- }
35
- ```
36
-
37
- **Step 2: Update `src/cli/index.ts` to import from shared lib**
38
-
39
- Replace the local `getFileType` function with:
40
- ```ts
41
- import { getFileType } from "../lib/utils.js";
42
- ```
43
-
44
- Remove the local `getFileType` function definition (lines 22-30).
45
-
46
- **Step 3: Verify build passes**
47
-
48
- Run: `bun run typecheck`
49
- Expected: No errors
50
-
51
- **Step 4: Commit**
52
-
53
- ```bash
54
- git add src/lib/utils.ts src/cli/index.ts
55
- git commit -m "refactor: extract getFileType to shared lib"
56
- ```
57
-
58
- ---
59
-
60
- ### Task 2: Add PID file write/cleanup to server
61
-
62
- **Files:**
63
- - Modify: `src/server/index.ts` — write `~/.readit/server.json` on start, delete on shutdown
64
- - Modify: `src/cli/index.ts` — clean up PID file in SIGINT handler
65
-
66
- **Step 1: Add PID file helpers to `src/server/index.ts`**
67
-
68
- Add near the top of the file, after the existing helpers:
69
-
70
- ```ts
71
- const SERVER_INFO_PATH = path.join(os.homedir(), ".readit", "server.json");
72
-
73
- async function writeServerInfo(port: number): Promise<void> {
74
- await fs.mkdir(path.dirname(SERVER_INFO_PATH), { recursive: true });
75
- await fs.writeFile(
76
- SERVER_INFO_PATH,
77
- JSON.stringify({ port, pid: process.pid }),
78
- "utf-8",
79
- );
80
- }
81
-
82
- async function removeServerInfo(): Promise<void> {
83
- try {
84
- await fs.unlink(SERVER_INFO_PATH);
85
- } catch (err) {
86
- if (!isErrnoException(err) || err.code !== "ENOENT") {
87
- console.error("Failed to remove server info:", err);
88
- }
89
- }
90
- }
91
- ```
92
-
93
- **Step 2: Call `writeServerInfo` at end of `startServer`**
94
-
95
- In the `startServer` function, after the server is successfully created, before the `return`:
96
-
97
- ```ts
98
- await writeServerInfo(actualPort);
99
- ```
100
-
101
- **Step 3: Export `removeServerInfo` and `SERVER_INFO_PATH`**
102
-
103
- Export both so the CLI can use them in its SIGINT handler:
104
-
105
- ```ts
106
- export { SERVER_INFO_PATH, removeServerInfo };
107
- ```
108
-
109
- **Step 4: Update SIGINT handler in `src/cli/index.ts`**
110
-
111
- ```ts
112
- import { removeServerInfo } from "../server/index.js";
113
-
114
- // In the SIGINT handler:
115
- process.on("SIGINT", async () => {
116
- console.log("\n\nShutting down...");
117
- server.stop();
118
- await removeServerInfo();
119
- process.exit(0);
120
- });
121
- ```
122
-
123
- **Step 5: Verify build passes**
124
-
125
- Run: `bun run typecheck`
126
- Expected: No errors
127
-
128
- **Step 6: Commit**
129
-
130
- ```bash
131
- git add src/server/index.ts src/cli/index.ts
132
- git commit -m "feat: write/cleanup PID file on server start/stop"
133
- ```
134
-
135
- ---
136
-
137
- ### Task 3: Add `POST /api/files` endpoint to server
138
-
139
- This endpoint hot-adds or refreshes files in a running server.
140
-
141
- **Files:**
142
- - Modify: `src/server/index.ts`
143
-
144
- **Step 1: Extract watcher setup into a reusable function**
145
-
146
- The file watcher logic (lines 686-719) needs to be callable for hot-added files too. Extract it within `createServer`:
147
-
148
- ```ts
149
- function watchFile(filePath: string): FSWatcher | null {
150
- try {
151
- const watcher = watch(filePath, async (eventType) => {
152
- if (eventType !== "change") return;
153
-
154
- const state = fileMap.get(filePath);
155
- if (!state) return;
156
-
157
- if (state.debounceTimer) clearTimeout(state.debounceTimer);
158
- state.debounceTimer = setTimeout(async () => {
159
- try {
160
- const newContent = await fs.readFile(filePath, "utf-8");
161
- if (newContent !== state.content) {
162
- state.content = newContent;
163
- console.log(`File changed: ${basename(filePath)}`);
164
-
165
- const message = `data: ${JSON.stringify({ type: "update", path: filePath })}\n\n`;
166
- for (const controller of sseClients) {
167
- try {
168
- controller.enqueue(message);
169
- } catch {
170
- sseClients.delete(controller);
171
- }
172
- }
173
- }
174
- } catch (err) {
175
- console.error(`Failed to read updated file ${filePath}:`, err);
176
- }
177
- }, 100);
178
- });
179
- return watcher;
180
- } catch (err) {
181
- console.warn(`File watching not available for ${filePath}:`, err);
182
- return null;
183
- }
184
- }
185
- ```
186
-
187
- Replace the inline watcher loop with:
188
- ```ts
189
- for (const filePath of fileOrder) {
190
- const watcher = watchFile(filePath);
191
- if (watcher) watchers.push(watcher);
192
- }
193
- ```
194
-
195
- **Step 2: Add `POST /api/files` route**
196
-
197
- Add inside the `fetch` handler in `createServer`, after the `/api/documents` route:
198
-
199
- ```ts
200
- if (pathname === "/api/files" && method === "POST") {
201
- try {
202
- const { path: requestedPath } = await req.json();
203
-
204
- if (!requestedPath || typeof requestedPath !== "string") {
205
- return errorResponse("Missing 'path' field", 400);
206
- }
207
-
208
- const filePath = path.resolve(requestedPath);
209
- const fileType = getFileType(filePath);
210
-
211
- if (!fileType) {
212
- return errorResponse(
213
- `Unsupported file type: ${filePath} (expected .md, .markdown, .html, or .htm)`,
214
- 400,
215
- );
216
- }
217
-
218
- let content: string;
219
- try {
220
- content = await fs.readFile(filePath, "utf-8");
221
- } catch (err) {
222
- if (isErrnoException(err) && err.code === "ENOENT") {
223
- return errorResponse(`File not found: ${filePath}`, 404);
224
- }
225
- throw err;
226
- }
227
-
228
- const existingState = fileMap.get(filePath);
229
-
230
- if (existingState) {
231
- // File already loaded — refresh content
232
- existingState.content = content;
233
- const message = `data: ${JSON.stringify({ type: "update", path: filePath })}\n\n`;
234
- for (const controller of sseClients) {
235
- try {
236
- controller.enqueue(message);
237
- } catch {
238
- sseClients.delete(controller);
239
- }
240
- }
241
- } else {
242
- // New file — add to server
243
- fileMap.set(filePath, {
244
- content,
245
- type: fileType,
246
- debounceTimer: null,
247
- });
248
- fileOrder.push(filePath);
249
-
250
- // Set up file watcher for the new file
251
- const watcher = watchFile(filePath);
252
- if (watcher) watchers.push(watcher);
253
-
254
- const message = `data: ${JSON.stringify({
255
- type: "file-added",
256
- path: filePath,
257
- fileName: basename(filePath),
258
- fileType,
259
- })}\n\n`;
260
- for (const controller of sseClients) {
261
- try {
262
- controller.enqueue(message);
263
- } catch {
264
- sseClients.delete(controller);
265
- }
266
- }
267
- }
268
-
269
- return json({
270
- path: filePath,
271
- fileName: basename(filePath),
272
- type: fileType,
273
- });
274
- } catch (err) {
275
- console.error("Failed to add file:", err);
276
- return errorResponse("Failed to add file", 500);
277
- }
278
- }
279
- ```
280
-
281
- **Step 3: Add the `getFileType` import**
282
-
283
- ```ts
284
- import { getFileType } from "../lib/utils.js";
285
- ```
286
-
287
- **Step 4: Verify build passes**
288
-
289
- Run: `bun run typecheck`
290
- Expected: No errors
291
-
292
- **Step 5: Commit**
293
-
294
- ```bash
295
- git add src/server/index.ts
296
- git commit -m "feat: add POST /api/files endpoint for hot-adding files"
297
- ```
298
-
299
- ---
300
-
301
- ### Task 4: Handle `file-added` SSE event in frontend
302
-
303
- **Files:**
304
- - Modify: `src/hooks/useDocument.ts`
305
-
306
- **Step 1: Add `file-added` handling to SSE listener**
307
-
308
- In the `eventSource.onmessage` handler (around line 90), add a branch for `file-added`:
309
-
310
- ```ts
311
- eventSource.onmessage = async (e) => {
312
- try {
313
- const data = JSON.parse(e.data);
314
-
315
- if (data.type === "file-added" && data.path) {
316
- appStore.getState().openDocument({
317
- content: "", // Lazy-loaded when tab activated
318
- type: data.fileType,
319
- filePath: data.path,
320
- fileName: data.fileName,
321
- clean: false,
322
- });
323
- return;
324
- }
325
-
326
- if (data.type === "update" && data.path) {
327
- // ... existing update logic unchanged
328
- }
329
- } catch {
330
- // Ignore non-JSON messages ("connected", "ping")
331
- }
332
- };
333
- ```
334
-
335
- **Step 2: Verify build passes**
336
-
337
- Run: `bun run typecheck`
338
- Expected: No errors
339
-
340
- **Step 3: Commit**
341
-
342
- ```bash
343
- git add src/hooks/useDocument.ts
344
- git commit -m "feat: handle file-added SSE event for hot-added documents"
345
- ```
346
-
347
- ---
348
-
349
- ### Task 5: Add `readit open` CLI command
350
-
351
- **Files:**
352
- - Modify: `src/cli/index.ts`
353
-
354
- **Step 1: Add server discovery function**
355
-
356
- Add after the imports:
357
-
358
- ```ts
359
- import { readFileSync as readFileSyncNode } from "node:fs";
360
-
361
- interface ServerInfo {
362
- port: number;
363
- pid: number;
364
- }
365
-
366
- async function discoverServer(): Promise<ServerInfo | null> {
367
- const serverInfoPath = join(os.homedir(), ".readit", "server.json");
368
-
369
- try {
370
- const content = readFileSyncNode(serverInfoPath, "utf-8");
371
- const info: ServerInfo = JSON.parse(content);
372
-
373
- // Verify the process is alive
374
- try {
375
- process.kill(info.pid, 0);
376
- } catch {
377
- return null;
378
- }
379
-
380
- // Verify health endpoint responds
381
- try {
382
- const res = await fetch(`http://127.0.0.1:${info.port}/api/health`);
383
- if (!res.ok) return null;
384
- } catch {
385
- return null;
386
- }
387
-
388
- return info;
389
- } catch {
390
- return null;
391
- }
392
- }
393
- ```
394
-
395
- **Step 2: Add `open` subcommand**
396
-
397
- Add before `program.parse()`:
398
-
399
- ```ts
400
- program
401
- .command("open")
402
- .argument("<files...>", "Markdown or HTML files to add to running server")
403
- .description("Add files to a running readit server, or start a new one")
404
- .option("-p, --port <number>", "Port for new server (if starting)", "4567")
405
- .option("--host <address>", "Host for new server (if starting)", "127.0.0.1")
406
- .action(
407
- async (
408
- fileArgs: string[],
409
- options: { port: string; host: string },
410
- ) => {
411
- // Resolve and validate files
412
- const resolvedFiles: { path: string; type: DocumentType }[] = [];
413
- for (const arg of fileArgs) {
414
- const filePath = resolve(process.cwd(), arg);
415
-
416
- if (!existsSync(filePath)) {
417
- console.error(`error: not found: ${filePath}`);
418
- process.exit(1);
419
- }
420
-
421
- const type = getFileType(filePath);
422
- if (!type) {
423
- console.error(
424
- `error: unsupported file type: ${arg} (expected .md, .markdown, .html, or .htm)`,
425
- );
426
- process.exit(1);
427
- }
428
-
429
- resolvedFiles.push({ path: filePath, type });
430
- }
431
-
432
- // Try to find running server
433
- const server = await discoverServer();
434
-
435
- if (server) {
436
- // Send files to running server
437
- for (const file of resolvedFiles) {
438
- try {
439
- const res = await fetch(
440
- `http://127.0.0.1:${server.port}/api/files`,
441
- {
442
- method: "POST",
443
- headers: { "Content-Type": "application/json" },
444
- body: JSON.stringify({ path: file.path }),
445
- },
446
- );
447
-
448
- if (!res.ok) {
449
- const data = await res.json();
450
- console.error(
451
- `error: failed to add ${file.path}: ${data.error}`,
452
- );
453
- process.exit(1);
454
- }
455
-
456
- const data = await res.json();
457
- console.log(`Added: ${data.fileName} (${data.type})`);
458
- } catch (err) {
459
- console.error(
460
- `error: failed to connect to server:`,
461
- err instanceof Error ? err.message : err,
462
- );
463
- process.exit(1);
464
- }
465
- }
466
-
467
- console.log(
468
- `\nServer: http://127.0.0.1:${server.port}`,
469
- );
470
- return;
471
- }
472
-
473
- // No running server — start one
474
- console.log("No running server found, starting new one...\n");
475
-
476
- const files = resolvedFiles.map((f) => ({
477
- content: readFileSync(f.path, "utf-8"),
478
- type: f.type,
479
- filePath: f.path,
480
- }));
481
-
482
- const preferredPort = Number.parseInt(options.port, 10);
483
- try {
484
- const { url, server: newServer } = await startServer({
485
- files,
486
- port: preferredPort,
487
- host: options.host,
488
- });
489
-
490
- const fileList = files.map((f) => ` ${f.filePath} (${f.type})`);
491
- console.log(`
492
- readit - Document Review Tool
493
-
494
- ${files.length === 1 ? "File:" : "Files:"}
495
- ${fileList.join("\n")}
496
- URL: ${url}
497
-
498
- Server running. Close browser tab to stop.
499
- Press Ctrl+C to force stop.
500
- `);
501
-
502
- open(url);
503
-
504
- process.on("SIGINT", async () => {
505
- console.log("\n\nShutting down...");
506
- newServer.stop();
507
- await removeServerInfo();
508
- process.exit(0);
509
- });
510
- } catch (error) {
511
- console.error(
512
- "error: failed to start server:",
513
- error instanceof Error ? error.message : error,
514
- );
515
- process.exit(1);
516
- }
517
- },
518
- );
519
- ```
520
-
521
- **Step 3: Add missing imports**
522
-
523
- Make sure these imports are at the top of the file:
524
-
525
- ```ts
526
- import { getFileType } from "../lib/utils.js";
527
- import { removeServerInfo } from "../server/index.js";
528
- import type { DocumentType } from "../types/index.js";
529
- ```
530
-
531
- **Step 4: Verify build passes**
532
-
533
- Run: `bun run typecheck`
534
- Expected: No errors
535
-
536
- **Step 5: Commit**
537
-
538
- ```bash
539
- git add src/cli/index.ts
540
- git commit -m "feat: add readit open command for client mode"
541
- ```
542
-
543
- ---
544
-
545
- ### Task 6: Update the hook configuration
546
-
547
- **Files:**
548
- - Modify: `/Users/jay/.claude/settings.json`
549
-
550
- **Step 1: Update the PostToolUse hook**
551
-
552
- Change the command from `open -a Arto` to `bunx readit open`:
553
-
554
- ```json
555
- "PostToolUse": [
556
- {
557
- "matcher": "Write|Edit",
558
- "hooks": [
559
- {
560
- "type": "command",
561
- "command": "bash -c 'FILE=$(cat | jq -r \".tool_input.file_path\"); if [[ \"$FILE\" == *.md ]]; then bunx readit open \"$FILE\"; fi; exit 0'"
562
- }
563
- ]
564
- }
565
- ]
566
- ```
567
-
568
- **Step 2: Verify the hook fires correctly**
569
-
570
- Write or edit any `.md` file and confirm the hook runs without error.
571
-
572
- ---
573
-
574
- ### Task 7: End-to-end verification
575
-
576
- **Step 1: Build the project**
577
-
578
- Run: `bun run build`
579
- Expected: Successful build
580
-
581
- **Step 2: Start server with a test file**
582
-
583
- Run: `bunx readit test.md`
584
- Expected: Server starts, browser opens
585
-
586
- **Step 3: Open another file via client mode**
587
-
588
- In another terminal:
589
- Run: `bunx readit open README.md`
590
- Expected: "Added: README.md (markdown)" printed, new tab appears in browser
591
-
592
- **Step 4: Verify live reload for hot-added file**
593
-
594
- Edit `README.md` on disk, confirm the browser updates automatically.
595
-
596
- **Step 5: Verify reload for already-loaded file**
597
-
598
- Run: `bunx readit open test.md`
599
- Expected: Content refreshes, no duplicate tab
600
-
601
- **Step 6: Verify auto-start when no server running**
602
-
603
- Stop the server (Ctrl+C), then:
604
- Run: `bunx readit open test.md`
605
- Expected: New server starts with `test.md`