@agent-native/core 0.44.3 → 0.44.4

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 (52) 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/skills.d.ts +5 -1
  6. package/dist/cli/skills.d.ts.map +1 -1
  7. package/dist/cli/skills.js +651 -21
  8. package/dist/cli/skills.js.map +1 -1
  9. package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts.map +1 -1
  10. package/dist/client/blocks/library/AnnotatedCodeBlock.js +14 -3
  11. package/dist/client/blocks/library/AnnotatedCodeBlock.js.map +1 -1
  12. package/dist/client/blocks/library/ApiEndpointBlock.d.ts.map +1 -1
  13. package/dist/client/blocks/library/ApiEndpointBlock.js +11 -7
  14. package/dist/client/blocks/library/ApiEndpointBlock.js.map +1 -1
  15. package/dist/client/blocks/library/DiffBlock.d.ts.map +1 -1
  16. package/dist/client/blocks/library/DiffBlock.js +89 -5
  17. package/dist/client/blocks/library/DiffBlock.js.map +1 -1
  18. package/dist/client/blocks/library/HighlightedCode.d.ts +2 -1
  19. package/dist/client/blocks/library/HighlightedCode.d.ts.map +1 -1
  20. package/dist/client/blocks/library/HighlightedCode.js +2 -2
  21. package/dist/client/blocks/library/HighlightedCode.js.map +1 -1
  22. package/dist/client/blocks/library/JsonExplorerBlock.d.ts.map +1 -1
  23. package/dist/client/blocks/library/JsonExplorerBlock.js +57 -13
  24. package/dist/client/blocks/library/JsonExplorerBlock.js.map +1 -1
  25. package/dist/client/blocks/library/code.d.ts.map +1 -1
  26. package/dist/client/blocks/library/code.js +27 -6
  27. package/dist/client/blocks/library/code.js.map +1 -1
  28. package/dist/client/blocks/library/columns.d.ts.map +1 -1
  29. package/dist/client/blocks/library/columns.js +11 -1
  30. package/dist/client/blocks/library/columns.js.map +1 -1
  31. package/dist/client/blocks/library/narrow-container.d.ts +13 -0
  32. package/dist/client/blocks/library/narrow-container.d.ts.map +1 -0
  33. package/dist/client/blocks/library/narrow-container.js +32 -0
  34. package/dist/client/blocks/library/narrow-container.js.map +1 -0
  35. package/dist/client/blocks/library/question-form.d.ts.map +1 -1
  36. package/dist/client/blocks/library/question-form.js +8 -9
  37. package/dist/client/blocks/library/question-form.js.map +1 -1
  38. package/dist/client/blocks/library/tabs.d.ts.map +1 -1
  39. package/dist/client/blocks/library/tabs.js +6 -5
  40. package/dist/client/blocks/library/tabs.js.map +1 -1
  41. package/dist/client/blocks/types.d.ts +2 -0
  42. package/dist/client/blocks/types.d.ts.map +1 -1
  43. package/dist/client/blocks/types.js.map +1 -1
  44. package/dist/db/client.d.ts +11 -0
  45. package/dist/db/client.d.ts.map +1 -1
  46. package/dist/db/client.js +20 -0
  47. package/dist/db/client.js.map +1 -1
  48. package/dist/db/migrations.d.ts.map +1 -1
  49. package/dist/db/migrations.js +9 -2
  50. package/dist/db/migrations.js.map +1 -1
  51. package/dist/styles/blocks.css +36 -10
  52. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"columns.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/columns.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAEV,cAAc,EACd,cAAc,EAEf,MAAM,aAAa,CAAC;AACrB,OAAO,EAGL,KAAK,WAAW,EAEjB,MAAM,qBAAqB,CAAC;AAsH7B,kFAAkF;AAClF,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,OAAO,EACP,KAAK,EACL,GAAG,GACJ,EAAE,cAAc,CAAC,WAAW,CAAC,2CAsB7B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,GAAG,GACJ,EAAE,cAAc,CAAC,WAAW,CAAC,2CAsE7B;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,8CA0DvB,CAAC"}
1
+ {"version":3,"file":"columns.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/columns.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAEV,cAAc,EACd,cAAc,EAEf,MAAM,aAAa,CAAC;AACrB,OAAO,EAGL,KAAK,WAAW,EAEjB,MAAM,qBAAqB,CAAC;AAuH7B,kFAAkF;AAClF,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,OAAO,EACP,KAAK,EACL,GAAG,GACJ,EAAE,cAAc,CAAC,WAAW,CAAC,2CAqC7B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,GAAG,GACJ,EAAE,cAAc,CAAC,WAAW,CAAC,2CAsE7B;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,8CA0DvB,CAAC"}
@@ -3,6 +3,7 @@ import { IconColumns } from "@tabler/icons-react";
3
3
  import { cn } from "../../utils.js";
4
4
  import { defineBlock } from "../types.js";
5
5
  import { columnsSchema, columnsMdx, } from "./columns.config.js";
6
+ import { NarrowContainerProvider } from "./narrow-container.js";
6
7
  /**
7
8
  * Standard `columns` block: a multi-column side-by-side container whose columns
8
9
  * each hold a list of child blocks. A column's optional `label` renders as a
@@ -102,7 +103,16 @@ function areSameBlocks(a, b) {
102
103
  }
103
104
  /** Read renderer: a responsive grid of columns, each child rendered read-only. */
104
105
  export function ColumnsBlockReader({ data, blockId, title, ctx, }) {
105
- return (_jsxs("section", { className: "plan-block", "data-block-id": blockId, children: [title && _jsx("div", { className: "plan-block-label", children: title }), _jsx("div", { className: cn("grid gap-6", columnsLayoutClass(data.columns)), children: data.columns.map((column) => (_jsxs("div", { className: "min-w-0", children: [column.label && (_jsx("h4", { className: "plan-columns-label", children: column.label })), _jsx("div", { children: column.blocks.map((child) => (_jsx("div", { children: ctx.renderBlock?.({ block: child, editing: false }) }, child.id))) })] }, column.id))) })] }));
106
+ // A column cell is width-constrained only when the layout actually renders
107
+ // more than one column side by side; single-column / stacked layouts (API
108
+ // reference groups, wide wireframes) keep full document width, so a nested
109
+ // width-sensitive block (e.g. a diff) should NOT be forced to its narrow
110
+ // default there.
111
+ const narrow = columnsLayoutClass(data.columns) !== COLS_CLASS[1];
112
+ return (_jsxs("section", { className: "plan-block", "data-block-id": blockId, children: [title && _jsx("div", { className: "plan-block-label", children: title }), _jsx("div", { className: cn("grid gap-6", columnsLayoutClass(data.columns)), children: data.columns.map((column) => {
113
+ const body = (_jsx("div", { children: column.blocks.map((child) => (_jsx("div", { children: ctx.renderBlock?.({ block: child, editing: false }) }, child.id))) }));
114
+ return (_jsxs("div", { className: "min-w-0", children: [column.label && (_jsx("h4", { className: "plan-columns-label", children: column.label })), narrow ? (_jsx(NarrowContainerProvider, { children: body })) : (body)] }, column.id));
115
+ }) })] }));
106
116
  }
107
117
  /**
108
118
  * Editor: the same responsive grid, with child blocks rendered editable in
@@ -1 +1 @@
1
- {"version":3,"file":"columns.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/columns.tsx"],"names":[],"mappings":"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","sourcesContent":["import { IconColumns } from \"@tabler/icons-react\";\nimport { cn } from \"../../utils.js\";\nimport { defineBlock } from \"../types.js\";\nimport type {\n BlockContainerRegion,\n BlockEditProps,\n BlockReadProps,\n NestedBlock,\n} from \"../types.js\";\nimport {\n columnsSchema,\n columnsMdx,\n type ColumnsData,\n type ColumnsColumn,\n} from \"./columns.config.js\";\n\n/**\n * Standard `columns` block: a multi-column side-by-side container whose columns\n * each hold a list of child blocks. A column's optional `label` renders as a\n * small heading above that column (e.g. `Before` / `After`), so a comparison\n * names its states outside the content — never baked into a child wireframe.\n *\n * Like `tabs`, child rendering flows through `ctx.renderBlock` — the app's own\n * block dispatcher — so registered children render via their spec and\n * unconverted children fall through the app's legacy switch. This is the\n * coexistence seam: the core columns block never has to know app-specific child\n * block types. The plan CSS classes (`plan-block`, `text-plan-*`) resolve\n * against the plan app's stylesheet at render time.\n */\n\n/** Mint a reasonably-unique column id without pulling a dep into core. */\nfunction newColId(): string {\n return `col-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/**\n * Tailwind grid-column classes keyed by the column count. The grid collapses to\n * a single column on small screens and fans out to the column count at `md`+, so\n * narrow viewports stack the panels instead of crushing them.\n */\nconst COLS_CLASS: Record<number, string> = {\n 1: \"grid-cols-1\",\n 2: \"grid-cols-1 md:grid-cols-2\",\n 3: \"grid-cols-1 md:grid-cols-3\",\n 4: \"grid-cols-1 md:grid-cols-4\",\n};\n\n/** Resolve the responsive grid class for a column count (clamped to 1–4). */\nfunction gridColsClass(count: number): string {\n return COLS_CLASS[Math.min(4, Math.max(1, count))] ?? COLS_CLASS[1];\n}\n\nconst API_REFERENCE_BLOCK_TYPES = new Set([\"api-endpoint\", \"openapi-spec\"]);\nconst BEFORE_LABELS = new Set([\"before\", \"old\", \"previous\", \"current\"]);\nconst AFTER_LABELS = new Set([\"after\", \"new\", \"next\", \"target\"]);\n\n// Wireframe surfaces that render too wide to survive a half-width comparison\n// column: a full desktop page or browser frame shrinks and crops when squeezed\n// side by side, so a comparison that holds one of these stacks vertically.\nconst WIDE_WIREFRAME_SURFACES = new Set([\"desktop\", \"browser\"]);\n\nfunction normalizedLabel(column: ColumnsColumn): string {\n return column.label?.trim().toLowerCase() ?? \"\";\n}\n\nfunction isComparisonGroup(columns: ColumnsColumn[]): boolean {\n const labels = columns.map(normalizedLabel);\n return (\n labels.some((label) => BEFORE_LABELS.has(label)) &&\n labels.some((label) => AFTER_LABELS.has(label))\n );\n}\n\n/** A wireframe child whose `surface` is wide enough to need full document width. */\nfunction isWideWireframeBlock(block: NestedBlock): boolean {\n if (block.type !== \"wireframe\") return false;\n const surface = (block.data as { surface?: unknown } | undefined)?.surface;\n return typeof surface === \"string\" && WIDE_WIREFRAME_SURFACES.has(surface);\n}\n\nfunction hasWideWireframe(columns: ColumnsColumn[]): boolean {\n return columns.some((column) => column.blocks.some(isWideWireframeBlock));\n}\n\nfunction isApiReferenceGroup(columns: ColumnsColumn[]): boolean {\n return (\n columns.length > 1 &&\n !isComparisonGroup(columns) &&\n columns.every(\n (column) =>\n column.blocks.length > 0 &&\n column.blocks.every((block) =>\n API_REFERENCE_BLOCK_TYPES.has(block.type),\n ),\n )\n );\n}\n\nfunction columnsLayoutClass(columns: ColumnsColumn[]): string {\n // API reference groups always read as a single stacked column.\n if (isApiReferenceGroup(columns)) return COLS_CLASS[1];\n // Wide wireframes (full desktop / browser surfaces) crop when squeezed into a\n // half-width comparison cell, so stack the states vertically and let each\n // frame use the full document width. Narrow surfaces stay side by side.\n if (hasWideWireframe(columns)) return COLS_CLASS[1];\n return gridColsClass(columns.length);\n}\n\nfunction isBlankRichTextBlock(block: NestedBlock): boolean {\n if (block.type !== \"rich-text\") return false;\n const data = block.data;\n if (!data || typeof data !== \"object\" || Array.isArray(data)) return false;\n const markdown = (data as { markdown?: unknown }).markdown;\n return typeof markdown === \"string\" && markdown.trim().length === 0;\n}\n\nfunction isEffectivelyEmptyRegion(blocks: NestedBlock[]): boolean {\n return (\n blocks.length === 0 ||\n (blocks.length === 1 && isBlankRichTextBlock(blocks[0]!))\n );\n}\n\nfunction areSameBlocks(a: NestedBlock[], b: NestedBlock[]): boolean {\n if (a === b) return true;\n try {\n return JSON.stringify(a) === JSON.stringify(b);\n } catch {\n return false;\n }\n}\n\n/** Read renderer: a responsive grid of columns, each child rendered read-only. */\nexport function ColumnsBlockReader({\n data,\n blockId,\n title,\n ctx,\n}: BlockReadProps<ColumnsData>) {\n return (\n <section className=\"plan-block\" data-block-id={blockId}>\n {title && <div className=\"plan-block-label\">{title}</div>}\n <div className={cn(\"grid gap-6\", columnsLayoutClass(data.columns))}>\n {data.columns.map((column) => (\n <div key={column.id} className=\"min-w-0\">\n {column.label && (\n <h4 className=\"plan-columns-label\">{column.label}</h4>\n )}\n <div>\n {column.blocks.map((child) => (\n <div key={child.id}>\n {ctx.renderBlock?.({ block: child, editing: false })}\n </div>\n ))}\n </div>\n </div>\n ))}\n </div>\n </section>\n );\n}\n\n/**\n * Editor: the same responsive grid, with child blocks rendered editable in\n * place through the app dispatcher. A child change updates that child within\n * its column and commits the whole\n * columns block — mirroring the legacy `tabs` onChange bubbling so the plan's\n * recursive `updateBlocks`/`findBlock` (`PlanContentRenderer`) keeps working.\n *\n * Renders BARE (no `plan-block` section / title): in edit mode the app's block\n * dispatcher already wraps registered editors in a titled `plan-block` section,\n * so wrapping again here would double-nest. The read renderer owns its own\n * section because read mode renders the spec directly.\n */\nexport function ColumnsBlockEditor({\n data,\n onChange,\n editable,\n blockId,\n ctx,\n}: BlockEditProps<ColumnsData>) {\n const commit = (columns: ColumnsColumn[]) => onChange({ columns });\n\n const updateChild = (columnId: string, child: NestedBlock) =>\n commit(\n data.columns.map((column) =>\n column.id === columnId\n ? {\n ...column,\n blocks: column.blocks.map((existing) =>\n existing.id === child.id ? child : existing,\n ),\n }\n : column,\n ),\n );\n\n return (\n <div data-columns-edit-block={blockId} className=\"grid gap-3\">\n <div className={cn(\"grid gap-6\", columnsLayoutClass(data.columns))}>\n {data.columns.map((column) => (\n <div key={column.id} className=\"min-w-0\">\n {column.label && (\n <h4 className=\"plan-columns-label\">{column.label}</h4>\n )}\n <div>\n {ctx.renderBlocksEditor\n ? ctx.renderBlocksEditor({\n blocks: column.blocks,\n onChange: (nextBlocks) => {\n if (areSameBlocks(nextBlocks, column.blocks)) return;\n onChange(\n {\n columns: data.columns.map((existing) =>\n existing.id === column.id\n ? {\n ...existing,\n blocks: nextBlocks,\n }\n : existing,\n ),\n },\n {\n containerRegion: {\n regionId: column.id,\n blocks: nextBlocks,\n },\n },\n );\n },\n editable,\n containerBlockId: blockId,\n regionId: column.id,\n regionLabel: column.label,\n })\n : column.blocks.map((child) => (\n <div key={child.id}>\n {ctx.renderBlock?.({\n block: child,\n editing: true,\n onChange: (next) => updateChild(column.id, next),\n })}\n </div>\n ))}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n\n/**\n * The standard columns block spec (with React `Read`/`Edit`). Apps register this\n * in their browser registry. The schema + MDX config come from\n * `./columns.config.ts`, the exact same object server / agent code registers, so\n * rendering and source round-trip never drift.\n */\nexport const columnsBlock = defineBlock<ColumnsData>({\n type: \"columns\",\n schema: columnsSchema,\n mdx: columnsMdx,\n Read: ColumnsBlockReader,\n Edit: ColumnsBlockEditor,\n placement: [\"block\"],\n editSurface: \"container\",\n container: {\n regions: (data): BlockContainerRegion[] => data.columns,\n updateRegion: (data, regionId, blocks) => {\n const shouldRemoveRegion =\n data.columns.length > 1 && isEffectivelyEmptyRegion(blocks);\n\n return {\n columns: data.columns\n .map((column) =>\n column.id === regionId ? { ...column, blocks } : column,\n )\n .filter((column) => column.id !== regionId || !shouldRemoveRegion),\n };\n },\n addRegion: (data, afterRegionId) => {\n if (data.columns.length >= 4) return data;\n const nextColumn: ColumnsColumn = {\n id: newColId(),\n blocks: [],\n };\n if (!afterRegionId) return { columns: [...data.columns, nextColumn] };\n const afterIndex = data.columns.findIndex(\n (column) => column.id === afterRegionId,\n );\n if (afterIndex < 0) return { columns: [...data.columns, nextColumn] };\n return {\n columns: [\n ...data.columns.slice(0, afterIndex + 1),\n nextColumn,\n ...data.columns.slice(afterIndex + 1),\n ],\n };\n },\n removeRegion: (data, regionId) => {\n if (data.columns.length <= 1) return data;\n return {\n columns: data.columns.filter((column) => column.id !== regionId),\n };\n },\n },\n label: \"Columns\",\n icon: IconColumns,\n description:\n \"A multi-column side-by-side layout container; each column holds its own list of blocks. Ideal for before/after or current/target comparisons.\",\n empty: () => ({\n columns: [\n { id: newColId(), blocks: [] },\n { id: newColId(), blocks: [] },\n ],\n }),\n});\n"]}
1
+ {"version":3,"file":"columns.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/columns.tsx"],"names":[],"mappings":"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","sourcesContent":["import { IconColumns } from \"@tabler/icons-react\";\nimport { cn } from \"../../utils.js\";\nimport { defineBlock } from \"../types.js\";\nimport type {\n BlockContainerRegion,\n BlockEditProps,\n BlockReadProps,\n NestedBlock,\n} from \"../types.js\";\nimport {\n columnsSchema,\n columnsMdx,\n type ColumnsData,\n type ColumnsColumn,\n} from \"./columns.config.js\";\nimport { NarrowContainerProvider } from \"./narrow-container.js\";\n\n/**\n * Standard `columns` block: a multi-column side-by-side container whose columns\n * each hold a list of child blocks. A column's optional `label` renders as a\n * small heading above that column (e.g. `Before` / `After`), so a comparison\n * names its states outside the content — never baked into a child wireframe.\n *\n * Like `tabs`, child rendering flows through `ctx.renderBlock` — the app's own\n * block dispatcher — so registered children render via their spec and\n * unconverted children fall through the app's legacy switch. This is the\n * coexistence seam: the core columns block never has to know app-specific child\n * block types. The plan CSS classes (`plan-block`, `text-plan-*`) resolve\n * against the plan app's stylesheet at render time.\n */\n\n/** Mint a reasonably-unique column id without pulling a dep into core. */\nfunction newColId(): string {\n return `col-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/**\n * Tailwind grid-column classes keyed by the column count. The grid collapses to\n * a single column on small screens and fans out to the column count at `md`+, so\n * narrow viewports stack the panels instead of crushing them.\n */\nconst COLS_CLASS: Record<number, string> = {\n 1: \"grid-cols-1\",\n 2: \"grid-cols-1 md:grid-cols-2\",\n 3: \"grid-cols-1 md:grid-cols-3\",\n 4: \"grid-cols-1 md:grid-cols-4\",\n};\n\n/** Resolve the responsive grid class for a column count (clamped to 1–4). */\nfunction gridColsClass(count: number): string {\n return COLS_CLASS[Math.min(4, Math.max(1, count))] ?? COLS_CLASS[1];\n}\n\nconst API_REFERENCE_BLOCK_TYPES = new Set([\"api-endpoint\", \"openapi-spec\"]);\nconst BEFORE_LABELS = new Set([\"before\", \"old\", \"previous\", \"current\"]);\nconst AFTER_LABELS = new Set([\"after\", \"new\", \"next\", \"target\"]);\n\n// Wireframe surfaces that render too wide to survive a half-width comparison\n// column: a full desktop page or browser frame shrinks and crops when squeezed\n// side by side, so a comparison that holds one of these stacks vertically.\nconst WIDE_WIREFRAME_SURFACES = new Set([\"desktop\", \"browser\"]);\n\nfunction normalizedLabel(column: ColumnsColumn): string {\n return column.label?.trim().toLowerCase() ?? \"\";\n}\n\nfunction isComparisonGroup(columns: ColumnsColumn[]): boolean {\n const labels = columns.map(normalizedLabel);\n return (\n labels.some((label) => BEFORE_LABELS.has(label)) &&\n labels.some((label) => AFTER_LABELS.has(label))\n );\n}\n\n/** A wireframe child whose `surface` is wide enough to need full document width. */\nfunction isWideWireframeBlock(block: NestedBlock): boolean {\n if (block.type !== \"wireframe\") return false;\n const surface = (block.data as { surface?: unknown } | undefined)?.surface;\n return typeof surface === \"string\" && WIDE_WIREFRAME_SURFACES.has(surface);\n}\n\nfunction hasWideWireframe(columns: ColumnsColumn[]): boolean {\n return columns.some((column) => column.blocks.some(isWideWireframeBlock));\n}\n\nfunction isApiReferenceGroup(columns: ColumnsColumn[]): boolean {\n return (\n columns.length > 1 &&\n !isComparisonGroup(columns) &&\n columns.every(\n (column) =>\n column.blocks.length > 0 &&\n column.blocks.every((block) =>\n API_REFERENCE_BLOCK_TYPES.has(block.type),\n ),\n )\n );\n}\n\nfunction columnsLayoutClass(columns: ColumnsColumn[]): string {\n // API reference groups always read as a single stacked column.\n if (isApiReferenceGroup(columns)) return COLS_CLASS[1];\n // Wide wireframes (full desktop / browser surfaces) crop when squeezed into a\n // half-width comparison cell, so stack the states vertically and let each\n // frame use the full document width. Narrow surfaces stay side by side.\n if (hasWideWireframe(columns)) return COLS_CLASS[1];\n return gridColsClass(columns.length);\n}\n\nfunction isBlankRichTextBlock(block: NestedBlock): boolean {\n if (block.type !== \"rich-text\") return false;\n const data = block.data;\n if (!data || typeof data !== \"object\" || Array.isArray(data)) return false;\n const markdown = (data as { markdown?: unknown }).markdown;\n return typeof markdown === \"string\" && markdown.trim().length === 0;\n}\n\nfunction isEffectivelyEmptyRegion(blocks: NestedBlock[]): boolean {\n return (\n blocks.length === 0 ||\n (blocks.length === 1 && isBlankRichTextBlock(blocks[0]!))\n );\n}\n\nfunction areSameBlocks(a: NestedBlock[], b: NestedBlock[]): boolean {\n if (a === b) return true;\n try {\n return JSON.stringify(a) === JSON.stringify(b);\n } catch {\n return false;\n }\n}\n\n/** Read renderer: a responsive grid of columns, each child rendered read-only. */\nexport function ColumnsBlockReader({\n data,\n blockId,\n title,\n ctx,\n}: BlockReadProps<ColumnsData>) {\n // A column cell is width-constrained only when the layout actually renders\n // more than one column side by side; single-column / stacked layouts (API\n // reference groups, wide wireframes) keep full document width, so a nested\n // width-sensitive block (e.g. a diff) should NOT be forced to its narrow\n // default there.\n const narrow = columnsLayoutClass(data.columns) !== COLS_CLASS[1];\n return (\n <section className=\"plan-block\" data-block-id={blockId}>\n {title && <div className=\"plan-block-label\">{title}</div>}\n <div className={cn(\"grid gap-6\", columnsLayoutClass(data.columns))}>\n {data.columns.map((column) => {\n const body = (\n <div>\n {column.blocks.map((child) => (\n <div key={child.id}>\n {ctx.renderBlock?.({ block: child, editing: false })}\n </div>\n ))}\n </div>\n );\n return (\n <div key={column.id} className=\"min-w-0\">\n {column.label && (\n <h4 className=\"plan-columns-label\">{column.label}</h4>\n )}\n {narrow ? (\n <NarrowContainerProvider>{body}</NarrowContainerProvider>\n ) : (\n body\n )}\n </div>\n );\n })}\n </div>\n </section>\n );\n}\n\n/**\n * Editor: the same responsive grid, with child blocks rendered editable in\n * place through the app dispatcher. A child change updates that child within\n * its column and commits the whole\n * columns block — mirroring the legacy `tabs` onChange bubbling so the plan's\n * recursive `updateBlocks`/`findBlock` (`PlanContentRenderer`) keeps working.\n *\n * Renders BARE (no `plan-block` section / title): in edit mode the app's block\n * dispatcher already wraps registered editors in a titled `plan-block` section,\n * so wrapping again here would double-nest. The read renderer owns its own\n * section because read mode renders the spec directly.\n */\nexport function ColumnsBlockEditor({\n data,\n onChange,\n editable,\n blockId,\n ctx,\n}: BlockEditProps<ColumnsData>) {\n const commit = (columns: ColumnsColumn[]) => onChange({ columns });\n\n const updateChild = (columnId: string, child: NestedBlock) =>\n commit(\n data.columns.map((column) =>\n column.id === columnId\n ? {\n ...column,\n blocks: column.blocks.map((existing) =>\n existing.id === child.id ? child : existing,\n ),\n }\n : column,\n ),\n );\n\n return (\n <div data-columns-edit-block={blockId} className=\"grid gap-3\">\n <div className={cn(\"grid gap-6\", columnsLayoutClass(data.columns))}>\n {data.columns.map((column) => (\n <div key={column.id} className=\"min-w-0\">\n {column.label && (\n <h4 className=\"plan-columns-label\">{column.label}</h4>\n )}\n <div>\n {ctx.renderBlocksEditor\n ? ctx.renderBlocksEditor({\n blocks: column.blocks,\n onChange: (nextBlocks) => {\n if (areSameBlocks(nextBlocks, column.blocks)) return;\n onChange(\n {\n columns: data.columns.map((existing) =>\n existing.id === column.id\n ? {\n ...existing,\n blocks: nextBlocks,\n }\n : existing,\n ),\n },\n {\n containerRegion: {\n regionId: column.id,\n blocks: nextBlocks,\n },\n },\n );\n },\n editable,\n containerBlockId: blockId,\n regionId: column.id,\n regionLabel: column.label,\n })\n : column.blocks.map((child) => (\n <div key={child.id}>\n {ctx.renderBlock?.({\n block: child,\n editing: true,\n onChange: (next) => updateChild(column.id, next),\n })}\n </div>\n ))}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n\n/**\n * The standard columns block spec (with React `Read`/`Edit`). Apps register this\n * in their browser registry. The schema + MDX config come from\n * `./columns.config.ts`, the exact same object server / agent code registers, so\n * rendering and source round-trip never drift.\n */\nexport const columnsBlock = defineBlock<ColumnsData>({\n type: \"columns\",\n schema: columnsSchema,\n mdx: columnsMdx,\n Read: ColumnsBlockReader,\n Edit: ColumnsBlockEditor,\n placement: [\"block\"],\n editSurface: \"container\",\n container: {\n regions: (data): BlockContainerRegion[] => data.columns,\n updateRegion: (data, regionId, blocks) => {\n const shouldRemoveRegion =\n data.columns.length > 1 && isEffectivelyEmptyRegion(blocks);\n\n return {\n columns: data.columns\n .map((column) =>\n column.id === regionId ? { ...column, blocks } : column,\n )\n .filter((column) => column.id !== regionId || !shouldRemoveRegion),\n };\n },\n addRegion: (data, afterRegionId) => {\n if (data.columns.length >= 4) return data;\n const nextColumn: ColumnsColumn = {\n id: newColId(),\n blocks: [],\n };\n if (!afterRegionId) return { columns: [...data.columns, nextColumn] };\n const afterIndex = data.columns.findIndex(\n (column) => column.id === afterRegionId,\n );\n if (afterIndex < 0) return { columns: [...data.columns, nextColumn] };\n return {\n columns: [\n ...data.columns.slice(0, afterIndex + 1),\n nextColumn,\n ...data.columns.slice(afterIndex + 1),\n ],\n };\n },\n removeRegion: (data, regionId) => {\n if (data.columns.length <= 1) return data;\n return {\n columns: data.columns.filter((column) => column.id !== regionId),\n };\n },\n },\n label: \"Columns\",\n icon: IconColumns,\n description:\n \"A multi-column side-by-side layout container; each column holds its own list of blocks. Ideal for before/after or current/target comparisons.\",\n empty: () => ({\n columns: [\n { id: newColId(), blocks: [] },\n { id: newColId(), blocks: [] },\n ],\n }),\n});\n"]}
@@ -0,0 +1,13 @@
1
+ import { type ReactNode } from "react";
2
+ /** True when the current block renders inside a tab panel or a column cell. */
3
+ export declare function useInNarrowContainer(): boolean;
4
+ /**
5
+ * Marks its subtree as living inside a width-constrained container. Wrap the
6
+ * children a `tabs`/`columns` block renders so nested width-sensitive blocks can
7
+ * pick a container-appropriate default. Idempotent: nesting the provider keeps
8
+ * the flag `true`.
9
+ */
10
+ export declare function NarrowContainerProvider({ children }: {
11
+ children: ReactNode;
12
+ }): import("react/jsx-runtime").JSX.Element;
13
+ //# sourceMappingURL=narrow-container.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"narrow-container.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/narrow-container.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAmBlE,+EAA+E;AAC/E,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,2CAM5E"}
@@ -0,0 +1,32 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext } from "react";
3
+ /**
4
+ * Flags that a block is rendered inside a WIDTH-CONSTRAINED container — a `tabs`
5
+ * tab panel or a `columns`/`Column` cell. Width-sensitive blocks (today the
6
+ * `diff` block) read this to pick a default layout that survives the narrower
7
+ * box: e.g. a diff with NO authored `mode` defaults to `unified` inside one of
8
+ * these containers instead of `split`, whose doubled line-number gutters crush
9
+ * the code in a half-width or vertical-tab column.
10
+ *
11
+ * It only nudges the DEFAULT. An explicitly authored mode (`mode="split"`) still
12
+ * wins, and the in-block Unified/Split toggle still works in either context —
13
+ * this never disables side-by-side, it just changes what you get before you pick.
14
+ *
15
+ * Lives in core beside the blocks so both the containers (`tabs`, `columns`) and
16
+ * the consumers (`DiffBlock`) share one source of truth without a new dep.
17
+ */
18
+ const NarrowContainerContext = createContext(false);
19
+ /** True when the current block renders inside a tab panel or a column cell. */
20
+ export function useInNarrowContainer() {
21
+ return useContext(NarrowContainerContext);
22
+ }
23
+ /**
24
+ * Marks its subtree as living inside a width-constrained container. Wrap the
25
+ * children a `tabs`/`columns` block renders so nested width-sensitive blocks can
26
+ * pick a container-appropriate default. Idempotent: nesting the provider keeps
27
+ * the flag `true`.
28
+ */
29
+ export function NarrowContainerProvider({ children }) {
30
+ return (_jsx(NarrowContainerContext.Provider, { value: true, children: children }));
31
+ }
32
+ //# sourceMappingURL=narrow-container.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"narrow-container.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/narrow-container.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAkB,MAAM,OAAO,CAAC;AAElE;;;;;;;;;;;;;;GAcG;AACH,MAAM,sBAAsB,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;AAEpD,+EAA+E;AAC/E,MAAM,UAAU,oBAAoB;IAClC,OAAO,UAAU,CAAC,sBAAsB,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CAAC,EAAE,QAAQ,EAA2B;IAC3E,OAAO,CACL,KAAC,sBAAsB,CAAC,QAAQ,IAAC,KAAK,EAAE,IAAI,YACzC,QAAQ,GACuB,CACnC,CAAC;AACJ,CAAC","sourcesContent":["import { createContext, useContext, type ReactNode } from \"react\";\n\n/**\n * Flags that a block is rendered inside a WIDTH-CONSTRAINED container — a `tabs`\n * tab panel or a `columns`/`Column` cell. Width-sensitive blocks (today the\n * `diff` block) read this to pick a default layout that survives the narrower\n * box: e.g. a diff with NO authored `mode` defaults to `unified` inside one of\n * these containers instead of `split`, whose doubled line-number gutters crush\n * the code in a half-width or vertical-tab column.\n *\n * It only nudges the DEFAULT. An explicitly authored mode (`mode=\"split\"`) still\n * wins, and the in-block Unified/Split toggle still works in either context —\n * this never disables side-by-side, it just changes what you get before you pick.\n *\n * Lives in core beside the blocks so both the containers (`tabs`, `columns`) and\n * the consumers (`DiffBlock`) share one source of truth without a new dep.\n */\nconst NarrowContainerContext = createContext(false);\n\n/** True when the current block renders inside a tab panel or a column cell. */\nexport function useInNarrowContainer(): boolean {\n return useContext(NarrowContainerContext);\n}\n\n/**\n * Marks its subtree as living inside a width-constrained container. Wrap the\n * children a `tabs`/`columns` block renders so nested width-sensitive blocks can\n * pick a container-appropriate default. Idempotent: nesting the provider keeps\n * the flag `true`.\n */\nexport function NarrowContainerProvider({ children }: { children: ReactNode }) {\n return (\n <NarrowContainerContext.Provider value={true}>\n {children}\n </NarrowContainerContext.Provider>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"question-form.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/question-form.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EAGf,MAAM,aAAa,CAAC;AACrB,OAAO,EAKL,KAAK,gBAAgB,EAIrB,KAAK,mBAAmB,EACzB,MAAM,2BAA2B,CAAC;AAoanC,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,CAAC,gBAAgB,CAAC,2CAEvE;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,cAAc,CAAC,mBAAmB,CAAC,2CAG3C;AAaD,qEAAqE;AACrE,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,QAAQ,EACR,QAAQ,GACT,EAAE,cAAc,CAAC,gBAAgB,CAAC,2CAsTlC;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,mDAsB5B,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,mDAmC/B,CAAC"}
1
+ {"version":3,"file":"question-form.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/question-form.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EAGf,MAAM,aAAa,CAAC;AACrB,OAAO,EAKL,KAAK,gBAAgB,EAIrB,KAAK,mBAAmB,EACzB,MAAM,2BAA2B,CAAC;AAganC,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,CAAC,gBAAgB,CAAC,2CAEvE;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,cAAc,CAAC,mBAAmB,CAAC,2CAG3C;AAaD,qEAAqE;AACrE,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,QAAQ,EACR,QAAQ,GACT,EAAE,cAAc,CAAC,gBAAgB,CAAC,2CAsTlC;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,mDAsB5B,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,mDAmC/B,CAAC"}
@@ -70,16 +70,16 @@ function QuestionView({ question, index, answer, blockId, ctx, onAnswer, }) {
70
70
  }), question.allowOther !== false && (_jsx("input", { value: answer?.text ?? "", onChange: (event) => onAnswer({ ...answer, text: event.target.value }), className: cn("h-10 w-full rounded-lg border border-border bg-card px-4 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring", hasVisualOptions ? "md:col-span-2" : "sm:w-80"), "data-plan-interactive": true, placeholder: question.placeholder || "Other — type your own answer…" }))] }))] })] }));
71
71
  }
72
72
  /** The "Send to agent" affordance: a popover (via the app surface) when wired. */
73
- function SubmitMenu({ blockId, ctx, onSubmit, buildSummary, }) {
73
+ function SubmitMenu({ ctx, onSubmit, buildSummary, }) {
74
74
  const [open, setOpen] = useState(false);
75
75
  const trigger = (_jsxs("button", { type: "button", "data-plan-interactive": true, className: "inline-flex h-9 shrink-0 items-center gap-1.5 rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90", children: ["Send to agent", _jsx(IconChevronDown, { className: "size-3.5 opacity-70" })] }));
76
- const menu = (_jsxs("div", { className: "grid gap-1", children: [_jsx("div", { className: "px-1 py-1 text-xs font-semibold text-muted-foreground", children: "Send feedback" }), _jsxs("button", { type: "button", "data-plan-interactive": true, disabled: !onSubmit, onClick: () => {
77
- onSubmit?.(buildSummary());
78
- setOpen(false);
79
- }, className: "grid grid-cols-[auto_1fr] items-start gap-2 rounded-md px-2 py-2 text-left text-sm text-foreground transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50", children: [_jsx(IconSend, { className: "mt-0.5 size-4" }), _jsxs("span", { className: "grid gap-0.5", children: [_jsx("span", { children: "Send to inline agent" }), _jsx("span", { className: "text-xs font-normal leading-4 text-muted-foreground", children: "Posts answered questions into the app side agent." })] })] }), _jsxs("button", { type: "button", "data-plan-interactive": true, onClick: () => {
76
+ const menu = (_jsxs("div", { className: "grid gap-1", children: [_jsx("div", { className: "px-1 py-1 text-xs font-semibold text-muted-foreground", children: "Send feedback" }), _jsxs("button", { type: "button", "data-plan-interactive": true, onClick: () => {
80
77
  void navigator.clipboard.writeText(buildSummary());
81
78
  setOpen(false);
82
- }, className: "grid grid-cols-[auto_1fr] items-start gap-2 rounded-md px-2 py-2 text-left text-sm text-foreground transition-colors hover:bg-accent", children: [_jsx(IconClipboardText, { className: "mt-0.5 size-4" }), _jsxs("span", { className: "grid gap-0.5", children: [_jsx("span", { children: "Copy for your agent" }), _jsx("span", { className: "text-xs font-normal leading-4 text-muted-foreground", children: "Copies a prompt you can paste into chat." })] })] })] }));
79
+ }, className: "grid grid-cols-[auto_1fr] items-start gap-2 rounded-md px-2 py-2 text-left text-sm text-foreground transition-colors hover:bg-accent", children: [_jsx(IconClipboardText, { className: "mt-0.5 size-4" }), _jsxs("span", { className: "grid gap-0.5", children: [_jsx("span", { children: "Copy for your agent" }), _jsx("span", { className: "text-xs font-normal leading-4 text-muted-foreground", children: "Copies a prompt you can paste into chat." })] })] }), _jsxs("button", { type: "button", "data-plan-interactive": true, disabled: !onSubmit, onClick: () => {
80
+ onSubmit?.(buildSummary());
81
+ setOpen(false);
82
+ }, className: "grid grid-cols-[auto_1fr] items-start gap-2 rounded-md px-2 py-2 text-left text-sm text-foreground transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50", children: [_jsx(IconSend, { className: "mt-0.5 size-4" }), _jsxs("span", { className: "grid gap-0.5", children: [_jsx("span", { children: "Send to inline agent" }), _jsx("span", { className: "text-xs font-normal leading-4 text-muted-foreground", children: "Posts answered questions into the app side agent." })] })] })] }));
83
83
  // Prefer the app-provided popover surface (shadcn Popover in plan/content);
84
84
  // core stays shadcn-free. Without a surface, fall back to a single button that
85
85
  // submits directly so the form still works.
@@ -87,8 +87,7 @@ function SubmitMenu({ blockId, ctx, onSubmit, buildSummary, }) {
87
87
  title: "Send to agent",
88
88
  open,
89
89
  onOpenChange: setOpen,
90
- blockId,
91
- blockType: "question-form",
90
+ variant: "menu",
92
91
  trigger,
93
92
  children: menu,
94
93
  });
@@ -109,7 +108,7 @@ function QuestionFormReadInner({ data, blockId, title, ctx, }) {
109
108
  };
110
109
  const answered = questions.filter((question) => isAnswered(question, answers[question.id])).length;
111
110
  const buildSummary = () => summarizeAnswers(blockId, title, questions, answers);
112
- return (_jsxs("section", { className: "an-questions-block plan-questions-block", "data-block-id": blockId, children: [title && (_jsx("h2", { className: "text-[1.45rem] font-semibold leading-tight text-foreground", children: title })), _jsx("div", { className: "mt-7 grid gap-8", children: questions.map((question, index) => (_jsx(QuestionView, { question: question, index: index, answer: answers[question.id], blockId: blockId, ctx: ctx, onAnswer: (next) => setAnswer(question.id, next) }, question.id))) }), _jsxs("div", { className: "sticky bottom-0 mt-10 flex items-center justify-between gap-4 border-t border-border bg-background py-4 backdrop-blur", children: [_jsxs("p", { className: "text-sm font-semibold text-muted-foreground", children: [answered, "/", questions.length, " answered"] }), _jsx("div", { "data-plan-interactive": true, children: _jsx(SubmitMenu, { blockId: blockId, ctx: ctx, onSubmit: submitCtx.onQuestionFormSubmit, buildSummary: buildSummary }) })] })] }));
111
+ return (_jsxs("section", { className: "an-questions-block plan-questions-block", "data-block-id": blockId, children: [title && (_jsx("h2", { className: "text-[1.45rem] font-semibold leading-tight text-foreground", children: title })), _jsx("div", { className: "mt-7 grid gap-8", children: questions.map((question, index) => (_jsx(QuestionView, { question: question, index: index, answer: answers[question.id], blockId: blockId, ctx: ctx, onAnswer: (next) => setAnswer(question.id, next) }, question.id))) }), _jsxs("div", { className: "sticky bottom-0 mt-10 flex items-center justify-between gap-4 border-t border-border py-4", children: [_jsxs("p", { className: "text-sm font-semibold text-muted-foreground", children: [answered, "/", questions.length, " answered"] }), _jsx("div", { "data-plan-interactive": true, children: _jsx(SubmitMenu, { ctx: ctx, onSubmit: submitCtx.onQuestionFormSubmit, buildSummary: buildSummary }) })] })] }));
113
112
  }
114
113
  export function QuestionFormRead(props) {
115
114
  return _jsx(QuestionFormReadInner, { ...props });
@@ -1 +1 @@
1
- {"version":3,"file":"question-form.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/question-form.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useState } from \"react\";\nimport {\n IconCheck,\n IconChevronDown,\n IconClipboardText,\n IconPlus,\n IconSend,\n IconTrash,\n} from \"@tabler/icons-react\";\nimport { cn } from \"../../utils.js\";\nimport { defineBlock } from \"../types.js\";\nimport type {\n BlockReadProps,\n BlockEditProps,\n BlockRenderContext,\n NestedBlock,\n} from \"../types.js\";\nimport {\n questionFormSchema,\n questionFormMdx,\n visualQuestionsSchema,\n visualQuestionsMdx,\n type QuestionFormData,\n type QuestionFormOption,\n type QuestionFormQuestion,\n type QuestionMode,\n type VisualQuestionsData,\n} from \"./question-form.config.js\";\n\n/**\n * Shared `question-form` and `visual-questions` blocks. A respondent-facing\n * intake form: single/multi/freeform questions, recommended options, optional\n * write-in answers, and optional inline wireframe/diagram previews per option.\n * Lives in core so any app can register it (it originated in the plan template).\n *\n * The block stays app-agnostic:\n * - It is shadcn-free. The \"Send to agent\" affordance uses `ctx.renderEditSurface`\n * (the app-provided popover primitive); when no surface is wired it falls back\n * to a plain button that submits directly.\n * - Submission routes through `ctx.onQuestionFormSubmit` so each app wires its own\n * destination (plan posts the summary into the side agent). The readable summary\n * string is built generically here from questions + collected answers.\n * - Per-option `wireframe`/`diagram` previews render through `ctx.renderBlock`\n * (the same nested-block seam tabs/columns use), so core never imports an app's\n * wireframe or diagram renderer.\n * - Colors map to shadcn theme tokens (`text-muted-foreground`, `border-border`,\n * `bg-background`, `bg-card`, `primary`). The root section carries BOTH the\n * app-neutral `an-questions-block` class and the legacy `plan-questions-block`\n * class so plan renders byte-identically while other apps get the theme treatment.\n */\n\n/**\n * `ctx.onQuestionFormSubmit` is the documented submit hook. It is read off the\n * render context as an optional extra so a host that has not yet added it to its\n * provider degrades to a no-op (the button disables) rather than throwing.\n */\ntype QuestionFormSubmitCtx = BlockRenderContext & {\n onQuestionFormSubmit?: (summary: string) => void;\n};\n\n/**\n * Reviewer answers are transient and never persisted on block data — they live\n * in local component state keyed by question id. `freeform` → a string;\n * `single`/`multi` → selected option ids (with an optional write-in `text`).\n */\ntype QuestionAnswer = { text?: string; selected?: string[] };\ntype QuestionAnswers = Record<string, QuestionAnswer>;\n\nfunction isAnswered(\n question: QuestionFormQuestion,\n answer?: QuestionAnswer,\n): boolean {\n if (question.mode === \"freeform\") return Boolean(answer?.text?.trim());\n return Boolean(answer?.selected?.length || answer?.text?.trim());\n}\n\n/**\n * Build a readable, agent-ready summary string from the questions + collected\n * answers. Generic replacement for the plan-specific `summarizeQuestionForm`.\n */\nfunction summarizeAnswers(\n blockId: string | undefined,\n blockTitle: string | undefined,\n questions: QuestionFormQuestion[],\n answers: QuestionAnswers,\n): string {\n const lines = [\n \"Use these question answers to revise the plan:\",\n blockId ? `Question block: ${blockId}` : \"\",\n blockTitle ? `Section: ${blockTitle}` : \"\",\n \"\",\n ].filter((line) => line !== \"\");\n for (const question of questions) {\n const answer = answers[question.id];\n const selectedLabels =\n question.options\n ?.filter((option) => answer?.selected?.includes(option.id))\n .map((option) => option.label) ?? [];\n const other = answer?.text?.trim();\n const value =\n question.mode === \"freeform\"\n ? other\n : [...selectedLabels, ...(other ? [`Other: ${other}`] : [])].join(\", \");\n lines.push(`- ${question.title}: ${value || \"No answer yet\"}`);\n }\n return lines.join(\"\\n\");\n}\n\n/** Render an inline preview (wireframe or diagram) through the app's dispatcher. */\nfunction OptionVisual({\n type,\n data,\n blockId,\n ctx,\n}: {\n type: \"wireframe\" | \"diagram\";\n data: unknown;\n blockId: string;\n ctx: BlockRenderContext;\n}) {\n if (!data || !ctx.renderBlock) return null;\n const block: NestedBlock = {\n id: `${blockId}-${type}`,\n type,\n data,\n };\n return (\n <>{ctx.renderBlock({ block, editing: false, compactVisuals: true })}</>\n );\n}\n\nfunction QuestionView({\n question,\n index,\n answer,\n blockId,\n ctx,\n onAnswer,\n}: {\n question: QuestionFormQuestion;\n index: number;\n answer?: QuestionAnswer;\n blockId: string;\n ctx: BlockRenderContext;\n onAnswer: (answer: QuestionAnswer) => void;\n}) {\n const selected = answer?.selected ?? [];\n const hasVisualOptions = Boolean(\n question.options?.some((option) => option.wireframe || option.diagram),\n );\n return (\n <article className=\"grid gap-4 sm:grid-cols-[36px_minmax(0,1fr)]\">\n <div className=\"flex size-7 items-center justify-center rounded-full border border-border bg-card text-xs font-semibold text-muted-foreground\">\n {index + 1}\n </div>\n <div>\n <h3 className=\"text-lg font-semibold leading-7 text-foreground\">\n {question.title}\n </h3>\n {question.subtitle && (\n <p className=\"mt-1.5 max-w-3xl text-sm leading-6 text-muted-foreground\">\n {question.subtitle}\n </p>\n )}\n {question.mode === \"freeform\" ? (\n <textarea\n value={answer?.text ?? \"\"}\n onChange={(event) => onAnswer({ text: event.target.value })}\n className=\"mt-4 min-h-28 w-full rounded-xl border border-border bg-card px-3 py-2 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring\"\n data-plan-interactive\n placeholder={question.placeholder || \"Add details...\"}\n />\n ) : (\n <div\n className={cn(\n \"mt-4\",\n hasVisualOptions\n ? \"grid gap-4 md:grid-cols-2\"\n : \"grid max-w-4xl gap-3\",\n )}\n >\n {question.options?.map((option) => {\n const isSelected = selected.includes(option.id);\n return (\n <button\n key={option.id}\n type=\"button\"\n data-plan-interactive\n aria-pressed={isSelected}\n className={cn(\n hasVisualOptions\n ? \"grid gap-4 rounded-xl border border-border bg-card p-4 text-left transition-colors hover:bg-accent/30\"\n : \"grid w-full gap-2 rounded-xl border border-border bg-card px-4 py-3 text-left text-foreground transition-colors hover:border-primary/40 hover:bg-accent/30\",\n isSelected && \"border-primary/40 bg-primary/10\",\n )}\n onClick={() => {\n if (question.mode === \"single\") {\n onAnswer({ ...answer, selected: [option.id] });\n return;\n }\n onAnswer({\n ...answer,\n selected: isSelected\n ? selected.filter((id) => id !== option.id)\n : [...selected, option.id],\n });\n }}\n >\n <div className=\"flex min-w-0 items-start gap-3\">\n <span\n className={cn(\n \"mt-0.5 flex size-5 shrink-0 items-center justify-center border\",\n question.mode === \"single\" ? \"rounded-full\" : \"rounded\",\n isSelected\n ? \"border-primary bg-primary text-primary-foreground\"\n : \"border-border\",\n )}\n >\n {isSelected && <IconCheck className=\"size-3.5\" />}\n </span>\n <span>\n <span className=\"text-base font-semibold leading-6 text-foreground\">\n {option.label}\n </span>\n {option.recommended && (\n <>\n {\" \"}\n <span className=\"ml-3 rounded-md border border-primary/30 px-2 py-0.5 align-middle text-[11px] font-medium uppercase tracking-[0.12em] text-primary\">\n Recommended\n </span>\n </>\n )}\n {option.detail && (\n <span className=\"mt-1 block max-w-2xl whitespace-pre-line text-sm font-normal leading-6 text-muted-foreground\">\n {option.detail}\n </span>\n )}\n </span>\n </div>\n {hasVisualOptions && (option.wireframe || option.diagram) && (\n <div className=\"ml-8 grid gap-4 lg:grid-cols-[minmax(0,1fr)_280px]\">\n {option.wireframe != null && (\n <OptionVisual\n type=\"wireframe\"\n data={option.wireframe}\n blockId={`${blockId}-${option.id}`}\n ctx={ctx}\n />\n )}\n {option.diagram != null && (\n <OptionVisual\n type=\"diagram\"\n data={option.diagram}\n blockId={`${blockId}-${option.id}`}\n ctx={ctx}\n />\n )}\n </div>\n )}\n </button>\n );\n })}\n {/* Multiple-choice questions always offer a write-in answer so a\n reviewer can give a custom response instead of the listed\n options. Authors opt out only by setting allowOther: false. */}\n {question.allowOther !== false && (\n <input\n value={answer?.text ?? \"\"}\n onChange={(event) =>\n onAnswer({ ...answer, text: event.target.value })\n }\n className={cn(\n \"h-10 w-full rounded-lg border border-border bg-card px-4 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring\",\n hasVisualOptions ? \"md:col-span-2\" : \"sm:w-80\",\n )}\n data-plan-interactive\n placeholder={\n question.placeholder || \"Other — type your own answer…\"\n }\n />\n )}\n </div>\n )}\n </div>\n </article>\n );\n}\n\n/** The \"Send to agent\" affordance: a popover (via the app surface) when wired. */\nfunction SubmitMenu({\n blockId,\n ctx,\n onSubmit,\n buildSummary,\n}: {\n blockId: string;\n ctx: BlockRenderContext;\n onSubmit?: (summary: string) => void;\n buildSummary: () => string;\n}) {\n const [open, setOpen] = useState(false);\n const trigger = (\n <button\n type=\"button\"\n data-plan-interactive\n className=\"inline-flex h-9 shrink-0 items-center gap-1.5 rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90\"\n >\n Send to agent\n <IconChevronDown className=\"size-3.5 opacity-70\" />\n </button>\n );\n\n const menu = (\n <div className=\"grid gap-1\">\n <div className=\"px-1 py-1 text-xs font-semibold text-muted-foreground\">\n Send feedback\n </div>\n <button\n type=\"button\"\n data-plan-interactive\n disabled={!onSubmit}\n onClick={() => {\n onSubmit?.(buildSummary());\n setOpen(false);\n }}\n className=\"grid grid-cols-[auto_1fr] items-start gap-2 rounded-md px-2 py-2 text-left text-sm text-foreground transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <IconSend className=\"mt-0.5 size-4\" />\n <span className=\"grid gap-0.5\">\n <span>Send to inline agent</span>\n <span className=\"text-xs font-normal leading-4 text-muted-foreground\">\n Posts answered questions into the app side agent.\n </span>\n </span>\n </button>\n <button\n type=\"button\"\n data-plan-interactive\n onClick={() => {\n void navigator.clipboard.writeText(buildSummary());\n setOpen(false);\n }}\n className=\"grid grid-cols-[auto_1fr] items-start gap-2 rounded-md px-2 py-2 text-left text-sm text-foreground transition-colors hover:bg-accent\"\n >\n <IconClipboardText className=\"mt-0.5 size-4\" />\n <span className=\"grid gap-0.5\">\n <span>Copy for your agent</span>\n <span className=\"text-xs font-normal leading-4 text-muted-foreground\">\n Copies a prompt you can paste into chat.\n </span>\n </span>\n </button>\n </div>\n );\n\n // Prefer the app-provided popover surface (shadcn Popover in plan/content);\n // core stays shadcn-free. Without a surface, fall back to a single button that\n // submits directly so the form still works.\n const surface = ctx.renderEditSurface?.({\n title: \"Send to agent\",\n open,\n onOpenChange: setOpen,\n blockId,\n blockType: \"question-form\",\n trigger,\n children: menu,\n });\n if (surface) return <>{surface}</>;\n\n return (\n <button\n type=\"button\"\n data-plan-interactive\n disabled={!onSubmit}\n onClick={() => onSubmit?.(buildSummary())}\n className=\"inline-flex h-9 shrink-0 items-center gap-1.5 rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n Send to agent\n </button>\n );\n}\n\n/** Shared read renderer for both `question-form` and `visual-questions`. */\nfunction QuestionFormReadInner({\n data,\n blockId,\n title,\n ctx,\n}: BlockReadProps<QuestionFormData>) {\n const questions = data.questions;\n const [answers, setAnswers] = useState<QuestionAnswers>({});\n const submitCtx = ctx as QuestionFormSubmitCtx;\n\n useEffect(() => {\n setAnswers({});\n }, [blockId]);\n\n const setAnswer = (questionId: string, next: QuestionAnswer) => {\n setAnswers((current) => ({ ...current, [questionId]: next }));\n };\n\n const answered = questions.filter((question) =>\n isAnswered(question, answers[question.id]),\n ).length;\n const buildSummary = () =>\n summarizeAnswers(blockId, title, questions, answers);\n\n return (\n <section\n className=\"an-questions-block plan-questions-block\"\n data-block-id={blockId}\n >\n {title && (\n <h2 className=\"text-[1.45rem] font-semibold leading-tight text-foreground\">\n {title}\n </h2>\n )}\n <div className=\"mt-7 grid gap-8\">\n {questions.map((question, index) => (\n <QuestionView\n key={question.id}\n question={question}\n index={index}\n answer={answers[question.id]}\n blockId={blockId}\n ctx={ctx}\n onAnswer={(next) => setAnswer(question.id, next)}\n />\n ))}\n </div>\n <div className=\"sticky bottom-0 mt-10 flex items-center justify-between gap-4 border-t border-border bg-background py-4 backdrop-blur\">\n <p className=\"text-sm font-semibold text-muted-foreground\">\n {answered}/{questions.length} answered\n </p>\n <div data-plan-interactive>\n <SubmitMenu\n blockId={blockId}\n ctx={ctx}\n onSubmit={submitCtx.onQuestionFormSubmit}\n buildSummary={buildSummary}\n />\n </div>\n </div>\n </section>\n );\n}\n\nexport function QuestionFormRead(props: BlockReadProps<QuestionFormData>) {\n return <QuestionFormReadInner {...props} />;\n}\n\nexport function VisualQuestionsRead(\n props: BlockReadProps<VisualQuestionsData>,\n) {\n return <QuestionFormReadInner {...props} />;\n}\n\nconst inlineInputClass =\n \"w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground shadow-sm outline-none transition-colors placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring\";\nconst inlineTextareaClass =\n \"w-full resize-y rounded-md border border-border bg-background px-3 py-2 text-sm leading-6 text-foreground shadow-sm outline-none transition-colors placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring\";\nconst inlineLabelClass =\n \"text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground\";\n\nfunction newLocalId(prefix: string): string {\n return `${prefix}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/** Shared editor for both `question-form` and `visual-questions`. */\nexport function QuestionFormEdit({\n data,\n onChange,\n editable,\n}: BlockEditProps<QuestionFormData>) {\n const updateQuestion = (\n questionId: string,\n patch: Partial<QuestionFormQuestion>,\n ) =>\n onChange({\n ...data,\n questions: data.questions.map((question) =>\n question.id === questionId ? { ...question, ...patch } : question,\n ),\n });\n\n const addQuestion = () => {\n if (data.questions.length >= 40) return;\n onChange({\n ...data,\n questions: [\n ...data.questions,\n {\n id: newLocalId(\"question\"),\n title: \"New question\",\n mode: \"freeform\",\n placeholder: \"Type an answer...\",\n },\n ],\n });\n };\n\n const removeQuestion = (questionId: string) => {\n if (data.questions.length <= 1) return;\n onChange({\n ...data,\n questions: data.questions.filter(\n (question) => question.id !== questionId,\n ),\n });\n };\n\n const setQuestionMode = (\n question: QuestionFormQuestion,\n mode: QuestionMode,\n ) =>\n updateQuestion(question.id, {\n mode,\n options:\n mode === \"freeform\"\n ? question.options\n : question.options && question.options.length > 0\n ? question.options\n : [\n { id: newLocalId(\"option\"), label: \"Option A\" },\n { id: newLocalId(\"option\"), label: \"Option B\" },\n ],\n });\n\n const updateOption = (\n questionId: string,\n optionId: string,\n patch: Partial<QuestionFormOption>,\n ) =>\n onChange({\n ...data,\n questions: data.questions.map((question) =>\n question.id === questionId\n ? {\n ...question,\n options: (question.options ?? []).map((option) =>\n option.id === optionId ? { ...option, ...patch } : option,\n ),\n }\n : question,\n ),\n });\n\n const addOption = (questionId: string) =>\n onChange({\n ...data,\n questions: data.questions.map((question) =>\n question.id === questionId && (question.options?.length ?? 0) < 40\n ? {\n ...question,\n options: [\n ...(question.options ?? []),\n { id: newLocalId(\"option\"), label: \"New option\" },\n ],\n }\n : question,\n ),\n });\n\n const removeOption = (questionId: string, optionId: string) =>\n onChange({\n ...data,\n questions: data.questions.map((question) => {\n if (question.id !== questionId) return question;\n const nextOptions = (question.options ?? []).filter(\n (option) => option.id !== optionId,\n );\n return { ...question, options: nextOptions };\n }),\n });\n\n return (\n <div className=\"grid gap-6\" data-plan-interactive>\n <div className=\"grid gap-4\">\n {data.questions.map((question, index) => {\n const options = question.options ?? [];\n return (\n <article\n key={question.id}\n className=\"rounded-lg border border-border bg-card p-4\"\n >\n <div className=\"mb-4 flex items-center justify-between gap-3\">\n <span className={inlineLabelClass}>Question {index + 1}</span>\n {data.questions.length > 1 && (\n <button\n type=\"button\"\n aria-label={`Delete question ${index + 1}`}\n className=\"inline-flex size-8 items-center justify-center rounded-md border border-border text-muted-foreground hover:bg-muted hover:text-foreground\"\n disabled={!editable}\n onClick={() => removeQuestion(question.id)}\n >\n <IconTrash className=\"size-4\" />\n </button>\n )}\n </div>\n <div className=\"grid gap-3 md:grid-cols-[minmax(0,1fr)_12rem]\">\n <label className=\"grid gap-1.5\">\n <span className={inlineLabelClass}>Title</span>\n <input\n className={inlineInputClass}\n value={question.title}\n disabled={!editable}\n onChange={(event) =>\n updateQuestion(question.id, {\n title: event.target.value,\n })\n }\n />\n </label>\n <label className=\"grid gap-1.5\">\n <span className={inlineLabelClass}>Mode</span>\n <select\n className={inlineInputClass}\n value={question.mode}\n disabled={!editable}\n onChange={(event) =>\n setQuestionMode(\n question,\n event.target.value as QuestionMode,\n )\n }\n >\n <option value=\"freeform\">Freeform</option>\n <option value=\"single\">Single choice</option>\n <option value=\"multi\">Multi choice</option>\n </select>\n </label>\n </div>\n <label className=\"mt-3 grid gap-1.5\">\n <span className={inlineLabelClass}>Subtitle</span>\n <textarea\n className={inlineTextareaClass}\n rows={2}\n value={question.subtitle ?? \"\"}\n disabled={!editable}\n onChange={(event) =>\n updateQuestion(question.id, {\n subtitle: event.target.value || undefined,\n })\n }\n />\n </label>\n <div className=\"mt-3 grid gap-3 md:grid-cols-[minmax(0,1fr)_auto_auto]\">\n <label className=\"grid gap-1.5\">\n <span className={inlineLabelClass}>Placeholder</span>\n <input\n className={inlineInputClass}\n value={question.placeholder ?? \"\"}\n disabled={!editable}\n onChange={(event) =>\n updateQuestion(question.id, {\n placeholder: event.target.value || undefined,\n })\n }\n />\n </label>\n <label className=\"flex items-end gap-2 text-sm font-semibold text-muted-foreground\">\n <input\n type=\"checkbox\"\n className=\"mb-2 size-4\"\n checked={Boolean(question.required)}\n disabled={!editable}\n onChange={(event) =>\n updateQuestion(question.id, {\n required: event.target.checked || undefined,\n })\n }\n />\n Required\n </label>\n {question.mode !== \"freeform\" && (\n <label className=\"flex items-end gap-2 text-sm font-semibold text-muted-foreground\">\n <input\n type=\"checkbox\"\n className=\"mb-2 size-4\"\n checked={question.allowOther !== false}\n disabled={!editable}\n onChange={(event) =>\n updateQuestion(question.id, {\n allowOther: event.target.checked ? undefined : false,\n })\n }\n />\n Allow write-in\n </label>\n )}\n </div>\n {question.mode !== \"freeform\" && (\n <div className=\"mt-4 grid gap-3\">\n {options.map((option) => (\n <div\n key={option.id}\n className=\"grid gap-3 rounded-md border border-border/80 bg-background p-3 md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_auto]\"\n >\n <label className=\"grid gap-1.5\">\n <span className={inlineLabelClass}>Option</span>\n <input\n className={inlineInputClass}\n value={option.label}\n disabled={!editable}\n onChange={(event) =>\n updateOption(question.id, option.id, {\n label: event.target.value,\n })\n }\n />\n </label>\n <label className=\"grid gap-1.5\">\n <span className={inlineLabelClass}>Detail</span>\n <input\n className={inlineInputClass}\n value={option.detail ?? \"\"}\n disabled={!editable}\n onChange={(event) =>\n updateOption(question.id, option.id, {\n detail: event.target.value || undefined,\n })\n }\n />\n </label>\n <div className=\"flex items-end gap-2\">\n <button\n type=\"button\"\n className={cn(\n \"inline-flex h-9 items-center gap-1.5 rounded-md border border-border px-3 text-sm font-semibold text-muted-foreground hover:bg-muted hover:text-foreground\",\n option.recommended && \"border-ring text-foreground\",\n )}\n disabled={!editable}\n onClick={() =>\n updateOption(question.id, option.id, {\n recommended: !option.recommended,\n })\n }\n >\n {option.recommended && (\n <IconCheck className=\"size-4\" />\n )}\n Recommended\n </button>\n {options.length > 1 && (\n <button\n type=\"button\"\n aria-label={`Delete ${option.label}`}\n className=\"inline-flex size-9 items-center justify-center rounded-md border border-border text-muted-foreground hover:bg-muted hover:text-foreground\"\n disabled={!editable}\n onClick={() => removeOption(question.id, option.id)}\n >\n <IconTrash className=\"size-4\" />\n </button>\n )}\n </div>\n </div>\n ))}\n <button\n type=\"button\"\n className=\"inline-flex h-9 w-fit items-center gap-1.5 rounded-md border border-border px-3 text-sm font-semibold text-muted-foreground hover:bg-muted hover:text-foreground\"\n disabled={!editable || options.length >= 40}\n onClick={() => addOption(question.id)}\n >\n <IconPlus className=\"size-4\" />\n Add option\n </button>\n </div>\n )}\n </article>\n );\n })}\n </div>\n <button\n type=\"button\"\n className=\"inline-flex h-9 w-fit items-center gap-1.5 rounded-md border border-border px-3 text-sm font-semibold text-muted-foreground hover:bg-muted hover:text-foreground\"\n disabled={!editable || data.questions.length >= 40}\n onClick={addQuestion}\n >\n <IconPlus className=\"size-4\" />\n Add question\n </button>\n </div>\n );\n}\n\n/**\n * Full client spec for the shared `question-form` block. A respondent-facing\n * intake form edited from the block panel (the schema-ish question shape lives\n * behind the edit surface, not inline).\n */\nexport const questionFormBlock = defineBlock<QuestionFormData>({\n type: \"question-form\",\n schema: questionFormSchema,\n mdx: questionFormMdx,\n Read: QuestionFormRead,\n Edit: QuestionFormEdit,\n placement: [\"block\"],\n editSurface: \"panel\",\n label: \"Question form\",\n description:\n \"An interactive respondent-facing form block for open questions, single-choice or multi-choice option rows, freeform answers, recommended options, and optional wireframe/diagram previews. Edit the question schema from the block panel.\",\n empty: () => ({\n submitLabel: \"Send to agent\",\n questions: [\n {\n id: \"open-question\",\n title: \"What should the agent clarify before revising this plan?\",\n mode: \"freeform\",\n placeholder: \"Add constraints, preferences, or a decision...\",\n },\n ],\n }),\n});\n\n/**\n * Full client spec for the shared `visual-questions` block — the same form UI\n * and data shape as `question-form`, branded for explicit visual intake before a\n * plan. Shares the Read/Edit internals; only the type, MDX tag, label, and seed\n * differ.\n */\nexport const visualQuestionsBlock = defineBlock<VisualQuestionsData>({\n type: \"visual-questions\",\n schema: visualQuestionsSchema,\n mdx: visualQuestionsMdx,\n Read: VisualQuestionsRead,\n Edit: QuestionFormEdit,\n placement: [\"block\"],\n editSurface: \"panel\",\n label: \"Visual questions\",\n description:\n \"A visual-intake question block that renders the respondent-facing question UI (single/multi/freeform, recommended options, inline wireframe/diagram previews) and keeps schema editing in the block panel.\",\n empty: () => ({\n submitLabel: \"Send to agent\",\n questions: [\n {\n id: \"visual-question\",\n title: \"Which direction should this plan take?\",\n mode: \"single\",\n options: [\n {\n id: \"option-a\",\n label: \"Direction A\",\n detail: \"Keep the current shape and refine it.\",\n recommended: true,\n },\n {\n id: \"option-b\",\n label: \"Direction B\",\n detail: \"Try a larger structural revision.\",\n },\n ],\n allowOther: true,\n },\n ],\n }),\n});\n"]}
1
+ {"version":3,"file":"question-form.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/question-form.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useState } from \"react\";\nimport {\n IconCheck,\n IconChevronDown,\n IconClipboardText,\n IconPlus,\n IconSend,\n IconTrash,\n} from \"@tabler/icons-react\";\nimport { cn } from \"../../utils.js\";\nimport { defineBlock } from \"../types.js\";\nimport type {\n BlockReadProps,\n BlockEditProps,\n BlockRenderContext,\n NestedBlock,\n} from \"../types.js\";\nimport {\n questionFormSchema,\n questionFormMdx,\n visualQuestionsSchema,\n visualQuestionsMdx,\n type QuestionFormData,\n type QuestionFormOption,\n type QuestionFormQuestion,\n type QuestionMode,\n type VisualQuestionsData,\n} from \"./question-form.config.js\";\n\n/**\n * Shared `question-form` and `visual-questions` blocks. A respondent-facing\n * intake form: single/multi/freeform questions, recommended options, optional\n * write-in answers, and optional inline wireframe/diagram previews per option.\n * Lives in core so any app can register it (it originated in the plan template).\n *\n * The block stays app-agnostic:\n * - It is shadcn-free. The \"Send to agent\" affordance uses `ctx.renderEditSurface`\n * (the app-provided popover primitive); when no surface is wired it falls back\n * to a plain button that submits directly.\n * - Submission routes through `ctx.onQuestionFormSubmit` so each app wires its own\n * destination (plan posts the summary into the side agent). The readable summary\n * string is built generically here from questions + collected answers.\n * - Per-option `wireframe`/`diagram` previews render through `ctx.renderBlock`\n * (the same nested-block seam tabs/columns use), so core never imports an app's\n * wireframe or diagram renderer.\n * - Colors map to shadcn theme tokens (`text-muted-foreground`, `border-border`,\n * `bg-background`, `bg-card`, `primary`). The root section carries BOTH the\n * app-neutral `an-questions-block` class and the legacy `plan-questions-block`\n * class so plan renders byte-identically while other apps get the theme treatment.\n */\n\n/**\n * `ctx.onQuestionFormSubmit` is the documented submit hook. It is read off the\n * render context as an optional extra so a host that has not yet added it to its\n * provider degrades to a no-op (the button disables) rather than throwing.\n */\ntype QuestionFormSubmitCtx = BlockRenderContext & {\n onQuestionFormSubmit?: (summary: string) => void;\n};\n\n/**\n * Reviewer answers are transient and never persisted on block data — they live\n * in local component state keyed by question id. `freeform` → a string;\n * `single`/`multi` → selected option ids (with an optional write-in `text`).\n */\ntype QuestionAnswer = { text?: string; selected?: string[] };\ntype QuestionAnswers = Record<string, QuestionAnswer>;\n\nfunction isAnswered(\n question: QuestionFormQuestion,\n answer?: QuestionAnswer,\n): boolean {\n if (question.mode === \"freeform\") return Boolean(answer?.text?.trim());\n return Boolean(answer?.selected?.length || answer?.text?.trim());\n}\n\n/**\n * Build a readable, agent-ready summary string from the questions + collected\n * answers. Generic replacement for the plan-specific `summarizeQuestionForm`.\n */\nfunction summarizeAnswers(\n blockId: string | undefined,\n blockTitle: string | undefined,\n questions: QuestionFormQuestion[],\n answers: QuestionAnswers,\n): string {\n const lines = [\n \"Use these question answers to revise the plan:\",\n blockId ? `Question block: ${blockId}` : \"\",\n blockTitle ? `Section: ${blockTitle}` : \"\",\n \"\",\n ].filter((line) => line !== \"\");\n for (const question of questions) {\n const answer = answers[question.id];\n const selectedLabels =\n question.options\n ?.filter((option) => answer?.selected?.includes(option.id))\n .map((option) => option.label) ?? [];\n const other = answer?.text?.trim();\n const value =\n question.mode === \"freeform\"\n ? other\n : [...selectedLabels, ...(other ? [`Other: ${other}`] : [])].join(\", \");\n lines.push(`- ${question.title}: ${value || \"No answer yet\"}`);\n }\n return lines.join(\"\\n\");\n}\n\n/** Render an inline preview (wireframe or diagram) through the app's dispatcher. */\nfunction OptionVisual({\n type,\n data,\n blockId,\n ctx,\n}: {\n type: \"wireframe\" | \"diagram\";\n data: unknown;\n blockId: string;\n ctx: BlockRenderContext;\n}) {\n if (!data || !ctx.renderBlock) return null;\n const block: NestedBlock = {\n id: `${blockId}-${type}`,\n type,\n data,\n };\n return (\n <>{ctx.renderBlock({ block, editing: false, compactVisuals: true })}</>\n );\n}\n\nfunction QuestionView({\n question,\n index,\n answer,\n blockId,\n ctx,\n onAnswer,\n}: {\n question: QuestionFormQuestion;\n index: number;\n answer?: QuestionAnswer;\n blockId: string;\n ctx: BlockRenderContext;\n onAnswer: (answer: QuestionAnswer) => void;\n}) {\n const selected = answer?.selected ?? [];\n const hasVisualOptions = Boolean(\n question.options?.some((option) => option.wireframe || option.diagram),\n );\n return (\n <article className=\"grid gap-4 sm:grid-cols-[36px_minmax(0,1fr)]\">\n <div className=\"flex size-7 items-center justify-center rounded-full border border-border bg-card text-xs font-semibold text-muted-foreground\">\n {index + 1}\n </div>\n <div>\n <h3 className=\"text-lg font-semibold leading-7 text-foreground\">\n {question.title}\n </h3>\n {question.subtitle && (\n <p className=\"mt-1.5 max-w-3xl text-sm leading-6 text-muted-foreground\">\n {question.subtitle}\n </p>\n )}\n {question.mode === \"freeform\" ? (\n <textarea\n value={answer?.text ?? \"\"}\n onChange={(event) => onAnswer({ text: event.target.value })}\n className=\"mt-4 min-h-28 w-full rounded-xl border border-border bg-card px-3 py-2 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring\"\n data-plan-interactive\n placeholder={question.placeholder || \"Add details...\"}\n />\n ) : (\n <div\n className={cn(\n \"mt-4\",\n hasVisualOptions\n ? \"grid gap-4 md:grid-cols-2\"\n : \"grid max-w-4xl gap-3\",\n )}\n >\n {question.options?.map((option) => {\n const isSelected = selected.includes(option.id);\n return (\n <button\n key={option.id}\n type=\"button\"\n data-plan-interactive\n aria-pressed={isSelected}\n className={cn(\n hasVisualOptions\n ? \"grid gap-4 rounded-xl border border-border bg-card p-4 text-left transition-colors hover:bg-accent/30\"\n : \"grid w-full gap-2 rounded-xl border border-border bg-card px-4 py-3 text-left text-foreground transition-colors hover:border-primary/40 hover:bg-accent/30\",\n isSelected && \"border-primary/40 bg-primary/10\",\n )}\n onClick={() => {\n if (question.mode === \"single\") {\n onAnswer({ ...answer, selected: [option.id] });\n return;\n }\n onAnswer({\n ...answer,\n selected: isSelected\n ? selected.filter((id) => id !== option.id)\n : [...selected, option.id],\n });\n }}\n >\n <div className=\"flex min-w-0 items-start gap-3\">\n <span\n className={cn(\n \"mt-0.5 flex size-5 shrink-0 items-center justify-center border\",\n question.mode === \"single\" ? \"rounded-full\" : \"rounded\",\n isSelected\n ? \"border-primary bg-primary text-primary-foreground\"\n : \"border-border\",\n )}\n >\n {isSelected && <IconCheck className=\"size-3.5\" />}\n </span>\n <span>\n <span className=\"text-base font-semibold leading-6 text-foreground\">\n {option.label}\n </span>\n {option.recommended && (\n <>\n {\" \"}\n <span className=\"ml-3 rounded-md border border-primary/30 px-2 py-0.5 align-middle text-[11px] font-medium uppercase tracking-[0.12em] text-primary\">\n Recommended\n </span>\n </>\n )}\n {option.detail && (\n <span className=\"mt-1 block max-w-2xl whitespace-pre-line text-sm font-normal leading-6 text-muted-foreground\">\n {option.detail}\n </span>\n )}\n </span>\n </div>\n {hasVisualOptions && (option.wireframe || option.diagram) && (\n <div className=\"ml-8 grid gap-4 lg:grid-cols-[minmax(0,1fr)_280px]\">\n {option.wireframe != null && (\n <OptionVisual\n type=\"wireframe\"\n data={option.wireframe}\n blockId={`${blockId}-${option.id}`}\n ctx={ctx}\n />\n )}\n {option.diagram != null && (\n <OptionVisual\n type=\"diagram\"\n data={option.diagram}\n blockId={`${blockId}-${option.id}`}\n ctx={ctx}\n />\n )}\n </div>\n )}\n </button>\n );\n })}\n {/* Multiple-choice questions always offer a write-in answer so a\n reviewer can give a custom response instead of the listed\n options. Authors opt out only by setting allowOther: false. */}\n {question.allowOther !== false && (\n <input\n value={answer?.text ?? \"\"}\n onChange={(event) =>\n onAnswer({ ...answer, text: event.target.value })\n }\n className={cn(\n \"h-10 w-full rounded-lg border border-border bg-card px-4 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring\",\n hasVisualOptions ? \"md:col-span-2\" : \"sm:w-80\",\n )}\n data-plan-interactive\n placeholder={\n question.placeholder || \"Other — type your own answer…\"\n }\n />\n )}\n </div>\n )}\n </div>\n </article>\n );\n}\n\n/** The \"Send to agent\" affordance: a popover (via the app surface) when wired. */\nfunction SubmitMenu({\n ctx,\n onSubmit,\n buildSummary,\n}: {\n ctx: BlockRenderContext;\n onSubmit?: (summary: string) => void;\n buildSummary: () => string;\n}) {\n const [open, setOpen] = useState(false);\n const trigger = (\n <button\n type=\"button\"\n data-plan-interactive\n className=\"inline-flex h-9 shrink-0 items-center gap-1.5 rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90\"\n >\n Send to agent\n <IconChevronDown className=\"size-3.5 opacity-70\" />\n </button>\n );\n\n const menu = (\n <div className=\"grid gap-1\">\n <div className=\"px-1 py-1 text-xs font-semibold text-muted-foreground\">\n Send feedback\n </div>\n <button\n type=\"button\"\n data-plan-interactive\n onClick={() => {\n void navigator.clipboard.writeText(buildSummary());\n setOpen(false);\n }}\n className=\"grid grid-cols-[auto_1fr] items-start gap-2 rounded-md px-2 py-2 text-left text-sm text-foreground transition-colors hover:bg-accent\"\n >\n <IconClipboardText className=\"mt-0.5 size-4\" />\n <span className=\"grid gap-0.5\">\n <span>Copy for your agent</span>\n <span className=\"text-xs font-normal leading-4 text-muted-foreground\">\n Copies a prompt you can paste into chat.\n </span>\n </span>\n </button>\n <button\n type=\"button\"\n data-plan-interactive\n disabled={!onSubmit}\n onClick={() => {\n onSubmit?.(buildSummary());\n setOpen(false);\n }}\n className=\"grid grid-cols-[auto_1fr] items-start gap-2 rounded-md px-2 py-2 text-left text-sm text-foreground transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <IconSend className=\"mt-0.5 size-4\" />\n <span className=\"grid gap-0.5\">\n <span>Send to inline agent</span>\n <span className=\"text-xs font-normal leading-4 text-muted-foreground\">\n Posts answered questions into the app side agent.\n </span>\n </span>\n </button>\n </div>\n );\n\n // Prefer the app-provided popover surface (shadcn Popover in plan/content);\n // core stays shadcn-free. Without a surface, fall back to a single button that\n // submits directly so the form still works.\n const surface = ctx.renderEditSurface?.({\n title: \"Send to agent\",\n open,\n onOpenChange: setOpen,\n variant: \"menu\",\n trigger,\n children: menu,\n });\n if (surface) return <>{surface}</>;\n\n return (\n <button\n type=\"button\"\n data-plan-interactive\n disabled={!onSubmit}\n onClick={() => onSubmit?.(buildSummary())}\n className=\"inline-flex h-9 shrink-0 items-center gap-1.5 rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n Send to agent\n </button>\n );\n}\n\n/** Shared read renderer for both `question-form` and `visual-questions`. */\nfunction QuestionFormReadInner({\n data,\n blockId,\n title,\n ctx,\n}: BlockReadProps<QuestionFormData>) {\n const questions = data.questions;\n const [answers, setAnswers] = useState<QuestionAnswers>({});\n const submitCtx = ctx as QuestionFormSubmitCtx;\n\n useEffect(() => {\n setAnswers({});\n }, [blockId]);\n\n const setAnswer = (questionId: string, next: QuestionAnswer) => {\n setAnswers((current) => ({ ...current, [questionId]: next }));\n };\n\n const answered = questions.filter((question) =>\n isAnswered(question, answers[question.id]),\n ).length;\n const buildSummary = () =>\n summarizeAnswers(blockId, title, questions, answers);\n\n return (\n <section\n className=\"an-questions-block plan-questions-block\"\n data-block-id={blockId}\n >\n {title && (\n <h2 className=\"text-[1.45rem] font-semibold leading-tight text-foreground\">\n {title}\n </h2>\n )}\n <div className=\"mt-7 grid gap-8\">\n {questions.map((question, index) => (\n <QuestionView\n key={question.id}\n question={question}\n index={index}\n answer={answers[question.id]}\n blockId={blockId}\n ctx={ctx}\n onAnswer={(next) => setAnswer(question.id, next)}\n />\n ))}\n </div>\n <div className=\"sticky bottom-0 mt-10 flex items-center justify-between gap-4 border-t border-border py-4\">\n <p className=\"text-sm font-semibold text-muted-foreground\">\n {answered}/{questions.length} answered\n </p>\n <div data-plan-interactive>\n <SubmitMenu\n ctx={ctx}\n onSubmit={submitCtx.onQuestionFormSubmit}\n buildSummary={buildSummary}\n />\n </div>\n </div>\n </section>\n );\n}\n\nexport function QuestionFormRead(props: BlockReadProps<QuestionFormData>) {\n return <QuestionFormReadInner {...props} />;\n}\n\nexport function VisualQuestionsRead(\n props: BlockReadProps<VisualQuestionsData>,\n) {\n return <QuestionFormReadInner {...props} />;\n}\n\nconst inlineInputClass =\n \"w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground shadow-sm outline-none transition-colors placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring\";\nconst inlineTextareaClass =\n \"w-full resize-y rounded-md border border-border bg-background px-3 py-2 text-sm leading-6 text-foreground shadow-sm outline-none transition-colors placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring\";\nconst inlineLabelClass =\n \"text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground\";\n\nfunction newLocalId(prefix: string): string {\n return `${prefix}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/** Shared editor for both `question-form` and `visual-questions`. */\nexport function QuestionFormEdit({\n data,\n onChange,\n editable,\n}: BlockEditProps<QuestionFormData>) {\n const updateQuestion = (\n questionId: string,\n patch: Partial<QuestionFormQuestion>,\n ) =>\n onChange({\n ...data,\n questions: data.questions.map((question) =>\n question.id === questionId ? { ...question, ...patch } : question,\n ),\n });\n\n const addQuestion = () => {\n if (data.questions.length >= 40) return;\n onChange({\n ...data,\n questions: [\n ...data.questions,\n {\n id: newLocalId(\"question\"),\n title: \"New question\",\n mode: \"freeform\",\n placeholder: \"Type an answer...\",\n },\n ],\n });\n };\n\n const removeQuestion = (questionId: string) => {\n if (data.questions.length <= 1) return;\n onChange({\n ...data,\n questions: data.questions.filter(\n (question) => question.id !== questionId,\n ),\n });\n };\n\n const setQuestionMode = (\n question: QuestionFormQuestion,\n mode: QuestionMode,\n ) =>\n updateQuestion(question.id, {\n mode,\n options:\n mode === \"freeform\"\n ? question.options\n : question.options && question.options.length > 0\n ? question.options\n : [\n { id: newLocalId(\"option\"), label: \"Option A\" },\n { id: newLocalId(\"option\"), label: \"Option B\" },\n ],\n });\n\n const updateOption = (\n questionId: string,\n optionId: string,\n patch: Partial<QuestionFormOption>,\n ) =>\n onChange({\n ...data,\n questions: data.questions.map((question) =>\n question.id === questionId\n ? {\n ...question,\n options: (question.options ?? []).map((option) =>\n option.id === optionId ? { ...option, ...patch } : option,\n ),\n }\n : question,\n ),\n });\n\n const addOption = (questionId: string) =>\n onChange({\n ...data,\n questions: data.questions.map((question) =>\n question.id === questionId && (question.options?.length ?? 0) < 40\n ? {\n ...question,\n options: [\n ...(question.options ?? []),\n { id: newLocalId(\"option\"), label: \"New option\" },\n ],\n }\n : question,\n ),\n });\n\n const removeOption = (questionId: string, optionId: string) =>\n onChange({\n ...data,\n questions: data.questions.map((question) => {\n if (question.id !== questionId) return question;\n const nextOptions = (question.options ?? []).filter(\n (option) => option.id !== optionId,\n );\n return { ...question, options: nextOptions };\n }),\n });\n\n return (\n <div className=\"grid gap-6\" data-plan-interactive>\n <div className=\"grid gap-4\">\n {data.questions.map((question, index) => {\n const options = question.options ?? [];\n return (\n <article\n key={question.id}\n className=\"rounded-lg border border-border bg-card p-4\"\n >\n <div className=\"mb-4 flex items-center justify-between gap-3\">\n <span className={inlineLabelClass}>Question {index + 1}</span>\n {data.questions.length > 1 && (\n <button\n type=\"button\"\n aria-label={`Delete question ${index + 1}`}\n className=\"inline-flex size-8 items-center justify-center rounded-md border border-border text-muted-foreground hover:bg-muted hover:text-foreground\"\n disabled={!editable}\n onClick={() => removeQuestion(question.id)}\n >\n <IconTrash className=\"size-4\" />\n </button>\n )}\n </div>\n <div className=\"grid gap-3 md:grid-cols-[minmax(0,1fr)_12rem]\">\n <label className=\"grid gap-1.5\">\n <span className={inlineLabelClass}>Title</span>\n <input\n className={inlineInputClass}\n value={question.title}\n disabled={!editable}\n onChange={(event) =>\n updateQuestion(question.id, {\n title: event.target.value,\n })\n }\n />\n </label>\n <label className=\"grid gap-1.5\">\n <span className={inlineLabelClass}>Mode</span>\n <select\n className={inlineInputClass}\n value={question.mode}\n disabled={!editable}\n onChange={(event) =>\n setQuestionMode(\n question,\n event.target.value as QuestionMode,\n )\n }\n >\n <option value=\"freeform\">Freeform</option>\n <option value=\"single\">Single choice</option>\n <option value=\"multi\">Multi choice</option>\n </select>\n </label>\n </div>\n <label className=\"mt-3 grid gap-1.5\">\n <span className={inlineLabelClass}>Subtitle</span>\n <textarea\n className={inlineTextareaClass}\n rows={2}\n value={question.subtitle ?? \"\"}\n disabled={!editable}\n onChange={(event) =>\n updateQuestion(question.id, {\n subtitle: event.target.value || undefined,\n })\n }\n />\n </label>\n <div className=\"mt-3 grid gap-3 md:grid-cols-[minmax(0,1fr)_auto_auto]\">\n <label className=\"grid gap-1.5\">\n <span className={inlineLabelClass}>Placeholder</span>\n <input\n className={inlineInputClass}\n value={question.placeholder ?? \"\"}\n disabled={!editable}\n onChange={(event) =>\n updateQuestion(question.id, {\n placeholder: event.target.value || undefined,\n })\n }\n />\n </label>\n <label className=\"flex items-end gap-2 text-sm font-semibold text-muted-foreground\">\n <input\n type=\"checkbox\"\n className=\"mb-2 size-4\"\n checked={Boolean(question.required)}\n disabled={!editable}\n onChange={(event) =>\n updateQuestion(question.id, {\n required: event.target.checked || undefined,\n })\n }\n />\n Required\n </label>\n {question.mode !== \"freeform\" && (\n <label className=\"flex items-end gap-2 text-sm font-semibold text-muted-foreground\">\n <input\n type=\"checkbox\"\n className=\"mb-2 size-4\"\n checked={question.allowOther !== false}\n disabled={!editable}\n onChange={(event) =>\n updateQuestion(question.id, {\n allowOther: event.target.checked ? undefined : false,\n })\n }\n />\n Allow write-in\n </label>\n )}\n </div>\n {question.mode !== \"freeform\" && (\n <div className=\"mt-4 grid gap-3\">\n {options.map((option) => (\n <div\n key={option.id}\n className=\"grid gap-3 rounded-md border border-border/80 bg-background p-3 md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_auto]\"\n >\n <label className=\"grid gap-1.5\">\n <span className={inlineLabelClass}>Option</span>\n <input\n className={inlineInputClass}\n value={option.label}\n disabled={!editable}\n onChange={(event) =>\n updateOption(question.id, option.id, {\n label: event.target.value,\n })\n }\n />\n </label>\n <label className=\"grid gap-1.5\">\n <span className={inlineLabelClass}>Detail</span>\n <input\n className={inlineInputClass}\n value={option.detail ?? \"\"}\n disabled={!editable}\n onChange={(event) =>\n updateOption(question.id, option.id, {\n detail: event.target.value || undefined,\n })\n }\n />\n </label>\n <div className=\"flex items-end gap-2\">\n <button\n type=\"button\"\n className={cn(\n \"inline-flex h-9 items-center gap-1.5 rounded-md border border-border px-3 text-sm font-semibold text-muted-foreground hover:bg-muted hover:text-foreground\",\n option.recommended && \"border-ring text-foreground\",\n )}\n disabled={!editable}\n onClick={() =>\n updateOption(question.id, option.id, {\n recommended: !option.recommended,\n })\n }\n >\n {option.recommended && (\n <IconCheck className=\"size-4\" />\n )}\n Recommended\n </button>\n {options.length > 1 && (\n <button\n type=\"button\"\n aria-label={`Delete ${option.label}`}\n className=\"inline-flex size-9 items-center justify-center rounded-md border border-border text-muted-foreground hover:bg-muted hover:text-foreground\"\n disabled={!editable}\n onClick={() => removeOption(question.id, option.id)}\n >\n <IconTrash className=\"size-4\" />\n </button>\n )}\n </div>\n </div>\n ))}\n <button\n type=\"button\"\n className=\"inline-flex h-9 w-fit items-center gap-1.5 rounded-md border border-border px-3 text-sm font-semibold text-muted-foreground hover:bg-muted hover:text-foreground\"\n disabled={!editable || options.length >= 40}\n onClick={() => addOption(question.id)}\n >\n <IconPlus className=\"size-4\" />\n Add option\n </button>\n </div>\n )}\n </article>\n );\n })}\n </div>\n <button\n type=\"button\"\n className=\"inline-flex h-9 w-fit items-center gap-1.5 rounded-md border border-border px-3 text-sm font-semibold text-muted-foreground hover:bg-muted hover:text-foreground\"\n disabled={!editable || data.questions.length >= 40}\n onClick={addQuestion}\n >\n <IconPlus className=\"size-4\" />\n Add question\n </button>\n </div>\n );\n}\n\n/**\n * Full client spec for the shared `question-form` block. A respondent-facing\n * intake form edited from the block panel (the schema-ish question shape lives\n * behind the edit surface, not inline).\n */\nexport const questionFormBlock = defineBlock<QuestionFormData>({\n type: \"question-form\",\n schema: questionFormSchema,\n mdx: questionFormMdx,\n Read: QuestionFormRead,\n Edit: QuestionFormEdit,\n placement: [\"block\"],\n editSurface: \"panel\",\n label: \"Question form\",\n description:\n \"An interactive respondent-facing form block for open questions, single-choice or multi-choice option rows, freeform answers, recommended options, and optional wireframe/diagram previews. Edit the question schema from the block panel.\",\n empty: () => ({\n submitLabel: \"Send to agent\",\n questions: [\n {\n id: \"open-question\",\n title: \"What should the agent clarify before revising this plan?\",\n mode: \"freeform\",\n placeholder: \"Add constraints, preferences, or a decision...\",\n },\n ],\n }),\n});\n\n/**\n * Full client spec for the shared `visual-questions` block — the same form UI\n * and data shape as `question-form`, branded for explicit visual intake before a\n * plan. Shares the Read/Edit internals; only the type, MDX tag, label, and seed\n * differ.\n */\nexport const visualQuestionsBlock = defineBlock<VisualQuestionsData>({\n type: \"visual-questions\",\n schema: visualQuestionsSchema,\n mdx: visualQuestionsMdx,\n Read: VisualQuestionsRead,\n Edit: QuestionFormEdit,\n placement: [\"block\"],\n editSurface: \"panel\",\n label: \"Visual questions\",\n description:\n \"A visual-intake question block that renders the respondent-facing question UI (single/multi/freeform, recommended options, inline wireframe/diagram previews) and keeps schema editing in the block panel.\",\n empty: () => ({\n submitLabel: \"Send to agent\",\n questions: [\n {\n id: \"visual-question\",\n title: \"Which direction should this plan take?\",\n mode: \"single\",\n options: [\n {\n id: \"option-a\",\n label: \"Direction A\",\n detail: \"Keep the current shape and refine it.\",\n recommended: true,\n },\n {\n id: \"option-b\",\n label: \"Direction B\",\n detail: \"Try a larger structural revision.\",\n },\n ],\n allowOther: true,\n },\n ],\n }),\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/tabs.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAEV,cAAc,EACd,cAAc,EAEf,MAAM,aAAa,CAAC;AACrB,OAAO,EAGL,KAAK,QAAQ,EAGd,MAAM,kBAAkB,CAAC;AAuG1B,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,OAAO,EACP,KAAK,EACL,GAAG,GACJ,EAAE,cAAc,CAAC,QAAQ,CAAC,2CAuC1B;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,KAAK,EACL,GAAG,GACJ,EAAE,cAAc,CAAC,QAAQ,CAAC,2CAgM1B;AAuLD;;;;;GAKG;AACH,eAAO,MAAM,SAAS,2CA0BpB,CAAC"}
1
+ {"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/tabs.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAEV,cAAc,EACd,cAAc,EAEf,MAAM,aAAa,CAAC;AACrB,OAAO,EAGL,KAAK,QAAQ,EAGd,MAAM,kBAAkB,CAAC;AAwG1B,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,OAAO,EACP,KAAK,EACL,GAAG,GACJ,EAAE,cAAc,CAAC,QAAQ,CAAC,2CAyC1B;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,KAAK,EACL,GAAG,GACJ,EAAE,cAAc,CAAC,QAAQ,CAAC,2CAgM1B;AAuLD;;;;;GAKG;AACH,eAAO,MAAM,SAAS,2CA0BpB,CAAC"}
@@ -5,6 +5,7 @@ import { cn } from "../../utils.js";
5
5
  import { Popover, PopoverContent, PopoverTrigger, } from "../../components/ui/popover.js";
6
6
  import { defineBlock } from "../types.js";
7
7
  import { tabsSchema, tabsMdx, } from "./tabs.config.js";
8
+ import { NarrowContainerProvider } from "./narrow-container.js";
8
9
  /**
9
10
  * Standard `tabs` block: a horizontal pill-tab container whose tabs each hold a
10
11
  * list of child blocks. Lives in core so any app (plan today, content later) can
@@ -65,11 +66,11 @@ export function TabsBlockReader({ data, blockId, title, ctx, }) {
65
66
  const orientation = tabOrientation(data);
66
67
  const vertical = orientation === "vertical";
67
68
  return (_jsxs("section", { className: "plan-block", "data-block-id": blockId, children: [title && _jsx("div", { className: "plan-block-label", children: title }), _jsx("div", { className: cn(vertical && "@container/tabs"), children: _jsxs("div", { className: cn(vertical &&
68
- "grid min-w-0 gap-5 @xl/tabs:grid-cols-[minmax(10rem,14rem)_minmax(0,1fr)] @xl/tabs:items-start"), children: [_jsx(TabRail, { tabs: data.tabs, activeId: active?.id, onSelect: setActiveId, orientation: orientation }), active && (_jsx("div", { className: cn(vertical && "min-w-0"), children: active.blocks.map((child) => (_jsx("div", { children: ctx.renderBlock?.({
69
- block: child,
70
- editing: false,
71
- compactVisuals: compact,
72
- }) }, child.id))) }))] }) })] }));
69
+ "grid min-w-0 gap-5 @xl/tabs:grid-cols-[minmax(10rem,14rem)_minmax(0,1fr)] @xl/tabs:items-start"), children: [_jsx(TabRail, { tabs: data.tabs, activeId: active?.id, onSelect: setActiveId, orientation: orientation }), active && (_jsx(NarrowContainerProvider, { children: _jsx("div", { className: cn(vertical && "min-w-0"), children: active.blocks.map((child) => (_jsx("div", { children: ctx.renderBlock?.({
70
+ block: child,
71
+ editing: false,
72
+ compactVisuals: compact,
73
+ }) }, child.id))) }) }))] }) })] }));
73
74
  }
74
75
  /**
75
76
  * Editor: pill tabs plus tab management (add/remove/rename), with child blocks