@onlyworlds/sdk 2.2.3 → 3.1.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 ADDED
@@ -0,0 +1,30 @@
1
+ # For AI agents using @onlyworlds/sdk
2
+
3
+ **What this package is**: the canonical typed TypeScript client for the OnlyWorlds v2 API,
4
+ plus the canonical constants (element types, icons, colour families, field schema).
5
+ OnlyWorlds is an open standard for portable world data — 22 element types, UUID-linked.
6
+
7
+ **Use the v2 surface.** `OwV2Client` + the `V2ElementType` slug union + the generated
8
+ interfaces in `types.generated.ts` (emitted from the canonical schema YAML, validated
9
+ against live data). The v1 surface (`OnlyWorldsClient`, the `ElementType` enum) is frozen
10
+ legacy — do not build new work on it.
11
+
12
+ **SDK vs MCP server — pick correctly**:
13
+ - Known, deterministic operations (CRUD, sync, bulk) → **this SDK**. Typed calls, typed
14
+ responses, far cheaper than tool-schema reasoning.
15
+ - Live exploration of a user's world from a chat/agent context → the **MCP server** at
16
+ `https://www.onlyworlds.com/mcp` (same `API-Key`/`API-Pin` headers, 11 tools).
17
+
18
+ **Wire facts that bite** (full details in README):
19
+ - Never send a `"world"` field in payloads — world identity comes from the API key (422 otherwise).
20
+ - v2 link fields use ONE name both directions (no `_ids` suffix — that is v1 dialect only).
21
+ - PATCH is destructive on sent fields; use `editLinks` (atomic add/remove) for relationships.
22
+ - World-meta changes do NOT appear in `/changes` — poll `GET /world` separately.
23
+ - Extension fields: `x_<toolname>_*` is the sanctioned namespace for tool-specific state;
24
+ unknown unprefixed fields 422.
25
+ - Colour carries the element's FAMILY (`elementColor(type, mode)`); the icon
26
+ (`ELEMENT_ICONS`) carries the TYPE. Icon + label are required alongside colour, not optional.
27
+
28
+ **Auth**: prefixed keys — `ow_w_` (read+write), `ow_r_` (read-only, no PIN — the share
29
+ primitive), `ow_a_` (account Bearer). Demo keys `0000000000`–`0000000009` are read-only
30
+ test credentials against real data.
package/CHANGELOG.md ADDED
@@ -0,0 +1,44 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@onlyworlds/sdk`. Maintained from 3.1.0 onward (Kael, Assembly);
4
+ earlier history lives in git log only.
5
+
6
+ ## [3.1.0] — 2026-07-23
7
+
8
+ ### Added
9
+ - **Canonical element colour palette** (`src/v2/palette.ts`, exported from root):
10
+ `ELEMENT_FAMILIES` (type → family), `FAMILY_COLORS` (family → `{light, dark}` hex),
11
+ `familyOf(type)`, `elementColor(type, mode)`, `FAMILY_ORDER`, type `ElementFamily`.
12
+ Four semantic families (agents / world / abstract / temporal) ruled 2026-07-22 after
13
+ CVD-validated measurement (Orrery `product/schema/element-palette-measurements.md`).
14
+ Colour carries the FAMILY; `ELEMENT_ICONS` carries the TYPE. Keyed on the v2 slug
15
+ union. First proven live in atlas and council, whose local copies become re-exports.
16
+ **`ELEMENT_FAMILIES` is GENERATED** from the `family:` key in keel's schema YAML
17
+ (keel `c69366b`, a keel presentation-wrapper key — not part of the council-governed
18
+ OnlyWorlds standard); hexes are hand-authored design constants beside it. Membership
19
+ and hex invariants test-gated (`test/palette.test.mjs`); light hexes render-proven on
20
+ the ruled OnlyWorlds light mode (ow-house-light) 2026-07-23.
21
+ - **Codegen drift guard**: `python codegen/generate_types.py --check` fails if
22
+ `types.generated.ts` doesn't match the schema YAMLs (release gate; mirrors keel's
23
+ schema CI job). Codegen also hard-fails on missing/invalid `family:` keys — the
24
+ canary for a canonical-refresh that overwrote keel's wrapper layer.
25
+ - **CI**: GitHub Action building + running the full suite against the compiled bundle.
26
+ - **AGENTS.md** shipped in the tarball — usage guide for AI agents reading the package
27
+ locally, including the SDK-vs-MCP division of labor and the wire gotchas.
28
+ - README: worked create→link→read-back round-trip, schema-verified field by field
29
+ (also fixes the old example patching `'character'` with a location's id); canonical
30
+ colour section; SDK-vs-MCP guidance.
31
+ - This CHANGELOG.
32
+
33
+ ### Fixed
34
+ - `FieldType` union now includes `'number'` — the legacy alias that 70 `FIELD_SCHEMA`
35
+ entries actually carry (consumers switch on it; data normalization deferred to 4.0).
36
+ - `generate_types.py` exits with a clear message when the sibling keel checkout is
37
+ absent instead of a bare traceback.
38
+
39
+ ## [3.0.0] — 2026-07-18
40
+
41
+ - v2-native client (`OwV2Client`) absorbed from Assembly's ow-v2-client v0.9.0 (Kael),
42
+ wire-corrected against live staging fixtures (S22). Generated element types from the
43
+ canonical keel schema YAML (`src/v2/types.generated.ts`), validated against all 1,086
44
+ live W11 elements. v1 surface unchanged and frozen.
package/README.md CHANGED
@@ -5,22 +5,100 @@
5
5
 
6
6
  A type-safe TypeScript SDK for building world-building applications with the OnlyWorlds API.
7
7
 
8
+ The SDK speaks two dialects of the same API:
9
+
10
+ - **v2 (`OwV2Client`)** -- the current, recommended default. Local-first shape: one-shape read/write (no `_ids` suffix), an opaque `/changes` sync feed, atomic bulk writes, and client-side UUID minting for safe retries. Base URL `https://www.onlyworlds.com/api/v2`.
11
+ - **v1 (`OnlyWorldsClient`)** -- the original resource-style client. Fully served forever; kept below as the legacy section. Existing 2.x code keeps working unchanged -- v2 is purely additive.
12
+
8
13
  ## Installation
9
14
 
10
15
  ```bash
11
16
  npm install @onlyworlds/sdk
12
17
  ```
13
18
 
14
- ## Quick Start
19
+ ## Quick Start (v2 -- recommended)
20
+
21
+ ```typescript
22
+ import { OwV2Client } from '@onlyworlds/sdk';
23
+
24
+ const client = new OwV2Client({
25
+ apiKey: 'ow_w_your_world_key', // ow_w_ write / ow_r_ read / ow_a_ account / 10-digit legacy
26
+ apiPin: '1234', // needed for writes on a PIN-protected world
27
+ });
28
+ // baseUrl defaults to https://www.onlyworlds.com/api/v2
29
+
30
+ // Read a page, or walk every page of a type
31
+ const page = await client.list('character'); // { data, has_more, next_cursor }
32
+ for await (const character of client.listAll('character')) {
33
+ // ...
34
+ }
35
+
36
+ // A worked round-trip: two elements, linked, read back. Byte-true v2 dialect:
37
+ // link fields use ONE bare name both directions (no _ids suffix — that's v1),
38
+ // and you NEVER send a "world" field (identity comes from the key; sending it 422s).
39
+ const location = await client.create('location', {
40
+ name: 'Dragon Peak',
41
+ description: 'A treacherous mountain peak where dragons nest',
42
+ }); // id minted client-side when omitted (retries stay idempotent)
43
+
44
+ const dragon = await client.create('creature', {
45
+ name: 'Vorrath the Ember-Scaled',
46
+ location: location.id, // single link: UUID (or null)
47
+ });
48
+
49
+ const fetched = await client.get('creature', dragon.id);
50
+ // fetched.location === location.id — reads the way it writes
51
+
52
+ // Partial update (PATCH is destructive on sent fields; arrays replace wholesale)
53
+ await client.patch('location', location.id, { supertype: 'Mountain' });
54
+
55
+ // For relationships, prefer the atomic link merge -- returns the full updated element
56
+ const fireBreath = await client.create('ability', { name: 'Ember Breath' });
57
+ await client.editLinks('creature', dragon.id, 'abilities', { add: [fireBreath.id], remove: [] });
58
+
59
+ // Bulk write (up to ~1000; partial success by default, atomic:true for all-or-nothing)
60
+ const res = await client.bulk([
61
+ { type: 'character', element: { name: 'A' } },
62
+ { type: 'event', element: { name: 'B' } },
63
+ ]);
64
+ // res.items[i].status is the per-slot HTTP status; res.errors flags any failure
65
+
66
+ // Sync: walk the opaque change feed and persist the final cursor
67
+ let cursor;
68
+ for await (const change of client.changesAll(cursor)) {
69
+ // apply change in order
70
+ }
71
+ ```
72
+
73
+ ### Canonical element colours
74
+
75
+ ```typescript
76
+ import { elementColor, ELEMENT_FAMILIES, FAMILY_COLORS } from '@onlyworlds/sdk';
77
+
78
+ elementColor('character', 'dark'); // '#3987e5' — colour carries the FAMILY
79
+ // (agents / world / abstract / temporal); ELEMENT_ICONS carries the TYPE.
80
+ // CVD-validated: always pair colour with icon + label, never colour alone.
81
+ ```
82
+
83
+ ### AI-assistant access (MCP) — and when to use which
84
+
85
+ An MCP server exists at `https://www.onlyworlds.com/mcp` for AI assistants (Claude and other MCP clients) to read and write worlds directly -- no SDK code required. See the [docs](https://onlyworlds.github.io) for setup.
86
+
87
+ Division of labor: for **known, deterministic operations** (CRUD, sync, bulk) use this SDK — typed calls, no tool-schema overhead. For **live exploration of a user's world from a chat/agent context**, use the MCP server. Agents: see `AGENTS.md` in this package.
88
+
89
+ ## Legacy: v1 client (`OnlyWorldsClient`)
90
+
91
+ The v1 resource-style client remains fully supported and served forever. Prefer `OwV2Client` for new code.
15
92
 
16
93
  ```typescript
17
94
  import { OnlyWorldsClient } from '@onlyworlds/sdk';
18
95
 
19
96
  const client = new OnlyWorldsClient({
20
97
  apiKey: 'your-api-key',
21
- apiPin: '1234',
22
- baseUrl: 'https://onlyworlds.com'
98
+ apiPin: '1234'
23
99
  });
100
+ // baseUrl defaults to https://www.onlyworlds.com/api/worldapi — only override it
101
+ // when pointing at a different host (it must include the full API path)
24
102
 
25
103
  // Get your world (API keys are world-scoped)
26
104
  const world = await client.worlds.get();