@tavora/sdk 0.0.0-stage → 0.2.2
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/CHANGELOG.md +30 -0
- package/LICENSE +21 -0
- package/README.md +68 -3
- package/dist/index.d.ts +173 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +267 -0
- package/dist/index.js.map +1 -0
- package/dist/protocol.d.ts +640 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +123 -0
- package/dist/protocol.js.map +1 -0
- package/package.json +43 -3
- package/src/index.ts +491 -0
- package/src/protocol.ts +539 -0
|
@@ -0,0 +1,640 @@
|
|
|
1
|
+
/** Major protocol version. Every message carries it as `v`. */
|
|
2
|
+
export declare const PROTOCOL_VERSION = 1;
|
|
3
|
+
/** Posted by the SDK on its own window to ask the host for a bridge port. */
|
|
4
|
+
export declare const HELLO_MESSAGE = "tavora:hello";
|
|
5
|
+
/** Posted by the host preload on the module window, carrying the port. */
|
|
6
|
+
export declare const PORT_MESSAGE = "tavora:port";
|
|
7
|
+
export interface TavoraGame {
|
|
8
|
+
id: string;
|
|
9
|
+
displayName: string;
|
|
10
|
+
}
|
|
11
|
+
export interface TavoraViewport {
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
}
|
|
15
|
+
export interface TavoraTheme {
|
|
16
|
+
mode: "dark" | "light";
|
|
17
|
+
/** A short summary of the palette, for modules that only need a few colours. */
|
|
18
|
+
colors: {
|
|
19
|
+
background: string;
|
|
20
|
+
surface: string;
|
|
21
|
+
text: string;
|
|
22
|
+
textMuted: string;
|
|
23
|
+
accent: string;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* The full semantic palette as CSS colours, named like the CSS variables
|
|
27
|
+
* of shadcn-vue plus Tavora's extras (see THEME_TOKENS). Set each one as
|
|
28
|
+
* `--<name>` to match the host UI.
|
|
29
|
+
*/
|
|
30
|
+
tokens: Record<ThemeToken, string>;
|
|
31
|
+
/** Corner radius for buttons, inputs and cards, in CSS pixels. */
|
|
32
|
+
radius: number;
|
|
33
|
+
}
|
|
34
|
+
/** Names of the semantic colour tokens in TavoraTheme.tokens. */
|
|
35
|
+
export declare const THEME_TOKENS: readonly ["background", "foreground", "card", "card-foreground", "popover", "popover-foreground", "primary", "primary-hover", "primary-foreground", "secondary", "secondary-foreground", "muted", "muted-foreground", "accent", "accent-foreground", "destructive", "border", "input", "ring", "rail", "success", "warning", "info"];
|
|
36
|
+
export type ThemeToken = (typeof THEME_TOKENS)[number];
|
|
37
|
+
export type JsonValue = null | boolean | number | string | JsonValue[] | {
|
|
38
|
+
[key: string]: JsonValue;
|
|
39
|
+
};
|
|
40
|
+
export interface HandshakeResult {
|
|
41
|
+
protocol: typeof PROTOCOL_VERSION;
|
|
42
|
+
host: {
|
|
43
|
+
name: "tavora-desktop";
|
|
44
|
+
version: string;
|
|
45
|
+
};
|
|
46
|
+
module: {
|
|
47
|
+
id: string;
|
|
48
|
+
version: string;
|
|
49
|
+
};
|
|
50
|
+
/** Capabilities this module has been granted. */
|
|
51
|
+
capabilities: Capability[];
|
|
52
|
+
/**
|
|
53
|
+
* The panel this page runs in: its panel type, one of the manifest's `panels` ids, or null for a module
|
|
54
|
+
* without panel types. Tavora 0.17.12 and newer send it.
|
|
55
|
+
*/
|
|
56
|
+
panel?: {
|
|
57
|
+
type: string | null;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export interface DocumentSummary {
|
|
61
|
+
id: string;
|
|
62
|
+
title: string;
|
|
63
|
+
revision: number;
|
|
64
|
+
updatedAt: string;
|
|
65
|
+
bytes: number;
|
|
66
|
+
}
|
|
67
|
+
export interface TavoraDocument extends DocumentSummary {
|
|
68
|
+
data: JsonValue;
|
|
69
|
+
}
|
|
70
|
+
export interface PutDocumentParams {
|
|
71
|
+
/** Omit to create a new document with a host-generated id. */
|
|
72
|
+
id?: string;
|
|
73
|
+
title: string;
|
|
74
|
+
data: JsonValue;
|
|
75
|
+
/** Reject with CONFLICT unless the stored revision still matches. */
|
|
76
|
+
ifRevision?: number;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* A web request the host makes for the module (network.fetch). Only to a host the module names in
|
|
80
|
+
* `permissions.network` and the player granted, only over HTTPS; the host sends no cookies and
|
|
81
|
+
* follows redirects only to granted hosts.
|
|
82
|
+
*/
|
|
83
|
+
export interface NetworkRequest {
|
|
84
|
+
url: string;
|
|
85
|
+
/** Default GET. */
|
|
86
|
+
method?: "GET" | "HEAD" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
87
|
+
/** Cookie, Host, Origin, Referer, Proxy-*, Sec-* and the transfer headers are set by the host and refused here. */
|
|
88
|
+
headers?: Record<string, string>;
|
|
89
|
+
/** Text only; send binary data as base64 or JSON. */
|
|
90
|
+
body?: string;
|
|
91
|
+
/** "base64" for pictures and other binary answers. Default "text" (read as UTF-8). */
|
|
92
|
+
responseType?: "text" | "base64";
|
|
93
|
+
}
|
|
94
|
+
export interface NetworkResponse {
|
|
95
|
+
status: number;
|
|
96
|
+
/** The address that answered, after any redirects. */
|
|
97
|
+
url: string;
|
|
98
|
+
/** Lowercase names; Set-Cookie is left out. */
|
|
99
|
+
headers: Record<string, string>;
|
|
100
|
+
/** The answer as text, or base64 when the request asked for it. */
|
|
101
|
+
body: string;
|
|
102
|
+
}
|
|
103
|
+
/** An AI account the player set up in Settings > Integrations > AI usage, as the ai-usage connector shows it. */
|
|
104
|
+
export interface AiUsageAccountInfo {
|
|
105
|
+
/** Chosen by Tavora; stays the same while the account exists. */
|
|
106
|
+
id: string;
|
|
107
|
+
provider: "claude" | "codex";
|
|
108
|
+
/** The player's name for it. */
|
|
109
|
+
label: string;
|
|
110
|
+
/** The subscription plan from the profile's saved login, from a fixed list of names (Pro, Max 5×, Plus, ...), or null. */
|
|
111
|
+
plan: string | null;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* One reading of an account's usage through the ai-usage connector. Tavora reads the login itself
|
|
115
|
+
* and hands over only the provider's answer, never the token. An account is read at most once a
|
|
116
|
+
* minute (LIMITS.aiUsageMinReadMs); asking sooner gives the last reading again.
|
|
117
|
+
*/
|
|
118
|
+
export interface AiUsageReading {
|
|
119
|
+
/**
|
|
120
|
+
* ok: `answer` holds the provider's answer. sign-in: the profile has no usable subscription login.
|
|
121
|
+
* rate-limited: the provider asked to wait (`retryAfterMs`). api-key: the login is an API key,
|
|
122
|
+
* which has no subscription allowance. cli-missing: the Codex command line is not installed.
|
|
123
|
+
* unavailable: anything else.
|
|
124
|
+
*/
|
|
125
|
+
status: "ok" | "sign-in" | "rate-limited" | "api-key" | "cli-missing" | "unavailable";
|
|
126
|
+
/** For rate-limited: how long to wait at least, in milliseconds; otherwise null. */
|
|
127
|
+
retryAfterMs: number | null;
|
|
128
|
+
/**
|
|
129
|
+
* The provider's answer as it came, for status ok: Claude's usage answer (undocumented, may change)
|
|
130
|
+
* or the Codex app-server's `account/rateLimits/read` result. Null otherwise.
|
|
131
|
+
*/
|
|
132
|
+
answer: JsonValue | null;
|
|
133
|
+
/** The signed-in email the provider reports, or null. */
|
|
134
|
+
email: string | null;
|
|
135
|
+
plan: string | null;
|
|
136
|
+
/** When Tavora took this reading (ISO 8601). */
|
|
137
|
+
readAt: string;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* The discord connector's connection to the Discord app on this PC, with Tavora's Discord sign-in.
|
|
141
|
+
* The connection runs while a panel of a module granted the connector has asked for it.
|
|
142
|
+
*/
|
|
143
|
+
export interface DiscordState {
|
|
144
|
+
/**
|
|
145
|
+
* connecting: looking for the Discord app and signing in. not-running: no Discord app was found;
|
|
146
|
+
* Tavora keeps looking. signed-out: Tavora was never approved in Discord, or the player signed out;
|
|
147
|
+
* connect() asks. approving: Discord shows its approval pop-up. connected: commands and events work.
|
|
148
|
+
* error: the last sign-in failed (see `error`); connect() tries again.
|
|
149
|
+
*/
|
|
150
|
+
status: "connecting" | "not-running" | "signed-out" | "approving" | "connected" | "error";
|
|
151
|
+
/**
|
|
152
|
+
* For error: not-approved (the player declined in Discord), no-code (Discord gave no sign-in code),
|
|
153
|
+
* offline (discord.com could not be reached), no-sign-in (discord.com refused the sign-in), failed.
|
|
154
|
+
*/
|
|
155
|
+
error: "not-approved" | "no-code" | "offline" | "no-sign-in" | "failed" | null;
|
|
156
|
+
/** Who Tavora is signed in to Discord as, once connected. Names come from Discord; show them as text only. */
|
|
157
|
+
user: {
|
|
158
|
+
id: string;
|
|
159
|
+
name: string;
|
|
160
|
+
} | null;
|
|
161
|
+
/** The sign-in may mute and deafen the player (SET_VOICE_SETTINGS). Sign-ins made before Tavora 0.5.11 can't until allowControl(). */
|
|
162
|
+
canControl: boolean;
|
|
163
|
+
/** False where this PC can't keep the sign-in safely, so it lasts only until Tavora closes. */
|
|
164
|
+
canSaveSignIn: boolean;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* The Discord RPC commands a module may send through the discord connector, and their arguments.
|
|
168
|
+
* Tavora checks every argument and sends exactly these fields; Discord's answer comes back as it came.
|
|
169
|
+
*/
|
|
170
|
+
export interface DiscordCommands {
|
|
171
|
+
/** The voice channel the player is in, with its `voice_states`, or null. */
|
|
172
|
+
GET_SELECTED_VOICE_CHANNEL: Record<string, never>;
|
|
173
|
+
/** The servers the player is on. */
|
|
174
|
+
GET_GUILDS: Record<string, never>;
|
|
175
|
+
GET_GUILD: {
|
|
176
|
+
guild_id: string;
|
|
177
|
+
};
|
|
178
|
+
/** A server's channels (ids, names and types; voice channels are type 2, stage channels 13). */
|
|
179
|
+
GET_CHANNELS: {
|
|
180
|
+
guild_id: string;
|
|
181
|
+
};
|
|
182
|
+
/** One channel, with who is in it when it is a voice channel. */
|
|
183
|
+
GET_CHANNEL: {
|
|
184
|
+
channel_id: string;
|
|
185
|
+
};
|
|
186
|
+
/** Joins a voice channel (an id) or leaves (null). Only right after a click or key press in the panel, one per click. */
|
|
187
|
+
SELECT_VOICE_CHANNEL: {
|
|
188
|
+
channel_id: string | null;
|
|
189
|
+
};
|
|
190
|
+
/** Mutes or deafens the player. Needs DiscordState.canControl. */
|
|
191
|
+
SET_VOICE_SETTINGS: {
|
|
192
|
+
mute?: boolean;
|
|
193
|
+
deaf?: boolean;
|
|
194
|
+
};
|
|
195
|
+
/** How loud someone is for the player (0 to 200) and/or muted for the player only: Discord's own per-person settings. */
|
|
196
|
+
SET_USER_VOICE_SETTINGS: {
|
|
197
|
+
user_id: string;
|
|
198
|
+
volume?: number;
|
|
199
|
+
mute?: boolean;
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
export type DiscordCommand = keyof DiscordCommands;
|
|
203
|
+
export declare const DISCORD_COMMANDS: readonly ["GET_SELECTED_VOICE_CHANNEL", "GET_GUILDS", "GET_GUILD", "GET_CHANNELS", "GET_CHANNEL", "SELECT_VOICE_CHANNEL", "SET_VOICE_SETTINGS", "SET_USER_VOICE_SETTINGS"];
|
|
204
|
+
/**
|
|
205
|
+
* Discord's answer to a command. not-connected: the connection is not `connected` right now.
|
|
206
|
+
* refused: Discord answered with an error (`code` and `message` are Discord's). no-answer: Discord
|
|
207
|
+
* did not answer in time, the connection ended, or the answer was too large (LIMITS.maxDiscordAnswerBytes).
|
|
208
|
+
*/
|
|
209
|
+
export type DiscordResult = {
|
|
210
|
+
ok: true;
|
|
211
|
+
data: JsonValue;
|
|
212
|
+
} | {
|
|
213
|
+
ok: false;
|
|
214
|
+
reason: "not-connected" | "refused" | "no-answer";
|
|
215
|
+
code: number | null;
|
|
216
|
+
message: string | null;
|
|
217
|
+
};
|
|
218
|
+
/**
|
|
219
|
+
* Discord RPC events a module may subscribe to. VOICE_CHANNEL_SELECT (the player joined, moved or left)
|
|
220
|
+
* takes no channel; the others are for one voice channel and need its id.
|
|
221
|
+
*/
|
|
222
|
+
export declare const DISCORD_EVENTS: readonly ["VOICE_CHANNEL_SELECT", "VOICE_STATE_CREATE", "VOICE_STATE_UPDATE", "VOICE_STATE_DELETE", "SPEAKING_START", "SPEAKING_STOP"];
|
|
223
|
+
export type DiscordEventName = (typeof DISCORD_EVENTS)[number];
|
|
224
|
+
/** One Discord event, with its data as Discord sent it. */
|
|
225
|
+
export interface DiscordEvent {
|
|
226
|
+
event: DiscordEventName;
|
|
227
|
+
data: JsonValue;
|
|
228
|
+
}
|
|
229
|
+
export interface DocumentChange {
|
|
230
|
+
id: string;
|
|
231
|
+
revision: number;
|
|
232
|
+
deleted: boolean;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Capabilities gate methods beyond the always-available core. A module has a
|
|
236
|
+
* capability once the player granted one of its permissions for it (`network`:
|
|
237
|
+
* a host in `permissions.network`; `aiUsage`: the `ai-usage` connector; `discord`:
|
|
238
|
+
* the `discord` connector); calling a gated method without it fails with
|
|
239
|
+
* PERMISSION_DENIED. The others cannot be granted yet.
|
|
240
|
+
*/
|
|
241
|
+
export type Capability = "network" | "aiUsage" | "discord" | "files" | "clipboard" | "sharedData";
|
|
242
|
+
/** Request methods and their params/result types. */
|
|
243
|
+
export interface Methods {
|
|
244
|
+
"bridge.handshake": {
|
|
245
|
+
params: {
|
|
246
|
+
protocol: number;
|
|
247
|
+
sdkVersion: string;
|
|
248
|
+
};
|
|
249
|
+
result: HandshakeResult;
|
|
250
|
+
};
|
|
251
|
+
"game.getCurrent": {
|
|
252
|
+
params: undefined;
|
|
253
|
+
result: TavoraGame;
|
|
254
|
+
};
|
|
255
|
+
"storage.get": {
|
|
256
|
+
params: {
|
|
257
|
+
key: string;
|
|
258
|
+
};
|
|
259
|
+
result: JsonValue | null;
|
|
260
|
+
};
|
|
261
|
+
"storage.set": {
|
|
262
|
+
params: {
|
|
263
|
+
key: string;
|
|
264
|
+
value: JsonValue;
|
|
265
|
+
};
|
|
266
|
+
result: null;
|
|
267
|
+
};
|
|
268
|
+
"storage.delete": {
|
|
269
|
+
params: {
|
|
270
|
+
key: string;
|
|
271
|
+
};
|
|
272
|
+
result: null;
|
|
273
|
+
};
|
|
274
|
+
"storage.keys": {
|
|
275
|
+
params: undefined;
|
|
276
|
+
result: string[];
|
|
277
|
+
};
|
|
278
|
+
/** The same calls for settings shared by every game: this module's own, in all games. */
|
|
279
|
+
"storage.app.get": {
|
|
280
|
+
params: {
|
|
281
|
+
key: string;
|
|
282
|
+
};
|
|
283
|
+
result: JsonValue | null;
|
|
284
|
+
};
|
|
285
|
+
"storage.app.set": {
|
|
286
|
+
params: {
|
|
287
|
+
key: string;
|
|
288
|
+
value: JsonValue;
|
|
289
|
+
};
|
|
290
|
+
result: null;
|
|
291
|
+
};
|
|
292
|
+
"storage.app.delete": {
|
|
293
|
+
params: {
|
|
294
|
+
key: string;
|
|
295
|
+
};
|
|
296
|
+
result: null;
|
|
297
|
+
};
|
|
298
|
+
"storage.app.keys": {
|
|
299
|
+
params: undefined;
|
|
300
|
+
result: string[];
|
|
301
|
+
};
|
|
302
|
+
"documents.list": {
|
|
303
|
+
params: undefined;
|
|
304
|
+
result: DocumentSummary[];
|
|
305
|
+
};
|
|
306
|
+
"documents.get": {
|
|
307
|
+
params: {
|
|
308
|
+
id: string;
|
|
309
|
+
};
|
|
310
|
+
result: TavoraDocument | null;
|
|
311
|
+
};
|
|
312
|
+
"documents.put": {
|
|
313
|
+
params: PutDocumentParams;
|
|
314
|
+
result: DocumentSummary;
|
|
315
|
+
};
|
|
316
|
+
"documents.delete": {
|
|
317
|
+
params: {
|
|
318
|
+
id: string;
|
|
319
|
+
ifRevision?: number;
|
|
320
|
+
};
|
|
321
|
+
result: null;
|
|
322
|
+
};
|
|
323
|
+
"panel.getState": {
|
|
324
|
+
params: undefined;
|
|
325
|
+
result: JsonValue | null;
|
|
326
|
+
};
|
|
327
|
+
"panel.setState": {
|
|
328
|
+
params: {
|
|
329
|
+
value: JsonValue | null;
|
|
330
|
+
};
|
|
331
|
+
result: null;
|
|
332
|
+
};
|
|
333
|
+
"workspace.getViewport": {
|
|
334
|
+
params: undefined;
|
|
335
|
+
result: TavoraViewport;
|
|
336
|
+
};
|
|
337
|
+
"ui.getTheme": {
|
|
338
|
+
params: undefined;
|
|
339
|
+
result: TavoraTheme;
|
|
340
|
+
};
|
|
341
|
+
/** The language of Tavora's own texts, as a code such as "en" or "de". */
|
|
342
|
+
"ui.getLanguage": {
|
|
343
|
+
params: undefined;
|
|
344
|
+
result: string;
|
|
345
|
+
};
|
|
346
|
+
/** Shows a menu drawn by Tavora above every panel. Only right after a click, right-click or key press in the panel. The chosen item's id, or null. */
|
|
347
|
+
"ui.showMenu": {
|
|
348
|
+
params: MenuRequest;
|
|
349
|
+
result: string | null;
|
|
350
|
+
};
|
|
351
|
+
/** Opens a web address in the game's Browser panel. Only right after a click or key press in the panel; http and https only. */
|
|
352
|
+
"links.open": {
|
|
353
|
+
params: {
|
|
354
|
+
url: string;
|
|
355
|
+
};
|
|
356
|
+
result: null;
|
|
357
|
+
};
|
|
358
|
+
"blobs.list": {
|
|
359
|
+
params: undefined;
|
|
360
|
+
result: BlobInfo[];
|
|
361
|
+
};
|
|
362
|
+
"blobs.usage": {
|
|
363
|
+
params: undefined;
|
|
364
|
+
result: BlobUsage;
|
|
365
|
+
};
|
|
366
|
+
"blobs.delete": {
|
|
367
|
+
params: {
|
|
368
|
+
id: string;
|
|
369
|
+
};
|
|
370
|
+
result: null;
|
|
371
|
+
};
|
|
372
|
+
/** A web request to a granted host (capability `network`). */
|
|
373
|
+
"network.fetch": {
|
|
374
|
+
params: NetworkRequest;
|
|
375
|
+
result: NetworkResponse;
|
|
376
|
+
};
|
|
377
|
+
/** The AI accounts the player set up, in their order (capability `aiUsage`). */
|
|
378
|
+
"aiUsage.accounts": {
|
|
379
|
+
params: undefined;
|
|
380
|
+
result: AiUsageAccountInfo[];
|
|
381
|
+
};
|
|
382
|
+
/** Reads one account's usage (capability `aiUsage`). */
|
|
383
|
+
"aiUsage.read": {
|
|
384
|
+
params: {
|
|
385
|
+
accountId: string;
|
|
386
|
+
};
|
|
387
|
+
result: AiUsageReading;
|
|
388
|
+
};
|
|
389
|
+
/** The connection to the Discord app; starts it for this panel (capability `discord`). */
|
|
390
|
+
"discord.state": {
|
|
391
|
+
params: undefined;
|
|
392
|
+
result: DiscordState;
|
|
393
|
+
};
|
|
394
|
+
/** Signs in, asking for approval in Discord when needed. Only right after a click or key press (capability `discord`). */
|
|
395
|
+
"discord.connect": {
|
|
396
|
+
params: undefined;
|
|
397
|
+
result: null;
|
|
398
|
+
};
|
|
399
|
+
/** Asks Discord to approve muting and deafening for an older sign-in. Only right after a click or key press (capability `discord`). */
|
|
400
|
+
"discord.allowControl": {
|
|
401
|
+
params: undefined;
|
|
402
|
+
result: null;
|
|
403
|
+
};
|
|
404
|
+
/** One Discord RPC command from DISCORD_COMMANDS (capability `discord`). */
|
|
405
|
+
"discord.command": {
|
|
406
|
+
params: {
|
|
407
|
+
command: DiscordCommand;
|
|
408
|
+
args: DiscordCommands[DiscordCommand];
|
|
409
|
+
};
|
|
410
|
+
result: DiscordResult;
|
|
411
|
+
};
|
|
412
|
+
/** Starts sending one Discord event to this panel; kept across reconnects until unsubscribed (capability `discord`). */
|
|
413
|
+
"discord.subscribe": {
|
|
414
|
+
params: {
|
|
415
|
+
event: DiscordEventName;
|
|
416
|
+
channelId?: string;
|
|
417
|
+
};
|
|
418
|
+
result: null;
|
|
419
|
+
};
|
|
420
|
+
"discord.unsubscribe": {
|
|
421
|
+
params: {
|
|
422
|
+
event: DiscordEventName;
|
|
423
|
+
channelId?: string;
|
|
424
|
+
};
|
|
425
|
+
result: null;
|
|
426
|
+
};
|
|
427
|
+
/** A picture from Discord's image server (someone's avatar, a server icon) as a small PNG data address, or null (capability `discord`). */
|
|
428
|
+
"discord.image": {
|
|
429
|
+
params: {
|
|
430
|
+
url: string;
|
|
431
|
+
};
|
|
432
|
+
result: string | null;
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
export type MethodName = keyof Methods;
|
|
436
|
+
/** Methods reserved for later milestones, and the capability each needs. */
|
|
437
|
+
export declare const RESERVED_METHODS: Readonly<Record<string, Capability>>;
|
|
438
|
+
/** Events the host pushes to the module. */
|
|
439
|
+
export interface Events {
|
|
440
|
+
"workspace.resize": TavoraViewport;
|
|
441
|
+
"ui.theme": TavoraTheme;
|
|
442
|
+
"ui.language": string;
|
|
443
|
+
"documents.changed": DocumentChange;
|
|
444
|
+
/** The player added, renamed or removed an AI account; ask aiUsage.accounts again. Only with capability `aiUsage`. */
|
|
445
|
+
"aiUsage.accountsChanged": null;
|
|
446
|
+
/** The connection to the Discord app changed. Only with capability `discord`, after discord.state. */
|
|
447
|
+
"discord.state": DiscordState;
|
|
448
|
+
/** A Discord event this panel subscribed to. Only with capability `discord`. */
|
|
449
|
+
"discord.event": DiscordEvent;
|
|
450
|
+
"lifecycle.suspend": null;
|
|
451
|
+
"lifecycle.resume": null;
|
|
452
|
+
"lifecycle.dispose": null;
|
|
453
|
+
}
|
|
454
|
+
export type EventName = keyof Events;
|
|
455
|
+
export type ErrorCode =
|
|
456
|
+
/** Malformed message, wrong protocol version or over a limit. */
|
|
457
|
+
"BAD_REQUEST"
|
|
458
|
+
/** The method is not part of the protocol. */
|
|
459
|
+
| "UNKNOWN_METHOD"
|
|
460
|
+
/** Params are missing or have the wrong shape. */
|
|
461
|
+
| "INVALID_PARAMS"
|
|
462
|
+
/** The method exists but this module has not been granted its capability. */
|
|
463
|
+
| "PERMISSION_DENIED"
|
|
464
|
+
/** A storage, document or panel-state limit would be exceeded, or a network answer was too large. */
|
|
465
|
+
| "QUOTA_EXCEEDED"
|
|
466
|
+
/** network.fetch got no answer: the host could not be found or reached, the connection failed or it took too long. An answer with an error status (404, 500) is not this; it is returned. */
|
|
467
|
+
| "NETWORK_ERROR"
|
|
468
|
+
/** `ifRevision` did not match the stored revision. */
|
|
469
|
+
| "CONFLICT"
|
|
470
|
+
/** The SDK and host speak different protocol versions. */
|
|
471
|
+
| "INCOMPATIBLE"
|
|
472
|
+
/** Something failed inside the host. Details are logged there, not sent. */
|
|
473
|
+
| "INTERNAL"
|
|
474
|
+
/** The host did not answer in time. */
|
|
475
|
+
| "TIMEOUT"
|
|
476
|
+
/** connect() found no Tavora host, e.g. the page was opened in a normal browser. */
|
|
477
|
+
| "HOST_UNAVAILABLE";
|
|
478
|
+
export interface ErrorPayload {
|
|
479
|
+
code: ErrorCode;
|
|
480
|
+
message: string;
|
|
481
|
+
/** Present for PERMISSION_DENIED. */
|
|
482
|
+
capability?: Capability;
|
|
483
|
+
/** Present for CONFLICT. */
|
|
484
|
+
revision?: number;
|
|
485
|
+
/** Present for INCOMPATIBLE and BAD_REQUEST version errors. */
|
|
486
|
+
supported?: number[];
|
|
487
|
+
}
|
|
488
|
+
export interface RequestMessage {
|
|
489
|
+
v: typeof PROTOCOL_VERSION;
|
|
490
|
+
id: number;
|
|
491
|
+
method: string;
|
|
492
|
+
params?: unknown;
|
|
493
|
+
}
|
|
494
|
+
export type ResponseMessage = {
|
|
495
|
+
v: typeof PROTOCOL_VERSION;
|
|
496
|
+
id: number;
|
|
497
|
+
ok: true;
|
|
498
|
+
result: unknown;
|
|
499
|
+
} | {
|
|
500
|
+
v: typeof PROTOCOL_VERSION;
|
|
501
|
+
id: number;
|
|
502
|
+
ok: false;
|
|
503
|
+
error: ErrorPayload;
|
|
504
|
+
};
|
|
505
|
+
export interface EventMessage {
|
|
506
|
+
v: typeof PROTOCOL_VERSION;
|
|
507
|
+
event: EventName;
|
|
508
|
+
data: unknown;
|
|
509
|
+
}
|
|
510
|
+
export type HostMessage = ResponseMessage | EventMessage;
|
|
511
|
+
export declare const LIMITS: {
|
|
512
|
+
/** Largest serialized request the host accepts. */
|
|
513
|
+
readonly maxMessageBytes: number;
|
|
514
|
+
/** Requests a module may have waiting at once. */
|
|
515
|
+
readonly maxInFlight: 64;
|
|
516
|
+
readonly maxKeyLength: 256;
|
|
517
|
+
/** Settings storage per module and game. */
|
|
518
|
+
readonly maxStoreBytes: number;
|
|
519
|
+
/** One document's data. */
|
|
520
|
+
readonly maxDocumentBytes: number;
|
|
521
|
+
/** All documents of one module in one game. */
|
|
522
|
+
readonly maxDocumentsBytes: number;
|
|
523
|
+
readonly maxDocuments: 1000;
|
|
524
|
+
readonly maxTitleLength: 200;
|
|
525
|
+
/** UI state for one panel. */
|
|
526
|
+
readonly maxPanelStateBytes: number;
|
|
527
|
+
/** One stored file (see Blobs). */
|
|
528
|
+
readonly maxBlobBytes: number;
|
|
529
|
+
/** All stored files of one module in one game. */
|
|
530
|
+
readonly maxBlobsBytes: number;
|
|
531
|
+
/** A PNG a module puts on the clipboard. */
|
|
532
|
+
readonly maxClipboardImageBytes: number;
|
|
533
|
+
/** The body of one network.fetch answer, before any base64. A longer answer fails with QUOTA_EXCEEDED. */
|
|
534
|
+
readonly maxNetworkResponseBytes: number;
|
|
535
|
+
/** How long one network.fetch may take, redirects included. */
|
|
536
|
+
readonly networkTimeoutMs: 15000;
|
|
537
|
+
/** Redirects one network.fetch follows; each must go to a granted host. */
|
|
538
|
+
readonly maxNetworkRedirects: 5;
|
|
539
|
+
/** network.fetch calls one panel may have running at once; more fail with BAD_REQUEST. */
|
|
540
|
+
readonly maxNetworkInFlight: 6;
|
|
541
|
+
/** How often Tavora reads one AI account at most, for every module together; asking sooner gives the last reading. */
|
|
542
|
+
readonly aiUsageMinReadMs: 60000;
|
|
543
|
+
/** How long one aiUsage.read may take; the Codex command line can be slow to start. */
|
|
544
|
+
readonly aiUsageTimeoutMs: 40000;
|
|
545
|
+
/** How long one discord.command may take; a slower answer is `no-answer`. */
|
|
546
|
+
readonly discordTimeoutMs: 15000;
|
|
547
|
+
/** Largest Discord answer or event passed on, as JSON; a larger one is `no-answer` (or dropped, for an event). */
|
|
548
|
+
readonly maxDiscordAnswerBytes: number;
|
|
549
|
+
/** Discord events one panel may subscribe to at once. */
|
|
550
|
+
readonly maxDiscordSubscriptions: 32;
|
|
551
|
+
/** Entries in one menu, submenus included. */
|
|
552
|
+
readonly maxMenuEntries: 100;
|
|
553
|
+
/** Characters of a menu label or heading. */
|
|
554
|
+
readonly maxMenuLabel: 80;
|
|
555
|
+
/** Characters of the hint on the right of a menu item, such as a shortcut. */
|
|
556
|
+
readonly maxMenuHint: 30;
|
|
557
|
+
};
|
|
558
|
+
/**
|
|
559
|
+
* One entry of a menu drawn by Tavora (ui.showMenu). Text only; Tavora draws it in the current theme.
|
|
560
|
+
* An item list where any item sets `checked` keeps a column for the mark, so labels line up.
|
|
561
|
+
*/
|
|
562
|
+
export type MenuEntry = {
|
|
563
|
+
type: "item";
|
|
564
|
+
/** Returned when the player picks it; unique within the menu, at most 64 characters. */
|
|
565
|
+
id: string;
|
|
566
|
+
label: string;
|
|
567
|
+
/** Small grey text on the right, such as a shortcut ("Ctrl+D"). */
|
|
568
|
+
hint?: string;
|
|
569
|
+
/** A colour dot before the label, as a CSS colour: `#rgb`, `#rrggbb`, `rgb()`, `hsl()`, `oklch()` and the like, or `transparent` for an empty ring. */
|
|
570
|
+
color?: string;
|
|
571
|
+
/** Shows a check mark (or a dot, with `radio`) when true, and keeps the mark's column when false. */
|
|
572
|
+
checked?: boolean;
|
|
573
|
+
/** The mark is a dot: one choice of several. */
|
|
574
|
+
radio?: boolean;
|
|
575
|
+
disabled?: boolean;
|
|
576
|
+
/** Red, for something that deletes or cannot be undone. */
|
|
577
|
+
danger?: boolean;
|
|
578
|
+
} | {
|
|
579
|
+
type: "separator";
|
|
580
|
+
} | {
|
|
581
|
+
type: "heading";
|
|
582
|
+
label: string;
|
|
583
|
+
} | {
|
|
584
|
+
type: "submenu";
|
|
585
|
+
label: string;
|
|
586
|
+
color?: string;
|
|
587
|
+
disabled?: boolean;
|
|
588
|
+
/** Items, separators and headings; a submenu holds no further submenus. */
|
|
589
|
+
items: MenuEntry[];
|
|
590
|
+
};
|
|
591
|
+
/** What ui.showMenu shows, and where. */
|
|
592
|
+
export interface MenuRequest {
|
|
593
|
+
items: MenuEntry[];
|
|
594
|
+
/**
|
|
595
|
+
* Where, in the panel's CSS pixels from its top left corner: a point for a context menu (the pointer's
|
|
596
|
+
* position), or a rectangle (a button) the menu opens next to. Tavora keeps the menu inside the window.
|
|
597
|
+
*/
|
|
598
|
+
at: {
|
|
599
|
+
x: number;
|
|
600
|
+
y: number;
|
|
601
|
+
width?: number;
|
|
602
|
+
height?: number;
|
|
603
|
+
};
|
|
604
|
+
/** Which side of `at` the menu opens on, when there is room. Default "bottom". */
|
|
605
|
+
side?: "bottom" | "top" | "right" | "left";
|
|
606
|
+
/** How the menu lines up with `at` along that side. Default "start". */
|
|
607
|
+
align?: "start" | "center" | "end";
|
|
608
|
+
}
|
|
609
|
+
/** The kinds of file a module can keep with blobs.put, found by looking at the file itself. */
|
|
610
|
+
export declare const BLOB_TYPES: readonly ["image/png", "image/jpeg", "image/gif", "image/webp"];
|
|
611
|
+
export type BlobType = (typeof BLOB_TYPES)[number];
|
|
612
|
+
/** A stored file. */
|
|
613
|
+
export interface BlobInfo {
|
|
614
|
+
/** 32 lowercase hex characters, chosen by the host. */
|
|
615
|
+
id: string;
|
|
616
|
+
bytes: number;
|
|
617
|
+
type: BlobType;
|
|
618
|
+
createdAt: string;
|
|
619
|
+
}
|
|
620
|
+
/** How much of the limits a module's files in the current game use. */
|
|
621
|
+
export interface BlobUsage {
|
|
622
|
+
bytes: number;
|
|
623
|
+
count: number;
|
|
624
|
+
/** All files together. */
|
|
625
|
+
maxBytes: number;
|
|
626
|
+
/** One file. */
|
|
627
|
+
maxFileBytes: number;
|
|
628
|
+
}
|
|
629
|
+
/**
|
|
630
|
+
* Files are sent to and shown from the module's own address, not over the
|
|
631
|
+
* bridge: POST /_blobs/ stores the request body and answers with a BlobInfo,
|
|
632
|
+
* GET /_blobs/<id> serves a file. Both only work from the module's own page.
|
|
633
|
+
*/
|
|
634
|
+
export declare const BLOB_PATH = "/_blobs/";
|
|
635
|
+
export declare const BLOB_ID: RegExp;
|
|
636
|
+
/** POST a PNG here, from the module's own page, to put it on the clipboard (see clipboard.writeImage). */
|
|
637
|
+
export declare const CLIPBOARD_PATH = "/_clipboard/";
|
|
638
|
+
/** Document ids: host-generated UUIDs or module-chosen slugs. */
|
|
639
|
+
export declare const DOCUMENT_ID: RegExp;
|
|
640
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
|