lumiverse-spindle-types 0.6.5 → 0.6.8

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.5",
3
+ "version": "0.6.8",
4
4
  "types": "./src/index.ts",
5
5
  "keywords": [
6
6
  "lumiverse",
package/src/api.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { SpindleManifest } from "./manifest";
2
+ import type { SpindleHostDescriptorV1 } from "./host";
2
3
  import type { CouncilMemberContext } from "./council";
3
4
  import type {
4
5
  ChatLinkAttachDTO,
@@ -16,13 +17,21 @@ export type LlmMessagePartDTO =
16
17
  | { type: "text"; text: string; cache_control?: Record<string, unknown> }
17
18
  | { type: "image"; data: string; mime_type: string; cache_control?: Record<string, unknown> }
18
19
  | { type: "audio"; data: string; mime_type: string; cache_control?: Record<string, unknown> }
19
- | { type: "tool_use"; id: string; name: string; input: Record<string, unknown>; cache_control?: Record<string, unknown> }
20
+ | { type: "tool_use"; id: string; name: string; input: Record<string, unknown>; cache_control?: Record<string, unknown>; thought_signature?: string }
20
21
  | { type: "tool_result"; tool_use_id: string; content: string; is_error?: boolean; cache_control?: Record<string, unknown> };
21
22
 
23
+ export interface LlmThinkingBlockDTO {
24
+ type: "thinking" | "redacted_thinking";
25
+ thinking?: string;
26
+ signature?: string;
27
+ data?: string;
28
+ }
29
+
22
30
  export interface LlmMessageDTO {
23
31
  role: "system" | "user" | "assistant";
24
32
  content: string | LlmMessagePartDTO[];
25
33
  name?: string;
34
+ cache_control?: Record<string, unknown>;
26
35
  /**
27
36
  * Thinking-mode reasoning content from the previous assistant turn, echoed
28
37
  * back on the next request. Required by DeepSeek's thinking-mode models
@@ -36,6 +45,8 @@ export interface LlmMessageDTO {
36
45
  * only on `role: 'assistant'` messages.
37
46
  */
38
47
  reasoning_content?: string;
48
+ thinking_blocks?: LlmThinkingBlockDTO[];
49
+ reasoning_details?: Record<string, unknown>[];
39
50
  /**
40
51
  * True when this message is a chat-history turn (as opposed to a depth-injected
41
52
  * world-info/preset/author's-note block that was spliced into the chat-history
@@ -57,6 +68,80 @@ export interface LlmMessageDTO {
57
68
  }
58
69
 
59
70
  export type SpindleUserRoleDTO = "operator" | "admin" | "user";
71
+ export type InterceptorGenerationType =
72
+ | "normal"
73
+ | "continue"
74
+ | "regenerate"
75
+ | "swipe"
76
+ | "impersonate"
77
+ | "quiet";
78
+
79
+ export type InterceptorMatchScalar = string | number | boolean | null;
80
+
81
+ export interface InterceptorMatchDTO {
82
+ /**
83
+ * Serializable filter domain. Terminal callbacks currently run only for
84
+ * live `normal` and `continue`; every other value is a fail-closed filter.
85
+ */
86
+ generationTypes?: InterceptorGenerationType[];
87
+ /** Terminal callbacks are never invoked for dry runs. */
88
+ isDryRun?: boolean;
89
+ presetField?: {
90
+ path: string[];
91
+ exists?: boolean;
92
+ oneOf?: InterceptorMatchScalar[];
93
+ notIn?: InterceptorMatchScalar[];
94
+ };
95
+ }
96
+
97
+ export interface InterceptorRegistrationMatchOptions {
98
+ match?: InterceptorMatchDTO;
99
+ }
100
+
101
+ export interface InterceptorRegistrationOptions {
102
+ priority?: number;
103
+ match?: InterceptorMatchDTO;
104
+ }
105
+
106
+ /**
107
+ * Host-owned, immutable context for one bound interceptor callback.
108
+ * `signal` is local to the worker invocation and is never serialized.
109
+ */
110
+ export interface InterceptorContextDTO {
111
+ readonly userId: string;
112
+ readonly chatId: string;
113
+ readonly generationId: string;
114
+ readonly generationType: InterceptorGenerationType;
115
+ readonly isDryRun: boolean;
116
+ readonly presetId: string | null;
117
+ /** Deep clone of only this extension's own preset metadata namespace. */
118
+ readonly presetMetadata: unknown;
119
+ readonly personaId: string | null;
120
+ readonly characterId: string | null;
121
+ readonly personaAddonStates: Readonly<Record<string, boolean>>;
122
+ readonly excludeMessageId?: string;
123
+ readonly rejectedSwipe?: string;
124
+ readonly regenFeedback?: string;
125
+ readonly regenFeedbackPosition?: "system" | "user";
126
+ readonly mainDispatch: {
127
+ readonly source: "main";
128
+ readonly descriptor: Readonly<ConnectionDispatchDescriptorDTO> | null;
129
+ readonly connectionDispatchRevision: string | null;
130
+ readonly dispatchKind: "concrete" | "roulette" | null;
131
+ };
132
+ readonly prefillCarrier: BoundPrefillAttachmentDTO;
133
+ readonly interceptorDeadlineAt: number;
134
+ readonly boundWorkDeadlineAt: number;
135
+ /** Worker-local cancellation signal; never serialized over the worker protocol. */
136
+ readonly signal: AbortSignal;
137
+ }
138
+
139
+ export interface DeferredGuidanceDTO {
140
+ id: string;
141
+ content: string;
142
+ role: "system";
143
+ }
144
+
60
145
 
61
146
  /**
62
147
  * Optional metadata returned by an interceptor so Lumiverse can surface
@@ -73,6 +158,13 @@ export interface InterceptorBreakdownEntryDTO {
73
158
  name?: string;
74
159
  }
75
160
 
161
+ /** Privileged response override returned by an interceptor. */
162
+ export interface FinalResponseDTO {
163
+ content: string;
164
+ reasoning?: string;
165
+ fallbackMessageIndex: number;
166
+ }
167
+
76
168
  /**
77
169
  * Return type for interceptor handlers.
78
170
  * Interceptors may return either a plain `LlmMessageDTO[]` (backwards-compatible)
@@ -84,8 +176,19 @@ export interface InterceptorResultDTO {
84
176
  parameters?: Record<string, unknown>;
85
177
  /** Optional prompt-breakdown entries for injected messages. */
86
178
  breakdown?: InterceptorBreakdownEntryDTO[];
179
+ /** Host-owned system guidance retained for each authoritative Main attempt. */
180
+ deferredGuidance?: DeferredGuidanceDTO[];
181
+ /** Optional privileged response replacement. Requires the `final_response` permission. */
182
+ finalResponse?: FinalResponseDTO;
87
183
  }
88
184
 
185
+ export type InterceptorDisposer = () => void;
186
+
187
+ export type InterceptorHandler = (
188
+ messages: LlmMessageDTO[],
189
+ context: InterceptorContextDTO,
190
+ ) => Promise<LlmMessageDTO[] | InterceptorResultDTO>;
191
+
89
192
  export interface MacroDefinitionDTO {
90
193
  name: string;
91
194
  category: string;
@@ -261,6 +364,15 @@ export interface ToolSchemaDTO {
261
364
  parameters: Record<string, unknown>; // JSON Schema
262
365
  }
263
366
 
367
+ export interface ToolDefinitionDTO {
368
+ name: string;
369
+ description: string;
370
+ parameters: Record<string, unknown>;
371
+ strict?: boolean;
372
+ inputExamples?: Array<Record<string, unknown>>;
373
+ cache_control?: Record<string, unknown>;
374
+ }
375
+
264
376
  /** A single function call made by the LLM. */
265
377
  export interface ToolCallDTO {
266
378
  /** Tool name (as given in the schema). */
@@ -269,8 +381,35 @@ export interface ToolCallDTO {
269
381
  args: Record<string, unknown>;
270
382
  /** Provider call ID (e.g. Anthropic `id`, OpenAI `id`). Synthetic UUID for providers that don't supply one (e.g. Google). */
271
383
  call_id: string;
384
+ /** Opaque provider signature preserved for tool-call continuations. */
385
+ thought_signature?: string;
386
+ }
387
+
388
+ export interface GenerationUsageDTO {
389
+ prompt_tokens?: number;
390
+ completion_tokens?: number;
391
+ total_tokens?: number;
392
+ provider_raw?: Record<string, unknown>;
272
393
  }
273
394
 
395
+ export interface GenerationResponseDTO {
396
+ content: string;
397
+ reasoning?: string;
398
+ finish_reason: string;
399
+ tool_calls?: ToolCallDTO[];
400
+ thinking_blocks?: LlmThinkingBlockDTO[];
401
+ reasoning_details?: Record<string, unknown>[];
402
+ usage?: GenerationUsageDTO;
403
+ }
404
+
405
+ export type GenerationDispatchSourceDTO =
406
+ | { source: "main"; expectedConnectionDispatchRevision: string }
407
+ | {
408
+ source: "slot";
409
+ connectionId: string;
410
+ expectedConnectionDispatchRevision: string;
411
+ };
412
+
274
413
  export interface GenerationRequestDTO {
275
414
  type: "raw" | "quiet" | "batch";
276
415
  messages?: LlmMessageDTO[];
@@ -535,6 +674,16 @@ export interface ConnectionProfileDTO {
535
674
  updated_at: number;
536
675
  }
537
676
 
677
+ export interface ConnectionDispatchDescriptorDTO {
678
+ connectionId: string;
679
+ connectionName: string;
680
+ provider: string;
681
+ model: string;
682
+ endpointOrigin: string;
683
+ dispatchKind: "concrete" | "roulette";
684
+ connectionDispatchRevision: string | null;
685
+ }
686
+
538
687
  // ─── Image Generation DTOs ──────────────────────────────────────────────
539
688
 
540
689
  /**
@@ -578,6 +727,11 @@ export interface ImageGenProviderDTO {
578
727
  modelListStyle: "static" | "dynamic" | "google";
579
728
  staticModels?: Array<{ id: string; label: string }>;
580
729
  defaultUrl: string;
730
+ /** Present only when the provider supports Lumiverse's WebSocket preview/status stream. */
731
+ websocketPreviewStreaming?: {
732
+ previews: true;
733
+ status: true;
734
+ };
581
735
  };
582
736
  }
583
737
 
@@ -612,6 +766,47 @@ export interface ImageGenResultDTO {
612
766
  imageUrl?: string;
613
767
  }
614
768
 
769
+ /** Input for {@link SpindleAPI.imageGen.generateStream}. */
770
+ export interface ImageGenStreamRequestDTO extends ImageGenRequestDTO {
771
+ /** Abort the upstream generation and close its WebSocket stream. */
772
+ signal?: AbortSignal;
773
+ }
774
+
775
+ /** A progress/status update received from the provider WebSocket. */
776
+ export interface ImageGenStreamStatusDTO {
777
+ type: "status";
778
+ /** Current step when the provider reports numerical progress. */
779
+ step?: number;
780
+ /** Total steps when the provider reports numerical progress. */
781
+ totalSteps?: number;
782
+ /** Current workflow node, when supplied by the provider. */
783
+ nodeId?: string;
784
+ }
785
+
786
+ /** A preview image received from the provider WebSocket. */
787
+ export interface ImageGenStreamPreviewDTO {
788
+ type: "preview";
789
+ /** Preview image as a base64 data URL. */
790
+ imageDataUrl: string;
791
+ /** Status reported with this preview, when available. */
792
+ step?: number;
793
+ totalSteps?: number;
794
+ nodeId?: string;
795
+ }
796
+
797
+ /** Terminal success event for an image generation stream. */
798
+ export interface ImageGenStreamDoneDTO {
799
+ type: "done";
800
+ /** Final image and its persisted asset identifiers. */
801
+ result: ImageGenResultDTO;
802
+ }
803
+
804
+ /** Events yielded by {@link SpindleAPI.imageGen.generateStream}. */
805
+ export type ImageGenStreamEventDTO =
806
+ | ImageGenStreamStatusDTO
807
+ | ImageGenStreamPreviewDTO
808
+ | ImageGenStreamDoneDTO;
809
+
615
810
  // ─── Image DTOs ─────────────────────────────────────────────────────────
616
811
 
617
812
  export type ImageSpecificityDTO = "full" | "sm" | "lg";
@@ -1753,6 +1948,126 @@ export interface AssembleResultDTO {
1753
1948
  breakdown: AssemblyBreakdownEntryDTO[];
1754
1949
  }
1755
1950
 
1951
+ export interface BoundPrefillAttachmentDTO {
1952
+ /**
1953
+ * Opaque parent-prefill attestation. It may be presented only by the live
1954
+ * worker invocation; it is not itself a reusable attachment capability,
1955
+ * message index, or carrier content.
1956
+ */
1957
+ readonly id: string;
1958
+ readonly state: "absent" | "available" | "invalid";
1959
+ }
1960
+
1961
+ export interface BoundAssembleRequestDTO {
1962
+ blocks: PromptBlockDTO[];
1963
+ promptVariableValues?: PromptVariableValuesDTO;
1964
+ dispatch: GenerationDispatchSourceDTO;
1965
+ deadlineAt: number;
1966
+ hookFailureMode?: "degrade" | "reject";
1967
+ macroFailureMode?: "degrade" | "reject";
1968
+ signal?: AbortSignal;
1969
+ }
1970
+
1971
+ export interface BoundAssemblySuccessDTO {
1972
+ messages: LlmMessageDTO[];
1973
+ breakdown: AssemblyBreakdownEntryDTO[];
1974
+ resolved: {
1975
+ source: "main" | "slot";
1976
+ connectionId: string | null;
1977
+ connectionDispatchRevision: string;
1978
+ dispatchKind: "concrete";
1979
+ };
1980
+ }
1981
+
1982
+ export type BoundAssemblyFailureDTO =
1983
+ | {
1984
+ kind: "hook";
1985
+ code: "ASSEMBLY_HOOK_FAILED";
1986
+ phase: "context" | "world_info" | "macro";
1987
+ reason: "error" | "timeout";
1988
+ message: string;
1989
+ }
1990
+ | {
1991
+ kind: "macro";
1992
+ code: "ASSEMBLY_MACRO_FAILED";
1993
+ reason: "definition" | "parse" | "recursion" | "budget" | "evaluation";
1994
+ message: string;
1995
+ }
1996
+ | {
1997
+ kind: "retrieval_snapshot";
1998
+ code: "ASSEMBLY_RETRIEVAL_SNAPSHOT_UNAVAILABLE";
1999
+ reason: "missing" | "expired" | "unavailable" | "oversize";
2000
+ message: string;
2001
+ }
2002
+ | {
2003
+ kind: "abort";
2004
+ code: "ASSEMBLY_ABORTED";
2005
+ name: "AbortError";
2006
+ message: string;
2007
+ }
2008
+ | {
2009
+ kind: "precondition" | "security" | "internal";
2010
+ code: string;
2011
+ message: string;
2012
+ };
2013
+
2014
+ export type BoundAssemblyOutcomeDTO =
2015
+ | { ok: true; result: BoundAssemblySuccessDTO }
2016
+ | { ok: false; error: BoundAssemblyFailureDTO };
2017
+
2018
+ export interface QuietTrackedRequestDTO {
2019
+ messages: LlmMessageDTO[];
2020
+ dispatch: GenerationDispatchSourceDTO;
2021
+ /**
2022
+ * When supplied, WorkerHost—not extension code—attaches the authenticated
2023
+ * parent assistant carrier as the final continuation carrier for this dispatch.
2024
+ */
2025
+ continuation?: {
2026
+ parentPrefill: BoundPrefillAttachmentDTO;
2027
+ mode: "append-parent-carrier-last";
2028
+ };
2029
+ parameters?: Record<string, unknown>;
2030
+ reasoning?: Record<string, unknown>;
2031
+ tools?: ToolDefinitionDTO[];
2032
+ deadlineAt: number;
2033
+ signal?: AbortSignal;
2034
+ }
2035
+
2036
+ export interface QuietDispatchReceiptDTO {
2037
+ providerInvoked: boolean;
2038
+ terminalResponse: boolean;
2039
+ source: "main" | "slot";
2040
+ connectionId: string | null;
2041
+ connectionDispatchRevision: string;
2042
+ usage?: GenerationUsageDTO;
2043
+ }
2044
+
2045
+ export type QuietTrackedResultDTO =
2046
+ | { ok: true; response: GenerationResponseDTO; receipt: QuietDispatchReceiptDTO }
2047
+ | {
2048
+ ok: false;
2049
+ phase: "preflight";
2050
+ providerInvoked: false;
2051
+ receipt: null;
2052
+ error: {
2053
+ kind: "precondition" | "security";
2054
+ code: string;
2055
+ name: string;
2056
+ message: string;
2057
+ };
2058
+ }
2059
+ | {
2060
+ ok: false;
2061
+ phase: "resolved";
2062
+ receipt: QuietDispatchReceiptDTO;
2063
+ error: {
2064
+ kind: "precondition" | "provider" | "abort" | "security" | "internal";
2065
+ code: string;
2066
+ name: string;
2067
+ message: string;
2068
+ };
2069
+ };
2070
+
1756
2071
  // ─── Chat Memory DTOs ──────────────────────────────────────────────────
1757
2072
 
1758
2073
  export interface ChatMemoryChunkDTO {
@@ -2641,13 +2956,22 @@ export type WorkerToHost =
2641
2956
  | { type: "register_macro"; definition: MacroDefinitionDTO }
2642
2957
  | { type: "unregister_macro"; name: string }
2643
2958
  | { type: "update_macro_value"; name: string; value: string }
2644
- | { type: "register_interceptor"; priority?: number }
2959
+ | {
2960
+ type: "register_interceptor";
2961
+ registrationId: string;
2962
+ priority?: number;
2963
+ match?: InterceptorMatchDTO;
2964
+ }
2965
+ | { type: "unregister_interceptor"; registrationId: string }
2645
2966
  | {
2646
2967
  type: "intercept_result";
2647
2968
  requestId: string;
2969
+ registrationId: string;
2648
2970
  messages: LlmMessageDTO[];
2649
2971
  parameters?: Record<string, unknown>;
2650
2972
  breakdown?: InterceptorBreakdownEntryDTO[];
2973
+ deferredGuidance?: DeferredGuidanceDTO[];
2974
+ finalResponse?: FinalResponseDTO;
2651
2975
  }
2652
2976
  | {
2653
2977
  type: "assemble_prompt";
@@ -2655,6 +2979,33 @@ export type WorkerToHost =
2655
2979
  input: Omit<AssembleRequestDTO, "signal">;
2656
2980
  userId?: string;
2657
2981
  }
2982
+ /**
2983
+ * Assemble through the active bound interceptor generation context. The
2984
+ * worker-local signal is omitted from the structured-clone payload.
2985
+ */
2986
+ | {
2987
+ type: "generate_assemble";
2988
+ requestId: string;
2989
+ input: Omit<BoundAssembleRequestDTO, "signal">;
2990
+ }
2991
+ /**
2992
+ * Dispatch tracked quiet generation through the active bound context.
2993
+ * The worker-local signal is omitted from the structured-clone payload.
2994
+ */
2995
+ | {
2996
+ type: "generate_quiet_tracked";
2997
+ requestId: string;
2998
+ input: Omit<QuietTrackedRequestDTO, "signal">;
2999
+ }
3000
+ /**
3001
+ * Inspect an owned concrete slot through the active bound interceptor
3002
+ * context. The host derives user scope from the authenticated callback.
3003
+ */
3004
+ | {
3005
+ type: "connections_resolve_dispatch";
3006
+ requestId: string;
3007
+ connectionId: string;
3008
+ }
2658
3009
  | { type: "register_tool"; tool: ToolRegistrationDTO }
2659
3010
  | { type: "unregister_tool"; name: string }
2660
3011
  | { type: "request_generation"; requestId: string; input: GenerationRequestDTO }
@@ -3079,6 +3430,12 @@ export type WorkerToHost =
3079
3430
  | { type: "macros_resolve"; requestId: string; template: string; chatId?: string; characterId?: string; userId?: string; commit?: boolean }
3080
3431
  // ─── Image Generation (gated: "image_gen") ──────────────────────────
3081
3432
  | { type: "image_gen_generate"; requestId: string; input: ImageGenRequestDTO }
3433
+ /**
3434
+ * Start a WebSocket-backed image stream. Only providers that advertise
3435
+ * `websocketPreviewStreaming` accept this request.
3436
+ */
3437
+ | { type: "image_gen_generate_stream"; requestId: string; input: Omit<ImageGenStreamRequestDTO, "signal"> }
3438
+ | { type: "image_gen_cancel_stream"; requestId: string }
3082
3439
  | { type: "image_gen_providers"; requestId: string; userId?: string }
3083
3440
  | { type: "image_gen_connections_list"; requestId: string; userId?: string }
3084
3441
  | { type: "image_gen_connections_get"; requestId: string; connectionId: string; userId?: string }
@@ -3205,7 +3562,7 @@ export type WorkerToHost =
3205
3562
  // ─── Host → Worker messages ──────────────────────────────────────────────
3206
3563
 
3207
3564
  export type HostToWorker =
3208
- | { type: "init"; manifest: SpindleManifest; storagePath: string }
3565
+ | { type: "init"; manifest: SpindleManifest; storagePath: string; host: SpindleHostDescriptorV1 }
3209
3566
  | { type: "event"; event: string; payload: unknown; userId?: string }
3210
3567
  | {
3211
3568
  type: "rpc_pool_request";
@@ -3218,8 +3575,15 @@ export type HostToWorker =
3218
3575
  | {
3219
3576
  type: "intercept_request";
3220
3577
  requestId: string;
3578
+ registrationId: string;
3221
3579
  messages: LlmMessageDTO[];
3222
- context: unknown;
3580
+ context: Omit<InterceptorContextDTO, "signal">;
3581
+ }
3582
+ | {
3583
+ type: "intercept_abort";
3584
+ requestId: string;
3585
+ registrationId: string;
3586
+ reason?: string;
3223
3587
  }
3224
3588
  | {
3225
3589
  type: "context_handler_request";
@@ -3310,4 +3674,6 @@ export type HostToWorker =
3310
3674
  * `request_generation_stream`. Mutually exclusive with the `done`
3311
3675
  * chunk in `generation_stream_chunk`. Aborts surface here too.
3312
3676
  */
3313
- | { type: "generation_stream_error"; requestId: string; error: string };
3677
+ | { type: "generation_stream_error"; requestId: string; error: string }
3678
+ | { type: "image_gen_stream_chunk"; requestId: string; event: ImageGenStreamEventDTO }
3679
+ | { type: "image_gen_stream_error"; requestId: string; error: string };
package/src/dom.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { PromptBlockDTO, PromptVariableValuesDTO, RequestInitDTO } from "./api";
2
2
  import type { SpindleComponentsHelper } from "./components";
3
+ import type { SpindleHostDescriptorV1, SpindleHostLocaleAPI } from "./host";
3
4
 
4
5
  /** A chat-message DOM element paired with its stable message id. */
5
6
  export interface SpindleMessageElement {
@@ -859,6 +860,10 @@ export interface SpindleDisplayResolverRegistry {
859
860
 
860
861
  /** Context object provided to frontend extension modules */
861
862
  export interface SpindleFrontendContext {
863
+ /** Immutable host compatibility descriptor for this extension runtime. */
864
+ readonly host: SpindleHostDescriptorV1;
865
+ /** Synchronous host locale access with removable live-change subscriptions. */
866
+ readonly locale: SpindleHostLocaleAPI;
862
867
  dom: SpindleDOMHelper;
863
868
  events: {
864
869
  on(event: string, handler: (payload: unknown) => void): () => void;
@@ -923,6 +928,8 @@ export interface SpindleFrontendContext {
923
928
  showConfirm(options: SpindleConfirmOptions): Promise<SpindleConfirmResult>;
924
929
  /** Request a tab move to a specific drawer location. */
925
930
  requestTabLocation(tabId: string, location: SpindleTabLocation): void;
931
+ /** Read the current drawer location for a built-in or extension tab. */
932
+ getTabLocation(tabId: string): SpindleTabLocation;
926
933
  /** Get the display title of a built-in drawer tab by its id. */
927
934
  getBuiltInTabTitle(tabId: string): string | undefined;
928
935
  /** Get the root HTMLElement of a built-in drawer tab by its id, or undefined if not mounted. */
@@ -1045,8 +1052,13 @@ export interface SpindleFrontendContext {
1045
1052
  manifest: import("./manifest").SpindleManifest;
1046
1053
  }
1047
1054
 
1055
+ /** Cleanup returned by a frontend extension setup hook. */
1056
+ export type SpindleFrontendTeardown = () => void | Promise<void>;
1057
+
1048
1058
  /** What a frontend extension module must export */
1049
1059
  export interface SpindleFrontendModule {
1050
- setup(ctx: SpindleFrontendContext): void | (() => void);
1051
- teardown?(): void;
1060
+ setup(
1061
+ ctx: SpindleFrontendContext,
1062
+ ): void | SpindleFrontendTeardown | Promise<void | SpindleFrontendTeardown>;
1063
+ teardown?(): void | Promise<void>;
1052
1064
  }
package/src/host.ts ADDED
@@ -0,0 +1,32 @@
1
+ export const SPINDLE_HOST_CAPABILITIES = Object.freeze({
2
+ "preset-extension-data-v1": 1,
3
+ "preset-editor-v1": 1,
4
+ "loom-block-editor-v1": 1,
5
+ "generation-assembly-v1": 1,
6
+ "interceptor-context-v1": 1,
7
+ "interceptor-final-response-v1": 1,
8
+ }) as Readonly<Record<string, number>>;
9
+ /** Structured error code returned when host compatibility validation fails. */
10
+ export const SPINDLE_COMPATIBILITY_ERROR_CODE = "SPINDLE_COMPATIBILITY_ERROR" as const;
11
+
12
+ /**
13
+ * Immutable host/runtime compatibility information exposed to extensions.
14
+ *
15
+ * Hosts may add capability keys over time. Extensions should only depend on
16
+ * the capability names they understand and the descriptor version they support.
17
+ */
18
+ export interface SpindleHostDescriptorV1 {
19
+ readonly descriptorVersion: 1;
20
+ readonly lumiverseVersion: string;
21
+ readonly capabilities: Readonly<Record<string, number>>;
22
+ readonly extensionInstallationId: string;
23
+ }
24
+
25
+ /** Locale identifiers supplied by the host's active UI locale. */
26
+ export type SpindleHostLocale = "en" | "zh" | "zh-TW" | "ja" | "fr" | "it";
27
+
28
+ /** Synchronous host locale lookup with a removable live-change subscription. */
29
+ export interface SpindleHostLocaleAPI {
30
+ get(): SpindleHostLocale;
31
+ subscribe(listener: (locale: SpindleHostLocale) => void): () => void;
32
+ }
package/src/index.ts CHANGED
@@ -8,6 +8,16 @@ export {
8
8
  validateIdentifier,
9
9
  } from "./manifest";
10
10
 
11
+ export type {
12
+ SpindleHostDescriptorV1,
13
+ SpindleHostLocale,
14
+ SpindleHostLocaleAPI,
15
+ } from "./host";
16
+ export {
17
+ SPINDLE_HOST_CAPABILITIES,
18
+ SPINDLE_COMPATIBILITY_ERROR_CODE,
19
+ } from "./host";
20
+
11
21
  export type { SpindlePermission as SpindlePermissionType } from "./permissions";
12
22
  export { ALL_PERMISSIONS, isValidPermission } from "./permissions";
13
23
 
@@ -18,8 +28,19 @@ export { SpindleEvent, CoreEventType } from "./events";
18
28
 
19
29
  export type {
20
30
  LlmMessageDTO,
31
+ LlmThinkingBlockDTO,
21
32
  SpindleUserRoleDTO,
33
+ InterceptorGenerationType,
34
+ InterceptorMatchScalar,
35
+ InterceptorMatchDTO,
36
+ InterceptorRegistrationMatchOptions,
37
+ InterceptorRegistrationOptions,
38
+ InterceptorContextDTO,
39
+ InterceptorDisposer,
40
+ InterceptorHandler,
41
+ DeferredGuidanceDTO,
22
42
  InterceptorBreakdownEntryDTO,
43
+ FinalResponseDTO,
23
44
  InterceptorResultDTO,
24
45
  MacroDefinitionDTO,
25
46
  MacroInvocationContextDTO,
@@ -28,6 +49,11 @@ export type {
28
49
  ToolRegistrationDTO,
29
50
  ToolSchemaDTO,
30
51
  ToolCallDTO,
52
+ ToolDefinitionDTO,
53
+ GenerationUsageDTO,
54
+ GenerationResponseDTO,
55
+ GenerationDispatchSourceDTO,
56
+ ConnectionDispatchDescriptorDTO,
31
57
  GenerationRequestDTO,
32
58
  GenerationReasoningOverrideDTO,
33
59
  ReasoningEffortDTO,
@@ -112,6 +138,14 @@ export type {
112
138
  DryRunResultDTO,
113
139
  AssembleRequestDTO,
114
140
  AssembleResultDTO,
141
+ BoundPrefillAttachmentDTO,
142
+ BoundAssembleRequestDTO,
143
+ BoundAssemblySuccessDTO,
144
+ BoundAssemblyFailureDTO,
145
+ BoundAssemblyOutcomeDTO,
146
+ QuietTrackedRequestDTO,
147
+ QuietDispatchReceiptDTO,
148
+ QuietTrackedResultDTO,
115
149
  AssemblyBreakdownEntryDTO,
116
150
  ActivationStatsDTO,
117
151
  MemoryStatsDTO,
@@ -121,9 +155,14 @@ export type {
121
155
  ImageGenConnectionDTO,
122
156
  ImageGenParameterSchemaDTO,
123
157
  ImageGenProviderDTO,
124
- ImageGenRequestDTO,
125
- ImageGenResultDTO,
126
- ImageGetOptionsDTO,
158
+ ImageGenRequestDTO,
159
+ ImageGenResultDTO,
160
+ ImageGenStreamRequestDTO,
161
+ ImageGenStreamStatusDTO,
162
+ ImageGenStreamPreviewDTO,
163
+ ImageGenStreamDoneDTO,
164
+ ImageGenStreamEventDTO,
165
+ ImageGetOptionsDTO,
127
166
  ImageDTO,
128
167
  ImageListOptionsDTO,
129
168
  ImageSpecificityDTO,
@@ -216,6 +255,7 @@ export type {
216
255
  PermissionRequestOptions,
217
256
  SpindleFrontendContext,
218
257
  SpindleFrontendModule,
258
+ SpindleFrontendTeardown,
219
259
  SpindleDrawerTabOptions,
220
260
  SpindleDrawerTabHandle,
221
261
  SpindleCharacterEditorTabOptions,
@@ -381,6 +421,8 @@ export type {
381
421
 
382
422
  export type {
383
423
  SpindleAPI,
424
+ SpindleGenerateAPI,
425
+ SpindleConnectionsAPI,
384
426
  SpindlePromptRegex,
385
427
  FrontendProcessHandle,
386
428
  BackendProcessHandle,