@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
@@ -0,0 +1,229 @@
1
+ import { defineBlock } from "../types.js";
2
+ import { registerBlocks } from "../registry.js";
3
+ // Pre-built standard library specs (schema + mdx + React Read/Edit all bundled).
4
+ import { checklistBlock } from "./checklist.js";
5
+ import { tableBlock } from "./table.js";
6
+ import { codeTabsBlock } from "./code-tabs.js";
7
+ import { htmlBlock } from "./html.js";
8
+ import { tabsBlock } from "./tabs.js";
9
+ // Dev-doc blocks: React-free schema + MDX config paired with the shared React
10
+ // Read/Edit renderers. Composed into full specs below with canonical metadata.
11
+ import { mermaidSchema, mermaidMdx, } from "./mermaid.config.js";
12
+ import { MermaidRead, MermaidEdit } from "./MermaidBlock.js";
13
+ import { apiEndpointSchema, apiEndpointMdx, } from "./api-endpoint.config.js";
14
+ import { ApiEndpointRead, ApiEndpointEdit } from "./ApiEndpointBlock.js";
15
+ import { openApiSpecSchema, openApiSpecMdx, } from "./openapi-spec.config.js";
16
+ import { OpenApiSpecRead, OpenApiSpecEdit } from "./OpenApiSpecBlock.js";
17
+ import { dataModelSchema, dataModelMdx, } from "./data-model.config.js";
18
+ import { DataModelRead, DataModelEdit } from "./DataModelBlock.js";
19
+ import { diffSchema, diffMdx } from "./diff.config.js";
20
+ import { DiffRead, DiffEdit } from "./DiffBlock.js";
21
+ import { fileTreeSchema, fileTreeMdx, } from "./file-tree.config.js";
22
+ import { FileTreeRead, FileTreeEdit } from "./FileTreeBlock.js";
23
+ import { jsonExplorerSchema, jsonExplorerMdx, } from "./json-explorer.config.js";
24
+ import { JsonExplorerRead, JsonExplorerEdit } from "./JsonExplorerBlock.js";
25
+ import { annotatedCodeSchema, annotatedCodeMdx, } from "./annotated-code.config.js";
26
+ import { AnnotatedCodeRead, AnnotatedCodeEdit } from "./AnnotatedCodeBlock.js";
27
+ /**
28
+ * Canonical specs for the standard library's dev-doc blocks (Mermaid, API
29
+ * endpoint, OpenAPI spec, data model, diff, file tree, JSON explorer, annotated
30
+ * code). Each pairs the shared React-free schema/MDX config with the shared
31
+ * React `Read`/`Edit` renderers and the canonical label/description/editSurface/
32
+ * empty metadata. Apps that need a slightly different label/description/empty for
33
+ * a block pass an override to {@link registerLibraryBlocks} rather than
34
+ * re-authoring the whole spec.
35
+ *
36
+ * The five fully pre-built standard specs (checklist, table, code-tabs, html,
37
+ * tabs) already bundle their metadata in their own modules, so they are appended
38
+ * by {@link libraryBlockSpecs} rather than re-declared here.
39
+ */
40
+ // Typed `BlockSpec<any>[]` (not `BlockSpec<unknown>[]`) so the per-block generic
41
+ // data types coexist in one array — mirroring `registerBlocks`' own signature,
42
+ // where `childrenField: keyof TData` would otherwise collapse to `never`.
43
+ const devDocBlockSpecs = [
44
+ defineBlock({
45
+ type: "mermaid",
46
+ schema: mermaidSchema,
47
+ mdx: mermaidMdx,
48
+ Read: MermaidRead,
49
+ Edit: MermaidEdit,
50
+ placement: ["block"],
51
+ editSurface: "panel",
52
+ label: "Diagram (Mermaid)",
53
+ description: "A Mermaid diagram (flowchart, sequence, etc.) defined as text and rendered as a diagram.",
54
+ empty: () => ({
55
+ source: "flowchart TD\n A[Start] --> B{Decision}\n B -->|Yes| C[Do it]\n B -->|No| D[Skip]",
56
+ }),
57
+ }),
58
+ defineBlock({
59
+ type: "api-endpoint",
60
+ schema: apiEndpointSchema,
61
+ mdx: apiEndpointMdx,
62
+ Read: ApiEndpointRead,
63
+ Edit: ApiEndpointEdit,
64
+ placement: ["block"],
65
+ editSurface: "panel",
66
+ label: "API endpoint",
67
+ description: "A Swagger-style API endpoint reference: a colored method pill + path, collapsed by default, expanding to params, request body, and per-status response examples.",
68
+ empty: () => ({ method: "GET", path: "/api/resource" }),
69
+ }),
70
+ defineBlock({
71
+ type: "openapi-spec",
72
+ schema: openApiSpecSchema,
73
+ mdx: openApiSpecMdx,
74
+ Read: OpenApiSpecRead,
75
+ Edit: OpenApiSpecEdit,
76
+ placement: ["block"],
77
+ editSurface: "panel",
78
+ label: "OpenAPI spec",
79
+ description: "A whole-document Redoc / Swagger-UI-style API reference rendered from a complete OpenAPI 3 / Swagger 2 spec (JSON): operations grouped by tag, each a collapsible row expanding to params, request body, and per-status responses, with $ref models resolved.",
80
+ empty: () => ({
81
+ spec: JSON.stringify({
82
+ openapi: "3.0.0",
83
+ info: { title: "Example API", version: "1.0.0" },
84
+ tags: [{ name: "widgets", description: "Manage widgets" }],
85
+ paths: {
86
+ "/widgets": {
87
+ get: {
88
+ tags: ["widgets"],
89
+ summary: "List widgets",
90
+ responses: { "200": { description: "OK" } },
91
+ },
92
+ },
93
+ },
94
+ }, null, 2),
95
+ }),
96
+ }),
97
+ defineBlock({
98
+ type: "data-model",
99
+ schema: dataModelSchema,
100
+ mdx: dataModelMdx,
101
+ Read: DataModelRead,
102
+ Edit: DataModelEdit,
103
+ placement: ["block"],
104
+ editSurface: "panel",
105
+ label: "Data model",
106
+ description: "An ERD / dbdiagram-style data model: entity cards with typed fields (PK/FK/nullable flags) and interactive foreign-key relations.",
107
+ empty: () => ({
108
+ entities: [
109
+ {
110
+ id: "e_user",
111
+ name: "User",
112
+ fields: [
113
+ { name: "id", type: "uuid", pk: true },
114
+ { name: "email", type: "text" },
115
+ ],
116
+ },
117
+ ],
118
+ }),
119
+ }),
120
+ defineBlock({
121
+ type: "diff",
122
+ schema: diffSchema,
123
+ mdx: diffMdx,
124
+ Read: DiffRead,
125
+ Edit: DiffEdit,
126
+ placement: ["block"],
127
+ editSurface: "panel",
128
+ label: "Diff",
129
+ description: "A GitHub-style before/after line diff for a file, with unified or split (side-by-side) view, added/removed line highlighting, and collapsible unchanged runs.",
130
+ empty: () => ({
131
+ before: "function add(a, b) {\n return a + b;\n}",
132
+ after: "function add(a: number, b: number): number {\n return a + b;\n}",
133
+ language: "ts",
134
+ }),
135
+ }),
136
+ defineBlock({
137
+ type: "file-tree",
138
+ schema: fileTreeSchema,
139
+ mdx: fileTreeMdx,
140
+ Read: FileTreeRead,
141
+ Edit: FileTreeEdit,
142
+ placement: ["block"],
143
+ editSurface: "panel",
144
+ label: "File tree",
145
+ description: "A VS Code / GitHub-explorer file and change tree derived from slash-delimited paths, with per-file change badges (added/modified/removed/renamed), notes, and code snippets.",
146
+ empty: () => ({
147
+ entries: [
148
+ {
149
+ path: "src/index.ts",
150
+ change: "modified",
151
+ note: "Wire the new route here.",
152
+ },
153
+ { path: "src/routes/git.ts", change: "added" },
154
+ ],
155
+ }),
156
+ }),
157
+ defineBlock({
158
+ type: "json-explorer",
159
+ schema: jsonExplorerSchema,
160
+ mdx: jsonExplorerMdx,
161
+ Read: JsonExplorerRead,
162
+ Edit: JsonExplorerEdit,
163
+ placement: ["block"],
164
+ editSurface: "panel",
165
+ label: "JSON explorer",
166
+ description: "A collapsible browser-devtools / Postman-style JSON tree with type-colored values and expand/collapse.",
167
+ empty: () => ({
168
+ json: JSON.stringify({
169
+ id: "abc123",
170
+ active: true,
171
+ tags: ["alpha", "beta"],
172
+ meta: { count: 2, owner: null },
173
+ }, null, 2),
174
+ }),
175
+ }),
176
+ defineBlock({
177
+ type: "annotated-code",
178
+ schema: annotatedCodeSchema,
179
+ mdx: annotatedCodeMdx,
180
+ Read: AnnotatedCodeRead,
181
+ Edit: AnnotatedCodeEdit,
182
+ placement: ["block"],
183
+ editSurface: "panel",
184
+ label: "Annotated code",
185
+ description: "A line-numbered code walkthrough whose line ranges carry anchored explanatory notes (Stripe-docs / Sourcegraph 'explain this code' style).",
186
+ empty: () => ({
187
+ language: "ts",
188
+ code: "export function resolveAuth(provider: string) {\n const cfg = providers[provider];\n return cfg.token;\n}",
189
+ annotations: [
190
+ {
191
+ lines: "2",
192
+ label: "Lookup",
193
+ note: "Resolves the provider config by key.",
194
+ },
195
+ ],
196
+ }),
197
+ }),
198
+ ];
199
+ /**
200
+ * The full standard library spec set, in registration order: the five fully
201
+ * pre-built specs (checklist, table, code-tabs, html, tabs) followed by the
202
+ * eight dev-doc specs. This is the single list both the plan and content browser
203
+ * registries register — adding a 14th library block here lands in both apps.
204
+ */
205
+ export const libraryBlockSpecs = [
206
+ checklistBlock,
207
+ tableBlock,
208
+ codeTabsBlock,
209
+ htmlBlock,
210
+ tabsBlock,
211
+ ...devDocBlockSpecs,
212
+ ];
213
+ /**
214
+ * Register the standard library block specs into a {@link BlockRegistry}. Both
215
+ * the plan and content browser registries call this, then register only their
216
+ * own app-specific blocks on top — so the shared library lives in exactly one
217
+ * place. Pass `overrides` (keyed by canonical `type`) for the small per-app
218
+ * differences (content re-types `table` → `table-block`; each app phrases the
219
+ * Mermaid description and seeds the OpenAPI example a little differently).
220
+ */
221
+ export function registerLibraryBlocks(registry, options = {}) {
222
+ const overrides = options.overrides ?? {};
223
+ const specs = libraryBlockSpecs.map((spec) => {
224
+ const override = overrides[spec.type];
225
+ return override ? { ...spec, ...override } : spec;
226
+ });
227
+ registerBlocks(registry, specs);
228
+ }
229
+ //# sourceMappingURL=specs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"specs.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/specs.tsx"],"names":[],"mappings":"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","sourcesContent":["import { defineBlock, type BlockSpec } from \"../types.js\";\nimport { registerBlocks, type BlockRegistry } from \"../registry.js\";\n\n// Pre-built standard library specs (schema + mdx + React Read/Edit all bundled).\nimport { checklistBlock } from \"./checklist.js\";\nimport { tableBlock } from \"./table.js\";\nimport { codeTabsBlock } from \"./code-tabs.js\";\nimport { htmlBlock } from \"./html.js\";\nimport { tabsBlock } from \"./tabs.js\";\n\n// Dev-doc blocks: React-free schema + MDX config paired with the shared React\n// Read/Edit renderers. Composed into full specs below with canonical metadata.\nimport {\n mermaidSchema,\n mermaidMdx,\n type MermaidData,\n} from \"./mermaid.config.js\";\nimport { MermaidRead, MermaidEdit } from \"./MermaidBlock.js\";\nimport {\n apiEndpointSchema,\n apiEndpointMdx,\n type ApiEndpointData,\n} from \"./api-endpoint.config.js\";\nimport { ApiEndpointRead, ApiEndpointEdit } from \"./ApiEndpointBlock.js\";\nimport {\n openApiSpecSchema,\n openApiSpecMdx,\n type OpenApiSpecData,\n} from \"./openapi-spec.config.js\";\nimport { OpenApiSpecRead, OpenApiSpecEdit } from \"./OpenApiSpecBlock.js\";\nimport {\n dataModelSchema,\n dataModelMdx,\n type DataModelData,\n} from \"./data-model.config.js\";\nimport { DataModelRead, DataModelEdit } from \"./DataModelBlock.js\";\nimport { diffSchema, diffMdx, type DiffData } from \"./diff.config.js\";\nimport { DiffRead, DiffEdit } from \"./DiffBlock.js\";\nimport {\n fileTreeSchema,\n fileTreeMdx,\n type FileTreeData,\n} from \"./file-tree.config.js\";\nimport { FileTreeRead, FileTreeEdit } from \"./FileTreeBlock.js\";\nimport {\n jsonExplorerSchema,\n jsonExplorerMdx,\n type JsonExplorerData,\n} from \"./json-explorer.config.js\";\nimport { JsonExplorerRead, JsonExplorerEdit } from \"./JsonExplorerBlock.js\";\nimport {\n annotatedCodeSchema,\n annotatedCodeMdx,\n type AnnotatedCodeData,\n} from \"./annotated-code.config.js\";\nimport { AnnotatedCodeRead, AnnotatedCodeEdit } from \"./AnnotatedCodeBlock.js\";\n\n/**\n * Canonical specs for the standard library's dev-doc blocks (Mermaid, API\n * endpoint, OpenAPI spec, data model, diff, file tree, JSON explorer, annotated\n * code). Each pairs the shared React-free schema/MDX config with the shared\n * React `Read`/`Edit` renderers and the canonical label/description/editSurface/\n * empty metadata. Apps that need a slightly different label/description/empty for\n * a block pass an override to {@link registerLibraryBlocks} rather than\n * re-authoring the whole spec.\n *\n * The five fully pre-built standard specs (checklist, table, code-tabs, html,\n * tabs) already bundle their metadata in their own modules, so they are appended\n * by {@link libraryBlockSpecs} rather than re-declared here.\n */\n// Typed `BlockSpec<any>[]` (not `BlockSpec<unknown>[]`) so the per-block generic\n// data types coexist in one array — mirroring `registerBlocks`' own signature,\n// where `childrenField: keyof TData` would otherwise collapse to `never`.\nconst devDocBlockSpecs: BlockSpec<any>[] = [\n defineBlock<MermaidData>({\n type: \"mermaid\",\n schema: mermaidSchema,\n mdx: mermaidMdx,\n Read: MermaidRead,\n Edit: MermaidEdit,\n placement: [\"block\"],\n editSurface: \"panel\",\n label: \"Diagram (Mermaid)\",\n description:\n \"A Mermaid diagram (flowchart, sequence, etc.) defined as text and rendered as a diagram.\",\n empty: () => ({\n source:\n \"flowchart TD\\n A[Start] --> B{Decision}\\n B -->|Yes| C[Do it]\\n B -->|No| D[Skip]\",\n }),\n }),\n defineBlock<ApiEndpointData>({\n type: \"api-endpoint\",\n schema: apiEndpointSchema,\n mdx: apiEndpointMdx,\n Read: ApiEndpointRead,\n Edit: ApiEndpointEdit,\n placement: [\"block\"],\n editSurface: \"panel\",\n label: \"API endpoint\",\n description:\n \"A Swagger-style API endpoint reference: a colored method pill + path, collapsed by default, expanding to params, request body, and per-status response examples.\",\n empty: () => ({ method: \"GET\", path: \"/api/resource\" }),\n }),\n defineBlock<OpenApiSpecData>({\n type: \"openapi-spec\",\n schema: openApiSpecSchema,\n mdx: openApiSpecMdx,\n Read: OpenApiSpecRead,\n Edit: OpenApiSpecEdit,\n placement: [\"block\"],\n editSurface: \"panel\",\n label: \"OpenAPI spec\",\n description:\n \"A whole-document Redoc / Swagger-UI-style API reference rendered from a complete OpenAPI 3 / Swagger 2 spec (JSON): operations grouped by tag, each a collapsible row expanding to params, request body, and per-status responses, with $ref models resolved.\",\n empty: () => ({\n spec: JSON.stringify(\n {\n openapi: \"3.0.0\",\n info: { title: \"Example API\", version: \"1.0.0\" },\n tags: [{ name: \"widgets\", description: \"Manage widgets\" }],\n paths: {\n \"/widgets\": {\n get: {\n tags: [\"widgets\"],\n summary: \"List widgets\",\n responses: { \"200\": { description: \"OK\" } },\n },\n },\n },\n },\n null,\n 2,\n ),\n }),\n }),\n defineBlock<DataModelData>({\n type: \"data-model\",\n schema: dataModelSchema,\n mdx: dataModelMdx,\n Read: DataModelRead,\n Edit: DataModelEdit,\n placement: [\"block\"],\n editSurface: \"panel\",\n label: \"Data model\",\n description:\n \"An ERD / dbdiagram-style data model: entity cards with typed fields (PK/FK/nullable flags) and interactive foreign-key relations.\",\n empty: () => ({\n entities: [\n {\n id: \"e_user\",\n name: \"User\",\n fields: [\n { name: \"id\", type: \"uuid\", pk: true },\n { name: \"email\", type: \"text\" },\n ],\n },\n ],\n }),\n }),\n defineBlock<DiffData>({\n type: \"diff\",\n schema: diffSchema,\n mdx: diffMdx,\n Read: DiffRead,\n Edit: DiffEdit,\n placement: [\"block\"],\n editSurface: \"panel\",\n label: \"Diff\",\n description:\n \"A GitHub-style before/after line diff for a file, with unified or split (side-by-side) view, added/removed line highlighting, and collapsible unchanged runs.\",\n empty: () => ({\n before: \"function add(a, b) {\\n return a + b;\\n}\",\n after: \"function add(a: number, b: number): number {\\n return a + b;\\n}\",\n language: \"ts\",\n }),\n }),\n defineBlock<FileTreeData>({\n type: \"file-tree\",\n schema: fileTreeSchema,\n mdx: fileTreeMdx,\n Read: FileTreeRead,\n Edit: FileTreeEdit,\n placement: [\"block\"],\n editSurface: \"panel\",\n label: \"File tree\",\n description:\n \"A VS Code / GitHub-explorer file and change tree derived from slash-delimited paths, with per-file change badges (added/modified/removed/renamed), notes, and code snippets.\",\n empty: () => ({\n entries: [\n {\n path: \"src/index.ts\",\n change: \"modified\",\n note: \"Wire the new route here.\",\n },\n { path: \"src/routes/git.ts\", change: \"added\" },\n ],\n }),\n }),\n defineBlock<JsonExplorerData>({\n type: \"json-explorer\",\n schema: jsonExplorerSchema,\n mdx: jsonExplorerMdx,\n Read: JsonExplorerRead,\n Edit: JsonExplorerEdit,\n placement: [\"block\"],\n editSurface: \"panel\",\n label: \"JSON explorer\",\n description:\n \"A collapsible browser-devtools / Postman-style JSON tree with type-colored values and expand/collapse.\",\n empty: () => ({\n json: JSON.stringify(\n {\n id: \"abc123\",\n active: true,\n tags: [\"alpha\", \"beta\"],\n meta: { count: 2, owner: null },\n },\n null,\n 2,\n ),\n }),\n }),\n defineBlock<AnnotatedCodeData>({\n type: \"annotated-code\",\n schema: annotatedCodeSchema,\n mdx: annotatedCodeMdx,\n Read: AnnotatedCodeRead,\n Edit: AnnotatedCodeEdit,\n placement: [\"block\"],\n editSurface: \"panel\",\n label: \"Annotated code\",\n description:\n \"A line-numbered code walkthrough whose line ranges carry anchored explanatory notes (Stripe-docs / Sourcegraph 'explain this code' style).\",\n empty: () => ({\n language: \"ts\",\n code: \"export function resolveAuth(provider: string) {\\n const cfg = providers[provider];\\n return cfg.token;\\n}\",\n annotations: [\n {\n lines: \"2\",\n label: \"Lookup\",\n note: \"Resolves the provider config by key.\",\n },\n ],\n }),\n }),\n];\n\n/**\n * The full standard library spec set, in registration order: the five fully\n * pre-built specs (checklist, table, code-tabs, html, tabs) followed by the\n * eight dev-doc specs. This is the single list both the plan and content browser\n * registries register — adding a 14th library block here lands in both apps.\n */\nexport const libraryBlockSpecs: BlockSpec<any>[] = [\n checklistBlock,\n tableBlock,\n codeTabsBlock,\n htmlBlock,\n tabsBlock,\n ...devDocBlockSpecs,\n];\n\n/**\n * Per-block metadata overrides for {@link registerLibraryBlocks}, keyed by the\n * canonical block `type`. Lets an app tweak the few fields that legitimately\n * differ (a `type` rename, a tweaked `description` or `empty` seed) without\n * re-authoring the spec. Anything omitted keeps the canonical value, so the\n * schema / MDX config and the React `Read`/`Edit` renderers always stay shared.\n */\nexport type LibraryBlockOverrides = Record<\n string,\n Partial<Pick<BlockSpec<any>, \"type\" | \"label\" | \"description\" | \"empty\">>\n>;\n\n/**\n * Register the standard library block specs into a {@link BlockRegistry}. Both\n * the plan and content browser registries call this, then register only their\n * own app-specific blocks on top — so the shared library lives in exactly one\n * place. Pass `overrides` (keyed by canonical `type`) for the small per-app\n * differences (content re-types `table` → `table-block`; each app phrases the\n * Mermaid description and seeds the OpenAPI example a little differently).\n */\nexport function registerLibraryBlocks(\n registry: BlockRegistry,\n options: { overrides?: LibraryBlockOverrides } = {},\n): void {\n const overrides = options.overrides ?? {};\n const specs = libraryBlockSpecs.map((spec) => {\n const override = overrides[spec.type];\n return override ? ({ ...spec, ...override } as BlockSpec<any>) : spec;\n });\n registerBlocks(registry, specs);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/table.tsx"],"names":[],"mappings":"AAUA,OAAO,EAAyB,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAyO1E;;;;GAIG;AACH,eAAO,MAAM,UAAU,4CAoBrB,CAAC"}
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/table.tsx"],"names":[],"mappings":"AAUA,OAAO,EAAyB,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAyO1E;;;;GAIG;AACH,eAAO,MAAM,UAAU,4CAsBrB,CAAC"}
@@ -21,7 +21,7 @@ import { tableMdx, tableSchema } from "./table.config.js";
21
21
  * `CalloutBlock` read renderer.
22
22
  */
23
23
  function TableBlockRead({ data, blockId, title }) {
24
- return (_jsxs("section", { className: "plan-block overflow-x-auto", "data-block-id": blockId, children: [title && _jsx("h2", { children: title }), _jsxs("table", { className: "w-full min-w-[640px] border-collapse text-left", children: [_jsx("thead", { children: _jsx("tr", { className: "border-b border-plan-line text-sm text-plan-muted", children: data.columns.map((column) => (_jsx("th", { className: "py-3 pr-4 font-semibold", children: column }, column))) }) }), _jsx("tbody", { children: data.rows.map((row, index) => (_jsx("tr", { className: "border-b border-plan-line", children: row.map((cell, cellIndex) => (_jsx("td", { className: "py-4 pr-4 text-plan-muted", children: cell }, cellIndex))) }, index))) })] })] }));
24
+ return (_jsxs("section", { className: "plan-block overflow-x-auto", "data-block-id": blockId, children: [title && _jsx("div", { className: "plan-block-label", children: title }), _jsxs("table", { className: "w-full min-w-[640px] border-collapse text-left", children: [_jsx("thead", { children: _jsx("tr", { className: "border-b border-plan-line text-sm text-plan-muted", children: data.columns.map((column) => (_jsx("th", { className: "py-3 pr-4 font-semibold", children: column }, column))) }) }), _jsx("tbody", { children: data.rows.map((row, index) => (_jsx("tr", { className: "border-b border-plan-line", children: row.map((cell, cellIndex) => (_jsx("td", { className: "py-4 pr-4 text-plan-muted", children: cell }, cellIndex))) }, index))) })] })] }));
25
25
  }
26
26
  const editInputClass = "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";
27
27
  const iconButtonClass = "inline-flex size-7 items-center justify-center rounded-md border border-input text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:opacity-50";
@@ -93,6 +93,8 @@ export const tableBlock = defineBlock({
93
93
  Read: TableBlockRead,
94
94
  Edit: TableBlockEdit,
95
95
  placement: ["block"],
96
+ // A simple grid maps to an NFM table, so it round-trips to Notion.
97
+ notionCompatible: true,
96
98
  label: "Table",
97
99
  icon: ({ size, className }) => (_jsx(IconTable, { size: size, className: className })),
98
100
  description: "A simple grid with header columns and string rows for comparisons, parameters, or structured lists.",
@@ -1 +1 @@
1
- {"version":3,"file":"table.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/table.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n IconColumnInsertRight,\n IconPlus,\n IconRowInsertBottom,\n IconTable,\n IconTrash,\n IconX,\n} from \"@tabler/icons-react\";\nimport { defineBlock } from \"../types.js\";\nimport type { BlockEditProps, BlockReadProps } from \"../types.js\";\nimport { tableMdx, tableSchema, type TableData } from \"./table.config.js\";\n\n/**\n * Standard `table` block — a simple grid of header columns and string rows.\n * STANDARD library block: lives in core (`@agent-native/core/blocks`) so any\n * app can register it. The plan app's registries (server + client) import\n * {@link tableBlock} (browser) and the React-free {@link tableMdx}/\n * {@link tableSchema} config (server) so its render + MDX round-trip move out\n * of the plan `PlanBlockView` switch / `serializeBlock` into the registry,\n * while the legacy branch stays as a backward-compatible fallback for\n * unregistered renderers.\n */\n\n/**\n * Read-only renderer. Mirrors the legacy plan `PlanBlockView` table branch\n * markup byte-for-byte (same `plan-block overflow-x-auto` section + title +\n * `plan-line`/`plan-muted` table) so converting the block to the registry does\n * not change the rendered output. The `plan-*` class names are styled by the\n * consuming app's CSS — core only emits the markup, exactly like the existing\n * `CalloutBlock` read renderer.\n */\nfunction TableBlockRead({ data, blockId, title }: BlockReadProps<TableData>) {\n return (\n <section className=\"plan-block overflow-x-auto\" data-block-id={blockId}>\n {title && <h2>{title}</h2>}\n <table className=\"w-full min-w-[640px] border-collapse text-left\">\n <thead>\n <tr className=\"border-b border-plan-line text-sm text-plan-muted\">\n {data.columns.map((column) => (\n <th key={column} className=\"py-3 pr-4 font-semibold\">\n {column}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {data.rows.map((row, index) => (\n <tr key={index} className=\"border-b border-plan-line\">\n {row.map((cell, cellIndex) => (\n <td key={cellIndex} className=\"py-4 pr-4 text-plan-muted\">\n {cell}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </section>\n );\n}\n\nconst editInputClass =\n \"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 iconButtonClass =\n \"inline-flex size-7 items-center justify-center rounded-md border border-input text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:opacity-50\";\n\nconst addButtonClass =\n \"inline-flex items-center gap-1.5 rounded-md border border-input bg-transparent px-3 py-1.5 text-sm text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:opacity-50\";\n\n/**\n * Editable grid. The schema's `columns: string[]` / `rows: string[][]` are\n * positional/structured, which the schema auto-editor intentionally cannot\n * render, so this block supplies its own `Edit`: an editable header row plus a\n * body grid, with add/remove controls for both columns and rows. Every change\n * commits a full new `{ columns, rows }` value (re-validated upstream by the\n * registry), keeping rows rectangular with the column count.\n */\nfunction TableBlockEdit({\n data,\n onChange,\n editable,\n}: BlockEditProps<TableData>) {\n const columns = data.columns ?? [];\n const rows = data.rows ?? [];\n const columnCount = columns.length;\n\n const commit = (next: TableData) => onChange(next);\n\n const setColumn = (index: number, value: string) => {\n commit({\n columns: columns.map((c, i) => (i === index ? value : c)),\n rows,\n });\n };\n\n const setCell = (rowIndex: number, cellIndex: number, value: string) => {\n commit({\n columns,\n rows: rows.map((row, i) =>\n i === rowIndex\n ? row.map((cell, j) => (j === cellIndex ? value : cell))\n : row,\n ),\n });\n };\n\n const addColumn = () => {\n commit({\n columns: [...columns, `Column ${columnCount + 1}`],\n // Keep rows rectangular: append an empty cell to every row.\n rows: rows.map((row) => [...row, \"\"]),\n });\n };\n\n const removeColumn = (index: number) => {\n commit({\n columns: columns.filter((_, i) => i !== index),\n rows: rows.map((row) => row.filter((_, i) => i !== index)),\n });\n };\n\n const addRow = () => {\n commit({\n columns,\n // New row matches the current column count.\n rows: [\n ...rows,\n Array.from({ length: Math.max(columnCount, 1) }, () => \"\"),\n ],\n });\n };\n\n const removeRow = (index: number) => {\n commit({ columns, rows: rows.filter((_, i) => i !== index) });\n };\n\n return (\n <div className=\"an-table-block-editor flex flex-col gap-3\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full min-w-[480px] border-collapse text-left\">\n <thead>\n <tr>\n {columns.map((column, index) => (\n <th key={index} className=\"p-1 align-top\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"text\"\n data-plan-interactive\n aria-label={`Column ${index + 1} header`}\n className={editInputClass}\n value={column}\n disabled={!editable}\n onChange={(event) => setColumn(index, event.target.value)}\n />\n <button\n type=\"button\"\n data-plan-interactive\n aria-label={`Remove column ${index + 1}`}\n className={iconButtonClass}\n disabled={!editable}\n onClick={() => removeColumn(index)}\n >\n <IconX size={14} />\n </button>\n </div>\n </th>\n ))}\n <th className=\"p-1 align-top\">\n <button\n type=\"button\"\n data-plan-interactive\n aria-label=\"Add column\"\n className={iconButtonClass}\n disabled={!editable}\n onClick={addColumn}\n >\n <IconColumnInsertRight size={16} />\n </button>\n </th>\n </tr>\n </thead>\n <tbody>\n {rows.map((row, rowIndex) => (\n <tr key={rowIndex}>\n {Array.from({ length: columnCount }).map((_, cellIndex) => (\n <td key={cellIndex} className=\"p-1 align-top\">\n <input\n type=\"text\"\n data-plan-interactive\n aria-label={`Row ${rowIndex + 1}, column ${cellIndex + 1}`}\n className={editInputClass}\n value={row[cellIndex] ?? \"\"}\n disabled={!editable}\n onChange={(event) =>\n setCell(rowIndex, cellIndex, event.target.value)\n }\n />\n </td>\n ))}\n <td className=\"p-1 align-top\">\n <button\n type=\"button\"\n data-plan-interactive\n aria-label={`Remove row ${rowIndex + 1}`}\n className={iconButtonClass}\n disabled={!editable}\n onClick={() => removeRow(rowIndex)}\n >\n <IconTrash size={14} />\n </button>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <button\n type=\"button\"\n data-plan-interactive\n className={addButtonClass}\n disabled={!editable}\n onClick={addRow}\n >\n <IconRowInsertBottom size={16} />\n Add row\n </button>\n <button\n type=\"button\"\n data-plan-interactive\n className={addButtonClass}\n disabled={!editable}\n onClick={addColumn}\n >\n <IconPlus size={16} />\n Add column\n </button>\n </div>\n </div>\n );\n}\n\n/**\n * The full standard `table` `BlockSpec`. Pairs the React-free\n * {@link tableSchema}/{@link tableMdx} config (also used by the server registry)\n * with the React `Read`/`Edit`. `empty()` seeds a 2×2 grid for slash insertion.\n */\nexport const tableBlock = defineBlock<TableData>({\n type: \"table\",\n schema: tableSchema,\n mdx: tableMdx,\n Read: TableBlockRead,\n Edit: TableBlockEdit,\n placement: [\"block\"],\n label: \"Table\",\n icon: ({ size, className }) => (\n <IconTable size={size} className={className} />\n ),\n description:\n \"A simple grid with header columns and string rows for comparisons, parameters, or structured lists.\",\n empty: () => ({\n columns: [\"Column 1\", \"Column 2\"],\n rows: [\n [\"\", \"\"],\n [\"\", \"\"],\n ],\n }),\n});\n"]}
1
+ {"version":3,"file":"table.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/table.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n IconColumnInsertRight,\n IconPlus,\n IconRowInsertBottom,\n IconTable,\n IconTrash,\n IconX,\n} from \"@tabler/icons-react\";\nimport { defineBlock } from \"../types.js\";\nimport type { BlockEditProps, BlockReadProps } from \"../types.js\";\nimport { tableMdx, tableSchema, type TableData } from \"./table.config.js\";\n\n/**\n * Standard `table` block — a simple grid of header columns and string rows.\n * STANDARD library block: lives in core (`@agent-native/core/blocks`) so any\n * app can register it. The plan app's registries (server + client) import\n * {@link tableBlock} (browser) and the React-free {@link tableMdx}/\n * {@link tableSchema} config (server) so its render + MDX round-trip move out\n * of the plan `PlanBlockView` switch / `serializeBlock` into the registry,\n * while the legacy branch stays as a backward-compatible fallback for\n * unregistered renderers.\n */\n\n/**\n * Read-only renderer. Mirrors the legacy plan `PlanBlockView` table branch\n * markup byte-for-byte (same `plan-block overflow-x-auto` section + title +\n * `plan-line`/`plan-muted` table) so converting the block to the registry does\n * not change the rendered output. The `plan-*` class names are styled by the\n * consuming app's CSS — core only emits the markup, exactly like the existing\n * `CalloutBlock` read renderer.\n */\nfunction TableBlockRead({ data, blockId, title }: BlockReadProps<TableData>) {\n return (\n <section className=\"plan-block overflow-x-auto\" data-block-id={blockId}>\n {title && <div className=\"plan-block-label\">{title}</div>}\n <table className=\"w-full min-w-[640px] border-collapse text-left\">\n <thead>\n <tr className=\"border-b border-plan-line text-sm text-plan-muted\">\n {data.columns.map((column) => (\n <th key={column} className=\"py-3 pr-4 font-semibold\">\n {column}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {data.rows.map((row, index) => (\n <tr key={index} className=\"border-b border-plan-line\">\n {row.map((cell, cellIndex) => (\n <td key={cellIndex} className=\"py-4 pr-4 text-plan-muted\">\n {cell}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </section>\n );\n}\n\nconst editInputClass =\n \"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 iconButtonClass =\n \"inline-flex size-7 items-center justify-center rounded-md border border-input text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:opacity-50\";\n\nconst addButtonClass =\n \"inline-flex items-center gap-1.5 rounded-md border border-input bg-transparent px-3 py-1.5 text-sm text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:opacity-50\";\n\n/**\n * Editable grid. The schema's `columns: string[]` / `rows: string[][]` are\n * positional/structured, which the schema auto-editor intentionally cannot\n * render, so this block supplies its own `Edit`: an editable header row plus a\n * body grid, with add/remove controls for both columns and rows. Every change\n * commits a full new `{ columns, rows }` value (re-validated upstream by the\n * registry), keeping rows rectangular with the column count.\n */\nfunction TableBlockEdit({\n data,\n onChange,\n editable,\n}: BlockEditProps<TableData>) {\n const columns = data.columns ?? [];\n const rows = data.rows ?? [];\n const columnCount = columns.length;\n\n const commit = (next: TableData) => onChange(next);\n\n const setColumn = (index: number, value: string) => {\n commit({\n columns: columns.map((c, i) => (i === index ? value : c)),\n rows,\n });\n };\n\n const setCell = (rowIndex: number, cellIndex: number, value: string) => {\n commit({\n columns,\n rows: rows.map((row, i) =>\n i === rowIndex\n ? row.map((cell, j) => (j === cellIndex ? value : cell))\n : row,\n ),\n });\n };\n\n const addColumn = () => {\n commit({\n columns: [...columns, `Column ${columnCount + 1}`],\n // Keep rows rectangular: append an empty cell to every row.\n rows: rows.map((row) => [...row, \"\"]),\n });\n };\n\n const removeColumn = (index: number) => {\n commit({\n columns: columns.filter((_, i) => i !== index),\n rows: rows.map((row) => row.filter((_, i) => i !== index)),\n });\n };\n\n const addRow = () => {\n commit({\n columns,\n // New row matches the current column count.\n rows: [\n ...rows,\n Array.from({ length: Math.max(columnCount, 1) }, () => \"\"),\n ],\n });\n };\n\n const removeRow = (index: number) => {\n commit({ columns, rows: rows.filter((_, i) => i !== index) });\n };\n\n return (\n <div className=\"an-table-block-editor flex flex-col gap-3\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full min-w-[480px] border-collapse text-left\">\n <thead>\n <tr>\n {columns.map((column, index) => (\n <th key={index} className=\"p-1 align-top\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"text\"\n data-plan-interactive\n aria-label={`Column ${index + 1} header`}\n className={editInputClass}\n value={column}\n disabled={!editable}\n onChange={(event) => setColumn(index, event.target.value)}\n />\n <button\n type=\"button\"\n data-plan-interactive\n aria-label={`Remove column ${index + 1}`}\n className={iconButtonClass}\n disabled={!editable}\n onClick={() => removeColumn(index)}\n >\n <IconX size={14} />\n </button>\n </div>\n </th>\n ))}\n <th className=\"p-1 align-top\">\n <button\n type=\"button\"\n data-plan-interactive\n aria-label=\"Add column\"\n className={iconButtonClass}\n disabled={!editable}\n onClick={addColumn}\n >\n <IconColumnInsertRight size={16} />\n </button>\n </th>\n </tr>\n </thead>\n <tbody>\n {rows.map((row, rowIndex) => (\n <tr key={rowIndex}>\n {Array.from({ length: columnCount }).map((_, cellIndex) => (\n <td key={cellIndex} className=\"p-1 align-top\">\n <input\n type=\"text\"\n data-plan-interactive\n aria-label={`Row ${rowIndex + 1}, column ${cellIndex + 1}`}\n className={editInputClass}\n value={row[cellIndex] ?? \"\"}\n disabled={!editable}\n onChange={(event) =>\n setCell(rowIndex, cellIndex, event.target.value)\n }\n />\n </td>\n ))}\n <td className=\"p-1 align-top\">\n <button\n type=\"button\"\n data-plan-interactive\n aria-label={`Remove row ${rowIndex + 1}`}\n className={iconButtonClass}\n disabled={!editable}\n onClick={() => removeRow(rowIndex)}\n >\n <IconTrash size={14} />\n </button>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <button\n type=\"button\"\n data-plan-interactive\n className={addButtonClass}\n disabled={!editable}\n onClick={addRow}\n >\n <IconRowInsertBottom size={16} />\n Add row\n </button>\n <button\n type=\"button\"\n data-plan-interactive\n className={addButtonClass}\n disabled={!editable}\n onClick={addColumn}\n >\n <IconPlus size={16} />\n Add column\n </button>\n </div>\n </div>\n );\n}\n\n/**\n * The full standard `table` `BlockSpec`. Pairs the React-free\n * {@link tableSchema}/{@link tableMdx} config (also used by the server registry)\n * with the React `Read`/`Edit`. `empty()` seeds a 2×2 grid for slash insertion.\n */\nexport const tableBlock = defineBlock<TableData>({\n type: \"table\",\n schema: tableSchema,\n mdx: tableMdx,\n Read: TableBlockRead,\n Edit: TableBlockEdit,\n placement: [\"block\"],\n // A simple grid maps to an NFM table, so it round-trips to Notion.\n notionCompatible: true,\n label: \"Table\",\n icon: ({ size, className }) => (\n <IconTable size={size} className={className} />\n ),\n description:\n \"A simple grid with header columns and string rows for comparisons, parameters, or structured lists.\",\n empty: () => ({\n columns: [\"Column 1\", \"Column 2\"],\n rows: [\n [\"\", \"\"],\n [\"\", \"\"],\n ],\n }),\n});\n"]}
@@ -44,7 +44,7 @@ export function TabsBlockReader({ data, blockId, title, ctx, }) {
44
44
  const [activeId, setActiveId] = useState(data.tabs[0]?.id ?? "");
45
45
  const active = data.tabs.find((tab) => tab.id === activeId) ?? data.tabs[0];
46
46
  const compact = isCompact(title);
47
- return (_jsxs("section", { className: "plan-block", "data-block-id": blockId, children: [title && _jsx("h2", { children: title }), _jsx(TabRail, { tabs: data.tabs, activeId: active?.id, onSelect: setActiveId }), active && (_jsx("div", { children: active.blocks.map((child) => (_jsx("div", { children: ctx.renderBlock?.({
47
+ return (_jsxs("section", { className: "plan-block", "data-block-id": blockId, children: [title && _jsx("div", { className: "plan-block-label", children: title }), _jsx(TabRail, { tabs: data.tabs, activeId: active?.id, onSelect: setActiveId }), active && (_jsx("div", { children: active.blocks.map((child) => (_jsx("div", { children: ctx.renderBlock?.({
48
48
  block: child,
49
49
  editing: false,
50
50
  compactVisuals: compact,
@@ -1 +1 @@
1
- {"version":3,"file":"tabs.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/tabs.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from \"react\";\nimport { IconLayoutNavbar, IconPlus, IconX } from \"@tabler/icons-react\";\nimport { cn } from \"../../utils.js\";\nimport { defineBlock } from \"../types.js\";\nimport type { BlockReadProps, BlockEditProps, NestedBlock } from \"../types.js\";\nimport {\n tabsSchema,\n tabsMdx,\n type TabsData,\n type TabsTab,\n} from \"./tabs.config.js\";\n\n/**\n * Standard `tabs` block: a horizontal pill-tab container whose tabs each hold a\n * list of child blocks. Lives in core so any app (plan today, content later) can\n * register it.\n *\n * `Read`/`Edit` mirror the legacy plan `TabsBlock` markup byte-for-byte (same\n * `plan-block` section, the `inline-flex` pill tab rail with `role=\"tablist\"`/\n * `role=\"tab\"`, the same active-tab `useState`, and the `compactVisuals`\n * heuristic on the block title) so converting the block to the registry does not\n * change rendered output. The plan CSS classes (`plan-block`, `bg-plan-block`,\n * `text-plan-*`) resolve against the plan app's stylesheet at render time,\n * exactly as before.\n *\n * Child rendering flows through `ctx.renderBlock` — the app's own block\n * dispatcher — so registered children render via their spec and unconverted\n * children fall through the app's legacy switch. This is the coexistence seam:\n * the core tabs block never has to know app-specific child block types.\n */\n\n/** Mint a reasonably-unique tab id without pulling a dep into core. */\nfunction newTabId(): string {\n return `tab-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/** Compact embedded visuals for dense tab panes, matching legacy behavior. */\nfunction isCompact(title: string | undefined): boolean {\n return /interaction|component|note/i.test(title ?? \"\");\n}\n\n/** Shared pill-tab rail. */\nfunction TabRail({\n tabs,\n activeId,\n onSelect,\n}: {\n tabs: TabsTab[];\n activeId: string | undefined;\n onSelect: (id: string) => void;\n}) {\n return (\n <div\n className=\"mb-8 inline-flex max-w-full gap-1 overflow-x-auto\"\n role=\"tablist\"\n data-plan-interactive\n >\n {tabs.map((tab) => {\n const selected = tab.id === activeId;\n return (\n <button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={selected}\n onClick={() => onSelect(tab.id)}\n className={cn(\n \"rounded-lg px-4 py-2 text-sm font-semibold transition-colors\",\n selected\n ? \"bg-plan-block text-plan-text shadow-sm\"\n : \"text-plan-muted hover:bg-plan-block/60 hover:text-plan-text\",\n )}\n >\n {tab.label}\n </button>\n );\n })}\n </div>\n );\n}\n\n/** Read renderer: pill tabs, child blocks rendered read-only via the app. */\nexport function TabsBlockReader({\n data,\n blockId,\n title,\n ctx,\n}: BlockReadProps<TabsData>) {\n const [activeId, setActiveId] = useState(data.tabs[0]?.id ?? \"\");\n const active = data.tabs.find((tab) => tab.id === activeId) ?? data.tabs[0];\n const compact = isCompact(title);\n return (\n <section className=\"plan-block\" data-block-id={blockId}>\n {title && <h2>{title}</h2>}\n <TabRail tabs={data.tabs} activeId={active?.id} onSelect={setActiveId} />\n {active && (\n <div>\n {active.blocks.map((child) => (\n <div key={child.id}>\n {ctx.renderBlock?.({\n block: child,\n editing: false,\n compactVisuals: compact,\n })}\n </div>\n ))}\n </div>\n )}\n </section>\n );\n}\n\n/**\n * Editor: pill tabs plus tab management (add/remove/rename), with child blocks\n * rendered editable in place through the app dispatcher. A child change updates\n * that child within its tab and commits the whole tabs block — mirroring the\n * legacy `TabsBlock` onChange bubbling so the plan's recursive `updateBlocks`/\n * `findBlock` (`PlanContentRenderer`) keeps working unchanged.\n */\nexport function TabsBlockEditor({\n data,\n onChange,\n editable,\n blockId,\n title,\n ctx,\n}: BlockEditProps<TabsData>) {\n const [activeId, setActiveId] = useState(data.tabs[0]?.id ?? \"\");\n const active = data.tabs.find((tab) => tab.id === activeId) ?? data.tabs[0];\n const compact = isCompact(title);\n\n const commit = (tabs: TabsTab[]) => onChange({ tabs });\n\n const renameTab = (id: string, label: string) =>\n commit(data.tabs.map((tab) => (tab.id === id ? { ...tab, label } : tab)));\n\n const removeTab = (id: string) => {\n const next = data.tabs.filter((tab) => tab.id !== id);\n if (next.length === 0) return; // tabs must keep at least one (schema min 1)\n commit(next);\n if (activeId === id) setActiveId(next[0]?.id ?? \"\");\n };\n\n const addTab = () => {\n if (data.tabs.length >= 12) return; // schema max\n const id = newTabId();\n commit([\n ...data.tabs,\n { id, label: `Tab ${data.tabs.length + 1}`, blocks: [] },\n ]);\n setActiveId(id);\n };\n\n const updateChild = (tabId: string, child: NestedBlock) =>\n commit(\n data.tabs.map((tab) =>\n tab.id === tabId\n ? {\n ...tab,\n blocks: tab.blocks.map((existing) =>\n existing.id === child.id ? child : existing,\n ),\n }\n : tab,\n ),\n );\n\n // Renders BARE (no `plan-block` section / title): in edit mode the app's\n // block dispatcher already wraps registered editors in a titled `plan-block`\n // section, so wrapping again here would double-nest. The read renderer\n // (`TabsBlockReader`) owns its own section because read mode renders the spec\n // directly.\n return (\n <div data-tabs-edit-block={blockId}>\n <div\n className=\"mb-8 flex max-w-full flex-wrap items-center gap-1 overflow-x-auto\"\n role=\"tablist\"\n data-plan-interactive\n >\n {data.tabs.map((tab) => {\n const selected = tab.id === active?.id;\n return (\n <div\n key={tab.id}\n className={cn(\n \"group flex items-center gap-1 rounded-lg pr-1 transition-colors\",\n selected ? \"bg-plan-block shadow-sm\" : \"hover:bg-plan-block/60\",\n )}\n >\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={selected}\n onClick={() => setActiveId(tab.id)}\n className={cn(\n \"rounded-lg px-4 py-2 text-sm font-semibold transition-colors\",\n selected ? \"text-plan-text\" : \"text-plan-muted\",\n )}\n >\n {tab.label}\n </button>\n {editable && data.tabs.length > 1 && (\n <button\n type=\"button\"\n data-plan-interactive\n aria-label={`Remove ${tab.label}`}\n className={cn(\n \"flex size-6 shrink-0 items-center justify-center rounded text-plan-muted transition-opacity\",\n \"opacity-0 group-hover:opacity-100 group-focus-within:opacity-100\",\n \"hover:bg-muted hover:text-foreground\",\n )}\n onClick={() => removeTab(tab.id)}\n >\n <IconX className=\"size-3.5 shrink-0\" />\n </button>\n )}\n </div>\n );\n })}\n {editable && data.tabs.length < 12 && (\n <button\n type=\"button\"\n data-plan-interactive\n aria-label=\"Add tab\"\n className=\"flex items-center gap-1.5 rounded-md px-2 py-2 text-sm text-plan-muted hover:bg-plan-block/60 hover:text-plan-text\"\n onClick={addTab}\n >\n <IconPlus className=\"size-4\" />\n Add tab\n </button>\n )}\n </div>\n {active && (\n <div className=\"grid gap-3\">\n {editable && (\n <input\n type=\"text\"\n data-plan-interactive\n className=\"flex h-9 w-full max-w-xs 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\"\n placeholder=\"Tab label\"\n value={active.label}\n onChange={(event) => renameTab(active.id, event.target.value)}\n />\n )}\n <div>\n {active.blocks.map((child) => (\n <div key={child.id}>\n {ctx.renderBlock?.({\n block: child,\n editing: true,\n compactVisuals: compact,\n onChange: (next) => updateChild(active.id, next),\n })}\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n );\n}\n\n/**\n * The standard tabs block spec (with React `Read`/`Edit`). Apps register this in\n * their browser registry. The schema + MDX config come from `./tabs.config.ts`,\n * the exact same object server / agent code registers, so rendering and source\n * round-trip never drift.\n */\nexport const tabsBlock = defineBlock<TabsData>({\n type: \"tabs\",\n schema: tabsSchema,\n mdx: tabsMdx,\n Read: TabsBlockReader,\n Edit: TabsBlockEditor,\n placement: [\"block\", \"inline\"],\n label: \"Tabs\",\n icon: IconLayoutNavbar,\n description:\n \"A horizontal pill-tab container; each tab holds its own list of blocks.\",\n empty: () => ({ tabs: [{ id: newTabId(), label: \"Tab 1\", blocks: [] }] }),\n});\n"]}
1
+ {"version":3,"file":"tabs.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/tabs.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from \"react\";\nimport { IconLayoutNavbar, IconPlus, IconX } from \"@tabler/icons-react\";\nimport { cn } from \"../../utils.js\";\nimport { defineBlock } from \"../types.js\";\nimport type { BlockReadProps, BlockEditProps, NestedBlock } from \"../types.js\";\nimport {\n tabsSchema,\n tabsMdx,\n type TabsData,\n type TabsTab,\n} from \"./tabs.config.js\";\n\n/**\n * Standard `tabs` block: a horizontal pill-tab container whose tabs each hold a\n * list of child blocks. Lives in core so any app (plan today, content later) can\n * register it.\n *\n * `Read`/`Edit` mirror the legacy plan `TabsBlock` markup byte-for-byte (same\n * `plan-block` section, the `inline-flex` pill tab rail with `role=\"tablist\"`/\n * `role=\"tab\"`, the same active-tab `useState`, and the `compactVisuals`\n * heuristic on the block title) so converting the block to the registry does not\n * change rendered output. The plan CSS classes (`plan-block`, `bg-plan-block`,\n * `text-plan-*`) resolve against the plan app's stylesheet at render time,\n * exactly as before.\n *\n * Child rendering flows through `ctx.renderBlock` — the app's own block\n * dispatcher — so registered children render via their spec and unconverted\n * children fall through the app's legacy switch. This is the coexistence seam:\n * the core tabs block never has to know app-specific child block types.\n */\n\n/** Mint a reasonably-unique tab id without pulling a dep into core. */\nfunction newTabId(): string {\n return `tab-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/** Compact embedded visuals for dense tab panes, matching legacy behavior. */\nfunction isCompact(title: string | undefined): boolean {\n return /interaction|component|note/i.test(title ?? \"\");\n}\n\n/** Shared pill-tab rail. */\nfunction TabRail({\n tabs,\n activeId,\n onSelect,\n}: {\n tabs: TabsTab[];\n activeId: string | undefined;\n onSelect: (id: string) => void;\n}) {\n return (\n <div\n className=\"mb-8 inline-flex max-w-full gap-1 overflow-x-auto\"\n role=\"tablist\"\n data-plan-interactive\n >\n {tabs.map((tab) => {\n const selected = tab.id === activeId;\n return (\n <button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={selected}\n onClick={() => onSelect(tab.id)}\n className={cn(\n \"rounded-lg px-4 py-2 text-sm font-semibold transition-colors\",\n selected\n ? \"bg-plan-block text-plan-text shadow-sm\"\n : \"text-plan-muted hover:bg-plan-block/60 hover:text-plan-text\",\n )}\n >\n {tab.label}\n </button>\n );\n })}\n </div>\n );\n}\n\n/** Read renderer: pill tabs, child blocks rendered read-only via the app. */\nexport function TabsBlockReader({\n data,\n blockId,\n title,\n ctx,\n}: BlockReadProps<TabsData>) {\n const [activeId, setActiveId] = useState(data.tabs[0]?.id ?? \"\");\n const active = data.tabs.find((tab) => tab.id === activeId) ?? data.tabs[0];\n const compact = isCompact(title);\n return (\n <section className=\"plan-block\" data-block-id={blockId}>\n {title && <div className=\"plan-block-label\">{title}</div>}\n <TabRail tabs={data.tabs} activeId={active?.id} onSelect={setActiveId} />\n {active && (\n <div>\n {active.blocks.map((child) => (\n <div key={child.id}>\n {ctx.renderBlock?.({\n block: child,\n editing: false,\n compactVisuals: compact,\n })}\n </div>\n ))}\n </div>\n )}\n </section>\n );\n}\n\n/**\n * Editor: pill tabs plus tab management (add/remove/rename), with child blocks\n * rendered editable in place through the app dispatcher. A child change updates\n * that child within its tab and commits the whole tabs block — mirroring the\n * legacy `TabsBlock` onChange bubbling so the plan's recursive `updateBlocks`/\n * `findBlock` (`PlanContentRenderer`) keeps working unchanged.\n */\nexport function TabsBlockEditor({\n data,\n onChange,\n editable,\n blockId,\n title,\n ctx,\n}: BlockEditProps<TabsData>) {\n const [activeId, setActiveId] = useState(data.tabs[0]?.id ?? \"\");\n const active = data.tabs.find((tab) => tab.id === activeId) ?? data.tabs[0];\n const compact = isCompact(title);\n\n const commit = (tabs: TabsTab[]) => onChange({ tabs });\n\n const renameTab = (id: string, label: string) =>\n commit(data.tabs.map((tab) => (tab.id === id ? { ...tab, label } : tab)));\n\n const removeTab = (id: string) => {\n const next = data.tabs.filter((tab) => tab.id !== id);\n if (next.length === 0) return; // tabs must keep at least one (schema min 1)\n commit(next);\n if (activeId === id) setActiveId(next[0]?.id ?? \"\");\n };\n\n const addTab = () => {\n if (data.tabs.length >= 12) return; // schema max\n const id = newTabId();\n commit([\n ...data.tabs,\n { id, label: `Tab ${data.tabs.length + 1}`, blocks: [] },\n ]);\n setActiveId(id);\n };\n\n const updateChild = (tabId: string, child: NestedBlock) =>\n commit(\n data.tabs.map((tab) =>\n tab.id === tabId\n ? {\n ...tab,\n blocks: tab.blocks.map((existing) =>\n existing.id === child.id ? child : existing,\n ),\n }\n : tab,\n ),\n );\n\n // Renders BARE (no `plan-block` section / title): in edit mode the app's\n // block dispatcher already wraps registered editors in a titled `plan-block`\n // section, so wrapping again here would double-nest. The read renderer\n // (`TabsBlockReader`) owns its own section because read mode renders the spec\n // directly.\n return (\n <div data-tabs-edit-block={blockId}>\n <div\n className=\"mb-8 flex max-w-full flex-wrap items-center gap-1 overflow-x-auto\"\n role=\"tablist\"\n data-plan-interactive\n >\n {data.tabs.map((tab) => {\n const selected = tab.id === active?.id;\n return (\n <div\n key={tab.id}\n className={cn(\n \"group flex items-center gap-1 rounded-lg pr-1 transition-colors\",\n selected ? \"bg-plan-block shadow-sm\" : \"hover:bg-plan-block/60\",\n )}\n >\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={selected}\n onClick={() => setActiveId(tab.id)}\n className={cn(\n \"rounded-lg px-4 py-2 text-sm font-semibold transition-colors\",\n selected ? \"text-plan-text\" : \"text-plan-muted\",\n )}\n >\n {tab.label}\n </button>\n {editable && data.tabs.length > 1 && (\n <button\n type=\"button\"\n data-plan-interactive\n aria-label={`Remove ${tab.label}`}\n className={cn(\n \"flex size-6 shrink-0 items-center justify-center rounded text-plan-muted transition-opacity\",\n \"opacity-0 group-hover:opacity-100 group-focus-within:opacity-100\",\n \"hover:bg-muted hover:text-foreground\",\n )}\n onClick={() => removeTab(tab.id)}\n >\n <IconX className=\"size-3.5 shrink-0\" />\n </button>\n )}\n </div>\n );\n })}\n {editable && data.tabs.length < 12 && (\n <button\n type=\"button\"\n data-plan-interactive\n aria-label=\"Add tab\"\n className=\"flex items-center gap-1.5 rounded-md px-2 py-2 text-sm text-plan-muted hover:bg-plan-block/60 hover:text-plan-text\"\n onClick={addTab}\n >\n <IconPlus className=\"size-4\" />\n Add tab\n </button>\n )}\n </div>\n {active && (\n <div className=\"grid gap-3\">\n {editable && (\n <input\n type=\"text\"\n data-plan-interactive\n className=\"flex h-9 w-full max-w-xs 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\"\n placeholder=\"Tab label\"\n value={active.label}\n onChange={(event) => renameTab(active.id, event.target.value)}\n />\n )}\n <div>\n {active.blocks.map((child) => (\n <div key={child.id}>\n {ctx.renderBlock?.({\n block: child,\n editing: true,\n compactVisuals: compact,\n onChange: (next) => updateChild(active.id, next),\n })}\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n );\n}\n\n/**\n * The standard tabs block spec (with React `Read`/`Edit`). Apps register this in\n * their browser registry. The schema + MDX config come from `./tabs.config.ts`,\n * the exact same object server / agent code registers, so rendering and source\n * round-trip never drift.\n */\nexport const tabsBlock = defineBlock<TabsData>({\n type: \"tabs\",\n schema: tabsSchema,\n mdx: tabsMdx,\n Read: TabsBlockReader,\n Edit: TabsBlockEditor,\n placement: [\"block\", \"inline\"],\n label: \"Tabs\",\n icon: IconLayoutNavbar,\n description:\n \"A horizontal pill-tab container; each tab holds its own list of blocks.\",\n empty: () => ({ tabs: [{ id: newTabId(), label: \"Tab 1\", blocks: [] }] }),\n});\n"]}
@@ -16,6 +16,14 @@ export declare class BlockRegistry {
16
16
  hasTag(tag: string): boolean;
17
17
  /** All registered MDX tags — replaces the hardcoded `BLOCK_COMPONENTS` set. */
18
18
  tags(): Set<string>;
19
+ /**
20
+ * The set of registered block `type`s whose specs declare
21
+ * `notionCompatible: true` — i.e. they round-trip to Notion-Flavored Markdown
22
+ * and may sync to Notion. Apps use this as the registry-backed part of their
23
+ * Notion gating allowlist; prose-only NFM analogs that are not registry atoms
24
+ * (rich-text, callout) are NOT in here — apps union those in separately.
25
+ */
26
+ notionCompatibleTypes(): Set<string>;
19
27
  /** All registered specs, optionally filtered by placement. */
20
28
  list(placement?: BlockPlacement): BlockSpec<any>[];
21
29
  }
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/client/blocks/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5D;;;;;;GAMG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,KAAK,CAAqC;IAElD,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI;IAWpC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,SAAS;IAI7C,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,SAAS;IAIjD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAI5B,+EAA+E;IAC/E,IAAI,IAAI,GAAG,CAAC,MAAM,CAAC;IAInB,8DAA8D;IAC9D,IAAI,CAAC,SAAS,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC,GAAG,CAAC,EAAE;CAMnD;AAED,0CAA0C;AAC1C,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,aAAa,EACvB,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,GACtB,IAAI,CAEN"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/client/blocks/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5D;;;;;;GAMG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,KAAK,CAAqC;IAElD,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI;IAWpC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,SAAS;IAI7C,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,SAAS;IAIjD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAI5B,+EAA+E;IAC/E,IAAI,IAAI,GAAG,CAAC,MAAM,CAAC;IAInB;;;;;;OAMG;IACH,qBAAqB,IAAI,GAAG,CAAC,MAAM,CAAC;IAQpC,8DAA8D;IAC9D,IAAI,CAAC,SAAS,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC,GAAG,CAAC,EAAE;CAMnD;AAED,0CAA0C;AAC1C,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,aAAa,EACvB,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,GACtB,IAAI,CAEN"}
@@ -34,6 +34,21 @@ export class BlockRegistry {
34
34
  tags() {
35
35
  return new Set(this.byTag.keys());
36
36
  }
37
+ /**
38
+ * The set of registered block `type`s whose specs declare
39
+ * `notionCompatible: true` — i.e. they round-trip to Notion-Flavored Markdown
40
+ * and may sync to Notion. Apps use this as the registry-backed part of their
41
+ * Notion gating allowlist; prose-only NFM analogs that are not registry atoms
42
+ * (rich-text, callout) are NOT in here — apps union those in separately.
43
+ */
44
+ notionCompatibleTypes() {
45
+ const types = new Set();
46
+ for (const spec of this.byType.values()) {
47
+ if (spec.notionCompatible)
48
+ types.add(spec.type);
49
+ }
50
+ return types;
51
+ }
37
52
  /** All registered specs, optionally filtered by placement. */
38
53
  list(placement) {
39
54
  const all = [...this.byType.values()];
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/client/blocks/registry.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,OAAO,aAAa;IAChB,MAAM,GAAG,IAAI,GAAG,EAA0B,CAAC;IAC3C,KAAK,GAAG,IAAI,GAAG,EAA0B,CAAC;IAElD,QAAQ,CAAC,IAAoB;QAC3B,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,CAAC,IAAI,0BAA0B,CAAC,CAAC;QACtE,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,kBAAkB,IAAI,CAAC,GAAG,CAAC,GAAG,0BAA0B,CAAC,CAAC;QAC5E,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,QAAQ,CAAC,GAAW;QAClB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,+EAA+E;IAC/E,IAAI;QACF,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,8DAA8D;IAC9D,IAAI,CAAC,SAA0B;QAC7B,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACtC,OAAO,SAAS;YACd,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YAC1D,CAAC,CAAC,GAAG,CAAC;IACV,CAAC;CACF;AAED,0CAA0C;AAC1C,MAAM,UAAU,cAAc,CAC5B,QAAuB,EACvB,KAAuB;IAEvB,KAAK,MAAM,IAAI,IAAI,KAAK;QAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACpD,CAAC","sourcesContent":["import type { BlockSpec, BlockPlacement } from \"./types.js\";\n\n/**\n * In-memory block registry. Holds two lookups: by runtime `type` (render +\n * serialize side) and by MDX `tag` (parse side). The registry is a plain object\n * usable both inside React (via the context provider) and outside it (the\n * server MDX serializer/parser, agent schema export) — mirroring how the legacy\n * `BLOCK_COMPONENTS` set and `serializeBlock`/`parseBlock` are plain functions.\n */\nexport class BlockRegistry {\n private byType = new Map<string, BlockSpec<any>>();\n private byTag = new Map<string, BlockSpec<any>>();\n\n register(spec: BlockSpec<any>): void {\n if (this.byType.has(spec.type)) {\n throw new Error(`Block type \"${spec.type}\" is already registered.`);\n }\n if (this.byTag.has(spec.mdx.tag)) {\n throw new Error(`Block MDX tag \"${spec.mdx.tag}\" is already registered.`);\n }\n this.byType.set(spec.type, spec);\n this.byTag.set(spec.mdx.tag, spec);\n }\n\n get(type: string): BlockSpec<any> | undefined {\n return this.byType.get(type);\n }\n\n getByTag(tag: string): BlockSpec<any> | undefined {\n return this.byTag.get(tag);\n }\n\n has(type: string): boolean {\n return this.byType.has(type);\n }\n\n hasTag(tag: string): boolean {\n return this.byTag.has(tag);\n }\n\n /** All registered MDX tags — replaces the hardcoded `BLOCK_COMPONENTS` set. */\n tags(): Set<string> {\n return new Set(this.byTag.keys());\n }\n\n /** All registered specs, optionally filtered by placement. */\n list(placement?: BlockPlacement): BlockSpec<any>[] {\n const all = [...this.byType.values()];\n return placement\n ? all.filter((spec) => spec.placement.includes(placement))\n : all;\n }\n}\n\n/** Register a batch of specs in order. */\nexport function registerBlocks(\n registry: BlockRegistry,\n specs: BlockSpec<any>[],\n): void {\n for (const spec of specs) registry.register(spec);\n}\n"]}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/client/blocks/registry.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,OAAO,aAAa;IAChB,MAAM,GAAG,IAAI,GAAG,EAA0B,CAAC;IAC3C,KAAK,GAAG,IAAI,GAAG,EAA0B,CAAC;IAElD,QAAQ,CAAC,IAAoB;QAC3B,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,CAAC,IAAI,0BAA0B,CAAC,CAAC;QACtE,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,kBAAkB,IAAI,CAAC,GAAG,CAAC,GAAG,0BAA0B,CAAC,CAAC;QAC5E,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,QAAQ,CAAC,GAAW;QAClB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,+EAA+E;IAC/E,IAAI;QACF,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACpC,CAAC;IAED;;;;;;OAMG;IACH,qBAAqB;QACnB,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;QAChC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACxC,IAAI,IAAI,CAAC,gBAAgB;gBAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClD,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,8DAA8D;IAC9D,IAAI,CAAC,SAA0B;QAC7B,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACtC,OAAO,SAAS;YACd,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YAC1D,CAAC,CAAC,GAAG,CAAC;IACV,CAAC;CACF;AAED,0CAA0C;AAC1C,MAAM,UAAU,cAAc,CAC5B,QAAuB,EACvB,KAAuB;IAEvB,KAAK,MAAM,IAAI,IAAI,KAAK;QAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACpD,CAAC","sourcesContent":["import type { BlockSpec, BlockPlacement } from \"./types.js\";\n\n/**\n * In-memory block registry. Holds two lookups: by runtime `type` (render +\n * serialize side) and by MDX `tag` (parse side). The registry is a plain object\n * usable both inside React (via the context provider) and outside it (the\n * server MDX serializer/parser, agent schema export) — mirroring how the legacy\n * `BLOCK_COMPONENTS` set and `serializeBlock`/`parseBlock` are plain functions.\n */\nexport class BlockRegistry {\n private byType = new Map<string, BlockSpec<any>>();\n private byTag = new Map<string, BlockSpec<any>>();\n\n register(spec: BlockSpec<any>): void {\n if (this.byType.has(spec.type)) {\n throw new Error(`Block type \"${spec.type}\" is already registered.`);\n }\n if (this.byTag.has(spec.mdx.tag)) {\n throw new Error(`Block MDX tag \"${spec.mdx.tag}\" is already registered.`);\n }\n this.byType.set(spec.type, spec);\n this.byTag.set(spec.mdx.tag, spec);\n }\n\n get(type: string): BlockSpec<any> | undefined {\n return this.byType.get(type);\n }\n\n getByTag(tag: string): BlockSpec<any> | undefined {\n return this.byTag.get(tag);\n }\n\n has(type: string): boolean {\n return this.byType.has(type);\n }\n\n hasTag(tag: string): boolean {\n return this.byTag.has(tag);\n }\n\n /** All registered MDX tags — replaces the hardcoded `BLOCK_COMPONENTS` set. */\n tags(): Set<string> {\n return new Set(this.byTag.keys());\n }\n\n /**\n * The set of registered block `type`s whose specs declare\n * `notionCompatible: true` — i.e. they round-trip to Notion-Flavored Markdown\n * and may sync to Notion. Apps use this as the registry-backed part of their\n * Notion gating allowlist; prose-only NFM analogs that are not registry atoms\n * (rich-text, callout) are NOT in here — apps union those in separately.\n */\n notionCompatibleTypes(): Set<string> {\n const types = new Set<string>();\n for (const spec of this.byType.values()) {\n if (spec.notionCompatible) types.add(spec.type);\n }\n return types;\n }\n\n /** All registered specs, optionally filtered by placement. */\n list(placement?: BlockPlacement): BlockSpec<any>[] {\n const all = [...this.byType.values()];\n return placement\n ? all.filter((spec) => spec.placement.includes(placement))\n : all;\n }\n}\n\n/** Register a batch of specs in order. */\nexport function registerBlocks(\n registry: BlockRegistry,\n specs: BlockSpec<any>[],\n): void {\n for (const spec of specs) registry.register(spec);\n}\n"]}
@@ -14,9 +14,18 @@ export { BlockRegistry, registerBlocks } from "./registry.js";
14
14
  export { markdown, richtext, introspect, type FieldKind, type FieldDescriptor, } from "./schema-form/introspect.js";
15
15
  export { prop, escapeAttr, jsonExpression, attributeValue, createAttrReader, serializeSpecBlock, parseSpecBlock, type MdxJsxNode, type MdxAttrNode, type SerializableBlock, type ParsedBlockBase, } from "./mdx.js";
16
16
  export { describeBlocksForAgent, renderBlockVocabularyReference, type BlockAgentDoc, } from "./agent.js";
17
+ export { libraryBlockConfigs, registerLibraryBlockConfigs, type LibraryBlockConfigOverrides, } from "./library/server-specs.js";
17
18
  export { checklistSchema, checklistMdx, type ChecklistData, type ChecklistItem, } from "./library/checklist.config.js";
18
19
  export { tableSchema, tableMdx, type TableData, } from "./library/table.config.js";
19
20
  export { codeTabsSchema, codeTabsMdx, type CodeTabsData, type CodeTabsTab, } from "./library/code-tabs.config.js";
20
21
  export { htmlSchema, htmlMdx, type HtmlBlockData, } from "./library/html.config.js";
21
22
  export { tabsSchema, tabsMdx, type TabsData, type TabsTab, } from "./library/tabs.config.js";
23
+ export { mermaidSchema, mermaidMdx, type MermaidData, } from "./library/mermaid.config.js";
24
+ 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";
25
+ export { dataModelSchema, dataModelMdx, DATA_MODEL_RELATION_KINDS, type DataModelData, type DataModelEntity, type DataModelField, type DataModelRelation, type DataModelRelationKind, } from "./library/data-model.config.js";
26
+ export { diffSchema, diffMdx, type DiffData, type DiffMode, } from "./library/diff.config.js";
27
+ export { fileTreeSchema, fileTreeMdx, FILE_TREE_CHANGES, type FileTreeData, type FileTreeEntry, type FileTreeChange, } from "./library/file-tree.config.js";
28
+ export { jsonExplorerSchema, jsonExplorerMdx, type JsonExplorerData, } from "./library/json-explorer.config.js";
29
+ export { annotatedCodeSchema, annotatedCodeMdx, type AnnotatedCodeData, type AnnotatedCodeAnnotation, } from "./library/annotated-code.config.js";
30
+ export { openApiSpecSchema, openApiSpecMdx, type OpenApiSpecData, } from "./library/openapi-spec.config.js";
22
31
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/client/blocks/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,WAAW,EACX,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE9D,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,KAAK,SAAS,EACd,KAAK,eAAe,GACrB,MAAM,6BAA6B,CAAC;AAErC,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;AAElB,OAAO,EACL,sBAAsB,EACtB,8BAA8B,EAC9B,KAAK,aAAa,GACnB,MAAM,YAAY,CAAC;AAKpB,OAAO,EACL,eAAe,EACf,YAAY,EACZ,KAAK,aAAa,EAClB,KAAK,aAAa,GACnB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,WAAW,EACX,QAAQ,EACR,KAAK,SAAS,GACf,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,cAAc,EACd,WAAW,EACX,KAAK,YAAY,EACjB,KAAK,WAAW,GACjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,UAAU,EACV,OAAO,EACP,KAAK,aAAa,GACnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,UAAU,EACV,OAAO,EACP,KAAK,QAAQ,EACb,KAAK,OAAO,GACb,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/client/blocks/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,WAAW,EACX,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE9D,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,KAAK,SAAS,EACd,KAAK,eAAe,GACrB,MAAM,6BAA6B,CAAC;AAErC,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;AAElB,OAAO,EACL,sBAAsB,EACtB,8BAA8B,EAC9B,KAAK,aAAa,GACnB,MAAM,YAAY,CAAC;AAMpB,OAAO,EACL,mBAAmB,EACnB,2BAA2B,EAC3B,KAAK,2BAA2B,GACjC,MAAM,2BAA2B,CAAC;AAKnC,OAAO,EACL,eAAe,EACf,YAAY,EACZ,KAAK,aAAa,EAClB,KAAK,aAAa,GACnB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,WAAW,EACX,QAAQ,EACR,KAAK,SAAS,GACf,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,cAAc,EACd,WAAW,EACX,KAAK,YAAY,EACjB,KAAK,WAAW,GACjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,UAAU,EACV,OAAO,EACP,KAAK,aAAa,GACnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,UAAU,EACV,OAAO,EACP,KAAK,QAAQ,EACb,KAAK,OAAO,GACb,MAAM,0BAA0B,CAAC;AAKlC,OAAO,EACL,aAAa,EACb,UAAU,EACV,KAAK,WAAW,GACjB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,GACtB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,eAAe,EACf,YAAY,EACZ,yBAAyB,EACzB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,GAC3B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,UAAU,EACV,OAAO,EACP,KAAK,QAAQ,EACb,KAAK,QAAQ,GACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,cAAc,GACpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,KAAK,gBAAgB,GACtB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,GAC7B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,KAAK,eAAe,GACrB,MAAM,kCAAkC,CAAC"}
@@ -14,6 +14,11 @@ export { BlockRegistry, registerBlocks } from "./registry.js";
14
14
  export { markdown, richtext, introspect, } from "./schema-form/introspect.js";
15
15
  export { prop, escapeAttr, jsonExpression, attributeValue, createAttrReader, serializeSpecBlock, parseSpecBlock, } from "./mdx.js";
16
16
  export { describeBlocksForAgent, renderBlockVocabularyReference, } from "./agent.js";
17
+ // Standard library registration (React-free). Server / shared registries call
18
+ // `registerLibraryBlockConfigs(registry)` to register the whole standard library
19
+ // as `Read: () => null` config stubs in one place, then add their app-specific
20
+ // block configs on top. `libraryBlockConfigs` is the underlying ordered array.
21
+ export { libraryBlockConfigs, registerLibraryBlockConfigs, } from "./library/server-specs.js";
17
22
  // Standard block library — React-free schema + MDX config only. The React
18
23
  // `Read`/`Edit` live in `./library/checklist.tsx` (imported from the full
19
24
  // `@agent-native/core/blocks` entry), never from here.
@@ -22,4 +27,15 @@ export { tableSchema, tableMdx, } from "./library/table.config.js";
22
27
  export { codeTabsSchema, codeTabsMdx, } from "./library/code-tabs.config.js";
23
28
  export { htmlSchema, htmlMdx, } from "./library/html.config.js";
24
29
  export { tabsSchema, tabsMdx, } from "./library/tabs.config.js";
30
+ // Dev-doc block library — React-free schema + MDX config only. The React
31
+ // `Read`/`Edit` live in the matching `./library/<Name>Block.tsx` (imported from
32
+ // the full `@agent-native/core/blocks` entry), never from here.
33
+ export { mermaidSchema, mermaidMdx, } from "./library/mermaid.config.js";
34
+ export { apiEndpointSchema, apiEndpointMdx, API_ENDPOINT_METHODS, API_PARAM_LOCATIONS, } from "./library/api-endpoint.config.js";
35
+ export { dataModelSchema, dataModelMdx, DATA_MODEL_RELATION_KINDS, } from "./library/data-model.config.js";
36
+ export { diffSchema, diffMdx, } from "./library/diff.config.js";
37
+ export { fileTreeSchema, fileTreeMdx, FILE_TREE_CHANGES, } from "./library/file-tree.config.js";
38
+ export { jsonExplorerSchema, jsonExplorerMdx, } from "./library/json-explorer.config.js";
39
+ export { annotatedCodeSchema, annotatedCodeMdx, } from "./library/annotated-code.config.js";
40
+ export { openApiSpecSchema, openApiSpecMdx, } from "./library/openapi-spec.config.js";
25
41
  //# sourceMappingURL=server.js.map