@agent-native/core 0.44.0 → 0.44.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/cli/pr-visual-recap-workflow.d.ts +1 -1
  2. package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -1
  3. package/dist/cli/pr-visual-recap-workflow.js +1 -1
  4. package/dist/cli/pr-visual-recap-workflow.js.map +1 -1
  5. package/dist/cli/recap.d.ts +23 -0
  6. package/dist/cli/recap.d.ts.map +1 -1
  7. package/dist/cli/recap.js +175 -0
  8. package/dist/cli/recap.js.map +1 -1
  9. package/dist/cli/skills.d.ts +3 -3
  10. package/dist/cli/skills.d.ts.map +1 -1
  11. package/dist/cli/skills.js +54 -7
  12. package/dist/cli/skills.js.map +1 -1
  13. package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts.map +1 -1
  14. package/dist/client/blocks/library/AnnotatedCodeBlock.js +21 -8
  15. package/dist/client/blocks/library/AnnotatedCodeBlock.js.map +1 -1
  16. package/dist/client/blocks/library/ApiEndpointBlock.d.ts.map +1 -1
  17. package/dist/client/blocks/library/ApiEndpointBlock.js +112 -12
  18. package/dist/client/blocks/library/ApiEndpointBlock.js.map +1 -1
  19. package/dist/client/blocks/library/DiffBlock.d.ts.map +1 -1
  20. package/dist/client/blocks/library/DiffBlock.js +59 -75
  21. package/dist/client/blocks/library/DiffBlock.js.map +1 -1
  22. package/dist/client/blocks/library/JsonExplorerBlock.d.ts.map +1 -1
  23. package/dist/client/blocks/library/JsonExplorerBlock.js +1 -1
  24. package/dist/client/blocks/library/JsonExplorerBlock.js.map +1 -1
  25. package/dist/client/blocks/library/MermaidBlock.d.ts.map +1 -1
  26. package/dist/client/blocks/library/MermaidBlock.js +22 -3
  27. package/dist/client/blocks/library/MermaidBlock.js.map +1 -1
  28. package/dist/client/blocks/library/annotation-rail.d.ts +85 -0
  29. package/dist/client/blocks/library/annotation-rail.d.ts.map +1 -1
  30. package/dist/client/blocks/library/annotation-rail.js +149 -8
  31. package/dist/client/blocks/library/annotation-rail.js.map +1 -1
  32. package/dist/client/blocks/library/diagram.d.ts +17 -0
  33. package/dist/client/blocks/library/diagram.d.ts.map +1 -1
  34. package/dist/client/blocks/library/diagram.js +47 -2
  35. package/dist/client/blocks/library/diagram.js.map +1 -1
  36. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  37. package/dist/client/composer/TiptapComposer.js +13 -8
  38. package/dist/client/composer/TiptapComposer.js.map +1 -1
  39. package/dist/client/composer/pasted-text.d.ts +25 -0
  40. package/dist/client/composer/pasted-text.d.ts.map +1 -1
  41. package/dist/client/composer/pasted-text.js +86 -4
  42. package/dist/client/composer/pasted-text.js.map +1 -1
  43. package/dist/db/migrations.d.ts +10 -0
  44. package/dist/db/migrations.d.ts.map +1 -1
  45. package/dist/db/migrations.js +32 -0
  46. package/dist/db/migrations.js.map +1 -1
  47. package/dist/server/og-fonts-data.d.ts +3 -0
  48. package/dist/server/og-fonts-data.d.ts.map +1 -0
  49. package/dist/server/og-fonts-data.js +9 -0
  50. package/dist/server/og-fonts-data.js.map +1 -0
  51. package/dist/server/og-fonts.d.ts +10 -0
  52. package/dist/server/og-fonts.d.ts.map +1 -0
  53. package/dist/server/og-fonts.js +58 -0
  54. package/dist/server/og-fonts.js.map +1 -0
  55. package/dist/server/social-og-image.d.ts.map +1 -1
  56. package/dist/server/social-og-image.js +16 -5
  57. package/dist/server/social-og-image.js.map +1 -1
  58. package/dist/styles/blocks.css +111 -0
  59. package/dist/usage/store.d.ts +12 -0
  60. package/dist/usage/store.d.ts.map +1 -1
  61. package/dist/usage/store.js +35 -5
  62. package/dist/usage/store.js.map +1 -1
  63. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"annotation-rail.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/annotation-rail.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useMemo, type ReactNode } from \"react\";\nimport { cn } from \"../../utils.js\";\nimport type { BlockRenderContext } from \"../types.js\";\n\n/**\n * Shared line-anchored annotation UI for the `annotated-code` and `diff` blocks.\n *\n * Both blocks render a numbered code surface plus a side \"rail\" of notes, where\n * each note targets a 1-based `lines` ref (`\"3\"` or `\"3-5\"`) and hovering a code\n * line ↔ its note cross-highlights. This module owns the pure pieces that were\n * identical between them so neither block forks the behavior:\n *\n * - `parseLineRange` — the forgiving 1-based `lines` range parser.\n * - `resolveAnnotations` / `buildLineMarkerMap` — turn a raw annotation list\n * into stable, marker-numbered, range-resolved records and a line→markers map.\n * - `rangeLabel` — the human \"Line 8\" / \"Lines 3–6\" label.\n * - `AnnotationGutterMarker` — the numbered amber pip placed on an annotated row\n * (used by the diff grid; the annotated-code surface uses its own rail bar).\n * - `AnnotationNoteRail` — the responsive list of note cards with two-way hover.\n * `showMarker` opts the diff block into a leading numbered pip on each card so\n * a note can be matched to its `①`/`②` row marker; annotated-code omits it to\n * keep its original card chrome.\n *\n * `AnnotatedCodeBlock` annotates a single code surface; `DiffBlock` annotates a\n * before/after grid (each annotation also carries a `side`). The shared types\n * here are intentionally minimal — callers pass their own `side` handling and\n * decide which rows a marker lands on; this module only owns the parsing, the\n * resolved-record shape, and the rendered marker + rail chrome.\n */\n\n/* ── Line-ref parsing ──────────────────────────────────────────────────────── */\n\n/**\n * Parse a 1-based `lines` ref (`\"3\"` or `\"3-5\"`) into an inclusive `[start,end]`\n * pair, clamped to `[1, lineCount]`. Returns `null` for malformed or fully\n * out-of-range refs so callers can ignore them gracefully. A reversed range\n * (`\"5-3\"`) is normalized; a partially out-of-range range is clamped.\n */\nexport function parseLineRange(\n ref: string,\n lineCount: number,\n): { start: number; end: number } | null {\n const match = /^\\s*(\\d+)\\s*(?:-\\s*(\\d+)\\s*)?$/.exec(ref);\n if (!match) return null;\n let start = Number.parseInt(match[1], 10);\n let end = match[2] != null ? Number.parseInt(match[2], 10) : start;\n if (!Number.isFinite(start) || !Number.isFinite(end)) return null;\n if (start > end) [start, end] = [end, start];\n // Fully outside the file → ignore.\n if (end < 1 || start > lineCount) return null;\n return { start: Math.max(1, start), end: Math.min(lineCount, end) };\n}\n\n/** The minimal annotation shape the rail needs (a superset works too). */\nexport interface RailAnnotation {\n lines: string;\n label?: string;\n note: string;\n}\n\nexport interface ResolvedAnnotation<A extends RailAnnotation = RailAnnotation> {\n /** Index in the original `annotations` array (stable hover key). */\n index: number;\n /** 1-based marker number (authoring order). */\n marker: number;\n annotation: A;\n range: { start: number; end: number } | null;\n}\n\n/**\n * Resolve a raw annotation list into stable, marker-numbered records, parsing\n * each `lines` ref against `lineCount`. `lineCountFor` lets the diff block pick a\n * per-annotation line count (before-side vs after-side); annotated-code passes a\n * single constant. Markers are authoring-order, 1-based, and assigned to ALL\n * annotations (even unresolved ones) so numbering is stable regardless of which\n * refs happen to match.\n */\nexport function resolveAnnotations<A extends RailAnnotation>(\n annotations: A[] | undefined,\n lineCountFor: (annotation: A) => number,\n): ResolvedAnnotation<A>[] {\n return (annotations ?? []).map((annotation, index) => ({\n index,\n marker: index + 1,\n annotation,\n range: parseLineRange(annotation.lines, lineCountFor(annotation)),\n }));\n}\n\n/** Map a 1-based line number → the resolved annotations covering it. */\nexport function buildLineMarkerMap<A extends RailAnnotation>(\n resolved: ResolvedAnnotation<A>[],\n): Map<number, ResolvedAnnotation<A>[]> {\n const map = new Map<number, ResolvedAnnotation<A>[]>();\n for (const item of resolved) {\n if (!item.range) continue;\n for (let n = item.range.start; n <= item.range.end; n += 1) {\n const list = map.get(n) ?? [];\n list.push(item);\n map.set(n, list);\n }\n }\n return map;\n}\n\n/** Human label for a resolved annotation's line span (\"Line 8\" / \"Lines 3–6\"). */\nexport function rangeLabel(item: ResolvedAnnotation): string {\n if (!item.range) return `Lines ${item.annotation.lines}`;\n return item.range.start === item.range.end\n ? `Line ${item.range.start}`\n : `Lines ${item.range.start}–${item.range.end}`;\n}\n\n/* ── Marker ────────────────────────────────────────────────────────────────── */\n\n/**\n * The numbered amber pip rendered on an annotated code row's gutter. `active`\n * brightens it when its note (or a co-located row) is hovered.\n */\nexport function AnnotationGutterMarker({\n marker,\n active,\n className,\n}: {\n marker: number;\n active: boolean;\n className?: string;\n}) {\n return (\n <span\n aria-hidden\n className={cn(\n \"inline-flex size-[15px] shrink-0 items-center justify-center rounded-full text-[9px] font-semibold leading-none tabular-nums transition-colors\",\n active\n ? \"bg-amber-500 text-white dark:bg-amber-400 dark:text-amber-950\"\n : \"bg-amber-400/25 text-amber-700 dark:bg-amber-300/20 dark:text-amber-300\",\n className,\n )}\n >\n {marker}\n </span>\n );\n}\n\n/* ── Note rail ─────────────────────────────────────────────────────────────── */\n\n/**\n * The responsive list of line-anchored note cards. Each card shows its marker\n * pip, the resolved line span (\"Line 8\"), an optional label, and the markdown\n * `note` (via `ctx.renderMarkdown`). Hovering a card sets the active index;\n * `activeIndex` driven from outside lets a hovered code row light its card and\n * vice-versa. Only annotations whose `range` resolved are listed.\n */\nexport function AnnotationNoteRail<A extends RailAnnotation>({\n items,\n activeIndex,\n onActiveChange,\n ctx,\n className,\n showMarker = false,\n}: {\n items: ResolvedAnnotation<A>[];\n activeIndex: number | null;\n onActiveChange: (index: number | null) => void;\n ctx: BlockRenderContext;\n className?: string;\n /** Show a leading numbered pip on each card (diff block). */\n showMarker?: boolean;\n}) {\n const sideAnnotations = useMemo(\n () => items.filter((item) => item.range),\n [items],\n );\n return (\n <div className={cn(\"flex flex-col gap-2.5\", className)}>\n {sideAnnotations.map((item) => {\n const isActive = activeIndex === item.index;\n return (\n <div\n key={item.index}\n onMouseEnter={() => onActiveChange(item.index)}\n onMouseLeave={() => onActiveChange(null)}\n className={cn(\n \"rounded-lg border px-3.5 py-2.5 transition-colors\",\n isActive\n ? \"border-amber-400/70 bg-amber-50 dark:border-amber-300/40 dark:bg-amber-300/[0.08]\"\n : \"border-plan-line bg-plan-block/40 hover:border-amber-400/50\",\n )}\n >\n <div\n className={cn(\n \"flex flex-wrap gap-x-2 gap-y-0.5\",\n showMarker ? \"items-center\" : \"items-baseline\",\n )}\n >\n {showMarker && (\n <AnnotationGutterMarker\n marker={item.marker}\n active={isActive}\n />\n )}\n <span className=\"text-[11px] font-semibold uppercase tracking-wide text-plan-muted\">\n {rangeLabel(item)}\n </span>\n {item.annotation.label && (\n <span className=\"text-[13px] font-semibold text-plan-text\">\n {item.annotation.label}\n </span>\n )}\n </div>\n <div className=\"plan-annotation-note mt-1 text-[13px] leading-relaxed text-plan-text/85\">\n {ctx.renderMarkdown ? (\n ctx.renderMarkdown(item.annotation.note)\n ) : (\n <p>{item.annotation.note}</p>\n )}\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n\n/** Whether a resolved list has at least one note worth rendering a rail for. */\nexport function hasRailAnnotations(items: ResolvedAnnotation[]): boolean {\n return items.some((item) => item.range);\n}\n\nexport type AnnotationRailChildren = ReactNode;\n"]}
1
+ {"version":3,"file":"annotation-rail.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/annotation-rail.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../../utils.js\";\nimport type { BlockRenderContext } from \"../types.js\";\n\n/**\n * Shared line-anchored annotation UI for the `annotated-code` and `diff` blocks.\n *\n * Both blocks render a numbered code surface plus a side \"rail\" of notes, where\n * each note targets a 1-based `lines` ref (`\"3\"` or `\"3-5\"`) and hovering a code\n * line ↔ its note cross-highlights. This module owns the pure pieces that were\n * identical between them so neither block forks the behavior:\n *\n * - `parseLineRange` — the forgiving 1-based `lines` range parser.\n * - `resolveAnnotations` / `buildLineMarkerMap` — turn a raw annotation list\n * into stable, marker-numbered, range-resolved records and a line→markers map.\n * - `rangeLabel` — the human \"Line 8\" / \"Lines 3–6\" label.\n * - `AnnotationGutterMarker` — the numbered amber pip placed on an annotated row\n * (used by the diff grid; the annotated-code surface uses its own rail bar).\n * - `AnnotationNoteRail` — the responsive list of note cards with two-way hover.\n * `showMarker` opts the diff block into a leading numbered pip on each card so\n * a note can be matched to its `①`/`②` row marker; annotated-code omits it to\n * keep its original card chrome.\n *\n * `AnnotatedCodeBlock` annotates a single code surface; `DiffBlock` annotates a\n * before/after grid (each annotation also carries a `side`). The shared types\n * here are intentionally minimal — callers pass their own `side` handling and\n * decide which rows a marker lands on; this module only owns the parsing, the\n * resolved-record shape, and the rendered marker + rail chrome.\n */\n\n/* ── Line-ref parsing ──────────────────────────────────────────────────────── */\n\n/**\n * Parse a 1-based `lines` ref (`\"3\"` or `\"3-5\"`) into an inclusive `[start,end]`\n * pair, clamped to `[1, lineCount]`. Returns `null` for malformed or fully\n * out-of-range refs so callers can ignore them gracefully. A reversed range\n * (`\"5-3\"`) is normalized; a partially out-of-range range is clamped.\n */\nexport function parseLineRange(\n ref: string,\n lineCount: number,\n): { start: number; end: number } | null {\n const match = /^\\s*(\\d+)\\s*(?:-\\s*(\\d+)\\s*)?$/.exec(ref);\n if (!match) return null;\n let start = Number.parseInt(match[1], 10);\n let end = match[2] != null ? Number.parseInt(match[2], 10) : start;\n if (!Number.isFinite(start) || !Number.isFinite(end)) return null;\n if (start > end) [start, end] = [end, start];\n // Fully outside the file → ignore.\n if (end < 1 || start > lineCount) return null;\n return { start: Math.max(1, start), end: Math.min(lineCount, end) };\n}\n\n/** The minimal annotation shape the rail needs (a superset works too). */\nexport interface RailAnnotation {\n lines: string;\n label?: string;\n note: string;\n}\n\nexport interface ResolvedAnnotation<A extends RailAnnotation = RailAnnotation> {\n /** Index in the original `annotations` array (stable hover key). */\n index: number;\n /** 1-based marker number (authoring order). */\n marker: number;\n annotation: A;\n range: { start: number; end: number } | null;\n}\n\n/**\n * Resolve a raw annotation list into stable, marker-numbered records, parsing\n * each `lines` ref against `lineCount`. `lineCountFor` lets the diff block pick a\n * per-annotation line count (before-side vs after-side); annotated-code passes a\n * single constant. Markers are authoring-order, 1-based, and assigned to ALL\n * annotations (even unresolved ones) so numbering is stable regardless of which\n * refs happen to match.\n */\nexport function resolveAnnotations<A extends RailAnnotation>(\n annotations: A[] | undefined,\n lineCountFor: (annotation: A) => number,\n): ResolvedAnnotation<A>[] {\n return (annotations ?? []).map((annotation, index) => ({\n index,\n marker: index + 1,\n annotation,\n range: parseLineRange(annotation.lines, lineCountFor(annotation)),\n }));\n}\n\n/** Map a 1-based line number → the resolved annotations covering it. */\nexport function buildLineMarkerMap<A extends RailAnnotation>(\n resolved: ResolvedAnnotation<A>[],\n): Map<number, ResolvedAnnotation<A>[]> {\n const map = new Map<number, ResolvedAnnotation<A>[]>();\n for (const item of resolved) {\n if (!item.range) continue;\n for (let n = item.range.start; n <= item.range.end; n += 1) {\n const list = map.get(n) ?? [];\n list.push(item);\n map.set(n, list);\n }\n }\n return map;\n}\n\n/** Human label for a resolved annotation's line span (\"Line 8\" / \"Lines 3–6\"). */\nexport function rangeLabel(item: ResolvedAnnotation): string {\n if (!item.range) return `Lines ${item.annotation.lines}`;\n return item.range.start === item.range.end\n ? `Line ${item.range.start}`\n : `Lines ${item.range.start}–${item.range.end}`;\n}\n\n/* ── Marker ────────────────────────────────────────────────────────────────── */\n\n/**\n * The numbered amber pip rendered on an annotated code row's gutter. `active`\n * brightens it when its note (or a co-located row) is hovered.\n */\nexport function AnnotationGutterMarker({\n marker,\n active,\n className,\n}: {\n marker: number;\n active: boolean;\n className?: string;\n}) {\n return (\n <span\n aria-hidden\n className={cn(\n \"inline-flex size-[15px] shrink-0 items-center justify-center rounded-full text-[9px] font-semibold leading-none tabular-nums transition-colors\",\n active\n ? \"bg-amber-500 text-white dark:bg-amber-400 dark:text-amber-950\"\n : \"bg-amber-400/25 text-amber-700 dark:bg-amber-300/20 dark:text-amber-300\",\n className,\n )}\n >\n {marker}\n </span>\n );\n}\n\n/* ── Note card ─────────────────────────────────────────────────────────────── */\n\n/**\n * One line-anchored note card: marker pip (when `showMarker`), the resolved line\n * span (\"Line 8\"), an optional label, and the markdown `note` (via\n * `ctx.renderMarkdown`). This is the single source of card markup, rendered both\n * by the visually-hidden a11y/test stack and by the on-hover portal popover.\n */\nexport function AnnotationCard<A extends RailAnnotation>({\n item,\n ctx,\n active = false,\n showMarker = false,\n className,\n onMouseEnter,\n onMouseLeave,\n}: {\n item: ResolvedAnnotation<A>;\n ctx: BlockRenderContext;\n active?: boolean;\n showMarker?: boolean;\n className?: string;\n onMouseEnter?: () => void;\n onMouseLeave?: () => void;\n}) {\n return (\n <div\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n className={cn(\n \"rounded-lg border px-3.5 py-2.5 transition-colors\",\n active\n ? \"border-amber-400/70 bg-amber-50 dark:border-amber-300/40 dark:bg-amber-300/[0.08]\"\n : \"border-plan-line bg-plan-block/40 hover:border-amber-400/50\",\n className,\n )}\n >\n <div\n className={cn(\n \"flex flex-wrap gap-x-2 gap-y-0.5\",\n showMarker ? \"items-center\" : \"items-baseline\",\n )}\n >\n {showMarker && (\n <AnnotationGutterMarker marker={item.marker} active={active} />\n )}\n <span className=\"text-[11px] font-semibold uppercase tracking-wide text-plan-muted\">\n {rangeLabel(item)}\n </span>\n {item.annotation.label && (\n <span className=\"text-[13px] font-semibold text-plan-text\">\n {item.annotation.label}\n </span>\n )}\n </div>\n <div className=\"plan-annotation-note mt-1 text-[13px] leading-relaxed text-plan-text/85\">\n {ctx.renderMarkdown ? (\n ctx.renderMarkdown(item.annotation.note)\n ) : (\n <p>{item.annotation.note}</p>\n )}\n </div>\n </div>\n );\n}\n\n/**\n * Visually-hidden stack of every resolved note. It is NOT a visible column — it\n * sits in the flow but clipped to a 1px box (the `sr-only` pattern) so the note\n * text and the per-card marker pips stay in the accessibility tree and in the\n * DOM (assistive tech can reach them, and tests that read `textContent`/count\n * pips still see them) WITHOUT painting a persistent rail beside the code. The\n * visible card appears only on hover via {@link AnnotationHoverCard}.\n */\nexport function AnnotationHiddenStack<A extends RailAnnotation>({\n items,\n ctx,\n showMarker = false,\n}: {\n items: ResolvedAnnotation<A>[];\n ctx: BlockRenderContext;\n showMarker?: boolean;\n}) {\n const resolved = useMemo(() => items.filter((item) => item.range), [items]);\n if (resolved.length === 0) return null;\n return (\n <div\n className=\"absolute size-px overflow-hidden whitespace-nowrap border-0 p-0 [clip:rect(0,0,0,0)] [clip-path:inset(50%)]\"\n data-annotation-hidden-stack\n >\n {resolved.map((item) => (\n <AnnotationCard\n key={item.index}\n item={item}\n ctx={ctx}\n showMarker={showMarker}\n />\n ))}\n </div>\n );\n}\n\n/* ── Hover popover (portal, anchored RIGHT of the code) ────────────────────── */\n\n/** The geometry the hover card anchors to (in viewport coordinates). */\nexport interface AnnotationAnchor {\n /** Right edge of the code block (where the card should start). */\n codeRight: number;\n /** Left edge of the code block (for the below-fallback alignment). */\n codeLeft: number;\n /** Vertical center of the hovered line. */\n lineCenter: number;\n /** Bottom of the hovered line (for the below-fallback placement). */\n lineBottom: number;\n}\n\nconst HOVER_CARD_WIDTH = 280;\nconst HOVER_CARD_GAP = 12;\nconst VIEWPORT_MARGIN = 8;\n\n/**\n * The single on-hover note card, portaled to `document.body` and positioned\n * `fixed` so it escapes the code block's `overflow` and never reflows the code.\n *\n * Placement: by default it sits to the RIGHT of the code block's right edge,\n * vertically centered on the hovered line — so it never overlaps the code text.\n * If there isn't room to the right (it would overflow the viewport), it clamps\n * within the viewport, and if the right gutter is too narrow for the card it\n * falls back to BELOW the hovered line (left-aligned to the code block). The card\n * keeps itself open while hovered (`onMouseEnter`/`onMouseLeave` forwarded) so it\n * stays readable; the caller adds the small hover-intent close delay.\n */\nexport function AnnotationHoverCard<A extends RailAnnotation>({\n item,\n anchor,\n ctx,\n showMarker = false,\n onMouseEnter,\n onMouseLeave,\n}: {\n item: ResolvedAnnotation<A>;\n anchor: AnnotationAnchor;\n ctx: BlockRenderContext;\n showMarker?: boolean;\n onMouseEnter?: () => void;\n onMouseLeave?: () => void;\n}) {\n const cardRef = useRef<HTMLDivElement | null>(null);\n const [pos, setPos] = useState<{ top: number; left: number } | null>(null);\n\n // Measure the rendered card, then resolve a non-overlapping position: right of\n // the code if it fits, else clamp into the viewport, else drop below the line.\n useLayoutEffect(() => {\n if (typeof window === \"undefined\") return;\n const el = cardRef.current;\n const rect = el?.getBoundingClientRect();\n const width = rect && rect.width > 0 ? rect.width : HOVER_CARD_WIDTH;\n const height = rect && rect.height > 0 ? rect.height : 0;\n const vw = window.innerWidth || 0;\n const vh = window.innerHeight || 0;\n\n const rightLeft = anchor.codeRight + HOVER_CARD_GAP;\n const fitsRight = rightLeft + width + VIEWPORT_MARGIN <= vw;\n\n let left: number;\n let top: number;\n if (fitsRight) {\n // Default: to the right of the code, centered on the hovered line.\n left = rightLeft;\n top = anchor.lineCenter - height / 2;\n } else {\n // No room to the right → drop below the line, aligned to the code's left.\n left = anchor.codeLeft;\n top = anchor.lineBottom + HOVER_CARD_GAP;\n }\n // Clamp within the viewport so the card is never cut off.\n left = Math.max(\n VIEWPORT_MARGIN,\n Math.min(left, vw - width - VIEWPORT_MARGIN),\n );\n top = Math.max(\n VIEWPORT_MARGIN,\n Math.min(top, vh - height - VIEWPORT_MARGIN),\n );\n setPos({ top, left });\n }, [\n anchor.codeRight,\n anchor.codeLeft,\n anchor.lineCenter,\n anchor.lineBottom,\n item.index,\n ]);\n\n if (typeof document === \"undefined\") return null;\n\n return createPortal(\n <div\n ref={cardRef}\n role=\"tooltip\"\n data-annotation-hover-card\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n className=\"pointer-events-auto fixed z-50\"\n style={{\n top: pos?.top ?? anchor.lineCenter,\n left: pos?.left ?? anchor.codeRight + HOVER_CARD_GAP,\n width: HOVER_CARD_WIDTH,\n // Hide until measured to avoid a one-frame jump from the fallback spot.\n visibility: pos ? \"visible\" : \"hidden\",\n }}\n >\n <AnnotationCard\n item={item}\n ctx={ctx}\n active\n showMarker={showMarker}\n className=\"shadow-lg shadow-black/10 dark:shadow-black/40\"\n />\n </div>,\n document.body,\n );\n}\n\n/**\n * Hover-intent controller for the on-hover note card. Exposes `activeIndex` +\n * the captured `anchor`, plus `open`/`scheduleClose`/`cancelClose` handlers.\n *\n * - `open(index, anchor)` shows a card immediately (cancels any pending close).\n * - `scheduleClose()` hides after a short delay, so moving the pointer from the\n * code line across the gap into the card itself keeps it open.\n * - `cancelClose()` (call on card mouse-enter) keeps it open while reading.\n */\nexport function useAnnotationHover(delay = 130) {\n const [active, setActive] = useState<{\n index: number;\n anchor: AnnotationAnchor;\n } | null>(null);\n const timer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const cancelClose = () => {\n if (timer.current) {\n clearTimeout(timer.current);\n timer.current = null;\n }\n };\n const open = (index: number, anchor: AnnotationAnchor) => {\n cancelClose();\n setActive({ index, anchor });\n };\n const scheduleClose = () => {\n cancelClose();\n timer.current = setTimeout(() => setActive(null), delay);\n };\n\n useEffect(() => () => cancelClose(), []);\n\n return {\n activeIndex: active?.index ?? null,\n anchor: active?.anchor ?? null,\n open,\n scheduleClose,\n cancelClose,\n } as const;\n}\n\n/**\n * Build an {@link AnnotationAnchor} from the code block element and the hovered\n * row element. The card anchors to the code block's RIGHT edge and the row's\n * vertical center, both in viewport coordinates (so a `fixed` portal lines up).\n */\nexport function anchorFromElements(\n codeEl: HTMLElement | null,\n rowEl: HTMLElement | null,\n): AnnotationAnchor | null {\n if (!codeEl || !rowEl) return null;\n const code = codeEl.getBoundingClientRect();\n const row = rowEl.getBoundingClientRect();\n return {\n codeRight: code.right,\n codeLeft: code.left,\n lineCenter: row.top + row.height / 2,\n lineBottom: row.bottom,\n };\n}\n\n/**\n * The responsive list of line-anchored note cards. Each card shows its marker\n * pip, the resolved line span (\"Line 8\"), an optional label, and the markdown\n * `note` (via `ctx.renderMarkdown`). Hovering a card sets the active index;\n * `activeIndex` driven from outside lets a hovered code row light its card and\n * vice-versa. Only annotations whose `range` resolved are listed.\n *\n * @deprecated Superseded by the on-hover {@link AnnotationHoverCard}; kept for\n * back-compat with any external importer. Both block read renderers now use the\n * hover popover anchored to the right of the code instead of a persistent rail.\n */\nexport function AnnotationNoteRail<A extends RailAnnotation>({\n items,\n activeIndex,\n onActiveChange,\n ctx,\n className,\n showMarker = false,\n}: {\n items: ResolvedAnnotation<A>[];\n activeIndex: number | null;\n onActiveChange: (index: number | null) => void;\n ctx: BlockRenderContext;\n className?: string;\n /** Show a leading numbered pip on each card (diff block). */\n showMarker?: boolean;\n}) {\n const sideAnnotations = useMemo(\n () => items.filter((item) => item.range),\n [items],\n );\n return (\n <div className={cn(\"flex flex-col gap-2.5\", className)}>\n {sideAnnotations.map((item) => (\n <AnnotationCard\n key={item.index}\n item={item}\n ctx={ctx}\n active={activeIndex === item.index}\n showMarker={showMarker}\n onMouseEnter={() => onActiveChange(item.index)}\n onMouseLeave={() => onActiveChange(null)}\n />\n ))}\n </div>\n );\n}\n\n/** Whether a resolved list has at least one note worth rendering a rail for. */\nexport function hasRailAnnotations(items: ResolvedAnnotation[]): boolean {\n return items.some((item) => item.range);\n}\n\nexport type AnnotationRailChildren = ReactNode;\n"]}
@@ -1,5 +1,22 @@
1
1
  import type { BlockReadProps, BlockEditProps } from "../types.js";
2
2
  import { type DiagramData } from "./diagram.config.js";
3
+ /**
4
+ * Enlarge overlay for a rendered diagram. Mirrors the image lightbox contract
5
+ * used by the composer's `ImagePreviewLightbox` (PromptComposer.tsx) so the
6
+ * expand affordance feels identical to viewing an image full-size: a fixed
7
+ * `bg-black/80` backdrop, Escape to close, click-the-backdrop to close, and a
8
+ * top-right close button. Unlike the image variant this renders arbitrary
9
+ * children (the diagram body re-rendered larger) rather than an `<img>`, since a
10
+ * diagram is live HTML/SVG/node-graph markup, not an image URL.
11
+ *
12
+ * Exported so the separate Mermaid block (`MermaidBlock.tsx`, which renders its
13
+ * diagram to an SVG through a different runtime) can reuse the exact same
14
+ * lightbox contract — one expand affordance shared across both diagram types.
15
+ */
16
+ export declare function DiagramLightbox({ children, onClose, }: {
17
+ children: React.ReactNode;
18
+ onClose: () => void;
19
+ }): import("react/jsx-runtime").JSX.Element;
3
20
  /** Read-only renderer: the diagram body wrapped in the standard titled block. */
4
21
  export declare function DiagramRead({ data, blockId, title, summary, ctx, }: BlockReadProps<DiagramData>): import("react/jsx-runtime").JSX.Element;
5
22
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"diagram.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/diagram.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EAEf,MAAM,aAAa,CAAC;AAQrB,OAAO,EAGL,KAAK,WAAW,EAGjB,MAAM,qBAAqB,CAAC;AAkX7B,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,OAAO,EACP,KAAK,EACL,OAAO,EACP,GAAG,GACJ,EAAE,cAAc,CAAC,WAAW,CAAC,2CAQ7B;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,KAAK,EACL,OAAO,EACP,GAAG,GACJ,EAAE,cAAc,CAAC,WAAW,CAAC,2CAkL7B;AAED,kFAAkF;AAClF,eAAO,MAAM,YAAY,8CAgBvB,CAAC"}
1
+ {"version":3,"file":"diagram.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/diagram.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EAEf,MAAM,aAAa,CAAC;AAQrB,OAAO,EAGL,KAAK,WAAW,EAGjB,MAAM,qBAAqB,CAAC;AAoX7B;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,OAAO,GACR,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,2CAsCA;AA2CD,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,OAAO,EACP,KAAK,EACL,OAAO,EACP,GAAG,GACJ,EAAE,cAAc,CAAC,WAAW,CAAC,2CAQ7B;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,KAAK,EACL,OAAO,EACP,GAAG,GACJ,EAAE,cAAc,CAAC,WAAW,CAAC,2CAkL7B;AAED,kFAAkF;AAClF,eAAO,MAAM,YAAY,8CAgBvB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useId, useMemo, useRef, useState } from "react";
3
+ import { IconArrowsMaximize, IconX } from "@tabler/icons-react";
3
4
  import { cn } from "../../utils.js";
4
5
  import { defineBlock } from "../types.js";
5
6
  import { AiEditableFieldLabel } from "../AiEditableField.js";
@@ -147,7 +148,9 @@ function SequenceDiagram({ data, compact, }) {
147
148
  /**
148
149
  * The diagram body. Routes to the preferred HTML/SVG path (when `data.html` is
149
150
  * set) and otherwise to a legacy node-graph path (positioned canvas when nodes
150
- * carry x/y, else an ordered sequence).
151
+ * carry x/y, else an ordered sequence). Used both inline and, scaled up, inside
152
+ * the expand lightbox — so every variant (html/css, positioned, sequence)
153
+ * enlarges through the same code path.
151
154
  */
152
155
  function DiagramBody({ data, ctx, compact, }) {
153
156
  const markerId = useId().replace(/:/g, "");
@@ -160,11 +163,53 @@ function DiagramBody({ data, ctx, compact, }) {
160
163
  return _jsx(SequenceDiagram, { data: data, compact: compact });
161
164
  }
162
165
  /* -------------------------------------------------------------------------- */
166
+ /* Expand / lightbox */
167
+ /* -------------------------------------------------------------------------- */
168
+ /**
169
+ * Enlarge overlay for a rendered diagram. Mirrors the image lightbox contract
170
+ * used by the composer's `ImagePreviewLightbox` (PromptComposer.tsx) so the
171
+ * expand affordance feels identical to viewing an image full-size: a fixed
172
+ * `bg-black/80` backdrop, Escape to close, click-the-backdrop to close, and a
173
+ * top-right close button. Unlike the image variant this renders arbitrary
174
+ * children (the diagram body re-rendered larger) rather than an `<img>`, since a
175
+ * diagram is live HTML/SVG/node-graph markup, not an image URL.
176
+ *
177
+ * Exported so the separate Mermaid block (`MermaidBlock.tsx`, which renders its
178
+ * diagram to an SVG through a different runtime) can reuse the exact same
179
+ * lightbox contract — one expand affordance shared across both diagram types.
180
+ */
181
+ export function DiagramLightbox({ children, onClose, }) {
182
+ useEffect(() => {
183
+ const handler = (e) => {
184
+ if (e.key === "Escape")
185
+ onClose();
186
+ };
187
+ document.addEventListener("keydown", handler);
188
+ document.body.style.overflow = "hidden";
189
+ return () => {
190
+ document.removeEventListener("keydown", handler);
191
+ document.body.style.overflow = "";
192
+ };
193
+ }, [onClose]);
194
+ return (_jsxs("div", { role: "dialog", "aria-modal": "true", "aria-label": "Diagram preview", onClick: onClose, "data-plan-interactive": true, className: "fixed inset-0 z-[300] flex items-center justify-center overflow-auto bg-black/80 p-6 cursor-zoom-out", children: [_jsx("div", { onClick: (e) => e.stopPropagation(), className: "max-h-full w-full max-w-5xl cursor-default overflow-auto rounded-md bg-background p-6 shadow-2xl", children: children }), _jsx("button", { type: "button", onClick: onClose, "aria-label": "Close preview", className: "absolute right-4 top-4 flex h-8 w-8 cursor-pointer items-center justify-center rounded-full border border-white/30 bg-black/40 text-white hover:bg-black/60", children: _jsx(IconX, { className: "h-4 w-4" }) })] }));
195
+ }
196
+ /**
197
+ * The diagram body plus a hover-revealed top-right "expand" button (like the
198
+ * image attachment zoom). Opening the button re-renders the exact same
199
+ * `DiagramBody` inside `DiagramLightbox` at a larger size, so html/css and
200
+ * mermaid/legacy node-graph diagrams alike enlarge through one path. The inline
201
+ * (non-expanded) render is otherwise unchanged.
202
+ */
203
+ function ExpandableDiagramBody({ data, ctx, }) {
204
+ const [expanded, setExpanded] = useState(false);
205
+ return (_jsxs("div", { className: "group/diagram relative", children: [_jsx(DiagramBody, { data: data, ctx: ctx }), _jsx("button", { type: "button", "data-plan-interactive": true, onClick: () => setExpanded(true), "aria-label": "Expand diagram", title: "Expand diagram", className: "an-diagram-expand-trigger absolute right-2 top-2 z-10 flex size-7 items-center justify-center rounded-md border border-border/60 bg-background/90 text-muted-foreground opacity-0 shadow-sm backdrop-blur transition-[color,opacity] hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring group-hover/diagram:opacity-100", children: _jsx(IconArrowsMaximize, { className: "size-4" }) }), expanded ? (_jsx(DiagramLightbox, { onClose: () => setExpanded(false), children: _jsx(DiagramBody, { data: data, ctx: ctx }) })) : null] }));
206
+ }
207
+ /* -------------------------------------------------------------------------- */
163
208
  /* Read + Edit */
164
209
  /* -------------------------------------------------------------------------- */
165
210
  /** Read-only renderer: the diagram body wrapped in the standard titled block. */
166
211
  export function DiagramRead({ data, blockId, title, summary, ctx, }) {
167
- return (_jsxs("section", { className: "an-block plan-block", "data-block-id": blockId, children: [title && _jsx("div", { className: "an-block-label plan-block-label", children: title }), _jsx(DiagramBody, { data: data, ctx: ctx }), summary && _jsx("p", { className: "mt-5 text-muted-foreground", children: summary })] }));
212
+ return (_jsxs("section", { className: "an-block plan-block", "data-block-id": blockId, children: [title && _jsx("div", { className: "an-block-label plan-block-label", children: title }), _jsx(ExpandableDiagramBody, { data: data, ctx: ctx }), summary && _jsx("p", { className: "mt-5 text-muted-foreground", children: summary })] }));
168
213
  }
169
214
  /**
170
215
  * Edit form (panel surface). The block can be an HTML/SVG fragment or a legacy
@@ -1 +1 @@
1
- {"version":3,"file":"diagram.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/diagram.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useId, useMemo, useRef, useState } from \"react\";\nimport { cn } from \"../../utils.js\";\nimport { defineBlock } from \"../types.js\";\nimport type {\n BlockReadProps,\n BlockEditProps,\n BlockRenderContext,\n} from \"../types.js\";\nimport { AiEditableFieldLabel } from \"../AiEditableField.js\";\nimport { RoughOverlay, useIsDark, useWireframeStyle } from \"./wireframe-kit.js\";\nimport {\n sanitizeDiagramHtml,\n sanitizeWireframeCss,\n scopeDesignCss,\n} from \"./sanitize-html.js\";\nimport {\n diagramMdx,\n diagramSchema,\n type DiagramData,\n type DiagramEdge,\n type DiagramNode,\n} from \"./diagram.config.js\";\n\n/**\n * Read + Edit renderers for the shared `diagram` block — a flexible inline\n * architecture/code diagram. The preferred authoring path is a scoped, inert\n * HTML/SVG fragment that leans on `.diagram-*` primitives and `--wf-*` tokens;\n * a legacy positional / sequence node-graph path is kept for older/simple plans.\n * Lives in core so any app can register it (it originated in the plan template).\n *\n * DECOUPLING from the plan original (mirrors the sibling `wireframe.tsx` port):\n * - Theme: `useIsDark()` reads `document.documentElement.classList` instead of\n * `next-themes`; `useWireframeStyle()` reads the viewer's sketchy/clean\n * preference from the shared `plan-wireframe-style` localStorage key — both\n * from `./wireframe-kit.js`, so core stays plan-free and shadcn-free.\n * - HTML sanitize: the HTML/SVG fragment + CSS run through the app-injected\n * `ctx.sanitizeHtml` at the render point (defense-in-depth against stored\n * XSS). Without a sanitizer wired, the HTML path emits nothing — core never\n * injects unsanitized author HTML. The React-free `diagramSchema` already\n * rejects active markup before storage.\n * - The rough.js sketch overlay reuses the kit's shared `RoughOverlay`, scoped\n * with the diagram selector and `drawFrame={false}` (the same call the plan\n * `HtmlDiagram` made). The `.plan-diagram-frame` / `.diagram-*` / `data-rough`\n * class contract is preserved exactly so the theme-token CSS in core's\n * `blocks.css` styles it in any app.\n *\n * The section carries the app-neutral `an-block` class plus the legacy\n * `plan-block` class so plan renders byte-identically while any other app gets\n * the theme-token treatment.\n */\n\n/* -------------------------------------------------------------------------- */\n/* HTML/SVG diagram path */\n/* -------------------------------------------------------------------------- */\n\n/** The rough-overlay selector for diagram bordered boxes (mirrors the plan). */\nconst DIAGRAM_ROUGH_SELECTOR =\n \"[data-rough],.diagram-panel,.diagram-node,.diagram-box,.diagram-pill,.diagram-card,[class*='card'],[class*='box'],[class*='panel'],[class*='pill'],[class*='chip'],[class*='badge'],hr\";\n\nfunction HtmlDiagram({\n data,\n ctx,\n compact,\n}: {\n data: DiagramData;\n ctx: BlockRenderContext;\n compact?: boolean;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const isDark = useIsDark();\n const style = useWireframeStyle();\n const scopeId = useId().replace(/[^a-zA-Z0-9_-]/g, \"\");\n // Sanitize author HTML/CSS at the render point (defense-in-depth against\n // stored XSS). Self-contained in core via the shared block sanitizer (DOM-based\n // in the browser, regex fallback on the server) so diagrams render in any app\n // without the host wiring a sanitizer hook.\n const safeHtml = useMemo(() => sanitizeDiagramHtml(data.html), [data.html]);\n const scopedCss = useMemo(() => {\n const safeCss = sanitizeWireframeCss(data.css);\n // Scope every author selector under this diagram instance so global\n // selectors (body, *, .app-shell, :root) can't escape and restyle the page.\n return safeCss\n ? scopeDesignCss(safeCss, `[data-plan-diagram-scope=\"${scopeId}\"]`)\n : \"\";\n }, [data.css, scopeId]);\n\n return (\n <div\n ref={ref}\n className={cn(\"plan-diagram-shell\", compact && \"plan-diagram-compact\")}\n >\n <div\n className=\"plan-diagram-frame\"\n data-theme={isDark ? \"dark\" : \"light\"}\n data-style={style}\n data-plan-diagram-scope={scopeId}\n >\n {scopedCss && <style>{scopedCss}</style>}\n <div\n className=\"plan-diagram-frame-content\"\n dangerouslySetInnerHTML={{ __html: safeHtml }}\n />\n </div>\n <RoughOverlay\n scopeRef={ref}\n enabled={style === \"sketchy\"}\n drawFrame={false}\n selector={DIAGRAM_ROUGH_SELECTOR}\n />\n {data.caption && !compact && (\n <p className=\"mt-3 text-sm leading-6 text-muted-foreground\">\n {data.caption}\n </p>\n )}\n </div>\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Legacy node-graph paths */\n/* -------------------------------------------------------------------------- */\n\nfunction clampDiagramPercent(value: number) {\n if (!Number.isFinite(value)) return 50;\n return Math.max(4, Math.min(96, value));\n}\n\nfunction hasPositionedDiagramNodes(data: DiagramData): boolean {\n return (data.nodes ?? []).some(\n (node) => typeof node.x === \"number\" && typeof node.y === \"number\",\n );\n}\n\nfunction orderDiagramNodes(\n nodes: DiagramNode[],\n edges: DiagramEdge[],\n): DiagramNode[] {\n if (nodes.length === 0) return [];\n const byId = new Map(nodes.map((node) => [node.id, node]));\n const indegree = new Map(nodes.map((node) => [node.id, 0]));\n for (const edge of edges) {\n if (byId.has(edge.from) && byId.has(edge.to)) {\n indegree.set(edge.to, (indegree.get(edge.to) ?? 0) + 1);\n }\n }\n const start = nodes.find((node) => (indegree.get(node.id) ?? 0) === 0);\n if (!start) return nodes;\n const ordered: DiagramNode[] = [];\n const seen = new Set<string>();\n let current: DiagramNode | undefined = start;\n while (current && !seen.has(current.id)) {\n const node: DiagramNode = current;\n ordered.push(node);\n seen.add(node.id);\n const next = edges.find((edge) => edge.from === node.id);\n current = next ? byId.get(next.to) : undefined;\n }\n for (const node of nodes) if (!seen.has(node.id)) ordered.push(node);\n return ordered;\n}\n\nfunction PositionedDiagram({\n data,\n compact,\n markerId,\n}: {\n data: DiagramData;\n compact?: boolean;\n markerId: string;\n}) {\n const nodes = (data.nodes ?? []).map((node) => ({\n ...node,\n x: clampDiagramPercent(node.x ?? 50),\n y: clampDiagramPercent(node.y ?? 50),\n }));\n const edges = data.edges ?? [];\n const nodeById = new Map(nodes.map((node) => [node.id, node]));\n const arrowId = `${markerId}-diagram-arrow`;\n const nodeWidth = compact ? 150 : 190;\n const canvasHeight = compact ? 280 : 430;\n\n return (\n <div className=\"plan-sketch rounded-[16px] border border-border bg-muted p-5\">\n <div\n className=\"relative overflow-hidden rounded-xl border border-border bg-background\"\n style={{ minHeight: canvasHeight }}\n >\n <svg\n className=\"pointer-events-none absolute inset-0 z-0 h-full w-full\"\n viewBox=\"0 0 100 100\"\n preserveAspectRatio=\"none\"\n aria-hidden=\"true\"\n >\n <defs>\n <marker\n id={arrowId}\n viewBox=\"0 0 10 10\"\n refX=\"8\"\n refY=\"5\"\n markerWidth=\"5\"\n markerHeight=\"5\"\n orient=\"auto-start-reverse\"\n >\n <path\n d=\"M 0 0 L 10 5 L 0 10 z\"\n className=\"fill-muted-foreground\"\n />\n </marker>\n </defs>\n {edges.map((edge, index) => {\n const from = nodeById.get(edge.from);\n const to = nodeById.get(edge.to);\n if (!from || !to) return null;\n return (\n <line\n key={`${edge.from}-${edge.to}-${index}`}\n x1={from.x}\n y1={from.y}\n x2={to.x}\n y2={to.y}\n markerEnd={`url(#${arrowId})`}\n vectorEffect=\"non-scaling-stroke\"\n className=\"stroke-border\"\n strokeWidth={2}\n strokeDasharray={edge.label ? \"0\" : \"6 5\"}\n />\n );\n })}\n </svg>\n\n {!compact &&\n edges.map((edge, index) => {\n const from = nodeById.get(edge.from);\n const to = nodeById.get(edge.to);\n if (!edge.label || !from || !to) return null;\n return (\n <span\n key={`${edge.from}-${edge.to}-${index}-label`}\n className=\"absolute z-10 max-w-[130px] -translate-x-1/2 -translate-y-1/2 rounded-full border border-border bg-background px-2 py-0.5 text-center text-[11px] font-semibold text-muted-foreground shadow-sm\"\n style={{\n left: `${(from.x + to.x) / 2}%`,\n top: `${(from.y + to.y) / 2}%`,\n }}\n >\n {edge.label}\n </span>\n );\n })}\n\n {nodes.map((node, index) => (\n <article\n key={node.id}\n className=\"absolute z-20 -translate-x-1/2 -translate-y-1/2 rounded-xl border-2 border-border bg-background p-3 text-foreground shadow-sm\"\n style={{\n left: `${node.x}%`,\n top: `${node.y}%`,\n width: nodeWidth,\n }}\n >\n <p className=\"text-[11px] font-semibold uppercase tracking-[0.12em] text-muted-foreground\">\n {index + 1}\n </p>\n <h3 className=\"mt-2 text-base font-semibold leading-tight\">\n {node.label}\n </h3>\n {node.detail && !compact && (\n <p className=\"mt-2 text-xs leading-5 text-muted-foreground\">\n {node.detail}\n </p>\n )}\n </article>\n ))}\n </div>\n {data.notes && data.notes.length > 0 && !compact && (\n <div className=\"mt-4 grid gap-2 border-t border-border pt-4 text-sm text-muted-foreground md:grid-cols-2\">\n {data.notes.map((note) => (\n <p key={note.id}>{note.text}</p>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction SequenceDiagram({\n data,\n compact,\n}: {\n data: DiagramData;\n compact?: boolean;\n}) {\n const edges = data.edges ?? [];\n const nodes = orderDiagramNodes(data.nodes ?? [], edges);\n if (nodes.length === 0) {\n return (\n <div className=\"rounded-[12px] border border-border bg-muted p-4 text-sm text-muted-foreground\">\n Diagram content is empty.\n </div>\n );\n }\n return (\n <div className=\"plan-sketch rounded-[16px] border border-border bg-muted p-5\">\n <div\n className={cn(\n \"flex gap-3 overflow-x-auto pb-2\",\n compact ? \"items-center\" : \"items-stretch\",\n )}\n >\n {nodes.map((node, index) => {\n const next = nodes[index + 1];\n const edge = next\n ? edges.find(\n (candidate) =>\n candidate.from === node.id && candidate.to === next.id,\n )\n : undefined;\n return (\n <div key={node.id} className=\"flex min-w-max items-center gap-3\">\n <article\n className={cn(\n \"w-[180px] rounded-xl border-2 border-border bg-background p-3 text-foreground\",\n compact && \"w-[150px]\",\n )}\n >\n <p className=\"text-[11px] font-semibold uppercase tracking-[0.12em] text-muted-foreground\">\n {index + 1}\n </p>\n <h3 className=\"mt-2 text-base font-semibold leading-tight\">\n {node.label}\n </h3>\n {node.detail && !compact && (\n <p className=\"mt-2 text-xs leading-5 text-muted-foreground\">\n {node.detail}\n </p>\n )}\n </article>\n {next && (\n <div className=\"grid min-w-[72px] justify-items-center gap-1 text-muted-foreground\">\n {edge?.label && (\n <span className=\"max-w-[96px] truncate rounded-full border border-border px-2 py-0.5 text-[11px] font-semibold\">\n {edge.label}\n </span>\n )}\n <span className=\"h-0.5 w-full rounded-full border-t-2 border-dashed border-border\" />\n </div>\n )}\n </div>\n );\n })}\n </div>\n {data.notes && data.notes.length > 0 && !compact && (\n <div className=\"mt-4 grid gap-2 border-t border-border pt-4 text-sm text-muted-foreground md:grid-cols-2\">\n {data.notes.map((note) => (\n <p key={note.id}>{note.text}</p>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/**\n * The diagram body. Routes to the preferred HTML/SVG path (when `data.html` is\n * set) and otherwise to a legacy node-graph path (positioned canvas when nodes\n * carry x/y, else an ordered sequence).\n */\nfunction DiagramBody({\n data,\n ctx,\n compact,\n}: {\n data: DiagramData;\n ctx: BlockRenderContext;\n compact?: boolean;\n}) {\n const markerId = useId().replace(/:/g, \"\");\n if (data.html?.trim()) {\n return <HtmlDiagram data={data} ctx={ctx} compact={compact} />;\n }\n if (hasPositionedDiagramNodes(data)) {\n return (\n <PositionedDiagram data={data} compact={compact} markerId={markerId} />\n );\n }\n return <SequenceDiagram data={data} compact={compact} />;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Read + Edit */\n/* -------------------------------------------------------------------------- */\n\n/** Read-only renderer: the diagram body wrapped in the standard titled block. */\nexport function DiagramRead({\n data,\n blockId,\n title,\n summary,\n ctx,\n}: BlockReadProps<DiagramData>) {\n return (\n <section className=\"an-block plan-block\" data-block-id={blockId}>\n {title && <div className=\"an-block-label plan-block-label\">{title}</div>}\n <DiagramBody data={data} ctx={ctx} />\n {summary && <p className=\"mt-5 text-muted-foreground\">{summary}</p>}\n </section>\n );\n}\n\n/**\n * Edit form (panel surface). The block can be an HTML/SVG fragment or a legacy\n * node/edge/note graph, so this exposes html/css/caption plus a collapsible\n * legacy node-graph JSON editor, each with an AI-edit affordance via\n * `ctx.renderAiFieldAction` (through `AiEditableFieldLabel`). `editSurface:\n * \"panel\"` means the registry renders the `Read` view with a corner edit button\n * that opens this form in the app-provided popover.\n */\nexport function DiagramEdit({\n data,\n onChange,\n editable,\n blockId,\n title,\n summary,\n ctx,\n}: BlockEditProps<DiagramData>) {\n const htmlId = useId();\n const cssId = useId();\n const captionId = useId();\n const legacyId = useId();\n const [html, setHtml] = useState(data.html ?? \"\");\n const [css, setCss] = useState(data.css ?? \"\");\n const [caption, setCaption] = useState(data.caption ?? \"\");\n const [legacyJson, setLegacyJson] = useState(() =>\n JSON.stringify(\n {\n nodes: data.nodes ?? [],\n edges: data.edges ?? [],\n notes: data.notes ?? [],\n },\n null,\n 2,\n ),\n );\n\n useEffect(() => {\n setHtml(data.html ?? \"\");\n setCss(data.css ?? \"\");\n setCaption(data.caption ?? \"\");\n setLegacyJson(\n JSON.stringify(\n {\n nodes: data.nodes ?? [],\n edges: data.edges ?? [],\n notes: data.notes ?? [],\n },\n null,\n 2,\n ),\n );\n }, [data]);\n\n const saveHtmlDiagram = () => {\n onChange({\n html: html.trim() || undefined,\n css: css.trim() || undefined,\n caption: caption.trim() || undefined,\n nodes: data.nodes,\n edges: data.edges,\n notes: data.notes,\n });\n };\n\n const saveLegacyDiagram = () => {\n const parsed = JSON.parse(legacyJson) as Pick<\n DiagramData,\n \"nodes\" | \"edges\" | \"notes\"\n >;\n onChange({\n ...data,\n nodes: parsed.nodes ?? [],\n edges: parsed.edges ?? [],\n notes: parsed.notes ?? [],\n });\n };\n\n const fieldAction = (\n field: \"HTML / SVG fragment\" | \"CSS\" | \"caption\" | \"legacy node graph JSON\",\n value: string,\n ) => ({\n blockId,\n blockType: \"diagram\",\n blockTitle: title,\n blockSummary: summary,\n fieldValue: value,\n draftScope: `block:diagram:${blockId}:${field.toLowerCase().replace(/[^a-z0-9]+/g, \"-\")}`,\n disabled: !editable,\n instructions:\n \"Update the plan with update-visual-plan using a targeted update-block content patch for this diagram block id. Preserve unrelated diagram fields unless the requested edit requires changing them. Keep diagram HTML/CSS on renderer-owned .diagram-* primitives and --wf-* tokens; do not introduce custom font-family or hard-coded hex/rgb/hsl colors.\",\n companionFields: [\n {\n label: \"HTML / SVG fragment\",\n value: html.trim() || \"(empty)\",\n language: \"html\",\n },\n { label: \"CSS\", value: css.trim() || \"(empty)\", language: \"css\" },\n {\n label: \"caption\",\n value: caption.trim() || \"(empty)\",\n language: \"text\",\n },\n ],\n });\n\n return (\n <div className=\"grid gap-4\" data-plan-interactive>\n <button\n type=\"button\"\n className=\"inline-flex h-8 w-fit items-center justify-center rounded-md bg-primary px-3 text-xs font-medium text-primary-foreground disabled:opacity-50\"\n disabled={!editable}\n onClick={saveHtmlDiagram}\n >\n Save diagram\n </button>\n <div className=\"group/field grid gap-1.5\">\n <AiEditableFieldLabel\n htmlFor={htmlId}\n label=\"HTML / SVG fragment\"\n ctx={ctx}\n action={fieldAction(\"HTML / SVG fragment\", html)}\n />\n <textarea\n id={htmlId}\n className=\"min-h-48 w-full rounded-md border border-input bg-background px-3 py-2 font-mono text-xs leading-5 text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n value={html}\n disabled={!editable}\n onChange={(event) => setHtml(event.target.value)}\n placeholder=\"<div class='diagram'>...</div>\"\n />\n </div>\n <div className=\"group/field grid gap-1.5\">\n <AiEditableFieldLabel\n htmlFor={cssId}\n label=\"CSS\"\n ctx={ctx}\n action={fieldAction(\"CSS\", css)}\n />\n <textarea\n id={cssId}\n className=\"min-h-32 w-full rounded-md border border-input bg-background px-3 py-2 font-mono text-xs leading-5 text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n value={css}\n disabled={!editable}\n onChange={(event) => setCss(event.target.value)}\n placeholder=\".diagram { display: grid; }\"\n />\n </div>\n <div className=\"group/field grid gap-1.5\">\n <AiEditableFieldLabel\n htmlFor={captionId}\n label=\"Caption\"\n ctx={ctx}\n action={fieldAction(\"caption\", caption)}\n />\n <input\n id={captionId}\n className=\"h-9 w-full rounded-md border border-input bg-background px-3 text-sm text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n value={caption}\n disabled={!editable}\n onChange={(event) => setCaption(event.target.value)}\n />\n </div>\n {!data.html && (\n <details className=\"rounded-md border border-border p-3\">\n <summary className=\"cursor-pointer text-xs font-semibold text-muted-foreground\">\n Legacy node graph data\n </summary>\n <div className=\"group/field mt-3 grid gap-1.5\">\n <AiEditableFieldLabel\n htmlFor={legacyId}\n label=\"JSON\"\n ctx={ctx}\n action={fieldAction(\"legacy node graph JSON\", legacyJson)}\n />\n <textarea\n id={legacyId}\n className=\"min-h-44 w-full rounded-md border border-input bg-background px-3 py-2 font-mono text-xs leading-5 text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n value={legacyJson}\n disabled={!editable}\n onChange={(event) => setLegacyJson(event.target.value)}\n />\n </div>\n <button\n type=\"button\"\n className=\"mt-3 inline-flex h-8 items-center justify-center rounded-md border border-input px-3 text-xs font-medium text-foreground disabled:opacity-50\"\n disabled={!editable}\n onClick={saveLegacyDiagram}\n >\n Save graph data\n </button>\n </details>\n )}\n </div>\n );\n}\n\n/** Full client spec for the shared `diagram` block (schema + MDX + Read/Edit). */\nexport const diagramBlock = defineBlock<DiagramData>({\n type: \"diagram\",\n schema: diagramSchema,\n mdx: diagramMdx,\n Read: DiagramRead,\n Edit: DiagramEdit,\n placement: [\"block\"],\n // Config-driven: the rendered diagram differs from its raw html/css source, so\n // edit from a corner button + panel rather than inline.\n editSurface: \"panel\",\n label: \"Diagram\",\n description:\n \"A flexible inline architecture/code diagram. Prefer html/css with SVG or semantic HTML for polished two-dimensional layouts; use .diagram-* primitives and --wf-* tokens for theme/sketch compatibility. Legacy nodes/edges are only for simple previews.\",\n // Seed the legacy fallback shape so a fresh block validates while agents can\n // replace it with html/css when layout quality matters.\n empty: () => ({ nodes: [{ id: \"n1\", label: \"Module\" }], edges: [] }),\n});\n"]}
1
+ {"version":3,"file":"diagram.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/diagram.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useId, useMemo, useRef, useState } from \"react\";\nimport { IconArrowsMaximize, IconX } from \"@tabler/icons-react\";\nimport { cn } from \"../../utils.js\";\nimport { defineBlock } from \"../types.js\";\nimport type {\n BlockReadProps,\n BlockEditProps,\n BlockRenderContext,\n} from \"../types.js\";\nimport { AiEditableFieldLabel } from \"../AiEditableField.js\";\nimport { RoughOverlay, useIsDark, useWireframeStyle } from \"./wireframe-kit.js\";\nimport {\n sanitizeDiagramHtml,\n sanitizeWireframeCss,\n scopeDesignCss,\n} from \"./sanitize-html.js\";\nimport {\n diagramMdx,\n diagramSchema,\n type DiagramData,\n type DiagramEdge,\n type DiagramNode,\n} from \"./diagram.config.js\";\n\n/**\n * Read + Edit renderers for the shared `diagram` block — a flexible inline\n * architecture/code diagram. The preferred authoring path is a scoped, inert\n * HTML/SVG fragment that leans on `.diagram-*` primitives and `--wf-*` tokens;\n * a legacy positional / sequence node-graph path is kept for older/simple plans.\n * Lives in core so any app can register it (it originated in the plan template).\n *\n * DECOUPLING from the plan original (mirrors the sibling `wireframe.tsx` port):\n * - Theme: `useIsDark()` reads `document.documentElement.classList` instead of\n * `next-themes`; `useWireframeStyle()` reads the viewer's sketchy/clean\n * preference from the shared `plan-wireframe-style` localStorage key — both\n * from `./wireframe-kit.js`, so core stays plan-free and shadcn-free.\n * - HTML sanitize: the HTML/SVG fragment + CSS run through the app-injected\n * `ctx.sanitizeHtml` at the render point (defense-in-depth against stored\n * XSS). Without a sanitizer wired, the HTML path emits nothing — core never\n * injects unsanitized author HTML. The React-free `diagramSchema` already\n * rejects active markup before storage.\n * - The rough.js sketch overlay reuses the kit's shared `RoughOverlay`, scoped\n * with the diagram selector and `drawFrame={false}` (the same call the plan\n * `HtmlDiagram` made). The `.plan-diagram-frame` / `.diagram-*` / `data-rough`\n * class contract is preserved exactly so the theme-token CSS in core's\n * `blocks.css` styles it in any app.\n *\n * The section carries the app-neutral `an-block` class plus the legacy\n * `plan-block` class so plan renders byte-identically while any other app gets\n * the theme-token treatment.\n */\n\n/* -------------------------------------------------------------------------- */\n/* HTML/SVG diagram path */\n/* -------------------------------------------------------------------------- */\n\n/** The rough-overlay selector for diagram bordered boxes (mirrors the plan). */\nconst DIAGRAM_ROUGH_SELECTOR =\n \"[data-rough],.diagram-panel,.diagram-node,.diagram-box,.diagram-pill,.diagram-card,[class*='card'],[class*='box'],[class*='panel'],[class*='pill'],[class*='chip'],[class*='badge'],hr\";\n\nfunction HtmlDiagram({\n data,\n ctx,\n compact,\n}: {\n data: DiagramData;\n ctx: BlockRenderContext;\n compact?: boolean;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const isDark = useIsDark();\n const style = useWireframeStyle();\n const scopeId = useId().replace(/[^a-zA-Z0-9_-]/g, \"\");\n // Sanitize author HTML/CSS at the render point (defense-in-depth against\n // stored XSS). Self-contained in core via the shared block sanitizer (DOM-based\n // in the browser, regex fallback on the server) so diagrams render in any app\n // without the host wiring a sanitizer hook.\n const safeHtml = useMemo(() => sanitizeDiagramHtml(data.html), [data.html]);\n const scopedCss = useMemo(() => {\n const safeCss = sanitizeWireframeCss(data.css);\n // Scope every author selector under this diagram instance so global\n // selectors (body, *, .app-shell, :root) can't escape and restyle the page.\n return safeCss\n ? scopeDesignCss(safeCss, `[data-plan-diagram-scope=\"${scopeId}\"]`)\n : \"\";\n }, [data.css, scopeId]);\n\n return (\n <div\n ref={ref}\n className={cn(\"plan-diagram-shell\", compact && \"plan-diagram-compact\")}\n >\n <div\n className=\"plan-diagram-frame\"\n data-theme={isDark ? \"dark\" : \"light\"}\n data-style={style}\n data-plan-diagram-scope={scopeId}\n >\n {scopedCss && <style>{scopedCss}</style>}\n <div\n className=\"plan-diagram-frame-content\"\n dangerouslySetInnerHTML={{ __html: safeHtml }}\n />\n </div>\n <RoughOverlay\n scopeRef={ref}\n enabled={style === \"sketchy\"}\n drawFrame={false}\n selector={DIAGRAM_ROUGH_SELECTOR}\n />\n {data.caption && !compact && (\n <p className=\"mt-3 text-sm leading-6 text-muted-foreground\">\n {data.caption}\n </p>\n )}\n </div>\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Legacy node-graph paths */\n/* -------------------------------------------------------------------------- */\n\nfunction clampDiagramPercent(value: number) {\n if (!Number.isFinite(value)) return 50;\n return Math.max(4, Math.min(96, value));\n}\n\nfunction hasPositionedDiagramNodes(data: DiagramData): boolean {\n return (data.nodes ?? []).some(\n (node) => typeof node.x === \"number\" && typeof node.y === \"number\",\n );\n}\n\nfunction orderDiagramNodes(\n nodes: DiagramNode[],\n edges: DiagramEdge[],\n): DiagramNode[] {\n if (nodes.length === 0) return [];\n const byId = new Map(nodes.map((node) => [node.id, node]));\n const indegree = new Map(nodes.map((node) => [node.id, 0]));\n for (const edge of edges) {\n if (byId.has(edge.from) && byId.has(edge.to)) {\n indegree.set(edge.to, (indegree.get(edge.to) ?? 0) + 1);\n }\n }\n const start = nodes.find((node) => (indegree.get(node.id) ?? 0) === 0);\n if (!start) return nodes;\n const ordered: DiagramNode[] = [];\n const seen = new Set<string>();\n let current: DiagramNode | undefined = start;\n while (current && !seen.has(current.id)) {\n const node: DiagramNode = current;\n ordered.push(node);\n seen.add(node.id);\n const next = edges.find((edge) => edge.from === node.id);\n current = next ? byId.get(next.to) : undefined;\n }\n for (const node of nodes) if (!seen.has(node.id)) ordered.push(node);\n return ordered;\n}\n\nfunction PositionedDiagram({\n data,\n compact,\n markerId,\n}: {\n data: DiagramData;\n compact?: boolean;\n markerId: string;\n}) {\n const nodes = (data.nodes ?? []).map((node) => ({\n ...node,\n x: clampDiagramPercent(node.x ?? 50),\n y: clampDiagramPercent(node.y ?? 50),\n }));\n const edges = data.edges ?? [];\n const nodeById = new Map(nodes.map((node) => [node.id, node]));\n const arrowId = `${markerId}-diagram-arrow`;\n const nodeWidth = compact ? 150 : 190;\n const canvasHeight = compact ? 280 : 430;\n\n return (\n <div className=\"plan-sketch rounded-[16px] border border-border bg-muted p-5\">\n <div\n className=\"relative overflow-hidden rounded-xl border border-border bg-background\"\n style={{ minHeight: canvasHeight }}\n >\n <svg\n className=\"pointer-events-none absolute inset-0 z-0 h-full w-full\"\n viewBox=\"0 0 100 100\"\n preserveAspectRatio=\"none\"\n aria-hidden=\"true\"\n >\n <defs>\n <marker\n id={arrowId}\n viewBox=\"0 0 10 10\"\n refX=\"8\"\n refY=\"5\"\n markerWidth=\"5\"\n markerHeight=\"5\"\n orient=\"auto-start-reverse\"\n >\n <path\n d=\"M 0 0 L 10 5 L 0 10 z\"\n className=\"fill-muted-foreground\"\n />\n </marker>\n </defs>\n {edges.map((edge, index) => {\n const from = nodeById.get(edge.from);\n const to = nodeById.get(edge.to);\n if (!from || !to) return null;\n return (\n <line\n key={`${edge.from}-${edge.to}-${index}`}\n x1={from.x}\n y1={from.y}\n x2={to.x}\n y2={to.y}\n markerEnd={`url(#${arrowId})`}\n vectorEffect=\"non-scaling-stroke\"\n className=\"stroke-border\"\n strokeWidth={2}\n strokeDasharray={edge.label ? \"0\" : \"6 5\"}\n />\n );\n })}\n </svg>\n\n {!compact &&\n edges.map((edge, index) => {\n const from = nodeById.get(edge.from);\n const to = nodeById.get(edge.to);\n if (!edge.label || !from || !to) return null;\n return (\n <span\n key={`${edge.from}-${edge.to}-${index}-label`}\n className=\"absolute z-10 max-w-[130px] -translate-x-1/2 -translate-y-1/2 rounded-full border border-border bg-background px-2 py-0.5 text-center text-[11px] font-semibold text-muted-foreground shadow-sm\"\n style={{\n left: `${(from.x + to.x) / 2}%`,\n top: `${(from.y + to.y) / 2}%`,\n }}\n >\n {edge.label}\n </span>\n );\n })}\n\n {nodes.map((node, index) => (\n <article\n key={node.id}\n className=\"absolute z-20 -translate-x-1/2 -translate-y-1/2 rounded-xl border-2 border-border bg-background p-3 text-foreground shadow-sm\"\n style={{\n left: `${node.x}%`,\n top: `${node.y}%`,\n width: nodeWidth,\n }}\n >\n <p className=\"text-[11px] font-semibold uppercase tracking-[0.12em] text-muted-foreground\">\n {index + 1}\n </p>\n <h3 className=\"mt-2 text-base font-semibold leading-tight\">\n {node.label}\n </h3>\n {node.detail && !compact && (\n <p className=\"mt-2 text-xs leading-5 text-muted-foreground\">\n {node.detail}\n </p>\n )}\n </article>\n ))}\n </div>\n {data.notes && data.notes.length > 0 && !compact && (\n <div className=\"mt-4 grid gap-2 border-t border-border pt-4 text-sm text-muted-foreground md:grid-cols-2\">\n {data.notes.map((note) => (\n <p key={note.id}>{note.text}</p>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction SequenceDiagram({\n data,\n compact,\n}: {\n data: DiagramData;\n compact?: boolean;\n}) {\n const edges = data.edges ?? [];\n const nodes = orderDiagramNodes(data.nodes ?? [], edges);\n if (nodes.length === 0) {\n return (\n <div className=\"rounded-[12px] border border-border bg-muted p-4 text-sm text-muted-foreground\">\n Diagram content is empty.\n </div>\n );\n }\n return (\n <div className=\"plan-sketch rounded-[16px] border border-border bg-muted p-5\">\n <div\n className={cn(\n \"flex gap-3 overflow-x-auto pb-2\",\n compact ? \"items-center\" : \"items-stretch\",\n )}\n >\n {nodes.map((node, index) => {\n const next = nodes[index + 1];\n const edge = next\n ? edges.find(\n (candidate) =>\n candidate.from === node.id && candidate.to === next.id,\n )\n : undefined;\n return (\n <div key={node.id} className=\"flex min-w-max items-center gap-3\">\n <article\n className={cn(\n \"w-[180px] rounded-xl border-2 border-border bg-background p-3 text-foreground\",\n compact && \"w-[150px]\",\n )}\n >\n <p className=\"text-[11px] font-semibold uppercase tracking-[0.12em] text-muted-foreground\">\n {index + 1}\n </p>\n <h3 className=\"mt-2 text-base font-semibold leading-tight\">\n {node.label}\n </h3>\n {node.detail && !compact && (\n <p className=\"mt-2 text-xs leading-5 text-muted-foreground\">\n {node.detail}\n </p>\n )}\n </article>\n {next && (\n <div className=\"grid min-w-[72px] justify-items-center gap-1 text-muted-foreground\">\n {edge?.label && (\n <span className=\"max-w-[96px] truncate rounded-full border border-border px-2 py-0.5 text-[11px] font-semibold\">\n {edge.label}\n </span>\n )}\n <span className=\"h-0.5 w-full rounded-full border-t-2 border-dashed border-border\" />\n </div>\n )}\n </div>\n );\n })}\n </div>\n {data.notes && data.notes.length > 0 && !compact && (\n <div className=\"mt-4 grid gap-2 border-t border-border pt-4 text-sm text-muted-foreground md:grid-cols-2\">\n {data.notes.map((note) => (\n <p key={note.id}>{note.text}</p>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/**\n * The diagram body. Routes to the preferred HTML/SVG path (when `data.html` is\n * set) and otherwise to a legacy node-graph path (positioned canvas when nodes\n * carry x/y, else an ordered sequence). Used both inline and, scaled up, inside\n * the expand lightbox — so every variant (html/css, positioned, sequence)\n * enlarges through the same code path.\n */\nfunction DiagramBody({\n data,\n ctx,\n compact,\n}: {\n data: DiagramData;\n ctx: BlockRenderContext;\n compact?: boolean;\n}) {\n const markerId = useId().replace(/:/g, \"\");\n if (data.html?.trim()) {\n return <HtmlDiagram data={data} ctx={ctx} compact={compact} />;\n }\n if (hasPositionedDiagramNodes(data)) {\n return (\n <PositionedDiagram data={data} compact={compact} markerId={markerId} />\n );\n }\n return <SequenceDiagram data={data} compact={compact} />;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Expand / lightbox */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Enlarge overlay for a rendered diagram. Mirrors the image lightbox contract\n * used by the composer's `ImagePreviewLightbox` (PromptComposer.tsx) so the\n * expand affordance feels identical to viewing an image full-size: a fixed\n * `bg-black/80` backdrop, Escape to close, click-the-backdrop to close, and a\n * top-right close button. Unlike the image variant this renders arbitrary\n * children (the diagram body re-rendered larger) rather than an `<img>`, since a\n * diagram is live HTML/SVG/node-graph markup, not an image URL.\n *\n * Exported so the separate Mermaid block (`MermaidBlock.tsx`, which renders its\n * diagram to an SVG through a different runtime) can reuse the exact same\n * lightbox contract — one expand affordance shared across both diagram types.\n */\nexport function DiagramLightbox({\n children,\n onClose,\n}: {\n children: React.ReactNode;\n onClose: () => void;\n}) {\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n document.addEventListener(\"keydown\", handler);\n document.body.style.overflow = \"hidden\";\n return () => {\n document.removeEventListener(\"keydown\", handler);\n document.body.style.overflow = \"\";\n };\n }, [onClose]);\n\n return (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Diagram preview\"\n onClick={onClose}\n data-plan-interactive\n className=\"fixed inset-0 z-[300] flex items-center justify-center overflow-auto bg-black/80 p-6 cursor-zoom-out\"\n >\n <div\n onClick={(e) => e.stopPropagation()}\n className=\"max-h-full w-full max-w-5xl cursor-default overflow-auto rounded-md bg-background p-6 shadow-2xl\"\n >\n {children}\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"Close preview\"\n className=\"absolute right-4 top-4 flex h-8 w-8 cursor-pointer items-center justify-center rounded-full border border-white/30 bg-black/40 text-white hover:bg-black/60\"\n >\n <IconX className=\"h-4 w-4\" />\n </button>\n </div>\n );\n}\n\n/**\n * The diagram body plus a hover-revealed top-right \"expand\" button (like the\n * image attachment zoom). Opening the button re-renders the exact same\n * `DiagramBody` inside `DiagramLightbox` at a larger size, so html/css and\n * mermaid/legacy node-graph diagrams alike enlarge through one path. The inline\n * (non-expanded) render is otherwise unchanged.\n */\nfunction ExpandableDiagramBody({\n data,\n ctx,\n}: {\n data: DiagramData;\n ctx: BlockRenderContext;\n}) {\n const [expanded, setExpanded] = useState(false);\n return (\n <div className=\"group/diagram relative\">\n <DiagramBody data={data} ctx={ctx} />\n <button\n type=\"button\"\n data-plan-interactive\n onClick={() => setExpanded(true)}\n aria-label=\"Expand diagram\"\n title=\"Expand diagram\"\n className=\"an-diagram-expand-trigger absolute right-2 top-2 z-10 flex size-7 items-center justify-center rounded-md border border-border/60 bg-background/90 text-muted-foreground opacity-0 shadow-sm backdrop-blur transition-[color,opacity] hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring group-hover/diagram:opacity-100\"\n >\n <IconArrowsMaximize className=\"size-4\" />\n </button>\n {expanded ? (\n <DiagramLightbox onClose={() => setExpanded(false)}>\n <DiagramBody data={data} ctx={ctx} />\n </DiagramLightbox>\n ) : null}\n </div>\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Read + Edit */\n/* -------------------------------------------------------------------------- */\n\n/** Read-only renderer: the diagram body wrapped in the standard titled block. */\nexport function DiagramRead({\n data,\n blockId,\n title,\n summary,\n ctx,\n}: BlockReadProps<DiagramData>) {\n return (\n <section className=\"an-block plan-block\" data-block-id={blockId}>\n {title && <div className=\"an-block-label plan-block-label\">{title}</div>}\n <ExpandableDiagramBody data={data} ctx={ctx} />\n {summary && <p className=\"mt-5 text-muted-foreground\">{summary}</p>}\n </section>\n );\n}\n\n/**\n * Edit form (panel surface). The block can be an HTML/SVG fragment or a legacy\n * node/edge/note graph, so this exposes html/css/caption plus a collapsible\n * legacy node-graph JSON editor, each with an AI-edit affordance via\n * `ctx.renderAiFieldAction` (through `AiEditableFieldLabel`). `editSurface:\n * \"panel\"` means the registry renders the `Read` view with a corner edit button\n * that opens this form in the app-provided popover.\n */\nexport function DiagramEdit({\n data,\n onChange,\n editable,\n blockId,\n title,\n summary,\n ctx,\n}: BlockEditProps<DiagramData>) {\n const htmlId = useId();\n const cssId = useId();\n const captionId = useId();\n const legacyId = useId();\n const [html, setHtml] = useState(data.html ?? \"\");\n const [css, setCss] = useState(data.css ?? \"\");\n const [caption, setCaption] = useState(data.caption ?? \"\");\n const [legacyJson, setLegacyJson] = useState(() =>\n JSON.stringify(\n {\n nodes: data.nodes ?? [],\n edges: data.edges ?? [],\n notes: data.notes ?? [],\n },\n null,\n 2,\n ),\n );\n\n useEffect(() => {\n setHtml(data.html ?? \"\");\n setCss(data.css ?? \"\");\n setCaption(data.caption ?? \"\");\n setLegacyJson(\n JSON.stringify(\n {\n nodes: data.nodes ?? [],\n edges: data.edges ?? [],\n notes: data.notes ?? [],\n },\n null,\n 2,\n ),\n );\n }, [data]);\n\n const saveHtmlDiagram = () => {\n onChange({\n html: html.trim() || undefined,\n css: css.trim() || undefined,\n caption: caption.trim() || undefined,\n nodes: data.nodes,\n edges: data.edges,\n notes: data.notes,\n });\n };\n\n const saveLegacyDiagram = () => {\n const parsed = JSON.parse(legacyJson) as Pick<\n DiagramData,\n \"nodes\" | \"edges\" | \"notes\"\n >;\n onChange({\n ...data,\n nodes: parsed.nodes ?? [],\n edges: parsed.edges ?? [],\n notes: parsed.notes ?? [],\n });\n };\n\n const fieldAction = (\n field: \"HTML / SVG fragment\" | \"CSS\" | \"caption\" | \"legacy node graph JSON\",\n value: string,\n ) => ({\n blockId,\n blockType: \"diagram\",\n blockTitle: title,\n blockSummary: summary,\n fieldValue: value,\n draftScope: `block:diagram:${blockId}:${field.toLowerCase().replace(/[^a-z0-9]+/g, \"-\")}`,\n disabled: !editable,\n instructions:\n \"Update the plan with update-visual-plan using a targeted update-block content patch for this diagram block id. Preserve unrelated diagram fields unless the requested edit requires changing them. Keep diagram HTML/CSS on renderer-owned .diagram-* primitives and --wf-* tokens; do not introduce custom font-family or hard-coded hex/rgb/hsl colors.\",\n companionFields: [\n {\n label: \"HTML / SVG fragment\",\n value: html.trim() || \"(empty)\",\n language: \"html\",\n },\n { label: \"CSS\", value: css.trim() || \"(empty)\", language: \"css\" },\n {\n label: \"caption\",\n value: caption.trim() || \"(empty)\",\n language: \"text\",\n },\n ],\n });\n\n return (\n <div className=\"grid gap-4\" data-plan-interactive>\n <button\n type=\"button\"\n className=\"inline-flex h-8 w-fit items-center justify-center rounded-md bg-primary px-3 text-xs font-medium text-primary-foreground disabled:opacity-50\"\n disabled={!editable}\n onClick={saveHtmlDiagram}\n >\n Save diagram\n </button>\n <div className=\"group/field grid gap-1.5\">\n <AiEditableFieldLabel\n htmlFor={htmlId}\n label=\"HTML / SVG fragment\"\n ctx={ctx}\n action={fieldAction(\"HTML / SVG fragment\", html)}\n />\n <textarea\n id={htmlId}\n className=\"min-h-48 w-full rounded-md border border-input bg-background px-3 py-2 font-mono text-xs leading-5 text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n value={html}\n disabled={!editable}\n onChange={(event) => setHtml(event.target.value)}\n placeholder=\"<div class='diagram'>...</div>\"\n />\n </div>\n <div className=\"group/field grid gap-1.5\">\n <AiEditableFieldLabel\n htmlFor={cssId}\n label=\"CSS\"\n ctx={ctx}\n action={fieldAction(\"CSS\", css)}\n />\n <textarea\n id={cssId}\n className=\"min-h-32 w-full rounded-md border border-input bg-background px-3 py-2 font-mono text-xs leading-5 text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n value={css}\n disabled={!editable}\n onChange={(event) => setCss(event.target.value)}\n placeholder=\".diagram { display: grid; }\"\n />\n </div>\n <div className=\"group/field grid gap-1.5\">\n <AiEditableFieldLabel\n htmlFor={captionId}\n label=\"Caption\"\n ctx={ctx}\n action={fieldAction(\"caption\", caption)}\n />\n <input\n id={captionId}\n className=\"h-9 w-full rounded-md border border-input bg-background px-3 text-sm text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n value={caption}\n disabled={!editable}\n onChange={(event) => setCaption(event.target.value)}\n />\n </div>\n {!data.html && (\n <details className=\"rounded-md border border-border p-3\">\n <summary className=\"cursor-pointer text-xs font-semibold text-muted-foreground\">\n Legacy node graph data\n </summary>\n <div className=\"group/field mt-3 grid gap-1.5\">\n <AiEditableFieldLabel\n htmlFor={legacyId}\n label=\"JSON\"\n ctx={ctx}\n action={fieldAction(\"legacy node graph JSON\", legacyJson)}\n />\n <textarea\n id={legacyId}\n className=\"min-h-44 w-full rounded-md border border-input bg-background px-3 py-2 font-mono text-xs leading-5 text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n value={legacyJson}\n disabled={!editable}\n onChange={(event) => setLegacyJson(event.target.value)}\n />\n </div>\n <button\n type=\"button\"\n className=\"mt-3 inline-flex h-8 items-center justify-center rounded-md border border-input px-3 text-xs font-medium text-foreground disabled:opacity-50\"\n disabled={!editable}\n onClick={saveLegacyDiagram}\n >\n Save graph data\n </button>\n </details>\n )}\n </div>\n );\n}\n\n/** Full client spec for the shared `diagram` block (schema + MDX + Read/Edit). */\nexport const diagramBlock = defineBlock<DiagramData>({\n type: \"diagram\",\n schema: diagramSchema,\n mdx: diagramMdx,\n Read: DiagramRead,\n Edit: DiagramEdit,\n placement: [\"block\"],\n // Config-driven: the rendered diagram differs from its raw html/css source, so\n // edit from a corner button + panel rather than inline.\n editSurface: \"panel\",\n label: \"Diagram\",\n description:\n \"A flexible inline architecture/code diagram. Prefer html/css with SVG or semantic HTML for polished two-dimensional layouts; use .diagram-* primitives and --wf-* tokens for theme/sketch compatibility. Legacy nodes/edges are only for simple previews.\",\n // Seed the legacy fallback shape so a fresh block validates while agents can\n // replace it with html/css when layout quality matters.\n empty: () => ({ nodes: [{ id: \"n1\", label: \"Module\" }], edges: [] }),\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"TiptapComposer.d.ts","sourceRoot":"","sources":["../../../src/client/composer/TiptapComposer.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TiptapComposer.d.ts","sourceRoot":"","sources":["../../../src/client/composer/TiptapComposer.tsx"],"names":[],"mappings":"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"}
@@ -18,7 +18,7 @@ import { ComposerPlusMenu } from "./ComposerPlusMenu.js";
18
18
  import { sendToAgentChat } from "../agent-chat.js";
19
19
  import { tryDelegateBuildRequestToBuilder } from "../builder-frame.js";
20
20
  import { getComposerDraftKey } from "./draft-key.js";
21
- import { createPastedTextFile, shouldConvertPasteToAttachment, } from "./pasted-text.js";
21
+ import { createPastedAttachmentFile, readClipboardPaste, shouldConvertClipboardToAttachment, } from "./pasted-text.js";
22
22
  import { getReasoningEffortOptionsForModel, reasoningEffortLabel, } from "../../shared/reasoning-effort.js";
23
23
  import { Tooltip, TooltipContent, TooltipTrigger, } from "../components/ui/tooltip.js";
24
24
  import { Popover, PopoverContent, PopoverTrigger, } from "../components/ui/popover.js";
@@ -574,7 +574,8 @@ export function TiptapComposer({ placeholder = "Message agent...", disabled = fa
574
574
  class: "agent-composer-prosemirror flex-1 resize-none bg-transparent text-sm text-foreground outline-none leading-[1.625rem] min-h-[3.25rem] max-h-[10rem] overflow-y-auto",
575
575
  },
576
576
  handlePaste: (_view, event) => {
577
- const pastedText = event.clipboardData?.getData("text/plain") ?? "";
577
+ const paste = readClipboardPaste(event.clipboardData);
578
+ const pastedText = paste.text;
578
579
  const files = Array.from(event.clipboardData?.files ?? []).filter((file) => file.type.startsWith("image/"));
579
580
  if (files.length > 0) {
580
581
  event.preventDefault();
@@ -591,20 +592,24 @@ export function TiptapComposer({ placeholder = "Message agent...", disabled = fa
591
592
  // prevent Tiptap's default paste, preserve any text as its own chip
592
593
  // instead of silently dropping the source material.
593
594
  if (pastedText.trim()) {
594
- attachments.push(createPastedTextFile(pastedText));
595
+ attachments.push(createPastedAttachmentFile(paste));
595
596
  }
596
597
  void Promise.all(attachments.map((file) => composerRuntime.addAttachment(file))).catch((error) => {
597
598
  console.error("Error adding pasted attachment:", error);
598
599
  });
599
600
  return true;
600
601
  }
601
- // Page-sized text pastes turn into a `Pasted text` attachment chip so
602
- // the prompt stays readable while normal paragraphs and lists stay
603
- // inline.
604
- if (shouldConvertPasteToAttachment(pastedText)) {
602
+ // Page-sized pastes turn into a `Pasted text` attachment chip so the
603
+ // prompt stays readable while normal paragraphs and lists stay inline.
604
+ // When the paste is HTML (e.g. an Alpine.js extension or a document the
605
+ // user wants hosted), it's stored as a real .html attachment so it
606
+ // travels the same rail as uploading that file — the agent reads it
607
+ // verbatim via contentFromAttachment instead of retyping it inline,
608
+ // which cuts off mid-stream on large files and triggers a spin.
609
+ if (shouldConvertClipboardToAttachment(paste)) {
605
610
  event.preventDefault();
606
611
  void composerRuntime
607
- .addAttachment(createPastedTextFile(pastedText))
612
+ .addAttachment(createPastedAttachmentFile(paste))
608
613
  .catch((error) => {
609
614
  console.error("Error adding pasted-text attachment:", error);
610
615
  });