@seriousgaming/sdk-tools 0.0.0-stage → 1.0.0-alpha.2

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 (391) hide show
  1. package/LICENSE +93 -0
  2. package/README.md +38 -2
  3. package/dist/bundling/logic-exports.d.ts +34 -0
  4. package/dist/bundling/node-builtins.d.ts +21 -0
  5. package/dist/bundling/transpiler.d.ts +7 -0
  6. package/dist/cli.js +27404 -0
  7. package/dist/client/dev-server.d.ts +59 -0
  8. package/dist/client/index.d.ts +28 -0
  9. package/dist/client/stub-services.d.ts +32 -0
  10. package/dist/client/test-session.d.ts +195 -0
  11. package/dist/client.js +16920 -0
  12. package/dist/core/asset-reference-translator.d.ts +46 -0
  13. package/dist/core/clock.d.ts +57 -0
  14. package/dist/core/faults.d.ts +65 -0
  15. package/dist/core/game-settings.d.ts +65 -0
  16. package/dist/core/history.d.ts +89 -0
  17. package/dist/core/listen-with-fallback.d.ts +30 -0
  18. package/dist/core/mutation-queue.d.ts +61 -0
  19. package/dist/core/package-scenario.d.ts +89 -0
  20. package/dist/core/participant-registry.d.ts +109 -0
  21. package/dist/core/pending-changes.d.ts +14 -0
  22. package/dist/core/protocol.d.ts +83 -0
  23. package/dist/core/scenario-drafts.d.ts +32 -0
  24. package/dist/core/session-endpoints.d.ts +108 -0
  25. package/dist/core/session-gates.d.ts +75 -0
  26. package/dist/core/session-host.d.ts +94 -0
  27. package/dist/core/session-refusals.d.ts +56 -0
  28. package/dist/core/session-rewind.d.ts +32 -0
  29. package/dist/core/session-roster.d.ts +128 -0
  30. package/dist/core/session-surfaces.d.ts +32 -0
  31. package/dist/core/session-ticks.d.ts +18 -0
  32. package/dist/core/session-timers.d.ts +84 -0
  33. package/dist/core/session-writes.d.ts +40 -0
  34. package/dist/core/session.d.ts +385 -0
  35. package/dist/core/settings-locks.d.ts +22 -0
  36. package/dist/core/team-names.d.ts +52 -0
  37. package/dist/core/team-state-store.d.ts +218 -0
  38. package/dist/core/tick-timer.d.ts +75 -0
  39. package/dist/dev/blob-links.d.ts +10 -0
  40. package/dist/dev/console/assets/index-DgFglsnA.js +204 -0
  41. package/dist/dev/console/index.html +12 -0
  42. package/dist/dev/console-path.d.ts +19 -0
  43. package/dist/dev/lockfile.d.ts +124 -0
  44. package/dist/dev/package-watcher.d.ts +21 -0
  45. package/dist/dev/routes.d.ts +67 -0
  46. package/dist/dev/shell.d.ts +260 -0
  47. package/dist/dev/surfaces.d.ts +41 -0
  48. package/dist/dev/tools-identity.d.ts +23 -0
  49. package/dist/dev/view/batch.d.ts +172 -0
  50. package/dist/dev/view/commands.d.ts +75 -0
  51. package/dist/dev/view/route.d.ts +58 -0
  52. package/dist/dev/view/view.d.ts +78 -0
  53. package/dist/dev/view/viewer.d.ts +32 -0
  54. package/dist/discovery/config.d.ts +9 -0
  55. package/dist/discovery/manifest-paths.d.ts +21 -0
  56. package/dist/discovery/removed-fields.d.ts +90 -0
  57. package/dist/docs/api/deck.md +386 -0
  58. package/dist/docs/api/index.md +67 -0
  59. package/dist/docs/api/sdk-commands.md +286 -0
  60. package/dist/docs/api/sdk-e2e.md +433 -0
  61. package/dist/docs/api/sdk-projection.md +207 -0
  62. package/dist/docs/api/sdk-testing.md +214 -0
  63. package/dist/docs/api/sdk-tools-client.md +560 -0
  64. package/dist/docs/api/sdk-ui-testing.md +231 -0
  65. package/dist/docs/api/sdk-ui.md +1269 -0
  66. package/dist/docs/api/sdk.md +2140 -0
  67. package/dist/docs/changelog-0.x.md +1156 -0
  68. package/dist/docs/changelog.md +241 -0
  69. package/dist/docs/cli-and-dev-server.md +217 -0
  70. package/dist/docs/cli-error-codes.md +156 -0
  71. package/dist/docs/cli-reference.md +2489 -0
  72. package/dist/docs/cli-simulation-testing.md +222 -0
  73. package/dist/docs/concepts/index.md +46 -0
  74. package/dist/docs/concepts/terminology.md +322 -0
  75. package/dist/docs/environment-variables.md +102 -0
  76. package/dist/docs/getting-started.md +145 -0
  77. package/dist/docs/guides/ai-facilitation.md +220 -0
  78. package/dist/docs/guides/capabilities.md +460 -0
  79. package/dist/docs/guides/endpoints.md +335 -0
  80. package/dist/docs/guides/engine-testing.md +477 -0
  81. package/dist/docs/guides/engine.md +527 -0
  82. package/dist/docs/guides/file-handling.md +405 -0
  83. package/dist/docs/guides/games.md +176 -0
  84. package/dist/docs/guides/global-settings.md +94 -0
  85. package/dist/docs/guides/guide.md +123 -0
  86. package/dist/docs/guides/hooks.md +183 -0
  87. package/dist/docs/guides/index.md +51 -0
  88. package/dist/docs/guides/internationalization.md +288 -0
  89. package/dist/docs/guides/llm-integration.md +635 -0
  90. package/dist/docs/guides/multi-team-games.md +586 -0
  91. package/dist/docs/guides/patterns.md +391 -0
  92. package/dist/docs/guides/presentation.md +196 -0
  93. package/dist/docs/guides/production-constraints.md +130 -0
  94. package/dist/docs/guides/scenario-editor.md +143 -0
  95. package/dist/docs/guides/scenarios.md +515 -0
  96. package/dist/docs/guides/session.md +972 -0
  97. package/dist/docs/guides/settings.md +458 -0
  98. package/dist/docs/guides/setup.md +193 -0
  99. package/dist/docs/guides/speech-generation.md +233 -0
  100. package/dist/docs/guides/starter-game.md +164 -0
  101. package/dist/docs/guides/testing.md +577 -0
  102. package/dist/docs/guides/tick-controller.md +569 -0
  103. package/dist/docs/guides/type-safety.md +516 -0
  104. package/dist/docs/guides/ui.md +1389 -0
  105. package/dist/docs/guides/upgrading.md +636 -0
  106. package/dist/docs/guides/validators.md +217 -0
  107. package/dist/docs/guides/waiting-room.md +244 -0
  108. package/dist/docs/index.md +41 -0
  109. package/dist/docs/recipes/act-on-the-session-from-an-endpoint.md +95 -0
  110. package/dist/docs/recipes/adapt-a-game-for-walkthroughs.md +133 -0
  111. package/dist/docs/recipes/adapt-ui-for-observers.md +74 -0
  112. package/dist/docs/recipes/call-endpoint-from-ui.md +109 -0
  113. package/dist/docs/recipes/check-a-package-from-a-script.md +117 -0
  114. package/dist/docs/recipes/create-capability.md +66 -0
  115. package/dist/docs/recipes/create-endpoint.md +127 -0
  116. package/dist/docs/recipes/create-engine.md +111 -0
  117. package/dist/docs/recipes/create-game.md +70 -0
  118. package/dist/docs/recipes/create-guide.md +75 -0
  119. package/dist/docs/recipes/create-hook.md +80 -0
  120. package/dist/docs/recipes/create-presentation.md +142 -0
  121. package/dist/docs/recipes/create-scenario-editor.md +102 -0
  122. package/dist/docs/recipes/create-scenario.md +98 -0
  123. package/dist/docs/recipes/create-session-ui.md +116 -0
  124. package/dist/docs/recipes/create-settings.md +88 -0
  125. package/dist/docs/recipes/create-setup.md +115 -0
  126. package/dist/docs/recipes/create-tick-controller.md +65 -0
  127. package/dist/docs/recipes/create-user-interface.md +96 -0
  128. package/dist/docs/recipes/create-validator.md +67 -0
  129. package/dist/docs/recipes/create-waiting-room-ui.md +109 -0
  130. package/dist/docs/recipes/declare-api-uses.md +67 -0
  131. package/dist/docs/recipes/design-state-for-concurrent-writes.md +96 -0
  132. package/dist/docs/recipes/distribute-package.md +80 -0
  133. package/dist/docs/recipes/e2e-testing.md +116 -0
  134. package/dist/docs/recipes/end-game-on-condition.md +154 -0
  135. package/dist/docs/recipes/fix-duplicate-packages.md +101 -0
  136. package/dist/docs/recipes/index.md +86 -0
  137. package/dist/docs/recipes/make-an-endpoint-external.md +101 -0
  138. package/dist/docs/recipes/negotiate-across-teams.md +164 -0
  139. package/dist/docs/recipes/observe-other-teams-state.md +119 -0
  140. package/dist/docs/recipes/publish-a-package.md +139 -0
  141. package/dist/docs/recipes/remember-a-viewers-choice.md +55 -0
  142. package/dist/docs/recipes/review-a-past-day.md +73 -0
  143. package/dist/docs/recipes/share-assets-across-scenarios.md +120 -0
  144. package/dist/docs/recipes/share-logic-between-engine-and-ui.md +130 -0
  145. package/dist/docs/recipes/show-all-teams-participants.md +109 -0
  146. package/dist/docs/recipes/start-from-an-empty-package.md +169 -0
  147. package/dist/docs/recipes/take-a-file-in-an-endpoint.md +82 -0
  148. package/dist/docs/recipes/test-a-multi-role-game.md +51 -0
  149. package/dist/docs/recipes/test-user-interface.md +95 -0
  150. package/dist/docs/recipes/test-with-engine.md +115 -0
  151. package/dist/docs/recipes/upload-and-display-files.md +148 -0
  152. package/dist/docs/recipes/use-request-play.md +65 -0
  153. package/dist/docs/recipes/use-request-tick.md +75 -0
  154. package/dist/docs/troubleshooting.md +816 -0
  155. package/dist/execution/blob-inputs.d.ts +57 -0
  156. package/dist/execution/bundle-reload.d.ts +42 -0
  157. package/dist/execution/config-resolver.d.ts +127 -0
  158. package/dist/execution/configuration-builder.d.ts +66 -0
  159. package/dist/execution/context-composition.d.ts +161 -0
  160. package/dist/execution/endpoint-actions.d.ts +9 -0
  161. package/dist/execution/endpoint-payloads.d.ts +32 -0
  162. package/dist/execution/endpoint-runner.d.ts +129 -0
  163. package/dist/execution/engine-state.d.ts +40 -0
  164. package/dist/execution/executor-callbacks.d.ts +56 -0
  165. package/dist/execution/executor.d.ts +436 -0
  166. package/dist/execution/gates.d.ts +45 -0
  167. package/dist/execution/hook-chain.d.ts +25 -0
  168. package/dist/execution/logic-calls.d.ts +190 -0
  169. package/dist/execution/logic-failure.d.ts +84 -0
  170. package/dist/execution/logic-loader.d.ts +54 -0
  171. package/dist/execution/logic-result.d.ts +76 -0
  172. package/dist/execution/tick-controller-call.d.ts +32 -0
  173. package/dist/execution/types.d.ts +48 -0
  174. package/dist/generation/ts-type.d.ts +39 -0
  175. package/dist/guide/locale.d.ts +12 -0
  176. package/dist/guide/video-registry.d.ts +42 -0
  177. package/dist/help-examples.d.ts +125 -0
  178. package/dist/host/adapter.d.ts +67 -0
  179. package/dist/host/host-channel.d.ts +222 -0
  180. package/dist/host/index.d.ts +20 -0
  181. package/dist/host/protocol.d.ts +783 -0
  182. package/dist/host/surfaces.d.ts +42 -0
  183. package/dist/host/theme.d.ts +55 -0
  184. package/dist/host.js +583 -0
  185. package/dist/prompts/index.d.ts +7 -0
  186. package/dist/prompts/schema-builder.d.ts +29 -0
  187. package/dist/prompts/types.d.ts +108 -0
  188. package/dist/prompts/validators.d.ts +32 -0
  189. package/dist/runtime/capability-scope.d.ts +6 -0
  190. package/dist/runtime/context-merge.d.ts +29 -0
  191. package/dist/runtime/context-projection.d.ts +41 -0
  192. package/dist/runtime/guarded-callbacks.d.ts +15 -0
  193. package/dist/runtime/index.d.ts +27 -0
  194. package/dist/runtime/manifest-version.d.ts +55 -0
  195. package/dist/runtime/tick-validation.d.ts +25 -0
  196. package/dist/runtime.js +346 -0
  197. package/dist/schema.json +1546 -0
  198. package/dist/server/vite-plugin.d.ts +46 -0
  199. package/dist/services/tts/client.d.ts +51 -0
  200. package/dist/services/tts/elevenlabs.d.ts +24 -0
  201. package/dist/services/tts/types.d.ts +44 -0
  202. package/dist/storage/asset-resolver.d.ts +49 -0
  203. package/dist/storage/blob-store.d.ts +41 -0
  204. package/dist/templates/endpoint/logic.test.ts.liquid +61 -0
  205. package/dist/templates/endpoint/logic.ts.liquid +25 -0
  206. package/dist/templates/engine/init.json.liquid +7 -0
  207. package/dist/templates/engine/logic-aggregate.test.ts.liquid +90 -0
  208. package/dist/templates/engine/logic-aggregate.ts.liquid +46 -0
  209. package/dist/templates/engine/logic.test.ts.liquid +61 -0
  210. package/dist/templates/engine/logic.ts.liquid +32 -0
  211. package/dist/templates/engine/run.json.liquid +7 -0
  212. package/dist/templates/guide/01-at-a-glance.md.liquid +19 -0
  213. package/dist/templates/guide/02-preparation.md.liquid +18 -0
  214. package/dist/templates/guide/03-running-the-session.md.liquid +37 -0
  215. package/dist/templates/hook/logic.test.ts.liquid +46 -0
  216. package/dist/templates/hook/logic.ts.liquid +12 -0
  217. package/dist/templates/package/CLAUDE.md.template +338 -0
  218. package/dist/templates/package/DESIGN.md.liquid +144 -0
  219. package/dist/templates/package/README.md.liquid +143 -0
  220. package/dist/templates/package/claude/rules/workflow-create-capability.md +26 -0
  221. package/dist/templates/package/claude/rules/workflow-create-endpoint.md +35 -0
  222. package/dist/templates/package/claude/rules/workflow-create-engine.md +35 -0
  223. package/dist/templates/package/claude/rules/workflow-create-guide.md +40 -0
  224. package/dist/templates/package/claude/rules/workflow-create-presentation.md +37 -0
  225. package/dist/templates/package/claude/rules/workflow-create-user-interface.md +31 -0
  226. package/dist/templates/package/claude/rules/workflow-publish-package.md +54 -0
  227. package/dist/templates/package/claude/rules/workflow-test-engine-or-ui.md +30 -0
  228. package/dist/templates/package/claude/rules/workflow-update-sdk-version.md +43 -0
  229. package/dist/templates/package/claude/settings.json.template +16 -0
  230. package/dist/templates/package/gitignore.template +15 -0
  231. package/dist/templates/package/global-setup.ts.template +21 -0
  232. package/dist/templates/package/globals.d.ts.template +2 -0
  233. package/dist/templates/package/oxfmtrc.json.template +14 -0
  234. package/dist/templates/package/oxlintrc.json.template +238 -0
  235. package/dist/templates/package/package.json.liquid +65 -0
  236. package/dist/templates/package/playwright.config.ts.liquid +19 -0
  237. package/dist/templates/package/pnpm-workspace.yaml.template +27 -0
  238. package/dist/templates/package/test-setup.ts.liquid +7 -0
  239. package/dist/templates/package/tsconfig.json.liquid +15 -0
  240. package/dist/templates/package/vite.config.ts.liquid +19 -0
  241. package/dist/templates/package/vitest.config.ts.liquid +25 -0
  242. package/dist/templates/package/vitest.engine.config.ts.liquid +12 -0
  243. package/dist/templates/presentation/index.html.liquid +20 -0
  244. package/dist/templates/presentation/src/App.tsx.liquid +49 -0
  245. package/dist/templates/presentation/src/Slides.tsx.liquid +81 -0
  246. package/dist/templates/presentation/src/i18n.ts.liquid +54 -0
  247. package/dist/templates/presentation/src/main.tsx.liquid +14 -0
  248. package/dist/templates/scenario_editor/src/App.test.tsx.liquid +30 -0
  249. package/dist/templates/scenario_editor/src/App.tsx.liquid +95 -0
  250. package/dist/templates/scenario_editor/src/i18n.ts.liquid +44 -0
  251. package/dist/templates/session/src/App.test.tsx.liquid +60 -0
  252. package/dist/templates/session/src/App.tsx.liquid +128 -0
  253. package/dist/templates/session/src/i18n.ts.liquid +53 -0
  254. package/dist/templates/session/src/main.tsx.liquid +48 -0
  255. package/dist/templates/session/src/theme.ts.liquid +46 -0
  256. package/dist/templates/settings-editor/index.html.liquid +12 -0
  257. package/dist/templates/settings-editor/src/main.tsx.liquid +48 -0
  258. package/dist/templates/settings-editor/src/theme.ts.liquid +24 -0
  259. package/dist/templates/setup/src/App.test.tsx.liquid +39 -0
  260. package/dist/templates/setup/src/App.tsx.liquid +102 -0
  261. package/dist/templates/setup/src/i18n.ts.liquid +47 -0
  262. package/dist/templates/starter-game/capabilities/briefing/capability.sdk.json +18 -0
  263. package/dist/templates/starter-game/capabilities/plan/capability.sdk.json +17 -0
  264. package/dist/templates/starter-game/capabilities/results/capability.sdk.json +61 -0
  265. package/dist/templates/starter-game/capabilities/roles/capability.sdk.json +17 -0
  266. package/dist/templates/starter-game/capabilities/weather/capability.sdk.json +23 -0
  267. package/dist/templates/starter-game/engine/defaults.ts +81 -0
  268. package/dist/templates/starter-game/engine/engine.sdk.json +12 -0
  269. package/dist/templates/starter-game/engine/logic.test.ts +221 -0
  270. package/dist/templates/starter-game/engine/logic.ts +149 -0
  271. package/dist/templates/starter-game/engine/test-helpers.ts +74 -0
  272. package/dist/templates/starter-game/engine/types.ts +139 -0
  273. package/dist/templates/starter-game/guide/content/en/01-at-a-glance.md +51 -0
  274. package/dist/templates/starter-game/guide/content/en/02-preparation.md +35 -0
  275. package/dist/templates/starter-game/guide/content/en/03-running-the-day.md +58 -0
  276. package/dist/templates/starter-game/guide/guide.sdk.json +10 -0
  277. package/dist/templates/starter-game/guide/guide.test.ts +108 -0
  278. package/dist/templates/starter-game/hooks/assignproducts/defaults.ts +37 -0
  279. package/dist/templates/starter-game/hooks/assignproducts/hook.sdk.json +13 -0
  280. package/dist/templates/starter-game/hooks/assignproducts/logic/logic.test.ts +77 -0
  281. package/dist/templates/starter-game/hooks/assignproducts/logic/logic.ts +47 -0
  282. package/dist/templates/starter-game/hooks/assignproducts/types.ts +55 -0
  283. package/dist/templates/starter-game/package.json +68 -0
  284. package/dist/templates/starter-game/playwright.config.ts +19 -0
  285. package/dist/templates/starter-game/scenarios/heatwave/scenario.sdk.json +20 -0
  286. package/dist/templates/starter-game/scenarios/ordinary_week/scenario.sdk.json +12 -0
  287. package/dist/templates/starter-game/seriousgaming.sdk.json +23 -0
  288. package/dist/templates/starter-game/session/defaults.ts +80 -0
  289. package/dist/templates/starter-game/session/index.html +12 -0
  290. package/dist/templates/starter-game/session/session.sdk.json +11 -0
  291. package/dist/templates/starter-game/session/src/App.test.tsx +307 -0
  292. package/dist/templates/starter-game/session/src/App.tsx +309 -0
  293. package/dist/templates/starter-game/session/src/Section.tsx +37 -0
  294. package/dist/templates/starter-game/session/src/TeamDoor.tsx +96 -0
  295. package/dist/templates/starter-game/session/src/format.ts +8 -0
  296. package/dist/templates/starter-game/session/src/i18n.ts +51 -0
  297. package/dist/templates/starter-game/session/src/main.tsx +48 -0
  298. package/dist/templates/starter-game/session/src/theme.ts +45 -0
  299. package/dist/templates/starter-game/session/types.ts +135 -0
  300. package/dist/templates/starter-game/settings/engine/settings.sdk.json +50 -0
  301. package/dist/templates/starter-game/settings/menu/settings.sdk.json +78 -0
  302. package/dist/templates/starter-game/settings/session/settings.sdk.json +23 -0
  303. package/dist/templates/starter-game/settings/ui/settings.sdk.json +25 -0
  304. package/dist/templates/starter-game/test-setup.ts +7 -0
  305. package/dist/templates/starter-game/testing/e2e/game.spec.ts +139 -0
  306. package/dist/templates/starter-game/testing/e2e/global-setup.ts +21 -0
  307. package/dist/templates/starter-game/testing/engine/game.engine.test.ts +171 -0
  308. package/dist/templates/starter-game/tsconfig.json +19 -0
  309. package/dist/templates/starter-game/ui/defaults.ts +60 -0
  310. package/dist/templates/starter-game/ui/index.html +12 -0
  311. package/dist/templates/starter-game/ui/src/App.test.tsx +138 -0
  312. package/dist/templates/starter-game/ui/src/App.tsx +175 -0
  313. package/dist/templates/starter-game/ui/src/DayBar.test.tsx +78 -0
  314. package/dist/templates/starter-game/ui/src/DayBar.tsx +72 -0
  315. package/dist/templates/starter-game/ui/src/HistoryPanel.test.tsx +74 -0
  316. package/dist/templates/starter-game/ui/src/HistoryPanel.tsx +120 -0
  317. package/dist/templates/starter-game/ui/src/MakeRow.tsx +129 -0
  318. package/dist/templates/starter-game/ui/src/Section.tsx +37 -0
  319. package/dist/templates/starter-game/ui/src/ThemeToggle.tsx +49 -0
  320. package/dist/templates/starter-game/ui/src/TodayPanel.test.tsx +179 -0
  321. package/dist/templates/starter-game/ui/src/TodayPanel.tsx +92 -0
  322. package/dist/templates/starter-game/ui/src/YesterdayPanel.tsx +142 -0
  323. package/dist/templates/starter-game/ui/src/format.ts +12 -0
  324. package/dist/templates/starter-game/ui/src/i18n.ts +95 -0
  325. package/dist/templates/starter-game/ui/src/main.tsx +48 -0
  326. package/dist/templates/starter-game/ui/src/menu.ts +18 -0
  327. package/dist/templates/starter-game/ui/src/test-helpers.ts +58 -0
  328. package/dist/templates/starter-game/ui/src/theme.ts +45 -0
  329. package/dist/templates/starter-game/ui/src/writes.ts +43 -0
  330. package/dist/templates/starter-game/ui/types.ts +137 -0
  331. package/dist/templates/starter-game/ui/ui.sdk.json +11 -0
  332. package/dist/templates/starter-game/validators/capacity/defaults.ts +37 -0
  333. package/dist/templates/starter-game/validators/capacity/logic/logic.test.ts +96 -0
  334. package/dist/templates/starter-game/validators/capacity/logic/logic.ts +45 -0
  335. package/dist/templates/starter-game/validators/capacity/types.ts +55 -0
  336. package/dist/templates/starter-game/validators/capacity/validator.sdk.json +11 -0
  337. package/dist/templates/starter-game/vite.config.ts +19 -0
  338. package/dist/templates/starter-game/vitest.config.ts +15 -0
  339. package/dist/templates/starter-game/vitest.engine.config.ts +19 -0
  340. package/dist/templates/starter-game/waiting_room/defaults.ts +40 -0
  341. package/dist/templates/starter-game/waiting_room/index.html +12 -0
  342. package/dist/templates/starter-game/waiting_room/src/App.test.tsx +102 -0
  343. package/dist/templates/starter-game/waiting_room/src/App.tsx +194 -0
  344. package/dist/templates/starter-game/waiting_room/src/i18n.ts +33 -0
  345. package/dist/templates/starter-game/waiting_room/src/main.tsx +48 -0
  346. package/dist/templates/starter-game/waiting_room/src/theme.ts +45 -0
  347. package/dist/templates/starter-game/waiting_room/types.ts +59 -0
  348. package/dist/templates/starter-game/waiting_room/waiting_room.sdk.json +10 -0
  349. package/dist/templates/tick-controller/logic.ts.liquid +8 -0
  350. package/dist/templates/ui/index.html.liquid +12 -0
  351. package/dist/templates/ui/src/App.test.tsx.liquid +41 -0
  352. package/dist/templates/ui/src/App.tsx.liquid +103 -0
  353. package/dist/templates/ui/src/i18n.ts.liquid +47 -0
  354. package/dist/templates/ui/src/main.tsx.liquid +48 -0
  355. package/dist/templates/ui/src/theme.ts.liquid +46 -0
  356. package/dist/templates/validator/logic.test.ts.liquid +42 -0
  357. package/dist/templates/validator/logic.ts.liquid +21 -0
  358. package/dist/templates/waiting-room/index.html.liquid +12 -0
  359. package/dist/templates/waiting-room/src/App.test.tsx.liquid +57 -0
  360. package/dist/templates/waiting-room/src/App.tsx.liquid +118 -0
  361. package/dist/templates/waiting-room/src/i18n.ts.liquid +44 -0
  362. package/dist/templates/waiting-room/src/main.tsx.liquid +48 -0
  363. package/dist/templates/waiting-room/src/theme.ts.liquid +46 -0
  364. package/dist/templating/resource-metadata.d.ts +131 -0
  365. package/dist/types.d.ts +14 -0
  366. package/dist/utils/atomic-write.d.ts +40 -0
  367. package/dist/utils/cli-error.d.ts +64 -0
  368. package/dist/utils/document-parser-client.d.ts +20 -0
  369. package/dist/utils/env-loader.d.ts +40 -0
  370. package/dist/utils/error-codes.d.ts +339 -0
  371. package/dist/utils/errors.d.ts +19 -0
  372. package/dist/utils/global-settings.d.ts +65 -0
  373. package/dist/utils/llm-client.d.ts +34 -0
  374. package/dist/utils/logger.d.ts +36 -0
  375. package/dist/utils/output.d.ts +109 -0
  376. package/dist/utils/platform.d.ts +14 -0
  377. package/dist/utils/prompt.d.ts +36 -0
  378. package/dist/utils/real-path.d.ts +6 -0
  379. package/dist/utils/schema-properties.d.ts +35 -0
  380. package/dist/validation/ajv.d.ts +17 -0
  381. package/dist/validation/facilitator-guide-validator.d.ts +27 -0
  382. package/dist/validation/findings.d.ts +40 -0
  383. package/dist/validation/game-constraints.d.ts +10 -0
  384. package/dist/validation/game-validator.d.ts +34 -0
  385. package/dist/validation/package-validation.d.ts +41 -0
  386. package/dist/validation/package-validator.d.ts +19 -0
  387. package/dist/validation/resource-validator.d.ts +79 -0
  388. package/dist/validation/schema-defaults-validator.d.ts +29 -0
  389. package/dist/validation/schema-validation.d.ts +115 -0
  390. package/dist/validation/semver.d.ts +9 -0
  391. package/package.json +123 -3
@@ -0,0 +1,56 @@
1
+ /**
2
+ * createExecutorCallbacks - builds the raw runtime callbacks exposed to resource
3
+ * logic (the engine, hooks, validators, endpoints, tick controllers).
4
+ *
5
+ * This is the un-guarded callbacks object. Per-resource `uses` enforcement is
6
+ * layered on top by the executor via `createGuardedCallbacks`, which replaces
7
+ * any callback a resource did not declare with a throwing stub.
8
+ */
9
+ import type { PastStateEntry, SDKGame, SignatureCallbacks } from '@seriousgaming/sdk';
10
+ import { TtsClient } from '../services/tts/client';
11
+ import { DocumentParserClient } from '../utils/document-parser-client';
12
+ import { LLMClient } from '../utils/llm-client';
13
+ export interface ExecutorCallbacksDeps {
14
+ /** Absolute path to the game package (asset resolution, blob storage). */
15
+ packagePath: string;
16
+ llmClient: LLMClient;
17
+ documentParserClient: DocumentParserClient;
18
+ ttsClient: TtsClient;
19
+ /** The currently loaded game, or null. Read lazily so a reload is picked up. */
20
+ getGame: () => SDKGame | null;
21
+ /** The active scenario's root directory (for scenario-scoped assets), or null. */
22
+ getActiveScenarioRoot: () => string | null;
23
+ /**
24
+ * Read committed past ticks (§12.5), or null before a host has supplied a
25
+ * history to read. The second argument is the team indexes the calling
26
+ * resource is scoped to, which the executor resolves from what is running.
27
+ */
28
+ readPastState: ((range: {
29
+ fromTick: number;
30
+ toTick?: number;
31
+ capabilityIds?: string[];
32
+ }, teamIndexes: number[]) => PastStateEntry[]) | null;
33
+ /**
34
+ * Team indexes the resource now running is scoped to, or null for one that
35
+ * is scoped to the whole session (a session-scoped endpoint, §6.12). Read
36
+ * lazily, like `getGame`, because one callbacks object serves a whole
37
+ * per-team loop.
38
+ */
39
+ getScopedTeamIndexes: () => number[] | null;
40
+ /** Every team index in the session, for a session-scoped read. */
41
+ getAllTeamIndexes: () => number[];
42
+ /** Test/host overrides spread over the built callbacks. */
43
+ callbackOverrides: Partial<SignatureCallbacks>;
44
+ /**
45
+ * Consume one occasion of an armed platform failure, returning it when one
46
+ * fires: the dev server's `llm-failure` fault. Null when nothing can arm one.
47
+ */
48
+ takePlatformFailure?: (() => {
49
+ reason?: string;
50
+ } | undefined) | null;
51
+ }
52
+ /**
53
+ * Build the raw callbacks object. Constructed fresh per resource invocation so
54
+ * `getGame` / `getActiveScenarioRoot` reflect the live executor state.
55
+ */
56
+ export declare function createExecutorCallbacks(deps: ExecutorCallbacksDeps): SignatureCallbacks;
@@ -0,0 +1,436 @@
1
+ import type { ResolvedPackageManifest, EndpointOutcome, HookPayload, HookSignal, Participant, RunKind, SDKEndpoint, SDKGame, SDKScenario, SignatureCallbacks, TickControllerResult, ValidationRejection, ValidatorActor } from '@seriousgaming/sdk';
2
+ import { type TtsClientConfig } from '../services/tts/client';
3
+ import { type BundleReload } from './bundle-reload';
4
+ import { ResolvedSettings } from './configuration-builder';
5
+ import { type EndpointCallArgs, type EndpointRun } from './endpoint-runner';
6
+ import type { ExecutorCallbacksDeps } from './executor-callbacks';
7
+ import type { SessionSettingsOverrides, GameContext, ExecutorDependencies } from './types';
8
+ export type { GameContext };
9
+ export type { BundleReload };
10
+ export type { EndpointCallArgs, EndpointRun } from './endpoint-runner';
11
+ export declare class GameExecutor {
12
+ private packagePath;
13
+ private inMemory;
14
+ private config;
15
+ private game;
16
+ private activeScenario;
17
+ private context;
18
+ /**
19
+ * Canonical session-wide value of every shared-scope capability. Team
20
+ * contexts (and `this.context`) are views that mirror it; the store is
21
+ * the single source of truth for storage, undo, and persistence.
22
+ */
23
+ private sharedContext;
24
+ /** The game's engine. A game wires exactly one, and may wire none. */
25
+ private engine;
26
+ private logicLoader;
27
+ private configResolver;
28
+ private capabilityDefaults;
29
+ /** Capabilities a reload adopted since the context was last built (#640). */
30
+ private readonly addedCapabilities;
31
+ private lastTick;
32
+ /**
33
+ * Which teams the last tick's engine reported complete, by position in the
34
+ * contexts it was handed (§11). Read by the session straight after a tick.
35
+ */
36
+ private lastTickCompletion;
37
+ private waitingRoomOpen;
38
+ private deps;
39
+ /** `meta`, the roster, callbacks and bounds: what every logic call shares. */
40
+ private readonly calls;
41
+ /** What every runner below the executor is handed of it. */
42
+ private readonly host;
43
+ private readonly endpoints;
44
+ constructor(packagePath: string, options?: {
45
+ seriousGamingApiKey?: string;
46
+ seriousGamingApiHost?: string;
47
+ inMemory?: boolean;
48
+ callbacks?: Partial<SignatureCallbacks>;
49
+ tts?: TtsClientConfig;
50
+ /** The clock `meta.now` is read from. Defaults to the system clock. */
51
+ clock?: {
52
+ now(): number;
53
+ };
54
+ }, deps?: Partial<ExecutorDependencies>);
55
+ /**
56
+ * Set the active session locale. Session-wide, not per participant: it is
57
+ * surfaced to every logic function as `meta.locale`, so it can generate
58
+ * prose in the session language.
59
+ */
60
+ setLocale(locale: string): void;
61
+ getLocale(): string;
62
+ /**
63
+ * Set the session's random seed, surfaced to logic as `meta.seed`.
64
+ *
65
+ * The host owns it because it has to be stable for the life of the session
66
+ * and across a restart: a seed the executor drew on startup would give a
67
+ * restored session a different world than the one it was persisted from.
68
+ * The dev server keeps it in persisted state for exactly that reason.
69
+ */
70
+ setSeed(seed: string): void;
71
+ getSeed(): string;
72
+ /**
73
+ * Record whether the session's waiting room is open. Session-wide, and read
74
+ * by the tick controller so an author can stop the clock while players wait
75
+ * (§11). The executor itself changes no behaviour on it — that is the whole
76
+ * point: the flag swaps a UI surface, it does not pause the simulation.
77
+ */
78
+ setWaitingRoomOpen(open: boolean): void;
79
+ getWaitingRoomOpen(): boolean;
80
+ /**
81
+ * Record which kind of run this is, surfaced to logic as `meta.runKind`.
82
+ *
83
+ * Set once by the host that owns the run, before it starts. Changing it
84
+ * part way through would let one tick of a game see a different kind than
85
+ * the next, which is the one thing `runKind` promises cannot happen.
86
+ */
87
+ setRunKind(kind: RunKind): void;
88
+ getRunKind(): RunKind;
89
+ /**
90
+ * Where the roster logic receives as `participants` comes from (§10.2).
91
+ *
92
+ * The host's, like the history: the session owns who is on which team,
93
+ * and a second copy here would be a second copy to fall out of step.
94
+ */
95
+ setRosterSource(source: () => Participant[]): void;
96
+ /**
97
+ * Run `work` as one operation: every logic call inside it reads the same
98
+ * `meta.now`, taken from the clock as it starts (§10.2). Nested calls join
99
+ * the operation already running rather than starting their own, so a
100
+ * cohort tick that runs each independent team separately, and the tick
101
+ * controller evaluated after it, all read one instant.
102
+ */
103
+ inOperation<T>(work: () => Promise<T>): Promise<T>;
104
+ /** The instant the current operation started, or now when there is none. */
105
+ operationNow(): number;
106
+ /** How a result folds into a board, for the game as it is loaded now. */
107
+ private composition;
108
+ /**
109
+ * Fold an aggregate result into the team contexts and the canonical store.
110
+ * See {@link applyAggregateResult}.
111
+ */
112
+ private applyAggregateResult;
113
+ /** An aggregate function's store and team arguments. See {@link aggregateArgs}. */
114
+ private aggregateArgs;
115
+ /**
116
+ * Initialize the executor by loading config and initializing game
117
+ * @param generateConfiguration - Whether to generate configuration if it doesn't exist (default: true)
118
+ * @param reconfigure - Whether to regenerate invalid configuration (default: false)
119
+ * @param scenarioId - Optional scenario ID to activate. Pass null to skip
120
+ * the game's default scenario and use the settings defaults.
121
+ */
122
+ initialize(generateConfiguration?: boolean, reconfigure?: boolean, scenarioId?: string | null): Promise<void>;
123
+ /**
124
+ * Reset the game (re-initialize)
125
+ * @param reconfigure - Whether to regenerate invalid configuration (default: false)
126
+ */
127
+ reset(reconfigure?: boolean): Promise<void>;
128
+ /**
129
+ * Whether the saved configuration was built for a different scenario than
130
+ * the one about to run, and so cannot be reused (#439).
131
+ *
132
+ * An unrecorded scenario means the configuration predates this record or
133
+ * was written by hand; treat it as current rather than discarding it, since
134
+ * silently overwriting an author's configuration is the failure this guards
135
+ * against. A genuine scenario switch always records, so it is still caught.
136
+ */
137
+ private configuredScenarioIsStale;
138
+ /**
139
+ * Reinitialize the executor by reloading config and resetting
140
+ * @param reconfigure - Whether to regenerate invalid configuration (default: false)
141
+ */
142
+ reinitialize(reconfigure?: boolean): Promise<void>;
143
+ /**
144
+ * Execute a single tick.
145
+ *
146
+ * `team` identifies the team this tick runs for when the caller manages
147
+ * multiple teams itself (independent mode swaps each team's context in
148
+ * before calling). Aggregate functions receive it in their single-element
149
+ * `teams` array; when omitted, the default single-team identity is used.
150
+ */
151
+ executeTick(tick?: number, team?: {
152
+ teamId: string;
153
+ index: number;
154
+ }): Promise<GameContext>;
155
+ /**
156
+ * Execute a tick across multiple teams.
157
+ * For each engine in order:
158
+ * - Run is called independently for each team's context
159
+ * - RunAggregate is called once with all teams' contexts, for a declared
160
+ * aggregate engine
161
+ * Returns the updated array of team contexts.
162
+ *
163
+ * `teamIndexes` carries each team's stable index (positions can have gaps
164
+ * after a removal); when omitted, indexes default to array position.
165
+ */
166
+ executeMultiTeamTick(teamContexts: GameContext[], tick: number, teamIndexes?: number[]): Promise<GameContext[]>;
167
+ /**
168
+ * The tick engine shared by {@link executeTick} and
169
+ * {@link executeMultiTeamTick}. For every engine in order it runs `Run` on
170
+ * each team's context (rejecting a shared-capability write from `Run`), then,
171
+ * for a declared aggregate engine, `RunAggregate` once across all teams,
172
+ * folding the aggregate's shared result back in. `identities` supplies the
173
+ * `teamId`/`index` each team presents to `RunAggregate`. The executor's own
174
+ * context is left mirroring team 0.
175
+ */
176
+ private runTick;
177
+ private runTickInOperation;
178
+ /**
179
+ * Upgrade a single-team initialisation to multi-team by running InitAggregate
180
+ * across all N teams simultaneously. Call this after initialize() when teamCount > 1.
181
+ *
182
+ * executeInit() runs Init per engine and InitAggregate with a single team (for
183
+ * single-team compatibility). This method then re-runs InitAggregate for each
184
+ * aggregate engine with all N teams' post-Init contexts, producing the correct
185
+ * multi-team initial state.
186
+ */
187
+ executeMultiTeamInit(teamCount: number, teamIndexes?: number[]): Promise<GameContext[]>;
188
+ /**
189
+ * Initialise independent teams, each on its own (§9.2a): `InitAggregate`
190
+ * is handed a one-element `teams` holding only that team (§5.3), as
191
+ * `RunAggregate` is at each team's tick.
192
+ */
193
+ executeIndependentInit(teamIndexes: number[]): Promise<GameContext[]>;
194
+ private executeMultiTeamInitInOperation;
195
+ /**
196
+ * One post-`Init` context per team, each built from the pristine initial
197
+ * context with that team's identity in `meta`.
198
+ *
199
+ * A game with no `Init` gets the initial context unchanged, which is what
200
+ * the clone produced before and what a game without one expects.
201
+ */
202
+ private initialiseTeamContexts;
203
+ /** Which teams the last tick's engine reported complete, by position (§11). */
204
+ getLastTickCompletion(): boolean[];
205
+ /**
206
+ * Get the current context.
207
+ *
208
+ * Cloned, as `getSharedContext` has always been: a spread leaves every
209
+ * capability value shared with the store, so a caller mutating one wrote
210
+ * game state without a validator, a write check or a persist (#491). A
211
+ * read hands back a value the caller owns.
212
+ */
213
+ getContext(): GameContext;
214
+ /**
215
+ * Set the context (used for undo)
216
+ */
217
+ setContext(context: GameContext): void;
218
+ /**
219
+ * Current value of the canonical shared store: one value per shared-scope
220
+ * capability, session-wide. Team contexts only ever carry views of it.
221
+ */
222
+ getSharedContext(): GameContext;
223
+ /**
224
+ * Merge values into the canonical shared store (the facilitator shared
225
+ * write path). The executor's own context view is kept in step; callers
226
+ * that hold team context views (dev server, runners) re-compose theirs.
227
+ */
228
+ setSharedContext(update: GameContext): void;
229
+ /**
230
+ * Get the configuration
231
+ */
232
+ getConfig(): ResolvedPackageManifest | null;
233
+ /**
234
+ * Hash of the fully resolved configuration (capability schemas included).
235
+ * Persisted with game state so a later load can detect that the
236
+ * configuration changed while the state sat on disk.
237
+ */
238
+ getConfigHash(): string;
239
+ /**
240
+ * Hash of the on-disk resolved configuration without mutating live state.
241
+ *
242
+ * {@link reinitialize} resets the executor (rebuilds context, re-runs Init),
243
+ * so it must not be used merely to learn whether the config changed: a no-op
244
+ * save would silently rewind a running session. The config watcher peeks the
245
+ * hash with this method and only reinitialises when it actually differs.
246
+ */
247
+ peekConfigHash(): Promise<string>;
248
+ /**
249
+ * Get the current game
250
+ */
251
+ getGame(): SDKGame | null;
252
+ reloadEngine(engineIdentifier: string): void;
253
+ /** Make the next run of every logic resource load what is on disk. */
254
+ clearLogicCache(): void;
255
+ /**
256
+ * Re-read the package's resource bundles without touching the session.
257
+ *
258
+ * Context, tick and session overrides are kept. What a running session can
259
+ * adopt, it adopts: logic, surfaces, endpoints, the game's locale names,
260
+ * and a capability it did not have, seeded with its schema defaults. What
261
+ * only applies when a session initialises is kept as the
262
+ * session started with it and reported as pending: settings whose
263
+ * resolved values changed, the manifest fields `Init` or session creation
264
+ * read, and a capability removed or moved to another scope. A bundle that
265
+ * fails to load or validate throws and leaves the previous configuration
266
+ * in force.
267
+ */
268
+ reloadBundles(): Promise<BundleReload>;
269
+ /**
270
+ * The schema defaults of each capability adopted by a reload since the
271
+ * session last initialised, for a host composing them under every board
272
+ * it builds. Only those: a board lacks one of them because it was built,
273
+ * or recorded, before the capability existed, which no other capability's
274
+ * absence means.
275
+ */
276
+ getAddedCapabilityDefaults(): Map<string, Record<string, unknown>>;
277
+ /**
278
+ * Build initial context from capabilities
279
+ */
280
+ private buildInitialContext;
281
+ /** Resolve the game's engine. A game wires exactly one. */
282
+ private resolveEngine;
283
+ private executeInit;
284
+ private executeInitInOperation;
285
+ /**
286
+ * Get the active scenario (if any)
287
+ */
288
+ getActiveScenario(): SDKScenario | null;
289
+ /** The scenario `initialize` would activate for this id, without activating it. */
290
+ findScenario(scenarioId?: string | null): SDKScenario | null;
291
+ /**
292
+ * Validate a prospective scenario's settings overrides without activating
293
+ * the scenario or mutating any state. Throws with the offending keys named
294
+ * when invalid.
295
+ *
296
+ * The dev server calls this at the scenario-select boundary before deleting
297
+ * the current session's state and configuration files, so an invalid target
298
+ * scenario is rejected up front and the last-good session survives (#239).
299
+ */
300
+ assertScenarioConfigurationValid(scenarioId: string | null): void;
301
+ /**
302
+ * Re-read the package manifest from disk and update only the scenario
303
+ * surface — `config.scenarios` and the active game's
304
+ * `definition.scenarios` reference list. Used by the author-time save
305
+ * flow (issue #101) to make a freshly-written `scenarios/<id>/` bundle
306
+ * visible without resetting context, history, or centralized
307
+ * configuration. Other resources are left untouched.
308
+ */
309
+ reloadPackageScenarios(): Promise<void>;
310
+ /**
311
+ * Set the active scenario by ID (used when restoring from persisted state)
312
+ */
313
+ setActiveScenarioId(scenarioId: string): void;
314
+ private loadEngine;
315
+ /**
316
+ * Execute the tick controller for the current game and return its result.
317
+ * Returns null if no tick controller is configured.
318
+ */
319
+ executeTickController(teams: {
320
+ teamId: string;
321
+ index: number;
322
+ context: Record<string, unknown>;
323
+ }[], identity?: {
324
+ teamId: string;
325
+ index: number;
326
+ }): Promise<TickControllerResult | null>;
327
+ /**
328
+ * Dispatch a lifecycle signal to all hooks subscribed to it. Each hook
329
+ * receives the previous hook's output as input, so the executor's context
330
+ * reflects the full chain of mutations after the call returns.
331
+ */
332
+ dispatchHook<S extends HookSignal>(signal: S, payload: HookPayload<S>): Promise<GameContext>;
333
+ /**
334
+ * Put a participant's context write to every validator exporting
335
+ * `UpdateData` whose `reads` it changes (§15.2.1). See
336
+ * {@link runUpdateDataGates}.
337
+ */
338
+ runValidators(previous: GameContext, next: GameContext, actor: ValidatorActor): Promise<ValidationRejection[]>;
339
+ /**
340
+ * Put a participant's request for the next tick to every validator
341
+ * exporting `RequestTick` (§15.1). A request changes nothing, so the
342
+ * changed-`reads` rule has nothing to look at: every such gate runs.
343
+ */
344
+ runTickGates(context: GameContext, actor: ValidatorActor, requestedTick: number): Promise<ValidationRejection[]>;
345
+ /**
346
+ * Directly set the session-override layer in memory. Used by the dev
347
+ * server in in-memory mode so config UI changes are captured without
348
+ * writing to disk.
349
+ */
350
+ setConfiguration(config: SessionSettingsOverrides): void;
351
+ /**
352
+ * Return the current in-memory session-override layer, if any.
353
+ */
354
+ getSessionOverrides(): SessionSettingsOverrides | null;
355
+ /**
356
+ * Every filled slot's configuration, resolved through the §8.2 layers now.
357
+ *
358
+ * Distinct from {@link getSessionOverrides}, which is the stored
359
+ * session-override layer and holds only what was overridden. A surface that
360
+ * wants values to render, seed a form with, or bake into a scenario wants
361
+ * this one.
362
+ */
363
+ resolveConfiguration(): ResolvedSettings;
364
+ /** The same, through the defaults and the active scenario only (§6.15.1). */
365
+ resolveConfigurationWithoutSession(): ResolvedSettings;
366
+ /** Every settings resource through the §8.2 layers, over any scenario and top layer. */
367
+ resolveLayers(scenario: SDKScenario | null, overrides: SessionSettingsOverrides | null): ResolvedSettings;
368
+ /**
369
+ * Every settings resource resolved as a scenario other than the session's
370
+ * would resolve it, under edits of its own rather than the session layer:
371
+ * the scenario editor's draft (§6.5). Null resolves the defaults alone.
372
+ * Throws when the package declares no such scenario.
373
+ */
374
+ resolveScenarioDraft(scenarioId: string | null, edits: SessionSettingsOverrides | null): ResolvedSettings;
375
+ /**
376
+ * Compute the default session-override layer for the current game,
377
+ * ignoring any cached user edits. Used by the dev server's 'Reset
378
+ * configuration' action so the operator can return to a clean slate without
379
+ * restarting the game. The caller persists the returned configuration.
380
+ */
381
+ buildResetConfiguration(): ResolvedSettings;
382
+ /**
383
+ * Get the identifiers of all shared capabilities referenced in the current game
384
+ */
385
+ getSharedCapabilityIds(): string[];
386
+ /**
387
+ * The capabilities declared `lifetime: 'session'` (§7.6): kept out of the
388
+ * tick's reach, so undo and reset leave them as they are.
389
+ */
390
+ getSessionLifetimeCapabilityIds(): string[];
391
+ /**
392
+ * Get the identifiers of all team-readable capabilities in the current game
393
+ */
394
+ getTeamReadableCapabilityIds(): string[];
395
+ /**
396
+ * Where `getPastState` reads from, and what 'every team' means to it.
397
+ *
398
+ * Both come from the host rather than being tracked here, because the
399
+ * history and the roster are the session's and a second copy of the team
400
+ * list in the executor is a second copy to fall out of step.
401
+ */
402
+ setHistoryAccess(access: {
403
+ read: NonNullable<ExecutorCallbacksDeps['readPastState']>;
404
+ allTeamIndexes: () => number[];
405
+ }): void;
406
+ /**
407
+ * Have the platform services logic calls (`generateText`, `extractText`,
408
+ * `generateSpeech`) fail whenever `take` returns a failure. The host owns
409
+ * what arms one: the dev server's `llm-failure` fault.
410
+ */
411
+ setPlatformFailures(take: NonNullable<ExecutorCallbacksDeps['takePlatformFailure']>): void;
412
+ /**
413
+ * Look up an endpoint by identifier in the loaded configuration.
414
+ */
415
+ getEndpoint(identifier: string): SDKEndpoint | undefined;
416
+ /**
417
+ * Invoke an endpoint's `Handle` function. The caller identity is sourced
418
+ * from host bookkeeping — iframe-supplied fields are never trusted. The
419
+ * returned value is validated against the endpoint's `responseSchema` by
420
+ * the dispatcher before being returned to the caller.
421
+ *
422
+ * Throws if the endpoint is unknown or its bundle does not export a
423
+ * `Handle` function.
424
+ */
425
+ runEndpoint(args: EndpointCallArgs): Promise<EndpointRun>;
426
+ /**
427
+ * Call `Respond` once an endpoint's effects have landed (§6.12). The
428
+ * arguments are built exactly as `Handle`'s were, from state the session
429
+ * has read afresh, with the plan `Handle` returned and what each of its
430
+ * actions came to. Its return is the response, held to `responseSchema`.
431
+ */
432
+ respondEndpoint(args: EndpointCallArgs & {
433
+ plan: EndpointRun;
434
+ outcomes: EndpointOutcome[];
435
+ }): Promise<unknown>;
436
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * The validator gates (§15): every validator that exports a gate, put to the
3
+ * action that gate stands for, collecting every refusal.
4
+ *
5
+ * Two gates exist, `UpdateData` for a participant's write and `RequestTick`
6
+ * for a participant's request for the next tick, and they differ only in what
7
+ * each validator is handed and in whether it runs at all. Everything else,
8
+ * which validators have the gate, the manifest order, a throw or an abandoned
9
+ * call read as one more refusal, and collect-all, is one rule, so it is written
10
+ * once here and each gate is an `invoke` over it. Who counts as a participant,
11
+ * and so whether a gate runs, is the session's to decide; this module is only
12
+ * the running of them.
13
+ */
14
+ import type { ValidationRejection, ValidatorActor } from '@seriousgaming/sdk';
15
+ import type { LogicHost } from './logic-calls';
16
+ import type { GameContext } from './types';
17
+ /**
18
+ * Put a participant's context write to every validator exporting
19
+ * `UpdateData` whose `reads` it changes (§15.2.1).
20
+ *
21
+ * Collects every rejection (form-style UX) rather than short-circuiting, and
22
+ * returns an empty array when every validator that ran returned
23
+ * `{ ok: true }`. Validators are reject-only: callers must not apply the
24
+ * proposed `next` state unless the returned array is empty.
25
+ *
26
+ * **Only the validators the write could affect run** (§15.2), on the rule
27
+ * §11.1a already applies to the tick controller: a validator runs when the
28
+ * write changes the value of a capability in its `reads`, and one that
29
+ * declares no reads runs on every write. Every validator running on every
30
+ * keystroke from every participant is the hottest path in the runtime, and
31
+ * most of those runs cannot change the verdict — a validator now receives
32
+ * only its declared reads (§7.4), so a write touching none of them cannot
33
+ * alter anything it can see.
34
+ *
35
+ * The comparison is by value, not by payload key. A full-context sender
36
+ * names every capability on every write, so gating on the keys present
37
+ * would re-run everything for exactly the chattiest callers.
38
+ */
39
+ export declare function runUpdateDataGates(host: LogicHost, previous: GameContext, next: GameContext, actor: ValidatorActor): Promise<ValidationRejection[]>;
40
+ /**
41
+ * Put a participant's request for the next tick to every validator
42
+ * exporting `RequestTick` (§15.1). A request changes nothing, so the
43
+ * changed-`reads` rule has nothing to look at: every such gate runs.
44
+ */
45
+ export declare function runRequestTickGates(host: LogicHost, context: GameContext, actor: ValidatorActor, requestedTick: number): Promise<ValidationRejection[]>;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Running the hooks subscribed to one lifecycle signal (§14), as a chain.
3
+ *
4
+ * Each hook receives the board the hook before it left, so the chain is one
5
+ * sequence of folds over one team's board rather than several independent
6
+ * calls, and the roster they read is taken once for all of them (§14.3). The
7
+ * executor owns the board; the chain reads it and writes it back after every
8
+ * hook, so a hook that throws leaves the ones before it applied, exactly as a
9
+ * runtime that stops a chain part way must.
10
+ */
11
+ import type { HookPayload, HookSignal } from '@seriousgaming/sdk';
12
+ import type { LogicHost } from './logic-calls';
13
+ import type { GameContext } from './types';
14
+ export interface HookChainHost extends LogicHost {
15
+ /** The board the chain runs against: the team the host swapped in. */
16
+ board(): GameContext;
17
+ setBoard(context: GameContext): void;
18
+ capabilityDefaults(): ReadonlyMap<string, Record<string, unknown>>;
19
+ }
20
+ /**
21
+ * Dispatch a lifecycle signal to all hooks subscribed to it. Each hook
22
+ * receives the previous hook's output as input, so the host's board
23
+ * reflects the full chain of mutations after the call returns.
24
+ */
25
+ export declare function runHookChain<S extends HookSignal>(host: HookChainHost, signal: S, payload: HookPayload<S>): Promise<GameContext>;