@agent-native/core 0.63.0 → 0.63.2

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 (134) hide show
  1. package/dist/agent/harness/ai-sdk-adapter.d.ts +44 -0
  2. package/dist/agent/harness/ai-sdk-adapter.d.ts.map +1 -1
  3. package/dist/agent/harness/ai-sdk-adapter.js +120 -1
  4. package/dist/agent/harness/ai-sdk-adapter.js.map +1 -1
  5. package/dist/agent/harness/index.d.ts +1 -1
  6. package/dist/agent/harness/index.d.ts.map +1 -1
  7. package/dist/agent/harness/index.js.map +1 -1
  8. package/dist/cli/code-agent-executor.js +1 -1
  9. package/dist/cli/code-agent-executor.js.map +1 -1
  10. package/dist/cli/create.js +1 -1
  11. package/dist/cli/create.js.map +1 -1
  12. package/dist/client/NewWorkspaceAppFlow.js +1 -1
  13. package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
  14. package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts.map +1 -1
  15. package/dist/client/blocks/library/AnnotatedCodeBlock.js +29 -10
  16. package/dist/client/blocks/library/AnnotatedCodeBlock.js.map +1 -1
  17. package/dist/client/blocks/library/DiffBlock.d.ts.map +1 -1
  18. package/dist/client/blocks/library/DiffBlock.js +48 -20
  19. package/dist/client/blocks/library/DiffBlock.js.map +1 -1
  20. package/dist/client/blocks/library/diagram.d.ts.map +1 -1
  21. package/dist/client/blocks/library/diagram.js +14 -3
  22. package/dist/client/blocks/library/diagram.js.map +1 -1
  23. package/dist/client/blocks/library/wireframe.d.ts.map +1 -1
  24. package/dist/client/blocks/library/wireframe.js +14 -3
  25. package/dist/client/blocks/library/wireframe.js.map +1 -1
  26. package/dist/client/blocks/types.d.ts +5 -0
  27. package/dist/client/blocks/types.d.ts.map +1 -1
  28. package/dist/client/blocks/types.js.map +1 -1
  29. package/dist/client/chat/index.d.ts +2 -1
  30. package/dist/client/chat/index.d.ts.map +1 -1
  31. package/dist/client/chat/index.js +2 -1
  32. package/dist/client/chat/index.js.map +1 -1
  33. package/dist/client/chat-view-transition.d.ts +17 -0
  34. package/dist/client/chat-view-transition.d.ts.map +1 -1
  35. package/dist/client/chat-view-transition.js +46 -0
  36. package/dist/client/chat-view-transition.js.map +1 -1
  37. package/dist/client/index.d.ts +2 -1
  38. package/dist/client/index.d.ts.map +1 -1
  39. package/dist/client/index.js +2 -1
  40. package/dist/client/index.js.map +1 -1
  41. package/dist/client/use-agent-chat-home-handoff.d.ts +27 -0
  42. package/dist/client/use-agent-chat-home-handoff.d.ts.map +1 -0
  43. package/dist/client/use-agent-chat-home-handoff.js +120 -0
  44. package/dist/client/use-agent-chat-home-handoff.js.map +1 -0
  45. package/dist/index.d.ts +1 -1
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +3 -1
  48. package/dist/index.js.map +1 -1
  49. package/dist/server/action-discovery.d.ts.map +1 -1
  50. package/dist/server/action-discovery.js +24 -2
  51. package/dist/server/action-discovery.js.map +1 -1
  52. package/dist/server/deep-link.d.ts +2 -2
  53. package/dist/server/deep-link.d.ts.map +1 -1
  54. package/dist/server/deep-link.js +2 -2
  55. package/dist/server/deep-link.js.map +1 -1
  56. package/dist/styles/agent-native.css +2 -6
  57. package/dist/tailwind.preset.d.ts.map +1 -1
  58. package/dist/tailwind.preset.js +8 -1
  59. package/dist/tailwind.preset.js.map +1 -1
  60. package/dist/templates/default/package.json +1 -0
  61. package/dist/templates/headless/AGENTS.md +3 -0
  62. package/dist/templates/headless/DEVELOPING.md +4 -0
  63. package/dist/templates/headless/actions/run.ts +6 -0
  64. package/dist/templates/workspace-root/README.md +4 -4
  65. package/docs/content/actions.md +32 -42
  66. package/docs/content/agent-surfaces.md +105 -84
  67. package/docs/content/agent-teams.md +2 -14
  68. package/docs/content/agent-web-surfaces.md +4 -4
  69. package/docs/content/authentication.md +40 -24
  70. package/docs/content/automations.md +18 -36
  71. package/docs/content/blueprint-installer.md +3 -0
  72. package/docs/content/cli-adapters.md +24 -168
  73. package/docs/content/client.md +11 -77
  74. package/docs/content/cloneable-saas.md +1 -1
  75. package/docs/content/code-agents-ui.md +44 -0
  76. package/docs/content/components.md +10 -23
  77. package/docs/content/context-awareness.md +3 -3
  78. package/docs/content/creating-templates.md +20 -18
  79. package/docs/content/database.md +1 -1
  80. package/docs/content/deployment.md +5 -37
  81. package/docs/content/dispatch.md +17 -28
  82. package/docs/content/drop-in-agent.md +24 -111
  83. package/docs/content/durable-resume.md +4 -0
  84. package/docs/content/embedding-sdk.md +141 -135
  85. package/docs/content/evals.md +3 -3
  86. package/docs/content/extensions.md +1 -1
  87. package/docs/content/external-agents.md +35 -61
  88. package/docs/content/faq.md +5 -5
  89. package/docs/content/frames.md +13 -4
  90. package/docs/content/getting-started.md +96 -142
  91. package/docs/content/harness-agents.md +53 -9
  92. package/docs/content/human-approval.md +1 -1
  93. package/docs/content/key-concepts.md +14 -99
  94. package/docs/content/local-file-mode.md +2 -2
  95. package/docs/content/mcp-apps.md +9 -2
  96. package/docs/content/mcp-clients.md +8 -3
  97. package/docs/content/mcp-protocol.md +11 -29
  98. package/docs/content/messaging.md +1 -1
  99. package/docs/content/migration-workbench.md +14 -175
  100. package/docs/content/multi-app-workspace.md +1 -1
  101. package/docs/content/multi-tenancy.md +18 -47
  102. package/docs/content/native-chat-ui.md +15 -12
  103. package/docs/content/observability.md +16 -4
  104. package/docs/content/observational-memory.md +1 -1
  105. package/docs/content/pure-agent-apps.md +17 -124
  106. package/docs/content/real-time-collaboration.md +14 -14
  107. package/docs/content/routing.md +71 -0
  108. package/docs/content/sandbox-adapters.md +78 -4
  109. package/docs/content/security.md +59 -39
  110. package/docs/content/server.md +16 -8
  111. package/docs/content/sharing.md +1 -6
  112. package/docs/content/skills-guide.md +3 -1
  113. package/docs/content/template-analytics.md +1 -1
  114. package/docs/content/template-assets.md +12 -3
  115. package/docs/content/template-brain.md +64 -72
  116. package/docs/content/template-chat.md +32 -4
  117. package/docs/content/template-clips.md +35 -4
  118. package/docs/content/template-design.md +19 -3
  119. package/docs/content/template-dispatch.md +9 -0
  120. package/docs/content/template-forms.md +15 -10
  121. package/docs/content/template-plan.md +13 -5
  122. package/docs/content/template-slides.md +14 -14
  123. package/docs/content/template-videos.md +10 -12
  124. package/docs/content/tracking.md +66 -55
  125. package/docs/content/using-your-agent.md +6 -16
  126. package/docs/content/what-is-agent-native.md +5 -11
  127. package/docs/content/workspace-management.md +2 -2
  128. package/docs/content/workspace.md +20 -160
  129. package/package.json +6 -2
  130. package/src/templates/default/package.json +1 -0
  131. package/src/templates/headless/AGENTS.md +3 -0
  132. package/src/templates/headless/DEVELOPING.md +4 -0
  133. package/src/templates/headless/actions/run.ts +6 -0
  134. package/src/templates/workspace-root/README.md +4 -4
@@ -527,19 +527,30 @@ function DiffRead({ data, blockId, title, summary, ctx, }) {
527
527
  const annotationHoverSide = annotationLayout?.hoverSide ?? "right";
528
528
  const annotationHoverFallbackSide = annotationLayout?.hoverFallbackSide ?? "right";
529
529
  const annotationMarginSide = annotationLayout?.marginSide ?? "auto";
530
+ const defaultVisibleAnnotations = annotationLayout?.defaultVisibleAnnotations ??
531
+ (annotationLayout?.showByDefaultWhenRoom ? "all" : undefined);
530
532
  const resolved = useMemo(() => resolveAnnotations(data.annotations, (annotation) => annotationSide(annotation) === "before"
531
533
  ? beforeLineCount
532
534
  : afterLineCount), [data.annotations, beforeLineCount, afterLineCount]);
533
535
  const hasAnnotations = hasRailAnnotations(resolved);
534
536
  const showMarginAnnotations = useAnnotationMarginNotesAvailable({
535
537
  containerRef: codeRef,
536
- enabled: Boolean(hasAnnotations &&
537
- !showAnnotationOverlays &&
538
- annotationLayout?.showByDefaultWhenRoom),
538
+ enabled: Boolean(hasAnnotations && !showAnnotationOverlays && defaultVisibleAnnotations),
539
539
  side: annotationMarginSide,
540
540
  preferredSide: annotationHoverSide,
541
541
  });
542
542
  const showPersistentAnnotations = showAnnotationOverlays || showMarginAnnotations;
543
+ const persistentAnnotationIndexes = useMemo(() => {
544
+ if (!showMarginAnnotations || !defaultVisibleAnnotations) {
545
+ return new Set();
546
+ }
547
+ const visible = resolved.filter((item) => item.range);
548
+ if (defaultVisibleAnnotations === "first") {
549
+ const first = visible[0];
550
+ return first ? new Set([first.index]) : new Set();
551
+ }
552
+ return new Set(visible.map((item) => item.index));
553
+ }, [defaultVisibleAnnotations, resolved, showMarginAnnotations]);
543
554
  const captureOverlayAnnotationIndex = useMemo(() => resolved.find((item) => item.range)?.index ?? null, [resolved]);
544
555
  // Effective render mode. Annotations live in a SEPARATE right-hand rail (not
545
556
  // over the code), so they no longer force a mode. When no mode was authored, a
@@ -599,6 +610,9 @@ function DiffRead({ data, blockId, title, summary, ctx, }) {
599
610
  const activeItem = useMemo(() => activeIndex == null
600
611
  ? null
601
612
  : (resolved.find((item) => item.index === activeIndex) ?? null), [activeIndex, resolved]);
613
+ const activeItemIsPersistentlyVisible = Boolean(activeItem &&
614
+ !showAnnotationOverlays &&
615
+ persistentAnnotationIndexes.has(activeItem.index));
602
616
  const added = rows.filter((r) => r.kind === "added").length;
603
617
  const removed = rows.filter((r) => r.kind === "removed").length;
604
618
  const unchanged = data.before === data.after;
@@ -632,11 +646,12 @@ function DiffRead({ data, blockId, title, summary, ctx, }) {
632
646
  // The bordered code box. It always spans its full width — annotations surface
633
647
  // as an on-hover popover anchored to this box's right edge, never as a column.
634
648
  // `codeRef` measures that right edge for the popover's placement.
635
- const diffBox = (_jsxs("div", { ref: codeRef, className: "overflow-hidden rounded-md border border-border bg-background", children: [_jsxs("div", { className: "flex min-h-10 flex-wrap items-center gap-2 border-b border-border bg-muted/60 px-3 py-1.5", children: [_jsx(IconFileDiff, { className: "size-4 shrink-0 text-muted-foreground" }), _jsxs("span", { className: "flex min-w-0 flex-1 items-baseline gap-1.5 font-mono", title: data.filename || undefined, children: [_jsx("span", { className: "min-w-0 max-w-[16rem] truncate text-[13px] font-semibold leading-5 text-foreground", children: fileParts.basename }), fileParts.directory && (_jsx("span", { className: "min-w-0 flex-1 truncate text-[11px] leading-5 text-muted-foreground/70", children: fileParts.directory }))] }), _jsxs("span", { className: "ml-1 flex shrink-0 items-center gap-2 font-mono text-xs", children: [_jsxs("span", { className: "text-emerald-700 dark:text-emerald-300", children: ["+", added] }), _jsxs("span", { className: "text-destructive", children: ["\u2212", removed] })] }), canSplit && (_jsxs("div", { className: "pointer-events-none ml-auto flex shrink-0 items-center overflow-hidden rounded-md border border-border bg-background opacity-0 transition-opacity group-hover/diff-block:pointer-events-auto group-hover/diff-block:opacity-100 group-focus-within/diff-block:pointer-events-auto group-focus-within/diff-block:opacity-100", children: [_jsx(ModeButton, { active: mode === "unified", onClick: () => setMode("unified"), icon: _jsx(IconList, { className: "size-3.5" }), label: "Unified" }), _jsx(ModeButton, { active: mode === "split", onClick: () => setMode("split"), icon: _jsx(IconColumns, { className: "size-3.5" }), label: "Split" })] }))] }), unchanged ? (_jsx("div", { className: "px-4 py-6 text-center font-mono text-sm text-muted-foreground", children: "No changes" })) : effectiveMode === "split" ? (_jsx(SplitView, { rows: rows, language: language, rowLimit: rowLimit, markersForRow: markersForRow, activeIndex: activeIndex, onRowEnter: onRowEnter, onRowLeave: onRowLeave, onRowClick: onRowClick, showAnnotationOverlays: showPersistentAnnotations, annotationOverlayMode: showAnnotationOverlays ? "capture" : "margin", annotationOverlaySide: showAnnotationOverlays ? "right" : annotationMarginSide, annotationOverlayPreferredSide: annotationHoverSide, annotationOverlayContainerRef: codeRef, captureOverlayAnnotationIndex: captureOverlayAnnotationIndex, ctx: ctx })) : (_jsx(UnifiedView, { rows: displayedRows, language: language, expanded: expanded, onToggleRun: toggleRun, markersForRow: markersForRow, anchoredRow: anchoredRow, activeIndex: activeIndex, onRowEnter: onRowEnter, onRowLeave: onRowLeave, onRowClick: onRowClick, showAnnotationOverlays: showPersistentAnnotations, annotationOverlayMode: showAnnotationOverlays ? "capture" : "margin", annotationOverlaySide: showAnnotationOverlays ? "right" : annotationMarginSide, annotationOverlayPreferredSide: annotationHoverSide, annotationOverlayContainerRef: codeRef, captureOverlayAnnotationIndex: captureOverlayAnnotationIndex, ctx: ctx })), !unchanged && shouldLimitRows && (_jsxs("button", { type: "button", "data-plan-interactive": true, "aria-expanded": showAllRows, onClick: () => setShowAllRows((current) => !current), className: "flex h-7 w-full items-center justify-center gap-1.5 border-t border-border bg-background px-2 text-[11px] font-medium text-muted-foreground transition-colors hover:bg-muted/70 hover:text-foreground", children: [_jsx(IconChevronRight, { className: cn("size-3 shrink-0 transition-transform", showAllRows ? "-rotate-90" : "rotate-90") }), showAllRows
649
+ const diffBox = (_jsxs("div", { ref: codeRef, className: "overflow-hidden rounded-md border border-border bg-background", children: [_jsxs("div", { className: "flex min-h-10 flex-wrap items-center gap-2 border-b border-border bg-muted/60 px-3 py-1.5", children: [_jsx(IconFileDiff, { className: "size-4 shrink-0 text-muted-foreground" }), _jsxs("span", { className: "flex min-w-0 flex-1 items-baseline gap-1.5 font-mono", title: data.filename || undefined, children: [_jsx("span", { className: "min-w-0 max-w-[16rem] truncate text-[13px] font-semibold leading-5 text-foreground", children: fileParts.basename }), fileParts.directory && (_jsx("span", { className: "min-w-0 flex-1 truncate text-[11px] leading-5 text-muted-foreground/70", children: fileParts.directory }))] }), _jsxs("span", { className: "ml-1 flex shrink-0 items-center gap-2 font-mono text-xs", children: [_jsxs("span", { className: "text-emerald-700 dark:text-emerald-300", children: ["+", added] }), _jsxs("span", { className: "text-destructive", children: ["\u2212", removed] })] }), canSplit && (_jsxs("div", { className: "pointer-events-none ml-auto flex shrink-0 items-center overflow-hidden rounded-md border border-border bg-background opacity-0 transition-opacity group-hover/diff-block:pointer-events-auto group-hover/diff-block:opacity-100 group-focus-within/diff-block:pointer-events-auto group-focus-within/diff-block:opacity-100", children: [_jsx(ModeButton, { active: mode === "unified", onClick: () => setMode("unified"), icon: _jsx(IconList, { className: "size-3.5" }), label: "Unified" }), _jsx(ModeButton, { active: mode === "split", onClick: () => setMode("split"), icon: _jsx(IconColumns, { className: "size-3.5" }), label: "Split" })] }))] }), unchanged ? (_jsx("div", { className: "px-4 py-6 text-center font-mono text-sm text-muted-foreground", children: "No changes" })) : effectiveMode === "split" ? (_jsx(SplitView, { rows: rows, language: language, rowLimit: rowLimit, markersForRow: markersForRow, activeIndex: activeIndex, onRowEnter: onRowEnter, onRowLeave: onRowLeave, onRowClick: onRowClick, showAnnotationOverlays: showPersistentAnnotations, annotationOverlayMode: showAnnotationOverlays ? "capture" : "margin", annotationOverlaySide: showAnnotationOverlays ? "right" : annotationMarginSide, annotationOverlayPreferredSide: annotationHoverSide, annotationOverlayContainerRef: codeRef, captureOverlayAnnotationIndex: captureOverlayAnnotationIndex, persistentAnnotationIndexes: persistentAnnotationIndexes, ctx: ctx })) : (_jsx(UnifiedView, { rows: displayedRows, language: language, expanded: expanded, onToggleRun: toggleRun, markersForRow: markersForRow, anchoredRow: anchoredRow, activeIndex: activeIndex, onRowEnter: onRowEnter, onRowLeave: onRowLeave, onRowClick: onRowClick, showAnnotationOverlays: showPersistentAnnotations, annotationOverlayMode: showAnnotationOverlays ? "capture" : "margin", annotationOverlaySide: showAnnotationOverlays ? "right" : annotationMarginSide, annotationOverlayPreferredSide: annotationHoverSide, annotationOverlayContainerRef: codeRef, captureOverlayAnnotationIndex: captureOverlayAnnotationIndex, persistentAnnotationIndexes: persistentAnnotationIndexes, ctx: ctx })), !unchanged && shouldLimitRows && (_jsxs("button", { type: "button", "data-plan-interactive": true, "aria-expanded": showAllRows, onClick: () => setShowAllRows((current) => !current), className: "flex h-7 w-full items-center justify-center gap-1.5 border-t border-border bg-background px-2 text-[11px] font-medium text-muted-foreground transition-colors hover:bg-muted/70 hover:text-foreground", children: [_jsx(IconChevronRight, { className: cn("size-3 shrink-0 transition-transform", showAllRows ? "-rotate-90" : "rotate-90") }), showAllRows
636
650
  ? "Show fewer"
637
651
  : `Show all ${totalVisibleLineCount} lines`] }))] }));
638
652
  return (_jsxs("section", { ...ltrCodeBlockProps, ref: containerRef, className: "relative plan-block group/diff-block", "data-block-id": blockId, children: [title && _jsx("div", { className: "plan-block-label", children: title }), summary && (_jsx("p", { className: "mb-3 text-sm leading-relaxed text-plan-muted", children: summary })), diffBox, hasAnnotations && (_jsx(AnnotationHiddenStack, { items: resolved, ctx: ctx, showMarker: true })), hasAnnotations &&
639
- !showPersistentAnnotations &&
653
+ !showAnnotationOverlays &&
654
+ !activeItemIsPersistentlyVisible &&
640
655
  activeItem &&
641
656
  hover.anchor && (_jsx(AnnotationHoverCard, { item: activeItem, anchor: hover.anchor, ctx: ctx, showMarker: true, preferredSide: annotationHoverSide, hoverFallbackSide: annotationHoverFallbackSide, onMouseEnter: hover.cancelClose, onMouseLeave: hover.scheduleClose, onClose: hover.closeForScroll }))] }));
642
657
  }
@@ -657,11 +672,14 @@ function rowMarkerInfo(markers, activeIndex) {
657
672
  return { isActive, primaryIndex: markers[0].index };
658
673
  }
659
674
  /** Shared amber wash for an annotated row, brighter when active. */
660
- function annotatedRowBg(info) {
675
+ function annotatedRowBg(info, persistentlyVisible = false) {
661
676
  if (!info)
662
677
  return null;
663
- return info.isActive
664
- ? "bg-amber-400/[0.12] dark:bg-amber-300/[0.10]"
678
+ if (info.isActive) {
679
+ return "bg-amber-400/[0.12] dark:bg-amber-300/[0.10]";
680
+ }
681
+ return persistentlyVisible
682
+ ? "bg-amber-300/[0.14] dark:bg-amber-300/[0.10]"
665
683
  : "bg-amber-400/[0.045] dark:bg-amber-300/[0.045]";
666
684
  }
667
685
  /**
@@ -678,7 +696,7 @@ function isMarkerRangeStart(row, marker) {
678
696
  return lineNo === marker.range.start;
679
697
  }
680
698
  /* ── Unified view ──────────────────────────────────────────────────────────── */
681
- function UnifiedView({ rows, language, expanded, onToggleRun, markersForRow, anchoredRow, activeIndex, onRowEnter, onRowLeave, onRowClick, showAnnotationOverlays, annotationOverlayMode, annotationOverlaySide, annotationOverlayPreferredSide, annotationOverlayContainerRef, captureOverlayAnnotationIndex, ctx, }) {
699
+ function UnifiedView({ rows, language, expanded, onToggleRun, markersForRow, anchoredRow, activeIndex, onRowEnter, onRowLeave, onRowClick, showAnnotationOverlays, annotationOverlayMode, annotationOverlaySide, annotationOverlayPreferredSide, annotationOverlayContainerRef, captureOverlayAnnotationIndex, persistentAnnotationIndexes, ctx, }) {
682
700
  const segments = useMemo(() => segmentRows(rows, anchoredRow), [rows, anchoredRow]);
683
701
  // Any annotation present ⇒ reserve the marker column so rows stay aligned.
684
702
  const showMarkerColumn = useMemo(() => rows.some((row) => markersForRow(row).length > 0), [rows, markersForRow]);
@@ -696,6 +714,7 @@ function UnifiedView({ rows, language, expanded, onToggleRun, markersForRow, anc
696
714
  annotationOverlayPreferredSide,
697
715
  annotationOverlayContainerRef,
698
716
  captureOverlayAnnotationIndex,
717
+ persistentAnnotationIndexes,
699
718
  ctx,
700
719
  };
701
720
  let runIndex = 0;
@@ -709,18 +728,20 @@ function UnifiedView({ rows, language, expanded, onToggleRun, markersForRow, anc
709
728
  return _jsx(UnifiedRow, { row: segment, ...rowProps }, idx);
710
729
  }) }) }));
711
730
  }
712
- function UnifiedRow({ language, row, markersForRow, activeIndex, onRowEnter, onRowLeave, onRowClick, showMarkerColumn, showAnnotationOverlays, annotationOverlayMode, annotationOverlaySide, annotationOverlayPreferredSide, annotationOverlayContainerRef, captureOverlayAnnotationIndex, ctx, }) {
731
+ function UnifiedRow({ language, row, markersForRow, activeIndex, onRowEnter, onRowLeave, onRowClick, showMarkerColumn, showAnnotationOverlays, annotationOverlayMode, annotationOverlaySide, annotationOverlayPreferredSide, annotationOverlayContainerRef, captureOverlayAnnotationIndex, persistentAnnotationIndexes, ctx, }) {
713
732
  const markers = markersForRow(row);
714
733
  const info = rowMarkerInfo(markers, activeIndex);
715
734
  const startMarker = markers.find((marker) => isMarkerRangeStart(row, marker));
716
735
  const primaryIndex = startMarker?.index ?? info?.primaryIndex;
717
736
  const overlayItems = showAnnotationOverlays &&
718
737
  startMarker &&
719
- (annotationOverlayMode !== "capture" ||
720
- startMarker.index === captureOverlayAnnotationIndex)
738
+ (annotationOverlayMode === "capture"
739
+ ? startMarker.index === captureOverlayAnnotationIndex
740
+ : persistentAnnotationIndexes.has(startMarker.index))
721
741
  ? [startMarker]
722
742
  : [];
723
- return (_jsxs("div", { "data-annot-row": startMarker ? startMarker.index : undefined, tabIndex: info ? 0 : undefined, role: info ? "button" : undefined, "aria-expanded": info ? info.isActive : undefined, className: cn("relative flex min-h-5 min-w-full", info && "cursor-pointer", ROW_BG[row.kind], annotatedRowBg(info)), onMouseEnter: info && primaryIndex != null
743
+ const rowHasPersistentAnnotation = markers.some((marker) => persistentAnnotationIndexes.has(marker.index));
744
+ return (_jsxs("div", { "data-annot-row": startMarker ? startMarker.index : undefined, tabIndex: info ? 0 : undefined, role: info ? "button" : undefined, "aria-expanded": info ? info.isActive : undefined, className: cn("relative flex min-h-5 min-w-full", info && "cursor-pointer", ROW_BG[row.kind], annotatedRowBg(info, rowHasPersistentAnnotation)), onMouseEnter: info && primaryIndex != null
724
745
  ? (event) => onRowEnter(primaryIndex, event.currentTarget)
725
746
  : undefined, onMouseLeave: info ? () => onRowLeave() : undefined, onClick: info && primaryIndex != null
726
747
  ? (event) => onRowClick(primaryIndex, event.currentTarget)
@@ -733,7 +754,9 @@ function UnifiedRow({ language, row, markersForRow, activeIndex, onRowEnter, onR
733
754
  }
734
755
  : undefined, onFocus: info && primaryIndex != null
735
756
  ? (event) => onRowEnter(primaryIndex, event.currentTarget)
736
- : undefined, onBlur: info ? () => onRowLeave() : undefined, children: [_jsx("span", { className: cn(LINE_NO_CLASS, "w-[52px]"), children: row.oldNo ?? "" }), _jsx("span", { className: cn(LINE_NO_CLASS, "w-[52px]"), children: row.newNo ?? "" }), _jsx("span", { className: cn("w-6 shrink-0 select-none py-0 text-center font-semibold leading-5", GUTTER_BG[row.kind], SIGN_COLOR[row.kind]), children: SIGN[row.kind] }), showMarkerColumn && (_jsx(MarkerCell, { startMarker: startMarker, active: startMarker != null && startMarker.index === activeIndex })), _jsx(DiffLineText, { text: row.text, language: language }), overlayItems.length > 0 && (_jsx(AnnotationInlineOverlayStack, { items: overlayItems, ctx: ctx, showMarker: true, containerRef: annotationOverlayContainerRef, mode: annotationOverlayMode, side: annotationOverlaySide, preferredSide: annotationOverlayPreferredSide }))] }));
757
+ : undefined, onBlur: info ? () => onRowLeave() : undefined, children: [_jsx("span", { className: cn(LINE_NO_CLASS, "w-[52px]"), children: row.oldNo ?? "" }), _jsx("span", { className: cn(LINE_NO_CLASS, "w-[52px]"), children: row.newNo ?? "" }), _jsx("span", { className: cn("w-6 shrink-0 select-none py-0 text-center font-semibold leading-5", GUTTER_BG[row.kind], SIGN_COLOR[row.kind]), children: SIGN[row.kind] }), showMarkerColumn && (_jsx(MarkerCell, { startMarker: startMarker, active: startMarker != null &&
758
+ (startMarker.index === activeIndex ||
759
+ persistentAnnotationIndexes.has(startMarker.index)) })), _jsx(DiffLineText, { text: row.text, language: language }), overlayItems.length > 0 && (_jsx(AnnotationInlineOverlayStack, { items: overlayItems, ctx: ctx, showMarker: true, containerRef: annotationOverlayContainerRef, mode: annotationOverlayMode, side: annotationOverlaySide, preferredSide: annotationOverlayPreferredSide }))] }));
737
760
  }
738
761
  /**
739
762
  * The fixed-width marker column rendered between the sign gutter and the code.
@@ -777,7 +800,7 @@ function pairSplitRows(rows) {
777
800
  }
778
801
  return out;
779
802
  }
780
- function SplitView({ language, rowLimit, rows, markersForRow, activeIndex, onRowEnter, onRowLeave, onRowClick, showAnnotationOverlays, annotationOverlayMode, annotationOverlaySide, annotationOverlayPreferredSide, annotationOverlayContainerRef, captureOverlayAnnotationIndex, ctx, }) {
803
+ function SplitView({ language, rowLimit, rows, markersForRow, activeIndex, onRowEnter, onRowLeave, onRowClick, showAnnotationOverlays, annotationOverlayMode, annotationOverlaySide, annotationOverlayPreferredSide, annotationOverlayContainerRef, captureOverlayAnnotationIndex, persistentAnnotationIndexes, ctx, }) {
781
804
  const pairs = useMemo(() => pairSplitRows(rows), [rows]);
782
805
  const displayedPairs = rowLimit ? pairs.slice(0, rowLimit) : pairs;
783
806
  // Reserve the marker column on a side only if any visible row there has one.
@@ -796,11 +819,12 @@ function SplitView({ language, rowLimit, rows, markersForRow, activeIndex, onRow
796
819
  annotationOverlayPreferredSide,
797
820
  annotationOverlayContainerRef,
798
821
  captureOverlayAnnotationIndex,
822
+ persistentAnnotationIndexes,
799
823
  ctx,
800
824
  };
801
825
  return (_jsxs("div", { className: "flex w-full bg-background font-mono [font-size:var(--plan-doc-code-size)] leading-5", "data-code-surface": true, children: [_jsx("div", { className: "min-w-0 flex-1 overflow-x-auto border-r border-border", children: _jsx("div", { className: "inline-block min-w-full", children: displayedPairs.map((pair, idx) => (_jsx(SplitCell, { row: pair.left, side: "old", showMarkerColumn: showOldMarkers, ...cellProps }, `old-${idx}`))) }) }), _jsx("div", { className: "min-w-0 flex-1 overflow-x-auto", children: _jsx("div", { className: "inline-block min-w-full", children: displayedPairs.map((pair, idx) => (_jsx(SplitCell, { row: pair.right, side: "new", showMarkerColumn: showNewMarkers, ...cellProps }, `new-${idx}`))) }) })] }));
802
826
  }
803
- function SplitCell({ language, row, side, markersForRow, activeIndex, onRowEnter, onRowLeave, onRowClick, showMarkerColumn, showAnnotationOverlays, annotationOverlayMode, annotationOverlaySide, annotationOverlayPreferredSide, annotationOverlayContainerRef, captureOverlayAnnotationIndex, ctx, }) {
827
+ function SplitCell({ language, row, side, markersForRow, activeIndex, onRowEnter, onRowLeave, onRowClick, showMarkerColumn, showAnnotationOverlays, annotationOverlayMode, annotationOverlaySide, annotationOverlayPreferredSide, annotationOverlayContainerRef, captureOverlayAnnotationIndex, persistentAnnotationIndexes, ctx, }) {
804
828
  if (!row) {
805
829
  return (_jsxs("div", { className: "flex min-h-5 min-w-full bg-muted/40 opacity-70", children: [_jsx("span", { className: cn(LINE_NO_CLASS, "w-[52px]") }), _jsx("span", { className: "w-6 shrink-0 bg-muted/60" }), showMarkerColumn && _jsx("span", { className: "w-6 shrink-0" }), _jsx("span", { className: DIFF_LINE_CLASS, children: " " })] }));
806
830
  }
@@ -812,11 +836,13 @@ function SplitCell({ language, row, side, markersForRow, activeIndex, onRowEnter
812
836
  const primaryIndex = startMarker?.index ?? info?.primaryIndex;
813
837
  const overlayItems = showAnnotationOverlays &&
814
838
  startMarker &&
815
- (annotationOverlayMode !== "capture" ||
816
- startMarker.index === captureOverlayAnnotationIndex)
839
+ (annotationOverlayMode === "capture"
840
+ ? startMarker.index === captureOverlayAnnotationIndex
841
+ : persistentAnnotationIndexes.has(startMarker.index))
817
842
  ? [startMarker]
818
843
  : [];
819
- return (_jsxs("div", { "data-annot-row": startMarker ? startMarker.index : undefined, tabIndex: info ? 0 : undefined, role: info ? "button" : undefined, "aria-expanded": info ? info.isActive : undefined, className: cn("relative flex min-h-5 min-w-full", info && "cursor-pointer", ROW_BG[row.kind], annotatedRowBg(info)), onMouseEnter: info && primaryIndex != null
844
+ const rowHasPersistentAnnotation = markers.some((marker) => persistentAnnotationIndexes.has(marker.index));
845
+ return (_jsxs("div", { "data-annot-row": startMarker ? startMarker.index : undefined, tabIndex: info ? 0 : undefined, role: info ? "button" : undefined, "aria-expanded": info ? info.isActive : undefined, className: cn("relative flex min-h-5 min-w-full", info && "cursor-pointer", ROW_BG[row.kind], annotatedRowBg(info, rowHasPersistentAnnotation)), onMouseEnter: info && primaryIndex != null
820
846
  ? (event) => onRowEnter(primaryIndex, event.currentTarget)
821
847
  : undefined, onMouseLeave: info ? () => onRowLeave() : undefined, onClick: info && primaryIndex != null
822
848
  ? (event) => onRowClick(primaryIndex, event.currentTarget)
@@ -829,7 +855,9 @@ function SplitCell({ language, row, side, markersForRow, activeIndex, onRowEnter
829
855
  }
830
856
  : undefined, onFocus: info && primaryIndex != null
831
857
  ? (event) => onRowEnter(primaryIndex, event.currentTarget)
832
- : undefined, onBlur: info ? () => onRowLeave() : undefined, children: [_jsx("span", { className: cn(LINE_NO_CLASS, "w-[52px]"), children: side === "old" ? (row.oldNo ?? "") : (row.newNo ?? "") }), _jsx("span", { className: cn("w-6 shrink-0 select-none py-0 text-center font-semibold leading-5", GUTTER_BG[row.kind], SIGN_COLOR[row.kind]), children: showSign ? sign : " " }), showMarkerColumn && (_jsx(MarkerCell, { startMarker: startMarker, active: startMarker != null && startMarker.index === activeIndex })), _jsx(DiffLineText, { text: row.text, language: language }), overlayItems.length > 0 && (_jsx(AnnotationInlineOverlayStack, { items: overlayItems, ctx: ctx, showMarker: true, containerRef: annotationOverlayContainerRef, mode: annotationOverlayMode, side: annotationOverlaySide, preferredSide: annotationOverlayPreferredSide }))] }));
858
+ : undefined, onBlur: info ? () => onRowLeave() : undefined, children: [_jsx("span", { className: cn(LINE_NO_CLASS, "w-[52px]"), children: side === "old" ? (row.oldNo ?? "") : (row.newNo ?? "") }), _jsx("span", { className: cn("w-6 shrink-0 select-none py-0 text-center font-semibold leading-5", GUTTER_BG[row.kind], SIGN_COLOR[row.kind]), children: showSign ? sign : " " }), showMarkerColumn && (_jsx(MarkerCell, { startMarker: startMarker, active: startMarker != null &&
859
+ (startMarker.index === activeIndex ||
860
+ persistentAnnotationIndexes.has(startMarker.index)) })), _jsx(DiffLineText, { text: row.text, language: language }), overlayItems.length > 0 && (_jsx(AnnotationInlineOverlayStack, { items: overlayItems, ctx: ctx, showMarker: true, containerRef: annotationOverlayContainerRef, mode: annotationOverlayMode, side: annotationOverlaySide, preferredSide: annotationOverlayPreferredSide }))] }));
833
861
  }
834
862
  /* ── Edit (panel) ──────────────────────────────────────────────────────────── */
835
863
  const codeAreaClass = "min-h-[140px] font-mono [font-size:var(--plan-code-size)] leading-5";