@onlyworlds/sdk 4.7.0 → 4.7.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/AGENTS.md +1 -1
- package/CHANGELOG.md +31 -16
- package/README.md +74 -76
- package/SCHEMA.md +5 -6
- package/dist/index.d.ts +8 -9
- package/dist/index.js +2 -2
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# For AI agents using @onlyworlds/sdk
|
|
2
2
|
|
|
3
|
-
**Current as of**: SDK **4.x** · schema-dist **v0.30.
|
|
3
|
+
**Current as of**: SDK **4.x** · schema-dist **v0.30.2-dist.16** (canonical 00.30.02).
|
|
4
4
|
This line is asserted by `codegen:check` in CI — if the pin moves and this file is not
|
|
5
5
|
re-read against it, the check fails rather than letting this document rot quietly.
|
|
6
6
|
|
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
All notable changes to `@onlyworlds/sdk`. Maintained from 3.1.0 onward
|
|
3
|
+
All notable changes to `@onlyworlds/sdk`. Maintained from 3.1.0 onward;
|
|
4
4
|
earlier history lives in git log only.
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [4.7.1] — 2026-10-08
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- **README rewritten**: install, a first run against the public demo world (its output shown,
|
|
12
|
+
run as written), your own world with an agent seat for writes, then the reference. It no
|
|
13
|
+
longer calls a `world` field in a payload an error: the API ignores it.
|
|
14
|
+
- Comments, the RFC and pin-file prose no longer name people or internal places.
|
|
15
|
+
- **Schema repinned `v0.30.1-dist.15` → `v0.30.2-dist.16`** (canonical **00.30.02**).
|
|
16
|
+
`ONLYWORLDS_VERSION` is now `'00.30.02'`. Field descriptions move with the schema: Location's
|
|
17
|
+
`rivalries` and `partnerships`, Marker's `order`, and Pin's `element` pair. No field shape and
|
|
18
|
+
no `FIELD_SCHEMA` entry changed: canonical now requires only `name` on every type, which is
|
|
19
|
+
what `FIELD_SCHEMA` already said, so its hand-made exception for the old Pin and Marker
|
|
20
|
+
lists is gone. If the schema lists more than `name` again, codegen stops and asks for a
|
|
21
|
+
ruling instead of dropping the list. 31/31 file hashes recomputed from the tag.
|
|
22
|
+
|
|
8
23
|
## [4.7.0] — 2026-10-08
|
|
9
24
|
|
|
10
25
|
### Added
|
|
@@ -36,7 +51,7 @@ Includes 4.5.1's documentation fixes: 4.5.1 was staged and never published.
|
|
|
36
51
|
refusals (`ticket_used`, `ticket_expired`, `bad_key`, `exists`, `unsupported_type`, ...) arrive
|
|
37
52
|
as `OwApiError` with their code. Set the returned `url` as an element's `image_url` yourself.
|
|
38
53
|
Checked live on 2026-10-06: one upload through keel's ticket to the edge (201), and the same
|
|
39
|
-
ticket again refused with 401 `ticket_used
|
|
54
|
+
ticket again refused with 401 `ticket_used`.
|
|
40
55
|
- **`createMediaTicket()`**: the first step alone, for callers that upload themselves (progress
|
|
41
56
|
bars, say). Types `OwMediaTicket` and `OwUploadedImage`.
|
|
42
57
|
|
|
@@ -51,11 +66,11 @@ Docs only: no code path changes.
|
|
|
51
66
|
### Documented
|
|
52
67
|
- **`isOwnerOnly`'s JSDoc in 4.5.0 was wrong about who sees `owner_only`.** It said owners and
|
|
53
68
|
co-builders never see it. A member key, a co-builder's too, gets it on `PATCH /world`; only the
|
|
54
|
-
owner's key is exempt (keel spec section 9; confirmed from keel's `patch_world
|
|
69
|
+
owner's key is exempt (keel spec section 9; confirmed from keel's `patch_world`,
|
|
55
70
|
2026-10-04).
|
|
56
71
|
- **`world_gone` is reserved.** `OwAuthErrorCode` and `isAuthError` still carry it, but keel never
|
|
57
72
|
emits it: a deleted world's keys are deleted with it, so the key answers 401 `invalid_credentials`
|
|
58
|
-
(
|
|
73
|
+
(2026-10-04; keel spec section 2). Found by the wire gate reading the SDK's own
|
|
59
74
|
built file for the codes it keys on.
|
|
60
75
|
|
|
61
76
|
## [4.5.0] — 2026-10-04
|
|
@@ -66,7 +81,7 @@ three behaviours the server has always had that no client doc said. Additive; no
|
|
|
66
81
|
### Added
|
|
67
82
|
- **`OwApiError.isOwnerOnly`**: 403 `owner_only`, a contributor attempting a world-level change
|
|
68
83
|
(`patchWorld`, publishing a show page). Owners and co-builders never see it. keel's OpenAPI
|
|
69
|
-
document does not name the code yet (
|
|
84
|
+
document does not name the code yet (the schema side has that to close); the wire returns it.
|
|
70
85
|
|
|
71
86
|
### Documented
|
|
72
87
|
- **An atomic `/bulk` rollback still returns 201 slots** for the items that would have
|
|
@@ -95,10 +110,10 @@ contributor meets on someone else's. Additive; nothing is removed or narrows.
|
|
|
95
110
|
### Fixed
|
|
96
111
|
- **`FIELD_SCHEMA` no longer marks `marker.map/zone/x/y/order` and `pin.map/element_type/element_id/x/y`
|
|
97
112
|
as `required: true`.** The wire requires `name` and nothing else (rulings.yaml `nullable-by-default`,
|
|
98
|
-
|
|
113
|
+
ruling 2026-07-28; keel's OpenAPI write schemas say `required: [name]`), but the schema files still
|
|
99
114
|
list those fields and the generator copied the lists, so a form built from the table demanded
|
|
100
115
|
coordinates the server never did. Found by comparing the SDK with keel's OpenAPI document (the
|
|
101
|
-
new `verify-sdk-wire` gate
|
|
116
|
+
new `verify-sdk-wire` gate). **If you read `required` from this table, marker and pin
|
|
102
117
|
fields now read as optional**, which is what the server accepts. The generator notes the lists it
|
|
103
118
|
ignores on every run and says when canonical stops carrying them.
|
|
104
119
|
|
|
@@ -146,7 +161,7 @@ Ids, honest filter docs, and the schema repin. Nothing is removed; no call needs
|
|
|
146
161
|
order elements by id. For creation order use `created_at`; `change_seq` is last-write
|
|
147
162
|
order. This is a **default, not a
|
|
148
163
|
requirement**: a v4 or v7 id a caller supplies is still accepted as-is, and
|
|
149
|
-
every id already stored stays valid. Keel mints v7 server-side too (
|
|
164
|
+
every id already stored stays valid. Keel mints v7 server-side too (ruling,
|
|
150
165
|
2026-09-28). Pinned by six tests: version and variant, the big-endian timestamp above
|
|
151
166
|
bit 32, fractional and pre-1970 clocks floored consistently, creation order across 50
|
|
152
167
|
consecutive milliseconds, 1,000 distinct ids inside one millisecond, and the no-`crypto`
|
|
@@ -156,7 +171,7 @@ Ids, honest filter docs, and the schema repin. Nothing is removed; no call needs
|
|
|
156
171
|
edges, and keel's `uuid7()` agrees on timestamp, version and variant for a pinned clock.
|
|
157
172
|
- **`elementColor()` on an unknown type now throws a `TypeError` that names the type.** It
|
|
158
173
|
used to crash with `Cannot read properties of undefined (reading 'dark')`. Found while
|
|
159
|
-
building
|
|
174
|
+
building a colour gate: atlas's own copy falls back to the `world` family for an
|
|
160
175
|
unknown type, so swapping it for this export is not a pure re-export for that input, and the
|
|
161
176
|
docstring now says so. Whether the package should fall back is left to its consumers.
|
|
162
177
|
- The generated field-schema comment no longer calls `maximum:` an open question or counts
|
|
@@ -303,7 +318,7 @@ pinned consumers.
|
|
|
303
318
|
### Added (post-alpha.0, same night)
|
|
304
319
|
- **`ELEMENT_ICONS` GENERATED** from keel's `icon:` wrapper key (keel `56c124a`).
|
|
305
320
|
- **`ELEMENT_SECTIONS` DERIVED** from the canonical schema's own document structure
|
|
306
|
-
(
|
|
321
|
+
(ruling: sections are the standard tier's property groups; document order is
|
|
307
322
|
display order). Divergence check vs the old hand table found and fixed three fossils:
|
|
308
323
|
creature "Behaviour"→"Behavior", pin's triple-listed generic link → `element`,
|
|
309
324
|
relation "Involves" listing a nonexistent `relations` field. Canonical is truth.
|
|
@@ -312,18 +327,18 @@ pinned consumers.
|
|
|
312
327
|
covered by the codegen drift guard. AGENTS.md points agents at it first.
|
|
313
328
|
- **`OwV2Client.request()` is public** (typed escape hatch; does not sanitize) and
|
|
314
329
|
structurally satisfies `TokenTransport` — `new TokenResource(client)` just works.
|
|
315
|
-
Token ruling
|
|
330
|
+
Token ruling: keel keeps `/tokens/*` long-term; ported, not deleted.
|
|
316
331
|
- README rewritten v2-native (v1 sections, branded types, and the encrypted-key
|
|
317
332
|
walkthrough removed; bulk partial-failure and idempotency-key hygiene promoted).
|
|
318
333
|
|
|
319
|
-
### alpha.1 — consumer-pin fixes (
|
|
334
|
+
### alpha.1 — consumer-pin fixes (atlas review, same night)
|
|
320
335
|
- **`parseEnvelope` → `parseErrorEnvelope`** (it parses the platform *error* envelope;
|
|
321
336
|
renamed before the 4.0 name freeze to avoid collision with the world-export envelope).
|
|
322
337
|
- The never-whitelist LAW now lives as a comment on `READ_ONLY_FIELDS` itself.
|
|
323
338
|
- Stale v1 example in the shipped d.ts fixed (TokenResource JSDoc).
|
|
324
339
|
|
|
325
340
|
### Release gates — ALL GREEN (2026-07-23 night)
|
|
326
|
-
- **Gate 3 (wire-log v1-traffic query
|
|
341
|
+
- **Gate 3 (wire-log v1-traffic query)**: GREEN — no unknown v1-SDK consumer on
|
|
327
342
|
the wire; observed v1 traffic is pinned deployed builds (council proxy, legacy plugin
|
|
328
343
|
walks) that an npm major cannot touch. The v1 API dialect stays served regardless.
|
|
329
344
|
- **`/api/v2/tokens/` live on prod + staging** (keel `e181689`; three-base byte
|
|
@@ -331,7 +346,7 @@ pinned consumers.
|
|
|
331
346
|
"older server", not "no tokens". Requirement noted in the migration guide.
|
|
332
347
|
- **`ONLYWORLDS_VERSION` now GENERATED** from canonical's `VERSION` file (carried
|
|
333
348
|
into keel `schema/` by the refresh script, keel `492168c`) — the last hand-synced
|
|
334
|
-
constant is dead. Consumer soak:
|
|
349
|
+
constant is dead. Consumer soak: the atlas app pinned the alpha against its full
|
|
335
350
|
static surface — strict-clean compile, correct runtime, package shape approved.
|
|
336
351
|
- **No `npm deprecate` on 3.x** (landscape research; 3.x stays plainly supported).
|
|
337
352
|
- 4.x wishlist: account client (list/mint/create — atlas first consumer), world-export
|
|
@@ -345,7 +360,7 @@ pinned consumers.
|
|
|
345
360
|
`ELEMENT_FAMILIES` (type → family), `FAMILY_COLORS` (family → `{light, dark}` hex),
|
|
346
361
|
`familyOf(type)`, `elementColor(type, mode)`, `FAMILY_ORDER`, type `ElementFamily`.
|
|
347
362
|
Four semantic families (agents / world / abstract / temporal) ruled 2026-07-22 after
|
|
348
|
-
CVD-validated measurement
|
|
363
|
+
CVD-validated measurement.
|
|
349
364
|
Colour carries the FAMILY; `ELEMENT_ICONS` carries the TYPE. Keyed on the v2 slug
|
|
350
365
|
union. First proven live in atlas and council, whose local copies become re-exports.
|
|
351
366
|
**`ELEMENT_FAMILIES` is GENERATED** from the `family:` key in keel's schema YAML
|
|
@@ -373,7 +388,7 @@ pinned consumers.
|
|
|
373
388
|
|
|
374
389
|
## [3.0.0] — 2026-07-18
|
|
375
390
|
|
|
376
|
-
- v2-native client (`OwV2Client`) absorbed from
|
|
391
|
+
- v2-native client (`OwV2Client`) absorbed from an earlier v2 client (ow-v2-client v0.9.0),
|
|
377
392
|
wire-corrected against live staging fixtures (S22). Generated element types from the
|
|
378
393
|
canonical keel schema YAML (`src/v2/types.generated.ts`), validated against all 1,086
|
|
379
394
|
live W11 elements. v1 surface unchanged and frozen.
|
package/README.md
CHANGED
|
@@ -3,74 +3,79 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@onlyworlds/sdk)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
canonical constants (element types, icons, colour families, field schema) — generated from the
|
|
8
|
-
canonical OnlyWorlds schema, obtained through the public
|
|
9
|
-
[schema distribution](https://github.com/OnlyWorlds/schema-dist) at a pinned, hash-verified
|
|
10
|
-
tag. The generated files carry that tag and commit in their header, so what these types were
|
|
11
|
-
built from is checkable rather than asserted.
|
|
6
|
+
OnlyWorlds is an open standard for worldbuilding data: 22 element types (characters, locations, events, laws and the rest) that any tool can read and write. This is a typed client for its API, with the schema's constants (element types, icons, colour families, field metadata) generated from the published [schema distribution](https://github.com/OnlyWorlds/schema-dist). It runs in Node 18+ and in the browser through a bundler (ESM only).
|
|
12
7
|
|
|
13
|
-
|
|
14
|
-
(`OnlyWorldsClient`) or CommonJS `require()`, stay on 3.x — it remains published and the v1 API
|
|
15
|
-
remains served. See [docs/migrating-3-to-4.md](docs/migrating-3-to-4.md).
|
|
16
|
-
|
|
17
|
-
## Installation
|
|
8
|
+
## Install
|
|
18
9
|
|
|
19
10
|
```bash
|
|
20
11
|
npm install @onlyworlds/sdk
|
|
21
12
|
```
|
|
22
13
|
|
|
23
|
-
##
|
|
14
|
+
## First run
|
|
15
|
+
|
|
16
|
+
Moppetopia is a public demo world. Its read-only key, `0000000001`, needs no account:
|
|
24
17
|
|
|
25
18
|
```typescript
|
|
26
19
|
import { OwV2Client } from '@onlyworlds/sdk';
|
|
27
20
|
|
|
28
|
-
const client = new OwV2Client({ apiKey: '
|
|
29
|
-
|
|
21
|
+
const client = new OwV2Client({ apiKey: '0000000001' });
|
|
22
|
+
console.log((await client.getWorld()).name);
|
|
23
|
+
const { data } = await client.list('character', { limit: 3 });
|
|
24
|
+
for (const c of data) console.log(' ', c.name);
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
Moppetopia
|
|
29
|
+
Admiral Splashworth
|
|
30
|
+
Admiral Fluffington
|
|
31
|
+
Captain Snoot
|
|
30
32
|
```
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
`ow_a_` account Bearer / 10-digit legacy. Writes on a PIN-protected world also pass `apiPin`.
|
|
34
|
-
Demo keys `0000000000`–`0000000009` read real sample worlds.
|
|
34
|
+
## Your own world
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
Create a world at [onlyworlds.com](https://www.onlyworlds.com); its keys are on the world's page. A new key is shown once, so copy it then.
|
|
37
|
+
|
|
38
|
+
- An `ow_r_` key reads, with no PIN. It is the key to give to players or a public site.
|
|
39
|
+
- An `ow_w_` key reads and writes. Writes also send a PIN as `apiPin`.
|
|
40
|
+
- Anyone who loads a web page can read the keys in its code. Ship only an `ow_r_` key to a browser, and keep write keys and seat secrets on a server.
|
|
41
|
+
- For code that writes, give it its own [agent seat](https://onlyworlds.github.io/docs/development/agents), a key for one tool or script. The seat's key and its `ow_s_` secret (sent as `apiPin`) work in one world, and you can remove them without touching your account PIN.
|
|
37
42
|
|
|
38
43
|
```typescript
|
|
39
|
-
const writer = new OwV2Client({ apiKey: '
|
|
44
|
+
const writer = new OwV2Client({ apiKey: 'ow_w_…', apiPin: 'ow_s_…' });
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Reading and writing
|
|
40
48
|
|
|
41
|
-
|
|
42
|
-
// - link fields use ONE bare name both directions (no _ids suffix — that's v1)
|
|
43
|
-
// - NEVER send a "world" field (identity comes from the key; the client strips it anyway)
|
|
49
|
+
```typescript
|
|
44
50
|
const location = await writer.create('location', {
|
|
45
51
|
name: 'Dragon Peak',
|
|
46
|
-
description: 'A
|
|
47
|
-
}); // id minted client-side when omitted
|
|
48
|
-
// name is the one required field, and required means the key is present:
|
|
49
|
-
// '' and null are accepted and stored as '' (nameless Markers exist).
|
|
52
|
+
description: 'A mountain peak where dragons nest',
|
|
53
|
+
}); // the id is minted client-side when omitted, so a retry creates nothing twice
|
|
50
54
|
|
|
51
55
|
const dragon = await writer.create('creature', {
|
|
52
56
|
name: 'Vorrath the Ember-Scaled',
|
|
53
|
-
location: location.id,
|
|
57
|
+
location: location.id, // a single link: a UUID or null
|
|
54
58
|
});
|
|
55
59
|
|
|
56
60
|
const fetched = await writer.get('creature', dragon.id);
|
|
57
|
-
// fetched.location === location.id
|
|
61
|
+
// fetched.location === location.id: a field reads the way it writes
|
|
58
62
|
|
|
59
|
-
// PATCH
|
|
63
|
+
// PATCH replaces the fields it sends; an array is replaced whole
|
|
60
64
|
await writer.patch('location', location.id, { supertype: 'Mountain' });
|
|
61
65
|
|
|
62
|
-
// For
|
|
63
|
-
const
|
|
64
|
-
await writer.editLinks('creature', dragon.id, 'abilities', { add: [
|
|
66
|
+
// For links, the atomic merge; it returns the updated element
|
|
67
|
+
const breath = await writer.create('ability', { name: 'Ember Breath' });
|
|
68
|
+
await writer.editLinks('creature', dragon.id, 'abilities', { add: [breath.id], remove: [] });
|
|
65
69
|
|
|
66
|
-
//
|
|
70
|
+
// Every page of a type
|
|
67
71
|
for await (const character of writer.listAll('character')) { /* ... */ }
|
|
68
72
|
```
|
|
69
73
|
|
|
70
|
-
|
|
74
|
+
A link field has one name in both directions (`location`, not `location_id`). Only `name` is required, and an empty name is stored as `''`. A `world` field in a payload is ignored: the key decides the world, and the client strips it anyway.
|
|
75
|
+
|
|
76
|
+
## Bulk writes
|
|
71
77
|
|
|
72
|
-
`/bulk`
|
|
73
|
-
never make: treating a 200 as "everything landed."
|
|
78
|
+
`/bulk` answers 200 even when some items fail, so check `errors`:
|
|
74
79
|
|
|
75
80
|
```typescript
|
|
76
81
|
const res = await writer.bulk(
|
|
@@ -78,87 +83,80 @@ const res = await writer.bulk(
|
|
|
78
83
|
{ type: 'character', element: { name: 'A' } },
|
|
79
84
|
{ type: 'event', element: { name: 'B' } },
|
|
80
85
|
],
|
|
81
|
-
{ idempotencyKey: crypto.randomUUID() }, //
|
|
82
|
-
);
|
|
86
|
+
{ idempotencyKey: crypto.randomUUID() }, // a new key per attempt: a failed batch is cached under its key
|
|
87
|
+
);
|
|
83
88
|
if (res.errors) {
|
|
84
89
|
for (const slot of res.items.filter((s) => s.status >= 400)) {
|
|
85
90
|
console.warn(slot.error?.code, slot.error?.message, slot.error?.doc_url);
|
|
86
91
|
}
|
|
87
92
|
}
|
|
88
|
-
// Pass { atomic: true } for all-or-nothing instead. res.wasReplay flags idempotent replays.
|
|
89
|
-
// After a failed atomic batch NOTHING was written, but the slots that would have succeeded
|
|
90
|
-
// still say 201 (keel's counterfactual 201s): do not record those ids as created.
|
|
91
93
|
```
|
|
92
94
|
|
|
95
|
+
Pass `{ atomic: true }` for all or nothing. After a failed atomic batch nothing was written, but the slots that would have succeeded still read 201: don't record those ids as created. `res.wasReplay` marks an idempotent replay.
|
|
96
|
+
|
|
93
97
|
## Images
|
|
94
98
|
|
|
95
99
|
```typescript
|
|
96
|
-
const image = await writer.uploadImage(file);
|
|
100
|
+
const image = await writer.uploadImage(file); // a Blob, File, ArrayBuffer or Uint8Array
|
|
97
101
|
await writer.patch('character', id, { image_url: image.url });
|
|
98
102
|
```
|
|
99
103
|
|
|
100
|
-
|
|
101
|
-
sees them, and the edge never sees your key). webp, png, jpeg or avif (never SVG or gif), read from the
|
|
102
|
-
bytes. Each ticket counts toward the world's daily limit and the account's image
|
|
103
|
-
storage. To upload yourself (for a progress bar), take `createMediaTicket()` and POST the bytes to
|
|
104
|
-
its `upload_url` with `Authorization: Bearer <ticket>`.
|
|
104
|
+
The SDK asks the API for a single-use ticket, then sends the bytes straight to the upload host, which never sees your key. webp, png, jpeg or avif (no SVG or gif), up to 15 MB. Each upload counts toward the world's daily limit and the account's storage. To upload yourself (for a progress bar), call `createMediaTicket()` and POST the bytes to its `upload_url` with `Authorization: Bearer <ticket>`.
|
|
105
105
|
|
|
106
106
|
## Sync
|
|
107
107
|
|
|
108
108
|
```typescript
|
|
109
|
-
let cursor; // opaque
|
|
109
|
+
let cursor; // opaque and never expires: keep it
|
|
110
110
|
for await (const change of client.changesAll(cursor)) {
|
|
111
|
-
//
|
|
111
|
+
// changes arrive in order; apply them in order and you converge
|
|
112
112
|
}
|
|
113
|
-
// GOTCHA: world-meta edits (name, calendar, public_read) do NOT enter /changes.
|
|
114
|
-
// Poll client.getWorld() and compare updated_at separately.
|
|
115
113
|
```
|
|
116
114
|
|
|
115
|
+
Edits to the world itself (its name, calendar, `public_read`) don't appear in the change feed. Read `client.getWorld()` and compare `updated_at`.
|
|
116
|
+
|
|
117
117
|
## Errors
|
|
118
118
|
|
|
119
|
-
Every non-2xx throws `OwApiError`
|
|
120
|
-
`.param` (the exact field that failed), and `.docUrl` — surface `docUrl` in your UX. Transport
|
|
121
|
-
failures throw `OwNetworkError`. `err.isValidationError` is the common branch.
|
|
119
|
+
Every non-2xx response throws `OwApiError` with the API's envelope: `.status`, `.type`, `.code`, `.param` (the field that failed) and `.docUrl`, which is worth showing to your users. A transport failure throws `OwNetworkError`. `err.isValidationError` covers the common case.
|
|
122
120
|
|
|
123
|
-
##
|
|
121
|
+
## Schema constants
|
|
124
122
|
|
|
125
123
|
```typescript
|
|
126
124
|
import {
|
|
127
|
-
ELEMENT_TYPES,
|
|
128
|
-
ELEMENT_ICONS,
|
|
129
|
-
ELEMENT_LABELS,
|
|
130
|
-
ELEMENT_SECTIONS,
|
|
131
|
-
FIELD_SCHEMA,
|
|
132
|
-
elementColor,
|
|
125
|
+
ELEMENT_TYPES, // the 22 type slugs (and the ElementType union)
|
|
126
|
+
ELEMENT_ICONS, // a Material Symbols icon per type
|
|
127
|
+
ELEMENT_LABELS, // plural display labels
|
|
128
|
+
ELEMENT_SECTIONS, // field grouping and display order
|
|
129
|
+
FIELD_SCHEMA, // per-field type and link target
|
|
130
|
+
elementColor, // colour by family; the icon carries the type
|
|
133
131
|
} from '@onlyworlds/sdk';
|
|
134
132
|
|
|
135
|
-
elementColor('character', 'dark'); // '#3987e5'
|
|
136
|
-
// Always pair colour with icon + label; colour alone is not accessible.
|
|
133
|
+
elementColor('character', 'dark'); // '#3987e5'
|
|
137
134
|
```
|
|
138
135
|
|
|
139
|
-
The
|
|
140
|
-
|
|
136
|
+
The four colour families (agents, world, abstract, temporal) are checked for colour-blind separation. Show colour with the icon and label, never alone. [SCHEMA.md](SCHEMA.md) (generated, in the package) describes every field; AI agents should read [AGENTS.md](AGENTS.md) first.
|
|
137
|
+
|
|
138
|
+
## Tokens
|
|
141
139
|
|
|
142
|
-
|
|
140
|
+
The account's token allowance and ratings, which some OnlyWorlds tools use.
|
|
143
141
|
|
|
144
142
|
```typescript
|
|
145
143
|
import { TokenResource } from '@onlyworlds/sdk';
|
|
146
|
-
const tokens = new TokenResource(writer);
|
|
144
|
+
const tokens = new TokenResource(writer);
|
|
147
145
|
const status = await tokens.getStatus();
|
|
148
146
|
```
|
|
149
147
|
|
|
150
|
-
##
|
|
148
|
+
## SDK or MCP
|
|
151
149
|
|
|
152
|
-
|
|
153
|
-
tool-schema overhead. For **live exploration of a user's world from a chat/agent context**, use
|
|
154
|
-
the MCP server at `https://www.onlyworlds.com/mcp` (same `API-Key`/`API-Pin` headers, 12 tools;
|
|
155
|
-
unaffected by SDK versioning).
|
|
150
|
+
Use this SDK for known operations in your own code (CRUD, sync, bulk). To let an AI assistant that speaks MCP (the Model Context Protocol) explore a world in a chat, connect it to `https://www.onlyworlds.com/mcp` with the same key and PIN as `API-Key` and `API-Pin` headers.
|
|
156
151
|
|
|
157
|
-
##
|
|
152
|
+
## Version 3 and the old API
|
|
158
153
|
|
|
159
|
-
|
|
154
|
+
4.x speaks the current (v2) API only. The v1 client (`OnlyWorldsClient`) and CommonJS `require()` stay on 3.x, which remains published and supported: see [the migration guide](docs/migrating-3-to-4.md).
|
|
160
155
|
|
|
161
156
|
## Links
|
|
162
157
|
|
|
163
|
-
|
|
164
|
-
|
|
158
|
+
[Docs](https://onlyworlds.github.io/docs/development/typescript) · [Games](https://onlyworlds.github.io/docs/development/games) · [API reference](https://www.onlyworlds.com/api/docs) · [Issues](https://github.com/OnlyWorlds/sdk/issues) · [Changelog](CHANGELOG.md)
|
|
159
|
+
|
|
160
|
+
## License
|
|
161
|
+
|
|
162
|
+
MIT
|
package/SCHEMA.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# OnlyWorlds Schema Reference
|
|
2
2
|
|
|
3
|
-
**Source**: https://github.com/OnlyWorlds/schema-dist @ **v0.30.
|
|
3
|
+
**Source**: https://github.com/OnlyWorlds/schema-dist @ **v0.30.2-dist.16** — canonical schema **00.30.02**, published 2026-10-08.
|
|
4
4
|
|
|
5
5
|
GENERATED from the canonical schema YAML — do not hand-edit (regenerate: `python codegen/generate_types.py`).
|
|
6
6
|
Written for both humans and AI agents reading this package locally.
|
|
@@ -326,8 +326,8 @@ Families (colour semantics; icon carries the type): agents · world · abstract
|
|
|
326
326
|
- `governing_title` (single link → title) — Governing figure assigned by the location's primary power
|
|
327
327
|
- `secondary_powers` (multi link → institution) — Institutions with significant political control
|
|
328
328
|
- `zone` (single link → zone) — Zone of interest that is associated with the location
|
|
329
|
-
- `rival` (single link → location) —
|
|
330
|
-
- `partner` (single link → location) —
|
|
329
|
+
- `rival` (single link → location) — Location with an active, traditional, or historical rivalry with this one
|
|
330
|
+
- `partner` (single link → location) — Location with active, cooperative, or historical ties to this one
|
|
331
331
|
|
|
332
332
|
### World
|
|
333
333
|
|
|
@@ -388,7 +388,7 @@ Families (colour semantics; icon carries the type): agents · world · abstract
|
|
|
388
388
|
- `x` (integer) — x coordinate, from bottom left of the map
|
|
389
389
|
- `y` (integer) — y coordinate, from bottom left of the map
|
|
390
390
|
- `z` (integer) — z coordinate, in case of depth
|
|
391
|
-
- `order` (integer) — Sequence position when markers define a polygon or line (0 = first point)
|
|
391
|
+
- `order` (integer) — Sequence position when markers define a polygon or line (0 = first point); without it, markers keep the order they were made in
|
|
392
392
|
|
|
393
393
|
|
|
394
394
|
## narrative · family: temporal · icon: menu_book
|
|
@@ -482,7 +482,7 @@ Families (colour semantics; icon carries the type): agents · world · abstract
|
|
|
482
482
|
### Details
|
|
483
483
|
|
|
484
484
|
- `map` (single link → map) — Map that the pin is placed on
|
|
485
|
-
- `element` (generic link (any element type)) —
|
|
485
|
+
- `element` (generic link (any element type)) — The element this pin places on the map, of any type
|
|
486
486
|
- `x` (integer) — x coordinate, from bottom left of the map
|
|
487
487
|
- `y` (integer) — y coordinate, from bottom left of the map
|
|
488
488
|
- `z` (integer) — z coordinate, in case of depth (optional)
|
|
@@ -517,7 +517,6 @@ Families (colour semantics; icon carries the type): agents · world · abstract
|
|
|
517
517
|
- `families` (multi link → family) — Families relevant to the relation
|
|
518
518
|
- `titles` (multi link → title) — Titles relevant to the relation
|
|
519
519
|
- `constructs` (multi link → construct) — Concepts, contracts, or principles relevant to the relation
|
|
520
|
-
- `events` (multi link → event) — Events where the relation is involved or relevant
|
|
521
520
|
- `narratives` (multi link → narrative) — Narratives relevant to the relation
|
|
522
521
|
|
|
523
522
|
|
package/dist/index.d.ts
CHANGED
|
@@ -33,7 +33,7 @@ type ElementType = 'ability' | 'character' | 'collective' | 'construct' | 'creat
|
|
|
33
33
|
declare const ELEMENT_TYPES: ElementType[];
|
|
34
34
|
/** Canonical OnlyWorlds schema version. Source: the `canonical:` value of the pinned
|
|
35
35
|
* distribution's VERSION file (see the provenance block at the top of this file). */
|
|
36
|
-
declare const ONLYWORLDS_VERSION: "00.30.
|
|
36
|
+
declare const ONLYWORLDS_VERSION: "00.30.02";
|
|
37
37
|
/** The four semantic families (colour carries the family; ELEMENT_ICONS carries the type). */
|
|
38
38
|
type ElementFamily = 'agents' | 'world' | 'abstract' | 'temporal';
|
|
39
39
|
/** Per-type semantic family. Source: the distribution's `presentation.json` sidecar
|
|
@@ -1844,7 +1844,7 @@ declare const FIELD_SCHEMA: {
|
|
|
1844
1844
|
};
|
|
1845
1845
|
|
|
1846
1846
|
/**
|
|
1847
|
-
* keel v2 engine absorbed from
|
|
1847
|
+
* keel v2 engine absorbed from an earlier v2 client (ow-v2-client v0.9.0),
|
|
1848
1848
|
* wire-corrected against live staging fixtures 2026-07-18.
|
|
1849
1849
|
*
|
|
1850
1850
|
* OnlyWorlds v2 (keel) wire types -- the NON-generated, hand-owned wire shapes
|
|
@@ -2024,7 +2024,7 @@ interface OwClientConfig {
|
|
|
2024
2024
|
}
|
|
2025
2025
|
|
|
2026
2026
|
/**
|
|
2027
|
-
* keel v2 engine absorbed from
|
|
2027
|
+
* keel v2 engine absorbed from an earlier v2 client (ow-v2-client v0.9.0),
|
|
2028
2028
|
* wire-corrected against live staging fixtures 2026-07-18.
|
|
2029
2029
|
*
|
|
2030
2030
|
* keel error envelope handling. The error contract is part of the contract:
|
|
@@ -2115,7 +2115,7 @@ declare function parseErrorEnvelope(status: number, body: unknown, retryAfter?:
|
|
|
2115
2115
|
declare function errorFromResponse(res: Response): Promise<OwApiError>;
|
|
2116
2116
|
|
|
2117
2117
|
/**
|
|
2118
|
-
* keel v2 engine absorbed from
|
|
2118
|
+
* keel v2 engine absorbed from an earlier v2 client (ow-v2-client v0.9.0),
|
|
2119
2119
|
* wire-corrected against live staging fixtures 2026-07-18.
|
|
2120
2120
|
*
|
|
2121
2121
|
* OnlyWorlds key-kind detection. Prefixes make leaked keys grep-scannable
|
|
@@ -2143,7 +2143,7 @@ declare function kindCanWrite(kind: OwKeyKind): boolean;
|
|
|
2143
2143
|
declare function pinExpectation(kind: OwKeyKind): 'never' | 'optional' | 'required-for-private-reads';
|
|
2144
2144
|
|
|
2145
2145
|
/**
|
|
2146
|
-
* keel v2 engine absorbed from
|
|
2146
|
+
* keel v2 engine absorbed from an earlier v2 client (ow-v2-client v0.9.0),
|
|
2147
2147
|
* wire-corrected against live staging fixtures 2026-07-18.
|
|
2148
2148
|
*
|
|
2149
2149
|
* OwV2Client -- thin typed fetch client for the keel v2 API.
|
|
@@ -2300,9 +2300,8 @@ declare class OwV2Client {
|
|
|
2300
2300
|
/**
|
|
2301
2301
|
* Canonical element colour palette — four semantic families.
|
|
2302
2302
|
*
|
|
2303
|
-
* Ruled
|
|
2304
|
-
*
|
|
2305
|
-
* hues is structurally impossible; four families is the ceiling that passes
|
|
2303
|
+
* Ruled 2026-07-22 after a measurement pass: 22 mutually-separable hues
|
|
2304
|
+
* is structurally impossible; four families is the ceiling that passes
|
|
2306
2305
|
* all-pairs CVD separation in both modes. **Colour carries the FAMILY; the
|
|
2307
2306
|
* icon (`ELEMENT_ICONS`) carries the TYPE.** Dark-mode pairs land in the 6–8
|
|
2308
2307
|
* CVD floor band, so secondary encoding (icon + label) is REQUIRED alongside
|
|
@@ -2493,7 +2492,7 @@ declare enum GameTier {
|
|
|
2493
2492
|
/**
|
|
2494
2493
|
* Minimal transport the token resource needs — structurally satisfied by
|
|
2495
2494
|
* `OwV2Client` (its `request()` is public since 4.0): `new TokenResource(client)`.
|
|
2496
|
-
* Wire ruling (
|
|
2495
|
+
* Wire ruling (2026-07-23): keel keeps the /tokens/* economy long-term
|
|
2497
2496
|
* (Tangle ratings write it, Council voting reads it) — port, don't delete.
|
|
2498
2497
|
*/
|
|
2499
2498
|
interface TokenTransport {
|
package/dist/index.js
CHANGED
|
@@ -433,7 +433,7 @@ function buildQuery(params) {
|
|
|
433
433
|
|
|
434
434
|
// src/v2/types.generated.ts
|
|
435
435
|
var ELEMENT_TYPES = ["ability", "character", "collective", "construct", "creature", "event", "family", "institution", "language", "law", "location", "map", "marker", "narrative", "object", "phenomenon", "pin", "relation", "species", "title", "trait", "zone"];
|
|
436
|
-
var ONLYWORLDS_VERSION = "00.30.
|
|
436
|
+
var ONLYWORLDS_VERSION = "00.30.02";
|
|
437
437
|
var ELEMENT_FAMILIES = {
|
|
438
438
|
ability: "abstract",
|
|
439
439
|
character: "agents",
|
|
@@ -564,7 +564,7 @@ var ELEMENT_SECTIONS = {
|
|
|
564
564
|
],
|
|
565
565
|
relation: [
|
|
566
566
|
{ name: "Nature", order: 1, fields: ["background", "start_date", "end_date", "intensity", "actor", "events"] },
|
|
567
|
-
{ name: "Involves", order: 2, fields: ["characters", "objects", "locations", "species", "creatures", "institutions", "traits", "collectives", "zones", "abilities", "phenomena", "languages", "families", "titles", "constructs", "
|
|
567
|
+
{ name: "Involves", order: 2, fields: ["characters", "objects", "locations", "species", "creatures", "institutions", "traits", "collectives", "zones", "abilities", "phenomena", "languages", "families", "titles", "constructs", "narratives"] }
|
|
568
568
|
],
|
|
569
569
|
species: [
|
|
570
570
|
{ name: "Biology", order: 1, fields: ["appearance", "life_span", "weight", "nourishment", "reproduction", "adaptations"] },
|