@agent-native/dispatch 0.15.13 → 0.15.16

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.
@@ -6,6 +6,19 @@ declare const _default: import("@agent-native/core").ActionDefinition<{
6
6
  content: string;
7
7
  scope: "all" | "selected";
8
8
  }, {
9
+ id: string;
10
+ ownerEmail: string;
11
+ orgId: string | null;
12
+ kind: string;
13
+ name: string;
14
+ description: string | null;
15
+ path: string;
16
+ content: string;
17
+ scope: string;
18
+ createdBy: string;
19
+ createdAt: number;
20
+ updatedAt: number;
21
+ } | {
9
22
  id: string;
10
23
  ownerEmail: string;
11
24
  orgId: string | null;
@@ -22,19 +35,6 @@ declare const _default: import("@agent-native/core").ActionDefinition<{
22
35
  reviewedAt: number | null;
23
36
  createdAt: number;
24
37
  updatedAt: number;
25
- } | {
26
- id: string;
27
- ownerEmail: string;
28
- orgId: string | null;
29
- kind: string;
30
- name: string;
31
- description: string | null;
32
- path: string;
33
- content: string;
34
- scope: string;
35
- createdBy: string;
36
- createdAt: number;
37
- updatedAt: number;
38
38
  }>;
39
39
  export default _default;
40
40
  //# sourceMappingURL=create-workspace-resource.d.ts.map
@@ -1,6 +1,18 @@
1
1
  declare const _default: import("@agent-native/core").ActionDefinition<{
2
2
  id: string;
3
3
  }, {
4
+ id: string;
5
+ ownerEmail: string;
6
+ orgId: string | null;
7
+ name: string;
8
+ platform: string;
9
+ destination: string;
10
+ threadRef: string | null;
11
+ notes: string | null;
12
+ createdBy: string;
13
+ createdAt: number;
14
+ updatedAt: number;
15
+ } | {
4
16
  id: string;
5
17
  ownerEmail: string;
6
18
  orgId: string | null;
@@ -17,18 +29,6 @@ declare const _default: import("@agent-native/core").ActionDefinition<{
17
29
  reviewedAt: number | null;
18
30
  createdAt: number;
19
31
  updatedAt: number;
20
- } | {
21
- id: string;
22
- ownerEmail: string;
23
- orgId: string | null;
24
- name: string;
25
- platform: string;
26
- destination: string;
27
- threadRef: string | null;
28
- notes: string | null;
29
- createdBy: string;
30
- createdAt: number;
31
- updatedAt: number;
32
32
  }>;
33
33
  export default _default;
34
34
  //# sourceMappingURL=delete-destination.d.ts.map
@@ -1,6 +1,19 @@
1
1
  declare const _default: import("@agent-native/core").ActionDefinition<{
2
2
  id: string;
3
3
  }, {
4
+ id: string;
5
+ ownerEmail: string;
6
+ orgId: string | null;
7
+ kind: string;
8
+ name: string;
9
+ description: string | null;
10
+ path: string;
11
+ content: string;
12
+ scope: string;
13
+ createdBy: string;
14
+ createdAt: number;
15
+ updatedAt: number;
16
+ } | {
4
17
  id: string;
5
18
  ownerEmail: string;
6
19
  orgId: string | null;
@@ -17,19 +30,6 @@ declare const _default: import("@agent-native/core").ActionDefinition<{
17
30
  reviewedAt: number | null;
18
31
  createdAt: number;
19
32
  updatedAt: number;
20
- } | {
21
- id: string;
22
- ownerEmail: string;
23
- orgId: string | null;
24
- kind: string;
25
- name: string;
26
- description: string | null;
27
- path: string;
28
- content: string;
29
- scope: string;
30
- createdBy: string;
31
- createdAt: number;
32
- updatedAt: number;
33
33
  }>;
34
34
  export default _default;
35
35
  //# sourceMappingURL=delete-workspace-resource.d.ts.map
@@ -47,10 +47,9 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
47
47
  notes?: string | undefined;
48
48
  scope?: "org" | "user" | undefined;
49
49
  }, {
50
- deleted?: undefined;
51
50
  id?: undefined;
52
- provider?: undefined;
53
- found?: undefined;
51
+ message?: undefined;
52
+ deleted?: undefined;
54
53
  providers: {
55
54
  id: string;
56
55
  label: string;
@@ -61,45 +60,46 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
61
60
  updatedAt: number;
62
61
  }[];
63
62
  count: number;
63
+ provider?: undefined;
64
+ found?: undefined;
64
65
  registered?: undefined;
65
66
  label?: undefined;
66
- message?: undefined;
67
67
  } | {
68
- deleted?: undefined;
69
- count?: undefined;
70
68
  id?: undefined;
69
+ message?: undefined;
70
+ deleted?: undefined;
71
71
  providers?: undefined;
72
+ count?: undefined;
72
73
  found: boolean;
73
74
  provider: import("node_modules/@agent-native/core/dist/provider-api").CustomProviderConfig;
74
75
  registered?: undefined;
75
76
  label?: undefined;
76
- message?: undefined;
77
77
  } | {
78
+ message?: undefined;
78
79
  deleted?: undefined;
80
+ providers?: undefined;
79
81
  count?: undefined;
80
82
  provider?: undefined;
81
- providers?: undefined;
82
83
  found: boolean;
83
84
  id: string;
84
85
  registered?: undefined;
85
86
  label?: undefined;
86
- message?: undefined;
87
87
  } | {
88
+ message?: undefined;
89
+ providers?: undefined;
88
90
  count?: undefined;
89
91
  provider?: undefined;
90
92
  found?: undefined;
91
- providers?: undefined;
92
93
  deleted: boolean;
93
94
  id: string;
94
95
  registered?: undefined;
95
96
  label?: undefined;
96
- message?: undefined;
97
97
  } | {
98
98
  deleted?: undefined;
99
+ providers?: undefined;
99
100
  count?: undefined;
100
101
  provider?: undefined;
101
102
  found?: undefined;
102
- providers?: undefined;
103
103
  registered: boolean;
104
104
  id: string;
105
105
  label: string;
@@ -5,19 +5,6 @@ declare const _default: import("@agent-native/core").ActionDefinition<{
5
5
  content?: string | undefined;
6
6
  scope?: "all" | "selected" | undefined;
7
7
  }, {
8
- id: string;
9
- ownerEmail: string;
10
- orgId: string | null;
11
- kind: string;
12
- name: string;
13
- description: string | null;
14
- path: string;
15
- content: string;
16
- scope: string;
17
- createdBy: string;
18
- createdAt: number;
19
- updatedAt: number;
20
- } | {
21
8
  id: string;
22
9
  ownerEmail: string;
23
10
  orgId: string | null;
@@ -34,6 +21,19 @@ declare const _default: import("@agent-native/core").ActionDefinition<{
34
21
  reviewedAt: number | null;
35
22
  createdAt: number;
36
23
  updatedAt: number;
24
+ } | {
25
+ id: string;
26
+ ownerEmail: string;
27
+ orgId: string | null;
28
+ kind: string;
29
+ name: string;
30
+ description: string | null;
31
+ path: string;
32
+ content: string;
33
+ scope: string;
34
+ createdBy: string;
35
+ createdAt: number;
36
+ updatedAt: number;
37
37
  }>;
38
38
  export default _default;
39
39
  //# sourceMappingURL=update-workspace-resource.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"messaging-setup-panel.d.ts","sourceRoot":"","sources":["../../src/components/messaging-setup-panel.tsx"],"names":[],"mappings":"AAoKA,wBAAgB,mBAAmB,oDAs2BlC"}
1
+ {"version":3,"file":"messaging-setup-panel.d.ts","sourceRoot":"","sources":["../../src/components/messaging-setup-panel.tsx"],"names":[],"mappings":"AAyMA,wBAAgB,mBAAmB,oDA05BlC"}
@@ -5,6 +5,7 @@ import { listBuiltInChannelIntegrations, } from "@agent-native/core/integrations
5
5
  import { IconBrandDiscord, IconBrandSlack, IconBrandTelegram, IconBrandTeams, IconBrandWhatsapp, IconCheck, IconChevronRight, IconCopy, IconExternalLink, IconFileDescription, IconInfoCircle, IconLoader2, IconMail, IconPlug, } from "@tabler/icons-react";
6
6
  import { useEffect, useMemo, useState } from "react";
7
7
  import { toast } from "sonner";
8
+ import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, } from "./ui/accordion.js";
8
9
  import { Button } from "./ui/button.js";
9
10
  import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "./ui/collapsible.js";
10
11
  import { Input } from "./ui/input.js";
@@ -39,11 +40,14 @@ function HelpTooltip({ content }) {
39
40
  }
40
41
  function StatusPill({ tone, label, }) {
41
42
  const toneClass = tone === "success"
42
- ? "border-emerald-500/30 bg-emerald-500/10 text-emerald-300"
43
+ ? "bg-emerald-500/10 text-emerald-700 dark:text-emerald-300"
43
44
  : tone === "warning"
44
- ? "border-amber-500/30 bg-amber-500/10 text-amber-300"
45
- : "border-border bg-muted/40 text-muted-foreground";
46
- return (_jsx("span", { className: `inline-flex items-center rounded-full border px-2.5 py-1 text-[11px] font-medium ${toneClass}`, children: label }));
45
+ ? "bg-amber-500/10 text-amber-700 dark:text-amber-300"
46
+ : "bg-muted text-muted-foreground";
47
+ return (_jsx("span", { className: `inline-flex items-center rounded-full px-2 py-1 text-[11px] font-medium ${toneClass}`, children: label }));
48
+ }
49
+ function DisclosureSection({ title, summary, children, defaultOpen = false, }) {
50
+ return (_jsxs(Collapsible, { defaultOpen: defaultOpen, className: "border-t", children: [_jsxs(CollapsibleTrigger, { className: "group flex w-full cursor-pointer items-center justify-between gap-3 py-3 text-left", children: [_jsxs("span", { className: "min-w-0", children: [_jsx("span", { className: "block text-sm font-medium text-foreground", children: title }), summary ? (_jsx("span", { className: "mt-0.5 block truncate text-xs text-muted-foreground", children: summary })) : null] }), _jsx(IconChevronRight, { className: "h-4 w-4 shrink-0 text-muted-foreground transition-transform group-data-[state=open]:rotate-90" })] }), _jsx(CollapsibleContent, { className: "pb-3", children: children })] }));
47
51
  }
48
52
  /** Render a non-secret env value (e.g. EMAIL_AGENT_ADDRESS) as a copyable
49
53
  * text block. We can't read the actual value from the backend (env-status
@@ -305,7 +309,7 @@ export function MessagingSetupPanel() {
305
309
  setSavingScope(null);
306
310
  }
307
311
  };
308
- return (_jsxs("div", { className: "space-y-4", children: [_jsx("div", { className: "grid gap-4 xl:grid-cols-2", children: CHANNELS.map((platform) => {
312
+ return (_jsxs("div", { className: "space-y-4", children: [_jsx(Accordion, { type: "single", collapsible: true, className: "overflow-hidden rounded-2xl border bg-card", children: CHANNELS.map((platform) => {
309
313
  const status = statusByPlatform.get(platform.id);
310
314
  const configured = !!status?.configured ||
311
315
  (platform.id === "slack" &&
@@ -315,75 +319,95 @@ export function MessagingSetupPanel() {
315
319
  const primaryEnvKeys = envKeys.filter((envKey) => envKey.key !== "SLACK_BOT_TOKEN");
316
320
  const legacyEnvKeys = envKeys.filter((envKey) => envKey.key === "SLACK_BOT_TOKEN");
317
321
  const missingRequiredCredentials = hasMissingRequiredCredentials(envKeys, envStatusByKey);
322
+ const configuredCredentialCount = envKeys.filter((envKey) => envStatusByKey.get(envKey.key)?.configured).length;
323
+ const credentialSummary = envLoading
324
+ ? "Checking saved credentials"
325
+ : missingRequiredCredentials
326
+ ? "Required credentials are missing"
327
+ : `${configuredCredentialCount} saved`;
318
328
  const Icon = PLATFORM_ICONS[platform.iconKey] ?? IconPlug;
319
- 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(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.name }), _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.documentation.href, target: "_blank", rel: "noreferrer", children: ["Docs", _jsx(IconExternalLink, { className: "ml-1 h-3 w-3" })] }) }), platform.documentation.externalHref ? (_jsx(Button, { asChild: true, variant: "ghost", size: "sm", className: "h-7 px-2 text-xs text-muted-foreground", children: _jsxs("a", { href: platform.documentation.externalHref, target: "_blank", rel: "noreferrer", children: [platform.documentation.externalLabel ?? "Open", _jsx(IconExternalLink, { className: "ml-1 h-3 w-3" })] }) })) : null] })] }), platform.id === "slack" ? (_jsxs("div", { className: "mt-5 space-y-3 rounded-xl border bg-muted/20 p-4", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsxs("div", { children: [_jsx("div", { className: "text-sm font-medium text-foreground", children: t("messaging.managed.title") }), _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: t("messaging.managed.description") }), _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: t("messaging.managed.agentManifestDescription") })] }), _jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx(Button, { asChild: true, variant: "outline", size: "sm", children: _jsxs("a", { href: managedSlackAgentManifestUrl(), children: [_jsx(IconFileDescription, { className: "mr-2 h-4 w-4" }), t("messaging.managed.agentManifest")] }) }), missingRequiredCredentials ? (_jsxs(Button, { size: "sm", disabled: true, children: [_jsx(IconBrandSlack, { className: "mr-2 h-4 w-4" }), t("messaging.managed.addToSlack")] })) : (_jsx(Button, { asChild: true, size: "sm", children: _jsxs("a", { href: managedIntegrationOAuthUrl("slack"), children: [_jsx(IconBrandSlack, { className: "mr-2 h-4 w-4" }), t("messaging.managed.addToSlack")] }) }))] }), missingRequiredCredentials ? (_jsx("p", { className: "max-w-72 text-xs text-amber-700 dark:text-amber-300", children: t("messaging.managed.requiredCredentials") })) : null] })] }), installations.length ? (_jsx("div", { className: "space-y-2", children: installations.map((installation) => (_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 rounded-lg border bg-background/60 px-3 py-2", children: [_jsxs("div", { children: [_jsx("div", { className: "text-sm font-medium text-foreground", children: installation.teamName ||
320
- installation.enterpriseName ||
321
- installation.teamId ||
322
- t("messaging.managed.workspaceFallback") }), _jsx("div", { className: "mt-0.5 text-xs text-muted-foreground", children: t("messaging.managed.scopesUpdated", {
323
- count: installation.scopes.length,
324
- date: formatDate(installation.updatedAt, {
325
- dateStyle: "medium",
326
- }),
327
- }) })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(StatusPill, { tone: installation.health === "healthy"
328
- ? "success"
329
- : installation.health === "degraded" ||
330
- installation.health === "revoked"
331
- ? "warning"
332
- : "neutral", label: t(`messaging.managed.health.${installation.health}`) }), _jsx(Button, { variant: "outline", size: "sm", onClick: () => runInstallationAction(installation, "test"), disabled: installationAction === `test:${installation.id}`, children: t("messaging.managed.test") }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => runInstallationAction(installation, "disconnect"), disabled: installationAction ===
333
- `disconnect:${installation.id}`, children: t("messaging.managed.disconnect") })] })] }, installation.id))) })) : (_jsx("p", { className: "text-xs text-muted-foreground", children: t("messaging.managed.empty") }))] })) : null, platform.id === "slack" && scopes.length ? (_jsxs("div", { className: "mt-4 space-y-3 rounded-xl border bg-muted/20 p-4", children: [_jsxs("div", { children: [_jsx("div", { className: "text-sm font-medium text-foreground", children: t("messaging.managed.channelAccessTitle") }), _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: t("messaging.managed.channelAccessDescription") })] }), scopes.map((scope) => {
334
- const subjectId = JSON.stringify([
335
- scope.platform,
336
- scope.tenantId,
337
- scope.conversationId,
338
- ]);
339
- const budget = budgets.find((item) => item.subjectType === "scope" &&
340
- item.subjectId === subjectId &&
341
- item.period === "month");
342
- return (_jsxs("div", { className: "space-y-3 rounded-lg border bg-background/60 p-3", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [_jsxs("div", { children: [_jsx("div", { className: "font-mono text-xs text-foreground", children: scope.conversationId }), _jsx("div", { className: "mt-0.5 text-xs text-muted-foreground", children: t("messaging.managed.isolatedIdentity", {
343
- trust: t(`messaging.managed.trust.${scope.trust}`),
344
- }) })] }), _jsx(StatusPill, { tone: scope.trust === "trusted" ? "success" : "warning", label: t(`messaging.managed.trust.${scope.trust}`) })] }), _jsx("div", { className: "grid gap-2 sm:grid-cols-3", children: [
345
- [
346
- "requireMention",
347
- t("messaging.managed.requireMention"),
348
- ],
349
- ["allowGuests", t("messaging.managed.allowGuests")],
350
- [
351
- "allowExternalShared",
352
- t("messaging.managed.allowSlackConnect"),
353
- ],
354
- ].map(([key, label]) => (_jsxs("label", { className: "flex items-center justify-between gap-2 rounded-md border px-2.5 py-2 text-xs", children: [label, _jsx(Switch, { checked: scope.policy[key], disabled: savingScope === scope.id, onCheckedChange: (checked) => updateScopePolicy(scope, { [key]: checked }) })] }, key))) }), _jsxs("div", { className: "flex flex-wrap items-end gap-2", children: [_jsxs("div", { className: "min-w-40 flex-1 space-y-1", children: [_jsx("label", { className: "text-xs font-medium text-foreground", children: t("messaging.managed.monthlyBudgetUsd") }), _jsx(Input, { inputMode: "decimal", value: scopeBudget[scope.id] ??
355
- (budget
356
- ? String(budget.limitMicros / 1_000_000)
357
- : ""), onChange: (event) => setScopeBudget((current) => ({
329
+ return (_jsxs(AccordionItem, { value: platform.id, className: "border-b last:border-b-0", children: [_jsx(AccordionTrigger, { className: "gap-3 px-4 text-left hover:no-underline", children: _jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-3", children: [_jsx(Icon, { className: "h-5 w-5 shrink-0 text-muted-foreground" }), _jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("h3", { className: "text-base font-semibold text-foreground", children: platform.name }), _jsx(ConnectionStatus, { configured: configured, enabled: enabled })] }), _jsx("p", { className: "mt-1 truncate text-sm text-muted-foreground", children: platform.description })] })] }) }), _jsx(AccordionContent, { className: "px-4", children: _jsxs("div", { className: "border-t", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 py-3", children: [_jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium text-foreground", children: enabled
330
+ ? "Messages are flowing"
331
+ : configured
332
+ ? "Ready to connect"
333
+ : "Finish setup to connect" }), _jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: credentialSummary })] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [platform.id === "telegram" && configured ? (_jsx(Button, { variant: "outline", size: "sm", onClick: () => runSetup(platform), disabled: setupPlatform === platform.id, children: setupPlatform === platform.id ? (_jsxs(_Fragment, { children: [_jsx(IconLoader2, { className: "mr-2 h-4 w-4 animate-spin" }), "Setting up..."] })) : ("Set up webhook") })) : null, !configured && !enabled ? (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { tabIndex: 0, children: _jsx(Button, { size: "sm", disabled: true, children: "Enable" }) }) }), _jsx(TooltipContent, { children: "Save the required credentials first." })] })) : (_jsx(Button, { size: "sm", onClick: () => togglePlatform(platform, enabled), disabled: togglingPlatform === platform.id, children: togglingPlatform === platform.id ? (_jsxs(_Fragment, { children: [_jsx(IconLoader2, { className: "mr-2 h-4 w-4 animate-spin" }), "Saving..."] })) : enabled ? ("Disable") : ("Enable") }))] })] }), platform.id === "slack" ? (_jsx(DisclosureSection, { title: t("messaging.managed.title"), summary: installations.length
334
+ ? `${installations.length} connected`
335
+ : "No workspaces connected yet", children: _jsxs("div", { className: "space-y-3", children: [_jsxs("p", { className: "text-xs text-muted-foreground", children: [t("messaging.managed.description"), " ", t("messaging.managed.agentManifestDescription")] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx(Button, { asChild: true, variant: "outline", size: "sm", children: _jsxs("a", { href: managedSlackAgentManifestUrl(), children: [_jsx(IconFileDescription, { className: "mr-2 h-4 w-4" }), t("messaging.managed.agentManifest")] }) }), missingRequiredCredentials ? (_jsxs(Button, { size: "sm", disabled: true, children: [_jsx(IconBrandSlack, { className: "mr-2 h-4 w-4" }), t("messaging.managed.addToSlack")] })) : (_jsx(Button, { asChild: true, size: "sm", children: _jsxs("a", { href: managedIntegrationOAuthUrl("slack"), children: [_jsx(IconBrandSlack, { className: "mr-2 h-4 w-4" }), t("messaging.managed.addToSlack")] }) }))] }), missingRequiredCredentials ? (_jsx("p", { className: "text-xs text-amber-700 dark:text-amber-300", children: t("messaging.managed.requiredCredentials") })) : null, installations.length ? (_jsx("div", { className: "divide-y rounded-lg bg-muted/20 px-3", children: installations.map((installation) => (_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 py-3", children: [_jsxs("div", { children: [_jsx("div", { className: "text-sm font-medium text-foreground", children: installation.teamName ||
336
+ installation.enterpriseName ||
337
+ installation.teamId ||
338
+ t("messaging.managed.workspaceFallback") }), _jsx("div", { className: "mt-0.5 text-xs text-muted-foreground", children: t("messaging.managed.scopesUpdated", {
339
+ count: installation.scopes.length,
340
+ date: formatDate(installation.updatedAt, {
341
+ dateStyle: "medium",
342
+ }),
343
+ }) })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(StatusPill, { tone: installation.health === "healthy"
344
+ ? "success"
345
+ : installation.health === "degraded" ||
346
+ installation.health === "revoked"
347
+ ? "warning"
348
+ : "neutral", label: t(`messaging.managed.health.${installation.health}`) }), _jsx(Button, { variant: "outline", size: "sm", onClick: () => runInstallationAction(installation, "test"), disabled: installationAction ===
349
+ `test:${installation.id}`, children: t("messaging.managed.test") }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => runInstallationAction(installation, "disconnect"), disabled: installationAction ===
350
+ `disconnect:${installation.id}`, children: t("messaging.managed.disconnect") })] })] }, installation.id))) })) : (_jsx("p", { className: "text-xs text-muted-foreground", children: t("messaging.managed.empty") }))] }) })) : null, platform.id === "slack" && scopes.length ? (_jsx(DisclosureSection, { title: t("messaging.managed.channelAccessTitle"), summary: `${scopes.length} channel${scopes.length === 1 ? "" : "s"}`, children: _jsxs("div", { className: "space-y-3", children: [_jsx("p", { className: "text-xs text-muted-foreground", children: t("messaging.managed.channelAccessDescription") }), scopes.map((scope) => {
351
+ const subjectId = JSON.stringify([
352
+ scope.platform,
353
+ scope.tenantId,
354
+ scope.conversationId,
355
+ ]);
356
+ const budget = budgets.find((item) => item.subjectType === "scope" &&
357
+ item.subjectId === subjectId &&
358
+ item.period === "month");
359
+ return (_jsxs(Collapsible, { className: "border-b last:border-b-0", children: [_jsxs(CollapsibleTrigger, { className: "group flex w-full cursor-pointer items-center justify-between gap-3 py-3 text-left", children: [_jsxs("span", { className: "min-w-0", children: [_jsx("span", { className: "block truncate font-mono text-xs text-foreground", children: scope.conversationId }), _jsx("span", { className: "mt-0.5 block text-xs text-muted-foreground", children: t("messaging.managed.isolatedIdentity", {
360
+ trust: t(`messaging.managed.trust.${scope.trust}`),
361
+ }) })] }), _jsxs("span", { className: "flex shrink-0 items-center gap-2", children: [_jsx(StatusPill, { tone: scope.trust === "trusted"
362
+ ? "success"
363
+ : "warning", label: t(`messaging.managed.trust.${scope.trust}`) }), _jsx(IconChevronRight, { className: "h-4 w-4 text-muted-foreground transition-transform group-data-[state=open]:rotate-90" })] })] }), _jsxs(CollapsibleContent, { className: "pb-3", children: [_jsx("div", { className: "grid gap-2 sm:grid-cols-3", children: [
364
+ [
365
+ "requireMention",
366
+ t("messaging.managed.requireMention"),
367
+ ],
368
+ [
369
+ "allowGuests",
370
+ t("messaging.managed.allowGuests"),
371
+ ],
372
+ [
373
+ "allowExternalShared",
374
+ t("messaging.managed.allowSlackConnect"),
375
+ ],
376
+ ].map(([key, label]) => (_jsxs("label", { className: "flex items-center justify-between gap-2 rounded-md border px-2.5 py-2 text-xs", children: [label, _jsx(Switch, { checked: scope.policy[key], disabled: savingScope === scope.id, onCheckedChange: (checked) => updateScopePolicy(scope, {
377
+ [key]: checked,
378
+ }) })] }, key))) }), _jsxs("div", { className: "flex flex-wrap items-end gap-2", children: [_jsxs("div", { className: "min-w-40 flex-1 space-y-1", children: [_jsx("label", { className: "text-xs font-medium text-foreground", children: t("messaging.managed.monthlyBudgetUsd") }), _jsx(Input, { inputMode: "decimal", value: scopeBudget[scope.id] ??
379
+ (budget
380
+ ? String(budget.limitMicros / 1_000_000)
381
+ : ""), onChange: (event) => setScopeBudget((current) => ({
382
+ ...current,
383
+ [scope.id]: event.target.value,
384
+ })), placeholder: "25" })] }), _jsx(Button, { variant: "outline", onClick: () => saveScopeBudget(scope), disabled: savingScope === `budget:${scope.id}`, children: t("messaging.managed.saveBudget") })] })] })] }, scope.id));
385
+ })] }) })) : null, _jsx(DisclosureSection, { title: "Setup steps", summary: `${platform.setup.steps.length} step${platform.setup.steps.length === 1 ? "" : "s"}`, children: _jsx("ol", { className: "space-y-2 rounded-lg bg-muted/20 px-3 py-3 text-sm text-muted-foreground", children: platform.setup.steps.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(DisclosureSection, { title: "Credentials", summary: credentialSummary, children: [_jsx("div", { className: "space-y-3", children: primaryEnvKeys.map((envKey) => {
386
+ const envStatus = envStatusByKey.get(envKey.key);
387
+ const isConfigured = !!envStatus?.configured;
388
+ const helpText = envKey.helpText ?? envStatus?.helpText;
389
+ const label = envKey.label || envStatus?.label || envKey.key;
390
+ // Email agent address is not a secret — show it plainly
391
+ // so users can copy and share it.
392
+ const isPublicValue = envKey.key === "EMAIL_AGENT_ADDRESS";
393
+ return (_jsxs("div", { className: "space-y-1.5", children: [_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsxs("label", { className: "text-xs font-medium text-foreground", children: [label, !envKey.required ? (_jsx("span", { className: "ml-1 text-muted-foreground", children: "(optional)" })) : null] }), helpText ? (_jsx(HelpTooltip, { content: helpText })) : null] }), isConfigured ? (_jsx(StatusPill, { tone: "success", label: "Saved" })) : (_jsx(StatusPill, { tone: "neutral", label: envKey.required ? "Missing" : "Not set" }))] }), isConfigured && isPublicValue ? (_jsx(PublicValueReveal, { envKey: envKey.key })) : !isConfigured ? (_jsx(Input, { type: isPublicValue ? "text" : "password", value: envValues[envKey.key] || "", onChange: (event) => setEnvValues((current) => ({
358
394
  ...current,
359
- [scope.id]: event.target.value,
360
- })), placeholder: "25" })] }), _jsx(Button, { variant: "outline", onClick: () => saveScopeBudget(scope), disabled: savingScope === `budget:${scope.id}`, children: t("messaging.managed.saveBudget") })] })] }, scope.id));
361
- })] })) : 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.setup.steps.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: primaryEnvKeys.map((envKey) => {
362
- const envStatus = envStatusByKey.get(envKey.key);
363
- const isConfigured = !!envStatus?.configured;
364
- const helpText = envKey.helpText ?? envStatus?.helpText;
365
- const label = envKey.label || envStatus?.label || envKey.key;
366
- // Email agent address is not a secret — show it plainly
367
- // so users can copy and share it.
368
- const isPublicValue = envKey.key === "EMAIL_AGENT_ADDRESS";
369
- return (_jsxs("div", { className: "space-y-1.5", children: [_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsxs("label", { className: "text-xs font-medium text-foreground", children: [label, !envKey.required ? (_jsx("span", { className: "ml-1 text-muted-foreground", children: "(optional)" })) : null] }), helpText ? (_jsx(HelpTooltip, { content: helpText })) : null] }), isConfigured ? (_jsx(StatusPill, { tone: "success", label: "Saved" })) : (_jsx(StatusPill, { tone: "neutral", label: envKey.required ? "Missing" : "Not set" }))] }), isConfigured && isPublicValue ? (_jsx(PublicValueReveal, { envKey: envKey.key })) : !isConfigured ? (_jsx(Input, { type: isPublicValue ? "text" : "password", value: envValues[envKey.key] || "", onChange: (event) => setEnvValues((current) => ({
370
- ...current,
371
- [envKey.key]: event.target.value,
372
- })), placeholder: isPublicValue
373
- ? "agent@yourcompany.com"
374
- : `Enter ${label}`, autoComplete: "off" })) : null] }, envKey.key));
375
- }) }), legacyEnvKeys.length ? (_jsxs(Collapsible, { 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: legacyEnvKeys[0]?.label })] }), _jsx(CollapsibleContent, { children: _jsxs("div", { className: "mt-2 space-y-3 rounded-xl border border-amber-500/30 bg-amber-500/5 p-4", children: [_jsx("p", { className: "text-xs text-muted-foreground", children: legacyEnvKeys[0]?.helpText }), legacyEnvKeys.map((envKey) => {
376
- const envStatus = envStatusByKey.get(envKey.key);
377
- const isConfigured = !!envStatus?.configured;
378
- const helpText = envKey.helpText ?? envStatus?.helpText;
379
- const label = envKey.label || envStatus?.label || envKey.key;
380
- return (_jsxs("div", { className: "space-y-1.5", children: [_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("label", { className: "text-xs font-medium text-foreground", children: label }), helpText ? (_jsx(HelpTooltip, { content: helpText })) : null] }), _jsx(StatusPill, { tone: isConfigured ? "success" : "neutral", label: isConfigured ? "Saved" : "Not set" })] }), !isConfigured ? (_jsx(Input, { type: "password", value: envValues[envKey.key] || "", onChange: (event) => setEnvValues((current) => ({
381
- ...current,
382
- [envKey.key]: event.target.value,
383
- })), placeholder: `Enter ${label}`, autoComplete: "off" })) : null] }, envKey.key));
384
- }), legacyEnvKeys.some((envKey) => !envStatusByKey.get(envKey.key)?.configured) ? (_jsx(Button, { variant: "outline", onClick: () => saveEnvKeys(platform, legacyEnvKeys.map((envKey) => envKey.key)), disabled: savingKeysFor === platform.id, children: savingKeysFor === platform.id
385
- ? "Saving..."
386
- : "Save credentials" })) : null] }) })] })) : null, missingRequiredCredentials ? (_jsx(Button, { variant: "outline", onClick: () => saveEnvKeys(platform, envKeys.map((k) => k.key)), disabled: savingKeysFor === platform.id, children: savingKeysFor === platform.id ? (_jsxs(_Fragment, { children: [_jsx(IconLoader2, { className: "mr-2 h-4 w-4 animate-spin" }), "Saving..."] })) : ("Save credentials") })) : null] }), status?.webhookUrl ? (_jsxs("div", { className: "mt-4 space-y-2", children: [_jsx("div", { className: "text-sm font-medium text-foreground", children: "Webhook URL" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("code", { className: "flex-1 truncate rounded-md border bg-muted/30 px-3 py-2 text-xs text-foreground", children: status.webhookUrl }), _jsx(Button, { variant: "outline", size: "icon", onClick: () => copyWebhook(status.webhookUrl), "aria-label": `Copy ${platform.name} webhook URL`, children: copiedWebhook === status.webhookUrl ? (_jsx(IconCheck, { className: "h-4 w-4" })) : (_jsx(IconCopy, { className: "h-4 w-4" })) })] })] })) : null, _jsxs("div", { className: "mt-5 flex flex-wrap items-center justify-end gap-2 border-t border-border pt-4", children: [platform.id === "telegram" && configured ? (_jsx(Button, { variant: "outline", onClick: () => runSetup(platform), disabled: setupPlatform === platform.id, children: setupPlatform === platform.id ? (_jsxs(_Fragment, { children: [_jsx(IconLoader2, { className: "mr-2 h-4 w-4 animate-spin" }), "Setting up..."] })) : ("Set up webhook") })) : null, !configured && !enabled ? (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { tabIndex: 0, children: _jsx(Button, { disabled: true, children: "Enable" }) }) }), _jsx(TooltipContent, { children: "Save the required credentials first." })] })) : (_jsx(Button, { onClick: () => togglePlatform(platform, enabled), disabled: togglingPlatform === platform.id, children: togglingPlatform === platform.id ? (_jsxs(_Fragment, { children: [_jsx(IconLoader2, { className: "mr-2 h-4 w-4 animate-spin" }), "Saving..."] })) : enabled ? ("Disable") : ("Enable") }))] })] }, platform.id));
395
+ [envKey.key]: event.target.value,
396
+ })), placeholder: isPublicValue
397
+ ? "agent@yourcompany.com"
398
+ : `Enter ${label}`, autoComplete: "off" })) : null] }, envKey.key));
399
+ }) }), legacyEnvKeys.length ? (_jsxs(Collapsible, { 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: legacyEnvKeys[0]?.label })] }), _jsx(CollapsibleContent, { children: _jsxs("div", { className: "mt-2 space-y-3 rounded-xl border border-amber-500/30 bg-amber-500/5 p-4", children: [_jsx("p", { className: "text-xs text-muted-foreground", children: legacyEnvKeys[0]?.helpText }), legacyEnvKeys.map((envKey) => {
400
+ const envStatus = envStatusByKey.get(envKey.key);
401
+ const isConfigured = !!envStatus?.configured;
402
+ const helpText = envKey.helpText ?? envStatus?.helpText;
403
+ const label = envKey.label || envStatus?.label || envKey.key;
404
+ return (_jsxs("div", { className: "space-y-1.5", children: [_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("label", { className: "text-xs font-medium text-foreground", children: label }), helpText ? (_jsx(HelpTooltip, { content: helpText })) : null] }), _jsx(StatusPill, { tone: isConfigured ? "success" : "neutral", label: isConfigured ? "Saved" : "Not set" })] }), !isConfigured ? (_jsx(Input, { type: "password", value: envValues[envKey.key] || "", onChange: (event) => setEnvValues((current) => ({
405
+ ...current,
406
+ [envKey.key]: event.target.value,
407
+ })), placeholder: `Enter ${label}`, autoComplete: "off" })) : null] }, envKey.key));
408
+ }), legacyEnvKeys.some((envKey) => !envStatusByKey.get(envKey.key)?.configured) ? (_jsx(Button, { variant: "outline", onClick: () => saveEnvKeys(platform, legacyEnvKeys.map((envKey) => envKey.key)), disabled: savingKeysFor === platform.id, children: savingKeysFor === platform.id
409
+ ? "Saving..."
410
+ : "Save credentials" })) : null] }) })] })) : null, missingRequiredCredentials ? (_jsx(Button, { variant: "outline", onClick: () => saveEnvKeys(platform, envKeys.map((k) => k.key)), disabled: savingKeysFor === platform.id, children: savingKeysFor === platform.id ? (_jsxs(_Fragment, { children: [_jsx(IconLoader2, { className: "mr-2 h-4 w-4 animate-spin" }), "Saving..."] })) : ("Save credentials") })) : null] }), status?.webhookUrl ? (_jsx(DisclosureSection, { title: "Webhook URL", summary: "Copy the endpoint for this channel", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("code", { className: "flex-1 truncate rounded-md bg-muted/30 px-3 py-2 text-xs text-foreground", children: status.webhookUrl }), _jsx(Button, { variant: "outline", size: "icon", onClick: () => copyWebhook(status.webhookUrl), "aria-label": `Copy ${platform.name} webhook URL`, children: copiedWebhook === status.webhookUrl ? (_jsx(IconCheck, { className: "h-4 w-4" })) : (_jsx(IconCopy, { className: "h-4 w-4" })) })] }) })) : null, _jsx(DisclosureSection, { title: "Resources", summary: "Documentation and external links", children: _jsxs("div", { className: "flex flex-wrap gap-2", children: [_jsx(Button, { asChild: true, variant: "ghost", size: "sm", className: "px-0 text-xs text-muted-foreground hover:bg-transparent hover:text-foreground", children: _jsxs("a", { href: platform.documentation.href, target: "_blank", rel: "noreferrer", children: ["Docs", _jsx(IconExternalLink, { className: "ml-1 h-3 w-3" })] }) }), platform.documentation.externalHref ? (_jsx(Button, { asChild: true, variant: "ghost", size: "sm", className: "px-0 text-xs text-muted-foreground hover:bg-transparent hover:text-foreground", children: _jsxs("a", { href: platform.documentation.externalHref, target: "_blank", rel: "noreferrer", children: [platform.documentation.externalLabel ?? "Open", _jsx(IconExternalLink, { className: "ml-1 h-3 w-3" })] }) })) : null] }) })] }) })] }, platform.id));
387
411
  }) }), loading ? (_jsx("div", { className: "rounded-2xl border border-dashed px-4 py-6 text-sm text-muted-foreground", children: "Loading messaging status..." })) : null] }));
388
412
  }
389
413
  //# sourceMappingURL=messaging-setup-panel.js.map