@plannotator/ui 0.22.0

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 (305) hide show
  1. package/README.md +60 -0
  2. package/assets/diff-options.png +0 -0
  3. package/assets/icon-codex.png +0 -0
  4. package/assets/look-flat.png +0 -0
  5. package/assets/look-grid.png +0 -0
  6. package/assets/review-sections.png +0 -0
  7. package/assets/review-tree.png +0 -0
  8. package/assets/workspaces.webp +0 -0
  9. package/components/AISettingsTab.tsx +145 -0
  10. package/components/ActionMenu.tsx +101 -0
  11. package/components/AgentControls.tsx +216 -0
  12. package/components/AgentsTab.tsx +1294 -0
  13. package/components/AnnotationPanel.tsx +731 -0
  14. package/components/AnnotationSidebar.tsx +86 -0
  15. package/components/AnnotationToolbar.tsx +323 -0
  16. package/components/AnnotationToolstrip.tsx +355 -0
  17. package/components/ApproveDropdown.tsx +170 -0
  18. package/components/AttachmentsButton.tsx +410 -0
  19. package/components/BlockRenderer.tsx +163 -0
  20. package/components/BorderTrail.tsx +38 -0
  21. package/components/CodeFilePicker.tsx +64 -0
  22. package/components/CodeFilePopout.tsx +602 -0
  23. package/components/CodePathValidationContext.tsx +14 -0
  24. package/components/CommentPopover.tsx +512 -0
  25. package/components/CompletionOverlay.tsx +99 -0
  26. package/components/ConfirmDialog.tsx +128 -0
  27. package/components/DocBadges.tsx +231 -0
  28. package/components/EditorAnnotationCard.tsx +65 -0
  29. package/components/ExportModal.tsx +565 -0
  30. package/components/FloatingQuickLabelPicker.tsx +144 -0
  31. package/components/GitHubIcon.tsx +16 -0
  32. package/components/GitLabIcon.tsx +30 -0
  33. package/components/GraphvizBlock.tsx +511 -0
  34. package/components/ImageAnnotator/Canvas.tsx +118 -0
  35. package/components/ImageAnnotator/Toolbar.tsx +218 -0
  36. package/components/ImageAnnotator/index.tsx +272 -0
  37. package/components/ImageAnnotator/types.ts +39 -0
  38. package/components/ImageAnnotator/utils.ts +147 -0
  39. package/components/ImageThumbnail.tsx +126 -0
  40. package/components/ImportModal.tsx +146 -0
  41. package/components/InlineMarkdown.tsx +1094 -0
  42. package/components/KeyboardShortcuts.tsx +208 -0
  43. package/components/Landing.tsx +496 -0
  44. package/components/ListItemBody.tsx +62 -0
  45. package/components/ListMarker.tsx +73 -0
  46. package/components/LookAndFeelAnnouncementDialog.tsx +230 -0
  47. package/components/MarkdownEditor.tsx +44 -0
  48. package/components/MenuVersionSection.tsx +91 -0
  49. package/components/MermaidBlock.tsx +579 -0
  50. package/components/ModeToggle.tsx +68 -0
  51. package/components/OpenInAppButton.tsx +299 -0
  52. package/components/OverlayScrollArea.tsx +82 -0
  53. package/components/PermissionModeSetup.tsx +92 -0
  54. package/components/PinpointOverlay.tsx +99 -0
  55. package/components/PlanAIAnnouncementDialog.tsx +187 -0
  56. package/components/PlanHeaderMenu.tsx +299 -0
  57. package/components/PopoutDialog.tsx +91 -0
  58. package/components/Popover.tsx +27 -0
  59. package/components/ProviderIcons.tsx +51 -0
  60. package/components/PullRequestIcon.tsx +12 -0
  61. package/components/QuickLabelDropdown.tsx +63 -0
  62. package/components/RenderedMarkdown.tsx +54 -0
  63. package/components/RepoIcon.tsx +12 -0
  64. package/components/ResizeHandle.tsx +86 -0
  65. package/components/ReviewAgentsIcon.tsx +18 -0
  66. package/components/SearchableSelect.tsx +157 -0
  67. package/components/Settings.tsx +2220 -0
  68. package/components/SparklesIcon.tsx +45 -0
  69. package/components/StickyHeaderLane.tsx +260 -0
  70. package/components/TableOfContents.tsx +157 -0
  71. package/components/TaterSpritePullup.tsx +34 -0
  72. package/components/TaterSpriteRunning.tsx +54 -0
  73. package/components/TaterSpriteSitting.tsx +37 -0
  74. package/components/TextShimmer.tsx +57 -0
  75. package/components/ThemeProvider.tsx +162 -0
  76. package/components/ThemeTab.tsx +139 -0
  77. package/components/ToolbarButtons.tsx +116 -0
  78. package/components/Tooltip.tsx +45 -0
  79. package/components/Viewer.tsx +977 -0
  80. package/components/ai/AIProviderBar.tsx +95 -0
  81. package/components/ai/DocumentAIChatPanel.tsx +313 -0
  82. package/components/blocks/AlertBlock.tsx +58 -0
  83. package/components/blocks/Callout.tsx +60 -0
  84. package/components/blocks/CodeBlock.tsx +75 -0
  85. package/components/blocks/HtmlBlock.tsx +122 -0
  86. package/components/blocks/MathBlock.tsx +36 -0
  87. package/components/blocks/TableBlock.tsx +146 -0
  88. package/components/blocks/TablePopout.tsx +279 -0
  89. package/components/blocks/TableToolbar.tsx +153 -0
  90. package/components/blocks/proseBody.tsx +102 -0
  91. package/components/core/button.tsx +44 -0
  92. package/components/core/textarea.tsx +26 -0
  93. package/components/diagramLanguages.ts +14 -0
  94. package/components/goal-setup/GoalSetupSurface.tsx +1354 -0
  95. package/components/html-viewer/HtmlViewer.tsx +386 -0
  96. package/components/html-viewer/bridge-script.ts +505 -0
  97. package/components/html-viewer/index.ts +1 -0
  98. package/components/html-viewer/useHtmlAnnotation.ts +400 -0
  99. package/components/icons/AgentIcons.tsx +66 -0
  100. package/components/icons/AppIcon.tsx +56 -0
  101. package/components/icons/MessagesIcon.tsx +11 -0
  102. package/components/icons/ObsidianIcons.tsx +208 -0
  103. package/components/icons/app/android-studio.svg +369 -0
  104. package/components/icons/app/antigravity.svg +97 -0
  105. package/components/icons/app/cursor.svg +16 -0
  106. package/components/icons/app/file-explorer.svg +20 -0
  107. package/components/icons/app/finder.png +0 -0
  108. package/components/icons/app/ghostty.svg +13 -0
  109. package/components/icons/app/iterm2.svg +13 -0
  110. package/components/icons/app/powershell.svg +14 -0
  111. package/components/icons/app/sublime-text.svg +17 -0
  112. package/components/icons/app/terminal.png +0 -0
  113. package/components/icons/app/textmate.png +0 -0
  114. package/components/icons/app/vscode.svg +39 -0
  115. package/components/icons/app/warp.png +0 -0
  116. package/components/icons/app/xcode.png +0 -0
  117. package/components/icons/app/zed-dark.svg +15 -0
  118. package/components/icons/app/zed.svg +15 -0
  119. package/components/icons/themeIcons.tsx +47 -0
  120. package/components/mermaidSvg.ts +33 -0
  121. package/components/plan-diff/PlanCleanDiffView.tsx +884 -0
  122. package/components/plan-diff/PlanDiffBadge.tsx +48 -0
  123. package/components/plan-diff/PlanDiffModeSwitcher.tsx +103 -0
  124. package/components/plan-diff/PlanDiffViewer.tsx +214 -0
  125. package/components/plan-diff/PlanRawDiffView.tsx +102 -0
  126. package/components/plan-diff/VSCodeIcon.tsx +132 -0
  127. package/components/settings/HooksTab.tsx +208 -0
  128. package/components/sidebar/ArchiveBrowser.tsx +98 -0
  129. package/components/sidebar/CountBadge.tsx +12 -0
  130. package/components/sidebar/FileBrowser.tsx +498 -0
  131. package/components/sidebar/MessagesBrowser.tsx +109 -0
  132. package/components/sidebar/SidebarContainer.tsx +353 -0
  133. package/components/sidebar/SidebarTabs.tsx +155 -0
  134. package/components/sidebar/VersionBrowser.tsx +141 -0
  135. package/components/types.d.ts +7 -0
  136. package/components/ui/badge.tsx +44 -0
  137. package/components/ui/button.tsx +83 -0
  138. package/components/ui/card.tsx +58 -0
  139. package/components/ui/dialog.tsx +106 -0
  140. package/components/ui/dropdown-menu.tsx +240 -0
  141. package/components/ui/state-pill.tsx +45 -0
  142. package/components/ui/tabs.tsx +46 -0
  143. package/components/ui/textarea.tsx +25 -0
  144. package/config/configStore.ts +214 -0
  145. package/config/index.ts +4 -0
  146. package/config/reviewView.ts +42 -0
  147. package/config/settings.ts +310 -0
  148. package/config/useConfig.ts +20 -0
  149. package/configure.ts +69 -0
  150. package/globals.d.ts +14 -0
  151. package/hooks/pfm/useCodeFilePopout.ts +111 -0
  152. package/hooks/useAIChat.ts +532 -0
  153. package/hooks/useAIProviderConfig.ts +115 -0
  154. package/hooks/useActiveSection.ts +78 -0
  155. package/hooks/useAgentJobs.ts +306 -0
  156. package/hooks/useAgentSettings.ts +579 -0
  157. package/hooks/useAgents.ts +90 -0
  158. package/hooks/useAnnotationDraft.ts +523 -0
  159. package/hooks/useAnnotationHighlighter.ts +1170 -0
  160. package/hooks/useArchive.ts +171 -0
  161. package/hooks/useAutoClose.ts +104 -0
  162. package/hooks/useCodeAnnotationDraft.ts +194 -0
  163. package/hooks/useCodeFilePopout.ts +1 -0
  164. package/hooks/useDismissOnOutsideAndEscape.ts +50 -0
  165. package/hooks/useDraggable.ts +108 -0
  166. package/hooks/useEditorAnnotations.ts +64 -0
  167. package/hooks/useExternalAnnotationHighlights.ts +105 -0
  168. package/hooks/useExternalAnnotations.ts +268 -0
  169. package/hooks/useFileBrowser.ts +402 -0
  170. package/hooks/useInputMethodSwitch.ts +89 -0
  171. package/hooks/useIsMobile.ts +17 -0
  172. package/hooks/useLinkedDoc.ts +494 -0
  173. package/hooks/useOverlayViewport.ts +36 -0
  174. package/hooks/usePinpoint.ts +182 -0
  175. package/hooks/usePlanDiff.ts +176 -0
  176. package/hooks/usePrintMode.ts +27 -0
  177. package/hooks/useResizablePanel.ts +173 -0
  178. package/hooks/useScrollViewport.ts +38 -0
  179. package/hooks/useSharing.ts +441 -0
  180. package/hooks/useSidebar.ts +55 -0
  181. package/hooks/useUpdateCheck.ts +132 -0
  182. package/hooks/useValidatedCodePaths.ts +94 -0
  183. package/icons/GitUser.tsx +17 -0
  184. package/lib/utils.ts +11 -0
  185. package/package.json +117 -0
  186. package/plannotator.webp +0 -0
  187. package/print.css +427 -0
  188. package/shortcuts/code-review/ai.shortcuts.ts +25 -0
  189. package/shortcuts/code-review/allFilesDiff.shortcuts.ts +46 -0
  190. package/shortcuts/code-review/annotationToolbar.shortcuts.ts +30 -0
  191. package/shortcuts/code-review/fileTree.shortcuts.ts +35 -0
  192. package/shortcuts/code-review/prComments.shortcuts.ts +18 -0
  193. package/shortcuts/code-review/suggestionModal.shortcuts.ts +25 -0
  194. package/shortcuts/code-review/tourDialog.shortcuts.ts +18 -0
  195. package/shortcuts/core.ts +399 -0
  196. package/shortcuts/index.ts +21 -0
  197. package/shortcuts/plan-review/annotationPanel.shortcuts.ts +25 -0
  198. package/shortcuts/plan-review/annotationToolbar.shortcuts.ts +39 -0
  199. package/shortcuts/plan-review/commentPopover.shortcuts.ts +21 -0
  200. package/shortcuts/plan-review/goalSetup.shortcuts.ts +10 -0
  201. package/shortcuts/plan-review/imageAnnotator.shortcuts.ts +42 -0
  202. package/shortcuts/plan-review/inputMethod.shortcuts.ts +30 -0
  203. package/shortcuts/plan-review/sidebar.shortcuts.ts +34 -0
  204. package/shortcuts/plan-review/viewer.shortcuts.ts +24 -0
  205. package/shortcuts/runtime.ts +259 -0
  206. package/sprite_package_additional/index.html +34 -0
  207. package/sprite_package_additional/sprite.png +0 -0
  208. package/sprite_package_new/index.html +34 -0
  209. package/sprite_package_new/sprite.png +0 -0
  210. package/sprite_package_pulluphang/index.html +34 -0
  211. package/sprite_package_pulluphang/sprite.png +0 -0
  212. package/styles.css +1 -0
  213. package/theme.css +893 -0
  214. package/themes/adwaita.css +62 -0
  215. package/themes/andromeeda.css +66 -0
  216. package/themes/aurora-x.css +66 -0
  217. package/themes/ayu-dark.css +66 -0
  218. package/themes/caffeine.css +113 -0
  219. package/themes/catppuccin.css +62 -0
  220. package/themes/claude-plus.css +60 -0
  221. package/themes/cursor-hc.css +34 -0
  222. package/themes/cursor-midnight.css +34 -0
  223. package/themes/cursor.css +62 -0
  224. package/themes/dark-plus.css +66 -0
  225. package/themes/doom-64.css +109 -0
  226. package/themes/dracula.css +33 -0
  227. package/themes/everforest-hard.css +62 -0
  228. package/themes/everforest-soft.css +62 -0
  229. package/themes/everforest.css +62 -0
  230. package/themes/github.css +66 -0
  231. package/themes/gruvbox.css +62 -0
  232. package/themes/houston.css +66 -0
  233. package/themes/kanagawa-dragon.css +34 -0
  234. package/themes/kanagawa-lotus.css +34 -0
  235. package/themes/kanagawa-wave.css +34 -0
  236. package/themes/laserwave.css +66 -0
  237. package/themes/material.css +62 -0
  238. package/themes/min.css +66 -0
  239. package/themes/monokai-pro.css +34 -0
  240. package/themes/neutral.css +59 -0
  241. package/themes/night-owl.css +66 -0
  242. package/themes/nord.css +66 -0
  243. package/themes/one-dark-pro.css +66 -0
  244. package/themes/one-light.css +66 -0
  245. package/themes/paulmillr.css +34 -0
  246. package/themes/plannotator.css +60 -0
  247. package/themes/plastic.css +66 -0
  248. package/themes/poimandres.css +66 -0
  249. package/themes/quantum-rose.css +109 -0
  250. package/themes/red.css +66 -0
  251. package/themes/rose-pine.css +62 -0
  252. package/themes/simple.css +124 -0
  253. package/themes/slack.css +66 -0
  254. package/themes/snazzy-light.css +66 -0
  255. package/themes/soft-pop.css +60 -0
  256. package/themes/solar-dusk.css +109 -0
  257. package/themes/solarized.css +66 -0
  258. package/themes/synthwave-84.css +34 -0
  259. package/themes/terminal.css +62 -0
  260. package/themes/tinacious.css +57 -0
  261. package/themes/tokyo-night.css +62 -0
  262. package/themes/vesper.css +62 -0
  263. package/themes/vitesse-black.css +66 -0
  264. package/themes/vitesse.css +62 -0
  265. package/types.ts +264 -0
  266. package/utils/agentSwitch.ts +71 -0
  267. package/utils/aiChatFormat.ts +33 -0
  268. package/utils/aiPrompt.ts +29 -0
  269. package/utils/aiProvider.ts +217 -0
  270. package/utils/anchors.ts +11 -0
  271. package/utils/annotateAgentTerminal.ts +29 -0
  272. package/utils/annotationHelpers.ts +101 -0
  273. package/utils/bear.ts +59 -0
  274. package/utils/blockTargeting.ts +240 -0
  275. package/utils/callback.ts +99 -0
  276. package/utils/commentContent.ts +8 -0
  277. package/utils/defaultNotesApp.ts +20 -0
  278. package/utils/diffFonts.ts +33 -0
  279. package/utils/editorMode.ts +31 -0
  280. package/utils/fileBrowser.ts +40 -0
  281. package/utils/generateId.ts +7 -0
  282. package/utils/generateIdentity.ts +29 -0
  283. package/utils/identity.ts +112 -0
  284. package/utils/inlineTransforms.ts +41 -0
  285. package/utils/inputMethod.ts +17 -0
  286. package/utils/lookAndFeelAnnouncement.ts +18 -0
  287. package/utils/obsidian.ts +201 -0
  288. package/utils/octarine.ts +53 -0
  289. package/utils/parser.ts +991 -0
  290. package/utils/permissionMode.ts +77 -0
  291. package/utils/planAIAnnouncement.ts +17 -0
  292. package/utils/planAgentInstructions.ts +137 -0
  293. package/utils/planDiffEngine.ts +590 -0
  294. package/utils/planSave.ts +49 -0
  295. package/utils/platform.ts +11 -0
  296. package/utils/quickLabels.ts +77 -0
  297. package/utils/reviewAgentInstructions.ts +182 -0
  298. package/utils/sanitizeHtml.ts +45 -0
  299. package/utils/sharing.ts +350 -0
  300. package/utils/slugify.ts +37 -0
  301. package/utils/storage.ts +141 -0
  302. package/utils/themeRegistry.ts +567 -0
  303. package/utils/uiPreferences.ts +34 -0
  304. package/utils/upload.ts +56 -0
  305. package/utils/wideMode.ts +48 -0
@@ -0,0 +1,94 @@
1
+ import { useEffect, useMemo, useState } from "react";
2
+ import { extractCandidateCodePaths } from "@plannotator/core/extract-code-paths";
3
+
4
+ export type ValidationEntry =
5
+ | { status: "found"; resolved: string }
6
+ | { status: "ambiguous"; matches: string[] }
7
+ | { status: "missing" }
8
+ | { status: "unavailable" };
9
+
10
+ export type ValidatedMap = Map<string, ValidationEntry>;
11
+
12
+ /**
13
+ * Extracts code-file path candidates from `markdown` and posts them to
14
+ * `/api/doc/exists` once per markdown change. The server has typically
15
+ * pre-warmed the file walk at plan/annotate load, so the response is fast.
16
+ *
17
+ * `validated` is empty until `ready` flips to true, at which point it holds
18
+ * an entry for every candidate (including missing/unavailable ones). The
19
+ * renderer dispatches on status — see InlineMarkdown.
20
+ *
21
+ * Empty candidate set short-circuits — no fetch, ready: true immediately.
22
+ *
23
+ * `baseDir` is the directory the active document lives in (linked-doc parent
24
+ * or the annotate source file's parent). When set, the server tries
25
+ * `<baseDir>/<input>` literal-resolve before its cwd walk so out-of-tree
26
+ * relative references (e.g. `../script.ts` in `~/notes/foo.md`) don't get
27
+ * demoted to plain text.
28
+ */
29
+ export function useValidatedCodePaths(
30
+ markdown: string,
31
+ baseDir?: string,
32
+ disabled?: boolean,
33
+ ): { validated: ValidatedMap; ready: boolean } {
34
+ const [validated, setValidated] = useState<ValidatedMap>(new Map());
35
+ const [ready, setReady] = useState<boolean>(false);
36
+
37
+ useEffect(() => {
38
+ setValidated(new Map());
39
+ setReady(false);
40
+
41
+ // Host opt-out (e.g. a backend with no /api/doc/exists). Default undefined
42
+ // for Plannotator => unchanged. When disabled we never probe and leave
43
+ // ready=false, so gateCodePath's no-validation fallback renders code links
44
+ // optimistically (clickable) instead of demoting them to plain text.
45
+ if (disabled) {
46
+ return;
47
+ }
48
+
49
+ const candidates = extractCandidateCodePaths(markdown);
50
+ if (candidates.length === 0) {
51
+ setReady(true);
52
+ return;
53
+ }
54
+
55
+ let cancelled = false;
56
+ (async () => {
57
+ try {
58
+ const res = await fetch("/api/doc/exists", {
59
+ method: "POST",
60
+ headers: { "Content-Type": "application/json" },
61
+ body: JSON.stringify(
62
+ baseDir ? { paths: candidates, base: baseDir } : { paths: candidates },
63
+ ),
64
+ });
65
+ if (cancelled) return;
66
+ if (!res.ok) {
67
+ setReady(true);
68
+ return;
69
+ }
70
+ const data = (await res.json()) as {
71
+ results: Record<string, ValidationEntry>;
72
+ };
73
+ if (cancelled) return;
74
+ const next: ValidatedMap = new Map();
75
+ for (const [k, v] of Object.entries(data.results ?? {})) {
76
+ next.set(k, v);
77
+ }
78
+ setValidated(next);
79
+ setReady(true);
80
+ } catch {
81
+ if (!cancelled) setReady(true);
82
+ }
83
+ })();
84
+
85
+ return () => {
86
+ cancelled = true;
87
+ };
88
+ }, [markdown, baseDir, disabled]);
89
+
90
+ // Stable reference: only changes when validated/ready actually change.
91
+ // Without memoization, the parent provider's value is a fresh object every
92
+ // render, forcing all context consumers (every InlineMarkdown) to re-render.
93
+ return useMemo(() => ({ validated, ready }), [validated, ready]);
94
+ }
@@ -0,0 +1,17 @@
1
+ import * as React from "react";
2
+
3
+ export const GitUser: React.FC<{ className?: string }> = ({ className }) => (
4
+ <svg
5
+ xmlns="http://www.w3.org/2000/svg"
6
+ className={className}
7
+ viewBox="0 0 97 104.44"
8
+ fill="currentColor"
9
+ >
10
+ {/* <!-- Git logo --> */}
11
+ <path d="M92.71 44.408 52.591 4.291c-2.31-2.311-6.057-2.311-8.369 0l-8.33 8.332L46.459 23.19c2.456-.83 5.272-.273 7.229 1.685 1.969 1.97 2.521 4.81 1.67 7.275l10.186 10.185c2.465-.85 5.307-.3 7.275 1.671 2.75 2.75 2.75 7.206 0 9.958-2.752 2.751-7.208 2.751-9.961 0-2.068-2.07-2.58-5.11-1.531-7.658l-9.5-9.499v24.997c.67.332 1.303.774 1.861 1.332 2.75 2.75 2.75 7.206 0 9.959-2.75 2.749-7.209 2.749-9.957 0-2.75-2.754-2.75-7.21 0-9.959.68-.679 1.467-1.193 2.307-1.537v-25.23c-.84-.344-1.625-.853-2.307-1.537-2.083-2.082-2.584-5.14-1.516-7.698L31.798 16.715 4.288 44.222c-2.311 2.313-2.311 6.06 0 8.371l40.121 40.118c2.31 2.311 6.056 2.311 8.369 0L92.71 52.779c2.311-2.311 2.311-6.06 0-8.371z" />
12
+ {/* User badge — scaled 1.8x from center (74, 74) */}
13
+ <circle cx="74" cy="74" r="32" fill="var(--background, white)" />
14
+ <circle cx="74" cy="65" r="9.9" />
15
+ <path d="M53.3 93.1c0-11.432 9.268-20.7 20.7-20.7s20.7 9.268 20.7 20.7" />
16
+ </svg>
17
+ );
package/lib/utils.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { type ClassValue, clsx } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+
4
+ /**
5
+ * Merge class names with Tailwind-aware conflict resolution.
6
+ * `clsx` handles conditionals/arrays; `twMerge` dedupes conflicting utilities
7
+ * (so a later `bg-*` wins over an earlier one, etc.).
8
+ */
9
+ export function cn(...inputs: ClassValue[]) {
10
+ return twMerge(clsx(inputs));
11
+ }
package/package.json ADDED
@@ -0,0 +1,117 @@
1
+ {
2
+ "name": "@plannotator/ui",
3
+ "version": "0.22.0",
4
+ "type": "module",
5
+ "exports": {
6
+ "./components/*": "./components/*.tsx",
7
+ "./components/ui/*": "./components/ui/*.tsx",
8
+ "./components/ai/*": "./components/ai/*.tsx",
9
+ "./components/core/*": "./components/core/*.tsx",
10
+ "./components/goal-setup/*": "./components/goal-setup/*.tsx",
11
+ "./components/ImageAnnotator": "./components/ImageAnnotator/index.tsx",
12
+ "./components/html-viewer": "./components/html-viewer/index.ts",
13
+ "./components/sidebar/*": "./components/sidebar/*.tsx",
14
+ "./components/plan-diff/*": "./components/plan-diff/*.tsx",
15
+ "./utils/*": "./utils/*.ts",
16
+ "./lib/*": "./lib/*.ts",
17
+ "./hooks/*": "./hooks/*.ts",
18
+ "./shortcuts": "./shortcuts/index.ts",
19
+ "./config": "./config/index.ts",
20
+ "./configure": "./configure.ts",
21
+ "./types": "./types.ts",
22
+ "./theme": "./theme.css",
23
+ "./styles.css": "./styles.css"
24
+ },
25
+ "files": [
26
+ "components",
27
+ "config",
28
+ "hooks",
29
+ "icons",
30
+ "lib",
31
+ "shortcuts",
32
+ "utils",
33
+ "assets",
34
+ "themes",
35
+ "sprite_package_additional",
36
+ "sprite_package_new",
37
+ "sprite_package_pulluphang",
38
+ "globals.d.ts",
39
+ "configure.ts",
40
+ "types.ts",
41
+ "theme.css",
42
+ "print.css",
43
+ "styles.css",
44
+ "plannotator.webp",
45
+ "!**/*.test.ts",
46
+ "!**/*.test.tsx",
47
+ "!test-setup"
48
+ ],
49
+ "dependencies": {
50
+ "@plannotator/atomic-editor": "^0.5.0",
51
+ "@codemirror/autocomplete": "^6.20.3",
52
+ "@codemirror/commands": "^6.10.3",
53
+ "@codemirror/lang-javascript": "^6.2.5",
54
+ "@codemirror/lang-json": "^6.0.2",
55
+ "@codemirror/lang-markdown": "^6.5.0",
56
+ "@codemirror/lang-python": "^6.2.1",
57
+ "@codemirror/lang-yaml": "^6.1.3",
58
+ "@codemirror/language": "^6.12.3",
59
+ "@codemirror/legacy-modes": "^6.5.3",
60
+ "@codemirror/search": "^6.7.0",
61
+ "@codemirror/state": "^6.6.0",
62
+ "@codemirror/view": "^6.43.0",
63
+ "@fontsource-variable/geist-mono": "5.2.7",
64
+ "@fontsource-variable/inter": "^5.2.8",
65
+ "@pierre/diffs": "1.2.8",
66
+ "@lezer/common": "^1.5.2",
67
+ "@lezer/highlight": "^1.2.3",
68
+ "@plannotator/core": "0.22.0",
69
+ "@plannotator/markdown-editor": "^0.2.0",
70
+ "@plannotator/web-highlighter": "^0.8.1",
71
+ "@radix-ui/react-dialog": "^1.1.15",
72
+ "@radix-ui/react-dropdown-menu": "^2.1.16",
73
+ "@radix-ui/react-popover": "^1.1.15",
74
+ "@radix-ui/react-slot": "^1.2.4",
75
+ "@radix-ui/react-tabs": "^1.1.13",
76
+ "@radix-ui/react-tooltip": "^1.2.8",
77
+ "@tanstack/react-table": "^8.21.3",
78
+ "@viz-js/viz": "^3.25.0",
79
+ "class-variance-authority": "^0.7.1",
80
+ "clsx": "^2.1.1",
81
+ "diff": "^8.0.4",
82
+ "dompurify": "^3.3.3",
83
+ "highlight.js": "^11.11.1",
84
+ "katex": "^0.16.47",
85
+ "lucide-react": "^1.14.0",
86
+ "marked": "^17.0.6",
87
+ "mermaid": "^11.12.2",
88
+ "motion": "^12.38.0",
89
+ "perfect-freehand": "^1.2.2",
90
+ "tailwind-merge": "^3.6.0",
91
+ "unique-username-generator": "^1.5.1"
92
+ },
93
+ "peerDependencies": {
94
+ "react": "^19.2.3",
95
+ "react-dom": "^19.2.3",
96
+ "tailwindcss": "^4.1.18",
97
+ "tailwindcss-animate": "^1.0.7"
98
+ },
99
+ "devDependencies": {
100
+ "@happy-dom/global-registrator": "^20.10.1",
101
+ "@tailwindcss/vite": "^4.1.18",
102
+ "@types/bun": "^1.2.0",
103
+ "@types/react": "^19.2.0",
104
+ "@types/react-dom": "^19.2.0",
105
+ "react": "^19.2.3",
106
+ "react-dom": "^19.2.3",
107
+ "tailwindcss": "^4.1.18",
108
+ "tailwindcss-animate": "^1.0.7",
109
+ "typescript": "~5.8.2",
110
+ "vite": "^6.2.0"
111
+ },
112
+ "scripts": {
113
+ "typecheck": "tsc --noEmit -p tsconfig.json",
114
+ "build:css": "vite build --config vite.css.config.ts && rm -f styles.js",
115
+ "prepack": "bun run build:css"
116
+ }
117
+ }
Binary file
package/print.css ADDED
@@ -0,0 +1,427 @@
1
+ /* Print Stylesheet — optimized for white paper output without annotations.
2
+ *
3
+ * Two-pronged approach:
4
+ * 1. @media print — standard print styles
5
+ * 2. .plannotator-print — class added via JS beforeprint/afterprint events
6
+ * to guarantee overrides that @media print alone cannot achieve
7
+ * (e.g. beating Tailwind layers + hljs github-dark theme).
8
+ */
9
+
10
+ /* ============================================================
11
+ * CLASS-BASED OVERRIDES — applied via beforeprint/afterprint JS
12
+ * These use .plannotator-print on <html> for maximum specificity.
13
+ * ============================================================ */
14
+
15
+ /* Code blocks: override github-dark.css .hljs{background:#0d1117} */
16
+ .plannotator-print pre,
17
+ .plannotator-print pre[class] {
18
+ background: #f5f5f5 !important;
19
+ background-color: #f5f5f5 !important;
20
+ color: #1a1a1a !important;
21
+ border: 1px solid #ccc !important;
22
+ border-left: 3px solid #888 !important;
23
+ }
24
+
25
+ .plannotator-print pre code,
26
+ .plannotator-print code.hljs,
27
+ .plannotator-print pre code.hljs,
28
+ .plannotator-print .hljs {
29
+ background: transparent !important;
30
+ background-color: transparent !important;
31
+ color: #1a1a1a !important;
32
+ }
33
+
34
+ .plannotator-print pre span,
35
+ .plannotator-print pre code span,
36
+ .plannotator-print .hljs span,
37
+ .plannotator-print [class*="hljs-"] {
38
+ color: #1a1a1a !important;
39
+ background: transparent !important;
40
+ background-color: transparent !important;
41
+ text-decoration: none !important;
42
+ font-style: normal !important;
43
+ }
44
+
45
+ /* Inline code */
46
+ .plannotator-print code {
47
+ background: #e8e8e8 !important;
48
+ background-color: #e8e8e8 !important;
49
+ color: #1a1a1a !important;
50
+ border: 1px solid #ccc !important;
51
+ }
52
+
53
+ /* Inline code inside pre should be transparent (not gray pill) */
54
+ .plannotator-print pre code {
55
+ background: transparent !important;
56
+ background-color: transparent !important;
57
+ border: none !important;
58
+ }
59
+
60
+ /* ============================================================
61
+ * @media print — layout, visibility, typography
62
+ * ============================================================ */
63
+
64
+ @media print {
65
+ /* ========== Reset & Page ========== */
66
+
67
+ * {
68
+ transition: none !important;
69
+ animation: none !important;
70
+ }
71
+
72
+ @page {
73
+ size: A4;
74
+ margin: 0.75in;
75
+ }
76
+
77
+ html, body {
78
+ margin: 0;
79
+ padding: 0;
80
+ background: white !important;
81
+ color: #1a1a1a !important;
82
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
83
+ line-height: 1.6;
84
+ font-size: 11pt;
85
+ overflow: visible !important;
86
+ height: auto !important;
87
+ }
88
+
89
+ /* ========== Hide UI Chrome ========== */
90
+
91
+ header {
92
+ display: none !important;
93
+ }
94
+
95
+ aside {
96
+ display: none !important;
97
+ }
98
+
99
+ .annotation-toolbar {
100
+ display: none !important;
101
+ }
102
+
103
+ .fixed {
104
+ display: none !important;
105
+ }
106
+
107
+ [data-resize-handle] {
108
+ display: none !important;
109
+ }
110
+
111
+ [data-print-hide] {
112
+ display: none !important;
113
+ margin: 0 !important;
114
+ padding: 0 !important;
115
+ }
116
+
117
+ .sidebar-tab-flag {
118
+ display: none !important;
119
+ }
120
+
121
+ pre .absolute,
122
+ .group > button.absolute {
123
+ display: none !important;
124
+ }
125
+
126
+ button[title="Settings"],
127
+ button[title="Toggle theme"],
128
+ button[title="Add global comment"],
129
+ button[title="Copy plan"],
130
+ button[title="Copy file"] {
131
+ display: none !important;
132
+ }
133
+
134
+ /* ========== Main Content Area ========== */
135
+
136
+ [data-print-region="root"] {
137
+ height: auto !important;
138
+ overflow: visible !important;
139
+ }
140
+
141
+ [data-print-region="content"] {
142
+ overflow: visible !important;
143
+ }
144
+
145
+ main, [data-print-region="document"] {
146
+ width: 100% !important;
147
+ overflow: visible !important;
148
+ background: white !important;
149
+ background-image: none !important;
150
+ padding: 0 !important;
151
+ }
152
+
153
+ main > div {
154
+ padding: 0 !important;
155
+ margin: 0 !important;
156
+ }
157
+
158
+
159
+ article, [data-print-region="article"] {
160
+ width: 100% !important;
161
+ max-width: 100% !important;
162
+ margin: 0 !important;
163
+ padding: 0 !important;
164
+ background: white !important;
165
+ border: none !important;
166
+ border-radius: 0 !important;
167
+ box-shadow: none !important;
168
+ }
169
+
170
+ /* Collapse first heading top margin for tight print layout */
171
+ article h1:first-of-type,
172
+ [data-print-region="article"] h1:first-of-type {
173
+ margin-top: 0 !important;
174
+ }
175
+
176
+ /* ========== Typography ========== */
177
+
178
+ body, div, span, p, li, td, th, label, strong, em, b, i {
179
+ color: #1a1a1a !important;
180
+ }
181
+
182
+ strong, b {
183
+ font-weight: bold !important;
184
+ color: #000 !important;
185
+ }
186
+
187
+ em, i {
188
+ font-style: italic !important;
189
+ color: #1a1a1a !important;
190
+ }
191
+
192
+ h1 {
193
+ font-size: 24pt;
194
+ font-weight: bold;
195
+ margin: 1.5em 0 0.5em 0;
196
+ page-break-after: avoid;
197
+ color: #000 !important;
198
+ }
199
+
200
+ h2 {
201
+ font-size: 18pt;
202
+ font-weight: bold;
203
+ margin: 1.25em 0 0.4em 0;
204
+ page-break-after: avoid;
205
+ color: #000 !important;
206
+ }
207
+
208
+ h3 {
209
+ font-size: 14pt;
210
+ font-weight: bold;
211
+ margin: 1em 0 0.3em 0;
212
+ page-break-after: avoid;
213
+ color: #000 !important;
214
+ }
215
+
216
+ h4 {
217
+ font-size: 12pt;
218
+ font-weight: bold;
219
+ margin: 0.8em 0 0.25em 0;
220
+ page-break-after: avoid;
221
+ color: #000 !important;
222
+ }
223
+
224
+ h5, h6 {
225
+ font-size: 11pt;
226
+ font-weight: bold;
227
+ margin: 0.6em 0 0.2em 0;
228
+ page-break-after: avoid;
229
+ color: #000 !important;
230
+ }
231
+
232
+ p {
233
+ margin: 0.5em 0;
234
+ color: #1a1a1a !important;
235
+ }
236
+
237
+ /* ========== Lists ========== */
238
+
239
+ ul, ol {
240
+ margin: 0.5em 0;
241
+ padding-left: 2em;
242
+ }
243
+
244
+ li {
245
+ margin: 0.25em 0;
246
+ color: #1a1a1a !important;
247
+ }
248
+
249
+ li p {
250
+ margin: 0.25em 0;
251
+ }
252
+
253
+ /* ========== Code & Preformatted ========== */
254
+
255
+ code,
256
+ code[class] {
257
+ font-family: 'Courier New', Monaco, Consolas, monospace !important;
258
+ font-size: 10pt !important;
259
+ background: #e8e8e8 !important;
260
+ background-color: #e8e8e8 !important;
261
+ color: #1a1a1a !important;
262
+ padding: 0.1em 0.4em !important;
263
+ border-radius: 3px !important;
264
+ border: 1px solid #ccc !important;
265
+ }
266
+
267
+ .group {
268
+ page-break-inside: avoid;
269
+ }
270
+
271
+ pre,
272
+ pre[class] {
273
+ margin: 1em 0 !important;
274
+ padding: 1em !important;
275
+ background: #f5f5f5 !important;
276
+ background-color: #f5f5f5 !important;
277
+ border: 1px solid #ccc !important;
278
+ border-left: 3px solid #888 !important;
279
+ border-radius: 4px !important;
280
+ page-break-inside: avoid;
281
+ overflow: visible !important;
282
+ color: #1a1a1a !important;
283
+ }
284
+
285
+ pre code,
286
+ pre code[class],
287
+ pre code.hljs,
288
+ code.hljs,
289
+ code[data-highlighted] {
290
+ font-size: 9pt !important;
291
+ background: transparent !important;
292
+ background-color: transparent !important;
293
+ color: #1a1a1a !important;
294
+ padding: 0 !important;
295
+ border: none !important;
296
+ display: block !important;
297
+ white-space: pre-wrap !important;
298
+ word-wrap: break-word !important;
299
+ }
300
+
301
+ .hljs {
302
+ background: transparent !important;
303
+ background-color: transparent !important;
304
+ color: #1a1a1a !important;
305
+ }
306
+
307
+ pre span, pre code span, .hljs span, code span,
308
+ [class*="hljs-"] {
309
+ color: #1a1a1a !important;
310
+ background: transparent !important;
311
+ background-color: transparent !important;
312
+ text-decoration: none !important;
313
+ font-style: normal !important;
314
+ }
315
+
316
+ /* ========== Tables ========== */
317
+
318
+ table {
319
+ margin: 1em 0;
320
+ border-collapse: collapse;
321
+ width: 100%;
322
+ page-break-inside: avoid;
323
+ }
324
+
325
+ thead {
326
+ background: #e8e8e8 !important;
327
+ page-break-after: avoid;
328
+ }
329
+
330
+ th {
331
+ font-weight: bold;
332
+ text-align: left;
333
+ padding: 0.5em;
334
+ border: 1px solid #999;
335
+ color: #000 !important;
336
+ background: #e8e8e8 !important;
337
+ }
338
+
339
+ td {
340
+ padding: 0.5em;
341
+ border: 1px solid #ccc;
342
+ color: #1a1a1a !important;
343
+ }
344
+
345
+ tbody tr:nth-child(even) {
346
+ background: #f9f9f9 !important;
347
+ }
348
+
349
+ tbody tr:nth-child(odd) {
350
+ background: white !important;
351
+ }
352
+
353
+ /* ========== Blockquotes ========== */
354
+
355
+ blockquote {
356
+ margin: 1em 0;
357
+ padding: 0.5em 0 0.5em 1em;
358
+ border-left: 4px solid #999 !important;
359
+ background: #f7f7f7 !important;
360
+ color: #333 !important;
361
+ }
362
+
363
+ blockquote p {
364
+ margin: 0.5em 0;
365
+ }
366
+
367
+ /* ========== Horizontal Rules ========== */
368
+
369
+ hr {
370
+ margin: 1.5em 0;
371
+ border: none;
372
+ border-top: 1px solid #999;
373
+ page-break-after: avoid;
374
+ }
375
+
376
+ /* ========== Links ========== */
377
+
378
+ a {
379
+ color: #0066cc !important;
380
+ text-decoration: underline;
381
+ }
382
+
383
+ a[href]::after {
384
+ content: " (" attr(href) ")";
385
+ font-size: 9pt;
386
+ color: #666 !important;
387
+ word-break: break-all;
388
+ }
389
+
390
+ a[href^="#"]::after {
391
+ content: "";
392
+ }
393
+
394
+ /* ========== Images ========== */
395
+
396
+ img {
397
+ max-width: 100%;
398
+ height: auto;
399
+ page-break-inside: avoid;
400
+ margin: 1em 0;
401
+ }
402
+
403
+ /* ========== Diagrams (Mermaid, Graphviz) ========== */
404
+
405
+ svg {
406
+ max-width: 100%;
407
+ height: auto !important;
408
+ page-break-inside: avoid;
409
+ }
410
+
411
+ /* ========== Page Break Hints ========== */
412
+
413
+ h1, h2, h3, h4, h5, h6 {
414
+ page-break-after: avoid;
415
+ }
416
+
417
+ pre, blockquote, table, figure {
418
+ page-break-inside: avoid;
419
+ }
420
+
421
+ /* ========== Print colour control ========== */
422
+
423
+ * {
424
+ -webkit-print-color-adjust: exact;
425
+ print-color-adjust: exact;
426
+ }
427
+ }
@@ -0,0 +1,25 @@
1
+ import { defineShortcutScope } from '../core';
2
+ import { createShortcutScopeHook } from '../runtime';
3
+
4
+ export const reviewAiShortcuts = defineShortcutScope({
5
+ id: 'review-ai',
6
+ title: 'AI Assistant',
7
+ shortcuts: {
8
+ submit: {
9
+ description: 'Send message',
10
+ bindings: ['Mod+Enter'],
11
+ section: 'AI Assistant',
12
+ hint: 'Available in the AI tab and the Ask AI inline input.',
13
+ displayOrder: 10,
14
+ },
15
+ cancel: {
16
+ description: 'Cancel inline AI input',
17
+ bindings: ['Escape'],
18
+ section: 'AI Assistant',
19
+ hint: 'Available in the Ask AI inline input.',
20
+ displayOrder: 20,
21
+ },
22
+ },
23
+ });
24
+
25
+ export const useReviewAiShortcuts = createShortcutScopeHook(reviewAiShortcuts);