@onlyworlds/sdk 3.1.0 → 4.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,913 +1,435 @@
1
- /**
2
- * Modern branded types for type-safe element relationships
3
- * Provides compile-time safety while maintaining zero runtime overhead
4
- */
5
- declare const __brand: unique symbol;
6
- type Brand<B> = {
7
- [__brand]: B;
8
- };
9
- /**
10
- * Branded type for element IDs - ensures type safety for relationships
11
- * @template T The element type this ID references
12
- */
13
- type ElementId<T extends ElementType$1> = string & Brand<T>;
14
- /**
15
- * Branded type for arrays of element IDs
16
- * @template T The element type these IDs reference
17
- */
18
- type ElementIds<T extends ElementType$1> = ElementId<T>[];
19
- /**
20
- * Special type for IDs that can reference ANY element type
21
- * Used in cases like Pin.element_type where the target can be any OnlyWorlds element
22
- */
23
- type AnyElementId = ElementId<ElementType$1>;
24
- /**
25
- * Base fields shared by all OnlyWorlds elements
26
- */
27
- interface BaseElement {
28
- id?: string;
1
+ /** Every element carries these. The extension index signature admits namespaced
2
+ * pass-through fields (atlas_* / shadow_* / x_*) returned verbatim by the server. */
3
+ interface OwElementBase {
4
+ /** Element type slug (server-managed, read-only). */
5
+ type: string;
6
+ /** Unique identifier, uuidv7 format. */
7
+ id: string;
8
+ /** Name of the element. */
29
9
  name: string;
10
+ /** Any kind of details about the element. */
30
11
  description?: string;
31
- image_url?: string;
12
+ /** The top level category to which the element belongs. */
32
13
  supertype?: string;
14
+ /** The sub level category through which the element is further classified. */
33
15
  subtype?: string;
34
- world?: string;
35
- created_at?: string;
36
- updated_at?: string;
37
- }
38
- /**
39
- * World element type
40
- */
41
- interface World {
42
- id?: string;
43
- api_key: string;
44
- name: string;
45
- description?: string;
46
- version?: string;
16
+ /** URL to an image representing the element. */
47
17
  image_url?: string;
48
- time_format_equivalents?: any[];
49
- time_format_names?: any[];
50
- time_basic_unit?: string;
51
- time_range_min?: number;
52
- time_range_max?: number;
53
- time_current?: number;
54
- user?: string;
18
+ /** Creation timestamp (server-managed, read-only). */
55
19
  created_at?: string;
20
+ /** Last-update timestamp (server-managed, read-only). */
56
21
  updated_at?: string;
22
+ /** Per-world change cursor, stamped on every write (server-managed, read-only). */
23
+ change_seq?: number;
24
+ /** Namespaced extension fields (atlas_* / shadow_* / x_*), returned verbatim. */
25
+ [ext: string]: unknown;
57
26
  }
58
- /**
59
- * World input type for creation/updates
60
- */
61
- interface WorldInput {
27
+ type ElementType = 'ability' | 'character' | 'collective' | 'construct' | 'creature' | 'event' | 'family' | 'institution' | 'language' | 'law' | 'location' | 'map' | 'marker' | 'narrative' | 'object' | 'phenomenon' | 'pin' | 'relation' | 'species' | 'title' | 'trait' | 'zone';
28
+ declare const ELEMENT_TYPES: ElementType[];
29
+ /** Canonical OnlyWorlds schema version. Source: canonical VERSION file, carried into keel schema/ by the refresh script (keel 492168c). */
30
+ declare const ONLYWORLDS_VERSION: "00.30.00";
31
+ /** The four semantic families (colour carries the family; ELEMENT_ICONS carries the type). */
32
+ type ElementFamily = 'agents' | 'world' | 'abstract' | 'temporal';
33
+ /** Per-type semantic family. Source: keel's PRESENTATION-WRAPPER schema key `family:`
34
+ * (first-party rendering metadata, keel-only — NOT part of the council-governed
35
+ * OnlyWorlds standard; see keel/schema-pipeline.md "The wrapper layer"). */
36
+ declare const ELEMENT_FAMILIES: Record<ElementType, ElementFamily>;
37
+ /** Material Symbols icon name per type. Source: keel's PRESENTATION-WRAPPER key `icon:` (keel 56c124a). */
38
+ declare const ELEMENT_ICONS: Record<ElementType, string>;
39
+ /** Field grouping for display. DERIVED from the canonical schema's own document
40
+ * structure (top-level property groups, document order = display order). */
41
+ interface SectionInfo {
62
42
  name: string;
63
- description?: string;
64
- version?: string;
65
- image_url?: string;
66
- time_format_equivalents?: any[];
67
- time_format_names?: any[];
68
- time_basic_unit?: string;
69
- time_range_min?: number;
70
- time_range_max?: number;
71
- time_current?: number;
72
- }
73
- /**
74
- * Ability element type
75
- * Fields organized by sections: Mechanics, World
76
- */
77
- interface Ability extends BaseElement {
78
- activation?: string;
79
- duration?: number;
80
- potency?: number;
81
- range?: number;
82
- effects?: ElementIds<ElementType$1.Phenomenon>;
83
- challenges?: string;
84
- talents?: ElementIds<ElementType$1.Trait>;
85
- requisites?: ElementIds<ElementType$1.Construct>;
86
- prevalence?: string;
87
- tradition?: ElementId<ElementType$1.Construct>;
88
- source?: ElementId<ElementType$1.Phenomenon>;
89
- locus?: ElementId<ElementType$1.Location>;
90
- instruments?: ElementIds<ElementType$1.Object>;
91
- systems?: ElementIds<ElementType$1.Construct>;
92
- }
93
- /**
94
- * Object element type
95
- * Fields organized by sections: Form, Function, World
96
- */
97
- interface Object$1 extends BaseElement {
98
- aesthetics?: string;
99
- weight?: number;
100
- amount?: number;
101
- parent_object?: ElementId<ElementType$1.Object>;
102
- materials?: ElementIds<ElementType$1.Construct>;
103
- technology?: ElementIds<ElementType$1.Construct>;
104
- utility?: string;
105
- effects?: ElementIds<ElementType$1.Phenomenon>;
106
- abilities?: ElementIds<ElementType$1.Ability>;
107
- consumes?: ElementIds<ElementType$1.Construct>;
108
- origins?: string;
109
- location?: ElementId<ElementType$1.Location>;
110
- language?: ElementId<ElementType$1.Language>;
111
- affinities?: ElementIds<ElementType$1.Trait>;
112
- }
113
- /**
114
- * Character element type
115
- * Fields organized by sections: Constitution, Origins, World, Personality, Social, TTRPG
116
- */
117
- interface Character extends BaseElement {
118
- physicality?: string;
119
- mentality?: string;
120
- height?: number;
121
- weight?: number;
122
- species?: ElementIds<ElementType$1.Species>;
123
- traits?: ElementIds<ElementType$1.Trait>;
124
- abilities?: ElementIds<ElementType$1.Ability>;
125
- background?: string;
126
- motivations?: string;
127
- birth_date?: number;
128
- birthplace?: ElementId<ElementType$1.Location>;
129
- languages?: ElementIds<ElementType$1.Language>;
130
- reputation?: string;
131
- location?: ElementId<ElementType$1.Location>;
132
- objects?: ElementIds<ElementType$1.Object>;
133
- institutions?: ElementIds<ElementType$1.Institution>;
134
- charisma?: number;
135
- coercion?: number;
136
- competence?: number;
137
- compassion?: number;
138
- creativity?: number;
139
- courage?: number;
140
- family?: ElementIds<ElementType$1.Family>;
141
- friends?: ElementIds<ElementType$1.Character>;
142
- rivals?: ElementIds<ElementType$1.Character>;
143
- level?: number;
144
- hit_points?: number;
145
- STR?: number;
146
- DEX?: number;
147
- CON?: number;
148
- INT?: number;
149
- WIS?: number;
150
- CHA?: number;
151
- }
152
- /**
153
- * Collective element type
154
- * Fields organized by sections: Formation, Dynamics, World
155
- */
156
- interface Collective extends BaseElement {
157
- composition?: string;
158
- count?: number;
159
- formation_date?: number;
160
- operator?: ElementId<ElementType$1.Institution>;
161
- equipment?: ElementIds<ElementType$1.Construct>;
162
- activity?: string;
163
- disposition?: string;
164
- state?: string;
165
- abilities?: ElementIds<ElementType$1.Ability>;
166
- symbolism?: ElementIds<ElementType$1.Construct>;
167
- species?: ElementIds<ElementType$1.Species>;
168
- characters?: ElementIds<ElementType$1.Character>;
169
- creatures?: ElementIds<ElementType$1.Creature>;
170
- phenomena?: ElementIds<ElementType$1.Phenomenon>;
171
- }
172
- /**
173
- * Construct element type
174
- * Fields organized by sections: Nature, Involves
175
- */
176
- interface Construct extends BaseElement {
177
- rationale?: string;
178
- history?: string;
179
- status?: string;
180
- reach?: string;
181
- start_date?: number;
182
- end_date?: number;
183
- founder?: ElementId<ElementType$1.Character>;
184
- custodian?: ElementId<ElementType$1.Institution>;
185
- characters?: ElementIds<ElementType$1.Character>;
186
- objects?: ElementIds<ElementType$1.Object>;
187
- locations?: ElementIds<ElementType$1.Location>;
188
- species?: ElementIds<ElementType$1.Species>;
189
- creatures?: ElementIds<ElementType$1.Creature>;
190
- institutions?: ElementIds<ElementType$1.Institution>;
191
- traits?: ElementIds<ElementType$1.Trait>;
192
- collectives?: ElementIds<ElementType$1.Collective>;
193
- zones?: ElementIds<ElementType$1.Zone>;
194
- abilities?: ElementIds<ElementType$1.Ability>;
195
- phenomena?: ElementIds<ElementType$1.Phenomenon>;
196
- languages?: ElementIds<ElementType$1.Language>;
197
- families?: ElementIds<ElementType$1.Family>;
198
- relations?: ElementIds<ElementType$1.Relation>;
199
- titles?: ElementIds<ElementType$1.Title>;
200
- constructs?: ElementIds<ElementType$1.Construct>;
201
- events?: ElementIds<ElementType$1.Event>;
202
- narratives?: ElementIds<ElementType$1.Narrative>;
203
- }
204
- /**
205
- * Creature element type
206
- * Fields organized by sections: Biology, Behaviour, World, TTRPG
207
- */
208
- interface Creature extends BaseElement {
209
- appearance?: string;
210
- weight?: number;
211
- height?: number;
212
- species?: ElementIds<ElementType$1.Species>;
213
- habits?: string;
214
- demeanor?: string;
215
- traits?: ElementIds<ElementType$1.Trait>;
216
- abilities?: ElementIds<ElementType$1.Ability>;
217
- languages?: ElementIds<ElementType$1.Language>;
218
- status?: string;
219
- birth_date?: number;
220
- location?: ElementId<ElementType$1.Location>;
221
- zone?: ElementId<ElementType$1.Zone>;
222
- challenge_rating?: number;
223
- hit_points?: number;
224
- armor_class?: number;
225
- speed?: number;
226
- actions?: ElementIds<ElementType$1.Ability>;
227
- }
228
- /**
229
- * Event element type
230
- * Fields organized by sections: Nature, Involves
231
- */
232
- interface Event extends BaseElement {
233
- history?: string;
234
- challenges?: string;
235
- consequences?: string;
236
- start_date?: number;
237
- end_date?: number;
238
- triggers?: ElementIds<ElementType$1.Event>;
239
- characters?: ElementIds<ElementType$1.Character>;
240
- objects?: ElementIds<ElementType$1.Object>;
241
- locations?: ElementIds<ElementType$1.Location>;
242
- species?: ElementIds<ElementType$1.Species>;
243
- creatures?: ElementIds<ElementType$1.Creature>;
244
- institutions?: ElementIds<ElementType$1.Institution>;
245
- traits?: ElementIds<ElementType$1.Trait>;
246
- collectives?: ElementIds<ElementType$1.Collective>;
247
- zones?: ElementIds<ElementType$1.Zone>;
248
- abilities?: ElementIds<ElementType$1.Ability>;
249
- phenomena?: ElementIds<ElementType$1.Phenomenon>;
250
- languages?: ElementIds<ElementType$1.Language>;
251
- families?: ElementIds<ElementType$1.Family>;
252
- relations?: ElementIds<ElementType$1.Relation>;
253
- titles?: ElementIds<ElementType$1.Title>;
254
- constructs?: ElementIds<ElementType$1.Construct>;
255
- }
256
- /**
257
- * Family element type
258
- * Fields organized by sections: Identity, World
259
- */
260
- interface Family extends BaseElement {
261
- spirit?: string;
262
- history?: string;
263
- traditions?: ElementIds<ElementType$1.Construct>;
264
- traits?: ElementIds<ElementType$1.Trait>;
265
- abilities?: ElementIds<ElementType$1.Ability>;
266
- languages?: ElementIds<ElementType$1.Language>;
267
- ancestors?: ElementIds<ElementType$1.Character>;
268
- reputation?: string;
269
- estates?: ElementIds<ElementType$1.Location>;
270
- governs?: ElementIds<ElementType$1.Institution>;
271
- heirlooms?: ElementIds<ElementType$1.Object>;
272
- creatures?: ElementIds<ElementType$1.Creature>;
273
- }
274
- /**
275
- * Institution element type
276
- * Fields organized by sections: Foundation, Claims, World
277
- */
278
- interface Institution extends BaseElement {
279
- doctrine?: string;
280
- founding_date?: number;
281
- parent_institution?: ElementId<ElementType$1.Institution>;
282
- zones?: ElementIds<ElementType$1.Zone>;
283
- objects?: ElementIds<ElementType$1.Object>;
284
- creatures?: ElementIds<ElementType$1.Creature>;
285
- status?: string;
286
- allies?: ElementIds<ElementType$1.Institution>;
287
- adversaries?: ElementIds<ElementType$1.Institution>;
288
- constructs?: ElementIds<ElementType$1.Construct>;
289
- }
290
- /**
291
- * Language element type
292
- * Fields organized by sections: Structure, World
293
- */
294
- interface Language extends BaseElement {
295
- phonology?: string;
296
- grammar?: string;
297
- lexicon?: string;
298
- writing?: string;
299
- classification?: ElementId<ElementType$1.Construct>;
300
- status?: string;
301
- spread?: ElementIds<ElementType$1.Location>;
302
- dialects?: ElementIds<ElementType$1.Language>;
303
- }
304
- /**
305
- * Law element type
306
- * Fields organized by sections: Code, World
307
- */
308
- interface Law extends BaseElement {
309
- declaration?: string;
310
- purpose?: string;
311
- date?: number;
312
- parent_law?: ElementId<ElementType$1.Law>;
313
- penalties?: ElementIds<ElementType$1.Construct>;
314
- author?: ElementId<ElementType$1.Institution>;
315
- locations?: ElementIds<ElementType$1.Location>;
316
- zones?: ElementIds<ElementType$1.Zone>;
317
- prohibitions?: ElementIds<ElementType$1.Construct>;
318
- adjudicators?: ElementIds<ElementType$1.Title>;
319
- enforcers?: ElementIds<ElementType$1.Title>;
320
- }
321
- /**
322
- * Location element type
323
- * Fields organized by sections: Setting, Politics, World, Production, Commerce, Construction, Defense
324
- */
325
- interface Location extends BaseElement {
326
- form?: string;
327
- function?: string;
328
- founding_date?: number;
329
- parent_location?: ElementId<ElementType$1.Location>;
330
- populations?: ElementIds<ElementType$1.Collective>;
331
- political_climate?: string;
332
- primary_power?: ElementId<ElementType$1.Institution>;
333
- governing_title?: ElementId<ElementType$1.Title>;
334
- secondary_powers?: ElementIds<ElementType$1.Institution>;
335
- zone?: ElementId<ElementType$1.Zone>;
336
- rival?: ElementId<ElementType$1.Location>;
337
- partner?: ElementId<ElementType$1.Location>;
338
- customs?: string;
339
- founders?: ElementIds<ElementType$1.Character>;
340
- cults?: ElementIds<ElementType$1.Construct>;
341
- delicacies?: ElementIds<ElementType$1.Species>;
342
- extraction_methods?: ElementIds<ElementType$1.Construct>;
343
- extraction_goods?: ElementIds<ElementType$1.Construct>;
344
- industry_methods?: ElementIds<ElementType$1.Construct>;
345
- industry_goods?: ElementIds<ElementType$1.Construct>;
346
- infrastructure?: string;
347
- extraction_markets?: ElementIds<ElementType$1.Location>;
348
- industry_markets?: ElementIds<ElementType$1.Location>;
349
- currencies?: ElementIds<ElementType$1.Construct>;
350
- architecture?: string;
351
- buildings?: ElementIds<ElementType$1.Object>;
352
- building_methods?: ElementIds<ElementType$1.Construct>;
353
- defensibility?: string;
354
- elevation?: number;
355
- fighters?: ElementIds<ElementType$1.Construct>;
356
- defensive_objects?: ElementIds<ElementType$1.Object>;
43
+ order: number;
44
+ fields: string[];
357
45
  }
46
+ declare const ELEMENT_SECTIONS: Record<ElementType, SectionInfo[]>;
47
+
358
48
  /**
359
- * Phenomenon element type
360
- * Fields organized by sections: Mechanics, World
49
+ * keel v2 engine absorbed from Assembly's ow-v2-client v0.9.0 (Kael),
50
+ * wire-corrected against live staging fixtures 2026-07-18.
51
+ *
52
+ * OnlyWorlds v2 (keel) wire types -- the NON-generated, hand-owned wire shapes
53
+ * (envelopes, pages, bulk, changes, config). Per-type element field typing is
54
+ * generated (types.generated.ts). One-shape principle: a field reads the way it
55
+ * writes -- links are UUID arrays (or UUID/null), same name both directions.
56
+ * No `_ids` suffix in v2.
361
57
  */
362
- interface Phenomenon extends BaseElement {
363
- expression?: string;
364
- effects?: string;
365
- duration?: number;
366
- catalysts?: ElementIds<ElementType$1.Object>;
367
- empowerments?: ElementIds<ElementType$1.Ability>;
368
- mythology?: string;
369
- system?: ElementId<ElementType$1.Phenomenon>;
370
- triggers?: ElementIds<ElementType$1.Construct>;
371
- wielders?: ElementIds<ElementType$1.Character>;
372
- environments?: ElementIds<ElementType$1.Location>;
58
+
59
+ /** An element as read from / written to the v2 API. Loose base + extension keys. */
60
+ type OwElement = OwElementBase;
61
+ /** Spatial types live under spatial/ in the OW Folder Format. */
62
+ declare const SPATIAL_TYPES: readonly ElementType[];
63
+ interface OwWorldMeta {
64
+ id: string;
65
+ name: string;
66
+ updated_at?: string;
67
+ public_read?: boolean;
68
+ [field: string]: unknown;
373
69
  }
374
- /**
375
- * Relation element type
376
- * Fields organized by sections: Nature, Involves
377
- */
378
- interface Relation extends BaseElement {
379
- background?: string;
380
- start_date?: number;
381
- end_date?: number;
382
- intensity?: number;
383
- actor?: ElementId<ElementType$1.Character>;
384
- events?: ElementIds<ElementType$1.Event>;
385
- characters?: ElementIds<ElementType$1.Character>;
386
- objects?: ElementIds<ElementType$1.Object>;
387
- locations?: ElementIds<ElementType$1.Location>;
388
- species?: ElementIds<ElementType$1.Species>;
389
- creatures?: ElementIds<ElementType$1.Creature>;
390
- institutions?: ElementIds<ElementType$1.Institution>;
391
- traits?: ElementIds<ElementType$1.Trait>;
392
- collectives?: ElementIds<ElementType$1.Collective>;
393
- zones?: ElementIds<ElementType$1.Zone>;
394
- abilities?: ElementIds<ElementType$1.Ability>;
395
- phenomena?: ElementIds<ElementType$1.Phenomenon>;
396
- languages?: ElementIds<ElementType$1.Language>;
397
- families?: ElementIds<ElementType$1.Family>;
398
- titles?: ElementIds<ElementType$1.Title>;
399
- constructs?: ElementIds<ElementType$1.Construct>;
400
- narratives?: ElementIds<ElementType$1.Narrative>;
70
+ /** List envelope: cursor-paginated. */
71
+ interface OwPage<T = OwElement> {
72
+ data: T[];
73
+ has_more: boolean;
74
+ next_cursor: string | null;
401
75
  }
76
+ /** /changes feed -- discriminated union on `op`. Apply in order -> convergence. */
77
+ type OwChange = {
78
+ op: 'upsert';
79
+ id: string;
80
+ type: string;
81
+ element: OwElement;
82
+ updated_at: string;
83
+ [k: string]: unknown;
84
+ } | {
85
+ op: 'delete';
86
+ id: string;
87
+ type: string;
88
+ deleted_at: string;
89
+ [k: string]: unknown;
90
+ };
402
91
  /**
403
- * Species element type
404
- * Fields organized by sections: Biology, Psychology, World
92
+ * /changes response. Wire shape verified in keel source (core/changes.py) and
93
+ * pinned here: {cursor, changes, has_more, head}.
405
94
  */
406
- interface Species extends BaseElement {
407
- appearance?: string;
408
- life_span?: number;
409
- weight?: number;
410
- nourishment?: ElementIds<ElementType$1.Species>;
411
- reproduction?: ElementIds<ElementType$1.Construct>;
412
- adaptations?: ElementIds<ElementType$1.Ability>;
413
- instincts?: string;
414
- sociality?: string;
415
- temperament?: string;
416
- communication?: string;
417
- aggression?: number;
418
- traits?: ElementIds<ElementType$1.Trait>;
419
- role?: string;
420
- parent_species?: ElementId<ElementType$1.Species>;
421
- locations?: ElementIds<ElementType$1.Location>;
422
- zones?: ElementIds<ElementType$1.Zone>;
423
- affinities?: ElementIds<ElementType$1.Phenomenon>;
95
+ interface OwChangesPage {
96
+ /** Opaque compound cursor -- persist verbatim, never parse, never expires. */
97
+ cursor: string;
98
+ changes: OwChange[];
99
+ has_more: boolean;
100
+ /**
101
+ * World's current change_seq. If a persisted cursor is ever AHEAD of head,
102
+ * the server rewound (disaster restore) -- re-baseline from cursor zero
103
+ * instead of assuming caught-up.
104
+ */
105
+ head: number;
424
106
  }
425
- /**
426
- * Zone element type
427
- * Fields organized by sections: Scope, World
428
- */
429
- interface Zone extends BaseElement {
430
- role?: string;
431
- start_date?: number;
432
- end_date?: number;
433
- phenomena?: ElementIds<ElementType$1.Phenomenon>;
434
- linked_zones?: ElementIds<ElementType$1.Zone>;
435
- context?: string;
436
- populations?: ElementIds<ElementType$1.Collective>;
437
- titles?: ElementIds<ElementType$1.Title>;
438
- principles?: ElementIds<ElementType$1.Construct>;
107
+ interface OwBulkItem {
108
+ type: ElementType | string;
109
+ element: OwElement | Record<string, unknown>;
439
110
  }
440
111
  /**
441
- * Title element type
442
- * Fields organized by sections: Mandate, World
112
+ * One slot of a /bulk response. WIRE-CORRECTED (fixtures P2a/P2c): `status` is
113
+ * the NUMERIC HTTP status of that slot (201/400/...), success slots echo
114
+ * created_at/updated_at, error slots carry an OwErrorBody under `error`.
443
115
  */
444
- interface Title extends BaseElement {
445
- authority?: string;
446
- eligibility?: string;
447
- grant_date?: number;
448
- revoke_date?: number;
449
- issuer?: ElementId<ElementType$1.Institution>;
450
- body?: ElementId<ElementType$1.Institution>;
451
- superior_title?: ElementId<ElementType$1.Title>;
452
- holders?: ElementIds<ElementType$1.Character>;
453
- symbols?: ElementIds<ElementType$1.Object>;
454
- status?: string;
455
- history?: string;
456
- characters?: ElementIds<ElementType$1.Character>;
457
- institutions?: ElementIds<ElementType$1.Institution>;
458
- families?: ElementIds<ElementType$1.Family>;
459
- zones?: ElementIds<ElementType$1.Zone>;
460
- locations?: ElementIds<ElementType$1.Location>;
461
- objects?: ElementIds<ElementType$1.Object>;
462
- constructs?: ElementIds<ElementType$1.Construct>;
463
- laws?: ElementIds<ElementType$1.Law>;
464
- collectives?: ElementIds<ElementType$1.Collective>;
465
- creatures?: ElementIds<ElementType$1.Creature>;
466
- phenomena?: ElementIds<ElementType$1.Phenomenon>;
467
- species?: ElementIds<ElementType$1.Species>;
468
- languages?: ElementIds<ElementType$1.Language>;
116
+ interface OwBulkItemResult {
117
+ status: number;
118
+ id?: string;
119
+ created_at?: string;
120
+ updated_at?: string;
121
+ error?: OwErrorBody;
469
122
  }
470
- /**
471
- * Trait element type
472
- * Fields organized by sections: Qualitative, Quantitative, World
473
- */
474
- interface Trait extends BaseElement {
475
- social_effects?: string;
476
- physical_effects?: string;
477
- functional_effects?: string;
478
- personality_effects?: string;
479
- behaviour_effects?: string;
480
- charisma?: number;
481
- coercion?: number;
482
- competence?: number;
483
- compassion?: number;
484
- creativity?: number;
485
- courage?: number;
486
- significance?: string;
487
- anti_trait?: ElementId<ElementType$1.Trait>;
488
- empowered_abilities?: ElementIds<ElementType$1.Ability>;
123
+ /** The wire error envelope carried in error slots and thrown errors. */
124
+ interface OwErrorBody {
125
+ type?: string;
126
+ code?: string;
127
+ message?: string;
128
+ param?: string | null;
129
+ doc_url?: string;
489
130
  }
490
131
  /**
491
- * Narrative element type
492
- * Fields organized by sections: Context, Involves
132
+ * /bulk response. WIRE-CORRECTED (fixtures P2a/P2c): the array key is `items`,
133
+ * not `results`. `wasReplay` is populated by the client from the (lowercase on
134
+ * the wire) Idempotent-Replay response header (fixture P2b) -- not a wire field.
493
135
  */
494
- interface Narrative extends BaseElement {
495
- story?: string;
496
- consequences?: string;
497
- start_date?: number;
498
- end_date?: number;
499
- order?: number;
500
- parent_narrative?: ElementId<ElementType$1.Narrative>;
501
- protagonist?: ElementId<ElementType$1.Character>;
502
- antagonist?: ElementId<ElementType$1.Character>;
503
- narrator?: ElementId<ElementType$1.Character>;
504
- conservator?: ElementId<ElementType$1.Institution>;
505
- events?: ElementIds<ElementType$1.Event>;
506
- characters?: ElementIds<ElementType$1.Character>;
507
- objects?: ElementIds<ElementType$1.Object>;
508
- locations?: ElementIds<ElementType$1.Location>;
509
- species?: ElementIds<ElementType$1.Species>;
510
- creatures?: ElementIds<ElementType$1.Creature>;
511
- institutions?: ElementIds<ElementType$1.Institution>;
512
- traits?: ElementIds<ElementType$1.Trait>;
513
- collectives?: ElementIds<ElementType$1.Collective>;
514
- zones?: ElementIds<ElementType$1.Zone>;
515
- abilities?: ElementIds<ElementType$1.Ability>;
516
- phenomena?: ElementIds<ElementType$1.Phenomenon>;
517
- languages?: ElementIds<ElementType$1.Language>;
518
- families?: ElementIds<ElementType$1.Family>;
519
- relations?: ElementIds<ElementType$1.Relation>;
520
- titles?: ElementIds<ElementType$1.Title>;
521
- constructs?: ElementIds<ElementType$1.Construct>;
522
- laws?: ElementIds<ElementType$1.Law>;
136
+ interface OwBulkResponse {
137
+ errors: boolean;
138
+ items: OwBulkItemResult[];
139
+ /** Client-derived: true when the server replayed a prior Idempotency-Key. */
140
+ wasReplay?: boolean;
141
+ [k: string]: unknown;
523
142
  }
524
- /**
525
- * Map element type
526
- * Fields organized by sections: Details
527
- */
528
- interface Map extends BaseElement {
529
- background_color?: string;
530
- hierarchy?: number;
531
- width?: number;
532
- height?: number;
533
- depth?: number;
534
- parent_map?: ElementId<ElementType$1.Map>;
535
- location?: ElementId<ElementType$1.Location>;
143
+ interface OwLinkEdit {
144
+ add?: string[];
145
+ remove?: string[];
536
146
  }
537
- /**
538
- * Marker element type
539
- * Fields organized by sections: Details
540
- */
541
- interface Marker extends BaseElement {
542
- map?: ElementId<ElementType$1.Map>;
543
- zone?: ElementId<ElementType$1.Zone>;
544
- x?: number;
545
- y?: number;
546
- z?: number;
547
- order?: number;
147
+ interface ListParams {
148
+ limit?: number;
149
+ cursor?: string;
150
+ /** One-level stub expansion, e.g. ['friends', 'location']. */
151
+ expand?: string[];
152
+ /** Sparse include-set of field names. */
153
+ fields?: string[];
154
+ /**
155
+ * Blessed Django-style filters: __icontains, __in, __gte, __lte, __isnull,
156
+ * supertype/subtype equality. Unknown params 422 loudly server-side -- the
157
+ * client passes them through and lets the platform name the typo.
158
+ */
159
+ filter?: Record<string, string | number | boolean>;
548
160
  }
549
- /**
550
- * Pin element type
551
- * Fields organized by sections: Details
552
- */
553
- interface Pin extends BaseElement {
554
- map?: ElementId<ElementType$1.Map>;
555
- element_type?: ElementType$1;
556
- element_id?: AnyElementId;
161
+ interface OwClientConfig {
162
+ /** ow_w_ / ow_r_ / ow_a_ prefixed key, or grandfathered 10-digit legacy key. */
163
+ apiKey: string;
557
164
  /**
558
- * X coordinate on map (must be integer)
559
- * The API requires integer values. Float coordinates from mouse events
560
- * or calculations should be rounded: Math.round(x)
165
+ * Optional. Required for writes when the world has a PIN, and for legacy-key
166
+ * reads of private worlds. Prefixed keys read PIN-less. String, not number --
167
+ * '0123' !== 123.
561
168
  */
562
- x?: number;
169
+ apiPin?: string;
170
+ /** Default: https://www.onlyworlds.com/api/v2 */
171
+ baseUrl?: string;
563
172
  /**
564
- * Y coordinate on map (must be integer)
565
- * The API requires integer values. Float coordinates from mouse events
566
- * or calculations should be rounded: Math.round(y)
173
+ * Page size for element lists. Default 100 (server default; max 1000).
174
+ * Deliberately visible in config: page size is a citizenship property.
567
175
  */
568
- y?: number;
176
+ pageSize?: number;
569
177
  /**
570
- * Z coordinate for 3D positioning (must be integer)
571
- * The API requires integer values. Float coordinates should be rounded: Math.round(z)
178
+ * Page size for /changes pulls. Default 100. Live precedents: Obsidian 100,
179
+ * Atlas 250, MCP 25. /changes is the platform's heaviest route -- be polite.
572
180
  */
573
- z?: number;
181
+ changesPageSize?: number;
182
+ /** Injectable for tests / fake-keel harnesses. Defaults to globalThis.fetch. */
183
+ fetch?: typeof globalThis.fetch;
574
184
  }
185
+
575
186
  /**
576
- * Input types for API requests
577
- * Use field names without _id/_ids suffix - prepareRelations() handles conversion
187
+ * keel v2 engine absorbed from Assembly's ow-v2-client v0.9.0 (Kael),
188
+ * wire-corrected against live staging fixtures 2026-07-18.
189
+ *
190
+ * keel error envelope handling. The error contract is part of the contract:
191
+ * envelopes carry a machine `code` and a `doc_url` fragment anchored at
192
+ * onlyworlds.github.io/api/errors -- surface both, always. The live wire
193
+ * envelope also carries `type` and `param` (fixtures P4a/P2c); both are
194
+ * surfaced on the thrown error.
578
195
  */
579
- interface AbilityInput extends Omit<Ability, 'tradition' | 'source' | 'locus' | 'effects' | 'talents' | 'requisites' | 'instruments' | 'systems'> {
580
- tradition?: string;
581
- source?: string;
582
- locus?: string;
583
- effects?: string[];
584
- talents?: string[];
585
- requisites?: string[];
586
- instruments?: string[];
587
- systems?: string[];
588
- }
589
- interface ObjectInput extends Omit<Object$1, 'parent_object' | 'location' | 'language' | 'materials' | 'technology' | 'effects' | 'abilities' | 'consumes' | 'affinities'> {
590
- parent_object?: string;
591
- location?: string;
592
- language?: string;
593
- materials?: string[];
594
- technology?: string[];
595
- effects?: string[];
596
- abilities?: string[];
597
- consumes?: string[];
598
- affinities?: string[];
599
- }
600
- interface CharacterInput extends Omit<Character, 'birthplace' | 'location' | 'species' | 'traits' | 'abilities' | 'languages' | 'objects' | 'institutions' | 'family' | 'friends' | 'rivals'> {
601
- birthplace?: string;
602
- location?: string;
603
- species?: string[];
604
- traits?: string[];
605
- abilities?: string[];
606
- languages?: string[];
607
- objects?: string[];
608
- institutions?: string[];
609
- family?: string[];
610
- friends?: string[];
611
- rivals?: string[];
612
- }
613
- interface CollectiveInput extends Omit<Collective, 'operator' | 'equipment' | 'abilities' | 'symbolism' | 'species' | 'characters' | 'creatures' | 'phenomena'> {
614
- operator?: string;
615
- equipment?: string[];
616
- abilities?: string[];
617
- symbolism?: string[];
618
- species?: string[];
619
- characters?: string[];
620
- creatures?: string[];
621
- phenomena?: string[];
622
- }
623
- interface ConstructInput extends Omit<Construct, 'founder' | 'custodian' | 'characters' | 'objects' | 'locations' | 'species' | 'creatures' | 'institutions' | 'traits' | 'collectives' | 'zones' | 'abilities' | 'phenomena' | 'languages' | 'families' | 'relations' | 'titles' | 'constructs' | 'events' | 'narratives'> {
624
- founder?: string;
625
- custodian?: string;
626
- characters?: string[];
627
- objects?: string[];
628
- locations?: string[];
629
- species?: string[];
630
- creatures?: string[];
631
- institutions?: string[];
632
- traits?: string[];
633
- collectives?: string[];
634
- zones?: string[];
635
- abilities?: string[];
636
- phenomena?: string[];
637
- languages?: string[];
638
- families?: string[];
639
- relations?: string[];
640
- titles?: string[];
641
- constructs?: string[];
642
- events?: string[];
643
- narratives?: string[];
644
- }
645
- interface CreatureInput extends Omit<Creature, 'location' | 'zone' | 'species' | 'traits' | 'abilities' | 'languages' | 'actions'> {
646
- location?: string;
647
- zone?: string;
648
- species?: string[];
649
- traits?: string[];
650
- abilities?: string[];
651
- languages?: string[];
652
- actions?: string[];
653
- }
654
- interface EventInput extends Omit<Event, 'triggers' | 'characters' | 'objects' | 'locations' | 'species' | 'creatures' | 'institutions' | 'traits' | 'collectives' | 'zones' | 'abilities' | 'phenomena' | 'languages' | 'families' | 'relations' | 'titles' | 'constructs'> {
655
- triggers?: string[];
656
- characters?: string[];
657
- objects?: string[];
658
- locations?: string[];
659
- species?: string[];
660
- creatures?: string[];
661
- institutions?: string[];
662
- traits?: string[];
663
- collectives?: string[];
664
- zones?: string[];
665
- abilities?: string[];
666
- phenomena?: string[];
667
- languages?: string[];
668
- families?: string[];
669
- relations?: string[];
670
- titles?: string[];
671
- constructs?: string[];
196
+ /** Auth codes are distinguishable by design; client recovery UX differs per code. */
197
+ type OwAuthErrorCode = 'invalid_credentials' | 'key_revoked' | 'world_gone';
198
+ declare class OwApiError extends Error {
199
+ readonly status: number;
200
+ /** Machine error code from the keel envelope, e.g. 'invalid_credentials'. */
201
+ readonly code: string | null;
202
+ /** Error family from the envelope, e.g. 'invalid_request', 'not_found'. */
203
+ readonly type: string | null;
204
+ /** Offending field/param named by the envelope (422/400), else null. */
205
+ readonly param: string | null;
206
+ /** Documentation link from the envelope -- show it to users/logs verbatim. */
207
+ readonly docUrl: string | null;
208
+ /** Raw parsed envelope (or body text when the body wasn't JSON). */
209
+ readonly detail: unknown;
210
+ constructor(status: number, code: string | null, message: string, docUrl: string | null, detail: unknown, type?: string | null, param?: string | null);
211
+ get isAuthError(): boolean;
212
+ /** 422s/400s name the offending param/field -- typos error loudly platform-wide. */
213
+ get isValidationError(): boolean;
214
+ /** Same Idempotency-Key replayed with a different payload. */
215
+ get isIdempotencyConflict(): boolean;
672
216
  }
673
- interface FamilyInput extends Omit<Family, 'traditions' | 'traits' | 'abilities' | 'languages' | 'ancestors' | 'estates' | 'governs' | 'heirlooms' | 'creatures'> {
674
- traditions?: string[];
675
- traits?: string[];
676
- abilities?: string[];
677
- languages?: string[];
678
- ancestors?: string[];
679
- estates?: string[];
680
- governs?: string[];
681
- heirlooms?: string[];
682
- creatures?: string[];
683
- }
684
- interface InstitutionInput extends Omit<Institution, 'parent_institution' | 'zones' | 'objects' | 'creatures' | 'allies' | 'adversaries' | 'constructs'> {
685
- parent_institution?: string;
686
- zones?: string[];
687
- objects?: string[];
688
- creatures?: string[];
689
- allies?: string[];
690
- adversaries?: string[];
691
- constructs?: string[];
692
- }
693
- interface LanguageInput extends Omit<Language, 'classification' | 'spread' | 'dialects'> {
694
- classification?: string;
695
- spread?: string[];
696
- dialects?: string[];
697
- }
698
- interface LawInput extends Omit<Law, 'parent_law' | 'author' | 'penalties' | 'locations' | 'zones' | 'prohibitions' | 'adjudicators' | 'enforcers'> {
699
- parent_law?: string;
700
- author?: string;
701
- penalties?: string[];
702
- locations?: string[];
703
- zones?: string[];
704
- prohibitions?: string[];
705
- adjudicators?: string[];
706
- enforcers?: string[];
707
- }
708
- interface LocationInput extends Omit<Location, 'parent_location' | 'primary_power' | 'governing_title' | 'zone' | 'rival' | 'partner' | 'populations' | 'secondary_powers' | 'founders' | 'cults' | 'delicacies' | 'extraction_methods' | 'extraction_goods' | 'industry_methods' | 'industry_goods' | 'extraction_markets' | 'industry_markets' | 'currencies' | 'buildings' | 'building_methods' | 'fighters' | 'defensive_objects'> {
709
- parent_location?: string;
710
- primary_power?: string;
711
- governing_title?: string;
712
- zone?: string;
713
- rival?: string;
714
- partner?: string;
715
- populations?: string[];
716
- secondary_powers?: string[];
717
- founders?: string[];
718
- cults?: string[];
719
- delicacies?: string[];
720
- extraction_methods?: string[];
721
- extraction_goods?: string[];
722
- industry_methods?: string[];
723
- industry_goods?: string[];
724
- extraction_markets?: string[];
725
- industry_markets?: string[];
726
- currencies?: string[];
727
- buildings?: string[];
728
- building_methods?: string[];
729
- fighters?: string[];
730
- defensive_objects?: string[];
731
- }
732
- interface PhenomenonInput extends Omit<Phenomenon, 'system' | 'catalysts' | 'empowerments' | 'triggers' | 'wielders' | 'environments'> {
733
- system?: string;
734
- catalysts?: string[];
735
- empowerments?: string[];
736
- triggers?: string[];
737
- wielders?: string[];
738
- environments?: string[];
739
- }
740
- interface RelationInput extends Omit<Relation, 'actor' | 'characters' | 'objects' | 'locations' | 'species' | 'creatures' | 'institutions' | 'traits' | 'collectives' | 'zones' | 'abilities' | 'phenomena' | 'languages' | 'families' | 'titles' | 'constructs' | 'events' | 'narratives'> {
741
- actor?: string;
742
- characters?: string[];
743
- objects?: string[];
744
- locations?: string[];
745
- species?: string[];
746
- creatures?: string[];
747
- institutions?: string[];
748
- traits?: string[];
749
- collectives?: string[];
750
- zones?: string[];
751
- abilities?: string[];
752
- phenomena?: string[];
753
- languages?: string[];
754
- families?: string[];
755
- titles?: string[];
756
- constructs?: string[];
757
- events?: string[];
758
- narratives?: string[];
759
- }
760
- interface SpeciesInput extends Omit<Species, 'parent_species' | 'nourishment' | 'reproduction' | 'adaptations' | 'traits' | 'locations' | 'zones' | 'affinities'> {
761
- parent_species?: string;
762
- nourishment?: string[];
763
- reproduction?: string[];
764
- adaptations?: string[];
765
- traits?: string[];
766
- locations?: string[];
767
- zones?: string[];
768
- affinities?: string[];
769
- }
770
- interface ZoneInput extends Omit<Zone, 'phenomena' | 'linked_zones' | 'populations' | 'titles' | 'principles'> {
771
- phenomena?: string[];
772
- linked_zones?: string[];
773
- populations?: string[];
774
- titles?: string[];
775
- principles?: string[];
776
- }
777
- interface TitleInput extends Omit<Title, 'issuer' | 'body' | 'superior_title' | 'holders' | 'symbols' | 'characters' | 'institutions' | 'families' | 'zones' | 'locations' | 'objects' | 'constructs' | 'laws' | 'collectives' | 'creatures' | 'phenomena' | 'species' | 'languages'> {
778
- issuer?: string;
779
- body?: string;
780
- superior_title?: string;
781
- holders?: string[];
782
- symbols?: string[];
783
- characters?: string[];
784
- institutions?: string[];
785
- families?: string[];
786
- zones?: string[];
787
- locations?: string[];
788
- objects?: string[];
789
- constructs?: string[];
790
- laws?: string[];
791
- collectives?: string[];
792
- creatures?: string[];
793
- phenomena?: string[];
794
- species?: string[];
795
- languages?: string[];
796
- }
797
- interface TraitInput extends Omit<Trait, 'anti_trait' | 'empowered_abilities'> {
798
- anti_trait?: string;
799
- empowered_abilities?: string[];
800
- }
801
- interface NarrativeInput extends Omit<Narrative, 'parent_narrative' | 'protagonist' | 'antagonist' | 'narrator' | 'conservator' | 'events' | 'characters' | 'objects' | 'locations' | 'species' | 'creatures' | 'institutions' | 'traits' | 'collectives' | 'zones' | 'abilities' | 'phenomena' | 'languages' | 'families' | 'relations' | 'titles' | 'constructs' | 'laws'> {
802
- parent_narrative?: string;
803
- protagonist?: string;
804
- antagonist?: string;
805
- narrator?: string;
806
- conservator?: string;
807
- events?: string[];
808
- characters?: string[];
809
- objects?: string[];
810
- locations?: string[];
811
- species?: string[];
812
- creatures?: string[];
813
- institutions?: string[];
814
- traits?: string[];
815
- collectives?: string[];
816
- zones?: string[];
817
- abilities?: string[];
818
- phenomena?: string[];
819
- languages?: string[];
820
- families?: string[];
821
- relations?: string[];
822
- titles?: string[];
823
- constructs?: string[];
824
- laws?: string[];
825
- }
826
- interface MapInput extends Omit<Map, 'parent_map' | 'location'> {
827
- parent_map?: string;
828
- location?: string;
829
- }
830
- interface MarkerInput extends Omit<Marker, 'map' | 'zone'> {
831
- map?: string;
832
- zone?: string;
833
- }
834
- interface PinInput extends Omit<Pin, 'map' | 'element_id'> {
835
- map?: string;
836
- element_id?: string;
217
+ /** Network-level failure (fetch rejected) -- no envelope to parse. */
218
+ declare class OwNetworkError extends Error {
219
+ readonly cause2: unknown;
220
+ constructor(message: string, cause: unknown);
837
221
  }
222
+ /** Parse a wire envelope into OwApiError parts (exported for the error type-tests). */
223
+ /** Parse the platform ERROR envelope into an OwApiError. (Renamed from parseEnvelope in 4.0 —
224
+ * distinct from the world-export envelope, which is a different artifact entirely.) */
225
+ declare function parseErrorEnvelope(status: number, body: unknown): OwApiError;
226
+ /** Build an OwApiError from a non-2xx response, tolerating non-JSON bodies. */
227
+ declare function errorFromResponse(res: Response): Promise<OwApiError>;
228
+
838
229
  /**
839
- * All available element types in OnlyWorlds
230
+ * keel v2 engine absorbed from Assembly's ow-v2-client v0.9.0 (Kael),
231
+ * wire-corrected against live staging fixtures 2026-07-18.
232
+ *
233
+ * OnlyWorlds key-kind detection. Prefixes make leaked keys grep-scannable
234
+ * (Stripe/GitHub precedent) -- and tell a client what auth shape to expect.
840
235
  */
841
- declare enum ElementType$1 {
842
- Ability = "ability",
843
- Character = "character",
844
- Collective = "collective",
845
- Construct = "construct",
846
- Creature = "creature",
847
- Event = "event",
848
- Family = "family",
849
- Institution = "institution",
850
- Language = "language",
851
- Law = "law",
852
- Location = "location",
853
- Map = "map",
854
- Marker = "marker",
855
- Narrative = "narrative",
856
- Object = "object",
857
- Phenomenon = "phenomenon",
858
- Pin = "pin",
859
- Relation = "relation",
860
- Species = "species",
861
- Title = "title",
862
- Trait = "trait",
863
- Zone = "zone"
864
- }
236
+ type OwKeyKind =
237
+ /** ow_w_ -- world key, read + write. Writes need the world's PIN if it has one. */
238
+ 'write'
239
+ /** ow_r_ -- world key, read-only, works bare (no PIN). The share-with-players primitive. */
240
+ | 'read'
241
+ /** ow_a_ -- account Bearer token for /account/* routes; can mint world keys. */
242
+ | 'account'
243
+ /** Grandfathered 10-digit key. Needs PIN to read private worlds. */
244
+ | 'legacy' | 'unknown';
245
+ /** Demo range 0000000000-0000000009: read-only aliases, safe as live read gates. */
246
+ declare function isDemoKey(key: string): boolean;
247
+ declare function detectKeyKind(key: string): OwKeyKind;
248
+ /** Can this key kind ever perform world writes? (PIN is a separate, per-world question.) */
249
+ declare function kindCanWrite(kind: OwKeyKind): boolean;
865
250
  /**
866
- * UI labels for element types - provides proper plural forms
867
- * Useful for displaying element type names in user interfaces
251
+ * Should a credential UI ask for a PIN with this key?
252
+ * Prefixed keys read PIN-less; legacy keys may need it; writes on pinned
253
+ * worlds always need it. 'optional' means: show the field, don't require it.
868
254
  */
869
- declare const ELEMENT_LABELS: Record<ElementType$1, string>;
255
+ declare function pinExpectation(kind: OwKeyKind): 'never' | 'optional' | 'required-for-private-reads';
256
+
870
257
  /**
871
- * Get the plural label for an element type
872
- * @param elementType The element type
873
- * @returns The plural label string
258
+ * keel v2 engine absorbed from Assembly's ow-v2-client v0.9.0 (Kael),
259
+ * wire-corrected against live staging fixtures 2026-07-18.
260
+ *
261
+ * OwV2Client -- thin typed fetch client for the keel v2 API.
262
+ *
263
+ * Deliberately thin: no caching, no sync state, no retry policy -- those belong
264
+ * to callers (sync engines, tools, games). What IS encoded here is the wire
265
+ * contract and its safety rails: payload read-only-field stripping, opaque
266
+ * cursors, idempotency headers, doc_url-bearing errors, polite page sizes, and
267
+ * client-side UUID minting so idempotent retries are structurally safe.
874
268
  */
875
- declare function getElementLabel(elementType: ElementType$1): string;
269
+
270
+ declare class OwV2Client {
271
+ readonly baseUrl: string;
272
+ readonly keyKind: OwKeyKind;
273
+ readonly pageSize: number;
274
+ readonly changesPageSize: number;
275
+ private readonly apiKey;
276
+ private readonly apiPin;
277
+ private readonly fetchImpl;
278
+ constructor(config: OwClientConfig);
279
+ /** GET /health -- unauthenticated liveness pulse. */
280
+ health(): Promise<unknown>;
281
+ /**
282
+ * GET /world -- world meta (name, calendar/time fields, public_read).
283
+ * GOTCHA (by server design): world-meta edits do NOT appear in /changes and
284
+ * do not bump change_seq. Poll getWorld().updated_at for meta freshness.
285
+ */
286
+ getWorld(): Promise<OwWorldMeta>;
287
+ /** PATCH /world -- partial world-meta update. */
288
+ patchWorld(partial: Record<string, unknown>): Promise<OwWorldMeta>;
289
+ /** GET /{type}/ -- one cursor page. */
290
+ list(type: ElementType | string, params?: ListParams): Promise<OwPage>;
291
+ /** Cursor-walk every page of a type. Politeness: uses config pageSize. */
292
+ listAll(type: ElementType | string, params?: Omit<ListParams, 'cursor'>): AsyncGenerator<OwElement>;
293
+ /** GET /{type}/{id}/ -- optional one-level stub expansion / sparse fields. */
294
+ get(type: ElementType | string, id: string, opts?: Pick<ListParams, 'expand' | 'fields'>): Promise<OwElement>;
295
+ /**
296
+ * POST /{type}/ -- create. Mints an RFC-4122 UUID for element.id when the
297
+ * caller omits one (design ruling D29d) so a retry carrying the same
298
+ * Idempotency-Key is structurally safe. Callers MAY still supply their own id.
299
+ */
300
+ create(type: ElementType | string, element: OwElement | Record<string, unknown>, opts?: {
301
+ idempotencyKey?: string;
302
+ }): Promise<OwElement>;
303
+ /** PUT /{type}/{id}/ -- upsert-by-client-id. The local-first write primitive. */
304
+ upsert(type: ElementType | string, id: string, element: OwElement | Record<string, unknown>): Promise<OwElement>;
305
+ /**
306
+ * PATCH /{type}/{id}/ -- partial update. DESTRUCTIVE on sent fields: arrays
307
+ * replace wholesale, omitted fields stay untouched. For link arrays prefer
308
+ * editLinks() -- atomic server-side merge, no read-before-write.
309
+ */
310
+ patch(type: ElementType | string, id: string, partial: Record<string, unknown>): Promise<OwElement>;
311
+ /**
312
+ * DELETE /{type}/{id}/ -- idempotent (204 on absent). Server writes a
313
+ * tombstone AND scrubs the id from every other element's links in the same
314
+ * transaction -- no client-side unlink pass needed, ever.
315
+ */
316
+ delete(type: ElementType | string, id: string): Promise<void>;
317
+ /**
318
+ * POST /{type}/{id}/links/{field} with {add, remove} -- atomic link merge.
319
+ * Dedupes, tolerates already-present/already-absent ids. Returns the FULL
320
+ * updated element (fixture P5). Use this for all relationship editing; it
321
+ * retires the read-merge-PATCH dance.
322
+ */
323
+ editLinks(type: ElementType | string, id: string, field: string, edit: OwLinkEdit): Promise<OwElement>;
324
+ /**
325
+ * POST /bulk -- up to ~1000 items. Partial success by default (HTTP 200
326
+ * always; inspect per-slot numeric `status` + top-level `errors` flag);
327
+ * atomic:true for all-or-nothing. Link validation runs against batch U
328
+ * database -- send in any order, cycles included; no client topo-sort.
329
+ * Success slots echo server-authoritative timestamps: set your sync baseline
330
+ * from this response alone. When an idempotencyKey is replayed, the returned
331
+ * response carries wasReplay:true (read from the Idempotent-Replay header).
332
+ */
333
+ bulk(items: OwBulkItem[], opts?: {
334
+ atomic?: boolean;
335
+ idempotencyKey?: string;
336
+ }): Promise<OwBulkResponse>;
337
+ /**
338
+ * GET /changes -- one page of the world's ordered change feed.
339
+ * Cursor is OPAQUE and never expires: persist verbatim, never parse.
340
+ * Zero/absent cursor = full export (byte-aligned with the Folder Format).
341
+ * Rewind rule: if your persisted position is ahead of page.head, the server
342
+ * was restored -- re-baseline from cursor zero; do not assume caught-up.
343
+ * Citizenship: heaviest route on the platform; default page size is polite.
344
+ */
345
+ changes(opts?: {
346
+ since?: string;
347
+ limit?: number;
348
+ }): Promise<OwChangesPage>;
349
+ /**
350
+ * Walk the feed from `since` (or from zero = full export) to the current
351
+ * tail, yielding ops in order. Returns the final cursor via the generator's
352
+ * return value; persist it for the next incremental pull.
353
+ */
354
+ changesAll(since?: string): AsyncGenerator<OwChange, {
355
+ cursor: string;
356
+ head: number;
357
+ }>;
358
+ /**
359
+ * Raw authenticated request against this client's baseUrl. Public since 4.0
360
+ * so auxiliary resources can ride the same transport — it structurally
361
+ * satisfies `TokenTransport` (`new TokenResource(client)`). Prefer the typed
362
+ * methods for element CRUD; this is the escape hatch, and it does NOT apply
363
+ * sanitizePayload — callers own their body shape.
364
+ */
365
+ request<T = unknown>(method: string, path: string, opts?: {
366
+ query?: string;
367
+ body?: unknown;
368
+ idempotencyKey?: string;
369
+ auth?: boolean;
370
+ allowEmpty?: boolean;
371
+ replayAware?: boolean;
372
+ }): Promise<T>;
373
+ }
374
+
876
375
  /**
877
- * Section metadata for OnlyWorlds elements
878
- * Source: sectioned_schema.json
376
+ * Canonical element colour palette — four semantic families.
377
+ *
378
+ * Ruled by Captain 2026-07-22 after Skeld's measurement pass (Orrery
379
+ * `product/schema/element-palette-measurements.md`): 22 mutually-separable
380
+ * hues is structurally impossible; four families is the ceiling that passes
381
+ * all-pairs CVD separation in both modes. **Colour carries the FAMILY; the
382
+ * icon (`ELEMENT_ICONS`) carries the TYPE.** Dark-mode pairs land in the 6–8
383
+ * CVD floor band, so secondary encoding (icon + label) is REQUIRED alongside
384
+ * colour, not optional.
385
+ *
386
+ * The type→family map is GENERATED: `ELEMENT_FAMILIES` is emitted by
387
+ * `codegen/generate_types.py` from the `family:` key in keel's schema YAML
388
+ * (added 2026-07-23, keel c69366b) — a keel PRESENTATION-WRAPPER key
389
+ * (first-party rendering metadata, not part of the council-governed
390
+ * OnlyWorlds standard). It cannot drift from the schema; membership and hex
391
+ * invariants stay test-gated in `test/palette.test.mjs`.
392
+ *
393
+ * The hexes below are design constants, hand-authored beside the generated
394
+ * map. Do not change any value without re-running the CVD validation (every
395
+ * brighter World green collides with Temporal amber for protan viewers — the
396
+ * green is pinned BY the accessibility budget).
397
+ *
398
+ * Provenance: first proven live in atlas (`src/core/element-colors.ts`) and
399
+ * council (`src/cosmos/element-families.ts`) — both become re-exports of this
400
+ * module.
879
401
  */
880
- interface SectionInfo {
881
- name: string;
882
- order: number;
883
- fields: string[];
884
- }
402
+
885
403
  /**
886
- * Element section definitions - provides organized field groupings for each element type
887
- * Enables UI components to display fields in logical sections with proper ordering
404
+ * Family → validated hex per surface mode. `light` assumes near-white
405
+ * surfaces, `dark` assumes near-black (measured against #0a0a0a).
406
+ * World green is identical in both modes and sits at its low-contrast end
407
+ * deliberately — see module header before "fixing" it.
888
408
  */
889
- declare const ELEMENT_SECTIONS: Record<ElementType$1, SectionInfo[]>;
409
+ declare const FAMILY_COLORS: Record<ElementFamily, {
410
+ light: string;
411
+ dark: string;
412
+ }>;
413
+ /** Semantic family for an element type slug. */
414
+ declare function familyOf(type: ElementType): ElementFamily;
890
415
  /**
891
- * Get sections for an element type
892
- * @param elementType The element type
893
- * @returns Array of section information for the element type
416
+ * The convenience most callers want: canonical colour for an element type.
417
+ * Name matches the live atlas/council implementations so their SDK swap is a
418
+ * re-export, not a rename. Defaults to `dark` (both current consumers are
419
+ * dark-surface).
894
420
  */
895
- declare function getElementSections(elementType: ElementType$1): SectionInfo[];
421
+ declare function elementColor(type: ElementType, mode?: 'light' | 'dark'): string;
422
+ /** All four families, in ruling order (the order IS the CVD-safety mechanism of the source palette). */
423
+ declare const FAMILY_ORDER: readonly ElementFamily[];
424
+
896
425
  /**
897
426
  * Current OnlyWorlds version
898
427
  * Synced with https://github.com/OnlyWorlds/OnlyWorlds/blob/main/VERSION
899
428
  */
900
- declare const ONLYWORLDS_VERSION: "00.30.00";
901
- /**
902
- * Material Design icons for element types
903
- * These are the uniform, monochrome icons used in the OnlyWorlds frontend
904
- * Compatible with Google Material Icons font
905
- */
906
- declare const ELEMENT_ICONS: Record<ElementType$1, string>;
907
429
  /**
908
430
  * Field type definitions for OnlyWorlds elements
909
431
  */
910
- type FieldType = 'text' | 'integer' | 'integer_max' | 'number' | 'single_link' | 'multi_link';
432
+ type FieldType = 'text' | 'integer' | 'integer_max' | 'single_link' | 'multi_link';
911
433
  /**
912
434
  * Field metadata structure
913
435
  */
@@ -917,10 +439,7 @@ interface FieldInfo {
917
439
  max?: number;
918
440
  required?: boolean;
919
441
  }
920
- /**
921
- * Comprehensive field schema - provides complete metadata for all fields
922
- * Maps element types to their field definitions including types and cardinality
923
- */
442
+ declare const ELEMENT_LABELS: Record<ElementType, string>;
924
443
  declare const FIELD_SCHEMA: {
925
444
  readonly ability: {
926
445
  readonly name: {
@@ -947,13 +466,13 @@ declare const FIELD_SCHEMA: {
947
466
  readonly type: "text";
948
467
  };
949
468
  readonly duration: {
950
- readonly type: "number";
469
+ readonly type: "integer";
951
470
  };
952
471
  readonly potency: {
953
- readonly type: "number";
472
+ readonly type: "integer";
954
473
  };
955
474
  readonly range: {
956
- readonly type: "number";
475
+ readonly type: "integer";
957
476
  };
958
477
  readonly effects: {
959
478
  readonly type: "multi_link";
@@ -1022,10 +541,10 @@ declare const FIELD_SCHEMA: {
1022
541
  readonly type: "text";
1023
542
  };
1024
543
  readonly height: {
1025
- readonly type: "number";
544
+ readonly type: "integer";
1026
545
  };
1027
546
  readonly weight: {
1028
- readonly type: "number";
547
+ readonly type: "integer";
1029
548
  };
1030
549
  readonly species: {
1031
550
  readonly type: "multi_link";
@@ -1046,7 +565,7 @@ declare const FIELD_SCHEMA: {
1046
565
  readonly type: "text";
1047
566
  };
1048
567
  readonly birth_date: {
1049
- readonly type: "number";
568
+ readonly type: "integer";
1050
569
  };
1051
570
  readonly birthplace: {
1052
571
  readonly type: "single_link";
@@ -1072,22 +591,22 @@ declare const FIELD_SCHEMA: {
1072
591
  readonly target: "institution";
1073
592
  };
1074
593
  readonly charisma: {
1075
- readonly type: "number";
594
+ readonly type: "integer";
1076
595
  };
1077
596
  readonly coercion: {
1078
- readonly type: "number";
597
+ readonly type: "integer";
1079
598
  };
1080
599
  readonly competence: {
1081
- readonly type: "number";
600
+ readonly type: "integer";
1082
601
  };
1083
602
  readonly compassion: {
1084
- readonly type: "number";
603
+ readonly type: "integer";
1085
604
  };
1086
605
  readonly creativity: {
1087
- readonly type: "number";
606
+ readonly type: "integer";
1088
607
  };
1089
608
  readonly courage: {
1090
- readonly type: "number";
609
+ readonly type: "integer";
1091
610
  };
1092
611
  readonly family: {
1093
612
  readonly type: "multi_link";
@@ -1102,28 +621,28 @@ declare const FIELD_SCHEMA: {
1102
621
  readonly target: "character";
1103
622
  };
1104
623
  readonly level: {
1105
- readonly type: "number";
624
+ readonly type: "integer";
1106
625
  };
1107
626
  readonly hit_points: {
1108
- readonly type: "number";
627
+ readonly type: "integer";
1109
628
  };
1110
629
  readonly STR: {
1111
- readonly type: "number";
630
+ readonly type: "integer";
1112
631
  };
1113
632
  readonly DEX: {
1114
- readonly type: "number";
633
+ readonly type: "integer";
1115
634
  };
1116
635
  readonly CON: {
1117
- readonly type: "number";
636
+ readonly type: "integer";
1118
637
  };
1119
638
  readonly INT: {
1120
- readonly type: "number";
639
+ readonly type: "integer";
1121
640
  };
1122
641
  readonly WIS: {
1123
- readonly type: "number";
642
+ readonly type: "integer";
1124
643
  };
1125
644
  readonly CHA: {
1126
- readonly type: "number";
645
+ readonly type: "integer";
1127
646
  };
1128
647
  };
1129
648
  readonly collective: {
@@ -1151,10 +670,10 @@ declare const FIELD_SCHEMA: {
1151
670
  readonly type: "text";
1152
671
  };
1153
672
  readonly count: {
1154
- readonly type: "number";
673
+ readonly type: "integer";
1155
674
  };
1156
675
  readonly formation_date: {
1157
- readonly type: "number";
676
+ readonly type: "integer";
1158
677
  };
1159
678
  readonly operator: {
1160
679
  readonly type: "single_link";
@@ -1232,10 +751,10 @@ declare const FIELD_SCHEMA: {
1232
751
  readonly type: "text";
1233
752
  };
1234
753
  readonly start_date: {
1235
- readonly type: "number";
754
+ readonly type: "integer";
1236
755
  };
1237
756
  readonly end_date: {
1238
- readonly type: "number";
757
+ readonly type: "integer";
1239
758
  };
1240
759
  readonly founder: {
1241
760
  readonly type: "single_link";
@@ -1343,10 +862,10 @@ declare const FIELD_SCHEMA: {
1343
862
  readonly type: "text";
1344
863
  };
1345
864
  readonly weight: {
1346
- readonly type: "number";
865
+ readonly type: "integer";
1347
866
  };
1348
867
  readonly height: {
1349
- readonly type: "number";
868
+ readonly type: "integer";
1350
869
  };
1351
870
  readonly species: {
1352
871
  readonly type: "multi_link";
@@ -1374,7 +893,7 @@ declare const FIELD_SCHEMA: {
1374
893
  readonly type: "text";
1375
894
  };
1376
895
  readonly birth_date: {
1377
- readonly type: "number";
896
+ readonly type: "integer";
1378
897
  };
1379
898
  readonly location: {
1380
899
  readonly type: "single_link";
@@ -1385,16 +904,16 @@ declare const FIELD_SCHEMA: {
1385
904
  readonly target: "zone";
1386
905
  };
1387
906
  readonly challenge_rating: {
1388
- readonly type: "number";
907
+ readonly type: "integer";
1389
908
  };
1390
909
  readonly hit_points: {
1391
- readonly type: "number";
910
+ readonly type: "integer";
1392
911
  };
1393
912
  readonly armor_class: {
1394
- readonly type: "number";
913
+ readonly type: "integer";
1395
914
  };
1396
915
  readonly speed: {
1397
- readonly type: "number";
916
+ readonly type: "integer";
1398
917
  };
1399
918
  readonly actions: {
1400
919
  readonly type: "multi_link";
@@ -1432,10 +951,10 @@ declare const FIELD_SCHEMA: {
1432
951
  readonly type: "text";
1433
952
  };
1434
953
  readonly start_date: {
1435
- readonly type: "number";
954
+ readonly type: "integer";
1436
955
  };
1437
956
  readonly end_date: {
1438
- readonly type: "number";
957
+ readonly type: "integer";
1439
958
  };
1440
959
  readonly triggers: {
1441
960
  readonly type: "multi_link";
@@ -1598,7 +1117,7 @@ declare const FIELD_SCHEMA: {
1598
1117
  readonly type: "text";
1599
1118
  };
1600
1119
  readonly founding_date: {
1601
- readonly type: "number";
1120
+ readonly type: "integer";
1602
1121
  };
1603
1122
  readonly parent_institution: {
1604
1123
  readonly type: "single_link";
@@ -1709,7 +1228,7 @@ declare const FIELD_SCHEMA: {
1709
1228
  readonly type: "text";
1710
1229
  };
1711
1230
  readonly date: {
1712
- readonly type: "number";
1231
+ readonly type: "integer";
1713
1232
  };
1714
1233
  readonly parent_law: {
1715
1234
  readonly type: "single_link";
@@ -1772,7 +1291,7 @@ declare const FIELD_SCHEMA: {
1772
1291
  readonly type: "text";
1773
1292
  };
1774
1293
  readonly founding_date: {
1775
- readonly type: "number";
1294
+ readonly type: "integer";
1776
1295
  };
1777
1296
  readonly parent_location: {
1778
1297
  readonly type: "single_link";
@@ -1870,7 +1389,7 @@ declare const FIELD_SCHEMA: {
1870
1389
  readonly type: "text";
1871
1390
  };
1872
1391
  readonly elevation: {
1873
- readonly type: "number";
1392
+ readonly type: "integer";
1874
1393
  };
1875
1394
  readonly fighters: {
1876
1395
  readonly type: "multi_link";
@@ -1906,16 +1425,16 @@ declare const FIELD_SCHEMA: {
1906
1425
  readonly type: "text";
1907
1426
  };
1908
1427
  readonly hierarchy: {
1909
- readonly type: "number";
1428
+ readonly type: "integer";
1910
1429
  };
1911
1430
  readonly width: {
1912
- readonly type: "number";
1431
+ readonly type: "integer";
1913
1432
  };
1914
1433
  readonly height: {
1915
- readonly type: "number";
1434
+ readonly type: "integer";
1916
1435
  };
1917
1436
  readonly depth: {
1918
- readonly type: "number";
1437
+ readonly type: "integer";
1919
1438
  };
1920
1439
  readonly parent_map: {
1921
1440
  readonly type: "single_link";
@@ -1958,18 +1477,18 @@ declare const FIELD_SCHEMA: {
1958
1477
  readonly required: true;
1959
1478
  };
1960
1479
  readonly x: {
1961
- readonly type: "number";
1480
+ readonly type: "integer";
1962
1481
  readonly required: true;
1963
1482
  };
1964
1483
  readonly y: {
1965
- readonly type: "number";
1484
+ readonly type: "integer";
1966
1485
  readonly required: true;
1967
1486
  };
1968
1487
  readonly z: {
1969
- readonly type: "number";
1488
+ readonly type: "integer";
1970
1489
  };
1971
1490
  readonly order: {
1972
- readonly type: "number";
1491
+ readonly type: "integer";
1973
1492
  readonly required: true;
1974
1493
  };
1975
1494
  };
@@ -2001,13 +1520,13 @@ declare const FIELD_SCHEMA: {
2001
1520
  readonly type: "text";
2002
1521
  };
2003
1522
  readonly start_date: {
2004
- readonly type: "number";
1523
+ readonly type: "integer";
2005
1524
  };
2006
1525
  readonly end_date: {
2007
- readonly type: "number";
1526
+ readonly type: "integer";
2008
1527
  };
2009
1528
  readonly order: {
2010
- readonly type: "number";
1529
+ readonly type: "integer";
2011
1530
  };
2012
1531
  readonly parent_narrative: {
2013
1532
  readonly type: "single_link";
@@ -2127,10 +1646,10 @@ declare const FIELD_SCHEMA: {
2127
1646
  readonly type: "text";
2128
1647
  };
2129
1648
  readonly weight: {
2130
- readonly type: "number";
1649
+ readonly type: "integer";
2131
1650
  };
2132
1651
  readonly amount: {
2133
- readonly type: "number";
1652
+ readonly type: "integer";
2134
1653
  };
2135
1654
  readonly parent_object: {
2136
1655
  readonly type: "single_link";
@@ -2203,7 +1722,7 @@ declare const FIELD_SCHEMA: {
2203
1722
  readonly type: "text";
2204
1723
  };
2205
1724
  readonly duration: {
2206
- readonly type: "number";
1725
+ readonly type: "integer";
2207
1726
  };
2208
1727
  readonly catalysts: {
2209
1728
  readonly type: "multi_link";
@@ -2269,15 +1788,15 @@ declare const FIELD_SCHEMA: {
2269
1788
  readonly required: true;
2270
1789
  };
2271
1790
  readonly x: {
2272
- readonly type: "number";
1791
+ readonly type: "integer";
2273
1792
  readonly required: true;
2274
1793
  };
2275
1794
  readonly y: {
2276
- readonly type: "number";
1795
+ readonly type: "integer";
2277
1796
  readonly required: true;
2278
1797
  };
2279
1798
  readonly z: {
2280
- readonly type: "number";
1799
+ readonly type: "integer";
2281
1800
  };
2282
1801
  };
2283
1802
  readonly relation: {
@@ -2305,13 +1824,13 @@ declare const FIELD_SCHEMA: {
2305
1824
  readonly type: "text";
2306
1825
  };
2307
1826
  readonly start_date: {
2308
- readonly type: "number";
1827
+ readonly type: "integer";
2309
1828
  };
2310
1829
  readonly end_date: {
2311
- readonly type: "number";
1830
+ readonly type: "integer";
2312
1831
  };
2313
1832
  readonly intensity: {
2314
- readonly type: "number";
1833
+ readonly type: "integer";
2315
1834
  };
2316
1835
  readonly actor: {
2317
1836
  readonly type: "single_link";
@@ -2415,10 +1934,10 @@ declare const FIELD_SCHEMA: {
2415
1934
  readonly type: "text";
2416
1935
  };
2417
1936
  readonly life_span: {
2418
- readonly type: "number";
1937
+ readonly type: "integer";
2419
1938
  };
2420
1939
  readonly weight: {
2421
- readonly type: "number";
1940
+ readonly type: "integer";
2422
1941
  };
2423
1942
  readonly nourishment: {
2424
1943
  readonly type: "multi_link";
@@ -2445,7 +1964,7 @@ declare const FIELD_SCHEMA: {
2445
1964
  readonly type: "text";
2446
1965
  };
2447
1966
  readonly aggression: {
2448
- readonly type: "number";
1967
+ readonly type: "integer";
2449
1968
  };
2450
1969
  readonly traits: {
2451
1970
  readonly type: "multi_link";
@@ -2499,10 +2018,10 @@ declare const FIELD_SCHEMA: {
2499
2018
  readonly type: "text";
2500
2019
  };
2501
2020
  readonly grant_date: {
2502
- readonly type: "number";
2021
+ readonly type: "integer";
2503
2022
  };
2504
2023
  readonly revoke_date: {
2505
- readonly type: "number";
2024
+ readonly type: "integer";
2506
2025
  };
2507
2026
  readonly issuer: {
2508
2027
  readonly type: "single_link";
@@ -2620,22 +2139,22 @@ declare const FIELD_SCHEMA: {
2620
2139
  readonly type: "text";
2621
2140
  };
2622
2141
  readonly charisma: {
2623
- readonly type: "number";
2142
+ readonly type: "integer";
2624
2143
  };
2625
2144
  readonly coercion: {
2626
- readonly type: "number";
2145
+ readonly type: "integer";
2627
2146
  };
2628
2147
  readonly competence: {
2629
- readonly type: "number";
2148
+ readonly type: "integer";
2630
2149
  };
2631
2150
  readonly compassion: {
2632
- readonly type: "number";
2151
+ readonly type: "integer";
2633
2152
  };
2634
2153
  readonly creativity: {
2635
- readonly type: "number";
2154
+ readonly type: "integer";
2636
2155
  };
2637
2156
  readonly courage: {
2638
- readonly type: "number";
2157
+ readonly type: "integer";
2639
2158
  };
2640
2159
  readonly significance: {
2641
2160
  readonly type: "text";
@@ -2674,10 +2193,10 @@ declare const FIELD_SCHEMA: {
2674
2193
  readonly type: "text";
2675
2194
  };
2676
2195
  readonly start_date: {
2677
- readonly type: "number";
2196
+ readonly type: "integer";
2678
2197
  };
2679
2198
  readonly end_date: {
2680
- readonly type: "number";
2199
+ readonly type: "integer";
2681
2200
  };
2682
2201
  readonly phenomena: {
2683
2202
  readonly type: "multi_link";
@@ -2705,23 +2224,15 @@ declare const FIELD_SCHEMA: {
2705
2224
  };
2706
2225
  };
2707
2226
  /**
2708
- * Creates a typed element ID from a string
2709
- * @param id The string ID to brand
2710
- * @returns Branded ElementId
2711
- */
2712
- declare function createElementId<T extends ElementType$1>(id: string): ElementId<T>;
2713
- /**
2714
- * Creates typed element IDs array from string array
2715
- * @param ids The string IDs to brand
2716
- * @returns Branded ElementIds array
2717
- */
2718
- declare function createElementIds<T extends ElementType$1>(ids: string[]): ElementIds<T>;
2719
- /**
2720
- * Creates an AnyElementId that can reference any element type
2721
- * @param id The string ID to brand
2722
- * @returns AnyElementId
2227
+ * Get Material Design icon name for an element type
2228
+ * Accepts multiple formats: 'character', 'characters', 'Character', etc.
2229
+ *
2230
+ * @param type - Element type in any format (singular, plural, any case)
2231
+ * @returns Material icon name (e.g., 'person', 'castle', 'thunderstorm')
2723
2232
  */
2724
- declare function createAnyElementId(id: string): AnyElementId;
2233
+ declare function getElementIcon(type: string): string;
2234
+ /** Plural display label for an element type (e.g. phenomenon → "Phenomena"). */
2235
+ declare function getElementLabel(elementType: ElementType): string;
2725
2236
 
2726
2237
  /**
2727
2238
  * OnlyWorlds Token Management API Types
@@ -2843,6 +2354,17 @@ declare enum GameTier {
2843
2354
  * Provides access to the OnlyWorlds token rating system API.
2844
2355
  * Based on the working implementation in base-tool/src/llm/token-service.ts
2845
2356
  */
2357
+ /**
2358
+ * Minimal transport the token resource needs — structurally satisfied by
2359
+ * `OwV2Client` (its `request()` is public since 4.0): `new TokenResource(client)`.
2360
+ * Wire ruling (Skeld 2026-07-23): keel keeps the /tokens/* economy long-term
2361
+ * (Tangle ratings write it, Council voting reads it) — port, don't delete.
2362
+ */
2363
+ interface TokenTransport {
2364
+ request<T>(method: string, path: string, opts?: {
2365
+ body?: unknown;
2366
+ }): Promise<T>;
2367
+ }
2846
2368
 
2847
2369
  /**
2848
2370
  * Token Management Resource
@@ -2854,7 +2376,8 @@ declare enum GameTier {
2854
2376
  *
2855
2377
  * Example usage:
2856
2378
  * ```typescript
2857
- * const client = new OnlyWorldsClient({ apiKey, apiPin });
2379
+ * const client = new OwV2Client({ apiKey: "ow_w_...", apiPin: "1234" });
2380
+ * const tokens = new TokenResource(client);
2858
2381
  *
2859
2382
  * // Check token status
2860
2383
  * const status = await client.tokens.getStatus();
@@ -2870,7 +2393,13 @@ declare enum GameTier {
2870
2393
  */
2871
2394
  declare class TokenResource {
2872
2395
  private client;
2873
- constructor(client: OnlyWorldsClient);
2396
+ constructor(client: TokenTransport);
2397
+ /**
2398
+ * All token routes go through here: a 404 on /tokens/* almost always means
2399
+ * the SERVER predates the v2 token mount (keel >= 2026-07-23, e181689) —
2400
+ * not "user has no tokens". Annotate so the failure reads correctly.
2401
+ */
2402
+ private req;
2874
2403
  /**
2875
2404
  * Get current token status for authenticated user
2876
2405
  *
@@ -2989,529 +2518,4 @@ declare class TokenResource {
2989
2518
  getEncryptionInfo(): Promise<EncryptionInfo>;
2990
2519
  }
2991
2520
 
2992
- interface OnlyWorldsConfig {
2993
- apiKey: string;
2994
- apiPin: string;
2995
- baseUrl?: string;
2996
- }
2997
- interface ListOptions {
2998
- limit?: number;
2999
- offset?: number;
3000
- ordering?: string;
3001
- search?: string;
3002
- [key: string]: any;
3003
- }
3004
- interface ApiResponse<T> {
3005
- count: number;
3006
- next: string | null;
3007
- previous: string | null;
3008
- results: T[];
3009
- }
3010
- /**
3011
- * Base resource class for CRUD operations
3012
- */
3013
- declare class Resource<T, TInput> {
3014
- private client;
3015
- private elementType;
3016
- constructor(client: OnlyWorldsClient, elementType: string);
3017
- list(options?: ListOptions): Promise<ApiResponse<T>>;
3018
- get(id: string): Promise<T>;
3019
- create(data: TInput): Promise<T>;
3020
- update(id: string, data: Partial<TInput>): Promise<T>;
3021
- delete(id: string): Promise<void>;
3022
- /**
3023
- * Round Pin coordinates to integers (API requirement)
3024
- * @private
3025
- */
3026
- private roundPinCoordinates;
3027
- }
3028
- /**
3029
- * Special resource class for World endpoint
3030
- * The /world/ endpoint returns a single World object directly (not paginated)
3031
- * because API keys are world-scoped (one key = one world)
3032
- */
3033
- declare class WorldResource {
3034
- private client;
3035
- constructor(client: OnlyWorldsClient);
3036
- /**
3037
- * Get the world associated with the current API key
3038
- * Returns the world directly (not wrapped in pagination)
3039
- */
3040
- get(): Promise<World>;
3041
- /**
3042
- * Update the current world
3043
- */
3044
- update(data: Partial<WorldInput>): Promise<World>;
3045
- }
3046
- /**
3047
- * Main OnlyWorlds API client
3048
- */
3049
- declare class OnlyWorldsClient {
3050
- private baseUrl;
3051
- private headers;
3052
- worlds: WorldResource;
3053
- tokens: TokenResource;
3054
- abilities: Resource<Ability, AbilityInput>;
3055
- characters: Resource<Character, CharacterInput>;
3056
- collectives: Resource<Collective, CollectiveInput>;
3057
- constructs: Resource<Construct, ConstructInput>;
3058
- creatures: Resource<Creature, CreatureInput>;
3059
- events: Resource<Event, EventInput>;
3060
- families: Resource<Family, FamilyInput>;
3061
- institutions: Resource<Institution, InstitutionInput>;
3062
- languages: Resource<Language, LanguageInput>;
3063
- laws: Resource<Law, LawInput>;
3064
- locations: Resource<Location, LocationInput>;
3065
- maps: Resource<Map, MapInput>;
3066
- markers: Resource<Marker, MarkerInput>;
3067
- narratives: Resource<Narrative, NarrativeInput>;
3068
- objects: Resource<Object$1, ObjectInput>;
3069
- phenomena: Resource<Phenomenon, PhenomenonInput>;
3070
- pins: Resource<Pin, PinInput>;
3071
- relations: Resource<Relation, RelationInput>;
3072
- species: Resource<Species, SpeciesInput>;
3073
- titles: Resource<Title, TitleInput>;
3074
- traits: Resource<Trait, TraitInput>;
3075
- zones: Resource<Zone, ZoneInput>;
3076
- constructor(config: OnlyWorldsConfig);
3077
- /**
3078
- * Make a request to the OnlyWorlds API
3079
- */
3080
- request<T>(method: string, path: string, options?: {
3081
- params?: Record<string, any>;
3082
- body?: any;
3083
- }): Promise<T>;
3084
- /**
3085
- * Helper to convert nested objects to _id/_ids format (legacy method)
3086
- * @deprecated Use prepareRelations instead - it's called automatically in create/update
3087
- */
3088
- static prepareInput<T extends Record<string, any>>(data: T): any;
3089
- /**
3090
- * Convert relation fields to API format (_id/_ids suffix)
3091
- *
3092
- * The OnlyWorlds API expects:
3093
- * - single_link fields: fieldname_id (e.g., birthplace_id)
3094
- * - multi_link fields: fieldname_ids (e.g., species_ids)
3095
- *
3096
- * This method auto-converts based on FIELD_SCHEMA:
3097
- * - { species: ["id1", "id2"] } → { species_ids: ["id1", "id2"] }
3098
- * - { birthplace: "location-id" } → { birthplace_id: "location-id" }
3099
- * - { species: [{id: "id1", name: "X"}] } → { species_ids: ["id1"] }
3100
- *
3101
- * Called automatically by create() and update() methods.
3102
- */
3103
- static prepareRelations<T extends Record<string, any>>(data: T, elementType: string): any;
3104
- }
3105
-
3106
- /**
3107
- * Get Material Design icon name for an element type
3108
- * Accepts multiple formats: 'character', 'characters', 'Character', etc.
3109
- *
3110
- * @param type - Element type in any format (singular, plural, any case)
3111
- * @returns Material icon name (e.g., 'person', 'castle', 'thunderstorm')
3112
- *
3113
- * @example
3114
- * getElementIcon('character') // 'person'
3115
- * getElementIcon('characters') // 'person'
3116
- * getElementIcon('Character') // 'person'
3117
- * getElementIcon('phenomena') // 'thunderstorm'
3118
- */
3119
- declare function getElementIcon(type: string): string;
3120
-
3121
- /** Every element carries these. The extension index signature admits namespaced
3122
- * pass-through fields (atlas_* / shadow_* / x_*) returned verbatim by the server. */
3123
- interface OwElementBase {
3124
- /** Element type slug (server-managed, read-only). */
3125
- type: string;
3126
- /** Unique identifier, uuidv7 format. */
3127
- id: string;
3128
- /** Name of the element. */
3129
- name: string;
3130
- /** Any kind of details about the element. */
3131
- description?: string;
3132
- /** The top level category to which the element belongs. */
3133
- supertype?: string;
3134
- /** The sub level category through which the element is further classified. */
3135
- subtype?: string;
3136
- /** URL to an image representing the element. */
3137
- image_url?: string;
3138
- /** Creation timestamp (server-managed, read-only). */
3139
- created_at?: string;
3140
- /** Last-update timestamp (server-managed, read-only). */
3141
- updated_at?: string;
3142
- /** Per-world change cursor, stamped on every write (server-managed, read-only). */
3143
- change_seq?: number;
3144
- /** Namespaced extension fields (atlas_* / shadow_* / x_*), returned verbatim. */
3145
- [ext: string]: unknown;
3146
- }
3147
- type ElementType = 'ability' | 'character' | 'collective' | 'construct' | 'creature' | 'event' | 'family' | 'institution' | 'language' | 'law' | 'location' | 'map' | 'marker' | 'narrative' | 'object' | 'phenomenon' | 'pin' | 'relation' | 'species' | 'title' | 'trait' | 'zone';
3148
- declare const ELEMENT_TYPES: ElementType[];
3149
- /** The four semantic families (colour carries the family; ELEMENT_ICONS carries the type). */
3150
- type ElementFamily = 'agents' | 'world' | 'abstract' | 'temporal';
3151
- /** Per-type semantic family. Source: keel's PRESENTATION-WRAPPER schema key `family:`
3152
- * (first-party rendering metadata, keel-only — NOT part of the council-governed
3153
- * OnlyWorlds standard; see keel/schema-pipeline.md "The wrapper layer"). */
3154
- declare const ELEMENT_FAMILIES: Record<ElementType, ElementFamily>;
3155
-
3156
- /**
3157
- * keel v2 engine absorbed from Assembly's ow-v2-client v0.9.0 (Kael),
3158
- * wire-corrected against live staging fixtures 2026-07-18.
3159
- *
3160
- * OnlyWorlds v2 (keel) wire types -- the NON-generated, hand-owned wire shapes
3161
- * (envelopes, pages, bulk, changes, config). Per-type element field typing is
3162
- * generated (types.generated.ts). One-shape principle: a field reads the way it
3163
- * writes -- links are UUID arrays (or UUID/null), same name both directions.
3164
- * No `_ids` suffix in v2.
3165
- */
3166
-
3167
- /** An element as read from / written to the v2 API. Loose base + extension keys. */
3168
- type OwElement = OwElementBase;
3169
- /** Spatial types live under spatial/ in the OW Folder Format. */
3170
- declare const SPATIAL_TYPES: readonly ElementType[];
3171
- interface OwWorldMeta {
3172
- id: string;
3173
- name: string;
3174
- updated_at?: string;
3175
- public_read?: boolean;
3176
- [field: string]: unknown;
3177
- }
3178
- /** List envelope: cursor-paginated. */
3179
- interface OwPage<T = OwElement> {
3180
- data: T[];
3181
- has_more: boolean;
3182
- next_cursor: string | null;
3183
- }
3184
- /** /changes feed -- discriminated union on `op`. Apply in order -> convergence. */
3185
- type OwChange = {
3186
- op: 'upsert';
3187
- id: string;
3188
- type: string;
3189
- element: OwElement;
3190
- updated_at: string;
3191
- [k: string]: unknown;
3192
- } | {
3193
- op: 'delete';
3194
- id: string;
3195
- type: string;
3196
- deleted_at: string;
3197
- [k: string]: unknown;
3198
- };
3199
- /**
3200
- * /changes response. Wire shape verified in keel source (core/changes.py) and
3201
- * pinned here: {cursor, changes, has_more, head}.
3202
- */
3203
- interface OwChangesPage {
3204
- /** Opaque compound cursor -- persist verbatim, never parse, never expires. */
3205
- cursor: string;
3206
- changes: OwChange[];
3207
- has_more: boolean;
3208
- /**
3209
- * World's current change_seq. If a persisted cursor is ever AHEAD of head,
3210
- * the server rewound (disaster restore) -- re-baseline from cursor zero
3211
- * instead of assuming caught-up.
3212
- */
3213
- head: number;
3214
- }
3215
- interface OwBulkItem {
3216
- type: ElementType | string;
3217
- element: OwElement | Record<string, unknown>;
3218
- }
3219
- /**
3220
- * One slot of a /bulk response. WIRE-CORRECTED (fixtures P2a/P2c): `status` is
3221
- * the NUMERIC HTTP status of that slot (201/400/...), success slots echo
3222
- * created_at/updated_at, error slots carry an OwErrorBody under `error`.
3223
- */
3224
- interface OwBulkItemResult {
3225
- status: number;
3226
- id?: string;
3227
- created_at?: string;
3228
- updated_at?: string;
3229
- error?: OwErrorBody;
3230
- }
3231
- /** The wire error envelope carried in error slots and thrown errors. */
3232
- interface OwErrorBody {
3233
- type?: string;
3234
- code?: string;
3235
- message?: string;
3236
- param?: string | null;
3237
- doc_url?: string;
3238
- }
3239
- /**
3240
- * /bulk response. WIRE-CORRECTED (fixtures P2a/P2c): the array key is `items`,
3241
- * not `results`. `wasReplay` is populated by the client from the (lowercase on
3242
- * the wire) Idempotent-Replay response header (fixture P2b) -- not a wire field.
3243
- */
3244
- interface OwBulkResponse {
3245
- errors: boolean;
3246
- items: OwBulkItemResult[];
3247
- /** Client-derived: true when the server replayed a prior Idempotency-Key. */
3248
- wasReplay?: boolean;
3249
- [k: string]: unknown;
3250
- }
3251
- interface OwLinkEdit {
3252
- add?: string[];
3253
- remove?: string[];
3254
- }
3255
- interface ListParams {
3256
- limit?: number;
3257
- cursor?: string;
3258
- /** One-level stub expansion, e.g. ['friends', 'location']. */
3259
- expand?: string[];
3260
- /** Sparse include-set of field names. */
3261
- fields?: string[];
3262
- /**
3263
- * Blessed Django-style filters: __icontains, __in, __gte, __lte, __isnull,
3264
- * supertype/subtype equality. Unknown params 422 loudly server-side -- the
3265
- * client passes them through and lets the platform name the typo.
3266
- */
3267
- filter?: Record<string, string | number | boolean>;
3268
- }
3269
- interface OwClientConfig {
3270
- /** ow_w_ / ow_r_ / ow_a_ prefixed key, or grandfathered 10-digit legacy key. */
3271
- apiKey: string;
3272
- /**
3273
- * Optional. Required for writes when the world has a PIN, and for legacy-key
3274
- * reads of private worlds. Prefixed keys read PIN-less. String, not number --
3275
- * '0123' !== 123.
3276
- */
3277
- apiPin?: string;
3278
- /** Default: https://www.onlyworlds.com/api/v2 */
3279
- baseUrl?: string;
3280
- /**
3281
- * Page size for element lists. Default 100 (server default; max 1000).
3282
- * Deliberately visible in config: page size is a citizenship property.
3283
- */
3284
- pageSize?: number;
3285
- /**
3286
- * Page size for /changes pulls. Default 100. Live precedents: Obsidian 100,
3287
- * Atlas 250, MCP 25. /changes is the platform's heaviest route -- be polite.
3288
- */
3289
- changesPageSize?: number;
3290
- /** Injectable for tests / fake-keel harnesses. Defaults to globalThis.fetch. */
3291
- fetch?: typeof globalThis.fetch;
3292
- }
3293
-
3294
- /**
3295
- * keel v2 engine absorbed from Assembly's ow-v2-client v0.9.0 (Kael),
3296
- * wire-corrected against live staging fixtures 2026-07-18.
3297
- *
3298
- * keel error envelope handling. The error contract is part of the contract:
3299
- * envelopes carry a machine `code` and a `doc_url` fragment anchored at
3300
- * onlyworlds.github.io/api/errors -- surface both, always. The live wire
3301
- * envelope also carries `type` and `param` (fixtures P4a/P2c); both are
3302
- * surfaced on the thrown error.
3303
- */
3304
- /** Auth codes are distinguishable by design; client recovery UX differs per code. */
3305
- type OwAuthErrorCode = 'invalid_credentials' | 'key_revoked' | 'world_gone';
3306
- declare class OwApiError extends Error {
3307
- readonly status: number;
3308
- /** Machine error code from the keel envelope, e.g. 'invalid_credentials'. */
3309
- readonly code: string | null;
3310
- /** Error family from the envelope, e.g. 'invalid_request', 'not_found'. */
3311
- readonly type: string | null;
3312
- /** Offending field/param named by the envelope (422/400), else null. */
3313
- readonly param: string | null;
3314
- /** Documentation link from the envelope -- show it to users/logs verbatim. */
3315
- readonly docUrl: string | null;
3316
- /** Raw parsed envelope (or body text when the body wasn't JSON). */
3317
- readonly detail: unknown;
3318
- constructor(status: number, code: string | null, message: string, docUrl: string | null, detail: unknown, type?: string | null, param?: string | null);
3319
- get isAuthError(): boolean;
3320
- /** 422s/400s name the offending param/field -- typos error loudly platform-wide. */
3321
- get isValidationError(): boolean;
3322
- /** Same Idempotency-Key replayed with a different payload. */
3323
- get isIdempotencyConflict(): boolean;
3324
- }
3325
- /** Network-level failure (fetch rejected) -- no envelope to parse. */
3326
- declare class OwNetworkError extends Error {
3327
- readonly cause2: unknown;
3328
- constructor(message: string, cause: unknown);
3329
- }
3330
- /** Parse a wire envelope into OwApiError parts (exported for the error type-tests). */
3331
- declare function parseEnvelope(status: number, body: unknown): OwApiError;
3332
- /** Build an OwApiError from a non-2xx response, tolerating non-JSON bodies. */
3333
- declare function errorFromResponse(res: Response): Promise<OwApiError>;
3334
-
3335
- /**
3336
- * keel v2 engine absorbed from Assembly's ow-v2-client v0.9.0 (Kael),
3337
- * wire-corrected against live staging fixtures 2026-07-18.
3338
- *
3339
- * OnlyWorlds key-kind detection. Prefixes make leaked keys grep-scannable
3340
- * (Stripe/GitHub precedent) -- and tell a client what auth shape to expect.
3341
- */
3342
- type OwKeyKind =
3343
- /** ow_w_ -- world key, read + write. Writes need the world's PIN if it has one. */
3344
- 'write'
3345
- /** ow_r_ -- world key, read-only, works bare (no PIN). The share-with-players primitive. */
3346
- | 'read'
3347
- /** ow_a_ -- account Bearer token for /account/* routes; can mint world keys. */
3348
- | 'account'
3349
- /** Grandfathered 10-digit key. Needs PIN to read private worlds. */
3350
- | 'legacy' | 'unknown';
3351
- /** Demo range 0000000000-0000000009: read-only aliases, safe as live read gates. */
3352
- declare function isDemoKey(key: string): boolean;
3353
- declare function detectKeyKind(key: string): OwKeyKind;
3354
- /** Can this key kind ever perform world writes? (PIN is a separate, per-world question.) */
3355
- declare function kindCanWrite(kind: OwKeyKind): boolean;
3356
- /**
3357
- * Should a credential UI ask for a PIN with this key?
3358
- * Prefixed keys read PIN-less; legacy keys may need it; writes on pinned
3359
- * worlds always need it. 'optional' means: show the field, don't require it.
3360
- */
3361
- declare function pinExpectation(kind: OwKeyKind): 'never' | 'optional' | 'required-for-private-reads';
3362
-
3363
- /**
3364
- * keel v2 engine absorbed from Assembly's ow-v2-client v0.9.0 (Kael),
3365
- * wire-corrected against live staging fixtures 2026-07-18.
3366
- *
3367
- * OwV2Client -- thin typed fetch client for the keel v2 API.
3368
- *
3369
- * Deliberately thin: no caching, no sync state, no retry policy -- those belong
3370
- * to callers (sync engines, tools, games). What IS encoded here is the wire
3371
- * contract and its safety rails: payload read-only-field stripping, opaque
3372
- * cursors, idempotency headers, doc_url-bearing errors, polite page sizes, and
3373
- * client-side UUID minting so idempotent retries are structurally safe.
3374
- */
3375
-
3376
- declare class OwV2Client {
3377
- readonly baseUrl: string;
3378
- readonly keyKind: OwKeyKind;
3379
- readonly pageSize: number;
3380
- readonly changesPageSize: number;
3381
- private readonly apiKey;
3382
- private readonly apiPin;
3383
- private readonly fetchImpl;
3384
- constructor(config: OwClientConfig);
3385
- /** GET /health -- unauthenticated liveness pulse. */
3386
- health(): Promise<unknown>;
3387
- /**
3388
- * GET /world -- world meta (name, calendar/time fields, public_read).
3389
- * GOTCHA (by server design): world-meta edits do NOT appear in /changes and
3390
- * do not bump change_seq. Poll getWorld().updated_at for meta freshness.
3391
- */
3392
- getWorld(): Promise<OwWorldMeta>;
3393
- /** PATCH /world -- partial world-meta update. */
3394
- patchWorld(partial: Record<string, unknown>): Promise<OwWorldMeta>;
3395
- /** GET /{type}/ -- one cursor page. */
3396
- list(type: ElementType | string, params?: ListParams): Promise<OwPage>;
3397
- /** Cursor-walk every page of a type. Politeness: uses config pageSize. */
3398
- listAll(type: ElementType | string, params?: Omit<ListParams, 'cursor'>): AsyncGenerator<OwElement>;
3399
- /** GET /{type}/{id}/ -- optional one-level stub expansion / sparse fields. */
3400
- get(type: ElementType | string, id: string, opts?: Pick<ListParams, 'expand' | 'fields'>): Promise<OwElement>;
3401
- /**
3402
- * POST /{type}/ -- create. Mints an RFC-4122 UUID for element.id when the
3403
- * caller omits one (design ruling D29d) so a retry carrying the same
3404
- * Idempotency-Key is structurally safe. Callers MAY still supply their own id.
3405
- */
3406
- create(type: ElementType | string, element: OwElement | Record<string, unknown>, opts?: {
3407
- idempotencyKey?: string;
3408
- }): Promise<OwElement>;
3409
- /** PUT /{type}/{id}/ -- upsert-by-client-id. The local-first write primitive. */
3410
- upsert(type: ElementType | string, id: string, element: OwElement | Record<string, unknown>): Promise<OwElement>;
3411
- /**
3412
- * PATCH /{type}/{id}/ -- partial update. DESTRUCTIVE on sent fields: arrays
3413
- * replace wholesale, omitted fields stay untouched. For link arrays prefer
3414
- * editLinks() -- atomic server-side merge, no read-before-write.
3415
- */
3416
- patch(type: ElementType | string, id: string, partial: Record<string, unknown>): Promise<OwElement>;
3417
- /**
3418
- * DELETE /{type}/{id}/ -- idempotent (204 on absent). Server writes a
3419
- * tombstone AND scrubs the id from every other element's links in the same
3420
- * transaction -- no client-side unlink pass needed, ever.
3421
- */
3422
- delete(type: ElementType | string, id: string): Promise<void>;
3423
- /**
3424
- * POST /{type}/{id}/links/{field} with {add, remove} -- atomic link merge.
3425
- * Dedupes, tolerates already-present/already-absent ids. Returns the FULL
3426
- * updated element (fixture P5). Use this for all relationship editing; it
3427
- * retires the read-merge-PATCH dance.
3428
- */
3429
- editLinks(type: ElementType | string, id: string, field: string, edit: OwLinkEdit): Promise<OwElement>;
3430
- /**
3431
- * POST /bulk -- up to ~1000 items. Partial success by default (HTTP 200
3432
- * always; inspect per-slot numeric `status` + top-level `errors` flag);
3433
- * atomic:true for all-or-nothing. Link validation runs against batch U
3434
- * database -- send in any order, cycles included; no client topo-sort.
3435
- * Success slots echo server-authoritative timestamps: set your sync baseline
3436
- * from this response alone. When an idempotencyKey is replayed, the returned
3437
- * response carries wasReplay:true (read from the Idempotent-Replay header).
3438
- */
3439
- bulk(items: OwBulkItem[], opts?: {
3440
- atomic?: boolean;
3441
- idempotencyKey?: string;
3442
- }): Promise<OwBulkResponse>;
3443
- /**
3444
- * GET /changes -- one page of the world's ordered change feed.
3445
- * Cursor is OPAQUE and never expires: persist verbatim, never parse.
3446
- * Zero/absent cursor = full export (byte-aligned with the Folder Format).
3447
- * Rewind rule: if your persisted position is ahead of page.head, the server
3448
- * was restored -- re-baseline from cursor zero; do not assume caught-up.
3449
- * Citizenship: heaviest route on the platform; default page size is polite.
3450
- */
3451
- changes(opts?: {
3452
- since?: string;
3453
- limit?: number;
3454
- }): Promise<OwChangesPage>;
3455
- /**
3456
- * Walk the feed from `since` (or from zero = full export) to the current
3457
- * tail, yielding ops in order. Returns the final cursor via the generator's
3458
- * return value; persist it for the next incremental pull.
3459
- */
3460
- changesAll(since?: string): AsyncGenerator<OwChange, {
3461
- cursor: string;
3462
- head: number;
3463
- }>;
3464
- private request;
3465
- }
3466
-
3467
- /**
3468
- * Canonical element colour palette — four semantic families.
3469
- *
3470
- * Ruled by Captain 2026-07-22 after Skeld's measurement pass (Orrery
3471
- * `product/schema/element-palette-measurements.md`): 22 mutually-separable
3472
- * hues is structurally impossible; four families is the ceiling that passes
3473
- * all-pairs CVD separation in both modes. **Colour carries the FAMILY; the
3474
- * icon (`ELEMENT_ICONS`) carries the TYPE.** Dark-mode pairs land in the 6–8
3475
- * CVD floor band, so secondary encoding (icon + label) is REQUIRED alongside
3476
- * colour, not optional.
3477
- *
3478
- * The type→family map is GENERATED: `ELEMENT_FAMILIES` is emitted by
3479
- * `codegen/generate_types.py` from the `family:` key in keel's schema YAML
3480
- * (added 2026-07-23, keel c69366b) — a keel PRESENTATION-WRAPPER key
3481
- * (first-party rendering metadata, not part of the council-governed
3482
- * OnlyWorlds standard). It cannot drift from the schema; membership and hex
3483
- * invariants stay test-gated in `test/palette.test.mjs`.
3484
- *
3485
- * The hexes below are design constants, hand-authored beside the generated
3486
- * map. Do not change any value without re-running the CVD validation (every
3487
- * brighter World green collides with Temporal amber for protan viewers — the
3488
- * green is pinned BY the accessibility budget).
3489
- *
3490
- * Provenance: first proven live in atlas (`src/core/element-colors.ts`) and
3491
- * council (`src/cosmos/element-families.ts`) — both become re-exports of this
3492
- * module.
3493
- */
3494
-
3495
- /**
3496
- * Family → validated hex per surface mode. `light` assumes near-white
3497
- * surfaces, `dark` assumes near-black (measured against #0a0a0a).
3498
- * World green is identical in both modes and sits at its low-contrast end
3499
- * deliberately — see module header before "fixing" it.
3500
- */
3501
- declare const FAMILY_COLORS: Record<ElementFamily, {
3502
- light: string;
3503
- dark: string;
3504
- }>;
3505
- /** Semantic family for an element type slug. */
3506
- declare function familyOf(type: ElementType): ElementFamily;
3507
- /**
3508
- * The convenience most callers want: canonical colour for an element type.
3509
- * Name matches the live atlas/council implementations so their SDK swap is a
3510
- * re-export, not a rename. Defaults to `dark` (both current consumers are
3511
- * dark-surface).
3512
- */
3513
- declare function elementColor(type: ElementType, mode?: 'light' | 'dark'): string;
3514
- /** All four families, in ruling order (the order IS the CVD-safety mechanism of the source palette). */
3515
- declare const FAMILY_ORDER: readonly ElementFamily[];
3516
-
3517
- export { type Ability, type AbilityInput, type AccessKeyResponse, type AnyElementId, type ApiResponse, type BaseElement, type Character, type CharacterInput, type Collective, type CollectiveInput, type Construct, type ConstructInput, type Creature, type CreatureInput, ELEMENT_FAMILIES, ELEMENT_ICONS, ELEMENT_LABELS, ELEMENT_SECTIONS, ELEMENT_TYPES, type ElementFamily, type ElementId, type ElementIds, ElementType$1 as ElementType, type EncryptionInfo, type Event, type EventInput, FAMILY_COLORS, FAMILY_ORDER, FIELD_SCHEMA, type Family, type FamilyInput, type FieldInfo, type FieldType, GameTier, type Institution, type InstitutionInput, type Language, type LanguageInput, type Law, type LawInput, type ListOptions, type ListParams, type Location, type LocationInput, type Map, type MapInput, type Marker, type MarkerInput, type Narrative, type NarrativeInput, ONLYWORLDS_VERSION, type Object$1 as Object, type ObjectInput, OnlyWorldsClient, type OnlyWorldsConfig, OwApiError, type OwAuthErrorCode, type OwBulkItem, type OwBulkItemResult, type OwBulkResponse, type OwChange, type OwChangesPage, type OwClientConfig, type OwElement, type OwElementBase, type OwErrorBody, type OwKeyKind, type OwLinkEdit, OwNetworkError, type OwPage, OwV2Client, type OwWorldMeta, type Phenomenon, type PhenomenonInput, type Pin, type PinInput, type Relation, type RelationInput, type RevokeAllSessionsResponse, type RevokeSessionResponse, SPATIAL_TYPES, type SectionInfo, type Species, type SpeciesInput, type Title, type TitleInput, type TokenConsumeParams, type TokenConsumeResponse, type TokenStatus, type Trait, type TraitInput, type ElementType as V2ElementType, type World, type WorldInput, type Zone, type ZoneInput, createAnyElementId, createElementId, createElementIds, detectKeyKind, elementColor, errorFromResponse, familyOf, getElementIcon, getElementLabel, getElementSections, isDemoKey, kindCanWrite, parseEnvelope, pinExpectation };
2521
+ export { type AccessKeyResponse, ELEMENT_FAMILIES, ELEMENT_ICONS, ELEMENT_LABELS, ELEMENT_SECTIONS, ELEMENT_TYPES, type ElementFamily, type ElementType, type EncryptionInfo, FAMILY_COLORS, FAMILY_ORDER, FIELD_SCHEMA, type FieldInfo, type FieldType, GameTier, type ListParams, ONLYWORLDS_VERSION, OwApiError, type OwAuthErrorCode, type OwBulkItem, type OwBulkItemResult, type OwBulkResponse, type OwChange, type OwChangesPage, type OwClientConfig, type OwElement, type OwElementBase, type OwErrorBody, type OwKeyKind, type OwLinkEdit, OwNetworkError, type OwPage, OwV2Client, type OwWorldMeta, type RevokeAllSessionsResponse, type RevokeSessionResponse, SPATIAL_TYPES, type SectionInfo, type TokenConsumeParams, type TokenConsumeResponse, TokenResource, type TokenStatus, type TokenTransport, detectKeyKind, elementColor, errorFromResponse, familyOf, getElementIcon, getElementLabel, isDemoKey, kindCanWrite, parseErrorEnvelope, pinExpectation };