@crowdedkingdoms/crowdyjs 11.0.0 → 12.0.0

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 (81) hide show
  1. package/MIGRATION.md +118 -0
  2. package/README.md +208 -0
  3. package/dist/crowdy-agent/browser-dispatcher.d.ts +41 -0
  4. package/dist/crowdy-agent/browser-dispatcher.d.ts.map +1 -0
  5. package/dist/crowdy-agent/browser-dispatcher.js +264 -0
  6. package/dist/crowdy-agent/controller.d.ts +144 -0
  7. package/dist/crowdy-agent/controller.d.ts.map +1 -0
  8. package/dist/crowdy-agent/controller.js +1239 -0
  9. package/dist/crowdy-agent/errors.d.ts +37 -0
  10. package/dist/crowdy-agent/errors.d.ts.map +1 -0
  11. package/dist/crowdy-agent/errors.js +107 -0
  12. package/dist/crowdy-agent/graphql-transport.d.ts +154 -0
  13. package/dist/crowdy-agent/graphql-transport.d.ts.map +1 -0
  14. package/dist/crowdy-agent/graphql-transport.js +854 -0
  15. package/dist/crowdy-agent/index.d.ts +16 -0
  16. package/dist/crowdy-agent/index.d.ts.map +1 -0
  17. package/dist/crowdy-agent/index.js +15 -0
  18. package/dist/crowdy-agent/registry.d.ts +29 -0
  19. package/dist/crowdy-agent/registry.d.ts.map +1 -0
  20. package/dist/crowdy-agent/registry.js +281 -0
  21. package/dist/crowdy-agent/schema.d.ts +72 -0
  22. package/dist/crowdy-agent/schema.d.ts.map +1 -0
  23. package/dist/crowdy-agent/schema.js +467 -0
  24. package/dist/crowdy-agent/studio-tools.d.ts +15 -0
  25. package/dist/crowdy-agent/studio-tools.d.ts.map +1 -0
  26. package/dist/crowdy-agent/studio-tools.js +280 -0
  27. package/dist/crowdy-agent/tool-descriptors.d.ts +4 -0
  28. package/dist/crowdy-agent/tool-descriptors.d.ts.map +1 -0
  29. package/dist/crowdy-agent/tool-descriptors.js +1049 -0
  30. package/dist/crowdy-agent/transport.d.ts +152 -0
  31. package/dist/crowdy-agent/transport.d.ts.map +1 -0
  32. package/dist/crowdy-agent/transport.js +27 -0
  33. package/dist/crowdy-agent/types.d.ts +328 -0
  34. package/dist/crowdy-agent/types.d.ts.map +1 -0
  35. package/dist/crowdy-agent/types.js +37 -0
  36. package/dist/crowdy-client.d.ts +3 -0
  37. package/dist/crowdy-client.d.ts.map +1 -1
  38. package/dist/crowdy-client.js +6 -0
  39. package/dist/crowdy-studio/agent-dom-shell.d.ts +40 -0
  40. package/dist/crowdy-studio/agent-dom-shell.d.ts.map +1 -0
  41. package/dist/crowdy-studio/agent-dom-shell.js +354 -0
  42. package/dist/crowdy-studio/controller.d.ts +74 -4
  43. package/dist/crowdy-studio/controller.d.ts.map +1 -1
  44. package/dist/crowdy-studio/controller.js +450 -17
  45. package/dist/crowdy-studio/dom-shell.d.ts +4 -1
  46. package/dist/crowdy-studio/dom-shell.d.ts.map +1 -1
  47. package/dist/crowdy-studio/dom-shell.js +6 -1
  48. package/dist/crowdy-studio/index.d.ts +6 -3
  49. package/dist/crowdy-studio/index.d.ts.map +1 -1
  50. package/dist/crowdy-studio/index.js +3 -0
  51. package/dist/crowdy-studio/models.d.ts +67 -0
  52. package/dist/crowdy-studio/models.d.ts.map +1 -1
  53. package/dist/crowdy-studio/mount.d.ts +22 -1
  54. package/dist/crowdy-studio/mount.d.ts.map +1 -1
  55. package/dist/crowdy-studio/mount.js +163 -2
  56. package/dist/crowdy-studio/styles.d.ts +1 -1
  57. package/dist/crowdy-studio/styles.d.ts.map +1 -1
  58. package/dist/crowdy-studio/styles.js +5 -3
  59. package/dist/generated/graphql.d.ts +3753 -1
  60. package/dist/generated/graphql.d.ts.map +1 -1
  61. package/dist/generated/graphql.js +296 -0
  62. package/dist/index.d.ts +1 -1
  63. package/dist/index.js +1 -1
  64. package/dist/kit/npcs.d.ts.map +1 -1
  65. package/dist/kit/social.d.ts.map +1 -1
  66. package/dist/player-host/index.d.ts +5 -0
  67. package/dist/player-host/index.d.ts.map +1 -0
  68. package/dist/player-host/index.js +3 -0
  69. package/dist/player-host/lease-manager.d.ts +66 -0
  70. package/dist/player-host/lease-manager.d.ts.map +1 -0
  71. package/dist/player-host/lease-manager.js +428 -0
  72. package/dist/player-host/schemas.d.ts +9 -0
  73. package/dist/player-host/schemas.d.ts.map +1 -0
  74. package/dist/player-host/schemas.js +347 -0
  75. package/dist/player-host/tools.d.ts +13 -0
  76. package/dist/player-host/tools.d.ts.map +1 -0
  77. package/dist/player-host/tools.js +79 -0
  78. package/dist/player-host/types.d.ts +203 -0
  79. package/dist/player-host/types.d.ts.map +1 -0
  80. package/dist/player-host/types.js +1 -0
  81. package/package.json +12 -2
package/MIGRATION.md CHANGED
@@ -1,3 +1,121 @@
1
+ # CrowdyJS v12 — Agentic Crowdy Studio contract (BREAKING)
2
+
3
+ Version 12 establishes the greenfield public contracts
4
+ `crowdy.studio-agent/1`, `crowdy.agent-tools/1`, and
5
+ `crowdy.player-host/1`. The major bump reserves their authority, event,
6
+ descriptor, and browser-control semantics before rollout; changing those
7
+ semantics later requires another major contract version.
8
+
9
+ New package subpaths:
10
+
11
+ - `@crowdedkingdoms/crowdyjs/agent` — immutable descriptor registry, bounded
12
+ JSON-schema validator, stable errors, injectable durable transport,
13
+ ordered/reconnecting session controller, exact approvals, and execute-once
14
+ browser dispatch.
15
+ - `@crowdedkingdoms/crowdyjs/player-host` — generic host capability,
16
+ observation, command, and result contracts plus the revocable Play lease
17
+ manager/gate.
18
+ - `@crowdedkingdoms/crowdyjs/crowdy-studio` re-exports both surfaces and adds
19
+ the integrated Ask/Build/Play dock.
20
+
21
+ The reconciled Game API SDL and generated agent operations are now committed.
22
+ `client.crowdyStudioAgent` is a production `CrowdyAgentGraphQLTransport`
23
+ implementing every `CrowdyStudioAgentTransportV1` query, Relay connection,
24
+ mutation, heartbeat, and typed event subscription. Tests and non-GraphQL hosts
25
+ may still inject the interface; do not add a generic raw-GraphQL callback.
26
+
27
+ Creation now carries optional `providerDataConsent`; attach carries a stable
28
+ `clientInstanceId` and consumes `replayAfterSeq`; the public transport
29
+ `message` maps to Game API `content`; cancellation requires the exact run id;
30
+ and nested browser results map to `AgentToolResultEnvelopeInput`. PLAY sends a
31
+ two-second heartbeat only while attached, active, and visible, stopping and
32
+ clearing local authority on pause, disconnect, stale epoch, kill, or destroy.
33
+ Descriptor builds verify the full registry and canonical 28-tool Game API
34
+ follow-up subset (14 mandatory game plus 14 Studio/diagnostic/runtime tools)
35
+ against the copied digest fixture.
36
+
37
+ Mode changes now consume the server-repinned registry/policy/context fields.
38
+ BUILD mounts derive `projectId` from the selected saved Studio project after
39
+ initialization; callers should no longer guess it. An existing session for a
40
+ different project fails closed, and project switches require a new session
41
+ until Game API adds an explicit set-project mutation.
42
+
43
+ BUILD workspace leases renew every ten seconds through agent heartbeat and
44
+ stop on human edit, project/context change, revocation, disconnect, or destroy.
45
+ Backend-advertised draft/live/stop/invoke tools execute through the headless
46
+ Studio controller, with exact approval for live work. Run events now preserve
47
+ typed code/error details, aborted handlers clear local intent, and inner
48
+ `OUTCOME_UNKNOWN` can no longer be wrapped as outer success.
49
+
50
+ Runtime draft/live calls now require an exact full-project target plan. Live
51
+ execution also binds the post-autosave revision, content/module hash, and
52
+ pairing preference; mismatches fail before any compile/deploy. Invoke verifies
53
+ the running DRAFT/LIVE environment and export, while stop remains an
54
+ all-project safety action.
55
+
56
+ Existing manual mounts continue to work:
57
+
58
+ ```ts
59
+ await mountCrowdyStudio(host, existingOptions);
60
+ ```
61
+
62
+ To enable the agent dock, inject the transport and either an existing session
63
+ or create-session input:
64
+
65
+ ```ts
66
+ await mountCrowdyStudio(host, {
67
+ ...existingOptions,
68
+ agent: {
69
+ transport: game.crowdyStudioAgent,
70
+ sessionId,
71
+ playerHost, // optional; required for generic Play tools
72
+ },
73
+ });
74
+ ```
75
+
76
+ `CrowdyStudioHandle` now exposes `agent` and `controlLeaseManager` (both `null`
77
+ when agent mode is not configured). `CrowdyStudioController.testDraft()` and
78
+ `deployLive()` now resolve typed `CrowdyStudioDeployResult` values; code that
79
+ ignored their previous `void` result remains valid.
80
+
81
+ Headless integrations should adopt:
82
+
83
+ - `prepareForAgentWork()` before sending a turn;
84
+ - `applyAtomicPatch()` / `synchronizeProject()` for complete revision-fenced
85
+ project updates;
86
+ - `CrowdyStudioSynchronizationProvider` for durable checkpoint list, atomic
87
+ patch, and approved restore hooks;
88
+ - `state.runtimeSync` instead of inferring saved-versus-running status from the
89
+ display phase.
90
+
91
+ Game integrations implement `PlayerHostAdapterV1`, route commands through the
92
+ same intent services as human input, and call
93
+ `AgentControlLeaseManager.preempt(reason)` synchronously on human input,
94
+ Escape, Stop, death, disconnect, or context/target changes. Do not adapt the
95
+ agent through DOM events, raw UDP/GraphQL/CrowdyJS methods,
96
+ `PlayerCodeBroker`, or client-mod `host_call`.
97
+
98
+ The current Game API pilot advertises its canonical 28-tool follow-up subset,
99
+ including all 14 mandatory game tools. CrowdyJS dispatches the game tools
100
+ through `PlayerHostAdapterV1`;
101
+ BWF Play still requires the concrete BWF adapter/shared-intent integration and
102
+ matching host/app policy.
103
+
104
+ The browser package contains no provider client or key. Provider routing,
105
+ policy, budgets, durable approvals, and server tools remain Game API
106
+ responsibilities.
107
+
108
+ # CrowdyJS v11.1 — responsive Crowdy Studio embedding
109
+
110
+ Crowdy Studio now sizes to its host instead of imposing a 680-pixel minimum
111
+ height. The mount observes host element resizes and relayouts Monaco, while its
112
+ explorer and settings panes respond to the host's container width rather than
113
+ the browser viewport.
114
+
115
+ Embedding hosts should provide an explicit width and height for the mount
116
+ element. No project, autosave, deploy, pairing, worker-security, or GraphQL
117
+ behavior changed.
118
+
1
119
  # CrowdyJS v11 — Crowdy Studio rename (BREAKING)
2
120
 
3
121
  Version 11 removes the previous Mod Studio names completely. There are no
package/README.md CHANGED
@@ -12,6 +12,21 @@ npm install @crowdedkingdoms/crowdyjs
12
12
 
13
13
  CrowdyJS v4 targets browsers by default and uses native `fetch`, `WebSocket`, `crypto`, `btoa`, and `atob`. Node tools can still use the SDK, but must provide browser-compatible globals when opening realtime connections.
14
14
 
15
+ > **CrowdyJS v12 (breaking): Agentic Crowdy Studio.** v12 adds the accepted
16
+ > `crowdy.studio-agent/1`, `crowdy.agent-tools/1`, and
17
+ > `crowdy.player-host/1` browser contracts. Import the provider-neutral durable
18
+ > client and immutable tool registry from
19
+ > `@crowdedkingdoms/crowdyjs/agent`, and generic game observations/control from
20
+ > `@crowdedkingdoms/crowdyjs/player-host`. Crowdy Studio can mount the
21
+ > integrated Ask/Build/Play dock when given an injectable agent transport.
22
+ > There is deliberately no OpenRouter key/client, raw GraphQL executor, DOM
23
+ > driver, `fetch`, shell, unrestricted SDK bridge, or client-mod `host_call` in
24
+ > these surfaces. The reconciled Game API SDL, generated operations, and
25
+ > production `CrowdyAgentGraphQLTransport` are included and exposed as
26
+ > `client.crowdyStudioAgent`; tests may still inject
27
+ > `CrowdyStudioAgentTransportV1`. Existing manual Studio mounting remains
28
+ > unchanged when `agent` is omitted.
29
+ >
15
30
  > **Server compatibility (v8.13):** v8.13 adds the **flow-correlation surface**: `gameModel.flow({ appId, flowId })` stitches one flow correlation id into a single cross-engine timeline (model events + automation runs + compute module runs, each time-ascending), and the default event/run fragments now select the nullable `flowId` field on `GmEvent` / `GmAutomationRun` / `WasmModuleRun`. Both require the 2026-07-19 `cks-game-api` dev line (the `2026-07-19-compute-fleet-hardening` migration for the columns and the `gameModelFlow` query for the timeline); older servers reject the operations with a GraphQL validation error, and everything else keeps working. `gameModel.flow` requires the app-admin `manage_apps` permission (it is a diagnostics surface). v8.13 also extends the kit invoke helpers' gameplay-verdict mapping: the typed invoke-contract violation `computeInvoke` raises (`BAD_REQUEST` with an "Invoke params violate ..." message, game-api 2026-07-19+) now maps onto `{ success: false, errorMessage }` (`kitInvoke`) / `{ success: false, reason }` (engine invokes) instead of throwing — see the exported `isKitVerdictError` predicate.
16
31
  >
17
32
  > **Server compatibility:** v8.12's **container query predicates** (`where`/`limit`/`offset` on `gameModel.containers`), **automation compute actions** (`actionKind: 'compute_invoke'` with `computeModuleName`/`computeExport` on `gameModel.upsertAutomation`; `property_changed` events additionally carry `oldValue`/`newValue` to compute modules), **container-change push** (`gameModel.containerChanged` — metadata-only pull-on-push over graphql-transport-ws; on Node ≤ 21 pass `webSocketImpl`), and **invoke-trigger contracts** (`contractJson` on `compute.upsertTrigger`/`moduleTriggers`, validated server-side pre-sandbox) require the 2026-07 `cks-game-api` dev line with the `2026-07-19-automation-compute-action` migration; older servers reject the new arguments/fields (omit them and everything else keeps working). (npm 8.11.0 is a partial cut of this surface — prefer 8.12.0.) v8.12 also adds the `runOptimisticAction` kit helper (client-only: the packaged optimistic apply → referee invoke → confirm/rollback loop with actionId receipts). v5.2+ targets environments on release **v0.1.19 or later** (`cks-game-api >= v0.10.3`, `cks-management-api >= v0.1.70`). The destructive mutations send an `idempotencyKey` argument that older servers don't define. v6.1's `client.gameApps.deleteGrid` additionally requires release **v0.1.33+** (`cks-game-api >= v0.12.3`). The game-model **permission effects** fields (`permissionEffects` on `gameModel.upsertFunction`/`seed`, `permissionEffectsAppliedJson` on events) require a `cks-game-api` build with the `2026-07-17-model-permission-effects` migration (v0.13.11+); older servers reject queries/mutations that include them (omit the fields and everything else keeps working). The **permission-read** surface (the `has_grid_permission`/`grid_at`/`has_chunk_permission` expression builtins the kit's `chunkPermission` locks compile to, and selector `*PermissionWhere` predicates) additionally requires `cks-game-api` **v0.13.12+**. Older `cks-game-api` builds report game-model **invoke policy denials** as `FORBIDDEN` GraphQL errors instead of resolving with `success: false`; as of this version the kit's invoke helpers map that error onto the documented `{ success: false, errorMessage }` result, so kit callers behave identically against both server generations. v8.6's **`client.compute`** (Compute Modules — server-side Rust/WASM logic) requires a `cks-game-api` build with the compute surface (the `compute*` root fields, v0.13.13+ dev line); older servers reject these operations with a GraphQL validation error, and everything else keeps working. v8.9's **realtime + live-ops surfaces** (`kit.abilities`/`movement`/`territory`/`racing`/`liveops`/`moderation`/`telemetry`, the loot engine path, `client.compute.deployTemplate` + `kit.deploy({engines})`, and the type-94..98 event parsers) complete the 30-abstraction catalog; v8.8's **session-genre engine surfaces** (`kit.instances`/`director`/`matchmaking`/`minigames`, the engine paths on matches/decks/leaderboards, `economy.orderBook`, and the type-91/92/93 event parsers) talk to the Wave 2 engine templates; capability detection keeps model-only deployments on today's behavior. v8.7's **engine kit surfaces** (`kit.mobs`, `kit.pets`, `kit.combat.attackRouted`, `kit.worldsim.forecast`, and the `kit/wire` pose/lane registry) talk to compute-module game engines built on the Wave 0/1 `cks-game-api` dev line (`crowdy-game-kit` crates); capability detection makes them degrade gracefully — model-only deployments keep today's behavior.
@@ -144,6 +159,7 @@ If `managementUrl` is omitted, the SDK falls back to `httpUrl` for backwards-com
144
159
  | `client.compute` | **Compute Modules** — server-side Rust/WASM logic: author + deploy source (`upsertModule`, `deployVersion`, `waitForCompile`), triggers + policy, synchronous `invoke`, and monitoring (`moduleRuns`, `moduleStats`, `moduleLogs`, `appDiagnostics`). Modules run server-only; see [Compute Modules docs](https://docs.crowdedkingdoms.com/game-api/compute-modules). |
145
160
  | `client.playerCompute` | Player-authored SERVER/CLIENT Rust/WASM bound to player-owned grids: deploy source, activate/deactivate, list modules/versions, and delete self-authored modules. |
146
161
  | `client.crowdyStudio` | Cloud project, personal-library, and common-file APIs for Crowdy Studio: target-scoped files, metadata/module names, pairing preference, optimistic revisions, copy-by-value imports, and atomic metadata/file saves. Generated operations are pinned to the committed merged SDL. |
162
+ | `client.crowdyStudioAgent` | Generated, app-token Game API transport for durable agent sessions, Relay history/session pages, descriptors/budgets, exact approvals, browser tool results, heartbeat, control mutations, and ordered event subscriptions. |
147
163
  | `client.playerModel` | Player-owned flexible model containers and grid-confined automations (`containers`, `createContainer`, `setProperty`, `automations`, `createAutomation`, …). |
148
164
  | `client.marketplace` | Player-code store/install/consent flows plus player-authorized grid claims: `claimGridOwnership` preserves the existing-grid policy flow, while `claimGridChunk` atomically creates and owns one chunk under `SELF_CLAIM` and `releaseClaimedGrid` releases an eligible owner-created claim. |
149
165
  | `client.udp` | UDP proxy subscriptions + spatial mutations (`sendActorUpdate`, `sendVoxelUpdate`, `sendAudioPacket`, `sendTextPacket`, `sendClientEvent`). |
@@ -166,6 +182,11 @@ server/client module names, and a pairing preference. Full-stack edits autosave
166
182
  as one optimistic-concurrency write; the UI renders **Saving**, **Saved**,
167
183
  **Conflict**, or **Offline**, with retry and conflict-resolution actions.
168
184
 
185
+ The mount fills its host and observes host element resizes, so games can embed
186
+ it in draggable docks or split panes without manually relaying window resize
187
+ events. Give the host an explicit width and height; Crowdy Studio relayouts
188
+ Monaco and collapses secondary panes from its own container width.
189
+
169
190
  ```ts
170
191
  import { mountCrowdyStudio } from '@crowdedkingdoms/crowdyjs/crowdy-studio';
171
192
 
@@ -243,6 +264,193 @@ presentation enum to Crowdy Studio's runtime-oriented project kind and
243
264
  `CrowdyStudioRevisionConflictError` with the latest cloud project when that
244
265
  follow-up read succeeds.
245
266
 
267
+ ### Agent SDK, transport, and integrated dock (v12)
268
+
269
+ The v12 agent API remains provider-neutral, while CrowdyJS now ships generated
270
+ operations plus the production `CrowdyAgentGraphQLTransport` exposed as
271
+ `client.crowdyStudioAgent`:
272
+
273
+ ```ts
274
+ import {
275
+ CROWDY_AGENT_TOOL_REGISTRY_V1,
276
+ CrowdyStudioAgentController,
277
+ } from '@crowdedkingdoms/crowdyjs/agent';
278
+
279
+ const agent = new CrowdyStudioAgentController({
280
+ transport: game.crowdyStudioAgent,
281
+ createSession: {
282
+ appId,
283
+ projectId,
284
+ gridId,
285
+ mode: 'BUILD',
286
+ providerDataConsent: true,
287
+ idempotencyKey: crypto.randomUUID(),
288
+ },
289
+ beforeAgentWork: () => studio.controller.prepareForAgentWork(),
290
+ });
291
+ await agent.initialize(); // attach epoch → durable replay/gap fill → live tail
292
+ ```
293
+
294
+ `CROWDY_AGENT_TOOL_REGISTRY_V1` is an immutable, digest-pinned registry of the
295
+ minimum Studio/project/workspace/library/template/diagnostics/runtime and
296
+ generic game tools. Every descriptor has exact logical and provider wire names,
297
+ semantic version, bounded input/output JSON schemas,
298
+ `additionalProperties:false`, executor, mode, risk/effect/reversibility,
299
+ scope, approval, idempotency, timeout, and redaction metadata. Input schemas
300
+ reject caller-supplied identity, epoch, lease, approval, endpoint, token, and
301
+ other authority fields. `CrowdyAgentToolRegistry.fromWireName` is exact and
302
+ case-sensitive; browser dispatch is execute-once by `toolCallId`, and ambiguous
303
+ effects become `OUTCOME_UNKNOWN` instead of being repeated.
304
+
305
+ `CrowdyStudioAgentTransportV1` owns no credentials and exposes only typed
306
+ durable orchestration operations: session/history/descriptor/budget queries;
307
+ create/attach/mode/event-ack/message/approval/tool-result/lease/pause/resume/
308
+ cancel/close mutations; and the ordered event subscription. A generated adapter
309
+ maps these methods to the operation names in
310
+ `CROWDY_AGENT_GRAPHQL_OPERATIONS_V1`:
311
+
312
+ - `crowdyStudioAgentSession`, `crowdyStudioAgentSessions`,
313
+ `crowdyStudioAgentHistory`, `crowdyStudioAgentToolDescriptors`, and
314
+ `crowdyStudioAgentBudget`;
315
+ - `crowdyStudioAgentCreateSession`, `AttachClient`, `SetMode`,
316
+ `AcknowledgeEvents`, `Heartbeat`, `SendMessage`, `ApproveTool`, `RejectTool`,
317
+ `ToolResult`, `GrantLease`, `RevokeLease`, `Pause`, `Resume`, `CancelRun`,
318
+ and `CloseSession` (all with the `crowdyStudioAgent` prefix);
319
+ - `crowdyStudioAgentEvents(sessionId, afterSeq, clientEpoch)`.
320
+
321
+ The controller applies only contiguous decimal-string sequences, deduplicates
322
+ event IDs, fills gaps from durable history, acknowledges the highest
323
+ contiguous cursor, fences old attach epochs, and explicitly reconnects without
324
+ resuming a run or Play lease. Approval methods use the exact displayed argument
325
+ hash. Human edit/game input calls local preemption before best-effort transport
326
+ cleanup. Attach uses a stable `clientInstanceId` and the server
327
+ `replayAfterSeq`; public message input maps to Game API `content`, cancellation
328
+ always sends an explicit run id, and PLAY sends a two-second heartbeat only
329
+ while attached, active, and visible. Heartbeat, kill, and stale-epoch failures
330
+ immediately clear local authority.
331
+
332
+ Mode changes adopt the complete server-repinned session (registry digest,
333
+ provider/app policy revisions, and context version) before loading its new
334
+ effective descriptors. The Studio mount resolves the selected saved project
335
+ after `CrowdyStudioController.initialize()`, overrides caller guesses when
336
+ creating a BUILD session, and rejects an existing session bound to another
337
+ project. Because v1 has no set-project mutation, switching projects fences the
338
+ agent and requires a new session/remount.
339
+
340
+ An active BUILD workspace lease is renewed every ten seconds through the same
341
+ authenticated heartbeat; the server returns its renewed 30-second expiry.
342
+ Human edits, project/context changes, lease revocation, disconnect, and destroy
343
+ stop renewal and abort browser handlers. Run events retain their stable
344
+ `code`, `reason`, and typed safe `error`.
345
+
346
+ The committed descriptor digest fixture is checked on every build against the
347
+ canonical registry. Coordinated refreshes first run
348
+ `npm run agent-descriptors:drift -- --source <game-api-fixture>`; builds then
349
+ recompute the full and canonical 28-tool Game API subset digest (14 mandatory
350
+ game plus 14 Studio/diagnostic/runtime tools) so the fixture cannot silently
351
+ diverge.
352
+
353
+ Mount the responsive agent dock by adding `agent`; omit it to retain the v11
354
+ manual UI unchanged:
355
+
356
+ ```ts
357
+ const studio = await mountCrowdyStudio(host, {
358
+ projectProvider: game.crowdyStudio,
359
+ playerCompute: game.playerCompute,
360
+ appId,
361
+ gridId,
362
+ agent: {
363
+ transport: game.crowdyStudioAgent,
364
+ sessionId,
365
+ playerHost: bwfPlayerHostAdapter,
366
+ },
367
+ });
368
+
369
+ studio.agent?.sendMessage('Explain the current diagnostics');
370
+ studio.controlLeaseManager?.preempt('HUMAN_INPUT');
371
+ ```
372
+
373
+ The dock provides human-owned Ask/Build/Play selection, chat streaming,
374
+ plan/tool status, exact approval hashes, diff/checkpoint cards, budget, visible
375
+ lease scope/expiry, Pause/Resume/Stop, and checkpoint-restore requests. It uses
376
+ text nodes for all untrusted content, ARIA status/log/group labels, visible
377
+ focus, keyboard submission, and a container-query layout that moves the agent
378
+ dock below narrow embeds.
379
+
380
+ The headless `CrowdyStudioController` now also exposes:
381
+
382
+ - `prepareForAgentWork()` to flush autosave and fail closed on conflict/offline;
383
+ - `applyAtomicPatch()` and `synchronizeProject()` for all-or-none multi-file
384
+ updates, human-edit preemption, and Monaco synchronization;
385
+ - `refreshCheckpoints()` / `restoreCheckpoint()` through the optional
386
+ transport-neutral `CrowdyStudioSynchronizationProvider` (the provider is
387
+ required for agent writes/restores and must make checkpoint + revision
388
+ changes durable and atomic);
389
+ - typed draft/live results plus `runtimeSync` (`RUNNING_SAVED`,
390
+ `RUNNING_STALE`, `STOPPED`, or `NEVER_RUN`).
391
+
392
+ ### PlayerHostAdapter and Blocks with Friends integration
393
+
394
+ `@crowdedkingdoms/crowdyjs/player-host` exports
395
+ `PlayerHostAdapterV1`, capability/observation/command/result types and schemas,
396
+ `AgentControlLeaseManager`, and `createPlayerHostAgentTools`. A game adapter
397
+ implements only:
398
+
399
+ ```ts
400
+ interface PlayerHostAdapterV1 {
401
+ readonly contractVersion: 'crowdy.player-host/1';
402
+ capabilities(): Promise<PlayerHostCapabilitiesV1>;
403
+ observe(request: ObserveRequestV1): Promise<GameObservationV1>;
404
+ dispatch(command: GameCommandV1, gate: ValidatedGateV1):
405
+ Promise<GameCommandResultV1>;
406
+ clearAgentIntent(reason: CrowdyAgentPreemptionReason): void;
407
+ }
408
+ ```
409
+
410
+ For Blocks with Friends, implement this interface over the same typed intent
411
+ methods used by `PlayerController`, `ActionService`, `InventoryService`,
412
+ `FishingService`, `RideService`, and existing referee/model calls. Construct
413
+ `createPlayerHostAgentTools(adapter)` and pass `adapter` as the mount's
414
+ `playerHost`. The returned lease manager enforces TTL, scopes, client epoch,
415
+ host/controlled-entity revision, observation freshness, modal/death state,
416
+ per-command rate limits, approvals, and tool-call dedup. Call
417
+ `leaseManager.preempt('HUMAN_INPUT')` synchronously on key/mouse/touch input,
418
+ `ESCAPE` on Escape, and the corresponding reason on death, target/context
419
+ change, disconnect, or Stop. `clearAgentIntent` must immediately zero movement,
420
+ look, and pending action intent. BWF does not integrate through raw CrowdyJS,
421
+ DOM input, UDP packets, `PlayerCodeBroker`, or client-mod host calls.
422
+
423
+ BWF should pass only `game.crowdyStudioAgent` and its
424
+ `BwfPlayerHostAdapter` to the Studio mount; the mount derives the selected
425
+ project id. Its adapter must implement the exact 14 mandatory game surfaces,
426
+ classify combat as conditional approval, return typed failed/denied/unknown
427
+ outcomes, and make `clearAgentIntent` synchronously cancel shared movement and
428
+ action intents when the dispatcher aborts.
429
+
430
+ The reconciled Game API development pilot advertises the exact 28-tool
431
+ follow-up subset, including all 14 mandatory game descriptors. CrowdyJS routes
432
+ all game tools through
433
+ `PlayerHostAdapterV1`, the scoped lease gate, conditional combat approval,
434
+ safety stop, heartbeat fencing, and typed result continuation. BWF Play now
435
+ remains blocked only on the concrete BWF adapter/shared-intent wiring and its
436
+ host/app policy configuration.
437
+
438
+ The same browser dispatcher routes backend-advertised `runtime.test_draft`,
439
+ `runtime.deploy_live`, `runtime.invoke`, and `runtime.stop` through the
440
+ headless Studio controller. Draft testing is routine BUILD work; live deploy
441
+ and LIVE invoke require the exact approval grant; stop remains an idempotent
442
+ safety action. Inner game `FAILED`, `DENIED`, or `OUTCOME_UNKNOWN` results are
443
+ promoted to matching outer terminal tool results and are never reported as
444
+ successful.
445
+
446
+ Runtime execution is plan-bound: requested targets must exactly equal the
447
+ selected project’s authoritative target set, so a full-stack project cannot run
448
+ CLIENT after SERVER-only authorization. Live deploy additionally rechecks the
449
+ saved revision, canonical project content hash (including module names/files),
450
+ and pairing preference after autosave. Invoke checks the exact running
451
+ DRAFT/LIVE environment and export; stop always stops the complete selected
452
+ project as a safety action rather than interpreting a partial target.
453
+
246
454
  | `createWorldSession(client, appId, config)` (from `@crowdedkingdoms/crowdyjs/stores`) | World Stores: opt-in, SDK-managed game state — typed codecs (`structCodec` binary DSL), your own actor with a 5 Hz send loop (`session.self`), a remote-actor registry with lanes/history/staleness (`session.actors`), attributed send errors (`session.errors`), a chunk/voxel cache with realtime merge + worldgen write-back (`session.chunks`), channel/direct-message inboxes + a typed event router, host tracking, typed save/avatar state, and a game-model container mirror. Only configured stores exist (compile-time + runtime); unimported stores tree-shake away. |
247
455
  | `client.kit(appId)` | Game Kit: ready-made mappings of game concepts onto the game model — `kit.inventory`, `kit.objects` (lockable doors/chests with custom permissions), `kit.npcs`, `kit.plots` (buy/rent land with transactional, replication-enforced grid grants), and the genre layers `kit.economy` (wallets/shops/trades/market), `kit.progression` (xp/skills/achievements/rating), `kit.loot`, `kit.quests`, `kit.combat`, `kit.matches` (session lobbies/turns/scores with notify-to-pull channels), `kit.decks` (hidden hands), `kit.worldsim` (clock/nodes/crops/waves), `kit.social` (parties/guilds/chat over teams+channels), `kit.leaderboards`, `kit.features` (tier gates), and the engine-aware helpers `kit.mobs` (refereed attacks, defs/slots, contact-damage parsing), `kit.pets` (adopt/summon/dismiss/rename), `kit.instances` (private world slices, seeded runs), `kit.director` (encounter runs), `kit.matchmaking` (queues/proposals/rating), `kit.minigames` (invoke-loop wrapper), `kit.economy.orderBook` (escrowed bid/ask market), engine paths on `kit.matches`/`kit.decks`/`kit.leaderboards`, `kit.quests` tutorial sequencing, `kit.engines` (compute capability detection) with `kit/wire` (the engine pose codec, `engineLanes()`, and the 77/90/91/92/93 event parsers) — plus blueprint builders + `kit.deploy(...)` for the admin "load the rules" step. |
248
456
 
@@ -0,0 +1,41 @@
1
+ import type { CrowdyAgentMode, CrowdyAgentToolInvocationV1, CrowdyAgentToolResultV1 } from './types.js';
2
+ import { CrowdyAgentToolRegistry } from './registry.js';
3
+ export interface CrowdyAgentBrowserToolContextV1 {
4
+ readonly invocation: CrowdyAgentToolInvocationV1;
5
+ readonly signal: AbortSignal;
6
+ }
7
+ export type CrowdyAgentBrowserToolHandlerV1 = (argumentsValue: Readonly<Record<string, unknown>>, context: CrowdyAgentBrowserToolContextV1) => unknown | Promise<unknown>;
8
+ export type CrowdyAgentBrowserToolHandlersV1 = Readonly<Record<string, CrowdyAgentBrowserToolHandlerV1>>;
9
+ export interface CrowdyAgentBrowserDispatcherOptionsV1 {
10
+ readonly registry: CrowdyAgentToolRegistry;
11
+ readonly handlers: CrowdyAgentBrowserToolHandlersV1;
12
+ readonly getSessionId?: () => string | null;
13
+ readonly getClientEpoch: () => string | null;
14
+ readonly getContextVersion: () => string;
15
+ readonly getMode?: () => CrowdyAgentMode;
16
+ readonly now?: () => number;
17
+ readonly maxRememberedCalls?: number;
18
+ }
19
+ /**
20
+ * Exact browser tool router with execute-once semantics. It has no fallback
21
+ * executor: unknown names, raw SDK access, and missing handlers fail closed.
22
+ */
23
+ export declare class CrowdyAgentBrowserToolDispatcher {
24
+ private readonly options;
25
+ private readonly records;
26
+ private readonly active;
27
+ private readonly now;
28
+ constructor(options: CrowdyAgentBrowserDispatcherOptionsV1);
29
+ dispatch(invocation: CrowdyAgentToolInvocationV1): Promise<CrowdyAgentToolResultV1>;
30
+ has(toolCallId: string): boolean;
31
+ /** Abort pending browser work during human or context preemption. */
32
+ cancelActive(): void;
33
+ /**
34
+ * Cache lifetime is the attached session. Call only after that session is
35
+ * closed or fenced; clearing during a live session could repeat an effect.
36
+ */
37
+ clearClosedSession(): void;
38
+ private execute;
39
+ private validateEnvelope;
40
+ }
41
+ //# sourceMappingURL=browser-dispatcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-dispatcher.d.ts","sourceRoot":"","sources":["../../src/crowdy-agent/browser-dispatcher.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,eAAe,EACf,2BAA2B,EAC3B,uBAAuB,EACxB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAExD,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,UAAU,EAAE,2BAA2B,CAAC;IACjD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAED,MAAM,MAAM,+BAA+B,GAAG,CAC5C,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACjD,OAAO,EAAE,+BAA+B,KACrC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC,MAAM,MAAM,gCAAgC,GAAG,QAAQ,CACrD,MAAM,CAAC,MAAM,EAAE,+BAA+B,CAAC,CAChD,CAAC;AAEF,MAAM,WAAW,qCAAqC;IACpD,QAAQ,CAAC,QAAQ,EAAE,uBAAuB,CAAC;IAC3C,QAAQ,CAAC,QAAQ,EAAE,gCAAgC,CAAC;IACpD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC5C,QAAQ,CAAC,cAAc,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC7C,QAAQ,CAAC,iBAAiB,EAAE,MAAM,MAAM,CAAC;IACzC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,eAAe,CAAC;IACzC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACtC;AAOD;;;GAGG;AACH,qBAAa,gCAAgC;IAK/B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAC7D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsC;IAC7D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;gBAEN,OAAO,EAAE,qCAAqC;IAe3E,QAAQ,CACN,UAAU,EAAE,2BAA2B,GACtC,OAAO,CAAC,uBAAuB,CAAC;IA6CnC,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAIhC,qEAAqE;IACrE,YAAY,IAAI,IAAI;IAIpB;;;OAGG;IACH,kBAAkB,IAAI,IAAI;YAKZ,OAAO;IA6IrB,OAAO,CAAC,gBAAgB;CAyFzB"}