@bastani/atomic 0.9.4-alpha.8 → 0.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/dist/builtin/cursor/CHANGELOG.md +6 -0
  3. package/dist/builtin/cursor/package.json +2 -2
  4. package/dist/builtin/intercom/CHANGELOG.md +6 -0
  5. package/dist/builtin/intercom/package.json +1 -1
  6. package/dist/builtin/mcp/CHANGELOG.md +6 -0
  7. package/dist/builtin/mcp/package.json +1 -1
  8. package/dist/builtin/subagents/CHANGELOG.md +34 -0
  9. package/dist/builtin/subagents/agents/code-simplifier.md +2 -2
  10. package/dist/builtin/subagents/agents/codebase-analyzer.md +2 -2
  11. package/dist/builtin/subagents/agents/codebase-locator.md +2 -2
  12. package/dist/builtin/subagents/agents/codebase-online-researcher.md +2 -2
  13. package/dist/builtin/subagents/agents/codebase-pattern-finder.md +2 -2
  14. package/dist/builtin/subagents/agents/codebase-research-analyzer.md +2 -2
  15. package/dist/builtin/subagents/agents/codebase-research-locator.md +2 -2
  16. package/dist/builtin/subagents/agents/debugger.md +1 -1
  17. package/dist/builtin/subagents/agents/worker.md +2 -2
  18. package/dist/builtin/subagents/package.json +1 -1
  19. package/dist/builtin/subagents/src/slash/slash-commands.ts +2 -2
  20. package/dist/builtin/subagents/src/tui/render-result-compact.ts +3 -2
  21. package/dist/builtin/subagents/src/tui/render-result.ts +3 -3
  22. package/dist/builtin/subagents/src/tui/render-widget-graph.ts +4 -3
  23. package/dist/builtin/subagents/src/tui/render-widget.ts +10 -4
  24. package/dist/builtin/web-access/CHANGELOG.md +6 -0
  25. package/dist/builtin/web-access/package.json +1 -1
  26. package/dist/builtin/workflows/CHANGELOG.md +30 -0
  27. package/dist/builtin/workflows/builtin/deep-research-codebase-utils.ts +24 -29
  28. package/dist/builtin/workflows/builtin/goal-runner.ts +13 -37
  29. package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +6 -9
  30. package/dist/builtin/workflows/builtin/ralph-models.ts +58 -115
  31. package/dist/builtin/workflows/package.json +1 -1
  32. package/dist/builtin/workflows/src/tui/keybindings-adapter.ts +4 -0
  33. package/dist/builtin/workflows/src/tui/overlay-adapter.ts +4 -0
  34. package/dist/builtin/workflows/src/tui/stage-chat-view-input.ts +12 -1
  35. package/dist/builtin/workflows/src/tui/stage-chat-view-state.ts +2 -0
  36. package/dist/builtin/workflows/src/tui/stage-chat-view-types.ts +6 -0
  37. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +4 -0
  38. package/dist/builtin/workflows/src/tui/workflow-attach-pane-types.ts +4 -0
  39. package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +8 -9
  40. package/dist/bun/cli.d.ts.map +1 -1
  41. package/dist/bun/cli.js +3 -2
  42. package/dist/bun/cli.js.map +1 -1
  43. package/dist/cli.d.ts.map +1 -1
  44. package/dist/cli.js +15 -5
  45. package/dist/cli.js.map +1 -1
  46. package/dist/config.d.ts +10 -3
  47. package/dist/config.d.ts.map +1 -1
  48. package/dist/config.js +18 -1
  49. package/dist/config.js.map +1 -1
  50. package/dist/core/agent-session-events.d.ts.map +1 -1
  51. package/dist/core/agent-session-events.js +16 -8
  52. package/dist/core/agent-session-events.js.map +1 -1
  53. package/dist/core/agent-session-export.d.ts.map +1 -1
  54. package/dist/core/agent-session-export.js +4 -2
  55. package/dist/core/agent-session-export.js.map +1 -1
  56. package/dist/core/agent-session-extension-bindings.d.ts +3 -1
  57. package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
  58. package/dist/core/agent-session-extension-bindings.js +7 -4
  59. package/dist/core/agent-session-extension-bindings.js.map +1 -1
  60. package/dist/core/agent-session-methods.d.ts +8 -2
  61. package/dist/core/agent-session-methods.d.ts.map +1 -1
  62. package/dist/core/agent-session-methods.js.map +1 -1
  63. package/dist/core/agent-session-retry.d.ts +2 -0
  64. package/dist/core/agent-session-retry.d.ts.map +1 -1
  65. package/dist/core/agent-session-retry.js +66 -7
  66. package/dist/core/agent-session-retry.js.map +1 -1
  67. package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
  68. package/dist/core/agent-session-tool-registry.js +4 -0
  69. package/dist/core/agent-session-tool-registry.js.map +1 -1
  70. package/dist/core/agent-session.d.ts +4 -1
  71. package/dist/core/agent-session.d.ts.map +1 -1
  72. package/dist/core/agent-session.js +4 -0
  73. package/dist/core/agent-session.js.map +1 -1
  74. package/dist/core/async/format.d.ts +3 -0
  75. package/dist/core/async/format.d.ts.map +1 -0
  76. package/dist/core/async/format.js +50 -0
  77. package/dist/core/async/format.js.map +1 -0
  78. package/dist/core/async/job-manager.d.ts +39 -0
  79. package/dist/core/async/job-manager.d.ts.map +1 -0
  80. package/dist/core/async/job-manager.js +254 -0
  81. package/dist/core/async/job-manager.js.map +1 -0
  82. package/dist/core/async/session-manager.d.ts +18 -0
  83. package/dist/core/async/session-manager.d.ts.map +1 -0
  84. package/dist/core/async/session-manager.js +61 -0
  85. package/dist/core/async/session-manager.js.map +1 -0
  86. package/dist/core/async/types.d.ts +23 -0
  87. package/dist/core/async/types.d.ts.map +1 -0
  88. package/dist/core/async/types.js +2 -0
  89. package/dist/core/async/types.js.map +1 -0
  90. package/dist/core/copilot-model-static-fallbacks.d.ts +43 -0
  91. package/dist/core/copilot-model-static-fallbacks.d.ts.map +1 -0
  92. package/dist/core/copilot-model-static-fallbacks.js +50 -0
  93. package/dist/core/copilot-model-static-fallbacks.js.map +1 -0
  94. package/dist/core/extensions/loader-virtual-modules.d.ts +11 -0
  95. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  96. package/dist/core/extensions/loader-virtual-modules.js +79 -11
  97. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  98. package/dist/core/model-registry-builtins.d.ts.map +1 -1
  99. package/dist/core/model-registry-builtins.js +9 -1
  100. package/dist/core/model-registry-builtins.js.map +1 -1
  101. package/dist/core/resource-loader-reload.d.ts.map +1 -1
  102. package/dist/core/resource-loader-reload.js +4 -2
  103. package/dist/core/resource-loader-reload.js.map +1 -1
  104. package/dist/core/resource-loader-types.d.ts +6 -0
  105. package/dist/core/resource-loader-types.d.ts.map +1 -1
  106. package/dist/core/resource-loader-types.js.map +1 -1
  107. package/dist/core/tools/bash-async-execution.d.ts +25 -0
  108. package/dist/core/tools/bash-async-execution.d.ts.map +1 -0
  109. package/dist/core/tools/bash-async-execution.js +71 -0
  110. package/dist/core/tools/bash-async-execution.js.map +1 -0
  111. package/dist/core/tools/bash-async-jobs.d.ts +10 -0
  112. package/dist/core/tools/bash-async-jobs.d.ts.map +1 -1
  113. package/dist/core/tools/bash-async-jobs.js +18 -2
  114. package/dist/core/tools/bash-async-jobs.js.map +1 -1
  115. package/dist/core/tools/bash-async-output.d.ts +3 -1
  116. package/dist/core/tools/bash-async-output.d.ts.map +1 -1
  117. package/dist/core/tools/bash-async-output.js +4 -1
  118. package/dist/core/tools/bash-async-output.js.map +1 -1
  119. package/dist/core/tools/bash-pty-native.d.ts.map +1 -1
  120. package/dist/core/tools/bash-pty-native.js +2 -2
  121. package/dist/core/tools/bash-pty-native.js.map +1 -1
  122. package/dist/core/tools/bash.d.ts +10 -4
  123. package/dist/core/tools/bash.d.ts.map +1 -1
  124. package/dist/core/tools/bash.js +20 -38
  125. package/dist/core/tools/bash.js.map +1 -1
  126. package/dist/core/tools/search-native.d.ts.map +1 -1
  127. package/dist/core/tools/search-native.js +2 -2
  128. package/dist/core/tools/search-native.js.map +1 -1
  129. package/dist/main.d.ts.map +1 -1
  130. package/dist/main.js +56 -32
  131. package/dist/main.js.map +1 -1
  132. package/dist/modes/interactive/interactive-deferred-startup.d.ts +2 -0
  133. package/dist/modes/interactive/interactive-deferred-startup.d.ts.map +1 -0
  134. package/dist/modes/interactive/interactive-deferred-startup.js +59 -0
  135. package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -0
  136. package/dist/modes/interactive/interactive-mode-base.d.ts +2 -0
  137. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  138. package/dist/modes/interactive/interactive-mode-base.js +4 -0
  139. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  140. package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -1
  141. package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
  142. package/dist/modes/interactive/interactive-mode-deps.js +1 -1
  143. package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
  144. package/dist/modes/interactive/interactive-mode-surface.d.ts +2 -0
  145. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  146. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  147. package/dist/modes/interactive/interactive-mode-types.d.ts +2 -0
  148. package/dist/modes/interactive/interactive-mode-types.d.ts.map +1 -1
  149. package/dist/modes/interactive/interactive-mode-types.js.map +1 -1
  150. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  151. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  152. package/dist/modes/interactive/interactive-mode.js +1 -0
  153. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  154. package/dist/modes/interactive/interactive-session-runtime.d.ts.map +1 -1
  155. package/dist/modes/interactive/interactive-session-runtime.js +4 -2
  156. package/dist/modes/interactive/interactive-session-runtime.js.map +1 -1
  157. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  158. package/dist/modes/interactive/interactive-startup.js +11 -1
  159. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  160. package/dist/utils/module-require.d.ts +11 -0
  161. package/dist/utils/module-require.d.ts.map +1 -0
  162. package/dist/utils/module-require.js +16 -0
  163. package/dist/utils/module-require.js.map +1 -0
  164. package/docs/tools.md +4 -2
  165. package/npm-shrinkwrap.json +23 -23
  166. package/package.json +5 -3
@@ -1 +1 @@
1
- {"version":3,"file":"loader-virtual-modules.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/loader-virtual-modules.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAMnD,iBAAe,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAqCnE;AAuBD,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAI1C;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,CAOrE;AAiBD;;;GAGG;AACH,iBAAS,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAkD5C;AAED,kEAAkE;AAClE,eAAO,MAAM,wBAAwB;;;CAGpC,CAAC;AAEF,wBAAsB,mBAAmB,CACvC,aAAa,EAAE,MAAM,EACrB,UAAU,CAAC,EAAE,mBAAmB,GAC/B,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAmBvC","sourcesContent":["import * as fs from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport * as path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { createJiti } from \"jiti/static\";\nimport { isBunBinary } from \"../../config.ts\";\nimport { resolvePath } from \"../../utils/paths.ts\";\nimport type { ExtensionFactory } from \"./types.ts\";\n\nconst require = createRequire(import.meta.url);\nlet _virtualModules: Record<string, object> | null = null;\nlet _virtualModulesPromise: Promise<Record<string, object>> | null = null;\n\nasync function loadVirtualModules(): Promise<Record<string, object>> {\n const [typebox, typeboxCompile, typeboxValue, piAgentCore, piTui, piAi, piAiOauth, piCodingAgent] = await Promise.all([\n import(\"typebox\"),\n import(\"typebox/compile\"),\n import(\"typebox/value\"),\n import(\"@earendil-works/pi-agent-core\"),\n import(\"@earendil-works/pi-tui\"),\n // pi 0.80.2: the old global pi-ai API moved off the root entrypoint onto\n // `/compat` (a strict superset). Extensions still `import ... from\n // \"@earendil-works/pi-ai\"`, so we load the compat module here and key it\n // under the root specifier below to keep every extension working unchanged.\n import(\"@earendil-works/pi-ai/compat\"),\n import(\"@earendil-works/pi-ai/oauth\"),\n // NOTE: This import works because loader.ts exports are NOT re-exported from index.ts,\n // avoiding a circular dependency while preserving the package-name extension import path.\n import(\"../../index.ts\"),\n ]);\n\n return {\n typebox,\n \"typebox/compile\": typeboxCompile,\n \"typebox/value\": typeboxValue,\n \"@sinclair/typebox\": typebox,\n \"@sinclair/typebox/compile\": typeboxCompile,\n \"@sinclair/typebox/value\": typeboxValue,\n \"@earendil-works/pi-agent-core\": piAgentCore,\n \"@earendil-works/pi-tui\": piTui,\n \"@earendil-works/pi-ai\": piAi,\n \"@earendil-works/pi-ai/compat\": piAi,\n \"@earendil-works/pi-ai/oauth\": piAiOauth,\n \"@bastani/atomic\": piCodingAgent,\n \"@mariozechner/pi-agent-core\": piAgentCore,\n \"@mariozechner/pi-tui\": piTui,\n \"@mariozechner/pi-ai\": piAi,\n \"@mariozechner/pi-ai/compat\": piAi,\n \"@mariozechner/pi-ai/oauth\": piAiOauth,\n };\n}\n\n/** Modules available to extensions via virtualModules (for compiled Bun binary). */\nasync function getVirtualModules(): Promise<Record<string, object>> {\n if (_virtualModules) return _virtualModules;\n _virtualModulesPromise ??= loadVirtualModules().then(\n (virtualModules) => {\n _virtualModules = virtualModules;\n return virtualModules;\n },\n (error: Error) => {\n _virtualModulesPromise = null;\n throw error;\n },\n );\n return _virtualModulesPromise;\n}\nlet _aliases: Record<string, string> | null = null;\n\nlet extensionCacheCwd: string | undefined;\nlet extensionCacheGeneration = 0;\nconst extensionCache = new Map<string, ExtensionFactory>();\n\nexport interface ExtensionCacheToken {\n cwd: string;\n generation: number;\n}\n\nexport function clearExtensionCache(): void {\n extensionCache.clear();\n extensionCacheCwd = undefined;\n extensionCacheGeneration++;\n}\n\nexport function useExtensionCacheCwd(cwd: string): ExtensionCacheToken {\n const resolvedCwd = resolvePath(cwd);\n if (extensionCacheCwd !== undefined && extensionCacheCwd !== resolvedCwd) {\n clearExtensionCache();\n }\n extensionCacheCwd = resolvedCwd;\n return { cwd: resolvedCwd, generation: extensionCacheGeneration };\n}\n\nfunction isCurrentCacheToken(cacheToken: ExtensionCacheToken | undefined): cacheToken is ExtensionCacheToken {\n return (\n cacheToken !== undefined &&\n extensionCacheCwd === cacheToken.cwd &&\n extensionCacheGeneration === cacheToken.generation\n );\n}\n\nfunction extensionImportSpecifier(extensionPath: string, cacheToken: ExtensionCacheToken | undefined): string {\n const url = pathToFileURL(extensionPath);\n const cacheKey = cacheToken ? `${cacheToken.generation}:${cacheToken.cwd}` : `${Date.now()}:${Math.random()}`;\n url.searchParams.set(\"atomicExtensionCache\", cacheKey);\n return url.href;\n}\n\n/**\n * Get aliases for jiti (used in Node.js/development mode).\n * In Bun binary mode, virtualModules is used instead.\n */\nfunction getAliases(): Record<string, string> {\n if (_aliases) return _aliases;\n\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n const packageIndex = path.resolve(__dirname, \"../..\", \"index.js\");\n\n const typeboxEntry = require.resolve(\"typebox\");\n const typeboxCompileEntry = require.resolve(\"typebox/compile\");\n const typeboxValueEntry = require.resolve(\"typebox/value\");\n\n const packagesRoot = path.resolve(__dirname, \"../../../../\");\n const resolveWorkspaceOrImport = (workspaceRelativePath: string, specifier: string): string => {\n const workspacePath = path.join(packagesRoot, workspaceRelativePath);\n if (fs.existsSync(workspacePath)) {\n return workspacePath;\n }\n return fileURLToPath(import.meta.resolve(specifier));\n };\n\n const piCodingAgentEntry = packageIndex;\n const piAgentCoreEntry = resolveWorkspaceOrImport(\"agent/dist/index.js\", \"@earendil-works/pi-agent-core\");\n const piTuiEntry = resolveWorkspaceOrImport(\"tui/dist/index.js\", \"@earendil-works/pi-tui\");\n // The workspace path mirrors pi-ai 0.80.x's built compat export. If an\n // upstream layout change moves that file, fall back to package export\n // resolution so installed Atomic builds still load the canonical entrypoint.\n const piAiEntry = resolveWorkspaceOrImport(\"ai/dist/compat.js\", \"@earendil-works/pi-ai/compat\");\n const piAiOauthEntry = resolveWorkspaceOrImport(\"ai/dist/oauth.js\", \"@earendil-works/pi-ai/oauth\");\n\n _aliases = {\n \"@bastani/atomic\": piCodingAgentEntry,\n \"@earendil-works/pi-coding-agent\": piCodingAgentEntry,\n \"@earendil-works/pi-agent-core\": piAgentCoreEntry,\n \"@earendil-works/pi-tui\": piTuiEntry,\n \"@earendil-works/pi-ai\": piAiEntry,\n \"@earendil-works/pi-ai/compat\": piAiEntry,\n \"@earendil-works/pi-ai/oauth\": piAiOauthEntry,\n \"@mariozechner/pi-agent-core\": piAgentCoreEntry,\n \"@mariozechner/pi-tui\": piTuiEntry,\n \"@mariozechner/pi-ai\": piAiEntry,\n \"@mariozechner/pi-ai/compat\": piAiEntry,\n \"@mariozechner/pi-ai/oauth\": piAiOauthEntry,\n typebox: typeboxEntry,\n \"typebox/compile\": typeboxCompileEntry,\n \"typebox/value\": typeboxValueEntry,\n \"@sinclair/typebox\": typeboxEntry,\n \"@sinclair/typebox/compile\": typeboxCompileEntry,\n \"@sinclair/typebox/value\": typeboxValueEntry,\n };\n\n return _aliases;\n}\n\n/** Internal hooks for extension-loader alias regression tests. */\nexport const extensionLoaderTestHooks = {\n loadVirtualModules,\n getAliases,\n};\n\nexport async function loadExtensionModule(\n extensionPath: string,\n cacheToken?: ExtensionCacheToken,\n): Promise<ExtensionFactory | undefined> {\n if (isCurrentCacheToken(cacheToken)) {\n const cachedFactory = extensionCache.get(extensionPath);\n if (cachedFactory) return cachedFactory;\n }\n\n const forceTransformedImports = isBunBinary || process.platform === \"win32\";\n const jiti = createJiti(import.meta.url, {\n moduleCache: false,\n ...(forceTransformedImports ? { fsCache: false, tryNative: false } : {}),\n ...(isBunBinary ? { virtualModules: await getVirtualModules() } : { alias: getAliases() }),\n });\n const module = await jiti.import(extensionImportSpecifier(extensionPath, cacheToken), { default: true });\n const factory = module as ExtensionFactory;\n if (typeof factory !== \"function\") return undefined;\n if (isCurrentCacheToken(cacheToken)) {\n extensionCache.set(extensionPath, factory);\n }\n return factory;\n}\n"]}
1
+ {"version":3,"file":"loader-virtual-modules.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/loader-virtual-modules.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAMnD,iBAAe,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAqCnE;AAoDD,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAI1C;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,CAOrE;AAiBD;;;;;;;;GAQG;AACH,iBAAS,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAQ5E;AAED;;;GAGG;AACH,iBAAS,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAoD5C;AAED,kEAAkE;AAClE,eAAO,MAAM,wBAAwB;;;;CAIpC,CAAC;AAUF,wBAAsB,mBAAmB,CACvC,aAAa,EAAE,MAAM,EACrB,UAAU,CAAC,EAAE,mBAAmB,GAC/B,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAmCvC","sourcesContent":["import * as fs from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport * as path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { createJiti } from \"jiti/static\";\nimport { getExtensionTranspileCacheDir, isBunBinary, isBundledBuild } from \"../../config.ts\";\nimport { resolvePath } from \"../../utils/paths.ts\";\nimport type { ExtensionFactory } from \"./types.ts\";\n\nconst require = createRequire(import.meta.url);\nlet _virtualModules: Record<string, object> | null = null;\nlet _virtualModulesPromise: Promise<Record<string, object>> | null = null;\n\nasync function loadVirtualModules(): Promise<Record<string, object>> {\n const [typebox, typeboxCompile, typeboxValue, piAgentCore, piTui, piAi, piAiOauth, piCodingAgent] = await Promise.all([\n import(\"typebox\"),\n import(\"typebox/compile\"),\n import(\"typebox/value\"),\n import(\"@earendil-works/pi-agent-core\"),\n import(\"@earendil-works/pi-tui\"),\n // pi 0.80.2: the old global pi-ai API moved off the root entrypoint onto\n // `/compat` (a strict superset). Extensions still `import ... from\n // \"@earendil-works/pi-ai\"`, so we load the compat module here and key it\n // under the root specifier below to keep every extension working unchanged.\n import(\"@earendil-works/pi-ai/compat\"),\n import(\"@earendil-works/pi-ai/oauth\"),\n // NOTE: This import works because loader.ts exports are NOT re-exported from index.ts,\n // avoiding a circular dependency while preserving the package-name extension import path.\n import(\"../../index.ts\"),\n ]);\n\n return {\n typebox,\n \"typebox/compile\": typeboxCompile,\n \"typebox/value\": typeboxValue,\n \"@sinclair/typebox\": typebox,\n \"@sinclair/typebox/compile\": typeboxCompile,\n \"@sinclair/typebox/value\": typeboxValue,\n \"@earendil-works/pi-agent-core\": piAgentCore,\n \"@earendil-works/pi-tui\": piTui,\n \"@earendil-works/pi-ai\": piAi,\n \"@earendil-works/pi-ai/compat\": piAi,\n \"@earendil-works/pi-ai/oauth\": piAiOauth,\n \"@bastani/atomic\": piCodingAgent,\n \"@mariozechner/pi-agent-core\": piAgentCore,\n \"@mariozechner/pi-tui\": piTui,\n \"@mariozechner/pi-ai\": piAi,\n \"@mariozechner/pi-ai/compat\": piAi,\n \"@mariozechner/pi-ai/oauth\": piAiOauth,\n };\n}\n\n/** Modules available to extensions via virtualModules (for compiled Bun binary). */\nasync function getVirtualModules(): Promise<Record<string, object>> {\n if (_virtualModules) return _virtualModules;\n _virtualModulesPromise ??= loadVirtualModules().then(\n (virtualModules) => {\n _virtualModules = virtualModules;\n return virtualModules;\n },\n (error: Error) => {\n _virtualModulesPromise = null;\n throw error;\n },\n );\n return _virtualModulesPromise;\n}\nlet _aliases: Record<string, string> | null = null;\nlet _transpileCacheDir: string | null = null;\n\n/**\n * Persistent on-disk cache for jiti-transpiled extension modules.\n * jiti keys cache entries by source-content hash, so entries self-invalidate\n * when extension sources change; stale sibling version dirs are pruned\n * in the background.\n */\nfunction getTranspileCacheDir(): string {\n if (_transpileCacheDir) return _transpileCacheDir;\n _transpileCacheDir = getExtensionTranspileCacheDir();\n pruneStaleTranspileCaches(_transpileCacheDir);\n return _transpileCacheDir;\n}\n\nfunction pruneStaleTranspileCaches(currentDir: string): void {\n const parent = path.dirname(currentDir);\n const keep = path.basename(currentDir);\n void fs.promises\n .readdir(parent)\n .then((entries) =>\n Promise.all(\n entries\n .filter((entry) => entry !== keep)\n .map((entry) => fs.promises.rm(path.join(parent, entry), { recursive: true, force: true })),\n ),\n )\n .catch(() => {});\n}\n\nlet extensionCacheCwd: string | undefined;\nlet extensionCacheGeneration = 0;\nconst extensionCache = new Map<string, ExtensionFactory>();\n\nexport interface ExtensionCacheToken {\n cwd: string;\n generation: number;\n}\n\nexport function clearExtensionCache(): void {\n extensionCache.clear();\n extensionCacheCwd = undefined;\n extensionCacheGeneration++;\n}\n\nexport function useExtensionCacheCwd(cwd: string): ExtensionCacheToken {\n const resolvedCwd = resolvePath(cwd);\n if (extensionCacheCwd !== undefined && extensionCacheCwd !== resolvedCwd) {\n clearExtensionCache();\n }\n extensionCacheCwd = resolvedCwd;\n return { cwd: resolvedCwd, generation: extensionCacheGeneration };\n}\n\nfunction isCurrentCacheToken(cacheToken: ExtensionCacheToken | undefined): cacheToken is ExtensionCacheToken {\n return (\n cacheToken !== undefined &&\n extensionCacheCwd === cacheToken.cwd &&\n extensionCacheGeneration === cacheToken.generation\n );\n}\n\nfunction extensionImportSpecifier(extensionPath: string, cacheToken: ExtensionCacheToken | undefined): string {\n const url = pathToFileURL(extensionPath);\n const cacheKey = cacheToken ? `${cacheToken.generation}:${cacheToken.cwd}` : `${Date.now()}:${Math.random()}`;\n url.searchParams.set(\"atomicExtensionCache\", cacheKey);\n return url.href;\n}\n\n/**\n * Locate an installed package's root directory without consulting its\n * \"exports\" map: require.resolve(\"<pkg>/package.json\") throws\n * ERR_PACKAGE_PATH_NOT_EXPORTED under Node for packages that do not export\n * \"./package.json\" (pi-ai does not), and import.meta.resolve() cannot be\n * used because its mere presence silently disables bytecode generation for\n * the compiled binary (CJS bundle). Scanning require.resolve.paths() walks\n * the same node_modules chain Node would, without exports-map encapsulation.\n */\nfunction findPackageRoot(packageName: string, searchPaths?: string[]): string {\n for (const base of searchPaths ?? require.resolve.paths(packageName) ?? []) {\n const candidate = path.join(base, packageName);\n if (fs.existsSync(path.join(candidate, \"package.json\"))) {\n return candidate;\n }\n }\n throw new Error(`Cannot locate package directory for \"${packageName}\"`);\n}\n\n/**\n * Get aliases for jiti (used in Node.js/development mode).\n * In Bun binary mode, virtualModules is used instead.\n */\nfunction getAliases(): Record<string, string> {\n if (_aliases) return _aliases;\n\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n const packageIndex = path.resolve(__dirname, \"../..\", \"index.js\");\n\n const typeboxEntry = require.resolve(\"typebox\");\n const typeboxCompileEntry = require.resolve(\"typebox/compile\");\n const typeboxValueEntry = require.resolve(\"typebox/value\");\n\n const packagesRoot = path.resolve(__dirname, \"../../../../\");\n const resolveWorkspaceOrImport = (workspaceRelativePath: string, packageName: string): string => {\n const workspacePath = path.join(packagesRoot, workspaceRelativePath);\n if (fs.existsSync(workspacePath)) {\n return workspacePath;\n }\n const packageRoot = findPackageRoot(packageName);\n const entryRelativePath = workspaceRelativePath.split(\"/\").slice(1).join(\"/\");\n return path.join(packageRoot, entryRelativePath);\n };\n\n const piCodingAgentEntry = packageIndex;\n const piAgentCoreEntry = resolveWorkspaceOrImport(\"agent/dist/index.js\", \"@earendil-works/pi-agent-core\");\n const piTuiEntry = resolveWorkspaceOrImport(\"tui/dist/index.js\", \"@earendil-works/pi-tui\");\n // The workspace path mirrors pi-ai 0.80.x's built dist layout. If an\n // upstream layout change moves these files, this join needs updating to\n // match the package's real dist paths.\n const piAiEntry = resolveWorkspaceOrImport(\"ai/dist/compat.js\", \"@earendil-works/pi-ai\");\n const piAiOauthEntry = resolveWorkspaceOrImport(\"ai/dist/oauth.js\", \"@earendil-works/pi-ai\");\n\n _aliases = {\n \"@bastani/atomic\": piCodingAgentEntry,\n \"@earendil-works/pi-coding-agent\": piCodingAgentEntry,\n \"@earendil-works/pi-agent-core\": piAgentCoreEntry,\n \"@earendil-works/pi-tui\": piTuiEntry,\n \"@earendil-works/pi-ai\": piAiEntry,\n \"@earendil-works/pi-ai/compat\": piAiEntry,\n \"@earendil-works/pi-ai/oauth\": piAiOauthEntry,\n \"@mariozechner/pi-agent-core\": piAgentCoreEntry,\n \"@mariozechner/pi-tui\": piTuiEntry,\n \"@mariozechner/pi-ai\": piAiEntry,\n \"@mariozechner/pi-ai/compat\": piAiEntry,\n \"@mariozechner/pi-ai/oauth\": piAiOauthEntry,\n typebox: typeboxEntry,\n \"typebox/compile\": typeboxCompileEntry,\n \"typebox/value\": typeboxValueEntry,\n \"@sinclair/typebox\": typeboxEntry,\n \"@sinclair/typebox/compile\": typeboxCompileEntry,\n \"@sinclair/typebox/value\": typeboxValueEntry,\n };\n\n return _aliases;\n}\n\n/** Internal hooks for extension-loader alias regression tests. */\nexport const extensionLoaderTestHooks = {\n loadVirtualModules,\n getAliases,\n findPackageRoot,\n};\n\n/**\n * Extension paths already evaluated via native import() in this process. Bun on\n * Windows ignores the cache-busting query on file URLs, so re-loads of these\n * paths (e.g. /reload) must go through jiti's transformed-import path to get a\n * fresh module evaluation.\n */\nconst nativelyImportedPaths = new Set<string>();\n\nexport async function loadExtensionModule(\n extensionPath: string,\n cacheToken?: ExtensionCacheToken,\n): Promise<ExtensionFactory | undefined> {\n if (isCurrentCacheToken(cacheToken)) {\n const cachedFactory = extensionCache.get(extensionPath);\n if (cachedFactory) return cachedFactory;\n }\n\n const isWindows = process.platform === \"win32\";\n // Single-file builds (compiled binary or dev bundle) cannot alias host\n // package specifiers to files on disk: extensions must share the live\n // module instances baked into the build, so virtualModules is used instead\n // (which requires jiti's transformed-import path).\n const isSingleFileBuild = isBunBinary || isBundledBuild;\n // Windows first-load fast path: native import() (jiti's default tryNative)\n // skips per-launch transpilation of the extension module graph. Re-loads of\n // the same path fall back to transformed imports for fresh evaluation.\n const forceTransformedImports = isSingleFileBuild || (isWindows && nativelyImportedPaths.has(extensionPath));\n const jiti = createJiti(import.meta.url, {\n moduleCache: false,\n ...(forceTransformedImports\n ? { fsCache: getTranspileCacheDir(), tryNative: false }\n : isWindows\n ? { fsCache: getTranspileCacheDir() }\n : {}),\n ...(isSingleFileBuild ? { virtualModules: await getVirtualModules() } : { alias: getAliases() }),\n });\n const module = await jiti.import(extensionImportSpecifier(extensionPath, cacheToken), { default: true });\n if (isWindows && !forceTransformedImports) {\n nativelyImportedPaths.add(extensionPath);\n }\n const factory = module as ExtensionFactory;\n if (typeof factory !== \"function\") return undefined;\n if (isCurrentCacheToken(cacheToken)) {\n extensionCache.set(extensionPath, factory);\n }\n return factory;\n}\n"]}
@@ -3,7 +3,7 @@ import { createRequire } from "node:module";
3
3
  import * as path from "node:path";
4
4
  import { fileURLToPath, pathToFileURL } from "node:url";
5
5
  import { createJiti } from "jiti/static";
6
- import { isBunBinary } from "../../config.js";
6
+ import { getExtensionTranspileCacheDir, isBunBinary, isBundledBuild } from "../../config.js";
7
7
  import { resolvePath } from "../../utils/paths.js";
8
8
  const require = createRequire(import.meta.url);
9
9
  let _virtualModules = null;
@@ -59,6 +59,30 @@ async function getVirtualModules() {
59
59
  return _virtualModulesPromise;
60
60
  }
61
61
  let _aliases = null;
62
+ let _transpileCacheDir = null;
63
+ /**
64
+ * Persistent on-disk cache for jiti-transpiled extension modules.
65
+ * jiti keys cache entries by source-content hash, so entries self-invalidate
66
+ * when extension sources change; stale sibling version dirs are pruned
67
+ * in the background.
68
+ */
69
+ function getTranspileCacheDir() {
70
+ if (_transpileCacheDir)
71
+ return _transpileCacheDir;
72
+ _transpileCacheDir = getExtensionTranspileCacheDir();
73
+ pruneStaleTranspileCaches(_transpileCacheDir);
74
+ return _transpileCacheDir;
75
+ }
76
+ function pruneStaleTranspileCaches(currentDir) {
77
+ const parent = path.dirname(currentDir);
78
+ const keep = path.basename(currentDir);
79
+ void fs.promises
80
+ .readdir(parent)
81
+ .then((entries) => Promise.all(entries
82
+ .filter((entry) => entry !== keep)
83
+ .map((entry) => fs.promises.rm(path.join(parent, entry), { recursive: true, force: true }))))
84
+ .catch(() => { });
85
+ }
62
86
  let extensionCacheCwd;
63
87
  let extensionCacheGeneration = 0;
64
88
  const extensionCache = new Map();
@@ -86,6 +110,24 @@ function extensionImportSpecifier(extensionPath, cacheToken) {
86
110
  url.searchParams.set("atomicExtensionCache", cacheKey);
87
111
  return url.href;
88
112
  }
113
+ /**
114
+ * Locate an installed package's root directory without consulting its
115
+ * "exports" map: require.resolve("<pkg>/package.json") throws
116
+ * ERR_PACKAGE_PATH_NOT_EXPORTED under Node for packages that do not export
117
+ * "./package.json" (pi-ai does not), and import.meta.resolve() cannot be
118
+ * used because its mere presence silently disables bytecode generation for
119
+ * the compiled binary (CJS bundle). Scanning require.resolve.paths() walks
120
+ * the same node_modules chain Node would, without exports-map encapsulation.
121
+ */
122
+ function findPackageRoot(packageName, searchPaths) {
123
+ for (const base of searchPaths ?? require.resolve.paths(packageName) ?? []) {
124
+ const candidate = path.join(base, packageName);
125
+ if (fs.existsSync(path.join(candidate, "package.json"))) {
126
+ return candidate;
127
+ }
128
+ }
129
+ throw new Error(`Cannot locate package directory for "${packageName}"`);
130
+ }
89
131
  /**
90
132
  * Get aliases for jiti (used in Node.js/development mode).
91
133
  * In Bun binary mode, virtualModules is used instead.
@@ -99,21 +141,23 @@ function getAliases() {
99
141
  const typeboxCompileEntry = require.resolve("typebox/compile");
100
142
  const typeboxValueEntry = require.resolve("typebox/value");
101
143
  const packagesRoot = path.resolve(__dirname, "../../../../");
102
- const resolveWorkspaceOrImport = (workspaceRelativePath, specifier) => {
144
+ const resolveWorkspaceOrImport = (workspaceRelativePath, packageName) => {
103
145
  const workspacePath = path.join(packagesRoot, workspaceRelativePath);
104
146
  if (fs.existsSync(workspacePath)) {
105
147
  return workspacePath;
106
148
  }
107
- return fileURLToPath(import.meta.resolve(specifier));
149
+ const packageRoot = findPackageRoot(packageName);
150
+ const entryRelativePath = workspaceRelativePath.split("/").slice(1).join("/");
151
+ return path.join(packageRoot, entryRelativePath);
108
152
  };
109
153
  const piCodingAgentEntry = packageIndex;
110
154
  const piAgentCoreEntry = resolveWorkspaceOrImport("agent/dist/index.js", "@earendil-works/pi-agent-core");
111
155
  const piTuiEntry = resolveWorkspaceOrImport("tui/dist/index.js", "@earendil-works/pi-tui");
112
- // The workspace path mirrors pi-ai 0.80.x's built compat export. If an
113
- // upstream layout change moves that file, fall back to package export
114
- // resolution so installed Atomic builds still load the canonical entrypoint.
115
- const piAiEntry = resolveWorkspaceOrImport("ai/dist/compat.js", "@earendil-works/pi-ai/compat");
116
- const piAiOauthEntry = resolveWorkspaceOrImport("ai/dist/oauth.js", "@earendil-works/pi-ai/oauth");
156
+ // The workspace path mirrors pi-ai 0.80.x's built dist layout. If an
157
+ // upstream layout change moves these files, this join needs updating to
158
+ // match the package's real dist paths.
159
+ const piAiEntry = resolveWorkspaceOrImport("ai/dist/compat.js", "@earendil-works/pi-ai");
160
+ const piAiOauthEntry = resolveWorkspaceOrImport("ai/dist/oauth.js", "@earendil-works/pi-ai");
117
161
  _aliases = {
118
162
  "@bastani/atomic": piCodingAgentEntry,
119
163
  "@earendil-works/pi-coding-agent": piCodingAgentEntry,
@@ -140,20 +184,44 @@ function getAliases() {
140
184
  export const extensionLoaderTestHooks = {
141
185
  loadVirtualModules,
142
186
  getAliases,
187
+ findPackageRoot,
143
188
  };
189
+ /**
190
+ * Extension paths already evaluated via native import() in this process. Bun on
191
+ * Windows ignores the cache-busting query on file URLs, so re-loads of these
192
+ * paths (e.g. /reload) must go through jiti's transformed-import path to get a
193
+ * fresh module evaluation.
194
+ */
195
+ const nativelyImportedPaths = new Set();
144
196
  export async function loadExtensionModule(extensionPath, cacheToken) {
145
197
  if (isCurrentCacheToken(cacheToken)) {
146
198
  const cachedFactory = extensionCache.get(extensionPath);
147
199
  if (cachedFactory)
148
200
  return cachedFactory;
149
201
  }
150
- const forceTransformedImports = isBunBinary || process.platform === "win32";
202
+ const isWindows = process.platform === "win32";
203
+ // Single-file builds (compiled binary or dev bundle) cannot alias host
204
+ // package specifiers to files on disk: extensions must share the live
205
+ // module instances baked into the build, so virtualModules is used instead
206
+ // (which requires jiti's transformed-import path).
207
+ const isSingleFileBuild = isBunBinary || isBundledBuild;
208
+ // Windows first-load fast path: native import() (jiti's default tryNative)
209
+ // skips per-launch transpilation of the extension module graph. Re-loads of
210
+ // the same path fall back to transformed imports for fresh evaluation.
211
+ const forceTransformedImports = isSingleFileBuild || (isWindows && nativelyImportedPaths.has(extensionPath));
151
212
  const jiti = createJiti(import.meta.url, {
152
213
  moduleCache: false,
153
- ...(forceTransformedImports ? { fsCache: false, tryNative: false } : {}),
154
- ...(isBunBinary ? { virtualModules: await getVirtualModules() } : { alias: getAliases() }),
214
+ ...(forceTransformedImports
215
+ ? { fsCache: getTranspileCacheDir(), tryNative: false }
216
+ : isWindows
217
+ ? { fsCache: getTranspileCacheDir() }
218
+ : {}),
219
+ ...(isSingleFileBuild ? { virtualModules: await getVirtualModules() } : { alias: getAliases() }),
155
220
  });
156
221
  const module = await jiti.import(extensionImportSpecifier(extensionPath, cacheToken), { default: true });
222
+ if (isWindows && !forceTransformedImports) {
223
+ nativelyImportedPaths.add(extensionPath);
224
+ }
157
225
  const factory = module;
158
226
  if (typeof factory !== "function")
159
227
  return undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"loader-virtual-modules.js","sourceRoot":"","sources":["../../../src/core/extensions/loader-virtual-modules.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport * as path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { createJiti } from \"jiti/static\";\nimport { isBunBinary } from \"../../config.ts\";\nimport { resolvePath } from \"../../utils/paths.ts\";\nimport type { ExtensionFactory } from \"./types.ts\";\n\nconst require = createRequire(import.meta.url);\nlet _virtualModules: Record<string, object> | null = null;\nlet _virtualModulesPromise: Promise<Record<string, object>> | null = null;\n\nasync function loadVirtualModules(): Promise<Record<string, object>> {\n const [typebox, typeboxCompile, typeboxValue, piAgentCore, piTui, piAi, piAiOauth, piCodingAgent] = await Promise.all([\n import(\"typebox\"),\n import(\"typebox/compile\"),\n import(\"typebox/value\"),\n import(\"@earendil-works/pi-agent-core\"),\n import(\"@earendil-works/pi-tui\"),\n // pi 0.80.2: the old global pi-ai API moved off the root entrypoint onto\n // `/compat` (a strict superset). Extensions still `import ... from\n // \"@earendil-works/pi-ai\"`, so we load the compat module here and key it\n // under the root specifier below to keep every extension working unchanged.\n import(\"@earendil-works/pi-ai/compat\"),\n import(\"@earendil-works/pi-ai/oauth\"),\n // NOTE: This import works because loader.ts exports are NOT re-exported from index.ts,\n // avoiding a circular dependency while preserving the package-name extension import path.\n import(\"../../index.ts\"),\n ]);\n\n return {\n typebox,\n \"typebox/compile\": typeboxCompile,\n \"typebox/value\": typeboxValue,\n \"@sinclair/typebox\": typebox,\n \"@sinclair/typebox/compile\": typeboxCompile,\n \"@sinclair/typebox/value\": typeboxValue,\n \"@earendil-works/pi-agent-core\": piAgentCore,\n \"@earendil-works/pi-tui\": piTui,\n \"@earendil-works/pi-ai\": piAi,\n \"@earendil-works/pi-ai/compat\": piAi,\n \"@earendil-works/pi-ai/oauth\": piAiOauth,\n \"@bastani/atomic\": piCodingAgent,\n \"@mariozechner/pi-agent-core\": piAgentCore,\n \"@mariozechner/pi-tui\": piTui,\n \"@mariozechner/pi-ai\": piAi,\n \"@mariozechner/pi-ai/compat\": piAi,\n \"@mariozechner/pi-ai/oauth\": piAiOauth,\n };\n}\n\n/** Modules available to extensions via virtualModules (for compiled Bun binary). */\nasync function getVirtualModules(): Promise<Record<string, object>> {\n if (_virtualModules) return _virtualModules;\n _virtualModulesPromise ??= loadVirtualModules().then(\n (virtualModules) => {\n _virtualModules = virtualModules;\n return virtualModules;\n },\n (error: Error) => {\n _virtualModulesPromise = null;\n throw error;\n },\n );\n return _virtualModulesPromise;\n}\nlet _aliases: Record<string, string> | null = null;\n\nlet extensionCacheCwd: string | undefined;\nlet extensionCacheGeneration = 0;\nconst extensionCache = new Map<string, ExtensionFactory>();\n\nexport interface ExtensionCacheToken {\n cwd: string;\n generation: number;\n}\n\nexport function clearExtensionCache(): void {\n extensionCache.clear();\n extensionCacheCwd = undefined;\n extensionCacheGeneration++;\n}\n\nexport function useExtensionCacheCwd(cwd: string): ExtensionCacheToken {\n const resolvedCwd = resolvePath(cwd);\n if (extensionCacheCwd !== undefined && extensionCacheCwd !== resolvedCwd) {\n clearExtensionCache();\n }\n extensionCacheCwd = resolvedCwd;\n return { cwd: resolvedCwd, generation: extensionCacheGeneration };\n}\n\nfunction isCurrentCacheToken(cacheToken: ExtensionCacheToken | undefined): cacheToken is ExtensionCacheToken {\n return (\n cacheToken !== undefined &&\n extensionCacheCwd === cacheToken.cwd &&\n extensionCacheGeneration === cacheToken.generation\n );\n}\n\nfunction extensionImportSpecifier(extensionPath: string, cacheToken: ExtensionCacheToken | undefined): string {\n const url = pathToFileURL(extensionPath);\n const cacheKey = cacheToken ? `${cacheToken.generation}:${cacheToken.cwd}` : `${Date.now()}:${Math.random()}`;\n url.searchParams.set(\"atomicExtensionCache\", cacheKey);\n return url.href;\n}\n\n/**\n * Get aliases for jiti (used in Node.js/development mode).\n * In Bun binary mode, virtualModules is used instead.\n */\nfunction getAliases(): Record<string, string> {\n if (_aliases) return _aliases;\n\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n const packageIndex = path.resolve(__dirname, \"../..\", \"index.js\");\n\n const typeboxEntry = require.resolve(\"typebox\");\n const typeboxCompileEntry = require.resolve(\"typebox/compile\");\n const typeboxValueEntry = require.resolve(\"typebox/value\");\n\n const packagesRoot = path.resolve(__dirname, \"../../../../\");\n const resolveWorkspaceOrImport = (workspaceRelativePath: string, specifier: string): string => {\n const workspacePath = path.join(packagesRoot, workspaceRelativePath);\n if (fs.existsSync(workspacePath)) {\n return workspacePath;\n }\n return fileURLToPath(import.meta.resolve(specifier));\n };\n\n const piCodingAgentEntry = packageIndex;\n const piAgentCoreEntry = resolveWorkspaceOrImport(\"agent/dist/index.js\", \"@earendil-works/pi-agent-core\");\n const piTuiEntry = resolveWorkspaceOrImport(\"tui/dist/index.js\", \"@earendil-works/pi-tui\");\n // The workspace path mirrors pi-ai 0.80.x's built compat export. If an\n // upstream layout change moves that file, fall back to package export\n // resolution so installed Atomic builds still load the canonical entrypoint.\n const piAiEntry = resolveWorkspaceOrImport(\"ai/dist/compat.js\", \"@earendil-works/pi-ai/compat\");\n const piAiOauthEntry = resolveWorkspaceOrImport(\"ai/dist/oauth.js\", \"@earendil-works/pi-ai/oauth\");\n\n _aliases = {\n \"@bastani/atomic\": piCodingAgentEntry,\n \"@earendil-works/pi-coding-agent\": piCodingAgentEntry,\n \"@earendil-works/pi-agent-core\": piAgentCoreEntry,\n \"@earendil-works/pi-tui\": piTuiEntry,\n \"@earendil-works/pi-ai\": piAiEntry,\n \"@earendil-works/pi-ai/compat\": piAiEntry,\n \"@earendil-works/pi-ai/oauth\": piAiOauthEntry,\n \"@mariozechner/pi-agent-core\": piAgentCoreEntry,\n \"@mariozechner/pi-tui\": piTuiEntry,\n \"@mariozechner/pi-ai\": piAiEntry,\n \"@mariozechner/pi-ai/compat\": piAiEntry,\n \"@mariozechner/pi-ai/oauth\": piAiOauthEntry,\n typebox: typeboxEntry,\n \"typebox/compile\": typeboxCompileEntry,\n \"typebox/value\": typeboxValueEntry,\n \"@sinclair/typebox\": typeboxEntry,\n \"@sinclair/typebox/compile\": typeboxCompileEntry,\n \"@sinclair/typebox/value\": typeboxValueEntry,\n };\n\n return _aliases;\n}\n\n/** Internal hooks for extension-loader alias regression tests. */\nexport const extensionLoaderTestHooks = {\n loadVirtualModules,\n getAliases,\n};\n\nexport async function loadExtensionModule(\n extensionPath: string,\n cacheToken?: ExtensionCacheToken,\n): Promise<ExtensionFactory | undefined> {\n if (isCurrentCacheToken(cacheToken)) {\n const cachedFactory = extensionCache.get(extensionPath);\n if (cachedFactory) return cachedFactory;\n }\n\n const forceTransformedImports = isBunBinary || process.platform === \"win32\";\n const jiti = createJiti(import.meta.url, {\n moduleCache: false,\n ...(forceTransformedImports ? { fsCache: false, tryNative: false } : {}),\n ...(isBunBinary ? { virtualModules: await getVirtualModules() } : { alias: getAliases() }),\n });\n const module = await jiti.import(extensionImportSpecifier(extensionPath, cacheToken), { default: true });\n const factory = module as ExtensionFactory;\n if (typeof factory !== \"function\") return undefined;\n if (isCurrentCacheToken(cacheToken)) {\n extensionCache.set(extensionPath, factory);\n }\n return factory;\n}\n"]}
1
+ {"version":3,"file":"loader-virtual-modules.js","sourceRoot":"","sources":["../../../src/core/extensions/loader-virtual-modules.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport * as path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { createJiti } from \"jiti/static\";\nimport { getExtensionTranspileCacheDir, isBunBinary, isBundledBuild } from \"../../config.ts\";\nimport { resolvePath } from \"../../utils/paths.ts\";\nimport type { ExtensionFactory } from \"./types.ts\";\n\nconst require = createRequire(import.meta.url);\nlet _virtualModules: Record<string, object> | null = null;\nlet _virtualModulesPromise: Promise<Record<string, object>> | null = null;\n\nasync function loadVirtualModules(): Promise<Record<string, object>> {\n const [typebox, typeboxCompile, typeboxValue, piAgentCore, piTui, piAi, piAiOauth, piCodingAgent] = await Promise.all([\n import(\"typebox\"),\n import(\"typebox/compile\"),\n import(\"typebox/value\"),\n import(\"@earendil-works/pi-agent-core\"),\n import(\"@earendil-works/pi-tui\"),\n // pi 0.80.2: the old global pi-ai API moved off the root entrypoint onto\n // `/compat` (a strict superset). Extensions still `import ... from\n // \"@earendil-works/pi-ai\"`, so we load the compat module here and key it\n // under the root specifier below to keep every extension working unchanged.\n import(\"@earendil-works/pi-ai/compat\"),\n import(\"@earendil-works/pi-ai/oauth\"),\n // NOTE: This import works because loader.ts exports are NOT re-exported from index.ts,\n // avoiding a circular dependency while preserving the package-name extension import path.\n import(\"../../index.ts\"),\n ]);\n\n return {\n typebox,\n \"typebox/compile\": typeboxCompile,\n \"typebox/value\": typeboxValue,\n \"@sinclair/typebox\": typebox,\n \"@sinclair/typebox/compile\": typeboxCompile,\n \"@sinclair/typebox/value\": typeboxValue,\n \"@earendil-works/pi-agent-core\": piAgentCore,\n \"@earendil-works/pi-tui\": piTui,\n \"@earendil-works/pi-ai\": piAi,\n \"@earendil-works/pi-ai/compat\": piAi,\n \"@earendil-works/pi-ai/oauth\": piAiOauth,\n \"@bastani/atomic\": piCodingAgent,\n \"@mariozechner/pi-agent-core\": piAgentCore,\n \"@mariozechner/pi-tui\": piTui,\n \"@mariozechner/pi-ai\": piAi,\n \"@mariozechner/pi-ai/compat\": piAi,\n \"@mariozechner/pi-ai/oauth\": piAiOauth,\n };\n}\n\n/** Modules available to extensions via virtualModules (for compiled Bun binary). */\nasync function getVirtualModules(): Promise<Record<string, object>> {\n if (_virtualModules) return _virtualModules;\n _virtualModulesPromise ??= loadVirtualModules().then(\n (virtualModules) => {\n _virtualModules = virtualModules;\n return virtualModules;\n },\n (error: Error) => {\n _virtualModulesPromise = null;\n throw error;\n },\n );\n return _virtualModulesPromise;\n}\nlet _aliases: Record<string, string> | null = null;\nlet _transpileCacheDir: string | null = null;\n\n/**\n * Persistent on-disk cache for jiti-transpiled extension modules.\n * jiti keys cache entries by source-content hash, so entries self-invalidate\n * when extension sources change; stale sibling version dirs are pruned\n * in the background.\n */\nfunction getTranspileCacheDir(): string {\n if (_transpileCacheDir) return _transpileCacheDir;\n _transpileCacheDir = getExtensionTranspileCacheDir();\n pruneStaleTranspileCaches(_transpileCacheDir);\n return _transpileCacheDir;\n}\n\nfunction pruneStaleTranspileCaches(currentDir: string): void {\n const parent = path.dirname(currentDir);\n const keep = path.basename(currentDir);\n void fs.promises\n .readdir(parent)\n .then((entries) =>\n Promise.all(\n entries\n .filter((entry) => entry !== keep)\n .map((entry) => fs.promises.rm(path.join(parent, entry), { recursive: true, force: true })),\n ),\n )\n .catch(() => {});\n}\n\nlet extensionCacheCwd: string | undefined;\nlet extensionCacheGeneration = 0;\nconst extensionCache = new Map<string, ExtensionFactory>();\n\nexport interface ExtensionCacheToken {\n cwd: string;\n generation: number;\n}\n\nexport function clearExtensionCache(): void {\n extensionCache.clear();\n extensionCacheCwd = undefined;\n extensionCacheGeneration++;\n}\n\nexport function useExtensionCacheCwd(cwd: string): ExtensionCacheToken {\n const resolvedCwd = resolvePath(cwd);\n if (extensionCacheCwd !== undefined && extensionCacheCwd !== resolvedCwd) {\n clearExtensionCache();\n }\n extensionCacheCwd = resolvedCwd;\n return { cwd: resolvedCwd, generation: extensionCacheGeneration };\n}\n\nfunction isCurrentCacheToken(cacheToken: ExtensionCacheToken | undefined): cacheToken is ExtensionCacheToken {\n return (\n cacheToken !== undefined &&\n extensionCacheCwd === cacheToken.cwd &&\n extensionCacheGeneration === cacheToken.generation\n );\n}\n\nfunction extensionImportSpecifier(extensionPath: string, cacheToken: ExtensionCacheToken | undefined): string {\n const url = pathToFileURL(extensionPath);\n const cacheKey = cacheToken ? `${cacheToken.generation}:${cacheToken.cwd}` : `${Date.now()}:${Math.random()}`;\n url.searchParams.set(\"atomicExtensionCache\", cacheKey);\n return url.href;\n}\n\n/**\n * Locate an installed package's root directory without consulting its\n * \"exports\" map: require.resolve(\"<pkg>/package.json\") throws\n * ERR_PACKAGE_PATH_NOT_EXPORTED under Node for packages that do not export\n * \"./package.json\" (pi-ai does not), and import.meta.resolve() cannot be\n * used because its mere presence silently disables bytecode generation for\n * the compiled binary (CJS bundle). Scanning require.resolve.paths() walks\n * the same node_modules chain Node would, without exports-map encapsulation.\n */\nfunction findPackageRoot(packageName: string, searchPaths?: string[]): string {\n for (const base of searchPaths ?? require.resolve.paths(packageName) ?? []) {\n const candidate = path.join(base, packageName);\n if (fs.existsSync(path.join(candidate, \"package.json\"))) {\n return candidate;\n }\n }\n throw new Error(`Cannot locate package directory for \"${packageName}\"`);\n}\n\n/**\n * Get aliases for jiti (used in Node.js/development mode).\n * In Bun binary mode, virtualModules is used instead.\n */\nfunction getAliases(): Record<string, string> {\n if (_aliases) return _aliases;\n\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n const packageIndex = path.resolve(__dirname, \"../..\", \"index.js\");\n\n const typeboxEntry = require.resolve(\"typebox\");\n const typeboxCompileEntry = require.resolve(\"typebox/compile\");\n const typeboxValueEntry = require.resolve(\"typebox/value\");\n\n const packagesRoot = path.resolve(__dirname, \"../../../../\");\n const resolveWorkspaceOrImport = (workspaceRelativePath: string, packageName: string): string => {\n const workspacePath = path.join(packagesRoot, workspaceRelativePath);\n if (fs.existsSync(workspacePath)) {\n return workspacePath;\n }\n const packageRoot = findPackageRoot(packageName);\n const entryRelativePath = workspaceRelativePath.split(\"/\").slice(1).join(\"/\");\n return path.join(packageRoot, entryRelativePath);\n };\n\n const piCodingAgentEntry = packageIndex;\n const piAgentCoreEntry = resolveWorkspaceOrImport(\"agent/dist/index.js\", \"@earendil-works/pi-agent-core\");\n const piTuiEntry = resolveWorkspaceOrImport(\"tui/dist/index.js\", \"@earendil-works/pi-tui\");\n // The workspace path mirrors pi-ai 0.80.x's built dist layout. If an\n // upstream layout change moves these files, this join needs updating to\n // match the package's real dist paths.\n const piAiEntry = resolveWorkspaceOrImport(\"ai/dist/compat.js\", \"@earendil-works/pi-ai\");\n const piAiOauthEntry = resolveWorkspaceOrImport(\"ai/dist/oauth.js\", \"@earendil-works/pi-ai\");\n\n _aliases = {\n \"@bastani/atomic\": piCodingAgentEntry,\n \"@earendil-works/pi-coding-agent\": piCodingAgentEntry,\n \"@earendil-works/pi-agent-core\": piAgentCoreEntry,\n \"@earendil-works/pi-tui\": piTuiEntry,\n \"@earendil-works/pi-ai\": piAiEntry,\n \"@earendil-works/pi-ai/compat\": piAiEntry,\n \"@earendil-works/pi-ai/oauth\": piAiOauthEntry,\n \"@mariozechner/pi-agent-core\": piAgentCoreEntry,\n \"@mariozechner/pi-tui\": piTuiEntry,\n \"@mariozechner/pi-ai\": piAiEntry,\n \"@mariozechner/pi-ai/compat\": piAiEntry,\n \"@mariozechner/pi-ai/oauth\": piAiOauthEntry,\n typebox: typeboxEntry,\n \"typebox/compile\": typeboxCompileEntry,\n \"typebox/value\": typeboxValueEntry,\n \"@sinclair/typebox\": typeboxEntry,\n \"@sinclair/typebox/compile\": typeboxCompileEntry,\n \"@sinclair/typebox/value\": typeboxValueEntry,\n };\n\n return _aliases;\n}\n\n/** Internal hooks for extension-loader alias regression tests. */\nexport const extensionLoaderTestHooks = {\n loadVirtualModules,\n getAliases,\n findPackageRoot,\n};\n\n/**\n * Extension paths already evaluated via native import() in this process. Bun on\n * Windows ignores the cache-busting query on file URLs, so re-loads of these\n * paths (e.g. /reload) must go through jiti's transformed-import path to get a\n * fresh module evaluation.\n */\nconst nativelyImportedPaths = new Set<string>();\n\nexport async function loadExtensionModule(\n extensionPath: string,\n cacheToken?: ExtensionCacheToken,\n): Promise<ExtensionFactory | undefined> {\n if (isCurrentCacheToken(cacheToken)) {\n const cachedFactory = extensionCache.get(extensionPath);\n if (cachedFactory) return cachedFactory;\n }\n\n const isWindows = process.platform === \"win32\";\n // Single-file builds (compiled binary or dev bundle) cannot alias host\n // package specifiers to files on disk: extensions must share the live\n // module instances baked into the build, so virtualModules is used instead\n // (which requires jiti's transformed-import path).\n const isSingleFileBuild = isBunBinary || isBundledBuild;\n // Windows first-load fast path: native import() (jiti's default tryNative)\n // skips per-launch transpilation of the extension module graph. Re-loads of\n // the same path fall back to transformed imports for fresh evaluation.\n const forceTransformedImports = isSingleFileBuild || (isWindows && nativelyImportedPaths.has(extensionPath));\n const jiti = createJiti(import.meta.url, {\n moduleCache: false,\n ...(forceTransformedImports\n ? { fsCache: getTranspileCacheDir(), tryNative: false }\n : isWindows\n ? { fsCache: getTranspileCacheDir() }\n : {}),\n ...(isSingleFileBuild ? { virtualModules: await getVirtualModules() } : { alias: getAliases() }),\n });\n const module = await jiti.import(extensionImportSpecifier(extensionPath, cacheToken), { default: true });\n if (isWindows && !forceTransformedImports) {\n nativelyImportedPaths.add(extensionPath);\n }\n const factory = module as ExtensionFactory;\n if (typeof factory !== \"function\") return undefined;\n if (isCurrentCacheToken(cacheToken)) {\n extensionCache.set(extensionPath, factory);\n }\n return factory;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"model-registry-builtins.d.ts","sourceRoot":"","sources":["../../src/core/model-registry-builtins.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,GAAG,EAIR,KAAK,KAAK,EAEV,MAAM,8BAA8B,CAAC;AAItC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAkB,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAmBlF,wBAAgB,iCAAiC,CAChD,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GACzC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAKpC;AA4BD,wBAAgB,WAAW,CAC1B,UAAU,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,EAChC,cAAc,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,GAC5D,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,SAAS,CAiClC;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,aAAa,GAAG,KAAK,CAAC,GAAG,CAAC,CAgCzF;AAED,wBAAgB,iBAAiB,CAChC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,EACxC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,GACrD,KAAK,CAAC,GAAG,CAAC,EAAE,CAsBd;AAED,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAWvG","sourcesContent":["import {\n\ttype Api,\n\tgetModels,\n\tgetProviders,\n\ttype KnownProvider,\n\ttype Model,\n\ttype OpenAICompletionsCompat,\n} from \"@earendil-works/pi-ai/compat\";\nimport { normalizeContextWindowOptions, withContextWindowOptions } from \"./context-window.ts\";\nimport { copilotApiBaseUrlFromToken, copilotTokenFromEnvironment, DEFAULT_COPILOT_API_BASE_URL, getActiveCopilotModelCatalog } from \"./copilot-model-catalog.ts\";\nimport { copilotTemplateFromModels, copilotThinkingLevelMapFor, synthesizeCopilotCatalogModels } from \"./copilot-model-synthesis.ts\";\nimport type { ModelOverride } from \"./model-registry-schemas.ts\";\nimport type { ProviderCompat, ProviderOverride } from \"./model-registry-types.ts\";\n\nconst GITHUB_COPILOT_API_VERSION_HEADER = \"X-GitHub-Api-Version\";\nconst GITHUB_COPILOT_API_VERSION = \"2026-06-01\";\n\nfunction withDynamicGitHubCopilotModels(provider: string, models: Model<Api>[]): Model<Api>[] {\n\tif (provider !== \"github-copilot\") return models;\n\tconst existingIds = new Set(models.map((model) => model.id));\n\tconst template = copilotTemplateFromModels(models);\n\tconst dynamicModels = synthesizeCopilotCatalogModels(getActiveCopilotModelCatalog(), existingIds, template);\n\treturn dynamicModels.length === 0 ? models : [...models, ...dynamicModels];\n}\n\nfunction hasHeader(headers: Record<string, string> | undefined, headerName: string): boolean {\n\tif (!headers) return false;\n\tconst normalizedHeaderName = headerName.toLowerCase();\n\treturn Object.keys(headers).some((key) => key.toLowerCase() === normalizedHeaderName);\n}\n\nexport function withGitHubCopilotApiVersionHeader(\n\tmodel: Model<Api>,\n\theaders: Record<string, string> | undefined,\n): Record<string, string> | undefined {\n\tif (model.provider !== \"github-copilot\" || hasHeader(headers, GITHUB_COPILOT_API_VERSION_HEADER)) {\n\t\treturn headers;\n\t}\n\treturn { ...(headers ?? {}), [GITHUB_COPILOT_API_VERSION_HEADER]: GITHUB_COPILOT_API_VERSION };\n}\n\nfunction withCopilotEnvironmentBaseUrl(model: Model<Api>): Model<Api> {\n\tif (model.provider !== \"github-copilot\") return model;\n\tconst resolvedBaseUrl = copilotApiBaseUrlFromToken(copilotTokenFromEnvironment());\n\tif (resolvedBaseUrl === DEFAULT_COPILOT_API_BASE_URL || resolvedBaseUrl === model.baseUrl) return model;\n\treturn { ...model, baseUrl: resolvedBaseUrl };\n}\n\nfunction withCopilotThinkingLevelMap(model: Model<Api>): Model<Api> {\n\tif (model.provider !== \"github-copilot\") return model;\n\tconst context = getActiveCopilotModelCatalog().get(model.id);\n\tif (!context?.supports?.reasoningEffortLevels) return model;\n\tconst thinkingLevelMap = copilotThinkingLevelMapFor(context, model.api);\n\treturn thinkingLevelMap ? { ...model, thinkingLevelMap } : model;\n}\n\nfunction withCopilotContextWindowOptions(model: Model<Api>): Model<Api> {\n\tif (model.provider !== \"github-copilot\") return model;\n\tconst context = getActiveCopilotModelCatalog().get(model.id);\n\tif (!context) return model;\n\tconst base = { ...model, contextWindow: context.contextWindow, maxInputTokens: context.maxInputTokens, maxTokens: context.maxTokens ?? model.maxTokens };\n\tif (context.contextWindowOptions && context.contextWindowOptions.length > 1) {\n\t\treturn withContextWindowOptions(base, context.contextWindowOptions);\n\t}\n\treturn base;\n}\n\nexport function mergeCompat(\n\tbaseCompat: Model<Api>[\"compat\"],\n\toverrideCompat: ModelOverride[\"compat\"] | Model<Api>[\"compat\"],\n): Model<Api>[\"compat\"] | undefined {\n\tif (!overrideCompat) return baseCompat;\n\n\tconst base = baseCompat as ProviderCompat | undefined;\n\tconst override = overrideCompat as ProviderCompat;\n\tconst merged = { ...base, ...override } as ProviderCompat;\n\n\tconst baseCompletions = base as OpenAICompletionsCompat | undefined;\n\tconst overrideCompletions = override as OpenAICompletionsCompat;\n\tconst mergedCompletions = merged as OpenAICompletionsCompat;\n\n\tif (baseCompletions?.openRouterRouting || overrideCompletions.openRouterRouting) {\n\t\tmergedCompletions.openRouterRouting = {\n\t\t\t...baseCompletions?.openRouterRouting,\n\t\t\t...overrideCompletions.openRouterRouting,\n\t\t};\n\t}\n\n\tif (baseCompletions?.vercelGatewayRouting || overrideCompletions.vercelGatewayRouting) {\n\t\tmergedCompletions.vercelGatewayRouting = {\n\t\t\t...baseCompletions?.vercelGatewayRouting,\n\t\t\t...overrideCompletions.vercelGatewayRouting,\n\t\t};\n\t}\n\n\tif (baseCompletions?.chatTemplateKwargs || overrideCompletions.chatTemplateKwargs) {\n\t\tmergedCompletions.chatTemplateKwargs = {\n\t\t\t...baseCompletions?.chatTemplateKwargs,\n\t\t\t...overrideCompletions.chatTemplateKwargs,\n\t\t};\n\t}\n\n\treturn merged as Model<Api>[\"compat\"];\n}\n\nexport function applyModelOverride(model: Model<Api>, override: ModelOverride): Model<Api> {\n\tconst result = { ...model };\n\n\tif (override.name !== undefined) result.name = override.name;\n\tif (override.reasoning !== undefined) result.reasoning = override.reasoning;\n\tif (override.thinkingLevelMap !== undefined) {\n\t\tresult.thinkingLevelMap = { ...model.thinkingLevelMap, ...override.thinkingLevelMap };\n\t}\n\tif (override.input !== undefined) result.input = override.input as (\"text\" | \"image\")[];\n\tif (override.contextWindow !== undefined) {\n\t\tresult.contextWindow = override.contextWindow;\n\t\tresult.defaultContextWindow = override.contextWindow;\n\t\tif (override.contextWindowOptions === undefined) {\n\t\t\tresult.contextWindowOptions = undefined;\n\t\t}\n\t}\n\tif (override.contextWindowOptions !== undefined) {\n\t\tresult.contextWindowOptions = normalizeContextWindowOptions(override.contextWindowOptions);\n\t}\n\tif (override.maxTokens !== undefined) result.maxTokens = override.maxTokens;\n\n\tif (override.cost) {\n\t\tresult.cost = {\n\t\t\tinput: override.cost.input ?? model.cost.input,\n\t\t\toutput: override.cost.output ?? model.cost.output,\n\t\t\tcacheRead: override.cost.cacheRead ?? model.cost.cacheRead,\n\t\t\tcacheWrite: override.cost.cacheWrite ?? model.cost.cacheWrite,\n\t\t};\n\t}\n\n\tresult.compat = mergeCompat(model.compat, override.compat);\n\treturn result;\n}\n\nexport function loadBuiltInModels(\n\toverrides: Map<string, ProviderOverride>,\n\tmodelOverrides: Map<string, Map<string, ModelOverride>>,\n): Model<Api>[] {\n\treturn getProviders().flatMap((provider) => {\n\t\tconst models = withDynamicGitHubCopilotModels(provider, getModels(provider as KnownProvider) as Model<Api>[]);\n\t\tconst providerOverride = overrides.get(provider);\n\t\tconst perModelOverrides = modelOverrides.get(provider);\n\n\t\treturn models.map((m) => {\n\t\t\tlet model = withCopilotEnvironmentBaseUrl(m);\n\n\t\t\tif (providerOverride) {\n\t\t\t\tmodel = {\n\t\t\t\t\t...model,\n\t\t\t\t\tbaseUrl: providerOverride.baseUrl ?? model.baseUrl,\n\t\t\t\t\tcompat: mergeCompat(model.compat, providerOverride.compat),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tmodel = withCopilotThinkingLevelMap(withCopilotContextWindowOptions(model));\n\t\t\tconst modelOverride = perModelOverrides?.get(m.id);\n\t\t\treturn modelOverride ? applyModelOverride(model, modelOverride) : model;\n\t\t});\n\t});\n}\n\nexport function mergeCustomModels(builtInModels: Model<Api>[], customModels: Model<Api>[]): Model<Api>[] {\n\tconst merged = [...builtInModels];\n\tfor (const customModel of customModels) {\n\t\tconst existingIndex = merged.findIndex((m) => m.provider === customModel.provider && m.id === customModel.id);\n\t\tif (existingIndex >= 0) {\n\t\t\tmerged[existingIndex] = customModel;\n\t\t} else {\n\t\t\tmerged.push(customModel);\n\t\t}\n\t}\n\treturn merged;\n}\n"]}
1
+ {"version":3,"file":"model-registry-builtins.d.ts","sourceRoot":"","sources":["../../src/core/model-registry-builtins.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,GAAG,EAIR,KAAK,KAAK,EAEV,MAAM,8BAA8B,CAAC;AAKtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAkB,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAmBlF,wBAAgB,iCAAiC,CAChD,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GACzC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAKpC;AAmCD,wBAAgB,WAAW,CAC1B,UAAU,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,EAChC,cAAc,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,GAC5D,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,SAAS,CAiClC;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,aAAa,GAAG,KAAK,CAAC,GAAG,CAAC,CAgCzF;AAED,wBAAgB,iBAAiB,CAChC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,EACxC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,GACrD,KAAK,CAAC,GAAG,CAAC,EAAE,CAsBd;AAED,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAWvG","sourcesContent":["import {\n\ttype Api,\n\tgetModels,\n\tgetProviders,\n\ttype KnownProvider,\n\ttype Model,\n\ttype OpenAICompletionsCompat,\n} from \"@earendil-works/pi-ai/compat\";\nimport { normalizeContextWindowOptions, withContextWindowOptions } from \"./context-window.ts\";\nimport { copilotApiBaseUrlFromToken, copilotTokenFromEnvironment, DEFAULT_COPILOT_API_BASE_URL, getActiveCopilotModelCatalog } from \"./copilot-model-catalog.ts\";\nimport { copilotTemplateFromModels, copilotThinkingLevelMapFor, synthesizeCopilotCatalogModels } from \"./copilot-model-synthesis.ts\";\nimport { getStaticCopilotModelFallback } from \"./copilot-model-static-fallbacks.ts\";\nimport type { ModelOverride } from \"./model-registry-schemas.ts\";\nimport type { ProviderCompat, ProviderOverride } from \"./model-registry-types.ts\";\n\nconst GITHUB_COPILOT_API_VERSION_HEADER = \"X-GitHub-Api-Version\";\nconst GITHUB_COPILOT_API_VERSION = \"2026-06-01\";\n\nfunction withDynamicGitHubCopilotModels(provider: string, models: Model<Api>[]): Model<Api>[] {\n\tif (provider !== \"github-copilot\") return models;\n\tconst existingIds = new Set(models.map((model) => model.id));\n\tconst template = copilotTemplateFromModels(models);\n\tconst dynamicModels = synthesizeCopilotCatalogModels(getActiveCopilotModelCatalog(), existingIds, template);\n\treturn dynamicModels.length === 0 ? models : [...models, ...dynamicModels];\n}\n\nfunction hasHeader(headers: Record<string, string> | undefined, headerName: string): boolean {\n\tif (!headers) return false;\n\tconst normalizedHeaderName = headerName.toLowerCase();\n\treturn Object.keys(headers).some((key) => key.toLowerCase() === normalizedHeaderName);\n}\n\nexport function withGitHubCopilotApiVersionHeader(\n\tmodel: Model<Api>,\n\theaders: Record<string, string> | undefined,\n): Record<string, string> | undefined {\n\tif (model.provider !== \"github-copilot\" || hasHeader(headers, GITHUB_COPILOT_API_VERSION_HEADER)) {\n\t\treturn headers;\n\t}\n\treturn { ...(headers ?? {}), [GITHUB_COPILOT_API_VERSION_HEADER]: GITHUB_COPILOT_API_VERSION };\n}\n\nfunction withCopilotEnvironmentBaseUrl(model: Model<Api>): Model<Api> {\n\tif (model.provider !== \"github-copilot\") return model;\n\tconst resolvedBaseUrl = copilotApiBaseUrlFromToken(copilotTokenFromEnvironment());\n\tif (resolvedBaseUrl === DEFAULT_COPILOT_API_BASE_URL || resolvedBaseUrl === model.baseUrl) return model;\n\treturn { ...model, baseUrl: resolvedBaseUrl };\n}\n\nfunction withCopilotThinkingLevelMap(model: Model<Api>): Model<Api> {\n\tif (model.provider !== \"github-copilot\") return model;\n\tconst context = getActiveCopilotModelCatalog().get(model.id);\n\tif (!context?.supports?.reasoningEffortLevels) return model;\n\tconst thinkingLevelMap = copilotThinkingLevelMapFor(context, model.api);\n\treturn thinkingLevelMap ? { ...model, thinkingLevelMap } : model;\n}\n\nfunction withCopilotContextWindowOptions(model: Model<Api>): Model<Api> {\n\tif (model.provider !== \"github-copilot\") return model;\n\t// The live CAPI catalog (or its disk cache) is authoritative. Without an\n\t// entry (cold start, fetch failure, offline), fall back to the bundled\n\t// static CAPI snapshot: several bundled pi-ai definitions overstate the\n\t// enforced default-tier window or understate output caps, which lets\n\t// sessions sail past the server-side limits before compaction fires\n\t// (issue #1608). Fallback entries carry the same tier structure as catalog\n\t// entries so long-context (1M-class) tiers stay selectable offline.\n\tconst context = getActiveCopilotModelCatalog().get(model.id) ?? getStaticCopilotModelFallback(model.id);\n\tif (!context) return model;\n\tconst base = { ...model, contextWindow: context.contextWindow, maxInputTokens: context.maxInputTokens, maxTokens: context.maxTokens ?? model.maxTokens };\n\tif (context.contextWindowOptions && context.contextWindowOptions.length > 1) {\n\t\treturn withContextWindowOptions(base, context.contextWindowOptions);\n\t}\n\treturn base;\n}\n\nexport function mergeCompat(\n\tbaseCompat: Model<Api>[\"compat\"],\n\toverrideCompat: ModelOverride[\"compat\"] | Model<Api>[\"compat\"],\n): Model<Api>[\"compat\"] | undefined {\n\tif (!overrideCompat) return baseCompat;\n\n\tconst base = baseCompat as ProviderCompat | undefined;\n\tconst override = overrideCompat as ProviderCompat;\n\tconst merged = { ...base, ...override } as ProviderCompat;\n\n\tconst baseCompletions = base as OpenAICompletionsCompat | undefined;\n\tconst overrideCompletions = override as OpenAICompletionsCompat;\n\tconst mergedCompletions = merged as OpenAICompletionsCompat;\n\n\tif (baseCompletions?.openRouterRouting || overrideCompletions.openRouterRouting) {\n\t\tmergedCompletions.openRouterRouting = {\n\t\t\t...baseCompletions?.openRouterRouting,\n\t\t\t...overrideCompletions.openRouterRouting,\n\t\t};\n\t}\n\n\tif (baseCompletions?.vercelGatewayRouting || overrideCompletions.vercelGatewayRouting) {\n\t\tmergedCompletions.vercelGatewayRouting = {\n\t\t\t...baseCompletions?.vercelGatewayRouting,\n\t\t\t...overrideCompletions.vercelGatewayRouting,\n\t\t};\n\t}\n\n\tif (baseCompletions?.chatTemplateKwargs || overrideCompletions.chatTemplateKwargs) {\n\t\tmergedCompletions.chatTemplateKwargs = {\n\t\t\t...baseCompletions?.chatTemplateKwargs,\n\t\t\t...overrideCompletions.chatTemplateKwargs,\n\t\t};\n\t}\n\n\treturn merged as Model<Api>[\"compat\"];\n}\n\nexport function applyModelOverride(model: Model<Api>, override: ModelOverride): Model<Api> {\n\tconst result = { ...model };\n\n\tif (override.name !== undefined) result.name = override.name;\n\tif (override.reasoning !== undefined) result.reasoning = override.reasoning;\n\tif (override.thinkingLevelMap !== undefined) {\n\t\tresult.thinkingLevelMap = { ...model.thinkingLevelMap, ...override.thinkingLevelMap };\n\t}\n\tif (override.input !== undefined) result.input = override.input as (\"text\" | \"image\")[];\n\tif (override.contextWindow !== undefined) {\n\t\tresult.contextWindow = override.contextWindow;\n\t\tresult.defaultContextWindow = override.contextWindow;\n\t\tif (override.contextWindowOptions === undefined) {\n\t\t\tresult.contextWindowOptions = undefined;\n\t\t}\n\t}\n\tif (override.contextWindowOptions !== undefined) {\n\t\tresult.contextWindowOptions = normalizeContextWindowOptions(override.contextWindowOptions);\n\t}\n\tif (override.maxTokens !== undefined) result.maxTokens = override.maxTokens;\n\n\tif (override.cost) {\n\t\tresult.cost = {\n\t\t\tinput: override.cost.input ?? model.cost.input,\n\t\t\toutput: override.cost.output ?? model.cost.output,\n\t\t\tcacheRead: override.cost.cacheRead ?? model.cost.cacheRead,\n\t\t\tcacheWrite: override.cost.cacheWrite ?? model.cost.cacheWrite,\n\t\t};\n\t}\n\n\tresult.compat = mergeCompat(model.compat, override.compat);\n\treturn result;\n}\n\nexport function loadBuiltInModels(\n\toverrides: Map<string, ProviderOverride>,\n\tmodelOverrides: Map<string, Map<string, ModelOverride>>,\n): Model<Api>[] {\n\treturn getProviders().flatMap((provider) => {\n\t\tconst models = withDynamicGitHubCopilotModels(provider, getModels(provider as KnownProvider) as Model<Api>[]);\n\t\tconst providerOverride = overrides.get(provider);\n\t\tconst perModelOverrides = modelOverrides.get(provider);\n\n\t\treturn models.map((m) => {\n\t\t\tlet model = withCopilotEnvironmentBaseUrl(m);\n\n\t\t\tif (providerOverride) {\n\t\t\t\tmodel = {\n\t\t\t\t\t...model,\n\t\t\t\t\tbaseUrl: providerOverride.baseUrl ?? model.baseUrl,\n\t\t\t\t\tcompat: mergeCompat(model.compat, providerOverride.compat),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tmodel = withCopilotThinkingLevelMap(withCopilotContextWindowOptions(model));\n\t\t\tconst modelOverride = perModelOverrides?.get(m.id);\n\t\t\treturn modelOverride ? applyModelOverride(model, modelOverride) : model;\n\t\t});\n\t});\n}\n\nexport function mergeCustomModels(builtInModels: Model<Api>[], customModels: Model<Api>[]): Model<Api>[] {\n\tconst merged = [...builtInModels];\n\tfor (const customModel of customModels) {\n\t\tconst existingIndex = merged.findIndex((m) => m.provider === customModel.provider && m.id === customModel.id);\n\t\tif (existingIndex >= 0) {\n\t\t\tmerged[existingIndex] = customModel;\n\t\t} else {\n\t\t\tmerged.push(customModel);\n\t\t}\n\t}\n\treturn merged;\n}\n"]}
@@ -2,6 +2,7 @@ import { getModels, getProviders, } from "@earendil-works/pi-ai/compat";
2
2
  import { normalizeContextWindowOptions, withContextWindowOptions } from "./context-window.js";
3
3
  import { copilotApiBaseUrlFromToken, copilotTokenFromEnvironment, DEFAULT_COPILOT_API_BASE_URL, getActiveCopilotModelCatalog } from "./copilot-model-catalog.js";
4
4
  import { copilotTemplateFromModels, copilotThinkingLevelMapFor, synthesizeCopilotCatalogModels } from "./copilot-model-synthesis.js";
5
+ import { getStaticCopilotModelFallback } from "./copilot-model-static-fallbacks.js";
5
6
  const GITHUB_COPILOT_API_VERSION_HEADER = "X-GitHub-Api-Version";
6
7
  const GITHUB_COPILOT_API_VERSION = "2026-06-01";
7
8
  function withDynamicGitHubCopilotModels(provider, models) {
@@ -44,7 +45,14 @@ function withCopilotThinkingLevelMap(model) {
44
45
  function withCopilotContextWindowOptions(model) {
45
46
  if (model.provider !== "github-copilot")
46
47
  return model;
47
- const context = getActiveCopilotModelCatalog().get(model.id);
48
+ // The live CAPI catalog (or its disk cache) is authoritative. Without an
49
+ // entry (cold start, fetch failure, offline), fall back to the bundled
50
+ // static CAPI snapshot: several bundled pi-ai definitions overstate the
51
+ // enforced default-tier window or understate output caps, which lets
52
+ // sessions sail past the server-side limits before compaction fires
53
+ // (issue #1608). Fallback entries carry the same tier structure as catalog
54
+ // entries so long-context (1M-class) tiers stay selectable offline.
55
+ const context = getActiveCopilotModelCatalog().get(model.id) ?? getStaticCopilotModelFallback(model.id);
48
56
  if (!context)
49
57
  return model;
50
58
  const base = { ...model, contextWindow: context.contextWindow, maxInputTokens: context.maxInputTokens, maxTokens: context.maxTokens ?? model.maxTokens };
@@ -1 +1 @@
1
- {"version":3,"file":"model-registry-builtins.js","sourceRoot":"","sources":["../../src/core/model-registry-builtins.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype Api,\n\tgetModels,\n\tgetProviders,\n\ttype KnownProvider,\n\ttype Model,\n\ttype OpenAICompletionsCompat,\n} from \"@earendil-works/pi-ai/compat\";\nimport { normalizeContextWindowOptions, withContextWindowOptions } from \"./context-window.ts\";\nimport { copilotApiBaseUrlFromToken, copilotTokenFromEnvironment, DEFAULT_COPILOT_API_BASE_URL, getActiveCopilotModelCatalog } from \"./copilot-model-catalog.ts\";\nimport { copilotTemplateFromModels, copilotThinkingLevelMapFor, synthesizeCopilotCatalogModels } from \"./copilot-model-synthesis.ts\";\nimport type { ModelOverride } from \"./model-registry-schemas.ts\";\nimport type { ProviderCompat, ProviderOverride } from \"./model-registry-types.ts\";\n\nconst GITHUB_COPILOT_API_VERSION_HEADER = \"X-GitHub-Api-Version\";\nconst GITHUB_COPILOT_API_VERSION = \"2026-06-01\";\n\nfunction withDynamicGitHubCopilotModels(provider: string, models: Model<Api>[]): Model<Api>[] {\n\tif (provider !== \"github-copilot\") return models;\n\tconst existingIds = new Set(models.map((model) => model.id));\n\tconst template = copilotTemplateFromModels(models);\n\tconst dynamicModels = synthesizeCopilotCatalogModels(getActiveCopilotModelCatalog(), existingIds, template);\n\treturn dynamicModels.length === 0 ? models : [...models, ...dynamicModels];\n}\n\nfunction hasHeader(headers: Record<string, string> | undefined, headerName: string): boolean {\n\tif (!headers) return false;\n\tconst normalizedHeaderName = headerName.toLowerCase();\n\treturn Object.keys(headers).some((key) => key.toLowerCase() === normalizedHeaderName);\n}\n\nexport function withGitHubCopilotApiVersionHeader(\n\tmodel: Model<Api>,\n\theaders: Record<string, string> | undefined,\n): Record<string, string> | undefined {\n\tif (model.provider !== \"github-copilot\" || hasHeader(headers, GITHUB_COPILOT_API_VERSION_HEADER)) {\n\t\treturn headers;\n\t}\n\treturn { ...(headers ?? {}), [GITHUB_COPILOT_API_VERSION_HEADER]: GITHUB_COPILOT_API_VERSION };\n}\n\nfunction withCopilotEnvironmentBaseUrl(model: Model<Api>): Model<Api> {\n\tif (model.provider !== \"github-copilot\") return model;\n\tconst resolvedBaseUrl = copilotApiBaseUrlFromToken(copilotTokenFromEnvironment());\n\tif (resolvedBaseUrl === DEFAULT_COPILOT_API_BASE_URL || resolvedBaseUrl === model.baseUrl) return model;\n\treturn { ...model, baseUrl: resolvedBaseUrl };\n}\n\nfunction withCopilotThinkingLevelMap(model: Model<Api>): Model<Api> {\n\tif (model.provider !== \"github-copilot\") return model;\n\tconst context = getActiveCopilotModelCatalog().get(model.id);\n\tif (!context?.supports?.reasoningEffortLevels) return model;\n\tconst thinkingLevelMap = copilotThinkingLevelMapFor(context, model.api);\n\treturn thinkingLevelMap ? { ...model, thinkingLevelMap } : model;\n}\n\nfunction withCopilotContextWindowOptions(model: Model<Api>): Model<Api> {\n\tif (model.provider !== \"github-copilot\") return model;\n\tconst context = getActiveCopilotModelCatalog().get(model.id);\n\tif (!context) return model;\n\tconst base = { ...model, contextWindow: context.contextWindow, maxInputTokens: context.maxInputTokens, maxTokens: context.maxTokens ?? model.maxTokens };\n\tif (context.contextWindowOptions && context.contextWindowOptions.length > 1) {\n\t\treturn withContextWindowOptions(base, context.contextWindowOptions);\n\t}\n\treturn base;\n}\n\nexport function mergeCompat(\n\tbaseCompat: Model<Api>[\"compat\"],\n\toverrideCompat: ModelOverride[\"compat\"] | Model<Api>[\"compat\"],\n): Model<Api>[\"compat\"] | undefined {\n\tif (!overrideCompat) return baseCompat;\n\n\tconst base = baseCompat as ProviderCompat | undefined;\n\tconst override = overrideCompat as ProviderCompat;\n\tconst merged = { ...base, ...override } as ProviderCompat;\n\n\tconst baseCompletions = base as OpenAICompletionsCompat | undefined;\n\tconst overrideCompletions = override as OpenAICompletionsCompat;\n\tconst mergedCompletions = merged as OpenAICompletionsCompat;\n\n\tif (baseCompletions?.openRouterRouting || overrideCompletions.openRouterRouting) {\n\t\tmergedCompletions.openRouterRouting = {\n\t\t\t...baseCompletions?.openRouterRouting,\n\t\t\t...overrideCompletions.openRouterRouting,\n\t\t};\n\t}\n\n\tif (baseCompletions?.vercelGatewayRouting || overrideCompletions.vercelGatewayRouting) {\n\t\tmergedCompletions.vercelGatewayRouting = {\n\t\t\t...baseCompletions?.vercelGatewayRouting,\n\t\t\t...overrideCompletions.vercelGatewayRouting,\n\t\t};\n\t}\n\n\tif (baseCompletions?.chatTemplateKwargs || overrideCompletions.chatTemplateKwargs) {\n\t\tmergedCompletions.chatTemplateKwargs = {\n\t\t\t...baseCompletions?.chatTemplateKwargs,\n\t\t\t...overrideCompletions.chatTemplateKwargs,\n\t\t};\n\t}\n\n\treturn merged as Model<Api>[\"compat\"];\n}\n\nexport function applyModelOverride(model: Model<Api>, override: ModelOverride): Model<Api> {\n\tconst result = { ...model };\n\n\tif (override.name !== undefined) result.name = override.name;\n\tif (override.reasoning !== undefined) result.reasoning = override.reasoning;\n\tif (override.thinkingLevelMap !== undefined) {\n\t\tresult.thinkingLevelMap = { ...model.thinkingLevelMap, ...override.thinkingLevelMap };\n\t}\n\tif (override.input !== undefined) result.input = override.input as (\"text\" | \"image\")[];\n\tif (override.contextWindow !== undefined) {\n\t\tresult.contextWindow = override.contextWindow;\n\t\tresult.defaultContextWindow = override.contextWindow;\n\t\tif (override.contextWindowOptions === undefined) {\n\t\t\tresult.contextWindowOptions = undefined;\n\t\t}\n\t}\n\tif (override.contextWindowOptions !== undefined) {\n\t\tresult.contextWindowOptions = normalizeContextWindowOptions(override.contextWindowOptions);\n\t}\n\tif (override.maxTokens !== undefined) result.maxTokens = override.maxTokens;\n\n\tif (override.cost) {\n\t\tresult.cost = {\n\t\t\tinput: override.cost.input ?? model.cost.input,\n\t\t\toutput: override.cost.output ?? model.cost.output,\n\t\t\tcacheRead: override.cost.cacheRead ?? model.cost.cacheRead,\n\t\t\tcacheWrite: override.cost.cacheWrite ?? model.cost.cacheWrite,\n\t\t};\n\t}\n\n\tresult.compat = mergeCompat(model.compat, override.compat);\n\treturn result;\n}\n\nexport function loadBuiltInModels(\n\toverrides: Map<string, ProviderOverride>,\n\tmodelOverrides: Map<string, Map<string, ModelOverride>>,\n): Model<Api>[] {\n\treturn getProviders().flatMap((provider) => {\n\t\tconst models = withDynamicGitHubCopilotModels(provider, getModels(provider as KnownProvider) as Model<Api>[]);\n\t\tconst providerOverride = overrides.get(provider);\n\t\tconst perModelOverrides = modelOverrides.get(provider);\n\n\t\treturn models.map((m) => {\n\t\t\tlet model = withCopilotEnvironmentBaseUrl(m);\n\n\t\t\tif (providerOverride) {\n\t\t\t\tmodel = {\n\t\t\t\t\t...model,\n\t\t\t\t\tbaseUrl: providerOverride.baseUrl ?? model.baseUrl,\n\t\t\t\t\tcompat: mergeCompat(model.compat, providerOverride.compat),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tmodel = withCopilotThinkingLevelMap(withCopilotContextWindowOptions(model));\n\t\t\tconst modelOverride = perModelOverrides?.get(m.id);\n\t\t\treturn modelOverride ? applyModelOverride(model, modelOverride) : model;\n\t\t});\n\t});\n}\n\nexport function mergeCustomModels(builtInModels: Model<Api>[], customModels: Model<Api>[]): Model<Api>[] {\n\tconst merged = [...builtInModels];\n\tfor (const customModel of customModels) {\n\t\tconst existingIndex = merged.findIndex((m) => m.provider === customModel.provider && m.id === customModel.id);\n\t\tif (existingIndex >= 0) {\n\t\t\tmerged[existingIndex] = customModel;\n\t\t} else {\n\t\t\tmerged.push(customModel);\n\t\t}\n\t}\n\treturn merged;\n}\n"]}
1
+ {"version":3,"file":"model-registry-builtins.js","sourceRoot":"","sources":["../../src/core/model-registry-builtins.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype Api,\n\tgetModels,\n\tgetProviders,\n\ttype KnownProvider,\n\ttype Model,\n\ttype OpenAICompletionsCompat,\n} from \"@earendil-works/pi-ai/compat\";\nimport { normalizeContextWindowOptions, withContextWindowOptions } from \"./context-window.ts\";\nimport { copilotApiBaseUrlFromToken, copilotTokenFromEnvironment, DEFAULT_COPILOT_API_BASE_URL, getActiveCopilotModelCatalog } from \"./copilot-model-catalog.ts\";\nimport { copilotTemplateFromModels, copilotThinkingLevelMapFor, synthesizeCopilotCatalogModels } from \"./copilot-model-synthesis.ts\";\nimport { getStaticCopilotModelFallback } from \"./copilot-model-static-fallbacks.ts\";\nimport type { ModelOverride } from \"./model-registry-schemas.ts\";\nimport type { ProviderCompat, ProviderOverride } from \"./model-registry-types.ts\";\n\nconst GITHUB_COPILOT_API_VERSION_HEADER = \"X-GitHub-Api-Version\";\nconst GITHUB_COPILOT_API_VERSION = \"2026-06-01\";\n\nfunction withDynamicGitHubCopilotModels(provider: string, models: Model<Api>[]): Model<Api>[] {\n\tif (provider !== \"github-copilot\") return models;\n\tconst existingIds = new Set(models.map((model) => model.id));\n\tconst template = copilotTemplateFromModels(models);\n\tconst dynamicModels = synthesizeCopilotCatalogModels(getActiveCopilotModelCatalog(), existingIds, template);\n\treturn dynamicModels.length === 0 ? models : [...models, ...dynamicModels];\n}\n\nfunction hasHeader(headers: Record<string, string> | undefined, headerName: string): boolean {\n\tif (!headers) return false;\n\tconst normalizedHeaderName = headerName.toLowerCase();\n\treturn Object.keys(headers).some((key) => key.toLowerCase() === normalizedHeaderName);\n}\n\nexport function withGitHubCopilotApiVersionHeader(\n\tmodel: Model<Api>,\n\theaders: Record<string, string> | undefined,\n): Record<string, string> | undefined {\n\tif (model.provider !== \"github-copilot\" || hasHeader(headers, GITHUB_COPILOT_API_VERSION_HEADER)) {\n\t\treturn headers;\n\t}\n\treturn { ...(headers ?? {}), [GITHUB_COPILOT_API_VERSION_HEADER]: GITHUB_COPILOT_API_VERSION };\n}\n\nfunction withCopilotEnvironmentBaseUrl(model: Model<Api>): Model<Api> {\n\tif (model.provider !== \"github-copilot\") return model;\n\tconst resolvedBaseUrl = copilotApiBaseUrlFromToken(copilotTokenFromEnvironment());\n\tif (resolvedBaseUrl === DEFAULT_COPILOT_API_BASE_URL || resolvedBaseUrl === model.baseUrl) return model;\n\treturn { ...model, baseUrl: resolvedBaseUrl };\n}\n\nfunction withCopilotThinkingLevelMap(model: Model<Api>): Model<Api> {\n\tif (model.provider !== \"github-copilot\") return model;\n\tconst context = getActiveCopilotModelCatalog().get(model.id);\n\tif (!context?.supports?.reasoningEffortLevels) return model;\n\tconst thinkingLevelMap = copilotThinkingLevelMapFor(context, model.api);\n\treturn thinkingLevelMap ? { ...model, thinkingLevelMap } : model;\n}\n\nfunction withCopilotContextWindowOptions(model: Model<Api>): Model<Api> {\n\tif (model.provider !== \"github-copilot\") return model;\n\t// The live CAPI catalog (or its disk cache) is authoritative. Without an\n\t// entry (cold start, fetch failure, offline), fall back to the bundled\n\t// static CAPI snapshot: several bundled pi-ai definitions overstate the\n\t// enforced default-tier window or understate output caps, which lets\n\t// sessions sail past the server-side limits before compaction fires\n\t// (issue #1608). Fallback entries carry the same tier structure as catalog\n\t// entries so long-context (1M-class) tiers stay selectable offline.\n\tconst context = getActiveCopilotModelCatalog().get(model.id) ?? getStaticCopilotModelFallback(model.id);\n\tif (!context) return model;\n\tconst base = { ...model, contextWindow: context.contextWindow, maxInputTokens: context.maxInputTokens, maxTokens: context.maxTokens ?? model.maxTokens };\n\tif (context.contextWindowOptions && context.contextWindowOptions.length > 1) {\n\t\treturn withContextWindowOptions(base, context.contextWindowOptions);\n\t}\n\treturn base;\n}\n\nexport function mergeCompat(\n\tbaseCompat: Model<Api>[\"compat\"],\n\toverrideCompat: ModelOverride[\"compat\"] | Model<Api>[\"compat\"],\n): Model<Api>[\"compat\"] | undefined {\n\tif (!overrideCompat) return baseCompat;\n\n\tconst base = baseCompat as ProviderCompat | undefined;\n\tconst override = overrideCompat as ProviderCompat;\n\tconst merged = { ...base, ...override } as ProviderCompat;\n\n\tconst baseCompletions = base as OpenAICompletionsCompat | undefined;\n\tconst overrideCompletions = override as OpenAICompletionsCompat;\n\tconst mergedCompletions = merged as OpenAICompletionsCompat;\n\n\tif (baseCompletions?.openRouterRouting || overrideCompletions.openRouterRouting) {\n\t\tmergedCompletions.openRouterRouting = {\n\t\t\t...baseCompletions?.openRouterRouting,\n\t\t\t...overrideCompletions.openRouterRouting,\n\t\t};\n\t}\n\n\tif (baseCompletions?.vercelGatewayRouting || overrideCompletions.vercelGatewayRouting) {\n\t\tmergedCompletions.vercelGatewayRouting = {\n\t\t\t...baseCompletions?.vercelGatewayRouting,\n\t\t\t...overrideCompletions.vercelGatewayRouting,\n\t\t};\n\t}\n\n\tif (baseCompletions?.chatTemplateKwargs || overrideCompletions.chatTemplateKwargs) {\n\t\tmergedCompletions.chatTemplateKwargs = {\n\t\t\t...baseCompletions?.chatTemplateKwargs,\n\t\t\t...overrideCompletions.chatTemplateKwargs,\n\t\t};\n\t}\n\n\treturn merged as Model<Api>[\"compat\"];\n}\n\nexport function applyModelOverride(model: Model<Api>, override: ModelOverride): Model<Api> {\n\tconst result = { ...model };\n\n\tif (override.name !== undefined) result.name = override.name;\n\tif (override.reasoning !== undefined) result.reasoning = override.reasoning;\n\tif (override.thinkingLevelMap !== undefined) {\n\t\tresult.thinkingLevelMap = { ...model.thinkingLevelMap, ...override.thinkingLevelMap };\n\t}\n\tif (override.input !== undefined) result.input = override.input as (\"text\" | \"image\")[];\n\tif (override.contextWindow !== undefined) {\n\t\tresult.contextWindow = override.contextWindow;\n\t\tresult.defaultContextWindow = override.contextWindow;\n\t\tif (override.contextWindowOptions === undefined) {\n\t\t\tresult.contextWindowOptions = undefined;\n\t\t}\n\t}\n\tif (override.contextWindowOptions !== undefined) {\n\t\tresult.contextWindowOptions = normalizeContextWindowOptions(override.contextWindowOptions);\n\t}\n\tif (override.maxTokens !== undefined) result.maxTokens = override.maxTokens;\n\n\tif (override.cost) {\n\t\tresult.cost = {\n\t\t\tinput: override.cost.input ?? model.cost.input,\n\t\t\toutput: override.cost.output ?? model.cost.output,\n\t\t\tcacheRead: override.cost.cacheRead ?? model.cost.cacheRead,\n\t\t\tcacheWrite: override.cost.cacheWrite ?? model.cost.cacheWrite,\n\t\t};\n\t}\n\n\tresult.compat = mergeCompat(model.compat, override.compat);\n\treturn result;\n}\n\nexport function loadBuiltInModels(\n\toverrides: Map<string, ProviderOverride>,\n\tmodelOverrides: Map<string, Map<string, ModelOverride>>,\n): Model<Api>[] {\n\treturn getProviders().flatMap((provider) => {\n\t\tconst models = withDynamicGitHubCopilotModels(provider, getModels(provider as KnownProvider) as Model<Api>[]);\n\t\tconst providerOverride = overrides.get(provider);\n\t\tconst perModelOverrides = modelOverrides.get(provider);\n\n\t\treturn models.map((m) => {\n\t\t\tlet model = withCopilotEnvironmentBaseUrl(m);\n\n\t\t\tif (providerOverride) {\n\t\t\t\tmodel = {\n\t\t\t\t\t...model,\n\t\t\t\t\tbaseUrl: providerOverride.baseUrl ?? model.baseUrl,\n\t\t\t\t\tcompat: mergeCompat(model.compat, providerOverride.compat),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tmodel = withCopilotThinkingLevelMap(withCopilotContextWindowOptions(model));\n\t\t\tconst modelOverride = perModelOverrides?.get(m.id);\n\t\t\treturn modelOverride ? applyModelOverride(model, modelOverride) : model;\n\t\t});\n\t});\n}\n\nexport function mergeCustomModels(builtInModels: Model<Api>[], customModels: Model<Api>[]): Model<Api>[] {\n\tconst merged = [...builtInModels];\n\tfor (const customModel of customModels) {\n\t\tconst existingIndex = merged.findIndex((m) => m.provider === customModel.provider && m.id === customModel.id);\n\t\tif (existingIndex >= 0) {\n\t\t\tmerged[existingIndex] = customModel;\n\t\t} else {\n\t\t\tmerged.push(customModel);\n\t\t}\n\t}\n\treturn merged;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"resource-loader-reload.d.ts","sourceRoot":"","sources":["../../src/core/resource-loader-reload.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAOlE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAWvE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AA2D9E,wBAAsB,0BAA0B,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAsC7G;AAED,wBAAsB,2BAA2B,CAChD,MAAM,EAAE,qBAAqB,EAC7B,OAAO,CAAC,EAAE,2BAA2B,GACnC,OAAO,CAAC,IAAI,CAAC,CA8Kf","sourcesContent":["import { existsSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { isLocalPath } from \"../utils/paths.ts\";\nimport { clearExtensionCache, loadExtensionsCached } from \"./extensions/loader.ts\";\nimport type { LoadExtensionsResult } from \"./extensions/types.ts\";\nimport type { PathMetadata, ResolvedPaths } from \"./package-manager.ts\";\nimport { resetTimings, startTimingSpan, endTimingSpan } from \"./timings.ts\";\nimport { loadProjectContextFiles, resolvePromptInput } from \"./resource-loader-context-files.ts\";\nimport { discoverAppendSystemPromptFile, discoverSystemPromptFile } from \"./resource-loader-discovery.ts\";\nimport { loadExtensionFactories, loadFinalExtensionSet } from \"./resource-loader-extensions.ts\";\nimport { resourceInternals } from \"./resource-loader-internals.ts\";\nimport type { DefaultResourceLoader } from \"./resource-loader-core.ts\";\nimport {\n\tcollectWorkflowResources,\n\tcreateInheritanceSnapshotProvider,\n\tcreateWorkflowResourceProvider,\n\tresolvePackageResourcePaths,\n\tresolveTrustedBorrowedProjectLocalSources,\n} from \"./resource-loader-package-resources.ts\";\nimport { applyExtensionSourceInfo } from \"./resource-loader-source-info.ts\";\nimport { updatePromptsFromPaths, updateSkillsFromPaths, updateThemesFromPaths } from \"./resource-loader-assets.ts\";\nimport { mergeResourcePaths, resolveResourcePath } from \"./resource-loader-paths.ts\";\nimport type { ResourceLoaderReloadOptions } from \"./resource-loader-types.ts\";\n\nfunction getEnabledResources(\n\tresources: Array<{ path: string; enabled: boolean; metadata: PathMetadata }>,\n\tmetadataByPath: Map<string, PathMetadata>,\n): Array<{ path: string; enabled: boolean; metadata: PathMetadata }> {\n\tfor (const r of resources) {\n\t\tif (!metadataByPath.has(r.path)) {\n\t\t\tmetadataByPath.set(r.path, r.metadata);\n\t\t}\n\t}\n\treturn resources.filter((r) => r.enabled);\n}\n\nfunction getEnabledPaths(\n\tresources: Array<{ path: string; enabled: boolean; metadata: PathMetadata }>,\n\tmetadataByPath: Map<string, PathMetadata>,\n): string[] {\n\treturn getEnabledResources(resources, metadataByPath).map((r) => r.path);\n}\n\nfunction mapSkillPath(\n\tresource: { path: string; metadata: PathMetadata },\n\tmetadataByPath: Map<string, PathMetadata>,\n): string {\n\tif (resource.metadata.source !== \"auto\" && resource.metadata.origin !== \"package\") {\n\t\treturn resource.path;\n\t}\n\ttry {\n\t\tconst stats = statSync(resource.path);\n\t\tif (!stats.isDirectory()) {\n\t\t\treturn resource.path;\n\t\t}\n\t} catch {\n\t\treturn resource.path;\n\t}\n\tconst skillFile = join(resource.path, \"SKILL.md\");\n\tif (existsSync(skillFile)) {\n\t\tif (!metadataByPath.has(skillFile)) {\n\t\t\tmetadataByPath.set(skillFile, resource.metadata);\n\t\t}\n\t\treturn skillFile;\n\t}\n\treturn resource.path;\n}\n\nfunction addCliMetadata(cliExtensionPaths: ResolvedPaths, metadataByPath: Map<string, PathMetadata>): void {\n\tfor (const r of cliExtensionPaths.extensions) {\n\t\tif (!metadataByPath.has(r.path)) {\n\t\t\tmetadataByPath.set(r.path, r.metadata);\n\t\t}\n\t}\n\tfor (const r of cliExtensionPaths.skills) {\n\t\tif (!metadataByPath.has(r.path)) {\n\t\t\tmetadataByPath.set(r.path, r.metadata);\n\t\t}\n\t}\n}\n\nexport async function loadProjectTrustExtensions(loader: DefaultResourceLoader): Promise<LoadExtensionsResult> {\n\tconst state = resourceInternals(loader);\n\tstate.settingsManager.setProjectTrusted(false);\n\tawait state.settingsManager.reload();\n\tconst { resolvedPaths, cliExtensionPaths, builtinPackagePaths } = await resolvePackageResourcePaths(loader, {\n\t\tincludeCliProjectLocalResources: false,\n\t});\n\tconst metadataByPath = new Map<string, PathMetadata>();\n\tconst cliEnabledExtensions = getEnabledPaths(cliExtensionPaths.extensions, metadataByPath);\n\tconst enabledExtensions = getEnabledPaths(resolvedPaths.extensions, metadataByPath);\n\tconst builtinEnabledExtensions = state.noExtensions\n\t\t? []\n\t\t: getEnabledPaths(builtinPackagePaths.extensions, metadataByPath);\n\tconst workflowResources = collectWorkflowResources(resolvedPaths, cliExtensionPaths, builtinPackagePaths);\n\tstate.workflowResources = workflowResources;\n\tconst workflowResourceProvider = createWorkflowResourceProvider(loader);\n\tconst inheritanceSnapshotProvider = createInheritanceSnapshotProvider(loader);\n\tconst extensionPaths = state.noExtensions\n\t\t? cliEnabledExtensions\n\t\t: mergeResourcePaths(state.cwd, cliEnabledExtensions, [...enabledExtensions, ...builtinEnabledExtensions]);\n\tconst extensionsResult = await loadExtensionsCached(\n\t\textensionPaths,\n\t\tstate.cwd,\n\t\tstate.eventBus,\n\t\tworkflowResourceProvider,\n\t\tundefined,\n\t\tinheritanceSnapshotProvider,\n\t);\n\tconst inlineExtensions = await loadExtensionFactories(\n\t\tloader,\n\t\textensionsResult.runtime,\n\t\tworkflowResourceProvider,\n\t\tinheritanceSnapshotProvider,\n\t);\n\textensionsResult.extensions.push(...inlineExtensions.extensions);\n\textensionsResult.errors.push(...inlineExtensions.errors);\n\tapplyExtensionSourceInfo(loader, extensionsResult.extensions, metadataByPath);\n\treturn extensionsResult;\n}\n\nexport async function reloadDefaultResourceLoader(\n\tloader: DefaultResourceLoader,\n\toptions?: ResourceLoaderReloadOptions,\n): Promise<void> {\n\tconst state = resourceInternals(loader);\n\tresetTimings(\"extensions\");\n\tif (state.loaded) {\n\t\tclearExtensionCache();\n\t}\n\tlet preTrustExtensions: LoadExtensionsResult | undefined;\n\tconst initialProjectTrusted = state.settingsManager.isProjectTrusted();\n\tif (options?.resolveProjectTrust || options?.resolveBorrowedProjectTrust) {\n\t\tpreTrustExtensions = await loadProjectTrustExtensions(loader);\n\t}\n\tif (options?.resolveProjectTrust && preTrustExtensions) {\n\t\tconst projectTrusted = await options.resolveProjectTrust({ extensionsResult: preTrustExtensions });\n\t\tstate.settingsManager.setProjectTrusted(projectTrusted);\n\t} else if (preTrustExtensions) {\n\t\tstate.settingsManager.setProjectTrusted(initialProjectTrusted);\n\t}\n\tif (options?.resolveBorrowedProjectTrust) {\n\t\tstate.trustedBorrowedProjectLocalSources = await resolveTrustedBorrowedProjectLocalSources(\n\t\t\tloader,\n\t\t\toptions.resolveBorrowedProjectTrust,\n\t\t\tpreTrustExtensions,\n\t\t);\n\t}\n\tconst resolveSpan = startTimingSpan(\"DefaultResourceLoader.reload.resolvePackageResourcePaths\");\n\tconst { resolvedPaths, cliExtensionPaths, builtinPackagePaths } = await resolvePackageResourcePaths(loader, {\n\t\ttrustedBorrowedProjectLocalSources: state.trustedBorrowedProjectLocalSources,\n\t});\n\tendTimingSpan(resolveSpan);\n\tconst metadataByPath = new Map<string, PathMetadata>();\n\n\tstate.extensionSkillSourceInfos = new Map();\n\tstate.extensionPromptSourceInfos = new Map();\n\tstate.extensionThemeSourceInfos = new Map();\n\n\tconst enabledExtensions = getEnabledPaths(resolvedPaths.extensions, metadataByPath);\n\tconst enabledSkillResources = getEnabledResources(resolvedPaths.skills, metadataByPath);\n\tconst enabledPrompts = getEnabledPaths(resolvedPaths.prompts, metadataByPath);\n\tconst enabledThemes = getEnabledPaths(resolvedPaths.themes, metadataByPath);\n\n\tconst builtinEnabledExtensions = state.noExtensions\n\t\t? []\n\t\t: getEnabledPaths(builtinPackagePaths.extensions, metadataByPath);\n\tconst builtinEnabledSkillResources = state.noSkills\n\t\t? []\n\t\t: getEnabledResources(builtinPackagePaths.skills, metadataByPath);\n\tconst builtinEnabledPrompts = state.noPromptTemplates\n\t\t? []\n\t\t: getEnabledPaths(builtinPackagePaths.prompts, metadataByPath);\n\tconst builtinEnabledThemes = state.noThemes\n\t\t? []\n\t\t: getEnabledPaths(builtinPackagePaths.themes, metadataByPath);\n\n\tconst enabledSkills = enabledSkillResources.map((resource) => mapSkillPath(resource, metadataByPath));\n\tconst builtinEnabledSkills = builtinEnabledSkillResources.map((resource) => mapSkillPath(resource, metadataByPath));\n\n\taddCliMetadata(cliExtensionPaths, metadataByPath);\n\n\tconst cliEnabledExtensions = getEnabledPaths(cliExtensionPaths.extensions, metadataByPath);\n\tconst cliEnabledSkills = getEnabledPaths(cliExtensionPaths.skills, metadataByPath);\n\tconst cliEnabledPrompts = getEnabledPaths(cliExtensionPaths.prompts, metadataByPath);\n\tconst cliEnabledThemes = getEnabledPaths(cliExtensionPaths.themes, metadataByPath);\n\tconst workflowResources = collectWorkflowResources(resolvedPaths, cliExtensionPaths, builtinPackagePaths);\n\tstate.workflowResources = workflowResources;\n\tconst workflowResourceProvider = createWorkflowResourceProvider(loader);\n\n\tconst extensionPaths = state.noExtensions\n\t\t? cliEnabledExtensions\n\t\t: mergeResourcePaths(state.cwd, cliEnabledExtensions, [...enabledExtensions, ...builtinEnabledExtensions]);\n\n\tconst inheritanceSnapshotProvider = createInheritanceSnapshotProvider(loader);\n\tconst extensionsResult = await loadFinalExtensionSet(\n\t\tloader,\n\t\textensionPaths,\n\t\tpreTrustExtensions,\n\t\tworkflowResourceProvider,\n\t\tinheritanceSnapshotProvider,\n\t);\n\n\tfor (const p of state.additionalExtensionPaths) {\n\t\tif (isLocalPath(p)) {\n\t\t\tconst resolved = resolveResourcePath(state.cwd, p);\n\t\t\tif (!existsSync(resolved)) {\n\t\t\t\textensionsResult.errors.push({ path: resolved, error: `Extension path does not exist: ${resolved}` });\n\t\t\t}\n\t\t}\n\t}\n\tstate.extensionsResult = state.extensionsOverride ? state.extensionsOverride(extensionsResult) : extensionsResult;\n\tapplyExtensionSourceInfo(loader, state.extensionsResult.extensions, metadataByPath);\n\n\tconst skillPaths = state.noSkills\n\t\t? mergeResourcePaths(state.cwd, cliEnabledSkills, state.additionalSkillPaths)\n\t\t: mergeResourcePaths(state.cwd, [...cliEnabledSkills, ...enabledSkills, ...builtinEnabledSkills], state.additionalSkillPaths);\n\n\tstate.lastSkillPaths = skillPaths;\n\tconst skillsSpan = startTimingSpan(\"DefaultResourceLoader.reload.updateSkillsFromPaths\");\n\tupdateSkillsFromPaths(loader, skillPaths, metadataByPath);\n\tendTimingSpan(skillsSpan);\n\tfor (const p of state.additionalSkillPaths) {\n\t\tif (isLocalPath(p)) {\n\t\t\tconst resolved = resolveResourcePath(state.cwd, p);\n\t\t\tif (!existsSync(resolved) && !state.skillDiagnostics.some((d) => d.path === resolved)) {\n\t\t\t\tstate.skillDiagnostics.push({ type: \"error\", message: \"Skill path does not exist\", path: resolved });\n\t\t\t}\n\t\t}\n\t}\n\n\tconst promptPaths = state.noPromptTemplates\n\t\t? mergeResourcePaths(state.cwd, cliEnabledPrompts, state.additionalPromptTemplatePaths)\n\t\t: mergeResourcePaths(state.cwd, [...cliEnabledPrompts, ...enabledPrompts, ...builtinEnabledPrompts], state.additionalPromptTemplatePaths);\n\n\tstate.lastPromptPaths = promptPaths;\n\tconst promptsSpan = startTimingSpan(\"DefaultResourceLoader.reload.updatePromptsFromPaths\");\n\tupdatePromptsFromPaths(loader, promptPaths, metadataByPath);\n\tendTimingSpan(promptsSpan);\n\tfor (const p of state.additionalPromptTemplatePaths) {\n\t\tif (isLocalPath(p)) {\n\t\t\tconst resolved = resolveResourcePath(state.cwd, p);\n\t\t\tif (!existsSync(resolved) && !state.promptDiagnostics.some((d) => d.path === resolved)) {\n\t\t\t\tstate.promptDiagnostics.push({\n\t\t\t\t\ttype: \"error\",\n\t\t\t\t\tmessage: \"Prompt template path does not exist\",\n\t\t\t\t\tpath: resolved,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tconst themePaths = state.noThemes\n\t\t? mergeResourcePaths(state.cwd, cliEnabledThemes, state.additionalThemePaths)\n\t\t: mergeResourcePaths(state.cwd, [...cliEnabledThemes, ...enabledThemes, ...builtinEnabledThemes], state.additionalThemePaths);\n\n\tstate.lastThemePaths = themePaths;\n\tconst themesSpan = startTimingSpan(\"DefaultResourceLoader.reload.updateThemesFromPaths\");\n\tupdateThemesFromPaths(loader, themePaths, metadataByPath);\n\tendTimingSpan(themesSpan);\n\tfor (const p of state.additionalThemePaths) {\n\t\tconst resolved = resolveResourcePath(state.cwd, p);\n\t\tif (!existsSync(resolved) && !state.themeDiagnostics.some((d) => d.path === resolved)) {\n\t\t\tstate.themeDiagnostics.push({ type: \"error\", message: \"Theme path does not exist\", path: resolved });\n\t\t}\n\t}\n\n\tconst contextFilesSpan = startTimingSpan(\"DefaultResourceLoader.reload.loadProjectContextFiles\");\n\tconst agentsFiles = {\n\t\tagentsFiles: state.noContextFiles\n\t\t\t? []\n\t\t\t: loadProjectContextFiles({\n\t\t\t\t\tcwd: state.cwd,\n\t\t\t\t\tagentDir: state.agentDir,\n\t\t\t\t\tprojectTrusted: state.settingsManager.isProjectTrusted(),\n\t\t\t\t}),\n\t};\n\tendTimingSpan(contextFilesSpan);\n\tconst resolvedAgentsFiles = state.agentsFilesOverride ? state.agentsFilesOverride(agentsFiles) : agentsFiles;\n\tstate.agentsFiles = resolvedAgentsFiles.agentsFiles;\n\n\tconst promptFilesSpan = startTimingSpan(\"DefaultResourceLoader.reload.resolvePromptFiles\");\n\tconst baseSystemPrompt = resolvePromptInput(\n\t\tstate.systemPromptSource ?? discoverSystemPromptFile(loader),\n\t\t\"system prompt\",\n\t);\n\tstate.systemPrompt = state.systemPromptOverride ? state.systemPromptOverride(baseSystemPrompt) : baseSystemPrompt;\n\n\tconst discoveredAppend = discoverAppendSystemPromptFile(loader);\n\tconst appendSources = state.appendSystemPromptSource ?? (discoveredAppend ? [discoveredAppend] : []);\n\tconst baseAppend = appendSources\n\t\t.map((s) => resolvePromptInput(s, \"append system prompt\"))\n\t\t.filter((s): s is string => s !== undefined);\n\tstate.appendSystemPrompt = state.appendSystemPromptOverride\n\t\t? state.appendSystemPromptOverride(baseAppend)\n\t\t: baseAppend;\n\tstate.loaded = true;\n\tendTimingSpan(promptFilesSpan);\n}\n"]}
1
+ {"version":3,"file":"resource-loader-reload.d.ts","sourceRoot":"","sources":["../../src/core/resource-loader-reload.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAOlE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAWvE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AA2D9E,wBAAsB,0BAA0B,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAsC7G;AAED,wBAAsB,2BAA2B,CAChD,MAAM,EAAE,qBAAqB,EAC7B,OAAO,CAAC,EAAE,2BAA2B,GACnC,OAAO,CAAC,IAAI,CAAC,CAgLf","sourcesContent":["import { existsSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { isLocalPath } from \"../utils/paths.ts\";\nimport { clearExtensionCache, createExtensionRuntime, loadExtensionsCached } from \"./extensions/loader.ts\";\nimport type { LoadExtensionsResult } from \"./extensions/types.ts\";\nimport type { PathMetadata, ResolvedPaths } from \"./package-manager.ts\";\nimport { resetTimings, startTimingSpan, endTimingSpan } from \"./timings.ts\";\nimport { loadProjectContextFiles, resolvePromptInput } from \"./resource-loader-context-files.ts\";\nimport { discoverAppendSystemPromptFile, discoverSystemPromptFile } from \"./resource-loader-discovery.ts\";\nimport { loadExtensionFactories, loadFinalExtensionSet } from \"./resource-loader-extensions.ts\";\nimport { resourceInternals } from \"./resource-loader-internals.ts\";\nimport type { DefaultResourceLoader } from \"./resource-loader-core.ts\";\nimport {\n\tcollectWorkflowResources,\n\tcreateInheritanceSnapshotProvider,\n\tcreateWorkflowResourceProvider,\n\tresolvePackageResourcePaths,\n\tresolveTrustedBorrowedProjectLocalSources,\n} from \"./resource-loader-package-resources.ts\";\nimport { applyExtensionSourceInfo } from \"./resource-loader-source-info.ts\";\nimport { updatePromptsFromPaths, updateSkillsFromPaths, updateThemesFromPaths } from \"./resource-loader-assets.ts\";\nimport { mergeResourcePaths, resolveResourcePath } from \"./resource-loader-paths.ts\";\nimport type { ResourceLoaderReloadOptions } from \"./resource-loader-types.ts\";\n\nfunction getEnabledResources(\n\tresources: Array<{ path: string; enabled: boolean; metadata: PathMetadata }>,\n\tmetadataByPath: Map<string, PathMetadata>,\n): Array<{ path: string; enabled: boolean; metadata: PathMetadata }> {\n\tfor (const r of resources) {\n\t\tif (!metadataByPath.has(r.path)) {\n\t\t\tmetadataByPath.set(r.path, r.metadata);\n\t\t}\n\t}\n\treturn resources.filter((r) => r.enabled);\n}\n\nfunction getEnabledPaths(\n\tresources: Array<{ path: string; enabled: boolean; metadata: PathMetadata }>,\n\tmetadataByPath: Map<string, PathMetadata>,\n): string[] {\n\treturn getEnabledResources(resources, metadataByPath).map((r) => r.path);\n}\n\nfunction mapSkillPath(\n\tresource: { path: string; metadata: PathMetadata },\n\tmetadataByPath: Map<string, PathMetadata>,\n): string {\n\tif (resource.metadata.source !== \"auto\" && resource.metadata.origin !== \"package\") {\n\t\treturn resource.path;\n\t}\n\ttry {\n\t\tconst stats = statSync(resource.path);\n\t\tif (!stats.isDirectory()) {\n\t\t\treturn resource.path;\n\t\t}\n\t} catch {\n\t\treturn resource.path;\n\t}\n\tconst skillFile = join(resource.path, \"SKILL.md\");\n\tif (existsSync(skillFile)) {\n\t\tif (!metadataByPath.has(skillFile)) {\n\t\t\tmetadataByPath.set(skillFile, resource.metadata);\n\t\t}\n\t\treturn skillFile;\n\t}\n\treturn resource.path;\n}\n\nfunction addCliMetadata(cliExtensionPaths: ResolvedPaths, metadataByPath: Map<string, PathMetadata>): void {\n\tfor (const r of cliExtensionPaths.extensions) {\n\t\tif (!metadataByPath.has(r.path)) {\n\t\t\tmetadataByPath.set(r.path, r.metadata);\n\t\t}\n\t}\n\tfor (const r of cliExtensionPaths.skills) {\n\t\tif (!metadataByPath.has(r.path)) {\n\t\t\tmetadataByPath.set(r.path, r.metadata);\n\t\t}\n\t}\n}\n\nexport async function loadProjectTrustExtensions(loader: DefaultResourceLoader): Promise<LoadExtensionsResult> {\n\tconst state = resourceInternals(loader);\n\tstate.settingsManager.setProjectTrusted(false);\n\tawait state.settingsManager.reload();\n\tconst { resolvedPaths, cliExtensionPaths, builtinPackagePaths } = await resolvePackageResourcePaths(loader, {\n\t\tincludeCliProjectLocalResources: false,\n\t});\n\tconst metadataByPath = new Map<string, PathMetadata>();\n\tconst cliEnabledExtensions = getEnabledPaths(cliExtensionPaths.extensions, metadataByPath);\n\tconst enabledExtensions = getEnabledPaths(resolvedPaths.extensions, metadataByPath);\n\tconst builtinEnabledExtensions = state.noExtensions\n\t\t? []\n\t\t: getEnabledPaths(builtinPackagePaths.extensions, metadataByPath);\n\tconst workflowResources = collectWorkflowResources(resolvedPaths, cliExtensionPaths, builtinPackagePaths);\n\tstate.workflowResources = workflowResources;\n\tconst workflowResourceProvider = createWorkflowResourceProvider(loader);\n\tconst inheritanceSnapshotProvider = createInheritanceSnapshotProvider(loader);\n\tconst extensionPaths = state.noExtensions\n\t\t? cliEnabledExtensions\n\t\t: mergeResourcePaths(state.cwd, cliEnabledExtensions, [...enabledExtensions, ...builtinEnabledExtensions]);\n\tconst extensionsResult = await loadExtensionsCached(\n\t\textensionPaths,\n\t\tstate.cwd,\n\t\tstate.eventBus,\n\t\tworkflowResourceProvider,\n\t\tundefined,\n\t\tinheritanceSnapshotProvider,\n\t);\n\tconst inlineExtensions = await loadExtensionFactories(\n\t\tloader,\n\t\textensionsResult.runtime,\n\t\tworkflowResourceProvider,\n\t\tinheritanceSnapshotProvider,\n\t);\n\textensionsResult.extensions.push(...inlineExtensions.extensions);\n\textensionsResult.errors.push(...inlineExtensions.errors);\n\tapplyExtensionSourceInfo(loader, extensionsResult.extensions, metadataByPath);\n\treturn extensionsResult;\n}\n\nexport async function reloadDefaultResourceLoader(\n\tloader: DefaultResourceLoader,\n\toptions?: ResourceLoaderReloadOptions,\n): Promise<void> {\n\tconst state = resourceInternals(loader);\n\tresetTimings(\"extensions\");\n\tif (state.loaded) {\n\t\tclearExtensionCache();\n\t}\n\tlet preTrustExtensions: LoadExtensionsResult | undefined;\n\tconst initialProjectTrusted = state.settingsManager.isProjectTrusted();\n\tif (options?.resolveProjectTrust || options?.resolveBorrowedProjectTrust) {\n\t\tpreTrustExtensions = await loadProjectTrustExtensions(loader);\n\t}\n\tif (options?.resolveProjectTrust && preTrustExtensions) {\n\t\tconst projectTrusted = await options.resolveProjectTrust({ extensionsResult: preTrustExtensions });\n\t\tstate.settingsManager.setProjectTrusted(projectTrusted);\n\t} else if (preTrustExtensions) {\n\t\tstate.settingsManager.setProjectTrusted(initialProjectTrusted);\n\t}\n\tif (options?.resolveBorrowedProjectTrust) {\n\t\tstate.trustedBorrowedProjectLocalSources = await resolveTrustedBorrowedProjectLocalSources(\n\t\t\tloader,\n\t\t\toptions.resolveBorrowedProjectTrust,\n\t\t\tpreTrustExtensions,\n\t\t);\n\t}\n\tconst resolveSpan = startTimingSpan(\"DefaultResourceLoader.reload.resolvePackageResourcePaths\");\n\tconst { resolvedPaths, cliExtensionPaths, builtinPackagePaths } = await resolvePackageResourcePaths(loader, {\n\t\ttrustedBorrowedProjectLocalSources: state.trustedBorrowedProjectLocalSources,\n\t});\n\tendTimingSpan(resolveSpan);\n\tconst metadataByPath = new Map<string, PathMetadata>();\n\n\tstate.extensionSkillSourceInfos = new Map();\n\tstate.extensionPromptSourceInfos = new Map();\n\tstate.extensionThemeSourceInfos = new Map();\n\n\tconst enabledExtensions = getEnabledPaths(resolvedPaths.extensions, metadataByPath);\n\tconst enabledSkillResources = getEnabledResources(resolvedPaths.skills, metadataByPath);\n\tconst enabledPrompts = getEnabledPaths(resolvedPaths.prompts, metadataByPath);\n\tconst enabledThemes = getEnabledPaths(resolvedPaths.themes, metadataByPath);\n\n\tconst builtinEnabledExtensions = state.noExtensions\n\t\t? []\n\t\t: getEnabledPaths(builtinPackagePaths.extensions, metadataByPath);\n\tconst builtinEnabledSkillResources = state.noSkills\n\t\t? []\n\t\t: getEnabledResources(builtinPackagePaths.skills, metadataByPath);\n\tconst builtinEnabledPrompts = state.noPromptTemplates\n\t\t? []\n\t\t: getEnabledPaths(builtinPackagePaths.prompts, metadataByPath);\n\tconst builtinEnabledThemes = state.noThemes\n\t\t? []\n\t\t: getEnabledPaths(builtinPackagePaths.themes, metadataByPath);\n\n\tconst enabledSkills = enabledSkillResources.map((resource) => mapSkillPath(resource, metadataByPath));\n\tconst builtinEnabledSkills = builtinEnabledSkillResources.map((resource) => mapSkillPath(resource, metadataByPath));\n\n\taddCliMetadata(cliExtensionPaths, metadataByPath);\n\n\tconst cliEnabledExtensions = getEnabledPaths(cliExtensionPaths.extensions, metadataByPath);\n\tconst cliEnabledSkills = getEnabledPaths(cliExtensionPaths.skills, metadataByPath);\n\tconst cliEnabledPrompts = getEnabledPaths(cliExtensionPaths.prompts, metadataByPath);\n\tconst cliEnabledThemes = getEnabledPaths(cliExtensionPaths.themes, metadataByPath);\n\tconst workflowResources = collectWorkflowResources(resolvedPaths, cliExtensionPaths, builtinPackagePaths);\n\tstate.workflowResources = workflowResources;\n\tconst workflowResourceProvider = createWorkflowResourceProvider(loader);\n\n\tconst extensionPaths = state.noExtensions\n\t\t? cliEnabledExtensions\n\t\t: mergeResourcePaths(state.cwd, cliEnabledExtensions, [...enabledExtensions, ...builtinEnabledExtensions]);\n\n\tconst inheritanceSnapshotProvider = createInheritanceSnapshotProvider(loader);\n\tconst extensionsResult: LoadExtensionsResult = options?.deferExtensions\n\t\t? { extensions: [], errors: [], runtime: createExtensionRuntime() }\n\t\t: await loadFinalExtensionSet(\n\t\t\t\tloader,\n\t\t\t\textensionPaths,\n\t\t\t\tpreTrustExtensions,\n\t\t\t\tworkflowResourceProvider,\n\t\t\t\tinheritanceSnapshotProvider,\n\t\t\t);\n\n\tfor (const p of state.additionalExtensionPaths) {\n\t\tif (isLocalPath(p)) {\n\t\t\tconst resolved = resolveResourcePath(state.cwd, p);\n\t\t\tif (!existsSync(resolved)) {\n\t\t\t\textensionsResult.errors.push({ path: resolved, error: `Extension path does not exist: ${resolved}` });\n\t\t\t}\n\t\t}\n\t}\n\tstate.extensionsResult = state.extensionsOverride ? state.extensionsOverride(extensionsResult) : extensionsResult;\n\tapplyExtensionSourceInfo(loader, state.extensionsResult.extensions, metadataByPath);\n\n\tconst skillPaths = state.noSkills\n\t\t? mergeResourcePaths(state.cwd, cliEnabledSkills, state.additionalSkillPaths)\n\t\t: mergeResourcePaths(state.cwd, [...cliEnabledSkills, ...enabledSkills, ...builtinEnabledSkills], state.additionalSkillPaths);\n\n\tstate.lastSkillPaths = skillPaths;\n\tconst skillsSpan = startTimingSpan(\"DefaultResourceLoader.reload.updateSkillsFromPaths\");\n\tupdateSkillsFromPaths(loader, skillPaths, metadataByPath);\n\tendTimingSpan(skillsSpan);\n\tfor (const p of state.additionalSkillPaths) {\n\t\tif (isLocalPath(p)) {\n\t\t\tconst resolved = resolveResourcePath(state.cwd, p);\n\t\t\tif (!existsSync(resolved) && !state.skillDiagnostics.some((d) => d.path === resolved)) {\n\t\t\t\tstate.skillDiagnostics.push({ type: \"error\", message: \"Skill path does not exist\", path: resolved });\n\t\t\t}\n\t\t}\n\t}\n\n\tconst promptPaths = state.noPromptTemplates\n\t\t? mergeResourcePaths(state.cwd, cliEnabledPrompts, state.additionalPromptTemplatePaths)\n\t\t: mergeResourcePaths(state.cwd, [...cliEnabledPrompts, ...enabledPrompts, ...builtinEnabledPrompts], state.additionalPromptTemplatePaths);\n\n\tstate.lastPromptPaths = promptPaths;\n\tconst promptsSpan = startTimingSpan(\"DefaultResourceLoader.reload.updatePromptsFromPaths\");\n\tupdatePromptsFromPaths(loader, promptPaths, metadataByPath);\n\tendTimingSpan(promptsSpan);\n\tfor (const p of state.additionalPromptTemplatePaths) {\n\t\tif (isLocalPath(p)) {\n\t\t\tconst resolved = resolveResourcePath(state.cwd, p);\n\t\t\tif (!existsSync(resolved) && !state.promptDiagnostics.some((d) => d.path === resolved)) {\n\t\t\t\tstate.promptDiagnostics.push({\n\t\t\t\t\ttype: \"error\",\n\t\t\t\t\tmessage: \"Prompt template path does not exist\",\n\t\t\t\t\tpath: resolved,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tconst themePaths = state.noThemes\n\t\t? mergeResourcePaths(state.cwd, cliEnabledThemes, state.additionalThemePaths)\n\t\t: mergeResourcePaths(state.cwd, [...cliEnabledThemes, ...enabledThemes, ...builtinEnabledThemes], state.additionalThemePaths);\n\n\tstate.lastThemePaths = themePaths;\n\tconst themesSpan = startTimingSpan(\"DefaultResourceLoader.reload.updateThemesFromPaths\");\n\tupdateThemesFromPaths(loader, themePaths, metadataByPath);\n\tendTimingSpan(themesSpan);\n\tfor (const p of state.additionalThemePaths) {\n\t\tconst resolved = resolveResourcePath(state.cwd, p);\n\t\tif (!existsSync(resolved) && !state.themeDiagnostics.some((d) => d.path === resolved)) {\n\t\t\tstate.themeDiagnostics.push({ type: \"error\", message: \"Theme path does not exist\", path: resolved });\n\t\t}\n\t}\n\n\tconst contextFilesSpan = startTimingSpan(\"DefaultResourceLoader.reload.loadProjectContextFiles\");\n\tconst agentsFiles = {\n\t\tagentsFiles: state.noContextFiles\n\t\t\t? []\n\t\t\t: loadProjectContextFiles({\n\t\t\t\t\tcwd: state.cwd,\n\t\t\t\t\tagentDir: state.agentDir,\n\t\t\t\t\tprojectTrusted: state.settingsManager.isProjectTrusted(),\n\t\t\t\t}),\n\t};\n\tendTimingSpan(contextFilesSpan);\n\tconst resolvedAgentsFiles = state.agentsFilesOverride ? state.agentsFilesOverride(agentsFiles) : agentsFiles;\n\tstate.agentsFiles = resolvedAgentsFiles.agentsFiles;\n\n\tconst promptFilesSpan = startTimingSpan(\"DefaultResourceLoader.reload.resolvePromptFiles\");\n\tconst baseSystemPrompt = resolvePromptInput(\n\t\tstate.systemPromptSource ?? discoverSystemPromptFile(loader),\n\t\t\"system prompt\",\n\t);\n\tstate.systemPrompt = state.systemPromptOverride ? state.systemPromptOverride(baseSystemPrompt) : baseSystemPrompt;\n\n\tconst discoveredAppend = discoverAppendSystemPromptFile(loader);\n\tconst appendSources = state.appendSystemPromptSource ?? (discoveredAppend ? [discoveredAppend] : []);\n\tconst baseAppend = appendSources\n\t\t.map((s) => resolvePromptInput(s, \"append system prompt\"))\n\t\t.filter((s): s is string => s !== undefined);\n\tstate.appendSystemPrompt = state.appendSystemPromptOverride\n\t\t? state.appendSystemPromptOverride(baseAppend)\n\t\t: baseAppend;\n\tstate.loaded = true;\n\tendTimingSpan(promptFilesSpan);\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { existsSync, statSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  import { isLocalPath } from "../utils/paths.js";
4
- import { clearExtensionCache, loadExtensionsCached } from "./extensions/loader.js";
4
+ import { clearExtensionCache, createExtensionRuntime, loadExtensionsCached } from "./extensions/loader.js";
5
5
  import { resetTimings, startTimingSpan, endTimingSpan } from "./timings.js";
6
6
  import { loadProjectContextFiles, resolvePromptInput } from "./resource-loader-context-files.js";
7
7
  import { discoverAppendSystemPromptFile, discoverSystemPromptFile } from "./resource-loader-discovery.js";
@@ -143,7 +143,9 @@ export async function reloadDefaultResourceLoader(loader, options) {
143
143
  ? cliEnabledExtensions
144
144
  : mergeResourcePaths(state.cwd, cliEnabledExtensions, [...enabledExtensions, ...builtinEnabledExtensions]);
145
145
  const inheritanceSnapshotProvider = createInheritanceSnapshotProvider(loader);
146
- const extensionsResult = await loadFinalExtensionSet(loader, extensionPaths, preTrustExtensions, workflowResourceProvider, inheritanceSnapshotProvider);
146
+ const extensionsResult = options?.deferExtensions
147
+ ? { extensions: [], errors: [], runtime: createExtensionRuntime() }
148
+ : await loadFinalExtensionSet(loader, extensionPaths, preTrustExtensions, workflowResourceProvider, inheritanceSnapshotProvider);
147
149
  for (const p of state.additionalExtensionPaths) {
148
150
  if (isLocalPath(p)) {
149
151
  const resolved = resolveResourcePath(state.cwd, p);