/** * Config teardown shared by every plugin's `uninstall` command. * * `config.json` is a **single shared file** every installed harness plugin * reads, so teardown is scoped: uninstalling one plugin must not knock the * others back to an unconfigured state. Two scopes exist, and which one runs is * decided from the install registry, not from a flag the caller guesses at: * * - **`harness` scope** — other plugins are still installed. Only the * departing harness's own identities go: the agent and sub-agent DCR * clients of **every session it retains** are revoked (RFC 7592), and its * entries are removed from `agent.dynamic` / `agent.subAgents`. Shared * state — `projectUrl`, `oauth2ClientId`, the user's tokens, the permission * mode — is left exactly as it was. * - **`all` scope** — the departing harness was the last one installed, or * the caller passed `purge: true`. Every harness's clients are revoked and * the config file is left as an empty object, so a re-install starts from a * clean slate rather than inheriting stale state. * * What an `all` teardown removes: * - the user's persisted OAuth2 tokens (`user`) * - every harness's agent and sub-agent registrations, across all sessions * (`agent`) * - all configuration values (`projectUrl`, `projectId`, `projectName`, * `workspaceName`, `oauth2ClientId`, `permissionModeCache`, * `userSubjectNamespace`, `installedHarnesses`) * - any dangling PKCE-flight lock * * Server-side teardown runs first, best-effort, and covers exactly the * resources the plugin itself created: each dynamically-registered OAuth2 * client in scope (the agent and every sub-agent, for every retained session) * is revoked via RFC 7592, so the Ory project isn't left with orphaned clients * accumulating across install/uninstall cycles. * * Nothing in the project's **permission** state is touched. Grants, blocks, * delegation edges, and the permission model are provisioned in the Ory * Console (Agent Security) and owned there — the plugin has no Keto write * path to unwind them with, and deleting an admin's grants on uninstall was * never its call to make. The shared user-login PKCE OAuth2 client * (`oauth2ClientId`) is likewise left in place: it is a public, identity-free * client that every user and every harness install on the project reuses, so * deleting it would break other installations. Both are only forgotten * locally. Every server-side step is best-effort: failures warn and local * state is cleared regardless. */ import { type OryPluginConfig } from "./config.js"; export interface ClearCredentialsOptions { /** * The harness being uninstalled. When other harness plugins are still * installed, teardown is scoped to this one and the shared config survives. * Omitted ⇒ the caller can't say whose state this is, so the whole config is * wiped (the pre-scoping behavior). */ harness?: string; /** * Force a full wipe of the shared config and every harness's credentials, * even when other plugins are still installed. Backs an explicit * `uninstall --purge`. Default: `false`. */ purge?: boolean; /** * Best-effort RFC 7592 `DELETE` of the agent + sub-agent dynamic clients * before clearing local state. Default: `true`. Set `false` to clear * local state only (offline / no network). */ revoke?: boolean; /** Sink for progress and warning lines. Default: `console.log`. */ log?: (message: string) => void; } export interface ClearCredentialsResult { /** Whether any credential was present before clearing. */ hadCredentials: boolean; /** * `harness` — only the departing harness's state was removed and the shared * config survives; `all` — everything was wiped (last plugin, or `purge`). */ scope: "harness" | "all"; /** Harness plugins still installed after this uninstall. */ remainingHarnesses: string[]; /** Number of dynamic clients revoked server-side (includes already-gone). */ revoked: number; /** Number of dynamic clients whose server-side revoke failed. */ revokeFailures: number; } /** * The harness plugins installed against the shared config, reconciled from * every source that evidences one. * * The `installedHarnesses` registry is authoritative, but it only exists on * configs written since it was introduced. Treating its absence as "nothing is * installed" would make the first uninstall on an upgraded machine wipe the * config every other plugin depends on — precisely the failure being fixed. So * the runtime manifest (what each harness has wired) and the persisted * credentials (which harnesses hold an identity) are folded in as evidence. */ export declare function resolveInstalledHarnesses(config?: OryPluginConfig): string[]; /** * Tear down the departing harness's state, wiping the whole shared config only * when nothing else still depends on it. Dynamically-registered clients in * scope are revoked server-side first. Never throws. */ export declare function clearCredentialsForUninstall(options?: ClearCredentialsOptions): Promise;