lumiverse-spindle-types 0.6.2 → 0.6.3

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.6.2",
3
+ "version": "0.6.3",
4
4
  "types": "./src/index.ts",
5
5
  "keywords": [
6
6
  "lumiverse",
package/src/api.ts CHANGED
@@ -1101,6 +1101,14 @@ export interface PromptBlockCategoryGroupDTO {
1101
1101
  children: PromptBlockDTO[];
1102
1102
  }
1103
1103
 
1104
+ export interface HostResponseErrorDTO {
1105
+ code: string;
1106
+ message: string;
1107
+ presetId?: string;
1108
+ expectedCacheRevision?: number;
1109
+ actualCacheRevision?: number;
1110
+ }
1111
+
1104
1112
  export interface UserPresetDTO {
1105
1113
  id: string;
1106
1114
  name: string;
@@ -1110,6 +1118,7 @@ export interface UserPresetDTO {
1110
1118
  prompt_order: PromptBlockDTO[];
1111
1119
  prompts: Record<string, unknown>;
1112
1120
  metadata: Record<string, unknown>;
1121
+ cache_revision: number;
1113
1122
  created_at: number;
1114
1123
  updated_at: number;
1115
1124
  }
@@ -1124,7 +1133,9 @@ export interface UserPresetCreateDTO {
1124
1133
  metadata?: Record<string, unknown>;
1125
1134
  }
1126
1135
 
1127
- export type UserPresetUpdateDTO = Partial<UserPresetCreateDTO>;
1136
+ export type UserPresetUpdateDTO = Partial<UserPresetCreateDTO> & {
1137
+ expected_cache_revision: number;
1138
+ };
1128
1139
  export type PromptBlockCreateDTO = Partial<PromptBlockDTO>;
1129
1140
  export type PromptBlockUpdateDTO = Partial<Omit<PromptBlockDTO, "id">>;
1130
1141
 
@@ -3234,7 +3245,7 @@ export type HostToWorker =
3234
3245
  type: "response";
3235
3246
  requestId: string;
3236
3247
  result?: unknown;
3237
- error?: string;
3248
+ error?: string | HostResponseErrorDTO;
3238
3249
  }
3239
3250
  | {
3240
3251
  type: "permission_denied";
package/src/dom.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { PromptBlockDTO, RequestInitDTO } from "./api";
1
+ import type { PromptBlockDTO, PromptVariableValuesDTO, RequestInitDTO } from "./api";
2
2
  import type { SpindleComponentsHelper } from "./components";
3
3
 
4
4
  /** A chat-message DOM element paired with its stable message id. */
@@ -221,6 +221,21 @@ export interface SpindlePresetEditorTabHandle {
221
221
  onActivate(handler: () => void): () => void;
222
222
  }
223
223
 
224
+ /** Extension-owned root placed above Loom's list and editor branches. */
225
+ export interface SpindlePresetEditorToolbarItemOptions {
226
+ /** Unique toolbar item identifier within the current extension. */
227
+ id: string;
228
+ /** Required accessible label for the extension-owned toolbar root. */
229
+ ariaLabel: string;
230
+ }
231
+
232
+ export interface SpindlePresetEditorToolbarItemHandle {
233
+ readonly root: HTMLElement;
234
+ readonly itemId: string;
235
+ setVisible(visible: boolean): void;
236
+ destroy(): void;
237
+ }
238
+
224
239
  /** Mutable, editor-native snapshot of the current Loom preset draft. */
225
240
  export interface SpindlePresetEditorDraft {
226
241
  id: string;
@@ -259,6 +274,38 @@ export interface SpindlePresetEditorHelper {
259
274
  ): void;
260
275
  /** Immediately persist and await any pending draft changes. */
261
276
  flush(): Promise<void>;
277
+ /**
278
+ * Cooperative, extension-identifier-scoped metadata access. This does not
279
+ * sandbox same-origin extension code; it prevents accidental whole-draft
280
+ * writes through the supported helper.
281
+ */
282
+ readonly extension: SpindlePresetEditorScopedHelper;
283
+ }
284
+
285
+ export type SpindlePresetEditorBuiltinTabId = "blocks";
286
+
287
+ export interface SpindlePresetEditorExtensionState {
288
+ readonly open: boolean;
289
+ readonly presetId: string | null;
290
+ readonly activeTabId: string | null;
291
+ /** Detached array cloned from the host draft. */
292
+ readonly blocks: readonly PromptBlockDTO[];
293
+ /** Detached prompt-variable values cloned from the host draft. */
294
+ readonly promptVariableValues: Readonly<PromptVariableValuesDTO>;
295
+ /** The raw metadata value currently owned by the calling extension. */
296
+ readonly metadata: unknown;
297
+ }
298
+
299
+ export interface SpindlePresetEditorScopedHelper {
300
+ getState(): SpindlePresetEditorExtensionState;
301
+ onChange(handler: (state: SpindlePresetEditorExtensionState) => void): () => void;
302
+ setMetadata(value: Record<string, unknown>, options?: SpindlePresetEditorSaveOptions): void;
303
+ updateMetadata(
304
+ mutator: (current: unknown) => Record<string, unknown>,
305
+ options?: SpindlePresetEditorSaveOptions,
306
+ ): void;
307
+ activateBuiltinTab(tab: SpindlePresetEditorBuiltinTabId): void;
308
+ flush(): Promise<void>;
262
309
  }
263
310
 
264
311
  // ── Float Widget ──
@@ -824,6 +871,7 @@ export interface SpindleFrontendContext {
824
871
  registerCharacterEditorTab(options: SpindleCharacterEditorTabOptions): SpindleCharacterEditorTabHandle;
825
872
  characterEditor: SpindleCharacterEditorHelper;
826
873
  registerPresetEditorTab(options: SpindlePresetEditorTabOptions): SpindlePresetEditorTabHandle;
874
+ registerPresetEditorToolbarItem(options: SpindlePresetEditorToolbarItemOptions): SpindlePresetEditorToolbarItemHandle;
827
875
  presetEditor: SpindlePresetEditorHelper;
828
876
  createFloatWidget(options?: SpindleFloatWidgetOptions): SpindleFloatWidgetHandle;
829
877
  requestDockPanel(options: SpindleDockPanelOptions): SpindleDockPanelHandle;
package/src/index.ts CHANGED
@@ -62,6 +62,7 @@ export type {
62
62
  PromptBlockCreateDTO,
63
63
  PromptBlockUpdateDTO,
64
64
  PromptBlockCategoryGroupDTO,
65
+ HostResponseErrorDTO,
65
66
  UserPresetDTO,
66
67
  UserPresetCreateDTO,
67
68
  UserPresetUpdateDTO,
@@ -224,10 +225,15 @@ export type {
224
225
  SpindleCharacterEditorHelper,
225
226
  SpindlePresetEditorTabOptions,
226
227
  SpindlePresetEditorTabHandle,
228
+ SpindlePresetEditorToolbarItemOptions,
229
+ SpindlePresetEditorToolbarItemHandle,
227
230
  SpindlePresetEditorDraft,
228
231
  SpindlePresetEditorState,
229
232
  SpindlePresetEditorSaveOptions,
230
233
  SpindlePresetEditorHelper,
234
+ SpindlePresetEditorBuiltinTabId,
235
+ SpindlePresetEditorExtensionState,
236
+ SpindlePresetEditorScopedHelper,
231
237
  SpindleFloatWidgetOptions,
232
238
  SpindleFloatWidgetHandle,
233
239
  SpindleDockEdge,
@@ -0,0 +1,31 @@
1
+ import type { SpindleFrontendContext } from "./dom";
2
+
3
+ /** Compile-time fixture for the additive preset-editor extension API. */
4
+ export function verifyPresetEditorContract(ctx: SpindleFrontendContext): void {
5
+ const toolbar = ctx.ui.registerPresetEditorToolbarItem({
6
+ id: "mode-controls",
7
+ ariaLabel: "Agent mode controls",
8
+ });
9
+ toolbar.setVisible(true);
10
+ // @ts-expect-error Extension-owned handles do not expose mutable host identity.
11
+ toolbar.itemId = "replacement";
12
+ toolbar.destroy();
13
+
14
+ const editor = ctx.ui.presetEditor.extension;
15
+ // @ts-expect-error Scoped helpers are acquired from a read-only getter.
16
+ ctx.ui.presetEditor.extension = editor;
17
+ const state = editor.getState();
18
+ state.blocks.forEach((block) => block.id);
19
+ // @ts-expect-error Snapshot identity is host-owned.
20
+ state.open = true;
21
+ // @ts-expect-error Scoped metadata is a read-only host snapshot.
22
+ state.metadata = { mode: "replacement" };
23
+
24
+ editor.setMetadata({ mode: "parallel" }, { immediate: true });
25
+ editor.updateMetadata((current) => ({
26
+ ...(current && typeof current === "object" && !Array.isArray(current) ? current : {}),
27
+ revision: 1,
28
+ }));
29
+ editor.activateBuiltinTab("blocks");
30
+ void editor.flush();
31
+ }