lumiverse-spindle-types 0.3.1 → 0.3.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lumiverse-spindle-types",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "types": "./src/index.ts",
5
5
  "keywords": [
6
6
  "lumiverse",
package/src/api.ts CHANGED
@@ -491,6 +491,61 @@ export interface PermissionDeniedDetail {
491
491
  operation: string;
492
492
  }
493
493
 
494
+ // ─── Theme DTOs ──────────────────────────────────────────────────────────
495
+
496
+ /**
497
+ * Theme override payload sent by extensions to customize the UI appearance.
498
+ * Overrides are applied on top of the user's current theme and automatically
499
+ * removed when the extension is disabled or unloaded.
500
+ */
501
+ export interface ThemeOverrideDTO {
502
+ /**
503
+ * Direct CSS variable overrides. Keys are CSS custom property names
504
+ * (e.g. `--lumiverse-primary`, `--lumiverse-bg`, `--lcs-glass-bg`).
505
+ * Values must be valid CSS values.
506
+ *
507
+ * Common variable groups:
508
+ * - **Primary accent**: `--lumiverse-primary`, `--lumiverse-primary-hover`, `-text`, `-muted`, `-light`, `-010`…`-050`, `-contrast`
509
+ * - **Backgrounds**: `--lumiverse-bg`, `-elevated`, `-hover`, `-dark`, `-darker`, `-deep`, `-040`…`-070`
510
+ * - **Text**: `--lumiverse-text`, `-muted`, `-dim`, `-hint`
511
+ * - **Borders**: `--lumiverse-border`, `-hover`, `-light`, `-neutral`, `-neutral-hover`
512
+ * - **Status**: `--lumiverse-danger`, `--lumiverse-success`, `--lumiverse-warning` (+ `-015`, `-020`, `-050` variants)
513
+ * - **Glass**: `--lcs-glass-bg`, `-bg-hover`, `-border`, `-border-hover`, `-blur`, `-soft-blur`, `-strong-blur`
514
+ * - **Prose**: `--lumiverse-prose-italic`, `-bold`, `-dialogue`, `-blockquote`, `-link`
515
+ * - **Shadows**: `--lumiverse-shadow`, `-sm`, `-md`, `-lg`, `-xl`
516
+ * - **Radii**: `--lumiverse-radius`, `-sm`, `-md`, `-lg`, `-xl`, `--lcs-radius`, `-sm`, `-xs`
517
+ * - **Fills**: `--lumiverse-fill`, `-subtle`, `-hover`, `-medium`, `-strong`, `-heavy`, `-deepest`
518
+ * - **Cards**: `--lumiverse-card-bg`, `--lumiverse-card-image-bg`
519
+ * - **Icons**: `--lumiverse-icon`, `-muted`, `-dim`
520
+ * - **Modals**: `--lumiverse-modal-backdrop`, `--lumiverse-gradient-modal`, `--lumiverse-swatch-border`
521
+ * - **Typography**: `--lumiverse-font-family`, `--lumiverse-font-mono`, `--lumiverse-font-scale`
522
+ * - **Transitions**: `--lumiverse-transition`, `--lumiverse-transition-fast`, `--lcs-transition`, `--lcs-transition-fast`
523
+ */
524
+ variables?: Record<string, string>;
525
+ }
526
+
527
+ /**
528
+ * Read-only snapshot of the user's current theme configuration.
529
+ */
530
+ export interface ThemeInfoDTO {
531
+ /** Theme preset ID (e.g. `"lumiverse-purple"`, `"character-aware"`) */
532
+ id: string;
533
+ /** Display name of the theme */
534
+ name: string;
535
+ /** Resolved mode — always `"light"` or `"dark"`, never `"system"` */
536
+ mode: "light" | "dark";
537
+ /** Primary accent color in HSL (hue 0-360, saturation 0-100, lightness 0-100) */
538
+ accent: { h: number; s: number; l: number };
539
+ /** Whether glassmorphic backdrop-filter effects are enabled */
540
+ enableGlass: boolean;
541
+ /** Border radius multiplier (1.0 = default) */
542
+ radiusScale: number;
543
+ /** Font size multiplier (1.0 = default) */
544
+ fontScale: number;
545
+ /** Whether the theme dynamically adapts to the active character's avatar */
546
+ characterAware: boolean;
547
+ }
548
+
494
549
  // ─── Worker → Host messages ──────────────────────────────────────────────
495
550
 
496
551
  export type WorkerToHost =
@@ -725,7 +780,11 @@ export type WorkerToHost =
725
780
  | { type: "image_gen_providers"; requestId: string; userId?: string }
726
781
  | { type: "image_gen_connections_list"; requestId: string; userId?: string }
727
782
  | { type: "image_gen_connections_get"; requestId: string; connectionId: string; userId?: string }
728
- | { type: "image_gen_models"; requestId: string; connectionId: string; userId?: string };
783
+ | { type: "image_gen_models"; requestId: string; connectionId: string; userId?: string }
784
+ // ─── Theme (gated: "app_manipulation") ──────────────────────────────────
785
+ | { type: "theme_apply"; requestId: string; overrides: ThemeOverrideDTO; userId?: string }
786
+ | { type: "theme_clear"; requestId: string; userId?: string }
787
+ | { type: "theme_get_current"; requestId: string; userId?: string };
729
788
 
730
789
  // ─── Host → Worker messages ──────────────────────────────────────────────
731
790
 
package/src/index.ts CHANGED
@@ -50,6 +50,8 @@ export type {
50
50
  ImageGenProviderDTO,
51
51
  ImageGenRequestDTO,
52
52
  ImageGenResultDTO,
53
+ ThemeOverrideDTO,
54
+ ThemeInfoDTO,
53
55
  WorkerToHost,
54
56
  HostToWorker,
55
57
  } from "./api";
@@ -29,6 +29,8 @@ import type {
29
29
  ImageGenResultDTO,
30
30
  ImageGenConnectionDTO,
31
31
  ImageGenProviderDTO,
32
+ ThemeOverrideDTO,
33
+ ThemeInfoDTO,
32
34
  } from "./api";
33
35
 
34
36
  /** The global `spindle` object available in backend extension workers */
@@ -547,6 +549,52 @@ export interface SpindleAPI {
547
549
  createState(): Promise<string>;
548
550
  };
549
551
 
552
+ /**
553
+ * Theme manipulation (permission: "app_manipulation").
554
+ * Apply CSS variable overrides on top of the user's current theme.
555
+ * Overrides are scoped to the extension and automatically removed
556
+ * when the extension is disabled or unloaded.
557
+ *
558
+ * @example
559
+ * ```ts
560
+ * // Apply a blue-tinted theme
561
+ * await spindle.theme.apply({
562
+ * variables: {
563
+ * '--lumiverse-primary': 'hsl(210, 80%, 60%)',
564
+ * '--lumiverse-bg': 'hsl(210, 12%, 11%)',
565
+ * '--lumiverse-bg-elevated': 'hsl(210, 12%, 14%)',
566
+ * '--lcs-glass-bg': 'hsla(210, 12%, 6%, 0.55)',
567
+ * },
568
+ * })
569
+ *
570
+ * // Read current theme state
571
+ * const info = await spindle.theme.getCurrent()
572
+ * console.log(info.mode, info.accent)
573
+ *
574
+ * // Remove all overrides
575
+ * await spindle.theme.clear()
576
+ * ```
577
+ */
578
+ theme: {
579
+ /**
580
+ * Apply CSS variable overrides on top of the user's current theme.
581
+ * Subsequent calls merge with (and overwrite) any previously applied
582
+ * overrides from this extension. The frontend applies overrides
583
+ * immediately via a WebSocket event.
584
+ */
585
+ apply(overrides: ThemeOverrideDTO): Promise<void>;
586
+ /**
587
+ * Remove all CSS variable overrides previously applied by this extension.
588
+ * The UI reverts to the user's base theme.
589
+ */
590
+ clear(): Promise<void>;
591
+ /**
592
+ * Get a read-only snapshot of the user's current theme configuration.
593
+ * Returns the base theme info (not including any extension overrides).
594
+ */
595
+ getCurrent(userId?: string): Promise<ThemeInfoDTO>;
596
+ };
597
+
550
598
  /** This extension's manifest */
551
599
  manifest: SpindleManifest;
552
600
  }