@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 +30 -0
- package/CHANGELOG.md +44 -0
- package/README.md +81 -3
- package/dist/index.d.mts +624 -228
- package/dist/index.d.ts +624 -228
- package/dist/index.js +386 -2
- package/dist/index.mjs +369 -1
- package/package.json +8 -2
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();
|