@agent-native/core 0.38.0 → 0.39.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/dist/cli/create.d.ts.map +1 -1
  2. package/dist/cli/create.js +8 -1
  3. package/dist/cli/create.js.map +1 -1
  4. package/dist/cli/index.js +1 -1
  5. package/dist/cli/index.js.map +1 -1
  6. package/dist/cli/skills.d.ts +6 -4
  7. package/dist/cli/skills.d.ts.map +1 -1
  8. package/dist/cli/skills.js +587 -126
  9. package/dist/cli/skills.js.map +1 -1
  10. package/dist/client/blocks/BlockView.d.ts +13 -4
  11. package/dist/client/blocks/BlockView.d.ts.map +1 -1
  12. package/dist/client/blocks/BlockView.js +34 -13
  13. package/dist/client/blocks/BlockView.js.map +1 -1
  14. package/dist/client/blocks/SchemaBlockEditor.d.ts.map +1 -1
  15. package/dist/client/blocks/SchemaBlockEditor.js +96 -3
  16. package/dist/client/blocks/SchemaBlockEditor.js.map +1 -1
  17. package/dist/client/blocks/index.d.ts +18 -1
  18. package/dist/client/blocks/index.d.ts.map +1 -1
  19. package/dist/client/blocks/index.js +26 -1
  20. package/dist/client/blocks/index.js.map +1 -1
  21. package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts +6 -0
  22. package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts.map +1 -0
  23. package/dist/client/blocks/library/AnnotatedCodeBlock.js +135 -0
  24. package/dist/client/blocks/library/AnnotatedCodeBlock.js.map +1 -0
  25. package/dist/client/blocks/library/ApiEndpointBlock.d.ts +20 -0
  26. package/dist/client/blocks/library/ApiEndpointBlock.d.ts.map +1 -0
  27. package/dist/client/blocks/library/ApiEndpointBlock.js +131 -0
  28. package/dist/client/blocks/library/ApiEndpointBlock.js.map +1 -0
  29. package/dist/client/blocks/library/DataModelBlock.d.ts +28 -0
  30. package/dist/client/blocks/library/DataModelBlock.d.ts.map +1 -0
  31. package/dist/client/blocks/library/DataModelBlock.js +222 -0
  32. package/dist/client/blocks/library/DataModelBlock.js.map +1 -0
  33. package/dist/client/blocks/library/DiffBlock.d.ts +6 -0
  34. package/dist/client/blocks/library/DiffBlock.d.ts.map +1 -0
  35. package/dist/client/blocks/library/DiffBlock.js +293 -0
  36. package/dist/client/blocks/library/DiffBlock.js.map +1 -0
  37. package/dist/client/blocks/library/FileTreeBlock.d.ts +23 -0
  38. package/dist/client/blocks/library/FileTreeBlock.d.ts.map +1 -0
  39. package/dist/client/blocks/library/FileTreeBlock.js +225 -0
  40. package/dist/client/blocks/library/FileTreeBlock.js.map +1 -0
  41. package/dist/client/blocks/library/JsonExplorerBlock.d.ts +19 -0
  42. package/dist/client/blocks/library/JsonExplorerBlock.d.ts.map +1 -0
  43. package/dist/client/blocks/library/JsonExplorerBlock.js +171 -0
  44. package/dist/client/blocks/library/JsonExplorerBlock.js.map +1 -0
  45. package/dist/client/blocks/library/MermaidBlock.d.ts +17 -0
  46. package/dist/client/blocks/library/MermaidBlock.d.ts.map +1 -0
  47. package/dist/client/blocks/library/MermaidBlock.js +131 -0
  48. package/dist/client/blocks/library/MermaidBlock.js.map +1 -0
  49. package/dist/client/blocks/library/OpenApiSpecBlock.d.ts +19 -0
  50. package/dist/client/blocks/library/OpenApiSpecBlock.d.ts.map +1 -0
  51. package/dist/client/blocks/library/OpenApiSpecBlock.js +494 -0
  52. package/dist/client/blocks/library/OpenApiSpecBlock.js.map +1 -0
  53. package/dist/client/blocks/library/annotated-code.config.d.ts +58 -0
  54. package/dist/client/blocks/library/annotated-code.config.d.ts.map +1 -0
  55. package/dist/client/blocks/library/annotated-code.config.js +53 -0
  56. package/dist/client/blocks/library/annotated-code.config.js.map +1 -0
  57. package/dist/client/blocks/library/api-endpoint.config.d.ts +71 -0
  58. package/dist/client/blocks/library/api-endpoint.config.d.ts.map +1 -0
  59. package/dist/client/blocks/library/api-endpoint.config.js +91 -0
  60. package/dist/client/blocks/library/api-endpoint.config.js.map +1 -0
  61. package/dist/client/blocks/library/checklist.d.ts.map +1 -1
  62. package/dist/client/blocks/library/checklist.js +3 -1
  63. package/dist/client/blocks/library/checklist.js.map +1 -1
  64. package/dist/client/blocks/library/code-tabs.js +1 -1
  65. package/dist/client/blocks/library/code-tabs.js.map +1 -1
  66. package/dist/client/blocks/library/data-model.config.d.ts +72 -0
  67. package/dist/client/blocks/library/data-model.config.d.ts.map +1 -0
  68. package/dist/client/blocks/library/data-model.config.js +59 -0
  69. package/dist/client/blocks/library/data-model.config.js.map +1 -0
  70. package/dist/client/blocks/library/dev-doc-ui.d.ts +49 -0
  71. package/dist/client/blocks/library/dev-doc-ui.d.ts.map +1 -0
  72. package/dist/client/blocks/library/dev-doc-ui.js +50 -0
  73. package/dist/client/blocks/library/dev-doc-ui.js.map +1 -0
  74. package/dist/client/blocks/library/diff.config.d.ts +41 -0
  75. package/dist/client/blocks/library/diff.config.d.ts.map +1 -0
  76. package/dist/client/blocks/library/diff.config.js +34 -0
  77. package/dist/client/blocks/library/diff.config.js.map +1 -0
  78. package/dist/client/blocks/library/file-tree.config.d.ts +59 -0
  79. package/dist/client/blocks/library/file-tree.config.d.ts.map +1 -0
  80. package/dist/client/blocks/library/file-tree.config.js +45 -0
  81. package/dist/client/blocks/library/file-tree.config.js.map +1 -0
  82. package/dist/client/blocks/library/html.d.ts.map +1 -1
  83. package/dist/client/blocks/library/html.js +4 -1
  84. package/dist/client/blocks/library/html.js.map +1 -1
  85. package/dist/client/blocks/library/json-explorer.config.d.ts +46 -0
  86. package/dist/client/blocks/library/json-explorer.config.d.ts.map +1 -0
  87. package/dist/client/blocks/library/json-explorer.config.js +28 -0
  88. package/dist/client/blocks/library/json-explorer.config.js.map +1 -0
  89. package/dist/client/blocks/library/mermaid.config.d.ts +32 -0
  90. package/dist/client/blocks/library/mermaid.config.d.ts.map +1 -0
  91. package/dist/client/blocks/library/mermaid.config.js +24 -0
  92. package/dist/client/blocks/library/mermaid.config.js.map +1 -0
  93. package/dist/client/blocks/library/openapi-spec.config.d.ts +49 -0
  94. package/dist/client/blocks/library/openapi-spec.config.d.ts.map +1 -0
  95. package/dist/client/blocks/library/openapi-spec.config.js +24 -0
  96. package/dist/client/blocks/library/openapi-spec.config.js.map +1 -0
  97. package/dist/client/blocks/library/server-specs.d.ts +35 -0
  98. package/dist/client/blocks/library/server-specs.d.ts.map +1 -0
  99. package/dist/client/blocks/library/server-specs.js +171 -0
  100. package/dist/client/blocks/library/server-specs.js.map +1 -0
  101. package/dist/client/blocks/library/specs.d.ts +29 -0
  102. package/dist/client/blocks/library/specs.d.ts.map +1 -0
  103. package/dist/client/blocks/library/specs.js +229 -0
  104. package/dist/client/blocks/library/specs.js.map +1 -0
  105. package/dist/client/blocks/library/table.d.ts.map +1 -1
  106. package/dist/client/blocks/library/table.js +3 -1
  107. package/dist/client/blocks/library/table.js.map +1 -1
  108. package/dist/client/blocks/library/tabs.js +1 -1
  109. package/dist/client/blocks/library/tabs.js.map +1 -1
  110. package/dist/client/blocks/registry.d.ts +8 -0
  111. package/dist/client/blocks/registry.d.ts.map +1 -1
  112. package/dist/client/blocks/registry.js +15 -0
  113. package/dist/client/blocks/registry.js.map +1 -1
  114. package/dist/client/blocks/server.d.ts +9 -0
  115. package/dist/client/blocks/server.d.ts.map +1 -1
  116. package/dist/client/blocks/server.js +16 -0
  117. package/dist/client/blocks/server.js.map +1 -1
  118. package/dist/client/blocks/types.d.ts +40 -0
  119. package/dist/client/blocks/types.d.ts.map +1 -1
  120. package/dist/client/blocks/types.js.map +1 -1
  121. package/dist/client/index.d.ts +2 -1
  122. package/dist/client/index.d.ts.map +1 -1
  123. package/dist/client/index.js +10 -1
  124. package/dist/client/index.js.map +1 -1
  125. package/dist/client/rich-markdown-editor/DragHandle.d.ts +52 -0
  126. package/dist/client/rich-markdown-editor/DragHandle.d.ts.map +1 -0
  127. package/dist/client/rich-markdown-editor/DragHandle.js +403 -0
  128. package/dist/client/rich-markdown-editor/DragHandle.js.map +1 -0
  129. package/dist/client/rich-markdown-editor/RegistryBlockNode.d.ts +97 -0
  130. package/dist/client/rich-markdown-editor/RegistryBlockNode.d.ts.map +1 -0
  131. package/dist/client/rich-markdown-editor/RegistryBlockNode.js +214 -0
  132. package/dist/client/rich-markdown-editor/RegistryBlockNode.js.map +1 -0
  133. package/dist/client/rich-markdown-editor/RunId.d.ts +28 -0
  134. package/dist/client/rich-markdown-editor/RunId.d.ts.map +1 -0
  135. package/dist/client/rich-markdown-editor/RunId.js +60 -0
  136. package/dist/client/rich-markdown-editor/RunId.js.map +1 -0
  137. package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts +25 -1
  138. package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts.map +1 -1
  139. package/dist/client/rich-markdown-editor/SharedRichEditor.js +14 -5
  140. package/dist/client/rich-markdown-editor/SharedRichEditor.js.map +1 -1
  141. package/dist/client/rich-markdown-editor/gfmDoc.d.ts +24 -0
  142. package/dist/client/rich-markdown-editor/gfmDoc.d.ts.map +1 -0
  143. package/dist/client/rich-markdown-editor/gfmDoc.js +83 -0
  144. package/dist/client/rich-markdown-editor/gfmDoc.js.map +1 -0
  145. package/dist/client/rich-markdown-editor/index.d.ts +5 -0
  146. package/dist/client/rich-markdown-editor/index.d.ts.map +1 -1
  147. package/dist/client/rich-markdown-editor/index.js +5 -0
  148. package/dist/client/rich-markdown-editor/index.js.map +1 -1
  149. package/dist/client/rich-markdown-editor/registrySlashCommands.d.ts +46 -0
  150. package/dist/client/rich-markdown-editor/registrySlashCommands.d.ts.map +1 -0
  151. package/dist/client/rich-markdown-editor/registrySlashCommands.js +13 -0
  152. package/dist/client/rich-markdown-editor/registrySlashCommands.js.map +1 -0
  153. package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts.map +1 -1
  154. package/dist/client/rich-markdown-editor/useCollabReconcile.js +33 -0
  155. package/dist/client/rich-markdown-editor/useCollabReconcile.js.map +1 -1
  156. package/docs/content/template-plan.md +19 -4
  157. package/docs/content/visual-plans.md +3 -1
  158. package/package.json +1 -1
@@ -1,11 +1,20 @@
1
1
  import type { BlockSpec, BlockRenderContext } from "./types.js";
2
+ /**
3
+ * Resolve a spec's effective edit surface. Defaults to `"inline"` when the block
4
+ * ships a custom `Edit` (its author built direct-manipulation editing), else
5
+ * `"panel"` — an auto-form block is a property form, which reads best behind a
6
+ * corner edit button. An explicit `spec.editSurface` always wins.
7
+ */
8
+ export declare function blockEditSurface(spec: BlockSpec<any>): "inline" | "panel";
2
9
  /**
3
10
  * Render one registered block. In read mode (or when the spec is inline-only and
4
11
  * not editing) it renders the spec's `Read`. In edit mode for a `block`-placed
5
- * spec it renders the spec's `Edit` if present, otherwise the schema-driven
6
- * {@link SchemaBlockEditor}. This is what the app renderer delegates to once the
7
- * registry recognizes a block type the legacy switch handles unregistered
8
- * types.
12
+ * spec it renders the editor — either inline (the spec's `Edit` or the
13
+ * schema-driven {@link SchemaBlockEditor}) or, for `editSurface: "panel"` blocks,
14
+ * the rendered `Read` plus a corner edit button that opens that editor in the
15
+ * app-provided panel ({@link BlockRenderContext.renderEditSurface}, e.g. a
16
+ * popover). This is what the app renderer delegates to once the registry
17
+ * recognizes a block type — the legacy switch handles unregistered types.
9
18
  */
10
19
  export declare function BlockView({ spec, block, editing, editable, onChange, ctx, }: {
11
20
  spec: BlockSpec<any>;
@@ -1 +1 @@
1
- {"version":3,"file":"BlockView.d.ts","sourceRoot":"","sources":["../../../src/client/blocks/BlockView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGhE;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,EACxB,IAAI,EACJ,KAAK,EACL,OAAO,EACP,QAAe,EACf,QAAQ,EACR,GAAG,GACJ,EAAE;IACD,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC;IACrB,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC;IACvE,yDAAyD;IACzD,OAAO,EAAE,OAAO,CAAC;IACjB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,GAAG,EAAE,kBAAkB,CAAC;CACzB,2CA4CA"}
1
+ {"version":3,"file":"BlockView.d.ts","sourceRoot":"","sources":["../../../src/client/blocks/BlockView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGhE;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,GAAG,QAAQ,GAAG,OAAO,CAEzE;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,EACxB,IAAI,EACJ,KAAK,EACL,OAAO,EACP,QAAe,EACf,QAAQ,EACR,GAAG,GACJ,EAAE;IACD,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC;IACrB,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC;IACvE,yDAAyD;IACzD,OAAO,EAAE,OAAO,CAAC;IACjB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,GAAG,EAAE,kBAAkB,CAAC;CACzB,2CAsEA"}
@@ -1,24 +1,45 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { IconPencil } from "@tabler/icons-react";
2
3
  import { SchemaBlockEditor } from "./SchemaBlockEditor.js";
4
+ /**
5
+ * Resolve a spec's effective edit surface. Defaults to `"inline"` when the block
6
+ * ships a custom `Edit` (its author built direct-manipulation editing), else
7
+ * `"panel"` — an auto-form block is a property form, which reads best behind a
8
+ * corner edit button. An explicit `spec.editSurface` always wins.
9
+ */
10
+ export function blockEditSurface(spec) {
11
+ return spec.editSurface ?? (spec.Edit ? "inline" : "panel");
12
+ }
3
13
  /**
4
14
  * Render one registered block. In read mode (or when the spec is inline-only and
5
15
  * not editing) it renders the spec's `Read`. In edit mode for a `block`-placed
6
- * spec it renders the spec's `Edit` if present, otherwise the schema-driven
7
- * {@link SchemaBlockEditor}. This is what the app renderer delegates to once the
8
- * registry recognizes a block type the legacy switch handles unregistered
9
- * types.
16
+ * spec it renders the editor — either inline (the spec's `Edit` or the
17
+ * schema-driven {@link SchemaBlockEditor}) or, for `editSurface: "panel"` blocks,
18
+ * the rendered `Read` plus a corner edit button that opens that editor in the
19
+ * app-provided panel ({@link BlockRenderContext.renderEditSurface}, e.g. a
20
+ * popover). This is what the app renderer delegates to once the registry
21
+ * recognizes a block type — the legacy switch handles unregistered types.
10
22
  */
11
23
  export function BlockView({ spec, block, editing, editable = true, onChange, ctx, }) {
24
+ const Read = spec.Read;
25
+ const readNode = (_jsx(Read, { data: block.data, blockId: block.id, title: block.title, summary: block.summary, ctx: ctx }));
12
26
  const canEdit = editing && editable && spec.placement.includes("block") && !!onChange;
13
- if (!canEdit) {
14
- const Read = spec.Read;
15
- return (_jsx(Read, { data: block.data, blockId: block.id, title: block.title, summary: block.summary, ctx: ctx }));
16
- }
27
+ if (!canEdit)
28
+ return readNode;
17
29
  const commit = (nextData) => onChange?.(nextData);
18
- if (spec.Edit) {
19
- const Edit = spec.Edit;
20
- return (_jsx(Edit, { data: block.data, onChange: commit, editable: true, blockId: block.id, title: block.title, summary: block.summary, ctx: ctx }));
30
+ const Edit = spec.Edit;
31
+ const formNode = Edit ? (_jsx(Edit, { data: block.data, onChange: commit, editable: true, blockId: block.id, title: block.title, summary: block.summary, ctx: ctx })) : (_jsx(SchemaBlockEditor, { data: block.data, onChange: commit, schema: spec.schema, editable: true, blockId: block.id, ctx: ctx }));
32
+ // Panel mode: show the rendered block with a corner edit button that opens the
33
+ // form in the app-provided panel (popover). Falls back to inline editing when
34
+ // the app hasn't wired `renderEditSurface`.
35
+ if (blockEditSurface(spec) === "panel" && ctx.renderEditSurface) {
36
+ return (_jsxs("div", { className: "an-block-panel group relative", children: [readNode, _jsx("div", { className: "an-block-panel__edit absolute right-2 top-2 z-10", children: ctx.renderEditSurface({
37
+ title: spec.label,
38
+ trigger: (_jsx("button", { type: "button", "data-plan-interactive": true, "aria-label": `Edit ${spec.label}`, className: "an-block-edit-trigger flex size-7 items-center justify-center rounded-md border border-border bg-background/80 text-muted-foreground opacity-0 shadow-sm backdrop-blur transition-opacity hover:bg-muted hover:text-foreground focus-visible:opacity-100 group-hover:opacity-100", children: _jsx(IconPencil, { className: "size-4" }) })),
39
+ children: formNode,
40
+ }) })] }));
21
41
  }
22
- return (_jsx(SchemaBlockEditor, { data: block.data, onChange: commit, schema: spec.schema, editable: true, blockId: block.id, ctx: ctx }));
42
+ // Inline mode (direct manipulation).
43
+ return formNode;
23
44
  }
24
45
  //# sourceMappingURL=BlockView.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BlockView.js","sourceRoot":"","sources":["../../../src/client/blocks/BlockView.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CAAC,EACxB,IAAI,EACJ,KAAK,EACL,OAAO,EACP,QAAQ,GAAG,IAAI,EACf,QAAQ,EACR,GAAG,GAWJ;IACC,MAAM,OAAO,GACX,OAAO,IAAI,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC;IAExE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,OAAO,CACL,KAAC,IAAI,IACH,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,OAAO,EAAE,KAAK,CAAC,EAAE,EACjB,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,OAAO,EAAE,KAAK,CAAC,OAAO,EACtB,GAAG,EAAE,GAAG,GACR,CACH,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,QAAiB,EAAE,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC;IAE3D,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,OAAO,CACL,KAAC,IAAI,IACH,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,QACR,OAAO,EAAE,KAAK,CAAC,EAAE,EACjB,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,OAAO,EAAE,KAAK,CAAC,OAAO,EACtB,GAAG,EAAE,GAAG,GACR,CACH,CAAC;IACJ,CAAC;IAED,OAAO,CACL,KAAC,iBAAiB,IAChB,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,IAAI,CAAC,MAAM,EACnB,QAAQ,QACR,OAAO,EAAE,KAAK,CAAC,EAAE,EACjB,GAAG,EAAE,GAAG,GACR,CACH,CAAC;AACJ,CAAC","sourcesContent":["import type { BlockSpec, BlockRenderContext } from \"./types.js\";\nimport { SchemaBlockEditor } from \"./SchemaBlockEditor.js\";\n\n/**\n * Render one registered block. In read mode (or when the spec is inline-only and\n * not editing) it renders the spec's `Read`. In edit mode for a `block`-placed\n * spec it renders the spec's `Edit` if present, otherwise the schema-driven\n * {@link SchemaBlockEditor}. This is what the app renderer delegates to once the\n * registry recognizes a block type — the legacy switch handles unregistered\n * types.\n */\nexport function BlockView({\n spec,\n block,\n editing,\n editable = true,\n onChange,\n ctx,\n}: {\n spec: BlockSpec<any>;\n block: { id: string; title?: string; summary?: string; data: unknown };\n /** Whether the document is in an editable/edit state. */\n editing: boolean;\n /** Whether this specific block allows editing (block.editable !== false). */\n editable?: boolean;\n /** Commit a new `data` value for the block. */\n onChange?: (nextData: unknown) => void;\n ctx: BlockRenderContext;\n}) {\n const canEdit =\n editing && editable && spec.placement.includes(\"block\") && !!onChange;\n\n if (!canEdit) {\n const Read = spec.Read;\n return (\n <Read\n data={block.data}\n blockId={block.id}\n title={block.title}\n summary={block.summary}\n ctx={ctx}\n />\n );\n }\n\n const commit = (nextData: unknown) => onChange?.(nextData);\n\n if (spec.Edit) {\n const Edit = spec.Edit;\n return (\n <Edit\n data={block.data}\n onChange={commit}\n editable\n blockId={block.id}\n title={block.title}\n summary={block.summary}\n ctx={ctx}\n />\n );\n }\n\n return (\n <SchemaBlockEditor\n data={block.data}\n onChange={commit}\n schema={spec.schema}\n editable\n blockId={block.id}\n ctx={ctx}\n />\n );\n}\n"]}
1
+ {"version":3,"file":"BlockView.js","sourceRoot":"","sources":["../../../src/client/blocks/BlockView.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAoB;IACnD,OAAO,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,SAAS,CAAC,EACxB,IAAI,EACJ,KAAK,EACL,OAAO,EACP,QAAQ,GAAG,IAAI,EACf,QAAQ,EACR,GAAG,GAWJ;IACC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IACvB,MAAM,QAAQ,GAAG,CACf,KAAC,IAAI,IACH,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,OAAO,EAAE,KAAK,CAAC,EAAE,EACjB,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,OAAO,EAAE,KAAK,CAAC,OAAO,EACtB,GAAG,EAAE,GAAG,GACR,CACH,CAAC;IAEF,MAAM,OAAO,GACX,OAAO,IAAI,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC;IAExE,IAAI,CAAC,OAAO;QAAE,OAAO,QAAQ,CAAC;IAE9B,MAAM,MAAM,GAAG,CAAC,QAAiB,EAAE,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC;IAE3D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CACtB,KAAC,IAAI,IACH,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,QACR,OAAO,EAAE,KAAK,CAAC,EAAE,EACjB,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,OAAO,EAAE,KAAK,CAAC,OAAO,EACtB,GAAG,EAAE,GAAG,GACR,CACH,CAAC,CAAC,CAAC,CACF,KAAC,iBAAiB,IAChB,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,IAAI,CAAC,MAAM,EACnB,QAAQ,QACR,OAAO,EAAE,KAAK,CAAC,EAAE,EACjB,GAAG,EAAE,GAAG,GACR,CACH,CAAC;IAEF,+EAA+E;IAC/E,8EAA8E;IAC9E,4CAA4C;IAC5C,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,OAAO,IAAI,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAChE,OAAO,CACL,eAAK,SAAS,EAAC,+BAA+B,aAC3C,QAAQ,EACT,cAAK,SAAS,EAAC,kDAAkD,YAC9D,GAAG,CAAC,iBAAiB,CAAC;wBACrB,KAAK,EAAE,IAAI,CAAC,KAAK;wBACjB,OAAO,EAAE,CACP,iBACE,IAAI,EAAC,QAAQ,+CAED,QAAQ,IAAI,CAAC,KAAK,EAAE,EAChC,SAAS,EAAC,kRAAkR,YAE5R,KAAC,UAAU,IAAC,SAAS,EAAC,QAAQ,GAAG,GAC1B,CACV;wBACD,QAAQ,EAAE,QAAQ;qBACnB,CAAC,GACE,IACF,CACP,CAAC;IACJ,CAAC;IAED,qCAAqC;IACrC,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["import { IconPencil } from \"@tabler/icons-react\";\nimport type { BlockSpec, BlockRenderContext } from \"./types.js\";\nimport { SchemaBlockEditor } from \"./SchemaBlockEditor.js\";\n\n/**\n * Resolve a spec's effective edit surface. Defaults to `\"inline\"` when the block\n * ships a custom `Edit` (its author built direct-manipulation editing), else\n * `\"panel\"` — an auto-form block is a property form, which reads best behind a\n * corner edit button. An explicit `spec.editSurface` always wins.\n */\nexport function blockEditSurface(spec: BlockSpec<any>): \"inline\" | \"panel\" {\n return spec.editSurface ?? (spec.Edit ? \"inline\" : \"panel\");\n}\n\n/**\n * Render one registered block. In read mode (or when the spec is inline-only and\n * not editing) it renders the spec's `Read`. In edit mode for a `block`-placed\n * spec it renders the editor — either inline (the spec's `Edit` or the\n * schema-driven {@link SchemaBlockEditor}) or, for `editSurface: \"panel\"` blocks,\n * the rendered `Read` plus a corner edit button that opens that editor in the\n * app-provided panel ({@link BlockRenderContext.renderEditSurface}, e.g. a\n * popover). This is what the app renderer delegates to once the registry\n * recognizes a block type — the legacy switch handles unregistered types.\n */\nexport function BlockView({\n spec,\n block,\n editing,\n editable = true,\n onChange,\n ctx,\n}: {\n spec: BlockSpec<any>;\n block: { id: string; title?: string; summary?: string; data: unknown };\n /** Whether the document is in an editable/edit state. */\n editing: boolean;\n /** Whether this specific block allows editing (block.editable !== false). */\n editable?: boolean;\n /** Commit a new `data` value for the block. */\n onChange?: (nextData: unknown) => void;\n ctx: BlockRenderContext;\n}) {\n const Read = spec.Read;\n const readNode = (\n <Read\n data={block.data}\n blockId={block.id}\n title={block.title}\n summary={block.summary}\n ctx={ctx}\n />\n );\n\n const canEdit =\n editing && editable && spec.placement.includes(\"block\") && !!onChange;\n\n if (!canEdit) return readNode;\n\n const commit = (nextData: unknown) => onChange?.(nextData);\n\n const Edit = spec.Edit;\n const formNode = Edit ? (\n <Edit\n data={block.data}\n onChange={commit}\n editable\n blockId={block.id}\n title={block.title}\n summary={block.summary}\n ctx={ctx}\n />\n ) : (\n <SchemaBlockEditor\n data={block.data}\n onChange={commit}\n schema={spec.schema}\n editable\n blockId={block.id}\n ctx={ctx}\n />\n );\n\n // Panel mode: show the rendered block with a corner edit button that opens the\n // form in the app-provided panel (popover). Falls back to inline editing when\n // the app hasn't wired `renderEditSurface`.\n if (blockEditSurface(spec) === \"panel\" && ctx.renderEditSurface) {\n return (\n <div className=\"an-block-panel group relative\">\n {readNode}\n <div className=\"an-block-panel__edit absolute right-2 top-2 z-10\">\n {ctx.renderEditSurface({\n title: spec.label,\n trigger: (\n <button\n type=\"button\"\n data-plan-interactive\n aria-label={`Edit ${spec.label}`}\n className=\"an-block-edit-trigger flex size-7 items-center justify-center rounded-md border border-border bg-background/80 text-muted-foreground opacity-0 shadow-sm backdrop-blur transition-opacity hover:bg-muted hover:text-foreground focus-visible:opacity-100 group-hover:opacity-100\"\n >\n <IconPencil className=\"size-4\" />\n </button>\n ),\n children: formNode,\n })}\n </div>\n </div>\n );\n }\n\n // Inline mode (direct manipulation).\n return formNode;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaBlockEditor.d.ts","sourceRoot":"","sources":["../../../src/client/blocks/SchemaBlockEditor.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAEnC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGrD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,EACnC,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,OAAO,EACP,GAAG,GACJ,EAAE;IACD,IAAI,EAAE,CAAC,CAAC;IACR,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAC5B,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,kBAAkB,CAAC;CACzB,2CAwDA"}
1
+ {"version":3,"file":"SchemaBlockEditor.d.ts","sourceRoot":"","sources":["../../../src/client/blocks/SchemaBlockEditor.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAGnC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGrD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,EACnC,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,OAAO,EACP,GAAG,GACJ,EAAE;IACD,IAAI,EAAE,CAAC,CAAC;IACR,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAC5B,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,kBAAkB,CAAC;CACzB,2CAwDA"}
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useMemo, useState } from "react";
3
+ import { IconPlus, IconTrash } from "@tabler/icons-react";
3
4
  import { cn } from "../utils.js";
4
5
  import { introspect } from "./schema-form/introspect.js";
5
6
  /**
@@ -35,6 +36,59 @@ const textareaClass = "flex min-h-[80px] w-full rounded-md border border-input b
35
36
  function FieldLabel({ children }) {
36
37
  return (_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: children }));
37
38
  }
39
+ /** A sensible empty value for a single field, used when adding array items. */
40
+ function emptyForField(field) {
41
+ switch (field.kind) {
42
+ case "text":
43
+ // A field literally named `id` gets a fresh stable id so new rows are
44
+ // distinguishable without the user having to type one.
45
+ return field.key === "id"
46
+ ? `item-${Math.random().toString(36).slice(2, 10)}`
47
+ : "";
48
+ case "longtext":
49
+ case "markdown":
50
+ case "richtext":
51
+ return "";
52
+ case "boolean":
53
+ return false;
54
+ case "enum":
55
+ return field.enumValues?.[0];
56
+ case "array":
57
+ return [];
58
+ case "object":
59
+ return emptyObjectFromFields(field.fields);
60
+ case "number":
61
+ default:
62
+ // number → undefined (the input shows blank until the user types); any
63
+ // unsupported kind also defaults to undefined.
64
+ return undefined;
65
+ }
66
+ }
67
+ /** Build an empty object value from a descriptor's child fields. */
68
+ function emptyObjectFromFields(fields) {
69
+ const result = {};
70
+ for (const child of fields ?? []) {
71
+ result[child.key] = emptyForField(child);
72
+ }
73
+ return result;
74
+ }
75
+ /** A scalar element kind classified from an array's inner element schema. */
76
+ function scalarKindFromInner(inner) {
77
+ const type = inner?._def?.type;
78
+ if (type === "number" || type === "bigint")
79
+ return "number";
80
+ if (type === "boolean")
81
+ return "boolean";
82
+ return "text";
83
+ }
84
+ /** An empty value for a scalar array element of the given kind. */
85
+ function emptyScalar(kind) {
86
+ if (kind === "boolean")
87
+ return false;
88
+ if (kind === "number")
89
+ return undefined;
90
+ return "";
91
+ }
38
92
  function FieldControl({ field, value, onChange, editable, blockId, ctx, }) {
39
93
  if (field.kind === "markdown" || field.kind === "richtext") {
40
94
  const node = ctx.renderMarkdownEditor?.({
@@ -64,9 +118,48 @@ function FieldControl({ field, value, onChange, editable, blockId, ctx, }) {
64
118
  if (field.kind === "text") {
65
119
  return (_jsxs("label", { className: "flex flex-col gap-1.5", children: [_jsx(FieldLabel, { children: field.label }), _jsx("input", { type: "text", "data-plan-interactive": true, className: inputClass, value: typeof value === "string" ? value : "", disabled: !editable, onChange: (event) => onChange(event.target.value) })] }));
66
120
  }
67
- // array / object / unsupported: the auto-editor intentionally does not render
68
- // a control for positional/structured data. Blocks with these fields should
69
- // ship a custom `Edit`. Surface a hint in dev so the gap is visible.
121
+ if (field.kind === "object" && field.fields && field.fields.length > 0) {
122
+ const objValue = value && typeof value === "object" && !Array.isArray(value)
123
+ ? value
124
+ : {};
125
+ return (_jsxs("div", { className: "flex flex-col gap-3 rounded-md border border-input px-3 py-3", children: [_jsx(FieldLabel, { children: field.label }), _jsx("div", { className: "flex flex-col gap-3", children: field.fields.map((child) => (_jsx(FieldControl, { field: child, value: objValue[child.key], onChange: (childVal) => onChange({ ...objValue, [child.key]: childVal }), editable: editable, blockId: blockId, ctx: ctx }, child.key))) })] }));
126
+ }
127
+ if (field.kind === "array") {
128
+ const items = Array.isArray(value) ? value : [];
129
+ const replaceItem = (index, next) => {
130
+ const copy = items.slice();
131
+ copy[index] = next;
132
+ onChange(copy);
133
+ };
134
+ const removeItem = (index) => {
135
+ onChange(items.filter((_, i) => i !== index));
136
+ };
137
+ const objectElement = Array.isArray(field.fields) && field.fields.length > 0;
138
+ const scalarKind = objectElement ? null : scalarKindFromInner(field.inner);
139
+ const addItem = () => {
140
+ if (objectElement) {
141
+ onChange([...items, emptyObjectFromFields(field.fields)]);
142
+ }
143
+ else {
144
+ onChange([...items, emptyScalar(scalarKind ?? "text")]);
145
+ }
146
+ };
147
+ return (_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(FieldLabel, { children: field.label }), _jsx("div", { className: "flex flex-col gap-2", children: items.map((item, index) => (_jsxs("div", { className: "flex items-start gap-2 rounded-md border border-input px-3 py-3", children: [_jsx("div", { className: "flex flex-1 flex-col gap-3", children: objectElement ? (field.fields.map((child) => {
148
+ const itemValue = item && typeof item === "object" && !Array.isArray(item)
149
+ ? item
150
+ : {};
151
+ return (_jsx(FieldControl, { field: child, value: itemValue[child.key], onChange: (childVal) => replaceItem(index, {
152
+ ...itemValue,
153
+ [child.key]: childVal,
154
+ }), editable: editable, blockId: blockId, ctx: ctx }, child.key));
155
+ })) : scalarKind === "boolean" ? (_jsx("input", { type: "checkbox", "data-plan-interactive": true, className: "size-4 self-start rounded border-input accent-primary", checked: Boolean(item), disabled: !editable, onChange: (event) => replaceItem(index, event.target.checked) })) : scalarKind === "number" ? (_jsx("input", { type: "number", "data-plan-interactive": true, className: inputClass, value: typeof item === "number" ? item : "", disabled: !editable, onChange: (event) => {
156
+ const raw = event.target.value;
157
+ replaceItem(index, raw === "" ? undefined : Number(raw));
158
+ } })) : (_jsx("input", { type: "text", "data-plan-interactive": true, className: inputClass, value: typeof item === "string" ? item : "", disabled: !editable, onChange: (event) => replaceItem(index, event.target.value) })) }), editable && (_jsx("button", { type: "button", "data-plan-interactive": true, "aria-label": "Remove item", className: "mt-0.5 inline-flex size-7 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground", onClick: () => removeItem(index), children: _jsx(IconTrash, { className: "size-4" }) }))] }, index))) }), editable && (_jsxs("button", { type: "button", "data-plan-interactive": true, className: "inline-flex items-center gap-1.5 self-start text-sm text-muted-foreground underline-offset-2 hover:text-foreground hover:underline", onClick: addItem, children: [_jsx(IconPlus, { className: "size-4" }), "Add ", field.label.replace(/s$/i, "").toLowerCase() || "item"] }))] }));
159
+ }
160
+ // Unsupported / structured-without-fields: the auto-editor cannot infer a
161
+ // control. Blocks with these fields should ship a custom `Edit`. Surface a
162
+ // hint in dev so the gap is visible.
70
163
  return (_jsxs("div", { className: cn("rounded-md border border-dashed border-input px-3 py-2 text-xs text-muted-foreground"), children: [_jsx(FieldLabel, { children: field.label }), _jsxs("p", { className: "mt-1", children: ["This field (", field.kind, ") needs a custom editor \u2014 define `Edit` on the block spec."] })] }));
71
164
  }
72
165
  //# sourceMappingURL=SchemaBlockEditor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaBlockEditor.js","sourceRoot":"","sources":["../../../src/client/blocks/SchemaBlockEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useMemo, useState } from \"react\";\nimport type { ZodType } from \"zod\";\nimport { cn } from \"../utils.js\";\nimport type { BlockRenderContext } from \"./types.js\";\nimport { introspect, type FieldDescriptor } from \"./schema-form/introspect.js\";\n\n/**\n * Schema-driven auto-editor. When a {@link BlockSpec} omits `Edit`, the registry\n * renders this: it walks the block's zod `data` schema and renders one control\n * per field (string → input, longtext → textarea, number, boolean → toggle,\n * enum → native select, array → repeating rows, object → nested fieldset). A\n * `markdown()`-tagged string field defers to the app-provided inline rich\n * editor via `ctx.renderMarkdownEditor` so prose stays Notion-editable.\n *\n * It uses plain accessible native controls (not template shadcn primitives,\n * which core does not bundle) styled to match the shadcn look. Validation runs\n * the spec's own schema on every edit; the raw edit is kept in local state so a\n * transiently-invalid value (e.g. mid-typing) doesn't get rolled back, and only\n * valid data is committed upstream.\n */\nexport function SchemaBlockEditor<T>({\n data,\n onChange,\n schema,\n editable,\n blockId,\n ctx,\n}: {\n data: T;\n onChange: (next: T) => void;\n schema: ZodType<T>;\n editable: boolean;\n blockId?: string;\n ctx: BlockRenderContext;\n}) {\n const fields = useMemo(() => introspect(schema), [schema]);\n const [showOptional, setShowOptional] = useState(false);\n\n const setField = (key: string, value: unknown) => {\n const next = { ...(data as Record<string, unknown>), [key]: value } as T;\n const parsed = schema.safeParse(next);\n // Commit valid data; otherwise pass the raw edit through so the user can\n // keep typing — the upstream owner re-validates before persisting.\n onChange((parsed.success ? parsed.data : next) as T);\n };\n\n const required = fields.filter((field) => !field.optional);\n const optional = fields.filter((field) => field.optional);\n\n return (\n <div className=\"an-schema-block-editor flex flex-col gap-3\">\n {required.map((field) => (\n <FieldControl\n key={field.key}\n field={field}\n value={(data as Record<string, unknown>)[field.key]}\n onChange={(value) => setField(field.key, value)}\n editable={editable}\n blockId={blockId}\n ctx={ctx}\n />\n ))}\n {optional.length > 0 && (\n <div className=\"flex flex-col gap-3\">\n {showOptional ? (\n optional.map((field) => (\n <FieldControl\n key={field.key}\n field={field}\n value={(data as Record<string, unknown>)[field.key]}\n onChange={(value) => setField(field.key, value)}\n editable={editable}\n blockId={blockId}\n ctx={ctx}\n />\n ))\n ) : (\n <button\n type=\"button\"\n data-plan-interactive\n className=\"self-start text-sm text-muted-foreground underline-offset-2 hover:underline\"\n onClick={() => setShowOptional(true)}\n >\n More options\n </button>\n )}\n </div>\n )}\n </div>\n );\n}\n\nconst inputClass =\n \"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\";\n\nconst textareaClass =\n \"flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\";\n\nfunction FieldLabel({ children }: { children: React.ReactNode }) {\n return (\n <span className=\"text-xs font-medium text-muted-foreground\">\n {children}\n </span>\n );\n}\n\nfunction FieldControl({\n field,\n value,\n onChange,\n editable,\n blockId,\n ctx,\n}: {\n field: FieldDescriptor;\n value: unknown;\n onChange: (value: unknown) => void;\n editable: boolean;\n blockId?: string;\n ctx: BlockRenderContext;\n}) {\n if (field.kind === \"markdown\" || field.kind === \"richtext\") {\n const node = ctx.renderMarkdownEditor?.({\n value: typeof value === \"string\" ? value : \"\",\n onChange: (next) => onChange(next),\n editable,\n blockId,\n });\n return (\n <label className=\"flex flex-col gap-1.5\">\n <FieldLabel>{field.label}</FieldLabel>\n {node ?? (\n // Fallback when no app markdown editor is injected: a plain textarea.\n <textarea\n data-plan-interactive\n className={textareaClass}\n value={typeof value === \"string\" ? value : \"\"}\n disabled={!editable}\n onChange={(event) => onChange(event.target.value)}\n />\n )}\n </label>\n );\n }\n\n if (field.kind === \"boolean\") {\n return (\n <label className=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n data-plan-interactive\n className=\"size-4 rounded border-input accent-primary\"\n checked={Boolean(value)}\n disabled={!editable}\n onChange={(event) => onChange(event.target.checked)}\n />\n <FieldLabel>{field.label}</FieldLabel>\n </label>\n );\n }\n\n if (field.kind === \"enum\") {\n const options = field.enumValues ?? [];\n return (\n <label className=\"flex flex-col gap-1.5\">\n <FieldLabel>{field.label}</FieldLabel>\n <select\n data-plan-interactive\n className={inputClass}\n value={typeof value === \"string\" ? value : \"\"}\n disabled={!editable}\n onChange={(event) => onChange(event.target.value || undefined)}\n >\n {field.optional && <option value=\"\">—</option>}\n {options.map((option) => (\n <option key={option} value={option}>\n {option}\n </option>\n ))}\n </select>\n </label>\n );\n }\n\n if (field.kind === \"number\") {\n return (\n <label className=\"flex flex-col gap-1.5\">\n <FieldLabel>{field.label}</FieldLabel>\n <input\n type=\"number\"\n data-plan-interactive\n className={inputClass}\n value={typeof value === \"number\" ? value : \"\"}\n disabled={!editable}\n onChange={(event) => {\n const raw = event.target.value;\n onChange(raw === \"\" ? undefined : Number(raw));\n }}\n />\n </label>\n );\n }\n\n if (field.kind === \"longtext\") {\n return (\n <label className=\"flex flex-col gap-1.5\">\n <FieldLabel>{field.label}</FieldLabel>\n <textarea\n data-plan-interactive\n className={textareaClass}\n value={typeof value === \"string\" ? value : \"\"}\n disabled={!editable}\n onChange={(event) => onChange(event.target.value)}\n />\n </label>\n );\n }\n\n if (field.kind === \"text\") {\n return (\n <label className=\"flex flex-col gap-1.5\">\n <FieldLabel>{field.label}</FieldLabel>\n <input\n type=\"text\"\n data-plan-interactive\n className={inputClass}\n value={typeof value === \"string\" ? value : \"\"}\n disabled={!editable}\n onChange={(event) => onChange(event.target.value)}\n />\n </label>\n );\n }\n\n // array / object / unsupported: the auto-editor intentionally does not render\n // a control for positional/structured data. Blocks with these fields should\n // ship a custom `Edit`. Surface a hint in dev so the gap is visible.\n return (\n <div\n className={cn(\n \"rounded-md border border-dashed border-input px-3 py-2 text-xs text-muted-foreground\",\n )}\n >\n <FieldLabel>{field.label}</FieldLabel>\n <p className=\"mt-1\">\n This field ({field.kind}) needs a custom editor — define `Edit` on the\n block spec.\n </p>\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"SchemaBlockEditor.js","sourceRoot":"","sources":["../../../src/client/blocks/SchemaBlockEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useMemo, useState } from \"react\";\nimport type { ZodType } from \"zod\";\nimport { IconPlus, IconTrash } from \"@tabler/icons-react\";\nimport { cn } from \"../utils.js\";\nimport type { BlockRenderContext } from \"./types.js\";\nimport { introspect, type FieldDescriptor } from \"./schema-form/introspect.js\";\n\n/**\n * Schema-driven auto-editor. When a {@link BlockSpec} omits `Edit`, the registry\n * renders this: it walks the block's zod `data` schema and renders one control\n * per field (string → input, longtext → textarea, number, boolean → toggle,\n * enum → native select, array → repeating rows, object → nested fieldset). A\n * `markdown()`-tagged string field defers to the app-provided inline rich\n * editor via `ctx.renderMarkdownEditor` so prose stays Notion-editable.\n *\n * It uses plain accessible native controls (not template shadcn primitives,\n * which core does not bundle) styled to match the shadcn look. Validation runs\n * the spec's own schema on every edit; the raw edit is kept in local state so a\n * transiently-invalid value (e.g. mid-typing) doesn't get rolled back, and only\n * valid data is committed upstream.\n */\nexport function SchemaBlockEditor<T>({\n data,\n onChange,\n schema,\n editable,\n blockId,\n ctx,\n}: {\n data: T;\n onChange: (next: T) => void;\n schema: ZodType<T>;\n editable: boolean;\n blockId?: string;\n ctx: BlockRenderContext;\n}) {\n const fields = useMemo(() => introspect(schema), [schema]);\n const [showOptional, setShowOptional] = useState(false);\n\n const setField = (key: string, value: unknown) => {\n const next = { ...(data as Record<string, unknown>), [key]: value } as T;\n const parsed = schema.safeParse(next);\n // Commit valid data; otherwise pass the raw edit through so the user can\n // keep typing — the upstream owner re-validates before persisting.\n onChange((parsed.success ? parsed.data : next) as T);\n };\n\n const required = fields.filter((field) => !field.optional);\n const optional = fields.filter((field) => field.optional);\n\n return (\n <div className=\"an-schema-block-editor flex flex-col gap-3\">\n {required.map((field) => (\n <FieldControl\n key={field.key}\n field={field}\n value={(data as Record<string, unknown>)[field.key]}\n onChange={(value) => setField(field.key, value)}\n editable={editable}\n blockId={blockId}\n ctx={ctx}\n />\n ))}\n {optional.length > 0 && (\n <div className=\"flex flex-col gap-3\">\n {showOptional ? (\n optional.map((field) => (\n <FieldControl\n key={field.key}\n field={field}\n value={(data as Record<string, unknown>)[field.key]}\n onChange={(value) => setField(field.key, value)}\n editable={editable}\n blockId={blockId}\n ctx={ctx}\n />\n ))\n ) : (\n <button\n type=\"button\"\n data-plan-interactive\n className=\"self-start text-sm text-muted-foreground underline-offset-2 hover:underline\"\n onClick={() => setShowOptional(true)}\n >\n More options\n </button>\n )}\n </div>\n )}\n </div>\n );\n}\n\nconst inputClass =\n \"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\";\n\nconst textareaClass =\n \"flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\";\n\nfunction FieldLabel({ children }: { children: React.ReactNode }) {\n return (\n <span className=\"text-xs font-medium text-muted-foreground\">\n {children}\n </span>\n );\n}\n\n/** A sensible empty value for a single field, used when adding array items. */\nfunction emptyForField(field: FieldDescriptor): unknown {\n switch (field.kind) {\n case \"text\":\n // A field literally named `id` gets a fresh stable id so new rows are\n // distinguishable without the user having to type one.\n return field.key === \"id\"\n ? `item-${Math.random().toString(36).slice(2, 10)}`\n : \"\";\n case \"longtext\":\n case \"markdown\":\n case \"richtext\":\n return \"\";\n case \"boolean\":\n return false;\n case \"enum\":\n return field.enumValues?.[0];\n case \"array\":\n return [];\n case \"object\":\n return emptyObjectFromFields(field.fields);\n case \"number\":\n default:\n // number → undefined (the input shows blank until the user types); any\n // unsupported kind also defaults to undefined.\n return undefined;\n }\n}\n\n/** Build an empty object value from a descriptor's child fields. */\nfunction emptyObjectFromFields(\n fields: FieldDescriptor[] | undefined,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const child of fields ?? []) {\n result[child.key] = emptyForField(child);\n }\n return result;\n}\n\n/** A scalar element kind classified from an array's inner element schema. */\nfunction scalarKindFromInner(\n inner: FieldDescriptor[\"inner\"],\n): \"number\" | \"boolean\" | \"text\" {\n const type = (inner?._def as { type?: string } | undefined)?.type;\n if (type === \"number\" || type === \"bigint\") return \"number\";\n if (type === \"boolean\") return \"boolean\";\n return \"text\";\n}\n\n/** An empty value for a scalar array element of the given kind. */\nfunction emptyScalar(kind: \"number\" | \"boolean\" | \"text\"): unknown {\n if (kind === \"boolean\") return false;\n if (kind === \"number\") return undefined;\n return \"\";\n}\n\nfunction FieldControl({\n field,\n value,\n onChange,\n editable,\n blockId,\n ctx,\n}: {\n field: FieldDescriptor;\n value: unknown;\n onChange: (value: unknown) => void;\n editable: boolean;\n blockId?: string;\n ctx: BlockRenderContext;\n}) {\n if (field.kind === \"markdown\" || field.kind === \"richtext\") {\n const node = ctx.renderMarkdownEditor?.({\n value: typeof value === \"string\" ? value : \"\",\n onChange: (next) => onChange(next),\n editable,\n blockId,\n });\n return (\n <label className=\"flex flex-col gap-1.5\">\n <FieldLabel>{field.label}</FieldLabel>\n {node ?? (\n // Fallback when no app markdown editor is injected: a plain textarea.\n <textarea\n data-plan-interactive\n className={textareaClass}\n value={typeof value === \"string\" ? value : \"\"}\n disabled={!editable}\n onChange={(event) => onChange(event.target.value)}\n />\n )}\n </label>\n );\n }\n\n if (field.kind === \"boolean\") {\n return (\n <label className=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n data-plan-interactive\n className=\"size-4 rounded border-input accent-primary\"\n checked={Boolean(value)}\n disabled={!editable}\n onChange={(event) => onChange(event.target.checked)}\n />\n <FieldLabel>{field.label}</FieldLabel>\n </label>\n );\n }\n\n if (field.kind === \"enum\") {\n const options = field.enumValues ?? [];\n return (\n <label className=\"flex flex-col gap-1.5\">\n <FieldLabel>{field.label}</FieldLabel>\n <select\n data-plan-interactive\n className={inputClass}\n value={typeof value === \"string\" ? value : \"\"}\n disabled={!editable}\n onChange={(event) => onChange(event.target.value || undefined)}\n >\n {field.optional && <option value=\"\">—</option>}\n {options.map((option) => (\n <option key={option} value={option}>\n {option}\n </option>\n ))}\n </select>\n </label>\n );\n }\n\n if (field.kind === \"number\") {\n return (\n <label className=\"flex flex-col gap-1.5\">\n <FieldLabel>{field.label}</FieldLabel>\n <input\n type=\"number\"\n data-plan-interactive\n className={inputClass}\n value={typeof value === \"number\" ? value : \"\"}\n disabled={!editable}\n onChange={(event) => {\n const raw = event.target.value;\n onChange(raw === \"\" ? undefined : Number(raw));\n }}\n />\n </label>\n );\n }\n\n if (field.kind === \"longtext\") {\n return (\n <label className=\"flex flex-col gap-1.5\">\n <FieldLabel>{field.label}</FieldLabel>\n <textarea\n data-plan-interactive\n className={textareaClass}\n value={typeof value === \"string\" ? value : \"\"}\n disabled={!editable}\n onChange={(event) => onChange(event.target.value)}\n />\n </label>\n );\n }\n\n if (field.kind === \"text\") {\n return (\n <label className=\"flex flex-col gap-1.5\">\n <FieldLabel>{field.label}</FieldLabel>\n <input\n type=\"text\"\n data-plan-interactive\n className={inputClass}\n value={typeof value === \"string\" ? value : \"\"}\n disabled={!editable}\n onChange={(event) => onChange(event.target.value)}\n />\n </label>\n );\n }\n\n if (field.kind === \"object\" && field.fields && field.fields.length > 0) {\n const objValue =\n value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n return (\n <div className=\"flex flex-col gap-3 rounded-md border border-input px-3 py-3\">\n <FieldLabel>{field.label}</FieldLabel>\n <div className=\"flex flex-col gap-3\">\n {field.fields.map((child) => (\n <FieldControl\n key={child.key}\n field={child}\n value={objValue[child.key]}\n onChange={(childVal) =>\n onChange({ ...objValue, [child.key]: childVal })\n }\n editable={editable}\n blockId={blockId}\n ctx={ctx}\n />\n ))}\n </div>\n </div>\n );\n }\n\n if (field.kind === \"array\") {\n const items = Array.isArray(value) ? (value as unknown[]) : [];\n const replaceItem = (index: number, next: unknown) => {\n const copy = items.slice();\n copy[index] = next;\n onChange(copy);\n };\n const removeItem = (index: number) => {\n onChange(items.filter((_, i) => i !== index));\n };\n const objectElement =\n Array.isArray(field.fields) && field.fields.length > 0;\n const scalarKind = objectElement ? null : scalarKindFromInner(field.inner);\n const addItem = () => {\n if (objectElement) {\n onChange([...items, emptyObjectFromFields(field.fields)]);\n } else {\n onChange([...items, emptyScalar(scalarKind ?? \"text\")]);\n }\n };\n return (\n <div className=\"flex flex-col gap-2\">\n <FieldLabel>{field.label}</FieldLabel>\n <div className=\"flex flex-col gap-2\">\n {items.map((item, index) => (\n <div\n key={index}\n className=\"flex items-start gap-2 rounded-md border border-input px-3 py-3\"\n >\n <div className=\"flex flex-1 flex-col gap-3\">\n {objectElement ? (\n field.fields!.map((child) => {\n const itemValue =\n item && typeof item === \"object\" && !Array.isArray(item)\n ? (item as Record<string, unknown>)\n : {};\n return (\n <FieldControl\n key={child.key}\n field={child}\n value={itemValue[child.key]}\n onChange={(childVal) =>\n replaceItem(index, {\n ...itemValue,\n [child.key]: childVal,\n })\n }\n editable={editable}\n blockId={blockId}\n ctx={ctx}\n />\n );\n })\n ) : scalarKind === \"boolean\" ? (\n <input\n type=\"checkbox\"\n data-plan-interactive\n className=\"size-4 self-start rounded border-input accent-primary\"\n checked={Boolean(item)}\n disabled={!editable}\n onChange={(event) =>\n replaceItem(index, event.target.checked)\n }\n />\n ) : scalarKind === \"number\" ? (\n <input\n type=\"number\"\n data-plan-interactive\n className={inputClass}\n value={typeof item === \"number\" ? item : \"\"}\n disabled={!editable}\n onChange={(event) => {\n const raw = event.target.value;\n replaceItem(index, raw === \"\" ? undefined : Number(raw));\n }}\n />\n ) : (\n <input\n type=\"text\"\n data-plan-interactive\n className={inputClass}\n value={typeof item === \"string\" ? item : \"\"}\n disabled={!editable}\n onChange={(event) => replaceItem(index, event.target.value)}\n />\n )}\n </div>\n {editable && (\n <button\n type=\"button\"\n data-plan-interactive\n aria-label=\"Remove item\"\n className=\"mt-0.5 inline-flex size-7 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\"\n onClick={() => removeItem(index)}\n >\n <IconTrash className=\"size-4\" />\n </button>\n )}\n </div>\n ))}\n </div>\n {editable && (\n <button\n type=\"button\"\n data-plan-interactive\n className=\"inline-flex items-center gap-1.5 self-start text-sm text-muted-foreground underline-offset-2 hover:text-foreground hover:underline\"\n onClick={addItem}\n >\n <IconPlus className=\"size-4\" />\n Add {field.label.replace(/s$/i, \"\").toLowerCase() || \"item\"}\n </button>\n )}\n </div>\n );\n }\n\n // Unsupported / structured-without-fields: the auto-editor cannot infer a\n // control. Blocks with these fields should ship a custom `Edit`. Surface a\n // hint in dev so the gap is visible.\n return (\n <div\n className={cn(\n \"rounded-md border border-dashed border-input px-3 py-2 text-xs text-muted-foreground\",\n )}\n >\n <FieldLabel>{field.label}</FieldLabel>\n <p className=\"mt-1\">\n This field ({field.kind}) needs a custom editor — define `Edit` on the\n block spec.\n </p>\n </div>\n );\n}\n"]}
@@ -16,11 +16,12 @@
16
16
  export { defineBlock, type BlockSpec, type BlockPlacement, type BlockMdxConfig, type BlockAttrReader, type BlockRenderContext, type BlockReadProps, type BlockEditProps, type MdxAttrValue, type NestedBlock, } from "./types.js";
17
17
  export { BlockRegistry, registerBlocks } from "./registry.js";
18
18
  export { BlockRegistryProvider, useBlockRegistry, useOptionalBlockRegistry, } from "./provider.js";
19
- export { BlockView } from "./BlockView.js";
19
+ export { BlockView, blockEditSurface } from "./BlockView.js";
20
20
  export { SchemaBlockEditor } from "./SchemaBlockEditor.js";
21
21
  export { markdown, richtext, introspect, type FieldKind, type FieldDescriptor, } from "./schema-form/introspect.js";
22
22
  export { prop, escapeAttr, jsonExpression, attributeValue, createAttrReader, serializeSpecBlock, parseSpecBlock, type MdxJsxNode, type MdxAttrNode, type SerializableBlock, type ParsedBlockBase, } from "./mdx.js";
23
23
  export { describeBlocksForAgent, renderBlockVocabularyReference, type BlockAgentDoc, } from "./agent.js";
24
+ export { libraryBlockSpecs, registerLibraryBlocks, type LibraryBlockOverrides, } from "./library/specs.js";
24
25
  export { checklistBlock, ChecklistBlock, ChecklistEditor, } from "./library/checklist.js";
25
26
  export { checklistSchema, checklistMdx, type ChecklistData, type ChecklistItem, } from "./library/checklist.config.js";
26
27
  export { tableBlock } from "./library/table.js";
@@ -31,4 +32,20 @@ export { htmlBlock, HtmlReadBlock, HtmlEditBlock } from "./library/html.js";
31
32
  export { htmlSchema, htmlMdx, type HtmlBlockData, } from "./library/html.config.js";
32
33
  export { tabsBlock, TabsBlockReader, TabsBlockEditor } from "./library/tabs.js";
33
34
  export { tabsSchema, tabsMdx, type TabsData, type TabsTab, } from "./library/tabs.config.js";
35
+ export { MermaidRead, MermaidEdit } from "./library/MermaidBlock.js";
36
+ export { mermaidSchema, mermaidMdx, type MermaidData, } from "./library/mermaid.config.js";
37
+ export { ApiEndpointRead, ApiEndpointEdit, } from "./library/ApiEndpointBlock.js";
38
+ export { apiEndpointSchema, apiEndpointMdx, API_ENDPOINT_METHODS, API_PARAM_LOCATIONS, type ApiEndpointData, type ApiEndpointMethod, type ApiEndpointParam, type ApiEndpointRequest, type ApiEndpointResponse, type ApiParamLocation, } from "./library/api-endpoint.config.js";
39
+ export { DataModelRead, DataModelEdit } from "./library/DataModelBlock.js";
40
+ export { dataModelSchema, dataModelMdx, DATA_MODEL_RELATION_KINDS, type DataModelData, type DataModelEntity, type DataModelField, type DataModelRelation, type DataModelRelationKind, } from "./library/data-model.config.js";
41
+ export { DiffRead, DiffEdit } from "./library/DiffBlock.js";
42
+ export { diffSchema, diffMdx, type DiffData, type DiffMode, } from "./library/diff.config.js";
43
+ export { FileTreeRead, FileTreeEdit } from "./library/FileTreeBlock.js";
44
+ export { fileTreeSchema, fileTreeMdx, FILE_TREE_CHANGES, type FileTreeData, type FileTreeEntry, type FileTreeChange, } from "./library/file-tree.config.js";
45
+ export { JsonExplorerRead, JsonExplorerEdit, } from "./library/JsonExplorerBlock.js";
46
+ export { jsonExplorerSchema, jsonExplorerMdx, type JsonExplorerData, } from "./library/json-explorer.config.js";
47
+ export { AnnotatedCodeRead, AnnotatedCodeEdit, } from "./library/AnnotatedCodeBlock.js";
48
+ export { annotatedCodeSchema, annotatedCodeMdx, type AnnotatedCodeData, type AnnotatedCodeAnnotation, } from "./library/annotated-code.config.js";
49
+ export { OpenApiSpecRead, OpenApiSpecEdit, } from "./library/OpenApiSpecBlock.js";
50
+ export { openApiSpecSchema, openApiSpecMdx, type OpenApiSpecData, } from "./library/openapi-spec.config.js";
34
51
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/blocks/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EACL,WAAW,EACX,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,wBAAwB,GACzB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAG3D,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,KAAK,SAAS,EACd,KAAK,eAAe,GACrB,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EACL,IAAI,EACJ,UAAU,EACV,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,eAAe,GACrB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,sBAAsB,EACtB,8BAA8B,EAC9B,KAAK,aAAa,GACnB,MAAM,YAAY,CAAC;AAIpB,OAAO,EACL,cAAc,EACd,cAAc,EACd,eAAe,GAChB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,eAAe,EACf,YAAY,EACZ,KAAK,aAAa,EAClB,KAAK,aAAa,GACnB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EACL,WAAW,EACX,QAAQ,EACR,KAAK,SAAS,GACf,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EACL,cAAc,EACd,WAAW,EACX,KAAK,YAAY,EACjB,KAAK,WAAW,GACjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EACL,UAAU,EACV,OAAO,EACP,KAAK,aAAa,GACnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EACL,UAAU,EACV,OAAO,EACP,KAAK,QAAQ,EACb,KAAK,OAAO,GACb,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/blocks/index.ts"],"names":[],"mappings":"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"}
@@ -19,7 +19,7 @@ export { defineBlock, } from "./types.js";
19
19
  export { BlockRegistry, registerBlocks } from "./registry.js";
20
20
  export { BlockRegistryProvider, useBlockRegistry, useOptionalBlockRegistry, } from "./provider.js";
21
21
  // Rendering
22
- export { BlockView } from "./BlockView.js";
22
+ export { BlockView, blockEditSurface } from "./BlockView.js";
23
23
  export { SchemaBlockEditor } from "./SchemaBlockEditor.js";
24
24
  // Schema-form helpers
25
25
  export { markdown, richtext, introspect, } from "./schema-form/introspect.js";
@@ -27,6 +27,11 @@ export { markdown, richtext, introspect, } from "./schema-form/introspect.js";
27
27
  export { prop, escapeAttr, jsonExpression, attributeValue, createAttrReader, serializeSpecBlock, parseSpecBlock, } from "./mdx.js";
28
28
  // Agent schema export
29
29
  export { describeBlocksForAgent, renderBlockVocabularyReference, } from "./agent.js";
30
+ // Standard library registration. Apps call `registerLibraryBlocks(registry)` to
31
+ // register the whole standard library (the five pre-built specs + the eight
32
+ // dev-doc specs) in one place, then register only their app-specific blocks on
33
+ // top. `libraryBlockSpecs` is the underlying ordered array.
34
+ export { libraryBlockSpecs, registerLibraryBlocks, } from "./library/specs.js";
30
35
  // Standard block library (React specs). Apps register these in their browser
31
36
  // registry alongside their own app-specific blocks.
32
37
  export { checklistBlock, ChecklistBlock, ChecklistEditor, } from "./library/checklist.js";
@@ -39,4 +44,24 @@ export { htmlBlock, HtmlReadBlock, HtmlEditBlock } from "./library/html.js";
39
44
  export { htmlSchema, htmlMdx, } from "./library/html.config.js";
40
45
  export { tabsBlock, TabsBlockReader, TabsBlockEditor } from "./library/tabs.js";
41
46
  export { tabsSchema, tabsMdx, } from "./library/tabs.config.js";
47
+ // Dev-doc block library (React `Read`/`Edit` renderers + their React-free
48
+ // schema/MDX config). Apps register these alongside their own blocks, supplying
49
+ // app-specific spec metadata (label/description/editSurface/empty) via
50
+ // `defineBlock`. Mirrors the standard library above.
51
+ export { MermaidRead, MermaidEdit } from "./library/MermaidBlock.js";
52
+ export { mermaidSchema, mermaidMdx, } from "./library/mermaid.config.js";
53
+ export { ApiEndpointRead, ApiEndpointEdit, } from "./library/ApiEndpointBlock.js";
54
+ export { apiEndpointSchema, apiEndpointMdx, API_ENDPOINT_METHODS, API_PARAM_LOCATIONS, } from "./library/api-endpoint.config.js";
55
+ export { DataModelRead, DataModelEdit } from "./library/DataModelBlock.js";
56
+ export { dataModelSchema, dataModelMdx, DATA_MODEL_RELATION_KINDS, } from "./library/data-model.config.js";
57
+ export { DiffRead, DiffEdit } from "./library/DiffBlock.js";
58
+ export { diffSchema, diffMdx, } from "./library/diff.config.js";
59
+ export { FileTreeRead, FileTreeEdit } from "./library/FileTreeBlock.js";
60
+ export { fileTreeSchema, fileTreeMdx, FILE_TREE_CHANGES, } from "./library/file-tree.config.js";
61
+ export { JsonExplorerRead, JsonExplorerEdit, } from "./library/JsonExplorerBlock.js";
62
+ export { jsonExplorerSchema, jsonExplorerMdx, } from "./library/json-explorer.config.js";
63
+ export { AnnotatedCodeRead, AnnotatedCodeEdit, } from "./library/AnnotatedCodeBlock.js";
64
+ export { annotatedCodeSchema, annotatedCodeMdx, } from "./library/annotated-code.config.js";
65
+ export { OpenApiSpecRead, OpenApiSpecEdit, } from "./library/OpenApiSpecBlock.js";
66
+ export { openApiSpecSchema, openApiSpecMdx, } from "./library/openapi-spec.config.js";
42
67
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/blocks/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,oBAAoB;AACpB,OAAO,EACL,WAAW,GAUZ,MAAM,YAAY,CAAC;AAEpB,0BAA0B;AAC1B,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,wBAAwB,GACzB,MAAM,eAAe,CAAC;AAEvB,YAAY;AACZ,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,sBAAsB;AACtB,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,UAAU,GAGX,MAAM,6BAA6B,CAAC;AAErC,+EAA+E;AAC/E,OAAO,EACL,IAAI,EACJ,UAAU,EACV,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,GAKf,MAAM,UAAU,CAAC;AAElB,sBAAsB;AACtB,OAAO,EACL,sBAAsB,EACtB,8BAA8B,GAE/B,MAAM,YAAY,CAAC;AAEpB,6EAA6E;AAC7E,oDAAoD;AACpD,OAAO,EACL,cAAc,EACd,cAAc,EACd,eAAe,GAChB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,eAAe,EACf,YAAY,GAGb,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EACL,WAAW,EACX,QAAQ,GAET,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EACL,cAAc,EACd,WAAW,GAGZ,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EACL,UAAU,EACV,OAAO,GAER,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EACL,UAAU,EACV,OAAO,GAGR,MAAM,0BAA0B,CAAC","sourcesContent":["/**\n * `@agent-native/core/blocks` — the first-party block registry.\n *\n * A block registry unifies structured document blocks under one `defineBlock`\n * contract: a zod `schema` for the data, an `mdx` config for byte-stable MDX\n * round-trip, a `Read` renderer, an optional `Edit` (auto-generated from the\n * schema when omitted), and `placement` (top-level and/or inline). Apps create a\n * `BlockRegistry`, register the core standard library plus their own specs, and\n * render through `BlockView` inside a `BlockRegistryProvider`. The renderer\n * checks the registry first and falls back to legacy code for unregistered\n * types, so existing documents keep working unchanged.\n *\n * This entry includes the React surface. For server/agent code that must stay\n * React-free, import from `@agent-native/core/blocks/server`.\n */\n\n// Types + authoring\nexport {\n defineBlock,\n type BlockSpec,\n type BlockPlacement,\n type BlockMdxConfig,\n type BlockAttrReader,\n type BlockRenderContext,\n type BlockReadProps,\n type BlockEditProps,\n type MdxAttrValue,\n type NestedBlock,\n} from \"./types.js\";\n\n// Registry + provisioning\nexport { BlockRegistry, registerBlocks } from \"./registry.js\";\nexport {\n BlockRegistryProvider,\n useBlockRegistry,\n useOptionalBlockRegistry,\n} from \"./provider.js\";\n\n// Rendering\nexport { BlockView } from \"./BlockView.js\";\nexport { SchemaBlockEditor } from \"./SchemaBlockEditor.js\";\n\n// Schema-form helpers\nexport {\n markdown,\n richtext,\n introspect,\n type FieldKind,\n type FieldDescriptor,\n} from \"./schema-form/introspect.js\";\n\n// MDX round-trip (registry-driven serialize/parse + shared encoder primitives)\nexport {\n prop,\n escapeAttr,\n jsonExpression,\n attributeValue,\n createAttrReader,\n serializeSpecBlock,\n parseSpecBlock,\n type MdxJsxNode,\n type MdxAttrNode,\n type SerializableBlock,\n type ParsedBlockBase,\n} from \"./mdx.js\";\n\n// Agent schema export\nexport {\n describeBlocksForAgent,\n renderBlockVocabularyReference,\n type BlockAgentDoc,\n} from \"./agent.js\";\n\n// Standard block library (React specs). Apps register these in their browser\n// registry alongside their own app-specific blocks.\nexport {\n checklistBlock,\n ChecklistBlock,\n ChecklistEditor,\n} from \"./library/checklist.js\";\nexport {\n checklistSchema,\n checklistMdx,\n type ChecklistData,\n type ChecklistItem,\n} from \"./library/checklist.config.js\";\nexport { tableBlock } from \"./library/table.js\";\nexport {\n tableSchema,\n tableMdx,\n type TableData,\n} from \"./library/table.config.js\";\nexport { codeTabsBlock } from \"./library/code-tabs.js\";\nexport {\n codeTabsSchema,\n codeTabsMdx,\n type CodeTabsData,\n type CodeTabsTab,\n} from \"./library/code-tabs.config.js\";\nexport { htmlBlock, HtmlReadBlock, HtmlEditBlock } from \"./library/html.js\";\nexport {\n htmlSchema,\n htmlMdx,\n type HtmlBlockData,\n} from \"./library/html.config.js\";\nexport { tabsBlock, TabsBlockReader, TabsBlockEditor } from \"./library/tabs.js\";\nexport {\n tabsSchema,\n tabsMdx,\n type TabsData,\n type TabsTab,\n} from \"./library/tabs.config.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/blocks/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `@agent-native/core/blocks` — the first-party block registry.\n *\n * A block registry unifies structured document blocks under one `defineBlock`\n * contract: a zod `schema` for the data, an `mdx` config for byte-stable MDX\n * round-trip, a `Read` renderer, an optional `Edit` (auto-generated from the\n * schema when omitted), and `placement` (top-level and/or inline). Apps create a\n * `BlockRegistry`, register the core standard library plus their own specs, and\n * render through `BlockView` inside a `BlockRegistryProvider`. The renderer\n * checks the registry first and falls back to legacy code for unregistered\n * types, so existing documents keep working unchanged.\n *\n * This entry includes the React surface. For server/agent code that must stay\n * React-free, import from `@agent-native/core/blocks/server`.\n */\n\n// Types + authoring\nexport {\n defineBlock,\n type BlockSpec,\n type BlockPlacement,\n type BlockMdxConfig,\n type BlockAttrReader,\n type BlockRenderContext,\n type BlockReadProps,\n type BlockEditProps,\n type MdxAttrValue,\n type NestedBlock,\n} from \"./types.js\";\n\n// Registry + provisioning\nexport { BlockRegistry, registerBlocks } from \"./registry.js\";\nexport {\n BlockRegistryProvider,\n useBlockRegistry,\n useOptionalBlockRegistry,\n} from \"./provider.js\";\n\n// Rendering\nexport { BlockView, blockEditSurface } from \"./BlockView.js\";\nexport { SchemaBlockEditor } from \"./SchemaBlockEditor.js\";\n\n// Schema-form helpers\nexport {\n markdown,\n richtext,\n introspect,\n type FieldKind,\n type FieldDescriptor,\n} from \"./schema-form/introspect.js\";\n\n// MDX round-trip (registry-driven serialize/parse + shared encoder primitives)\nexport {\n prop,\n escapeAttr,\n jsonExpression,\n attributeValue,\n createAttrReader,\n serializeSpecBlock,\n parseSpecBlock,\n type MdxJsxNode,\n type MdxAttrNode,\n type SerializableBlock,\n type ParsedBlockBase,\n} from \"./mdx.js\";\n\n// Agent schema export\nexport {\n describeBlocksForAgent,\n renderBlockVocabularyReference,\n type BlockAgentDoc,\n} from \"./agent.js\";\n\n// Standard library registration. Apps call `registerLibraryBlocks(registry)` to\n// register the whole standard library (the five pre-built specs + the eight\n// dev-doc specs) in one place, then register only their app-specific blocks on\n// top. `libraryBlockSpecs` is the underlying ordered array.\nexport {\n libraryBlockSpecs,\n registerLibraryBlocks,\n type LibraryBlockOverrides,\n} from \"./library/specs.js\";\n\n// Standard block library (React specs). Apps register these in their browser\n// registry alongside their own app-specific blocks.\nexport {\n checklistBlock,\n ChecklistBlock,\n ChecklistEditor,\n} from \"./library/checklist.js\";\nexport {\n checklistSchema,\n checklistMdx,\n type ChecklistData,\n type ChecklistItem,\n} from \"./library/checklist.config.js\";\nexport { tableBlock } from \"./library/table.js\";\nexport {\n tableSchema,\n tableMdx,\n type TableData,\n} from \"./library/table.config.js\";\nexport { codeTabsBlock } from \"./library/code-tabs.js\";\nexport {\n codeTabsSchema,\n codeTabsMdx,\n type CodeTabsData,\n type CodeTabsTab,\n} from \"./library/code-tabs.config.js\";\nexport { htmlBlock, HtmlReadBlock, HtmlEditBlock } from \"./library/html.js\";\nexport {\n htmlSchema,\n htmlMdx,\n type HtmlBlockData,\n} from \"./library/html.config.js\";\nexport { tabsBlock, TabsBlockReader, TabsBlockEditor } from \"./library/tabs.js\";\nexport {\n tabsSchema,\n tabsMdx,\n type TabsData,\n type TabsTab,\n} from \"./library/tabs.config.js\";\n\n// Dev-doc block library (React `Read`/`Edit` renderers + their React-free\n// schema/MDX config). Apps register these alongside their own blocks, supplying\n// app-specific spec metadata (label/description/editSurface/empty) via\n// `defineBlock`. Mirrors the standard library above.\nexport { MermaidRead, MermaidEdit } from \"./library/MermaidBlock.js\";\nexport {\n mermaidSchema,\n mermaidMdx,\n type MermaidData,\n} from \"./library/mermaid.config.js\";\nexport {\n ApiEndpointRead,\n ApiEndpointEdit,\n} from \"./library/ApiEndpointBlock.js\";\nexport {\n apiEndpointSchema,\n apiEndpointMdx,\n API_ENDPOINT_METHODS,\n API_PARAM_LOCATIONS,\n type ApiEndpointData,\n type ApiEndpointMethod,\n type ApiEndpointParam,\n type ApiEndpointRequest,\n type ApiEndpointResponse,\n type ApiParamLocation,\n} from \"./library/api-endpoint.config.js\";\nexport { DataModelRead, DataModelEdit } from \"./library/DataModelBlock.js\";\nexport {\n dataModelSchema,\n dataModelMdx,\n DATA_MODEL_RELATION_KINDS,\n type DataModelData,\n type DataModelEntity,\n type DataModelField,\n type DataModelRelation,\n type DataModelRelationKind,\n} from \"./library/data-model.config.js\";\nexport { DiffRead, DiffEdit } from \"./library/DiffBlock.js\";\nexport {\n diffSchema,\n diffMdx,\n type DiffData,\n type DiffMode,\n} from \"./library/diff.config.js\";\nexport { FileTreeRead, FileTreeEdit } from \"./library/FileTreeBlock.js\";\nexport {\n fileTreeSchema,\n fileTreeMdx,\n FILE_TREE_CHANGES,\n type FileTreeData,\n type FileTreeEntry,\n type FileTreeChange,\n} from \"./library/file-tree.config.js\";\nexport {\n JsonExplorerRead,\n JsonExplorerEdit,\n} from \"./library/JsonExplorerBlock.js\";\nexport {\n jsonExplorerSchema,\n jsonExplorerMdx,\n type JsonExplorerData,\n} from \"./library/json-explorer.config.js\";\nexport {\n AnnotatedCodeRead,\n AnnotatedCodeEdit,\n} from \"./library/AnnotatedCodeBlock.js\";\nexport {\n annotatedCodeSchema,\n annotatedCodeMdx,\n type AnnotatedCodeData,\n type AnnotatedCodeAnnotation,\n} from \"./library/annotated-code.config.js\";\nexport {\n OpenApiSpecRead,\n OpenApiSpecEdit,\n} from \"./library/OpenApiSpecBlock.js\";\nexport {\n openApiSpecSchema,\n openApiSpecMdx,\n type OpenApiSpecData,\n} from \"./library/openapi-spec.config.js\";\n"]}
@@ -0,0 +1,6 @@
1
+ import type { BlockEditProps, BlockReadProps } from "../types.js";
2
+ import type { AnnotatedCodeData } from "./annotated-code.config.js";
3
+ declare function AnnotatedCodeRead({ data, blockId, title, summary, ctx, }: BlockReadProps<AnnotatedCodeData>): import("react/jsx-runtime").JSX.Element;
4
+ declare function AnnotatedCodeEdit({ data, onChange, editable, }: BlockEditProps<AnnotatedCodeData>): import("react/jsx-runtime").JSX.Element;
5
+ export { AnnotatedCodeRead, AnnotatedCodeEdit };
6
+ //# sourceMappingURL=AnnotatedCodeBlock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnnotatedCodeBlock.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/AnnotatedCodeBlock.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,KAAK,EAEV,iBAAiB,EAClB,MAAM,4BAA4B,CAAC;AAsDpC,iBAAS,iBAAiB,CAAC,EACzB,IAAI,EACJ,OAAO,EACP,KAAK,EACL,OAAO,EACP,GAAG,GACJ,EAAE,cAAc,CAAC,iBAAiB,CAAC,2CAmOnC;AAMD,iBAAS,iBAAiB,CAAC,EACzB,IAAI,EACJ,QAAQ,EACR,QAAQ,GACT,EAAE,cAAc,CAAC,iBAAiB,CAAC,2CAiJnC;AAED,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,CAAC"}