{"version":3,"file":"oauth-bridge-C_MAPMGA.mjs","names":["#path","#persist"],"sources":["../src/compat/vendor/pi-ai-abort.ts","../src/compat/vendor/pi-ai-credential-store.ts","../src/compat/vendor/pi-ai-diagnostics.ts","../src/compat/vendor/pi-ai-auth-resolve.ts","../src/compat/vendor/pi-oauth-adapt.ts","../src/oauth-bridge.ts"],"sourcesContent":["// @ts-nocheck — vendored Pi source (pi-ai utils/abort.js @0.84.1, MIT, see ./PI-LICENSE); unchanged.\nfunction abortReason(signal) {\n    if (signal.reason !== undefined)\n        return signal.reason;\n    const error = new Error(\"The operation was aborted\");\n    error.name = \"AbortError\";\n    return error;\n}\n/** Create an operation-local signal for public APIs whose signal is optional. */\nexport function operationSignal(signal) {\n    return signal ?? new AbortController().signal;\n}\n/**\n * Stop waiting for an operation when its signal aborts while continuing to\n * observe the abandoned promise so a later rejection is always handled.\n */\nexport function raceWithAbortSignal(operation, signal) {\n    if (signal.aborted) {\n        void operation.catch(() => { });\n        return Promise.reject(abortReason(signal));\n    }\n    return new Promise((resolve, reject) => {\n        let settled = false;\n        const cleanup = () => signal.removeEventListener(\"abort\", onAbort);\n        const onAbort = () => {\n            if (settled)\n                return;\n            settled = true;\n            cleanup();\n            reject(abortReason(signal));\n        };\n        signal.addEventListener(\"abort\", onAbort, { once: true });\n        void operation.then((value) => {\n            if (settled)\n                return;\n            settled = true;\n            cleanup();\n            resolve(value);\n        }, (error) => {\n            if (settled)\n                return;\n            settled = true;\n            cleanup();\n            reject(error);\n        });\n        if (signal.aborted)\n            onAbort();\n    });\n}\n//# sourceMappingURL=abort.js.map","// @ts-nocheck — vendored Pi source (pi-ai auth/credential-store.js @0.84.1, MIT, see ./PI-LICENSE); import remapped, logic unchanged.\nimport { operationSignal, raceWithAbortSignal } from './pi-ai-abort.js';\n/**\n * Default in-memory credential store. Apps inject persistent stores.\n * Keyed by `Provider.id`, one credential per provider; see `CredentialStore`.\n * Writes are serialized per provider through a promise chain.\n */\nexport class InMemoryCredentialStore {\n    credentials = new Map();\n    chains = new Map();\n    /** Serialize tasks per provider id without releasing the chain before active work settles. */\n    enqueue(providerId, task, options) {\n        const signal = operationSignal(options?.signal);\n        const previous = this.chains.get(providerId) ?? Promise.resolve();\n        const queued = (async () => {\n            await previous.catch(() => { });\n            signal.throwIfAborted();\n            return task();\n        })();\n        const tail = queued.catch(() => { });\n        this.chains.set(providerId, tail);\n        void tail.then(() => {\n            if (this.chains.get(providerId) === tail)\n                this.chains.delete(providerId);\n        });\n        return raceWithAbortSignal(queued, signal);\n    }\n    async read(providerId, options) {\n        options?.signal?.throwIfAborted();\n        return this.credentials.get(providerId);\n    }\n    async list(options) {\n        options?.signal?.throwIfAborted();\n        return [...this.credentials].map(([providerId, credential]) => ({ providerId, type: credential.type }));\n    }\n    modify(providerId, fn, options) {\n        return this.enqueue(providerId, async () => {\n            const current = this.credentials.get(providerId);\n            const next = await fn(current);\n            options?.signal?.throwIfAborted();\n            if (next !== undefined)\n                this.credentials.set(providerId, next);\n            return next ?? current;\n        }, options);\n    }\n    delete(providerId, options) {\n        return this.enqueue(providerId, async () => {\n            this.credentials.delete(providerId);\n        }, options);\n    }\n}\n//# sourceMappingURL=credential-store.js.map","// @ts-nocheck — vendored Pi source (pi-ai utils/diagnostics.js @0.84.1, MIT, see ./PI-LICENSE); unchanged.\nexport function formatThrownValue(value) {\n    if (value instanceof Error)\n        return value.message || value.name;\n    if (typeof value === \"string\")\n        return value;\n    return String(value);\n}\nexport function extractDiagnosticError(error) {\n    if (!(error instanceof Error))\n        return { name: \"ThrownValue\", message: formatThrownValue(error) };\n    const code = error.code;\n    return {\n        name: error.name || undefined,\n        message: error.message || error.name,\n        stack: error.stack,\n        code: typeof code === \"string\" || typeof code === \"number\" ? code : undefined,\n    };\n}\nexport function createAssistantMessageDiagnostic(type, error, details) {\n    return { type, timestamp: Date.now(), error: extractDiagnosticError(error), details };\n}\nexport function appendAssistantMessageDiagnostic(message, diagnostic) {\n    message.diagnostics = [...(message.diagnostics ?? []), diagnostic];\n}\n//# sourceMappingURL=diagnostics.js.map","// @ts-nocheck — vendored Pi source (pi-ai auth/resolve.js @0.84.1, MIT, see ./PI-LICENSE); imports remapped, logic unchanged\n// (double-checked-lock OAuth refresh with persistence, no silent env fallback).\nimport { operationSignal, raceWithAbortSignal } from './pi-ai-abort.js';\nimport { formatThrownValue } from './pi-ai-diagnostics.js';\nexport class ModelsError extends Error {\n    code;\n    constructor(code, message, options) {\n        super(withCauseDetail(message, options?.cause), options);\n        this.name = \"ModelsError\";\n        this.code = code;\n    }\n}\n/** Callers surface `error.message` only, so keep the underlying reason in it. */\nfunction withCauseDetail(message, cause) {\n    if (cause === undefined || cause === null)\n        return message;\n    const detail = formatThrownValue(cause).trim();\n    if (!detail || message.includes(detail))\n        return message;\n    return `${message}: ${detail}`;\n}\n/**\n * Auth resolution shared by the `Models` and `ImagesModels` collections.\n * A stored credential owns the provider: ambient/env is consulted only when\n * nothing is stored. No silent env fallback after a failed refresh or for a\n * credential type without a matching handler.\n */\nexport function resolveProviderAuth(provider, credentials, authContext, overrides) {\n    const signal = operationSignal(overrides?.signal);\n    return raceWithAbortSignal(resolveProviderAuthWithSignal(provider, credentials, authContext, overrides, signal), signal);\n}\nasync function resolveProviderAuthWithSignal(provider, credentials, authContext, overrides, signal) {\n    signal.throwIfAborted();\n    const requestAuthContext = overrides?.env ? overlayEnvAuthContext(authContext, overrides.env) : authContext;\n    if (overrides?.apiKey !== undefined && provider.auth.apiKey) {\n        return resolveApiKey(requestAuthContext, provider.auth.apiKey, provider.id, {\n            type: \"api_key\",\n            key: overrides.apiKey,\n            env: overrides.env,\n        }, signal);\n    }\n    const stored = await readCredential(credentials, provider.id, signal);\n    if (stored) {\n        if (stored.type === \"oauth\" && provider.auth.oauth) {\n            return resolveStoredOAuth(credentials, provider.id, provider.auth.oauth, stored, signal, overrides?.minOAuthValidityMs);\n        }\n        if (stored.type === \"api_key\" && provider.auth.apiKey) {\n            const credential = overrides?.env ? { ...stored, env: { ...stored.env, ...overrides.env } } : stored;\n            return resolveApiKey(requestAuthContext, provider.auth.apiKey, provider.id, credential, signal);\n        }\n        return undefined;\n    }\n    // Ambient (env vars, AWS profiles, ADC files).\n    return provider.auth.apiKey\n        ? resolveApiKey(requestAuthContext, provider.auth.apiKey, provider.id, undefined, signal)\n        : undefined;\n}\nfunction overlayEnvAuthContext(base, env) {\n    return {\n        env: async (name) => env[name] || (await base.env(name)),\n        fileExists: (path) => base.fileExists(path),\n    };\n}\nconst DEFAULT_OAUTH_MINIMUM_VALIDITY_MS = 5 * 60 * 1000;\nconst DEFAULT_OAUTH_REFRESH_TIMEOUT_MS = 15_000;\n/**\n * OAuth resolution with double-checked locking: tokens with less than five\n * minutes remaining lock, re-check expiry under the lock, refresh once\n * globally, and persist the rotated credential before release.\n */\nasync function resolveStoredOAuth(credentials, providerId, oauth, stored, signal, minOAuthValidityMs) {\n    const minimumValidityMs = Math.max(DEFAULT_OAUTH_MINIMUM_VALIDITY_MS, minOAuthValidityMs ?? 0);\n    const expiresSoon = (credential) => Date.now() + minimumValidityMs >= credential.expires;\n    let credential = stored;\n    if (expiresSoon(credential)) {\n        // Optimistic check said expired; the authoritative check runs under the lock.\n        let post;\n        try {\n            post = await credentials.modify(providerId, async (current) => {\n                if (current?.type !== \"oauth\")\n                    return undefined; // logged out meanwhile\n                if (!expiresSoon(current))\n                    return undefined; // another process/request refreshed\n                try {\n                    const refreshSignal = AbortSignal.any([\n                        signal,\n                        AbortSignal.timeout(DEFAULT_OAUTH_REFRESH_TIMEOUT_MS),\n                    ]);\n                    return await oauth.refresh(current, refreshSignal);\n                }\n                catch (error) {\n                    throw new ModelsError(\"oauth\", `OAuth refresh failed for ${providerId}`, { cause: error });\n                }\n            }, { signal });\n        }\n        catch (error) {\n            if (error instanceof ModelsError)\n                throw error;\n            throw new ModelsError(\"auth\", `Credential store modify failed for ${providerId}`, { cause: error });\n        }\n        if (post?.type !== \"oauth\")\n            return undefined; // logged out meanwhile\n        credential = post;\n        // The normal five-minute window triggers a refresh but does not impose a\n        // provider contract. Explicit callers (such as bearer-token export) do\n        // require the requested minimum after the refresh.\n        if (minOAuthValidityMs !== undefined && expiresSoon(credential)) {\n            throw new ModelsError(\"oauth\", `OAuth refresh returned a token that expires too soon for ${providerId}`);\n        }\n    }\n    try {\n        return { auth: await oauth.toAuth(credential), source: \"OAuth\" };\n    }\n    catch (error) {\n        throw new ModelsError(\"oauth\", `OAuth auth derivation failed for ${providerId}`, { cause: error });\n    }\n}\nasync function resolveApiKey(authContext, apiKey, providerId, credential, signal) {\n    try {\n        return await apiKey.resolve({ ctx: authContext, credential, signal });\n    }\n    catch (error) {\n        throw new ModelsError(\"auth\", `API key auth failed for provider ${providerId}`, { cause: error });\n    }\n}\nasync function readCredential(credentials, providerId, signal) {\n    try {\n        return await credentials.read(providerId, { signal });\n    }\n    catch (error) {\n        throw new ModelsError(\"auth\", `Credential store read failed for ${providerId}`, { cause: error });\n    }\n}\n//# sourceMappingURL=resolve.js.map","// @ts-nocheck — vendored Pi source excerpt (pi-coding-agent core/provider-composer.js adaptOAuth @0.84.1, MIT, see ./PI-LICENSE); logic unchanged.\n// The official two-generation adapter: extension oauth callbacks (onAuth/onDeviceCode/onPrompt/onSelect)\n// over the pi-ai interaction surface (prompt/notify/signal), plus refresh and toAuth->getApiKey.\nexport function adaptOAuth(config) {\n    return {\n        name: config.name,\n        isSubscription: config.isSubscription,\n        login: async (callbacks) => {\n            const credential = await config.login({\n                onAuth: (info) => callbacks.notify({ type: \"auth_url\", ...info }),\n                onDeviceCode: (info) => callbacks.notify({ type: \"device_code\", ...info }),\n                onPrompt: (prompt) => callbacks.prompt({ type: \"text\", ...prompt }),\n                onProgress: (message) => callbacks.notify({ type: \"progress\", message }),\n                onManualCodeInput: () => callbacks.prompt({ type: \"manual_code\", message: \"Paste the authorization code\" }),\n                onSelect: (prompt) => callbacks.prompt({ type: \"select\", ...prompt }),\n                signal: callbacks.signal,\n            });\n            return { ...credential, type: \"oauth\" };\n        },\n        refresh: async (credential, signal) => ({ ...(await config.refreshToken(credential, signal)), type: \"oauth\" }),\n        toAuth: async (credential) => ({ apiKey: config.getApiKey(credential) }),\n    };\n}\n","import { existsSync, readFileSync } from 'node:fs'\nimport { mkdir, rename, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport { InMemoryCredentialStore } from './compat/vendor/pi-ai-credential-store.js'\nimport { resolveProviderAuth } from './compat/vendor/pi-ai-auth-resolve.js'\nimport { adaptOAuth } from './compat/vendor/pi-oauth-adapt.js'\n\ntype UnknownRecord = Record<string, unknown>\n\n// The interactive OAuth host seam, four layers with one owner each:\n//   L1 protocol   — the package's own oauth.login/refreshToken/getApiKey code\n//                   runs verbatim (device-code, auth-code, rotation). The\n//                   bridge implements zero protocol.\n//   L2 interaction— Pi's official adaptOAuth (vendored) turns the package's\n//                   callbacks into prompt/notify events; this file routes\n//                   those onto the Pi ui surface, which pi2dsh already maps\n//                   to DSH userQuestions with real waits.\n//   L3 credentials— Pi's auth.json contract: one file keyed by provider id,\n//                   0600, atomic replace, per-provider serialized writes\n//                   (the vendored InMemoryCredentialStore chain), refresh via\n//                   Pi's vendored double-checked-lock resolver.\n//   L4 routing    — resolveOAuthApiKey yields the request key for dsh-llm's\n//                   one-shot credential seam; tokens never enter DSH settings.\n\n// Reference convention shared with the optional credentials provider:\n// PI2DSH_OAUTH_<PROVIDER_ID> (upper-cased, `-` → `_`). Lives HERE — not in\n// credentials-oauth.ts — because that module imports @deepseek-ai/dsh-credentials\n// (an optional peer a clean profile does not install), and the engine's main\n// runtime chunk must never share a static import graph with it.\nconst OAUTH_REF_PREFIX = 'PI2DSH_OAUTH_'\n\nexport function oauthCredentialRef(providerId: string): string {\n  return `${OAUTH_REF_PREFIX}${providerId.toUpperCase().replaceAll('-', '_')}`\n}\n\nexport function providerIdOfOAuthRef(ref: string): string | undefined {\n  if (!ref.startsWith(OAUTH_REF_PREFIX)) return undefined\n  return ref.slice(OAUTH_REF_PREFIX.length).toLowerCase().replaceAll('_', '-')\n}\n\nexport class FileCredentialStore extends InMemoryCredentialStore {\n  readonly #path: string\n\n  constructor(path: string) {\n    super()\n    this.#path = path\n    try {\n      const data = JSON.parse(readFileSync(path, 'utf8')) as Record<string, UnknownRecord>\n      for (const [providerId, credential] of Object.entries(data)) {\n        ;(this as unknown as { credentials: Map<string, unknown> }).credentials.set(providerId, credential)\n      }\n    } catch {\n      // Missing or unreadable auth.json starts empty, exactly like Pi.\n    }\n  }\n\n  get path(): string {\n    return this.#path\n  }\n\n  async #persist(): Promise<void> {\n    const credentials = (this as unknown as { credentials: Map<string, unknown> }).credentials\n    const data = Object.fromEntries(credentials)\n    await mkdir(dirname(this.#path), { recursive: true })\n    // Atomic replace so a crash mid-write never truncates the store; 0600 so\n    // tokens stay owner-readable only. Same contract Pi's file store keeps.\n    const temp = `${this.#path}.tmp-${process.pid}-${Math.floor(Math.random() * 1e9).toString(36)}`\n    await writeFile(temp, `${JSON.stringify(data, null, 2)}\\n`, { mode: 0o600 })\n    await rename(temp, this.#path)\n  }\n\n  override modify(providerId: string, fn: (current: unknown) => unknown, options?: UnknownRecord): Promise<unknown> {\n    // The vendored per-provider chain already serializes writers; persisting\n    // inside the chained task keeps disk order identical to memory order.\n    return super.modify(providerId, async (current: unknown) => {\n      const next = await fn(current)\n      if (next !== undefined) {\n        const credentials = (this as unknown as { credentials: Map<string, unknown> }).credentials\n        credentials.set(providerId, next)\n        await this.#persist()\n      }\n      return next\n    }, options)\n  }\n\n  override delete(providerId: string, options?: UnknownRecord): Promise<void> {\n    return super.delete(providerId, options).then(() => this.#persist()) as Promise<void>\n  }\n}\n\n/**\n * One signal that fires when EITHER input does.\n *\n * A question on screen has two reasons to close: the flow's own race (the\n * browser callback beating the paste box) and the whole login being called off.\n * @param ambient - the login's signal, live for the whole flow.\n * @param perCall - the flow's signal for this one question, when it sent one.\n * @returns the joined signal, or whichever one exists.\n */\nexport function joinSignals(ambient: AbortSignal | undefined, perCall: unknown): AbortSignal | undefined {\n  if (!(perCall instanceof AbortSignal)) return ambient\n  if (ambient === undefined) return perCall\n  const joined = new AbortController()\n  const stop = () => joined.abort()\n  if (ambient.aborted || perCall.aborted) joined.abort()\n  else {\n    ambient.addEventListener('abort', stop, { once: true })\n    perCall.addEventListener('abort', stop, { once: true })\n  }\n  return joined.signal\n}\n\nexport interface OAuthUiSurface {\n  /**\n   * @param signal cancels THIS question when another path in the flow answers\n   *   first — the browser callback beating the paste box. Optional because\n   *   Pi's own ui.input takes two arguments; the bridge's accepts a third.\n   */\n  input(title: unknown, placeholder?: unknown, signal?: AbortSignal): Promise<string | undefined>\n  select(title: unknown, options: unknown[], signal?: AbortSignal): Promise<string | undefined>\n  notify(message: unknown): void\n  /**\n   * Keep a device-code flow visible while the package polls in the background.\n   *\n   * Unlike auth-code flows, device-code flows normally do not issue a later\n   * prompt. A command notice therefore arrives only after the code has expired.\n   * Hosts with a live question surface should implement this optional seam;\n   * older/headless hosts still receive the plain notification below.\n   */\n  deviceCode?(title: unknown, detail: unknown, signal?: AbortSignal): Promise<void>\n}\n\ninterface OAuthPromptEvent {\n  type: 'text' | 'manual_code' | 'select'\n  message: string\n  placeholder?: string\n  options?: Array<{ id: string, label: string }>\n  /** Cancels THIS question when another path in the flow answers first. */\n  signal?: AbortSignal\n}\n\ninterface OAuthNotifyEvent {\n  type: 'auth_url' | 'device_code' | 'progress'\n  url?: string\n  instructions?: string\n  userCode?: string\n  verificationUri?: string\n  message?: string\n  /** How long the device code stays valid. Every device-code flow sends it. */\n  expiresInSeconds?: number\n  /** How often the flow polls; sent alongside the expiry. */\n  intervalSeconds?: number\n}\n\n// The pi-ai interaction surface ({prompt, notify, signal}) over the Pi ui\n// surface pi2dsh already maps to DSH userQuestions.\n/**\n * Hand a URL to the host's browser opener, when the host gave one.\n *\n * Opening a window is the HOST's action, not the translation layer's, so the\n * opener is injected rather than reached for. Wiring it in here meant every\n * caller opened a real browser tab — including the test suite, which spawned a\n * tab per assertion on the developer's own machine.\n * @param open - the host's opener, absent when the host does not open windows.\n * @param url - the address the flow announced, when it announced one.\n */\nfunction openIfPossible(open: ((url: string) => void) | undefined, url: string | undefined): void {\n  if (open === undefined || typeof url !== 'string' || !/^https?:\\/\\//u.test(url)) return\n  try {\n    open(url)\n  } catch {\n    // Best effort by design: the URL is in the prompt either way, and a host\n    // with no desktop session (a container, a remote box) must still be able to\n    // finish the login by pasting the code.\n  }\n}\n\nexport function oauthInteraction(\n  ui: OAuthUiSurface,\n  signal?: AbortSignal,\n  shorten?: (url: string) => string | undefined,\n  open?: (url: string) => void,\n  cancel?: () => void,\n): {\n  prompt(prompt: OAuthPromptEvent): Promise<string | undefined>\n  notify(event: OAuthNotifyEvent): void\n  signal: AbortSignal\n} {\n  // Pi hosts always hand flows a live signal; flows attach abort listeners\n  // unconditionally, so an absent caller signal becomes a never-aborting one.\n  const effectiveSignal = signal ?? new AbortController().signal\n  // Where the user has to GO to authorize, held until the next prompt.\n  //\n  // The flow announces the authorization URL through notify() and then blocks\n  // on prompt() for the code. A notice is a command notice on DSH: it reaches\n  // the user when the command ENDS — and this command cannot end until the user\n  // acts on the notice. So the address was delivered after it was needed, and\n  // the dialog on screen showed only the redirect URI (localhost/auth/callback),\n  // which does nothing when clicked. Carrying it into the prompt puts it where\n  // the user is already looking.\n  let pending: string | undefined\n  /**\n   * Hand the announced address to the prompt as its DETAIL, not its title.\n   *\n   * An authorization URL is 400 characters of query string. Prepending it to\n   * the question turned the dialog into a wall of wrapped text with the actual\n   * question buried underneath; `detail` is the slot DSH renders supporting\n   * text in.\n   * @param placeholder - the flow's own placeholder, kept when it supplied one.\n   */\n  const takePending = (placeholder: unknown): string | undefined => {\n    const carried = pending\n    pending = undefined\n    // A carried address takes the slot alone. Pi's placeholder is greyed hint\n    // text INSIDE its input box; DSH's dialog has no such slot, so it lands in\n    // the same body text — and codex's placeholder is the redirect URI\n    // (localhost:1455/auth/callback), which GFM autolinks into a second,\n    // clickable, useless address sitting right under the real one. That is the\n    // trap the user already fell into. Where nothing was announced it is still\n    // the only hint there is, so it stays.\n    if (carried !== undefined) return carried\n    return placeholder === undefined ? undefined : String(placeholder)\n  }\n  return {\n    signal: effectiveSignal,\n    async prompt(prompt) {\n      if (prompt.type === 'select') {\n        const options = prompt.options ?? []\n        pending = undefined\n        const picked = await ui.select(prompt.message, options.map(option => option.label), effectiveSignal)\n        return options.find(option => option.label === picked)?.id ?? picked\n      }\n      // BOTH signals close this box: the flow's own (another path won the race\n      // — the local callback got the code) and the login's (it was called off).\n      //\n      // The second one is not optional. Cancelling a flow only tells the flow;\n      // the question is the HOST's, and Pi's host takes its dialog down, which\n      // is how the flow's `await manualPromise` gets to settle. Pi's anthropic\n      // flow deadlocks without that: cancelling makes its callback wait return\n      // nothing, and it then waits on the paste box forever, because the abort\n      // that would close the box sits in a `finally` this wait never reaches.\n      return ui.input(prompt.message, takePending(prompt.placeholder), joinSignals(effectiveSignal, prompt.signal))\n    },\n    notify(event) {\n      if (event.type === 'auth_url') {\n        // An authorize URL is 400 characters of query string. Pasted whole it\n        // filled the dialog with wrapped text and gave the user nothing to\n        // click. The dialog's detail slot is rendered as markdown, so the\n        // address goes in as a LINK — one short clickable line, opened in a new\n        // tab by the host's own renderer. The short redirect on this app's\n        // origin is what makes it copyable too (a notice is plain text).\n        const shown = (event.url === undefined ? undefined : shorten?.(event.url)) ?? event.url\n        const tail = event.instructions === undefined ? '' : `\\n\\n${event.instructions}`\n        pending = `[Open the login page](${shown})${tail}`\n        ui.notify(`Open this URL to authorize: ${shown}${tail}`)\n        // Open it, the way Pi's own login dialog does. The flows themselves\n        // print \"A browser window should open\" — that sentence is Pi telling\n        // the user what the HOST is about to do, and a host that does not do it\n        // leaves a wrapped, unclickable URL and no way to authorize.\n        openIfPossible(open, event.url)\n      } else if (event.type === 'device_code') {\n        // A device code EXPIRES. Dropping that left the user staring at a code\n        // with no idea it was on a clock — every device-code flow sends the\n        // window, and Pi's own host shows it.\n        const window = typeof event.expiresInSeconds === 'number' && event.expiresInSeconds > 0\n          ? ` (valid for ${Math.round(event.expiresInSeconds / 60)} min)`\n          : ''\n        // Same as above: a clickable line in the dialog, plain text in the\n        // notice. The code stays as code so it survives the markdown pass.\n        const detail = `[Open the device login page](${event.verificationUri}) and enter code \\`${event.userCode}\\`${window}`\n        pending = detail\n        ui.notify(`Visit ${event.verificationUri} and enter code ${event.userCode}${window}`)\n        // A device flow polls without asking a follow-up question. Put a live\n        // host dialog on screen NOW; otherwise the only visible artifact is a\n        // command notice released after the command ends, when the code is no\n        // longer useful. Resolving this dialog means the user cancelled it.\n        // Successful/failed login aborts the signal first and merely closes it.\n        if (ui.deviceCode !== undefined) {\n          pending = undefined\n          void ui.deviceCode('Complete login in your browser', detail, effectiveSignal).then(\n            () => { if (!effectiveSignal.aborted) cancel?.() },\n            () => undefined,\n          )\n        }\n        openIfPossible(open, event.verificationUri)\n      } else if (event.message !== undefined) {\n        ui.notify(event.message)\n      }\n    },\n  }\n}\n\nfunction oauthConfigOf(providerConfig: UnknownRecord | undefined): UnknownRecord | undefined {\n  // Extension-generation configs carry oauth at the top level; pi-ai\n  // createProvider() objects carry it under auth.oauth. Pi accepts both.\n  const oauth = providerConfig?.oauth\n    ?? (providerConfig?.auth as UnknownRecord | undefined)?.oauth\n  return typeof oauth === 'object' && oauth !== null && typeof (oauth as UnknownRecord).login === 'function'\n    ? oauth as UnknownRecord\n    : undefined\n}\n\n// Pi accepts both oauth generations: pi-ai native flows carry toAuth and take\n// the interaction surface directly; extension configs carry getApiKey and go\n// through Pi's adaptOAuth (vendored). Same acceptance here.\nfunction oauthAdapterOf(oauthConfig: UnknownRecord): {\n  login(interaction: unknown): Promise<UnknownRecord>\n  refresh(credential: unknown, signal?: AbortSignal): Promise<UnknownRecord>\n  toAuth(credential: unknown): Promise<UnknownRecord>\n} {\n  if (typeof oauthConfig.toAuth === 'function') {\n    return oauthConfig as never\n  }\n  return adaptOAuth(oauthConfig) as never\n}\n\nexport function providerSupportsOAuth(providerConfig: UnknownRecord | undefined): boolean {\n  return oauthConfigOf(providerConfig) !== undefined\n}\n\n// Pi models.login semantics: find the provider's oauth surface, run the\n// package's own login through the vendored adapter, persist through the\n// store's serialized modify.\nexport async function loginPiProvider(options: {\n  providerId: string\n  providerName?: string\n  providerConfig: UnknownRecord\n  store: FileCredentialStore\n  ui: OAuthUiSurface\n  signal?: AbortSignal\n  /** Turns a long authorize URL into a short one the user can actually click. */\n  shorten?: (url: string) => string | undefined\n  /** The host's browser opener. Absent = this host opens nothing. */\n  open?: (url: string) => void\n}): Promise<UnknownRecord> {\n  const oauthConfig = oauthConfigOf(options.providerConfig)\n  if (oauthConfig === undefined) {\n    throw new Error(`${options.providerName ?? options.providerId} does not support oauth login`)\n  }\n  const adapter = oauthAdapterOf(oauthConfig)\n  // The flow's own signal, so a question still on screen when the login ends\n  // gets cancelled. The browser half of an OAuth login finishes at the local\n  // callback, not at the paste box — leaving that box open after the flow has\n  // resolved (or failed, as a region-blocked token exchange does) strands the\n  // user in front of a dialog that can no longer do anything.\n  const done = new AbortController()\n  if (options.signal !== undefined) {\n    if (options.signal.aborted) done.abort()\n    else options.signal.addEventListener('abort', () => done.abort(), { once: true })\n  }\n  try {\n    const credential = await adapter.login(oauthInteraction(\n      options.ui,\n      done.signal,\n      options.shorten,\n      options.open,\n      () => done.abort(),\n    ))\n    await options.store.modify(options.providerId, async () => credential)\n    return credential\n  } finally {\n    done.abort()\n  }\n}\n\n// Pi's resolveProviderAuth over the stored credential: five-minute expiry\n// window, double-checked-lock refresh through the package's own refreshToken,\n// rotated credential persisted before release, key derived by the package's\n// own getApiKey. Returns undefined when nothing is stored.\nexport async function resolveOAuthApiKey(options: {\n  providerId: string\n  providerName?: string\n  providerConfig: UnknownRecord\n  store: FileCredentialStore\n  signal?: AbortSignal\n}): Promise<string | undefined> {\n  const oauthConfig = oauthConfigOf(options.providerConfig)\n  if (oauthConfig === undefined) return undefined\n  const provider = {\n    id: options.providerId,\n    name: options.providerName ?? options.providerId,\n    auth: { oauth: oauthAdapterOf(oauthConfig) },\n  }\n  const resolved = await resolveProviderAuth(\n    provider,\n    options.store,\n    { env: async () => undefined },\n    options.signal !== undefined ? { signal: options.signal } : undefined,\n  ) as { auth?: { apiKey?: string } } | undefined\n  return resolved?.auth?.apiKey\n}\n\nexport async function storedOAuthCredential(store: FileCredentialStore, providerId: string): Promise<UnknownRecord | undefined> {\n  const stored = await store.read(providerId, undefined) as UnknownRecord | undefined\n  return stored?.type === 'oauth' ? stored : undefined\n}\n\n// Pi's FULL getProviderAuth precedence over the vendored resolver — stored\n// OAuth (double-checked-lock refresh), then stored api_key, then the\n// provider's own auth.apiKey ambient resolution (its resolve() reads env vars\n// and probes credential files through the auth context). The package's\n// resolve code runs verbatim; the bridge supplies only the context.\nexport async function resolvePiProviderAuth(options: {\n  providerId: string\n  providerName?: string\n  providerConfig: UnknownRecord\n  store: FileCredentialStore\n  signal?: AbortSignal\n}): Promise<{ auth?: UnknownRecord, source?: string } | undefined> {\n  const oauthConfig = oauthConfigOf(options.providerConfig)\n  const declaredApiKey = (options.providerConfig.auth as UnknownRecord | undefined)?.apiKey\n  if (oauthConfig === undefined && declaredApiKey === undefined) return undefined\n  const auth: UnknownRecord = {}\n  if (oauthConfig !== undefined) auth.oauth = oauthAdapterOf(oauthConfig)\n  if (declaredApiKey !== undefined) auth.apiKey = declaredApiKey\n  const provider = { id: options.providerId, name: options.providerName ?? options.providerId, auth }\n  return await resolveProviderAuth(\n    provider,\n    options.store,\n    {\n      env: async (name: string) => process.env[name],\n      fileExists: async (path: string) => existsSync(path),\n    },\n    options.signal !== undefined ? { signal: options.signal } : undefined,\n  ) as { auth?: UnknownRecord, source?: string } | undefined\n}\n"],"mappings":"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"}