@portel/photon-core 2.1.2 → 2.3.0

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.
Files changed (76) hide show
  1. package/README.md +61 -0
  2. package/dist/base.d.ts +42 -2
  3. package/dist/base.d.ts.map +1 -1
  4. package/dist/base.js +75 -7
  5. package/dist/base.js.map +1 -1
  6. package/dist/channels/daemon-broker.d.ts +35 -0
  7. package/dist/channels/daemon-broker.d.ts.map +1 -0
  8. package/dist/channels/daemon-broker.js +229 -0
  9. package/dist/channels/daemon-broker.js.map +1 -0
  10. package/dist/channels/http-broker.d.ts +45 -0
  11. package/dist/channels/http-broker.d.ts.map +1 -0
  12. package/dist/channels/http-broker.js +182 -0
  13. package/dist/channels/http-broker.js.map +1 -0
  14. package/dist/channels/index.d.ts +53 -0
  15. package/dist/channels/index.d.ts.map +1 -0
  16. package/dist/channels/index.js +67 -0
  17. package/dist/channels/index.js.map +1 -0
  18. package/dist/channels/noop-broker.d.ts +21 -0
  19. package/dist/channels/noop-broker.d.ts.map +1 -0
  20. package/dist/channels/noop-broker.js +38 -0
  21. package/dist/channels/noop-broker.js.map +1 -0
  22. package/dist/channels/redis-broker.d.ts +45 -0
  23. package/dist/channels/redis-broker.d.ts.map +1 -0
  24. package/dist/channels/redis-broker.js +214 -0
  25. package/dist/channels/redis-broker.js.map +1 -0
  26. package/dist/channels/registry.d.ts +49 -0
  27. package/dist/channels/registry.d.ts.map +1 -0
  28. package/dist/channels/registry.js +150 -0
  29. package/dist/channels/registry.js.map +1 -0
  30. package/dist/channels/types.d.ts +85 -0
  31. package/dist/channels/types.d.ts.map +1 -0
  32. package/dist/channels/types.js +8 -0
  33. package/dist/channels/types.js.map +1 -0
  34. package/dist/config.d.ts +63 -0
  35. package/dist/config.d.ts.map +1 -0
  36. package/dist/config.js +117 -0
  37. package/dist/config.js.map +1 -0
  38. package/dist/decorators.d.ts +48 -0
  39. package/dist/decorators.d.ts.map +1 -0
  40. package/dist/decorators.js +64 -0
  41. package/dist/decorators.js.map +1 -0
  42. package/dist/design-system/tokens.d.ts +66 -0
  43. package/dist/design-system/tokens.d.ts.map +1 -1
  44. package/dist/design-system/tokens.js +324 -44
  45. package/dist/design-system/tokens.js.map +1 -1
  46. package/dist/index.d.ts +4 -0
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +12 -0
  49. package/dist/index.js.map +1 -1
  50. package/dist/mcp-apps.d.ts +130 -0
  51. package/dist/mcp-apps.d.ts.map +1 -0
  52. package/dist/mcp-apps.js +87 -0
  53. package/dist/mcp-apps.js.map +1 -0
  54. package/dist/schema-extractor.d.ts +41 -3
  55. package/dist/schema-extractor.d.ts.map +1 -1
  56. package/dist/schema-extractor.js +166 -14
  57. package/dist/schema-extractor.js.map +1 -1
  58. package/dist/types.d.ts +91 -0
  59. package/dist/types.d.ts.map +1 -1
  60. package/dist/types.js.map +1 -1
  61. package/package.json +15 -3
  62. package/src/base.ts +82 -6
  63. package/src/channels/daemon-broker.ts +271 -0
  64. package/src/channels/http-broker.ts +221 -0
  65. package/src/channels/index.ts +96 -0
  66. package/src/channels/noop-broker.ts +47 -0
  67. package/src/channels/redis-broker.ts +252 -0
  68. package/src/channels/registry.ts +170 -0
  69. package/src/channels/types.ts +95 -0
  70. package/src/config.ts +134 -0
  71. package/src/decorators.ts +87 -0
  72. package/src/design-system/tokens.ts +381 -57
  73. package/src/index.ts +39 -0
  74. package/src/mcp-apps.ts +204 -0
  75. package/src/schema-extractor.ts +191 -15
  76. package/src/types.ts +103 -0
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Photon Lock Helpers
3
+ *
4
+ * Runtime support for distributed locking via daemon.
5
+ * The @locked docblock tag and this.withLock() helper both use this.
6
+ */
7
+
8
+ // ============================================================================
9
+ // Lock Manager Interface
10
+ // ============================================================================
11
+
12
+ /**
13
+ * Interface for lock management
14
+ * Implemented by daemon client or other providers
15
+ */
16
+ export interface LockManager {
17
+ acquire(lockName: string, timeout?: number): Promise<boolean>;
18
+ release(lockName: string): Promise<boolean>;
19
+ }
20
+
21
+ let _lockManager: LockManager | null = null;
22
+
23
+ /**
24
+ * Set the global lock manager (called by runtime)
25
+ * @internal
26
+ */
27
+ export function setLockManager(manager: LockManager | null): void {
28
+ _lockManager = manager;
29
+ }
30
+
31
+ /**
32
+ * Get the current lock manager
33
+ * @internal
34
+ */
35
+ export function getLockManager(): LockManager | null {
36
+ return _lockManager;
37
+ }
38
+
39
+ // ============================================================================
40
+ // withLock Helper
41
+ // ============================================================================
42
+
43
+ /**
44
+ * Execute a function with a distributed lock
45
+ *
46
+ * Use this for fine-grained locking within a method, or when you
47
+ * need dynamic lock names.
48
+ *
49
+ * @param lockName Name of the lock to acquire
50
+ * @param fn Function to execute while holding the lock
51
+ * @param timeout Optional lock timeout in ms (default 30000)
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * async moveTask(params: { taskId: string; column: string }) {
56
+ * return this.withLock(`task:${params.taskId}`, async () => {
57
+ * const task = await this.loadTask(params.taskId);
58
+ * task.column = params.column;
59
+ * await this.saveTask(task);
60
+ * return task;
61
+ * });
62
+ * }
63
+ * ```
64
+ */
65
+ export async function withLock<T>(
66
+ lockName: string,
67
+ fn: () => Promise<T>,
68
+ timeout?: number
69
+ ): Promise<T> {
70
+ const lockManager = getLockManager();
71
+
72
+ if (!lockManager) {
73
+ // No lock manager, run without lock
74
+ return fn();
75
+ }
76
+
77
+ const acquired = await lockManager.acquire(lockName, timeout);
78
+ if (!acquired) {
79
+ throw new Error(`Could not acquire lock: ${lockName}`);
80
+ }
81
+
82
+ try {
83
+ return await fn();
84
+ } finally {
85
+ await lockManager.release(lockName);
86
+ }
87
+ }
@@ -15,15 +15,15 @@
15
15
  export const spacing = {
16
16
  // Base unit: 4px (for fine adjustments)
17
17
  '0': '0',
18
- '1': '4px', // xs - minimal spacing
19
- '2': '8px', // sm - tight spacing
20
- '3': '12px', // md - default spacing
21
- '4': '16px', // lg - comfortable spacing
22
- '5': '20px', // xl - generous spacing
23
- '6': '24px', // 2xl - section spacing
24
- '8': '32px', // 3xl - large section spacing
25
- '10': '40px', // 4xl - hero spacing
26
- '12': '48px', // 5xl - page spacing
18
+ '1': '4px', // xs - minimal spacing
19
+ '2': '8px', // sm - tight spacing
20
+ '3': '12px', // md - default spacing
21
+ '4': '16px', // lg - comfortable spacing
22
+ '5': '20px', // xl - generous spacing
23
+ '6': '24px', // 2xl - section spacing
24
+ '8': '32px', // 3xl - large section spacing
25
+ '10': '40px', // 4xl - hero spacing
26
+ '12': '48px', // 5xl - page spacing
27
27
  } as const;
28
28
 
29
29
  // Semantic spacing aliases
@@ -179,8 +179,8 @@ const colorPalette = {
179
179
  },
180
180
  } as const;
181
181
 
182
- // System colors (semantic tokens - what components use)
183
- export const colors = {
182
+ // System colors - Dark Theme (default)
183
+ export const colorsDark = {
184
184
  // Surfaces
185
185
  surface: colorPalette.neutral[5],
186
186
  surfaceContainer: colorPalette.neutral[10],
@@ -225,6 +225,66 @@ export const colors = {
225
225
  scrim: 'rgba(0, 0, 0, 0.5)',
226
226
  } as const;
227
227
 
228
+ // System colors - Light Theme
229
+ export const colorsLight = {
230
+ // Surfaces (inverted - light backgrounds)
231
+ surface: colorPalette.neutral[100], // white
232
+ surfaceContainer: colorPalette.neutral[95],
233
+ surfaceContainerHigh: colorPalette.neutral[90],
234
+ surfaceContainerHighest: colorPalette.neutral[80],
235
+ surfaceBright: colorPalette.neutral[100],
236
+
237
+ // Text on surfaces (dark text on light)
238
+ onSurface: colorPalette.neutral[10],
239
+ onSurfaceVariant: colorPalette.neutral[30],
240
+ onSurfaceMuted: colorPalette.neutral[50],
241
+
242
+ // Primary (darker for light theme)
243
+ primary: colorPalette.primary[40],
244
+ primaryContainer: colorPalette.primary[90],
245
+ onPrimary: colorPalette.neutral[100], // white text on primary
246
+ onPrimaryContainer: colorPalette.primary[10],
247
+
248
+ // Success
249
+ success: colorPalette.success[40],
250
+ successContainer: colorPalette.success[90],
251
+ onSuccess: colorPalette.neutral[100], // white text
252
+ onSuccessContainer: colorPalette.success[10],
253
+
254
+ // Warning
255
+ warning: colorPalette.warning[40],
256
+ warningContainer: colorPalette.warning[90],
257
+ onWarning: colorPalette.neutral[100], // white text
258
+ onWarningContainer: colorPalette.warning[10],
259
+
260
+ // Error
261
+ error: colorPalette.error[40],
262
+ errorContainer: colorPalette.error[90],
263
+ onError: colorPalette.neutral[100], // white text
264
+ onErrorContainer: colorPalette.error[10],
265
+
266
+ // Outline (darker for light theme)
267
+ outline: colorPalette.neutral[50],
268
+ outlineVariant: colorPalette.neutral[80],
269
+
270
+ // Scrim (overlay)
271
+ scrim: 'rgba(0, 0, 0, 0.3)' as const,
272
+ };
273
+
274
+ // Default export (dark theme for backwards compatibility)
275
+ export const colors = colorsDark;
276
+
277
+ // Theme type
278
+ export type ThemeMode = 'light' | 'dark' | 'system';
279
+
280
+ // Theme colors type (union of both)
281
+ export type ThemeColors = typeof colorsDark | typeof colorsLight;
282
+
283
+ // Get colors for a specific theme
284
+ export function getThemeColors(theme: 'light' | 'dark'): ThemeColors {
285
+ return theme === 'light' ? colorsLight : colorsDark;
286
+ }
287
+
228
288
  // =============================================================================
229
289
  // ELEVATION - Material Design 3 Shadows
230
290
  // =============================================================================
@@ -244,10 +304,10 @@ export const elevation = {
244
304
 
245
305
  export const radius = {
246
306
  none: '0',
247
- sm: '6px', // Small elements (chips, badges)
248
- md: '10px', // Cards, inputs (iOS default)
249
- lg: '14px', // Large cards
250
- xl: '20px', // Modal, sheet
307
+ sm: '6px', // Small elements (chips, badges)
308
+ md: '10px', // Cards, inputs (iOS default)
309
+ lg: '14px', // Large cards
310
+ xl: '20px', // Modal, sheet
251
311
  full: '9999px', // Pills, circles
252
312
  } as const;
253
313
 
@@ -299,11 +359,61 @@ export const zIndex = {
299
359
  // CSS CUSTOM PROPERTIES GENERATOR
300
360
  // =============================================================================
301
361
 
362
+ /**
363
+ * Generate color CSS variables for a specific theme
364
+ */
365
+ function generateColorVars(themeColors: ThemeColors): string {
366
+ return `
367
+ /* Colors - Surfaces */
368
+ --color-surface: ${themeColors.surface};
369
+ --color-surface-container: ${themeColors.surfaceContainer};
370
+ --color-surface-container-high: ${themeColors.surfaceContainerHigh};
371
+ --color-surface-container-highest: ${themeColors.surfaceContainerHighest};
372
+ --color-surface-bright: ${themeColors.surfaceBright};
373
+
374
+ /* Colors - Text */
375
+ --color-on-surface: ${themeColors.onSurface};
376
+ --color-on-surface-variant: ${themeColors.onSurfaceVariant};
377
+ --color-on-surface-muted: ${themeColors.onSurfaceMuted};
378
+
379
+ /* Colors - Primary */
380
+ --color-primary: ${themeColors.primary};
381
+ --color-primary-container: ${themeColors.primaryContainer};
382
+ --color-on-primary: ${themeColors.onPrimary};
383
+ --color-on-primary-container: ${themeColors.onPrimaryContainer};
384
+
385
+ /* Colors - Success */
386
+ --color-success: ${themeColors.success};
387
+ --color-success-container: ${themeColors.successContainer};
388
+ --color-on-success: ${themeColors.onSuccess};
389
+ --color-on-success-container: ${themeColors.onSuccessContainer};
390
+
391
+ /* Colors - Warning */
392
+ --color-warning: ${themeColors.warning};
393
+ --color-warning-container: ${themeColors.warningContainer};
394
+ --color-on-warning: ${themeColors.onWarning};
395
+ --color-on-warning-container: ${themeColors.onWarningContainer};
396
+
397
+ /* Colors - Error */
398
+ --color-error: ${themeColors.error};
399
+ --color-error-container: ${themeColors.errorContainer};
400
+ --color-on-error: ${themeColors.onError};
401
+ --color-on-error-container: ${themeColors.onErrorContainer};
402
+
403
+ /* Colors - Outline */
404
+ --color-outline: ${themeColors.outline};
405
+ --color-outline-variant: ${themeColors.outlineVariant};
406
+
407
+ /* Colors - Scrim */
408
+ --color-scrim: ${themeColors.scrim};`;
409
+ }
410
+
302
411
  export function generateTokensCSS(): string {
303
412
  return `
304
413
  /* ==========================================================================
305
414
  Photon Design System - Design Tokens
306
415
  Based on Material Design 3 + Apple HIG
416
+ Supports: dark (default), light, system preference
307
417
  ========================================================================== */
308
418
 
309
419
  :root {
@@ -363,48 +473,8 @@ export function generateTokensCSS(): string {
363
473
  --weight-semibold: ${fontWeight.semibold};
364
474
  --weight-bold: ${fontWeight.bold};
365
475
 
366
- /* Colors - Surfaces */
367
- --color-surface: ${colors.surface};
368
- --color-surface-container: ${colors.surfaceContainer};
369
- --color-surface-container-high: ${colors.surfaceContainerHigh};
370
- --color-surface-container-highest: ${colors.surfaceContainerHighest};
371
- --color-surface-bright: ${colors.surfaceBright};
372
-
373
- /* Colors - Text */
374
- --color-on-surface: ${colors.onSurface};
375
- --color-on-surface-variant: ${colors.onSurfaceVariant};
376
- --color-on-surface-muted: ${colors.onSurfaceMuted};
377
-
378
- /* Colors - Primary */
379
- --color-primary: ${colors.primary};
380
- --color-primary-container: ${colors.primaryContainer};
381
- --color-on-primary: ${colors.onPrimary};
382
- --color-on-primary-container: ${colors.onPrimaryContainer};
383
-
384
- /* Colors - Success */
385
- --color-success: ${colors.success};
386
- --color-success-container: ${colors.successContainer};
387
- --color-on-success: ${colors.onSuccess};
388
- --color-on-success-container: ${colors.onSuccessContainer};
389
-
390
- /* Colors - Warning */
391
- --color-warning: ${colors.warning};
392
- --color-warning-container: ${colors.warningContainer};
393
- --color-on-warning: ${colors.onWarning};
394
- --color-on-warning-container: ${colors.onWarningContainer};
395
-
396
- /* Colors - Error */
397
- --color-error: ${colors.error};
398
- --color-error-container: ${colors.errorContainer};
399
- --color-on-error: ${colors.onError};
400
- --color-on-error-container: ${colors.onErrorContainer};
401
-
402
- /* Colors - Outline */
403
- --color-outline: ${colors.outline};
404
- --color-outline-variant: ${colors.outlineVariant};
405
-
406
- /* Colors - Scrim */
407
- --color-scrim: ${colors.scrim};
476
+ /* Default: Dark Theme Colors */
477
+ ${generateColorVars(colorsDark)}
408
478
 
409
479
  /* Elevation */
410
480
  --elevation-0: ${elevation['0']};
@@ -447,5 +517,259 @@ export function generateTokensCSS(): string {
447
517
  --z-popover: ${zIndex.popover};
448
518
  --z-toast: ${zIndex.toast};
449
519
  }
520
+
521
+ /* Light Theme Override */
522
+ [data-theme="light"],
523
+ .light {
524
+ ${generateColorVars(colorsLight)}
525
+ }
526
+
527
+ /* System Preference: Light Mode */
528
+ @media (prefers-color-scheme: light) {
529
+ [data-theme="system"] {
530
+ ${generateColorVars(colorsLight)}
531
+ }
532
+ }
450
533
  `;
451
534
  }
535
+
536
+ // =============================================================================
537
+ // THEME TOKENS FOR MCP APPS / PLATFORM BRIDGES
538
+ // =============================================================================
539
+
540
+ /**
541
+ * Get theme tokens as a flat object for MCP Apps ui/initialize
542
+ * Compatible with OpenAI Apps SDK and MCP Apps Extension (SEP-1865)
543
+ */
544
+ export function getThemeTokens(theme: 'light' | 'dark'): Record<string, string> {
545
+ const themeColors = theme === 'light' ? colorsLight : colorsDark;
546
+
547
+ return {
548
+ // ═══════════════════════════════════════════════════════════════════════
549
+ // DESIGN SYSTEM TOKENS (Material Design 3 naming)
550
+ // ═══════════════════════════════════════════════════════════════════════
551
+
552
+ // Colors
553
+ '--color-surface': themeColors.surface,
554
+ '--color-surface-container': themeColors.surfaceContainer,
555
+ '--color-surface-container-high': themeColors.surfaceContainerHigh,
556
+ '--color-surface-container-highest': themeColors.surfaceContainerHighest,
557
+ '--color-surface-bright': themeColors.surfaceBright,
558
+ '--color-on-surface': themeColors.onSurface,
559
+ '--color-on-surface-variant': themeColors.onSurfaceVariant,
560
+ '--color-on-surface-muted': themeColors.onSurfaceMuted,
561
+ '--color-primary': themeColors.primary,
562
+ '--color-primary-container': themeColors.primaryContainer,
563
+ '--color-on-primary': themeColors.onPrimary,
564
+ '--color-on-primary-container': themeColors.onPrimaryContainer,
565
+ '--color-success': themeColors.success,
566
+ '--color-success-container': themeColors.successContainer,
567
+ '--color-on-success': themeColors.onSuccess,
568
+ '--color-on-success-container': themeColors.onSuccessContainer,
569
+ '--color-warning': themeColors.warning,
570
+ '--color-warning-container': themeColors.warningContainer,
571
+ '--color-on-warning': themeColors.onWarning,
572
+ '--color-on-warning-container': themeColors.onWarningContainer,
573
+ '--color-error': themeColors.error,
574
+ '--color-error-container': themeColors.errorContainer,
575
+ '--color-on-error': themeColors.onError,
576
+ '--color-on-error-container': themeColors.onErrorContainer,
577
+ '--color-outline': themeColors.outline,
578
+ '--color-outline-variant': themeColors.outlineVariant,
579
+ '--color-scrim': themeColors.scrim,
580
+
581
+ // Spacing
582
+ '--space-0': spacing['0'],
583
+ '--space-1': spacing['1'],
584
+ '--space-2': spacing['2'],
585
+ '--space-3': spacing['3'],
586
+ '--space-4': spacing['4'],
587
+ '--space-6': spacing['6'],
588
+ '--space-8': spacing['8'],
589
+
590
+ // Typography
591
+ '--font-sans': fontFamily.sans,
592
+ '--font-mono': fontFamily.mono,
593
+ '--text-body-md': fontSize['body-md'],
594
+ '--text-body-sm': fontSize['body-sm'],
595
+ '--text-title-md': fontSize['title-md'],
596
+ '--text-label-md': fontSize['label-md'],
597
+
598
+ // Border Radius
599
+ '--radius-sm': radius.sm,
600
+ '--radius-md': radius.md,
601
+ '--radius-lg': radius.lg,
602
+ '--radius-full': radius.full,
603
+
604
+ // ═══════════════════════════════════════════════════════════════════════
605
+ // COMMON ALIASES - For compatibility with various app conventions
606
+ // Apps use different naming conventions; these aliases ensure apps work
607
+ // regardless of whether they use --bg, --background, --bg-primary, etc.
608
+ // ═══════════════════════════════════════════════════════════════════════
609
+
610
+ // Background aliases (apps use: --bg, --background, --bg-primary, --bg-secondary)
611
+ '--bg': themeColors.surface,
612
+ '--background': themeColors.surface,
613
+ '--bg-primary': themeColors.surface,
614
+ '--bg-secondary': themeColors.surfaceContainer,
615
+ '--bg-tertiary': themeColors.surfaceContainerHigh,
616
+ '--bg-card': themeColors.surfaceContainer,
617
+ '--card': themeColors.surfaceContainer,
618
+ '--card-background': themeColors.surfaceContainer,
619
+
620
+ // Text/foreground aliases (apps use: --text, --foreground, --text-primary, --text-muted)
621
+ '--text': themeColors.onSurface,
622
+ '--foreground': themeColors.onSurface,
623
+ '--text-primary': themeColors.onSurface,
624
+ '--text-secondary': themeColors.onSurfaceVariant,
625
+ '--text-muted': themeColors.onSurfaceMuted,
626
+ '--muted': themeColors.onSurfaceMuted,
627
+ '--muted-foreground': themeColors.onSurfaceMuted,
628
+
629
+ // Border aliases (apps use: --border, --border-color)
630
+ '--border': themeColors.outline,
631
+ '--border-color': themeColors.outline,
632
+ '--border-muted': themeColors.outlineVariant,
633
+
634
+ // Accent/primary aliases (apps use: --accent, --primary, --accent-color)
635
+ '--accent': themeColors.primary,
636
+ '--primary': themeColors.primary,
637
+ '--accent-color': themeColors.primary,
638
+ '--accent-foreground': themeColors.onPrimary,
639
+ '--accent-hover': themeColors.primaryContainer,
640
+
641
+ // Status colors (common naming)
642
+ '--success': themeColors.success,
643
+ '--warning': themeColors.warning,
644
+ '--error': themeColors.error,
645
+ '--danger': themeColors.error,
646
+
647
+ // Input/form aliases
648
+ '--input': themeColors.surfaceContainerHigh,
649
+ '--input-border': themeColors.outline,
650
+ '--ring': themeColors.primary,
651
+
652
+ // ═══════════════════════════════════════════════════════════════════════
653
+ // MCP APPS STANDARD CSS VARIABLES (2026-01-26 spec)
654
+ // Maps standard names to closest Photon semantic tokens.
655
+ // Both Photon-native and standard MCP Apps names are emitted.
656
+ // ═══════════════════════════════════════════════════════════════════════
657
+
658
+ // --- Background Colors ---
659
+ '--color-background-primary': themeColors.surface,
660
+ '--color-background-secondary': themeColors.surfaceContainer,
661
+ '--color-background-tertiary': themeColors.surfaceContainerHigh,
662
+ '--color-background-inverse': themeColors.surfaceBright,
663
+ '--color-background-brand': themeColors.primary,
664
+ '--color-background-info': themeColors.primaryContainer,
665
+ '--color-background-danger': themeColors.errorContainer,
666
+ '--color-background-success': themeColors.successContainer,
667
+ '--color-background-warning': themeColors.warningContainer,
668
+ '--color-background-ghost': 'transparent',
669
+ '--color-background-disabled': themeColors.surfaceContainerHigh,
670
+
671
+ // --- Text Colors ---
672
+ '--color-text-primary': themeColors.onSurface,
673
+ '--color-text-secondary': themeColors.onSurfaceVariant,
674
+ '--color-text-tertiary': themeColors.onSurfaceMuted,
675
+ '--color-text-inverse': themeColors.onPrimary,
676
+ '--color-text-brand': themeColors.primary,
677
+ '--color-text-info': themeColors.primary,
678
+ '--color-text-danger': themeColors.error,
679
+ '--color-text-success': themeColors.success,
680
+ '--color-text-warning': themeColors.warning,
681
+ '--color-text-ghost': themeColors.onSurfaceVariant,
682
+ '--color-text-disabled': themeColors.onSurfaceMuted,
683
+ '--color-text-link': themeColors.primary,
684
+ '--color-text-on-brand': themeColors.onPrimary,
685
+ '--color-text-on-info': themeColors.onPrimaryContainer,
686
+ '--color-text-on-danger': themeColors.onErrorContainer,
687
+ '--color-text-on-success': themeColors.onSuccessContainer,
688
+ '--color-text-on-warning': themeColors.onWarningContainer,
689
+
690
+ // --- Border Colors ---
691
+ '--color-border-primary': themeColors.outline,
692
+ '--color-border-secondary': themeColors.outlineVariant,
693
+ '--color-border-brand': themeColors.primary,
694
+ '--color-border-info': themeColors.primary,
695
+ '--color-border-danger': themeColors.error,
696
+ '--color-border-success': themeColors.success,
697
+ '--color-border-warning': themeColors.warning,
698
+ '--color-border-disabled': themeColors.outlineVariant,
699
+ '--color-border-focus': themeColors.primary,
700
+
701
+ // --- Border Colors (additional spec variants) ---
702
+ '--color-border-tertiary': themeColors.outlineVariant,
703
+ '--color-border-inverse': themeColors.onSurface,
704
+ '--color-border-ghost': themeColors.outlineVariant,
705
+
706
+ // --- Ring (focus) ---
707
+ '--color-ring-primary': themeColors.primary,
708
+ '--color-ring-secondary': themeColors.outlineVariant,
709
+ '--color-ring-inverse': themeColors.onSurface,
710
+ '--color-ring-brand': themeColors.primary,
711
+ '--color-ring-info': themeColors.primary,
712
+ '--color-ring-danger': themeColors.error,
713
+ '--color-ring-success': themeColors.success,
714
+ '--color-ring-warning': themeColors.warning,
715
+
716
+ // --- Icon Colors ---
717
+ '--color-icon-primary': themeColors.onSurface,
718
+ '--color-icon-secondary': themeColors.onSurfaceVariant,
719
+ '--color-icon-brand': themeColors.primary,
720
+ '--color-icon-info': themeColors.primary,
721
+ '--color-icon-danger': themeColors.error,
722
+ '--color-icon-success': themeColors.success,
723
+ '--color-icon-warning': themeColors.warning,
724
+
725
+ // --- Font Weights ---
726
+ '--font-weight-normal': fontWeight.regular,
727
+ '--font-weight-medium': fontWeight.medium,
728
+ '--font-weight-semibold': fontWeight.semibold,
729
+ '--font-weight-bold': fontWeight.bold,
730
+
731
+ // --- Font Text Sizes ---
732
+ '--font-text-xs-size': fontSize['label-sm'],
733
+ '--font-text-xs-line-height': lineHeight['label-sm'],
734
+ '--font-text-sm-size': fontSize['body-sm'],
735
+ '--font-text-sm-line-height': lineHeight['body-sm'],
736
+ '--font-text-md-size': fontSize['body-md'],
737
+ '--font-text-md-line-height': lineHeight['body-md'],
738
+ '--font-text-lg-size': fontSize['body-lg'],
739
+ '--font-text-lg-line-height': lineHeight['body-lg'],
740
+
741
+ // --- Font Heading Sizes ---
742
+ '--font-heading-xs-size': fontSize['title-sm'],
743
+ '--font-heading-xs-line-height': lineHeight['title-sm'],
744
+ '--font-heading-sm-size': fontSize['title-md'],
745
+ '--font-heading-sm-line-height': lineHeight['title-md'],
746
+ '--font-heading-md-size': fontSize['title-lg'],
747
+ '--font-heading-md-line-height': lineHeight['title-lg'],
748
+ '--font-heading-lg-size': fontSize['headline-sm'],
749
+ '--font-heading-lg-line-height': lineHeight['headline-sm'],
750
+ '--font-heading-xl-size': fontSize['headline-md'],
751
+ '--font-heading-xl-line-height': lineHeight['headline-md'],
752
+ '--font-heading-2xl-size': fontSize['headline-lg'],
753
+ '--font-heading-2xl-line-height': lineHeight['headline-lg'],
754
+ '--font-heading-3xl-size': fontSize['display-sm'],
755
+ '--font-heading-3xl-line-height': lineHeight['display-sm'],
756
+
757
+ // --- Border Radius ---
758
+ '--border-radius-xs': '4px',
759
+ '--border-radius-sm': radius.sm,
760
+ '--border-radius-md': radius.md,
761
+ '--border-radius-lg': radius.lg,
762
+ '--border-radius-xl': radius.xl,
763
+ '--border-radius-full': radius.full,
764
+
765
+ // --- Shadows ---
766
+ '--shadow-hairline': `0 0 0 1px ${themeColors.outlineVariant}`,
767
+ '--shadow-sm': elevation['1'],
768
+ '--shadow-md': elevation['2'],
769
+ '--shadow-lg': elevation['3'],
770
+
771
+ // --- Border Width ---
772
+ '--border-width-regular': '1px',
773
+ '--border-width-thick': '2px',
774
+ };
775
+ }
package/src/index.ts CHANGED
@@ -321,3 +321,42 @@ export * from './rendering/index.js';
321
321
  // ===== UCP (Universal Commerce Protocol) =====
322
322
  // Agentic commerce with checkout, identity, orders, and AP2 payments
323
323
  export * from './ucp/index.js';
324
+
325
+ // ===== CHANNEL-BASED PUB/SUB =====
326
+ // Cross-process messaging with pluggable brokers (daemon, Redis, HTTP, etc.)
327
+ export * from './channels/index.js';
328
+
329
+ // ===== LOCK HELPERS =====
330
+ // Runtime support for distributed locking via daemon
331
+ export {
332
+ withLock,
333
+ setLockManager,
334
+ getLockManager,
335
+ type LockManager,
336
+ } from './decorators.js';
337
+
338
+ // ===== MCP APPS STANDARD =====
339
+ // Types and helpers for MCP Apps Extension (2026-01-26) compliance
340
+ export {
341
+ type McpAppsInitialize,
342
+ type McpAppsToolInput,
343
+ type McpAppsToolResult,
344
+ type McpAppsHostContextChanged,
345
+ type McpAppsResourceTeardown,
346
+ type McpAppsModelContextUpdate,
347
+ type PlatformContext,
348
+ createMcpAppsInitialize,
349
+ createThemeChangeMessages,
350
+ } from './mcp-apps.js';
351
+
352
+ // ===== CONFIGURATION CONVENTION =====
353
+ // Utilities for photons implementing the configure() convention
354
+ export {
355
+ getPhotonConfigDir,
356
+ getPhotonConfigPath,
357
+ loadPhotonConfig,
358
+ savePhotonConfig,
359
+ hasPhotonConfig,
360
+ deletePhotonConfig,
361
+ listConfiguredPhotons,
362
+ } from './config.js';