@plannotator/ui 0.52.1 → 0.53.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 (76) hide show
  1. package/HANDOFF.md +284 -29
  2. package/README.md +45 -5
  3. package/components/AnnotationPanel.tsx +195 -118
  4. package/components/AnnotationToolbar.tsx +17 -14
  5. package/components/AnnotationToolstrip.tsx +54 -40
  6. package/components/BlockRenderer.tsx +20 -14
  7. package/components/CodeFilePopout.tsx +132 -69
  8. package/components/CommentPopover.tsx +8 -349
  9. package/components/ComposerTokenTextarea.tsx +379 -0
  10. package/components/ExportModal.tsx +6 -1
  11. package/components/HostTitle.tsx +108 -0
  12. package/components/HtmlSurfaceControls.tsx +2 -1
  13. package/components/ImageLightbox.tsx +288 -17
  14. package/components/ImagePeek.tsx +255 -0
  15. package/components/ImageResolverContext.tsx +31 -0
  16. package/components/InlineMarkdown.tsx +123 -15
  17. package/components/LocalLinkContext.tsx +49 -0
  18. package/components/MentionPicker.tsx +51 -0
  19. package/components/MenuVersionSection.tsx +51 -25
  20. package/components/OpenInAppButton.tsx +18 -49
  21. package/components/PlanHeaderMenu.tsx +2 -8
  22. package/components/ProviderIcons.tsx +10 -4
  23. package/components/RenderedMarkdown.tsx +40 -4
  24. package/components/Settings.tsx +33 -5
  25. package/components/SkillReferenceMenu.tsx +67 -18
  26. package/components/Tooltip.tsx +51 -4
  27. package/components/Viewer.tsx +220 -49
  28. package/components/ai/AIProviderBar.tsx +11 -0
  29. package/components/ai/AskSessionSetupHint.tsx +12 -0
  30. package/components/ai/DocumentAIChatPanel.tsx +17 -5
  31. package/components/ai/SessionAskNotice.tsx +4 -3
  32. package/components/blocks/BlockquoteBlock.tsx +159 -0
  33. package/components/blocks/HtmlBlock.tsx +121 -9
  34. package/components/blocks/QuestionBlock.tsx +183 -96
  35. package/components/blocks/QuestionContext.tsx +3 -0
  36. package/components/diagram/DiagramViewer.tsx +41 -4
  37. package/components/diagram/index.ts +1 -1
  38. package/components/html-viewer/HtmlViewer.tsx +95 -3
  39. package/components/html-viewer/bridge-script.asset.js +413 -7
  40. package/components/html-viewer/bridge-script.lite.ts +1 -1
  41. package/components/html-viewer/bridge-script.ts +454 -7
  42. package/components/html-viewer/useHtmlAnnotation.ts +51 -3
  43. package/components/icons/AgentIcons.tsx +9 -7
  44. package/components/plan-diff/PlanCleanDiffView.tsx +239 -36
  45. package/components/plan-diff/PlanDiffViewer.tsx +6 -1
  46. package/configure.ts +27 -1
  47. package/hooks/useAgentJobs.ts +8 -3
  48. package/hooks/useAnnotationHighlighter.ts +128 -23
  49. package/hooks/useExternalAnnotations.ts +6 -0
  50. package/hooks/useMentionAutocomplete.ts +1 -1
  51. package/hooks/useOpenInApps.ts +88 -0
  52. package/hooks/useSkillReferenceAutocomplete.ts +7 -3
  53. package/hooks/useUpdateCheck.ts +38 -98
  54. package/hooks/useUpdateCheckSetting.ts +43 -0
  55. package/hooks/useUpdateToast.ts +101 -0
  56. package/hooks/useVimSelection.ts +9 -0
  57. package/package.json +2 -2
  58. package/shortcuts/code-review/markdownPreview.shortcuts.ts +18 -0
  59. package/shortcuts/index.ts +1 -0
  60. package/shortcuts/runtime.ts +10 -3
  61. package/styles.css +1 -1
  62. package/types.ts +48 -0
  63. package/utils/agentClosed.ts +26 -0
  64. package/utils/agentToolSetting.ts +16 -9
  65. package/utils/aiProvider.ts +7 -0
  66. package/utils/askSessionSetupHint.ts +27 -0
  67. package/utils/blockTargeting.ts +14 -3
  68. package/utils/mentions.ts +34 -5
  69. package/utils/parser.ts +65 -51
  70. package/utils/pasteInsert.ts +234 -0
  71. package/utils/planDiffEngine.ts +272 -2
  72. package/utils/skillCatalog.ts +15 -2
  73. package/utils/skillReferences.ts +50 -13
  74. package/utils/storage.ts +5 -0
  75. package/utils/textCut.ts +41 -0
  76. package/utils/updateNotice.ts +120 -0
package/README.md CHANGED
@@ -19,6 +19,7 @@ configurePlannotatorUI({
19
19
  storageBackend, // where settings persist
20
20
  identityProvider, // who the current user is
21
21
  imageSrcResolver, // how image paths resolve to URLs
22
+ uploadTransport, // where pasted/attached images upload to
22
23
  docPreviewFetcher,
23
24
  fileTreeBackend,
24
25
  draftTransport,
@@ -26,12 +27,16 @@ configurePlannotatorUI({
26
27
  aiTransport,
27
28
  skillCatalogTransport, // skill-reference catalog for comment composers
28
29
  skillContentTransport, // human-only skill contents for feedback injection
30
+ skillReferenceExport, // false: no per-comment "Skills referenced" list (a host composing one block per message)
31
+ skillInstructionsDestination, // what the human-only line says instructions go with (default "your feedback")
29
32
  serverSync,
30
33
  webmcp, // browser-agent (WebMCP) provider policy: { enabled, namePrefix }
31
34
  mathRendererLoader, // how KaTeX loads when no renderer is registered before first math render
32
35
  identityGenerator, // sync generator behind the default "tater" name (no identityProvider)
33
36
  alertIconRenderer, // (name) => ReactNode | null for a GitHub alert title line's <!-- icon: name --> (default: null, the type's icon)
34
37
  fenceTheme, // (colorTheme, mode) => Shiki theme name | undefined for code fences (default: SHIKI_THEME_MAP, else pierre-dark/light)
38
+ componentTooltips, // true: ui's own hover text (components/HostTitle) draws as ui's Tooltip, not a native title (ui 0.53.0; default false)
39
+ loadSettingsFromBackend, // true: re-hydrate settings from your (synchronous) storageBackend after install, applied last
35
40
  });
36
41
  ```
37
42
 
@@ -292,6 +297,16 @@ in 0.42.0 (proven by diffing the mounted `outerHTML` against the base commit).
292
297
  in a plain-text body, so the first person you list owns every occurrence of
293
298
  it; and a restored draft has no chips (and reports no ids) until the author
294
299
  picks again. No source → no overlay element at all.
300
+ - **Agents in the `@` picker** (ui 0.53.1; the Plannotator
301
+ Inbox's agent tags): `MentionSource.kinds?: ('user' | 'agent')[]` (absent →
302
+ users only, as before) lets a host offer agents; `MentionSource.matchDetail?:
303
+ boolean` (absent → true) keeps a query from matching the `detail` line;
304
+ `MentionPerson.group?: string` draws consecutive people of one group under a
305
+ heading, each run a `role="group"` labelled by it (absent on every person →
306
+ the flat list); `MentionSource.renderNotice?: (tagged) => ReactNode` draws a
307
+ host line under the composer field from the people the draft still tags
308
+ (`CommentPopover`). All optional; a host passing none renders exactly as
309
+ before.
295
310
  - **`Viewer` / `HtmlViewer` `mentionSource`** (0.43.1): the same prop on the two
296
311
  viewers, forwarded to every comment composer each of them mounts, so a host
297
312
  wires mentions once per surface instead of per composer. The ids the author
@@ -348,6 +363,22 @@ Neither prop reaches `CodeAnnotation` cards (the review-editor shape), which
348
363
  take no `renderCardFooter` either. See HANDOFF.md § "Annotation card header
349
364
  slot and mentions on the edit box (0.45.0)".
350
365
 
366
+ - **`compareAnnotations?: (a, b) => number`** (ui 0.53.0) — the order of the
367
+ comment timeline and of each All-files group, for comments with an order of
368
+ their own (the Inbox sorts a video's comments by the moment they are at).
369
+ Ties keep creation order; replies still thread under their parent. Omit it
370
+ and the panel sorts by creation exactly as before.
371
+ - **`title?`, `titleNote?`, `cardParts?: (annotation) => { quote?, images? }`**
372
+ (ui 0.53.0) — the header's title (default "Annotations") and a quiet note
373
+ at its right, and per card whether the built-in quote and image row are
374
+ drawn (the Inbox's video comments draw the moment and the frame in
375
+ `renderCardHeader` instead). Omit them and the panel is as before.
376
+ - **Export: `exportLocation`** (ui 0.53.0) — a string a host sets on the
377
+ COPY of an annotation it hands the exporters (`exportAnnotations`,
378
+ `exportLinkedDocAnnotations`): one line printed under the entry's heading
379
+ (the Inbox's `At 1:42 (102.4 s of 7:41)`). Never stored; an annotation
380
+ without it exports byte-identically.
381
+
351
382
  ### WebMCP provider (`@plannotator/ui/webmcp`; 0.32.0)
352
383
 
353
384
  The engine that lets a browser-integrated agent (Chrome/Edge WebMCP, `document.modelContext`) call in-page tools on a document surface. Feature-detected once; a browser without the API sees no registration, no DOM, no network, no timers. Seam: `configurePlannotatorUI({ webmcp: { enabled, namePrefix } })`, default enabled with the `plannotator.` prefix; pass `enabled: false` to keep a host page tool-free, or your own prefix to namespace the tools beside your own. There is deliberately no confirmation seam: the catalog is read-and-comment only (no approve / submit / close tools), and the agent may only edit or remove comments stamped `source: "browser-agent"`.
@@ -384,22 +415,31 @@ See HANDOFF.md § "Questions in documents (0.48.0, core 0.25.8)".
384
415
 
385
416
  See HANDOFF.md § "Question host seams (ui 0.49.0, core 0.25.9)".
386
417
 
387
- **Decision recording toggle and status tag (ui 0.52.0, unreleased).** Also optional on `Viewer`, also unused by Plannotator:
418
+ **Decision recording toggle and status tag (ui 0.52.0).** Also optional on `Viewer`, also unused by Plannotator:
388
419
 
389
- - `questionDecisionRecording(question) => boolean | undefined`: false draws a `Decision: when answered` question's "Records a decision" tag dimmed with a dotted outline and hides its "Answering this records a decision" row. A recorded decision is never affected.
420
+ - `questionDecisionRecording(question) => boolean | undefined`: false draws a `Decision: when answered` question's "Records a decision" tag faded (muted-foreground at 55%; the focus ring stays at full strength) with a dotted outline and hides its "Answering this records a decision" row. A recorded decision is never affected.
390
421
  - `onToggleQuestionDecisionRecording(key, next)`: makes that tag an `aria-pressed` toggle button; store `next` and return it from `questionDecisionRecording`. Not offered under `readOnly` or in a card without an answer handler.
391
422
  - `questionStatusTag: 'none'`: hides the card's own Open / Answered / Settled / Skipped tag so you can draw your own; the decision tags stay.
423
+ - `renderQuestionCard(question, savedAnswer)` (ui 0.53.0): your own card in place of a question's answer card (return `undefined` to keep it), e.g. for a question the asker withdrew; `renderQuestionBelowPrompt(question)`: content under a card's prompt.
392
424
 
393
- See HANDOFF.md § "Question decision toggle and status tag (ui 0.52.0, unreleased; …)".
425
+ See HANDOFF.md § "Question decision toggle and status tag (ui 0.52.0; …)".
394
426
 
395
- **Decision toggle on any question, and a decision-card opener (ui 0.52.1, unreleased).** Also optional on `Viewer`, also unused by Plannotator:
427
+ **Decision toggle on any question, and a decision-card opener (ui 0.52.1).** Also optional on `Viewer`, also unused by Plannotator:
396
428
 
397
429
  - `questionDecisionScope?: 'when-answered' | 'any'` (default `'when-answered'`, the 0.52.0 behaviour). With `'any'`, `questionDecisionRecording(question)` also applies to a question with no decision line: a boolean adds the "Records a decision" tag in that state (true also shows the "Answering this records a decision" row); `undefined` leaves it tag-less. Return `false` for "off by default".
398
430
  - `onOpenQuestionDecision(key, anchor)`: splits the tag into a diamond switch (`aria-pressed`, "Record as a decision", driven by `onToggleQuestionDecisionRecording`) and the words as a button (`aria-haspopup="dialog"`) that calls this with its own element to anchor your decision card. Offered on and off; not offered under `readOnly`. Without it the whole tag is the toggle, as in 0.52.0.
399
431
 
400
432
  See HANDOFF.md § "Decision toggle on any question, and an opener for the host's decision card (ui 0.52.1, …)".
401
433
 
402
- ### Diff file tree (`components/DiffFileTree`; next ui release)
434
+ **Questions without decision lines (ui 0.53.0, core 0.25.13).** `Viewer` `questionDecisionLines?: boolean` (default `true`, today's behaviour). `false` parses every `:::question` card with core's new `{ decisionLines: false }` option (`parseQuestionBlock(kind, body, options?)`, `indexQuestionBlocks(blocks, options?)`): a `Decision:` line is shown as context, and no card gets a decision tag or row from it. The prompt, key, numbering and choices are the default parse's (the line still ends a choice right above it). For a host that records no decisions; the Plannotator Inbox passes it since Decisions were removed there (2026-10). Every decision seam above is unchanged.
435
+
436
+ **Answers without comments (ui 0.53.0).** `Viewer` `answerOnly`: annotation authoring and the document actions (Global comment, Copy) are off as under `readOnly`, while question cards and checkboxes keep their handlers, for a host that shows a message to answer, not a document to annotate. See HANDOFF.md § "Viewer `answerOnly` (ui 0.53.0)".
437
+
438
+ **Comments on an answer-only document (ui 0.53.1).** `Viewer` `textComments`, with `answerOnly`: the text-selection toolbar (comment-only) and its composer come back, question cards stay out of selection, nothing else of authoring does. See HANDOFF.md § "Viewer `textComments` (ui 0.53.1)".
439
+
440
+ **Local links decided by the host (ui 0.53.0).** `Viewer` `resolveLocalLink`: the host decides what a link to a local path does (open it itself, or draw it as inert text), markdown and raw HTML alike. See HANDOFF.md § "Viewer `resolveLocalLink` (ui 0.53.0)".
441
+
442
+ ### Diff file tree (`components/DiffFileTree`; ui 0.50.0)
403
443
 
404
444
  A read-only file tree for a list of changed files, to sit beside a host's own per-file diff list. It is Plannotator's code-review tree, not a lookalike: the builder (`utils/diffFileTree`), the folder open/closed hook (`hooks/useDiffFileTreeExpansion`) and the row atoms moved here from `packages/review-editor`, and the review now renders from them.
405
445