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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (391) hide show
  1. package/LICENSE +93 -0
  2. package/README.md +36 -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 +27368 -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 +16884 -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 +209 -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 +236 -0
  69. package/dist/docs/cli-and-dev-server.md +217 -0
  70. package/dist/docs/cli-error-codes.md +154 -0
  71. package/dist/docs/cli-reference.md +2488 -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 +575 -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 +335 -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 +122 -3
@@ -0,0 +1,58 @@
1
+ import type { Context, Settings } from '../types';
2
+
3
+ /**
4
+ * A complete starting context and settings for the surface's tests.
5
+ *
6
+ * A game wires one participant surface, so `Context` is every capability it
7
+ * reads or writes. A panel test cares about a handful of those, so it spreads
8
+ * what it needs over these rather than restating the whole shape, and adding a
9
+ * field to a capability does not break every test that was never about it.
10
+ */
11
+ export const baseContext: Context = {
12
+ plan: { Make: { lemonade: 40, icedtea: 20, cookies: 10 } },
13
+ weather: { Today: 'sunny', Expected: { lemonade: 72, icedtea: 39, cookies: 26 } },
14
+ results: {
15
+ Day: 0,
16
+ Weather: 'sunny',
17
+ Lines: {},
18
+ Takings: 0,
19
+ Spent: 0,
20
+ Profit: 0,
21
+ Purse: 0,
22
+ },
23
+ roles: { LooksAfter: {} },
24
+ briefing: { Message: '' },
25
+ };
26
+
27
+ /** A day that has been played, for the panels that only appear once one has. */
28
+ export const playedDay: Context = {
29
+ ...baseContext,
30
+ results: {
31
+ Day: 1,
32
+ Weather: 'sunny',
33
+ Lines: {
34
+ lemonade: { Made: 40, Wanted: 68, Sold: 40, PouredAway: 0, TurnedAway: 28 },
35
+ icedtea: { Made: 20, Wanted: 15, Sold: 15, PouredAway: 5, TurnedAway: 0 },
36
+ cookies: { Made: 10, Wanted: 24, Sold: 10, PouredAway: 0, TurnedAway: 14 },
37
+ },
38
+ Takings: 40 * 50 + 15 * 60 + 10 * 70,
39
+ Spent: 40 * 15 + 20 * 20 + 10 * 25,
40
+ Profit: 40 * 50 + 15 * 60 + 10 * 70 - (40 * 15 + 20 * 20 + 10 * 25),
41
+ Purse: 2350,
42
+ },
43
+ };
44
+
45
+ export const baseSettings: Settings = {
46
+ menu: {
47
+ Capacity: 120,
48
+ Menu: {
49
+ lemonade: { Name: 'Lemonade', Order: 1, Cost: 15, Price: 50 },
50
+ icedtea: { Name: 'Iced tea', Order: 2, Cost: 20, Price: 60 },
51
+ cookies: { Name: 'Cookies', Order: 3, Cost: 25, Price: 70 },
52
+ },
53
+ },
54
+ ui: {
55
+ Step: 5,
56
+ CurrencySymbol: '£',
57
+ },
58
+ };
@@ -0,0 +1,45 @@
1
+ import { createTheme } from '@mui/material/styles';
2
+ import { useUserInterfaceTheme } from '@seriousgaming/sdk/ui';
3
+ import { useMemo } from 'react';
4
+
5
+ /**
6
+ * The host owns the palette, the game owns the typography and the component
7
+ * shapes. Reading `theme.mode` rather than the browser's preference is what
8
+ * keeps a participant's screen and the facilitator's looking like one product.
9
+ */
10
+ export const useAppTheme = () => {
11
+ const theme = useUserInterfaceTheme();
12
+
13
+ return useMemo(() => {
14
+ const colors = theme.mode === 'light' ? theme.light : theme.dark;
15
+ return createTheme({
16
+ palette: {
17
+ mode: theme.mode,
18
+ primary: { main: colors.primary, contrastText: colors.contrastText.primary },
19
+ secondary: { main: colors.secondary, contrastText: colors.contrastText.secondary },
20
+ success: { main: colors.success, contrastText: colors.contrastText.success },
21
+ error: { main: colors.error, contrastText: colors.contrastText.error },
22
+ warning: { main: colors.warning, contrastText: colors.contrastText.warning },
23
+ info: { main: colors.info, contrastText: colors.contrastText.info },
24
+ },
25
+ shape: { borderRadius: 10 },
26
+ components: {
27
+ MuiButton: { styleOverrides: { root: { textTransform: 'none' } } },
28
+ MuiTab: {
29
+ styleOverrides: { root: { textTransform: 'none', fontSize: '0.95rem' } },
30
+ },
31
+ MuiToggleButton: { styleOverrides: { root: { textTransform: 'none' } } },
32
+ MuiTableCell: {
33
+ styleOverrides: {
34
+ head: {
35
+ fontSize: '0.75rem',
36
+ fontWeight: 700,
37
+ letterSpacing: '0.07em',
38
+ textTransform: 'uppercase',
39
+ },
40
+ },
41
+ },
42
+ },
43
+ });
44
+ }, [theme]);
45
+ };
@@ -0,0 +1,43 @@
1
+ import type { MutationReporter } from '@seriousgaming/sdk/ui';
2
+ import { createContext, useContext } from 'react';
3
+
4
+ /**
5
+ * One mutation reporter for the whole surface.
6
+ *
7
+ * `setData` returns a promise, and a write the host refuses rejects it. Nothing
8
+ * on screen says so by itself, because the local view merged the change the
9
+ * moment it was sent: the participant is left looking at a decision the game
10
+ * never received. Every write here goes through `reporter.run`, and `App`
11
+ * renders the one notice that reports what comes back.
12
+ *
13
+ * The context carries the whole reporter, `pending` included, so any control
14
+ * can disable itself while a write is in flight. That re-renders the tab tree
15
+ * on every write, which is free at this size. A surface with dozens of leaf
16
+ * inputs would narrow the context to `run` alone and let individual controls
17
+ * call `useMutationReporter` for their own pending state.
18
+ */
19
+ export const WriteContext = createContext<MutationReporter | null>(null);
20
+
21
+ /**
22
+ * Outside a provider the write still runs and its result is dropped, so a
23
+ * component stays renderable on its own in a test without every one of them
24
+ * having to install the provider.
25
+ */
26
+ const UNREPORTED: MutationReporter = {
27
+ run: async (mutate) => {
28
+ try {
29
+ await mutate();
30
+ return true;
31
+ } catch {
32
+ return false;
33
+ }
34
+ },
35
+ pending: false,
36
+ late: null,
37
+ failure: null,
38
+ dismiss: () => {},
39
+ };
40
+
41
+ export function useWrite(): MutationReporter {
42
+ return useContext(WriteContext) ?? UNREPORTED;
43
+ }
@@ -0,0 +1,137 @@
1
+ // This file is auto-generated from the user interface's capability definitions.
2
+ // Do not edit this file directly. It will be regenerated on build.
3
+
4
+ export interface Context {
5
+ plan: {
6
+ /**
7
+ * How many of each menu item to make today, keyed by item id. Keyed rather than a flat set of fields so that two people changing two different items write different keys, and the host's merge keeps both.
8
+ */
9
+ Make: {
10
+ [k: string]: number;
11
+ };
12
+ };
13
+ weather: {
14
+ /**
15
+ * The forecast for the day about to be played
16
+ */
17
+ Today: 'sunny' | 'cloudy' | 'rainy';
18
+ /**
19
+ * Roughly how many of each item people will want today, keyed by item id. A forecast, not a promise: the day lands somewhere near it.
20
+ */
21
+ Expected: {
22
+ [k: string]: number;
23
+ };
24
+ };
25
+ results: {
26
+ /**
27
+ * The day these results are for
28
+ */
29
+ Day: number;
30
+ /**
31
+ * What the weather actually did
32
+ */
33
+ Weather: string;
34
+ /**
35
+ * What happened to each menu item, keyed by item id
36
+ */
37
+ Lines: {
38
+ [k: string]: DayLine;
39
+ };
40
+ /**
41
+ * Money in, in pence
42
+ */
43
+ Takings: number;
44
+ /**
45
+ * Cost of everything made, in pence
46
+ */
47
+ Spent: number;
48
+ /**
49
+ * Takings less spend, in pence
50
+ */
51
+ Profit: number;
52
+ /**
53
+ * Everything made so far, in pence
54
+ */
55
+ Purse: number;
56
+ };
57
+ roles: {
58
+ /**
59
+ * Which menu item each participant is in charge of, keyed by participant id. Written by the participantJoin hook, and the reason two people normally edit two different keys.
60
+ */
61
+ LooksAfter: {
62
+ [k: string]: string;
63
+ };
64
+ };
65
+ briefing: {
66
+ /**
67
+ * Facilitator note shown on every team's screen. Shared scope: one value for the whole session, written only from the session surface. Session lifetime: an undo or a reset leaves it as the facilitator last wrote it.
68
+ */
69
+ Message: string;
70
+ };
71
+ }
72
+ export interface DayLine {
73
+ Made: number;
74
+ /**
75
+ * How many people asked for one
76
+ */
77
+ Wanted: number;
78
+ Sold: number;
79
+ /**
80
+ * Made and not sold
81
+ */
82
+ PouredAway: number;
83
+ /**
84
+ * Asked for and not available
85
+ */
86
+ TurnedAway: number;
87
+ }
88
+
89
+ export type CrossTeamContext = Record<string, never>;
90
+
91
+ export interface Settings {
92
+ menu: {
93
+ /**
94
+ * How many items the stall can make in a day, across the whole menu
95
+ */
96
+ Capacity: number;
97
+ Menu: Menu;
98
+ };
99
+ ui: {
100
+ /**
101
+ * How many items each nudge of a slider adds to or takes off the plan
102
+ */
103
+ Step: number;
104
+ /**
105
+ * Symbol for money on the participant surface. Prices are the same numbers whichever symbol is shown
106
+ */
107
+ CurrencySymbol: '£' | '$' | '€';
108
+ };
109
+ }
110
+ /**
111
+ * What the stall sells, keyed by item id. Money is in pence, so the sums stay in whole numbers. Read by the engine and every surface, so the price on screen and the price in the sums are the same number.
112
+ */
113
+ export interface Menu {
114
+ [k: string]: MenuItem;
115
+ }
116
+ export interface MenuItem {
117
+ /**
118
+ * What the item is called on every screen
119
+ */
120
+ Name: string;
121
+ /**
122
+ * Where it sits on the menu, so every screen lists it in the same order. 1 comes first
123
+ */
124
+ Order: number;
125
+ /**
126
+ * Cost to make one, in pence
127
+ */
128
+ Cost: number;
129
+ /**
130
+ * Sale price, in pence
131
+ */
132
+ Price: number;
133
+ }
134
+
135
+ import type { UserInterfaceCallbacks } from '@seriousgaming/sdk';
136
+
137
+ export type Callbacks = Pick<UserInterfaceCallbacks, never>;
@@ -0,0 +1,11 @@
1
+ {
2
+ "definition": {
3
+ "reads": ["plan", "weather", "results", "roles", "briefing"],
4
+ "writes": ["plan"],
5
+ "settings": ["menu", "ui"]
6
+ },
7
+ "ui": {
8
+ "entrypoint": "index.html"
9
+ },
10
+ "rootDirectory": "."
11
+ }
@@ -0,0 +1,37 @@
1
+ // This file is auto-generated from the schemas the resource declares: the values
2
+ // a session starts with, for use as test fixtures.
3
+ // Do not edit this file directly. It will be regenerated on build.
4
+
5
+ import type { Context, Settings } from './types';
6
+
7
+ export const defaultContext: Context = {
8
+ plan: {
9
+ Make: {},
10
+ },
11
+ };
12
+
13
+ export const defaultSettings: Settings = {
14
+ menu: {
15
+ Capacity: 120,
16
+ Menu: {
17
+ lemonade: {
18
+ Name: 'Lemonade',
19
+ Order: 1,
20
+ Cost: 15,
21
+ Price: 50,
22
+ },
23
+ icedtea: {
24
+ Name: 'Iced tea',
25
+ Order: 2,
26
+ Cost: 20,
27
+ Price: 60,
28
+ },
29
+ cookies: {
30
+ Name: 'Cookies',
31
+ Order: 3,
32
+ Cost: 25,
33
+ Price: 70,
34
+ },
35
+ },
36
+ },
37
+ };
@@ -0,0 +1,96 @@
1
+ import { describe, expect, it } from 'vitest';
2
+
3
+ import type { Settings, Context } from '../types';
4
+ import { UpdateData } from './logic';
5
+
6
+ const actor = {
7
+ role: 'participant',
8
+ participant: {
9
+ id: 'participant-1',
10
+ teamId: 'team-1',
11
+ name: 'Ada',
12
+ index: 0,
13
+ connected: true,
14
+ },
15
+ } as const;
16
+
17
+ const settings: Settings = {
18
+ menu: {
19
+ Capacity: 120,
20
+ Menu: {
21
+ lemonade: { Name: 'Lemonade', Order: 1, Cost: 15, Price: 50 },
22
+ icedtea: { Name: 'Iced tea', Order: 2, Cost: 20, Price: 60 },
23
+ cookies: { Name: 'Cookies', Order: 3, Cost: 25, Price: 70 },
24
+ },
25
+ },
26
+ };
27
+
28
+ const START = { lemonade: 40, icedtea: 20, cookies: 10 };
29
+
30
+ /** `next` is the merged state the write would produce, which is what the host hands a validator. */
31
+ const verdict = (
32
+ made: Partial<Record<string, number>>,
33
+ over: { previous?: Partial<Context['plan']['Make']> } = {}
34
+ ) =>
35
+ UpdateData({
36
+ participants: [],
37
+ previous: { plan: { Make: { ...START, ...over.previous } } },
38
+ next: {
39
+ plan: { Make: { ...START, ...over.previous, ...made } as Record<string, number> },
40
+ },
41
+ actor,
42
+ settings,
43
+ meta: { locale: 'en', seed: 'lemonade-test-seed', runKind: 'session', now: 0 },
44
+ });
45
+
46
+ describe('UpdateData', () => {
47
+ it('accepts a plan the stall can make', async () => {
48
+ expect(await verdict({ lemonade: 60 })).toEqual({ ok: true });
49
+ });
50
+
51
+ it('accepts a plan that fills the stall exactly', async () => {
52
+ expect(await verdict({ lemonade: 90, icedtea: 20, cookies: 10 })).toEqual({ ok: true });
53
+ });
54
+
55
+ /**
56
+ * The case the whole validator exists for. Two people each change their own
57
+ * item, each within capacity on the screen in front of them, and the merged
58
+ * plan is not.
59
+ */
60
+ it('refuses the write that tips the merged plan over capacity', async () => {
61
+ // Ada took the lemonade to 70: 70 + 20 + 10 is 100, and lands.
62
+ expect(await verdict({ lemonade: 70 })).toEqual({ ok: true });
63
+
64
+ // Grace, at the same moment, takes the cookies to 60. Her screen showed
65
+ // the lemonade at 40, so 40 + 20 + 60 looked fine to her. It merges onto
66
+ // Ada's write, and 70 + 20 + 60 does not fit in the stall.
67
+ const result = await verdict({ cookies: 60 }, { previous: { lemonade: 70 } });
68
+
69
+ expect(result.ok).toBe(false);
70
+ expect(result).toHaveProperty('message', expect.stringContaining('asks for 150'));
71
+ expect(result).toHaveProperty(
72
+ 'message',
73
+ expect.stringContaining('at the same time as you')
74
+ );
75
+ });
76
+
77
+ it('refuses a fraction of a cup', async () => {
78
+ const result = await verdict({ lemonade: 40.5 });
79
+
80
+ expect(result.ok).toBe(false);
81
+ expect(result).toHaveProperty('message', expect.stringContaining('Lemonade'));
82
+ });
83
+
84
+ it('refuses a negative number', async () => {
85
+ const result = await verdict({ lemonade: -1 });
86
+
87
+ expect(result.ok).toBe(false);
88
+ });
89
+
90
+ it('refuses something that is not on the menu', async () => {
91
+ const result = await verdict({ brownies: 10 });
92
+
93
+ expect(result.ok).toBe(false);
94
+ expect(result).toHaveProperty('message', expect.stringContaining('no brownies'));
95
+ });
96
+ });
@@ -0,0 +1,45 @@
1
+ import type { ValidatorFunction } from '../types';
2
+
3
+ /**
4
+ * The gate on every change a surface makes to the day's plan.
5
+ *
6
+ * This is the case a schema shape cannot fix, and the reason validators exist.
7
+ *
8
+ * Each person looks after one thing on the menu, so two people changing two
9
+ * different things write two different keys and the host's merge keeps both.
10
+ * That is the design working. But the stall can only make so much in a day, and
11
+ * the cap is on the *total*: Ada can raise the lemonade to 70 and Grace can
12
+ * raise the cookies to 60 at the same moment, each of them looking at a screen
13
+ * where their own change fits, and the merged plan asks the stall for 130.
14
+ *
15
+ * Neither write is wrong on its own, and no amount of keying state differently
16
+ * makes them compatible. Only something looking at the merged result can tell,
17
+ * which is exactly what `next` is. The second write is refused with a message
18
+ * saying what happened, instead of quietly committing a plan nobody chose.
19
+ */
20
+ export const UpdateData: ValidatorFunction = async ({ next, settings }) => {
21
+ const { Capacity, Menu } = settings.menu;
22
+
23
+ let total = 0;
24
+ for (const [id, count] of Object.entries(next.plan.Make)) {
25
+ if (!Menu[id]) {
26
+ return { ok: false, message: `There is no ${id} on the menu.` };
27
+ }
28
+ if (!Number.isInteger(count) || count < 0) {
29
+ return {
30
+ ok: false,
31
+ message: `You cannot make ${count} ${Menu[id].Name}.`,
32
+ };
33
+ }
34
+ total += count;
35
+ }
36
+
37
+ if (total > Capacity) {
38
+ return {
39
+ ok: false,
40
+ message: `The stall can make ${Capacity} things in a day, and that plan asks for ${total}. Somebody may have changed something at the same time as you.`,
41
+ };
42
+ }
43
+
44
+ return { ok: true };
45
+ };
@@ -0,0 +1,55 @@
1
+ // This file is auto-generated from the validator's capability definitions.
2
+ // Do not edit this file directly. It will be regenerated on build.
3
+
4
+ export interface Context {
5
+ plan: {
6
+ /**
7
+ * How many of each menu item to make today, keyed by item id. Keyed rather than a flat set of fields so that two people changing two different items write different keys, and the host's merge keeps both.
8
+ */
9
+ Make: {
10
+ [k: string]: number;
11
+ };
12
+ };
13
+ }
14
+
15
+ export interface Settings {
16
+ menu: {
17
+ /**
18
+ * How many items the stall can make in a day, across the whole menu
19
+ */
20
+ Capacity: number;
21
+ Menu: Menu;
22
+ };
23
+ }
24
+ /**
25
+ * What the stall sells, keyed by item id. Money is in pence, so the sums stay in whole numbers. Read by the engine and every surface, so the price on screen and the price in the sums are the same number.
26
+ */
27
+ export interface Menu {
28
+ [k: string]: MenuItem;
29
+ }
30
+ export interface MenuItem {
31
+ /**
32
+ * What the item is called on every screen
33
+ */
34
+ Name: string;
35
+ /**
36
+ * Where it sits on the menu, so every screen lists it in the same order. 1 comes first
37
+ */
38
+ Order: number;
39
+ /**
40
+ * Cost to make one, in pence
41
+ */
42
+ Cost: number;
43
+ /**
44
+ * Sale price, in pence
45
+ */
46
+ Price: number;
47
+ }
48
+
49
+ import type {
50
+ RequestTickFunction as SDKRequestTickFunction,
51
+ ValidatorFunction as SDKValidatorFunction,
52
+ } from '@seriousgaming/sdk';
53
+
54
+ export type ValidatorFunction = SDKValidatorFunction<Context, Settings>;
55
+ export type RequestTickFunction = SDKRequestTickFunction<Context, Settings>;
@@ -0,0 +1,11 @@
1
+ {
2
+ "definition": {
3
+ "reads": ["plan"],
4
+ "settings": ["menu"]
5
+ },
6
+ "logic": {
7
+ "directory": "logic",
8
+ "entrypoint": "logic.ts"
9
+ },
10
+ "rootDirectory": "."
11
+ }
@@ -0,0 +1,19 @@
1
+ import { defineConfig } from 'vite';
2
+
3
+ export default defineConfig({
4
+ resolve: {
5
+ // One copy of each package that holds React context, however many
6
+ // paths lead to it. A second copy brings contexts of its own, so a
7
+ // hook reads empty data: React's "Invalid hook call" when MUI bundles
8
+ // its own React, or an SDK hook in a shared package of yours that
9
+ // finds none of the providers the host set up.
10
+ dedupe: [
11
+ 'react',
12
+ 'react-dom',
13
+ '@emotion/react',
14
+ '@emotion/styled',
15
+ '@seriousgaming/sdk',
16
+ '@seriousgaming/deck',
17
+ ],
18
+ },
19
+ });
@@ -0,0 +1,15 @@
1
+ import { defineConfig } from 'vitest/config';
2
+
3
+ export default defineConfig({
4
+ resolve: {
5
+ // Ensure a single React instance is used across the project and
6
+ // file:// SDK dependency, preventing "Invalid hook call" errors.
7
+ dedupe: ['react', 'react-dom'],
8
+ },
9
+ test: {
10
+ environment: 'jsdom',
11
+ setupFiles: ['./test-setup.ts'],
12
+ // Exclude engine tests (node env, separate config) and Playwright specs
13
+ exclude: ['testing/**', '**/node_modules/**'],
14
+ },
15
+ });
@@ -0,0 +1,19 @@
1
+ import { fileURLToPath } from 'url';
2
+
3
+ import { defineConfig } from 'vitest/config';
4
+
5
+ export default defineConfig({
6
+ resolve: {
7
+ alias: {
8
+ // Point the client subpath to source in development (dist doesn't exist until built)
9
+ '@seriousgaming/sdk-tools/client': fileURLToPath(
10
+ new URL('../../sdk-tools/cli/client/index.ts', import.meta.url)
11
+ ),
12
+ },
13
+ },
14
+ test: {
15
+ environment: 'node',
16
+ testTimeout: 60_000,
17
+ include: ['testing/engine/**/*.engine.test.ts'],
18
+ },
19
+ });
@@ -0,0 +1,40 @@
1
+ // This file is auto-generated from the schemas the resource declares: the values
2
+ // a session starts with, for use as test fixtures.
3
+ // Do not edit this file directly. It will be regenerated on build.
4
+
5
+ import type { Context, Settings } from './types';
6
+
7
+ export const defaultContext: Context = {
8
+ roles: {
9
+ LooksAfter: {},
10
+ },
11
+ briefing: {
12
+ Message: '',
13
+ },
14
+ };
15
+
16
+ export const defaultSettings: Settings = {
17
+ menu: {
18
+ Capacity: 120,
19
+ Menu: {
20
+ lemonade: {
21
+ Name: 'Lemonade',
22
+ Order: 1,
23
+ Cost: 15,
24
+ Price: 50,
25
+ },
26
+ icedtea: {
27
+ Name: 'Iced tea',
28
+ Order: 2,
29
+ Cost: 20,
30
+ Price: 60,
31
+ },
32
+ cookies: {
33
+ Name: 'Cookies',
34
+ Order: 3,
35
+ Cost: 25,
36
+ Price: 70,
37
+ },
38
+ },
39
+ },
40
+ };
@@ -0,0 +1,12 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Lemonade Stand</title>
7
+ </head>
8
+ <body>
9
+ <div id="root"></div>
10
+ <script type="module" src="./src/main.tsx"></script>
11
+ </body>
12
+ </html>