@onlyworlds/sdk 4.1.0 → 4.2.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 +48 -34
- package/CHANGELOG.md +57 -0
- package/SCHEMA.md +4 -2
- package/dist/index.d.ts +12 -4
- package/dist/index.js +15 -7
- package/package.json +3 -2
package/AGENTS.md
CHANGED
|
@@ -1,34 +1,48 @@
|
|
|
1
|
-
# For AI agents using @onlyworlds/sdk
|
|
2
|
-
|
|
3
|
-
**
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
**
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
**
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
1
|
+
# For AI agents using @onlyworlds/sdk
|
|
2
|
+
|
|
3
|
+
**Current as of**: SDK **4.x** · schema-dist **v0.30.1-dist.15** (canonical 00.30.01).
|
|
4
|
+
This line is asserted by `codegen:check` in CI — if the pin moves and this file is not
|
|
5
|
+
re-read against it, the check fails rather than letting this document rot quietly.
|
|
6
|
+
|
|
7
|
+
**Start with [SCHEMA.md](SCHEMA.md)** (in this package): the full generated schema reference —
|
|
8
|
+
every type, every field with its meaning, link directions, families, icons, display sections.
|
|
9
|
+
It is generated from the same canonical YAML as the types, so it cannot drift.
|
|
10
|
+
|
|
11
|
+
**What this package is**: the canonical typed TypeScript client for the OnlyWorlds v2 API,
|
|
12
|
+
plus the canonical constants (element types, icons, colour families, field schema).
|
|
13
|
+
OnlyWorlds is an open standard for portable world data — 22 element types, UUID-linked.
|
|
14
|
+
|
|
15
|
+
**Use the v2 surface.** `OwV2Client` + the `V2ElementType` slug union + the generated
|
|
16
|
+
interfaces in `types.generated.ts` (emitted from the canonical schema YAML, validated
|
|
17
|
+
against live data). The v1 surface (`OnlyWorldsClient`, the `ElementType` enum) is not in
|
|
18
|
+
4.x — it was removed at 4.0.0 and lives only in 3.x. Do not build new work on it.
|
|
19
|
+
|
|
20
|
+
**SDK vs MCP server — pick correctly**:
|
|
21
|
+
- Known, deterministic operations (CRUD, sync, bulk) → **this SDK**. Typed calls, typed
|
|
22
|
+
responses, far cheaper than tool-schema reasoning.
|
|
23
|
+
- Live exploration of a user's world from a chat/agent context → the **MCP server** at
|
|
24
|
+
`https://www.onlyworlds.com/mcp` (same `API-Key`/`API-Pin` headers, 11 tools).
|
|
25
|
+
|
|
26
|
+
**Wire facts that bite** (full details in README):
|
|
27
|
+
- Never send a `"world"` field in payloads — world identity comes from the API key (422 otherwise).
|
|
28
|
+
- v2 link fields use ONE name both directions (no `_ids` suffix — that is v1 dialect only).
|
|
29
|
+
- PATCH is destructive on sent fields; use `editLinks` (atomic add/remove) for relationships.
|
|
30
|
+
- World-meta changes do NOT appear in `/changes` — poll `GET /world` separately.
|
|
31
|
+
- Extension fields: `x_<toolname>_*` is the sanctioned namespace for tool-specific state;
|
|
32
|
+
unknown unprefixed fields 422. Extensions are capped at **64 KB per element** (422,
|
|
33
|
+
`param: extensions`).
|
|
34
|
+
- List filters: only `name__icontains`, `supertype` and `subtype` are built. Any other
|
|
35
|
+
filter key — and `?ordering=` — returns 422 naming it. Filter or sort client-side.
|
|
36
|
+
- Ids: the client mints **UUIDv7** on an id-less `create` (since 4.2.0; keel mints v7 too).
|
|
37
|
+
A v4 or v7 id you supply is accepted. **Never sort elements by id**: worlds mix v7, v4
|
|
38
|
+
and legacy `06x…` ids (nibble 7 too, but seconds-first). For creation order use
|
|
39
|
+
`created_at`; `change_seq` is last-write order, not creation.
|
|
40
|
+
A PUT or bulk item whose id belongs to **another world** returns 409 `id_conflict`.
|
|
41
|
+
- A string holding an unpaired surrogate (text cut mid-emoji) is a 422 naming the field.
|
|
42
|
+
Slice strings by code point, not by UTF-16 unit.
|
|
43
|
+
- Colour carries the element's FAMILY (`elementColor(type, mode)`); the icon
|
|
44
|
+
(`ELEMENT_ICONS`) carries the TYPE. Icon + label are required alongside colour, not optional.
|
|
45
|
+
|
|
46
|
+
**Auth**: prefixed keys — `ow_w_` (read+write), `ow_r_` (read-only, no PIN — the share
|
|
47
|
+
primitive), `ow_a_` (account Bearer). Demo keys `0000000000`–`0000000009` are read-only
|
|
48
|
+
test credentials against real data.
|
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,63 @@
|
|
|
3
3
|
All notable changes to `@onlyworlds/sdk`. Maintained from 3.1.0 onward (Kael, Assembly);
|
|
4
4
|
earlier history lives in git log only.
|
|
5
5
|
|
|
6
|
+
## [Unreleased]
|
|
7
|
+
|
|
8
|
+
## [4.2.0] — staged 2026-09-28, not yet published
|
|
9
|
+
|
|
10
|
+
Ids, honest filter docs, and the schema repin. Nothing is removed; no call needs to change.
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- **`create()` now mints an RFC 9562 UUIDv7** when the element has no id (was v4). The first
|
|
14
|
+
48 bits are the creation millisecond, so ids this client mints a millisecond or more apart
|
|
15
|
+
sort by creation (while the clock does not step backwards), which gives databases better
|
|
16
|
+
index locality. **This holds within one client only**: worlds also hold v4 ids and legacy
|
|
17
|
+
v1-server ids (`06x…`, which also carry version nibble 7 but put seconds first), so never
|
|
18
|
+
order elements by id. For creation order use `created_at`; `change_seq` is last-write
|
|
19
|
+
order. This is a **default, not a
|
|
20
|
+
requirement**: a v4 or v7 id a caller supplies is still accepted as-is, and
|
|
21
|
+
every id already stored stays valid. Keel mints v7 server-side too (Captain's ruling,
|
|
22
|
+
2026-09-28). Pinned by six tests: version and variant, the big-endian timestamp above
|
|
23
|
+
bit 32, fractional and pre-1970 clocks floored consistently, creation order across 50
|
|
24
|
+
consecutive milliseconds, 1,000 distinct ids inside one millisecond, and the no-`crypto`
|
|
25
|
+
fallback (asserting `Math.random` is actually used). Five injected defects (v4 nibble,
|
|
26
|
+
32-bit truncation, a dropped random fill, a dropped variant mask, an unfloored clock)
|
|
27
|
+
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
|
|
28
|
+
edges, and keel's `uuid7()` agrees on timestamp, version and variant for a pinned clock.
|
|
29
|
+
- **`elementColor()` on an unknown type now throws a `TypeError` that names the type.** It
|
|
30
|
+
used to crash with `Cannot read properties of undefined (reading 'dark')`. Found while
|
|
31
|
+
building the Forge's colour gate: atlas's own copy falls back to the `world` family for an
|
|
32
|
+
unknown type, so swapping it for this export is not a pure re-export for that input, and the
|
|
33
|
+
docstring now says so. Whether the package should fall back is left to its consumers.
|
|
34
|
+
- The generated field-schema comment no longer calls `maximum:` an open question or counts
|
|
35
|
+
its occurrences (the count was 41; since 00.30.01 it is 15). The question was ruled on
|
|
36
|
+
2026-07-29.
|
|
37
|
+
- **`ListParams.filter` JSDoc names what the server actually accepts**: `name__icontains`,
|
|
38
|
+
`supertype`, `subtype`. It used to list `__in`, `__gte`, `__lte` and `__isnull`, copied
|
|
39
|
+
from keel's spec, which described them but never built them. Probed live 2026-09-28: the
|
|
40
|
+
three accepted keys answer 200; every other one, and `?ordering=`, answers 422.
|
|
41
|
+
- **Schema repinned `v0.30.1-dist.13` → `v0.30.1-dist.15`** (canonical unchanged, 00.30.01).
|
|
42
|
+
Two generated values move: `ELEMENT_ICONS.institution` `business` → `account_balance`,
|
|
43
|
+
`ELEMENT_ICONS.marker` `place` → `location_on` (both Material Symbols names). dist.15
|
|
44
|
+
also adds `minimum: 0` to `ability.potency`; the walk does not surface bounds, so nothing
|
|
45
|
+
generated changes for it. 31/31 file hashes recomputed from a fresh download.
|
|
46
|
+
- **`AGENTS.md` re-read against the new pin** (its gate fired on the repin, as designed).
|
|
47
|
+
It still called the v1 client "frozen legacy" in this package; v1 was removed at 4.0.0.
|
|
48
|
+
It now also names the wire behaviours keel deployed on 2026-09-28 (keel D70): the 64 KB
|
|
49
|
+
extension cap, the three built filters and the `?ordering=` 422, 409 `id_conflict` for a
|
|
50
|
+
PUT or bulk id that belongs to another world, and the 422 for unpaired surrogates. None of
|
|
51
|
+
them needs client code.
|
|
52
|
+
|
|
53
|
+
### Also in this release (staged earlier)
|
|
54
|
+
- **`SCHEMA.md` now opens with its own provenance** (dist tag, canonical version, publish
|
|
55
|
+
date — rendered from `schema-pin.json`, never the wall clock). It ships in the tarball
|
|
56
|
+
and is read cold by agents outside this repo, where the pin file is not present; a
|
|
57
|
+
generated reference that cannot name its source was the one remaining self-dating gap.
|
|
58
|
+
- **`AGENTS.md` carries a "Current as of" line, asserted by `codegen:check`** — the tag it
|
|
59
|
+
names must match the pin or CI fails. A hand-maintained agent doc with an ungated date
|
|
60
|
+
is how this repo's previous agent doc went a major version stale. Gate watched firing
|
|
61
|
+
(tampered tag → exit 1, restored → 0).
|
|
62
|
+
|
|
6
63
|
## [4.1.0] — 2026-07-29
|
|
7
64
|
|
|
8
65
|
Public-surface hygiene. Nothing breaks; one member is now marked for removal, and one
|
package/SCHEMA.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# OnlyWorlds Schema Reference
|
|
2
2
|
|
|
3
|
+
**Source**: https://github.com/OnlyWorlds/schema-dist @ **v0.30.1-dist.15** — canonical schema **00.30.01**, published 2026-09-18.
|
|
4
|
+
|
|
3
5
|
GENERATED from the canonical schema YAML — do not hand-edit (regenerate: `python codegen/generate_types.py`).
|
|
4
6
|
Written for both humans and AI agents reading this package locally.
|
|
5
7
|
|
|
@@ -244,7 +246,7 @@ Families (colour semantics; icon carries the type): agents · world · abstract
|
|
|
244
246
|
- `creatures` (multi link → creature) — Creatures owned, bonded to, or representing the family
|
|
245
247
|
|
|
246
248
|
|
|
247
|
-
## institution · family: agents · icon:
|
|
249
|
+
## institution · family: agents · icon: account_balance
|
|
248
250
|
|
|
249
251
|
|
|
250
252
|
### Foundation
|
|
@@ -376,7 +378,7 @@ Families (colour semantics; icon carries the type): agents · world · abstract
|
|
|
376
378
|
- `location` (single link → location) — Location element that this map represents
|
|
377
379
|
|
|
378
380
|
|
|
379
|
-
## marker · family: world · icon:
|
|
381
|
+
## marker · family: world · icon: location_on
|
|
380
382
|
|
|
381
383
|
|
|
382
384
|
### Details
|
package/dist/index.d.ts
CHANGED
|
@@ -1958,9 +1958,10 @@ interface ListParams {
|
|
|
1958
1958
|
/** Sparse include-set of field names. */
|
|
1959
1959
|
fields?: string[];
|
|
1960
1960
|
/**
|
|
1961
|
-
*
|
|
1962
|
-
*
|
|
1963
|
-
*
|
|
1961
|
+
* Accepted: `name__icontains`, `supertype`, `subtype`. Any other key 422s
|
|
1962
|
+
* server-side, which names the typo -- the client passes keys through
|
|
1963
|
+
* unchecked and lets the platform say so. (`__in`, `__gte`, `__lte` and
|
|
1964
|
+
* `__isnull` are designed in keel's spec but not built; `ordering` 422s too.)
|
|
1964
1965
|
*/
|
|
1965
1966
|
filter?: Record<string, string | number | boolean>;
|
|
1966
1967
|
}
|
|
@@ -2099,7 +2100,7 @@ declare class OwV2Client {
|
|
|
2099
2100
|
/** GET /{type}/{id}/ -- optional one-level stub expansion / sparse fields. */
|
|
2100
2101
|
get(type: ElementType | string, id: string, opts?: Pick<ListParams, 'expand' | 'fields'>): Promise<OwElement>;
|
|
2101
2102
|
/**
|
|
2102
|
-
* POST /{type}/ -- create. Mints an RFC
|
|
2103
|
+
* POST /{type}/ -- create. Mints an RFC 9562 UUIDv7 for element.id when the
|
|
2103
2104
|
* caller omits one (design ruling D29d) so a retry carrying the same
|
|
2104
2105
|
* Idempotency-Key is structurally safe. Callers MAY still supply their own id.
|
|
2105
2106
|
*/
|
|
@@ -2223,6 +2224,13 @@ declare function familyOf(type: ElementType): ElementFamily;
|
|
|
2223
2224
|
* Name matches the live atlas/council implementations so their SDK swap is a
|
|
2224
2225
|
* re-export, not a rename. Defaults to `dark` (both current consumers are
|
|
2225
2226
|
* dark-surface).
|
|
2227
|
+
*
|
|
2228
|
+
* An unknown type throws a TypeError naming it (since 4.2.0; before, it crashed
|
|
2229
|
+
* with "Cannot read properties of undefined"). This is the one place a swap from
|
|
2230
|
+
* atlas's own copy is NOT a pure re-export: atlas falls back to the `world`
|
|
2231
|
+
* family for an unknown type. A caller that wants a fallback catches, or checks
|
|
2232
|
+
* `type in ELEMENT_FAMILIES` first; which fallback, if any, is a design call
|
|
2233
|
+
* this package does not make for its consumers.
|
|
2226
2234
|
*/
|
|
2227
2235
|
declare function elementColor(type: ElementType, mode?: 'light' | 'dark'): string;
|
|
2228
2236
|
/** All four families, in ruling order (the order IS the CVD-safety mechanism of the source palette). */
|
package/dist/index.js
CHANGED
|
@@ -143,7 +143,7 @@ var OwV2Client = class {
|
|
|
143
143
|
return this.request("GET", `/${type}/${id}/`, { query });
|
|
144
144
|
}
|
|
145
145
|
/**
|
|
146
|
-
* POST /{type}/ -- create. Mints an RFC
|
|
146
|
+
* POST /{type}/ -- create. Mints an RFC 9562 UUIDv7 for element.id when the
|
|
147
147
|
* caller omits one (design ruling D29d) so a retry carrying the same
|
|
148
148
|
* Idempotency-Key is structurally safe. Callers MAY still supply their own id.
|
|
149
149
|
*/
|
|
@@ -289,16 +289,22 @@ function readReplayHeader(headers) {
|
|
|
289
289
|
const v = headers.get("Idempotent-Replay");
|
|
290
290
|
return v != null && v.toLowerCase() === "true";
|
|
291
291
|
}
|
|
292
|
-
function mintUuid() {
|
|
292
|
+
function mintUuid(now = Date.now()) {
|
|
293
293
|
const c = globalThis.crypto;
|
|
294
|
-
if (c && typeof c.randomUUID === "function") return c.randomUUID();
|
|
295
294
|
const bytes = new Uint8Array(16);
|
|
296
295
|
if (c && typeof c.getRandomValues === "function") {
|
|
297
296
|
c.getRandomValues(bytes);
|
|
298
297
|
} else {
|
|
299
298
|
for (let i = 0; i < 16; i++) bytes[i] = Math.floor(Math.random() * 256);
|
|
300
299
|
}
|
|
301
|
-
|
|
300
|
+
const ms = Math.floor(now);
|
|
301
|
+
bytes[0] = Math.floor(ms / 2 ** 40) & 255;
|
|
302
|
+
bytes[1] = Math.floor(ms / 2 ** 32) & 255;
|
|
303
|
+
bytes[2] = ms >>> 24 & 255;
|
|
304
|
+
bytes[3] = ms >>> 16 & 255;
|
|
305
|
+
bytes[4] = ms >>> 8 & 255;
|
|
306
|
+
bytes[5] = ms & 255;
|
|
307
|
+
bytes[6] = bytes[6] & 15 | 112;
|
|
302
308
|
bytes[8] = bytes[8] & 63 | 128;
|
|
303
309
|
const hex = [];
|
|
304
310
|
for (let i = 0; i < 256; i++) hex.push((i + 256).toString(16).slice(1));
|
|
@@ -347,12 +353,12 @@ var ELEMENT_ICONS = {
|
|
|
347
353
|
creature: "bug_report",
|
|
348
354
|
event: "saved_search",
|
|
349
355
|
family: "supervisor_account",
|
|
350
|
-
institution: "
|
|
356
|
+
institution: "account_balance",
|
|
351
357
|
language: "edit_road",
|
|
352
358
|
law: "gpp_bad",
|
|
353
359
|
location: "castle",
|
|
354
360
|
map: "map",
|
|
355
|
-
marker: "
|
|
361
|
+
marker: "location_on",
|
|
356
362
|
narrative: "menu_book",
|
|
357
363
|
object: "webhook",
|
|
358
364
|
phenomenon: "thunderstorm",
|
|
@@ -1072,7 +1078,9 @@ function familyOf(type) {
|
|
|
1072
1078
|
return ELEMENT_FAMILIES[type];
|
|
1073
1079
|
}
|
|
1074
1080
|
function elementColor(type, mode = "dark") {
|
|
1075
|
-
|
|
1081
|
+
const family = ELEMENT_FAMILIES[type];
|
|
1082
|
+
if (family === void 0) throw new TypeError(`elementColor: unknown element type "${String(type)}"`);
|
|
1083
|
+
return FAMILY_COLORS[family][mode];
|
|
1076
1084
|
}
|
|
1077
1085
|
var FAMILY_ORDER = ["agents", "world", "abstract", "temporal"];
|
|
1078
1086
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onlyworlds/sdk",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"description": "TypeScript SDK for the OnlyWorlds API - build world-building applications with type safety",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -28,7 +28,8 @@
|
|
|
28
28
|
"codegen:check": "python codegen/generate_types.py --check",
|
|
29
29
|
"schema:verify": "python codegen/verify_dist.py",
|
|
30
30
|
"schema:check": "npm run schema:verify && npm run codegen:check",
|
|
31
|
-
"prepublishOnly": "npm run build"
|
|
31
|
+
"prepublishOnly": "npm run build",
|
|
32
|
+
"release:verify": "node codegen/verify_release.mjs"
|
|
32
33
|
},
|
|
33
34
|
"keywords": [
|
|
34
35
|
"onlyworlds",
|