@greatapps/greatagents-ui 0.3.2 → 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.
Files changed (38) hide show
  1. package/dist/index.d.ts +204 -1
  2. package/dist/index.js +1797 -125
  3. package/dist/index.js.map +1 -1
  4. package/package.json +1 -1
  5. package/src/client/index.ts +14 -0
  6. package/src/components/agents/agent-edit-form.tsx +4 -1
  7. package/src/components/agents/agent-form-dialog.tsx +5 -1
  8. package/src/components/agents/agent-objectives-list.tsx +15 -6
  9. package/src/components/agents/agent-prompt-editor.tsx +9 -5
  10. package/src/components/agents/agent-tabs.tsx +4 -4
  11. package/src/components/agents/agent-tools-list.tsx +12 -5
  12. package/src/components/agents/agents-table.tsx +7 -2
  13. package/src/components/capabilities/advanced-tab.tsx +82 -0
  14. package/src/components/capabilities/capabilities-tab.tsx +475 -0
  15. package/src/components/capabilities/integration-card.tsx +162 -0
  16. package/src/components/capabilities/integration-wizard.tsx +537 -0
  17. package/src/components/capabilities/integrations-tab.tsx +61 -0
  18. package/src/components/capabilities/types.ts +48 -0
  19. package/src/components/capabilities/wizard-steps/config-step.tsx +117 -0
  20. package/src/components/capabilities/wizard-steps/confirm-step.tsx +123 -0
  21. package/src/components/capabilities/wizard-steps/credentials-step.tsx +205 -0
  22. package/src/components/capabilities/wizard-steps/info-step.tsx +78 -0
  23. package/src/components/conversations/agent-conversations-table.tsx +13 -2
  24. package/src/components/conversations/conversation-view.tsx +2 -2
  25. package/src/components/tools/tool-credentials-form.tsx +34 -14
  26. package/src/components/tools/tool-form-dialog.tsx +9 -5
  27. package/src/components/tools/tools-table.tsx +8 -3
  28. package/src/data/integrations-registry.ts +23 -0
  29. package/src/hooks/index.ts +10 -0
  30. package/src/hooks/use-capabilities.ts +50 -0
  31. package/src/hooks/use-integrations.ts +114 -0
  32. package/src/index.ts +34 -0
  33. package/src/pages/agent-capabilities-page.tsx +159 -0
  34. package/src/pages/agent-detail-page.tsx +1 -0
  35. package/src/pages/index.ts +2 -0
  36. package/src/pages/integrations-management-page.tsx +166 -0
  37. package/src/types/capabilities.ts +32 -0
  38. package/src/types/index.ts +10 -0
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,
@@ -504,6 +610,7 @@ function useColumns(onEdit, onDelete) {
504
610
  variant: "ghost",
505
611
  size: "icon",
506
612
  className: "h-8 w-8",
613
+ "aria-label": "Editar",
507
614
  onClick: () => onEdit(row.original),
508
615
  children: /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4" })
509
616
  }
@@ -517,6 +624,7 @@ function useColumns(onEdit, onDelete) {
517
624
  variant: "ghost",
518
625
  size: "icon",
519
626
  className: "h-8 w-8 text-destructive hover:text-destructive",
627
+ "aria-label": "Excluir",
520
628
  onClick: () => onDelete(row.original.id),
521
629
  children: /* @__PURE__ */ jsx(Trash2, { className: "h-4 w-4" })
522
630
  }
@@ -530,7 +638,7 @@ function useColumns(onEdit, onDelete) {
530
638
  function AgentsTable({ config, onNavigateToAgent }) {
531
639
  const [search, setSearch] = useState("");
532
640
  const [page, setPage] = useState(1);
533
- const queryParams = useMemo2(() => {
641
+ const queryParams = useMemo3(() => {
534
642
  const params = {
535
643
  limit: "15",
536
644
  page: String(page)
@@ -565,11 +673,14 @@ function AgentsTable({ config, onNavigateToAgent }) {
565
673
  }
566
674
  return /* @__PURE__ */ jsxs(Fragment, { children: [
567
675
  /* @__PURE__ */ jsx("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxs("div", { className: "relative flex-1 max-w-md", children: [
568
- /* @__PURE__ */ jsx(Search, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
676
+ /* @__PURE__ */ jsx(Search, { "aria-hidden": "true", className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
569
677
  /* @__PURE__ */ jsx(
570
678
  Input,
571
679
  {
572
- placeholder: "Buscar agentes...",
680
+ placeholder: "Buscar agentes\\u2026",
681
+ "aria-label": "Buscar agentes",
682
+ name: "search",
683
+ autoComplete: "off",
573
684
  value: search,
574
685
  onChange: (e) => handleSearchChange(e.target.value),
575
686
  className: "pl-9"
@@ -693,6 +804,7 @@ function AgentFormDialog({
693
804
  Input2,
694
805
  {
695
806
  id: "agent-photo",
807
+ name: "photo",
696
808
  value: photo,
697
809
  onChange: (e) => setPhoto(e.target.value),
698
810
  placeholder: "https://exemplo.com/foto.jpg",
@@ -706,6 +818,7 @@ function AgentFormDialog({
706
818
  Input2,
707
819
  {
708
820
  id: "agent-title",
821
+ name: "title",
709
822
  value: title,
710
823
  onChange: (e) => setTitle(e.target.value),
711
824
  placeholder: "Ex: Assistente de Agendamento",
@@ -721,6 +834,7 @@ function AgentFormDialog({
721
834
  Input2,
722
835
  {
723
836
  id: "agent-delay",
837
+ name: "delay",
724
838
  type: "number",
725
839
  value: delayTyping,
726
840
  onChange: (e) => setDelayTyping(e.target.value),
@@ -736,6 +850,7 @@ function AgentFormDialog({
736
850
  Input2,
737
851
  {
738
852
  id: "agent-waiting",
853
+ name: "waiting",
739
854
  type: "number",
740
855
  value: waitingTime,
741
856
  onChange: (e) => setWaitingTime(e.target.value),
@@ -758,7 +873,7 @@ function AgentFormDialog({
758
873
  }
759
874
  ),
760
875
  /* @__PURE__ */ jsxs2(Button2, { type: "submit", disabled: isPending || !title.trim(), children: [
761
- isPending ? /* @__PURE__ */ jsx2(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : null,
876
+ isPending ? /* @__PURE__ */ jsx2(Loader2, { "aria-hidden": "true", className: "mr-2 h-4 w-4 animate-spin" }) : null,
762
877
  isEditing ? "Salvar" : "Criar"
763
878
  ] })
764
879
  ] })
@@ -857,6 +972,7 @@ function AgentEditForm({ config, agent, idAccount, open, onOpenChange }) {
857
972
  Input3,
858
973
  {
859
974
  id: "edit-title",
975
+ name: "title",
860
976
  value: form.title,
861
977
  onChange: (e) => {
862
978
  setForm((prev) => ({
@@ -890,6 +1006,7 @@ function AgentEditForm({ config, agent, idAccount, open, onOpenChange }) {
890
1006
  Input3,
891
1007
  {
892
1008
  id: "edit-delay",
1009
+ name: "delay",
893
1010
  type: "number",
894
1011
  value: form.delayTyping,
895
1012
  onChange: (e) => updateField("delayTyping", e.target.value),
@@ -907,6 +1024,7 @@ function AgentEditForm({ config, agent, idAccount, open, onOpenChange }) {
907
1024
  Input3,
908
1025
  {
909
1026
  id: "edit-waiting",
1027
+ name: "waiting",
910
1028
  type: "number",
911
1029
  value: form.waitingTime,
912
1030
  onChange: (e) => updateField("waitingTime", e.target.value),
@@ -931,7 +1049,7 @@ function AgentEditForm({ config, agent, idAccount, open, onOpenChange }) {
931
1049
  }
932
1050
  ),
933
1051
  /* @__PURE__ */ jsxs3(Button3, { type: "submit", disabled: updateAgent.isPending, children: [
934
- updateAgent.isPending && /* @__PURE__ */ jsx3(Loader22, { className: "mr-2 h-4 w-4 animate-spin" }),
1052
+ updateAgent.isPending && /* @__PURE__ */ jsx3(Loader22, { "aria-hidden": "true", className: "mr-2 h-4 w-4 animate-spin" }),
935
1053
  "Salvar"
936
1054
  ] })
937
1055
  ] })
@@ -1100,7 +1218,9 @@ function AgentToolsList({ agent, config }) {
1100
1218
  /* @__PURE__ */ jsx4("div", { className: "p-2", children: /* @__PURE__ */ jsx4(
1101
1219
  Input4,
1102
1220
  {
1103
- placeholder: "Buscar ferramenta...",
1221
+ placeholder: "Buscar ferramenta\\u2026",
1222
+ "aria-label": "Buscar ferramenta",
1223
+ name: "search",
1104
1224
  value: search,
1105
1225
  onChange: (e) => setSearch(e.target.value),
1106
1226
  className: "h-8"
@@ -1144,6 +1264,7 @@ function AgentToolsList({ agent, config }) {
1144
1264
  /* @__PURE__ */ jsx4(
1145
1265
  Switch2,
1146
1266
  {
1267
+ "aria-label": "Ativar/Desativar",
1147
1268
  checked: agentTool.enabled,
1148
1269
  onCheckedChange: (checked) => handleToggleEnabled(agentTool, checked),
1149
1270
  disabled: updateMutation.isPending
@@ -1154,6 +1275,7 @@ function AgentToolsList({ agent, config }) {
1154
1275
  {
1155
1276
  variant: "ghost",
1156
1277
  size: "icon",
1278
+ "aria-label": "Configurar",
1157
1279
  className: "shrink-0 text-muted-foreground hover:text-foreground",
1158
1280
  onClick: () => openConfig(agentTool),
1159
1281
  title: "Configurar instru\xE7\xF5es",
@@ -1165,6 +1287,7 @@ function AgentToolsList({ agent, config }) {
1165
1287
  {
1166
1288
  variant: "ghost",
1167
1289
  size: "icon",
1290
+ "aria-label": "Remover",
1168
1291
  className: "shrink-0 text-muted-foreground hover:text-destructive",
1169
1292
  onClick: () => setRemoveTarget(agentTool),
1170
1293
  children: /* @__PURE__ */ jsx4(Trash22, { className: "h-4 w-4" })
@@ -1184,14 +1307,14 @@ function AgentToolsList({ agent, config }) {
1184
1307
  /* @__PURE__ */ jsx4(DialogHeader3, { children: /* @__PURE__ */ jsx4(DialogTitle3, { children: "Instru\xE7\xF5es da Ferramenta" }) }),
1185
1308
  /* @__PURE__ */ jsxs4("div", { className: "space-y-4", children: [
1186
1309
  configTarget && getToolInfo(configTarget.id_tool)?.type !== "none" && /* @__PURE__ */ jsxs4("div", { className: "space-y-2", children: [
1187
- /* @__PURE__ */ jsx4(Label3, { children: "Credencial" }),
1310
+ /* @__PURE__ */ jsx4(Label3, { htmlFor: "tool-credential", children: "Credencial" }),
1188
1311
  /* @__PURE__ */ jsxs4(
1189
1312
  Select,
1190
1313
  {
1191
1314
  value: configCredentialId || void 0,
1192
1315
  onValueChange: (val) => setConfigCredentialId(val === "__none__" ? "" : val),
1193
1316
  children: [
1194
- /* @__PURE__ */ jsx4(SelectTrigger, { children: /* @__PURE__ */ jsx4(SelectValue, { placeholder: "Selecione uma credencial (opcional)" }) }),
1317
+ /* @__PURE__ */ jsx4(SelectTrigger, { id: "tool-credential", children: /* @__PURE__ */ jsx4(SelectValue, { placeholder: "Selecione uma credencial (opcional)" }) }),
1195
1318
  /* @__PURE__ */ jsxs4(SelectContent, { children: [
1196
1319
  /* @__PURE__ */ jsx4(SelectItem, { value: "__none__", children: "Nenhuma (autom\xE1tico)" }),
1197
1320
  allCredentials.filter((c) => configTarget && c.id_tool === configTarget.id_tool && c.status === "active").map((c) => /* @__PURE__ */ jsx4(SelectItem, { value: String(c.id), children: c.label || `Credencial #${c.id}` }, c.id))
@@ -1202,13 +1325,15 @@ function AgentToolsList({ agent, config }) {
1202
1325
  /* @__PURE__ */ jsx4("p", { className: "text-xs text-muted-foreground", children: "Vincule uma credencial espec\xEDfica a esta ferramenta neste agente." })
1203
1326
  ] }),
1204
1327
  /* @__PURE__ */ jsxs4("div", { className: "space-y-2", children: [
1205
- /* @__PURE__ */ jsx4(Label3, { children: "Instru\xE7\xF5es Personalizadas" }),
1328
+ /* @__PURE__ */ jsx4(Label3, { htmlFor: "tool-instructions", children: "Instru\xE7\xF5es Personalizadas" }),
1206
1329
  /* @__PURE__ */ jsx4(
1207
1330
  Textarea,
1208
1331
  {
1332
+ id: "tool-instructions",
1333
+ name: "instructions",
1209
1334
  value: configInstructions,
1210
1335
  onChange: (e) => setConfigInstructions(e.target.value),
1211
- placeholder: "Instru\xE7\xF5es sobre como e quando o agente deve usar esta ferramenta...",
1336
+ placeholder: "Instru\\u00e7\\u00f5es sobre como e quando o agente deve usar esta ferramenta\\u2026",
1212
1337
  rows: 6
1213
1338
  }
1214
1339
  ),
@@ -1903,7 +2028,7 @@ function AgentObjectivesList({ agent, config }) {
1903
2028
  value: objective.id,
1904
2029
  className: "flex items-center gap-3 rounded-lg border bg-card p-3",
1905
2030
  children: [
1906
- /* @__PURE__ */ jsx6(SortableItemHandle, { className: "shrink-0 text-muted-foreground hover:text-foreground", children: /* @__PURE__ */ jsx6(GripVertical, { className: "h-5 w-5" }) }),
2031
+ /* @__PURE__ */ jsx6(SortableItemHandle, { className: "shrink-0 text-muted-foreground hover:text-foreground", children: /* @__PURE__ */ jsx6(GripVertical, { "aria-hidden": "true", className: "h-5 w-5" }) }),
1907
2032
  /* @__PURE__ */ jsxs5("div", { className: "flex flex-1 flex-col gap-1 min-w-0", children: [
1908
2033
  /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
1909
2034
  /* @__PURE__ */ jsx6("span", { className: "truncate font-medium", children: objective.title }),
@@ -1914,6 +2039,7 @@ function AgentObjectivesList({ agent, config }) {
1914
2039
  /* @__PURE__ */ jsx6(
1915
2040
  Switch3,
1916
2041
  {
2042
+ "aria-label": "Ativar/Desativar",
1917
2043
  checked: objective.active,
1918
2044
  onCheckedChange: (checked) => handleToggleActive(objective, checked),
1919
2045
  disabled: updateMutation.isPending
@@ -1924,6 +2050,7 @@ function AgentObjectivesList({ agent, config }) {
1924
2050
  {
1925
2051
  variant: "ghost",
1926
2052
  size: "icon",
2053
+ "aria-label": "Editar",
1927
2054
  className: "shrink-0 text-muted-foreground hover:text-foreground",
1928
2055
  onClick: () => openEdit(objective),
1929
2056
  children: /* @__PURE__ */ jsx6(Pencil2, { className: "h-4 w-4" })
@@ -1934,6 +2061,7 @@ function AgentObjectivesList({ agent, config }) {
1934
2061
  {
1935
2062
  variant: "ghost",
1936
2063
  size: "icon",
2064
+ "aria-label": "Excluir",
1937
2065
  className: "shrink-0 text-muted-foreground hover:text-destructive",
1938
2066
  onClick: () => setRemoveTarget(objective),
1939
2067
  children: /* @__PURE__ */ jsx6(Trash23, { className: "h-4 w-4" })
@@ -1946,7 +2074,7 @@ function AgentObjectivesList({ agent, config }) {
1946
2074
  /* @__PURE__ */ jsx6(SortableOverlay, { children: ({ value }) => {
1947
2075
  const obj = sortedObjectives.find((o) => o.id === value);
1948
2076
  return /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-3 rounded-lg border bg-card p-3 shadow-lg", children: [
1949
- /* @__PURE__ */ jsx6(GripVertical, { className: "h-5 w-5 text-muted-foreground" }),
2077
+ /* @__PURE__ */ jsx6(GripVertical, { "aria-hidden": "true", className: "h-5 w-5 text-muted-foreground" }),
1950
2078
  /* @__PURE__ */ jsx6("span", { className: "font-medium", children: obj?.title })
1951
2079
  ] });
1952
2080
  } })
@@ -1957,10 +2085,12 @@ function AgentObjectivesList({ agent, config }) {
1957
2085
  /* @__PURE__ */ jsx6(DialogHeader4, { children: /* @__PURE__ */ jsx6(DialogTitle4, { children: editTarget ? "Editar Objetivo" : "Novo Objetivo" }) }),
1958
2086
  /* @__PURE__ */ jsxs5("div", { className: "space-y-4", children: [
1959
2087
  /* @__PURE__ */ jsxs5("div", { className: "space-y-2", children: [
1960
- /* @__PURE__ */ jsx6(Label4, { children: "T\xEDtulo *" }),
2088
+ /* @__PURE__ */ jsx6(Label4, { htmlFor: "objective-title", children: "T\xEDtulo *" }),
1961
2089
  /* @__PURE__ */ jsx6(
1962
2090
  Input5,
1963
2091
  {
2092
+ id: "objective-title",
2093
+ name: "title",
1964
2094
  value: form.title,
1965
2095
  onChange: (e) => {
1966
2096
  const title = e.target.value;
@@ -1975,10 +2105,12 @@ function AgentObjectivesList({ agent, config }) {
1975
2105
  )
1976
2106
  ] }),
1977
2107
  /* @__PURE__ */ jsxs5("div", { className: "space-y-2", children: [
1978
- /* @__PURE__ */ jsx6(Label4, { children: "Slug (identificador) *" }),
2108
+ /* @__PURE__ */ jsx6(Label4, { htmlFor: "objective-slug", children: "Slug (identificador) *" }),
1979
2109
  /* @__PURE__ */ jsx6(
1980
2110
  Input5,
1981
2111
  {
2112
+ id: "objective-slug",
2113
+ name: "slug",
1982
2114
  value: form.slug,
1983
2115
  onChange: (e) => {
1984
2116
  setSlugManual(true);
@@ -1991,13 +2123,15 @@ function AgentObjectivesList({ agent, config }) {
1991
2123
  /* @__PURE__ */ jsx6("p", { className: "text-xs text-muted-foreground", children: "Gerado automaticamente. Usado pelo agente para identificar o objetivo." })
1992
2124
  ] }),
1993
2125
  /* @__PURE__ */ jsxs5("div", { className: "space-y-2", children: [
1994
- /* @__PURE__ */ jsx6(Label4, { children: "Instru\xE7\xF5es do Objetivo" }),
2126
+ /* @__PURE__ */ jsx6(Label4, { htmlFor: "objective-prompt", children: "Instru\xE7\xF5es do Objetivo" }),
1995
2127
  /* @__PURE__ */ jsx6(
1996
2128
  Textarea2,
1997
2129
  {
2130
+ id: "objective-prompt",
2131
+ name: "prompt",
1998
2132
  value: form.prompt,
1999
2133
  onChange: (e) => setForm((f) => ({ ...f, prompt: e.target.value })),
2000
- placeholder: "Instru\xE7\xF5es detalhadas que o agente seguir\xE1 quando este objetivo for ativado. Ex: passos para agendar consulta, perguntas a fazer, valida\xE7\xF5es necess\xE1rias...",
2134
+ placeholder: "Instru\\u00e7\\u00f5es detalhadas que o agente seguir\\u00e1 quando este objetivo for ativado\\u2026",
2001
2135
  rows: 8
2002
2136
  }
2003
2137
  ),
@@ -2206,22 +2340,24 @@ function AgentPromptEditor({ config, agent }) {
2206
2340
  "textarea",
2207
2341
  {
2208
2342
  ref: textareaRef,
2343
+ "aria-label": "Prompt do sistema",
2344
+ name: "prompt",
2209
2345
  value: promptText,
2210
2346
  onChange: (e) => setPromptText(e.target.value),
2211
2347
  onKeyDown: handleKeyDown,
2212
- placeholder: "Escreva o prompt do sistema aqui...",
2348
+ placeholder: "Escreva o prompt do sistema aqui\\u2026",
2213
2349
  disabled: updateAgent.isPending,
2214
2350
  className: "w-full resize-none rounded-lg border bg-background p-3 font-mono text-sm leading-relaxed focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50",
2215
2351
  style: { minHeight: "300px" }
2216
2352
  }
2217
2353
  ),
2218
2354
  /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-3 text-xs text-muted-foreground", children: [
2219
- /* @__PURE__ */ jsxs6("span", { children: [
2355
+ /* @__PURE__ */ jsxs6("span", { className: "tabular-nums", children: [
2220
2356
  charCount.toLocaleString("pt-BR"),
2221
2357
  " caracteres"
2222
2358
  ] }),
2223
2359
  /* @__PURE__ */ jsx7("span", { children: "\xB7" }),
2224
- /* @__PURE__ */ jsxs6("span", { children: [
2360
+ /* @__PURE__ */ jsxs6("span", { className: "tabular-nums", children: [
2225
2361
  "~",
2226
2362
  tokenEstimate.toLocaleString("pt-BR"),
2227
2363
  " tokens"
@@ -2232,6 +2368,8 @@ function AgentPromptEditor({ config, agent }) {
2232
2368
  /* @__PURE__ */ jsx7(
2233
2369
  Input6,
2234
2370
  {
2371
+ "aria-label": "Notas da altera\xE7\xE3o",
2372
+ name: "changeNotes",
2235
2373
  value: changeNotes,
2236
2374
  onChange: (e) => setChangeNotes(e.target.value),
2237
2375
  placeholder: "O que mudou? (opcional)",
@@ -2356,7 +2494,7 @@ function AgentPromptEditor({ config, agent }) {
2356
2494
  onClick: () => setCompareVersionId(isComparing ? null : version.id),
2357
2495
  className: "flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground",
2358
2496
  children: [
2359
- /* @__PURE__ */ jsx7(FileText, { className: "h-3 w-3" }),
2497
+ /* @__PURE__ */ jsx7(FileText, { "aria-hidden": "true", className: "h-3 w-3" }),
2360
2498
  isComparing ? "Ocultar diff" : "Comparar"
2361
2499
  ]
2362
2500
  }
@@ -2368,7 +2506,7 @@ function AgentPromptEditor({ config, agent }) {
2368
2506
  onClick: () => handleRestore(version),
2369
2507
  className: "flex items-center gap-1 text-xs text-primary hover:underline",
2370
2508
  children: [
2371
- /* @__PURE__ */ jsx7(RotateCcw, { className: "h-3 w-3" }),
2509
+ /* @__PURE__ */ jsx7(RotateCcw, { "aria-hidden": "true", className: "h-3 w-3" }),
2372
2510
  "Restaurar"
2373
2511
  ]
2374
2512
  }
@@ -2422,7 +2560,7 @@ function ConversationView({
2422
2560
  if (!conversation) {
2423
2561
  return /* @__PURE__ */ jsx8("div", { className: "rounded-lg border bg-card p-4", children: /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between", children: [
2424
2562
  /* @__PURE__ */ jsx8("p", { className: "text-sm text-muted-foreground", children: "Conversa n\xE3o encontrada." }),
2425
- /* @__PURE__ */ jsx8(Button7, { variant: "ghost", size: "icon", onClick: onClose, children: /* @__PURE__ */ jsx8(X, { className: "h-4 w-4" }) })
2563
+ /* @__PURE__ */ jsx8(Button7, { variant: "ghost", size: "icon", "aria-label": "Fechar", onClick: onClose, children: /* @__PURE__ */ jsx8(X, { className: "h-4 w-4" }) })
2426
2564
  ] }) });
2427
2565
  }
2428
2566
  return /* @__PURE__ */ jsxs7("div", { className: "rounded-lg border bg-card p-4 space-y-4", children: [
@@ -2431,7 +2569,7 @@ function ConversationView({
2431
2569
  "Detalhes da conversa #",
2432
2570
  conversation.id
2433
2571
  ] }),
2434
- /* @__PURE__ */ jsx8("div", { className: "flex items-center gap-1", children: /* @__PURE__ */ jsx8(Button7, { variant: "ghost", size: "icon", onClick: onClose, children: /* @__PURE__ */ jsx8(X, { className: "h-4 w-4" }) }) })
2572
+ /* @__PURE__ */ jsx8("div", { className: "flex items-center gap-1", children: /* @__PURE__ */ jsx8(Button7, { variant: "ghost", size: "icon", "aria-label": "Fechar", onClick: onClose, children: /* @__PURE__ */ jsx8(X, { className: "h-4 w-4" }) }) })
2435
2573
  ] }),
2436
2574
  conversation.id_external ? renderChatLink ? renderChatLink(conversation.id_external) : /* @__PURE__ */ jsx8(Button7, { variant: "outline", size: "sm", asChild: true, children: /* @__PURE__ */ jsxs7("a", { href: `/gchat/inbox/${conversation.id_external}`, children: [
2437
2575
  /* @__PURE__ */ jsx8(MessageSquare, { className: "mr-2 h-4 w-4" }),
@@ -2524,16 +2662,26 @@ function AgentConversationsTable({
2524
2662
  TableRow,
2525
2663
  {
2526
2664
  className: "cursor-pointer",
2665
+ role: "button",
2666
+ tabIndex: 0,
2527
2667
  onClick: () => setSelectedId(
2528
2668
  selectedId === conversation.id ? null : conversation.id
2529
2669
  ),
2670
+ onKeyDown: (e) => {
2671
+ if (e.key === "Enter" || e.key === " ") {
2672
+ e.preventDefault();
2673
+ setSelectedId(
2674
+ selectedId === conversation.id ? null : conversation.id
2675
+ );
2676
+ }
2677
+ },
2530
2678
  "data-state": selectedId === conversation.id ? "selected" : void 0,
2531
2679
  children: [
2532
2680
  /* @__PURE__ */ jsx9(TableCell, { className: "font-mono text-xs", children: conversation.id }),
2533
2681
  /* @__PURE__ */ jsx9(TableCell, { children: contactsMap?.get(conversation.id_contact) ?? conversation.id_contact }),
2534
2682
  /* @__PURE__ */ jsx9(TableCell, { children: conversation.id_objective && objectivesMap?.get(conversation.id_objective) ? /* @__PURE__ */ jsx9(Badge5, { variant: "secondary", className: "text-xs", children: objectivesMap.get(conversation.id_objective) }) : /* @__PURE__ */ jsx9("span", { className: "text-xs text-muted-foreground", children: "\u2014" }) }),
2535
- /* @__PURE__ */ jsx9(TableCell, { className: "text-right", children: conversation.message_count ?? "\u2014" }),
2536
- /* @__PURE__ */ jsx9(TableCell, { className: "text-right", children: conversation.usage_tokens ?? "\u2014" }),
2683
+ /* @__PURE__ */ jsx9(TableCell, { className: "text-right tabular-nums", children: conversation.message_count ?? "\u2014" }),
2684
+ /* @__PURE__ */ jsx9(TableCell, { className: "text-right tabular-nums", children: conversation.usage_tokens ?? "\u2014" }),
2537
2685
  /* @__PURE__ */ jsx9(TableCell, { children: new Date(conversation.datetime_add).toLocaleDateString("pt-BR") }),
2538
2686
  /* @__PURE__ */ jsx9(TableCell, { children: formatRelativeDate(conversation.datetime_alt) }),
2539
2687
  /* @__PURE__ */ jsx9(TableCell, { children: conversation.id_external ? renderChatLink ? /* @__PURE__ */ jsx9("span", { onClick: (e) => e.stopPropagation(), children: renderChatLink(conversation.id_external) }) : /* @__PURE__ */ jsx9(
@@ -2541,6 +2689,7 @@ function AgentConversationsTable({
2541
2689
  {
2542
2690
  href: `/gchat/inbox/${conversation.id_external}`,
2543
2691
  title: "Ver no Chat",
2692
+ "aria-label": "Ver no Chat",
2544
2693
  onClick: (e) => e.stopPropagation(),
2545
2694
  className: "inline-flex items-center justify-center rounded-md p-1.5 text-muted-foreground hover:text-foreground hover:bg-accent transition-colors",
2546
2695
  children: /* @__PURE__ */ jsx9(ExternalLink, { className: "h-4 w-4" })
@@ -2610,19 +2759,19 @@ function AgentTabs({ agent, config, renderChatLink }) {
2610
2759
  return /* @__PURE__ */ jsxs9(Tabs, { defaultValue: "prompt", children: [
2611
2760
  /* @__PURE__ */ jsxs9(TabsList, { children: [
2612
2761
  /* @__PURE__ */ jsxs9(TabsTrigger, { value: "prompt", className: "flex items-center gap-1.5", children: [
2613
- /* @__PURE__ */ jsx11(FileText2, { className: "h-3.5 w-3.5" }),
2762
+ /* @__PURE__ */ jsx11(FileText2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
2614
2763
  "Prompt"
2615
2764
  ] }),
2616
2765
  /* @__PURE__ */ jsxs9(TabsTrigger, { value: "objetivos", className: "flex items-center gap-1.5", children: [
2617
- /* @__PURE__ */ jsx11(Target2, { className: "h-3.5 w-3.5" }),
2766
+ /* @__PURE__ */ jsx11(Target2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
2618
2767
  "Objetivos"
2619
2768
  ] }),
2620
2769
  /* @__PURE__ */ jsxs9(TabsTrigger, { value: "ferramentas", className: "flex items-center gap-1.5", children: [
2621
- /* @__PURE__ */ jsx11(Wrench2, { className: "h-3.5 w-3.5" }),
2770
+ /* @__PURE__ */ jsx11(Wrench2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
2622
2771
  "Ferramentas"
2623
2772
  ] }),
2624
2773
  /* @__PURE__ */ jsxs9(TabsTrigger, { value: "conversas", className: "flex items-center gap-1.5", children: [
2625
- /* @__PURE__ */ jsx11(MessageCircle2, { className: "h-3.5 w-3.5" }),
2774
+ /* @__PURE__ */ jsx11(MessageCircle2, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
2626
2775
  "Conversas"
2627
2776
  ] })
2628
2777
  ] }),
@@ -2641,7 +2790,7 @@ function AgentTabs({ agent, config, renderChatLink }) {
2641
2790
  }
2642
2791
 
2643
2792
  // src/components/tools/tools-table.tsx
2644
- import { useMemo as useMemo4, useState as useState9 } from "react";
2793
+ import { useMemo as useMemo5, useState as useState9 } from "react";
2645
2794
  import { DataTable as DataTable2 } from "@greatapps/greatauth-ui";
2646
2795
  import {
2647
2796
  Input as Input7,
@@ -2688,7 +2837,7 @@ function useColumns2(onEdit, onDelete) {
2688
2837
  cell: ({ row }) => {
2689
2838
  const desc = row.original.description;
2690
2839
  if (!desc) return /* @__PURE__ */ jsx12("span", { className: "text-muted-foreground text-sm", children: "\u2014" });
2691
- return /* @__PURE__ */ jsx12("span", { className: "text-muted-foreground text-sm", children: desc.length > 50 ? `${desc.slice(0, 50)}...` : desc });
2840
+ return /* @__PURE__ */ jsx12("span", { className: "text-muted-foreground text-sm", children: desc.length > 50 ? `${desc.slice(0, 50)}\u2026` : desc });
2692
2841
  }
2693
2842
  },
2694
2843
  {
@@ -2710,6 +2859,7 @@ function useColumns2(onEdit, onDelete) {
2710
2859
  variant: "ghost",
2711
2860
  size: "icon",
2712
2861
  className: "h-8 w-8",
2862
+ "aria-label": "Editar",
2713
2863
  onClick: () => onEdit(row.original),
2714
2864
  children: /* @__PURE__ */ jsx12(Pencil3, { className: "h-4 w-4" })
2715
2865
  }
@@ -2723,6 +2873,7 @@ function useColumns2(onEdit, onDelete) {
2723
2873
  variant: "ghost",
2724
2874
  size: "icon",
2725
2875
  className: "h-8 w-8 text-destructive hover:text-destructive",
2876
+ "aria-label": "Excluir",
2726
2877
  onClick: () => onDelete(row.original.id),
2727
2878
  children: /* @__PURE__ */ jsx12(Trash24, { className: "h-4 w-4" })
2728
2879
  }
@@ -2736,7 +2887,7 @@ function useColumns2(onEdit, onDelete) {
2736
2887
  function ToolsTable({ onEdit, config }) {
2737
2888
  const [search, setSearch] = useState9("");
2738
2889
  const [page, setPage] = useState9(1);
2739
- const queryParams = useMemo4(() => {
2890
+ const queryParams = useMemo5(() => {
2740
2891
  const params = {
2741
2892
  limit: "15",
2742
2893
  page: String(page)
@@ -2771,11 +2922,14 @@ function ToolsTable({ onEdit, config }) {
2771
2922
  }
2772
2923
  return /* @__PURE__ */ jsxs10(Fragment2, { children: [
2773
2924
  /* @__PURE__ */ jsx12("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxs10("div", { className: "relative flex-1 max-w-md", children: [
2774
- /* @__PURE__ */ jsx12(Search2, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
2925
+ /* @__PURE__ */ jsx12(Search2, { "aria-hidden": "true", className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
2775
2926
  /* @__PURE__ */ jsx12(
2776
2927
  Input7,
2777
2928
  {
2778
- placeholder: "Buscar ferramentas...",
2929
+ placeholder: "Buscar ferramentas\\u2026",
2930
+ "aria-label": "Buscar ferramentas",
2931
+ name: "search",
2932
+ autoComplete: "off",
2779
2933
  value: search,
2780
2934
  onChange: (e) => handleSearchChange(e.target.value),
2781
2935
  className: "pl-9"
@@ -2963,6 +3117,7 @@ function ToolFormDialog({
2963
3117
  Input8,
2964
3118
  {
2965
3119
  id: "tool-name",
3120
+ name: "name",
2966
3121
  value: form.name,
2967
3122
  onChange: (e) => {
2968
3123
  const name = e.target.value;
@@ -2985,6 +3140,7 @@ function ToolFormDialog({
2985
3140
  Input8,
2986
3141
  {
2987
3142
  id: "tool-slug",
3143
+ name: "slug",
2988
3144
  value: form.slug,
2989
3145
  onChange: (e) => {
2990
3146
  setSlugManuallyEdited(true);
@@ -3030,9 +3186,10 @@ function ToolFormDialog({
3030
3186
  Textarea3,
3031
3187
  {
3032
3188
  id: "tool-description",
3189
+ name: "description",
3033
3190
  value: form.description,
3034
3191
  onChange: (e) => setForm((prev) => ({ ...prev, description: e.target.value })),
3035
- placeholder: "Descri\xE7\xE3o da ferramenta...",
3192
+ placeholder: "Descri\\u00e7\\u00e3o da ferramenta\\u2026",
3036
3193
  rows: 3,
3037
3194
  disabled: isPending
3038
3195
  }
@@ -3044,6 +3201,7 @@ function ToolFormDialog({
3044
3201
  Textarea3,
3045
3202
  {
3046
3203
  id: "tool-function-defs",
3204
+ name: "functionDefs",
3047
3205
  value: form.functionDefinitions,
3048
3206
  onChange: (e) => {
3049
3207
  setForm((prev) => ({
@@ -3060,8 +3218,8 @@ function ToolFormDialog({
3060
3218
  "description": "O que a fun\xE7\xE3o faz",
3061
3219
  "parameters": {
3062
3220
  "type": "object",
3063
- "properties": { ... },
3064
- "required": [...]
3221
+ "properties": { \u2026 },
3222
+ "required": [\u2026]
3065
3223
  }
3066
3224
  }
3067
3225
  }
@@ -3086,7 +3244,7 @@ function ToolFormDialog({
3086
3244
  }
3087
3245
  ),
3088
3246
  /* @__PURE__ */ jsxs11(Button9, { type: "submit", disabled: isPending, children: [
3089
- isPending ? /* @__PURE__ */ jsx13(Loader24, { className: "mr-2 h-4 w-4 animate-spin" }) : null,
3247
+ isPending ? /* @__PURE__ */ jsx13(Loader24, { "aria-hidden": "true", className: "mr-2 h-4 w-4 animate-spin" }) : null,
3090
3248
  isEditing ? "Salvar" : "Criar"
3091
3249
  ] })
3092
3250
  ] })
@@ -3095,7 +3253,7 @@ function ToolFormDialog({
3095
3253
  }
3096
3254
 
3097
3255
  // src/components/tools/tool-credentials-form.tsx
3098
- import { useMemo as useMemo5, useState as useState11 } from "react";
3256
+ import { useMemo as useMemo6, useState as useState11 } from "react";
3099
3257
  import { DataTable as DataTable3 } from "@greatapps/greatauth-ui";
3100
3258
  import {
3101
3259
  Input as Input9,
@@ -3188,6 +3346,7 @@ function useColumns3(tools, onEdit, onConnect, onRemove) {
3188
3346
  variant: "ghost",
3189
3347
  size: "icon",
3190
3348
  className: "h-8 w-8",
3349
+ "aria-label": "Vincular",
3191
3350
  disabled: true,
3192
3351
  children: /* @__PURE__ */ jsx14(Link, { className: "h-4 w-4" })
3193
3352
  }
@@ -3201,6 +3360,7 @@ function useColumns3(tools, onEdit, onConnect, onRemove) {
3201
3360
  variant: "ghost",
3202
3361
  size: "icon",
3203
3362
  className: "h-8 w-8",
3363
+ "aria-label": "Editar",
3204
3364
  onClick: () => onEdit(row.original),
3205
3365
  children: /* @__PURE__ */ jsx14(Pencil4, { className: "h-4 w-4" })
3206
3366
  }
@@ -3214,6 +3374,7 @@ function useColumns3(tools, onEdit, onConnect, onRemove) {
3214
3374
  variant: "ghost",
3215
3375
  size: "icon",
3216
3376
  className: "h-8 w-8 text-destructive hover:text-destructive",
3377
+ "aria-label": "Excluir",
3217
3378
  onClick: () => onRemove(row.original),
3218
3379
  children: /* @__PURE__ */ jsx14(Trash25, { className: "h-4 w-4" })
3219
3380
  }
@@ -3256,7 +3417,7 @@ function ToolCredentialsForm({
3256
3417
  status: ""
3257
3418
  });
3258
3419
  const [removeTarget, setRemoveTarget] = useState11(null);
3259
- const filteredCredentials = useMemo5(() => {
3420
+ const filteredCredentials = useMemo6(() => {
3260
3421
  if (!search) return credentials;
3261
3422
  const term = search.toLowerCase();
3262
3423
  return credentials.filter((cred) => {
@@ -3363,11 +3524,14 @@ function ToolCredentialsForm({
3363
3524
  }
3364
3525
  return /* @__PURE__ */ jsxs12("div", { className: "space-y-4", children: [
3365
3526
  /* @__PURE__ */ jsx14("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxs12("div", { className: "relative flex-1 max-w-md", children: [
3366
- /* @__PURE__ */ jsx14(Search3, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
3527
+ /* @__PURE__ */ jsx14(Search3, { "aria-hidden": "true", className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
3367
3528
  /* @__PURE__ */ jsx14(
3368
3529
  Input9,
3369
3530
  {
3370
- placeholder: "Buscar credenciais...",
3531
+ placeholder: "Buscar credenciais\\u2026",
3532
+ "aria-label": "Buscar credenciais",
3533
+ name: "search",
3534
+ autoComplete: "off",
3371
3535
  value: search,
3372
3536
  onChange: (e) => setSearch(e.target.value),
3373
3537
  className: "pl-9"
@@ -3387,24 +3551,26 @@ function ToolCredentialsForm({
3387
3551
  /* @__PURE__ */ jsx14(DialogHeader6, { children: /* @__PURE__ */ jsx14(DialogTitle6, { children: "Nova Credencial" }) }),
3388
3552
  /* @__PURE__ */ jsxs12("div", { className: "space-y-4", children: [
3389
3553
  /* @__PURE__ */ jsxs12("div", { children: [
3390
- /* @__PURE__ */ jsx14("label", { className: "mb-1 block text-sm font-medium", children: "Ferramenta *" }),
3554
+ /* @__PURE__ */ jsx14("label", { htmlFor: "cred-tool", className: "mb-1 block text-sm font-medium", children: "Ferramenta *" }),
3391
3555
  /* @__PURE__ */ jsxs12(
3392
3556
  Select3,
3393
3557
  {
3394
3558
  value: createForm.id_tool,
3395
3559
  onValueChange: (val) => setCreateForm((f) => ({ ...f, id_tool: val })),
3396
3560
  children: [
3397
- /* @__PURE__ */ jsx14(SelectTrigger3, { children: /* @__PURE__ */ jsx14(SelectValue3, { placeholder: "Selecione a ferramenta" }) }),
3561
+ /* @__PURE__ */ jsx14(SelectTrigger3, { id: "cred-tool", children: /* @__PURE__ */ jsx14(SelectValue3, { placeholder: "Selecione a ferramenta" }) }),
3398
3562
  /* @__PURE__ */ jsx14(SelectContent3, { children: tools.map((tool) => /* @__PURE__ */ jsx14(SelectItem3, { value: String(tool.id), children: tool.name }, tool.id)) })
3399
3563
  ]
3400
3564
  }
3401
3565
  )
3402
3566
  ] }),
3403
3567
  /* @__PURE__ */ jsxs12("div", { children: [
3404
- /* @__PURE__ */ jsx14("label", { className: "mb-1 block text-sm font-medium", children: "Label *" }),
3568
+ /* @__PURE__ */ jsx14("label", { htmlFor: "cred-label", className: "mb-1 block text-sm font-medium", children: "Label *" }),
3405
3569
  /* @__PURE__ */ jsx14(
3406
3570
  Input9,
3407
3571
  {
3572
+ id: "cred-label",
3573
+ name: "label",
3408
3574
  value: createForm.label,
3409
3575
  onChange: (e) => setCreateForm((f) => ({ ...f, label: e.target.value })),
3410
3576
  placeholder: "Ex: Google Calendar - Cl\xEDnica S\xE3o Paulo"
@@ -3412,10 +3578,13 @@ function ToolCredentialsForm({
3412
3578
  )
3413
3579
  ] }),
3414
3580
  /* @__PURE__ */ jsxs12("div", { children: [
3415
- /* @__PURE__ */ jsx14("label", { className: "mb-1 block text-sm font-medium", children: "Credencial *" }),
3581
+ /* @__PURE__ */ jsx14("label", { htmlFor: "cred-credential", className: "mb-1 block text-sm font-medium", children: "Credencial *" }),
3416
3582
  /* @__PURE__ */ jsx14(
3417
3583
  Input9,
3418
3584
  {
3585
+ id: "cred-credential",
3586
+ name: "credential",
3587
+ autoComplete: "off",
3419
3588
  type: "password",
3420
3589
  value: createForm.credentials_encrypted,
3421
3590
  onChange: (e) => setCreateForm((f) => ({
@@ -3427,10 +3596,12 @@ function ToolCredentialsForm({
3427
3596
  )
3428
3597
  ] }),
3429
3598
  /* @__PURE__ */ jsxs12("div", { children: [
3430
- /* @__PURE__ */ jsx14("label", { className: "mb-1 block text-sm font-medium", children: "Data de Expira\xE7\xE3o (opcional)" }),
3599
+ /* @__PURE__ */ jsx14("label", { htmlFor: "cred-expires", className: "mb-1 block text-sm font-medium", children: "Data de Expira\xE7\xE3o (opcional)" }),
3431
3600
  /* @__PURE__ */ jsx14(
3432
3601
  Input9,
3433
3602
  {
3603
+ id: "cred-expires",
3604
+ name: "expires",
3434
3605
  type: "date",
3435
3606
  value: createForm.expires_at,
3436
3607
  onChange: (e) => setCreateForm((f) => ({ ...f, expires_at: e.target.value }))
@@ -3466,24 +3637,26 @@ function ToolCredentialsForm({
3466
3637
  /* @__PURE__ */ jsx14(DialogHeader6, { children: /* @__PURE__ */ jsx14(DialogTitle6, { children: "Editar Credencial" }) }),
3467
3638
  /* @__PURE__ */ jsxs12("div", { className: "space-y-4", children: [
3468
3639
  /* @__PURE__ */ jsxs12("div", { children: [
3469
- /* @__PURE__ */ jsx14("label", { className: "mb-1 block text-sm font-medium", children: "Ferramenta *" }),
3640
+ /* @__PURE__ */ jsx14("label", { htmlFor: "edit-cred-tool", className: "mb-1 block text-sm font-medium", children: "Ferramenta *" }),
3470
3641
  /* @__PURE__ */ jsxs12(
3471
3642
  Select3,
3472
3643
  {
3473
3644
  value: editForm.id_tool,
3474
3645
  onValueChange: (val) => setEditForm((f) => ({ ...f, id_tool: val })),
3475
3646
  children: [
3476
- /* @__PURE__ */ jsx14(SelectTrigger3, { children: /* @__PURE__ */ jsx14(SelectValue3, { placeholder: "Selecione a ferramenta" }) }),
3647
+ /* @__PURE__ */ jsx14(SelectTrigger3, { id: "edit-cred-tool", children: /* @__PURE__ */ jsx14(SelectValue3, { placeholder: "Selecione a ferramenta" }) }),
3477
3648
  /* @__PURE__ */ jsx14(SelectContent3, { children: tools.map((tool) => /* @__PURE__ */ jsx14(SelectItem3, { value: String(tool.id), children: tool.name }, tool.id)) })
3478
3649
  ]
3479
3650
  }
3480
3651
  )
3481
3652
  ] }),
3482
3653
  /* @__PURE__ */ jsxs12("div", { children: [
3483
- /* @__PURE__ */ jsx14("label", { className: "mb-1 block text-sm font-medium", children: "Label" }),
3654
+ /* @__PURE__ */ jsx14("label", { htmlFor: "edit-cred-label", className: "mb-1 block text-sm font-medium", children: "Label" }),
3484
3655
  /* @__PURE__ */ jsx14(
3485
3656
  Input9,
3486
3657
  {
3658
+ id: "edit-cred-label",
3659
+ name: "label",
3487
3660
  value: editForm.label,
3488
3661
  onChange: (e) => setEditForm((f) => ({ ...f, label: e.target.value })),
3489
3662
  placeholder: "Label da credencial"
@@ -3491,10 +3664,13 @@ function ToolCredentialsForm({
3491
3664
  )
3492
3665
  ] }),
3493
3666
  /* @__PURE__ */ jsxs12("div", { children: [
3494
- /* @__PURE__ */ jsx14("label", { className: "mb-1 block text-sm font-medium", children: "Nova Credencial (vazio = manter atual)" }),
3667
+ /* @__PURE__ */ jsx14("label", { htmlFor: "edit-cred-credential", className: "mb-1 block text-sm font-medium", children: "Nova Credencial (vazio = manter atual)" }),
3495
3668
  /* @__PURE__ */ jsx14(
3496
3669
  Input9,
3497
3670
  {
3671
+ id: "edit-cred-credential",
3672
+ name: "credential",
3673
+ autoComplete: "off",
3498
3674
  type: "password",
3499
3675
  value: editForm.credentials_encrypted,
3500
3676
  onChange: (e) => setEditForm((f) => ({
@@ -3506,10 +3682,12 @@ function ToolCredentialsForm({
3506
3682
  )
3507
3683
  ] }),
3508
3684
  /* @__PURE__ */ jsxs12("div", { children: [
3509
- /* @__PURE__ */ jsx14("label", { className: "mb-1 block text-sm font-medium", children: "Data de Expira\xE7\xE3o" }),
3685
+ /* @__PURE__ */ jsx14("label", { htmlFor: "edit-cred-expires", className: "mb-1 block text-sm font-medium", children: "Data de Expira\xE7\xE3o" }),
3510
3686
  /* @__PURE__ */ jsx14(
3511
3687
  Input9,
3512
3688
  {
3689
+ id: "edit-cred-expires",
3690
+ name: "expires",
3513
3691
  type: "date",
3514
3692
  value: editForm.expires_at,
3515
3693
  onChange: (e) => setEditForm((f) => ({ ...f, expires_at: e.target.value }))
@@ -3517,7 +3695,7 @@ function ToolCredentialsForm({
3517
3695
  )
3518
3696
  ] }),
3519
3697
  /* @__PURE__ */ jsxs12("div", { children: [
3520
- /* @__PURE__ */ jsx14("label", { className: "mb-1 block text-sm font-medium", children: "Status" }),
3698
+ /* @__PURE__ */ jsx14("label", { htmlFor: "edit-cred-status", className: "mb-1 block text-sm font-medium", children: "Status" }),
3521
3699
  /* @__PURE__ */ jsxs12(
3522
3700
  Select3,
3523
3701
  {
@@ -3527,7 +3705,7 @@ function ToolCredentialsForm({
3527
3705
  status: val
3528
3706
  })),
3529
3707
  children: [
3530
- /* @__PURE__ */ jsx14(SelectTrigger3, { children: /* @__PURE__ */ jsx14(SelectValue3, {}) }),
3708
+ /* @__PURE__ */ jsx14(SelectTrigger3, { id: "edit-cred-status", children: /* @__PURE__ */ jsx14(SelectValue3, {}) }),
3531
3709
  /* @__PURE__ */ jsxs12(SelectContent3, { children: [
3532
3710
  /* @__PURE__ */ jsx14(SelectItem3, { value: "active", children: "Ativo" }),
3533
3711
  /* @__PURE__ */ jsx14(SelectItem3, { value: "expired", children: "Expirado" })
@@ -3578,31 +3756,1302 @@ function ToolCredentialsForm({
3578
3756
  ] });
3579
3757
  }
3580
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
+
3581
5030
  // src/pages/agents-page.tsx
3582
- import { useState as useState12 } from "react";
3583
- 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";
3584
5033
  import { Plus as Plus3 } from "lucide-react";
3585
- import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
5034
+ import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
3586
5035
  function AgentsPage({
3587
5036
  config,
3588
5037
  onNavigateToAgent,
3589
5038
  title = "Agentes AI",
3590
5039
  subtitle = "Gerencie seus agentes de atendimento inteligente"
3591
5040
  }) {
3592
- const [createOpen, setCreateOpen] = useState12(false);
3593
- return /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
3594
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between", children: [
3595
- /* @__PURE__ */ jsxs13("div", { children: [
3596
- /* @__PURE__ */ jsx15("h1", { className: "text-xl font-semibold", children: title }),
3597
- /* @__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 })
3598
5047
  ] }),
3599
- /* @__PURE__ */ jsxs13(Button11, { onClick: () => setCreateOpen(true), size: "sm", children: [
3600
- /* @__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" }),
3601
5050
  "Novo Agente"
3602
5051
  ] })
3603
5052
  ] }),
3604
- /* @__PURE__ */ jsx15(AgentsTable, { config, onNavigateToAgent }),
3605
- /* @__PURE__ */ jsx15(
5053
+ /* @__PURE__ */ jsx24(AgentsTable, { config, onNavigateToAgent }),
5054
+ /* @__PURE__ */ jsx24(
3606
5055
  AgentFormDialog,
3607
5056
  {
3608
5057
  config,
@@ -3614,11 +5063,11 @@ function AgentsPage({
3614
5063
  }
3615
5064
 
3616
5065
  // src/pages/agent-detail-page.tsx
3617
- import { useState as useState13 } from "react";
3618
- 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";
3619
5068
  import { EntityAvatar as EntityAvatar2 } from "@greatapps/greatauth-ui";
3620
5069
  import { ArrowLeft, Pencil as Pencil5 } from "lucide-react";
3621
- import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
5070
+ import { jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
3622
5071
  function AgentDetailPage({
3623
5072
  config,
3624
5073
  agentId,
@@ -3626,42 +5075,43 @@ function AgentDetailPage({
3626
5075
  renderChatLink
3627
5076
  }) {
3628
5077
  const { data: agent, isLoading } = useAgent(config, agentId);
3629
- const [editOpen, setEditOpen] = useState13(false);
5078
+ const [editOpen, setEditOpen] = useState16(false);
3630
5079
  if (isLoading) {
3631
- return /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-4 p-4", children: [
3632
- /* @__PURE__ */ jsx16(Skeleton6, { className: "h-4 w-32" }),
3633
- /* @__PURE__ */ jsx16(Skeleton6, { className: "h-8 w-48" }),
3634
- /* @__PURE__ */ jsx16(Skeleton6, { className: "h-10 w-full" }),
3635
- /* @__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" })
3636
5085
  ] });
3637
5086
  }
3638
5087
  if (!agent) {
3639
- return /* @__PURE__ */ jsxs14("div", { className: "flex flex-col items-center justify-center gap-2 p-8", children: [
3640
- /* @__PURE__ */ jsx16("p", { className: "text-muted-foreground", children: "Agente n\xE3o encontrado" }),
3641
- onBack && /* @__PURE__ */ jsxs14(Button12, { variant: "ghost", size: "sm", onClick: onBack, children: [
3642
- /* @__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" }),
3643
5092
  "Voltar para agentes"
3644
5093
  ] })
3645
5094
  ] });
3646
5095
  }
3647
- return /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-6 p-4 md:p-6", children: [
3648
- /* @__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: [
3649
- /* @__PURE__ */ jsxs14("div", { className: "flex items-start gap-3 flex-1", children: [
3650
- onBack && /* @__PURE__ */ jsx16(
3651
- 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,
3652
5101
  {
3653
5102
  variant: "ghost",
3654
5103
  size: "icon",
5104
+ "aria-label": "Voltar",
3655
5105
  className: "shrink-0 mt-1",
3656
5106
  onClick: onBack,
3657
- children: /* @__PURE__ */ jsx16(ArrowLeft, { className: "h-4 w-4" })
5107
+ children: /* @__PURE__ */ jsx25(ArrowLeft, { className: "h-4 w-4" })
3658
5108
  }
3659
5109
  ),
3660
- /* @__PURE__ */ jsx16(EntityAvatar2, { photo: agent.photo, name: agent.title, size: "xl" }),
3661
- /* @__PURE__ */ jsx16("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2 flex-wrap", children: [
3662
- /* @__PURE__ */ jsx16("h1", { className: "text-xl font-semibold", children: agent.title }),
3663
- /* @__PURE__ */ jsx16(
3664
- 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,
3665
5115
  {
3666
5116
  variant: agent.active ? "default" : "destructive",
3667
5117
  className: "text-xs",
@@ -3670,21 +5120,21 @@ function AgentDetailPage({
3670
5120
  )
3671
5121
  ] }) })
3672
5122
  ] }),
3673
- /* @__PURE__ */ jsxs14(
3674
- Button12,
5123
+ /* @__PURE__ */ jsxs23(
5124
+ Button16,
3675
5125
  {
3676
5126
  variant: "outline",
3677
5127
  size: "sm",
3678
5128
  className: "shrink-0 self-start",
3679
5129
  onClick: () => setEditOpen(true),
3680
5130
  children: [
3681
- /* @__PURE__ */ jsx16(Pencil5, { className: "mr-2 h-4 w-4" }),
5131
+ /* @__PURE__ */ jsx25(Pencil5, { className: "mr-2 h-4 w-4" }),
3682
5132
  "Editar"
3683
5133
  ]
3684
5134
  }
3685
5135
  )
3686
5136
  ] }) }),
3687
- /* @__PURE__ */ jsx16(
5137
+ /* @__PURE__ */ jsx25(
3688
5138
  AgentTabs,
3689
5139
  {
3690
5140
  agent,
@@ -3692,7 +5142,7 @@ function AgentDetailPage({
3692
5142
  renderChatLink
3693
5143
  }
3694
5144
  ),
3695
- editOpen && /* @__PURE__ */ jsx16(
5145
+ editOpen && /* @__PURE__ */ jsx25(
3696
5146
  AgentEditForm,
3697
5147
  {
3698
5148
  agent,
@@ -3705,31 +5155,133 @@ function AgentDetailPage({
3705
5155
  ] });
3706
5156
  }
3707
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
+
3708
5260
  // src/pages/tools-page.tsx
3709
- import { useState as useState14 } from "react";
3710
- 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";
3711
5263
  import { Plus as Plus4 } from "lucide-react";
3712
- import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
5264
+ import { jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
3713
5265
  function ToolsPage({
3714
5266
  config,
3715
5267
  title = "Ferramentas",
3716
5268
  subtitle = "Gerencie as ferramentas dispon\xEDveis para seus agentes"
3717
5269
  }) {
3718
- const [createOpen, setCreateOpen] = useState14(false);
3719
- const [editTool, setEditTool] = useState14(void 0);
3720
- return /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
3721
- /* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
3722
- /* @__PURE__ */ jsxs15("div", { children: [
3723
- /* @__PURE__ */ jsx17("h1", { className: "text-xl font-semibold", children: title }),
3724
- /* @__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 })
3725
5277
  ] }),
3726
- /* @__PURE__ */ jsxs15(Button13, { onClick: () => setCreateOpen(true), size: "sm", children: [
3727
- /* @__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" }),
3728
5280
  "Nova Ferramenta"
3729
5281
  ] })
3730
5282
  ] }),
3731
- /* @__PURE__ */ jsx17(ToolsTable, { config, onEdit: (tool) => setEditTool(tool) }),
3732
- /* @__PURE__ */ jsx17(
5283
+ /* @__PURE__ */ jsx27(ToolsTable, { config, onEdit: (tool) => setEditTool(tool) }),
5284
+ /* @__PURE__ */ jsx27(
3733
5285
  ToolFormDialog,
3734
5286
  {
3735
5287
  config,
@@ -3737,7 +5289,7 @@ function ToolsPage({
3737
5289
  onOpenChange: setCreateOpen
3738
5290
  }
3739
5291
  ),
3740
- /* @__PURE__ */ jsx17(
5292
+ /* @__PURE__ */ jsx27(
3741
5293
  ToolFormDialog,
3742
5294
  {
3743
5295
  config,
@@ -3750,10 +5302,10 @@ function ToolsPage({
3750
5302
  }
3751
5303
 
3752
5304
  // src/pages/credentials-page.tsx
3753
- import { useState as useState15 } from "react";
3754
- 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";
3755
5307
  import { Plus as Plus5 } from "lucide-react";
3756
- import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
5308
+ import { jsx as jsx28, jsxs as jsxs26 } from "react/jsx-runtime";
3757
5309
  function CredentialsPage({
3758
5310
  config,
3759
5311
  gagentsApiUrl,
@@ -3761,20 +5313,20 @@ function CredentialsPage({
3761
5313
  subtitle = "Gerencie as credenciais de autentica\xE7\xE3o das ferramentas"
3762
5314
  }) {
3763
5315
  const { data: credentialsData, isLoading: credentialsLoading } = useToolCredentials(config);
3764
- const [createOpen, setCreateOpen] = useState15(false);
5316
+ const [createOpen, setCreateOpen] = useState19(false);
3765
5317
  const credentials = credentialsData?.data || [];
3766
- return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-4 p-4 md:p-6", children: [
3767
- /* @__PURE__ */ jsxs16("div", { className: "flex items-center justify-between", children: [
3768
- /* @__PURE__ */ jsxs16("div", { children: [
3769
- /* @__PURE__ */ jsx18("h1", { className: "text-xl font-semibold", children: title }),
3770
- /* @__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 })
3771
5323
  ] }),
3772
- /* @__PURE__ */ jsxs16(Button14, { onClick: () => setCreateOpen(true), size: "sm", children: [
3773
- /* @__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" }),
3774
5326
  "Nova Credencial"
3775
5327
  ] })
3776
5328
  ] }),
3777
- /* @__PURE__ */ jsx18(
5329
+ /* @__PURE__ */ jsx28(
3778
5330
  ToolCredentialsForm,
3779
5331
  {
3780
5332
  config,
@@ -3787,7 +5339,117 @@ function CredentialsPage({
3787
5339
  )
3788
5340
  ] });
3789
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
+ }
3790
5450
  export {
5451
+ AdvancedTab,
5452
+ AgentCapabilitiesPage,
3791
5453
  AgentConversationsPanel,
3792
5454
  AgentConversationsTable,
3793
5455
  AgentDetailPage,
@@ -3799,8 +5461,14 @@ export {
3799
5461
  AgentToolsList,
3800
5462
  AgentsPage,
3801
5463
  AgentsTable,
5464
+ CapabilitiesTab,
3802
5465
  ConversationView,
3803
5466
  CredentialsPage,
5467
+ INTEGRATIONS_REGISTRY,
5468
+ IntegrationCard,
5469
+ IntegrationWizard,
5470
+ IntegrationsManagementPage,
5471
+ IntegrationsTab,
3804
5472
  Sortable,
3805
5473
  SortableContent,
3806
5474
  SortableItem,
@@ -3814,9 +5482,11 @@ export {
3814
5482
  createGagentsClient,
3815
5483
  useAddAgentTool,
3816
5484
  useAgent,
5485
+ useAgentCapabilities,
3817
5486
  useAgentConversations,
3818
5487
  useAgentTools,
3819
5488
  useAgents,
5489
+ useCapabilities,
3820
5490
  useContactUsers,
3821
5491
  useConversation,
3822
5492
  useConversations,
@@ -3830,6 +5500,7 @@ export {
3830
5500
  useDeleteToolCredential,
3831
5501
  useGagentsClient,
3832
5502
  useGagentsContacts,
5503
+ useIntegrationState,
3833
5504
  useObjectives,
3834
5505
  usePromptVersions,
3835
5506
  useRemoveAgentTool,
@@ -3837,6 +5508,7 @@ export {
3837
5508
  useToolCredentials,
3838
5509
  useTools,
3839
5510
  useUpdateAgent,
5511
+ useUpdateAgentCapabilities,
3840
5512
  useUpdateAgentTool,
3841
5513
  useUpdateObjective,
3842
5514
  useUpdateTool,