@cubelife/sdk 0.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/LICENSE +21 -0
- package/README.md +80 -0
- package/dist/admin.d.ts +183 -0
- package/dist/admin.js +178 -0
- package/dist/client.d.ts +68 -0
- package/dist/client.js +161 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +9 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +4 -0
- package/package.json +38 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ivy Innovation
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# @cubelife/sdk
|
|
2
|
+
|
|
3
|
+
Node.js SDK for CubeLife. Give your AI agent a living pixel-art character.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @cubelife/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { CubeLifeClient } from '@cubelife/sdk';
|
|
15
|
+
|
|
16
|
+
const client = new CubeLifeClient({ apiKey: 'your-agent-api-key' });
|
|
17
|
+
|
|
18
|
+
// Report what your agent is doing
|
|
19
|
+
await client.report('coding', { detail: 'Building the login page', sentiment: 'positive' });
|
|
20
|
+
|
|
21
|
+
// Update progress
|
|
22
|
+
await client.report('coding', { detail: 'Building the login page', progress: 0.5 });
|
|
23
|
+
|
|
24
|
+
// Mark complete
|
|
25
|
+
await client.report('complete', { detail: 'Login page shipped' });
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## API
|
|
29
|
+
|
|
30
|
+
### `CubeLifeClient`
|
|
31
|
+
|
|
32
|
+
Agent-facing client using API key authentication.
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
const client = new CubeLifeClient({ apiKey: 'your-key' });
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Methods:**
|
|
39
|
+
|
|
40
|
+
- `report(state, options?)` - Report agent state (`coding`, `reading`, `researching`, `designing`, `testing`, `reviewing`, `thinking`, `writing`, `error`, `complete`, `waiting`, `awaiting_input`)
|
|
41
|
+
- `getState()` - Get current agent state
|
|
42
|
+
- `navigate(destination)` - Move agent to a different room
|
|
43
|
+
- `customise(options)` - Update character appearance (outfit, skin tone, accessories)
|
|
44
|
+
- `setCreature(type)` - Switch agent to a creature form
|
|
45
|
+
|
|
46
|
+
### `CubeLifeAdmin`
|
|
47
|
+
|
|
48
|
+
Management client using bearer token authentication.
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
const admin = new CubeLifeAdmin();
|
|
52
|
+
await admin.login('email', 'password');
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Methods:**
|
|
56
|
+
|
|
57
|
+
- `login(email, password)` / `register(email, password)` - Authenticate
|
|
58
|
+
- `createProject(name)` / `listProjects()` / `deleteProject(id)` - Project management
|
|
59
|
+
- `createAgent(projectId, name)` / `listAgents(projectId)` / `deleteAgent(projectId, agentId)` - Agent management
|
|
60
|
+
|
|
61
|
+
## Work States
|
|
62
|
+
|
|
63
|
+
| State | Description |
|
|
64
|
+
|-------|-------------|
|
|
65
|
+
| `coding` | Writing or editing code |
|
|
66
|
+
| `reading` | Reading documentation or code |
|
|
67
|
+
| `researching` | Investigating solutions |
|
|
68
|
+
| `designing` | Designing architecture or UI |
|
|
69
|
+
| `testing` | Running or writing tests |
|
|
70
|
+
| `reviewing` | Reviewing code or PRs |
|
|
71
|
+
| `thinking` | Processing or reasoning |
|
|
72
|
+
| `writing` | Writing docs or content |
|
|
73
|
+
| `error` | Something went wrong |
|
|
74
|
+
| `complete` | Task finished |
|
|
75
|
+
| `waiting` | Waiting for external input |
|
|
76
|
+
| `awaiting_input` | Waiting for user input |
|
|
77
|
+
|
|
78
|
+
## Licence
|
|
79
|
+
|
|
80
|
+
MIT
|
package/dist/admin.d.ts
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
interface CubeLifeAdminOptions {
|
|
2
|
+
baseUrl?: string;
|
|
3
|
+
}
|
|
4
|
+
interface AuthTokens {
|
|
5
|
+
idToken: string;
|
|
6
|
+
refreshToken: string;
|
|
7
|
+
userId: string;
|
|
8
|
+
email: string;
|
|
9
|
+
expiresIn: number;
|
|
10
|
+
}
|
|
11
|
+
interface Project {
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
product: 'life' | 'world';
|
|
15
|
+
ownerId: string;
|
|
16
|
+
createdAt: unknown;
|
|
17
|
+
}
|
|
18
|
+
interface Character {
|
|
19
|
+
seed: number;
|
|
20
|
+
skinTone: string;
|
|
21
|
+
outfit: string;
|
|
22
|
+
outfitColor: string;
|
|
23
|
+
accessories: string[];
|
|
24
|
+
}
|
|
25
|
+
interface CreatureTraits {
|
|
26
|
+
type: string;
|
|
27
|
+
color: string;
|
|
28
|
+
name?: string;
|
|
29
|
+
}
|
|
30
|
+
interface Agent {
|
|
31
|
+
id: string;
|
|
32
|
+
name: string;
|
|
33
|
+
form?: 'human' | 'creature';
|
|
34
|
+
character: Character;
|
|
35
|
+
creature?: CreatureTraits;
|
|
36
|
+
createdAt: unknown;
|
|
37
|
+
apiKey?: string;
|
|
38
|
+
personality?: Personality | null;
|
|
39
|
+
}
|
|
40
|
+
interface Personality {
|
|
41
|
+
emotions: Record<string, number>;
|
|
42
|
+
traits: string[];
|
|
43
|
+
interests: string[];
|
|
44
|
+
ambition?: string | null;
|
|
45
|
+
aptitudes?: Record<string, number>;
|
|
46
|
+
quirks?: string[];
|
|
47
|
+
opinions?: Record<string, string>;
|
|
48
|
+
}
|
|
49
|
+
interface Room {
|
|
50
|
+
id: string;
|
|
51
|
+
type: string;
|
|
52
|
+
name: string;
|
|
53
|
+
theme: string;
|
|
54
|
+
ownerId: string | null;
|
|
55
|
+
layout: unknown;
|
|
56
|
+
decoration: Record<string, unknown>;
|
|
57
|
+
presentAgents: string[];
|
|
58
|
+
maxOccupancy: number;
|
|
59
|
+
createdAt: unknown;
|
|
60
|
+
}
|
|
61
|
+
interface ChestItem {
|
|
62
|
+
id: string;
|
|
63
|
+
catalogueId: string;
|
|
64
|
+
name: string;
|
|
65
|
+
sprite: string;
|
|
66
|
+
}
|
|
67
|
+
interface Possession {
|
|
68
|
+
id: string;
|
|
69
|
+
name: string;
|
|
70
|
+
sprite: string;
|
|
71
|
+
equipped: boolean;
|
|
72
|
+
}
|
|
73
|
+
interface Neighbourhood {
|
|
74
|
+
id: string;
|
|
75
|
+
typeId: string;
|
|
76
|
+
name: string;
|
|
77
|
+
index: number;
|
|
78
|
+
roomCount: number;
|
|
79
|
+
capacity: number;
|
|
80
|
+
}
|
|
81
|
+
interface WorldRoom {
|
|
82
|
+
id: string;
|
|
83
|
+
sourceProjectId: string;
|
|
84
|
+
sourceRoomId: string;
|
|
85
|
+
neighbourhoodId: string;
|
|
86
|
+
streetNumber: number;
|
|
87
|
+
visibility: string;
|
|
88
|
+
guestList?: string[];
|
|
89
|
+
membershipCost: number | null;
|
|
90
|
+
roomName: string | null;
|
|
91
|
+
roomType: string | null;
|
|
92
|
+
createdAt: unknown;
|
|
93
|
+
}
|
|
94
|
+
export declare class CubeLifeAdmin {
|
|
95
|
+
static readonly VERSION = "0.1.0";
|
|
96
|
+
private readonly baseUrl;
|
|
97
|
+
private idToken;
|
|
98
|
+
constructor(opts?: CubeLifeAdminOptions);
|
|
99
|
+
private get headers();
|
|
100
|
+
private request;
|
|
101
|
+
register(email: string, password: string): Promise<AuthTokens>;
|
|
102
|
+
login(email: string, password: string): Promise<AuthTokens>;
|
|
103
|
+
setToken(idToken: string): void;
|
|
104
|
+
createProject(name: string): Promise<Project>;
|
|
105
|
+
listProjects(): Promise<Project[]>;
|
|
106
|
+
getProject(projectId: string): Promise<Project>;
|
|
107
|
+
updateProject(projectId: string, name: string): Promise<Project>;
|
|
108
|
+
deleteProject(projectId: string): Promise<void>;
|
|
109
|
+
createAgent(projectId: string, name: string, character?: Partial<Character>, personality?: Personality, opts?: {
|
|
110
|
+
form?: 'human' | 'creature';
|
|
111
|
+
creature?: CreatureTraits;
|
|
112
|
+
}): Promise<Agent>;
|
|
113
|
+
listAgents(projectId: string): Promise<Agent[]>;
|
|
114
|
+
getAgent(projectId: string, agentId: string): Promise<Agent>;
|
|
115
|
+
updateAgent(projectId: string, agentId: string, updates: {
|
|
116
|
+
name?: string;
|
|
117
|
+
character?: Partial<Character>;
|
|
118
|
+
form?: 'human' | 'creature';
|
|
119
|
+
creature?: Partial<CreatureTraits>;
|
|
120
|
+
}): Promise<Agent>;
|
|
121
|
+
deleteAgent(projectId: string, agentId: string): Promise<void>;
|
|
122
|
+
regenerateKey(projectId: string, agentId: string): Promise<{
|
|
123
|
+
apiKey: string;
|
|
124
|
+
}>;
|
|
125
|
+
getPersonality(projectId: string, agentId: string): Promise<Personality>;
|
|
126
|
+
setPersonality(projectId: string, agentId: string, personality: Personality): Promise<Personality>;
|
|
127
|
+
updatePersonality(projectId: string, agentId: string, updates: Partial<Personality>): Promise<Personality>;
|
|
128
|
+
createRoom(projectId: string, opts: {
|
|
129
|
+
name: string;
|
|
130
|
+
type?: string;
|
|
131
|
+
theme?: string;
|
|
132
|
+
}): Promise<Room>;
|
|
133
|
+
listRooms(projectId: string): Promise<Room[]>;
|
|
134
|
+
getRoom(projectId: string, roomId: string): Promise<Room>;
|
|
135
|
+
updateRoom(projectId: string, roomId: string, updates: {
|
|
136
|
+
name?: string;
|
|
137
|
+
decoration?: Record<string, unknown>;
|
|
138
|
+
backgroundLayers?: {
|
|
139
|
+
wall: {
|
|
140
|
+
texture: string;
|
|
141
|
+
tint: string;
|
|
142
|
+
};
|
|
143
|
+
floor: {
|
|
144
|
+
texture: string;
|
|
145
|
+
tint: string;
|
|
146
|
+
};
|
|
147
|
+
furniture: string[];
|
|
148
|
+
} | null;
|
|
149
|
+
}): Promise<Room>;
|
|
150
|
+
deleteRoom(projectId: string, roomId: string): Promise<void>;
|
|
151
|
+
addToChest(projectId: string, roomId: string, item: {
|
|
152
|
+
catalogueId: string;
|
|
153
|
+
name: string;
|
|
154
|
+
sprite: string;
|
|
155
|
+
}): Promise<ChestItem>;
|
|
156
|
+
listChest(projectId: string, roomId: string): Promise<ChestItem[]>;
|
|
157
|
+
removeFromChest(projectId: string, roomId: string, itemId: string): Promise<void>;
|
|
158
|
+
listPossessions(projectId: string, agentId: string): Promise<Possession[]>;
|
|
159
|
+
givePossession(projectId: string, agentId: string, item: {
|
|
160
|
+
name: string;
|
|
161
|
+
category: string;
|
|
162
|
+
sprite: string;
|
|
163
|
+
catalogueId?: string;
|
|
164
|
+
}): Promise<Possession>;
|
|
165
|
+
removePossession(projectId: string, agentId: string, itemId: string): Promise<void>;
|
|
166
|
+
listNeighbourhoods(): Promise<Neighbourhood[]>;
|
|
167
|
+
getNeighbourhood(neighbourhoodId: string): Promise<Neighbourhood>;
|
|
168
|
+
listWorldRooms(neighbourhoodId: string): Promise<WorldRoom[]>;
|
|
169
|
+
getWorldRoom(worldRoomId: string): Promise<WorldRoom>;
|
|
170
|
+
/** World-product only. Returns 403 for life projects. */
|
|
171
|
+
updateWorldRoom(worldRoomId: string, updates: {
|
|
172
|
+
visibility?: string;
|
|
173
|
+
guestList?: string[];
|
|
174
|
+
membershipCost?: number | null;
|
|
175
|
+
}): Promise<WorldRoom>;
|
|
176
|
+
/** World-product only. Returns 403 for life projects. */
|
|
177
|
+
registerWorldRoom(projectId: string, roomId: string, typeId?: string, roomName?: string, roomType?: string): Promise<{
|
|
178
|
+
worldRoomId: string;
|
|
179
|
+
neighbourhoodId: string;
|
|
180
|
+
streetNumber: number;
|
|
181
|
+
}>;
|
|
182
|
+
}
|
|
183
|
+
export type { CubeLifeAdminOptions, AuthTokens, Project, Agent, Character, CreatureTraits, Personality, Room, ChestItem, Possession, Neighbourhood, WorldRoom, };
|
package/dist/admin.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CubeLifeAdmin = void 0;
|
|
4
|
+
const version_1 = require("./version");
|
|
5
|
+
const client_1 = require("./client");
|
|
6
|
+
const DEFAULT_BASE_URL = 'https://cubelife-2dd2e.web.app';
|
|
7
|
+
class CubeLifeAdmin {
|
|
8
|
+
static VERSION = version_1.SDK_VERSION;
|
|
9
|
+
baseUrl;
|
|
10
|
+
idToken = null;
|
|
11
|
+
constructor(opts) {
|
|
12
|
+
this.baseUrl = opts?.baseUrl || DEFAULT_BASE_URL;
|
|
13
|
+
}
|
|
14
|
+
get headers() {
|
|
15
|
+
const h = {
|
|
16
|
+
'Content-Type': 'application/json',
|
|
17
|
+
'User-Agent': `cubelife-admin-sdk/${CubeLifeAdmin.VERSION}`,
|
|
18
|
+
};
|
|
19
|
+
if (this.idToken) {
|
|
20
|
+
h['Authorization'] = `Bearer ${this.idToken}`;
|
|
21
|
+
}
|
|
22
|
+
return h;
|
|
23
|
+
}
|
|
24
|
+
async request(method, path, body) {
|
|
25
|
+
const res = await fetch(`${this.baseUrl}/api${path}`, {
|
|
26
|
+
method,
|
|
27
|
+
headers: this.headers,
|
|
28
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
29
|
+
});
|
|
30
|
+
if (!res.ok) {
|
|
31
|
+
const err = await res.json().catch(() => ({}));
|
|
32
|
+
const message = err.error || 'Unknown error';
|
|
33
|
+
if (res.status === 429)
|
|
34
|
+
throw new client_1.RateLimitError(message);
|
|
35
|
+
throw new client_1.CubeLifeError(res.status, message);
|
|
36
|
+
}
|
|
37
|
+
return res.json();
|
|
38
|
+
}
|
|
39
|
+
// --- Auth ---
|
|
40
|
+
async register(email, password) {
|
|
41
|
+
const result = await this.request('POST', '/v1/auth/register', {
|
|
42
|
+
email,
|
|
43
|
+
password,
|
|
44
|
+
});
|
|
45
|
+
this.idToken = result.idToken;
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
async login(email, password) {
|
|
49
|
+
const result = await this.request('POST', '/v1/auth/login', {
|
|
50
|
+
email,
|
|
51
|
+
password,
|
|
52
|
+
});
|
|
53
|
+
this.idToken = result.idToken;
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
setToken(idToken) {
|
|
57
|
+
this.idToken = idToken;
|
|
58
|
+
}
|
|
59
|
+
// --- Projects ---
|
|
60
|
+
async createProject(name) {
|
|
61
|
+
return this.request('POST', '/v1/projects', { name });
|
|
62
|
+
}
|
|
63
|
+
async listProjects() {
|
|
64
|
+
const result = await this.request('GET', '/v1/projects');
|
|
65
|
+
return result.projects;
|
|
66
|
+
}
|
|
67
|
+
async getProject(projectId) {
|
|
68
|
+
return this.request('GET', `/v1/projects/${projectId}`);
|
|
69
|
+
}
|
|
70
|
+
async updateProject(projectId, name) {
|
|
71
|
+
return this.request('PATCH', `/v1/projects/${projectId}`, { name });
|
|
72
|
+
}
|
|
73
|
+
async deleteProject(projectId) {
|
|
74
|
+
await this.request('DELETE', `/v1/projects/${projectId}`);
|
|
75
|
+
}
|
|
76
|
+
// --- Agents ---
|
|
77
|
+
async createAgent(projectId, name, character, personality, opts) {
|
|
78
|
+
const body = { name };
|
|
79
|
+
if (character)
|
|
80
|
+
body.character = character;
|
|
81
|
+
if (personality)
|
|
82
|
+
body.personality = personality;
|
|
83
|
+
if (opts?.form)
|
|
84
|
+
body.form = opts.form;
|
|
85
|
+
if (opts?.creature)
|
|
86
|
+
body.creature = opts.creature;
|
|
87
|
+
return this.request('POST', `/v1/projects/${projectId}/agents`, body);
|
|
88
|
+
}
|
|
89
|
+
async listAgents(projectId) {
|
|
90
|
+
const result = await this.request('GET', `/v1/projects/${projectId}/agents`);
|
|
91
|
+
return result.agents;
|
|
92
|
+
}
|
|
93
|
+
async getAgent(projectId, agentId) {
|
|
94
|
+
return this.request('GET', `/v1/projects/${projectId}/agents/${agentId}`);
|
|
95
|
+
}
|
|
96
|
+
async updateAgent(projectId, agentId, updates) {
|
|
97
|
+
return this.request('PATCH', `/v1/projects/${projectId}/agents/${agentId}`, updates);
|
|
98
|
+
}
|
|
99
|
+
async deleteAgent(projectId, agentId) {
|
|
100
|
+
await this.request('DELETE', `/v1/projects/${projectId}/agents/${agentId}`);
|
|
101
|
+
}
|
|
102
|
+
async regenerateKey(projectId, agentId) {
|
|
103
|
+
return this.request('POST', `/v1/projects/${projectId}/agents/${agentId}/regenerate-key`);
|
|
104
|
+
}
|
|
105
|
+
// --- Personality ---
|
|
106
|
+
async getPersonality(projectId, agentId) {
|
|
107
|
+
return this.request('GET', `/v1/projects/${projectId}/agents/${agentId}/personality`);
|
|
108
|
+
}
|
|
109
|
+
async setPersonality(projectId, agentId, personality) {
|
|
110
|
+
return this.request('PUT', `/v1/projects/${projectId}/agents/${agentId}/personality`, personality);
|
|
111
|
+
}
|
|
112
|
+
async updatePersonality(projectId, agentId, updates) {
|
|
113
|
+
return this.request('PATCH', `/v1/projects/${projectId}/agents/${agentId}/personality`, updates);
|
|
114
|
+
}
|
|
115
|
+
// --- Rooms ---
|
|
116
|
+
async createRoom(projectId, opts) {
|
|
117
|
+
return this.request('POST', `/manage/v1/projects/${projectId}/rooms`, opts);
|
|
118
|
+
}
|
|
119
|
+
async listRooms(projectId) {
|
|
120
|
+
const result = await this.request('GET', `/manage/v1/projects/${projectId}/rooms`);
|
|
121
|
+
return result.rooms;
|
|
122
|
+
}
|
|
123
|
+
async getRoom(projectId, roomId) {
|
|
124
|
+
return this.request('GET', `/manage/v1/projects/${projectId}/rooms/${roomId}`);
|
|
125
|
+
}
|
|
126
|
+
async updateRoom(projectId, roomId, updates) {
|
|
127
|
+
return this.request('PATCH', `/manage/v1/projects/${projectId}/rooms/${roomId}`, updates);
|
|
128
|
+
}
|
|
129
|
+
async deleteRoom(projectId, roomId) {
|
|
130
|
+
await this.request('DELETE', `/manage/v1/projects/${projectId}/rooms/${roomId}`);
|
|
131
|
+
}
|
|
132
|
+
// --- Room Chest ---
|
|
133
|
+
async addToChest(projectId, roomId, item) {
|
|
134
|
+
return this.request('POST', `/manage/v1/projects/${projectId}/rooms/${roomId}/chest`, item);
|
|
135
|
+
}
|
|
136
|
+
async listChest(projectId, roomId) {
|
|
137
|
+
const result = await this.request('GET', `/manage/v1/projects/${projectId}/rooms/${roomId}/chest`);
|
|
138
|
+
return result.items;
|
|
139
|
+
}
|
|
140
|
+
async removeFromChest(projectId, roomId, itemId) {
|
|
141
|
+
await this.request('DELETE', `/manage/v1/projects/${projectId}/rooms/${roomId}/chest/${itemId}`);
|
|
142
|
+
}
|
|
143
|
+
// --- Possessions ---
|
|
144
|
+
async listPossessions(projectId, agentId) {
|
|
145
|
+
const result = await this.request('GET', `/manage/v1/projects/${projectId}/agents/${agentId}/possessions`);
|
|
146
|
+
return result.possessions;
|
|
147
|
+
}
|
|
148
|
+
async givePossession(projectId, agentId, item) {
|
|
149
|
+
return this.request('POST', `/manage/v1/projects/${projectId}/agents/${agentId}/possessions`, item);
|
|
150
|
+
}
|
|
151
|
+
async removePossession(projectId, agentId, itemId) {
|
|
152
|
+
await this.request('DELETE', `/manage/v1/projects/${projectId}/agents/${agentId}/possessions/${itemId}`);
|
|
153
|
+
}
|
|
154
|
+
// --- World Map (world-product only — returns 403 for life projects) ---
|
|
155
|
+
async listNeighbourhoods() {
|
|
156
|
+
const result = await this.request('GET', '/v1/world/neighbourhoods');
|
|
157
|
+
return result.neighbourhoods;
|
|
158
|
+
}
|
|
159
|
+
async getNeighbourhood(neighbourhoodId) {
|
|
160
|
+
return this.request('GET', `/v1/world/neighbourhoods/${neighbourhoodId}`);
|
|
161
|
+
}
|
|
162
|
+
async listWorldRooms(neighbourhoodId) {
|
|
163
|
+
const result = await this.request('GET', `/v1/world/neighbourhoods/${neighbourhoodId}/rooms`);
|
|
164
|
+
return result.rooms;
|
|
165
|
+
}
|
|
166
|
+
async getWorldRoom(worldRoomId) {
|
|
167
|
+
return this.request('GET', `/v1/world/rooms/${worldRoomId}`);
|
|
168
|
+
}
|
|
169
|
+
/** World-product only. Returns 403 for life projects. */
|
|
170
|
+
async updateWorldRoom(worldRoomId, updates) {
|
|
171
|
+
return this.request('PATCH', `/v1/world/rooms/${worldRoomId}`, updates);
|
|
172
|
+
}
|
|
173
|
+
/** World-product only. Returns 403 for life projects. */
|
|
174
|
+
async registerWorldRoom(projectId, roomId, typeId, roomName, roomType) {
|
|
175
|
+
return this.request('POST', '/v1/world/rooms/register', { projectId, roomId, typeId, roomName, roomType });
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
exports.CubeLifeAdmin = CubeLifeAdmin;
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
type WorkState = 'coding' | 'reading' | 'researching' | 'designing' | 'testing' | 'reviewing' | 'thinking' | 'writing' | 'error' | 'complete' | 'waiting' | 'awaiting_input';
|
|
2
|
+
type Sentiment = 'positive' | 'negative' | 'neutral';
|
|
3
|
+
type OutfitStyle = 'default_tee' | 'shirt' | 'lab_coat' | 'hoodie' | 'dress' | 'sweater' | 'overalls';
|
|
4
|
+
type AccessoryStyle = 'none' | 'glasses' | 'headphones' | 'cap' | 'beanie' | 'bandana' | 'scarf' | 'earrings';
|
|
5
|
+
interface ReportOptions {
|
|
6
|
+
detail?: string;
|
|
7
|
+
progress?: number;
|
|
8
|
+
sentiment?: Sentiment;
|
|
9
|
+
}
|
|
10
|
+
interface CharacterOptions {
|
|
11
|
+
outfit?: OutfitStyle;
|
|
12
|
+
outfitColor?: string;
|
|
13
|
+
skinTone?: string;
|
|
14
|
+
accessories?: AccessoryStyle[];
|
|
15
|
+
}
|
|
16
|
+
interface NavigationResult {
|
|
17
|
+
ok: boolean;
|
|
18
|
+
roomId: string;
|
|
19
|
+
worldRoomId: string;
|
|
20
|
+
neighbourhoodId: string;
|
|
21
|
+
distance: number;
|
|
22
|
+
zone: string;
|
|
23
|
+
}
|
|
24
|
+
interface AgentState {
|
|
25
|
+
state: WorkState;
|
|
26
|
+
detail: string | null;
|
|
27
|
+
progress: number | null;
|
|
28
|
+
sentiment: Sentiment | null;
|
|
29
|
+
updatedAt: number | null;
|
|
30
|
+
}
|
|
31
|
+
interface CubeLifeOptions {
|
|
32
|
+
apiKey: string;
|
|
33
|
+
baseUrl?: string;
|
|
34
|
+
}
|
|
35
|
+
export declare class CubeLifeError extends Error {
|
|
36
|
+
readonly status: number;
|
|
37
|
+
constructor(status: number, message: string);
|
|
38
|
+
}
|
|
39
|
+
export declare class RateLimitError extends CubeLifeError {
|
|
40
|
+
constructor(message?: string);
|
|
41
|
+
}
|
|
42
|
+
export declare class CubeLifeClient {
|
|
43
|
+
static readonly VERSION = "0.1.0";
|
|
44
|
+
private readonly apiKey;
|
|
45
|
+
private readonly baseUrl;
|
|
46
|
+
constructor(opts: CubeLifeOptions);
|
|
47
|
+
getState(): Promise<AgentState>;
|
|
48
|
+
report(state: WorkState, opts?: ReportOptions): Promise<void>;
|
|
49
|
+
coding(detail?: string, progress?: number): Promise<void>;
|
|
50
|
+
reading(detail?: string): Promise<void>;
|
|
51
|
+
researching(detail?: string): Promise<void>;
|
|
52
|
+
designing(detail?: string): Promise<void>;
|
|
53
|
+
testing(detail?: string, progress?: number): Promise<void>;
|
|
54
|
+
reviewing(detail?: string): Promise<void>;
|
|
55
|
+
thinking(detail?: string): Promise<void>;
|
|
56
|
+
writing(detail?: string): Promise<void>;
|
|
57
|
+
error(detail?: string): Promise<void>;
|
|
58
|
+
complete(detail?: string): Promise<void>;
|
|
59
|
+
waiting(detail?: string): Promise<void>;
|
|
60
|
+
awaitingInput(detail?: string): Promise<void>;
|
|
61
|
+
moveTo(roomId: string, zone?: string): Promise<void>;
|
|
62
|
+
/** World-product only. Returns 403 for life projects. */
|
|
63
|
+
navigateTo(worldRoomId: string, zone?: string): Promise<NavigationResult>;
|
|
64
|
+
updateCharacter(opts: CharacterOptions): Promise<void>;
|
|
65
|
+
}
|
|
66
|
+
type AgentForm = 'human' | 'creature';
|
|
67
|
+
type HairStyle = 'none' | 'short' | 'long' | 'curly' | 'ponytail' | 'mohawk';
|
|
68
|
+
export type { WorkState, Sentiment, ReportOptions, CubeLifeOptions, CharacterOptions, OutfitStyle, AccessoryStyle, NavigationResult, AgentState, AgentForm, HairStyle };
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CubeLifeClient = exports.RateLimitError = exports.CubeLifeError = void 0;
|
|
4
|
+
const version_1 = require("./version");
|
|
5
|
+
const DEFAULT_BASE_URL = 'https://cubelife-2dd2e.web.app';
|
|
6
|
+
class CubeLifeError extends Error {
|
|
7
|
+
status;
|
|
8
|
+
constructor(status, message) {
|
|
9
|
+
super(`CubeLife API error ${status}: ${message}`);
|
|
10
|
+
this.name = 'CubeLifeError';
|
|
11
|
+
this.status = status;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.CubeLifeError = CubeLifeError;
|
|
15
|
+
class RateLimitError extends CubeLifeError {
|
|
16
|
+
constructor(message = 'Rate limit exceeded') {
|
|
17
|
+
super(429, message);
|
|
18
|
+
this.name = 'RateLimitError';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.RateLimitError = RateLimitError;
|
|
22
|
+
function throwApiError(status, errorMessage) {
|
|
23
|
+
if (status === 429)
|
|
24
|
+
throw new RateLimitError(errorMessage);
|
|
25
|
+
throw new CubeLifeError(status, errorMessage);
|
|
26
|
+
}
|
|
27
|
+
class CubeLifeClient {
|
|
28
|
+
static VERSION = version_1.SDK_VERSION;
|
|
29
|
+
apiKey;
|
|
30
|
+
baseUrl;
|
|
31
|
+
constructor(opts) {
|
|
32
|
+
this.apiKey = opts.apiKey;
|
|
33
|
+
this.baseUrl = opts.baseUrl || DEFAULT_BASE_URL;
|
|
34
|
+
}
|
|
35
|
+
async getState() {
|
|
36
|
+
const res = await fetch(`${this.baseUrl}/api/v1/state`, {
|
|
37
|
+
method: 'GET',
|
|
38
|
+
headers: {
|
|
39
|
+
'X-Agent-Key': this.apiKey,
|
|
40
|
+
'User-Agent': `cubelife-sdk/${CubeLifeClient.VERSION}`,
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
if (!res.ok) {
|
|
44
|
+
const err = await res.json().catch(() => ({}));
|
|
45
|
+
throwApiError(res.status, err.error || 'Unknown error');
|
|
46
|
+
}
|
|
47
|
+
return res.json();
|
|
48
|
+
}
|
|
49
|
+
async report(state, opts) {
|
|
50
|
+
const body = { state };
|
|
51
|
+
if (opts?.detail)
|
|
52
|
+
body.detail = opts.detail;
|
|
53
|
+
if (opts?.progress !== undefined)
|
|
54
|
+
body.progress = opts.progress;
|
|
55
|
+
if (opts?.sentiment)
|
|
56
|
+
body.sentiment = opts.sentiment;
|
|
57
|
+
const res = await fetch(`${this.baseUrl}/api/v1/state`, {
|
|
58
|
+
method: 'POST',
|
|
59
|
+
headers: {
|
|
60
|
+
'Content-Type': 'application/json',
|
|
61
|
+
'X-Agent-Key': this.apiKey,
|
|
62
|
+
'User-Agent': `cubelife-sdk/${CubeLifeClient.VERSION}`,
|
|
63
|
+
},
|
|
64
|
+
body: JSON.stringify(body),
|
|
65
|
+
});
|
|
66
|
+
if (!res.ok) {
|
|
67
|
+
const err = await res.json().catch(() => ({}));
|
|
68
|
+
throwApiError(res.status, err.error || 'Unknown error');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async coding(detail, progress) {
|
|
72
|
+
return this.report('coding', { detail, progress });
|
|
73
|
+
}
|
|
74
|
+
async reading(detail) {
|
|
75
|
+
return this.report('reading', { detail });
|
|
76
|
+
}
|
|
77
|
+
async researching(detail) {
|
|
78
|
+
return this.report('researching', { detail });
|
|
79
|
+
}
|
|
80
|
+
async designing(detail) {
|
|
81
|
+
return this.report('designing', { detail });
|
|
82
|
+
}
|
|
83
|
+
async testing(detail, progress) {
|
|
84
|
+
return this.report('testing', { detail, progress });
|
|
85
|
+
}
|
|
86
|
+
async reviewing(detail) {
|
|
87
|
+
return this.report('reviewing', { detail });
|
|
88
|
+
}
|
|
89
|
+
async thinking(detail) {
|
|
90
|
+
return this.report('thinking', { detail });
|
|
91
|
+
}
|
|
92
|
+
async writing(detail) {
|
|
93
|
+
return this.report('writing', { detail });
|
|
94
|
+
}
|
|
95
|
+
async error(detail) {
|
|
96
|
+
return this.report('error', { detail, sentiment: 'negative' });
|
|
97
|
+
}
|
|
98
|
+
async complete(detail) {
|
|
99
|
+
return this.report('complete', { detail, sentiment: 'positive' });
|
|
100
|
+
}
|
|
101
|
+
async waiting(detail) {
|
|
102
|
+
return this.report('waiting', { detail });
|
|
103
|
+
}
|
|
104
|
+
async awaitingInput(detail) {
|
|
105
|
+
return this.report('awaiting_input', { detail });
|
|
106
|
+
}
|
|
107
|
+
async moveTo(roomId, zone) {
|
|
108
|
+
const body = { roomId };
|
|
109
|
+
if (zone)
|
|
110
|
+
body.zone = zone;
|
|
111
|
+
const res = await fetch(`${this.baseUrl}/api/v1/location`, {
|
|
112
|
+
method: 'POST',
|
|
113
|
+
headers: {
|
|
114
|
+
'Content-Type': 'application/json',
|
|
115
|
+
'X-Agent-Key': this.apiKey,
|
|
116
|
+
'User-Agent': `cubelife-sdk/${CubeLifeClient.VERSION}`,
|
|
117
|
+
},
|
|
118
|
+
body: JSON.stringify(body),
|
|
119
|
+
});
|
|
120
|
+
if (!res.ok) {
|
|
121
|
+
const err = await res.json().catch(() => ({}));
|
|
122
|
+
throwApiError(res.status, err.error || 'Unknown error');
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/** World-product only. Returns 403 for life projects. */
|
|
126
|
+
async navigateTo(worldRoomId, zone) {
|
|
127
|
+
const body = { worldRoomId };
|
|
128
|
+
if (zone)
|
|
129
|
+
body.zone = zone;
|
|
130
|
+
const res = await fetch(`${this.baseUrl}/api/v1/navigate`, {
|
|
131
|
+
method: 'POST',
|
|
132
|
+
headers: {
|
|
133
|
+
'Content-Type': 'application/json',
|
|
134
|
+
'X-Agent-Key': this.apiKey,
|
|
135
|
+
'User-Agent': `cubelife-sdk/${CubeLifeClient.VERSION}`,
|
|
136
|
+
},
|
|
137
|
+
body: JSON.stringify(body),
|
|
138
|
+
});
|
|
139
|
+
if (!res.ok) {
|
|
140
|
+
const err = await res.json().catch(() => ({}));
|
|
141
|
+
throwApiError(res.status, err.error || 'Unknown error');
|
|
142
|
+
}
|
|
143
|
+
return res.json();
|
|
144
|
+
}
|
|
145
|
+
async updateCharacter(opts) {
|
|
146
|
+
const res = await fetch(`${this.baseUrl}/api/v1/character`, {
|
|
147
|
+
method: 'PATCH',
|
|
148
|
+
headers: {
|
|
149
|
+
'Content-Type': 'application/json',
|
|
150
|
+
'X-Agent-Key': this.apiKey,
|
|
151
|
+
'User-Agent': `cubelife-sdk/${CubeLifeClient.VERSION}`,
|
|
152
|
+
},
|
|
153
|
+
body: JSON.stringify(opts),
|
|
154
|
+
});
|
|
155
|
+
if (!res.ok) {
|
|
156
|
+
const err = await res.json().catch(() => ({}));
|
|
157
|
+
throwApiError(res.status, err.error || 'Unknown error');
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
exports.CubeLifeClient = CubeLifeClient;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { CubeLifeClient, CubeLifeError, RateLimitError } from './client';
|
|
2
|
+
export type { WorkState, Sentiment, ReportOptions, CubeLifeOptions, CharacterOptions, OutfitStyle, AccessoryStyle, NavigationResult, AgentState, AgentForm, HairStyle, } from './client';
|
|
3
|
+
export { CubeLifeAdmin } from './admin';
|
|
4
|
+
export type { CubeLifeAdminOptions, AuthTokens, Project, Agent, Character, CreatureTraits, Personality, Room, ChestItem, Possession, Neighbourhood, WorldRoom, } from './admin';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CubeLifeAdmin = exports.RateLimitError = exports.CubeLifeError = exports.CubeLifeClient = void 0;
|
|
4
|
+
var client_1 = require("./client");
|
|
5
|
+
Object.defineProperty(exports, "CubeLifeClient", { enumerable: true, get: function () { return client_1.CubeLifeClient; } });
|
|
6
|
+
Object.defineProperty(exports, "CubeLifeError", { enumerable: true, get: function () { return client_1.CubeLifeError; } });
|
|
7
|
+
Object.defineProperty(exports, "RateLimitError", { enumerable: true, get: function () { return client_1.RateLimitError; } });
|
|
8
|
+
var admin_1 = require("./admin");
|
|
9
|
+
Object.defineProperty(exports, "CubeLifeAdmin", { enumerable: true, get: function () { return admin_1.CubeLifeAdmin; } });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const SDK_VERSION = "0.1.0";
|
package/dist/version.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cubelife/sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "SDK for CubeLife — give your AI agent a living pixel-art character",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"prepublishOnly": "npm run build",
|
|
13
|
+
"test": "vitest run",
|
|
14
|
+
"test:watch": "vitest",
|
|
15
|
+
"test:coverage": "vitest run --coverage",
|
|
16
|
+
"test:e2e": "vitest run --config vitest.e2e.config.ts"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"ai",
|
|
20
|
+
"agent",
|
|
21
|
+
"pixel-art",
|
|
22
|
+
"character",
|
|
23
|
+
"visualization"
|
|
24
|
+
],
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "https://github.com/AndriesJacobus/CubeWorld.git",
|
|
29
|
+
"directory": "sdk"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://life.cubeworld.co.za",
|
|
32
|
+
"bugs": "https://github.com/AndriesJacobus/CubeWorld/issues",
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
35
|
+
"typescript": "^5.7.0",
|
|
36
|
+
"vitest": "^4.0.18"
|
|
37
|
+
}
|
|
38
|
+
}
|