@ponythewhite/base-context 1.0.1 → 1.0.4

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.
Files changed (48) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/base-context-runtime/pyproject.toml +1 -1
  3. package/dist/base-context-runtime/src/rlm/mcp.py +39 -17
  4. package/dist/base-context-runtime/test/test_mcp.py +87 -1
  5. package/dist/base-context-runtime/uv.lock +1 -1
  6. package/dist/build-info.json +1 -1
  7. package/dist/bundle/{bundled-modules-TXUMJ2XQ.js → bundled-modules-R5EAJ62K.js} +2 -2
  8. package/dist/bundle/{chunk-S3INFPZZ.js → chunk-BV25CVRM.js} +378 -199
  9. package/dist/bundle/{chunk-V3L54UD6.js → chunk-XDJ56NJA.js} +26 -11
  10. package/dist/bundle/{cli-main-BYMSRPH6.js → cli-main-OUKN743U.js} +2 -2
  11. package/dist/bundle/cli.js +1 -1
  12. package/dist/bundle/{main-ODOYCEQC.js → main-QPCXSW6X.js} +2 -2
  13. package/dist/cli/daemon-ps.d.ts.map +1 -1
  14. package/dist/cli/daemon-ps.js +1 -0
  15. package/dist/cli/daemon-ps.js.map +1 -1
  16. package/dist/core/auth-storage.d.ts +4 -0
  17. package/dist/core/auth-storage.d.ts.map +1 -1
  18. package/dist/core/auth-storage.js +77 -19
  19. package/dist/core/auth-storage.js.map +1 -1
  20. package/dist/core/kernel/bootstrap.d.ts.map +1 -1
  21. package/dist/core/kernel/bootstrap.js +5 -2
  22. package/dist/core/kernel/bootstrap.js.map +1 -1
  23. package/dist/core/mcp/mcp-manager.d.ts.map +1 -1
  24. package/dist/core/mcp/mcp-manager.js +2 -2
  25. package/dist/core/mcp/mcp-manager.js.map +1 -1
  26. package/dist/installer.mjs +5 -2
  27. package/dist/modes/daemon/daemon-supervisor-ownership.d.ts.map +1 -1
  28. package/dist/modes/daemon/daemon-supervisor-ownership.js +16 -16
  29. package/dist/modes/daemon/daemon-supervisor-ownership.js.map +1 -1
  30. package/dist/modes/interactive/auth-flows.d.ts.map +1 -1
  31. package/dist/modes/interactive/auth-flows.js +7 -6
  32. package/dist/modes/interactive/auth-flows.js.map +1 -1
  33. package/dist/modes/interactive/components/login-dialog.d.ts +3 -1
  34. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  35. package/dist/modes/interactive/components/login-dialog.js +3 -1
  36. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  37. package/dist/modes/interactive/components/menu-panel.d.ts +1 -0
  38. package/dist/modes/interactive/components/menu-panel.d.ts.map +1 -1
  39. package/dist/modes/interactive/components/menu-panel.js +3 -0
  40. package/dist/modes/interactive/components/menu-panel.js.map +1 -1
  41. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  42. package/dist/modes/interactive/interactive-mode.js +7 -5
  43. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  44. package/dist/modes/rpc/rpc-client.d.ts +2 -0
  45. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  46. package/dist/modes/rpc/rpc-client.js +58 -31
  47. package/dist/modes/rpc/rpc-client.js.map +1 -1
  48. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"auth-storage.js","sourceRoot":"","sources":["../../src/core/auth-storage.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Credential storage for API keys and OAuth tokens.\n * Handles loading, saving, and refreshing credentials from auth.json.\n *\n * Uses file locking to prevent race conditions when multiple pi instances\n * try to refresh tokens simultaneously.\n */\n\nimport { createHash } from \"node:crypto\";\nimport {\n\tfindEnvKeys,\n\tgetEnvApiKey,\n\ttype OAuthCredentials,\n\ttype OAuthLoginCallbacks,\n\ttype OAuthProviderId,\n} from \"@ponythewhite/base-context-ai\";\nimport { getOAuthApiKey, getOAuthProvider, getOAuthProviders } from \"@ponythewhite/base-context-ai/oauth\";\nimport { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\nimport lockfile from \"proper-lockfile\";\nimport { getAgentDir } from \"../config.js\";\nimport { assertProductStatePath } from \"../runtime-paths.js\";\nimport { getProviderAuthContract, isProviderApiKeyAllowed } from \"./provider-contracts.js\";\nimport { resolveConfigValue, resolveConfigValueUncached } from \"./resolve-config-value.js\";\n\nexport type ApiKeyCredential = {\n\ttype: \"api_key\";\n\tkey: string;\n};\n\nexport type OAuthCredential = {\n\ttype: \"oauth\";\n} & OAuthCredentials;\n\nexport type AuthCredential = ApiKeyCredential | OAuthCredential;\n\nexport type AuthStorageData = Record<string, AuthCredential>;\n\nexport type AuthStatus = {\n\tconfigured: boolean;\n\tsource?: \"stored\" | \"runtime\" | \"environment\" | \"fallback\" | \"models_json_key\" | \"models_json_command\" | \"stale\";\n\tlabel?: string;\n};\n\ntype LockResult<T> = {\n\tresult: T;\n\tnext?: string;\n};\n\ntype ActiveAuthStatusSource = Exclude<NonNullable<AuthStatus[\"source\"]>, \"stale\">;\n\nexport type AuthSourceToken = {\n\tprovider: string;\n\tsource: ActiveAuthStatusSource;\n\tidentityFingerprint: string;\n\tvalueFingerprint: string;\n};\n\ntype AuthSourceCandidate = {\n\tsource: ActiveAuthStatusSource;\n\tconfigured: boolean;\n\tlabel?: string;\n\tidentityFingerprint: string;\n\tvalueFingerprint?: string;\n\tresolveValueFingerprint?: () => string | undefined;\n};\n\ntype AuthApiKeyResult = {\n\tapiKey?: string;\n\tsourceToken?: AuthSourceToken;\n};\n\nexport interface AuthStorageBackend {\n\twithLock<T>(fn: (current: string | undefined) => LockResult<T>): T;\n\twithLockAsync<T>(fn: (current: string | undefined) => Promise<LockResult<T>>): Promise<T>;\n}\n\nexport class FileAuthStorageBackend implements AuthStorageBackend {\n\tconstructor(private authPath: string = join(getAgentDir(), \"auth.json\")) {}\n\n\tprivate ensureParentDir(): void {\n\t\tassertProductStatePath(this.authPath);\n\t\tconst dir = dirname(this.authPath);\n\t\tif (!existsSync(dir)) {\n\t\t\tmkdirSync(dir, { recursive: true, mode: 0o700 });\n\t\t}\n\t}\n\n\tprivate ensureFileExists(): void {\n\t\tif (!existsSync(this.authPath)) {\n\t\t\twriteFileSync(this.authPath, \"{}\", \"utf-8\");\n\t\t\tchmodSync(this.authPath, 0o600);\n\t\t}\n\t}\n\n\tprivate acquireLockSyncWithRetry(path: string): () => void {\n\t\tconst maxAttempts = 10;\n\t\tconst delayMs = 20;\n\t\tlet lastError: unknown;\n\t\tlet compromisedError: Error | undefined;\n\n\t\tfor (let attempt = 1; attempt <= maxAttempts; attempt++) {\n\t\t\ttry {\n\t\t\t\tconst release = lockfile.lockSync(path, {\n\t\t\t\t\trealpath: false,\n\t\t\t\t\tonCompromised: (error) => {\n\t\t\t\t\t\tcompromisedError ??= error;\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tif (compromisedError) {\n\t\t\t\t\trelease();\n\t\t\t\t\tthrow compromisedError;\n\t\t\t\t}\n\t\t\t\treturn release;\n\t\t\t} catch (error) {\n\t\t\t\tif (compromisedError) throw compromisedError;\n\t\t\t\tconst code =\n\t\t\t\t\ttypeof error === \"object\" && error !== null && \"code\" in error\n\t\t\t\t\t\t? String((error as { code?: unknown }).code)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tif (code !== \"ELOCKED\" || attempt === maxAttempts) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tlastError = error;\n\t\t\t\tconst start = Date.now();\n\t\t\t\twhile (Date.now() - start < delayMs) {\n\t\t\t\t\t// Sleep synchronously to avoid changing callers to async.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthrow (lastError as Error) ?? new Error(\"Failed to acquire auth storage lock\");\n\t}\n\n\twithLock<T>(fn: (current: string | undefined) => LockResult<T>): T {\n\t\tthis.ensureParentDir();\n\t\tthis.ensureFileExists();\n\n\t\tlet release: (() => void) | undefined;\n\t\ttry {\n\t\t\trelease = this.acquireLockSyncWithRetry(this.authPath);\n\t\t\tconst current = existsSync(this.authPath) ? readFileSync(this.authPath, \"utf-8\") : undefined;\n\t\t\tconst { result, next } = fn(current);\n\t\t\tif (next !== undefined) {\n\t\t\t\twriteFileSync(this.authPath, next, \"utf-8\");\n\t\t\t\tchmodSync(this.authPath, 0o600);\n\t\t\t}\n\t\t\treturn result;\n\t\t} finally {\n\t\t\tif (release) {\n\t\t\t\trelease();\n\t\t\t}\n\t\t}\n\t}\n\n\tasync withLockAsync<T>(fn: (current: string | undefined) => Promise<LockResult<T>>): Promise<T> {\n\t\tthis.ensureParentDir();\n\t\tthis.ensureFileExists();\n\n\t\tlet release: (() => Promise<void>) | undefined;\n\t\tlet lockCompromised = false;\n\t\tlet lockCompromisedError: Error | undefined;\n\t\tconst throwIfCompromised = () => {\n\t\t\tif (lockCompromised) {\n\t\t\t\tthrow lockCompromisedError ?? new Error(\"Auth storage lock was compromised\");\n\t\t\t}\n\t\t};\n\n\t\ttry {\n\t\t\trelease = await lockfile.lock(this.authPath, {\n\t\t\t\tretries: {\n\t\t\t\t\tretries: 10,\n\t\t\t\t\tfactor: 2,\n\t\t\t\t\tminTimeout: 100,\n\t\t\t\t\tmaxTimeout: 10000,\n\t\t\t\t\trandomize: true,\n\t\t\t\t},\n\t\t\t\tstale: 30000,\n\t\t\t\tonCompromised: (err) => {\n\t\t\t\t\tlockCompromised = true;\n\t\t\t\t\tlockCompromisedError = err;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tthrowIfCompromised();\n\t\t\tconst current = existsSync(this.authPath) ? readFileSync(this.authPath, \"utf-8\") : undefined;\n\t\t\tconst { result, next } = await fn(current);\n\t\t\tthrowIfCompromised();\n\t\t\tif (next !== undefined) {\n\t\t\t\twriteFileSync(this.authPath, next, \"utf-8\");\n\t\t\t\tchmodSync(this.authPath, 0o600);\n\t\t\t}\n\t\t\tthrowIfCompromised();\n\t\t\treturn result;\n\t\t} finally {\n\t\t\tif (release) {\n\t\t\t\tif (lockCompromised) await release().catch(() => undefined);\n\t\t\t\telse await release();\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport class InMemoryAuthStorageBackend implements AuthStorageBackend {\n\tprivate value: string | undefined;\n\n\twithLock<T>(fn: (current: string | undefined) => LockResult<T>): T {\n\t\tconst { result, next } = fn(this.value);\n\t\tif (next !== undefined) {\n\t\t\tthis.value = next;\n\t\t}\n\t\treturn result;\n\t}\n\n\tasync withLockAsync<T>(fn: (current: string | undefined) => Promise<LockResult<T>>): Promise<T> {\n\t\tconst { result, next } = await fn(this.value);\n\t\tif (next !== undefined) {\n\t\t\tthis.value = next;\n\t\t}\n\t\treturn result;\n\t}\n}\n\n/**\n * Credential storage backed by a JSON file.\n */\nexport class AuthStorage {\n\tprivate data: AuthStorageData = {};\n\tprivate runtimeOverrides: Map<string, string> = new Map();\n\tprivate staleAuthSources: Map<string, AuthSourceToken[]> = new Map();\n\tprivate fallbackResolver?: (provider: string) => string | undefined;\n\tprivate loadError: Error | null = null;\n\tprivate errors: Error[] = [];\n\n\tprivate constructor(\n\t\tprivate storage: AuthStorageBackend,\n\t\tprivate readonly existingOpenAICodexSubscription = false,\n\t) {\n\t\tthis.reload();\n\t}\n\n\tstatic create(authPath?: string): AuthStorage {\n\t\treturn new AuthStorage(new FileAuthStorageBackend(authPath ?? join(getAgentDir(), \"auth.json\")));\n\t}\n\n\t/** Reuse an existing host login only through an explicitly read-only backend.\n\t * This SDK mode never logs in, writes credentials, or refreshes tokens.\n\t */\n\tstatic fromStorage(\n\t\tstorage: AuthStorageBackend,\n\t\toptions?: { existingOpenAICodexSubscription?: boolean },\n\t): AuthStorage {\n\t\tconst existing = options?.existingOpenAICodexSubscription === true;\n\t\tif (!existing) return new AuthStorage(storage);\n\t\tif (storage instanceof FileAuthStorageBackend)\n\t\t\tthrow new Error(\"Existing OpenAI subscription requires a read-only auth backend\");\n\t\tconst readOnly: AuthStorageBackend = {\n\t\t\twithLock: (read) =>\n\t\t\t\tstorage.withLock((current) => {\n\t\t\t\t\tconst { result, next } = read(current);\n\t\t\t\t\tif (next !== undefined) throw new Error(\"Existing OpenAI subscription storage is read-only\");\n\t\t\t\t\treturn { result };\n\t\t\t\t}),\n\t\t\t// Refresh happens inside this callback, so never invoke it in this mode.\n\t\t\twithLockAsync: async () => {\n\t\t\t\tthrow new Error(\"Existing OpenAI subscription refresh is disabled\");\n\t\t\t},\n\t\t};\n\t\treturn new AuthStorage(readOnly, true);\n\t}\n\n\tisExistingOpenAICodexSubscription(provider: string): boolean {\n\t\treturn this.existingOpenAICodexSubscription && provider === \"openai-codex\";\n\t}\n\n\tprivate assertWritableStorage(): void {\n\t\tif (this.existingOpenAICodexSubscription) throw new Error(\"Existing OpenAI subscription storage is read-only\");\n\t}\n\n\tstatic inMemory(data: AuthStorageData = {}): AuthStorage {\n\t\tconst storage = new InMemoryAuthStorageBackend();\n\t\tstorage.withLock(() => ({ result: undefined, next: JSON.stringify(data, null, 2) }));\n\t\treturn AuthStorage.fromStorage(storage);\n\t}\n\n\t/**\n\t * Set a runtime API key override (not persisted to disk).\n\t * Used for CLI --api-key flag.\n\t */\n\tsetRuntimeApiKey(provider: string, apiKey: string): void {\n\t\tthis.clearStaleAuthSource(provider, \"runtime\");\n\t\tthis.runtimeOverrides.set(provider, apiKey);\n\t}\n\n\t/**\n\t * Remove a runtime API key override.\n\t */\n\tremoveRuntimeApiKey(provider: string): void {\n\t\tthis.clearStaleAuthSource(provider, \"runtime\");\n\t\tthis.runtimeOverrides.delete(provider);\n\t}\n\n\t/**\n\t * Set a fallback resolver for API keys not found in auth.json or env vars.\n\t * Used for custom provider keys from models.json.\n\t */\n\tsetFallbackResolver(resolver: (provider: string) => string | undefined): void {\n\t\tthis.fallbackResolver = resolver;\n\t}\n\n\tprivate recordError(error: unknown): void {\n\t\tconst normalizedError = error instanceof Error ? error : new Error(String(error));\n\t\tthis.errors.push(normalizedError);\n\t}\n\n\tprivate fingerprintAuthSource(source: ActiveAuthStatusSource, material: string): string {\n\t\tconst digest = createHash(\"sha256\").update(source).update(\"\\0\").update(material).digest(\"hex\");\n\t\treturn `${source}:${digest}`;\n\t}\n\n\tprivate createAuthSourceCandidate(options: {\n\t\tsource: ActiveAuthStatusSource;\n\t\tconfigured: boolean;\n\t\tidentityMaterial: string;\n\t\tvalueMaterial?: string;\n\t\tlabel?: string;\n\t\tresolveValueMaterial?: () => string | undefined;\n\t}): AuthSourceCandidate {\n\t\treturn {\n\t\t\tconfigured: options.configured,\n\t\t\tsource: options.source,\n\t\t\t...(options.label ? { label: options.label } : {}),\n\t\t\tidentityFingerprint: this.fingerprintAuthSource(options.source, `identity:${options.identityMaterial}`),\n\t\t\t...(options.valueMaterial !== undefined\n\t\t\t\t? {\n\t\t\t\t\t\tvalueFingerprint: this.fingerprintAuthSource(\n\t\t\t\t\t\t\toptions.source,\n\t\t\t\t\t\t\t`value:${options.identityMaterial}\\0${options.valueMaterial}`,\n\t\t\t\t\t\t),\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t\t...(options.resolveValueMaterial\n\t\t\t\t? {\n\t\t\t\t\t\tresolveValueFingerprint: () => {\n\t\t\t\t\t\t\tconst valueMaterial = options.resolveValueMaterial?.();\n\t\t\t\t\t\t\treturn valueMaterial === undefined\n\t\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t\t: this.fingerprintAuthSource(\n\t\t\t\t\t\t\t\t\t\toptions.source,\n\t\t\t\t\t\t\t\t\t\t`value:${options.identityMaterial}\\0${valueMaterial}`,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t};\n\t}\n\n\tprivate getStoredCredentialValueMaterial(providerId: string, credential: AuthCredential): string | undefined {\n\t\tif (credential.type === \"api_key\") {\n\t\t\tconst isCommand = credential.key.startsWith(\"!\");\n\t\t\tconst resolvedKey = isCommand\n\t\t\t\t? resolveConfigValueUncached(credential.key)\n\t\t\t\t: resolveConfigValue(credential.key);\n\t\t\tif (resolvedKey !== undefined && !isProviderApiKeyAllowed(providerId, resolvedKey)) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tif (isCommand) {\n\t\t\t\treturn resolvedKey === undefined ? undefined : `api_key:command:${credential.key}\\0${resolvedKey}`;\n\t\t\t}\n\t\t\treturn `api_key:${credential.key}\\0${resolvedKey ?? \"\"}`;\n\t\t}\n\t\tif (this.isExistingOpenAICodexSubscription(providerId))\n\t\t\treturn `oauth:${credential.access}\\0${credential.expires}`;\n\t\tif (getProviderAuthContract(providerId).oauth !== \"supported\") {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst provider = getOAuthProvider(providerId);\n\t\tconst apiKey = provider?.getApiKey(credential) ?? credential.access;\n\t\treturn `oauth:${apiKey}\\0${credential.refresh}\\0${credential.expires}`;\n\t}\n\n\tprivate getRuntimeAuthCandidate(provider: string): AuthSourceCandidate | undefined {\n\t\tconst apiKey = this.runtimeOverrides.get(provider);\n\t\tif (!apiKey || !isProviderApiKeyAllowed(provider, apiKey)) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn {\n\t\t\tlabel: \"--api-key\",\n\t\t\t...this.createAuthSourceCandidate({\n\t\t\t\tconfigured: false,\n\t\t\t\tsource: \"runtime\",\n\t\t\t\tidentityMaterial: provider,\n\t\t\t\tvalueMaterial: apiKey,\n\t\t\t}),\n\t\t};\n\t}\n\n\tprivate getStoredAuthCandidate(\n\t\tprovider: string,\n\t\toptions?: { resolveCommandValue?: boolean; resolvedCommandValue?: string },\n\t): AuthSourceCandidate | undefined {\n\t\tconst credential = this.data[provider];\n\t\tif (\n\t\t\t!credential ||\n\t\t\t(credential.type === \"oauth\" &&\n\t\t\t\tgetProviderAuthContract(provider).oauth !== \"supported\" &&\n\t\t\t\t!this.isExistingOpenAICodexSubscription(provider))\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst isCommandApiKey = credential.type === \"api_key\" && credential.key.startsWith(\"!\");\n\t\tif (credential.type === \"api_key\") {\n\t\t\tconst apiKey =\n\t\t\t\toptions?.resolvedCommandValue ?? (isCommandApiKey ? credential.key : resolveConfigValue(credential.key));\n\t\t\tif (apiKey !== undefined && !isProviderApiKeyAllowed(provider, apiKey)) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}\n\t\tconst identityMaterial = isCommandApiKey ? `api_key:command:${credential.key}` : `${provider}:${credential.type}`;\n\t\tconst commandValueMaterial =\n\t\t\tisCommandApiKey && options?.resolvedCommandValue !== undefined\n\t\t\t\t? `api_key:command:${credential.key}\\0${options.resolvedCommandValue}`\n\t\t\t\t: undefined;\n\t\treturn this.createAuthSourceCandidate({\n\t\t\tconfigured: true,\n\t\t\tsource: \"stored\",\n\t\t\tidentityMaterial,\n\t\t\tvalueMaterial:\n\t\t\t\tcommandValueMaterial ??\n\t\t\t\t(isCommandApiKey && !options?.resolveCommandValue\n\t\t\t\t\t? undefined\n\t\t\t\t\t: this.getStoredCredentialValueMaterial(provider, credential)),\n\t\t\tresolveValueMaterial: isCommandApiKey\n\t\t\t\t? () => this.getStoredCredentialValueMaterial(provider, credential)\n\t\t\t\t: undefined,\n\t\t});\n\t}\n\n\tprivate getEnvironmentApiKey(provider: string): string | undefined {\n\t\tconst apiKey = getEnvApiKey(provider);\n\t\treturn apiKey && isProviderApiKeyAllowed(provider, apiKey) ? apiKey : undefined;\n\t}\n\n\tprivate getEnvironmentAuthCandidate(provider: string): AuthSourceCandidate | undefined {\n\t\tconst envKeys = findEnvKeys(provider);\n\t\tconst envKey = envKeys?.[0];\n\t\tconst apiKey = this.getEnvironmentApiKey(provider);\n\t\tif (!apiKey) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst label = envKey ?? \"ambient credentials\";\n\t\tconst identityMaterial = envKey ?? this.getAmbientEnvironmentIdentityMaterial(provider);\n\t\treturn this.createAuthSourceCandidate({\n\t\t\tconfigured: false,\n\t\t\tsource: \"environment\",\n\t\t\tlabel,\n\t\t\tidentityMaterial,\n\t\t\tvalueMaterial: `${identityMaterial}\\0${apiKey}`,\n\t\t});\n\t}\n\n\tprivate getAmbientEnvironmentIdentityMaterial(provider: string): string {\n\t\tif (provider === \"amazon-bedrock\") {\n\t\t\tif (process.env.AWS_PROFILE) return `amazon-bedrock:profile:${process.env.AWS_PROFILE}`;\n\t\t\tif (process.env.AWS_ACCESS_KEY_ID) {\n\t\t\t\treturn `amazon-bedrock:access-key:${process.env.AWS_ACCESS_KEY_ID}:${process.env.AWS_SECRET_ACCESS_KEY ?? \"\"}:${process.env.AWS_SESSION_TOKEN ?? \"\"}`;\n\t\t\t}\n\t\t\tif (process.env.AWS_BEARER_TOKEN_BEDROCK) {\n\t\t\t\treturn `amazon-bedrock:bearer:${process.env.AWS_BEARER_TOKEN_BEDROCK}`;\n\t\t\t}\n\t\t\tif (process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI) {\n\t\t\t\treturn `amazon-bedrock:ecs-relative:${process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI}`;\n\t\t\t}\n\t\t\tif (process.env.AWS_CONTAINER_CREDENTIALS_FULL_URI) {\n\t\t\t\treturn `amazon-bedrock:ecs-full:${process.env.AWS_CONTAINER_CREDENTIALS_FULL_URI}`;\n\t\t\t}\n\t\t\tif (process.env.AWS_WEB_IDENTITY_TOKEN_FILE) {\n\t\t\t\treturn `amazon-bedrock:web-identity:${process.env.AWS_WEB_IDENTITY_TOKEN_FILE}`;\n\t\t\t}\n\t\t}\n\t\tif (provider === \"google-vertex\") {\n\t\t\tconst project = process.env.GOOGLE_CLOUD_PROJECT ?? process.env.GCLOUD_PROJECT ?? \"\";\n\t\t\tconst location = process.env.GOOGLE_CLOUD_LOCATION ?? \"\";\n\t\t\tconst credentialsPath = process.env.GOOGLE_APPLICATION_CREDENTIALS ?? \"application-default\";\n\t\t\treturn `google-vertex:${project}:${location}:${credentialsPath}`;\n\t\t}\n\t\treturn provider;\n\t}\n\n\tprivate getFallbackAuthCandidate(provider: string): AuthSourceCandidate | undefined {\n\t\tconst apiKey = this.fallbackResolver?.(provider);\n\t\tif (!apiKey || !isProviderApiKeyAllowed(provider, apiKey)) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this.createAuthSourceCandidate({\n\t\t\tconfigured: false,\n\t\t\tsource: \"fallback\",\n\t\t\tlabel: \"custom provider config\",\n\t\t\tidentityMaterial: provider,\n\t\t\tvalueMaterial: apiKey,\n\t\t});\n\t}\n\n\tprivate getAuthSourceCandidates(provider: string, options?: { includeFallback?: boolean }): AuthSourceCandidate[] {\n\t\tconst fallbackCandidate =\n\t\t\toptions?.includeFallback === false ? undefined : this.getFallbackAuthCandidate(provider);\n\t\tconst candidates = [\n\t\t\tthis.getRuntimeAuthCandidate(provider),\n\t\t\tthis.getStoredAuthCandidate(provider),\n\t\t\tthis.getEnvironmentAuthCandidate(provider),\n\t\t\tfallbackCandidate,\n\t\t];\n\t\treturn candidates.filter((candidate): candidate is AuthSourceCandidate => candidate !== undefined);\n\t}\n\n\tprivate isAuthSourceStale(provider: string, candidate: AuthSourceCandidate): boolean {\n\t\tconst matchingStale = this.getMatchingStaleAuthSources(provider, candidate);\n\t\tif (matchingStale.length === 0) {\n\t\t\treturn false;\n\t\t}\n\t\tconst valueFingerprint = candidate.valueFingerprint ?? candidate.resolveValueFingerprint?.();\n\t\treturn Boolean(valueFingerprint && matchingStale.some((token) => token.valueFingerprint === valueFingerprint));\n\t}\n\n\tprivate getMatchingStaleAuthSources(provider: string, candidate: AuthSourceCandidate): AuthSourceToken[] {\n\t\tconst stale = this.staleAuthSources.get(provider);\n\t\tif (!stale) {\n\t\t\treturn [];\n\t\t}\n\t\treturn stale.filter(\n\t\t\t(token) => token.source === candidate.source && token.identityFingerprint === candidate.identityFingerprint,\n\t\t);\n\t}\n\n\tprivate getAvailableAuthCandidate(\n\t\tprovider: string,\n\t\toptions?: { includeFallback?: boolean },\n\t): { candidate?: AuthSourceCandidate; hasStaleCandidate: boolean } {\n\t\tlet hasStaleCandidate = false;\n\t\tfor (const candidate of this.getAuthSourceCandidates(provider, options)) {\n\t\t\tif (this.isAuthSourceStale(provider, candidate)) {\n\t\t\t\thasStaleCandidate = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\treturn { candidate, hasStaleCandidate };\n\t\t}\n\t\treturn { hasStaleCandidate };\n\t}\n\n\tprivate toAuthStatus(candidate: AuthSourceCandidate): AuthStatus {\n\t\treturn {\n\t\t\tconfigured: candidate.configured,\n\t\t\tsource: candidate.source,\n\t\t\t...(candidate.label ? { label: candidate.label } : {}),\n\t\t};\n\t}\n\n\tprivate getAuthStatusFromCandidates(provider: string): AuthStatus {\n\t\tconst { candidate, hasStaleCandidate } = this.getAvailableAuthCandidate(provider);\n\t\tif (candidate) {\n\t\t\treturn this.toAuthStatus(candidate);\n\t\t}\n\t\tif (hasStaleCandidate) {\n\t\t\treturn { configured: false, source: \"stale\", label: \"expired\" };\n\t\t}\n\t\treturn { configured: false };\n\t}\n\n\tmarkAuthStale(provider: string): boolean {\n\t\tconst token = this.getCurrentAuthSourceToken(provider);\n\t\treturn token ? this.markAuthSourceStale(token) : false;\n\t}\n\n\tprivate getAuthSourceTokenForCandidate(\n\t\tprovider: string,\n\t\tcandidate: AuthSourceCandidate,\n\t): AuthSourceToken | undefined {\n\t\tconst valueFingerprint = candidate.valueFingerprint ?? candidate.resolveValueFingerprint?.();\n\t\tif (!valueFingerprint) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn {\n\t\t\tprovider,\n\t\t\tsource: candidate.source,\n\t\t\tidentityFingerprint: candidate.identityFingerprint,\n\t\t\tvalueFingerprint,\n\t\t};\n\t}\n\n\tgetCurrentAuthSourceToken(provider: string): AuthSourceToken | undefined {\n\t\tconst { candidate } = this.getAvailableAuthCandidate(provider);\n\t\tif (!candidate) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this.getAuthSourceTokenForCandidate(provider, candidate);\n\t}\n\n\tmarkAuthSourceStale(token: AuthSourceToken): boolean {\n\t\tif (token.provider.length === 0) {\n\t\t\treturn false;\n\t\t}\n\t\tconst stale = this.staleAuthSources.get(token.provider) ?? [];\n\t\tif (\n\t\t\t!stale.some(\n\t\t\t\t(existing) =>\n\t\t\t\t\texisting.source === token.source &&\n\t\t\t\t\texisting.identityFingerprint === token.identityFingerprint &&\n\t\t\t\t\texisting.valueFingerprint === token.valueFingerprint,\n\t\t\t)\n\t\t) {\n\t\t\tstale.push(token);\n\t\t}\n\t\tthis.staleAuthSources.set(token.provider, stale);\n\t\treturn true;\n\t}\n\n\tprivate clearStaleAuthSource(provider: string, source: ActiveAuthStatusSource): void {\n\t\tconst stale = this.staleAuthSources.get(provider);\n\t\tif (!stale) {\n\t\t\treturn;\n\t\t}\n\t\tconst next = stale.filter((token) => token.source !== source);\n\t\tif (next.length === 0) {\n\t\t\tthis.staleAuthSources.delete(provider);\n\t\t} else {\n\t\t\tthis.staleAuthSources.set(provider, next);\n\t\t}\n\t}\n\n\tprivate parseStorageData(content: string | undefined): AuthStorageData {\n\t\tif (!content) {\n\t\t\treturn {};\n\t\t}\n\t\treturn JSON.parse(content) as AuthStorageData;\n\t}\n\n\t/**\n\t * Reload credentials from storage.\n\t */\n\treload(): void {\n\t\tlet content: string | undefined;\n\t\ttry {\n\t\t\tthis.storage.withLock((current) => {\n\t\t\t\tcontent = current;\n\t\t\t\treturn { result: undefined };\n\t\t\t});\n\t\t\tthis.data = this.parseStorageData(content);\n\t\t\tthis.loadError = null;\n\t\t} catch (error) {\n\t\t\tthis.loadError = error as Error;\n\t\t\tthis.recordError(error);\n\t\t}\n\t}\n\n\tprivate persistProviderChange(provider: string, credential: AuthCredential | undefined): void {\n\t\tif (this.loadError) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tthis.storage.withLock((current) => {\n\t\t\t\tconst currentData = this.parseStorageData(current);\n\t\t\t\tconst merged: AuthStorageData = { ...currentData };\n\t\t\t\tif (credential) {\n\t\t\t\t\tmerged[provider] = credential;\n\t\t\t\t} else {\n\t\t\t\t\tdelete merged[provider];\n\t\t\t\t}\n\t\t\t\treturn { result: undefined, next: JSON.stringify(merged, null, 2) };\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthis.recordError(error);\n\t\t}\n\t}\n\n\t/**\n\t * Get credential for a provider.\n\t */\n\tget(provider: string): AuthCredential | undefined {\n\t\treturn this.data[provider] ?? undefined;\n\t}\n\n\t/**\n\t * Set credential for a provider.\n\t */\n\tset(provider: string, credential: AuthCredential): void {\n\t\tthis.assertWritableStorage();\n\t\tthis.clearStaleAuthSource(provider, \"stored\");\n\t\tthis.data[provider] = credential;\n\t\tthis.persistProviderChange(provider, credential);\n\t}\n\n\t/**\n\t * Remove credential for a provider.\n\t */\n\tremove(provider: string): void {\n\t\tthis.assertWritableStorage();\n\t\tthis.clearStaleAuthSource(provider, \"stored\");\n\t\tdelete this.data[provider];\n\t\tthis.persistProviderChange(provider, undefined);\n\t}\n\n\t/**\n\t * Remove a provider's credential with the disk write verified: throws on any\n\t * load or write failure instead of recording it, so callers can refuse to\n\t * proceed while the credential may still exist on disk. Disk-authoritative\n\t * and idempotent — in-memory state is only updated after the write succeeds.\n\t */\n\tremoveVerified(provider: string): void {\n\t\tthis.assertWritableStorage();\n\t\tthis.storage.withLock((current) => {\n\t\t\tconst currentData = this.parseStorageData(current);\n\t\t\tif (!(provider in currentData)) return { result: undefined };\n\t\t\tconst merged: AuthStorageData = { ...currentData };\n\t\t\tdelete merged[provider];\n\t\t\treturn { result: undefined, next: JSON.stringify(merged, null, 2) };\n\t\t});\n\t\tdelete this.data[provider];\n\t\t// Post-success only: a failed removal must not make a stale-marked credential selectable again.\n\t\tthis.clearStaleAuthSource(provider, \"stored\");\n\t}\n\n\t/**\n\t * List all providers with credentials.\n\t */\n\tlist(): string[] {\n\t\treturn Object.keys(this.data);\n\t}\n\n\t/**\n\t * Check if credentials exist for a provider in auth.json.\n\t */\n\thas(provider: string): boolean {\n\t\treturn provider in this.data;\n\t}\n\n\t/**\n\t * Check if any form of auth is configured for a provider.\n\t * Unlike getApiKey(), this doesn't refresh OAuth tokens.\n\t */\n\thasAuth(provider: string): boolean {\n\t\treturn this.getAvailableAuthCandidate(provider).candidate !== undefined;\n\t}\n\n\t/**\n\t * Return auth status without exposing credential values or refreshing tokens.\n\t */\n\tgetAuthStatus(provider: string): AuthStatus {\n\t\treturn this.getAuthStatusFromCandidates(provider);\n\t}\n\n\t/**\n\t * Get all credentials (for passing to getOAuthApiKey).\n\t */\n\tgetAll(): AuthStorageData {\n\t\treturn { ...this.data };\n\t}\n\n\tdrainErrors(): Error[] {\n\t\tconst drained = [...this.errors];\n\t\tthis.errors = [];\n\t\treturn drained;\n\t}\n\n\t/**\n\t * Login to an OAuth provider.\n\t */\n\tasync login(providerId: OAuthProviderId, callbacks: OAuthLoginCallbacks): Promise<void> {\n\t\tthis.assertWritableStorage();\n\t\tconst contract = getProviderAuthContract(providerId);\n\t\tif (contract.oauth !== \"supported\") {\n\t\t\tthrow new Error(contract.guidance);\n\t\t}\n\t\tconst provider = getOAuthProvider(providerId);\n\t\tif (!provider) {\n\t\t\tthrow new Error(`Unknown OAuth provider: ${providerId}`);\n\t\t}\n\n\t\tconst credentials = await provider.login(callbacks);\n\t\tthis.set(providerId, { type: \"oauth\", ...credentials });\n\t}\n\n\t/**\n\t * Logout from a provider.\n\t */\n\tlogout(provider: string): void {\n\t\tthis.remove(provider);\n\t}\n\n\t/**\n\t * Refresh OAuth token with backend locking to prevent race conditions.\n\t * Multiple pi instances may try to refresh simultaneously when tokens expire.\n\t */\n\tprivate async refreshOAuthTokenWithLock(\n\t\tproviderId: OAuthProviderId,\n\t): Promise<{ apiKey: string; newCredentials: OAuthCredentials } | null> {\n\t\tif (getProviderAuthContract(providerId).oauth !== \"supported\") {\n\t\t\treturn null;\n\t\t}\n\t\tconst provider = getOAuthProvider(providerId);\n\t\tif (!provider) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst result = await this.storage.withLockAsync(async (current) => {\n\t\t\tconst currentData = this.parseStorageData(current);\n\t\t\tthis.data = currentData;\n\t\t\tthis.loadError = null;\n\n\t\t\tconst cred = currentData[providerId];\n\t\t\tif (cred?.type !== \"oauth\" || getProviderAuthContract(providerId).oauth !== \"supported\") {\n\t\t\t\treturn { result: null };\n\t\t\t}\n\n\t\t\tif (Date.now() < cred.expires) {\n\t\t\t\treturn { result: { apiKey: provider.getApiKey(cred), newCredentials: cred } };\n\t\t\t}\n\n\t\t\tconst oauthCreds: Record<string, OAuthCredentials> = {};\n\t\t\tfor (const [key, value] of Object.entries(currentData)) {\n\t\t\t\tif (value.type === \"oauth\") {\n\t\t\t\t\toauthCreds[key] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst refreshed = await getOAuthApiKey(providerId, oauthCreds);\n\t\t\tif (!refreshed) {\n\t\t\t\treturn { result: null };\n\t\t\t}\n\n\t\t\tconst merged: AuthStorageData = {\n\t\t\t\t...currentData,\n\t\t\t\t[providerId]: { type: \"oauth\", ...refreshed.newCredentials },\n\t\t\t};\n\t\t\tthis.data = merged;\n\t\t\tthis.loadError = null;\n\t\t\treturn { result: refreshed, next: JSON.stringify(merged, null, 2) };\n\t\t});\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Get API key for a provider.\n\t * Priority:\n\t * 1. Runtime override (CLI --api-key)\n\t * 2. auth.json\n\t * 3. Environment variable\n\t * 4. Fallback resolver (models.json custom providers)\n\t */\n\tasync getApiKeyWithSourceToken(\n\t\tproviderId: string,\n\t\toptions?: { includeFallback?: boolean },\n\t): Promise<AuthApiKeyResult> {\n\t\tif (this.isExistingOpenAICodexSubscription(providerId)) {\n\t\t\tif (this.runtimeOverrides.has(providerId))\n\t\t\t\tthrow new Error(\"Existing OpenAI subscription does not accept API-key overrides\");\n\t\t\tconst credential = this.data[providerId];\n\t\t\tif (\n\t\t\t\t!credential ||\n\t\t\t\tcredential.type !== \"oauth\" ||\n\t\t\t\ttypeof credential.access !== \"string\" ||\n\t\t\t\t!credential.access ||\n\t\t\t\t!Number.isFinite(credential.expires)\n\t\t\t)\n\t\t\t\tthrow new Error(\"Existing OpenAI subscription credential is unavailable\");\n\t\t\tif (Date.now() >= credential.expires) throw new Error(\"Existing OpenAI subscription credential has expired\");\n\t\t\tconst candidate = this.getStoredAuthCandidate(providerId);\n\t\t\tif (!candidate || this.isAuthSourceStale(providerId, candidate))\n\t\t\t\tthrow new Error(\"Existing OpenAI subscription credential is unavailable\");\n\t\t\treturn {\n\t\t\t\tapiKey: credential.access,\n\t\t\t\tsourceToken: this.getAuthSourceTokenForCandidate(providerId, candidate),\n\t\t\t};\n\t\t}\n\n\t\t// Runtime overrides take precedence over stored credentials and environment keys.\n\t\tconst runtimeCandidate = this.getRuntimeAuthCandidate(providerId);\n\t\tconst runtimeKey = this.runtimeOverrides.get(providerId);\n\t\tif (runtimeKey && runtimeCandidate && !this.isAuthSourceStale(providerId, runtimeCandidate)) {\n\t\t\treturn {\n\t\t\t\tapiKey: runtimeKey,\n\t\t\t\tsourceToken: this.getAuthSourceTokenForCandidate(providerId, runtimeCandidate),\n\t\t\t};\n\t\t}\n\n\t\tconst cred = this.data[providerId];\n\n\t\tif (cred?.type === \"api_key\") {\n\t\t\tconst storedCandidate = this.getStoredAuthCandidate(providerId);\n\t\t\tif (storedCandidate && !this.isAuthSourceStale(providerId, storedCandidate)) {\n\t\t\t\tconst hasStaleRecord = this.getMatchingStaleAuthSources(providerId, storedCandidate).length > 0;\n\t\t\t\tconst apiKey =\n\t\t\t\t\tcred.key.startsWith(\"!\") && hasStaleRecord\n\t\t\t\t\t\t? resolveConfigValueUncached(cred.key)\n\t\t\t\t\t\t: resolveConfigValue(cred.key);\n\t\t\t\tif (apiKey === undefined || isProviderApiKeyAllowed(providerId, apiKey)) {\n\t\t\t\t\tconst sourceToken =\n\t\t\t\t\t\tapiKey === undefined\n\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t: this.getAuthSourceTokenForCandidate(\n\t\t\t\t\t\t\t\t\tproviderId,\n\t\t\t\t\t\t\t\t\tcred.key.startsWith(\"!\")\n\t\t\t\t\t\t\t\t\t\t? (this.getStoredAuthCandidate(providerId, { resolvedCommandValue: apiKey }) ??\n\t\t\t\t\t\t\t\t\t\t\t\tstoredCandidate)\n\t\t\t\t\t\t\t\t\t\t: storedCandidate,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\treturn { apiKey, sourceToken };\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (cred?.type === \"oauth\" && getProviderAuthContract(providerId).oauth === \"supported\") {\n\t\t\tconst storedCandidate = this.getStoredAuthCandidate(providerId);\n\t\t\tif (storedCandidate && !this.isAuthSourceStale(providerId, storedCandidate)) {\n\t\t\t\tconst provider = getOAuthProvider(providerId);\n\t\t\t\tif (!provider) {\n\t\t\t\t\treturn {};\n\t\t\t\t}\n\t\t\t\t// Lock refreshes so concurrent instances cannot race on the credential file.\n\t\t\t\tconst needsRefresh = Date.now() >= cred.expires;\n\n\t\t\t\tif (needsRefresh) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await this.refreshOAuthTokenWithLock(providerId);\n\t\t\t\t\t\tif (result) {\n\t\t\t\t\t\t\tconst refreshedCandidate = this.getStoredAuthCandidate(providerId);\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tapiKey: result.apiKey,\n\t\t\t\t\t\t\t\tsourceToken: refreshedCandidate\n\t\t\t\t\t\t\t\t\t? this.getAuthSourceTokenForCandidate(providerId, refreshedCandidate)\n\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tthis.recordError(error);\n\t\t\t\t\t\t// A peer may have refreshed successfully; reload before treating this refresh as failed.\n\t\t\t\t\t\tthis.reload();\n\t\t\t\t\t\tconst updatedCred = this.data[providerId];\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tupdatedCred?.type === \"oauth\" &&\n\t\t\t\t\t\t\tgetProviderAuthContract(providerId).oauth === \"supported\" &&\n\t\t\t\t\t\t\tDate.now() < updatedCred.expires\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tconst updatedCandidate = this.getStoredAuthCandidate(providerId);\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tapiKey: provider.getApiKey(updatedCred),\n\t\t\t\t\t\t\t\tsourceToken: updatedCandidate\n\t\t\t\t\t\t\t\t\t? this.getAuthSourceTokenForCandidate(providerId, updatedCandidate)\n\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Preserve credentials for a later /login retry while discovery skips this provider.\n\t\t\t\t\t\treturn {};\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tapiKey: provider.getApiKey(cred),\n\t\t\t\t\t\tsourceToken: this.getAuthSourceTokenForCandidate(providerId, storedCandidate),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst envCandidate = this.getEnvironmentAuthCandidate(providerId);\n\t\tconst envKey = this.getEnvironmentApiKey(providerId);\n\t\tif (envKey && envCandidate && !this.isAuthSourceStale(providerId, envCandidate)) {\n\t\t\treturn {\n\t\t\t\tapiKey: envKey,\n\t\t\t\tsourceToken: this.getAuthSourceTokenForCandidate(providerId, envCandidate),\n\t\t\t};\n\t\t}\n\t\tif (options?.includeFallback !== false) {\n\t\t\tconst fallbackCandidate = this.getFallbackAuthCandidate(providerId);\n\t\t\tif (fallbackCandidate && !this.isAuthSourceStale(providerId, fallbackCandidate)) {\n\t\t\t\tconst apiKey = this.fallbackResolver?.(providerId) ?? undefined;\n\t\t\t\tif (apiKey === undefined || isProviderApiKeyAllowed(providerId, apiKey)) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tapiKey,\n\t\t\t\t\t\tsourceToken: this.getAuthSourceTokenForCandidate(providerId, fallbackCandidate),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {};\n\t}\n\n\tasync getApiKey(providerId: string, options?: { includeFallback?: boolean }): Promise<string | undefined> {\n\t\tconst result = await this.getApiKeyWithSourceToken(providerId, options);\n\t\treturn result.apiKey;\n\t}\n\n\t/**\n\t * Get supported registered OAuth providers. Read-only SDK storage cannot log in.\n\t */\n\tgetOAuthProviders() {\n\t\tif (this.existingOpenAICodexSubscription) return [];\n\t\treturn getOAuthProviders().filter((provider) => getProviderAuthContract(provider.id).oauth === \"supported\");\n\t}\n}\n"]}
1
+ {"version":3,"file":"auth-storage.js","sourceRoot":"","sources":["../../src/core/auth-storage.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Credential storage for API keys and OAuth tokens.\n * Handles loading, saving, and refreshing credentials from auth.json.\n *\n * Uses file locking to prevent race conditions when multiple pi instances\n * try to refresh tokens simultaneously.\n */\n\nimport { createHash, randomUUID } from \"node:crypto\";\nimport {\n\tfindEnvKeys,\n\tgetEnvApiKey,\n\ttype OAuthCredentials,\n\ttype OAuthLoginCallbacks,\n\ttype OAuthProviderId,\n} from \"@ponythewhite/base-context-ai\";\nimport { getOAuthApiKey, getOAuthProvider, getOAuthProviders } from \"@ponythewhite/base-context-ai/oauth\";\nimport { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\nimport lockfile from \"proper-lockfile\";\nimport { getAgentDir } from \"../config.js\";\nimport { assertProductStatePath } from \"../runtime-paths.js\";\nimport { getProviderAuthContract, isProviderApiKeyAllowed } from \"./provider-contracts.js\";\nimport { resolveConfigValue, resolveConfigValueUncached } from \"./resolve-config-value.js\";\n\nexport type ApiKeyCredential = {\n\ttype: \"api_key\";\n\tkey: string;\n};\n\nexport type OAuthCredential = {\n\ttype: \"oauth\";\n} & OAuthCredentials;\n\nexport type AuthCredential = ApiKeyCredential | OAuthCredential;\n\nexport type AuthStorageData = Record<string, AuthCredential>;\n\nexport type AuthStatus = {\n\tconfigured: boolean;\n\tsource?: \"stored\" | \"runtime\" | \"environment\" | \"fallback\" | \"models_json_key\" | \"models_json_command\" | \"stale\";\n\tlabel?: string;\n};\n\ntype LockResult<T> = {\n\tresult: T;\n\tnext?: string;\n};\n\n// Only active login ownership is persisted; it is not a credential or a history.\ntype AuthStorageState = {\n\tcredentials: AuthStorageData;\n\tloginAttempts: Record<string, string>;\n};\n\ntype ActiveAuthStatusSource = Exclude<NonNullable<AuthStatus[\"source\"]>, \"stale\">;\n\nexport type AuthSourceToken = {\n\tprovider: string;\n\tsource: ActiveAuthStatusSource;\n\tidentityFingerprint: string;\n\tvalueFingerprint: string;\n};\n\ntype AuthSourceCandidate = {\n\tsource: ActiveAuthStatusSource;\n\tconfigured: boolean;\n\tlabel?: string;\n\tidentityFingerprint: string;\n\tvalueFingerprint?: string;\n\tresolveValueFingerprint?: () => string | undefined;\n};\n\ntype AuthApiKeyResult = {\n\tapiKey?: string;\n\tsourceToken?: AuthSourceToken;\n};\n\nexport interface AuthStorageBackend {\n\twithLock<T>(fn: (current: string | undefined) => LockResult<T>): T;\n\twithLockAsync<T>(fn: (current: string | undefined) => Promise<LockResult<T>>): Promise<T>;\n}\n\nexport class FileAuthStorageBackend implements AuthStorageBackend {\n\tconstructor(private authPath: string = join(getAgentDir(), \"auth.json\")) {}\n\n\tprivate ensureParentDir(): void {\n\t\tassertProductStatePath(this.authPath);\n\t\tconst dir = dirname(this.authPath);\n\t\tif (!existsSync(dir)) {\n\t\t\tmkdirSync(dir, { recursive: true, mode: 0o700 });\n\t\t}\n\t}\n\n\tprivate ensureFileExists(): void {\n\t\tif (!existsSync(this.authPath)) {\n\t\t\twriteFileSync(this.authPath, \"{}\", \"utf-8\");\n\t\t\tchmodSync(this.authPath, 0o600);\n\t\t}\n\t}\n\n\tprivate acquireLockSyncWithRetry(path: string): () => void {\n\t\tconst maxAttempts = 10;\n\t\tconst delayMs = 20;\n\t\tlet lastError: unknown;\n\t\tlet compromisedError: Error | undefined;\n\n\t\tfor (let attempt = 1; attempt <= maxAttempts; attempt++) {\n\t\t\ttry {\n\t\t\t\tconst release = lockfile.lockSync(path, {\n\t\t\t\t\trealpath: false,\n\t\t\t\t\tonCompromised: (error) => {\n\t\t\t\t\t\tcompromisedError ??= error;\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tif (compromisedError) {\n\t\t\t\t\trelease();\n\t\t\t\t\tthrow compromisedError;\n\t\t\t\t}\n\t\t\t\treturn release;\n\t\t\t} catch (error) {\n\t\t\t\tif (compromisedError) throw compromisedError;\n\t\t\t\tconst code =\n\t\t\t\t\ttypeof error === \"object\" && error !== null && \"code\" in error\n\t\t\t\t\t\t? String((error as { code?: unknown }).code)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tif (code !== \"ELOCKED\" || attempt === maxAttempts) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tlastError = error;\n\t\t\t\tconst start = Date.now();\n\t\t\t\twhile (Date.now() - start < delayMs) {\n\t\t\t\t\t// Sleep synchronously to avoid changing callers to async.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthrow (lastError as Error) ?? new Error(\"Failed to acquire auth storage lock\");\n\t}\n\n\twithLock<T>(fn: (current: string | undefined) => LockResult<T>): T {\n\t\tthis.ensureParentDir();\n\t\tthis.ensureFileExists();\n\n\t\tlet release: (() => void) | undefined;\n\t\ttry {\n\t\t\trelease = this.acquireLockSyncWithRetry(this.authPath);\n\t\t\tconst current = existsSync(this.authPath) ? readFileSync(this.authPath, \"utf-8\") : undefined;\n\t\t\tconst { result, next } = fn(current);\n\t\t\tif (next !== undefined) {\n\t\t\t\twriteFileSync(this.authPath, next, \"utf-8\");\n\t\t\t\tchmodSync(this.authPath, 0o600);\n\t\t\t}\n\t\t\treturn result;\n\t\t} finally {\n\t\t\tif (release) {\n\t\t\t\trelease();\n\t\t\t}\n\t\t}\n\t}\n\n\tasync withLockAsync<T>(fn: (current: string | undefined) => Promise<LockResult<T>>): Promise<T> {\n\t\tthis.ensureParentDir();\n\t\tthis.ensureFileExists();\n\n\t\tlet release: (() => Promise<void>) | undefined;\n\t\tlet lockCompromised = false;\n\t\tlet lockCompromisedError: Error | undefined;\n\t\tconst throwIfCompromised = () => {\n\t\t\tif (lockCompromised) {\n\t\t\t\tthrow lockCompromisedError ?? new Error(\"Auth storage lock was compromised\");\n\t\t\t}\n\t\t};\n\n\t\ttry {\n\t\t\trelease = await lockfile.lock(this.authPath, {\n\t\t\t\tretries: {\n\t\t\t\t\tretries: 10,\n\t\t\t\t\tfactor: 2,\n\t\t\t\t\tminTimeout: 100,\n\t\t\t\t\tmaxTimeout: 10000,\n\t\t\t\t\trandomize: true,\n\t\t\t\t},\n\t\t\t\tstale: 30000,\n\t\t\t\tonCompromised: (err) => {\n\t\t\t\t\tlockCompromised = true;\n\t\t\t\t\tlockCompromisedError = err;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tthrowIfCompromised();\n\t\t\tconst current = existsSync(this.authPath) ? readFileSync(this.authPath, \"utf-8\") : undefined;\n\t\t\tconst { result, next } = await fn(current);\n\t\t\tthrowIfCompromised();\n\t\t\tif (next !== undefined) {\n\t\t\t\twriteFileSync(this.authPath, next, \"utf-8\");\n\t\t\t\tchmodSync(this.authPath, 0o600);\n\t\t\t}\n\t\t\tthrowIfCompromised();\n\t\t\treturn result;\n\t\t} finally {\n\t\t\tif (release) {\n\t\t\t\tif (lockCompromised) await release().catch(() => undefined);\n\t\t\t\telse await release();\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport class InMemoryAuthStorageBackend implements AuthStorageBackend {\n\tprivate value: string | undefined;\n\n\twithLock<T>(fn: (current: string | undefined) => LockResult<T>): T {\n\t\tconst { result, next } = fn(this.value);\n\t\tif (next !== undefined) {\n\t\t\tthis.value = next;\n\t\t}\n\t\treturn result;\n\t}\n\n\tasync withLockAsync<T>(fn: (current: string | undefined) => Promise<LockResult<T>>): Promise<T> {\n\t\tconst { result, next } = await fn(this.value);\n\t\tif (next !== undefined) {\n\t\t\tthis.value = next;\n\t\t}\n\t\treturn result;\n\t}\n}\n\n/**\n * Credential storage backed by a JSON file.\n */\nexport class AuthStorage {\n\tprivate data: AuthStorageData = {};\n\tprivate runtimeOverrides: Map<string, string> = new Map();\n\tprivate staleAuthSources: Map<string, AuthSourceToken[]> = new Map();\n\tprivate fallbackResolver?: (provider: string) => string | undefined;\n\tprivate loadError: Error | null = null;\n\tprivate errors: Error[] = [];\n\n\tprivate constructor(\n\t\tprivate storage: AuthStorageBackend,\n\t\tprivate readonly existingOpenAICodexSubscription = false,\n\t) {\n\t\tthis.reload();\n\t}\n\n\tstatic create(authPath?: string): AuthStorage {\n\t\treturn new AuthStorage(new FileAuthStorageBackend(authPath ?? join(getAgentDir(), \"auth.json\")));\n\t}\n\n\t/** Reuse an existing host login only through an explicitly read-only backend.\n\t * This SDK mode never logs in, writes credentials, or refreshes tokens.\n\t */\n\tstatic fromStorage(\n\t\tstorage: AuthStorageBackend,\n\t\toptions?: { existingOpenAICodexSubscription?: boolean },\n\t): AuthStorage {\n\t\tconst existing = options?.existingOpenAICodexSubscription === true;\n\t\tif (!existing) return new AuthStorage(storage);\n\t\tif (storage instanceof FileAuthStorageBackend)\n\t\t\tthrow new Error(\"Existing OpenAI subscription requires a read-only auth backend\");\n\t\tconst readOnly: AuthStorageBackend = {\n\t\t\twithLock: (read) =>\n\t\t\t\tstorage.withLock((current) => {\n\t\t\t\t\tconst { result, next } = read(current);\n\t\t\t\t\tif (next !== undefined) throw new Error(\"Existing OpenAI subscription storage is read-only\");\n\t\t\t\t\treturn { result };\n\t\t\t\t}),\n\t\t\t// Refresh happens inside this callback, so never invoke it in this mode.\n\t\t\twithLockAsync: async () => {\n\t\t\t\tthrow new Error(\"Existing OpenAI subscription refresh is disabled\");\n\t\t\t},\n\t\t};\n\t\treturn new AuthStorage(readOnly, true);\n\t}\n\n\tisExistingOpenAICodexSubscription(provider: string): boolean {\n\t\treturn this.existingOpenAICodexSubscription && provider === \"openai-codex\";\n\t}\n\n\tprivate assertWritableStorage(): void {\n\t\tif (this.existingOpenAICodexSubscription) throw new Error(\"Existing OpenAI subscription storage is read-only\");\n\t}\n\n\tstatic inMemory(data: AuthStorageData = {}): AuthStorage {\n\t\tconst storage = new InMemoryAuthStorageBackend();\n\t\tstorage.withLock(() => ({ result: undefined, next: JSON.stringify(data, null, 2) }));\n\t\treturn AuthStorage.fromStorage(storage);\n\t}\n\n\t/**\n\t * Set a runtime API key override (not persisted to disk).\n\t * Used for CLI --api-key flag.\n\t */\n\tsetRuntimeApiKey(provider: string, apiKey: string): void {\n\t\tthis.clearStaleAuthSource(provider, \"runtime\");\n\t\tthis.runtimeOverrides.set(provider, apiKey);\n\t}\n\n\t/**\n\t * Remove a runtime API key override.\n\t */\n\tremoveRuntimeApiKey(provider: string): void {\n\t\tthis.clearStaleAuthSource(provider, \"runtime\");\n\t\tthis.runtimeOverrides.delete(provider);\n\t}\n\n\t/**\n\t * Set a fallback resolver for API keys not found in auth.json or env vars.\n\t * Used for custom provider keys from models.json.\n\t */\n\tsetFallbackResolver(resolver: (provider: string) => string | undefined): void {\n\t\tthis.fallbackResolver = resolver;\n\t}\n\n\tprivate recordError(error: unknown): void {\n\t\tconst normalizedError = error instanceof Error ? error : new Error(String(error));\n\t\tthis.errors.push(normalizedError);\n\t}\n\n\tprivate fingerprintAuthSource(source: ActiveAuthStatusSource, material: string): string {\n\t\tconst digest = createHash(\"sha256\").update(source).update(\"\\0\").update(material).digest(\"hex\");\n\t\treturn `${source}:${digest}`;\n\t}\n\n\tprivate createAuthSourceCandidate(options: {\n\t\tsource: ActiveAuthStatusSource;\n\t\tconfigured: boolean;\n\t\tidentityMaterial: string;\n\t\tvalueMaterial?: string;\n\t\tlabel?: string;\n\t\tresolveValueMaterial?: () => string | undefined;\n\t}): AuthSourceCandidate {\n\t\treturn {\n\t\t\tconfigured: options.configured,\n\t\t\tsource: options.source,\n\t\t\t...(options.label ? { label: options.label } : {}),\n\t\t\tidentityFingerprint: this.fingerprintAuthSource(options.source, `identity:${options.identityMaterial}`),\n\t\t\t...(options.valueMaterial !== undefined\n\t\t\t\t? {\n\t\t\t\t\t\tvalueFingerprint: this.fingerprintAuthSource(\n\t\t\t\t\t\t\toptions.source,\n\t\t\t\t\t\t\t`value:${options.identityMaterial}\\0${options.valueMaterial}`,\n\t\t\t\t\t\t),\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t\t...(options.resolveValueMaterial\n\t\t\t\t? {\n\t\t\t\t\t\tresolveValueFingerprint: () => {\n\t\t\t\t\t\t\tconst valueMaterial = options.resolveValueMaterial?.();\n\t\t\t\t\t\t\treturn valueMaterial === undefined\n\t\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t\t: this.fingerprintAuthSource(\n\t\t\t\t\t\t\t\t\t\toptions.source,\n\t\t\t\t\t\t\t\t\t\t`value:${options.identityMaterial}\\0${valueMaterial}`,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t};\n\t}\n\n\tprivate getStoredCredentialValueMaterial(providerId: string, credential: AuthCredential): string | undefined {\n\t\tif (credential.type === \"api_key\") {\n\t\t\tconst isCommand = credential.key.startsWith(\"!\");\n\t\t\tconst resolvedKey = isCommand\n\t\t\t\t? resolveConfigValueUncached(credential.key)\n\t\t\t\t: resolveConfigValue(credential.key);\n\t\t\tif (resolvedKey !== undefined && !isProviderApiKeyAllowed(providerId, resolvedKey)) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tif (isCommand) {\n\t\t\t\treturn resolvedKey === undefined ? undefined : `api_key:command:${credential.key}\\0${resolvedKey}`;\n\t\t\t}\n\t\t\treturn `api_key:${credential.key}\\0${resolvedKey ?? \"\"}`;\n\t\t}\n\t\tif (this.isExistingOpenAICodexSubscription(providerId))\n\t\t\treturn `oauth:${credential.access}\\0${credential.expires}`;\n\t\tif (getProviderAuthContract(providerId).oauth !== \"supported\") {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst provider = getOAuthProvider(providerId);\n\t\tconst apiKey = provider?.getApiKey(credential) ?? credential.access;\n\t\treturn `oauth:${apiKey}\\0${credential.refresh}\\0${credential.expires}`;\n\t}\n\n\tprivate getRuntimeAuthCandidate(provider: string): AuthSourceCandidate | undefined {\n\t\tconst apiKey = this.runtimeOverrides.get(provider);\n\t\tif (!apiKey || !isProviderApiKeyAllowed(provider, apiKey)) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn {\n\t\t\tlabel: \"--api-key\",\n\t\t\t...this.createAuthSourceCandidate({\n\t\t\t\tconfigured: false,\n\t\t\t\tsource: \"runtime\",\n\t\t\t\tidentityMaterial: provider,\n\t\t\t\tvalueMaterial: apiKey,\n\t\t\t}),\n\t\t};\n\t}\n\n\tprivate getStoredAuthCandidate(\n\t\tprovider: string,\n\t\toptions?: { resolveCommandValue?: boolean; resolvedCommandValue?: string },\n\t): AuthSourceCandidate | undefined {\n\t\tconst credential = this.data[provider];\n\t\tif (\n\t\t\t!credential ||\n\t\t\t(credential.type === \"oauth\" &&\n\t\t\t\tgetProviderAuthContract(provider).oauth !== \"supported\" &&\n\t\t\t\t!this.isExistingOpenAICodexSubscription(provider))\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst isCommandApiKey = credential.type === \"api_key\" && credential.key.startsWith(\"!\");\n\t\tif (credential.type === \"api_key\") {\n\t\t\tconst apiKey =\n\t\t\t\toptions?.resolvedCommandValue ?? (isCommandApiKey ? credential.key : resolveConfigValue(credential.key));\n\t\t\tif (apiKey !== undefined && !isProviderApiKeyAllowed(provider, apiKey)) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}\n\t\tconst identityMaterial = isCommandApiKey ? `api_key:command:${credential.key}` : `${provider}:${credential.type}`;\n\t\tconst commandValueMaterial =\n\t\t\tisCommandApiKey && options?.resolvedCommandValue !== undefined\n\t\t\t\t? `api_key:command:${credential.key}\\0${options.resolvedCommandValue}`\n\t\t\t\t: undefined;\n\t\treturn this.createAuthSourceCandidate({\n\t\t\tconfigured: true,\n\t\t\tsource: \"stored\",\n\t\t\tidentityMaterial,\n\t\t\tvalueMaterial:\n\t\t\t\tcommandValueMaterial ??\n\t\t\t\t(isCommandApiKey && !options?.resolveCommandValue\n\t\t\t\t\t? undefined\n\t\t\t\t\t: this.getStoredCredentialValueMaterial(provider, credential)),\n\t\t\tresolveValueMaterial: isCommandApiKey\n\t\t\t\t? () => this.getStoredCredentialValueMaterial(provider, credential)\n\t\t\t\t: undefined,\n\t\t});\n\t}\n\n\tprivate getEnvironmentApiKey(provider: string): string | undefined {\n\t\tconst apiKey = getEnvApiKey(provider);\n\t\treturn apiKey && isProviderApiKeyAllowed(provider, apiKey) ? apiKey : undefined;\n\t}\n\n\tprivate getEnvironmentAuthCandidate(provider: string): AuthSourceCandidate | undefined {\n\t\tconst envKeys = findEnvKeys(provider);\n\t\tconst envKey = envKeys?.[0];\n\t\tconst apiKey = this.getEnvironmentApiKey(provider);\n\t\tif (!apiKey) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst label = envKey ?? \"ambient credentials\";\n\t\tconst identityMaterial = envKey ?? this.getAmbientEnvironmentIdentityMaterial(provider);\n\t\treturn this.createAuthSourceCandidate({\n\t\t\tconfigured: false,\n\t\t\tsource: \"environment\",\n\t\t\tlabel,\n\t\t\tidentityMaterial,\n\t\t\tvalueMaterial: `${identityMaterial}\\0${apiKey}`,\n\t\t});\n\t}\n\n\tprivate getAmbientEnvironmentIdentityMaterial(provider: string): string {\n\t\tif (provider === \"amazon-bedrock\") {\n\t\t\tif (process.env.AWS_PROFILE) return `amazon-bedrock:profile:${process.env.AWS_PROFILE}`;\n\t\t\tif (process.env.AWS_ACCESS_KEY_ID) {\n\t\t\t\treturn `amazon-bedrock:access-key:${process.env.AWS_ACCESS_KEY_ID}:${process.env.AWS_SECRET_ACCESS_KEY ?? \"\"}:${process.env.AWS_SESSION_TOKEN ?? \"\"}`;\n\t\t\t}\n\t\t\tif (process.env.AWS_BEARER_TOKEN_BEDROCK) {\n\t\t\t\treturn `amazon-bedrock:bearer:${process.env.AWS_BEARER_TOKEN_BEDROCK}`;\n\t\t\t}\n\t\t\tif (process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI) {\n\t\t\t\treturn `amazon-bedrock:ecs-relative:${process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI}`;\n\t\t\t}\n\t\t\tif (process.env.AWS_CONTAINER_CREDENTIALS_FULL_URI) {\n\t\t\t\treturn `amazon-bedrock:ecs-full:${process.env.AWS_CONTAINER_CREDENTIALS_FULL_URI}`;\n\t\t\t}\n\t\t\tif (process.env.AWS_WEB_IDENTITY_TOKEN_FILE) {\n\t\t\t\treturn `amazon-bedrock:web-identity:${process.env.AWS_WEB_IDENTITY_TOKEN_FILE}`;\n\t\t\t}\n\t\t}\n\t\tif (provider === \"google-vertex\") {\n\t\t\tconst project = process.env.GOOGLE_CLOUD_PROJECT ?? process.env.GCLOUD_PROJECT ?? \"\";\n\t\t\tconst location = process.env.GOOGLE_CLOUD_LOCATION ?? \"\";\n\t\t\tconst credentialsPath = process.env.GOOGLE_APPLICATION_CREDENTIALS ?? \"application-default\";\n\t\t\treturn `google-vertex:${project}:${location}:${credentialsPath}`;\n\t\t}\n\t\treturn provider;\n\t}\n\n\tprivate getFallbackAuthCandidate(provider: string): AuthSourceCandidate | undefined {\n\t\tconst apiKey = this.fallbackResolver?.(provider);\n\t\tif (!apiKey || !isProviderApiKeyAllowed(provider, apiKey)) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this.createAuthSourceCandidate({\n\t\t\tconfigured: false,\n\t\t\tsource: \"fallback\",\n\t\t\tlabel: \"custom provider config\",\n\t\t\tidentityMaterial: provider,\n\t\t\tvalueMaterial: apiKey,\n\t\t});\n\t}\n\n\tprivate getAuthSourceCandidates(provider: string, options?: { includeFallback?: boolean }): AuthSourceCandidate[] {\n\t\tconst fallbackCandidate =\n\t\t\toptions?.includeFallback === false ? undefined : this.getFallbackAuthCandidate(provider);\n\t\tconst candidates = [\n\t\t\tthis.getRuntimeAuthCandidate(provider),\n\t\t\tthis.getStoredAuthCandidate(provider),\n\t\t\tthis.getEnvironmentAuthCandidate(provider),\n\t\t\tfallbackCandidate,\n\t\t];\n\t\treturn candidates.filter((candidate): candidate is AuthSourceCandidate => candidate !== undefined);\n\t}\n\n\tprivate isAuthSourceStale(provider: string, candidate: AuthSourceCandidate): boolean {\n\t\tconst matchingStale = this.getMatchingStaleAuthSources(provider, candidate);\n\t\tif (matchingStale.length === 0) {\n\t\t\treturn false;\n\t\t}\n\t\tconst valueFingerprint = candidate.valueFingerprint ?? candidate.resolveValueFingerprint?.();\n\t\treturn Boolean(valueFingerprint && matchingStale.some((token) => token.valueFingerprint === valueFingerprint));\n\t}\n\n\tprivate getMatchingStaleAuthSources(provider: string, candidate: AuthSourceCandidate): AuthSourceToken[] {\n\t\tconst stale = this.staleAuthSources.get(provider);\n\t\tif (!stale) {\n\t\t\treturn [];\n\t\t}\n\t\treturn stale.filter(\n\t\t\t(token) => token.source === candidate.source && token.identityFingerprint === candidate.identityFingerprint,\n\t\t);\n\t}\n\n\tprivate getAvailableAuthCandidate(\n\t\tprovider: string,\n\t\toptions?: { includeFallback?: boolean },\n\t): { candidate?: AuthSourceCandidate; hasStaleCandidate: boolean } {\n\t\tlet hasStaleCandidate = false;\n\t\tfor (const candidate of this.getAuthSourceCandidates(provider, options)) {\n\t\t\tif (this.isAuthSourceStale(provider, candidate)) {\n\t\t\t\thasStaleCandidate = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\treturn { candidate, hasStaleCandidate };\n\t\t}\n\t\treturn { hasStaleCandidate };\n\t}\n\n\tprivate toAuthStatus(candidate: AuthSourceCandidate): AuthStatus {\n\t\treturn {\n\t\t\tconfigured: candidate.configured,\n\t\t\tsource: candidate.source,\n\t\t\t...(candidate.label ? { label: candidate.label } : {}),\n\t\t};\n\t}\n\n\tprivate getAuthStatusFromCandidates(provider: string): AuthStatus {\n\t\tconst { candidate, hasStaleCandidate } = this.getAvailableAuthCandidate(provider);\n\t\tif (candidate) {\n\t\t\treturn this.toAuthStatus(candidate);\n\t\t}\n\t\tif (hasStaleCandidate) {\n\t\t\treturn { configured: false, source: \"stale\", label: \"expired\" };\n\t\t}\n\t\treturn { configured: false };\n\t}\n\n\tmarkAuthStale(provider: string): boolean {\n\t\tconst token = this.getCurrentAuthSourceToken(provider);\n\t\treturn token ? this.markAuthSourceStale(token) : false;\n\t}\n\n\tprivate getAuthSourceTokenForCandidate(\n\t\tprovider: string,\n\t\tcandidate: AuthSourceCandidate,\n\t): AuthSourceToken | undefined {\n\t\tconst valueFingerprint = candidate.valueFingerprint ?? candidate.resolveValueFingerprint?.();\n\t\tif (!valueFingerprint) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn {\n\t\t\tprovider,\n\t\t\tsource: candidate.source,\n\t\t\tidentityFingerprint: candidate.identityFingerprint,\n\t\t\tvalueFingerprint,\n\t\t};\n\t}\n\n\tgetCurrentAuthSourceToken(provider: string): AuthSourceToken | undefined {\n\t\tconst { candidate } = this.getAvailableAuthCandidate(provider);\n\t\tif (!candidate) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this.getAuthSourceTokenForCandidate(provider, candidate);\n\t}\n\n\tmarkAuthSourceStale(token: AuthSourceToken): boolean {\n\t\tif (token.provider.length === 0) {\n\t\t\treturn false;\n\t\t}\n\t\tconst stale = this.staleAuthSources.get(token.provider) ?? [];\n\t\tif (\n\t\t\t!stale.some(\n\t\t\t\t(existing) =>\n\t\t\t\t\texisting.source === token.source &&\n\t\t\t\t\texisting.identityFingerprint === token.identityFingerprint &&\n\t\t\t\t\texisting.valueFingerprint === token.valueFingerprint,\n\t\t\t)\n\t\t) {\n\t\t\tstale.push(token);\n\t\t}\n\t\tthis.staleAuthSources.set(token.provider, stale);\n\t\treturn true;\n\t}\n\n\tprivate clearStaleAuthSource(provider: string, source: ActiveAuthStatusSource): void {\n\t\tconst stale = this.staleAuthSources.get(provider);\n\t\tif (!stale) {\n\t\t\treturn;\n\t\t}\n\t\tconst next = stale.filter((token) => token.source !== source);\n\t\tif (next.length === 0) {\n\t\t\tthis.staleAuthSources.delete(provider);\n\t\t} else {\n\t\t\tthis.staleAuthSources.set(provider, next);\n\t\t}\n\t}\n\n\tprivate parseStorageState(content: string | undefined): AuthStorageState {\n\t\tconst { __base_context_login_attempts: loginAttempts = {}, ...credentials } = JSON.parse(\n\t\t\tcontent || \"{}\",\n\t\t) as AuthStorageData & { __base_context_login_attempts?: Record<string, string> };\n\t\treturn { credentials, loginAttempts };\n\t}\n\n\tprivate serializeStorageState({ credentials, loginAttempts }: AuthStorageState): string {\n\t\treturn JSON.stringify(\n\t\t\t{\n\t\t\t\t...credentials,\n\t\t\t\t...(Object.keys(loginAttempts).length > 0 ? { __base_context_login_attempts: loginAttempts } : {}),\n\t\t\t},\n\t\t\tnull,\n\t\t\t2,\n\t\t);\n\t}\n\n\tprivate parseStorageData(content: string | undefined): AuthStorageData {\n\t\treturn this.parseStorageState(content).credentials;\n\t}\n\n\t/**\n\t * Reload credentials from storage.\n\t */\n\treload(): void {\n\t\tlet content: string | undefined;\n\t\ttry {\n\t\t\tthis.storage.withLock((current) => {\n\t\t\t\tcontent = current;\n\t\t\t\treturn { result: undefined };\n\t\t\t});\n\t\t\tthis.data = this.parseStorageData(content);\n\t\t\tthis.loadError = null;\n\t\t} catch (error) {\n\t\t\tthis.loadError = error as Error;\n\t\t\tthis.recordError(error);\n\t\t}\n\t}\n\n\tprivate persistProviderChange(provider: string, credential: AuthCredential | undefined): void {\n\t\tif (this.loadError) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tthis.storage.withLock((current) => {\n\t\t\t\tconst state = this.parseStorageState(current);\n\t\t\t\tdelete state.loginAttempts[provider];\n\t\t\t\tif (credential) {\n\t\t\t\t\tstate.credentials[provider] = credential;\n\t\t\t\t} else {\n\t\t\t\t\tdelete state.credentials[provider];\n\t\t\t\t}\n\t\t\t\treturn { result: undefined, next: this.serializeStorageState(state) };\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthis.recordError(error);\n\t\t}\n\t}\n\n\t/**\n\t * Get credential for a provider.\n\t */\n\tget(provider: string): AuthCredential | undefined {\n\t\treturn this.data[provider] ?? undefined;\n\t}\n\n\t/**\n\t * Set credential for a provider.\n\t */\n\tset(provider: string, credential: AuthCredential): void {\n\t\tthis.assertWritableStorage();\n\t\tthis.clearStaleAuthSource(provider, \"stored\");\n\t\tthis.data[provider] = credential;\n\t\tthis.persistProviderChange(provider, credential);\n\t}\n\n\t/**\n\t * Remove credential for a provider.\n\t */\n\tremove(provider: string): void {\n\t\tthis.assertWritableStorage();\n\t\tthis.clearStaleAuthSource(provider, \"stored\");\n\t\tdelete this.data[provider];\n\t\tthis.persistProviderChange(provider, undefined);\n\t}\n\n\t/**\n\t * Remove a provider's credential with the disk write verified: throws on any\n\t * load or write failure instead of recording it, so callers can refuse to\n\t * proceed while the credential may still exist on disk. Disk-authoritative\n\t * and idempotent — in-memory state is only updated after the write succeeds.\n\t */\n\tremoveVerified(provider: string): void {\n\t\tthis.assertWritableStorage();\n\t\tthis.storage.withLock((current) => {\n\t\t\tconst state = this.parseStorageState(current);\n\t\t\tif (!(provider in state.credentials) && !(provider in state.loginAttempts)) return { result: undefined };\n\t\t\tdelete state.credentials[provider];\n\t\t\tdelete state.loginAttempts[provider];\n\t\t\treturn { result: undefined, next: this.serializeStorageState(state) };\n\t\t});\n\t\tdelete this.data[provider];\n\t\t// Post-success only: a failed removal must not make a stale-marked credential selectable again.\n\t\tthis.clearStaleAuthSource(provider, \"stored\");\n\t}\n\n\t/**\n\t * List all providers with credentials.\n\t */\n\tlist(): string[] {\n\t\treturn Object.keys(this.data);\n\t}\n\n\t/**\n\t * Check if credentials exist for a provider in auth.json.\n\t */\n\thas(provider: string): boolean {\n\t\treturn provider in this.data;\n\t}\n\n\t/**\n\t * Check if any form of auth is configured for a provider.\n\t * Unlike getApiKey(), this doesn't refresh OAuth tokens.\n\t */\n\thasAuth(provider: string): boolean {\n\t\treturn this.getAvailableAuthCandidate(provider).candidate !== undefined;\n\t}\n\n\t/**\n\t * Return auth status without exposing credential values or refreshing tokens.\n\t */\n\tgetAuthStatus(provider: string): AuthStatus {\n\t\treturn this.getAuthStatusFromCandidates(provider);\n\t}\n\n\t/**\n\t * Get all credentials (for passing to getOAuthApiKey).\n\t */\n\tgetAll(): AuthStorageData {\n\t\treturn { ...this.data };\n\t}\n\n\tdrainErrors(): Error[] {\n\t\tconst drained = [...this.errors];\n\t\tthis.errors = [];\n\t\treturn drained;\n\t}\n\n\t/**\n\t * Login to an OAuth provider.\n\t */\n\tasync login(providerId: OAuthProviderId, callbacks: OAuthLoginCallbacks): Promise<void> {\n\t\tthis.assertWritableStorage();\n\t\tconst contract = getProviderAuthContract(providerId);\n\t\tif (contract.oauth !== \"supported\") {\n\t\t\tthrow new Error(contract.guidance);\n\t\t}\n\t\tconst provider = getOAuthProvider(providerId);\n\t\tif (!provider) {\n\t\t\tthrow new Error(`Unknown OAuth provider: ${providerId}`);\n\t\t}\n\n\t\tawait this.setFromLogin(\n\t\t\tproviderId,\n\t\t\tasync () => ({ type: \"oauth\", ...(await provider.login(callbacks)) }),\n\t\t\tcallbacks.signal,\n\t\t);\n\t}\n\n\t/** Collect credentials without holding the lock, then commit only for the current login. */\n\tasync setFromLogin(\n\t\tproviderId: string,\n\t\tcollectCredential: () => Promise<AuthCredential>,\n\t\tsignal?: AbortSignal,\n\t): Promise<void> {\n\t\tthis.assertWritableStorage();\n\t\tif (signal?.aborted) throw new Error(\"Login cancelled\");\n\t\tconst attemptId = randomUUID();\n\t\tthis.storage.withLock((current) => {\n\t\t\tconst state = this.parseStorageState(current);\n\t\t\tstate.loginAttempts[providerId] = attemptId;\n\t\t\treturn { result: undefined, next: this.serializeStorageState(state) };\n\t\t});\n\n\t\tconst releaseAttempt = () => {\n\t\t\ttry {\n\t\t\t\tthis.storage.withLock((current) => {\n\t\t\t\t\tconst state = this.parseStorageState(current);\n\t\t\t\t\tif (state.loginAttempts[providerId] !== attemptId) return { result: undefined };\n\t\t\t\t\tdelete state.loginAttempts[providerId];\n\t\t\t\t\treturn { result: undefined, next: this.serializeStorageState(state) };\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tthis.recordError(error);\n\t\t\t}\n\t\t};\n\t\tsignal?.addEventListener(\"abort\", releaseAttempt, { once: true });\n\t\ttry {\n\t\t\tconst credential = await collectCredential();\n\t\t\tif (signal?.aborted) throw new Error(\"Login cancelled\");\n\t\t\tconst data = this.storage.withLock((current) => {\n\t\t\t\tconst state = this.parseStorageState(current);\n\t\t\t\tif (state.loginAttempts[providerId] !== attemptId) {\n\t\t\t\t\tthrow new Error(\"Login cancelled: credentials changed or login was superseded\");\n\t\t\t\t}\n\t\t\t\tdelete state.loginAttempts[providerId];\n\t\t\t\tstate.credentials[providerId] = credential;\n\t\t\t\treturn { result: state.credentials, next: this.serializeStorageState(state) };\n\t\t\t});\n\t\t\tthis.data = data;\n\t\t\tthis.loadError = null;\n\t\t\tthis.clearStaleAuthSource(providerId, \"stored\");\n\t\t} catch (error) {\n\t\t\treleaseAttempt();\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tsignal?.removeEventListener(\"abort\", releaseAttempt);\n\t\t}\n\t}\n\n\t/**\n\t * Logout from a provider.\n\t */\n\tlogout(provider: string): void {\n\t\tthis.remove(provider);\n\t}\n\n\t/**\n\t * Refresh OAuth token with backend locking to prevent race conditions.\n\t * Multiple pi instances may try to refresh simultaneously when tokens expire.\n\t */\n\tprivate async refreshOAuthTokenWithLock(\n\t\tproviderId: OAuthProviderId,\n\t): Promise<{ apiKey: string; newCredentials: OAuthCredentials } | null> {\n\t\tif (getProviderAuthContract(providerId).oauth !== \"supported\") {\n\t\t\treturn null;\n\t\t}\n\t\tconst provider = getOAuthProvider(providerId);\n\t\tif (!provider) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst result = await this.storage.withLockAsync(async (current) => {\n\t\t\tconst state = this.parseStorageState(current);\n\t\t\tconst currentData = state.credentials;\n\t\t\tthis.data = currentData;\n\t\t\tthis.loadError = null;\n\n\t\t\tconst cred = currentData[providerId];\n\t\t\tif (cred?.type !== \"oauth\" || getProviderAuthContract(providerId).oauth !== \"supported\") {\n\t\t\t\treturn { result: null };\n\t\t\t}\n\n\t\t\tif (Date.now() < cred.expires) {\n\t\t\t\treturn { result: { apiKey: provider.getApiKey(cred), newCredentials: cred } };\n\t\t\t}\n\n\t\t\tconst oauthCreds: Record<string, OAuthCredentials> = {};\n\t\t\tfor (const [key, value] of Object.entries(currentData)) {\n\t\t\t\tif (value.type === \"oauth\") {\n\t\t\t\t\toauthCreds[key] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst refreshed = await getOAuthApiKey(providerId, oauthCreds);\n\t\t\tif (!refreshed) {\n\t\t\t\treturn { result: null };\n\t\t\t}\n\n\t\t\tconst merged: AuthStorageData = {\n\t\t\t\t...currentData,\n\t\t\t\t[providerId]: { type: \"oauth\", ...refreshed.newCredentials },\n\t\t\t};\n\t\t\tthis.data = merged;\n\t\t\tthis.loadError = null;\n\t\t\treturn { result: refreshed, next: this.serializeStorageState({ ...state, credentials: merged }) };\n\t\t});\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Get API key for a provider.\n\t * Priority:\n\t * 1. Runtime override (CLI --api-key)\n\t * 2. auth.json\n\t * 3. Environment variable\n\t * 4. Fallback resolver (models.json custom providers)\n\t */\n\tasync getApiKeyWithSourceToken(\n\t\tproviderId: string,\n\t\toptions?: { includeFallback?: boolean },\n\t): Promise<AuthApiKeyResult> {\n\t\tif (this.isExistingOpenAICodexSubscription(providerId)) {\n\t\t\tif (this.runtimeOverrides.has(providerId))\n\t\t\t\tthrow new Error(\"Existing OpenAI subscription does not accept API-key overrides\");\n\t\t\tconst credential = this.data[providerId];\n\t\t\tif (\n\t\t\t\t!credential ||\n\t\t\t\tcredential.type !== \"oauth\" ||\n\t\t\t\ttypeof credential.access !== \"string\" ||\n\t\t\t\t!credential.access ||\n\t\t\t\t!Number.isFinite(credential.expires)\n\t\t\t)\n\t\t\t\tthrow new Error(\"Existing OpenAI subscription credential is unavailable\");\n\t\t\tif (Date.now() >= credential.expires) throw new Error(\"Existing OpenAI subscription credential has expired\");\n\t\t\tconst candidate = this.getStoredAuthCandidate(providerId);\n\t\t\tif (!candidate || this.isAuthSourceStale(providerId, candidate))\n\t\t\t\tthrow new Error(\"Existing OpenAI subscription credential is unavailable\");\n\t\t\treturn {\n\t\t\t\tapiKey: credential.access,\n\t\t\t\tsourceToken: this.getAuthSourceTokenForCandidate(providerId, candidate),\n\t\t\t};\n\t\t}\n\n\t\t// Runtime overrides take precedence over stored credentials and environment keys.\n\t\tconst runtimeCandidate = this.getRuntimeAuthCandidate(providerId);\n\t\tconst runtimeKey = this.runtimeOverrides.get(providerId);\n\t\tif (runtimeKey && runtimeCandidate && !this.isAuthSourceStale(providerId, runtimeCandidate)) {\n\t\t\treturn {\n\t\t\t\tapiKey: runtimeKey,\n\t\t\t\tsourceToken: this.getAuthSourceTokenForCandidate(providerId, runtimeCandidate),\n\t\t\t};\n\t\t}\n\n\t\tconst cred = this.data[providerId];\n\n\t\tif (cred?.type === \"api_key\") {\n\t\t\tconst storedCandidate = this.getStoredAuthCandidate(providerId);\n\t\t\tif (storedCandidate && !this.isAuthSourceStale(providerId, storedCandidate)) {\n\t\t\t\tconst hasStaleRecord = this.getMatchingStaleAuthSources(providerId, storedCandidate).length > 0;\n\t\t\t\tconst apiKey =\n\t\t\t\t\tcred.key.startsWith(\"!\") && hasStaleRecord\n\t\t\t\t\t\t? resolveConfigValueUncached(cred.key)\n\t\t\t\t\t\t: resolveConfigValue(cred.key);\n\t\t\t\tif (apiKey === undefined || isProviderApiKeyAllowed(providerId, apiKey)) {\n\t\t\t\t\tconst sourceToken =\n\t\t\t\t\t\tapiKey === undefined\n\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t: this.getAuthSourceTokenForCandidate(\n\t\t\t\t\t\t\t\t\tproviderId,\n\t\t\t\t\t\t\t\t\tcred.key.startsWith(\"!\")\n\t\t\t\t\t\t\t\t\t\t? (this.getStoredAuthCandidate(providerId, { resolvedCommandValue: apiKey }) ??\n\t\t\t\t\t\t\t\t\t\t\t\tstoredCandidate)\n\t\t\t\t\t\t\t\t\t\t: storedCandidate,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\treturn { apiKey, sourceToken };\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (cred?.type === \"oauth\" && getProviderAuthContract(providerId).oauth === \"supported\") {\n\t\t\tconst storedCandidate = this.getStoredAuthCandidate(providerId);\n\t\t\tif (storedCandidate && !this.isAuthSourceStale(providerId, storedCandidate)) {\n\t\t\t\tconst provider = getOAuthProvider(providerId);\n\t\t\t\tif (!provider) {\n\t\t\t\t\treturn {};\n\t\t\t\t}\n\t\t\t\t// Lock refreshes so concurrent instances cannot race on the credential file.\n\t\t\t\tconst needsRefresh = Date.now() >= cred.expires;\n\n\t\t\t\tif (needsRefresh) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await this.refreshOAuthTokenWithLock(providerId);\n\t\t\t\t\t\tif (result) {\n\t\t\t\t\t\t\tconst refreshedCandidate = this.getStoredAuthCandidate(providerId);\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tapiKey: result.apiKey,\n\t\t\t\t\t\t\t\tsourceToken: refreshedCandidate\n\t\t\t\t\t\t\t\t\t? this.getAuthSourceTokenForCandidate(providerId, refreshedCandidate)\n\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tthis.recordError(error);\n\t\t\t\t\t\t// A peer may have refreshed successfully; reload before treating this refresh as failed.\n\t\t\t\t\t\tthis.reload();\n\t\t\t\t\t\tconst updatedCred = this.data[providerId];\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tupdatedCred?.type === \"oauth\" &&\n\t\t\t\t\t\t\tgetProviderAuthContract(providerId).oauth === \"supported\" &&\n\t\t\t\t\t\t\tDate.now() < updatedCred.expires\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tconst updatedCandidate = this.getStoredAuthCandidate(providerId);\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tapiKey: provider.getApiKey(updatedCred),\n\t\t\t\t\t\t\t\tsourceToken: updatedCandidate\n\t\t\t\t\t\t\t\t\t? this.getAuthSourceTokenForCandidate(providerId, updatedCandidate)\n\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Preserve credentials for a later /login retry while discovery skips this provider.\n\t\t\t\t\t\treturn {};\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tapiKey: provider.getApiKey(cred),\n\t\t\t\t\t\tsourceToken: this.getAuthSourceTokenForCandidate(providerId, storedCandidate),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst envCandidate = this.getEnvironmentAuthCandidate(providerId);\n\t\tconst envKey = this.getEnvironmentApiKey(providerId);\n\t\tif (envKey && envCandidate && !this.isAuthSourceStale(providerId, envCandidate)) {\n\t\t\treturn {\n\t\t\t\tapiKey: envKey,\n\t\t\t\tsourceToken: this.getAuthSourceTokenForCandidate(providerId, envCandidate),\n\t\t\t};\n\t\t}\n\t\tif (options?.includeFallback !== false) {\n\t\t\tconst fallbackCandidate = this.getFallbackAuthCandidate(providerId);\n\t\t\tif (fallbackCandidate && !this.isAuthSourceStale(providerId, fallbackCandidate)) {\n\t\t\t\tconst apiKey = this.fallbackResolver?.(providerId) ?? undefined;\n\t\t\t\tif (apiKey === undefined || isProviderApiKeyAllowed(providerId, apiKey)) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tapiKey,\n\t\t\t\t\t\tsourceToken: this.getAuthSourceTokenForCandidate(providerId, fallbackCandidate),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {};\n\t}\n\n\tasync getApiKey(providerId: string, options?: { includeFallback?: boolean }): Promise<string | undefined> {\n\t\tconst result = await this.getApiKeyWithSourceToken(providerId, options);\n\t\treturn result.apiKey;\n\t}\n\n\t/**\n\t * Get supported registered OAuth providers. Read-only SDK storage cannot log in.\n\t */\n\tgetOAuthProviders() {\n\t\tif (this.existingOpenAICodexSubscription) return [];\n\t\treturn getOAuthProviders().filter((provider) => getProviderAuthContract(provider.id).oauth === \"supported\");\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../../src/core/kernel/bootstrap.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAuB3D,eAAO,MAAM,yBAAyB,UAAqD,CAAC;AAC5F,eAAO,MAAM,8BAA8B,UAA0D,CAAC;AACtG,eAAO,MAAM,+BAA+B,UAA2D,CAAC;AAyBxG,MAAM,MAAM,iBAAiB,GAAG,sBAAsB,CAAC;AACvD,MAAM,MAAM,8BAA8B,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AAEvE,MAAM,WAAW,yBAAyB;IACzC,YAAY,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC5C,UAAU,CAAC,EAAE,8BAA8B,CAAC;CAC5C;AAwQD,wBAAgB,gBAAgB,IAAI,MAAM,CAGzC;AAgSD,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAO/C;AAWD,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC,CAE9D;AAqOD,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,yBAA8B,GAAG,OAAO,CAAC,MAAM,CAAC,CAU3F;AAED,wFAAwF;AACxF,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,MAAM,CAAC,CAmBhE","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { constants, existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { access, mkdir, readdir, readFile, rm, stat, writeFile } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { stderr, stdin } from \"node:process\";\nimport { createInterface } from \"node:readline/promises\";\nimport { setTimeout as sleep } from \"node:timers/promises\";\nimport { getPackageDir, getPhysicalPackageDir } from \"../../config.js\";\nimport { getOwnedInstallation, readInstallSelection } from \"../../owned-install-layout.js\";\nimport { PRODUCT, PRODUCT_ENV } from \"../../product-identity.js\";\nimport { assertProductStatePath, readAbsolutePathEnv, resolveRuntimePaths } from \"../../runtime-paths.js\";\nimport type { PythonSkillRuntimeInfo } from \"../skills.js\";\n\nconst ownedRuntime = getOwnedInstallation(getPhysicalPackageDir());\nconst BOOTSTRAP_SCHEMA = 11;\nconst PYTHON_VERSION = \"3.13\";\nconst RUNTIME_REQUIREMENT = PRODUCT.runtimeDistribution;\n// Serializes the kernel's user namespace so it can be revived across session\n// resume. Internal-only; intentionally not surfaced to the model as an import.\nconst STATE_SNAPSHOT_REQUIREMENT = \"dill\";\nconst DEFAULT_RLM_EXTRA_PACKAGES = [\n\t{ uvArg: \"requests\", importName: \"requests\", promptLabel: \"requests\" },\n\t{ uvArg: \"httpx\", importName: \"httpx\", promptLabel: \"httpx\" },\n\t{ uvArg: \"pyyaml\", importName: \"yaml\", promptLabel: \"yaml (PyYAML)\" },\n\t{ uvArg: \"tomli\", importName: \"tomli\", promptLabel: \"tomli\" },\n\t{ uvArg: \"python-dotenv\", importName: \"dotenv\", promptLabel: \"dotenv (python-dotenv)\" },\n\t{ uvArg: \"pandas\", importName: \"pandas\", promptLabel: \"pandas\" },\n\t{ uvArg: \"numpy\", importName: \"numpy\", promptLabel: \"numpy\" },\n\t{ uvArg: \"scipy\", importName: \"scipy\", promptLabel: \"scipy\" },\n\t{ uvArg: \"beautifulsoup4\", importName: \"bs4\", promptLabel: \"bs4 (Beautiful Soup)\" },\n\t{ uvArg: \"lxml\", importName: \"lxml\", promptLabel: \"lxml\" },\n\t{ uvArg: \"pydantic\", importName: \"pydantic\", promptLabel: \"pydantic\" },\n\t{ uvArg: \"tyro\", importName: \"tyro\", promptLabel: \"tyro\" },\n];\nexport const DEFAULT_RLM_EXTRA_UV_ARGS = DEFAULT_RLM_EXTRA_PACKAGES.map((pkg) => pkg.uvArg);\nexport const DEFAULT_RLM_EXTRA_IMPORT_NAMES = DEFAULT_RLM_EXTRA_PACKAGES.map((pkg) => pkg.importName);\nexport const DEFAULT_RLM_EXTRA_IMPORT_LABELS = DEFAULT_RLM_EXTRA_PACKAGES.map((pkg) => pkg.promptLabel);\nconst UV_INSTALL_COMMAND = \"curl -LsSf https://astral.sh/uv/install.sh | UV_NO_MODIFY_PATH=1 sh\";\nconst REQUIRED_HARNESS_METHODS = [\n\t\"create_memory\",\n\t\"update_memory\",\n\t\"delete_memory\",\n\t\"create_skill\",\n\t\"update_skill\",\n\t\"delete_skill\",\n\t\"create_subagent\",\n\t\"update_subagent\",\n\t\"delete_subagent\",\n\t\"create_prompt_note\",\n\t\"update_prompt_note\",\n\t\"delete_prompt_note\",\n\t\"record_refinement\",\n];\nconst RUNTIME_READY_CHECK = `import inspect; from importlib import metadata; import rlm; assert metadata.version(\"${RUNTIME_REQUIREMENT}\"); assert \"prime-agent-runtime\" not in {d.metadata[\"Name\"].lower().replace(\"_\", \"-\") for d in metadata.distributions()}; from rlm import McpIntegration; import rlm.mcp as mcp; from rlm.harness import HarnessEntry; _harness_methods = ${JSON.stringify(REQUIRED_HARNESS_METHODS)}; assert callable(mcp.list_tools); assert callable(mcp.call_tool); assert hasattr(rlm, 'run'); assert callable(rlm); assert hasattr(rlm, 'rlm'); assert callable(rlm.rlm); assert callable(rlm.host_request); assert callable(rlm.find_models); assert callable(rlm.rlm.find_models); assert hasattr(rlm, 'harness'); assert hasattr(rlm, 'get_harness_state'); assert hasattr(rlm.rlm, 'harness'); assert hasattr(rlm.rlm, 'get_harness_state'); assert all(callable(getattr(_harness, _method, None)) for _harness in (rlm.harness, rlm.rlm.harness) for _method in _harness_methods); assert 'reference' in HarnessEntry.__dataclass_fields__; assert 'scope' in HarnessEntry.__dataclass_fields__; assert 'reference' in inspect.signature(rlm.harness.create_skill).parameters; assert 'reference' in inspect.signature(rlm.harness.update_skill).parameters; assert 'global_' in inspect.signature(rlm.harness.create_memory).parameters; assert 'global_' in inspect.signature(rlm.get_harness_state).parameters; assert not hasattr(rlm, 'background'); assert not hasattr(rlm.rlm, 'background'); from rlm.bash import BashHandle, BashResult; assert callable(rlm.bash); assert all(callable(getattr(BashHandle, _m, None)) for _m in ('tail', 'output', 'poll', 'kill')); assert {'exit_code', 'output', 'duration'} <= set(BashResult.__dataclass_fields__); import rlm.repl as _repl; assert callable(_repl.main); assert callable(_repl.emit); assert callable(_repl.host_request); assert callable(_repl.is_active); assert _repl.PROTOCOL_VERSION == 4; assert callable(rlm.emit); assert not hasattr(rlm, 'HOST_COMM_TARGET'); assert not hasattr(mcp, 'install_shutdown_hook')`;\nconst BOOTSTRAP_VERSION_FILE = \".bootstrap-version\";\nconst BOOTSTRAP_LOCK_NAME = \".bootstrap.lock\";\nconst BOOTSTRAP_LOCK_RETRY_MS = 100;\nconst BOOTSTRAP_LOCK_STALE_WITHOUT_PID_MS = 30_000;\n\nlet inFlightEnsureKernelPython: { key: string; promise: Promise<string> } | null = null;\n\nexport type KernelPythonSkill = PythonSkillRuntimeInfo;\nexport type KernelBootstrapProgressHandler = (message: string) => void;\n\nexport interface EnsureKernelPythonOptions {\n\tpythonSkills?: readonly KernelPythonSkill[];\n\tonProgress?: KernelBootstrapProgressHandler;\n}\n\ninterface BootstrapPythonSkill {\n\timportName: string;\n\tpackagePath: string;\n\tpyprojectPath: string;\n\tpyprojectHash: string;\n}\n\ninterface BootstrapVersion {\n\tschema: number;\n\truntime?: string;\n\tsnapshot?: string;\n\textraUvArgs?: string[];\n\tpythonSkills?: BootstrapPythonSkill[];\n}\n\nfunction errorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction isNodeError(error: unknown, code: string): boolean {\n\treturn error instanceof Error && \"code\" in error && error.code === code;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nasync function exists(filePath: string): Promise<boolean> {\n\ttry {\n\t\tawait access(filePath);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function isExecutable(filePath: string): Promise<boolean> {\n\ttry {\n\t\tawait access(filePath, constants.X_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction fileContentHash(filePath: string): string {\n\ttry {\n\t\treturn `sha256:${createHash(\"sha256\").update(readFileSync(filePath)).digest(\"hex\")}`;\n\t} catch {\n\t\treturn \"unreadable\";\n\t}\n}\n\nfunction normalizePythonSkills(pythonSkills: readonly KernelPythonSkill[] | undefined): BootstrapPythonSkill[] {\n\tconst byKey = new Map<string, BootstrapPythonSkill>();\n\tconst addSkill = (skill: Pick<KernelPythonSkill, \"importName\" | \"packagePath\" | \"pyprojectPath\">): void => {\n\t\tconst packagePath = path.resolve(skill.packagePath);\n\t\tconst pyprojectPath = path.resolve(skill.pyprojectPath);\n\t\tconst key = `${skill.importName}\\0${packagePath}`;\n\t\tif (byKey.has(key)) {\n\t\t\treturn;\n\t\t}\n\t\tconst bootstrapSkill: BootstrapPythonSkill = {\n\t\t\timportName: skill.importName,\n\t\t\tpackagePath,\n\t\t\tpyprojectPath,\n\t\t\tpyprojectHash: fileContentHash(pyprojectPath),\n\t\t};\n\t\tbyKey.set(key, bootstrapSkill);\n\t\tfor (const dependencyName of readPythonSkillDependencyNames(bootstrapSkill)) {\n\t\t\tconst siblingDependency = resolveSiblingPythonSkillDependency(bootstrapSkill, dependencyName);\n\t\t\tif (siblingDependency) {\n\t\t\t\taddSkill(siblingDependency);\n\t\t\t}\n\t\t}\n\t};\n\tfor (const skill of pythonSkills ?? []) {\n\t\taddSkill(skill);\n\t}\n\treturn [...byKey.values()].sort((a, b) => {\n\t\tconst packageCompare = a.packagePath.localeCompare(b.packagePath);\n\t\tif (packageCompare !== 0) return packageCompare;\n\t\treturn a.importName.localeCompare(b.importName);\n\t});\n}\n\nfunction readTomlProjectSection(pyprojectPath: string): string | undefined {\n\ttry {\n\t\tconst text = readFileSync(pyprojectPath, \"utf-8\");\n\t\tconst match = text.match(/^\\s*\\[project\\]\\s*$/m);\n\t\tif (!match || match.index === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst sectionStart = match.index + match[0].length;\n\t\tconst rest = text.slice(sectionStart);\n\t\tconst nextSection = rest.search(/^\\s*\\[/m);\n\t\treturn nextSection >= 0 ? rest.slice(0, nextSection) : rest;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction readPythonSkillProjectName(skill: BootstrapPythonSkill): string {\n\tconst projectSection = readTomlProjectSection(skill.pyprojectPath);\n\tconst name = projectSection?.match(/^\\s*name\\s*=\\s*[\"']([^\"']+)[\"']/m)?.[1];\n\treturn name?.trim() || skill.importName.replaceAll(\"_\", \"-\");\n}\n\nfunction parseDependencyPackageName(dependency: string): string | undefined {\n\tconst withoutMarker = dependency.split(\";\")[0]?.trim() ?? \"\";\n\tif (!withoutMarker) {\n\t\treturn undefined;\n\t}\n\tconst match = withoutMarker.match(/^([A-Za-z0-9_.-]+)/);\n\treturn match?.[1]?.replaceAll(\"_\", \"-\").toLowerCase();\n}\n\nfunction findTomlArrayEnd(text: string, startIndex: number): number {\n\tlet inQuote: '\"' | \"'\" | undefined;\n\tlet escaped = false;\n\tfor (let index = startIndex; index < text.length; index++) {\n\t\tconst char = text[index];\n\t\tif (inQuote) {\n\t\t\tif (escaped) {\n\t\t\t\tescaped = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (char === \"\\\\\") {\n\t\t\t\tescaped = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (char === inQuote) {\n\t\t\t\tinQuote = undefined;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === '\"' || char === \"'\") {\n\t\t\tinQuote = char;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"]\") {\n\t\t\treturn index;\n\t\t}\n\t}\n\treturn -1;\n}\n\nfunction readPythonSkillDependencyNames(skill: BootstrapPythonSkill): Set<string> {\n\tconst projectSection = readTomlProjectSection(skill.pyprojectPath);\n\tif (!projectSection) {\n\t\treturn new Set();\n\t}\n\tconst dependenciesStart = projectSection.search(/^\\s*dependencies\\s*=\\s*\\[/m);\n\tif (dependenciesStart < 0) {\n\t\treturn new Set();\n\t}\n\tconst arrayStart = projectSection.indexOf(\"[\", dependenciesStart);\n\tif (arrayStart < 0) {\n\t\treturn new Set();\n\t}\n\tconst arrayEnd = findTomlArrayEnd(projectSection, arrayStart + 1);\n\tif (arrayEnd < 0) {\n\t\treturn new Set();\n\t}\n\tconst dependenciesArray = projectSection.slice(arrayStart, arrayEnd + 1);\n\tconst dependencies = new Set<string>();\n\tconst dependencyPattern = /\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\"|'([^'\\\\]*(?:\\\\.[^'\\\\]*)*)'/g;\n\tfor (const match of dependenciesArray.matchAll(dependencyPattern)) {\n\t\tconst dependency = (match[1] ?? match[2] ?? \"\").replaceAll('\\\\\"', '\"').replaceAll(\"\\\\'\", \"'\");\n\t\tconst name = parseDependencyPackageName(dependency);\n\t\tif (name) {\n\t\t\tdependencies.add(name);\n\t\t}\n\t}\n\treturn dependencies;\n}\n\nfunction resolveSiblingPythonSkillDependency(\n\tskill: BootstrapPythonSkill,\n\tdependencyName: string,\n): BootstrapPythonSkill | undefined {\n\tconst siblingsDir = path.dirname(skill.packagePath);\n\tfor (const entry of readdirSync(siblingsDir, { withFileTypes: true })) {\n\t\tif (!entry.isDirectory()) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst packagePath = path.join(siblingsDir, entry.name);\n\t\tconst pyprojectPath = path.join(packagePath, \"pyproject.toml\");\n\t\tif (!existsSync(pyprojectPath)) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst dependency: BootstrapPythonSkill = {\n\t\t\timportName: entry.name.replaceAll(\"-\", \"_\"),\n\t\t\tpackagePath,\n\t\t\tpyprojectPath,\n\t\t\tpyprojectHash: fileContentHash(pyprojectPath),\n\t\t};\n\t\tif (readPythonSkillProjectName(dependency).replaceAll(\"_\", \"-\").toLowerCase() === dependencyName) {\n\t\t\treturn dependency;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction sortPythonSkillsForInstall(pythonSkills: readonly BootstrapPythonSkill[]): BootstrapPythonSkill[] {\n\tconst byProjectName = new Map<string, BootstrapPythonSkill>();\n\tconst originalIndex = new Map<BootstrapPythonSkill, number>();\n\tfor (const [index, skill] of pythonSkills.entries()) {\n\t\toriginalIndex.set(skill, index);\n\t\tbyProjectName.set(readPythonSkillProjectName(skill).replaceAll(\"_\", \"-\").toLowerCase(), skill);\n\t}\n\n\tconst dependenciesBySkill = new Map<BootstrapPythonSkill, BootstrapPythonSkill[]>();\n\tfor (const skill of pythonSkills) {\n\t\tdependenciesBySkill.set(\n\t\t\tskill,\n\t\t\t[...readPythonSkillDependencyNames(skill)]\n\t\t\t\t.map(\n\t\t\t\t\t(dependencyName) =>\n\t\t\t\t\t\tbyProjectName.get(dependencyName) ?? resolveSiblingPythonSkillDependency(skill, dependencyName),\n\t\t\t\t)\n\t\t\t\t.filter((dependency): dependency is BootstrapPythonSkill => Boolean(dependency)),\n\t\t);\n\t}\n\n\tconst pending = new Set(pythonSkills);\n\tconst sorted: BootstrapPythonSkill[] = [];\n\twhile (pending.size > 0) {\n\t\tlet progressed = false;\n\t\tfor (const skill of [...pending].sort((a, b) => (originalIndex.get(a) ?? 0) - (originalIndex.get(b) ?? 0))) {\n\t\t\tconst dependencies = dependenciesBySkill.get(skill) ?? [];\n\t\t\tif (dependencies.some((dependency) => pending.has(dependency))) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tsorted.push(skill);\n\t\t\tpending.delete(skill);\n\t\t\tprogressed = true;\n\t\t}\n\t\tif (!progressed) {\n\t\t\t// Cyclic local skill dependencies cannot be topologically ordered; keep a\n\t\t\t// deterministic order and let uv surface the packaging error if needed.\n\t\t\tsorted.push(...[...pending].sort((a, b) => a.packagePath.localeCompare(b.packagePath)));\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn sorted;\n}\n\nfunction formatPythonSkillInstallArgs(skill: BootstrapPythonSkill): string[] {\n\treturn [\"--editable\", skill.packagePath];\n}\n\nfunction ensureKernelPythonKey(pythonSkills: readonly BootstrapPythonSkill[]): string {\n\treturn [\n\t\tprocess.env[PRODUCT_ENV.kernelPython] ?? \"\",\n\t\tprocess.env[PRODUCT_ENV.kernelVenv] ?? \"\",\n\t\tprocess.env.HOME ?? \"\",\n\t\tprocess.env[PRODUCT_ENV.home] ?? \"\",\n\t\tJSON.stringify(pythonSkills),\n\t].join(\"\\0\");\n}\n\nexport function getKernelVenvDir(): string {\n\tconst override = readAbsolutePathEnv(PRODUCT_ENV.kernelVenv);\n\treturn assertProductStatePath(override ?? ownedRuntime?.runtimeDir ?? resolveRuntimePaths().runtime);\n}\n\nasync function resolveWritableKernelVenvDir(): Promise<string> {\n\tconst venv = getKernelVenvDir();\n\tawait mkdir(path.dirname(venv), { recursive: true });\n\treturn venv;\n}\n\nfunction run(command: string, args: string[], options: { stdio?: \"ignore\" | \"inherit\" } = {}): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst child = spawn(command, args, {\n\t\t\tenv: process.env,\n\t\t\tstdio: options.stdio ?? \"ignore\",\n\t\t});\n\t\tchild.on(\"error\", reject);\n\t\tchild.on(\"exit\", (code, signal) => {\n\t\t\tif (code === 0) {\n\t\t\t\tresolve();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst reason = signal ? `signal ${signal}` : `exit code ${code}`;\n\t\t\treject(new Error(`${command} ${args.join(\" \")} failed with ${reason}`));\n\t\t});\n\t});\n}\n\nasync function pythonImports(python: string, moduleName: string): Promise<boolean> {\n\ttry {\n\t\tawait run(python, [\"-c\", `import ${moduleName}`], { stdio: \"ignore\" });\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function hasBaseContextRuntime(python: string): Promise<boolean> {\n\ttry {\n\t\tawait run(python, [\"-c\", RUNTIME_READY_CHECK], { stdio: \"ignore\" });\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function missingRlmExtraImportLabels(python: string): Promise<string[]> {\n\tconst missing: string[] = [];\n\tfor (const pkg of DEFAULT_RLM_EXTRA_PACKAGES) {\n\t\tif (!(await pythonImports(python, pkg.importName))) {\n\t\t\tmissing.push(pkg.promptLabel);\n\t\t}\n\t}\n\treturn missing;\n}\n\nasync function missingPythonSkillImportLabels(\n\tpython: string,\n\tpythonSkills: readonly KernelPythonSkill[],\n): Promise<string[]> {\n\tconst missing: string[] = [];\n\tfor (const skill of pythonSkills) {\n\t\tif (!(await pythonImports(python, skill.importName))) {\n\t\t\tmissing.push(`${skill.name} (${skill.importName})`);\n\t\t}\n\t}\n\treturn missing;\n}\n\nfunction reportProgress(options: EnsureKernelPythonOptions, message: string): void {\n\tif (options.onProgress) {\n\t\toptions.onProgress(message);\n\t\treturn;\n\t}\n\tprocess.stderr.write(`${message}\\n`);\n}\n\nfunction bootstrapLockDir(venv: string): string {\n\treturn path.join(path.dirname(venv), `${path.basename(venv)}${BOOTSTRAP_LOCK_NAME}`);\n}\n\nfunction processIsRunning(pid: number): boolean {\n\ttry {\n\t\tprocess.kill(pid, 0);\n\t\treturn true;\n\t} catch (error) {\n\t\treturn isNodeError(error, \"EPERM\");\n\t}\n}\n\nasync function readLockPid(lockDir: string): Promise<number | null> {\n\ttry {\n\t\tconst raw = await readFile(path.join(lockDir, \"pid\"), \"utf8\");\n\t\tconst pid = Number.parseInt(raw.trim(), 10);\n\t\treturn Number.isInteger(pid) && pid > 0 ? pid : null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nasync function lockMissingPidIsStale(lockDir: string): Promise<boolean> {\n\ttry {\n\t\tconst lockStat = await stat(lockDir);\n\t\treturn Date.now() - lockStat.mtimeMs > BOOTSTRAP_LOCK_STALE_WITHOUT_PID_MS;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function acquireBootstrapLock(venv: string): Promise<() => Promise<void>> {\n\tconst lockDir = bootstrapLockDir(venv);\n\tawait mkdir(path.dirname(lockDir), { recursive: true });\n\n\tfor (;;) {\n\t\ttry {\n\t\t\tawait mkdir(lockDir);\n\t\t\tawait writeFile(path.join(lockDir, \"pid\"), `${process.pid}\\n`, \"utf8\");\n\t\t\treturn () => rm(lockDir, { recursive: true, force: true });\n\t\t} catch (error) {\n\t\t\tif (!isNodeError(error, \"EEXIST\")) throw error;\n\n\t\t\tconst pid = await readLockPid(lockDir);\n\t\t\tif (pid === null ? await lockMissingPidIsStale(lockDir) : !processIsRunning(pid)) {\n\t\t\t\tawait rm(lockDir, { recursive: true, force: true });\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tawait sleep(BOOTSTRAP_LOCK_RETRY_MS);\n\t\t}\n\t}\n}\n\nasync function findExecutable(name: string): Promise<string | null> {\n\tconst pathValue = process.env.PATH;\n\tif (!pathValue) return null;\n\tconst candidates = process.platform === \"win32\" ? [name, `${name}.exe`] : [name];\n\tfor (const dir of pathValue.split(path.delimiter)) {\n\t\tif (!dir) continue;\n\t\tfor (const candidate of candidates) {\n\t\t\tconst fullPath = path.join(dir, candidate);\n\t\t\tif (await isExecutable(fullPath)) return fullPath;\n\t\t}\n\t}\n\treturn null;\n}\n\nasync function ensureUv(options: EnsureKernelPythonOptions): Promise<string> {\n\tconst fromPath = await findExecutable(\"uv\");\n\tif (fromPath) return fromPath;\n\n\tconst localUv = path.join(os.homedir(), \".local\", \"bin\", process.platform === \"win32\" ? \"uv.exe\" : \"uv\");\n\tif (await isExecutable(localUv)) return localUv;\n\n\tconst shouldInstallUv =\n\t\tprocess.env[PRODUCT_ENV.installUv] === \"1\" || (!options.onProgress && (await confirmUvInstall()));\n\tif (!shouldInstallUv) {\n\t\tthrow new Error(\n\t\t\t`uv is required to set up the Python kernel. Install uv yourself: ${UV_INSTALL_COMMAND}, ` +\n\t\t\t\t\"or set BASE_CONTEXT_INSTALL_UV=1 to let base-context run that installer.\",\n\t\t);\n\t}\n\n\treportProgress(options, \"› installing uv (one-time)…\");\n\ttry {\n\t\tawait run(\"sh\", [\"-c\", UV_INSTALL_COMMAND], { stdio: options.onProgress ? \"ignore\" : \"inherit\" });\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`couldn't install uv from astral.sh; install it yourself: ${UV_INSTALL_COMMAND}, then re-run base-context. ${errorMessage(error)}`,\n\t\t);\n\t}\n\n\tif (await isExecutable(localUv)) return localUv;\n\tconst installedFromPath = await findExecutable(\"uv\");\n\tif (installedFromPath) return installedFromPath;\n\tthrow new Error(\"uv install completed but binary not found at ~/.local/bin/uv\");\n}\n\nasync function confirmUvInstall(): Promise<boolean> {\n\tif (process.env[PRODUCT_ENV.installUv] === \"0\") return false;\n\tif (!stdin.isTTY || !stderr.isTTY) return false;\n\n\tconst rl = createInterface({ input: stdin, output: stderr });\n\ttry {\n\t\tconst answer = (\n\t\t\tawait rl.question(\"Base Context needs uv to set up Python. Install uv from astral.sh now? [Y/n] \")\n\t\t)\n\t\t\t.trim()\n\t\t\t.toLowerCase();\n\t\treturn answer !== \"n\" && answer !== \"no\";\n\t} finally {\n\t\trl.close();\n\t}\n}\n\nasync function readBootstrapVersion(venv: string): Promise<BootstrapVersion | null> {\n\ttry {\n\t\tconst raw = await readFile(path.join(venv, BOOTSTRAP_VERSION_FILE), \"utf8\");\n\t\tconst parsed: unknown = JSON.parse(raw);\n\t\tif (!isRecord(parsed) || typeof parsed.schema !== \"number\") return null;\n\t\tconst extraUvArgs =\n\t\t\tArray.isArray(parsed.extraUvArgs) &&\n\t\t\tparsed.extraUvArgs.every((v: unknown): v is string => typeof v === \"string\")\n\t\t\t\t? (parsed.extraUvArgs as string[])\n\t\t\t\t: undefined;\n\t\tlet pythonSkills: BootstrapPythonSkill[] | undefined;\n\t\tif (Array.isArray(parsed.pythonSkills)) {\n\t\t\tif (\n\t\t\t\t!parsed.pythonSkills.every((v: unknown): v is BootstrapPythonSkill => {\n\t\t\t\t\tif (!isRecord(v)) return false;\n\t\t\t\t\treturn (\n\t\t\t\t\t\ttypeof v.importName === \"string\" &&\n\t\t\t\t\t\ttypeof v.packagePath === \"string\" &&\n\t\t\t\t\t\ttypeof v.pyprojectPath === \"string\" &&\n\t\t\t\t\t\ttypeof v.pyprojectHash === \"string\"\n\t\t\t\t\t);\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tpythonSkills = parsed.pythonSkills as BootstrapPythonSkill[];\n\t\t}\n\t\treturn {\n\t\t\tschema: parsed.schema,\n\t\t\truntime: typeof parsed.runtime === \"string\" ? parsed.runtime : undefined,\n\t\t\tsnapshot: typeof parsed.snapshot === \"string\" ? parsed.snapshot : undefined,\n\t\t\textraUvArgs,\n\t\t\tpythonSkills,\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction extraUvArgsMatch(a: string[] | undefined, b: string[] | undefined): boolean {\n\tif (a === b) return true;\n\tif (!a || !b) return false;\n\tif (a.length !== b.length) return false;\n\treturn a.every((v, i) => v === b[i]);\n}\n\nfunction pythonSkillsMatch(a: BootstrapPythonSkill[] | undefined, b: readonly BootstrapPythonSkill[]): boolean {\n\tconst left = a ?? [];\n\tif (left.length !== b.length) return false;\n\treturn left.every((skill, index) => {\n\t\tconst expected = b[index];\n\t\treturn (\n\t\t\tskill.importName === expected.importName &&\n\t\t\tskill.packagePath === expected.packagePath &&\n\t\t\tskill.pyprojectPath === expected.pyprojectPath &&\n\t\t\tskill.pyprojectHash === expected.pyprojectHash\n\t\t);\n\t});\n}\n\nfunction bootstrapVersionCurrent(\n\tversion: BootstrapVersion | null,\n\truntimeIdentity: string,\n\tpythonSkills: readonly BootstrapPythonSkill[],\n): boolean {\n\treturn (\n\t\tversion !== null &&\n\t\tbootstrapBaseVersionCurrent(version, runtimeIdentity) &&\n\t\tpythonSkillsMatch(version.pythonSkills, pythonSkills)\n\t);\n}\n\nfunction bootstrapBaseVersionCurrent(version: BootstrapVersion | null, runtimeIdentity: string): boolean {\n\treturn (\n\t\tversion?.schema === BOOTSTRAP_SCHEMA &&\n\t\tversion.runtime === runtimeIdentity &&\n\t\tversion.snapshot === STATE_SNAPSHOT_REQUIREMENT &&\n\t\textraUvArgsMatch(version.extraUvArgs, DEFAULT_RLM_EXTRA_UV_ARGS)\n\t);\n}\n\nasync function writeBootstrapVersion(\n\tvenv: string,\n\truntimeIdentity: string,\n\tpythonSkills: readonly BootstrapPythonSkill[],\n): Promise<void> {\n\tconst version: BootstrapVersion = {\n\t\tschema: BOOTSTRAP_SCHEMA,\n\t\truntime: runtimeIdentity,\n\t\tsnapshot: STATE_SNAPSHOT_REQUIREMENT,\n\t\textraUvArgs: DEFAULT_RLM_EXTRA_UV_ARGS,\n\t\tpythonSkills: [...pythonSkills],\n\t};\n\tawait writeFile(path.join(venv, BOOTSTRAP_VERSION_FILE), `${JSON.stringify(version)}\\n`, \"utf8\");\n}\n\nexport function runtimeCandidateDirs(): string[] {\n\tif (ownedRuntime) return [path.join(ownedRuntime.packageDir, \"dist\", RUNTIME_REQUIREMENT)];\n\tconst packageDir = getPackageDir();\n\tif (existsSync(path.join(packageDir, \"src\"))) {\n\t\treturn [path.resolve(packageDir, \"..\", \"..\", \"prime-agent-runtime\")];\n\t}\n\treturn [path.join(packageDir, \"dist\", RUNTIME_REQUIREMENT), path.join(packageDir, RUNTIME_REQUIREMENT)];\n}\n\nasync function resolveRuntimeSourceDir(): Promise<string> {\n\tfor (const candidate of runtimeCandidateDirs()) {\n\t\tif (await exists(path.join(candidate, \"pyproject.toml\"))) return candidate;\n\t}\n\tthrow new Error(\n\t\t\"Base Context runtime payload is missing. Reinstall this Base Context release; registry runtime fallback is disabled.\",\n\t);\n}\n\nexport async function resolveRuntimeIdentity(): Promise<string> {\n\treturn hashRuntimeSource(await resolveRuntimeSourceDir());\n}\n\n// A source read failure must not be replaced by a registry runtime.\nasync function hashRuntimeSource(sourceDir: string): Promise<string> {\n\tconst rlmDir = path.join(sourceDir, \"src\", \"rlm\");\n\tconst files: string[] = [path.join(sourceDir, \"pyproject.toml\")];\n\tasync function collect(dir: string): Promise<void> {\n\t\tconst entries = await readdir(dir, { withFileTypes: true });\n\t\tfor (const entry of entries) {\n\t\t\tconst full = path.join(dir, entry.name);\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tawait collect(full);\n\t\t\t} else if (entry.isFile() && entry.name.endsWith(\".py\")) {\n\t\t\t\tfiles.push(full);\n\t\t\t}\n\t\t}\n\t}\n\tawait collect(rlmDir);\n\tfiles.sort();\n\tconst hash = createHash(\"sha256\");\n\tfor (const file of files) {\n\t\thash.update(path.relative(sourceDir, file));\n\t\thash.update(\"\\0\");\n\t\thash.update(await readFile(file));\n\t\thash.update(\"\\0\");\n\t}\n\treturn `sha256:${hash.digest(\"hex\")}`;\n}\n\nasync function bootstrapVenv(\n\tvenv: string,\n\tpythonSkills: readonly BootstrapPythonSkill[],\n\toptions: EnsureKernelPythonOptions,\n): Promise<void> {\n\tawait mkdir(path.dirname(venv), { recursive: true });\n\tconst uv = await ensureUv(options);\n\tconst python = path.join(venv, \"bin\", \"python\");\n\tconst sourceDir = await resolveRuntimeSourceDir();\n\tconst runtimeRequirement = sourceDir;\n\tconst runtimeIdentity = await resolveRuntimeIdentity();\n\n\tawait run(uv, [\"python\", \"install\", PYTHON_VERSION]);\n\tawait run(uv, [\"venv\", venv, \"--python\", PYTHON_VERSION, \"--seed\"]);\n\tawait run(uv, [\n\t\t\"pip\",\n\t\t\"install\",\n\t\t\"--python\",\n\t\tpython,\n\t\truntimeRequirement,\n\t\tSTATE_SNAPSHOT_REQUIREMENT,\n\t\t...DEFAULT_RLM_EXTRA_UV_ARGS,\n\t]);\n\tawait syncPythonSkills(uv, venv, python, runtimeIdentity, pythonSkills, options);\n}\n\nasync function syncPythonSkills(\n\tuv: string,\n\tvenv: string,\n\tpython: string,\n\truntimeIdentity: string,\n\tpythonSkills: readonly BootstrapPythonSkill[],\n\toptions: EnsureKernelPythonOptions,\n): Promise<void> {\n\tconst version = await readBootstrapVersion(venv);\n\tconst installedPythonSkills: BootstrapPythonSkill[] = [];\n\tconst currentPythonSkills = new Map(\n\t\t(version?.pythonSkills ?? []).map((skill) => [`${skill.importName}\\0${skill.packagePath}`, skill]),\n\t);\n\tconst pythonSkillsByProjectName = new Map(\n\t\tpythonSkills.map((skill) => [readPythonSkillProjectName(skill).replaceAll(\"_\", \"-\").toLowerCase(), skill]),\n\t);\n\tconst dependenciesBySkill = new Map(\n\t\tpythonSkills.map((skill) => [\n\t\t\tskill,\n\t\t\t[...readPythonSkillDependencyNames(skill)]\n\t\t\t\t.map(\n\t\t\t\t\t(dependencyName) =>\n\t\t\t\t\t\tpythonSkillsByProjectName.get(dependencyName) ??\n\t\t\t\t\t\tresolveSiblingPythonSkillDependency(skill, dependencyName),\n\t\t\t\t)\n\t\t\t\t.filter((dependency): dependency is BootstrapPythonSkill => Boolean(dependency)),\n\t\t]),\n\t);\n\n\tfor (const skill of sortPythonSkillsForInstall(pythonSkills)) {\n\t\tconst existingSkill = currentPythonSkills.get(`${skill.importName}\\0${skill.packagePath}`);\n\t\tif (existingSkill?.pyprojectPath === skill.pyprojectPath && existingSkill.pyprojectHash === skill.pyprojectHash) {\n\t\t\tinstalledPythonSkills.push(skill);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst localDependencies = dependenciesBySkill.get(skill) ?? [];\n\t\tconst localDependencyArgs = localDependencies\n\t\t\t.filter((dependency) => {\n\t\t\t\tconst installedDependency = currentPythonSkills.get(`${dependency.importName}\\0${dependency.packagePath}`);\n\t\t\t\tconst installedThisSync = installedPythonSkills.some(\n\t\t\t\t\t(installed) =>\n\t\t\t\t\t\tinstalled.importName === dependency.importName &&\n\t\t\t\t\t\tinstalled.packagePath === dependency.packagePath &&\n\t\t\t\t\t\tinstalled.pyprojectPath === dependency.pyprojectPath &&\n\t\t\t\t\t\tinstalled.pyprojectHash === dependency.pyprojectHash,\n\t\t\t\t);\n\t\t\t\treturn !(\n\t\t\t\t\tinstalledThisSync ||\n\t\t\t\t\t(installedDependency?.pyprojectPath === dependency.pyprojectPath &&\n\t\t\t\t\t\tinstalledDependency.pyprojectHash === dependency.pyprojectHash)\n\t\t\t\t);\n\t\t\t})\n\t\t\t.flatMap(formatPythonSkillInstallArgs);\n\n\t\ttry {\n\t\t\tawait run(uv, [\n\t\t\t\t\"pip\",\n\t\t\t\t\"install\",\n\t\t\t\t\"--python\",\n\t\t\t\tpython,\n\t\t\t\t...formatPythonSkillInstallArgs(skill),\n\t\t\t\t...localDependencyArgs,\n\t\t\t]);\n\t\t\tinstalledPythonSkills.push(\n\t\t\t\tskill,\n\t\t\t\t...localDependencies.filter((dependency) => !installedPythonSkills.includes(dependency)),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\treportProgress(\n\t\t\t\toptions,\n\t\t\t\t`Warning: Python skill ${skill.importName} failed to install and will be unavailable: ${errorMessage(error)}`,\n\t\t\t);\n\t\t}\n\t}\n\tawait writeBootstrapVersion(venv, runtimeIdentity, installedPythonSkills);\n}\n\nasync function kernelBaseReady(python: string, venv: string, runtimeIdentity: string): Promise<boolean> {\n\treturn (\n\t\t(await hasBaseContextRuntime(python)) &&\n\t\tbootstrapBaseVersionCurrent(await readBootstrapVersion(venv), runtimeIdentity)\n\t);\n}\n\nasync function kernelReady(\n\tpython: string,\n\tvenv: string,\n\truntimeIdentity: string,\n\tpythonSkills: readonly BootstrapPythonSkill[],\n): Promise<boolean> {\n\treturn (\n\t\t(await hasBaseContextRuntime(python)) &&\n\t\tbootstrapVersionCurrent(await readBootstrapVersion(venv), runtimeIdentity, pythonSkills)\n\t);\n}\n\nfunction formatBootstrapFailure(error: unknown): Error {\n\treturn new Error(\n\t\t`Failed to set up the Python kernel runtime. ${errorMessage(error)}\\n` +\n\t\t\t\"First-time setup needs internet to install uv, Python, the bundled base-context-runtime, and default Python packages; once set up, base-context runs offline. \" +\n\t\t\t\"Set BASE_CONTEXT_KERNEL_PYTHON to a Python with a current base-context-runtime and default Python packages installed to skip auto-bootstrap.\",\n\t);\n}\n\nasync function ensureKernelPythonUncached(\n\toptions: EnsureKernelPythonOptions,\n\tpythonSkills: readonly BootstrapPythonSkill[],\n): Promise<string> {\n\tconst override = readAbsolutePathEnv(PRODUCT_ENV.kernelPython);\n\tif (override) {\n\t\tconst python = override;\n\t\tconst missing: string[] = [];\n\t\tif (!(await hasBaseContextRuntime(python))) {\n\t\t\tmissing.push(\n\t\t\t\t\"a current base-context-runtime with callable rlm.run, rlm.host_request, and explicit harness CRUD methods\",\n\t\t\t);\n\t\t}\n\t\tif (missing.length === 0) {\n\t\t\tconst missingExtraImports = await missingRlmExtraImportLabels(python);\n\t\t\tif (missingExtraImports.length > 0) {\n\t\t\t\tmissing.push(`default Python packages (${missingExtraImports.join(\", \")})`);\n\t\t\t}\n\t\t}\n\t\tif (missing.length === 0 && pythonSkills.length > 0) {\n\t\t\tconst missingPythonSkills = await missingPythonSkillImportLabels(python, options.pythonSkills ?? []);\n\t\t\tif (missingPythonSkills.length > 0) {\n\t\t\t\treportProgress(\n\t\t\t\t\toptions,\n\t\t\t\t\t`Warning: Python skills unavailable in BASE_CONTEXT_KERNEL_PYTHON and will be disabled: ${missingPythonSkills.join(\", \")}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tif (missing.length === 0) return python;\n\t\tthrow new Error(`BASE_CONTEXT_KERNEL_PYTHON points to a Python missing ${missing.join(\" and \")}: ${python}`);\n\t}\n\n\tconst venv = await resolveWritableKernelVenvDir();\n\tconst python = path.join(venv, \"bin\", \"python\");\n\tconst runtimeIdentity = await resolveRuntimeIdentity();\n\tif (await kernelReady(python, venv, runtimeIdentity, pythonSkills)) return python;\n\n\tconst releaseLock = await acquireBootstrapLock(venv);\n\ttry {\n\t\tif (await kernelReady(python, venv, runtimeIdentity, pythonSkills)) return python;\n\t\tif (await kernelBaseReady(python, venv, runtimeIdentity)) {\n\t\t\tawait syncPythonSkills(await ensureUv(options), venv, python, runtimeIdentity, pythonSkills, options);\n\t\t\treturn python;\n\t\t}\n\n\t\tif (ownedRuntime && !readAbsolutePathEnv(PRODUCT_ENV.kernelVenv)) {\n\t\t\tthrow new Error(\n\t\t\t\t\"The selected Base-Context default runtime is unavailable or stale. Install a prepared candidate or explicitly roll back; the retained runtime was not rebuilt.\",\n\t\t\t);\n\t\t}\n\n\t\tconst hadVenv = existsSync(venv);\n\t\treportProgress(options, \"› setting up python kernel (one-time, ~30s)…\");\n\t\tif (hadVenv) {\n\t\t\treportProgress(options, \"rebuilding kernel venv\");\n\t\t\tawait rm(venv, { recursive: true, force: true });\n\t\t}\n\n\t\tawait bootstrapVenv(venv, pythonSkills, options);\n\t} catch (error) {\n\t\tthrow formatBootstrapFailure(error);\n\t} finally {\n\t\tawait releaseLock().catch(() => undefined);\n\t}\n\n\treportProgress(options, \"✓ ready\");\n\treturn python;\n}\n\nexport function ensureKernelPython(options: EnsureKernelPythonOptions = {}): Promise<string> {\n\tconst pythonSkills = normalizePythonSkills(options.pythonSkills);\n\tconst key = ensureKernelPythonKey(pythonSkills);\n\tif (inFlightEnsureKernelPython?.key === key) return inFlightEnsureKernelPython.promise;\n\n\tconst promise = ensureKernelPythonUncached(options, pythonSkills).finally(() => {\n\t\tif (inFlightEnsureKernelPython?.promise === promise) inFlightEnsureKernelPython = null;\n\t});\n\tinFlightEnsureKernelPython = { key, promise };\n\treturn promise;\n}\n\n/** Prepare only a new physical owned release, before its selection can be published. */\nexport async function prepareOwnedKernelPython(): Promise<string> {\n\tif (!ownedRuntime || existsSync(ownedRuntime.runtimeDir)) {\n\t\tthrow new Error(\"Base-Context runtime preparation requires a new, empty owned release runtime directory.\");\n\t}\n\tconst selected = readInstallSelection(ownedRuntime.root);\n\tif (selected?.active === ownedRuntime.version || selected?.previous === ownedRuntime.version) {\n\t\tthrow new Error(\"Base-Context will not prepare a published release in place. Install a new candidate instead.\");\n\t}\n\tconst python = path.join(ownedRuntime.runtimeDir, \"bin\", \"python\");\n\tconst options: EnsureKernelPythonOptions = { onProgress: (message) => console.error(message) };\n\tawait bootstrapVenv(ownedRuntime.runtimeDir, [], options);\n\tconst runtimeIdentity = await resolveRuntimeIdentity();\n\tif (\n\t\t!(await kernelReady(python, ownedRuntime.runtimeDir, runtimeIdentity, [])) ||\n\t\t(await missingRlmExtraImportLabels(python)).length > 0\n\t) {\n\t\tthrow new Error(\"Base-Context candidate Python runtime did not become ready. This candidate was not activated.\");\n\t}\n\treturn python;\n}\n"]}
1
+ {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../../src/core/kernel/bootstrap.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAuB3D,eAAO,MAAM,yBAAyB,UAAqD,CAAC;AAC5F,eAAO,MAAM,8BAA8B,UAA0D,CAAC;AACtG,eAAO,MAAM,+BAA+B,UAA2D,CAAC;AAyBxG,MAAM,MAAM,iBAAiB,GAAG,sBAAsB,CAAC;AACvD,MAAM,MAAM,8BAA8B,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AAEvE,MAAM,WAAW,yBAAyB;IACzC,YAAY,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC5C,UAAU,CAAC,EAAE,8BAA8B,CAAC;CAC5C;AAwQD,wBAAgB,gBAAgB,IAAI,MAAM,CAGzC;AAuSD,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAO/C;AAWD,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC,CAE9D;AAqOD,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,yBAA8B,GAAG,OAAO,CAAC,MAAM,CAAC,CAU3F;AAED,wFAAwF;AACxF,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,MAAM,CAAC,CAmBhE","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { constants, existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { access, mkdir, readdir, readFile, rm, stat, writeFile } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { stderr, stdin } from \"node:process\";\nimport { createInterface } from \"node:readline/promises\";\nimport { setTimeout as sleep } from \"node:timers/promises\";\nimport { getPackageDir, getPhysicalPackageDir } from \"../../config.js\";\nimport { getOwnedInstallation, readInstallSelection } from \"../../owned-install-layout.js\";\nimport { PRODUCT, PRODUCT_ENV } from \"../../product-identity.js\";\nimport { assertProductStatePath, readAbsolutePathEnv, resolveRuntimePaths } from \"../../runtime-paths.js\";\nimport type { PythonSkillRuntimeInfo } from \"../skills.js\";\n\nconst ownedRuntime = getOwnedInstallation(getPhysicalPackageDir());\nconst BOOTSTRAP_SCHEMA = 11;\nconst PYTHON_VERSION = \"3.13\";\nconst RUNTIME_REQUIREMENT = PRODUCT.runtimeDistribution;\n// Serializes the kernel's user namespace so it can be revived across session\n// resume. Internal-only; intentionally not surfaced to the model as an import.\nconst STATE_SNAPSHOT_REQUIREMENT = \"dill\";\nconst DEFAULT_RLM_EXTRA_PACKAGES = [\n\t{ uvArg: \"requests\", importName: \"requests\", promptLabel: \"requests\" },\n\t{ uvArg: \"httpx\", importName: \"httpx\", promptLabel: \"httpx\" },\n\t{ uvArg: \"pyyaml\", importName: \"yaml\", promptLabel: \"yaml (PyYAML)\" },\n\t{ uvArg: \"tomli\", importName: \"tomli\", promptLabel: \"tomli\" },\n\t{ uvArg: \"python-dotenv\", importName: \"dotenv\", promptLabel: \"dotenv (python-dotenv)\" },\n\t{ uvArg: \"pandas\", importName: \"pandas\", promptLabel: \"pandas\" },\n\t{ uvArg: \"numpy\", importName: \"numpy\", promptLabel: \"numpy\" },\n\t{ uvArg: \"scipy\", importName: \"scipy\", promptLabel: \"scipy\" },\n\t{ uvArg: \"beautifulsoup4\", importName: \"bs4\", promptLabel: \"bs4 (Beautiful Soup)\" },\n\t{ uvArg: \"lxml\", importName: \"lxml\", promptLabel: \"lxml\" },\n\t{ uvArg: \"pydantic\", importName: \"pydantic\", promptLabel: \"pydantic\" },\n\t{ uvArg: \"tyro\", importName: \"tyro\", promptLabel: \"tyro\" },\n];\nexport const DEFAULT_RLM_EXTRA_UV_ARGS = DEFAULT_RLM_EXTRA_PACKAGES.map((pkg) => pkg.uvArg);\nexport const DEFAULT_RLM_EXTRA_IMPORT_NAMES = DEFAULT_RLM_EXTRA_PACKAGES.map((pkg) => pkg.importName);\nexport const DEFAULT_RLM_EXTRA_IMPORT_LABELS = DEFAULT_RLM_EXTRA_PACKAGES.map((pkg) => pkg.promptLabel);\nconst UV_INSTALL_COMMAND = \"curl -LsSf https://astral.sh/uv/install.sh | UV_NO_MODIFY_PATH=1 sh\";\nconst REQUIRED_HARNESS_METHODS = [\n\t\"create_memory\",\n\t\"update_memory\",\n\t\"delete_memory\",\n\t\"create_skill\",\n\t\"update_skill\",\n\t\"delete_skill\",\n\t\"create_subagent\",\n\t\"update_subagent\",\n\t\"delete_subagent\",\n\t\"create_prompt_note\",\n\t\"update_prompt_note\",\n\t\"delete_prompt_note\",\n\t\"record_refinement\",\n];\nconst RUNTIME_READY_CHECK = `import inspect; from importlib import metadata; import rlm; assert metadata.version(\"${RUNTIME_REQUIREMENT}\"); assert \"prime-agent-runtime\" not in {d.metadata[\"Name\"].lower().replace(\"_\", \"-\") for d in metadata.distributions()}; from rlm import McpIntegration; import rlm.mcp as mcp; from rlm.harness import HarnessEntry; _harness_methods = ${JSON.stringify(REQUIRED_HARNESS_METHODS)}; assert callable(mcp.list_tools); assert callable(mcp.call_tool); assert hasattr(rlm, 'run'); assert callable(rlm); assert hasattr(rlm, 'rlm'); assert callable(rlm.rlm); assert callable(rlm.host_request); assert callable(rlm.find_models); assert callable(rlm.rlm.find_models); assert hasattr(rlm, 'harness'); assert hasattr(rlm, 'get_harness_state'); assert hasattr(rlm.rlm, 'harness'); assert hasattr(rlm.rlm, 'get_harness_state'); assert all(callable(getattr(_harness, _method, None)) for _harness in (rlm.harness, rlm.rlm.harness) for _method in _harness_methods); assert 'reference' in HarnessEntry.__dataclass_fields__; assert 'scope' in HarnessEntry.__dataclass_fields__; assert 'reference' in inspect.signature(rlm.harness.create_skill).parameters; assert 'reference' in inspect.signature(rlm.harness.update_skill).parameters; assert 'global_' in inspect.signature(rlm.harness.create_memory).parameters; assert 'global_' in inspect.signature(rlm.get_harness_state).parameters; assert not hasattr(rlm, 'background'); assert not hasattr(rlm.rlm, 'background'); from rlm.bash import BashHandle, BashResult; assert callable(rlm.bash); assert all(callable(getattr(BashHandle, _m, None)) for _m in ('tail', 'output', 'poll', 'kill')); assert {'exit_code', 'output', 'duration'} <= set(BashResult.__dataclass_fields__); import rlm.repl as _repl; assert callable(_repl.main); assert callable(_repl.emit); assert callable(_repl.host_request); assert callable(_repl.is_active); assert _repl.PROTOCOL_VERSION == 4; assert callable(rlm.emit); assert not hasattr(rlm, 'HOST_COMM_TARGET'); assert not hasattr(mcp, 'install_shutdown_hook')`;\nconst BOOTSTRAP_VERSION_FILE = \".bootstrap-version\";\nconst BOOTSTRAP_LOCK_NAME = \".bootstrap.lock\";\nconst BOOTSTRAP_LOCK_RETRY_MS = 100;\nconst BOOTSTRAP_LOCK_STALE_WITHOUT_PID_MS = 30_000;\n\nlet inFlightEnsureKernelPython: { key: string; promise: Promise<string> } | null = null;\n\nexport type KernelPythonSkill = PythonSkillRuntimeInfo;\nexport type KernelBootstrapProgressHandler = (message: string) => void;\n\nexport interface EnsureKernelPythonOptions {\n\tpythonSkills?: readonly KernelPythonSkill[];\n\tonProgress?: KernelBootstrapProgressHandler;\n}\n\ninterface BootstrapPythonSkill {\n\timportName: string;\n\tpackagePath: string;\n\tpyprojectPath: string;\n\tpyprojectHash: string;\n}\n\ninterface BootstrapVersion {\n\tschema: number;\n\truntime?: string;\n\tsnapshot?: string;\n\textraUvArgs?: string[];\n\tpythonSkills?: BootstrapPythonSkill[];\n}\n\nfunction errorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction isNodeError(error: unknown, code: string): boolean {\n\treturn error instanceof Error && \"code\" in error && error.code === code;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nasync function exists(filePath: string): Promise<boolean> {\n\ttry {\n\t\tawait access(filePath);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function isExecutable(filePath: string): Promise<boolean> {\n\ttry {\n\t\tawait access(filePath, constants.X_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction fileContentHash(filePath: string): string {\n\ttry {\n\t\treturn `sha256:${createHash(\"sha256\").update(readFileSync(filePath)).digest(\"hex\")}`;\n\t} catch {\n\t\treturn \"unreadable\";\n\t}\n}\n\nfunction normalizePythonSkills(pythonSkills: readonly KernelPythonSkill[] | undefined): BootstrapPythonSkill[] {\n\tconst byKey = new Map<string, BootstrapPythonSkill>();\n\tconst addSkill = (skill: Pick<KernelPythonSkill, \"importName\" | \"packagePath\" | \"pyprojectPath\">): void => {\n\t\tconst packagePath = path.resolve(skill.packagePath);\n\t\tconst pyprojectPath = path.resolve(skill.pyprojectPath);\n\t\tconst key = `${skill.importName}\\0${packagePath}`;\n\t\tif (byKey.has(key)) {\n\t\t\treturn;\n\t\t}\n\t\tconst bootstrapSkill: BootstrapPythonSkill = {\n\t\t\timportName: skill.importName,\n\t\t\tpackagePath,\n\t\t\tpyprojectPath,\n\t\t\tpyprojectHash: fileContentHash(pyprojectPath),\n\t\t};\n\t\tbyKey.set(key, bootstrapSkill);\n\t\tfor (const dependencyName of readPythonSkillDependencyNames(bootstrapSkill)) {\n\t\t\tconst siblingDependency = resolveSiblingPythonSkillDependency(bootstrapSkill, dependencyName);\n\t\t\tif (siblingDependency) {\n\t\t\t\taddSkill(siblingDependency);\n\t\t\t}\n\t\t}\n\t};\n\tfor (const skill of pythonSkills ?? []) {\n\t\taddSkill(skill);\n\t}\n\treturn [...byKey.values()].sort((a, b) => {\n\t\tconst packageCompare = a.packagePath.localeCompare(b.packagePath);\n\t\tif (packageCompare !== 0) return packageCompare;\n\t\treturn a.importName.localeCompare(b.importName);\n\t});\n}\n\nfunction readTomlProjectSection(pyprojectPath: string): string | undefined {\n\ttry {\n\t\tconst text = readFileSync(pyprojectPath, \"utf-8\");\n\t\tconst match = text.match(/^\\s*\\[project\\]\\s*$/m);\n\t\tif (!match || match.index === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst sectionStart = match.index + match[0].length;\n\t\tconst rest = text.slice(sectionStart);\n\t\tconst nextSection = rest.search(/^\\s*\\[/m);\n\t\treturn nextSection >= 0 ? rest.slice(0, nextSection) : rest;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction readPythonSkillProjectName(skill: BootstrapPythonSkill): string {\n\tconst projectSection = readTomlProjectSection(skill.pyprojectPath);\n\tconst name = projectSection?.match(/^\\s*name\\s*=\\s*[\"']([^\"']+)[\"']/m)?.[1];\n\treturn name?.trim() || skill.importName.replaceAll(\"_\", \"-\");\n}\n\nfunction parseDependencyPackageName(dependency: string): string | undefined {\n\tconst withoutMarker = dependency.split(\";\")[0]?.trim() ?? \"\";\n\tif (!withoutMarker) {\n\t\treturn undefined;\n\t}\n\tconst match = withoutMarker.match(/^([A-Za-z0-9_.-]+)/);\n\treturn match?.[1]?.replaceAll(\"_\", \"-\").toLowerCase();\n}\n\nfunction findTomlArrayEnd(text: string, startIndex: number): number {\n\tlet inQuote: '\"' | \"'\" | undefined;\n\tlet escaped = false;\n\tfor (let index = startIndex; index < text.length; index++) {\n\t\tconst char = text[index];\n\t\tif (inQuote) {\n\t\t\tif (escaped) {\n\t\t\t\tescaped = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (char === \"\\\\\") {\n\t\t\t\tescaped = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (char === inQuote) {\n\t\t\t\tinQuote = undefined;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === '\"' || char === \"'\") {\n\t\t\tinQuote = char;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"]\") {\n\t\t\treturn index;\n\t\t}\n\t}\n\treturn -1;\n}\n\nfunction readPythonSkillDependencyNames(skill: BootstrapPythonSkill): Set<string> {\n\tconst projectSection = readTomlProjectSection(skill.pyprojectPath);\n\tif (!projectSection) {\n\t\treturn new Set();\n\t}\n\tconst dependenciesStart = projectSection.search(/^\\s*dependencies\\s*=\\s*\\[/m);\n\tif (dependenciesStart < 0) {\n\t\treturn new Set();\n\t}\n\tconst arrayStart = projectSection.indexOf(\"[\", dependenciesStart);\n\tif (arrayStart < 0) {\n\t\treturn new Set();\n\t}\n\tconst arrayEnd = findTomlArrayEnd(projectSection, arrayStart + 1);\n\tif (arrayEnd < 0) {\n\t\treturn new Set();\n\t}\n\tconst dependenciesArray = projectSection.slice(arrayStart, arrayEnd + 1);\n\tconst dependencies = new Set<string>();\n\tconst dependencyPattern = /\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\"|'([^'\\\\]*(?:\\\\.[^'\\\\]*)*)'/g;\n\tfor (const match of dependenciesArray.matchAll(dependencyPattern)) {\n\t\tconst dependency = (match[1] ?? match[2] ?? \"\").replaceAll('\\\\\"', '\"').replaceAll(\"\\\\'\", \"'\");\n\t\tconst name = parseDependencyPackageName(dependency);\n\t\tif (name) {\n\t\t\tdependencies.add(name);\n\t\t}\n\t}\n\treturn dependencies;\n}\n\nfunction resolveSiblingPythonSkillDependency(\n\tskill: BootstrapPythonSkill,\n\tdependencyName: string,\n): BootstrapPythonSkill | undefined {\n\tconst siblingsDir = path.dirname(skill.packagePath);\n\tfor (const entry of readdirSync(siblingsDir, { withFileTypes: true })) {\n\t\tif (!entry.isDirectory()) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst packagePath = path.join(siblingsDir, entry.name);\n\t\tconst pyprojectPath = path.join(packagePath, \"pyproject.toml\");\n\t\tif (!existsSync(pyprojectPath)) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst dependency: BootstrapPythonSkill = {\n\t\t\timportName: entry.name.replaceAll(\"-\", \"_\"),\n\t\t\tpackagePath,\n\t\t\tpyprojectPath,\n\t\t\tpyprojectHash: fileContentHash(pyprojectPath),\n\t\t};\n\t\tif (readPythonSkillProjectName(dependency).replaceAll(\"_\", \"-\").toLowerCase() === dependencyName) {\n\t\t\treturn dependency;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction sortPythonSkillsForInstall(pythonSkills: readonly BootstrapPythonSkill[]): BootstrapPythonSkill[] {\n\tconst byProjectName = new Map<string, BootstrapPythonSkill>();\n\tconst originalIndex = new Map<BootstrapPythonSkill, number>();\n\tfor (const [index, skill] of pythonSkills.entries()) {\n\t\toriginalIndex.set(skill, index);\n\t\tbyProjectName.set(readPythonSkillProjectName(skill).replaceAll(\"_\", \"-\").toLowerCase(), skill);\n\t}\n\n\tconst dependenciesBySkill = new Map<BootstrapPythonSkill, BootstrapPythonSkill[]>();\n\tfor (const skill of pythonSkills) {\n\t\tdependenciesBySkill.set(\n\t\t\tskill,\n\t\t\t[...readPythonSkillDependencyNames(skill)]\n\t\t\t\t.map(\n\t\t\t\t\t(dependencyName) =>\n\t\t\t\t\t\tbyProjectName.get(dependencyName) ?? resolveSiblingPythonSkillDependency(skill, dependencyName),\n\t\t\t\t)\n\t\t\t\t.filter((dependency): dependency is BootstrapPythonSkill => Boolean(dependency)),\n\t\t);\n\t}\n\n\tconst pending = new Set(pythonSkills);\n\tconst sorted: BootstrapPythonSkill[] = [];\n\twhile (pending.size > 0) {\n\t\tlet progressed = false;\n\t\tfor (const skill of [...pending].sort((a, b) => (originalIndex.get(a) ?? 0) - (originalIndex.get(b) ?? 0))) {\n\t\t\tconst dependencies = dependenciesBySkill.get(skill) ?? [];\n\t\t\tif (dependencies.some((dependency) => pending.has(dependency))) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tsorted.push(skill);\n\t\t\tpending.delete(skill);\n\t\t\tprogressed = true;\n\t\t}\n\t\tif (!progressed) {\n\t\t\t// Cyclic local skill dependencies cannot be topologically ordered; keep a\n\t\t\t// deterministic order and let uv surface the packaging error if needed.\n\t\t\tsorted.push(...[...pending].sort((a, b) => a.packagePath.localeCompare(b.packagePath)));\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn sorted;\n}\n\nfunction formatPythonSkillInstallArgs(skill: BootstrapPythonSkill): string[] {\n\treturn [\"--editable\", skill.packagePath];\n}\n\nfunction ensureKernelPythonKey(pythonSkills: readonly BootstrapPythonSkill[]): string {\n\treturn [\n\t\tprocess.env[PRODUCT_ENV.kernelPython] ?? \"\",\n\t\tprocess.env[PRODUCT_ENV.kernelVenv] ?? \"\",\n\t\tprocess.env.HOME ?? \"\",\n\t\tprocess.env[PRODUCT_ENV.home] ?? \"\",\n\t\tJSON.stringify(pythonSkills),\n\t].join(\"\\0\");\n}\n\nexport function getKernelVenvDir(): string {\n\tconst override = readAbsolutePathEnv(PRODUCT_ENV.kernelVenv);\n\treturn assertProductStatePath(override ?? ownedRuntime?.runtimeDir ?? resolveRuntimePaths().runtime);\n}\n\nasync function resolveWritableKernelVenvDir(): Promise<string> {\n\tconst venv = getKernelVenvDir();\n\tawait mkdir(path.dirname(venv), { recursive: true });\n\treturn venv;\n}\n\nfunction run(\n\tcommand: string,\n\targs: string[],\n\toptions: { stdio?: \"ignore\" | \"inherit\"; env?: NodeJS.ProcessEnv } = {},\n): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst child = spawn(command, args, {\n\t\t\tenv: options.env ?? process.env,\n\t\t\tstdio: options.stdio ?? \"ignore\",\n\t\t});\n\t\tchild.on(\"error\", reject);\n\t\tchild.on(\"exit\", (code, signal) => {\n\t\t\tif (code === 0) {\n\t\t\t\tresolve();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst reason = signal ? `signal ${signal}` : `exit code ${code}`;\n\t\t\treject(new Error(`${command} ${args.join(\" \")} failed with ${reason}`));\n\t\t});\n\t});\n}\n\nasync function pythonImports(python: string, moduleName: string): Promise<boolean> {\n\ttry {\n\t\tawait run(python, [\"-c\", `import ${moduleName}`], { stdio: \"ignore\" });\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function hasBaseContextRuntime(python: string): Promise<boolean> {\n\ttry {\n\t\tawait run(python, [\"-c\", RUNTIME_READY_CHECK], { stdio: \"ignore\" });\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function missingRlmExtraImportLabels(python: string): Promise<string[]> {\n\tconst missing: string[] = [];\n\tfor (const pkg of DEFAULT_RLM_EXTRA_PACKAGES) {\n\t\tif (!(await pythonImports(python, pkg.importName))) {\n\t\t\tmissing.push(pkg.promptLabel);\n\t\t}\n\t}\n\treturn missing;\n}\n\nasync function missingPythonSkillImportLabels(\n\tpython: string,\n\tpythonSkills: readonly KernelPythonSkill[],\n): Promise<string[]> {\n\tconst missing: string[] = [];\n\tfor (const skill of pythonSkills) {\n\t\tif (!(await pythonImports(python, skill.importName))) {\n\t\t\tmissing.push(`${skill.name} (${skill.importName})`);\n\t\t}\n\t}\n\treturn missing;\n}\n\nfunction reportProgress(options: EnsureKernelPythonOptions, message: string): void {\n\tif (options.onProgress) {\n\t\toptions.onProgress(message);\n\t\treturn;\n\t}\n\tprocess.stderr.write(`${message}\\n`);\n}\n\nfunction bootstrapLockDir(venv: string): string {\n\treturn path.join(path.dirname(venv), `${path.basename(venv)}${BOOTSTRAP_LOCK_NAME}`);\n}\n\nfunction processIsRunning(pid: number): boolean {\n\ttry {\n\t\tprocess.kill(pid, 0);\n\t\treturn true;\n\t} catch (error) {\n\t\treturn isNodeError(error, \"EPERM\");\n\t}\n}\n\nasync function readLockPid(lockDir: string): Promise<number | null> {\n\ttry {\n\t\tconst raw = await readFile(path.join(lockDir, \"pid\"), \"utf8\");\n\t\tconst pid = Number.parseInt(raw.trim(), 10);\n\t\treturn Number.isInteger(pid) && pid > 0 ? pid : null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nasync function lockMissingPidIsStale(lockDir: string): Promise<boolean> {\n\ttry {\n\t\tconst lockStat = await stat(lockDir);\n\t\treturn Date.now() - lockStat.mtimeMs > BOOTSTRAP_LOCK_STALE_WITHOUT_PID_MS;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function acquireBootstrapLock(venv: string): Promise<() => Promise<void>> {\n\tconst lockDir = bootstrapLockDir(venv);\n\tawait mkdir(path.dirname(lockDir), { recursive: true });\n\n\tfor (;;) {\n\t\ttry {\n\t\t\tawait mkdir(lockDir);\n\t\t\tawait writeFile(path.join(lockDir, \"pid\"), `${process.pid}\\n`, \"utf8\");\n\t\t\treturn () => rm(lockDir, { recursive: true, force: true });\n\t\t} catch (error) {\n\t\t\tif (!isNodeError(error, \"EEXIST\")) throw error;\n\n\t\t\tconst pid = await readLockPid(lockDir);\n\t\t\tif (pid === null ? await lockMissingPidIsStale(lockDir) : !processIsRunning(pid)) {\n\t\t\t\tawait rm(lockDir, { recursive: true, force: true });\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tawait sleep(BOOTSTRAP_LOCK_RETRY_MS);\n\t\t}\n\t}\n}\n\nasync function findExecutable(name: string): Promise<string | null> {\n\tconst pathValue = process.env.PATH;\n\tif (!pathValue) return null;\n\tconst candidates = process.platform === \"win32\" ? [name, `${name}.exe`] : [name];\n\tfor (const dir of pathValue.split(path.delimiter)) {\n\t\tif (!dir) continue;\n\t\tfor (const candidate of candidates) {\n\t\t\tconst fullPath = path.join(dir, candidate);\n\t\t\tif (await isExecutable(fullPath)) return fullPath;\n\t\t}\n\t}\n\treturn null;\n}\n\nasync function ensureUv(options: EnsureKernelPythonOptions): Promise<string> {\n\tconst fromPath = await findExecutable(\"uv\");\n\tif (fromPath) return fromPath;\n\n\tconst localUv = path.join(os.homedir(), \".local\", \"bin\", process.platform === \"win32\" ? \"uv.exe\" : \"uv\");\n\tif (await isExecutable(localUv)) return localUv;\n\n\tconst shouldInstallUv =\n\t\tprocess.env[PRODUCT_ENV.installUv] === \"1\" || (!options.onProgress && (await confirmUvInstall()));\n\tif (!shouldInstallUv) {\n\t\tthrow new Error(\n\t\t\t`uv is required to set up the Python kernel. Install uv yourself: ${UV_INSTALL_COMMAND}, ` +\n\t\t\t\t\"or set BASE_CONTEXT_INSTALL_UV=1 to let base-context run that installer.\",\n\t\t);\n\t}\n\n\treportProgress(options, \"› installing uv (one-time)…\");\n\ttry {\n\t\tawait run(\"sh\", [\"-c\", UV_INSTALL_COMMAND], {\n\t\t\tstdio: options.onProgress ? \"ignore\" : \"inherit\",\n\t\t\tenv: { ...process.env, UV_INSTALL_DIR: path.dirname(localUv) },\n\t\t});\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`couldn't install uv from astral.sh; install it yourself: ${UV_INSTALL_COMMAND}, then re-run base-context. ${errorMessage(error)}`,\n\t\t);\n\t}\n\n\tif (await isExecutable(localUv)) return localUv;\n\tconst installedFromPath = await findExecutable(\"uv\");\n\tif (installedFromPath) return installedFromPath;\n\tthrow new Error(\"uv install completed but binary not found at ~/.local/bin/uv\");\n}\n\nasync function confirmUvInstall(): Promise<boolean> {\n\tif (process.env[PRODUCT_ENV.installUv] === \"0\") return false;\n\tif (!stdin.isTTY || !stderr.isTTY) return false;\n\n\tconst rl = createInterface({ input: stdin, output: stderr });\n\ttry {\n\t\tconst answer = (\n\t\t\tawait rl.question(\"Base Context needs uv to set up Python. Install uv from astral.sh now? [Y/n] \")\n\t\t)\n\t\t\t.trim()\n\t\t\t.toLowerCase();\n\t\treturn answer !== \"n\" && answer !== \"no\";\n\t} finally {\n\t\trl.close();\n\t}\n}\n\nasync function readBootstrapVersion(venv: string): Promise<BootstrapVersion | null> {\n\ttry {\n\t\tconst raw = await readFile(path.join(venv, BOOTSTRAP_VERSION_FILE), \"utf8\");\n\t\tconst parsed: unknown = JSON.parse(raw);\n\t\tif (!isRecord(parsed) || typeof parsed.schema !== \"number\") return null;\n\t\tconst extraUvArgs =\n\t\t\tArray.isArray(parsed.extraUvArgs) &&\n\t\t\tparsed.extraUvArgs.every((v: unknown): v is string => typeof v === \"string\")\n\t\t\t\t? (parsed.extraUvArgs as string[])\n\t\t\t\t: undefined;\n\t\tlet pythonSkills: BootstrapPythonSkill[] | undefined;\n\t\tif (Array.isArray(parsed.pythonSkills)) {\n\t\t\tif (\n\t\t\t\t!parsed.pythonSkills.every((v: unknown): v is BootstrapPythonSkill => {\n\t\t\t\t\tif (!isRecord(v)) return false;\n\t\t\t\t\treturn (\n\t\t\t\t\t\ttypeof v.importName === \"string\" &&\n\t\t\t\t\t\ttypeof v.packagePath === \"string\" &&\n\t\t\t\t\t\ttypeof v.pyprojectPath === \"string\" &&\n\t\t\t\t\t\ttypeof v.pyprojectHash === \"string\"\n\t\t\t\t\t);\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tpythonSkills = parsed.pythonSkills as BootstrapPythonSkill[];\n\t\t}\n\t\treturn {\n\t\t\tschema: parsed.schema,\n\t\t\truntime: typeof parsed.runtime === \"string\" ? parsed.runtime : undefined,\n\t\t\tsnapshot: typeof parsed.snapshot === \"string\" ? parsed.snapshot : undefined,\n\t\t\textraUvArgs,\n\t\t\tpythonSkills,\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction extraUvArgsMatch(a: string[] | undefined, b: string[] | undefined): boolean {\n\tif (a === b) return true;\n\tif (!a || !b) return false;\n\tif (a.length !== b.length) return false;\n\treturn a.every((v, i) => v === b[i]);\n}\n\nfunction pythonSkillsMatch(a: BootstrapPythonSkill[] | undefined, b: readonly BootstrapPythonSkill[]): boolean {\n\tconst left = a ?? [];\n\tif (left.length !== b.length) return false;\n\treturn left.every((skill, index) => {\n\t\tconst expected = b[index];\n\t\treturn (\n\t\t\tskill.importName === expected.importName &&\n\t\t\tskill.packagePath === expected.packagePath &&\n\t\t\tskill.pyprojectPath === expected.pyprojectPath &&\n\t\t\tskill.pyprojectHash === expected.pyprojectHash\n\t\t);\n\t});\n}\n\nfunction bootstrapVersionCurrent(\n\tversion: BootstrapVersion | null,\n\truntimeIdentity: string,\n\tpythonSkills: readonly BootstrapPythonSkill[],\n): boolean {\n\treturn (\n\t\tversion !== null &&\n\t\tbootstrapBaseVersionCurrent(version, runtimeIdentity) &&\n\t\tpythonSkillsMatch(version.pythonSkills, pythonSkills)\n\t);\n}\n\nfunction bootstrapBaseVersionCurrent(version: BootstrapVersion | null, runtimeIdentity: string): boolean {\n\treturn (\n\t\tversion?.schema === BOOTSTRAP_SCHEMA &&\n\t\tversion.runtime === runtimeIdentity &&\n\t\tversion.snapshot === STATE_SNAPSHOT_REQUIREMENT &&\n\t\textraUvArgsMatch(version.extraUvArgs, DEFAULT_RLM_EXTRA_UV_ARGS)\n\t);\n}\n\nasync function writeBootstrapVersion(\n\tvenv: string,\n\truntimeIdentity: string,\n\tpythonSkills: readonly BootstrapPythonSkill[],\n): Promise<void> {\n\tconst version: BootstrapVersion = {\n\t\tschema: BOOTSTRAP_SCHEMA,\n\t\truntime: runtimeIdentity,\n\t\tsnapshot: STATE_SNAPSHOT_REQUIREMENT,\n\t\textraUvArgs: DEFAULT_RLM_EXTRA_UV_ARGS,\n\t\tpythonSkills: [...pythonSkills],\n\t};\n\tawait writeFile(path.join(venv, BOOTSTRAP_VERSION_FILE), `${JSON.stringify(version)}\\n`, \"utf8\");\n}\n\nexport function runtimeCandidateDirs(): string[] {\n\tif (ownedRuntime) return [path.join(ownedRuntime.packageDir, \"dist\", RUNTIME_REQUIREMENT)];\n\tconst packageDir = getPackageDir();\n\tif (existsSync(path.join(packageDir, \"src\"))) {\n\t\treturn [path.resolve(packageDir, \"..\", \"..\", \"prime-agent-runtime\")];\n\t}\n\treturn [path.join(packageDir, \"dist\", RUNTIME_REQUIREMENT), path.join(packageDir, RUNTIME_REQUIREMENT)];\n}\n\nasync function resolveRuntimeSourceDir(): Promise<string> {\n\tfor (const candidate of runtimeCandidateDirs()) {\n\t\tif (await exists(path.join(candidate, \"pyproject.toml\"))) return candidate;\n\t}\n\tthrow new Error(\n\t\t\"Base Context runtime payload is missing. Reinstall this Base Context release; registry runtime fallback is disabled.\",\n\t);\n}\n\nexport async function resolveRuntimeIdentity(): Promise<string> {\n\treturn hashRuntimeSource(await resolveRuntimeSourceDir());\n}\n\n// A source read failure must not be replaced by a registry runtime.\nasync function hashRuntimeSource(sourceDir: string): Promise<string> {\n\tconst rlmDir = path.join(sourceDir, \"src\", \"rlm\");\n\tconst files: string[] = [path.join(sourceDir, \"pyproject.toml\")];\n\tasync function collect(dir: string): Promise<void> {\n\t\tconst entries = await readdir(dir, { withFileTypes: true });\n\t\tfor (const entry of entries) {\n\t\t\tconst full = path.join(dir, entry.name);\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tawait collect(full);\n\t\t\t} else if (entry.isFile() && entry.name.endsWith(\".py\")) {\n\t\t\t\tfiles.push(full);\n\t\t\t}\n\t\t}\n\t}\n\tawait collect(rlmDir);\n\tfiles.sort();\n\tconst hash = createHash(\"sha256\");\n\tfor (const file of files) {\n\t\thash.update(path.relative(sourceDir, file));\n\t\thash.update(\"\\0\");\n\t\thash.update(await readFile(file));\n\t\thash.update(\"\\0\");\n\t}\n\treturn `sha256:${hash.digest(\"hex\")}`;\n}\n\nasync function bootstrapVenv(\n\tvenv: string,\n\tpythonSkills: readonly BootstrapPythonSkill[],\n\toptions: EnsureKernelPythonOptions,\n): Promise<void> {\n\tawait mkdir(path.dirname(venv), { recursive: true });\n\tconst uv = await ensureUv(options);\n\tconst python = path.join(venv, \"bin\", \"python\");\n\tconst sourceDir = await resolveRuntimeSourceDir();\n\tconst runtimeRequirement = sourceDir;\n\tconst runtimeIdentity = await resolveRuntimeIdentity();\n\n\tawait run(uv, [\"python\", \"install\", PYTHON_VERSION]);\n\tawait run(uv, [\"venv\", venv, \"--python\", PYTHON_VERSION, \"--seed\"]);\n\tawait run(uv, [\n\t\t\"pip\",\n\t\t\"install\",\n\t\t\"--python\",\n\t\tpython,\n\t\truntimeRequirement,\n\t\tSTATE_SNAPSHOT_REQUIREMENT,\n\t\t...DEFAULT_RLM_EXTRA_UV_ARGS,\n\t]);\n\tawait syncPythonSkills(uv, venv, python, runtimeIdentity, pythonSkills, options);\n}\n\nasync function syncPythonSkills(\n\tuv: string,\n\tvenv: string,\n\tpython: string,\n\truntimeIdentity: string,\n\tpythonSkills: readonly BootstrapPythonSkill[],\n\toptions: EnsureKernelPythonOptions,\n): Promise<void> {\n\tconst version = await readBootstrapVersion(venv);\n\tconst installedPythonSkills: BootstrapPythonSkill[] = [];\n\tconst currentPythonSkills = new Map(\n\t\t(version?.pythonSkills ?? []).map((skill) => [`${skill.importName}\\0${skill.packagePath}`, skill]),\n\t);\n\tconst pythonSkillsByProjectName = new Map(\n\t\tpythonSkills.map((skill) => [readPythonSkillProjectName(skill).replaceAll(\"_\", \"-\").toLowerCase(), skill]),\n\t);\n\tconst dependenciesBySkill = new Map(\n\t\tpythonSkills.map((skill) => [\n\t\t\tskill,\n\t\t\t[...readPythonSkillDependencyNames(skill)]\n\t\t\t\t.map(\n\t\t\t\t\t(dependencyName) =>\n\t\t\t\t\t\tpythonSkillsByProjectName.get(dependencyName) ??\n\t\t\t\t\t\tresolveSiblingPythonSkillDependency(skill, dependencyName),\n\t\t\t\t)\n\t\t\t\t.filter((dependency): dependency is BootstrapPythonSkill => Boolean(dependency)),\n\t\t]),\n\t);\n\n\tfor (const skill of sortPythonSkillsForInstall(pythonSkills)) {\n\t\tconst existingSkill = currentPythonSkills.get(`${skill.importName}\\0${skill.packagePath}`);\n\t\tif (existingSkill?.pyprojectPath === skill.pyprojectPath && existingSkill.pyprojectHash === skill.pyprojectHash) {\n\t\t\tinstalledPythonSkills.push(skill);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst localDependencies = dependenciesBySkill.get(skill) ?? [];\n\t\tconst localDependencyArgs = localDependencies\n\t\t\t.filter((dependency) => {\n\t\t\t\tconst installedDependency = currentPythonSkills.get(`${dependency.importName}\\0${dependency.packagePath}`);\n\t\t\t\tconst installedThisSync = installedPythonSkills.some(\n\t\t\t\t\t(installed) =>\n\t\t\t\t\t\tinstalled.importName === dependency.importName &&\n\t\t\t\t\t\tinstalled.packagePath === dependency.packagePath &&\n\t\t\t\t\t\tinstalled.pyprojectPath === dependency.pyprojectPath &&\n\t\t\t\t\t\tinstalled.pyprojectHash === dependency.pyprojectHash,\n\t\t\t\t);\n\t\t\t\treturn !(\n\t\t\t\t\tinstalledThisSync ||\n\t\t\t\t\t(installedDependency?.pyprojectPath === dependency.pyprojectPath &&\n\t\t\t\t\t\tinstalledDependency.pyprojectHash === dependency.pyprojectHash)\n\t\t\t\t);\n\t\t\t})\n\t\t\t.flatMap(formatPythonSkillInstallArgs);\n\n\t\ttry {\n\t\t\tawait run(uv, [\n\t\t\t\t\"pip\",\n\t\t\t\t\"install\",\n\t\t\t\t\"--python\",\n\t\t\t\tpython,\n\t\t\t\t...formatPythonSkillInstallArgs(skill),\n\t\t\t\t...localDependencyArgs,\n\t\t\t]);\n\t\t\tinstalledPythonSkills.push(\n\t\t\t\tskill,\n\t\t\t\t...localDependencies.filter((dependency) => !installedPythonSkills.includes(dependency)),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\treportProgress(\n\t\t\t\toptions,\n\t\t\t\t`Warning: Python skill ${skill.importName} failed to install and will be unavailable: ${errorMessage(error)}`,\n\t\t\t);\n\t\t}\n\t}\n\tawait writeBootstrapVersion(venv, runtimeIdentity, installedPythonSkills);\n}\n\nasync function kernelBaseReady(python: string, venv: string, runtimeIdentity: string): Promise<boolean> {\n\treturn (\n\t\t(await hasBaseContextRuntime(python)) &&\n\t\tbootstrapBaseVersionCurrent(await readBootstrapVersion(venv), runtimeIdentity)\n\t);\n}\n\nasync function kernelReady(\n\tpython: string,\n\tvenv: string,\n\truntimeIdentity: string,\n\tpythonSkills: readonly BootstrapPythonSkill[],\n): Promise<boolean> {\n\treturn (\n\t\t(await hasBaseContextRuntime(python)) &&\n\t\tbootstrapVersionCurrent(await readBootstrapVersion(venv), runtimeIdentity, pythonSkills)\n\t);\n}\n\nfunction formatBootstrapFailure(error: unknown): Error {\n\treturn new Error(\n\t\t`Failed to set up the Python kernel runtime. ${errorMessage(error)}\\n` +\n\t\t\t\"First-time setup needs internet to install uv, Python, the bundled base-context-runtime, and default Python packages; once set up, base-context runs offline. \" +\n\t\t\t\"Set BASE_CONTEXT_KERNEL_PYTHON to a Python with a current base-context-runtime and default Python packages installed to skip auto-bootstrap.\",\n\t);\n}\n\nasync function ensureKernelPythonUncached(\n\toptions: EnsureKernelPythonOptions,\n\tpythonSkills: readonly BootstrapPythonSkill[],\n): Promise<string> {\n\tconst override = readAbsolutePathEnv(PRODUCT_ENV.kernelPython);\n\tif (override) {\n\t\tconst python = override;\n\t\tconst missing: string[] = [];\n\t\tif (!(await hasBaseContextRuntime(python))) {\n\t\t\tmissing.push(\n\t\t\t\t\"a current base-context-runtime with callable rlm.run, rlm.host_request, and explicit harness CRUD methods\",\n\t\t\t);\n\t\t}\n\t\tif (missing.length === 0) {\n\t\t\tconst missingExtraImports = await missingRlmExtraImportLabels(python);\n\t\t\tif (missingExtraImports.length > 0) {\n\t\t\t\tmissing.push(`default Python packages (${missingExtraImports.join(\", \")})`);\n\t\t\t}\n\t\t}\n\t\tif (missing.length === 0 && pythonSkills.length > 0) {\n\t\t\tconst missingPythonSkills = await missingPythonSkillImportLabels(python, options.pythonSkills ?? []);\n\t\t\tif (missingPythonSkills.length > 0) {\n\t\t\t\treportProgress(\n\t\t\t\t\toptions,\n\t\t\t\t\t`Warning: Python skills unavailable in BASE_CONTEXT_KERNEL_PYTHON and will be disabled: ${missingPythonSkills.join(\", \")}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tif (missing.length === 0) return python;\n\t\tthrow new Error(`BASE_CONTEXT_KERNEL_PYTHON points to a Python missing ${missing.join(\" and \")}: ${python}`);\n\t}\n\n\tconst venv = await resolveWritableKernelVenvDir();\n\tconst python = path.join(venv, \"bin\", \"python\");\n\tconst runtimeIdentity = await resolveRuntimeIdentity();\n\tif (await kernelReady(python, venv, runtimeIdentity, pythonSkills)) return python;\n\n\tconst releaseLock = await acquireBootstrapLock(venv);\n\ttry {\n\t\tif (await kernelReady(python, venv, runtimeIdentity, pythonSkills)) return python;\n\t\tif (await kernelBaseReady(python, venv, runtimeIdentity)) {\n\t\t\tawait syncPythonSkills(await ensureUv(options), venv, python, runtimeIdentity, pythonSkills, options);\n\t\t\treturn python;\n\t\t}\n\n\t\tif (ownedRuntime && !readAbsolutePathEnv(PRODUCT_ENV.kernelVenv)) {\n\t\t\tthrow new Error(\n\t\t\t\t\"The selected Base-Context default runtime is unavailable or stale. Install a prepared candidate or explicitly roll back; the retained runtime was not rebuilt.\",\n\t\t\t);\n\t\t}\n\n\t\tconst hadVenv = existsSync(venv);\n\t\treportProgress(options, \"› setting up python kernel (one-time, ~30s)…\");\n\t\tif (hadVenv) {\n\t\t\treportProgress(options, \"rebuilding kernel venv\");\n\t\t\tawait rm(venv, { recursive: true, force: true });\n\t\t}\n\n\t\tawait bootstrapVenv(venv, pythonSkills, options);\n\t} catch (error) {\n\t\tthrow formatBootstrapFailure(error);\n\t} finally {\n\t\tawait releaseLock().catch(() => undefined);\n\t}\n\n\treportProgress(options, \"✓ ready\");\n\treturn python;\n}\n\nexport function ensureKernelPython(options: EnsureKernelPythonOptions = {}): Promise<string> {\n\tconst pythonSkills = normalizePythonSkills(options.pythonSkills);\n\tconst key = ensureKernelPythonKey(pythonSkills);\n\tif (inFlightEnsureKernelPython?.key === key) return inFlightEnsureKernelPython.promise;\n\n\tconst promise = ensureKernelPythonUncached(options, pythonSkills).finally(() => {\n\t\tif (inFlightEnsureKernelPython?.promise === promise) inFlightEnsureKernelPython = null;\n\t});\n\tinFlightEnsureKernelPython = { key, promise };\n\treturn promise;\n}\n\n/** Prepare only a new physical owned release, before its selection can be published. */\nexport async function prepareOwnedKernelPython(): Promise<string> {\n\tif (!ownedRuntime || existsSync(ownedRuntime.runtimeDir)) {\n\t\tthrow new Error(\"Base-Context runtime preparation requires a new, empty owned release runtime directory.\");\n\t}\n\tconst selected = readInstallSelection(ownedRuntime.root);\n\tif (selected?.active === ownedRuntime.version || selected?.previous === ownedRuntime.version) {\n\t\tthrow new Error(\"Base-Context will not prepare a published release in place. Install a new candidate instead.\");\n\t}\n\tconst python = path.join(ownedRuntime.runtimeDir, \"bin\", \"python\");\n\tconst options: EnsureKernelPythonOptions = { onProgress: (message) => console.error(message) };\n\tawait bootstrapVenv(ownedRuntime.runtimeDir, [], options);\n\tconst runtimeIdentity = await resolveRuntimeIdentity();\n\tif (\n\t\t!(await kernelReady(python, ownedRuntime.runtimeDir, runtimeIdentity, [])) ||\n\t\t(await missingRlmExtraImportLabels(python)).length > 0\n\t) {\n\t\tthrow new Error(\"Base-Context candidate Python runtime did not become ready. This candidate was not activated.\");\n\t}\n\treturn python;\n}\n"]}
@@ -294,7 +294,7 @@ async function resolveWritableKernelVenvDir() {
294
294
  function run(command, args, options = {}) {
295
295
  return new Promise((resolve, reject) => {
296
296
  const child = spawn(command, args, {
297
- env: process.env,
297
+ env: options.env ?? process.env,
298
298
  stdio: options.stdio ?? "ignore",
299
299
  });
300
300
  child.on("error", reject);
@@ -433,7 +433,10 @@ async function ensureUv(options) {
433
433
  }
434
434
  reportProgress(options, "› installing uv (one-time)…");
435
435
  try {
436
- await run("sh", ["-c", UV_INSTALL_COMMAND], { stdio: options.onProgress ? "ignore" : "inherit" });
436
+ await run("sh", ["-c", UV_INSTALL_COMMAND], {
437
+ stdio: options.onProgress ? "ignore" : "inherit",
438
+ env: { ...process.env, UV_INSTALL_DIR: path.dirname(localUv) },
439
+ });
437
440
  }
438
441
  catch (error) {
439
442
  throw new Error(`couldn't install uv from astral.sh; install it yourself: ${UV_INSTALL_COMMAND}, then re-run base-context. ${errorMessage(error)}`);