lumiverse-spindle-types 0.1.3 → 0.1.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lumiverse-spindle-types",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "types": "./src/index.ts",
5
5
  "keywords": [
6
6
  "lumiverse",
package/src/api.ts CHANGED
@@ -62,6 +62,80 @@ export interface ConnectionProfileDTO {
62
62
  updated_at: number;
63
63
  }
64
64
 
65
+ // ─── Character DTOs ─────────────────────────────────────────────────────
66
+
67
+ /**
68
+ * Safe representation of a character exposed to extensions.
69
+ * Omits raw extensions blob — only exposes user-facing fields.
70
+ */
71
+ export interface CharacterDTO {
72
+ id: string;
73
+ name: string;
74
+ description: string;
75
+ personality: string;
76
+ scenario: string;
77
+ first_mes: string;
78
+ mes_example: string;
79
+ creator_notes: string;
80
+ system_prompt: string;
81
+ post_history_instructions: string;
82
+ tags: string[];
83
+ alternate_greetings: string[];
84
+ creator: string;
85
+ image_id: string | null;
86
+ created_at: number;
87
+ updated_at: number;
88
+ }
89
+
90
+ export interface CharacterCreateDTO {
91
+ name: string;
92
+ description?: string;
93
+ personality?: string;
94
+ scenario?: string;
95
+ first_mes?: string;
96
+ mes_example?: string;
97
+ creator_notes?: string;
98
+ system_prompt?: string;
99
+ post_history_instructions?: string;
100
+ tags?: string[];
101
+ alternate_greetings?: string[];
102
+ creator?: string;
103
+ }
104
+
105
+ export interface CharacterUpdateDTO {
106
+ name?: string;
107
+ description?: string;
108
+ personality?: string;
109
+ scenario?: string;
110
+ first_mes?: string;
111
+ mes_example?: string;
112
+ creator_notes?: string;
113
+ system_prompt?: string;
114
+ post_history_instructions?: string;
115
+ tags?: string[];
116
+ alternate_greetings?: string[];
117
+ creator?: string;
118
+ }
119
+
120
+ // ─── Chat DTOs ──────────────────────────────────────────────────────────
121
+
122
+ /**
123
+ * Safe representation of a chat session exposed to extensions.
124
+ */
125
+ export interface ChatDTO {
126
+ id: string;
127
+ character_id: string;
128
+ name: string;
129
+ metadata: Record<string, unknown>;
130
+ created_at: number;
131
+ updated_at: number;
132
+ }
133
+
134
+ export interface ChatUpdateDTO {
135
+ name?: string;
136
+ metadata?: Record<string, unknown>;
137
+ }
138
+
65
139
  /**
66
140
  * Structured error code included in permission-denied error messages.
67
141
  * Extensions can check `error.startsWith("PERMISSION_DENIED:")` to
@@ -246,7 +320,30 @@ export type WorkerToHost =
246
320
  }
247
321
  | { type: "tool_invocation_result"; requestId: string; result?: string; error?: string }
248
322
  | { type: "create_oauth_state"; requestId: string }
249
- | { type: "log"; level: "info" | "warn" | "error"; message: string };
323
+ | { type: "log"; level: "info" | "warn" | "error"; message: string }
324
+ // ─── Variables (free tier) ──────────────────────────────────────────
325
+ | { type: "vars_get_local"; requestId: string; chatId: string; key: string }
326
+ | { type: "vars_set_local"; requestId: string; chatId: string; key: string; value: string }
327
+ | { type: "vars_delete_local"; requestId: string; chatId: string; key: string }
328
+ | { type: "vars_list_local"; requestId: string; chatId: string }
329
+ | { type: "vars_has_local"; requestId: string; chatId: string; key: string }
330
+ | { type: "vars_get_global"; requestId: string; key: string; userId?: string }
331
+ | { type: "vars_set_global"; requestId: string; key: string; value: string; userId?: string }
332
+ | { type: "vars_delete_global"; requestId: string; key: string; userId?: string }
333
+ | { type: "vars_list_global"; requestId: string; userId?: string }
334
+ | { type: "vars_has_global"; requestId: string; key: string; userId?: string }
335
+ // ─── Characters (gated: "characters") ──────────────────────────────
336
+ | { type: "characters_list"; requestId: string; limit?: number; offset?: number; userId?: string }
337
+ | { type: "characters_get"; requestId: string; characterId: string; userId?: string }
338
+ | { type: "characters_create"; requestId: string; input: CharacterCreateDTO; userId?: string }
339
+ | { type: "characters_update"; requestId: string; characterId: string; input: CharacterUpdateDTO; userId?: string }
340
+ | { type: "characters_delete"; requestId: string; characterId: string; userId?: string }
341
+ // ─── Chats (gated: "chats") ────────────────────────────────────────
342
+ | { type: "chats_list"; requestId: string; characterId?: string; limit?: number; offset?: number; userId?: string }
343
+ | { type: "chats_get"; requestId: string; chatId: string; userId?: string }
344
+ | { type: "chats_get_active"; requestId: string; userId?: string }
345
+ | { type: "chats_update"; requestId: string; chatId: string; input: ChatUpdateDTO; userId?: string }
346
+ | { type: "chats_delete"; requestId: string; chatId: string; userId?: string };
250
347
 
251
348
  // ─── Host → Worker messages ──────────────────────────────────────────────
252
349
 
package/src/index.ts CHANGED
@@ -20,6 +20,11 @@ export type {
20
20
  RequestInitDTO,
21
21
  ConnectionProfileDTO,
22
22
  PermissionDeniedDetail,
23
+ CharacterDTO,
24
+ CharacterCreateDTO,
25
+ CharacterUpdateDTO,
26
+ ChatDTO,
27
+ ChatUpdateDTO,
23
28
  WorkerToHost,
24
29
  HostToWorker,
25
30
  } from "./api";
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Gated permissions that extensions must declare in spindle.json.
3
3
  *
4
- * Free tier (no declaration needed): events, storage, macros, dom
4
+ * Free tier (no declaration needed): events, storage, macros, dom, variables
5
5
  *
6
6
  * Gated tier (must declare):
7
7
  * - "generation" — fire generations on behalf of user
@@ -9,6 +9,8 @@
9
9
  * - "tools" — register LLM tools
10
10
  * - "cors_proxy" — use CORS proxy
11
11
  * - "context_handler" — register global context middleware
12
+ * - "characters" — CRUD on character cards
13
+ * - "chats" — CRUD on chat sessions
12
14
  */
13
15
  export type SpindlePermission =
14
16
  | "generation"
@@ -21,7 +23,9 @@ export type SpindlePermission =
21
23
  | "event_tracking"
22
24
  | "ui_panels"
23
25
  | "app_manipulation"
24
- | "oauth";
26
+ | "oauth"
27
+ | "characters"
28
+ | "chats";
25
29
 
26
30
  export const ALL_PERMISSIONS: readonly SpindlePermission[] = [
27
31
  "generation",
@@ -35,6 +39,8 @@ export const ALL_PERMISSIONS: readonly SpindlePermission[] = [
35
39
  "ui_panels",
36
40
  "app_manipulation",
37
41
  "oauth",
42
+ "characters",
43
+ "chats",
38
44
  ] as const;
39
45
 
40
46
  export function isValidPermission(p: string): p is SpindlePermission {
@@ -7,6 +7,11 @@ import type {
7
7
  RequestInitDTO,
8
8
  ConnectionProfileDTO,
9
9
  PermissionDeniedDetail,
10
+ CharacterDTO,
11
+ CharacterCreateDTO,
12
+ CharacterUpdateDTO,
13
+ ChatDTO,
14
+ ChatUpdateDTO,
10
15
  } from "./api";
11
16
 
12
17
  /** The global `spindle` object available in backend extension workers */
@@ -228,6 +233,52 @@ export interface SpindleAPI {
228
233
  get(connectionId: string, userId?: string): Promise<ConnectionProfileDTO | null>;
229
234
  };
230
235
 
236
+ /**
237
+ * Local (chat-scoped) and global variable access (free tier — no permission needed).
238
+ * Uses the same storage as built-in {{getvar}}/{{setgvar}} macros.
239
+ */
240
+ variables: {
241
+ local: {
242
+ get(chatId: string, key: string): Promise<string>;
243
+ set(chatId: string, key: string, value: string): Promise<void>;
244
+ delete(chatId: string, key: string): Promise<void>;
245
+ list(chatId: string): Promise<Record<string, string>>;
246
+ has(chatId: string, key: string): Promise<boolean>;
247
+ };
248
+ global: {
249
+ get(key: string): Promise<string>;
250
+ set(key: string, value: string): Promise<void>;
251
+ delete(key: string): Promise<void>;
252
+ list(): Promise<Record<string, string>>;
253
+ has(key: string): Promise<boolean>;
254
+ };
255
+ };
256
+
257
+ /**
258
+ * Character CRUD (permission: "characters").
259
+ * Returns safe DTO representations — raw extensions blob is not exposed.
260
+ */
261
+ characters: {
262
+ list(options?: { limit?: number; offset?: number }): Promise<{ data: CharacterDTO[]; total: number }>;
263
+ get(characterId: string): Promise<CharacterDTO | null>;
264
+ create(input: CharacterCreateDTO): Promise<CharacterDTO>;
265
+ update(characterId: string, input: CharacterUpdateDTO): Promise<CharacterDTO>;
266
+ delete(characterId: string): Promise<boolean>;
267
+ };
268
+
269
+ /**
270
+ * Chat session CRUD (permission: "chats").
271
+ * Separate from `chat` (message-level mutation) — this operates on chat entities.
272
+ */
273
+ chats: {
274
+ list(options?: { characterId?: string; limit?: number; offset?: number }): Promise<{ data: ChatDTO[]; total: number }>;
275
+ get(chatId: string): Promise<ChatDTO | null>;
276
+ /** Get the user's currently active chat (as tracked by the frontend). Returns null if none. */
277
+ getActive(): Promise<ChatDTO | null>;
278
+ update(chatId: string, input: ChatUpdateDTO): Promise<ChatDTO>;
279
+ delete(chatId: string): Promise<boolean>;
280
+ };
281
+
231
282
  permissions: {
232
283
  getGranted(): Promise<string[]>;
233
284
  /**