@peaske7/readit 0.2.1 → 0.3.0-rc.1
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.
- package/dist/.vite/manifest.json +1111 -0
- package/dist/assets/_basePickBy-BMMA4Tou.js +1 -0
- package/dist/assets/_baseUniq-D40qku1I.js +1 -0
- package/dist/assets/arc-Ckg65iy8.js +1 -0
- package/dist/assets/architecture-YZFGNWBL-Dv3EY0zV.js +1 -0
- package/dist/assets/architectureDiagram-Q4EWVU46-ClRss4cm.js +36 -0
- package/dist/assets/array-Bjz-wYpJ.js +1 -0
- package/dist/assets/blockDiagram-DXYQGD6D-CBcFvoK1.js +132 -0
- package/dist/assets/c4Diagram-AHTNJAMY-D4d3ZLam.js +10 -0
- package/dist/assets/channel-D9EJxDy_.js +1 -0
- package/dist/assets/chunk-2KRD3SAO-DaFfaCGO.js +1 -0
- package/dist/assets/chunk-336JU56O-yLEQoF0v.js +2 -0
- package/dist/assets/chunk-426QAEUC-Uyzd4wAA.js +1 -0
- package/dist/assets/chunk-4BX2VUAB-DRuTD7x5.js +1 -0
- package/dist/assets/chunk-4TB4RGXK-3xbpIi_o.js +206 -0
- package/dist/assets/chunk-55IACEB6-BExiaAoD.js +1 -0
- package/dist/assets/chunk-5FUZZQ4R-DatVvHnF.js +62 -0
- package/dist/assets/chunk-5PVQY5BW-BKgvrGh8.js +2 -0
- package/dist/assets/chunk-67CJDMHE-DMt8LNEX.js +1 -0
- package/dist/assets/chunk-7N4EOEYR-CzLGefVf.js +1 -0
- package/dist/assets/chunk-AA7GKIK3-B6GFAk4U.js +1 -0
- package/dist/assets/chunk-BSJP7CBP-BK29yehL.js +1 -0
- package/dist/assets/chunk-CIAEETIT-D7hBXImP.js +1 -0
- package/dist/assets/chunk-Dlc7tRH4.js +1 -0
- package/dist/assets/chunk-EDXVE4YY-PYJdlmyH.js +1 -0
- package/dist/assets/chunk-ENJZ2VHE-DUHKBv6x.js +10 -0
- package/dist/assets/chunk-FMBD7UC4-2FWyCCAV.js +15 -0
- package/dist/assets/chunk-FOC6F5B3-DKFHrt4K.js +1 -0
- package/dist/assets/chunk-ICPOFSXX-Bh__D0ec.js +122 -0
- package/dist/assets/chunk-K5T4RW27-D51O7IkG.js +94 -0
- package/dist/assets/chunk-KGLVRYIC-DMHSCH4T.js +1 -0
- package/dist/assets/chunk-LIHQZDEY-C2aANxt9.js +1 -0
- package/dist/assets/chunk-ORNJ4GCN-Db_37NRX.js +1 -0
- package/dist/assets/chunk-OYMX7WX6-BltXOJLJ.js +231 -0
- package/dist/assets/chunk-QZHKN3VN-8Lcg9gti.js +1 -0
- package/dist/assets/chunk-U2HBQHQK-ByS6tilY.js +70 -0
- package/dist/assets/chunk-X2U36JSP-Bm-4Gqg_.js +1 -0
- package/dist/assets/chunk-XPW4576I-Bqbompq4.js +32 -0
- package/dist/assets/chunk-YZCP3GAM-CsC0imPb.js +1 -0
- package/dist/assets/chunk-ZZ45TVLE-CG-CqfPC.js +1 -0
- package/dist/assets/classDiagram-6PBFFD2Q-Jy1uFUk4.js +1 -0
- package/dist/assets/classDiagram-v2-HSJHXN6E-ChiLl3rR.js +1 -0
- package/dist/assets/clone-BBjvuERA.js +1 -0
- package/dist/assets/cose-bilkent-S5V4N54A-q90QeGKv.js +1 -0
- package/dist/assets/cytoscape.esm-BfXff3fb.js +321 -0
- package/dist/assets/dagre-KV5264BT-BQWiLFJB.js +4 -0
- package/dist/assets/dagre-nn_aIZ2E.js +1 -0
- package/dist/assets/defaultLocale-BwmRmqJp.js +1 -0
- package/dist/assets/diagram-5BDNPKRD-CJa7Y97H.js +10 -0
- package/dist/assets/diagram-G4DWMVQ6-tVQGBWfY.js +24 -0
- package/dist/assets/diagram-MMDJMWI5-CpimFldm.js +43 -0
- package/dist/assets/diagram-TYMM5635-D11WQVgy.js +24 -0
- package/dist/assets/dist-BNz65Ibc.js +1 -0
- package/dist/assets/erDiagram-SMLLAGMA-C2bLd0jS.js +85 -0
- package/dist/assets/flowDiagram-DWJPFMVM-Kw3fOOLT.js +162 -0
- package/dist/assets/ganttDiagram-T4ZO3ILL-fyMhyE2X.js +292 -0
- package/dist/assets/gitGraph-7Q5UKJZL-BGFRt2qs.js +1 -0
- package/dist/assets/gitGraphDiagram-UUTBAWPF-D4JoiOvg.js +106 -0
- package/dist/assets/graphlib-DGcD9J2L.js +1 -0
- package/dist/assets/index-Cow3qpoq.css +2 -0
- package/dist/assets/index-DUf7okYi.js +14 -0
- package/dist/assets/info-OMHHGYJF-DI6-Z9vh.js +1 -0
- package/dist/assets/infoDiagram-42DDH7IO-D1ZkeMBy.js +2 -0
- package/dist/assets/init-TPm5RB77.js +1 -0
- package/dist/assets/isArrayLikeObject-69BLnVNM.js +1 -0
- package/dist/assets/isEmpty-DUS28g5f.js +1 -0
- package/dist/assets/ishikawaDiagram-UXIWVN3A-Dv8hzjZB.js +70 -0
- package/dist/assets/journeyDiagram-VCZTEJTY-COeB7F5r.js +139 -0
- package/dist/assets/kanban-definition-6JOO6SKY-BbYmxCYU.js +89 -0
- package/dist/assets/katex-5SGEXwpi.js +261 -0
- package/dist/assets/line-_v2NGEdn.js +1 -0
- package/dist/assets/linear-CXMqTN8N.js +1 -0
- package/dist/assets/mermaid-config-C8a4L22x.js +1 -0
- package/dist/assets/mermaid-parser.core-CFmphzPP.js +4 -0
- package/dist/assets/mermaid.core-DnHAupTp.js +11 -0
- package/dist/assets/mindmap-definition-QFDTVHPH-D7_lIep7.js +96 -0
- package/dist/assets/ordinal-D7l-8DAO.js +1 -0
- package/dist/assets/packet-4T2RLAQJ-DidW3JFc.js +1 -0
- package/dist/assets/path-BVpCanzE.js +1 -0
- package/dist/assets/pie-ZZUOXDRM-Bff2e5hg.js +1 -0
- package/dist/assets/pieDiagram-DEJITSTG-DDvYHCT_.js +30 -0
- package/dist/assets/quadrantDiagram-34T5L4WZ-DcLcIrdi.js +7 -0
- package/dist/assets/radar-PYXPWWZC-CsdZBH3M.js +1 -0
- package/dist/assets/requirementDiagram-MS252O5E-DLX6ld7D.js +84 -0
- package/dist/assets/rough.esm-BoTisKeL.js +1 -0
- package/dist/assets/sankeyDiagram-XADWPNL6-D-1GtsHM.js +10 -0
- package/dist/assets/sequenceDiagram-FGHM5R23-Bwxs0YQg.js +157 -0
- package/dist/assets/src-CrmkjRpa.js +1 -0
- package/dist/assets/stateDiagram-FHFEXIEX-DW7rOcnQ.js +1 -0
- package/dist/assets/stateDiagram-v2-QKLJ7IA2-Jm-24vQ2.js +1 -0
- package/dist/assets/timeline-definition-GMOUNBTQ-DVdHyzxS.js +120 -0
- package/dist/assets/treeView-SZITEDCU-DPKseaET.js +1 -0
- package/dist/assets/treemap-W4RFUUIX-DH-7GZe_.js +1 -0
- package/dist/assets/vennDiagram-DHZGUBPP-DJaC6xmI.js +34 -0
- package/dist/assets/wardley-RL74JXVD-AgyXyBN5.js +1 -0
- package/dist/assets/wardleyDiagram-NUSXRM2D-CTKERPKv.js +20 -0
- package/dist/assets/xychartDiagram-5P7HB3ND-BuExiLXc.js +7 -0
- package/{index.html → dist/index.html} +2 -1
- package/dist/index.js +2539 -0
- package/package.json +11 -1
- package/.agents/skills/remotion-best-practices/SKILL.md +0 -61
- package/.agents/skills/remotion-best-practices/rules/3d.md +0 -86
- package/.agents/skills/remotion-best-practices/rules/animations.md +0 -27
- package/.agents/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx +0 -178
- package/.agents/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +0 -100
- package/.agents/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +0 -108
- package/.agents/skills/remotion-best-practices/rules/assets.md +0 -78
- package/.agents/skills/remotion-best-practices/rules/audio-visualization.md +0 -198
- package/.agents/skills/remotion-best-practices/rules/audio.md +0 -169
- package/.agents/skills/remotion-best-practices/rules/calculate-metadata.md +0 -134
- package/.agents/skills/remotion-best-practices/rules/can-decode.md +0 -75
- package/.agents/skills/remotion-best-practices/rules/charts.md +0 -120
- package/.agents/skills/remotion-best-practices/rules/compositions.md +0 -154
- package/.agents/skills/remotion-best-practices/rules/display-captions.md +0 -184
- package/.agents/skills/remotion-best-practices/rules/extract-frames.md +0 -229
- package/.agents/skills/remotion-best-practices/rules/ffmpeg.md +0 -38
- package/.agents/skills/remotion-best-practices/rules/fonts.md +0 -152
- package/.agents/skills/remotion-best-practices/rules/get-audio-duration.md +0 -58
- package/.agents/skills/remotion-best-practices/rules/get-video-dimensions.md +0 -68
- package/.agents/skills/remotion-best-practices/rules/get-video-duration.md +0 -60
- package/.agents/skills/remotion-best-practices/rules/gifs.md +0 -141
- package/.agents/skills/remotion-best-practices/rules/images.md +0 -134
- package/.agents/skills/remotion-best-practices/rules/import-srt-captions.md +0 -69
- package/.agents/skills/remotion-best-practices/rules/light-leaks.md +0 -73
- package/.agents/skills/remotion-best-practices/rules/lottie.md +0 -70
- package/.agents/skills/remotion-best-practices/rules/maps.md +0 -412
- package/.agents/skills/remotion-best-practices/rules/measuring-dom-nodes.md +0 -34
- package/.agents/skills/remotion-best-practices/rules/measuring-text.md +0 -140
- package/.agents/skills/remotion-best-practices/rules/parameters.md +0 -109
- package/.agents/skills/remotion-best-practices/rules/sequencing.md +0 -118
- package/.agents/skills/remotion-best-practices/rules/sfx.md +0 -26
- package/.agents/skills/remotion-best-practices/rules/subtitles.md +0 -36
- package/.agents/skills/remotion-best-practices/rules/tailwind.md +0 -11
- package/.agents/skills/remotion-best-practices/rules/text-animations.md +0 -20
- package/.agents/skills/remotion-best-practices/rules/timing.md +0 -179
- package/.agents/skills/remotion-best-practices/rules/transcribe-captions.md +0 -70
- package/.agents/skills/remotion-best-practices/rules/transitions.md +0 -197
- package/.agents/skills/remotion-best-practices/rules/transparent-videos.md +0 -106
- package/.agents/skills/remotion-best-practices/rules/trimming.md +0 -51
- package/.agents/skills/remotion-best-practices/rules/videos.md +0 -171
- package/.agents/skills/remotion-best-practices/rules/voiceover.md +0 -99
- package/.agents/skills/simple/SKILL.md +0 -52
- package/.agents/skills/vercel-react-best-practices/AGENTS.md +0 -3254
- package/.agents/skills/vercel-react-best-practices/README.md +0 -123
- package/.agents/skills/vercel-react-best-practices/SKILL.md +0 -141
- package/.agents/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +0 -55
- package/.agents/skills/vercel-react-best-practices/rules/advanced-init-once.md +0 -42
- package/.agents/skills/vercel-react-best-practices/rules/advanced-use-latest.md +0 -39
- package/.agents/skills/vercel-react-best-practices/rules/async-api-routes.md +0 -38
- package/.agents/skills/vercel-react-best-practices/rules/async-defer-await.md +0 -80
- package/.agents/skills/vercel-react-best-practices/rules/async-dependencies.md +0 -51
- package/.agents/skills/vercel-react-best-practices/rules/async-parallel.md +0 -28
- package/.agents/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +0 -99
- package/.agents/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +0 -59
- package/.agents/skills/vercel-react-best-practices/rules/bundle-conditional.md +0 -31
- package/.agents/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +0 -49
- package/.agents/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +0 -35
- package/.agents/skills/vercel-react-best-practices/rules/bundle-preload.md +0 -50
- package/.agents/skills/vercel-react-best-practices/rules/client-event-listeners.md +0 -74
- package/.agents/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +0 -71
- package/.agents/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +0 -48
- package/.agents/skills/vercel-react-best-practices/rules/client-swr-dedup.md +0 -56
- package/.agents/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +0 -107
- package/.agents/skills/vercel-react-best-practices/rules/js-cache-function-results.md +0 -80
- package/.agents/skills/vercel-react-best-practices/rules/js-cache-property-access.md +0 -28
- package/.agents/skills/vercel-react-best-practices/rules/js-cache-storage.md +0 -70
- package/.agents/skills/vercel-react-best-practices/rules/js-combine-iterations.md +0 -32
- package/.agents/skills/vercel-react-best-practices/rules/js-early-exit.md +0 -50
- package/.agents/skills/vercel-react-best-practices/rules/js-flatmap-filter.md +0 -60
- package/.agents/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +0 -45
- package/.agents/skills/vercel-react-best-practices/rules/js-index-maps.md +0 -37
- package/.agents/skills/vercel-react-best-practices/rules/js-length-check-first.md +0 -49
- package/.agents/skills/vercel-react-best-practices/rules/js-min-max-loop.md +0 -82
- package/.agents/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +0 -24
- package/.agents/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +0 -57
- package/.agents/skills/vercel-react-best-practices/rules/rendering-activity.md +0 -26
- package/.agents/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
- package/.agents/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +0 -40
- package/.agents/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +0 -38
- package/.agents/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +0 -46
- package/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
- package/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +0 -30
- package/.agents/skills/vercel-react-best-practices/rules/rendering-resource-hints.md +0 -85
- package/.agents/skills/vercel-react-best-practices/rules/rendering-script-defer-async.md +0 -68
- package/.agents/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +0 -28
- package/.agents/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +0 -75
- package/.agents/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +0 -39
- package/.agents/skills/vercel-react-best-practices/rules/rerender-dependencies.md +0 -45
- package/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +0 -40
- package/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state.md +0 -29
- package/.agents/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +0 -74
- package/.agents/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +0 -58
- package/.agents/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +0 -38
- package/.agents/skills/vercel-react-best-practices/rules/rerender-memo.md +0 -44
- package/.agents/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +0 -45
- package/.agents/skills/vercel-react-best-practices/rules/rerender-no-inline-components.md +0 -82
- package/.agents/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +0 -35
- package/.agents/skills/vercel-react-best-practices/rules/rerender-transitions.md +0 -40
- package/.agents/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +0 -73
- package/.agents/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +0 -73
- package/.agents/skills/vercel-react-best-practices/rules/server-auth-actions.md +0 -96
- package/.agents/skills/vercel-react-best-practices/rules/server-cache-lru.md +0 -41
- package/.agents/skills/vercel-react-best-practices/rules/server-cache-react.md +0 -76
- package/.agents/skills/vercel-react-best-practices/rules/server-dedup-props.md +0 -65
- package/.agents/skills/vercel-react-best-practices/rules/server-hoist-static-io.md +0 -142
- package/.agents/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +0 -83
- package/.agents/skills/vercel-react-best-practices/rules/server-serialization.md +0 -38
- package/.claude/CLAUDE.md +0 -184
- package/.claude/commands/review.md +0 -120
- package/.claude/commands/sync-docs.md +0 -71
- package/.claude/roadmap.md +0 -121
- package/.claude/rules/style-guide.md +0 -830
- package/.claude/settings.json +0 -18
- package/.claude/user-stories.md +0 -333
- package/AGENTS.md +0 -68
- package/Makefile +0 -32
- package/biome.json +0 -79
- package/bun.lock +0 -854
- package/bunfig.toml +0 -2
- package/docs/design.md +0 -563
- package/docs/perf-baseline.md +0 -130
- package/docs/plans/2026-03-13-client-mode-design.md +0 -86
- package/docs/plans/2026-03-13-client-mode-plan.md +0 -605
- package/docs/plans/2026-03-13-keyboard-shortcuts-design.md +0 -129
- package/docs/plans/2026-03-13-keyboard-shortcuts-plan.md +0 -1471
- package/docs/plans/2026-03-13-multi-document-design.md +0 -183
- package/docs/plans/2026-03-13-performance-benchmarks-design.md +0 -121
- package/docs/superpowers/plans/2026-03-26-surgical-pruning.md +0 -1176
- package/docs/superpowers/specs/2026-03-27-go-server-rewrite-design.md +0 -284
- package/e2e/comments.spec.ts +0 -81
- package/e2e/document-load.spec.ts +0 -32
- package/e2e/export.spec.ts +0 -58
- package/e2e/fixtures/sample.md +0 -7
- package/e2e/perf/add-comment.spec.ts +0 -116
- package/e2e/perf/fixtures/generate.ts +0 -327
- package/e2e/perf/initial-load.spec.ts +0 -49
- package/e2e/perf/perf.setup.ts +0 -23
- package/e2e/perf/perf.teardown.ts +0 -9
- package/e2e/perf/screenshot-final.png +0 -0
- package/e2e/perf/scroll.spec.ts +0 -39
- package/e2e/perf/tab-switch.spec.ts +0 -69
- package/e2e/perf/text-selection.spec.ts +0 -119
- package/e2e/perf/utils/metrics.ts +0 -350
- package/e2e/perf/utils/perf-cli.ts +0 -86
- package/e2e/persistence-file.spec.ts +0 -357
- package/e2e/utils/cli.ts +0 -84
- package/e2e/utils/selection.ts +0 -79
- package/go/cmd/readit/main.go +0 -416
- package/go/go.mod +0 -20
- package/go/go.sum +0 -41
- package/go/internal/server/anchor.go +0 -302
- package/go/internal/server/anchor_test.go +0 -111
- package/go/internal/server/comments.go +0 -390
- package/go/internal/server/documents.go +0 -113
- package/go/internal/server/embed.go +0 -17
- package/go/internal/server/headings.go +0 -33
- package/go/internal/server/headings_test.go +0 -75
- package/go/internal/server/htmltext.go +0 -123
- package/go/internal/server/markdown.go +0 -157
- package/go/internal/server/markdown_bench_test.go +0 -42
- package/go/internal/server/markdown_test.go +0 -79
- package/go/internal/server/server.go +0 -453
- package/go/internal/server/server_bench_test.go +0 -122
- package/go/internal/server/settings.go +0 -110
- package/go/internal/server/sse.go +0 -140
- package/go/internal/server/storage.go +0 -275
- package/go/internal/server/storage_test.go +0 -118
- package/go/internal/server/template.go +0 -66
- package/go/internal/server/types.go +0 -101
- package/go/internal/server/watcher.go +0 -74
- package/lefthook.yml +0 -8
- package/nvim-readit/lua/readit/health.lua +0 -64
- package/nvim-readit/lua/readit/init.lua +0 -463
- package/nvim-readit/plugin/readit.lua +0 -19
- package/playwright.config.ts +0 -34
- package/skills-lock.json +0 -20
- package/src/App.svelte +0 -881
- package/src/cli.ts +0 -881
- package/src/components/ActionsMenu.svelte +0 -95
- package/src/components/CommentBadge.svelte +0 -67
- package/src/components/CommentErrorBanner.svelte +0 -33
- package/src/components/CommentInput.svelte +0 -75
- package/src/components/CommentListItem.svelte +0 -95
- package/src/components/CommentManager.svelte +0 -129
- package/src/components/CommentNav.svelte +0 -109
- package/src/components/DocumentViewer.svelte +0 -218
- package/src/components/FloatingComment.svelte +0 -107
- package/src/components/Header.svelte +0 -76
- package/src/components/InlineEditor.svelte +0 -72
- package/src/components/MarginNote.svelte +0 -167
- package/src/components/MarginNotesContainer.svelte +0 -33
- package/src/components/RawModal.svelte +0 -126
- package/src/components/ReanchorConfirm.svelte +0 -30
- package/src/components/SettingsModal.svelte +0 -220
- package/src/components/ShortcutCapture.svelte +0 -82
- package/src/components/ShortcutList.svelte +0 -145
- package/src/components/TabBar.svelte +0 -52
- package/src/components/TableOfContents.svelte +0 -125
- package/src/components/ui/ActionLink.svelte +0 -40
- package/src/components/ui/Button.svelte +0 -53
- package/src/components/ui/Dialog.svelte +0 -97
- package/src/components/ui/DropdownMenu.svelte +0 -85
- package/src/components/ui/DropdownMenuItem.svelte +0 -38
- package/src/components/ui/DropdownMenuSeparator.svelte +0 -11
- package/src/components/ui/Text.svelte +0 -42
- package/src/env.d.ts +0 -6
- package/src/index.css +0 -754
- package/src/lib/__fixtures__/bench-data.ts +0 -114
- package/src/lib/anchor.bench.ts +0 -91
- package/src/lib/anchor.test.ts +0 -527
- package/src/lib/anchor.ts +0 -381
- package/src/lib/comment-storage.bench.ts +0 -49
- package/src/lib/comment-storage.test.ts +0 -632
- package/src/lib/comment-storage.ts +0 -222
- package/src/lib/export.bench.ts +0 -21
- package/src/lib/export.ts +0 -36
- package/src/lib/headings.test.ts +0 -103
- package/src/lib/headings.ts +0 -44
- package/src/lib/highlight/core.test.ts +0 -93
- package/src/lib/highlight/dom.ts +0 -187
- package/src/lib/highlight/highlight-registry.ts +0 -221
- package/src/lib/highlight/highlight.bench.ts +0 -92
- package/src/lib/highlight/highlighter.ts +0 -247
- package/src/lib/highlight/resolver.ts +0 -38
- package/src/lib/highlight/types.ts +0 -17
- package/src/lib/html-text.test.ts +0 -162
- package/src/lib/html-text.ts +0 -161
- package/src/lib/i18n/en.ts +0 -116
- package/src/lib/i18n/index.ts +0 -3
- package/src/lib/i18n/ja.ts +0 -118
- package/src/lib/i18n/translations.ts +0 -27
- package/src/lib/i18n/types.ts +0 -122
- package/src/lib/margin-layout.bench.ts +0 -61
- package/src/lib/margin-layout.ts +0 -71
- package/src/lib/markdown-renderer.test.ts +0 -154
- package/src/lib/markdown-renderer.ts +0 -177
- package/src/lib/mermaid-config.ts +0 -38
- package/src/lib/mermaid-renderer.ts +0 -162
- package/src/lib/mermaid-worker.ts +0 -60
- package/src/lib/positions.ts +0 -157
- package/src/lib/shortcut-registry.ts +0 -244
- package/src/lib/utils.ts +0 -15
- package/src/main.ts +0 -16
- package/src/schema.ts +0 -92
- package/src/server.ts +0 -1220
- package/src/stores/app.svelte.ts +0 -231
- package/src/stores/locale.svelte.ts +0 -46
- package/src/stores/settings.svelte.ts +0 -90
- package/src/stores/shortcuts.svelte.ts +0 -104
- package/src/stores/ui.svelte.ts +0 -12
- package/src/template.ts +0 -104
- package/src/test-setup.ts +0 -48
- package/svelte.config.js +0 -5
- package/test.md +0 -74
- package/tsconfig.cli.json +0 -12
- package/tsconfig.json +0 -20
- package/vite.config.ts +0 -47
- package/vitest.config.ts +0 -15
- package/vscode-readit/.mcp.json +0 -7
- package/vscode-readit/.vscodeignore +0 -7
- package/vscode-readit/bun.lock +0 -78
- package/vscode-readit/icon.svg +0 -10
- package/vscode-readit/package.json +0 -110
- package/vscode-readit/src/extension.ts +0 -117
- package/vscode-readit/src/server-manager.ts +0 -272
- package/vscode-readit/src/webview-provider.ts +0 -204
- package/vscode-readit/tsconfig.json +0 -20
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Per-Request Deduplication with React.cache()
|
|
3
|
-
impact: MEDIUM
|
|
4
|
-
impactDescription: deduplicates within request
|
|
5
|
-
tags: server, cache, react-cache, deduplication
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Per-Request Deduplication with React.cache()
|
|
9
|
-
|
|
10
|
-
Use `React.cache()` for server-side request deduplication. Authentication and database queries benefit most.
|
|
11
|
-
|
|
12
|
-
**Usage:**
|
|
13
|
-
|
|
14
|
-
```typescript
|
|
15
|
-
import { cache } from 'react'
|
|
16
|
-
|
|
17
|
-
export const getCurrentUser = cache(async () => {
|
|
18
|
-
const session = await auth()
|
|
19
|
-
if (!session?.user?.id) return null
|
|
20
|
-
return await db.user.findUnique({
|
|
21
|
-
where: { id: session.user.id }
|
|
22
|
-
})
|
|
23
|
-
})
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Within a single request, multiple calls to `getCurrentUser()` execute the query only once.
|
|
27
|
-
|
|
28
|
-
**Avoid inline objects as arguments:**
|
|
29
|
-
|
|
30
|
-
`React.cache()` uses shallow equality (`Object.is`) to determine cache hits. Inline objects create new references each call, preventing cache hits.
|
|
31
|
-
|
|
32
|
-
**Incorrect (always cache miss):**
|
|
33
|
-
|
|
34
|
-
```typescript
|
|
35
|
-
const getUser = cache(async (params: { uid: number }) => {
|
|
36
|
-
return await db.user.findUnique({ where: { id: params.uid } })
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
// Each call creates new object, never hits cache
|
|
40
|
-
getUser({ uid: 1 })
|
|
41
|
-
getUser({ uid: 1 }) // Cache miss, runs query again
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
**Correct (cache hit):**
|
|
45
|
-
|
|
46
|
-
```typescript
|
|
47
|
-
const getUser = cache(async (uid: number) => {
|
|
48
|
-
return await db.user.findUnique({ where: { id: uid } })
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
// Primitive args use value equality
|
|
52
|
-
getUser(1)
|
|
53
|
-
getUser(1) // Cache hit, returns cached result
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
If you must pass objects, pass the same reference:
|
|
57
|
-
|
|
58
|
-
```typescript
|
|
59
|
-
const params = { uid: 1 }
|
|
60
|
-
getUser(params) // Query runs
|
|
61
|
-
getUser(params) // Cache hit (same reference)
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
**Next.js-Specific Note:**
|
|
65
|
-
|
|
66
|
-
In Next.js, the `fetch` API is automatically extended with request memoization. Requests with the same URL and options are automatically deduplicated within a single request, so you don't need `React.cache()` for `fetch` calls. However, `React.cache()` is still essential for other async tasks:
|
|
67
|
-
|
|
68
|
-
- Database queries (Prisma, Drizzle, etc.)
|
|
69
|
-
- Heavy computations
|
|
70
|
-
- Authentication checks
|
|
71
|
-
- File system operations
|
|
72
|
-
- Any non-fetch async work
|
|
73
|
-
|
|
74
|
-
Use `React.cache()` to deduplicate these operations across your component tree.
|
|
75
|
-
|
|
76
|
-
Reference: [React.cache documentation](https://react.dev/reference/react/cache)
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Avoid Duplicate Serialization in RSC Props
|
|
3
|
-
impact: LOW
|
|
4
|
-
impactDescription: reduces network payload by avoiding duplicate serialization
|
|
5
|
-
tags: server, rsc, serialization, props, client-components
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Avoid Duplicate Serialization in RSC Props
|
|
9
|
-
|
|
10
|
-
**Impact: LOW (reduces network payload by avoiding duplicate serialization)**
|
|
11
|
-
|
|
12
|
-
RSC→client serialization deduplicates by object reference, not value. Same reference = serialized once; new reference = serialized again. Do transformations (`.toSorted()`, `.filter()`, `.map()`) in client, not server.
|
|
13
|
-
|
|
14
|
-
**Incorrect (duplicates array):**
|
|
15
|
-
|
|
16
|
-
```tsx
|
|
17
|
-
// RSC: sends 6 strings (2 arrays × 3 items)
|
|
18
|
-
<ClientList usernames={usernames} usernamesOrdered={usernames.toSorted()} />
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
**Correct (sends 3 strings):**
|
|
22
|
-
|
|
23
|
-
```tsx
|
|
24
|
-
// RSC: send once
|
|
25
|
-
<ClientList usernames={usernames} />
|
|
26
|
-
|
|
27
|
-
// Client: transform there
|
|
28
|
-
'use client'
|
|
29
|
-
const sorted = useMemo(() => [...usernames].sort(), [usernames])
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
**Nested deduplication behavior:**
|
|
33
|
-
|
|
34
|
-
Deduplication works recursively. Impact varies by data type:
|
|
35
|
-
|
|
36
|
-
- `string[]`, `number[]`, `boolean[]`: **HIGH impact** - array + all primitives fully duplicated
|
|
37
|
-
- `object[]`: **LOW impact** - array duplicated, but nested objects deduplicated by reference
|
|
38
|
-
|
|
39
|
-
```tsx
|
|
40
|
-
// string[] - duplicates everything
|
|
41
|
-
usernames={['a','b']} sorted={usernames.toSorted()} // sends 4 strings
|
|
42
|
-
|
|
43
|
-
// object[] - duplicates array structure only
|
|
44
|
-
users={[{id:1},{id:2}]} sorted={users.toSorted()} // sends 2 arrays + 2 unique objects (not 4)
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
**Operations breaking deduplication (create new references):**
|
|
48
|
-
|
|
49
|
-
- Arrays: `.toSorted()`, `.filter()`, `.map()`, `.slice()`, `[...arr]`
|
|
50
|
-
- Objects: `{...obj}`, `Object.assign()`, `structuredClone()`, `JSON.parse(JSON.stringify())`
|
|
51
|
-
|
|
52
|
-
**More examples:**
|
|
53
|
-
|
|
54
|
-
```tsx
|
|
55
|
-
// ❌ Bad
|
|
56
|
-
<C users={users} active={users.filter(u => u.active)} />
|
|
57
|
-
<C product={product} productName={product.name} />
|
|
58
|
-
|
|
59
|
-
// ✅ Good
|
|
60
|
-
<C users={users} />
|
|
61
|
-
<C product={product} />
|
|
62
|
-
// Do filtering/destructuring in client
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
**Exception:** Pass derived data when transformation is expensive or client doesn't need original.
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Hoist Static I/O to Module Level
|
|
3
|
-
impact: HIGH
|
|
4
|
-
impactDescription: avoids repeated file/network I/O per request
|
|
5
|
-
tags: server, io, performance, next.js, route-handlers, og-image
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Hoist Static I/O to Module Level
|
|
9
|
-
|
|
10
|
-
**Impact: HIGH (avoids repeated file/network I/O per request)**
|
|
11
|
-
|
|
12
|
-
When loading static assets (fonts, logos, images, config files) in route handlers or server functions, hoist the I/O operation to module level. Module-level code runs once when the module is first imported, not on every request. This eliminates redundant file system reads or network fetches that would otherwise run on every invocation.
|
|
13
|
-
|
|
14
|
-
**Incorrect: reads font file on every request**
|
|
15
|
-
|
|
16
|
-
```typescript
|
|
17
|
-
// app/api/og/route.tsx
|
|
18
|
-
import { ImageResponse } from 'next/og'
|
|
19
|
-
|
|
20
|
-
export async function GET(request: Request) {
|
|
21
|
-
// Runs on EVERY request - expensive!
|
|
22
|
-
const fontData = await fetch(
|
|
23
|
-
new URL('./fonts/Inter.ttf', import.meta.url)
|
|
24
|
-
).then(res => res.arrayBuffer())
|
|
25
|
-
|
|
26
|
-
const logoData = await fetch(
|
|
27
|
-
new URL('./images/logo.png', import.meta.url)
|
|
28
|
-
).then(res => res.arrayBuffer())
|
|
29
|
-
|
|
30
|
-
return new ImageResponse(
|
|
31
|
-
<div style={{ fontFamily: 'Inter' }}>
|
|
32
|
-
<img src={logoData} />
|
|
33
|
-
Hello World
|
|
34
|
-
</div>,
|
|
35
|
-
{ fonts: [{ name: 'Inter', data: fontData }] }
|
|
36
|
-
)
|
|
37
|
-
}
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
**Correct: loads once at module initialization**
|
|
41
|
-
|
|
42
|
-
```typescript
|
|
43
|
-
// app/api/og/route.tsx
|
|
44
|
-
import { ImageResponse } from 'next/og'
|
|
45
|
-
|
|
46
|
-
// Module-level: runs ONCE when module is first imported
|
|
47
|
-
const fontData = fetch(
|
|
48
|
-
new URL('./fonts/Inter.ttf', import.meta.url)
|
|
49
|
-
).then(res => res.arrayBuffer())
|
|
50
|
-
|
|
51
|
-
const logoData = fetch(
|
|
52
|
-
new URL('./images/logo.png', import.meta.url)
|
|
53
|
-
).then(res => res.arrayBuffer())
|
|
54
|
-
|
|
55
|
-
export async function GET(request: Request) {
|
|
56
|
-
// Await the already-started promises
|
|
57
|
-
const [font, logo] = await Promise.all([fontData, logoData])
|
|
58
|
-
|
|
59
|
-
return new ImageResponse(
|
|
60
|
-
<div style={{ fontFamily: 'Inter' }}>
|
|
61
|
-
<img src={logo} />
|
|
62
|
-
Hello World
|
|
63
|
-
</div>,
|
|
64
|
-
{ fonts: [{ name: 'Inter', data: font }] }
|
|
65
|
-
)
|
|
66
|
-
}
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
**Alternative: synchronous file reads with Node.js fs**
|
|
70
|
-
|
|
71
|
-
```typescript
|
|
72
|
-
// app/api/og/route.tsx
|
|
73
|
-
import { ImageResponse } from 'next/og'
|
|
74
|
-
import { readFileSync } from 'fs'
|
|
75
|
-
import { join } from 'path'
|
|
76
|
-
|
|
77
|
-
// Synchronous read at module level - blocks only during module init
|
|
78
|
-
const fontData = readFileSync(
|
|
79
|
-
join(process.cwd(), 'public/fonts/Inter.ttf')
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
const logoData = readFileSync(
|
|
83
|
-
join(process.cwd(), 'public/images/logo.png')
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
export async function GET(request: Request) {
|
|
87
|
-
return new ImageResponse(
|
|
88
|
-
<div style={{ fontFamily: 'Inter' }}>
|
|
89
|
-
<img src={logoData} />
|
|
90
|
-
Hello World
|
|
91
|
-
</div>,
|
|
92
|
-
{ fonts: [{ name: 'Inter', data: fontData }] }
|
|
93
|
-
)
|
|
94
|
-
}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
**General Node.js example: loading config or templates**
|
|
98
|
-
|
|
99
|
-
```typescript
|
|
100
|
-
// Incorrect: reads config on every call
|
|
101
|
-
export async function processRequest(data: Data) {
|
|
102
|
-
const config = JSON.parse(
|
|
103
|
-
await fs.readFile('./config.json', 'utf-8')
|
|
104
|
-
)
|
|
105
|
-
const template = await fs.readFile('./template.html', 'utf-8')
|
|
106
|
-
|
|
107
|
-
return render(template, data, config)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Correct: loads once at module level
|
|
111
|
-
const configPromise = fs.readFile('./config.json', 'utf-8')
|
|
112
|
-
.then(JSON.parse)
|
|
113
|
-
const templatePromise = fs.readFile('./template.html', 'utf-8')
|
|
114
|
-
|
|
115
|
-
export async function processRequest(data: Data) {
|
|
116
|
-
const [config, template] = await Promise.all([
|
|
117
|
-
configPromise,
|
|
118
|
-
templatePromise
|
|
119
|
-
])
|
|
120
|
-
|
|
121
|
-
return render(template, data, config)
|
|
122
|
-
}
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
**When to use this pattern:**
|
|
126
|
-
|
|
127
|
-
- Loading fonts for OG image generation
|
|
128
|
-
- Loading static logos, icons, or watermarks
|
|
129
|
-
- Reading configuration files that don't change at runtime
|
|
130
|
-
- Loading email templates or other static templates
|
|
131
|
-
- Any static asset that's the same across all requests
|
|
132
|
-
|
|
133
|
-
**When NOT to use this pattern:**
|
|
134
|
-
|
|
135
|
-
- Assets that vary per request or user
|
|
136
|
-
- Files that may change during runtime (use caching with TTL instead)
|
|
137
|
-
- Large files that would consume too much memory if kept loaded
|
|
138
|
-
- Sensitive data that shouldn't persist in memory
|
|
139
|
-
|
|
140
|
-
**With Vercel's [Fluid Compute](https://vercel.com/docs/fluid-compute):** Module-level caching is especially effective because multiple concurrent requests share the same function instance. The static assets stay loaded in memory across requests without cold start penalties.
|
|
141
|
-
|
|
142
|
-
**In traditional serverless:** Each cold start re-executes module-level code, but subsequent warm invocations reuse the loaded assets until the instance is recycled.
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Parallel Data Fetching with Component Composition
|
|
3
|
-
impact: CRITICAL
|
|
4
|
-
impactDescription: eliminates server-side waterfalls
|
|
5
|
-
tags: server, rsc, parallel-fetching, composition
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Parallel Data Fetching with Component Composition
|
|
9
|
-
|
|
10
|
-
React Server Components execute sequentially within a tree. Restructure with composition to parallelize data fetching.
|
|
11
|
-
|
|
12
|
-
**Incorrect (Sidebar waits for Page's fetch to complete):**
|
|
13
|
-
|
|
14
|
-
```tsx
|
|
15
|
-
export default async function Page() {
|
|
16
|
-
const header = await fetchHeader()
|
|
17
|
-
return (
|
|
18
|
-
<div>
|
|
19
|
-
<div>{header}</div>
|
|
20
|
-
<Sidebar />
|
|
21
|
-
</div>
|
|
22
|
-
)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
async function Sidebar() {
|
|
26
|
-
const items = await fetchSidebarItems()
|
|
27
|
-
return <nav>{items.map(renderItem)}</nav>
|
|
28
|
-
}
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
**Correct (both fetch simultaneously):**
|
|
32
|
-
|
|
33
|
-
```tsx
|
|
34
|
-
async function Header() {
|
|
35
|
-
const data = await fetchHeader()
|
|
36
|
-
return <div>{data}</div>
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async function Sidebar() {
|
|
40
|
-
const items = await fetchSidebarItems()
|
|
41
|
-
return <nav>{items.map(renderItem)}</nav>
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export default function Page() {
|
|
45
|
-
return (
|
|
46
|
-
<div>
|
|
47
|
-
<Header />
|
|
48
|
-
<Sidebar />
|
|
49
|
-
</div>
|
|
50
|
-
)
|
|
51
|
-
}
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
**Alternative with children prop:**
|
|
55
|
-
|
|
56
|
-
```tsx
|
|
57
|
-
async function Header() {
|
|
58
|
-
const data = await fetchHeader()
|
|
59
|
-
return <div>{data}</div>
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
async function Sidebar() {
|
|
63
|
-
const items = await fetchSidebarItems()
|
|
64
|
-
return <nav>{items.map(renderItem)}</nav>
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function Layout({ children }: { children: ReactNode }) {
|
|
68
|
-
return (
|
|
69
|
-
<div>
|
|
70
|
-
<Header />
|
|
71
|
-
{children}
|
|
72
|
-
</div>
|
|
73
|
-
)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export default function Page() {
|
|
77
|
-
return (
|
|
78
|
-
<Layout>
|
|
79
|
-
<Sidebar />
|
|
80
|
-
</Layout>
|
|
81
|
-
)
|
|
82
|
-
}
|
|
83
|
-
```
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Minimize Serialization at RSC Boundaries
|
|
3
|
-
impact: HIGH
|
|
4
|
-
impactDescription: reduces data transfer size
|
|
5
|
-
tags: server, rsc, serialization, props
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Minimize Serialization at RSC Boundaries
|
|
9
|
-
|
|
10
|
-
The React Server/Client boundary serializes all object properties into strings and embeds them in the HTML response and subsequent RSC requests. This serialized data directly impacts page weight and load time, so **size matters a lot**. Only pass fields that the client actually uses.
|
|
11
|
-
|
|
12
|
-
**Incorrect (serializes all 50 fields):**
|
|
13
|
-
|
|
14
|
-
```tsx
|
|
15
|
-
async function Page() {
|
|
16
|
-
const user = await fetchUser() // 50 fields
|
|
17
|
-
return <Profile user={user} />
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
'use client'
|
|
21
|
-
function Profile({ user }: { user: User }) {
|
|
22
|
-
return <div>{user.name}</div> // uses 1 field
|
|
23
|
-
}
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
**Correct (serializes only 1 field):**
|
|
27
|
-
|
|
28
|
-
```tsx
|
|
29
|
-
async function Page() {
|
|
30
|
-
const user = await fetchUser()
|
|
31
|
-
return <Profile name={user.name} />
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
'use client'
|
|
35
|
-
function Profile({ name }: { name: string }) {
|
|
36
|
-
return <div>{name}</div>
|
|
37
|
-
}
|
|
38
|
-
```
|
package/.claude/CLAUDE.md
DELETED
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
# CLAUDE.md
|
|
2
|
-
|
|
3
|
-
## Project Overview
|
|
4
|
-
|
|
5
|
-
**readit** is a CLI tool for reviewing Markdown and HTML documents with inline comments. It serves documents in a local web interface and allows users to add comments to selected text. Comments appear as margin notes next to highlighted text (similar to Google Docs). Comments can be exported for use with AI coding assistants or applied back to the source document.
|
|
6
|
-
|
|
7
|
-
Inspired by [difit](https://github.com/yoshiko-pg/difit) - a local code review tool for the AI era.
|
|
8
|
-
|
|
9
|
-
## Quick Reference
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
# Development
|
|
13
|
-
bun install # Install dependencies
|
|
14
|
-
bun dev # Start dev server (CLI with --watch)
|
|
15
|
-
bun run dev:client # Start Vite dev server only
|
|
16
|
-
bun run build # Build for production (Vite + CLI)
|
|
17
|
-
bun run test # Run unit tests (Vitest)
|
|
18
|
-
bun run test:e2e # Run e2e tests (Playwright)
|
|
19
|
-
bun run test:perf # Run performance tests
|
|
20
|
-
bun run bench # Run benchmarks
|
|
21
|
-
bun run typecheck # Run TypeScript checks
|
|
22
|
-
bun run check # Run Biome (lint + format check)
|
|
23
|
-
bun run check:fix # Fix lint + format issues
|
|
24
|
-
bun run format # Format with Biome
|
|
25
|
-
|
|
26
|
-
# Go server (production binary)
|
|
27
|
-
make dev # Go server + Vite HMR
|
|
28
|
-
make build # Build single binary (dist/readit)
|
|
29
|
-
make test # Run Go tests
|
|
30
|
-
make clean # Clean build artifacts
|
|
31
|
-
|
|
32
|
-
# Usage
|
|
33
|
-
bunx readit <file.md> # Review Markdown file
|
|
34
|
-
bunx readit <file.html> # Review HTML file
|
|
35
|
-
bunx readit <file.md> --port 3000 # Custom port
|
|
36
|
-
bunx readit <file.md> --host 0.0.0.0 # Custom host address
|
|
37
|
-
bunx readit <file.md> --no-open # Don't auto-open browser
|
|
38
|
-
bunx readit <file.md> --clean # Clear existing comments
|
|
39
|
-
|
|
40
|
-
bunx readit list # List all files with comments
|
|
41
|
-
bunx readit show <file.md> # Show comments for a file
|
|
42
|
-
bunx readit open <files...> # Add files to running server
|
|
43
|
-
bunx readit completion zsh # Output shell integration script
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## Architecture
|
|
47
|
-
|
|
48
|
-
```
|
|
49
|
-
readit/
|
|
50
|
-
├── src/
|
|
51
|
-
│ ├── cli.ts # CLI entry point (Commander.js)
|
|
52
|
-
│ ├── server.ts # Bun.serve() server + API routes
|
|
53
|
-
│ ├── App.svelte # Main Svelte component
|
|
54
|
-
│ ├── main.ts # Svelte entry point
|
|
55
|
-
│ ├── schema.ts # TypeScript types
|
|
56
|
-
│ ├── template.ts # HTML template rendering
|
|
57
|
-
│ ├── index.css # Tailwind styles + CSS custom properties
|
|
58
|
-
│ ├── components/
|
|
59
|
-
│ │ ├── Header.svelte
|
|
60
|
-
│ │ ├── DocumentViewer.svelte # Renders document HTML
|
|
61
|
-
│ │ ├── CommentInput.svelte # Comment input area
|
|
62
|
-
│ │ ├── CommentNav.svelte # Navigate between comments
|
|
63
|
-
│ │ ├── CommentListItem.svelte # Comment item in manager
|
|
64
|
-
│ │ ├── CommentManager.svelte # Comment management panel
|
|
65
|
-
│ │ ├── CommentBadge.svelte # Comment count badge
|
|
66
|
-
│ │ ├── MarginNote.svelte # Individual margin note
|
|
67
|
-
│ │ ├── MarginNotesContainer.svelte
|
|
68
|
-
│ │ ├── ActionsMenu.svelte # Actions dropdown menu
|
|
69
|
-
│ │ ├── InlineEditor.svelte # Inline text editing
|
|
70
|
-
│ │ ├── RawModal.svelte # View raw .comments.md file
|
|
71
|
-
│ │ ├── ReanchorConfirm.svelte # Re-anchor confirmation dialog
|
|
72
|
-
│ │ ├── SettingsModal.svelte # Settings modal
|
|
73
|
-
│ │ ├── ShortcutCapture.svelte # Keyboard shortcut capture
|
|
74
|
-
│ │ ├── ShortcutList.svelte # Keyboard shortcuts list
|
|
75
|
-
│ │ ├── TabBar.svelte # Multi-file tab bar
|
|
76
|
-
│ │ ├── TableOfContents.svelte # Document headings navigation
|
|
77
|
-
│ │ └── ui/ # Primitive UI components
|
|
78
|
-
│ │ ├── ActionLink.svelte
|
|
79
|
-
│ │ ├── Button.svelte
|
|
80
|
-
│ │ ├── Dialog.svelte
|
|
81
|
-
│ │ ├── DropdownMenu.svelte
|
|
82
|
-
│ │ ├── DropdownMenuItem.svelte
|
|
83
|
-
│ │ ├── DropdownMenuSeparator.svelte
|
|
84
|
-
│ │ └── Text.svelte
|
|
85
|
-
│ ├── stores/ # Svelte 5 reactive stores
|
|
86
|
-
│ │ ├── app.svelte.ts # Application state
|
|
87
|
-
│ │ ├── settings.svelte.ts # User settings
|
|
88
|
-
│ │ ├── shortcuts.svelte.ts # Keyboard shortcuts
|
|
89
|
-
│ │ ├── locale.svelte.ts # i18n state
|
|
90
|
-
│ │ └── ui.svelte.ts # UI state
|
|
91
|
-
│ └── lib/
|
|
92
|
-
│ ├── anchor.ts # Anchor-based comment resolution
|
|
93
|
-
│ ├── comment-storage.ts # File-based comment storage
|
|
94
|
-
│ ├── export.ts # Export utilities (JSON, prompt format)
|
|
95
|
-
│ ├── headings.ts # Heading extraction
|
|
96
|
-
│ ├── html-text.ts # HTML text extraction
|
|
97
|
-
│ ├── margin-layout.ts # Margin note position resolution
|
|
98
|
-
│ ├── markdown-renderer.ts # Server-side markdown rendering
|
|
99
|
-
│ ├── mermaid-renderer.ts # Mermaid diagram rendering
|
|
100
|
-
│ ├── mermaid-config.ts # Mermaid configuration
|
|
101
|
-
│ ├── mermaid-worker.ts # Mermaid worker thread
|
|
102
|
-
│ ├── positions.ts # Position calculations
|
|
103
|
-
│ ├── shortcut-registry.ts # Keyboard shortcut registry
|
|
104
|
-
│ ├── utils.ts # Common utilities (cn, etc.)
|
|
105
|
-
│ ├── highlight/ # Text highlighting system
|
|
106
|
-
│ │ ├── highlighter.ts # Highlight manager
|
|
107
|
-
│ │ ├── highlight-registry.ts # Highlight registry
|
|
108
|
-
│ │ ├── resolver.ts # Highlight resolution
|
|
109
|
-
│ │ ├── dom.ts # DOM manipulation
|
|
110
|
-
│ │ └── types.ts # Type definitions
|
|
111
|
-
│ └── i18n/ # Internationalization
|
|
112
|
-
│ ├── index.ts
|
|
113
|
-
│ ├── translations.ts
|
|
114
|
-
│ ├── types.ts
|
|
115
|
-
│ ├── en.ts # English translations
|
|
116
|
-
│ └── ja.ts # Japanese translations
|
|
117
|
-
├── go/ # Go server (production binary)
|
|
118
|
-
│ ├── cmd/readit/main.go # Go CLI entry point
|
|
119
|
-
│ └── internal/server/ # HTTP server, markdown, comments, SSE
|
|
120
|
-
├── shell/ # Shell integration
|
|
121
|
-
│ ├── readit.zsh # Zsh plugin (@ file picker + completions)
|
|
122
|
-
│ └── _readit # Zsh compdef completion function
|
|
123
|
-
├── nvim-readit/ # Neovim plugin
|
|
124
|
-
│ ├── lua/readit/init.lua # Core plugin (server mgmt, commands, keymaps)
|
|
125
|
-
│ ├── lua/readit/health.lua # :checkhealth support
|
|
126
|
-
│ └── plugin/readit.lua # Auto-loader
|
|
127
|
-
├── vscode-readit/ # VS Code extension
|
|
128
|
-
│ └── src/ # Extension source (TypeScript)
|
|
129
|
-
├── e2e/ # Playwright e2e tests
|
|
130
|
-
├── docs/ # Design docs and specs
|
|
131
|
-
├── dist/ # Built output
|
|
132
|
-
├── .claude/ # AI agent docs
|
|
133
|
-
│ ├── user-stories.md
|
|
134
|
-
│ ├── roadmap.md
|
|
135
|
-
│ └── settings.json
|
|
136
|
-
├── Makefile # Go build targets (make dev, make build)
|
|
137
|
-
├── CLAUDE.md # This file
|
|
138
|
-
└── AGENTS.md # AI agent instructions
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
## Key Design Decisions
|
|
142
|
-
|
|
143
|
-
1. **markdown-it for Markdown**: Server-side rendering with shiki for syntax highlighting
|
|
144
|
-
2. **Mermaid for diagrams**: Server-side Mermaid diagram rendering
|
|
145
|
-
3. **Margin notes UX**: Comments appear as margin notes next to highlighted text (Google Docs style)
|
|
146
|
-
4. **File-based comments**: Human-readable `.comments.md` files stored in `~/.readit/comments/`
|
|
147
|
-
5. **difit-style UX**: CLI → local server → browser, familiar pattern
|
|
148
|
-
6. **Svelte 5 stores for state**: Reactive stores (`.svelte.ts`) for state management
|
|
149
|
-
7. **i18n support**: English and Japanese translations
|
|
150
|
-
8. **Live reload**: fs.watch() on documents + SSE push to browser; handles rename-style saves (Vim/Neovim/Emacs)
|
|
151
|
-
9. **Editor integrations**: Neovim plugin (Lua), VS Code extension, shell completions with `@` fzf file picker
|
|
152
|
-
|
|
153
|
-
## Tech Stack
|
|
154
|
-
|
|
155
|
-
- **Runtime**: Bun
|
|
156
|
-
- **CLI**: Commander.js for argument parsing
|
|
157
|
-
- **Server**: Bun.serve() for API, SSE, and static files
|
|
158
|
-
- **Markdown Rendering**: markdown-it (server-side) + shiki (syntax highlighting)
|
|
159
|
-
- **Frontend**: Svelte 5 + TypeScript + Vite
|
|
160
|
-
- **Styling**: Tailwind CSS v4
|
|
161
|
-
- **Icons**: lucide-svelte
|
|
162
|
-
- **Testing**: Vitest (unit) + Playwright (e2e)
|
|
163
|
-
- **Production Binary**: Go (embeds frontend via go:embed)
|
|
164
|
-
- **Quality**: Biome (lint + format), lefthook
|
|
165
|
-
- **Shell Integration**: Zsh/Bash/Fish completions, fzf-powered `@` file picker
|
|
166
|
-
- **Editor Plugins**: Neovim (Lua), VS Code (TypeScript)
|
|
167
|
-
|
|
168
|
-
## Current Limitations
|
|
169
|
-
|
|
170
|
-
- Comments use anchor-based text matching, may break if document changes significantly
|
|
171
|
-
- No comment status tracking yet (resolved/unresolved planned for v0.3.0)
|
|
172
|
-
|
|
173
|
-
## User Stories
|
|
174
|
-
|
|
175
|
-
See `.claude/user-stories.md` for detailed user stories and acceptance criteria.
|
|
176
|
-
|
|
177
|
-
## Code Style
|
|
178
|
-
|
|
179
|
-
- TypeScript strict mode
|
|
180
|
-
- Svelte 5 components with reactive stores
|
|
181
|
-
- Tailwind for styling
|
|
182
|
-
- ESM modules throughout
|
|
183
|
-
- Co-located test files (`*.test.ts`, `*.bench.ts`)
|
|
184
|
-
- E2E tests in `e2e/`
|