@agent-native/dispatch 0.8.20 → 0.8.24
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/dist/components/messaging-setup-panel.d.ts.map +1 -1
- package/dist/components/messaging-setup-panel.js +2 -3
- package/dist/components/messaging-setup-panel.js.map +1 -1
- package/dist/routes/pages/chat.d.ts +21 -2
- package/dist/routes/pages/chat.d.ts.map +1 -1
- package/dist/routes/pages/chat.js +12 -3
- package/dist/routes/pages/chat.js.map +1 -1
- package/dist/routes/pages/overview.d.ts +21 -2
- package/dist/routes/pages/overview.d.ts.map +1 -1
- package/dist/routes/pages/overview.js +13 -4
- package/dist/routes/pages/overview.js.map +1 -1
- package/dist/server/lib/dispatch-integrations.d.ts.map +1 -1
- package/dist/server/lib/dispatch-integrations.js +27 -3
- package/dist/server/lib/dispatch-integrations.js.map +1 -1
- package/dist/server/lib/mcp-gateway.d.ts.map +1 -1
- package/dist/server/lib/mcp-gateway.js +0 -6
- package/dist/server/lib/mcp-gateway.js.map +1 -1
- package/dist/server/lib/thread-link-preview.d.ts +24 -0
- package/dist/server/lib/thread-link-preview.d.ts.map +1 -0
- package/dist/server/lib/thread-link-preview.js +176 -0
- package/dist/server/lib/thread-link-preview.js.map +1 -0
- package/dist/server/lib/vault-store.d.ts +1 -0
- package/dist/server/lib/vault-store.d.ts.map +1 -1
- package/dist/server/lib/vault-store.js +67 -20
- package/dist/server/lib/vault-store.js.map +1 -1
- package/package.json +1 -1
- package/src/components/messaging-setup-panel.tsx +2 -3
- package/src/routes/pages/chat.tsx +20 -3
- package/src/routes/pages/overview.tsx +21 -8
- package/src/server/lib/dispatch-integrations.spec.ts +69 -0
- package/src/server/lib/dispatch-integrations.ts +26 -3
- package/src/server/lib/mcp-gateway.ts +0 -6
- package/src/server/lib/thread-link-preview.spec.ts +129 -0
- package/src/server/lib/thread-link-preview.ts +187 -0
- package/src/server/lib/vault-store.spec.ts +25 -0
- package/src/server/lib/vault-store.ts +75 -20
- package/src/server/lib/workspace-resource-approval-lifecycle.spec.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messaging-setup-panel.d.ts","sourceRoot":"","sources":["../../src/components/messaging-setup-panel.tsx"],"names":[],"mappings":"AAuNA,wBAAgB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"messaging-setup-panel.d.ts","sourceRoot":"","sources":["../../src/components/messaging-setup-panel.tsx"],"names":[],"mappings":"AAuNA,wBAAgB,mBAAmB,4CAgdlC"}
|
|
@@ -216,7 +216,7 @@ export function MessagingSetupPanel() {
|
|
|
216
216
|
setTogglingPlatform(platform.id);
|
|
217
217
|
try {
|
|
218
218
|
const action = enabled ? "disable" : "enable";
|
|
219
|
-
const res = await fetch(`/_agent-native/integrations/${platform.id}/${action}
|
|
219
|
+
const res = await fetch(agentNativePath(`/_agent-native/integrations/${platform.id}/${action}`), {
|
|
220
220
|
method: "POST",
|
|
221
221
|
});
|
|
222
222
|
if (!res.ok) {
|
|
@@ -238,7 +238,7 @@ export function MessagingSetupPanel() {
|
|
|
238
238
|
const runSetup = async (platform) => {
|
|
239
239
|
setSetupPlatform(platform.id);
|
|
240
240
|
try {
|
|
241
|
-
const res = await fetch(`/_agent-native/integrations/${platform.id}/setup
|
|
241
|
+
const res = await fetch(agentNativePath(`/_agent-native/integrations/${platform.id}/setup`), {
|
|
242
242
|
method: "POST",
|
|
243
243
|
});
|
|
244
244
|
if (!res.ok) {
|
|
@@ -279,7 +279,6 @@ export function MessagingSetupPanel() {
|
|
|
279
279
|
label: key,
|
|
280
280
|
required: true,
|
|
281
281
|
}));
|
|
282
|
-
const canEnable = configured;
|
|
283
282
|
return (_jsxs("section", { className: "rounded-2xl border bg-card p-5", children: [_jsxs("div", { className: "flex items-start justify-between gap-4", children: [_jsxs("div", { className: "flex items-start gap-3", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-xl border bg-muted/30 text-foreground", children: _jsx(platform.icon, { size: 18 }) }), _jsxs("div", { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("h3", { className: "text-base font-semibold text-foreground", children: platform.label }), _jsx(ConnectionStatus, { configured: configured, enabled: enabled })] }), _jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: platform.description })] })] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [_jsx(Button, { asChild: true, variant: "ghost", size: "sm", className: "h-7 px-2 text-xs text-muted-foreground", children: _jsxs("a", { href: platform.docsUrl, target: "_blank", rel: "noreferrer", children: ["Docs", _jsx(IconExternalLink, { className: "ml-1 h-3 w-3" })] }) }), platform.externalUrl ? (_jsx(Button, { asChild: true, variant: "ghost", size: "sm", className: "h-7 px-2 text-xs text-muted-foreground", children: _jsxs("a", { href: platform.externalUrl, target: "_blank", rel: "noreferrer", children: [platform.externalLabel ?? "Open", _jsx(IconExternalLink, { className: "ml-1 h-3 w-3" })] }) })) : null] })] }), _jsxs(Collapsible, { className: "mt-5", children: [_jsxs(CollapsibleTrigger, { className: "group flex w-full cursor-pointer items-center gap-1.5 text-xs font-medium text-muted-foreground hover:text-foreground", children: [_jsx(IconChevronRight, { className: "h-3.5 w-3.5 transition-transform group-data-[state=open]:rotate-90" }), _jsx("span", { children: "Setup steps" })] }), _jsx(CollapsibleContent, { children: _jsx("div", { className: "mt-2 rounded-xl border bg-muted/20 p-4", children: _jsx("ol", { className: "space-y-2 text-sm text-muted-foreground", children: platform.setupSteps.map((step, index) => (_jsxs("li", { className: "flex gap-2", children: [_jsxs("span", { className: "text-muted-foreground/60", children: [index + 1, "."] }), _jsx("span", { children: step })] }, step))) }) }) })] }), _jsxs("div", { className: "mt-4 space-y-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "text-sm font-medium text-foreground", children: "Credentials" }), envLoading ? (_jsx("span", { className: "text-xs text-muted-foreground", children: "Checking..." })) : null] }), _jsx("div", { className: "space-y-3", children: envKeys.map((envKey) => {
|
|
284
283
|
const envStatus = envStatusByKey.get(envKey.key);
|
|
285
284
|
const isConfigured = !!envStatus?.configured;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messaging-setup-panel.js","sourceRoot":"","sources":["../../src/components/messaging-setup-panel.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useMemo, useState } from \"react\";\nimport { toast } from \"sonner\";\nimport {\n IconBrandSlack,\n IconBrandTelegram,\n IconBrandWhatsapp,\n IconCheck,\n IconChevronRight,\n IconCopy,\n IconExternalLink,\n IconInfoCircle,\n IconLoader2,\n IconMail,\n} from \"@tabler/icons-react\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/components/ui/collapsible\";\nimport { Input } from \"@/components/ui/input\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { agentNativePath } from \"@agent-native/core/client\";\n\ninterface EnvStatus {\n key: string;\n label: string;\n required: boolean;\n configured: boolean;\n helpText?: string;\n}\n\ninterface RequiredEnvKey {\n key: string;\n label: string;\n required: boolean;\n helpText?: string;\n}\n\ninterface IntegrationStatus {\n platform: string;\n label: string;\n enabled: boolean;\n configured: boolean;\n webhookUrl?: string;\n requiredEnvKeys?: RequiredEnvKey[];\n}\n\ninterface PlatformDefinition {\n id: \"slack\" | \"telegram\" | \"email\" | \"whatsapp\";\n label: string;\n icon: typeof IconBrandSlack;\n description: string;\n /** Our own docs anchor — keep these on /docs/messaging so users land on\n * the page that explains the platform in plain English. */\n docsUrl: string;\n /** Optional external link (e.g. to the platform's developer console). */\n externalUrl?: string;\n externalLabel?: string;\n setupSteps: string[];\n /** Fallback env keys when the adapter doesn't surface them via\n * `IntegrationStatus.requiredEnvKeys`. The panel prefers adapter-supplied\n * keys when present so optional fields (webhook secrets, etc.) appear\n * automatically. */\n envKeys: string[];\n}\n\nconst PLATFORM_DEFINITIONS: PlatformDefinition[] = [\n {\n id: \"slack\",\n label: \"Slack\",\n icon: IconBrandSlack,\n description: \"Receive mentions and DMs in one workspace-aware dispatch.\",\n docsUrl: \"/docs/messaging#slack\",\n externalUrl: \"https://api.slack.com/apps\",\n externalLabel: \"Open Slack apps\",\n envKeys: [\"SLACK_BOT_TOKEN\", \"SLACK_SIGNING_SECRET\"],\n setupSteps: [\n \"Create or open a Slack app at api.slack.com/apps.\",\n \"Save the bot token and signing secret below — the webhook URL appears once they're saved.\",\n \"Back in Slack, enable Event Subscriptions and paste the webhook URL.\",\n \"Subscribe to app_mention and message.im events, then install the app.\",\n \"Optional but recommended: Basic Information → Display Information → upload an app icon and pick a background color so the bot has a clean avatar in every channel.\",\n ],\n },\n {\n id: \"telegram\",\n label: \"Telegram\",\n icon: IconBrandTelegram,\n description: \"Chat with dispatch through a Telegram bot.\",\n docsUrl: \"/docs/messaging#telegram\",\n externalUrl: \"https://t.me/BotFather\",\n externalLabel: \"Open BotFather\",\n envKeys: [\"TELEGRAM_BOT_TOKEN\"],\n setupSteps: [\n \"Open @BotFather in Telegram and send /newbot.\",\n \"Save the bot token here, then click Set up webhook below.\",\n \"DM the bot in Telegram to test.\",\n ],\n },\n {\n id: \"email\",\n label: \"Email\",\n icon: IconMail,\n description:\n \"Give your agent an email address. People can email it directly or CC it on threads.\",\n docsUrl: \"/docs/messaging#email\",\n externalUrl: \"https://resend.com/webhooks\",\n externalLabel: \"Open Resend webhooks\",\n envKeys: [\"EMAIL_AGENT_ADDRESS\"],\n setupSteps: [\n \"Save your Resend or SendGrid API key (Vault or onboarding).\",\n \"Pick an email address — the easiest is a free <slug>.resend.app address.\",\n \"If using your own domain, add MX records pointing to your provider.\",\n \"Save the address here, then register the webhook URL below in Resend (event: email.received).\",\n ],\n },\n {\n id: \"whatsapp\",\n label: \"WhatsApp\",\n icon: IconBrandWhatsapp,\n description:\n \"Receive WhatsApp messages and reply through a Meta-managed phone number.\",\n docsUrl: \"/docs/messaging#whatsapp\",\n externalUrl: \"https://developers.facebook.com/apps\",\n externalLabel: \"Open Meta developer console\",\n envKeys: [\n \"WHATSAPP_ACCESS_TOKEN\",\n \"WHATSAPP_VERIFY_TOKEN\",\n \"WHATSAPP_PHONE_NUMBER_ID\",\n ],\n setupSteps: [\n \"Create a Meta app and add the WhatsApp product.\",\n \"Save the access token, verify token, and phone number ID below.\",\n \"In Meta's WhatsApp configuration, paste the webhook URL and your verify token.\",\n \"Subscribe to the messages field, then enable here.\",\n ],\n },\n];\n\nfunction HelpTooltip({ content }: { content: string }) {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n className=\"text-muted-foreground/60 hover:text-foreground cursor-pointer\"\n >\n <IconInfoCircle className=\"h-3.5 w-3.5\" />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"top\" className=\"max-w-64 text-xs leading-relaxed\">\n {content}\n </TooltipContent>\n </Tooltip>\n );\n}\n\nfunction StatusPill({\n tone,\n label,\n}: {\n tone: \"neutral\" | \"success\" | \"warning\";\n label: string;\n}) {\n const toneClass =\n tone === \"success\"\n ? \"border-emerald-500/30 bg-emerald-500/10 text-emerald-300\"\n : tone === \"warning\"\n ? \"border-amber-500/30 bg-amber-500/10 text-amber-300\"\n : \"border-border bg-muted/40 text-muted-foreground\";\n\n return (\n <span\n className={`inline-flex items-center rounded-full border px-2.5 py-1 text-[11px] font-medium ${toneClass}`}\n >\n {label}\n </span>\n );\n}\n\n/** Render a non-secret env value (e.g. EMAIL_AGENT_ADDRESS) as a copyable\n * text block. We can't read the actual value from the backend (env-status\n * only reports `configured: true|false`), so we offer a one-click reveal\n * that hits a server endpoint, falling back to \"saved\" if the value is\n * not exposed. For now we just render a \"Saved — re-enter to change\"\n * placeholder; a future endpoint can return the actual value. */\nfunction PublicValueReveal({ envKey: _envKey }: { envKey: string }) {\n return (\n <div className=\"rounded-md border bg-muted/20 px-3 py-2 text-xs text-muted-foreground\">\n Saved. Re-enter below to change.\n </div>\n );\n}\n\nfunction ConnectionStatus({\n configured,\n enabled,\n}: {\n configured: boolean;\n enabled: boolean;\n}) {\n if (enabled) {\n return <StatusPill tone=\"success\" label=\"Connected\" />;\n }\n if (configured) {\n return <StatusPill tone=\"warning\" label=\"Configured, not enabled\" />;\n }\n return <StatusPill tone=\"neutral\" label=\"Not configured\" />;\n}\n\nexport function MessagingSetupPanel() {\n const [statuses, setStatuses] = useState<IntegrationStatus[]>([]);\n const [loading, setLoading] = useState(true);\n const [envStatuses, setEnvStatuses] = useState<EnvStatus[]>([]);\n const [envLoading, setEnvLoading] = useState(true);\n const [envValues, setEnvValues] = useState<Record<string, string>>({});\n const [savingKeysFor, setSavingKeysFor] = useState<string | null>(null);\n const [togglingPlatform, setTogglingPlatform] = useState<string | null>(null);\n const [setupPlatform, setSetupPlatform] = useState<string | null>(null);\n const [copiedWebhook, setCopiedWebhook] = useState<string | null>(null);\n\n const refreshStatuses = async () => {\n setLoading(true);\n try {\n const res = await fetch(\n agentNativePath(\"/_agent-native/integrations/status\"),\n );\n const rows = res.ok ? await res.json() : [];\n setStatuses(Array.isArray(rows) ? rows : []);\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n let active = true;\n fetch(agentNativePath(\"/_agent-native/integrations/status\"))\n .then((res) => (res.ok ? res.json() : []))\n .then((rows) => {\n if (active) {\n setStatuses(Array.isArray(rows) ? rows : []);\n setLoading(false);\n }\n })\n .catch(() => {\n if (active) setLoading(false);\n });\n return () => {\n active = false;\n };\n }, []);\n\n useEffect(() => {\n let active = true;\n fetch(agentNativePath(\"/_agent-native/env-status\"))\n .then((res) => (res.ok ? res.json() : []))\n .then((rows) => {\n if (active) {\n setEnvStatuses(Array.isArray(rows) ? rows : []);\n setEnvLoading(false);\n }\n })\n .catch(() => {\n if (active) setEnvLoading(false);\n });\n return () => {\n active = false;\n };\n }, []);\n\n const envStatusByKey = useMemo(\n () => new Map(envStatuses.map((status) => [status.key, status])),\n [envStatuses],\n );\n const statusByPlatform = useMemo(\n () => new Map(statuses.map((status) => [status.platform, status])),\n [statuses],\n );\n\n const refreshEnvStatus = async () => {\n setEnvLoading(true);\n try {\n const res = await fetch(agentNativePath(\"/_agent-native/env-status\"));\n const rows = res.ok ? await res.json() : [];\n setEnvStatuses(Array.isArray(rows) ? rows : []);\n } finally {\n setEnvLoading(false);\n }\n };\n\n const saveEnvKeys = async (platform: PlatformDefinition, keys: string[]) => {\n const vars = keys\n .map((key) => ({ key, value: envValues[key]?.trim() || \"\" }))\n .filter((item) => item.value);\n\n if (vars.length === 0) {\n toast.error(\"Add the required credentials first.\");\n return;\n }\n\n setSavingKeysFor(platform.id);\n try {\n const res = await fetch(agentNativePath(\"/_agent-native/env-vars\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ vars }),\n });\n\n if (!res.ok) {\n const payload = await res.json().catch(() => ({}));\n throw new Error(payload.error || \"Failed to save credentials\");\n }\n\n toast.success(`${platform.label} credentials saved`);\n setEnvValues((current) => {\n const next = { ...current };\n for (const key of keys) delete next[key];\n return next;\n });\n await refreshEnvStatus();\n await refreshStatuses();\n } catch (error) {\n toast.error(\n error instanceof Error ? error.message : \"Failed to save credentials\",\n );\n } finally {\n setSavingKeysFor(null);\n }\n };\n\n const togglePlatform = async (\n platform: PlatformDefinition,\n enabled: boolean,\n ) => {\n setTogglingPlatform(platform.id);\n try {\n const action = enabled ? \"disable\" : \"enable\";\n const res = await fetch(\n `/_agent-native/integrations/${platform.id}/${action}`,\n {\n method: \"POST\",\n },\n );\n if (!res.ok) {\n const payload = await res.json().catch(() => ({}));\n throw new Error(\n payload.error || `Failed to ${action} ${platform.label}`,\n );\n }\n toast.success(\n enabled\n ? `${platform.label} disconnected`\n : `${platform.label} connected`,\n );\n await refreshStatuses();\n } catch (error) {\n toast.error(\n error instanceof Error ? error.message : \"Failed to update integration\",\n );\n } finally {\n setTogglingPlatform(null);\n }\n };\n\n const runSetup = async (platform: PlatformDefinition) => {\n setSetupPlatform(platform.id);\n try {\n const res = await fetch(\n `/_agent-native/integrations/${platform.id}/setup`,\n {\n method: \"POST\",\n },\n );\n if (!res.ok) {\n const payload = await res.json().catch(() => ({}));\n throw new Error(payload.error || `Failed to set up ${platform.label}`);\n }\n toast.success(\n platform.id === \"telegram\"\n ? \"Telegram webhook registered\"\n : `${platform.label} setup complete`,\n );\n await refreshStatuses();\n } catch (error) {\n toast.error(\n error instanceof Error\n ? error.message\n : `Failed to set up ${platform.label}`,\n );\n } finally {\n setSetupPlatform(null);\n }\n };\n\n const copyWebhook = async (webhookUrl: string) => {\n await navigator.clipboard.writeText(webhookUrl);\n setCopiedWebhook(webhookUrl);\n toast.success(\"Webhook URL copied\");\n setTimeout(() => setCopiedWebhook(null), 1500);\n };\n\n return (\n <div className=\"space-y-4\">\n <div className=\"grid gap-4 xl:grid-cols-2\">\n {PLATFORM_DEFINITIONS.map((platform) => {\n const status = statusByPlatform.get(platform.id);\n const configured = !!status?.configured;\n const enabled = !!status?.enabled;\n // Prefer adapter-supplied env keys (includes optional fields like\n // webhook secrets); fall back to the static list.\n const adapterKeys = status?.requiredEnvKeys;\n const envKeys: RequiredEnvKey[] =\n adapterKeys && adapterKeys.length > 0\n ? adapterKeys\n : platform.envKeys.map((key) => ({\n key,\n label: key,\n required: true,\n }));\n const canEnable = configured;\n\n return (\n <section\n key={platform.id}\n className=\"rounded-2xl border bg-card p-5\"\n >\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"flex items-start gap-3\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-xl border bg-muted/30 text-foreground\">\n <platform.icon size={18} />\n </div>\n <div>\n <div className=\"flex items-center gap-2\">\n <h3 className=\"text-base font-semibold text-foreground\">\n {platform.label}\n </h3>\n <ConnectionStatus\n configured={configured}\n enabled={enabled}\n />\n </div>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {platform.description}\n </p>\n </div>\n </div>\n <div className=\"flex shrink-0 items-center gap-1\">\n <Button\n asChild\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 px-2 text-xs text-muted-foreground\"\n >\n <a href={platform.docsUrl} target=\"_blank\" rel=\"noreferrer\">\n Docs\n <IconExternalLink className=\"ml-1 h-3 w-3\" />\n </a>\n </Button>\n {platform.externalUrl ? (\n <Button\n asChild\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 px-2 text-xs text-muted-foreground\"\n >\n <a\n href={platform.externalUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {platform.externalLabel ?? \"Open\"}\n <IconExternalLink className=\"ml-1 h-3 w-3\" />\n </a>\n </Button>\n ) : null}\n </div>\n </div>\n\n <Collapsible className=\"mt-5\">\n <CollapsibleTrigger className=\"group flex w-full cursor-pointer items-center gap-1.5 text-xs font-medium text-muted-foreground hover:text-foreground\">\n <IconChevronRight className=\"h-3.5 w-3.5 transition-transform group-data-[state=open]:rotate-90\" />\n <span>Setup steps</span>\n </CollapsibleTrigger>\n <CollapsibleContent>\n <div className=\"mt-2 rounded-xl border bg-muted/20 p-4\">\n <ol className=\"space-y-2 text-sm text-muted-foreground\">\n {platform.setupSteps.map((step, index) => (\n <li key={step} className=\"flex gap-2\">\n <span className=\"text-muted-foreground/60\">\n {index + 1}.\n </span>\n <span>{step}</span>\n </li>\n ))}\n </ol>\n </div>\n </CollapsibleContent>\n </Collapsible>\n\n <div className=\"mt-4 space-y-3\">\n <div className=\"flex items-center gap-2\">\n <div className=\"text-sm font-medium text-foreground\">\n Credentials\n </div>\n {envLoading ? (\n <span className=\"text-xs text-muted-foreground\">\n Checking...\n </span>\n ) : null}\n </div>\n <div className=\"space-y-3\">\n {envKeys.map((envKey) => {\n const envStatus = envStatusByKey.get(envKey.key);\n const isConfigured = !!envStatus?.configured;\n const helpText = envKey.helpText ?? envStatus?.helpText;\n const label =\n envKey.label || envStatus?.label || envKey.key;\n // Email agent address is not a secret — show it plainly\n // so users can copy and share it.\n const isPublicValue = envKey.key === \"EMAIL_AGENT_ADDRESS\";\n return (\n <div key={envKey.key} className=\"space-y-1.5\">\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"flex items-center gap-1.5\">\n <label className=\"text-xs font-medium text-foreground\">\n {label}\n {!envKey.required ? (\n <span className=\"ml-1 text-muted-foreground\">\n (optional)\n </span>\n ) : null}\n </label>\n {helpText ? (\n <HelpTooltip content={helpText} />\n ) : null}\n </div>\n {isConfigured ? (\n <StatusPill tone=\"success\" label=\"Saved\" />\n ) : (\n <StatusPill\n tone={envKey.required ? \"neutral\" : \"neutral\"}\n label={envKey.required ? \"Missing\" : \"Not set\"}\n />\n )}\n </div>\n {isConfigured && isPublicValue ? (\n <PublicValueReveal envKey={envKey.key} />\n ) : !isConfigured ? (\n <Input\n type={isPublicValue ? \"text\" : \"password\"}\n value={envValues[envKey.key] || \"\"}\n onChange={(event) =>\n setEnvValues((current) => ({\n ...current,\n [envKey.key]: event.target.value,\n }))\n }\n placeholder={\n isPublicValue\n ? \"agent@yourcompany.com\"\n : `Enter ${label}`\n }\n autoComplete=\"off\"\n />\n ) : null}\n </div>\n );\n })}\n </div>\n {envKeys.some((k) => !envStatusByKey.get(k.key)?.configured) ? (\n <Button\n variant=\"outline\"\n onClick={() =>\n saveEnvKeys(\n platform,\n envKeys.map((k) => k.key),\n )\n }\n disabled={savingKeysFor === platform.id}\n >\n {savingKeysFor === platform.id ? (\n <>\n <IconLoader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n Saving...\n </>\n ) : (\n \"Save credentials\"\n )}\n </Button>\n ) : null}\n </div>\n\n {status?.webhookUrl ? (\n <div className=\"mt-4 space-y-2\">\n <div className=\"text-sm font-medium text-foreground\">\n Webhook URL\n </div>\n <div className=\"flex items-center gap-2\">\n <code className=\"flex-1 truncate rounded-md border bg-muted/30 px-3 py-2 text-xs text-foreground\">\n {status.webhookUrl}\n </code>\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => copyWebhook(status.webhookUrl!)}\n aria-label={`Copy ${platform.label} webhook URL`}\n >\n {copiedWebhook === status.webhookUrl ? (\n <IconCheck className=\"h-4 w-4\" />\n ) : (\n <IconCopy className=\"h-4 w-4\" />\n )}\n </Button>\n </div>\n </div>\n ) : null}\n\n <div className=\"mt-5 flex flex-wrap items-center justify-end gap-2 border-t border-border pt-4\">\n {platform.id === \"telegram\" && configured ? (\n <Button\n variant=\"outline\"\n onClick={() => runSetup(platform)}\n disabled={setupPlatform === platform.id}\n >\n {setupPlatform === platform.id ? (\n <>\n <IconLoader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n Setting up...\n </>\n ) : (\n \"Set up webhook\"\n )}\n </Button>\n ) : null}\n {!configured && !enabled ? (\n <Tooltip>\n <TooltipTrigger asChild>\n <span tabIndex={0}>\n <Button disabled>Enable</Button>\n </span>\n </TooltipTrigger>\n <TooltipContent>\n Save the required credentials first.\n </TooltipContent>\n </Tooltip>\n ) : (\n <Button\n onClick={() => togglePlatform(platform, enabled)}\n disabled={togglingPlatform === platform.id}\n >\n {togglingPlatform === platform.id ? (\n <>\n <IconLoader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n Saving...\n </>\n ) : enabled ? (\n \"Disable\"\n ) : (\n \"Enable\"\n )}\n </Button>\n )}\n </div>\n </section>\n );\n })}\n </div>\n\n {loading ? (\n <div className=\"rounded-2xl border border-dashed px-4 py-6 text-sm text-muted-foreground\">\n Loading messaging status...\n </div>\n ) : null}\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"messaging-setup-panel.js","sourceRoot":"","sources":["../../src/components/messaging-setup-panel.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useMemo, useState } from \"react\";\nimport { toast } from \"sonner\";\nimport {\n IconBrandSlack,\n IconBrandTelegram,\n IconBrandWhatsapp,\n IconCheck,\n IconChevronRight,\n IconCopy,\n IconExternalLink,\n IconInfoCircle,\n IconLoader2,\n IconMail,\n} from \"@tabler/icons-react\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/components/ui/collapsible\";\nimport { Input } from \"@/components/ui/input\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { agentNativePath } from \"@agent-native/core/client\";\n\ninterface EnvStatus {\n key: string;\n label: string;\n required: boolean;\n configured: boolean;\n helpText?: string;\n}\n\ninterface RequiredEnvKey {\n key: string;\n label: string;\n required: boolean;\n helpText?: string;\n}\n\ninterface IntegrationStatus {\n platform: string;\n label: string;\n enabled: boolean;\n configured: boolean;\n webhookUrl?: string;\n requiredEnvKeys?: RequiredEnvKey[];\n}\n\ninterface PlatformDefinition {\n id: \"slack\" | \"telegram\" | \"email\" | \"whatsapp\";\n label: string;\n icon: typeof IconBrandSlack;\n description: string;\n /** Our own docs anchor — keep these on /docs/messaging so users land on\n * the page that explains the platform in plain English. */\n docsUrl: string;\n /** Optional external link (e.g. to the platform's developer console). */\n externalUrl?: string;\n externalLabel?: string;\n setupSteps: string[];\n /** Fallback env keys when the adapter doesn't surface them via\n * `IntegrationStatus.requiredEnvKeys`. The panel prefers adapter-supplied\n * keys when present so optional fields (webhook secrets, etc.) appear\n * automatically. */\n envKeys: string[];\n}\n\nconst PLATFORM_DEFINITIONS: PlatformDefinition[] = [\n {\n id: \"slack\",\n label: \"Slack\",\n icon: IconBrandSlack,\n description: \"Receive mentions and DMs in one workspace-aware dispatch.\",\n docsUrl: \"/docs/messaging#slack\",\n externalUrl: \"https://api.slack.com/apps\",\n externalLabel: \"Open Slack apps\",\n envKeys: [\"SLACK_BOT_TOKEN\", \"SLACK_SIGNING_SECRET\"],\n setupSteps: [\n \"Create or open a Slack app at api.slack.com/apps.\",\n \"Save the bot token and signing secret below — the webhook URL appears once they're saved.\",\n \"Back in Slack, enable Event Subscriptions and paste the webhook URL.\",\n \"Subscribe to app_mention and message.im events, then install the app.\",\n \"Optional but recommended: Basic Information → Display Information → upload an app icon and pick a background color so the bot has a clean avatar in every channel.\",\n ],\n },\n {\n id: \"telegram\",\n label: \"Telegram\",\n icon: IconBrandTelegram,\n description: \"Chat with dispatch through a Telegram bot.\",\n docsUrl: \"/docs/messaging#telegram\",\n externalUrl: \"https://t.me/BotFather\",\n externalLabel: \"Open BotFather\",\n envKeys: [\"TELEGRAM_BOT_TOKEN\"],\n setupSteps: [\n \"Open @BotFather in Telegram and send /newbot.\",\n \"Save the bot token here, then click Set up webhook below.\",\n \"DM the bot in Telegram to test.\",\n ],\n },\n {\n id: \"email\",\n label: \"Email\",\n icon: IconMail,\n description:\n \"Give your agent an email address. People can email it directly or CC it on threads.\",\n docsUrl: \"/docs/messaging#email\",\n externalUrl: \"https://resend.com/webhooks\",\n externalLabel: \"Open Resend webhooks\",\n envKeys: [\"EMAIL_AGENT_ADDRESS\"],\n setupSteps: [\n \"Save your Resend or SendGrid API key (Vault or onboarding).\",\n \"Pick an email address — the easiest is a free <slug>.resend.app address.\",\n \"If using your own domain, add MX records pointing to your provider.\",\n \"Save the address here, then register the webhook URL below in Resend (event: email.received).\",\n ],\n },\n {\n id: \"whatsapp\",\n label: \"WhatsApp\",\n icon: IconBrandWhatsapp,\n description:\n \"Receive WhatsApp messages and reply through a Meta-managed phone number.\",\n docsUrl: \"/docs/messaging#whatsapp\",\n externalUrl: \"https://developers.facebook.com/apps\",\n externalLabel: \"Open Meta developer console\",\n envKeys: [\n \"WHATSAPP_ACCESS_TOKEN\",\n \"WHATSAPP_VERIFY_TOKEN\",\n \"WHATSAPP_PHONE_NUMBER_ID\",\n ],\n setupSteps: [\n \"Create a Meta app and add the WhatsApp product.\",\n \"Save the access token, verify token, and phone number ID below.\",\n \"In Meta's WhatsApp configuration, paste the webhook URL and your verify token.\",\n \"Subscribe to the messages field, then enable here.\",\n ],\n },\n];\n\nfunction HelpTooltip({ content }: { content: string }) {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n className=\"text-muted-foreground/60 hover:text-foreground cursor-pointer\"\n >\n <IconInfoCircle className=\"h-3.5 w-3.5\" />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"top\" className=\"max-w-64 text-xs leading-relaxed\">\n {content}\n </TooltipContent>\n </Tooltip>\n );\n}\n\nfunction StatusPill({\n tone,\n label,\n}: {\n tone: \"neutral\" | \"success\" | \"warning\";\n label: string;\n}) {\n const toneClass =\n tone === \"success\"\n ? \"border-emerald-500/30 bg-emerald-500/10 text-emerald-300\"\n : tone === \"warning\"\n ? \"border-amber-500/30 bg-amber-500/10 text-amber-300\"\n : \"border-border bg-muted/40 text-muted-foreground\";\n\n return (\n <span\n className={`inline-flex items-center rounded-full border px-2.5 py-1 text-[11px] font-medium ${toneClass}`}\n >\n {label}\n </span>\n );\n}\n\n/** Render a non-secret env value (e.g. EMAIL_AGENT_ADDRESS) as a copyable\n * text block. We can't read the actual value from the backend (env-status\n * only reports `configured: true|false`), so we offer a one-click reveal\n * that hits a server endpoint, falling back to \"saved\" if the value is\n * not exposed. For now we just render a \"Saved — re-enter to change\"\n * placeholder; a future endpoint can return the actual value. */\nfunction PublicValueReveal({ envKey: _envKey }: { envKey: string }) {\n return (\n <div className=\"rounded-md border bg-muted/20 px-3 py-2 text-xs text-muted-foreground\">\n Saved. Re-enter below to change.\n </div>\n );\n}\n\nfunction ConnectionStatus({\n configured,\n enabled,\n}: {\n configured: boolean;\n enabled: boolean;\n}) {\n if (enabled) {\n return <StatusPill tone=\"success\" label=\"Connected\" />;\n }\n if (configured) {\n return <StatusPill tone=\"warning\" label=\"Configured, not enabled\" />;\n }\n return <StatusPill tone=\"neutral\" label=\"Not configured\" />;\n}\n\nexport function MessagingSetupPanel() {\n const [statuses, setStatuses] = useState<IntegrationStatus[]>([]);\n const [loading, setLoading] = useState(true);\n const [envStatuses, setEnvStatuses] = useState<EnvStatus[]>([]);\n const [envLoading, setEnvLoading] = useState(true);\n const [envValues, setEnvValues] = useState<Record<string, string>>({});\n const [savingKeysFor, setSavingKeysFor] = useState<string | null>(null);\n const [togglingPlatform, setTogglingPlatform] = useState<string | null>(null);\n const [setupPlatform, setSetupPlatform] = useState<string | null>(null);\n const [copiedWebhook, setCopiedWebhook] = useState<string | null>(null);\n\n const refreshStatuses = async () => {\n setLoading(true);\n try {\n const res = await fetch(\n agentNativePath(\"/_agent-native/integrations/status\"),\n );\n const rows = res.ok ? await res.json() : [];\n setStatuses(Array.isArray(rows) ? rows : []);\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n let active = true;\n fetch(agentNativePath(\"/_agent-native/integrations/status\"))\n .then((res) => (res.ok ? res.json() : []))\n .then((rows) => {\n if (active) {\n setStatuses(Array.isArray(rows) ? rows : []);\n setLoading(false);\n }\n })\n .catch(() => {\n if (active) setLoading(false);\n });\n return () => {\n active = false;\n };\n }, []);\n\n useEffect(() => {\n let active = true;\n fetch(agentNativePath(\"/_agent-native/env-status\"))\n .then((res) => (res.ok ? res.json() : []))\n .then((rows) => {\n if (active) {\n setEnvStatuses(Array.isArray(rows) ? rows : []);\n setEnvLoading(false);\n }\n })\n .catch(() => {\n if (active) setEnvLoading(false);\n });\n return () => {\n active = false;\n };\n }, []);\n\n const envStatusByKey = useMemo(\n () => new Map(envStatuses.map((status) => [status.key, status])),\n [envStatuses],\n );\n const statusByPlatform = useMemo(\n () => new Map(statuses.map((status) => [status.platform, status])),\n [statuses],\n );\n\n const refreshEnvStatus = async () => {\n setEnvLoading(true);\n try {\n const res = await fetch(agentNativePath(\"/_agent-native/env-status\"));\n const rows = res.ok ? await res.json() : [];\n setEnvStatuses(Array.isArray(rows) ? rows : []);\n } finally {\n setEnvLoading(false);\n }\n };\n\n const saveEnvKeys = async (platform: PlatformDefinition, keys: string[]) => {\n const vars = keys\n .map((key) => ({ key, value: envValues[key]?.trim() || \"\" }))\n .filter((item) => item.value);\n\n if (vars.length === 0) {\n toast.error(\"Add the required credentials first.\");\n return;\n }\n\n setSavingKeysFor(platform.id);\n try {\n const res = await fetch(agentNativePath(\"/_agent-native/env-vars\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ vars }),\n });\n\n if (!res.ok) {\n const payload = await res.json().catch(() => ({}));\n throw new Error(payload.error || \"Failed to save credentials\");\n }\n\n toast.success(`${platform.label} credentials saved`);\n setEnvValues((current) => {\n const next = { ...current };\n for (const key of keys) delete next[key];\n return next;\n });\n await refreshEnvStatus();\n await refreshStatuses();\n } catch (error) {\n toast.error(\n error instanceof Error ? error.message : \"Failed to save credentials\",\n );\n } finally {\n setSavingKeysFor(null);\n }\n };\n\n const togglePlatform = async (\n platform: PlatformDefinition,\n enabled: boolean,\n ) => {\n setTogglingPlatform(platform.id);\n try {\n const action = enabled ? \"disable\" : \"enable\";\n const res = await fetch(\n agentNativePath(`/_agent-native/integrations/${platform.id}/${action}`),\n {\n method: \"POST\",\n },\n );\n if (!res.ok) {\n const payload = await res.json().catch(() => ({}));\n throw new Error(\n payload.error || `Failed to ${action} ${platform.label}`,\n );\n }\n toast.success(\n enabled\n ? `${platform.label} disconnected`\n : `${platform.label} connected`,\n );\n await refreshStatuses();\n } catch (error) {\n toast.error(\n error instanceof Error ? error.message : \"Failed to update integration\",\n );\n } finally {\n setTogglingPlatform(null);\n }\n };\n\n const runSetup = async (platform: PlatformDefinition) => {\n setSetupPlatform(platform.id);\n try {\n const res = await fetch(\n agentNativePath(`/_agent-native/integrations/${platform.id}/setup`),\n {\n method: \"POST\",\n },\n );\n if (!res.ok) {\n const payload = await res.json().catch(() => ({}));\n throw new Error(payload.error || `Failed to set up ${platform.label}`);\n }\n toast.success(\n platform.id === \"telegram\"\n ? \"Telegram webhook registered\"\n : `${platform.label} setup complete`,\n );\n await refreshStatuses();\n } catch (error) {\n toast.error(\n error instanceof Error\n ? error.message\n : `Failed to set up ${platform.label}`,\n );\n } finally {\n setSetupPlatform(null);\n }\n };\n\n const copyWebhook = async (webhookUrl: string) => {\n await navigator.clipboard.writeText(webhookUrl);\n setCopiedWebhook(webhookUrl);\n toast.success(\"Webhook URL copied\");\n setTimeout(() => setCopiedWebhook(null), 1500);\n };\n\n return (\n <div className=\"space-y-4\">\n <div className=\"grid gap-4 xl:grid-cols-2\">\n {PLATFORM_DEFINITIONS.map((platform) => {\n const status = statusByPlatform.get(platform.id);\n const configured = !!status?.configured;\n const enabled = !!status?.enabled;\n // Prefer adapter-supplied env keys (includes optional fields like\n // webhook secrets); fall back to the static list.\n const adapterKeys = status?.requiredEnvKeys;\n const envKeys: RequiredEnvKey[] =\n adapterKeys && adapterKeys.length > 0\n ? adapterKeys\n : platform.envKeys.map((key) => ({\n key,\n label: key,\n required: true,\n }));\n\n return (\n <section\n key={platform.id}\n className=\"rounded-2xl border bg-card p-5\"\n >\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"flex items-start gap-3\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-xl border bg-muted/30 text-foreground\">\n <platform.icon size={18} />\n </div>\n <div>\n <div className=\"flex items-center gap-2\">\n <h3 className=\"text-base font-semibold text-foreground\">\n {platform.label}\n </h3>\n <ConnectionStatus\n configured={configured}\n enabled={enabled}\n />\n </div>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {platform.description}\n </p>\n </div>\n </div>\n <div className=\"flex shrink-0 items-center gap-1\">\n <Button\n asChild\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 px-2 text-xs text-muted-foreground\"\n >\n <a href={platform.docsUrl} target=\"_blank\" rel=\"noreferrer\">\n Docs\n <IconExternalLink className=\"ml-1 h-3 w-3\" />\n </a>\n </Button>\n {platform.externalUrl ? (\n <Button\n asChild\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 px-2 text-xs text-muted-foreground\"\n >\n <a\n href={platform.externalUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {platform.externalLabel ?? \"Open\"}\n <IconExternalLink className=\"ml-1 h-3 w-3\" />\n </a>\n </Button>\n ) : null}\n </div>\n </div>\n\n <Collapsible className=\"mt-5\">\n <CollapsibleTrigger className=\"group flex w-full cursor-pointer items-center gap-1.5 text-xs font-medium text-muted-foreground hover:text-foreground\">\n <IconChevronRight className=\"h-3.5 w-3.5 transition-transform group-data-[state=open]:rotate-90\" />\n <span>Setup steps</span>\n </CollapsibleTrigger>\n <CollapsibleContent>\n <div className=\"mt-2 rounded-xl border bg-muted/20 p-4\">\n <ol className=\"space-y-2 text-sm text-muted-foreground\">\n {platform.setupSteps.map((step, index) => (\n <li key={step} className=\"flex gap-2\">\n <span className=\"text-muted-foreground/60\">\n {index + 1}.\n </span>\n <span>{step}</span>\n </li>\n ))}\n </ol>\n </div>\n </CollapsibleContent>\n </Collapsible>\n\n <div className=\"mt-4 space-y-3\">\n <div className=\"flex items-center gap-2\">\n <div className=\"text-sm font-medium text-foreground\">\n Credentials\n </div>\n {envLoading ? (\n <span className=\"text-xs text-muted-foreground\">\n Checking...\n </span>\n ) : null}\n </div>\n <div className=\"space-y-3\">\n {envKeys.map((envKey) => {\n const envStatus = envStatusByKey.get(envKey.key);\n const isConfigured = !!envStatus?.configured;\n const helpText = envKey.helpText ?? envStatus?.helpText;\n const label =\n envKey.label || envStatus?.label || envKey.key;\n // Email agent address is not a secret — show it plainly\n // so users can copy and share it.\n const isPublicValue = envKey.key === \"EMAIL_AGENT_ADDRESS\";\n return (\n <div key={envKey.key} className=\"space-y-1.5\">\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"flex items-center gap-1.5\">\n <label className=\"text-xs font-medium text-foreground\">\n {label}\n {!envKey.required ? (\n <span className=\"ml-1 text-muted-foreground\">\n (optional)\n </span>\n ) : null}\n </label>\n {helpText ? (\n <HelpTooltip content={helpText} />\n ) : null}\n </div>\n {isConfigured ? (\n <StatusPill tone=\"success\" label=\"Saved\" />\n ) : (\n <StatusPill\n tone={envKey.required ? \"neutral\" : \"neutral\"}\n label={envKey.required ? \"Missing\" : \"Not set\"}\n />\n )}\n </div>\n {isConfigured && isPublicValue ? (\n <PublicValueReveal envKey={envKey.key} />\n ) : !isConfigured ? (\n <Input\n type={isPublicValue ? \"text\" : \"password\"}\n value={envValues[envKey.key] || \"\"}\n onChange={(event) =>\n setEnvValues((current) => ({\n ...current,\n [envKey.key]: event.target.value,\n }))\n }\n placeholder={\n isPublicValue\n ? \"agent@yourcompany.com\"\n : `Enter ${label}`\n }\n autoComplete=\"off\"\n />\n ) : null}\n </div>\n );\n })}\n </div>\n {envKeys.some((k) => !envStatusByKey.get(k.key)?.configured) ? (\n <Button\n variant=\"outline\"\n onClick={() =>\n saveEnvKeys(\n platform,\n envKeys.map((k) => k.key),\n )\n }\n disabled={savingKeysFor === platform.id}\n >\n {savingKeysFor === platform.id ? (\n <>\n <IconLoader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n Saving...\n </>\n ) : (\n \"Save credentials\"\n )}\n </Button>\n ) : null}\n </div>\n\n {status?.webhookUrl ? (\n <div className=\"mt-4 space-y-2\">\n <div className=\"text-sm font-medium text-foreground\">\n Webhook URL\n </div>\n <div className=\"flex items-center gap-2\">\n <code className=\"flex-1 truncate rounded-md border bg-muted/30 px-3 py-2 text-xs text-foreground\">\n {status.webhookUrl}\n </code>\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => copyWebhook(status.webhookUrl!)}\n aria-label={`Copy ${platform.label} webhook URL`}\n >\n {copiedWebhook === status.webhookUrl ? (\n <IconCheck className=\"h-4 w-4\" />\n ) : (\n <IconCopy className=\"h-4 w-4\" />\n )}\n </Button>\n </div>\n </div>\n ) : null}\n\n <div className=\"mt-5 flex flex-wrap items-center justify-end gap-2 border-t border-border pt-4\">\n {platform.id === \"telegram\" && configured ? (\n <Button\n variant=\"outline\"\n onClick={() => runSetup(platform)}\n disabled={setupPlatform === platform.id}\n >\n {setupPlatform === platform.id ? (\n <>\n <IconLoader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n Setting up...\n </>\n ) : (\n \"Set up webhook\"\n )}\n </Button>\n ) : null}\n {!configured && !enabled ? (\n <Tooltip>\n <TooltipTrigger asChild>\n <span tabIndex={0}>\n <Button disabled>Enable</Button>\n </span>\n </TooltipTrigger>\n <TooltipContent>\n Save the required credentials first.\n </TooltipContent>\n </Tooltip>\n ) : (\n <Button\n onClick={() => togglePlatform(platform, enabled)}\n disabled={togglingPlatform === platform.id}\n >\n {togglingPlatform === platform.id ? (\n <>\n <IconLoader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n Saving...\n </>\n ) : enabled ? (\n \"Disable\"\n ) : (\n \"Enable\"\n )}\n </Button>\n )}\n </div>\n </section>\n );\n })}\n </div>\n\n {loading ? (\n <div className=\"rounded-2xl border border-dashed px-4 py-6 text-sm text-muted-foreground\">\n Loading messaging status...\n </div>\n ) : null}\n </div>\n );\n}\n"]}
|
|
@@ -1,5 +1,24 @@
|
|
|
1
|
-
|
|
1
|
+
import { type LoaderFunctionArgs } from "react-router";
|
|
2
|
+
export declare function loader({ request }: LoaderFunctionArgs): Promise<{
|
|
3
|
+
threadPreview: import("../../server/lib/thread-link-preview.js").ThreadLinkPreview;
|
|
4
|
+
}>;
|
|
5
|
+
export declare function meta({ data }: {
|
|
6
|
+
data?: Awaited<ReturnType<typeof loader>>;
|
|
7
|
+
}): ({
|
|
2
8
|
title: string;
|
|
3
|
-
|
|
9
|
+
name?: undefined;
|
|
10
|
+
content?: undefined;
|
|
11
|
+
property?: undefined;
|
|
12
|
+
} | {
|
|
13
|
+
name: string;
|
|
14
|
+
content: string;
|
|
15
|
+
title?: undefined;
|
|
16
|
+
property?: undefined;
|
|
17
|
+
} | {
|
|
18
|
+
property: string;
|
|
19
|
+
content: string;
|
|
20
|
+
title?: undefined;
|
|
21
|
+
name?: undefined;
|
|
22
|
+
})[];
|
|
4
23
|
export default function ChatRoute(): import("react/jsx-runtime").JSX.Element;
|
|
5
24
|
//# sourceMappingURL=chat.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/chat.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/chat.tsx"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,cAAc,CAAC;AAoBtB,wBAAsB,MAAM,CAAC,EAAE,OAAO,EAAE,EAAE,kBAAkB;;GAK3D;AAED,wBAAgB,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC,CAAA;CAAE;;;;;;;;;;;;;;;KAI3E;AAED,MAAM,CAAC,OAAO,UAAU,SAAS,4CA6EhC"}
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useRef } from "react";
|
|
3
|
-
import { useLocation, useNavigate } from "react-router";
|
|
3
|
+
import { useLocation, useNavigate, } from "react-router";
|
|
4
4
|
import { AgentChatSurface } from "@agent-native/core/client";
|
|
5
5
|
import { submitOverviewPrompt } from "../../lib/overview-chat.js";
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
import { buildThreadLinkPreviewMeta, loadThreadLinkPreview, } from "../../server/lib/thread-link-preview.js";
|
|
7
|
+
export async function loader({ request }) {
|
|
8
|
+
const threadId = new URL(request.url).searchParams.get("thread");
|
|
9
|
+
return {
|
|
10
|
+
threadPreview: await loadThreadLinkPreview(threadId),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export function meta({ data }) {
|
|
14
|
+
return data?.threadPreview
|
|
15
|
+
? buildThreadLinkPreviewMeta(data.threadPreview)
|
|
16
|
+
: [{ title: "Chat — Dispatch" }];
|
|
8
17
|
}
|
|
9
18
|
export default function ChatRoute() {
|
|
10
19
|
const location = useLocation();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.js","sourceRoot":"","sources":["../../../src/routes/pages/chat.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,
|
|
1
|
+
{"version":3,"file":"chat.js","sourceRoot":"","sources":["../../../src/routes/pages/chat.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useRef } from \"react\";\nimport {\n useLocation,\n useNavigate,\n type LoaderFunctionArgs,\n} from \"react-router\";\nimport { AgentChatSurface } from \"@agent-native/core/client\";\nimport { submitOverviewPrompt } from \"@/lib/overview-chat\";\nimport {\n buildThreadLinkPreviewMeta,\n loadThreadLinkPreview,\n} from \"@/server/lib/thread-link-preview\";\n\ninterface DispatchChatLocationState {\n dispatchPrompt?: {\n id?: string | number;\n message?: string;\n selectedModel?: string | null;\n };\n dispatchThread?: {\n id?: string | number;\n threadId?: string;\n };\n}\n\nexport async function loader({ request }: LoaderFunctionArgs) {\n const threadId = new URL(request.url).searchParams.get(\"thread\");\n return {\n threadPreview: await loadThreadLinkPreview(threadId),\n };\n}\n\nexport function meta({ data }: { data?: Awaited<ReturnType<typeof loader>> }) {\n return data?.threadPreview\n ? buildThreadLinkPreviewMeta(data.threadPreview)\n : [{ title: \"Chat — Dispatch\" }];\n}\n\nexport default function ChatRoute() {\n const location = useLocation();\n const navigate = useNavigate();\n const handledStateIds = useRef(new Set<string>());\n const state = location.state as DispatchChatLocationState | null;\n const prompt = state?.dispatchPrompt;\n const thread = state?.dispatchThread;\n\n useEffect(() => {\n const message = prompt?.message?.trim();\n const threadId = thread?.threadId?.trim();\n if (!message && !threadId) return;\n\n const stateId = String(\n prompt?.id ?? thread?.id ?? `${message ?? \"\"}:${threadId ?? \"\"}`,\n );\n if (handledStateIds.current.has(stateId)) return;\n handledStateIds.current.add(stateId);\n\n const timer = window.setTimeout(() => {\n if (threadId) {\n window.dispatchEvent(\n new CustomEvent(\"agent-chat:open-thread\", {\n detail: { threadId },\n }),\n );\n }\n if (message) {\n submitOverviewPrompt(message, prompt?.selectedModel, {\n openSidebar: false,\n });\n }\n navigate(`${location.pathname}${location.search}${location.hash}`, {\n replace: true,\n state: null,\n });\n }, 0);\n\n return () => window.clearTimeout(timer);\n }, [\n location.hash,\n location.pathname,\n location.search,\n navigate,\n prompt?.id,\n prompt?.message,\n prompt?.selectedModel,\n thread?.id,\n thread?.threadId,\n ]);\n\n return (\n <div className=\"flex h-full min-h-0 flex-col bg-background\">\n <AgentChatSurface\n mode=\"page\"\n className=\"dispatch-chat-panel\"\n defaultMode=\"chat\"\n showHeader={false}\n showTabBar={false}\n dynamicSuggestions={false}\n suggestions={[]}\n emptyStateText=\"Ask Dispatch to create apps, route work, or manage the workspace.\"\n emptyStateDisplay=\"hidden\"\n centerComposerWhenEmpty\n composerLayoutVariant=\"hero\"\n composerPlaceholder=\"Ask Dispatch...\"\n composerSlot={\n <div className=\"dispatch-chat-intro\">\n <h1>What should Dispatch do next?</h1>\n <p>\n Create apps, manage shared keys, and route work across agents.\n </p>\n </div>\n }\n />\n </div>\n );\n}\n"]}
|
|
@@ -1,5 +1,24 @@
|
|
|
1
|
-
|
|
1
|
+
import { type LoaderFunctionArgs } from "react-router";
|
|
2
|
+
export declare function loader({ request }: LoaderFunctionArgs): Promise<{
|
|
3
|
+
threadPreview: import("../../server/lib/thread-link-preview.js").ThreadLinkPreview;
|
|
4
|
+
}>;
|
|
5
|
+
export declare function meta({ data }: {
|
|
6
|
+
data?: Awaited<ReturnType<typeof loader>>;
|
|
7
|
+
}): ({
|
|
2
8
|
title: string;
|
|
3
|
-
|
|
9
|
+
name?: undefined;
|
|
10
|
+
content?: undefined;
|
|
11
|
+
property?: undefined;
|
|
12
|
+
} | {
|
|
13
|
+
name: string;
|
|
14
|
+
content: string;
|
|
15
|
+
title?: undefined;
|
|
16
|
+
property?: undefined;
|
|
17
|
+
} | {
|
|
18
|
+
property: string;
|
|
19
|
+
content: string;
|
|
20
|
+
title?: undefined;
|
|
21
|
+
name?: undefined;
|
|
22
|
+
})[];
|
|
4
23
|
export default function OverviewRoute(): import("react/jsx-runtime").JSX.Element;
|
|
5
24
|
//# sourceMappingURL=overview.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overview.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/overview.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"overview.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/overview.tsx"],"names":[],"mappings":"AACA,OAAO,EAAqB,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAC;AA4d1E,wBAAsB,MAAM,CAAC,EAAE,OAAO,EAAE,EAAE,kBAAkB;;GAK3D;AAED,wBAAgB,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC,CAAA;CAAE;;;;;;;;;;;;;;;KAI3E;AAED,MAAM,CAAC,OAAO,UAAU,aAAa,4CA4RpC"}
|
|
@@ -11,6 +11,7 @@ import { Button } from "../../components/ui/button.js";
|
|
|
11
11
|
import { Skeleton } from "../../components/ui/skeleton.js";
|
|
12
12
|
import { Tooltip, TooltipContent, TooltipTrigger, } from "../../components/ui/tooltip.js";
|
|
13
13
|
import { submitOverviewPrompt } from "../../lib/overview-chat.js";
|
|
14
|
+
import { buildThreadLinkPreviewMeta, loadThreadLinkPreview, } from "../../server/lib/thread-link-preview.js";
|
|
14
15
|
const ZERO_TASK_QUEUE_STATS = {
|
|
15
16
|
pending: 0,
|
|
16
17
|
processing: 0,
|
|
@@ -96,14 +97,22 @@ function HelpTooltip({ content }) {
|
|
|
96
97
|
return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", className: "text-muted-foreground/60 hover:text-foreground cursor-pointer", children: _jsx(IconInfoCircle, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { side: "top", className: "max-w-64 text-xs leading-relaxed", children: content })] }));
|
|
97
98
|
}
|
|
98
99
|
function StatCard({ label, help, value, icon: Icon, cta, }) {
|
|
99
|
-
return (_jsxs("div", { className: "rounded-2xl border bg-card p-5", children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "flex items-center gap-1.5 text-sm font-medium text-foreground", children: [_jsx("span", { children: label }), _jsx(HelpTooltip, { content: help })] }), _jsx("div", { className: "mt-3 text-3xl font-semibold text-foreground", children: value })] }), _jsx("div", { className: "rounded-xl border bg-muted/30 p-3 text-muted-foreground", children: _jsx(Icon, { size: 18 }) })] }), cta ? _jsx("div", { className: "mt-4", children: cta }) : null] }));
|
|
100
|
+
return (_jsxs("div", { className: "min-w-0 rounded-2xl border bg-card p-5", children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "flex items-center gap-1.5 text-sm font-medium leading-snug text-foreground", children: [_jsx("span", { className: "min-w-0", children: label }), _jsx(HelpTooltip, { content: help })] }), _jsx("div", { className: "mt-3 text-3xl font-semibold text-foreground", children: value })] }), _jsx("div", { className: "shrink-0 rounded-xl border bg-muted/30 p-3 text-muted-foreground", children: _jsx(Icon, { size: 18 }) })] }), cta ? _jsx("div", { className: "mt-4", children: cta }) : null] }));
|
|
100
101
|
}
|
|
101
102
|
function StepRow({ step }) {
|
|
102
103
|
const done = step.complete && !step.informational;
|
|
103
104
|
return (_jsxs("div", { className: `flex items-start gap-4 rounded-xl border px-5 py-4 ${done ? "border-border/50 bg-muted/20" : "bg-card"}`, children: [_jsx("div", { className: "flex-none pt-0.5", children: done ? (_jsx("div", { className: "flex h-7 w-7 items-center justify-center rounded-full bg-emerald-500/15 text-emerald-600 dark:text-emerald-400", children: _jsx(IconCheck, { size: 16, strokeWidth: 2.5 }) })) : (_jsx("div", { className: "flex h-7 w-7 items-center justify-center rounded-full border border-muted-foreground/30 text-muted-foreground", children: _jsx(IconListCheck, { size: 15 }) })) }), _jsxs("div", { className: `min-w-0 flex-1 ${done ? "opacity-50" : ""}`, children: [_jsx("div", { className: `text-sm font-semibold ${done ? "line-through decoration-muted-foreground/40" : "text-foreground"}`, children: step.title }), _jsx("p", { className: "mt-0.5 text-sm leading-relaxed text-muted-foreground", children: step.description })] }), step.to && !done && (_jsx("div", { className: "flex-none pt-0.5", children: _jsx(Button, { variant: "outline", size: "sm", asChild: true, children: _jsx(Link, { to: step.to, children: step.actionLabel || "Set up" }) }) }))] }));
|
|
104
105
|
}
|
|
105
|
-
export function
|
|
106
|
-
|
|
106
|
+
export async function loader({ request }) {
|
|
107
|
+
const threadId = new URL(request.url).searchParams.get("thread");
|
|
108
|
+
return {
|
|
109
|
+
threadPreview: await loadThreadLinkPreview(threadId),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
export function meta({ data }) {
|
|
113
|
+
return data?.threadPreview
|
|
114
|
+
? buildThreadLinkPreviewMeta(data.threadPreview)
|
|
115
|
+
: [{ title: "Overview — Dispatch" }];
|
|
107
116
|
}
|
|
108
117
|
export default function OverviewRoute() {
|
|
109
118
|
const { data, isLoading } = useActionQuery("list-dispatch-overview", {});
|
|
@@ -208,7 +217,7 @@ export default function OverviewRoute() {
|
|
|
208
217
|
},
|
|
209
218
|
];
|
|
210
219
|
const hasIncompleteSteps = steps.some((s) => !s.complete && !s.informational);
|
|
211
|
-
return (_jsxs(DispatchShell, { title: "Overview", description: "Create apps, manage shared keys, and route work across your workspace.", children: [_jsx(HomeChatPanel, {}), _jsx(WorkspaceAppsSection, { apps: typedWorkspaceApps, isLoading: appsLoading }), hasIncompleteSteps && (_jsxs("section", { className: "space-y-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(IconRocket, { size: 16, className: "text-muted-foreground" }), _jsx("h2", { className: "text-sm font-semibold text-foreground", children: "Getting started" })] }), _jsx("div", { className: "space-y-2", children: steps.map((step) => (_jsx(StepRow, { step: step }, step.number))) })] })), _jsxs("section", { className: "space-y-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(IconActivity, { size: 16, className: "text-muted-foreground" }), _jsx("h2", { className: "text-sm font-semibold text-foreground", children: "At a glance" })] }), _jsxs("div", { className: "grid
|
|
220
|
+
return (_jsxs(DispatchShell, { title: "Overview", description: "Create apps, manage shared keys, and route work across your workspace.", children: [_jsx(HomeChatPanel, {}), _jsx(WorkspaceAppsSection, { apps: typedWorkspaceApps, isLoading: appsLoading }), hasIncompleteSteps && (_jsxs("section", { className: "space-y-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(IconRocket, { size: 16, className: "text-muted-foreground" }), _jsx("h2", { className: "text-sm font-semibold text-foreground", children: "Getting started" })] }), _jsx("div", { className: "space-y-2", children: steps.map((step) => (_jsx(StepRow, { step: step }, step.number))) })] })), _jsxs("section", { className: "space-y-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(IconActivity, { size: 16, className: "text-muted-foreground" }), _jsx("h2", { className: "text-sm font-semibold text-foreground", children: "At a glance" })] }), _jsxs("div", { className: "grid grid-cols-[repeat(auto-fit,minmax(min(100%,13rem),1fr))] gap-4", children: [_jsx(StatCard, { label: "Vault secrets", help: "Credentials stored in the workspace vault.", value: data?.vault?.secretCount || 0, icon: IconKey, cta: (data?.vault?.secretCount || 0) === 0 ? (_jsx(Button, { variant: "outline", size: "sm", asChild: true, children: _jsx(Link, { to: "/vault", children: "Set up vault" }) })) : undefined }), _jsx(StatCard, { label: data?.vault?.accessMode === "manual"
|
|
212
221
|
? "Active grants"
|
|
213
222
|
: "Accessible keys", help: data?.vault?.accessMode === "manual"
|
|
214
223
|
? "Secrets currently granted to apps. Sync them to push credentials."
|