@agent-relay/dashboard 2.0.82 → 2.0.84
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/out/404.html +1 -1
- package/out/_next/static/chunks/1028-da5d75e35d1420f1.js +1 -0
- package/out/_next/static/chunks/1528-78b17000a7e10bc6.js +2 -0
- package/out/_next/static/chunks/1695-4a5d33ba715e09b4.js +1 -0
- package/out/_next/static/chunks/1705-36c2180d00a4a569.js +1 -0
- package/out/_next/static/chunks/1dd3208c-e1f87c7b3dc1a820.js +1 -0
- package/out/_next/static/chunks/3663-47290254b8f6f5dd.js +1 -0
- package/out/_next/static/chunks/3677-4b225baf4801d9b9.js +73 -0
- package/out/_next/static/chunks/5118-7e8ada2df38eef07.js +1 -0
- package/out/_next/static/chunks/5888-15cbe97c90ed5fae.js +1 -0
- package/out/_next/static/chunks/6773-a45343a98df3abb5.js +1 -0
- package/out/_next/static/chunks/6940-b824612b605e79b3.js +9 -0
- package/out/_next/static/chunks/7894-f4a15249082a680d.js +1 -0
- package/out/_next/static/chunks/9175-b3617c1e5cbfed0e.js +1 -0
- package/out/_next/static/chunks/9372-1a804b8d08c7a236.js +1 -0
- package/out/_next/static/chunks/{ab6c8a12-0a58072fbb505134.js → ab6c8a12-91438a812d94ecf0.js} +1 -1
- package/out/_next/static/chunks/app/_not-found/page-8e8842f82d204726.js +1 -0
- package/out/_next/static/chunks/app/about/page-b78577a7da8fa459.js +1 -0
- package/out/_next/static/chunks/app/app/[[...slug]]/page-3dffd65b6344f53e.js +1 -0
- package/out/_next/static/chunks/app/app/onboarding/page-b89be9aa6264a5e1.js +1 -0
- package/out/_next/static/chunks/app/blog/go-to-bed-wake-up-to-a-finished-product/page-fbd00893ef69e499.js +1 -0
- package/out/_next/static/chunks/app/blog/let-them-cook-multi-agent-orchestration/page-de2ea13649d0b6d3.js +1 -0
- package/out/_next/static/chunks/app/blog/page-a08e263c57a156fa.js +1 -0
- package/out/_next/static/chunks/app/careers/page-02228e1d6969b232.js +1 -0
- package/out/_next/static/chunks/app/changelog/page-1b5c1d79efc6e53a.js +1 -0
- package/out/_next/static/chunks/app/cloud/link/page-99654edffffb3af2.js +1 -0
- package/out/_next/static/chunks/app/complete-profile/page-59d146e5ddeafc5c.js +1 -0
- package/out/_next/static/chunks/app/connect-repos/page-995e16a976a6632c.js +1 -0
- package/out/_next/static/chunks/app/contact/page-273396a5ad57bcee.js +1 -0
- package/out/_next/static/chunks/app/dev/cli-tools/page-a71b80dcb2d5fc8d.js +1 -0
- package/out/_next/static/chunks/app/dev/log-viewer/page-46a6151ae1be0796.js +1 -0
- package/out/_next/static/chunks/app/docs/page-7c7cb603b24b7c40.js +1 -0
- package/out/_next/static/chunks/app/history/page-0c5cab1dab4e8886.js +1 -0
- package/out/_next/static/chunks/app/layout-96d72ba8ef8a43a0.js +1 -0
- package/out/_next/static/chunks/app/login/page-0ccbab34213df842.js +1 -0
- package/out/_next/static/chunks/app/metrics/page-8616272aeab9c8b0.js +1 -0
- package/out/_next/static/chunks/app/page-09ce10603ad9a251.js +1 -0
- package/out/_next/static/chunks/app/pricing/page-91c975079120c941.js +1 -0
- package/out/_next/static/chunks/app/privacy/{page-c21d51ac2dee3a88.js → page-a49ab271cc686644.js} +1 -1
- package/out/_next/static/chunks/app/providers/{page-59114505f4353512.js → page-d775d6eb5bc29e96.js} +1 -1
- package/out/_next/static/chunks/app/providers/setup/[provider]/page-ec4ef3cd80de807e.js +1 -0
- package/out/_next/static/chunks/app/security/page-d9da9bd9191e8f95.js +1 -0
- package/out/_next/static/chunks/app/signup/page-930eca0bf5fd299d.js +1 -0
- package/out/_next/static/chunks/app/terms/page-3e4827620b98613c.js +1 -0
- package/out/_next/static/chunks/framework-648e1ae7da590300.js +1 -0
- package/out/_next/static/chunks/{main-acb1b24265295d6a.js → main-2b1990080c292d92.js} +1 -1
- package/out/_next/static/chunks/main-app-9f6b7ff9e754a8f5.js +1 -0
- package/out/_next/static/chunks/pages/_app-a077b72e02273ab1.js +1 -0
- package/out/_next/static/chunks/pages/_error-84001666436a04e4.js +1 -0
- package/out/_next/static/chunks/{webpack-dd93b81e2659669c.js → webpack-7586035f1585f2db.js} +1 -1
- package/out/_next/static/css/eb9fc69d1e3d2bed.css +1 -0
- package/out/_next/static/{IxfA6RZu4trcsEMYlkQra → g3G0LMdB7lxcrU5mdM54m}/_buildManifest.js +1 -1
- package/out/about.html +2 -2
- package/out/about.txt +2 -2
- package/out/app/onboarding.html +1 -1
- package/out/app/onboarding.txt +2 -2
- package/out/app.html +1 -1
- package/out/app.txt +2 -2
- package/out/blog/go-to-bed-wake-up-to-a-finished-product.html +3 -3
- package/out/blog/go-to-bed-wake-up-to-a-finished-product.txt +1 -1
- package/out/blog/let-them-cook-multi-agent-orchestration.html +2 -2
- package/out/blog/let-them-cook-multi-agent-orchestration.txt +2 -2
- package/out/blog.html +2 -2
- package/out/blog.txt +1 -1
- package/out/careers.html +2 -2
- package/out/careers.txt +2 -2
- package/out/changelog.html +2 -2
- package/out/changelog.txt +2 -2
- package/out/cloud/link.html +1 -1
- package/out/cloud/link.txt +2 -2
- package/out/complete-profile.html +2 -2
- package/out/complete-profile.txt +2 -2
- package/out/connect-repos.html +1 -1
- package/out/connect-repos.txt +2 -2
- package/out/contact.html +2 -2
- package/out/contact.txt +2 -2
- package/out/dev/cli-tools.html +1 -0
- package/out/dev/cli-tools.txt +7 -0
- package/out/dev/log-viewer.html +23 -0
- package/out/dev/log-viewer.txt +7 -0
- package/out/docs.html +2 -2
- package/out/docs.txt +2 -2
- package/out/history.html +1 -1
- package/out/history.txt +2 -2
- package/out/index.html +1 -1
- package/out/index.txt +2 -2
- package/out/login.html +2 -2
- package/out/login.txt +2 -2
- package/out/metrics.html +1 -1
- package/out/metrics.txt +2 -2
- package/out/pricing.html +2 -2
- package/out/pricing.txt +2 -2
- package/out/privacy.html +2 -2
- package/out/privacy.txt +2 -2
- package/out/providers/setup/claude.html +1 -1
- package/out/providers/setup/claude.txt +2 -2
- package/out/providers/setup/codex.html +1 -1
- package/out/providers/setup/codex.txt +2 -2
- package/out/providers/setup/cursor.html +1 -1
- package/out/providers/setup/cursor.txt +2 -2
- package/out/providers.html +1 -1
- package/out/providers.txt +2 -2
- package/out/security.html +2 -2
- package/out/security.txt +2 -2
- package/out/signup.html +2 -2
- package/out/signup.txt +2 -2
- package/out/terms.html +2 -2
- package/out/terms.txt +2 -2
- package/package.json +5 -1
- package/src/adapters/DashboardConfigProvider.tsx +56 -0
- package/src/adapters/cloudFetchAdapter.ts +278 -0
- package/src/adapters/index.ts +3 -0
- package/src/adapters/types.ts +508 -0
- package/src/app/app/[[...slug]]/DashboardPageClient.tsx +67 -18
- package/src/app/app/onboarding/page.tsx +870 -170
- package/src/app/cloud/link/page.tsx +14 -6
- package/src/app/connect-repos/page.tsx +9 -3
- package/src/app/dev/cli-tools/page.tsx +130 -0
- package/src/app/dev/log-viewer/MockLogViewer.tsx +132 -0
- package/src/app/dev/log-viewer/fixtures.ts +110 -0
- package/src/app/dev/log-viewer/page.tsx +288 -0
- package/src/app/history/page.tsx +28 -12
- package/src/app/page.tsx +1 -1
- package/src/app/providers/setup/[provider]/ProviderSetupClient.tsx +209 -59
- package/src/components/AgentCard.tsx +4 -4
- package/src/components/AgentLogPreview.tsx +2 -38
- package/src/components/App.tsx +441 -2624
- package/src/components/CliToolHarness.test.tsx +83 -0
- package/src/components/CliToolHarness.tsx +292 -0
- package/src/components/CoordinatorPanel.tsx +13 -6
- package/src/components/LogViewer.tsx +2 -42
- package/src/components/ProviderAuthFlow.tsx +201 -81
- package/src/components/ProvisioningProgress.tsx +1 -1
- package/src/components/ReactionChips.tsx +2 -1
- package/src/components/SpawnModal.test.tsx +51 -18
- package/src/components/SpawnModal.tsx +175 -207
- package/src/components/TerminalProviderSetup.tsx +1 -1
- package/src/components/ThreadPanel.tsx +2 -0
- package/src/components/WorkspaceContext.tsx +7 -19
- package/src/components/XTermLogViewer.tsx +190 -27
- package/src/components/channels/ChannelMessageList.tsx +94 -4
- package/src/components/channels/ChannelViewV1.tsx +35 -11
- package/src/components/channels/api.ts +21 -20
- package/src/components/channels/types.ts +16 -0
- package/src/components/hooks/index.ts +0 -19
- package/src/components/hooks/useMessages.test.ts +80 -0
- package/src/components/hooks/useMessages.ts +13 -4
- package/src/components/hooks/useOrchestrator.ts +1 -1
- package/src/components/hooks/usePresence.ts +45 -6
- package/src/components/hooks/useThread.ts +83 -46
- package/src/components/hooks/useTrajectory.ts +62 -5
- package/src/components/hooks/useWebSocket.test.ts +358 -0
- package/src/components/hooks/useWebSocket.ts +243 -5
- package/src/components/index.ts +2 -14
- package/src/components/layout/Header.tsx +9 -15
- package/src/components/layout/Sidebar.tsx +1 -8
- package/src/components/settings/SettingsPage.tsx +108 -47
- package/src/components/settings/index.ts +0 -3
- package/src/landing/blogData.ts +1 -1
- package/src/lib/agent-merge.test.ts +2 -2
- package/src/lib/api.ts +8 -38
- package/src/lib/identity.test.ts +139 -0
- package/src/lib/identity.ts +48 -0
- package/src/lib/relaycastMessageAdapters.test.ts +182 -0
- package/src/lib/relaycastMessageAdapters.ts +105 -0
- package/src/lib/sanitize-logs.test.ts +227 -0
- package/src/lib/sanitize-logs.ts +202 -0
- package/src/providers/AgentProvider.tsx +799 -0
- package/src/providers/ChannelProvider.tsx +528 -0
- package/src/providers/CloudWorkspaceProvider.tsx +402 -0
- package/src/providers/MessageProvider.tsx +875 -0
- package/src/providers/RelayConfigProvider.tsx +94 -0
- package/src/providers/SendProvider.tsx +497 -0
- package/src/providers/SettingsProvider.tsx +247 -0
- package/src/providers/index.ts +26 -0
- package/src/types/index.ts +10 -10
- package/out/_next/static/chunks/11-9a2993a37266dcb3.js +0 -9
- package/out/_next/static/chunks/118-ae2b650136a5a5fc.js +0 -1
- package/out/_next/static/chunks/1dd3208c-40ab0fc0f60392b8.js +0 -1
- package/out/_next/static/chunks/202-fc0763dd7488e58f.js +0 -1
- package/out/_next/static/chunks/259-83b77fa1b91ba5aa.js +0 -1
- package/out/_next/static/chunks/407-0c82986cf79c8ecb.js +0 -1
- package/out/_next/static/chunks/528-f5f676996d613c25.js +0 -2
- package/out/_next/static/chunks/663-ddb04081febc3678.js +0 -1
- package/out/_next/static/chunks/687-88b6b139a6bb0e2e.js +0 -1
- package/out/_next/static/chunks/695-51d25b1988644374.js +0 -1
- package/out/_next/static/chunks/773-54a2641043c81e55.js +0 -1
- package/out/_next/static/chunks/app/_not-found/page-6da9b72091e5b511.js +0 -1
- package/out/_next/static/chunks/app/about/page-fff7c6457683f243.js +0 -1
- package/out/_next/static/chunks/app/app/[[...slug]]/page-f7eca1b66fb4249b.js +0 -1
- package/out/_next/static/chunks/app/app/onboarding/page-129abc5da2e67971.js +0 -1
- package/out/_next/static/chunks/app/blog/go-to-bed-wake-up-to-a-finished-product/page-5d5f28fd126b692f.js +0 -1
- package/out/_next/static/chunks/app/blog/let-them-cook-multi-agent-orchestration/page-b194f207fbd91862.js +0 -1
- package/out/_next/static/chunks/app/blog/page-b9bd9d8703fca76a.js +0 -1
- package/out/_next/static/chunks/app/careers/page-a4bd8d5f4de8f4eb.js +0 -1
- package/out/_next/static/chunks/app/changelog/page-9a1f6ad1743d63c5.js +0 -1
- package/out/_next/static/chunks/app/cloud/link/page-0844c5699b027c3b.js +0 -1
- package/out/_next/static/chunks/app/complete-profile/page-39ed5a67916beb87.js +0 -1
- package/out/_next/static/chunks/app/connect-repos/page-297eddee0c39f2a3.js +0 -1
- package/out/_next/static/chunks/app/contact/page-3c1dd8690217fade.js +0 -1
- package/out/_next/static/chunks/app/docs/page-1875e981f2c3fd13.js +0 -1
- package/out/_next/static/chunks/app/history/page-2d5c5695c9e8b40c.js +0 -1
- package/out/_next/static/chunks/app/layout-0a4b99656da25511.js +0 -1
- package/out/_next/static/chunks/app/login/page-f69c076f5a6fc520.js +0 -1
- package/out/_next/static/chunks/app/metrics/page-bebbee055669a17e.js +0 -1
- package/out/_next/static/chunks/app/page-0ee604f7070d14c0.js +0 -1
- package/out/_next/static/chunks/app/pricing/page-eeae7d594af333b6.js +0 -1
- package/out/_next/static/chunks/app/providers/setup/[provider]/page-daf9b3e05e77ae19.js +0 -1
- package/out/_next/static/chunks/app/security/page-cd562730fe84a0a2.js +0 -1
- package/out/_next/static/chunks/app/signup/page-c242ca08101a84ff.js +0 -1
- package/out/_next/static/chunks/app/terms/page-c7001720e7941dc6.js +0 -1
- package/out/_next/static/chunks/framework-3664cab31236a9fa.js +0 -1
- package/out/_next/static/chunks/main-app-7f73a939a312a228.js +0 -1
- package/out/_next/static/chunks/pages/_app-10a93ab5b7c32eb3.js +0 -1
- package/out/_next/static/chunks/pages/_error-2d792b2a41857be4.js +0 -1
- package/out/_next/static/css/8968d98ed4c4d33f.css +0 -1
- package/src/components/BillingResult.tsx +0 -447
- package/src/components/CloudSessionProvider.tsx +0 -130
- package/src/components/SessionExpiredModal.tsx +0 -128
- package/src/components/WorkspaceStatusIndicator.tsx +0 -396
- package/src/components/hooks/useSession.ts +0 -209
- package/src/components/hooks/useWorkspaceMembers.ts +0 -132
- package/src/components/hooks/useWorkspaceStatus.ts +0 -237
- package/src/components/settings/BillingSettingsPanel.tsx +0 -564
- package/src/components/settings/TeamSettingsPanel.tsx +0 -560
- package/src/components/settings/WorkspaceSettingsPanel.tsx +0 -1368
- package/src/lib/cloudApi.ts +0 -893
- /package/out/_next/static/{IxfA6RZu4trcsEMYlkQra → g3G0LMdB7lxcrU5mdM54m}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Settings Provider
|
|
3
|
+
*
|
|
4
|
+
* Manages user preferences: theme, display options, notification settings.
|
|
5
|
+
* Persists to localStorage and applies theme to the document root.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import React, { createContext, useContext, useState, useCallback, useEffect } from 'react';
|
|
9
|
+
import { defaultSettings, type Settings } from '../components/settings';
|
|
10
|
+
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Types
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
|
|
15
|
+
type LegacyDashboardSettings = {
|
|
16
|
+
theme?: 'dark' | 'light' | 'system';
|
|
17
|
+
compactMode?: boolean;
|
|
18
|
+
showTimestamps?: boolean;
|
|
19
|
+
soundEnabled?: boolean;
|
|
20
|
+
notificationsEnabled?: boolean;
|
|
21
|
+
autoScrollMessages?: boolean;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
interface SettingsContextValue {
|
|
25
|
+
settings: Settings;
|
|
26
|
+
updateSettings: (updater: (prev: Settings) => Settings) => void;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Constants
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
|
|
33
|
+
const SETTINGS_STORAGE_KEY = 'dashboard-settings';
|
|
34
|
+
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// Helpers
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
|
|
39
|
+
function mergeSettings(base: Settings, partial: Partial<Settings>): Settings {
|
|
40
|
+
return {
|
|
41
|
+
...base,
|
|
42
|
+
...partial,
|
|
43
|
+
notifications: { ...base.notifications, ...partial.notifications },
|
|
44
|
+
display: { ...base.display, ...partial.display },
|
|
45
|
+
messages: { ...base.messages, ...partial.messages },
|
|
46
|
+
connection: { ...base.connection, ...partial.connection },
|
|
47
|
+
agentDefaults: {
|
|
48
|
+
...base.agentDefaults,
|
|
49
|
+
...partial.agentDefaults,
|
|
50
|
+
defaultModels: {
|
|
51
|
+
...base.agentDefaults?.defaultModels,
|
|
52
|
+
...partial.agentDefaults?.defaultModels,
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function migrateLegacySettings(raw: LegacyDashboardSettings): Settings {
|
|
59
|
+
const theme = raw.theme && ['dark', 'light', 'system'].includes(raw.theme)
|
|
60
|
+
? raw.theme
|
|
61
|
+
: defaultSettings.theme;
|
|
62
|
+
const sound = raw.soundEnabled ?? defaultSettings.notifications.sound;
|
|
63
|
+
const desktop = raw.notificationsEnabled ?? defaultSettings.notifications.desktop;
|
|
64
|
+
return {
|
|
65
|
+
...defaultSettings,
|
|
66
|
+
theme,
|
|
67
|
+
display: {
|
|
68
|
+
...defaultSettings.display,
|
|
69
|
+
compactMode: raw.compactMode ?? defaultSettings.display.compactMode,
|
|
70
|
+
showTimestamps: raw.showTimestamps ?? defaultSettings.display.showTimestamps,
|
|
71
|
+
},
|
|
72
|
+
notifications: {
|
|
73
|
+
...defaultSettings.notifications,
|
|
74
|
+
sound,
|
|
75
|
+
desktop,
|
|
76
|
+
enabled: sound || desktop || defaultSettings.notifications.mentionsOnly,
|
|
77
|
+
},
|
|
78
|
+
messages: {
|
|
79
|
+
...defaultSettings.messages,
|
|
80
|
+
autoScroll: raw.autoScrollMessages ?? defaultSettings.messages.autoScroll,
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function loadSettingsFromStorage(): Settings {
|
|
86
|
+
if (typeof window === 'undefined') return defaultSettings;
|
|
87
|
+
try {
|
|
88
|
+
const saved = localStorage.getItem(SETTINGS_STORAGE_KEY);
|
|
89
|
+
if (!saved) return defaultSettings;
|
|
90
|
+
const parsed = JSON.parse(saved);
|
|
91
|
+
if (!parsed || typeof parsed !== 'object') return defaultSettings;
|
|
92
|
+
if ('notifications' in parsed && 'display' in parsed) {
|
|
93
|
+
const merged = mergeSettings(defaultSettings, parsed as Partial<Settings>);
|
|
94
|
+
merged.notifications.enabled = merged.notifications.sound ||
|
|
95
|
+
merged.notifications.desktop ||
|
|
96
|
+
merged.notifications.mentionsOnly;
|
|
97
|
+
return merged;
|
|
98
|
+
}
|
|
99
|
+
if ('notificationsEnabled' in parsed || 'soundEnabled' in parsed || 'autoScrollMessages' in parsed) {
|
|
100
|
+
return migrateLegacySettings(parsed as LegacyDashboardSettings);
|
|
101
|
+
}
|
|
102
|
+
} catch {
|
|
103
|
+
// Fall back to defaults
|
|
104
|
+
}
|
|
105
|
+
return defaultSettings;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function saveSettingsToStorage(settings: Settings) {
|
|
109
|
+
if (typeof window === 'undefined') return;
|
|
110
|
+
try {
|
|
111
|
+
localStorage.setItem(SETTINGS_STORAGE_KEY, JSON.stringify(settings));
|
|
112
|
+
} catch {
|
|
113
|
+
// Ignore localStorage failures
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// ---------------------------------------------------------------------------
|
|
118
|
+
// Context
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
|
|
121
|
+
const SettingsContext = createContext<SettingsContextValue | null>(null);
|
|
122
|
+
|
|
123
|
+
// ---------------------------------------------------------------------------
|
|
124
|
+
// Provider
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
|
|
127
|
+
export interface SettingsProviderProps {
|
|
128
|
+
children: React.ReactNode;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function SettingsProvider({ children }: SettingsProviderProps) {
|
|
132
|
+
const [settings, setSettings] = useState<Settings>(() => loadSettingsFromStorage());
|
|
133
|
+
|
|
134
|
+
const updateSettings = useCallback((updater: (prev: Settings) => Settings) => {
|
|
135
|
+
setSettings((prev) => updater(prev));
|
|
136
|
+
}, []);
|
|
137
|
+
|
|
138
|
+
// Persist settings changes
|
|
139
|
+
useEffect(() => {
|
|
140
|
+
saveSettingsToStorage(settings);
|
|
141
|
+
}, [settings]);
|
|
142
|
+
|
|
143
|
+
// Apply theme to document
|
|
144
|
+
useEffect(() => {
|
|
145
|
+
const applyTheme = (theme: 'light' | 'dark' | 'system') => {
|
|
146
|
+
let effectiveTheme: 'light' | 'dark';
|
|
147
|
+
|
|
148
|
+
if (theme === 'system') {
|
|
149
|
+
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
150
|
+
effectiveTheme = prefersDark ? 'dark' : 'light';
|
|
151
|
+
} else {
|
|
152
|
+
effectiveTheme = theme;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const root = document.documentElement;
|
|
156
|
+
root.classList.remove('theme-light', 'theme-dark');
|
|
157
|
+
root.classList.add(`theme-${effectiveTheme}`);
|
|
158
|
+
root.style.colorScheme = effectiveTheme;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
applyTheme(settings.theme);
|
|
162
|
+
|
|
163
|
+
if (settings.theme === 'system') {
|
|
164
|
+
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
165
|
+
const handleChange = () => applyTheme('system');
|
|
166
|
+
mediaQuery.addEventListener('change', handleChange);
|
|
167
|
+
return () => mediaQuery.removeEventListener('change', handleChange);
|
|
168
|
+
}
|
|
169
|
+
}, [settings.theme]);
|
|
170
|
+
|
|
171
|
+
// Request browser notification permissions when enabled
|
|
172
|
+
useEffect(() => {
|
|
173
|
+
if (!settings.notifications.desktop) return;
|
|
174
|
+
if (typeof window === 'undefined' || !('Notification' in window)) return;
|
|
175
|
+
|
|
176
|
+
if (Notification.permission === 'granted') return;
|
|
177
|
+
|
|
178
|
+
if (Notification.permission === 'denied') {
|
|
179
|
+
updateSettings((prev) => ({
|
|
180
|
+
...prev,
|
|
181
|
+
notifications: {
|
|
182
|
+
...prev.notifications,
|
|
183
|
+
desktop: false,
|
|
184
|
+
enabled: prev.notifications.sound || prev.notifications.mentionsOnly,
|
|
185
|
+
},
|
|
186
|
+
}));
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
Notification.requestPermission().then((permission) => {
|
|
191
|
+
if (permission !== 'granted') {
|
|
192
|
+
updateSettings((prev) => ({
|
|
193
|
+
...prev,
|
|
194
|
+
notifications: {
|
|
195
|
+
...prev.notifications,
|
|
196
|
+
desktop: false,
|
|
197
|
+
enabled: prev.notifications.sound || prev.notifications.mentionsOnly,
|
|
198
|
+
},
|
|
199
|
+
}));
|
|
200
|
+
}
|
|
201
|
+
}).catch(() => undefined);
|
|
202
|
+
}, [settings.notifications.desktop, settings.notifications.sound, settings.notifications.mentionsOnly, updateSettings]);
|
|
203
|
+
|
|
204
|
+
return (
|
|
205
|
+
<SettingsContext.Provider value={{ settings, updateSettings }}>
|
|
206
|
+
{children}
|
|
207
|
+
</SettingsContext.Provider>
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// ---------------------------------------------------------------------------
|
|
212
|
+
// Hook
|
|
213
|
+
// ---------------------------------------------------------------------------
|
|
214
|
+
|
|
215
|
+
export function useSettings(): SettingsContextValue {
|
|
216
|
+
const ctx = useContext(SettingsContext);
|
|
217
|
+
if (!ctx) {
|
|
218
|
+
throw new Error('useSettings must be used within a SettingsProvider');
|
|
219
|
+
}
|
|
220
|
+
return ctx;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Re-export the notification sound helper so App can still use it
|
|
224
|
+
export function playNotificationSound() {
|
|
225
|
+
if (typeof window === 'undefined') return;
|
|
226
|
+
const AudioContextConstructor =
|
|
227
|
+
window.AudioContext ||
|
|
228
|
+
(window as Window & { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;
|
|
229
|
+
if (!AudioContextConstructor) return;
|
|
230
|
+
try {
|
|
231
|
+
const context = new AudioContextConstructor();
|
|
232
|
+
const oscillator = context.createOscillator();
|
|
233
|
+
const gain = context.createGain();
|
|
234
|
+
oscillator.type = 'sine';
|
|
235
|
+
oscillator.frequency.value = 880;
|
|
236
|
+
gain.gain.value = 0.03;
|
|
237
|
+
oscillator.connect(gain);
|
|
238
|
+
gain.connect(context.destination);
|
|
239
|
+
oscillator.start();
|
|
240
|
+
oscillator.stop(context.currentTime + 0.12);
|
|
241
|
+
oscillator.onended = () => {
|
|
242
|
+
context.close().catch(() => undefined);
|
|
243
|
+
};
|
|
244
|
+
} catch {
|
|
245
|
+
// Audio might be blocked by browser autoplay policies
|
|
246
|
+
}
|
|
247
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider exports
|
|
3
|
+
*
|
|
4
|
+
* Focused context providers extracted from the monolithic App component.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export { SettingsProvider, useSettings, playNotificationSound } from './SettingsProvider';
|
|
8
|
+
export type { SettingsProviderProps } from './SettingsProvider';
|
|
9
|
+
|
|
10
|
+
export { CloudWorkspaceProvider, useCloudWorkspace } from './CloudWorkspaceProvider';
|
|
11
|
+
export type { CloudWorkspaceProviderProps, CloudWorkspace } from './CloudWorkspaceProvider';
|
|
12
|
+
|
|
13
|
+
export { RelayConfigProvider } from './RelayConfigProvider';
|
|
14
|
+
export type { RelayConfigProviderProps } from './RelayConfigProvider';
|
|
15
|
+
|
|
16
|
+
export { AgentProvider, useAgentContext } from './AgentProvider';
|
|
17
|
+
export type { AgentProviderProps } from './AgentProvider';
|
|
18
|
+
|
|
19
|
+
export { MessageProvider, useMessageContext, ACTIVITY_FEED_ID } from './MessageProvider';
|
|
20
|
+
export type { MessageProviderProps } from './MessageProvider';
|
|
21
|
+
|
|
22
|
+
export { ChannelProvider, useChannelContext } from './ChannelProvider';
|
|
23
|
+
export type { ChannelProviderProps, ChannelContextValue } from './ChannelProvider';
|
|
24
|
+
|
|
25
|
+
export { SendProvider, useSendContext } from './SendProvider';
|
|
26
|
+
export type { SendProviderProps, SendContextValue } from './SendProvider';
|
package/src/types/index.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import type { AgentStatus } from '../lib/colors';
|
|
6
6
|
import type { ThreadMetadata } from './threading';
|
|
7
|
+
import type { ReactionGroup } from '@relaycast/types';
|
|
7
8
|
|
|
8
9
|
export type { ThreadMetadata } from './threading';
|
|
9
10
|
|
|
@@ -22,6 +23,7 @@ export interface Agent {
|
|
|
22
23
|
server?: string; // For fleet view - which server the agent is on
|
|
23
24
|
isProcessing?: boolean; // True when agent is thinking/processing a message
|
|
24
25
|
processingStartedAt?: number; // Timestamp when processing started
|
|
26
|
+
lastLogLine?: string; // Last log output line from worker_stream
|
|
25
27
|
isSpawned?: boolean; // True if agent was spawned via dashboard (can be killed)
|
|
26
28
|
team?: string; // Optional user-defined team grouping (e.g., "frontend-team", "backend-team")
|
|
27
29
|
agentId?: string; // Unique agent ID for resume functionality
|
|
@@ -32,10 +34,10 @@ export interface Agent {
|
|
|
32
34
|
avatarUrl?: string; // Avatar URL for human users
|
|
33
35
|
authRevoked?: boolean; // True if agent's authentication has been revoked (needs re-login)
|
|
34
36
|
cwd?: string; // Working directory (repo name) the agent was spawned in
|
|
35
|
-
// Local
|
|
36
|
-
isLocal?: boolean; // True if agent is from a linked local
|
|
37
|
-
|
|
38
|
-
machineId?: string; // Machine ID of the linked
|
|
37
|
+
// Local broker agent fields
|
|
38
|
+
isLocal?: boolean; // True if agent is from a linked local broker
|
|
39
|
+
brokerName?: string; // Name of the linked broker
|
|
40
|
+
machineId?: string; // Machine ID of the linked broker
|
|
39
41
|
// Profile fields for understanding agent behavior
|
|
40
42
|
profile?: AgentProfile;
|
|
41
43
|
}
|
|
@@ -101,12 +103,8 @@ export interface Attachment {
|
|
|
101
103
|
}
|
|
102
104
|
|
|
103
105
|
|
|
104
|
-
// Reaction Types
|
|
105
|
-
export
|
|
106
|
-
emoji: string;
|
|
107
|
-
count: number;
|
|
108
|
-
agents: string[];
|
|
109
|
-
}
|
|
106
|
+
// Reaction Types — sourced from canonical @relaycast/types
|
|
107
|
+
export type Reaction = ReactionGroup;
|
|
110
108
|
|
|
111
109
|
// Message Types
|
|
112
110
|
export interface Message {
|
|
@@ -279,6 +277,8 @@ export interface SpawnAgentRequest {
|
|
|
279
277
|
shadowTriggers?: SpeakOnTrigger[];
|
|
280
278
|
/** When the shadow should speak */
|
|
281
279
|
shadowSpeakOn?: SpeakOnTrigger[];
|
|
280
|
+
/** Agent name to continue session from (agent continuity) */
|
|
281
|
+
continueFrom?: string;
|
|
282
282
|
}
|
|
283
283
|
|
|
284
284
|
export interface SpawnAgentResponse {
|