@sharpee/if-domain 0.9.111 → 1.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.
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @sharpee/if-domain/channels — channel-I/O type contracts.
3
+ *
4
+ * Owner context: domain layer. Single canonical home for the channel
5
+ * type contracts shared across the channel-I/O subsystem (ADR-163 §14
6
+ * + CLAUDE.md rule 7b).
7
+ *
8
+ * Public interface:
9
+ *
10
+ * - `IOChannel<T>`, `IChannelRegistry`, `ChannelProduceContext` — the
11
+ * closure-per-channel definition contract (ADR-163 §6, §7).
12
+ * - `ChannelContentType`, `ChannelMode`, `ChannelEmitPolicy` — channel
13
+ * configuration enums (§3, §4, §5).
14
+ * - `ClientCapabilities`, `CapabilityFlag` — capability declaration and
15
+ * the gating discriminator (§2, §6).
16
+ * - `ChannelDefinition`, `HelloPacket`, `CmgtPacket`, `TurnPacket`,
17
+ * `CommandPacket`, `WirePacket` — wire-protocol packets (§1, §11).
18
+ *
19
+ * @see ADR-163 — Channel-Service Platform
20
+ */
21
+ export type { ChannelContentType, ChannelMode, ChannelEmitPolicy, ClientCapabilities, CapabilityFlag, ChannelProduceContext, IOChannel, IChannelRegistry, MainEntry, } from './types';
22
+ export type { ChannelDefinition, HelloPacket, CmgtPacket, TurnPacket, CommandPacket, WirePacket, } from './wire';
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/if-domain/src/channels/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,YAAY,EACV,kBAAkB,EAClB,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,SAAS,EACT,gBAAgB,EAChB,SAAS,GACV,MAAM,SAAS,CAAC;AAEjB,YAAY,EACV,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,UAAU,EACV,aAAa,EACb,UAAU,GACX,MAAM,QAAQ,CAAC"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ /**
3
+ * @sharpee/if-domain/channels — channel-I/O type contracts.
4
+ *
5
+ * Owner context: domain layer. Single canonical home for the channel
6
+ * type contracts shared across the channel-I/O subsystem (ADR-163 §14
7
+ * + CLAUDE.md rule 7b).
8
+ *
9
+ * Public interface:
10
+ *
11
+ * - `IOChannel<T>`, `IChannelRegistry`, `ChannelProduceContext` — the
12
+ * closure-per-channel definition contract (ADR-163 §6, §7).
13
+ * - `ChannelContentType`, `ChannelMode`, `ChannelEmitPolicy` — channel
14
+ * configuration enums (§3, §4, §5).
15
+ * - `ClientCapabilities`, `CapabilityFlag` — capability declaration and
16
+ * the gating discriminator (§2, §6).
17
+ * - `ChannelDefinition`, `HelloPacket`, `CmgtPacket`, `TurnPacket`,
18
+ * `CommandPacket`, `WirePacket` — wire-protocol packets (§1, §11).
19
+ *
20
+ * @see ADR-163 — Channel-Service Platform
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../repos/sharpee/packages/if-domain/src/channels/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG"}
@@ -0,0 +1,237 @@
1
+ /**
2
+ * @sharpee/if-domain — channel type contracts (ADR-163, closure-per-channel
3
+ * model, 2026-05-02 rewrite + 2026-05-03 refinement).
4
+ *
5
+ * Owner context: domain layer. These types describe the channel-I/O
6
+ * contract used by every package that participates in the channel system:
7
+ *
8
+ * - `@sharpee/channel-service` runs the closures (`ChannelService.build`).
9
+ * - `@sharpee/stdlib` defines the standard `IOChannel` instances.
10
+ * - `@sharpee/engine` composes the registry with the service and emits
11
+ * manifest / packet events.
12
+ * - Consumers (`@sharpee/platform-browser`, multi-user web-client, CLI
13
+ * bundle) consume the wire packets via ADR-165 renderers.
14
+ *
15
+ * Public interface: the `IOChannel<T>` contract, the `IChannelRegistry`
16
+ * registry shape, the `ChannelProduceContext` passed to closures, and the
17
+ * three small enums (`ChannelContentType`, `ChannelMode`,
18
+ * `ChannelEmitPolicy`) plus `ClientCapabilities` and `CapabilityFlag`.
19
+ *
20
+ * No implementation lives here. Per ADR-163 §14 and CLAUDE.md rule 7b:
21
+ * if-domain is the single home for channel type contracts so co-located
22
+ * client and server code share them by direct import, not duplication.
23
+ *
24
+ * @see ADR-163 — Channel-Service Platform — §6, §7, §14
25
+ */
26
+ import type { ISemanticEvent } from "../../core/index";
27
+ import type { ITextBlock, TextContent } from "../../text-blocks/index";
28
+ /**
29
+ * Channel content types (ADR-163 §3).
30
+ *
31
+ * - `text` — plain string. Renderer writes verbatim or styles.
32
+ * - `number` — integer or float. Producer emits the number; client formats.
33
+ * - `json` — structured object. Escape hatch for author-defined surfaces
34
+ * and for the platform's `main` channel which carries `MainEntry[]`.
35
+ */
36
+ export type ChannelContentType = 'text' | 'number' | 'json';
37
+ /**
38
+ * A single entry in the `main` channel's append-mode value array.
39
+ *
40
+ * Each entry corresponds to one `<p>`-equivalent surface in a text
41
+ * renderer. The wire value of the `main` channel is `MainEntry[]` (the
42
+ * new entries produced this turn).
43
+ *
44
+ * Per the prose-pipeline pre-line removal (session 2026-05-12), every
45
+ * intra-block `\n` was lifted to a block boundary. Where the former
46
+ * `\n` was inside a paragraph (book text under its prefix, banner
47
+ * lines under a title), the second-and-later block carries
48
+ * `tight: true` and the renderer collapses the inter-paragraph margin
49
+ * so the lines stack flush.
50
+ *
51
+ * Invariant: a `tight` entry must not appear first in a packet — the
52
+ * renderer relies on a non-tight predecessor in the same packet or in
53
+ * an already-rendered prior packet.
54
+ */
55
+ export interface MainEntry {
56
+ /** Content of this entry — strings and decorations, no `\n` in any string. */
57
+ readonly content: ReadonlyArray<TextContent>;
58
+ /** Visual continuation hint. See type-level doc above. */
59
+ readonly tight?: boolean;
60
+ /**
61
+ * Optional semantic CSS class the renderer applies to the rendered
62
+ * element in addition to `main-entry`. Mirrors `ITextBlock.className`
63
+ * — used by the prose pipeline to flow per-piece visual identity
64
+ * through the channel wire to the browser renderer.
65
+ */
66
+ readonly className?: string;
67
+ }
68
+ /**
69
+ * Channel update modes (ADR-163 §4).
70
+ *
71
+ * - `replace` — newest value supersedes prior values. Persistent: a
72
+ * mid-session join replays the latest value.
73
+ * - `append` — value added to a chronological list (transcript-shaped).
74
+ * Persistent: a mid-session join replays the full list (subject to
75
+ * `clear` truncation per §10).
76
+ * - `event` — transient signal; client renders once and discards. Not
77
+ * persisted; mid-session joins do not see prior `event` emissions.
78
+ */
79
+ export type ChannelMode = 'replace' | 'append' | 'event';
80
+ /**
81
+ * Per-channel emit policy (ADR-163 §5).
82
+ *
83
+ * - `always` — channel populated in every turn packet. `replace` emits
84
+ * current value (changed or not); `append` emits any new entries
85
+ * (possibly empty array); `event` is the natural exception (only
86
+ * emits on fire).
87
+ * - `sparse` — channel appears only when its value changed (`replace`)
88
+ * or new entries were produced (`append`/`event`). Default for
89
+ * author-defined channels.
90
+ */
91
+ export type ChannelEmitPolicy = 'always' | 'sparse';
92
+ /**
93
+ * Client capabilities declared at session start (ADR-163 §2).
94
+ *
95
+ * Fields preserve ADR-101's `ClientCapabilities` interface verbatim so
96
+ * existing consumers can adopt without rewriting their declarations.
97
+ *
98
+ * The `ChannelService` filters capability-gated channels at manifest
99
+ * production using these flags (`IOChannel.gatedBy`).
100
+ */
101
+ export interface ClientCapabilities {
102
+ /** Always true — every Sharpee surface renders text. */
103
+ readonly text: true;
104
+ readonly images: boolean;
105
+ readonly animations: boolean;
106
+ readonly video: boolean;
107
+ readonly sound: boolean;
108
+ readonly music: boolean;
109
+ readonly speech: boolean;
110
+ readonly splitPane: boolean;
111
+ readonly statusBar: boolean;
112
+ readonly sidebar: boolean;
113
+ readonly clickableText: boolean;
114
+ readonly clickableImage: boolean;
115
+ readonly dragDrop: boolean;
116
+ readonly transitions: boolean;
117
+ readonly layers: boolean;
118
+ readonly customFonts: boolean;
119
+ readonly screenWidth?: number;
120
+ readonly screenHeight?: number;
121
+ }
122
+ /**
123
+ * Subset of `ClientCapabilities` keys that name boolean flags. The
124
+ * `text` field is always `true`; the dimension fields are numbers.
125
+ *
126
+ * `IOChannel.gatedBy` accepts only `CapabilityFlag` values: a channel
127
+ * cannot gate on `text` (always true) or on screen dimensions (numeric).
128
+ */
129
+ export type CapabilityFlag = Exclude<{
130
+ [K in keyof ClientCapabilities]: ClientCapabilities[K] extends boolean ? K : never;
131
+ }[keyof ClientCapabilities], 'text'>;
132
+ /**
133
+ * Context passed to an `IOChannel.produce` closure (ADR-163 §6).
134
+ *
135
+ * The closure receives:
136
+ *
137
+ * - `world` — current world state (read-only from the producer's POV).
138
+ * Typed as `unknown` here because if-domain cannot import
139
+ * `IWorldModel` from `@sharpee/world-model` without creating a cycle
140
+ * (world-model depends on if-domain). Consumers in stdlib and engine
141
+ * narrow this at the call site:
142
+ * ```ts
143
+ * produce: (ctx) => {
144
+ * const world = ctx.world as IWorldModel;
145
+ * return world.getCapability('scoring');
146
+ * }
147
+ * ```
148
+ * The narrowing happens once per channel definition. The trade-off
149
+ * keeps if-domain dependency-clean; the alternative (replicating
150
+ * `IWorldModel` in if-domain) is a much larger refactor.
151
+ *
152
+ * - `events` — semantic events fired during the turn just executed.
153
+ * Frozen array; producers must not mutate.
154
+ *
155
+ * - `blocks` — text blocks produced by `text-service.processTurn` for
156
+ * the turn just executed. Frozen array.
157
+ *
158
+ * - `turn` — monotonic turn count for this session. Engine increments.
159
+ *
160
+ * - `prevValue` — the value this channel emitted on the previous turn,
161
+ * or `undefined` if no prior emission. Closures use this for
162
+ * diff-aware emission decisions and for append-mode awareness.
163
+ *
164
+ * Closures are pure functions of context. They project; they do not
165
+ * mutate.
166
+ */
167
+ export interface ChannelProduceContext {
168
+ /**
169
+ * World state for the current turn. Typed `unknown` to avoid an
170
+ * if-domain → world-model cycle. Consumers cast at the call site.
171
+ */
172
+ readonly world: unknown;
173
+ readonly events: readonly ISemanticEvent[];
174
+ readonly blocks: readonly ITextBlock[];
175
+ readonly turn: number;
176
+ readonly prevValue: unknown | undefined;
177
+ }
178
+ /**
179
+ * A typed channel definition with embedded producer (ADR-163 §6).
180
+ *
181
+ * Channels are objects. They carry identity (`id`), configuration
182
+ * (`contentType`, `mode`, `emit`, optional `gatedBy`), and a
183
+ * `produce(ctx)` closure that computes the channel's value for the
184
+ * current turn.
185
+ *
186
+ * The closure return value drives emission semantics:
187
+ *
188
+ * - `T` — emit this value.
189
+ * - `undefined` — skip emission this turn (sparse channels stay quiet;
190
+ * always channels re-emit their previous value).
191
+ * - `null` — emit a hide / stop / clear signal (used by media channels
192
+ * per §9 and by `clear` per §12).
193
+ *
194
+ * For `append`-mode channels, return an array of new entries (or
195
+ * `undefined` for "no new entries this turn"). For `replace` or `event`
196
+ * mode, return a single value (or `undefined`).
197
+ *
198
+ * Story override of a standard channel = re-register an `IOChannel`
199
+ * with the same `id` (last write wins per §6).
200
+ */
201
+ export interface IOChannel<T = unknown> {
202
+ readonly id: string;
203
+ readonly contentType: ChannelContentType;
204
+ readonly mode: ChannelMode;
205
+ readonly emit: ChannelEmitPolicy;
206
+ /** Capability flag this channel is gated by, if any. */
207
+ readonly gatedBy?: CapabilityFlag;
208
+ /**
209
+ * Produce this channel's value for the current turn. See class
210
+ * comment above for the return-shape contract.
211
+ */
212
+ readonly produce: (ctx: ChannelProduceContext) => T | T[] | undefined | null;
213
+ }
214
+ /**
215
+ * Channel registry contract (ADR-163 §7, §14).
216
+ *
217
+ * The registry is a simple keyed collection of `IOChannel` instances.
218
+ * It does not enforce mode invariants, capability filtering, or
219
+ * registration order — those are the `ChannelService`'s job.
220
+ *
221
+ * `add(channel)` is last-write-wins by `channel.id`: re-registering an
222
+ * id replaces the prior definition. This is how stories override
223
+ * standard channels (per §6).
224
+ *
225
+ * Implementations live elsewhere:
226
+ *
227
+ * - `@sharpee/stdlib` exports a populated `channelRegistry` instance
228
+ * with the standard channels pre-registered (per §7).
229
+ * - Engine bootstrap calls `Story.registerChannels?.(registry)` to let
230
+ * stories add or override channels.
231
+ */
232
+ export interface IChannelRegistry {
233
+ add(channel: IOChannel): void;
234
+ get(id: string): IOChannel | undefined;
235
+ all(): readonly IOChannel[];
236
+ }
237
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/if-domain/src/channels/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAMpE;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE5D;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,SAAS;IACxB,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAC7C,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEzD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAMpD;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAkB;IAEjC,wDAAwD;IACxD,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IAGxB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAGzB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAG1B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAG3B,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAG9B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,CAClC;KACG,CAAC,IAAI,MAAM,kBAAkB,GAAG,kBAAkB,CAAC,CAAC,CAAC,SAAS,OAAO,GAClE,CAAC,GACD,KAAK;CACV,CAAC,MAAM,kBAAkB,CAAC,EAC3B,MAAM,CACP,CAAC;AAMF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,QAAQ,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,SAAS,CAAC;CACzC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,SAAS,CAAC,CAAC,GAAG,OAAO;IACpC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,WAAW,EAAE,kBAAkB,CAAC;IACzC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,wDAAwD;IACxD,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,SAAS,GAAG,IAAI,CAAC;CAC9E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,CAAC,OAAO,EAAE,SAAS,GAAG,IAAI,CAAC;IAC9B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IACvC,GAAG,IAAI,SAAS,SAAS,EAAE,CAAC;CAC7B"}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ /**
3
+ * @sharpee/if-domain — channel type contracts (ADR-163, closure-per-channel
4
+ * model, 2026-05-02 rewrite + 2026-05-03 refinement).
5
+ *
6
+ * Owner context: domain layer. These types describe the channel-I/O
7
+ * contract used by every package that participates in the channel system:
8
+ *
9
+ * - `@sharpee/channel-service` runs the closures (`ChannelService.build`).
10
+ * - `@sharpee/stdlib` defines the standard `IOChannel` instances.
11
+ * - `@sharpee/engine` composes the registry with the service and emits
12
+ * manifest / packet events.
13
+ * - Consumers (`@sharpee/platform-browser`, multi-user web-client, CLI
14
+ * bundle) consume the wire packets via ADR-165 renderers.
15
+ *
16
+ * Public interface: the `IOChannel<T>` contract, the `IChannelRegistry`
17
+ * registry shape, the `ChannelProduceContext` passed to closures, and the
18
+ * three small enums (`ChannelContentType`, `ChannelMode`,
19
+ * `ChannelEmitPolicy`) plus `ClientCapabilities` and `CapabilityFlag`.
20
+ *
21
+ * No implementation lives here. Per ADR-163 §14 and CLAUDE.md rule 7b:
22
+ * if-domain is the single home for channel type contracts so co-located
23
+ * client and server code share them by direct import, not duplication.
24
+ *
25
+ * @see ADR-163 — Channel-Service Platform — §6, §7, §14
26
+ */
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../../../repos/sharpee/packages/if-domain/src/channels/types.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * @sharpee/if-domain — channel wire-protocol types (ADR-163 §1, §11).
3
+ *
4
+ * Owner context: domain layer. Pure types describing the four packets
5
+ * that cross the wire between server and client in the channel-I/O
6
+ * system.
7
+ *
8
+ * Public interface (per CLAUDE.md rule 7b): single-user and multi-user
9
+ * surfaces both import directly from this module. Co-located client and
10
+ * server code shares the wire contract via direct import to make
11
+ * protocol drift mechanically impossible.
12
+ *
13
+ * Constraint: NO runtime-specific types (no `Buffer`, `fs.Stats`,
14
+ * `DOMException`, no DOM globals, no Node globals). The module must be
15
+ * importable by browser, Node, and CLI contexts without dragging in a
16
+ * runtime they don't have.
17
+ *
18
+ * @see ADR-163 — Channel-Service Platform — §1, §3, §4, §5, §11
19
+ */
20
+ import type { ChannelContentType, ChannelEmitPolicy, ChannelMode, ClientCapabilities } from './types';
21
+ /**
22
+ * Channel definition as it appears in a CMGT manifest (ADR-163 §11).
23
+ *
24
+ * Wire-shaped subset of `IOChannel` — just identity and configuration.
25
+ * The producer closure does not cross the wire; only its outputs do.
26
+ *
27
+ * Mode lives on the channel, not on the rule (ADR-163 §4). A channel
28
+ * always behaves the same way regardless of which `IOChannel` produced
29
+ * it, and clients dispatch on the manifest entry alone.
30
+ */
31
+ export interface ChannelDefinition {
32
+ /** Channel id. String — no integer packing. */
33
+ readonly id: string;
34
+ /** Content type carried by emissions on this channel. */
35
+ readonly contentType: ChannelContentType;
36
+ /** Update mode (replace / append / event). */
37
+ readonly mode: ChannelMode;
38
+ /**
39
+ * Emit policy. Optional in the wire shape because authors may omit
40
+ * it on `IOChannel` registration; the platform standard channels
41
+ * default to `'always'` and author channels default to `'sparse'`.
42
+ */
43
+ readonly emit?: ChannelEmitPolicy;
44
+ }
45
+ /**
46
+ * Hello packet — client → server at session start (ADR-163 §1, §2).
47
+ *
48
+ * Single-user runtimes synthesize a hello internally. In transport-
49
+ * attached deployments (ADR-164) the client transmits one over the wire.
50
+ * Either way, the `ChannelService` may not emit `cmgt` until a hello
51
+ * has been registered for the session (bootstrap-order invariant per
52
+ * §11).
53
+ */
54
+ export interface HelloPacket {
55
+ readonly kind: 'hello';
56
+ readonly capabilities: ClientCapabilities;
57
+ }
58
+ /**
59
+ * CMGT (channel-management) packet — server → client (ADR-163 §1, §11).
60
+ *
61
+ * Pure schema; no values. The manifest is per-client — derived from the
62
+ * union of registered channels filtered by the client's capability
63
+ * declaration (per §6, §11).
64
+ */
65
+ export interface CmgtPacket {
66
+ readonly kind: 'cmgt';
67
+ /**
68
+ * Wire protocol version. Initial value `1`. Bumped on breaking shape
69
+ * changes to packet kinds or `ChannelDefinition` fields. Additive
70
+ * channels do not bump version.
71
+ */
72
+ readonly protocol_version: number;
73
+ /**
74
+ * Capability-filtered channel definitions for this client.
75
+ */
76
+ readonly channels: ReadonlyArray<ChannelDefinition>;
77
+ }
78
+ /**
79
+ * Turn packet — server → client per turn (ADR-163 §1).
80
+ *
81
+ * The payload is a record keyed by channel id. Per-channel emit policy
82
+ * (§5) governs which channel keys appear: `'always'` channels appear
83
+ * every turn, `'sparse'` channels appear only on change.
84
+ *
85
+ * Append-mode payload values carry NEW ENTRIES THIS TURN ONLY, not the
86
+ * accumulated list (§5). The renderer is responsible for accumulation.
87
+ */
88
+ export interface TurnPacket {
89
+ readonly kind: 'turn';
90
+ /**
91
+ * Turn identifier — opaque string. Used for re-emission identity
92
+ * (§14) and for transcript ordering in downstream consumers.
93
+ */
94
+ readonly turn_id: string;
95
+ /**
96
+ * Channel-keyed payload. Channel ids map to type-specific values:
97
+ * text channels carry strings, number channels carry numbers, json
98
+ * channels carry arbitrary objects (or `null` for replace-mode
99
+ * media channels signaling stop/hide per §7).
100
+ */
101
+ readonly payload: Readonly<Record<string, unknown>>;
102
+ }
103
+ /**
104
+ * Command packet — client → server per input (ADR-163 §1, §9).
105
+ *
106
+ * UI gestures (hotspot click, drag-drop, custom widget) are synthesized
107
+ * into command packets indistinguishable from typed input. The boundary
108
+ * rule (§9): if the action would change what the engine sees on the
109
+ * next turn, it is a `CommandPacket`; otherwise it is renderer-local
110
+ * and never reaches the wire.
111
+ */
112
+ export interface CommandPacket {
113
+ readonly kind: 'command';
114
+ readonly text: string;
115
+ }
116
+ /**
117
+ * Wire packet discriminated union — every packet that crosses the wire.
118
+ *
119
+ * Decoders pattern-match on `kind` to dispatch.
120
+ */
121
+ export type WirePacket = HelloPacket | CmgtPacket | TurnPacket | CommandPacket;
122
+ //# sourceMappingURL=wire.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire.d.ts","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/if-domain/src/channels/wire.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,iBAAiB,EACjB,WAAW,EACX,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;GASG;AACH,MAAM,WAAW,iBAAiB;IAChC,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,QAAQ,CAAC,WAAW,EAAE,kBAAkB,CAAC;IACzC,8CAA8C;IAC9C,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,iBAAiB,CAAC;CACnC;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAAC;CAC3C;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;CACrD;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACrD;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAClB,WAAW,GACX,UAAU,GACV,UAAU,GACV,aAAa,CAAC"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ /**
3
+ * @sharpee/if-domain — channel wire-protocol types (ADR-163 §1, §11).
4
+ *
5
+ * Owner context: domain layer. Pure types describing the four packets
6
+ * that cross the wire between server and client in the channel-I/O
7
+ * system.
8
+ *
9
+ * Public interface (per CLAUDE.md rule 7b): single-user and multi-user
10
+ * surfaces both import directly from this module. Co-located client and
11
+ * server code shares the wire contract via direct import to make
12
+ * protocol drift mechanically impossible.
13
+ *
14
+ * Constraint: NO runtime-specific types (no `Buffer`, `fs.Stats`,
15
+ * `DOMException`, no DOM globals, no Node globals). The module must be
16
+ * importable by browser, Node, and CLI contexts without dragging in a
17
+ * runtime they don't have.
18
+ *
19
+ * @see ADR-163 — Channel-Service Platform — §1, §3, §4, §5, §11
20
+ */
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ //# sourceMappingURL=wire.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire.js","sourceRoot":"","sources":["../../../../../../../repos/sharpee/packages/if-domain/src/channels/wire.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;GAkBG"}
package/index.d.ts CHANGED
@@ -13,4 +13,6 @@ export * from './parser-contracts';
13
13
  export * from './vocabulary-contracts';
14
14
  export * from './grammar';
15
15
  export * from './prompt';
16
+ export * from './channels';
17
+ export * from './sound';
16
18
  //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../repos/sharpee/packages/if-domain/src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,UAAU,CAAC;AAGzB,cAAc,aAAa,CAAC;AAG5B,cAAc,WAAW,CAAC;AAG1B,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAG3C,cAAc,oBAAoB,CAAC;AAGnC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,WAAW,CAAC;AAG1B,cAAc,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../repos/sharpee/packages/if-domain/src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,UAAU,CAAC;AAGzB,cAAc,aAAa,CAAC;AAG5B,cAAc,WAAW,CAAC;AAG1B,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAG3C,cAAc,oBAAoB,CAAC;AAGnC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,WAAW,CAAC;AAG1B,cAAc,UAAU,CAAC;AAGzB,cAAc,YAAY,CAAC;AAG3B,cAAc,SAAS,CAAC"}
package/index.js CHANGED
@@ -37,4 +37,8 @@ __exportStar(require("./vocabulary-contracts"), exports);
37
37
  __exportStar(require("./grammar"), exports);
38
38
  // Prompt types (ADR-137)
39
39
  __exportStar(require("./prompt"), exports);
40
+ // Channel-I/O type contracts (ADR-163)
41
+ __exportStar(require("./channels"), exports);
42
+ // Spatial sound propagation contracts (ADR-172)
43
+ __exportStar(require("./sound"), exports);
40
44
  //# sourceMappingURL=index.js.map
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/if-domain/src/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;AAEH,gBAAgB;AAChB,2CAAyB;AAEzB,mBAAmB;AACnB,8CAA4B;AAE5B,sBAAsB;AACtB,4CAA0B;AAE1B,+BAA+B;AAC/B,sDAAoC;AACpC,6DAA2C;AAE3C,mBAAmB;AACnB,qDAAmC;AAEnC,uBAAuB;AACvB,yDAAuC;AAEvC,iBAAiB;AACjB,4CAA0B;AAE1B,yBAAyB;AACzB,2CAAyB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/if-domain/src/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;AAEH,gBAAgB;AAChB,2CAAyB;AAEzB,mBAAmB;AACnB,8CAA4B;AAE5B,sBAAsB;AACtB,4CAA0B;AAE1B,+BAA+B;AAC/B,sDAAoC;AACpC,6DAA2C;AAE3C,mBAAmB;AACnB,qDAAmC;AAEnC,uBAAuB;AACvB,yDAAuC;AAEvC,iBAAiB;AACjB,4CAA0B;AAE1B,yBAAyB;AACzB,2CAAyB;AAEzB,uCAAuC;AACvC,6CAA2B;AAE3B,gDAAgD;AAChD,0CAAwB"}
@@ -70,6 +70,12 @@ export interface LanguageProvider {
70
70
  * @returns Array of action IDs
71
71
  */
72
72
  getSupportedActions?(): string[];
73
+ /**
74
+ * Get all registered message IDs and their text.
75
+ * Used by tooling (VS Code extension) for language introspection.
76
+ * @returns Map of message ID to text, or undefined if not supported
77
+ */
78
+ getAllMessages?(): Map<string, string>;
73
79
  }
74
80
  /**
75
81
  * Language provider registry interface
@@ -1 +1 @@
1
- {"version":3,"file":"language-provider.d.ts","sourceRoot":"","sources":["../../../../../repos/sharpee/packages/if-domain/src/language-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;IAEhB;;OAEG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;IAEnB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAE9B;;;;OAIG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;IAE1D;;;;;OAKG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC;IAEpE;;;;OAIG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;IAEvC;;;;OAIG;IACH,aAAa,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IAEzD;;;OAGG;IACH,mBAAmB,CAAC,IAAI,MAAM,EAAE,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAE3C;;;;OAIG;IACH,GAAG,CAAC,YAAY,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAAC;IAExD;;;;OAIG;IACH,UAAU,IAAI,gBAAgB,CAAC;IAE/B;;;OAGG;IACH,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvC;;;OAGG;IACH,qBAAqB,IAAI,MAAM,EAAE,CAAC;CACnC"}
1
+ {"version":3,"file":"language-provider.d.ts","sourceRoot":"","sources":["../../../../../repos/sharpee/packages/if-domain/src/language-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;IAEhB;;OAEG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;IAEnB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAE9B;;;;OAIG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;IAE1D;;;;;OAKG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC;IAEpE;;;;OAIG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;IAEvC;;;;OAIG;IACH,aAAa,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IAEzD;;;OAGG;IACH,mBAAmB,CAAC,IAAI,MAAM,EAAE,CAAC;IAEjC;;;;OAIG;IACH,cAAc,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAE3C;;;;OAIG;IACH,GAAG,CAAC,YAAY,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAAC;IAExD;;;;OAIG;IACH,UAAU,IAAI,gBAAgB,CAAC;IAE/B;;;OAGG;IACH,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvC;;;OAGG;IACH,qBAAqB,IAAI,MAAM,EAAE,CAAC;CACnC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sharpee/if-domain",
3
- "version": "0.9.111",
3
+ "version": "1.0.0",
4
4
  "description": "Core domain model and contracts for Sharpee Interactive Fiction Platform",
5
5
  "main": "./index.js",
6
6
  "types": "./index.d.ts",
@@ -12,7 +12,8 @@
12
12
  }
13
13
  },
14
14
  "dependencies": {
15
- "@sharpee/core": "^0.9.111"
15
+ "@sharpee/core": "^1.0.0",
16
+ "@sharpee/text-blocks": "^1.0.0"
16
17
  },
17
18
  "keywords": [
18
19
  "interactive-fiction",
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @sharpee/if-domain/sound — spatial sound propagation type contracts.
3
+ *
4
+ * Owner context: domain layer. Single canonical home for the sound
5
+ * type contracts shared between emission (stdlib), propagation (engine),
6
+ * and rendering (lang-{locale}, audio-capable clients).
7
+ *
8
+ * Public interface:
9
+ *
10
+ * - `VolumeTier`, `VOLUME_TIER_BUDGETS` — emission-side volume tier set.
11
+ * - `AudibilityTier` — listener-side audibility tier set.
12
+ * - `SoundKind` — semantic classifier string.
13
+ * - `ISoundContent` — optional structured content payload.
14
+ * - `ISound` — emission shape for `context.emitSound`.
15
+ * - `IAudibilityEvent` — per-listener delivery shape produced by
16
+ * propagation and routed through the sound channel.
17
+ *
18
+ * @see ADR-172 — Spatial Sound Propagation
19
+ */
20
+ export * from './types';
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/if-domain/src/sound/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,cAAc,SAAS,CAAC"}
package/sound/index.js ADDED
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ /**
3
+ * @sharpee/if-domain/sound — spatial sound propagation type contracts.
4
+ *
5
+ * Owner context: domain layer. Single canonical home for the sound
6
+ * type contracts shared between emission (stdlib), propagation (engine),
7
+ * and rendering (lang-{locale}, audio-capable clients).
8
+ *
9
+ * Public interface:
10
+ *
11
+ * - `VolumeTier`, `VOLUME_TIER_BUDGETS` — emission-side volume tier set.
12
+ * - `AudibilityTier` — listener-side audibility tier set.
13
+ * - `SoundKind` — semantic classifier string.
14
+ * - `ISoundContent` — optional structured content payload.
15
+ * - `ISound` — emission shape for `context.emitSound`.
16
+ * - `IAudibilityEvent` — per-listener delivery shape produced by
17
+ * propagation and routed through the sound channel.
18
+ *
19
+ * @see ADR-172 — Spatial Sound Propagation
20
+ */
21
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ var desc = Object.getOwnPropertyDescriptor(m, k);
24
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
25
+ desc = { enumerable: true, get: function() { return m[k]; } };
26
+ }
27
+ Object.defineProperty(o, k2, desc);
28
+ }) : (function(o, m, k, k2) {
29
+ if (k2 === undefined) k2 = k;
30
+ o[k2] = m[k];
31
+ }));
32
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
33
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
34
+ };
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ __exportStar(require("./types"), exports);
37
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../repos/sharpee/packages/if-domain/src/sound/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;GAkBG;;;;;;;;;;;;;;;;AAEH,0CAAwB"}
@@ -0,0 +1,162 @@
1
+ /**
2
+ * @file Sound and AudibilityEvent domain types (ADR-172).
3
+ *
4
+ * The wire-level contract between sound emission, propagation, and
5
+ * rendering. This file defines:
6
+ *
7
+ * - `VolumeTier` — the discrete emission-volume tier set
8
+ * (whisper / subdued / normal / raised / shouting) with platform
9
+ * propagation budgets.
10
+ * - `AudibilityTier` — the discrete listener-side tier set
11
+ * (silent / presence-only / fragments / muffled / full).
12
+ * - `Sound` — the emission shape an action constructs and hands to
13
+ * `context.emitSound` (Phase 6).
14
+ * - `AudibilityEvent` — the per-listener delivery shape produced by
15
+ * the propagation function (Phase 3) and routed through the sound
16
+ * channel (Phase 5).
17
+ *
18
+ * No behavior — pure shapes. Propagation logic lands in
19
+ * `@sharpee/engine` (Phase 3); trait definitions land in
20
+ * `@sharpee/world-model` (Phase 2). Both depend on this file.
21
+ *
22
+ * Owner context: `@sharpee/if-domain` — domain-layer contracts.
23
+ *
24
+ * @see ADR-172 — Spatial Sound Propagation
25
+ * @see ADR-173 — Wall Adjacency Primitive (substrate this rides on)
26
+ */
27
+ import type { EntityId } from "../../core/index";
28
+ /**
29
+ * The five discrete volume tiers an emitter may declare. Ordered from
30
+ * quietest to loudest. Each tier has an integer propagation budget (see
31
+ * `VOLUME_TIER_BUDGETS`); the propagation algorithm subtracts accumulated
32
+ * path cost from this budget to compute clarity at each listener.
33
+ *
34
+ * Discrete tiers are deliberate over continuous numeric volumes: authoring
35
+ * is qualitative, prose layers render per-tier, and continuous values
36
+ * invite balance tuning that produces no gameplay value.
37
+ */
38
+ export type VolumeTier = 'whisper' | 'subdued' | 'normal' | 'raised' | 'shouting';
39
+ /**
40
+ * Platform-default propagation budgets per volume tier (ADR-172). Stories
41
+ * that want a different acoustic register (a horror story with sound that
42
+ * carries unnaturally far, a soundproofed-bunker setting) override this
43
+ * table without the platform code changing.
44
+ *
45
+ * The budget is consumed against accumulated path cost during propagation;
46
+ * negative remainders below 1 collapse to `silent`.
47
+ */
48
+ export declare const VOLUME_TIER_BUDGETS: Readonly<Record<VolumeTier, number>>;
49
+ /**
50
+ * The five discrete audibility tiers the propagation function reports per
51
+ * listener. `silent` means the listener does not perceive the sound and
52
+ * receives no event; the other four are delivered as `AudibilityEvent`s
53
+ * with rendering modulated by tier.
54
+ *
55
+ * - `presence-only` — the listener knows a sound occurred (kind, rough
56
+ * direction) but no content passes.
57
+ * - `fragments` — partial content; key words, broken phrases.
58
+ * - `muffled` — full content, rendered with distortion framing at
59
+ * the prose layer.
60
+ * - `full` — verbatim; clean reception.
61
+ */
62
+ export type AudibilityTier = 'silent' | 'presence-only' | 'fragments' | 'muffled' | 'full';
63
+ /**
64
+ * A sound's *kind*: a coarse semantic classifier the rendering layer uses
65
+ * to pick per-`(kind, audibility_tier)` prose defaults. New kinds are
66
+ * added as the platform grows; this is a string union, not a closed enum,
67
+ * to keep the type extensible to story-level kinds.
68
+ *
69
+ * Examples chosen from ADR-172's running examples; this list is *not*
70
+ * exhaustive and not part of the platform contract — story code may pass
71
+ * any string here, with the language layer falling through to a generic
72
+ * default if no per-kind prose is registered.
73
+ */
74
+ export type SoundKind = string;
75
+ /**
76
+ * Optional structured content for a sound. Content-bearing sounds carry
77
+ * a content payload that audibility tier modulates: at `full` the content
78
+ * is verbatim; at `muffled` it's distorted; at `fragments` only key
79
+ * fragments pass; at `presence-only` no content passes (the listener
80
+ * only knows the sound happened).
81
+ *
82
+ * The shape carries a `messageId` (resolved by the language layer) and
83
+ * optional `params` for templating. Pattern-as-content (knock codes,
84
+ * rhythmic taps) is *not* a separate dimension — it composes through
85
+ * the same content + tier pipeline, with the language layer rendering
86
+ * pattern degradation per tier.
87
+ */
88
+ export interface ISoundContent {
89
+ /** Message ID resolved by the language layer (e.g. story-authored line ID). */
90
+ messageId: string;
91
+ /** Optional params for the message template; keys depend on the messageId. */
92
+ params?: Readonly<Record<string, unknown>>;
93
+ }
94
+ /**
95
+ * The emission shape an action hands to the platform's sound dispatcher.
96
+ *
97
+ * `sourceLocation` is the room-id the sound originates from; the
98
+ * propagation function uses it as the path-search root. `sourceEntity`
99
+ * is the entity that produced the sound (an actor, a device, an
100
+ * inanimate object) — propagation does not consult it, but downstream
101
+ * handlers and prose templates may.
102
+ *
103
+ * `kind` is the semantic classifier (see `SoundKind`). `volumeTier` is
104
+ * the emission-side tier (see `VolumeTier`). `content` is optional;
105
+ * sounds without content are *ambient* (a gunshot, breaking glass, a
106
+ * closing door) and the prose layer renders the sound itself rather
107
+ * than its content.
108
+ */
109
+ export interface ISound {
110
+ readonly sourceLocation: EntityId;
111
+ readonly sourceEntity: EntityId;
112
+ readonly kind: SoundKind;
113
+ readonly volumeTier: VolumeTier;
114
+ readonly content?: ISoundContent;
115
+ }
116
+ /**
117
+ * The per-listener event the propagation function produces and the sound
118
+ * channel routes. Carries enough context for both prose rendering and
119
+ * audio-cue mapping.
120
+ *
121
+ * - `sourceRoomId` — room-id where the sound was emitted.
122
+ * - `targetRoomId` — room-id the listener is in when the sound reaches
123
+ * them (typically the listener's current room).
124
+ * - `wallId` — the wall entity-id whose acoustic cost contributed
125
+ * to the lowest-cost path, when the path crosses one
126
+ * wall. Optional — may be absent for paths that go
127
+ * through doors, conduits, or are within the same
128
+ * room. Future ADRs may extend this to a path of
129
+ * crossings; today the field is single-valued for
130
+ * common single-hop cases.
131
+ * - `sourceEntityId` — the entity that emitted the sound (mirrors
132
+ * `Sound.sourceEntity`).
133
+ * - `kind` — the sound's kind, copied from the emission.
134
+ * - `volumeTier` — the emission's volume tier, copied as-emitted.
135
+ * - `audibilityTier` — the propagation result for this listener.
136
+ * Never `silent`: silent results suppress event
137
+ * delivery entirely (no `AudibilityEvent` is
138
+ * produced).
139
+ * - `content` — copied from the emission iff content-bearing.
140
+ * - `timestamp` — engine-provided turn-sequence integer for ordering.
141
+ *
142
+ * The prose layer maps `(kind, audibilityTier)` to a default rendering
143
+ * pattern; stories override per-kind. The audio-channel renderer maps
144
+ * `audibilityTier` to a playback volume via ADR-169's fade infrastructure.
145
+ *
146
+ * Adding fields to this interface requires a future ADR — it is the
147
+ * contract L2+ ADRs (NPC voice, conversation choreography, stealth
148
+ * observation) ride on.
149
+ */
150
+ export interface IAudibilityEvent {
151
+ readonly sourceRoomId: EntityId;
152
+ readonly targetRoomId: EntityId;
153
+ readonly wallId?: EntityId;
154
+ readonly sourceEntityId: EntityId;
155
+ readonly kind: SoundKind;
156
+ readonly volumeTier: VolumeTier;
157
+ /** Always one of the *delivered* tiers — never `'silent'`. */
158
+ readonly audibilityTier: Exclude<AudibilityTier, 'silent'>;
159
+ readonly content?: ISoundContent;
160
+ readonly timestamp: number;
161
+ }
162
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/if-domain/src/sound/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAM9C;;;;;;;;;GASG;AACH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;AAElF;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAMnE,CAAC;AAMH;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,eAAe,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,CAAC;AAM3F;;;;;;;;;;GAUG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC;AAE/B;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,aAAa;IAC5B,+EAA+E;IAC/E,SAAS,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC5C;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,cAAc,EAAE,QAAQ,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;CAClC;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,QAAQ,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,8DAA8D;IAC9D,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;IAC3D,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B"}
package/sound/types.js ADDED
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ /**
3
+ * @file Sound and AudibilityEvent domain types (ADR-172).
4
+ *
5
+ * The wire-level contract between sound emission, propagation, and
6
+ * rendering. This file defines:
7
+ *
8
+ * - `VolumeTier` — the discrete emission-volume tier set
9
+ * (whisper / subdued / normal / raised / shouting) with platform
10
+ * propagation budgets.
11
+ * - `AudibilityTier` — the discrete listener-side tier set
12
+ * (silent / presence-only / fragments / muffled / full).
13
+ * - `Sound` — the emission shape an action constructs and hands to
14
+ * `context.emitSound` (Phase 6).
15
+ * - `AudibilityEvent` — the per-listener delivery shape produced by
16
+ * the propagation function (Phase 3) and routed through the sound
17
+ * channel (Phase 5).
18
+ *
19
+ * No behavior — pure shapes. Propagation logic lands in
20
+ * `@sharpee/engine` (Phase 3); trait definitions land in
21
+ * `@sharpee/world-model` (Phase 2). Both depend on this file.
22
+ *
23
+ * Owner context: `@sharpee/if-domain` — domain-layer contracts.
24
+ *
25
+ * @see ADR-172 — Spatial Sound Propagation
26
+ * @see ADR-173 — Wall Adjacency Primitive (substrate this rides on)
27
+ */
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.VOLUME_TIER_BUDGETS = void 0;
30
+ /**
31
+ * Platform-default propagation budgets per volume tier (ADR-172). Stories
32
+ * that want a different acoustic register (a horror story with sound that
33
+ * carries unnaturally far, a soundproofed-bunker setting) override this
34
+ * table without the platform code changing.
35
+ *
36
+ * The budget is consumed against accumulated path cost during propagation;
37
+ * negative remainders below 1 collapse to `silent`.
38
+ */
39
+ exports.VOLUME_TIER_BUDGETS = Object.freeze({
40
+ whisper: 1,
41
+ subdued: 2,
42
+ normal: 5,
43
+ raised: 7,
44
+ shouting: 9,
45
+ });
46
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../../../repos/sharpee/packages/if-domain/src/sound/types.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;;;AAoBH;;;;;;;;GAQG;AACU,QAAA,mBAAmB,GAAyC,MAAM,CAAC,MAAM,CAAC;IACrF,OAAO,EAAE,CAAC;IACV,OAAO,EAAE,CAAC;IACV,MAAM,EAAE,CAAC;IACT,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,CAAC;CACZ,CAAC,CAAC"}