open-multi-agent-kit 0.94.0 → 0.95.0

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 (109) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +100 -646
  3. package/dist/core/agent-session.d.ts.map +1 -1
  4. package/dist/core/agent-session.js +11 -11
  5. package/dist/core/agent-session.js.map +1 -1
  6. package/dist/core/auth-storage.d.ts +27 -2
  7. package/dist/core/auth-storage.d.ts.map +1 -1
  8. package/dist/core/auth-storage.js +239 -56
  9. package/dist/core/auth-storage.js.map +1 -1
  10. package/dist/core/context-budget-v2-cache-invalidation.d.ts.map +1 -1
  11. package/dist/core/context-budget-v2-cache-invalidation.js +1 -1
  12. package/dist/core/context-budget-v2-cache-invalidation.js.map +1 -1
  13. package/dist/core/context-budget-v2-cache-provider.d.ts +5 -1
  14. package/dist/core/context-budget-v2-cache-provider.d.ts.map +1 -1
  15. package/dist/core/context-budget-v2-cache-provider.js +37 -7
  16. package/dist/core/context-budget-v2-cache-provider.js.map +1 -1
  17. package/dist/core/context-budget-v2-cache-telemetry.d.ts +1 -1
  18. package/dist/core/context-budget-v2-cache-telemetry.d.ts.map +1 -1
  19. package/dist/core/context-budget-v2-cache-telemetry.js +2 -1
  20. package/dist/core/context-budget-v2-cache-telemetry.js.map +1 -1
  21. package/dist/core/context-budget-v2-cache.d.ts.map +1 -1
  22. package/dist/core/context-budget-v2-cache.js +3 -0
  23. package/dist/core/context-budget-v2-cache.js.map +1 -1
  24. package/dist/core/context-budget-v2-representation-cache.d.ts.map +1 -1
  25. package/dist/core/context-budget-v2-representation-cache.js +4 -3
  26. package/dist/core/context-budget-v2-representation-cache.js.map +1 -1
  27. package/dist/core/context-budget-v2-selection.d.ts.map +1 -1
  28. package/dist/core/context-budget-v2-selection.js +4 -0
  29. package/dist/core/context-budget-v2-selection.js.map +1 -1
  30. package/dist/core/context-budget-v2-types.d.ts +3 -0
  31. package/dist/core/context-budget-v2-types.d.ts.map +1 -1
  32. package/dist/core/context-budget-v2-types.js.map +1 -1
  33. package/dist/core/extensions/types.d.ts +2 -0
  34. package/dist/core/extensions/types.d.ts.map +1 -1
  35. package/dist/core/extensions/types.js.map +1 -1
  36. package/dist/core/github-repository.d.ts +3 -0
  37. package/dist/core/github-repository.d.ts.map +1 -0
  38. package/dist/core/github-repository.js +3 -0
  39. package/dist/core/github-repository.js.map +1 -0
  40. package/dist/core/model-registry.d.ts +3 -3
  41. package/dist/core/model-registry.d.ts.map +1 -1
  42. package/dist/core/model-registry.js +9 -8
  43. package/dist/core/model-registry.js.map +1 -1
  44. package/dist/core/provider-usage.d.ts +48 -0
  45. package/dist/core/provider-usage.d.ts.map +1 -0
  46. package/dist/core/provider-usage.js +780 -0
  47. package/dist/core/provider-usage.js.map +1 -0
  48. package/dist/core/sdk.d.ts.map +1 -1
  49. package/dist/core/sdk.js +10 -0
  50. package/dist/core/sdk.js.map +1 -1
  51. package/dist/core/session-termination.d.ts.map +1 -1
  52. package/dist/core/session-termination.js +8 -1
  53. package/dist/core/session-termination.js.map +1 -1
  54. package/dist/core/settings-manager.d.ts +1 -0
  55. package/dist/core/settings-manager.d.ts.map +1 -1
  56. package/dist/core/settings-manager.js +15 -8
  57. package/dist/core/settings-manager.js.map +1 -1
  58. package/dist/core/skills-catalog-cache.d.ts +1 -0
  59. package/dist/core/skills-catalog-cache.d.ts.map +1 -1
  60. package/dist/core/skills-catalog-cache.js +42 -11
  61. package/dist/core/skills-catalog-cache.js.map +1 -1
  62. package/dist/core/slash-commands.d.ts.map +1 -1
  63. package/dist/core/slash-commands.js +1 -0
  64. package/dist/core/slash-commands.js.map +1 -1
  65. package/dist/core/tools/read.d.ts +1 -1
  66. package/dist/core/tools/read.d.ts.map +1 -1
  67. package/dist/core/tools/read.js.map +1 -1
  68. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  69. package/dist/modes/interactive/components/footer.js.map +1 -1
  70. package/dist/modes/interactive/components/index.d.ts +1 -0
  71. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  72. package/dist/modes/interactive/components/index.js +1 -0
  73. package/dist/modes/interactive/components/index.js.map +1 -1
  74. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  75. package/dist/modes/interactive/components/model-selector.js +5 -3
  76. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  77. package/dist/modes/interactive/components/oauth-account-selector.d.ts +16 -0
  78. package/dist/modes/interactive/components/oauth-account-selector.d.ts.map +1 -0
  79. package/dist/modes/interactive/components/oauth-account-selector.js +61 -0
  80. package/dist/modes/interactive/components/oauth-account-selector.js.map +1 -0
  81. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  82. package/dist/modes/interactive/components/oauth-selector.js +25 -4
  83. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  84. package/dist/modes/interactive/components/status-sidebar.d.ts +21 -1
  85. package/dist/modes/interactive/components/status-sidebar.d.ts.map +1 -1
  86. package/dist/modes/interactive/components/status-sidebar.js +165 -6
  87. package/dist/modes/interactive/components/status-sidebar.js.map +1 -1
  88. package/dist/modes/interactive/interactive-mode.d.ts +2 -0
  89. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  90. package/dist/modes/interactive/interactive-mode.js +99 -15
  91. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  92. package/dist/utils/image-resize-core.d.ts.map +1 -1
  93. package/dist/utils/image-resize-core.js +2 -2
  94. package/dist/utils/image-resize-core.js.map +1 -1
  95. package/docs/development.md +3 -2
  96. package/docs/providers.md +19 -4
  97. package/docs/settings.md +9 -9
  98. package/docs/usage.md +10 -9
  99. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  100. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  101. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  102. package/examples/extensions/gondolin/package-lock.json +2 -2
  103. package/examples/extensions/gondolin/package.json +1 -1
  104. package/examples/extensions/sandbox/package-lock.json +2 -2
  105. package/examples/extensions/sandbox/package.json +1 -1
  106. package/examples/extensions/with-deps/package-lock.json +2 -2
  107. package/examples/extensions/with-deps/package.json +1 -1
  108. package/npm-shrinkwrap.json +24 -24
  109. package/package.json +6 -6
@@ -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 OMK instances\n * try to refresh tokens simultaneously.\n */\n\nimport { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport {\n\tfindEnvKeys,\n\tgetEnvApiKey,\n\ttype OAuthCredentials,\n\ttype OAuthLoginCallbacks,\n\ttype OAuthProviderId,\n} from \"omk-ai\";\nimport { getOAuthApiKey, getOAuthProvider, getOAuthProviders } from \"omk-ai/oauth\";\nimport { dirname, join } from \"path\";\nimport lockfile from \"proper-lockfile\";\nimport { getAgentDir } from \"../config.ts\";\nimport { normalizePath } from \"../utils/paths.ts\";\nimport { resolveConfigValue } from \"./resolve-config-value.ts\";\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\";\n\tlabel?: string;\n};\n\ntype LockResult<T> = {\n\tresult: T;\n\tnext?: string;\n};\n\nconst AUTH_FILE_WRITE_OPTIONS = { encoding: \"utf-8\", mode: 0o600 } as const;\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\tprivate authPath: string;\n\n\tconstructor(authPath: string = join(getAgentDir(), \"auth.json\")) {\n\t\tthis.authPath = normalizePath(authPath);\n\t}\n\n\tprivate ensureParentDir(): void {\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, \"{}\", AUTH_FILE_WRITE_OPTIONS);\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\n\t\tfor (let attempt = 1; attempt <= maxAttempts; attempt++) {\n\t\t\ttry {\n\t\t\t\treturn lockfile.lockSync(path, { realpath: false });\n\t\t\t} catch (error) {\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, AUTH_FILE_WRITE_OPTIONS);\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, AUTH_FILE_WRITE_OPTIONS);\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\ttry {\n\t\t\t\t\tawait release();\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore unlock errors when lock is compromised.\n\t\t\t\t}\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 fallbackResolver?: (provider: string) => string | undefined;\n\tprivate loadError: Error | null = null;\n\tprivate errors: Error[] = [];\n\tprivate storage: AuthStorageBackend;\n\n\tprivate constructor(storage: AuthStorageBackend) {\n\t\tthis.storage = storage;\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\tstatic fromStorage(storage: AuthStorageBackend): AuthStorage {\n\t\treturn new AuthStorage(storage);\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.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.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 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.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\tdelete this.data[provider];\n\t\tthis.persistProviderChange(provider, undefined);\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\tif (this.runtimeOverrides.has(provider)) return true;\n\t\tif (this.data[provider]) return true;\n\t\tif (getEnvApiKey(provider)) return true;\n\t\tif (this.fallbackResolver?.(provider)) return true;\n\t\treturn false;\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\tif (this.data[provider]) {\n\t\t\treturn { configured: true, source: \"stored\" };\n\t\t}\n\n\t\tif (this.runtimeOverrides.has(provider)) {\n\t\t\treturn { configured: false, source: \"runtime\", label: \"--api-key\" };\n\t\t}\n\n\t\tconst envKeys = findEnvKeys(provider);\n\t\tif (envKeys?.[0]) {\n\t\t\treturn { configured: false, source: \"environment\", label: envKeys[0] };\n\t\t}\n\n\t\tif (this.fallbackResolver?.(provider)) {\n\t\t\treturn { configured: false, source: \"fallback\", label: \"custom provider config\" };\n\t\t}\n\n\t\treturn { configured: false };\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\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 OMK 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\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\") {\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. API key from auth.json\n\t * 3. OAuth token from auth.json (auto-refreshed with locking)\n\t * 4. Environment variable\n\t * 5. Fallback resolver (models.json custom providers)\n\t */\n\tasync getApiKey(providerId: string, options?: { includeFallback?: boolean }): Promise<string | undefined> {\n\t\t// Runtime override takes highest priority\n\t\tconst runtimeKey = this.runtimeOverrides.get(providerId);\n\t\tif (runtimeKey) {\n\t\t\treturn runtimeKey;\n\t\t}\n\n\t\tconst cred = this.data[providerId];\n\n\t\tif (cred?.type === \"api_key\") {\n\t\t\treturn resolveConfigValue(cred.key);\n\t\t}\n\n\t\tif (cred?.type === \"oauth\") {\n\t\t\tconst provider = getOAuthProvider(providerId);\n\t\t\tif (!provider) {\n\t\t\t\t// Unknown OAuth provider, can't get API key\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\t// Check if token needs refresh\n\t\t\tconst needsRefresh = Date.now() >= cred.expires;\n\n\t\t\tif (needsRefresh) {\n\t\t\t\t// Use locked refresh to prevent race conditions\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await this.refreshOAuthTokenWithLock(providerId);\n\t\t\t\t\tif (result) {\n\t\t\t\t\t\treturn result.apiKey;\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.recordError(error);\n\t\t\t\t\t// Refresh failed - re-read file to check if another instance succeeded\n\t\t\t\t\tthis.reload();\n\t\t\t\t\tconst updatedCred = this.data[providerId];\n\n\t\t\t\t\tif (updatedCred?.type === \"oauth\" && Date.now() < updatedCred.expires) {\n\t\t\t\t\t\t// Another instance refreshed successfully, use those credentials\n\t\t\t\t\t\treturn provider.getApiKey(updatedCred);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Refresh truly failed - return undefined so model discovery skips this provider\n\t\t\t\t\t// User can /login to re-authenticate (credentials preserved for retry)\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Token not expired, use current access token\n\t\t\t\treturn provider.getApiKey(cred);\n\t\t\t}\n\t\t}\n\n\t\t// Fall back to environment variable\n\t\tconst envKey = getEnvApiKey(providerId);\n\t\tif (envKey) return envKey;\n\n\t\t// Fall back to custom resolver (e.g., models.json custom providers)\n\t\tif (options?.includeFallback !== false) {\n\t\t\treturn this.fallbackResolver?.(providerId) ?? undefined;\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Get all registered OAuth providers\n\t */\n\tgetOAuthProviders() {\n\t\treturn getOAuthProviders();\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 OMK instances\n * try to refresh tokens simultaneously.\n */\n\nimport { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport {\n\tfindEnvKeys,\n\tgetEnvApiKey,\n\ttype OAuthCredentials,\n\ttype OAuthLoginCallbacks,\n\ttype OAuthProviderId,\n} from \"omk-ai\";\nimport { getOAuthApiKey, getOAuthProvider, getOAuthProviders } from \"omk-ai/oauth\";\nimport { dirname, join } from \"path\";\nimport lockfile from \"proper-lockfile\";\nimport { getAgentDir } from \"../config.ts\";\nimport { stripAnsi } from \"../utils/ansi.ts\";\nimport { normalizePath } from \"../utils/paths.ts\";\nimport { resolveConfigValue } from \"./resolve-config-value.ts\";\n\nexport type ApiKeyCredential = {\n\ttype: \"api_key\";\n\tkey: string;\n};\n\nexport type OAuthCredential = {\n\ttype: \"oauth\";\n\t/** Complete account list when more than one subscription account is configured. */\n\taccounts?: OAuthCredentials[];\n\t/** Index of the account explicitly selected for this provider. */\n\tactiveAccount?: number;\n\t/** Legacy cursor accepted when migrating older auth.json files. */\n\tnextAccount?: number;\n} & OAuthCredentials;\n\nexport interface OAuthAccountSummary {\n\tindex: number;\n\tlabel: string;\n\tselected: boolean;\n}\n\nexport type AuthCredential = ApiKeyCredential | OAuthCredential;\n\nexport type AuthStorageData = Record<string, AuthCredential>;\n\nconst OAUTH_ACCOUNT_ID_FIELDS = [\"accountId\", \"email\", \"userId\", \"username\"] as const;\nconst OAUTH_ACCOUNT_LABEL_FIELDS = [\"email\", \"username\"] as const;\nconst OAUTH_ACCOUNT_LABEL_MAX_LENGTH = 96;\nconst UNSAFE_ACCOUNT_LABEL_PATTERN =\n\t/[\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f\\u007f-\\u009f\\u200b-\\u200f\\u202a-\\u202e\\u2060-\\u206f\\ufeff]/g;\n\nfunction sanitizeOAuthAccountLabel(value: string): string | undefined {\n\tconst sanitized = stripAnsi(value)\n\t\t.replace(/[\\t\\r\\n]+/g, \" \")\n\t\t.replace(UNSAFE_ACCOUNT_LABEL_PATTERN, \"\")\n\t\t.replace(/\\s+/g, \" \")\n\t\t.trim()\n\t\t.slice(0, OAUTH_ACCOUNT_LABEL_MAX_LENGTH);\n\treturn sanitized || undefined;\n}\n\nfunction stripOAuthStorageMetadata(credential: OAuthCredential): OAuthCredentials {\n\tconst {\n\t\ttype: _type,\n\t\taccounts: _accounts,\n\t\tactiveAccount: _activeAccount,\n\t\tnextAccount: _nextAccount,\n\t\t...credentials\n\t} = credential;\n\treturn credentials;\n}\n\nfunction getOAuthAccounts(credential: OAuthCredential): OAuthCredentials[] {\n\tif (Array.isArray(credential.accounts) && credential.accounts.length > 0) {\n\t\treturn credential.accounts;\n\t}\n\treturn [stripOAuthStorageMetadata(credential)];\n}\n\nfunction normalizeOAuthAccountIndex(index: unknown, accountCount: number): number {\n\tif (accountCount <= 0 || typeof index !== \"number\" || !Number.isInteger(index)) {\n\t\treturn 0;\n\t}\n\treturn ((index % accountCount) + accountCount) % accountCount;\n}\n\nfunction getSelectedOAuthAccountIndex(credential: OAuthCredential, accountCount: number): number {\n\treturn normalizeOAuthAccountIndex(credential.activeAccount ?? credential.nextAccount, accountCount);\n}\n\nfunction createOAuthCredential(accounts: OAuthCredentials[], activeAccount = 0): OAuthCredential {\n\tconst selectedIndex = normalizeOAuthAccountIndex(activeAccount, accounts.length);\n\tconst selected = accounts[selectedIndex];\n\tif (!selected) {\n\t\tthrow new Error(\"OAuth credential must contain at least one account\");\n\t}\n\tif (accounts.length === 1) {\n\t\treturn { ...selected, type: \"oauth\" };\n\t}\n\treturn {\n\t\t...selected,\n\t\ttype: \"oauth\",\n\t\taccounts,\n\t\tactiveAccount: selectedIndex,\n\t};\n}\n\nfunction getOAuthAccountIdentity(credentials: OAuthCredentials): string | undefined {\n\tconst accountId = credentials.accountId;\n\tconst orgId = credentials.orgId;\n\tif (typeof accountId === \"string\" && accountId.trim() && typeof orgId === \"string\" && orgId.trim()) {\n\t\treturn `accountId:${accountId.trim().toLowerCase()}:orgId:${orgId.trim().toLowerCase()}`;\n\t}\n\tfor (const field of OAUTH_ACCOUNT_ID_FIELDS) {\n\t\tconst value = credentials[field];\n\t\tif (typeof value === \"string\" && value.trim()) {\n\t\t\treturn `${field}:${value.trim().toLowerCase()}`;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction getOAuthAccountDisplayLabel(providerId: string, credentials: OAuthCredentials): string | undefined {\n\tfor (const field of OAUTH_ACCOUNT_LABEL_FIELDS) {\n\t\tconst value = credentials[field];\n\t\tif (typeof value === \"string\" && value.trim()) {\n\t\t\tconst label = sanitizeOAuthAccountLabel(value);\n\t\t\tif (!label) continue;\n\t\t\tconst orgName =\n\t\t\t\ttypeof credentials.orgName === \"string\" ? sanitizeOAuthAccountLabel(credentials.orgName) : undefined;\n\t\t\treturn sanitizeOAuthAccountLabel(orgName ? `${label} (${orgName})` : label);\n\t\t}\n\t}\n\ttry {\n\t\tconst label = getOAuthProvider(providerId)?.getAccountLabel?.(credentials);\n\t\treturn typeof label === \"string\" ? sanitizeOAuthAccountLabel(label) : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction findMatchingOAuthAccount(accounts: OAuthCredentials[], credentials: OAuthCredentials): number {\n\tconst identity = getOAuthAccountIdentity(credentials);\n\tif (identity) {\n\t\tconst exactMatch = accounts.findIndex((account) => getOAuthAccountIdentity(account) === identity);\n\t\tif (exactMatch >= 0) return exactMatch;\n\t}\n\n\t// Let newly enriched credentials update older entries that predate email/org metadata.\n\tfor (const field of OAUTH_ACCOUNT_ID_FIELDS) {\n\t\tconst value = credentials[field];\n\t\tif (typeof value !== \"string\" || !value.trim()) continue;\n\t\tconst normalizedValue = value.trim().toLowerCase();\n\t\tconst orgId = typeof credentials.orgId === \"string\" ? credentials.orgId.trim().toLowerCase() : \"\";\n\t\tconst compatibleMatch = accounts.findIndex((account) => {\n\t\t\tconst existingValue = account[field];\n\t\t\tif (typeof existingValue !== \"string\" || existingValue.trim().toLowerCase() !== normalizedValue) return false;\n\t\t\tconst existingOrgId = typeof account.orgId === \"string\" ? account.orgId.trim().toLowerCase() : \"\";\n\t\t\treturn !orgId || !existingOrgId || orgId === existingOrgId;\n\t\t});\n\t\tif (compatibleMatch >= 0) return compatibleMatch;\n\t}\n\n\treturn accounts.findIndex((account) => account.refresh === credentials.refresh);\n}\n\nexport type AuthStatus = {\n\tconfigured: boolean;\n\tsource?: \"stored\" | \"runtime\" | \"environment\" | \"fallback\" | \"models_json_key\" | \"models_json_command\";\n\tlabel?: string;\n};\n\ntype LockResult<T> = {\n\tresult: T;\n\tnext?: string;\n};\n\nconst AUTH_FILE_WRITE_OPTIONS = { encoding: \"utf-8\", mode: 0o600 } as const;\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\tprivate authPath: string;\n\n\tconstructor(authPath: string = join(getAgentDir(), \"auth.json\")) {\n\t\tthis.authPath = normalizePath(authPath);\n\t}\n\n\tprivate ensureParentDir(): void {\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, \"{}\", AUTH_FILE_WRITE_OPTIONS);\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\n\t\tfor (let attempt = 1; attempt <= maxAttempts; attempt++) {\n\t\t\ttry {\n\t\t\t\treturn lockfile.lockSync(path, { realpath: false });\n\t\t\t} catch (error) {\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, AUTH_FILE_WRITE_OPTIONS);\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, AUTH_FILE_WRITE_OPTIONS);\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\ttry {\n\t\t\t\t\tawait release();\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore unlock errors when lock is compromised.\n\t\t\t\t}\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 fallbackResolver?: (provider: string) => string | undefined;\n\tprivate loadError: Error | null = null;\n\tprivate errors: Error[] = [];\n\tprivate storage: AuthStorageBackend;\n\n\tprivate constructor(storage: AuthStorageBackend) {\n\t\tthis.storage = storage;\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\tstatic fromStorage(storage: AuthStorageBackend): AuthStorage {\n\t\treturn new AuthStorage(storage);\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.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.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 parseStorageData(content: string | undefined): AuthStorageData {\n\t\tif (!content) {\n\t\t\treturn {};\n\t\t}\n\t\ttry {\n\t\t\treturn JSON.parse(content) as AuthStorageData;\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tthrow new Error(`Failed to parse auth storage: ${message}`);\n\t\t}\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.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\tdelete this.data[provider];\n\t\tthis.persistProviderChange(provider, undefined);\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\tif (this.runtimeOverrides.has(provider)) return true;\n\t\tif (this.data[provider]) return true;\n\t\tif (getEnvApiKey(provider)) return true;\n\t\tif (this.fallbackResolver?.(provider)) return true;\n\t\treturn false;\n\t}\n\n\t/** Return the number of stored OAuth accounts for a provider. */\n\tgetOAuthAccountCount(provider: string): number {\n\t\tconst credential = this.data[provider];\n\t\treturn credential?.type === \"oauth\" ? getOAuthAccounts(credential).length : 0;\n\t}\n\n\t/** Return safe, human-readable labels for every stored OAuth account. */\n\tlistOAuthAccounts(provider: string): OAuthAccountSummary[] {\n\t\tconst credential = this.data[provider];\n\t\tif (credential?.type !== \"oauth\") return [];\n\t\tconst accounts = getOAuthAccounts(credential);\n\t\tconst selectedIndex = getSelectedOAuthAccountIndex(credential, accounts.length);\n\t\treturn accounts.map((account, index) => ({\n\t\t\tindex,\n\t\t\tlabel: getOAuthAccountDisplayLabel(provider, account) ?? `Account ${index + 1}`,\n\t\t\tselected: index === selectedIndex,\n\t\t}));\n\t}\n\n\t/** Return the human-readable label of the selected OAuth account. */\n\tgetOAuthAccountLabel(provider: string): string | undefined {\n\t\treturn this.listOAuthAccounts(provider).find((account) => account.selected)?.label;\n\t}\n\n\t/** Explicitly select and persist the OAuth account used by this provider. */\n\tselectOAuthAccount(provider: string, accountIndex: number): void {\n\t\tthis.storage.withLock((current) => {\n\t\t\tconst currentData = this.parseStorageData(current);\n\t\t\tconst credential = currentData[provider];\n\t\t\tif (credential?.type !== \"oauth\") {\n\t\t\t\tthrow new Error(`No OAuth accounts configured for ${provider}`);\n\t\t\t}\n\t\t\tconst accounts = [...getOAuthAccounts(credential)];\n\t\t\tif (!Number.isInteger(accountIndex) || accountIndex < 0 || accountIndex >= accounts.length) {\n\t\t\t\tthrow new Error(`Invalid OAuth account index ${accountIndex} for ${provider}`);\n\t\t\t}\n\t\t\tconst merged: AuthStorageData = {\n\t\t\t\t...currentData,\n\t\t\t\t[provider]: createOAuthCredential(accounts, accountIndex),\n\t\t\t};\n\t\t\tthis.data = merged;\n\t\t\tthis.loadError = null;\n\t\t\treturn { result: undefined, next: JSON.stringify(merged, null, 2) };\n\t\t});\n\t}\n\n\t/**\n\t * Return the explicitly selected OAuth credentials without refreshing tokens.\n\t * Used by provider model customization hooks.\n\t */\n\tgetOAuthCredentials(provider: string): OAuthCredentials | undefined {\n\t\tconst credential = this.data[provider];\n\t\tif (credential?.type !== \"oauth\") {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst accounts = getOAuthAccounts(credential);\n\t\treturn accounts[getSelectedOAuthAccountIndex(credential, accounts.length)];\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\tif (this.data[provider]) {\n\t\t\treturn { configured: true, source: \"stored\" };\n\t\t}\n\n\t\tif (this.runtimeOverrides.has(provider)) {\n\t\t\treturn { configured: false, source: \"runtime\", label: \"--api-key\" };\n\t\t}\n\n\t\tconst envKeys = findEnvKeys(provider);\n\t\tif (envKeys?.[0]) {\n\t\t\treturn { configured: false, source: \"environment\", label: envKeys[0] };\n\t\t}\n\n\t\tif (this.fallbackResolver?.(provider)) {\n\t\t\treturn { configured: false, source: \"fallback\", label: \"custom provider config\" };\n\t\t}\n\n\t\treturn { configured: false };\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. Repeated logins append distinct accounts and\n\t * update an existing account when the provider exposes a stable identity.\n\t */\n\tasync login(providerId: OAuthProviderId, callbacks: OAuthLoginCallbacks): Promise<void> {\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\tif (this.loadError) {\n\t\t\tthis.data[providerId] = { type: \"oauth\", ...credentials };\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 existing = currentData[providerId];\n\t\t\t\tlet credential: OAuthCredential;\n\n\t\t\t\tif (existing?.type === \"oauth\") {\n\t\t\t\t\tconst accounts = [...getOAuthAccounts(existing)];\n\t\t\t\t\tconst matchingIndex = findMatchingOAuthAccount(accounts, credentials);\n\t\t\t\t\tlet activeAccount: number;\n\t\t\t\t\tif (matchingIndex >= 0) {\n\t\t\t\t\t\taccounts[matchingIndex] = credentials;\n\t\t\t\t\t\tactiveAccount = matchingIndex;\n\t\t\t\t\t} else {\n\t\t\t\t\t\taccounts.push(credentials);\n\t\t\t\t\t\tactiveAccount = accounts.length - 1;\n\t\t\t\t\t}\n\t\t\t\t\tcredential = createOAuthCredential(accounts, activeAccount);\n\t\t\t\t} else {\n\t\t\t\t\tcredential = createOAuthCredential([credentials]);\n\t\t\t\t}\n\n\t\t\t\tconst merged: AuthStorageData = { ...currentData, [providerId]: credential };\n\t\t\t\tthis.data = merged;\n\t\t\t\tthis.loadError = null;\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 * Logout from a provider.\n\t */\n\tlogout(provider: string): void {\n\t\tthis.remove(provider);\n\t}\n\n\t/** Resolve the explicitly selected account and refresh it under the storage lock. */\n\tprivate async resolveOAuthTokenWithLock(\n\t\tproviderId: OAuthProviderId,\n\t): Promise<{ apiKey: string; newCredentials: OAuthCredentials } | null> {\n\t\tconst provider = getOAuthProvider(providerId);\n\t\tif (!provider) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn 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 credential = currentData[providerId];\n\t\t\tif (credential?.type !== \"oauth\") {\n\t\t\t\treturn { result: null };\n\t\t\t}\n\n\t\t\tconst accounts = [...getOAuthAccounts(credential)];\n\t\t\tconst accountIndex = getSelectedOAuthAccountIndex(credential, accounts.length);\n\t\t\tconst account = accounts[accountIndex];\n\t\t\tif (!account) return { result: null };\n\n\t\t\tconst resolved =\n\t\t\t\tDate.now() < account.expires\n\t\t\t\t\t? { apiKey: provider.getApiKey(account), newCredentials: account }\n\t\t\t\t\t: await getOAuthApiKey(providerId, { [providerId]: account });\n\t\t\tif (!resolved) return { result: null };\n\n\t\t\tif (resolved.newCredentials === account) {\n\t\t\t\treturn { result: resolved };\n\t\t\t}\n\n\t\t\tconst newCredentials = { ...account, ...resolved.newCredentials };\n\t\t\taccounts[accountIndex] = newCredentials;\n\t\t\tconst merged: AuthStorageData = {\n\t\t\t\t...currentData,\n\t\t\t\t[providerId]: createOAuthCredential(accounts, accountIndex),\n\t\t\t};\n\t\t\tthis.data = merged;\n\t\t\treturn {\n\t\t\t\tresult: { ...resolved, newCredentials },\n\t\t\t\tnext: JSON.stringify(merged, null, 2),\n\t\t\t};\n\t\t});\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. API key from auth.json\n\t * 3. OAuth token from auth.json (auto-refreshed with locking)\n\t * 4. Environment variable\n\t * 5. Fallback resolver (models.json custom providers)\n\t */\n\tasync getApiKey(providerId: string, options?: { includeFallback?: boolean }): Promise<string | undefined> {\n\t\t// Runtime override takes highest priority\n\t\tconst runtimeKey = this.runtimeOverrides.get(providerId);\n\t\tif (runtimeKey) {\n\t\t\treturn runtimeKey;\n\t\t}\n\n\t\tconst cred = this.data[providerId];\n\n\t\tif (cred?.type === \"api_key\") {\n\t\t\treturn resolveConfigValue(cred.key);\n\t\t}\n\n\t\tif (cred?.type === \"oauth\") {\n\t\t\ttry {\n\t\t\t\tconst result = await this.resolveOAuthTokenWithLock(providerId);\n\t\t\t\tif (result) {\n\t\t\t\t\treturn result.apiKey;\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tthis.recordError(error);\n\t\t\t\t// Credentials are preserved so a later request or /login can recover.\n\t\t\t\tthis.reload();\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}\n\n\t\t// Fall back to environment variable\n\t\tconst envKey = getEnvApiKey(providerId);\n\t\tif (envKey) return envKey;\n\n\t\t// Fall back to custom resolver (e.g., models.json custom providers)\n\t\tif (options?.includeFallback !== false) {\n\t\t\treturn this.fallbackResolver?.(providerId) ?? undefined;\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Get all registered OAuth providers\n\t */\n\tgetOAuthProviders() {\n\t\treturn getOAuthProviders();\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"context-budget-v2-cache-invalidation.d.ts","sourceRoot":"","sources":["../../src/core/context-budget-v2-cache-invalidation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Browser-safe, pure context-cache invalidation snapshot helper.\n *\n * Every public function is side-effect free and depends only on\n * platform-agnostic primitives. Returned snapshots are always\n * independently deep-frozen copies of the caller-supplied data, so\n * callers cannot mutate cached state through retained references.\n *\n * Snapshots are cache-key material for invalidation tracking, not an\n * authorization or authentication primitive.\n *\n * Schema: context-cache-invalidation-v1.\n */\n\nexport const CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION = \"context-cache-invalidation-v1\" as const;\nexport const CONTEXT_CACHE_INVALIDATION_SAFE_ID_MAX_LENGTH = 256;\n\n/** Event counters tracked by an invalidation snapshot. */\nexport interface ContextCacheInvalidationCounters {\n\treadonly transcriptRepair: number;\n\treadonly toolResultDisposition: number;\n\treadonly evidenceReceipt: number;\n\treadonly userSteering: number;\n\treadonly settings: number;\n}\n\n/** Immutable schema-v1 invalidation snapshot. */\nexport interface ContextCacheInvalidationSnapshot {\n\treadonly schemaVersion: typeof CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION;\n\treadonly forkId: string;\n\treadonly globalEpoch: number;\n\treadonly counters: ContextCacheInvalidationCounters;\n\treadonly worktreeFingerprint: string;\n\treadonly activeModelId: string;\n\treadonly compactionModelId: string;\n}\n\n/** Constructor input for a fresh snapshot. Counters and epoch default to 0. */\nexport interface ContextCacheInvalidationSnapshotInit {\n\treadonly forkId: string;\n\treadonly worktreeFingerprint: string;\n\treadonly activeModelId: string;\n\treadonly compactionModelId: string;\n\treadonly globalEpoch?: number;\n\treadonly transcriptRepair?: number;\n\treadonly toolResultDisposition?: number;\n\treadonly evidenceReceipt?: number;\n\treadonly userSteering?: number;\n\treadonly settings?: number;\n}\n\n/**\n * Strict union covering all eight invalidation events. The five counter\n * events increment their counter; the three identity events set a value.\n */\nexport type ContextCacheInvalidationEvent =\n\t| { readonly type: \"transcriptRepair\" }\n\t| { readonly type: \"toolResultDisposition\" }\n\t| { readonly type: \"evidenceReceipt\" }\n\t| { readonly type: \"userSteering\" }\n\t| { readonly type: \"settings\" }\n\t| { readonly type: \"worktreeFingerprint\"; readonly value: string }\n\t| { readonly type: \"activeModelId\"; readonly value: string }\n\t| { readonly type: \"compactionModelId\"; readonly value: string };\n\nexport type ContextCacheInvalidationStatus = \"applied\" | \"unchanged\" | \"overflow\";\n\nexport interface ContextCacheInvalidationResult {\n\treadonly status: ContextCacheInvalidationStatus;\n\treadonly snapshot: ContextCacheInvalidationSnapshot;\n}\n\nexport type ContextCacheMergeStatus = \"equal\" | \"dominant\" | \"divergent\";\n\nexport type ContextCacheMergeResult =\n\t| { readonly status: \"equal\"; readonly snapshot: ContextCacheInvalidationSnapshot }\n\t| { readonly status: \"dominant\"; readonly snapshot: ContextCacheInvalidationSnapshot }\n\t| {\n\t\t\treadonly status: \"divergent\";\n\t\t\treadonly left: ContextCacheInvalidationSnapshot;\n\t\t\treadonly right: ContextCacheInvalidationSnapshot;\n\t };\n\ntype CounterKey = \"transcriptRepair\" | \"toolResultDisposition\" | \"evidenceReceipt\" | \"userSteering\" | \"settings\";\n\ntype IdentityKey = \"worktreeFingerprint\" | \"activeModelId\" | \"compactionModelId\";\n\nconst MAX_REPRESENTABLE = Number.MAX_SAFE_INTEGER;\nconst SAFE_ID_PATTERN = /^[\\w.\\-:+]+$/u;\n\n/**\n * High-confidence credential markers, checked in addition to the\n * safe-character gate. A value already consists only of safe characters\n * before it is tested here. Each pattern is anchored to the whole string\n * to keep the false-positive rate low; identifiers and fingerprints in\n * this domain never legitimately take these shapes.\n */\nconst CREDENTIAL_MARKERS: ReadonlyArray<RegExp> = [\n\t/^sk-[A-Za-z0-9_-]{8,}$/i, // OpenAI / generic \"sk-\" secret keys\n\t/^gh[pousr]_[A-Za-z0-9]{16,}$/i, // GitHub classic tokens (ghp_ gho_ ghu_ ghs_ ghr_)\n\t/^github_pat_[A-Za-z0-9_]{20,}$/i, // GitHub fine-grained PATs\n\t/^xox[pabrse]-[A-Za-z0-9-]{10,}$/i, // Slack tokens (xoxp xoxb xoxa xoxs xoxr xoxe)\n\t/^AKIA[0-9A-Z]{16}$/, // AWS access key id (20 chars, uppercase)\n\t/^eyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}$/, // JWT (three base64url segments)\n\t/^bearer$/i, // literal Bearer token marker\n];\n\nfunction looksLikeCredential(value: string): boolean {\n\tfor (const marker of CREDENTIAL_MARKERS) {\n\t\tif (marker.test(value)) return true;\n\t}\n\treturn false;\n}\n\nconst TOP_LEVEL_KEYS: ReadonlySet<string> = new Set([\n\t\"schemaVersion\",\n\t\"forkId\",\n\t\"globalEpoch\",\n\t\"counters\",\n\t\"worktreeFingerprint\",\n\t\"activeModelId\",\n\t\"compactionModelId\",\n]);\n\nconst COUNTER_KEYS: ReadonlySet<string> = new Set([\n\t\"transcriptRepair\",\n\t\"toolResultDisposition\",\n\t\"evidenceReceipt\",\n\t\"userSteering\",\n\t\"settings\",\n]);\n\nfunction fail(reason: string): never {\n\tthrow new Error(`context-cache-invalidation: ${reason}`);\n}\n\nfunction assertSafeId(value: unknown, field: string): asserts value is string {\n\tif (typeof value !== \"string\") fail(`${field} must be a string`);\n\tif (value.length === 0) fail(`${field} must not be empty`);\n\tif (value.length > CONTEXT_CACHE_INVALIDATION_SAFE_ID_MAX_LENGTH) {\n\t\tfail(`${field} exceeds ${CONTEXT_CACHE_INVALIDATION_SAFE_ID_MAX_LENGTH} characters`);\n\t}\n\tif (!SAFE_ID_PATTERN.test(value)) fail(`${field} contains unsafe characters`);\n\tif (looksLikeCredential(value)) fail(`${field} looks like a credential and was rejected`);\n}\n\nfunction assertNonNegativeSafeInt(value: unknown, field: string): asserts value is number {\n\tif (typeof value !== \"number\") fail(`${field} must be a number`);\n\tif (!Number.isFinite(value)) fail(`${field} must be finite`);\n\tif (!Number.isInteger(value)) fail(`${field} must be an integer`);\n\tif (value < 0) fail(`${field} must be nonnegative`);\n\tif (!Number.isSafeInteger(value)) fail(`${field} must be a safe integer`);\n}\n\nfunction assertExactKeys(record: Record<string, unknown>, allowed: ReadonlySet<string>, scope: string): void {\n\tconst keys = Object.keys(record);\n\tif (keys.length !== allowed.size) fail(`${scope} has unexpected keys`);\n\tfor (const key of keys) {\n\t\tif (!allowed.has(key)) fail(`${scope} has unknown key \"${key}\"`);\n\t}\n}\n\n/** Reject non-plain inputs: null, arrays, primitives, and class instances. */\nfunction assertPlainObject(value: unknown, scope: string): asserts value is Record<string, unknown> {\n\tif (value === null || typeof value !== \"object\") fail(`${scope} must be a plain object`);\n\tif (Array.isArray(value)) fail(`${scope} must be a plain object`);\n\tconst proto = Object.getPrototypeOf(value);\n\tif (proto !== null && proto !== Object.prototype) fail(`${scope} must be a plain object`);\n}\n\n/** Reject getter/setter accessors, whose reads are not stable. */\nfunction assertNoAccessors(record: object, scope: string): void {\n\tfor (const key of Object.getOwnPropertyNames(record)) {\n\t\tconst desc = Object.getOwnPropertyDescriptor(record, key);\n\t\tif (desc !== undefined && (typeof desc.get === \"function\" || typeof desc.set === \"function\")) {\n\t\t\tfail(`${scope} must not define accessors`);\n\t\t}\n\t}\n}\n\nconst INIT_REQUIRED_KEYS: ReadonlySet<string> = new Set([\n\t\"forkId\",\n\t\"worktreeFingerprint\",\n\t\"activeModelId\",\n\t\"compactionModelId\",\n]);\n\nconst INIT_OPTIONAL_KEYS: ReadonlySet<string> = new Set([\n\t\"globalEpoch\",\n\t\"transcriptRepair\",\n\t\"toolResultDisposition\",\n\t\"evidenceReceipt\",\n\t\"userSteering\",\n\t\"settings\",\n]);\n\nconst INIT_ALLOWED_KEYS: ReadonlySet<string> = new Set([...INIT_REQUIRED_KEYS, ...INIT_OPTIONAL_KEYS]);\n\n/**\n * Strictly validate a snapshot constructor input: a plain data object with\n * exactly the required identity/fork keys plus optional counters/epoch, and\n * no accessor properties. Rejects null, arrays, class instances, unknown\n * keys, and getters/setters with a stable error.\n */\nfunction assertInitShape(input: unknown): asserts input is ContextCacheInvalidationSnapshotInit {\n\tassertPlainObject(input, \"init\");\n\tassertNoAccessors(input, \"init\");\n\tfor (const key of Object.keys(input)) {\n\t\tif (!INIT_ALLOWED_KEYS.has(key)) fail(`init has unknown key \"${key}\"`);\n\t}\n\tfor (const required of INIT_REQUIRED_KEYS) {\n\t\tif (!Object.hasOwn(input, required)) {\n\t\t\tfail(`init is missing required key \"${required}\"`);\n\t\t}\n\t}\n}\n\nconst COUNTER_EVENT_TYPES: ReadonlySet<string> = new Set([\n\t\"transcriptRepair\",\n\t\"toolResultDisposition\",\n\t\"evidenceReceipt\",\n\t\"userSteering\",\n\t\"settings\",\n]);\n\nconst IDENTITY_EVENT_TYPES: ReadonlySet<string> = new Set([\n\t\"worktreeFingerprint\",\n\t\"activeModelId\",\n\t\"compactionModelId\",\n]);\n\nconst COUNTER_EVENT_KEYS: ReadonlySet<string> = new Set([\"type\"]);\nconst IDENTITY_EVENT_KEYS: ReadonlySet<string> = new Set([\"type\", \"value\"]);\n\n/**\n * Strictly validate a runtime invalidation event before dispatch. The event\n * must be a plain data object carrying exactly the keys its discriminant\n * allows (counter events: `{ type }`; identity events: `{ type, value }`),\n * a known `type` string, and (for identity events) a safe value. Forged or\n * malformed events always throw here and can never fall through to an\n * undefined result.\n */\nfunction validateEvent(input: unknown): asserts input is ContextCacheInvalidationEvent {\n\tassertPlainObject(input, \"event\");\n\tassertNoAccessors(input, \"event\");\n\tconst type = input.type;\n\tif (type === undefined) fail(\"event is missing type\");\n\tif (typeof type !== \"string\") fail(\"event type must be a string\");\n\tif (COUNTER_EVENT_TYPES.has(type)) {\n\t\tassertExactKeys(input, COUNTER_EVENT_KEYS, \"event\");\n\t\treturn;\n\t}\n\tif (IDENTITY_EVENT_TYPES.has(type)) {\n\t\tassertExactKeys(input, IDENTITY_EVENT_KEYS, \"event\");\n\t\tassertSafeId(input.value, type);\n\t\treturn;\n\t}\n\tfail(`event type \"${type}\" is unknown`);\n}\n\n/**\n * Strictly validate that {@link input} is a structurally correct snapshot.\n * Rejects extra keys, missing keys, malformed counters, unsafe integers,\n * and control/credential-unsafe identifier strings. Does not require the\n * object to be frozen.\n */\nexport function validateContextCacheInvalidationSnapshot(\n\tinput: unknown,\n): asserts input is ContextCacheInvalidationSnapshot {\n\tif (input === null || typeof input !== \"object\" || Array.isArray(input)) {\n\t\tfail(\"snapshot must be a plain object\");\n\t}\n\tconst obj = input as Record<string, unknown>;\n\tassertExactKeys(obj, TOP_LEVEL_KEYS, \"snapshot\");\n\tif (obj.schemaVersion !== CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION) {\n\t\tfail(`schemaVersion must be ${CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION}`);\n\t}\n\tassertSafeId(obj.forkId, \"forkId\");\n\tassertNonNegativeSafeInt(obj.globalEpoch, \"globalEpoch\");\n\tif (obj.counters === null || typeof obj.counters !== \"object\" || Array.isArray(obj.counters)) {\n\t\tfail(\"counters must be a plain object\");\n\t}\n\tconst counters = obj.counters as Record<string, unknown>;\n\tassertExactKeys(counters, COUNTER_KEYS, \"counters\");\n\tassertNonNegativeSafeInt(counters.transcriptRepair, \"counters.transcriptRepair\");\n\tassertNonNegativeSafeInt(counters.toolResultDisposition, \"counters.toolResultDisposition\");\n\tassertNonNegativeSafeInt(counters.evidenceReceipt, \"counters.evidenceReceipt\");\n\tassertNonNegativeSafeInt(counters.userSteering, \"counters.userSteering\");\n\tassertNonNegativeSafeInt(counters.settings, \"counters.settings\");\n\tassertSafeId(obj.worktreeFingerprint, \"worktreeFingerprint\");\n\tassertSafeId(obj.activeModelId, \"activeModelId\");\n\tassertSafeId(obj.compactionModelId, \"compactionModelId\");\n}\n\n/** Non-throwing variant of {@link validateContextCacheInvalidationSnapshot}. */\nexport function isContextCacheInvalidationSnapshot(input: unknown): input is ContextCacheInvalidationSnapshot {\n\ttry {\n\t\tvalidateContextCacheInvalidationSnapshot(input);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\ninterface SnapshotBuilder {\n\tschemaVersion: typeof CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION;\n\tforkId: string;\n\tglobalEpoch: number;\n\tcounters: ContextCacheInvalidationCounters;\n\tworktreeFingerprint: string;\n\tactiveModelId: string;\n\tcompactionModelId: string;\n}\n\nfunction freezeSnapshot(builder: SnapshotBuilder): ContextCacheInvalidationSnapshot {\n\tObject.freeze(builder.counters);\n\treturn Object.freeze(builder) as ContextCacheInvalidationSnapshot;\n}\n\nfunction copyCounters(counters: ContextCacheInvalidationCounters): Record<CounterKey, number> {\n\treturn {\n\t\ttranscriptRepair: counters.transcriptRepair,\n\t\ttoolResultDisposition: counters.toolResultDisposition,\n\t\tevidenceReceipt: counters.evidenceReceipt,\n\t\tuserSteering: counters.userSteering,\n\t\tsettings: counters.settings,\n\t};\n}\n\nfunction cloneAndFreeze(snapshot: ContextCacheInvalidationSnapshot): ContextCacheInvalidationSnapshot {\n\treturn freezeSnapshot({\n\t\tschemaVersion: snapshot.schemaVersion,\n\t\tforkId: snapshot.forkId,\n\t\tglobalEpoch: snapshot.globalEpoch,\n\t\tcounters: copyCounters(snapshot.counters),\n\t\tworktreeFingerprint: snapshot.worktreeFingerprint,\n\t\tactiveModelId: snapshot.activeModelId,\n\t\tcompactionModelId: snapshot.compactionModelId,\n\t});\n}\n\nfunction resolveOptionalCounter(value: number | undefined, field: string): number {\n\tif (value === undefined) return 0;\n\tassertNonNegativeSafeInt(value, field);\n\treturn value;\n}\n\n/** Build a validated, deep-frozen initial snapshot. */\nexport function createContextCacheInvalidationSnapshot(\n\tinit: ContextCacheInvalidationSnapshotInit,\n): ContextCacheInvalidationSnapshot {\n\tassertInitShape(init);\n\tassertSafeId(init.forkId, \"forkId\");\n\tassertSafeId(init.worktreeFingerprint, \"worktreeFingerprint\");\n\tassertSafeId(init.activeModelId, \"activeModelId\");\n\tassertSafeId(init.compactionModelId, \"compactionModelId\");\n\tconst globalEpoch = init.globalEpoch ?? 0;\n\tassertNonNegativeSafeInt(globalEpoch, \"globalEpoch\");\n\treturn freezeSnapshot({\n\t\tschemaVersion: CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION,\n\t\tforkId: init.forkId,\n\t\tglobalEpoch,\n\t\tcounters: {\n\t\t\ttranscriptRepair: resolveOptionalCounter(init.transcriptRepair, \"transcriptRepair\"),\n\t\t\ttoolResultDisposition: resolveOptionalCounter(init.toolResultDisposition, \"toolResultDisposition\"),\n\t\t\tevidenceReceipt: resolveOptionalCounter(init.evidenceReceipt, \"evidenceReceipt\"),\n\t\t\tuserSteering: resolveOptionalCounter(init.userSteering, \"userSteering\"),\n\t\t\tsettings: resolveOptionalCounter(init.settings, \"settings\"),\n\t\t},\n\t\tworktreeFingerprint: init.worktreeFingerprint,\n\t\tactiveModelId: init.activeModelId,\n\t\tcompactionModelId: init.compactionModelId,\n\t});\n}\n\nfunction applyCounterEvent(current: ContextCacheInvalidationSnapshot, key: CounterKey): ContextCacheInvalidationResult {\n\tconst value = current.counters[key];\n\tif (value >= MAX_REPRESENTABLE || current.globalEpoch >= MAX_REPRESENTABLE) {\n\t\treturn Object.freeze({ status: \"overflow\", snapshot: cloneAndFreeze(current) } as const);\n\t}\n\tconst nextCounters = copyCounters(current.counters);\n\tnextCounters[key] = value + 1;\n\treturn Object.freeze({\n\t\tstatus: \"applied\",\n\t\tsnapshot: freezeSnapshot({\n\t\t\tschemaVersion: current.schemaVersion,\n\t\t\tforkId: current.forkId,\n\t\t\tglobalEpoch: current.globalEpoch + 1,\n\t\t\tcounters: nextCounters,\n\t\t\tworktreeFingerprint: current.worktreeFingerprint,\n\t\t\tactiveModelId: current.activeModelId,\n\t\t\tcompactionModelId: current.compactionModelId,\n\t\t}),\n\t} as const);\n}\n\nfunction applyIdentityEvent(\n\tcurrent: ContextCacheInvalidationSnapshot,\n\tkey: IdentityKey,\n\tvalue: string,\n): ContextCacheInvalidationResult {\n\tassertSafeId(value, key);\n\tif (current[key] === value) {\n\t\treturn Object.freeze({ status: \"unchanged\", snapshot: cloneAndFreeze(current) } as const);\n\t}\n\tif (current.globalEpoch >= MAX_REPRESENTABLE) {\n\t\treturn Object.freeze({ status: \"overflow\", snapshot: cloneAndFreeze(current) } as const);\n\t}\n\treturn Object.freeze({\n\t\tstatus: \"applied\",\n\t\tsnapshot: freezeSnapshot({\n\t\t\tschemaVersion: current.schemaVersion,\n\t\t\tforkId: current.forkId,\n\t\t\tglobalEpoch: current.globalEpoch + 1,\n\t\t\tcounters: copyCounters(current.counters),\n\t\t\tworktreeFingerprint: key === \"worktreeFingerprint\" ? value : current.worktreeFingerprint,\n\t\t\tactiveModelId: key === \"activeModelId\" ? value : current.activeModelId,\n\t\t\tcompactionModelId: key === \"compactionModelId\" ? value : current.compactionModelId,\n\t\t}),\n\t} as const);\n}\n\n/**\n * Apply a single invalidation event. Increments the global epoch and the\n * relevant counter, or sets an identity. A same-value identity set is a\n * no-op and returns {@link ContextCacheInvalidationStatus.unchanged} without\n * an epoch bump. Any counter or epoch overflow returns\n * {@link ContextCacheInvalidationStatus.overflow} with the snapshot unchanged\n * and never wraps.\n */\nexport function applyContextCacheInvalidation(\n\tcurrent: ContextCacheInvalidationSnapshot,\n\tevent: ContextCacheInvalidationEvent,\n): ContextCacheInvalidationResult {\n\tvalidateContextCacheInvalidationSnapshot(current);\n\tvalidateEvent(event);\n\tswitch (event.type) {\n\t\tcase \"transcriptRepair\":\n\t\tcase \"toolResultDisposition\":\n\t\tcase \"evidenceReceipt\":\n\t\tcase \"userSteering\":\n\t\tcase \"settings\":\n\t\t\treturn applyCounterEvent(current, event.type);\n\t\tcase \"worktreeFingerprint\":\n\t\tcase \"activeModelId\":\n\t\tcase \"compactionModelId\":\n\t\t\treturn applyIdentityEvent(current, event.type, event.value);\n\t\tdefault: {\n\t\t\t// Exhaustiveness guard: a new event variant without a matching\n\t\t\t// case becomes a compile error on the assignment below.\n\t\t\tconst _exhaustive: never = event;\n\t\t\tfail(`unhandled event type ${_exhaustive}`);\n\t\t}\n\t}\n}\n\n/**\n * Fork a snapshot: keep all event counters and identity values, change the\n * fork id, and reset the global epoch to 0. The caller supplies the new fork\n * id. Rejects an id equal to the current fork id.\n */\nexport function forkContextCacheSnapshot(\n\tcurrent: ContextCacheInvalidationSnapshot,\n\tnextForkId: string,\n): ContextCacheInvalidationSnapshot {\n\tvalidateContextCacheInvalidationSnapshot(current);\n\tassertSafeId(nextForkId, \"forkId\");\n\tif (nextForkId === current.forkId) {\n\t\tfail(\"forkId must differ from current fork\");\n\t}\n\treturn freezeSnapshot({\n\t\tschemaVersion: current.schemaVersion,\n\t\tforkId: nextForkId,\n\t\tglobalEpoch: 0,\n\t\tcounters: copyCounters(current.counters),\n\t\tworktreeFingerprint: current.worktreeFingerprint,\n\t\tactiveModelId: current.activeModelId,\n\t\tcompactionModelId: current.compactionModelId,\n\t});\n}\n\nfunction snapshotsEqual(a: ContextCacheInvalidationSnapshot, b: ContextCacheInvalidationSnapshot): boolean {\n\treturn (\n\t\ta.globalEpoch === b.globalEpoch &&\n\t\ta.counters.transcriptRepair === b.counters.transcriptRepair &&\n\t\ta.counters.toolResultDisposition === b.counters.toolResultDisposition &&\n\t\ta.counters.evidenceReceipt === b.counters.evidenceReceipt &&\n\t\ta.counters.userSteering === b.counters.userSteering &&\n\t\ta.counters.settings === b.counters.settings &&\n\t\ta.worktreeFingerprint === b.worktreeFingerprint &&\n\t\ta.activeModelId === b.activeModelId &&\n\t\ta.compactionModelId === b.compactionModelId\n\t);\n}\n\nfunction dominates(x: ContextCacheInvalidationSnapshot, y: ContextCacheInvalidationSnapshot): boolean {\n\treturn (\n\t\tx.globalEpoch >= y.globalEpoch &&\n\t\tx.counters.transcriptRepair >= y.counters.transcriptRepair &&\n\t\tx.counters.toolResultDisposition >= y.counters.toolResultDisposition &&\n\t\tx.counters.evidenceReceipt >= y.counters.evidenceReceipt &&\n\t\tx.counters.userSteering >= y.counters.userSteering &&\n\t\tx.counters.settings >= y.counters.settings &&\n\t\tx.worktreeFingerprint === y.worktreeFingerprint &&\n\t\tx.activeModelId === y.activeModelId &&\n\t\tx.compactionModelId === y.compactionModelId\n\t);\n}\n\n/**\n * Fail-closed merge of two snapshots.\n *\n * - Different fork ids, or two snapshots that are not on a shared linear\n * history, yield {@link ContextCacheMergeStatus.divergent}. Disjoint\n * changes are never max-merged.\n * - Structurally equal snapshots yield {@link ContextCacheMergeStatus.equal}.\n * - When one snapshot componentwise-dominates the other (epoch and every\n * counter greater-or-equal, and all identity values equal), the dominant\n * snapshot is chosen via {@link ContextCacheMergeStatus.dominant}.\n */\nexport function mergeContextCacheSnapshots(\n\ta: ContextCacheInvalidationSnapshot,\n\tb: ContextCacheInvalidationSnapshot,\n): ContextCacheMergeResult {\n\tvalidateContextCacheInvalidationSnapshot(a);\n\tvalidateContextCacheInvalidationSnapshot(b);\n\tif (a.forkId !== b.forkId) {\n\t\treturn Object.freeze({ status: \"divergent\", left: cloneAndFreeze(a), right: cloneAndFreeze(b) } as const);\n\t}\n\tif (snapshotsEqual(a, b)) {\n\t\treturn Object.freeze({ status: \"equal\", snapshot: cloneAndFreeze(a) } as const);\n\t}\n\tconst aDominates = dominates(a, b);\n\tconst bDominates = dominates(b, a);\n\tif (aDominates && !bDominates) {\n\t\treturn Object.freeze({ status: \"dominant\", snapshot: cloneAndFreeze(a) } as const);\n\t}\n\tif (bDominates && !aDominates) {\n\t\treturn Object.freeze({ status: \"dominant\", snapshot: cloneAndFreeze(b) } as const);\n\t}\n\treturn Object.freeze({ status: \"divergent\", left: cloneAndFreeze(a), right: cloneAndFreeze(b) } as const);\n}\n\n/**\n * Canonical, fixed-order JSON serialization of a snapshot, suitable as\n * future cache-key material. The field order is fixed and every distinct\n * field participates, so any distinct field change alters the result.\n * Returns a deterministic string with no hash claim.\n */\nexport function serializeContextCacheSnapshot(snapshot: ContextCacheInvalidationSnapshot): string {\n\tvalidateContextCacheInvalidationSnapshot(snapshot);\n\treturn JSON.stringify({\n\t\tschemaVersion: snapshot.schemaVersion,\n\t\tforkId: snapshot.forkId,\n\t\tglobalEpoch: snapshot.globalEpoch,\n\t\tcounters: {\n\t\t\ttranscriptRepair: snapshot.counters.transcriptRepair,\n\t\t\ttoolResultDisposition: snapshot.counters.toolResultDisposition,\n\t\t\tevidenceReceipt: snapshot.counters.evidenceReceipt,\n\t\t\tuserSteering: snapshot.counters.userSteering,\n\t\t\tsettings: snapshot.counters.settings,\n\t\t},\n\t\tworktreeFingerprint: snapshot.worktreeFingerprint,\n\t\tactiveModelId: snapshot.activeModelId,\n\t\tcompactionModelId: snapshot.compactionModelId,\n\t});\n}\n"]}
1
+ {"version":3,"file":"context-budget-v2-cache-invalidation.d.ts","sourceRoot":"","sources":["../../src/core/context-budget-v2-cache-invalidation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Browser-safe, pure context-cache invalidation snapshot helper.\n *\n * Every public function is side-effect free and depends only on\n * platform-agnostic primitives. Returned snapshots are always\n * independently deep-frozen copies of the caller-supplied data, so\n * callers cannot mutate cached state through retained references.\n *\n * Snapshots are cache-key material for invalidation tracking, not an\n * authorization or authentication primitive.\n *\n * Schema: context-cache-invalidation-v1.\n */\n\nexport const CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION = \"context-cache-invalidation-v1\" as const;\nexport const CONTEXT_CACHE_INVALIDATION_SAFE_ID_MAX_LENGTH = 256;\n\n/** Event counters tracked by an invalidation snapshot. */\nexport interface ContextCacheInvalidationCounters {\n\treadonly transcriptRepair: number;\n\treadonly toolResultDisposition: number;\n\treadonly evidenceReceipt: number;\n\treadonly userSteering: number;\n\treadonly settings: number;\n}\n\n/** Immutable schema-v1 invalidation snapshot. */\nexport interface ContextCacheInvalidationSnapshot {\n\treadonly schemaVersion: typeof CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION;\n\treadonly forkId: string;\n\treadonly globalEpoch: number;\n\treadonly counters: ContextCacheInvalidationCounters;\n\treadonly worktreeFingerprint: string;\n\treadonly activeModelId: string;\n\treadonly compactionModelId: string;\n}\n\n/** Constructor input for a fresh snapshot. Counters and epoch default to 0. */\nexport interface ContextCacheInvalidationSnapshotInit {\n\treadonly forkId: string;\n\treadonly worktreeFingerprint: string;\n\treadonly activeModelId: string;\n\treadonly compactionModelId: string;\n\treadonly globalEpoch?: number;\n\treadonly transcriptRepair?: number;\n\treadonly toolResultDisposition?: number;\n\treadonly evidenceReceipt?: number;\n\treadonly userSteering?: number;\n\treadonly settings?: number;\n}\n\n/**\n * Strict union covering all eight invalidation events. The five counter\n * events increment their counter; the three identity events set a value.\n */\nexport type ContextCacheInvalidationEvent =\n\t| { readonly type: \"transcriptRepair\" }\n\t| { readonly type: \"toolResultDisposition\" }\n\t| { readonly type: \"evidenceReceipt\" }\n\t| { readonly type: \"userSteering\" }\n\t| { readonly type: \"settings\" }\n\t| { readonly type: \"worktreeFingerprint\"; readonly value: string }\n\t| { readonly type: \"activeModelId\"; readonly value: string }\n\t| { readonly type: \"compactionModelId\"; readonly value: string };\n\nexport type ContextCacheInvalidationStatus = \"applied\" | \"unchanged\" | \"overflow\";\n\nexport interface ContextCacheInvalidationResult {\n\treadonly status: ContextCacheInvalidationStatus;\n\treadonly snapshot: ContextCacheInvalidationSnapshot;\n}\n\nexport type ContextCacheMergeStatus = \"equal\" | \"dominant\" | \"divergent\";\n\nexport type ContextCacheMergeResult =\n\t| { readonly status: \"equal\"; readonly snapshot: ContextCacheInvalidationSnapshot }\n\t| { readonly status: \"dominant\"; readonly snapshot: ContextCacheInvalidationSnapshot }\n\t| {\n\t\t\treadonly status: \"divergent\";\n\t\t\treadonly left: ContextCacheInvalidationSnapshot;\n\t\t\treadonly right: ContextCacheInvalidationSnapshot;\n\t };\n\ntype CounterKey = \"transcriptRepair\" | \"toolResultDisposition\" | \"evidenceReceipt\" | \"userSteering\" | \"settings\";\n\ntype IdentityKey = \"worktreeFingerprint\" | \"activeModelId\" | \"compactionModelId\";\n\nconst MAX_REPRESENTABLE = Number.MAX_SAFE_INTEGER;\nconst SAFE_ID_PATTERN = /^[\\w.\\-:+]+$/u;\n\n/**\n * High-confidence credential markers, checked in addition to the\n * safe-character gate. A value already consists only of safe characters\n * before it is tested here. Each pattern is anchored to the whole string\n * to keep the false-positive rate low; identifiers and fingerprints in\n * this domain never legitimately take these shapes.\n */\nconst CREDENTIAL_MARKERS: ReadonlyArray<RegExp> = [\n\t/^sk-[A-Za-z0-9_-]{8,}$/i, // OpenAI / generic \"sk-\" secret keys\n\t/^gh[pousr]_[A-Za-z0-9]{16,}$/i, // GitHub classic tokens (ghp_ gho_ ghu_ ghs_ ghr_)\n\t/^github_pat_[A-Za-z0-9_]{20,}$/i, // GitHub fine-grained PATs\n\t/^xox[pabrse]-[A-Za-z0-9-]{10,}$/i, // Slack tokens (xoxp xoxb xoxa xoxs xoxr xoxe)\n\t/^AKIA[0-9A-Z]{16}$/, // AWS access key id (20 chars, uppercase)\n\t/^eyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}$/, // JWT (three base64url segments)\n\t/^bearer$/i, // literal Bearer token marker\n];\n\nfunction looksLikeCredential(value: string): boolean {\n\tfor (const marker of CREDENTIAL_MARKERS) {\n\t\tif (marker.test(value)) return true;\n\t}\n\treturn false;\n}\n\nconst TOP_LEVEL_KEYS: ReadonlySet<string> = new Set([\n\t\"schemaVersion\",\n\t\"forkId\",\n\t\"globalEpoch\",\n\t\"counters\",\n\t\"worktreeFingerprint\",\n\t\"activeModelId\",\n\t\"compactionModelId\",\n]);\n\nconst COUNTER_KEYS: ReadonlySet<string> = new Set([\n\t\"transcriptRepair\",\n\t\"toolResultDisposition\",\n\t\"evidenceReceipt\",\n\t\"userSteering\",\n\t\"settings\",\n]);\n\nfunction fail(reason: string): never {\n\tthrow new Error(`context-cache-invalidation: ${reason}`);\n}\n\nfunction assertSafeId(value: unknown, field: string): asserts value is string {\n\tif (typeof value !== \"string\") fail(`${field} must be a string`);\n\tif (value.length === 0) fail(`${field} must not be empty`);\n\tif (value.length > CONTEXT_CACHE_INVALIDATION_SAFE_ID_MAX_LENGTH) {\n\t\tfail(`${field} exceeds ${CONTEXT_CACHE_INVALIDATION_SAFE_ID_MAX_LENGTH} characters`);\n\t}\n\tif (!SAFE_ID_PATTERN.test(value)) fail(`${field} contains unsafe characters`);\n\tif (looksLikeCredential(value)) fail(`${field} looks like a credential and was rejected`);\n}\n\nfunction assertNonNegativeSafeInt(value: unknown, field: string): asserts value is number {\n\tif (typeof value !== \"number\") fail(`${field} must be a number`);\n\tif (!Number.isFinite(value)) fail(`${field} must be finite`);\n\tif (!Number.isInteger(value)) fail(`${field} must be an integer`);\n\tif (value < 0) fail(`${field} must be nonnegative`);\n\tif (!Number.isSafeInteger(value)) fail(`${field} must be a safe integer`);\n}\n\nfunction assertExactKeys(record: Record<string, unknown>, allowed: ReadonlySet<string>, scope: string): void {\n\tconst keys = Object.keys(record);\n\tif (keys.length !== allowed.size) fail(`${scope} has unexpected keys`);\n\tfor (const key of keys) {\n\t\tif (!allowed.has(key)) fail(`${scope} has unknown key \"${key}\"`);\n\t}\n}\n\n/** Reject non-plain inputs: null, arrays, primitives, and class instances. */\nfunction assertPlainObject(value: unknown, scope: string): asserts value is Record<string, unknown> {\n\tif (value === null || typeof value !== \"object\") fail(`${scope} must be a plain object`);\n\tif (Array.isArray(value)) fail(`${scope} must be a plain object`);\n\tconst proto = Object.getPrototypeOf(value);\n\tif (proto !== null && proto !== Object.prototype) fail(`${scope} must be a plain object`);\n}\n\n/** Reject getter/setter accessors, whose reads are not stable. */\nfunction assertNoAccessors(record: object, scope: string): void {\n\tfor (const key of Object.getOwnPropertyNames(record)) {\n\t\tconst desc = Object.getOwnPropertyDescriptor(record, key);\n\t\tif (desc !== undefined && (typeof desc.get === \"function\" || typeof desc.set === \"function\")) {\n\t\t\tfail(`${scope} must not define accessors`);\n\t\t}\n\t}\n}\n\nconst INIT_REQUIRED_KEYS: ReadonlySet<string> = new Set([\n\t\"forkId\",\n\t\"worktreeFingerprint\",\n\t\"activeModelId\",\n\t\"compactionModelId\",\n]);\n\nconst INIT_OPTIONAL_KEYS: ReadonlySet<string> = new Set([\n\t\"globalEpoch\",\n\t\"transcriptRepair\",\n\t\"toolResultDisposition\",\n\t\"evidenceReceipt\",\n\t\"userSteering\",\n\t\"settings\",\n]);\n\nconst INIT_ALLOWED_KEYS: ReadonlySet<string> = new Set([...INIT_REQUIRED_KEYS, ...INIT_OPTIONAL_KEYS]);\n\n/**\n * Strictly validate a snapshot constructor input: a plain data object with\n * exactly the required identity/fork keys plus optional counters/epoch, and\n * no accessor properties. Rejects null, arrays, class instances, unknown\n * keys, and getters/setters with a stable error.\n */\nfunction assertInitShape(input: unknown): asserts input is ContextCacheInvalidationSnapshotInit {\n\tassertPlainObject(input, \"init\");\n\tassertNoAccessors(input, \"init\");\n\tfor (const key of Object.keys(input)) {\n\t\tif (!INIT_ALLOWED_KEYS.has(key)) fail(`init has unknown key \"${key}\"`);\n\t}\n\tfor (const required of INIT_REQUIRED_KEYS) {\n\t\tif (Object.getOwnPropertyDescriptor(input, required) === undefined) {\n\t\t\tfail(`init is missing required key \"${required}\"`);\n\t\t}\n\t}\n}\n\nconst COUNTER_EVENT_TYPES: ReadonlySet<string> = new Set([\n\t\"transcriptRepair\",\n\t\"toolResultDisposition\",\n\t\"evidenceReceipt\",\n\t\"userSteering\",\n\t\"settings\",\n]);\n\nconst IDENTITY_EVENT_TYPES: ReadonlySet<string> = new Set([\n\t\"worktreeFingerprint\",\n\t\"activeModelId\",\n\t\"compactionModelId\",\n]);\n\nconst COUNTER_EVENT_KEYS: ReadonlySet<string> = new Set([\"type\"]);\nconst IDENTITY_EVENT_KEYS: ReadonlySet<string> = new Set([\"type\", \"value\"]);\n\n/**\n * Strictly validate a runtime invalidation event before dispatch. The event\n * must be a plain data object carrying exactly the keys its discriminant\n * allows (counter events: `{ type }`; identity events: `{ type, value }`),\n * a known `type` string, and (for identity events) a safe value. Forged or\n * malformed events always throw here and can never fall through to an\n * undefined result.\n */\nfunction validateEvent(input: unknown): asserts input is ContextCacheInvalidationEvent {\n\tassertPlainObject(input, \"event\");\n\tassertNoAccessors(input, \"event\");\n\tconst type = input.type;\n\tif (type === undefined) fail(\"event is missing type\");\n\tif (typeof type !== \"string\") fail(\"event type must be a string\");\n\tif (COUNTER_EVENT_TYPES.has(type)) {\n\t\tassertExactKeys(input, COUNTER_EVENT_KEYS, \"event\");\n\t\treturn;\n\t}\n\tif (IDENTITY_EVENT_TYPES.has(type)) {\n\t\tassertExactKeys(input, IDENTITY_EVENT_KEYS, \"event\");\n\t\tassertSafeId(input.value, type);\n\t\treturn;\n\t}\n\tfail(`event type \"${type}\" is unknown`);\n}\n\n/**\n * Strictly validate that {@link input} is a structurally correct snapshot.\n * Rejects extra keys, missing keys, malformed counters, unsafe integers,\n * and control/credential-unsafe identifier strings. Does not require the\n * object to be frozen.\n */\nexport function validateContextCacheInvalidationSnapshot(\n\tinput: unknown,\n): asserts input is ContextCacheInvalidationSnapshot {\n\tif (input === null || typeof input !== \"object\" || Array.isArray(input)) {\n\t\tfail(\"snapshot must be a plain object\");\n\t}\n\tconst obj = input as Record<string, unknown>;\n\tassertExactKeys(obj, TOP_LEVEL_KEYS, \"snapshot\");\n\tif (obj.schemaVersion !== CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION) {\n\t\tfail(`schemaVersion must be ${CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION}`);\n\t}\n\tassertSafeId(obj.forkId, \"forkId\");\n\tassertNonNegativeSafeInt(obj.globalEpoch, \"globalEpoch\");\n\tif (obj.counters === null || typeof obj.counters !== \"object\" || Array.isArray(obj.counters)) {\n\t\tfail(\"counters must be a plain object\");\n\t}\n\tconst counters = obj.counters as Record<string, unknown>;\n\tassertExactKeys(counters, COUNTER_KEYS, \"counters\");\n\tassertNonNegativeSafeInt(counters.transcriptRepair, \"counters.transcriptRepair\");\n\tassertNonNegativeSafeInt(counters.toolResultDisposition, \"counters.toolResultDisposition\");\n\tassertNonNegativeSafeInt(counters.evidenceReceipt, \"counters.evidenceReceipt\");\n\tassertNonNegativeSafeInt(counters.userSteering, \"counters.userSteering\");\n\tassertNonNegativeSafeInt(counters.settings, \"counters.settings\");\n\tassertSafeId(obj.worktreeFingerprint, \"worktreeFingerprint\");\n\tassertSafeId(obj.activeModelId, \"activeModelId\");\n\tassertSafeId(obj.compactionModelId, \"compactionModelId\");\n}\n\n/** Non-throwing variant of {@link validateContextCacheInvalidationSnapshot}. */\nexport function isContextCacheInvalidationSnapshot(input: unknown): input is ContextCacheInvalidationSnapshot {\n\ttry {\n\t\tvalidateContextCacheInvalidationSnapshot(input);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\ninterface SnapshotBuilder {\n\tschemaVersion: typeof CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION;\n\tforkId: string;\n\tglobalEpoch: number;\n\tcounters: ContextCacheInvalidationCounters;\n\tworktreeFingerprint: string;\n\tactiveModelId: string;\n\tcompactionModelId: string;\n}\n\nfunction freezeSnapshot(builder: SnapshotBuilder): ContextCacheInvalidationSnapshot {\n\tObject.freeze(builder.counters);\n\treturn Object.freeze(builder) as ContextCacheInvalidationSnapshot;\n}\n\nfunction copyCounters(counters: ContextCacheInvalidationCounters): Record<CounterKey, number> {\n\treturn {\n\t\ttranscriptRepair: counters.transcriptRepair,\n\t\ttoolResultDisposition: counters.toolResultDisposition,\n\t\tevidenceReceipt: counters.evidenceReceipt,\n\t\tuserSteering: counters.userSteering,\n\t\tsettings: counters.settings,\n\t};\n}\n\nfunction cloneAndFreeze(snapshot: ContextCacheInvalidationSnapshot): ContextCacheInvalidationSnapshot {\n\treturn freezeSnapshot({\n\t\tschemaVersion: snapshot.schemaVersion,\n\t\tforkId: snapshot.forkId,\n\t\tglobalEpoch: snapshot.globalEpoch,\n\t\tcounters: copyCounters(snapshot.counters),\n\t\tworktreeFingerprint: snapshot.worktreeFingerprint,\n\t\tactiveModelId: snapshot.activeModelId,\n\t\tcompactionModelId: snapshot.compactionModelId,\n\t});\n}\n\nfunction resolveOptionalCounter(value: number | undefined, field: string): number {\n\tif (value === undefined) return 0;\n\tassertNonNegativeSafeInt(value, field);\n\treturn value;\n}\n\n/** Build a validated, deep-frozen initial snapshot. */\nexport function createContextCacheInvalidationSnapshot(\n\tinit: ContextCacheInvalidationSnapshotInit,\n): ContextCacheInvalidationSnapshot {\n\tassertInitShape(init);\n\tassertSafeId(init.forkId, \"forkId\");\n\tassertSafeId(init.worktreeFingerprint, \"worktreeFingerprint\");\n\tassertSafeId(init.activeModelId, \"activeModelId\");\n\tassertSafeId(init.compactionModelId, \"compactionModelId\");\n\tconst globalEpoch = init.globalEpoch ?? 0;\n\tassertNonNegativeSafeInt(globalEpoch, \"globalEpoch\");\n\treturn freezeSnapshot({\n\t\tschemaVersion: CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION,\n\t\tforkId: init.forkId,\n\t\tglobalEpoch,\n\t\tcounters: {\n\t\t\ttranscriptRepair: resolveOptionalCounter(init.transcriptRepair, \"transcriptRepair\"),\n\t\t\ttoolResultDisposition: resolveOptionalCounter(init.toolResultDisposition, \"toolResultDisposition\"),\n\t\t\tevidenceReceipt: resolveOptionalCounter(init.evidenceReceipt, \"evidenceReceipt\"),\n\t\t\tuserSteering: resolveOptionalCounter(init.userSteering, \"userSteering\"),\n\t\t\tsettings: resolveOptionalCounter(init.settings, \"settings\"),\n\t\t},\n\t\tworktreeFingerprint: init.worktreeFingerprint,\n\t\tactiveModelId: init.activeModelId,\n\t\tcompactionModelId: init.compactionModelId,\n\t});\n}\n\nfunction applyCounterEvent(current: ContextCacheInvalidationSnapshot, key: CounterKey): ContextCacheInvalidationResult {\n\tconst value = current.counters[key];\n\tif (value >= MAX_REPRESENTABLE || current.globalEpoch >= MAX_REPRESENTABLE) {\n\t\treturn Object.freeze({ status: \"overflow\", snapshot: cloneAndFreeze(current) } as const);\n\t}\n\tconst nextCounters = copyCounters(current.counters);\n\tnextCounters[key] = value + 1;\n\treturn Object.freeze({\n\t\tstatus: \"applied\",\n\t\tsnapshot: freezeSnapshot({\n\t\t\tschemaVersion: current.schemaVersion,\n\t\t\tforkId: current.forkId,\n\t\t\tglobalEpoch: current.globalEpoch + 1,\n\t\t\tcounters: nextCounters,\n\t\t\tworktreeFingerprint: current.worktreeFingerprint,\n\t\t\tactiveModelId: current.activeModelId,\n\t\t\tcompactionModelId: current.compactionModelId,\n\t\t}),\n\t} as const);\n}\n\nfunction applyIdentityEvent(\n\tcurrent: ContextCacheInvalidationSnapshot,\n\tkey: IdentityKey,\n\tvalue: string,\n): ContextCacheInvalidationResult {\n\tassertSafeId(value, key);\n\tif (current[key] === value) {\n\t\treturn Object.freeze({ status: \"unchanged\", snapshot: cloneAndFreeze(current) } as const);\n\t}\n\tif (current.globalEpoch >= MAX_REPRESENTABLE) {\n\t\treturn Object.freeze({ status: \"overflow\", snapshot: cloneAndFreeze(current) } as const);\n\t}\n\treturn Object.freeze({\n\t\tstatus: \"applied\",\n\t\tsnapshot: freezeSnapshot({\n\t\t\tschemaVersion: current.schemaVersion,\n\t\t\tforkId: current.forkId,\n\t\t\tglobalEpoch: current.globalEpoch + 1,\n\t\t\tcounters: copyCounters(current.counters),\n\t\t\tworktreeFingerprint: key === \"worktreeFingerprint\" ? value : current.worktreeFingerprint,\n\t\t\tactiveModelId: key === \"activeModelId\" ? value : current.activeModelId,\n\t\t\tcompactionModelId: key === \"compactionModelId\" ? value : current.compactionModelId,\n\t\t}),\n\t} as const);\n}\n\n/**\n * Apply a single invalidation event. Increments the global epoch and the\n * relevant counter, or sets an identity. A same-value identity set is a\n * no-op and returns {@link ContextCacheInvalidationStatus.unchanged} without\n * an epoch bump. Any counter or epoch overflow returns\n * {@link ContextCacheInvalidationStatus.overflow} with the snapshot unchanged\n * and never wraps.\n */\nexport function applyContextCacheInvalidation(\n\tcurrent: ContextCacheInvalidationSnapshot,\n\tevent: ContextCacheInvalidationEvent,\n): ContextCacheInvalidationResult {\n\tvalidateContextCacheInvalidationSnapshot(current);\n\tvalidateEvent(event);\n\tswitch (event.type) {\n\t\tcase \"transcriptRepair\":\n\t\tcase \"toolResultDisposition\":\n\t\tcase \"evidenceReceipt\":\n\t\tcase \"userSteering\":\n\t\tcase \"settings\":\n\t\t\treturn applyCounterEvent(current, event.type);\n\t\tcase \"worktreeFingerprint\":\n\t\tcase \"activeModelId\":\n\t\tcase \"compactionModelId\":\n\t\t\treturn applyIdentityEvent(current, event.type, event.value);\n\t\tdefault: {\n\t\t\t// Exhaustiveness guard: a new event variant without a matching\n\t\t\t// case becomes a compile error on the assignment below.\n\t\t\tconst _exhaustive: never = event;\n\t\t\tfail(`unhandled event type ${_exhaustive}`);\n\t\t}\n\t}\n}\n\n/**\n * Fork a snapshot: keep all event counters and identity values, change the\n * fork id, and reset the global epoch to 0. The caller supplies the new fork\n * id. Rejects an id equal to the current fork id.\n */\nexport function forkContextCacheSnapshot(\n\tcurrent: ContextCacheInvalidationSnapshot,\n\tnextForkId: string,\n): ContextCacheInvalidationSnapshot {\n\tvalidateContextCacheInvalidationSnapshot(current);\n\tassertSafeId(nextForkId, \"forkId\");\n\tif (nextForkId === current.forkId) {\n\t\tfail(\"forkId must differ from current fork\");\n\t}\n\treturn freezeSnapshot({\n\t\tschemaVersion: current.schemaVersion,\n\t\tforkId: nextForkId,\n\t\tglobalEpoch: 0,\n\t\tcounters: copyCounters(current.counters),\n\t\tworktreeFingerprint: current.worktreeFingerprint,\n\t\tactiveModelId: current.activeModelId,\n\t\tcompactionModelId: current.compactionModelId,\n\t});\n}\n\nfunction snapshotsEqual(a: ContextCacheInvalidationSnapshot, b: ContextCacheInvalidationSnapshot): boolean {\n\treturn (\n\t\ta.globalEpoch === b.globalEpoch &&\n\t\ta.counters.transcriptRepair === b.counters.transcriptRepair &&\n\t\ta.counters.toolResultDisposition === b.counters.toolResultDisposition &&\n\t\ta.counters.evidenceReceipt === b.counters.evidenceReceipt &&\n\t\ta.counters.userSteering === b.counters.userSteering &&\n\t\ta.counters.settings === b.counters.settings &&\n\t\ta.worktreeFingerprint === b.worktreeFingerprint &&\n\t\ta.activeModelId === b.activeModelId &&\n\t\ta.compactionModelId === b.compactionModelId\n\t);\n}\n\nfunction dominates(x: ContextCacheInvalidationSnapshot, y: ContextCacheInvalidationSnapshot): boolean {\n\treturn (\n\t\tx.globalEpoch >= y.globalEpoch &&\n\t\tx.counters.transcriptRepair >= y.counters.transcriptRepair &&\n\t\tx.counters.toolResultDisposition >= y.counters.toolResultDisposition &&\n\t\tx.counters.evidenceReceipt >= y.counters.evidenceReceipt &&\n\t\tx.counters.userSteering >= y.counters.userSteering &&\n\t\tx.counters.settings >= y.counters.settings &&\n\t\tx.worktreeFingerprint === y.worktreeFingerprint &&\n\t\tx.activeModelId === y.activeModelId &&\n\t\tx.compactionModelId === y.compactionModelId\n\t);\n}\n\n/**\n * Fail-closed merge of two snapshots.\n *\n * - Different fork ids, or two snapshots that are not on a shared linear\n * history, yield {@link ContextCacheMergeStatus.divergent}. Disjoint\n * changes are never max-merged.\n * - Structurally equal snapshots yield {@link ContextCacheMergeStatus.equal}.\n * - When one snapshot componentwise-dominates the other (epoch and every\n * counter greater-or-equal, and all identity values equal), the dominant\n * snapshot is chosen via {@link ContextCacheMergeStatus.dominant}.\n */\nexport function mergeContextCacheSnapshots(\n\ta: ContextCacheInvalidationSnapshot,\n\tb: ContextCacheInvalidationSnapshot,\n): ContextCacheMergeResult {\n\tvalidateContextCacheInvalidationSnapshot(a);\n\tvalidateContextCacheInvalidationSnapshot(b);\n\tif (a.forkId !== b.forkId) {\n\t\treturn Object.freeze({ status: \"divergent\", left: cloneAndFreeze(a), right: cloneAndFreeze(b) } as const);\n\t}\n\tif (snapshotsEqual(a, b)) {\n\t\treturn Object.freeze({ status: \"equal\", snapshot: cloneAndFreeze(a) } as const);\n\t}\n\tconst aDominates = dominates(a, b);\n\tconst bDominates = dominates(b, a);\n\tif (aDominates && !bDominates) {\n\t\treturn Object.freeze({ status: \"dominant\", snapshot: cloneAndFreeze(a) } as const);\n\t}\n\tif (bDominates && !aDominates) {\n\t\treturn Object.freeze({ status: \"dominant\", snapshot: cloneAndFreeze(b) } as const);\n\t}\n\treturn Object.freeze({ status: \"divergent\", left: cloneAndFreeze(a), right: cloneAndFreeze(b) } as const);\n}\n\n/**\n * Canonical, fixed-order JSON serialization of a snapshot, suitable as\n * future cache-key material. The field order is fixed and every distinct\n * field participates, so any distinct field change alters the result.\n * Returns a deterministic string with no hash claim.\n */\nexport function serializeContextCacheSnapshot(snapshot: ContextCacheInvalidationSnapshot): string {\n\tvalidateContextCacheInvalidationSnapshot(snapshot);\n\treturn JSON.stringify({\n\t\tschemaVersion: snapshot.schemaVersion,\n\t\tforkId: snapshot.forkId,\n\t\tglobalEpoch: snapshot.globalEpoch,\n\t\tcounters: {\n\t\t\ttranscriptRepair: snapshot.counters.transcriptRepair,\n\t\t\ttoolResultDisposition: snapshot.counters.toolResultDisposition,\n\t\t\tevidenceReceipt: snapshot.counters.evidenceReceipt,\n\t\t\tuserSteering: snapshot.counters.userSteering,\n\t\t\tsettings: snapshot.counters.settings,\n\t\t},\n\t\tworktreeFingerprint: snapshot.worktreeFingerprint,\n\t\tactiveModelId: snapshot.activeModelId,\n\t\tcompactionModelId: snapshot.compactionModelId,\n\t});\n}\n"]}
@@ -139,7 +139,7 @@ function assertInitShape(input) {
139
139
  fail(`init has unknown key "${key}"`);
140
140
  }
141
141
  for (const required of INIT_REQUIRED_KEYS) {
142
- if (!Object.hasOwn(input, required)) {
142
+ if (Object.getOwnPropertyDescriptor(input, required) === undefined) {
143
143
  fail(`init is missing required key "${required}"`);
144
144
  }
145
145
  }
@@ -1 +1 @@
1
- {"version":3,"file":"context-budget-v2-cache-invalidation.js","sourceRoot":"","sources":["../../src/core/context-budget-v2-cache-invalidation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Browser-safe, pure context-cache invalidation snapshot helper.\n *\n * Every public function is side-effect free and depends only on\n * platform-agnostic primitives. Returned snapshots are always\n * independently deep-frozen copies of the caller-supplied data, so\n * callers cannot mutate cached state through retained references.\n *\n * Snapshots are cache-key material for invalidation tracking, not an\n * authorization or authentication primitive.\n *\n * Schema: context-cache-invalidation-v1.\n */\n\nexport const CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION = \"context-cache-invalidation-v1\" as const;\nexport const CONTEXT_CACHE_INVALIDATION_SAFE_ID_MAX_LENGTH = 256;\n\n/** Event counters tracked by an invalidation snapshot. */\nexport interface ContextCacheInvalidationCounters {\n\treadonly transcriptRepair: number;\n\treadonly toolResultDisposition: number;\n\treadonly evidenceReceipt: number;\n\treadonly userSteering: number;\n\treadonly settings: number;\n}\n\n/** Immutable schema-v1 invalidation snapshot. */\nexport interface ContextCacheInvalidationSnapshot {\n\treadonly schemaVersion: typeof CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION;\n\treadonly forkId: string;\n\treadonly globalEpoch: number;\n\treadonly counters: ContextCacheInvalidationCounters;\n\treadonly worktreeFingerprint: string;\n\treadonly activeModelId: string;\n\treadonly compactionModelId: string;\n}\n\n/** Constructor input for a fresh snapshot. Counters and epoch default to 0. */\nexport interface ContextCacheInvalidationSnapshotInit {\n\treadonly forkId: string;\n\treadonly worktreeFingerprint: string;\n\treadonly activeModelId: string;\n\treadonly compactionModelId: string;\n\treadonly globalEpoch?: number;\n\treadonly transcriptRepair?: number;\n\treadonly toolResultDisposition?: number;\n\treadonly evidenceReceipt?: number;\n\treadonly userSteering?: number;\n\treadonly settings?: number;\n}\n\n/**\n * Strict union covering all eight invalidation events. The five counter\n * events increment their counter; the three identity events set a value.\n */\nexport type ContextCacheInvalidationEvent =\n\t| { readonly type: \"transcriptRepair\" }\n\t| { readonly type: \"toolResultDisposition\" }\n\t| { readonly type: \"evidenceReceipt\" }\n\t| { readonly type: \"userSteering\" }\n\t| { readonly type: \"settings\" }\n\t| { readonly type: \"worktreeFingerprint\"; readonly value: string }\n\t| { readonly type: \"activeModelId\"; readonly value: string }\n\t| { readonly type: \"compactionModelId\"; readonly value: string };\n\nexport type ContextCacheInvalidationStatus = \"applied\" | \"unchanged\" | \"overflow\";\n\nexport interface ContextCacheInvalidationResult {\n\treadonly status: ContextCacheInvalidationStatus;\n\treadonly snapshot: ContextCacheInvalidationSnapshot;\n}\n\nexport type ContextCacheMergeStatus = \"equal\" | \"dominant\" | \"divergent\";\n\nexport type ContextCacheMergeResult =\n\t| { readonly status: \"equal\"; readonly snapshot: ContextCacheInvalidationSnapshot }\n\t| { readonly status: \"dominant\"; readonly snapshot: ContextCacheInvalidationSnapshot }\n\t| {\n\t\t\treadonly status: \"divergent\";\n\t\t\treadonly left: ContextCacheInvalidationSnapshot;\n\t\t\treadonly right: ContextCacheInvalidationSnapshot;\n\t };\n\ntype CounterKey = \"transcriptRepair\" | \"toolResultDisposition\" | \"evidenceReceipt\" | \"userSteering\" | \"settings\";\n\ntype IdentityKey = \"worktreeFingerprint\" | \"activeModelId\" | \"compactionModelId\";\n\nconst MAX_REPRESENTABLE = Number.MAX_SAFE_INTEGER;\nconst SAFE_ID_PATTERN = /^[\\w.\\-:+]+$/u;\n\n/**\n * High-confidence credential markers, checked in addition to the\n * safe-character gate. A value already consists only of safe characters\n * before it is tested here. Each pattern is anchored to the whole string\n * to keep the false-positive rate low; identifiers and fingerprints in\n * this domain never legitimately take these shapes.\n */\nconst CREDENTIAL_MARKERS: ReadonlyArray<RegExp> = [\n\t/^sk-[A-Za-z0-9_-]{8,}$/i, // OpenAI / generic \"sk-\" secret keys\n\t/^gh[pousr]_[A-Za-z0-9]{16,}$/i, // GitHub classic tokens (ghp_ gho_ ghu_ ghs_ ghr_)\n\t/^github_pat_[A-Za-z0-9_]{20,}$/i, // GitHub fine-grained PATs\n\t/^xox[pabrse]-[A-Za-z0-9-]{10,}$/i, // Slack tokens (xoxp xoxb xoxa xoxs xoxr xoxe)\n\t/^AKIA[0-9A-Z]{16}$/, // AWS access key id (20 chars, uppercase)\n\t/^eyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}$/, // JWT (three base64url segments)\n\t/^bearer$/i, // literal Bearer token marker\n];\n\nfunction looksLikeCredential(value: string): boolean {\n\tfor (const marker of CREDENTIAL_MARKERS) {\n\t\tif (marker.test(value)) return true;\n\t}\n\treturn false;\n}\n\nconst TOP_LEVEL_KEYS: ReadonlySet<string> = new Set([\n\t\"schemaVersion\",\n\t\"forkId\",\n\t\"globalEpoch\",\n\t\"counters\",\n\t\"worktreeFingerprint\",\n\t\"activeModelId\",\n\t\"compactionModelId\",\n]);\n\nconst COUNTER_KEYS: ReadonlySet<string> = new Set([\n\t\"transcriptRepair\",\n\t\"toolResultDisposition\",\n\t\"evidenceReceipt\",\n\t\"userSteering\",\n\t\"settings\",\n]);\n\nfunction fail(reason: string): never {\n\tthrow new Error(`context-cache-invalidation: ${reason}`);\n}\n\nfunction assertSafeId(value: unknown, field: string): asserts value is string {\n\tif (typeof value !== \"string\") fail(`${field} must be a string`);\n\tif (value.length === 0) fail(`${field} must not be empty`);\n\tif (value.length > CONTEXT_CACHE_INVALIDATION_SAFE_ID_MAX_LENGTH) {\n\t\tfail(`${field} exceeds ${CONTEXT_CACHE_INVALIDATION_SAFE_ID_MAX_LENGTH} characters`);\n\t}\n\tif (!SAFE_ID_PATTERN.test(value)) fail(`${field} contains unsafe characters`);\n\tif (looksLikeCredential(value)) fail(`${field} looks like a credential and was rejected`);\n}\n\nfunction assertNonNegativeSafeInt(value: unknown, field: string): asserts value is number {\n\tif (typeof value !== \"number\") fail(`${field} must be a number`);\n\tif (!Number.isFinite(value)) fail(`${field} must be finite`);\n\tif (!Number.isInteger(value)) fail(`${field} must be an integer`);\n\tif (value < 0) fail(`${field} must be nonnegative`);\n\tif (!Number.isSafeInteger(value)) fail(`${field} must be a safe integer`);\n}\n\nfunction assertExactKeys(record: Record<string, unknown>, allowed: ReadonlySet<string>, scope: string): void {\n\tconst keys = Object.keys(record);\n\tif (keys.length !== allowed.size) fail(`${scope} has unexpected keys`);\n\tfor (const key of keys) {\n\t\tif (!allowed.has(key)) fail(`${scope} has unknown key \"${key}\"`);\n\t}\n}\n\n/** Reject non-plain inputs: null, arrays, primitives, and class instances. */\nfunction assertPlainObject(value: unknown, scope: string): asserts value is Record<string, unknown> {\n\tif (value === null || typeof value !== \"object\") fail(`${scope} must be a plain object`);\n\tif (Array.isArray(value)) fail(`${scope} must be a plain object`);\n\tconst proto = Object.getPrototypeOf(value);\n\tif (proto !== null && proto !== Object.prototype) fail(`${scope} must be a plain object`);\n}\n\n/** Reject getter/setter accessors, whose reads are not stable. */\nfunction assertNoAccessors(record: object, scope: string): void {\n\tfor (const key of Object.getOwnPropertyNames(record)) {\n\t\tconst desc = Object.getOwnPropertyDescriptor(record, key);\n\t\tif (desc !== undefined && (typeof desc.get === \"function\" || typeof desc.set === \"function\")) {\n\t\t\tfail(`${scope} must not define accessors`);\n\t\t}\n\t}\n}\n\nconst INIT_REQUIRED_KEYS: ReadonlySet<string> = new Set([\n\t\"forkId\",\n\t\"worktreeFingerprint\",\n\t\"activeModelId\",\n\t\"compactionModelId\",\n]);\n\nconst INIT_OPTIONAL_KEYS: ReadonlySet<string> = new Set([\n\t\"globalEpoch\",\n\t\"transcriptRepair\",\n\t\"toolResultDisposition\",\n\t\"evidenceReceipt\",\n\t\"userSteering\",\n\t\"settings\",\n]);\n\nconst INIT_ALLOWED_KEYS: ReadonlySet<string> = new Set([...INIT_REQUIRED_KEYS, ...INIT_OPTIONAL_KEYS]);\n\n/**\n * Strictly validate a snapshot constructor input: a plain data object with\n * exactly the required identity/fork keys plus optional counters/epoch, and\n * no accessor properties. Rejects null, arrays, class instances, unknown\n * keys, and getters/setters with a stable error.\n */\nfunction assertInitShape(input: unknown): asserts input is ContextCacheInvalidationSnapshotInit {\n\tassertPlainObject(input, \"init\");\n\tassertNoAccessors(input, \"init\");\n\tfor (const key of Object.keys(input)) {\n\t\tif (!INIT_ALLOWED_KEYS.has(key)) fail(`init has unknown key \"${key}\"`);\n\t}\n\tfor (const required of INIT_REQUIRED_KEYS) {\n\t\tif (!Object.hasOwn(input, required)) {\n\t\t\tfail(`init is missing required key \"${required}\"`);\n\t\t}\n\t}\n}\n\nconst COUNTER_EVENT_TYPES: ReadonlySet<string> = new Set([\n\t\"transcriptRepair\",\n\t\"toolResultDisposition\",\n\t\"evidenceReceipt\",\n\t\"userSteering\",\n\t\"settings\",\n]);\n\nconst IDENTITY_EVENT_TYPES: ReadonlySet<string> = new Set([\n\t\"worktreeFingerprint\",\n\t\"activeModelId\",\n\t\"compactionModelId\",\n]);\n\nconst COUNTER_EVENT_KEYS: ReadonlySet<string> = new Set([\"type\"]);\nconst IDENTITY_EVENT_KEYS: ReadonlySet<string> = new Set([\"type\", \"value\"]);\n\n/**\n * Strictly validate a runtime invalidation event before dispatch. The event\n * must be a plain data object carrying exactly the keys its discriminant\n * allows (counter events: `{ type }`; identity events: `{ type, value }`),\n * a known `type` string, and (for identity events) a safe value. Forged or\n * malformed events always throw here and can never fall through to an\n * undefined result.\n */\nfunction validateEvent(input: unknown): asserts input is ContextCacheInvalidationEvent {\n\tassertPlainObject(input, \"event\");\n\tassertNoAccessors(input, \"event\");\n\tconst type = input.type;\n\tif (type === undefined) fail(\"event is missing type\");\n\tif (typeof type !== \"string\") fail(\"event type must be a string\");\n\tif (COUNTER_EVENT_TYPES.has(type)) {\n\t\tassertExactKeys(input, COUNTER_EVENT_KEYS, \"event\");\n\t\treturn;\n\t}\n\tif (IDENTITY_EVENT_TYPES.has(type)) {\n\t\tassertExactKeys(input, IDENTITY_EVENT_KEYS, \"event\");\n\t\tassertSafeId(input.value, type);\n\t\treturn;\n\t}\n\tfail(`event type \"${type}\" is unknown`);\n}\n\n/**\n * Strictly validate that {@link input} is a structurally correct snapshot.\n * Rejects extra keys, missing keys, malformed counters, unsafe integers,\n * and control/credential-unsafe identifier strings. Does not require the\n * object to be frozen.\n */\nexport function validateContextCacheInvalidationSnapshot(\n\tinput: unknown,\n): asserts input is ContextCacheInvalidationSnapshot {\n\tif (input === null || typeof input !== \"object\" || Array.isArray(input)) {\n\t\tfail(\"snapshot must be a plain object\");\n\t}\n\tconst obj = input as Record<string, unknown>;\n\tassertExactKeys(obj, TOP_LEVEL_KEYS, \"snapshot\");\n\tif (obj.schemaVersion !== CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION) {\n\t\tfail(`schemaVersion must be ${CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION}`);\n\t}\n\tassertSafeId(obj.forkId, \"forkId\");\n\tassertNonNegativeSafeInt(obj.globalEpoch, \"globalEpoch\");\n\tif (obj.counters === null || typeof obj.counters !== \"object\" || Array.isArray(obj.counters)) {\n\t\tfail(\"counters must be a plain object\");\n\t}\n\tconst counters = obj.counters as Record<string, unknown>;\n\tassertExactKeys(counters, COUNTER_KEYS, \"counters\");\n\tassertNonNegativeSafeInt(counters.transcriptRepair, \"counters.transcriptRepair\");\n\tassertNonNegativeSafeInt(counters.toolResultDisposition, \"counters.toolResultDisposition\");\n\tassertNonNegativeSafeInt(counters.evidenceReceipt, \"counters.evidenceReceipt\");\n\tassertNonNegativeSafeInt(counters.userSteering, \"counters.userSteering\");\n\tassertNonNegativeSafeInt(counters.settings, \"counters.settings\");\n\tassertSafeId(obj.worktreeFingerprint, \"worktreeFingerprint\");\n\tassertSafeId(obj.activeModelId, \"activeModelId\");\n\tassertSafeId(obj.compactionModelId, \"compactionModelId\");\n}\n\n/** Non-throwing variant of {@link validateContextCacheInvalidationSnapshot}. */\nexport function isContextCacheInvalidationSnapshot(input: unknown): input is ContextCacheInvalidationSnapshot {\n\ttry {\n\t\tvalidateContextCacheInvalidationSnapshot(input);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\ninterface SnapshotBuilder {\n\tschemaVersion: typeof CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION;\n\tforkId: string;\n\tglobalEpoch: number;\n\tcounters: ContextCacheInvalidationCounters;\n\tworktreeFingerprint: string;\n\tactiveModelId: string;\n\tcompactionModelId: string;\n}\n\nfunction freezeSnapshot(builder: SnapshotBuilder): ContextCacheInvalidationSnapshot {\n\tObject.freeze(builder.counters);\n\treturn Object.freeze(builder) as ContextCacheInvalidationSnapshot;\n}\n\nfunction copyCounters(counters: ContextCacheInvalidationCounters): Record<CounterKey, number> {\n\treturn {\n\t\ttranscriptRepair: counters.transcriptRepair,\n\t\ttoolResultDisposition: counters.toolResultDisposition,\n\t\tevidenceReceipt: counters.evidenceReceipt,\n\t\tuserSteering: counters.userSteering,\n\t\tsettings: counters.settings,\n\t};\n}\n\nfunction cloneAndFreeze(snapshot: ContextCacheInvalidationSnapshot): ContextCacheInvalidationSnapshot {\n\treturn freezeSnapshot({\n\t\tschemaVersion: snapshot.schemaVersion,\n\t\tforkId: snapshot.forkId,\n\t\tglobalEpoch: snapshot.globalEpoch,\n\t\tcounters: copyCounters(snapshot.counters),\n\t\tworktreeFingerprint: snapshot.worktreeFingerprint,\n\t\tactiveModelId: snapshot.activeModelId,\n\t\tcompactionModelId: snapshot.compactionModelId,\n\t});\n}\n\nfunction resolveOptionalCounter(value: number | undefined, field: string): number {\n\tif (value === undefined) return 0;\n\tassertNonNegativeSafeInt(value, field);\n\treturn value;\n}\n\n/** Build a validated, deep-frozen initial snapshot. */\nexport function createContextCacheInvalidationSnapshot(\n\tinit: ContextCacheInvalidationSnapshotInit,\n): ContextCacheInvalidationSnapshot {\n\tassertInitShape(init);\n\tassertSafeId(init.forkId, \"forkId\");\n\tassertSafeId(init.worktreeFingerprint, \"worktreeFingerprint\");\n\tassertSafeId(init.activeModelId, \"activeModelId\");\n\tassertSafeId(init.compactionModelId, \"compactionModelId\");\n\tconst globalEpoch = init.globalEpoch ?? 0;\n\tassertNonNegativeSafeInt(globalEpoch, \"globalEpoch\");\n\treturn freezeSnapshot({\n\t\tschemaVersion: CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION,\n\t\tforkId: init.forkId,\n\t\tglobalEpoch,\n\t\tcounters: {\n\t\t\ttranscriptRepair: resolveOptionalCounter(init.transcriptRepair, \"transcriptRepair\"),\n\t\t\ttoolResultDisposition: resolveOptionalCounter(init.toolResultDisposition, \"toolResultDisposition\"),\n\t\t\tevidenceReceipt: resolveOptionalCounter(init.evidenceReceipt, \"evidenceReceipt\"),\n\t\t\tuserSteering: resolveOptionalCounter(init.userSteering, \"userSteering\"),\n\t\t\tsettings: resolveOptionalCounter(init.settings, \"settings\"),\n\t\t},\n\t\tworktreeFingerprint: init.worktreeFingerprint,\n\t\tactiveModelId: init.activeModelId,\n\t\tcompactionModelId: init.compactionModelId,\n\t});\n}\n\nfunction applyCounterEvent(current: ContextCacheInvalidationSnapshot, key: CounterKey): ContextCacheInvalidationResult {\n\tconst value = current.counters[key];\n\tif (value >= MAX_REPRESENTABLE || current.globalEpoch >= MAX_REPRESENTABLE) {\n\t\treturn Object.freeze({ status: \"overflow\", snapshot: cloneAndFreeze(current) } as const);\n\t}\n\tconst nextCounters = copyCounters(current.counters);\n\tnextCounters[key] = value + 1;\n\treturn Object.freeze({\n\t\tstatus: \"applied\",\n\t\tsnapshot: freezeSnapshot({\n\t\t\tschemaVersion: current.schemaVersion,\n\t\t\tforkId: current.forkId,\n\t\t\tglobalEpoch: current.globalEpoch + 1,\n\t\t\tcounters: nextCounters,\n\t\t\tworktreeFingerprint: current.worktreeFingerprint,\n\t\t\tactiveModelId: current.activeModelId,\n\t\t\tcompactionModelId: current.compactionModelId,\n\t\t}),\n\t} as const);\n}\n\nfunction applyIdentityEvent(\n\tcurrent: ContextCacheInvalidationSnapshot,\n\tkey: IdentityKey,\n\tvalue: string,\n): ContextCacheInvalidationResult {\n\tassertSafeId(value, key);\n\tif (current[key] === value) {\n\t\treturn Object.freeze({ status: \"unchanged\", snapshot: cloneAndFreeze(current) } as const);\n\t}\n\tif (current.globalEpoch >= MAX_REPRESENTABLE) {\n\t\treturn Object.freeze({ status: \"overflow\", snapshot: cloneAndFreeze(current) } as const);\n\t}\n\treturn Object.freeze({\n\t\tstatus: \"applied\",\n\t\tsnapshot: freezeSnapshot({\n\t\t\tschemaVersion: current.schemaVersion,\n\t\t\tforkId: current.forkId,\n\t\t\tglobalEpoch: current.globalEpoch + 1,\n\t\t\tcounters: copyCounters(current.counters),\n\t\t\tworktreeFingerprint: key === \"worktreeFingerprint\" ? value : current.worktreeFingerprint,\n\t\t\tactiveModelId: key === \"activeModelId\" ? value : current.activeModelId,\n\t\t\tcompactionModelId: key === \"compactionModelId\" ? value : current.compactionModelId,\n\t\t}),\n\t} as const);\n}\n\n/**\n * Apply a single invalidation event. Increments the global epoch and the\n * relevant counter, or sets an identity. A same-value identity set is a\n * no-op and returns {@link ContextCacheInvalidationStatus.unchanged} without\n * an epoch bump. Any counter or epoch overflow returns\n * {@link ContextCacheInvalidationStatus.overflow} with the snapshot unchanged\n * and never wraps.\n */\nexport function applyContextCacheInvalidation(\n\tcurrent: ContextCacheInvalidationSnapshot,\n\tevent: ContextCacheInvalidationEvent,\n): ContextCacheInvalidationResult {\n\tvalidateContextCacheInvalidationSnapshot(current);\n\tvalidateEvent(event);\n\tswitch (event.type) {\n\t\tcase \"transcriptRepair\":\n\t\tcase \"toolResultDisposition\":\n\t\tcase \"evidenceReceipt\":\n\t\tcase \"userSteering\":\n\t\tcase \"settings\":\n\t\t\treturn applyCounterEvent(current, event.type);\n\t\tcase \"worktreeFingerprint\":\n\t\tcase \"activeModelId\":\n\t\tcase \"compactionModelId\":\n\t\t\treturn applyIdentityEvent(current, event.type, event.value);\n\t\tdefault: {\n\t\t\t// Exhaustiveness guard: a new event variant without a matching\n\t\t\t// case becomes a compile error on the assignment below.\n\t\t\tconst _exhaustive: never = event;\n\t\t\tfail(`unhandled event type ${_exhaustive}`);\n\t\t}\n\t}\n}\n\n/**\n * Fork a snapshot: keep all event counters and identity values, change the\n * fork id, and reset the global epoch to 0. The caller supplies the new fork\n * id. Rejects an id equal to the current fork id.\n */\nexport function forkContextCacheSnapshot(\n\tcurrent: ContextCacheInvalidationSnapshot,\n\tnextForkId: string,\n): ContextCacheInvalidationSnapshot {\n\tvalidateContextCacheInvalidationSnapshot(current);\n\tassertSafeId(nextForkId, \"forkId\");\n\tif (nextForkId === current.forkId) {\n\t\tfail(\"forkId must differ from current fork\");\n\t}\n\treturn freezeSnapshot({\n\t\tschemaVersion: current.schemaVersion,\n\t\tforkId: nextForkId,\n\t\tglobalEpoch: 0,\n\t\tcounters: copyCounters(current.counters),\n\t\tworktreeFingerprint: current.worktreeFingerprint,\n\t\tactiveModelId: current.activeModelId,\n\t\tcompactionModelId: current.compactionModelId,\n\t});\n}\n\nfunction snapshotsEqual(a: ContextCacheInvalidationSnapshot, b: ContextCacheInvalidationSnapshot): boolean {\n\treturn (\n\t\ta.globalEpoch === b.globalEpoch &&\n\t\ta.counters.transcriptRepair === b.counters.transcriptRepair &&\n\t\ta.counters.toolResultDisposition === b.counters.toolResultDisposition &&\n\t\ta.counters.evidenceReceipt === b.counters.evidenceReceipt &&\n\t\ta.counters.userSteering === b.counters.userSteering &&\n\t\ta.counters.settings === b.counters.settings &&\n\t\ta.worktreeFingerprint === b.worktreeFingerprint &&\n\t\ta.activeModelId === b.activeModelId &&\n\t\ta.compactionModelId === b.compactionModelId\n\t);\n}\n\nfunction dominates(x: ContextCacheInvalidationSnapshot, y: ContextCacheInvalidationSnapshot): boolean {\n\treturn (\n\t\tx.globalEpoch >= y.globalEpoch &&\n\t\tx.counters.transcriptRepair >= y.counters.transcriptRepair &&\n\t\tx.counters.toolResultDisposition >= y.counters.toolResultDisposition &&\n\t\tx.counters.evidenceReceipt >= y.counters.evidenceReceipt &&\n\t\tx.counters.userSteering >= y.counters.userSteering &&\n\t\tx.counters.settings >= y.counters.settings &&\n\t\tx.worktreeFingerprint === y.worktreeFingerprint &&\n\t\tx.activeModelId === y.activeModelId &&\n\t\tx.compactionModelId === y.compactionModelId\n\t);\n}\n\n/**\n * Fail-closed merge of two snapshots.\n *\n * - Different fork ids, or two snapshots that are not on a shared linear\n * history, yield {@link ContextCacheMergeStatus.divergent}. Disjoint\n * changes are never max-merged.\n * - Structurally equal snapshots yield {@link ContextCacheMergeStatus.equal}.\n * - When one snapshot componentwise-dominates the other (epoch and every\n * counter greater-or-equal, and all identity values equal), the dominant\n * snapshot is chosen via {@link ContextCacheMergeStatus.dominant}.\n */\nexport function mergeContextCacheSnapshots(\n\ta: ContextCacheInvalidationSnapshot,\n\tb: ContextCacheInvalidationSnapshot,\n): ContextCacheMergeResult {\n\tvalidateContextCacheInvalidationSnapshot(a);\n\tvalidateContextCacheInvalidationSnapshot(b);\n\tif (a.forkId !== b.forkId) {\n\t\treturn Object.freeze({ status: \"divergent\", left: cloneAndFreeze(a), right: cloneAndFreeze(b) } as const);\n\t}\n\tif (snapshotsEqual(a, b)) {\n\t\treturn Object.freeze({ status: \"equal\", snapshot: cloneAndFreeze(a) } as const);\n\t}\n\tconst aDominates = dominates(a, b);\n\tconst bDominates = dominates(b, a);\n\tif (aDominates && !bDominates) {\n\t\treturn Object.freeze({ status: \"dominant\", snapshot: cloneAndFreeze(a) } as const);\n\t}\n\tif (bDominates && !aDominates) {\n\t\treturn Object.freeze({ status: \"dominant\", snapshot: cloneAndFreeze(b) } as const);\n\t}\n\treturn Object.freeze({ status: \"divergent\", left: cloneAndFreeze(a), right: cloneAndFreeze(b) } as const);\n}\n\n/**\n * Canonical, fixed-order JSON serialization of a snapshot, suitable as\n * future cache-key material. The field order is fixed and every distinct\n * field participates, so any distinct field change alters the result.\n * Returns a deterministic string with no hash claim.\n */\nexport function serializeContextCacheSnapshot(snapshot: ContextCacheInvalidationSnapshot): string {\n\tvalidateContextCacheInvalidationSnapshot(snapshot);\n\treturn JSON.stringify({\n\t\tschemaVersion: snapshot.schemaVersion,\n\t\tforkId: snapshot.forkId,\n\t\tglobalEpoch: snapshot.globalEpoch,\n\t\tcounters: {\n\t\t\ttranscriptRepair: snapshot.counters.transcriptRepair,\n\t\t\ttoolResultDisposition: snapshot.counters.toolResultDisposition,\n\t\t\tevidenceReceipt: snapshot.counters.evidenceReceipt,\n\t\t\tuserSteering: snapshot.counters.userSteering,\n\t\t\tsettings: snapshot.counters.settings,\n\t\t},\n\t\tworktreeFingerprint: snapshot.worktreeFingerprint,\n\t\tactiveModelId: snapshot.activeModelId,\n\t\tcompactionModelId: snapshot.compactionModelId,\n\t});\n}\n"]}
1
+ {"version":3,"file":"context-budget-v2-cache-invalidation.js","sourceRoot":"","sources":["../../src/core/context-budget-v2-cache-invalidation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Browser-safe, pure context-cache invalidation snapshot helper.\n *\n * Every public function is side-effect free and depends only on\n * platform-agnostic primitives. Returned snapshots are always\n * independently deep-frozen copies of the caller-supplied data, so\n * callers cannot mutate cached state through retained references.\n *\n * Snapshots are cache-key material for invalidation tracking, not an\n * authorization or authentication primitive.\n *\n * Schema: context-cache-invalidation-v1.\n */\n\nexport const CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION = \"context-cache-invalidation-v1\" as const;\nexport const CONTEXT_CACHE_INVALIDATION_SAFE_ID_MAX_LENGTH = 256;\n\n/** Event counters tracked by an invalidation snapshot. */\nexport interface ContextCacheInvalidationCounters {\n\treadonly transcriptRepair: number;\n\treadonly toolResultDisposition: number;\n\treadonly evidenceReceipt: number;\n\treadonly userSteering: number;\n\treadonly settings: number;\n}\n\n/** Immutable schema-v1 invalidation snapshot. */\nexport interface ContextCacheInvalidationSnapshot {\n\treadonly schemaVersion: typeof CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION;\n\treadonly forkId: string;\n\treadonly globalEpoch: number;\n\treadonly counters: ContextCacheInvalidationCounters;\n\treadonly worktreeFingerprint: string;\n\treadonly activeModelId: string;\n\treadonly compactionModelId: string;\n}\n\n/** Constructor input for a fresh snapshot. Counters and epoch default to 0. */\nexport interface ContextCacheInvalidationSnapshotInit {\n\treadonly forkId: string;\n\treadonly worktreeFingerprint: string;\n\treadonly activeModelId: string;\n\treadonly compactionModelId: string;\n\treadonly globalEpoch?: number;\n\treadonly transcriptRepair?: number;\n\treadonly toolResultDisposition?: number;\n\treadonly evidenceReceipt?: number;\n\treadonly userSteering?: number;\n\treadonly settings?: number;\n}\n\n/**\n * Strict union covering all eight invalidation events. The five counter\n * events increment their counter; the three identity events set a value.\n */\nexport type ContextCacheInvalidationEvent =\n\t| { readonly type: \"transcriptRepair\" }\n\t| { readonly type: \"toolResultDisposition\" }\n\t| { readonly type: \"evidenceReceipt\" }\n\t| { readonly type: \"userSteering\" }\n\t| { readonly type: \"settings\" }\n\t| { readonly type: \"worktreeFingerprint\"; readonly value: string }\n\t| { readonly type: \"activeModelId\"; readonly value: string }\n\t| { readonly type: \"compactionModelId\"; readonly value: string };\n\nexport type ContextCacheInvalidationStatus = \"applied\" | \"unchanged\" | \"overflow\";\n\nexport interface ContextCacheInvalidationResult {\n\treadonly status: ContextCacheInvalidationStatus;\n\treadonly snapshot: ContextCacheInvalidationSnapshot;\n}\n\nexport type ContextCacheMergeStatus = \"equal\" | \"dominant\" | \"divergent\";\n\nexport type ContextCacheMergeResult =\n\t| { readonly status: \"equal\"; readonly snapshot: ContextCacheInvalidationSnapshot }\n\t| { readonly status: \"dominant\"; readonly snapshot: ContextCacheInvalidationSnapshot }\n\t| {\n\t\t\treadonly status: \"divergent\";\n\t\t\treadonly left: ContextCacheInvalidationSnapshot;\n\t\t\treadonly right: ContextCacheInvalidationSnapshot;\n\t };\n\ntype CounterKey = \"transcriptRepair\" | \"toolResultDisposition\" | \"evidenceReceipt\" | \"userSteering\" | \"settings\";\n\ntype IdentityKey = \"worktreeFingerprint\" | \"activeModelId\" | \"compactionModelId\";\n\nconst MAX_REPRESENTABLE = Number.MAX_SAFE_INTEGER;\nconst SAFE_ID_PATTERN = /^[\\w.\\-:+]+$/u;\n\n/**\n * High-confidence credential markers, checked in addition to the\n * safe-character gate. A value already consists only of safe characters\n * before it is tested here. Each pattern is anchored to the whole string\n * to keep the false-positive rate low; identifiers and fingerprints in\n * this domain never legitimately take these shapes.\n */\nconst CREDENTIAL_MARKERS: ReadonlyArray<RegExp> = [\n\t/^sk-[A-Za-z0-9_-]{8,}$/i, // OpenAI / generic \"sk-\" secret keys\n\t/^gh[pousr]_[A-Za-z0-9]{16,}$/i, // GitHub classic tokens (ghp_ gho_ ghu_ ghs_ ghr_)\n\t/^github_pat_[A-Za-z0-9_]{20,}$/i, // GitHub fine-grained PATs\n\t/^xox[pabrse]-[A-Za-z0-9-]{10,}$/i, // Slack tokens (xoxp xoxb xoxa xoxs xoxr xoxe)\n\t/^AKIA[0-9A-Z]{16}$/, // AWS access key id (20 chars, uppercase)\n\t/^eyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}$/, // JWT (three base64url segments)\n\t/^bearer$/i, // literal Bearer token marker\n];\n\nfunction looksLikeCredential(value: string): boolean {\n\tfor (const marker of CREDENTIAL_MARKERS) {\n\t\tif (marker.test(value)) return true;\n\t}\n\treturn false;\n}\n\nconst TOP_LEVEL_KEYS: ReadonlySet<string> = new Set([\n\t\"schemaVersion\",\n\t\"forkId\",\n\t\"globalEpoch\",\n\t\"counters\",\n\t\"worktreeFingerprint\",\n\t\"activeModelId\",\n\t\"compactionModelId\",\n]);\n\nconst COUNTER_KEYS: ReadonlySet<string> = new Set([\n\t\"transcriptRepair\",\n\t\"toolResultDisposition\",\n\t\"evidenceReceipt\",\n\t\"userSteering\",\n\t\"settings\",\n]);\n\nfunction fail(reason: string): never {\n\tthrow new Error(`context-cache-invalidation: ${reason}`);\n}\n\nfunction assertSafeId(value: unknown, field: string): asserts value is string {\n\tif (typeof value !== \"string\") fail(`${field} must be a string`);\n\tif (value.length === 0) fail(`${field} must not be empty`);\n\tif (value.length > CONTEXT_CACHE_INVALIDATION_SAFE_ID_MAX_LENGTH) {\n\t\tfail(`${field} exceeds ${CONTEXT_CACHE_INVALIDATION_SAFE_ID_MAX_LENGTH} characters`);\n\t}\n\tif (!SAFE_ID_PATTERN.test(value)) fail(`${field} contains unsafe characters`);\n\tif (looksLikeCredential(value)) fail(`${field} looks like a credential and was rejected`);\n}\n\nfunction assertNonNegativeSafeInt(value: unknown, field: string): asserts value is number {\n\tif (typeof value !== \"number\") fail(`${field} must be a number`);\n\tif (!Number.isFinite(value)) fail(`${field} must be finite`);\n\tif (!Number.isInteger(value)) fail(`${field} must be an integer`);\n\tif (value < 0) fail(`${field} must be nonnegative`);\n\tif (!Number.isSafeInteger(value)) fail(`${field} must be a safe integer`);\n}\n\nfunction assertExactKeys(record: Record<string, unknown>, allowed: ReadonlySet<string>, scope: string): void {\n\tconst keys = Object.keys(record);\n\tif (keys.length !== allowed.size) fail(`${scope} has unexpected keys`);\n\tfor (const key of keys) {\n\t\tif (!allowed.has(key)) fail(`${scope} has unknown key \"${key}\"`);\n\t}\n}\n\n/** Reject non-plain inputs: null, arrays, primitives, and class instances. */\nfunction assertPlainObject(value: unknown, scope: string): asserts value is Record<string, unknown> {\n\tif (value === null || typeof value !== \"object\") fail(`${scope} must be a plain object`);\n\tif (Array.isArray(value)) fail(`${scope} must be a plain object`);\n\tconst proto = Object.getPrototypeOf(value);\n\tif (proto !== null && proto !== Object.prototype) fail(`${scope} must be a plain object`);\n}\n\n/** Reject getter/setter accessors, whose reads are not stable. */\nfunction assertNoAccessors(record: object, scope: string): void {\n\tfor (const key of Object.getOwnPropertyNames(record)) {\n\t\tconst desc = Object.getOwnPropertyDescriptor(record, key);\n\t\tif (desc !== undefined && (typeof desc.get === \"function\" || typeof desc.set === \"function\")) {\n\t\t\tfail(`${scope} must not define accessors`);\n\t\t}\n\t}\n}\n\nconst INIT_REQUIRED_KEYS: ReadonlySet<string> = new Set([\n\t\"forkId\",\n\t\"worktreeFingerprint\",\n\t\"activeModelId\",\n\t\"compactionModelId\",\n]);\n\nconst INIT_OPTIONAL_KEYS: ReadonlySet<string> = new Set([\n\t\"globalEpoch\",\n\t\"transcriptRepair\",\n\t\"toolResultDisposition\",\n\t\"evidenceReceipt\",\n\t\"userSteering\",\n\t\"settings\",\n]);\n\nconst INIT_ALLOWED_KEYS: ReadonlySet<string> = new Set([...INIT_REQUIRED_KEYS, ...INIT_OPTIONAL_KEYS]);\n\n/**\n * Strictly validate a snapshot constructor input: a plain data object with\n * exactly the required identity/fork keys plus optional counters/epoch, and\n * no accessor properties. Rejects null, arrays, class instances, unknown\n * keys, and getters/setters with a stable error.\n */\nfunction assertInitShape(input: unknown): asserts input is ContextCacheInvalidationSnapshotInit {\n\tassertPlainObject(input, \"init\");\n\tassertNoAccessors(input, \"init\");\n\tfor (const key of Object.keys(input)) {\n\t\tif (!INIT_ALLOWED_KEYS.has(key)) fail(`init has unknown key \"${key}\"`);\n\t}\n\tfor (const required of INIT_REQUIRED_KEYS) {\n\t\tif (Object.getOwnPropertyDescriptor(input, required) === undefined) {\n\t\t\tfail(`init is missing required key \"${required}\"`);\n\t\t}\n\t}\n}\n\nconst COUNTER_EVENT_TYPES: ReadonlySet<string> = new Set([\n\t\"transcriptRepair\",\n\t\"toolResultDisposition\",\n\t\"evidenceReceipt\",\n\t\"userSteering\",\n\t\"settings\",\n]);\n\nconst IDENTITY_EVENT_TYPES: ReadonlySet<string> = new Set([\n\t\"worktreeFingerprint\",\n\t\"activeModelId\",\n\t\"compactionModelId\",\n]);\n\nconst COUNTER_EVENT_KEYS: ReadonlySet<string> = new Set([\"type\"]);\nconst IDENTITY_EVENT_KEYS: ReadonlySet<string> = new Set([\"type\", \"value\"]);\n\n/**\n * Strictly validate a runtime invalidation event before dispatch. The event\n * must be a plain data object carrying exactly the keys its discriminant\n * allows (counter events: `{ type }`; identity events: `{ type, value }`),\n * a known `type` string, and (for identity events) a safe value. Forged or\n * malformed events always throw here and can never fall through to an\n * undefined result.\n */\nfunction validateEvent(input: unknown): asserts input is ContextCacheInvalidationEvent {\n\tassertPlainObject(input, \"event\");\n\tassertNoAccessors(input, \"event\");\n\tconst type = input.type;\n\tif (type === undefined) fail(\"event is missing type\");\n\tif (typeof type !== \"string\") fail(\"event type must be a string\");\n\tif (COUNTER_EVENT_TYPES.has(type)) {\n\t\tassertExactKeys(input, COUNTER_EVENT_KEYS, \"event\");\n\t\treturn;\n\t}\n\tif (IDENTITY_EVENT_TYPES.has(type)) {\n\t\tassertExactKeys(input, IDENTITY_EVENT_KEYS, \"event\");\n\t\tassertSafeId(input.value, type);\n\t\treturn;\n\t}\n\tfail(`event type \"${type}\" is unknown`);\n}\n\n/**\n * Strictly validate that {@link input} is a structurally correct snapshot.\n * Rejects extra keys, missing keys, malformed counters, unsafe integers,\n * and control/credential-unsafe identifier strings. Does not require the\n * object to be frozen.\n */\nexport function validateContextCacheInvalidationSnapshot(\n\tinput: unknown,\n): asserts input is ContextCacheInvalidationSnapshot {\n\tif (input === null || typeof input !== \"object\" || Array.isArray(input)) {\n\t\tfail(\"snapshot must be a plain object\");\n\t}\n\tconst obj = input as Record<string, unknown>;\n\tassertExactKeys(obj, TOP_LEVEL_KEYS, \"snapshot\");\n\tif (obj.schemaVersion !== CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION) {\n\t\tfail(`schemaVersion must be ${CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION}`);\n\t}\n\tassertSafeId(obj.forkId, \"forkId\");\n\tassertNonNegativeSafeInt(obj.globalEpoch, \"globalEpoch\");\n\tif (obj.counters === null || typeof obj.counters !== \"object\" || Array.isArray(obj.counters)) {\n\t\tfail(\"counters must be a plain object\");\n\t}\n\tconst counters = obj.counters as Record<string, unknown>;\n\tassertExactKeys(counters, COUNTER_KEYS, \"counters\");\n\tassertNonNegativeSafeInt(counters.transcriptRepair, \"counters.transcriptRepair\");\n\tassertNonNegativeSafeInt(counters.toolResultDisposition, \"counters.toolResultDisposition\");\n\tassertNonNegativeSafeInt(counters.evidenceReceipt, \"counters.evidenceReceipt\");\n\tassertNonNegativeSafeInt(counters.userSteering, \"counters.userSteering\");\n\tassertNonNegativeSafeInt(counters.settings, \"counters.settings\");\n\tassertSafeId(obj.worktreeFingerprint, \"worktreeFingerprint\");\n\tassertSafeId(obj.activeModelId, \"activeModelId\");\n\tassertSafeId(obj.compactionModelId, \"compactionModelId\");\n}\n\n/** Non-throwing variant of {@link validateContextCacheInvalidationSnapshot}. */\nexport function isContextCacheInvalidationSnapshot(input: unknown): input is ContextCacheInvalidationSnapshot {\n\ttry {\n\t\tvalidateContextCacheInvalidationSnapshot(input);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\ninterface SnapshotBuilder {\n\tschemaVersion: typeof CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION;\n\tforkId: string;\n\tglobalEpoch: number;\n\tcounters: ContextCacheInvalidationCounters;\n\tworktreeFingerprint: string;\n\tactiveModelId: string;\n\tcompactionModelId: string;\n}\n\nfunction freezeSnapshot(builder: SnapshotBuilder): ContextCacheInvalidationSnapshot {\n\tObject.freeze(builder.counters);\n\treturn Object.freeze(builder) as ContextCacheInvalidationSnapshot;\n}\n\nfunction copyCounters(counters: ContextCacheInvalidationCounters): Record<CounterKey, number> {\n\treturn {\n\t\ttranscriptRepair: counters.transcriptRepair,\n\t\ttoolResultDisposition: counters.toolResultDisposition,\n\t\tevidenceReceipt: counters.evidenceReceipt,\n\t\tuserSteering: counters.userSteering,\n\t\tsettings: counters.settings,\n\t};\n}\n\nfunction cloneAndFreeze(snapshot: ContextCacheInvalidationSnapshot): ContextCacheInvalidationSnapshot {\n\treturn freezeSnapshot({\n\t\tschemaVersion: snapshot.schemaVersion,\n\t\tforkId: snapshot.forkId,\n\t\tglobalEpoch: snapshot.globalEpoch,\n\t\tcounters: copyCounters(snapshot.counters),\n\t\tworktreeFingerprint: snapshot.worktreeFingerprint,\n\t\tactiveModelId: snapshot.activeModelId,\n\t\tcompactionModelId: snapshot.compactionModelId,\n\t});\n}\n\nfunction resolveOptionalCounter(value: number | undefined, field: string): number {\n\tif (value === undefined) return 0;\n\tassertNonNegativeSafeInt(value, field);\n\treturn value;\n}\n\n/** Build a validated, deep-frozen initial snapshot. */\nexport function createContextCacheInvalidationSnapshot(\n\tinit: ContextCacheInvalidationSnapshotInit,\n): ContextCacheInvalidationSnapshot {\n\tassertInitShape(init);\n\tassertSafeId(init.forkId, \"forkId\");\n\tassertSafeId(init.worktreeFingerprint, \"worktreeFingerprint\");\n\tassertSafeId(init.activeModelId, \"activeModelId\");\n\tassertSafeId(init.compactionModelId, \"compactionModelId\");\n\tconst globalEpoch = init.globalEpoch ?? 0;\n\tassertNonNegativeSafeInt(globalEpoch, \"globalEpoch\");\n\treturn freezeSnapshot({\n\t\tschemaVersion: CONTEXT_CACHE_INVALIDATION_SCHEMA_VERSION,\n\t\tforkId: init.forkId,\n\t\tglobalEpoch,\n\t\tcounters: {\n\t\t\ttranscriptRepair: resolveOptionalCounter(init.transcriptRepair, \"transcriptRepair\"),\n\t\t\ttoolResultDisposition: resolveOptionalCounter(init.toolResultDisposition, \"toolResultDisposition\"),\n\t\t\tevidenceReceipt: resolveOptionalCounter(init.evidenceReceipt, \"evidenceReceipt\"),\n\t\t\tuserSteering: resolveOptionalCounter(init.userSteering, \"userSteering\"),\n\t\t\tsettings: resolveOptionalCounter(init.settings, \"settings\"),\n\t\t},\n\t\tworktreeFingerprint: init.worktreeFingerprint,\n\t\tactiveModelId: init.activeModelId,\n\t\tcompactionModelId: init.compactionModelId,\n\t});\n}\n\nfunction applyCounterEvent(current: ContextCacheInvalidationSnapshot, key: CounterKey): ContextCacheInvalidationResult {\n\tconst value = current.counters[key];\n\tif (value >= MAX_REPRESENTABLE || current.globalEpoch >= MAX_REPRESENTABLE) {\n\t\treturn Object.freeze({ status: \"overflow\", snapshot: cloneAndFreeze(current) } as const);\n\t}\n\tconst nextCounters = copyCounters(current.counters);\n\tnextCounters[key] = value + 1;\n\treturn Object.freeze({\n\t\tstatus: \"applied\",\n\t\tsnapshot: freezeSnapshot({\n\t\t\tschemaVersion: current.schemaVersion,\n\t\t\tforkId: current.forkId,\n\t\t\tglobalEpoch: current.globalEpoch + 1,\n\t\t\tcounters: nextCounters,\n\t\t\tworktreeFingerprint: current.worktreeFingerprint,\n\t\t\tactiveModelId: current.activeModelId,\n\t\t\tcompactionModelId: current.compactionModelId,\n\t\t}),\n\t} as const);\n}\n\nfunction applyIdentityEvent(\n\tcurrent: ContextCacheInvalidationSnapshot,\n\tkey: IdentityKey,\n\tvalue: string,\n): ContextCacheInvalidationResult {\n\tassertSafeId(value, key);\n\tif (current[key] === value) {\n\t\treturn Object.freeze({ status: \"unchanged\", snapshot: cloneAndFreeze(current) } as const);\n\t}\n\tif (current.globalEpoch >= MAX_REPRESENTABLE) {\n\t\treturn Object.freeze({ status: \"overflow\", snapshot: cloneAndFreeze(current) } as const);\n\t}\n\treturn Object.freeze({\n\t\tstatus: \"applied\",\n\t\tsnapshot: freezeSnapshot({\n\t\t\tschemaVersion: current.schemaVersion,\n\t\t\tforkId: current.forkId,\n\t\t\tglobalEpoch: current.globalEpoch + 1,\n\t\t\tcounters: copyCounters(current.counters),\n\t\t\tworktreeFingerprint: key === \"worktreeFingerprint\" ? value : current.worktreeFingerprint,\n\t\t\tactiveModelId: key === \"activeModelId\" ? value : current.activeModelId,\n\t\t\tcompactionModelId: key === \"compactionModelId\" ? value : current.compactionModelId,\n\t\t}),\n\t} as const);\n}\n\n/**\n * Apply a single invalidation event. Increments the global epoch and the\n * relevant counter, or sets an identity. A same-value identity set is a\n * no-op and returns {@link ContextCacheInvalidationStatus.unchanged} without\n * an epoch bump. Any counter or epoch overflow returns\n * {@link ContextCacheInvalidationStatus.overflow} with the snapshot unchanged\n * and never wraps.\n */\nexport function applyContextCacheInvalidation(\n\tcurrent: ContextCacheInvalidationSnapshot,\n\tevent: ContextCacheInvalidationEvent,\n): ContextCacheInvalidationResult {\n\tvalidateContextCacheInvalidationSnapshot(current);\n\tvalidateEvent(event);\n\tswitch (event.type) {\n\t\tcase \"transcriptRepair\":\n\t\tcase \"toolResultDisposition\":\n\t\tcase \"evidenceReceipt\":\n\t\tcase \"userSteering\":\n\t\tcase \"settings\":\n\t\t\treturn applyCounterEvent(current, event.type);\n\t\tcase \"worktreeFingerprint\":\n\t\tcase \"activeModelId\":\n\t\tcase \"compactionModelId\":\n\t\t\treturn applyIdentityEvent(current, event.type, event.value);\n\t\tdefault: {\n\t\t\t// Exhaustiveness guard: a new event variant without a matching\n\t\t\t// case becomes a compile error on the assignment below.\n\t\t\tconst _exhaustive: never = event;\n\t\t\tfail(`unhandled event type ${_exhaustive}`);\n\t\t}\n\t}\n}\n\n/**\n * Fork a snapshot: keep all event counters and identity values, change the\n * fork id, and reset the global epoch to 0. The caller supplies the new fork\n * id. Rejects an id equal to the current fork id.\n */\nexport function forkContextCacheSnapshot(\n\tcurrent: ContextCacheInvalidationSnapshot,\n\tnextForkId: string,\n): ContextCacheInvalidationSnapshot {\n\tvalidateContextCacheInvalidationSnapshot(current);\n\tassertSafeId(nextForkId, \"forkId\");\n\tif (nextForkId === current.forkId) {\n\t\tfail(\"forkId must differ from current fork\");\n\t}\n\treturn freezeSnapshot({\n\t\tschemaVersion: current.schemaVersion,\n\t\tforkId: nextForkId,\n\t\tglobalEpoch: 0,\n\t\tcounters: copyCounters(current.counters),\n\t\tworktreeFingerprint: current.worktreeFingerprint,\n\t\tactiveModelId: current.activeModelId,\n\t\tcompactionModelId: current.compactionModelId,\n\t});\n}\n\nfunction snapshotsEqual(a: ContextCacheInvalidationSnapshot, b: ContextCacheInvalidationSnapshot): boolean {\n\treturn (\n\t\ta.globalEpoch === b.globalEpoch &&\n\t\ta.counters.transcriptRepair === b.counters.transcriptRepair &&\n\t\ta.counters.toolResultDisposition === b.counters.toolResultDisposition &&\n\t\ta.counters.evidenceReceipt === b.counters.evidenceReceipt &&\n\t\ta.counters.userSteering === b.counters.userSteering &&\n\t\ta.counters.settings === b.counters.settings &&\n\t\ta.worktreeFingerprint === b.worktreeFingerprint &&\n\t\ta.activeModelId === b.activeModelId &&\n\t\ta.compactionModelId === b.compactionModelId\n\t);\n}\n\nfunction dominates(x: ContextCacheInvalidationSnapshot, y: ContextCacheInvalidationSnapshot): boolean {\n\treturn (\n\t\tx.globalEpoch >= y.globalEpoch &&\n\t\tx.counters.transcriptRepair >= y.counters.transcriptRepair &&\n\t\tx.counters.toolResultDisposition >= y.counters.toolResultDisposition &&\n\t\tx.counters.evidenceReceipt >= y.counters.evidenceReceipt &&\n\t\tx.counters.userSteering >= y.counters.userSteering &&\n\t\tx.counters.settings >= y.counters.settings &&\n\t\tx.worktreeFingerprint === y.worktreeFingerprint &&\n\t\tx.activeModelId === y.activeModelId &&\n\t\tx.compactionModelId === y.compactionModelId\n\t);\n}\n\n/**\n * Fail-closed merge of two snapshots.\n *\n * - Different fork ids, or two snapshots that are not on a shared linear\n * history, yield {@link ContextCacheMergeStatus.divergent}. Disjoint\n * changes are never max-merged.\n * - Structurally equal snapshots yield {@link ContextCacheMergeStatus.equal}.\n * - When one snapshot componentwise-dominates the other (epoch and every\n * counter greater-or-equal, and all identity values equal), the dominant\n * snapshot is chosen via {@link ContextCacheMergeStatus.dominant}.\n */\nexport function mergeContextCacheSnapshots(\n\ta: ContextCacheInvalidationSnapshot,\n\tb: ContextCacheInvalidationSnapshot,\n): ContextCacheMergeResult {\n\tvalidateContextCacheInvalidationSnapshot(a);\n\tvalidateContextCacheInvalidationSnapshot(b);\n\tif (a.forkId !== b.forkId) {\n\t\treturn Object.freeze({ status: \"divergent\", left: cloneAndFreeze(a), right: cloneAndFreeze(b) } as const);\n\t}\n\tif (snapshotsEqual(a, b)) {\n\t\treturn Object.freeze({ status: \"equal\", snapshot: cloneAndFreeze(a) } as const);\n\t}\n\tconst aDominates = dominates(a, b);\n\tconst bDominates = dominates(b, a);\n\tif (aDominates && !bDominates) {\n\t\treturn Object.freeze({ status: \"dominant\", snapshot: cloneAndFreeze(a) } as const);\n\t}\n\tif (bDominates && !aDominates) {\n\t\treturn Object.freeze({ status: \"dominant\", snapshot: cloneAndFreeze(b) } as const);\n\t}\n\treturn Object.freeze({ status: \"divergent\", left: cloneAndFreeze(a), right: cloneAndFreeze(b) } as const);\n}\n\n/**\n * Canonical, fixed-order JSON serialization of a snapshot, suitable as\n * future cache-key material. The field order is fixed and every distinct\n * field participates, so any distinct field change alters the result.\n * Returns a deterministic string with no hash claim.\n */\nexport function serializeContextCacheSnapshot(snapshot: ContextCacheInvalidationSnapshot): string {\n\tvalidateContextCacheInvalidationSnapshot(snapshot);\n\treturn JSON.stringify({\n\t\tschemaVersion: snapshot.schemaVersion,\n\t\tforkId: snapshot.forkId,\n\t\tglobalEpoch: snapshot.globalEpoch,\n\t\tcounters: {\n\t\t\ttranscriptRepair: snapshot.counters.transcriptRepair,\n\t\t\ttoolResultDisposition: snapshot.counters.toolResultDisposition,\n\t\t\tevidenceReceipt: snapshot.counters.evidenceReceipt,\n\t\t\tuserSteering: snapshot.counters.userSteering,\n\t\t\tsettings: snapshot.counters.settings,\n\t\t},\n\t\tworktreeFingerprint: snapshot.worktreeFingerprint,\n\t\tactiveModelId: snapshot.activeModelId,\n\t\tcompactionModelId: snapshot.compactionModelId,\n\t});\n}\n"]}
@@ -6,8 +6,9 @@ export declare class MemoryContextBudgetCacheProviderV2 implements ContextBudget
6
6
  private readonly negatives;
7
7
  private readonly plans;
8
8
  private readonly layer;
9
+ private readonly maxEntries;
9
10
  private invalidationSnapshot;
10
- constructor(layer: ContextBudgetCacheLayerV2);
11
+ constructor(layer: ContextBudgetCacheLayerV2, maxEntries?: number);
11
12
  getInvalidationSnapshot(): ContextCacheInvalidationSnapshot | undefined;
12
13
  setInvalidationSnapshot(snapshot: ContextCacheInvalidationSnapshot): void;
13
14
  readRepresentation(key: string): ContextBudgetRepresentationCacheReadV2 | undefined;
@@ -15,15 +16,18 @@ export declare class MemoryContextBudgetCacheProviderV2 implements ContextBudget
15
16
  readonly key: string;
16
17
  readonly entry: ContextBudgetRepresentationCacheEntryV2;
17
18
  }): void;
19
+ deleteRepresentation(key: string): void;
18
20
  readNegativeRepresentation(key: string): ContextBudgetNegativeCacheEntryV2 | undefined;
19
21
  writeNegativeRepresentation(input: {
20
22
  readonly key: string;
21
23
  readonly reason: string;
22
24
  }): void;
25
+ deleteNegativeRepresentation(key: string): void;
23
26
  readPlan(key: string): ContextBudgetPlanCacheReadV2 | undefined;
24
27
  writePlan(input: {
25
28
  readonly key: string;
26
29
  readonly entry: ContextBudgetPlanCacheEntryV2;
27
30
  }): void;
31
+ deletePlan(key: string): void;
28
32
  }
29
33
  //# sourceMappingURL=context-budget-v2-cache-provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context-budget-v2-cache-provider.d.ts","sourceRoot":"","sources":["../../src/core/context-budget-v2-cache-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,gCAAgC,EAErC,MAAM,2CAA2C,CAAC;AACnD,OAAO,KAAK,EACX,yBAAyB,EACzB,4BAA4B,EAC5B,iCAAiC,EACjC,6BAA6B,EAC7B,4BAA4B,EAC5B,uCAAuC,EACvC,sCAAsC,EACtC,MAAM,8BAA8B,CAAC;AAEtC,wBAAgB,wCAAwC,CACvD,KAAK,GAAE,yBAAkC,GACvC,4BAA4B,CAE9B;AAED,qBAAa,kCAAmC,YAAW,4BAA4B;IACtF,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA8D;IAC9F,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwD;IAClF,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoD;IAC1E,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA4B;IAClD,OAAO,CAAC,oBAAoB,CAA+C;IAE3E,YAAY,KAAK,EAAE,yBAAyB,EAE3C;IAED,uBAAuB,IAAI,gCAAgC,GAAG,SAAS,CAEtE;IAED,uBAAuB,CAAC,QAAQ,EAAE,gCAAgC,GAAG,IAAI,CAaxE;IAED,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,sCAAsC,GAAG,SAAS,CAGlF;IAED,mBAAmB,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,uCAAuC,CAAA;KAAE,GAAG,IAAI,CAElH;IAED,0BAA0B,CAAC,GAAG,EAAE,MAAM,GAAG,iCAAiC,GAAG,SAAS,CAErF;IAED,2BAA2B,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAE1F;IAED,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,4BAA4B,GAAG,SAAS,CAG9D;IAED,SAAS,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,6BAA6B,CAAA;KAAE,GAAG,IAAI,CAE9F;CACD","sourcesContent":["import {\n\ttype ContextCacheInvalidationSnapshot,\n\tcreateContextCacheInvalidationSnapshot,\n} from \"./context-budget-v2-cache-invalidation.ts\";\nimport type {\n\tContextBudgetCacheLayerV2,\n\tContextBudgetCacheProviderV2,\n\tContextBudgetNegativeCacheEntryV2,\n\tContextBudgetPlanCacheEntryV2,\n\tContextBudgetPlanCacheReadV2,\n\tContextBudgetRepresentationCacheEntryV2,\n\tContextBudgetRepresentationCacheReadV2,\n} from \"./context-budget-v2-types.ts\";\n\nexport function createMemoryContextBudgetCacheProviderV2(\n\tlayer: ContextBudgetCacheLayerV2 = \"turn\",\n): ContextBudgetCacheProviderV2 {\n\treturn new MemoryContextBudgetCacheProviderV2(layer);\n}\n\nexport class MemoryContextBudgetCacheProviderV2 implements ContextBudgetCacheProviderV2 {\n\tprivate readonly representations = new Map<string, ContextBudgetRepresentationCacheEntryV2>();\n\tprivate readonly negatives = new Map<string, ContextBudgetNegativeCacheEntryV2>();\n\tprivate readonly plans = new Map<string, ContextBudgetPlanCacheEntryV2>();\n\tprivate readonly layer: ContextBudgetCacheLayerV2;\n\tprivate invalidationSnapshot: ContextCacheInvalidationSnapshot | undefined;\n\n\tconstructor(layer: ContextBudgetCacheLayerV2) {\n\t\tthis.layer = layer;\n\t}\n\n\tgetInvalidationSnapshot(): ContextCacheInvalidationSnapshot | undefined {\n\t\treturn this.invalidationSnapshot;\n\t}\n\n\tsetInvalidationSnapshot(snapshot: ContextCacheInvalidationSnapshot): void {\n\t\tthis.invalidationSnapshot = createContextCacheInvalidationSnapshot({\n\t\t\tforkId: snapshot.forkId,\n\t\t\tworktreeFingerprint: snapshot.worktreeFingerprint,\n\t\t\tactiveModelId: snapshot.activeModelId,\n\t\t\tcompactionModelId: snapshot.compactionModelId,\n\t\t\tglobalEpoch: snapshot.globalEpoch,\n\t\t\ttranscriptRepair: snapshot.counters.transcriptRepair,\n\t\t\ttoolResultDisposition: snapshot.counters.toolResultDisposition,\n\t\t\tevidenceReceipt: snapshot.counters.evidenceReceipt,\n\t\t\tuserSteering: snapshot.counters.userSteering,\n\t\t\tsettings: snapshot.counters.settings,\n\t\t});\n\t}\n\n\treadRepresentation(key: string): ContextBudgetRepresentationCacheReadV2 | undefined {\n\t\tconst entry = this.representations.get(key);\n\t\treturn entry ? { entry, layer: this.layer } : undefined;\n\t}\n\n\twriteRepresentation(input: { readonly key: string; readonly entry: ContextBudgetRepresentationCacheEntryV2 }): void {\n\t\tthis.representations.set(input.key, input.entry);\n\t}\n\n\treadNegativeRepresentation(key: string): ContextBudgetNegativeCacheEntryV2 | undefined {\n\t\treturn this.negatives.get(key);\n\t}\n\n\twriteNegativeRepresentation(input: { readonly key: string; readonly reason: string }): void {\n\t\tthis.negatives.set(input.key, { reason: input.reason, layer: this.layer });\n\t}\n\n\treadPlan(key: string): ContextBudgetPlanCacheReadV2 | undefined {\n\t\tconst entry = this.plans.get(key);\n\t\treturn entry ? { entry, layer: this.layer } : undefined;\n\t}\n\n\twritePlan(input: { readonly key: string; readonly entry: ContextBudgetPlanCacheEntryV2 }): void {\n\t\tthis.plans.set(input.key, input.entry);\n\t}\n}\n"]}
1
+ {"version":3,"file":"context-budget-v2-cache-provider.d.ts","sourceRoot":"","sources":["../../src/core/context-budget-v2-cache-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,gCAAgC,EAErC,MAAM,2CAA2C,CAAC;AACnD,OAAO,KAAK,EACX,yBAAyB,EACzB,4BAA4B,EAC5B,iCAAiC,EACjC,6BAA6B,EAC7B,4BAA4B,EAC5B,uCAAuC,EACvC,sCAAsC,EACtC,MAAM,8BAA8B,CAAC;AAsBtC,wBAAgB,wCAAwC,CACvD,KAAK,GAAE,yBAAkC,GACvC,4BAA4B,CAE9B;AAED,qBAAa,kCAAmC,YAAW,4BAA4B;IACtF,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA8D;IAC9F,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwD;IAClF,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoD;IAC1E,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA4B;IAClD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,oBAAoB,CAA+C;IAE3E,YAAY,KAAK,EAAE,yBAAyB,EAAE,UAAU,SAAgC,EAGvF;IAED,uBAAuB,IAAI,gCAAgC,GAAG,SAAS,CAEtE;IAED,uBAAuB,CAAC,QAAQ,EAAE,gCAAgC,GAAG,IAAI,CAaxE;IAED,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,sCAAsC,GAAG,SAAS,CAGlF;IAED,mBAAmB,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,uCAAuC,CAAA;KAAE,GAAG,IAAI,CAElH;IAED,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEtC;IAED,0BAA0B,CAAC,GAAG,EAAE,MAAM,GAAG,iCAAiC,GAAG,SAAS,CAErF;IAED,2BAA2B,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAO1F;IAED,4BAA4B,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE9C;IAED,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,4BAA4B,GAAG,SAAS,CAG9D;IAED,SAAS,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,6BAA6B,CAAA;KAAE,GAAG,IAAI,CAE9F;IAED,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE5B;CACD","sourcesContent":["import {\n\ttype ContextCacheInvalidationSnapshot,\n\tcreateContextCacheInvalidationSnapshot,\n} from \"./context-budget-v2-cache-invalidation.ts\";\nimport type {\n\tContextBudgetCacheLayerV2,\n\tContextBudgetCacheProviderV2,\n\tContextBudgetNegativeCacheEntryV2,\n\tContextBudgetPlanCacheEntryV2,\n\tContextBudgetPlanCacheReadV2,\n\tContextBudgetRepresentationCacheEntryV2,\n\tContextBudgetRepresentationCacheReadV2,\n} from \"./context-budget-v2-types.ts\";\n\nconst DEFAULT_MAX_ENTRIES_PER_CACHE = 256;\n\nfunction readLru<T>(store: Map<string, T>, key: string): T | undefined {\n\tconst entry = store.get(key);\n\tif (entry === undefined) return undefined;\n\tstore.delete(key);\n\tstore.set(key, entry);\n\treturn entry;\n}\n\nfunction writeLru<T>(store: Map<string, T>, key: string, entry: T, maxEntries: number): void {\n\tstore.delete(key);\n\tstore.set(key, entry);\n\twhile (store.size > maxEntries) {\n\t\tconst oldestKey = store.keys().next().value;\n\t\tif (oldestKey === undefined) return;\n\t\tstore.delete(oldestKey);\n\t}\n}\n\nexport function createMemoryContextBudgetCacheProviderV2(\n\tlayer: ContextBudgetCacheLayerV2 = \"turn\",\n): ContextBudgetCacheProviderV2 {\n\treturn new MemoryContextBudgetCacheProviderV2(layer);\n}\n\nexport class MemoryContextBudgetCacheProviderV2 implements ContextBudgetCacheProviderV2 {\n\tprivate readonly representations = new Map<string, ContextBudgetRepresentationCacheEntryV2>();\n\tprivate readonly negatives = new Map<string, ContextBudgetNegativeCacheEntryV2>();\n\tprivate readonly plans = new Map<string, ContextBudgetPlanCacheEntryV2>();\n\tprivate readonly layer: ContextBudgetCacheLayerV2;\n\tprivate readonly maxEntries: number;\n\tprivate invalidationSnapshot: ContextCacheInvalidationSnapshot | undefined;\n\n\tconstructor(layer: ContextBudgetCacheLayerV2, maxEntries = DEFAULT_MAX_ENTRIES_PER_CACHE) {\n\t\tthis.layer = layer;\n\t\tthis.maxEntries = maxEntries;\n\t}\n\n\tgetInvalidationSnapshot(): ContextCacheInvalidationSnapshot | undefined {\n\t\treturn this.invalidationSnapshot;\n\t}\n\n\tsetInvalidationSnapshot(snapshot: ContextCacheInvalidationSnapshot): void {\n\t\tthis.invalidationSnapshot = createContextCacheInvalidationSnapshot({\n\t\t\tforkId: snapshot.forkId,\n\t\t\tworktreeFingerprint: snapshot.worktreeFingerprint,\n\t\t\tactiveModelId: snapshot.activeModelId,\n\t\t\tcompactionModelId: snapshot.compactionModelId,\n\t\t\tglobalEpoch: snapshot.globalEpoch,\n\t\t\ttranscriptRepair: snapshot.counters.transcriptRepair,\n\t\t\ttoolResultDisposition: snapshot.counters.toolResultDisposition,\n\t\t\tevidenceReceipt: snapshot.counters.evidenceReceipt,\n\t\t\tuserSteering: snapshot.counters.userSteering,\n\t\t\tsettings: snapshot.counters.settings,\n\t\t});\n\t}\n\n\treadRepresentation(key: string): ContextBudgetRepresentationCacheReadV2 | undefined {\n\t\tconst entry = readLru(this.representations, key);\n\t\treturn entry ? { entry, layer: this.layer } : undefined;\n\t}\n\n\twriteRepresentation(input: { readonly key: string; readonly entry: ContextBudgetRepresentationCacheEntryV2 }): void {\n\t\twriteLru(this.representations, input.key, input.entry, this.maxEntries);\n\t}\n\n\tdeleteRepresentation(key: string): void {\n\t\tthis.representations.delete(key);\n\t}\n\n\treadNegativeRepresentation(key: string): ContextBudgetNegativeCacheEntryV2 | undefined {\n\t\treturn readLru(this.negatives, key);\n\t}\n\n\twriteNegativeRepresentation(input: { readonly key: string; readonly reason: string }): void {\n\t\twriteLru(\n\t\t\tthis.negatives,\n\t\t\tinput.key,\n\t\t\t{ reason: input.reason, createdAtEpochMs: Date.now(), layer: this.layer },\n\t\t\tthis.maxEntries,\n\t\t);\n\t}\n\n\tdeleteNegativeRepresentation(key: string): void {\n\t\tthis.negatives.delete(key);\n\t}\n\n\treadPlan(key: string): ContextBudgetPlanCacheReadV2 | undefined {\n\t\tconst entry = readLru(this.plans, key);\n\t\treturn entry ? { entry, layer: this.layer } : undefined;\n\t}\n\n\twritePlan(input: { readonly key: string; readonly entry: ContextBudgetPlanCacheEntryV2 }): void {\n\t\twriteLru(this.plans, input.key, input.entry, this.maxEntries);\n\t}\n\n\tdeletePlan(key: string): void {\n\t\tthis.plans.delete(key);\n\t}\n}\n"]}