@north-light/crouter 0.3.197 → 0.3.199

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 (339) hide show
  1. package/dist/api/client.d.ts +19 -19
  2. package/dist/api/client.js +29 -37
  3. package/dist/api/dto/broker-ops.d.ts +3 -1
  4. package/dist/api/dto/broker.d.ts +13 -2
  5. package/dist/api/dto/broker.js +4 -4
  6. package/dist/api/dto/human.d.ts +6 -5
  7. package/dist/api/dto/inbox.d.ts +126 -33
  8. package/dist/api/dto/nodes.d.ts +8 -2
  9. package/dist/api/dto/profiles.d.ts +23 -0
  10. package/dist/api/dto/profiles.js +2 -2
  11. package/dist/api/dto/worktree.d.ts +3 -5
  12. package/dist/api/routes.d.ts +3 -5
  13. package/dist/api/routes.js +4 -6
  14. package/dist/builtin-memory/00-runtime-base.md +8 -8
  15. package/dist/builtin-memory/01-spine/01-no-manager.md +1 -1
  16. package/dist/builtin-memory/02-lifecycle/00-terminal.md +3 -3
  17. package/dist/builtin-memory/04-orchestration-kernel.md +6 -6
  18. package/dist/builtin-memory/05-kinds/design/00-base.md +1 -1
  19. package/dist/builtin-memory/05-kinds/plan/reviewers/security.md +2 -2
  20. package/dist/builtin-memory/05-kinds/review/00-base.md +2 -2
  21. package/dist/builtin-memory/05-kinds/review/01-orchestrator.md +1 -1
  22. package/dist/builtin-memory/05-kinds/spec/01-orchestrator.md +1 -1
  23. package/dist/builtin-memory/insights/capture.md +2 -2
  24. package/dist/builtin-memory/insights/init.md +3 -3
  25. package/dist/builtin-memory/internal/INDEX.md +1 -1
  26. package/dist/builtin-memory/internal/memory-loading.md +1 -1
  27. package/dist/builtin-memory/internal/nodes-and-canvas.md +3 -3
  28. package/dist/builtin-memory/internal/plugins.md +59 -2
  29. package/dist/builtin-memory/internal/storage-tiers.md +3 -1
  30. package/dist/builtin-memory/spec/roadmap.md +2 -2
  31. package/dist/builtin-memory/testing.md +1 -1
  32. package/dist/builtin-memory/wedged-child-on-runaway-bash.md +1 -1
  33. package/dist/clients/attach/chrome/bash-jobs.js +3 -3
  34. package/dist/clients/attach/render/chat-view.d.ts +29 -9
  35. package/dist/clients/attach/render/chat-view.js +64 -35
  36. package/dist/clients/attach/render/markdown-source.js +0 -6
  37. package/dist/clients/attach/render/page-block.d.ts +34 -0
  38. package/dist/clients/attach/render/page-block.js +226 -0
  39. package/dist/clients/attach/render/tool-calls.js +16 -2
  40. package/dist/clients/attach/session/whip.d.ts +2 -0
  41. package/dist/clients/attach/session/whip.js +2 -0
  42. package/dist/clients/attach/viewer.js +1419 -982
  43. package/dist/clients/conversation/projection.js +18 -3
  44. package/dist/clients/inbox/__tests__/serial/inbox-controller.test.js +9 -6
  45. package/dist/clients/inbox/__tests__/serial/mount-panel.test.js +13 -14
  46. package/dist/clients/inbox/controller.js +10 -16
  47. package/dist/clients/inbox/page-adapter.d.ts +3 -4
  48. package/dist/clients/inbox/page-adapter.js +3 -4
  49. package/dist/clients/inbox/resolve.d.ts +1 -1
  50. package/dist/clients/inbox/resolve.js +3 -3
  51. package/dist/clients/inbox/review/document-surface.js +3 -1
  52. package/dist/clients/inbox/review/state.d.ts +2 -1
  53. package/dist/clients/inbox/review/state.js +5 -16
  54. package/dist/clients/inbox/tui/input.js +37 -19
  55. package/dist/clients/inbox/tui/panel.js +5 -31
  56. package/dist/clients/inbox/tui/render.d.ts +11 -0
  57. package/dist/clients/inbox/tui/render.js +101 -36
  58. package/dist/clients/inbox/tui/slots.d.ts +4 -4
  59. package/dist/clients/inbox/tui/slots.js +19 -44
  60. package/dist/clients/inbox/tui/types.d.ts +6 -10
  61. package/dist/clients/inbox/tui.js +2 -2
  62. package/dist/commands/__tests__/human.test.js +118 -24
  63. package/dist/commands/__tests__/node-message.test.js +14 -0
  64. package/dist/commands/attention.js +4 -4
  65. package/dist/commands/canvas-browse.js +1 -1
  66. package/dist/commands/canvas-snapshot.js +1 -1
  67. package/dist/commands/canvas.js +1 -1
  68. package/dist/commands/dashboard.js +1 -1
  69. package/dist/commands/human/{doc.d.ts → components.d.ts} +1 -1
  70. package/dist/commands/human/components.js +77 -0
  71. package/dist/commands/human/feedback.d.ts +2 -0
  72. package/dist/commands/human/feedback.js +108 -0
  73. package/dist/commands/human/prompts.d.ts +17 -8
  74. package/dist/commands/human/prompts.js +217 -226
  75. package/dist/commands/human/queue.js +57 -88
  76. package/dist/commands/human/shared.d.ts +4 -15
  77. package/dist/commands/human/shared.js +19 -61
  78. package/dist/commands/human.js +32 -19
  79. package/dist/commands/memory/origin.js +2 -2
  80. package/dist/commands/node/bash.js +4 -4
  81. package/dist/commands/node/inspect.js +3 -3
  82. package/dist/commands/node/lifecycle.js +1 -1
  83. package/dist/commands/node/message.js +2 -2
  84. package/dist/commands/node-worktree.js +8 -8
  85. package/dist/commands/pkg/browse.js +1 -1
  86. package/dist/commands/pkg/plugin-manage.js +129 -10
  87. package/dist/commands/profile/delete.js +41 -15
  88. package/dist/commands/profile.js +1 -1
  89. package/dist/commands/push.js +1 -1
  90. package/dist/commands/surface/node/focus.js +29 -14
  91. package/dist/commands/surface-edit.js +3 -3
  92. package/dist/commands/surface-inbox.d.ts +2 -0
  93. package/dist/commands/{human/inbox.js → surface-inbox.js} +14 -18
  94. package/dist/commands/surface.js +2 -1
  95. package/dist/commands/sys/doctor.js +60 -3
  96. package/dist/commands/sys/feedback.js +79 -25
  97. package/dist/commands/sys/settings.js +1 -1
  98. package/dist/core/__tests__/cron-broker-capacity.test.js +1 -1
  99. package/dist/core/__tests__/daemon-boot.test.js +7 -4
  100. package/dist/core/__tests__/dead-node-policy-table.test.js +20 -36
  101. package/dist/core/__tests__/extension-abort.test.js +5 -2
  102. package/dist/core/__tests__/fixtures/fake-engine.d.ts +13 -2
  103. package/dist/core/__tests__/fixtures/fake-engine.js +47 -3
  104. package/dist/core/__tests__/human-cancel-guard.test.js +31 -10
  105. package/dist/core/__tests__/human-deliver.test.js +41 -45
  106. package/dist/core/__tests__/human-node-not-supervised.test.js +1 -1
  107. package/dist/core/__tests__/plugin-page-components.test.js +157 -0
  108. package/dist/core/__tests__/seam/broker-crash-teardown.test.js +13 -11
  109. package/dist/core/__tests__/seam/dormancy-release.test.js +103 -4
  110. package/dist/core/__tests__/serial/flagship-lifecycle.test.js +2 -2
  111. package/dist/core/__tests__/serial/human-deliver-e2e.test.js +12 -16
  112. package/dist/core/__tests__/serial/live-mutation.test.js +1 -1
  113. package/dist/core/__tests__/serial/tmux-surface.test.js +4 -2
  114. package/dist/core/__tests__/serial/worktree.test.js +24 -198
  115. package/dist/core/__tests__/session-cycles.test.js +22 -0
  116. package/dist/core/__tests__/stop-guard.test.js +4 -4
  117. package/dist/core/__tests__/watchdog-abort-arms-retry.test.js +19 -4
  118. package/dist/core/bash-jobs.d.ts +6 -0
  119. package/dist/core/bash-jobs.js +10 -0
  120. package/dist/core/canvas/__tests__/attention.test.js +8 -5
  121. package/dist/core/canvas/__tests__/render-remote.test.js +5 -5
  122. package/dist/core/canvas/attention.js +8 -6
  123. package/dist/core/canvas/browse/app.d.ts +1 -1
  124. package/dist/core/canvas/browse/app.js +21 -3
  125. package/dist/core/canvas/browse/model.d.ts +8 -2
  126. package/dist/core/canvas/browse/model.js +11 -4
  127. package/dist/core/canvas/browse/render.d.ts +4 -0
  128. package/dist/core/canvas/browse/render.js +5 -1
  129. package/dist/core/canvas/canvas.d.ts +33 -0
  130. package/dist/core/canvas/canvas.js +92 -0
  131. package/dist/core/canvas/crons.d.ts +9 -0
  132. package/dist/core/canvas/crons.js +51 -0
  133. package/dist/core/canvas/node-order.d.ts +22 -1
  134. package/dist/core/canvas/node-order.js +26 -1
  135. package/dist/core/canvas/render-source.d.ts +5 -0
  136. package/dist/core/canvas/render-source.js +1 -0
  137. package/dist/core/canvas/types.d.ts +9 -3
  138. package/dist/core/command-plugins/bundle.d.ts +6 -1
  139. package/dist/core/command-plugins/bundle.js +26 -13
  140. package/dist/core/command.js +8 -12
  141. package/dist/core/config.d.ts +47 -1
  142. package/dist/core/config.js +138 -4
  143. package/dist/core/help.d.ts +3 -0
  144. package/dist/core/help.js +1 -1
  145. package/dist/core/human/__tests__/page-catalog.test.d.ts +1 -0
  146. package/dist/core/human/__tests__/page-catalog.test.js +20 -0
  147. package/dist/core/human/__tests__/page-tickets.test.js +68 -34
  148. package/dist/core/human/__tests__/page.test.js +60 -119
  149. package/dist/core/human/__tests__/serial/inbox-core.test.js +6 -16
  150. package/dist/core/human/answer-text.d.ts +3 -0
  151. package/dist/core/human/answer-text.js +98 -0
  152. package/dist/core/human/answer.d.ts +53 -0
  153. package/dist/core/human/answer.js +119 -0
  154. package/dist/core/human/component-docs.d.ts +18 -0
  155. package/dist/core/human/component-docs.js +434 -0
  156. package/dist/core/human/convention.d.ts +17 -3
  157. package/dist/core/human/convention.js +36 -5
  158. package/dist/core/human/feedback-companion.d.ts +20 -0
  159. package/dist/core/human/feedback-companion.js +98 -0
  160. package/dist/core/human/feedback.d.ts +65 -0
  161. package/dist/core/human/feedback.js +116 -0
  162. package/dist/core/human/page-catalog.d.ts +56 -5
  163. package/dist/core/human/page-catalog.js +151 -22
  164. package/dist/core/human/page-errors.d.ts +4 -0
  165. package/dist/core/human/page-errors.js +7 -0
  166. package/dist/core/human/page-eval.d.ts +20 -0
  167. package/dist/core/human/page-eval.js +123 -0
  168. package/dist/core/human/page-schema.d.ts +48 -116
  169. package/dist/core/human/page-schema.js +100 -72
  170. package/dist/core/human/page-synth.d.ts +2 -4
  171. package/dist/core/human/page-synth.js +20 -7
  172. package/dist/core/human/page.d.ts +13 -21
  173. package/dist/core/human/page.js +147 -391
  174. package/dist/core/human/review-schema.d.ts +1 -0
  175. package/dist/core/human/review-schema.js +1 -1
  176. package/dist/core/human/root.d.ts +6 -2
  177. package/dist/core/human/root.js +12 -4
  178. package/dist/core/human/scan.d.ts +3 -3
  179. package/dist/core/human/scan.js +21 -21
  180. package/dist/core/human/summary.d.ts +2 -6
  181. package/dist/core/human/summary.js +3 -59
  182. package/dist/core/human/tickets.d.ts +22 -15
  183. package/dist/core/human/tickets.js +90 -28
  184. package/dist/core/human/types.d.ts +14 -2
  185. package/dist/core/keybindings/catalog.d.ts +2 -2
  186. package/dist/core/keybindings/catalog.js +1 -0
  187. package/dist/core/preview-registry.js +8 -10
  188. package/dist/core/profiles/default-binding.d.ts +4 -0
  189. package/dist/core/profiles/default-binding.js +24 -0
  190. package/dist/core/profiles/deletion-reservation.d.ts +8 -0
  191. package/dist/core/profiles/deletion-reservation.js +38 -0
  192. package/dist/core/profiles/manifest.d.ts +3 -0
  193. package/dist/core/profiles/manifest.js +12 -0
  194. package/dist/core/profiles/select.js +2 -2
  195. package/dist/core/review/realize.js +12 -4
  196. package/dist/core/review/store.d.ts +6 -0
  197. package/dist/core/review/store.js +31 -0
  198. package/dist/core/runtime/bearings.d.ts +0 -4
  199. package/dist/core/runtime/bearings.js +4 -62
  200. package/dist/core/runtime/bin-contributions.d.ts +44 -0
  201. package/dist/core/runtime/bin-contributions.js +186 -0
  202. package/dist/core/runtime/boot-root.js +6 -1
  203. package/dist/core/runtime/broker/client-registry.d.ts +4 -0
  204. package/dist/core/runtime/broker/client-registry.js +13 -1
  205. package/dist/core/runtime/broker/extension-abort.d.ts +1 -1
  206. package/dist/core/runtime/broker/extension-abort.js +4 -2
  207. package/dist/core/runtime/broker/fault-retry.js +4 -0
  208. package/dist/core/runtime/broker/frame-dispatch.d.ts +3 -1
  209. package/dist/core/runtime/broker/frame-dispatch.js +5 -6
  210. package/dist/core/runtime/broker/read-ops.d.ts +1 -1
  211. package/dist/core/runtime/broker/read-ops.js +2 -2
  212. package/dist/core/runtime/broker/rebind.d.ts +1 -0
  213. package/dist/core/runtime/broker/rebind.js +6 -1
  214. package/dist/core/runtime/broker-extension-render.js +19 -0
  215. package/dist/core/runtime/broker-protocol.d.ts +14 -0
  216. package/dist/core/runtime/broker.d.ts +1 -1
  217. package/dist/core/runtime/broker.js +25 -12
  218. package/dist/core/runtime/busy.d.ts +4 -3
  219. package/dist/core/runtime/busy.js +4 -3
  220. package/dist/core/runtime/front-door-env.d.ts +5 -0
  221. package/dist/core/runtime/front-door-env.js +16 -0
  222. package/dist/core/runtime/front-door.d.ts +1 -5
  223. package/dist/core/runtime/front-door.js +2 -5
  224. package/dist/core/runtime/host.d.ts +1 -1
  225. package/dist/core/runtime/invocation.d.ts +6 -0
  226. package/dist/core/runtime/invocation.js +10 -0
  227. package/dist/core/runtime/kickoff.js +34 -0
  228. package/dist/core/runtime/launch.d.ts +2 -6
  229. package/dist/core/runtime/node-read.js +4 -1
  230. package/dist/core/runtime/nodes.js +2 -0
  231. package/dist/core/runtime/promote.d.ts +1 -0
  232. package/dist/core/runtime/promote.js +3 -1
  233. package/dist/core/runtime/session-cycles.d.ts +6 -0
  234. package/dist/core/runtime/session-cycles.js +15 -1
  235. package/dist/core/runtime/session-visibility.d.ts +17 -8
  236. package/dist/core/runtime/session-visibility.js +19 -10
  237. package/dist/core/runtime/spawn-env.d.ts +9 -1
  238. package/dist/core/runtime/spawn-env.js +62 -2
  239. package/dist/core/runtime/spawn.js +4 -4
  240. package/dist/core/runtime/stop-guard.d.ts +2 -2
  241. package/dist/core/runtime/stop-guard.js +2 -2
  242. package/dist/core/runtime/stop-signals.d.ts +1 -1
  243. package/dist/core/runtime/stop-signals.js +2 -2
  244. package/dist/core/runtime/tmux-bindings.js +1 -1
  245. package/dist/core/session-model/session-state.d.ts +4 -3
  246. package/dist/core/session-model/session-state.js +14 -1
  247. package/dist/core/user-settings.d.ts +36 -2
  248. package/dist/core/user-settings.js +56 -14
  249. package/dist/core/worktree.d.ts +15 -45
  250. package/dist/core/worktree.js +59 -261
  251. package/dist/daemon/api/__tests__/seam/profile-delete.test.d.ts +1 -0
  252. package/dist/daemon/api/__tests__/seam/profile-delete.test.js +386 -0
  253. package/dist/daemon/api/handlers/bash-jobs.js +1 -1
  254. package/dist/daemon/api/handlers/broker-ops.js +9 -5
  255. package/dist/daemon/api/handlers/feedback-comments.d.ts +2 -0
  256. package/dist/daemon/api/handlers/feedback-comments.js +207 -0
  257. package/dist/daemon/api/handlers/human.js +24 -20
  258. package/dist/daemon/api/handlers/inbox.d.ts +10 -0
  259. package/dist/daemon/api/handlers/inbox.js +48 -109
  260. package/dist/daemon/api/handlers/profiles.js +11 -29
  261. package/dist/daemon/api/map.d.ts +6 -1
  262. package/dist/daemon/api/map.js +23 -0
  263. package/dist/daemon/api/server.js +3 -1
  264. package/dist/daemon/companion-retire.d.ts +2 -0
  265. package/dist/daemon/companion-retire.js +33 -0
  266. package/dist/daemon/cron-run.js +29 -17
  267. package/dist/daemon/crtrd.js +1 -1
  268. package/dist/daemon/fleet.d.ts +22 -10
  269. package/dist/daemon/fleet.js +43 -24
  270. package/dist/daemon/human/finish.d.ts +12 -6
  271. package/dist/daemon/human/finish.js +134 -54
  272. package/dist/daemon/human/sweep.js +9 -3
  273. package/dist/daemon/profile-delete.d.ts +7 -0
  274. package/dist/daemon/profile-delete.js +306 -0
  275. package/dist/daemon/reconcilers/broker-supervision.js +14 -9
  276. package/dist/daemon/reconcilers/dormant-inbox.js +11 -6
  277. package/dist/daemon/reconcilers/live-obligation.d.ts +21 -1
  278. package/dist/daemon/reconcilers/live-obligation.js +30 -2
  279. package/dist/daemon/reconcilers/storage-maintenance.d.ts +5 -0
  280. package/dist/daemon/reconcilers/storage-maintenance.js +28 -1
  281. package/dist/daemon/review/deliver.js +3 -3
  282. package/dist/daemon/review/finish.d.ts +0 -2
  283. package/dist/daemon/review/finish.js +1 -29
  284. package/dist/daemon/review/sweep.js +12 -1
  285. package/dist/pi-extensions/__tests__/canvas-bash-valve.test.js +56 -1
  286. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +4 -4
  287. package/dist/pi-extensions/canvas-bash-valve.d.ts +9 -1
  288. package/dist/pi-extensions/canvas-bash-valve.js +31 -13
  289. package/dist/pi-extensions/canvas-inbox-watcher.js +1 -1
  290. package/dist/pi-extensions/canvas-review-boundary.d.ts +4 -0
  291. package/dist/pi-extensions/canvas-review-boundary.js +18 -9
  292. package/dist/pi-extensions/canvas-stophook.js +4 -4
  293. package/dist/shared/generated-context.js +2 -2
  294. package/dist/types.d.ts +61 -5
  295. package/dist/types.js +8 -2
  296. package/package.json +4 -4
  297. package/runtime.lock.json +5 -33
  298. package/scripts/install-runtime.mjs +19 -24
  299. package/dist/builtin-memory/init.md +0 -38
  300. package/dist/builtin-memory/plan.md +0 -19
  301. package/dist/builtin-memory/spec.md +0 -19
  302. package/dist/clients/attach/render/html-markdown.d.ts +0 -13
  303. package/dist/clients/attach/render/html-markdown.js +0 -206
  304. package/dist/commands/human/doc.js +0 -144
  305. package/dist/commands/human/inbox.d.ts +0 -2
  306. package/dist/core/human/__tests__/page-render.test.js +0 -49
  307. package/dist/core/human/markdown-html.d.ts +0 -8
  308. package/dist/core/human/markdown-html.js +0 -581
  309. package/dist/core/human/page-render.d.ts +0 -3
  310. package/dist/core/human/page-render.js +0 -131
  311. package/dist/pages/bundle.css +0 -1
  312. package/dist/pages/bundle.js +0 -1347
  313. package/dist/pages/comments.d.ts +0 -43
  314. package/dist/pages/comments.js +0 -125
  315. package/dist/pages/elements/cards.d.ts +0 -17
  316. package/dist/pages/elements/cards.js +0 -802
  317. package/dist/pages/elements/chart.js +0 -648
  318. package/dist/pages/elements/options.d.ts +0 -21
  319. package/dist/pages/elements/options.js +0 -629
  320. package/dist/pages/elements/pages.d.ts +0 -24
  321. package/dist/pages/elements/pages.js +0 -355
  322. package/dist/pages/elements/slot.d.ts +0 -21
  323. package/dist/pages/elements/slot.js +0 -105
  324. package/dist/pages/elements/table.d.ts +0 -19
  325. package/dist/pages/elements/table.js +0 -935
  326. package/dist/pages/elements/text.d.ts +0 -25
  327. package/dist/pages/elements/text.js +0 -968
  328. package/dist/pages/entry.d.ts +0 -8
  329. package/dist/pages/entry.js +0 -8
  330. package/dist/pages/host.d.ts +0 -158
  331. package/dist/pages/host.js +0 -182
  332. package/dist/pages/register.d.ts +0 -2
  333. package/dist/pages/register.js +0 -3
  334. package/dist/pages/slot-config.d.ts +0 -36
  335. package/dist/pages/slot-config.js +0 -50
  336. package/dist/pages/types.d.ts +0 -98
  337. package/dist/pages/types.js +0 -23
  338. /package/dist/{core/human/__tests__/page-render.test.d.ts → commands/__tests__/node-message.test.d.ts} +0 -0
  339. /package/dist/{pages/elements/chart.d.ts → core/__tests__/plugin-page-components.test.d.ts} +0 -0
@@ -1,47 +1,23 @@
1
1
  import { z } from 'zod';
2
+ import { BUILTIN_PAGE_KINDS } from './page-catalog.js';
3
+ import type { ProductPageComponents } from '../../types.js';
2
4
  export declare const PAGE_SLOT_ID_PATTERN: RegExp;
3
5
  export declare const commentAnchorSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
4
- kind: z.ZodLiteral<"whole">;
5
- }, z.core.$strict>, z.ZodObject<{
6
6
  kind: z.ZodLiteral<"option">;
7
7
  optionId: z.ZodString;
8
8
  }, z.core.$strict>, z.ZodObject<{
9
9
  kind: z.ZodLiteral<"row">;
10
10
  rowId: z.ZodString;
11
- }, z.core.$strict>, z.ZodObject<{
12
- kind: z.ZodLiteral<"column">;
13
- columnId: z.ZodString;
14
- }, z.core.$strict>, z.ZodObject<{
15
- kind: z.ZodLiteral<"card">;
16
- cardId: z.ZodString;
17
- }, z.core.$strict>, z.ZodObject<{
18
- kind: z.ZodLiteral<"range">;
19
- start: z.ZodNumber;
20
- end: z.ZodNumber;
21
- quote: z.ZodString;
22
11
  }, z.core.$strict>], "kind">;
23
12
  export type CommentAnchor = z.infer<typeof commentAnchorSchema>;
24
13
  export declare const commentSchema: z.ZodObject<{
25
14
  id: z.ZodString;
26
15
  anchor: z.ZodDiscriminatedUnion<[z.ZodObject<{
27
- kind: z.ZodLiteral<"whole">;
28
- }, z.core.$strict>, z.ZodObject<{
29
16
  kind: z.ZodLiteral<"option">;
30
17
  optionId: z.ZodString;
31
18
  }, z.core.$strict>, z.ZodObject<{
32
19
  kind: z.ZodLiteral<"row">;
33
20
  rowId: z.ZodString;
34
- }, z.core.$strict>, z.ZodObject<{
35
- kind: z.ZodLiteral<"column">;
36
- columnId: z.ZodString;
37
- }, z.core.$strict>, z.ZodObject<{
38
- kind: z.ZodLiteral<"card">;
39
- cardId: z.ZodString;
40
- }, z.core.$strict>, z.ZodObject<{
41
- kind: z.ZodLiteral<"range">;
42
- start: z.ZodNumber;
43
- end: z.ZodNumber;
44
- quote: z.ZodString;
45
21
  }, z.core.$strict>], "kind">;
46
22
  text: z.ZodString;
47
23
  }, z.core.$strict>;
@@ -52,6 +28,8 @@ export declare const optionSchema: z.ZodObject<{
52
28
  description: z.ZodOptional<z.ZodString>;
53
29
  }, z.core.$strict>;
54
30
  export declare const optionsConfigSchema: z.ZodObject<{
31
+ label: z.ZodOptional<z.ZodString>;
32
+ body: z.ZodOptional<z.ZodString>;
55
33
  options: z.ZodArray<z.ZodObject<{
56
34
  id: z.ZodString;
57
35
  label: z.ZodString;
@@ -71,24 +49,11 @@ export declare const optionsResponseSchema: z.ZodObject<{
71
49
  comments: z.ZodArray<z.ZodObject<{
72
50
  id: z.ZodString;
73
51
  anchor: z.ZodDiscriminatedUnion<[z.ZodObject<{
74
- kind: z.ZodLiteral<"whole">;
75
- }, z.core.$strict>, z.ZodObject<{
76
52
  kind: z.ZodLiteral<"option">;
77
53
  optionId: z.ZodString;
78
54
  }, z.core.$strict>, z.ZodObject<{
79
55
  kind: z.ZodLiteral<"row">;
80
56
  rowId: z.ZodString;
81
- }, z.core.$strict>, z.ZodObject<{
82
- kind: z.ZodLiteral<"column">;
83
- columnId: z.ZodString;
84
- }, z.core.$strict>, z.ZodObject<{
85
- kind: z.ZodLiteral<"card">;
86
- cardId: z.ZodString;
87
- }, z.core.$strict>, z.ZodObject<{
88
- kind: z.ZodLiteral<"range">;
89
- start: z.ZodNumber;
90
- end: z.ZodNumber;
91
- quote: z.ZodString;
92
57
  }, z.core.$strict>], "kind">;
93
58
  text: z.ZodString;
94
59
  }, z.core.$strict>>;
@@ -96,38 +61,15 @@ export declare const optionsResponseSchema: z.ZodObject<{
96
61
  }, z.core.$strict>;
97
62
  export type OptionsResponse = z.infer<typeof optionsResponseSchema>;
98
63
  export declare const textConfigSchema: z.ZodObject<{
64
+ label: z.ZodOptional<z.ZodString>;
99
65
  initialText: z.ZodString;
100
- editable: z.ZodOptional<z.ZodBoolean>;
101
66
  placeholder: z.ZodOptional<z.ZodString>;
67
+ singleLine: z.ZodOptional<z.ZodBoolean>;
102
68
  }, z.core.$strict>;
103
69
  export type TextConfig = z.infer<typeof textConfigSchema>;
104
70
  export declare const textResponseSchema: z.ZodObject<{
105
71
  text: z.ZodString;
106
72
  edited: z.ZodBoolean;
107
- comments: z.ZodArray<z.ZodObject<{
108
- id: z.ZodString;
109
- anchor: z.ZodDiscriminatedUnion<[z.ZodObject<{
110
- kind: z.ZodLiteral<"whole">;
111
- }, z.core.$strict>, z.ZodObject<{
112
- kind: z.ZodLiteral<"option">;
113
- optionId: z.ZodString;
114
- }, z.core.$strict>, z.ZodObject<{
115
- kind: z.ZodLiteral<"row">;
116
- rowId: z.ZodString;
117
- }, z.core.$strict>, z.ZodObject<{
118
- kind: z.ZodLiteral<"column">;
119
- columnId: z.ZodString;
120
- }, z.core.$strict>, z.ZodObject<{
121
- kind: z.ZodLiteral<"card">;
122
- cardId: z.ZodString;
123
- }, z.core.$strict>, z.ZodObject<{
124
- kind: z.ZodLiteral<"range">;
125
- start: z.ZodNumber;
126
- end: z.ZodNumber;
127
- quote: z.ZodString;
128
- }, z.core.$strict>], "kind">;
129
- text: z.ZodString;
130
- }, z.core.$strict>>;
131
73
  }, z.core.$strict>;
132
74
  export type TextResponse = z.infer<typeof textResponseSchema>;
133
75
  export declare const tableColumnSchema: z.ZodObject<{
@@ -144,7 +86,14 @@ export declare const tableRowSchema: z.ZodObject<{
144
86
  id: z.ZodString;
145
87
  cells: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>;
146
88
  }, z.core.$strict>;
89
+ export declare const tableRowsSchema: z.ZodArray<z.ZodObject<{
90
+ id: z.ZodString;
91
+ cells: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>;
92
+ }, z.core.$strict>>;
93
+ /** Table config: its data is always embedded. */
147
94
  export declare const tableConfigSchema: z.ZodObject<{
95
+ label: z.ZodOptional<z.ZodString>;
96
+ body: z.ZodOptional<z.ZodString>;
148
97
  columns: z.ZodArray<z.ZodObject<{
149
98
  id: z.ZodString;
150
99
  label: z.ZodString;
@@ -158,7 +107,6 @@ export declare const tableConfigSchema: z.ZodObject<{
158
107
  id: z.ZodString;
159
108
  cells: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>;
160
109
  }, z.core.$strict>>>;
161
- source: z.ZodOptional<z.ZodString>;
162
110
  rowSelect: z.ZodDefault<z.ZodEnum<{
163
111
  none: "none";
164
112
  single: "single";
@@ -169,7 +117,6 @@ export declare const tableConfigSchema: z.ZodObject<{
169
117
  single: "single";
170
118
  multi: "multi";
171
119
  }>>;
172
- caption: z.ZodOptional<z.ZodString>;
173
120
  }, z.core.$strict>;
174
121
  export type TableConfig = z.infer<typeof tableConfigSchema>;
175
122
  export declare const tableResponseSchema: z.ZodObject<{
@@ -178,24 +125,11 @@ export declare const tableResponseSchema: z.ZodObject<{
178
125
  comments: z.ZodArray<z.ZodObject<{
179
126
  id: z.ZodString;
180
127
  anchor: z.ZodDiscriminatedUnion<[z.ZodObject<{
181
- kind: z.ZodLiteral<"whole">;
182
- }, z.core.$strict>, z.ZodObject<{
183
128
  kind: z.ZodLiteral<"option">;
184
129
  optionId: z.ZodString;
185
130
  }, z.core.$strict>, z.ZodObject<{
186
131
  kind: z.ZodLiteral<"row">;
187
132
  rowId: z.ZodString;
188
- }, z.core.$strict>, z.ZodObject<{
189
- kind: z.ZodLiteral<"column">;
190
- columnId: z.ZodString;
191
- }, z.core.$strict>, z.ZodObject<{
192
- kind: z.ZodLiteral<"card">;
193
- cardId: z.ZodString;
194
- }, z.core.$strict>, z.ZodObject<{
195
- kind: z.ZodLiteral<"range">;
196
- start: z.ZodNumber;
197
- end: z.ZodNumber;
198
- quote: z.ZodString;
199
133
  }, z.core.$strict>], "kind">;
200
134
  text: z.ZodString;
201
135
  }, z.core.$strict>>;
@@ -208,7 +142,17 @@ export declare const cardSchema: z.ZodObject<{
208
142
  body: z.ZodOptional<z.ZodString>;
209
143
  tag: z.ZodOptional<z.ZodString>;
210
144
  }, z.core.$strict>;
145
+ export declare const cardsSchema: z.ZodArray<z.ZodObject<{
146
+ id: z.ZodString;
147
+ title: z.ZodString;
148
+ subtitle: z.ZodOptional<z.ZodString>;
149
+ body: z.ZodOptional<z.ZodString>;
150
+ tag: z.ZodOptional<z.ZodString>;
151
+ }, z.core.$strict>>;
152
+ /** Cards config: its data is always embedded. */
211
153
  export declare const cardsConfigSchema: z.ZodObject<{
154
+ label: z.ZodOptional<z.ZodString>;
155
+ body: z.ZodOptional<z.ZodString>;
212
156
  cards: z.ZodOptional<z.ZodArray<z.ZodObject<{
213
157
  id: z.ZodString;
214
158
  title: z.ZodString;
@@ -216,7 +160,6 @@ export declare const cardsConfigSchema: z.ZodObject<{
216
160
  body: z.ZodOptional<z.ZodString>;
217
161
  tag: z.ZodOptional<z.ZodString>;
218
162
  }, z.core.$strict>>>;
219
- source: z.ZodOptional<z.ZodString>;
220
163
  mode: z.ZodEnum<{
221
164
  single: "single";
222
165
  multi: "multi";
@@ -226,36 +169,14 @@ export declare const cardsConfigSchema: z.ZodObject<{
226
169
  export type CardsConfig = z.infer<typeof cardsConfigSchema>;
227
170
  export declare const cardsResponseSchema: z.ZodObject<{
228
171
  selectedCardIds: z.ZodArray<z.ZodString>;
229
- comments: z.ZodArray<z.ZodObject<{
230
- id: z.ZodString;
231
- anchor: z.ZodDiscriminatedUnion<[z.ZodObject<{
232
- kind: z.ZodLiteral<"whole">;
233
- }, z.core.$strict>, z.ZodObject<{
234
- kind: z.ZodLiteral<"option">;
235
- optionId: z.ZodString;
236
- }, z.core.$strict>, z.ZodObject<{
237
- kind: z.ZodLiteral<"row">;
238
- rowId: z.ZodString;
239
- }, z.core.$strict>, z.ZodObject<{
240
- kind: z.ZodLiteral<"column">;
241
- columnId: z.ZodString;
242
- }, z.core.$strict>, z.ZodObject<{
243
- kind: z.ZodLiteral<"card">;
244
- cardId: z.ZodString;
245
- }, z.core.$strict>, z.ZodObject<{
246
- kind: z.ZodLiteral<"range">;
247
- start: z.ZodNumber;
248
- end: z.ZodNumber;
249
- quote: z.ZodString;
250
- }, z.core.$strict>], "kind">;
251
- text: z.ZodString;
252
- }, z.core.$strict>>;
253
172
  }, z.core.$strict>;
254
173
  export type CardsResponse = z.infer<typeof cardsResponseSchema>;
255
174
  export declare const chartSeriesSchema: z.ZodObject<{
256
175
  field: z.ZodString;
257
176
  label: z.ZodOptional<z.ZodString>;
258
177
  }, z.core.$strict>;
178
+ export declare const chartDataRowsSchema: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
179
+ /** Chart config: its data is always embedded. */
259
180
  export declare const chartConfigSchema: z.ZodObject<{
260
181
  kind: z.ZodEnum<{
261
182
  line: "line";
@@ -268,8 +189,7 @@ export declare const chartConfigSchema: z.ZodObject<{
268
189
  label: z.ZodOptional<z.ZodString>;
269
190
  }, z.core.$strict>>;
270
191
  title: z.ZodOptional<z.ZodString>;
271
- data: z.ZodOptional<z.ZodUnknown>;
272
- source: z.ZodOptional<z.ZodString>;
192
+ data: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
273
193
  }, z.core.$strict>;
274
194
  export type ChartConfig = z.infer<typeof chartConfigSchema>;
275
195
  export type SlotConfig = OptionsConfig | TextConfig | TableConfig | CardsConfig | ChartConfig | Record<string, unknown>;
@@ -280,33 +200,45 @@ export interface PageSlot {
280
200
  step: number;
281
201
  config: SlotConfig;
282
202
  unvalidated?: true;
203
+ /** Product registration declares this component display-only, so it carries no response. */
204
+ display?: true;
283
205
  }
284
206
  export interface PageSource {
285
207
  sessionName?: string;
286
208
  askedBy?: string;
287
- blockedSince?: string;
209
+ emittedAt?: string;
210
+ profileName?: string;
288
211
  nodeId?: string;
289
212
  }
213
+ export interface PageDelivery {
214
+ placement: 'inline' | 'panel';
215
+ inbox: boolean;
216
+ reply: boolean;
217
+ }
290
218
  export interface PageManifest {
291
- schema: 'crtr.page/v1';
292
- dialect: 'md' | 'html';
219
+ schema: 'crtr.page/v2';
220
+ dialect: 'jsx' | 'html';
293
221
  title: string;
294
222
  subtitle?: string;
295
- placement: 'inline' | 'panel';
296
- document: 'page.md' | 'page.html';
223
+ delivery: PageDelivery;
224
+ document: 'page.tsx' | 'page.html';
297
225
  steps: number;
298
226
  slots: PageSlot[];
299
227
  source?: PageSource;
300
228
  }
229
+ export declare const BUILTIN_PAGE_CONFIG_SCHEMAS: Record<(typeof BUILTIN_PAGE_KINDS)[number], z.ZodType>;
230
+ export declare const BUILTIN_PAGE_RESPONSE_SCHEMAS: Partial<Record<(typeof BUILTIN_PAGE_KINDS)[number], z.ZodType>>;
231
+ export declare function issueText(error: z.ZodError): string;
301
232
  /** The canonical response-bearing predicate used by every page consumer. */
302
233
  export declare function isResponseBearingSlot(slot: PageSlot): boolean;
303
- /** Validate and normalize a derived or stored manifest against the resolved product catalog. */
304
- export declare function validatePageManifest(parsed: unknown, productKinds?: string[]): PageManifest;
305
- export declare function createPageManifestSchema(productKinds?: string[]): z.ZodType<PageManifest>;
306
- /** Built-in-only manifest schema; product-aware callers use createPageManifestSchema. */
234
+ /** Validate a persisted manifest. Publish-time validation made its slots authoritative, so reads do not resolve a component catalog. */
235
+ export declare function validatePageManifest(parsed: unknown): PageManifest;
236
+ /** Validate a manifest derived from an authored page, where the display flag comes from the registration rather than the source. */
237
+ export declare function validateAuthoredPageManifest(parsed: unknown, productComponents?: ProductPageComponents): PageManifest;
238
+ export declare function createPageManifestSchema(): z.ZodType<PageManifest>;
307
239
  export declare const pageManifestSchema: z.ZodType<PageManifest, unknown, z.core.$ZodTypeInternals<PageManifest, unknown>>;
308
240
  export type PageResponses = Record<string, SlotResponse>;
309
241
  /** Validate a complete final response map. */
310
242
  export declare function validatePageResponses(manifest: PageManifest, responses: unknown): PageResponses;
311
- /** Validate an autosaved response map, permitting omitted response-bearing slots. */
243
+ /** Validate an autosaved response map, permitting omitted response-bearing components. */
312
244
  export declare function validatePartialPageResponses(manifest: PageManifest, responses: unknown): PageResponses;
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { BUILTIN_PAGE_KINDS, isRegisteredPageKind } from './page-catalog.js';
2
+ import { BUILTIN_PAGE_KINDS, productPageComponent } from './page-catalog.js';
3
3
  export const PAGE_SLOT_ID_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;
4
4
  const idSchema = z.string().regex(PAGE_SLOT_ID_PATTERN, { error: 'slot id must match /^[A-Za-z0-9_-]{1,64}$/' });
5
5
  const itemIdSchema = z.string().min(1);
@@ -13,20 +13,19 @@ function uniqueIds(items, ctx, label) {
13
13
  seen.add(item.id);
14
14
  });
15
15
  }
16
+ // Response comments qualify the answer itself, so anchors name only answerable structure:
17
+ // one of a question's options, or a table row. Feedback on rendered page content — including
18
+ // the question text itself — is a ticket-level feedback comment (feedback.ts), not part of
19
+ // any response.
16
20
  export const commentAnchorSchema = z.discriminatedUnion('kind', [
17
- z.object({ kind: z.literal('whole') }).strict(),
18
21
  z.object({ kind: z.literal('option'), optionId: itemIdSchema }).strict(),
19
22
  z.object({ kind: z.literal('row'), rowId: itemIdSchema }).strict(),
20
- z.object({ kind: z.literal('column'), columnId: itemIdSchema }).strict(),
21
- z.object({ kind: z.literal('card'), cardId: itemIdSchema }).strict(),
22
- z.object({ kind: z.literal('range'), start: z.number().int().nonnegative(), end: z.number().int().nonnegative(), quote: z.string() }).strict().superRefine((anchor, ctx) => {
23
- if (anchor.end < anchor.start)
24
- ctx.addIssue({ code: 'custom', path: ['end'], message: 'range end must be greater than or equal to start' });
25
- }),
26
23
  ]);
27
24
  export const commentSchema = z.object({ id: z.string().min(1), anchor: commentAnchorSchema, text: z.string() }).strict();
28
25
  export const optionSchema = z.object({ id: itemIdSchema, label: z.string().min(1), description: z.string().optional() }).strict();
29
26
  export const optionsConfigSchema = z.object({
27
+ label: z.string().optional(),
28
+ body: z.string().optional(),
30
29
  options: z.array(optionSchema).min(1).superRefine((items, ctx) => uniqueIds(items, ctx, 'option')),
31
30
  mode: z.enum(['single', 'multi']),
32
31
  allowFreetext: z.boolean().optional(),
@@ -34,68 +33,88 @@ export const optionsConfigSchema = z.object({
34
33
  freetextPlaceholder: z.string().optional(),
35
34
  }).strict();
36
35
  export const optionsResponseSchema = z.object({ selectedOptionIds: z.array(itemIdSchema), comments: z.array(commentSchema), freetext: z.string().optional() }).strict();
37
- export const textConfigSchema = z.object({ initialText: z.string(), editable: z.boolean().optional(), placeholder: z.string().optional() }).strict();
38
- export const textResponseSchema = z.object({ text: z.string(), edited: z.boolean(), comments: z.array(commentSchema) }).strict();
36
+ // Text is a writing surface, always: its whole point is the string the user hands back, so
37
+ // there is no read-only mode. `singleLine` only swaps the multi-line surface for one compact
38
+ // form field — a subject line, a name, a URL.
39
+ export const textConfigSchema = z.object({ label: z.string().optional(), initialText: z.string(), placeholder: z.string().optional(), singleLine: z.boolean().optional() }).strict();
40
+ export const textResponseSchema = z.object({ text: z.string(), edited: z.boolean() }).strict();
39
41
  export const tableColumnSchema = z.object({ id: itemIdSchema, label: z.string().min(1), align: z.enum(['left', 'right']).optional(), mono: z.boolean().optional() }).strict();
40
42
  export const tableCellSchema = z.union([z.string(), z.number(), z.boolean(), z.null()]);
41
43
  export const tableRowSchema = z.object({ id: itemIdSchema, cells: z.record(z.string(), tableCellSchema) }).strict();
42
- export const tableConfigSchema = z.object({
44
+ export const tableRowsSchema = z.array(tableRowSchema).superRefine((items, ctx) => uniqueIds(items, ctx, 'row'));
45
+ const tableConfigFields = {
46
+ label: z.string().optional(),
47
+ body: z.string().optional(),
43
48
  columns: z.array(tableColumnSchema).min(1).superRefine((items, ctx) => uniqueIds(items, ctx, 'column')),
44
- rows: z.array(tableRowSchema).superRefine((items, ctx) => uniqueIds(items, ctx, 'row')).optional(),
45
- source: z.string().optional(),
49
+ rows: tableRowsSchema.optional(),
46
50
  rowSelect: selectModeSchema.default('none'),
47
51
  columnSelect: selectModeSchema.default('none'),
48
- caption: z.string().optional(),
49
- }).strict().superRefine((config, ctx) => {
50
- if (config.rows !== undefined && config.source !== undefined)
51
- ctx.addIssue({ code: 'custom', message: 'table rows and source are mutually exclusive' });
52
- });
52
+ };
53
+ /** Table config: its data is always embedded. */
54
+ export const tableConfigSchema = z.object(tableConfigFields).strict();
53
55
  export const tableResponseSchema = z.object({ selectedRowIds: z.array(itemIdSchema), selectedColumnIds: z.array(itemIdSchema), comments: z.array(commentSchema) }).strict();
54
56
  export const cardSchema = z.object({ id: itemIdSchema, title: z.string().min(1), subtitle: z.string().optional(), body: z.string().optional(), tag: z.string().optional() }).strict();
55
- export const cardsConfigSchema = z.object({
56
- cards: z.array(cardSchema).superRefine((items, ctx) => uniqueIds(items, ctx, 'card')).optional(),
57
- source: z.string().optional(),
57
+ export const cardsSchema = z.array(cardSchema).superRefine((items, ctx) => uniqueIds(items, ctx, 'card'));
58
+ const cardsConfigFields = {
59
+ label: z.string().optional(),
60
+ body: z.string().optional(),
61
+ cards: cardsSchema.optional(),
58
62
  mode: z.enum(['single', 'multi']),
59
63
  columns: z.union([z.literal(2), z.literal(3)]).optional(),
60
- }).strict().superRefine((config, ctx) => {
61
- if (config.cards !== undefined && config.source !== undefined)
62
- ctx.addIssue({ code: 'custom', message: 'cards data and source are mutually exclusive' });
63
- });
64
- export const cardsResponseSchema = z.object({ selectedCardIds: z.array(itemIdSchema), comments: z.array(commentSchema) }).strict();
64
+ };
65
+ /** Cards config: its data is always embedded. */
66
+ export const cardsConfigSchema = z.object(cardsConfigFields).strict();
67
+ export const cardsResponseSchema = z.object({ selectedCardIds: z.array(itemIdSchema) }).strict();
65
68
  export const chartSeriesSchema = z.object({ field: z.string().min(1), label: z.string().optional() }).strict();
66
- export const chartConfigSchema = z.object({
69
+ export const chartDataRowsSchema = z.array(z.record(z.string(), z.unknown()));
70
+ const chartConfigFields = {
67
71
  kind: z.enum(['line', 'bar', 'area']),
68
72
  x: z.string().min(1),
69
73
  y: z.array(chartSeriesSchema).min(1),
70
74
  title: z.string().optional(),
71
- data: z.unknown().optional(),
72
- source: z.string().optional(),
73
- }).strict();
74
- const sourceSchema = z.object({ sessionName: z.string().optional(), askedBy: z.string().optional(), blockedSince: z.string().optional(), nodeId: z.string().optional() }).strict();
75
- const rawSlotSchema = z.object({ id: idSchema.optional(), kind: z.string().min(1), step: z.number().int().nonnegative(), config: jsonObjectSchema, unvalidated: z.literal(true).optional() }).strict();
75
+ data: chartDataRowsSchema.optional(),
76
+ };
77
+ /** Chart config: its data is always embedded. */
78
+ export const chartConfigSchema = z.object(chartConfigFields).strict();
79
+ const sourceSchema = z.object({ sessionName: z.string().optional(), askedBy: z.string().optional(), emittedAt: z.string().datetime({ offset: true }).optional(), profileName: z.string().optional(), nodeId: z.string().optional() }).strict();
80
+ const deliverySchema = z.object({ placement: z.enum(['inline', 'panel']), inbox: z.boolean(), reply: z.boolean() }).strict();
81
+ const rawSlotSchema = z.object({ id: idSchema.optional(), kind: z.string().min(1), step: z.number().int().nonnegative(), config: jsonObjectSchema, unvalidated: z.literal(true).optional(), display: z.literal(true).optional() }).strict();
76
82
  const rawPageManifestSchema = z.object({
77
- schema: z.literal('crtr.page/v1'),
78
- dialect: z.enum(['md', 'html']),
83
+ schema: z.literal('crtr.page/v2'),
84
+ dialect: z.enum(['jsx', 'html']),
79
85
  title: z.string().trim().min(1),
80
86
  subtitle: z.string().optional(),
81
- placement: z.enum(['inline', 'panel']),
82
- document: z.enum(['page.md', 'page.html']),
87
+ delivery: deliverySchema,
88
+ document: z.enum(['page.tsx', 'page.html']),
83
89
  steps: z.number().int().positive(),
84
90
  slots: z.array(rawSlotSchema),
85
91
  source: sourceSchema.optional(),
86
- }).strict();
87
- const configSchemas = {
92
+ }).strict().superRefine((manifest, ctx) => {
93
+ if ((manifest.dialect === 'jsx') !== (manifest.document === 'page.tsx'))
94
+ ctx.addIssue({ code: 'custom', path: ['document'], message: 'document must agree with dialect' });
95
+ if (manifest.dialect === 'html' && (manifest.steps !== 1 || manifest.slots.length !== 0))
96
+ ctx.addIssue({ code: 'custom', path: ['slots'], message: 'HTML pages have exactly one step and no slots' });
97
+ });
98
+ export const BUILTIN_PAGE_CONFIG_SCHEMAS = {
88
99
  options: optionsConfigSchema,
89
100
  text: textConfigSchema,
90
101
  table: tableConfigSchema,
91
102
  cards: cardsConfigSchema,
92
103
  chart: chartConfigSchema,
93
104
  };
94
- function issueText(error) {
105
+ export const BUILTIN_PAGE_RESPONSE_SCHEMAS = {
106
+ options: optionsResponseSchema,
107
+ text: textResponseSchema,
108
+ table: tableResponseSchema,
109
+ cards: cardsResponseSchema,
110
+ };
111
+ export function issueText(error) {
95
112
  return error.issues.map((issue) => `${issue.path.length === 0 ? 'value' : issue.path.join('.')}: ${issue.message}`).join('; ');
96
113
  }
97
114
  /** The canonical response-bearing predicate used by every page consumer. */
98
115
  export function isResponseBearingSlot(slot) {
116
+ if (slot.display === true)
117
+ return false;
99
118
  if (slot.unvalidated === true)
100
119
  return true;
101
120
  if (slot.kind === 'options' || slot.kind === 'text' || slot.kind === 'cards')
@@ -105,13 +124,10 @@ export function isResponseBearingSlot(slot) {
105
124
  const config = slot.config;
106
125
  return (config.rowSelect ?? 'none') !== 'none' || (config.columnSelect ?? 'none') !== 'none';
107
126
  }
108
- /** Validate and normalize a derived or stored manifest against the resolved product catalog. */
109
- export function validatePageManifest(parsed, productKinds = []) {
127
+ function validateManifest(parsed, productComponents, authored) {
110
128
  const manifest = rawPageManifestSchema.parse(parsed);
111
- if (manifest.document !== (manifest.dialect === 'md' ? 'page.md' : 'page.html'))
112
- throw new Error(`page document "${manifest.document}" does not match ${manifest.dialect} dialect`);
113
- if (manifest.dialect === 'md' && manifest.steps !== 1)
114
- throw new Error(`md page steps must be 1; received ${manifest.steps}`);
129
+ if (!authored && manifest.dialect === 'html')
130
+ return manifest;
115
131
  const seen = new Set();
116
132
  const slots = manifest.slots.map((raw, index) => {
117
133
  if (raw.step >= manifest.steps)
@@ -120,20 +136,41 @@ export function validatePageManifest(parsed, productKinds = []) {
120
136
  if (BUILTIN_PAGE_KINDS.includes(raw.kind)) {
121
137
  if (raw.unvalidated === true)
122
138
  throw new Error(`built-in slot kind "${raw.kind}" cannot be unvalidated`);
123
- const result = configSchemas[raw.kind].safeParse(raw.config);
139
+ if (raw.display === true)
140
+ throw new Error(`built-in slot kind "${raw.kind}" cannot set display: true`);
141
+ const result = BUILTIN_PAGE_CONFIG_SCHEMAS[raw.kind].safeParse(raw.config);
124
142
  if (!result.success)
125
143
  throw new Error(`invalid config for slot ${raw.id === undefined ? `#${index}` : `"${raw.id}"`} (${raw.kind}): ${issueText(result.error)}`);
144
+ // Authoring-time only: persisted manifests predate this rule and must keep reading.
145
+ if (authored && raw.kind === 'options') {
146
+ const options = result.data;
147
+ const slotName = raw.id === undefined ? `#${index}` : `"${raw.id}"`;
148
+ if ((options.label ?? '').trim() === '')
149
+ throw new Error(`slot ${slotName} (options): label is required — the question itself, drawn as the bold first line`);
150
+ if ((options.body ?? '').trim() === '')
151
+ throw new Error(`slot ${slotName} (options): body is required — the context under the question a label cannot carry`);
152
+ }
126
153
  slot = { ...(raw.id === undefined ? {} : { id: raw.id }), kind: raw.kind, step: raw.step, config: result.data };
127
154
  }
128
155
  else {
129
- if (!isRegisteredPageKind(raw.kind, productKinds))
156
+ const component = productComponents === undefined ? undefined : productPageComponent(raw.kind, productComponents);
157
+ if (authored && component === undefined)
130
158
  throw new Error(`unregistered page slot kind "${raw.kind}" at slot #${index}`);
131
159
  if (raw.unvalidated !== true)
132
- throw new Error(`registered product slot kind "${raw.kind}" must set unvalidated: true`);
133
- slot = { ...(raw.id === undefined ? {} : { id: raw.id }), kind: raw.kind, step: raw.step, config: raw.config, unvalidated: true };
160
+ throw new Error(`registered page slot kind "${raw.kind}" must set unvalidated: true`);
161
+ if (!authored)
162
+ slot = { ...(raw.id === undefined ? {} : { id: raw.id }), kind: raw.kind, step: raw.step, config: raw.config, unvalidated: true, ...(raw.display === true ? { display: true } : {}) };
163
+ else {
164
+ if (raw.display === true && component?.display !== true)
165
+ throw new Error(`non-display page slot kind "${raw.kind}" cannot set display: true`);
166
+ slot = { ...(raw.id === undefined ? {} : { id: raw.id }), kind: raw.kind, step: raw.step, config: raw.config, unvalidated: true, ...(component?.display === true ? { display: true } : {}) };
167
+ }
168
+ }
169
+ if (isResponseBearingSlot(slot) && slot.id === undefined) {
170
+ throw new Error(slot.unvalidated === true
171
+ ? `product slot kind "${slot.kind}" at slot #${index} requires an id prop`
172
+ : `response-bearing slot kind "${slot.kind}" at slot #${index} requires an id prop`);
134
173
  }
135
- if (isResponseBearingSlot(slot) && slot.id === undefined)
136
- throw new Error(`response-bearing slot kind "${slot.kind}" at slot #${index} requires an id`);
137
174
  if (slot.id !== undefined) {
138
175
  if (seen.has(slot.id))
139
176
  throw new Error(`duplicate slot id "${slot.id}"`);
@@ -143,18 +180,25 @@ export function validatePageManifest(parsed, productKinds = []) {
143
180
  });
144
181
  return { ...manifest, slots };
145
182
  }
146
- export function createPageManifestSchema(productKinds = []) {
183
+ /** Validate a persisted manifest. Publish-time validation made its slots authoritative, so reads do not resolve a component catalog. */
184
+ export function validatePageManifest(parsed) {
185
+ return validateManifest(parsed, undefined, false);
186
+ }
187
+ /** Validate a manifest derived from an authored page, where the display flag comes from the registration rather than the source. */
188
+ export function validateAuthoredPageManifest(parsed, productComponents = []) {
189
+ return validateManifest(parsed, productComponents, true);
190
+ }
191
+ export function createPageManifestSchema() {
147
192
  return z.custom((value) => {
148
193
  try {
149
- validatePageManifest(value, productKinds);
194
+ validatePageManifest(value);
150
195
  return true;
151
196
  }
152
197
  catch {
153
198
  return false;
154
199
  }
155
- }, { error: 'invalid page manifest' }).transform((value) => validatePageManifest(value, productKinds));
200
+ }, { error: 'invalid page manifest' }).transform((value) => validatePageManifest(value));
156
201
  }
157
- /** Built-in-only manifest schema; product-aware callers use createPageManifestSchema. */
158
202
  export const pageManifestSchema = createPageManifestSchema();
159
203
  function assertUnique(values, slotId, field) {
160
204
  if (new Set(values).size !== values.length)
@@ -164,30 +208,16 @@ function validateComments(slot, comments) {
164
208
  const config = slot.config;
165
209
  for (const comment of comments) {
166
210
  const anchor = comment.anchor;
167
- if (anchor.kind === 'whole')
168
- continue;
169
211
  if (slot.kind === 'options' && anchor.kind === 'option') {
170
212
  if (!config.options.some((option) => option.id === anchor.optionId))
171
213
  throw new Error(`slot "${slot.id}" comment names unknown option id "${anchor.optionId}"`);
172
214
  continue;
173
215
  }
174
- if (slot.kind === 'text' && anchor.kind === 'range')
175
- continue;
176
216
  if (slot.kind === 'table' && anchor.kind === 'row') {
177
217
  if (!(config.rows ?? []).some((row) => row.id === anchor.rowId))
178
218
  throw new Error(`slot "${slot.id}" comment names unknown row id "${anchor.rowId}"`);
179
219
  continue;
180
220
  }
181
- if (slot.kind === 'table' && anchor.kind === 'column') {
182
- if (!config.columns.some((column) => column.id === anchor.columnId))
183
- throw new Error(`slot "${slot.id}" comment names unknown column id "${anchor.columnId}"`);
184
- continue;
185
- }
186
- if (slot.kind === 'cards' && anchor.kind === 'card') {
187
- if (!(config.cards ?? []).some((card) => card.id === anchor.cardId))
188
- throw new Error(`slot "${slot.id}" comment names unknown card id "${anchor.cardId}"`);
189
- continue;
190
- }
191
221
  throw new Error(`slot "${slot.id}" does not allow comment anchor kind "${anchor.kind}"`);
192
222
  }
193
223
  }
@@ -224,7 +254,6 @@ function parseResponse(slot, raw) {
224
254
  const result = textResponseSchema.safeParse(raw);
225
255
  if (!result.success)
226
256
  throw new Error(`invalid response for slot "${slot.id}": ${issueText(result.error)}`);
227
- validateComments(slot, result.data.comments);
228
257
  return result.data;
229
258
  }
230
259
  if (slot.kind === 'table') {
@@ -262,7 +291,6 @@ function parseResponse(slot, raw) {
262
291
  throw new Error(`slot "${slot.id}" selects unknown card id "${id}"`);
263
292
  if (config.mode === 'single' && response.selectedCardIds.length > 1)
264
293
  throw new Error(`slot "${slot.id}" is single-select but received ${response.selectedCardIds.length} card ids`);
265
- validateComments(slot, response.comments);
266
294
  return response;
267
295
  }
268
296
  throw new Error(`slot "${slot.id}" kind "${slot.kind}" does not accept a response`);
@@ -287,5 +315,5 @@ function validateResponses(manifest, raw, partial) {
287
315
  }
288
316
  /** Validate a complete final response map. */
289
317
  export function validatePageResponses(manifest, responses) { return validateResponses(manifest, responses, false); }
290
- /** Validate an autosaved response map, permitting omitted response-bearing slots. */
318
+ /** Validate an autosaved response map, permitting omitted response-bearing components. */
291
319
  export function validatePartialPageResponses(manifest, responses) { return validateResponses(manifest, responses, true); }
@@ -1,8 +1,6 @@
1
- /** The single response slot every synthesized question page carries. */
2
- export declare const ASK_RESPONSE_SLOT = "```slot:text\n{ \"id\": \"response\", \"initialText\": \"\", \"editable\": true }\n```";
3
- /** Build a page document from title/subtitle/body — the shape crtr synthesizes when no page file is authored. */
1
+ /** Build a complete TSX page from title, subtitle, and body for internal producers. */
4
2
  export declare function synthesizedPageDocument(title: string, subtitle: string, body: string, responseBearing: boolean): string;
5
- /** Materialize a synthesized document into a private temp dir; the caller removes that dir once submitted. */
3
+ /** Materialize an internally generated document into a private temp dir; the caller removes it after submission. */
6
4
  export declare function writeSynthesizedPage(document: string): {
7
5
  dir: string;
8
6
  path: string;