agent-relay 2.0.21 → 2.0.23
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/bin/relay-pty-linux-arm64 +0 -0
- package/dist/src/cli/index.d.ts +3 -3
- package/dist/src/cli/index.js +31 -100
- package/package.json +22 -29
- package/packages/api-types/package.json +1 -1
- package/packages/bridge/package.json +8 -8
- package/packages/cli-tester/package.json +1 -1
- package/packages/cloud/dist/server.js +25 -4
- package/packages/cloud/package.json +6 -6
- package/packages/config/package.json +2 -2
- package/packages/continuity/package.json +1 -1
- package/packages/daemon/dist/orchestrator.js +21 -1
- package/packages/daemon/dist/router.d.ts +5 -0
- package/packages/daemon/dist/router.js +31 -0
- package/packages/daemon/dist/server.d.ts +5 -0
- package/packages/daemon/dist/server.js +131 -1
- package/packages/daemon/package.json +12 -12
- package/packages/hooks/package.json +4 -4
- package/packages/mcp/dist/client.d.ts +15 -0
- package/packages/mcp/dist/client.js +9 -0
- package/packages/mcp/dist/server.js +13 -1
- package/packages/mcp/dist/tools/index.d.ts +2 -0
- package/packages/mcp/dist/tools/index.js +2 -0
- package/packages/mcp/dist/tools/relay-connected.d.ts +17 -0
- package/packages/mcp/dist/tools/relay-connected.js +40 -0
- package/packages/mcp/dist/tools/relay-remove-agent.d.ts +20 -0
- package/packages/mcp/dist/tools/relay-remove-agent.js +50 -0
- package/packages/mcp/package.json +2 -2
- package/packages/memory/package.json +2 -2
- package/packages/policy/package.json +2 -2
- package/packages/protocol/dist/types.d.ts +46 -1
- package/packages/protocol/package.json +1 -1
- package/packages/resiliency/package.json +1 -1
- package/packages/sdk/dist/client.d.ts +22 -1
- package/packages/sdk/dist/client.js +31 -0
- package/packages/sdk/dist/protocol/index.d.ts +1 -1
- package/packages/sdk/dist/protocol/types.d.ts +35 -1
- package/packages/sdk/package.json +2 -2
- package/packages/spawner/package.json +1 -1
- package/packages/state/package.json +1 -1
- package/packages/storage/dist/adapter.d.ts +4 -0
- package/packages/storage/dist/sqlite-adapter.d.ts +10 -0
- package/packages/storage/dist/sqlite-adapter.js +26 -0
- package/packages/storage/package.json +2 -2
- package/packages/telemetry/package.json +1 -1
- package/packages/trajectory/package.json +2 -2
- package/packages/user-directory/package.json +2 -2
- package/packages/utils/dist/update-checker.js +4 -0
- package/packages/utils/package.json +1 -1
- package/packages/wrapper/package.json +6 -6
- package/deploy/workspace/codex.config.toml +0 -20
- package/deploy/workspace/entrypoint-browser.sh +0 -118
- package/deploy/workspace/entrypoint.sh +0 -612
- package/deploy/workspace/gh-credential-relay +0 -90
- package/deploy/workspace/gh-relay +0 -156
- package/deploy/workspace/git-credential-relay +0 -330
- package/deploy/workspace/git-credential-relay.test.sh +0 -230
- package/dist/dashboard/out/404.html +0 -1
- package/dist/dashboard/out/_next/static/7MZPqYkVGw3EGzVBkVmY9/_buildManifest.js +0 -1
- package/dist/dashboard/out/_next/static/7MZPqYkVGw3EGzVBkVmY9/_ssgManifest.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/116-a883fca163f3a5bc.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/117-c8afed19e821a35d.js +0 -2
- package/dist/dashboard/out/_next/static/chunks/282-980c2eb8fff20123.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/320-a6304232cd0ee2ce.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/532-bace199897eeab37.js +0 -9
- package/dist/dashboard/out/_next/static/chunks/631-16b905e5920f9b59.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/648-acb2ff9f77cbfbd3.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/766-2aea80818f7eb0d8.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/83-26d2bde54616ee90.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/847-f1f467060f32afff.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/891-5cb1513eeb97a891.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/_not-found/page-60501fddbafba9dc.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/app/onboarding/page-9914652442f7e4fb.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/app/page-366fb7c078d4e9e0.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/cloud/link/page-fa1d5842aa90e8a6.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/complete-profile/page-dd64bbdf66b639cd.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/connect-repos/page-113060009ef35bc2.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/history/page-9965d2483011b846.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/layout-6b91e33784c20610.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/login/page-435eceb0073be027.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/metrics/page-1e37ef8e73940b40.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/page-8119d4246743574e.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/pricing/page-9db3ebdfa567a7c9.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/providers/page-ecb16ffd3b36262b.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/providers/setup/[provider]/page-4dbe33f0f7691b7c.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/signup/page-c7a0a28341365ae0.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/e868780c-48e5f147c90a3a41.js +0 -18
- package/dist/dashboard/out/_next/static/chunks/fd9d1056-609918ca7b6280bb.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/framework-f66176bb897dc684.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/main-311c3db74dcfadb7.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/main-app-fdbeb09028f57c9f.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/pages/_app-72b849fbd24ac258.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/pages/_error-7ba65e1336b92748.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/webpack-1cdd8ed57114d5e1.js +0 -1
- package/dist/dashboard/out/_next/static/css/4034f236dd1a3178.css +0 -1
- package/dist/dashboard/out/_next/static/css/6892f8422896ef7a.css +0 -1
- package/dist/dashboard/out/alt-logos/agent-relay-logo-128.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo-256.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo-32.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo-512.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo-64.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo.svg +0 -45
- package/dist/dashboard/out/alt-logos/logo.svg +0 -38
- package/dist/dashboard/out/alt-logos/monogram-logo-128.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo-256.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo-32.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo-512.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo-64.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo.svg +0 -38
- package/dist/dashboard/out/app/onboarding.html +0 -1
- package/dist/dashboard/out/app/onboarding.txt +0 -7
- package/dist/dashboard/out/app.html +0 -1
- package/dist/dashboard/out/app.txt +0 -7
- package/dist/dashboard/out/apple-icon.png +0 -0
- package/dist/dashboard/out/cloud/link.html +0 -1
- package/dist/dashboard/out/cloud/link.txt +0 -7
- package/dist/dashboard/out/complete-profile.html +0 -5
- package/dist/dashboard/out/complete-profile.txt +0 -7
- package/dist/dashboard/out/connect-repos.html +0 -1
- package/dist/dashboard/out/connect-repos.txt +0 -7
- package/dist/dashboard/out/history.html +0 -1
- package/dist/dashboard/out/history.txt +0 -7
- package/dist/dashboard/out/index.html +0 -1
- package/dist/dashboard/out/index.txt +0 -7
- package/dist/dashboard/out/login.html +0 -5
- package/dist/dashboard/out/login.txt +0 -7
- package/dist/dashboard/out/metrics.html +0 -1
- package/dist/dashboard/out/metrics.txt +0 -7
- package/dist/dashboard/out/pricing.html +0 -13
- package/dist/dashboard/out/pricing.txt +0 -7
- package/dist/dashboard/out/providers/setup/claude.html +0 -1
- package/dist/dashboard/out/providers/setup/claude.txt +0 -8
- package/dist/dashboard/out/providers/setup/codex.html +0 -1
- package/dist/dashboard/out/providers/setup/codex.txt +0 -8
- package/dist/dashboard/out/providers/setup/cursor.html +0 -1
- package/dist/dashboard/out/providers/setup/cursor.txt +0 -8
- package/dist/dashboard/out/providers.html +0 -1
- package/dist/dashboard/out/providers.txt +0 -7
- package/dist/dashboard/out/signup.html +0 -6
- package/dist/dashboard/out/signup.txt +0 -7
- package/dist/src/dashboard-server/index.d.ts +0 -8
- package/dist/src/dashboard-server/index.js +0 -8
- package/packages/dashboard/README.md +0 -48
- package/packages/dashboard/dist/health-worker-manager.d.ts +0 -62
- package/packages/dashboard/dist/health-worker-manager.js +0 -144
- package/packages/dashboard/dist/health-worker.d.ts +0 -9
- package/packages/dashboard/dist/health-worker.js +0 -79
- package/packages/dashboard/dist/index.d.ts +0 -20
- package/packages/dashboard/dist/index.js +0 -19
- package/packages/dashboard/dist/metrics.d.ts +0 -105
- package/packages/dashboard/dist/metrics.js +0 -193
- package/packages/dashboard/dist/needs-attention.d.ts +0 -24
- package/packages/dashboard/dist/needs-attention.js +0 -78
- package/packages/dashboard/dist/server.d.ts +0 -25
- package/packages/dashboard/dist/server.js +0 -5270
- package/packages/dashboard/dist/start.d.ts +0 -6
- package/packages/dashboard/dist/start.js +0 -13
- package/packages/dashboard/dist/types/threading.d.ts +0 -8
- package/packages/dashboard/dist/types/threading.js +0 -2
- package/packages/dashboard/dist/user-bridge.d.ts +0 -154
- package/packages/dashboard/dist/user-bridge.js +0 -372
- package/packages/dashboard/package.json +0 -65
- package/packages/dashboard/ui/app/app/onboarding/page.tsx +0 -394
- package/packages/dashboard/ui/app/app/page.tsx +0 -667
- package/packages/dashboard/ui/app/apple-icon.png +0 -0
- package/packages/dashboard/ui/app/cloud/link/page.tsx +0 -464
- package/packages/dashboard/ui/app/complete-profile/page.tsx +0 -204
- package/packages/dashboard/ui/app/connect-repos/page.tsx +0 -410
- package/packages/dashboard/ui/app/favicon.png +0 -0
- package/packages/dashboard/ui/app/globals.css +0 -59
- package/packages/dashboard/ui/app/history/page.tsx +0 -658
- package/packages/dashboard/ui/app/layout.tsx +0 -25
- package/packages/dashboard/ui/app/login/page.tsx +0 -424
- package/packages/dashboard/ui/app/metrics/page.tsx +0 -751
- package/packages/dashboard/ui/app/page.tsx +0 -59
- package/packages/dashboard/ui/app/pricing/page.tsx +0 -7
- package/packages/dashboard/ui/app/providers/page.tsx +0 -193
- package/packages/dashboard/ui/app/providers/setup/[provider]/ProviderSetupClient.tsx +0 -148
- package/packages/dashboard/ui/app/providers/setup/[provider]/constants.ts +0 -35
- package/packages/dashboard/ui/app/providers/setup/[provider]/page.tsx +0 -42
- package/packages/dashboard/ui/app/signup/page.tsx +0 -533
- package/packages/dashboard/ui/index.ts +0 -49
- package/packages/dashboard/ui/landing/LandingPage.tsx +0 -713
- package/packages/dashboard/ui/landing/PricingPage.tsx +0 -559
- package/packages/dashboard/ui/landing/index.ts +0 -6
- package/packages/dashboard/ui/landing/styles.css +0 -2850
- package/packages/dashboard/ui/lib/agent-merge.ts +0 -35
- package/packages/dashboard/ui/lib/api.ts +0 -1155
- package/packages/dashboard/ui/lib/cloudApi.ts +0 -877
- package/packages/dashboard/ui/lib/colors.ts +0 -218
- package/packages/dashboard/ui/lib/hierarchy.ts +0 -242
- package/packages/dashboard/ui/lib/stuckDetection.ts +0 -142
- package/packages/dashboard/ui/next-env.d.ts +0 -5
- package/packages/dashboard/ui/next.config.js +0 -41
- package/packages/dashboard/ui/package-lock.json +0 -2882
- package/packages/dashboard/ui/package.json +0 -33
- package/packages/dashboard/ui/postcss.config.js +0 -5
- package/packages/dashboard/ui/react-components/ActivityFeed.tsx +0 -216
- package/packages/dashboard/ui/react-components/AddWorkspaceModal.tsx +0 -170
- package/packages/dashboard/ui/react-components/AgentCard.tsx +0 -587
- package/packages/dashboard/ui/react-components/AgentList.tsx +0 -411
- package/packages/dashboard/ui/react-components/AgentProfilePanel.tsx +0 -564
- package/packages/dashboard/ui/react-components/App.tsx +0 -3033
- package/packages/dashboard/ui/react-components/BillingPanel.tsx +0 -922
- package/packages/dashboard/ui/react-components/BillingResult.tsx +0 -447
- package/packages/dashboard/ui/react-components/BroadcastComposer.tsx +0 -690
- package/packages/dashboard/ui/react-components/ChannelAdminPanel.tsx +0 -773
- package/packages/dashboard/ui/react-components/ChannelBrowser.tsx +0 -385
- package/packages/dashboard/ui/react-components/ChannelChat.tsx +0 -261
- package/packages/dashboard/ui/react-components/ChannelSidebar.tsx +0 -399
- package/packages/dashboard/ui/react-components/CloudSessionProvider.tsx +0 -130
- package/packages/dashboard/ui/react-components/CommandPalette.tsx +0 -815
- package/packages/dashboard/ui/react-components/ConfirmationDialog.tsx +0 -133
- package/packages/dashboard/ui/react-components/ConversationHistory.tsx +0 -518
- package/packages/dashboard/ui/react-components/CoordinatorPanel.tsx +0 -944
- package/packages/dashboard/ui/react-components/DecisionQueue.tsx +0 -717
- package/packages/dashboard/ui/react-components/DirectMessageView.tsx +0 -164
- package/packages/dashboard/ui/react-components/FileAutocomplete.tsx +0 -368
- package/packages/dashboard/ui/react-components/FleetOverview.tsx +0 -278
- package/packages/dashboard/ui/react-components/LogViewer.tsx +0 -310
- package/packages/dashboard/ui/react-components/LogViewerPanel.tsx +0 -482
- package/packages/dashboard/ui/react-components/Logo.tsx +0 -284
- package/packages/dashboard/ui/react-components/MentionAutocomplete.tsx +0 -384
- package/packages/dashboard/ui/react-components/MessageComposer.tsx +0 -457
- package/packages/dashboard/ui/react-components/MessageList.tsx +0 -649
- package/packages/dashboard/ui/react-components/MessageSenderName.tsx +0 -91
- package/packages/dashboard/ui/react-components/MessageStatusIndicator.tsx +0 -142
- package/packages/dashboard/ui/react-components/NewConversationModal.tsx +0 -400
- package/packages/dashboard/ui/react-components/NotificationToast.tsx +0 -488
- package/packages/dashboard/ui/react-components/OnlineUsersIndicator.tsx +0 -164
- package/packages/dashboard/ui/react-components/Pagination.tsx +0 -124
- package/packages/dashboard/ui/react-components/PricingPlans.tsx +0 -386
- package/packages/dashboard/ui/react-components/ProjectList.tsx +0 -625
- package/packages/dashboard/ui/react-components/ProviderAuthFlow.tsx +0 -853
- package/packages/dashboard/ui/react-components/ProviderConnectionList.tsx +0 -378
- package/packages/dashboard/ui/react-components/ProvisioningProgress.tsx +0 -730
- package/packages/dashboard/ui/react-components/RepoAccessPanel.tsx +0 -549
- package/packages/dashboard/ui/react-components/ServerCard.tsx +0 -202
- package/packages/dashboard/ui/react-components/SessionExpiredModal.tsx +0 -128
- package/packages/dashboard/ui/react-components/SpawnModal.tsx +0 -804
- package/packages/dashboard/ui/react-components/TaskAssignmentUI.tsx +0 -375
- package/packages/dashboard/ui/react-components/TerminalProviderSetup.tsx +0 -608
- package/packages/dashboard/ui/react-components/ThemeProvider.tsx +0 -325
- package/packages/dashboard/ui/react-components/ThinkingIndicator.tsx +0 -231
- package/packages/dashboard/ui/react-components/ThreadList.tsx +0 -198
- package/packages/dashboard/ui/react-components/ThreadPanel.tsx +0 -346
- package/packages/dashboard/ui/react-components/TrajectoryViewer.tsx +0 -698
- package/packages/dashboard/ui/react-components/TypingIndicator.tsx +0 -69
- package/packages/dashboard/ui/react-components/UsageBanner.tsx +0 -231
- package/packages/dashboard/ui/react-components/UserProfilePanel.tsx +0 -233
- package/packages/dashboard/ui/react-components/WorkspaceContext.tsx +0 -107
- package/packages/dashboard/ui/react-components/WorkspaceSelector.tsx +0 -234
- package/packages/dashboard/ui/react-components/WorkspaceStatusIndicator.tsx +0 -370
- package/packages/dashboard/ui/react-components/XTermInteractive.tsx +0 -510
- package/packages/dashboard/ui/react-components/XTermLogViewer.tsx +0 -719
- package/packages/dashboard/ui/react-components/channels/ChannelDialogs.tsx +0 -1411
- package/packages/dashboard/ui/react-components/channels/ChannelHeader.tsx +0 -317
- package/packages/dashboard/ui/react-components/channels/ChannelMessageList.tsx +0 -463
- package/packages/dashboard/ui/react-components/channels/ChannelViewV1.tsx +0 -146
- package/packages/dashboard/ui/react-components/channels/MessageInput.tsx +0 -288
- package/packages/dashboard/ui/react-components/channels/SearchInput.tsx +0 -172
- package/packages/dashboard/ui/react-components/channels/SearchResults.tsx +0 -336
- package/packages/dashboard/ui/react-components/channels/api.ts +0 -697
- package/packages/dashboard/ui/react-components/channels/index.ts +0 -76
- package/packages/dashboard/ui/react-components/channels/mockApi.ts +0 -344
- package/packages/dashboard/ui/react-components/channels/types.ts +0 -566
- package/packages/dashboard/ui/react-components/hooks/index.ts +0 -57
- package/packages/dashboard/ui/react-components/hooks/useAgentLogs.ts +0 -394
- package/packages/dashboard/ui/react-components/hooks/useAgents.ts +0 -127
- package/packages/dashboard/ui/react-components/hooks/useBroadcastDedup.ts +0 -86
- package/packages/dashboard/ui/react-components/hooks/useChannelAdmin.ts +0 -329
- package/packages/dashboard/ui/react-components/hooks/useChannelBrowser.ts +0 -239
- package/packages/dashboard/ui/react-components/hooks/useChannelCommands.ts +0 -138
- package/packages/dashboard/ui/react-components/hooks/useChannels.ts +0 -328
- package/packages/dashboard/ui/react-components/hooks/useDebounce.ts +0 -29
- package/packages/dashboard/ui/react-components/hooks/useDirectMessage.ts +0 -141
- package/packages/dashboard/ui/react-components/hooks/useMessages.ts +0 -309
- package/packages/dashboard/ui/react-components/hooks/useOrchestrator.ts +0 -364
- package/packages/dashboard/ui/react-components/hooks/usePinnedAgents.ts +0 -140
- package/packages/dashboard/ui/react-components/hooks/usePresence.ts +0 -340
- package/packages/dashboard/ui/react-components/hooks/useRecentRepos.ts +0 -130
- package/packages/dashboard/ui/react-components/hooks/useSession.ts +0 -209
- package/packages/dashboard/ui/react-components/hooks/useTrajectory.ts +0 -265
- package/packages/dashboard/ui/react-components/hooks/useWebSocket.ts +0 -169
- package/packages/dashboard/ui/react-components/hooks/useWorkspaceMembers.ts +0 -120
- package/packages/dashboard/ui/react-components/hooks/useWorkspaceRepos.ts +0 -73
- package/packages/dashboard/ui/react-components/hooks/useWorkspaceStatus.ts +0 -237
- package/packages/dashboard/ui/react-components/index.ts +0 -81
- package/packages/dashboard/ui/react-components/layout/Header.tsx +0 -355
- package/packages/dashboard/ui/react-components/layout/RepoContextHeader.tsx +0 -361
- package/packages/dashboard/ui/react-components/layout/Sidebar.archive.test.tsx +0 -126
- package/packages/dashboard/ui/react-components/layout/Sidebar.test.tsx +0 -691
- package/packages/dashboard/ui/react-components/layout/Sidebar.tsx +0 -930
- package/packages/dashboard/ui/react-components/layout/index.ts +0 -7
- package/packages/dashboard/ui/react-components/settings/BillingSettingsPanel.tsx +0 -564
- package/packages/dashboard/ui/react-components/settings/SettingsPage.tsx +0 -544
- package/packages/dashboard/ui/react-components/settings/TeamSettingsPanel.tsx +0 -560
- package/packages/dashboard/ui/react-components/settings/WorkspaceSettingsPanel.tsx +0 -1386
- package/packages/dashboard/ui/react-components/settings/index.ts +0 -11
- package/packages/dashboard/ui/react-components/settings/types.ts +0 -53
- package/packages/dashboard/ui/react-components/utils/messageFormatting.tsx +0 -370
- package/packages/dashboard/ui/tailwind.config.js +0 -148
- package/packages/dashboard/ui/types/index.ts +0 -304
- package/packages/dashboard/ui/types/threading.ts +0 -7
- package/packages/dashboard/ui-dist/404.html +0 -1
- package/packages/dashboard/ui-dist/_next/static/7MZPqYkVGw3EGzVBkVmY9/_buildManifest.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/7MZPqYkVGw3EGzVBkVmY9/_ssgManifest.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/116-a883fca163f3a5bc.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/117-c8afed19e821a35d.js +0 -2
- package/packages/dashboard/ui-dist/_next/static/chunks/282-980c2eb8fff20123.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/320-a6304232cd0ee2ce.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/532-bace199897eeab37.js +0 -9
- package/packages/dashboard/ui-dist/_next/static/chunks/631-16b905e5920f9b59.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/648-acb2ff9f77cbfbd3.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/766-2aea80818f7eb0d8.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/83-26d2bde54616ee90.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/847-f1f467060f32afff.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/891-5cb1513eeb97a891.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/_not-found/page-60501fddbafba9dc.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/app/onboarding/page-9914652442f7e4fb.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/app/page-366fb7c078d4e9e0.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/cloud/link/page-fa1d5842aa90e8a6.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/complete-profile/page-dd64bbdf66b639cd.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/connect-repos/page-113060009ef35bc2.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/history/page-9965d2483011b846.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/layout-6b91e33784c20610.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/login/page-435eceb0073be027.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/metrics/page-1e37ef8e73940b40.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/page-8119d4246743574e.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/pricing/page-9db3ebdfa567a7c9.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/providers/page-ecb16ffd3b36262b.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/providers/setup/[provider]/page-4dbe33f0f7691b7c.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/signup/page-c7a0a28341365ae0.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/e868780c-48e5f147c90a3a41.js +0 -18
- package/packages/dashboard/ui-dist/_next/static/chunks/fd9d1056-609918ca7b6280bb.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/framework-f66176bb897dc684.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/main-311c3db74dcfadb7.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/main-app-fdbeb09028f57c9f.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/pages/_app-72b849fbd24ac258.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/pages/_error-7ba65e1336b92748.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/webpack-1cdd8ed57114d5e1.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/css/4034f236dd1a3178.css +0 -1
- package/packages/dashboard/ui-dist/_next/static/css/6892f8422896ef7a.css +0 -1
- package/packages/dashboard/ui-dist/_next/static/iJ3Uiz3IrqUJL7IxKZHiV/_buildManifest.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/iJ3Uiz3IrqUJL7IxKZHiV/_ssgManifest.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/l-jd878zUJ_IlraqEWMZc/_buildManifest.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/l-jd878zUJ_IlraqEWMZc/_ssgManifest.js +0 -1
- package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-128.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-256.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-32.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-512.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-64.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo.svg +0 -45
- package/packages/dashboard/ui-dist/alt-logos/logo.svg +0 -38
- package/packages/dashboard/ui-dist/alt-logos/monogram-logo-128.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/monogram-logo-256.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/monogram-logo-32.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/monogram-logo-512.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/monogram-logo-64.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/monogram-logo.svg +0 -38
- package/packages/dashboard/ui-dist/app/onboarding.html +0 -1
- package/packages/dashboard/ui-dist/app/onboarding.txt +0 -7
- package/packages/dashboard/ui-dist/app.html +0 -1
- package/packages/dashboard/ui-dist/app.txt +0 -7
- package/packages/dashboard/ui-dist/apple-icon.png +0 -0
- package/packages/dashboard/ui-dist/cloud/link.html +0 -1
- package/packages/dashboard/ui-dist/cloud/link.txt +0 -7
- package/packages/dashboard/ui-dist/complete-profile.html +0 -5
- package/packages/dashboard/ui-dist/complete-profile.txt +0 -7
- package/packages/dashboard/ui-dist/connect-repos.html +0 -1
- package/packages/dashboard/ui-dist/connect-repos.txt +0 -7
- package/packages/dashboard/ui-dist/history.html +0 -1
- package/packages/dashboard/ui-dist/history.txt +0 -7
- package/packages/dashboard/ui-dist/index.html +0 -1
- package/packages/dashboard/ui-dist/index.txt +0 -7
- package/packages/dashboard/ui-dist/login.html +0 -5
- package/packages/dashboard/ui-dist/login.txt +0 -7
- package/packages/dashboard/ui-dist/metrics.html +0 -1
- package/packages/dashboard/ui-dist/metrics.txt +0 -7
- package/packages/dashboard/ui-dist/pricing.html +0 -13
- package/packages/dashboard/ui-dist/pricing.txt +0 -7
- package/packages/dashboard/ui-dist/providers/setup/claude.html +0 -1
- package/packages/dashboard/ui-dist/providers/setup/claude.txt +0 -8
- package/packages/dashboard/ui-dist/providers/setup/codex.html +0 -1
- package/packages/dashboard/ui-dist/providers/setup/codex.txt +0 -8
- package/packages/dashboard/ui-dist/providers/setup/cursor.html +0 -1
- package/packages/dashboard/ui-dist/providers/setup/cursor.txt +0 -8
- package/packages/dashboard/ui-dist/providers.html +0 -1
- package/packages/dashboard/ui-dist/providers.txt +0 -7
- package/packages/dashboard/ui-dist/signup.html +0 -6
- package/packages/dashboard/ui-dist/signup.txt +0 -7
- package/packages/dashboard-server/dist/health-worker-manager.d.ts +0 -62
- package/packages/dashboard-server/dist/health-worker-manager.js +0 -144
- package/packages/dashboard-server/dist/health-worker.d.ts +0 -9
- package/packages/dashboard-server/dist/health-worker.js +0 -79
- package/packages/dashboard-server/dist/index.d.ts +0 -18
- package/packages/dashboard-server/dist/index.js +0 -17
- package/packages/dashboard-server/dist/metrics.d.ts +0 -105
- package/packages/dashboard-server/dist/metrics.js +0 -193
- package/packages/dashboard-server/dist/needs-attention.d.ts +0 -24
- package/packages/dashboard-server/dist/needs-attention.js +0 -78
- package/packages/dashboard-server/dist/server.d.ts +0 -25
- package/packages/dashboard-server/dist/server.js +0 -5158
- package/packages/dashboard-server/dist/start.d.ts +0 -6
- package/packages/dashboard-server/dist/start.js +0 -13
- package/packages/dashboard-server/dist/types/threading.d.ts +0 -8
- package/packages/dashboard-server/dist/types/threading.js +0 -2
- package/packages/dashboard-server/dist/user-bridge.d.ts +0 -158
- package/packages/dashboard-server/dist/user-bridge.js +0 -390
- package/packages/dashboard-server/package.json +0 -55
|
@@ -1,804 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SpawnModal Component
|
|
3
|
-
*
|
|
4
|
-
* Modal for spawning new agent instances with configuration options.
|
|
5
|
-
* Supports different agent types (claude, codex, etc.) and naming conventions.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import React, { useState, useRef, useEffect, useCallback, useMemo } from 'react';
|
|
9
|
-
import { getAgentColor, getAgentInitials } from '../lib/colors';
|
|
10
|
-
import { cloudApi } from '../lib/cloudApi';
|
|
11
|
-
|
|
12
|
-
export type SpeakOnTrigger = 'SESSION_END' | 'CODE_WRITTEN' | 'REVIEW_REQUEST' | 'EXPLICIT_ASK' | 'ALL_MESSAGES';
|
|
13
|
-
|
|
14
|
-
export interface SpawnConfig {
|
|
15
|
-
name: string;
|
|
16
|
-
command: string;
|
|
17
|
-
cwd?: string;
|
|
18
|
-
team?: string;
|
|
19
|
-
shadowMode?: 'subagent' | 'process';
|
|
20
|
-
shadowOf?: string;
|
|
21
|
-
shadowAgent?: string;
|
|
22
|
-
shadowTriggers?: SpeakOnTrigger[];
|
|
23
|
-
shadowSpeakOn?: SpeakOnTrigger[];
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function deriveShadowMode(command: string): 'subagent' | 'process' {
|
|
27
|
-
const base = command.trim().split(' ')[0].toLowerCase();
|
|
28
|
-
if (base.startsWith('claude') || base === 'codex' || base === 'opencode' || base === 'gemini' || base === 'droid' || base === 'cursor') return 'subagent';
|
|
29
|
-
return 'process';
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface SpawnModalProps {
|
|
33
|
-
isOpen: boolean;
|
|
34
|
-
onClose: () => void;
|
|
35
|
-
onSpawn: (config: SpawnConfig) => Promise<boolean>;
|
|
36
|
-
existingAgents: string[];
|
|
37
|
-
isSpawning?: boolean;
|
|
38
|
-
error?: string | null;
|
|
39
|
-
/** Whether running in cloud mode (enables credentials check) */
|
|
40
|
-
isCloudMode?: boolean;
|
|
41
|
-
/** Active workspace ID for provider setup redirect */
|
|
42
|
-
workspaceId?: string;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/** Model options for Claude agents */
|
|
46
|
-
const CLAUDE_MODEL_OPTIONS: { value: string; label: string }[] = [
|
|
47
|
-
{ value: 'sonnet', label: 'Sonnet' },
|
|
48
|
-
{ value: 'opus', label: 'Opus' },
|
|
49
|
-
{ value: 'haiku', label: 'Haiku' },
|
|
50
|
-
];
|
|
51
|
-
|
|
52
|
-
type ClaudeModel = string;
|
|
53
|
-
|
|
54
|
-
/** Model options for Cursor agents */
|
|
55
|
-
const CURSOR_MODEL_OPTIONS: { value: string; label: string }[] = [
|
|
56
|
-
{ value: 'opus-4.5-thinking', label: 'Claude 4.5 Opus (Thinking)' },
|
|
57
|
-
{ value: 'opus-4.5', label: 'Claude 4.5 Opus' },
|
|
58
|
-
{ value: 'sonnet-4.5', label: 'Claude 4.5 Sonnet' },
|
|
59
|
-
{ value: 'sonnet-4.5-thinking', label: 'Claude 4.5 Sonnet (Thinking)' },
|
|
60
|
-
{ value: 'gpt-5.2-codex', label: 'GPT-5.2 Codex' },
|
|
61
|
-
{ value: 'gpt-5.2-codex-high', label: 'GPT-5.2 Codex High' },
|
|
62
|
-
{ value: 'gpt-5.2-codex-low', label: 'GPT-5.2 Codex Low' },
|
|
63
|
-
{ value: 'gpt-5.2-codex-xhigh', label: 'GPT-5.2 Codex Extra High' },
|
|
64
|
-
{ value: 'gpt-5.2-codex-fast', label: 'GPT-5.2 Codex Fast' },
|
|
65
|
-
{ value: 'gpt-5.2-codex-high-fast', label: 'GPT-5.2 Codex High Fast' },
|
|
66
|
-
{ value: 'gpt-5.2-codex-low-fast', label: 'GPT-5.2 Codex Low Fast' },
|
|
67
|
-
{ value: 'gpt-5.2-codex-xhigh-fast', label: 'GPT-5.2 Codex Extra High Fast' },
|
|
68
|
-
{ value: 'gpt-5.1-codex-max', label: 'GPT-5.1 Codex Max' },
|
|
69
|
-
{ value: 'gpt-5.1-codex-max-high', label: 'GPT-5.1 Codex Max High' },
|
|
70
|
-
{ value: 'gpt-5.2', label: 'GPT-5.2' },
|
|
71
|
-
{ value: 'gpt-5.2-high', label: 'GPT-5.2 High' },
|
|
72
|
-
{ value: 'gpt-5.1-high', label: 'GPT-5.1 High' },
|
|
73
|
-
{ value: 'gemini-3-pro', label: 'Gemini 3 Pro' },
|
|
74
|
-
{ value: 'gemini-3-flash', label: 'Gemini 3 Flash' },
|
|
75
|
-
{ value: 'composer-1', label: 'Composer 1' },
|
|
76
|
-
{ value: 'grok', label: 'Grok' },
|
|
77
|
-
];
|
|
78
|
-
|
|
79
|
-
type CursorModel = string;
|
|
80
|
-
|
|
81
|
-
/** Model options for Codex agents */
|
|
82
|
-
const CODEX_MODEL_OPTIONS: { value: string; label: string }[] = [
|
|
83
|
-
{ value: 'gpt-5.2-codex', label: 'GPT-5.2 Codex' },
|
|
84
|
-
{ value: 'gpt-5.1-codex-max', label: 'GPT-5.1 Codex Max' },
|
|
85
|
-
{ value: 'gpt-5.1-codex-mini', label: 'GPT-5.1 Codex Mini' },
|
|
86
|
-
{ value: 'gpt-5.2', label: 'GPT-5.2' },
|
|
87
|
-
];
|
|
88
|
-
|
|
89
|
-
type CodexModel = string;
|
|
90
|
-
|
|
91
|
-
const AGENT_TEMPLATES = [
|
|
92
|
-
{
|
|
93
|
-
id: 'claude',
|
|
94
|
-
name: 'Claude',
|
|
95
|
-
command: 'claude',
|
|
96
|
-
description: 'Claude Code CLI agent',
|
|
97
|
-
icon: '🤖',
|
|
98
|
-
providerId: 'anthropic', // Maps to provider credential ID
|
|
99
|
-
supportsModelSelection: true,
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
id: 'codex',
|
|
103
|
-
name: 'Codex',
|
|
104
|
-
command: 'codex',
|
|
105
|
-
description: 'OpenAI Codex agent',
|
|
106
|
-
icon: '⚡',
|
|
107
|
-
providerId: 'codex', // Backend uses 'openai', but we check for both
|
|
108
|
-
supportsModelSelection: true,
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
id: 'gemini',
|
|
112
|
-
name: 'Gemini',
|
|
113
|
-
command: 'gemini',
|
|
114
|
-
description: 'Google Gemini CLI agent',
|
|
115
|
-
icon: '💎',
|
|
116
|
-
providerId: 'google',
|
|
117
|
-
},
|
|
118
|
-
{
|
|
119
|
-
id: 'opencode',
|
|
120
|
-
name: 'OpenCode',
|
|
121
|
-
command: 'opencode',
|
|
122
|
-
description: 'OpenCode AI agent',
|
|
123
|
-
icon: '🔷',
|
|
124
|
-
providerId: 'opencode',
|
|
125
|
-
comingSoon: true, // Not yet fully tested
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
id: 'droid',
|
|
129
|
-
name: 'Droid',
|
|
130
|
-
command: 'droid',
|
|
131
|
-
description: 'Factory Droid agent',
|
|
132
|
-
icon: '🤖',
|
|
133
|
-
providerId: 'droid',
|
|
134
|
-
comingSoon: true, // Not yet fully tested
|
|
135
|
-
},
|
|
136
|
-
{
|
|
137
|
-
id: 'cursor',
|
|
138
|
-
name: 'Cursor',
|
|
139
|
-
command: 'cursor',
|
|
140
|
-
description: 'Cursor AI agent',
|
|
141
|
-
icon: '📝',
|
|
142
|
-
providerId: 'cursor',
|
|
143
|
-
supportsModelSelection: true,
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
id: 'custom',
|
|
147
|
-
name: 'Custom',
|
|
148
|
-
command: '',
|
|
149
|
-
description: 'Custom command',
|
|
150
|
-
icon: '🔧',
|
|
151
|
-
providerId: null, // Custom commands don't require credentials check
|
|
152
|
-
},
|
|
153
|
-
];
|
|
154
|
-
|
|
155
|
-
export function SpawnModal({
|
|
156
|
-
isOpen,
|
|
157
|
-
onClose,
|
|
158
|
-
onSpawn,
|
|
159
|
-
existingAgents,
|
|
160
|
-
isSpawning = false,
|
|
161
|
-
error,
|
|
162
|
-
isCloudMode = false,
|
|
163
|
-
workspaceId,
|
|
164
|
-
}: SpawnModalProps) {
|
|
165
|
-
const [selectedTemplate, setSelectedTemplate] = useState(AGENT_TEMPLATES[0]);
|
|
166
|
-
const [name, setName] = useState('');
|
|
167
|
-
const [customCommand, setCustomCommand] = useState('');
|
|
168
|
-
const [selectedModel, setSelectedModel] = useState<ClaudeModel>('sonnet');
|
|
169
|
-
const [selectedCursorModel, setSelectedCursorModel] = useState<CursorModel>('opus-4.5-thinking');
|
|
170
|
-
const [selectedCodexModel, setSelectedCodexModel] = useState<CodexModel>('gpt-5.2-codex');
|
|
171
|
-
const [cwd, setCwd] = useState('');
|
|
172
|
-
const [team, setTeam] = useState('');
|
|
173
|
-
const [isShadow, setIsShadow] = useState(false);
|
|
174
|
-
const [shadowOf, setShadowOf] = useState('');
|
|
175
|
-
const [shadowAgent, setShadowAgent] = useState('');
|
|
176
|
-
const [shadowSpeakOn, setShadowSpeakOn] = useState<SpeakOnTrigger[]>(['EXPLICIT_ASK']);
|
|
177
|
-
const [localError, setLocalError] = useState<string | null>(null);
|
|
178
|
-
const nameInputRef = useRef<HTMLInputElement>(null);
|
|
179
|
-
|
|
180
|
-
// Build effective command, always including model flag for Claude, Cursor, and Codex
|
|
181
|
-
const effectiveCommand = useMemo(() => {
|
|
182
|
-
if (selectedTemplate.id === 'custom') {
|
|
183
|
-
return customCommand;
|
|
184
|
-
}
|
|
185
|
-
// For Claude, always append model flag
|
|
186
|
-
if (selectedTemplate.id === 'claude') {
|
|
187
|
-
return `${selectedTemplate.command} --model ${selectedModel}`;
|
|
188
|
-
}
|
|
189
|
-
// For Cursor, always append model flag
|
|
190
|
-
if (selectedTemplate.id === 'cursor') {
|
|
191
|
-
return `${selectedTemplate.command} --model ${selectedCursorModel}`;
|
|
192
|
-
}
|
|
193
|
-
// For Codex, always append model flag
|
|
194
|
-
if (selectedTemplate.id === 'codex') {
|
|
195
|
-
return `${selectedTemplate.command} --model ${selectedCodexModel}`;
|
|
196
|
-
}
|
|
197
|
-
return selectedTemplate.command;
|
|
198
|
-
}, [selectedTemplate, customCommand, selectedModel, selectedCursorModel, selectedCodexModel]);
|
|
199
|
-
|
|
200
|
-
const shadowMode = useMemo(() => deriveShadowMode(effectiveCommand), [effectiveCommand]);
|
|
201
|
-
|
|
202
|
-
// Provider credentials state (for cloud mode)
|
|
203
|
-
const [connectedProviders, setConnectedProviders] = useState<Set<string>>(new Set());
|
|
204
|
-
const [isLoadingCredentials, setIsLoadingCredentials] = useState(false);
|
|
205
|
-
|
|
206
|
-
// Check if selected provider has active credentials
|
|
207
|
-
const hasActiveCredentials = useMemo(() => {
|
|
208
|
-
// Non-cloud mode or custom template: no credentials check needed
|
|
209
|
-
if (!isCloudMode || !selectedTemplate.providerId) {
|
|
210
|
-
return true;
|
|
211
|
-
}
|
|
212
|
-
// Check if provider is connected (handle both 'openai' and 'codex' for OpenAI)
|
|
213
|
-
if (selectedTemplate.providerId === 'codex') {
|
|
214
|
-
return connectedProviders.has('codex') || connectedProviders.has('openai');
|
|
215
|
-
}
|
|
216
|
-
return connectedProviders.has(selectedTemplate.providerId);
|
|
217
|
-
}, [isCloudMode, selectedTemplate.providerId, connectedProviders]);
|
|
218
|
-
|
|
219
|
-
// Provider setup URL for CTA
|
|
220
|
-
// Note: /providers/setup/ only supports 'claude' and 'codex'
|
|
221
|
-
// Other providers should go to /providers page
|
|
222
|
-
const providerSetupUrl = useMemo(() => {
|
|
223
|
-
if (!selectedTemplate.providerId) return null;
|
|
224
|
-
const command = selectedTemplate.command;
|
|
225
|
-
const supportedSetupPages = ['claude', 'codex'];
|
|
226
|
-
|
|
227
|
-
if (supportedSetupPages.includes(command)) {
|
|
228
|
-
const base = `/providers/setup/${command}`;
|
|
229
|
-
return workspaceId ? `${base}?workspace=${workspaceId}` : base;
|
|
230
|
-
} else {
|
|
231
|
-
// For other providers, go to main providers page
|
|
232
|
-
return workspaceId ? `/providers?workspace=${workspaceId}` : '/providers';
|
|
233
|
-
}
|
|
234
|
-
}, [selectedTemplate, workspaceId]);
|
|
235
|
-
|
|
236
|
-
// Fetch connected providers when modal opens in cloud mode
|
|
237
|
-
useEffect(() => {
|
|
238
|
-
if (!isOpen || !isCloudMode || !workspaceId) {
|
|
239
|
-
return;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
const fetchProviders = async () => {
|
|
243
|
-
setIsLoadingCredentials(true);
|
|
244
|
-
try {
|
|
245
|
-
// Get workspace-specific provider connection status
|
|
246
|
-
const result = await cloudApi.getProviders(workspaceId);
|
|
247
|
-
if (result.success && result.data.providers) {
|
|
248
|
-
const providers = new Set(
|
|
249
|
-
result.data.providers
|
|
250
|
-
.filter(p => p.isConnected)
|
|
251
|
-
.map(p => p.id)
|
|
252
|
-
);
|
|
253
|
-
setConnectedProviders(providers);
|
|
254
|
-
}
|
|
255
|
-
} catch (err) {
|
|
256
|
-
console.error('Failed to fetch provider credentials:', err);
|
|
257
|
-
} finally {
|
|
258
|
-
setIsLoadingCredentials(false);
|
|
259
|
-
}
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
fetchProviders();
|
|
263
|
-
}, [isOpen, isCloudMode, workspaceId]);
|
|
264
|
-
|
|
265
|
-
const SPEAK_ON_OPTIONS: { value: SpeakOnTrigger; label: string; description: string }[] = [
|
|
266
|
-
{ value: 'EXPLICIT_ASK', label: 'Explicit Ask', description: 'When directly asked' },
|
|
267
|
-
{ value: 'SESSION_END', label: 'Session End', description: 'When session ends' },
|
|
268
|
-
{ value: 'CODE_WRITTEN', label: 'Code Written', description: 'When code is written' },
|
|
269
|
-
{ value: 'REVIEW_REQUEST', label: 'Review Request', description: 'When review requested' },
|
|
270
|
-
{ value: 'ALL_MESSAGES', label: 'All Messages', description: 'On every message' },
|
|
271
|
-
];
|
|
272
|
-
|
|
273
|
-
const suggestedName = useCallback(() => {
|
|
274
|
-
const prefix = selectedTemplate.id === 'claude' ? 'claude' : selectedTemplate.id;
|
|
275
|
-
let num = 1;
|
|
276
|
-
while (existingAgents.includes(`${prefix}-${num}`)) {
|
|
277
|
-
num++;
|
|
278
|
-
}
|
|
279
|
-
return `${prefix}-${num}`;
|
|
280
|
-
}, [selectedTemplate, existingAgents]);
|
|
281
|
-
|
|
282
|
-
useEffect(() => {
|
|
283
|
-
if (isOpen) {
|
|
284
|
-
setSelectedTemplate(AGENT_TEMPLATES[0]);
|
|
285
|
-
setName('');
|
|
286
|
-
setCustomCommand('');
|
|
287
|
-
setSelectedModel('sonnet');
|
|
288
|
-
setSelectedCursorModel('opus-4.5-thinking');
|
|
289
|
-
setSelectedCodexModel('gpt-5.2-codex');
|
|
290
|
-
setCwd('');
|
|
291
|
-
setTeam('');
|
|
292
|
-
setIsShadow(false);
|
|
293
|
-
setShadowOf('');
|
|
294
|
-
setShadowAgent('');
|
|
295
|
-
setShadowSpeakOn(['EXPLICIT_ASK']);
|
|
296
|
-
setLocalError(null);
|
|
297
|
-
setTimeout(() => nameInputRef.current?.focus(), 100);
|
|
298
|
-
}
|
|
299
|
-
}, [isOpen]);
|
|
300
|
-
|
|
301
|
-
const validateName = useCallback(
|
|
302
|
-
(value: string): string | null => {
|
|
303
|
-
if (!value.trim()) {
|
|
304
|
-
return 'Name is required';
|
|
305
|
-
}
|
|
306
|
-
if (!/^[a-zA-Z][a-zA-Z0-9-]*$/.test(value)) {
|
|
307
|
-
return 'Name must start with a letter and contain only letters, numbers, and hyphens';
|
|
308
|
-
}
|
|
309
|
-
if (existingAgents.includes(value)) {
|
|
310
|
-
return 'An agent with this name already exists';
|
|
311
|
-
}
|
|
312
|
-
return null;
|
|
313
|
-
},
|
|
314
|
-
[existingAgents]
|
|
315
|
-
);
|
|
316
|
-
|
|
317
|
-
const handleSubmit = async (e: React.FormEvent) => {
|
|
318
|
-
e.preventDefault();
|
|
319
|
-
|
|
320
|
-
const finalName = name.trim() || suggestedName();
|
|
321
|
-
const nameError = validateName(finalName);
|
|
322
|
-
if (nameError) {
|
|
323
|
-
setLocalError(nameError);
|
|
324
|
-
return;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
const command = effectiveCommand;
|
|
328
|
-
if (!command.trim()) {
|
|
329
|
-
setLocalError('Command is required');
|
|
330
|
-
return;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
if (isShadow && !shadowOf) {
|
|
334
|
-
setLocalError('Please select an agent to shadow');
|
|
335
|
-
return;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
setLocalError(null);
|
|
339
|
-
const success = await onSpawn({
|
|
340
|
-
name: finalName,
|
|
341
|
-
command: command.trim(),
|
|
342
|
-
cwd: cwd.trim() || undefined,
|
|
343
|
-
team: team.trim() || undefined,
|
|
344
|
-
shadowMode: shadowMode,
|
|
345
|
-
shadowOf: isShadow ? shadowOf : undefined,
|
|
346
|
-
shadowAgent: shadowAgent.trim() || undefined,
|
|
347
|
-
shadowTriggers: isShadow ? shadowSpeakOn : undefined,
|
|
348
|
-
shadowSpeakOn: isShadow ? shadowSpeakOn : undefined,
|
|
349
|
-
});
|
|
350
|
-
|
|
351
|
-
if (success) {
|
|
352
|
-
onClose();
|
|
353
|
-
}
|
|
354
|
-
};
|
|
355
|
-
|
|
356
|
-
const handleKeyDown = (e: React.KeyboardEvent) => {
|
|
357
|
-
if (e.key === 'Escape') {
|
|
358
|
-
e.preventDefault();
|
|
359
|
-
onClose();
|
|
360
|
-
}
|
|
361
|
-
};
|
|
362
|
-
|
|
363
|
-
if (!isOpen) return null;
|
|
364
|
-
|
|
365
|
-
const colors = name ? getAgentColor(name) : getAgentColor(suggestedName());
|
|
366
|
-
const displayError = error || localError;
|
|
367
|
-
|
|
368
|
-
return (
|
|
369
|
-
<div
|
|
370
|
-
className="fixed inset-0 bg-black/50 flex items-center justify-center z-[1000] animate-fade-in"
|
|
371
|
-
onClick={onClose}
|
|
372
|
-
>
|
|
373
|
-
<div
|
|
374
|
-
className="bg-bg-primary border border-border rounded-xl w-[480px] max-w-[90vw] max-h-[90vh] overflow-y-auto shadow-modal animate-slide-up"
|
|
375
|
-
onClick={(e) => e.stopPropagation()}
|
|
376
|
-
onKeyDown={handleKeyDown}
|
|
377
|
-
>
|
|
378
|
-
<div className="flex items-center justify-between p-5 border-b border-border">
|
|
379
|
-
<h2 className="m-0 text-lg font-semibold text-text-primary">Spawn New Agent</h2>
|
|
380
|
-
<button
|
|
381
|
-
className="flex items-center justify-center w-8 h-8 bg-transparent border-none rounded-md text-text-muted cursor-pointer transition-all duration-150 hover:bg-bg-hover hover:text-text-primary"
|
|
382
|
-
onClick={onClose}
|
|
383
|
-
aria-label="Close"
|
|
384
|
-
>
|
|
385
|
-
<CloseIcon />
|
|
386
|
-
</button>
|
|
387
|
-
</div>
|
|
388
|
-
|
|
389
|
-
<form onSubmit={handleSubmit} className="p-6">
|
|
390
|
-
{/* Agent Type Selection */}
|
|
391
|
-
<div className="mb-5">
|
|
392
|
-
<label className="block text-sm font-semibold text-text-primary mb-2">Agent Type</label>
|
|
393
|
-
<div className="grid grid-cols-3 gap-2">
|
|
394
|
-
{AGENT_TEMPLATES.map((template) => (
|
|
395
|
-
<button
|
|
396
|
-
key={template.id}
|
|
397
|
-
type="button"
|
|
398
|
-
disabled={template.comingSoon}
|
|
399
|
-
className={`
|
|
400
|
-
flex flex-col items-center gap-1 py-3 px-2 border-2 rounded-lg font-sans transition-all duration-150 relative
|
|
401
|
-
${template.comingSoon
|
|
402
|
-
? 'opacity-50 cursor-not-allowed bg-bg-hover border-transparent'
|
|
403
|
-
: selectedTemplate.id === template.id
|
|
404
|
-
? 'bg-accent/10 border-accent cursor-pointer'
|
|
405
|
-
: 'bg-bg-hover border-transparent hover:bg-bg-active cursor-pointer'
|
|
406
|
-
}
|
|
407
|
-
`}
|
|
408
|
-
onClick={() => !template.comingSoon && setSelectedTemplate(template)}
|
|
409
|
-
>
|
|
410
|
-
{template.comingSoon && (
|
|
411
|
-
<span className="absolute top-1 right-1 px-1.5 py-0.5 bg-amber-400/20 text-amber-400 text-[10px] font-medium rounded">
|
|
412
|
-
Soon
|
|
413
|
-
</span>
|
|
414
|
-
)}
|
|
415
|
-
<span className={`text-2xl ${template.comingSoon ? 'grayscale' : ''}`}>{template.icon}</span>
|
|
416
|
-
<span className="text-sm font-semibold text-text-primary">{template.name}</span>
|
|
417
|
-
<span className="text-xs text-text-muted text-center">{template.description}</span>
|
|
418
|
-
</button>
|
|
419
|
-
))}
|
|
420
|
-
</div>
|
|
421
|
-
</div>
|
|
422
|
-
|
|
423
|
-
{/* Model Selection (Claude only) */}
|
|
424
|
-
{selectedTemplate.id === 'claude' && (
|
|
425
|
-
<div className="mb-5">
|
|
426
|
-
<label className="block text-sm font-semibold text-text-primary mb-2" htmlFor="claude-model">
|
|
427
|
-
Model
|
|
428
|
-
</label>
|
|
429
|
-
<select
|
|
430
|
-
id="claude-model"
|
|
431
|
-
className="w-full py-2.5 px-3.5 border border-border rounded-md text-sm font-sans outline-none bg-bg-primary text-text-primary transition-colors duration-150 focus:border-accent disabled:bg-bg-hover disabled:text-text-muted"
|
|
432
|
-
value={selectedModel}
|
|
433
|
-
onChange={(e) => setSelectedModel(e.target.value as ClaudeModel)}
|
|
434
|
-
disabled={isSpawning}
|
|
435
|
-
>
|
|
436
|
-
{CLAUDE_MODEL_OPTIONS.map((model) => (
|
|
437
|
-
<option key={model.value} value={model.value}>
|
|
438
|
-
{model.label}
|
|
439
|
-
</option>
|
|
440
|
-
))}
|
|
441
|
-
</select>
|
|
442
|
-
</div>
|
|
443
|
-
)}
|
|
444
|
-
|
|
445
|
-
{/* Model Selection (Cursor only) */}
|
|
446
|
-
{selectedTemplate.id === 'cursor' && (
|
|
447
|
-
<div className="mb-5">
|
|
448
|
-
<label className="block text-sm font-semibold text-text-primary mb-2" htmlFor="cursor-model">
|
|
449
|
-
Model
|
|
450
|
-
</label>
|
|
451
|
-
<select
|
|
452
|
-
id="cursor-model"
|
|
453
|
-
className="w-full py-2.5 px-3.5 border border-border rounded-md text-sm font-sans outline-none bg-bg-primary text-text-primary transition-colors duration-150 focus:border-accent disabled:bg-bg-hover disabled:text-text-muted"
|
|
454
|
-
value={selectedCursorModel}
|
|
455
|
-
onChange={(e) => setSelectedCursorModel(e.target.value as CursorModel)}
|
|
456
|
-
disabled={isSpawning}
|
|
457
|
-
>
|
|
458
|
-
{CURSOR_MODEL_OPTIONS.map((model) => (
|
|
459
|
-
<option key={model.value} value={model.value}>
|
|
460
|
-
{model.label}
|
|
461
|
-
</option>
|
|
462
|
-
))}
|
|
463
|
-
</select>
|
|
464
|
-
</div>
|
|
465
|
-
)}
|
|
466
|
-
|
|
467
|
-
{/* Model Selection (Codex only) */}
|
|
468
|
-
{selectedTemplate.id === 'codex' && (
|
|
469
|
-
<div className="mb-5">
|
|
470
|
-
<label className="block text-sm font-semibold text-text-primary mb-2" htmlFor="codex-model">
|
|
471
|
-
Model
|
|
472
|
-
</label>
|
|
473
|
-
<select
|
|
474
|
-
id="codex-model"
|
|
475
|
-
className="w-full py-2.5 px-3.5 border border-border rounded-md text-sm font-sans outline-none bg-bg-primary text-text-primary transition-colors duration-150 focus:border-accent disabled:bg-bg-hover disabled:text-text-muted"
|
|
476
|
-
value={selectedCodexModel}
|
|
477
|
-
onChange={(e) => setSelectedCodexModel(e.target.value as CodexModel)}
|
|
478
|
-
disabled={isSpawning}
|
|
479
|
-
>
|
|
480
|
-
{CODEX_MODEL_OPTIONS.map((model) => (
|
|
481
|
-
<option key={model.value} value={model.value}>
|
|
482
|
-
{model.label}
|
|
483
|
-
</option>
|
|
484
|
-
))}
|
|
485
|
-
</select>
|
|
486
|
-
</div>
|
|
487
|
-
)}
|
|
488
|
-
|
|
489
|
-
{/* Agent Name */}
|
|
490
|
-
<div className="mb-5">
|
|
491
|
-
<label className="block text-sm font-semibold text-text-primary mb-2" htmlFor="agent-name">
|
|
492
|
-
Agent Name
|
|
493
|
-
</label>
|
|
494
|
-
<div className="flex items-center gap-3">
|
|
495
|
-
<div
|
|
496
|
-
className="shrink-0 w-10 h-10 rounded-lg flex items-center justify-center text-sm font-semibold"
|
|
497
|
-
style={{ backgroundColor: colors.primary, color: colors.text }}
|
|
498
|
-
>
|
|
499
|
-
{getAgentInitials(name || suggestedName())}
|
|
500
|
-
</div>
|
|
501
|
-
<input
|
|
502
|
-
ref={nameInputRef}
|
|
503
|
-
id="agent-name"
|
|
504
|
-
type="text"
|
|
505
|
-
className="flex-1 py-2.5 px-3.5 border border-border rounded-md text-sm font-sans outline-none bg-transparent text-text-primary transition-colors duration-150 focus:border-accent disabled:bg-bg-hover disabled:text-text-muted placeholder:text-text-muted"
|
|
506
|
-
placeholder={suggestedName()}
|
|
507
|
-
value={name}
|
|
508
|
-
onChange={(e) => {
|
|
509
|
-
setName(e.target.value);
|
|
510
|
-
setLocalError(null);
|
|
511
|
-
}}
|
|
512
|
-
disabled={isSpawning}
|
|
513
|
-
/>
|
|
514
|
-
</div>
|
|
515
|
-
</div>
|
|
516
|
-
|
|
517
|
-
{/* Team Assignment - moved higher for prominence */}
|
|
518
|
-
<div className="mb-5">
|
|
519
|
-
<label className="block text-sm font-semibold text-text-primary mb-2" htmlFor="agent-team">
|
|
520
|
-
Team <span className="font-normal text-text-muted">(optional)</span>
|
|
521
|
-
</label>
|
|
522
|
-
<input
|
|
523
|
-
id="agent-team"
|
|
524
|
-
type="text"
|
|
525
|
-
className="w-full py-2.5 px-3.5 border border-border rounded-md text-sm font-sans outline-none bg-transparent text-text-primary transition-colors duration-150 focus:border-accent disabled:bg-bg-hover disabled:text-text-muted placeholder:text-text-muted"
|
|
526
|
-
placeholder="e.g., frontend, backend, infra"
|
|
527
|
-
value={team}
|
|
528
|
-
onChange={(e) => setTeam(e.target.value)}
|
|
529
|
-
disabled={isSpawning}
|
|
530
|
-
/>
|
|
531
|
-
</div>
|
|
532
|
-
|
|
533
|
-
{/* Custom Command (if custom template) */}
|
|
534
|
-
{selectedTemplate.id === 'custom' && (
|
|
535
|
-
<div className="mb-5">
|
|
536
|
-
<label className="block text-sm font-semibold text-text-primary mb-2" htmlFor="agent-command">
|
|
537
|
-
Command
|
|
538
|
-
</label>
|
|
539
|
-
<input
|
|
540
|
-
id="agent-command"
|
|
541
|
-
type="text"
|
|
542
|
-
className="w-full py-2.5 px-3.5 border border-border rounded-md text-sm font-sans outline-none bg-transparent text-text-primary transition-colors duration-150 focus:border-accent disabled:bg-bg-hover disabled:text-text-muted placeholder:text-text-muted"
|
|
543
|
-
placeholder="e.g., python agent.py"
|
|
544
|
-
value={customCommand}
|
|
545
|
-
onChange={(e) => setCustomCommand(e.target.value)}
|
|
546
|
-
disabled={isSpawning}
|
|
547
|
-
/>
|
|
548
|
-
</div>
|
|
549
|
-
)}
|
|
550
|
-
|
|
551
|
-
{/* Working Directory (optional) */}
|
|
552
|
-
<div className="mb-5">
|
|
553
|
-
<label className="block text-sm font-semibold text-text-primary mb-2" htmlFor="agent-cwd">
|
|
554
|
-
Working Directory <span className="font-normal text-text-muted">(optional)</span>
|
|
555
|
-
</label>
|
|
556
|
-
<input
|
|
557
|
-
id="agent-cwd"
|
|
558
|
-
type="text"
|
|
559
|
-
className="w-full py-2.5 px-3.5 border border-border rounded-md text-sm font-sans outline-none bg-transparent text-text-primary transition-colors duration-150 focus:border-accent disabled:bg-bg-hover disabled:text-text-muted placeholder:text-text-muted"
|
|
560
|
-
placeholder="Current directory"
|
|
561
|
-
value={cwd}
|
|
562
|
-
onChange={(e) => setCwd(e.target.value)}
|
|
563
|
-
disabled={isSpawning}
|
|
564
|
-
/>
|
|
565
|
-
</div>
|
|
566
|
-
|
|
567
|
-
{/* Shadow Agent Configuration */}
|
|
568
|
-
<div className="mb-5 p-4 border border-border rounded-lg bg-bg-hover/50">
|
|
569
|
-
<div className="flex items-center justify-between mb-3">
|
|
570
|
-
<div>
|
|
571
|
-
<label className="block text-sm font-semibold text-text-primary">
|
|
572
|
-
Shadow Mode
|
|
573
|
-
</label>
|
|
574
|
-
<span className="text-xs text-text-muted">
|
|
575
|
-
Shadow execution: {shadowMode === 'subagent' ? 'Subagent (in-process)' : 'Process (separate)'}
|
|
576
|
-
</span>
|
|
577
|
-
</div>
|
|
578
|
-
<button
|
|
579
|
-
type="button"
|
|
580
|
-
className={`
|
|
581
|
-
relative w-11 h-6 rounded-full transition-colors duration-200
|
|
582
|
-
${isShadow ? 'bg-accent' : 'bg-bg-active'}
|
|
583
|
-
`}
|
|
584
|
-
onClick={() => setIsShadow(!isShadow)}
|
|
585
|
-
disabled={isSpawning}
|
|
586
|
-
aria-pressed={isShadow}
|
|
587
|
-
>
|
|
588
|
-
<span
|
|
589
|
-
className={`
|
|
590
|
-
absolute top-0.5 left-0.5 w-5 h-5 bg-white rounded-full transition-transform duration-200 shadow-sm
|
|
591
|
-
${isShadow ? 'translate-x-5' : 'translate-x-0'}
|
|
592
|
-
`}
|
|
593
|
-
/>
|
|
594
|
-
</button>
|
|
595
|
-
</div>
|
|
596
|
-
|
|
597
|
-
{isShadow && (
|
|
598
|
-
<>
|
|
599
|
-
{/* Primary Agent Selection */}
|
|
600
|
-
<div className="mb-4">
|
|
601
|
-
<label className="block text-sm font-medium text-text-secondary mb-2" htmlFor="shadow-of">
|
|
602
|
-
Shadow Agent
|
|
603
|
-
</label>
|
|
604
|
-
<select
|
|
605
|
-
id="shadow-of"
|
|
606
|
-
className="w-full py-2.5 px-3.5 border border-border rounded-md text-sm font-sans outline-none bg-bg-primary text-text-primary transition-colors duration-150 focus:border-accent disabled:bg-bg-hover disabled:text-text-muted"
|
|
607
|
-
value={shadowOf}
|
|
608
|
-
onChange={(e) => setShadowOf(e.target.value)}
|
|
609
|
-
disabled={isSpawning}
|
|
610
|
-
>
|
|
611
|
-
<option value="">Select an agent to shadow...</option>
|
|
612
|
-
{existingAgents.map((agent) => (
|
|
613
|
-
<option key={agent} value={agent}>
|
|
614
|
-
{agent}
|
|
615
|
-
</option>
|
|
616
|
-
))}
|
|
617
|
-
</select>
|
|
618
|
-
</div>
|
|
619
|
-
|
|
620
|
-
{/* Shadow Agent Profile (optional) */}
|
|
621
|
-
<div className="mb-4">
|
|
622
|
-
<label className="block text-sm font-medium text-text-secondary mb-2" htmlFor="shadow-agent">
|
|
623
|
-
Shadow Agent Profile <span className="font-normal text-text-muted">(optional)</span>
|
|
624
|
-
</label>
|
|
625
|
-
<input
|
|
626
|
-
id="shadow-agent"
|
|
627
|
-
type="text"
|
|
628
|
-
className="w-full py-2.5 px-3.5 border border-border rounded-md text-sm font-sans outline-none bg-bg-primary text-text-primary transition-colors duration-150 focus:border-accent disabled:bg-bg-hover disabled:text-text-muted placeholder:text-text-muted"
|
|
629
|
-
placeholder="e.g., shadow-reviewer"
|
|
630
|
-
value={shadowAgent}
|
|
631
|
-
onChange={(e) => setShadowAgent(e.target.value)}
|
|
632
|
-
disabled={isSpawning}
|
|
633
|
-
/>
|
|
634
|
-
</div>
|
|
635
|
-
|
|
636
|
-
{/* Speak On Triggers */}
|
|
637
|
-
<div>
|
|
638
|
-
<label className="block text-sm font-medium text-text-secondary mb-2">
|
|
639
|
-
Speak When
|
|
640
|
-
</label>
|
|
641
|
-
<div className="flex flex-wrap gap-2">
|
|
642
|
-
{SPEAK_ON_OPTIONS.map((option) => (
|
|
643
|
-
<button
|
|
644
|
-
key={option.value}
|
|
645
|
-
type="button"
|
|
646
|
-
className={`
|
|
647
|
-
py-1.5 px-3 rounded-md text-xs font-medium transition-all duration-150 border
|
|
648
|
-
${shadowSpeakOn.includes(option.value)
|
|
649
|
-
? 'bg-accent/20 border-accent text-accent'
|
|
650
|
-
: 'bg-bg-primary border-border text-text-secondary hover:bg-bg-active hover:text-text-primary'
|
|
651
|
-
}
|
|
652
|
-
`}
|
|
653
|
-
onClick={() => {
|
|
654
|
-
if (shadowSpeakOn.includes(option.value)) {
|
|
655
|
-
setShadowSpeakOn(shadowSpeakOn.filter(t => t !== option.value));
|
|
656
|
-
} else {
|
|
657
|
-
setShadowSpeakOn([...shadowSpeakOn, option.value]);
|
|
658
|
-
}
|
|
659
|
-
}}
|
|
660
|
-
disabled={isSpawning}
|
|
661
|
-
title={option.description}
|
|
662
|
-
>
|
|
663
|
-
{option.label}
|
|
664
|
-
</button>
|
|
665
|
-
))}
|
|
666
|
-
</div>
|
|
667
|
-
</div>
|
|
668
|
-
</>
|
|
669
|
-
)}
|
|
670
|
-
</div>
|
|
671
|
-
|
|
672
|
-
{/* Credentials CTA - shown when provider is not connected */}
|
|
673
|
-
{isCloudMode && !hasActiveCredentials && !isLoadingCredentials && selectedTemplate.providerId && (
|
|
674
|
-
<div className="p-4 bg-amber-400/10 border border-amber-400/30 rounded-lg mb-5">
|
|
675
|
-
<div className="flex items-start gap-3">
|
|
676
|
-
<div className="shrink-0 w-8 h-8 rounded-lg bg-amber-400/20 flex items-center justify-center">
|
|
677
|
-
<LockIcon />
|
|
678
|
-
</div>
|
|
679
|
-
<div className="flex-1">
|
|
680
|
-
<h4 className="text-sm font-semibold text-amber-400 mb-1">
|
|
681
|
-
{selectedTemplate.name} credentials required
|
|
682
|
-
</h4>
|
|
683
|
-
<p className="text-xs text-text-secondary mb-3">
|
|
684
|
-
Connect your {selectedTemplate.name} account to spawn {selectedTemplate.name} agents.
|
|
685
|
-
This enables secure access to the AI provider's API.
|
|
686
|
-
</p>
|
|
687
|
-
<a
|
|
688
|
-
href={providerSetupUrl || '#'}
|
|
689
|
-
className="inline-flex items-center gap-2 py-2 px-4 bg-amber-400 text-bg-deep font-semibold rounded-md text-sm hover:bg-amber-500 transition-colors"
|
|
690
|
-
>
|
|
691
|
-
<LockIcon />
|
|
692
|
-
Connect {selectedTemplate.name}
|
|
693
|
-
</a>
|
|
694
|
-
</div>
|
|
695
|
-
</div>
|
|
696
|
-
</div>
|
|
697
|
-
)}
|
|
698
|
-
|
|
699
|
-
{/* Loading credentials indicator */}
|
|
700
|
-
{isCloudMode && isLoadingCredentials && (
|
|
701
|
-
<div className="flex items-center gap-2 p-3 bg-bg-hover rounded-md text-text-muted text-sm mb-5">
|
|
702
|
-
<Spinner />
|
|
703
|
-
<span>Checking provider credentials...</span>
|
|
704
|
-
</div>
|
|
705
|
-
)}
|
|
706
|
-
|
|
707
|
-
{/* Error Display */}
|
|
708
|
-
{displayError && (
|
|
709
|
-
<div className="flex items-center gap-2 p-3 bg-error/10 border border-error/30 rounded-md text-error text-sm mb-5">
|
|
710
|
-
<ErrorIcon />
|
|
711
|
-
<span>{displayError}</span>
|
|
712
|
-
</div>
|
|
713
|
-
)}
|
|
714
|
-
|
|
715
|
-
{/* Actions */}
|
|
716
|
-
<div className="flex justify-end gap-2 pt-2 border-t border-border">
|
|
717
|
-
<button
|
|
718
|
-
type="button"
|
|
719
|
-
className="flex items-center gap-1.5 py-2.5 px-4 border-none rounded-md text-sm font-medium cursor-pointer font-sans transition-all duration-150 bg-bg-hover text-text-secondary hover:bg-bg-active hover:text-text-primary disabled:opacity-50 disabled:cursor-not-allowed"
|
|
720
|
-
onClick={onClose}
|
|
721
|
-
disabled={isSpawning}
|
|
722
|
-
>
|
|
723
|
-
Cancel
|
|
724
|
-
</button>
|
|
725
|
-
<button
|
|
726
|
-
type="submit"
|
|
727
|
-
className="flex items-center gap-1.5 py-2.5 px-4 border-none rounded-md text-sm font-medium cursor-pointer font-sans transition-all duration-150 bg-accent text-white hover:bg-accent-hover disabled:opacity-50 disabled:cursor-not-allowed"
|
|
728
|
-
disabled={isSpawning || (isCloudMode && !hasActiveCredentials)}
|
|
729
|
-
title={!hasActiveCredentials && isCloudMode ? `Connect ${selectedTemplate.name} credentials first` : undefined}
|
|
730
|
-
>
|
|
731
|
-
{isSpawning ? (
|
|
732
|
-
<>
|
|
733
|
-
<Spinner />
|
|
734
|
-
Spawning...
|
|
735
|
-
</>
|
|
736
|
-
) : (
|
|
737
|
-
<>
|
|
738
|
-
<RocketIcon />
|
|
739
|
-
Spawn Agent
|
|
740
|
-
</>
|
|
741
|
-
)}
|
|
742
|
-
</button>
|
|
743
|
-
</div>
|
|
744
|
-
</form>
|
|
745
|
-
</div>
|
|
746
|
-
</div>
|
|
747
|
-
);
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
function CloseIcon() {
|
|
751
|
-
return (
|
|
752
|
-
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
|
753
|
-
<line x1="18" y1="6" x2="6" y2="18" />
|
|
754
|
-
<line x1="6" y1="6" x2="18" y2="18" />
|
|
755
|
-
</svg>
|
|
756
|
-
);
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
function ErrorIcon() {
|
|
760
|
-
return (
|
|
761
|
-
<svg className="shrink-0" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
|
762
|
-
<circle cx="12" cy="12" r="10" />
|
|
763
|
-
<line x1="12" y1="8" x2="12" y2="12" />
|
|
764
|
-
<line x1="12" y1="16" x2="12.01" y2="16" />
|
|
765
|
-
</svg>
|
|
766
|
-
);
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
function RocketIcon() {
|
|
770
|
-
return (
|
|
771
|
-
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
|
772
|
-
<path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z" />
|
|
773
|
-
<path d="m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z" />
|
|
774
|
-
<path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0" />
|
|
775
|
-
<path d="M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5" />
|
|
776
|
-
</svg>
|
|
777
|
-
);
|
|
778
|
-
}
|
|
779
|
-
|
|
780
|
-
function Spinner() {
|
|
781
|
-
return (
|
|
782
|
-
<svg className="animate-spin" width="16" height="16" viewBox="0 0 24 24">
|
|
783
|
-
<circle
|
|
784
|
-
cx="12"
|
|
785
|
-
cy="12"
|
|
786
|
-
r="10"
|
|
787
|
-
stroke="currentColor"
|
|
788
|
-
strokeWidth="2"
|
|
789
|
-
fill="none"
|
|
790
|
-
strokeDasharray="32"
|
|
791
|
-
strokeLinecap="round"
|
|
792
|
-
/>
|
|
793
|
-
</svg>
|
|
794
|
-
);
|
|
795
|
-
}
|
|
796
|
-
|
|
797
|
-
function LockIcon() {
|
|
798
|
-
return (
|
|
799
|
-
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
800
|
-
<rect x="3" y="11" width="18" height="11" rx="2" ry="2" />
|
|
801
|
-
<path d="M7 11V7a5 5 0 0 1 10 0v4" />
|
|
802
|
-
</svg>
|
|
803
|
-
);
|
|
804
|
-
}
|