@plannotator/ui 0.28.0 → 0.29.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/README.md +6 -0
  2. package/components/AISettingsTab.tsx +5 -4
  3. package/components/ActionMenu.tsx +5 -1
  4. package/components/AgentsTab.tsx +10 -23
  5. package/components/AnnotationPanel.tsx +9 -5
  6. package/components/AnnotationToolbar.tsx +5 -13
  7. package/components/AnnotationToolstrip.tsx +2 -2
  8. package/components/ApproveDropdown.tsx +1 -1
  9. package/components/BlockRenderer.tsx +1 -1
  10. package/components/CodeFilePopout.tsx +5 -4
  11. package/components/CommentPopover.tsx +391 -65
  12. package/components/DocBadges.tsx +29 -11
  13. package/components/ExportModal.tsx +16 -8
  14. package/components/GraphvizBlock.tsx +1 -1
  15. package/components/InlineMarkdown.tsx +30 -13
  16. package/components/KeyboardShortcuts.tsx +37 -2
  17. package/components/Landing.tsx +7 -7
  18. package/components/MenuVersionSection.tsx +4 -4
  19. package/components/MermaidBlock.tsx +1 -1
  20. package/components/ModeToggle.tsx +7 -6
  21. package/components/OpenInAppButton.tsx +2 -5
  22. package/components/PinpointOverlay.tsx +9 -7
  23. package/components/PlanHeaderMenu.tsx +8 -8
  24. package/components/PopoutDialog.tsx +6 -1
  25. package/components/ResizeHandle.tsx +1 -0
  26. package/components/Settings.tsx +172 -12
  27. package/components/SkillReferenceMenu.tsx +260 -0
  28. package/components/StickyHeaderLane.tsx +7 -0
  29. package/components/ThemeProvider.tsx +131 -32
  30. package/components/ThemeTab.tsx +123 -77
  31. package/components/ToolbarButtons.tsx +29 -8
  32. package/components/Viewer.tsx +396 -130
  33. package/components/VimKeyHud.tsx +695 -0
  34. package/components/VimModeAnnouncementDialog.tsx +557 -0
  35. package/components/VimModeOverlay.tsx +235 -0
  36. package/components/VimTargetReticle.tsx +284 -0
  37. package/components/ai/DocumentAIChatPanel.tsx +1 -1
  38. package/components/blocks/CodeBlock.tsx +18 -18
  39. package/components/blocks/TablePopout.tsx +7 -8
  40. package/components/blocks/TableToolbar.tsx +7 -8
  41. package/components/goal-setup/GoalSetupSurface.tsx +16 -3
  42. package/components/html-viewer/HtmlViewer.tsx +450 -47
  43. package/components/html-viewer/annotationNumbering.ts +37 -0
  44. package/components/html-viewer/bridge-script.ts +4051 -298
  45. package/components/html-viewer/composerYield.ts +51 -0
  46. package/components/html-viewer/srcdoc.ts +18 -3
  47. package/components/html-viewer/useHtmlAnnotation.ts +457 -32
  48. package/components/icons/themeIcons.tsx +1 -1
  49. package/components/plan-diff/PlanCleanDiffView.tsx +9 -9
  50. package/components/plan-diff/PlanDiffBadge.tsx +22 -1
  51. package/components/settings/HooksTab.tsx +12 -8
  52. package/components/sidebar/FileBrowser.tsx +4 -1
  53. package/components/themeModes.tsx +28 -0
  54. package/config/configStore.ts +76 -1
  55. package/config/settings.ts +152 -0
  56. package/configure.ts +9 -0
  57. package/globals.d.ts +7 -1
  58. package/hooks/useAIChat.ts +5 -2
  59. package/hooks/useAIProviderActivation.ts +47 -0
  60. package/hooks/useAIProviderConfig.ts +5 -1
  61. package/hooks/useAgentSettings.ts +64 -23
  62. package/hooks/useAgents.ts +4 -4
  63. package/hooks/useAnnotationHighlighter.ts +100 -3
  64. package/hooks/useArchive.ts +2 -1
  65. package/hooks/useFenceTheme.ts +17 -0
  66. package/hooks/useLinkedDoc.ts +68 -1
  67. package/hooks/usePinpoint.ts +76 -75
  68. package/hooks/usePlanDiff.ts +73 -2
  69. package/hooks/useSkillReferenceAutocomplete.ts +239 -0
  70. package/hooks/useUpdateCheck.ts +1 -2
  71. package/hooks/useVimDocumentFocus.ts +116 -0
  72. package/hooks/useVimSelection.ts +1063 -0
  73. package/package.json +4 -4
  74. package/print.css +14 -13
  75. package/shortcuts/core.ts +38 -13
  76. package/shortcuts/index.ts +10 -0
  77. package/shortcuts/plan-review/commentPopover.shortcuts.ts +7 -0
  78. package/shortcuts/plan-review/vimSelection.shortcuts.ts +251 -0
  79. package/shortcuts/runtime.ts +111 -12
  80. package/styles.css +1 -1
  81. package/theme.css +504 -0
  82. package/themes/colorblind.css +89 -0
  83. package/themes/plannotator.css +2 -2
  84. package/types.ts +93 -10
  85. package/utils/agentSwitch.ts +33 -7
  86. package/utils/blockTargeting.ts +462 -178
  87. package/utils/clipboard.ts +110 -0
  88. package/utils/codeBlockMark.ts +50 -0
  89. package/utils/codeHighlight.ts +293 -0
  90. package/utils/codexModels.ts +79 -0
  91. package/utils/domSelection.ts +84 -0
  92. package/utils/htmlChrome.ts +73 -0
  93. package/utils/inputMethod.ts +79 -6
  94. package/utils/parser.ts +517 -21
  95. package/utils/preferenceTtl.ts +15 -0
  96. package/utils/sharing.ts +0 -1
  97. package/utils/skillCatalog.ts +269 -0
  98. package/utils/skillReferences.ts +475 -0
  99. package/utils/syntaxTheme.ts +83 -0
  100. package/utils/themeRegistry.ts +154 -0
  101. package/utils/vimHud.ts +263 -0
  102. package/utils/vimModeAnnouncement.ts +23 -0
  103. package/utils/vimNavigation.ts +417 -0
  104. package/utils/vimReticle.ts +88 -0
  105. package/utils/vimScroll.ts +162 -0
@@ -1,17 +1,90 @@
1
1
  import { storage } from './storage';
2
+ import { isStalePreference } from './preferenceTtl';
2
3
  import type { InputMethod } from '../types';
3
4
 
4
5
  const STORAGE_KEY = 'plannotator-input-method';
6
+ const HTML_STORAGE_KEY = 'plannotator-input-method-html';
5
7
  const DEFAULT_METHOD: InputMethod = 'drag';
8
+ /**
9
+ * Raw-HTML sessions default to Pinpoint: arbitrary pages are element-shaped,
10
+ * not prose-shaped, so click-an-element is the natural first gesture.
11
+ */
12
+ const DEFAULT_HTML_METHOD: InputMethod = 'pinpoint';
6
13
 
7
- export function getInputMethod(): InputMethod {
8
- const stored = storage.getItem(STORAGE_KEY);
9
- if (stored === 'drag' || stored === 'pinpoint') {
10
- return stored;
14
+ /** Which document surface the input method applies to. */
15
+ export type InputMethodSurface = 'markdown' | 'html';
16
+
17
+ function parseInputMethod(value: unknown): InputMethod | null {
18
+ return value === 'drag' || value === 'pinpoint' ? value : null;
19
+ }
20
+
21
+ /**
22
+ * The HTML preference is stored as JSON `{ m, savedAt }` so it can expire.
23
+ * A plain legacy string (pre-TTL cookie) has an unknowable age and is treated
24
+ * as expired, which one-time resets everyone to the Pinpoint default.
25
+ */
26
+ function parseHtmlRecord(raw: string | null, now: number): InputMethod | null {
27
+ if (!raw) return null;
28
+ try {
29
+ const parsed: unknown = JSON.parse(raw);
30
+ if (typeof parsed !== 'object' || parsed === null) return null;
31
+ const record = parsed as Record<string, unknown>;
32
+ if (isStalePreference(record.savedAt, now)) return null;
33
+ return parseInputMethod(record.m);
34
+ } catch {
35
+ return null;
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Pure resolution logic (exported for tests).
41
+ *
42
+ * Persistence decision: the two surfaces keep SEPARATE preferences. The legacy
43
+ * shared key was only ever written from markdown sessions, so honoring it for
44
+ * HTML would let a markdown-era "drag" choice silently suppress the new HTML
45
+ * default. HTML sessions therefore read/write their own key: first run
46
+ * defaults to Pinpoint, an explicit switch made inside an HTML session wins on
47
+ * later HTML sessions, and a switch not refreshed within the staleness TTL
48
+ * (explicit change or annotation activity, see refreshInputMethodStamp)
49
+ * expires back to Pinpoint — without touching the markdown default, which
50
+ * deliberately has no TTL.
51
+ */
52
+ export function resolveInputMethod(
53
+ surface: InputMethodSurface,
54
+ savedShared: string | null,
55
+ savedHtml: string | null,
56
+ now: number = Date.now(),
57
+ ): InputMethod {
58
+ if (surface === 'html') {
59
+ return parseHtmlRecord(savedHtml, now) ?? DEFAULT_HTML_METHOD;
11
60
  }
12
- return DEFAULT_METHOD;
61
+ return parseInputMethod(savedShared) ?? DEFAULT_METHOD;
13
62
  }
14
63
 
15
- export function saveInputMethod(method: InputMethod): void {
64
+ export function getInputMethod(surface: InputMethodSurface = 'markdown'): InputMethod {
65
+ return resolveInputMethod(
66
+ surface,
67
+ storage.getItem(STORAGE_KEY),
68
+ storage.getItem(HTML_STORAGE_KEY),
69
+ );
70
+ }
71
+
72
+ export function saveInputMethod(
73
+ method: InputMethod,
74
+ surface: InputMethodSurface = 'markdown',
75
+ ): void {
76
+ if (surface === 'html') {
77
+ storage.setItem(HTML_STORAGE_KEY, JSON.stringify({ m: method, savedAt: Date.now() }));
78
+ return;
79
+ }
16
80
  storage.setItem(STORAGE_KEY, method);
17
81
  }
82
+
83
+ /**
84
+ * Re-stamp the persisted HTML preference with the given method and a fresh
85
+ * timestamp. Called on annotation activity so an actively-used preference
86
+ * never expires mid-habit; a no-op for the markdown surface.
87
+ */
88
+ export function refreshInputMethodStamp(method: InputMethod): void {
89
+ saveInputMethod(method, 'html');
90
+ }