@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,460 @@
1
+ # Capabilities
2
+
3
+ Capabilities hold your game's state. This guide explains the state model, who sees and writes each capability, and how long its values last, then covers creating capabilities and every kind of variable they hold.
4
+
5
+ ## The state model
6
+
7
+ A capability is a named collection of related variables, declared by a schema. For example:
8
+
9
+ - `inventory` holds `Stock` and `Reorder`
10
+ - `sales` holds `Revenue` and `UnitsSold`
11
+ - `pricing` holds `Price` and `PricingStrategy`
12
+
13
+ Each capability declares its variables in a `variablesSchema`: a full JSON Schema 7 object whose properties are the variables, each with a type, a `default`, and any constraints. Every capability starts from those defaults, so its variables exist from the first tick for anything that declares it.
14
+
15
+ ### Context is scoped by capability
16
+
17
+ A team's state, the context, is one object keyed by capability identifier, each value holding that capability's variables:
18
+
19
+ ```typescript
20
+ {
21
+ inventory: { Stock: 100, Reorder: false },
22
+ sales: { Revenue: 5000, UnitsSold: 50 },
23
+ production: { Output: 75 },
24
+ }
25
+ ```
26
+
27
+ Logic reads a variable through its capability: `context.inventory.Stock`. Scoping variables under their capability prevents name clashes between capabilities and keeps related variables together, and it is what lets every resource declare, by identifier, exactly which slices of state it touches.
28
+
29
+ ### Immutable updates
30
+
31
+ Never assign to `context`. Build a new object with spreads and return what you write under `capabilities`:
32
+
33
+ ```typescript
34
+ // ❌ Don't
35
+ context.inventory.Stock = 50;
36
+
37
+ // ✅ Do
38
+ return {
39
+ capabilities: {
40
+ ...context,
41
+ inventory: {
42
+ ...context.inventory,
43
+ Stock: 50,
44
+ },
45
+ },
46
+ };
47
+ ```
48
+
49
+ The runtime folds the result into the context one level deep, and removes keys only through `deletes`. See [How a result folds into the context](./engine.md#how-a-result-folds-into-the-context).
50
+
51
+ ### How state moves through a tick
52
+
53
+ 1. **Initialisation**: every capability starts from its defaults, then the engine's `Init`, if it has one, sets up each team's starting state
54
+ 2. **Each tick**: the engine's `Run` plays the round, calling the simulation's steps in the order it writes them, each step's output becoming the next step's input
55
+ 3. **Between ticks**: surfaces, endpoints and hooks change the capabilities they declare in `writes`, and the next tick reads the result
56
+
57
+ See [Ordering the simulation](./engine.md#ordering-the-simulation).
58
+
59
+ ## Declaring reads and writes
60
+
61
+ Every resource that touches state declares the capabilities it reads and writes, by identifier:
62
+
63
+ ```json
64
+ {
65
+ "reads": ["inventory", "discounts"],
66
+ "writes": ["revenue"]
67
+ }
68
+ ```
69
+
70
+ - **`reads`**: the capabilities the resource consumes. Every declared capability is present from the first tick, holding its schema defaults until something writes it, so a read is never conditional. The build fails if an identifier names no capability in the package
71
+ - **`writes`**: the capabilities the resource produces values for, or removes keys from
72
+
73
+ ### A declaration is what gets delivered
74
+
75
+ A resource receives exactly the capabilities it declares, in `reads` or in `writes`, and nothing else.
76
+
77
+ On a user interface (game, session or waiting room) two things follow:
78
+
79
+ - A capability you forgot to declare is **absent** from `data`, not just undocumented. Your generated `Context` already says so, so TypeScript catches it before you run
80
+ - A capability you declare but never render is payload you pay for on every update, to every participant
81
+
82
+ Writes count because a screen that sets a value almost always shows it: a decisions panel writes `price` and displays the current price in the same field.
83
+
84
+ `writes` is also what a game or waiting room UI is allowed to change. The runtime refuses a `setData` naming a capability the UI only `reads`, or anything that is not a capability, as `denied`. A session UI's team writes are the facilitator's and are not held to it.
85
+
86
+ The engine, hooks, validators, tick controllers, and endpoints follow the same rule: their logic is handed exactly the capabilities in `reads` and `writes`. What a resource returns under `capabilities` is folded over the wider context as a patch, so a resource cannot drop a capability it was never shown. A result that changes a capability not in its `writes`, whether it only reads it or never declared it, fails the call, naming it; this holds an aggregate engine's `shared` slice and each `teams` entry too. A capability returned unchanged, as `{ ...context }` returns it, is not a change. A result removes a key by naming its path in `deletes`, and only under a capability in its `writes`: a delete under one it only reads fails the call.
87
+
88
+ ## Scope
89
+
90
+ A capability's `scope` controls who may write it and who may see it:
91
+
92
+ | Scope | Meaning |
93
+ | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
94
+ | `team` (default) | One value per team, delivered to that team's surfaces |
95
+ | `team-readable` | Each team writes only its own copy, but user interfaces on other teams can observe every team's value live (shared-state games only) |
96
+ | `shared` | One value for all teams, written by an aggregate engine, by the facilitator (a session UI that declares it in `writes`), or by a session-scoped endpoint |
97
+ | `private` | Per team like `team`, but never delivered to any user interface. For engine bookkeeping |
98
+
99
+ ```json
100
+ {
101
+ "definition": {
102
+ "scope": "team-readable",
103
+ "variablesSchema": { "...": "..." }
104
+ }
105
+ }
106
+ ```
107
+
108
+ See [Multi-team games](./multi-team-games.md) for the full rules and the `useUserInterfaceCrossTeamData` hook.
109
+
110
+ ### Private capabilities
111
+
112
+ Simulations accumulate state that exists only to get from one tick to the next: a serialised engine, a smoothing accumulator, a seed, a ledger the next tick consumes. Nothing on screen needs it, and under team scope all of it is sent to every screen on every update.
113
+
114
+ `scope: 'private'` says so out loud. A private capability reaches your engine, hooks, validators, tick controller, and endpoints exactly as a team-scoped one does, and reaches no interface at all. Declaring one on an interface fails the build, naming the interface and the capability.
115
+
116
+ ```json
117
+ {
118
+ "definition": {
119
+ "scope": "private",
120
+ "variablesSchema": {
121
+ "type": "object",
122
+ "properties": {
123
+ "PreviousProfit": { "type": "number", "default": 0 }
124
+ },
125
+ "required": ["PreviousProfit"],
126
+ "additionalProperties": false
127
+ }
128
+ }
129
+ }
130
+ ```
131
+
132
+ A `trend` capability like this one carries last tick's profit, so the engine's report can say whether things are improving, and no UI can read it.
133
+
134
+ Reach for it whenever a screen would have no reason to render the value. When nothing but the engine reads it either, the engine's own `state` is simpler still: no capability, no schema, typed by TypeScript (see [Keeping memory between ticks](./engine.md#keeping-memory-between-ticks)). It costs nothing to change your mind later: widening `private` to `team` is a one-word edit, where narrowing `team` to `private` means finding out which screens had come to depend on it.
135
+
136
+ ## Lifetime
137
+
138
+ Most state belongs to the round it was written in: undo a tick and it goes back, reset the session and it starts again from its defaults. Some state does not. That setup is complete, the round a facilitator has opened, the announcement on everyone's screen: undoing a mistaken tick should not wipe any of those.
139
+
140
+ Set `lifetime` to `session` for that kind of value:
141
+
142
+ ```json
143
+ {
144
+ "definition": {
145
+ "scope": "shared",
146
+ "lifetime": "session",
147
+ "variablesSchema": {
148
+ "type": "object",
149
+ "properties": {
150
+ "Message": { "type": "string", "default": "" }
151
+ },
152
+ "required": ["Message"],
153
+ "additionalProperties": false
154
+ }
155
+ }
156
+ }
157
+ ```
158
+
159
+ A session-lifetime value:
160
+
161
+ - **Is left alone by undo and reset.** Per team for a team-scoped capability, in the one store for a shared one
162
+ - **Is not part of any round.** `getPastState` never reports it, because a past round did not hold it
163
+ - **Starts from its defaults once,** when the session is created or a team is added
164
+ - **Is not the engine's.** The build refuses one in the engine's `reads` or `writes`. A tick has to be replayable from its snapshot, and a value that undo leaves alone would change under it. Surfaces, endpoints, hooks, validators and the tick controller use it as its `scope` allows
165
+
166
+ `lifetime` is independent of `scope`: `scope` says who sees a value, `lifetime` how long it lasts. The default, `tick`, keeps a value in each tick snapshot. The starter game makes its facilitator `briefing` session-lifetime, so an undo never takes a note back off the teams' screens.
167
+
168
+ ## Creating a capability
169
+
170
+ Create a capability with the CLI. The identifier becomes the directory name:
171
+
172
+ ```bash
173
+ pnpm run sdk new capability '{
174
+ "definition": {
175
+ "identifier": "inventory",
176
+ "variablesSchema": {
177
+ "type": "object",
178
+ "properties": {
179
+ "Stock": { "type": "number", "default": 100 }
180
+ },
181
+ "required": ["Stock"],
182
+ "additionalProperties": false
183
+ }
184
+ }
185
+ }'
186
+ ```
187
+
188
+ This writes `capabilities/inventory/capability.sdk.json`, a capability with one numeric variable that starts at 100. A capability directory may also hold TypeScript files its schema names through [`tsType`](#a-typescript-type-of-your-own), such as `capabilities/chathistory/message.ts`.
189
+
190
+ A capability can hold several variables of different types:
191
+
192
+ ```bash
193
+ pnpm run sdk new capability '{
194
+ "definition": {
195
+ "identifier": "warehouse",
196
+ "variablesSchema": {
197
+ "type": "object",
198
+ "properties": {
199
+ "CurrentStock": {
200
+ "type": "number",
201
+ "default": 500,
202
+ "minimum": 0,
203
+ "description": "Current stock level"
204
+ },
205
+ "LastRestockDate": {
206
+ "type": "string",
207
+ "default": "2024-01-01",
208
+ "description": "Date of last restock"
209
+ },
210
+ "IsOperating": {
211
+ "type": "boolean",
212
+ "default": true,
213
+ "description": "Whether warehouse is open"
214
+ }
215
+ },
216
+ "required": ["CurrentStock", "LastRestockDate", "IsOperating"],
217
+ "additionalProperties": false
218
+ }
219
+ }
220
+ }'
221
+ ```
222
+
223
+ Then list it in the `reads` or `writes` of each resource that uses it.
224
+
225
+ ### Defaults
226
+
227
+ A variable's `default` is its tick-0 value, so it must itself satisfy the subschema that declares it. `sdk build` fails on a default that does not, so an object default cannot carry an undeclared field under `additionalProperties: false`, and a value your logic only produces later (a status that starts as `'Unknown'`) still has to be admitted by the `enum`. See [Schema defaults](../cli-reference.md#schema-defaults).
228
+
229
+ A default seeds the value and nothing else: the generated type comes from the schema's `type`, `properties`, `items`, `enum` and `const`. See [Where a precise type comes from](./type-safety.md#where-a-precise-type-comes-from).
230
+
231
+ ## Variable types
232
+
233
+ ### Number
234
+
235
+ ```json
236
+ {
237
+ "StockLevel": {
238
+ "type": "number",
239
+ "default": 0,
240
+ "minimum": 0,
241
+ "maximum": 1000,
242
+ "description": "Current stock"
243
+ }
244
+ }
245
+ ```
246
+
247
+ ### String
248
+
249
+ ```json
250
+ {
251
+ "Status": {
252
+ "type": "string",
253
+ "default": "pending",
254
+ "description": "Current status"
255
+ }
256
+ }
257
+ ```
258
+
259
+ ### Boolean
260
+
261
+ ```json
262
+ {
263
+ "IsActive": {
264
+ "type": "boolean",
265
+ "default": true,
266
+ "description": "Is capability active"
267
+ }
268
+ }
269
+ ```
270
+
271
+ ### Object
272
+
273
+ ```json
274
+ {
275
+ "Preferences": {
276
+ "type": "object",
277
+ "properties": {
278
+ "Theme": { "type": "string" }
279
+ },
280
+ "required": ["Theme"],
281
+ "additionalProperties": false,
282
+ "default": {
283
+ "Theme": "light"
284
+ },
285
+ "description": "Preferences object"
286
+ }
287
+ }
288
+ ```
289
+
290
+ Declare the object's `properties`: an object with only a `default` generates `{ [k: string]: unknown }`.
291
+
292
+ ### Array
293
+
294
+ ```json
295
+ {
296
+ "Items": {
297
+ "type": "array",
298
+ "default": [],
299
+ "description": "List of items"
300
+ }
301
+ }
302
+ ```
303
+
304
+ An array replaces whole when a write merges, so it is the wrong shape for anything several participants add to at once: two people each sending a list is two lists, and the last one wins. Use a keyed collection instead.
305
+
306
+ ### Keyed collection
307
+
308
+ A collection several participants write at the same time is an object keyed by a stable id, not an array. Concurrent writes then touch different keys and the merge unions them, rather than replacing each other's list.
309
+
310
+ Describe the item under `additionalProperties`, and give it a `title`:
311
+
312
+ ```json
313
+ {
314
+ "Notes": {
315
+ "type": "object",
316
+ "default": {},
317
+ "description": "One sticky note per participant, keyed by participant id",
318
+ "additionalProperties": {
319
+ "title": "PinboardNote",
320
+ "type": "object",
321
+ "properties": {
322
+ "Author": { "type": "string" },
323
+ "Text": { "type": "string" }
324
+ },
325
+ "required": ["Author", "Text"],
326
+ "additionalProperties": false
327
+ }
328
+ }
329
+ }
330
+ ```
331
+
332
+ The `title` is what gives the item a name in the generated types, so surfaces and engine logic can refer to it:
333
+
334
+ ```typescript
335
+ import type { Context, PinboardNote } from '../types';
336
+
337
+ const render = (note: PinboardNote) => note.Text;
338
+ ```
339
+
340
+ Without one you still get the right shape, `{ [k: string]: { Author: string; Text: string } }`, but nothing to name it, and every function taking an item has to index back into the map that holds it.
341
+
342
+ Where the order of the collection matters, carry it on the entry (a rank, or when it was added) and sort on read. A separate ordered array is an array again, with the same problem.
343
+
344
+ See [Design state for concurrent writes](../recipes/design-state-for-concurrent-writes.md) for the full set of rules this belongs to.
345
+
346
+ ### A TypeScript type of your own
347
+
348
+ The generated types are only as precise as the schema. A schema that says `{ "type": "object" }` for a deep structure, such as a model's output, generates `{ [k: string]: unknown }`, and every read of it needs a cast. Where you already have the type in TypeScript, name it with `tsType` and the generated `types.ts` files use it instead:
349
+
350
+ ```json
351
+ {
352
+ "Messages": {
353
+ "type": "array",
354
+ "default": [],
355
+ "items": {
356
+ "type": "object",
357
+ "tsType": "import('./message').ChatMessage",
358
+ "properties": {
359
+ "role": { "type": "string", "enum": ["user", "assistant"] },
360
+ "content": { "type": "string" }
361
+ },
362
+ "required": ["role", "content"],
363
+ "additionalProperties": false
364
+ }
365
+ }
366
+ }
367
+ ```
368
+
369
+ - **The path is relative to the capability's own directory,** as an import in a file beside `capability.sdk.json` would be. Each generated `types.ts` sits somewhere different, so the generator rewrites the path for each one. A bare module name (`import('some-package').Thing`) is left alone, and so is a `tsType` with no import (`"'low' | 'high'"`)
370
+ - **The build checks the reference.** A path that resolves to no module, or a name the module does not export, fails the build, naming the capability
371
+ - **The schema still does the rest.** `default` still seeds the value, and the runtime still validates against `properties`. `tsType` changes only what TypeScript sees, so keep the two describing the same thing
372
+
373
+ The type lives in a file beside the bundle, here `capabilities/chathistory/message.ts`:
374
+
375
+ ```typescript
376
+ export interface ChatMessage {
377
+ role: 'user' | 'assistant';
378
+ content: string;
379
+ }
380
+ ```
381
+
382
+ For engine bookkeeping nothing else reads, the engine's own [state](./engine.md#keeping-memory-between-ticks) is simpler still: no capability and no schema at all.
383
+
384
+ ## Updating capabilities
385
+
386
+ Update an existing capability:
387
+
388
+ ```bash
389
+ pnpm run sdk update capability inventory '{
390
+ "definition": {
391
+ "variablesSchema": {
392
+ "type": "object",
393
+ "properties": {
394
+ "Stock": { "type": "number", "default": 100 },
395
+ "MinimumStock": { "type": "number", "default": 20 }
396
+ },
397
+ "required": ["Stock", "MinimumStock"],
398
+ "additionalProperties": false
399
+ }
400
+ }
401
+ }'
402
+ ```
403
+
404
+ ## Deleting capabilities
405
+
406
+ Remove a capability:
407
+
408
+ ```bash
409
+ pnpm run sdk delete capability inventory
410
+ ```
411
+
412
+ Deleting a capability also removes every read and write of it, from whichever resources declared them.
413
+
414
+ ## Best practices
415
+
416
+ 1. **Use meaningful identifiers**: a short directory name that says what the variables are
417
+ - ✅ `inventory`
418
+ - ❌ `data1`
419
+
420
+ 2. **Keep variables related**: group related variables in one capability
421
+ - ✅ One capability for inventory variables
422
+ - ❌ Mix inventory and sales in one capability
423
+
424
+ 3. **Provide descriptions**: document what each variable means
425
+ - ✅ `"description": "Current stock level in units"`
426
+ - ❌ `"description": "stock"`
427
+
428
+ 4. **Set sensible defaults**: initialise variables to realistic values
429
+ - ✅ `"default": 100`
430
+ - ❌ `"default": 0` for a stock level that shouldn't be zero
431
+
432
+ 5. **Use constraints**: apply minimum/maximum to numeric values
433
+ - ✅ `"minimum": 0` for quantities that can't be negative
434
+ - ❌ No constraints on bounded values
435
+
436
+ 6. **Use proper types**: never use a string to hold JSON or complex data
437
+ - ✅ Use an `object` type with `properties`
438
+ - ❌ Use a string type with JSON: `{ "type": "string", "default": "{\"key\": \"value\"}" }`
439
+ - See the [type safety guide](./type-safety.md)
440
+
441
+ 7. **Define array elements**: use an `items` schema with property definitions
442
+ - ✅ `{ "type": "array", "items": { "type": "object", "properties": {...} }, "default": [...] }`
443
+ - ❌ `{ "type": "array", "default": [] }` (no type info)
444
+ - See the [type safety guide](./type-safety.md)
445
+
446
+ 8. **Mark engine bookkeeping private**: state that no screen reads it
447
+ - ✅ `"scope": "private"` for a serialised engine, an accumulator, a seed, a ledger the next tick consumes
448
+ - ❌ Leaving it team-scoped, where it is delivered to every screen on every update and a screen can quietly start depending on it
449
+ - See [Private capabilities](#private-capabilities)
450
+
451
+ 9. **Declare only what a screen renders**: a user interface receives exactly its declared capabilities
452
+ - ✅ A `reads` list that matches what the screen actually displays
453
+ - ❌ A long `reads` list kept 'just in case', which is payload sent to every participant on every update
454
+ - Logic resources follow the same rule: the engine, hooks, validators, tick controllers, and endpoints receive only what they declare
455
+
456
+ ## Next steps
457
+
458
+ - [Engines](./engine.md): read and write these capabilities each tick
459
+ - [Multi-team games](./multi-team-games.md): shared and team-readable capabilities in practice
460
+ - [Design state for concurrent writes](../recipes/design-state-for-concurrent-writes.md): shaping state several participants write at once