@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,238 @@
1
+ {
2
+ "$schema": "./node_modules/oxlint/configuration_schema.json",
3
+ "plugins": null,
4
+ "categories": {},
5
+ "rules": {
6
+ "typescript/no-explicit-any": "error",
7
+ "typescript/no-non-null-assertion": "error"
8
+ },
9
+ "settings": {
10
+ "jsx-a11y": {
11
+ "polymorphicPropName": null,
12
+ "components": {},
13
+ "attributes": {}
14
+ },
15
+ "next": {
16
+ "rootDir": []
17
+ },
18
+ "react": {
19
+ "formComponents": [],
20
+ "linkComponents": [],
21
+ "version": null,
22
+ "componentWrapperFunctions": []
23
+ },
24
+ "jsdoc": {
25
+ "ignorePrivate": false,
26
+ "ignoreInternal": false,
27
+ "ignoreReplacesDocs": true,
28
+ "overrideReplacesDocs": true,
29
+ "augmentsExtendsReplacesDocs": false,
30
+ "implementsReplacesDocs": false,
31
+ "exemptDestructuredRootsFromChecks": false,
32
+ "tagNamePreference": {}
33
+ },
34
+ "vitest": {
35
+ "typecheck": false
36
+ }
37
+ },
38
+ "env": {
39
+ "builtin": true
40
+ },
41
+ "globals": {},
42
+ "ignorePatterns": ["**/types.ts"],
43
+ "overrides": [
44
+ {
45
+ "files": [
46
+ "engine/**/*.ts",
47
+ "tick_controller/**/*.ts",
48
+ "**/hooks/*/logic/**/*.ts",
49
+ "**/validators/*/logic/**/*.ts",
50
+ "**/endpoints/*/logic/**/*.ts"
51
+ ],
52
+ "rules": {
53
+ "no-restricted-globals": [
54
+ "error",
55
+ {
56
+ "name": "structuredClone",
57
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics. Context is JSON-serialisable, so JSON.parse(JSON.stringify(value)) is the portable equivalent."
58
+ },
59
+ {
60
+ "name": "TextEncoder",
61
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics. Import encodeUtf8 from @seriousgaming/sdk instead."
62
+ },
63
+ {
64
+ "name": "TextDecoder",
65
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics. Import decodeUtf8 from @seriousgaming/sdk instead."
66
+ },
67
+ {
68
+ "name": "fetch",
69
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics. Reach external services through the injected callbacks, or through an endpoint."
70
+ },
71
+ {
72
+ "name": "XMLHttpRequest",
73
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics. Reach external services through the injected callbacks, or through an endpoint."
74
+ },
75
+ {
76
+ "name": "setTimeout",
77
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics. Ticks are the scheduling primitive: logic must run to completion within one tick."
78
+ },
79
+ {
80
+ "name": "setInterval",
81
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics. Ticks are the scheduling primitive: logic must run to completion within one tick."
82
+ },
83
+ {
84
+ "name": "setImmediate",
85
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics. Ticks are the scheduling primitive: logic must run to completion within one tick."
86
+ },
87
+ {
88
+ "name": "queueMicrotask",
89
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics. Ticks are the scheduling primitive: logic must run to completion within one tick."
90
+ },
91
+ {
92
+ "name": "process",
93
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics. Settings reach logic through the `settings` argument."
94
+ },
95
+ {
96
+ "name": "Buffer",
97
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics. Use Uint8Array, with the SDK's encodeUtf8 / decodeUtf8 for string conversion."
98
+ },
99
+ {
100
+ "name": "URL",
101
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics. Build asset URLs from the references and callbacks the runtime injects."
102
+ },
103
+ {
104
+ "name": "clearTimeout",
105
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
106
+ },
107
+ {
108
+ "name": "clearInterval",
109
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
110
+ },
111
+ {
112
+ "name": "clearImmediate",
113
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
114
+ },
115
+ {
116
+ "name": "URLSearchParams",
117
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
118
+ },
119
+ {
120
+ "name": "crypto",
121
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
122
+ },
123
+ {
124
+ "name": "atob",
125
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
126
+ },
127
+ {
128
+ "name": "btoa",
129
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
130
+ },
131
+ {
132
+ "name": "performance",
133
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
134
+ },
135
+ {
136
+ "name": "ReadableStream",
137
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
138
+ },
139
+ {
140
+ "name": "WritableStream",
141
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
142
+ },
143
+ {
144
+ "name": "TransformStream",
145
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
146
+ },
147
+ {
148
+ "name": "Blob",
149
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
150
+ },
151
+ {
152
+ "name": "File",
153
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
154
+ },
155
+ {
156
+ "name": "FormData",
157
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
158
+ },
159
+ {
160
+ "name": "Headers",
161
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
162
+ },
163
+ {
164
+ "name": "Request",
165
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
166
+ },
167
+ {
168
+ "name": "Response",
169
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
170
+ },
171
+ {
172
+ "name": "AbortController",
173
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
174
+ },
175
+ {
176
+ "name": "EventTarget",
177
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
178
+ },
179
+ {
180
+ "name": "WebSocket",
181
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
182
+ },
183
+ {
184
+ "name": "localStorage",
185
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
186
+ },
187
+ {
188
+ "name": "sessionStorage",
189
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
190
+ },
191
+ {
192
+ "name": "window",
193
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
194
+ },
195
+ {
196
+ "name": "document",
197
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
198
+ },
199
+ {
200
+ "name": "navigator",
201
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
202
+ },
203
+ {
204
+ "name": "require",
205
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
206
+ },
207
+ {
208
+ "name": "__dirname",
209
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
210
+ },
211
+ {
212
+ "name": "__filename",
213
+ "message": "Not available in the production runtime, which is a bare V8 isolate exposing only the ECMAScript intrinsics."
214
+ }
215
+ ]
216
+ }
217
+ },
218
+ {
219
+ "files": ["**/*.test.ts", "**/*.spec.ts"],
220
+ "rules": {
221
+ "no-restricted-globals": "off"
222
+ }
223
+ },
224
+ {
225
+ "files": ["**/*.test.ts", "**/*.test.tsx", "**/*.spec.ts", "**/testing/**"],
226
+ "rules": {
227
+ "typescript/no-explicit-any": "off",
228
+ "typescript/no-non-null-assertion": "off"
229
+ }
230
+ },
231
+ {
232
+ "files": ["**/src/main.tsx"],
233
+ "rules": {
234
+ "typescript/no-non-null-assertion": "off"
235
+ }
236
+ }
237
+ ]
238
+ }
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "{{ identifier }}",
3
+ "version": "{{ version }}",
4
+ "description": "{{ name }}",
5
+ "license": "UNLICENSED",
6
+ "files": [
7
+ "dist"
8
+ ],
9
+ "type": "module",
10
+ "main": "index.js",
11
+ "scripts": {
12
+ "generate": "pnpm run sdk generate",
13
+ "build": "pnpm run sdk build",
14
+ "start": "pnpm run sdk dev",
15
+ "test": "vitest",
16
+ "test:run": "vitest run",
17
+ "test:coverage": "vitest run --coverage",
18
+ "test:engine": "vitest run --config vitest.engine.config.ts",
19
+ "test:e2e": "playwright test",
20
+ "lint": "oxlint --max-warnings=0",
21
+ "lint:fix": "oxlint --fix",
22
+ "format": "oxfmt",
23
+ "format:check": "oxfmt --check",
24
+ "typecheck": "tsc --noEmit",
25
+ "sdk": "seriousgaming-sdk"
26
+ },
27
+ "dependencies": {
28
+ "@emotion/cache": "^11.14.0",
29
+ "@emotion/react": "^11.14.0",
30
+ "@emotion/styled": "^11.14.1",
31
+ "@fontsource-variable/roboto-mono": "^5.3.0",
32
+ "@fontsource-variable/work-sans": "^5.3.0",
33
+ "@mui/icons-material": "^9.4.0",
34
+ "@mui/material": "^9.4.0",
35
+ "@mui/stylis-plugin-rtl": "^9.4.0",
36
+ "@seriousgaming/deck": "^{{ sdkVersion }}",
37
+ "i18next": "^26.4.2",
38
+ "react": "^19.3.0",
39
+ "react-dom": "^19.3.0",
40
+ "react-i18next": "^17.0.16",
41
+ "stylis": "^4.4.0",
42
+ "vite": "^8.3.4"
43
+ },
44
+ "devDependencies": {
45
+ "@playwright/test": "^1.64.0",
46
+ "@seriousgaming/sdk": "^{{ sdkVersion }}",
47
+ "@seriousgaming/sdk-tools": "^{{ sdkVersion }}",
48
+ "@testing-library/jest-dom": "^7.0.1",
49
+ "@testing-library/react": "^16.3.3",
50
+ "@testing-library/user-event": "^14.6.7",
51
+ "@types/node": "^24.19.1",
52
+ "@types/react": "^19.3.0",
53
+ "@types/react-dom": "^19.3.0",
54
+ "@types/stylis": "^4.2.7",
55
+ "jsdom": "^30.1.2",
56
+ "oxfmt": "^0.67.0",
57
+ "oxlint": "^1.87.0",
58
+ "typescript": "^6.0.3",
59
+ "vite-node": "^6.0.0",
60
+ "vitest": "^5.0.3"
61
+ },
62
+ "peerDependencies": {
63
+ "@seriousgaming/sdk": "^{{ sdkVersion }}"
64
+ }
65
+ }
@@ -0,0 +1,19 @@
1
+ import { defineConfig } from '@playwright/test';
2
+
3
+ export default defineConfig({
4
+ testDir: './testing/e2e',
5
+ // Starts an isolated dev server on free ports, beside any `sdk dev` you
6
+ // have running, and stops it when the run ends. It names the server in
7
+ // SERIOUSGAMING_DEV_URL, which the SDK's e2e helpers read.
8
+ globalSetup: './testing/e2e/global-setup.ts',
9
+ // One worker: these tests share a session, so a tick in one is visible to
10
+ // the next. Running them in parallel makes each test's starting state
11
+ // depend on what another happened to be doing.
12
+ workers: 1,
13
+ // A stray `test.only` passes locally and silently skips the rest on CI.
14
+ forbidOnly: !!process.env.CI,
15
+ use: {
16
+ // Read again in each worker, after the global setup has set it.
17
+ baseURL: process.env.SERIOUSGAMING_DEV_URL,
18
+ },
19
+ });
@@ -0,0 +1,27 @@
1
+ # A transitive dependency of the SDK packages whose parent pins it to a range
2
+ # that only reaches a version with a security advisory against it. Your package
3
+ # does not depend on it directly, and nothing you change in package.json moves
4
+ # it, so it is held here instead.
5
+ # - image-size: @seriousgaming/deck reaches it through pptxgenjs, which asks for
6
+ # ^1.2.1, and no 1.x is patched against the parser loops in
7
+ # GHSA-5p2g-fcmc-qvqq and GHSA-w3rx-r6r6-pgpr. pptxgenjs never loads it at
8
+ # run time, so the newer major is safe.
9
+ #
10
+ # Keep the list this short. Most flagged transitives resolve to a patched
11
+ # version on their own once you update, so run `pnpm audit` first and add an
12
+ # override only for what it still reports. Note that overrides belong in this
13
+ # file and not under a `pnpm` key in package.json: pnpm 11 no longer reads that
14
+ # key, and ignores what it finds there without warning you.
15
+ overrides:
16
+ image-size: '>=2.0.3'
17
+
18
+ # Which dependencies may run an install script. esbuild reaches your game
19
+ # through the SDK tooling, and its script has never run: the executable arrives
20
+ # in the @esbuild/<platform> optional dependency, and the script only re-checks
21
+ # that it matches. pnpm 11 onwards treats an undeclared install script as an
22
+ # error rather than a warning, so without this entry `pnpm install` stops with
23
+ # ERR_PNPM_IGNORED_BUILDS. Add your own entries here as you add dependencies
24
+ # that want to run scripts, and prefer `false` unless the package genuinely
25
+ # needs the script to work.
26
+ allowBuilds:
27
+ esbuild: false
@@ -0,0 +1,7 @@
1
+ import '@testing-library/jest-dom/vitest';
2
+ import { cleanup } from '@testing-library/react';
3
+ import { afterEach } from 'vitest';
4
+
5
+ // RTL does not auto-detect Vitest without globals mode enabled,
6
+ // so we explicitly clean up the DOM after each test.
7
+ afterEach(cleanup);
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "esnext",
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "esModuleInterop": true,
8
+ "noImplicitAny": true,
9
+ "sourceMap": true,
10
+ "outDir": "dist",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "jsx": "react-jsx"
14
+ }
15
+ }
@@ -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,25 @@
1
+ import { defineConfig } from 'vitest/config';
2
+
3
+ export default defineConfig({
4
+ resolve: {
5
+ // The same single copies vite.config.ts asks for, so a test renders
6
+ // with the providers the component reads.
7
+ dedupe: [
8
+ 'react',
9
+ 'react-dom',
10
+ '@emotion/react',
11
+ '@emotion/styled',
12
+ '@seriousgaming/sdk',
13
+ '@seriousgaming/deck',
14
+ ],
15
+ },
16
+ esbuild: {
17
+ jsx: 'automatic',
18
+ },
19
+ test: {
20
+ environment: 'jsdom',
21
+ setupFiles: ['./test-setup.ts'],
22
+ // Exclude engine tests (node env, separate config) and Playwright specs
23
+ exclude: ['testing/**', '**/node_modules/**'],
24
+ },
25
+ });
@@ -0,0 +1,12 @@
1
+ import { defineConfig } from 'vitest/config';
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ // Node environment — engine tests run the game engine in-process,
6
+ // no browser APIs needed.
7
+ environment: 'node',
8
+ // Allow long-running games (e.g. 100+ ticks with LLM calls).
9
+ testTimeout: 60_000,
10
+ include: ['testing/engine/**/*.engine.test.ts'],
11
+ },
12
+ });
@@ -0,0 +1,20 @@
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>{{ name }}</title>
7
+ <style>
8
+ html,
9
+ body,
10
+ #root {
11
+ height: 100%;
12
+ margin: 0;
13
+ }
14
+ </style>
15
+ </head>
16
+ <body>
17
+ <div id="root"></div>
18
+ <script type="module" src="./src/main.tsx"></script>
19
+ </body>
20
+ </html>
@@ -0,0 +1,49 @@
1
+ import { Deck, defaultBrand, type Brand } from '@seriousgaming/deck';
2
+ import { usePresentation } from '@seriousgaming/sdk/ui';
3
+ import { useEffect } from 'react';
4
+ import { useTranslation } from 'react-i18next';
5
+
6
+ import type { Settings, SharedContext, TeamContext } from '../types';
7
+ import { slides } from './Slides';
8
+
9
+ /*
10
+ A presentation is the facilitator's slide deck. It is read-only, and it renders
11
+ with or without a session: in a game's library, while rehearsing or to export
12
+ it beforehand, `session` is null, so every slide must make sense without
13
+ results.
14
+
15
+ The host's theme colours are mapped onto the deck's brand here, so the slides
16
+ pick up the same primary and secondary as every other surface.
17
+ */
18
+
19
+ export default function App() {
20
+ const { game, session, theme, locale } = usePresentation<Settings, TeamContext, SharedContext>();
21
+ const { t, i18n } = useTranslation();
22
+ const language = locale.locale.split('-')[0];
23
+
24
+ useEffect(() => {
25
+ void i18n.changeLanguage(language);
26
+ }, [i18n, language]);
27
+
28
+ const brand: Partial<Brand> = {
29
+ colors: {
30
+ ...defaultBrand.colors,
31
+ primary: theme.light.primary,
32
+ secondary: theme.light.secondary,
33
+ },
34
+ };
35
+
36
+ return (
37
+ <Deck
38
+ brand={brand}
39
+ title={game.name}
40
+ dir={i18n.dir(language)}
41
+ lang={language}
42
+ // Come back to the same slide after a reload or a break. Each session
43
+ // keeps its own place; rehearsing without one has one of its own.
44
+ rememberAs={session ? `session:${session.id}` : `rehearsal:${game.name}`}
45
+ >
46
+ {slides({ game, session, t })}
47
+ </Deck>
48
+ );
49
+ }
@@ -0,0 +1,81 @@
1
+ {% raw %}import {
2
+ Bullets,
3
+ Heading,
4
+ Slide,
5
+ Table,
6
+ Text,
7
+ } from '@seriousgaming/deck';
8
+ import type { PresentationGame } from '@seriousgaming/sdk/ui';
9
+ import type { TFunction } from 'i18next';
10
+
11
+ import type { PresentationSession } from '../types';
12
+
13
+ const PADDING = '120px 140px';
14
+
15
+ /*
16
+ Every element in the returned array is one slide, so add a slide by adding an
17
+ element. Keep them in an array rather than wrapping them in a component of
18
+ your own: the deck counts its direct children, and a wrapper would be one
19
+ slide.
20
+
21
+ Every word goes through `t`, so the slides follow the session's language.
22
+ */
23
+ export function slides({
24
+ game,
25
+ session,
26
+ t,
27
+ }: {
28
+ game: PresentationGame;
29
+ session: PresentationSession | null;
30
+ t: TFunction;
31
+ }) {
32
+ return [
33
+ <Slide key="title" notes="Welcome everyone and introduce the session.">
34
+ <div
35
+ style={{
36
+ display: 'flex',
37
+ flexDirection: 'column',
38
+ justifyContent: 'center',
39
+ gap: 32,
40
+ height: '100%',
41
+ padding: PADDING,
42
+ boxSizing: 'border-box',
43
+ }}
44
+ >
45
+ <Heading level={1}>{game.name}</Heading>
46
+ {session && <Text variant="lead">{session.name}</Text>}
47
+ </div>
48
+ </Slide>,
49
+
50
+ <Slide key="agenda" transition="slide" notes="Reveal each point in turn.">
51
+ <div style={{ padding: PADDING }}>
52
+ <Heading>{t('agendaHeading')}</Heading>
53
+ <Bullets
54
+ stepped
55
+ style={{ marginTop: 60 }}
56
+ items={[t('agendaTeam'), t('agendaDecide'), t('agendaReview')]}
57
+ />
58
+ </div>
59
+ </Slide>,
60
+
61
+ <Slide key="results" transition="rise">
62
+ <div style={{ padding: PADDING }}>
63
+ <Heading>{t('resultsHeading')}</Heading>
64
+ <div style={{ marginTop: 60 }}>
65
+ {session ? (
66
+ <Table
67
+ columns={[t('resultsTeam'), t('resultsRound')]}
68
+ align={['start', 'end']}
69
+ rows={session.teams.map((team) => [
70
+ team.name,
71
+ session.data.teams[team.teamId]?.completedTicks ?? 0,
72
+ ])}
73
+ />
74
+ ) : (
75
+ <Text>{t('resultsPending')}</Text>
76
+ )}
77
+ </div>
78
+ </div>
79
+ </Slide>,
80
+ ];
81
+ }{% endraw %}
@@ -0,0 +1,54 @@
1
+ import i18n from 'i18next';
2
+ import { initReactI18next } from 'react-i18next';
3
+
4
+ // Every word on a slide comes from here, so the deck follows the session's
5
+ // language and exports in it.
6
+ const resources = {
7
+ en: {
8
+ translation: {
9
+ agendaHeading: 'Today',
10
+ agendaTeam: 'Meet your team',
11
+ agendaDecide: 'Make your decisions each round',
12
+ agendaReview: 'Review the results together',
13
+ resultsHeading: 'Results',
14
+ resultsTeam: 'Team',
15
+ resultsRound: 'Round',
16
+ resultsPending: 'Results appear here once the session has started',
17
+ },
18
+ },
19
+ it: {
20
+ translation: {
21
+ agendaHeading: 'Oggi',
22
+ agendaTeam: 'Conosci la tua squadra',
23
+ agendaDecide: 'Prendi le tue decisioni a ogni turno',
24
+ agendaReview: 'Esaminate insieme i risultati',
25
+ resultsHeading: 'Risultati',
26
+ resultsTeam: 'Squadra',
27
+ resultsRound: 'Turno',
28
+ resultsPending: 'I risultati compaiono qui quando la sessione è iniziata',
29
+ },
30
+ },
31
+ ar: {
32
+ translation: {
33
+ agendaHeading: 'اليوم',
34
+ agendaTeam: 'تعرّف على فريقك',
35
+ agendaDecide: 'اتخذ قراراتك في كل جولة',
36
+ agendaReview: 'راجعوا النتائج معًا',
37
+ resultsHeading: 'النتائج',
38
+ resultsTeam: 'الفريق',
39
+ resultsRound: 'الجولة',
40
+ resultsPending: 'تظهر النتائج هنا بعد بدء الجلسة',
41
+ },
42
+ },
43
+ };
44
+
45
+ i18n.use(initReactI18next).init({
46
+ resources,
47
+ lng: 'en',
48
+ fallbackLng: 'en',
49
+ interpolation: {
50
+ escapeValue: false, // React already escapes
51
+ },
52
+ });
53
+
54
+ export default i18n;
@@ -0,0 +1,14 @@
1
+ import { PresentationWrapper } from '@seriousgaming/sdk/ui';
2
+ import { StrictMode } from 'react';
3
+ import { createRoot } from 'react-dom/client';
4
+
5
+ import App from './App';
6
+ import './i18n';
7
+
8
+ createRoot(document.getElementById('root')!).render(
9
+ <StrictMode>
10
+ <PresentationWrapper>
11
+ <App />
12
+ </PresentationWrapper>
13
+ </StrictMode>
14
+ );