@engramind/client 0.0.0-stage → 0.1.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react/provider.tsx","../src/react/components/ui/tooltip.tsx","../src/react/lib/utils.ts","../src/react/components/ui/portal-container.tsx","../src/core/errors.ts","../src/react/lib/api.ts","../src/react/lib/config.tsx","../src/react/lib/messages.ts","../src/react/lib/navigation.ts","../src/react/lib/toast.ts","../src/react/lib/live.ts","../src/react/engramind/components/network/EngramindNetwork.tsx","../src/react/hooks/usePersistentState.ts","../src/react/components/feedback/EmptyState.tsx","../src/react/components/ui/button.tsx","../src/react/components/motion/presets.ts","../src/react/engramind/network/app-network.ts","../src/react/engramind/network/network-math.ts","../src/react/engramind/network/filters.ts","../src/core/constants.ts","../src/react/engramind/network/overview-layout.ts","../src/react/engramind/hooks/useEngramind.ts","../src/react/engramind/hooks/useEngramindNetwork.ts","../src/react/engramind/hooks/useNetworkSearch.ts","../src/react/engramind/components/shared/QueryBoundary.tsx","../src/react/components/feedback/ErrorState.tsx","../src/react/engramind/components/page/memories/ImportMemoriesDialog.tsx","../src/react/components/ui/dialog.tsx","../src/react/components/ui/input.tsx","../src/react/components/ui/select.tsx","../src/react/engramind/help/identities.ts","../src/react/engramind/schemas/import.ts","../src/core/schemas.ts","../src/core/scopes.ts","../src/react/components/ui/info-tooltip.tsx","../src/react/components/ui/label.tsx","../src/react/engramind/components/shared/InfoField.tsx","../src/react/engramind/components/page/channels/ChannelDialog.tsx","../src/react/components/ui/form-grid.ts","../src/react/components/ui/textarea.tsx","../src/react/engramind/components/shared/useSchemaForm.ts","../src/react/engramind/components/page/channels/ChannelBySubscriptionDialog.tsx","../src/react/components/ui/option-tabs.tsx","../src/react/engramind/components/network/ChannelPanel.tsx","../src/react/lib/link.tsx","../src/react/components/ui/confirm-dialog.tsx","../src/react/components/ui/alert-dialog.tsx","../src/react/components/ui/sheet.tsx","../src/react/engramind/components/page/channels/SubscribersCard.tsx","../src/react/components/ui/tooltip-icon-button.tsx","../src/react/components/ui/badge.tsx","../src/react/engramind/components/shared/Badges.tsx","../src/react/components/ui/skeleton.tsx","../src/react/engramind/components/shared/ListSkeleton.tsx","../src/react/engramind/components/shared/Section.tsx","../src/react/components/ui/card.tsx","../src/react/engramind/components/page/channels/SubscriptionDialog.tsx","../src/react/engramind/components/shared/ScopePicker.tsx","../src/react/engramind/components/network/ChannelName.tsx","../src/react/engramind/network/channel-labels.ts","../src/react/engramind/components/network/AgentLabels.tsx","../src/react/engramind/components/network/MemoryUniverse.tsx","../src/react/engramind/network/particles.ts","../src/react/engramind/hooks/useEngramindConsumption.ts","../src/core/events.ts","../src/react/engramind/components/network/ActiveMemoryCard.tsx","../src/react/engramind/components/network/MemoryCardLayer.tsx","../src/react/engramind/components/network/MemoryCard.tsx","../src/react/components/ui/switch.tsx","../src/react/engramind/components/network/agent-icons.ts","../src/react/engramind/components/network/NetworkCanvas.tsx","../src/react/engramind/components/network/edges.tsx","../src/react/engramind/components/network/network-labels.ts","../src/react/engramind/components/network/live.tsx","../src/react/components/flow/path-traveler.tsx","../src/react/hooks/useMediaQuery.ts","../src/react/components/flow/flow-theme.ts","../src/react/engramind/components/network/layout-classes.ts","../src/react/engramind/components/network/MemoryNode.tsx","../src/react/engramind/components/network/nodes.tsx","../src/react/engramind/components/network/usePositionSlide.ts","../src/react/engramind/components/network/RecenterButton.tsx","../src/react/engramind/components/network/UniversePanels.tsx","../src/react/engramind/components/network/UniverseStatsCard.tsx","../src/react/engramind/components/network/StatsCard.tsx","../src/react/components/motion/AnimatedNumber.tsx","../src/react/engramind/components/network/useEnteringIds.ts","../src/react/engramind/components/network/useLeavingItems.ts","../src/react/engramind/components/network/useStableNodes.ts","../src/react/engramind/components/network/NetworkBreadcrumb.tsx","../src/react/engramind/components/network/NetworkSkeleton.tsx","../src/react/engramind/components/network/NetworkToolbar.tsx","../src/react/components/list/ListFilters.tsx","../src/react/hooks/useDebouncedSearch.ts","../src/react/components/list/CollapsibleFilters.tsx","../src/react/components/list/ActiveFilterChips.tsx","../src/react/components/list/CadastroFilterCard.tsx","../src/react/components/list/FilterGroup.tsx","../src/react/engramind/components/network/NetworkFiltersBar.tsx","../src/react/engramind/components/network/NetworkFiltersSheet.tsx","../src/react/components/ui/popover.tsx","../src/react/components/ui/checkbox.tsx","../src/react/components/list/CadastroMultiSelect.tsx","../src/react/components/list/FilterSwitch.tsx","../src/react/components/ui/preset-date-range-filter.tsx","../src/react/components/ui/date-range-calendar.tsx","../src/react/components/ui/calendar.tsx","../src/react/engramind/components/network/OverviewView.tsx","../src/react/engramind/components/network/overview-shared.tsx","../src/react/engramind/components/network/useAgentWrites.ts","../src/react/engramind/components/network/AppsOverviewView.tsx","../src/react/engramind/components/network/NetworkFooter.tsx","../src/react/engramind/components/network/useRawMemoryActions.tsx","../src/react/engramind/components/page/memories/MemoryHistoryDialog.tsx","../src/react/engramind/components/shared/format.ts","../src/react/engramind/components/shared/LoadMore.tsx","../src/react/engramind/components/page/memories/MoveMemoryDialog.tsx","../src/react/engramind/components/network/useLocalRemovals.ts","../src/react/engramind/components/memory/MemoryEditor.tsx","../src/react/engramind/memory-text.ts","../src/react/engramind/components/network/MemoryEditorDialog.tsx","../src/react/engramind/components/network/useUniverseParam.ts","../src/react/engramind/components/page/channels/ChannelDetail.tsx","../src/react/components/list/CadastroHeader.tsx","../src/react/engramind/components/config/AppSettings.tsx","../src/react/components/ui/tabs.tsx","../src/react/engramind/components/config/AgentDetail.tsx","../src/react/engramind/identities.ts","../src/react/engramind/components/config/AgentDialog.tsx","../src/react/engramind/components/config/TokensCard.tsx","../src/react/hooks/usePageVirtualizer.ts","../src/react/components/list/VirtualizedRows.tsx","../src/react/engramind/components/config/EditTokenDialog.tsx","../src/react/engramind/components/config/IssueTokenDialog.tsx","../src/react/components/ui/secret-reveal.tsx","../src/react/engramind/components/config/RotateTokenDialog.tsx","../src/react/engramind/components/config/TokenHealthBadges.tsx","../src/react/engramind/components/config/AgentsCard.tsx","../src/react/engramind/components/config/ChannelsCard.tsx","../src/react/engramind/components/config/WebhookCard.tsx"],"sourcesContent":["\"use client\"\n\nimport { useMemo, type ReactNode } from \"react\"\nimport type { LucideIcon } from \"lucide-react\"\nimport { TooltipProvider } from \"./components/ui/tooltip\"\nimport { setActiveDataSource, type EngramindDataSource } from \"./lib/api\"\nimport { DEFAULT_CONFIG, defaultAgentIcon, EngramindConfigContext, type EngramindConfig, type EngramindHrefs, type ConfigureTarget, type EngramindMode, type FooterContext, type RenderLinkProps } from \"./lib/config\"\nimport { mergeMessages, type PartialMessages } from \"./lib/messages\"\nimport type { NavigationAdapter } from \"./lib/navigation\"\nimport { setNotifier, type Notify } from \"./lib/toast\"\nimport type { ChannelLabel } from \"./engramind/network/channel-labels\"\n\nexport interface EngramindProviderProps {\n /** Fonte de dados: o proxy da lib montado pelo app (`createHttpDataSource({ basePath })`). */\n dataSource: EngramindDataSource\n /** `app` (padrão): token do próprio app. `manager`: só para o gestor da rede (token admin). */\n mode?: EngramindMode\n /** URL do SSE da lib (`createSseHandler`); sem ela, a tela atualiza só pelas próprias ações e ao reconsultar. */\n events?: string | null\n /** Slug do app do token (modo app); sem ele, a lib lê de `whoami`. */\n app?: string | null\n /** Nome exibido do app (modo app). */\n appName?: string\n /** Toasts do app (ex.: `sonner`). */\n notify?: Notify\n /** Navegação do roteador do app (ex.: `next/navigation`); padrão: History API. */\n navigation?: NavigationAdapter\n /** Link interno do app (ex.: `next/link`); padrão: `<a>`. */\n renderLink?: (props: RenderLinkProps) => ReactNode\n hrefs?: Partial<EngramindHrefs>\n agentIcon?: (agent: string) => LucideIcon\n agentWrites?: (agent: string) => { total: number; last7d: number } | null\n channelLabels?: ReadonlyMap<string, ChannelLabel>\n /** Textos sobrescritos (chave ausente usa o padrão pt-BR). */\n messages?: PartialMessages\n staleAfterDays?: number\n onConfigure?: (target?: ConfigureTarget) => void\n slots?: { footer?: (context: FooterContext) => ReactNode; channelDetail?: (slug: string) => ReactNode }\n storagePrefix?: string\n children: ReactNode\n}\n\n/**\n * Raiz dos componentes do Engramind. O app monta dentro do próprio `QueryClientProvider` (TanStack Query)\n * e do próprio login: o provider só leva a fonte de dados (o proxy), o SSE e os adaptadores do app.\n * Uma fonte de dados por página: dois providers com fontes diferentes na mesma tela usam a última montada.\n */\nexport function EngramindProvider(props: EngramindProviderProps) {\n const { dataSource, notify, children } = props\n setActiveDataSource(dataSource)\n setNotifier(notify ?? null)\n const { mode, events, app, appName, navigation, renderLink, hrefs, agentIcon, agentWrites, channelLabels, messages, staleAfterDays, onConfigure, slots, storagePrefix } = props\n const config = useMemo<EngramindConfig>(\n () => ({\n ...DEFAULT_CONFIG,\n mode: mode ?? \"app\",\n events: events ?? null,\n app: app ?? null,\n appName,\n navigation: navigation ?? DEFAULT_CONFIG.navigation,\n renderLink,\n hrefs: { ...DEFAULT_CONFIG.hrefs, ...hrefs },\n agentIcon: agentIcon ?? defaultAgentIcon,\n agentWrites,\n channelLabels: channelLabels ?? DEFAULT_CONFIG.channelLabels,\n messages: mergeMessages(messages),\n staleAfterDays,\n onConfigure,\n slots: slots ?? {},\n storagePrefix: storagePrefix ?? DEFAULT_CONFIG.storagePrefix,\n }),\n [mode, events, app, appName, navigation, renderLink, hrefs, agentIcon, agentWrites, channelLabels, messages, staleAfterDays, onConfigure, slots, storagePrefix],\n )\n return (\n <EngramindConfigContext.Provider value={config}>\n <TooltipProvider delayDuration={200}>{children}</TooltipProvider>\n </EngramindConfigContext.Provider>\n )\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\"\nimport { cn } from \"../../lib/utils\"\nimport { usePortalContainer } from \"./portal-container\"\n\nconst TooltipProvider = TooltipPrimitive.Provider\n\nconst Tooltip = TooltipPrimitive.Root\n\nconst TooltipTrigger = TooltipPrimitive.Trigger\n\nconst TooltipContent = React.forwardRef<\n React.ElementRef<typeof TooltipPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n <TooltipPrimitive.Portal container={usePortalContainer()}>\n <TooltipPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n className={cn(\n \"z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n className\n )}\n {...props}\n />\n </TooltipPrimitive.Portal>\n))\nTooltipContent.displayName = TooltipPrimitive.Content.displayName\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n","import { type ClassValue, clsx } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","\"use client\"\n\nimport { createContext, useContext, type ReactNode } from \"react\"\n\n/**\n * Onde os wrappers de `src/components/ui` desenham os painéis flutuantes (popover, menu, dica,\n * seletor, diálogo). Sem provider, o Radix usa o `document.body`. Um elemento em tela cheia do\n * navegador só mostra o que está DENTRO dele: quem entra em tela cheia aponta o provider para o\n * próprio elemento, senão os painéis abririam invisíveis.\n */\nconst PortalContainerContext = createContext<HTMLElement | null>(null)\n\nexport function PortalContainerProvider({ container, children }: { container: HTMLElement | null; children: ReactNode }) {\n return <PortalContainerContext.Provider value={container}>{children}</PortalContainerContext.Provider>\n}\n\n/** Contêiner atual dos portais (`undefined` = o padrão do Radix, o `document.body`). */\nexport function usePortalContainer(): HTMLElement | undefined {\n return useContext(PortalContainerContext) ?? undefined\n}\n","/**\n * Erros do Engramind traduzidos para pt-BR. Decide pelo `code` estável do envelope\n * `{ error: { code, message, details } }`, nunca pela `message`. Os códigos expostos pela lib levam o\n * prefixo `ENGRAMIND_` (ex.: `ENGRAMIND_CHANNEL_SHARED`), e os erros da própria lib também\n * (`ENGRAMIND_UNREACHABLE`, `ENGRAMIND_PROXY_MASKED`, `ENGRAMIND_NOT_CONFIGURED`).\n */\n\nexport interface EngramindErrorBody {\n code: string\n message?: string\n details?: unknown\n}\n\nexport class EngramindError extends Error {\n readonly status: number\n readonly code: string\n readonly details?: unknown\n /** Segundos de `Retry-After` (429). */\n readonly retryAfter: number | null\n\n constructor(status: number, message: string, code: string, details?: unknown, retryAfter: number | null = null) {\n super(message)\n this.name = \"EngramindError\"\n this.status = status\n this.code = code\n this.details = details\n this.retryAfter = retryAfter\n }\n}\n\ntype Details = Record<string, unknown>\nconst asDetails = (details: unknown): Details => (details && typeof details === \"object\" ? (details as Details) : {})\nconst list = (value: unknown) => (Array.isArray(value) ? value.map(String).join(\", \") : \"\")\n\nconst MESSAGES: Record<string, (details: Details, retryAfter: string | null) => string> = {\n AUTH_INVALID: () => \"O Engramind recusou o token do app (ausente, inválido, expirado, revogado ou de app desativado). Peça um novo token ao gestor e reconfigure o app.\",\n SCOPE_REQUIRED: (d) =>\n `O token do app não tem permissão para esta operação${d.required_kind ? ` (exige ${String(d.required_kind)}` : \"\"}${d.required_scope ? ` com ${String(d.required_scope)})` : d.required_kind ? \")\" : \"\"}.`,\n FOREIGN_APP: () => \"Sem acesso: o registro pertence a outro app.\",\n CHANNEL_NOT_SUBSCRIBED: (d) => `Sem acesso: o token não alcança o canal${d.channel ? ` ${String(d.channel)}` : \"\"}.`,\n CHANNEL_SHARED: () => \"O canal é assinado por outro app e não pode ser arquivado por este app.\",\n LAST_ADMIN_TOKEN: () => \"A rede ficaria sem nenhum token admin ativo com write. Emita outro token admin antes.\",\n SLUG_ALREADY_EXISTS: () => \"Já existe um registro com esse slug. Escolha outro.\",\n SUBSCRIPTION_EXISTS: () => \"O agente já assina esse alvo.\",\n CATEGORY_NOT_FOUND: (d) => `Categoria fora da lista${d.valid ? ` (aceitas: ${list(d.valid)})` : \"\"}${d.index !== undefined ? `; item ${Number(d.index) + 1}` : \"\"}.`,\n BATCH_TOO_LARGE: (d) => `O lote passa do limite${d.max !== undefined ? ` (${String(d.received)} de no máximo ${String(d.max)})` : \"\"}. Divida o arquivo.`,\n IDEMPOTENCY_KEY_REQUIRED: () => \"A operação exige uma chave de idempotência.\",\n IDEMPOTENCY_KEY_CONFLICT: () => \"A chave de idempotência já foi usada com outro conteúdo.\",\n RATE_LIMITED: (_d, retryAfter) => `O Engramind limitou as requisições do app${retryAfter ? `; tente de novo em ${retryAfter} s` : \"\"}.`,\n VALIDATION_ERROR: (d) => `O Engramind recusou os dados${d.index !== undefined ? ` (item ${Number(d.index) + 1})` : \"\"}${d.field ? ` no campo ${String(d.field)}` : \"\"}.`,\n CHANNEL_NOT_ARCHIVED: () => \"Só um canal arquivado pode ser excluído: arquive antes.\",\n CHANNEL_ARCHIVED: () => \"O canal está arquivado e não recebe escrita: restaure-o antes.\",\n CHANNEL_NOT_FOUND: () => \"Canal não encontrado no Engramind.\",\n APP_NOT_FOUND: () => \"App não encontrado no Engramind.\",\n AGENT_NOT_FOUND: () => \"Agente não encontrado no Engramind.\",\n TOKEN_NOT_FOUND: () => \"Token não encontrado no Engramind.\",\n SUBSCRIPTION_NOT_FOUND: () => \"Assinatura não encontrada no Engramind.\",\n MEMORY_NOT_FOUND: () => \"Memória não encontrada no Engramind.\",\n REVISION_NOT_FOUND: () => \"A memória não tem essa versão.\",\n MEMORY_VERSION_CONFLICT: () => \"Esta memória mudou enquanto você editava. Confira a versão atual.\",\n MEMORY_DUPLICATE: (d) => `Já existe uma memória com esse texto no canal${d.existing_id ? ` (${String(d.existing_id)})` : \"\"}.`,\n MEMORY_KEY_EXISTS: () => \"Já existe uma memória com essa chave no canal.\",\n PAYLOAD_TOO_LARGE: () => \"O corpo passou do limite do Engramind.\",\n DATABASE_UNAVAILABLE: () => \"O banco do Engramind está indisponível. Tente novamente.\",\n MIGRATIONS_PENDING: () => \"O Engramind tem migrações pendentes e ainda não recebe tráfego. Tente novamente em instantes.\",\n REQUEST_TIMEOUT: () => \"O Engramind excedeu o tempo limite da requisição. Tente novamente.\",\n INTERNAL_ERROR: () => \"Falha inesperada no Engramind. Tente novamente.\",\n ROUTE_NOT_FOUND: () => \"Operação não disponível neste Engramind.\",\n}\n\n/** Status devolvido ao navegador: falha do próprio serviço vira 502 e token recusado vira 409 (reconfigurar). */\nexport function clientStatus(status: number): number {\n if (status === 401) return 409\n if (status >= 500) return 502\n return status\n}\n\n/**\n * Corpo de um 5xx trocado pelo proxy na frente do Engramind (o Cloudflare substitui o corpo das respostas\n * 5xx pela própria página/JSON): devolve o nome do erro do proxy, quando reconhecido.\n */\nexport function proxyMaskedError(text: string, json: unknown): string | null {\n if (json && typeof json === \"object\" && (\"ray_id\" in json || \"error_name\" in json || \"cloudflare_error\" in json)) {\n const name = (json as { error_name?: unknown; title?: unknown }).error_name ?? (json as { title?: unknown }).title\n return typeof name === \"string\" && name ? name : \"cloudflare\"\n }\n if (/cloudflare/i.test(text) && /ray id|cf-ray|cloudflare/i.test(text)) return \"cloudflare\"\n return null\n}\n\nconst parseRetryAfter = (value: string | null): number | null => {\n if (!value) return null\n const seconds = Number(value)\n if (Number.isFinite(seconds) && seconds >= 0) return seconds\n const date = Date.parse(value)\n return Number.isNaN(date) ? null : Math.max(0, Math.round((date - Date.now()) / 1000))\n}\n\nexport function toEngramindError(status: number, body: EngramindErrorBody | null, retryAfter: string | null = null, masked: string | null = null): EngramindError {\n if (!body && status >= 500 && masked) {\n return new EngramindError(502, `Um proxy (Cloudflare) escondeu a resposta HTTP ${status} do Engramind (${masked}). Chame a URL de origem do Engramind para ver o motivo.`, \"ENGRAMIND_PROXY_MASKED\", { status, proxyError: masked })\n }\n const code = body?.code ?? (status === 404 ? \"ROUTE_NOT_FOUND\" : `HTTP_${status}`)\n const message = MESSAGES[code]?.(asDetails(body?.details), retryAfter) ?? body?.message ?? `O Engramind respondeu HTTP ${status}.`\n return new EngramindError(clientStatus(status), message, `ENGRAMIND_${code}`, body?.details ?? undefined, parseRetryAfter(retryAfter))\n}\n\n/** Engramind fora do ar ou inalcançável. */\nexport const unreachableError = (reason: string) =>\n new EngramindError(503, `Não foi possível falar com o Engramind (${reason}). Confira a URL base e se o serviço está no ar.`, \"ENGRAMIND_UNREACHABLE\")\n\nexport const notConfiguredError = () => new EngramindError(409, \"Configure a conexão com o Engramind (URL base e token) no servidor do app.\", \"ENGRAMIND_NOT_CONFIGURED\")\n\n/** Código do Engramind (sem o prefixo) de um erro traduzido. */\nexport const engramindCodeOf = (error: unknown): string | null => (error instanceof EngramindError && error.code.startsWith(\"ENGRAMIND_\") ? error.code.slice(\"ENGRAMIND_\".length) : null)\n","import { EngramindError } from \"../../core/errors\"\n\nexport type HttpMethod = \"get\" | \"post\" | \"put\" | \"patch\" | \"delete\"\nexport type Params = Record<string, string | number | boolean | undefined | null>\n\n/**\n * Fonte de dados dos componentes: o caminho é o mesmo do REST do Engramind sem o `/v1`\n * (`channels`, `memories/m_1/pin`). O navegador nunca chama o Engramind direto: a fonte padrão\n * (`createHttpDataSource`) chama o proxy montado pelo app.\n */\nexport interface EngramindDataSource {\n request<T>(method: HttpMethod, path: string, options?: { params?: Params; body?: unknown; signal?: AbortSignal }): Promise<T>\n}\n\nexport interface HttpDataSourceOptions {\n /** Prefixo das rotas do proxy no app (ex.: `/api/engramind`). */\n basePath: string\n /** Desembrulha a resposta (padrão: `{ success, data }` → `data`; outro JSON passa como está). */\n unwrap?: (json: unknown) => unknown\n headers?: Record<string, string> | (() => Record<string, string>)\n fetch?: typeof fetch\n credentials?: RequestCredentials\n}\n\nconst clean = (params: Params = {}) => Object.entries(params).filter(([, value]) => value !== undefined && value !== null && value !== \"\") as [string, string | number | boolean][]\n\nconst defaultUnwrap = (json: unknown) => (json && typeof json === \"object\" && \"success\" in json && \"data\" in json ? (json as { data: unknown }).data : json)\n\n/** Erro de uma resposta do proxy: `{ success: false, error, code, details }` ou `{ error: { code, message } }`. */\nexport function errorFromResponse(status: number, json: unknown, retryAfter: string | null = null): EngramindError {\n const body = (json && typeof json === \"object\" ? json : {}) as { error?: unknown; code?: unknown; details?: unknown; message?: unknown }\n const nested = body.error && typeof body.error === \"object\" ? (body.error as { code?: unknown; message?: unknown; details?: unknown }) : null\n const message = typeof body.error === \"string\" ? body.error : typeof nested?.message === \"string\" ? nested.message : typeof body.message === \"string\" ? body.message : `Falha na requisição (HTTP ${status}).`\n const code = typeof body.code === \"string\" ? body.code : typeof nested?.code === \"string\" ? (nested.code.startsWith(\"ENGRAMIND_\") ? nested.code : `ENGRAMIND_${nested.code}`) : `HTTP_${status}`\n const seconds = retryAfter ? Number(retryAfter) : NaN\n return new EngramindError(status, message, code, body.details ?? nested?.details, Number.isFinite(seconds) ? seconds : null)\n}\n\nexport function createHttpDataSource(options: HttpDataSourceOptions): EngramindDataSource {\n const base = options.basePath.replace(/\\/+$/, \"\")\n const unwrap = options.unwrap ?? defaultUnwrap\n return {\n async request<T>(method: HttpMethod, path: string, request: { params?: Params; body?: unknown; signal?: AbortSignal } = {}) {\n const query = new URLSearchParams(clean(request.params).map(([key, value]) => [key, String(value)])).toString()\n const url = `${base}/${path.replace(/^\\/+/, \"\")}${query ? `?${query}` : \"\"}`\n const extra = typeof options.headers === \"function\" ? options.headers() : (options.headers ?? {})\n const hasBody = method !== \"get\" && method !== \"delete\"\n let res: Response\n try {\n res = await (options.fetch ?? fetch)(url, {\n method: method.toUpperCase(),\n headers: { Accept: \"application/json\", ...(hasBody ? { \"Content-Type\": \"application/json\" } : {}), ...extra },\n body: hasBody ? JSON.stringify(request.body ?? {}) : undefined,\n credentials: options.credentials ?? \"same-origin\",\n signal: request.signal,\n })\n } catch (error) {\n throw new EngramindError(0, \"Sem conexão com o servidor. Confira a rede e tente novamente.\", \"NETWORK_ERROR\", { reason: error instanceof Error ? error.message : String(error) })\n }\n const text = await res.text()\n let json: unknown = null\n if (text) {\n try {\n json = JSON.parse(text)\n } catch {\n json = null\n }\n }\n if (!res.ok) throw errorFromResponse(res.status, json, res.headers.get(\"retry-after\"))\n return unwrap(json) as T\n },\n }\n}\n\nlet activeSource: EngramindDataSource | null = null\n\n/** Registra a fonte do `EngramindProvider` (uma fonte por página). */\nexport function setActiveDataSource(source: EngramindDataSource | null) {\n activeSource = source\n}\n\nexport function activeDataSource(): EngramindDataSource {\n if (!activeSource) throw new EngramindError(0, \"Monte os componentes do Engramind dentro de <EngramindProvider>.\", \"ENGRAMIND_NO_PROVIDER\")\n return activeSource\n}\n\n/** Código estável de um erro (`ENGRAMIND_CHANNEL_SHARED`...). */\nexport function apiErrorCode(error: unknown): string | undefined {\n if (error instanceof EngramindError) return error.code\n const code = (error as { code?: unknown } | null)?.code\n return typeof code === \"string\" ? code : undefined\n}\n\n/** Mensagem pt-BR de um erro, com um texto padrão. */\nexport function apiErrorMessage(error: unknown, fallback = \"Não foi possível concluir a ação.\"): string {\n if (error instanceof EngramindError) return error.message || fallback\n if (error instanceof Error && error.message) return error.message\n return fallback\n}\n\n/** Status HTTP de um erro. */\nexport const apiErrorStatus = (error: unknown): number | undefined => (error instanceof EngramindError ? error.status : undefined)\n","\"use client\"\n\nimport { createContext, useContext, type ReactNode } from \"react\"\nimport { Bot, type LucideIcon } from \"lucide-react\"\nimport type { ChannelLabel } from \"../engramind/network/channel-labels\"\nimport type { OverviewLayoutMode } from \"../engramind/network/overview-layout\"\nimport { DEFAULT_MESSAGES, type Messages } from \"./messages\"\nimport { historyNavigation, type NavigationAdapter } from \"./navigation\"\n\n/**\n * `app`: o token do próprio app (o app, os agentes dele e os canais que eles alcançam), sem funções de\n * gestor. `manager`: só para o gestor da rede (token admin), libera a visão Apps x canais.\n */\nexport type EngramindMode = \"app\" | \"manager\"\n\nexport interface EngramindHrefs {\n /** Página da rede (os parâmetros `?app=` e `?universo=` são acrescentados). */\n network: string\n /** Página de detalhe de um canal; `null` esconde o link \"Abrir página do canal\". */\n channel: ((slug: string) => string) | null\n}\n\nexport interface RenderLinkProps {\n href: string\n children?: ReactNode\n className?: string\n [key: string]: unknown\n}\n\nexport interface FooterContext {\n /** Distribuição da visão inicial (só fora dos universos). */\n layout?: { value: OverviewLayoutMode; onChange: (value: OverviewLayoutMode) => void }\n}\n\n/** Para onde levar o \"Configurar\". */\nexport type ConfigureTarget = \"connection\" | \"identities\"\n\nexport interface EngramindConfig {\n mode: EngramindMode\n /** Slug do app do token (modo app); a visão inicial é a rede Agentes x canais dele. */\n app: string | null\n /** Nome exibido do app no modo app (padrão: o slug). */\n appName?: string\n /** URL do SSE da lib montado pelo app (`createSseHandler`); `null` desliga o tempo real. */\n events: string | null\n navigation: NavigationAdapter\n renderLink?: (props: RenderLinkProps) => ReactNode\n hrefs: EngramindHrefs\n /** Ícone de cada agente (`app/agente`); padrão: robô. */\n agentIcon: (agent: string) => LucideIcon\n /** Gravações por agente que o app conhece (selo \"gravadas\" do node do agente). */\n agentWrites?: (agent: string) => { total: number; last7d: number } | null\n /** Rótulos legíveis de canais (título e dica no lugar da ponta do slug). */\n channelLabels: ReadonlyMap<string, ChannelLabel>\n messages: Messages\n /** Prazo de desuso fixo (sobrepõe o do Engramind). */\n staleAfterDays?: number\n /**\n * Ação \"Configurar\": `connection` (token recusado ou sem conexão, card do fim da página) ou `identities`\n * (nenhum app, app sem agentes ativos).\n */\n onConfigure?: (target?: ConfigureTarget) => void\n /** Conteúdo extra: o fim da página da rede e o detalhe do canal. */\n slots: {\n footer?: (context: FooterContext) => ReactNode\n channelDetail?: (slug: string) => ReactNode\n }\n /** Prefixo das chaves do `localStorage` (filtros da rede); vazio usa a chave sem prefixo. */\n storagePrefix: string\n}\n\nexport const defaultAgentIcon = (): LucideIcon => Bot\n\nexport const DEFAULT_CONFIG: EngramindConfig = {\n mode: \"app\",\n app: null,\n events: null,\n navigation: historyNavigation,\n hrefs: { network: \"\", channel: null },\n agentIcon: defaultAgentIcon,\n channelLabels: new Map(),\n messages: DEFAULT_MESSAGES,\n slots: {},\n storagePrefix: \"engramind\",\n}\n\nexport const EngramindConfigContext = createContext<EngramindConfig>(DEFAULT_CONFIG)\n\nexport function useEngramindConfig(): EngramindConfig {\n return useContext(EngramindConfigContext)\n}\n\n/** `true` no modo gestor (Apps x canais, apps e configurações globais). */\nexport const useIsManager = () => useEngramindConfig().mode === \"manager\"\n\n/** Texto pt-BR (ou o sobrescrito pelo app) de uma chave do dicionário. */\nexport function useT() {\n const { messages } = useEngramindConfig()\n return (key: keyof Messages, vars?: Record<string, string | number>) => format(messages[key] ?? DEFAULT_MESSAGES[key], vars)\n}\n\nexport function format(template: string, vars?: Record<string, string | number>): string {\n if (!vars) return template\n return template.replace(/\\{(\\w+)\\}/g, (match, name: string) => (name in vars ? String(vars[name]) : match))\n}\n","/**\n * Textos da lib (pt-BR). O app sobrescreve qualquer chave pelo `messages` do `EngramindProvider`; chave\n * ausente usa o texto padrão. `{nome}` é trocado pelo valor correspondente.\n */\nexport const DEFAULT_MESSAGES = {\n \"network.channelNotFound\": \"Canal não encontrado: voltando à rede.\",\n \"network.agentNotFound\": \"Agente não encontrado: voltando à rede.\",\n \"network.appNotFound\": \"App não encontrado: voltando à rede.\",\n \"network.searchFailed\": \"Não foi possível buscar as memórias.\",\n \"network.backToNetwork\": \"Voltar à rede\",\n \"network.noApps.title\": \"Nenhum app no Engramind\",\n \"network.noApps.description\": \"Crie um app e os agentes dele para ver a rede.\",\n \"network.noAgents.title\": \"Este app não tem agentes ativos\",\n \"network.noAgents.description\": \"Crie ou ative um agente deste app na configuração do Engramind.\",\n \"network.noLinkedChannels.title\": \"Os agentes deste app não assinam nenhum canal com memórias\",\n \"network.noLinkedChannels.description\": \"Canais sem memórias ficam fora da rede. Assine um canal ou grave uma memória num canal assinado.\",\n \"network.configure\": \"Configurar\",\n \"network.layout\": \"Distribuição da rede\",\n \"network.newMemory\": \"Nova memória\",\n \"network.agentEmpty\": \"Nenhuma memória nos canais deste agente\",\n \"network.agentNoChannels\": \"Este agente não assina nenhum canal\",\n \"state.configure.title\": \"Reconfigure o Engramind\",\n \"state.configure.description\": \"O Engramind recusou o token do app. Peça um novo token ao gestor e reconfigure o servidor do app.\",\n \"state.noAccess.title\": \"Sem acesso\",\n \"state.noAccess.description\": \"O token do app não alcança este registro.\",\n \"state.retry\": \"Tentar novamente\",\n \"config.agents.title\": \"Agentes\",\n \"config.channels.title\": \"Canais\",\n \"config.tokens.title\": \"Tokens de agente\",\n \"config.webhook.title\": \"Webhook do app\",\n \"config.empty.agents\": \"Nenhum agente neste app.\",\n \"config.newAgent\": \"Novo agente\",\n \"config.newChannel\": \"Novo canal\",\n \"config.webhook.url\": \"URL do webhook\",\n \"config.webhook.save\": \"Salvar webhook\",\n \"config.webhook.remove\": \"Remover webhook\",\n \"config.webhook.rotate\": \"Gerar novo segredo\",\n \"config.webhook.saved\": \"Webhook do app atualizado.\",\n \"config.webhook.secretOnce\": \"Copie o segredo agora: ele não aparece de novo. Configure-o no servidor do app para validar a assinatura.\",\n \"config.webhook.configured\": \"Segredo configurado\",\n \"config.webhook.notConfigured\": \"Sem webhook: a rede atualiza só pelas próprias ações e ao reconsultar.\",\n} as const\n\nexport type MessageKey = keyof typeof DEFAULT_MESSAGES\nexport type Messages = Record<MessageKey, string>\nexport type PartialMessages = Partial<Messages>\n\nexport function mergeMessages(overrides?: PartialMessages): Messages {\n const merged = { ...DEFAULT_MESSAGES } as Messages\n for (const [key, value] of Object.entries(overrides ?? {})) if (typeof value === \"string\" && key in merged) merged[key as MessageKey] = value\n return merged\n}\n","\"use client\"\n\nimport { useCallback, useMemo, useSyncExternalStore } from \"react\"\nimport { useEngramindConfig } from \"./config\"\n\n/**\n * Navegação dos componentes (`?universo=`, `?app=`, links internos). O app pode passar as funções do\n * próprio roteador (`navigation` no provider, ex.: Next.js); o padrão usa o History API do navegador.\n */\nexport interface EngramindRouter {\n push(url: string, options?: { scroll?: boolean }): void\n replace(url: string, options?: { scroll?: boolean }): void\n}\n\nexport interface NavigationAdapter {\n useRouter: () => EngramindRouter\n usePathname: () => string\n useSearchParams: () => { get(name: string): string | null; toString(): string }\n}\n\nconst CHANGE = \"engramind:navigate\"\nconst subscribe = (callback: () => void) => {\n if (typeof window === \"undefined\") return () => undefined\n window.addEventListener(\"popstate\", callback)\n window.addEventListener(CHANGE, callback)\n return () => {\n window.removeEventListener(\"popstate\", callback)\n window.removeEventListener(CHANGE, callback)\n }\n}\nconst href = () => (typeof window === \"undefined\" ? \"\" : window.location.pathname + window.location.search)\n\nfunction useLocation() {\n return useSyncExternalStore(subscribe, href, () => \"\")\n}\n\n/** Navegação padrão pelo History API (sem roteador). */\nexport const historyNavigation: NavigationAdapter = {\n useRouter() {\n const go = useCallback((method: \"pushState\" | \"replaceState\") => (url: string) => {\n window.history[method](null, \"\", url)\n window.dispatchEvent(new Event(CHANGE))\n }, [])\n return useMemo(() => ({ push: go(\"pushState\"), replace: go(\"replaceState\") }), [go])\n },\n usePathname() {\n const location = useLocation()\n return location.split(\"?\")[0] ?? \"\"\n },\n useSearchParams() {\n const location = useLocation()\n return useMemo(() => new URLSearchParams(location.split(\"?\")[1] ?? \"\"), [location])\n },\n}\n\nexport function useRouter(): EngramindRouter {\n return useEngramindConfig().navigation.useRouter()\n}\n\nexport function usePathname(): string {\n return useEngramindConfig().navigation.usePathname()\n}\n\nexport function useSearchParams() {\n return useEngramindConfig().navigation.useSearchParams()\n}\n","/**\n * Toasts da lib: delegam ao `notify` do `EngramindProvider` (o app liga ao seu sistema de toasts, como o\n * `sonner`). Sem `notify`, nada aparece. Mesma forma do `sonner` (`toast.success(...)`).\n */\nexport type NotifyKind = \"success\" | \"error\" | \"info\" | \"warning\"\nexport type Notify = (kind: NotifyKind, message: string, options?: { description?: string; id?: string | number }) => void\n\nlet notifier: Notify | null = null\n\nexport function setNotifier(next: Notify | null) {\n notifier = next\n}\n\nconst send = (kind: NotifyKind) => (message: string, options?: { description?: string; id?: string | number }) => notifier?.(kind, message, options)\n\nexport const toast = { success: send(\"success\"), error: send(\"error\"), info: send(\"info\"), warning: send(\"warning\") }\n","\"use client\"\n\nimport type { LiveEvent } from \"../../core/events\"\n\n/**\n * Conexão SSE compartilhada por URL (`EventSource`), com contagem de referências. Quando cai, reconecta\n * com espera crescente (1 s → 30 s) e avisa os ouvintes `onReconnect` (a tela relê o que pode ter perdido).\n */\ntype Listener = (event: LiveEvent) => void\ntype StatusListener = (connected: boolean) => void\n\ninterface LiveConnection {\n refs: number\n listeners: Set<Listener>\n reconnects: Set<() => void>\n status: Set<StatusListener>\n source: EventSource | null\n timer: ReturnType<typeof setTimeout> | null\n attempt: number\n hadError: boolean\n}\n\nconst connections = new Map<string, LiveConnection>()\nconst MAX_DELAY_MS = 30_000\n\nexport const isLiveAvailable = () => typeof window !== \"undefined\" && typeof window.EventSource === \"function\"\n\nfunction open(url: string, connection: LiveConnection) {\n const source = new EventSource(url, { withCredentials: true })\n connection.source = source\n source.addEventListener(\"open\", () => {\n connection.attempt = 0\n for (const listener of connection.status) listener(true)\n if (connection.hadError) {\n connection.hadError = false\n for (const listener of connection.reconnects) listener()\n }\n })\n source.addEventListener(\"engramind\", (message) => {\n let event: LiveEvent | null = null\n try {\n event = JSON.parse((message as MessageEvent<string>).data) as LiveEvent\n } catch {\n return\n }\n if (!event || typeof event.type !== \"string\") return\n for (const listener of connection.listeners) listener(event)\n })\n source.addEventListener(\"error\", () => {\n connection.hadError = true\n for (const listener of connection.status) listener(false)\n if (source.readyState !== EventSource.CLOSED) return\n source.close()\n connection.source = null\n const delay = Math.min(MAX_DELAY_MS, 1000 * 2 ** connection.attempt)\n connection.attempt += 1\n connection.timer = setTimeout(() => {\n connection.timer = null\n if (connection.refs > 0) open(url, connection)\n }, delay)\n })\n}\n\nexport interface LiveSubscription {\n onEvent?: Listener\n onReconnect?: () => void\n onStatus?: StatusListener\n}\n\n/** Assina o SSE em `url`; devolve a função que cancela a assinatura. */\nexport function subscribeLive(url: string, subscription: LiveSubscription): () => void {\n if (!isLiveAvailable()) return () => undefined\n let connection = connections.get(url)\n if (!connection) {\n connection = { refs: 0, listeners: new Set(), reconnects: new Set(), status: new Set(), source: null, timer: null, attempt: 0, hadError: false }\n connections.set(url, connection)\n }\n connection.refs += 1\n if (subscription.onEvent) connection.listeners.add(subscription.onEvent)\n if (subscription.onReconnect) connection.reconnects.add(subscription.onReconnect)\n if (subscription.onStatus) connection.status.add(subscription.onStatus)\n if (!connection.source && !connection.timer) open(url, connection)\n const current = connection\n return () => {\n if (subscription.onEvent) current.listeners.delete(subscription.onEvent)\n if (subscription.onReconnect) current.reconnects.delete(subscription.onReconnect)\n if (subscription.onStatus) current.status.delete(subscription.onStatus)\n current.refs -= 1\n if (current.refs > 0) return\n current.source?.close()\n if (current.timer) clearTimeout(current.timer)\n connections.delete(url)\n }\n}\n","\"use client\"\n\nimport { useCallback, useEffect, useMemo, useState } from \"react\"\nimport { AnimatePresence, motion } from \"framer-motion\"\nimport { AppWindow, Unplug, UserX } from \"lucide-react\"\nimport { toast } from \"../../../lib/toast\"\nimport { usePersistentState } from \"../../../hooks/usePersistentState\"\nimport { apiErrorMessage } from \"../../../lib/api\"\nimport { EmptyState } from \"../../../components/feedback/EmptyState\"\nimport { useEngramindConfig, useT } from \"../../../lib/config\"\nimport { channelsWithMemories } from \"../../network/app-network\"\nimport { channelColors, pickChannelColors, subscriptionLinks } from \"../../network/network-math\"\nimport { clearNetworkFilters, DEFAULT_NETWORK_FILTERS, hasActiveFilters, matchesFilters, NETWORK_FILTERS_STORAGE_KEY, networkFiltersSchema, type NetworkFilters } from \"../../network/filters\"\nimport type { NetworkMemory } from \"../../network/types\"\nimport { useEngramindRealtime } from \"../../hooks/useEngramind\"\nimport { useEngramindNetwork } from \"../../hooks/useEngramindNetwork\"\nimport { useNetworkSearch } from \"../../hooks/useNetworkSearch\"\nimport { QueryBoundary } from \"../shared/QueryBoundary\"\nimport { ImportMemoriesDialog } from \"../page/memories/ImportMemoriesDialog\"\nimport { ChannelDialog } from \"../page/channels/ChannelDialog\"\nimport { ChannelBySubscriptionDialog } from \"../page/channels/ChannelBySubscriptionDialog\"\nimport { ChannelPanel } from \"./ChannelPanel\"\nimport { AgentLabelsProvider } from \"./AgentLabels\"\nimport { ChannelLabelsProvider, useChannelLabels } from \"./ChannelName\"\nimport { channelDisplayName } from \"../../network/channel-labels\"\nimport { MemoryUniverse } from \"./MemoryUniverse\"\nimport { NetworkBreadcrumb } from \"./NetworkBreadcrumb\"\nimport { NetworkSkeleton } from \"./NetworkSkeleton\"\nimport { NetworkActions, NetworkToolbar } from \"./NetworkToolbar\"\nimport { OverviewView } from \"./OverviewView\"\nimport { AppsOverviewView } from \"./AppsOverviewView\"\nimport { EmptyChannelList } from \"./overview-shared\"\nimport { NetworkFooter } from \"./NetworkFooter\"\nimport { useRawMemoryActions } from \"./useRawMemoryActions\"\nimport { useUniverseParam } from \"./useUniverseParam\"\n\n/**\n * Rede do Engramind: no modo gestor, a visão inicial Apps x canais e a visão Agentes x canais de um app\n * (`?app=`); no modo app, a visão inicial é a rede Agentes x canais do próprio app. Universo do canal e\n * universo do agente (`?universo=`), com a gestão de canais e memórias. As redes escondem os canais sem\n * nenhuma memória (lista \"Sem memórias (N)\").\n */\nexport function EngramindNetwork({ onConfigure }: { onConfigure?: () => void }) {\n return (\n <ChannelLabelsProvider>\n <EngramindNetworkContent onConfigure={onConfigure} />\n </ChannelLabelsProvider>\n )\n}\n\nfunction EngramindNetworkContent({ onConfigure }: { onConfigure?: () => void }) {\n useEngramindRealtime()\n const data = useEngramindNetwork()\n return (\n <AgentLabelsProvider value={data.agentNames}>\n <EngramindNetworkView onConfigure={onConfigure} data={data} />\n </AgentLabelsProvider>\n )\n}\n\nfunction EngramindNetworkView({ onConfigure: onConfigureProp, data }: { onConfigure?: () => void; data: ReturnType<typeof useEngramindNetwork> }) {\n const config = useEngramindConfig()\n const t = useT()\n const manager = config.mode === \"manager\"\n const onConfigure = onConfigureProp ?? (config.onConfigure ? () => config.onConfigure!(\"connection\") : undefined)\n // Nenhum app ou app sem agentes: leva à configuração das identidades (agentes e apps).\n const configureIdentities = config.onConfigure ? () => config.onConfigure!(\"identities\") : onConfigure\n const { value: filters, setValue: setFilters } = usePersistentState<NetworkFilters>(config.storagePrefix ? `${config.storagePrefix}:${NETWORK_FILTERS_STORAGE_KEY}` : NETWORK_FILTERS_STORAGE_KEY, networkFiltersSchema, DEFAULT_NETWORK_FILTERS)\n const patchFilters = useCallback((patch: Partial<NetworkFilters>) => setFilters((previous) => ({ ...previous, ...patch })), [setFilters])\n const clearFilters = useCallback(() => setFilters((previous) => clearNetworkFilters(previous)), [setFilters])\n const includeArchived = filters.includeArchived\n const [panel, setPanel] = useState<string | null>(null)\n const [dialog, setDialog] = useState<\"import\" | \"channel\" | null>(null)\n const { universe, app: appSlug, open, openApp, back, home } = useUniverseParam({ escapeEnabled: panel === null && dialog === null, fixedApp: manager ? null : data.ownApp })\n\n const rawById = useMemo(() => new Map(data.rawMemories.map((memory) => [memory.id, memory])), [data.rawMemories])\n const raw = useRawMemoryActions({ rawById, channels: data.rawChannels, categories: data.categories, limits: data.limits })\n const links = useMemo(() => subscriptionLinks(data.subscriptions, data.channels, true), [data.subscriptions, data.channels])\n const visibleChannels = useMemo(() => data.channels.filter((channel) => includeArchived || !channel.archived), [data.channels, includeArchived])\n const visibleLinks = useMemo(() => subscriptionLinks(data.subscriptions, data.channels, includeArchived), [data.subscriptions, data.channels, includeArchived])\n\n const channel = universe?.kind === \"channel\" ? data.channels.find((item) => item.slug === universe.slug) : undefined\n const agent = universe?.kind === \"agent\" ? data.agents.find((item) => item.id === universe.id) : undefined\n // Canal recém-criado (Novo canal abre o universo dele): espera a lista de canais ser relida.\n const missing = !data.isLoading && !data.error && universe !== null && !channel && !agent && !(universe.kind === \"channel\" && data.channelsFetching)\n useEffect(() => {\n if (!missing) return\n toast.error(universe?.kind === \"channel\" ? t(\"network.channelNotFound\") : t(\"network.agentNotFound\"))\n back({ replace: true })\n }, [missing, universe, back])\n const app = appSlug ? data.apps.find((item) => item.slug === appSlug) : undefined\n const missingApp = manager && !data.isLoading && !data.error && appSlug !== null && !app\n useEffect(() => {\n if (!missingApp) return\n toast.error(t(\"network.appNotFound\"))\n home({ replace: true })\n }, [missingApp, home])\n\n // As duas redes (Apps x canais e Agentes x canais) só mostram canais com alguma memória (inativas contam).\n const networkChannels = useMemo(() => channelsWithMemories(visibleChannels, data.memories), [visibleChannels, data.memories])\n const networkLinks = useMemo(() => {\n const slugs = new Set(networkChannels.map((item) => item.slug))\n return visibleLinks.filter((link) => slugs.has(link.channel))\n }, [networkChannels, visibleLinks])\n const appAgents = useMemo(() => (app ? data.agents.filter((item) => item.app === app.slug) : []), [app, data.agents])\n const appLinksOfApp = useMemo(() => {\n const ids = new Set(appAgents.map((item) => item.id))\n return networkLinks.filter((link) => ids.has(link.agent))\n }, [appAgents, networkLinks])\n const appChannelList = useMemo(() => {\n const slugs = new Set(appLinksOfApp.map((link) => link.channel))\n return networkChannels.filter((item) => slugs.has(item.slug))\n }, [appLinksOfApp, networkChannels])\n // Canais assinados pelo app, mesmo sem memória (a rede esconde; o card de estatísticas abre o painel).\n const appLinkedChannelSlugs = useMemo(() => {\n if (!app) return null\n const ids = new Set(appAgents.map((item) => item.id))\n return new Set(visibleLinks.filter((link) => ids.has(link.agent)).map((link) => link.channel))\n }, [app, appAgents, visibleLinks])\n // Canais sem memória: fora do canvas, continuam editáveis pelo card de estatísticas (OPE-129).\n const emptyChannels = useMemo(() => {\n if (universe) return []\n const shown = new Set(networkChannels.map((item) => item.slug))\n return visibleChannels.filter((item) => !shown.has(item.slug) && (!appLinkedChannelSlugs || appLinkedChannelSlugs.has(item.slug)))\n }, [universe, networkChannels, visibleChannels, appLinkedChannelSlugs])\n\n const agentChannels = useMemo(() => (agent ? [...new Set(links.filter((link) => link.agent === agent.id && (includeArchived || !data.channels.find((item) => item.slug === link.channel)?.archived)).map((link) => link.channel))] : []), [agent, links, includeArchived, data.channels])\n // Cores sobre todos os canais (estáveis entre universos); o universo só lê as dos seus canais e dá o\n // roxo primário ao canal com mais memórias nele (`universeChannelColors`, no MemoryUniverse).\n const allColors = useMemo(() => channelColors(data.channels.map((item) => item.slug)), [data.channels])\n const colors = useMemo(() => pickChannelColors(allColors, agentChannels), [allColors, agentChannels])\n const universeMemories = useMemo(() => {\n if (channel) return data.memories.filter((memory) => memory.channel === channel.slug)\n if (agent) return data.memories.filter((memory) => agentChannels.includes(memory.channel))\n return []\n }, [channel, agent, agentChannels, data.memories])\n // Canais da rede em tela: os do app aberto ou todos os da visão de apps.\n const overviewChannels = app ? appChannelList : networkChannels\n const overviewMemories = useMemo(() => {\n const slugs = new Set(overviewChannels.map((item) => item.slug))\n return data.memories.filter((memory) => slugs.has(memory.channel))\n }, [data.memories, overviewChannels])\n\n // A busca cita os canais da visão atual (o Engramind só busca nos `manage` e arquivados citados).\n const viewChannels = useMemo(() => (channel ? [channel.slug] : agent ? agentChannels : overviewChannels.map((item) => item.slug)), [channel, agent, agentChannels, overviewChannels])\n const searchChannels = useMemo(() => (filters.channels.length ? viewChannels.filter((slug) => filters.channels.includes(slug)) : viewChannels), [viewChannels, filters.channels])\n const searching = filters.search.trim().length > 0\n const search = useNetworkSearch({ query: filters.search, channels: searchChannels, categories: filters.categories, fusion: data.searchFusion, enabled: searchChannels.length > 0 })\n // Busca que falhou não reaproveita o destaque do termo anterior: nada destaca e a barra avisa.\n const searchFailed = searching && searchChannels.length > 0 && search.isError\n const searchError = searchFailed ? apiErrorMessage(search.error, t(\"network.searchFailed\")) : null\n const searchIds = useMemo<ReadonlySet<string> | null>(() => (!searching || searchFailed ? null : searchChannels.length ? (search.data?.ids ?? null) : new Set<string>()), [searching, searchFailed, searchChannels.length, search.data])\n useEffect(() => {\n if (search.errorUpdatedAt && searchFailed) toast.error(`Busca falhou: ${apiErrorMessage(search.error, \"Não foi possível buscar as memórias.\")}`)\n // Um aviso por falha (o `errorUpdatedAt` muda a cada erro).\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [search.errorUpdatedAt])\n\n const filtering = hasActiveFilters(filters, searchIds)\n const isMatch = useMemo(() => (filtering ? (memory: NetworkMemory) => matchesFilters(memory, filters, searchIds) : null), [filtering, filters, searchIds])\n const hitsByChannel = useMemo(() => {\n if (!isMatch) return null\n const hits = new Map<string, number>()\n for (const memory of data.memories) if (isMatch(memory)) hits.set(memory.channel, (hits.get(memory.channel) ?? 0) + 1)\n return hits\n }, [isMatch, data.memories])\n const viewMemories = channel || agent ? universeMemories : overviewMemories\n const total = isMatch ? viewMemories.filter(isMatch).length : viewMemories.length\n const filterOptions = useMemo(\n () => ({\n channels: data.channels.filter((item) => includeArchived || !item.archived).map((item) => item.slug),\n categories: data.categories.map((item) => item.key),\n authors: [...new Set(data.memories.map((memory) => memory.author).filter((author): author is string => Boolean(author)))].sort(),\n }),\n [data.channels, data.categories, data.memories, includeArchived],\n )\n\n const channelLabels = useChannelLabels()\n const current = channel ? { kind: \"channel\" as const, id: channel.slug, label: channelDisplayName(channel.slug, channelLabels) } : agent ? { kind: \"agent\" as const, id: agent.id, label: agent.name } : null\n const viewKey = current ? `${current.kind}:${current.id}` : app ? `app:${app.slug}` : \"apps\"\n // Modo app: a visão do app é a inicial (sem \"voltar\"); os estados vazios levam à configuração.\n const emptyAction = manager ? { actionLabel: t(\"network.backToNetwork\"), onAction: () => back() } : configureIdentities ? { actionLabel: t(\"network.configure\"), onAction: configureIdentities } : {}\n return (\n <div className=\"flex flex-col gap-3\">\n <NetworkBreadcrumb\n app={app && manager ? { label: app.name, onOpen: () => openApp(app.slug) } : null}\n current={current}\n onBack={() => back()}\n onHome={() => home()}\n actions={<NetworkActions onNewChannel={() => setDialog(\"channel\")} onImport={() => setDialog(\"import\")} importDisabled={data.channels.every((item) => item.archived)} onChannelMenu={channel ? () => setPanel(channel.slug) : undefined} />}\n />\n <NetworkToolbar\n filters={filters}\n onFilters={patchFilters}\n options={filterOptions}\n onClear={clearFilters}\n total={total}\n textOnly={searching && !searchFailed && search.data?.textOnly === true}\n searchError={searchError}\n onRetrySearch={() => void search.refetch()}\n />\n <QueryBoundary isLoading={data.isLoading} error={data.error} onRetry={data.refetch} skeleton={<NetworkSkeleton />} onConfigure={onConfigure}>\n <AnimatePresence mode=\"wait\" initial={false}>\n <motion.div key={viewKey} initial={{ opacity: 0, scale: 0.96 }} animate={{ opacity: 1, scale: 1 }} exit={{ opacity: 0, scale: 1.04 }} transition={{ duration: 0.22 }}>\n {channel ? (\n <MemoryUniverse\n center={{ kind: \"channel\", id: channel.slug, label: channel.slug, archived: channel.archived }}\n memories={universeMemories}\n staleAfterDays={data.staleAfterDays}\n isMatch={isMatch}\n actions={channel.archived ? { ...raw.actions, readOnly: true } : raw.actions}\n localRemovals={raw.localRemovals}\n subscribers={new Set(links.filter((link) => link.channel === channel.slug).map((link) => link.agent)).size}\n dataVersion={data.memoriesUpdatedAt}\n onCreate={channel.archived ? null : () => raw.openCreate(channel.slug)}\n createLabel={t(\"network.newMemory\")}\n />\n ) : agent ? (\n <MemoryUniverse\n center={{ kind: \"agent\", id: agent.id, label: agent.name }}\n memories={universeMemories}\n staleAfterDays={data.staleAfterDays}\n channelColors={colors}\n isMatch={isMatch}\n actions={raw.actions}\n localRemovals={raw.localRemovals}\n dataVersion={data.memoriesUpdatedAt}\n emptyTitle={agentChannels.length ? t(\"network.agentEmpty\") : t(\"network.agentNoChannels\")}\n />\n ) : app ? (\n !appAgents.length ? (\n <EmptyState icon={UserX} title={t(\"network.noAgents.title\")} description={t(\"network.noAgents.description\")} {...emptyAction} />\n ) : !appChannelList.length ? (\n <EmptyState icon={Unplug} title={t(\"network.noLinkedChannels.title\")} description={t(\"network.noLinkedChannels.description\")} {...emptyAction}>\n <EmptyChannelList channels={emptyChannels} onOpen={setPanel} className=\"w-full max-w-sm border-t-0 pt-0 text-left\" />\n </EmptyState>\n ) : (\n <OverviewView\n agents={appAgents}\n channels={appChannelList}\n emptyChannels={emptyChannels}\n links={appLinksOfApp}\n memories={overviewMemories}\n allMemories={data.memories}\n title={app.name}\n layout={filters.overviewLayout}\n hitsByChannel={hitsByChannel}\n onOpenAgent={(id) => open({ kind: \"agent\", id })}\n onOpenChannel={(slug) => open({ kind: \"channel\", slug })}\n onChannelMenu={setPanel}\n />\n )\n ) : !manager ? (\n <EmptyState icon={UserX} title={t(\"network.noAgents.title\")} description={t(\"network.noAgents.description\")} {...emptyAction} />\n ) : !data.apps.length ? (\n <EmptyState icon={AppWindow} title={t(\"network.noApps.title\")} description={t(\"network.noApps.description\")} actionLabel={configureIdentities ? t(\"network.configure\") : undefined} onAction={configureIdentities} />\n ) : (\n <AppsOverviewView\n apps={data.apps}\n agents={data.agents}\n channels={networkChannels}\n emptyChannels={emptyChannels}\n links={networkLinks}\n memories={overviewMemories}\n allMemories={data.memories}\n layout={filters.overviewLayout}\n hitsByChannel={hitsByChannel}\n onOpenApp={openApp}\n onOpenChannel={(slug) => open({ kind: \"channel\", slug })}\n onChannelMenu={setPanel}\n />\n )}\n </motion.div>\n </AnimatePresence>\n </QueryBoundary>\n {/* Fim da página (OPE-113): o resumo, Configurar, Saiba mais e a distribuição da visão inicial. */}\n <NetworkFooter layout={universe ? undefined : { value: filters.overviewLayout, onChange: (overviewLayout) => patchFilters({ overviewLayout }) }} />\n <ChannelPanel channel={data.rawChannels.find((item) => item.slug === panel) ?? null} onOpenChange={(next) => !next && setPanel(null)} onDeleted={(slug) => universe?.kind === \"channel\" && universe.slug === slug && back()} />\n {dialog === \"channel\" &&\n (manager ? (\n <ChannelDialog key=\"new\" channel={null} open onOpenChange={(next) => !next && setDialog(null)} onCreated={(slug) => open({ kind: \"channel\", slug })} />\n ) : (\n <ChannelBySubscriptionDialog agents={data.rawAgents} open onOpenChange={(next) => !next && setDialog(null)} onCreated={(slug) => open({ kind: \"channel\", slug })} />\n ))}\n {dialog === \"import\" && <ImportMemoriesDialog channels={data.rawChannels} maxBatch={data.maxBatch} onOpenChange={(next) => !next && setDialog(null)} />}\n {raw.dialogs}\n </div>\n )\n}\n","\"use client\"\n\nimport { useCallback, useSyncExternalStore, type SetStateAction } from \"react\"\nimport type { ZodType } from \"zod\"\n\n/**\n * Estado salvo no `localStorage` sem prazo (ex.: filtros de uma tela), validado por um schema Zod\n * — dado corrompido ou de versão antiga volta ao padrão. Sincroniza entre componentes da mesma\n * aba e entre abas (evento `storage`). Versione a chave ao mudar o formato (`…:v2`).\n *\n * `ready` é `false` no servidor e na hidratação: mostre um esqueleto até lá para não piscar os\n * valores padrão (padrão `areFiltersReady` do Smart Desk).\n */\n\nconst LOCAL_EVENT = \"opex:persistent-state\"\n\nconst cache = new Map<string, { raw: string | null; value: unknown }>()\n\nfunction read<T>(key: string, schema: ZodType<T, unknown>, fallback: T): T {\n let raw: string | null = null\n try {\n raw = window.localStorage.getItem(key)\n } catch {\n return fallback\n }\n const hit = cache.get(key)\n if (hit && hit.raw === raw) return hit.value as T\n let value = fallback\n if (raw !== null) {\n try {\n const parsed = schema.safeParse(JSON.parse(raw))\n if (parsed.success) value = parsed.data\n } catch {\n // JSON inválido: padrão.\n }\n }\n cache.set(key, { raw, value })\n return value\n}\n\nfunction subscribe(key: string, callback: () => void): () => void {\n const onStorage = (event: StorageEvent) => {\n if (event.key === null || event.key === key) callback()\n }\n const onLocal = (event: Event) => {\n if ((event as CustomEvent<string>).detail === key) callback()\n }\n window.addEventListener(\"storage\", onStorage)\n window.addEventListener(LOCAL_EVENT, onLocal)\n return () => {\n window.removeEventListener(\"storage\", onStorage)\n window.removeEventListener(LOCAL_EVENT, onLocal)\n }\n}\n\nconst subscribeNoop = () => () => {}\n\n/**\n * Leitura imperativa do mesmo estado persistido (mesma validação e mesmo cache do hook). Usada por\n * código fora do React (ex.: comandos `:set` do editor Vim).\n */\nexport function readPersistentState<T>(key: string, schema: ZodType<T, unknown>, fallback: T): T {\n if (typeof window === \"undefined\") return fallback\n return read(key, schema, fallback)\n}\n\n/** Gravação imperativa do estado persistido, notificando os componentes da mesma aba. */\nexport function writePersistentState<T>(key: string, value: T): void {\n if (typeof window === \"undefined\") return\n try {\n window.localStorage.setItem(key, JSON.stringify(value))\n } catch {\n // Armazenamento cheio/bloqueado: mantém só na memória desta sessão.\n cache.set(key, { raw: null, value })\n }\n window.dispatchEvent(new CustomEvent(LOCAL_EVENT, { detail: key }))\n}\n\nexport function usePersistentState<T>(\n key: string,\n schema: ZodType<T, unknown>,\n fallback: T,\n): { value: T; setValue: (next: SetStateAction<T>) => void; reset: () => void; ready: boolean } {\n const value = useSyncExternalStore(\n useCallback((callback: () => void) => subscribe(key, callback), [key]),\n () => read(key, schema, fallback),\n () => fallback,\n )\n const ready = useSyncExternalStore(\n subscribeNoop,\n () => true,\n () => false,\n )\n\n const setValue = useCallback(\n (next: SetStateAction<T>) => {\n const current = read(key, schema, fallback)\n const resolved = typeof next === \"function\" ? (next as (prev: T) => T)(current) : next\n try {\n window.localStorage.setItem(key, JSON.stringify(resolved))\n } catch {\n // Armazenamento cheio/bloqueado: mantém só na memória desta sessão.\n cache.set(key, { raw: null, value: resolved })\n }\n window.dispatchEvent(new CustomEvent(LOCAL_EVENT, { detail: key }))\n },\n [key, schema, fallback],\n )\n\n const reset = useCallback(() => setValue(fallback), [setValue, fallback])\n\n return { value, setValue, reset, ready }\n}\n","\"use client\"\n\nimport type { ReactNode } from \"react\"\nimport { motion } from \"framer-motion\"\nimport type { LucideIcon } from \"lucide-react\"\nimport { Inbox } from \"lucide-react\"\nimport { Button } from \"../ui/button\"\nimport { fadeUp } from \"../motion/presets\"\n\ninterface EmptyStateProps {\n icon?: LucideIcon\n title: string\n description?: string\n actionLabel?: string\n onAction?: () => void\n children?: ReactNode\n}\n\n/** Estado vazio padrão: ícone + texto pt-BR + ação opcional. */\nexport function EmptyState({ icon: Icon = Inbox, title, description, actionLabel, onAction, children }: EmptyStateProps) {\n return (\n <motion.div\n variants={fadeUp}\n initial=\"hidden\"\n animate=\"visible\"\n className=\"flex flex-col items-center justify-center gap-3 px-4 py-14 text-center\"\n >\n <div className=\"rounded-full bg-muted p-3\">\n <Icon className=\"h-6 w-6 text-muted-foreground\" aria-hidden />\n </div>\n <div className=\"max-w-sm space-y-1\">\n <p className=\"text-sm font-semibold text-foreground\">{title}</p>\n {description && <p className=\"text-xs text-muted-foreground\">{description}</p>}\n </div>\n {actionLabel && onAction && (\n <Button size=\"sm\" variant=\"outline\" onClick={onAction}>\n {actionLabel}\n </Button>\n )}\n {children}\n </motion.div>\n )\n}\n","import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../../lib/utils\"\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground shadow hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90\",\n outline:\n \"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground\",\n secondary:\n \"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2\",\n sm: \"h-8 rounded-md px-3 text-xs\",\n lg: \"h-10 rounded-md px-8\",\n icon: \"h-9 w-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : \"button\"\n return (\n <Comp\n className={cn(buttonVariants({ variant, size, className }))}\n ref={ref}\n {...props}\n />\n )\n }\n)\nButton.displayName = \"Button\"\n\nexport { Button, buttonVariants }\n","import type { Transition, Variants } from \"framer-motion\"\n\n/** Durações e presets de animação do app (≈150–300 ms, sem bloquear a interação). */\nexport const DURATION = { fast: 0.15, base: 0.2, slow: 0.3 } as const\n\nexport const easeOut: Transition = { duration: DURATION.base, ease: \"easeOut\" }\n\nexport const fadeUp: Variants = {\n hidden: { opacity: 0, y: 8 },\n visible: { opacity: 1, y: 0, transition: easeOut },\n exit: { opacity: 0, y: -6, transition: { duration: DURATION.fast } },\n}\n\nexport const listContainer: Variants = {\n visible: { transition: { staggerChildren: 0.04 } },\n}\n\nexport const listItem: Variants = {\n hidden: { opacity: 0, y: 6 },\n visible: { opacity: 1, y: 0, transition: easeOut },\n exit: { opacity: 0, x: -8, transition: { duration: DURATION.fast } },\n}\n\n/** Troca de abas/etapas (`AnimatePresence mode=\"wait\"`). */\nexport const tabSwap: Variants = {\n hidden: { opacity: 0, x: 12 },\n visible: { opacity: 1, x: 0, transition: easeOut },\n exit: { opacity: 0, x: -12, transition: { duration: DURATION.fast } },\n}\n\n/** Reversão animada de resposta otimista que falhou. */\nexport const shakeOnError = { x: [0, -6, 6, -4, 4, 0], transition: { duration: DURATION.slow } }\n","import type { NetworkLink, SubscriptionMode } from \"./types\"\n\n/**\n * Visão inicial Apps x canais (OPE-129, puro): os links por agente agregados por app e o corte dos\n * canais vazios. Decisão do dono no plano aprovado: as duas redes (Apps x canais e Agentes x canais)\n * escondem o canal **sem nenhuma memória**; inativas contam (só some com zero de qualquer status).\n * Os universos, o filtro Canal, o painel do canal e o Importar continuam com todos os canais.\n */\n\n/** Só os canais com ao menos uma memória (de qualquer status), na ordem recebida. */\nexport function channelsWithMemories<T extends { slug: string }>(channels: readonly T[], memories: readonly { channel: string }[]): T[] {\n const used = new Set(memories.map((memory) => memory.channel))\n return channels.filter((channel) => used.has(channel.slug))\n}\n\n/** App de um agente (`app/agente` → `app`). */\nexport const appOfAgent = (agent: string): string => agent.split(\"/\")[0] ?? agent\n\n/** Id da aresta app → canal na visão de apps. */\nexport const appLinkEdgeId = (app: string, channel: string) => `app:${app}→${channel}`\n\n/** Link app → canal: as assinaturas de todos os agentes do app naquele canal. */\nexport interface AppLink {\n id: string\n app: string\n channel: string\n /** Modos das assinaturas, sem repetição (ordem de chegada). */\n modes: SubscriptionMode[]\n /** Agentes (`app/agente`) que assinam o canal, sem repetição. */\n agents: string[]\n}\n\n/** Um link por par (app, canal), na ordem em que o par aparece pela primeira vez. */\nexport function appLinks(links: readonly NetworkLink[]): AppLink[] {\n const byKey = new Map<string, AppLink>()\n for (const link of links) {\n const app = appOfAgent(link.agent)\n const id = appLinkEdgeId(app, link.channel)\n const current = byKey.get(id) ?? { id, app, channel: link.channel, modes: [], agents: [] }\n if (!current.modes.includes(link.mode)) current.modes.push(link.mode)\n if (!current.agents.includes(link.agent)) current.agents.push(link.agent)\n byKey.set(id, current)\n }\n return [...byKey.values()]\n}\n\n/** Canais assinados por algum agente do app (sem repetição, na ordem dos links). */\nexport function appChannels(app: string, links: readonly NetworkLink[]): string[] {\n return [...new Set(links.filter((link) => appOfAgent(link.agent) === app).map((link) => link.channel))]\n}\n\n/** Alcance do app: soma das memórias (ativas) dos canais que os agentes dele assinam, cada canal uma vez. */\nexport function appReach(links: readonly AppLink[], countByChannel: ReadonlyMap<string, number>): Map<string, number> {\n const reach = new Map<string, number>()\n for (const link of links) reach.set(link.app, (reach.get(link.app) ?? 0) + (countByChannel.get(link.channel) ?? 0))\n return reach\n}\n","import type { MemoryStatus, NetworkChannel, NetworkLink, NetworkMemory, SubscriptionMode } from \"./types\"\n\n/**\n * Cálculos puros da rede \"universo de partículas\" do Engramind (OPE-109, OPE-114): cor pelo canal,\n * distância do centro pela idade, tamanho pelo uso, brilho pelo prazo do consolidador, cor estável dos\n * canais, links das assinaturas e layout.\n * Cores só por tokens do tema (`color-mix` sobre variáveis CSS), nunca valores fixos.\n */\n\nconst DAY_MS = 24 * 3600 * 1000\nexport const PARTICLE_MIN_PX = 10\nexport const PARTICLE_MAX_PX = 34\n/** Fixada nunca some: brilho mínimo visível. */\nexport const PINNED_MIN_BRIGHTNESS = 0.25\n/** Padrão do Engramind para `consolidation.stale_after_days` (quando a configuração não vem). */\nexport const DEFAULT_STALE_AFTER_DAYS = 90\n\nconst time = (iso: string | null | undefined): number => {\n if (!iso) return Number.NaN\n return new Date(iso).getTime()\n}\n\n/** \"Agente Opex\" → \"Opex\" (os nodes mostram o nome sem o prefixo). */\nexport function agentDisplayName(name: string): string {\n const stripped = name.replace(/^\\s*agente\\s+/i, \"\").trim()\n return stripped || name.trim()\n}\n\n/** Relevância: consultas + injeções somadas. */\nexport const memoryUses = (memory: Pick<NetworkMemory, \"retrievals\" | \"injections\">): number => Math.max(0, memory.retrievals) + Math.max(0, memory.injections)\n\n/**\n * Último uso: o maior entre a última recuperação no Engramind (`last_retrieved_at`) e a criação. A verificação\n * do consolidador (`verified_at`) não é consumo e não conta.\n */\nexport function lastUseOf(memory: Pick<NetworkMemory, \"id\" | \"lastRetrievedAt\" | \"createdAt\">): string {\n const candidates = [memory.lastRetrievedAt, memory.createdAt].filter((value): value is string => Boolean(value) && !Number.isNaN(time(value)))\n return candidates.reduce((best, value) => (time(value) > time(best) ? value : best), memory.createdAt)\n}\n\n/** Data de uso real (sem cair na criação): `null` = \"nunca usada\". */\nexport function lastRealUseOf(memory: Pick<NetworkMemory, \"id\" | \"lastRetrievedAt\">): string | null {\n const candidates = [memory.lastRetrievedAt].filter((value): value is string => Boolean(value) && !Number.isNaN(time(value)))\n if (!candidates.length) return null\n return candidates.reduce((best, value) => (time(value) > time(best) ? value : best))\n}\n\n/** Tamanho pela soma de consultas e injeções, em escala logarítmica suave relativa ao universo. */\nexport function particleSize(uses: number, maxUses: number): number {\n if (maxUses <= 0 || uses <= 0) return PARTICLE_MIN_PX\n const ratio = Math.log1p(uses) / Math.log1p(maxUses)\n return Math.round((PARTICLE_MIN_PX + (PARTICLE_MAX_PX - PARTICLE_MIN_PX) * clamp01(ratio)) * 10) / 10\n}\n\n/**\n * Brilho de 1 (usada agora) a 0 (cinza), linear até o prazo `stale_after_days` do consolidador.\n * Candidata a esquecimento → 0; inativa → 0; fixada nunca fica abaixo do mínimo visível.\n */\nexport function particleBrightness(input: { status: MemoryStatus; stale: boolean; lastUse: string }, staleAfterDays: number, now: number = Date.now()): number {\n if (input.status === \"archived\") return 0\n const days = Math.max(0, (now - time(input.lastUse)) / DAY_MS)\n const limit = staleAfterDays > 0 ? staleAfterDays : DEFAULT_STALE_AFTER_DAYS\n let value = Number.isNaN(days) ? 0 : clamp01(1 - days / limit)\n if (input.stale) value = 0\n if (input.status === \"permanent\") value = Math.max(value, PINNED_MIN_BRIGHTNESS)\n return Math.round(value * 1000) / 1000\n}\n\n/** Cor final da partícula: a cor do canal apagada em direção ao cinza conforme perde brilho. */\nexport function particleColor(base: string, brightness: number): string {\n const pct = Math.round(clamp01(brightness) * 100)\n return `color-mix(in oklch, ${base} ${pct}%, var(--color-muted-foreground))`\n}\n\n/** Paleta dos canais: `--chart-2..6` (o `--chart-1` é o roxo primário, reservado ao canal em destaque). */\nconst CHANNEL_TOKENS = 5\n/** Cor do canal com mais memórias do universo (e de todo universo de um canal só). */\nexport const PRIMARY_CHANNEL_COLOR = \"var(--color-primary)\"\nconst TONES = [\"\", \"var(--color-foreground)\", \"var(--color-background)\"] as const\n\nexport function stableHash(text: string): number {\n let hash = 2166136261\n for (let index = 0; index < text.length; index += 1) {\n hash ^= text.charCodeAt(index)\n hash = Math.imul(hash, 16777619)\n }\n return hash >>> 0\n}\n\n/**\n * Token `--chart-N` do tema. O shadcn/ui traz `--chart-1..5`: o `--chart-6` cai numa variação do\n * `--chart-3` quando o app não o define (sem cor fixa).\n */\nexport const chartToken = (index: number): string => (index <= 5 ? `var(--chart-${index})` : `var(--chart-${index}, color-mix(in oklch, var(--chart-3) 55%, var(--color-foreground)))`)\n\nconst toneOf = (base: number, tone: number): string => {\n const token = chartToken(base + 2)\n if (tone === 0) return token\n return `color-mix(in oklch, ${token} 70%, ${TONES[tone % TONES.length] || TONES[1]})`\n}\n\n/**\n * Cor de cada canal: a cor base (`--chart-2..6`) vem só do slug (o mesmo canal tem sempre a mesma\n * cor). Quando mais de um canal cai na mesma base, os seguintes (em ordem de slug) ganham variações de\n * tom da mesma cor.\n */\nexport function channelColors(slugs: readonly string[]): Map<string, string> {\n const byBase = new Map<number, string[]>()\n for (const slug of [...new Set(slugs)].sort()) {\n const base = stableHash(slug) % CHANNEL_TOKENS\n byBase.set(base, [...(byBase.get(base) ?? []), slug])\n }\n const colors = new Map<string, string>()\n for (const [base, group] of byBase) group.forEach((slug, index) => colors.set(slug, toneOf(base, index)))\n return colors\n}\n\n/** Só as cores dos canais de um universo, a partir do mapa de TODOS os canais (a cor não muda entre universos). */\nexport function pickChannelColors(all: ReadonlyMap<string, string>, slugs: readonly string[]): Map<string, string> {\n const picked = new Map<string, string>()\n for (const slug of slugs) {\n const color = all.get(slug) ?? channelColors([slug]).get(slug)\n if (color) picked.set(slug, color)\n }\n return picked\n}\n\n/**\n * Cores de um universo: cada canal com a sua cor estável (do mapa `base` ou do slug) e o canal com mais\n * memórias (todas, inclusive inativas; empate pelo slug, a ordem da legenda \"Por canal\") com o roxo\n * primário. Canais do mapa sem memórias entram com a cor estável. Sem memórias, nenhum fica roxo.\n */\nexport function universeChannelColors(base: ReadonlyMap<string, string> | undefined, memories: readonly Pick<NetworkMemory, \"channel\">[]): Map<string, string> {\n const counts = new Map<string, number>()\n for (const memory of memories) counts.set(memory.channel, (counts.get(memory.channel) ?? 0) + 1)\n const slugs = [...new Set([...(base?.keys() ?? []), ...counts.keys()])]\n const colors = new Map<string, string>()\n for (const slug of slugs) {\n const color = base?.get(slug) ?? channelColors([slug]).get(slug)\n if (color) colors.set(slug, color)\n }\n const top = [...counts].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))[0]\n if (top) colors.set(top[0], PRIMARY_CHANNEL_COLOR)\n return colors\n}\n\n/**\n * Nome do canal em duas partes: o prefixo até a última `/` (linha discreta) e a ponta final (o\n * título destacado). Canais com o mesmo começo (`agentes/desenvolvedor/…`) passam a se distinguir.\n */\nexport function splitChannelSlug(slug: string): { prefix: string; leaf: string } {\n const trimmed = slug.replace(/\\/+$/, \"\")\n const cut = trimmed.lastIndexOf(\"/\")\n if (cut <= 0) return { prefix: \"\", leaf: trimmed || slug }\n return { prefix: trimmed.slice(0, cut + 1), leaf: trimmed.slice(cut + 1) }\n}\n\n/** O alvo da assinatura (exato ou prefixo `eng/projeto-*`) alcança o canal? */\nexport function subscriptionReaches(target: string, isPrefix: boolean, slug: string): boolean {\n if (!isPrefix && !target.endsWith(\"*\")) return target === slug\n const base = target.endsWith(\"*\") ? target.slice(0, -1) : target\n return base.length > 0 && slug.startsWith(base)\n}\n\nexport interface SubscriptionInput {\n id: string\n agent: string\n target: string\n isPrefix: boolean\n mode: SubscriptionMode\n /** Canais ativos que o alvo alcança (`reaches` do Engramind). */\n reaches: readonly string[]\n}\n\n/**\n * Um link por canal casado em cada assinatura: os ativos pelo `reaches` do Engramind e, com\n * \"Mostrar arquivados\", os arquivados casados localmente. Só canais visíveis; prefixo sem canal não gera link.\n */\nexport function subscriptionLinks(subscriptions: readonly SubscriptionInput[], channels: readonly NetworkChannel[], includeArchived: boolean): NetworkLink[] {\n const visible = new Map(channels.filter((channel) => includeArchived || !channel.archived).map((channel) => [channel.slug, channel]))\n const links: NetworkLink[] = []\n const seen = new Set<string>()\n for (const subscription of subscriptions) {\n const reached = new Set(subscription.reaches)\n if (includeArchived) for (const channel of visible.values()) if (channel.archived && subscriptionReaches(subscription.target, subscription.isPrefix, channel.slug)) reached.add(channel.slug)\n for (const slug of reached) {\n if (!visible.has(slug)) continue\n const id = `${subscription.agent}→${slug}`\n if (seen.has(id)) continue\n seen.add(id)\n links.push({ id, agent: subscription.agent, channel: slug, mode: subscription.mode })\n }\n }\n return links\n}\n\nexport interface Point {\n x: number\n y: number\n}\n\nexport interface Rect {\n x: number\n y: number\n width: number\n height: number\n}\n\n/** Zoom mínimo do enquadramento inicial no celular: os nomes continuam legíveis. */\nexport const MOBILE_FIT_MIN_ZOOM = 0.5\n\n/**\n * Enquadramento com zoom mínimo (celular): se caber o retângulo inteiro com zoom ≥ `minZoom`, devolve\n * `null` (enquadra normalmente); senão, centraliza no meio do retângulo com `minZoom` (o resto fica a\n * um arrastar). Sem tamanho medido do quadro, `null`.\n */\nexport function minZoomCenter(bounds: Rect, size: { width: number; height: number }, minZoom: number): { x: number; y: number; zoom: number } | null {\n if (size.width <= 0 || size.height <= 0 || bounds.width <= 0 || bounds.height <= 0) return null\n const fit = Math.min(size.width / bounds.width, size.height / bounds.height)\n if (fit >= minZoom) return null\n return { x: bounds.x + bounds.width / 2, y: bounds.y + bounds.height / 2, zoom: minZoom }\n}\n\n/**\n * Tamanho visível do card da memória: o natural (largura fixa, altura do conteúdo) limitado ao quadro\n * menos `margin` de cada lado. Sem quadro medido, o natural.\n */\nexport function memoryCardSize(natural: { width: number; height: number }, canvas: { width: number; height: number }, margin = 8): { width: number; height: number } {\n const width = canvas.width > 0 ? Math.min(natural.width, Math.max(canvas.width - margin * 2, 160)) : natural.width\n const height = canvas.height > 0 ? Math.min(natural.height, Math.max(canvas.height - margin * 2, 120)) : natural.height\n return { width, height }\n}\n\n/**\n * Posição (canto superior esquerdo, em px da tela) do card que substitui a partícula: centralizado\n * sobre ela e empurrado para dentro do canvas, com `margin` de folga em todas as bordas.\n */\nexport function clampCardRect(anchor: Point, card: { width: number; height: number }, canvas: { width: number; height: number }, margin = 8): Point {\n const axis = (center: number, size: number, limit: number) => {\n const max = limit - size - margin\n if (max < margin) return margin\n return Math.min(Math.max(center - size / 2, margin), max)\n }\n return { x: axis(anchor.x, card.width, canvas.width), y: axis(anchor.y, card.height, canvas.height) }\n}\n\nexport const UNIVERSE_FIRST_RADIUS = 150\nexport const UNIVERSE_RING_GAP = 58\nexport const UNIVERSE_SLOT = 46\n\n/** Criação em ms; data inválida conta como a mais antiga. */\nconst createdTime = (memory: Pick<NetworkMemory, \"createdAt\">): number => {\n const value = time(memory.createdAt)\n return Number.isNaN(value) ? Number.NEGATIVE_INFINITY : value\n}\n\n/**\n * Universo: órbitas concêntricas em volta do centro (0,0) pela idade (criação): as mais novas nas\n * órbitas internas, as mais antigas (e as de data inválida) nas externas.\n */\nexport function layoutUniverse(memories: readonly Pick<NetworkMemory, \"id\" | \"createdAt\">[]): Map<string, Point> {\n const sorted = [...memories].sort((a, b) => {\n const diff = createdTime(b) - createdTime(a)\n return (Number.isNaN(diff) ? 0 : diff) || a.id.localeCompare(b.id)\n })\n const positions = new Map<string, Point>()\n let cursor = 0\n universeRingCounts(sorted.length).forEach((count, ring) => {\n const radius = UNIVERSE_FIRST_RADIUS + ring * UNIVERSE_RING_GAP\n const members = sorted.slice(cursor, cursor + count)\n const offset = ring * 0.61\n members.forEach((memory, index) => {\n const angle = offset + (index / members.length) * 2 * Math.PI\n positions.set(memory.id, { x: Math.round(Math.cos(angle) * radius * 10) / 10, y: Math.round(Math.sin(angle) * radius * 10) / 10 })\n })\n cursor += count\n })\n return positions\n}\n\n/** Vagas de um anel (≈ `UNIVERSE_SLOT` px entre vizinhas). */\nexport const universeRingCapacity = (ring: number) => Math.max(6, Math.floor((2 * Math.PI * (UNIVERSE_FIRST_RADIUS + ring * UNIVERSE_RING_GAP)) / UNIVERSE_SLOT))\n\n/**\n * Quantas memórias em cada anel: o número de anéis é o mínimo que comporta todas, e elas são\n * distribuídas proporcionalmente às vagas de cada anel (maior resto), para o último anel não ficar\n * quase vazio (50 memórias: ~12/17/21 em vez de 20/28/2).\n */\nexport function universeRingCounts(total: number): number[] {\n if (total <= 0) return []\n const capacities: number[] = []\n let room = 0\n while (room < total) {\n const capacity = universeRingCapacity(capacities.length)\n capacities.push(capacity)\n room += capacity\n }\n const exact = capacities.map((capacity) => (total * capacity) / room)\n const counts = exact.map((value, ring) => Math.min(Math.floor(value), capacities[ring] ?? 0))\n let missing = total - counts.reduce((sum, count) => sum + count, 0)\n const byRemainder = exact.map((value, ring) => ({ ring, rest: value - Math.floor(value) })).sort((a, b) => b.rest - a.rest || a.ring - b.ring)\n for (let index = 0; missing > 0; index = (index + 1) % byRemainder.length) {\n const ring = byRemainder[index]?.ring ?? 0\n if ((counts[ring] ?? 0) < (capacities[ring] ?? 0)) {\n counts[ring] = (counts[ring] ?? 0) + 1\n missing -= 1\n }\n }\n return counts\n}\n\n/** Deslocamento do hover: as demais partículas se afastam levemente da focada. */\nexport function repelOffset(from: Point, focus: Point, strength = 18, radius = 220): Point {\n const dx = from.x - focus.x\n const dy = from.y - focus.y\n const distance = Math.hypot(dx, dy)\n if (distance === 0 || distance > radius) return { x: 0, y: 0 }\n const factor = (strength * (1 - distance / radius)) / distance\n return { x: dx * factor, y: dy * factor }\n}\n\n/** Link partícula ↔ centro destacado: só no universo do agente, quando ele escreveu a memória. */\nexport function isAuthoredByCenter(memory: Pick<NetworkMemory, \"authorAgent\">, center: { kind: \"channel\" | \"agent\"; id: string }): boolean {\n return center.kind === \"agent\" && Boolean(memory.authorAgent) && memory.authorAgent === center.id\n}\n\n/** Janela em que uma memória nova conta como \"acabou de ser criada\" (partícula de criação). */\nexport const AGENT_WRITE_WINDOW_MS = 2 * 60 * 1000\n\nexport interface AgentWrite {\n id: string\n agent: string\n channel: string\n}\n\n/**\n * Criações por agente entre os ids que acabaram de aparecer: só memórias com agente autor\n * (`authorAgent`) criadas há pouco. Ids que só apareceram agora por outro motivo (Mostrar arquivados,\n * filtro de app, memória movida) não contam.\n */\nexport function agentWritesOf(fresh: readonly string[], memories: readonly Pick<NetworkMemory, \"id\" | \"authorAgent\" | \"channel\" | \"createdAt\">[], now: number = Date.now()): AgentWrite[] {\n if (!fresh.length) return []\n const byId = new Map(memories.map((memory) => [memory.id, memory]))\n const writes: AgentWrite[] = []\n for (const id of fresh) {\n const memory = byId.get(id)\n if (!memory?.authorAgent) continue\n const age = now - time(memory.createdAt)\n if (Number.isNaN(age) || age > AGENT_WRITE_WINDOW_MS || age < -AGENT_WRITE_WINDOW_MS) continue\n writes.push({ id, agent: memory.authorAgent, channel: memory.channel })\n }\n return writes\n}\n\n/** Pesos da fusão da busca do Engramind (`search.vector_weight`, `search.text_weight`, `search.rrf_k`). */\nexport interface SearchFusion {\n vectorWeight: number\n textWeight: number\n k: number\n}\n\nexport const DEFAULT_SEARCH_FUSION: SearchFusion = { vectorWeight: 1, textWeight: 1, k: 60 }\n\n/** Acertos de um ramo sozinho que ainda destacam: as primeiras posições (as mais próximas pelo sentido). */\nexport const SEARCH_SINGLE_BRANCH_TOP = 3\n\n/**\n * Ids que a busca destaca. O ramo vetorial do Engramind não tem limiar: devolve as memórias mais\n * próximas até o `limit`, mesmo sem relação com o termo, e com poucas memórias elas são todas. No modo\n * `hybrid`, destacam as que os dois ramos encontraram (sentido e texto) e as que um ramo sozinho pôs\n * nas `SEARCH_SINGLE_BRANCH_TOP` primeiras posições: score ≥ `max(peso) / (k + top)`. Como o acerto dos\n * dois ramos vale no mínimo `(pesoV + pesoT) / (k + limit)`, ele sempre passa. No modo `text`, todas.\n */\nexport function relevantSearchIds(results: readonly { score: number; memory: { id: string } }[], mode: \"hybrid\" | \"text\", fusion: SearchFusion = DEFAULT_SEARCH_FUSION): string[] {\n if (mode === \"text\") return results.map((hit) => hit.memory.id)\n const threshold = Math.max(fusion.vectorWeight, fusion.textWeight) / (fusion.k + SEARCH_SINGLE_BRANCH_TOP)\n return results.filter((hit) => hit.score >= threshold - 1e-6).map((hit) => hit.memory.id)\n}\n\nexport interface UniverseStats {\n active: number\n inactive: number\n pinned: number\n uses: number\n lastUse: string | null\n forgotten: number\n byChannel: { slug: string; count: number }[]\n}\n\n/** Números do card de estatísticas de um universo (canal ou agente). */\nexport function universeStats(memories: readonly NetworkMemory[], brightness: ReadonlyMap<string, number>): UniverseStats {\n const byChannel = new Map<string, number>()\n let lastUse: string | null = null\n for (const memory of memories) {\n byChannel.set(memory.channel, (byChannel.get(memory.channel) ?? 0) + 1)\n const used = lastRealUseOf(memory)\n if (used && (!lastUse || time(used) > time(lastUse))) lastUse = used\n }\n return {\n active: memories.filter((memory) => memory.status !== \"archived\").length,\n inactive: memories.filter((memory) => memory.status === \"archived\").length,\n pinned: memories.filter((memory) => memory.status === \"permanent\").length,\n uses: memories.reduce((sum, memory) => sum + memoryUses(memory), 0),\n lastUse,\n forgotten: memories.filter((memory) => memory.status !== \"archived\" && (brightness.get(memory.id) ?? 1) === 0).length,\n byChannel: [...byChannel].map(([slug, count]) => ({ slug, count })).sort((a, b) => b.count - a.count || a.slug.localeCompare(b.slug)),\n }\n}\n\n/** Alcance de cada agente: memórias somadas dos canais ligados a ele. */\nexport function agentReach(links: readonly NetworkLink[], countByChannel: ReadonlyMap<string, number>): Map<string, number> {\n const reach = new Map<string, number>()\n for (const link of links) reach.set(link.agent, (reach.get(link.agent) ?? 0) + (countByChannel.get(link.channel) ?? 0))\n return reach\n}\n\nfunction clamp01(value: number): number {\n if (Number.isNaN(value)) return 0\n return Math.min(1, Math.max(0, value))\n}\n","import { z } from \"zod\"\nimport { MEMORY_STATUSES } from \"../constants\"\nimport { DEFAULT_OVERVIEW_LAYOUT, OVERVIEW_LAYOUT_MODES } from \"./overview-layout\"\nimport type { NetworkMemory } from \"./types\"\n\n/**\n * Busca e filtros da rede do Engramind (OPE-113, puro): no padrão de `/tarefas`, ficam no navegador\n * (`usePersistentState`, chave versionada) e **destacam sem remover** (as que não casam ficam apagadas).\n */\n\nexport const NETWORK_FILTERS_STORAGE_KEY = \"opex.engramind.network-filters.v1\"\n\nconst list = z.array(z.string().max(200)).max(200).catch([])\nconst day = z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/).or(z.literal(\"\")).catch(\"\")\n\nexport const networkFiltersSchema = z.object({\n search: z.string().max(500).catch(\"\"),\n channels: list,\n statuses: list,\n categories: list,\n authors: list,\n /** Período (`yyyy-mm-dd`) pela última alteração da memória. */\n from: day,\n to: day,\n includeArchived: z.boolean().catch(false),\n /** Distribuição da visão inicial (escolhida na legenda; o Limpar não mexe). */\n overviewLayout: z.enum(OVERVIEW_LAYOUT_MODES).catch(DEFAULT_OVERVIEW_LAYOUT),\n})\n\nexport type NetworkFilters = z.infer<typeof networkFiltersSchema>\n\nexport const DEFAULT_NETWORK_FILTERS: NetworkFilters = { search: \"\", channels: [], statuses: [], categories: [], authors: [], from: \"\", to: \"\", includeArchived: false, overviewLayout: DEFAULT_OVERVIEW_LAYOUT }\n\n/** Campos que o \"Limpar\" zera (a distribuição escolhida no card \"O que é o Engramind\" fica). */\nexport const NETWORK_FILTER_KEYS = [\"search\", \"channels\", \"statuses\", \"categories\", \"authors\", \"from\", \"to\", \"includeArchived\"] as const satisfies readonly (keyof NetworkFilters)[]\n\nexport const clearNetworkFilters = (filters: NetworkFilters): NetworkFilters => ({ ...DEFAULT_NETWORK_FILTERS, overviewLayout: filters.overviewLayout })\n\n/** Filtros que destacam memórias (sem a busca, que vem do servidor, e sem os arquivados). */\nexport const hasMemoryFilters = (filters: NetworkFilters): boolean => Boolean(filters.channels.length || filters.statuses.length || filters.categories.length || filters.authors.length || filters.from || filters.to)\n\nexport const hasActiveFilters = (filters: NetworkFilters, searchIds: ReadonlySet<string> | null): boolean => Boolean(searchIds) || hasMemoryFilters(filters)\n\nconst time = (iso: string) => new Date(iso).getTime()\n\n/** A memória casa com a busca e os filtros? (Destaque: as demais ficam apagadas, nada sai da rede.) */\nexport function matchesFilters(memory: NetworkMemory, filters: NetworkFilters, searchIds: ReadonlySet<string> | null): boolean {\n if (searchIds && !searchIds.has(memory.id)) return false\n if (filters.channels.length && !filters.channels.includes(memory.channel)) return false\n if (filters.statuses.length && !filters.statuses.includes(memory.status)) return false\n if (filters.categories.length && !filters.categories.includes(memory.category)) return false\n if (filters.authors.length && !filters.authors.includes(memory.author ?? \"\")) return false\n const updated = time(memory.updatedAt)\n if (filters.from && !(updated >= time(`${filters.from}T00:00:00`))) return false\n if (filters.to && !(updated <= time(`${filters.to}T23:59:59.999`))) return false\n return true\n}\n\nconst STATUS_LABEL: Record<string, string> = { active: \"Ativa\", permanent: \"Fixada\", archived: \"Inativa\" }\nexport const memoryStatusLabel = (status: string) => STATUS_LABEL[status] ?? status\nexport const MEMORY_STATUS_OPTIONS = MEMORY_STATUSES.map((value) => ({ value, label: memoryStatusLabel(value) }))\n\nexport interface NetworkFilterChip {\n key: string\n label: string\n remove: Partial<NetworkFilters>\n}\n\nconst formatDay = (value: string) => value.split(\"-\").reverse().join(\"/\")\n\n/**\n * Chips dos filtros ativos (resumo do cartão recolhido e contagem da gaveta no celular). `channelLabel`\n * mostra o canal legível (`channelDisplayName`: sigla da central no lugar do id).\n */\nexport function activeNetworkFilterChips(filters: NetworkFilters, channelLabel: (slug: string) => string = (slug) => slug): NetworkFilterChip[] {\n const chips: NetworkFilterChip[] = []\n if (filters.search.trim()) chips.push({ key: \"search\", label: `Busca: ${filters.search.trim()}`, remove: { search: \"\" } })\n const many = (key: \"channels\" | \"statuses\" | \"categories\" | \"authors\", title: string, label: (value: string) => string = (value) => value) => {\n for (const value of filters[key]) chips.push({ key: `${key}:${value}`, label: `${title}: ${label(value)}`, remove: { [key]: filters[key].filter((item) => item !== value) } })\n }\n many(\"channels\", \"Canal\", channelLabel)\n many(\"statuses\", \"Status\", memoryStatusLabel)\n many(\"categories\", \"Categoria\")\n many(\"authors\", \"Autor\")\n if (filters.from || filters.to) {\n const label = filters.from && filters.to ? `${formatDay(filters.from)} a ${formatDay(filters.to)}` : filters.from ? `desde ${formatDay(filters.from)}` : `até ${formatDay(filters.to)}`\n chips.push({ key: \"period\", label: `Período: ${label}`, remove: { from: \"\", to: \"\" } })\n }\n if (filters.includeArchived) chips.push({ key: \"archived\", label: \"Mostrando arquivados\", remove: { includeArchived: false } })\n return chips\n}\n","/** Prefixo das chaves do TanStack Query da lib (`[\"engramind\", <área>, ...]`). */\nexport const ENGRAMIND_QUERY_KEY = \"engramind\"\n\nexport const ENGRAMIND_SCOPES = [\"read\", \"write\", \"delete\"] as const\nexport type EngramindScope = (typeof ENGRAMIND_SCOPES)[number]\nexport const SCOPE_COMBINATIONS = [\"read\", \"read+write\", \"read+delete\", \"read+write+delete\"] as const\nexport type ScopeCombination = (typeof SCOPE_COMBINATIONS)[number]\nexport const scopesOfCombination = (combination: ScopeCombination): EngramindScope[] => combination.split(\"+\") as EngramindScope[]\nexport function combinationOf(scopes: readonly string[]): ScopeCombination | null {\n const key = ENGRAMIND_SCOPES.filter((scope) => scopes.includes(scope)).join(\"+\")\n return (SCOPE_COMBINATIONS as readonly string[]).includes(key) && key.split(\"+\").length === scopes.length ? (key as ScopeCombination) : null\n}\n\nexport const TOKEN_KINDS = [\"admin\", \"app\", \"agent\"] as const\nexport const SUBSCRIPTION_MODES = [\"inject\", \"search\", \"manage\"] as const\nexport const MEMORY_STATUSES = [\"active\", \"permanent\", \"archived\"] as const\n","import type { Point, Rect } from \"./network-math\"\n\n/**\n * Layout da visão inicial da rede do Engramind (OPE-113, puro). Duas distribuições, escolhidas na\n * legenda do diagrama:\n * - `by-agent` (\"Canais junto dos agentes\", padrão): o canal de um agente só orbita esse agente; o\n * canal compartilhado fica entre os agentes que o usam (no centroide deles);\n * - `agents-center` (\"Agentes no centro\"): agentes num círculo no meio e canais em anéis em volta, cada\n * canal no ângulo médio dos agentes que o usam.\n * Os cards (os mesmos de sempre) crescem com as memórias (`overviewScale`) e nunca se sobrepõem: um\n * afastamento determinístico separa o que encostar, e o círculo cresce enquanto sobrar sobreposição.\n * Os links são curvas suaves de centro a centro: minimizam cruzamentos, sem garantia absoluta.\n */\n\nexport type OverviewLayoutMode = \"by-agent\" | \"agents-center\"\nexport const OVERVIEW_LAYOUT_MODES = [\"by-agent\", \"agents-center\"] as const satisfies readonly OverviewLayoutMode[]\nexport const DEFAULT_OVERVIEW_LAYOUT: OverviewLayoutMode = \"by-agent\"\nexport const OVERVIEW_LAYOUT_LABEL: Record<OverviewLayoutMode, string> = { \"by-agent\": \"Órbita\", \"agents-center\": \"Radial\" }\n\n/** Caixa dos cards em escala 1 (pílula do agente até 180 px; card do canal até 288 px, `max-w-72`). */\nexport const OVERVIEW_AGENT_BOX = { width: 180, height: 48 }\nexport const OVERVIEW_CHANNEL_BOX = { width: 288, height: 64 }\n/** Faixa de escala dos cards pela quantidade de memórias (log). */\nexport const OVERVIEW_SCALE_MIN = 0.85\nexport const OVERVIEW_SCALE_MAX = 1.6\n/** Folga mínima entre dois cards. */\nexport const OVERVIEW_PADDING = 16\n/** Folga do enquadramento inicial em cada lado (fração do tamanho). */\nexport const OVERVIEW_FIT_MARGIN = 0.1\n/** Curvatura dos links (fração do comprimento, para o lado). */\nexport const OVERVIEW_LINK_BEND = 0.12\n\nconst RELAX_STEPS = 160\n/** Passadas finais só de afastamento (até ninguém encostar). */\nconst SEPARATE_STEPS = 600\n/**\n * Caso residual: se ainda sobrar sobreposição, o círculo de agentes cresce pouco e poucas vezes. O\n * conflito comum (canais compartilhados no mesmo centroide) não depende do círculo: quem resolve é o\n * afastamento dos cards móveis, nunca o crescimento sem teto (a rede explodia a ~27.000 px).\n */\nconst MAX_ATTEMPTS = 3\nconst GROWTH = 1.1\n/** Radial um pouco mais compacta (OPE-113, rodada 3). */\nconst RADIAL_RING_GAP = 0.8\nconst RADIAL_SLOT = 1.7\nconst RADIAL_INNER = 0.85\n\nexport interface OverviewLayoutInput {\n agents: readonly { id: string; app: string }[]\n channels: readonly { slug: string }[]\n /** Assinaturas visíveis (agente → canal). */\n links: readonly { agent: string; channel: string }[]\n /** Memórias por agente (alcance) e por canal: o tamanho dos cards. */\n agentCounts?: ReadonlyMap<string, number>\n channelCounts?: ReadonlyMap<string, number>\n mode?: OverviewLayoutMode\n}\n\nexport interface OverviewLayout {\n agents: Map<string, Point>\n channels: Map<string, Point>\n /** Escala de cada card (`agent:<id>` / `channel:<slug>`). */\n scales: Map<string, number>\n /** Caixa de cada card já escalada. */\n boxes: Map<string, { width: number; height: number }>\n mode: OverviewLayoutMode\n}\n\nconst round = (value: number) => Math.round(value * 10) / 10 || 0\n\n/** Escala do card pela quantidade de memórias, em log entre `OVERVIEW_SCALE_MIN` e `OVERVIEW_SCALE_MAX`. */\nexport function overviewScale(count: number, max: number): number {\n if (max <= 0 || count <= 0) return OVERVIEW_SCALE_MIN\n const ratio = Math.min(1, Math.log1p(count) / Math.log1p(max))\n return Math.round((OVERVIEW_SCALE_MIN + (OVERVIEW_SCALE_MAX - OVERVIEW_SCALE_MIN) * ratio) * 1000) / 1000\n}\n\ninterface Body {\n key: string\n x: number\n y: number\n width: number\n height: number\n /** Agentes e canais exclusivos ficam parados; compartilhados e soltos se afastam. */\n fixed: boolean\n /** Ponto a que o card volta aos poucos (centroide ou lugar no anel). */\n anchor: Point | null\n}\n\n/** Penetração entre duas caixas (com a folga); `null` sem sobreposição. */\nfunction overlap(a: Body, b: Body): { x: number; y: number } | null {\n const ox = (a.width + b.width) / 2 + OVERVIEW_PADDING - Math.abs(a.x - b.x)\n const oy = (a.height + b.height) / 2 + OVERVIEW_PADDING - Math.abs(a.y - b.y)\n // Meio pixel de tolerância: encostar por erro de arredondamento não conta (senão o afastamento empurra 1e-13 para sempre).\n return ox > 0.5 && oy > 0.5 ? { x: ox, y: oy } : null\n}\n\n/** Uma passada de afastamento: separa cada par sobreposto pela menor penetração. Devolve se mexeu. */\nfunction separate(bodies: Body[]): boolean {\n let moved = false\n for (let i = 0; i < bodies.length; i += 1)\n for (let j = i + 1; j < bodies.length; j += 1) {\n const a = bodies[i]!\n const b = bodies[j]!\n if (a.fixed && b.fixed) continue\n const hit = overlap(a, b)\n if (!hit) continue\n moved = true\n const share = a.fixed || b.fixed ? 1 : 0.5\n // Sem direção (mesmo ponto): sai para um lado pelo índice, para ser determinístico.\n const dx = a.x - b.x || (j % 2 ? 1 : -1)\n const dy = a.y - b.y || (i % 2 ? 1 : -1)\n const push = hit.x < hit.y ? { x: Math.sign(dx) * hit.x, y: 0 } : { x: 0, y: Math.sign(dy) * hit.y }\n if (!a.fixed) {\n a.x += push.x * share\n a.y += push.y * share\n }\n if (!b.fixed) {\n b.x -= push.x * share\n b.y -= push.y * share\n }\n }\n return moved\n}\n\n/**\n * Afasta os cards móveis que se sobrepõem, com uma volta suave ao ponto de origem (centroide ou lugar no\n * anel); no fim, só afastamento até ninguém mais encostar.\n */\nfunction relax(bodies: Body[]): void {\n for (let step = 0; step < RELAX_STEPS; step += 1) {\n for (const body of bodies)\n if (!body.fixed && body.anchor) {\n body.x += (body.anchor.x - body.x) * 0.04\n body.y += (body.anchor.y - body.y) * 0.04\n }\n separate(bodies)\n }\n for (let step = 0; step < SEPARATE_STEPS && separate(bodies); step += 1) {\n // só afastamento\n }\n}\n\nconst hasOverlap = (bodies: readonly Body[]) => bodies.some((a, i) => bodies.some((b, j) => j > i && overlap(a, b) !== null))\n\n/**\n * Pontos num círculo com espaço proporcional a cada item (`sizes` = \"raio\" de cada um, já com folga):\n * o raio é o menor em que cada par vizinho fica a pelo menos a soma dos dois.\n */\nfunction circle(sizes: readonly number[], minRadius = 0, startAngle = -Math.PI / 2): { radius: number; angles: number[] } {\n const count = sizes.length\n if (count === 0) return { radius: 0, angles: [] }\n if (count === 1) return { radius: 0, angles: [startAngle] }\n const gaps = sizes.map((size, index) => size + sizes[(index + 1) % count]!)\n const total = gaps.reduce((sum, value) => sum + value, 0)\n const steps = gaps.map((gap) => (gap / total) * 2 * Math.PI)\n let radius = Math.max(minRadius, total / (2 * Math.PI))\n for (let guard = 0; guard < 60; guard += 1) {\n const ok = steps.every((step, index) => 2 * radius * Math.sin(Math.min(step, Math.PI) / 2) >= gaps[index]! - 0.5)\n if (ok) break\n radius *= 1.08\n }\n const angles: number[] = []\n let angle = startAngle\n for (const step of steps) {\n angles.push(angle)\n angle += step\n }\n return { radius, angles }\n}\n\n/** \"Raio\" de um card para os círculos: metade da diagonal, com metade da folga. */\nconst reach = (box: { width: number; height: number }) => Math.hypot(box.width, box.height) / 2 + OVERVIEW_PADDING / 2\n\n/** Média circular dos ângulos (`null` quando se anulam ou não há nenhum). */\nfunction meanAngle(angles: readonly number[]): number | null {\n if (!angles.length) return null\n const x = angles.reduce((sum, angle) => sum + Math.cos(angle), 0)\n const y = angles.reduce((sum, angle) => sum + Math.sin(angle), 0)\n return Math.hypot(x, y) < 1e-6 ? null : Math.atan2(y, x)\n}\n\n/** Canais em anéis em volta de `inner`, na ordem dada; mais anéis quando não cabem num só. */\nfunction rings(boxes: readonly { width: number; height: number }[], inner: number, preferred: readonly (number | null)[]): Point[] {\n if (!boxes.length) return []\n const widest = Math.max(...boxes.map((box) => box.width))\n const ringGap = RADIAL_RING_GAP * widest + OVERVIEW_PADDING\n const slot = (index: number) => reach(boxes[index]!) * RADIAL_SLOT\n const points: Point[] = new Array(boxes.length)\n let start = 0\n let radius = inner + reach({ width: widest, height: Math.max(...boxes.map((box) => box.height)) })\n while (start < boxes.length) {\n let used = 0\n let end = start\n while (end < boxes.length && (end === start || used + slot(end) <= 2 * Math.PI * radius)) {\n used += slot(end)\n end += 1\n }\n const count = end - start\n const step = (2 * Math.PI) / count\n // Gira o anel para os ângulos preferidos (média do quanto cada um quer se deslocar).\n const shifts = Array.from({ length: count }, (_, index) => preferred[start + index]).flatMap((angle, index) => (angle === null || angle === undefined ? [] : [angle - (index * step - Math.PI / 2)]))\n const offset = meanAngle(shifts) ?? 0\n for (let index = 0; index < count; index += 1) {\n const angle = -Math.PI / 2 + index * step + offset\n points[start + index] = { x: radius * Math.cos(angle), y: radius * Math.sin(angle) }\n }\n start = end\n radius += ringGap\n }\n return points\n}\n\n/** Distribui agentes e canais (ver o topo do arquivo). Mesmo resultado para a mesma entrada. */\nexport function layoutOverview(input: OverviewLayoutInput): OverviewLayout {\n const mode = input.mode ?? DEFAULT_OVERVIEW_LAYOUT\n const agents = [...input.agents].sort((a, b) => a.app.localeCompare(b.app) || a.id.localeCompare(b.id))\n const channels = [...input.channels].sort((a, b) => a.slug.localeCompare(b.slug))\n const agentIds = new Set(agents.map((agent) => agent.id))\n const channelIds = new Set(channels.map((channel) => channel.slug))\n const usersOf = new Map<string, string[]>()\n for (const link of input.links) {\n if (!agentIds.has(link.agent) || !channelIds.has(link.channel)) continue\n const list = usersOf.get(link.channel) ?? []\n if (!list.includes(link.agent)) list.push(link.agent)\n usersOf.set(link.channel, list)\n }\n const maxAgent = Math.max(0, ...agents.map((agent) => input.agentCounts?.get(agent.id) ?? 0))\n const maxChannel = Math.max(0, ...channels.map((channel) => input.channelCounts?.get(channel.slug) ?? 0))\n const scales = new Map<string, number>()\n const boxes = new Map<string, { width: number; height: number }>()\n const boxOf = (key: string, base: { width: number; height: number }, scale: number) => {\n scales.set(key, scale)\n const box = { width: round(base.width * scale), height: round(base.height * scale) }\n boxes.set(key, box)\n return box\n }\n for (const agent of agents) boxOf(`agent:${agent.id}`, OVERVIEW_AGENT_BOX, overviewScale(input.agentCounts?.get(agent.id) ?? 0, maxAgent))\n for (const channel of channels) boxOf(`channel:${channel.slug}`, OVERVIEW_CHANNEL_BOX, overviewScale(input.channelCounts?.get(channel.slug) ?? 0, maxChannel))\n\n const place = mode === \"agents-center\" ? placeAgentsCenter : placeByAgent\n let spread = 1\n let bodies: Body[] = []\n for (let attempt = 0; attempt <= MAX_ATTEMPTS; attempt += 1) {\n bodies = place({ agents, channels, usersOf, boxes, spread })\n relax(bodies)\n if (!hasOverlap(bodies)) break\n spread *= GROWTH\n }\n const agentPoints = new Map<string, Point>()\n const channelPoints = new Map<string, Point>()\n for (const body of bodies) {\n const point = { x: round(body.x), y: round(body.y) }\n if (body.key.startsWith(\"agent:\")) agentPoints.set(body.key.slice(\"agent:\".length), point)\n else channelPoints.set(body.key.slice(\"channel:\".length), point)\n }\n return { agents: agentPoints, channels: channelPoints, scales, boxes, mode }\n}\n\ninterface PlaceInput {\n agents: readonly { id: string; app: string }[]\n channels: readonly { slug: string }[]\n usersOf: ReadonlyMap<string, readonly string[]>\n boxes: ReadonlyMap<string, { width: number; height: number }>\n /** Fator do raio dos círculos (cresce a cada tentativa com sobreposição). */\n spread: number\n}\n\nconst body = (key: string, point: Point, box: { width: number; height: number }, fixed: boolean, anchor: Point | null = null): Body => ({ key, x: point.x, y: point.y, width: box.width, height: box.height, fixed, anchor })\n\n/** \"Agentes no centro\": agentes num círculo e canais em anéis em volta, no ângulo médio dos seus agentes. */\nfunction placeAgentsCenter({ agents, channels, usersOf, boxes, spread }: PlaceInput): Body[] {\n const agentBoxes = agents.map((agent) => boxes.get(`agent:${agent.id}`)!)\n const { radius, angles } = circle(agentBoxes.map(reach))\n const agentRadius = radius * spread\n const angleOf = new Map(agents.map((agent, index) => [agent.id, angles[index]!]))\n const bodies: Body[] = agents.map((agent, index) => body(`agent:${agent.id}`, { x: agentRadius * Math.cos(angles[index]!), y: agentRadius * Math.sin(angles[index]!) }, agentBoxes[index]!, true))\n // Ângulo médio dos agentes do canal; quando eles se anulam (agentes opostos, ou três a 120°), o do\n // primeiro agente: o canal fica ao lado de um dos seus, nunca no fim do anel longe de todos.\n const preferredOf = (slug: string) => {\n if (agents.length < 2) return null\n const users = (usersOf.get(slug) ?? []).filter((agent) => angleOf.has(agent)).sort()\n if (!users.length) return null\n return meanAngle(users.map((agent) => angleOf.get(agent)!)) ?? angleOf.get(users[0]!)!\n }\n // Ordem no anel: pelo ângulo preferido; os sem agente (ou sem direção) no fim, pelo slug.\n const ordered = [...channels].sort((a, b) => {\n const pa = preferredOf(a.slug)\n const pb = preferredOf(b.slug)\n if (pa === null || pb === null) return pa === null && pb === null ? a.slug.localeCompare(b.slug) : pa === null ? 1 : -1\n const norm = (angle: number) => (angle + Math.PI / 2 + 4 * Math.PI) % (2 * Math.PI)\n return norm(pa) - norm(pb) || a.slug.localeCompare(b.slug)\n })\n const inner = (agentRadius + Math.max(0, ...agentBoxes.map(reach))) * RADIAL_INNER\n const channelBoxes = ordered.map((channel) => boxes.get(`channel:${channel.slug}`)!)\n const points = rings(channelBoxes, inner * (agents.length ? 1 : 0), ordered.map((channel) => preferredOf(channel.slug)))\n ordered.forEach((channel, index) => bodies.push(body(`channel:${channel.slug}`, points[index]!, channelBoxes[index]!, false, points[index]!)))\n return bodies\n}\n\n/** Menor distância entre os centros de duas caixas, na direção `angle`, para não se tocarem (com a folga). */\nexport function clearDistance(a: { width: number; height: number }, b: { width: number; height: number }, angle: number): number {\n const cos = Math.abs(Math.cos(angle))\n const sin = Math.abs(Math.sin(angle))\n const byX = cos > 1e-9 ? ((a.width + b.width) / 2 + OVERVIEW_PADDING) / cos : Infinity\n const byY = sin > 1e-9 ? ((a.height + b.height) / 2 + OVERVIEW_PADDING) / sin : Infinity\n return Math.min(byX, byY)\n}\n\n/**\n * \"Órbita\" (`by-agent`): cada agente com os canais só dele numa órbita **justa pela caixa** (a menor\n * distância que separa os cards naquela direção: perto em cima e embaixo, mais longe dos lados), virada\n * para fora; os agentes num círculo do tamanho real dos grupos; o canal compartilhado no centroide dos\n * seus agentes (o meio fica livre para eles); os sem agente num anel de fora. Canais são móveis com\n * âncora: o afastamento resolve quem encostar, sem aumentar o círculo.\n */\nfunction placeByAgent({ agents, channels, usersOf, boxes, spread }: PlaceInput): Body[] {\n const exclusive = new Map<string, string[]>(agents.map((agent) => [agent.id, []]))\n const shared: string[] = []\n const loose: string[] = []\n for (const channel of channels) {\n const users = usersOf.get(channel.slug) ?? []\n if (users.length === 1) exclusive.get(users[0]!)!.push(channel.slug)\n else if (users.length > 1) shared.push(channel.slug)\n else loose.push(channel.slug)\n }\n const agentBox = (id: string) => boxes.get(`agent:${id}`)!\n const channelBox = (slug: string) => boxes.get(`channel:${slug}`)!\n const single = agents.length === 1\n // Grupo de cada agente em coordenadas locais, com os canais começando virados para fora (ângulo 0).\n const groups = agents.map((agent) => {\n const mine = exclusive.get(agent.id)!\n const own = agentBox(agent.id)\n // Leque para fora (meia volta) quando há outros agentes; volta inteira com um agente só.\n const span = single ? 2 * Math.PI : Math.min(Math.PI, (mine.length * Math.PI) / 3)\n const offsets = mine.map((slug, index) => {\n const angle = mine.length === 1 ? 0 : single ? (index * span) / mine.length : -span / 2 + (index * span) / (mine.length - 1)\n const box = channelBox(slug)\n const distance = clearDistance(own, box, angle) + (index % 2 ? box.height + OVERVIEW_PADDING : 0) * (mine.length > 3 ? 1 : 0)\n return { slug, angle, distance, box }\n })\n // Pegada pela caixa real (canto mais distante do card), sem a meia diagonal de folga extra.\n const footprint = Math.max(reach(own), ...offsets.map((item) => Math.hypot(item.distance + item.box.height / 2, item.box.width / 2)))\n return { offsets, footprint }\n })\n // Miolo livre para os compartilhados (nascem no centroide, entre os agentes): um disco com a área\n // deles; o círculo de agentes nunca fica menor que ele (senão os agentes os prendem no meio).\n const sharedArea = shared.reduce((sum, slug) => sum + (channelBox(slug).width + OVERVIEW_PADDING) * (channelBox(slug).height + OVERVIEW_PADDING), 0)\n const core = shared.length ? 1.2 * Math.sqrt(sharedArea / Math.PI) + Math.max(...agents.map((agent) => reach(agentBox(agent.id)))) : 0\n const { radius, angles } = circle(groups.map((group) => group.footprint), agents.length > 1 ? core : 0)\n const agentRadius = radius * spread\n const bodies: Body[] = []\n const agentPoint = new Map<string, Point>()\n agents.forEach((agent, index) => {\n const outward = single ? -Math.PI / 2 : angles[index]!\n const point = { x: agentRadius * Math.cos(angles[index]!), y: agentRadius * Math.sin(angles[index]!) }\n agentPoint.set(agent.id, point)\n bodies.push(body(`agent:${agent.id}`, point, agentBox(agent.id), true))\n for (const item of groups[index]!.offsets) {\n const angle = outward + item.angle\n const at = { x: point.x + item.distance * Math.cos(angle), y: point.y + item.distance * Math.sin(angle) }\n bodies.push(body(`channel:${item.slug}`, at, item.box, false, at))\n }\n })\n for (const slug of shared) {\n const users = usersOf.get(slug)!\n const centroid = { x: users.reduce((sum, agent) => sum + agentPoint.get(agent)!.x, 0) / users.length, y: users.reduce((sum, agent) => sum + agentPoint.get(agent)!.y, 0) / users.length }\n bodies.push(body(`channel:${slug}`, centroid, channelBox(slug), false, centroid))\n }\n if (loose.length) {\n const extent = Math.max(0, ...bodies.map((item) => Math.hypot(item.x, item.y) + reach(item)))\n const points = rings(loose.map(channelBox), extent, loose.map(() => null))\n loose.forEach((slug, index) => bodies.push(body(`channel:${slug}`, points[index]!, channelBox(slug), false, points[index]!)))\n }\n return bodies\n}\n\n/** Ponto de controle da curva do link (para o lado, proporcional ao comprimento). */\nfunction control(source: Point, target: Point, bend: number): Point {\n const dx = target.x - source.x\n const dy = target.y - source.y\n return { x: (source.x + target.x) / 2 - dy * bend, y: (source.y + target.y) / 2 + dx * bend }\n}\n\n/** Link agente → canal: curva quadrática suave de centro a centro. */\nexport function overviewLinkPath(source: Point, target: Point, bend = OVERVIEW_LINK_BEND): string {\n const c = control(source, target, bend)\n return `M${round(source.x)},${round(source.y)} Q${round(c.x)},${round(c.y)} ${round(target.x)},${round(target.y)}`\n}\n\n/** Meio da curva do link (rótulo do modo). */\nexport function overviewLinkMidpoint(source: Point, target: Point, bend = OVERVIEW_LINK_BEND): Point {\n const c = control(source, target, bend)\n return { x: (source.x + 2 * c.x + target.x) / 4, y: (source.y + 2 * c.y + target.y) / 4 }\n}\n\n/** Enquadramento inicial: a caixa de todos os cards escalados, com `OVERVIEW_FIT_MARGIN` de folga. */\nexport function overviewInitialBounds(layout: Pick<OverviewLayout, \"agents\" | \"channels\" | \"boxes\">): Rect | null {\n const items = [...[...layout.agents].map(([id, point]) => ({ point, box: layout.boxes.get(`agent:${id}`) })), ...[...layout.channels].map(([slug, point]) => ({ point, box: layout.boxes.get(`channel:${slug}`) }))]\n if (!items.length) return null\n let minX = Infinity\n let minY = Infinity\n let maxX = -Infinity\n let maxY = -Infinity\n for (const { point, box } of items) {\n const width = box?.width ?? 0\n const height = box?.height ?? 0\n minX = Math.min(minX, point.x - width / 2)\n maxX = Math.max(maxX, point.x + width / 2)\n minY = Math.min(minY, point.y - height / 2)\n maxY = Math.max(maxY, point.y + height / 2)\n }\n const width = maxX - minX\n const height = maxY - minY\n const mx = width * OVERVIEW_FIT_MARGIN\n const my = height * OVERVIEW_FIT_MARGIN\n return { x: minX - mx, y: minY - my, width: width + 2 * mx, height: height + 2 * my }\n}\n","\"use client\"\n\nimport { useEffect, useMemo } from \"react\"\nimport { useInfiniteQuery, useMutation, useQuery, useQueryClient, type QueryKey } from \"@tanstack/react-query\"\nimport { toast } from \"../../lib/toast\"\nimport { activeDataSource, apiErrorCode, apiErrorMessage } from \"../../lib/api\"\nimport { useEngramindConfig } from \"../../lib/config\"\nimport { subscribeLive } from \"../../lib/live\"\nimport { ENGRAMIND_QUERY_KEY } from \"../constants\"\n\n/**\n * Base dos hooks do Engramind: tudo passa pela fonte de dados do `EngramindProvider` (o proxy montado\n * pelo app; o navegador nunca chama o Engramind). Chave: `[\"engramind\", <1º segmento da rota>, rota, parâmetros]`, invalidada\n * pelo prefixo no tempo real (`useEngramindRealtime`).\n */\n\nexport type Params = Record<string, string | number | boolean | undefined | null>\n\nconst clean = (params: Params = {}) => Object.fromEntries(Object.entries(params).filter(([, value]) => value !== undefined && value !== null && value !== \"\"))\nexport const engramindKey = (route: string, params?: Params): QueryKey => [ENGRAMIND_QUERY_KEY, route.split(\"/\")[0], route, clean(params)]\nexport const areaKey = (area: string): QueryKey => [ENGRAMIND_QUERY_KEY, area]\n\n/** Caminho do Opex com os segmentos codificados (`channels/eng%2Fglobal/stats`). */\nexport const route = (...segments: (string | number)[]) => segments.map((segment) => encodeURIComponent(String(segment))).join(\"/\")\n\nexport async function engramindGet<T>(path: string, params?: Params): Promise<T> {\n return activeDataSource().request<T>(\"get\", path, { params: clean(params) })\n}\n\nexport async function engramindSend<T>(method: \"post\" | \"put\" | \"patch\" | \"delete\", path: string, body?: unknown): Promise<T> {\n return activeDataSource().request<T>(method, path, method === \"delete\" ? {} : { body: body ?? {} })\n}\n\n/** Consulta simples de uma rota do Engramind. */\nexport function useEngramindQuery<T>(path: string | null, params?: Params, options: { enabled?: boolean; /** Número, `false` ou função dos dados atuais (ex.: polling só enquanto algo carrega). */ refetchInterval?: number | false | ((data: T | undefined) => number | false) } = {}) {\n const interval = options.refetchInterval\n return useQuery({\n queryKey: engramindKey(path ?? \"-\", params),\n queryFn: () => engramindGet<T>(path!, params),\n enabled: path !== null && options.enabled !== false,\n refetchInterval: typeof interval === \"function\" ? (query) => interval(query.state.data as T | undefined) : interval,\n retry: (count, error) => count < 1 && apiErrorCode(error) !== \"ENGRAMIND_NOT_CONFIGURED\",\n })\n}\n\n/** Lista paginada por cursor (`next_cursor`). `field` é o nome da lista na resposta do Engramind. */\n/** Lista vazia estável (sem dados ainda). */\nconst EMPTY_ITEMS: never[] = []\n\nexport function useEngramindList<T>(path: string | null, field: string, params?: Params, options: { enabled?: boolean; /** Lê todas as páginas (listas pequenas, como apps e tokens). */ all?: boolean } = {}) {\n const query = useInfiniteQuery({\n queryKey: [...engramindKey(path ?? \"-\", params), \"pages\"],\n initialPageParam: null as string | null,\n queryFn: async ({ pageParam }) => {\n const page = await engramindGet<Record<string, unknown>>(path!, { ...params, cursor: pageParam ?? undefined, limit: 100 })\n return { items: (page[field] as T[] | undefined) ?? [], nextCursor: (page.next_cursor as string | null | undefined) ?? null, truncated: page.truncated === true }\n },\n getNextPageParam: (last) => last.nextCursor,\n enabled: path !== null && options.enabled !== false,\n retry: (count, error) => count < 1 && apiErrorCode(error) !== \"ENGRAMIND_NOT_CONFIGURED\",\n })\n const { hasNextPage, isFetchingNextPage, fetchNextPage } = query\n useEffect(() => {\n if (options.all && hasNextPage && !isFetchingNextPage) void fetchNextPage()\n }, [options.all, hasNextPage, isFetchingNextPage, fetchNextPage])\n // Mesma referência enquanto os dados não mudam: as telas derivam layout e nodes de `items`.\n const items = useMemo(() => query.data?.pages.flatMap((page) => page.items) ?? EMPTY_ITEMS, [query.data]) as T[]\n return { ...query, items }\n}\n\ninterface MutationOptions<V> {\n /** Áreas (1º segmento) a invalidar no sucesso. */\n invalidate: string[]\n success?: string | ((variables: V) => string)\n /** Não mostra o toast de erro (o chamador mostra no formulário). */\n silentError?: boolean\n /** Outras chaves a invalidar (ex.: o detalhe da integração). */\n alsoInvalidate?: readonly QueryKey[]\n}\n\n/** Mutação numa rota do Engramind, com toast pt-BR e invalidação das áreas afetadas. */\nexport function useEngramindMutation<V, T = unknown>(request: (variables: V) => Promise<T>, options: MutationOptions<V>) {\n const queryClient = useQueryClient()\n return useMutation({\n mutationFn: request,\n onSuccess: (_data, variables) => {\n for (const area of options.invalidate) void queryClient.invalidateQueries({ queryKey: areaKey(area) })\n for (const queryKey of options.alsoInvalidate ?? []) void queryClient.invalidateQueries({ queryKey })\n const message = typeof options.success === \"function\" ? options.success(variables) : options.success\n if (message) toast.success(message)\n },\n onError: (error) => {\n if (!options.silentError) toast.error(apiErrorMessage(error, \"Não foi possível concluir a ação no Engramind.\"))\n },\n })\n}\n\n/** Áreas a invalidar por tipo de evento. `memory.consumed` não invalida nada (só anima a rede). */\nexport function areasForEvent(type: string): string[] {\n if (type === \"memory.consumed\") return []\n if (type.startsWith(\"memory.\")) return [\"memories\", \"channels\", \"agent-activity\"]\n if (type === \"memories.context\") return [\"agent-activity\"]\n if (type === \"channel.updated\") return [\"channels\", \"memories\", \"consumer-settings\"]\n if (type === \"subscription.updated\") return [\"subscriptions\", \"agents\", \"channels\", \"consumer-settings\"]\n if (type === \"settings.updated\") return [\"settings\", \"channels\", \"status\", \"providers\", \"consumer-settings\", \"categories\"]\n if (type === \"identities.updated\") return [\"apps\", \"agents\", \"tokens\", \"connection\", \"whoami\"]\n if (type === \"jobs.updated\" || type === \"status.updated\") return [\"jobs\", \"status\"]\n if (type.startsWith(\"env.\")) return [\"env\", \"status\", \"connection\"]\n if (type === \"migration.updated\") return [\"migration\"]\n return []\n}\n\n/**\n * Tempo real pelo SSE da lib (`events` do provider): cada evento invalida as áreas afetadas e, quando a\n * conexão volta depois de cair, todas as consultas do Engramind são relidas. Sem `events`, nada.\n */\nexport function useEngramindRealtime(): void {\n const queryClient = useQueryClient()\n const { events } = useEngramindConfig()\n useEffect(() => {\n if (!events) return\n return subscribeLive(events, {\n onEvent: (event) => {\n for (const area of areasForEvent(event.type)) void queryClient.invalidateQueries({ queryKey: areaKey(area) })\n },\n onReconnect: () => void queryClient.invalidateQueries({ queryKey: [ENGRAMIND_QUERY_KEY] }),\n })\n }, [events, queryClient])\n}\n\n/** Erro que pede reconfigurar a conexão (token inválido/insuficiente ou sem configuração). */\nexport function needsReconnect(error: unknown): \"configure\" | \"token\" | null {\n const code = apiErrorCode(error)\n if (code === \"ENGRAMIND_NOT_CONFIGURED\") return \"configure\"\n if (code === \"ENGRAMIND_AUTH_INVALID\" || code === \"ENGRAMIND_SCOPE_REQUIRED\" || code === \"ENGRAMIND_TOKEN_INSUFFICIENT\") return \"token\"\n return null\n}\n","\"use client\"\n\nimport { useMemo } from \"react\"\nimport { useEngramindConfig } from \"../../lib/config\"\nimport { agentDisplayName, DEFAULT_SEARCH_FUSION, DEFAULT_STALE_AFTER_DAYS, type SearchFusion, type SubscriptionInput } from \"../network/network-math\"\nimport type { NetworkAgent, NetworkChannel, NetworkMemory } from \"../network/types\"\nimport type { Category, ConsumerSettings, EngramindAgent, EngramindApp, EngramindChannel, EngramindMemory, EngramindSubscription, SettingMeta, WhoAmI } from \"../types\"\nimport { useEngramindList, useEngramindQuery } from \"./useEngramind\"\n\n/**\n * Dados da rede do Engramind: canais (com os arquivados), agentes, assinaturas e memórias de todos os\n * status (todas as páginas). No modo gestor, também os apps e as configurações globais (o prazo\n * `consolidation.stale_after_days` e os pesos da busca); no modo app, o próprio app (`whoami`), as\n * categorias e os limites de `get_consumer_settings`. Tudo pela fonte de dados do provider.\n */\n\nexport const STALE_AFTER_DAYS_KEY = \"consolidation.stale_after_days\"\nconst ALL_STATUSES = \"active,permanent,archived\"\n\nexport function toNetworkMemory(memory: EngramindMemory): NetworkMemory {\n return {\n id: memory.id,\n channel: memory.channel,\n title: memory.title?.trim() || firstSentence(memory.text),\n text: memory.text,\n category: memory.category,\n status: memory.status,\n version: memory.version,\n createdAt: memory.created_at,\n updatedAt: memory.updated_at,\n retrievals: memory.retrieval_count ?? 0,\n injections: memory.injected_count ?? 0,\n lastRetrievedAt: memory.last_retrieved_at ?? null,\n verifiedAt: memory.verified_at ?? null,\n stale: memory.stale_candidate === true,\n author: memory.author?.agent ?? memory.author?.app ?? null,\n authorAgent: memory.author?.agent ?? null,\n }\n}\n\n/** Pesos da fusão da busca nas configurações do Engramind (padrão 1/1/60). */\nexport function searchFusionOf(setting: (key: string) => unknown): SearchFusion {\n const number = (key: string, fallback: number) => {\n const value = setting(key)\n return typeof value === \"number\" && value >= 0 ? value : fallback\n }\n return { vectorWeight: number(\"search.vector_weight\", DEFAULT_SEARCH_FUSION.vectorWeight), textWeight: number(\"search.text_weight\", DEFAULT_SEARCH_FUSION.textWeight), k: number(\"search.rrf_k\", DEFAULT_SEARCH_FUSION.k) }\n}\n\nexport function firstSentence(text: string): string {\n const flat = text.replace(/\\s+/g, \" \").trim()\n const match = /^(.{1,140}?[.!?])(\\s|$)/.exec(flat)\n return match ? match[1] : flat.length > 140 ? `${flat.slice(0, 137)}…` : flat\n}\n\n/** Pesos da fusão da busca em `get_consumer_settings` (modo app). */\nexport function consumerSearchFusion(consumer: ConsumerSettings | undefined): SearchFusion {\n const search = consumer?.search\n const number = (value: unknown, fallback: number) => (typeof value === \"number\" && value >= 0 ? value : fallback)\n return { vectorWeight: number(search?.vector_weight, DEFAULT_SEARCH_FUSION.vectorWeight), textWeight: number(search?.text_weight, DEFAULT_SEARCH_FUSION.textWeight), k: number(search?.rrf_k, DEFAULT_SEARCH_FUSION.k) }\n}\n\n/** Prazo de desuso: o fixado pelo app, o do Engramind (gestor: `settings`; app: `consumer-settings`) ou 90. */\nexport function resolveStaleAfterDays(fixed: number | undefined, fromEngramind: unknown): number {\n if (typeof fixed === \"number\" && fixed > 0) return fixed\n return typeof fromEngramind === \"number\" && fromEngramind > 0 ? fromEngramind : DEFAULT_STALE_AFTER_DAYS\n}\n\n/** Slug do app do token (modo app): o fixado no provider ou o de `whoami`. */\nexport function useOwnApp(): { slug: string | null; isLoading: boolean; error: unknown } {\n const config = useEngramindConfig()\n const whoami = useEngramindQuery<WhoAmI>(\"whoami\", undefined, { enabled: config.mode === \"app\" && !config.app })\n return { slug: config.app ?? whoami.data?.app.slug ?? null, isLoading: !config.app && whoami.isLoading, error: config.app ? null : whoami.error }\n}\n\nexport function useEngramindNetwork() {\n const config = useEngramindConfig()\n const manager = config.mode === \"manager\"\n const own = useOwnApp()\n const channels = useEngramindList<EngramindChannel>(\"channels\", \"channels\", { include_archived: true }, { all: true })\n const apps = useEngramindList<EngramindApp>(\"apps\", \"apps\", {}, { all: true, enabled: manager })\n const agents = useEngramindList<EngramindAgent>(\"agents\", \"agents\", manager ? {} : { app: own.slug }, { all: true, enabled: manager || own.slug !== null })\n const subscriptions = useEngramindList<EngramindSubscription>(\"subscriptions\", \"subscriptions\", {}, { all: true })\n const memories = useEngramindList<EngramindMemory>(\"memories\", \"memories\", { status: ALL_STATUSES }, { all: true })\n const settings = useEngramindQuery<{ settings: SettingMeta[] }>(\"settings\", undefined, { enabled: manager })\n const consumer = useEngramindQuery<ConsumerSettings>(manager ? null : \"consumer-settings\")\n const categoryList = useEngramindQuery<{ categories: Category[] }>(manager ? null : \"categories\")\n\n const setting = (key: string) => settings.data?.settings?.find((meta) => meta.key === key)?.value\n const staleDays = manager ? setting(STALE_AFTER_DAYS_KEY) : consumer.data?.consolidation?.stale_after_days\n const maxBatch = manager ? setting(\"limits.max_batch\") : consumer.data?.limits?.max_batch\n const categoriesSetting = (manager ? setting(\"categories.list\") : categoryList.data?.categories) as Category[] | undefined\n const categories = useMemo(() => categoriesSetting ?? [], [categoriesSetting])\n const textMin = manager ? setting(\"memory.text_min\") : consumer.data?.memory?.text_min\n const textMax = manager ? setting(\"memory.text_max\") : consumer.data?.memory?.text_max\n const limits = typeof textMin === \"number\" && typeof textMax === \"number\" ? { textMin, textMax } : undefined\n\n const data = useMemo(() => {\n const qualifiedById = new Map(agents.items.map((agent) => [agent.id, agent.qualified_slug]))\n const networkAgents: NetworkAgent[] = agents.items.filter((agent) => !agent.disabled_at).map((agent) => ({ id: agent.qualified_slug, app: agent.app.slug, name: agentDisplayName(agent.name) }))\n const networkChannels: NetworkChannel[] = channels.items.map((channel) => ({ slug: channel.slug, name: channel.name, archived: Boolean(channel.archived_at) }))\n const subscriptionInputs: SubscriptionInput[] = subscriptions.items.map((subscription) => ({\n id: subscription.id,\n agent: subscription.agent.qualified_slug ?? qualifiedById.get(subscription.agent.id) ?? subscription.agent.slug,\n target: subscription.target,\n isPrefix: subscription.is_prefix,\n mode: subscription.mode,\n reaches: subscription.reaches ?? [],\n }))\n // Nome de todos os agentes (inclusive os desligados): chip do autor no card da memória.\n const agentNames = new Map(agents.items.map((agent) => [agent.qualified_slug, agentDisplayName(agent.name)]))\n return { agents: networkAgents, agentNames, channels: networkChannels, subscriptions: subscriptionInputs, memories: memories.items.map(toNetworkMemory) }\n }, [agents.items, channels.items, subscriptions.items, memories.items])\n\n // Referências estáveis enquanto os dados não mudam (o layout e os nodes da rede derivam delas).\n const activeApps = useMemo(\n () => (manager ? apps.items.filter((app) => !app.disabled_at).map((app) => ({ slug: app.slug, name: app.name })) : own.slug ? [{ slug: own.slug, name: config.appName ?? own.slug }] : []),\n [manager, apps.items, own.slug, config.appName],\n )\n\n const queries = manager ? [channels, apps, agents, subscriptions, memories] : [channels, agents, subscriptions, memories]\n const loading = queries.some((query) => query.isLoading) || queries.some((query) => query.hasNextPage) || own.isLoading\n const error = queries.find((query) => query.error)?.error ?? (manager ? settings.error : (consumer.error ?? own.error)) ?? null\n return {\n ...data,\n apps: activeApps,\n /** App do token (modo app); `null` no gestor. */\n ownApp: manager ? null : own.slug,\n rawChannels: channels.items,\n rawAgents: agents.items,\n rawMemories: memories.items,\n categories,\n limits,\n maxBatch: typeof maxBatch === \"number\" ? maxBatch : null,\n searchFusion: manager ? searchFusionOf(setting) : consumerSearchFusion(consumer.data),\n staleAfterDays: resolveStaleAfterDays(config.staleAfterDays, staleDays),\n memoriesUpdatedAt: memories.dataUpdatedAt,\n /** Lista de canais sendo relida (canal recém-criado ainda não chegou). */\n channelsFetching: channels.isFetching,\n isLoading: loading && !error,\n error: error as unknown,\n refetch: () => {\n for (const query of queries) void query.refetch()\n if (manager) void settings.refetch()\n else {\n void consumer.refetch()\n void categoryList.refetch()\n }\n },\n }\n}\n","\"use client\"\n\nimport { keepPreviousData, useQuery } from \"@tanstack/react-query\"\nimport { ENGRAMIND_QUERY_KEY } from \"../constants\"\nimport { relevantSearchIds, type SearchFusion } from \"../network/network-math\"\nimport type { SearchResults } from \"../types\"\nimport { engramindSend } from \"./useEngramind\"\n\n/** Limite de canais citados por requisição (schema de `search_memories`). */\nexport const SEARCH_CHANNELS_PER_REQUEST = 50\nconst SEARCH_LIMIT = 50\n\nexport interface NetworkSearchResult {\n ids: Set<string>\n textOnly: boolean\n}\n\n/** Divide os canais citados em lotes de `size`. Sem canais: um lote vazio (busca sem citar canais). */\nexport function channelBatches(channels: readonly string[], size = SEARCH_CHANNELS_PER_REQUEST): string[][] {\n const unique = [...new Set(channels)].sort()\n if (!unique.length) return [[]]\n const batches: string[][] = []\n for (let index = 0; index < unique.length; index += size) batches.push(unique.slice(index, index + size))\n return batches\n}\n\n/**\n * Busca da rede (OPE-113): roda sozinha com o termo (a espera de digitação fica no campo), cita os\n * canais da visão atual (o Engramind só busca nos canais `manage` e arquivados quando citados), em lotes\n * de 50, e destaca só os resultados relevantes (`relevantSearchIds`).\n */\nexport function useNetworkSearch({ query, channels, categories, fusion, enabled = true }: { query: string; channels: readonly string[]; categories: readonly string[]; fusion: SearchFusion; enabled?: boolean }) {\n const text = query.trim()\n const batches = channelBatches(channels)\n const sortedCategories = [...new Set(categories)].sort()\n return useQuery({\n // Fora da área `memories`: memória alterada pelo tempo real não refaz a busca. Cada busca conta como\n // consulta no Engramind (`retrieval_count`, `last_retrieved_at`), então ela só roda quando o termo,\n // os canais citados ou as categorias mudam: sem refazer por foco, reconexão ou idade do cache.\n queryKey: [ENGRAMIND_QUERY_KEY, \"network-search\", text, batches, sortedCategories, fusion.vectorWeight, fusion.textWeight, fusion.k],\n enabled: enabled && text.length > 0,\n placeholderData: keepPreviousData,\n staleTime: Number.POSITIVE_INFINITY,\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n refetchOnMount: false,\n retry: false,\n queryFn: async (): Promise<NetworkSearchResult> => {\n const responses = await Promise.all(\n batches.map((batch) =>\n engramindSend<SearchResults>(\"post\", \"memories/search\", {\n query: text,\n ...(batch.length ? { channels: batch } : {}),\n ...(sortedCategories.length ? { categories: sortedCategories } : {}),\n include_archived: true,\n limit: SEARCH_LIMIT,\n }),\n ),\n )\n const ids = new Set<string>()\n for (const response of responses) for (const id of relevantSearchIds(response.results, response.mode, fusion)) ids.add(id)\n return { ids, textOnly: responses.some((response) => response.mode === \"text\") }\n },\n })\n}\n","\"use client\"\n\nimport type { ReactNode } from \"react\"\nimport { KeyRound, Lock, PlugZap } from \"lucide-react\"\nimport { EmptyState } from \"../../../components/feedback/EmptyState\"\nimport { ErrorState } from \"../../../components/feedback/ErrorState\"\nimport { apiErrorCode, apiErrorMessage } from \"../../../lib/api\"\nimport { useEngramindConfig, useT } from \"../../../lib/config\"\nimport { needsReconnect } from \"../../hooks/useEngramind\"\n\ninterface QueryBoundaryProps {\n isLoading: boolean\n error: unknown\n onRetry: () => void\n skeleton: ReactNode\n /** Para onde levar quando a conexão precisa ser (re)configurada. */\n onConfigure?: () => void\n children: ReactNode\n}\n\n/** Erro de acesso do token de app (registro de outro app ou canal fora das assinaturas). */\nexport const isNoAccessError = (error: unknown) => {\n const code = apiErrorCode(error)\n return code === \"ENGRAMIND_FOREIGN_APP\" || code === \"ENGRAMIND_CHANNEL_NOT_SUBSCRIBED\"\n}\n\n/**\n * Carregando (skeleton), erro com \"Tentar novamente\", \"Reconfigure o token\" (401 do Engramind), \"Sem\n * acesso\" (`403 FOREIGN_APP`/`CHANNEL_NOT_SUBSCRIBED`) e o conteúdo. Fora do ar, proxy mascarado e `429`\n * (com o `Retry-After` na mensagem) mostram a mensagem pt-BR com \"Tentar novamente\".\n */\nexport function QueryBoundary({ isLoading, error, onRetry, skeleton, onConfigure, children }: QueryBoundaryProps) {\n const config = useEngramindConfig()\n const t = useT()\n const configure = onConfigure ?? (config.onConfigure ? () => config.onConfigure!(\"connection\") : undefined)\n const manager = config.mode === \"manager\"\n if (isLoading) return <>{skeleton}</>\n if (error) {\n const reconnect = needsReconnect(error)\n if (reconnect === \"configure\") return <EmptyState icon={PlugZap} title=\"Configure a conexão\" description={manager ? \"Informe a URL base e o token admin do Engramind na aba Conexão.\" : \"Informe a URL base e o token do app no servidor do app.\"} actionLabel={configure ? (manager ? \"Ir para Conexão\" : t(\"network.configure\")) : undefined} onAction={configure} />\n if (reconnect === \"token\") return <EmptyState icon={KeyRound} title={manager ? \"Reconfigure o token\" : t(\"state.configure.title\")} description={apiErrorMessage(error, t(\"state.configure.description\"))} actionLabel={configure ? (manager ? \"Ir para Conexão\" : t(\"network.configure\")) : undefined} onAction={configure} />\n if (isNoAccessError(error)) return <EmptyState icon={Lock} title={t(\"state.noAccess.title\")} description={apiErrorMessage(error, t(\"state.noAccess.description\"))} actionLabel={t(\"state.retry\")} onAction={onRetry} />\n return <ErrorState description={apiErrorMessage(error, \"Não foi possível falar com o Engramind.\")} onRetry={onRetry} />\n }\n return <>{children}</>\n}\n","\"use client\"\n\nimport { motion } from \"framer-motion\"\nimport { AlertTriangle, RotateCw } from \"lucide-react\"\nimport { Button } from \"../ui/button\"\nimport { fadeUp } from \"../motion/presets\"\n\ninterface ErrorStateProps {\n title?: string\n description?: string\n onRetry?: () => void\n}\n\n/** Estado de erro padrão, com \"Tentar novamente\". */\nexport function ErrorState({\n title = \"Não foi possível carregar os dados\",\n description = \"Verifique sua conexão e tente novamente.\",\n onRetry,\n}: ErrorStateProps) {\n return (\n <motion.div\n variants={fadeUp}\n initial=\"hidden\"\n animate=\"visible\"\n role=\"alert\"\n className=\"flex flex-col items-center justify-center gap-3 px-4 py-14 text-center\"\n >\n <div className=\"rounded-full bg-destructive/10 p-3\">\n <AlertTriangle className=\"h-6 w-6 text-destructive\" aria-hidden />\n </div>\n <div className=\"max-w-sm space-y-1\">\n <p className=\"text-sm font-semibold text-foreground\">{title}</p>\n <p className=\"text-xs text-muted-foreground\">{description}</p>\n </div>\n {onRetry && (\n <Button size=\"sm\" variant=\"outline\" onClick={onRetry}>\n <RotateCw className=\"mr-2 h-3.5 w-3.5\" aria-hidden />\n Tentar novamente\n </Button>\n )}\n </motion.div>\n )\n}\n","\"use client\"\n\nimport { useState } from \"react\"\nimport { AnimatePresence, motion } from \"framer-motion\"\nimport { FileUp, Loader2 } from \"lucide-react\"\nimport { toast } from \"../../../../lib/toast\"\nimport { Button } from \"../../../../components/ui/button\"\nimport { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from \"../../../../components/ui/dialog\"\nimport { Input } from \"../../../../components/ui/input\"\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"../../../../components/ui/select\"\nimport { apiErrorMessage } from \"../../../../lib/api\"\nimport { MEMORY_HELP } from \"../../../help/identities\"\nimport { batchLimitError, parseImportFile, type ImportParseResult } from \"../../../schemas/import\"\nimport type { EngramindChannel, ImportResult } from \"../../../types\"\nimport { engramindSend, useEngramindMutation } from \"../../../hooks/useEngramind\"\nimport { InfoField } from \"../../shared/InfoField\"\n\n/** Importar: canal ativo + arquivo JSON (lista ou `{ memories }`) ou JSONL, prévia com erros por índice e resultado. */\nexport function ImportMemoriesDialog({ channels, maxBatch, onOpenChange }: { channels: EngramindChannel[]; maxBatch: number | null; onOpenChange: (open: boolean) => void }) {\n const active = channels.filter((channel) => !channel.archived_at)\n const [channel, setChannel] = useState(active[0]?.slug ?? \"\")\n const [file, setFile] = useState<{ name: string; parsed: ImportParseResult } | null>(null)\n const [result, setResult] = useState<ImportResult | null>(null)\n const send = useEngramindMutation((body: { channel: string; memories: ImportParseResult[\"items\"] }) => engramindSend<ImportResult>(\"post\", \"memories/import\", body), { invalidate: [\"memories\", \"channels\"], silentError: true })\n const tooLarge = file ? batchLimitError(file.parsed.items.length + file.parsed.errors.length, maxBatch) : null\n const blocked = !file || Boolean(file.parsed.fatal) || file.parsed.errors.length > 0 || file.parsed.items.length === 0 || Boolean(tooLarge) || !channel\n const pick = async (selected: File | undefined) => {\n setResult(null)\n if (!selected) return setFile(null)\n setFile({ name: selected.name, parsed: parseImportFile(await selected.text()) })\n }\n const submit = async () => {\n if (!file) return\n try {\n setResult(await send.mutateAsync({ channel, memories: file.parsed.items }))\n } catch (error) {\n toast.error(apiErrorMessage(error, \"Não foi possível importar\"))\n }\n }\n return (\n <Dialog open onOpenChange={onOpenChange}>\n <DialogContent className=\"max-h-[85vh] overflow-y-auto sm:max-w-xl\">\n <DialogHeader>\n <DialogTitle>Importar memórias</DialogTitle>\n <DialogDescription>Tudo é validado antes de gravar: um item inválido recusa o lote. {MEMORY_HELP.importKey}</DialogDescription>\n </DialogHeader>\n <div className=\"space-y-4\">\n <InfoField id=\"import-channel\" label=\"Canal\" info=\"Canal ativo que recebe as memórias (um canal por arquivo).\">\n <Select value={channel} onValueChange={setChannel}>\n <SelectTrigger id=\"import-channel\" className=\"bg-transparent\">\n <SelectValue placeholder=\"Escolha o canal\" />\n </SelectTrigger>\n <SelectContent>\n {active.map((item) => (\n <SelectItem key={item.id} value={item.slug}>\n {item.slug}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </InfoField>\n <InfoField id=\"import-file\" label=\"Arquivo\" info={`Lista JSON, { \"memories\": [...] } ou JSONL. Cada item: text (obrigatório), category, created_at, status (active/permanent), author { app, agent } e origin.${maxBatch ? ` Até ${maxBatch} itens (limits.max_batch).` : \"\"}`}>\n <Input id=\"import-file\" type=\"file\" accept=\".json,.jsonl,application/json\" onChange={(event) => void pick(event.target.files?.[0])} />\n </InfoField>\n <AnimatePresence mode=\"wait\" initial={false}>\n {result ? (\n <motion.div key=\"result\" initial={{ opacity: 0, y: 6 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-2 rounded-lg border p-3 text-sm\">\n <p className=\"text-success\">{result.created.length} memória(s) criada(s).</p>\n {result.duplicates.length > 0 && (\n <div>\n <p>{result.duplicates.length} duplicada(s) (já existiam):</p>\n <ul className=\"max-h-32 overflow-auto font-mono text-xs text-muted-foreground\">\n {result.duplicates.map((item) => (\n <li key={item.index}>\n item {item.index + 1} → {item.existing_id}\n </li>\n ))}\n </ul>\n </div>\n )}\n </motion.div>\n ) : file ? (\n <motion.div key=\"preview\" initial={{ opacity: 0, y: 6 }} animate={{ opacity: 1, y: 0 }} className=\"space-y-2 rounded-lg border p-3 text-sm\">\n {file.parsed.fatal ? (\n <p className=\"text-destructive\">{file.parsed.fatal}</p>\n ) : (\n <p>\n {file.name}: {file.parsed.items.length} memória(s) válida(s)\n {file.parsed.errors.length > 0 && <span className=\"text-destructive\">, {file.parsed.errors.length} com erro</span>}\n </p>\n )}\n {tooLarge && <p className=\"text-destructive\">{tooLarge}</p>}\n {file.parsed.errors.length > 0 && (\n <ul className=\"max-h-40 overflow-auto text-xs text-destructive\">\n {file.parsed.errors.map((error) => (\n <li key={error.index}>\n Item {error.index + 1}: {error.message}\n </li>\n ))}\n </ul>\n )}\n </motion.div>\n ) : null}\n </AnimatePresence>\n </div>\n <DialogFooter>\n {result ? (\n <Button type=\"button\" onClick={() => onOpenChange(false)}>\n Concluir\n </Button>\n ) : (\n <Button type=\"button\" onClick={() => void submit()} disabled={blocked || send.isPending}>\n {send.isPending ? <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" aria-hidden /> : <FileUp className=\"mr-2 h-4 w-4\" aria-hidden />} Importar\n </Button>\n )}\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\"\nimport { X } from \"lucide-react\"\nimport { cn } from \"../../lib/utils\"\nimport { usePortalContainer } from \"./portal-container\"\n\nconst Dialog = DialogPrimitive.Root\n\nconst DialogTrigger = DialogPrimitive.Trigger\n\nconst DialogPortal = DialogPrimitive.Portal\n\nconst DialogClose = DialogPrimitive.Close\n\nconst DialogOverlay = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Overlay\n ref={ref}\n className={cn(\n \"fixed inset-0 z-50 bg-background/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n className\n )}\n {...props}\n />\n))\nDialogOverlay.displayName = DialogPrimitive.Overlay.displayName\n\nconst DialogContent = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>\n>(({ className, children, ...props }, ref) => (\n <DialogPortal container={usePortalContainer()}>\n <DialogOverlay />\n <DialogPrimitive.Content\n ref={ref}\n className={cn(\n \"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg\",\n className\n )}\n {...props}\n >\n {children}\n <DialogPrimitive.Close className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground\">\n <X className=\"h-4 w-4\" />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n </DialogPrimitive.Content>\n </DialogPortal>\n))\nDialogContent.displayName = DialogPrimitive.Content.displayName\n\nconst DialogHeader = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex flex-col space-y-1.5 text-center sm:text-left\",\n className\n )}\n {...props}\n />\n)\nDialogHeader.displayName = \"DialogHeader\"\n\nconst DialogFooter = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2\",\n className\n )}\n {...props}\n />\n)\nDialogFooter.displayName = \"DialogFooter\"\n\nconst DialogTitle = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Title\n ref={ref}\n className={cn(\n \"text-lg font-semibold leading-none tracking-tight\",\n className\n )}\n {...props}\n />\n))\nDialogTitle.displayName = DialogPrimitive.Title.displayName\n\nconst DialogDescription = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Description\n ref={ref}\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n))\nDialogDescription.displayName = DialogPrimitive.Description.displayName\n\nexport {\n Dialog,\n DialogPortal,\n DialogOverlay,\n DialogClose,\n DialogTrigger,\n DialogContent,\n DialogHeader,\n DialogFooter,\n DialogTitle,\n DialogDescription,\n}\n","import * as React from \"react\"\n\nimport { cn } from \"../../lib/utils\"\n\nconst Input = React.forwardRef<HTMLInputElement, React.ComponentProps<\"input\">>(\n ({ className, type, ...props }, ref) => {\n return (\n <input\n type={type}\n className={cn(\n \"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n (type === \"date\" || type === \"time\" || type === \"datetime-local\") && \"block\",\n className\n )}\n ref={ref}\n {...props}\n />\n )\n }\n)\nInput.displayName = \"Input\"\n\nexport { Input }\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as SelectPrimitive from \"@radix-ui/react-select\"\nimport { Check, ChevronDown, ChevronUp } from \"lucide-react\"\n\nimport { cn } from \"../../lib/utils\"\nimport { usePortalContainer } from \"./portal-container\"\n\n/**\n * Dentro de um `<form>`, o Radix espelha o valor num `<select>` nativo oculto e dispara\n * `onValueChange(\"\")` quando o valor controlado muda antes de a opção existir (ex.: `form.reset`\n * com o valor salvo), deixando o campo vazio e o formulário \"sujo\". O Radix proíbe `SelectItem`\n * com `value=\"\"`, então `\"\"` nunca é escolha do usuário e é ignorado.\n */\nfunction Select({ onValueChange, ...props }: React.ComponentProps<typeof SelectPrimitive.Root>) {\n return (\n <SelectPrimitive.Root\n {...props}\n onValueChange={(value) => {\n if (value === \"\") return\n onValueChange?.(value)\n }}\n />\n )\n}\n\nconst SelectGroup = SelectPrimitive.Group\n\nconst SelectValue = SelectPrimitive.Value\n\nconst SelectTrigger = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Trigger\n ref={ref}\n className={cn(\n \"flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background data-[placeholder]:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1\",\n className\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDown className=\"h-4 w-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n))\nSelectTrigger.displayName = SelectPrimitive.Trigger.displayName\n\nconst SelectScrollUpButton = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.ScrollUpButton\n ref={ref}\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className\n )}\n {...props}\n >\n <ChevronUp className=\"h-4 w-4\" />\n </SelectPrimitive.ScrollUpButton>\n))\nSelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName\n\nconst SelectScrollDownButton = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.ScrollDownButton\n ref={ref}\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className\n )}\n {...props}\n >\n <ChevronDown className=\"h-4 w-4\" />\n </SelectPrimitive.ScrollDownButton>\n))\nSelectScrollDownButton.displayName =\n SelectPrimitive.ScrollDownButton.displayName\n\nconst SelectContent = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>\n>(({ className, children, position = \"popper\", ...props }, ref) => (\n <SelectPrimitive.Portal container={usePortalContainer()}>\n <SelectPrimitive.Content\n ref={ref}\n className={cn(\n \"relative z-50 max-h-[var(--radix-select-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[var(--radix-select-content-transform-origin)]\",\n position === \"popper\" &&\n \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n className\n )}\n position={position}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n className={cn(\n \"p-1\",\n position === \"popper\" &&\n \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]\"\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n))\nSelectContent.displayName = SelectPrimitive.Content.displayName\n\nconst SelectLabel = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Label\n ref={ref}\n className={cn(\"px-2 py-1.5 text-sm font-semibold\", className)}\n {...props}\n />\n))\nSelectLabel.displayName = SelectPrimitive.Label.displayName\n\nconst SelectItem = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Item\n ref={ref}\n className={cn(\n \"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n className\n )}\n {...props}\n >\n <span className=\"absolute right-2 flex h-3.5 w-3.5 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <Check className=\"h-4 w-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n))\nSelectItem.displayName = SelectPrimitive.Item.displayName\n\nconst SelectSeparator = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Separator\n ref={ref}\n className={cn(\"-mx-1 my-1 h-px bg-muted\", className)}\n {...props}\n />\n))\nSelectSeparator.displayName = SelectPrimitive.Separator.displayName\n\nexport {\n Select,\n SelectGroup,\n SelectValue,\n SelectTrigger,\n SelectContent,\n SelectLabel,\n SelectItem,\n SelectSeparator,\n SelectScrollUpButton,\n SelectScrollDownButton,\n}\n","/** Explicações de tokens, escopos, tipos e assinaturas (guias `tokens-e-escopos` e `canais-e-assinaturas`). */\nexport const SCOPE_HELP: Record<string, string> = {\n read: \"Ler e consultar. Num token admin, também ler identidades, configurações, status e auditoria.\",\n write: \"Criar e alterar. Num token admin, também identidades, canais, assinaturas e configurações. Exige read.\",\n delete: \"Excluir de vez. Num token admin, também excluir canais, apps e agentes e revogar tokens. Exige read.\",\n}\n\nexport const SCOPE_COMBINATION_HELP: Record<string, string> = {\n read: \"Só leitura.\",\n \"read+write\": \"Ler, criar e alterar; não exclui nem revoga.\",\n \"read+delete\": \"Ler e excluir; não cria nem altera.\",\n \"read+write+delete\": \"Acesso completo (o necessário para o Opex administrar a rede).\",\n}\n\nexport const TOKEN_KIND_HELP: Record<string, string> = {\n admin: \"Gere a rede: apps, agentes, tokens, canais, assinaturas, configurações, status e auditoria. Alcança todos os canais. Pertence a um app.\",\n agent: \"Opera memórias só nos canais que o agente assina (acesso = escopos ∩ acesso da assinatura). Pertence a um agente.\",\n app: \"Provisiona o próprio app: agentes, tokens de agente, assinaturas e o webhook dele (403 FOREIGN_APP fora do app). Não grava memórias uma a uma. Só o admin emite.\",\n}\n\nexport const TOKEN_STATUS_HELP: Record<string, string> = {\n active: \"Autentica normalmente.\",\n expired: \"Passou da expiração: recebe 401.\",\n revoked: \"Revogado: recebe 401 na hora.\",\n}\n\nexport const SUBSCRIPTION_MODE_HELP: Record<string, string> = {\n inject: \"Entra no contexto pronto do agente, na busca e nas dicas.\",\n search: \"Entra na busca e nas dicas, mas não no contexto.\",\n manage: \"Só é alcançado quando o canal é citado pelo slug exato (curadoria sem poluir o contexto).\",\n}\n\nexport const IDENTITY_HELP = {\n app: \"Sistema que usa o Engramind (consumidor ou gestor). Slug único na rede; recebe webhooks dos canais que os agentes dele assinam (todos, se tiver token admin).\",\n agent: \"Agente de um app (endereço app/agente). Os tokens agent dele só alcançam os canais assinados.\",\n token: \"Credencial Bearer eng.tk_…; o segredo aparece só na emissão. last_used_at é gravado em lote a cada 10 s.\",\n webhook: \"URL que recebe os eventos assinados (HMAC-SHA256) e o segredo de 32 a 256 caracteres, só gravado.\",\n disabled: \"Desativado: os tokens deixam de autenticar e voltam ao reativar, sem perder o vínculo.\",\n access: \"Restringe os escopos do token neste alvo (nunca amplia). Vazio: os escopos do token.\",\n target: \"Canal exato (eng/global) ou prefixo com * depois de um segmento completo (eng/*, eng/projeto-*). Prefixo vale para canais criados depois.\",\n subscriptionPriority: \"Sobrepõe a prioridade do canal na ordem do contexto deste agente. Vazio: a do canal.\",\n reaches: \"Canais ativos que o alvo alcança agora.\",\n expiresAt: \"Opcional. Depois desta data o token recebe 401 (status expired).\",\n label: \"Nome para reconhecer o token na lista.\",\n ownToken: \"Token que este Opex usa para administrar o Engramind: não pode ser revogado nem rebaixado por aqui.\",\n lastAdmin: \"A rede nunca fica sem um token admin ativo com write: emita outro antes de revogar, rebaixar, desativar ou excluir o último.\",\n} as const\n\nexport const CHANNEL_HELP = {\n slug: \"Endereço hierárquico e imutável do canal (eng/global): minúsculas, dígitos e hífens, até 8 segmentos.\",\n priority: \"De -1000 a 1000 (padrão 0): ordem padrão do canal no contexto.\",\n version: \"Cresce a cada mudança do canal ou das memórias dele.\",\n archived: \"Arquivado: sai do contexto, da busca e das dicas e não recebe escrita. Só canal arquivado pode ser excluído.\",\n override: \"Sobreposição do canal: vale só neste canal no lugar do valor global.\",\n pending: \"Memórias aguardando o título do Redator ou o vetor do embedding.\",\n retrievals: \"Quantas vezes as memórias do canal foram devolvidas em buscas e contextos.\",\n} as const\n\nexport const MEMORY_HELP = {\n status: \"active: em uso; permanent: fixada; archived: fora do contexto e da busca padrão.\",\n title_state: \"pending: aguardando o Redator; ready: título gerado; fallback: título provisório (Redator desligado ou falhou).\",\n embedding_state: \"pending: na fila; ready: vetorizada; failed: esgotou as tentativas; off: embeddings desligados.\",\n version: \"Cresce a cada revisão. O histórico guarda todas e Reverter cria uma revisão nova com o texto antigo.\",\n textOnly: \"Busca só textual: o embedding está desligado, sem configuração ou indisponível.\",\n importKey: \"A chave de idempotência sai do canal e do conteúdo: o mesmo arquivo de novo não duplica nada.\",\n} as const\n","import { z } from \"zod\"\nimport { channelSlugSchema } from \"../../../core/schemas\"\n\n/** Um item de `import_memories` (mesmo contrato do Engramind). */\nexport const importItemSchema = z\n .object({\n text: z.string().trim().min(1, \"Texto vazio\").max(20_000),\n category: z.string().trim().min(1).max(40).optional(),\n created_at: z.string().datetime({ offset: true, message: \"created_at: use RFC 3339\" }).optional(),\n status: z.enum([\"active\", \"permanent\"]).optional(),\n author: z.object({ app: z.string().trim().min(1).max(80), agent: z.string().trim().min(1).max(80).optional() }).optional(),\n origin: z.object({ source: z.string().trim().min(1).max(80), label: z.string().trim().max(200).optional() }).optional(),\n })\n .strict()\nexport type ImportItem = z.infer<typeof importItemSchema>\n\n/** Corpo de `POST /api/engramind/memories/import`. */\nexport const importInputSchema = z.object({\n channel: z.union([channelSlugSchema, z.string().regex(/^ch_[A-Za-z0-9]+$/)]),\n memories: z.array(importItemSchema).min(1, \"O arquivo não tem memórias\").max(1000),\n})\nexport type ImportInput = z.infer<typeof importInputSchema>\n\nexport interface ImportParseResult {\n items: ImportItem[]\n errors: { index: number; message: string }[]\n /** O arquivo nem pôde ser lido (JSON inválido ou formato desconhecido). */\n fatal: string | null\n}\n\n/** Lê uma lista JSON, `{ \"memories\": [...] }` ou JSONL (um item por linha) e valida cada item. */\nexport function parseImportFile(content: string): ImportParseResult {\n const text = content.trim()\n if (!text) return { items: [], errors: [], fatal: \"Arquivo vazio\" }\n let raw: unknown[]\n try {\n const parsed: unknown = JSON.parse(text)\n if (Array.isArray(parsed)) raw = parsed\n else if (parsed && typeof parsed === \"object\" && Array.isArray((parsed as { memories?: unknown }).memories)) raw = (parsed as { memories: unknown[] }).memories\n // JSONL de uma linha só: o arquivo inteiro é um item (objeto com `text`).\n else if (parsed && typeof parsed === \"object\" && \"text\" in parsed) raw = [parsed]\n else return { items: [], errors: [], fatal: \"Use uma lista JSON, { \\\"memories\\\": [...] } ou JSONL\" }\n } catch {\n raw = []\n const lines = text.split(/\\r?\\n/).filter((line) => line.trim())\n for (const [index, line] of lines.entries()) {\n try {\n raw.push(JSON.parse(line))\n } catch {\n return { items: [], errors: [{ index, message: \"Linha não é JSON válido\" }], fatal: `JSON inválido na linha ${index + 1}` }\n }\n }\n }\n const items: ImportItem[] = []\n const errors: ImportParseResult[\"errors\"] = []\n raw.forEach((value, index) => {\n const parsed = importItemSchema.safeParse(value)\n if (parsed.success) items.push(parsed.data)\n else errors.push({ index, message: parsed.error.issues.map((issue) => `${issue.path.join(\".\") || \"item\"}: ${issue.message}`).join(\"; \") })\n })\n return { items, errors, fatal: null }\n}\n\n/** Recusa antes do envio o lote acima de `limits.max_batch`. */\nexport function batchLimitError(count: number, maxBatch: number | null | undefined): string | null {\n if (typeof maxBatch !== \"number\" || count <= maxBatch) return null\n return `O arquivo tem ${count} memórias e o limite por lote é ${maxBatch} (limits.max_batch). Divida o arquivo.`\n}\n","import { z } from \"zod\"\nimport { MEMORY_STATUSES, SUBSCRIPTION_MODES, TOKEN_KINDS } from \"./constants\"\nimport { scopesSchema } from \"./scopes\"\n\n/**\n * Schemas de entrada das operações que a lib usa (os mesmos do catálogo do Opex): o formulário valida com\n * eles e o proxy valida o corpo antes de chamar o Engramind.\n */\n\nconst limit = z.number().int().min(1).max(200).optional().describe(\"Itens por página (1 a 200, padrão 50)\")\nconst cursor = z.string().trim().min(1).max(500).optional().describe(\"Cursor da próxima página (next_cursor)\")\nconst page = { cursor, limit }\nconst isoDate = z.string().trim().datetime({ offset: true, message: \"Use data e hora RFC 3339 (ex.: 2026-10-31T12:00:00Z)\" })\n\n/** Slug hierárquico do canal (`eng/global`): minúsculas, dígitos e hífens; até 8 segmentos e 120 caracteres. */\nexport const channelSlugSchema = z\n .string()\n .trim()\n .max(120, \"Até 120 caracteres\")\n .regex(/^[a-z0-9]+(?:-[a-z0-9]+)*(?:\\/[a-z0-9]+(?:-[a-z0-9]+)*){0,7}$/, \"Use segmentos com minúsculas, dígitos e hífens simples, separados por /\")\nconst channelRef = z.string().trim().min(1).max(160).describe(\"Id (ch_…) ou slug do canal (eng/global)\")\nconst identitySlug = z\n .string()\n .trim()\n .min(1)\n .max(64)\n .regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, \"Use minúsculas, dígitos e hífens simples\")\nconst appRef = z.string().trim().min(1).max(80).describe(\"Id (app_…) ou slug do app\")\nconst agentRef = z.string().trim().min(1).max(160).describe(\"Id (ag_…) ou app/agente\")\nconst tokenRef = z.string().trim().min(1).max(40).describe(\"Id do token (tk_…)\")\nconst memoryRef = z.string().trim().min(1).max(60).describe(\"Id da memória (m_…)\")\nconst name = z.string().trim().min(1, \"Informe o nome\").max(120)\nconst description = z.string().trim().max(1000).nullable().optional()\nconst priority = z.number().int().min(-1000).max(1000)\nconst webhookUrl = z.string().trim().url(\"URL inválida\").max(2048).regex(/^https?:\\/\\//, \"Use http:// ou https://\").nullable().optional()\nconst webhookSecret = z.string().min(32, \"O segredo do webhook tem de 32 a 256 caracteres\").max(256).nullable().optional()\n/** Alvo de assinatura: canal exato (`eng/global`) ou prefixo com um segmento completo antes do `*` (`eng/*`, `eng/projeto-*`). */\nexport function isValidSubscriptionTarget(value: string): boolean {\n if (!value.endsWith(\"*\")) return channelSlugSchema.safeParse(value).success\n const base = value.slice(0, -1)\n const slash = base.lastIndexOf(\"/\")\n if (slash <= 0) return false\n return channelSlugSchema.safeParse(base.slice(0, slash)).success && /^[a-z0-9-]*$/.test(base.slice(slash + 1))\n}\nconst subscriptionTarget = z\n .string()\n .trim()\n .min(1)\n .max(121)\n .refine(isValidSubscriptionTarget, \"Canal exato (eng/global) ou prefixo terminado em * depois de um segmento completo (eng/*, eng/projeto-*)\")\nexport const createAgentInput = z.object({ app: appRef, slug: identitySlug, name, description })\nexport const updateAgentInput = z.object({ agent: agentRef, name: name.optional(), description, disabled: z.boolean().optional() })\nexport const updateTokenInput = z.object({ token: tokenRef, label: z.string().trim().max(120).nullable().optional(), scopes: scopesSchema.optional(), expires_at: isoDate.nullable().optional() })\nexport const createChannelInput = z.object({ slug: channelSlugSchema, name, description, priority: priority.optional() })\nexport const updateChannelInput = z.object({ channel: channelRef, name: name.optional(), description, priority: priority.optional() })\nexport const subscribeInput = z.object({ agent: agentRef, target: subscriptionTarget, mode: z.enum(SUBSCRIPTION_MODES), access: scopesSchema.nullable().optional(), priority: priority.nullable().optional() })\nexport const updateSubscriptionInput = z.object({ subscription: z.string().trim().min(1).max(40), mode: z.enum(SUBSCRIPTION_MODES).optional(), access: scopesSchema.nullable().optional(), priority: priority.nullable().optional() })\nexport const issueTokenInput = z\n.object({\n kind: z.enum(TOKEN_KINDS),\n app: appRef.optional(),\n agent: agentRef.optional(),\n scopes: scopesSchema,\n label: z.string().trim().max(120).optional(),\n expires_at: isoDate.optional(),\n})\n.superRefine((value, ctx) => {\n if (value.kind === \"agent\" && !value.agent) ctx.addIssue({ code: \"custom\", path: [\"agent\"], message: \"Token agent exige o agente\" })\n if (value.kind === \"admin\" && !value.app && !value.agent) ctx.addIssue({ code: \"custom\", path: [\"app\"], message: \"Informe o app do token admin\" })\n if (value.kind === \"app\" && !value.app) ctx.addIssue({ code: \"custom\", path: [\"app\"], message: \"Informe o app do token de app\" })\n if (value.kind === \"app\" && value.agent) ctx.addIssue({ code: \"custom\", path: [\"agent\"], message: \"Token de app não tem agente\" })\n})\n .meta({ examples: [{ kind: \"agent\", agent: \"app-a/curador\", scopes: [\"read\", \"write\"] }] })\n\nexport const createMemoryInput = z.object({ channel: channelRef, text: z.string().min(1), category: z.string().trim().min(1).max(64).optional(), key: z.string().trim().max(200).optional(), tags: z.array(z.string()).optional() })\nexport const updateMemoryInput = z.object({ text: z.string().min(1).optional(), category: z.string().trim().min(1).max(64).optional(), expected_version: z.number().int().optional(), tags: z.array(z.string()).optional() })\nexport const moveMemoryInput = z.object({ channel: channelRef })\n/** `update_app_webhook`: `url: null` remove a URL e o segredo; URL exige segredo (o enviado ou o já gravado). */\nexport const appWebhookInput = z.object({ url: webhookUrl, secret: webhookSecret }).strict()\nexport const memoryStatusSchema = z.enum(MEMORY_STATUSES)\nexport { memoryRef, tokenRef, agentRef, appRef, channelRef, cursor, limit, page }\n","import { z } from \"zod\"\nimport { combinationOf, ENGRAMIND_SCOPES } from \"./constants\"\n\n/** Escopos de um token ou acesso de assinatura: só `read`, `read+write`, `read+delete` ou `read+write+delete`. */\nexport const scopesSchema = z\n .array(z.enum(ENGRAMIND_SCOPES))\n .min(1, \"Escolha os escopos\")\n .max(3)\n .refine((scopes) => combinationOf(scopes) !== null, \"Combinações aceitas: read, read+write, read+delete ou read+write+delete (write e delete exigem read)\")\n","\"use client\"\n\nimport type { ReactNode } from \"react\"\nimport { Info } from \"lucide-react\"\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"./tooltip\"\nimport { cn } from \"../../lib/utils\"\n\ninterface InfoTooltipProps {\n /** Explicação mostrada ao passar o mouse ou focar o ícone. */\n text: ReactNode\n /** Nome do que é explicado (rótulo acessível: \"Sobre <label>\"). */\n label?: string\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n className?: string\n /** Classes da dica (ex.: mais larga para um texto longo). */\n contentClassName?: string\n}\n\n/** Ícone de informação com tooltip: explica um campo, parâmetro, escopo ou status ao lado do rótulo. */\nexport function InfoTooltip({ text, label, side = \"top\", className, contentClassName }: InfoTooltipProps) {\n return (\n <TooltipProvider delayDuration={150}>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n aria-label={label ? `Sobre ${label}` : \"Mais informações\"}\n className={cn(\"inline-flex h-4 w-4 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\", className)}\n >\n <Info className=\"h-3.5 w-3.5\" aria-hidden />\n </button>\n </TooltipTrigger>\n <TooltipContent side={side} className={cn(\"max-w-xs text-xs leading-relaxed\", contentClassName)}>\n {text}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )\n}\n\ninterface LabelWithInfoProps {\n children: ReactNode\n info?: ReactNode\n htmlFor?: string\n className?: string\n}\n\n/** Rótulo de campo com o ícone de informação ao lado. */\nexport function LabelWithInfo({ children, info, htmlFor, className }: LabelWithInfoProps) {\n return (\n <span className={cn(\"inline-flex items-center gap-1.5 text-sm font-medium\", className)}>\n {htmlFor ? <label htmlFor={htmlFor}>{children}</label> : <span>{children}</span>}\n {info && <InfoTooltip text={info} label={typeof children === \"string\" ? children : undefined} />}\n </span>\n )\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as LabelPrimitive from \"@radix-ui/react-label\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../../lib/utils\"\n\nconst labelVariants = cva(\n \"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n)\n\nconst Label = React.forwardRef<\n React.ElementRef<typeof LabelPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &\n VariantProps<typeof labelVariants>\n>(({ className, ...props }, ref) => (\n <LabelPrimitive.Root\n ref={ref}\n className={cn(labelVariants(), className)}\n {...props}\n />\n))\nLabel.displayName = LabelPrimitive.Root.displayName\n\nexport { Label }\n","import type { ReactNode } from \"react\"\nimport { InfoTooltip } from \"../../../components/ui/info-tooltip\"\nimport { Label } from \"../../../components/ui/label\"\n\n/** Campo rotulado com o ícone de informação ao lado do rótulo e a mensagem de erro pt-BR. */\nexport function InfoField({ id, label, info, error, hint, children, className }: { id: string; label: string; info?: ReactNode; error?: string; hint?: ReactNode; children: ReactNode; className?: string }) {\n return (\n <div className={className ?? \"space-y-1.5\"}>\n <span className=\"flex items-center gap-1.5\">\n <Label htmlFor={id} className=\"text-xs font-semibold\">\n {label}\n </Label>\n {info && <InfoTooltip text={info} label={label} />}\n </span>\n {children}\n {hint && !error && <p className=\"text-xs text-muted-foreground\">{hint}</p>}\n {error && (\n <p role=\"alert\" className=\"text-xs text-destructive\">\n {error}\n </p>\n )}\n </div>\n )\n}\n","\"use client\"\n\nimport { useCallback } from \"react\"\nimport { Loader2 } from \"lucide-react\"\nimport { Button } from \"../../../../components/ui/button\"\nimport { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from \"../../../../components/ui/dialog\"\nimport { FORM_GRID } from \"../../../../components/ui/form-grid\"\nimport { Input } from \"../../../../components/ui/input\"\nimport { Textarea } from \"../../../../components/ui/textarea\"\nimport { createChannelInput, updateChannelInput } from \"../../../../../core/schemas\"\nimport { CHANNEL_HELP } from \"../../../help/identities\"\nimport type { EngramindChannel } from \"../../../types\"\nimport { engramindSend, route, useEngramindMutation } from \"../../../hooks/useEngramind\"\nimport { InfoField } from \"../../shared/InfoField\"\nimport { emptyTo, useSchemaForm } from \"../../shared/useSchemaForm\"\n\ntype Values = { slug: string; name: string; description: string; priority: string }\n\n/** Criar ou editar canal (o slug é imutável). `onCreated`: só na criação, com o slug do canal novo. */\nexport function ChannelDialog({ channel, open, onOpenChange, onCreated }: { channel: EngramindChannel | null; open: boolean; onOpenChange: (open: boolean) => void; onCreated?: (slug: string) => void }) {\n const editing = channel !== null\n const toPayload = useCallback(\n (values: Values) => {\n const priority = values.priority.trim() === \"\" ? undefined : Number(values.priority)\n return editing\n ? { channel: channel.slug, name: values.name.trim(), description: emptyTo(values.description, null), priority }\n : { slug: values.slug.trim(), name: values.name.trim(), description: emptyTo(values.description, undefined), priority }\n },\n [channel, editing],\n )\n const form = useSchemaForm<Values, unknown>(editing ? updateChannelInput : createChannelInput, { slug: channel?.slug ?? \"\", name: channel?.name ?? \"\", description: channel?.description ?? \"\", priority: channel ? String(channel.priority) : \"\" }, toPayload)\n const save = useEngramindMutation(({ channel: slug, ...body }: Record<string, unknown>) => (editing ? engramindSend(\"patch\", route(\"channels\", String(slug)), body) : engramindSend(\"post\", \"channels\", body)), {\n invalidate: [\"channels\"],\n success: editing ? \"Canal atualizado\" : \"Canal criado\",\n })\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"sm:max-w-xl\">\n <DialogHeader>\n <DialogTitle>{editing ? `Editar canal ${channel.slug}` : \"Novo canal\"}</DialogTitle>\n <DialogDescription>Memórias pertencem a canais. Agentes alcançam um canal quando o assinam.</DialogDescription>\n </DialogHeader>\n <div className={FORM_GRID}>\n <InfoField id=\"channel-slug\" label=\"Slug\" info={CHANNEL_HELP.slug} error={form.error(\"slug\")}>\n <Input id=\"channel-slug\" value={form.values.slug} onChange={(event) => form.set(\"slug\", event.target.value)} disabled={editing} placeholder=\"eng/global\" />\n </InfoField>\n <InfoField id=\"channel-name\" label=\"Nome\" error={form.error(\"name\")}>\n <Input id=\"channel-name\" value={form.values.name} onChange={(event) => form.set(\"name\", event.target.value)} placeholder=\"Engenharia global\" />\n </InfoField>\n <InfoField id=\"channel-priority\" label=\"Prioridade\" info={CHANNEL_HELP.priority} error={form.error(\"priority\")}>\n <Input id=\"channel-priority\" type=\"number\" value={form.values.priority} onChange={(event) => form.set(\"priority\", event.target.value)} placeholder=\"0\" />\n </InfoField>\n <InfoField id=\"channel-description\" label=\"Descrição\" error={form.error(\"description\")}>\n <Textarea id=\"channel-description\" rows={2} value={form.values.description} onChange={(event) => form.set(\"description\", event.target.value)} />\n </InfoField>\n </div>\n <DialogFooter>\n <Button type=\"button\" disabled={!form.valid || save.isPending} onClick={() => form.payload && save.mutate(form.payload as Record<string, unknown>, {\n onSuccess: (_data, variables) => {\n onOpenChange(false)\n if (!editing && typeof variables.slug === \"string\") onCreated?.(variables.slug)\n },\n })}>\n {save.isPending && <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" aria-hidden />} {editing ? \"Salvar\" : \"Criar canal\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n","/**\n * Grades de formulário (regra de layout: campos ocupam TODA a largura disponível).\n * Dois campos dividem a linha; o último de uma quantidade ímpar — inclusive quando outro campo\n * some por condição — ocupa a linha inteira, em vez de deixar meia linha vazia. Abaixo de `sm`,\n * um campo por linha.\n */\nconst LAST_ODD_FULL_ROW = \"sm:[&>*:last-child:nth-child(odd)]:col-span-2\"\n\n/** Espaçamento padrão dos formulários (cards e diálogos). */\nexport const FORM_GRID = `grid gap-4 sm:grid-cols-2 ${LAST_ODD_FULL_ROW}`\n\n/** Espaçamento compacto (listas dinâmicas de campos, ex.: variáveis, parâmetros). */\nexport const FORM_GRID_COMPACT = `grid gap-3 sm:grid-cols-2 ${LAST_ODD_FULL_ROW}`\n\n/** Espaçamento amplo (páginas de configuração, ex.: integrações). */\nexport const FORM_GRID_WIDE = `grid gap-5 sm:grid-cols-2 ${LAST_ODD_FULL_ROW}`\n\n/**\n * Três campos curtos dividindo a mesma linha (ex.: SKU | Unidade | Preço). Use só quando a linha\n * tem exatamente 3 campos — com outra quantidade, prefira `FORM_GRID`.\n */\nexport const FORM_GRID_3 = \"grid gap-4 sm:grid-cols-3\"\n","import * as React from \"react\"\n\nimport { cn } from \"../../lib/utils\"\n\nexport interface TextareaProps extends React.ComponentProps<\"textarea\"> {\n /** Compatibilidade com o Opex (modo Vim); ignorado na lib. */\n vim?: boolean\n}\n\nconst Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(({ className, vim: _vim, ...props }, ref) => (\n <textarea\n className={cn(\n \"flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n className,\n )}\n ref={ref}\n {...props}\n />\n))\nTextarea.displayName = \"Textarea\"\n\nexport { Textarea }\n","\"use client\"\n\nimport { useMemo, useState } from \"react\"\nimport type { ZodType } from \"zod\"\n\n/**\n * Formulário pequeno validado pelo MESMO schema Zod da rota e do agente (`operations.ts`), em tempo\n * real: `toPayload` monta o corpo a partir dos campos e o schema dá os erros por campo.\n */\nexport function useSchemaForm<V extends Record<string, unknown>, P>(schema: ZodType<P>, initial: V, toPayload: (values: V) => unknown) {\n const [values, setValues] = useState<V>(initial)\n const [touched, setTouched] = useState(false)\n const parsed = useMemo(() => schema.safeParse(toPayload(values)), [schema, toPayload, values])\n const errors = useMemo(() => {\n const out: Record<string, string> = {}\n if (!parsed.success) for (const issue of parsed.error.issues) out[String(issue.path[0] ?? \"_\")] ??= issue.message\n return out\n }, [parsed])\n const set = <K extends keyof V>(key: K, value: V[K]) => {\n setTouched(true)\n setValues((prev) => ({ ...prev, [key]: value }))\n }\n return {\n values,\n set,\n reset: (next: V) => {\n setValues(next)\n setTouched(false)\n },\n touched,\n valid: parsed.success,\n payload: parsed.success ? parsed.data : null,\n /** Erro do campo (só depois da primeira edição). */\n error: (key: string) => (touched ? errors[key] : undefined),\n }\n}\n\n/** Texto vazio vira `null` (limpa) ou `undefined` (não muda). */\nexport const emptyTo = <T extends null | undefined>(value: string, empty: T): string | T => (value.trim() === \"\" ? empty : value.trim())\n","\"use client\"\n\nimport { useCallback } from \"react\"\nimport { Loader2 } from \"lucide-react\"\nimport { Button } from \"../../../../components/ui/button\"\nimport { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from \"../../../../components/ui/dialog\"\nimport { FORM_GRID } from \"../../../../components/ui/form-grid\"\nimport { Input } from \"../../../../components/ui/input\"\nimport { OptionTabs } from \"../../../../components/ui/option-tabs\"\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"../../../../components/ui/select\"\nimport { subscribeInput } from \"../../../../../core/schemas\"\nimport { SUBSCRIPTION_MODES } from \"../../../constants\"\nimport { CHANNEL_HELP, SUBSCRIPTION_MODE_HELP } from \"../../../help/identities\"\nimport type { EngramindAgent } from \"../../../types\"\nimport { engramindSend, useEngramindMutation } from \"../../../hooks/useEngramind\"\nimport { InfoField } from \"../../shared/InfoField\"\nimport { useSchemaForm } from \"../../shared/useSchemaForm\"\n\ntype Values = { agent: string; target: string; mode: string }\nconst MODE_OPTIONS = SUBSCRIPTION_MODES.map((mode) => ({ value: mode, label: mode }))\n\n/**\n * Novo canal no modo app: o token de app não cria canal direto (`POST /v1/channels` é do gestor), então o\n * canal nasce pela assinatura exata de um agente do app (nome = slug, criado pelo app). Repetir a mesma\n * assinatura devolve a existente.\n */\nexport function ChannelBySubscriptionDialog({ agents, open, onOpenChange, onCreated }: { agents: readonly EngramindAgent[]; open: boolean; onOpenChange: (open: boolean) => void; onCreated?: (slug: string) => void }) {\n const active = agents.filter((agent) => !agent.disabled_at)\n const toPayload = useCallback((values: Values) => ({ agent: values.agent, target: values.target.trim(), mode: values.mode }), [])\n const form = useSchemaForm<Values, unknown>(subscribeInput, { agent: active[0]?.qualified_slug ?? \"\", target: \"\", mode: \"inject\" }, toPayload)\n const save = useEngramindMutation((body: Record<string, unknown>) => engramindSend(\"post\", \"subscriptions\", body), { invalidate: [\"channels\", \"subscriptions\", \"agents\", \"consumer-settings\"], success: \"Canal criado pela assinatura\" })\n const exact = !form.values.target.trim().endsWith(\"*\")\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"sm:max-w-xl\">\n <DialogHeader>\n <DialogTitle>Novo canal</DialogTitle>\n <DialogDescription>O canal nasce quando um agente do app assina o slug exato. Agentes alcançam um canal quando o assinam.</DialogDescription>\n </DialogHeader>\n <div className={FORM_GRID}>\n <InfoField id=\"channel-agent\" label=\"Agente\" error={form.error(\"agent\")}>\n <Select value={form.values.agent} onValueChange={(value) => form.set(\"agent\", value)}>\n <SelectTrigger id=\"channel-agent\" className=\"bg-transparent\">\n <SelectValue placeholder=\"Escolha o agente\" />\n </SelectTrigger>\n <SelectContent>\n {active.map((agent) => (\n <SelectItem key={agent.id} value={agent.qualified_slug}>\n {agent.name} ({agent.qualified_slug})\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </InfoField>\n <InfoField id=\"channel-target\" label=\"Slug do canal\" info={CHANNEL_HELP.slug} error={form.error(\"target\") ?? (exact ? undefined : \"Use o slug exato do canal (sem *)\")}>\n <Input id=\"channel-target\" value={form.values.target} onChange={(event) => form.set(\"target\", event.target.value)} placeholder=\"meu-app/global\" />\n </InfoField>\n <InfoField id=\"channel-mode\" label=\"Modo\" info={SUBSCRIPTION_MODE_HELP[form.values.mode]}>\n <OptionTabs aria-label=\"Modo da assinatura\" options={MODE_OPTIONS} value={form.values.mode} onChange={(value) => form.set(\"mode\", value)} />\n </InfoField>\n </div>\n <DialogFooter>\n <Button\n type=\"button\"\n disabled={!form.valid || !exact || !active.length || save.isPending}\n onClick={() =>\n form.payload &&\n save.mutate(form.payload as Record<string, unknown>, {\n onSuccess: (_data, variables) => {\n onOpenChange(false)\n if (typeof variables.target === \"string\") onCreated?.(variables.target)\n },\n })\n }\n >\n {save.isPending && <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" aria-hidden />} Criar canal\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n","\"use client\"\n\nimport { useRef, type KeyboardEvent, type ReactNode } from \"react\"\nimport { Info } from \"lucide-react\"\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"./tooltip\"\nimport { cn } from \"../../lib/utils\"\n\n/**\n * Seletor segmentado para \"escolher uma opção de uma lista pequena\" (2–4 opções), copiado do\n * seletor CIF/FOB do formulário de item de negociação do Smart Desk (`renderTabSelector`).\n * A cor ativa vem do tema (`primary`), nunca de valores fixos.\n * Acessível como `radiogroup`: setas navegam e selecionam, Home/End vão às pontas.\n */\n\nexport interface OptionTabsOption<T extends string> {\n value: T\n label: string\n /** Texto completo (dica e leitor de tela) quando `label` é abreviado. */\n title?: string\n /** Dica rica (tooltip) explicando quando escolher a opção; mostra um ícone de informação no botão. */\n tooltip?: ReactNode\n disabled?: boolean\n}\n\ninterface OptionTabsProps<T extends string> {\n options: readonly OptionTabsOption<T>[]\n value: T\n onChange: (value: T) => void\n /** Rótulo acessível do grupo (quando não há `<Label>` associado por `aria-labelledby`). */\n \"aria-label\"?: string\n \"aria-labelledby\"?: string\n id?: string\n disabled?: boolean\n size?: \"xs\" | \"sm\" | \"md\"\n className?: string\n}\n\nexport function OptionTabs<T extends string>({\n options,\n value,\n onChange,\n id,\n disabled = false,\n size = \"sm\",\n className,\n ...aria\n}: OptionTabsProps<T>) {\n const refs = useRef<Array<HTMLButtonElement | null>>([])\n const enabled = options.map((option, index) => ({ option, index })).filter(({ option }) => !disabled && !option.disabled)\n\n const select = (index: number) => {\n const option = options[index]\n if (!option || disabled || option.disabled) return\n onChange(option.value)\n refs.current[index]?.focus()\n }\n\n const onKeyDown = (event: KeyboardEvent<HTMLButtonElement>, index: number) => {\n if (enabled.length === 0) return\n const position = enabled.findIndex((item) => item.index === index)\n let target: number | undefined\n if (event.key === \"ArrowRight\" || event.key === \"ArrowDown\") target = enabled[(position + 1) % enabled.length]?.index\n else if (event.key === \"ArrowLeft\" || event.key === \"ArrowUp\") target = enabled[(position - 1 + enabled.length) % enabled.length]?.index\n else if (event.key === \"Home\") target = enabled[0]?.index\n else if (event.key === \"End\") target = enabled[enabled.length - 1]?.index\n if (target === undefined) return\n event.preventDefault()\n select(target)\n }\n\n const selectedIndex = options.findIndex((option) => option.value === value)\n\n return (\n <div\n id={id}\n role=\"radiogroup\"\n aria-label={aria[\"aria-label\"]}\n aria-labelledby={aria[\"aria-labelledby\"]}\n aria-disabled={disabled || undefined}\n className={cn(\"flex gap-1 rounded-lg bg-muted p-1\", disabled && \"opacity-60\", className)}\n >\n {options.map((option, index) => {\n const isActive = option.value === value\n const isDisabled = disabled || option.disabled\n // Roving tabindex: só a opção marcada (ou a primeira) entra na ordem de tabulação.\n const focusable = selectedIndex >= 0 ? isActive : index === 0\n const button = (\n <button\n key={option.value}\n ref={(node) => {\n refs.current[index] = node\n }}\n type=\"button\"\n role=\"radio\"\n aria-checked={isActive}\n disabled={isDisabled}\n tabIndex={focusable ? 0 : -1}\n title={option.title}\n aria-label={option.title}\n onClick={() => select(index)}\n onKeyDown={(event) => onKeyDown(event, index)}\n className={cn(\n \"flex-1 whitespace-nowrap rounded-md font-bold transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed\",\n option.tooltip && \"inline-flex items-center justify-center gap-1.5\",\n size === \"xs\" ? \"px-2 py-1 text-[11px]\" : size === \"sm\" ? \"px-3 py-1.5 text-xs\" : \"px-4 py-2 text-sm\",\n isActive ? \"bg-primary text-primary-foreground shadow-sm\" : \"text-muted-foreground hover:text-foreground\",\n )}\n >\n {option.label}\n {option.tooltip && <Info className=\"h-3.5 w-3.5 shrink-0 opacity-70\" aria-hidden />}\n </button>\n )\n if (!option.tooltip) return button\n return (\n <TooltipProvider key={option.value} delayDuration={200}>\n <Tooltip>\n <TooltipTrigger asChild>{button}</TooltipTrigger>\n <TooltipContent className=\"max-w-xs text-xs\">{option.tooltip}</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )\n })}\n </div>\n )\n}\n","\"use client\"\n\nimport { useState } from \"react\"\nimport Link from \"../../../lib/link\"\nimport { Archive, ExternalLink, Pencil, RotateCcw, Trash2 } from \"lucide-react\"\nimport { Button } from \"../../../components/ui/button\"\nimport { ConfirmDialog } from \"../../../components/ui/confirm-dialog\"\nimport { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from \"../../../components/ui/sheet\"\nimport { useEngramindConfig } from \"../../../lib/config\"\nimport type { EngramindChannel } from \"../../types\"\nimport { engramindSend, route, useEngramindMutation } from \"../../hooks/useEngramind\"\nimport { ChannelDialog } from \"../page/channels/ChannelDialog\"\nimport { SubscribersCard } from \"../page/channels/SubscribersCard\"\nimport { ChannelDisplayName } from \"./ChannelName\"\n\ntype ChannelAction = \"archive\" | \"restore\" | \"delete\"\n\nconst CONFIRM: Record<\"archive\" | \"delete\", { title: (slug: string) => string; description: string; label: string }> = {\n archive: { title: (slug) => `Arquivar o canal ${slug}?`, description: \"Sai do contexto, da busca e das dicas e deixa de receber escrita. Restaurar desfaz.\", label: \"Arquivar\" },\n delete: { title: (slug) => `Excluir de vez o canal ${slug}?`, description: \"Saem junto as memórias (com as revisões) e as assinaturas exatas. Não dá para desfazer.\", label: \"Excluir de vez\" },\n}\n\n/**\n * Painel lateral do canal (menu \"⋯\" ou botão direito no node): Editar (slug imutável), Assinantes,\n * o conteúdo extra do app (`slots.channelDetail`, ex.: as configurações do canal no gestor) e\n * Arquivar / Restaurar / Excluir de vez (só arquivado), com confirmação. No modo app, o Engramind só\n * deixa o token de app arquivar e restaurar os canais que ele criou (`409 CHANNEL_SHARED` nos outros):\n * editar e excluir de vez são do gestor e não aparecem.\n */\nexport function ChannelPanel({ channel, onOpenChange, onDeleted }: { channel: EngramindChannel | null; onOpenChange: (open: boolean) => void; onDeleted?: (slug: string) => void }) {\n const [editing, setEditing] = useState(false)\n const [confirm, setConfirm] = useState<\"archive\" | \"delete\" | null>(null)\n const act = useEngramindMutation(({ action, slug }: { action: ChannelAction; slug: string }) => (action === \"delete\" ? engramindSend(\"delete\", route(\"channels\", slug)) : engramindSend(\"post\", route(\"channels\", slug, action), {})), {\n invalidate: [\"channels\", \"memories\"],\n success: ({ action }) => (action === \"archive\" ? \"Canal arquivado\" : action === \"restore\" ? \"Canal restaurado\" : \"Canal excluído\"),\n })\n const archived = Boolean(channel?.archived_at)\n const { mode, hrefs, slots } = useEngramindConfig()\n const manager = mode === \"manager\"\n const detailHref = channel && hrefs.channel ? hrefs.channel(channel.slug) : null\n return (\n <>\n <Sheet open={channel !== null} onOpenChange={onOpenChange}>\n <SheetContent side=\"right\" className=\"flex w-full flex-col gap-4 overflow-y-auto sm:max-w-2xl\">\n {channel && (\n <>\n <SheetHeader>\n <SheetTitle>{channel.name}</SheetTitle>\n <SheetDescription>\n Canal <ChannelDisplayName slug={channel.slug} />\n {archived ? \" (arquivado)\" : \"\"}\n </SheetDescription>\n </SheetHeader>\n <div className=\"flex flex-wrap gap-2\">\n {manager && (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => setEditing(true)}>\n <Pencil className=\"mr-1.5 h-4 w-4\" aria-hidden /> Editar\n </Button>\n )}\n {archived ? (\n <>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" disabled={act.isPending} onClick={() => act.mutate({ action: \"restore\", slug: channel.slug })}>\n <RotateCcw className=\"mr-1.5 h-4 w-4\" aria-hidden /> Restaurar\n </Button>\n {manager && (\n <Button type=\"button\" variant=\"destructive\" size=\"sm\" onClick={() => setConfirm(\"delete\")}>\n <Trash2 className=\"mr-1.5 h-4 w-4\" aria-hidden /> Excluir de vez\n </Button>\n )}\n </>\n ) : (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => setConfirm(\"archive\")}>\n <Archive className=\"mr-1.5 h-4 w-4\" aria-hidden /> Arquivar\n </Button>\n )}\n {detailHref && (\n <Button asChild variant=\"ghost\" size=\"sm\" className=\"ml-auto\">\n <Link href={detailHref}>\n <ExternalLink className=\"mr-1.5 h-4 w-4\" aria-hidden /> Abrir detalhe\n </Link>\n </Button>\n )}\n </div>\n <SubscribersCard channel={channel.slug} />\n {slots.channelDetail?.(channel.slug)}\n </>\n )}\n </SheetContent>\n </Sheet>\n {editing && channel && <ChannelDialog key={channel.id} channel={channel} open onOpenChange={(open) => !open && setEditing(false)} />}\n <ConfirmDialog\n open={confirm !== null && channel !== null}\n onOpenChange={(open) => !open && setConfirm(null)}\n title={confirm && channel ? CONFIRM[confirm].title(channel.slug) : \"\"}\n description={confirm ? CONFIRM[confirm].description : undefined}\n confirmLabel={confirm ? CONFIRM[confirm].label : \"\"}\n variant=\"destructive\"\n pending={act.isPending}\n onConfirm={() => {\n if (!confirm || !channel) return\n const slug = channel.slug\n act.mutate(\n { action: confirm, slug },\n {\n onSuccess: () => {\n if (confirm === \"delete\") {\n onOpenChange(false)\n onDeleted?.(slug)\n }\n },\n onSettled: () => setConfirm(null),\n },\n )\n }}\n />\n </>\n )\n}\n","\"use client\"\n\nimport type { AnchorHTMLAttributes, ReactNode } from \"react\"\nimport { useEngramindConfig } from \"./config\"\n\nexport interface LinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"href\"> {\n href: string\n children?: ReactNode\n}\n\n/** Link interno: usa o `renderLink` do provider (ex.: `next/link`) ou um `<a>`. */\nexport default function Link({ href, children, ...props }: LinkProps) {\n const { renderLink } = useEngramindConfig()\n if (renderLink) return <>{renderLink({ href, children, ...props })}</>\n return (\n <a href={href} {...props}>\n {children}\n </a>\n )\n}\n","\"use client\"\n\nimport type { ReactNode } from \"react\"\nimport { AnimatePresence, motion } from \"framer-motion\"\nimport { Loader2 } from \"lucide-react\"\nimport {\n AlertDialog,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from \"./alert-dialog\"\nimport { Button } from \"./button\"\nimport { listContainer, listItem } from \"../motion/presets\"\n\ninterface ConfirmDialogProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n title: string\n description?: ReactNode\n /** O que será afetado, listado abaixo da descrição. */\n items?: ReadonlyArray<string>\n confirmLabel: string\n cancelLabel?: string\n /** `destructive` para ações que cancelam, excluem ou descartam. */\n variant?: \"default\" | \"destructive\"\n pending?: boolean\n onConfirm: () => void\n children?: ReactNode\n}\n\n/**\n * Confirmação explícita de ação crítica, composta sobre o `AlertDialog` (copiada do\n * crm-marketing-campanhas): título, descrição, itens afetados, botão principal com carregamento e\n * \"Voltar\". Enquanto `pending`, nada fecha o diálogo.\n */\nexport function ConfirmDialog({ open, onOpenChange, title, description, items, confirmLabel, cancelLabel = \"Voltar\", variant = \"default\", pending = false, onConfirm, children }: ConfirmDialogProps) {\n return (\n <AlertDialog open={open} onOpenChange={(next) => !pending && onOpenChange(next)}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>{title}</AlertDialogTitle>\n {description && <AlertDialogDescription>{description}</AlertDialogDescription>}\n </AlertDialogHeader>\n <AnimatePresence initial={false}>\n {items && items.length > 0 && (\n <motion.ul variants={listContainer} initial=\"hidden\" animate=\"visible\" className=\"max-h-40 space-y-1 overflow-y-auto rounded-lg border bg-muted/40 p-3 text-sm\">\n {items.map((item) => (\n <motion.li key={item} variants={listItem} className=\"text-foreground\">\n {item}\n </motion.li>\n ))}\n </motion.ul>\n )}\n </AnimatePresence>\n {children}\n <AlertDialogFooter>\n <AlertDialogCancel disabled={pending}>{cancelLabel}</AlertDialogCancel>\n <Button variant={variant === \"destructive\" ? \"destructive\" : \"default\"} onClick={onConfirm} disabled={pending}>\n {pending && <Loader2 className=\"animate-spin\" aria-hidden />} {confirmLabel}\n </Button>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n )\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as AlertDialogPrimitive from \"@radix-ui/react-alert-dialog\"\n\nimport { cn } from \"../../lib/utils\"\nimport { buttonVariants } from \"./button\"\nimport { usePortalContainer } from \"./portal-container\"\n\nconst AlertDialog = AlertDialogPrimitive.Root\n\nconst AlertDialogTrigger = AlertDialogPrimitive.Trigger\n\nconst AlertDialogPortal = AlertDialogPrimitive.Portal\n\nconst AlertDialogOverlay = React.forwardRef<\n React.ElementRef<typeof AlertDialogPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Overlay\n className={cn(\n \"fixed inset-0 z-50 bg-background/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n className\n )}\n {...props}\n ref={ref}\n />\n))\nAlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName\n\nconst AlertDialogContent = React.forwardRef<\n React.ElementRef<typeof AlertDialogPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content>\n>(({ className, ...props }, ref) => (\n <AlertDialogPortal container={usePortalContainer()}>\n <AlertDialogOverlay />\n <AlertDialogPrimitive.Content\n ref={ref}\n className={cn(\n \"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg\",\n className\n )}\n {...props}\n />\n </AlertDialogPortal>\n))\nAlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName\n\nconst AlertDialogHeader = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex flex-col space-y-2 text-center sm:text-left\",\n className\n )}\n {...props}\n />\n)\nAlertDialogHeader.displayName = \"AlertDialogHeader\"\n\nconst AlertDialogFooter = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2\",\n className\n )}\n {...props}\n />\n)\nAlertDialogFooter.displayName = \"AlertDialogFooter\"\n\nconst AlertDialogTitle = React.forwardRef<\n React.ElementRef<typeof AlertDialogPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Title\n ref={ref}\n className={cn(\"text-lg font-semibold\", className)}\n {...props}\n />\n))\nAlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName\n\nconst AlertDialogDescription = React.forwardRef<\n React.ElementRef<typeof AlertDialogPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Description\n ref={ref}\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n))\nAlertDialogDescription.displayName =\n AlertDialogPrimitive.Description.displayName\n\nconst AlertDialogAction = React.forwardRef<\n React.ElementRef<typeof AlertDialogPrimitive.Action>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Action>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Action\n ref={ref}\n className={cn(buttonVariants(), className)}\n {...props}\n />\n))\nAlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName\n\nconst AlertDialogCancel = React.forwardRef<\n React.ElementRef<typeof AlertDialogPrimitive.Cancel>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Cancel>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Cancel\n ref={ref}\n className={cn(\n buttonVariants({ variant: \"outline\" }),\n \"mt-2 sm:mt-0\",\n className\n )}\n {...props}\n />\n))\nAlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName\n\nexport {\n AlertDialog,\n AlertDialogPortal,\n AlertDialogOverlay,\n AlertDialogTrigger,\n AlertDialogContent,\n AlertDialogHeader,\n AlertDialogFooter,\n AlertDialogTitle,\n AlertDialogDescription,\n AlertDialogAction,\n AlertDialogCancel,\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as SheetPrimitive from \"@radix-ui/react-dialog\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { X } from \"lucide-react\"\n\nimport { cn } from \"../../lib/utils\"\nimport { usePortalContainer } from \"./portal-container\"\n\nconst Sheet = SheetPrimitive.Root\n\nconst SheetTrigger = SheetPrimitive.Trigger\n\nconst SheetClose = SheetPrimitive.Close\n\nconst SheetPortal = SheetPrimitive.Portal\n\nconst SheetOverlay = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <SheetPrimitive.Overlay\n className={cn(\n \"fixed inset-0 z-50 bg-background/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n className\n )}\n {...props}\n ref={ref}\n />\n))\nSheetOverlay.displayName = SheetPrimitive.Overlay.displayName\n\nconst sheetVariants = cva(\n \"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500 data-[state=open]:animate-in data-[state=closed]:animate-out\",\n {\n variants: {\n side: {\n top: \"inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top\",\n bottom:\n \"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom\",\n left: \"inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm\",\n right:\n \"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm\",\n },\n },\n defaultVariants: {\n side: \"right\",\n },\n }\n)\n\ninterface SheetContentProps\n extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,\n VariantProps<typeof sheetVariants> {}\n\nconst SheetContent = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Content>,\n SheetContentProps\n>(({ side = \"right\", className, children, ...props }, ref) => (\n <SheetPortal container={usePortalContainer()}>\n <SheetOverlay />\n <SheetPrimitive.Content\n ref={ref}\n className={cn(sheetVariants({ side }), className)}\n {...props}\n >\n <SheetPrimitive.Close className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary\">\n <X className=\"h-4 w-4\" />\n <span className=\"sr-only\">Close</span>\n </SheetPrimitive.Close>\n {children}\n </SheetPrimitive.Content>\n </SheetPortal>\n))\nSheetContent.displayName = SheetPrimitive.Content.displayName\n\nconst SheetHeader = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex flex-col space-y-2 text-center sm:text-left\",\n className\n )}\n {...props}\n />\n)\nSheetHeader.displayName = \"SheetHeader\"\n\nconst SheetFooter = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2\",\n className\n )}\n {...props}\n />\n)\nSheetFooter.displayName = \"SheetFooter\"\n\nconst SheetTitle = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <SheetPrimitive.Title\n ref={ref}\n className={cn(\"text-lg font-semibold text-foreground\", className)}\n {...props}\n />\n))\nSheetTitle.displayName = SheetPrimitive.Title.displayName\n\nconst SheetDescription = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <SheetPrimitive.Description\n ref={ref}\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n))\nSheetDescription.displayName = SheetPrimitive.Description.displayName\n\nexport {\n Sheet,\n SheetPortal,\n SheetOverlay,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n}\n","\"use client\"\n\nimport { useState } from \"react\"\nimport { Pencil, Plus, Trash2, Users } from \"lucide-react\"\nimport { Button } from \"../../../../components/ui/button\"\nimport { ConfirmDialog } from \"../../../../components/ui/confirm-dialog\"\nimport { TooltipIconButton } from \"../../../../components/ui/tooltip-icon-button\"\nimport { EmptyState } from \"../../../../components/feedback/EmptyState\"\nimport { IDENTITY_HELP, SCOPE_HELP, SUBSCRIPTION_MODE_HELP } from \"../../../help/identities\"\nimport type { EngramindAgent, EngramindSubscription } from \"../../../types\"\nimport { engramindSend, route, useEngramindList, useEngramindMutation } from \"../../../hooks/useEngramind\"\nimport { HelpBadge } from \"../../shared/Badges\"\nimport { QueryBoundary } from \"../../shared/QueryBoundary\"\nimport { ListSkeleton } from \"../../shared/ListSkeleton\"\nimport { Section } from \"../../shared/Section\"\nimport { SubscriptionDialog } from \"./SubscriptionDialog\"\n\n/** Assinantes do canal: listar, assinar um agente, editar e remover. */\nexport function SubscribersCard({ channel }: { channel: string }) {\n const subscriptions = useEngramindList<EngramindSubscription>(\"subscriptions\", \"subscriptions\", { channel }, { all: true })\n const agents = useEngramindList<EngramindAgent>(\"agents\", \"agents\", undefined, { all: true })\n const [editing, setEditing] = useState<EngramindSubscription | null | \"new\">(null)\n const [removing, setRemoving] = useState<EngramindSubscription | null>(null)\n const remove = useEngramindMutation((id: string) => engramindSend(\"delete\", route(\"subscriptions\", id)), { invalidate: [\"subscriptions\", \"agents\"], success: \"Assinatura removida\" })\n return (\n <Section\n title=\"Assinantes\"\n info=\"Agentes que alcançam este canal por assinatura exata ou por prefixo. A mais específica vence (exata > prefixo mais longo).\"\n actions={\n <Button type=\"button\" size=\"sm\" onClick={() => setEditing(\"new\")} disabled={agents.items.length === 0}>\n <Plus className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden /> Assinar agente\n </Button>\n }\n >\n <QueryBoundary isLoading={subscriptions.isLoading} error={subscriptions.error} onRetry={() => void subscriptions.refetch()} skeleton={<ListSkeleton rows={3} rowClassName=\"h-12\" />}>\n {subscriptions.items.length === 0 ? (\n <EmptyState icon={Users} title=\"Nenhum assinante\" description=\"Sem assinatura, só tokens admin alcançam o canal.\" actionLabel={agents.items.length ? \"Assinar agente\" : undefined} onAction={() => setEditing(\"new\")} />\n ) : (\n <ul className=\"divide-y rounded-lg border\">\n {subscriptions.items.map((subscription) => (\n <li key={subscription.id} className=\"flex flex-wrap items-center gap-2 p-3 text-sm\">\n <div className=\"min-w-0 flex-1 space-y-1\">\n <p className=\"flex flex-wrap items-center gap-1.5\">\n <span className=\"font-medium\">{subscription.agent.qualified_slug ?? subscription.agent.slug}</span>\n <HelpBadge value={subscription.is_prefix ? `prefixo ${subscription.target}` : \"exata\"} help={IDENTITY_HELP.target} />\n <HelpBadge value={subscription.mode} help={SUBSCRIPTION_MODE_HELP[subscription.mode]} />\n {(subscription.access ?? [\"escopos do token\"]).map((scope) => (\n <HelpBadge key={scope} value={scope} help={SCOPE_HELP[scope] ?? IDENTITY_HELP.access} />\n ))}\n {subscription.priority != null && <HelpBadge value={`prioridade ${subscription.priority}`} help={IDENTITY_HELP.subscriptionPriority} />}\n </p>\n {subscription.is_prefix && <p className=\"text-xs text-muted-foreground\">Alcança: {subscription.reaches.join(\", \") || \"nenhum canal ativo\"}</p>}\n </div>\n <TooltipIconButton label=\"Editar assinatura\" onClick={() => setEditing(subscription)}>\n <Pencil aria-hidden />\n </TooltipIconButton>\n <TooltipIconButton label=\"Remover assinatura\" onClick={() => setRemoving(subscription)}>\n <Trash2 aria-hidden />\n </TooltipIconButton>\n </li>\n ))}\n </ul>\n )}\n </QueryBoundary>\n {editing !== null && <SubscriptionDialog key={editing === \"new\" ? \"new\" : editing.id} channel={channel} subscription={editing === \"new\" ? null : editing} agents={agents.items} open onOpenChange={(open) => !open && setEditing(null)} />}\n <ConfirmDialog\n open={removing !== null}\n onOpenChange={(open) => !open && setRemoving(null)}\n title=\"Remover a assinatura?\"\n description={`${removing?.agent.qualified_slug ?? removing?.agent.slug ?? \"\"} deixa de alcançar ${removing?.target ?? \"\"}. As memórias continuam no canal.`}\n confirmLabel=\"Remover\"\n variant=\"destructive\"\n pending={remove.isPending}\n onConfirm={() => removing && remove.mutate(removing.id, { onSettled: () => setRemoving(null) })}\n />\n </Section>\n )\n}\n","\"use client\"\n\nimport type { ButtonHTMLAttributes, ReactNode } from \"react\"\nimport Link from \"../../lib/link\"\nimport { Button } from \"./button\"\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"./tooltip\"\nimport { cn } from \"../../lib/utils\"\n\ninterface TooltipIconButtonProps {\n /** Nome acessível (e texto da dica quando `tooltip` não é informado). */\n label: string\n /** Conteúdo da dica; padrão: `label`. */\n tooltip?: ReactNode\n /** Bloqueia a ação e mostra o motivo na dica (continua focável). */\n disabledReason?: string | null\n /** Vira link: interno (`next/link`) ou, com `external`, nova aba. */\n href?: string\n external?: boolean\n onClick?: () => void\n className?: string\n /** Atributos extras do `<button>` (ex.: `aria-haspopup`/`aria-expanded` quando o botão abre um popover). */\n buttonProps?: ButtonHTMLAttributes<HTMLButtonElement>\n /** Ícone (e extras, como o número da issue). */\n children: ReactNode\n}\n\n/**\n * Botão de ícone com contorno e dica (cabeçalhos das páginas de tarefa). Bloqueado usa `aria-disabled`\n * em vez de `disabled` para continuar recebendo foco/hover e a dica explicar o motivo.\n */\nexport function TooltipIconButton({ label, tooltip, disabledReason, href, external, onClick, className, buttonProps, children }: TooltipIconButtonProps) {\n const blocked = Boolean(disabledReason)\n const classes = cn(\"h-9 min-w-9 px-2.5 [&_svg]:size-4\", blocked && \"cursor-not-allowed opacity-50\", className)\n\n const trigger =\n href && !blocked ? (\n <Button asChild variant=\"outline\" className={classes}>\n {external ? (\n <a href={href} target=\"_blank\" rel=\"noreferrer noopener\" aria-label={label}>\n {children}\n </a>\n ) : (\n <Link href={href} aria-label={label}>\n {children}\n </Link>\n )}\n </Button>\n ) : (\n <Button type=\"button\" variant=\"outline\" className={classes} aria-label={label} aria-disabled={blocked || undefined} onClick={() => !blocked && onClick?.()} {...buttonProps}>\n {children}\n </Button>\n )\n\n return (\n <TooltipProvider delayDuration={200}>\n <Tooltip>\n <TooltipTrigger asChild>{trigger}</TooltipTrigger>\n <TooltipContent className=\"max-w-xs text-xs\">{disabledReason ?? tooltip ?? label}</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )\n}\n","import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"../../lib/utils\"\n\nconst badgeVariants = cva(\"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2\", {\n variants: {\n variant: {\n default: \"border-transparent bg-primary text-primary-foreground\",\n secondary: \"border-transparent bg-secondary text-secondary-foreground\",\n destructive: \"border-transparent bg-destructive text-destructive-foreground\",\n outline: \"text-foreground\",\n success: \"border-transparent bg-[var(--color-success,var(--color-primary))] text-[var(--color-success-foreground,var(--color-primary-foreground))]\",\n warning: \"border-transparent bg-[var(--color-warning,var(--color-accent))] text-[var(--color-warning-foreground,var(--color-accent-foreground))]\",\n info: \"border-transparent bg-primary text-primary-foreground\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n})\n\nexport interface BadgeProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof badgeVariants> {}\n\nfunction Badge({ className, variant, ...props }: BadgeProps) {\n return (\n <div className={cn(badgeVariants({ variant }), className)} {...props} />\n )\n}\n\nexport { Badge, badgeVariants }\n","\"use client\"\n\nimport { Badge } from \"../../../components/ui/badge\"\nimport { InfoTooltip } from \"../../../components/ui/info-tooltip\"\nimport { cn } from \"../../../lib/utils\"\n\n/** Selo com tooltip (status, modo, tipo, escopo...). */\nexport function HelpBadge({ value, help, tone = \"outline\", className }: { value: string; help?: string; tone?: \"outline\" | \"success\" | \"warning\" | \"destructive\" | \"secondary\"; className?: string }) {\n return (\n <span className=\"inline-flex items-center gap-1\">\n <Badge variant={tone} className={cn(\"font-mono text-[10px] font-normal\", className)}>\n {value}\n </Badge>\n {help && <InfoTooltip text={help} label={value} />}\n </span>\n )\n}\n\nconst TONES: Record<string, \"success\" | \"warning\" | \"destructive\" | \"secondary\" | \"outline\"> = {\n active: \"success\",\n ok: \"success\",\n ready: \"success\",\n done: \"success\",\n delivered: \"success\",\n success: \"success\",\n permanent: \"secondary\",\n queued: \"secondary\",\n running: \"warning\",\n reindexing: \"warning\",\n downloading: \"warning\",\n loading: \"warning\",\n idle: \"outline\",\n pending: \"warning\",\n skip: \"outline\",\n off: \"outline\",\n expired: \"warning\",\n archived: \"outline\",\n revoked: \"destructive\",\n failed: \"destructive\",\n fail: \"destructive\",\n}\n\nexport const toneOf = (value: string | null | undefined) => (value ? (TONES[value] ?? \"outline\") : \"outline\")\n","import { cn } from \"../../lib/utils\"\n\nfunction Skeleton({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n return <div className={cn(\"animate-pulse rounded-md bg-muted\", className)} {...props} />\n}\n\nexport { Skeleton }\n","import { Skeleton } from \"../../../components/ui/skeleton\"\n\n/** Skeleton das listas do Engramind (linhas com borda, na altura das linhas reais). */\nexport function ListSkeleton({ rows = 4, rowClassName = \"h-14\" }: { rows?: number; rowClassName?: string }) {\n return (\n <div className=\"space-y-2 rounded-lg border p-2\" aria-busy=\"true\" data-testid=\"list-skeleton\">\n {Array.from({ length: rows }, (_, index) => (\n <Skeleton key={index} className={`${rowClassName} w-full`} />\n ))}\n </div>\n )\n}\n","\"use client\"\n\nimport type { ReactNode } from \"react\"\nimport { motion } from \"framer-motion\"\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from \"../../../components/ui/card\"\nimport { InfoTooltip } from \"../../../components/ui/info-tooltip\"\nimport { cn } from \"../../../lib/utils\"\n\ninterface SectionProps {\n title: string\n info?: ReactNode\n description?: ReactNode\n actions?: ReactNode\n children: ReactNode\n className?: string\n contentClassName?: string\n}\n\nconst cardMotion = { initial: { opacity: 0, y: 12 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.3, ease: \"easeOut\" } } as const\n\n/** Card de uma seção das telas do Engramind: título com tooltip, descrição e ações à direita. */\nexport function Section({ title, info, description, actions, children, className, contentClassName }: SectionProps) {\n return (\n <motion.div {...cardMotion} className={className}>\n <Card>\n <CardHeader className=\"flex flex-row flex-wrap items-start gap-3 space-y-0\">\n <div className=\"min-w-0 flex-1 space-y-1\">\n <CardTitle className=\"flex items-center gap-1.5 text-base\">\n {title}\n {info && <InfoTooltip text={info} label={title} />}\n </CardTitle>\n {description && <CardDescription>{description}</CardDescription>}\n </div>\n {actions && <div className=\"ml-auto flex flex-wrap items-center gap-2\">{actions}</div>}\n </CardHeader>\n <CardContent className={cn(\"space-y-4\", contentClassName)}>{children}</CardContent>\n </Card>\n </motion.div>\n )\n}\n","import * as React from \"react\"\n\nimport { cn } from \"../../lib/utils\"\n\nconst Card = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n \"rounded-xl border bg-card text-card-foreground shadow\",\n className\n )}\n {...props}\n />\n))\nCard.displayName = \"Card\"\n\nconst CardHeader = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"flex flex-col space-y-1.5 p-6\", className)}\n {...props}\n />\n))\nCardHeader.displayName = \"CardHeader\"\n\nconst CardTitle = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"font-semibold leading-none tracking-tight\", className)}\n {...props}\n />\n))\nCardTitle.displayName = \"CardTitle\"\n\nconst CardDescription = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n))\nCardDescription.displayName = \"CardDescription\"\n\nconst CardContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div ref={ref} className={cn(\"p-6 pt-0\", className)} {...props} />\n))\nCardContent.displayName = \"CardContent\"\n\nconst CardFooter = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"flex items-center p-6 pt-0\", className)}\n {...props}\n />\n))\nCardFooter.displayName = \"CardFooter\"\n\nexport { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }\n","\"use client\"\n\nimport { useCallback } from \"react\"\nimport { Loader2 } from \"lucide-react\"\nimport { Button } from \"../../../../components/ui/button\"\nimport { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from \"../../../../components/ui/dialog\"\nimport { FORM_GRID } from \"../../../../components/ui/form-grid\"\nimport { Input } from \"../../../../components/ui/input\"\nimport { OptionTabs } from \"../../../../components/ui/option-tabs\"\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"../../../../components/ui/select\"\nimport { combinationOf, scopesOfCombination, SUBSCRIPTION_MODES, type ScopeCombination } from \"../../../constants\"\nimport { subscribeInput, updateSubscriptionInput } from \"../../../../../core/schemas\"\nimport { IDENTITY_HELP, SUBSCRIPTION_MODE_HELP } from \"../../../help/identities\"\nimport type { EngramindAgent, EngramindSubscription } from \"../../../types\"\nimport { engramindSend, route, useEngramindMutation } from \"../../../hooks/useEngramind\"\nimport { InfoField } from \"../../shared/InfoField\"\nimport { ScopePicker } from \"../../shared/ScopePicker\"\nimport { useSchemaForm } from \"../../shared/useSchemaForm\"\n\ntype Mode = (typeof SUBSCRIPTION_MODES)[number]\ntype Values = { agent: string; target: string; mode: Mode; access: ScopeCombination | \"token\"; priority: string }\nconst TOKEN_ACCESS = \"token\"\n\n/** Assinar um agente (canal exato ou prefixo) ou editar modo, acesso e prioridade de uma assinatura. */\nexport function SubscriptionDialog({ channel, subscription, agents, open, onOpenChange }: { channel: string; subscription: EngramindSubscription | null; agents: EngramindAgent[]; open: boolean; onOpenChange: (open: boolean) => void }) {\n const editing = subscription !== null\n const toPayload = useCallback(\n (values: Values) => {\n const access = values.access === TOKEN_ACCESS ? null : scopesOfCombination(values.access)\n const priority = values.priority.trim() === \"\" ? null : Number(values.priority)\n return editing ? { subscription: subscription.id, mode: values.mode, access, priority } : { agent: values.agent, target: values.target.trim(), mode: values.mode, access, priority }\n },\n [editing, subscription],\n )\n const form = useSchemaForm<Values, unknown>(\n editing ? updateSubscriptionInput : subscribeInput,\n {\n agent: agents[0]?.qualified_slug ?? \"\",\n target: subscription?.target ?? channel,\n mode: subscription?.mode ?? \"inject\",\n access: subscription?.access ? (combinationOf(subscription.access) ?? TOKEN_ACCESS) : TOKEN_ACCESS,\n priority: subscription?.priority != null ? String(subscription.priority) : \"\",\n },\n toPayload,\n )\n const save = useEngramindMutation(({ subscription: id, ...body }: Record<string, unknown>) => (editing ? engramindSend(\"patch\", route(\"subscriptions\", String(id)), body) : engramindSend(\"post\", \"subscriptions\", body)), {\n invalidate: [\"subscriptions\", \"agents\", \"channels\", \"consumer-settings\"],\n success: editing ? \"Assinatura atualizada\" : \"Agente assinado\",\n })\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"sm:max-w-xl\">\n <DialogHeader>\n <DialogTitle>{editing ? `Editar assinatura de ${subscription.agent.qualified_slug ?? subscription.agent.slug}` : \"Assinar agente\"}</DialogTitle>\n <DialogDescription>Acesso efetivo = escopos do token ∩ acesso da assinatura (nunca amplia).</DialogDescription>\n </DialogHeader>\n <div className={FORM_GRID}>\n <InfoField id=\"sub-agent\" label=\"Agente\" info={IDENTITY_HELP.agent} error={form.error(\"agent\")}>\n <Select value={form.values.agent} onValueChange={(value) => form.set(\"agent\", value)} disabled={editing}>\n <SelectTrigger id=\"sub-agent\" className=\"bg-transparent\">\n <SelectValue placeholder=\"Escolha o agente\" />\n </SelectTrigger>\n <SelectContent>\n {agents.map((agent) => (\n <SelectItem key={agent.id} value={agent.qualified_slug}>\n {agent.qualified_slug}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </InfoField>\n <InfoField id=\"sub-target\" label=\"Alvo\" info={IDENTITY_HELP.target} error={form.error(\"target\")}>\n <Input id=\"sub-target\" value={form.values.target} onChange={(event) => form.set(\"target\", event.target.value)} disabled={editing} placeholder={`${channel} ou eng/*`} />\n </InfoField>\n <InfoField id=\"sub-mode\" label=\"Modo\" info=\"Como o canal entra para o agente.\" className=\"space-y-1.5 sm:col-span-2\">\n <OptionTabs id=\"sub-mode\" aria-label=\"Modo\" options={SUBSCRIPTION_MODES.map((mode) => ({ value: mode, label: mode, tooltip: SUBSCRIPTION_MODE_HELP[mode] }))} value={form.values.mode} onChange={(mode) => form.set(\"mode\", mode)} />\n </InfoField>\n <InfoField id=\"sub-access\" label=\"Acesso\" info={IDENTITY_HELP.access} error={form.error(\"access\")} className=\"space-y-1.5 sm:col-span-2\">\n <div className=\"space-y-2\">\n <OptionTabs id=\"sub-access-kind\" aria-label=\"Origem do acesso\" size=\"sm\" options={[{ value: \"token\", label: \"Escopos do token\", tooltip: \"Sem restrição além dos escopos do token\" }, { value: \"custom\", label: \"Restringir\", tooltip: IDENTITY_HELP.access }]} value={form.values.access === TOKEN_ACCESS ? \"token\" : \"custom\"} onChange={(kind) => form.set(\"access\", kind === \"token\" ? TOKEN_ACCESS : \"read\")} />\n {form.values.access !== TOKEN_ACCESS && <ScopePicker id=\"sub-access\" value={form.values.access} onChange={(access) => form.set(\"access\", access)} />}\n </div>\n </InfoField>\n <InfoField id=\"sub-priority\" label=\"Prioridade (opcional)\" info={IDENTITY_HELP.subscriptionPriority} error={form.error(\"priority\")}>\n <Input id=\"sub-priority\" type=\"number\" value={form.values.priority} onChange={(event) => form.set(\"priority\", event.target.value)} placeholder=\"A do canal\" />\n </InfoField>\n </div>\n <DialogFooter>\n <Button type=\"button\" disabled={!form.valid || save.isPending} onClick={() => form.payload && save.mutate(form.payload as Record<string, unknown>, { onSuccess: () => onOpenChange(false) })}>\n {save.isPending && <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" aria-hidden />} {editing ? \"Salvar\" : \"Assinar\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n","\"use client\"\n\nimport { OptionTabs } from \"../../../components/ui/option-tabs\"\nimport { SCOPE_COMBINATIONS, type ScopeCombination } from \"../../constants\"\nimport { SCOPE_COMBINATION_HELP, SCOPE_HELP } from \"../../help/identities\"\n\nconst describe = (combination: ScopeCombination) =>\n `${SCOPE_COMBINATION_HELP[combination]} ${combination\n .split(\"+\")\n .map((scope) => `${scope}: ${SCOPE_HELP[scope]}`)\n .join(\" \")}`\n\n/** Escopos (só as combinações aceitas pelo Engramind), cada uma com tooltip. */\nexport function ScopePicker({ id, value, onChange, allowed, disabled }: { id: string; value: ScopeCombination; onChange: (next: ScopeCombination) => void; allowed?: readonly ScopeCombination[]; disabled?: boolean }) {\n return (\n <OptionTabs\n id={id}\n aria-label=\"Escopos\"\n size=\"sm\"\n options={SCOPE_COMBINATIONS.map((combination) => ({ value: combination, label: combination, tooltip: describe(combination), disabled: allowed ? !allowed.includes(combination) : false }))}\n value={value}\n onChange={onChange}\n disabled={disabled}\n />\n )\n}\n","\"use client\"\n\nimport { createContext, useContext, useMemo } from \"react\"\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../../../components/ui/tooltip\"\nimport { useEngramindConfig } from \"../../../lib/config\"\nimport { cn } from \"../../../lib/utils\"\nimport { channelDisplayHint, channelDisplayName, channelNameParts, type ChannelLabel } from \"../../network/channel-labels\"\n\nconst ChannelLabelsContext = createContext<ReadonlyMap<string, ChannelLabel>>(new Map())\n\n/**\n * Rótulos legíveis dos canais (título no lugar da ponta do slug e a dica): os de `value` ou os do\n * `channelLabels` do provider (o app calcula os dele, ex.: a sigla de um repositório).\n */\nexport function ChannelLabelsProvider({ value, children }: { value?: ReadonlyMap<string, ChannelLabel>; children: React.ReactNode }) {\n const { channelLabels } = useEngramindConfig()\n const labels = useMemo(() => value ?? channelLabels, [value, channelLabels])\n return <ChannelLabelsContext.Provider value={labels}>{children}</ChannelLabelsContext.Provider>\n}\n\n/** Rótulos dos canais de central (fora do `ChannelLabelsProvider`, um mapa vazio: o slug como está). */\nexport function useChannelLabels(): ReadonlyMap<string, ChannelLabel> {\n return useContext(ChannelLabelsContext)\n}\n\n/** Nome legível de um canal numa linha (`channelDisplayName`), com o slug e o repositório na dica. */\nexport function ChannelDisplayName({ slug, className }: { slug: string; className?: string }) {\n const labels = useChannelLabels()\n return (\n <span className={cn(\"truncate\", className)} title={channelDisplayHint(slug, labels)} data-channel-slug={slug}>\n {channelDisplayName(slug, labels)}\n </span>\n )\n}\n\nconst SIZES = {\n node: { prefix: \"text-[10px]\", title: \"text-sm\" },\n center: { prefix: \"text-[10px]\", title: \"text-sm\" },\n legend: { prefix: \"text-[9px]\", title: \"text-xs\" },\n} as const\n\n/**\n * Nome do canal em duas linhas: o prefixo até a última `/` discreto em cima e a ponta final como\n * título destacado (canal de central: a sigla do repositório, com o nome na dica). O slug inteiro\n * aparece ao passar o mouse.\n */\nexport function ChannelName({ slug, size = \"node\", className, titleClassName }: { slug: string; size?: keyof typeof SIZES; className?: string; titleClassName?: string }) {\n const labels = useContext(ChannelLabelsContext)\n const { prefix, title, hint } = channelNameParts(slug, labels)\n const sizes = SIZES[size]\n const titleText = (\n <span data-testid=\"channel-name-title\" data-hint={hint ?? undefined} className={cn(\"truncate font-medium text-foreground\", sizes.title, titleClassName)}>\n {title}\n </span>\n )\n return (\n <span data-testid={`channel-name-${slug}`} title={hint ? undefined : slug} className={cn(\"flex min-w-0 flex-col leading-tight\", className)}>\n {prefix && (\n <span data-testid=\"channel-name-prefix\" className={cn(\"truncate text-muted-foreground/70\", sizes.prefix)}>\n {prefix}\n </span>\n )}\n {hint ? (\n <TooltipProvider delayDuration={200}>\n <Tooltip>\n <TooltipTrigger asChild>{titleText}</TooltipTrigger>\n <TooltipContent className=\"text-xs\">\n <span className=\"block font-medium\">{hint}</span>\n <span className=\"block text-muted-foreground\">{slug}</span>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n ) : (\n titleText\n )}\n </span>\n )\n}\n","import { splitChannelSlug } from \"./network-math\"\n\n/** Título e dica de um canal quando a ponta do slug não é legível (ex.: id da central). */\nexport interface ChannelLabel {\n /** Texto destacado no lugar da ponta final do slug (ex.: a sigla `OPE`). */\n title: string\n /** Dica ao passar o mouse no título (ex.: o nome do repositório). */\n hint: string\n}\n\n/** Partes exibidas do nome de um canal: prefixo discreto, título e a dica (quando houver rótulo). */\nexport function channelNameParts(slug: string, labels?: ReadonlyMap<string, ChannelLabel>): { prefix: string; title: string; hint: string | null } {\n const { prefix, leaf } = splitChannelSlug(slug)\n const label = labels?.get(slug)\n return { prefix, title: label?.title ?? leaf, hint: label?.hint ?? null }\n}\n\n/**\n * Slug do canal para exibir numa linha (chips, legendas, trilha, opções de filtro): canal de central com\n * a ponta trocada pela sigla (`agentes/desenvolvedor/central/OPE`); sem rótulo, o slug como está.\n * Helper único (OPE-113): todo lugar que mostra um canal usa este.\n */\nexport function channelDisplayName(slug: string, labels?: ReadonlyMap<string, ChannelLabel>): string {\n const label = labels?.get(slug)\n if (!label) return slug\n const { prefix } = splitChannelSlug(slug)\n return `${prefix}${label.title}`\n}\n\n/** Dica do canal exibido: nome do repositório e o slug inteiro (quando há rótulo); senão o slug. */\nexport function channelDisplayHint(slug: string, labels?: ReadonlyMap<string, ChannelLabel>): string {\n const label = labels?.get(slug)\n return label ? `${label.hint} · ${slug}` : slug\n}\n","\"use client\"\n\nimport { createContext, useContext } from \"react\"\n\nconst AgentLabelsContext = createContext<ReadonlyMap<string, string>>(new Map())\n\n/** Nome de exibição dos agentes por `app/agente` (sem o prefixo \"Agente\"), para o chip do autor no card. */\nexport const AgentLabelsProvider = AgentLabelsContext.Provider\n\n/** Nome do agente pelo `app/agente`; fora do provider ou agente desconhecido, o próprio `app/agente`. */\nexport function useAgentLabel(qualified: string): string {\n return useContext(AgentLabelsContext).get(qualified) ?? qualified\n}\n","\"use client\"\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\nimport type { Edge, Node } from \"@xyflow/react\"\nimport { Hash, type LucideIcon } from \"lucide-react\"\nimport { toast } from \"../../../lib/toast\"\nimport { agentWritesOf, isAuthoredByCenter, layoutUniverse, universeChannelColors } from \"../../network/network-math\"\nimport { buildParticles } from \"../../network/particles\"\nimport type { ConsumptionEvent, NetworkMemory } from \"../../network/types\"\nimport { useEngramindConsumption, useLiveEffects } from \"../../hooks/useEngramindConsumption\"\nimport { ActiveMemoryCard } from \"./ActiveMemoryCard\"\nimport { useAgentIcon } from \"./agent-icons\"\nimport { NetworkLiveProvider } from \"./live\"\nimport type { MemoryCardActions } from \"./MemoryCard\"\nimport { MemoryNode, UniverseFocusContext, type MemoryNodeData } from \"./MemoryNode\"\nimport { NetworkCanvas } from \"./NetworkCanvas\"\nimport { CenterNode, type CenterNodeData } from \"./nodes\"\nimport { RecenterButton } from \"./RecenterButton\"\nimport { UniversePanels } from \"./UniversePanels\"\nimport { UniverseStatsCard } from \"./UniverseStatsCard\"\nimport { useEnteringIds } from \"./useEnteringIds\"\nimport { useLeavingItems } from \"./useLeavingItems\"\nimport { useStable } from \"./useStableNodes\"\nimport type { LocalRemovals } from \"./useLocalRemovals\"\n\nconst NODE_TYPES = { center: CenterNode, memory: MemoryNode }\nconst CENTER_ID = \"center\"\n/** Atraso entre o nascimento da memória criada pelo agente do centro e a partícula verde. */\nconst AUTHORED_TRAVEL_DELAY_MS = 300\n\nexport interface UniverseCenter {\n kind: \"channel\" | \"agent\"\n /** Slug do canal ou `app/agente`. */\n id: string\n label: string\n archived?: boolean\n}\n\nexport interface MemoryUniverseProps {\n center: UniverseCenter\n memories: NetworkMemory[]\n staleAfterDays: number\n /** Cor estável de cada canal (universo do agente); o universo marca o maior canal com o roxo primário. */\n channelColors?: Map<string, string>\n /** Destaque da busca/filtros (`null` = sem filtro). */\n isMatch?: ((memory: NetworkMemory) => boolean) | null\n actions: MemoryCardActions\n /** Assinantes do canal (universo do canal). */\n subscribers?: number\n /** Releitura dos dados: zera o crescimento local do consumo ao vivo. */\n dataVersion?: number\n onCreate?: (() => void) | null\n /** Botão de criar no canto (universo com memórias); vazio mostra a ação no estado vazio. */\n createLabel?: string\n emptyTitle?: string\n className?: string\n /** Memória provisória da lista otimista (`pendente-…`): a definitiva que a substitui não nasce de novo. */\n isProvisional?: (id: string) => boolean\n /** Remoções confirmadas nesta tela (sem o aviso de \"outra origem\" quando a memória aberta sai). */\n localRemovals?: LocalRemovals\n}\n\n/**\n * Universo de um canal ou de um agente (OPE-109): o node central e uma partícula por memória, em\n * órbitas (mais novas mais perto), com a cor do canal (o com mais memórias no roxo primário), tamanho pelo\n * uso e brilho pelo último uso. Clique ou toque abre o card (passar o mouse só afasta as vizinhas); o\n * consumo ao vivo pulsa a memória e manda uma partícula ao centro. No universo do agente, o link tem a\n * cor do canal e é destacado nas memórias que ele escreveu (OPE-113).\n */\nexport function MemoryUniverse({\n center,\n memories,\n staleAfterDays,\n channelColors,\n isMatch = null,\n actions,\n subscribers,\n dataVersion,\n onCreate,\n createLabel,\n emptyTitle = \"Nenhuma memória neste universo\",\n className,\n isProvisional,\n localRemovals,\n}: MemoryUniverseProps) {\n const live = useLiveEffects(dataVersion)\n // O card abre só por clique/toque (`opened`); o cursor (`hovered`) só afasta as vizinhas.\n const [hovered, setHovered] = useState<string | null>(null)\n const [opened, setOpened] = useState<string | null>(null)\n const ids = useMemo(() => new Set(memories.map((memory) => memory.id)), [memories])\n const openRef = useRef<(string | null)[]>([])\n const items = useLeavingItems(memories, (removed) => {\n // Memória aberta que sumiu por outra origem (excluída ou movida): o card fecha com aviso.\n if (removed.some((id) => openRef.current.includes(id) && !localRemovals?.has(id))) toast.info(\"A memória aberta foi excluída ou movida por outra origem.\")\n for (const id of removed) localRemovals?.forget(id)\n })\n\n const memoryIds = useMemo(() => memories.map((memory) => memory.id), [memories])\n const { pulse, travel } = live\n const authoredBy = center.kind === \"agent\" ? center.id : null\n const byIdRef = useRef(new Map<string, NetworkMemory>())\n useEffect(() => {\n byIdRef.current = new Map(memories.map((memory) => [memory.id, memory]))\n })\n const entering = useEnteringIds(memoryIds, {\n isProvisional,\n onEnter: (fresh) => {\n pulse(fresh.map((id) => `memory:${id}`))\n // Universo do agente: a memória que ele acabou de criar recebe a partícula verde do centro.\n if (!authoredBy) return\n const writes = agentWritesOf(fresh, [...byIdRef.current.values()]).filter((write) => write.agent === authoredBy)\n travel(writes.map((write) => ({ edge: `orbit:${write.id}`, reverse: true, tone: \"success\" as const, delayMs: AUTHORED_TRAVEL_DELAY_MS })))\n },\n })\n\n const particleColors = useMemo(() => universeChannelColors(channelColors, memories), [channelColors, memories])\n // Links, legenda e selo do card com a cor do canal: só no universo do agente (o do canal mantém o link\n // fraco primário). A memória escrita pelo agente do centro tem o link destacado (OPE-113).\n const legendColors = center.kind === \"agent\" ? particleColors : undefined\n const visuals = useMemo(() => buildParticles(memories, { channelColors: particleColors, staleAfterDays, bumps: live.bumps }), [memories, particleColors, staleAfterDays, live.bumps])\n const positions = useMemo(() => layoutUniverse(items), [items])\n // Só vale o que ainda está no universo: a memória que saiu fecha o card sozinha.\n const openId = opened !== null && ids.has(opened) ? opened : null\n const focusId = openId ?? (hovered !== null && ids.has(hovered) ? hovered : null)\n useEffect(() => {\n openRef.current = [opened]\n }, [opened])\n\n const onConsumption = useCallback(\n (event: ConsumptionEvent) => {\n const mine = event.memoryIds.filter((id) => ids.has(id))\n if (!mine.length) return\n live.countEvent()\n live.bump(mine)\n live.pulse(mine.map((id) => `memory:${id}`))\n live.travel(mine.slice(0, 20).map((id) => ({ edge: `orbit:${id}`, reverse: false, tone: \"white\" as const, delayMs: 150 })))\n live.pulse([`${center.kind}:${center.id}`], 1000)\n },\n [ids, live, center.kind, center.id],\n )\n useEngramindConsumption(onConsumption)\n\n const wrapped = actions\n const agentIcon = useAgentIcon()\n\n const nodes = useMemo<Node[]>(() => {\n const centerData: CenterNodeData = {\n label: center.label,\n detail: `${memories.length} ${memories.length === 1 ? \"memória\" : \"memórias\"}`,\n icon: center.kind === \"agent\" ? agentIcon(center.id) : (Hash as LucideIcon),\n pulseKey: `${center.kind}:${center.id}`,\n archived: center.archived,\n channelSlug: center.kind === \"channel\" ? center.id : undefined,\n }\n const list: Node[] = [{ id: CENTER_ID, type: \"center\", position: { x: 0, y: 0 }, data: centerData, zIndex: 5 }]\n for (const memory of items) {\n const visual = visuals.get(memory.id) ?? buildParticles([memory], { channelColors: particleColors, staleAfterDays }).get(memory.id)\n const point = positions.get(memory.id) ?? { x: 0, y: 0 }\n if (!visual) continue\n const data: MemoryNodeData = { memory, visual, point, matched: isMatch ? isMatch(memory) : null, leaving: memory.leaving, entering: entering.has(memory.id) }\n // Sem nada do hover/card aberto aqui (vem pelo contexto): node novo pisca no React Flow.\n list.push({ id: memory.id, type: \"memory\", position: point, data, zIndex: 1 })\n }\n return list\n }, [items, visuals, positions, isMatch, particleColors, center, memories.length, staleAfterDays, entering, agentIcon])\n const stableNodes = useStable(nodes)\n\n const edges = useMemo<Edge[]>(\n () =>\n items.map((memory) => ({\n id: `orbit:${memory.id}`,\n source: memory.id,\n target: CENTER_ID,\n type: \"orbit\",\n data: { color: legendColors?.get(memory.channel), authored: isAuthoredByCenter(memory, { kind: center.kind, id: center.id }), dimmed: isMatch ? !isMatch(memory) : false, entering: entering.has(memory.id) },\n })),\n [items, legendColors, center.kind, center.id, isMatch, entering],\n )\n const stableEdges = useStable(edges)\n\n\n const hover = useCallback((id: string | null) => setHovered(id), [])\n const focus = useMemo(() => ({ openId, focusId, focusPoint: focusId ? (positions.get(focusId) ?? null) : null, hover, actions: wrapped }), [openId, focusId, positions, hover, wrapped])\n const liveValue = useMemo(() => ({ pulses: live.pulses, travels: live.travels, finish: live.finish }), [live.pulses, live.travels, live.finish])\n\n return (\n <NetworkLiveProvider value={liveValue}>\n <UniverseFocusContext.Provider value={focus}>\n <NetworkCanvas\n nodes={stableNodes}\n edges={stableEdges}\n nodeTypes={NODE_TYPES}\n fitKey={`${center.kind}:${center.id}:${memories.length === 0 ? \"empty\" : \"full\"}`}\n label={center.kind === \"agent\" ? `Universo do agente ${center.label}` : `Universo do canal ${center.label}`}\n onNodeClick={(_event, node) => node.type === \"memory\" && setOpened((current) => (current === node.id ? null : node.id))}\n onPaneClick={() => setOpened(null)}\n className={className}\n >\n <UniverseStatsCard kind={center.kind} memories={memories} visuals={visuals} subscribers={subscribers} liveCount={live.liveCount} channelColors={legendColors} />\n <ActiveMemoryCard\n memory={openId ? (memories.find((memory) => memory.id === openId) ?? null) : null}\n visual={openId ? visuals.get(openId) : undefined}\n point={openId ? positions.get(openId) : undefined}\n channelColors={legendColors}\n actions={wrapped}\n pinned={openId !== null}\n />\n <RecenterButton />\n <UniversePanels count={memories.length} onCreate={onCreate} createLabel={createLabel} emptyTitle={emptyTitle} />\n </NetworkCanvas>\n </UniverseFocusContext.Provider>\n </NetworkLiveProvider>\n )\n}\n","import { lastRealUseOf, lastUseOf, memoryUses, particleBrightness, particleColor, particleSize, PARTICLE_MAX_PX, PRIMARY_CHANNEL_COLOR } from \"./network-math\"\nimport type { NetworkMemory } from \"./types\"\n\n/** Aparência calculada de uma partícula de memória (módulo puro, OPE-109). */\nexport interface ParticleVisual {\n id: string\n size: number\n /** Cor final (a do canal apagada pelo brilho). */\n color: string\n /** Cor do canal, sem o brilho. */\n baseColor: string\n brightness: number\n uses: number\n /** Data usada no brilho (cai na criação). */\n lastUse: string\n /** Último uso real (`null` = nunca usada). */\n lastRealUse: string | null\n pinned: boolean\n archived: boolean\n}\n\n/** Crescimento local por consumo ao vivo, até a releitura dos contadores. */\nexport const LIVE_BUMP_PX = 2\n\n/**\n * Escala relativa ao universo visível: cor pelo canal (`channelColors`, de `universeChannelColors`;\n * sem mapa, o roxo primário), tamanho logarítmico pelo uso e brilho pelo prazo do consolidador. A escala considera todas as memórias do\n * universo, inclusive as que a busca apaga (o destaque não recalcula nada).\n */\nexport function buildParticles(memories: readonly NetworkMemory[], options: { channelColors?: ReadonlyMap<string, string>; staleAfterDays: number; bumps?: Record<string, number>; now?: number }): Map<string, ParticleVisual> {\n const maxUses = memories.reduce((max, memory) => Math.max(max, memoryUses(memory)), 0)\n const now = options.now ?? Date.now()\n const result = new Map<string, ParticleVisual>()\n for (const memory of memories) {\n const uses = memoryUses(memory)\n // Consumida ao vivo desde a última leitura: brilho cheio na hora (o `last_retrieved_at` e o\n // `stale_candidate` do Engramind só mudam na releitura).\n const consumedLive = (options.bumps?.[memory.id] ?? 0) > 0\n const lastUse = consumedLive ? new Date(now).toISOString() : lastUseOf(memory)\n const brightness = particleBrightness({ status: memory.status, stale: memory.stale && !consumedLive, lastUse }, options.staleAfterDays, now)\n const base = options.channelColors?.get(memory.channel) ?? PRIMARY_CHANNEL_COLOR\n const bump = (options.bumps?.[memory.id] ?? 0) * LIVE_BUMP_PX\n result.set(memory.id, {\n id: memory.id,\n size: Math.min(PARTICLE_MAX_PX + 4 * LIVE_BUMP_PX, particleSize(uses, maxUses) + bump),\n color: memory.status === \"archived\" ? \"var(--color-muted-foreground)\" : particleColor(base, brightness),\n baseColor: base,\n brightness,\n uses,\n lastUse,\n lastRealUse: consumedLive ? lastUse : lastRealUseOf(memory),\n pinned: memory.status === \"permanent\",\n archived: memory.status === \"archived\",\n })\n }\n return result\n}\n","\"use client\"\n\nimport { useCallback, useEffect, useRef, useState } from \"react\"\nimport { useQueryClient } from \"@tanstack/react-query\"\nimport { useReducedMotion } from \"framer-motion\"\nimport { createConsumptionGrouper } from \"../../../core/events\"\nimport { useEngramindConfig } from \"../../lib/config\"\nimport { subscribeLive } from \"../../lib/live\"\nimport type { ConsumptionEvent } from \"../network/types\"\nimport { areaKey } from \"./useEngramind\"\n\n/** O Engramind grava os contadores em lote a cada 5 s: a releitura espera um pouco mais. */\nexport const CONSUMPTION_REFRESH_DELAY_MS = 6_000\n/** Espera para juntar os eventos por canal de uma mesma leitura (`consumption`). */\nexport const CONSUMPTION_GROUP_WINDOW_MS = 400\n\nexport function isConsumptionEvent(value: unknown): value is ConsumptionEvent {\n const event = value as Partial<ConsumptionEvent> | null\n return Boolean(event && typeof event.agent === \"string\" && (event.kind === \"context\" || event.kind === \"search\") && Array.isArray(event.channels) && Array.isArray(event.memoryIds))\n}\n\n/**\n * Tempo real do consumo de memórias: o webhook `memory.consumed` (Engramind ≥ 0.12.0) chega pelo SSE da\n * lib, um evento por canal; os eventos da mesma leitura são agrupados pelo `consumption` e a tela anima\n * **uma** vez com o `handler` (estado local: brilho cheio e tamanho um pouco maior). Leitura sem agente\n * (token de app ou admin) não anima. Os contadores reais são relidos depois do lote do Engramind; o\n * consumo não invalida o contexto.\n */\nexport function useEngramindConsumption(handler: (event: ConsumptionEvent) => void): void {\n const queryClient = useQueryClient()\n const { events } = useEngramindConfig()\n const handlerRef = useRef(handler)\n useEffect(() => {\n handlerRef.current = handler\n }, [handler])\n useEffect(() => {\n if (!events) return\n let timer: ReturnType<typeof setTimeout> | null = null\n const grouper = createConsumptionGrouper({\n windowMs: CONSUMPTION_GROUP_WINDOW_MS,\n onGroup: (event) => {\n handlerRef.current(event)\n if (timer) clearTimeout(timer)\n timer = setTimeout(() => void queryClient.invalidateQueries({ queryKey: areaKey(\"memories\") }), CONSUMPTION_REFRESH_DELAY_MS)\n },\n })\n const unsubscribe = subscribeLive(events, { onEvent: (event) => grouper.push(event) })\n return () => {\n unsubscribe()\n grouper.dispose()\n if (timer) clearTimeout(timer)\n }\n }, [events, queryClient])\n}\n\nexport interface Travel {\n id: string\n /** Aresta por onde a partícula viaja. */\n edge: string\n /** `true`: do alvo para a origem da aresta. */\n reverse: boolean\n /** `success`: criação de memória por um agente (verde). */\n tone: \"primary\" | \"white\" | \"success\"\n delayMs: number\n}\n\nlet travelSeq = 0\nconst NO_BUMPS: Record<string, number> = {}\n\n/**\n * Efeitos locais da rede: pulsos por node (contador que remonta o anel), partículas viajando pelas\n * arestas e o leve aumento de tamanho das memórias consumidas (zerado quando o Engramind relê os\n * números). Movimento reduzido: sem pulsos nem viagens; o aumento e o brilho continuam.\n */\nexport function useLiveEffects(resetKey: unknown) {\n const reducedMotion = useReducedMotion()\n const [pulses, setPulses] = useState<Record<string, number>>({})\n const [travels, setTravels] = useState<Travel[]>([])\n // O aumento vale até a próxima releitura (`resetKey`): o estado guarda a chave em que nasceu.\n const [bumpState, setBumpState] = useState<{ key: unknown; bumps: Record<string, number> }>({ key: resetKey, bumps: {} })\n const bumps = bumpState.key === resetKey ? bumpState.bumps : NO_BUMPS\n const keyRef = useRef(resetKey)\n const [liveCount, setLiveCount] = useState(0)\n const timers = useRef<ReturnType<typeof setTimeout>[]>([])\n\n useEffect(() => {\n keyRef.current = resetKey\n }, [resetKey])\n useEffect(() => {\n const pending = timers.current\n return () => pending.forEach(clearTimeout)\n }, [])\n\n const pulse = useCallback(\n (keys: readonly string[], delayMs = 0) => {\n if (reducedMotion || !keys.length) return\n const run = () => setPulses((previous) => Object.fromEntries([...Object.entries(previous), ...keys.map((key) => [key, (previous[key] ?? 0) + 1] as const)]))\n if (delayMs > 0) timers.current.push(setTimeout(run, delayMs))\n else run()\n },\n [reducedMotion],\n )\n const travel = useCallback(\n (items: readonly Omit<Travel, \"id\">[]) => {\n if (reducedMotion || !items.length) return\n setTravels((previous) => [...previous, ...items.map((item) => ({ ...item, id: `t${(travelSeq += 1)}` }))].slice(-60))\n },\n [reducedMotion],\n )\n const finish = useCallback((id: string) => setTravels((previous) => previous.filter((item) => item.id !== id)), [])\n const bump = useCallback((ids: readonly string[]) => {\n if (!ids.length) return\n setBumpState((previous) => {\n const key = keyRef.current\n const next = { ...(previous.key === key ? previous.bumps : {}) }\n for (const id of ids) next[id] = (next[id] ?? 0) + 1\n return { key, bumps: next }\n })\n }, [])\n const countEvent = useCallback(() => setLiveCount((count) => count + 1), [])\n return { pulses, travels, bumps, liveCount, pulse, travel, finish, bump, countEvent, reducedMotion: Boolean(reducedMotion) }\n}\n\nexport type LiveEffects = ReturnType<typeof useLiveEffects>\n","/**\n * Eventos do Engramind (webhook) e o formato que a lib repassa ao navegador pelo SSE: só ids, slugs e\n * tipos — nunca texto, título, `query` ou segredo.\n */\n\nexport type WebhookEventType =\n | \"memory.created\"\n | \"memory.updated\"\n | \"memory.archived\"\n | \"memory.deleted\"\n | \"memory.consumed\"\n | \"channel.updated\"\n | \"subscription.updated\"\n | \"settings.updated\"\n | \"identities.updated\"\n\n/** Corpo do webhook (`POST <webhook_url>`), contrato do Engramind ≥ 0.12.0. */\nexport interface WebhookEvent {\n id: string\n type: WebhookEventType | (string & {})\n channel: string | null\n channel_version?: number | null\n memory_ids?: string[]\n at?: string\n keys?: string[]\n subscription?: string\n agent?: string | null\n target?: string\n app?: string | null\n consumption?: string\n operation?: \"get_context\" | \"search_memories\" | \"get_hints\" | \"get_memory\" | (string & {})\n title_ids?: string[]\n context_version?: string\n}\n\n/** Evento ao vivo entregue pelo SSE da lib (`event: engramind`). */\nexport interface LiveEvent {\n /** `id` do webhook (ausente nos eventos gerados pelo próprio app). */\n id?: string\n type: string\n channel?: string | null\n memoryIds?: string[]\n keys?: string[]\n agent?: string | null\n app?: string | null\n consumption?: string\n operation?: string\n titleIds?: string[]\n contextVersion?: string\n at?: string\n}\n\nconst ids = (value: unknown): string[] | undefined => (Array.isArray(value) ? value.filter((item): item is string => typeof item === \"string\") : undefined)\nconst str = (value: unknown): string | undefined => (typeof value === \"string\" && value ? value : undefined)\n\n/** Webhook → evento ao vivo (só os campos permitidos). */\nexport function toLiveEvent(event: WebhookEvent): LiveEvent {\n const live: LiveEvent = { id: event.id, type: event.type, channel: event.channel ?? null }\n const memoryIds = ids(event.memory_ids)\n if (memoryIds) live.memoryIds = memoryIds\n const keys = ids(event.keys)\n if (keys) live.keys = keys\n if (event.agent !== undefined) live.agent = event.agent ?? null\n if (event.app !== undefined) live.app = event.app ?? null\n const consumption = str(event.consumption)\n if (consumption) live.consumption = consumption\n const operation = str(event.operation)\n if (operation) live.operation = operation\n const titleIds = ids(event.title_ids)\n if (titleIds) live.titleIds = titleIds\n const contextVersion = str(event.context_version)\n if (contextVersion) live.contextVersion = contextVersion\n const at = str(event.at)\n if (at) live.at = at\n return live\n}\n\n/** `memory.consumed` não muda nada: nunca marca o contexto como sujo nem invalida as listas. */\nexport const isConsumedEvent = (type: string) => type === \"memory.consumed\"\n\n/** Eventos `memory.*` que mudam o contexto (todos menos `memory.consumed`). */\nexport const isMemoryChange = (type: string) => type.startsWith(\"memory.\") && !isConsumedEvent(type)\n\n/**\n * Consumo agrupado (um por `consumption`): o formato que a rede anima. `channels` são os canais que\n * entregaram memórias (um evento por canal), `delivered` idem.\n */\nexport interface ConsumptionEvent {\n /** Agente que leu (`app/agente`). */\n agent: string\n kind: \"context\" | \"search\"\n channels: string[]\n delivered: string[]\n memoryIds: string[]\n titleIds?: string[]\n version?: string\n /** Id do consumo no Engramind (`cns_…`). */\n consumption?: string\n operation?: string\n}\n\n/** Junta os eventos `memory.consumed` de uma mesma leitura (`consumption`). */\nexport function mergeConsumption(events: readonly LiveEvent[]): ConsumptionEvent | null {\n const first = events.find((event) => event.agent)\n if (!first?.agent) return null\n const channels = new Set<string>()\n const memoryIds = new Set<string>()\n const titleIds = new Set<string>()\n let version: string | undefined\n for (const event of events) {\n if (event.channel && (event.memoryIds?.length ?? 0) > 0) channels.add(event.channel)\n for (const id of event.memoryIds ?? []) memoryIds.add(id)\n for (const id of event.titleIds ?? []) titleIds.add(id)\n version = version ?? event.contextVersion\n }\n if (!memoryIds.size) return null\n const merged: ConsumptionEvent = {\n agent: first.agent,\n kind: first.operation === \"get_context\" ? \"context\" : \"search\",\n channels: [...channels],\n delivered: [...channels],\n memoryIds: [...memoryIds],\n ...(titleIds.size ? { titleIds: [...titleIds] } : {}),\n ...(version ? { version } : {}),\n ...(first.consumption ? { consumption: first.consumption } : {}),\n ...(first.operation ? { operation: first.operation } : {}),\n }\n return merged\n}\n\nexport interface ConsumptionGrouperOptions {\n /** Espera para juntar os eventos de canais da mesma leitura (padrão 400 ms). */\n windowMs?: number\n /** Quantos `consumption` já emitidos são lembrados para descartar repetições (padrão 500). */\n memory?: number\n onGroup: (event: ConsumptionEvent) => void\n}\n\n/**\n * Agrupa `memory.consumed` por `consumption`: emite **um** consumo por leitura, depois de `windowMs` sem\n * novos canais. Evento sem `agent` (leitura por token de app ou admin) é ignorado, e um `consumption` já\n * emitido não é emitido de novo (retentativa do webhook). Isomórfico (servidor e navegador).\n */\nexport function createConsumptionGrouper(options: ConsumptionGrouperOptions) {\n const windowMs = options.windowMs ?? 400\n const limit = options.memory ?? 500\n const pending = new Map<string, { events: LiveEvent[]; timer: ReturnType<typeof setTimeout> }>()\n const done: string[] = []\n const doneSet = new Set<string>()\n const flush = (key: string) => {\n const entry = pending.get(key)\n if (!entry) return\n pending.delete(key)\n doneSet.add(key)\n done.push(key)\n while (done.length > limit) doneSet.delete(done.shift()!)\n const merged = mergeConsumption(entry.events)\n if (merged) options.onGroup(merged)\n }\n return {\n push(event: LiveEvent) {\n if (!isConsumedEvent(event.type) || !event.agent) return\n const key = event.consumption ?? event.id ?? `${event.agent}:${event.at ?? \"\"}`\n if (doneSet.has(key)) return\n const entry = pending.get(key)\n if (entry) {\n clearTimeout(entry.timer)\n entry.events.push(event)\n entry.timer = setTimeout(() => flush(key), windowMs)\n } else pending.set(key, { events: [event], timer: setTimeout(() => flush(key), windowMs) })\n },\n /** Emite os grupos pendentes na hora (desmontagem, testes). */\n flushAll() {\n for (const key of [...pending.keys()]) {\n clearTimeout(pending.get(key)!.timer)\n flush(key)\n }\n },\n dispose() {\n for (const entry of pending.values()) clearTimeout(entry.timer)\n pending.clear()\n },\n }\n}\n","\"use client\"\n\nimport { useEffect } from \"react\"\nimport { useReactFlow } from \"@xyflow/react\"\nimport { AnimatePresence, useReducedMotion } from \"framer-motion\"\nimport type { Point } from \"../../network/network-math\"\nimport type { ParticleVisual } from \"../../network/particles\"\nimport type { NetworkMemory } from \"../../network/types\"\nimport type { MemoryCardActions } from \"./MemoryCard\"\nimport { MemoryCardLayer } from \"./MemoryCardLayer\"\nimport { FIT_DURATION_MS } from \"./NetworkCanvas\"\nimport { CARD_MIN_ZOOM } from \"./MemoryNode\"\nimport { useZoom } from \"./nodes\"\n\n/**\n * Card da memória aberta (só por clique ou toque; o hover só afasta as vizinhas) na camada sem zoom (filho do React Flow): a partícula vira o card a partir\n * do zoom `CARD_MIN_ZOOM`; afastada demais, só a partícula se destaca. Clique/toque (`pinned`) com o\n * zoom afastado aproxima até `CARD_MIN_ZOOM`, centralizado na partícula, e o card abre.\n */\nexport function ActiveMemoryCard({\n memory,\n visual,\n point,\n channelColors,\n actions,\n pinned = false,\n}: {\n memory: NetworkMemory | null\n visual?: ParticleVisual\n point?: Point\n channelColors?: Map<string, string>\n actions: MemoryCardActions\n /** O card acabou de ser aberto por clique/toque (com a rede afastada, aproxima até `CARD_MIN_ZOOM`). */\n pinned?: boolean\n}) {\n const zoom = useZoom()\n const flow = useReactFlow()\n const reducedMotion = useReducedMotion()\n const pinnedId = pinned && memory ? memory.id : null\n useEffect(() => {\n if (!pinnedId || !point || zoom >= CARD_MIN_ZOOM) return\n void flow.setCenter(point.x, point.y, { zoom: CARD_MIN_ZOOM, duration: reducedMotion ? 0 : FIT_DURATION_MS })\n // Só ao fixar (o zoom que o usuário muda depois não puxa a rede de volta).\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pinnedId])\n const open = memory && visual && point && zoom >= CARD_MIN_ZOOM\n return (\n <AnimatePresence>\n {open && (\n <MemoryCardLayer key={memory.id} memory={memory} visual={visual} point={point} actions={actions} channelColor={channelColors?.get(memory.channel)} />\n )}\n </AnimatePresence>\n )\n}\n","\"use client\"\n\nimport { useState } from \"react\"\nimport { useStore } from \"@xyflow/react\"\nimport { motion, useReducedMotion } from \"framer-motion\"\nimport { clampCardRect, memoryCardSize, type Point } from \"../../network/network-math\"\nimport type { ParticleVisual } from \"../../network/particles\"\nimport type { NetworkMemory } from \"../../network/types\"\nimport { MemoryCard, type MemoryCardActions } from \"./MemoryCard\"\n\n/** Card quadrado e fixo (OPE-113): não depende do zoom da rede; o texto rola dentro. */\nexport const MEMORY_CARD_WIDTH = 360\nexport const MEMORY_CARD_HEIGHT = 360\nexport const MEMORY_CARD_MORPH_S = 0.22\n\n/**\n * Card da memória numa camada FORA da área com zoom (filho do React Flow, irmão do viewport): tem\n * sempre o mesmo tamanho e fonte, fica inteiro dentro do quadro (`clampCardRect`) e acompanha o\n * arrastar e o zoom. Abre se transformando a partir da partícula (mesmo lugar, tamanho e cor na\n * tela) e fecha encolhendo de volta para ela; com movimento reduzido, a troca é instantânea.\n */\nexport function MemoryCardLayer({\n memory,\n visual,\n point,\n actions,\n channelColor,\n}: {\n memory: NetworkMemory\n visual: ParticleVisual\n /** Posição da partícula na rede (coordenadas do React Flow). */\n point: Point\n actions: MemoryCardActions\n channelColor?: string\n}) {\n const reducedMotion = useReducedMotion()\n const tx = useStore((state) => state.transform[0])\n const ty = useStore((state) => state.transform[1])\n const zoom = useStore((state) => state.transform[2])\n const canvasWidth = useStore((state) => state.width)\n const canvasHeight = useStore((state) => state.height)\n const [settled, setSettled] = useState(false)\n\n const anchor = { x: point.x * zoom + tx, y: point.y * zoom + ty }\n // Limitado ao quadro (8 px de cada lado): o quadrado encolhe só quando o quadro não comporta.\n const { width, height: visibleHeight } = memoryCardSize({ width: MEMORY_CARD_WIDTH, height: MEMORY_CARD_HEIGHT }, { width: canvasWidth, height: canvasHeight })\n const target = clampCardRect(anchor, { width, height: visibleHeight }, { width: canvasWidth || width + 16, height: canvasHeight || visibleHeight + 16 })\n const particle = Math.max(visual.size * zoom, 6)\n const asParticle = { left: anchor.x - particle / 2, top: anchor.y - particle / 2, width: particle, height: particle, borderRadius: particle / 2 }\n const asCard = { left: target.x, top: target.y, width, height: visibleHeight, borderRadius: 12 }\n const morph = { duration: reducedMotion ? 0 : MEMORY_CARD_MORPH_S, ease: \"easeOut\" as const }\n // Depois de aberto, a posição segue o arrastar/zoom na hora (sem transição atrasada).\n const follow = settled || reducedMotion ? { duration: 0 } : morph\n\n return (\n <motion.div\n role=\"dialog\"\n aria-label={`Memória ${memory.title}`}\n data-testid={`memory-card-${memory.id}`}\n data-card-width={width}\n data-card-height={visibleHeight}\n data-network-card=\"\"\n className=\"nodrag nopan nowheel pointer-events-auto absolute z-30 cursor-default overflow-hidden border bg-popover text-popover-foreground shadow-xl\"\n initial={reducedMotion ? { ...asCard, opacity: 0 } : { ...asParticle, opacity: 1 }}\n animate={{ ...asCard, opacity: 1 }}\n exit={reducedMotion ? { opacity: 0, transition: { duration: 0 } } : { ...asParticle, opacity: 0, transition: morph }}\n transition={{ ...morph, left: follow, top: follow }}\n onAnimationComplete={() => setSettled(true)}\n onClick={(event) => event.stopPropagation()}\n onDoubleClick={(event) => event.stopPropagation()}\n >\n {/* A cor da partícula some enquanto a forma cresce: a partícula \"vira\" o card. */}\n <motion.span\n aria-hidden\n className=\"pointer-events-none absolute inset-0\"\n style={{ background: visual.archived ? \"transparent\" : visual.color }}\n initial={{ opacity: reducedMotion ? 0 : 1 }}\n animate={{ opacity: 0 }}\n exit={{ opacity: 1 }}\n transition={morph}\n />\n <div className=\"relative h-full overflow-hidden\" data-testid=\"memory-card-scroll\">\n <div className=\"h-full\" style={{ width }}>\n <MemoryCard memory={memory} visual={visual} actions={actions} channelColor={channelColor} contentDelay={reducedMotion ? 0 : MEMORY_CARD_MORPH_S * 0.7} />\n </div>\n </div>\n </motion.div>\n )\n}\n","\"use client\"\n\nimport { formatDistanceToNow } from \"date-fns\"\nimport { ptBR } from \"date-fns/locale\"\nimport { motion } from \"framer-motion\"\nimport { ArrowRightLeft, History, Pencil, Pin, PinOff, Trash2 } from \"lucide-react\"\nimport { Badge } from \"../../../components/ui/badge\"\nimport { Button } from \"../../../components/ui/button\"\nimport { Label } from \"../../../components/ui/label\"\nimport { Switch } from \"../../../components/ui/switch\"\nimport type { ParticleVisual } from \"../../network/particles\"\nimport type { NetworkMemory } from \"../../network/types\"\nimport { useAgentLabel } from \"./AgentLabels\"\nimport { AgentIcon } from \"./agent-icons\"\nimport { ChannelDisplayName } from \"./ChannelName\"\n\n/** Ações do card da memória; a origem dos dados (Engramind bruto ou listas dos agentes) decide como gravar. */\nexport interface MemoryCardActions {\n onActive: (memory: NetworkMemory, active: boolean) => void\n onPin: (memory: NetworkMemory, pinned: boolean) => void\n onEdit: (memory: NetworkMemory) => void\n onDelete: (memory: NetworkMemory) => void\n onMove?: (memory: NetworkMemory) => void\n onHistory?: (memory: NetworkMemory) => void\n /** Somente leitura (ex.: canal arquivado). */\n readOnly?: boolean\n}\n\nexport const ago = (iso: string) => formatDistanceToNow(new Date(iso), { addSuffix: true, locale: ptBR })\n\n/**\n * Conteúdo do card que a partícula vira no clique ou toque: título, texto (rola dentro), chips\n * (categoria, canal legível, agente autor), idade, relevância, último uso e ações, sempre visíveis\n * embaixo. A forma, a posição e a transformação a partir da partícula ficam no `MemoryCardLayer` (fora\n * da camada com zoom); o conteúdo entra com fade quando a forma termina de crescer.\n */\nexport function MemoryCard({ memory, visual, actions, channelColor, contentDelay = 0 }: { memory: NetworkMemory; visual: ParticleVisual; actions: MemoryCardActions; channelColor?: string; contentDelay?: number }) {\n const active = memory.status !== \"archived\"\n const readOnly = actions.readOnly === true\n return (\n <motion.div data-testid=\"memory-card-body\" className=\"flex h-full flex-col p-3 text-left\" initial={{ opacity: 0 }} animate={{ opacity: 1, transition: { duration: 0.14, delay: contentDelay } }} exit={{ opacity: 0, transition: { duration: 0.08 } }}>\n <div className=\"flex shrink-0 items-start gap-2\">\n <span aria-hidden className=\"mt-1 h-2.5 w-2.5 shrink-0 rounded-full\" style={{ background: visual.baseColor }} />\n <p className=\"flex-1 text-sm font-semibold leading-snug\">{memory.title}</p>\n {visual.pinned && <Pin className=\"h-3.5 w-3.5 shrink-0 text-primary\" aria-label=\"Fixada\" />}\n </div>\n <p className=\"mt-2 min-h-0 flex-1 overflow-y-auto overscroll-contain whitespace-pre-wrap text-xs text-muted-foreground\" data-testid=\"memory-card-text\">\n {memory.text}\n </p>\n <div className=\"mt-2 flex shrink-0 flex-wrap items-center gap-1\">\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {memory.category}\n </Badge>\n <Badge variant=\"outline\" className=\"text-[10px]\" style={channelColor ? { borderColor: channelColor } : undefined}>\n <ChannelDisplayName slug={memory.channel} className=\"max-w-56\" />\n </Badge>\n <AuthorChip memory={memory} />\n {memory.originLabel && (\n <Badge variant=\"outline\" className=\"text-[10px]\" title={`Gravada por ${memory.originLabel}`} data-testid=\"memory-card-origin\">\n {memory.originLabel}\n </Badge>\n )}\n {memory.fromOwner && (\n <Badge variant=\"outline\" className=\"text-[10px]\">\n Memória do dono\n </Badge>\n )}\n </div>\n <dl className=\"mt-2 grid shrink-0 grid-cols-2 gap-x-2 gap-y-1 text-[11px]\">\n <dt className=\"text-muted-foreground\">Idade</dt>\n <dd data-testid=\"memory-card-age\">{ago(memory.createdAt)}</dd>\n <dt className=\"text-muted-foreground\">Relevância</dt>\n <dd data-testid=\"memory-card-uses\">\n {visual.uses} {visual.uses === 1 ? \"uso\" : \"usos\"} ({memory.retrievals} consultas · {memory.injections} injeções)\n </dd>\n <dt className=\"text-muted-foreground\">Última vez usada</dt>\n <dd data-testid=\"memory-card-last-use\">{visual.lastRealUse ? ago(visual.lastRealUse) : \"nunca usada\"}</dd>\n </dl>\n <div className=\"mt-3 flex shrink-0 items-center justify-between gap-2 border-t pt-2\">\n <span className=\"flex items-center gap-2\">\n <Switch id={`active-${memory.id}`} checked={active} disabled={readOnly} onCheckedChange={(checked) => actions.onActive(memory, checked)} />\n <Label htmlFor={`active-${memory.id}`} className=\"text-xs\">\n Ativa\n </Label>\n </span>\n <span className=\"flex items-center gap-0.5\">\n <CardAction label={visual.pinned ? \"Desafixar\" : \"Fixar\"} disabled={readOnly || !active} onClick={() => actions.onPin(memory, !visual.pinned)}>\n {visual.pinned ? <PinOff className=\"h-3.5 w-3.5\" /> : <Pin className=\"h-3.5 w-3.5\" />}\n </CardAction>\n <CardAction label=\"Editar\" disabled={readOnly} onClick={() => actions.onEdit(memory)}>\n <Pencil className=\"h-3.5 w-3.5\" />\n </CardAction>\n {actions.onMove && (\n <CardAction label=\"Mover de canal\" disabled={readOnly} onClick={() => actions.onMove?.(memory)}>\n <ArrowRightLeft className=\"h-3.5 w-3.5\" />\n </CardAction>\n )}\n {actions.onHistory && (\n <CardAction label=\"Histórico\" onClick={() => actions.onHistory?.(memory)}>\n <History className=\"h-3.5 w-3.5\" />\n </CardAction>\n )}\n <CardAction label=\"Excluir\" destructive disabled={readOnly} onClick={() => actions.onDelete(memory)}>\n <Trash2 className=\"h-3.5 w-3.5\" />\n </CardAction>\n </span>\n </div>\n </motion.div>\n )\n}\n\n/**\n * Chip de quem criou a memória (OPE-113): o agente (ícone + nome sem \"Agente\", `app/agente` na dica) ou,\n * sem agente, o app que gravou. Sem autor (ou com a origem do Opex, que tem selo próprio), nada.\n */\nfunction AuthorChip({ memory }: { memory: NetworkMemory }) {\n const agent = memory.authorAgent ?? null\n const name = useAgentLabel(agent ?? \"\")\n if (agent)\n return (\n <Badge variant=\"outline\" className=\"gap-1 text-[10px]\" title={`Criada pelo agente ${agent}`} data-testid=\"memory-card-author\">\n <AgentIcon agent={agent} className=\"h-3 w-3\" />\n <span className=\"max-w-40 truncate\">{name}</span>\n </Badge>\n )\n if (memory.authorAgent === null && memory.author && !memory.originLabel)\n return (\n <Badge variant=\"outline\" className=\"text-[10px]\" title={`Criada pelo app ${memory.author}`} data-testid=\"memory-card-author\">\n App {memory.author}\n </Badge>\n )\n return null\n}\n\nfunction CardAction({ label, onClick, disabled, destructive, children }: { label: string; onClick: () => void; disabled?: boolean; destructive?: boolean; children: React.ReactNode }) {\n return (\n <Button type=\"button\" variant=\"ghost\" size=\"icon\" className={destructive ? \"h-7 w-7 text-destructive hover:text-destructive\" : \"h-7 w-7\"} aria-label={label} title={label} disabled={disabled} onClick={onClick}>\n {children}\n </Button>\n )\n}\n","import * as React from \"react\"\nimport { cn } from \"../../lib/utils\"\n\ninterface SwitchProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {\n onCheckedChange?: (checked: boolean) => void\n}\n\nconst Switch = React.forwardRef<HTMLInputElement, SwitchProps>(\n ({ className, onCheckedChange, checked, defaultChecked, ...props }, ref) => {\n const [isChecked, setIsChecked] = React.useState(defaultChecked || checked || false)\n\n React.useEffect(() => {\n if (checked !== undefined) {\n setIsChecked(checked)\n }\n }, [checked])\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const newChecked = e.target.checked\n setIsChecked(newChecked)\n onCheckedChange?.(newChecked)\n props.onChange?.(e)\n }\n\n return (\n <label className=\"relative inline-flex items-center cursor-pointer\">\n <input type=\"checkbox\" ref={ref} className=\"sr-only peer\" checked={isChecked} onChange={handleChange} {...props} />\n <div\n className={cn(\n \"w-11 h-6 bg-input peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-primary/30 rounded-full peer peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-primary-foreground after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-background after:border-border after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary\",\n props.disabled && \"opacity-50 cursor-not-allowed\",\n className,\n )}\n />\n </label>\n )\n }\n)\nSwitch.displayName = \"Switch\"\n\nexport { Switch }\n","import { createElement } from \"react\"\nimport type { LucideIcon } from \"lucide-react\"\nimport { useEngramindConfig } from \"../../../lib/config\"\n\n/** Ícone de cada agente (`agentIcon` do provider; padrão: o robô genérico). */\nexport function useAgentIcon(): (agent: string) => LucideIcon {\n return useEngramindConfig().agentIcon\n}\n\n/** Ícone do agente como elemento (sem criar componente durante o render). */\nexport const AgentIcon = ({ agent, className }: { agent: string; className?: string }) => {\n const icon = useAgentIcon()\n return createElement(icon(agent), { className, \"aria-hidden\": true })\n}\n","\"use client\"\n\nimport { createContext, useContext, useEffect } from \"react\"\nimport { Background, ReactFlow, useReactFlow, useStore, type Edge, type Node, type NodeMouseHandler, type NodeTypes, type ReactFlowInstance } from \"@xyflow/react\"\nimport { useReducedMotion } from \"framer-motion\"\nimport { cn } from \"../../../lib/utils\"\nimport { NETWORK_EDGE_TYPES } from \"./edges\"\nimport { useIsMobile } from \"../../../hooks/useMediaQuery\"\nimport { MOBILE_FIT_MIN_ZOOM, minZoomCenter, type Rect } from \"../../network/network-math\"\nimport { NETWORK_CANVAS_CLASS, NETWORK_FLOW_THEME } from \"./layout-classes\"\nimport { FLOW_BACKGROUND_PROPS } from \"../../../components/flow/flow-theme\"\n\nexport const FIT_DURATION_MS = 300\nconst FIT_PADDING = 0.15\n\n/** Enquadramento da visão atual (`null` = a rede inteira): o \"Centralizar\" volta a ele. */\nconst FitBoundsContext = createContext<Rect | null>(null)\n\ntype Fitter = Pick<ReactFlowInstance, \"fitView\" | \"fitBounds\" | \"setCenter\">\n\n/**\n * Enquadra a visão: o retângulo da visão (ou a rede inteira). No celular, o enquadramento inicial\n * não afasta abaixo de `MOBILE_FIT_MIN_ZOOM`: centraliza no retângulo e o resto fica a um arrastar.\n */\nfunction fitTo(flow: Fitter, bounds: Rect | null, duration: number, mobile: { size: { width: number; height: number } } | null) {\n const center = bounds && mobile ? minZoomCenter(bounds, mobile.size, MOBILE_FIT_MIN_ZOOM) : null\n if (center) void flow.setCenter(center.x, center.y, { zoom: center.zoom, duration })\n else if (bounds) void flow.fitBounds(bounds, { padding: 0, duration })\n else void flow.fitView({ padding: FIT_PADDING, duration })\n}\n\n/** Tamanho do quadro quando é celular (a regra do zoom mínimo só vale lá). */\nfunction useMobileFit(): { size: { width: number; height: number } } | null {\n const mobile = useIsMobile()\n const width = useStore((state) => state.width)\n const height = useStore((state) => state.height)\n return mobile ? { size: { width, height } } : null\n}\n\n/**\n * Canvas da rede (React Flow): arrastar move a rede inteira, scroll/pinça dá zoom e nodes não são\n * arrastáveis (layout automático). `fitKey` reenquadra quando a visão muda (transição animada de zoom);\n * `initialBounds` troca o \"enquadrar tudo\" por um retângulo (visão inicial: a linha de agentes).\n * Os `children` ficam fora da camada com zoom (cards, painéis e a camada do card da memória).\n */\nexport function NetworkCanvas({\n nodes,\n edges,\n nodeTypes,\n fitKey,\n initialBounds = null,\n onNodeClick,\n onNodeContextMenu,\n onPaneClick,\n className,\n label,\n children,\n}: {\n nodes: Node[]\n edges: Edge[]\n nodeTypes: NodeTypes\n fitKey: string\n initialBounds?: Rect | null\n onNodeClick?: NodeMouseHandler\n onNodeContextMenu?: NodeMouseHandler\n onPaneClick?: () => void\n className?: string\n label: string\n children?: React.ReactNode\n}) {\n return (\n <div className={cn(NETWORK_CANVAS_CLASS, className)} aria-label={label} role=\"region\" data-testid=\"network-canvas\">\n <ReactFlow\n nodes={nodes}\n edges={edges}\n nodeTypes={nodeTypes}\n edgeTypes={NETWORK_EDGE_TYPES}\n colorMode=\"dark\"\n style={NETWORK_FLOW_THEME}\n nodeOrigin={[0.5, 0.5]}\n nodesDraggable={false}\n nodesConnectable={false}\n elementsSelectable={false}\n panOnDrag\n zoomOnScroll\n zoomOnPinch\n zoomOnDoubleClick={false}\n onlyRenderVisibleElements\n minZoom={0.1}\n maxZoom={2.5}\n fitView={!initialBounds}\n fitViewOptions={{ padding: FIT_PADDING }}\n onNodeClick={onNodeClick}\n onNodeContextMenu={onNodeContextMenu}\n onPaneClick={onPaneClick}\n proOptions={{ hideAttribution: true }}\n className=\"bg-transparent\"\n >\n <Background {...FLOW_BACKGROUND_PROPS} />\n <FitBoundsContext.Provider value={initialBounds}>\n <FitOnChange fitKey={fitKey} />\n {children}\n </FitBoundsContext.Provider>\n </ReactFlow>\n </div>\n )\n}\n\n/** Reenquadra a visão quando a chave muda (troca de universo ou nodes novos). */\nfunction FitOnChange({ fitKey }: { fitKey: string }) {\n const flow = useReactFlow()\n const reducedMotion = useReducedMotion()\n const bounds = useContext(FitBoundsContext)\n const mobile = useMobileFit()\n const boundsKey = bounds ? `${bounds.x}:${bounds.y}:${bounds.width}:${bounds.height}` : \"all\"\n // Celular: refaz quando o quadro ganha tamanho (o zoom mínimo depende dele).\n const mobileKey = mobile ? `${mobile.size.width}x${mobile.size.height}` : \"desktop\"\n useEffect(() => {\n const frame = requestAnimationFrame(() => fitTo(flow, bounds, reducedMotion ? 0 : FIT_DURATION_MS, mobile))\n return () => cancelAnimationFrame(frame)\n // `boundsKey`/`mobileKey` resumem o retângulo e o quadro (os objetos mudam a cada render).\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [fitKey, boundsKey, mobileKey, flow, reducedMotion])\n return null\n}\n\n/** Reenquadrar (botão \"Centralizar\"): volta ao enquadramento da visão (o inicial, na visão horizontal). */\nexport function useRecenter() {\n const flow = useReactFlow()\n const reducedMotion = useReducedMotion()\n const bounds = useContext(FitBoundsContext)\n const mobile = useMobileFit()\n return () => fitTo(flow, bounds, reducedMotion ? 0 : FIT_DURATION_MS, mobile)\n}\n","\"use client\"\n\nimport { memo, useEffect, useRef, useState } from \"react\"\nimport { BaseEdge, EdgeLabelRenderer, getStraightPath, type Edge, type EdgeProps } from \"@xyflow/react\"\nimport { motion, useReducedMotion } from \"framer-motion\"\nimport { SUBSCRIPTION_MODE_LABEL } from \"./network-labels\"\nimport { TravelDots } from \"./live\"\nimport { OVERVIEW_LINK_BEND, overviewLinkMidpoint, overviewLinkPath } from \"../../network/overview-layout\"\nimport type { SubscriptionMode } from \"../../network/types\"\n\n/** `bend`: curvatura do link (o sinal alterna entre links vizinhos, para não se sobreporem). */\n/** `label`: dica no lugar do modo (link app → canal: agentes e modos agregados, OPE-129). */\nexport type LinkEdgeData = { mode: SubscriptionMode; dimmed?: boolean; bend?: number; label?: string }\n/** `color`: cor do canal (universo do agente); `authored`: memória escrita pelo agente do centro (link destacado). */\nexport type OrbitEdgeData = { color?: string; authored?: boolean; dimmed?: boolean; entering?: boolean }\n\n/** Traço do link ao centro: normal e destacado (memória escrita pelo agente do centro). */\nexport const ORBIT_STROKE_WIDTH = { normal: 1, authored: 2.25 } as const\n\n/** Tempo que o modo do link fica à mostra depois de um toque (no toque não há \"passar o mouse\"). */\nexport const LINK_TOUCH_LABEL_MS = 1500\n\n/** Link agente ↔ canal (uma assinatura): o modo aparece ao passar o mouse ou, no toque, por um instante. */\nexport const LinkEdge = memo(function LinkEdge({ id, sourceX, sourceY, targetX, targetY, data }: EdgeProps<Edge<LinkEdgeData, \"link\">>) {\n const [hover, setHover] = useState(false)\n const touchTimer = useRef<ReturnType<typeof setTimeout> | null>(null)\n useEffect(() => () => void (touchTimer.current && clearTimeout(touchTimer.current)), [])\n const onPointerDown = (event: React.PointerEvent) => {\n if (event.pointerType !== \"touch\") return\n if (touchTimer.current) clearTimeout(touchTimer.current)\n setHover(true)\n touchTimer.current = setTimeout(() => setHover(false), LINK_TOUCH_LABEL_MS)\n }\n const bend = data?.bend ?? OVERVIEW_LINK_BEND\n const path = overviewLinkPath({ x: sourceX, y: sourceY }, { x: targetX, y: targetY }, bend)\n const { x: labelX, y: labelY } = overviewLinkMidpoint({ x: sourceX, y: sourceY }, { x: targetX, y: targetY }, bend)\n return (\n <>\n <BaseEdge id={id} path={path} style={{ stroke: \"var(--color-primary)\", strokeOpacity: data?.dimmed ? 0.12 : hover ? 0.9 : 0.4, strokeWidth: hover ? 2 : 1.25 }} />\n <path d={path} fill=\"none\" stroke=\"transparent\" strokeWidth={14} data-testid={`link-${id}`} onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)} onPointerDown={onPointerDown} />\n <TravelDots edgeId={id} path={path} />\n {hover && data && (\n <EdgeLabelRenderer>\n <div\n role=\"tooltip\"\n className=\"pointer-events-none absolute rounded-md border bg-popover px-2 py-0.5 text-xs text-popover-foreground shadow\"\n style={{ transform: `translate(-50%, -50%) translate(${labelX}px, ${labelY}px)` }}\n >\n {data.label ?? SUBSCRIPTION_MODE_LABEL[data.mode]}\n </div>\n </EdgeLabelRenderer>\n )}\n </>\n )\n})\n\n/** Link fraco e sem significado entre a partícula e o centro (cor do canal no universo do agente). */\nexport const OrbitEdge = memo(function OrbitEdge({ id, sourceX, sourceY, targetX, targetY, data }: EdgeProps<Edge<OrbitEdgeData, \"orbit\">>) {\n const reducedMotion = useReducedMotion()\n const [path] = getStraightPath({ sourceX, sourceY, targetX, targetY })\n const authored = data?.authored === true\n const opacity = data?.dimmed ? 0.04 : authored ? 0.6 : data?.color ? 0.32 : 0.14\n const style = { stroke: data?.color ?? \"var(--color-primary)\", strokeOpacity: opacity, strokeWidth: authored ? ORBIT_STROKE_WIDTH.authored : ORBIT_STROKE_WIDTH.normal }\n const marks = { \"data-authored\": authored || undefined }\n return (\n <>\n {data?.entering && !reducedMotion ? (\n // Memória nova: o link se desenha entre a partícula e o centro enquanto ela nasce.\n <motion.path data-testid={`orbit-entering-${id}`} {...marks} d={path} fill=\"none\" style={style} initial={{ pathLength: 0 }} animate={{ pathLength: 1 }} transition={{ duration: 0.5, ease: \"easeOut\" }} />\n ) : (\n <BaseEdge id={id} path={path} style={style} {...marks} />\n )}\n <TravelDots edgeId={id} path={path} />\n </>\n )\n})\n\nexport const NETWORK_EDGE_TYPES = { link: LinkEdge, orbit: OrbitEdge }\n","import type { SubscriptionMode } from \"../../network/types\"\n\nexport const SUBSCRIPTION_MODE_LABEL: Record<SubscriptionMode, string> = {\n inject: \"inject: entra no contexto\",\n search: \"search: só por busca\",\n manage: \"manage: gerencia o canal\",\n}\n","\"use client\"\n\nimport { createContext, useContext, useMemo } from \"react\"\nimport { motion } from \"framer-motion\"\nimport { PathTraveler } from \"../../../components/flow/path-traveler\"\nimport type { Travel } from \"../../hooks/useEngramindConsumption\"\n\n/** Pulsos e partículas em viagem da rede (OPE-109), lidos pelos nodes e arestas do React Flow. */\ninterface NetworkLive {\n pulses: Record<string, number>\n travels: Travel[]\n finish: (id: string) => void\n}\n\nconst EMPTY: NetworkLive = { pulses: {}, travels: [], finish: () => undefined }\nexport const NetworkLiveContext = createContext<NetworkLive>(EMPTY)\n\nexport function NetworkLiveProvider({ value, children }: { value: NetworkLive; children: React.ReactNode }) {\n return <NetworkLiveContext.Provider value={value}>{children}</NetworkLiveContext.Provider>\n}\n\n/** Anel que pulsa uma vez a cada consumo (a chave remonta a animação). */\nexport function PulseRing({ nodeKey, className }: { nodeKey: string; className?: string }) {\n const count = useContext(NetworkLiveContext).pulses[nodeKey] ?? 0\n if (!count) return null\n return (\n <motion.span\n key={count}\n data-testid={`pulse-${nodeKey}`}\n aria-hidden\n className={`pointer-events-none absolute inset-0 rounded-full border-2 border-primary ${className ?? \"\"}`}\n initial={{ scale: 1, opacity: 0.8 }}\n animate={{ scale: 1.9, opacity: 0 }}\n transition={{ duration: 0.6, ease: \"easeOut\" }}\n />\n )\n}\n\n/** Partículas que viajam pela aresta `edgeId` (caminho SVG `path`). */\nexport function TravelDots({ edgeId, path }: { edgeId: string; path: string }) {\n const { travels, finish } = useContext(NetworkLiveContext)\n const mine = useMemo(() => travels.filter((travel) => travel.edge === edgeId), [travels, edgeId])\n if (!mine.length) return null\n return (\n <>\n {mine.map((travel) => (\n <TravelDot key={travel.id} travel={travel} path={path} onDone={() => finish(travel.id)} />\n ))}\n </>\n )\n}\n\nconst TRAVEL_FILL: Record<Travel[\"tone\"], string> = { primary: \"fill-primary\", white: \"fill-foreground\", success: \"fill-[var(--color-success,var(--color-primary))]\" }\n\nfunction TravelDot({ travel, path, onDone }: { travel: Travel; path: string; onDone: () => void }) {\n return <PathTraveler path={path} reverse={travel.reverse} delayMs={travel.delayMs} radius={travel.tone === \"white\" ? 2.5 : 4} className={TRAVEL_FILL[travel.tone]} edge={travel.edge} tone={travel.tone} onDone={onDone} />\n}\n","\"use client\"\n\nimport { useEffect, useRef } from \"react\"\nimport { animate, motion, useMotionValue, useTransform } from \"framer-motion\"\n\n/**\n * Partícula que percorre um caminho SVG uma vez (Framer Motion) e avisa ao chegar. Usada nas redes do\n * Engramind (memórias viajando) e nos diagramas do Agente Arquiteto (pulso da aresta que nasce).\n */\nexport function PathTraveler({ path, reverse = false, delayMs = 0, durationMs = 900, radius = 4, className = \"fill-primary\", testId = \"travel-dot\", edge, tone, onDone }: { path: string; reverse?: boolean; delayMs?: number; durationMs?: number; radius?: number; className?: string; testId?: string; /** `data-edge` do grupo e `data-tone` do círculo (testes e estilo). */ edge?: string; tone?: string; onDone?: () => void }) {\n const ref = useRef<SVGPathElement>(null)\n const progress = useMotionValue(0)\n const point = (value: number) => {\n const element = ref.current\n if (!element || typeof element.getTotalLength !== \"function\") return { x: 0, y: 0 }\n const length = element.getTotalLength()\n const at = element.getPointAtLength((reverse ? 1 - value : value) * length)\n return { x: at.x, y: at.y }\n }\n const cx = useTransform(progress, (value) => point(value).x)\n const cy = useTransform(progress, (value) => point(value).y)\n useEffect(() => {\n const controls = animate(progress, 1, { duration: durationMs / 1000, delay: delayMs / 1000, ease: \"easeInOut\", onComplete: onDone })\n return () => controls.stop()\n // A viagem roda uma vez por partícula.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n return (\n <g data-testid={testId} data-edge={edge}>\n <path ref={ref} d={path} fill=\"none\" stroke=\"none\" />\n <motion.circle cx={cx} cy={cy} r={radius} className={className} data-tone={tone} />\n </g>\n )\n}\n","\"use client\"\n\nimport { useCallback, useSyncExternalStore } from \"react\"\n\n/**\n * Consulta de mídia reativa. Antes da primeira medição (SSR) devolve `false`, como o\n * `getServerSnapshot` exige; sem `matchMedia` no ambiente (jsdom de teste) também devolve `false`.\n */\nexport function useMediaQuery(query: string): boolean {\n const subscribe = useCallback(\n (onChange: () => void) => {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") return () => {}\n const list = window.matchMedia(query)\n // jsdom antigo só expõe `addListener`/`removeListener` (depreciados).\n if (typeof list.addEventListener === \"function\") list.addEventListener(\"change\", onChange)\n else list.addListener?.(onChange)\n return () => {\n if (typeof list.removeEventListener === \"function\") list.removeEventListener(\"change\", onChange)\n else list.removeListener?.(onChange)\n }\n },\n [query],\n )\n const getSnapshot = useCallback(\n () => (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\" ? false : window.matchMedia(query).matches),\n [query],\n )\n return useSyncExternalStore(subscribe, getSnapshot, () => false)\n}\n\n/** Consulta de celular: abaixo de `md` (768px). */\nexport const MOBILE_MEDIA_QUERY = \"(max-width: 767px)\"\n\n/**\n * Celular (`< md`). A tela de Tarefas troca a tabela por cards compactos aqui — por isso a\n * apresentação é escolhida em JS (só a ativa monta) e não apenas por classes responsivas.\n */\nexport function useIsMobile(): boolean {\n return useMediaQuery(MOBILE_MEDIA_QUERY)\n}\n","import type { CSSProperties } from \"react\"\nimport type { BackgroundVariant } from \"@xyflow/react\"\n\n/**\n * Tema dos canvas React Flow (rede do Engramind e outros canvas do app). Só tokens do tema do app\n * (`var(--color-*)` do Tailwind 4 e `color-mix`), sem cor fixa: a cor primária do app manda.\n *\n * O fundo segue o padrão das páginas (`bg-background`) com um brilho da cor primária bem suave no centro; o\n * React Flow fica transparente. O `colorMode=\"dark\"` da biblioteca pinta o canvas, o minimapa e os\n * controles de cinza neutro fixo por uma folha de estilo fora das camadas do Tailwind: as variáveis no\n * `style` do próprio elemento (`FLOW_THEME_STYLE`) vencem essa folha. Os tipos de nó reservados da\n * biblioteca (`group`, `default`, `input`, `output`) ganham classe com fundo, padding e borda próprios:\n * os canvas usam tipos com prefixo do domínio, e as variáveis abaixo neutralizam o que sobrar.\n *\n * Cor e espessura das arestas vão no `style` inline do `path`: a folha do React Flow é importada fora\n * das camadas do Tailwind, então a regra `.react-flow__edge-path { stroke; stroke-width }` vence\n * qualquer classe utilitária (`stroke-primary`) e o atributo `strokeWidth` do SVG.\n */\nexport const FLOW_SURFACE_CLASS = \"relative overflow-hidden rounded-xl border bg-background bg-[radial-gradient(ellipse_at_center,color-mix(in_oklab,var(--color-primary)_8%,transparent),transparent_70%)]\"\n\n/** Cor das linhas das arestas: a primária do tema (aplicar no `style` inline, ver acima). */\nexport const FLOW_EDGE_PRIMARY_STROKE = \"var(--color-primary)\"\n\nexport const FLOW_THEME_STYLE = {\n \"--xy-background-color\": \"transparent\",\n \"--xy-background-pattern-color\": \"color-mix(in oklab, var(--color-muted-foreground) 18%, transparent)\",\n \"--xy-edge-stroke\": \"var(--color-border)\",\n \"--xy-node-background-color\": \"transparent\",\n \"--xy-node-border\": \"0\",\n \"--xy-node-color\": \"var(--color-foreground)\",\n \"--xy-node-group-background-color\": \"transparent\",\n \"--xy-node-border-radius\": \"var(--radius)\",\n \"--xy-node-boxshadow-hover\": \"none\",\n \"--xy-node-boxshadow-selected\": \"0 0 0 1px color-mix(in oklab, var(--color-primary) 60%, transparent)\",\n \"--xy-minimap-background-color\": \"color-mix(in oklab, var(--color-card) 90%, transparent)\",\n \"--xy-minimap-mask-background-color\": \"color-mix(in oklab, var(--color-background) 60%, transparent)\",\n \"--xy-minimap-mask-stroke-color\": \"color-mix(in oklab, var(--color-primary) 40%, transparent)\",\n \"--xy-minimap-node-background-color\": \"color-mix(in oklab, var(--color-primary) 50%, transparent)\",\n \"--xy-minimap-node-stroke-color\": \"transparent\",\n \"--xy-controls-button-background-color\": \"color-mix(in oklab, var(--color-card) 90%, transparent)\",\n \"--xy-controls-button-background-color-hover\": \"color-mix(in oklab, var(--color-primary) 15%, transparent)\",\n \"--xy-controls-button-color\": \"var(--color-foreground)\",\n \"--xy-controls-button-color-hover\": \"var(--color-foreground)\",\n \"--xy-controls-button-border-color\": \"var(--color-border)\",\n \"--xy-controls-box-shadow\": \"none\",\n \"--xy-attribution-background-color\": \"transparent\",\n} as CSSProperties\n\n/** Pontos discretos do fundo (`<Background {...FLOW_BACKGROUND_PROPS} />`). */\nexport const FLOW_BACKGROUND_PROPS = { variant: \"dots\" as BackgroundVariant, gap: 28, size: 1 }\n","import { FLOW_SURFACE_CLASS, FLOW_THEME_STYLE } from \"../../../components/flow/flow-theme\"\n\n/** Dimensões compartilhadas pela rede e pelo skeleton (o skeleton acompanha a interface). */\n\n/** Fundo das redes no padrão do app (tema compartilhado dos canvas React Flow, `@/components/flow/flow-theme`). */\nexport const NETWORK_CANVAS_CLASS = `${FLOW_SURFACE_CLASS} h-[min(72dvh,44rem)] w-full max-md:h-[70dvh]`\n/** Tema do React Flow pelos tokens do app (variáveis no próprio elemento vencem a folha do `colorMode=\"dark\"`). */\nexport const NETWORK_FLOW_THEME = FLOW_THEME_STYLE\n/** Altura menor dos universos dentro dos cards de `/integracoes/ia` (no celular, quase a tela). */\nexport const NETWORK_CANVAS_COMPACT_CLASS = \"h-[28rem] max-md:h-[60dvh]\"\nexport const NETWORK_STATS_CLASS = \"pointer-events-auto absolute right-3 top-3 z-10 max-h-[calc(100%-1.5rem)] w-64 overflow-y-auto rounded-xl border bg-card/90 p-3 text-xs shadow-lg backdrop-blur max-md:left-3 max-md:w-auto\"\n/** Card de estatísticas recolhido (celular): um botão no canto com o resumo. */\nexport const NETWORK_STATS_TOGGLE_CLASS = \"pointer-events-auto absolute right-3 top-3 z-10 flex h-10 items-center gap-1.5 rounded-xl border bg-card/90 px-3 text-xs font-medium text-foreground shadow-lg backdrop-blur\"\n/** Área de toque mínima (40 px) dos botões sobre a rede no celular. */\nexport const NETWORK_TOUCH_BUTTON_CLASS = \"max-md:h-10 max-md:px-3\"\n/** Skeleton da visão inicial: área livre à esquerda do card de estatísticas, com o grupo de agentes e canais ao centro. */\nexport const NETWORK_SKELETON_AREA_CLASS = \"absolute inset-y-0 left-0 right-72 flex items-center justify-center max-md:right-0 max-md:overflow-hidden\"\n/** Card do agente na visão inicial: largura e altura fixas (as linhas de contagem não deslocam o layout, OPE-117). */\nexport const AGENT_NODE_SIZE_CLASS = \"w-[11.25rem] h-16\"\n","\"use client\"\n\nimport { createContext, memo, useContext, useEffect, useState } from \"react\"\nimport type { Node, NodeProps } from \"@xyflow/react\"\nimport { motion, useReducedMotion } from \"framer-motion\"\nimport { cn } from \"../../../lib/utils\"\nimport { repelOffset, type Point } from \"../../network/network-math\"\nimport type { ParticleVisual } from \"../../network/particles\"\nimport type { NetworkMemory } from \"../../network/types\"\nimport { PulseRing } from \"./live\"\nimport type { MemoryCardActions } from \"./MemoryCard\"\nimport { CenterHandles, LABEL_MIN_ZOOM, useZoom } from \"./nodes\"\nimport { usePositionSlide } from \"./usePositionSlide\"\n\n/** Zoom mínimo para o card abrir (visão afastada demais só destaca a partícula). */\nexport const CARD_MIN_ZOOM = 0.6\n\ninterface UniverseFocus {\n /** Memória com o card aberto (só por clique ou toque). */\n openId: string | null\n /** Foco do afastamento e do leve aumento: a aberta ou, sem card, a que está sob o cursor. */\n focusId: string | null\n focusPoint: Point | null\n hover: (id: string | null) => void\n actions: MemoryCardActions\n}\n\nexport const UniverseFocusContext = createContext<UniverseFocus | null>(null)\n\nexport type MemoryNodeData = {\n memory: NetworkMemory\n visual: ParticleVisual\n point: Point\n /** `false` = apagada pela busca/filtros; `null` = sem filtro. */\n matched: boolean | null\n leaving?: boolean\n /** Memória que acabou de chegar: nasce do centro com o link se desenhando. */\n entering?: boolean\n}\n\n/** Partícula: nasce do centro do universo (memória nova), desliza quando a órbita muda e some (opacidade 0) enquanto vira o card. */\nexport const MemoryNode = memo(function MemoryNode({ data }: NodeProps<Node<MemoryNodeData, \"memory\">>) {\n const focus = useContext(UniverseFocusContext)\n const zoom = useZoom()\n const reducedMotion = useReducedMotion()\n const { memory, visual, point } = data\n const isFocused = focus?.focusId === memory.id\n const expanded = focus?.openId === memory.id && zoom >= CARD_MIN_ZOOM\n const offset = !isFocused && focus?.focusPoint ? repelOffset(point, focus.focusPoint) : { x: 0, y: 0 }\n const glow = visual.archived ? 0 : Math.round(4 + 14 * visual.brightness)\n const dimmed = data.matched === false\n const ready = useAfterMeasure()\n const slide = usePositionSlide(point, reducedMotion === true)\n // Nascimento: começa no centro (0,0 da rede), invisível e sem tamanho, até a própria órbita.\n const born = data.entering && !reducedMotion\n const hidden = { scale: 0, opacity: 0, x: born ? -point.x : 0, y: born ? -point.y : 0 }\n const shown = { scale: data.leaving ? 0 : isFocused && !expanded ? 1.35 : 1, opacity: data.leaving || expanded ? 0 : dimmed ? 0.18 : 1, x: offset.x, y: offset.y }\n return (\n <motion.div style={{ x: slide.x, y: slide.y }} className=\"relative\">\n <motion.div\n data-testid={`memory-node-${memory.id}`}\n data-brightness={visual.brightness}\n data-pinned={visual.pinned || undefined}\n data-archived={visual.archived || undefined}\n data-expanded={expanded || undefined}\n data-focused={isFocused || undefined}\n data-entering={data.entering || undefined}\n data-matched={data.matched === null ? undefined : String(data.matched)}\n className=\"relative\"\n initial={hidden}\n animate={ready ? shown : hidden}\n transition={born ? { type: \"spring\", stiffness: 140, damping: 18, mass: 0.9 } : { duration: expanded ? 0.12 : 0.22 }}\n // O card abre só pelo clique/toque; passar o mouse (fora do toque) só afasta as vizinhas.\n onPointerEnter={(event) => event.pointerType !== \"touch\" && focus?.hover(memory.id)}\n onPointerLeave={(event) => event.pointerType !== \"touch\" && focus?.hover(null)}\n >\n <span\n aria-label={memory.title}\n className={cn(\"relative block cursor-pointer rounded-full\", visual.pinned && \"ring-2 ring-primary ring-offset-1 ring-offset-background\", visual.archived && \"border border-dashed border-muted-foreground bg-transparent\")}\n style={{ width: visual.size, height: visual.size, background: visual.archived ? \"transparent\" : visual.color, boxShadow: glow ? `0 0 ${glow}px ${visual.color}` : \"none\" }}\n >\n <PulseRing nodeKey={`memory:${memory.id}`} />\n <CenterHandles />\n </span>\n {zoom >= LABEL_MIN_ZOOM * 2 && !isFocused && <span className=\"pointer-events-none absolute left-1/2 top-full mt-1 w-28 -translate-x-1/2 truncate text-center text-[9px] text-muted-foreground\">{memory.title}</span>}\n </motion.div>\n </motion.div>\n )\n})\n\n/**\n * O React Flow monta o node invisível e só o mostra depois de medi-lo: a animação de entrada espera\n * dois quadros para não rodar escondida.\n */\nfunction useAfterMeasure(): boolean {\n const [ready, setReady] = useState(false)\n useEffect(() => {\n let second = 0\n const first = requestAnimationFrame(() => {\n second = requestAnimationFrame(() => setReady(true))\n })\n return () => {\n cancelAnimationFrame(first)\n cancelAnimationFrame(second)\n }\n }, [])\n return ready\n}\n\n","\"use client\"\n\nimport { memo } from \"react\"\nimport { motion, useReducedMotion } from \"framer-motion\"\nimport { Handle, Position, useStore, type Node, type NodeProps } from \"@xyflow/react\"\nimport { AppWindow, Archive, Hash, MoreHorizontal, type LucideIcon } from \"lucide-react\"\nimport { Button } from \"../../../components/ui/button\"\nimport { cn } from \"../../../lib/utils\"\nimport { AgentIcon } from \"./agent-icons\"\nimport { ChannelName } from \"./ChannelName\"\nimport { AGENT_NODE_SIZE_CLASS } from \"./layout-classes\"\nimport { PulseRing } from \"./live\"\nimport { usePositionSlide } from \"./usePositionSlide\"\nimport type { Point } from \"../../network/network-math\"\n\n/** Zoom abaixo do qual os rótulos somem (visão muito afastada). */\nexport const LABEL_MIN_ZOOM = 0.45\nexport const useZoom = () => useStore((state) => state.transform[2])\n\nconst HANDLE_STYLE: React.CSSProperties = { left: \"50%\", top: \"50%\", width: 1, height: 1, minWidth: 0, minHeight: 0, opacity: 0, border: 0, transform: \"translate(-50%, -50%)\", pointerEvents: \"none\" }\n\n/** Arestas saem e chegam pelo centro do node (o caminho é desenhado pela própria aresta). */\nexport function CenterHandles() {\n return (\n <>\n <Handle type=\"source\" position={Position.Right} style={HANDLE_STYLE} isConnectable={false} />\n <Handle type=\"target\" position={Position.Left} style={HANDLE_STYLE} isConnectable={false} />\n </>\n )\n}\n\n/** Visão inicial (OPE-113): `scale` pelo tamanho (alcance do agente, memórias do canal) e `point` (desliza ao trocar a distribuição). */\ntype OverviewNodeLook = { scale?: number; point?: Point }\n\n/** Card da visão inicial escalado a partir do centro, deslizando quando a posição muda. */\nfunction OverviewNodeShell({ look, children }: { look: OverviewNodeLook; children: React.ReactNode }) {\n const reducedMotion = useReducedMotion()\n const slide = usePositionSlide(look.point ?? ORIGIN, reducedMotion === true, 0.3)\n const scale = look.scale ?? 1\n return (\n <motion.div style={{ x: slide.x, y: slide.y }} data-scale={scale}>\n <div style={scale === 1 ? undefined : { transform: `scale(${scale})`, transformOrigin: \"center\" }}>{children}</div>\n <CenterHandles />\n </motion.div>\n )\n}\nconst ORIGIN: Point = { x: 0, y: 0 }\n\nexport type AgentNodeData = {\n id: string\n name: string\n app: string\n dimmed?: boolean\n /** Memórias que o agente gravou (auditoria do Opex; só agentes do Opex): total e últimos 7 dias. */\n written?: { total: number; last7d: number } | null\n /** Memórias ativas dos canais que ele lê (soma das assinaturas). */\n reachable?: number\n} & OverviewNodeLook\n\nconst plural = (count: number, one: string, many: string) => `${count} ${count === 1 ? one : many}`\n\n/** \"N gravadas · M acessíveis\" no padrão da linha \"N memórias\" do canal (zero explícito). */\nfunction AgentCounts({ data }: { data: AgentNodeData }) {\n const reachable = data.reachable ?? 0\n return (\n <span className=\"truncate text-[10px] text-muted-foreground\" data-testid={`agent-counts-${data.id}`}>\n {data.written && (\n <span title={`${data.written.last7d} nos últimos 7 dias`} data-testid={`agent-written-${data.id}`}>\n {plural(data.written.total, \"gravada\", \"gravadas\")} ·{\" \"}\n </span>\n )}\n <span data-testid={`agent-reachable-${data.id}`}>{plural(reachable, \"acessível\", \"acessíveis\")}</span>\n </span>\n )\n}\n\nexport const AgentNode = memo(function AgentNode({ data }: NodeProps<Node<AgentNodeData, \"agent\">>) {\n const showLabel = useZoom() >= LABEL_MIN_ZOOM\n return (\n <OverviewNodeShell look={data}>\n <div data-testid={`agent-node-${data.id}`} data-scale={data.scale ?? 1} title={data.id} className={cn(\"relative flex cursor-pointer items-center gap-2 rounded-full border border-primary/40 bg-card px-3 py-2 shadow-sm transition-opacity hover:border-primary\", AGENT_NODE_SIZE_CLASS, data.dimmed && \"opacity-40\")}>\n <PulseRing nodeKey={`agent:${data.id}`} />\n <span className=\"flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-primary/15 text-primary\">\n <AgentIcon agent={data.id} className=\"h-4 w-4\" />\n </span>\n {showLabel && (\n <span className=\"flex min-w-0 flex-col leading-tight\">\n <span className=\"truncate text-sm font-medium text-foreground\">{data.name}</span>\n <span className=\"truncate text-[10px] text-muted-foreground\">{data.app}</span>\n <AgentCounts data={data} />\n </span>\n )}\n </div>\n </OverviewNodeShell>\n )\n})\n\nexport type AppNodeData = {\n slug: string\n name: string\n /** Agentes ativos do app. */\n agents: number\n /** Memórias ativas dos canais que os agentes do app assinam. */\n reachable: number\n} & OverviewNodeLook\n\n/** Card do app na visão inicial Apps x canais (OPE-129): mesmas dimensões do card do agente. */\nexport const AppNode = memo(function AppNode({ data }: NodeProps<Node<AppNodeData, \"app\">>) {\n const showLabel = useZoom() >= LABEL_MIN_ZOOM\n return (\n <OverviewNodeShell look={data}>\n <div data-testid={`app-node-${data.slug}`} data-scale={data.scale ?? 1} title={data.slug} className={cn(\"relative flex cursor-pointer items-center gap-2 rounded-full border border-primary/40 bg-card px-3 py-2 shadow-sm transition-opacity hover:border-primary\", AGENT_NODE_SIZE_CLASS)}>\n <PulseRing nodeKey={`app:${data.slug}`} />\n <span className=\"flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-primary/15 text-primary\">\n <AppWindow className=\"h-4 w-4\" aria-hidden />\n </span>\n {showLabel && (\n <span className=\"flex min-w-0 flex-col leading-tight\">\n <span className=\"truncate text-sm font-medium text-foreground\">{data.name}</span>\n <span className=\"truncate text-[10px] text-muted-foreground\">{data.slug}</span>\n <span className=\"truncate text-[10px] text-muted-foreground\" data-testid={`app-counts-${data.slug}`}>\n {plural(data.agents, \"agente\", \"agentes\")} · {plural(data.reachable, \"acessível\", \"acessíveis\")}\n </span>\n </span>\n )}\n </div>\n </OverviewNodeShell>\n )\n})\n\nexport type ChannelNodeData = { slug: string; name: string; count: number; archived: boolean; hits?: number | null; dimmed?: boolean; onMenu?: (slug: string) => void } & OverviewNodeLook\n\nexport const ChannelNode = memo(function ChannelNode({ data }: NodeProps<Node<ChannelNodeData, \"channel\">>) {\n const showLabel = useZoom() >= LABEL_MIN_ZOOM\n return (\n <OverviewNodeShell look={data}>\n <div\n data-testid={`channel-node-${data.slug}`}\n data-scale={data.scale ?? 1}\n data-archived={data.archived || undefined}\n className={cn(\"relative flex min-w-48 max-w-72 cursor-pointer items-center gap-2 rounded-xl border bg-card px-3 py-2 shadow-sm transition-opacity hover:border-primary\", data.archived && \"border-dashed opacity-60\", data.dimmed && \"opacity-30\")}\n >\n <PulseRing nodeKey={`channel:${data.slug}`} className=\"rounded-xl\" />\n <span className=\"flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-muted text-muted-foreground\">{data.archived ? <Archive className=\"h-4 w-4\" aria-hidden /> : <Hash className=\"h-4 w-4\" aria-hidden />}</span>\n {showLabel && (\n <span className=\"flex min-w-0 flex-1 flex-col leading-tight\">\n <ChannelName slug={data.slug} />\n <span className=\"truncate text-[10px] text-muted-foreground\">\n {data.count} {data.count === 1 ? \"memória\" : \"memórias\"}\n {typeof data.hits === \"number\" && <span className=\"ml-1 font-semibold text-primary\">· {data.hits} na busca</span>}\n </span>\n </span>\n )}\n {data.onMenu && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n aria-label={`Ações do canal ${data.slug}`}\n className=\"nodrag nopan h-7 w-7 text-muted-foreground max-md:h-9 max-md:w-9\"\n onClick={(event) => {\n event.stopPropagation()\n data.onMenu?.(data.slug)\n }}\n >\n <MoreHorizontal className=\"h-4 w-4\" aria-hidden />\n </Button>\n )}\n </div>\n </OverviewNodeShell>\n )\n})\n\nexport type CenterNodeData = {\n label: string\n detail: string\n icon: LucideIcon\n pulseKey: string\n archived?: boolean\n /** Universo do canal: o nome sai em duas linhas (`ChannelName`). */\n channelSlug?: string\n}\n\nexport const CenterNode = memo(function CenterNode({ data }: NodeProps<Node<CenterNodeData, \"center\">>) {\n const Icon = data.icon\n return (\n <div data-testid=\"universe-center\" className={cn(\"relative flex flex-col items-center gap-1\", data.archived && \"opacity-60\")}>\n <span className={cn(\"relative flex h-16 w-16 items-center justify-center rounded-full border-2 border-primary bg-primary/20 text-primary shadow-[0_0_32px] shadow-primary/40\", data.archived && \"border-dashed\")}>\n <PulseRing nodeKey={data.pulseKey} />\n <Icon className=\"h-7 w-7\" aria-hidden />\n <CenterHandles />\n </span>\n {data.channelSlug ? (\n <span className=\"flex max-w-72 flex-col items-center rounded-md bg-card/80 px-2 text-center\">\n <ChannelName slug={data.channelSlug} size=\"center\" className=\"items-center\" titleClassName=\"font-semibold\" />\n </span>\n ) : (\n <span className=\"max-w-56 truncate rounded-md bg-card/80 px-2 text-sm font-semibold text-foreground\">{data.label}</span>\n )}\n <span className=\"text-[10px] text-muted-foreground\">{data.detail}</span>\n </div>\n )\n})\n","\"use client\"\n\nimport { useLayoutEffect, useRef } from \"react\"\nimport { animate, useMotionValue } from \"framer-motion\"\nimport type { Point } from \"../../network/network-math\"\n\n/**\n * O node mudou de posição (órbita recalculada, troca de distribuição): desliza da posição antiga para a\n * nova (deslocamento animado até zero). Com movimento reduzido, a troca é instantânea.\n */\nexport function usePositionSlide(point: Point, reduced: boolean, duration = 0.45) {\n const x = useMotionValue(0)\n const y = useMotionValue(0)\n const previous = useRef(point)\n useLayoutEffect(() => {\n const before = previous.current\n previous.current = point\n if (reduced || (before.x === point.x && before.y === point.y)) return\n x.set(before.x - point.x + x.get())\n y.set(before.y - point.y + y.get())\n const controls = [animate(x, 0, { duration, ease: \"easeInOut\" }), animate(y, 0, { duration, ease: \"easeInOut\" })]\n return () => controls.forEach((control) => control.stop())\n }, [point, reduced, x, y, duration])\n return { x, y }\n}\n","\"use client\"\n\nimport { Panel } from \"@xyflow/react\"\nimport { Crosshair } from \"lucide-react\"\nimport { Button } from \"../../../components/ui/button\"\nimport { cn } from \"../../../lib/utils\"\nimport { NETWORK_TOUCH_BUTTON_CLASS } from \"./layout-classes\"\nimport { useRecenter } from \"./NetworkCanvas\"\n\n/** \"Centralizar\": reenquadra a visão (dentro do canvas, onde o React Flow está disponível). */\nexport function RecenterButton() {\n const recenter = useRecenter()\n return (\n <Panel position=\"bottom-right\">\n <Button type=\"button\" size=\"sm\" variant=\"outline\" className={cn(\"bg-card/90\", NETWORK_TOUCH_BUTTON_CLASS)} onClick={recenter}>\n <Crosshair className=\"mr-1.5 h-4 w-4\" aria-hidden /> Centralizar\n </Button>\n </Panel>\n )\n}\n","\"use client\"\n\nimport { Panel } from \"@xyflow/react\"\nimport { Brain, Plus } from \"lucide-react\"\nimport { Button } from \"../../../components/ui/button\"\nimport { cn } from \"../../../lib/utils\"\nimport { NETWORK_TOUCH_BUTTON_CLASS } from \"./layout-classes\"\n\n/** Ação de criar no canto (universo com memórias) e o estado vazio com a mesma ação. */\nexport function UniversePanels({ count, onCreate, createLabel, emptyTitle }: { count: number; onCreate?: (() => void) | null; createLabel?: string; emptyTitle: string }) {\n return (\n <>\n {onCreate && createLabel && count > 0 && (\n <Panel position=\"top-left\">\n <Button type=\"button\" size=\"sm\" variant=\"outline\" className={cn(\"bg-card/90\", NETWORK_TOUCH_BUTTON_CLASS)} onClick={onCreate}>\n <Plus className=\"mr-1 h-4 w-4\" aria-hidden /> {createLabel}\n </Button>\n </Panel>\n )}\n {count === 0 && (\n <Panel position=\"bottom-center\" className=\"!mb-10\">\n <div className=\"flex flex-col items-center gap-2 rounded-xl border bg-card/90 p-4 text-center shadow\" data-testid=\"universe-empty\">\n <Brain className=\"h-6 w-6 text-muted-foreground\" aria-hidden />\n <p className=\"text-sm font-medium\">{emptyTitle}</p>\n {onCreate && (\n <Button type=\"button\" size=\"sm\" variant=\"outline\" className={NETWORK_TOUCH_BUTTON_CLASS} onClick={onCreate}>\n <Plus className=\"mr-1 h-4 w-4\" aria-hidden /> Nova memória\n </Button>\n )}\n </div>\n </Panel>\n )}\n </>\n )\n}\n","\"use client\"\n\nimport { useMemo } from \"react\"\nimport { format } from \"date-fns\"\nimport { ptBR } from \"date-fns/locale\"\nimport { universeStats } from \"../../network/network-math\"\nimport type { ParticleVisual } from \"../../network/particles\"\nimport type { NetworkMemory } from \"../../network/types\"\nimport { ChannelName } from \"./ChannelName\"\nimport { StatList, StatsCard, type StatRow } from \"./StatsCard\"\n\n/** Estatísticas do universo (canal ou agente); no do agente, a legenda \"Por canal\" com a cor de cada um. */\nexport function UniverseStatsCard({\n kind,\n memories,\n visuals,\n subscribers,\n liveCount,\n channelColors,\n}: {\n kind: \"channel\" | \"agent\"\n memories: NetworkMemory[]\n visuals: Map<string, ParticleVisual>\n subscribers?: number\n liveCount: number\n channelColors?: Map<string, string>\n}) {\n const brightness = useMemo(() => new Map([...visuals].map(([id, visual]) => [id, visual.brightness])), [visuals])\n const stats = universeStats(memories, brightness)\n const rows: StatRow[] = [\n { label: \"Ativas\", value: stats.active, testId: \"stat-active\" },\n { label: \"Inativas\", value: stats.inactive, testId: \"stat-inactive\" },\n { label: \"Fixadas\", value: stats.pinned, testId: \"stat-pinned\" },\n { label: \"Consultas + injeções\", value: stats.uses, testId: \"stat-uses\" },\n { label: \"Última consulta\", value: stats.lastUse ? format(new Date(stats.lastUse), \"dd/MM HH:mm\", { locale: ptBR }) : \"nunca\", testId: \"stat-last-use\" },\n ...(typeof subscribers === \"number\" ? [{ label: \"Assinantes\", value: subscribers, testId: \"stat-subscribers\" }] : []),\n { label: \"Esquecidas (cinza)\", value: stats.forgotten, testId: \"stat-forgotten\" },\n ...(liveCount ? [{ label: \"Consumos ao vivo\", value: liveCount, testId: \"stat-live\" }] : []),\n ]\n return (\n <StatsCard title={kind === \"agent\" ? \"Universo do agente\" : \"Universo do canal\"} rows={rows} summary={`${memories.length} ${memories.length === 1 ? \"memória\" : \"memórias\"}`}>\n {kind === \"agent\" && (\n <p className=\"mt-3 flex items-center gap-1.5 border-t pt-2 text-muted-foreground\" data-testid=\"authored-link-legend\">\n <span aria-hidden className=\"h-[3px] w-4 shrink-0 rounded-full bg-foreground/70\" />\n Link destacado: memória escrita por este agente\n </p>\n )}\n {kind === \"agent\" && (\n <StatList\n title=\"Por canal\"\n testId=\"channel-legend\"\n colors={channelColors}\n items={stats.byChannel.map((item) => ({ key: item.slug, label: item.slug, count: item.count, node: <ChannelName slug={item.slug} size=\"legend\" className=\"flex-1\" titleClassName=\"text-muted-foreground\" /> }))}\n />\n )}\n </StatsCard>\n )\n}\n","\"use client\"\n\nimport { useState } from \"react\"\nimport { AnimatePresence, motion } from \"framer-motion\"\nimport { BarChart3, X } from \"lucide-react\"\nimport { AnimatedNumber } from \"../../../components/motion/AnimatedNumber\"\nimport { Button } from \"../../../components/ui/button\"\nimport { useIsMobile } from \"../../../hooks/useMediaQuery\"\nimport { NETWORK_STATS_CLASS, NETWORK_STATS_TOGGLE_CLASS } from \"./layout-classes\"\n\nexport interface StatRow {\n label: string\n value: number | string\n testId?: string\n}\n\n/**\n * Card de estatísticas do que está sendo visto (todas as visões); números animados. No celular começa\n * recolhido num botão com o `summary` (o card aberto cobriria a rede) e abre por cima do quadro.\n */\nexport function StatsCard({ title, rows, summary, children }: { title: string; rows: StatRow[]; summary?: string; children?: React.ReactNode }) {\n const mobile = useIsMobile()\n const [open, setOpen] = useState(false)\n const card = (\n <section aria-label=\"Estatísticas\" data-testid=\"network-stats\" className={NETWORK_STATS_CLASS}>\n <h3 className=\"mb-2 flex items-center gap-1.5 text-xs font-semibold text-foreground\">\n <BarChart3 className=\"h-3.5 w-3.5 text-primary\" aria-hidden /> {title}\n {mobile && (\n <Button type=\"button\" variant=\"ghost\" size=\"icon\" aria-label=\"Recolher estatísticas\" className=\"ml-auto h-8 w-8\" onClick={() => setOpen(false)}>\n <X className=\"h-4 w-4\" aria-hidden />\n </Button>\n )}\n </h3>\n <dl className=\"grid grid-cols-[1fr_auto] gap-x-3 gap-y-1\">\n {rows.map((row) => (\n <div key={row.label} className=\"contents\">\n <dt className=\"text-muted-foreground\">{row.label}</dt>\n <dd className=\"text-right font-medium tabular-nums text-foreground\" data-testid={row.testId} data-value={row.value}>\n {typeof row.value === \"number\" ? <AnimatedNumber value={row.value} /> : row.value}\n </dd>\n </div>\n ))}\n </dl>\n {children}\n </section>\n )\n if (!mobile) return card\n return (\n <AnimatePresence initial={false} mode=\"wait\">\n {open ? (\n <motion.div key=\"open\" initial={{ opacity: 0, scale: 0.96 }} animate={{ opacity: 1, scale: 1 }} exit={{ opacity: 0, scale: 0.96 }} transition={{ duration: 0.18 }} style={{ transformOrigin: \"top right\" }}>\n {card}\n </motion.div>\n ) : (\n <motion.button\n key=\"closed\"\n type=\"button\"\n data-testid=\"network-stats-toggle\"\n aria-label={`Abrir estatísticas: ${title}`}\n aria-expanded={false}\n className={NETWORK_STATS_TOGGLE_CLASS}\n initial={{ opacity: 0, scale: 0.9 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.9 }}\n transition={{ duration: 0.15 }}\n onClick={() => setOpen(true)}\n >\n <BarChart3 className=\"h-4 w-4 text-primary\" aria-hidden /> {summary ?? title}\n </motion.button>\n )}\n </AnimatePresence>\n )\n}\n\n/** Lista \"nome → total\" (por canal, por agente) dentro do card. */\nexport function StatList({ title, items, colors, testId }: { title: string; items: { key: string; label: string; count: number; node?: React.ReactNode }[]; colors?: Map<string, string>; testId?: string }) {\n if (!items.length) return null\n return (\n <div className=\"mt-3 border-t pt-2\" data-testid={testId}>\n <p className=\"mb-1 font-semibold text-foreground\">{title}</p>\n <ul className=\"max-h-40 space-y-0.5 overflow-y-auto pr-1\">\n {items.map((item) => (\n <li key={item.key} className=\"flex items-center gap-1.5\">\n {colors && <span aria-hidden className=\"h-2 w-2 shrink-0 rounded-full\" style={{ background: colors.get(item.key) }} />}\n {/* `node`: conteúdo no lugar do rótulo (ex.: `ChannelName`). */}\n {item.node ?? (\n <span className=\"min-w-0 flex-1 truncate text-muted-foreground\" title={item.label}>\n {item.label}\n </span>\n )}\n <span className=\"tabular-nums text-foreground\">\n <AnimatedNumber value={item.count} />\n </span>\n </li>\n ))}\n </ul>\n </div>\n )\n}\n","\"use client\"\n\nimport { useEffect, useState } from \"react\"\nimport { animate, useMotionValue, useReducedMotion } from \"framer-motion\"\n\ninterface AnimatedNumberProps {\n value: number\n formatter?: (value: number) => string\n className?: string\n duration?: number\n}\n\nconst defaultFormatter = (value: number) => Math.round(value).toLocaleString(\"pt-BR\")\n\n/** Número que anima entre valores (copiado do Smart Desk); respeita movimento reduzido. */\nexport function AnimatedNumber({ value, formatter = defaultFormatter, className, duration = 0.45 }: AnimatedNumberProps) {\n const motionValue = useMotionValue(value)\n const reduceMotion = useReducedMotion()\n const [displayValue, setDisplayValue] = useState(value)\n\n useEffect(() => {\n const controls = animate(motionValue, value, {\n duration: reduceMotion ? 0 : duration,\n ease: \"easeOut\",\n onUpdate: (latest) => setDisplayValue(latest),\n })\n return () => controls.stop()\n }, [value, duration, motionValue, reduceMotion])\n\n return <span className={className}>{formatter(displayValue)}</span>\n}\n","\"use client\"\n\nimport { useEffect, useRef, useState } from \"react\"\n\n/** Duração do nascimento de uma memória nova (partícula + link). */\nexport const ENTER_MS = 600\n\n/**\n * Ids que acabaram de chegar ao universo (memória criada ou movida para cá depois da primeira\n * carga): ficam marcados por `ENTER_MS` para o nascimento animado. A primeira leitura não conta.\n * `isProvisional`: uma memória provisória da lista otimista (`pendente-…`) que vira a definitiva já\n * nasceu, e a definitiva herda o estado em vez de nascer de novo.\n */\nexport function useEnteringIds(ids: readonly string[], options: { isProvisional?: (id: string) => boolean; onEnter?: (ids: string[]) => void } = {}): ReadonlySet<string> {\n const known = useRef<Set<string> | null>(null)\n const previous = useRef<readonly string[]>([])\n const timers = useRef<ReturnType<typeof setTimeout>[]>([])\n const optionsRef = useRef(options)\n const [entering, setEntering] = useState<ReadonlySet<string>>(() => new Set())\n\n useEffect(() => {\n optionsRef.current = options\n })\n useEffect(() => {\n const pending = timers.current\n return () => pending.forEach(clearTimeout)\n }, [])\n\n useEffect(() => {\n const before = previous.current\n previous.current = ids\n if (known.current === null) {\n known.current = new Set(ids)\n return\n }\n const seen = known.current\n let fresh = ids.filter((id) => !seen.has(id))\n for (const id of ids) seen.add(id)\n const { isProvisional, onEnter } = optionsRef.current\n if (isProvisional) {\n const current = new Set(ids)\n const resolved = before.filter((id) => isProvisional(id) && !current.has(id)).length\n fresh = fresh.slice(resolved)\n }\n if (!fresh.length) return\n onEnter?.(fresh)\n setEntering((set) => new Set([...set, ...fresh]))\n timers.current.push(\n setTimeout(() => {\n setEntering((set) => {\n const next = new Set(set)\n for (const id of fresh) next.delete(id)\n return next\n })\n }, ENTER_MS),\n )\n }, [ids])\n\n return entering\n}\n","\"use client\"\n\nimport { useEffect, useMemo, useRef, useState } from \"react\"\n\nexport const LEAVE_MS = 260\n\n/**\n * Mantém por um instante os itens que saíram da lista (marcados `leaving`) para a animação de\n * saída das partículas; o React Flow removeria o node na hora.\n */\nexport function useLeavingItems<T extends { id: string }>(items: readonly T[], onRemoved?: (ids: string[]) => void): (T & { leaving?: boolean })[] {\n const previous = useRef<Map<string, T>>(new Map())\n const [leaving, setLeaving] = useState<Map<string, T>>(new Map())\n const onRemovedRef = useRef(onRemoved)\n useEffect(() => {\n onRemovedRef.current = onRemoved\n }, [onRemoved])\n // Um timer por item que sai, independente do ciclo do efeito: uma nova referência de `items`\n // dentro de `LEAVE_MS` não cancela a limpeza (senão o item ficaria \"saindo\" para sempre).\n const timers = useRef<Map<string, ReturnType<typeof setTimeout>>>(new Map())\n useEffect(() => {\n const pending = timers.current\n return () => {\n for (const timer of pending.values()) clearTimeout(timer)\n pending.clear()\n }\n }, [])\n useEffect(() => {\n const current = new Map(items.map((item) => [item.id, item]))\n const gone = [...previous.current.values()].filter((item) => !current.has(item.id))\n previous.current = current\n if (!gone.length) return\n onRemovedRef.current?.(gone.map((item) => item.id))\n setLeaving((map) => new Map([...map, ...gone.map((item) => [item.id, item] as const)]))\n for (const item of gone) {\n const existing = timers.current.get(item.id)\n if (existing) clearTimeout(existing)\n timers.current.set(\n item.id,\n setTimeout(() => {\n timers.current.delete(item.id)\n setLeaving((map) => {\n if (!map.has(item.id)) return map\n const next = new Map(map)\n next.delete(item.id)\n return next\n })\n }, LEAVE_MS),\n )\n }\n }, [items])\n // Mesma referência enquanto nada sai: o layout e os nodes só recalculam quando os dados mudam.\n return useMemo(() => {\n if (!leaving.size) return items as (T & { leaving?: boolean })[]\n const present = new Set(items.map((item) => item.id))\n return [...items, ...[...leaving.values()].filter((item) => !present.has(item.id)).map((item) => ({ ...item, leaving: true }))]\n }, [items, leaving])\n}\n","\"use client\"\n\nimport { useMemo, useState } from \"react\"\nimport type { Edge, Node } from \"@xyflow/react\"\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => typeof value === \"object\" && value !== null && Object.getPrototypeOf(value) === Object.prototype\n\n/** Igualdade rasa; com `depth > 0`, objetos simples dentro também são comparados raso a raso. */\nexport function shallowEqualDeep(a: unknown, b: unknown, depth = 1): boolean {\n if (Object.is(a, b)) return true\n if (!isPlainObject(a) || !isPlainObject(b)) return false\n const keys = Object.keys(a)\n if (keys.length !== Object.keys(b).length) return false\n return keys.every((key) => Object.prototype.hasOwnProperty.call(b, key) && (depth > 0 ? shallowEqualDeep(a[key], b[key], depth - 1) : Object.is(a[key], b[key])))\n}\n\n/**\n * Reaproveita o objeto anterior de cada node (ou aresta) quando nada dele mudou (OPE-113). O React Flow\n * trata objeto novo como node ainda não medido: zera a medida e o esconde até medir de novo, o que\n * aparece como piscada. Hover, foco e card aberto chegam por contexto, nunca pelo array.\n */\nexport function useStable<T extends Node | Edge>(items: T[], depth = 3): T[] {\n // Cache mutável e estável (o objeto do estado nunca é trocado): o último objeto entregue por id.\n const [cache] = useState(() => new Map<string, T>())\n return useMemo(() => {\n const seen = new Set<string>()\n const result = items.map((item) => {\n seen.add(item.id)\n const old = cache.get(item.id)\n if (old && shallowEqualDeep(old, item, depth)) return old\n cache.set(item.id, item)\n return item\n })\n for (const id of [...cache.keys()]) if (!seen.has(id)) cache.delete(id)\n return result\n }, [items, cache, depth])\n}\n","\"use client\"\n\nimport { AnimatePresence, motion } from \"framer-motion\"\nimport { ArrowLeft, ChevronRight, Network } from \"lucide-react\"\nimport { Button } from \"../../../components/ui/button\"\n\nexport interface BreadcrumbApp {\n label: string\n /** Abre o app (quando há um universo aberto por cima dele). */\n onOpen: () => void\n}\n\n/**\n * Trilha \"Rede › App X › Agente Y\" / \"Rede › Canal X\" com Voltar (o Esc também volta, um nível por\n * vez, OPE-129). No celular, só Voltar e o nome atual (cortado no fim). `actions` (Importar e Novo\n * canal) ficam à direita, na mesma linha.\n */\nexport function NetworkBreadcrumb({ app = null, current, onBack, onHome, actions }: { app?: BreadcrumbApp | null; current: { kind: \"channel\" | \"agent\"; label: string } | null; onBack: () => void; onHome?: () => void; actions?: React.ReactNode }) {\n const nested = current !== null || app !== null\n return (\n <nav aria-label=\"Trilha da rede\" className=\"flex min-h-8 min-w-0 items-center gap-2 text-sm\" data-testid=\"network-breadcrumb\">\n <AnimatePresence initial={false}>\n {nested && (\n <motion.span key=\"back\" className=\"shrink-0\" initial={{ opacity: 0, x: -6 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, x: -6 }} transition={{ duration: 0.15 }}>\n <Button type=\"button\" size=\"sm\" variant=\"outline\" className=\"max-md:h-10\" onClick={onBack}>\n <ArrowLeft className=\"mr-1 h-4 w-4\" aria-hidden /> Voltar\n </Button>\n </motion.span>\n )}\n </AnimatePresence>\n {nested ? (\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" className=\"gap-1 px-2 text-muted-foreground max-md:hidden\" onClick={onHome ?? onBack}>\n <Network className=\"h-4 w-4\" aria-hidden /> Rede\n </Button>\n ) : (\n <span className=\"flex items-center gap-1 font-medium text-foreground\">\n <Network className=\"h-4 w-4\" aria-hidden /> Rede\n </span>\n )}\n {app && (\n <motion.span key=\"app\" className={current ? \"flex min-w-0 items-center gap-2 max-md:hidden\" : \"flex min-w-0 items-center gap-2\"} initial={{ opacity: 0, x: -6 }} animate={{ opacity: 1, x: 0 }} transition={{ duration: 0.15 }}>\n <ChevronRight className=\"h-4 w-4 shrink-0 text-muted-foreground max-md:hidden\" aria-hidden />\n {current ? (\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" className=\"px-2 text-muted-foreground max-md:hidden\" data-testid=\"breadcrumb-app\" onClick={app.onOpen}>\n App {app.label}\n </Button>\n ) : (\n <span className=\"min-w-0 truncate font-medium text-foreground\" data-testid=\"breadcrumb-current\">\n App {app.label}\n </span>\n )}\n </motion.span>\n )}\n {current && (\n <>\n <ChevronRight className=\"h-4 w-4 shrink-0 text-muted-foreground max-md:hidden\" aria-hidden />\n <span className=\"min-w-0 truncate font-medium text-foreground\" data-testid=\"breadcrumb-current\">\n {current.kind === \"channel\" ? \"Canal\" : \"Agente\"} {current.label}\n </span>\n </>\n )}\n {actions}\n </nav>\n )\n}\n","import { Skeleton } from \"../../../components/ui/skeleton\"\nimport { cn } from \"../../../lib/utils\"\nimport { AGENT_NODE_SIZE_CLASS, NETWORK_CANVAS_CLASS, NETWORK_SKELETON_AREA_CLASS, NETWORK_STATS_CLASS, NETWORK_STATS_TOGGLE_CLASS } from \"./layout-classes\"\n\n/** Agentes em volta do centro e os canais de cada um em órbita (\"Canais junto dos agentes\", o padrão). */\nconst SKELETON_AGENTS = [0, 1, 2].map((index) => {\n const angle = -Math.PI / 2 + (index * 2 * Math.PI) / 3\n return { x: Math.cos(angle) * 150, y: Math.sin(angle) * 120, angle }\n})\n\n/**\n * Skeleton com as dimensões da rede: área do canvas (mesmo fundo), a visão inicial na distribuição\n * padrão (agentes em volta do centro, cada um com os seus canais em órbita, OPE-113) e o card de\n * estatísticas (a barra fica fora da carga). No celular, o card aparece recolhido (o botão do canto),\n * como na rede.\n */\nexport function NetworkSkeleton({ className }: { className?: string }) {\n return (\n <div className={cn(NETWORK_CANVAS_CLASS, className)} aria-busy=\"true\" data-testid=\"network-skeleton\">\n <div className={NETWORK_SKELETON_AREA_CLASS} data-testid=\"network-skeleton-area\">\n <div className=\"relative h-0 w-0\">\n {SKELETON_AGENTS.map((agent, index) => (\n <div key={index}>\n <Skeleton className={cn(\"absolute -translate-x-1/2 -translate-y-1/2 rounded-full\", AGENT_NODE_SIZE_CLASS)} style={{ left: agent.x, top: agent.y }} data-testid=\"network-skeleton-agent\" />\n {[-0.7, 0.7].map((turn) => (\n <Skeleton\n key={turn}\n className=\"absolute h-12 w-44 -translate-x-1/2 -translate-y-1/2 rounded-xl\"\n style={{ left: agent.x + Math.cos(agent.angle + turn) * 150, top: agent.y + Math.sin(agent.angle + turn) * 110 }}\n data-testid=\"network-skeleton-channel\"\n />\n ))}\n </div>\n ))}\n </div>\n </div>\n <div className={cn(NETWORK_STATS_TOGGLE_CLASS, \"md:hidden\")} data-testid=\"network-skeleton-stats-toggle\">\n <Skeleton className=\"h-4 w-24\" />\n </div>\n <div className={cn(NETWORK_STATS_CLASS, \"max-md:hidden\")}>\n <Skeleton className=\"mb-3 h-4 w-24\" />\n {[0, 1, 2, 3, 4].map((index) => (\n <Skeleton key={index} className=\"mb-2 h-3 w-full\" />\n ))}\n </div>\n </div>\n )\n}\n","\"use client\"\n\nimport { useCallback } from \"react\"\nimport { AnimatePresence, motion } from \"framer-motion\"\nimport { AlertTriangle, FileUp, Info, MoreHorizontal, Plus, RotateCw, Search, X } from \"lucide-react\"\nimport { Button } from \"../../../components/ui/button\"\nimport { Input } from \"../../../components/ui/input\"\nimport { SEARCH_DEBOUNCE_MS } from \"../../../components/list/ListFilters\"\nimport { TooltipIconButton } from \"../../../components/ui/tooltip-icon-button\"\nimport { useDebouncedSearch } from \"../../../hooks/useDebouncedSearch\"\nimport { useIsMobile } from \"../../../hooks/useMediaQuery\"\nimport { MEMORY_HELP } from \"../../help/identities\"\nimport { NetworkFiltersBar } from \"./NetworkFiltersBar\"\nimport { NetworkFiltersSheet, type NetworkFilterFieldsProps } from \"./NetworkFiltersSheet\"\n\nexport interface NetworkToolbarProps extends NetworkFilterFieldsProps {\n onClear: () => void\n /** Memórias que casam na visão atual (total do cartão de filtros). */\n total: number\n textOnly: boolean\n /** Falha da busca automática (mensagem pt-BR) ou `null`. */\n searchError?: string | null\n onRetrySearch?: () => void\n}\n\nexport interface NetworkActionsProps {\n onNewChannel: () => void\n onImport: () => void\n importDisabled: boolean\n /** Universo do canal aberto: o menu do canal (editar, assinantes, arquivar/excluir) fica aqui. */\n onChannelMenu?: () => void\n}\n\n/**\n * Importar e Novo canal, na linha da trilha (à direita do Voltar / Rede / nome, OPE-113). No universo do\n * canal, o menu do canal vem antes (OPE-129: canal sem memória não tem node, mas continua editável). No\n * celular, só com ícone e dica.\n */\nexport function NetworkActions({ onNewChannel, onImport, importDisabled, onChannelMenu }: NetworkActionsProps) {\n const mobile = useIsMobile()\n if (mobile)\n return (\n <span className=\"ml-auto flex shrink-0 items-center gap-2\" data-testid=\"network-actions\">\n {onChannelMenu && (\n <TooltipIconButton label=\"Ações do canal\" className=\"h-10 min-w-10 bg-transparent\" onClick={onChannelMenu}>\n <MoreHorizontal aria-hidden />\n </TooltipIconButton>\n )}\n <TooltipIconButton label=\"Importar\" className=\"h-10 min-w-10 bg-transparent\" disabledReason={importDisabled ? \"Nenhum canal ativo para importar\" : null} onClick={onImport}>\n <FileUp aria-hidden />\n </TooltipIconButton>\n <TooltipIconButton label=\"Novo canal\" className=\"h-10 min-w-10 bg-transparent\" onClick={onNewChannel}>\n <Plus aria-hidden />\n </TooltipIconButton>\n </span>\n )\n return (\n <span className=\"ml-auto flex shrink-0 items-center gap-2\" data-testid=\"network-actions\">\n {onChannelMenu && (\n <Button type=\"button\" variant=\"outline\" aria-label=\"Ações do canal\" onClick={onChannelMenu}>\n <MoreHorizontal className=\"mr-1.5 h-4 w-4\" aria-hidden /> Canal\n </Button>\n )}\n <Button type=\"button\" variant=\"outline\" onClick={onImport} disabled={importDisabled}>\n <FileUp className=\"mr-1.5 h-4 w-4\" aria-hidden /> Importar\n </Button>\n <Button type=\"button\" onClick={onNewChannel}>\n <Plus className=\"mr-1.5 h-4 w-4\" aria-hidden /> Novo canal\n </Button>\n </span>\n )\n}\n\n/**\n * Barra da rede: a busca e os filtros no padrão de `/tarefas` (`NetworkFiltersBar`, recolhível). A busca\n * roda sozinha ao digitar; filtros destacam sem remover. Importar e Novo canal ficam na trilha.\n */\nexport function NetworkToolbar(props: NetworkToolbarProps) {\n const mobile = useIsMobile()\n if (mobile) return <MobileToolbar {...props} />\n return (\n <div className=\"flex flex-col gap-2\" data-testid=\"network-toolbar\">\n <NetworkFiltersBar filters={props.filters} onFilters={props.onFilters} options={props.options} onClear={props.onClear} total={props.total} />\n <SearchErrorNotice error={props.searchError ?? null} onRetry={props.onRetrySearch} />\n <TextOnlyNotice show={props.textOnly} />\n </div>\n )\n}\n\n/** Busca automática que falhou: a mensagem e \"Tentar novamente\" (nada fica destacado enquanto isso). */\nfunction SearchErrorNotice({ error, onRetry }: { error: string | null; onRetry?: () => void }) {\n return (\n <AnimatePresence initial={false}>\n {error && (\n <motion.div key=\"search-error\" role=\"alert\" data-testid=\"network-search-error\" initial={{ opacity: 0, height: 0 }} animate={{ opacity: 1, height: \"auto\" }} exit={{ opacity: 0, height: 0 }} className=\"flex flex-wrap items-center gap-2 text-xs text-destructive\">\n <AlertTriangle className=\"h-3.5 w-3.5\" aria-hidden /> Busca falhou: {error}\n {onRetry && (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" className=\"h-7 bg-transparent\" onClick={onRetry}>\n <RotateCw className=\"mr-1 h-3.5 w-3.5\" aria-hidden /> Tentar novamente\n </Button>\n )}\n </motion.div>\n )}\n </AnimatePresence>\n )\n}\n\nfunction TextOnlyNotice({ show }: { show: boolean }) {\n return (\n <AnimatePresence initial={false}>\n {show && (\n <motion.p key=\"text-only\" initial={{ opacity: 0, height: 0 }} animate={{ opacity: 1, height: \"auto\" }} exit={{ opacity: 0, height: 0 }} className=\"flex items-center gap-1.5 text-xs text-warning\">\n <Info className=\"h-3.5 w-3.5\" aria-hidden /> Busca só textual. {MEMORY_HELP.textOnly}\n </motion.p>\n )}\n </AnimatePresence>\n )\n}\n\n/**\n * Celular: a busca ocupa a linha inteira (roda sozinha ao digitar; o × limpa); embaixo, o botão\n * Filtros (gaveta com os mesmos campos). Importar/Novo canal ficam na trilha, só com ícone e dica.\n */\nfunction MobileToolbar(props: NetworkToolbarProps) {\n const { onFilters } = props\n const pushSearch = useCallback((value: string) => onFilters({ search: value }), [onFilters])\n const [search, setSearch] = useDebouncedSearch(props.filters.search, pushSearch, SEARCH_DEBOUNCE_MS)\n return (\n <div className=\"flex flex-col gap-2\" data-testid=\"network-toolbar\" data-mobile=\"\">\n <div className=\"relative w-full\">\n <Search className=\"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground\" aria-hidden />\n <Input value={search} onChange={(event) => setSearch(event.target.value)} placeholder=\"Buscar memórias\" aria-label=\"Buscar memórias\" className=\"h-10 bg-transparent pl-9 pr-10\" />\n {search && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n aria-label=\"Limpar busca\"\n className=\"absolute right-0 top-0 h-10 w-10\"\n onClick={() => {\n setSearch(\"\")\n props.onFilters({ search: \"\" })\n }}\n >\n <X className=\"h-4 w-4\" aria-hidden />\n </Button>\n )}\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <NetworkFiltersSheet filters={props.filters} onFilters={props.onFilters} options={props.options} onClear={props.onClear} />\n </div>\n <TextOnlyNotice show={props.textOnly} />\n <SearchErrorNotice error={props.searchError ?? null} onRetry={props.onRetrySearch} />\n </div>\n )\n}\n","\"use client\"\n\nimport type { ReactNode } from \"react\"\nimport { AnimatePresence, motion } from \"framer-motion\"\nimport { Filter, Search, X } from \"lucide-react\"\nimport { Button } from \"../ui/button\"\nimport { Card, CardContent, CardHeader } from \"../ui/card\"\nimport { Input } from \"../ui/input\"\nimport { TooltipProvider } from \"../ui/tooltip\"\nimport { cn } from \"../../lib/utils\"\nimport { useDebouncedSearch } from \"../../hooks/useDebouncedSearch\"\nimport type { ActiveFilterChip } from \"./ActiveFilterChips\"\nimport { CollapseToggle, CollapsedChips, CollapsibleBody, useFiltersCollapse } from \"./CollapsibleFilters\"\nimport { CadastroFilterCard } from \"./CadastroFilterCard\"\nimport { FilterGroup } from \"./FilterGroup\"\n\nexport type { ActiveFilterChip } from \"./ActiveFilterChips\"\n\nexport const SEARCH_DEBOUNCE_MS = 500\n\ninterface ListFiltersProps {\n /** Total de registros exibido no cabeçalho do cartão. */\n total?: number\n /** Busca compartilhada (omitir para páginas sem busca). */\n search?: {\n value: string\n onChange: (value: string) => void\n placeholder: string\n label?: string\n }\n /** Zera a busca e os filtros da página. */\n onClear: () => void\n /** Filtros próprios da página, cada um num `FilterGroup` (ex.: `className=\"flex-1 min-w-[180px]\"`). */\n children?: ReactNode\n /**\n * Segunda linha de `FilterGroup`s (telas com muitos filtros, ex.: funil). Mesmo visual; evita\n * espremer tudo numa linha só no desktop.\n */\n secondary?: ReactNode\n /**\n * Cartão recolhível: começa recolhido (`defaultCollapsed`, padrão `true`) mostrando só o resumo\n * `chips`; clicar expande; o botão ⌃ recolhe.\n */\n collapsible?: boolean\n defaultCollapsed?: boolean\n /** Filtros ativos no resumo recolhido (ver `ActiveFilterChip`). */\n chips?: readonly ActiveFilterChip[]\n}\n\n/**\n * Wrapper genérico de filtros das listas (padrão do Smart Desk: `CadastroFilterCard` +\n * `FilterGroup`s em linha). A busca ocupa o espaço disponível (`flex-[2]`), os filtros da página\n * dividem o resto (`flex-1`) e o botão Limpar fecha a linha. No desktop tudo fica numa linha; no\n * celular quebra. O estado vive na página que o usa (URL ou navegador).\n *\n * Com `collapsible`, o cartão começa recolhido numa linha: título, chips dos filtros ativos\n * (removíveis), total, limpar e expandir. Clicar na linha do título expande e recolhe (o chevron\n * também alterna). Abre/fecha animado (Framer Motion).\n */\nexport function ListFilters({ total, search, onClear, children, secondary, collapsible = false, defaultCollapsed = true, chips = [] }: ListFiltersProps) {\n const [localSearch, setLocalSearch] = useDebouncedSearch(search?.value ?? \"\", search?.onChange, SEARCH_DEBOUNCE_MS)\n const { collapsed, toggle, contentId } = useFiltersCollapse(collapsible && defaultCollapsed)\n\n const clear = () => {\n setLocalSearch(\"\")\n onClear()\n }\n\n const fields = (\n <>\n <div className=\"flex w-full flex-wrap items-end gap-3 lg:flex-nowrap\">\n {search && (\n <FilterGroup label={search.label ?? \"Busca\"} className=\"min-w-[200px] flex-[2]\">\n <div className=\"relative\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground opacity-50\" aria-hidden />\n <Input\n aria-label={search.label ?? \"Busca\"}\n placeholder={search.placeholder}\n value={localSearch}\n onChange={(event) => setLocalSearch(event.target.value)}\n className=\"h-10 pl-9\"\n />\n </div>\n </FilterGroup>\n )}\n\n {children}\n\n <div className=\"shrink-0\">\n <div className=\"flex flex-col gap-2\">\n <span className=\"hidden select-none text-[10px] font-bold uppercase tracking-wider text-transparent lg:block\">_</span>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n className=\"h-10 w-10 bg-transparent transition-colors hover:border-destructive/30 hover:bg-destructive/10 hover:text-destructive\"\n onClick={clear}\n title=\"Limpar filtros\"\n aria-label=\"Limpar filtros\"\n >\n <X className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n </div>\n {secondary && <div className=\"mt-3 flex w-full flex-wrap items-end gap-3 lg:flex-nowrap\">{secondary}</div>}\n </>\n )\n\n if (!collapsible) return <CadastroFilterCard total={total}>{fields}</CadastroFilterCard>\n\n const hasActive = chips.some((chip) => !chip.subtle)\n\n return (\n <TooltipProvider>\n <Card>\n <CardHeader className={cn(\"transition-[padding]\", collapsed ? \"py-3\" : \"pb-3\")}>\n <div\n className=\"grid cursor-pointer grid-cols-[auto_1fr] items-center gap-x-3 gap-y-2 md:grid-cols-[auto_1fr_auto]\"\n onClick={toggle}\n data-testid=\"list-filters-header\"\n >\n <div className=\"col-start-1 col-end-2 row-start-1 flex min-w-0 items-center gap-2\">\n <Filter className=\"h-5 w-5 shrink-0 text-primary\" aria-hidden />\n <h2 className=\"whitespace-nowrap text-sm font-semibold uppercase tracking-wider text-muted-foreground\">Filtros</h2>\n </div>\n <div className=\"col-start-1 col-end-3 row-start-2 min-w-0 md:col-start-2 md:col-end-3 md:row-start-1\" data-testid=\"list-filters-summary\">\n <CollapsedChips collapsed={collapsed} chips={chips} />\n </div>\n <div className=\"col-start-2 col-end-3 row-start-1 flex shrink-0 items-center justify-end gap-1.5 md:col-start-3 md:col-end-4\" data-testid=\"list-filters-controls\">\n {total !== undefined && total > 0 && (\n <div className=\"rounded-full bg-primary/10 px-2 py-0.5 text-[10px] font-bold text-primary\">{total} REGISTROS</div>\n )}\n <AnimatePresence initial={false}>\n {collapsed && hasActive && (\n <motion.span key=\"clear\" initial={{ opacity: 0, scale: 0.8 }} animate={{ opacity: 1, scale: 1 }} exit={{ opacity: 0, scale: 0.8 }} transition={{ duration: 0.15 }} className=\"inline-flex\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7 text-muted-foreground hover:bg-destructive/10 hover:text-destructive\"\n onClick={(event) => {\n event.stopPropagation()\n clear()\n }}\n title=\"Limpar filtros\"\n aria-label=\"Limpar filtros\"\n >\n <X className=\"h-3.5 w-3.5\" aria-hidden />\n </Button>\n </motion.span>\n )}\n </AnimatePresence>\n <CollapseToggle collapsed={collapsed} onToggle={toggle} controls={contentId} />\n </div>\n </div>\n </CardHeader>\n {/* Popovers dos campos abrem em portal: o overflow não os corta. */}\n <CollapsibleBody collapsed={collapsed} id={contentId}>\n <CardContent>{fields}</CardContent>\n </CollapsibleBody>\n </Card>\n </TooltipProvider>\n )\n}\n","\"use client\"\n\nimport { useEffect, useState } from \"react\"\n\n/**\n * Campo de busca com espera de digitação: o valor local muda na hora (o campo responde) e só chega a\n * `onChange` depois de `delayMs` sem digitar. Mudanças externas (Limpar, remover chip, voltar no\n * navegador) substituem o valor local.\n */\nexport function useDebouncedSearch(external: string, onChange: ((value: string) => void) | undefined, delayMs: number): [string, (value: string) => void] {\n const [local, setLocal] = useState(external)\n const [lastExternal, setLastExternal] = useState(external)\n if (lastExternal !== external) {\n setLastExternal(external)\n setLocal(external)\n }\n useEffect(() => {\n if (!onChange || local === external) return\n const timer = setTimeout(() => onChange(local), delayMs)\n return () => clearTimeout(timer)\n }, [local, external, onChange, delayMs])\n return [local, setLocal]\n}\n","\"use client\"\n\nimport { useCallback, useId, useState, type ReactNode } from \"react\"\nimport { AnimatePresence, motion, useReducedMotion } from \"framer-motion\"\nimport { ChevronDown, ChevronUp } from \"lucide-react\"\nimport { Button } from \"../ui/button\"\nimport { cn } from \"../../lib/utils\"\nimport { ActiveFilterChips, type ActiveFilterChip } from \"./ActiveFilterChips\"\n\n/**\n * Peças compartilhadas das áreas de filtros recolhíveis (`ListFilters` de /tarefas e a coluna\n * Tarefas da Central de desenvolvimento): o estado compartilhado (`useFiltersCollapse`), o chevron que\n * alterna, o resumo em chips enquanto recolhida e o conteúdo que abre/fecha com a altura animada (Framer Motion, movimento reduzido só\n * com opacidade).\n */\n\n/**\n * Estado aberto/recolhido da área de filtros. O mesmo `toggle` vai na linha do título e no chevron:\n * clicar em qualquer ponto da linha expande e recolhe.\n */\nexport function useFiltersCollapse(defaultCollapsed = true) {\n const [collapsed, setCollapsed] = useState(defaultCollapsed)\n const contentId = useId()\n const toggle = useCallback(() => setCollapsed((value) => !value), [])\n return { collapsed, toggle, contentId }\n}\n\ninterface CollapseToggleProps {\n collapsed: boolean\n onToggle: () => void\n /** Id do conteúdo controlado (`aria-controls`). */\n controls: string\n}\n\n/** Botão ⌄/⌃ que expande/recolhe os filtros (não propaga o clique à linha do título, que alternaria de novo). */\nexport function CollapseToggle({ collapsed, onToggle, controls }: CollapseToggleProps) {\n const label = collapsed ? \"Expandir filtros\" : \"Recolher filtros\"\n return (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7 text-muted-foreground hover:text-foreground\"\n onClick={(event) => {\n event.stopPropagation()\n onToggle()\n }}\n aria-expanded={!collapsed}\n aria-controls={controls}\n aria-label={label}\n title={label}\n >\n {collapsed ? <ChevronDown className=\"h-4 w-4\" aria-hidden /> : <ChevronUp className=\"h-4 w-4\" aria-hidden />}\n </Button>\n )\n}\n\ninterface CollapsedChipsProps {\n collapsed: boolean\n chips: readonly ActiveFilterChip[]\n maxVisible?: number\n className?: string\n}\n\n/** Resumo dos filtros ativos, visível só com a área recolhida (entra/sai com fade). */\nexport function CollapsedChips({ collapsed, chips, maxVisible, className }: CollapsedChipsProps) {\n return (\n <AnimatePresence initial={false}>\n {collapsed && (\n <motion.div key=\"chips\" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} transition={{ duration: 0.15 }}>\n <ActiveFilterChips chips={chips} maxVisible={maxVisible} className={className} />\n </motion.div>\n )}\n </AnimatePresence>\n )\n}\n\ninterface CollapsibleBodyProps {\n collapsed: boolean\n id: string\n className?: string\n children: ReactNode\n}\n\n/** Conteúdo dos filtros: abre/fecha com a altura animada. Popovers abrem em portal (o overflow não os corta). */\nexport function CollapsibleBody({ collapsed, id, className, children }: CollapsibleBodyProps) {\n const reduceMotion = useReducedMotion()\n return (\n <AnimatePresence initial={false}>\n {!collapsed && (\n <motion.div\n key=\"content\"\n id={id}\n initial={reduceMotion ? { opacity: 0 } : { height: 0, opacity: 0 }}\n animate={reduceMotion ? { opacity: 1 } : { height: \"auto\", opacity: 1 }}\n exit={reduceMotion ? { opacity: 0 } : { height: 0, opacity: 0 }}\n transition={{ duration: 0.2, ease: \"easeOut\" }}\n className={cn(\"overflow-hidden\", className)}\n >\n {children}\n </motion.div>\n )}\n </AnimatePresence>\n )\n}\n","\"use client\"\n\nimport { AnimatePresence, motion } from \"framer-motion\"\nimport { X } from \"lucide-react\"\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../ui/tooltip\"\nimport { cn } from \"../../lib/utils\"\n\n/** Um filtro ativo no resumo do `ListFilters` recolhido. */\nexport interface ActiveFilterChip {\n key: string\n label: string\n /** Texto completo (ex.: todos os valores quando o rótulo resume \"3 selecionados\"). */\n title?: string\n /** Remove só este filtro (mostra o ×). */\n onRemove?: () => void\n /** Chip discreto (preferência, não filtro — ex.: ordenação). */\n subtle?: boolean\n}\n\ninterface ActiveFilterChipsProps {\n chips: readonly ActiveFilterChip[]\n /** Chips visíveis antes do \"+N\". */\n maxVisible?: number\n emptyLabel?: string\n className?: string\n}\n\nfunction Chip({ chip }: { chip: ActiveFilterChip }) {\n return (\n <motion.span\n layout=\"position\"\n initial={{ opacity: 0, scale: 0.85 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.85 }}\n transition={{ duration: 0.15 }}\n title={chip.title ?? chip.label}\n className={cn(\n \"inline-flex min-w-0 max-w-[260px] items-center gap-1 rounded-full border py-0.5 pl-2.5 text-xs\",\n chip.onRemove ? \"pr-1\" : \"pr-2.5\",\n chip.subtle ? \"border-border bg-muted/50 text-muted-foreground\" : \"border-primary/30 bg-primary/10 text-foreground\",\n )}\n data-testid={`filter-chip-${chip.key}`}\n >\n <span className=\"truncate\">{chip.label}</span>\n {chip.onRemove && (\n <button\n type=\"button\"\n onClick={(event) => {\n event.stopPropagation()\n chip.onRemove?.()\n }}\n className=\"rounded-full p-0.5 text-muted-foreground transition-colors hover:bg-destructive/15 hover:text-destructive focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary\"\n aria-label={`Remover filtro ${chip.label}`}\n >\n <X className=\"h-3 w-3\" aria-hidden />\n </button>\n )}\n </motion.span>\n )\n}\n\n/** Resumo dos filtros ativos (chips removíveis, \"+N\" com o restante na dica). */\nexport function ActiveFilterChips({ chips, maxVisible = 4, emptyLabel = \"Nenhum filtro ativo · clique para filtrar\", className }: ActiveFilterChipsProps) {\n const visible = chips.slice(0, maxVisible)\n const hidden = chips.slice(maxVisible)\n\n return (\n <div className={cn(\"flex min-w-0 flex-wrap items-center gap-1.5\", className)}>\n <AnimatePresence initial={false} mode=\"popLayout\">\n {chips.length === 0 ? (\n <motion.span key=\"empty\" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} className=\"text-xs italic text-muted-foreground\">\n {emptyLabel}\n </motion.span>\n ) : (\n visible.map((chip) => <Chip key={chip.key} chip={chip} />)\n )}\n </AnimatePresence>\n {hidden.length > 0 && (\n <Tooltip delayDuration={200}>\n <TooltipTrigger asChild>\n <span className=\"inline-flex shrink-0 cursor-default items-center rounded-full border border-border bg-muted px-2 py-0.5 text-xs font-semibold text-muted-foreground\" onClick={(event) => event.stopPropagation()}>\n +{hidden.length}\n </span>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"max-w-xs p-2\">\n <ul className=\"space-y-1 text-xs\">\n {hidden.map((chip) => (\n <li key={chip.key}>{chip.title ?? chip.label}</li>\n ))}\n </ul>\n </TooltipContent>\n </Tooltip>\n )}\n </div>\n )\n}\n","import { ReactNode } from \"react\"\nimport { Card, CardHeader, CardContent } from \"../ui/card\"\nimport { Filter } from \"lucide-react\"\n\ninterface CadastroFilterCardProps {\n total?: number\n children: ReactNode\n}\n\nexport function CadastroFilterCard({ total, children }: CadastroFilterCardProps) {\n return (\n <Card>\n <CardHeader className=\"pb-3\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <Filter className=\"h-5 w-5 text-primary\" />\n <h2 className=\"text-sm font-semibold uppercase tracking-wider text-muted-foreground\">Filtros</h2>\n </div>\n {total !== undefined && total > 0 && (\n <div className=\"px-2 py-0.5 rounded-full bg-primary/10 text-primary text-[10px] font-bold\">\n {total} REGISTROS\n </div>\n )}\n </div>\n </CardHeader>\n <CardContent>\n {children}\n </CardContent>\n </Card>\n )\n}\n","import { ReactNode } from \"react\"\nimport { Label } from \"../ui/label\"\nimport { cn } from \"../../lib/utils\"\n\ninterface FilterGroupProps {\n label: string\n children: ReactNode\n className?: string\n}\n\nexport function FilterGroup({ label, children, className }: FilterGroupProps) {\n return (\n <div className={cn(\"flex flex-col gap-2\", className)}>\n <Label className=\"text-[10px] font-bold uppercase tracking-wider text-muted-foreground\">{label}</Label>\n {children}\n </div>\n )\n}\n","\"use client\"\n\nimport { useCallback, useMemo } from \"react\"\nimport { ListFilters } from \"../../../components/list/ListFilters\"\nimport { channelDisplayName } from \"../../network/channel-labels\"\nimport { activeNetworkFilterChips } from \"../../network/filters\"\nimport { useChannelLabels } from \"./ChannelName\"\nimport { NetworkFilterFields, type NetworkFilterFieldsProps } from \"./NetworkFiltersSheet\"\n\n/**\n * Computador: busca e filtros da rede no cartão recolhível de `/tarefas` (`ListFilters`), com os chips\n * dos filtros ativos no resumo. A busca roda sozinha depois da espera de digitação.\n */\nexport function NetworkFiltersBar({ filters, onFilters, options, onClear, total }: NetworkFilterFieldsProps & { onClear: () => void; total: number }) {\n const labels = useChannelLabels()\n const chips = useMemo(() => activeNetworkFilterChips(filters, (slug) => channelDisplayName(slug, labels)).map((chip) => ({ key: chip.key, label: chip.label, onRemove: () => onFilters(chip.remove) })), [filters, onFilters, labels])\n const onSearch = useCallback((search: string) => onFilters({ search }), [onFilters])\n return (\n <ListFilters\n collapsible\n chips={chips}\n total={total}\n search={{ value: filters.search, onChange: onSearch, placeholder: \"Buscar por sentido e por texto\", label: \"Buscar memórias\" }}\n onClear={onClear}\n secondary={<NetworkFilterFields filters={filters} onFilters={onFilters} options={options} part=\"secondary\" />}\n >\n <NetworkFilterFields filters={filters} onFilters={onFilters} options={options} part=\"primary\" />\n </ListFilters>\n )\n}\n","\"use client\"\n\nimport { useState } from \"react\"\nimport { AnimatePresence, motion } from \"framer-motion\"\nimport { Archive, CircleDot, Hash, SlidersHorizontal, Tag, UserRound } from \"lucide-react\"\nimport { CadastroMultiSelect } from \"../../../components/list/CadastroMultiSelect\"\nimport { FilterGroup } from \"../../../components/list/FilterGroup\"\nimport { FilterSwitch } from \"../../../components/list/FilterSwitch\"\nimport { Button } from \"../../../components/ui/button\"\nimport { PresetDateRangeFilter } from \"../../../components/ui/preset-date-range-filter\"\nimport { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from \"../../../components/ui/sheet\"\nimport { channelDisplayName } from \"../../network/channel-labels\"\nimport { activeNetworkFilterChips, MEMORY_STATUS_OPTIONS, type NetworkFilters } from \"../../network/filters\"\nimport { useChannelLabels } from \"./ChannelName\"\n\nexport interface NetworkFilterOptions {\n channels: readonly string[]\n categories: readonly string[]\n authors: readonly string[]\n}\n\nexport interface NetworkFilterFieldsProps {\n filters: NetworkFilters\n onFilters: (patch: Partial<NetworkFilters>) => void\n options: NetworkFilterOptions\n}\n\nconst COL = \"min-w-[160px] flex-1\"\nconst toOptions = (values: readonly string[]) => values.map((value) => ({ value, label: value }))\n\n/** Quantos filtros da rede estão preenchidos (selo do botão Filtros no celular; a busca fica no campo). */\nexport function activeFilterCount(filters: NetworkFilters): number {\n return activeNetworkFilterChips(filters).filter((chip) => chip.key !== \"search\").length\n}\n\n/**\n * Filtros da rede com os componentes de `/tarefas` (destacam sem remover). `part`: a primeira linha\n * (Canal e Categoria, ao lado da busca), a segunda (Status, Autor, Período e Arquivados) ou todos\n * empilhados (gaveta do celular).\n */\nexport function NetworkFilterFields({ filters, onFilters, options, part = \"all\", groupClassName = COL }: NetworkFilterFieldsProps & { part?: \"primary\" | \"secondary\" | \"all\"; groupClassName?: string }) {\n const labels = useChannelLabels()\n const primary = (\n <>\n <FilterGroup label=\"Canal\" className={groupClassName}>\n <CadastroMultiSelect icon={Hash} aria-label=\"Filtrar por canal\" placeholder=\"Todos\" options={options.channels.map((slug) => ({ value: slug, label: channelDisplayName(slug, labels) }))} selected={filters.channels} onSelect={(channels) => onFilters({ channels })} searchable searchPlaceholder=\"Buscar canal...\" />\n </FilterGroup>\n <FilterGroup label=\"Categoria\" className={groupClassName}>\n <CadastroMultiSelect icon={Tag} aria-label=\"Filtrar por categoria\" placeholder=\"Todas\" options={toOptions(options.categories)} selected={filters.categories} onSelect={(categories) => onFilters({ categories })} searchable searchPlaceholder=\"Buscar categoria...\" />\n </FilterGroup>\n </>\n )\n const secondary = (\n <>\n <FilterGroup label=\"Status\" className={groupClassName}>\n <CadastroMultiSelect icon={CircleDot} aria-label=\"Filtrar por status\" placeholder=\"Todos\" options={MEMORY_STATUS_OPTIONS} selected={filters.statuses} onSelect={(statuses) => onFilters({ statuses })} />\n </FilterGroup>\n <FilterGroup label=\"Autor\" className={groupClassName}>\n <CadastroMultiSelect icon={UserRound} aria-label=\"Filtrar por autor\" placeholder=\"Todos\" options={toOptions(options.authors)} selected={filters.authors} onSelect={(authors) => onFilters({ authors })} searchable searchPlaceholder=\"Buscar autor...\" />\n </FilterGroup>\n <FilterGroup label=\"Período\" className={groupClassName}>\n <PresetDateRangeFilter startDate={filters.from} endDate={filters.to} onChange={(next) => onFilters({ from: next.startDate, to: next.endDate })} />\n </FilterGroup>\n <FilterGroup label=\"Arquivados\" className=\"shrink-0\">\n <FilterSwitch icon={Archive} text=\"Mostrar\" ariaLabel=\"Mostrar arquivados\" checked={filters.includeArchived} onCheckedChange={(includeArchived) => onFilters({ includeArchived })} />\n </FilterGroup>\n </>\n )\n if (part === \"primary\") return primary\n if (part === \"secondary\") return secondary\n return (\n <>\n {primary}\n {secondary}\n </>\n )\n}\n\n/** Celular: botão \"Filtros\" (com quantos estão ativos) que abre os filtros numa gaveta de baixo para cima. */\nexport function NetworkFiltersSheet(props: NetworkFilterFieldsProps & { onClear: () => void }) {\n const [open, setOpen] = useState(false)\n const count = activeFilterCount(props.filters)\n return (\n <>\n <Button type=\"button\" variant=\"outline\" className=\"h-10 bg-transparent\" onClick={() => setOpen(true)} aria-label={count ? `Filtros (${count} ${count === 1 ? \"ativo\" : \"ativos\"})` : \"Filtros\"}>\n <SlidersHorizontal className=\"mr-1.5 h-4 w-4\" aria-hidden /> Filtros\n <AnimatePresence initial={false}>\n {count > 0 && (\n <motion.span\n key=\"count\"\n data-testid=\"network-filter-count\"\n initial={{ opacity: 0, scale: 0.6 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.6 }}\n transition={{ duration: 0.15 }}\n className=\"ml-1.5 rounded-full bg-primary px-1.5 text-[10px] font-semibold text-primary-foreground\"\n >\n {count}\n </motion.span>\n )}\n </AnimatePresence>\n </Button>\n <Sheet open={open} onOpenChange={setOpen}>\n <SheetContent side=\"bottom\" className=\"max-h-[85dvh] overflow-y-auto rounded-t-xl\">\n <SheetHeader>\n <SheetTitle>Filtros da rede</SheetTitle>\n <SheetDescription>Destacam as memórias que combinam, sem remover as demais.</SheetDescription>\n </SheetHeader>\n <div className=\"mt-4 flex flex-col gap-3\" data-testid=\"network-filters-sheet-fields\">\n <NetworkFilterFields filters={props.filters} onFilters={props.onFilters} options={props.options} groupClassName=\"w-full\" />\n </div>\n <div className=\"mt-4 flex gap-2\">\n <Button type=\"button\" variant=\"outline\" className=\"h-10 flex-1 bg-transparent\" disabled={!count} onClick={props.onClear}>\n Limpar\n </Button>\n <Button type=\"button\" className=\"h-10 flex-1\" onClick={() => setOpen(false)}>\n Ver rede\n </Button>\n </div>\n </SheetContent>\n </Sheet>\n </>\n )\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\"\nimport { cn } from \"../../lib/utils\"\nimport { usePortalContainer } from \"./portal-container\"\n\nconst Popover = PopoverPrimitive.Root\n\nconst PopoverTrigger = PopoverPrimitive.Trigger\n\nconst PopoverAnchor = PopoverPrimitive.Anchor\n\nconst PopoverContent = React.forwardRef<\n React.ElementRef<typeof PopoverPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>\n>(({ className, align = \"center\", sideOffset = 4, ...props }, ref) => (\n <PopoverPrimitive.Portal container={usePortalContainer()}>\n <PopoverPrimitive.Content\n ref={ref}\n align={align}\n sideOffset={sideOffset}\n className={cn(\n \"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n className\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n))\nPopoverContent.displayName = PopoverPrimitive.Content.displayName\n\nexport { Popover, PopoverTrigger, PopoverAnchor, PopoverContent }\n","import * as React from \"react\"\nimport { cn } from \"../../lib/utils\"\nimport { Check, Minus } from \"lucide-react\"\n\ninterface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {\n onCheckedChange?: (checked: boolean) => void\n indeterminate?: boolean\n}\n\nconst Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(\n ({ className, onCheckedChange, checked, defaultChecked, indeterminate = false, ...props }, ref) => {\n const [isChecked, setIsChecked] = React.useState(defaultChecked || checked || false)\n\n React.useEffect(() => {\n if (checked !== undefined) {\n setIsChecked(checked)\n }\n }, [checked])\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const newChecked = e.target.checked\n setIsChecked(newChecked)\n onCheckedChange?.(newChecked)\n props.onChange?.(e)\n }\n\n const handleClick = () => {\n if (!props.disabled) {\n const newChecked = !isChecked\n setIsChecked(newChecked)\n onCheckedChange?.(newChecked)\n }\n }\n\n return (\n <div className=\"relative inline-flex items-center\">\n <input type=\"checkbox\" ref={ref} className=\"sr-only peer\" checked={isChecked} aria-checked={!isChecked && indeterminate ? \"mixed\" : undefined} onChange={handleChange} {...props} />\n <div\n onClick={handleClick}\n className={cn(\n \"h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 peer-checked:bg-primary peer-checked:text-primary-foreground flex items-center justify-center transition-colors\",\n !props.disabled && \"cursor-pointer\",\n props.disabled && \"opacity-50 cursor-not-allowed\",\n className,\n )}\n >\n {isChecked ? <Check className=\"h-3 w-3 text-current\" /> : indeterminate ? <Minus className=\"h-3 w-3 text-current\" /> : null}\n </div>\n </div>\n )\n }\n)\nCheckbox.displayName = \"Checkbox\"\n\nexport { Checkbox }\n","\"use client\"\n\nimport { Popover, PopoverContent, PopoverTrigger } from \"../ui/popover\"\nimport { Button } from \"../ui/button\"\nimport { Checkbox } from \"../ui/checkbox\"\nimport { Badge } from \"../ui/badge\"\nimport { cn } from \"../../lib/utils\"\nimport { LucideIcon, Search } from \"lucide-react\"\nimport { Input } from \"../ui/input\"\nimport { useState } from \"react\"\n\ninterface Option {\n value: string\n label: string\n}\n\ninterface CadastroMultiSelectProps {\n options: Option[]\n selected: string[]\n onSelect: (values: string[]) => void\n placeholder?: string\n renderLabel?: (option: Option) => React.ReactNode\n icon?: LucideIcon\n className?: string\n searchable?: boolean\n searchPlaceholder?: string\n /** Associa o gatilho ao rótulo do formulário (`Label htmlFor`). */\n id?: string\n /** Nome acessível do gatilho quando não há `Label` associado. */\n \"aria-label\"?: string\n /**\n * Rótulo da opção que marca/desmarca todas de uma vez (ex.: \"Todos\"), no topo da lista; aparece\n * parcialmente marcada quando só parte está escolhida. Sem o rótulo, a opção não existe.\n */\n selectAllLabel?: string\n}\n\nexport function CadastroMultiSelect({ \n options, \n selected, \n onSelect, \n placeholder = \"Selecionar...\",\n renderLabel,\n icon: Icon,\n className,\n searchable = false,\n searchPlaceholder = \"Buscar...\",\n id,\n \"aria-label\": ariaLabel,\n selectAllLabel\n}: CadastroMultiSelectProps) {\n const [search, setSearch] = useState(\"\")\n const allSelected = options.length > 0 && options.every((option) => selected.includes(option.value))\n const someSelected = !allSelected && options.some((option) => selected.includes(option.value))\n const toggleAll = () => onSelect(allSelected ? [] : options.map((option) => option.value))\n\n const toggle = (value: string) => {\n if (selected.includes(value)) {\n onSelect(selected.filter(v => v !== value))\n } else {\n onSelect([...selected, value])\n }\n }\n\n const displayValue = () => {\n if (selected.length === 0) return placeholder\n if (selectAllLabel && allSelected && options.length > 1) return selectAllLabel\n if (selected.length === 1) return options.find(o => o.value === selected[0])?.label || selected[0]\n return `${selected.length} selecionados`\n }\n\n const filteredOptions = options.filter(o => \n o.label.toLowerCase().includes(search.toLowerCase()) ||\n o.value.toLowerCase().includes(search.toLowerCase())\n )\n\n return (\n <Popover>\n <PopoverTrigger asChild>\n <Button id={id} aria-label={ariaLabel} variant=\"outline\" className={cn(\"w-full justify-start h-10 bg-transparent font-normal px-3 transition-all\", className)}>\n <div className=\"flex items-center gap-2 truncate flex-1\">\n {Icon && <Icon className=\"h-4 w-4 shrink-0 opacity-50 text-primary\" />}\n <span className={cn(\"truncate\", selected.length === 0 && \"text-muted-foreground\")}>\n {displayValue()}\n </span>\n </div>\n {selected.length > 0 && (\n <Badge variant=\"secondary\" className=\"h-5 px-1 py-0 text-[10px] font-mono shrink-0 ml-2 bg-primary/10 text-primary border-none\">\n {selected.length}\n </Badge>\n )}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-64 p-1\" align=\"start\">\n {searchable && (\n <div className=\"p-2 border-b mb-1\">\n <div className=\"relative\">\n <Search className=\"absolute left-2 top-1/2 -translate-y-1/2 h-3 w-3 text-muted-foreground opacity-50\" />\n <Input \n placeholder={searchPlaceholder}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"h-8 pl-7 text-xs\"\n />\n </div>\n </div>\n )}\n {selectAllLabel && options.length > 0 && (\n <div className=\"mb-1 border-b pb-1\">\n <div className=\"flex items-center space-x-2 p-2 hover:bg-accent rounded-md cursor-pointer transition-colors\" onClick={toggleAll}>\n <Checkbox\n checked={allSelected}\n indeterminate={someSelected}\n onCheckedChange={toggleAll}\n onClick={(e) => e.stopPropagation()}\n aria-label={selectAllLabel}\n />\n <div className=\"flex-1 text-xs font-medium truncate\">{selectAllLabel}</div>\n </div>\n </div>\n )}\n <div className=\"max-h-[250px] overflow-y-auto space-y-0.5 custom-scrollbar\">\n {filteredOptions.length === 0 ? (\n <div className=\"p-4 text-center text-xs text-muted-foreground italic\">\n Nenhum resultado\n </div>\n ) : (\n filteredOptions.map((option) => (\n <div \n key={option.value}\n className=\"flex items-center space-x-2 p-2 hover:bg-accent rounded-md cursor-pointer transition-colors\"\n onClick={() => toggle(option.value)}\n >\n <Checkbox \n checked={selected.includes(option.value)} \n onCheckedChange={() => toggle(option.value)}\n onClick={(e) => e.stopPropagation()}\n />\n <div className=\"flex-1 text-xs truncate\">\n {renderLabel ? renderLabel(option) : option.label}\n </div>\n </div>\n ))\n )}\n </div>\n </PopoverContent>\n </Popover>\n )\n}\n","\"use client\"\n\nimport type { LucideIcon } from \"lucide-react\"\nimport { Switch } from \"../ui/switch\"\nimport { cn } from \"../../lib/utils\"\n\ninterface FilterSwitchProps {\n icon: LucideIcon\n text: string\n ariaLabel: string\n checked: boolean\n onCheckedChange: (checked: boolean) => void\n className?: string\n}\n\n/** Switch de filtro com ícone e texto, na altura dos demais campos (`h-10`) e com o fundo do card. */\nexport function FilterSwitch({ icon: Icon, text, ariaLabel, checked, onCheckedChange, className }: FilterSwitchProps) {\n return (\n <div className={cn(\"flex h-10 items-center gap-2 rounded-md border border-input bg-transparent px-3\", className)}>\n <Icon className={checked ? \"h-4 w-4 text-primary\" : \"h-4 w-4 text-muted-foreground\"} aria-hidden />\n <span className=\"text-sm\">{text}</span>\n <Switch checked={checked} onCheckedChange={onCheckedChange} aria-label={ariaLabel} />\n </div>\n )\n}\n","\"use client\"\n\nimport { format, subDays, subMonths } from \"date-fns\"\nimport { Calendar, CalendarDays, CalendarRange, Sparkles, type LucideIcon } from \"lucide-react\"\nimport { Button } from \"./button\"\nimport { Popover, PopoverContent, PopoverTrigger } from \"./popover\"\nimport { cn } from \"../../lib/utils\"\nimport { DateRangeCalendar, formatRangeLabel, type DateRangeValue } from \"./date-range-calendar\"\n\n/**\n * Filtro de período padrão do app — cópia do `PresetDateRangeFilter` do Smart Desk (filtro\n * \"Data Disparo\" das notificações), com date-fns. Botão com o período, popover com \"Período\n * personalizado\" (calendário de intervalo) e \"Atalhos\". Todo filtro/componente de janela de data\n * usa este componente dentro de um `FilterGroup`.\n *\n * Atalhos: por padrão Hoje, Última semana e Último mês (`DEFAULT_DATE_PRESETS`). Para personalizar,\n * passe `presets` — monte com os prontos (`DATE_PRESET.today`, ...) ou crie com `lastDaysPreset`.\n */\n\nexport type { DateRangeValue } from \"./date-range-calendar\"\n\nexport interface DatePreset {\n key: string\n label: string\n icon: LucideIcon\n getRange: () => DateRangeValue\n}\n\nconst iso = (date: Date) => format(date, \"yyyy-MM-dd\")\n\n/** Atalho \"últimos N dias\" (de hoje − N até hoje). */\nexport const lastDaysPreset = (days: number, label = `Últimos ${days} dias`, icon: LucideIcon = CalendarDays): DatePreset => ({\n key: `last-${days}d`,\n label,\n icon,\n getRange: () => ({ startDate: iso(subDays(new Date(), days)), endDate: iso(new Date()) }),\n})\n\nexport const DATE_PRESET = {\n today: { key: \"today\", label: \"Hoje\", icon: Sparkles, getRange: () => ({ startDate: iso(new Date()), endDate: iso(new Date()) }) },\n week: lastDaysPreset(7, \"Última semana\", CalendarDays),\n month: {\n key: \"month\",\n label: \"Último mês\",\n icon: CalendarRange,\n getRange: () => ({ startDate: iso(subMonths(new Date(), 1)), endDate: iso(new Date()) }),\n },\n} satisfies Record<string, DatePreset>\n\nexport const DEFAULT_DATE_PRESETS: readonly DatePreset[] = [DATE_PRESET.today, DATE_PRESET.week, DATE_PRESET.month]\n\ninterface PresetDateRangeFilterProps {\n startDate: string\n endDate: string\n onChange: (next: DateRangeValue) => void\n emptyLabel?: string\n /** Atalhos da tela; padrão: Hoje, Última semana, Último mês. `[]` esconde a seção. */\n presets?: readonly DatePreset[]\n className?: string\n}\n\nconst isPresetActive = (preset: DatePreset, value: DateRangeValue) => {\n const range = preset.getRange()\n return value.startDate === range.startDate && value.endDate === range.endDate\n}\n\nexport function PresetDateRangeFilter({ startDate, endDate, onChange, emptyLabel = \"Selecionar período\", presets = DEFAULT_DATE_PRESETS, className }: PresetDateRangeFilterProps) {\n const hasValue = Boolean(startDate || endDate)\n\n return (\n <Popover>\n <PopoverTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n className={cn(\n \"h-10 w-full justify-start truncate px-3 text-left font-normal\",\n hasValue ? \"border-primary/30 bg-primary/5 text-foreground\" : \"bg-transparent text-muted-foreground\",\n className,\n )}\n >\n <Calendar className={cn(\"mr-2 h-4 w-4 shrink-0\", hasValue ? \"text-primary\" : \"opacity-40\")} aria-hidden />\n <span className=\"truncate text-sm\">{formatRangeLabel(startDate, endDate, emptyLabel)}</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-[340px] overflow-hidden p-0\" align=\"start\">\n <div className=\"space-y-2 p-3\">\n <p className=\"px-1 text-[10px] font-bold uppercase tracking-wider text-muted-foreground\">Período personalizado</p>\n <DateRangeCalendar value={{ startDate, endDate }} onChange={onChange} placeholder=\"Selecionar período\" />\n </div>\n\n {(presets.length > 0 || hasValue) && <div className=\"mx-3 h-px bg-border\" />}\n\n <div className=\"space-y-2 p-3\">\n {presets.length > 0 && (\n <>\n <p className=\"px-1 text-[10px] font-bold uppercase tracking-wider text-muted-foreground\">Atalhos</p>\n <div className=\"grid grid-cols-3 gap-2\">\n {presets.map((preset) => {\n const active = isPresetActive(preset, { startDate, endDate })\n const Icon = preset.icon\n return (\n <button\n key={preset.key}\n type=\"button\"\n aria-pressed={active}\n onClick={() => onChange(preset.getRange())}\n className={cn(\n \"flex flex-col items-center gap-1.5 rounded-lg border px-2 py-2.5 text-xs transition-all\",\n active\n ? \"border-primary bg-primary text-primary-foreground shadow-sm shadow-primary/20\"\n : \"border-border text-muted-foreground hover:border-primary/30 hover:bg-primary/5 hover:text-foreground\",\n )}\n >\n <Icon size={15} className={active ? \"opacity-90\" : \"opacity-50\"} aria-hidden />\n <span className={cn(\"text-center font-medium leading-none\", active && \"font-semibold\")}>{preset.label}</span>\n </button>\n )\n })}\n </div>\n </>\n )}\n {hasValue && (\n <button\n type=\"button\"\n onClick={() => onChange({ startDate: \"\", endDate: \"\" })}\n className=\"w-full pt-0.5 text-center text-[10px] text-muted-foreground/50 transition-colors hover:text-destructive\"\n >\n Limpar período\n </button>\n )}\n </div>\n </PopoverContent>\n </Popover>\n )\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport { format, isBefore, isSameDay, isValid, parse, startOfDay } from \"date-fns\"\nimport type { DateRange } from \"react-day-picker\"\nimport { Calendar as CalendarIcon } from \"lucide-react\"\n\nimport { Button } from \"./button\"\nimport { Calendar } from \"./calendar\"\nimport { Popover, PopoverContent, PopoverTrigger } from \"./popover\"\nimport { cn } from \"../../lib/utils\"\n\n/**\n * Calendário de intervalo — cópia do `DeliveryDateRangePicker` do Smart Desk (dayjs → date-fns;\n * prévia na cor primária). 1º clique marca o início, 2º marca o fim e fecha; clicar antes do\n * início inverte as pontas. Valores `yyyy-MM-dd` (vazio = `\"\"`).\n */\n\nexport interface DateRangeValue {\n startDate: string\n endDate: string\n}\n\ninterface DateRangeCalendarProps {\n value: DateRangeValue\n onChange: (value: DateRangeValue) => void\n placeholder?: string\n className?: string\n}\n\nconst ISO = \"yyyy-MM-dd\"\n\nexport function parseIsoDate(value: string): Date | undefined {\n if (!value) return undefined\n const parsed = parse(value, ISO, new Date())\n return isValid(parsed) ? parsed : undefined\n}\n\nexport const toIsoDate = (value: Date): string => format(value, ISO)\n\nconst display = (value: string) => {\n const date = parseIsoDate(value)\n return date ? format(date, \"dd/MM/yyyy\") : value\n}\n\nexport function formatRangeLabel(startDate: string, endDate: string, placeholder: string): string {\n if (!startDate && !endDate) return placeholder\n if (startDate && !endDate) return `Desde ${display(startDate)}`\n if (!startDate && endDate) return `Até ${display(endDate)}`\n return `${display(startDate)} - ${display(endDate)}`\n}\n\nfunction DateRangeCalendarImpl({ value, onChange, placeholder = \"Selecionar período\", className }: DateRangeCalendarProps) {\n const [open, setOpen] = React.useState(false)\n const [hoveredDate, setHoveredDate] = React.useState<Date | undefined>(undefined)\n const selectedFrom = parseIsoDate(value.startDate)\n const selectedTo = parseIsoDate(value.endDate)\n const selected: DateRange | undefined = selectedFrom || selectedTo ? { from: selectedFrom, to: selectedTo } : undefined\n const previewRange = (() => {\n if (!selectedFrom || selectedTo || !hoveredDate) return null\n const start = startOfDay(selectedFrom)\n const hover = startOfDay(hoveredDate)\n if (isSameDay(hover, start)) return null\n return isBefore(hover, start) ? { from: hover, to: start } : { from: start, to: hover }\n })()\n const hasValue = Boolean(value.startDate || value.endDate)\n\n const isPreviewDate = (date: Date) => {\n if (!previewRange || !selectedFrom) return false\n const day = startOfDay(date)\n return !isSameDay(day, selectedFrom) && !isBefore(day, previewRange.from) && !isBefore(previewRange.to, day)\n }\n\n const handleDayClick = (date: Date) => {\n const clickedDate = toIsoDate(date)\n const start = value.endDate ? undefined : parseIsoDate(value.startDate)\n setHoveredDate(undefined)\n if (!start) {\n onChange({ startDate: clickedDate, endDate: \"\" })\n return\n }\n const next = isBefore(startOfDay(date), startOfDay(start))\n ? { startDate: clickedDate, endDate: toIsoDate(start) }\n : { startDate: value.startDate, endDate: clickedDate }\n onChange(next)\n setOpen(false)\n }\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button type=\"button\" variant=\"outline\" className={cn(\"h-10 w-full justify-start truncate bg-transparent px-3 text-left font-normal\", !hasValue && \"text-muted-foreground\", className)}>\n <CalendarIcon className=\"mr-2 h-4 w-4 shrink-0\" />\n <span className=\"truncate\">{formatRangeLabel(value.startDate, value.endDate, placeholder)}</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <Calendar\n mode=\"range\"\n selected={selected}\n defaultMonth={selected?.from ?? selected?.to}\n onDayClick={handleDayClick}\n onDayMouseEnter={(date) => {\n if (value.startDate && !value.endDate) setHoveredDate(date)\n }}\n onDayMouseLeave={() => setHoveredDate(undefined)}\n modifiers={{ rangePreview: isPreviewDate }}\n modifiersClassNames={{ rangePreview: \"[&>button]:bg-primary/20 [&>button]:text-foreground\" }}\n />\n </PopoverContent>\n </Popover>\n )\n}\n\n/** Memoizado como no Smart Desk: consumidores que re-renderizam não engolem cliques de navegação. */\nexport const DateRangeCalendar = React.memo(DateRangeCalendarImpl)\nDateRangeCalendar.displayName = \"DateRangeCalendar\"\n","\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronLeft, ChevronRight } from \"lucide-react\"\nimport { DayPicker } from \"react-day-picker\"\nimport { ptBR } from \"date-fns/locale\"\n\nimport { cn } from \"../../lib/utils\"\nimport { buttonVariants } from \"./button\"\n\n\nexport type CalendarProps = React.ComponentProps<typeof DayPicker>\n\nexport function Calendar({\n className,\n classNames,\n showOutsideDays = true,\n fixedWeeks = true,\n ...props\n}: CalendarProps) {\n return (\n <DayPicker\n locale={ptBR}\n showOutsideDays={showOutsideDays}\n fixedWeeks={fixedWeeks}\n className={cn(\"p-3\", className)}\n classNames={{\n months: \"relative flex flex-col sm:flex-row gap-2\",\n month: \"flex flex-col gap-3\",\n month_caption: \"flex h-9 items-center justify-center\",\n caption_label: \"text-sm font-medium capitalize\",\n nav: \"pointer-events-none absolute top-0 left-0 right-0 z-30 flex h-9 items-center justify-between px-1\",\n button_previous:\n \"pointer-events-auto inline-flex h-9 w-9 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-accent-foreground disabled:opacity-40 disabled:hover:bg-transparent disabled:hover:text-muted-foreground\",\n button_next:\n \"pointer-events-auto inline-flex h-9 w-9 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-accent-foreground disabled:opacity-40 disabled:hover:bg-transparent disabled:hover:text-muted-foreground\",\n month_grid: \"w-full border-collapse\",\n weekdays: \"flex\",\n weekday: \"text-muted-foreground rounded-md w-8 font-normal text-[0.7rem] uppercase\",\n week: \"flex w-full mt-1\",\n day: \"relative h-8 w-8 text-center text-sm p-0 focus-within:relative focus-within:z-20\",\n day_button: cn(\n buttonVariants({ variant: \"ghost\" }),\n \"h-8 w-8 p-0 font-normal aria-selected:opacity-100\",\n ),\n range_start: \"day-range-start\",\n range_end: \"day-range-end\",\n selected:\n // Cor primária do tema (`primary`), nunca fixa.\n \"[&>button]:bg-primary [&>button]:text-primary-foreground [&>button]:hover:bg-primary/90 [&>button]:hover:text-primary-foreground [&>button]:focus:bg-primary/90 [&>button]:focus:text-primary-foreground\",\n today: \"[&>button]:bg-accent [&>button]:text-accent-foreground\",\n outside:\n \"day-outside text-muted-foreground aria-selected:bg-accent/50 aria-selected:text-muted-foreground\",\n disabled: \"text-muted-foreground opacity-40 line-through\",\n range_middle:\n \"aria-selected:bg-accent aria-selected:text-accent-foreground\",\n hidden: \"invisible\",\n ...classNames,\n }}\n components={{\n Chevron: ({ orientation }) =>\n orientation === \"left\" ? (\n <ChevronLeft className=\"h-4 w-4\" />\n ) : (\n <ChevronRight className=\"h-4 w-4\" />\n ),\n }}\n {...props}\n />\n )\n}\nCalendar.displayName = \"Calendar\"\n","\"use client\"\n\nimport { useCallback, useMemo } from \"react\"\nimport type { Edge, Node } from \"@xyflow/react\"\nimport { agentReach } from \"../../network/network-math\"\nimport { layoutOverview, OVERVIEW_LINK_BEND, overviewInitialBounds, type OverviewLayoutMode } from \"../../network/overview-layout\"\nimport type { NetworkAgent, NetworkChannel, NetworkLink, NetworkMemory } from \"../../network/types\"\nimport { NetworkLiveProvider } from \"./live\"\nimport { NetworkCanvas } from \"./NetworkCanvas\"\nimport { AgentNode, ChannelNode, type AgentNodeData, type ChannelNodeData } from \"./nodes\"\nimport { RecenterButton } from \"./RecenterButton\"\nimport { StatList, StatsCard } from \"./StatsCard\"\nimport { channelNodesOf, ChannelStatList, overviewStatRows, useChannelCounts, useHubLive } from \"./overview-shared\"\nimport { useStable } from \"./useStableNodes\"\nimport { useEngramindConfig } from \"../../../lib/config\"\n\nconst NODE_TYPES = { agent: AgentNode, channel: ChannelNode }\n\nexport interface OverviewViewProps {\n /** Agentes do app aberto (OPE-129: a visão é sempre de um app). */\n agents: NetworkAgent[]\n /** Canais ligados aos agentes do app, já sem os vazios. */\n channels: NetworkChannel[]\n /** Canais do app sem memórias: fora da rede, acessíveis pelo menu do card de estatísticas. */\n emptyChannels?: NetworkChannel[]\n links: NetworkLink[]\n memories: NetworkMemory[]\n /** Todas as memórias da rede (criações por agente: a partícula verde não depende dos filtros da visão). */\n allMemories?: NetworkMemory[]\n /** Título do card de estatísticas (o nome do app). */\n title?: string\n /** Distribuição da visão (escolhida no card \"O que é o Engramind\"; guardada no navegador). */\n layout: OverviewLayoutMode\n /** Busca/filtros: memórias que casam por canal (`null` = sem filtro). */\n hitsByChannel: Map<string, number> | null\n onOpenAgent: (agent: string) => void\n onOpenChannel: (slug: string) => void\n onChannelMenu: (slug: string) => void\n}\n\n/** Ids das arestas agente → canal (um link por canal casado). */\nexport const linkEdgeId = (agent: string, channel: string) => `${agent}→${channel}`\nconst agentNodeKey = (agent: string) => `agent:${agent}`\n\n/**\n * Visão Agentes x canais de um app (aberta pela visão inicial Apps x canais, OPE-129): os agentes do\n * app e os canais que eles assinam, na distribuição escolhida no card \"O que é o Engramind\" (Órbita ou\n * Radial), com os cards pelo tamanho. O consumo ao vivo de um agente pulsa o agente, manda a\n * partícula ao canal e, se ele entregou memórias, de volta ao agente.\n */\nexport function OverviewView({ agents, channels, emptyChannels = [], links, memories, allMemories, title = \"Rede\", layout, hitsByChannel, onOpenAgent, onOpenChannel, onChannelMenu }: OverviewViewProps) {\n const agentIds = useMemo(() => new Set(agents.map((agent) => agent.id)), [agents])\n const visibleLinks = useMemo(() => links.filter((link) => agentIds.has(link.agent)), [links, agentIds])\n const { countByChannel, totalByChannel } = useChannelCounts(memories)\n const reach = useMemo(() => agentReach(visibleLinks, countByChannel), [visibleLinks, countByChannel])\n const positions = useMemo(() => layoutOverview({ agents, channels, links: visibleLinks, agentCounts: reach, channelCounts: totalByChannel, mode: layout }), [agents, channels, visibleLinks, reach, totalByChannel, layout])\n const initialBounds = useMemo(() => overviewInitialBounds(positions), [positions])\n // Gravadas: só quando o app conhece as gravações do agente (`agentWrites`); os demais mostram só as acessíveis.\n const { agentWrites } = useEngramindConfig()\n const writtenOf = useCallback((id: string) => agentWrites?.(id) ?? null, [agentWrites])\n\n const hubOf = useCallback((agent: string) => (agentIds.has(agent) ? agent : null), [agentIds])\n const hubLinks = useMemo(() => visibleLinks.map((link) => ({ hub: link.agent, channel: link.channel })), [visibleLinks])\n const live = useHubLive({ hubOf, links: hubLinks, edgeOf: linkEdgeId, nodeKey: agentNodeKey, channels, memories: allMemories ?? memories })\n\n const nodes = useMemo<Node[]>(() => {\n const list: Node[] = agents.map((agent) => {\n const point = positions.agents.get(agent.id) ?? { x: 0, y: 0 }\n const data: AgentNodeData = { id: agent.id, name: agent.name, app: agent.app, written: writtenOf(agent.id), reachable: reach.get(agent.id) ?? 0, scale: positions.scales.get(`agent:${agent.id}`), point }\n return { id: agentNodeKey(agent.id), type: \"agent\", position: point, data }\n })\n return [...list, ...channelNodesOf({ channels, positions, countByChannel, hitsByChannel, onChannelMenu })]\n }, [agents, channels, positions, hitsByChannel, countByChannel, onChannelMenu, writtenOf, reach])\n\n const edges = useMemo<Edge[]>(\n () =>\n // Links vizinhos do mesmo canal curvam para lados alternados (não se sobrepõem por inteiro).\n visibleLinks.map((link, index) => ({\n id: linkEdgeId(link.agent, link.channel),\n source: agentNodeKey(link.agent),\n target: `channel:${link.channel}`,\n type: \"link\",\n data: { mode: link.mode, dimmed: hitsByChannel ? !hitsByChannel.get(link.channel) : false, bend: index % 2 ? -OVERVIEW_LINK_BEND : OVERVIEW_LINK_BEND },\n })),\n [visibleLinks, hitsByChannel],\n )\n const stableNodes = useStable(nodes)\n const stableEdges = useStable(edges)\n\n return (\n <NetworkLiveProvider value={live.value}>\n <NetworkCanvas\n nodes={stableNodes}\n edges={stableEdges}\n nodeTypes={NODE_TYPES}\n fitKey={`overview:${agents.length}:${channels.length}:${layout}`}\n initialBounds={initialBounds}\n label=\"Rede de agentes e canais\"\n onNodeClick={(_event, node) => (node.type === \"agent\" ? onOpenAgent((node.data as AgentNodeData).id) : node.type === \"channel\" && onOpenChannel((node.data as ChannelNodeData).slug))}\n onNodeContextMenu={(event, node) => {\n if (node.type !== \"channel\") return\n event.preventDefault()\n onChannelMenu((node.data as ChannelNodeData).slug)\n }}\n >\n <StatsCard\n title={title}\n summary={`${agents.length} ${agents.length === 1 ? \"agente\" : \"agentes\"} · ${channels.length} ${channels.length === 1 ? \"canal\" : \"canais\"}`}\n rows={overviewStatRows({ hub: { label: \"Agentes\", value: agents.length, testId: \"stat-agents\" }, channels: channels.length, memories, liveCount: live.liveCount })}\n >\n <ChannelStatList channels={channels} countByChannel={countByChannel} emptyChannels={emptyChannels} onOpenChannel={onChannelMenu} />\n <StatList title=\"Por agente (alcance)\" testId=\"stats-by-agent\" items={agents.map((agent) => ({ key: agent.id, label: agent.name, count: reach.get(agent.id) ?? 0 })).sort((a, b) => b.count - a.count)} />\n </StatsCard>\n <RecenterButton />\n </NetworkCanvas>\n </NetworkLiveProvider>\n )\n}\n","\"use client\"\n\nimport { useCallback, useMemo } from \"react\"\nimport type { Node } from \"@xyflow/react\"\nimport { MoreHorizontal } from \"lucide-react\"\nimport { Button } from \"../../../components/ui/button\"\nimport { cn } from \"../../../lib/utils\"\nimport type { AgentWrite } from \"../../network/network-math\"\nimport type { OverviewLayout } from \"../../network/overview-layout\"\nimport type { ConsumptionEvent, NetworkChannel, NetworkMemory } from \"../../network/types\"\nimport { useEngramindConsumption, useLiveEffects } from \"../../hooks/useEngramindConsumption\"\nimport { ChannelDisplayName } from \"./ChannelName\"\nimport type { ChannelNodeData } from \"./nodes\"\nimport { StatList, type StatRow } from \"./StatsCard\"\nimport { useAgentWrites } from \"./useAgentWrites\"\n\n/**\n * Peças comuns das duas visões de rede (OPE-129): Agentes x canais (`OverviewView`) e Apps x canais\n * (`AppsOverviewView`). O \"hub\" é o card ligado aos canais: o agente numa, o app na outra.\n */\n\nconst TRAVEL_MS = 900\n\n/** Memórias por canal: ativas (rótulo do card e alcance) e todas, inclusive inativas (tamanho do card). */\nexport function useChannelCounts(memories: readonly NetworkMemory[]) {\n return useMemo(() => {\n const active = new Map<string, number>()\n const total = new Map<string, number>()\n for (const memory of memories) {\n total.set(memory.channel, (total.get(memory.channel) ?? 0) + 1)\n if (memory.status !== \"archived\") active.set(memory.channel, (active.get(memory.channel) ?? 0) + 1)\n }\n return { countByChannel: active, totalByChannel: total }\n }, [memories])\n}\n\n/** Nodes dos canais da visão (posição e escala do layout; \"N na busca\" com filtro). */\nexport function channelNodesOf(input: { channels: readonly NetworkChannel[]; positions: OverviewLayout; countByChannel: ReadonlyMap<string, number>; hitsByChannel: Map<string, number> | null; onChannelMenu: (slug: string) => void }): Node[] {\n const { channels, positions, countByChannel, hitsByChannel, onChannelMenu } = input\n return channels.map((channel) => {\n const hits = hitsByChannel ? (hitsByChannel.get(channel.slug) ?? 0) : null\n const point = positions.channels.get(channel.slug) ?? { x: 0, y: 0 }\n const data: ChannelNodeData = { slug: channel.slug, name: channel.name, count: countByChannel.get(channel.slug) ?? 0, archived: channel.archived, hits, dimmed: hits === 0, onMenu: onChannelMenu, scale: positions.scales.get(`channel:${channel.slug}`), point }\n return { id: `channel:${channel.slug}`, type: \"channel\", position: point, data }\n })\n}\n\n/** Linhas do card de estatísticas: o hub (agentes ou apps), canais, memórias e consumos ao vivo. */\nexport function overviewStatRows(input: { hub: StatRow; channels: number; memories: readonly NetworkMemory[]; liveCount: number }): StatRow[] {\n const active = input.memories.filter((memory) => memory.status !== \"archived\").length\n return [\n input.hub,\n { label: \"Canais\", value: input.channels, testId: \"stat-channels\" },\n { label: \"Memórias ativas\", value: active, testId: \"stat-active\" },\n { label: \"Memórias inativas\", value: input.memories.length - active, testId: \"stat-inactive\" },\n { label: \"Consumos ao vivo\", value: input.liveCount, testId: \"stat-live\" },\n ]\n}\n\n/**\n * Canais fora da rede por não terem memória (OPE-129): sem node, o menu do canal só fica acessível\n * aqui (ou no estado vazio do app). Abrir leva ao `ChannelPanel` — editar, assinantes, configurações,\n * arquivar/restaurar e excluir de vez.\n */\nexport function EmptyChannelList({ channels, onOpen, className }: { channels: readonly NetworkChannel[]; onOpen: (slug: string) => void; className?: string }) {\n return (\n <div className={cn(\"mt-3 border-t pt-2\", className)} data-testid=\"empty-channels\">\n <p className=\"mb-1 font-semibold text-foreground\">Sem memórias ({channels.length})</p>\n <p className=\"mb-1 text-[11px] text-muted-foreground\">Fora da rede até a primeira memória. Abra o canal para editar, ver assinantes ou arquivar.</p>\n <ul className=\"max-h-40 space-y-0.5 overflow-y-auto pr-1\">\n {channels.map((channel) => (\n <li key={channel.slug} className=\"flex items-center gap-1.5\">\n <ChannelDisplayName slug={channel.slug} className=\"min-w-0 flex-1 text-muted-foreground\" />\n <Button type=\"button\" variant=\"ghost\" size=\"icon\" aria-label={`Abrir o canal ${channel.slug}`} className=\"h-6 w-6 shrink-0 text-muted-foreground\" onClick={() => onOpen(channel.slug)}>\n <MoreHorizontal className=\"h-3.5 w-3.5\" aria-hidden />\n </Button>\n </li>\n ))}\n </ul>\n </div>\n )\n}\n\n/** Lista \"Por canal\" do card de estatísticas (nome legível, maior primeiro) e os canais sem memórias. */\nexport function ChannelStatList({ channels, countByChannel, emptyChannels = [], onOpenChannel }: { channels: readonly NetworkChannel[]; countByChannel: ReadonlyMap<string, number>; emptyChannels?: readonly NetworkChannel[]; onOpenChannel?: (slug: string) => void }) {\n const items = channels.map((channel) => ({ key: channel.slug, label: channel.slug, node: <ChannelDisplayName slug={channel.slug} className=\"min-w-0 flex-1 text-muted-foreground\" />, count: countByChannel.get(channel.slug) ?? 0 })).sort((a, b) => b.count - a.count)\n return (\n <>\n <StatList title=\"Por canal\" testId=\"stats-by-channel\" items={items} />\n {emptyChannels.length > 0 && onOpenChannel && <EmptyChannelList channels={emptyChannels} onOpen={onOpenChannel} />}\n </>\n )\n}\n\nexport interface HubLinkRef {\n hub: string\n channel: string\n}\n\n/**\n * Tempo real da visão: o consumo ao vivo de um agente pulsa o hub dele, manda a partícula pelo link\n * hub → canal e, se entregou memórias, de volta; a memória criada por um agente manda a partícula\n * verde. `hubOf` devolve o hub do agente na visão; o agente fora da tela (de outro app) só pulsa os\n * canais visíveis que entregaram. Consumo sem nenhuma memória carregada na tela é ignorado.\n */\nexport function useHubLive(input: { hubOf: (agent: string) => string | null; links: readonly HubLinkRef[]; edgeOf: (hub: string, channel: string) => string; nodeKey: (hub: string) => string; channels: readonly NetworkChannel[]; memories: readonly NetworkMemory[] }) {\n const { hubOf, links, edgeOf, nodeKey, channels, memories } = input\n const live = useLiveEffects(null)\n const linked = useCallback((hub: string, channel: string) => links.some((link) => link.hub === hub && link.channel === channel), [links])\n\n const loaded = useMemo(() => new Set(memories.map((memory) => memory.id)), [memories])\n const visibleChannels = useMemo(() => new Set(channels.map((channel) => channel.slug)), [channels])\n const onConsumption = useCallback(\n (event: ConsumptionEvent) => {\n if (!event.memoryIds.some((id) => loaded.has(id))) return\n const hub = hubOf(event.agent)\n if (!hub) {\n const shown = (event.delivered ?? event.channels).filter((slug) => visibleChannels.has(slug))\n if (!shown.length) return\n live.countEvent()\n live.pulse(shown.map((slug) => `channel:${slug}`))\n return\n }\n live.countEvent()\n const reached = event.channels.filter((slug) => linked(hub, slug))\n const delivered = (event.delivered ?? []).filter((slug) => reached.includes(slug))\n live.pulse([nodeKey(hub)])\n live.travel(reached.map((slug) => ({ edge: edgeOf(hub, slug), reverse: false, tone: \"primary\" as const, delayMs: 0 })))\n live.pulse(\n reached.map((slug) => `channel:${slug}`),\n TRAVEL_MS,\n )\n live.travel(delivered.map((slug) => ({ edge: edgeOf(hub, slug), reverse: true, tone: \"primary\" as const, delayMs: TRAVEL_MS + 150 })))\n if (delivered.length) live.pulse([nodeKey(hub)], 2 * TRAVEL_MS + 150)\n },\n [hubOf, linked, nodeKey, edgeOf, live, loaded, visibleChannels],\n )\n useEngramindConsumption(onConsumption)\n\n // Memória criada por um agente: pulso no hub, partícula verde até o canal e pulso no canal.\n const channelSlugs = useMemo(() => new Set(channels.map((channel) => channel.slug)), [channels])\n const onWrite = useCallback(\n (writes: AgentWrite[]) => {\n const mine = writes.flatMap((write) => {\n const hub = hubOf(write.agent)\n return hub && channelSlugs.has(write.channel) ? [{ hub, channel: write.channel }] : []\n })\n if (!mine.length) return\n live.pulse([...new Set(mine.map((write) => nodeKey(write.hub)))])\n const withLink = mine.filter((write) => linked(write.hub, write.channel))\n live.travel(withLink.map((write) => ({ edge: edgeOf(write.hub, write.channel), reverse: false, tone: \"success\" as const, delayMs: 0 })))\n live.pulse([...new Set(mine.map((write) => `channel:${write.channel}`))], withLink.length ? TRAVEL_MS : 0)\n },\n [hubOf, channelSlugs, linked, nodeKey, edgeOf, live],\n )\n useAgentWrites(memories, onWrite)\n\n const value = useMemo(() => ({ pulses: live.pulses, travels: live.travels, finish: live.finish }), [live.pulses, live.travels, live.finish])\n return { value, liveCount: live.liveCount }\n}\n","\"use client\"\n\nimport { useEffect, useMemo, useRef } from \"react\"\nimport { agentWritesOf, type AgentWrite } from \"../../network/network-math\"\nimport type { NetworkMemory } from \"../../network/types\"\nimport { useEnteringIds } from \"./useEnteringIds\"\n\n/**\n * Memórias que um agente acabou de criar (OPE-113): ids que chegam depois da primeira carga\n * (`useEnteringIds`), com agente autor e criados há pouco (`agentWritesOf`). `onWrite` recebe as\n * criações uma vez, para a partícula verde do agente até o canal.\n */\nexport function useAgentWrites(memories: readonly NetworkMemory[], onWrite: (writes: AgentWrite[]) => void): void {\n const ids = useMemo(() => memories.map((memory) => memory.id), [memories])\n const memoriesRef = useRef(memories)\n const onWriteRef = useRef(onWrite)\n useEffect(() => {\n memoriesRef.current = memories\n onWriteRef.current = onWrite\n })\n useEnteringIds(ids, {\n onEnter: (fresh) => {\n const writes = agentWritesOf(fresh, memoriesRef.current)\n if (writes.length) onWriteRef.current(writes)\n },\n })\n}\n","\"use client\"\n\nimport { useCallback, useMemo } from \"react\"\nimport type { Edge, Node } from \"@xyflow/react\"\nimport { appLinkEdgeId, appLinks, appOfAgent, appReach } from \"../../network/app-network\"\nimport { layoutOverview, OVERVIEW_LINK_BEND, overviewInitialBounds, type OverviewLayoutMode } from \"../../network/overview-layout\"\nimport type { NetworkAgent, NetworkChannel, NetworkLink, NetworkMemory } from \"../../network/types\"\nimport { NetworkLiveProvider } from \"./live\"\nimport { NetworkCanvas } from \"./NetworkCanvas\"\nimport { AppNode, ChannelNode, type AppNodeData, type ChannelNodeData } from \"./nodes\"\nimport { RecenterButton } from \"./RecenterButton\"\nimport { StatList, StatsCard } from \"./StatsCard\"\nimport { channelNodesOf, ChannelStatList, overviewStatRows, useChannelCounts, useHubLive } from \"./overview-shared\"\nimport { useStable } from \"./useStableNodes\"\nimport type { LinkEdgeData } from \"./edges\"\n\nconst NODE_TYPES = { app: AppNode, channel: ChannelNode }\nconst appNodeKey = (app: string) => `app:${app}`\nconst plural = (count: number, one: string, many: string) => `${count} ${count === 1 ? one : many}`\n\nexport interface AppsOverviewViewProps {\n /** Apps ativos do Engramind. */\n apps: { slug: string; name: string }[]\n /** Agentes ativos (contagem por app). */\n agents: NetworkAgent[]\n /** Canais da rede, já sem os vazios. */\n channels: NetworkChannel[]\n /** Canais sem memórias: fora da rede, acessíveis pelo menu do card de estatísticas. */\n emptyChannels?: NetworkChannel[]\n /** Assinaturas por agente (agregadas aqui por app). */\n links: NetworkLink[]\n memories: NetworkMemory[]\n /** Todas as memórias da rede (partícula verde de criação). */\n allMemories?: NetworkMemory[]\n layout: OverviewLayoutMode\n hitsByChannel: Map<string, number> | null\n onOpenApp: (app: string) => void\n onOpenChannel: (slug: string) => void\n onChannelMenu: (slug: string) => void\n}\n\n/**\n * Visão inicial de `/engramind` (OPE-129): os apps do Engramind e os canais, ligados pelas assinaturas\n * dos agentes de cada app (um link por app e canal). Mesmo canvas, distribuições e escala da visão\n * Agentes x canais; clicar no app abre essa visão restrita a ele.\n */\nexport function AppsOverviewView({ apps, agents, channels, emptyChannels = [], links, memories, allMemories, layout, hitsByChannel, onOpenApp, onOpenChannel, onChannelMenu }: AppsOverviewViewProps) {\n const appSlugs = useMemo(() => new Set(apps.map((app) => app.slug)), [apps])\n const agentsByApp = useMemo(() => {\n const counts = new Map<string, number>()\n for (const agent of agents) counts.set(agent.app, (counts.get(agent.app) ?? 0) + 1)\n return counts\n }, [agents])\n const activeAgents = useMemo(() => new Set(agents.map((agent) => agent.id)), [agents])\n const aggregated = useMemo(() => appLinks(links.filter((link) => activeAgents.has(link.agent) && appSlugs.has(appOfAgent(link.agent)))), [links, activeAgents, appSlugs])\n const { countByChannel, totalByChannel } = useChannelCounts(memories)\n const reach = useMemo(() => appReach(aggregated, countByChannel), [aggregated, countByChannel])\n // O layout trata os apps como os \"agentes\" da visão: as distribuições valem iguais.\n const hubs = useMemo(() => apps.map((app) => ({ id: app.slug, app: app.slug })), [apps])\n const layoutLinks = useMemo(() => aggregated.map((link) => ({ agent: link.app, channel: link.channel })), [aggregated])\n const positions = useMemo(() => layoutOverview({ agents: hubs, channels, links: layoutLinks, agentCounts: reach, channelCounts: totalByChannel, mode: layout }), [hubs, channels, layoutLinks, reach, totalByChannel, layout])\n const initialBounds = useMemo(() => overviewInitialBounds(positions), [positions])\n\n const hubOf = useCallback((agent: string) => (activeAgents.has(agent) && appSlugs.has(appOfAgent(agent)) ? appOfAgent(agent) : null), [activeAgents, appSlugs])\n const hubLinks = useMemo(() => aggregated.map((link) => ({ hub: link.app, channel: link.channel })), [aggregated])\n const live = useHubLive({ hubOf, links: hubLinks, edgeOf: appLinkEdgeId, nodeKey: appNodeKey, channels, memories: allMemories ?? memories })\n\n const nodes = useMemo<Node[]>(() => {\n const list: Node[] = apps.map((app) => {\n const point = positions.agents.get(app.slug) ?? { x: 0, y: 0 }\n const data: AppNodeData = { slug: app.slug, name: app.name, agents: agentsByApp.get(app.slug) ?? 0, reachable: reach.get(app.slug) ?? 0, scale: positions.scales.get(`agent:${app.slug}`), point }\n return { id: appNodeKey(app.slug), type: \"app\", position: point, data }\n })\n return [...list, ...channelNodesOf({ channels, positions, countByChannel, hitsByChannel, onChannelMenu })]\n }, [apps, channels, positions, agentsByApp, reach, countByChannel, hitsByChannel, onChannelMenu])\n\n const edges = useMemo<Edge[]>(\n () =>\n aggregated.map((link, index) => {\n const data: LinkEdgeData = {\n mode: link.modes[0] ?? \"inject\",\n label: `${plural(link.agents.length, \"agente\", \"agentes\")} · ${link.modes.join(\", \")}`,\n dimmed: hitsByChannel ? !hitsByChannel.get(link.channel) : false,\n bend: index % 2 ? -OVERVIEW_LINK_BEND : OVERVIEW_LINK_BEND,\n }\n return { id: link.id, source: appNodeKey(link.app), target: `channel:${link.channel}`, type: \"link\", data }\n }),\n [aggregated, hitsByChannel],\n )\n const stableNodes = useStable(nodes)\n const stableEdges = useStable(edges)\n\n return (\n <NetworkLiveProvider value={live.value}>\n <NetworkCanvas\n nodes={stableNodes}\n edges={stableEdges}\n nodeTypes={NODE_TYPES}\n fitKey={`apps:${apps.length}:${channels.length}:${layout}`}\n initialBounds={initialBounds}\n label=\"Rede de apps e canais\"\n onNodeClick={(_event, node) => (node.type === \"app\" ? onOpenApp((node.data as AppNodeData).slug) : node.type === \"channel\" && onOpenChannel((node.data as ChannelNodeData).slug))}\n onNodeContextMenu={(event, node) => {\n if (node.type !== \"channel\") return\n event.preventDefault()\n onChannelMenu((node.data as ChannelNodeData).slug)\n }}\n >\n <StatsCard\n title=\"Rede\"\n summary={`${plural(apps.length, \"app\", \"apps\")} · ${plural(channels.length, \"canal\", \"canais\")}`}\n rows={overviewStatRows({ hub: { label: \"Apps\", value: apps.length, testId: \"stat-apps\" }, channels: channels.length, memories, liveCount: live.liveCount })}\n >\n <ChannelStatList channels={channels} countByChannel={countByChannel} emptyChannels={emptyChannels} onOpenChannel={onChannelMenu} />\n <StatList title=\"Por app (alcance)\" testId=\"stats-by-app\" items={apps.map((app) => ({ key: app.slug, label: app.name, count: reach.get(app.slug) ?? 0 })).sort((a, b) => b.count - a.count)} />\n </StatsCard>\n <RecenterButton />\n </NetworkCanvas>\n </NetworkLiveProvider>\n )\n}\n","\"use client\"\n\nimport { AnimatePresence, motion } from \"framer-motion\"\nimport { Settings } from \"lucide-react\"\nimport { Button } from \"../../../components/ui/button\"\nimport { OptionTabs } from \"../../../components/ui/option-tabs\"\nimport { useEngramindConfig, useT, type FooterContext } from \"../../../lib/config\"\nimport { OVERVIEW_LAYOUT_LABEL, OVERVIEW_LAYOUT_MODES } from \"../../network/overview-layout\"\nimport { Section } from \"../shared/Section\"\n\nconst LAYOUT_OPTIONS = OVERVIEW_LAYOUT_MODES.map((mode) => ({ value: mode, label: OVERVIEW_LAYOUT_LABEL[mode] }))\n\n/**\n * Fim da página da rede: o `slots.footer` do app (ex.: o card \"O que é o Engramind\" do Opex) ou, sem ele,\n * um card com a distribuição da visão inicial (Órbita ou Radial; só fora dos universos) e Configurar.\n */\nexport function NetworkFooter(context: FooterContext) {\n const { slots, onConfigure } = useEngramindConfig()\n const t = useT()\n if (slots.footer) return <>{slots.footer(context)}</>\n const { layout } = context\n if (!layout && !onConfigure) return null\n return (\n <Section\n title=\"Rede\"\n className=\"mt-3\"\n actions={\n <div data-testid=\"network-footer-actions\" className=\"flex flex-wrap items-center gap-2\">\n <AnimatePresence initial={false}>\n {layout && (\n <motion.div key=\"layout\" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} transition={{ duration: 0.15 }}>\n <OptionTabs aria-label={t(\"network.layout\")} size=\"sm\" options={LAYOUT_OPTIONS} value={layout.value} onChange={layout.onChange} />\n </motion.div>\n )}\n </AnimatePresence>\n {onConfigure && (\n <Button type=\"button\" size=\"sm\" variant=\"outline\" onClick={() => onConfigure(\"connection\")}>\n <Settings className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden /> {t(\"network.configure\")}\n </Button>\n )}\n </div>\n }\n >\n <p className=\"text-sm text-muted-foreground\">Agentes, canais e memórias do app no Engramind.</p>\n </Section>\n )\n}\n","\"use client\"\n\nimport { useMemo, useState } from \"react\"\nimport { useMutation, useQueryClient, type InfiniteData, type QueryKey } from \"@tanstack/react-query\"\nimport { toast } from \"../../../lib/toast\"\nimport { apiErrorCode, apiErrorMessage } from \"../../../lib/api\"\nimport { ConfirmDialog } from \"../../../components/ui/confirm-dialog\"\nimport type { MemoryTextLimits } from \"../../memory-text\"\nimport type { NetworkMemory } from \"../../network/types\"\nimport type { Category, EngramindChannel, EngramindMemory } from \"../../types\"\nimport { areaKey, engramindGet, engramindSend, route, useEngramindMutation } from \"../../hooks/useEngramind\"\nimport { toNetworkMemory } from \"../../hooks/useEngramindNetwork\"\nimport { MemoryHistoryDialog } from \"../page/memories/MemoryHistoryDialog\"\nimport { MoveMemoryDialog } from \"../page/memories/MoveMemoryDialog\"\nimport { useLocalRemovals } from \"./useLocalRemovals\"\nimport type { MemoryCardActions } from \"./MemoryCard\"\nimport { MemoryEditorDialog, type MemoryEditorTarget } from \"./MemoryEditorDialog\"\n\ntype MemoryOp = \"pin\" | \"unpin\" | \"archive\" | \"restore\" | \"delete\"\ntype StatusOp = \"pin\" | \"unpin\" | \"archive\" | \"restore\"\nconst NEXT_STATUS: Record<StatusOp, EngramindMemory[\"status\"]> = { pin: \"permanent\", unpin: \"active\", archive: \"archived\", restore: \"active\" }\ntype MemoryPages = InfiniteData<{ items: EngramindMemory[]; nextCursor: string | null; truncated: boolean }>\nconst isMemoryPages = (data: unknown): data is MemoryPages => Array.isArray((data as MemoryPages | undefined)?.pages)\n\n/** Troca o status da memória em todas as listas carregadas (resposta otimista). */\nexport function setMemoryStatusInCache(data: unknown, id: string, status: EngramindMemory[\"status\"]): unknown {\n if (!isMemoryPages(data)) return data\n return { ...data, pages: data.pages.map((page) => ({ ...page, items: page.items.map((memory) => (memory.id === id ? { ...memory, status } : memory)) })) }\n}\n\nconst SUCCESS: Record<MemoryOp, string> = { pin: \"Memória fixada\", unpin: \"Memória desafixada\", archive: \"Memória desativada\", restore: \"Memória ativada\", delete: \"Memória excluída\" }\n\n/**\n * Ações do card da memória na página `/engramind` (Engramind bruto, pelo proxy do Opex): ativar,\n * fixar, editar (com `expected_version`), mover, histórico com Reverter e excluir (com confirmação).\n */\nexport function useRawMemoryActions({ rawById, channels, categories, limits }: { rawById: Map<string, EngramindMemory>; channels: EngramindChannel[]; categories: Category[]; limits?: MemoryTextLimits }) {\n const [editor, setEditor] = useState<(MemoryEditorTarget & { memory?: NetworkMemory }) | null>(null)\n const [history, setHistory] = useState<EngramindMemory | null>(null)\n const [move, setMove] = useState<EngramindMemory | null>(null)\n const [deleting, setDeleting] = useState<NetworkMemory | null>(null)\n const queryClient = useQueryClient()\n const localRemovals = useLocalRemovals()\n const act = useEngramindMutation(({ op, id }: { op: MemoryOp; id: string }) => (op === \"delete\" ? engramindSend(\"delete\", route(\"memories\", id)) : engramindSend(\"post\", route(\"memories\", id, op), {})), {\n invalidate: [\"memories\", \"channels\"],\n success: ({ op }) => SUCCESS[op],\n })\n // Ativar/desativar e fixar mudam a partícula na hora; a falha volta o estado (animado) com toast.\n const status = useMutation({\n mutationFn: ({ op, id }: { op: StatusOp; id: string }) => engramindSend(\"post\", route(\"memories\", id, op), {}),\n onMutate: async ({ op, id }) => {\n await queryClient.cancelQueries({ queryKey: areaKey(\"memories\") })\n const previous = queryClient.getQueriesData({ queryKey: areaKey(\"memories\") })\n queryClient.setQueriesData({ queryKey: areaKey(\"memories\") }, (data: unknown) => setMemoryStatusInCache(data, id, NEXT_STATUS[op]))\n return { previous }\n },\n onError: (error, _variables, context) => {\n for (const [key, data] of (context?.previous ?? []) as [QueryKey, unknown][]) queryClient.setQueryData(key, data)\n toast.error(apiErrorMessage(error, \"Não foi possível concluir a ação no Engramind.\"))\n },\n onSuccess: (_data, { op }) => toast.success(SUCCESS[op]),\n onSettled: () => {\n void queryClient.invalidateQueries({ queryKey: areaKey(\"memories\") })\n void queryClient.invalidateQueries({ queryKey: areaKey(\"channels\") })\n },\n })\n const save = useEngramindMutation(\n ({ target, texto, categoria }: { target: MemoryEditorTarget & { memory?: NetworkMemory }; texto: string; categoria: string }) =>\n target.mode === \"edit\" && target.memory\n ? engramindSend(\"patch\", route(\"memories\", target.memory.id), { text: texto, category: categoria, expected_version: target.memory.version })\n : engramindSend(\"post\", \"memories\", { channel: target.channel, text: texto, category: categoria }),\n { invalidate: [\"memories\", \"channels\"], success: ({ target }) => (target.mode === \"edit\" ? \"Memória atualizada\" : \"Memória gravada\") },\n )\n\n const actions = useMemo<MemoryCardActions>(\n () => ({\n onActive: (memory, active) => status.mutate({ op: active ? \"restore\" : \"archive\", id: memory.id }),\n onPin: (memory, pinned) => status.mutate({ op: pinned ? \"pin\" : \"unpin\", id: memory.id }),\n onEdit: (memory) => setEditor({ mode: \"edit\", channel: memory.channel, memory, initial: { texto: memory.text, categoria: memory.category } }),\n onDelete: (memory) => setDeleting(memory),\n onMove: (memory) => setMove(rawById.get(memory.id) ?? null),\n onHistory: (memory) => setHistory(rawById.get(memory.id) ?? null),\n }),\n [status, rawById],\n )\n\n const dialogs = (\n <>\n <MemoryEditorDialog\n target={editor}\n limits={limits}\n categories={categories}\n onClose={() => setEditor(null)}\n onSave={async (values) => {\n if (!editor) return false\n try {\n await save.mutateAsync({ target: editor, ...values })\n return true\n } catch (error) {\n // Conflito de versão: relê a memória e o próximo Salvar usa a versão atual (o rascunho fica).\n if (editor.mode === \"edit\" && editor.memory && apiErrorCode(error) === \"MEMORY_VERSION_CONFLICT\") {\n const memory = editor.memory\n void queryClient.invalidateQueries({ queryKey: areaKey(\"memories\") })\n try {\n const current = toNetworkMemory(await engramindGet<EngramindMemory>(route(\"memories\", memory.id)))\n setEditor((target) => (target?.memory?.id === memory.id ? { ...target, memory: current } : target))\n } catch {\n // Sem a releitura, o próximo Salvar mostra o conflito de novo.\n }\n }\n return false\n }\n }}\n />\n {history && <MemoryHistoryDialog memory={history} onOpenChange={(open) => !open && setHistory(null)} />}\n {move && <MoveMemoryDialog memory={move} channels={channels} onOpenChange={(open) => !open && setMove(null)} onConfirm={() => localRemovals.mark(move.id)} onFailed={() => localRemovals.forget(move.id)} />}\n <ConfirmDialog\n open={deleting !== null}\n onOpenChange={(open) => !open && setDeleting(null)}\n title={deleting ? `Excluir de vez a memória ${deleting.id}?` : \"\"}\n description=\"Sai junto o histórico de versões. Não dá para desfazer.\"\n confirmLabel=\"Excluir de vez\"\n variant=\"destructive\"\n pending={act.isPending}\n onConfirm={() => {\n if (!deleting) return\n const id = deleting.id\n localRemovals.mark(id)\n act.mutate({ op: \"delete\", id }, { onError: () => localRemovals.forget(id), onSettled: () => setDeleting(null) })\n }}\n />\n </>\n )\n return { actions, dialogs, localRemovals, openCreate: (channel: string) => setEditor({ mode: \"create\", channel }) }\n}\n","\"use client\"\n\nimport { History, Loader2, Undo2 } from \"lucide-react\"\nimport { Button } from \"../../../../components/ui/button\"\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \"../../../../components/ui/dialog\"\nimport { EmptyState } from \"../../../../components/feedback/EmptyState\"\nimport type { EngramindMemory, MemoryRevision } from \"../../../types\"\nimport { engramindSend, route, useEngramindList, useEngramindMutation } from \"../../../hooks/useEngramind\"\nimport { formatDateTime } from \"../../shared/format\"\nimport { LoadMore } from \"../../shared/LoadMore\"\nimport { QueryBoundary } from \"../../shared/QueryBoundary\"\nimport { ListSkeleton } from \"../../shared/ListSkeleton\"\n\n/** Histórico de versões da memória, com \"Reverter\" (cria uma revisão nova com o texto antigo). */\nexport function MemoryHistoryDialog({ memory, onOpenChange }: { memory: EngramindMemory; onOpenChange: (open: boolean) => void }) {\n const history = useEngramindList<MemoryRevision>(route(\"memories\", memory.id, \"history\"), \"revisions\")\n const revert = useEngramindMutation((version: number) => engramindSend(\"post\", route(\"memories\", memory.id, \"revert\"), { version }), { invalidate: [\"memories\"], success: (version) => `Memória revertida para a versão ${version}` })\n return (\n <Dialog open onOpenChange={onOpenChange}>\n <DialogContent className=\"max-h-[85vh] overflow-y-auto sm:max-w-2xl\">\n <DialogHeader>\n <DialogTitle>Histórico de {memory.id}</DialogTitle>\n <DialogDescription>Cada edição cria uma versão. Reverter devolve texto, título e categoria numa versão nova.</DialogDescription>\n </DialogHeader>\n <QueryBoundary isLoading={history.isLoading} error={history.error} onRetry={() => void history.refetch()} skeleton={<ListSkeleton rows={3} rowClassName=\"h-20\" />}>\n {history.items.length === 0 ? (\n <EmptyState icon={History} title=\"Sem histórico\" />\n ) : (\n <ol className=\"space-y-3\">\n {history.items.map((revision) => (\n <li key={revision.version} className=\"space-y-1 rounded-lg border p-3 text-sm\">\n <p className=\"flex flex-wrap items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-semibold text-foreground\">v{revision.version}</span>\n {formatDateTime(revision.created_at)} · {revision.author.agent ? `${revision.author.app}/${revision.author.agent}` : revision.author.app} {revision.reason ? `· ${revision.reason}` : \"\"} · {revision.category}\n {revision.version !== memory.version && (\n <Button type=\"button\" size=\"sm\" variant=\"outline\" className=\"ml-auto h-7\" onClick={() => revert.mutate(revision.version, { onSuccess: () => onOpenChange(false) })} disabled={revert.isPending}>\n {revert.isPending ? <Loader2 className=\"mr-1 h-3 w-3 animate-spin\" aria-hidden /> : <Undo2 className=\"mr-1 h-3 w-3\" aria-hidden />} Reverter\n </Button>\n )}\n </p>\n {revision.title && <p className=\"font-medium\">{revision.title}</p>}\n <p className=\"whitespace-pre-wrap\">{revision.text}</p>\n </li>\n ))}\n </ol>\n )}\n </QueryBoundary>\n <LoadMore hasNextPage={Boolean(history.hasNextPage)} isFetchingNextPage={history.isFetchingNextPage} fetchNextPage={history.fetchNextPage} />\n </DialogContent>\n </Dialog>\n )\n}\n","import { format, formatDistanceToNowStrict } from \"date-fns\"\nimport { ptBR } from \"date-fns/locale\"\n\n/** Data e hora pt-BR (vazio → \"—\"). */\nexport function formatDateTime(value: string | null | undefined): string {\n if (!value) return \"—\"\n const date = new Date(value)\n return Number.isNaN(date.getTime()) ? value : format(date, \"dd/MM/yyyy HH:mm\", { locale: ptBR })\n}\n\nexport function formatRelative(value: string | null | undefined): string {\n if (!value) return \"nunca\"\n const date = new Date(value)\n return Number.isNaN(date.getTime()) ? value : `há ${formatDistanceToNowStrict(date, { locale: ptBR })}`\n}\n\nexport function formatBytes(bytes: number | null | undefined): string {\n if (typeof bytes !== \"number\") return \"—\"\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 ** 2) return `${(bytes / 1024).toLocaleString(\"pt-BR\", { maximumFractionDigits: 1 })} KB`\n if (bytes < 1024 ** 3) return `${(bytes / 1024 ** 2).toLocaleString(\"pt-BR\", { maximumFractionDigits: 1 })} MB`\n return `${(bytes / 1024 ** 3).toLocaleString(\"pt-BR\", { maximumFractionDigits: 1 })} GB`\n}\n\nexport function formatDuration(seconds: number | null | undefined): string {\n if (typeof seconds !== \"number\") return \"—\"\n if (seconds < 60) return `${Math.round(seconds)} s`\n if (seconds < 3600) return `${Math.round(seconds / 60)} min`\n if (seconds < 86_400) return `${Math.round(seconds / 3600)} h`\n return `${Math.round(seconds / 86_400)} d`\n}\n\n/** Valor de configuração legível (listas e objetos em JSON curto). */\nexport function formatSettingValue(value: unknown): string {\n if (value === null || value === undefined || value === \"\") return \"—\"\n if (typeof value === \"boolean\") return value ? \"Sim\" : \"Não\"\n if (typeof value === \"number\") return value.toLocaleString(\"pt-BR\")\n if (typeof value === \"string\") return value\n if (Array.isArray(value)) return value.length === 0 ? \"(vazia)\" : value.map((item) => (typeof item === \"object\" ? (item as { key?: string }).key ?? JSON.stringify(item) : String(item))).join(\", \")\n return JSON.stringify(value)\n}\n","\"use client\"\n\nimport { Loader2 } from \"lucide-react\"\nimport { Button } from \"../../../components/ui/button\"\n\n/** \"Carregar mais\" das listas paginadas por cursor. */\nexport function LoadMore({ hasNextPage, isFetchingNextPage, fetchNextPage }: { hasNextPage: boolean; isFetchingNextPage: boolean; fetchNextPage: () => unknown }) {\n if (!hasNextPage) return null\n return (\n <div className=\"flex justify-center\">\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => void fetchNextPage()} disabled={isFetchingNextPage}>\n {isFetchingNextPage && <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" aria-hidden />} Carregar mais\n </Button>\n </div>\n )\n}\n","\"use client\"\n\nimport { useState } from \"react\"\nimport { Loader2 } from \"lucide-react\"\nimport { Button } from \"../../../../components/ui/button\"\nimport { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from \"../../../../components/ui/dialog\"\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"../../../../components/ui/select\"\nimport type { EngramindChannel, EngramindMemory } from \"../../../types\"\nimport { engramindSend, route, useEngramindMutation } from \"../../../hooks/useEngramind\"\nimport { InfoField } from \"../../shared/InfoField\"\n\n/** Mover a memória para outro canal ativo. */\nexport function MoveMemoryDialog({\n memory,\n channels,\n onOpenChange,\n onConfirm,\n onFailed,\n}: {\n memory: EngramindMemory\n channels: EngramindChannel[]\n onOpenChange: (open: boolean) => void\n /** Clicou em Mover (antes da resposta). */\n onConfirm?: () => void\n /** A movimentação falhou. */\n onFailed?: () => void\n}) {\n const options = channels.filter((channel) => !channel.archived_at && channel.slug !== memory.channel)\n const [to, setTo] = useState(options[0]?.slug ?? \"\")\n const move = useEngramindMutation((target: string) => engramindSend(\"post\", route(\"memories\", memory.id, \"move\"), { to: target }), { invalidate: [\"memories\", \"channels\"], success: (target) => `Memória movida para ${target}` })\n return (\n <Dialog open onOpenChange={onOpenChange}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Mover {memory.id}</DialogTitle>\n <DialogDescription>Hoje em {memory.channel}.</DialogDescription>\n </DialogHeader>\n <InfoField id=\"move-to\" label=\"Canal de destino\" info=\"Só canais ativos recebem escrita.\">\n <Select value={to} onValueChange={setTo}>\n <SelectTrigger id=\"move-to\" className=\"bg-transparent\">\n <SelectValue placeholder=\"Escolha o canal\" />\n </SelectTrigger>\n <SelectContent>\n {options.map((channel) => (\n <SelectItem key={channel.id} value={channel.slug}>\n {channel.slug}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </InfoField>\n <DialogFooter>\n <Button type=\"button\" disabled={!to || move.isPending} onClick={() => {\n onConfirm?.()\n move.mutate(to, { onSuccess: () => onOpenChange(false), onError: () => onFailed?.() })\n }}>\n {move.isPending && <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" aria-hidden />} Mover\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n","\"use client\"\n\nimport { useMemo, useRef } from \"react\"\n\n/**\n * Remoções confirmadas nesta tela (excluir ou mover): o universo não avisa \"excluída por outra origem\"\n * quando a memória aberta sai por uma ação daqui. A marca entra só na **confirmação** (cancelar o\n * diálogo não marca), sai se a ação falhar e é esquecida quando o item deixa o universo.\n */\nexport interface LocalRemovals {\n mark: (id: string) => void\n forget: (id: string) => void\n has: (id: string) => boolean\n}\n\nexport function useLocalRemovals(): LocalRemovals {\n const ids = useRef(new Set<string>())\n return useMemo(\n () => ({\n mark: (id: string) => void ids.current.add(id),\n forget: (id: string) => void ids.current.delete(id),\n has: (id: string) => ids.current.has(id),\n }),\n [],\n )\n}\n","\"use client\"\n\nimport { useId, useMemo } from \"react\"\nimport { useForm, useWatch } from \"react-hook-form\"\nimport { zodResolver } from \"@hookform/resolvers/zod\"\nimport { Save, X } from \"lucide-react\"\nimport { z } from \"zod\"\nimport { Button } from \"../../../components/ui/button\"\nimport { Label } from \"../../../components/ui/label\"\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"../../../components/ui/select\"\nimport { Textarea } from \"../../../components/ui/textarea\"\nimport { DEFAULT_MEMORY_TEXT_LIMITS, memoryTextSchema, type MemoryTextLimits } from \"../../memory-text\"\n\ninterface MemoryEditorProps {\n label: string\n initial?: { texto: string; categoria: string | null }\n limits?: MemoryTextLimits\n categories: { key: string; label: string }[]\n onSave: (values: { texto: string; categoria: string }) => void\n onCancel: () => void\n}\n\n/** Schema do editor: texto nos limites do Engramind e categoria da lista `categories.list`. */\nexport function memoryEditorSchema(limits: MemoryTextLimits, categories: readonly { key: string }[]) {\n const keys = categories.map((item) => item.key)\n return z.object({\n texto: memoryTextSchema(limits),\n categoria: keys.length ? z.string().refine((value) => keys.includes(value), \"Categoria inválida: escolha uma da lista\") : z.string(),\n })\n}\n\n/** Texto livre da memória + categoria (mesmos limites da API, vindos do Engramind). Ctrl+Enter salva, Esc cancela. */\nexport function MemoryEditor({ label, initial, limits = DEFAULT_MEMORY_TEXT_LIMITS, categories, onSave, onCancel }: MemoryEditorProps) {\n const id = useId()\n const schema = useMemo(() => memoryEditorSchema(limits, categories), [limits, categories])\n const startCategory = initial?.categoria ?? categories[0]?.key ?? \"\"\n const form = useForm<{ texto: string; categoria: string }>({ resolver: zodResolver(schema), mode: \"onChange\", defaultValues: { texto: initial?.texto ?? \"\", categoria: startCategory } })\n const texto = useWatch({ control: form.control, name: \"texto\" }) ?? \"\"\n const categoria = useWatch({ control: form.control, name: \"categoria\" }) ?? \"\"\n const error = form.formState.errors.texto?.message\n const categoryError = form.formState.errors.categoria?.message ?? (categoria && categories.length && !categories.some((item) => item.key === categoria) ? \"Categoria inválida: escolha uma da lista\" : undefined)\n const isValid = form.formState.isValid\n const unchanged = initial ? texto.trim() === initial.texto.trim() && categoria === (initial.categoria ?? \"\") : false\n const submit = form.handleSubmit((values) => onSave(values))\n return (\n <div className=\"space-y-2 rounded-lg border bg-muted/30 p-3\">\n <label htmlFor={id} className=\"text-sm font-medium\">\n {label}\n </label>\n <Textarea\n id={id}\n rows={4}\n autoFocus\n placeholder=\"Escreva a instrução ou o fato que o agente deve lembrar. O Redator do Engramind gera o resumo da lista.\"\n aria-invalid={Boolean(error)}\n {...form.register(\"texto\")}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" && (event.ctrlKey || event.metaKey)) {\n event.preventDefault()\n void submit()\n }\n if (event.key === \"Escape\") onCancel()\n }}\n />\n {categories.length > 0 && (\n <div className=\"space-y-1\">\n <Label htmlFor={`${id}-categoria`} className=\"text-xs font-semibold\">\n Categoria\n </Label>\n <Select value={categories.some((item) => item.key === categoria) ? categoria : undefined} onValueChange={(next) => form.setValue(\"categoria\", next, { shouldDirty: true, shouldValidate: true })}>\n <SelectTrigger id={`${id}-categoria`} className=\"w-full bg-transparent\" aria-invalid={Boolean(categoryError)}>\n <SelectValue placeholder={categoria ? `${categoria} (inválida)` : \"Escolha a categoria\"} />\n </SelectTrigger>\n <SelectContent>\n {categories.map((item) => (\n <SelectItem key={item.key} value={item.key}>\n {item.label} ({item.key})\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {categoryError && (\n <p role=\"alert\" className=\"text-xs text-destructive\">\n {categoryError}\n </p>\n )}\n </div>\n )}\n <div className=\"flex items-center justify-between gap-2 text-xs\">\n <span className={error ? \"text-destructive\" : \"text-muted-foreground\"} data-testid=\"memory-editor-counter\">\n {error ?? `${texto.length}/${limits.textMax}`}\n </span>\n <div className=\"flex gap-2\">\n <Button type=\"button\" size=\"sm\" variant=\"ghost\" className=\"gap-1\" onClick={onCancel}>\n <X className=\"h-4 w-4\" aria-hidden /> Cancelar\n </Button>\n <Button type=\"button\" size=\"sm\" className=\"gap-1\" disabled={!isValid || Boolean(categoryError) || unchanged} onClick={() => void submit()}>\n <Save className=\"h-4 w-4\" aria-hidden /> Salvar\n </Button>\n </div>\n </div>\n </div>\n )\n}\n","import { z } from \"zod\"\n\n/**\n * Texto das memórias dos agentes (módulo PURO: tela, rotas, ferramentas e migração). Os limites vêm do\n * Engramind (`memory.text_min` / `memory.text_max`, este com sobreposição por canal); os schemas\n * estáticos só seguram o teto absoluto do Engramind (20.000) e a regra fina fica em `memoryInputSchemaFor`.\n */\n\nexport interface MemoryTextLimits {\n textMin: number\n textMax: number\n}\n\n/** Padrões do Engramind (usados até a primeira leitura das configurações). */\nexport const DEFAULT_MEMORY_TEXT_LIMITS: MemoryTextLimits = { textMin: 3, textMax: 4000 }\n/** Teto absoluto aceito pelo Engramind (`memory.text_max` vai até 20.000). */\nexport const MEMORY_TEXT_ABSOLUTE_MAX = 20_000\n\nconst formatCount = (value: number) => value.toLocaleString(\"pt-BR\")\n\nexport function memoryTextSchema(limits: MemoryTextLimits = DEFAULT_MEMORY_TEXT_LIMITS) {\n return z\n .string()\n .trim()\n .min(limits.textMin, limits.textMin <= 1 ? \"Escreva a memória\" : `Escreva a memória (mínimo de ${formatCount(limits.textMin)} caracteres)`)\n .max(limits.textMax, `Até ${formatCount(limits.textMax)} caracteres`)\n}\n\n/** Formulário de memória (tela): texto com os limites do Engramind + categoria. */\nexport function memoryInputSchemaFor(limits: MemoryTextLimits = DEFAULT_MEMORY_TEXT_LIMITS) {\n return z.object({ texto: memoryTextSchema(limits), categoria: z.string().trim().min(1, \"Escolha a categoria\").max(40) })\n}\nexport type MemoryFormInput = z.infer<ReturnType<typeof memoryInputSchemaFor>>\n\nconst categoria = z.string().trim().min(1).max(40)\n\n/** Corpo de `POST .../memories` (mesmo contrato na tela e na API; os limites finos são do servidor). */\nexport const memoryCreateSchema = z.object({\n texto: z.string().trim().min(1, \"Escreva a memória\").max(MEMORY_TEXT_ABSOLUTE_MAX),\n categoria: categoria.nullish(),\n fixada: z.boolean().optional(),\n})\nexport type MemoryCreateInput = z.infer<typeof memoryCreateSchema>\n\n/** Corpo de `PATCH .../memories/[id]`: texto/categoria (com a versão lida), fixar e ativar. */\nexport const memoryPatchSchema = z\n .object({\n texto: z.string().trim().min(1, \"Escreva a memória\").max(MEMORY_TEXT_ABSOLUTE_MAX).optional(),\n categoria: categoria.optional(),\n versao: z.number().int().positive().optional(),\n fixada: z.boolean().optional(),\n ativa: z.boolean().optional(),\n })\n .refine((value) => value.texto !== undefined || value.categoria !== undefined || value.fixada !== undefined || value.ativa !== undefined, { message: \"Informe o que mudar na memória\" })\nexport type MemoryPatchInput = z.infer<typeof memoryPatchSchema>\n\n/** Normaliza espaços sem perder as quebras de parágrafo. */\nexport function normalizeText(text: string): string {\n return text\n .replace(/\\r\\n/g, \"\\n\")\n .split(\"\\n\")\n .map((line) => line.replace(/[ \\t]+/g, \" \").trim())\n .join(\"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim()\n}\n\n/** Corta em limite de palavra, com reticências (ex.: nunca \"integraç…\"). */\nexport function truncateAtWord(text: string, maxLength: number): string {\n const collapsed = text.replace(/\\s+/g, \" \").trim()\n if (collapsed.length <= maxLength) return collapsed\n const slice = collapsed.slice(0, maxLength - 1)\n const lastSpace = slice.lastIndexOf(\" \")\n return `${(lastSpace > maxLength / 2 ? slice.slice(0, lastSpace) : slice).trimEnd()}…`\n}\n\n/** Resumo de reserva enquanto o Redator não respondeu: a primeira frase do texto, cortada em palavra. */\nexport function firstSentence(text: string, maxLength = 120): string {\n const first = normalizeText(text).split(/(?<=[.!?])\\s|\\n/)[0] ?? text\n return truncateAtWord(first.replace(/[.!?;:,]+$/, \"\"), maxLength)\n}\n\n/** Estimativa de tokens (≈ 4 caracteres por token), só para avisos de orçamento. */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4)\n}\n\n/** Teto usado onde o limite do Engramind ainda não foi lido (Agente Mentor): o padrão de `memory.text_max`. */\nexport const MEMORY_TEXT_MAX = DEFAULT_MEMORY_TEXT_LIMITS.textMax\n","\"use client\"\n\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \"../../../components/ui/dialog\"\nimport { MemoryEditor } from \"../memory/MemoryEditor\"\nimport type { MemoryTextLimits } from \"../../memory-text\"\nimport { ChannelDisplayName } from \"./ChannelName\"\n\nexport interface MemoryEditorTarget {\n mode: \"create\" | \"edit\"\n channel: string\n initial?: { texto: string; categoria: string | null }\n}\n\n/**\n * O mesmo editor de memória das listas (texto + categoria, limites do Engramind) num diálogo da rede.\n * `onSave` resolve `true` no sucesso; num conflito de versão o diálogo continua aberto com o texto.\n */\nexport function MemoryEditorDialog({ target, limits, categories, onSave, onClose }: { target: MemoryEditorTarget | null; limits?: MemoryTextLimits; categories: { key: string; label: string }[]; onSave: (values: { texto: string; categoria: string }) => Promise<boolean>; onClose: () => void }) {\n return (\n <Dialog open={target !== null} onOpenChange={(open) => !open && onClose()}>\n <DialogContent className=\"sm:max-w-xl\">\n <DialogHeader>\n <DialogTitle>{target?.mode === \"edit\" ? \"Editar memória\" : \"Nova memória\"}</DialogTitle>\n <DialogDescription>Canal {target?.channel ? <ChannelDisplayName slug={target.channel} /> : null}</DialogDescription>\n </DialogHeader>\n {target && (\n <MemoryEditor\n label=\"Texto da memória\"\n initial={target.initial}\n limits={limits}\n categories={categories}\n onCancel={onClose}\n onSave={(values) => {\n void onSave(values).then((saved) => saved && onClose())\n }}\n />\n )}\n </DialogContent>\n </Dialog>\n )\n}\n","\"use client\"\n\nimport { useCallback, useEffect } from \"react\"\nimport { usePathname, useRouter, useSearchParams } from \"../../../lib/navigation\"\nimport type { UniverseRef } from \"../../network/types\"\n\nexport const UNIVERSE_PARAM = \"universo\"\n/** App aberto (`?app=<slug>`): a visão Agentes x canais restrita a ele (OPE-129). */\nexport const APP_PARAM = \"app\"\n\n/** `canal:<slug>` / `agente:<app/agente>` ↔ referência do universo (inválido → `null`). */\nexport function parseUniverse(value: string | null | undefined): UniverseRef | null {\n if (!value) return null\n const [kind, ...rest] = value.split(\":\")\n const id = rest.join(\":\").trim()\n if (!id) return null\n if (kind === \"canal\") return { kind: \"channel\", slug: id }\n if (kind === \"agente\") return { kind: \"agent\", id }\n return null\n}\n\nexport const formatUniverse = (ref: UniverseRef): string => (ref.kind === \"channel\" ? `canal:${ref.slug}` : `agente:${ref.id}`)\n\n/**\n * O universo aberto fica no endereço (`?universo=`), assim como o app (`?app=`, OPE-129): o link pode\n * ser compartilhado e o voltar do navegador funciona. Voltar e `Esc` sobem um nível (universo → app,\n * se houver → visão inicial Apps x canais), fora de diálogos modais e campos (o card da memória,\n * `data-network-card`, não é modal e não segura a tecla). Com `fixedApp` (modo app), o app é sempre\n * esse: o endereço só guarda o universo e a visão do app é a inicial.\n */\nexport function useUniverseParam(options: { escapeEnabled: boolean; fixedApp?: string | null }) {\n const router = useRouter()\n const pathname = usePathname()\n const searchParams = useSearchParams()\n const universe = parseUniverse(searchParams.get(UNIVERSE_PARAM))\n const fixedApp = options.fixedApp ?? null\n const app = fixedApp ?? (searchParams.get(APP_PARAM)?.trim() || null)\n const go = useCallback(\n (next: { app: string | null; universe: UniverseRef | null }, options: { replace?: boolean } = {}) => {\n const params = new URLSearchParams(searchParams.toString())\n if (next.app && !fixedApp) params.set(APP_PARAM, next.app)\n else params.delete(APP_PARAM)\n if (next.universe) params.set(UNIVERSE_PARAM, formatUniverse(next.universe))\n else params.delete(UNIVERSE_PARAM)\n const query = params.toString()\n const url = query ? `${pathname}?${query}` : pathname\n // `replace`: o endereço inválido sai do histórico (o voltar do navegador não volta a ele).\n if (options.replace) router.replace(url, { scroll: false })\n else router.push(url, { scroll: false })\n },\n [router, pathname, searchParams, fixedApp],\n )\n /** Abre um universo mantendo o app aberto (o Voltar do universo volta a ele). */\n const open = useCallback((ref: UniverseRef | null, options: { replace?: boolean } = {}) => go({ app, universe: ref }, options), [go, app])\n const openApp = useCallback((slug: string) => go({ app: slug, universe: null }), [go])\n /** Sobe um nível: do universo ao app (se houver) e do app à visão inicial. */\n const back = useCallback((options: { replace?: boolean } = {}) => go({ app: universe ? app : null, universe: null }, options), [go, universe, app])\n /** Volta direto à visão inicial (app inexistente). */\n const home = useCallback((options: { replace?: boolean } = {}) => go({ app: null, universe: null }, options), [go])\n const nested = universe !== null || (app !== null && !fixedApp)\n useEffect(() => {\n if (!nested || !options.escapeEnabled) return\n const onKey = (event: KeyboardEvent) => {\n if (event.key !== \"Escape\" || event.defaultPrevented) return\n const target = event.target\n if (target instanceof Element && target.closest(\"input, textarea, [role='dialog']:not([data-network-card]), [role='alertdialog']\")) return\n back()\n }\n window.addEventListener(\"keydown\", onKey)\n return () => window.removeEventListener(\"keydown\", onKey)\n }, [nested, options.escapeEnabled, back])\n return { universe, app, open, openApp, back, home }\n}\n","\"use client\"\n\nimport Link from \"../../../../lib/link\"\nimport { ArrowLeft } from \"lucide-react\"\nimport { Button } from \"../../../../components/ui/button\"\nimport { Skeleton } from \"../../../../components/ui/skeleton\"\nimport { CadastroHeader } from \"../../../../components/list/CadastroHeader\"\nimport { useEngramindConfig } from \"../../../../lib/config\"\nimport { CHANNEL_HELP } from \"../../../help/identities\"\nimport type { EngramindChannel } from \"../../../types\"\nimport { route, useEngramindQuery, useEngramindRealtime } from \"../../../hooks/useEngramind\"\nimport { HelpBadge } from \"../../shared/Badges\"\nimport { QueryBoundary } from \"../../shared/QueryBoundary\"\nimport { SubscribersCard } from \"./SubscribersCard\"\n\n/** Link de volta à rede, com o universo do canal aberto. */\nexport function networkHref(network: string, params: Record<string, string>): string {\n const query = new URLSearchParams(params).toString()\n return query ? `${network}?${query}` : network\n}\n\n/** Detalhe do canal: assinantes e o conteúdo extra do app (`slots.channelDetail`, ex.: configurações do canal). */\nexport function ChannelDetail({ slug }: { slug: string }) {\n useEngramindRealtime()\n const { hrefs, slots, onConfigure } = useEngramindConfig()\n const channel = useEngramindQuery<EngramindChannel>(route(\"channels\", slug))\n return (\n <div className=\"flex flex-col gap-6\">\n <CadastroHeader title={channel.data?.name ?? slug} description={`Canal ${slug}`}>\n <Button asChild variant=\"outline\" size=\"sm\">\n <Link href={networkHref(hrefs.network, { universo: `canal:${slug}` })}>\n <ArrowLeft className=\"mr-1.5 h-4 w-4\" aria-hidden /> Rede\n </Link>\n </Button>\n </CadastroHeader>\n <QueryBoundary\n isLoading={channel.isLoading}\n error={channel.error}\n onRetry={() => void channel.refetch()}\n onConfigure={onConfigure ? () => onConfigure(\"connection\") : undefined}\n skeleton={\n <div className=\"flex flex-col gap-6\" aria-busy=\"true\">\n <Skeleton className=\"h-48 w-full rounded-xl\" />\n <Skeleton className=\"h-64 w-full rounded-xl\" />\n </div>\n }\n >\n {channel.data && (\n <div className=\"flex flex-col gap-6\">\n <div className=\"flex flex-wrap items-center gap-2 text-sm text-muted-foreground\">\n {channel.data.description && <span>{channel.data.description}</span>}\n <HelpBadge value={`prioridade ${channel.data.priority}`} help={CHANNEL_HELP.priority} />\n <HelpBadge value={`versão ${channel.data.version}`} help={CHANNEL_HELP.version} />\n {channel.data.archived_at && <HelpBadge value=\"arquivado\" help={CHANNEL_HELP.archived} />}\n </div>\n <SubscribersCard channel={channel.data.slug} />\n {slots.channelDetail?.(channel.data.slug)}\n </div>\n )}\n </QueryBoundary>\n </div>\n )\n}\n","import { type ReactNode } from \"react\"\nimport { Button } from \"../ui/button\"\n\ninterface CadastroHeaderProps {\n title: string\n description: string\n actionLabel?: string\n onAction?: () => void\n actionIcon?: ReactNode\n children?: ReactNode\n}\n\nexport const CadastroHeader = ({ title, description, actionLabel, onAction, actionIcon, children }: CadastroHeaderProps) => {\n return (\n <div className=\"flex flex-col gap-4\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-lg font-semibold md:text-2xl\">{title}</h1>\n <p className=\"text-sm text-muted-foreground mt-1\">{description}</p>\n </div>\n {actionLabel && onAction && (\n <Button onClick={onAction} className=\"h-9 px-4\">\n {actionIcon && <span className=\"mr-2\">{actionIcon}</span>}\n {actionLabel}\n </Button>\n )}\n </div>\n {children}\n </div>\n )\n}\n","\"use client\"\n\nimport { useState } from \"react\"\nimport { AnimatePresence, motion } from \"framer-motion\"\nimport { Skeleton } from \"../../../components/ui/skeleton\"\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"../../../components/ui/tabs\"\nimport { useT } from \"../../../lib/config\"\nimport type { EngramindAgent, EngramindApp, EngramindChannel, EngramindSubscription, EngramindToken } from \"../../types\"\nimport { useEngramindList, useEngramindRealtime } from \"../../hooks/useEngramind\"\nimport { useOwnApp } from \"../../hooks/useEngramindNetwork\"\nimport { QueryBoundary } from \"../shared/QueryBoundary\"\nimport { AgentDetail } from \"./AgentDetail\"\nimport { AgentsCard } from \"./AgentsCard\"\nimport { ChannelsCard } from \"./ChannelsCard\"\nimport { TokensCard } from \"./TokensCard\"\nimport { WebhookCard } from \"./WebhookCard\"\n\nconst fade = { initial: { opacity: 0, y: 4 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.18 } } as const\nconst slide = { initial: { opacity: 0, x: 12 }, animate: { opacity: 1, x: 0 }, exit: { opacity: 0, x: -12 }, transition: { duration: 0.18 } } as const\n\nexport type AppSettingsTab = \"agents\" | \"channels\" | \"tokens\" | \"webhook\"\n\n/**\n * Configuração do app no Engramind (modo app, só o token do próprio app): Agentes e assinaturas, Canais,\n * Tokens de agente (o segredo aparece uma única vez) e Webhook. Sem funções de gestor (outros apps,\n * tokens admin ou de app, configurações globais).\n */\nexport function EngramindAppSettings({ defaultTab = \"agents\" }: { defaultTab?: AppSettingsTab }) {\n useEngramindRealtime()\n const t = useT()\n const own = useOwnApp()\n const enabled = own.slug !== null\n const agents = useEngramindList<EngramindAgent>(\"agents\", \"agents\", { app: own.slug }, { all: true, enabled })\n const tokens = useEngramindList<EngramindToken>(\"tokens\", \"tokens\", { app: own.slug }, { all: true, enabled })\n const subscriptions = useEngramindList<EngramindSubscription>(\"subscriptions\", \"subscriptions\", {}, { all: true, enabled })\n const channels = useEngramindList<EngramindChannel>(\"channels\", \"channels\", { include_archived: true }, { all: true, enabled })\n const [agentId, setAgentId] = useState<string | null>(null)\n const app: EngramindApp | null = own.slug ? { id: own.slug, slug: own.slug, name: own.slug, description: null, created_at: \"\", disabled_at: null, webhook: null } : null\n const apps = app ? [app] : []\n const agentTokens = tokens.items.filter((token) => token.kind === \"agent\")\n const agent = agentId ? agents.items.find((item) => item.id === agentId) : undefined\n const queries = [agents, tokens, subscriptions, channels]\n const error = own.error ?? queries.find((query) => query.error)?.error ?? null\n return (\n <QueryBoundary isLoading={own.isLoading || queries.some((query) => query.isLoading)} error={error} onRetry={() => queries.forEach((query) => void query.refetch())} skeleton={<AppSettingsSkeleton />}>\n <AnimatePresence mode=\"wait\" initial={false}>\n {agent && app ? (\n <motion.div key={`agent-${agent.id}`} {...slide}>\n <AgentDetail agent={agent} apps={apps} agents={agents.items} tokens={tokens.items} subscriptions={subscriptions.items} ownTokenIds={[]} onBack={() => setAgentId(null)} />\n </motion.div>\n ) : (\n <motion.div key=\"tabs\" {...slide}>\n <Tabs defaultValue={defaultTab}>\n <TabsList className=\"flex-wrap\">\n <TabsTrigger value=\"agents\">\n {t(\"config.agents.title\")} ({agents.items.length})\n </TabsTrigger>\n <TabsTrigger value=\"channels\">\n {t(\"config.channels.title\")} ({channels.items.length})\n </TabsTrigger>\n <TabsTrigger value=\"tokens\">\n {t(\"config.tokens.title\")} ({agentTokens.length})\n </TabsTrigger>\n <TabsTrigger value=\"webhook\">{t(\"config.webhook.title\")}</TabsTrigger>\n </TabsList>\n <TabsContent value=\"agents\">\n <motion.div {...fade}>\n <AgentsCard agents={agents.items} apps={apps} subscriptions={subscriptions.items} onOpen={(item) => setAgentId(item.id)} />\n </motion.div>\n </TabsContent>\n <TabsContent value=\"channels\">\n <motion.div {...fade}>\n <ChannelsCard channels={channels.items} agents={agents.items} subscriptions={subscriptions.items} />\n </motion.div>\n </TabsContent>\n <TabsContent value=\"tokens\">\n <motion.div {...fade}>\n {app && <TokensCard title={t(\"config.tokens.title\")} info=\"Tokens agent dos agentes do app: alcançam só os canais que o agente assina. O segredo aparece uma única vez.\" tokens={agentTokens} apps={apps} agents={agents.items} ownTokenIds={[]} issuePreset={{ app: app.slug, agentOnly: true }} emptyDescription=\"Nenhum token de agente.\" />}\n </motion.div>\n </TabsContent>\n <TabsContent value=\"webhook\">\n <motion.div {...fade}>{app && <WebhookCard app={app.slug} />}</motion.div>\n </TabsContent>\n </Tabs>\n </motion.div>\n )}\n </AnimatePresence>\n </QueryBoundary>\n )\n}\n\nexport function AppSettingsSkeleton() {\n return (\n <div className=\"flex flex-col gap-4\" aria-busy=\"true\" data-testid=\"app-settings-skeleton\">\n <Skeleton className=\"h-9 w-full max-w-md\" />\n <div className=\"space-y-3 rounded-xl border p-6\">\n <Skeleton className=\"h-5 w-24\" />\n {Array.from({ length: 3 }, (_, row) => (\n <Skeleton key={row} className=\"h-[4.5rem] w-full\" />\n ))}\n </div>\n </div>\n )\n}\n","import * as React from \"react\"\nimport { cn } from \"../../lib/utils\"\n\ninterface TabsContextValue {\n value: string\n onValueChange: (value: string) => void\n}\n\nconst TabsContext = React.createContext<TabsContextValue | undefined>(undefined)\n\nconst useTabsContext = () => {\n const context = React.useContext(TabsContext)\n if (!context) {\n throw new Error(\"Tabs components must be used within a Tabs component\")\n }\n return context\n}\n\ninterface TabsProps extends React.HTMLAttributes<HTMLDivElement> {\n defaultValue?: string\n value?: string\n onValueChange?: (value: string) => void\n}\n\nconst Tabs = React.forwardRef<HTMLDivElement, TabsProps>(\n ({ defaultValue, value: controlledValue, onValueChange, className, ...props }, ref) => {\n const [internalValue, setInternalValue] = React.useState(defaultValue || \"\")\n const value = controlledValue ?? internalValue\n\n const handleValueChange = React.useCallback(\n (newValue: string) => {\n setInternalValue(newValue)\n onValueChange?.(newValue)\n },\n [onValueChange]\n )\n\n return (\n <TabsContext.Provider value={{ value, onValueChange: handleValueChange }}>\n <div ref={ref} className={cn(\"w-full\", className)} {...props} />\n </TabsContext.Provider>\n )\n }\n)\nTabs.displayName = \"Tabs\"\n\nconst TabsList = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n \"inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground\",\n className\n )}\n {...props}\n />\n))\nTabsList.displayName = \"TabsList\"\n\ninterface TabsTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n value: string\n}\n\nconst TabsTrigger = React.forwardRef<HTMLButtonElement, TabsTriggerProps>(\n ({ className, value: triggerValue, ...props }, ref) => {\n const { value, onValueChange } = useTabsContext()\n const isActive = value === triggerValue\n\n return (\n <button\n ref={ref}\n type=\"button\"\n role=\"tab\"\n aria-selected={isActive}\n onClick={() => onValueChange(triggerValue)}\n className={cn(\n \"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\",\n isActive\n ? \"bg-background text-foreground shadow-sm\"\n : \"text-muted-foreground hover:text-foreground\",\n className\n )}\n {...props}\n />\n )\n }\n)\nTabsTrigger.displayName = \"TabsTrigger\"\n\ninterface TabsContentProps extends React.HTMLAttributes<HTMLDivElement> {\n value: string\n}\n\nconst TabsContent = React.forwardRef<HTMLDivElement, TabsContentProps>(\n ({ className, value: contentValue, ...props }, ref) => {\n const { value } = useTabsContext()\n const isActive = value === contentValue\n\n if (!isActive) return null\n\n return (\n <div\n ref={ref}\n role=\"tabpanel\"\n className={cn(\n \"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n className\n )}\n {...props}\n />\n )\n }\n)\nTabsContent.displayName = \"TabsContent\"\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent }\n","\"use client\"\n\nimport { useMemo, useState } from \"react\"\nimport { motion } from \"framer-motion\"\nimport { ArrowLeft, Pencil, Plus, Power, Trash2 } from \"lucide-react\"\nimport { Button } from \"../../../components/ui/button\"\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"../../../components/ui/tabs\"\nimport { ConfirmDialog } from \"../../../components/ui/confirm-dialog\"\nimport { TooltipIconButton } from \"../../../components/ui/tooltip-icon-button\"\nimport { IDENTITY_HELP, SUBSCRIPTION_MODE_HELP } from \"../../help/identities\"\nimport { tokensOfAgent } from \"../../identities\"\nimport type { EngramindAgent, EngramindApp, EngramindMemory, EngramindSubscription, EngramindToken } from \"../../types\"\nimport { engramindSend, route, useEngramindList, useEngramindMutation } from \"../../hooks/useEngramind\"\nimport { SubscriptionDialog } from \"../page/channels/SubscriptionDialog\"\nimport { HelpBadge } from \"../shared/Badges\"\nimport { formatDateTime } from \"../shared/format\"\nimport { Section } from \"../shared/Section\"\nimport { AgentDialog } from \"./AgentDialog\"\nimport { TokensCard } from \"./TokensCard\"\n\nconst fade = { initial: { opacity: 0, y: 4 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.18 } } as const\n\ninterface AgentDetailProps {\n agent: EngramindAgent\n apps: EngramindApp[]\n agents: EngramindAgent[]\n tokens: EngramindToken[]\n subscriptions: EngramindSubscription[]\n ownTokenIds: readonly (string | null | undefined)[]\n onBack: () => void\n}\n\n/** Memórias ativas dos canais que o agente alcança (pelas assinaturas), por canal. */\nfunction AccessibleMemories({ channels }: { channels: string[] }) {\n const memories = useEngramindList<EngramindMemory>(channels.length ? \"memories\" : null, \"memories\", { channels: channels.join(\",\"), status: \"active,permanent\" }, { all: true })\n const byChannel = useMemo(() => {\n const counts = new Map<string, number>()\n for (const memory of memories.items) counts.set(memory.channel, (counts.get(memory.channel) ?? 0) + 1)\n return counts\n }, [memories.items])\n if (!channels.length) return <p className=\"text-sm text-muted-foreground\">Sem assinaturas: o agente não alcança nenhum canal.</p>\n return (\n <div className=\"space-y-1 text-sm\" data-testid=\"accessible-memories\">\n <p className=\"font-medium\">{memories.isLoading ? \"…\" : memories.items.length} memória(s) acessível(is)</p>\n {channels.map((channel) => (\n <p key={channel} className=\"flex justify-between gap-2 text-xs\">\n <span className=\"truncate font-mono\">{channel}</span>\n <span className=\"text-muted-foreground\">{memories.isLoading ? \"…\" : (byChannel.get(channel) ?? 0)}</span>\n </p>\n ))}\n </div>\n )\n}\n\n/**\n * Detalhe do agente: Configuração (editar, desativar/reativar) · Tokens · Assinaturas (canal exato ou\n * prefixo, modo inject/search/manage; assinar um canal exato que não existe cria o canal) · Memórias\n * acessíveis.\n */\nexport function AgentDetail({ agent, apps, agents, tokens, subscriptions, ownTokenIds, onBack }: AgentDetailProps) {\n const [editing, setEditing] = useState(false)\n const own = subscriptions.filter((subscription) => subscription.agent.id === agent.id)\n const reached = [...new Set(own.flatMap((subscription) => subscription.reaches))]\n const [subscription, setSubscription] = useState<EngramindSubscription | \"new\" | null>(null)\n const [removing, setRemoving] = useState<EngramindSubscription | null>(null)\n const remove = useEngramindMutation((id: string) => engramindSend(\"delete\", route(\"subscriptions\", id)), { invalidate: [\"subscriptions\", \"agents\", \"channels\"], success: \"Assinatura removida\" })\n const toggle = useEngramindMutation(() => engramindSend(\"patch\", route(\"agents\", agent.qualified_slug), { disabled: !agent.disabled_at }), { invalidate: [\"agents\"], success: agent.disabled_at ? \"Agente reativado\" : \"Agente desativado\" })\n return (\n <div className=\"flex flex-col gap-4\" data-testid={`agent-detail-${agent.qualified_slug}`}>\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={onBack}>\n <ArrowLeft className=\"mr-1.5 h-4 w-4\" aria-hidden /> Agentes\n </Button>\n <h3 className=\"flex flex-wrap items-center gap-1.5 text-base font-semibold\">\n {agent.name} <span className=\"font-mono text-xs text-muted-foreground\">{agent.qualified_slug}</span>\n {agent.disabled_at && <HelpBadge value=\"desativado\" tone=\"warning\" help={IDENTITY_HELP.disabled} />}\n </h3>\n </div>\n <Tabs defaultValue=\"config\">\n <TabsList className=\"flex-wrap\">\n <TabsTrigger value=\"config\">Configuração</TabsTrigger>\n <TabsTrigger value=\"tokens\">Tokens</TabsTrigger>\n <TabsTrigger value=\"subscriptions\">Assinaturas ({own.length})</TabsTrigger>\n <TabsTrigger value=\"reachable\">Memórias acessíveis</TabsTrigger>\n </TabsList>\n <TabsContent value=\"config\">\n <motion.div {...fade}>\n <Section\n title=\"Configuração\"\n info={IDENTITY_HELP.agent}\n actions={\n <>\n <Button type=\"button\" size=\"sm\" variant=\"outline\" className=\"bg-transparent\" onClick={() => toggle.mutate(undefined as never)} disabled={toggle.isPending}>\n <Power className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden /> {agent.disabled_at ? \"Reativar\" : \"Desativar\"}\n </Button>\n <Button type=\"button\" size=\"sm\" variant=\"outline\" className=\"bg-transparent\" onClick={() => setEditing(true)}>\n <Pencil className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden /> Editar\n </Button>\n </>\n }\n >\n <dl className=\"grid grid-cols-1 gap-2 text-sm sm:grid-cols-2\">\n <div><dt className=\"text-xs text-muted-foreground\">Nome</dt><dd>{agent.name}</dd></div>\n <div><dt className=\"text-xs text-muted-foreground\">Status</dt><dd>{agent.disabled_at ? `Desativado em ${formatDateTime(agent.disabled_at)}` : \"Ativo\"}</dd></div>\n <div className=\"sm:col-span-2\"><dt className=\"text-xs text-muted-foreground\">Descrição</dt><dd>{agent.description ?? \"—\"}</dd></div>\n <div className=\"sm:col-span-2\"><dt className=\"text-xs text-muted-foreground\">Categorias</dt><dd className=\"text-xs text-muted-foreground\">As categorias são globais (Configurações › Categorias); os canais do agente são as assinaturas.</dd></div>\n </dl>\n </Section>\n </motion.div>\n </TabsContent>\n <TabsContent value=\"tokens\">\n <motion.div {...fade}>\n <TokensCard title=\"Tokens do agente\" info=\"Tokens agent deste agente: alcançam só os canais que ele assina.\" tokens={tokensOfAgent(tokens, agent)} apps={apps} agents={agents} ownTokenIds={ownTokenIds} issuePreset={{ app: agent.app.slug, agent: agent.qualified_slug }} emptyDescription=\"Nenhum token deste agente.\" />\n </motion.div>\n </TabsContent>\n <TabsContent value=\"subscriptions\">\n <motion.div {...fade}>\n <Section\n title=\"Assinaturas\"\n info=\"Canais que o agente lê e grava (modo e alcance). Assinar um canal exato que ainda não existe cria o canal.\"\n actions={\n <Button type=\"button\" size=\"sm\" onClick={() => setSubscription(\"new\")} disabled={Boolean(agent.disabled_at)}>\n <Plus className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden /> Assinar canal\n </Button>\n }\n >\n {own.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">Sem assinaturas.</p>\n ) : (\n <ul className=\"divide-y rounded-lg border\" data-testid=\"agent-subscriptions\">\n {own.map((item) => (\n <li key={item.id} className=\"flex flex-wrap items-center gap-2 p-2 text-xs\">\n <span className=\"flex min-w-0 flex-1 flex-wrap items-center gap-1.5\">\n <HelpBadge value={`${item.is_prefix ? `prefixo ${item.target}` : item.target} · ${item.mode}`} help={SUBSCRIPTION_MODE_HELP[item.mode]} />\n <span className=\"text-muted-foreground\">alcança {item.reaches.length} canal(is)</span>\n </span>\n <TooltipIconButton label=\"Editar assinatura\" onClick={() => setSubscription(item)}>\n <Pencil aria-hidden />\n </TooltipIconButton>\n <TooltipIconButton label=\"Remover assinatura\" onClick={() => setRemoving(item)}>\n <Trash2 aria-hidden />\n </TooltipIconButton>\n </li>\n ))}\n </ul>\n )}\n </Section>\n </motion.div>\n </TabsContent>\n <TabsContent value=\"reachable\">\n <motion.div {...fade}>\n <Section title=\"Memórias acessíveis\" info=\"Memórias ativas dos canais que as assinaturas alcançam.\">\n <AccessibleMemories channels={reached} />\n </Section>\n </motion.div>\n </TabsContent>\n </Tabs>\n {editing && <AgentDialog agent={agent} apps={apps} open onOpenChange={setEditing} />}\n {subscription !== null && (\n <SubscriptionDialog key={subscription === \"new\" ? \"new\" : subscription.id} channel=\"\" subscription={subscription === \"new\" ? null : subscription} agents={[agent]} open onOpenChange={(open) => !open && setSubscription(null)} />\n )}\n <ConfirmDialog\n open={removing !== null}\n onOpenChange={(open) => !open && setRemoving(null)}\n title=\"Remover a assinatura?\"\n description={`${agent.qualified_slug} deixa de alcançar ${removing?.target ?? \"\"}. As memórias continuam no canal.`}\n confirmLabel=\"Remover\"\n variant=\"destructive\"\n pending={remove.isPending}\n onConfirm={() => removing && remove.mutate(removing.id, { onSettled: () => setRemoving(null) })}\n />\n </div>\n )\n}\n","import type { EngramindAgent, EngramindApp, EngramindToken } from \"./types\"\n\n/**\n * Gestão de apps, agentes e tokens da aba Identidades (OPE-117; módulo PURO). No Engramind 0.11.0 todo\n * token pertence a um app (`app` obrigatório) e o vínculo app/agente é imutável:\n * - a lista geral mostra só os tokens **administrativos** (`kind: admin`; decisão do dono);\n * - os tokens `app` e os `agent` sem agente aparecem no detalhe do app; os de agente, no agente;\n * - o **token em uso** de um app é o do próprio Opex (app opex) ou o `kind: app` ativo usado por último.\n */\n\nexport const TOKEN_EXPIRING_DAYS = 7\nexport const TOKEN_IDLE_DAYS = 30\nconst DAY_MS = 24 * 3600_000\n\nexport const adminTokens = (tokens: readonly EngramindToken[]) => tokens.filter((token) => token.kind === \"admin\")\n\nexport const tokensOfAgent = (tokens: readonly EngramindToken[], agent: Pick<EngramindAgent, \"id\" | \"slug\" | \"app\">) =>\n tokens.filter((token) => token.agent && (token.agent.id === agent.id || (token.agent.slug === agent.slug && token.app.slug === agent.app.slug)))\n\nconst time = (value: string | null | undefined) => (value ? Date.parse(value) : 0)\n\n/** Token em uso do app: o de app do Opex (id conhecido) ou o `kind: app` ativo usado (ou criado) por último. */\nexport function appTokenInUse(tokens: readonly EngramindToken[], app: Pick<EngramindApp, \"slug\">, ownIds: readonly (string | null | undefined)[] = []): EngramindToken | null {\n const candidates = tokens.filter((token) => token.app.slug === app.slug && token.kind === \"app\" && token.status === \"active\")\n const own = candidates.find((token) => ownIds.includes(token.id))\n if (own) return own\n return [...candidates].sort((a, b) => time(b.last_used_at) - time(a.last_used_at) || time(b.created_at) - time(a.created_at))[0] ?? null\n}\n\n/** Tokens do app sem agente (os `app` e os `admin` dele), sem o token em uso (que fica fixo no topo). */\nexport function tokensOfApp(tokens: readonly EngramindToken[], app: Pick<EngramindApp, \"slug\">, inUse: EngramindToken | null): EngramindToken[] {\n return tokens.filter((token) => token.app.slug === app.slug && !token.agent && token.id !== inUse?.id)\n}\n\nexport type TokenAlert = \"expiring\" | \"idle\" | \"owner-disabled\"\n\nexport const TOKEN_ALERT_LABELS: Record<TokenAlert, string> = {\n expiring: `Expira em até ${TOKEN_EXPIRING_DAYS} dias`,\n idle: `Sem uso há ${TOKEN_IDLE_DAYS} dias ou mais`,\n \"owner-disabled\": \"App ou agente desativado com o token ativo\",\n}\n\n/** Alertas de saúde de um token ativo (expirando, sem uso, dono desativado). */\nexport function tokenHealth(token: EngramindToken, context: { apps: readonly EngramindApp[]; agents: readonly EngramindAgent[] }, now = new Date()): TokenAlert[] {\n if (token.status !== \"active\") return []\n const alerts: TokenAlert[] = []\n const nowMs = now.getTime()\n if (token.expires_at && Date.parse(token.expires_at) - nowMs <= TOKEN_EXPIRING_DAYS * DAY_MS) alerts.push(\"expiring\")\n const reference = token.last_used_at ?? token.created_at\n if (reference && nowMs - Date.parse(reference) >= TOKEN_IDLE_DAYS * DAY_MS) alerts.push(\"idle\")\n const app = context.apps.find((item) => item.slug === token.app.slug)\n const agent = token.agent ? context.agents.find((item) => item.id === token.agent!.id || (item.slug === token.agent!.slug && item.app.slug === token.app.slug)) : null\n if (app?.disabled_at || agent?.disabled_at) alerts.push(\"owner-disabled\")\n return alerts\n}\n\nexport interface AppSummary {\n app: EngramindApp\n agents: number\n activeTokens: number\n /** Último uso entre os tokens do app (ISO), ou `null`. */\n lastActivity: string | null\n alerts: number\n}\n\n/** Resumo de cada app (contagens e última atividade) para a lista. */\nexport function appSummaries(apps: readonly EngramindApp[], agents: readonly EngramindAgent[], tokens: readonly EngramindToken[], now = new Date()): AppSummary[] {\n return apps.map((app) => {\n const own = tokens.filter((token) => token.app.slug === app.slug)\n const last = own.map((token) => token.last_used_at).filter((value): value is string => Boolean(value)).sort((a, b) => Date.parse(b) - Date.parse(a))[0] ?? null\n return {\n app,\n agents: agents.filter((agent) => agent.app.slug === app.slug).length,\n activeTokens: own.filter((token) => token.status === \"active\").length,\n lastActivity: last,\n alerts: own.reduce((sum, token) => sum + tokenHealth(token, { apps, agents }, now).length, 0),\n }\n })\n}\n\nexport type AppStatusFilter = \"all\" | \"active\" | \"inactive\"\n\n/** Filtros da lista de apps: busca (nome/slug), status e \"com alertas\". */\nexport function filterAppSummaries(rows: readonly AppSummary[], filters: { term: string; status: AppStatusFilter; alertsOnly: boolean }): AppSummary[] {\n const term = filters.term.trim().toLowerCase()\n return rows.filter((row) => {\n if (term && !row.app.slug.toLowerCase().includes(term) && !row.app.name.toLowerCase().includes(term)) return false\n if (filters.status === \"active\" && row.app.disabled_at) return false\n if (filters.status === \"inactive\" && !row.app.disabled_at) return false\n if (filters.alertsOnly && row.alerts === 0) return false\n return true\n })\n}\n","\"use client\"\n\nimport { useCallback } from \"react\"\nimport { Loader2 } from \"lucide-react\"\nimport { Button } from \"../../../components/ui/button\"\nimport { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from \"../../../components/ui/dialog\"\nimport { FORM_GRID } from \"../../../components/ui/form-grid\"\nimport { Input } from \"../../../components/ui/input\"\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"../../../components/ui/select\"\nimport { Textarea } from \"../../../components/ui/textarea\"\nimport { createAgentInput, updateAgentInput } from \"../../../../core/schemas\"\nimport { IDENTITY_HELP } from \"../../help/identities\"\nimport type { EngramindAgent, EngramindApp } from \"../../types\"\nimport { engramindSend, route, useEngramindMutation } from \"../../hooks/useEngramind\"\nimport { InfoField } from \"../shared/InfoField\"\nimport { emptyTo, useSchemaForm } from \"../shared/useSchemaForm\"\n\ninterface AgentDialogProps {\n agent: EngramindAgent | null\n apps: EngramindApp[]\n open: boolean\n onOpenChange: (open: boolean) => void\n}\n\ntype Values = { app: string; slug: string; name: string; description: string }\n\n/** Criar ou editar um agente (o endereço completo é app/agente). */\nexport function AgentDialog({ agent, apps, open, onOpenChange }: AgentDialogProps) {\n const editing = agent !== null\n const toPayload = useCallback(\n (values: Values) =>\n editing ? { agent: agent.qualified_slug, name: values.name.trim(), description: emptyTo(values.description, null) } : { app: values.app, slug: values.slug.trim(), name: values.name.trim(), description: emptyTo(values.description, undefined) },\n [agent, editing],\n )\n const form = useSchemaForm<Values, unknown>(editing ? updateAgentInput : createAgentInput, { app: agent?.app.slug ?? apps[0]?.slug ?? \"\", slug: agent?.slug ?? \"\", name: agent?.name ?? \"\", description: agent?.description ?? \"\" }, toPayload)\n const save = useEngramindMutation((payload: Record<string, unknown>) => (editing ? engramindSend(\"patch\", route(\"agents\", agent.qualified_slug), payload) : engramindSend(\"post\", \"agents\", payload)), {\n invalidate: [\"agents\"],\n success: editing ? \"Agente atualizado\" : \"Agente criado\",\n })\n const submit = () => form.payload && save.mutate(form.payload as Record<string, unknown>, { onSuccess: () => onOpenChange(false) })\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"sm:max-w-xl\">\n <DialogHeader>\n <DialogTitle>{editing ? `Editar agente ${agent.qualified_slug}` : \"Novo agente\"}</DialogTitle>\n <DialogDescription>{IDENTITY_HELP.agent}</DialogDescription>\n </DialogHeader>\n <div className={FORM_GRID}>\n <InfoField id=\"agent-app\" label=\"App\" info=\"App dono do agente.\" error={form.error(\"app\")}>\n <Select value={form.values.app} onValueChange={(value) => form.set(\"app\", value)} disabled={editing}>\n <SelectTrigger id=\"agent-app\" className=\"bg-transparent\">\n <SelectValue placeholder=\"Escolha o app\" />\n </SelectTrigger>\n <SelectContent>\n {apps.map((app) => (\n <SelectItem key={app.id} value={app.slug}>\n {app.name} ({app.slug})\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </InfoField>\n <InfoField id=\"agent-slug\" label=\"Slug\" info=\"Único dentro do app; minúsculas, dígitos e hífens. Não muda depois.\" error={form.error(\"slug\")}>\n <Input id=\"agent-slug\" value={form.values.slug} onChange={(event) => form.set(\"slug\", event.target.value)} disabled={editing} placeholder=\"curador\" />\n </InfoField>\n <InfoField id=\"agent-name\" label=\"Nome\" error={form.error(\"name\")}>\n <Input id=\"agent-name\" value={form.values.name} onChange={(event) => form.set(\"name\", event.target.value)} />\n </InfoField>\n <InfoField id=\"agent-description\" label=\"Descrição\" error={form.error(\"description\")}>\n <Textarea id=\"agent-description\" rows={2} value={form.values.description} onChange={(event) => form.set(\"description\", event.target.value)} />\n </InfoField>\n </div>\n <DialogFooter>\n <Button type=\"button\" onClick={submit} disabled={!form.valid || save.isPending}>\n {save.isPending && <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" aria-hidden />} {editing ? \"Salvar\" : \"Criar agente\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n","\"use client\"\n\nimport { useState } from \"react\"\nimport { AnimatePresence } from \"framer-motion\"\nimport { Ban, KeyRound, Pencil, Plus, RefreshCw } from \"lucide-react\"\nimport { Button } from \"../../../components/ui/button\"\nimport { ConfirmDialog } from \"../../../components/ui/confirm-dialog\"\nimport { TooltipIconButton } from \"../../../components/ui/tooltip-icon-button\"\nimport { EmptyState } from \"../../../components/feedback/EmptyState\"\nimport { VirtualizedRows } from \"../../../components/list/VirtualizedRows\"\nimport { IDENTITY_HELP, SCOPE_HELP, TOKEN_KIND_HELP, TOKEN_STATUS_HELP } from \"../../help/identities\"\nimport type { EngramindAgent, EngramindApp, EngramindToken } from \"../../types\"\nimport { engramindSend, route, useEngramindMutation } from \"../../hooks/useEngramind\"\nimport { HelpBadge, toneOf } from \"../shared/Badges\"\nimport { formatDateTime, formatRelative } from \"../shared/format\"\nimport { Section } from \"../shared/Section\"\nimport { EditTokenDialog } from \"./EditTokenDialog\"\nimport { IssueTokenDialog, type IssueTokenPreset } from \"./IssueTokenDialog\"\nimport { RotateTokenDialog } from \"./RotateTokenDialog\"\nimport { TokenHealthBadges } from \"./TokenHealthBadges\"\n\ninterface TokensCardProps {\n tokens: EngramindToken[]\n apps: EngramindApp[]\n agents: EngramindAgent[]\n /** Tokens do próprio Opex (admin da Conexão e o de app): selo \"Este Opex\" e protegidos. */\n ownTokenIds: readonly (string | null | undefined)[]\n title?: string\n info?: string\n /** Emissão já escopada ao app/agente da tela (OPE-117). */\n issuePreset?: IssueTokenPreset\n emptyDescription?: string\n}\n\n/** Tokens: prefixo, dono, tipo, escopos, rótulo, status, expiração, último uso e alertas; emitir, editar, rotacionar e revogar. */\nexport function TokensCard({ tokens, apps, agents, ownTokenIds, title = \"Tokens\", info, issuePreset, emptyDescription = \"Emita um token para um app ou agente.\" }: TokensCardProps) {\n const [issuing, setIssuing] = useState(false)\n const [editing, setEditing] = useState<EngramindToken | null>(null)\n const [revoking, setRevoking] = useState<EngramindToken | null>(null)\n const [rotating, setRotating] = useState<EngramindToken | null>(null)\n const revoke = useEngramindMutation((id: string) => engramindSend(\"post\", route(\"tokens\", id, \"revoke\"), {}), { invalidate: [\"tokens\"], success: \"Token revogado\" })\n const isOwn = (id: string) => ownTokenIds.includes(id)\n return (\n <Section\n title={title}\n info={info ?? `${IDENTITY_HELP.token} ${IDENTITY_HELP.lastAdmin}`}\n actions={\n <Button type=\"button\" size=\"sm\" onClick={() => setIssuing(true)}>\n <Plus className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden /> Emitir token\n </Button>\n }\n >\n {tokens.length === 0 ? (\n <EmptyState icon={KeyRound} title=\"Nenhum token\" description={emptyDescription} actionLabel=\"Emitir token\" onAction={() => setIssuing(true)} />\n ) : (\n <div className=\"max-h-[32rem] overflow-auto rounded-lg border\">\n <VirtualizedRows\n rows={tokens}\n rowKey={(token) => token.id}\n estimateSize={72}\n rowClassName=\"border-b last:border-b-0\"\n renderRow={(token) => {\n const own = isOwn(token.id)\n const inactive = token.status !== \"active\"\n return (\n <div className=\"flex flex-wrap items-center gap-2 p-3 text-sm\">\n <div className=\"min-w-0 flex-1 space-y-1\">\n <div className=\"flex flex-wrap items-center gap-1.5\">\n <span className=\"font-mono text-xs\">{token.prefix}</span>\n {own && <HelpBadge value=\"Este Opex\" tone=\"secondary\" help={IDENTITY_HELP.ownToken} />}\n <HelpBadge value={token.kind} help={TOKEN_KIND_HELP[token.kind]} />\n <HelpBadge value={token.status} tone={toneOf(token.status)} help={TOKEN_STATUS_HELP[token.status]} />\n {token.scopes.map((scope) => (\n <HelpBadge key={scope} value={scope} help={SCOPE_HELP[scope]} />\n ))}\n <TokenHealthBadges token={token} apps={apps} agents={agents} />\n </div>\n <p className=\"text-xs text-muted-foreground\">\n {token.label ?? \"Sem rótulo\"} · {token.agent ? `${token.app.slug}/${token.agent.slug}` : token.app.slug} · expira {token.expires_at ? formatDateTime(token.expires_at) : \"nunca\"} · último uso {formatRelative(token.last_used_at)}\n </p>\n </div>\n <TooltipIconButton label=\"Editar token\" onClick={() => setEditing(token)} disabledReason={inactive ? \"Token inativo\" : null}>\n <Pencil aria-hidden />\n </TooltipIconButton>\n <TooltipIconButton label=\"Rotacionar token\" onClick={() => setRotating(token)} disabledReason={inactive ? \"Token inativo\" : null}>\n <RefreshCw aria-hidden />\n </TooltipIconButton>\n <TooltipIconButton label=\"Revogar token\" onClick={() => setRevoking(token)} disabledReason={own ? \"É um token que o Opex usa: rotacione em vez de revogar\" : inactive ? \"Token já inativo\" : null}>\n <Ban aria-hidden />\n </TooltipIconButton>\n </div>\n )\n }}\n />\n </div>\n )}\n <AnimatePresence>{issuing && <IssueTokenDialog key=\"issue\" apps={apps} agents={agents} open onOpenChange={setIssuing} preset={issuePreset} />}</AnimatePresence>\n {editing && <EditTokenDialog key={editing.id} token={editing} own={isOwn(editing.id)} open onOpenChange={(open) => !open && setEditing(null)} />}\n {rotating && <RotateTokenDialog key={rotating.id} token={rotating} own={isOwn(rotating.id)} open onOpenChange={(open) => !open && setRotating(null)} />}\n <ConfirmDialog\n open={revoking !== null}\n onOpenChange={(open) => !open && setRevoking(null)}\n title={`Revogar o token ${revoking?.prefix ?? \"\"}?`}\n description=\"A próxima requisição com ele recebe 401 na hora. Não dá para desfazer.\"\n confirmLabel=\"Revogar\"\n variant=\"destructive\"\n pending={revoke.isPending}\n onConfirm={() => revoking && revoke.mutate(revoking.id, { onSettled: () => setRevoking(null) })}\n />\n </Section>\n )\n}\n","\"use client\"\n\nimport { useCallback, useEffect, useLayoutEffect, useRef, useState } from \"react\"\nimport { useVirtualizer } from \"@tanstack/react-virtual\"\n\n/**\n * Id da área que rola as páginas (o `<main>` do `AppShell`). Listas longas rolam por ela, não por\n * um container próprio com altura máxima.\n */\nexport const APP_SCROLL_CONTAINER_ID = \"main-content\"\n\nexport function getAppScrollContainer(): HTMLElement | null {\n return typeof document === \"undefined\" ? null : document.getElementById(APP_SCROLL_CONTAINER_ID)\n}\n\nconst useIsomorphicLayoutEffect = typeof window === \"undefined\" ? useEffect : useLayoutEffect\n\ninterface PageVirtualizerOptions {\n count: number\n estimateSize: number\n overscan?: number\n /** Altura de tela usada antes da primeira medição (e em testes, sem layout). */\n initialHeight?: number\n}\n\n/**\n * Virtualização de uma lista que rola com a página (`#main-content`): mede a posição da lista dentro\n * da área de rolagem (`scrollMargin`, recalculada quando o conteúdo acima muda de altura — ex.:\n * filtros abrindo) e informa se o topo da lista já passou (`stuck`, para sombra do cabeçalho fixo).\n * Prenda `anchorRef` no elemento que envolve a lista.\n */\nexport function usePageVirtualizer({ count, estimateSize, overscan = 10, initialHeight = 800 }: PageVirtualizerOptions) {\n const anchorRef = useRef<HTMLDivElement>(null)\n const [scrollElement, setScrollElement] = useState<HTMLElement | null>(null)\n const [scrollMargin, setScrollMargin] = useState(0)\n const [stuck, setStuck] = useState(false)\n\n const measure = useCallback(() => {\n const anchor = anchorRef.current\n const container = getAppScrollContainer()\n if (!anchor || !container) return\n const offset = anchor.getBoundingClientRect().top - container.getBoundingClientRect().top + container.scrollTop\n setScrollMargin((current) => (Math.abs(current - offset) < 1 ? current : offset))\n setStuck(container.scrollTop > offset)\n }, [])\n\n useIsomorphicLayoutEffect(() => {\n const container = getAppScrollContainer()\n setScrollElement(container)\n measure()\n if (!container) return\n container.addEventListener(\"scroll\", measure, { passive: true })\n window.addEventListener(\"resize\", measure)\n // O que está acima da lista (filtros, cabeçalho) muda de altura sem rolar: mede de novo.\n const observer = typeof ResizeObserver === \"undefined\" ? null : new ResizeObserver(measure)\n const page = container.firstElementChild\n if (observer && page) observer.observe(page)\n return () => {\n container.removeEventListener(\"scroll\", measure)\n window.removeEventListener(\"resize\", measure)\n observer?.disconnect()\n }\n }, [measure])\n\n // eslint-disable-next-line react-hooks/incompatible-library -- padrão do TanStack Virtual\n const virtualizer = useVirtualizer({\n count,\n getScrollElement: () => scrollElement,\n estimateSize: () => estimateSize,\n overscan,\n scrollMargin,\n initialRect: { width: 0, height: initialHeight },\n })\n\n const items = virtualizer.getVirtualItems()\n const padTop = Math.max(0, (items[0]?.start ?? scrollMargin) - scrollMargin)\n const padBottom = Math.max(0, virtualizer.getTotalSize() - ((items.at(-1)?.end ?? scrollMargin) - scrollMargin))\n\n return { anchorRef, virtualizer, items, padTop, padBottom, stuck }\n}\n","\"use client\"\n\nimport type { ReactNode } from \"react\"\nimport { usePageVirtualizer } from \"../../hooks/usePageVirtualizer\"\n\n/** Acima disto a lista é virtualizada (regra do projeto: listas com mais de 50 itens). */\nexport const VIRTUALIZE_ABOVE = 50\n\ninterface VirtualizedRowsProps<T> {\n rows: readonly T[]\n rowKey: (row: T) => string\n renderRow: (row: T) => ReactNode\n /** Altura estimada de uma linha (as reais são medidas: linhas podem expandir). */\n estimateSize?: number\n rowClassName?: string\n}\n\nfunction PlainRows<T>({ rows, rowKey, renderRow, rowClassName }: VirtualizedRowsProps<T>) {\n return rows.map((row) => (\n <div key={rowKey(row)} role=\"listitem\" className={rowClassName}>\n {renderRow(row)}\n </div>\n ))\n}\n\nfunction VirtualRows<T>({ rows, rowKey, renderRow, estimateSize = 60, rowClassName }: VirtualizedRowsProps<T>) {\n const { anchorRef, virtualizer, items, padTop, padBottom } = usePageVirtualizer({ count: rows.length, estimateSize })\n return (\n <div ref={anchorRef} style={{ paddingTop: padTop, paddingBottom: padBottom }}>\n {items.map((item) => {\n const row = rows[item.index]\n if (!row) return null\n return (\n <div key={rowKey(row)} ref={virtualizer.measureElement} data-index={item.index} role=\"listitem\" className={rowClassName}>\n {renderRow(row)}\n </div>\n )\n })}\n </div>\n )\n}\n\n/**\n * Linhas de uma lista em card: até 50 renderiza tudo; acima, virtualiza pela rolagem da página\n * (`usePageVirtualizer`, alturas medidas). Usado pelas contas e pelos recursos do OpenCode.\n */\nexport function VirtualizedRows<T>(props: VirtualizedRowsProps<T>) {\n return props.rows.length > VIRTUALIZE_ABOVE ? <VirtualRows {...props} /> : <PlainRows {...props} />\n}\n","\"use client\"\n\nimport { useCallback } from \"react\"\nimport { Loader2 } from \"lucide-react\"\nimport { Button } from \"../../../components/ui/button\"\nimport { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from \"../../../components/ui/dialog\"\nimport { FORM_GRID } from \"../../../components/ui/form-grid\"\nimport { Input } from \"../../../components/ui/input\"\nimport { combinationOf, scopesOfCombination, SCOPE_COMBINATIONS, type ScopeCombination } from \"../../constants\"\nimport { updateTokenInput } from \"../../../../core/schemas\"\nimport { IDENTITY_HELP } from \"../../help/identities\"\nimport type { EngramindToken } from \"../../types\"\nimport { engramindSend, route, useEngramindMutation } from \"../../hooks/useEngramind\"\nimport { InfoField } from \"../shared/InfoField\"\nimport { ScopePicker } from \"../shared/ScopePicker\"\nimport { useSchemaForm } from \"../shared/useSchemaForm\"\n\nconst toLocal = (iso: string | null) => (iso ? new Date(new Date(iso).getTime() - new Date().getTimezoneOffset() * 60_000).toISOString().slice(0, 16) : \"\")\n\n/** Editar rótulo, escopos (sem escalada) e expiração. O token do Opex não pode ser rebaixado. */\nexport function EditTokenDialog({ token, own, open, onOpenChange }: { token: EngramindToken; own: boolean; open: boolean; onOpenChange: (open: boolean) => void }) {\n const toPayload = useCallback(\n (values: { label: string; scopes: ScopeCombination; expiresAt: string }) => ({\n token: token.id,\n label: values.label.trim() || null,\n scopes: scopesOfCombination(values.scopes),\n expires_at: values.expiresAt ? new Date(values.expiresAt).toISOString() : null,\n }),\n [token.id],\n )\n const form = useSchemaForm(updateTokenInput, { label: token.label ?? \"\", scopes: combinationOf(token.scopes) ?? \"read\", expiresAt: toLocal(token.expires_at) }, toPayload)\n const save = useEngramindMutation(({ token: id, ...body }: Record<string, unknown>) => engramindSend(\"patch\", route(\"tokens\", String(id)), body), { invalidate: [\"tokens\"], success: \"Token atualizado\" })\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"sm:max-w-xl\">\n <DialogHeader>\n <DialogTitle>Editar token {token.prefix}</DialogTitle>\n <DialogDescription>{own ? IDENTITY_HELP.ownToken : \"Os escopos só podem ser reduzidos (sem escalada).\"}</DialogDescription>\n </DialogHeader>\n <div className={FORM_GRID}>\n <InfoField id=\"edit-token-label\" label=\"Rótulo\" info={IDENTITY_HELP.label} error={form.error(\"label\")}>\n <Input id=\"edit-token-label\" value={form.values.label} onChange={(event) => form.set(\"label\", event.target.value)} />\n </InfoField>\n <InfoField id=\"edit-token-expires\" label=\"Expira em\" info={`${IDENTITY_HELP.expiresAt} Vazio remove a expiração.`} error={form.error(\"expires_at\")}>\n <Input id=\"edit-token-expires\" type=\"datetime-local\" value={form.values.expiresAt} onChange={(event) => form.set(\"expiresAt\", event.target.value)} />\n </InfoField>\n <InfoField id=\"edit-token-scopes\" label=\"Escopos\" info={own ? IDENTITY_HELP.ownToken : \"write e delete exigem read.\"} error={form.error(\"scopes\")} className=\"space-y-1.5 sm:col-span-2\">\n <ScopePicker id=\"edit-token-scopes\" value={form.values.scopes} onChange={(scopes) => form.set(\"scopes\", scopes)} allowed={own ? [\"read+write+delete\"] : SCOPE_COMBINATIONS} />\n </InfoField>\n </div>\n <DialogFooter>\n <Button type=\"button\" disabled={!form.valid || save.isPending} onClick={() => form.payload && save.mutate(form.payload as Record<string, unknown>, { onSuccess: () => onOpenChange(false) })}>\n {save.isPending && <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" aria-hidden />} Salvar\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n","\"use client\"\n\nimport { useCallback, useState } from \"react\"\nimport { AnimatePresence, motion } from \"framer-motion\"\nimport { Loader2 } from \"lucide-react\"\nimport { Button } from \"../../../components/ui/button\"\nimport { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from \"../../../components/ui/dialog\"\nimport { FORM_GRID } from \"../../../components/ui/form-grid\"\nimport { Input } from \"../../../components/ui/input\"\nimport { OptionTabs } from \"../../../components/ui/option-tabs\"\nimport { SecretReveal } from \"../../../components/ui/secret-reveal\"\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"../../../components/ui/select\"\nimport { scopesOfCombination, TOKEN_KINDS, type ScopeCombination } from \"../../constants\"\nimport { issueTokenInput } from \"../../../../core/schemas\"\nimport { IDENTITY_HELP, TOKEN_KIND_HELP } from \"../../help/identities\"\nimport type { EngramindAgent, EngramindApp, IssuedToken } from \"../../types\"\nimport { engramindSend, useEngramindMutation } from \"../../hooks/useEngramind\"\nimport { InfoField } from \"../shared/InfoField\"\nimport { ScopePicker } from \"../shared/ScopePicker\"\nimport { useSchemaForm } from \"../shared/useSchemaForm\"\n\n/** Emissão já escopada ao app ou ao agente em que está (OPE-117): o dono não precisa escolher. */\nexport interface IssueTokenPreset {\n app: string\n /** `app/agente` (token de agente). */\n agent?: string\n /** Só token de agente, escolhendo um agente do app (modo app: o token de app só emite `kind: agent`). */\n agentOnly?: boolean\n}\n\ninterface IssueTokenDialogProps {\n apps: EngramindApp[]\n agents: EngramindAgent[]\n open: boolean\n onOpenChange: (open: boolean) => void\n preset?: IssueTokenPreset\n}\n\ntype Values = { kind: (typeof TOKEN_KINDS)[number]; app: string; agent: string; scopes: ScopeCombination; label: string; expiresAt: string }\n\n/** Emitir token: app/agente, tipo, escopos (só combinações válidas), rótulo e expiração; o segredo aparece UMA vez. */\nexport function IssueTokenDialog({ apps, agents, open, onOpenChange, preset }: IssueTokenDialogProps) {\n const [secret, setSecret] = useState<string | null>(null)\n const toPayload = useCallback(\n (values: Values) => ({\n kind: values.kind,\n ...(values.kind === \"admin\" ? { app: values.app || undefined, agent: values.agent || undefined } : values.kind === \"app\" ? { app: values.app || undefined } : { agent: values.agent || undefined }),\n scopes: scopesOfCombination(values.scopes),\n label: values.label.trim() || undefined,\n expires_at: values.expiresAt ? new Date(values.expiresAt).toISOString() : undefined,\n }),\n [],\n )\n const form = useSchemaForm(issueTokenInput, { kind: preset ? (preset.agent || preset.agentOnly ? \"agent\" : \"app\") : \"agent\", app: preset?.app ?? apps[0]?.slug ?? \"\", agent: preset?.agent ?? (preset?.agentOnly ? (agents.find((agent) => agent.app.slug === preset.app && !agent.disabled_at)?.qualified_slug ?? \"\") : \"\"), scopes: \"read+write\", label: \"\", expiresAt: \"\" } as Values, toPayload)\n const kinds = preset ? (preset.agent || preset.agentOnly ? ([\"agent\"] as const) : ([\"app\", \"admin\"] as const)) : TOKEN_KINDS\n const issue = useEngramindMutation((payload: Record<string, unknown>) => engramindSend<IssuedToken>(\"post\", \"tokens\", payload), { invalidate: [\"tokens\"], success: \"Token emitido\" })\n const submit = () => form.payload && issue.mutate(form.payload as Record<string, unknown>, { onSuccess: (result) => setSecret(result.secret ?? null) })\n const agentOptions = form.values.kind === \"admin\" || preset?.agentOnly ? agents.filter((agent) => agent.app.slug === (preset?.agentOnly ? preset.app : form.values.app) && (!preset?.agentOnly || !agent.disabled_at)) : agents\n const showApp = !preset && (form.values.kind === \"admin\" || form.values.kind === \"app\")\n const showAgent = (!preset || Boolean(preset.agentOnly)) && form.values.kind !== \"app\"\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"sm:max-w-xl\">\n <DialogHeader>\n <DialogTitle>{secret ? \"Token emitido\" : \"Emitir token\"}</DialogTitle>\n <DialogDescription>{secret ? \"Este é o único momento em que o segredo aparece. Copie e guarde agora.\" : IDENTITY_HELP.token}</DialogDescription>\n </DialogHeader>\n <AnimatePresence mode=\"wait\" initial={false}>\n {secret ? (\n <motion.div key=\"secret\" initial={{ opacity: 0, x: 16 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, x: -16 }} className=\"space-y-3\">\n <SecretReveal value={secret} hint=\"Use no cabeçalho Authorization: Bearer … do sistema que vai consumir o Engramind.\" />\n </motion.div>\n ) : (\n <motion.div key=\"form\" initial={{ opacity: 0, x: -16 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, x: 16 }} className={FORM_GRID}>\n {preset && (\n <p className=\"text-xs text-muted-foreground sm:col-span-2\" data-testid=\"issue-preset\">\n Token {preset.agent ? `do agente ${preset.agent}` : `do app ${preset.app}`}.\n </p>\n )}\n <InfoField id=\"token-kind\" label=\"Tipo\" info={kinds.map((kind) => `${kind}: ${TOKEN_KIND_HELP[kind]}`).join(\" \")} className=\"space-y-1.5 sm:col-span-2\">\n <OptionTabs id=\"token-kind\" aria-label=\"Tipo\" options={kinds.map((kind) => ({ value: kind, label: kind, tooltip: TOKEN_KIND_HELP[kind] }))} value={form.values.kind} onChange={(kind) => form.set(\"kind\", kind)} />\n </InfoField>\n {showApp && (\n <InfoField id=\"token-app\" label=\"App\" info=\"App dono do token admin.\" error={form.error(\"app\")}>\n <Select value={form.values.app} onValueChange={(value) => form.set(\"app\", value)}>\n <SelectTrigger id=\"token-app\" className=\"bg-transparent\">\n <SelectValue placeholder=\"Escolha o app\" />\n </SelectTrigger>\n <SelectContent>\n {apps.map((app) => (\n <SelectItem key={app.id} value={app.slug}>\n {app.slug}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </InfoField>\n )}\n {showAgent && (\n <InfoField id=\"token-agent\" label={form.values.kind === \"admin\" ? \"Agente (opcional)\" : \"Agente\"} info={form.values.kind === \"agent\" ? \"Token agent pertence a um agente e só alcança os canais que ele assina.\" : \"Opcional: um agente do mesmo app.\"} error={form.error(\"agent\")}>\n <Select value={form.values.agent || \"__none__\"} onValueChange={(value) => form.set(\"agent\", value === \"__none__\" ? \"\" : value)}>\n <SelectTrigger id=\"token-agent\" className=\"bg-transparent\">\n <SelectValue placeholder=\"Escolha o agente\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"__none__\">Nenhum</SelectItem>\n {agentOptions.map((agent) => (\n <SelectItem key={agent.id} value={agent.qualified_slug}>\n {agent.qualified_slug}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </InfoField>\n )}\n <InfoField id=\"token-scopes\" label=\"Escopos\" info=\"write e delete exigem read. Quem emite não concede o que não tem.\" error={form.error(\"scopes\")} className=\"space-y-1.5 sm:col-span-2\">\n <ScopePicker id=\"token-scopes\" value={form.values.scopes} onChange={(scopes) => form.set(\"scopes\", scopes)} />\n </InfoField>\n <InfoField id=\"token-label\" label=\"Rótulo\" info={IDENTITY_HELP.label} error={form.error(\"label\")}>\n <Input id=\"token-label\" value={form.values.label} onChange={(event) => form.set(\"label\", event.target.value)} placeholder=\"curador produção\" />\n </InfoField>\n <InfoField id=\"token-expires\" label=\"Expira em (opcional)\" info={IDENTITY_HELP.expiresAt} error={form.error(\"expires_at\")}>\n <Input id=\"token-expires\" type=\"datetime-local\" value={form.values.expiresAt} onChange={(event) => form.set(\"expiresAt\", event.target.value)} />\n </InfoField>\n </motion.div>\n )}\n </AnimatePresence>\n <DialogFooter>\n {secret ? (\n <Button type=\"button\" onClick={() => onOpenChange(false)}>\n Já copiei\n </Button>\n ) : (\n <Button type=\"button\" onClick={submit} disabled={!form.valid || issue.isPending}>\n {issue.isPending && <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" aria-hidden />} Emitir\n </Button>\n )}\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n","\"use client\"\n\nimport { useState, type ReactNode } from \"react\"\nimport { Check, Copy, ShieldAlert } from \"lucide-react\"\nimport { toast } from \"../../lib/toast\"\nimport { Button } from \"./button\"\n\ninterface SecretRevealProps {\n value: string\n /** Texto do toast e do rótulo acessível (ex.: \"Token\"). */\n noun?: string\n /** Aviso abaixo do valor. */\n hint?: ReactNode\n}\n\n/** Valor secreto que aparece UMA vez: código, Copiar e o aviso de uso. */\nexport function SecretReveal({ value, noun = \"Token\", hint }: SecretRevealProps) {\n const [copied, setCopied] = useState(false)\n const copy = async () => {\n try {\n await navigator.clipboard.writeText(value)\n setCopied(true)\n toast.success(`${noun} copiado.`)\n } catch {\n toast.error(\"Não foi possível copiar: selecione e copie manualmente.\")\n }\n }\n return (\n <>\n <div className=\"flex items-center gap-2 rounded-md border bg-muted/50 p-2\">\n <code className=\"min-w-0 flex-1 break-all font-mono text-xs\">{value}</code>\n <Button type=\"button\" size=\"sm\" variant=\"outline\" onClick={() => void copy()} aria-label={`Copiar ${noun.toLowerCase()}`}>\n {copied ? <Check className=\"h-4 w-4\" aria-hidden /> : <Copy className=\"h-4 w-4\" aria-hidden />}\n </Button>\n </div>\n {hint && (\n <p className=\"flex items-start gap-2 text-xs text-muted-foreground\">\n <ShieldAlert className=\"mt-0.5 h-3.5 w-3.5 shrink-0 text-warning\" aria-hidden />\n <span>{hint}</span>\n </p>\n )}\n </>\n )\n}\n","\"use client\"\n\nimport { useState } from \"react\"\nimport { AnimatePresence, motion } from \"framer-motion\"\nimport { CheckCircle2, Loader2 } from \"lucide-react\"\nimport { Button } from \"../../../components/ui/button\"\nimport { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from \"../../../components/ui/dialog\"\nimport { SecretReveal } from \"../../../components/ui/secret-reveal\"\nimport type { EngramindToken, IssuedToken } from \"../../types\"\nimport { engramindSend, route, useEngramindMutation } from \"../../hooks/useEngramind\"\n\ntype Rotated = IssuedToken & { own?: \"admin\" | \"app\" | null; savedOwn?: boolean }\n\n/**\n * Rotacionar (OPE-117): o Engramind emite o token igual e revoga o antigo num passo. O consumidor precisa\n * receber o novo segredo (mostrado UMA vez, com Copiar); nos tokens do próprio Opex ele já é gravado.\n */\nexport function RotateTokenDialog({ token, own, open, onOpenChange }: { token: EngramindToken; own: boolean; open: boolean; onOpenChange: (open: boolean) => void }) {\n const [result, setResult] = useState<Rotated | null>(null)\n const rotate = useEngramindMutation(() => engramindSend<Rotated>(\"post\", route(\"tokens\", token.id, \"rotate\"), {}), { invalidate: [\"tokens\", \"connection\"], success: \"Token rotacionado\" })\n const done = result !== null\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"sm:max-w-xl\">\n <DialogHeader>\n <DialogTitle>{done ? \"Token rotacionado\" : `Rotacionar o token ${token.prefix}?`}</DialogTitle>\n <DialogDescription>\n {done\n ? result.savedOwn\n ? \"O novo segredo já foi gravado no Opex; o antigo deixou de autenticar.\"\n : \"Este é o único momento em que o novo segredo aparece. Copie e entregue ao consumidor agora.\"\n : own\n ? \"É um token do próprio Opex: o novo segredo é gravado sozinho na integração e o antigo deixa de autenticar na hora.\"\n : \"Um token igual (mesmo app, agente, escopos, rótulo e validade) é emitido e o antigo é revogado na hora: o consumidor precisa receber o novo segredo.\"}\n </DialogDescription>\n </DialogHeader>\n <AnimatePresence mode=\"wait\" initial={false}>\n {done && (\n <motion.div key=\"done\" initial={{ opacity: 0, x: 16 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0 }} className=\"space-y-2\" data-testid=\"rotate-result\">\n {result.secret ? (\n <>\n {result.own && <p className=\"text-xs text-warning\">O Opex não conseguiu gravar o novo segredo: cole-o na aba Conexão ({result.own === \"admin\" ? \"Token admin\" : \"Token do app opex\"}).</p>}\n <SecretReveal value={result.secret} hint=\"Use no cabeçalho Authorization: Bearer … do sistema que consome o Engramind.\" />\n </>\n ) : (\n <p className=\"flex items-center gap-1.5 text-sm text-success\">\n <CheckCircle2 className=\"h-4 w-4\" aria-hidden /> Novo token {result.token.prefix} em uso.\n </p>\n )}\n </motion.div>\n )}\n </AnimatePresence>\n <DialogFooter>\n {done ? (\n <Button type=\"button\" onClick={() => onOpenChange(false)}>\n {result.secret ? \"Já copiei\" : \"Fechar\"}\n </Button>\n ) : (\n <>\n <Button type=\"button\" variant=\"outline\" className=\"bg-transparent\" onClick={() => onOpenChange(false)} disabled={rotate.isPending}>\n Cancelar\n </Button>\n <Button type=\"button\" onClick={() => rotate.mutate(undefined as never, { onSuccess: (response) => setResult(response) })} disabled={rotate.isPending}>\n {rotate.isPending && <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" aria-hidden />} Rotacionar\n </Button>\n </>\n )}\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n","\"use client\"\n\nimport { TOKEN_ALERT_LABELS, tokenHealth } from \"../../identities\"\nimport type { EngramindAgent, EngramindApp, EngramindToken } from \"../../types\"\nimport { HelpBadge } from \"../shared/Badges\"\n\n/** Alertas de saúde do token (expirando, sem uso, dono desativado), no padrão dos selos da aba. */\nexport function TokenHealthBadges({ token, apps, agents }: { token: EngramindToken; apps: readonly EngramindApp[]; agents: readonly EngramindAgent[] }) {\n const alerts = tokenHealth(token, { apps, agents })\n return (\n <>\n {alerts.map((alert) => (\n <HelpBadge key={alert} value={alert === \"expiring\" ? \"expira logo\" : alert === \"idle\" ? \"sem uso\" : \"dono desativado\"} tone=\"warning\" help={TOKEN_ALERT_LABELS[alert]} />\n ))}\n </>\n )\n}\n","\"use client\"\n\nimport { useState } from \"react\"\nimport { Bot, ChevronRight, Pencil, Plus, Power, Trash2 } from \"lucide-react\"\nimport { Button } from \"../../../components/ui/button\"\nimport { ConfirmDialog } from \"../../../components/ui/confirm-dialog\"\nimport { TooltipIconButton } from \"../../../components/ui/tooltip-icon-button\"\nimport { EmptyState } from \"../../../components/feedback/EmptyState\"\nimport { VirtualizedRows } from \"../../../components/list/VirtualizedRows\"\nimport { IDENTITY_HELP, SUBSCRIPTION_MODE_HELP } from \"../../help/identities\"\nimport type { EngramindAgent, EngramindApp, EngramindSubscription } from \"../../types\"\nimport { engramindSend, route, useEngramindMutation } from \"../../hooks/useEngramind\"\nimport { HelpBadge } from \"../shared/Badges\"\nimport { Section } from \"../shared/Section\"\nimport { AgentDialog } from \"./AgentDialog\"\n\n/** Agentes: criar, editar, desativar/reativar e excluir; cada um mostra as assinaturas (só leitura). */\nexport function AgentsCard({ agents, apps, subscriptions, onOpen }: { agents: EngramindAgent[]; apps: EngramindApp[]; subscriptions: EngramindSubscription[]; onOpen?: (agent: EngramindAgent) => void }) {\n const [editing, setEditing] = useState<EngramindAgent | null | \"new\">(null)\n const [deleting, setDeleting] = useState<EngramindAgent | null>(null)\n const toggle = useEngramindMutation((agent: EngramindAgent) => engramindSend(\"patch\", route(\"agents\", agent.qualified_slug), { disabled: !agent.disabled_at }), {\n invalidate: [\"agents\"],\n success: (agent) => (agent.disabled_at ? \"Agente reativado\" : \"Agente desativado\"),\n })\n const remove = useEngramindMutation((slug: string) => engramindSend(\"delete\", route(\"agents\", slug)), { invalidate: [\"agents\", \"tokens\", \"subscriptions\"], success: \"Agente excluído\" })\n return (\n <Section\n title=\"Agentes\"\n info={IDENTITY_HELP.agent}\n actions={\n <Button type=\"button\" size=\"sm\" onClick={() => setEditing(\"new\")} disabled={apps.length === 0}>\n <Plus className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden /> Novo agente\n </Button>\n }\n >\n {agents.length === 0 ? (\n <EmptyState icon={Bot} title=\"Nenhum agente\" description=\"Agentes pertencem a um app e operam memórias pelos canais que assinam.\" actionLabel={apps.length ? \"Novo agente\" : undefined} onAction={() => setEditing(\"new\")} />\n ) : (\n <div className=\"max-h-[28rem] overflow-auto rounded-lg border\">\n <VirtualizedRows\n rows={agents}\n rowKey={(agent) => agent.id}\n estimateSize={64}\n rowClassName=\"border-b last:border-b-0\"\n renderRow={(agent) => {\n const own = subscriptions.filter((subscription) => subscription.agent.id === agent.id)\n return (\n <div className=\"flex flex-wrap items-center gap-2 p-3 text-sm\">\n <div className=\"min-w-0 flex-1 space-y-1\">\n <p className=\"flex flex-wrap items-center gap-1.5 font-medium\">\n {agent.name} <span className=\"font-mono text-xs text-muted-foreground\">{agent.qualified_slug}</span>\n {agent.disabled_at && <HelpBadge value=\"desativado\" tone=\"warning\" help={IDENTITY_HELP.disabled} />}\n </p>\n <div className=\"flex flex-wrap items-center gap-1 text-xs text-muted-foreground\">\n {own.length === 0 ? (\n \"Sem assinaturas\"\n ) : (\n own.map((subscription) => <HelpBadge key={subscription.id} value={`${subscription.target} · ${subscription.mode}`} help={SUBSCRIPTION_MODE_HELP[subscription.mode]} />)\n )}\n </div>\n </div>\n {onOpen && (\n <TooltipIconButton label={`Abrir o agente ${agent.qualified_slug}`} onClick={() => onOpen(agent)}>\n <ChevronRight aria-hidden />\n </TooltipIconButton>\n )}\n <TooltipIconButton label=\"Editar agente\" onClick={() => setEditing(agent)}>\n <Pencil aria-hidden />\n </TooltipIconButton>\n <TooltipIconButton label={agent.disabled_at ? \"Reativar agente\" : \"Desativar agente\"} tooltip={IDENTITY_HELP.disabled} onClick={() => toggle.mutate(agent)}>\n <Power aria-hidden />\n </TooltipIconButton>\n <TooltipIconButton label=\"Excluir agente\" onClick={() => setDeleting(agent)}>\n <Trash2 aria-hidden />\n </TooltipIconButton>\n </div>\n )\n }}\n />\n </div>\n )}\n {editing !== null && <AgentDialog key={editing === \"new\" ? \"new\" : editing.id} agent={editing === \"new\" ? null : editing} apps={apps} open onOpenChange={(open) => !open && setEditing(null)} />}\n <ConfirmDialog\n open={deleting !== null}\n onOpenChange={(open) => !open && setDeleting(null)}\n title={`Excluir o agente ${deleting?.qualified_slug ?? \"\"}?`}\n description=\"Saem junto os tokens e as assinaturas dele. A autoria das memórias e a auditoria ficam.\"\n confirmLabel=\"Excluir\"\n variant=\"destructive\"\n pending={remove.isPending}\n onConfirm={() => deleting && remove.mutate(deleting.qualified_slug, { onSettled: () => setDeleting(null) })}\n />\n </Section>\n )\n}\n","\"use client\"\n\nimport { useMemo, useState } from \"react\"\nimport { Hash, MoreHorizontal, Plus } from \"lucide-react\"\nimport { EmptyState } from \"../../../components/feedback/EmptyState\"\nimport { Button } from \"../../../components/ui/button\"\nimport { useT } from \"../../../lib/config\"\nimport { CHANNEL_HELP } from \"../../help/identities\"\nimport type { EngramindAgent, EngramindChannel, EngramindSubscription } from \"../../types\"\nimport { ChannelPanel } from \"../network/ChannelPanel\"\nimport { ChannelDisplayName } from \"../network/ChannelName\"\nimport { ChannelBySubscriptionDialog } from \"../page/channels/ChannelBySubscriptionDialog\"\nimport { HelpBadge } from \"../shared/Badges\"\nimport { Section } from \"../shared/Section\"\n\n/**\n * Canais que os agentes do app alcançam: criar pela assinatura exata (o token de app não cria canal\n * direto), abrir o painel do canal (assinantes, arquivar e restaurar os que o app criou; o Engramind\n * recusa os compartilhados com `409 CHANNEL_SHARED`).\n */\nexport function ChannelsCard({ channels, agents, subscriptions }: { channels: readonly EngramindChannel[]; agents: readonly EngramindAgent[]; subscriptions: readonly EngramindSubscription[] }) {\n const t = useT()\n const [creating, setCreating] = useState(false)\n const [panel, setPanel] = useState<string | null>(null)\n const subscribers = useMemo(() => {\n const counts = new Map<string, Set<string>>()\n for (const subscription of subscriptions) for (const slug of subscription.reaches) counts.set(slug, (counts.get(slug) ?? new Set()).add(subscription.agent.id))\n return counts\n }, [subscriptions])\n const sorted = useMemo(() => [...channels].sort((a, b) => Number(Boolean(a.archived_at)) - Number(Boolean(b.archived_at)) || a.slug.localeCompare(b.slug)), [channels])\n const hasAgents = agents.some((agent) => !agent.disabled_at)\n return (\n <Section\n title={t(\"config.channels.title\")}\n info=\"Memórias pertencem a canais. Os agentes do app alcançam um canal quando o assinam.\"\n actions={\n <Button type=\"button\" size=\"sm\" onClick={() => setCreating(true)} disabled={!hasAgents}>\n <Plus className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden /> {t(\"config.newChannel\")}\n </Button>\n }\n >\n {sorted.length === 0 ? (\n <EmptyState icon={Hash} title=\"Nenhum canal\" description=\"Assine um canal exato com um agente do app para criá-lo.\" actionLabel={hasAgents ? t(\"config.newChannel\") : undefined} onAction={() => setCreating(true)} />\n ) : (\n <ul className=\"divide-y rounded-lg border\" data-testid=\"app-channels\">\n {sorted.map((channel) => (\n <li key={channel.id} className=\"flex flex-wrap items-center gap-2 p-3 text-sm\">\n <div className=\"min-w-0 flex-1 space-y-1\">\n <p className=\"flex flex-wrap items-center gap-1.5\">\n <span className=\"font-medium\">{channel.name}</span>\n <ChannelDisplayName slug={channel.slug} className=\"font-mono text-xs text-muted-foreground\" />\n {channel.archived_at && <HelpBadge value=\"arquivado\" tone=\"warning\" help={CHANNEL_HELP.archived} />}\n </p>\n <p className=\"text-xs text-muted-foreground\">{subscribers.get(channel.slug)?.size ?? 0} agente(s) do app</p>\n </div>\n <Button type=\"button\" variant=\"ghost\" size=\"icon\" aria-label={`Abrir o canal ${channel.slug}`} className=\"h-8 w-8\" onClick={() => setPanel(channel.slug)}>\n <MoreHorizontal className=\"h-4 w-4\" aria-hidden />\n </Button>\n </li>\n ))}\n </ul>\n )}\n {creating && <ChannelBySubscriptionDialog agents={agents} open onOpenChange={setCreating} />}\n <ChannelPanel channel={channels.find((channel) => channel.slug === panel) ?? null} onOpenChange={(open) => !open && setPanel(null)} />\n </Section>\n )\n}\n","\"use client\"\n\nimport { useState } from \"react\"\nimport { AnimatePresence, motion } from \"framer-motion\"\nimport { KeyRound, Loader2, Save, Trash2 } from \"lucide-react\"\nimport { Button } from \"../../../components/ui/button\"\nimport { ConfirmDialog } from \"../../../components/ui/confirm-dialog\"\nimport { Input } from \"../../../components/ui/input\"\nimport { SecretReveal } from \"../../../components/ui/secret-reveal\"\nimport { apiErrorMessage } from \"../../../lib/api\"\nimport { useT } from \"../../../lib/config\"\nimport { appWebhookInput } from \"../../../../core/schemas\"\nimport type { EngramindApp } from \"../../types\"\nimport { engramindSend, route, useEngramindMutation, useEngramindQuery } from \"../../hooks/useEngramind\"\nimport { HelpBadge } from \"../shared/Badges\"\nimport { formatDateTime } from \"../shared/format\"\nimport { InfoField } from \"../shared/InfoField\"\nimport { Section } from \"../shared/Section\"\n\n/** Segredo novo do webhook: 32 bytes aleatórios em hexadecimal (64 caracteres, dentro de 32 a 256). */\nexport function generateWebhookSecret(): string {\n const bytes = new Uint8Array(32)\n crypto.getRandomValues(bytes)\n return Array.from(bytes, (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\")\n}\n\n/**\n * Webhook do app (`update_app_webhook`): registrar a URL, gerar ou rotacionar o segredo (mostrado uma\n * única vez, para o app gravar no servidor dele) e remover. A leitura do estado atual usa `get_app`; se o\n * Engramind não a liberar para o token de app, a tela mostra só o que foi gravado nesta visita.\n */\nexport function WebhookCard({ app }: { app: string }) {\n const t = useT()\n const current = useEngramindQuery<EngramindApp>(route(\"apps\", app), undefined, {})\n const [saved, setSaved] = useState<EngramindApp[\"webhook\"] | undefined>(undefined)\n const webhook = saved !== undefined ? saved : current.data?.webhook\n const [url, setUrl] = useState<string | null>(null)\n const value = url ?? webhook?.url ?? \"\"\n const [secret, setSecret] = useState<string | null>(null)\n const [removing, setRemoving] = useState(false)\n const parsed = appWebhookInput.safeParse({ url: value.trim() || null })\n const save = useEngramindMutation((body: { url: string | null; secret?: string | null }) => engramindSend<EngramindApp | { app?: EngramindApp }>(\"put\", route(\"apps\", app, \"webhook\"), body), { invalidate: [\"apps\"], success: t(\"config.webhook.saved\") })\n const apply = (body: { url: string | null; secret?: string | null }, onDone?: () => void) =>\n save.mutate(body, {\n onSuccess: (result) => {\n const next = (result && \"webhook\" in result ? result : (result as { app?: EngramindApp } | null)?.app)?.webhook\n setSaved(next ?? (body.url ? { url: body.url, secret: { configured: Boolean(body.secret) || Boolean(webhook?.secret.configured), updated_at: body.secret ? new Date().toISOString() : (webhook?.secret.updated_at ?? null) } } : null))\n setUrl(null)\n onDone?.()\n },\n })\n const rotate = () => {\n const next = generateWebhookSecret()\n apply({ url: value.trim(), secret: next }, () => setSecret(next))\n }\n // A URL exige um segredo (o enviado ou o já gravado): sem segredo conhecido, salvar gera um.\n const saveUrl = () => (webhook?.secret.configured ? apply({ url: value.trim() }) : rotate())\n return (\n <Section title={t(\"config.webhook.title\")} info=\"Destino dos eventos dos canais que os agentes do app assinam (memórias, consumo, canais, assinaturas e identidades), assinados com HMAC-SHA256.\">\n <div className=\"space-y-4\" data-testid=\"webhook-card\">\n {current.isError && saved === undefined && <p className=\"text-xs text-muted-foreground\">Estado atual indisponível para este token ({apiErrorMessage(current.error)}). Gravar continua funcionando.</p>}\n <InfoField id=\"webhook-url\" label={t(\"config.webhook.url\")} info=\"URL pública do handler de webhook da lib montado pelo app (ex.: https://meu-app.com/api/engramind/webhook).\" error={value && !parsed.success ? parsed.error.issues[0]?.message : undefined}>\n <Input id=\"webhook-url\" value={value} onChange={(event) => setUrl(event.target.value)} placeholder=\"https://meu-app.com/api/engramind/webhook\" />\n </InfoField>\n <p className=\"flex flex-wrap items-center gap-1.5 text-xs text-muted-foreground\" data-testid=\"webhook-state\">\n {webhook?.url ? (\n webhook.secret.configured ? (\n <HelpBadge value={t(\"config.webhook.configured\")} tone=\"secondary\" help={`Gravado em ${formatDateTime(webhook.secret.updated_at)}`} />\n ) : (\n <HelpBadge value=\"sem segredo\" tone=\"warning\" help=\"Sem segredo, o app não consegue validar a assinatura: gere um.\" />\n )\n ) : (\n t(\"config.webhook.notConfigured\")\n )}\n </p>\n <div className=\"flex flex-wrap gap-2\">\n <Button type=\"button\" size=\"sm\" disabled={!value.trim() || !parsed.success || save.isPending} onClick={saveUrl}>\n {save.isPending ? <Loader2 className=\"mr-1.5 h-3.5 w-3.5 animate-spin\" aria-hidden /> : <Save className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden />} {t(\"config.webhook.save\")}\n </Button>\n <Button type=\"button\" size=\"sm\" variant=\"outline\" className=\"bg-transparent\" disabled={!value.trim() || !parsed.success || save.isPending} onClick={rotate}>\n <KeyRound className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden /> {t(\"config.webhook.rotate\")}\n </Button>\n {webhook?.url && (\n <Button type=\"button\" size=\"sm\" variant=\"ghost\" disabled={save.isPending} onClick={() => setRemoving(true)}>\n <Trash2 className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden /> {t(\"config.webhook.remove\")}\n </Button>\n )}\n </div>\n <AnimatePresence initial={false}>\n {secret && (\n <motion.div key=\"secret\" initial={{ opacity: 0, y: 6 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -6 }} transition={{ duration: 0.18 }} className=\"space-y-2\">\n <SecretReveal value={secret} noun=\"Segredo\" hint={t(\"config.webhook.secretOnce\")} />\n <Button type=\"button\" size=\"sm\" variant=\"ghost\" onClick={() => setSecret(null)}>\n Já copiei\n </Button>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n <ConfirmDialog\n open={removing}\n onOpenChange={setRemoving}\n title=\"Remover o webhook do app?\"\n description=\"O app deixa de receber os eventos: sem tempo real nem consumo ao vivo até registrar de novo.\"\n confirmLabel=\"Remover\"\n variant=\"destructive\"\n pending={save.isPending}\n onConfirm={() => apply({ url: null }, () => setRemoving(false))}\n />\n </Section>\n )\n}\n"],"mappings":"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","names":["useMemo","jsx","body","createContext","useContext","createContext","useContext","name","jsx","useMemo","useCallback","useEffect","useMemo","useState","AnimatePresence","motion","AppWindow","useCallback","useSyncExternalStore","subscribe","useSyncExternalStore","useCallback","subscribe","React","jsx","jsx","Icon","description","reach","iso","name","limit","cursor","reach","body","list","width","height","time","iso","useMemo","clean","route","body","useMemo","useMemo","useMemo","useQuery","useQuery","motion","jsx","jsxs","description","motion","jsx","motion","React","jsx","jsxs","jsx","jsxs","React","jsx","React","jsx","jsxs","jsxs","jsx","z","z","z","z","z","z","z","jsx","jsxs","React","cva","jsx","cva","Label","jsx","jsxs","Label","jsx","jsxs","channel","send","body","motion","useCallback","Loader2","React","jsx","useMemo","useState","jsx","jsxs","open","useCallback","priority","body","Loader2","useCallback","Loader2","Info","jsx","jsxs","Info","jsx","jsxs","open","useCallback","body","Loader2","useState","Fragment","jsx","href","Pencil","Trash2","AnimatePresence","motion","Loader2","React","jsx","jsxs","jsx","jsxs","jsx","jsxs","open","description","AnimatePresence","motion","Loader2","React","cva","X","jsx","jsxs","jsx","cva","jsxs","X","useState","jsx","jsxs","href","cva","jsx","cva","jsx","jsxs","TONES","toneOf","jsx","jsx","motion","React","jsx","jsx","jsxs","description","motion","useCallback","Loader2","jsx","jsx","jsxs","open","useCallback","priority","body","Loader2","jsx","jsxs","useState","open","createContext","useContext","useMemo","jsx","jsxs","createContext","useMemo","useContext","Fragment","jsx","jsxs","useState","Pencil","Trash2","open","createContext","useContext","useCallback","useEffect","useMemo","useRef","useState","Hash","useCallback","useEffect","useRef","useState","useQueryClient","limit","useQueryClient","useRef","useEffect","useState","useCallback","useEffect","useReactFlow","AnimatePresence","useReducedMotion","useState","motion","useReducedMotion","motion","Pencil","Trash2","React","jsx","jsxs","jsx","jsxs","iso","motion","Label","Pencil","Trash2","name","jsx","jsxs","useReducedMotion","useState","motion","createContext","useContext","useEffect","useStore","useReducedMotion","useEffect","useRef","useState","motion","useReducedMotion","createContext","useContext","useMemo","motion","useEffect","useRef","motion","jsx","jsxs","Fragment","jsx","createContext","useContext","motion","useMemo","Fragment","jsx","jsxs","LinkEdge","useState","useRef","useEffect","OrbitEdge","useReducedMotion","motion","useCallback","useSyncExternalStore","subscribe","list","jsx","jsxs","createContext","useStore","useReducedMotion","useContext","useEffect","createContext","memo","useContext","useEffect","useState","motion","useReducedMotion","memo","motion","useReducedMotion","useStore","Archive","useRef","animate","useMotionValue","control","Fragment","jsx","jsxs","useStore","useReducedMotion","slide","motion","memo","AgentNode","AppNode","ChannelNode","Archive","CenterNode","Icon","jsx","jsxs","createContext","memo","MemoryNode","useContext","useReducedMotion","slide","motion","useState","useEffect","jsx","channelColors","useReactFlow","useReducedMotion","useEffect","open","AnimatePresence","jsx","jsxs","Panel","Plus","Fragment","jsx","jsxs","Panel","Plus","useMemo","format","ptBR","useState","AnimatePresence","motion","X","useEffect","useState","animate","useMotionValue","useReducedMotion","jsx","jsx","jsxs","open","useState","X","AnimatePresence","motion","jsx","jsxs","channelColors","useMemo","format","ptBR","useEffect","useRef","useState","useEffect","useMemo","useRef","useState","useMemo","useState","cache","jsx","jsxs","channelColors","useState","useMemo","useRef","useEffect","useCallback","Hash","list","AnimatePresence","motion","Fragment","jsx","jsxs","AnimatePresence","motion","jsx","jsxs","useCallback","AnimatePresence","motion","AlertTriangle","FileUp","Info","MoreHorizontal","Plus","RotateCw","Search","X","AnimatePresence","motion","Filter","X","useEffect","useState","useCallback","useState","AnimatePresence","motion","useReducedMotion","ChevronDown","ChevronUp","AnimatePresence","motion","X","jsx","jsxs","motion","X","AnimatePresence","jsx","useState","useCallback","ChevronDown","ChevronUp","AnimatePresence","motion","useReducedMotion","jsx","jsxs","jsx","jsxs","Label","Fragment","jsx","jsxs","X","Filter","AnimatePresence","motion","useCallback","useMemo","useState","AnimatePresence","motion","Archive","Hash","React","jsx","jsx","React","Check","jsx","jsxs","Search","useState","jsx","jsxs","Icon","Search","jsx","jsxs","Icon","format","Calendar","React","format","ChevronRight","ptBR","jsx","ptBR","ChevronRight","jsx","jsxs","format","open","day","Fragment","jsx","jsxs","format","Calendar","Icon","Fragment","jsx","jsxs","Hash","Archive","open","useState","AnimatePresence","motion","jsx","useMemo","useCallback","jsx","jsxs","MoreHorizontal","FileUp","Plus","AnimatePresence","motion","AlertTriangle","RotateCw","Info","useCallback","Search","X","useCallback","useMemo","useCallback","useMemo","MoreHorizontal","useEffect","useMemo","useRef","useMemo","useRef","useEffect","Fragment","jsx","jsxs","useMemo","MoreHorizontal","useCallback","jsx","jsxs","NODE_TYPES","useMemo","reach","useCallback","list","useCallback","useMemo","jsx","jsxs","NODE_TYPES","plural","useMemo","reach","useCallback","list","AnimatePresence","motion","Fragment","jsx","jsxs","AnimatePresence","motion","useMemo","useState","useMutation","useQueryClient","History","Loader2","format","ptBR","Loader2","jsx","jsxs","Loader2","jsx","jsxs","History","Loader2","useState","Loader2","jsx","jsxs","useState","Loader2","useMemo","useRef","useId","useMemo","X","z","z","z","jsx","jsxs","z","useId","useMemo","categoria","isValid","Label","X","jsx","jsxs","open","Fragment","jsx","jsxs","useState","useQueryClient","useMutation","categoria","useMemo","open","useCallback","useEffect","useCallback","options","open","useEffect","jsx","jsxs","useCallback","useState","open","useMemo","channel","useEffect","AnimatePresence","motion","AppWindow","ArrowLeft","jsx","jsxs","description","jsx","jsxs","ArrowLeft","useState","AnimatePresence","motion","React","jsx","useMemo","useState","motion","ArrowLeft","Pencil","Plus","Trash2","DAY_MS","DAY_MS","useCallback","Loader2","jsx","jsxs","open","useCallback","Loader2","useState","AnimatePresence","KeyRound","Pencil","Plus","useCallback","useEffect","useLayoutEffect","useRef","useState","jsx","useCallback","Loader2","jsx","jsxs","iso","open","useCallback","body","Loader2","useCallback","useState","AnimatePresence","motion","Loader2","useState","Check","Fragment","jsx","jsxs","useState","Check","jsx","jsxs","open","useState","useCallback","AnimatePresence","motion","Loader2","useState","AnimatePresence","motion","Loader2","Fragment","jsx","jsxs","open","useState","AnimatePresence","motion","Loader2","Fragment","jsx","jsx","jsxs","useState","Plus","KeyRound","toneOf","Pencil","AnimatePresence","open","Fragment","jsx","jsxs","useMemo","useState","subscription","ArrowLeft","motion","Pencil","Plus","Trash2","open","useState","Bot","ChevronRight","Pencil","Plus","Power","Trash2","jsx","jsxs","useState","Plus","Bot","ChevronRight","Pencil","Power","Trash2","open","useMemo","useState","Hash","MoreHorizontal","Plus","jsx","jsxs","useState","useMemo","Plus","Hash","MoreHorizontal","open","useState","AnimatePresence","motion","KeyRound","Loader2","Save","Trash2","jsx","jsxs","useState","body","Loader2","Save","KeyRound","Trash2","AnimatePresence","motion","jsx","jsxs","fade","useState","AnimatePresence","motion"]}