pi2dsh 0.13.2 → 0.13.3
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.
- package/README.md +22 -19
- package/README.zh.md +18 -15
- package/dist/{analyzer-CJFwQlSG.mjs → analyzer-DBtUYKI1.mjs} +2 -2
- package/dist/{analyzer-CJFwQlSG.mjs.map → analyzer-DBtUYKI1.mjs.map} +1 -1
- package/dist/anthropic-messages-CaYTgvLF.mjs +6436 -0
- package/dist/anthropic-messages-CaYTgvLF.mjs.map +1 -0
- package/dist/azure-openai-responses-HKWkzl2m.mjs +208 -0
- package/dist/azure-openai-responses-HKWkzl2m.mjs.map +1 -0
- package/dist/cli.mjs +3 -2
- package/dist/cli.mjs.map +1 -1
- package/dist/compat/pi-ai.d.mts +3 -2636
- package/dist/compat/pi-ai.mjs +3 -2
- package/dist/compat/pi-coding-agent.d.mts +2 -2
- package/dist/compat/pi-coding-agent.mjs +2 -2
- package/dist/{mcp-config-_idn-pzI.mjs → compatibility-Bz6ZXA7F.mjs} +8 -185
- package/dist/compatibility-Bz6ZXA7F.mjs.map +1 -0
- package/dist/completionchunk-Dhk56lZl.mjs +5212 -0
- package/dist/completionchunk-Dhk56lZl.mjs.map +1 -0
- package/dist/{credentials-oauth-Txs6oew8.mjs → credentials-oauth-CAohSLcB.mjs} +3 -3
- package/dist/{credentials-oauth-Txs6oew8.mjs.map → credentials-oauth-CAohSLcB.mjs.map} +1 -1
- package/dist/credentials-oauth.mjs +1 -1
- package/dist/deferred-tools-BD4g5QUx.mjs +32 -0
- package/dist/deferred-tools-BD4g5QUx.mjs.map +1 -0
- package/dist/diagnostics-BqYkodgB.mjs +35 -0
- package/dist/diagnostics-BqYkodgB.mjs.map +1 -0
- package/dist/dist-QBBA-dL_.mjs +1246 -0
- package/dist/dist-QBBA-dL_.mjs.map +1 -0
- package/dist/error-body-DKA3lknR.mjs +104 -0
- package/dist/error-body-DKA3lknR.mjs.map +1 -0
- package/dist/event-stream-QxN1yvIF.mjs +64 -0
- package/dist/event-stream-QxN1yvIF.mjs.map +1 -0
- package/dist/from-BCscBQ9P.mjs +3856 -0
- package/dist/from-BCscBQ9P.mjs.map +1 -0
- package/dist/github-copilot-headers-CZo2QHrt.mjs +25 -0
- package/dist/github-copilot-headers-CZo2QHrt.mjs.map +1 -0
- package/dist/google-generative-ai-2gCFYp-t.mjs +356 -0
- package/dist/google-generative-ai-2gCFYp-t.mjs.map +1 -0
- package/dist/google-shared-75IdVyrx.mjs +29041 -0
- package/dist/google-shared-75IdVyrx.mjs.map +1 -0
- package/dist/google-vertex-Bhyo4z2i.mjs +400 -0
- package/dist/google-vertex-Bhyo4z2i.mjs.map +1 -0
- package/dist/hash-Dbggamac.mjs +19 -0
- package/dist/hash-Dbggamac.mjs.map +1 -0
- package/dist/headers-CPzZhJQn.mjs +17 -0
- package/dist/headers-CPzZhJQn.mjs.map +1 -0
- package/dist/host.d.mts +12 -2
- package/dist/host.d.mts.map +1 -1
- package/dist/host.mjs +43 -5
- package/dist/host.mjs.map +1 -1
- package/dist/index.d.mts +5 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +40 -16
- package/dist/index.mjs.map +1 -1
- package/dist/json-parse-CZ0U0sj_.mjs +384 -0
- package/dist/json-parse-CZ0U0sj_.mjs.map +1 -0
- package/dist/mcp-config-jmzbgdHa.mjs +181 -0
- package/dist/mcp-config-jmzbgdHa.mjs.map +1 -0
- package/dist/mistral-conversations-DJyeTo8C.mjs +36921 -0
- package/dist/mistral-conversations-DJyeTo8C.mjs.map +1 -0
- package/dist/multipart-parser-SRcGkVuX.mjs +301 -0
- package/dist/multipart-parser-SRcGkVuX.mjs.map +1 -0
- package/dist/{pi-ai-D7PqVeWs.mjs → openai-DkzRh5_G.mjs} +78 -5063
- package/dist/openai-DkzRh5_G.mjs.map +1 -0
- package/dist/openai-codex-responses-DedxQjNG.mjs +1220 -0
- package/dist/openai-codex-responses-DedxQjNG.mjs.map +1 -0
- package/dist/openai-completions-DrjrWRdX.mjs +945 -0
- package/dist/openai-completions-DrjrWRdX.mjs.map +1 -0
- package/dist/openai-prompt-cache-BDWtZRKh.mjs +11 -0
- package/dist/openai-prompt-cache-BDWtZRKh.mjs.map +1 -0
- package/dist/openai-responses-BRdGpBX6.mjs +251 -0
- package/dist/openai-responses-BRdGpBX6.mjs.map +1 -0
- package/dist/openai-responses-shared-BmnSvdKL.mjs +570 -0
- package/dist/openai-responses-shared-BmnSvdKL.mjs.map +1 -0
- package/dist/otel-CBhmS-NR.mjs +24935 -0
- package/dist/otel-CBhmS-NR.mjs.map +1 -0
- package/dist/pi-ai-CfokFhIL.d.mts +2673 -0
- package/dist/pi-ai-CfokFhIL.d.mts.map +1 -0
- package/dist/pi-ai-Dh7HUxbt.mjs +3239 -0
- package/dist/pi-ai-Dh7HUxbt.mjs.map +1 -0
- package/dist/{pi-coding-agent-B0PT23gE.d.mts → pi-coding-agent-69yY0ke-.d.mts} +4 -2
- package/dist/{pi-coding-agent-B0PT23gE.d.mts.map → pi-coding-agent-69yY0ke-.d.mts.map} +1 -1
- package/dist/{pi-coding-agent-BVZu0dHG.mjs → pi-coding-agent-Cvez0jkF.mjs} +0 -0
- package/dist/{pi-coding-agent-BVZu0dHG.mjs.map → pi-coding-agent-Cvez0jkF.mjs.map} +1 -1
- package/dist/pi-messages-D61G2tgs.mjs +307 -0
- package/dist/pi-messages-D61G2tgs.mjs.map +1 -0
- package/dist/provider-env-C72pF4vP.mjs +40 -0
- package/dist/provider-env-C72pF4vP.mjs.map +1 -0
- package/dist/provider-retry-Cw6YJ4cr.mjs +80 -0
- package/dist/provider-retry-Cw6YJ4cr.mjs.map +1 -0
- package/dist/rolldown-runtime-CTfmNlz1.mjs +44 -0
- package/dist/{runtime-DEjs_Qlf.mjs → runtime-Dd2KhoX-.mjs} +659 -125
- package/dist/runtime-Dd2KhoX-.mjs.map +1 -0
- package/dist/runtime.d.mts +135 -26
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +1 -1
- package/dist/simple-options-B_GO8FDE.mjs +456 -0
- package/dist/simple-options-B_GO8FDE.mjs.map +1 -0
- package/dist/src-DlTagfW5.mjs +1186 -0
- package/dist/src-DlTagfW5.mjs.map +1 -0
- package/dist/{types-7IWJPPvS.d.mts → types-B9VBF8le.d.mts} +2 -9
- package/dist/{types-7IWJPPvS.d.mts.map → types-B9VBF8le.d.mts.map} +1 -1
- package/package.json +2 -2
- package/dist/compat/pi-ai.d.mts.map +0 -1
- package/dist/mcp-config-_idn-pzI.mjs.map +0 -1
- package/dist/pi-ai-D7PqVeWs.mjs.map +0 -1
- package/dist/runtime-DEjs_Qlf.mjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
|
-
import
|
|
3
|
-
import "./pi-coding-agent-BVZu0dHG.mjs";
|
|
2
|
+
import "./pi-coding-agent-Cvez0jkF.mjs";
|
|
4
3
|
import { t as getAgentDir } from "./pi-config-shim-CZ1wFzqM.mjs";
|
|
4
|
+
import { c as builtinProviders } from "./pi-ai-Dh7HUxbt.mjs";
|
|
5
5
|
import { mkdir, rename, writeFile } from "node:fs/promises";
|
|
6
6
|
import { existsSync, readFileSync } from "node:fs";
|
|
7
7
|
import { dirname, join } from "node:path";
|
|
@@ -538,4 +538,4 @@ function apply(ctx, config = {}) {
|
|
|
538
538
|
//#endregion
|
|
539
539
|
export { FileCredentialStore as a, providerSupportsOAuth as c, oauthCredentialRef as i, resolvePiProviderAuth as l, apply as n, joinSignals as o, name as r, loginPiProvider as s, PiOAuthCredentialProvider as t, storedOAuthCredential as u };
|
|
540
540
|
|
|
541
|
-
//# sourceMappingURL=credentials-oauth-
|
|
541
|
+
//# sourceMappingURL=credentials-oauth-CAohSLcB.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentials-oauth-Txs6oew8.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","../src/credentials-oauth.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\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","import { join } from 'node:path'\nimport type { Context } from '@deepseek-ai/cordis'\nimport { CredentialProvider, type CredentialInfo, type CredentialRef, type ResolvedCredential } from '@deepseek-ai/dsh-credentials'\nimport { FileCredentialStore, providerSupportsOAuth, resolveOAuthApiKey, storedOAuthCredential } from './oauth-bridge.js'\nimport { builtinProviders } from './compat/pi-ai.js'\nimport { getAgentDir } from './compat/pi-coding-agent.js'\n\ntype UnknownRecord = Record<string, unknown>\n\n// L4 of the OAuth host seam: a standard dsh-credentials provider that serves\n// Pi OAuth tokens to DSH's native LLM request path. A route configured as\n// `apiKeyEnv: PI2DSH_OAUTH_OPENAI_CODEX` resolves per request through this\n// provider — Pi's double-checked-lock refresh runs on every resolution, so a\n// rotated token reaches the next model call with no restart, exactly the\n// per-operation semantics the credentials seam demands. Every other reference\n// falls through to the process environment, so one provider instance serves a\n// whole composition.\n//\n// Reference convention: PI2DSH_OAUTH_<PROVIDER_ID> where the provider id is\n// upper-cased with `-` as `_` (openai-codex → PI2DSH_OAUTH_OPENAI_CODEX).\n\nconst OAUTH_REF_PREFIX = 'PI2DSH_OAUTH_'\n\nexport function oauthCredentialRef(providerId: string): string {\n return `${OAUTH_REF_PREFIX}${providerId.toUpperCase().replaceAll('-', '_')}`\n}\n\nfunction providerIdOfRef(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 interface PiOAuthCredentialProviderOptions {\n /** Path to the Pi-format auth.json; defaults to `$agentDir/auth.json`. */\n authPath?: string\n /** Additional provider configs (id → config with an oauth block), e.g. from packages that registered providers. */\n providers?: ReadonlyMap<string, UnknownRecord>\n}\n\nexport class PiOAuthCredentialProvider extends CredentialProvider {\n private readonly oauthStore: FileCredentialStore\n private readonly extraProviders: ReadonlyMap<string, UnknownRecord>\n\n constructor(ctx: Context, options: PiOAuthCredentialProviderOptions = {}) {\n super(ctx)\n this.oauthStore = new FileCredentialStore(options.authPath ?? join(getAgentDir(), 'auth.json'))\n this.extraProviders = options.providers ?? new Map()\n }\n\n private oauthConfigFor(providerId: string): UnknownRecord | undefined {\n const registered = this.extraProviders.get(providerId)\n if (providerSupportsOAuth(registered)) return registered\n const builtin = builtinProviders().find(provider => provider.id === providerId)\n if (builtin === undefined) return undefined\n return { name: builtin.name, baseUrl: builtin.baseUrl, oauth: builtin.auth.oauth }\n }\n\n async resolve(ref: CredentialRef): Promise<ResolvedCredential | undefined> {\n const providerId = providerIdOfRef(String(ref))\n if (providerId === undefined) {\n const value = process.env[String(ref)]\n return value !== undefined && value.length > 0 ? { value, source: 'env' } : undefined\n }\n const config = this.oauthConfigFor(providerId)\n if (config === undefined) return undefined\n const value = await resolveOAuthApiKey({\n providerId,\n providerName: typeof config.name === 'string' ? config.name : providerId,\n providerConfig: config,\n store: this.oauthStore,\n })\n return value !== undefined && value.length > 0 ? { value, source: 'pi-oauth' } : undefined\n }\n\n async describe(ref: CredentialRef): Promise<CredentialInfo> {\n const providerId = providerIdOfRef(String(ref))\n if (providerId === undefined) {\n const value = process.env[String(ref)]\n return { configured: value !== undefined && value.length > 0, ...(value ? { source: 'env' } : {}), writable: false }\n }\n const stored = await storedOAuthCredential(this.oauthStore, providerId)\n return { configured: stored !== undefined, ...(stored !== undefined ? { source: 'pi-oauth' } : {}), writable: false }\n }\n\n async set(ref: CredentialRef, _value: string): Promise<void> {\n throw new Error(`credential ${String(ref)} is read-only here: OAuth tokens are managed by /login, environment values by the shell`)\n }\n\n async unset(ref: CredentialRef): Promise<void> {\n const providerId = providerIdOfRef(String(ref))\n if (providerId === undefined) {\n throw new Error(`credential ${String(ref)} is read-only here: environment values are managed by the shell`)\n }\n // Logging out is a legitimate unset: drop the stored token.\n await this.oauthStore.delete(providerId, undefined)\n }\n}\n\nexport const name = 'pi2dsh-credentials-oauth'\n\nexport function apply(ctx: Context, config: PiOAuthCredentialProviderOptions = {}): void {\n // The Service constructor registers itself as ctx.credentials.\n void new PiOAuthCredentialProvider(ctx, config)\n}\n"],"mappings":";;;;;;;;;AACA,SAAS,YAAY,QAAQ;CACzB,IAAI,OAAO,WAAW,KAAA,GAClB,OAAO,OAAO;CAClB,MAAM,wBAAQ,IAAI,MAAM,2BAA2B;CACnD,MAAM,OAAO;CACb,OAAO;AACX;;AAEA,SAAgB,gBAAgB,QAAQ;CACpC,OAAO,UAAU,IAAI,gBAAgB,CAAC,CAAC;AAC3C;;;;;AAKA,SAAgB,oBAAoB,WAAW,QAAQ;CACnD,IAAI,OAAO,SAAS;EAChB,UAAe,YAAY,CAAE,CAAC;EAC9B,OAAO,QAAQ,OAAO,YAAY,MAAM,CAAC;CAC7C;CACA,OAAO,IAAI,SAAS,SAAS,WAAW;EACpC,IAAI,UAAU;EACd,MAAM,gBAAgB,OAAO,oBAAoB,SAAS,OAAO;EACjE,MAAM,gBAAgB;GAClB,IAAI,SACA;GACJ,UAAU;GACV,QAAQ;GACR,OAAO,YAAY,MAAM,CAAC;EAC9B;EACA,OAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;EACxD,UAAe,MAAM,UAAU;GAC3B,IAAI,SACA;GACJ,UAAU;GACV,QAAQ;GACR,QAAQ,KAAK;EACjB,IAAI,UAAU;GACV,IAAI,SACA;GACJ,UAAU;GACV,QAAQ;GACR,OAAO,KAAK;EAChB,CAAC;EACD,IAAI,OAAO,SACP,QAAQ;CAChB,CAAC;AACL;;;;;;;;ACzCA,IAAa,0BAAb,MAAqC;CACjC,8BAAc,IAAI,IAAI;CACtB,yBAAS,IAAI,IAAI;;CAEjB,QAAQ,YAAY,MAAM,SAAS;EAC/B,MAAM,SAAS,gBAAgB,SAAS,MAAM;EAC9C,MAAM,WAAW,KAAK,OAAO,IAAI,UAAU,KAAK,QAAQ,QAAQ;EAChE,MAAM,UAAU,YAAY;GACxB,MAAM,SAAS,YAAY,CAAE,CAAC;GAC9B,OAAO,eAAe;GACtB,OAAO,KAAK;EAChB,EAAA,CAAG;EACH,MAAM,OAAO,OAAO,YAAY,CAAE,CAAC;EACnC,KAAK,OAAO,IAAI,YAAY,IAAI;EAChC,KAAU,WAAW;GACjB,IAAI,KAAK,OAAO,IAAI,UAAU,MAAM,MAChC,KAAK,OAAO,OAAO,UAAU;EACrC,CAAC;EACD,OAAO,oBAAoB,QAAQ,MAAM;CAC7C;CACA,MAAM,KAAK,YAAY,SAAS;EAC5B,SAAS,QAAQ,eAAe;EAChC,OAAO,KAAK,YAAY,IAAI,UAAU;CAC1C;CACA,MAAM,KAAK,SAAS;EAChB,SAAS,QAAQ,eAAe;EAChC,OAAO,CAAC,GAAG,KAAK,WAAW,CAAC,CAAC,KAAK,CAAC,YAAY,iBAAiB;GAAE;GAAY,MAAM,WAAW;EAAK,EAAE;CAC1G;CACA,OAAO,YAAY,IAAI,SAAS;EAC5B,OAAO,KAAK,QAAQ,YAAY,YAAY;GACxC,MAAM,UAAU,KAAK,YAAY,IAAI,UAAU;GAC/C,MAAM,OAAO,MAAM,GAAG,OAAO;GAC7B,SAAS,QAAQ,eAAe;GAChC,IAAI,SAAS,KAAA,GACT,KAAK,YAAY,IAAI,YAAY,IAAI;GACzC,OAAO,QAAQ;EACnB,GAAG,OAAO;CACd;CACA,OAAO,YAAY,SAAS;EACxB,OAAO,KAAK,QAAQ,YAAY,YAAY;GACxC,KAAK,YAAY,OAAO,UAAU;EACtC,GAAG,OAAO;CACd;AACJ;;;ACjDA,SAAgB,kBAAkB,OAAO;CACrC,IAAI,iBAAiB,OACjB,OAAO,MAAM,WAAW,MAAM;CAClC,IAAI,OAAO,UAAU,UACjB,OAAO;CACX,OAAO,OAAO,KAAK;AACvB;;;ACHA,IAAa,cAAb,cAAiC,MAAM;CACnC;CACA,YAAY,MAAM,SAAS,SAAS;EAChC,MAAM,gBAAgB,SAAS,SAAS,KAAK,GAAG,OAAO;EACvD,KAAK,OAAO;EACZ,KAAK,OAAO;CAChB;AACJ;;AAEA,SAAS,gBAAgB,SAAS,OAAO;CACrC,IAAI,UAAU,KAAA,KAAa,UAAU,MACjC,OAAO;CACX,MAAM,SAAS,kBAAkB,KAAK,CAAC,CAAC,KAAK;CAC7C,IAAI,CAAC,UAAU,QAAQ,SAAS,MAAM,GAClC,OAAO;CACX,OAAO,GAAG,QAAQ,IAAI;AAC1B;;;;;;;AAOA,SAAgB,oBAAoB,UAAU,aAAa,aAAa,WAAW;CAC/E,MAAM,SAAS,gBAAgB,WAAW,MAAM;CAChD,OAAO,oBAAoB,8BAA8B,UAAU,aAAa,aAAa,WAAW,MAAM,GAAG,MAAM;AAC3H;AACA,eAAe,8BAA8B,UAAU,aAAa,aAAa,WAAW,QAAQ;CAChG,OAAO,eAAe;CACtB,MAAM,qBAAqB,WAAW,MAAM,sBAAsB,aAAa,UAAU,GAAG,IAAI;CAChG,IAAI,WAAW,WAAW,KAAA,KAAa,SAAS,KAAK,QACjD,OAAO,cAAc,oBAAoB,SAAS,KAAK,QAAQ,SAAS,IAAI;EACxE,MAAM;EACN,KAAK,UAAU;EACf,KAAK,UAAU;CACnB,GAAG,MAAM;CAEb,MAAM,SAAS,MAAM,eAAe,aAAa,SAAS,IAAI,MAAM;CACpE,IAAI,QAAQ;EACR,IAAI,OAAO,SAAS,WAAW,SAAS,KAAK,OACzC,OAAO,mBAAmB,aAAa,SAAS,IAAI,SAAS,KAAK,OAAO,QAAQ,QAAQ,WAAW,kBAAkB;EAE1H,IAAI,OAAO,SAAS,aAAa,SAAS,KAAK,QAAQ;GACnD,MAAM,aAAa,WAAW,MAAM;IAAE,GAAG;IAAQ,KAAK;KAAE,GAAG,OAAO;KAAK,GAAG,UAAU;IAAI;GAAE,IAAI;GAC9F,OAAO,cAAc,oBAAoB,SAAS,KAAK,QAAQ,SAAS,IAAI,YAAY,MAAM;EAClG;EACA;CACJ;CAEA,OAAO,SAAS,KAAK,SACf,cAAc,oBAAoB,SAAS,KAAK,QAAQ,SAAS,IAAI,KAAA,GAAW,MAAM,IACtF,KAAA;AACV;AACA,SAAS,sBAAsB,MAAM,KAAK;CACtC,OAAO;EACH,KAAK,OAAO,SAAS,IAAI,SAAU,MAAM,KAAK,IAAI,IAAI;EACtD,aAAa,SAAS,KAAK,WAAW,IAAI;CAC9C;AACJ;AACA,MAAM,oCAAoC;AAC1C,MAAM,mCAAmC;;;;;;AAMzC,eAAe,mBAAmB,aAAa,YAAY,OAAO,QAAQ,QAAQ,oBAAoB;CAClG,MAAM,oBAAoB,KAAK,IAAI,mCAAmC,sBAAsB,CAAC;CAC7F,MAAM,eAAe,eAAe,KAAK,IAAI,IAAI,qBAAqB,WAAW;CACjF,IAAI,aAAa;CACjB,IAAI,YAAY,UAAU,GAAG;EAEzB,IAAI;EACJ,IAAI;GACA,OAAO,MAAM,YAAY,OAAO,YAAY,OAAO,YAAY;IAC3D,IAAI,SAAS,SAAS,SAClB,OAAO,KAAA;IACX,IAAI,CAAC,YAAY,OAAO,GACpB,OAAO,KAAA;IACX,IAAI;KACA,MAAM,gBAAgB,YAAY,IAAI,CAClC,QACA,YAAY,QAAQ,gCAAgC,CACxD,CAAC;KACD,OAAO,MAAM,MAAM,QAAQ,SAAS,aAAa;IACrD,SACO,OAAO;KACV,MAAM,IAAI,YAAY,SAAS,4BAA4B,cAAc,EAAE,OAAO,MAAM,CAAC;IAC7F;GACJ,GAAG,EAAE,OAAO,CAAC;EACjB,SACO,OAAO;GACV,IAAI,iBAAiB,aACjB,MAAM;GACV,MAAM,IAAI,YAAY,QAAQ,sCAAsC,cAAc,EAAE,OAAO,MAAM,CAAC;EACtG;EACA,IAAI,MAAM,SAAS,SACf,OAAO,KAAA;EACX,aAAa;EAIb,IAAI,uBAAuB,KAAA,KAAa,YAAY,UAAU,GAC1D,MAAM,IAAI,YAAY,SAAS,4DAA4D,YAAY;CAE/G;CACA,IAAI;EACA,OAAO;GAAE,MAAM,MAAM,MAAM,OAAO,UAAU;GAAG,QAAQ;EAAQ;CACnE,SACO,OAAO;EACV,MAAM,IAAI,YAAY,SAAS,oCAAoC,cAAc,EAAE,OAAO,MAAM,CAAC;CACrG;AACJ;AACA,eAAe,cAAc,aAAa,QAAQ,YAAY,YAAY,QAAQ;CAC9E,IAAI;EACA,OAAO,MAAM,OAAO,QAAQ;GAAE,KAAK;GAAa;GAAY;EAAO,CAAC;CACxE,SACO,OAAO;EACV,MAAM,IAAI,YAAY,QAAQ,oCAAoC,cAAc,EAAE,OAAO,MAAM,CAAC;CACpG;AACJ;AACA,eAAe,eAAe,aAAa,YAAY,QAAQ;CAC3D,IAAI;EACA,OAAO,MAAM,YAAY,KAAK,YAAY,EAAE,OAAO,CAAC;CACxD,SACO,OAAO;EACV,MAAM,IAAI,YAAY,QAAQ,oCAAoC,cAAc,EAAE,OAAO,MAAM,CAAC;CACpG;AACJ;;;ACjIA,SAAgB,WAAW,QAAQ;CAC/B,OAAO;EACH,MAAM,OAAO;EACb,gBAAgB,OAAO;EACvB,OAAO,OAAO,cAAc;GAUxB,OAAO;IAAE,GAAG,MATa,OAAO,MAAM;KAClC,SAAS,SAAS,UAAU,OAAO;MAAE,MAAM;MAAY,GAAG;KAAK,CAAC;KAChE,eAAe,SAAS,UAAU,OAAO;MAAE,MAAM;MAAe,GAAG;KAAK,CAAC;KACzE,WAAW,WAAW,UAAU,OAAO;MAAE,MAAM;MAAQ,GAAG;KAAO,CAAC;KAClE,aAAa,YAAY,UAAU,OAAO;MAAE,MAAM;MAAY;KAAQ,CAAC;KACvE,yBAAyB,UAAU,OAAO;MAAE,MAAM;MAAe,SAAS;KAA+B,CAAC;KAC1G,WAAW,WAAW,UAAU,OAAO;MAAE,MAAM;MAAU,GAAG;KAAO,CAAC;KACpE,QAAQ,UAAU;IACtB,CAAC;IACuB,MAAM;GAAQ;EAC1C;EACA,SAAS,OAAO,YAAY,YAAY;GAAE,GAAI,MAAM,OAAO,aAAa,YAAY,MAAM;GAAI,MAAM;EAAQ;EAC5G,QAAQ,OAAO,gBAAgB,EAAE,QAAQ,OAAO,UAAU,UAAU,EAAE;CAC1E;AACJ;;;ACEA,IAAa,sBAAb,cAAyC,wBAAwB;CAC/D;CAEA,YAAY,MAAc;EACxB,MAAM;EACN,KAAKA,QAAQ;EACb,IAAI;GACF,MAAM,OAAO,KAAK,MAAM,aAAa,MAAM,MAAM,CAAC;GAClD,KAAK,MAAM,CAAC,YAAY,eAAe,OAAO,QAAQ,IAAI,GACvD,KAA2D,YAAY,IAAI,YAAY,UAAU;EAEtG,QAAQ,CAER;CACF;CAEA,IAAI,OAAe;EACjB,OAAO,KAAKA;CACd;CAEA,MAAMC,WAA0B;EAC9B,MAAM,cAAe,KAA0D;EAC/E,MAAM,OAAO,OAAO,YAAY,WAAW;EAC3C,MAAM,MAAM,QAAQ,KAAKD,KAAK,GAAG,EAAE,WAAW,KAAK,CAAC;EAGpD,MAAM,OAAO,GAAG,KAAKA,MAAM,OAAO,QAAQ,IAAI,GAAG,KAAK,MAAM,KAAK,OAAO,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE;EAC5F,MAAM,UAAU,MAAM,GAAG,KAAK,UAAU,MAAM,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,IAAM,CAAC;EAC3E,MAAM,OAAO,MAAM,KAAKA,KAAK;CAC/B;CAEA,OAAgB,YAAoB,IAAmC,SAA2C;EAGhH,OAAO,MAAM,OAAO,YAAY,OAAO,YAAqB;GAC1D,MAAM,OAAO,MAAM,GAAG,OAAO;GAC7B,IAAI,SAAS,KAAA,GAAW;IAEtB,KAD+E,YACnE,IAAI,YAAY,IAAI;IAChC,MAAM,KAAKC,SAAS;GACtB;GACA,OAAO;EACT,GAAG,OAAO;CACZ;CAEA,OAAgB,YAAoB,SAAwC;EAC1E,OAAO,MAAM,OAAO,YAAY,OAAO,CAAC,CAAC,WAAW,KAAKA,SAAS,CAAC;CACrE;AACF;;;;;;;;;;AAWA,SAAgB,YAAY,SAAkC,SAA2C;CACvG,IAAI,EAAE,mBAAmB,cAAc,OAAO;CAC9C,IAAI,YAAY,KAAA,GAAW,OAAO;CAClC,MAAM,SAAS,IAAI,gBAAgB;CACnC,MAAM,aAAa,OAAO,MAAM;CAChC,IAAI,QAAQ,WAAW,QAAQ,SAAS,OAAO,MAAM;MAChD;EACH,QAAQ,iBAAiB,SAAS,MAAM,EAAE,MAAM,KAAK,CAAC;EACtD,QAAQ,iBAAiB,SAAS,MAAM,EAAE,MAAM,KAAK,CAAC;CACxD;CACA,OAAO,OAAO;AAChB;;;;;;;;;;;AAwDA,SAAS,eAAe,MAA2C,KAA+B;CAChG,IAAI,SAAS,KAAA,KAAa,OAAO,QAAQ,YAAY,CAAC,gBAAgB,KAAK,GAAG,GAAG;CACjF,IAAI;EACF,KAAK,GAAG;CACV,QAAQ,CAIR;AACF;AAEA,SAAgB,iBACd,IACA,QACA,SACA,MACA,QAKA;CAGA,MAAM,kBAAkB,UAAU,IAAI,gBAAgB,CAAC,CAAC;CAUxD,IAAI;;;;;;;;;;CAUJ,MAAM,eAAe,gBAA6C;EAChE,MAAM,UAAU;EAChB,UAAU,KAAA;EAQV,IAAI,YAAY,KAAA,GAAW,OAAO;EAClC,OAAO,gBAAgB,KAAA,IAAY,KAAA,IAAY,OAAO,WAAW;CACnE;CACA,OAAO;EACL,QAAQ;EACR,MAAM,OAAO,QAAQ;GACnB,IAAI,OAAO,SAAS,UAAU;IAC5B,MAAM,UAAU,OAAO,WAAW,CAAC;IACnC,UAAU,KAAA;IACV,MAAM,SAAS,MAAM,GAAG,OAAO,OAAO,SAAS,QAAQ,KAAI,WAAU,OAAO,KAAK,GAAG,eAAe;IACnG,OAAO,QAAQ,MAAK,WAAU,OAAO,UAAU,MAAM,CAAC,EAAE,MAAM;GAChE;GAUA,OAAO,GAAG,MAAM,OAAO,SAAS,YAAY,OAAO,WAAW,GAAG,YAAY,iBAAiB,OAAO,MAAM,CAAC;EAC9G;EACA,OAAO,OAAO;GACZ,IAAI,MAAM,SAAS,YAAY;IAO7B,MAAM,SAAS,MAAM,QAAQ,KAAA,IAAY,KAAA,IAAY,UAAU,MAAM,GAAG,MAAM,MAAM;IACpF,MAAM,OAAO,MAAM,iBAAiB,KAAA,IAAY,KAAK,OAAO,MAAM;IAClE,UAAU,yBAAyB,MAAM,GAAG;IAC5C,GAAG,OAAO,+BAA+B,QAAQ,MAAM;IAKvD,eAAe,MAAM,MAAM,GAAG;GAChC,OAAO,IAAI,MAAM,SAAS,eAAe;IAIvC,MAAM,SAAS,OAAO,MAAM,qBAAqB,YAAY,MAAM,mBAAmB,IAClF,eAAe,KAAK,MAAM,MAAM,mBAAmB,EAAE,EAAE,SACvD;IAGJ,MAAM,SAAS,gCAAgC,MAAM,gBAAgB,qBAAqB,MAAM,SAAS,IAAI;IAC7G,UAAU;IACV,GAAG,OAAO,SAAS,MAAM,gBAAgB,kBAAkB,MAAM,WAAW,QAAQ;IAMpF,IAAI,GAAG,eAAe,KAAA,GAAW;KAC/B,UAAU,KAAA;KACV,GAAQ,WAAW,kCAAkC,QAAQ,eAAe,CAAC,CAAC,WACtE;MAAE,IAAI,CAAC,gBAAgB,SAAS,SAAS;KAAE,SAC3C,KAAA,CACR;IACF;IACA,eAAe,MAAM,MAAM,eAAe;GAC5C,OAAO,IAAI,MAAM,YAAY,KAAA,GAC3B,GAAG,OAAO,MAAM,OAAO;EAE3B;CACF;AACF;AAEA,SAAS,cAAc,gBAAsE;CAG3F,MAAM,QAAQ,gBAAgB,UACxB,gBAAgB,KAAA,EAAoC;CAC1D,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,OAAQ,MAAwB,UAAU,aAC5F,QACA,KAAA;AACN;AAKA,SAAS,eAAe,aAItB;CACA,IAAI,OAAO,YAAY,WAAW,YAChC,OAAO;CAET,OAAO,WAAW,WAAW;AAC/B;AAEA,SAAgB,sBAAsB,gBAAoD;CACxF,OAAO,cAAc,cAAc,MAAM,KAAA;AAC3C;AAKA,eAAsB,gBAAgB,SAWX;CACzB,MAAM,cAAc,cAAc,QAAQ,cAAc;CACxD,IAAI,gBAAgB,KAAA,GAClB,MAAM,IAAI,MAAM,GAAG,QAAQ,gBAAgB,QAAQ,WAAW,8BAA8B;CAE9F,MAAM,UAAU,eAAe,WAAW;CAM1C,MAAM,OAAO,IAAI,gBAAgB;CACjC,IAAI,QAAQ,WAAW,KAAA,GAAW;EAChC,IAAI,QAAQ,OAAO,SAAS,KAAK,MAAM;OAClC,QAAQ,OAAO,iBAAiB,eAAe,KAAK,MAAM,GAAG,EAAE,MAAM,KAAK,CAAC;CAClF;CACA,IAAI;EACF,MAAM,aAAa,MAAM,QAAQ,MAAM,iBACrC,QAAQ,IACR,KAAK,QACL,QAAQ,SACR,QAAQ,YACF,KAAK,MAAM,CACnB,CAAC;EACD,MAAM,QAAQ,MAAM,OAAO,QAAQ,YAAY,YAAY,UAAU;EACrE,OAAO;CACT,UAAU;EACR,KAAK,MAAM;CACb;AACF;AAMA,eAAsB,mBAAmB,SAMT;CAC9B,MAAM,cAAc,cAAc,QAAQ,cAAc;CACxD,IAAI,gBAAgB,KAAA,GAAW,OAAO,KAAA;CAYtC,QAAO,MANgB,oBACrB;EALA,IAAI,QAAQ;EACZ,MAAM,QAAQ,gBAAgB,QAAQ;EACtC,MAAM,EAAE,OAAO,eAAe,WAAW,EAAE;CAG3C,GACA,QAAQ,OACR,EAAE,KAAK,YAAY,KAAA,EAAU,GAC7B,QAAQ,WAAW,KAAA,IAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,KAAA,CAC9D,EAAA,EACiB,MAAM;AACzB;AAEA,eAAsB,sBAAsB,OAA4B,YAAwD;CAC9H,MAAM,SAAS,MAAM,MAAM,KAAK,YAAY,KAAA,CAAS;CACrD,OAAO,QAAQ,SAAS,UAAU,SAAS,KAAA;AAC7C;AAOA,eAAsB,sBAAsB,SAMuB;CACjE,MAAM,cAAc,cAAc,QAAQ,cAAc;CACxD,MAAM,iBAAkB,QAAQ,eAAe,MAAoC;CACnF,IAAI,gBAAgB,KAAA,KAAa,mBAAmB,KAAA,GAAW,OAAO,KAAA;CACtE,MAAM,OAAsB,CAAC;CAC7B,IAAI,gBAAgB,KAAA,GAAW,KAAK,QAAQ,eAAe,WAAW;CACtE,IAAI,mBAAmB,KAAA,GAAW,KAAK,SAAS;CAEhD,OAAO,MAAM,oBACX;EAFiB,IAAI,QAAQ;EAAY,MAAM,QAAQ,gBAAgB,QAAQ;EAAY;CAE3F,GACA,QAAQ,OACR;EACE,KAAK,OAAO,SAAiB,QAAQ,IAAI;EACzC,YAAY,OAAO,SAAiB,WAAW,IAAI;CACrD,GACA,QAAQ,WAAW,KAAA,IAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,KAAA,CAC9D;AACF;;;ACpYA,MAAM,mBAAmB;AAEzB,SAAgB,mBAAmB,YAA4B;CAC7D,OAAO,GAAG,mBAAmB,WAAW,YAAY,CAAC,CAAC,WAAW,KAAK,GAAG;AAC3E;AAEA,SAAS,gBAAgB,KAAiC;CACxD,IAAI,CAAC,IAAI,WAAW,gBAAgB,GAAG,OAAO,KAAA;CAC9C,OAAO,IAAI,MAAM,EAAuB,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,KAAK,GAAG;AAC7E;AASA,IAAa,4BAAb,cAA+C,mBAAmB;CAChE;CACA;CAEA,YAAY,KAAc,UAA4C,CAAC,GAAG;EACxE,MAAM,GAAG;EACT,KAAK,aAAa,IAAI,oBAAoB,QAAQ,YAAY,KAAK,YAAY,GAAG,WAAW,CAAC;EAC9F,KAAK,iBAAiB,QAAQ,6BAAa,IAAI,IAAI;CACrD;CAEA,eAAuB,YAA+C;EACpE,MAAM,aAAa,KAAK,eAAe,IAAI,UAAU;EACrD,IAAI,sBAAsB,UAAU,GAAG,OAAO;EAC9C,MAAM,UAAU,iBAAiB,CAAC,CAAC,MAAK,aAAY,SAAS,OAAO,UAAU;EAC9E,IAAI,YAAY,KAAA,GAAW,OAAO,KAAA;EAClC,OAAO;GAAE,MAAM,QAAQ;GAAM,SAAS,QAAQ;GAAS,OAAO,QAAQ,KAAK;EAAM;CACnF;CAEA,MAAM,QAAQ,KAA6D;EACzE,MAAM,aAAa,gBAAgB,OAAO,GAAG,CAAC;EAC9C,IAAI,eAAe,KAAA,GAAW;GAC5B,MAAM,QAAQ,QAAQ,IAAI,OAAO,GAAG;GACpC,OAAO,UAAU,KAAA,KAAa,MAAM,SAAS,IAAI;IAAE;IAAO,QAAQ;GAAM,IAAI,KAAA;EAC9E;EACA,MAAM,SAAS,KAAK,eAAe,UAAU;EAC7C,IAAI,WAAW,KAAA,GAAW,OAAO,KAAA;EACjC,MAAM,QAAQ,MAAM,mBAAmB;GACrC;GACA,cAAc,OAAO,OAAO,SAAS,WAAW,OAAO,OAAO;GAC9D,gBAAgB;GAChB,OAAO,KAAK;EACd,CAAC;EACD,OAAO,UAAU,KAAA,KAAa,MAAM,SAAS,IAAI;GAAE;GAAO,QAAQ;EAAW,IAAI,KAAA;CACnF;CAEA,MAAM,SAAS,KAA6C;EAC1D,MAAM,aAAa,gBAAgB,OAAO,GAAG,CAAC;EAC9C,IAAI,eAAe,KAAA,GAAW;GAC5B,MAAM,QAAQ,QAAQ,IAAI,OAAO,GAAG;GACpC,OAAO;IAAE,YAAY,UAAU,KAAA,KAAa,MAAM,SAAS;IAAG,GAAI,QAAQ,EAAE,QAAQ,MAAM,IAAI,CAAC;IAAI,UAAU;GAAM;EACrH;EACA,MAAM,SAAS,MAAM,sBAAsB,KAAK,YAAY,UAAU;EACtE,OAAO;GAAE,YAAY,WAAW,KAAA;GAAW,GAAI,WAAW,KAAA,IAAY,EAAE,QAAQ,WAAW,IAAI,CAAC;GAAI,UAAU;EAAM;CACtH;CAEA,MAAM,IAAI,KAAoB,QAA+B;EAC3D,MAAM,IAAI,MAAM,cAAc,OAAO,GAAG,EAAE,wFAAwF;CACpI;CAEA,MAAM,MAAM,KAAmC;EAC7C,MAAM,aAAa,gBAAgB,OAAO,GAAG,CAAC;EAC9C,IAAI,eAAe,KAAA,GACjB,MAAM,IAAI,MAAM,cAAc,OAAO,GAAG,EAAE,gEAAgE;EAG5G,MAAM,KAAK,WAAW,OAAO,YAAY,KAAA,CAAS;CACpD;AACF;AAEA,MAAa,OAAO;AAEpB,SAAgB,MAAM,KAAc,SAA2C,CAAC,GAAS;CAEvF,IAAS,0BAA0B,KAAK,MAAM;AAChD"}
|
|
1
|
+
{"version":3,"file":"credentials-oauth-CAohSLcB.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","../src/credentials-oauth.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\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","import { join } from 'node:path'\nimport type { Context } from '@deepseek-ai/cordis'\nimport { CredentialProvider, type CredentialInfo, type CredentialRef, type ResolvedCredential } from '@deepseek-ai/dsh-credentials'\nimport { FileCredentialStore, providerSupportsOAuth, resolveOAuthApiKey, storedOAuthCredential } from './oauth-bridge.js'\nimport { builtinProviders } from './compat/pi-ai.js'\nimport { getAgentDir } from './compat/pi-coding-agent.js'\n\ntype UnknownRecord = Record<string, unknown>\n\n// L4 of the OAuth host seam: a standard dsh-credentials provider that serves\n// Pi OAuth tokens to DSH's native LLM request path. A route configured as\n// `apiKeyEnv: PI2DSH_OAUTH_OPENAI_CODEX` resolves per request through this\n// provider — Pi's double-checked-lock refresh runs on every resolution, so a\n// rotated token reaches the next model call with no restart, exactly the\n// per-operation semantics the credentials seam demands. Every other reference\n// falls through to the process environment, so one provider instance serves a\n// whole composition.\n//\n// Reference convention: PI2DSH_OAUTH_<PROVIDER_ID> where the provider id is\n// upper-cased with `-` as `_` (openai-codex → PI2DSH_OAUTH_OPENAI_CODEX).\n\nconst OAUTH_REF_PREFIX = 'PI2DSH_OAUTH_'\n\nexport function oauthCredentialRef(providerId: string): string {\n return `${OAUTH_REF_PREFIX}${providerId.toUpperCase().replaceAll('-', '_')}`\n}\n\nfunction providerIdOfRef(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 interface PiOAuthCredentialProviderOptions {\n /** Path to the Pi-format auth.json; defaults to `$agentDir/auth.json`. */\n authPath?: string\n /** Additional provider configs (id → config with an oauth block), e.g. from packages that registered providers. */\n providers?: ReadonlyMap<string, UnknownRecord>\n}\n\nexport class PiOAuthCredentialProvider extends CredentialProvider {\n private readonly oauthStore: FileCredentialStore\n private readonly extraProviders: ReadonlyMap<string, UnknownRecord>\n\n constructor(ctx: Context, options: PiOAuthCredentialProviderOptions = {}) {\n super(ctx)\n this.oauthStore = new FileCredentialStore(options.authPath ?? join(getAgentDir(), 'auth.json'))\n this.extraProviders = options.providers ?? new Map()\n }\n\n private oauthConfigFor(providerId: string): UnknownRecord | undefined {\n const registered = this.extraProviders.get(providerId)\n if (providerSupportsOAuth(registered)) return registered\n const builtin = builtinProviders().find(provider => provider.id === providerId)\n if (builtin === undefined) return undefined\n return { name: builtin.name, baseUrl: builtin.baseUrl, oauth: builtin.auth.oauth }\n }\n\n async resolve(ref: CredentialRef): Promise<ResolvedCredential | undefined> {\n const providerId = providerIdOfRef(String(ref))\n if (providerId === undefined) {\n const value = process.env[String(ref)]\n return value !== undefined && value.length > 0 ? { value, source: 'env' } : undefined\n }\n const config = this.oauthConfigFor(providerId)\n if (config === undefined) return undefined\n const value = await resolveOAuthApiKey({\n providerId,\n providerName: typeof config.name === 'string' ? config.name : providerId,\n providerConfig: config,\n store: this.oauthStore,\n })\n return value !== undefined && value.length > 0 ? { value, source: 'pi-oauth' } : undefined\n }\n\n async describe(ref: CredentialRef): Promise<CredentialInfo> {\n const providerId = providerIdOfRef(String(ref))\n if (providerId === undefined) {\n const value = process.env[String(ref)]\n return { configured: value !== undefined && value.length > 0, ...(value ? { source: 'env' } : {}), writable: false }\n }\n const stored = await storedOAuthCredential(this.oauthStore, providerId)\n return { configured: stored !== undefined, ...(stored !== undefined ? { source: 'pi-oauth' } : {}), writable: false }\n }\n\n async set(ref: CredentialRef, _value: string): Promise<void> {\n throw new Error(`credential ${String(ref)} is read-only here: OAuth tokens are managed by /login, environment values by the shell`)\n }\n\n async unset(ref: CredentialRef): Promise<void> {\n const providerId = providerIdOfRef(String(ref))\n if (providerId === undefined) {\n throw new Error(`credential ${String(ref)} is read-only here: environment values are managed by the shell`)\n }\n // Logging out is a legitimate unset: drop the stored token.\n await this.oauthStore.delete(providerId, undefined)\n }\n}\n\nexport const name = 'pi2dsh-credentials-oauth'\n\nexport function apply(ctx: Context, config: PiOAuthCredentialProviderOptions = {}): void {\n // The Service constructor registers itself as ctx.credentials.\n void new PiOAuthCredentialProvider(ctx, config)\n}\n"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
|
|
2
|
-
import { i as oauthCredentialRef, n as apply, r as name, t as PiOAuthCredentialProvider } from "./credentials-oauth-
|
|
2
|
+
import { i as oauthCredentialRef, n as apply, r as name, t as PiOAuthCredentialProvider } from "./credentials-oauth-CAohSLcB.mjs";
|
|
3
3
|
export { PiOAuthCredentialProvider, apply, name, oauthCredentialRef };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
|
|
2
|
+
//#region node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/utils/deferred-tools.js
|
|
3
|
+
const identityToolName = (name) => name;
|
|
4
|
+
/** Split current tools into prefix and transcript-loaded definitions. */
|
|
5
|
+
function splitDeferredTools(context, enabled, normalizeName = identityToolName) {
|
|
6
|
+
const uniqueTools = /* @__PURE__ */ new Map();
|
|
7
|
+
for (const tool of context.tools ?? []) uniqueTools.set(normalizeName(tool.name), tool);
|
|
8
|
+
if (!enabled) return {
|
|
9
|
+
immediate: [...uniqueTools.values()],
|
|
10
|
+
deferred: /* @__PURE__ */ new Map()
|
|
11
|
+
};
|
|
12
|
+
const deferredNames = /* @__PURE__ */ new Set();
|
|
13
|
+
const usedNames = /* @__PURE__ */ new Set();
|
|
14
|
+
for (const message of context.messages) if (message.role === "assistant") {
|
|
15
|
+
for (const block of message.content) if (block.type === "toolCall") usedNames.add(normalizeName(block.name));
|
|
16
|
+
} else if (message.role === "toolResult") for (const name of message.addedToolNames ?? []) {
|
|
17
|
+
const normalizedName = normalizeName(name);
|
|
18
|
+
if (!usedNames.has(normalizedName)) deferredNames.add(normalizedName);
|
|
19
|
+
}
|
|
20
|
+
const immediate = [];
|
|
21
|
+
const deferred = /* @__PURE__ */ new Map();
|
|
22
|
+
for (const [name, tool] of uniqueTools) if (deferredNames.has(name)) deferred.set(name, tool);
|
|
23
|
+
else immediate.push(tool);
|
|
24
|
+
return {
|
|
25
|
+
immediate,
|
|
26
|
+
deferred
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
30
|
+
export { splitDeferredTools as t };
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=deferred-tools-BD4g5QUx.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deferred-tools-BD4g5QUx.mjs","names":[],"sources":["../node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/utils/deferred-tools.js"],"sourcesContent":["const identityToolName = (name) => name;\n/** Split current tools into prefix and transcript-loaded definitions. */\nexport function splitDeferredTools(context, enabled, normalizeName = identityToolName) {\n const uniqueTools = new Map();\n for (const tool of context.tools ?? [])\n uniqueTools.set(normalizeName(tool.name), tool);\n if (!enabled)\n return { immediate: [...uniqueTools.values()], deferred: new Map() };\n const deferredNames = new Set();\n const usedNames = new Set();\n for (const message of context.messages) {\n if (message.role === \"assistant\") {\n for (const block of message.content) {\n if (block.type === \"toolCall\")\n usedNames.add(normalizeName(block.name));\n }\n }\n else if (message.role === \"toolResult\") {\n for (const name of message.addedToolNames ?? []) {\n const normalizedName = normalizeName(name);\n if (!usedNames.has(normalizedName))\n deferredNames.add(normalizedName);\n }\n }\n }\n const immediate = [];\n const deferred = new Map();\n for (const [name, tool] of uniqueTools) {\n if (deferredNames.has(name))\n deferred.set(name, tool);\n else\n immediate.push(tool);\n }\n return { immediate, deferred };\n}\n//# sourceMappingURL=deferred-tools.js.map"],"x_google_ignoreList":[0],"mappings":";;AAAA,MAAM,oBAAoB,SAAS;;AAEnC,SAAgB,mBAAmB,SAAS,SAAS,gBAAgB,kBAAkB;CACnF,MAAM,8BAAc,IAAI,IAAI;CAC5B,KAAK,MAAM,QAAQ,QAAQ,SAAS,CAAC,GACjC,YAAY,IAAI,cAAc,KAAK,IAAI,GAAG,IAAI;CAClD,IAAI,CAAC,SACD,OAAO;EAAE,WAAW,CAAC,GAAG,YAAY,OAAO,CAAC;EAAG,0BAAU,IAAI,IAAI;CAAE;CACvE,MAAM,gCAAgB,IAAI,IAAI;CAC9B,MAAM,4BAAY,IAAI,IAAI;CAC1B,KAAK,MAAM,WAAW,QAAQ,UAC1B,IAAI,QAAQ,SAAS,aACZ;OAAA,MAAM,SAAS,QAAQ,SACxB,IAAI,MAAM,SAAS,YACf,UAAU,IAAI,cAAc,MAAM,IAAI,CAAC;CAAA,OAG9C,IAAI,QAAQ,SAAS,cACtB,KAAK,MAAM,QAAQ,QAAQ,kBAAkB,CAAC,GAAG;EAC7C,MAAM,iBAAiB,cAAc,IAAI;EACzC,IAAI,CAAC,UAAU,IAAI,cAAc,GAC7B,cAAc,IAAI,cAAc;CACxC;CAGR,MAAM,YAAY,CAAC;CACnB,MAAM,2BAAW,IAAI,IAAI;CACzB,KAAK,MAAM,CAAC,MAAM,SAAS,aACvB,IAAI,cAAc,IAAI,IAAI,GACtB,SAAS,IAAI,MAAM,IAAI;MAEvB,UAAU,KAAK,IAAI;CAE3B,OAAO;EAAE;EAAW;CAAS;AACjC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
|
|
2
|
+
//#region node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/utils/diagnostics.js
|
|
3
|
+
function formatThrownValue(value) {
|
|
4
|
+
if (value instanceof Error) return value.message || value.name;
|
|
5
|
+
if (typeof value === "string") return value;
|
|
6
|
+
return String(value);
|
|
7
|
+
}
|
|
8
|
+
function extractDiagnosticError(error) {
|
|
9
|
+
if (!(error instanceof Error)) return {
|
|
10
|
+
name: "ThrownValue",
|
|
11
|
+
message: formatThrownValue(error)
|
|
12
|
+
};
|
|
13
|
+
const code = error.code;
|
|
14
|
+
return {
|
|
15
|
+
name: error.name || void 0,
|
|
16
|
+
message: error.message || error.name,
|
|
17
|
+
stack: error.stack,
|
|
18
|
+
code: typeof code === "string" || typeof code === "number" ? code : void 0
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function createAssistantMessageDiagnostic(type, error, details) {
|
|
22
|
+
return {
|
|
23
|
+
type,
|
|
24
|
+
timestamp: Date.now(),
|
|
25
|
+
error: extractDiagnosticError(error),
|
|
26
|
+
details
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function appendAssistantMessageDiagnostic(message, diagnostic) {
|
|
30
|
+
message.diagnostics = [...message.diagnostics ?? [], diagnostic];
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { createAssistantMessageDiagnostic as n, formatThrownValue as r, appendAssistantMessageDiagnostic as t };
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=diagnostics-BqYkodgB.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics-BqYkodgB.mjs","names":[],"sources":["../node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/utils/diagnostics.js"],"sourcesContent":["export 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"],"x_google_ignoreList":[0],"mappings":";;AAAA,SAAgB,kBAAkB,OAAO;CACrC,IAAI,iBAAiB,OACjB,OAAO,MAAM,WAAW,MAAM;CAClC,IAAI,OAAO,UAAU,UACjB,OAAO;CACX,OAAO,OAAO,KAAK;AACvB;AACA,SAAgB,uBAAuB,OAAO;CAC1C,IAAI,EAAE,iBAAiB,QACnB,OAAO;EAAE,MAAM;EAAe,SAAS,kBAAkB,KAAK;CAAE;CACpE,MAAM,OAAO,MAAM;CACnB,OAAO;EACH,MAAM,MAAM,QAAQ,KAAA;EACpB,SAAS,MAAM,WAAW,MAAM;EAChC,OAAO,MAAM;EACb,MAAM,OAAO,SAAS,YAAY,OAAO,SAAS,WAAW,OAAO,KAAA;CACxE;AACJ;AACA,SAAgB,iCAAiC,MAAM,OAAO,SAAS;CACnE,OAAO;EAAE;EAAM,WAAW,KAAK,IAAI;EAAG,OAAO,uBAAuB,KAAK;EAAG;CAAQ;AACxF;AACA,SAAgB,iCAAiC,SAAS,YAAY;CAClE,QAAQ,cAAc,CAAC,GAAI,QAAQ,eAAe,CAAC,GAAI,UAAU;AACrE"}
|