@peaske7/readit 0.1.4 → 0.1.6

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 (322) hide show
  1. package/.agents/skills/remotion-best-practices/SKILL.md +61 -0
  2. package/.agents/skills/remotion-best-practices/rules/3d.md +86 -0
  3. package/.agents/skills/remotion-best-practices/rules/animations.md +27 -0
  4. package/.agents/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx +178 -0
  5. package/.agents/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +100 -0
  6. package/.agents/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +108 -0
  7. package/.agents/skills/remotion-best-practices/rules/assets.md +78 -0
  8. package/.agents/skills/remotion-best-practices/rules/audio-visualization.md +198 -0
  9. package/.agents/skills/remotion-best-practices/rules/audio.md +169 -0
  10. package/.agents/skills/remotion-best-practices/rules/calculate-metadata.md +134 -0
  11. package/.agents/skills/remotion-best-practices/rules/can-decode.md +75 -0
  12. package/.agents/skills/remotion-best-practices/rules/charts.md +120 -0
  13. package/.agents/skills/remotion-best-practices/rules/compositions.md +154 -0
  14. package/.agents/skills/remotion-best-practices/rules/display-captions.md +184 -0
  15. package/.agents/skills/remotion-best-practices/rules/extract-frames.md +229 -0
  16. package/.agents/skills/remotion-best-practices/rules/ffmpeg.md +38 -0
  17. package/.agents/skills/remotion-best-practices/rules/fonts.md +152 -0
  18. package/.agents/skills/remotion-best-practices/rules/get-audio-duration.md +58 -0
  19. package/.agents/skills/remotion-best-practices/rules/get-video-dimensions.md +68 -0
  20. package/.agents/skills/remotion-best-practices/rules/get-video-duration.md +60 -0
  21. package/.agents/skills/remotion-best-practices/rules/gifs.md +141 -0
  22. package/.agents/skills/remotion-best-practices/rules/images.md +134 -0
  23. package/.agents/skills/remotion-best-practices/rules/import-srt-captions.md +69 -0
  24. package/.agents/skills/remotion-best-practices/rules/light-leaks.md +73 -0
  25. package/.agents/skills/remotion-best-practices/rules/lottie.md +70 -0
  26. package/.agents/skills/remotion-best-practices/rules/maps.md +412 -0
  27. package/.agents/skills/remotion-best-practices/rules/measuring-dom-nodes.md +34 -0
  28. package/.agents/skills/remotion-best-practices/rules/measuring-text.md +140 -0
  29. package/.agents/skills/remotion-best-practices/rules/parameters.md +109 -0
  30. package/.agents/skills/remotion-best-practices/rules/sequencing.md +118 -0
  31. package/.agents/skills/remotion-best-practices/rules/sfx.md +26 -0
  32. package/.agents/skills/remotion-best-practices/rules/subtitles.md +36 -0
  33. package/.agents/skills/remotion-best-practices/rules/tailwind.md +11 -0
  34. package/.agents/skills/remotion-best-practices/rules/text-animations.md +20 -0
  35. package/.agents/skills/remotion-best-practices/rules/timing.md +179 -0
  36. package/.agents/skills/remotion-best-practices/rules/transcribe-captions.md +70 -0
  37. package/.agents/skills/remotion-best-practices/rules/transitions.md +197 -0
  38. package/.agents/skills/remotion-best-practices/rules/transparent-videos.md +106 -0
  39. package/.agents/skills/remotion-best-practices/rules/trimming.md +51 -0
  40. package/.agents/skills/remotion-best-practices/rules/videos.md +171 -0
  41. package/.agents/skills/remotion-best-practices/rules/voiceover.md +99 -0
  42. package/.agents/skills/simple/SKILL.md +52 -0
  43. package/.agents/skills/vercel-react-best-practices/AGENTS.md +3254 -0
  44. package/.agents/skills/vercel-react-best-practices/README.md +123 -0
  45. package/.agents/skills/vercel-react-best-practices/SKILL.md +141 -0
  46. package/.agents/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  47. package/.agents/skills/vercel-react-best-practices/rules/advanced-init-once.md +42 -0
  48. package/.agents/skills/vercel-react-best-practices/rules/advanced-use-latest.md +39 -0
  49. package/.agents/skills/vercel-react-best-practices/rules/async-api-routes.md +38 -0
  50. package/.agents/skills/vercel-react-best-practices/rules/async-defer-await.md +80 -0
  51. package/.agents/skills/vercel-react-best-practices/rules/async-dependencies.md +51 -0
  52. package/.agents/skills/vercel-react-best-practices/rules/async-parallel.md +28 -0
  53. package/.agents/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
  54. package/.agents/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +59 -0
  55. package/.agents/skills/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
  56. package/.agents/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
  57. package/.agents/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  58. package/.agents/skills/vercel-react-best-practices/rules/bundle-preload.md +50 -0
  59. package/.agents/skills/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
  60. package/.agents/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -0
  61. package/.agents/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -0
  62. package/.agents/skills/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
  63. package/.agents/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +107 -0
  64. package/.agents/skills/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
  65. package/.agents/skills/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
  66. package/.agents/skills/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
  67. package/.agents/skills/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
  68. package/.agents/skills/vercel-react-best-practices/rules/js-early-exit.md +50 -0
  69. package/.agents/skills/vercel-react-best-practices/rules/js-flatmap-filter.md +60 -0
  70. package/.agents/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
  71. package/.agents/skills/vercel-react-best-practices/rules/js-index-maps.md +37 -0
  72. package/.agents/skills/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
  73. package/.agents/skills/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
  74. package/.agents/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
  75. package/.agents/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
  76. package/.agents/skills/vercel-react-best-practices/rules/rendering-activity.md +26 -0
  77. package/.agents/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  78. package/.agents/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
  79. package/.agents/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
  80. package/.agents/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  81. package/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  82. package/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
  83. package/.agents/skills/vercel-react-best-practices/rules/rendering-resource-hints.md +85 -0
  84. package/.agents/skills/vercel-react-best-practices/rules/rendering-script-defer-async.md +68 -0
  85. package/.agents/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
  86. package/.agents/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -0
  87. package/.agents/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
  88. package/.agents/skills/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
  89. package/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
  90. package/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
  91. package/.agents/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
  92. package/.agents/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  93. package/.agents/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
  94. package/.agents/skills/vercel-react-best-practices/rules/rerender-memo.md +44 -0
  95. package/.agents/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
  96. package/.agents/skills/vercel-react-best-practices/rules/rerender-no-inline-components.md +82 -0
  97. package/.agents/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
  98. package/.agents/skills/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
  99. package/.agents/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
  100. package/.agents/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
  101. package/.agents/skills/vercel-react-best-practices/rules/server-auth-actions.md +96 -0
  102. package/.agents/skills/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
  103. package/.agents/skills/vercel-react-best-practices/rules/server-cache-react.md +76 -0
  104. package/.agents/skills/vercel-react-best-practices/rules/server-dedup-props.md +65 -0
  105. package/.agents/skills/vercel-react-best-practices/rules/server-hoist-static-io.md +142 -0
  106. package/.agents/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -0
  107. package/.agents/skills/vercel-react-best-practices/rules/server-serialization.md +38 -0
  108. package/.claude/CLAUDE.md +142 -0
  109. package/.claude/commands/review.md +120 -0
  110. package/.claude/commands/sync-docs.md +71 -0
  111. package/.claude/roadmap.md +98 -0
  112. package/.claude/rules/style-guide.md +830 -0
  113. package/.claude/settings.json +18 -0
  114. package/.claude/user-stories.md +248 -0
  115. package/AGENTS.md +64 -0
  116. package/README.md +7 -7
  117. package/biome.json +69 -0
  118. package/bun.lock +1124 -0
  119. package/docs/design.md +563 -0
  120. package/docs/plans/2026-03-13-client-mode-design.md +86 -0
  121. package/docs/plans/2026-03-13-client-mode-plan.md +605 -0
  122. package/docs/plans/2026-03-13-keyboard-shortcuts-design.md +129 -0
  123. package/docs/plans/2026-03-13-keyboard-shortcuts-plan.md +1471 -0
  124. package/docs/plans/2026-03-13-multi-document-design.md +183 -0
  125. package/docs/plans/2026-03-13-performance-benchmarks-design.md +121 -0
  126. package/e2e/comments.spec.ts +125 -0
  127. package/e2e/document-load.spec.ts +54 -0
  128. package/e2e/export.spec.ts +58 -0
  129. package/e2e/fixtures/sample.html +13 -0
  130. package/e2e/fixtures/sample.md +7 -0
  131. package/e2e/persistence-file.spec.ts +342 -0
  132. package/e2e/utils/cli.ts +84 -0
  133. package/e2e/utils/selection.ts +135 -0
  134. package/{dist/index.html → index.html} +8 -2
  135. package/lefthook.yml +8 -0
  136. package/package.json +17 -39
  137. package/playwright.config.ts +22 -0
  138. package/skills-lock.json +20 -0
  139. package/src/App.tsx +396 -0
  140. package/src/cli/index.ts +467 -0
  141. package/src/components/ActionsMenu.tsx +110 -0
  142. package/src/components/DocumentViewer/CodeBlock.tsx +83 -0
  143. package/src/components/DocumentViewer/DocumentViewer.tsx +257 -0
  144. package/src/components/DocumentViewer/IframeContainer.tsx +251 -0
  145. package/src/components/DocumentViewer/MermaidDiagram.tsx +137 -0
  146. package/src/components/DocumentViewer/index.ts +1 -0
  147. package/src/components/FloatingTOC.tsx +59 -0
  148. package/src/components/Header.tsx +63 -0
  149. package/src/components/InlineEditor.tsx +72 -0
  150. package/src/components/MarginNote.tsx +198 -0
  151. package/src/components/MarginNotes.tsx +50 -0
  152. package/src/components/RawModal.tsx +141 -0
  153. package/src/components/ReanchorConfirm.tsx +33 -0
  154. package/src/components/SettingsModal.tsx +221 -0
  155. package/src/components/ShortcutCapture.tsx +45 -0
  156. package/src/components/ShortcutList.tsx +157 -0
  157. package/src/components/TabBar.tsx +60 -0
  158. package/src/components/TableOfContents.tsx +108 -0
  159. package/src/components/comments/CommentBadge.tsx +43 -0
  160. package/src/components/comments/CommentInput.tsx +119 -0
  161. package/src/components/comments/CommentListItem.tsx +82 -0
  162. package/src/components/comments/CommentManager.tsx +106 -0
  163. package/src/components/comments/CommentMinimap.tsx +62 -0
  164. package/src/components/comments/CommentNav.tsx +104 -0
  165. package/src/components/ui/ActionBar.tsx +16 -0
  166. package/src/components/ui/ActionLink.tsx +32 -0
  167. package/src/components/ui/Button.tsx +55 -0
  168. package/src/components/ui/Dialog.tsx +156 -0
  169. package/src/components/ui/DropdownMenu.tsx +114 -0
  170. package/src/components/ui/SeparatorDot.tsx +9 -0
  171. package/src/components/ui/Text.tsx +54 -0
  172. package/src/contexts/CommentContext.tsx +222 -0
  173. package/src/contexts/LayoutContext.tsx +76 -0
  174. package/src/hooks/useClickOutside.ts +35 -0
  175. package/src/hooks/useClipboard.ts +79 -0
  176. package/src/hooks/useCommentNavigation.ts +130 -0
  177. package/src/hooks/useComments.ts +323 -0
  178. package/src/hooks/useDocument.ts +141 -0
  179. package/src/hooks/useFontPreference.ts +76 -0
  180. package/src/hooks/useHeadings.test.ts +159 -0
  181. package/src/hooks/useHeadings.ts +129 -0
  182. package/src/hooks/useKeybindings.ts +120 -0
  183. package/src/hooks/useKeyboardShortcuts.ts +63 -0
  184. package/src/hooks/useLayoutMode.ts +44 -0
  185. package/src/hooks/useReanchorMode.ts +33 -0
  186. package/src/hooks/useScrollMetrics.ts +56 -0
  187. package/src/hooks/useScrollSpy.ts +81 -0
  188. package/src/hooks/useTextSelection.ts +123 -0
  189. package/src/hooks/useThemePreference.ts +66 -0
  190. package/src/index.css +823 -0
  191. package/src/lib/__fixtures__/bench-data.ts +167 -0
  192. package/src/lib/anchor.bench.ts +112 -0
  193. package/src/lib/anchor.test.ts +531 -0
  194. package/src/lib/anchor.ts +465 -0
  195. package/src/lib/comment-storage.bench.ts +63 -0
  196. package/src/lib/comment-storage.test.ts +624 -0
  197. package/src/lib/comment-storage.ts +263 -0
  198. package/src/lib/context.bench.ts +41 -0
  199. package/src/lib/context.test.ts +224 -0
  200. package/src/lib/context.ts +193 -0
  201. package/src/lib/export.bench.ts +35 -0
  202. package/src/lib/export.ts +43 -0
  203. package/src/lib/highlight/colors.ts +37 -0
  204. package/src/lib/highlight/core.test.ts +98 -0
  205. package/src/lib/highlight/core.ts +54 -0
  206. package/src/lib/highlight/dom.ts +342 -0
  207. package/src/lib/highlight/highlighter.ts +427 -0
  208. package/src/lib/highlight/index.ts +23 -0
  209. package/src/lib/highlight/script-builder.ts +485 -0
  210. package/src/lib/highlight/types.ts +57 -0
  211. package/src/lib/html-processor.test.tsx +170 -0
  212. package/src/lib/html-processor.tsx +95 -0
  213. package/src/lib/layout-constants.ts +12 -0
  214. package/src/lib/margin-layout.bench.ts +28 -0
  215. package/src/lib/margin-layout.ts +100 -0
  216. package/src/lib/scroll.test.ts +118 -0
  217. package/src/lib/scroll.ts +47 -0
  218. package/src/lib/shortcut-registry.test.ts +173 -0
  219. package/src/lib/shortcut-registry.ts +209 -0
  220. package/src/lib/utils.test.ts +110 -0
  221. package/src/lib/utils.ts +61 -0
  222. package/src/main.tsx +10 -0
  223. package/src/server/index.ts +883 -0
  224. package/src/store/index.test.ts +220 -0
  225. package/src/store/index.ts +234 -0
  226. package/src/test-setup.ts +1 -0
  227. package/src/types/index.ts +115 -0
  228. package/test.md +74 -0
  229. package/tsconfig.cli.json +12 -0
  230. package/tsconfig.json +20 -0
  231. package/vite.config.ts +19 -0
  232. package/vitest.config.ts +15 -0
  233. package/dist/assets/_basePickBy-hOr-yGsE.js +0 -1
  234. package/dist/assets/_baseUniq-b7bzdUSn.js +0 -1
  235. package/dist/assets/arc-D65wG9gm.js +0 -1
  236. package/dist/assets/architecture-PBZL5I3N-DBa6CAv_.js +0 -1
  237. package/dist/assets/architectureDiagram-2XIMDMQ5-Djwpsh98.js +0 -36
  238. package/dist/assets/array-DOVTz2Mq.js +0 -1
  239. package/dist/assets/blockDiagram-WCTKOSBZ-BdW5TTxj.js +0 -132
  240. package/dist/assets/c4Diagram-IC4MRINW-DTmkHEXu.js +0 -10
  241. package/dist/assets/channel-B3MUFipN.js +0 -1
  242. package/dist/assets/chunk-4BX2VUAB-DEqzsvDc.js +0 -1
  243. package/dist/assets/chunk-55IACEB6-BzVuSUV8.js +0 -1
  244. package/dist/assets/chunk-7E7YKBS2-CZ8IcA4c.js +0 -1
  245. package/dist/assets/chunk-7R4GIKGN-CWVVC8HX.js +0 -79
  246. package/dist/assets/chunk-C72U2L5F-B1Tso5TH.js +0 -1
  247. package/dist/assets/chunk-EGIJ26TM-Cx_7CFik.js +0 -1
  248. package/dist/assets/chunk-FMBD7UC4-Cfk_iGhv.js +0 -15
  249. package/dist/assets/chunk-GEFDOKGD-C_5hRbJt.js +0 -2
  250. package/dist/assets/chunk-GLR3WWYH-CkY7IyBj.js +0 -2
  251. package/dist/assets/chunk-HHEYEP7N-B0I4X5cr.js +0 -1
  252. package/dist/assets/chunk-JSJVCQXG-CAjwlVLg.js +0 -1
  253. package/dist/assets/chunk-KX2RTZJC-DWqnZZ02.js +0 -1
  254. package/dist/assets/chunk-KYZI473N-gjRVhJgJ.js +0 -53
  255. package/dist/assets/chunk-L3YUKLVL-D7C9GuxL.js +0 -1
  256. package/dist/assets/chunk-MX3YWQON-i-77iuVj.js +0 -1
  257. package/dist/assets/chunk-NQ4KR5QH-B22Pvemm.js +0 -220
  258. package/dist/assets/chunk-O4XLMI2P-ZQd5L6ZD.js +0 -7
  259. package/dist/assets/chunk-OZEHJAEY-BaPKTELw.js +0 -1
  260. package/dist/assets/chunk-PQ6SQG4A-DqE1eupT.js +0 -1
  261. package/dist/assets/chunk-PU5JKC2W-BTqWqedh.js +0 -70
  262. package/dist/assets/chunk-QZHKN3VN-Nm9TvMss.js +0 -1
  263. package/dist/assets/chunk-R5LLSJPH-DkiNs1dN.js +0 -1
  264. package/dist/assets/chunk-WL4C6EOR-CioD2fv2.js +0 -189
  265. package/dist/assets/chunk-XIRO2GV7-B4GGQONY.js +0 -1
  266. package/dist/assets/chunk-XPW4576I-C0IbbQos.js +0 -32
  267. package/dist/assets/chunk-XZSTWKYB-DMOqFWmT.js +0 -94
  268. package/dist/assets/chunk-YBOYWFTD-CoeQgeVY.js +0 -1
  269. package/dist/assets/classDiagram-VBA2DB6C-DV9ltQ7h.js +0 -1
  270. package/dist/assets/classDiagram-v2-RAHNMMFH-C6nD9wmM.js +0 -1
  271. package/dist/assets/clone-DuY6BQEm.js +0 -1
  272. package/dist/assets/cose-bilkent-S5V4N54A-B6FexK6p.js +0 -1
  273. package/dist/assets/cytoscape.esm-DoTFyJaN.js +0 -321
  274. package/dist/assets/dagre-CCcocoCU.js +0 -1
  275. package/dist/assets/dagre-KLK3FWXG-DIELowj9.js +0 -4
  276. package/dist/assets/defaultLocale-Ck2Xxk-C.js +0 -1
  277. package/dist/assets/diagram-E7M64L7V-D1mm0PoO.js +0 -24
  278. package/dist/assets/diagram-IFDJBPK2-7DVjly8y.js +0 -43
  279. package/dist/assets/diagram-P4PSJMXO-jO7pfyMb.js +0 -24
  280. package/dist/assets/dist-BywRdrPx.js +0 -1
  281. package/dist/assets/erDiagram-INFDFZHY-DSRxlRFy.js +0 -70
  282. package/dist/assets/flowDiagram-PKNHOUZH-CgKzzNdR.js +0 -162
  283. package/dist/assets/ganttDiagram-A5KZAMGK-CtsE7Y4E.js +0 -292
  284. package/dist/assets/gitGraph-HDMCJU4V-BU9uhwtz.js +0 -1
  285. package/dist/assets/gitGraphDiagram-K3NZZRJ6-DOU8RGdw.js +0 -65
  286. package/dist/assets/graphlib-WkJoBgka.js +0 -1
  287. package/dist/assets/index-CKVArt9D.js +0 -562
  288. package/dist/assets/index-DzRKJazf.css +0 -2
  289. package/dist/assets/info-3K5VOQVL-CPpvM-SG.js +0 -1
  290. package/dist/assets/infoDiagram-LFFYTUFH-VKLs5DsF.js +0 -2
  291. package/dist/assets/init-Bft5Ffpj.js +0 -1
  292. package/dist/assets/isArrayLikeObject-icl0H0jo.js +0 -1
  293. package/dist/assets/isEmpty-Du8sNmkE.js +0 -1
  294. package/dist/assets/ishikawaDiagram-PHBUUO56-CsWvEjux.js +0 -70
  295. package/dist/assets/journeyDiagram-4ABVD52K-BzJGTdIT.js +0 -139
  296. package/dist/assets/kanban-definition-K7BYSVSG-B_9ClJ1A.js +0 -89
  297. package/dist/assets/katex-BJrMXEjr.js +0 -261
  298. package/dist/assets/line-CC_tDGId.js +0 -1
  299. package/dist/assets/linear-Cts_d04Y.js +0 -1
  300. package/dist/assets/math-CNhlSIO3.js +0 -1
  301. package/dist/assets/mermaid-parser.core-Vb9KKv1R.js +0 -4
  302. package/dist/assets/mermaid.core-C_7xsp3d.js +0 -11
  303. package/dist/assets/mindmap-definition-YRQLILUH-BWmfy5wB.js +0 -68
  304. package/dist/assets/ordinal-DIg8h6NI.js +0 -1
  305. package/dist/assets/packet-RMMSAZCW-Q-WG6o3b.js +0 -1
  306. package/dist/assets/path-DfRbCp9y.js +0 -1
  307. package/dist/assets/pie-UPGHQEXC-Cwi2tLlt.js +0 -1
  308. package/dist/assets/pieDiagram-SKSYHLDU-Dyf3X_in.js +0 -30
  309. package/dist/assets/quadrantDiagram-337W2JSQ-B5_5m61Q.js +0 -7
  310. package/dist/assets/radar-KQ55EAFF-Dtw2VzxY.js +0 -1
  311. package/dist/assets/requirementDiagram-Z7DCOOCP-BSERBnlW.js +0 -73
  312. package/dist/assets/rough.esm-KjoEK0it.js +0 -1
  313. package/dist/assets/sankeyDiagram-WA2Y5GQK-CMcEY8Cz.js +0 -10
  314. package/dist/assets/sequenceDiagram-2WXFIKYE-D28qcXwC.js +0 -145
  315. package/dist/assets/src-C8kkzlHX.js +0 -1
  316. package/dist/assets/stateDiagram-RAJIS63D-7oVrCmRl.js +0 -1
  317. package/dist/assets/stateDiagram-v2-FVOUBMTO-DtFptQAd.js +0 -1
  318. package/dist/assets/timeline-definition-YZTLITO2-rbCfBEvG.js +0 -61
  319. package/dist/assets/treemap-KZPCXAKY-BlRvF0um.js +0 -1
  320. package/dist/assets/vennDiagram-LZ73GAT5-DBit3zWa.js +0 -34
  321. package/dist/assets/xychartDiagram-JWTSCODW-BVYXv51y.js +0 -7
  322. package/dist/index.js +0 -1040
@@ -0,0 +1,76 @@
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)
@@ -0,0 +1,65 @@
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.
@@ -0,0 +1,142 @@
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.
@@ -0,0 +1,83 @@
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
+ ```
@@ -0,0 +1,38 @@
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
+ ```
@@ -0,0 +1,142 @@
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 (Vite + CLI)
15
+ bun run build # Build for production
16
+ bun run test # Run tests
17
+ bun run typecheck # Run TypeScript checks
18
+ bun run check # Run Biome (lint + format check)
19
+ bun run check:fix # Fix lint + format issues
20
+ bun run format # Format with Biome
21
+
22
+ # Usage
23
+ bunx readit <file.md> # Review Markdown file
24
+ bunx readit <file.html> # Review HTML file
25
+ bunx readit <file.md> --port 3000 # Custom port
26
+ bunx readit <file.md> --host 0.0.0.0 # Custom host address
27
+ bunx readit <file.md> --no-open # Don't auto-open browser
28
+ bunx readit <file.md> --clean # Clear existing comments
29
+
30
+ bunx readit list # List all files with comments
31
+ bunx readit show <file.md> # Show comments for a file
32
+ ```
33
+
34
+ ## Architecture
35
+
36
+ ```
37
+ readit/
38
+ ├── src/
39
+ │ ├── cli/
40
+ │ │ └── index.ts # CLI entry point (Commander.js)
41
+ │ ├── server/
42
+ │ │ └── index.ts # Bun.serve() server + API routes
43
+ │ ├── components/
44
+ │ │ ├── Header.tsx
45
+ │ │ ├── DocumentViewer.tsx # Renders MD (react-markdown) or HTML (IframeContainer)
46
+ │ │ ├── IframeContainer.tsx # Isolated HTML rendering with comment support
47
+ │ │ ├── CodeBlock.tsx # Syntax-highlighted code blocks
48
+ │ │ ├── CommentInputArea.tsx
49
+ │ │ ├── CommentListItem.tsx # Comment item in manager dropdown
50
+ │ │ ├── CommentManagerDropdown.tsx # Dropdown menu for managing comments
51
+ │ │ ├── CommentMinimap.tsx # Visual minimap of comment positions
52
+ │ │ ├── CommentNavigator.tsx # Navigate between comments
53
+ │ │ ├── FloatingTOC.tsx # Floating TOC button (fullscreen mode)
54
+ │ │ ├── MarginNote.tsx # Individual margin note
55
+ │ │ ├── MarginNotesContainer.tsx
56
+ │ │ ├── MermaidDiagram.tsx # Mermaid diagram rendering
57
+ │ │ ├── RawCommentsModal.tsx # View raw .comments.md file
58
+ │ │ ├── SettingsModal.tsx # Settings modal (font preferences)
59
+ │ │ ├── TableOfContents.tsx # Document headings navigation
60
+ │ │ └── index.ts
61
+ │ ├── hooks/
62
+ │ │ ├── useComments.ts # Comment state management
63
+ │ │ ├── useCommentNavigation.ts # Navigate between comments
64
+ │ │ ├── useDocument.ts # Document fetching and state
65
+ │ │ ├── useFontPreference.ts # Font preference with server persistence
66
+ │ │ ├── useHeadings.ts # Extract headings from document
67
+ │ │ ├── useLayoutMode.ts # Layout mode toggle (centered/fullscreen)
68
+ │ │ ├── useReanchorMode.ts # Re-anchor mode for unresolved comments
69
+ │ │ ├── useScrollMetrics.ts # Scroll position tracking
70
+ │ │ ├── useScrollSpy.ts # Track scroll position for TOC
71
+ │ │ ├── useTextSelection.ts # Text selection handling
72
+ │ │ └── index.ts
73
+ │ ├── lib/
74
+ │ │ ├── anchor.ts # Anchor-based comment resolution
75
+ │ │ ├── comment-storage.ts # File-based comment storage
76
+ │ │ ├── context.ts # LLM context extraction
77
+ │ │ ├── export.ts # Export utilities (JSON, prompt format)
78
+ │ │ ├── layout-constants.ts # Layout dimensions and breakpoints
79
+ │ │ ├── margin-layout.ts # Margin note position resolution
80
+ │ │ ├── scroll.ts # Scroll calculation utilities
81
+ │ │ ├── utils.ts # Common utilities (cn, etc.)
82
+ │ │ └── highlight/ # Text highlighting system
83
+ │ │ ├── index.ts
84
+ │ │ ├── highlighter.ts # Unified highlighter factory
85
+ │ │ ├── core.ts # Core highlight logic
86
+ │ │ ├── dom.ts # DOM manipulation
87
+ │ │ ├── colors.ts # Comment color palette
88
+ │ │ ├── types.ts # Type definitions
89
+ │ │ └── script-builder.ts
90
+ │ ├── types/
91
+ │ │ └── index.ts # Shared types
92
+ │ ├── App.tsx # Main React component
93
+ │ ├── main.tsx # React entry point
94
+ │ └── index.css # Tailwind styles
95
+ ├── dist/ # Built output
96
+ ├── .claude/ # AI agent docs
97
+ │ ├── user-stories.md
98
+ │ ├── roadmap.md
99
+ │ └── settings.json
100
+ ├── CLAUDE.md # This file
101
+ ├── AGENTS.md # AI agent instructions
102
+ └── CHANGELOG.md # Version changelog
103
+ ```
104
+
105
+ ## Key Design Decisions
106
+
107
+ 1. **react-markdown for Markdown**: Client-side rendering, no external dependencies
108
+ 2. **unified/rehype for HTML**: Safe HTML rendering with XSS protection via html-processor
109
+ 3. **IframeContainer for HTML isolation**: Renders HTML in sandboxed iframe to prevent style/script leakage
110
+ 4. **Margin notes UX**: Comments appear as margin notes next to highlighted text (Google Docs style)
111
+ 5. **File-based comments**: Human-readable `.comments.md` files stored in `~/.readit/comments/`
112
+ 6. **difit-style UX**: CLI → local server → browser, familiar pattern
113
+ 7. **Hooks for state**: Custom hooks for comment management
114
+
115
+ ## Tech Stack
116
+
117
+ - **Runtime**: Bun
118
+ - **CLI**: Commander.js for argument parsing
119
+ - **Server**: Bun.serve() for API and static files
120
+ - **Markdown Rendering**: react-markdown
121
+ - **HTML Rendering**: unified + rehype-parse + rehype-react (with XSS sanitization)
122
+ - **Frontend**: React 19 + TypeScript + Vite
123
+ - **Styling**: Tailwind CSS v4
124
+ - **Testing**: Vitest
125
+ - **Quality**: Biome (lint + format), lefthook
126
+
127
+ ## Current Limitations
128
+
129
+ - Comments use text offset, may break if document changes significantly
130
+ - No comment status tracking yet (resolved/unresolved planned for v0.3.0)
131
+
132
+ ## User Stories
133
+
134
+ See `.claude/user-stories.md` for detailed user stories and acceptance criteria.
135
+
136
+ ## Code Style
137
+
138
+ - TypeScript strict mode
139
+ - Functional React components with hooks
140
+ - Tailwind for styling (no CSS-in-JS)
141
+ - ESM modules throughout
142
+ - Co-located test files (`*.test.ts`)
@@ -0,0 +1,120 @@
1
+ # Code Review: 本質的な課題発見と解決
2
+
3
+ Review code in $ARGUMENTS for **fundamental design issues**, not surface-level cleanup. Use extended thinking (ultrathink).
4
+
5
+ **Philosophy**: Find root causes, but respect the codebase's simplicity-first approach. From `style-guide.md`:
6
+
7
+ - "Obvious over clever" - Can you understand it in 5 seconds?
8
+ - "Duplication over wrong abstraction" - Write it twice, abstract on the third
9
+ - "Simple over complex" - Prefer imperative solutions over abstractions
10
+ - "Do not model state machines or data with classes" - Use discriminated unions sparingly
11
+
12
+ **CRITICAL**: Do NOT suggest new abstractions (state machines, wrapper classes, generic utilities) unless the same pattern appears 3+ times. Prefer inline, obvious code.
13
+
14
+ ## What to Look For
15
+
16
+ Reference `.claude/rules/style-guide.md` for detailed examples.
17
+
18
+ ### 1. Abstractions & Decomposition
19
+
20
+ - §9.2 Refactoring & Anti-Patterns - Premature abstraction, wrong boundaries
21
+ - §3.2 Balanced Function Decomposition - When to extract vs inline
22
+
23
+ ### 2. Type Design
24
+
25
+ - §2.1 Parse, Don't Validate - Transform at boundaries, don't re-validate
26
+ - §2.2 Discriminated Unions Over Classes - Exhaustive checking, no inheritance
27
+ - §6.3 No Enums - Use const object pattern
28
+
29
+ ### 3. Control Flow
30
+
31
+ - §3.3 Early Returns and Guard Clauses - Happy path at root indentation
32
+ - §3.3.1 Prefer Early Returns Over `let` Accumulation
33
+ - §7.2 Sequential vs Parallel Processing - Right async pattern for the job
34
+ - §4.1 Single Try-Catch for Related Operations
35
+
36
+ ### 4. Function Design
37
+
38
+ - §3.5 Object Destructuring for Opaque Parameters
39
+ - §3.1 Simple Over Complex - Prefer imperative over functional abstractions
40
+
41
+ ### 5. Code Hygiene (Always Check)
42
+
43
+ - §3.4 Naming Conventions - No generic names, Hungarian notation, abbreviations
44
+ - §3.2 Superfluous abstractions - Inline trivial one-liners
45
+ - Comments - Delete restating JSDoc, commented-out code, TODOs without tickets
46
+ - Dead code - Remove unused imports, uncalled methods, unread variables
47
+
48
+ ## Review Process
49
+
50
+ 1. **Understand the use case** - What is this code trying to accomplish?
51
+ 2. **Trace the data flow** - Follow the data from input to output
52
+ 3. **Question abstractions** - Does this class/function earn its existence? Could it be simpler?
53
+ 4. **Resist adding complexity** - The fix should simplify, not add layers
54
+
55
+ ## Output Format
56
+
57
+ ```markdown
58
+ ## 本質的な課題 (Fundamental Issues)
59
+
60
+ ### [Critical/High/Medium] Issue Title
61
+ **Root Cause**: Why this problem exists at the design level
62
+ **Symptom**: What you observe in the code
63
+ **Location**: `path/to/file.ts:123`
64
+ **Proposed Fix**: How to simplify (prefer removal/inlining over adding new abstractions)
65
+
66
+ ## Surface Issues (Lower Priority)
67
+ - Brief list of naming, formatting, comment issues (fix these only after fundamental issues)
68
+ ```
69
+
70
+ ## Fix Approach
71
+
72
+ **For fundamental issues:**
73
+
74
+ 1. Propose the simplest fix first (often: inline, remove, or merge)
75
+ 2. Ask for confirmation if the change affects multiple files or public interfaces
76
+ 3. Implement the fix
77
+
78
+ **For surface issues:**
79
+
80
+ 1. Fix silently after addressing fundamental issues
81
+ 2. Run `pnpm turbo run fix` to format
82
+
83
+ ## Anti-patterns to Flag
84
+
85
+ - **Adding abstraction to fix a bug** - Symptom-fixing vs root cause
86
+ - **Creating a "utils" function** - Find the right home or inline it
87
+ - **Wrapper functions that just pass through** - No value added, remove them
88
+ - **Extracting trivial operations** - `name.replace(/_id_seq$/, "")` should stay inline
89
+ - **Boolean parameters** - Should often be two separate functions
90
+
91
+ ## When Abstractions ARE Appropriate
92
+
93
+ **State machines** - Use when:
94
+
95
+ - There are distinct, named states (e.g., VOID → EVENT_CREATED → BOT_SCHEDULED)
96
+ - Transitions between states have specific actions
97
+ - The switch statement covers all state combinations exhaustively
98
+
99
+ **Don't use** state machines for:
100
+
101
+ - Simple if/else that can be early returns
102
+ - Boolean flags that don't represent true states
103
+ - "Just in case" future flexibility
104
+
105
+ **New types/classes** - Use when:
106
+
107
+ - Pattern repeats 3+ times
108
+ - Encapsulates meaningful domain complexity
109
+ - Makes invalid states unrepresentable
110
+
111
+ ## Anti-patterns to AVOID Suggesting
112
+
113
+ - Generic utility wrappers
114
+ - New abstraction layers for 1-2 use cases
115
+ - "Future-proofing" changes
116
+ - State machines for simple conditional logic
117
+
118
+ ---
119
+
120
+ Now analyze: $ARGUMENTS