@vibecook/ice 0.6.0 → 0.8.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 (69) hide show
  1. package/dist/{chunk-BFT7YWS2.js → chunk-3SUDKHUF.js} +3 -3
  2. package/dist/{chunk-JLXETATP.js → chunk-BE4F4X3Q.js} +485 -77
  3. package/dist/chunk-BE4F4X3Q.js.map +1 -0
  4. package/dist/{chunk-ELCBCTKY.js → chunk-CBCSIEXW.js} +2 -2
  5. package/dist/devtools.js +1 -1
  6. package/dist/dom.js +2 -2
  7. package/dist/ground.js +1 -1
  8. package/dist/index.js +3 -1
  9. package/dist/r3f.js +3 -3
  10. package/dist/react.js +3 -3
  11. package/dist/types/packages/core/src/behavior/define-behavior.d.ts +2 -1
  12. package/dist/types/packages/core/src/behavior/runtime.d.ts +16 -2
  13. package/dist/types/packages/core/src/behavior/types.d.ts +47 -1
  14. package/dist/types/packages/core/src/engine/guests.d.ts +5 -2
  15. package/dist/types/packages/core/src/facade/create-canvas-engine.d.ts +38 -6
  16. package/dist/types/packages/core/src/index.d.ts +4 -3
  17. package/dist/types/packages/core/src/interaction/install.d.ts +1 -1
  18. package/dist/types/packages/core/src/nav/nested-canvas.d.ts +1 -1
  19. package/dist/types/packages/core/src/ops/point-pick.d.ts +1 -1
  20. package/dist/types/packages/core/src/ops/port-geometry.d.ts +1 -1
  21. package/dist/types/packages/core/src/presence/presence-kit.d.ts +11 -0
  22. package/dist/types/packages/core/src/presence/remote-cursors.d.ts +10 -7
  23. package/dist/types/packages/core/src/systems/l1-pick.d.ts +1 -1
  24. package/dist/types/packages/core/src/systems/l1-wires.d.ts +1 -1
  25. package/dist/types/packages/core/src/systems/l3-connect.d.ts +1 -1
  26. package/dist/types/packages/core/src/systems/l3-drop.d.ts +1 -1
  27. package/dist/types/packages/core/src/systems/l3-marquee.d.ts +1 -1
  28. package/dist/types/packages/core/src/systems/l3-ports.d.ts +1 -1
  29. package/dist/types/packages/core/src/systems/l3-snap.d.ts +1 -1
  30. package/dist/types/packages/core/src/systems/nav-flight.d.ts +1 -1
  31. package/dist/types/packages/devtools/src/attach.d.ts +1 -1
  32. package/dist/types/packages/dom/src/loop.d.ts +1 -1
  33. package/dist/types/packages/dom/src/measure-adapter.d.ts +1 -1
  34. package/dist/types/packages/dom/src/measure-wiring.d.ts +1 -1
  35. package/dist/types/packages/dom/src/pointer-adapter.d.ts +1 -1
  36. package/dist/types/packages/dom/src/reflectors/chrome.d.ts +1 -1
  37. package/dist/types/packages/dom/src/reflectors/cursor.d.ts +1 -1
  38. package/dist/types/packages/dom/src/reflectors/dom-widgets.d.ts +1 -1
  39. package/dist/types/packages/dom/src/reflectors/graybox.d.ts +1 -1
  40. package/dist/types/packages/dom/src/reflectors/plane-transform.d.ts +1 -1
  41. package/dist/types/packages/dom/src/reflectors/remote-cursors.d.ts +1 -1
  42. package/dist/types/packages/dom/src/widget-focus.d.ts +1 -1
  43. package/dist/types/packages/ground/src/index.d.ts +2 -2
  44. package/dist/types/packages/ground/src/layer.d.ts +1 -1
  45. package/dist/types/packages/ground/src/pass.d.ts +1 -1
  46. package/dist/types/packages/ground/src/passes/grid.d.ts +1 -1
  47. package/dist/types/packages/ground/src/passes/guides-collect.d.ts +1 -1
  48. package/dist/types/packages/ground/src/passes/guides.d.ts +1 -1
  49. package/dist/types/packages/ground/src/passes/wires-collect.d.ts +1 -1
  50. package/dist/types/packages/ground/src/passes/wires.d.ts +1 -1
  51. package/dist/types/packages/r3f/src/bridge.d.ts +1 -1
  52. package/dist/types/packages/r3f/src/compositor-pass.d.ts +1 -1
  53. package/dist/types/packages/r3f/src/dev-write-trap.d.ts +1 -1
  54. package/dist/types/packages/r3f/src/gl-root.d.ts +1 -1
  55. package/dist/types/packages/r3f/src/gl-router.d.ts +2 -2
  56. package/dist/types/packages/r3f/src/island-state.d.ts +1 -1
  57. package/dist/types/packages/r3f/src/island.d.ts +1 -1
  58. package/dist/types/packages/r3f/src/use-island-frame.d.ts +1 -1
  59. package/dist/types/packages/react/src/engine-context.d.ts +1 -1
  60. package/dist/types/packages/react/src/hooks.d.ts +1 -1
  61. package/dist/types/packages/react/src/infinite-canvas.d.ts +2 -2
  62. package/dist/types/packages/react/src/keymap.d.ts +1 -1
  63. package/dist/types/packages/react/src/use-commit.d.ts +1 -1
  64. package/dist/types/packages/react/src/use-presence.d.ts +1 -1
  65. package/dist/types/packages/react/src/widget-root.d.ts +1 -1
  66. package/package.json +2 -2
  67. package/dist/chunk-JLXETATP.js.map +0 -1
  68. /package/dist/{chunk-BFT7YWS2.js.map → chunk-3SUDKHUF.js.map} +0 -0
  69. /package/dist/{chunk-ELCBCTKY.js.map → chunk-CBCSIEXW.js.map} +0 -0
@@ -16,7 +16,7 @@ import {
16
16
  createSiblingOrderIndex,
17
17
  defineQuery,
18
18
  widgets
19
- } from "./chunk-JLXETATP.js";
19
+ } from "./chunk-BE4F4X3Q.js";
20
20
  import {
21
21
  planeCssTransform,
22
22
  worldToScreen
@@ -1160,4 +1160,4 @@ export {
1160
1160
  wireMeasurement,
1161
1161
  DOM_VERSION
1162
1162
  };
1163
- //# sourceMappingURL=chunk-ELCBCTKY.js.map
1163
+ //# sourceMappingURL=chunk-CBCSIEXW.js.map
package/dist/devtools.js CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  WheelPan,
15
15
  WheelZoom,
16
16
  Wire
17
- } from "./chunk-JLXETATP.js";
17
+ } from "./chunk-BE4F4X3Q.js";
18
18
  import "./chunk-OR5FNVUE.js";
19
19
 
20
20
  // ../devtools/src/attach.ts
package/dist/dom.js CHANGED
@@ -19,8 +19,8 @@ import {
19
19
  startRafLoop,
20
20
  wheelCede,
21
21
  wireMeasurement
22
- } from "./chunk-ELCBCTKY.js";
23
- import "./chunk-JLXETATP.js";
22
+ } from "./chunk-CBCSIEXW.js";
23
+ import "./chunk-BE4F4X3Q.js";
24
24
  import "./chunk-OR5FNVUE.js";
25
25
  export {
26
26
  CLAIM_OWNS_ESCAPE,
package/dist/ground.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  defineQuery,
24
24
  portSlots,
25
25
  widgets
26
- } from "./chunk-JLXETATP.js";
26
+ } from "./chunk-BE4F4X3Q.js";
27
27
  import {
28
28
  portAnchor,
29
29
  tessellateCubic,
package/dist/index.js CHANGED
@@ -228,6 +228,7 @@ import {
228
228
  defineTickSystem,
229
229
  defineTool,
230
230
  defineWidget,
231
+ describeBehavior,
231
232
  devGuardsEnabled,
232
233
  distPointToBox,
233
234
  docBehaviorVersion,
@@ -279,7 +280,7 @@ import {
279
280
  widgetSpawnInits,
280
281
  widgets,
281
282
  writeRuntimeResource
282
- } from "./chunk-JLXETATP.js";
283
+ } from "./chunk-BE4F4X3Q.js";
283
284
  import "./chunk-OR5FNVUE.js";
284
285
  export {
285
286
  Accepts,
@@ -511,6 +512,7 @@ export {
511
512
  defineTickSystem,
512
513
  defineTool,
513
514
  defineWidget,
515
+ describeBehavior,
514
516
  devGuardsEnabled,
515
517
  distPointToBox,
516
518
  docBehaviorVersion,
package/dist/r3f.js CHANGED
@@ -2,8 +2,8 @@ import {
2
2
  EngineProvider,
3
3
  hasPreviewSnapshot,
4
4
  setPreviewSnapshot
5
- } from "./chunk-BFT7YWS2.js";
6
- import "./chunk-ELCBCTKY.js";
5
+ } from "./chunk-3SUDKHUF.js";
6
+ import "./chunk-CBCSIEXW.js";
7
7
  import {
8
8
  Active,
9
9
  Camera,
@@ -26,7 +26,7 @@ import {
26
26
  navFlightActive,
27
27
  pickTopAt,
28
28
  widgets
29
- } from "./chunk-JLXETATP.js";
29
+ } from "./chunk-BE4F4X3Q.js";
30
30
  import {
31
31
  compositeCameraFrustum,
32
32
  computeIslandPhase,
package/dist/react.js CHANGED
@@ -25,9 +25,9 @@ import {
25
25
  useWidgetProps,
26
26
  useWorld,
27
27
  useWorldComponent
28
- } from "./chunk-BFT7YWS2.js";
29
- import "./chunk-ELCBCTKY.js";
30
- import "./chunk-JLXETATP.js";
28
+ } from "./chunk-3SUDKHUF.js";
29
+ import "./chunk-CBCSIEXW.js";
30
+ import "./chunk-BE4F4X3Q.js";
31
31
  import "./chunk-OR5FNVUE.js";
32
32
  export {
33
33
  EngineProvider,
@@ -15,7 +15,7 @@
15
15
  * depends on import order is a check that reports differently on a good day.
16
16
  */
17
17
  import type { Component } from "@vibecook/strata-ecs";
18
- import { type AnyBehaviorDef, type BehaviorHandle, type BehaviorRead, type BehaviorSchema, type BehaviorSpec, type BehaviorStore, type DataOf } from "./types";
18
+ import { type AnyBehaviorDef, type BehaviorDescription, type BehaviorHandle, type BehaviorRead, type BehaviorSchema, type BehaviorSpec, type BehaviorStore, type DataOf } from "./types";
19
19
  /**
20
20
  * The generated component's name. Prefixed so a behavior can never collide
21
21
  * with `defineWidget`'s `<type>:<group>` components — and, because this string
@@ -46,6 +46,7 @@ export declare function classifyRead(r: BehaviorRead): {
46
46
  } | undefined;
47
47
  /** The read component a `reads:` entry contributes, if it contributes one. */
48
48
  export declare function readComponentOf(r: BehaviorRead): Component | undefined;
49
+ export declare function describeBehavior(behavior: AnyBehaviorDef): BehaviorDescription;
49
50
  export declare function defineBehavior<const S extends BehaviorStore, const Sch extends BehaviorSchema = BehaviorSchema>(name: string, spec: BehaviorSpec<S, Sch>): BehaviorHandle<DataOf<Sch>>;
50
51
  /**
51
52
  * TEST-ONLY registry wipe (mirrors `__resetPrefabsForTests`; deliberately NOT
@@ -1,5 +1,5 @@
1
1
  import type { Component, Entity, World } from "@vibecook/strata-ecs";
2
- import type { GuestRegistry } from "../engine/guests";
2
+ import type { GuestLedgerRecord, GuestRegistry } from "../engine/guests";
3
3
  import type { PhaseGroup } from "../engine/pipeline";
4
4
  import type { LiveWriter } from "../guards/live-writer";
5
5
  import { type BehaviorMeta } from "./migrate";
@@ -72,10 +72,24 @@ export interface BehaviorStatus {
72
72
  readonly failed: number;
73
73
  readonly ticking: number;
74
74
  readonly suspended: boolean;
75
+ /**
76
+ * The EPHEMERAL singleton was quarantined this generation (I17): its facet
77
+ * is withdrawn and stays withdrawn until a fresh registration. Without this
78
+ * field a quarantined singleton is indistinguishable from a dormant one —
79
+ * withdrawal makes the instance depart, so `failed` reads 0. Always false
80
+ * for durable/runtime behaviors (their quarantine stays visible in `failed`).
81
+ */
82
+ readonly quarantined: boolean;
83
+ }
84
+ export interface BehaviorRegistrationOptions {
85
+ /** Stable host policy key. Explicitly ordered registrations run before unkeyed registrations. */
86
+ readonly orderKey?: string;
87
+ /** Prior breaker state, normally persisted by a host across engine generations. */
88
+ readonly ledger?: GuestLedgerRecord;
75
89
  }
76
90
  export interface BehaviorRuntime {
77
91
  /** Compile + install a behavior. Returns an uninstaller. */
78
- register(b: AnyBehaviorDef): () => void;
92
+ register(b: AnyBehaviorDef, options?: BehaviorRegistrationOptions): () => void;
79
93
  registered(): readonly AnyBehaviorDef[];
80
94
  /** Runtime/ephemeral attach from OUTSIDE a hook (the facade surface). */
81
95
  attach(e: Entity, b: AnyBehaviorDef, data?: Record<string, unknown>): void;
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import type { Component, Entity, Relation, Resource, Tag } from "@vibecook/strata-ecs";
17
17
  import type { GuardedTx } from "../guards/guarded-tx";
18
- import type { BooleanSpec, EntityKeySpec, EnumSpec, JsonSpec, NumberSpec, PropSpec, StringSpec } from "../widget/props";
18
+ import type { BooleanSpec, EntityKeySpec, EnumSpec, JsonShape, JsonSpec, NumberSpec, PropSpec, StringSpec } from "../widget/props";
19
19
  export type BehaviorStore = "durable" | "runtime" | "ephemeral";
20
20
  /**
21
21
  * The CURATED phase set (design-009 §4.4, BF-D8) — a deliberate subset of the
@@ -31,6 +31,52 @@ export declare const BEHAVIOR_PHASES: Readonly<Record<BehaviorStore, readonly Be
31
31
  export declare const BEHAVIOR_DEFAULT_PHASE: Readonly<Record<BehaviorStore, BehaviorPhase>>;
32
32
  /** A behavior's declared data: the SAME `p.*` DSL `defineWidget` uses. */
33
33
  export type BehaviorSchema = Readonly<Record<string, PropSpec>>;
34
+ export type BehaviorHookName = "init" | "update" | "changed" | "tick" | "dispose";
35
+ export type BehaviorPropDescription = {
36
+ readonly kind: "string";
37
+ readonly default?: string;
38
+ } | {
39
+ readonly kind: "number";
40
+ readonly default?: number;
41
+ readonly min?: number;
42
+ readonly max?: number;
43
+ } | {
44
+ readonly kind: "boolean";
45
+ readonly default?: boolean;
46
+ } | {
47
+ readonly kind: "enum";
48
+ readonly options: readonly string[];
49
+ readonly default?: string;
50
+ } | {
51
+ readonly kind: "json";
52
+ readonly inner: JsonShape;
53
+ readonly default?: string;
54
+ } | {
55
+ readonly kind: "entityKey";
56
+ readonly default?: string;
57
+ };
58
+ export interface BehaviorReadDescription {
59
+ readonly kind: "behavior" | "component" | "tag" | "relation" | "resource";
60
+ readonly name: string;
61
+ }
62
+ export interface BehaviorDescription {
63
+ readonly id: string;
64
+ readonly store: BehaviorStore;
65
+ readonly derived: boolean;
66
+ readonly deriveDuringGesture: boolean;
67
+ readonly version: number;
68
+ readonly phase: BehaviorPhase;
69
+ readonly budgetMs?: number;
70
+ readonly tickWhile: "all" | "visible";
71
+ readonly schema: readonly {
72
+ readonly name: string;
73
+ readonly spec: BehaviorPropDescription;
74
+ }[];
75
+ readonly reads: readonly BehaviorReadDescription[];
76
+ readonly writes: readonly string[];
77
+ readonly migrationFrom: readonly number[];
78
+ readonly hooks: readonly BehaviorHookName[];
79
+ }
34
80
  type ValueOfSpec<S extends PropSpec> = S extends NumberSpec ? number : S extends BooleanSpec ? boolean : S extends EnumSpec ? string : S extends JsonSpec ? unknown : S extends StringSpec | EntityKeySpec ? string : never;
35
81
  /**
36
82
  * The hook-facing data view. `p.json` fields arrive PARSED (the cell is a
@@ -79,8 +79,11 @@ export interface GuestSpec {
79
79
  /** Per-invocation budget request; the effective budget is
80
80
  * `min(budgetMs, seamCapMs)` — no single guest may claim the whole seam. */
81
81
  readonly budgetMs?: number;
82
- /** RESERVED. v1 hosts the publish slot only; pipeline-group values arrive
83
- * with the behavior framework (design-009 M13a), wrapped by this breaker. */
82
+ /** RESERVED. Hosted guests run in the publish slot only — and that is now the
83
+ * settled shape, not a v1 placeholder: M13 reached pipeline cadence through
84
+ * `addDriven` (behaviors run as pipeline systems and CHARGE this breaker)
85
+ * instead of widening this field. A wider value would mean a second way to
86
+ * put foreign code in the tick that `addDriven` already provides. */
84
87
  readonly phase?: "publish";
85
88
  /** Seed prior breaker state (host-persisted across engine generations). */
86
89
  readonly ledger?: GuestLedgerRecord;
@@ -34,7 +34,7 @@ import { type DocSession, type DocSessionOpts, type OpenDocResult } from "../doc
34
34
  import { type JoinDocOpts, type JoinResult } from "../doc/bootstrap";
35
35
  import type { ByteChannel } from "../doc/channels";
36
36
  import { type Autosave, type AutosaveOpts, type AutosaveStorageWrite } from "../doc/autosave";
37
- import { type PresenceSession } from "../presence/presence-kit";
37
+ import { type PresenceOpts, type PresenceSession } from "../presence/presence-kit";
38
38
  import type { MeasureQueue } from "../input/measure-queue";
39
39
  import { GESTURE_DEFAULTS, POINTER_DEFAULTS } from "../settings/defaults";
40
40
  export interface CanvasEngineOpts {
@@ -51,6 +51,16 @@ export interface CanvasEngineOpts {
51
51
  * what makes "a plugin declared it" and "this engine runs it" separable.
52
52
  */
53
53
  readonly behaviors?: readonly AnyBehaviorDef[];
54
+ /** Generic guest breaker routing for hosts that use the published facade. */
55
+ readonly onGuestFault?: (id: string, error: unknown) => void;
56
+ readonly onGuestNotice?: (message: string) => void;
57
+ /** Behavior-specific routing preserves hook and entity provenance. The two
58
+ * pairs are COMPLEMENTARY, not alternatives: a fault that also strikes the
59
+ * breaker (a thenable hook; throws spanning instances) reaches BOTH the
60
+ * behavior route and the guest route — pass both, or the guest half of
61
+ * those events still lands on the console default. */
62
+ readonly onBehaviorFault?: (behavior: string, hook: string, entity: Entity | undefined, error: unknown) => void;
63
+ readonly onBehaviorLog?: (behavior: string, message: string, rest: readonly unknown[]) => void;
54
64
  readonly budgets?: {
55
65
  readonly keepMounted?: number;
56
66
  readonly fboBytes?: number;
@@ -146,11 +156,33 @@ export interface CanvasDocs {
146
156
  }): Promise<JoinResult>;
147
157
  current(): DocSession | undefined;
148
158
  /**
149
- * The live presence session (the `join({presence})` sugar's attachment), or
150
- * undefined when doc-less / presence-less. An INSPECTION seam — the devtools
151
- * dock's ephemeral tab reads `presence().eph` (DevtoolsOpts.presence) —
152
- * never a sync path; same contract as `DocSession.attachment`. Swaps with
153
- * the doc lifecycle exactly like `current()`: set by join, cleared by close.
159
+ * Attach facade presence to an ALREADY-live document (petition I18) — for
160
+ * hosts that own their document lifecycle (`create()`/`open()` + their own
161
+ * transport) and therefore never call `join({presence})`. Creates the
162
+ * session with the public `attachPresence(world, opts)`, installs the
163
+ * presence publish + remote-cursor systems, and exposes it through
164
+ * `docs.presence()` — which is also the seam the behavior runtime reads, so
165
+ * a registered ephemeral behavior leaves dormancy on the next publish step.
166
+ * The caller wires the transport itself: `presence().wire.apply(bytes)`
167
+ * inbound, `presence().onOutbound(send)` outbound (transport-free core —
168
+ * the standing `PresenceSession` contract). Refuses without a live document
169
+ * and refuses while a presence session is already live (either sugar's).
170
+ * Returns an idempotent, IDENTITY-BOUND inverse: it detaches THIS
171
+ * attachment — leave tombstones flush through still-subscribed outbound
172
+ * before wiring tears down (best-effort per subscriber: one that THROWS,
173
+ * e.g. `ws.send` on a closing socket, forfeits its own delivery and those
174
+ * peers fall back to TTL expiry; route `PresenceOpts.onFault` to observe) —
175
+ * and cannot touch a replacement; `docs.close()` and engine disposal run
176
+ * the same teardown automatically.
177
+ */
178
+ attachPresence(opts: PresenceOpts): () => void;
179
+ /**
180
+ * The live presence session (the `join({presence})` sugar's or
181
+ * `attachPresence`'s), or undefined when doc-less / presence-less. An
182
+ * INSPECTION seam — the devtools dock's ephemeral tab reads
183
+ * `presence().eph` (DevtoolsOpts.presence) — never a sync path; same
184
+ * contract as `DocSession.attachment`. Swaps with the doc lifecycle exactly
185
+ * like `current()`: set by join/attach, cleared by close.
154
186
  */
155
187
  presence(): PresenceSession | undefined;
156
188
  close(): void;
@@ -3,7 +3,7 @@
3
3
  * scene systems · doc kit · publish step · engine facade · reflector registry.
4
4
  * Import wall: strata-ecs + @ice/kernel ONLY — never react/dom/three (enforced).
5
5
  */
6
- export declare const CORE_VERSION = "0.6.0";
6
+ export declare const CORE_VERSION = "0.8.0";
7
7
  export { defineSchemaOnce, hmrInvalidateOnSchemaChange } from "./boot/hmr";
8
8
  export { All, Any, Not, Related, createWorld, defineQuery, defineSystem, defineTickSystem, enumOf, field, Local, } from "@vibecook/strata-ecs";
9
9
  export type { Batch, Component, Condition, Entity, OrderPlace, Pipeline, Query, Relation, Resource, System, SystemCtx, Tag, TickSystem, World, } from "@vibecook/strata-ecs";
@@ -16,8 +16,9 @@ export { createReflectorRegistry, type ReflectorDef, type ReflectorObserve, type
16
16
  export { createEngine, type Engine, type EngineOpts, type FrameTelemetry, type PublishHook, type SystemRunRecord, } from "./engine/engine";
17
17
  export { createFrameControl, SETTLE_CAP, type FrameControl } from "./engine/frame-control";
18
18
  export { createGuestRegistry, GUEST_BUDGET, type GuestFactory, type GuestFrame, type GuestGeneration, type GuestInstance, type GuestLedgerRecord, type GuestRegistry, type GuestRegistryOpts, type GuestRun, type GuestSpec, type GuestStatus, } from "./engine/guests";
19
- export { behaviors, defineBehavior } from "./behavior/define-behavior";
20
- export { BEHAVIOR_DEFAULT_PHASE, BEHAVIOR_PHASES, type AnyBehaviorAttachSpec, type AnyBehaviorDef, type BehaviorAttachSpec, type BehaviorChanges, type BehaviorCtxBase, type BehaviorCtxFor, type BehaviorFrame, type BehaviorHandle, type BehaviorHooks, type BehaviorPhase, type BehaviorQuery, type BehaviorQuerySpec, type BehaviorRead, type BehaviorSchema, type BehaviorSpec, type BehaviorStore, type BehaviorTx, type BehaviorWorld, type DataOf, type DurableBehaviorCtx, type EphemeralBehaviorCtx, type PeerFacet, type RuntimeBehaviorCtx, } from "./behavior/types";
19
+ export { behaviors, defineBehavior, describeBehavior } from "./behavior/define-behavior";
20
+ export type { BehaviorRegistrationOptions } from "./behavior/runtime";
21
+ export { BEHAVIOR_DEFAULT_PHASE, BEHAVIOR_PHASES, type AnyBehaviorAttachSpec, type AnyBehaviorDef, type BehaviorAttachSpec, type BehaviorChanges, type BehaviorCtxBase, type BehaviorCtxFor, type BehaviorDescription, type BehaviorFrame, type BehaviorHandle, type BehaviorHookName, type BehaviorHooks, type BehaviorPhase, type BehaviorPropDescription, type BehaviorQuery, type BehaviorQuerySpec, type BehaviorRead, type BehaviorReadDescription, type BehaviorSchema, type BehaviorSpec, type BehaviorStore, type BehaviorTx, type BehaviorWorld, type DataOf, type DurableBehaviorCtx, type EphemeralBehaviorCtx, type PeerFacet, type RuntimeBehaviorCtx, } from "./behavior/types";
21
22
  export { compileBehavior, isDurableEligible, type CompiledBehavior } from "./behavior/compile";
22
23
  export { behaviorMarkerKey, classifyBehaviorVersion, docBehaviorVersion, stampBehaviorMarker, BEHAVIOR_MARKER_PREFIX, type BehaviorMeta, type BehaviorVerdict, } from "./behavior/migrate";
23
24
  export { createBehaviorHarness, type BehaviorHarness, type BehaviorHarnessOpts, type HarnessCommit, } from "./behavior/harness";
@@ -13,7 +13,7 @@
13
13
  * always resolves to SOMETHING; L0 ingest schedules on it).
14
14
  */
15
15
  import type { Entity, World } from "@vibecook/strata-ecs";
16
- import { SpatialIndex } from "@ice/kernel";
16
+ import { SpatialIndex } from "../../../kernel/src/index";
17
17
  import { type CommitSink } from "../engine/commit-sink";
18
18
  import type { Engine } from "../engine/engine";
19
19
  import type { InputQueue } from "../input/queue";
@@ -54,7 +54,7 @@
54
54
  * calls snap, preserving the pre-T1 behavior exactly.
55
55
  */
56
56
  import type { Entity, TickSystem, World } from "@vibecook/strata-ecs";
57
- import type { SpatialIndex } from "@ice/kernel";
57
+ import type { SpatialIndex } from "../../../kernel/src/index";
58
58
  /** Deepest live nav entry, or undefined at root. */
59
59
  export declare function currentNavEntry(world: World): Entity | undefined;
60
60
  /** The container the user is inside, or undefined at root. */
@@ -15,7 +15,7 @@
15
15
  * mixed-overlap consequence and accepts it; do not "fix" it here.
16
16
  */
17
17
  import type { Component, Entity } from "@vibecook/strata-ecs";
18
- import type { Cubic, SpatialIndex } from "@ice/kernel";
18
+ import type { Cubic, SpatialIndex } from "../../../kernel/src/index";
19
19
  /** Structural reads both `World` and `SystemCtx` provide. */
20
20
  export interface PickReader {
21
21
  isAlive(e: Entity): boolean;
@@ -9,7 +9,7 @@
9
9
  * numbered by their declared `index` when given, else by declaration order; the
10
10
  * side's `count` drives the even spacing.
11
11
  */
12
- import type { PortSlot } from "@ice/kernel";
12
+ import type { PortSlot } from "../../../kernel/src/index";
13
13
  import type { WidgetPortDecl } from "../widget/define-widget";
14
14
  /** Map every declared port id → its `PortSlot` (side/index/count for even spacing). */
15
15
  export declare function portSlots(decls: readonly WidgetPortDecl[]): Map<string, PortSlot>;
@@ -11,6 +11,17 @@ export interface PresenceOpts {
11
11
  readonly color: string;
12
12
  /** Per-entry TTL (design §15.3), default {@link DEFAULT_PRESENCE_TTL_MS}. */
13
13
  readonly ttlMs?: number;
14
+ /**
15
+ * Contained presence faults, host-routable (0.8.0 review): `"outbound"` — a
16
+ * subscriber (canonically `ws.send` on a closing socket) threw and its bytes
17
+ * were dropped for that subscriber; `"leave"` — the leave flush failed
18
+ * during detach and remote peers will drop this peer at TTL instead of
19
+ * immediately; `"heal"` — the reset-heal's leave failed and stale keys age
20
+ * out at TTL. Every fault is contained either way — this is observability
21
+ * (telemetry, a "presence degraded" UI state), never control flow. Default:
22
+ * `console.error`.
23
+ */
24
+ readonly onFault?: (where: "outbound" | "leave" | "heal", error: unknown) => void;
14
25
  }
15
26
  export interface PresenceSession {
16
27
  /** This session's peer id (the ephemeral partition prefix). */
@@ -3,16 +3,19 @@ import type { Engine } from "../engine/engine";
3
3
  import { type PresencePublishOpts } from "./publish";
4
4
  import type { PresenceSession } from "./presence-kit";
5
5
  /**
6
- * The derive tick system that pools + reaps remote cursor entities. `world` is
7
- * unused directly (iteration goes through `ctx`), kept for factory symmetry with
8
- * the other `create*System(world)` builders.
6
+ * The tick system that pools + reaps remote cursor entities — standalone
7
+ * export for imperative rigs, which choose their own phase (`installPresence`
8
+ * registers its own copy in `present`, and builds it through a rig so its
9
+ * uninstall can reap the pool too).
9
10
  */
10
- export declare function createRemoteCursorsSystem(_world: World): TickSystem;
11
+ export declare function createRemoteCursorsSystem(world: World): TickSystem;
11
12
  export type InstallPresenceOpts = PresencePublishOpts;
12
13
  /**
13
14
  * Wire a presence session into an engine: the publish hook (outbound facet
14
- * derivation) + the remote-cursor derive system. Returns an uninstall that
15
- * removes both. Does NOT own the session's lifecycle — call `session.detach()`
16
- * separately.
15
+ * derivation) + the remote-cursor system (`present` phase). Returns an
16
+ * uninstall that removes both AND destroys the system's pooled cursor
17
+ * entities — uninstalling on a live document must not leave ghost cursors
18
+ * (a between-frames call, like every teardown here). Does NOT own the
19
+ * session's lifecycle — call `session.detach()` separately.
17
20
  */
18
21
  export declare function installPresence(engine: Engine, session: PresenceSession, opts?: InstallPresenceOpts): () => void;
@@ -44,7 +44,7 @@
44
44
  * change-only (design-002 §4 hygiene). Wires/ports are M8 — skipped.
45
45
  */
46
46
  import type { Entity, System, TickSystem, World } from "@vibecook/strata-ecs";
47
- import { SpatialIndex } from "@ice/kernel";
47
+ import { SpatialIndex } from "../../../kernel/src/index";
48
48
  import { type WirePickSource } from "../ops/point-pick";
49
49
  export interface PickingSystems {
50
50
  spatialSync: TickSystem;
@@ -20,7 +20,7 @@
20
20
  * screen-constant pick slop as `slopWorld = wirePickSlopPx / zoom`.
21
21
  */
22
22
  import type { Entity, TickSystem, World } from "@vibecook/strata-ecs";
23
- import { type SpatialIndex } from "@ice/kernel";
23
+ import { type SpatialIndex } from "../../../kernel/src/index";
24
24
  import type { WirePickSource } from "../ops/point-pick";
25
25
  export interface WireSyncSystem {
26
26
  wireSync: TickSystem;
@@ -25,7 +25,7 @@
25
25
  * is polish deferred; the one-frame gap is invisible in practice.
26
26
  */
27
27
  import type { Entity, System, TickSystem, World } from "@vibecook/strata-ecs";
28
- import { type SpatialIndex } from "@ice/kernel";
28
+ import { type SpatialIndex } from "../../../kernel/src/index";
29
29
  import type { CommitSink } from "../engine/commit-sink";
30
30
  import type { WirePickSource } from "../ops/point-pick";
31
31
  /**
@@ -19,5 +19,5 @@
19
19
  * behavior clears them on every terminal path.
20
20
  */
21
21
  import type { Entity, System, World } from "@vibecook/strata-ecs";
22
- import type { SpatialIndex } from "@ice/kernel";
22
+ import type { SpatialIndex } from "../../../kernel/src/index";
23
23
  export declare function createDropSystem(world: World, index: SpatialIndex<Entity>): System;
@@ -19,7 +19,7 @@
19
19
  * marquee camera move re-projects the rect (accepted — design-002 §2).
20
20
  */
21
21
  import type { Entity, TickSystem, World } from "@vibecook/strata-ecs";
22
- import { type SpatialIndex } from "@ice/kernel";
22
+ import { type SpatialIndex } from "../../../kernel/src/index";
23
23
  /** The out-of-ECS marquee preview (design-003 §5.7): rect + hit set, recomputed each frame. */
24
24
  export interface MarqueeBuffer {
25
25
  rect: {
@@ -26,5 +26,5 @@
26
26
  * churns nothing). `SpatialVersion` bumps only on a real index change.
27
27
  */
28
28
  import type { Entity, TickSystem, World } from "@vibecook/strata-ecs";
29
- import { type SpatialIndex } from "@ice/kernel";
29
+ import { type SpatialIndex } from "../../../kernel/src/index";
30
30
  export declare function createPortMaterialize(world: World, index: SpatialIndex<Entity>): TickSystem;
@@ -33,5 +33,5 @@
33
33
  * MAX_GUIDES=16 truncation is banned).
34
34
  */
35
35
  import type { Entity, TickSystem, World } from "@vibecook/strata-ecs";
36
- import { type SpatialIndex } from "@ice/kernel";
36
+ import { type SpatialIndex } from "../../../kernel/src/index";
37
37
  export declare function createSnapSystem(world: World, index: SpatialIndex<Entity>): TickSystem;
@@ -25,7 +25,7 @@
25
25
  * math only needs c0/c1.
26
26
  */
27
27
  import type { TickSystem, World } from "@vibecook/strata-ecs";
28
- import type { CameraState, PortalAffine } from "@ice/kernel";
28
+ import type { CameraState, PortalAffine } from "../../../kernel/src/index";
29
29
  /** The one in-flight nav transition (design-006 §3.1). Inactive = at rest. */
30
30
  export declare const NavTransition: import("@vibecook/strata-ecs").Resource<import("@vibecook/strata-ecs").ValueOf<{
31
31
  readonly active: import("@vibecook/strata-ecs").FieldSpec<"bool", true>;
@@ -31,7 +31,7 @@ import type { Entity, World } from "@vibecook/strata-ecs";
31
31
  import { type DescribeFn, type EntityDescription, type ObserverHandle, type ObserverOptions, type ProfilerHandle, type ProfilerOptions } from "@vibecook/strata-ecs/tools";
32
32
  import { type DockOptions } from "./dock";
33
33
  import { type GlPanelOptions, type GlPanelStats } from "./gl-panel";
34
- import { type CanvasEngine, type Engine, type PresenceSession } from "@ice/core";
34
+ import { type CanvasEngine, type Engine, type PresenceSession } from "../../core/src/index";
35
35
  export interface DevtoolsOpts {
36
36
  /** Where the dock (or, with `dock: false`, each panel) mounts (default: document.body). */
37
37
  readonly container?: HTMLElement;
@@ -27,5 +27,5 @@
27
27
  * scheduled in a `finally`, so a faulting frame is loud but survivable — the
28
28
  * throw still reaches the browser's error handler; only the death is gone.
29
29
  */
30
- import type { Engine } from "@ice/core";
30
+ import type { Engine } from "../../core/src/index";
31
31
  export declare function startRafLoop(engine: Engine): () => void;
@@ -19,7 +19,7 @@
19
19
  * identical semantics to one-per-element); `element → entity` maps a callback
20
20
  * entry back to its widget.
21
21
  */
22
- import type { Entity, MeasureQueue } from "@ice/core";
22
+ import type { Entity, MeasureQueue } from "../../core/src/index";
23
23
  export interface MeasureAdapter {
24
24
  /** Begin observing the entity's content element (no-op if `hostFor` yields none). */
25
25
  observe(entity: Entity): void;
@@ -26,7 +26,7 @@
26
26
  * Law 2 holds: everything here only enqueues (through the adapter or the forced
27
27
  * sample) — no world writes, no ECS reads.
28
28
  */
29
- import type { Entity, MeasureQueue, WidgetMountStore } from "@ice/core";
29
+ import type { Entity, MeasureQueue, WidgetMountStore } from "../../core/src/index";
30
30
  /** The element source (the `domWidgets` reflector supplies this via `hostFor`). */
31
31
  export interface MeasureWiringHosts {
32
32
  hostFor(entity: Entity): HTMLElement | undefined;
@@ -51,7 +51,7 @@
51
51
  * `overInteractive` reads false mid-gesture — correct: the gesture owns the
52
52
  * pointer, not the widget under it.
53
53
  */
54
- import { type InputQueue } from "@ice/core";
54
+ import { type InputQueue } from "../../core/src/index";
55
55
  import type { CanvasHost } from "./host";
56
56
  /**
57
57
  * The router GL path's adapter seam (design-004 §4). The GL plane is
@@ -25,7 +25,7 @@
25
25
  * Law 10: reflectors write output only, never read layout or write ECS — this
26
26
  * flush touches only the overlay plane's node styles.
27
27
  */
28
- import { type MarqueeBuffer, type ReflectorDef, type World } from "@ice/core";
28
+ import { type MarqueeBuffer, type ReflectorDef, type World } from "../../../core/src/index";
29
29
  import type { CanvasHost } from "../host";
30
30
  export declare function createChromeReflector(host: CanvasHost, _world: World, marqueeBuffer: MarqueeBuffer): ReflectorDef & {
31
31
  writes(): number;
@@ -14,7 +14,7 @@
14
14
  * Law 10: reflectors run post-notify, write output only, never read layout
15
15
  * or write ECS — this flush touches only `host.container.style`.
16
16
  */
17
- import type { ReflectorDef } from "@ice/core";
17
+ import type { ReflectorDef } from "../../../core/src/index";
18
18
  import type { CanvasHost } from "../host";
19
19
  export declare function createCursorReflector(host: CanvasHost, readCursor: () => string): ReflectorDef & {
20
20
  writes(): number;
@@ -40,7 +40,7 @@
40
40
  * Law 10: reflectors run post-notify, write output only, never read layout or
41
41
  * write ECS — this flush touches only host `<div>` style/attributes/parentage.
42
42
  */
43
- import { type Entity, type ReflectorDef, type WidgetMountStore, type World } from "@ice/core";
43
+ import { type Entity, type ReflectorDef, type WidgetMountStore, type World } from "../../../core/src/index";
44
44
  /** The two planes a host can live in (design-004 §1: P1 content, P3 lifted). */
45
45
  export interface DomWidgetsHost {
46
46
  readonly contentPlane: HTMLElement;
@@ -23,7 +23,7 @@
23
23
  * is the live div count. Because the reflector is dirty-driven, a static frame
24
24
  * does not flush at all, so neither counter moves.
25
25
  */
26
- import { type ReflectorDef } from "@ice/core";
26
+ import { type ReflectorDef } from "../../../core/src/index";
27
27
  import type { CanvasHost } from "../host";
28
28
  export declare function createGrayboxReflector(host: CanvasHost): ReflectorDef & {
29
29
  styleWrites(): number;
@@ -24,7 +24,7 @@
24
24
  * Law 10: reflectors run post-notify, write output only, and NEVER read layout
25
25
  * or write ECS — this flush touches only `host.contentPlane.style`.
26
26
  */
27
- import { type ReflectorDef } from "@ice/core";
27
+ import { type ReflectorDef } from "../../../core/src/index";
28
28
  /**
29
29
  * The camera-transformed DOM plane(s). A `CanvasHost` satisfies this
30
30
  * structurally (M3 backward compat); M6 passes `liftedPlane` too so P3 tracks P1.
@@ -10,7 +10,7 @@
10
10
  * cursor dirt only. The plane mounts LAST in the container, above chrome;
11
11
  * `pointer-events: none` throughout — cursors are never hit-testable.
12
12
  */
13
- import { type ReflectorDef, type World } from "@ice/core";
13
+ import { type ReflectorDef, type World } from "../../../core/src/index";
14
14
  import type { CanvasHost } from "../host";
15
15
  export interface RemoteCursorsReflector {
16
16
  readonly reflector: ReflectorDef;
@@ -34,7 +34,7 @@
34
34
  * via node removal, window blur deliberately does NOT force-blur (the browser
35
35
  * restores focus on refocus — adapter's cancelAllInput keeps its hands off).
36
36
  */
37
- import type { Entity } from "@ice/core";
37
+ import type { Entity } from "../../core/src/index";
38
38
  import type { CanvasHost } from "./host";
39
39
  /** The widget-declared focus target (a proxy descendant): `<div data-canvas-focus tabIndex={-1}>`. */
40
40
  export declare const FOCUS_PROXY_ATTR = "data-canvas-focus";