@plannotator/ui 0.30.0 → 0.32.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 (102) hide show
  1. package/README.md +46 -1
  2. package/components/ActionMenu.tsx +6 -1
  3. package/components/AgentsTab.tsx +8 -9
  4. package/components/AnalysisLayerToggle.tsx +48 -0
  5. package/components/AnnotationPanel.tsx +158 -36
  6. package/components/AnnotationToolbar.tsx +50 -30
  7. package/components/AnnotationToolstrip.tsx +9 -0
  8. package/components/CommentPopover.tsx +238 -46
  9. package/components/ConfirmDialog.tsx +42 -28
  10. package/components/GraphvizBlock.tsx +86 -7
  11. package/components/HtmlSurfaceControls.tsx +170 -0
  12. package/components/InlineMarkdown.tsx +25 -4
  13. package/components/KeyboardShortcuts.tsx +9 -0
  14. package/components/Landing.tsx +1 -1
  15. package/components/LookAndFeelAnnouncementDialog.tsx +147 -178
  16. package/components/MarkdownEditor/embedPicker.ts +349 -0
  17. package/components/MarkdownEditor.tsx +12 -0
  18. package/components/MermaidBlock.tsx +60 -26
  19. package/components/ModeToggle.tsx +2 -1
  20. package/components/PermissionModeSetup.tsx +24 -5
  21. package/components/PinpointOverlay.tsx +11 -6
  22. package/components/PlanHeaderMenu.tsx +140 -1
  23. package/components/SearchableSelect.tsx +2 -0
  24. package/components/Settings.tsx +175 -10
  25. package/components/SkillReferenceMenu.tsx +9 -0
  26. package/components/StickyHeaderLane.tsx +9 -2
  27. package/components/TableOfContents.tsx +9 -4
  28. package/components/TextShimmer.tsx +8 -5
  29. package/components/ThemeProvider.tsx +43 -1
  30. package/components/ThemeTab.tsx +52 -1
  31. package/components/Tooltip.tsx +3 -1
  32. package/components/Viewer.tsx +19 -5
  33. package/components/VimTargetReticle.tsx +12 -4
  34. package/components/ai/DocumentAIChatPanel.tsx +1 -0
  35. package/components/blocks/MathBlock.tsx +26 -14
  36. package/components/core/button.tsx +14 -6
  37. package/components/html-viewer/HtmlViewer.tsx +320 -41
  38. package/components/html-viewer/bridge-script.ts +360 -72
  39. package/components/html-viewer/composerYield.ts +1 -51
  40. package/components/html-viewer/hostThreads.ts +37 -0
  41. package/components/html-viewer/index.ts +9 -0
  42. package/components/html-viewer/unanchored.ts +47 -0
  43. package/components/html-viewer/useHtmlAnnotation.ts +240 -61
  44. package/components/plan-diff/PlanCleanDiffView.tsx +1 -0
  45. package/components/sidebar/FileBrowser.tsx +17 -5
  46. package/components/sidebar/SidebarContainer.tsx +124 -28
  47. package/components/ui/button.tsx +10 -8
  48. package/components/ui/dialog.tsx +35 -25
  49. package/config/index.ts +6 -1
  50. package/config/reviewView.ts +42 -9
  51. package/config/settings.ts +141 -0
  52. package/configure.ts +32 -0
  53. package/hooks/useAIProviderConfig.ts +8 -7
  54. package/hooks/useActiveSection.ts +6 -4
  55. package/hooks/useAgentJobs.ts +3 -0
  56. package/hooks/useAnnotationHighlighter.ts +20 -0
  57. package/hooks/useHtmlRefresh.ts +149 -0
  58. package/hooks/useIsMobile.ts +37 -0
  59. package/hooks/useLinkedDoc.ts +7 -0
  60. package/hooks/useMathRenderer.ts +30 -0
  61. package/hooks/useScrollViewport.ts +74 -0
  62. package/hooks/useSharing.ts +31 -5
  63. package/hooks/useViewportEnvironment.ts +350 -0
  64. package/package.json +5 -2
  65. package/shortcuts/index.ts +3 -0
  66. package/shortcuts/plan-review/annotationMode.shortcuts.ts +91 -0
  67. package/shortcuts/plan-review/documentView.shortcuts.ts +26 -0
  68. package/shortcuts/plan-review/htmlAnnotate.shortcuts.ts +24 -0
  69. package/styles.css +1 -1
  70. package/theme.css +229 -0
  71. package/types.ts +35 -0
  72. package/utils/annotateAgentTerminal.ts +36 -5
  73. package/utils/blockTargeting.ts +6 -3
  74. package/utils/composerYield.ts +45 -0
  75. package/utils/generateIdentity.ts +64 -14
  76. package/utils/htmlChrome.ts +20 -16
  77. package/utils/identity-tater.ts +36 -0
  78. package/utils/lookAndFeelAnnouncement.ts +12 -8
  79. package/utils/markdownExtensions.ts +57 -0
  80. package/utils/math-eager.ts +25 -0
  81. package/utils/math.ts +146 -0
  82. package/utils/mermaid-eager.ts +28 -0
  83. package/utils/mermaid.ts +132 -0
  84. package/utils/parser.ts +75 -2
  85. package/utils/quickLabels.ts +13 -0
  86. package/utils/vimNavigation.ts +4 -1
  87. package/utils/vimScroll.ts +9 -4
  88. package/utils/wideMode.ts +20 -0
  89. package/webmcp/activity.ts +46 -0
  90. package/webmcp/changes.ts +227 -0
  91. package/webmcp/index.ts +72 -0
  92. package/webmcp/modelContext.ts +103 -0
  93. package/webmcp/nudges.ts +174 -0
  94. package/webmcp/policy.ts +50 -0
  95. package/webmcp/preference.ts +50 -0
  96. package/webmcp/schema.ts +81 -0
  97. package/webmcp/toolset.ts +337 -0
  98. package/webmcp/useToolset.ts +74 -0
  99. package/components/PlanAIAnnouncementDialog.tsx +0 -187
  100. package/components/VimModeAnnouncementDialog.tsx +0 -557
  101. package/utils/planAIAnnouncement.ts +0 -17
  102. package/utils/vimModeAnnouncement.ts +0 -23
@@ -1,51 +1 @@
1
- /**
2
- * Composer-yield state machine for shift-click multi-select.
3
- *
4
- * While Shift is held during an HTML pinpoint draft, the comment composer must
5
- * get out of the way of the pointer: fade to ~40% as the pointer approaches,
6
- * and to near-zero + click-through (pointer-events: none) when the pointer is
7
- * over it — the DOM equivalent of Codex's setIgnoreMouseEvents click-through
8
- * popup, so the shift-click lands on the iframe beneath.
9
- *
10
- * Restoration uses hysteresis so the composer doesn't flicker at the border:
11
- * once 'over', the pointer must clear the composer by OVER_EXIT px before the
12
- * state drops back, and 'near' persists until NEAR_EXIT px (> NEAR_ENTER).
13
- */
14
-
15
- export type ComposerYieldState = "none" | "near" | "over";
16
-
17
- /** Distance (px from the composer rect) at which the composer starts fading. */
18
- export const COMPOSER_YIELD_NEAR_ENTER_PX = 80;
19
- /** Distance the pointer must exceed before a faded composer fully restores. */
20
- export const COMPOSER_YIELD_NEAR_EXIT_PX = 96;
21
- /** Distance the pointer must clear a click-through composer by to restore. */
22
- export const COMPOSER_YIELD_OVER_EXIT_PX = 48;
23
-
24
- /** Shortest distance from a point to a rect's edge; <= 0 means inside. */
25
- export function distanceToRect(
26
- x: number,
27
- y: number,
28
- rect: { left: number; top: number; right: number; bottom: number },
29
- ): number {
30
- const dx = Math.max(rect.left - x, 0, x - rect.right);
31
- const dy = Math.max(rect.top - y, 0, y - rect.bottom);
32
- if (dx === 0 && dy === 0) return 0;
33
- return Math.hypot(dx, dy);
34
- }
35
-
36
- /** Next yield state for a pointer at `distance` px from the composer rect. */
37
- export function computeComposerYield(
38
- prev: ComposerYieldState,
39
- distance: number,
40
- ): ComposerYieldState {
41
- if (distance <= 0) return "over";
42
- if (prev === "over") {
43
- // Hysteresis: don't restore until the pointer has moved well away.
44
- if (distance <= COMPOSER_YIELD_OVER_EXIT_PX) return "over";
45
- return distance <= COMPOSER_YIELD_NEAR_EXIT_PX ? "near" : "none";
46
- }
47
- if (prev === "near") {
48
- return distance <= COMPOSER_YIELD_NEAR_EXIT_PX ? "near" : "none";
49
- }
50
- return distance <= COMPOSER_YIELD_NEAR_ENTER_PX ? "near" : "none";
51
- }
1
+ export * from '../../utils/composerYield';
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Host-side helpers for the raw-HTML viewer, re-exported from
3
+ * `@plannotator/core/html-anchor` with the package's `Annotation` type.
4
+ *
5
+ * `projectHostThreads` turns a host's stored rows into the `annotations`
6
+ * prop (output order == marker numbering); `buildPersistedHtmlAnchor` trims a
7
+ * composed comment's anchor to a bounded record the host can persist. Both
8
+ * are pure and dependency-free (they live in `@plannotator/core`).
9
+ */
10
+ import {
11
+ projectHostThreads as projectHostThreadsCore,
12
+ type HostThread,
13
+ type ProjectHostThreadsOptions,
14
+ } from "@plannotator/core/html-anchor";
15
+ import type { Annotation } from "../../types";
16
+
17
+ export {
18
+ buildPersistedHtmlAnchor,
19
+ type BuildPersistedHtmlAnchorOptions,
20
+ type HostThread,
21
+ type PersistedHtmlAnchor,
22
+ type PersistedHtmlAnchorResult,
23
+ type ProjectHostThreadsOptions,
24
+ } from "@plannotator/core/html-anchor";
25
+
26
+ /**
27
+ * Project stored host rows onto the viewer's `annotations` prop, in the
28
+ * host's order (which becomes the marker numbering). See the core function
29
+ * for the projection rules; the `type` literals it emits are the string
30
+ * values of `AnnotationType`, so the cast below is representation-exact.
31
+ */
32
+ export function projectHostThreads(
33
+ threads: readonly HostThread[],
34
+ options?: ProjectHostThreadsOptions,
35
+ ): Annotation[] {
36
+ return projectHostThreadsCore(threads, options) as unknown as Annotation[];
37
+ }
@@ -1 +1,10 @@
1
1
  export { HtmlViewer, type HtmlViewerProps } from "./HtmlViewer";
2
+ export {
3
+ buildPersistedHtmlAnchor,
4
+ projectHostThreads,
5
+ type BuildPersistedHtmlAnchorOptions,
6
+ type HostThread,
7
+ type PersistedHtmlAnchor,
8
+ type PersistedHtmlAnchorResult,
9
+ type ProjectHostThreadsOptions,
10
+ } from "./hostThreads";
@@ -0,0 +1,47 @@
1
+ import { AnnotationType, type Annotation } from "../../types";
2
+
3
+ /**
4
+ * A page-anchored row the viewer can never post to the bridge: nothing to
5
+ * find it by (no quoted text, no element anchor, no additional target
6
+ * anchor). Document-level comments are excluded on purpose: a
7
+ * GLOBAL_COMMENT has no page location by design and is not "unanchored".
8
+ */
9
+ export function isTextlessPageAnnotation(annotation: Annotation): boolean {
10
+ if (annotation.type === AnnotationType.GLOBAL_COMMENT) return false;
11
+ if (annotation.originalText) return false;
12
+ if (annotation.htmlAnchor) return false;
13
+ return !(annotation.htmlAdditionalTargets ?? []).some((target) => !!target.anchor);
14
+ }
15
+
16
+ /**
17
+ * The host-facing unanchored set: the bridge's report (ids with no live
18
+ * representation on the page) completed with what the bridge cannot see.
19
+ *
20
+ * - Textless page rows are added: they were never posted, so the bridge
21
+ * cannot report them, yet they have no marker and no highlight.
22
+ * - An id this viewer minted for a locally created comment (`create-mark`)
23
+ * that the host never carried in `annotations`, or has since swapped out
24
+ * for its own id, is dropped: the host holds no card for it, so naming it
25
+ * would be noise. Every other bridge id passes through untouched, so a
26
+ * host that paints through the imperative handle keeps today's delivery.
27
+ *
28
+ * Sorted and deduplicated like the bridge's own emission. With no textless
29
+ * rows and no swapped-out minted ids the result is exactly the bridge list.
30
+ */
31
+ export function mergeUnanchoredIds(input: {
32
+ bridgeIds: readonly string[];
33
+ annotations: readonly Annotation[];
34
+ createdIds: ReadonlySet<string>;
35
+ }): string[] {
36
+ const known = new Set<string>();
37
+ for (const annotation of input.annotations) known.add(annotation.id);
38
+ const out = new Set<string>();
39
+ for (const id of input.bridgeIds) {
40
+ if (input.createdIds.has(id) && !known.has(id)) continue;
41
+ out.add(id);
42
+ }
43
+ for (const annotation of input.annotations) {
44
+ if (isTextlessPageAnnotation(annotation)) out.add(annotation.id);
45
+ }
46
+ return [...out].sort();
47
+ }