@agent-native/core 0.63.1 → 0.63.3

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 (123) 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/client/blocks/library/AnnotatedCodeBlock.d.ts.map +1 -1
  9. package/dist/client/blocks/library/AnnotatedCodeBlock.js +29 -10
  10. package/dist/client/blocks/library/AnnotatedCodeBlock.js.map +1 -1
  11. package/dist/client/blocks/library/DiffBlock.d.ts.map +1 -1
  12. package/dist/client/blocks/library/DiffBlock.js +48 -20
  13. package/dist/client/blocks/library/DiffBlock.js.map +1 -1
  14. package/dist/client/blocks/library/diagram.d.ts.map +1 -1
  15. package/dist/client/blocks/library/diagram.js +14 -3
  16. package/dist/client/blocks/library/diagram.js.map +1 -1
  17. package/dist/client/blocks/library/wireframe.d.ts.map +1 -1
  18. package/dist/client/blocks/library/wireframe.js +14 -3
  19. package/dist/client/blocks/library/wireframe.js.map +1 -1
  20. package/dist/client/blocks/types.d.ts +5 -0
  21. package/dist/client/blocks/types.d.ts.map +1 -1
  22. package/dist/client/blocks/types.js.map +1 -1
  23. package/dist/server/action-discovery.d.ts.map +1 -1
  24. package/dist/server/action-discovery.js +24 -2
  25. package/dist/server/action-discovery.js.map +1 -1
  26. package/dist/server/deep-link.d.ts +2 -2
  27. package/dist/server/deep-link.d.ts.map +1 -1
  28. package/dist/server/deep-link.js +2 -2
  29. package/dist/server/deep-link.js.map +1 -1
  30. package/dist/styles/blocks.css +25 -3
  31. package/dist/tailwind.preset.d.ts.map +1 -1
  32. package/dist/tailwind.preset.js +8 -1
  33. package/dist/tailwind.preset.js.map +1 -1
  34. package/dist/templates/default/package.json +1 -0
  35. package/dist/templates/headless/AGENTS.md +3 -0
  36. package/dist/templates/headless/DEVELOPING.md +4 -0
  37. package/dist/templates/headless/actions/run.ts +6 -0
  38. package/docs/content/a2a-protocol.md +48 -10
  39. package/docs/content/actions.md +35 -16
  40. package/docs/content/agent-mentions.md +25 -32
  41. package/docs/content/agent-surfaces.md +31 -0
  42. package/docs/content/agent-teams.md +17 -14
  43. package/docs/content/agent-web-surfaces.md +24 -15
  44. package/docs/content/authentication.md +21 -0
  45. package/docs/content/automations.md +37 -21
  46. package/docs/content/blueprint-installer.md +7 -0
  47. package/docs/content/cli-adapters.md +7 -0
  48. package/docs/content/client.md +14 -0
  49. package/docs/content/cloneable-saas.md +14 -0
  50. package/docs/content/code-agents-ui.md +30 -2
  51. package/docs/content/components.md +21 -0
  52. package/docs/content/context-awareness.md +33 -48
  53. package/docs/content/creating-templates.md +43 -52
  54. package/docs/content/cross-app-sso.md +41 -0
  55. package/docs/content/database.md +41 -21
  56. package/docs/content/deployment.md +23 -6
  57. package/docs/content/dispatch.md +27 -0
  58. package/docs/content/drop-in-agent.md +26 -27
  59. package/docs/content/durable-resume.md +13 -1
  60. package/docs/content/embedding-sdk.md +14 -0
  61. package/docs/content/evals.md +14 -0
  62. package/docs/content/extensions.md +19 -0
  63. package/docs/content/external-agents.md +39 -2
  64. package/docs/content/faq.md +14 -0
  65. package/docs/content/file-uploads.md +20 -0
  66. package/docs/content/frames.md +14 -0
  67. package/docs/content/getting-started.md +34 -16
  68. package/docs/content/harness-agents.md +49 -8
  69. package/docs/content/human-approval.md +15 -30
  70. package/docs/content/key-concepts.md +37 -0
  71. package/docs/content/local-file-mode.md +26 -19
  72. package/docs/content/mcp-apps.md +36 -1
  73. package/docs/content/mcp-clients.md +49 -0
  74. package/docs/content/mcp-protocol.md +36 -0
  75. package/docs/content/messaging.md +34 -8
  76. package/docs/content/migration-workbench.md +7 -0
  77. package/docs/content/multi-app-workspace.md +29 -16
  78. package/docs/content/multi-tenancy.md +14 -0
  79. package/docs/content/native-chat-ui.md +20 -3
  80. package/docs/content/notifications.md +30 -0
  81. package/docs/content/observability.md +20 -1
  82. package/docs/content/observational-memory.md +14 -0
  83. package/docs/content/onboarding.md +32 -41
  84. package/docs/content/plan-plugin.md +14 -0
  85. package/docs/content/pr-visual-recap.md +14 -0
  86. package/docs/content/processors.md +7 -0
  87. package/docs/content/progress.md +23 -0
  88. package/docs/content/pure-agent-apps.md +7 -0
  89. package/docs/content/real-time-collaboration.md +19 -18
  90. package/docs/content/recurring-jobs.md +22 -19
  91. package/docs/content/routing.md +8 -0
  92. package/docs/content/sandbox-adapters.md +19 -0
  93. package/docs/content/security.md +38 -0
  94. package/docs/content/server.md +47 -25
  95. package/docs/content/sharing.md +50 -0
  96. package/docs/content/skills-guide.md +27 -42
  97. package/docs/content/template-analytics.md +60 -0
  98. package/docs/content/template-assets.md +68 -0
  99. package/docs/content/template-brain.md +83 -0
  100. package/docs/content/template-calendar.md +74 -0
  101. package/docs/content/template-chat.md +19 -0
  102. package/docs/content/template-clips.md +113 -0
  103. package/docs/content/template-content.md +133 -0
  104. package/docs/content/template-design.md +55 -0
  105. package/docs/content/template-dispatch.md +50 -0
  106. package/docs/content/template-forms.md +59 -0
  107. package/docs/content/template-mail.md +62 -0
  108. package/docs/content/template-plan.md +80 -5
  109. package/docs/content/template-slides.md +82 -0
  110. package/docs/content/template-videos.md +62 -0
  111. package/docs/content/tracking.md +21 -0
  112. package/docs/content/using-your-agent.md +14 -0
  113. package/docs/content/voice-input.md +31 -10
  114. package/docs/content/what-is-agent-native.md +25 -13
  115. package/docs/content/workspace-connections.md +49 -0
  116. package/docs/content/workspace-management.md +24 -0
  117. package/docs/content/workspace.md +50 -19
  118. package/docs/content/writing-agent-instructions.md +7 -0
  119. package/package.json +6 -2
  120. package/src/templates/default/package.json +1 -0
  121. package/src/templates/headless/AGENTS.md +3 -0
  122. package/src/templates/headless/DEVELOPING.md +4 -0
  123. package/src/templates/headless/actions/run.ts +6 -0
@@ -1 +1 @@
1
- {"version":3,"file":"AnnotatedCodeBlock.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/AnnotatedCodeBlock.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useMemo, useRef, useState } from \"react\";\nimport { IconCode, IconPlus, IconTrash } from \"@tabler/icons-react\";\nimport { cn } from \"../../utils.js\";\nimport { ltrCodeBlockProps } from \"../code-block-direction.js\";\nimport type { BlockEditProps, BlockReadProps } from \"../types.js\";\nimport type {\n AnnotatedCodeAnnotation,\n AnnotatedCodeData,\n} from \"./annotated-code.config.js\";\nimport {\n highlightCode,\n inferLanguageFromFilename,\n normalizeCodeLanguage,\n} from \"./code-highlight.js\";\nimport {\n AnnotationHiddenStack,\n AnnotationHoverCard,\n AnnotationInlineOverlayStack,\n anchorFromElements,\n buildLineMarkerMap,\n hasRailAnnotations,\n resolveAnnotations,\n useAnnotationMarginNotesAvailable,\n useAnnotationHover,\n type ResolvedAnnotation,\n} from \"./annotation-rail.js\";\nimport { CodeFilenameLabel } from \"./code-filename-label.js\";\nimport { DevInput, DevLabel, DevTextarea } from \"./dev-doc-ui.js\";\n\n/**\n * \"Explain this code\" walkthrough block: a standard syntax-highlighted code\n * surface on the left with line-anchored annotation cards on the right (the\n * Stripe-docs / Sourcegraph layout). Each annotated line range gets a subtle\n * highlight band + an accent rail down the gutter; its card shows the `lines`\n * range, optional `label`, and the always-visible markdown `note` (via\n * `ctx.renderMarkdown`). Hovering a card highlights its lines and vice-versa.\n *\n * Syntax highlighting reuses the shared `highlightCode` lowlight helper (the same\n * colorful palette as the `code-tabs` block) per line, so it matches the app's\n * standard code styling and supports per-line bands without an async loader. The\n * surface uses the plan `--plan-code*`/`--plan-*` tokens and Tailwind `dark:`\n * pairs, so it reads correctly in BOTH light and dark mode. Code lines render as\n * `<span>`s (never one `<pre>` per line) so they don't pick up document\n * code/pre chrome. Lives in core so any app can register the dev-doc block.\n *\n * Editing is panel-driven (config-style, like the diff/HTML blocks): a monospace\n * code Textarea, filename/language Inputs, and add/remove-able annotation rows.\n */\n\n/* ── Collapse helpers ──────────────────────────────────────────────────────── */\n\n/**\n * Minimum total line count before collapse is considered. Short files render\n * fully expanded regardless of annotation coverage.\n */\nconst COLLAPSE_MIN_TOTAL_LINES = 40;\n\n/**\n * Number of unannotated lines in a run that triggers collapse. Runs at or\n * below this threshold always stay expanded (no expander button).\n */\nconst COLLAPSE_THRESHOLD = 16;\n\n/**\n * Context lines kept visible at each edge of a collapsed run (8 lines of\n * breathing room so the collapsed region is clearly framed).\n */\nconst COLLAPSE_CONTEXT_EDGE = 8;\n\ntype CollapsedSegment = {\n kind: \"collapsed\";\n startLine: number;\n endLine: number;\n};\ntype VisibleSegment = { kind: \"visible\"; startLine: number; endLine: number };\ntype LineSegment = VisibleSegment | CollapsedSegment;\n\n/**\n * Partition line numbers [1..lineCount] into visible and collapsed segments.\n * Annotated lines (and COLLAPSE_CONTEXT_EDGE lines on either side of them) are\n * always visible. Runs of unannotated lines longer than COLLAPSE_THRESHOLD are\n * collapsed. The file header (first COLLAPSE_CONTEXT_EDGE lines) is always\n * visible so context is preserved.\n */\nfunction buildLineSegments(\n lineCount: number,\n lineMarkers: Map<number, Array<{ index: number }>>,\n): LineSegment[] {\n if (lineCount <= COLLAPSE_MIN_TOTAL_LINES) {\n return [{ kind: \"visible\", startLine: 1, endLine: lineCount }];\n }\n\n // Build a boolean array: true if the line must stay visible.\n const mustShow = new Array<boolean>(lineCount + 1).fill(false);\n // File header always visible.\n for (let i = 1; i <= Math.min(COLLAPSE_CONTEXT_EDGE, lineCount); i += 1) {\n mustShow[i] = true;\n }\n // Annotated lines and their context edges.\n for (const lineNo of lineMarkers.keys()) {\n for (\n let i = Math.max(1, lineNo - COLLAPSE_CONTEXT_EDGE);\n i <= Math.min(lineCount, lineNo + COLLAPSE_CONTEXT_EDGE);\n i += 1\n ) {\n mustShow[i] = true;\n }\n }\n\n // Compute initial segments.\n const raw: LineSegment[] = [];\n let segStart = 1;\n let visible = mustShow[1] ?? false;\n for (let i = 2; i <= lineCount; i += 1) {\n const nextVisible = mustShow[i] ?? false;\n if (nextVisible !== visible) {\n raw.push(\n visible\n ? { kind: \"visible\", startLine: segStart, endLine: i - 1 }\n : { kind: \"collapsed\", startLine: segStart, endLine: i - 1 },\n );\n segStart = i;\n visible = nextVisible;\n }\n }\n raw.push(\n visible\n ? { kind: \"visible\", startLine: segStart, endLine: lineCount }\n : { kind: \"collapsed\", startLine: segStart, endLine: lineCount },\n );\n\n // Don't collapse short hidden runs — expand them in-place.\n return raw.map((seg) => {\n if (\n seg.kind === \"collapsed\" &&\n seg.endLine - seg.startLine + 1 <= COLLAPSE_THRESHOLD\n ) {\n return {\n kind: \"visible\",\n startLine: seg.startLine,\n endLine: seg.endLine,\n };\n }\n return seg;\n });\n}\n\n/* ── Read ──────────────────────────────────────────────────────────────────── */\n\nfunction AnnotatedCodeRead({\n data,\n blockId,\n title,\n summary,\n ctx,\n}: BlockReadProps<AnnotatedCodeData>) {\n // On-hover popover (anchored to the right of the code) replaces the old\n // persistent rail: nothing is visible when idle. `codeRef` measures the code\n // block's right edge; `hover` carries the active index + captured geometry.\n const hover = useAnnotationHover();\n const { activeIndex } = hover;\n const codeRef = useRef<HTMLDivElement | null>(null);\n const lineRefs = useRef(new Map<number, HTMLDivElement>());\n\n const setLineRef = (lineNo: number, node: HTMLDivElement | null) => {\n if (node) lineRefs.current.set(lineNo, node);\n else lineRefs.current.delete(lineNo);\n };\n\n const lines = useMemo(\n () => data.code.replace(/\\n$/, \"\").split(\"\\n\"),\n [data.code],\n );\n const lineCount = lines.length;\n\n const language = useMemo(\n () =>\n normalizeCodeLanguage(data.language) ??\n inferLanguageFromFilename(data.filename),\n [data.language, data.filename],\n );\n\n // Highlight each line once; empty lines keep their height with a NBSP.\n const highlightedLines = useMemo(\n () =>\n lines.map((text) => (text.length ? highlightCode(text, language) : \" \")),\n [lines, language],\n );\n\n const resolved = useMemo(\n () => resolveAnnotations(data.annotations, () => lineCount),\n [data.annotations, lineCount],\n );\n\n // line number (1-based) → resolved annotations covering it.\n const lineMarkers = useMemo(() => buildLineMarkerMap(resolved), [resolved]);\n\n const hasAnnotations = hasRailAnnotations(resolved);\n const showAnnotationOverlays = Boolean(ctx.showCodeAnnotationOverlays);\n const annotationLayout = ctx.codeAnnotationLayout;\n const annotationHoverSide = annotationLayout?.hoverSide ?? \"right\";\n const annotationHoverFallbackSide =\n annotationLayout?.hoverFallbackSide ?? \"right\";\n const annotationMarginSide = annotationLayout?.marginSide ?? \"auto\";\n const showMarginAnnotations = useAnnotationMarginNotesAvailable({\n containerRef: codeRef,\n enabled: Boolean(\n hasAnnotations &&\n !showAnnotationOverlays &&\n annotationLayout?.showByDefaultWhenRoom,\n ),\n side: annotationMarginSide,\n preferredSide: annotationHoverSide,\n });\n const showPersistentAnnotations =\n showAnnotationOverlays || showMarginAnnotations;\n const captureOverlayAnnotationIndex = useMemo(\n () => resolved.find((item) => item.range)?.index ?? null,\n [resolved],\n );\n const langChip = data.language?.trim();\n const hasFilename = Boolean(data.filename?.trim());\n const showLangChip = Boolean(langChip && !hasFilename);\n\n // The resolved annotation whose card is currently shown on hover.\n const activeItem =\n useMemo<ResolvedAnnotation<AnnotatedCodeAnnotation> | null>(\n () =>\n activeIndex == null\n ? null\n : (resolved.find((item) => item.index === activeIndex) ?? null),\n [activeIndex, resolved],\n );\n\n // Line-collapse state: a set of collapsed segment start lines that have been\n // expanded by the reader. Starts empty (all segments in their default state).\n const [expandedCollapsed, setExpandedCollapsed] = useState<Set<number>>(\n () => new Set(),\n );\n\n const segments = useMemo(\n () => buildLineSegments(lineCount, lineMarkers),\n [lineCount, lineMarkers],\n );\n\n const renderLine = (lineNo: number) => {\n const markers = lineMarkers.get(lineNo);\n const isAnnotated = !!markers?.length;\n const isActive =\n activeIndex != null && !!markers?.some((m) => m.index === activeIndex);\n const overlayItems =\n showPersistentAnnotations && markers\n ? markers.filter(\n (item) =>\n item.range?.start === lineNo &&\n (!showAnnotationOverlays ||\n item.index === captureOverlayAnnotationIndex),\n )\n : [];\n\n const buildAnchorForRow = (el: HTMLElement) => {\n if (!markers) return null;\n const primaryMarker = markers[0];\n const anchorLine = primaryMarker.range?.start ?? lineNo;\n const anchorRow = lineRefs.current.get(anchorLine) ?? el;\n return anchorFromElements(codeRef.current, anchorRow);\n };\n\n return (\n <div\n key={lineNo}\n ref={(node) => setLineRef(lineNo, node)}\n data-code-line={lineNo}\n data-annot-row={isAnnotated ? markers?.[0].index : undefined}\n tabIndex={isAnnotated ? 0 : undefined}\n role={isAnnotated ? \"button\" : undefined}\n aria-expanded={isAnnotated ? isActive : undefined}\n aria-label={isAnnotated ? `Line ${lineNo} annotation` : undefined}\n className={cn(\n \"relative flex w-full\",\n isAnnotated && \"cursor-pointer\",\n isActive\n ? \"bg-amber-400/[0.12] dark:bg-amber-300/[0.10]\"\n : isAnnotated && showAnnotationOverlays\n ? \"bg-amber-300/[0.14] dark:bg-amber-300/[0.10]\"\n : isAnnotated\n ? \"bg-amber-400/[0.045] dark:bg-amber-300/[0.045]\"\n : null,\n )}\n onMouseEnter={\n isAnnotated && markers\n ? (event) => {\n const anchor = buildAnchorForRow(event.currentTarget);\n if (anchor) hover.open(markers[0].index, anchor);\n }\n : undefined\n }\n onMouseLeave={isAnnotated ? () => hover.scheduleClose() : undefined}\n onClick={\n isAnnotated && markers\n ? (event) => {\n const anchor = buildAnchorForRow(event.currentTarget);\n if (anchor) hover.open(markers[0].index, anchor);\n }\n : undefined\n }\n onKeyDown={\n isAnnotated && markers\n ? (event) => {\n if (event.key !== \"Enter\" && event.key !== \" \") return;\n event.preventDefault();\n const anchor = buildAnchorForRow(event.currentTarget);\n if (anchor) hover.open(markers[0].index, anchor);\n }\n : undefined\n }\n onFocus={\n isAnnotated && markers\n ? (event) => {\n const anchor = buildAnchorForRow(event.currentTarget);\n if (anchor) hover.open(markers[0].index, anchor);\n }\n : undefined\n }\n onBlur={isAnnotated ? () => hover.scheduleClose() : undefined}\n >\n <span\n aria-hidden\n className={cn(\n \"w-[3px] shrink-0 self-stretch\",\n isAnnotated\n ? isActive\n ? \"bg-amber-500/80 dark:bg-amber-400/70\"\n : showAnnotationOverlays\n ? \"bg-amber-500/55 dark:bg-amber-300/45\"\n : \"bg-amber-400/30 dark:bg-amber-300/25\"\n : null,\n )}\n />\n <span className=\"w-11 shrink-0 select-none px-3 text-right text-[11px] tabular-nums text-plan-muted/60\">\n {lineNo}\n </span>\n <span className=\"flex-1 whitespace-pre pr-4 text-plan-code-text\">\n {highlightedLines[lineNo - 1]}\n </span>\n {overlayItems.length > 0 && (\n <AnnotationInlineOverlayStack\n items={overlayItems}\n ctx={ctx}\n containerRef={codeRef}\n mode={showAnnotationOverlays ? \"capture\" : \"margin\"}\n side={showAnnotationOverlays ? \"right\" : annotationMarginSide}\n preferredSide={annotationHoverSide}\n />\n )}\n </div>\n );\n };\n\n const codeSurface = (\n <div\n ref={codeRef}\n className=\"overflow-hidden rounded-xl border border-plan-line bg-plan-code\"\n >\n {(hasFilename || showLangChip) && (\n <div className=\"flex items-center gap-2 border-b border-plan-line bg-plan-block/50 px-3.5 py-2\">\n <IconCode className=\"size-3.5 shrink-0 text-plan-muted\" />\n <CodeFilenameLabel\n filename={data.filename}\n className=\"text-[13px] font-medium\"\n directoryClassName=\"text-plan-muted\"\n basenameClassName=\"text-plan-code-text\"\n />\n {showLangChip && (\n <span className=\"shrink-0 rounded border border-plan-line px-1.5 py-0.5 font-mono text-[10px] uppercase tracking-wide text-plan-muted\">\n {langChip}\n </span>\n )}\n </div>\n )}\n <div className=\"overflow-x-auto py-1.5\" data-code-surface>\n <div className=\"min-w-full font-mono [font-size:var(--plan-doc-code-size)] leading-[22px]\">\n {segments.map((seg) => {\n if (seg.kind === \"visible\") {\n const lineNos = Array.from(\n { length: seg.endLine - seg.startLine + 1 },\n (_, i) => seg.startLine + i,\n );\n return lineNos.map(renderLine);\n }\n // Collapsed segment — show an expander row.\n const isExpanded = expandedCollapsed.has(seg.startLine);\n const hiddenCount = seg.endLine - seg.startLine + 1;\n if (isExpanded) {\n const lineNos = Array.from(\n { length: hiddenCount },\n (_, i) => seg.startLine + i,\n );\n return lineNos.map(renderLine);\n }\n return (\n <button\n key={`collapse-${seg.startLine}`}\n type=\"button\"\n data-plan-interactive\n onClick={() =>\n setExpandedCollapsed((prev) => {\n const next = new Set(prev);\n next.add(seg.startLine);\n return next;\n })\n }\n className=\"flex w-full cursor-pointer items-center gap-2 border-y border-plan-line/50 bg-plan-block/20 px-3 py-0.5 text-left hover:bg-plan-block/40\"\n >\n <span aria-hidden className=\"w-[3px] shrink-0 self-stretch\" />\n <span className=\"w-8 shrink-0 select-none text-right text-[11px] tabular-nums text-plan-muted/40\">\n ···\n </span>\n <span className=\"flex-1 text-[11px] text-plan-muted/70\">\n {hiddenCount} lines — click to expand\n </span>\n </button>\n );\n })}\n </div>\n </div>\n </div>\n );\n\n return (\n <section\n {...ltrCodeBlockProps}\n className=\"plan-block relative\"\n data-block-id={blockId}\n >\n {title && <div className=\"plan-block-label\">{title}</div>}\n {/* The code keeps its full width — no persistent annotation column. Notes\n live in a visually-hidden stack (a11y + tests) and surface ONE at a\n time as an on-hover popover anchored to the right of the code. */}\n {codeSurface}\n {hasAnnotations && <AnnotationHiddenStack items={resolved} ctx={ctx} />}\n {hasAnnotations &&\n !showPersistentAnnotations &&\n activeItem &&\n hover.anchor && (\n <AnnotationHoverCard\n item={activeItem}\n anchor={hover.anchor}\n ctx={ctx}\n preferredSide={annotationHoverSide}\n hoverFallbackSide={annotationHoverFallbackSide}\n onMouseEnter={hover.cancelClose}\n onMouseLeave={hover.scheduleClose}\n onClose={hover.closeForScroll}\n />\n )}\n {summary && <p className=\"mt-5 text-plan-muted\">{summary}</p>}\n </section>\n );\n}\n\n/* ── Edit (panel) ──────────────────────────────────────────────────────────── */\n\nconst codeAreaClass =\n \"min-h-[160px] font-mono [font-size:var(--plan-code-size)] leading-5\";\n\nfunction AnnotatedCodeEdit({\n data,\n onChange,\n editable,\n}: BlockEditProps<AnnotatedCodeData>) {\n const annotations = data.annotations ?? [];\n const patch = (next: Partial<AnnotatedCodeData>) =>\n onChange({ ...data, ...next });\n\n const updateAnnotation = (\n index: number,\n next: Partial<AnnotatedCodeAnnotation>,\n ) =>\n patch({\n annotations: annotations.map((annotation, i) =>\n i === index ? { ...annotation, ...next } : annotation,\n ),\n });\n\n const removeAnnotation = (index: number) =>\n patch({ annotations: annotations.filter((_, i) => i !== index) });\n\n const addAnnotation = () => {\n if (annotations.length >= 80) return; // schema max\n patch({\n annotations: [...annotations, { lines: \"1\", label: \"\", note: \"\" }],\n });\n };\n\n return (\n <div className=\"flex flex-col gap-3\" data-plan-interactive>\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1.5\">\n <DevLabel htmlFor=\"annotated-code-filename\" className=\"text-xs\">\n Filename\n </DevLabel>\n <DevInput\n id=\"annotated-code-filename\"\n value={data.filename ?? \"\"}\n placeholder=\"src/server/auth.ts\"\n disabled={!editable}\n onChange={(event) =>\n patch({ filename: event.target.value || undefined })\n }\n />\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <DevLabel htmlFor=\"annotated-code-language\" className=\"text-xs\">\n Language\n </DevLabel>\n <DevInput\n id=\"annotated-code-language\"\n value={data.language ?? \"\"}\n placeholder=\"ts\"\n disabled={!editable}\n onChange={(event) =>\n patch({ language: event.target.value || undefined })\n }\n />\n </div>\n </div>\n\n <div className=\"flex flex-col gap-1.5\">\n <DevLabel htmlFor=\"annotated-code-code\" className=\"text-xs\">\n Code\n </DevLabel>\n <DevTextarea\n id=\"annotated-code-code\"\n spellCheck={false}\n className={codeAreaClass}\n value={data.code}\n disabled={!editable}\n onChange={(event) => patch({ code: event.target.value })}\n />\n </div>\n\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex items-center justify-between\">\n <DevLabel className=\"text-xs\">Annotations</DevLabel>\n {editable && annotations.length < 80 && (\n <button\n type=\"button\"\n data-plan-interactive\n onClick={addAnnotation}\n className=\"flex cursor-pointer items-center gap-1 rounded-md px-2 py-1 text-xs font-medium text-plan-muted transition-colors hover:bg-plan-block/60 hover:text-plan-text\"\n >\n <IconPlus className=\"size-3.5\" />\n Add annotation\n </button>\n )}\n </div>\n {annotations.length === 0 && (\n <p className=\"text-xs text-plan-muted\">\n No annotations yet. Add one to anchor a note to a line range.\n </p>\n )}\n {annotations.map((annotation, index) => (\n <div\n key={index}\n className=\"flex flex-col gap-2 rounded-md border border-plan-line bg-plan-block/30 p-2\"\n >\n <div className=\"grid gap-2 sm:grid-cols-[120px_minmax(0,1fr)_auto]\">\n <DevInput\n aria-label={`Annotation ${index + 1} lines`}\n value={annotation.lines}\n placeholder=\"3-5\"\n disabled={!editable}\n onChange={(event) =>\n updateAnnotation(index, { lines: event.target.value })\n }\n />\n <DevInput\n aria-label={`Annotation ${index + 1} label`}\n value={annotation.label ?? \"\"}\n placeholder=\"Label (optional)\"\n disabled={!editable}\n onChange={(event) =>\n updateAnnotation(index, {\n label: event.target.value || undefined,\n })\n }\n />\n {editable && (\n <button\n type=\"button\"\n data-plan-interactive\n aria-label={`Remove annotation ${index + 1}`}\n onClick={() => removeAnnotation(index)}\n className=\"flex size-9 shrink-0 cursor-pointer items-center justify-center rounded-md text-plan-muted transition-colors hover:bg-muted hover:text-foreground\"\n >\n <IconTrash className=\"size-4\" />\n </button>\n )}\n </div>\n <DevTextarea\n aria-label={`Annotation ${index + 1} note`}\n className=\"min-h-[60px] text-sm\"\n value={annotation.note}\n placeholder=\"Explain what these lines do…\"\n disabled={!editable}\n onChange={(event) =>\n updateAnnotation(index, { note: event.target.value })\n }\n />\n </div>\n ))}\n </div>\n </div>\n );\n}\n\nexport { AnnotatedCodeRead, AnnotatedCodeEdit };\n"]}
1
+ {"version":3,"file":"AnnotatedCodeBlock.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/AnnotatedCodeBlock.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useMemo, useRef, useState } from \"react\";\nimport { IconCode, IconPlus, IconTrash } from \"@tabler/icons-react\";\nimport { cn } from \"../../utils.js\";\nimport { ltrCodeBlockProps } from \"../code-block-direction.js\";\nimport type { BlockEditProps, BlockReadProps } from \"../types.js\";\nimport type {\n AnnotatedCodeAnnotation,\n AnnotatedCodeData,\n} from \"./annotated-code.config.js\";\nimport {\n highlightCode,\n inferLanguageFromFilename,\n normalizeCodeLanguage,\n} from \"./code-highlight.js\";\nimport {\n AnnotationHiddenStack,\n AnnotationHoverCard,\n AnnotationInlineOverlayStack,\n anchorFromElements,\n buildLineMarkerMap,\n hasRailAnnotations,\n resolveAnnotations,\n useAnnotationMarginNotesAvailable,\n useAnnotationHover,\n type ResolvedAnnotation,\n} from \"./annotation-rail.js\";\nimport { CodeFilenameLabel } from \"./code-filename-label.js\";\nimport { DevInput, DevLabel, DevTextarea } from \"./dev-doc-ui.js\";\n\n/**\n * \"Explain this code\" walkthrough block: a standard syntax-highlighted code\n * surface on the left with line-anchored annotation cards on the right (the\n * Stripe-docs / Sourcegraph layout). Each annotated line range gets a subtle\n * highlight band + an accent rail down the gutter; its card shows the `lines`\n * range, optional `label`, and the always-visible markdown `note` (via\n * `ctx.renderMarkdown`). Hovering a card highlights its lines and vice-versa.\n *\n * Syntax highlighting reuses the shared `highlightCode` lowlight helper (the same\n * colorful palette as the `code-tabs` block) per line, so it matches the app's\n * standard code styling and supports per-line bands without an async loader. The\n * surface uses the plan `--plan-code*`/`--plan-*` tokens and Tailwind `dark:`\n * pairs, so it reads correctly in BOTH light and dark mode. Code lines render as\n * `<span>`s (never one `<pre>` per line) so they don't pick up document\n * code/pre chrome. Lives in core so any app can register the dev-doc block.\n *\n * Editing is panel-driven (config-style, like the diff/HTML blocks): a monospace\n * code Textarea, filename/language Inputs, and add/remove-able annotation rows.\n */\n\n/* ── Collapse helpers ──────────────────────────────────────────────────────── */\n\n/**\n * Minimum total line count before collapse is considered. Short files render\n * fully expanded regardless of annotation coverage.\n */\nconst COLLAPSE_MIN_TOTAL_LINES = 40;\n\n/**\n * Number of unannotated lines in a run that triggers collapse. Runs at or\n * below this threshold always stay expanded (no expander button).\n */\nconst COLLAPSE_THRESHOLD = 16;\n\n/**\n * Context lines kept visible at each edge of a collapsed run (8 lines of\n * breathing room so the collapsed region is clearly framed).\n */\nconst COLLAPSE_CONTEXT_EDGE = 8;\n\ntype CollapsedSegment = {\n kind: \"collapsed\";\n startLine: number;\n endLine: number;\n};\ntype VisibleSegment = { kind: \"visible\"; startLine: number; endLine: number };\ntype LineSegment = VisibleSegment | CollapsedSegment;\n\n/**\n * Partition line numbers [1..lineCount] into visible and collapsed segments.\n * Annotated lines (and COLLAPSE_CONTEXT_EDGE lines on either side of them) are\n * always visible. Runs of unannotated lines longer than COLLAPSE_THRESHOLD are\n * collapsed. The file header (first COLLAPSE_CONTEXT_EDGE lines) is always\n * visible so context is preserved.\n */\nfunction buildLineSegments(\n lineCount: number,\n lineMarkers: Map<number, Array<{ index: number }>>,\n): LineSegment[] {\n if (lineCount <= COLLAPSE_MIN_TOTAL_LINES) {\n return [{ kind: \"visible\", startLine: 1, endLine: lineCount }];\n }\n\n // Build a boolean array: true if the line must stay visible.\n const mustShow = new Array<boolean>(lineCount + 1).fill(false);\n // File header always visible.\n for (let i = 1; i <= Math.min(COLLAPSE_CONTEXT_EDGE, lineCount); i += 1) {\n mustShow[i] = true;\n }\n // Annotated lines and their context edges.\n for (const lineNo of lineMarkers.keys()) {\n for (\n let i = Math.max(1, lineNo - COLLAPSE_CONTEXT_EDGE);\n i <= Math.min(lineCount, lineNo + COLLAPSE_CONTEXT_EDGE);\n i += 1\n ) {\n mustShow[i] = true;\n }\n }\n\n // Compute initial segments.\n const raw: LineSegment[] = [];\n let segStart = 1;\n let visible = mustShow[1] ?? false;\n for (let i = 2; i <= lineCount; i += 1) {\n const nextVisible = mustShow[i] ?? false;\n if (nextVisible !== visible) {\n raw.push(\n visible\n ? { kind: \"visible\", startLine: segStart, endLine: i - 1 }\n : { kind: \"collapsed\", startLine: segStart, endLine: i - 1 },\n );\n segStart = i;\n visible = nextVisible;\n }\n }\n raw.push(\n visible\n ? { kind: \"visible\", startLine: segStart, endLine: lineCount }\n : { kind: \"collapsed\", startLine: segStart, endLine: lineCount },\n );\n\n // Don't collapse short hidden runs — expand them in-place.\n return raw.map((seg) => {\n if (\n seg.kind === \"collapsed\" &&\n seg.endLine - seg.startLine + 1 <= COLLAPSE_THRESHOLD\n ) {\n return {\n kind: \"visible\",\n startLine: seg.startLine,\n endLine: seg.endLine,\n };\n }\n return seg;\n });\n}\n\n/* ── Read ──────────────────────────────────────────────────────────────────── */\n\nfunction AnnotatedCodeRead({\n data,\n blockId,\n title,\n summary,\n ctx,\n}: BlockReadProps<AnnotatedCodeData>) {\n // On-hover popover (anchored to the right of the code) replaces the old\n // persistent rail: nothing is visible when idle. `codeRef` measures the code\n // block's right edge; `hover` carries the active index + captured geometry.\n const hover = useAnnotationHover();\n const { activeIndex } = hover;\n const codeRef = useRef<HTMLDivElement | null>(null);\n const lineRefs = useRef(new Map<number, HTMLDivElement>());\n\n const setLineRef = (lineNo: number, node: HTMLDivElement | null) => {\n if (node) lineRefs.current.set(lineNo, node);\n else lineRefs.current.delete(lineNo);\n };\n\n const lines = useMemo(\n () => data.code.replace(/\\n$/, \"\").split(\"\\n\"),\n [data.code],\n );\n const lineCount = lines.length;\n\n const language = useMemo(\n () =>\n normalizeCodeLanguage(data.language) ??\n inferLanguageFromFilename(data.filename),\n [data.language, data.filename],\n );\n\n // Highlight each line once; empty lines keep their height with a NBSP.\n const highlightedLines = useMemo(\n () =>\n lines.map((text) => (text.length ? highlightCode(text, language) : \" \")),\n [lines, language],\n );\n\n const resolved = useMemo(\n () => resolveAnnotations(data.annotations, () => lineCount),\n [data.annotations, lineCount],\n );\n\n // line number (1-based) → resolved annotations covering it.\n const lineMarkers = useMemo(() => buildLineMarkerMap(resolved), [resolved]);\n\n const hasAnnotations = hasRailAnnotations(resolved);\n const showAnnotationOverlays = Boolean(ctx.showCodeAnnotationOverlays);\n const annotationLayout = ctx.codeAnnotationLayout;\n const annotationHoverSide = annotationLayout?.hoverSide ?? \"right\";\n const annotationHoverFallbackSide =\n annotationLayout?.hoverFallbackSide ?? \"right\";\n const annotationMarginSide = annotationLayout?.marginSide ?? \"auto\";\n const defaultVisibleAnnotations =\n annotationLayout?.defaultVisibleAnnotations ??\n (annotationLayout?.showByDefaultWhenRoom ? \"all\" : undefined);\n const showMarginAnnotations = useAnnotationMarginNotesAvailable({\n containerRef: codeRef,\n enabled: Boolean(\n hasAnnotations && !showAnnotationOverlays && defaultVisibleAnnotations,\n ),\n side: annotationMarginSide,\n preferredSide: annotationHoverSide,\n });\n const showPersistentAnnotations =\n showAnnotationOverlays || showMarginAnnotations;\n const persistentAnnotationIndexes = useMemo(() => {\n if (!showMarginAnnotations || !defaultVisibleAnnotations) {\n return new Set<number>();\n }\n const visible = resolved.filter((item) => item.range);\n if (defaultVisibleAnnotations === \"first\") {\n const first = visible[0];\n return first ? new Set([first.index]) : new Set<number>();\n }\n return new Set(visible.map((item) => item.index));\n }, [defaultVisibleAnnotations, resolved, showMarginAnnotations]);\n const captureOverlayAnnotationIndex = useMemo(\n () => resolved.find((item) => item.range)?.index ?? null,\n [resolved],\n );\n const langChip = data.language?.trim();\n const hasFilename = Boolean(data.filename?.trim());\n const showLangChip = Boolean(langChip && !hasFilename);\n\n // The resolved annotation whose card is currently shown on hover.\n const activeItem =\n useMemo<ResolvedAnnotation<AnnotatedCodeAnnotation> | null>(\n () =>\n activeIndex == null\n ? null\n : (resolved.find((item) => item.index === activeIndex) ?? null),\n [activeIndex, resolved],\n );\n const activeItemIsPersistentlyVisible = Boolean(\n activeItem &&\n !showAnnotationOverlays &&\n persistentAnnotationIndexes.has(activeItem.index),\n );\n\n // Line-collapse state: a set of collapsed segment start lines that have been\n // expanded by the reader. Starts empty (all segments in their default state).\n const [expandedCollapsed, setExpandedCollapsed] = useState<Set<number>>(\n () => new Set(),\n );\n\n const segments = useMemo(\n () => buildLineSegments(lineCount, lineMarkers),\n [lineCount, lineMarkers],\n );\n\n const renderLine = (lineNo: number) => {\n const markers = lineMarkers.get(lineNo);\n const isAnnotated = !!markers?.length;\n const isActive =\n activeIndex != null && !!markers?.some((m) => m.index === activeIndex);\n const overlayItems =\n showPersistentAnnotations && markers\n ? markers.filter(\n (item) =>\n item.range?.start === lineNo &&\n (showAnnotationOverlays\n ? item.index === captureOverlayAnnotationIndex\n : persistentAnnotationIndexes.has(item.index)),\n )\n : [];\n const rowHasPersistentAnnotation = Boolean(\n markers?.some((item) => persistentAnnotationIndexes.has(item.index)),\n );\n\n const buildAnchorForRow = (el: HTMLElement) => {\n if (!markers) return null;\n const primaryMarker = markers[0];\n const anchorLine = primaryMarker.range?.start ?? lineNo;\n const anchorRow = lineRefs.current.get(anchorLine) ?? el;\n return anchorFromElements(codeRef.current, anchorRow);\n };\n\n return (\n <div\n key={lineNo}\n ref={(node) => setLineRef(lineNo, node)}\n data-code-line={lineNo}\n data-annot-row={isAnnotated ? markers?.[0].index : undefined}\n tabIndex={isAnnotated ? 0 : undefined}\n role={isAnnotated ? \"button\" : undefined}\n aria-expanded={isAnnotated ? isActive : undefined}\n aria-label={isAnnotated ? `Line ${lineNo} annotation` : undefined}\n className={cn(\n \"relative flex w-full\",\n isAnnotated && \"cursor-pointer\",\n isActive\n ? \"bg-amber-400/[0.12] dark:bg-amber-300/[0.10]\"\n : rowHasPersistentAnnotation\n ? \"bg-amber-300/[0.14] dark:bg-amber-300/[0.10]\"\n : isAnnotated && showAnnotationOverlays\n ? \"bg-amber-300/[0.14] dark:bg-amber-300/[0.10]\"\n : isAnnotated\n ? \"bg-amber-400/[0.045] dark:bg-amber-300/[0.045]\"\n : null,\n )}\n onMouseEnter={\n isAnnotated && markers\n ? (event) => {\n const anchor = buildAnchorForRow(event.currentTarget);\n if (anchor) hover.open(markers[0].index, anchor);\n }\n : undefined\n }\n onMouseLeave={isAnnotated ? () => hover.scheduleClose() : undefined}\n onClick={\n isAnnotated && markers\n ? (event) => {\n const anchor = buildAnchorForRow(event.currentTarget);\n if (anchor) hover.open(markers[0].index, anchor);\n }\n : undefined\n }\n onKeyDown={\n isAnnotated && markers\n ? (event) => {\n if (event.key !== \"Enter\" && event.key !== \" \") return;\n event.preventDefault();\n const anchor = buildAnchorForRow(event.currentTarget);\n if (anchor) hover.open(markers[0].index, anchor);\n }\n : undefined\n }\n onFocus={\n isAnnotated && markers\n ? (event) => {\n const anchor = buildAnchorForRow(event.currentTarget);\n if (anchor) hover.open(markers[0].index, anchor);\n }\n : undefined\n }\n onBlur={isAnnotated ? () => hover.scheduleClose() : undefined}\n >\n <span\n aria-hidden\n className={cn(\n \"w-[3px] shrink-0 self-stretch\",\n isAnnotated\n ? isActive\n ? \"bg-amber-500/80 dark:bg-amber-400/70\"\n : showAnnotationOverlays\n ? \"bg-amber-500/55 dark:bg-amber-300/45\"\n : \"bg-amber-400/30 dark:bg-amber-300/25\"\n : null,\n )}\n />\n <span className=\"w-11 shrink-0 select-none px-3 text-right text-[11px] tabular-nums text-plan-muted/60\">\n {lineNo}\n </span>\n <span className=\"flex-1 whitespace-pre pr-4 text-plan-code-text\">\n {highlightedLines[lineNo - 1]}\n </span>\n {overlayItems.length > 0 && (\n <AnnotationInlineOverlayStack\n items={overlayItems}\n ctx={ctx}\n containerRef={codeRef}\n mode={showAnnotationOverlays ? \"capture\" : \"margin\"}\n side={showAnnotationOverlays ? \"right\" : annotationMarginSide}\n preferredSide={annotationHoverSide}\n />\n )}\n </div>\n );\n };\n\n const codeSurface = (\n <div\n ref={codeRef}\n className=\"overflow-hidden rounded-xl border border-plan-line bg-plan-code\"\n >\n {(hasFilename || showLangChip) && (\n <div className=\"flex items-center gap-2 border-b border-plan-line bg-plan-block/50 px-3.5 py-2\">\n <IconCode className=\"size-3.5 shrink-0 text-plan-muted\" />\n <CodeFilenameLabel\n filename={data.filename}\n className=\"text-[13px] font-medium\"\n directoryClassName=\"text-plan-muted\"\n basenameClassName=\"text-plan-code-text\"\n />\n {showLangChip && (\n <span className=\"shrink-0 rounded border border-plan-line px-1.5 py-0.5 font-mono text-[10px] uppercase tracking-wide text-plan-muted\">\n {langChip}\n </span>\n )}\n </div>\n )}\n <div className=\"overflow-x-auto py-1.5\" data-code-surface>\n <div className=\"min-w-full font-mono [font-size:var(--plan-doc-code-size)] leading-[22px]\">\n {segments.map((seg) => {\n if (seg.kind === \"visible\") {\n const lineNos = Array.from(\n { length: seg.endLine - seg.startLine + 1 },\n (_, i) => seg.startLine + i,\n );\n return lineNos.map(renderLine);\n }\n // Collapsed segment — show an expander row.\n const isExpanded = expandedCollapsed.has(seg.startLine);\n const hiddenCount = seg.endLine - seg.startLine + 1;\n if (isExpanded) {\n const lineNos = Array.from(\n { length: hiddenCount },\n (_, i) => seg.startLine + i,\n );\n return lineNos.map(renderLine);\n }\n return (\n <button\n key={`collapse-${seg.startLine}`}\n type=\"button\"\n data-plan-interactive\n onClick={() =>\n setExpandedCollapsed((prev) => {\n const next = new Set(prev);\n next.add(seg.startLine);\n return next;\n })\n }\n className=\"flex w-full cursor-pointer items-center gap-2 border-y border-plan-line/50 bg-plan-block/20 px-3 py-0.5 text-left hover:bg-plan-block/40\"\n >\n <span aria-hidden className=\"w-[3px] shrink-0 self-stretch\" />\n <span className=\"w-8 shrink-0 select-none text-right text-[11px] tabular-nums text-plan-muted/40\">\n ···\n </span>\n <span className=\"flex-1 text-[11px] text-plan-muted/70\">\n {hiddenCount} lines — click to expand\n </span>\n </button>\n );\n })}\n </div>\n </div>\n </div>\n );\n\n return (\n <section\n {...ltrCodeBlockProps}\n className=\"plan-block relative\"\n data-block-id={blockId}\n >\n {title && <div className=\"plan-block-label\">{title}</div>}\n {/* The code keeps its full width — no persistent annotation column. Notes\n live in a visually-hidden stack (a11y + tests) and surface ONE at a\n time as an on-hover popover anchored to the right of the code. */}\n {codeSurface}\n {hasAnnotations && <AnnotationHiddenStack items={resolved} ctx={ctx} />}\n {hasAnnotations &&\n !showAnnotationOverlays &&\n !activeItemIsPersistentlyVisible &&\n activeItem &&\n hover.anchor && (\n <AnnotationHoverCard\n item={activeItem}\n anchor={hover.anchor}\n ctx={ctx}\n preferredSide={annotationHoverSide}\n hoverFallbackSide={annotationHoverFallbackSide}\n onMouseEnter={hover.cancelClose}\n onMouseLeave={hover.scheduleClose}\n onClose={hover.closeForScroll}\n />\n )}\n {summary && <p className=\"mt-5 text-plan-muted\">{summary}</p>}\n </section>\n );\n}\n\n/* ── Edit (panel) ──────────────────────────────────────────────────────────── */\n\nconst codeAreaClass =\n \"min-h-[160px] font-mono [font-size:var(--plan-code-size)] leading-5\";\n\nfunction AnnotatedCodeEdit({\n data,\n onChange,\n editable,\n}: BlockEditProps<AnnotatedCodeData>) {\n const annotations = data.annotations ?? [];\n const patch = (next: Partial<AnnotatedCodeData>) =>\n onChange({ ...data, ...next });\n\n const updateAnnotation = (\n index: number,\n next: Partial<AnnotatedCodeAnnotation>,\n ) =>\n patch({\n annotations: annotations.map((annotation, i) =>\n i === index ? { ...annotation, ...next } : annotation,\n ),\n });\n\n const removeAnnotation = (index: number) =>\n patch({ annotations: annotations.filter((_, i) => i !== index) });\n\n const addAnnotation = () => {\n if (annotations.length >= 80) return; // schema max\n patch({\n annotations: [...annotations, { lines: \"1\", label: \"\", note: \"\" }],\n });\n };\n\n return (\n <div className=\"flex flex-col gap-3\" data-plan-interactive>\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1.5\">\n <DevLabel htmlFor=\"annotated-code-filename\" className=\"text-xs\">\n Filename\n </DevLabel>\n <DevInput\n id=\"annotated-code-filename\"\n value={data.filename ?? \"\"}\n placeholder=\"src/server/auth.ts\"\n disabled={!editable}\n onChange={(event) =>\n patch({ filename: event.target.value || undefined })\n }\n />\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <DevLabel htmlFor=\"annotated-code-language\" className=\"text-xs\">\n Language\n </DevLabel>\n <DevInput\n id=\"annotated-code-language\"\n value={data.language ?? \"\"}\n placeholder=\"ts\"\n disabled={!editable}\n onChange={(event) =>\n patch({ language: event.target.value || undefined })\n }\n />\n </div>\n </div>\n\n <div className=\"flex flex-col gap-1.5\">\n <DevLabel htmlFor=\"annotated-code-code\" className=\"text-xs\">\n Code\n </DevLabel>\n <DevTextarea\n id=\"annotated-code-code\"\n spellCheck={false}\n className={codeAreaClass}\n value={data.code}\n disabled={!editable}\n onChange={(event) => patch({ code: event.target.value })}\n />\n </div>\n\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex items-center justify-between\">\n <DevLabel className=\"text-xs\">Annotations</DevLabel>\n {editable && annotations.length < 80 && (\n <button\n type=\"button\"\n data-plan-interactive\n onClick={addAnnotation}\n className=\"flex cursor-pointer items-center gap-1 rounded-md px-2 py-1 text-xs font-medium text-plan-muted transition-colors hover:bg-plan-block/60 hover:text-plan-text\"\n >\n <IconPlus className=\"size-3.5\" />\n Add annotation\n </button>\n )}\n </div>\n {annotations.length === 0 && (\n <p className=\"text-xs text-plan-muted\">\n No annotations yet. Add one to anchor a note to a line range.\n </p>\n )}\n {annotations.map((annotation, index) => (\n <div\n key={index}\n className=\"flex flex-col gap-2 rounded-md border border-plan-line bg-plan-block/30 p-2\"\n >\n <div className=\"grid gap-2 sm:grid-cols-[120px_minmax(0,1fr)_auto]\">\n <DevInput\n aria-label={`Annotation ${index + 1} lines`}\n value={annotation.lines}\n placeholder=\"3-5\"\n disabled={!editable}\n onChange={(event) =>\n updateAnnotation(index, { lines: event.target.value })\n }\n />\n <DevInput\n aria-label={`Annotation ${index + 1} label`}\n value={annotation.label ?? \"\"}\n placeholder=\"Label (optional)\"\n disabled={!editable}\n onChange={(event) =>\n updateAnnotation(index, {\n label: event.target.value || undefined,\n })\n }\n />\n {editable && (\n <button\n type=\"button\"\n data-plan-interactive\n aria-label={`Remove annotation ${index + 1}`}\n onClick={() => removeAnnotation(index)}\n className=\"flex size-9 shrink-0 cursor-pointer items-center justify-center rounded-md text-plan-muted transition-colors hover:bg-muted hover:text-foreground\"\n >\n <IconTrash className=\"size-4\" />\n </button>\n )}\n </div>\n <DevTextarea\n aria-label={`Annotation ${index + 1} note`}\n className=\"min-h-[60px] text-sm\"\n value={annotation.note}\n placeholder=\"Explain what these lines do…\"\n disabled={!editable}\n onChange={(event) =>\n updateAnnotation(index, { note: event.target.value })\n }\n />\n </div>\n ))}\n </div>\n </div>\n );\n}\n\nexport { AnnotatedCodeRead, AnnotatedCodeEdit };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"DiffBlock.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/DiffBlock.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EAEf,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAkB,QAAQ,EAAY,MAAM,kBAAkB,CAAC;AAmB3E;;;;;;;;;;;;;;;GAeG;AAIH,UAAU,MAAM;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAqBD;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAsEjE;AAoeD,iBAAS,QAAQ,CAAC,EAChB,IAAI,EACJ,OAAO,EACP,KAAK,EACL,OAAO,EACP,GAAG,GACJ,EAAE,cAAc,CAAC,QAAQ,CAAC,2CAgW1B;AAylBD,iBAAS,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,cAAc,CAAC,QAAQ,CAAC,2CA2LvE;AAED,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC"}
1
+ {"version":3,"file":"DiffBlock.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/DiffBlock.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EAEf,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAkB,QAAQ,EAAY,MAAM,kBAAkB,CAAC;AAmB3E;;;;;;;;;;;;;;;GAeG;AAIH,UAAU,MAAM;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAqBD;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAsEjE;AAoeD,iBAAS,QAAQ,CAAC,EAChB,IAAI,EACJ,OAAO,EACP,KAAK,EACL,OAAO,EACP,GAAG,GACJ,EAAE,cAAc,CAAC,QAAQ,CAAC,2CAoX1B;AAwnBD,iBAAS,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,cAAc,CAAC,QAAQ,CAAC,2CA2LvE;AAED,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC"}
@@ -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";