@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,233 @@
1
+ # Speech generation guide
2
+
3
+ The SDK exposes a provider-agnostic text-to-speech callback, `generateSpeech`. Engines, hooks, tick controllers, and endpoints can synthesise audio without knowing which provider executes the call. User interfaces reach it through an endpoint. The audio is persisted as a blob, so the same artefact can be played from a UI or analysed in an engine.
4
+
5
+ The dev server ships with one provider adapter (ElevenLabs). Additional providers (OpenAI, Google Cloud, Azure, AWS Polly) will land behind a future `TTS_PROVIDER` env var without breaking changes to game code.
6
+
7
+ ## Table of contents
8
+
9
+ - [Overview](#overview)
10
+ - [Configuration](#configuration)
11
+ - [Voice presets](#voice-presets)
12
+ - [Tiers](#tiers)
13
+ - [Using generateSpeech in the engine, hooks, and tick controllers](#using-generatespeech-in-the-engine-hooks-and-tick-controllers)
14
+ - [Using generateSpeech in user interfaces](#using-generatespeech-in-user-interfaces)
15
+ - [Request and response shape](#request-and-response-shape)
16
+ - [Limitations](#limitations)
17
+
18
+ ## Overview
19
+
20
+ `generateSpeech` accepts either a bare string or a request object, mirroring `generateText`:
21
+
22
+ ```typescript
23
+ await callbacks.generateSpeech('Welcome to the simulation.');
24
+ await callbacks.generateSpeech({ text: '...', voice: 'narrator' });
25
+ ```
26
+
27
+ It returns a `blob:<id>` asset reference in `reference`, a MIME type, and best-effort observability fields (`durationMs`, `charactersBilled`). Game code only ever passes role-based voice presets like `'narrator'` or `'announcer'`; the runtime maps each preset to a concrete provider voice.
28
+
29
+ The callback is exposed to the engine, hooks, tick controllers, and endpoints. Every such resource gates calls through the standard `uses` declaration, so the bundle must list `'generateSpeech'` in `uses`. User interfaces cannot call `generateSpeech` directly; they reach it through an endpoint that declares the callback and returns the audio blob reference.
30
+
31
+ ### Plain text only
32
+
33
+ `text` is read verbatim by the provider. Passing markdown (e.g. an LLM-generated report) causes the TTS engine to read out hashes, asterisks, and bullet characters. Strip the formatting first:
34
+
35
+ ```typescript
36
+ const audio = await callbacks.generateSpeech({
37
+ text: stripMarkdown(report.content),
38
+ voice: 'narrator',
39
+ });
40
+ ```
41
+
42
+ A small inline stripper covering headings, emphasis, lists, links, and code is enough for most cases:
43
+
44
+ ````typescript
45
+ export function stripMarkdown(input: string): string {
46
+ return input
47
+ .replace(/```[\s\S]*?```/g, '') // code fences
48
+ .replace(/^[ \t]*[-*_]{3,}[ \t]*$/gm, '') // horizontal rules
49
+ .replace(/^[ \t]{0,3}#{1,6}[ \t]+/gm, '') // heading markers
50
+ .replace(/^[ \t]{0,3}>[ \t]?/gm, '') // blockquote markers
51
+ .replace(/^[ \t]*[-*+][ \t]+/gm, '') // bullets
52
+ .replace(/^[ \t]*\d+\.[ \t]+/gm, '') // numbered items
53
+ .replace(/!\[([^\]]*)\]\([^)]*\)/g, '$1') // images, to their alt text
54
+ .replace(/\[([^\]]+)\]\([^)]*\)/g, '$1') // links, to their text
55
+ .replace(/(\*\*|__)(.*?)\1/g, '$2') // bold
56
+ .replace(/(\*|_)(.*?)\1/g, '$2') // italic
57
+ .replace(/`([^`]+)`/g, '$1') // inline code
58
+ .replace(/\n{3,}/g, '\n\n')
59
+ .trim();
60
+ }
61
+ ````
62
+
63
+ SSML and provider-specific markup are out of scope (see [Limitations](#limitations)).
64
+
65
+ ## Configuration
66
+
67
+ The dev server's v1 adapter is ElevenLabs. Operators configure it via environment variables. Models fall back along the tier chain (`expert` → `standard` → `quick`) and voice presets fall back to `neutral`, then to the provider's own default voice.
68
+
69
+ ```
70
+ ELEVENLABS_API_KEY=...
71
+ TTS_MODEL_QUICK=eleven_flash_v2_5 # Optional
72
+ TTS_MODEL_STANDARD=eleven_turbo_v2_5 # Optional, falls back to quick
73
+ TTS_MODEL_EXPERT=eleven_multilingual_v2 # Optional, falls back to standard
74
+ TTS_VOICE_NEUTRAL=<voice-id> # Optional, falls back to ElevenLabs default
75
+ TTS_VOICE_NARRATOR=<voice-id> # Optional, falls back to neutral
76
+ TTS_VOICE_ANNOUNCER=<voice-id> # Optional, falls back to neutral
77
+ TTS_VOICE_EXECUTIVE=<voice-id> # Optional, falls back to neutral
78
+ TTS_VOICE_COACH=<voice-id> # Optional, falls back to neutral
79
+ ```
80
+
81
+ Browse and copy voice IDs from <https://elevenlabs.io/voices>. Any voice ID accepted by ElevenLabs works.
82
+
83
+ Calling `generateSpeech` without `ELEVENLABS_API_KEY` set throws a `TtsClientError` with a configuration message. This matches the fail-at-call-time behaviour of `generateText`.
84
+
85
+ Production runtimes are free to resolve provider, model, and voice mappings however they like (config files, admin UI, per-tenant settings); the SDK contract is just the callback signature and the preset name convention.
86
+
87
+ ## Voice presets
88
+
89
+ The five recommended presets cover most simulation needs:
90
+
91
+ | Preset | Tone | Pace | Formality |
92
+ | ----------- | ---------------------------------- | -------------- | --------------- |
93
+ | `neutral` | Warm, balanced, unobtrusive | Medium | Mid |
94
+ | `narrator` | Engaging, gravitas, draws listener | Measured | Mid-formal |
95
+ | `announcer` | Clear, authoritative, broadcast | Crisp | Formal |
96
+ | `executive` | Confident, weighty, commands focus | Measured | Formal |
97
+ | `coach` | Encouraging, warm, reassuring | Conversational | Informal to mid |
98
+
99
+ Games may pass any preset name; unknown presets fall back to `neutral`. Operators free-text-map each preset to a concrete provider voice through the env vars above.
100
+
101
+ ## Tiers
102
+
103
+ `tier` works the same way it does for `generateText`. The default is `'quick'`. The runtime maps each tier to a provider model; missing tiers fall back toward `quick`.
104
+
105
+ ```typescript
106
+ await callbacks.generateSpeech({ text: '...', tier: 'standard' });
107
+ await callbacks.generateSpeech({ text: '...', tier: 'expert' });
108
+ ```
109
+
110
+ For ElevenLabs, the defaults are `eleven_flash_v2_5` (quick), `eleven_turbo_v2_5` (standard), and `eleven_multilingual_v2` (expert).
111
+
112
+ ## Using generateSpeech in the engine, hooks, and tick controllers
113
+
114
+ 1. Declare the API in the resource's bundle:
115
+
116
+ ```json
117
+ {
118
+ "definition": {
119
+ "reads": ["briefing"],
120
+ "writes": ["briefing"],
121
+ "uses": ["generateSpeech"]
122
+ },
123
+ "logic": { "directory": "logic", "entrypoint": "logic.ts" },
124
+ "rootDirectory": "."
125
+ }
126
+ ```
127
+
128
+ 2. Run `pnpm run sdk generate` so the per-resource `types.ts` narrows the `Callbacks` alias.
129
+ 3. Call the callback from `Init` or `Run`:
130
+
131
+ ```typescript
132
+ import type { RunFunction } from '@seriousgaming/sdk';
133
+ import type { Context, Settings, Callbacks } from '../types';
134
+
135
+ export const Run: RunFunction<Context, Settings, Callbacks> = async ({
136
+ context,
137
+ callbacks,
138
+ }) => {
139
+ // Declared in `uses`, so present: a runtime without speech refuses the
140
+ // package at load rather than leaving this undefined.
141
+ const audio = await callbacks.generateSpeech({
142
+ text: 'Welcome to round two. Let us begin.',
143
+ voice: 'narrator',
144
+ tier: 'standard',
145
+ });
146
+ return {
147
+ capabilities: {
148
+ ...context,
149
+ briefing: {
150
+ ...context.briefing,
151
+ audioRef: audio.reference,
152
+ },
153
+ },
154
+ };
155
+ };
156
+ ```
157
+
158
+ A UI reading `audioRef` can play the audio with `<audio src={callbacks.getAssetUrl(audioRef)} controls />`. See [Asset references](./file-handling.md#asset-references) for the full scheme.
159
+
160
+ ## Using generateSpeech in user interfaces
161
+
162
+ User interfaces cannot call `generateSpeech` directly. Declare an [endpoint](../recipes/create-endpoint.md) that wraps the callback and returns the blob reference, then invoke it from the UI and resolve the reference with `getAssetUrl`.
163
+
164
+ The endpoint bundle declares `'generateSpeech'` in its `uses`:
165
+
166
+ ```typescript
167
+ // endpoints/narrate/logic/logic.ts
168
+ import type { Handler } from '../types';
169
+
170
+ export const Handle: Handler = async ({ request, callbacks }) => {
171
+ const audio = await callbacks.generateSpeech({
172
+ text: request.text,
173
+ voice: 'announcer',
174
+ });
175
+ return { audioRef: audio.reference };
176
+ };
177
+ ```
178
+
179
+ The UI declares the endpoint in its `endpoints` array, calls it, and plays the returned blob:
180
+
181
+ ```tsx
182
+ const { getAssetUrl, endpoints } = useUserInterfaceCallbacks() as Callbacks;
183
+ const [audioUrl, setAudioUrl] = useState<string | undefined>();
184
+
185
+ const handleNarrate = async () => {
186
+ const { audioRef } = await endpoints['narrate']({ text: 'Time is up.' });
187
+ setAudioUrl(getAssetUrl(audioRef));
188
+ };
189
+
190
+ return audioUrl ? <audio src={audioUrl} autoPlay /> : <button onClick={handleNarrate}>Play</button>;
191
+ ```
192
+
193
+ `getAssetUrl` stays available to UIs: it is runtime plumbing and is not gated by `uses`. See [Call an endpoint from a UI](../recipes/call-endpoint-from-ui.md).
194
+
195
+ ## Request and response shape
196
+
197
+ ```typescript
198
+ type GenerateSpeechRequest = {
199
+ text: string;
200
+ voice?: string; // preset name; defaults to 'neutral'
201
+ tier?: 'quick' | 'standard' | 'expert'; // matches generateText
202
+ format?: 'mp3' | 'wav' | 'opus'; // default 'mp3'
203
+ languageHint?: string; // BCP-47, advisory
204
+ speed?: number; // 0.5 to 2.0, clamped per provider
205
+ };
206
+
207
+ type GenerateSpeechResponse = {
208
+ reference: string; // 'blob:abc123'; resolve via getAssetUrl or readAsset
209
+ mimeType: string; // e.g. 'audio/mpeg'
210
+ durationMs?: number; // best-effort
211
+ charactersBilled?: number; // observability
212
+ };
213
+ ```
214
+
215
+ ## Limitations
216
+
217
+ v1 is intentionally minimal so the API stays stable as providers come and go. The following are deliberately out of scope and may land later as non-breaking additions:
218
+
219
+ - SSML and provider-specific markup
220
+ - Style and emotion tags
221
+ - Pitch and volume gain
222
+ - Deterministic seed
223
+ - Sample-rate control
224
+ - Streaming responses
225
+ - Multi-voice dialogue input
226
+
227
+ ## Related
228
+
229
+ - [Declare the APIs a resource uses](./llm-integration.md#declare-the-apis-a-resource-uses) - the safety boundary mental model
230
+ - [Declare API uses](../recipes/declare-api-uses.md) - step-by-step declaration recipe
231
+ - [LLM integration](llm-integration.md) - the companion `generateText` callback
232
+ - [File handling](file-handling.md) - the unified `asset:` / `blob:` scheme for files
233
+ - [Environment variables](../environment-variables.md) - full env-var reference
@@ -0,0 +1,164 @@
1
+ # A tour of the starter game
2
+
3
+ `new package` hands you Lemonade Stand, a complete game rather than an empty shell. This page walks through every directory and file it writes, says what each one does, and points at the guide that goes deeper.
4
+
5
+ **Keywords:** starter game, lemonade stand, package layout, directory structure, scaffold, tour, what new package creates
6
+
7
+ The game is the one the SDK's own test suites play, copied out whole. A team runs a lemonade stand for 10 days: each morning they choose how many lemonades, iced teas, and cookies to make, and the engine plays out the day against the weather. For how to play it and make a first change, see [Getting started](../getting-started.md).
8
+
9
+ ## The shape worth keeping
10
+
11
+ Most of the starter game is ordinary, but four decisions in it are the ones a first game usually gets wrong. Keep them when you replace the model:
12
+
13
+ - **State keyed so participants cannot overwrite each other.** `plan.Make` is keyed by menu item, and a hook puts each participant in charge of one item, so two people changing two numbers write two different keys
14
+ - **A validator on the one thing they share.** Two changes can each fit while the merged plan busts the stall's capacity. No shape of state prevents that, so `validators/capacity` checks the merged result
15
+ - **Every write awaited.** The game UI reports a refused write to the participant who made it, instead of showing a decision the game never received
16
+ - **Teams run their own days.** The game is in independent mode: each team opens its stall when it is ready, and the facilitator watches and can undo
17
+
18
+ [Design state for concurrent writes](../recipes/design-state-for-concurrent-writes.md) explains the first two in full.
19
+
20
+ ## The manifest
21
+
22
+ ### `seriousgaming.sdk.json`
23
+
24
+ The game itself, as one flat object: the package identifier, the locales and the game's name, `maxTicks: 10`, the team rules, the waiting room setting, and the scenario format. The game's own values are the defaults of its settings resources, not overrides here.
25
+
26
+ - `teams.mode: "independent"` with one to eight teams of two to five participants
27
+ - `waitingRoom.openOnStart: true`, so participants are held in the waiting room until the facilitator lets them in
28
+ - `scenarioFormat: 1`, and no `customScenarios`, so a hosted runtime offers only the game's own scenarios. Facilitators saving scenarios of their own is a decision to make deliberately: add `customScenarios: { "supported": true }` when you want it, and bump `scenarioFormat` when a release changes what a setting means (see [Scenario format: when to bump it](./scenarios.md#scenario-format-when-to-bump-it)). The game has no scenario editor, so a runtime's generic form, or an AI agent, would author them from the settings schemas
29
+
30
+ See [Shaping games](./games.md).
31
+
32
+ ## Capabilities
33
+
34
+ ### `capabilities/`
35
+
36
+ Each directory is one capability, a named slice of the game's state with a JSON Schema for its variables. There is no logic here.
37
+
38
+ | Capability | Holds |
39
+ | ---------- | --------------------------------------------------------------------------------------------------------------------- |
40
+ | `plan` | How many of each item to make today, keyed by item. The one capability participants write |
41
+ | `weather` | Today's forecast and roughly how many people will want each item |
42
+ | `results` | What happened yesterday, item by item, and the money: takings, spending, profit, and the running total in the jar |
43
+ | `roles` | Which item each participant looks after, keyed by participant id |
44
+ | `briefing` | A note from the facilitator shown on every team's screen. `shared` scope, so there is one value for the whole session |
45
+
46
+ See [Capabilities](./capabilities.md).
47
+
48
+ ## Settings
49
+
50
+ ### `settings/`
51
+
52
+ Each directory is one settings resource: read-only parameters, every one with a default, which a scenario or the facilitator can override before play starts. A resource reads the ones it lists in its own `settings`. Every property has a `title`, a `description` with its units, a range, and an `enum` where the choices are closed (`CurrencySymbol`), because those schemas are all a scenario author without an editor has to go on.
53
+
54
+ | Settings | Holds | Read by |
55
+ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
56
+ | `menu` | `Capacity` (120) and the `Menu`, each item's name, cost, and price | The engine, every surface, the hook, and the validator |
57
+ | `engine` | `UsualDemand` for each item, `SunnyPull`, `RainyPull`, and `Variation`. Only the engine reads it, so no participant's browser ever holds the demand | The engine |
58
+ | `ui` | `Step` and `CurrencySymbol` | The game UI |
59
+ | `session` | `ShowJoinLinks` and `CurrencySymbol` | The session UI |
60
+
61
+ See [Settings](./settings.md).
62
+
63
+ ## Logic
64
+
65
+ ### `engine/`
66
+
67
+ The one engine, which plays a day each tick.
68
+
69
+ - `engine.sdk.json`: what the engine reads and writes, and `"settings": ["menu", "engine"]`, the settings it plays with
70
+ - `logic.ts`: `Init` sets a provisional plan and forecasts day one; `Run` plays the day, charges for everything made, and forecasts tomorrow. Weather and demand are derived from the session seed, so a day always plays out the same way
71
+ - `logic.test.ts`: unit tests for one day's arithmetic
72
+ - `test-helpers.ts`: starting fixtures the tests spread over
73
+ - `types.ts` and `defaults.ts`: generated from the schemas. Do not edit them; `sdk generate`, `new`, and `update` rewrite them
74
+
75
+ See [Creating engines](./engine.md) and [Testing](./testing.md).
76
+
77
+ ### `hooks/assignproducts/`
78
+
79
+ A hook on the `participantJoin` signal. When a participant joins a team, it reads the `menu` settings and writes into `roles` which menu item they look after, so participants normally change different keys. Its logic is in `logic/logic.ts`, with tests beside it.
80
+
81
+ See [Hooks](./hooks.md).
82
+
83
+ ### `validators/capacity/`
84
+
85
+ A validator that sees every change a UI makes to the plan before it is applied. It reads the `menu` settings, and refuses a plan that asks for more than the stall's capacity, a negative or fractional count, or an item not on the menu. It never changes state; it only says no, with a message the game UI shows.
86
+
87
+ See [Validators](./validators.md).
88
+
89
+ ## User interfaces
90
+
91
+ Each is a small React app built with Vite and MUI, with its own `index.html`, `src/main.tsx` (the SDK wrapper, locale, and right-to-left set-up), `src/theme.ts` (typography over the host's palette), and `src/i18n.ts` (every string on the screen).
92
+
93
+ ### `ui/`
94
+
95
+ The game UI: what each participant sees.
96
+
97
+ - `src/App.tsx`: the layout, the facilitator's notice, and the one place a refused write is reported
98
+ - `src/TodayPanel.tsx` and `src/MakeRow.tsx`: the controls for today's plan, one row per item, with the participant's own item marked
99
+ - `src/DayBar.tsx`: the **Open the stall** button, which calls `requestTick` to play the team's day
100
+ - `src/YesterdayPanel.tsx` and `src/HistoryPanel.tsx`: how yesterday went, and every day so far. The history table asks the host for the earlier days with `getPastState` and adds today's from live context, so nothing in context grows as the days go by (see [Review a past day in a UI](../recipes/review-a-past-day.md))
101
+ - `src/writes.ts`: one mutation reporter every write goes through
102
+ - `src/menu.ts`, `src/format.ts`, `src/Section.tsx`, `src/ThemeToggle.tsx`: menu ordering, money formatting, the card layout, and a light or dark switch
103
+ - `ui.sdk.json`: reads every capability it shows, writes only `plan`, and reads the `ui` settings (`Step` and `CurrencySymbol`)
104
+
105
+ See [Building user interfaces](./ui.md).
106
+
107
+ ### `session/`
108
+
109
+ The session UI: the facilitator's whole screen, which the dev server shows at `/` as the console. It shows what each stall is making and whether anyone has changed it today, links into any stall to observe or join it (`src/TeamDoor.tsx`), writes the shared `briefing`, and toggles the waiting room and the facilitator guide through the host. `ShowJoinLinks`, in the `session` settings it reads, turns the per-team join and observe links off.
110
+
111
+ See [Building session UIs](./session.md).
112
+
113
+ ### `waiting_room/`
114
+
115
+ The screen participants see while the session is held. It tells a held start ('Nearly opening time') from a pause part-way through, shows who is on the team, and lets the team name its stall.
116
+
117
+ See [Building waiting room UIs](./waiting-room.md).
118
+
119
+ ## Content
120
+
121
+ ### `scenarios/`
122
+
123
+ Two variants of the game, each a `scenario.sdk.json`:
124
+
125
+ - `ordinary_week`: 10 days of mixed weather, marked `default`, so a session starts on it
126
+ - `heatwave`: five days with the `engine` settings' `SunnyPull` and `RainyPull` raised, so the queue is longer than the stall can serve
127
+
128
+ See [Scenarios](./scenarios.md).
129
+
130
+ ### `guide/`
131
+
132
+ The facilitator guide: three markdown chapters under `content/en/` (at a glance, preparation, running the day), rendered on the facilitator's page. `guide.test.ts` checks the structure the host relies on.
133
+
134
+ See [Facilitator guides](./guide.md).
135
+
136
+ ## Tests
137
+
138
+ ### `testing/engine/`
139
+
140
+ Whole-game tests that play several days in-process with `createTestSession`: no server, no browser. Run them with `pnpm test:engine`. See [Engine testing](./engine-testing.md).
141
+
142
+ ### `testing/e2e/`
143
+
144
+ Playwright tests against a real dev server, which `testing/e2e/global-setup.ts` starts on free ports, beside any you have running. Run them with `pnpm test:e2e`. See [Test UIs end to end with Playwright](../recipes/e2e-testing.md).
145
+
146
+ The unit and component tests sit beside the code they test (`*.test.ts`, `*.test.tsx`) and run with `pnpm test:run`.
147
+
148
+ ## Package files
149
+
150
+ These are written by `new package` for every package, starter game or not:
151
+
152
+ | File | What it is for |
153
+ | ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
154
+ | `package.json` | Dependencies, and the scripts: `sdk`, `generate`, `build`, `test:run`, `test:engine`, `test:e2e`, `typecheck`, `lint` |
155
+ | `tsconfig.json`, `globals.d.ts` | TypeScript settings, and declarations for the font imports |
156
+ | `vite.config.ts`, `vitest.config.ts`, `test-setup.ts` | Build and component-test settings, including the single copy of React and the SDK every UI needs |
157
+ | `vitest.engine.config.ts`, `playwright.config.ts` | Settings for the whole-game and browser test suites, and `testing/e2e/global-setup.ts`, which starts the browser suite's server |
158
+ | `pnpm-workspace.yaml` | Dependency overrides and install-script decisions the SDK tooling needs |
159
+ | `.oxlintrc.json`, `.oxfmtrc.json` | Lint and format settings |
160
+ | `README.md`, `DESIGN.md` | A readme, and prompts for writing down your game's design as you build it |
161
+ | `CLAUDE.md`, `.claude/` | Guidance and permissions for an AI coding agent working in the package |
162
+ | `.gitignore` | Keeps `dist/`, `node_modules/`, `.seriousgaming-sdk/`, and Playwright's `test-results/` and `playwright-report/` out of version control |
163
+
164
+ Two directories appear once you use the package. `dist/` is what `sdk build` writes. `.seriousgaming-sdk/` holds the dev server's lock file (`session.json`) and the session overrides `sdk configure` writes (`configuration.json`); the session itself lives only in the dev server's memory.