dreamboard 0.1.21 → 0.1.23
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.
- package/dist/{chunk-EYYWGWTO.js → chunk-2RCUHMGL.js} +343 -1911
- package/dist/chunk-2RCUHMGL.js.map +1 -0
- package/dist/{chunk-MOVHYB6E.js → chunk-GN7232BY.js} +1025 -695
- package/dist/chunk-GN7232BY.js.map +1 -0
- package/dist/{chunk-BMYC6772.js → chunk-H3O43F5P.js} +9765 -3068
- package/dist/chunk-H3O43F5P.js.map +1 -0
- package/dist/dev-host/dev-api-proxy-plugin.ts +330 -0
- package/dist/dev-host/dev-diagnostics.ts +62 -0
- package/dist/dev-host/dev-fallback-stylesheet.ts +50 -0
- package/dist/dev-host/dev-host-controller.ts +686 -0
- package/dist/dev-host/dev-host-player-query.ts +17 -0
- package/dist/dev-host/dev-host-session-transport.ts +52 -0
- package/dist/dev-host/dev-host-storage.ts +56 -0
- package/dist/dev-host/dev-log-relay-plugin.ts +469 -0
- package/dist/dev-host/dev-runtime-config.ts +14 -0
- package/dist/dev-host/dev-runtime-platform.ts +419 -0
- package/dist/dev-host/dev-virtual-modules-plugin.ts +63 -0
- package/dist/dev-host/host-main.css +182 -0
- package/dist/dev-host/host-main.tsx +754 -0
- package/dist/dev-host/index.html +56 -0
- package/dist/dev-host/plugin-main.ts +55 -0
- package/dist/dev-host/plugin.html +24 -0
- package/dist/dev-host/start-dev-server.ts +138 -0
- package/dist/dev-host/virtual-modules.d.ts +27 -0
- package/dist/dist-FEPN3BDN.js +16543 -0
- package/dist/dist-FEPN3BDN.js.map +1 -0
- package/dist/{dist-WJRJNFLI.js → dist-FRURQI7Q.js} +4 -2
- package/dist/index.js +3 -3
- package/dist/internal.js +159 -124
- package/dist/internal.js.map +1 -1
- package/dist/runtime-packages/tailwind-config/shared-styles.css +146 -0
- package/dist/runtime-packages/ui/src/components/.gitkeep +0 -0
- package/dist/runtime-packages/ui/src/components/accordion.tsx +66 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/actions.tsx +65 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/artifact.tsx +147 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/branch.tsx +215 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/canvas.tsx +22 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/chain-of-thought.tsx +228 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/code-block.tsx +179 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/confirmation.tsx +158 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/connection.tsx +28 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/context.tsx +408 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/controls.tsx +18 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/conversation.tsx +97 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/edge.tsx +140 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/image.tsx +24 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/inline-citation.tsx +287 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/loader.tsx +96 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/message.tsx +463 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/node.tsx +71 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/open-in-chat.tsx +365 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/panel.tsx +15 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/plan.tsx +142 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/prompt-input.tsx +1380 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/queue.tsx +274 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/reasoning.tsx +182 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/response.tsx +22 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/shimmer.tsx +64 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/sources.tsx +77 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/suggestion.tsx +53 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/task.tsx +87 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/tool.tsx +165 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/toolbar.tsx +16 -0
- package/dist/runtime-packages/ui/src/components/ai-elements/web-preview.tsx +263 -0
- package/dist/runtime-packages/ui/src/components/alert-dialog.tsx +157 -0
- package/dist/runtime-packages/ui/src/components/alert.tsx +66 -0
- package/dist/runtime-packages/ui/src/components/avatar.tsx +53 -0
- package/dist/runtime-packages/ui/src/components/badge.tsx +46 -0
- package/dist/runtime-packages/ui/src/components/button-group.tsx +83 -0
- package/dist/runtime-packages/ui/src/components/button.tsx +65 -0
- package/dist/runtime-packages/ui/src/components/card.tsx +92 -0
- package/dist/runtime-packages/ui/src/components/carousel.tsx +241 -0
- package/dist/runtime-packages/ui/src/components/collapsible.tsx +33 -0
- package/dist/runtime-packages/ui/src/components/command.tsx +184 -0
- package/dist/runtime-packages/ui/src/components/context-menu.tsx +252 -0
- package/dist/runtime-packages/ui/src/components/counter.tsx +11 -0
- package/dist/runtime-packages/ui/src/components/dialog.tsx +146 -0
- package/dist/runtime-packages/ui/src/components/drawer.tsx +132 -0
- package/dist/runtime-packages/ui/src/components/dropdown-menu.tsx +257 -0
- package/dist/runtime-packages/ui/src/components/form.tsx +168 -0
- package/dist/runtime-packages/ui/src/components/header.tsx +13 -0
- package/dist/runtime-packages/ui/src/components/hover-card.tsx +44 -0
- package/dist/runtime-packages/ui/src/components/input-group.tsx +178 -0
- package/dist/runtime-packages/ui/src/components/input.tsx +21 -0
- package/dist/runtime-packages/ui/src/components/item.tsx +193 -0
- package/dist/runtime-packages/ui/src/components/label.tsx +24 -0
- package/dist/runtime-packages/ui/src/components/navigation-menu.tsx +168 -0
- package/dist/runtime-packages/ui/src/components/popover.tsx +55 -0
- package/dist/runtime-packages/ui/src/components/progress.tsx +31 -0
- package/dist/runtime-packages/ui/src/components/radio-group.tsx +45 -0
- package/dist/runtime-packages/ui/src/components/resizable.tsx +56 -0
- package/dist/runtime-packages/ui/src/components/scroll-area.tsx +58 -0
- package/dist/runtime-packages/ui/src/components/select.tsx +187 -0
- package/dist/runtime-packages/ui/src/components/separator.tsx +28 -0
- package/dist/runtime-packages/ui/src/components/skeleton.tsx +13 -0
- package/dist/runtime-packages/ui/src/components/sonner.tsx +25 -0
- package/dist/runtime-packages/ui/src/components/spinner.tsx +16 -0
- package/dist/runtime-packages/ui/src/components/switch.tsx +31 -0
- package/dist/runtime-packages/ui/src/components/table.tsx +137 -0
- package/dist/runtime-packages/ui/src/components/tabs.tsx +74 -0
- package/dist/runtime-packages/ui/src/components/textarea.tsx +23 -0
- package/dist/runtime-packages/ui/src/components/theme-provider.tsx +73 -0
- package/dist/runtime-packages/ui/src/components/tooltip.tsx +61 -0
- package/dist/runtime-packages/ui/src/components/ui/file-upload.tsx +195 -0
- package/dist/runtime-packages/ui/src/hooks/.gitkeep +0 -0
- package/dist/runtime-packages/ui/src/index.ts +68 -0
- package/dist/runtime-packages/ui/src/lib/utils.ts +6 -0
- package/dist/runtime-packages/ui-host-runtime/src/actor-principal.ts +68 -0
- package/dist/runtime-packages/ui-host-runtime/src/components/host-controls.tsx +359 -0
- package/dist/runtime-packages/ui-host-runtime/src/components/host-feedback-toaster.tsx +274 -0
- package/dist/runtime-packages/ui-host-runtime/src/components/host-feedback.tsx +214 -0
- package/dist/runtime-packages/ui-host-runtime/src/components/host-session-metadata.tsx +135 -0
- package/dist/runtime-packages/ui-host-runtime/src/components/index.ts +5 -0
- package/dist/runtime-packages/ui-host-runtime/src/components/perf-overlay.tsx +194 -0
- package/dist/runtime-packages/ui-host-runtime/src/host-controls.tsx +1 -0
- package/dist/runtime-packages/ui-host-runtime/src/host-feedback.tsx +1 -0
- package/dist/runtime-packages/ui-host-runtime/src/host-session-transport.ts +162 -0
- package/dist/runtime-packages/ui-host-runtime/src/index.ts +2 -0
- package/dist/runtime-packages/ui-host-runtime/src/logger.ts +11 -0
- package/dist/runtime-packages/ui-host-runtime/src/perf.ts +253 -0
- package/dist/runtime-packages/ui-host-runtime/src/plugin-bridge.ts +195 -0
- package/dist/runtime-packages/ui-host-runtime/src/plugin-health-check.ts +138 -0
- package/dist/runtime-packages/ui-host-runtime/src/plugin-messages.ts +159 -0
- package/dist/runtime-packages/ui-host-runtime/src/plugin-session-gateway.ts +524 -0
- package/dist/runtime-packages/ui-host-runtime/src/runtime/index.ts +12 -0
- package/dist/runtime-packages/ui-host-runtime/src/screenshot/projection-to-snapshot.ts +122 -0
- package/dist/runtime-packages/ui-host-runtime/src/screenshot/static-store-api.ts +26 -0
- package/dist/runtime-packages/ui-host-runtime/src/session-ingress-controller.ts +477 -0
- package/dist/runtime-packages/ui-host-runtime/src/session-ingress.ts +209 -0
- package/dist/runtime-packages/ui-host-runtime/src/session-live-runtime.ts +112 -0
- package/dist/runtime-packages/ui-host-runtime/src/session-model.ts +318 -0
- package/dist/runtime-packages/ui-host-runtime/src/session-projection.ts +211 -0
- package/dist/runtime-packages/ui-host-runtime/src/session-state-reducer.ts +814 -0
- package/dist/runtime-packages/ui-host-runtime/src/sse-manager.ts +334 -0
- package/dist/runtime-packages/ui-host-runtime/src/unified-session-store.ts +180 -0
- package/dist/scaffold/assets/static/app/tsconfig.framework.json +3 -1
- package/dist/scaffold/assets/static/ui/tsconfig.framework.json +7 -19
- package/package.json +52 -17
- package/skills/dreamboard/SKILL.md +41 -75
- package/LICENSE +0 -89
- package/NOTICE +0 -1
- package/dist/chunk-BMYC6772.js.map +0 -1
- package/dist/chunk-EYYWGWTO.js.map +0 -1
- package/dist/chunk-MOVHYB6E.js.map +0 -1
- package/dist/scaffold/assets/static/ui/App.tsx +0 -22
- package/dist/src-CUL7EGGG.js +0 -634
- package/dist/src-CUL7EGGG.js.map +0 -1
- package/skills/dreamboard/references/authoring-lifecycle.md +0 -102
- package/skills/dreamboard/references/board-surfaces.md +0 -36
- package/skills/dreamboard/references/board-topology.md +0 -443
- package/skills/dreamboard/references/boards-and-topology.md +0 -100
- package/skills/dreamboard/references/card-actions.md +0 -107
- package/skills/dreamboard/references/cli.md +0 -120
- package/skills/dreamboard/references/core-concepts.md +0 -514
- package/skills/dreamboard/references/custom-renderers.md +0 -26
- package/skills/dreamboard/references/derived-values.md +0 -55
- package/skills/dreamboard/references/effects.md +0 -111
- package/skills/dreamboard/references/game-contract.md +0 -89
- package/skills/dreamboard/references/game-definition.md +0 -89
- package/skills/dreamboard/references/game-shell.md +0 -80
- package/skills/dreamboard/references/hand-surfaces.md +0 -33
- package/skills/dreamboard/references/index.md +0 -112
- package/skills/dreamboard/references/inputs-and-targets.md +0 -160
- package/skills/dreamboard/references/interactions.md +0 -158
- package/skills/dreamboard/references/manifest-fields.md +0 -137
- package/skills/dreamboard/references/manifest.md +0 -81
- package/skills/dreamboard/references/package-surfaces.md +0 -69
- package/skills/dreamboard/references/phases.md +0 -145
- package/skills/dreamboard/references/prompts-and-choices.md +0 -55
- package/skills/dreamboard/references/quickstart.md +0 -71
- package/skills/dreamboard/references/rule-authoring.md +0 -144
- package/skills/dreamboard/references/setup-bootstrap.md +0 -78
- package/skills/dreamboard/references/stages-and-zones.md +0 -59
- package/skills/dreamboard/references/static-views.md +0 -67
- package/skills/dreamboard/references/table-queries-and-ops.md +0 -103
- package/skills/dreamboard/references/testing-bases.md +0 -147
- package/skills/dreamboard/references/testing-generated-contracts.md +0 -142
- package/skills/dreamboard/references/testing-runtime-assertions.md +0 -124
- package/skills/dreamboard/references/testing-scenarios.md +0 -148
- package/skills/dreamboard/references/testing-ui-tests.md +0 -174
- package/skills/dreamboard/references/testing.md +0 -161
- package/skills/dreamboard/references/ui-architecture.md +0 -137
- package/skills/dreamboard/references/ui-components.md +0 -34
- package/skills/dreamboard/references/views.md +0 -72
- package/skills/dreamboard/references/workspace-layout.md +0 -136
- /package/dist/{dist-WJRJNFLI.js.map → dist-FRURQI7Q.js.map} +0 -0
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
# Testing overview
|
|
2
|
-
|
|
3
|
-
Generate and run Dreamboard reducer-native tests.
|
|
4
|
-
|
|
5
|
-
Dreamboard tests run authored scenarios against the
|
|
6
|
-
same reducer contract that powers the game, using generated workspace types for
|
|
7
|
-
player ids, interaction ids, params, phases, views, and assertion helpers.
|
|
8
|
-
|
|
9
|
-
Use tests for repeatable gameplay coverage:
|
|
10
|
-
|
|
11
|
-
- opening-state invariants
|
|
12
|
-
- setup checkpoints reused by many scenarios
|
|
13
|
-
- happy paths across a turn, round, or full game
|
|
14
|
-
- rejection paths for illegal actors or params
|
|
15
|
-
- prompt recipient and availability checks
|
|
16
|
-
- UI component probes against reducer-projected plugin state
|
|
17
|
-
|
|
18
|
-
## Workspace layout
|
|
19
|
-
|
|
20
|
-
| Path | Ownership | Purpose |
|
|
21
|
-
| --- | --- | --- |
|
|
22
|
-
| `test/bases/*.base.ts` | Authored | Reusable seeded starting states via `defineBase`. |
|
|
23
|
-
| `test/scenarios/*.scenario.ts` | Authored | Reducer-native scenario files via `defineScenario`. |
|
|
24
|
-
| `test/ui/*.test.tsx` | Authored | Optional UI tests using `createTestRuntime`. |
|
|
25
|
-
| `test/testing-types.ts` | Generated | Workspace-narrowed test import surface. |
|
|
26
|
-
| `test/generated/*` | Generated | Base snapshots, testing contract, scenario manifest, projections, snapshots, and metadata. |
|
|
27
|
-
|
|
28
|
-
Import test helpers from `../testing-types`. Do not import directly from
|
|
29
|
-
`test/generated/*` and do not edit generated files by hand.
|
|
30
|
-
|
|
31
|
-
## Command flow
|
|
32
|
-
|
|
33
|
-
Generate or refresh reducer-native artifacts:
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
dreamboard test generate
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
Run all reducer scenarios:
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
dreamboard test run
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Run one scenario file:
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
dreamboard test run --scenario test/scenarios/trade-full-lifecycle.scenario.ts
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
Refresh scenario snapshots while running:
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
|
-
dreamboard test run --update-snapshots
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
Public workspaces should normally omit `--runner`. The default runner is the
|
|
58
|
-
reducer runner. Internal source-checkout lanes may also use `embedded` or
|
|
59
|
-
`browser`, but those are parity lanes rather than the public authoring loop.
|
|
60
|
-
|
|
61
|
-
Example workspaces may also expose package-local checks. Star Settlers, for
|
|
62
|
-
example, uses `pnpm typecheck:test` for test TypeScript and `pnpm test:ui` for
|
|
63
|
-
React UI probes under `test/ui`.
|
|
64
|
-
|
|
65
|
-
## What generate does
|
|
66
|
-
|
|
67
|
-
`dreamboard test generate`:
|
|
68
|
-
|
|
69
|
-
1. Ensures `test/testing-types.ts` and `test/generated/testing-contract.ts`
|
|
70
|
-
exist and match the current workspace contract.
|
|
71
|
-
2. Loads `test/bases/*.base.ts` and `test/scenarios/*.scenario.ts`.
|
|
72
|
-
3. Validates that every scenario references an existing base.
|
|
73
|
-
4. Executes base setup against the reducer to produce deterministic base
|
|
74
|
-
snapshots.
|
|
75
|
-
5. Writes generated artifacts under `test/generated/`.
|
|
76
|
-
|
|
77
|
-
Regenerate after changes that affect runtime or type shape:
|
|
78
|
-
|
|
79
|
-
- `manifest.ts`
|
|
80
|
-
- `app/game.ts`
|
|
81
|
-
- phase files, interactions, card actions, targets, or views
|
|
82
|
-
- setup profiles
|
|
83
|
-
- generated `shared/generated/ui-contract.ts`
|
|
84
|
-
- stale base fingerprints reported by `dreamboard test run`
|
|
85
|
-
|
|
86
|
-
## What run does
|
|
87
|
-
|
|
88
|
-
`dreamboard test run`:
|
|
89
|
-
|
|
90
|
-
1. Ensures generated testing files exist.
|
|
91
|
-
2. Loads bases, scenarios, generated base states, manifest, and game reducer.
|
|
92
|
-
3. Checks generated base fingerprints against the current workspace.
|
|
93
|
-
4. Starts each scenario from its base.
|
|
94
|
-
5. Runs `when`.
|
|
95
|
-
6. Checks optional `phase` and `stage`.
|
|
96
|
-
7. Runs `then`.
|
|
97
|
-
8. Prints one pass or fail line per scenario plus a summary.
|
|
98
|
-
|
|
99
|
-
If the base artifact is stale, the runner fails before pretending the scenario
|
|
100
|
-
is meaningful. Regenerate instead of debugging against an old snapshot.
|
|
101
|
-
|
|
102
|
-
## Minimal base and scenario
|
|
103
|
-
|
|
104
|
-
```ts
|
|
105
|
-
// test/bases/initial-turn.base.ts
|
|
106
|
-
import { defineBase } from "../testing-types";
|
|
107
|
-
|
|
108
|
-
export default defineBase({
|
|
109
|
-
id: "initial-turn",
|
|
110
|
-
seed: 1337,
|
|
111
|
-
players: 4,
|
|
112
|
-
setup: async () => undefined,
|
|
113
|
-
});
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
```ts
|
|
117
|
-
// test/scenarios/smoke-initial-turn.scenario.ts
|
|
118
|
-
import { defineScenario } from "../testing-types";
|
|
119
|
-
|
|
120
|
-
export default defineScenario({
|
|
121
|
-
id: "smoke-initial-turn",
|
|
122
|
-
from: "initial-turn",
|
|
123
|
-
phase: "setup",
|
|
124
|
-
when: async () => undefined,
|
|
125
|
-
then: ({ state, interactions, expect, seat }) => {
|
|
126
|
-
expect(state()).toBe("setup");
|
|
127
|
-
expect(interactions(seat(0))).toHaveInteraction("placeSetupMarker");
|
|
128
|
-
},
|
|
129
|
-
});
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
Use `seat(0)`, `seat(1)`, and `players()` instead of hard-coded `"player-1"`
|
|
133
|
-
strings. This keeps tests portable across player counts and generated player id
|
|
134
|
-
unions.
|
|
135
|
-
|
|
136
|
-
## Recommended coverage
|
|
137
|
-
|
|
138
|
-
Every game should have:
|
|
139
|
-
|
|
140
|
-
- one opening-state scenario
|
|
141
|
-
- one normal turn or round scenario
|
|
142
|
-
- one scenario that crosses a phase boundary
|
|
143
|
-
- one rejection scenario for out-of-turn or invalid params
|
|
144
|
-
- one prompt recipient scenario if the game uses prompts
|
|
145
|
-
- one setup-profile or setup-completion scenario when setup is non-trivial
|
|
146
|
-
|
|
147
|
-
For larger games, create bases for expensive checkpoints such as post-setup,
|
|
148
|
-
mid-game economy, pending trade, pending combat, or near-endgame. Do not make
|
|
149
|
-
one scenario replay a full game just to test a late rule.
|
|
150
|
-
|
|
151
|
-
## Split pages
|
|
152
|
-
|
|
153
|
-
- [Bases](./testing-bases.md) explains seeded checkpoints and inheritance.
|
|
154
|
-
- [Scenarios](./testing-scenarios.md) explains `defineScenario` and scenario
|
|
155
|
-
flow.
|
|
156
|
-
- [Runtime assertions](./testing-runtime-assertions.md) lists context helpers
|
|
157
|
-
and matchers.
|
|
158
|
-
- [UI tests](./testing-ui-tests.md) shows `createTestRuntime` with React
|
|
159
|
-
providers.
|
|
160
|
-
- [Generated testing contracts](./testing-generated-contracts.md) explains
|
|
161
|
-
generated files and stale-artifact failures.
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
# UI architecture
|
|
2
|
-
|
|
3
|
-
Understand the generated UI contract, UI SDK, and host runtime boundaries.
|
|
4
|
-
|
|
5
|
-
Dreamboard UI is reducer-driven and component-first. The reducer projects the
|
|
6
|
-
current player's view and available interactions; React composes generated
|
|
7
|
-
primitives, package defaults, and local visuals around those authoritative
|
|
8
|
-
descriptors.
|
|
9
|
-
|
|
10
|
-
Do not reimplement legality in React. UI code may choose layout, copy,
|
|
11
|
-
highlights, and controls, but availability, eligible targets, prompt options,
|
|
12
|
-
and submitted param shapes should come from authored reducer contracts and
|
|
13
|
-
generated types.
|
|
14
|
-
|
|
15
|
-
## Layers
|
|
16
|
-
|
|
17
|
-
| Layer | Import path | Owns |
|
|
18
|
-
| --- | --- | --- |
|
|
19
|
-
| Workspace UI contract | `@dreamboard/ui-contract` | Typed `Interaction`, `Prompt`, `PromptInbox`, `Zone`, `Board`, generated hooks, interaction keys, input keys, zone ids, card ids, phase names, and board targets. |
|
|
20
|
-
| UI SDK | `@dreamboard/ui-sdk` | Runtime providers, generic hooks, visual primitives such as `Card`, `HexGrid`, `ResourceCounter`, and advanced escape-hatch hooks. |
|
|
21
|
-
| UI defaults | `@dreamboard/ui-sdk/defaults` | Styled wrappers over primitives such as `DefaultPromptInbox`, `DefaultInteractionList`, `DefaultZone`, and `GameLayout`. |
|
|
22
|
-
| Host runtime | Provided by the dev/play host | Session state, state-sync snapshots, interaction submission, validation RPCs, player switching, history restore, and host-only feedback. |
|
|
23
|
-
|
|
24
|
-
Most authored UI imports the generated contract first:
|
|
25
|
-
|
|
26
|
-
```tsx
|
|
27
|
-
import {
|
|
28
|
-
Interaction,
|
|
29
|
-
PromptInbox,
|
|
30
|
-
Zone,
|
|
31
|
-
useBoardInteractions,
|
|
32
|
-
useGameView,
|
|
33
|
-
useInteractionByKey,
|
|
34
|
-
} from "@dreamboard/ui-contract";
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Use `@dreamboard/ui-sdk` for framework primitives that are not
|
|
38
|
-
workspace-specific:
|
|
39
|
-
|
|
40
|
-
```tsx
|
|
41
|
-
import { Card, HexGrid, ResourceCounter, ToastProvider } from "@dreamboard/ui-sdk";
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
`@dreamboard/ui-contract` is a generated workspace alias backed by
|
|
45
|
-
`shared/generated/ui-contract.ts`, not a standalone npm package. The generated
|
|
46
|
-
file augments `@dreamboard/ui-sdk`'s `DreamboardUIRegister`, calls
|
|
47
|
-
`createDreamboardUI(uiContract)`, and exports typed primitives such as
|
|
48
|
-
`Interaction`, `Prompt`, `PromptInbox`, `PromptDialogHost`, `PlayerRoster`,
|
|
49
|
-
`Phase`, `Zone`, and `Board`.
|
|
50
|
-
|
|
51
|
-
## Data flow
|
|
52
|
-
|
|
53
|
-
1. Authoring files declare manifest objects, phases, interactions, inputs,
|
|
54
|
-
targets, card actions, and views.
|
|
55
|
-
2. `dreamboard sync` generates workspace contracts, including
|
|
56
|
-
`@dreamboard/ui-contract`.
|
|
57
|
-
3. The trusted bundle evaluates the current seat and projects descriptors into
|
|
58
|
-
plugin state.
|
|
59
|
-
4. UI primitives read those descriptors and expose state through props,
|
|
60
|
-
contexts, `data-*` attributes, and typed handles.
|
|
61
|
-
5. UI submits through `Interaction.Submit`, `Prompt.Option`,
|
|
62
|
-
`InteractionHandle`, or generated board target helpers.
|
|
63
|
-
|
|
64
|
-
The descriptor is a behavior contract, not a presentation DSL. It carries ids,
|
|
65
|
-
availability, unavailable reasons, input domains, target eligibility, prompt
|
|
66
|
-
options, zone metadata, and phase metadata. Visual policy belongs in React/CSS
|
|
67
|
-
or default wrappers.
|
|
68
|
-
|
|
69
|
-
## Primitive scaffold
|
|
70
|
-
|
|
71
|
-
```tsx
|
|
72
|
-
import { PromptInbox } from "@dreamboard/ui-contract";
|
|
73
|
-
|
|
74
|
-
export default function App() {
|
|
75
|
-
return (
|
|
76
|
-
<main>
|
|
77
|
-
<PromptInbox.Root>
|
|
78
|
-
<PromptInbox.Empty>No available prompts.</PromptInbox.Empty>
|
|
79
|
-
<PromptInbox.Items />
|
|
80
|
-
</PromptInbox.Root>
|
|
81
|
-
</main>
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
Use the same pattern for actions and zones:
|
|
87
|
-
|
|
88
|
-
```tsx
|
|
89
|
-
<Interaction.Root interaction="playerTurn.buyCard">
|
|
90
|
-
<Interaction.Label />
|
|
91
|
-
<Interaction.Submit>Buy</Interaction.Submit>
|
|
92
|
-
</Interaction.Root>
|
|
93
|
-
|
|
94
|
-
<Zone.Root zone="hand">
|
|
95
|
-
<Zone.List>
|
|
96
|
-
{view.hand.map((card) => (
|
|
97
|
-
<Zone.Item key={card.id} card={card.id}>
|
|
98
|
-
<Interaction.CardInput input="cardId" card={card.id}>
|
|
99
|
-
<Card card={card} />
|
|
100
|
-
</Interaction.CardInput>
|
|
101
|
-
</Zone.Item>
|
|
102
|
-
))}
|
|
103
|
-
</Zone.List>
|
|
104
|
-
</Zone.Root>
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
## Custom board escape hatch
|
|
108
|
-
|
|
109
|
-
SVG or canvas-heavy boards can use generated `useBoardInteractions()` while the
|
|
110
|
-
reducer still owns eligibility:
|
|
111
|
-
|
|
112
|
-
```tsx
|
|
113
|
-
const board = useBoardInteractions();
|
|
114
|
-
|
|
115
|
-
<HexGrid
|
|
116
|
-
board={view.board}
|
|
117
|
-
interactiveVertices={board.targetLayers.vertex()}
|
|
118
|
-
interactiveEdges={board.targetLayers.edge()}
|
|
119
|
-
renderTile={(tile, geometry) => <polygon points={geometry.points()} />}
|
|
120
|
-
renderEdge={(edge) => <line />}
|
|
121
|
-
renderVertex={(vertex) => <circle /> /* sketch only */}
|
|
122
|
-
/>;
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
## Boundaries
|
|
126
|
-
|
|
127
|
-
| Put it here | Examples |
|
|
128
|
-
| --- | --- |
|
|
129
|
-
| Reducer authoring | Turn order, actor rules, prompt recipients, target eligibility, costs, validation, state transitions. |
|
|
130
|
-
| Generated UI contract | Interaction keys, input names, prompt options, phase-qualified param types, zones, card ids, board target ids. |
|
|
131
|
-
| Authored React UI | Layout, styling, board geometry, card faces, component composition, selected draft inputs. |
|
|
132
|
-
| Host runtime | Player switching, session chrome, state-sync, submission transport, host-only notifications. |
|
|
133
|
-
|
|
134
|
-
Do not mirror host-only concepts into authored reducer state just to make UI
|
|
135
|
-
chrome easier. Do not copy target predicates into React just to enable or
|
|
136
|
-
disable a board element. If React needs a highlight, expose it through a target
|
|
137
|
-
collector or derived view.
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# UI components
|
|
2
|
-
|
|
3
|
-
Generic presentational components available from @dreamboard/ui-sdk.
|
|
4
|
-
|
|
5
|
-
Dreamboard ships generic presentational components in `@dreamboard/ui-sdk`.
|
|
6
|
-
They are not game-specific; pair them with generated primitives from
|
|
7
|
-
`@dreamboard/ui-contract` when behavior needs typed interactions.
|
|
8
|
-
|
|
9
|
-
| Component | Use |
|
|
10
|
-
| --- | --- |
|
|
11
|
-
| `Card` | Render a card face from projected view data. |
|
|
12
|
-
| `Hand` | Presentational card row/fan helper. |
|
|
13
|
-
| `HexGrid` / `SquareGrid` | Board geometry renderers. |
|
|
14
|
-
| `ResourceCounter` / `CostDisplay` | Resource and cost display. |
|
|
15
|
-
| `DiceRoller` | Dice display plus optional roll action handle. |
|
|
16
|
-
| `PlayerRoster` | Generated player roster primitive for player chrome. |
|
|
17
|
-
| `GameEndDisplay` | End-of-game summary. |
|
|
18
|
-
| `ToastProvider` | Local toast context for UI feedback. |
|
|
19
|
-
|
|
20
|
-
Behavior comes from generated primitives:
|
|
21
|
-
|
|
22
|
-
```tsx
|
|
23
|
-
import { Interaction, Zone } from "@dreamboard/ui-contract";
|
|
24
|
-
import { Card } from "@dreamboard/ui-sdk";
|
|
25
|
-
|
|
26
|
-
<Zone.Item card={card.id}>
|
|
27
|
-
<Interaction.CardInput input="cardId" card={card.id}>
|
|
28
|
-
<Card card={card} />
|
|
29
|
-
</Interaction.CardInput>
|
|
30
|
-
</Zone.Item>
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
Presentational components should render projected view data or interaction
|
|
34
|
-
handles. They should not inspect reducer internals or recompute legality.
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
# Views
|
|
2
|
-
|
|
3
|
-
Use defineView to project dynamic player-facing state for UI and clients.
|
|
4
|
-
|
|
5
|
-
Views are the dynamic player-facing projection boundary. The UI reads a view; it should not inspect raw reducer state.
|
|
6
|
-
|
|
7
|
-
```ts
|
|
8
|
-
export const playerView = defineView<GameContract>()({
|
|
9
|
-
project({ state, playerId, q }) {
|
|
10
|
-
const scores = state.publicState.scores;
|
|
11
|
-
const handCards = q.zone.playerCards(playerId, "things-hand").map((cardId) => {
|
|
12
|
-
const card = q.card.get(cardId);
|
|
13
|
-
return {
|
|
14
|
-
id: cardId,
|
|
15
|
-
label: card.name ?? cardId,
|
|
16
|
-
};
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
return {
|
|
20
|
-
phase: state.flow.currentPhase,
|
|
21
|
-
myScore: scores[playerId] ?? 0,
|
|
22
|
-
scores,
|
|
23
|
-
handCards,
|
|
24
|
-
winnerPlayerId: state.publicState.winnerPlayerId,
|
|
25
|
-
};
|
|
26
|
-
},
|
|
27
|
-
});
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
Register views in `defineGame`:
|
|
31
|
-
|
|
32
|
-
```ts
|
|
33
|
-
export default defineGame({
|
|
34
|
-
contract: gameContract,
|
|
35
|
-
phases,
|
|
36
|
-
views: {
|
|
37
|
-
player: playerView,
|
|
38
|
-
},
|
|
39
|
-
});
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
The generated UI contract exposes the projected type as `GameView` and `InferView<"player">`.
|
|
43
|
-
|
|
44
|
-
## What a view can read
|
|
45
|
-
|
|
46
|
-
`project` receives:
|
|
47
|
-
|
|
48
|
-
- `state`, including public/private/hidden/phase/table data as appropriate for the runtime projection
|
|
49
|
-
- `playerId`
|
|
50
|
-
- `q`, the typed table query namespace
|
|
51
|
-
- `derived`, for memoized derived values
|
|
52
|
-
- runtime context such as current phase, player order, active players, and setup
|
|
53
|
-
|
|
54
|
-
Use `q` for table facts such as cards in a hand, board occupants, resource balances, and component locations.
|
|
55
|
-
|
|
56
|
-
## What belongs in a view
|
|
57
|
-
|
|
58
|
-
Views should shape data for UI consumption:
|
|
59
|
-
|
|
60
|
-
- labels for cards or pieces
|
|
61
|
-
- counts and summaries
|
|
62
|
-
- player-specific hand information
|
|
63
|
-
- current phase and step display data
|
|
64
|
-
- safe public slices of score and winner state
|
|
65
|
-
|
|
66
|
-
Views should not run rule validation or decide legal moves. The runtime projects interactions and eligible targets from reducer definitions.
|
|
67
|
-
|
|
68
|
-
## Static vs dynamic
|
|
69
|
-
|
|
70
|
-
Use `defineView` for data that can change during a session. Use [Static views](./static-views.md) for manifest-derived payloads that do not change after session initialization.
|
|
71
|
-
|
|
72
|
-
Avoid putting large static topology in every dynamic view update.
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
# Workspace layout
|
|
2
|
-
|
|
3
|
-
Understand which Dreamboard workspace files are authored, generated, scaffold-owned, and runtime-facing.
|
|
4
|
-
|
|
5
|
-
A Dreamboard workspace is split by ownership. Keep that split intact: edit authored source, regenerate generated contracts, and avoid patching files that say they are generated.
|
|
6
|
-
|
|
7
|
-
## Main files
|
|
8
|
-
|
|
9
|
-
| Path | Ownership | Purpose |
|
|
10
|
-
| ------------------------ | -------------------- | ------------------------------------------------------------------------------------------------ |
|
|
11
|
-
| `rule.md` | Authored | Human-readable rules, setup, turn flow, scoring, and edge cases. |
|
|
12
|
-
| `manifest.ts` | Authored | Static game topology: players, cards, zones, boards, pieces, dice, resources, setup options. |
|
|
13
|
-
| `app/game-contract.ts` | Authored | State schemas, phase-name tuple, and generated manifest contract binding. |
|
|
14
|
-
| `app/game.ts` | Authored | Assembles the game with `defineGame`: initial state, phases, views, setup profiles, static view. |
|
|
15
|
-
| `app/phases/` | Authored | Phase definitions, interactions, card actions, effects, stages, zones. |
|
|
16
|
-
| `app/player-view.ts` | Authored | Dynamic player-facing projection with `defineView`. |
|
|
17
|
-
| `app/board-static.ts` | Authored when needed | Session-scoped immutable projection with `defineStaticView`. |
|
|
18
|
-
| `app/derived.ts` | Authored when needed | Pure reusable computations with `defineDerived`. |
|
|
19
|
-
| `app/reducer-support.ts` | Authored | Game-specific helper functions that accept injected `q` and `ops`. |
|
|
20
|
-
| `ui/` | Authored | React UI built from generated `@dreamboard/ui-contract` primitives and generic SDK visuals. |
|
|
21
|
-
| `test/bases/` | Authored | Reusable scenario starting states via `defineBase`. |
|
|
22
|
-
| `test/scenarios/` | Authored | Reducer-native scenarios via `defineScenario`. |
|
|
23
|
-
|
|
24
|
-
## Recommended app structure
|
|
25
|
-
|
|
26
|
-
Small games can stay flat:
|
|
27
|
-
|
|
28
|
-
```txt
|
|
29
|
-
app/
|
|
30
|
-
game-contract.ts
|
|
31
|
-
game.ts
|
|
32
|
-
derived.ts
|
|
33
|
-
reducer-support.ts
|
|
34
|
-
phases/
|
|
35
|
-
setup.ts
|
|
36
|
-
player-turn.ts
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
As the game grows, split by game concept instead of letting one phase file
|
|
40
|
-
collect every rule:
|
|
41
|
-
|
|
42
|
-
```txt
|
|
43
|
-
app/
|
|
44
|
-
game-contract.ts # schemas, phase names, exported state types
|
|
45
|
-
game.ts # defineGame assembly
|
|
46
|
-
derived.ts # defineDerived values
|
|
47
|
-
player-view.ts # player-facing projection
|
|
48
|
-
reducer-support.ts # small shared reducer plumbing
|
|
49
|
-
rules/ # domain helpers once reducer-support grows
|
|
50
|
-
board.ts
|
|
51
|
-
resources.ts
|
|
52
|
-
scoring.ts
|
|
53
|
-
phases/
|
|
54
|
-
player-turn/
|
|
55
|
-
index.ts # definePhase assembly only
|
|
56
|
-
turn-state.ts # phase-local constants and types
|
|
57
|
-
action-rules.ts # shared availability and validation rules
|
|
58
|
-
inputs.ts # shared typed input helpers
|
|
59
|
-
build.ts # build interactions
|
|
60
|
-
player-trade.ts # trade interactions
|
|
61
|
-
tech-cards.ts # card actions
|
|
62
|
-
end-turn.ts # end-turn interaction
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
Use a phase folder when a phase has multiple action families, shared typed input
|
|
66
|
-
helpers, card actions, or is roughly 250-300 lines. Keep
|
|
67
|
-
`index.ts` as the table of contents: import interactions, card actions, and
|
|
68
|
-
phase state, then register them with `definePhase`.
|
|
69
|
-
|
|
70
|
-
## Generated files
|
|
71
|
-
|
|
72
|
-
Generated files are there to make the authored surface strongly typed. Do not edit them directly.
|
|
73
|
-
|
|
74
|
-
| Path | Generated by | Contains |
|
|
75
|
-
| ------------------------------------ | -------------------------- | ------------------------------------------------------------------------------------------------- |
|
|
76
|
-
| `shared/manifest-contract.ts` | `dreamboard sync` | Literal ID unions, Zod ID schemas, runtime table types, setup profile helpers, manifest defaults. |
|
|
77
|
-
| `shared/generated/ui-contract.ts` | `dreamboard sync` | Typed primitives, interaction keys, input keys, prompt options, zones, board targets, view types, typed hooks. |
|
|
78
|
-
| `test/testing-types.ts` | `dreamboard test generate` | Workspace-narrowed `defineBase`, `defineScenario`, and `createTestRuntime`. |
|
|
79
|
-
| `test/generated/testing-contract.ts` | `dreamboard test generate` | Scenario context, generated assertions, interaction parameter types. |
|
|
80
|
-
|
|
81
|
-
If a generated file is stale, regenerate it instead of patching it:
|
|
82
|
-
|
|
83
|
-
```bash
|
|
84
|
-
dreamboard sync
|
|
85
|
-
dreamboard test generate
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
## Imports
|
|
89
|
-
|
|
90
|
-
Use the public reducer surface for app code:
|
|
91
|
-
|
|
92
|
-
```ts
|
|
93
|
-
import {
|
|
94
|
-
defineGame,
|
|
95
|
-
defineGameContract,
|
|
96
|
-
definePhase,
|
|
97
|
-
defineInteraction,
|
|
98
|
-
pipe,
|
|
99
|
-
} from "@dreamboard/app-sdk/reducer";
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
Use generated workspace contracts for IDs and typed UI:
|
|
103
|
-
|
|
104
|
-
```ts
|
|
105
|
-
import { ids, literals, manifestContract } from "../shared/manifest-contract";
|
|
106
|
-
import {
|
|
107
|
-
Interaction,
|
|
108
|
-
PromptInbox,
|
|
109
|
-
Zone,
|
|
110
|
-
useInteractionByKey,
|
|
111
|
-
} from "../shared/generated/ui-contract";
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
Generated aliases may expose these as package-level imports inside scaffolded workspaces, but the ownership rule is the same: app code depends on the generated workspace contract, not on hand-written copies of IDs.
|
|
115
|
-
|
|
116
|
-
## Where helpers belong
|
|
117
|
-
|
|
118
|
-
Put small reusable reducer helpers in `app/reducer-support.ts` when they are
|
|
119
|
-
game-specific and SDK-shaped. Helpers should accept injected `q` and `ops`
|
|
120
|
-
instead of constructing their own table readers or state writers.
|
|
121
|
-
|
|
122
|
-
```ts
|
|
123
|
-
export function incrementScore(ops: Ops, playerId: PlayerId): Op<GameState> {
|
|
124
|
-
return ops.patchPublicState((prev) => ({
|
|
125
|
-
...prev,
|
|
126
|
-
scores: {
|
|
127
|
-
...prev.scores,
|
|
128
|
-
[playerId]: (prev.scores[playerId] ?? 0) + 1,
|
|
129
|
-
},
|
|
130
|
-
}));
|
|
131
|
-
}
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
When helpers become domain rules, split them into `app/rules/*` modules such as
|
|
135
|
-
`board.ts`, `resources.ts`, or `scoring.ts`. If the helper is broadly useful
|
|
136
|
-
across games, it probably belongs in the SDK rather than in a local example.
|
|
File without changes
|