@greatapps/greatagents-ui 0.3.3 → 0.3.4

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/index.js CHANGED
@@ -88,7 +88,11 @@ function createGagentsClient(config) {
88
88
  `calendar/disconnect/${encodeURIComponent(externalReference)}`,
89
89
  void 0,
90
90
  { provider }
91
- )
91
+ ),
92
+ // --- Capabilities ---
93
+ getCapabilities: (idAccount) => request("GET", idAccount, "capabilities"),
94
+ getAgentCapabilities: (idAccount, idAgent) => request("GET", idAccount, `agents/${idAgent}/capabilities`),
95
+ updateAgentCapabilities: (idAccount, idAgent, body) => request("PUT", idAccount, `agents/${idAgent}/capabilities`, body)
92
96
  };
93
97
  }
94
98
 
@@ -444,8 +448,110 @@ function useGagentsContacts(config, params) {
444
448
  });
445
449
  }
446
450
 
451
+ // src/hooks/use-capabilities.ts
452
+ import { useQuery as useQuery8, useMutation as useMutation6, useQueryClient as useQueryClient6 } from "@tanstack/react-query";
453
+ function useCapabilities(config) {
454
+ const client = useGagentsClient(config);
455
+ return useQuery8({
456
+ queryKey: ["greatagents", "capabilities", config.accountId],
457
+ queryFn: async () => {
458
+ const res = await client.getCapabilities(config.accountId);
459
+ return res.data ?? { product: null, categories: [] };
460
+ },
461
+ enabled: !!config.token && !!config.accountId
462
+ });
463
+ }
464
+ function useAgentCapabilities(config, agentId) {
465
+ const client = useGagentsClient(config);
466
+ return useQuery8({
467
+ queryKey: ["greatagents", "agent-capabilities", config.accountId, agentId],
468
+ queryFn: async () => {
469
+ const res = await client.getAgentCapabilities(config.accountId, agentId);
470
+ const d = res.data;
471
+ return Array.isArray(d) ? d : [];
472
+ },
473
+ enabled: !!config.token && !!config.accountId && !!agentId
474
+ });
475
+ }
476
+ function useUpdateAgentCapabilities(config) {
477
+ const client = useGagentsClient(config);
478
+ const queryClient = useQueryClient6();
479
+ return useMutation6({
480
+ mutationFn: ({ agentId, payload }) => client.updateAgentCapabilities(config.accountId, agentId, payload),
481
+ onSuccess: (_data, variables) => {
482
+ queryClient.invalidateQueries({
483
+ queryKey: ["greatagents", "agent-capabilities", config.accountId, variables.agentId]
484
+ });
485
+ queryClient.invalidateQueries({
486
+ queryKey: ["greatagents", "agent-tools"]
487
+ });
488
+ }
489
+ });
490
+ }
491
+
492
+ // src/hooks/use-integrations.ts
493
+ import { useMemo as useMemo2 } from "react";
494
+
495
+ // src/data/integrations-registry.ts
496
+ var INTEGRATIONS_REGISTRY = [
497
+ {
498
+ slug: "google_calendar",
499
+ name: "Google Agenda",
500
+ description: "Sincronize agendamentos com o Google Calendar",
501
+ icon: "CalendarSync",
502
+ authType: "oauth2",
503
+ status: "available"
504
+ }
505
+ // Future integrations — add entries here without code changes
506
+ ];
507
+
508
+ // src/hooks/use-integrations.ts
509
+ function useIntegrationState(config, agentId) {
510
+ const { data: credentialsData, isLoading: loadingCredentials } = useToolCredentials(config);
511
+ const { data: toolsData, isLoading: loadingTools } = useTools(config);
512
+ const { data: agentToolsData, isLoading: loadingAgentTools } = useAgentTools(
513
+ config,
514
+ agentId ?? 0
515
+ );
516
+ const isLoading = loadingCredentials || loadingTools || loadingAgentTools;
517
+ const cards = useMemo2(() => {
518
+ const credentials = credentialsData?.data ?? [];
519
+ const tools = toolsData?.data ?? [];
520
+ const agentTools = agentToolsData?.data ?? [];
521
+ return INTEGRATIONS_REGISTRY.map((def) => {
522
+ if (def.status === "coming_soon") {
523
+ return {
524
+ definition: def,
525
+ state: "coming_soon",
526
+ credential: null,
527
+ tool: null,
528
+ sharedByAgentsCount: 0,
529
+ linkedToAgent: false
530
+ };
531
+ }
532
+ const matchedTool = tools.find((t) => t.slug === def.slug) ?? null;
533
+ const matchedCredential = matchedTool ? credentials.find((c) => c.id_tool === matchedTool.id) ?? null : null;
534
+ const linkedToAgent = matchedTool ? agentTools.some((at) => at.id_tool === matchedTool.id) : false;
535
+ const sharedByAgentsCount = matchedCredential ? 1 : 0;
536
+ let state = "available";
537
+ if (matchedCredential) {
538
+ state = matchedCredential.status === "expired" ? "expired" : "connected";
539
+ }
540
+ return {
541
+ definition: def,
542
+ state,
543
+ credential: matchedCredential,
544
+ tool: matchedTool,
545
+ sharedByAgentsCount,
546
+ linkedToAgent
547
+ };
548
+ });
549
+ }, [credentialsData, toolsData, agentToolsData]);
550
+ return { cards, isLoading };
551
+ }
552
+
447
553
  // src/components/agents/agents-table.tsx
448
- import { useMemo as useMemo2, useState } from "react";
554
+ import { useMemo as useMemo3, useState } from "react";
449
555
  import { DataTable } from "@greatapps/greatauth-ui";
450
556
  import {
451
557
  Input,
@@ -532,7 +638,7 @@ function useColumns(onEdit, onDelete) {
532
638
  function AgentsTable({ config, onNavigateToAgent }) {
533
639
  const [search, setSearch] = useState("");
534
640
  const [page, setPage] = useState(1);
535
- const queryParams = useMemo2(() => {
641
+ const queryParams = useMemo3(() => {
536
642
  const params = {
537
643
  limit: "15",
538
644
  page: String(page)
@@ -2684,7 +2790,7 @@ function AgentTabs({ agent, config, renderChatLink }) {
2684
2790
  }
2685
2791
 
2686
2792
  // src/components/tools/tools-table.tsx
2687
- import { useMemo as useMemo4, useState as useState9 } from "react";
2793
+ import { useMemo as useMemo5, useState as useState9 } from "react";
2688
2794
  import { DataTable as DataTable2 } from "@greatapps/greatauth-ui";
2689
2795
  import {
2690
2796
  Input as Input7,
@@ -2781,7 +2887,7 @@ function useColumns2(onEdit, onDelete) {
2781
2887
  function ToolsTable({ onEdit, config }) {
2782
2888
  const [search, setSearch] = useState9("");
2783
2889
  const [page, setPage] = useState9(1);
2784
- const queryParams = useMemo4(() => {
2890
+ const queryParams = useMemo5(() => {
2785
2891
  const params = {
2786
2892
  limit: "15",
2787
2893
  page: String(page)
@@ -3147,7 +3253,7 @@ function ToolFormDialog({
3147
3253
  }
3148
3254
 
3149
3255
  // src/components/tools/tool-credentials-form.tsx
3150
- import { useMemo as useMemo5, useState as useState11 } from "react";
3256
+ import { useMemo as useMemo6, useState as useState11 } from "react";
3151
3257
  import { DataTable as DataTable3 } from "@greatapps/greatauth-ui";
3152
3258
  import {
3153
3259
  Input as Input9,
@@ -3311,7 +3417,7 @@ function ToolCredentialsForm({
3311
3417
  status: ""
3312
3418
  });
3313
3419
  const [removeTarget, setRemoveTarget] = useState11(null);
3314
- const filteredCredentials = useMemo5(() => {
3420
+ const filteredCredentials = useMemo6(() => {
3315
3421
  if (!search) return credentials;
3316
3422
  const term = search.toLowerCase();
3317
3423
  return credentials.filter((cred) => {
@@ -3650,31 +3756,1302 @@ function ToolCredentialsForm({
3650
3756
  ] });
3651
3757
  }
3652
3758
 
3759
+ // src/components/capabilities/integration-card.tsx
3760
+ import { Badge as Badge8, Button as Button11, Tooltip as Tooltip4, TooltipContent as TooltipContent4, TooltipTrigger as TooltipTrigger4 } from "@greatapps/greatauth-ui/ui";
3761
+ import {
3762
+ CalendarSync,
3763
+ Plug,
3764
+ Settings,
3765
+ RefreshCw,
3766
+ Users,
3767
+ Clock
3768
+ } from "lucide-react";
3769
+ import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
3770
+ var ICON_MAP = {
3771
+ CalendarSync,
3772
+ Plug,
3773
+ Settings,
3774
+ RefreshCw,
3775
+ Users,
3776
+ Clock
3777
+ };
3778
+ function resolveIcon(name) {
3779
+ return ICON_MAP[name] ?? Plug;
3780
+ }
3781
+ var STATE_BADGES = {
3782
+ available: {
3783
+ label: "Dispon\xEDvel",
3784
+ className: "bg-muted text-muted-foreground"
3785
+ },
3786
+ connected: {
3787
+ label: "Conectado",
3788
+ className: "bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400"
3789
+ },
3790
+ expired: {
3791
+ label: "Expirado",
3792
+ className: "bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400"
3793
+ },
3794
+ coming_soon: {
3795
+ label: "Em breve",
3796
+ className: "bg-muted text-muted-foreground"
3797
+ }
3798
+ };
3799
+ function getActionLabel(state) {
3800
+ switch (state) {
3801
+ case "available":
3802
+ return "Conectar";
3803
+ case "connected":
3804
+ return "Configurar";
3805
+ case "expired":
3806
+ return "Reconectar";
3807
+ default:
3808
+ return "";
3809
+ }
3810
+ }
3811
+ function IntegrationCard({ card, onConnect }) {
3812
+ const { definition, state, sharedByAgentsCount } = card;
3813
+ const Icon = resolveIcon(definition.icon);
3814
+ const badge = STATE_BADGES[state];
3815
+ const actionLabel = getActionLabel(state);
3816
+ const isComingSoon = state === "coming_soon";
3817
+ return /* @__PURE__ */ jsxs13(
3818
+ "div",
3819
+ {
3820
+ className: cn(
3821
+ "group relative flex flex-col gap-3 rounded-xl border bg-card p-5 transition-shadow",
3822
+ isComingSoon ? "opacity-60 cursor-default" : "hover:shadow-md cursor-pointer"
3823
+ ),
3824
+ role: "button",
3825
+ tabIndex: isComingSoon ? -1 : 0,
3826
+ "aria-label": `${definition.name} \u2014 ${badge.label}`,
3827
+ "aria-disabled": isComingSoon,
3828
+ onClick: () => !isComingSoon && onConnect(card),
3829
+ onKeyDown: (e) => {
3830
+ if (!isComingSoon && (e.key === "Enter" || e.key === " ")) {
3831
+ e.preventDefault();
3832
+ onConnect(card);
3833
+ }
3834
+ },
3835
+ children: [
3836
+ /* @__PURE__ */ jsxs13("div", { className: "flex items-start justify-between gap-2", children: [
3837
+ /* @__PURE__ */ jsx15("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: /* @__PURE__ */ jsx15(Icon, { className: "h-5 w-5" }) }),
3838
+ /* @__PURE__ */ jsx15(Badge8, { variant: "outline", className: cn("text-xs", badge.className), children: badge.label })
3839
+ ] }),
3840
+ /* @__PURE__ */ jsxs13("div", { className: "space-y-1", children: [
3841
+ /* @__PURE__ */ jsx15("h3", { className: "text-sm font-semibold leading-tight", children: definition.name }),
3842
+ /* @__PURE__ */ jsx15("p", { className: "text-xs text-muted-foreground leading-relaxed", children: definition.description })
3843
+ ] }),
3844
+ /* @__PURE__ */ jsxs13("div", { className: "mt-auto flex items-center justify-between gap-2 pt-1", children: [
3845
+ sharedByAgentsCount > 0 ? /* @__PURE__ */ jsxs13(Tooltip4, { children: [
3846
+ /* @__PURE__ */ jsx15(TooltipTrigger4, { asChild: true, children: /* @__PURE__ */ jsxs13("span", { className: "inline-flex items-center gap-1 text-xs text-blue-600 dark:text-blue-400", children: [
3847
+ /* @__PURE__ */ jsx15(Users, { className: "h-3.5 w-3.5" }),
3848
+ "Compartilhada"
3849
+ ] }) }),
3850
+ /* @__PURE__ */ jsx15(TooltipContent4, { children: "Esta credencial est\xE1 dispon\xEDvel para todos os agentes da conta" })
3851
+ ] }) : /* @__PURE__ */ jsx15("span", {}),
3852
+ !isComingSoon && /* @__PURE__ */ jsx15(
3853
+ Button11,
3854
+ {
3855
+ variant: state === "expired" ? "destructive" : "outline",
3856
+ size: "sm",
3857
+ className: "text-xs",
3858
+ onClick: (e) => {
3859
+ e.stopPropagation();
3860
+ onConnect(card);
3861
+ },
3862
+ children: actionLabel
3863
+ }
3864
+ )
3865
+ ] })
3866
+ ]
3867
+ }
3868
+ );
3869
+ }
3870
+
3871
+ // src/components/capabilities/integrations-tab.tsx
3872
+ import { Plug as Plug2, Loader2 as Loader25 } from "lucide-react";
3873
+ import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
3874
+ function IntegrationsTab({
3875
+ config,
3876
+ agentId,
3877
+ onConnect
3878
+ }) {
3879
+ const { cards, isLoading } = useIntegrationState(config, agentId);
3880
+ if (isLoading) {
3881
+ return /* @__PURE__ */ jsx16("div", { className: "flex items-center justify-center py-16", children: /* @__PURE__ */ jsx16(Loader25, { className: "h-6 w-6 animate-spin text-muted-foreground" }) });
3882
+ }
3883
+ if (cards.length === 0) {
3884
+ return /* @__PURE__ */ jsxs14("div", { className: "flex flex-col items-center justify-center gap-3 py-16 text-muted-foreground", children: [
3885
+ /* @__PURE__ */ jsx16(Plug2, { className: "h-10 w-10" }),
3886
+ /* @__PURE__ */ jsx16("p", { className: "text-sm", children: "Nenhuma integra\xE7\xE3o dispon\xEDvel" })
3887
+ ] });
3888
+ }
3889
+ return /* @__PURE__ */ jsx16("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: cards.map((card) => /* @__PURE__ */ jsx16(
3890
+ IntegrationCard,
3891
+ {
3892
+ card,
3893
+ onConnect
3894
+ },
3895
+ card.definition.slug
3896
+ )) });
3897
+ }
3898
+
3899
+ // src/components/capabilities/capabilities-tab.tsx
3900
+ import { useState as useState12, useCallback as useCallback4, useRef as useRef2, useEffect as useEffect4, useMemo as useMemo7 } from "react";
3901
+ import {
3902
+ Accordion,
3903
+ AccordionItem,
3904
+ AccordionTrigger,
3905
+ AccordionContent,
3906
+ Switch as Switch4,
3907
+ Checkbox,
3908
+ Badge as Badge9,
3909
+ Button as Button12,
3910
+ Skeleton as Skeleton6
3911
+ } from "@greatapps/greatauth-ui/ui";
3912
+ import {
3913
+ Calendar,
3914
+ Users as Users2,
3915
+ Settings as Settings3,
3916
+ HeartHandshake,
3917
+ Package,
3918
+ ChevronDown as ChevronDown2
3919
+ } from "lucide-react";
3920
+ import { toast as toast10 } from "sonner";
3921
+ import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
3922
+ var OPERATION_LABELS = {
3923
+ list: "Listar",
3924
+ view: "Visualizar",
3925
+ create: "Criar",
3926
+ update: "Atualizar"
3927
+ };
3928
+ function getOperationLabel(slug) {
3929
+ return OPERATION_LABELS[slug] ?? slug;
3930
+ }
3931
+ var CATEGORY_ICONS = {
3932
+ agenda: Calendar,
3933
+ cadastros: Users2,
3934
+ infraestrutura: Settings3,
3935
+ relacionamentos: HeartHandshake
3936
+ };
3937
+ function getCategoryIcon(slug) {
3938
+ return CATEGORY_ICONS[slug] ?? Package;
3939
+ }
3940
+ function buildStateFromAgent(agentCaps) {
3941
+ const state = /* @__PURE__ */ new Map();
3942
+ for (const cap of agentCaps) {
3943
+ state.set(cap.module, new Set(cap.operations));
3944
+ }
3945
+ return state;
3946
+ }
3947
+ function stateToPayload(state) {
3948
+ const capabilities = [];
3949
+ state.forEach((ops, mod) => {
3950
+ if (ops.size > 0) {
3951
+ capabilities.push({ module: mod, operations: Array.from(ops) });
3952
+ }
3953
+ });
3954
+ return { capabilities };
3955
+ }
3956
+ function cloneState(state) {
3957
+ const next = /* @__PURE__ */ new Map();
3958
+ state.forEach((ops, mod) => next.set(mod, new Set(ops)));
3959
+ return next;
3960
+ }
3961
+ function statesEqual(a, b) {
3962
+ if (a.size !== b.size) return false;
3963
+ for (const [mod, opsA] of a) {
3964
+ const opsB = b.get(mod);
3965
+ if (!opsB || opsA.size !== opsB.size) return false;
3966
+ for (const op of opsA) {
3967
+ if (!opsB.has(op)) return false;
3968
+ }
3969
+ }
3970
+ return true;
3971
+ }
3972
+ function CapabilitiesTab({ config, agentId }) {
3973
+ const { data: registry, isLoading: isLoadingRegistry } = useCapabilities(config);
3974
+ const { data: agentCaps, isLoading: isLoadingAgent } = useAgentCapabilities(config, agentId);
3975
+ const updateMutation = useUpdateAgentCapabilities(config);
3976
+ const [localState, setLocalState] = useState12(/* @__PURE__ */ new Map());
3977
+ const [serverState, setServerState] = useState12(/* @__PURE__ */ new Map());
3978
+ const [initialized, setInitialized] = useState12(false);
3979
+ const debounceRef = useRef2(null);
3980
+ useEffect4(() => {
3981
+ if (agentCaps && !initialized) {
3982
+ const state = buildStateFromAgent(agentCaps);
3983
+ setLocalState(state);
3984
+ setServerState(cloneState(state));
3985
+ setInitialized(true);
3986
+ }
3987
+ }, [agentCaps, initialized]);
3988
+ useEffect4(() => {
3989
+ setInitialized(false);
3990
+ }, [agentId]);
3991
+ const hasChanges = useMemo7(
3992
+ () => initialized && !statesEqual(localState, serverState),
3993
+ [localState, serverState, initialized]
3994
+ );
3995
+ const scheduleSave = useCallback4(
3996
+ (nextState) => {
3997
+ if (debounceRef.current) clearTimeout(debounceRef.current);
3998
+ debounceRef.current = setTimeout(() => {
3999
+ const payload = stateToPayload(nextState);
4000
+ updateMutation.mutate(
4001
+ { agentId, payload },
4002
+ {
4003
+ onSuccess: () => {
4004
+ setServerState(cloneState(nextState));
4005
+ toast10.success("Capacidades salvas");
4006
+ },
4007
+ onError: () => {
4008
+ setLocalState(cloneState(serverState));
4009
+ toast10.error("Erro ao salvar capacidades");
4010
+ }
4011
+ }
4012
+ );
4013
+ }, 500);
4014
+ },
4015
+ [agentId, updateMutation, serverState]
4016
+ );
4017
+ const updateState = useCallback4(
4018
+ (updater) => {
4019
+ setLocalState((prev) => {
4020
+ const next = updater(prev);
4021
+ scheduleSave(next);
4022
+ return next;
4023
+ });
4024
+ },
4025
+ [scheduleSave]
4026
+ );
4027
+ const toggleModule = useCallback4(
4028
+ (mod, enabled) => {
4029
+ updateState((prev) => {
4030
+ const next = cloneState(prev);
4031
+ if (enabled) {
4032
+ next.set(mod.slug, new Set(mod.operations));
4033
+ } else {
4034
+ next.delete(mod.slug);
4035
+ }
4036
+ return next;
4037
+ });
4038
+ },
4039
+ [updateState]
4040
+ );
4041
+ const toggleOperation = useCallback4(
4042
+ (mod, opSlug, enabled) => {
4043
+ updateState((prev) => {
4044
+ const next = cloneState(prev);
4045
+ const ops = new Set(next.get(mod.slug) ?? []);
4046
+ if (enabled) {
4047
+ ops.add(opSlug);
4048
+ } else {
4049
+ ops.delete(opSlug);
4050
+ }
4051
+ if (ops.size > 0) {
4052
+ next.set(mod.slug, ops);
4053
+ } else {
4054
+ next.delete(mod.slug);
4055
+ }
4056
+ return next;
4057
+ });
4058
+ },
4059
+ [updateState]
4060
+ );
4061
+ const enableAll = useCallback4(() => {
4062
+ if (!registry) return;
4063
+ updateState(() => {
4064
+ const next = /* @__PURE__ */ new Map();
4065
+ for (const cat of registry.categories) {
4066
+ for (const mod of cat.modules) {
4067
+ next.set(mod.slug, new Set(mod.operations));
4068
+ }
4069
+ }
4070
+ return next;
4071
+ });
4072
+ }, [registry, updateState]);
4073
+ const disableAll = useCallback4(() => {
4074
+ updateState(() => /* @__PURE__ */ new Map());
4075
+ }, [updateState]);
4076
+ const discard = useCallback4(() => {
4077
+ if (debounceRef.current) clearTimeout(debounceRef.current);
4078
+ setLocalState(cloneState(serverState));
4079
+ }, [serverState]);
4080
+ const saveNow = useCallback4(() => {
4081
+ if (debounceRef.current) clearTimeout(debounceRef.current);
4082
+ const payload = stateToPayload(localState);
4083
+ updateMutation.mutate(
4084
+ { agentId, payload },
4085
+ {
4086
+ onSuccess: () => {
4087
+ setServerState(cloneState(localState));
4088
+ toast10.success("Capacidades salvas");
4089
+ },
4090
+ onError: () => {
4091
+ setLocalState(cloneState(serverState));
4092
+ toast10.error("Erro ao salvar capacidades");
4093
+ }
4094
+ }
4095
+ );
4096
+ }, [agentId, localState, serverState, updateMutation]);
4097
+ function countActiveModules(cat) {
4098
+ return cat.modules.filter((m) => (localState.get(m.slug)?.size ?? 0) > 0).length;
4099
+ }
4100
+ if (isLoadingRegistry || isLoadingAgent) {
4101
+ return /* @__PURE__ */ jsx17("div", { className: "space-y-3", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx17(Skeleton6, { className: "h-14 w-full" }, i)) });
4102
+ }
4103
+ if (!registry || !registry.categories.length) {
4104
+ return /* @__PURE__ */ jsxs15("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: [
4105
+ /* @__PURE__ */ jsx17(Package, { className: "h-12 w-12 text-muted-foreground mb-3" }),
4106
+ /* @__PURE__ */ jsx17("h3", { className: "text-base font-medium", children: "Nenhuma capacidade dispon\xEDvel" }),
4107
+ /* @__PURE__ */ jsx17("p", { className: "text-sm text-muted-foreground mt-1 max-w-sm", children: "Este produto ainda n\xE3o possui capacidades registadas. As capacidades ser\xE3o adicionadas automaticamente quando o produto for configurado." })
4108
+ ] });
4109
+ }
4110
+ return /* @__PURE__ */ jsxs15("div", { className: "space-y-4", children: [
4111
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
4112
+ /* @__PURE__ */ jsxs15("div", { children: [
4113
+ /* @__PURE__ */ jsx17("h3", { className: "text-sm font-medium", children: "Capacidades do agente" }),
4114
+ /* @__PURE__ */ jsx17("p", { className: "text-xs text-muted-foreground mt-0.5", children: "Ative ou desative m\xF3dulos e opera\xE7\xF5es dispon\xEDveis para este agente." })
4115
+ ] }),
4116
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2", children: [
4117
+ /* @__PURE__ */ jsx17(Button12, { variant: "outline", size: "sm", onClick: enableAll, children: "Ativar tudo" }),
4118
+ /* @__PURE__ */ jsx17(Button12, { variant: "outline", size: "sm", onClick: disableAll, children: "Desativar tudo" })
4119
+ ] })
4120
+ ] }),
4121
+ /* @__PURE__ */ jsx17(Accordion, { type: "multiple", className: "space-y-2", children: registry.categories.map((cat) => {
4122
+ const Icon = getCategoryIcon(cat.slug);
4123
+ const activeCount = countActiveModules(cat);
4124
+ const totalModules = cat.modules.length;
4125
+ return /* @__PURE__ */ jsxs15(
4126
+ AccordionItem,
4127
+ {
4128
+ value: cat.slug,
4129
+ className: "border rounded-lg px-4",
4130
+ children: [
4131
+ /* @__PURE__ */ jsx17(AccordionTrigger, { className: "hover:no-underline py-3", children: /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-3 flex-1", children: [
4132
+ /* @__PURE__ */ jsx17(Icon, { className: "h-4 w-4 text-muted-foreground" }),
4133
+ /* @__PURE__ */ jsx17("span", { className: "font-medium text-sm", children: cat.label }),
4134
+ /* @__PURE__ */ jsxs15(Badge9, { variant: "secondary", className: "text-xs", children: [
4135
+ activeCount,
4136
+ " de ",
4137
+ totalModules,
4138
+ " m\xF3dulos ativos"
4139
+ ] })
4140
+ ] }) }),
4141
+ /* @__PURE__ */ jsx17(AccordionContent, { className: "pb-3", children: /* @__PURE__ */ jsx17("div", { className: "space-y-1", children: cat.modules.map((mod) => {
4142
+ const enabledOps = localState.get(mod.slug);
4143
+ const isModuleOn = (enabledOps?.size ?? 0) > 0;
4144
+ const allOpsEnabled = enabledOps?.size === mod.operations.length;
4145
+ return /* @__PURE__ */ jsx17(
4146
+ ModuleRow,
4147
+ {
4148
+ module: mod,
4149
+ isOn: isModuleOn,
4150
+ allOpsEnabled,
4151
+ enabledOps: enabledOps ?? /* @__PURE__ */ new Set(),
4152
+ onToggleModule: (on) => toggleModule(mod, on),
4153
+ onToggleOperation: (op, on) => toggleOperation(mod, op, on)
4154
+ },
4155
+ mod.slug
4156
+ );
4157
+ }) }) })
4158
+ ]
4159
+ },
4160
+ cat.slug
4161
+ );
4162
+ }) }),
4163
+ hasChanges && /* @__PURE__ */ jsxs15("div", { className: "sticky bottom-0 bg-background border-t py-3 px-4 -mx-4 flex items-center justify-between", children: [
4164
+ /* @__PURE__ */ jsx17("span", { className: "text-sm text-muted-foreground", children: "Voc\xEA tem altera\xE7\xF5es n\xE3o salvas." }),
4165
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2", children: [
4166
+ /* @__PURE__ */ jsx17(Button12, { variant: "outline", size: "sm", onClick: discard, children: "Descartar" }),
4167
+ /* @__PURE__ */ jsx17(
4168
+ Button12,
4169
+ {
4170
+ size: "sm",
4171
+ onClick: saveNow,
4172
+ disabled: updateMutation.isPending,
4173
+ children: updateMutation.isPending ? "Salvando..." : "Salvar"
4174
+ }
4175
+ )
4176
+ ] })
4177
+ ] })
4178
+ ] });
4179
+ }
4180
+ function ModuleRow({
4181
+ module: mod,
4182
+ isOn,
4183
+ enabledOps,
4184
+ onToggleModule,
4185
+ onToggleOperation
4186
+ }) {
4187
+ const [expanded, setExpanded] = useState12(false);
4188
+ return /* @__PURE__ */ jsxs15("div", { className: "rounded-md border px-3 py-2", children: [
4189
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
4190
+ /* @__PURE__ */ jsxs15(
4191
+ "button",
4192
+ {
4193
+ type: "button",
4194
+ className: "flex items-center gap-2 flex-1 text-left",
4195
+ onClick: () => setExpanded(!expanded),
4196
+ "aria-expanded": expanded,
4197
+ "aria-label": `Expandir ${mod.label}`,
4198
+ children: [
4199
+ /* @__PURE__ */ jsx17(
4200
+ ChevronDown2,
4201
+ {
4202
+ className: `h-3.5 w-3.5 text-muted-foreground transition-transform ${expanded ? "rotate-0" : "-rotate-90"}`
4203
+ }
4204
+ ),
4205
+ /* @__PURE__ */ jsx17("span", { className: "text-sm font-medium", children: mod.label }),
4206
+ mod.description && /* @__PURE__ */ jsxs15("span", { className: "text-xs text-muted-foreground hidden sm:inline", children: [
4207
+ "\u2014 ",
4208
+ mod.description
4209
+ ] }),
4210
+ isOn && /* @__PURE__ */ jsxs15(Badge9, { variant: "secondary", className: "text-xs ml-1", children: [
4211
+ enabledOps.size,
4212
+ "/",
4213
+ mod.operations.length
4214
+ ] })
4215
+ ]
4216
+ }
4217
+ ),
4218
+ /* @__PURE__ */ jsx17(
4219
+ Switch4,
4220
+ {
4221
+ checked: isOn,
4222
+ onCheckedChange: onToggleModule,
4223
+ "aria-label": `Ativar m\xF3dulo ${mod.label}`
4224
+ }
4225
+ )
4226
+ ] }),
4227
+ expanded && /* @__PURE__ */ jsx17("div", { className: "mt-2 ml-6 flex flex-wrap gap-x-5 gap-y-1.5 pb-1", children: mod.operations.map((op) => {
4228
+ const checked = enabledOps.has(op);
4229
+ return /* @__PURE__ */ jsxs15(
4230
+ "label",
4231
+ {
4232
+ className: "flex items-center gap-1.5 text-sm cursor-pointer",
4233
+ children: [
4234
+ /* @__PURE__ */ jsx17(
4235
+ Checkbox,
4236
+ {
4237
+ checked,
4238
+ onCheckedChange: (val) => onToggleOperation(op, val === true),
4239
+ "aria-label": `${getOperationLabel(op)} em ${mod.label}`
4240
+ }
4241
+ ),
4242
+ /* @__PURE__ */ jsx17("span", { className: checked ? "" : "text-muted-foreground", children: getOperationLabel(op) })
4243
+ ]
4244
+ },
4245
+ op
4246
+ );
4247
+ }) })
4248
+ ] });
4249
+ }
4250
+
4251
+ // src/components/capabilities/advanced-tab.tsx
4252
+ import { useState as useState13 } from "react";
4253
+ import { Info } from "lucide-react";
4254
+ import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
4255
+ function AdvancedTab({ config, agentId, gagentsApiUrl }) {
4256
+ const { data: credentialsData, isLoading: isLoadingCredentials } = useToolCredentials(config);
4257
+ const credentials = credentialsData?.data ?? [];
4258
+ const [editingTool, setEditingTool] = useState13(null);
4259
+ const [showToolForm, setShowToolForm] = useState13(false);
4260
+ function handleEditTool(tool) {
4261
+ setEditingTool(tool);
4262
+ setShowToolForm(true);
4263
+ }
4264
+ function handleToolFormOpenChange(open) {
4265
+ setShowToolForm(open);
4266
+ if (!open) setEditingTool(null);
4267
+ }
4268
+ return /* @__PURE__ */ jsxs16("div", { className: "space-y-8", children: [
4269
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-start gap-3 rounded-lg border border-blue-200 bg-blue-50 p-4 dark:border-blue-900 dark:bg-blue-950/30", children: [
4270
+ /* @__PURE__ */ jsx18(Info, { className: "mt-0.5 h-4 w-4 shrink-0 text-blue-600 dark:text-blue-400" }),
4271
+ /* @__PURE__ */ jsxs16("p", { className: "text-sm text-blue-800 dark:text-blue-300", children: [
4272
+ "Use as abas ",
4273
+ /* @__PURE__ */ jsx18("strong", { children: "Capacidades" }),
4274
+ " e ",
4275
+ /* @__PURE__ */ jsx18("strong", { children: "Integra\xE7\xF5es" }),
4276
+ " para configura\xE7\xE3o simplificada. Esta aba oferece controlo manual avan\xE7ado sobre ferramentas e credenciais."
4277
+ ] })
4278
+ ] }),
4279
+ /* @__PURE__ */ jsxs16("section", { className: "space-y-3", children: [
4280
+ /* @__PURE__ */ jsx18("h3", { className: "text-sm font-medium", children: "Ferramentas" }),
4281
+ /* @__PURE__ */ jsx18(ToolsTable, { onEdit: handleEditTool, config })
4282
+ ] }),
4283
+ /* @__PURE__ */ jsxs16("section", { className: "space-y-3", children: [
4284
+ /* @__PURE__ */ jsx18("h3", { className: "text-sm font-medium", children: "Credenciais" }),
4285
+ /* @__PURE__ */ jsx18(
4286
+ ToolCredentialsForm,
4287
+ {
4288
+ credentials,
4289
+ isLoading: isLoadingCredentials,
4290
+ config,
4291
+ gagentsApiUrl
4292
+ }
4293
+ )
4294
+ ] }),
4295
+ /* @__PURE__ */ jsx18(
4296
+ ToolFormDialog,
4297
+ {
4298
+ open: showToolForm,
4299
+ onOpenChange: handleToolFormOpenChange,
4300
+ tool: editingTool ?? void 0,
4301
+ config
4302
+ }
4303
+ )
4304
+ ] });
4305
+ }
4306
+
4307
+ // src/components/capabilities/integration-wizard.tsx
4308
+ import { useCallback as useCallback5, useEffect as useEffect5, useRef as useRef3, useState as useState14 } from "react";
4309
+ import {
4310
+ Dialog as Dialog7,
4311
+ DialogContent as DialogContent7,
4312
+ DialogFooter as DialogFooter7,
4313
+ DialogHeader as DialogHeader7,
4314
+ DialogTitle as DialogTitle7,
4315
+ Button as Button14
4316
+ } from "@greatapps/greatauth-ui/ui";
4317
+ import { Loader2 as Loader28, ChevronLeft, ChevronRight, Check as Check2 } from "lucide-react";
4318
+ import { toast as toast11 } from "sonner";
4319
+
4320
+ // src/components/capabilities/wizard-steps/info-step.tsx
4321
+ import { Check, Info as Info2 } from "lucide-react";
4322
+ import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
4323
+ function InfoStep({ integration, meta }) {
4324
+ return /* @__PURE__ */ jsxs17("div", { className: "space-y-6", children: [
4325
+ /* @__PURE__ */ jsxs17("div", { className: "flex items-start gap-4", children: [
4326
+ meta.icon && /* @__PURE__ */ jsx19("div", { className: "flex h-12 w-12 shrink-0 items-center justify-center rounded-lg bg-muted", children: meta.icon }),
4327
+ /* @__PURE__ */ jsxs17("div", { className: "space-y-1", children: [
4328
+ /* @__PURE__ */ jsx19("h3", { className: "text-lg font-semibold", children: integration.name }),
4329
+ /* @__PURE__ */ jsx19("p", { className: "text-sm text-muted-foreground", children: integration.description })
4330
+ ] })
4331
+ ] }),
4332
+ meta.capabilities.length > 0 && /* @__PURE__ */ jsxs17("div", { className: "space-y-3", children: [
4333
+ /* @__PURE__ */ jsx19("h4", { className: "text-sm font-medium", children: "O que esta integra\xE7\xE3o permite:" }),
4334
+ /* @__PURE__ */ jsx19("ul", { className: "space-y-2", children: meta.capabilities.map((cap, i) => /* @__PURE__ */ jsxs17("li", { className: "flex items-start gap-2 text-sm", children: [
4335
+ /* @__PURE__ */ jsx19(
4336
+ Check,
4337
+ {
4338
+ "aria-hidden": "true",
4339
+ className: "mt-0.5 h-4 w-4 shrink-0 text-green-600"
4340
+ }
4341
+ ),
4342
+ /* @__PURE__ */ jsxs17("div", { children: [
4343
+ /* @__PURE__ */ jsx19("span", { className: "font-medium", children: cap.label }),
4344
+ cap.description && /* @__PURE__ */ jsxs17("span", { className: "text-muted-foreground", children: [
4345
+ " ",
4346
+ "\u2014 ",
4347
+ cap.description
4348
+ ] })
4349
+ ] })
4350
+ ] }, i)) })
4351
+ ] }),
4352
+ meta.requirements.length > 0 && /* @__PURE__ */ jsxs17("div", { className: "space-y-3", children: [
4353
+ /* @__PURE__ */ jsx19("h4", { className: "text-sm font-medium", children: "Requisitos:" }),
4354
+ /* @__PURE__ */ jsx19("ul", { className: "space-y-2", children: meta.requirements.map((req, i) => /* @__PURE__ */ jsxs17(
4355
+ "li",
4356
+ {
4357
+ className: "flex items-start gap-2 text-sm text-muted-foreground",
4358
+ children: [
4359
+ /* @__PURE__ */ jsx19(
4360
+ Info2,
4361
+ {
4362
+ "aria-hidden": "true",
4363
+ className: "mt-0.5 h-4 w-4 shrink-0 text-blue-500"
4364
+ }
4365
+ ),
4366
+ /* @__PURE__ */ jsx19("span", { children: req })
4367
+ ]
4368
+ },
4369
+ i
4370
+ )) })
4371
+ ] })
4372
+ ] });
4373
+ }
4374
+
4375
+ // src/components/capabilities/wizard-steps/credentials-step.tsx
4376
+ import { CheckCircle2, Loader2 as Loader26, AlertCircle, Shield } from "lucide-react";
4377
+ import { Button as Button13, Input as Input10, Label as Label6 } from "@greatapps/greatauth-ui/ui";
4378
+ import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
4379
+ function CredentialsStep({
4380
+ integration,
4381
+ meta,
4382
+ oauthStatus,
4383
+ oauthResult,
4384
+ apiKey,
4385
+ onApiKeyChange,
4386
+ onStartOAuth,
4387
+ isReconnect = false
4388
+ }) {
4389
+ if (integration.authType === "oauth2") {
4390
+ return /* @__PURE__ */ jsx20(
4391
+ OAuthCredentials,
4392
+ {
4393
+ integration,
4394
+ meta,
4395
+ oauthStatus,
4396
+ oauthResult,
4397
+ onStartOAuth,
4398
+ isReconnect
4399
+ }
4400
+ );
4401
+ }
4402
+ return /* @__PURE__ */ jsx20(ApiKeyCredentials, { apiKey, onApiKeyChange });
4403
+ }
4404
+ function OAuthCredentials({
4405
+ integration,
4406
+ meta,
4407
+ oauthStatus,
4408
+ oauthResult,
4409
+ onStartOAuth,
4410
+ isReconnect
4411
+ }) {
4412
+ const providerLabel = meta.providerLabel || integration.name;
4413
+ return /* @__PURE__ */ jsxs18("div", { className: "space-y-6", children: [
4414
+ /* @__PURE__ */ jsxs18("div", { className: "space-y-2", children: [
4415
+ /* @__PURE__ */ jsx20("h3", { className: "text-lg font-semibold", children: "Autentica\xE7\xE3o" }),
4416
+ /* @__PURE__ */ jsx20("p", { className: "text-sm text-muted-foreground", children: isReconnect ? `Reconecte sua conta ${providerLabel} para renovar a autoriza\xE7\xE3o.` : `Conecte sua conta ${providerLabel} para permitir o acesso.` })
4417
+ ] }),
4418
+ /* @__PURE__ */ jsxs18("div", { className: "flex flex-col items-center gap-4 rounded-lg border p-6", children: [
4419
+ oauthStatus === "idle" && /* @__PURE__ */ jsxs18(Button13, { onClick: onStartOAuth, size: "lg", className: "gap-2", children: [
4420
+ meta.icon,
4421
+ isReconnect ? `Reconectar com ${providerLabel}` : `Conectar com ${providerLabel}`
4422
+ ] }),
4423
+ oauthStatus === "waiting" && /* @__PURE__ */ jsxs18("div", { className: "flex flex-col items-center gap-3 text-center", children: [
4424
+ /* @__PURE__ */ jsx20(
4425
+ Loader26,
4426
+ {
4427
+ "aria-hidden": "true",
4428
+ className: "h-8 w-8 animate-spin text-muted-foreground"
4429
+ }
4430
+ ),
4431
+ /* @__PURE__ */ jsxs18("div", { children: [
4432
+ /* @__PURE__ */ jsx20("p", { className: "text-sm font-medium", children: "Aguardando autoriza\xE7\xE3o..." }),
4433
+ /* @__PURE__ */ jsx20("p", { className: "text-xs text-muted-foreground", children: "Complete o login na janela que foi aberta." })
4434
+ ] })
4435
+ ] }),
4436
+ oauthStatus === "success" && oauthResult && /* @__PURE__ */ jsxs18("div", { className: "flex flex-col items-center gap-3 text-center", children: [
4437
+ /* @__PURE__ */ jsx20(
4438
+ CheckCircle2,
4439
+ {
4440
+ "aria-hidden": "true",
4441
+ className: "h-8 w-8 text-green-600"
4442
+ }
4443
+ ),
4444
+ /* @__PURE__ */ jsxs18("div", { children: [
4445
+ /* @__PURE__ */ jsx20("p", { className: "text-sm font-medium text-green-700", children: "Conectado com sucesso!" }),
4446
+ oauthResult.email && /* @__PURE__ */ jsx20("p", { className: "text-xs text-muted-foreground", children: oauthResult.email })
4447
+ ] })
4448
+ ] }),
4449
+ oauthStatus === "error" && /* @__PURE__ */ jsxs18("div", { className: "flex flex-col items-center gap-3 text-center", children: [
4450
+ /* @__PURE__ */ jsx20(
4451
+ AlertCircle,
4452
+ {
4453
+ "aria-hidden": "true",
4454
+ className: "h-8 w-8 text-destructive"
4455
+ }
4456
+ ),
4457
+ /* @__PURE__ */ jsxs18("div", { children: [
4458
+ /* @__PURE__ */ jsx20("p", { className: "text-sm font-medium text-destructive", children: "Falha na conex\xE3o" }),
4459
+ oauthResult?.error && /* @__PURE__ */ jsx20("p", { className: "text-xs text-muted-foreground", children: oauthResult.error })
4460
+ ] }),
4461
+ /* @__PURE__ */ jsx20(Button13, { variant: "outline", onClick: onStartOAuth, size: "sm", children: "Tentar novamente" })
4462
+ ] })
4463
+ ] }),
4464
+ /* @__PURE__ */ jsxs18("div", { className: "flex items-start gap-2 rounded-md bg-muted/50 p-3", children: [
4465
+ /* @__PURE__ */ jsx20(
4466
+ Shield,
4467
+ {
4468
+ "aria-hidden": "true",
4469
+ className: "mt-0.5 h-4 w-4 shrink-0 text-green-600"
4470
+ }
4471
+ ),
4472
+ /* @__PURE__ */ jsxs18("p", { className: "text-xs text-muted-foreground", children: [
4473
+ "Seus dados est\xE3o seguros. Usamos OAuth 2.0 para autentica\xE7\xE3o \u2014 nunca armazenamos sua senha. Voc\xEA pode revogar o acesso a qualquer momento nas configura\xE7\xF5es da sua conta ",
4474
+ providerLabel,
4475
+ "."
4476
+ ] })
4477
+ ] })
4478
+ ] });
4479
+ }
4480
+ function ApiKeyCredentials({
4481
+ apiKey,
4482
+ onApiKeyChange
4483
+ }) {
4484
+ return /* @__PURE__ */ jsxs18("div", { className: "space-y-6", children: [
4485
+ /* @__PURE__ */ jsxs18("div", { className: "space-y-2", children: [
4486
+ /* @__PURE__ */ jsx20("h3", { className: "text-lg font-semibold", children: "Autentica\xE7\xE3o" }),
4487
+ /* @__PURE__ */ jsx20("p", { className: "text-sm text-muted-foreground", children: "Insira a chave de API para conectar a integra\xE7\xE3o." })
4488
+ ] }),
4489
+ /* @__PURE__ */ jsxs18("div", { className: "space-y-2", children: [
4490
+ /* @__PURE__ */ jsx20(Label6, { htmlFor: "integration-api-key", children: "Chave de API" }),
4491
+ /* @__PURE__ */ jsx20(
4492
+ Input10,
4493
+ {
4494
+ id: "integration-api-key",
4495
+ type: "password",
4496
+ autoComplete: "off",
4497
+ placeholder: "Insira sua chave de API...",
4498
+ value: apiKey,
4499
+ onChange: (e) => onApiKeyChange(e.target.value)
4500
+ }
4501
+ )
4502
+ ] }),
4503
+ /* @__PURE__ */ jsxs18("div", { className: "flex items-start gap-2 rounded-md bg-muted/50 p-3", children: [
4504
+ /* @__PURE__ */ jsx20(
4505
+ Shield,
4506
+ {
4507
+ "aria-hidden": "true",
4508
+ className: "mt-0.5 h-4 w-4 shrink-0 text-green-600"
4509
+ }
4510
+ ),
4511
+ /* @__PURE__ */ jsx20("p", { className: "text-xs text-muted-foreground", children: "Sua chave de API \xE9 armazenada de forma segura e encriptada. Nunca \xE9 exposta no frontend." })
4512
+ ] })
4513
+ ] });
4514
+ }
4515
+
4516
+ // src/components/capabilities/wizard-steps/config-step.tsx
4517
+ import { Loader2 as Loader27 } from "lucide-react";
4518
+ import {
4519
+ Label as Label7,
4520
+ Select as Select4,
4521
+ SelectContent as SelectContent4,
4522
+ SelectItem as SelectItem4,
4523
+ SelectTrigger as SelectTrigger4,
4524
+ SelectValue as SelectValue4
4525
+ } from "@greatapps/greatauth-ui/ui";
4526
+ import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
4527
+ function ConfigStep({
4528
+ integration,
4529
+ options,
4530
+ isLoading,
4531
+ selectedValue,
4532
+ onValueChange,
4533
+ selectLabel,
4534
+ selectPlaceholder
4535
+ }) {
4536
+ const label = selectLabel || getDefaultLabel(integration.slug);
4537
+ const placeholder = selectPlaceholder || getDefaultPlaceholder(integration.slug);
4538
+ return /* @__PURE__ */ jsxs19("div", { className: "space-y-6", children: [
4539
+ /* @__PURE__ */ jsxs19("div", { className: "space-y-2", children: [
4540
+ /* @__PURE__ */ jsx21("h3", { className: "text-lg font-semibold", children: "Configura\xE7\xE3o" }),
4541
+ /* @__PURE__ */ jsx21("p", { className: "text-sm text-muted-foreground", children: "Configure as op\xE7\xF5es espec\xEDficas da integra\xE7\xE3o." })
4542
+ ] }),
4543
+ isLoading ? /* @__PURE__ */ jsxs19("div", { className: "flex flex-col items-center gap-3 py-8", children: [
4544
+ /* @__PURE__ */ jsx21(
4545
+ Loader27,
4546
+ {
4547
+ "aria-hidden": "true",
4548
+ className: "h-6 w-6 animate-spin text-muted-foreground"
4549
+ }
4550
+ ),
4551
+ /* @__PURE__ */ jsx21("p", { className: "text-sm text-muted-foreground", children: "Carregando op\xE7\xF5es..." })
4552
+ ] }) : options.length === 0 ? /* @__PURE__ */ jsx21("div", { className: "rounded-lg border border-dashed p-6 text-center", children: /* @__PURE__ */ jsx21("p", { className: "text-sm text-muted-foreground", children: "Nenhuma op\xE7\xE3o dispon\xEDvel. A configura\xE7\xE3o padr\xE3o ser\xE1 usada." }) }) : /* @__PURE__ */ jsxs19("div", { className: "space-y-2", children: [
4553
+ /* @__PURE__ */ jsx21(Label7, { htmlFor: "integration-config-select", children: label }),
4554
+ /* @__PURE__ */ jsxs19(Select4, { value: selectedValue, onValueChange, children: [
4555
+ /* @__PURE__ */ jsx21(SelectTrigger4, { id: "integration-config-select", children: /* @__PURE__ */ jsx21(SelectValue4, { placeholder }) }),
4556
+ /* @__PURE__ */ jsx21(SelectContent4, { children: options.map((opt) => /* @__PURE__ */ jsxs19(SelectItem4, { value: opt.id, children: [
4557
+ /* @__PURE__ */ jsx21("span", { children: opt.label }),
4558
+ opt.description && /* @__PURE__ */ jsxs19("span", { className: "ml-2 text-xs text-muted-foreground", children: [
4559
+ "(",
4560
+ opt.description,
4561
+ ")"
4562
+ ] })
4563
+ ] }, opt.id)) })
4564
+ ] })
4565
+ ] })
4566
+ ] });
4567
+ }
4568
+ function getDefaultLabel(slug) {
4569
+ switch (slug) {
4570
+ case "google_calendar":
4571
+ return "Calend\xE1rio";
4572
+ default:
4573
+ return "Op\xE7\xE3o";
4574
+ }
4575
+ }
4576
+ function getDefaultPlaceholder(slug) {
4577
+ switch (slug) {
4578
+ case "google_calendar":
4579
+ return "Selecione o calend\xE1rio...";
4580
+ default:
4581
+ return "Selecione uma op\xE7\xE3o...";
4582
+ }
4583
+ }
4584
+
4585
+ // src/components/capabilities/wizard-steps/confirm-step.tsx
4586
+ import { CheckCircle2 as CheckCircle22 } from "lucide-react";
4587
+ import { Label as Label8 } from "@greatapps/greatauth-ui/ui";
4588
+ import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
4589
+ function ConfirmStep({
4590
+ integration,
4591
+ oauthResult,
4592
+ selectedConfigOption,
4593
+ enableOnComplete,
4594
+ onEnableChange
4595
+ }) {
4596
+ return /* @__PURE__ */ jsxs20("div", { className: "space-y-6", children: [
4597
+ /* @__PURE__ */ jsxs20("div", { className: "space-y-2", children: [
4598
+ /* @__PURE__ */ jsx22("h3", { className: "text-lg font-semibold", children: "Confirma\xE7\xE3o" }),
4599
+ /* @__PURE__ */ jsx22("p", { className: "text-sm text-muted-foreground", children: "Revise as configura\xE7\xF5es antes de concluir." })
4600
+ ] }),
4601
+ /* @__PURE__ */ jsxs20("div", { className: "space-y-3 rounded-lg border p-4", children: [
4602
+ /* @__PURE__ */ jsx22(SummaryRow, { label: "Integra\xE7\xE3o", value: integration.name }),
4603
+ oauthResult?.email && /* @__PURE__ */ jsx22(SummaryRow, { label: "Conta conectada", value: oauthResult.email }),
4604
+ selectedConfigOption && /* @__PURE__ */ jsx22(
4605
+ SummaryRow,
4606
+ {
4607
+ label: getConfigLabel(integration.slug),
4608
+ value: selectedConfigOption.label
4609
+ }
4610
+ ),
4611
+ /* @__PURE__ */ jsx22(
4612
+ SummaryRow,
4613
+ {
4614
+ label: "Tipo de autentica\xE7\xE3o",
4615
+ value: integration.authType === "oauth2" ? "OAuth 2.0" : "API Key"
4616
+ }
4617
+ )
4618
+ ] }),
4619
+ /* @__PURE__ */ jsxs20("div", { className: "flex items-center justify-between rounded-lg border p-4", children: [
4620
+ /* @__PURE__ */ jsxs20("div", { className: "space-y-0.5", children: [
4621
+ /* @__PURE__ */ jsx22(Label8, { htmlFor: "enable-on-complete", className: "text-sm font-medium", children: "Ativar imediatamente" }),
4622
+ /* @__PURE__ */ jsx22("p", { className: "text-xs text-muted-foreground", children: "A integra\xE7\xE3o ficar\xE1 ativa assim que concluir o assistente." })
4623
+ ] }),
4624
+ /* @__PURE__ */ jsx22(
4625
+ "button",
4626
+ {
4627
+ id: "enable-on-complete",
4628
+ role: "switch",
4629
+ type: "button",
4630
+ "aria-checked": enableOnComplete,
4631
+ onClick: () => onEnableChange(!enableOnComplete),
4632
+ className: `
4633
+ relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent
4634
+ transition-colors duration-200 ease-in-out focus-visible:outline-none focus-visible:ring-2
4635
+ focus-visible:ring-ring focus-visible:ring-offset-2
4636
+ ${enableOnComplete ? "bg-primary" : "bg-muted"}
4637
+ `,
4638
+ children: /* @__PURE__ */ jsx22(
4639
+ "span",
4640
+ {
4641
+ "aria-hidden": "true",
4642
+ className: `
4643
+ pointer-events-none inline-block h-5 w-5 transform rounded-full bg-background shadow-lg
4644
+ ring-0 transition duration-200 ease-in-out
4645
+ ${enableOnComplete ? "translate-x-5" : "translate-x-0"}
4646
+ `
4647
+ }
4648
+ )
4649
+ }
4650
+ )
4651
+ ] }),
4652
+ /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-2 rounded-md bg-green-50 p-3 dark:bg-green-950/20", children: [
4653
+ /* @__PURE__ */ jsx22(
4654
+ CheckCircle22,
4655
+ {
4656
+ "aria-hidden": "true",
4657
+ className: "h-4 w-4 shrink-0 text-green-600"
4658
+ }
4659
+ ),
4660
+ /* @__PURE__ */ jsx22("p", { className: "text-xs text-green-700 dark:text-green-400", children: 'Tudo pronto! Clique em "Concluir" para finalizar a configura\xE7\xE3o.' })
4661
+ ] })
4662
+ ] });
4663
+ }
4664
+ function SummaryRow({ label, value }) {
4665
+ return /* @__PURE__ */ jsxs20("div", { className: "flex items-center justify-between text-sm", children: [
4666
+ /* @__PURE__ */ jsx22("span", { className: "text-muted-foreground", children: label }),
4667
+ /* @__PURE__ */ jsx22("span", { className: "font-medium", children: value })
4668
+ ] });
4669
+ }
4670
+ function getConfigLabel(slug) {
4671
+ switch (slug) {
4672
+ case "google_calendar":
4673
+ return "Calend\xE1rio";
4674
+ default:
4675
+ return "Configura\xE7\xE3o";
4676
+ }
4677
+ }
4678
+
4679
+ // src/components/capabilities/integration-wizard.tsx
4680
+ import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
4681
+ var STEPS = ["info", "credentials", "config", "confirm"];
4682
+ var STEP_LABELS = {
4683
+ info: "Informa\xE7\xE3o",
4684
+ credentials: "Credenciais",
4685
+ config: "Configura\xE7\xE3o",
4686
+ confirm: "Confirma\xE7\xE3o"
4687
+ };
4688
+ function IntegrationWizard({
4689
+ open,
4690
+ onOpenChange,
4691
+ integration,
4692
+ meta,
4693
+ agentId: _agentId,
4694
+ config,
4695
+ onComplete,
4696
+ gagentsApiUrl,
4697
+ existingCredentialId,
4698
+ loadConfigOptions,
4699
+ existingConfigValue
4700
+ }) {
4701
+ const isReconnect = !!existingCredentialId;
4702
+ const [currentStep, setCurrentStep] = useState14("info");
4703
+ const currentIndex = STEPS.indexOf(currentStep);
4704
+ const [oauthStatus, setOauthStatus] = useState14("idle");
4705
+ const [oauthResult, setOauthResult] = useState14(null);
4706
+ const popupRef = useRef3(null);
4707
+ const popupPollRef = useRef3(null);
4708
+ const [apiKey, setApiKey] = useState14("");
4709
+ const [configOptions, setConfigOptions] = useState14([]);
4710
+ const [configLoading, setConfigLoading] = useState14(false);
4711
+ const [selectedConfigValue, setSelectedConfigValue] = useState14("");
4712
+ const [enableOnComplete, setEnableOnComplete] = useState14(true);
4713
+ const [isSubmitting, setIsSubmitting] = useState14(false);
4714
+ useEffect5(() => {
4715
+ return () => {
4716
+ if (popupPollRef.current) {
4717
+ clearInterval(popupPollRef.current);
4718
+ }
4719
+ };
4720
+ }, []);
4721
+ useEffect5(() => {
4722
+ if (open) {
4723
+ setCurrentStep("info");
4724
+ setOauthStatus("idle");
4725
+ setOauthResult(null);
4726
+ setApiKey("");
4727
+ setConfigOptions([]);
4728
+ setConfigLoading(false);
4729
+ setSelectedConfigValue(existingConfigValue ?? "");
4730
+ setEnableOnComplete(true);
4731
+ setIsSubmitting(false);
4732
+ } else {
4733
+ if (popupRef.current && !popupRef.current.closed) {
4734
+ popupRef.current.close();
4735
+ }
4736
+ if (popupPollRef.current) {
4737
+ clearInterval(popupPollRef.current);
4738
+ popupPollRef.current = null;
4739
+ }
4740
+ }
4741
+ }, [open]);
4742
+ const handleOAuthMessage = useCallback5(
4743
+ (event) => {
4744
+ try {
4745
+ if (event.origin !== new URL(gagentsApiUrl).origin) return;
4746
+ } catch {
4747
+ return;
4748
+ }
4749
+ if (!event.data || typeof event.data !== "object") return;
4750
+ const msg = event.data;
4751
+ if (msg.type !== "oauth-callback") return;
4752
+ if (msg.success) {
4753
+ setOauthStatus("success");
4754
+ setOauthResult({
4755
+ success: true,
4756
+ email: msg.email,
4757
+ credentialId: msg.credentialId
4758
+ });
4759
+ const credId = msg.credentialId || existingCredentialId;
4760
+ if (credId && loadConfigOptions && meta.hasConfigStep) {
4761
+ setConfigLoading(true);
4762
+ loadConfigOptions(credId).then((opts) => {
4763
+ setConfigOptions(opts);
4764
+ if (opts.length === 1) {
4765
+ setSelectedConfigValue(opts[0].id);
4766
+ }
4767
+ }).catch(() => setConfigOptions([])).finally(() => setConfigLoading(false));
4768
+ }
4769
+ setTimeout(() => {
4770
+ setCurrentStep(meta.hasConfigStep ? "config" : "confirm");
4771
+ }, 1200);
4772
+ } else {
4773
+ setOauthStatus("error");
4774
+ setOauthResult({
4775
+ success: false,
4776
+ error: msg.error || "Falha na autoriza\xE7\xE3o"
4777
+ });
4778
+ }
4779
+ },
4780
+ [gagentsApiUrl, existingCredentialId, meta.hasConfigStep, loadConfigOptions]
4781
+ );
4782
+ useEffect5(() => {
4783
+ if (!open) return;
4784
+ window.addEventListener("message", handleOAuthMessage);
4785
+ return () => window.removeEventListener("message", handleOAuthMessage);
4786
+ }, [open, handleOAuthMessage]);
4787
+ function startOAuth() {
4788
+ const { language = "pt-br", idWl = 1, accountId } = config;
4789
+ const redirectUri = `${window.location.origin}/oauth/callback`;
4790
+ const url = new URL(
4791
+ `${gagentsApiUrl}/v1/${language}/${idWl}/accounts/${accountId}/oauth/authorize/${integration.slug}`
4792
+ );
4793
+ url.searchParams.set("redirect_uri", redirectUri);
4794
+ setOauthStatus("waiting");
4795
+ const popup = window.open(
4796
+ url.toString(),
4797
+ "oauth-popup",
4798
+ "width=500,height=600,scrollbars=yes,resizable=yes"
4799
+ );
4800
+ popupRef.current = popup;
4801
+ if (popup) {
4802
+ if (popupPollRef.current) {
4803
+ clearInterval(popupPollRef.current);
4804
+ }
4805
+ popupPollRef.current = setInterval(() => {
4806
+ if (popup.closed) {
4807
+ if (popupPollRef.current) {
4808
+ clearInterval(popupPollRef.current);
4809
+ popupPollRef.current = null;
4810
+ }
4811
+ setOauthStatus(
4812
+ (prev) => prev === "waiting" ? "error" : prev
4813
+ );
4814
+ setOauthResult(
4815
+ (prev) => prev === null ? { success: false, error: "Janela fechada antes de concluir" } : prev
4816
+ );
4817
+ }
4818
+ }, 500);
4819
+ }
4820
+ }
4821
+ function canAdvance() {
4822
+ switch (currentStep) {
4823
+ case "info":
4824
+ return true;
4825
+ case "credentials":
4826
+ if (integration.authType === "oauth2") {
4827
+ return oauthStatus === "success";
4828
+ }
4829
+ return apiKey.trim().length > 0;
4830
+ case "config":
4831
+ return true;
4832
+ case "confirm":
4833
+ return true;
4834
+ default:
4835
+ return false;
4836
+ }
4837
+ }
4838
+ function goNext() {
4839
+ if (!canAdvance()) return;
4840
+ if (currentStep === "credentials" && !meta.hasConfigStep) {
4841
+ setCurrentStep("confirm");
4842
+ return;
4843
+ }
4844
+ const nextIndex = currentIndex + 1;
4845
+ if (nextIndex < STEPS.length) {
4846
+ setCurrentStep(STEPS[nextIndex]);
4847
+ }
4848
+ }
4849
+ function goPrev() {
4850
+ if (currentStep === "confirm" && !meta.hasConfigStep) {
4851
+ setCurrentStep("credentials");
4852
+ return;
4853
+ }
4854
+ const prevIndex = currentIndex - 1;
4855
+ if (prevIndex >= 0) {
4856
+ setCurrentStep(STEPS[prevIndex]);
4857
+ }
4858
+ }
4859
+ async function handleComplete() {
4860
+ setIsSubmitting(true);
4861
+ try {
4862
+ onComplete();
4863
+ onOpenChange(false);
4864
+ toast11.success(
4865
+ `${integration.name} ${isReconnect ? "reconectado" : "configurado"} com sucesso!`
4866
+ );
4867
+ } catch {
4868
+ toast11.error("Erro ao finalizar configura\xE7\xE3o");
4869
+ } finally {
4870
+ setIsSubmitting(false);
4871
+ }
4872
+ }
4873
+ const selectedConfigOption = configOptions.find((o) => o.id === selectedConfigValue) || null;
4874
+ const isLastStep = currentStep === "confirm";
4875
+ const effectiveSteps = meta.hasConfigStep ? STEPS : STEPS.filter((s) => s !== "config");
4876
+ return /* @__PURE__ */ jsx23(Dialog7, { open, onOpenChange, children: /* @__PURE__ */ jsxs21(DialogContent7, { className: "sm:max-w-lg", children: [
4877
+ /* @__PURE__ */ jsx23(DialogHeader7, { children: /* @__PURE__ */ jsx23(DialogTitle7, { children: integration.name }) }),
4878
+ /* @__PURE__ */ jsx23(StepIndicator, { steps: effectiveSteps, currentStep }),
4879
+ /* @__PURE__ */ jsxs21("div", { className: "min-h-[280px] py-2", children: [
4880
+ currentStep === "info" && /* @__PURE__ */ jsx23(
4881
+ InfoStep,
4882
+ {
4883
+ integration,
4884
+ meta
4885
+ }
4886
+ ),
4887
+ currentStep === "credentials" && /* @__PURE__ */ jsx23(
4888
+ CredentialsStep,
4889
+ {
4890
+ integration,
4891
+ meta,
4892
+ oauthStatus,
4893
+ oauthResult,
4894
+ apiKey,
4895
+ onApiKeyChange: setApiKey,
4896
+ onStartOAuth: startOAuth,
4897
+ isReconnect
4898
+ }
4899
+ ),
4900
+ currentStep === "config" && /* @__PURE__ */ jsx23(
4901
+ ConfigStep,
4902
+ {
4903
+ integration,
4904
+ options: configOptions,
4905
+ isLoading: configLoading,
4906
+ selectedValue: selectedConfigValue,
4907
+ onValueChange: setSelectedConfigValue
4908
+ }
4909
+ ),
4910
+ currentStep === "confirm" && /* @__PURE__ */ jsx23(
4911
+ ConfirmStep,
4912
+ {
4913
+ integration,
4914
+ oauthResult,
4915
+ selectedConfigOption,
4916
+ enableOnComplete,
4917
+ onEnableChange: setEnableOnComplete
4918
+ }
4919
+ )
4920
+ ] }),
4921
+ /* @__PURE__ */ jsxs21(DialogFooter7, { className: "flex-row justify-between sm:justify-between", children: [
4922
+ /* @__PURE__ */ jsx23("div", { children: currentStep === "info" ? /* @__PURE__ */ jsx23(
4923
+ Button14,
4924
+ {
4925
+ type: "button",
4926
+ variant: "outline",
4927
+ onClick: () => onOpenChange(false),
4928
+ children: "Cancelar"
4929
+ }
4930
+ ) : /* @__PURE__ */ jsxs21(
4931
+ Button14,
4932
+ {
4933
+ type: "button",
4934
+ variant: "outline",
4935
+ onClick: goPrev,
4936
+ className: "gap-1",
4937
+ children: [
4938
+ /* @__PURE__ */ jsx23(ChevronLeft, { "aria-hidden": "true", className: "h-4 w-4" }),
4939
+ "Voltar"
4940
+ ]
4941
+ }
4942
+ ) }),
4943
+ /* @__PURE__ */ jsx23("div", { children: isLastStep ? /* @__PURE__ */ jsxs21(
4944
+ Button14,
4945
+ {
4946
+ type: "button",
4947
+ onClick: handleComplete,
4948
+ disabled: isSubmitting,
4949
+ className: "gap-1",
4950
+ children: [
4951
+ isSubmitting ? /* @__PURE__ */ jsx23(
4952
+ Loader28,
4953
+ {
4954
+ "aria-hidden": "true",
4955
+ className: "h-4 w-4 animate-spin"
4956
+ }
4957
+ ) : /* @__PURE__ */ jsx23(Check2, { "aria-hidden": "true", className: "h-4 w-4" }),
4958
+ "Concluir"
4959
+ ]
4960
+ }
4961
+ ) : /* @__PURE__ */ jsxs21(
4962
+ Button14,
4963
+ {
4964
+ type: "button",
4965
+ onClick: goNext,
4966
+ disabled: !canAdvance(),
4967
+ className: "gap-1",
4968
+ children: [
4969
+ "Continuar",
4970
+ /* @__PURE__ */ jsx23(ChevronRight, { "aria-hidden": "true", className: "h-4 w-4" })
4971
+ ]
4972
+ }
4973
+ ) })
4974
+ ] })
4975
+ ] }) });
4976
+ }
4977
+ function StepIndicator({
4978
+ steps,
4979
+ currentStep
4980
+ }) {
4981
+ const currentIndex = steps.indexOf(currentStep);
4982
+ return /* @__PURE__ */ jsx23(
4983
+ "div",
4984
+ {
4985
+ className: "flex items-center justify-center gap-1 py-2",
4986
+ role: "list",
4987
+ "aria-label": "Passos do assistente",
4988
+ children: steps.map((step, i) => {
4989
+ const isCompleted = i < currentIndex;
4990
+ const isCurrent = step === currentStep;
4991
+ return /* @__PURE__ */ jsxs21("div", { className: "flex items-center", role: "listitem", children: [
4992
+ /* @__PURE__ */ jsx23(
4993
+ "div",
4994
+ {
4995
+ className: `
4996
+ flex h-7 w-7 items-center justify-center rounded-full text-xs font-medium
4997
+ transition-colors duration-200
4998
+ ${isCurrent ? "bg-primary text-primary-foreground" : isCompleted ? "bg-green-600 text-white" : "bg-muted text-muted-foreground"}
4999
+ `,
5000
+ "aria-current": isCurrent ? "step" : void 0,
5001
+ "aria-label": `${STEP_LABELS[step]}${isCompleted ? " (conclu\xEDdo)" : isCurrent ? " (atual)" : ""}`,
5002
+ children: isCompleted ? /* @__PURE__ */ jsx23(Check2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }) : i + 1
5003
+ }
5004
+ ),
5005
+ /* @__PURE__ */ jsx23(
5006
+ "span",
5007
+ {
5008
+ className: `
5009
+ ml-1.5 hidden text-xs sm:inline
5010
+ ${isCurrent ? "font-medium text-foreground" : "text-muted-foreground"}
5011
+ `,
5012
+ children: STEP_LABELS[step]
5013
+ }
5014
+ ),
5015
+ i < steps.length - 1 && /* @__PURE__ */ jsx23(
5016
+ "div",
5017
+ {
5018
+ className: `
5019
+ mx-2 h-px w-6
5020
+ ${i < currentIndex ? "bg-green-600" : "bg-border"}
5021
+ `
5022
+ }
5023
+ )
5024
+ ] }, step);
5025
+ })
5026
+ }
5027
+ );
5028
+ }
5029
+
3653
5030
  // src/pages/agents-page.tsx
3654
- import { useState as useState12 } from "react";
3655
- import { Button as Button11 } from "@greatapps/greatauth-ui/ui";
5031
+ import { useState as useState15 } from "react";
5032
+ import { Button as Button15 } from "@greatapps/greatauth-ui/ui";
3656
5033
  import { Plus as Plus3 } from "lucide-react";
3657
- import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
5034
+ import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
3658
5035
  function AgentsPage({
3659
5036
  config,
3660
5037
  onNavigateToAgent,
3661
5038
  title = "Agentes AI",
3662
5039
  subtitle = "Gerencie seus agentes de atendimento inteligente"
3663
5040
  }) {
3664
- const [createOpen, setCreateOpen] = useState12(false);
3665
- return /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
3666
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between", children: [
3667
- /* @__PURE__ */ jsxs13("div", { children: [
3668
- /* @__PURE__ */ jsx15("h1", { className: "text-xl font-semibold", children: title }),
3669
- /* @__PURE__ */ jsx15("p", { className: "text-sm text-muted-foreground", children: subtitle })
5041
+ const [createOpen, setCreateOpen] = useState15(false);
5042
+ return /* @__PURE__ */ jsxs22("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
5043
+ /* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-between", children: [
5044
+ /* @__PURE__ */ jsxs22("div", { children: [
5045
+ /* @__PURE__ */ jsx24("h1", { className: "text-xl font-semibold", children: title }),
5046
+ /* @__PURE__ */ jsx24("p", { className: "text-sm text-muted-foreground", children: subtitle })
3670
5047
  ] }),
3671
- /* @__PURE__ */ jsxs13(Button11, { onClick: () => setCreateOpen(true), size: "sm", children: [
3672
- /* @__PURE__ */ jsx15(Plus3, { className: "mr-2 h-4 w-4" }),
5048
+ /* @__PURE__ */ jsxs22(Button15, { onClick: () => setCreateOpen(true), size: "sm", children: [
5049
+ /* @__PURE__ */ jsx24(Plus3, { className: "mr-2 h-4 w-4" }),
3673
5050
  "Novo Agente"
3674
5051
  ] })
3675
5052
  ] }),
3676
- /* @__PURE__ */ jsx15(AgentsTable, { config, onNavigateToAgent }),
3677
- /* @__PURE__ */ jsx15(
5053
+ /* @__PURE__ */ jsx24(AgentsTable, { config, onNavigateToAgent }),
5054
+ /* @__PURE__ */ jsx24(
3678
5055
  AgentFormDialog,
3679
5056
  {
3680
5057
  config,
@@ -3686,11 +5063,11 @@ function AgentsPage({
3686
5063
  }
3687
5064
 
3688
5065
  // src/pages/agent-detail-page.tsx
3689
- import { useState as useState13 } from "react";
3690
- import { Badge as Badge8, Button as Button12, Skeleton as Skeleton6 } from "@greatapps/greatauth-ui/ui";
5066
+ import { useState as useState16 } from "react";
5067
+ import { Badge as Badge10, Button as Button16, Skeleton as Skeleton7 } from "@greatapps/greatauth-ui/ui";
3691
5068
  import { EntityAvatar as EntityAvatar2 } from "@greatapps/greatauth-ui";
3692
5069
  import { ArrowLeft, Pencil as Pencil5 } from "lucide-react";
3693
- import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
5070
+ import { jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
3694
5071
  function AgentDetailPage({
3695
5072
  config,
3696
5073
  agentId,
@@ -3698,43 +5075,43 @@ function AgentDetailPage({
3698
5075
  renderChatLink
3699
5076
  }) {
3700
5077
  const { data: agent, isLoading } = useAgent(config, agentId);
3701
- const [editOpen, setEditOpen] = useState13(false);
5078
+ const [editOpen, setEditOpen] = useState16(false);
3702
5079
  if (isLoading) {
3703
- return /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-4 p-4", children: [
3704
- /* @__PURE__ */ jsx16(Skeleton6, { className: "h-4 w-32" }),
3705
- /* @__PURE__ */ jsx16(Skeleton6, { className: "h-8 w-48" }),
3706
- /* @__PURE__ */ jsx16(Skeleton6, { className: "h-10 w-full" }),
3707
- /* @__PURE__ */ jsx16(Skeleton6, { className: "h-64 w-full" })
5080
+ return /* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-4 p-4", children: [
5081
+ /* @__PURE__ */ jsx25(Skeleton7, { className: "h-4 w-32" }),
5082
+ /* @__PURE__ */ jsx25(Skeleton7, { className: "h-8 w-48" }),
5083
+ /* @__PURE__ */ jsx25(Skeleton7, { className: "h-10 w-full" }),
5084
+ /* @__PURE__ */ jsx25(Skeleton7, { className: "h-64 w-full" })
3708
5085
  ] });
3709
5086
  }
3710
5087
  if (!agent) {
3711
- return /* @__PURE__ */ jsxs14("div", { className: "flex flex-col items-center justify-center gap-2 p-8", children: [
3712
- /* @__PURE__ */ jsx16("p", { className: "text-muted-foreground", children: "Agente n\xE3o encontrado" }),
3713
- onBack && /* @__PURE__ */ jsxs14(Button12, { variant: "ghost", size: "sm", onClick: onBack, children: [
3714
- /* @__PURE__ */ jsx16(ArrowLeft, { className: "mr-2 h-4 w-4" }),
5088
+ return /* @__PURE__ */ jsxs23("div", { className: "flex flex-col items-center justify-center gap-2 p-8", children: [
5089
+ /* @__PURE__ */ jsx25("p", { className: "text-muted-foreground", children: "Agente n\xE3o encontrado" }),
5090
+ onBack && /* @__PURE__ */ jsxs23(Button16, { variant: "ghost", size: "sm", onClick: onBack, children: [
5091
+ /* @__PURE__ */ jsx25(ArrowLeft, { className: "mr-2 h-4 w-4" }),
3715
5092
  "Voltar para agentes"
3716
5093
  ] })
3717
5094
  ] });
3718
5095
  }
3719
- return /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-6 p-4 md:p-6", children: [
3720
- /* @__PURE__ */ jsx16("div", { className: "rounded-lg border p-4 md:p-6", children: /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-4 md:flex-row md:items-start md:gap-6", children: [
3721
- /* @__PURE__ */ jsxs14("div", { className: "flex items-start gap-3 flex-1", children: [
3722
- onBack && /* @__PURE__ */ jsx16(
3723
- Button12,
5096
+ return /* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-6 p-4 md:p-6", children: [
5097
+ /* @__PURE__ */ jsx25("div", { className: "rounded-lg border p-4 md:p-6", children: /* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-4 md:flex-row md:items-start md:gap-6", children: [
5098
+ /* @__PURE__ */ jsxs23("div", { className: "flex items-start gap-3 flex-1", children: [
5099
+ onBack && /* @__PURE__ */ jsx25(
5100
+ Button16,
3724
5101
  {
3725
5102
  variant: "ghost",
3726
5103
  size: "icon",
3727
5104
  "aria-label": "Voltar",
3728
5105
  className: "shrink-0 mt-1",
3729
5106
  onClick: onBack,
3730
- children: /* @__PURE__ */ jsx16(ArrowLeft, { className: "h-4 w-4" })
5107
+ children: /* @__PURE__ */ jsx25(ArrowLeft, { className: "h-4 w-4" })
3731
5108
  }
3732
5109
  ),
3733
- /* @__PURE__ */ jsx16(EntityAvatar2, { photo: agent.photo, name: agent.title, size: "xl" }),
3734
- /* @__PURE__ */ jsx16("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2 flex-wrap", children: [
3735
- /* @__PURE__ */ jsx16("h1", { className: "text-xl font-semibold", children: agent.title }),
3736
- /* @__PURE__ */ jsx16(
3737
- Badge8,
5110
+ /* @__PURE__ */ jsx25(EntityAvatar2, { photo: agent.photo, name: agent.title, size: "xl" }),
5111
+ /* @__PURE__ */ jsx25("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-2 flex-wrap", children: [
5112
+ /* @__PURE__ */ jsx25("h1", { className: "text-xl font-semibold", children: agent.title }),
5113
+ /* @__PURE__ */ jsx25(
5114
+ Badge10,
3738
5115
  {
3739
5116
  variant: agent.active ? "default" : "destructive",
3740
5117
  className: "text-xs",
@@ -3743,21 +5120,21 @@ function AgentDetailPage({
3743
5120
  )
3744
5121
  ] }) })
3745
5122
  ] }),
3746
- /* @__PURE__ */ jsxs14(
3747
- Button12,
5123
+ /* @__PURE__ */ jsxs23(
5124
+ Button16,
3748
5125
  {
3749
5126
  variant: "outline",
3750
5127
  size: "sm",
3751
5128
  className: "shrink-0 self-start",
3752
5129
  onClick: () => setEditOpen(true),
3753
5130
  children: [
3754
- /* @__PURE__ */ jsx16(Pencil5, { className: "mr-2 h-4 w-4" }),
5131
+ /* @__PURE__ */ jsx25(Pencil5, { className: "mr-2 h-4 w-4" }),
3755
5132
  "Editar"
3756
5133
  ]
3757
5134
  }
3758
5135
  )
3759
5136
  ] }) }),
3760
- /* @__PURE__ */ jsx16(
5137
+ /* @__PURE__ */ jsx25(
3761
5138
  AgentTabs,
3762
5139
  {
3763
5140
  agent,
@@ -3765,7 +5142,7 @@ function AgentDetailPage({
3765
5142
  renderChatLink
3766
5143
  }
3767
5144
  ),
3768
- editOpen && /* @__PURE__ */ jsx16(
5145
+ editOpen && /* @__PURE__ */ jsx25(
3769
5146
  AgentEditForm,
3770
5147
  {
3771
5148
  agent,
@@ -3778,31 +5155,133 @@ function AgentDetailPage({
3778
5155
  ] });
3779
5156
  }
3780
5157
 
5158
+ // src/pages/agent-capabilities-page.tsx
5159
+ import { useState as useState17, useCallback as useCallback6 } from "react";
5160
+ import {
5161
+ Tabs as Tabs2,
5162
+ TabsList as TabsList2,
5163
+ TabsTrigger as TabsTrigger2,
5164
+ TabsContent as TabsContent2
5165
+ } from "@greatapps/greatauth-ui/ui";
5166
+ import { Blocks, Plug as Plug3, Settings as Settings4 } from "lucide-react";
5167
+ import { jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
5168
+ function defaultResolveWizardMeta(card) {
5169
+ return {
5170
+ capabilities: [
5171
+ { label: card.definition.name, description: card.definition.description }
5172
+ ],
5173
+ requirements: [],
5174
+ hasConfigStep: false
5175
+ };
5176
+ }
5177
+ function AgentCapabilitiesPage({
5178
+ config,
5179
+ agentId,
5180
+ gagentsApiUrl,
5181
+ resolveWizardMeta = defaultResolveWizardMeta,
5182
+ loadConfigOptions,
5183
+ onWizardComplete
5184
+ }) {
5185
+ const [wizardOpen, setWizardOpen] = useState17(false);
5186
+ const [activeCard, setActiveCard] = useState17(null);
5187
+ const handleConnect = useCallback6(
5188
+ (card) => {
5189
+ setActiveCard(card);
5190
+ setWizardOpen(true);
5191
+ },
5192
+ []
5193
+ );
5194
+ const handleWizardComplete = useCallback6(() => {
5195
+ setWizardOpen(false);
5196
+ setActiveCard(null);
5197
+ onWizardComplete?.();
5198
+ }, [onWizardComplete]);
5199
+ const handleWizardOpenChange = useCallback6((open) => {
5200
+ setWizardOpen(open);
5201
+ if (!open) setActiveCard(null);
5202
+ }, []);
5203
+ const wizardMeta = activeCard ? resolveWizardMeta(activeCard) : null;
5204
+ return /* @__PURE__ */ jsxs24("div", { className: "space-y-4", children: [
5205
+ /* @__PURE__ */ jsxs24("div", { children: [
5206
+ /* @__PURE__ */ jsx26("h2", { className: "text-lg font-semibold", children: "Capacidades e Integra\xE7\xF5es" }),
5207
+ /* @__PURE__ */ jsx26("p", { className: "text-sm text-muted-foreground", children: "Configure o que este agente pode fazer e quais servi\xE7os externos ele utiliza." })
5208
+ ] }),
5209
+ /* @__PURE__ */ jsxs24(Tabs2, { defaultValue: "capacidades", children: [
5210
+ /* @__PURE__ */ jsxs24(TabsList2, { children: [
5211
+ /* @__PURE__ */ jsxs24(TabsTrigger2, { value: "capacidades", className: "flex items-center gap-1.5", children: [
5212
+ /* @__PURE__ */ jsx26(Blocks, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
5213
+ "Capacidades"
5214
+ ] }),
5215
+ /* @__PURE__ */ jsxs24(TabsTrigger2, { value: "integracoes", className: "flex items-center gap-1.5", children: [
5216
+ /* @__PURE__ */ jsx26(Plug3, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
5217
+ "Integra\xE7\xF5es"
5218
+ ] }),
5219
+ /* @__PURE__ */ jsxs24(TabsTrigger2, { value: "avancado", className: "flex items-center gap-1.5", children: [
5220
+ /* @__PURE__ */ jsx26(Settings4, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
5221
+ "Avan\xE7ado"
5222
+ ] })
5223
+ ] }),
5224
+ /* @__PURE__ */ jsx26(TabsContent2, { value: "capacidades", className: "mt-4", children: /* @__PURE__ */ jsx26(CapabilitiesTab, { config, agentId }) }),
5225
+ /* @__PURE__ */ jsx26(TabsContent2, { value: "integracoes", className: "mt-4", children: /* @__PURE__ */ jsx26(
5226
+ IntegrationsTab,
5227
+ {
5228
+ config,
5229
+ agentId,
5230
+ onConnect: handleConnect
5231
+ }
5232
+ ) }),
5233
+ /* @__PURE__ */ jsx26(TabsContent2, { value: "avancado", className: "mt-4", children: /* @__PURE__ */ jsx26(
5234
+ AdvancedTab,
5235
+ {
5236
+ config,
5237
+ agentId,
5238
+ gagentsApiUrl
5239
+ }
5240
+ ) })
5241
+ ] }),
5242
+ activeCard && wizardMeta && /* @__PURE__ */ jsx26(
5243
+ IntegrationWizard,
5244
+ {
5245
+ open: wizardOpen,
5246
+ onOpenChange: handleWizardOpenChange,
5247
+ integration: activeCard.definition,
5248
+ meta: wizardMeta,
5249
+ agentId,
5250
+ config,
5251
+ onComplete: handleWizardComplete,
5252
+ gagentsApiUrl,
5253
+ existingCredentialId: activeCard.credential?.id,
5254
+ loadConfigOptions
5255
+ }
5256
+ )
5257
+ ] });
5258
+ }
5259
+
3781
5260
  // src/pages/tools-page.tsx
3782
- import { useState as useState14 } from "react";
3783
- import { Button as Button13 } from "@greatapps/greatauth-ui/ui";
5261
+ import { useState as useState18 } from "react";
5262
+ import { Button as Button17 } from "@greatapps/greatauth-ui/ui";
3784
5263
  import { Plus as Plus4 } from "lucide-react";
3785
- import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
5264
+ import { jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
3786
5265
  function ToolsPage({
3787
5266
  config,
3788
5267
  title = "Ferramentas",
3789
5268
  subtitle = "Gerencie as ferramentas dispon\xEDveis para seus agentes"
3790
5269
  }) {
3791
- const [createOpen, setCreateOpen] = useState14(false);
3792
- const [editTool, setEditTool] = useState14(void 0);
3793
- return /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
3794
- /* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
3795
- /* @__PURE__ */ jsxs15("div", { children: [
3796
- /* @__PURE__ */ jsx17("h1", { className: "text-xl font-semibold", children: title }),
3797
- /* @__PURE__ */ jsx17("p", { className: "text-sm text-muted-foreground", children: subtitle })
5270
+ const [createOpen, setCreateOpen] = useState18(false);
5271
+ const [editTool, setEditTool] = useState18(void 0);
5272
+ return /* @__PURE__ */ jsxs25("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
5273
+ /* @__PURE__ */ jsxs25("div", { className: "flex items-center justify-between", children: [
5274
+ /* @__PURE__ */ jsxs25("div", { children: [
5275
+ /* @__PURE__ */ jsx27("h1", { className: "text-xl font-semibold", children: title }),
5276
+ /* @__PURE__ */ jsx27("p", { className: "text-sm text-muted-foreground", children: subtitle })
3798
5277
  ] }),
3799
- /* @__PURE__ */ jsxs15(Button13, { onClick: () => setCreateOpen(true), size: "sm", children: [
3800
- /* @__PURE__ */ jsx17(Plus4, { className: "mr-2 h-4 w-4" }),
5278
+ /* @__PURE__ */ jsxs25(Button17, { onClick: () => setCreateOpen(true), size: "sm", children: [
5279
+ /* @__PURE__ */ jsx27(Plus4, { className: "mr-2 h-4 w-4" }),
3801
5280
  "Nova Ferramenta"
3802
5281
  ] })
3803
5282
  ] }),
3804
- /* @__PURE__ */ jsx17(ToolsTable, { config, onEdit: (tool) => setEditTool(tool) }),
3805
- /* @__PURE__ */ jsx17(
5283
+ /* @__PURE__ */ jsx27(ToolsTable, { config, onEdit: (tool) => setEditTool(tool) }),
5284
+ /* @__PURE__ */ jsx27(
3806
5285
  ToolFormDialog,
3807
5286
  {
3808
5287
  config,
@@ -3810,7 +5289,7 @@ function ToolsPage({
3810
5289
  onOpenChange: setCreateOpen
3811
5290
  }
3812
5291
  ),
3813
- /* @__PURE__ */ jsx17(
5292
+ /* @__PURE__ */ jsx27(
3814
5293
  ToolFormDialog,
3815
5294
  {
3816
5295
  config,
@@ -3823,10 +5302,10 @@ function ToolsPage({
3823
5302
  }
3824
5303
 
3825
5304
  // src/pages/credentials-page.tsx
3826
- import { useState as useState15 } from "react";
3827
- import { Button as Button14 } from "@greatapps/greatauth-ui/ui";
5305
+ import { useState as useState19 } from "react";
5306
+ import { Button as Button18 } from "@greatapps/greatauth-ui/ui";
3828
5307
  import { Plus as Plus5 } from "lucide-react";
3829
- import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
5308
+ import { jsx as jsx28, jsxs as jsxs26 } from "react/jsx-runtime";
3830
5309
  function CredentialsPage({
3831
5310
  config,
3832
5311
  gagentsApiUrl,
@@ -3834,20 +5313,20 @@ function CredentialsPage({
3834
5313
  subtitle = "Gerencie as credenciais de autentica\xE7\xE3o das ferramentas"
3835
5314
  }) {
3836
5315
  const { data: credentialsData, isLoading: credentialsLoading } = useToolCredentials(config);
3837
- const [createOpen, setCreateOpen] = useState15(false);
5316
+ const [createOpen, setCreateOpen] = useState19(false);
3838
5317
  const credentials = credentialsData?.data || [];
3839
- return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
3840
- /* @__PURE__ */ jsxs16("div", { className: "flex items-center justify-between", children: [
3841
- /* @__PURE__ */ jsxs16("div", { children: [
3842
- /* @__PURE__ */ jsx18("h1", { className: "text-xl font-semibold", children: title }),
3843
- /* @__PURE__ */ jsx18("p", { className: "text-sm text-muted-foreground", children: subtitle })
5318
+ return /* @__PURE__ */ jsxs26("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
5319
+ /* @__PURE__ */ jsxs26("div", { className: "flex items-center justify-between", children: [
5320
+ /* @__PURE__ */ jsxs26("div", { children: [
5321
+ /* @__PURE__ */ jsx28("h1", { className: "text-xl font-semibold", children: title }),
5322
+ /* @__PURE__ */ jsx28("p", { className: "text-sm text-muted-foreground", children: subtitle })
3844
5323
  ] }),
3845
- /* @__PURE__ */ jsxs16(Button14, { onClick: () => setCreateOpen(true), size: "sm", children: [
3846
- /* @__PURE__ */ jsx18(Plus5, { className: "mr-2 h-4 w-4" }),
5324
+ /* @__PURE__ */ jsxs26(Button18, { onClick: () => setCreateOpen(true), size: "sm", children: [
5325
+ /* @__PURE__ */ jsx28(Plus5, { className: "mr-2 h-4 w-4" }),
3847
5326
  "Nova Credencial"
3848
5327
  ] })
3849
5328
  ] }),
3850
- /* @__PURE__ */ jsx18(
5329
+ /* @__PURE__ */ jsx28(
3851
5330
  ToolCredentialsForm,
3852
5331
  {
3853
5332
  config,
@@ -3860,7 +5339,117 @@ function CredentialsPage({
3860
5339
  )
3861
5340
  ] });
3862
5341
  }
5342
+
5343
+ // src/pages/integrations-management-page.tsx
5344
+ import { useState as useState20, useMemo as useMemo8 } from "react";
5345
+ import {
5346
+ Badge as Badge11,
5347
+ Button as Button19,
5348
+ Tabs as Tabs3,
5349
+ TabsContent as TabsContent3,
5350
+ TabsList as TabsList3,
5351
+ TabsTrigger as TabsTrigger3
5352
+ } from "@greatapps/greatauth-ui/ui";
5353
+ import { Plus as Plus6, Plug as Plug4, KeyRound, Info as Info3 } from "lucide-react";
5354
+ import { jsx as jsx29, jsxs as jsxs27 } from "react/jsx-runtime";
5355
+ function useCredentialAgentSummary(credentials, tools, agents) {
5356
+ return useMemo8(() => {
5357
+ const toolIdsWithCredentials = new Set(
5358
+ credentials.map((c) => c.id_tool).filter(Boolean)
5359
+ );
5360
+ const linkedCount = credentials.filter(
5361
+ (c) => c.id_tool && toolIdsWithCredentials.has(c.id_tool)
5362
+ ).length;
5363
+ return {
5364
+ totalCredentials: credentials.length,
5365
+ linkedToTools: linkedCount,
5366
+ totalAgents: agents.length,
5367
+ totalTools: tools.length
5368
+ };
5369
+ }, [credentials, tools, agents]);
5370
+ }
5371
+ function IntegrationsManagementPage({
5372
+ config,
5373
+ gagentsApiUrl,
5374
+ onConnect,
5375
+ title = "Integra\xE7\xF5es e Credenciais",
5376
+ subtitle = "Gerencie todas as integra\xE7\xF5es e credenciais da conta."
5377
+ }) {
5378
+ const { data: credentialsData, isLoading: credentialsLoading } = useToolCredentials(config);
5379
+ const { data: agentsData } = useAgents(config);
5380
+ const { data: toolsData } = useTools(config);
5381
+ const [createOpen, setCreateOpen] = useState20(false);
5382
+ const credentials = credentialsData?.data || [];
5383
+ const agents = agentsData?.data || [];
5384
+ const tools = toolsData?.data || [];
5385
+ const summary = useCredentialAgentSummary(credentials, tools, agents);
5386
+ return /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
5387
+ /* @__PURE__ */ jsx29("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxs27("div", { children: [
5388
+ /* @__PURE__ */ jsx29("h1", { className: "text-xl font-semibold", children: title }),
5389
+ /* @__PURE__ */ jsx29("p", { className: "text-sm text-muted-foreground", children: subtitle })
5390
+ ] }) }),
5391
+ /* @__PURE__ */ jsxs27(Tabs3, { defaultValue: "integrations", className: "w-full", children: [
5392
+ /* @__PURE__ */ jsxs27(TabsList3, { children: [
5393
+ /* @__PURE__ */ jsxs27(TabsTrigger3, { value: "integrations", className: "gap-2", children: [
5394
+ /* @__PURE__ */ jsx29(Plug4, { className: "h-4 w-4" }),
5395
+ "Integra\xE7\xF5es"
5396
+ ] }),
5397
+ /* @__PURE__ */ jsxs27(TabsTrigger3, { value: "credentials", className: "gap-2", children: [
5398
+ /* @__PURE__ */ jsx29(KeyRound, { className: "h-4 w-4" }),
5399
+ "Credenciais"
5400
+ ] })
5401
+ ] }),
5402
+ /* @__PURE__ */ jsx29(TabsContent3, { value: "integrations", className: "mt-4", children: /* @__PURE__ */ jsx29(
5403
+ IntegrationsTab,
5404
+ {
5405
+ config,
5406
+ agentId: null,
5407
+ onConnect: onConnect ?? (() => {
5408
+ })
5409
+ }
5410
+ ) }),
5411
+ /* @__PURE__ */ jsxs27(TabsContent3, { value: "credentials", className: "mt-4", children: [
5412
+ !credentialsLoading && /* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-4 rounded-lg border bg-muted/50 px-4 py-3 mb-4", children: [
5413
+ /* @__PURE__ */ jsx29(Info3, { className: "h-4 w-4 text-muted-foreground shrink-0" }),
5414
+ /* @__PURE__ */ jsxs27("div", { className: "flex flex-wrap items-center gap-3 text-sm", children: [
5415
+ /* @__PURE__ */ jsxs27("span", { children: [
5416
+ /* @__PURE__ */ jsx29(Badge11, { variant: "secondary", className: "mr-1", children: summary.totalCredentials }),
5417
+ summary.totalCredentials === 1 ? "credencial configurada" : "credenciais configuradas"
5418
+ ] }),
5419
+ /* @__PURE__ */ jsx29("span", { className: "text-muted-foreground", children: "|" }),
5420
+ /* @__PURE__ */ jsxs27("span", { children: [
5421
+ /* @__PURE__ */ jsx29(Badge11, { variant: "secondary", className: "mr-1", children: summary.linkedToTools }),
5422
+ summary.linkedToTools === 1 ? "vinculada a ferramentas" : "vinculadas a ferramentas"
5423
+ ] }),
5424
+ /* @__PURE__ */ jsx29("span", { className: "text-muted-foreground", children: "|" }),
5425
+ /* @__PURE__ */ jsxs27("span", { children: [
5426
+ /* @__PURE__ */ jsx29(Badge11, { variant: "secondary", className: "mr-1", children: summary.totalAgents }),
5427
+ summary.totalAgents === 1 ? "agente na conta" : "agentes na conta"
5428
+ ] })
5429
+ ] })
5430
+ ] }),
5431
+ /* @__PURE__ */ jsx29("div", { className: "flex items-center justify-end mb-4", children: /* @__PURE__ */ jsxs27(Button19, { onClick: () => setCreateOpen(true), size: "sm", children: [
5432
+ /* @__PURE__ */ jsx29(Plus6, { className: "mr-2 h-4 w-4" }),
5433
+ "Nova Credencial"
5434
+ ] }) }),
5435
+ /* @__PURE__ */ jsx29(
5436
+ ToolCredentialsForm,
5437
+ {
5438
+ config,
5439
+ gagentsApiUrl,
5440
+ credentials,
5441
+ isLoading: credentialsLoading,
5442
+ createOpen,
5443
+ onCreateOpenChange: setCreateOpen
5444
+ }
5445
+ )
5446
+ ] })
5447
+ ] })
5448
+ ] });
5449
+ }
3863
5450
  export {
5451
+ AdvancedTab,
5452
+ AgentCapabilitiesPage,
3864
5453
  AgentConversationsPanel,
3865
5454
  AgentConversationsTable,
3866
5455
  AgentDetailPage,
@@ -3872,8 +5461,14 @@ export {
3872
5461
  AgentToolsList,
3873
5462
  AgentsPage,
3874
5463
  AgentsTable,
5464
+ CapabilitiesTab,
3875
5465
  ConversationView,
3876
5466
  CredentialsPage,
5467
+ INTEGRATIONS_REGISTRY,
5468
+ IntegrationCard,
5469
+ IntegrationWizard,
5470
+ IntegrationsManagementPage,
5471
+ IntegrationsTab,
3877
5472
  Sortable,
3878
5473
  SortableContent,
3879
5474
  SortableItem,
@@ -3887,9 +5482,11 @@ export {
3887
5482
  createGagentsClient,
3888
5483
  useAddAgentTool,
3889
5484
  useAgent,
5485
+ useAgentCapabilities,
3890
5486
  useAgentConversations,
3891
5487
  useAgentTools,
3892
5488
  useAgents,
5489
+ useCapabilities,
3893
5490
  useContactUsers,
3894
5491
  useConversation,
3895
5492
  useConversations,
@@ -3903,6 +5500,7 @@ export {
3903
5500
  useDeleteToolCredential,
3904
5501
  useGagentsClient,
3905
5502
  useGagentsContacts,
5503
+ useIntegrationState,
3906
5504
  useObjectives,
3907
5505
  usePromptVersions,
3908
5506
  useRemoveAgentTool,
@@ -3910,6 +5508,7 @@ export {
3910
5508
  useToolCredentials,
3911
5509
  useTools,
3912
5510
  useUpdateAgent,
5511
+ useUpdateAgentCapabilities,
3913
5512
  useUpdateAgentTool,
3914
5513
  useUpdateObjective,
3915
5514
  useUpdateTool,