lumiverse-spindle-types 0.3.8 → 0.3.9
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 +1 -1
- package/src/api.ts +57 -1
- package/src/index.ts +2 -0
- package/src/spindle-api.ts +67 -0
package/package.json
CHANGED
package/src/api.ts
CHANGED
|
@@ -640,6 +640,53 @@ export type SpindleModalItemDTO =
|
|
|
640
640
|
/** A themed card/container that groups child items. */
|
|
641
641
|
| { type: "card"; items: SpindleModalItemDTO[] };
|
|
642
642
|
|
|
643
|
+
// ─── Command Palette DTOs ──────────────────────────────────────────────
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
* Command registration payload sent by extensions to add entries
|
|
647
|
+
* to the Lumiverse command palette (Cmd/Ctrl+K).
|
|
648
|
+
*
|
|
649
|
+
* Commands are contextual — extensions can register different sets
|
|
650
|
+
* based on the current chat, page, or app state by calling
|
|
651
|
+
* `spindle.commands.register()` with an updated list at any time.
|
|
652
|
+
* Each call replaces all previously registered commands from that extension.
|
|
653
|
+
*/
|
|
654
|
+
export interface SpindleCommandDTO {
|
|
655
|
+
/** Unique identifier for this command within the extension (e.g. `"summarize-chat"`). */
|
|
656
|
+
id: string;
|
|
657
|
+
/** Display label shown in the command palette. Max 80 characters. */
|
|
658
|
+
label: string;
|
|
659
|
+
/** Description shown below the label. Max 200 characters. */
|
|
660
|
+
description: string;
|
|
661
|
+
/** Optional search keywords for fuzzy matching. Max 10 keywords, 30 chars each. */
|
|
662
|
+
keywords?: string[];
|
|
663
|
+
/**
|
|
664
|
+
* Scope restriction controlling when the command appears.
|
|
665
|
+
* - `'global'` — always visible (default)
|
|
666
|
+
* - `'chat'` — only when viewing a chat
|
|
667
|
+
* - `'chat-idle'` — only when in a chat and not streaming
|
|
668
|
+
* - `'landing'` — only on the home page
|
|
669
|
+
* - `'character'` — only on character pages
|
|
670
|
+
*/
|
|
671
|
+
scope?: "global" | "chat" | "chat-idle" | "landing" | "character";
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
/**
|
|
675
|
+
* Context snapshot sent to the extension when a command is invoked
|
|
676
|
+
* from the command palette. Contains the frontend's current UI state
|
|
677
|
+
* so the extension can act on the right chat/character/page.
|
|
678
|
+
*/
|
|
679
|
+
export interface SpindleCommandContextDTO {
|
|
680
|
+
/** Current route path (e.g. `"/chat/abc-123"`, `"/"`, `"/characters/xyz"`). */
|
|
681
|
+
route: string;
|
|
682
|
+
/** Active chat ID, if the user is in a chat view. */
|
|
683
|
+
chatId?: string;
|
|
684
|
+
/** Active character ID, if available. */
|
|
685
|
+
characterId?: string;
|
|
686
|
+
/** Whether the active chat is a group chat. */
|
|
687
|
+
isGroupChat?: boolean;
|
|
688
|
+
}
|
|
689
|
+
|
|
643
690
|
// ─── Worker → Host messages ──────────────────────────────────────────────
|
|
644
691
|
|
|
645
692
|
export type WorkerToHost =
|
|
@@ -883,7 +930,10 @@ export type WorkerToHost =
|
|
|
883
930
|
| { type: "theme_clear"; requestId: string; userId?: string }
|
|
884
931
|
| { type: "theme_get_current"; requestId: string; userId?: string }
|
|
885
932
|
// ─── Color Extraction (gated: "app_manipulation") ─────────────────────
|
|
886
|
-
| { type: "color_extract"; requestId: string; imageId: string; userId?: string }
|
|
933
|
+
| { type: "color_extract"; requestId: string; imageId: string; userId?: string }
|
|
934
|
+
// ─── Commands (free tier) ──────────────────────────────────────────────
|
|
935
|
+
| { type: "commands_register"; commands: SpindleCommandDTO[] }
|
|
936
|
+
| { type: "commands_unregister"; commandIds: string[] };
|
|
887
937
|
|
|
888
938
|
// ─── Host → Worker messages ──────────────────────────────────────────────
|
|
889
939
|
|
|
@@ -930,4 +980,10 @@ export type HostToWorker =
|
|
|
930
980
|
type: "oauth_callback";
|
|
931
981
|
requestId: string;
|
|
932
982
|
params: Record<string, string>;
|
|
983
|
+
}
|
|
984
|
+
| {
|
|
985
|
+
type: "command_invoked";
|
|
986
|
+
commandId: string;
|
|
987
|
+
context: SpindleCommandContextDTO;
|
|
988
|
+
userId: string;
|
|
933
989
|
};
|
package/src/index.ts
CHANGED
package/src/spindle-api.ts
CHANGED
|
@@ -34,6 +34,8 @@ import type {
|
|
|
34
34
|
ThemeInfoDTO,
|
|
35
35
|
ColorExtractionResult,
|
|
36
36
|
SpindleModalItemDTO,
|
|
37
|
+
SpindleCommandDTO,
|
|
38
|
+
SpindleCommandContextDTO,
|
|
37
39
|
} from "./api";
|
|
38
40
|
|
|
39
41
|
/** The global `spindle` object available in backend extension workers */
|
|
@@ -728,6 +730,71 @@ export interface SpindleAPI {
|
|
|
728
730
|
}>;
|
|
729
731
|
};
|
|
730
732
|
|
|
733
|
+
/**
|
|
734
|
+
* Command palette integration (free tier — no permission needed).
|
|
735
|
+
* Register commands that appear in the Lumiverse command palette
|
|
736
|
+
* (Cmd/Ctrl+K). Commands are contextual — call `register()` with
|
|
737
|
+
* an updated list whenever the available commands should change
|
|
738
|
+
* (e.g. based on active chat, character, or extension state).
|
|
739
|
+
*
|
|
740
|
+
* Each `register()` call **replaces** all previously registered
|
|
741
|
+
* commands from this extension. To add commands incrementally,
|
|
742
|
+
* maintain your own list and pass the full set each time.
|
|
743
|
+
*
|
|
744
|
+
* @example
|
|
745
|
+
* ```ts
|
|
746
|
+
* // Register commands
|
|
747
|
+
* spindle.commands.register([
|
|
748
|
+
* {
|
|
749
|
+
* id: 'summarize-chat',
|
|
750
|
+
* label: 'Summarize Chat',
|
|
751
|
+
* description: 'Generate a summary of the current conversation',
|
|
752
|
+
* keywords: ['summary', 'recap', 'tldr'],
|
|
753
|
+
* scope: 'chat',
|
|
754
|
+
* },
|
|
755
|
+
* ])
|
|
756
|
+
*
|
|
757
|
+
* // Handle invocations
|
|
758
|
+
* spindle.commands.onInvoked((commandId, context) => {
|
|
759
|
+
* if (commandId === 'summarize-chat') {
|
|
760
|
+
* // context.chatId, context.characterId, etc.
|
|
761
|
+
* }
|
|
762
|
+
* })
|
|
763
|
+
*
|
|
764
|
+
* // Update commands based on context
|
|
765
|
+
* spindle.on('CHAT_CHANGED', () => {
|
|
766
|
+
* spindle.commands.register(getCommandsForCurrentState())
|
|
767
|
+
* })
|
|
768
|
+
*
|
|
769
|
+
* // Remove all commands
|
|
770
|
+
* spindle.commands.unregister()
|
|
771
|
+
* ```
|
|
772
|
+
*/
|
|
773
|
+
commands: {
|
|
774
|
+
/**
|
|
775
|
+
* Register (or replace) the extension's command palette entries.
|
|
776
|
+
* Each call replaces the full set — pass the complete list of
|
|
777
|
+
* commands you want visible. Max 20 commands per extension.
|
|
778
|
+
*/
|
|
779
|
+
register(commands: SpindleCommandDTO[]): void;
|
|
780
|
+
/**
|
|
781
|
+
* Remove specific commands by ID, or all commands if no IDs given.
|
|
782
|
+
*/
|
|
783
|
+
unregister(commandIds?: string[]): void;
|
|
784
|
+
/**
|
|
785
|
+
* Register a handler called when the user selects one of this
|
|
786
|
+
* extension's commands from the palette. The handler receives
|
|
787
|
+
* the command ID and a snapshot of the frontend's current state.
|
|
788
|
+
* Returns an unsubscribe function.
|
|
789
|
+
*/
|
|
790
|
+
onInvoked(
|
|
791
|
+
handler: (
|
|
792
|
+
commandId: string,
|
|
793
|
+
context: SpindleCommandContextDTO,
|
|
794
|
+
) => void | Promise<void>,
|
|
795
|
+
): () => void;
|
|
796
|
+
};
|
|
797
|
+
|
|
731
798
|
/** This extension's manifest */
|
|
732
799
|
manifest: SpindleManifest;
|
|
733
800
|
}
|