/** * Org-directory discovery for the generic cross-app MCP verbs * (`list_apps` / `ask_app` in `builtin-tools.ts`). * * Phase 3b of cross-app auto-wiring. Today the cross-app verbs resolve sibling * apps from *local workspace* info only (`workspace-resolve.ts`), so the mail * agent can only reach the calendar agent in a local dev workspace. When the * deployment runs against an org directory (Dispatch is also the identity hub * for the org), this module discovers the org's *deployed* sibling apps so the * same verbs work cross-app in production with ZERO manual setup. * * ## The directory request * * GET /_agent-native/org/apps * Auth Authorization: Bearer (same signed token A2A peers * already mint — reuses `resolveA2ACallerAuth()`; the org A2A secret / * global `A2A_SECRET` is loaded exactly how outgoing A2A calls load it) * ⇒ { org, apps: [ { id, name, url, a2aUrl, capabilities? } ] } * (allow-listed first-party apps only, prod URLs — enforced by the * authority side, Phase 3a, on Dispatch) * * ## Resolution + safety model * * - A selected org's bound workspace URL wins for org-scoped requests; the * deployment's `AGENT_NATIVE_ORG_DIRECTORY_URL` or * `AGENT_NATIVE_IDENTITY_HUB_URL` is the fallback when no binding exists. * When neither is set the feature is inactive — `fetchOrgApps()` returns * `[]` and nothing changes anywhere (asserted by a test). * - `fetchOrgAppsResult()` preserves directory availability for callers * that cannot mistake a failed lookup for an empty directory. * `fetchOrgApps()` remains the best-effort compatibility wrapper: on ANY * error it returns `[]` and NEVER throws, so cross-app verbs still degrade * silently to their exact current local-only behavior. * - Mounted `/dispatch` requests retry at the host root only after a 404. * Credentialed requests require HTTPS and use manual redirects. A short * in-memory TTL cache (default 60s) is keyed by directory origin and * caller identity/org scope so sibling app lists never cross tenants. * Successful responses are cached for 60s; transient unavailable results * are cached for 30s to avoid repeating failing directory requests. * - No secrets are ever logged. * * Bundled alongside `mountMCP` (no Node-only top-level imports). The A2A * caller-auth + a2a client are dynamically imported inside `fetchOrgApps()`. */ export interface OrgApp { id: string; name: string; url: string; a2aUrl: string; capabilities?: string[]; description?: string; whenToUse?: string[]; aliases?: string[]; } export type OrgDirectoryUnavailableReason = "not-configured" | "authentication" | "unauthorized" | "authorization" | "invalid-origin" | "missing-route" | "timeout" | "network" | "invalid-response" | "ssrf-blocked" | "workspace-url-unavailable" | "server-error" | "http-error"; export type OrgDirectoryFetchResult = { status: "available"; apps: OrgApp[]; } | { status: "unavailable"; reason: OrgDirectoryUnavailableReason; }; export declare function resolveOrgDirectoryOrigin(env?: NodeJS.ProcessEnv): string | null; export interface FetchOrgAppsOptions { selfId?: string; selfOrigin?: string; directoryBaseUrl?: string; includeDirectoryApp?: boolean; serviceOrgId?: string; env?: NodeJS.ProcessEnv; } export declare function fetchOrgAppsResult(opts?: FetchOrgAppsOptions): Promise; export declare function fetchOrgApps(opts?: FetchOrgAppsOptions): Promise; export declare function _resetOrgDirectoryCache(): void;