@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
|
@@ -12,6 +12,29 @@ import { useState, useEffect, useCallback, useRef } from 'react';
|
|
|
12
12
|
import type { Agent, Message, Session, AgentSummary, FleetData } from '../../types';
|
|
13
13
|
import { getWebSocketUrl } from '../../lib/config';
|
|
14
14
|
|
|
15
|
+
/** Broker event payload forwarded by the dashboard server */
|
|
16
|
+
interface BrokerEvent {
|
|
17
|
+
kind: string;
|
|
18
|
+
name?: string;
|
|
19
|
+
from?: string;
|
|
20
|
+
target?: string;
|
|
21
|
+
body?: string;
|
|
22
|
+
event_id?: string;
|
|
23
|
+
thread_id?: string | null;
|
|
24
|
+
code?: number | null;
|
|
25
|
+
signal?: string | null;
|
|
26
|
+
cli?: string | null;
|
|
27
|
+
model?: string | null;
|
|
28
|
+
runtime?: string;
|
|
29
|
+
reason?: string;
|
|
30
|
+
idle_secs?: number;
|
|
31
|
+
restart_count?: number;
|
|
32
|
+
delivery_id?: string;
|
|
33
|
+
error?: unknown;
|
|
34
|
+
stream?: string;
|
|
35
|
+
chunk?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
15
38
|
export interface DashboardData {
|
|
16
39
|
agents: Agent[];
|
|
17
40
|
users?: Agent[]; // Human users (cli === 'dashboard')
|
|
@@ -67,6 +90,214 @@ function getDefaultUrl(): string {
|
|
|
67
90
|
return getWebSocketUrl('/ws');
|
|
68
91
|
}
|
|
69
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Apply an incremental broker event to the current dashboard state.
|
|
95
|
+
* Returns a new state object with the event applied, or the previous state
|
|
96
|
+
* if the event is not relevant for the UI.
|
|
97
|
+
*/
|
|
98
|
+
export function applyBrokerEvent(prev: DashboardData | null, event: BrokerEvent): DashboardData | null {
|
|
99
|
+
if (!prev) {
|
|
100
|
+
// Bootstrap empty state so events arriving before the snapshot aren't lost
|
|
101
|
+
prev = { agents: [], messages: [] };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
switch (event.kind) {
|
|
105
|
+
case 'relay_inbound': {
|
|
106
|
+
if (!event.from || !event.target || !event.body) return prev;
|
|
107
|
+
// Channel messages are handled by useChannels — skip here to avoid duplication
|
|
108
|
+
if (event.target.startsWith('#')) return prev;
|
|
109
|
+
const msgId = event.event_id || `broker_${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
|
110
|
+
// Deduplicate by event_id — the same event can arrive via multiple paths
|
|
111
|
+
if (event.event_id && prev.messages.some((m) => m.id === event.event_id)) {
|
|
112
|
+
return prev;
|
|
113
|
+
}
|
|
114
|
+
const newMessage: Message = {
|
|
115
|
+
id: msgId,
|
|
116
|
+
from: event.from,
|
|
117
|
+
to: event.target,
|
|
118
|
+
content: event.body,
|
|
119
|
+
timestamp: new Date().toISOString(),
|
|
120
|
+
thread: event.thread_id ?? undefined,
|
|
121
|
+
isBroadcast: event.target === '*',
|
|
122
|
+
};
|
|
123
|
+
// Clear thinking/processing state only when a known processing agent sends a response
|
|
124
|
+
const senderIsProcessingAgent = prev.agents.some(
|
|
125
|
+
(a) => a.name === event.from && a.isProcessing,
|
|
126
|
+
);
|
|
127
|
+
// If this is a thread reply, increment replyCount on the parent message
|
|
128
|
+
const updatedMessages = [...prev.messages, newMessage];
|
|
129
|
+
if (event.thread_id) {
|
|
130
|
+
const parentIdx = updatedMessages.findIndex((m) => m.id === event.thread_id);
|
|
131
|
+
if (parentIdx !== -1) {
|
|
132
|
+
updatedMessages[parentIdx] = {
|
|
133
|
+
...updatedMessages[parentIdx],
|
|
134
|
+
replyCount: (updatedMessages[parentIdx].replyCount ?? 0) + 1,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
...prev,
|
|
140
|
+
messages: updatedMessages,
|
|
141
|
+
agents: senderIsProcessingAgent
|
|
142
|
+
? prev.agents.map((a) =>
|
|
143
|
+
a.name === event.from
|
|
144
|
+
? { ...a, isProcessing: false, processingStartedAt: undefined, lastLogLine: undefined }
|
|
145
|
+
: a,
|
|
146
|
+
)
|
|
147
|
+
: prev.agents,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
case 'agent_spawned': {
|
|
152
|
+
if (!event.name) return prev;
|
|
153
|
+
// Avoid duplicates
|
|
154
|
+
const exists = prev.agents.some((a) => a.name === event.name);
|
|
155
|
+
if (exists) {
|
|
156
|
+
return {
|
|
157
|
+
...prev,
|
|
158
|
+
agents: prev.agents.map((a) =>
|
|
159
|
+
a.name === event.name ? { ...a, status: 'online' as const, cli: event.cli ?? a.cli, model: event.model ?? a.model } : a,
|
|
160
|
+
),
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
...prev,
|
|
165
|
+
agents: [
|
|
166
|
+
...prev.agents,
|
|
167
|
+
{
|
|
168
|
+
name: event.name,
|
|
169
|
+
status: 'online' as const,
|
|
170
|
+
cli: event.cli ?? undefined,
|
|
171
|
+
model: event.model ?? undefined,
|
|
172
|
+
isSpawned: true,
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
case 'agent_exited': {
|
|
179
|
+
if (!event.name) return prev;
|
|
180
|
+
return {
|
|
181
|
+
...prev,
|
|
182
|
+
agents: prev.agents.filter((a) => a.name !== event.name),
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
case 'agent_released': {
|
|
187
|
+
if (!event.name) return prev;
|
|
188
|
+
return {
|
|
189
|
+
...prev,
|
|
190
|
+
agents: prev.agents.filter((a) => a.name !== event.name),
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
case 'worker_ready': {
|
|
195
|
+
if (!event.name) return prev;
|
|
196
|
+
return {
|
|
197
|
+
...prev,
|
|
198
|
+
agents: prev.agents.map((a) =>
|
|
199
|
+
a.name === event.name
|
|
200
|
+
? { ...a, status: 'online' as const, cli: event.cli ?? a.cli, model: event.model ?? a.model }
|
|
201
|
+
: a,
|
|
202
|
+
),
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
case 'agent_idle': {
|
|
207
|
+
if (!event.name) return prev;
|
|
208
|
+
return {
|
|
209
|
+
...prev,
|
|
210
|
+
agents: prev.agents.map((a) =>
|
|
211
|
+
a.name === event.name
|
|
212
|
+
? { ...a, isProcessing: false, processingStartedAt: undefined, lastLogLine: undefined }
|
|
213
|
+
: a,
|
|
214
|
+
),
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
case 'agent_restarting': {
|
|
219
|
+
if (!event.name) return prev;
|
|
220
|
+
return {
|
|
221
|
+
...prev,
|
|
222
|
+
agents: prev.agents.map((a) =>
|
|
223
|
+
a.name === event.name ? { ...a, status: 'busy' as const } : a,
|
|
224
|
+
),
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
case 'agent_restarted': {
|
|
229
|
+
if (!event.name) return prev;
|
|
230
|
+
return {
|
|
231
|
+
...prev,
|
|
232
|
+
agents: prev.agents.map((a) =>
|
|
233
|
+
a.name === event.name ? { ...a, status: 'online' as const } : a,
|
|
234
|
+
),
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
case 'agent_permanently_dead': {
|
|
239
|
+
if (!event.name) return prev;
|
|
240
|
+
return {
|
|
241
|
+
...prev,
|
|
242
|
+
agents: prev.agents.map((a) =>
|
|
243
|
+
a.name === event.name ? { ...a, status: 'offline' as const } : a,
|
|
244
|
+
),
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
case 'delivery_verified': {
|
|
249
|
+
if (!event.event_id) return prev;
|
|
250
|
+
return {
|
|
251
|
+
...prev,
|
|
252
|
+
messages: prev.messages.map((m) =>
|
|
253
|
+
m.id === event.event_id ? { ...m, status: 'acked' as const } : m,
|
|
254
|
+
),
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
case 'delivery_failed': {
|
|
259
|
+
if (!event.event_id) return prev;
|
|
260
|
+
return {
|
|
261
|
+
...prev,
|
|
262
|
+
messages: prev.messages.map((m) =>
|
|
263
|
+
m.id === event.event_id ? { ...m, status: 'failed' as const } : m,
|
|
264
|
+
),
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
case 'delivery_ack':
|
|
269
|
+
case 'delivery_active': {
|
|
270
|
+
if (!event.name) return prev;
|
|
271
|
+
return {
|
|
272
|
+
...prev,
|
|
273
|
+
agents: prev.agents.map((a) =>
|
|
274
|
+
a.name === event.name
|
|
275
|
+
? { ...a, isProcessing: true, processingStartedAt: Date.now() }
|
|
276
|
+
: a,
|
|
277
|
+
),
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
case 'worker_stream': {
|
|
282
|
+
if (!event.name) return prev;
|
|
283
|
+
return {
|
|
284
|
+
...prev,
|
|
285
|
+
agents: prev.agents.map((a) =>
|
|
286
|
+
a.name === event.name ? { ...a, lastLogLine: event.chunk } : a,
|
|
287
|
+
),
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
case 'worker_error': {
|
|
292
|
+
// Worker error — could show in agent details
|
|
293
|
+
return prev;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
default:
|
|
297
|
+
return prev;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
70
301
|
export function useWebSocket(options: UseWebSocketOptions = {}): UseWebSocketReturn {
|
|
71
302
|
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
72
303
|
|
|
@@ -122,13 +353,20 @@ export function useWebSocket(options: UseWebSocketOptions = {}): UseWebSocketRet
|
|
|
122
353
|
// Strip seq from the payload before routing (it's only for tracking, not data)
|
|
123
354
|
const { seq: _seq, ...payload } = parsed;
|
|
124
355
|
|
|
125
|
-
// Check
|
|
126
|
-
// vs dashboard data (has agents array)
|
|
356
|
+
// Check message type and route accordingly
|
|
127
357
|
if (payload && typeof payload === 'object' && 'type' in payload && typeof payload.type === 'string') {
|
|
128
|
-
//
|
|
129
|
-
|
|
358
|
+
// Incremental broker event — apply as state patch
|
|
359
|
+
if (payload.type === 'broker_event' && payload.payload && typeof payload.payload === 'object' && 'kind' in payload.payload) {
|
|
360
|
+
setData((prev) => applyBrokerEvent(prev, payload.payload as BrokerEvent));
|
|
361
|
+
} else {
|
|
362
|
+
// Other event messages (direct_message, channel_message, presence, etc.)
|
|
363
|
+
onEventRef.current?.(payload as WebSocketEvent);
|
|
364
|
+
}
|
|
365
|
+
} else if (payload && typeof payload === 'object' && 'kind' in payload && typeof payload.kind === 'string') {
|
|
366
|
+
// Raw (unwrapped) broker event — apply as incremental patch
|
|
367
|
+
setData((prev) => applyBrokerEvent(prev, payload as BrokerEvent));
|
|
130
368
|
} else {
|
|
131
|
-
//
|
|
369
|
+
// Full dashboard snapshot — replace state
|
|
132
370
|
setData(payload as DashboardData);
|
|
133
371
|
}
|
|
134
372
|
|
package/src/components/index.ts
CHANGED
|
@@ -14,7 +14,7 @@ export { MessageStatusIndicator, type MessageStatusIndicatorProps } from './Mess
|
|
|
14
14
|
export { MessageList, type MessageListProps } from './MessageList';
|
|
15
15
|
export { ThreadPanel, type ThreadPanelProps } from './ThreadPanel';
|
|
16
16
|
export { CommandPalette, type CommandPaletteProps, type Command } from './CommandPalette';
|
|
17
|
-
export { SpawnModal, type SpawnModalProps, type SpawnConfig, type SpeakOnTrigger } from './SpawnModal';
|
|
17
|
+
export { SpawnModal, type SpawnModalProps, type SpawnConfig, type SpeakOnTrigger, type ModelOption } from './SpawnModal';
|
|
18
18
|
export { NewConversationModal, type NewConversationModalProps } from './NewConversationModal';
|
|
19
19
|
export { TrajectoryViewer, type TrajectoryViewerProps, type TrajectoryStep } from './TrajectoryViewer';
|
|
20
20
|
export { DecisionQueue, type DecisionQueueProps, type Decision } from './DecisionQueue';
|
|
@@ -28,18 +28,10 @@ export { App, appStyles, type AppProps } from './App';
|
|
|
28
28
|
export { MentionAutocomplete, useMentionAutocomplete, getMentionQuery, completeMentionInValue, type MentionAutocompleteProps } from './MentionAutocomplete';
|
|
29
29
|
export { ProjectList, type ProjectListProps } from './ProjectList';
|
|
30
30
|
export { WorkspaceSelector, type WorkspaceSelectorProps, type Workspace } from './WorkspaceSelector';
|
|
31
|
-
export { WorkspaceSettingsPanel, type WorkspaceSettingsPanelProps } from './settings/WorkspaceSettingsPanel';
|
|
32
31
|
export { AddWorkspaceModal, type AddWorkspaceModalProps } from './AddWorkspaceModal';
|
|
33
32
|
export { PricingPlans, type PricingPlansProps, type Plan } from './PricingPlans';
|
|
34
33
|
export { BillingPanel, type BillingPanelProps, type Subscription, type Invoice, type PaymentMethod } from './BillingPanel';
|
|
35
|
-
export { SessionExpiredModal, type SessionExpiredModalProps } from './SessionExpiredModal';
|
|
36
34
|
export { ProvisioningProgress, type ProvisioningProgressProps } from './ProvisioningProgress';
|
|
37
|
-
export {
|
|
38
|
-
CloudSessionProvider,
|
|
39
|
-
useCloudSession,
|
|
40
|
-
useCloudSessionOptional,
|
|
41
|
-
type CloudSessionProviderProps,
|
|
42
|
-
} from './CloudSessionProvider';
|
|
43
35
|
export {
|
|
44
36
|
WorkspaceProvider,
|
|
45
37
|
useWorkspace,
|
|
@@ -50,6 +42,7 @@ export {
|
|
|
50
42
|
// Terminal Components
|
|
51
43
|
export { XTermLogViewer, type XTermLogViewerProps } from './XTermLogViewer';
|
|
52
44
|
export { XTermInteractive, type XTermInteractiveProps } from './XTermInteractive';
|
|
45
|
+
export { CliToolHarness, type CliToolHarnessConfig, type CliToolHarnessProps } from './CliToolHarness';
|
|
53
46
|
|
|
54
47
|
// Layout Components
|
|
55
48
|
export { Sidebar, type SidebarProps } from './layout/Sidebar';
|
|
@@ -61,7 +54,6 @@ export {
|
|
|
61
54
|
useAgents,
|
|
62
55
|
useMessages,
|
|
63
56
|
useOrchestrator,
|
|
64
|
-
useSession,
|
|
65
57
|
type UseWebSocketOptions,
|
|
66
58
|
type UseWebSocketReturn,
|
|
67
59
|
type UseAgentsOptions,
|
|
@@ -70,12 +62,8 @@ export {
|
|
|
70
62
|
type UseMessagesReturn,
|
|
71
63
|
type UseOrchestratorOptions,
|
|
72
64
|
type UseOrchestratorResult,
|
|
73
|
-
type UseSessionOptions,
|
|
74
|
-
type UseSessionReturn,
|
|
75
65
|
type DashboardData,
|
|
76
66
|
type AgentWithColor,
|
|
77
67
|
type OrchestratorAgent,
|
|
78
68
|
type OrchestratorEvent,
|
|
79
|
-
type SessionError,
|
|
80
|
-
type CloudUser,
|
|
81
69
|
} from './hooks';
|
|
@@ -10,7 +10,6 @@ import type { Agent, Project } from '../../types';
|
|
|
10
10
|
import { getAgentColor, getAgentInitials } from '../../lib/colors';
|
|
11
11
|
import { getAgentBreadcrumb } from '../../lib/hierarchy';
|
|
12
12
|
import { RepoContextHeader } from './RepoContextHeader';
|
|
13
|
-
import { WorkspaceStatusIndicator } from '../WorkspaceStatusIndicator';
|
|
14
13
|
|
|
15
14
|
export interface HeaderProps {
|
|
16
15
|
currentChannel: string;
|
|
@@ -97,12 +96,6 @@ export function Header({
|
|
|
97
96
|
<div className="w-px h-6 bg-border-subtle mr-3 max-md:hidden" />
|
|
98
97
|
)}
|
|
99
98
|
|
|
100
|
-
{/* Workspace Status Indicator */}
|
|
101
|
-
<WorkspaceStatusIndicator className="max-md:hidden mr-3" />
|
|
102
|
-
|
|
103
|
-
{/* Divider after workspace status */}
|
|
104
|
-
<div className="w-px h-6 bg-border-subtle mr-3 max-md:hidden" />
|
|
105
|
-
|
|
106
99
|
<div className="flex items-center gap-2 sm:gap-3 flex-1 min-w-0">
|
|
107
100
|
{selectedAgent && !selectedAgent.isHuman && selectedAgent.cli !== 'dashboard' ? (
|
|
108
101
|
<>
|
|
@@ -222,13 +215,15 @@ export function Header({
|
|
|
222
215
|
<MetricsIcon />
|
|
223
216
|
</a>
|
|
224
217
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
218
|
+
{onSettingsClick && (
|
|
219
|
+
<button
|
|
220
|
+
className="flex items-center justify-center p-1.5 sm:p-2 bg-bg-tertiary border border-border-subtle rounded-lg text-text-secondary cursor-pointer transition-all duration-150 hover:bg-bg-elevated hover:border-border-medium hover:text-accent-purple"
|
|
221
|
+
onClick={onSettingsClick}
|
|
222
|
+
title="Settings"
|
|
223
|
+
>
|
|
224
|
+
<SettingsIcon />
|
|
225
|
+
</button>
|
|
226
|
+
)}
|
|
232
227
|
</div>
|
|
233
228
|
</header>
|
|
234
229
|
);
|
|
@@ -308,4 +303,3 @@ function MenuIcon() {
|
|
|
308
303
|
</svg>
|
|
309
304
|
);
|
|
310
305
|
}
|
|
311
|
-
|
|
@@ -9,7 +9,6 @@ import React, { useState, useEffect } from 'react';
|
|
|
9
9
|
import type { Agent, Project } from '../../types';
|
|
10
10
|
import type { ThreadInfo } from '../hooks/useMessages';
|
|
11
11
|
import { usePinnedAgents } from '../hooks/usePinnedAgents';
|
|
12
|
-
import { useWorkspaceStatus } from '../hooks/useWorkspaceStatus';
|
|
13
12
|
import { AgentList } from '../AgentList';
|
|
14
13
|
import { ProjectList } from '../ProjectList';
|
|
15
14
|
import { ThreadList } from '../ThreadList';
|
|
@@ -225,10 +224,6 @@ export function Sidebar({
|
|
|
225
224
|
// Pinned agents for quick access
|
|
226
225
|
const { pinnedAgents, togglePin, isMaxPinned } = usePinnedAgents();
|
|
227
226
|
|
|
228
|
-
// Check if workspace is stopped - hide channels when stopped
|
|
229
|
-
const { workspace } = useWorkspaceStatus();
|
|
230
|
-
const isWorkspaceStopped = workspace?.isStopped ?? false;
|
|
231
|
-
|
|
232
227
|
// Determine if we should show unified project view
|
|
233
228
|
const hasProjects = projects.length > 0;
|
|
234
229
|
|
|
@@ -346,8 +341,7 @@ export function Sidebar({
|
|
|
346
341
|
</button>
|
|
347
342
|
</div>
|
|
348
343
|
|
|
349
|
-
{/* Channels Section - Collapsible
|
|
350
|
-
{!isWorkspaceStopped && (
|
|
344
|
+
{/* Channels Section - Collapsible */}
|
|
351
345
|
<div className="border-b border-border-subtle">
|
|
352
346
|
<button
|
|
353
347
|
className="w-full flex items-center justify-between px-3 py-2 text-xs font-semibold text-text-muted uppercase tracking-wide hover:bg-bg-hover transition-colors"
|
|
@@ -494,7 +488,6 @@ export function Sidebar({
|
|
|
494
488
|
</div>
|
|
495
489
|
)}
|
|
496
490
|
</div>
|
|
497
|
-
)}
|
|
498
491
|
|
|
499
492
|
{/* Agent/Project List */}
|
|
500
493
|
<div className="flex-1 overflow-y-auto px-2">
|