@agent-native/core 0.7.2 → 0.7.6
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/README.md +6 -5
- package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
- package/dist/agent/engine/anthropic-engine.js +8 -4
- package/dist/agent/engine/anthropic-engine.js.map +1 -1
- package/dist/agent/engine/types.d.ts +1 -1
- package/dist/agent/engine/types.d.ts.map +1 -1
- package/dist/agent/production-agent.d.ts +7 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +153 -118
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +8 -1
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +8 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/info.d.ts +2 -0
- package/dist/cli/info.d.ts.map +1 -0
- package/dist/cli/info.js +103 -0
- package/dist/cli/info.js.map +1 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +171 -68
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/FeedbackButton.d.ts +3 -1
- package/dist/client/FeedbackButton.d.ts.map +1 -1
- package/dist/client/FeedbackButton.js +115 -40
- package/dist/client/FeedbackButton.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +12 -1
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +3 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +46 -2
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/VoiceButton.d.ts +21 -0
- package/dist/client/composer/VoiceButton.d.ts.map +1 -0
- package/dist/client/composer/VoiceButton.js +51 -0
- package/dist/client/composer/VoiceButton.js.map +1 -0
- package/dist/client/composer/useVoiceDictation.d.ts +38 -0
- package/dist/client/composer/useVoiceDictation.d.ts.map +1 -0
- package/dist/client/composer/useVoiceDictation.js +398 -0
- package/dist/client/composer/useVoiceDictation.js.map +1 -0
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/onboarding/OnboardingPanel.js +2 -2
- package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts +5 -4
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +90 -24
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/resources/McpServerDetail.d.ts +15 -0
- package/dist/client/resources/McpServerDetail.d.ts.map +1 -0
- package/dist/client/resources/McpServerDetail.js +65 -0
- package/dist/client/resources/McpServerDetail.js.map +1 -0
- package/dist/client/resources/ResourceEditor.js +1 -1
- package/dist/client/resources/ResourceEditor.js.map +1 -1
- package/dist/client/resources/ResourceTree.d.ts +6 -1
- package/dist/client/resources/ResourceTree.d.ts.map +1 -1
- package/dist/client/resources/ResourceTree.js +18 -7
- package/dist/client/resources/ResourceTree.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +191 -20
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/resources/use-mcp-servers.d.ts +68 -0
- package/dist/client/resources/use-mcp-servers.d.ts.map +1 -0
- package/dist/client/resources/use-mcp-servers.js +83 -0
- package/dist/client/resources/use-mcp-servers.js.map +1 -0
- package/dist/client/resources/use-resources.d.ts +27 -1
- package/dist/client/resources/use-resources.d.ts.map +1 -1
- package/dist/client/resources/use-resources.js +63 -0
- package/dist/client/resources/use-resources.js.map +1 -1
- package/dist/client/settings/SecretsSection.d.ts +12 -0
- package/dist/client/settings/SecretsSection.d.ts.map +1 -0
- package/dist/client/settings/SecretsSection.js +148 -0
- package/dist/client/settings/SecretsSection.js.map +1 -0
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +101 -2
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/VoiceTranscriptionSection.d.ts +14 -0
- package/dist/client/settings/VoiceTranscriptionSection.d.ts.map +1 -0
- package/dist/client/settings/VoiceTranscriptionSection.js +111 -0
- package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -0
- package/dist/client/settings/index.d.ts +1 -0
- package/dist/client/settings/index.d.ts.map +1 -1
- package/dist/client/settings/index.js +1 -0
- package/dist/client/settings/index.js.map +1 -1
- package/dist/client/sharing/ShareButton.d.ts +16 -0
- package/dist/client/sharing/ShareButton.d.ts.map +1 -0
- package/dist/client/sharing/ShareButton.js +308 -0
- package/dist/client/sharing/ShareButton.js.map +1 -0
- package/dist/client/sharing/ShareDialog.d.ts +33 -0
- package/dist/client/sharing/ShareDialog.d.ts.map +1 -0
- package/dist/client/sharing/ShareDialog.js +231 -0
- package/dist/client/sharing/ShareDialog.js.map +1 -0
- package/dist/client/sharing/VisibilityBadge.d.ts +11 -0
- package/dist/client/sharing/VisibilityBadge.d.ts.map +1 -0
- package/dist/client/sharing/VisibilityBadge.js +19 -0
- package/dist/client/sharing/VisibilityBadge.js.map +1 -0
- package/dist/client/sharing/index.d.ts +4 -0
- package/dist/client/sharing/index.d.ts.map +1 -0
- package/dist/client/sharing/index.js +4 -0
- package/dist/client/sharing/index.js.map +1 -0
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +27 -3
- package/dist/client/use-action.js.map +1 -1
- package/dist/db/migrations.d.ts +18 -3
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +25 -3
- package/dist/db/migrations.js.map +1 -1
- package/dist/db/schema.d.ts +1 -0
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +4 -0
- package/dist/db/schema.js.map +1 -1
- package/dist/deploy/build.js +22 -3
- package/dist/deploy/build.js.map +1 -1
- package/dist/deploy/workspace-core.js +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp-client/config.d.ts +20 -1
- package/dist/mcp-client/config.d.ts.map +1 -1
- package/dist/mcp-client/config.js +28 -11
- package/dist/mcp-client/config.js.map +1 -1
- package/dist/mcp-client/hub-client.d.ts +38 -0
- package/dist/mcp-client/hub-client.d.ts.map +1 -0
- package/dist/mcp-client/hub-client.js +147 -0
- package/dist/mcp-client/hub-client.js.map +1 -0
- package/dist/mcp-client/hub-routes.d.ts +42 -0
- package/dist/mcp-client/hub-routes.d.ts.map +1 -0
- package/dist/mcp-client/hub-routes.js +114 -0
- package/dist/mcp-client/hub-routes.js.map +1 -0
- package/dist/mcp-client/index.d.ts +15 -0
- package/dist/mcp-client/index.d.ts.map +1 -1
- package/dist/mcp-client/index.js +35 -0
- package/dist/mcp-client/index.js.map +1 -1
- package/dist/mcp-client/manager.d.ts +54 -8
- package/dist/mcp-client/manager.d.ts.map +1 -1
- package/dist/mcp-client/manager.js +276 -59
- package/dist/mcp-client/manager.js.map +1 -1
- package/dist/mcp-client/remote-store.d.ts +102 -0
- package/dist/mcp-client/remote-store.d.ts.map +1 -0
- package/dist/mcp-client/remote-store.js +200 -0
- package/dist/mcp-client/remote-store.js.map +1 -0
- package/dist/mcp-client/routes.d.ts +55 -0
- package/dist/mcp-client/routes.d.ts.map +1 -0
- package/dist/mcp-client/routes.js +384 -0
- package/dist/mcp-client/routes.js.map +1 -0
- package/dist/mcp-client/visibility.d.ts +16 -0
- package/dist/mcp-client/visibility.d.ts.map +1 -0
- package/dist/mcp-client/visibility.js +45 -0
- package/dist/mcp-client/visibility.js.map +1 -0
- package/dist/onboarding/default-steps.d.ts.map +1 -1
- package/dist/onboarding/default-steps.js +5 -0
- package/dist/onboarding/default-steps.js.map +1 -1
- package/dist/org/accept-pending.d.ts +22 -0
- package/dist/org/accept-pending.d.ts.map +1 -0
- package/dist/org/accept-pending.js +75 -0
- package/dist/org/accept-pending.js.map +1 -0
- package/dist/org/context.js +2 -2
- package/dist/org/context.js.map +1 -1
- package/dist/org/handlers.d.ts +2 -0
- package/dist/org/handlers.d.ts.map +1 -1
- package/dist/org/handlers.js +54 -3
- package/dist/org/handlers.js.map +1 -1
- package/dist/org/index.d.ts +2 -0
- package/dist/org/index.d.ts.map +1 -1
- package/dist/org/index.js +1 -0
- package/dist/org/index.js.map +1 -1
- package/dist/resources/handlers.d.ts.map +1 -1
- package/dist/resources/handlers.js +30 -0
- package/dist/resources/handlers.js.map +1 -1
- package/dist/secrets/index.d.ts +15 -0
- package/dist/secrets/index.d.ts.map +1 -0
- package/dist/secrets/index.js +15 -0
- package/dist/secrets/index.js.map +1 -0
- package/dist/secrets/onboarding.d.ts +18 -0
- package/dist/secrets/onboarding.d.ts.map +1 -0
- package/dist/secrets/onboarding.js +87 -0
- package/dist/secrets/onboarding.js.map +1 -0
- package/dist/secrets/register-framework-secrets.d.ts +13 -0
- package/dist/secrets/register-framework-secrets.d.ts.map +1 -0
- package/dist/secrets/register-framework-secrets.js +59 -0
- package/dist/secrets/register-framework-secrets.js.map +1 -0
- package/dist/secrets/register.d.ts +63 -0
- package/dist/secrets/register.d.ts.map +1 -0
- package/dist/secrets/register.js +62 -0
- package/dist/secrets/register.js.map +1 -0
- package/dist/secrets/routes.d.ts +67 -0
- package/dist/secrets/routes.d.ts.map +1 -0
- package/dist/secrets/routes.js +275 -0
- package/dist/secrets/routes.js.map +1 -0
- package/dist/secrets/schema.d.ts +154 -0
- package/dist/secrets/schema.d.ts.map +1 -0
- package/dist/secrets/schema.js +41 -0
- package/dist/secrets/schema.js.map +1 -0
- package/dist/secrets/storage.d.ts +54 -0
- package/dist/secrets/storage.d.ts.map +1 -0
- package/dist/secrets/storage.js +181 -0
- package/dist/secrets/storage.js.map +1 -0
- package/dist/server/action-discovery.d.ts +18 -0
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +95 -0
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +22 -2
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +16 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +120 -25
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/app-name.d.ts +13 -0
- package/dist/server/app-name.d.ts.map +1 -0
- package/dist/server/app-name.js +41 -0
- package/dist/server/app-name.js.map +1 -0
- package/dist/server/app-url.d.ts +24 -0
- package/dist/server/app-url.d.ts.map +1 -0
- package/dist/server/app-url.js +76 -0
- package/dist/server/app-url.js.map +1 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +50 -0
- package/dist/server/auth.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +137 -13
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +73 -0
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/create-server.d.ts.map +1 -1
- package/dist/server/create-server.js +6 -0
- package/dist/server/create-server.js.map +1 -1
- package/dist/server/date-utils.d.ts +15 -0
- package/dist/server/date-utils.d.ts.map +1 -0
- package/dist/server/date-utils.js +41 -0
- package/dist/server/date-utils.js.map +1 -0
- package/dist/server/email-template.d.ts +51 -0
- package/dist/server/email-template.d.ts.map +1 -0
- package/dist/server/email-template.js +146 -0
- package/dist/server/email-template.js.map +1 -0
- package/dist/server/index.d.ts +6 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +6 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/onboarding-html.d.ts +3 -0
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +13 -3
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/server/request-context.d.ts +9 -0
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js +10 -0
- package/dist/server/request-context.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +26 -0
- package/dist/server/transcribe-voice.d.ts.map +1 -0
- package/dist/server/transcribe-voice.js +143 -0
- package/dist/server/transcribe-voice.js.map +1 -0
- package/dist/sharing/access.d.ts +56 -0
- package/dist/sharing/access.d.ts.map +1 -0
- package/dist/sharing/access.js +149 -0
- package/dist/sharing/access.js.map +1 -0
- package/dist/sharing/actions/list-resource-shares.d.ts +3 -0
- package/dist/sharing/actions/list-resource-shares.d.ts.map +1 -0
- package/dist/sharing/actions/list-resource-shares.js +38 -0
- package/dist/sharing/actions/list-resource-shares.js.map +1 -0
- package/dist/sharing/actions/set-resource-visibility.d.ts +3 -0
- package/dist/sharing/actions/set-resource-visibility.d.ts.map +1 -0
- package/dist/sharing/actions/set-resource-visibility.js +24 -0
- package/dist/sharing/actions/set-resource-visibility.js.map +1 -0
- package/dist/sharing/actions/share-resource.d.ts +3 -0
- package/dist/sharing/actions/share-resource.d.ts.map +1 -0
- package/dist/sharing/actions/share-resource.js +64 -0
- package/dist/sharing/actions/share-resource.js.map +1 -0
- package/dist/sharing/actions/unshare-resource.d.ts +3 -0
- package/dist/sharing/actions/unshare-resource.d.ts.map +1 -0
- package/dist/sharing/actions/unshare-resource.js +24 -0
- package/dist/sharing/actions/unshare-resource.js.map +1 -0
- package/dist/sharing/index.d.ts +11 -0
- package/dist/sharing/index.d.ts.map +1 -0
- package/dist/sharing/index.js +11 -0
- package/dist/sharing/index.js.map +1 -0
- package/dist/sharing/registry.d.ts +44 -0
- package/dist/sharing/registry.d.ts.map +1 -0
- package/dist/sharing/registry.js +54 -0
- package/dist/sharing/registry.js.map +1 -0
- package/dist/sharing/schema.d.ts +202 -0
- package/dist/sharing/schema.d.ts.map +1 -0
- package/dist/sharing/schema.js +88 -0
- package/dist/sharing/schema.js.map +1 -0
- package/dist/styles/agent-native.css +111 -0
- package/dist/tailwind.preset.d.ts +2 -2
- package/dist/tailwind.preset.d.ts.map +1 -1
- package/dist/tailwind.preset.js +27 -7
- package/dist/tailwind.preset.js.map +1 -1
- package/dist/templates/default/app/global.css +65 -68
- package/dist/templates/default/components.json +1 -1
- package/dist/templates/default/package.json +2 -4
- package/dist/templates/default/vite.config.ts +3 -0
- package/dist/templates/workspace-core/package.json +1 -4
- package/dist/templates/workspace-core/src/index.ts +1 -1
- package/dist/templates/workspace-core/styles/tokens.css +22 -0
- package/dist/templates/workspace-core/tsconfig.json +1 -1
- package/dist/vite/action-types-plugin.d.ts +5 -0
- package/dist/vite/action-types-plugin.d.ts.map +1 -1
- package/dist/vite/action-types-plugin.js +129 -28
- package/dist/vite/action-types-plugin.js.map +1 -1
- package/dist/vite/client.d.ts +6 -0
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +18 -1
- package/dist/vite/client.js.map +1 -1
- package/docs/content/actions.md +169 -74
- package/docs/content/agent-teams.md +139 -0
- package/docs/content/cloneable-saas.md +98 -0
- package/docs/content/creating-templates.md +9 -11
- package/docs/content/deployment.md +2 -9
- package/docs/content/drop-in-agent.md +200 -0
- package/docs/content/enterprise-workspace.md +22 -10
- package/docs/content/getting-started.md +34 -19
- package/docs/content/integrations.md +3 -3
- package/docs/content/key-concepts.md +50 -23
- package/docs/content/mcp-clients.md +71 -0
- package/docs/content/pure-agent-apps.md +69 -0
- package/docs/content/recurring-jobs.md +123 -0
- package/docs/content/skills-guide.md +8 -0
- package/docs/content/template-analytics.md +190 -0
- package/docs/content/template-calendar.md +151 -0
- package/docs/content/template-clips.md +55 -0
- package/docs/content/template-content.md +141 -0
- package/docs/content/template-dispatch.md +58 -0
- package/docs/content/template-forms.md +51 -0
- package/docs/content/template-mail.md +169 -0
- package/docs/content/template-slides.md +218 -0
- package/docs/content/template-starter.md +68 -0
- package/docs/content/template-video.md +162 -0
- package/docs/content/voice-input.md +59 -0
- package/docs/content/what-is-agent-native.md +142 -45
- package/docs/content/workspace-management.md +1 -0
- package/docs/content/{resources.md → workspace.md} +94 -42
- package/package.json +20 -19
- package/src/templates/default/app/global.css +65 -68
- package/src/templates/default/components.json +1 -1
- package/src/templates/default/package.json +2 -4
- package/src/templates/default/vite.config.ts +3 -0
- package/src/templates/workspace-core/package.json +1 -4
- package/src/templates/workspace-core/src/index.ts +1 -1
- package/src/templates/workspace-core/styles/tokens.css +22 -0
- package/src/templates/workspace-core/tsconfig.json +1 -1
- package/dist/templates/default/postcss.config.js +0 -6
- package/dist/templates/default/tailwind.config.ts +0 -7
- package/dist/templates/workspace-core/tailwind.preset.ts +0 -34
- package/src/templates/default/postcss.config.js +0 -6
- package/src/templates/default/tailwind.config.ts +0 -7
- package/src/templates/workspace-core/tailwind.preset.ts +0 -34
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React-query hooks for remote MCP servers surfaced inside the Workspace
|
|
3
|
+
* tab as a virtual `mcp-servers/` folder.
|
|
4
|
+
*
|
|
5
|
+
* MCP servers live in the settings store (user- and org-scope), not the
|
|
6
|
+
* resources table. These hooks wrap the existing `/_agent-native/mcp/servers`
|
|
7
|
+
* endpoints so the Workspace UI can list, create, and delete them with the
|
|
8
|
+
* same keys/invalidations the old Settings panel used.
|
|
9
|
+
*/
|
|
10
|
+
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
11
|
+
const ENDPOINT = "/_agent-native/mcp/servers";
|
|
12
|
+
const LIST_KEY = ["mcp-servers"];
|
|
13
|
+
export function useMcpServers() {
|
|
14
|
+
return useQuery({
|
|
15
|
+
queryKey: LIST_KEY,
|
|
16
|
+
queryFn: async () => {
|
|
17
|
+
const res = await fetch(ENDPOINT, { credentials: "include" });
|
|
18
|
+
if (!res.ok)
|
|
19
|
+
throw new Error(`Failed to load (${res.status})`);
|
|
20
|
+
return (await res.json());
|
|
21
|
+
},
|
|
22
|
+
staleTime: 10_000,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
export function useCreateMcpServer() {
|
|
26
|
+
const qc = useQueryClient();
|
|
27
|
+
return useMutation({
|
|
28
|
+
mutationFn: async (args) => {
|
|
29
|
+
const res = await fetch(ENDPOINT, {
|
|
30
|
+
method: "POST",
|
|
31
|
+
credentials: "include",
|
|
32
|
+
headers: { "Content-Type": "application/json" },
|
|
33
|
+
body: JSON.stringify(args),
|
|
34
|
+
});
|
|
35
|
+
const body = (await res.json().catch(() => ({})));
|
|
36
|
+
if (!res.ok || !body.ok) {
|
|
37
|
+
throw new Error(body.error || `Create failed (${res.status})`);
|
|
38
|
+
}
|
|
39
|
+
return body.server;
|
|
40
|
+
},
|
|
41
|
+
onSuccess: () => qc.invalidateQueries({ queryKey: LIST_KEY }),
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
export function useDeleteMcpServer() {
|
|
45
|
+
const qc = useQueryClient();
|
|
46
|
+
return useMutation({
|
|
47
|
+
mutationFn: async (args) => {
|
|
48
|
+
const res = await fetch(`${ENDPOINT}/${encodeURIComponent(args.id)}?scope=${args.scope}`, { method: "DELETE", credentials: "include" });
|
|
49
|
+
const body = (await res.json().catch(() => ({})));
|
|
50
|
+
if (!res.ok || !body.ok) {
|
|
51
|
+
throw new Error(body.error || `Delete failed (${res.status})`);
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
onSuccess: () => qc.invalidateQueries({ queryKey: LIST_KEY }),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
export async function testMcpServerUrl(url, headers) {
|
|
58
|
+
const res = await fetch(`${ENDPOINT}/test`, {
|
|
59
|
+
method: "POST",
|
|
60
|
+
credentials: "include",
|
|
61
|
+
headers: { "Content-Type": "application/json" },
|
|
62
|
+
body: JSON.stringify({ url, headers }),
|
|
63
|
+
});
|
|
64
|
+
const body = (await res.json().catch(() => ({})));
|
|
65
|
+
if (!res.ok)
|
|
66
|
+
return { ok: false, error: body.error || "Test failed" };
|
|
67
|
+
return body;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Virtual tree-node id used when a server is surfaced in the Workspace tree.
|
|
71
|
+
* Shape: `mcp:<scope>:<serverId>`. Not a real resource row; purely a handle
|
|
72
|
+
* the panel uses to route clicks/delete back to the MCP endpoints.
|
|
73
|
+
*/
|
|
74
|
+
export function mcpVirtualId(scope, serverId) {
|
|
75
|
+
return `mcp:${scope}:${serverId}`;
|
|
76
|
+
}
|
|
77
|
+
export function parseMcpVirtualId(id) {
|
|
78
|
+
const m = /^mcp:(user|org):(.+)$/.exec(id);
|
|
79
|
+
if (!m)
|
|
80
|
+
return null;
|
|
81
|
+
return { scope: m[1], serverId: m[2] };
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=use-mcp-servers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-mcp-servers.js","sourceRoot":"","sources":["../../../src/client/resources/use-mcp-servers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AA0B9E,MAAM,QAAQ,GAAG,4BAA4B,CAAC;AAC9C,MAAM,QAAQ,GAAG,CAAC,aAAa,CAAU,CAAC;AAE1C,MAAM,UAAU,aAAa;IAC3B,OAAO,QAAQ,CAAiB;QAC9B,QAAQ,EAAE,QAAQ;QAClB,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC;YAC9D,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;YAC/D,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAmB,CAAC;QAC9C,CAAC;QACD,SAAS,EAAE,MAAM;KAClB,CAAC,CAAC;AACL,CAAC;AAUD,MAAM,UAAU,kBAAkB;IAChC,MAAM,EAAE,GAAG,cAAc,EAAE,CAAC;IAC5B,OAAO,WAAW,CAAC;QACjB,UAAU,EAAE,KAAK,EAAE,IAAyB,EAAE,EAAE;YAC9C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;gBAChC,MAAM,EAAE,MAAM;gBACd,WAAW,EAAE,SAAS;gBACtB,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;aAC3B,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAI/C,CAAC;YACF,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,kBAAkB,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;YACjE,CAAC;YACD,OAAO,IAAI,CAAC,MAAO,CAAC;QACtB,CAAC;QACD,SAAS,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;KAC9D,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,MAAM,EAAE,GAAG,cAAc,EAAE,CAAC;IAC5B,OAAO,WAAW,CAAC;QACjB,UAAU,EAAE,KAAK,EAAE,IAA2C,EAAE,EAAE;YAChE,MAAM,GAAG,GAAG,MAAM,KAAK,CACrB,GAAG,QAAQ,IAAI,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,IAAI,CAAC,KAAK,EAAE,EAChE,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,CAC7C,CAAC;YACF,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAG/C,CAAC;YACF,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,kBAAkB,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;YACjE,CAAC;QACH,CAAC;QACD,SAAS,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;KAC9D,CAAC,CAAC;AACL,CAAC;AASD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAW,EACX,OAAgC;IAEhC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,OAAO,EAAE;QAC1C,MAAM,EAAE,MAAM;QACd,WAAW,EAAE,SAAS;QACtB,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;KACvC,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAqB,CAAC;IACtE,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,aAAa,EAAE,CAAC;IACtE,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAqB,EAAE,QAAgB;IAClE,OAAO,OAAO,KAAK,IAAI,QAAQ,EAAE,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,EAAU;IAEV,MAAM,CAAC,GAAG,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3C,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAmB,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC3D,CAAC"}
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import type { CustomAgentProfile, RemoteAgentManifest, ResourceKind, SkillMetadata } from "../../resources/metadata.js";
|
|
1
|
+
import type { CustomAgentProfile, RemoteAgentManifest, ResourceKind as StoredResourceKind, SkillMetadata } from "../../resources/metadata.js";
|
|
2
|
+
import type { McpServer } from "./use-mcp-servers.js";
|
|
3
|
+
/**
|
|
4
|
+
* Extended resource kind that includes virtual entries injected into the
|
|
5
|
+
* Workspace tree — MCP servers live in the settings store, not the
|
|
6
|
+
* resources table, but they render as a folder inside each scope.
|
|
7
|
+
*/
|
|
8
|
+
export type ResourceKind = StoredResourceKind | "mcp-server";
|
|
2
9
|
export interface Resource {
|
|
3
10
|
id: string;
|
|
4
11
|
path: string;
|
|
@@ -38,8 +45,27 @@ export interface TreeNode {
|
|
|
38
45
|
skillMeta?: SkillMetadata;
|
|
39
46
|
agentMeta?: CustomAgentProfile;
|
|
40
47
|
remoteAgentMeta?: RemoteAgentManifest;
|
|
48
|
+
/** Attached when `kind === "mcp-server"` — virtual tree entry. */
|
|
49
|
+
mcpServerMeta?: McpServer;
|
|
41
50
|
}
|
|
42
51
|
export type ResourceScope = "personal" | "shared" | "all";
|
|
52
|
+
/**
|
|
53
|
+
* Inject a virtual `mcp-servers/` folder into a scope's resource tree.
|
|
54
|
+
*
|
|
55
|
+
* MCP servers aren't stored as resource rows — they live in the settings
|
|
56
|
+
* store — but we surface them in the Workspace tree alongside `memory/`,
|
|
57
|
+
* `skills/`, etc. Each server becomes a synthetic `TreeNode` whose
|
|
58
|
+
* `resource.id` is an `mcp:<scope>:<id>` virtual id the panel recognizes
|
|
59
|
+
* on click/delete and routes to the MCP endpoints instead of the
|
|
60
|
+
* resource endpoints.
|
|
61
|
+
*
|
|
62
|
+
* Returns a new tree; the input is not mutated. If `servers` is empty
|
|
63
|
+
* and `alwaysShow` is false, the folder is not added — same behavior as
|
|
64
|
+
* any other optional folder.
|
|
65
|
+
*/
|
|
66
|
+
export declare function withMcpServersFolder(tree: TreeNode[], servers: McpServer[], opts?: {
|
|
67
|
+
alwaysShow?: boolean;
|
|
68
|
+
}): TreeNode[];
|
|
43
69
|
export declare function useResources(scope?: ResourceScope): import("@tanstack/react-query").UseQueryResult<ResourceMeta[], Error>;
|
|
44
70
|
export declare function useResourceTree(scope?: ResourceScope): import("@tanstack/react-query").UseQueryResult<TreeNode[], Error>;
|
|
45
71
|
export declare function useResource(id: string | null): import("@tanstack/react-query").UseQueryResult<Resource, Error>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-resources.d.ts","sourceRoot":"","sources":["../../../src/client/resources/use-resources.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,
|
|
1
|
+
{"version":3,"file":"use-resources.d.ts","sourceRoot":"","sources":["../../../src/client/resources/use-resources.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,IAAI,kBAAkB,EAClC,aAAa,EACd,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,kBAAkB,GAAG,YAAY,CAAC;AAE7D,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC;IACxB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,kDAAkD;IAClD,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC,kEAAkE;IAClE,aAAa,CAAC,EAAE,SAAS,CAAC;CAC3B;AAED,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE1D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,QAAQ,EAAE,EAChB,OAAO,EAAE,SAAS,EAAE,EACpB,IAAI,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9B,QAAQ,EAAE,CAqDZ;AAQD,wBAAgB,YAAY,CAAC,KAAK,GAAE,aAA0B,yEAU7D;AAED,wBAAgB,eAAe,CAAC,KAAK,GAAE,aAA0B,qEAUhE;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,mEAM5C;AAED,wBAAgB,iBAAiB;UAIrB,MAAM;cACF,MAAM;eACL,MAAM;aACR,OAAO;YAcrB;AAED,wBAAgB,iBAAiB;QAOvB,MAAM;cACA,MAAM;WACT,MAAM;eACF,MAAM;YAetB;AAED,wBAAgB,iBAAiB,oFAahC;AAED,wBAAgB,iBAAiB,0FAehC"}
|
|
@@ -1,4 +1,67 @@
|
|
|
1
1
|
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
|
2
|
+
/**
|
|
3
|
+
* Inject a virtual `mcp-servers/` folder into a scope's resource tree.
|
|
4
|
+
*
|
|
5
|
+
* MCP servers aren't stored as resource rows — they live in the settings
|
|
6
|
+
* store — but we surface them in the Workspace tree alongside `memory/`,
|
|
7
|
+
* `skills/`, etc. Each server becomes a synthetic `TreeNode` whose
|
|
8
|
+
* `resource.id` is an `mcp:<scope>:<id>` virtual id the panel recognizes
|
|
9
|
+
* on click/delete and routes to the MCP endpoints instead of the
|
|
10
|
+
* resource endpoints.
|
|
11
|
+
*
|
|
12
|
+
* Returns a new tree; the input is not mutated. If `servers` is empty
|
|
13
|
+
* and `alwaysShow` is false, the folder is not added — same behavior as
|
|
14
|
+
* any other optional folder.
|
|
15
|
+
*/
|
|
16
|
+
export function withMcpServersFolder(tree, servers, opts) {
|
|
17
|
+
const alwaysShow = opts?.alwaysShow ?? false;
|
|
18
|
+
if (servers.length === 0 && !alwaysShow)
|
|
19
|
+
return tree;
|
|
20
|
+
// Filter out any real `mcp-servers/` entries so the virtual folder is
|
|
21
|
+
// authoritative. (Shouldn't happen today, but guards against collisions
|
|
22
|
+
// if a user pastes a file there.)
|
|
23
|
+
const filtered = tree.filter((n) => !(n.type === "folder" && n.name === "mcp-servers"));
|
|
24
|
+
const now = Date.now();
|
|
25
|
+
const children = servers.map((s) => {
|
|
26
|
+
const virtualId = `mcp:${s.scope}:${s.id}`;
|
|
27
|
+
const path = `mcp-servers/${s.name}.json`;
|
|
28
|
+
return {
|
|
29
|
+
name: `${s.name}.json`,
|
|
30
|
+
path,
|
|
31
|
+
type: "file",
|
|
32
|
+
kind: "mcp-server",
|
|
33
|
+
mcpServerMeta: s,
|
|
34
|
+
resource: {
|
|
35
|
+
id: virtualId,
|
|
36
|
+
path,
|
|
37
|
+
owner: s.scope,
|
|
38
|
+
mimeType: "application/json",
|
|
39
|
+
size: 0,
|
|
40
|
+
createdAt: s.createdAt,
|
|
41
|
+
updatedAt: s.createdAt,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
const folder = {
|
|
46
|
+
name: "mcp-servers",
|
|
47
|
+
path: "mcp-servers",
|
|
48
|
+
type: "folder",
|
|
49
|
+
children,
|
|
50
|
+
};
|
|
51
|
+
// Insert the folder so it sorts naturally with other folders (alphabetical).
|
|
52
|
+
// The backend already sorts folders-first, alpha — match that.
|
|
53
|
+
const foldersFirst = [];
|
|
54
|
+
const files = [];
|
|
55
|
+
for (const n of filtered) {
|
|
56
|
+
(n.type === "folder" ? foldersFirst : files).push(n);
|
|
57
|
+
}
|
|
58
|
+
foldersFirst.push(folder);
|
|
59
|
+
foldersFirst.sort((a, b) => a.name.localeCompare(b.name));
|
|
60
|
+
// Assign a synthetic `updatedAt`-less ordering — use current time so the
|
|
61
|
+
// folder appears stable across renders; we rely on alpha sort.
|
|
62
|
+
void now;
|
|
63
|
+
return [...foldersFirst, ...files];
|
|
64
|
+
}
|
|
2
65
|
async function fetchJson(url) {
|
|
3
66
|
const res = await fetch(url);
|
|
4
67
|
if (!res.ok)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-resources.js","sourceRoot":"","sources":["../../../src/client/resources/use-resources.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"use-resources.js","sourceRoot":"","sources":["../../../src/client/resources/use-resources.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* <SecretsSection /> — renders the registered secrets from the framework
|
|
3
|
+
* secrets registry. Fetches `/_agent-native/secrets` on mount and shows a
|
|
4
|
+
* card per secret with a masked input + Save / Rotate / Delete / Test
|
|
5
|
+
* buttons (api-key kind) or a Connect / Disconnect button (oauth kind).
|
|
6
|
+
*/
|
|
7
|
+
export interface SecretsSectionProps {
|
|
8
|
+
/** Optional hash fragment to focus a specific secret (e.g. "secrets:OPENAI_API_KEY"). */
|
|
9
|
+
focusKey?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function SecretsSection({ focusKey }: SecretsSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=SecretsSection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SecretsSection.d.ts","sourceRoot":"","sources":["../../../src/client/settings/SecretsSection.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AA8BH,MAAM,WAAW,mBAAmB;IAClC,yFAAyF;IACzF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,cAAc,CAAC,EAAE,QAAQ,EAAE,EAAE,mBAAmB,2CA+D/D"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* <SecretsSection /> — renders the registered secrets from the framework
|
|
4
|
+
* secrets registry. Fetches `/_agent-native/secrets` on mount and shows a
|
|
5
|
+
* card per secret with a masked input + Save / Rotate / Delete / Test
|
|
6
|
+
* buttons (api-key kind) or a Connect / Disconnect button (oauth kind).
|
|
7
|
+
*/
|
|
8
|
+
import React, { useEffect, useMemo, useState, useCallback } from "react";
|
|
9
|
+
import { IconCheck, IconExternalLink, IconLoader2, IconPlugConnected, IconTrash, IconRefresh, } from "@tabler/icons-react";
|
|
10
|
+
const ENDPOINT = "/_agent-native/secrets";
|
|
11
|
+
export function SecretsSection({ focusKey }) {
|
|
12
|
+
const [secrets, setSecrets] = useState(null);
|
|
13
|
+
const [error, setError] = useState(null);
|
|
14
|
+
const [reloadToken, setReloadToken] = useState(0);
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
let cancelled = false;
|
|
17
|
+
fetch(ENDPOINT)
|
|
18
|
+
.then(async (r) => {
|
|
19
|
+
if (!r.ok) {
|
|
20
|
+
throw new Error(`Failed to load secrets (${r.status})`);
|
|
21
|
+
}
|
|
22
|
+
return (await r.json());
|
|
23
|
+
})
|
|
24
|
+
.then((data) => {
|
|
25
|
+
if (!cancelled)
|
|
26
|
+
setSecrets(data);
|
|
27
|
+
})
|
|
28
|
+
.catch((err) => {
|
|
29
|
+
if (!cancelled)
|
|
30
|
+
setError(err?.message ?? "Failed to load");
|
|
31
|
+
});
|
|
32
|
+
return () => {
|
|
33
|
+
cancelled = true;
|
|
34
|
+
};
|
|
35
|
+
}, [reloadToken]);
|
|
36
|
+
const reload = useCallback(() => setReloadToken((t) => t + 1), []);
|
|
37
|
+
if (error) {
|
|
38
|
+
return (_jsxs("p", { className: "text-[10px] text-red-500", children: ["Failed to load secrets: ", error] }));
|
|
39
|
+
}
|
|
40
|
+
if (secrets === null) {
|
|
41
|
+
return (_jsxs("div", { className: "flex items-center gap-1.5 text-[10px] text-muted-foreground", children: [_jsx(IconLoader2, { size: 10, className: "animate-spin" }), "Loading\u2026"] }));
|
|
42
|
+
}
|
|
43
|
+
if (secrets.length === 0) {
|
|
44
|
+
return (_jsxs("p", { className: "text-[10px] text-muted-foreground", children: ["No secrets registered yet. Templates register API keys and connections via ", _jsx("code", { children: "registerRequiredSecret()" }), "."] }));
|
|
45
|
+
}
|
|
46
|
+
return (_jsx("div", { className: "space-y-2", children: secrets.map((secret) => (_jsx(SecretCard, { secret: secret, onChanged: reload, focusInput: focusKey === secret.key }, secret.key))) }));
|
|
47
|
+
}
|
|
48
|
+
function SecretCard({ secret, onChanged, focusInput }) {
|
|
49
|
+
const [value, setValue] = useState("");
|
|
50
|
+
const [busy, setBusy] = useState(null);
|
|
51
|
+
const [toast, setToast] = useState(null);
|
|
52
|
+
const inputRef = React.useRef(null);
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
if (focusInput && inputRef.current) {
|
|
55
|
+
inputRef.current.focus();
|
|
56
|
+
}
|
|
57
|
+
}, [focusInput]);
|
|
58
|
+
const setToastAndClear = (kind, text, ms = 2500) => {
|
|
59
|
+
setToast({ kind, text });
|
|
60
|
+
setTimeout(() => setToast(null), ms);
|
|
61
|
+
};
|
|
62
|
+
const handleSave = async () => {
|
|
63
|
+
if (!value.trim() || busy)
|
|
64
|
+
return;
|
|
65
|
+
setBusy("save");
|
|
66
|
+
try {
|
|
67
|
+
const res = await fetch(`${ENDPOINT}/${encodeURIComponent(secret.key)}`, {
|
|
68
|
+
method: "POST",
|
|
69
|
+
headers: { "Content-Type": "application/json" },
|
|
70
|
+
body: JSON.stringify({ value: value.trim() }),
|
|
71
|
+
});
|
|
72
|
+
if (!res.ok) {
|
|
73
|
+
const err = await res
|
|
74
|
+
.json()
|
|
75
|
+
.then((j) => j.error)
|
|
76
|
+
.catch(() => null);
|
|
77
|
+
setToastAndClear("err", err ?? `Save failed (${res.status})`);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
setValue("");
|
|
81
|
+
setToastAndClear("ok", "Saved");
|
|
82
|
+
onChanged();
|
|
83
|
+
}
|
|
84
|
+
finally {
|
|
85
|
+
setBusy(null);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
const handleDelete = async () => {
|
|
89
|
+
if (busy)
|
|
90
|
+
return;
|
|
91
|
+
setBusy("delete");
|
|
92
|
+
try {
|
|
93
|
+
const res = await fetch(`${ENDPOINT}/${encodeURIComponent(secret.key)}`, {
|
|
94
|
+
method: "DELETE",
|
|
95
|
+
});
|
|
96
|
+
if (!res.ok) {
|
|
97
|
+
const err = await res
|
|
98
|
+
.json()
|
|
99
|
+
.then((j) => j.error)
|
|
100
|
+
.catch(() => null);
|
|
101
|
+
setToastAndClear("err", err ?? `Delete failed (${res.status})`);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
setToastAndClear("ok", "Removed");
|
|
105
|
+
onChanged();
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
setBusy(null);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
const handleTest = async () => {
|
|
112
|
+
if (busy)
|
|
113
|
+
return;
|
|
114
|
+
setBusy("test");
|
|
115
|
+
try {
|
|
116
|
+
const res = await fetch(`${ENDPOINT}/${encodeURIComponent(secret.key)}/test`, {
|
|
117
|
+
method: "POST",
|
|
118
|
+
});
|
|
119
|
+
const body = (await res.json().catch(() => ({})));
|
|
120
|
+
if (res.ok && body.ok) {
|
|
121
|
+
setToastAndClear("ok", "Working");
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
setToastAndClear("err", body.error ?? (body.ok === false ? "Invalid" : `Test failed`));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
setBusy(null);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
const pill = useMemo(() => {
|
|
132
|
+
if (secret.status === "set") {
|
|
133
|
+
return (_jsxs("span", { className: "flex items-center gap-1 text-[10px] text-green-500", children: [_jsx(IconCheck, { size: 10 }), "Set"] }));
|
|
134
|
+
}
|
|
135
|
+
if (secret.required) {
|
|
136
|
+
return (_jsx("span", { className: "rounded-full bg-red-500/15 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide text-red-500", children: "Required" }));
|
|
137
|
+
}
|
|
138
|
+
return (_jsx("span", { className: "rounded-full bg-accent/60 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Optional" }));
|
|
139
|
+
}, [secret.status, secret.required]);
|
|
140
|
+
const isOAuth = secret.kind === "oauth";
|
|
141
|
+
return (_jsxs("div", { className: "rounded-md border border-border px-2.5 py-2 bg-accent/30", children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "text-[11px] font-medium text-foreground truncate", children: secret.label }), secret.description && (_jsx("p", { className: "text-[10px] text-muted-foreground mt-0.5", children: secret.description }))] }), _jsx("div", { className: "shrink-0", children: pill })] }), isOAuth ? (_jsxs("div", { className: "mt-2 flex items-center gap-1.5", children: [secret.oauthConnectUrl && (_jsxs("a", { href: secret.oauthConnectUrl, className: "inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium no-underline", style: { backgroundColor: "#625DF5", color: "white" }, children: [_jsx(IconPlugConnected, { size: 10 }), secret.status === "set" ? "Reconnect" : "Connect"] })), secret.docsUrl && (_jsxs("a", { href: secret.docsUrl, target: "_blank", rel: "noopener noreferrer", className: "inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] no-underline text-muted-foreground hover:text-foreground", children: ["Docs", _jsx(IconExternalLink, { size: 10 })] }))] })) : (_jsxs("div", { className: "mt-2 space-y-1.5", children: [secret.status === "set" && (_jsxs("div", { className: "flex items-center gap-2 text-[10px] text-muted-foreground", children: [_jsx("span", { children: "Stored value ending in" }), _jsx("code", { className: "rounded bg-background px-1 py-0.5 text-foreground", children: secret.last4 })] })), _jsxs("div", { className: "flex gap-1.5", children: [_jsx("input", { ref: inputRef, type: "password", value: value, onChange: (e) => setValue(e.target.value), onKeyDown: (e) => {
|
|
142
|
+
if (e.key === "Enter")
|
|
143
|
+
handleSave();
|
|
144
|
+
}, placeholder: secret.status === "set"
|
|
145
|
+
? "Enter new value to rotate"
|
|
146
|
+
: "Paste key", className: "flex-1 rounded border border-border bg-background px-2 py-1 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent" }), _jsx("button", { type: "button", onClick: handleSave, disabled: !value.trim() || busy !== null, className: "inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium disabled:opacity-40", style: { backgroundColor: "#625DF5", color: "white" }, children: busy === "save" ? (_jsx(IconLoader2, { size: 10, className: "animate-spin" })) : secret.status === "set" ? (_jsxs(_Fragment, { children: [_jsx(IconRefresh, { size: 10 }), "Rotate"] })) : ("Save") })] }), _jsxs("div", { className: "flex items-center gap-1.5", children: [secret.status === "set" && (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: handleTest, disabled: busy !== null, className: "inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] text-muted-foreground hover:text-foreground disabled:opacity-40", children: busy === "test" ? (_jsx(IconLoader2, { size: 10, className: "animate-spin" })) : ("Test") }), _jsx("button", { type: "button", onClick: handleDelete, disabled: busy !== null, className: "inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] text-muted-foreground hover:text-red-500 disabled:opacity-40", children: busy === "delete" ? (_jsx(IconLoader2, { size: 10, className: "animate-spin" })) : (_jsxs(_Fragment, { children: [_jsx(IconTrash, { size: 10 }), "Remove"] })) })] })), secret.docsUrl && (_jsxs("a", { href: secret.docsUrl, target: "_blank", rel: "noopener noreferrer", className: "inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] no-underline text-muted-foreground hover:text-foreground ml-auto", children: ["Get key", _jsx(IconExternalLink, { size: 10 })] }))] })] })), toast && (_jsx("p", { className: `mt-1.5 text-[10px] ${toast.kind === "ok" ? "text-green-500" : "text-red-500"}`, children: toast.text }))] }));
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=SecretsSection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SecretsSection.js","sourceRoot":"","sources":["../../../src/client/settings/SecretsSection.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SettingsPanel.d.ts","sourceRoot":"","sources":["../../../src/client/settings/SettingsPanel.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SettingsPanel.d.ts","sourceRoot":"","sources":["../../../src/client/settings/SettingsPanel.tsx"],"names":[],"mappings":"AAukBA,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAeD,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,eAAe,EACf,aAAa,EACb,SAAS,GACV,EAAE,kBAAkB,2CAgTpB"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Suspense, lazy, useState, useEffect } from "react";
|
|
3
3
|
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
4
|
-
import { IconChevronDown, IconCheck, IconExternalLink, IconBrain, IconBrowser, IconGitBranch, IconCloud, IconDatabase, IconShield, IconPlugConnected, IconTopologyRing2, IconLoader2, IconUpload, IconCoin, } from "@tabler/icons-react";
|
|
4
|
+
import { IconChevronDown, IconCheck, IconExternalLink, IconBrain, IconBrowser, IconGitBranch, IconCloud, IconDatabase, IconShield, IconPlugConnected, IconTopologyRing2, IconLoader2, IconUpload, IconCoin, IconMail, IconKey, IconMicrophone, } from "@tabler/icons-react";
|
|
5
5
|
import { SettingsSection } from "./SettingsSection.js";
|
|
6
6
|
import { useBuilderStatus } from "./useBuilderStatus.js";
|
|
7
7
|
import { AgentsSection } from "./AgentsSection.js";
|
|
8
8
|
import { UsageSection } from "./UsageSection.js";
|
|
9
|
+
import { SecretsSection } from "./SecretsSection.js";
|
|
10
|
+
import { VoiceTranscriptionSection } from "./VoiceTranscriptionSection.js";
|
|
9
11
|
const IntegrationsPanel = lazy(() => import("../integrations/IntegrationsPanel.js").then((m) => ({
|
|
10
12
|
default: m.IntegrationsPanel,
|
|
11
13
|
})));
|
|
@@ -70,6 +72,74 @@ function LLMSectionInner({ builderEnabled, connectUrl, connected, orgName, open,
|
|
|
70
72
|
handleSave();
|
|
71
73
|
}, placeholder: "sk-ant-...", className: "flex-1 rounded border border-border bg-background px-2 py-1 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent" }), _jsx("button", { onClick: handleSave, disabled: !apiKey.trim() || saving, className: "rounded bg-accent px-2 py-1 text-[10px] font-medium text-foreground hover:bg-accent/80 disabled:opacity-40", children: saving ? (_jsx(IconLoader2, { size: 10, className: "animate-spin" })) : saved ? (_jsx(IconCheck, { size: 10 })) : ("Save") })] })) })] }) }));
|
|
72
74
|
}
|
|
75
|
+
// ─── Email Section ──────────────────────────────────────────────────────────
|
|
76
|
+
function EmailSectionInner({ open, onToggle, }) {
|
|
77
|
+
const [envKeys, setEnvKeys] = useState([]);
|
|
78
|
+
const [resendKey, setResendKey] = useState("");
|
|
79
|
+
const [sendgridKey, setSendgridKey] = useState("");
|
|
80
|
+
const [fromAddr, setFromAddr] = useState("");
|
|
81
|
+
const [saving, setSaving] = useState(false);
|
|
82
|
+
const [saved, setSaved] = useState(false);
|
|
83
|
+
const [showSendgrid, setShowSendgrid] = useState(false);
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
fetch("/_agent-native/env-status")
|
|
86
|
+
.then((r) => (r.ok ? r.json() : []))
|
|
87
|
+
.then(setEnvKeys)
|
|
88
|
+
.catch(() => { });
|
|
89
|
+
}, [saved]);
|
|
90
|
+
const resendConfigured = envKeys.find((k) => k.key === "RESEND_API_KEY")?.configured ?? false;
|
|
91
|
+
const sendgridConfigured = envKeys.find((k) => k.key === "SENDGRID_API_KEY")?.configured ?? false;
|
|
92
|
+
const fromConfigured = envKeys.find((k) => k.key === "EMAIL_FROM")?.configured ?? false;
|
|
93
|
+
const anyConfigured = resendConfigured || sendgridConfigured;
|
|
94
|
+
const save = async (vars) => {
|
|
95
|
+
setSaving(true);
|
|
96
|
+
try {
|
|
97
|
+
const res = await fetch("/_agent-native/env-vars", {
|
|
98
|
+
method: "POST",
|
|
99
|
+
headers: { "Content-Type": "application/json" },
|
|
100
|
+
body: JSON.stringify({ vars }),
|
|
101
|
+
});
|
|
102
|
+
if (res.ok) {
|
|
103
|
+
setSaved(true);
|
|
104
|
+
setResendKey("");
|
|
105
|
+
setSendgridKey("");
|
|
106
|
+
setFromAddr("");
|
|
107
|
+
setTimeout(() => setSaved(false), 2000);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
finally {
|
|
111
|
+
setSaving(false);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
const saveResend = () => {
|
|
115
|
+
const vars = [];
|
|
116
|
+
if (resendKey.trim())
|
|
117
|
+
vars.push({ key: "RESEND_API_KEY", value: resendKey.trim() });
|
|
118
|
+
if (fromAddr.trim())
|
|
119
|
+
vars.push({ key: "EMAIL_FROM", value: fromAddr.trim() });
|
|
120
|
+
if (vars.length)
|
|
121
|
+
save(vars);
|
|
122
|
+
};
|
|
123
|
+
const saveSendgrid = () => {
|
|
124
|
+
const vars = [];
|
|
125
|
+
if (sendgridKey.trim())
|
|
126
|
+
vars.push({ key: "SENDGRID_API_KEY", value: sendgridKey.trim() });
|
|
127
|
+
if (fromAddr.trim())
|
|
128
|
+
vars.push({ key: "EMAIL_FROM", value: fromAddr.trim() });
|
|
129
|
+
if (vars.length)
|
|
130
|
+
save(vars);
|
|
131
|
+
};
|
|
132
|
+
return (_jsx(SettingsSection, { icon: _jsx(IconMail, { size: 14 }), title: "Email", subtitle: "Send password resets and team invitations. Without a provider, emails are logged to the server console.", connected: anyConfigured, open: open, onToggle: onToggle, children: _jsxs("div", { className: "space-y-2", children: [_jsxs(ManualSetupCard, { hint: "Paste a Resend API key to start sending real emails.", docsUrl: "https://resend.com/api-keys", docsLabel: "Get a Resend key", children: [resendConfigured ? (_jsxs("div", { className: "flex items-center gap-1.5 text-[10px] text-green-500 mb-1", children: [_jsx(IconCheck, { size: 10 }), "RESEND_API_KEY configured"] })) : (_jsxs("div", { className: "flex gap-1.5 mb-1", children: [_jsx("input", { type: "password", value: resendKey, onChange: (e) => setResendKey(e.target.value), onKeyDown: (e) => {
|
|
133
|
+
if (e.key === "Enter")
|
|
134
|
+
saveResend();
|
|
135
|
+
}, placeholder: "re_...", className: "flex-1 rounded border border-border bg-background px-2 py-1 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent" }), _jsx("button", { onClick: saveResend, disabled: !resendKey.trim() || saving, className: "rounded bg-accent px-2 py-1 text-[10px] font-medium text-foreground hover:bg-accent/80 disabled:opacity-40", children: saving ? (_jsx(IconLoader2, { size: 10, className: "animate-spin" })) : saved ? (_jsx(IconCheck, { size: 10 })) : ("Save") })] })), fromConfigured ? (_jsxs("div", { className: "flex items-center gap-1.5 text-[10px] text-green-500", children: [_jsx(IconCheck, { size: 10 }), "EMAIL_FROM configured"] })) : (_jsxs("div", { className: "flex gap-1.5", children: [_jsx("input", { type: "text", value: fromAddr, onChange: (e) => setFromAddr(e.target.value), onKeyDown: (e) => {
|
|
136
|
+
if (e.key === "Enter")
|
|
137
|
+
saveResend();
|
|
138
|
+
}, placeholder: "From address \u2014 e.g. Acme <hi@acme.com>", className: "flex-1 rounded border border-border bg-background px-2 py-1 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent" }), !resendConfigured ? null : (_jsx("button", { onClick: saveResend, disabled: !fromAddr.trim() || saving, className: "rounded bg-accent px-2 py-1 text-[10px] font-medium text-foreground hover:bg-accent/80 disabled:opacity-40", children: saving ? (_jsx(IconLoader2, { size: 10, className: "animate-spin" })) : saved ? (_jsx(IconCheck, { size: 10 })) : ("Save") }))] }))] }), !sendgridConfigured && !showSendgrid ? (_jsx("button", { type: "button", onClick: () => setShowSendgrid(true), className: "text-[10px] text-muted-foreground hover:text-foreground", children: "Use SendGrid instead" })) : (_jsx(ManualSetupCard, { hint: "SendGrid alternative \u2014 requires a verified sender address (set EMAIL_FROM above).", docsUrl: "https://app.sendgrid.com/settings/api_keys", docsLabel: "Get a SendGrid key", children: sendgridConfigured ? (_jsxs("div", { className: "flex items-center gap-1.5 text-[10px] text-green-500", children: [_jsx(IconCheck, { size: 10 }), "SENDGRID_API_KEY configured"] })) : (_jsxs("div", { className: "flex gap-1.5", children: [_jsx("input", { type: "password", value: sendgridKey, onChange: (e) => setSendgridKey(e.target.value), onKeyDown: (e) => {
|
|
139
|
+
if (e.key === "Enter")
|
|
140
|
+
saveSendgrid();
|
|
141
|
+
}, placeholder: "SG....", className: "flex-1 rounded border border-border bg-background px-2 py-1 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent" }), _jsx("button", { onClick: saveSendgrid, disabled: !sendgridKey.trim() || saving, className: "rounded bg-accent px-2 py-1 text-[10px] font-medium text-foreground hover:bg-accent/80 disabled:opacity-40", children: saving ? (_jsx(IconLoader2, { size: 10, className: "animate-spin" })) : saved ? (_jsx(IconCheck, { size: 10 })) : ("Save") })] })) }))] }) }));
|
|
142
|
+
}
|
|
73
143
|
const environmentOptions = [
|
|
74
144
|
{
|
|
75
145
|
value: "production",
|
|
@@ -99,13 +169,42 @@ export function SettingsPanel({ isDevMode, onToggleDevMode, showDevToggle, devAp
|
|
|
99
169
|
})
|
|
100
170
|
.catch(() => { });
|
|
101
171
|
}, []);
|
|
172
|
+
// Detect whether the app registered any secrets — controls whether the
|
|
173
|
+
// "API Keys & Connections" section renders at all.
|
|
174
|
+
const [hasSecrets, setHasSecrets] = useState(false);
|
|
175
|
+
const [focusSecretKey, setFocusSecretKey] = useState(undefined);
|
|
176
|
+
useEffect(() => {
|
|
177
|
+
fetch("/_agent-native/secrets")
|
|
178
|
+
.then((r) => (r.ok ? r.json() : []))
|
|
179
|
+
.then((list) => {
|
|
180
|
+
setHasSecrets(Array.isArray(list) && list.length > 0);
|
|
181
|
+
})
|
|
182
|
+
.catch(() => setHasSecrets(false));
|
|
183
|
+
}, []);
|
|
102
184
|
// Accordion: only one section open at a time (null = all closed)
|
|
103
185
|
const [openSection, setOpenSection] = useState("llm");
|
|
104
186
|
const toggle = (id) => setOpenSection((prev) => (prev === id ? null : id));
|
|
187
|
+
// Support `#secrets:<KEY>` hash fragments from the onboarding CTA — opens
|
|
188
|
+
// the section and focuses the matching input.
|
|
189
|
+
useEffect(() => {
|
|
190
|
+
if (typeof window === "undefined")
|
|
191
|
+
return;
|
|
192
|
+
const handleHash = () => {
|
|
193
|
+
const hash = window.location.hash?.replace(/^#/, "") ?? "";
|
|
194
|
+
if (hash.startsWith("secrets:") || hash === "secrets") {
|
|
195
|
+
setOpenSection("secrets");
|
|
196
|
+
const key = hash.slice("secrets:".length);
|
|
197
|
+
setFocusSecretKey(key || undefined);
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
handleHash();
|
|
201
|
+
window.addEventListener("hashchange", handleHash);
|
|
202
|
+
return () => window.removeEventListener("hashchange", handleHash);
|
|
203
|
+
}, []);
|
|
105
204
|
return (_jsxs("div", { className: "flex-1 min-h-0 overflow-y-auto p-3 space-y-2", style: { overflowY: "auto" }, children: [(showDevToggle || devAppUrl) && (_jsx("div", { className: "space-y-2 pb-2 border-b border-border mb-2", children: showDevToggle && (_jsx(SettingsSelect, { label: "Environment", labelAdornment: devAppUrl ? (_jsx("a", { href: devAppUrl, target: "_blank", rel: "noopener noreferrer", title: "Open app in new tab", "aria-label": "Open app in new tab", className: "flex items-center text-muted-foreground hover:text-foreground", children: _jsx(IconExternalLink, { size: 14 }) })) : undefined, value: isDevMode ? "development" : "production", options: environmentOptions, onValueChange: (next) => {
|
|
106
205
|
const nextIsDev = next === "development";
|
|
107
206
|
if (nextIsDev !== isDevMode)
|
|
108
207
|
onToggleDevMode();
|
|
109
|
-
} })) })), _jsx(LLMSectionInner, { builderEnabled: builderEnabled, connectUrl: connectUrl, connected: connected, orgName: orgName, open: openSection === "llm", onToggle: () => toggle("llm") }), _jsx(SettingsSection, { icon: _jsx(IconCloud, { size: 14 }), title: "Hosting", subtitle: "Deploy your app to the cloud.", connected: connected, open: openSection === "hosting", onToggle: () => toggle("hosting"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { connectUrl: connectUrl, connected: connected, orgName: orgName, comingSoon: true, builderEnabled: builderEnabled }), _jsx(ManualSetupCard, { hint: "Deploy manually to Netlify, Vercel, Cloudflare, or any Nitro-supported target.", docsUrl: "https://www.builder.io/c/docs/agent-native-deployment", dim: connected })] }) }), _jsx(SettingsSection, { icon: _jsx(IconDatabase, { size: 14 }), title: "Database", subtitle: "Connect a cloud database for persistent storage.", connected: connected, open: openSection === "database", onToggle: () => toggle("database"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { connectUrl: connectUrl, connected: connected, orgName: orgName, comingSoon: true, builderEnabled: builderEnabled }), _jsx(ManualSetupCard, { hint: "Set DATABASE_URL in your .env to connect Neon, Supabase, Turso, or any Postgres/SQLite database.", docsUrl: "https://www.builder.io/c/docs/agent-native-database", dim: connected })] }) }), _jsx(SettingsSection, { icon: _jsx(IconUpload, { size: 14 }), title: "File uploads", subtitle: "Where user-uploaded files (avatars, chat attachments) are stored.", connected: connected, open: openSection === "uploads", onToggle: () => toggle("uploads"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { connectUrl: connectUrl, connected: connected, orgName: orgName, comingSoon: true, builderEnabled: builderEnabled }), _jsx(ManualSetupCard, { hint: "Without a provider, files are stored as base64 in your database. Fine for dev, not recommended for production.", docsUrl: "https://www.builder.io/c/docs/agent-native-file-uploads", dim: connected })] }) }), _jsx(SettingsSection, { icon: _jsx(IconShield, { size: 14 }), title: "Authentication", subtitle: "Set up user authentication and access control.", connected: connected, open: openSection === "auth", onToggle: () => toggle("auth"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { connectUrl: connectUrl, connected: connected, orgName: orgName, comingSoon: true, builderEnabled: builderEnabled }), _jsx(ManualSetupCard, { hint: "Configure Better Auth with BETTER_AUTH_SECRET and optional Google/GitHub OAuth providers.", docsUrl: "https://www.builder.io/c/docs/agent-native-authentication", dim: connected })] }) }), _jsx(SettingsSection, { icon: _jsx(IconBrowser, { size: 14 }), title: "Browser Automation", subtitle: "Let agents control a real browser for web tasks.", connected: connected, open: openSection === "browser", onToggle: () => toggle("browser"), children: _jsx(UseBuilderCard, { connectUrl: connectUrl, connected: connected, orgName: orgName, comingSoon: true, builderEnabled: builderEnabled }) }), _jsx(SettingsSection, { icon: _jsx(IconGitBranch, { size: 14 }), title: "Background Agent", subtitle: "Make code changes from production mode via Builder.", connected: connected, open: openSection === "background", onToggle: () => toggle("background"), children: _jsx(UseBuilderCard, { connectUrl: connectUrl, connected: connected, orgName: orgName, comingSoon: true, builderEnabled: builderEnabled }) }), _jsx(SettingsSection, { icon: _jsx(IconPlugConnected, { size: 14 }), title: "Integrations", subtitle: "Connect messaging platforms and external services.", open: openSection === "integrations", onToggle: () => toggle("integrations"), children: _jsx(Suspense, { fallback: null, children: _jsx(IntegrationsPanel, {}) }) }), _jsx(SettingsSection, { icon: _jsx(IconCoin, { size: 14 }), title: "Usage", subtitle: "Track token consumption and estimated cost \u2014 broken down by chat, automations, and background jobs.", open: openSection === "usage", onToggle: () => toggle("usage"), children: _jsx(UsageSection, {}) }), _jsx(SettingsSection, { icon: _jsx(IconTopologyRing2, { size: 14 }), title: "Connected Agents (A2A)", subtitle: "Manage remote agents connected via the A2A protocol.", open: openSection === "a2a", onToggle: () => toggle("a2a"), children: _jsx(AgentsSection, {}) })] }));
|
|
208
|
+
} })) })), _jsx(LLMSectionInner, { builderEnabled: builderEnabled, connectUrl: connectUrl, connected: connected, orgName: orgName, open: openSection === "llm", onToggle: () => toggle("llm") }), _jsx(SettingsSection, { icon: _jsx(IconMicrophone, { size: 14 }), title: "Voice Transcription", subtitle: "How the composer microphone turns your voice into text.", open: openSection === "voice", onToggle: () => toggle("voice"), children: _jsx(VoiceTranscriptionSection, {}) }), hasSecrets && (_jsx(SettingsSection, { icon: _jsx(IconKey, { size: 14 }), title: "API Keys & Connections", subtitle: "Service credentials registered by this app.", open: openSection === "secrets", onToggle: () => toggle("secrets"), children: _jsx(SecretsSection, { focusKey: focusSecretKey }) })), _jsx(SettingsSection, { icon: _jsx(IconCloud, { size: 14 }), title: "Hosting", subtitle: "Deploy your app to the cloud.", connected: connected, open: openSection === "hosting", onToggle: () => toggle("hosting"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { connectUrl: connectUrl, connected: connected, orgName: orgName, comingSoon: true, builderEnabled: builderEnabled }), _jsx(ManualSetupCard, { hint: "Deploy manually to Netlify, Vercel, Cloudflare, or any Nitro-supported target.", docsUrl: "https://www.builder.io/c/docs/agent-native-deployment", dim: connected })] }) }), _jsx(SettingsSection, { icon: _jsx(IconDatabase, { size: 14 }), title: "Database", subtitle: "Connect a cloud database for persistent storage.", connected: connected, open: openSection === "database", onToggle: () => toggle("database"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { connectUrl: connectUrl, connected: connected, orgName: orgName, comingSoon: true, builderEnabled: builderEnabled }), _jsx(ManualSetupCard, { hint: "Set DATABASE_URL in your .env to connect Neon, Supabase, Turso, or any Postgres/SQLite database.", docsUrl: "https://www.builder.io/c/docs/agent-native-database", dim: connected })] }) }), _jsx(SettingsSection, { icon: _jsx(IconUpload, { size: 14 }), title: "File uploads", subtitle: "Where user-uploaded files (avatars, chat attachments) are stored.", connected: connected, open: openSection === "uploads", onToggle: () => toggle("uploads"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { connectUrl: connectUrl, connected: connected, orgName: orgName, comingSoon: true, builderEnabled: builderEnabled }), _jsx(ManualSetupCard, { hint: "Without a provider, files are stored as base64 in your database. Fine for dev, not recommended for production.", docsUrl: "https://www.builder.io/c/docs/agent-native-file-uploads", dim: connected })] }) }), _jsx(SettingsSection, { icon: _jsx(IconShield, { size: 14 }), title: "Authentication", subtitle: "Set up user authentication and access control.", connected: connected, open: openSection === "auth", onToggle: () => toggle("auth"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { connectUrl: connectUrl, connected: connected, orgName: orgName, comingSoon: true, builderEnabled: builderEnabled }), _jsx(ManualSetupCard, { hint: "Configure Better Auth with BETTER_AUTH_SECRET and optional Google/GitHub OAuth providers.", docsUrl: "https://www.builder.io/c/docs/agent-native-authentication", dim: connected })] }) }), _jsx(EmailSectionInner, { open: openSection === "email", onToggle: () => toggle("email") }), _jsx(SettingsSection, { icon: _jsx(IconBrowser, { size: 14 }), title: "Browser Automation", subtitle: "Let agents control a real browser for web tasks.", connected: connected, open: openSection === "browser", onToggle: () => toggle("browser"), children: _jsx(UseBuilderCard, { connectUrl: connectUrl, connected: connected, orgName: orgName, comingSoon: true, builderEnabled: builderEnabled }) }), _jsx(SettingsSection, { icon: _jsx(IconGitBranch, { size: 14 }), title: "Background Agent", subtitle: "Make code changes from production mode via Builder.", connected: connected, open: openSection === "background", onToggle: () => toggle("background"), children: _jsx(UseBuilderCard, { connectUrl: connectUrl, connected: connected, orgName: orgName, comingSoon: true, builderEnabled: builderEnabled }) }), _jsx(SettingsSection, { icon: _jsx(IconPlugConnected, { size: 14 }), title: "Integrations", subtitle: "Connect messaging platforms and external services.", open: openSection === "integrations", onToggle: () => toggle("integrations"), children: _jsx(Suspense, { fallback: null, children: _jsx(IntegrationsPanel, {}) }) }), _jsx(SettingsSection, { icon: _jsx(IconCoin, { size: 14 }), title: "Usage", subtitle: "Track token consumption and estimated cost \u2014 broken down by chat, automations, and background jobs.", open: openSection === "usage", onToggle: () => toggle("usage"), children: _jsx(UsageSection, {}) }), _jsx(SettingsSection, { icon: _jsx(IconTopologyRing2, { size: 14 }), title: "Connected Agents (A2A)", subtitle: "Manage remote agents connected via the A2A protocol.", open: openSection === "a2a", onToggle: () => toggle("a2a"), children: _jsx(AgentsSection, {}) })] }));
|
|
110
209
|
}
|
|
111
210
|
//# sourceMappingURL=SettingsPanel.js.map
|