@onlyworlds/sdk 4.8.0 → 4.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +66 -63
- package/CHANGELOG.md +459 -434
- package/LICENSE +21 -21
- package/README.md +183 -167
- package/SCHEMA.md +631 -631
- package/dist/index.d.ts +36 -5
- package/dist/index.js +36 -7
- package/package.json +64 -64
package/CHANGELOG.md
CHANGED
|
@@ -1,434 +1,459 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to `@onlyworlds/sdk`. Maintained from 3.1.0 onward;
|
|
4
|
-
earlier history lives in git log only.
|
|
5
|
-
|
|
6
|
-
## [Unreleased]
|
|
7
|
-
|
|
8
|
-
## [4.
|
|
9
|
-
|
|
10
|
-
### Added
|
|
11
|
-
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
## [4.
|
|
24
|
-
|
|
25
|
-
### Changed
|
|
26
|
-
- **Schema repinned `v0.31.0-dist.
|
|
27
|
-
|
|
28
|
-
`
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
`
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
## [4.7.
|
|
49
|
-
|
|
50
|
-
### Changed
|
|
51
|
-
- **
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
- **`
|
|
112
|
-
|
|
113
|
-
(
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
- **`
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
- **`
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
field
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
`
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
`
|
|
345
|
-
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
- **
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
###
|
|
424
|
-
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@onlyworlds/sdk`. Maintained from 3.1.0 onward;
|
|
4
|
+
earlier history lives in git log only.
|
|
5
|
+
|
|
6
|
+
## [Unreleased]
|
|
7
|
+
|
|
8
|
+
## [4.9.0] — 2026-10-11
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Only if unchanged (keel #210).** `patch(type, id, partial, { ifMatch })` and
|
|
12
|
+
`editLinks(type, id, field, edit, { ifMatch })` send `If-Match: "<change_seq>"`: the write
|
|
13
|
+
lands only if the element is still at that `change_seq`. When it has moved, nothing is
|
|
14
|
+
written and the call throws **`OwPreconditionFailedError`** (412 `precondition_failed`), an
|
|
15
|
+
`OwApiError` whose `current` is the element as it is now, so the client's re-read is free.
|
|
16
|
+
`OwApiError.isPreconditionFailed` names the case. The server never merges; the client
|
|
17
|
+
compares the copy it edited from with `current`. An `ifMatch` that is not a whole number
|
|
18
|
+
throws `TypeError` before anything is sent. Without `ifMatch`, nothing changes.
|
|
19
|
+
Checked live on keel-staging: a matching token lands, a stale one is refused with
|
|
20
|
+
`current` at the live `change_seq`, the refused write changes nothing, and the links
|
|
21
|
+
route behaves the same.
|
|
22
|
+
|
|
23
|
+
## [4.8.1] — 2026-10-11
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
- **Schema repinned `v0.31.0-dist.19` → `v0.32.0-dist.20`** (canonical 00.31.00 → 00.32.00).
|
|
27
|
+
The standard's World gains `public_read`, the walk's first boolean field (`scalar_bool`).
|
|
28
|
+
`OwWorldMeta` already carried `public_read` from `GET /world`; it stays read-only, since
|
|
29
|
+
`PATCH /world` refuses it (flipping a world public is an owner-level act on
|
|
30
|
+
onlyworlds.com). `ONLYWORLDS_VERSION` is now `'00.32.00'`. No element type, field or
|
|
31
|
+
`FIELD_SCHEMA` entry changed.
|
|
32
|
+
|
|
33
|
+
## [4.8.0] — 2026-10-10
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
- **`removeImage(keyOrUrl, { ticket? })`**: removes one uploaded image. A removal ticket from
|
|
37
|
+
keel (`POST /media/remove-ticket`, keel D91), then the removal at the ticket's `remove_url`
|
|
38
|
+
with the ticket only, never the API key. Takes the object key or the whole `image_url`. The
|
|
39
|
+
image's uploader or the world's owner key may remove it; the bytes go back to the uploader's
|
|
40
|
+
storage. Elements keep their `image_url`: clear it yourself.
|
|
41
|
+
- **`createRemovalTicket(key)`** and the types **`OwRemovalTicket`** (`ticket`, `remove_url`,
|
|
42
|
+
`exp` in unix seconds, `key`, `referenced`: how many elements still show the image) and
|
|
43
|
+
**`OwRemovedImage`** (`removed`, `bytes`, `cache`). Refusals arrive as `OwApiError`: keel's
|
|
44
|
+
`permission_error`, `not_found`, `removal_in_flight` and `upload_pending` (both 409 with
|
|
45
|
+
Retry-After); the edge's `ticket_expired`, `ticket_used`, `ticket_invalid`, `not_removable`,
|
|
46
|
+
`remove_failed`.
|
|
47
|
+
|
|
48
|
+
## [4.7.3] — 2026-10-10
|
|
49
|
+
|
|
50
|
+
### Changed
|
|
51
|
+
- **Schema repinned `v0.31.0-dist.18` → `v0.31.0-dist.19`** (canonical unchanged, 00.31.00).
|
|
52
|
+
Two generated values move: `ELEMENT_ICONS.zone` `architecture` → `pentagon`,
|
|
53
|
+
`ELEMENT_ICONS.marker` `location_on` → `polyline` (Material Symbols names; Marker no longer
|
|
54
|
+
shares the pin glyph). No field, type or `FIELD_SCHEMA` entry changed. The vendored tree grows
|
|
55
|
+
from 31 to 69 files (dist.19 adds `schema.json` and an example world); 69/69 hashed against
|
|
56
|
+
the pinned manifest.
|
|
57
|
+
- **`AGENTS.md` re-read against the new pin** (its gate fired on the repin, as designed); its
|
|
58
|
+
wire facts hold, its "Current as of" line moves.
|
|
59
|
+
|
|
60
|
+
## [4.7.2] — 2026-10-09
|
|
61
|
+
|
|
62
|
+
### Changed
|
|
63
|
+
- **README first run** finds Admiral Fluffington by name (the demo world's default list order moves with every edit, so "the first three" could not be promised); the npm page shows the corrected output.
|
|
64
|
+
- **Schema repinned `v0.30.2-dist.16` → `v0.31.0-dist.18`** (canonical **00.31.00**).
|
|
65
|
+
`ONLYWORLDS_VERSION` is now `'00.31.00'`. The World gains three optional free-text settings,
|
|
66
|
+
`length_unit`, `mass_unit` and `distance_unit`; the nine element fields that promised "world
|
|
67
|
+
LENGTH / MASS / DISTANCE units" now name them in their descriptions (Ability `range`, Character
|
|
68
|
+
and Creature `height` and `weight`, Creature `speed`, Location `elevation`, Object and Species
|
|
69
|
+
`weight`). No element field shape and no `FIELD_SCHEMA` entry changed. The world body is not
|
|
70
|
+
typed per field (`OwWorldMeta` is open), so `getWorld` returns the three keys and `patchWorld`
|
|
71
|
+
sends them with no code change; a test says so.
|
|
72
|
+
|
|
73
|
+
## [4.7.1] — 2026-10-08
|
|
74
|
+
|
|
75
|
+
### Changed
|
|
76
|
+
- **README rewritten**: install, a first run against the public demo world (its output shown,
|
|
77
|
+
run as written), your own world with an agent seat for writes, then the reference. It no
|
|
78
|
+
longer calls a `world` field in a payload an error: the API ignores it.
|
|
79
|
+
- Comments, the RFC and pin-file prose no longer name people or internal places.
|
|
80
|
+
- **Schema repinned `v0.30.1-dist.15` → `v0.30.2-dist.16`** (canonical **00.30.02**).
|
|
81
|
+
`ONLYWORLDS_VERSION` is now `'00.30.02'`. Field descriptions move with the schema: Location's
|
|
82
|
+
`rivalries` and `partnerships`, Marker's `order`, and Pin's `element` pair. No field shape and
|
|
83
|
+
no `FIELD_SCHEMA` entry changed: canonical now requires only `name` on every type, which is
|
|
84
|
+
what `FIELD_SCHEMA` already said, so its hand-made exception for the old Pin and Marker
|
|
85
|
+
lists is gone. If the schema lists more than `name` again, codegen stops and asks for a
|
|
86
|
+
ruling instead of dropping the list. 31/31 file hashes recomputed from the tag.
|
|
87
|
+
|
|
88
|
+
## [4.7.0] — 2026-10-08
|
|
89
|
+
|
|
90
|
+
### Added
|
|
91
|
+
- **`OwApiError.isResyncRequired`**: 409 `resync_required` from `/changes`. Guests can follow the
|
|
92
|
+
feed since keel D79; when a guest's view or a key's role changes, its stored cursor is refused. Drop
|
|
93
|
+
it, walk from zero, and replace the local copy rather than merging.
|
|
94
|
+
|
|
95
|
+
### Documented
|
|
96
|
+
- `uploadImage` accepts webp, png, jpeg and avif. 4.6.0's JSDoc and README also listed gif, which
|
|
97
|
+
the edge refuses (415 `unsupported_type`); checked against the Worker's type table.
|
|
98
|
+
- `changes()`: the old rewind rule compared a stored cursor with `head`, which an opaque cursor
|
|
99
|
+
cannot do; replaced with the reset rule (`isResyncRequired`).
|
|
100
|
+
- The doc comments of `OwClientConfig`, `create` and `uploadImage` are written for users: internal
|
|
101
|
+
ruling numbers and test-harness notes are gone, and each opens with what the option or method does.
|
|
102
|
+
The docs site's TypeScript reference is generated from these comments.
|
|
103
|
+
|
|
104
|
+
## [4.6.0] — 2026-10-06
|
|
105
|
+
|
|
106
|
+
Published from `e198298` (tag `v4.6.0`); the tarball was checked against a build of that commit.
|
|
107
|
+
|
|
108
|
+
Includes 4.5.1's documentation fixes: 4.5.1 was staged and never published.
|
|
109
|
+
|
|
110
|
+
### Added
|
|
111
|
+
- **`uploadImage(image, { key?, ticket? })`**: upload one image (webp, png, jpeg, avif;
|
|
112
|
+
never SVG; 4.6.0's docs also said gif, which the edge refuses with 415) and get its permanent public URL. Two requests: a ticket from keel
|
|
113
|
+
(`POST /media/ticket`), then the bytes straight to the edge at the ticket's `upload_url`
|
|
114
|
+
(keel never sees them). Only the ticket goes to the edge, never the API key or PIN. An image
|
|
115
|
+
larger than the ticket's `max_bytes` throws 413 `too_large` before anything is sent; the edge's
|
|
116
|
+
refusals (`ticket_used`, `ticket_expired`, `bad_key`, `exists`, `unsupported_type`, ...) arrive
|
|
117
|
+
as `OwApiError` with their code. Set the returned `url` as an element's `image_url` yourself.
|
|
118
|
+
Checked live on 2026-10-06: one upload through keel's ticket to the edge (201), and the same
|
|
119
|
+
ticket again refused with 401 `ticket_used`.
|
|
120
|
+
- **`createMediaTicket()`**: the first step alone, for callers that upload themselves (progress
|
|
121
|
+
bars, say). Types `OwMediaTicket` and `OwUploadedImage`.
|
|
122
|
+
|
|
123
|
+
### Documented
|
|
124
|
+
- `ListParams.filter` lists what keel accepts now: exact `name`, and `characters=<id>` on every
|
|
125
|
+
type with a `characters` link (keel D76d).
|
|
126
|
+
|
|
127
|
+
## [4.5.1] — 2026-10-05 (never published; shipped in 4.6.0)
|
|
128
|
+
|
|
129
|
+
Docs only: no code path changes.
|
|
130
|
+
|
|
131
|
+
### Documented
|
|
132
|
+
- **`isOwnerOnly`'s JSDoc in 4.5.0 was wrong about who sees `owner_only`.** It said owners and
|
|
133
|
+
co-builders never see it. A member key, a co-builder's too, gets it on `PATCH /world`; only the
|
|
134
|
+
owner's key is exempt (keel spec section 9; confirmed from keel's `patch_world`,
|
|
135
|
+
2026-10-04).
|
|
136
|
+
- **`world_gone` is reserved.** `OwAuthErrorCode` and `isAuthError` still carry it, but keel never
|
|
137
|
+
emits it: a deleted world's keys are deleted with it, so the key answers 401 `invalid_credentials`
|
|
138
|
+
(2026-10-04; keel spec section 2). Found by the wire gate reading the SDK's own
|
|
139
|
+
built file for the codes it keys on.
|
|
140
|
+
|
|
141
|
+
## [4.5.0] — 2026-10-04
|
|
142
|
+
|
|
143
|
+
What the staging write probes found on the wire (Python package, 2026-10-04): one new getter, and
|
|
144
|
+
three behaviours the server has always had that no client doc said. Additive; nothing is removed.
|
|
145
|
+
|
|
146
|
+
### Added
|
|
147
|
+
- **`OwApiError.isOwnerOnly`**: 403 `owner_only`, a contributor attempting a world-level change
|
|
148
|
+
(`patchWorld`, publishing a show page). Owners and co-builders never see it. keel's OpenAPI
|
|
149
|
+
document does not name the code yet (the schema side has that to close); the wire returns it.
|
|
150
|
+
|
|
151
|
+
### Documented
|
|
152
|
+
- **An atomic `/bulk` rollback still returns 201 slots** for the items that would have
|
|
153
|
+
succeeded, with the ids and timestamps they would have had (keel spec: "counterfactual 201s").
|
|
154
|
+
After `atomic: true` with `errors: true`, nothing was written. On `bulk()`, `OwBulkItemResult`
|
|
155
|
+
and the README.
|
|
156
|
+
- **`name` is required as a key only**: `''` and `null` are accepted and stored as `''` (keel
|
|
157
|
+
ruling 2026-09-28, spec §6; nameless Markers exist). On `create()` and the README.
|
|
158
|
+
|
|
159
|
+
## [4.4.0] — 2026-10-04
|
|
160
|
+
|
|
161
|
+
Membership, as far as the server has shipped it: who created an element, and the refusal a
|
|
162
|
+
contributor meets on someone else's. Additive; nothing is removed or narrows.
|
|
163
|
+
|
|
164
|
+
### Added
|
|
165
|
+
- **`created_by`** on `OwElementBase` (so on every element type): `string | null`, the id of the
|
|
166
|
+
membership that created the element, `null` for the world's owner and for anything made
|
|
167
|
+
before memberships existed (keel D72 phase 2, live 2026-09-28; keel spec §4). Read-only. The
|
|
168
|
+
schema does not carry it (like `created_at` it is server bookkeeping), so the generator adds
|
|
169
|
+
it to the wire base under the declared mapping. A write body that carries it has it dropped
|
|
170
|
+
by the server, so the client does not strip it and a read body still round-trips.
|
|
171
|
+
- **`OwApiError.isNotAuthor`**: 403 `not_author`, a contributor changing, replacing, relinking
|
|
172
|
+
or deleting an element someone else created. `/bulk` answers 200 and reports it in the item
|
|
173
|
+
slot, so check the slot (documented on `OwBulkItemResult`).
|
|
174
|
+
|
|
175
|
+
### Fixed
|
|
176
|
+
- **`FIELD_SCHEMA` no longer marks `marker.map/zone/x/y/order` and `pin.map/element_type/element_id/x/y`
|
|
177
|
+
as `required: true`.** The wire requires `name` and nothing else (rulings.yaml `nullable-by-default`,
|
|
178
|
+
ruling 2026-07-28; keel's OpenAPI write schemas say `required: [name]`), but the schema files still
|
|
179
|
+
list those fields and the generator copied the lists, so a form built from the table demanded
|
|
180
|
+
coordinates the server never did. Found by comparing the SDK with keel's OpenAPI document (the
|
|
181
|
+
new `verify-sdk-wire` gate). **If you read `required` from this table, marker and pin
|
|
182
|
+
fields now read as optional**, which is what the server accepts. The generator notes the lists it
|
|
183
|
+
ignores on every run and says when canonical stops carrying them.
|
|
184
|
+
|
|
185
|
+
### Not yet
|
|
186
|
+
- `me()` and `members()` wait for the server routes (keel's M2b). Nothing in this release
|
|
187
|
+
guesses at their names.
|
|
188
|
+
|
|
189
|
+
## [4.3.0] — 2026-09-28
|
|
190
|
+
|
|
191
|
+
Errors you can act on: the two 409s told apart, and the busy server's `Retry-After`, in Node and
|
|
192
|
+
browsers. One getter narrows (see Fixed); nothing is removed.
|
|
193
|
+
|
|
194
|
+
### Fixed
|
|
195
|
+
- **`OwApiError.isIdempotencyConflict` no longer claims every 409.** keel sends two: 409
|
|
196
|
+
`idempotency_error` (a key reused with a different body) and 409 `id_conflict` (the id is
|
|
197
|
+
taken: a create with an existing id since D39, or a PUT / bulk id held by another world since
|
|
198
|
+
D70). The getter was true for both, so an id conflict read as a key problem, and retrying with
|
|
199
|
+
a fresh key could never help. It now matches `idempotency_error` only, and the new
|
|
200
|
+
**`isIdConflict`** names the other. A caller who relied on the old catch-all for `id_conflict`
|
|
201
|
+
should switch to `isIdConflict`. A 409 with no code (a proxy, a non-JSON body) now reads
|
|
202
|
+
false for both. `/bulk` is unaffected: it answers 200 and reports a per-item 409 in the slot.
|
|
203
|
+
|
|
204
|
+
### Added
|
|
205
|
+
- **`OwApiError.retryAfter`** (seconds, or null) is parsed from `Retry-After`, as a delay or an
|
|
206
|
+
HTTP date, and **`isBusy`** marks keel's 503 `server_busy` (admission control, keel D71: six
|
|
207
|
+
requests at once per worker, up to 10 s of queueing, then 503 with `Retry-After: 5`). The client
|
|
208
|
+
still never retries on its own; it gives callers what they need to back off. A malformed
|
|
209
|
+
`Retry-After` is null, never "retry now". **Works in browsers too** since keel `4949406`
|
|
210
|
+
(2026-09-28): every response exposes `Retry-After`, `Idempotent-Replay` and
|
|
211
|
+
`X-OW-Schema-Version` over CORS (probed from an allowed origin), and keel reports that the
|
|
212
|
+
admission gate's 503 now carries CORS headers, so a busy server reads as busy, not as
|
|
213
|
+
`OwNetworkError` (keel's word; the 503 can't be triggered on demand to probe). Six tests; the
|
|
214
|
+
four core ones watched failing on the previous `errors.ts`.
|
|
215
|
+
|
|
216
|
+
## [4.2.0] — 2026-09-28
|
|
217
|
+
|
|
218
|
+
Ids, honest filter docs, and the schema repin. Nothing is removed; no call needs to change.
|
|
219
|
+
|
|
220
|
+
### Changed
|
|
221
|
+
- **`create()` now mints an RFC 9562 UUIDv7** when the element has no id (was v4). The first
|
|
222
|
+
48 bits are the creation millisecond, so ids this client mints a millisecond or more apart
|
|
223
|
+
sort by creation (while the clock does not step backwards), which gives databases better
|
|
224
|
+
index locality. **This holds within one client only**: worlds also hold v4 ids and legacy
|
|
225
|
+
v1-server ids (`06x…`, which also carry version nibble 7 but put seconds first), so never
|
|
226
|
+
order elements by id. For creation order use `created_at`; `change_seq` is last-write
|
|
227
|
+
order. This is a **default, not a
|
|
228
|
+
requirement**: a v4 or v7 id a caller supplies is still accepted as-is, and
|
|
229
|
+
every id already stored stays valid. Keel mints v7 server-side too (ruling,
|
|
230
|
+
2026-09-28). Pinned by six tests: version and variant, the big-endian timestamp above
|
|
231
|
+
bit 32, fractional and pre-1970 clocks floored consistently, creation order across 50
|
|
232
|
+
consecutive milliseconds, 1,000 distinct ids inside one millisecond, and the no-`crypto`
|
|
233
|
+
fallback (asserting `Math.random` is actually used). Five injected defects (v4 nibble,
|
|
234
|
+
32-bit truncation, a dropped random fill, a dropped variant mask, an unfloored clock)
|
|
235
|
+
each fail the suite on every run, on Node 20 and 22. An independent reviewer's decoder agreed on 20,000 random timestamps and the 48-bit
|
|
236
|
+
edges, and keel's `uuid7()` agrees on timestamp, version and variant for a pinned clock.
|
|
237
|
+
- **`elementColor()` on an unknown type now throws a `TypeError` that names the type.** It
|
|
238
|
+
used to crash with `Cannot read properties of undefined (reading 'dark')`. Found while
|
|
239
|
+
building a colour gate: atlas's own copy falls back to the `world` family for an
|
|
240
|
+
unknown type, so swapping it for this export is not a pure re-export for that input, and the
|
|
241
|
+
docstring now says so. Whether the package should fall back is left to its consumers.
|
|
242
|
+
- The generated field-schema comment no longer calls `maximum:` an open question or counts
|
|
243
|
+
its occurrences (the count was 41; since 00.30.01 it is 15). The question was ruled on
|
|
244
|
+
2026-07-29.
|
|
245
|
+
- **`ListParams.filter` JSDoc names what the server actually accepts**: `name__icontains`,
|
|
246
|
+
`supertype`, `subtype`. It used to list `__in`, `__gte`, `__lte` and `__isnull`, copied
|
|
247
|
+
from keel's spec, which described them but never built them. Probed live 2026-09-28: the
|
|
248
|
+
three accepted keys answer 200; every other one, and `?ordering=`, answers 422.
|
|
249
|
+
- **Schema repinned `v0.30.1-dist.13` → `v0.30.1-dist.15`** (canonical unchanged, 00.30.01).
|
|
250
|
+
Two generated values move: `ELEMENT_ICONS.institution` `business` → `account_balance`,
|
|
251
|
+
`ELEMENT_ICONS.marker` `place` → `location_on` (both Material Symbols names). dist.15
|
|
252
|
+
also adds `minimum: 0` to `ability.potency`; the walk does not surface bounds, so nothing
|
|
253
|
+
generated changes for it. 31/31 file hashes recomputed from a fresh download.
|
|
254
|
+
- **`AGENTS.md` re-read against the new pin** (its gate fired on the repin, as designed).
|
|
255
|
+
It still called the v1 client "frozen legacy" in this package; v1 was removed at 4.0.0.
|
|
256
|
+
It now also names the wire behaviours keel deployed on 2026-09-28 (keel D70): the 64 KB
|
|
257
|
+
extension cap, the three built filters and the `?ordering=` 422, 409 `id_conflict` for a
|
|
258
|
+
PUT or bulk id that belongs to another world, and the 422 for unpaired surrogates. None of
|
|
259
|
+
them needs client code.
|
|
260
|
+
|
|
261
|
+
### Also in this release (staged earlier)
|
|
262
|
+
- **`SCHEMA.md` now opens with its own provenance** (dist tag, canonical version, publish
|
|
263
|
+
date — rendered from `schema-pin.json`, never the wall clock). It ships in the tarball
|
|
264
|
+
and is read cold by agents outside this repo, where the pin file is not present; a
|
|
265
|
+
generated reference that cannot name its source was the one remaining self-dating gap.
|
|
266
|
+
- **`AGENTS.md` carries a "Current as of" line, asserted by `codegen:check`** — the tag it
|
|
267
|
+
names must match the pin or CI fails. A hand-maintained agent doc with an ungated date
|
|
268
|
+
is how this repo's previous agent doc went a major version stale. Gate watched firing
|
|
269
|
+
(tampered tag → exit 1, restored → 0).
|
|
270
|
+
|
|
271
|
+
## [4.1.0] — 2026-07-29
|
|
272
|
+
|
|
273
|
+
Public-surface hygiene. Nothing breaks; one member is now marked for removal, and one
|
|
274
|
+
piece of long-standing speculation is retired by measurement.
|
|
275
|
+
|
|
276
|
+
⚑ **4.0.2 was tagged in git and superseded before it reached npm.** Everything in it ships
|
|
277
|
+
here — the tag stays as a record rather than being moved or deleted.
|
|
278
|
+
|
|
279
|
+
### Deprecated
|
|
280
|
+
- **`FieldType.integer_max` and `FieldInfo.max`** — removal scheduled for **5.0.0**. No
|
|
281
|
+
`FIELD_SCHEMA` entry has ever carried either, in this repository's entire history. They
|
|
282
|
+
existed to surface the schema's `maximum:` constraint, and that constraint is **advisory**:
|
|
283
|
+
keel declares no `MaxValueValidator`, and a `charisma: 9999` write against a `maximum: 100`
|
|
284
|
+
field returns 201 and stores it verbatim. The canonical schema walk therefore stays silent
|
|
285
|
+
on bounds permanently. There is no source to wire them to and no promise they could keep —
|
|
286
|
+
and a public type member meaning "hint the wire ignores" is one consumers read as
|
|
287
|
+
validation. Deprecating now rather than at the major so the signal arrives early; the
|
|
288
|
+
`@deprecated` tags surface in editors via the shipped `.d.ts`.
|
|
289
|
+
|
|
290
|
+
### Changed
|
|
291
|
+
- **`TokenResource` is confirmed staying.** RFC-001 §5 asked the platform owner whether the
|
|
292
|
+
token routes were carried long-term or deprecated wire-side, and the question was never
|
|
293
|
+
answered in writing — so this package's own barrel carried "wire fate under review; may be
|
|
294
|
+
removed in a later 4.x" for months, on nobody's authority. Probed against production:
|
|
295
|
+
`GET /api/v2/tokens/status/` and `/tokens/encryption-info/` both return **200**, with a 404
|
|
296
|
+
control on a nonexistent route proving the check meant something. The wire carries it. The
|
|
297
|
+
speculation is retired and the comment now records the evidence instead.
|
|
298
|
+
|
|
299
|
+
## [4.0.2] — 2026-07-29
|
|
300
|
+
|
|
301
|
+
Re-pinned to `v0.30.1-dist.13` (canonical **00.30.01**). No field shape changed and no
|
|
302
|
+
`FIELD_SCHEMA` entry changed — the schema walk is byte-identical between the two pins, so
|
|
303
|
+
nothing about decoding moved. Three things changed and nothing else.
|
|
304
|
+
|
|
305
|
+
### Fixed
|
|
306
|
+
- **`construct.relations` and `event.languages` shipped with no description at all** — in
|
|
307
|
+
`types.generated.ts` and in `SCHEMA.md`. Their descriptions were nested one level too deep
|
|
308
|
+
inside `items:` in the canonical YAML, which made them invisible to every consumer that reads
|
|
309
|
+
field descriptions, this package included. `SCHEMA.md` is the package's AI-legibility artifact,
|
|
310
|
+
so the gap landed where it did the most harm.
|
|
311
|
+
- **Five description typos** corrected in published JSDoc and `SCHEMA.md`: `beapplied`,
|
|
312
|
+
`phyiscal`, `relating the`, `object grant`, `eventuated`. The rendered docs site had already
|
|
313
|
+
fixed all five by hand — the downstream copy was the correct one, and nobody noticed because
|
|
314
|
+
the fix went where it was visible rather than where it was true.
|
|
315
|
+
|
|
316
|
+
### Changed
|
|
317
|
+
- `ONLYWORLDS_VERSION` `'00.30.00'` → `'00.30.01'`. It is a public `as const`, so its **literal
|
|
318
|
+
type** changes. Depending on that literal is pathological, but it is a type-level change and
|
|
319
|
+
should not be discovered rather than announced.
|
|
320
|
+
- The pin now carries canonical's numeric-bounds correction: the `maximum: 0` sentinel is gone
|
|
321
|
+
from 26 fields, 8 fields gained `minimum: 0`, and `rulings.yaml` carries the numeric-bounds
|
|
322
|
+
row. Nothing in this package consumes bounds — `maximum:` is **advisory** (keel does not
|
|
323
|
+
enforce it; a `charisma: 9999` write returns 201 and stores verbatim) and the walk stays
|
|
324
|
+
silent on bounds permanently. `integer_max` / `max` therefore remain declared no-ops here.
|
|
325
|
+
|
|
326
|
+
## [4.0.1] — 2026-07-29
|
|
327
|
+
|
|
328
|
+
**Metadata correction release.** No wire-path change: the client's reads and writes never
|
|
329
|
+
consulted `FIELD_SCHEMA`, and the generated interfaces carried the correct targets throughout.
|
|
330
|
+
The exposure is anything that builds UI or validation by **iterating `FIELD_SCHEMA`**.
|
|
331
|
+
|
|
332
|
+
⚑ **One way this can surface as a compile error**: `relation.relations` is removed, so
|
|
333
|
+
`FIELD_SCHEMA.relation.relations` is now a TypeScript error rather than a value. That is the
|
|
334
|
+
intended outcome — the field does not exist in the standard and the API rejects it — but it can
|
|
335
|
+
break a build rather than only a behaviour.
|
|
336
|
+
|
|
337
|
+
### Fixed
|
|
338
|
+
- **`FIELD_SCHEMA.collective.equipment` targeted `construct`; the standard says `object`.**
|
|
339
|
+
This is the founding case of the schema ruling table
|
|
340
|
+
(`collective-equipment-target`, ruled 2026-07-23): the v1 implementation used
|
|
341
|
+
Construct, v1 is decommissioned, and keel serves per YAML. The generated code path
|
|
342
|
+
in this repo was corrected the same week. The hand-maintained `FIELD_SCHEMA` copy of
|
|
343
|
+
the same fact, in the same package, kept shipping the decommissioned value on
|
|
344
|
+
`latest` — the fix went where someone happened to be looking.
|
|
345
|
+
- **`FIELD_SCHEMA.relation.relations` removed** — a `multi_link` to `relation` that does
|
|
346
|
+
not exist in `relation.yaml`. A phantom field, publicly exported, that consumers
|
|
347
|
+
building forms from this table would have sent to an API that 422s unknown keys.
|
|
348
|
+
|
|
349
|
+
### Changed
|
|
350
|
+
- **`FIELD_SCHEMA` is now GENERATED** from the pinned schema distribution and gated by
|
|
351
|
+
`codegen:check`, joining `ELEMENT_ICONS` / `ELEMENT_SECTIONS` / `ELEMENT_FAMILIES`. It
|
|
352
|
+
was ~650 hand-maintained lines whose test compared nothing to the schema. Regenerating
|
|
353
|
+
it changed exactly 2 of 467 entries — the two above. Runtime shape and the deeply
|
|
354
|
+
readonly public types (`as const`) are unchanged.
|
|
355
|
+
Two declared deviations from a naive schema read are now stated in the generated file:
|
|
356
|
+
`pin.element` (a `generic-link`) splits into `element_type` + `element_id`, as the wire
|
|
357
|
+
serves it; and `integer_max` / `max` remain in the `FieldType` union unused, because
|
|
358
|
+
the walk does not surface the schema's `maximum:` constraint (41 across 17 types).
|
|
359
|
+
- `codegen/generate_types.py` imports the vendored schema walk instead of carrying its
|
|
360
|
+
own copy of it. Output byte-identical.
|
|
361
|
+
|
|
362
|
+
## [4.0.0] — 2026-07-23
|
|
363
|
+
|
|
364
|
+
**v2-native only.** See `docs/migrating-3-to-4.md`. 3.x stays published forever for
|
|
365
|
+
pinned consumers.
|
|
366
|
+
|
|
367
|
+
### Removed (BREAKING)
|
|
368
|
+
- The v1 client (`OnlyWorldsClient`), the v1 `ElementType` enum, `icon-utils`.
|
|
369
|
+
`ElementType` at the root is now THE v2 slug union (was `V2ElementType` alias in 3.x).
|
|
370
|
+
- CJS build — the package is ESM-only with a sealed `exports` map (`"type": "module"`,
|
|
371
|
+
`sideEffects: false`).
|
|
372
|
+
|
|
373
|
+
### Changed
|
|
374
|
+
- Metadata tables (`ELEMENT_ICONS`, `ELEMENT_LABELS`, `ELEMENT_SECTIONS`, `FIELD_SCHEMA`,
|
|
375
|
+
`getElementIcon`, `getElementLabel`) ported onto the v2 slug union — same export names,
|
|
376
|
+
same shapes, contents byte-identical EXCEPT: `FIELD_SCHEMA` `type: 'number'` →
|
|
377
|
+
`'integer'` (70 entries; 'number' dropped from `FieldType`). Migration: consumers
|
|
378
|
+
switching on `'number'` switch on `'integer'`.
|
|
379
|
+
- `TokenResource` now takes a structural `TokenTransport` (`{ request<T>(method, path,
|
|
380
|
+
body?) }`) instead of the removed v1 client. Token surface retained pending the
|
|
381
|
+
wire-fate ruling (RFC-001 §5) — may be removed in a later 4.x.
|
|
382
|
+
|
|
383
|
+
### Added (post-alpha.0, same night)
|
|
384
|
+
- **`ELEMENT_ICONS` GENERATED** from keel's `icon:` wrapper key (keel `56c124a`).
|
|
385
|
+
- **`ELEMENT_SECTIONS` DERIVED** from the canonical schema's own document structure
|
|
386
|
+
(ruling: sections are the standard tier's property groups; document order is
|
|
387
|
+
display order). Divergence check vs the old hand table found and fixed three fossils:
|
|
388
|
+
creature "Behaviour"→"Behavior", pin's triple-listed generic link → `element`,
|
|
389
|
+
relation "Involves" listing a nonexistent `relations` field. Canonical is truth.
|
|
390
|
+
- **`SCHEMA.md`** — full generated schema reference (every field with its canonical
|
|
391
|
+
description, link directions, families, icons, sections), ships in the tarball;
|
|
392
|
+
covered by the codegen drift guard. AGENTS.md points agents at it first.
|
|
393
|
+
- **`OwV2Client.request()` is public** (typed escape hatch; does not sanitize) and
|
|
394
|
+
structurally satisfies `TokenTransport` — `new TokenResource(client)` just works.
|
|
395
|
+
Token ruling: keel keeps `/tokens/*` long-term; ported, not deleted.
|
|
396
|
+
- README rewritten v2-native (v1 sections, branded types, and the encrypted-key
|
|
397
|
+
walkthrough removed; bulk partial-failure and idempotency-key hygiene promoted).
|
|
398
|
+
|
|
399
|
+
### alpha.1 — consumer-pin fixes (atlas review, same night)
|
|
400
|
+
- **`parseEnvelope` → `parseErrorEnvelope`** (it parses the platform *error* envelope;
|
|
401
|
+
renamed before the 4.0 name freeze to avoid collision with the world-export envelope).
|
|
402
|
+
- The never-whitelist LAW now lives as a comment on `READ_ONLY_FIELDS` itself.
|
|
403
|
+
- Stale v1 example in the shipped d.ts fixed (TokenResource JSDoc).
|
|
404
|
+
|
|
405
|
+
### Release gates — ALL GREEN (2026-07-23 night)
|
|
406
|
+
- **Gate 3 (wire-log v1-traffic query)**: GREEN — no unknown v1-SDK consumer on
|
|
407
|
+
the wire; observed v1 traffic is pinned deployed builds (council proxy, legacy plugin
|
|
408
|
+
walks) that an npm major cannot touch. The v1 API dialect stays served regardless.
|
|
409
|
+
- **`/api/v2/tokens/` live on prod + staging** (keel `e181689`; three-base byte
|
|
410
|
+
agreement test-pinned). `TokenResource` annotates a 404 on token routes as
|
|
411
|
+
"older server", not "no tokens". Requirement noted in the migration guide.
|
|
412
|
+
- **`ONLYWORLDS_VERSION` now GENERATED** from canonical's `VERSION` file (carried
|
|
413
|
+
into keel `schema/` by the refresh script, keel `492168c`) — the last hand-synced
|
|
414
|
+
constant is dead. Consumer soak: the atlas app pinned the alpha against its full
|
|
415
|
+
static surface — strict-clean compile, correct runtime, package shape approved.
|
|
416
|
+
- **No `npm deprecate` on 3.x** (landscape research; 3.x stays plainly supported).
|
|
417
|
+
- 4.x wishlist: account client (list/mint/create — atlas first consumer), world-export
|
|
418
|
+
envelope reader (§8c), per-status error classes, richer codegen JSDoc, retry/backoff
|
|
419
|
+
parity audit, FIELD_SCHEMA generation with `required:` from YAML.
|
|
420
|
+
|
|
421
|
+
## [3.1.0] — 2026-07-23
|
|
422
|
+
|
|
423
|
+
### Added
|
|
424
|
+
- **Canonical element colour palette** (`src/v2/palette.ts`, exported from root):
|
|
425
|
+
`ELEMENT_FAMILIES` (type → family), `FAMILY_COLORS` (family → `{light, dark}` hex),
|
|
426
|
+
`familyOf(type)`, `elementColor(type, mode)`, `FAMILY_ORDER`, type `ElementFamily`.
|
|
427
|
+
Four semantic families (agents / world / abstract / temporal) ruled 2026-07-22 after
|
|
428
|
+
CVD-validated measurement.
|
|
429
|
+
Colour carries the FAMILY; `ELEMENT_ICONS` carries the TYPE. Keyed on the v2 slug
|
|
430
|
+
union. First proven live in atlas and council, whose local copies become re-exports.
|
|
431
|
+
**`ELEMENT_FAMILIES` is GENERATED** from the `family:` key in keel's schema YAML
|
|
432
|
+
(keel `c69366b`, a keel presentation-wrapper key — not part of the council-governed
|
|
433
|
+
OnlyWorlds standard); hexes are hand-authored design constants beside it. Membership
|
|
434
|
+
and hex invariants test-gated (`test/palette.test.mjs`); light hexes render-proven on
|
|
435
|
+
the ruled OnlyWorlds light mode (ow-house-light) 2026-07-23.
|
|
436
|
+
- **Codegen drift guard**: `python codegen/generate_types.py --check` fails if
|
|
437
|
+
`types.generated.ts` doesn't match the schema YAMLs (release gate; mirrors keel's
|
|
438
|
+
schema CI job). Codegen also hard-fails on missing/invalid `family:` keys — the
|
|
439
|
+
canary for a canonical-refresh that overwrote keel's wrapper layer.
|
|
440
|
+
- **CI**: GitHub Action building + running the full suite against the compiled bundle.
|
|
441
|
+
- **AGENTS.md** shipped in the tarball — usage guide for AI agents reading the package
|
|
442
|
+
locally, including the SDK-vs-MCP division of labor and the wire gotchas.
|
|
443
|
+
- README: worked create→link→read-back round-trip, schema-verified field by field
|
|
444
|
+
(also fixes the old example patching `'character'` with a location's id); canonical
|
|
445
|
+
colour section; SDK-vs-MCP guidance.
|
|
446
|
+
- This CHANGELOG.
|
|
447
|
+
|
|
448
|
+
### Fixed
|
|
449
|
+
- `FieldType` union now includes `'number'` — the legacy alias that 70 `FIELD_SCHEMA`
|
|
450
|
+
entries actually carry (consumers switch on it; data normalization deferred to 4.0).
|
|
451
|
+
- `generate_types.py` exits with a clear message when the sibling keel checkout is
|
|
452
|
+
absent instead of a bare traceback.
|
|
453
|
+
|
|
454
|
+
## [3.0.0] — 2026-07-18
|
|
455
|
+
|
|
456
|
+
- v2-native client (`OwV2Client`) absorbed from an earlier v2 client (ow-v2-client v0.9.0),
|
|
457
|
+
wire-corrected against live staging fixtures (S22). Generated element types from the
|
|
458
|
+
canonical keel schema YAML (`src/v2/types.generated.ts`), validated against all 1,086
|
|
459
|
+
live W11 elements. v1 surface unchanged and frozen.
|