gsd-pi 2.63.0 → 2.64.0-dev.9c14bd0

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 (448) hide show
  1. package/README.md +46 -134
  2. package/dist/cli.js +48 -6
  3. package/dist/headless-query.js +11 -1
  4. package/dist/help-text.js +4 -1
  5. package/dist/onboarding.js +15 -8
  6. package/dist/resource-loader.js +18 -3
  7. package/dist/resources/extensions/cmux/index.js +21 -12
  8. package/dist/resources/extensions/gsd/auto/detect-stuck.js +27 -0
  9. package/dist/resources/extensions/gsd/auto/finalize-timeout.js +40 -0
  10. package/dist/resources/extensions/gsd/auto/loop.js +4 -0
  11. package/dist/resources/extensions/gsd/auto/phases.js +157 -22
  12. package/dist/resources/extensions/gsd/auto/session.js +12 -0
  13. package/dist/resources/extensions/gsd/auto-dashboard.js +14 -8
  14. package/dist/resources/extensions/gsd/auto-model-selection.js +32 -0
  15. package/dist/resources/extensions/gsd/auto-post-unit.js +222 -11
  16. package/dist/resources/extensions/gsd/auto-prompts.js +25 -0
  17. package/dist/resources/extensions/gsd/auto-recovery.js +15 -7
  18. package/dist/resources/extensions/gsd/auto-start.js +10 -21
  19. package/dist/resources/extensions/gsd/auto-timers.js +2 -1
  20. package/dist/resources/extensions/gsd/auto-tool-tracking.js +17 -0
  21. package/dist/resources/extensions/gsd/auto-verification.js +138 -1
  22. package/dist/resources/extensions/gsd/auto-worktree.js +13 -7
  23. package/dist/resources/extensions/gsd/auto.js +24 -2
  24. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +147 -75
  25. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +13 -0
  26. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +85 -0
  27. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +3 -0
  28. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +32 -1
  29. package/dist/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.js +54 -0
  30. package/dist/resources/extensions/gsd/bootstrap/system-context.js +30 -2
  31. package/dist/resources/extensions/gsd/commands-handlers.js +9 -4
  32. package/dist/resources/extensions/gsd/constants.js +42 -0
  33. package/dist/resources/extensions/gsd/db-writer.js +72 -4
  34. package/dist/resources/extensions/gsd/forensics.js +20 -4
  35. package/dist/resources/extensions/gsd/gsd-db.js +64 -17
  36. package/dist/resources/extensions/gsd/guided-flow.js +19 -0
  37. package/dist/resources/extensions/gsd/metrics.js +27 -1
  38. package/dist/resources/extensions/gsd/native-git-bridge.js +5 -3
  39. package/dist/resources/extensions/gsd/post-execution-checks.js +407 -0
  40. package/dist/resources/extensions/gsd/pre-execution-checks.js +464 -0
  41. package/dist/resources/extensions/gsd/preferences-types.js +6 -0
  42. package/dist/resources/extensions/gsd/preferences-validation.js +33 -0
  43. package/dist/resources/extensions/gsd/preferences.js +11 -2
  44. package/dist/resources/extensions/gsd/prompt-loader.js +7 -0
  45. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
  46. package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -0
  47. package/dist/resources/extensions/gsd/prompts/doctor-heal.md +1 -0
  48. package/dist/resources/extensions/gsd/prompts/forensics.md +2 -0
  49. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +2 -0
  50. package/dist/resources/extensions/gsd/prompts/system.md +4 -7
  51. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
  52. package/dist/resources/extensions/gsd/roadmap-mutations.js +1 -1
  53. package/dist/resources/extensions/gsd/roadmap-slices.js +9 -5
  54. package/dist/resources/extensions/gsd/safety/content-validator.js +73 -0
  55. package/dist/resources/extensions/gsd/safety/destructive-guard.js +34 -0
  56. package/dist/resources/extensions/gsd/safety/evidence-collector.js +109 -0
  57. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +83 -0
  58. package/dist/resources/extensions/gsd/safety/file-change-validator.js +71 -0
  59. package/dist/resources/extensions/gsd/safety/git-checkpoint.js +91 -0
  60. package/dist/resources/extensions/gsd/safety/safety-harness.js +64 -0
  61. package/dist/resources/extensions/gsd/slice-parallel-conflict.js +67 -0
  62. package/dist/resources/extensions/gsd/slice-parallel-eligibility.js +51 -0
  63. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +378 -0
  64. package/dist/resources/extensions/gsd/state.js +74 -14
  65. package/dist/resources/extensions/gsd/status-guards.js +11 -0
  66. package/dist/resources/extensions/gsd/tools/complete-milestone.js +17 -12
  67. package/dist/resources/extensions/gsd/tools/complete-slice.js +40 -26
  68. package/dist/resources/extensions/gsd/tools/complete-task.js +12 -12
  69. package/dist/resources/extensions/gsd/tools/plan-milestone.js +33 -25
  70. package/dist/resources/extensions/gsd/tools/plan-slice.js +5 -8
  71. package/dist/resources/extensions/gsd/verification-evidence.js +18 -0
  72. package/dist/resources/extensions/gsd/workflow-projections.js +21 -5
  73. package/dist/resources/extensions/gsd/worktree-manager.js +82 -29
  74. package/dist/resources/extensions/gsd/worktree-resolver.js +4 -3
  75. package/dist/resources/extensions/mcp-client/auth.js +101 -0
  76. package/dist/resources/extensions/mcp-client/index.js +10 -1
  77. package/dist/resources/extensions/ollama/index.js +28 -22
  78. package/dist/resources/extensions/ollama/model-capabilities.js +37 -34
  79. package/dist/resources/extensions/ollama/ndjson-stream.js +54 -0
  80. package/dist/resources/extensions/ollama/ollama-chat-provider.js +380 -0
  81. package/dist/resources/extensions/ollama/ollama-client.js +23 -32
  82. package/dist/resources/extensions/ollama/ollama-discovery.js +2 -7
  83. package/dist/resources/extensions/ollama/ollama-tool.js +62 -0
  84. package/dist/resources/extensions/ollama/thinking-parser.js +104 -0
  85. package/dist/update-cmd.js +4 -2
  86. package/dist/web/standalone/.next/BUILD_ID +1 -1
  87. package/dist/web/standalone/.next/app-path-routes-manifest.json +15 -15
  88. package/dist/web/standalone/.next/build-manifest.json +3 -3
  89. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  90. package/dist/web/standalone/.next/required-server-files.json +4 -4
  91. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  92. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  93. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  94. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  102. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  103. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  104. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  105. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  106. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  108. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  113. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  116. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  119. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  121. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  122. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  127. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  130. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  135. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  137. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  140. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  143. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  146. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  149. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  152. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  155. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  158. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  161. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  164. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  167. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  172. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  175. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  177. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  180. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  183. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  185. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  186. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  189. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  192. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  197. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  200. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  203. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  204. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  205. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  207. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  209. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  210. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  212. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  213. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  214. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  217. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  218. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  219. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  220. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  221. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  222. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  223. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  224. package/dist/web/standalone/.next/server/app/index.html +1 -1
  225. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  226. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  227. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  228. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  229. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  230. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  231. package/dist/web/standalone/.next/server/app/page.js +2 -2
  232. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  233. package/dist/web/standalone/.next/server/app-paths-manifest.json +15 -15
  234. package/dist/web/standalone/.next/server/chunks/6897.js +12 -0
  235. package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
  236. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  237. package/dist/web/standalone/.next/server/middleware.js +2 -2
  238. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  239. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  240. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  241. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  242. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  243. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  244. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  245. package/dist/web/standalone/.next/static/chunks/app/page-0c485498795110d6.js +1 -0
  246. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  247. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  248. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  249. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  250. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  251. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  252. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  253. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  254. package/dist/web/standalone/server.js +1 -1
  255. package/dist/welcome-screen.js +1 -1
  256. package/package.json +1 -1
  257. package/packages/pi-agent-core/dist/agent-loop.d.ts +8 -0
  258. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  259. package/packages/pi-agent-core/dist/agent-loop.js +50 -0
  260. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  261. package/packages/pi-agent-core/src/agent-loop.test.ts +221 -5
  262. package/packages/pi-agent-core/src/agent-loop.ts +53 -0
  263. package/packages/pi-ai/dist/types.d.ts +16 -1
  264. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  265. package/packages/pi-ai/dist/types.js.map +1 -1
  266. package/packages/pi-ai/src/types.ts +18 -1
  267. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +9 -0
  268. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  269. package/packages/pi-coding-agent/dist/core/auth-storage.js +50 -1
  270. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  271. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +41 -0
  272. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  273. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +7 -0
  274. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  275. package/packages/pi-coding-agent/dist/core/extensions/loader.js +31 -4
  276. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  277. package/packages/pi-coding-agent/dist/core/extensions/loader.test.js +28 -1
  278. package/packages/pi-coding-agent/dist/core/extensions/loader.test.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/core/extensions/provider-registration.test.d.ts +2 -0
  280. package/packages/pi-coding-agent/dist/core/extensions/provider-registration.test.d.ts.map +1 -0
  281. package/packages/pi-coding-agent/dist/core/extensions/provider-registration.test.js +46 -0
  282. package/packages/pi-coding-agent/dist/core/extensions/provider-registration.test.js.map +1 -0
  283. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +2 -0
  284. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  285. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  286. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +1 -0
  287. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  288. package/packages/pi-coding-agent/dist/core/model-registry.js +12 -0
  289. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  290. package/packages/pi-coding-agent/dist/core/model-resolver.js +3 -3
  291. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  292. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +23 -1
  293. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  294. package/packages/pi-coding-agent/dist/core/resource-loader.js +80 -56
  295. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  296. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  297. package/packages/pi-coding-agent/dist/core/sdk.js +9 -0
  298. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  299. package/packages/pi-coding-agent/package.json +1 -1
  300. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +53 -0
  301. package/packages/pi-coding-agent/src/core/auth-storage.ts +66 -1
  302. package/packages/pi-coding-agent/src/core/extensions/loader.test.ts +39 -1
  303. package/packages/pi-coding-agent/src/core/extensions/loader.ts +34 -4
  304. package/packages/pi-coding-agent/src/core/extensions/provider-registration.test.ts +81 -0
  305. package/packages/pi-coding-agent/src/core/extensions/types.ts +2 -0
  306. package/packages/pi-coding-agent/src/core/model-registry.ts +14 -0
  307. package/packages/pi-coding-agent/src/core/model-resolver.ts +3 -3
  308. package/packages/pi-coding-agent/src/core/resource-loader.ts +89 -56
  309. package/packages/pi-coding-agent/src/core/sdk.ts +10 -0
  310. package/pkg/package.json +1 -1
  311. package/src/resources/extensions/cmux/index.ts +18 -12
  312. package/src/resources/extensions/gsd/auto/detect-stuck.ts +27 -0
  313. package/src/resources/extensions/gsd/auto/finalize-timeout.ts +46 -0
  314. package/src/resources/extensions/gsd/auto/loop.ts +5 -0
  315. package/src/resources/extensions/gsd/auto/phases.ts +194 -33
  316. package/src/resources/extensions/gsd/auto/session.ts +14 -0
  317. package/src/resources/extensions/gsd/auto-dashboard.ts +16 -7
  318. package/src/resources/extensions/gsd/auto-model-selection.ts +36 -0
  319. package/src/resources/extensions/gsd/auto-post-unit.ts +263 -12
  320. package/src/resources/extensions/gsd/auto-prompts.ts +21 -0
  321. package/src/resources/extensions/gsd/auto-recovery.ts +9 -8
  322. package/src/resources/extensions/gsd/auto-start.ts +11 -20
  323. package/src/resources/extensions/gsd/auto-timers.ts +2 -1
  324. package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
  325. package/src/resources/extensions/gsd/auto-verification.ts +190 -2
  326. package/src/resources/extensions/gsd/auto-worktree.ts +14 -6
  327. package/src/resources/extensions/gsd/auto.ts +26 -1
  328. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +160 -88
  329. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +15 -0
  330. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +98 -0
  331. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +4 -0
  332. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +36 -1
  333. package/src/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.ts +57 -0
  334. package/src/resources/extensions/gsd/bootstrap/system-context.ts +31 -2
  335. package/src/resources/extensions/gsd/commands-handlers.ts +10 -4
  336. package/src/resources/extensions/gsd/constants.ts +44 -0
  337. package/src/resources/extensions/gsd/db-writer.ts +78 -4
  338. package/src/resources/extensions/gsd/forensics.ts +21 -5
  339. package/src/resources/extensions/gsd/gsd-db.ts +64 -17
  340. package/src/resources/extensions/gsd/guided-flow.ts +22 -0
  341. package/src/resources/extensions/gsd/metrics.ts +28 -1
  342. package/src/resources/extensions/gsd/native-git-bridge.ts +5 -3
  343. package/src/resources/extensions/gsd/post-execution-checks.ts +539 -0
  344. package/src/resources/extensions/gsd/pre-execution-checks.ts +573 -0
  345. package/src/resources/extensions/gsd/preferences-types.ts +44 -0
  346. package/src/resources/extensions/gsd/preferences-validation.ts +33 -0
  347. package/src/resources/extensions/gsd/preferences.ts +13 -2
  348. package/src/resources/extensions/gsd/prompt-loader.ts +8 -0
  349. package/src/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
  350. package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -0
  351. package/src/resources/extensions/gsd/prompts/doctor-heal.md +1 -0
  352. package/src/resources/extensions/gsd/prompts/forensics.md +2 -0
  353. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +2 -0
  354. package/src/resources/extensions/gsd/prompts/system.md +4 -7
  355. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
  356. package/src/resources/extensions/gsd/roadmap-mutations.ts +1 -1
  357. package/src/resources/extensions/gsd/roadmap-slices.ts +10 -5
  358. package/src/resources/extensions/gsd/safety/content-validator.ts +98 -0
  359. package/src/resources/extensions/gsd/safety/destructive-guard.ts +49 -0
  360. package/src/resources/extensions/gsd/safety/evidence-collector.ts +151 -0
  361. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +120 -0
  362. package/src/resources/extensions/gsd/safety/file-change-validator.ts +108 -0
  363. package/src/resources/extensions/gsd/safety/git-checkpoint.ts +106 -0
  364. package/src/resources/extensions/gsd/safety/safety-harness.ts +105 -0
  365. package/src/resources/extensions/gsd/slice-parallel-conflict.ts +86 -0
  366. package/src/resources/extensions/gsd/slice-parallel-eligibility.ts +73 -0
  367. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +477 -0
  368. package/src/resources/extensions/gsd/state.ts +67 -12
  369. package/src/resources/extensions/gsd/status-guards.ts +13 -0
  370. package/src/resources/extensions/gsd/tests/artifact-corruption-2630.test.ts +288 -0
  371. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +34 -13
  372. package/src/resources/extensions/gsd/tests/auto-start-time-persistence.test.ts +50 -0
  373. package/src/resources/extensions/gsd/tests/cmux.test.ts +58 -0
  374. package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +51 -0
  375. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +140 -0
  376. package/src/resources/extensions/gsd/tests/complete-slice-string-coercion.test.ts +211 -0
  377. package/src/resources/extensions/gsd/tests/complete-task.test.ts +39 -0
  378. package/src/resources/extensions/gsd/tests/dashboard-model-label-ordering.test.ts +107 -0
  379. package/src/resources/extensions/gsd/tests/db-access-guardrails.test.ts +109 -0
  380. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +13 -9
  381. package/src/resources/extensions/gsd/tests/db-writer.test.ts +134 -0
  382. package/src/resources/extensions/gsd/tests/deferred-slice-dispatch.test.ts +203 -0
  383. package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +130 -0
  384. package/src/resources/extensions/gsd/tests/doctor-fix-flag.test.ts +92 -0
  385. package/src/resources/extensions/gsd/tests/enhanced-verification-integration.test.ts +526 -0
  386. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +116 -0
  387. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +50 -0
  388. package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +103 -0
  389. package/src/resources/extensions/gsd/tests/git-checkpoint.test.ts +94 -0
  390. package/src/resources/extensions/gsd/tests/insert-slice-no-wipe.test.ts +88 -0
  391. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +27 -7
  392. package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +34 -0
  393. package/src/resources/extensions/gsd/tests/metrics.test.ts +116 -1
  394. package/src/resources/extensions/gsd/tests/milestone-status-tool.test.ts +201 -0
  395. package/src/resources/extensions/gsd/tests/plan-milestone-title.test.ts +2 -1
  396. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +82 -18
  397. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +312 -0
  398. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +813 -0
  399. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +999 -0
  400. package/src/resources/extensions/gsd/tests/pre-execution-fail-closed.test.ts +266 -0
  401. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +457 -0
  402. package/src/resources/extensions/gsd/tests/preferences.test.ts +10 -0
  403. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +25 -0
  404. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +69 -0
  405. package/src/resources/extensions/gsd/tests/shared-wal.test.ts +30 -0
  406. package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +50 -0
  407. package/src/resources/extensions/gsd/tests/slice-parallel-conflict.test.ts +92 -0
  408. package/src/resources/extensions/gsd/tests/slice-parallel-eligibility.test.ts +95 -0
  409. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +83 -0
  410. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +42 -0
  411. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +103 -0
  412. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +349 -0
  413. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +35 -2
  414. package/src/resources/extensions/gsd/tests/worktree-health-monorepo.test.ts +73 -0
  415. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +34 -0
  416. package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +1 -1
  417. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +148 -0
  418. package/src/resources/extensions/gsd/tools/complete-milestone.ts +34 -20
  419. package/src/resources/extensions/gsd/tools/complete-slice.ts +41 -26
  420. package/src/resources/extensions/gsd/tools/complete-task.ts +12 -12
  421. package/src/resources/extensions/gsd/tools/plan-milestone.ts +55 -30
  422. package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -8
  423. package/src/resources/extensions/gsd/types.ts +44 -22
  424. package/src/resources/extensions/gsd/verification-evidence.ts +68 -0
  425. package/src/resources/extensions/gsd/workflow-logger.ts +2 -1
  426. package/src/resources/extensions/gsd/workflow-projections.ts +23 -5
  427. package/src/resources/extensions/gsd/worktree-manager.ts +76 -28
  428. package/src/resources/extensions/gsd/worktree-resolver.ts +4 -3
  429. package/src/resources/extensions/mcp-client/auth.ts +149 -0
  430. package/src/resources/extensions/mcp-client/index.ts +16 -1
  431. package/src/resources/extensions/ollama/index.ts +26 -25
  432. package/src/resources/extensions/ollama/model-capabilities.ts +41 -34
  433. package/src/resources/extensions/ollama/ndjson-stream.ts +63 -0
  434. package/src/resources/extensions/ollama/ollama-auth-mode.test.ts +20 -0
  435. package/src/resources/extensions/ollama/ollama-chat-provider.ts +459 -0
  436. package/src/resources/extensions/ollama/ollama-client.ts +30 -30
  437. package/src/resources/extensions/ollama/ollama-discovery.ts +5 -8
  438. package/src/resources/extensions/ollama/ollama-tool.ts +69 -0
  439. package/src/resources/extensions/ollama/tests/ollama-chat-provider-stream.test.ts +82 -0
  440. package/src/resources/extensions/ollama/tests/ollama-discovery.test.ts +0 -27
  441. package/src/resources/extensions/ollama/thinking-parser.ts +116 -0
  442. package/src/resources/extensions/ollama/types.ts +23 -0
  443. package/dist/web/standalone/.next/server/chunks/2229.js +0 -12
  444. package/dist/web/standalone/.next/static/chunks/app/page-62be3b5fa91e4c8f.js +0 -1
  445. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  446. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  447. /package/dist/web/standalone/.next/static/{5FLUBNdqolRyyehCyChPd → SoxM61WC_ia7R2gk4VMpJ}/_buildManifest.js +0 -0
  448. /package/dist/web/standalone/.next/static/{5FLUBNdqolRyyehCyChPd → SoxM61WC_ia7R2gk4VMpJ}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"auth-storage.test.js","sourceRoot":"","sources":["../../src/core/auth-storage.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, it } from \"node:test\";\nimport assert from \"node:assert/strict\";\nimport { AuthStorage } from \"./auth-storage.js\";\n\n// ─── helpers ──────────────────────────────────────────────────────────────────\n\nfunction makeKey(key: string) {\n\treturn { type: \"api_key\" as const, key };\n}\n\nfunction inMemory(data: Record<string, unknown> = {}) {\n\treturn AuthStorage.inMemory(data as any);\n}\n\n// ─── single credential (backward compat) ─────────────────────────────────────\n\ndescribe(\"AuthStorage — single credential (backward compat)\", () => {\n\tit(\"returns the api key for a provider with one key\", async () => {\n\t\tconst storage = inMemory({ anthropic: makeKey(\"sk-abc\") });\n\t\tconst key = await storage.getApiKey(\"anthropic\");\n\t\tassert.equal(key, \"sk-abc\");\n\t});\n\n\tit(\"returns undefined for unknown provider\", async () => {\n\t\tconst storage = inMemory({});\n\t\tconst key = await storage.getApiKey(\"unknown\");\n\t\tassert.equal(key, undefined);\n\t});\n\n\tit(\"runtime override takes precedence over stored key\", async () => {\n\t\tconst storage = inMemory({ anthropic: makeKey(\"sk-stored\") });\n\t\tstorage.setRuntimeApiKey(\"anthropic\", \"sk-runtime\");\n\t\tconst key = await storage.getApiKey(\"anthropic\");\n\t\tassert.equal(key, \"sk-runtime\");\n\t});\n});\n\n// ─── multiple credentials ─────────────────────────────────────────────────────\n\ndescribe(\"AuthStorage — multiple credentials\", () => {\n\tit(\"round-robins across multiple api keys without sessionId\", async () => {\n\t\tconst storage = inMemory({\n\t\t\tanthropic: [makeKey(\"sk-1\"), makeKey(\"sk-2\"), makeKey(\"sk-3\")],\n\t\t});\n\n\t\tconst keys = new Set<string>();\n\t\tfor (let i = 0; i < 6; i++) {\n\t\t\tconst k = await storage.getApiKey(\"anthropic\");\n\t\t\tassert.ok(k, `call ${i} should return a key`);\n\t\t\tkeys.add(k);\n\t\t}\n\t\t// All three keys should have been selected across 6 calls\n\t\tassert.deepEqual(keys, new Set([\"sk-1\", \"sk-2\", \"sk-3\"]));\n\t});\n\n\tit(\"session-sticky: same sessionId always picks the same key\", async () => {\n\t\tconst storage = inMemory({\n\t\t\tanthropic: [makeKey(\"sk-1\"), makeKey(\"sk-2\"), makeKey(\"sk-3\")],\n\t\t});\n\n\t\tconst sessionId = \"sess-abc\";\n\t\tconst first = await storage.getApiKey(\"anthropic\", sessionId);\n\t\tfor (let i = 0; i < 5; i++) {\n\t\t\tconst k = await storage.getApiKey(\"anthropic\", sessionId);\n\t\t\tassert.equal(k, first, `call ${i} should be sticky to first selection`);\n\t\t}\n\t});\n\n\tit(\"different sessionIds may select different keys\", async () => {\n\t\tconst storage = inMemory({\n\t\t\tanthropic: [makeKey(\"sk-1\"), makeKey(\"sk-2\"), makeKey(\"sk-3\")],\n\t\t});\n\n\t\tconst results = new Set<string>();\n\t\tfor (let i = 0; i < 20; i++) {\n\t\t\tconst k = await storage.getApiKey(\"anthropic\", `sess-${i}`);\n\t\t\tif (k) results.add(k);\n\t\t}\n\t\t// With 20 different sessions and 3 keys, we should see more than one key\n\t\tassert.ok(results.size > 1, \"multiple sessions should hash to different keys\");\n\t});\n});\n\n// ─── login accumulation ───────────────────────────────────────────────────────\n\ndescribe(\"AuthStorage — login accumulation\", () => {\n\tit(\"accumulates api keys on repeated set()\", () => {\n\t\tconst storage = inMemory({});\n\t\tstorage.set(\"anthropic\", makeKey(\"sk-1\"));\n\t\tstorage.set(\"anthropic\", makeKey(\"sk-2\"));\n\t\tconst creds = storage.getCredentialsForProvider(\"anthropic\");\n\t\tassert.equal(creds.length, 2);\n\t\tassert.deepEqual(\n\t\t\tcreds.map((c) => (c.type === \"api_key\" ? c.key : null)),\n\t\t\t[\"sk-1\", \"sk-2\"],\n\t\t);\n\t});\n\n\tit(\"deduplicates identical api keys\", () => {\n\t\tconst storage = inMemory({});\n\t\tstorage.set(\"anthropic\", makeKey(\"sk-1\"));\n\t\tstorage.set(\"anthropic\", makeKey(\"sk-1\"));\n\t\tconst creds = storage.getCredentialsForProvider(\"anthropic\");\n\t\tassert.equal(creds.length, 1);\n\t});\n});\n\n// ─── backoff / markUsageLimitReached ─────────────────────────────────────────\n\ndescribe(\"AuthStorage — rate-limit backoff\", () => {\n\tit(\"returns true when a backed-off credential has an alternate\", async () => {\n\t\tconst storage = inMemory({\n\t\t\tanthropic: [makeKey(\"sk-1\"), makeKey(\"sk-2\")],\n\t\t});\n\n\t\t// Use sk-1 via round-robin (first call, index 0)\n\t\tawait storage.getApiKey(\"anthropic\");\n\n\t\t// Mark it as rate-limited; sk-2 should still be available\n\t\tconst hasAlternate = storage.markUsageLimitReached(\"anthropic\");\n\t\tassert.equal(hasAlternate, true);\n\t});\n\n\tit(\"returns false when all credentials are backed off\", async () => {\n\t\tconst storage = inMemory({\n\t\t\tanthropic: [makeKey(\"sk-1\"), makeKey(\"sk-2\")],\n\t\t});\n\n\t\t// Back off both keys\n\t\tawait storage.getApiKey(\"anthropic\"); // uses index 0\n\t\tstorage.markUsageLimitReached(\"anthropic\"); // backs off index 0\n\t\tawait storage.getApiKey(\"anthropic\"); // uses index 1\n\t\tconst hasAlternate = storage.markUsageLimitReached(\"anthropic\"); // backs off index 1\n\t\tassert.equal(hasAlternate, false);\n\t});\n\n\tit(\"backed-off credential is skipped; next available key is returned\", async () => {\n\t\tconst storage = inMemory({\n\t\t\tanthropic: [makeKey(\"sk-1\"), makeKey(\"sk-2\")],\n\t\t});\n\n\t\t// First call → sk-1 (round-robin index 0)\n\t\tconst first = await storage.getApiKey(\"anthropic\");\n\t\tassert.equal(first, \"sk-1\");\n\n\t\t// Back off sk-1\n\t\tstorage.markUsageLimitReached(\"anthropic\");\n\n\t\t// Next call should skip backed-off sk-1 and return sk-2\n\t\tconst second = await storage.getApiKey(\"anthropic\");\n\t\tassert.equal(second, \"sk-2\");\n\t});\n\n\tit(\"single credential: markUsageLimitReached returns false\", async () => {\n\t\tconst storage = inMemory({ anthropic: makeKey(\"sk-only\") });\n\t\tawait storage.getApiKey(\"anthropic\");\n\t\tconst hasAlternate = storage.markUsageLimitReached(\"anthropic\");\n\t\tassert.equal(hasAlternate, false);\n\t});\n\n\tit(\"single credential: unknown error type skips backoff entirely\", async () => {\n\t\tconst storage = inMemory({ anthropic: makeKey(\"sk-only\") });\n\t\tawait storage.getApiKey(\"anthropic\");\n\n\t\t// Mark with unknown error type (transport failure)\n\t\tconst hasAlternate = storage.markUsageLimitReached(\"anthropic\", undefined, {\n\t\t\terrorType: \"unknown\",\n\t\t});\n\t\tassert.equal(hasAlternate, false);\n\n\t\t// Key should still be available — backoff was not applied\n\t\tconst key = await storage.getApiKey(\"anthropic\");\n\t\tassert.equal(key, \"sk-only\");\n\t});\n\n\tit(\"multiple credentials: unknown error type still backs off the used credential\", async () => {\n\t\tconst storage = inMemory({\n\t\t\tanthropic: [makeKey(\"sk-1\"), makeKey(\"sk-2\")],\n\t\t});\n\t\tawait storage.getApiKey(\"anthropic\"); // uses sk-1\n\n\t\t// Mark with unknown error type — should still back off when alternates exist\n\t\tconst hasAlternate = storage.markUsageLimitReached(\"anthropic\", undefined, {\n\t\t\terrorType: \"unknown\",\n\t\t});\n\t\tassert.equal(hasAlternate, true);\n\n\t\t// Next call should return sk-2\n\t\tconst key = await storage.getApiKey(\"anthropic\");\n\t\tassert.equal(key, \"sk-2\");\n\t});\n\n\tit(\"single credential: rate_limit error type still backs off\", async () => {\n\t\tconst storage = inMemory({ anthropic: makeKey(\"sk-only\") });\n\t\tawait storage.getApiKey(\"anthropic\");\n\n\t\t// rate_limit should still back off even single credentials\n\t\tconst hasAlternate = storage.markUsageLimitReached(\"anthropic\", undefined, {\n\t\t\terrorType: \"rate_limit\",\n\t\t});\n\t\tassert.equal(hasAlternate, false);\n\n\t\t// Key should be backed off\n\t\tconst key = await storage.getApiKey(\"anthropic\");\n\t\tassert.equal(key, undefined);\n\t});\n\n\tit(\"session-sticky: marks the correct credential as backed off\", async () => {\n\t\tconst storage = inMemory({\n\t\t\tanthropic: [makeKey(\"sk-1\"), makeKey(\"sk-2\")],\n\t\t});\n\n\t\tconst sessionId = \"sess-xyz\";\n\t\tconst chosen = await storage.getApiKey(\"anthropic\", sessionId);\n\t\tassert.ok(chosen);\n\n\t\t// Back off the chosen credential for this session\n\t\tconst hasAlternate = storage.markUsageLimitReached(\"anthropic\", sessionId);\n\t\tassert.equal(hasAlternate, true);\n\n\t\t// Next call with same session should return the other key\n\t\tconst next = await storage.getApiKey(\"anthropic\", sessionId);\n\t\tassert.ok(next);\n\t\tassert.notEqual(next, chosen);\n\t});\n});\n\n// ─── areAllCredentialsBackedOff ───────────────────────────────────────────────\n\ndescribe(\"AuthStorage — areAllCredentialsBackedOff\", () => {\n\tit(\"returns false when no credentials are configured\", () => {\n\t\tconst storage = inMemory({});\n\t\tassert.equal(storage.areAllCredentialsBackedOff(\"anthropic\"), false);\n\t});\n\n\tit(\"returns false when credentials exist and none are backed off\", async () => {\n\t\tconst storage = inMemory({ anthropic: makeKey(\"sk-abc\") });\n\t\tassert.equal(storage.areAllCredentialsBackedOff(\"anthropic\"), false);\n\t});\n\n\tit(\"returns true when the single credential is backed off\", async () => {\n\t\tconst storage = inMemory({ anthropic: makeKey(\"sk-only\") });\n\t\tawait storage.getApiKey(\"anthropic\");\n\t\tstorage.markUsageLimitReached(\"anthropic\");\n\t\tassert.equal(storage.areAllCredentialsBackedOff(\"anthropic\"), true);\n\t});\n\n\tit(\"returns false when at least one credential is still available\", async () => {\n\t\tconst storage = inMemory({ anthropic: [makeKey(\"sk-1\"), makeKey(\"sk-2\")] });\n\t\tawait storage.getApiKey(\"anthropic\"); // uses index 0\n\t\tstorage.markUsageLimitReached(\"anthropic\"); // backs off index 0\n\t\t// index 1 is still available\n\t\tassert.equal(storage.areAllCredentialsBackedOff(\"anthropic\"), false);\n\t});\n\n\tit(\"returns true when all credentials are backed off\", async () => {\n\t\tconst storage = inMemory({ anthropic: [makeKey(\"sk-1\"), makeKey(\"sk-2\")] });\n\t\tawait storage.getApiKey(\"anthropic\"); // uses index 0\n\t\tstorage.markUsageLimitReached(\"anthropic\"); // backs off index 0\n\t\tawait storage.getApiKey(\"anthropic\"); // uses index 1\n\t\tstorage.markUsageLimitReached(\"anthropic\"); // backs off index 1\n\t\tassert.equal(storage.areAllCredentialsBackedOff(\"anthropic\"), true);\n\t});\n});\n\n// ─── mismatched oauth credential for non-OAuth provider (#2083) ───────────────\n\ndescribe(\"AuthStorage — oauth credential for non-OAuth provider (#2083)\", () => {\n\tit(\"returns undefined when openrouter has type:oauth (no registered OAuth provider)\", async (t) => {\n\t\t// Simulates the bug: OpenRouter credential stored as type:\"oauth\"\n\t\t// but OpenRouter is not a registered OAuth provider.\n\t\tconst storage = inMemory({\n\t\t\topenrouter: {\n\t\t\t\ttype: \"oauth\",\n\t\t\t\taccess_token: \"sk-or-v1-fake\",\n\t\t\t\trefresh_token: \"rt-fake\",\n\t\t\t\texpires: Date.now() + 3_600_000,\n\t\t\t},\n\t\t});\n\n\t\t// Isolate from any real OPENROUTER_API_KEY in the environment so the\n\t\t// fall-through to env / fallback finds nothing and returns undefined.\n\t\tconst origEnv = process.env.OPENROUTER_API_KEY;\n\t\tdelete process.env.OPENROUTER_API_KEY;\n\t\tt.after(() => {\n\t\t\tif (origEnv === undefined) {\n\t\t\t\tdelete process.env.OPENROUTER_API_KEY;\n\t\t\t} else {\n\t\t\t\tprocess.env.OPENROUTER_API_KEY = origEnv;\n\t\t\t}\n\t\t});\n\n\t\t// Before the fix, getApiKey returns undefined because\n\t\t// resolveCredentialApiKey calls getOAuthProvider(\"openrouter\") → null → undefined.\n\t\t// The key in the oauth credential is never extracted.\n\t\tconst key = await storage.getApiKey(\"openrouter\");\n\t\t// After the fix, the oauth credential with an unrecognised provider\n\t\t// should be skipped, and getApiKey should fall through to env / fallback.\n\t\t// With no env var and no fallback resolver configured, the result is undefined.\n\t\tassert.equal(key, undefined);\n\t});\n\n\tit(\"falls through to env var when openrouter has type:oauth credential\", async (t) => {\n\t\tconst storage = inMemory({\n\t\t\topenrouter: {\n\t\t\t\ttype: \"oauth\",\n\t\t\t\taccess_token: \"sk-or-v1-fake\",\n\t\t\t\trefresh_token: \"rt-fake\",\n\t\t\t\texpires: Date.now() + 3_600_000,\n\t\t\t},\n\t\t});\n\n\t\t// Simulate OPENROUTER_API_KEY being set via env\n\t\tconst origEnv = process.env.OPENROUTER_API_KEY;\n\t\tt.after(() => {\n\t\t\tif (origEnv === undefined) {\n\t\t\t\tdelete process.env.OPENROUTER_API_KEY;\n\t\t\t} else {\n\t\t\t\tprocess.env.OPENROUTER_API_KEY = origEnv;\n\t\t\t}\n\t\t});\n\n\t\tprocess.env.OPENROUTER_API_KEY = \"sk-or-v1-env-key\";\n\t\tconst key = await storage.getApiKey(\"openrouter\");\n\t\tassert.equal(key, \"sk-or-v1-env-key\");\n\t});\n\n\tit(\"falls through to fallback resolver when openrouter has type:oauth credential\", async (t) => {\n\t\tconst storage = inMemory({\n\t\t\topenrouter: {\n\t\t\t\ttype: \"oauth\",\n\t\t\t\taccess_token: \"sk-or-v1-fake\",\n\t\t\t\trefresh_token: \"rt-fake\",\n\t\t\t\texpires: Date.now() + 3_600_000,\n\t\t\t},\n\t\t});\n\n\t\t// Isolate from any real OPENROUTER_API_KEY so env fallback is skipped\n\t\t// and the fallback resolver is reached.\n\t\tconst origEnv = process.env.OPENROUTER_API_KEY;\n\t\tdelete process.env.OPENROUTER_API_KEY;\n\t\tt.after(() => {\n\t\t\tif (origEnv === undefined) {\n\t\t\t\tdelete process.env.OPENROUTER_API_KEY;\n\t\t\t} else {\n\t\t\t\tprocess.env.OPENROUTER_API_KEY = origEnv;\n\t\t\t}\n\t\t});\n\n\t\tstorage.setFallbackResolver((provider) =>\n\t\t\tprovider === \"openrouter\" ? \"sk-or-v1-fallback\" : undefined,\n\t\t);\n\n\t\tconst key = await storage.getApiKey(\"openrouter\");\n\t\tassert.equal(key, \"sk-or-v1-fallback\");\n\t});\n});\n\n// ─── getAll truncation ────────────────────────────────────────────────────────\n\ndescribe(\"AuthStorage — getAll()\", () => {\n\tit(\"returns first credential only for providers with multiple keys\", () => {\n\t\tconst storage = inMemory({\n\t\t\tanthropic: [makeKey(\"sk-1\"), makeKey(\"sk-2\")],\n\t\t\topenai: makeKey(\"sk-openai\"),\n\t\t});\n\t\tconst all = storage.getAll();\n\t\tassert.ok(all[\"anthropic\"]?.type === \"api_key\");\n\t\tassert.equal((all[\"anthropic\"] as any).key, \"sk-1\");\n\t\tassert.equal((all[\"openai\"] as any).key, \"sk-openai\");\n\t});\n});\n"]}
1
+ {"version":3,"file":"auth-storage.test.js","sourceRoot":"","sources":["../../src/core/auth-storage.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, it } from \"node:test\";\nimport assert from \"node:assert/strict\";\nimport { AuthStorage } from \"./auth-storage.js\";\n\n// ─── helpers ──────────────────────────────────────────────────────────────────\n\nfunction makeKey(key: string) {\n\treturn { type: \"api_key\" as const, key };\n}\n\nfunction inMemory(data: Record<string, unknown> = {}) {\n\treturn AuthStorage.inMemory(data as any);\n}\n\n// ─── single credential (backward compat) ─────────────────────────────────────\n\ndescribe(\"AuthStorage — single credential (backward compat)\", () => {\n\tit(\"returns the api key for a provider with one key\", async () => {\n\t\tconst storage = inMemory({ anthropic: makeKey(\"sk-abc\") });\n\t\tconst key = await storage.getApiKey(\"anthropic\");\n\t\tassert.equal(key, \"sk-abc\");\n\t});\n\n\tit(\"returns undefined for unknown provider\", async () => {\n\t\tconst storage = inMemory({});\n\t\tconst key = await storage.getApiKey(\"unknown\");\n\t\tassert.equal(key, undefined);\n\t});\n\n\tit(\"runtime override takes precedence over stored key\", async () => {\n\t\tconst storage = inMemory({ anthropic: makeKey(\"sk-stored\") });\n\t\tstorage.setRuntimeApiKey(\"anthropic\", \"sk-runtime\");\n\t\tconst key = await storage.getApiKey(\"anthropic\");\n\t\tassert.equal(key, \"sk-runtime\");\n\t});\n});\n\n// ─── multiple credentials ─────────────────────────────────────────────────────\n\ndescribe(\"AuthStorage — multiple credentials\", () => {\n\tit(\"round-robins across multiple api keys without sessionId\", async () => {\n\t\tconst storage = inMemory({\n\t\t\tanthropic: [makeKey(\"sk-1\"), makeKey(\"sk-2\"), makeKey(\"sk-3\")],\n\t\t});\n\n\t\tconst keys = new Set<string>();\n\t\tfor (let i = 0; i < 6; i++) {\n\t\t\tconst k = await storage.getApiKey(\"anthropic\");\n\t\t\tassert.ok(k, `call ${i} should return a key`);\n\t\t\tkeys.add(k);\n\t\t}\n\t\t// All three keys should have been selected across 6 calls\n\t\tassert.deepEqual(keys, new Set([\"sk-1\", \"sk-2\", \"sk-3\"]));\n\t});\n\n\tit(\"session-sticky: same sessionId always picks the same key\", async () => {\n\t\tconst storage = inMemory({\n\t\t\tanthropic: [makeKey(\"sk-1\"), makeKey(\"sk-2\"), makeKey(\"sk-3\")],\n\t\t});\n\n\t\tconst sessionId = \"sess-abc\";\n\t\tconst first = await storage.getApiKey(\"anthropic\", sessionId);\n\t\tfor (let i = 0; i < 5; i++) {\n\t\t\tconst k = await storage.getApiKey(\"anthropic\", sessionId);\n\t\t\tassert.equal(k, first, `call ${i} should be sticky to first selection`);\n\t\t}\n\t});\n\n\tit(\"different sessionIds may select different keys\", async () => {\n\t\tconst storage = inMemory({\n\t\t\tanthropic: [makeKey(\"sk-1\"), makeKey(\"sk-2\"), makeKey(\"sk-3\")],\n\t\t});\n\n\t\tconst results = new Set<string>();\n\t\tfor (let i = 0; i < 20; i++) {\n\t\t\tconst k = await storage.getApiKey(\"anthropic\", `sess-${i}`);\n\t\t\tif (k) results.add(k);\n\t\t}\n\t\t// With 20 different sessions and 3 keys, we should see more than one key\n\t\tassert.ok(results.size > 1, \"multiple sessions should hash to different keys\");\n\t});\n});\n\n// ─── login accumulation ───────────────────────────────────────────────────────\n\ndescribe(\"AuthStorage — login accumulation\", () => {\n\tit(\"accumulates api keys on repeated set()\", () => {\n\t\tconst storage = inMemory({});\n\t\tstorage.set(\"anthropic\", makeKey(\"sk-1\"));\n\t\tstorage.set(\"anthropic\", makeKey(\"sk-2\"));\n\t\tconst creds = storage.getCredentialsForProvider(\"anthropic\");\n\t\tassert.equal(creds.length, 2);\n\t\tassert.deepEqual(\n\t\t\tcreds.map((c) => (c.type === \"api_key\" ? c.key : null)),\n\t\t\t[\"sk-1\", \"sk-2\"],\n\t\t);\n\t});\n\n\tit(\"deduplicates identical api keys\", () => {\n\t\tconst storage = inMemory({});\n\t\tstorage.set(\"anthropic\", makeKey(\"sk-1\"));\n\t\tstorage.set(\"anthropic\", makeKey(\"sk-1\"));\n\t\tconst creds = storage.getCredentialsForProvider(\"anthropic\");\n\t\tassert.equal(creds.length, 1);\n\t});\n});\n\n// ─── backoff / markUsageLimitReached ─────────────────────────────────────────\n\ndescribe(\"AuthStorage — rate-limit backoff\", () => {\n\tit(\"returns true when a backed-off credential has an alternate\", async () => {\n\t\tconst storage = inMemory({\n\t\t\tanthropic: [makeKey(\"sk-1\"), makeKey(\"sk-2\")],\n\t\t});\n\n\t\t// Use sk-1 via round-robin (first call, index 0)\n\t\tawait storage.getApiKey(\"anthropic\");\n\n\t\t// Mark it as rate-limited; sk-2 should still be available\n\t\tconst hasAlternate = storage.markUsageLimitReached(\"anthropic\");\n\t\tassert.equal(hasAlternate, true);\n\t});\n\n\tit(\"returns false when all credentials are backed off\", async () => {\n\t\tconst storage = inMemory({\n\t\t\tanthropic: [makeKey(\"sk-1\"), makeKey(\"sk-2\")],\n\t\t});\n\n\t\t// Back off both keys\n\t\tawait storage.getApiKey(\"anthropic\"); // uses index 0\n\t\tstorage.markUsageLimitReached(\"anthropic\"); // backs off index 0\n\t\tawait storage.getApiKey(\"anthropic\"); // uses index 1\n\t\tconst hasAlternate = storage.markUsageLimitReached(\"anthropic\"); // backs off index 1\n\t\tassert.equal(hasAlternate, false);\n\t});\n\n\tit(\"backed-off credential is skipped; next available key is returned\", async () => {\n\t\tconst storage = inMemory({\n\t\t\tanthropic: [makeKey(\"sk-1\"), makeKey(\"sk-2\")],\n\t\t});\n\n\t\t// First call → sk-1 (round-robin index 0)\n\t\tconst first = await storage.getApiKey(\"anthropic\");\n\t\tassert.equal(first, \"sk-1\");\n\n\t\t// Back off sk-1\n\t\tstorage.markUsageLimitReached(\"anthropic\");\n\n\t\t// Next call should skip backed-off sk-1 and return sk-2\n\t\tconst second = await storage.getApiKey(\"anthropic\");\n\t\tassert.equal(second, \"sk-2\");\n\t});\n\n\tit(\"single credential: markUsageLimitReached returns false\", async () => {\n\t\tconst storage = inMemory({ anthropic: makeKey(\"sk-only\") });\n\t\tawait storage.getApiKey(\"anthropic\");\n\t\tconst hasAlternate = storage.markUsageLimitReached(\"anthropic\");\n\t\tassert.equal(hasAlternate, false);\n\t});\n\n\tit(\"single credential: unknown error type skips backoff entirely\", async () => {\n\t\tconst storage = inMemory({ anthropic: makeKey(\"sk-only\") });\n\t\tawait storage.getApiKey(\"anthropic\");\n\n\t\t// Mark with unknown error type (transport failure)\n\t\tconst hasAlternate = storage.markUsageLimitReached(\"anthropic\", undefined, {\n\t\t\terrorType: \"unknown\",\n\t\t});\n\t\tassert.equal(hasAlternate, false);\n\n\t\t// Key should still be available — backoff was not applied\n\t\tconst key = await storage.getApiKey(\"anthropic\");\n\t\tassert.equal(key, \"sk-only\");\n\t});\n\n\tit(\"multiple credentials: unknown error type still backs off the used credential\", async () => {\n\t\tconst storage = inMemory({\n\t\t\tanthropic: [makeKey(\"sk-1\"), makeKey(\"sk-2\")],\n\t\t});\n\t\tawait storage.getApiKey(\"anthropic\"); // uses sk-1\n\n\t\t// Mark with unknown error type — should still back off when alternates exist\n\t\tconst hasAlternate = storage.markUsageLimitReached(\"anthropic\", undefined, {\n\t\t\terrorType: \"unknown\",\n\t\t});\n\t\tassert.equal(hasAlternate, true);\n\n\t\t// Next call should return sk-2\n\t\tconst key = await storage.getApiKey(\"anthropic\");\n\t\tassert.equal(key, \"sk-2\");\n\t});\n\n\tit(\"single credential: rate_limit error type still backs off\", async () => {\n\t\tconst storage = inMemory({ anthropic: makeKey(\"sk-only\") });\n\t\tawait storage.getApiKey(\"anthropic\");\n\n\t\t// rate_limit should still back off even single credentials\n\t\tconst hasAlternate = storage.markUsageLimitReached(\"anthropic\", undefined, {\n\t\t\terrorType: \"rate_limit\",\n\t\t});\n\t\tassert.equal(hasAlternate, false);\n\n\t\t// Key should be backed off\n\t\tconst key = await storage.getApiKey(\"anthropic\");\n\t\tassert.equal(key, undefined);\n\t});\n\n\tit(\"session-sticky: marks the correct credential as backed off\", async () => {\n\t\tconst storage = inMemory({\n\t\t\tanthropic: [makeKey(\"sk-1\"), makeKey(\"sk-2\")],\n\t\t});\n\n\t\tconst sessionId = \"sess-xyz\";\n\t\tconst chosen = await storage.getApiKey(\"anthropic\", sessionId);\n\t\tassert.ok(chosen);\n\n\t\t// Back off the chosen credential for this session\n\t\tconst hasAlternate = storage.markUsageLimitReached(\"anthropic\", sessionId);\n\t\tassert.equal(hasAlternate, true);\n\n\t\t// Next call with same session should return the other key\n\t\tconst next = await storage.getApiKey(\"anthropic\", sessionId);\n\t\tassert.ok(next);\n\t\tassert.notEqual(next, chosen);\n\t});\n});\n\n// ─── areAllCredentialsBackedOff ───────────────────────────────────────────────\n\ndescribe(\"AuthStorage — areAllCredentialsBackedOff\", () => {\n\tit(\"returns false when no credentials are configured\", () => {\n\t\tconst storage = inMemory({});\n\t\tassert.equal(storage.areAllCredentialsBackedOff(\"anthropic\"), false);\n\t});\n\n\tit(\"returns false when credentials exist and none are backed off\", async () => {\n\t\tconst storage = inMemory({ anthropic: makeKey(\"sk-abc\") });\n\t\tassert.equal(storage.areAllCredentialsBackedOff(\"anthropic\"), false);\n\t});\n\n\tit(\"returns true when the single credential is backed off\", async () => {\n\t\tconst storage = inMemory({ anthropic: makeKey(\"sk-only\") });\n\t\tawait storage.getApiKey(\"anthropic\");\n\t\tstorage.markUsageLimitReached(\"anthropic\");\n\t\tassert.equal(storage.areAllCredentialsBackedOff(\"anthropic\"), true);\n\t});\n\n\tit(\"returns false when at least one credential is still available\", async () => {\n\t\tconst storage = inMemory({ anthropic: [makeKey(\"sk-1\"), makeKey(\"sk-2\")] });\n\t\tawait storage.getApiKey(\"anthropic\"); // uses index 0\n\t\tstorage.markUsageLimitReached(\"anthropic\"); // backs off index 0\n\t\t// index 1 is still available\n\t\tassert.equal(storage.areAllCredentialsBackedOff(\"anthropic\"), false);\n\t});\n\n\tit(\"returns true when all credentials are backed off\", async () => {\n\t\tconst storage = inMemory({ anthropic: [makeKey(\"sk-1\"), makeKey(\"sk-2\")] });\n\t\tawait storage.getApiKey(\"anthropic\"); // uses index 0\n\t\tstorage.markUsageLimitReached(\"anthropic\"); // backs off index 0\n\t\tawait storage.getApiKey(\"anthropic\"); // uses index 1\n\t\tstorage.markUsageLimitReached(\"anthropic\"); // backs off index 1\n\t\tassert.equal(storage.areAllCredentialsBackedOff(\"anthropic\"), true);\n\t});\n});\n\n// ─── mismatched oauth credential for non-OAuth provider (#2083) ───────────────\n\ndescribe(\"AuthStorage — oauth credential for non-OAuth provider (#2083)\", () => {\n\tit(\"returns undefined when openrouter has type:oauth (no registered OAuth provider)\", async (t) => {\n\t\t// Simulates the bug: OpenRouter credential stored as type:\"oauth\"\n\t\t// but OpenRouter is not a registered OAuth provider.\n\t\tconst storage = inMemory({\n\t\t\topenrouter: {\n\t\t\t\ttype: \"oauth\",\n\t\t\t\taccess_token: \"sk-or-v1-fake\",\n\t\t\t\trefresh_token: \"rt-fake\",\n\t\t\t\texpires: Date.now() + 3_600_000,\n\t\t\t},\n\t\t});\n\n\t\t// Isolate from any real OPENROUTER_API_KEY in the environment so the\n\t\t// fall-through to env / fallback finds nothing and returns undefined.\n\t\tconst origEnv = process.env.OPENROUTER_API_KEY;\n\t\tdelete process.env.OPENROUTER_API_KEY;\n\t\tt.after(() => {\n\t\t\tif (origEnv === undefined) {\n\t\t\t\tdelete process.env.OPENROUTER_API_KEY;\n\t\t\t} else {\n\t\t\t\tprocess.env.OPENROUTER_API_KEY = origEnv;\n\t\t\t}\n\t\t});\n\n\t\t// Before the fix, getApiKey returns undefined because\n\t\t// resolveCredentialApiKey calls getOAuthProvider(\"openrouter\") → null → undefined.\n\t\t// The key in the oauth credential is never extracted.\n\t\tconst key = await storage.getApiKey(\"openrouter\");\n\t\t// After the fix, the oauth credential with an unrecognised provider\n\t\t// should be skipped, and getApiKey should fall through to env / fallback.\n\t\t// With no env var and no fallback resolver configured, the result is undefined.\n\t\tassert.equal(key, undefined);\n\t});\n\n\tit(\"falls through to env var when openrouter has type:oauth credential\", async (t) => {\n\t\tconst storage = inMemory({\n\t\t\topenrouter: {\n\t\t\t\ttype: \"oauth\",\n\t\t\t\taccess_token: \"sk-or-v1-fake\",\n\t\t\t\trefresh_token: \"rt-fake\",\n\t\t\t\texpires: Date.now() + 3_600_000,\n\t\t\t},\n\t\t});\n\n\t\t// Simulate OPENROUTER_API_KEY being set via env\n\t\tconst origEnv = process.env.OPENROUTER_API_KEY;\n\t\tt.after(() => {\n\t\t\tif (origEnv === undefined) {\n\t\t\t\tdelete process.env.OPENROUTER_API_KEY;\n\t\t\t} else {\n\t\t\t\tprocess.env.OPENROUTER_API_KEY = origEnv;\n\t\t\t}\n\t\t});\n\n\t\tprocess.env.OPENROUTER_API_KEY = \"sk-or-v1-env-key\";\n\t\tconst key = await storage.getApiKey(\"openrouter\");\n\t\tassert.equal(key, \"sk-or-v1-env-key\");\n\t});\n\n\tit(\"falls through to fallback resolver when openrouter has type:oauth credential\", async (t) => {\n\t\tconst storage = inMemory({\n\t\t\topenrouter: {\n\t\t\t\ttype: \"oauth\",\n\t\t\t\taccess_token: \"sk-or-v1-fake\",\n\t\t\t\trefresh_token: \"rt-fake\",\n\t\t\t\texpires: Date.now() + 3_600_000,\n\t\t\t},\n\t\t});\n\n\t\t// Isolate from any real OPENROUTER_API_KEY so env fallback is skipped\n\t\t// and the fallback resolver is reached.\n\t\tconst origEnv = process.env.OPENROUTER_API_KEY;\n\t\tdelete process.env.OPENROUTER_API_KEY;\n\t\tt.after(() => {\n\t\t\tif (origEnv === undefined) {\n\t\t\t\tdelete process.env.OPENROUTER_API_KEY;\n\t\t\t} else {\n\t\t\t\tprocess.env.OPENROUTER_API_KEY = origEnv;\n\t\t\t}\n\t\t});\n\n\t\tstorage.setFallbackResolver((provider) =>\n\t\t\tprovider === \"openrouter\" ? \"sk-or-v1-fallback\" : undefined,\n\t\t);\n\n\t\tconst key = await storage.getApiKey(\"openrouter\");\n\t\tassert.equal(key, \"sk-or-v1-fallback\");\n\t});\n});\n\n// ─── Gemini CLI OAuth token detection ─────────────────────────────────────────\n\ndescribe(\"AuthStorage — Gemini CLI OAuth token detection\", () => {\n\tit(\"rejects Google OAuth access token (ya29. prefix) stored as api_key for google provider\", () => {\n\t\tconst storage = inMemory({});\n\t\tassert.throws(\n\t\t\t() => storage.set(\"google\", makeKey(\"ya29.a0ARrdaM_fake_oauth_token_from_gemini_cli\")),\n\t\t\t(err: Error) => {\n\t\t\t\tassert.ok(err.message.includes(\"OAuth access token\"), `Expected message about OAuth token, got: ${err.message}`);\n\t\t\t\tassert.ok(\n\t\t\t\t\terr.message.includes(\"GEMINI_API_KEY\") || err.message.includes(\"google-gemini-cli\"),\n\t\t\t\t\t`Expected guidance about GEMINI_API_KEY or google-gemini-cli, got: ${err.message}`,\n\t\t\t\t);\n\t\t\t\treturn true;\n\t\t\t},\n\t\t);\n\t});\n\n\tit(\"rejects Google OAuth access token for google provider via getApiKey when set as env var\", async () => {\n\t\tconst storage = inMemory({});\n\t\t// Simulate runtime override with OAuth token\n\t\tstorage.setRuntimeApiKey(\"google\", \"ya29.c.b0AXv0zTPQ_fake_oauth_token\");\n\t\tconst key = await storage.getApiKey(\"google\");\n\t\t// Should return undefined (blocked) or throw\n\t\tassert.equal(key, undefined, \"OAuth token should be blocked for google provider\");\n\t});\n\n\tit(\"allows legitimate Google API keys (AIza prefix) for google provider\", () => {\n\t\tconst storage = inMemory({});\n\t\tstorage.set(\"google\", makeKey(\"AIzaSyD_fake_legitimate_api_key_here\"));\n\t\tconst creds = storage.getCredentialsForProvider(\"google\");\n\t\tassert.equal(creds.length, 1);\n\t});\n\n\tit(\"allows ya29 tokens for google-gemini-cli provider (OAuth is expected there)\", () => {\n\t\t// google-gemini-cli stores OAuth credentials with type: \"oauth\", not \"api_key\"\n\t\t// But if someone somehow stored an api_key, it shouldn't be blocked for OAuth providers\n\t\tconst storage = inMemory({});\n\t\tstorage.set(\"google-gemini-cli\", makeKey(\"ya29.a0ARrdaM_token_for_gemini_cli\"));\n\t\tconst creds = storage.getCredentialsForProvider(\"google-gemini-cli\");\n\t\tassert.equal(creds.length, 1);\n\t});\n\n\tit(\"rejects Google OAuth token (ya29. prefix) for openai provider that uses GEMINI_API_KEY indirectly\", () => {\n\t\t// Only google provider should be blocked, not others\n\t\tconst storage = inMemory({});\n\t\t// This should NOT throw - other providers can have whatever keys they want\n\t\tstorage.set(\"openai\", makeKey(\"ya29.some_value\"));\n\t\tconst creds = storage.getCredentialsForProvider(\"openai\");\n\t\tassert.equal(creds.length, 1);\n\t});\n});\n\n// ─── getAll truncation ────────────────────────────────────────────────────────\n\ndescribe(\"AuthStorage — getAll()\", () => {\n\tit(\"returns first credential only for providers with multiple keys\", () => {\n\t\tconst storage = inMemory({\n\t\t\tanthropic: [makeKey(\"sk-1\"), makeKey(\"sk-2\")],\n\t\t\topenai: makeKey(\"sk-openai\"),\n\t\t});\n\t\tconst all = storage.getAll();\n\t\tassert.ok(all[\"anthropic\"]?.type === \"api_key\");\n\t\tassert.equal((all[\"anthropic\"] as any).key, \"sk-1\");\n\t\tassert.equal((all[\"openai\"] as any).key, \"sk-openai\");\n\t});\n});\n"]}
@@ -18,6 +18,13 @@ export declare function createExtensionRuntime(): ExtensionRuntime;
18
18
  * but is tuned to catch the most common TS-in-JS mistakes.
19
19
  */
20
20
  export declare function containsTypeScriptSyntax(source: string): boolean;
21
+ /**
22
+ * Reset the shared jiti singleton so the next call to getExtensionLoaderJiti()
23
+ * creates a fresh instance. This prevents memory leaks in long-running daemon
24
+ * processes (every loaded module stays cached forever) and ensures stale modules
25
+ * are not returned when extension source changes on disk.
26
+ */
27
+ export declare function resetExtensionLoaderCache(): void;
21
28
  /**
22
29
  * Create an Extension from an inline factory function.
23
30
  */
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA+BH,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAIhE,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAChG,OAAO,KAAK,EACX,SAAS,EAET,gBAAgB,EAEhB,gBAAgB,EAChB,oBAAoB,EAKpB,MAAM,YAAY,CAAC;AAsTpB,wBAAsB,qBAAqB,CAAC,CAAC,GAAG,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAI/G;AA6BD;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,gBAAgB,CAqCzD;AAsLD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhE;AAiKD;;GAEG;AACH,wBAAsB,wBAAwB,CAC7C,OAAO,EAAE,gBAAgB,EACzB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,gBAAgB,EACzB,aAAa,SAAa,GACxB,OAAO,CAAC,SAAS,CAAC,CAKpB;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAyBrH;AAmHD;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAC9C,eAAe,EAAE,MAAM,EAAE,EACzB,GAAG,EAAE,MAAM,EACX,QAAQ,GAAE,MAAsB,EAChC,QAAQ,CAAC,EAAE,QAAQ,GACjB,OAAO,CAAC,oBAAoB,CAAC,CAoD/B"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA+BH,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAIhE,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAChG,OAAO,KAAK,EACX,SAAS,EAET,gBAAgB,EAEhB,gBAAgB,EAChB,oBAAoB,EAKpB,MAAM,YAAY,CAAC;AAsTpB,wBAAsB,qBAAqB,CAAC,CAAC,GAAG,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAI/G;AA6BD;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,gBAAgB,CAqCzD;AAsLD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhE;AAeD;;;;;GAKG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD;AAwKD;;GAEG;AACH,wBAAsB,wBAAwB,CAC7C,OAAO,EAAE,gBAAgB,EACzB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,gBAAgB,EACzB,aAAa,SAAa,GACxB,OAAO,CAAC,SAAS,CAAC,CAKpB;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAyBrH;AAmHD;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAC9C,eAAe,EAAE,MAAM,EAAE,EACzB,GAAG,EAAE,MAAM,EACX,QAAQ,GAAE,MAAsB,EAChC,QAAQ,CAAC,EAAE,QAAQ,GACjB,OAAO,CAAC,oBAAoB,CAAC,CAoD/B"}
@@ -523,6 +523,36 @@ const TS_SYNTAX_PATTERNS = [
523
523
  export function containsTypeScriptSyntax(source) {
524
524
  return TS_SYNTAX_PATTERNS.some((pattern) => pattern.test(source));
525
525
  }
526
+ /**
527
+ * Shared jiti instance for loading extension modules.
528
+ *
529
+ * Before this fix (#2108), each extension created a NEW jiti instance with
530
+ * `moduleCache: false`, causing shared dependencies (e.g. @gsd/pi-agent-core)
531
+ * to be recompiled for every extension — turning a ~3s parallel load into a
532
+ * ~15-30s serial compilation bottleneck.
533
+ *
534
+ * Using a single shared instance with `moduleCache: true` means shared modules
535
+ * are compiled once and reused across all extensions.
536
+ */
537
+ let _extensionLoaderJiti = null;
538
+ /**
539
+ * Reset the shared jiti singleton so the next call to getExtensionLoaderJiti()
540
+ * creates a fresh instance. This prevents memory leaks in long-running daemon
541
+ * processes (every loaded module stays cached forever) and ensures stale modules
542
+ * are not returned when extension source changes on disk.
543
+ */
544
+ export function resetExtensionLoaderCache() {
545
+ _extensionLoaderJiti = null;
546
+ }
547
+ function getExtensionLoaderJiti() {
548
+ if (!_extensionLoaderJiti) {
549
+ _extensionLoaderJiti = createJiti(import.meta.url, {
550
+ moduleCache: true,
551
+ ...getJitiOptions(),
552
+ });
553
+ }
554
+ return _extensionLoaderJiti;
555
+ }
526
556
  async function loadExtensionModule(extensionPath) {
527
557
  // Pre-compiled extension loading: if the source is .ts and a sibling .js
528
558
  // file exists with matching or newer mtime, use native import() to skip
@@ -542,10 +572,7 @@ async function loadExtensionModule(extensionPath) {
542
572
  // .js file doesn't exist or stat failed — fall through to jiti
543
573
  }
544
574
  }
545
- const jiti = createJiti(import.meta.url, {
546
- moduleCache: false,
547
- ...getJitiOptions(),
548
- });
575
+ const jiti = getExtensionLoaderJiti();
549
576
  const module = await jiti.import(extensionPath, { default: true });
550
577
  const factory = module;
551
578
  return typeof factory !== "function" ? undefined : factory;
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/core/extensions/loader.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Extension loader - loads TypeScript extension modules using jiti.\n *\n * Uses @mariozechner/jiti fork with virtualModules support for compiled Bun binaries.\n */\n\nimport * as fs from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { createJiti } from \"@mariozechner/jiti\";\nimport * as _bundledPiAgentCore from \"@gsd/pi-agent-core\";\nimport * as _bundledPiAi from \"@gsd/pi-ai\";\nimport * as _bundledPiAiOauth from \"@gsd/pi-ai/oauth\";\nimport type { KeyId } from \"@gsd/pi-tui\";\nimport * as _bundledPiTui from \"@gsd/pi-tui\";\n// Static imports of packages that extensions may use.\n// These MUST be static so Bun bundles them into the compiled binary.\n// The virtualModules option then makes them available to extensions.\nimport * as _bundledTypebox from \"@sinclair/typebox\";\nimport * as _bundledYaml from \"yaml\";\nimport * as _bundledMcpClient from \"@modelcontextprotocol/sdk/client\";\nimport * as _bundledMcpStdio from \"@modelcontextprotocol/sdk/client/stdio.js\";\nimport * as _bundledMcpStreamableHttp from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport * as _bundledMcpSse from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport * as _bundledMcpServer from \"@modelcontextprotocol/sdk/server\";\nimport * as _bundledMcpServerStdio from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport * as _bundledMcpServerSse from \"@modelcontextprotocol/sdk/server/sse.js\";\nimport * as _bundledMcpServerStreamableHttp from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport * as _bundledMcpTypes from \"@modelcontextprotocol/sdk/types.js\";\nimport { getAgentDir, isBunBinary } from \"../../config.js\";\n// NOTE: This import works because loader.ts exports are NOT re-exported from index.ts,\n// avoiding a circular dependency. Extensions can import from @gsd/pi-coding-agent.\nimport * as _bundledPiCodingAgent from \"../../index.js\";\nimport { createEventBus, type EventBus } from \"../event-bus.js\";\nimport type { ExecOptions } from \"../exec.js\";\nimport { execCommand } from \"../exec.js\";\nimport { getUntrustedExtensionPaths } from \"./project-trust.js\";\nexport { isProjectTrusted, trustProject, getUntrustedExtensionPaths } from \"./project-trust.js\";\nimport type {\n\tExtension,\n\tExtensionAPI,\n\tExtensionFactory,\n\tLifecycleHookHandler,\n\tExtensionRuntime,\n\tLoadExtensionsResult,\n\tMessageRenderer,\n\tProviderConfig,\n\tRegisteredCommand,\n\tToolDefinition,\n} from \"./types.js\";\n\n/**\n * Statically imported modules for Bun binary virtualModules.\n * Maps specifier -> module object for subpaths that must be available in compiled binaries.\n */\nconst STATIC_BUNDLED_MODULES: Record<string, unknown> = {\n\t\"@sinclair/typebox\": _bundledTypebox,\n\t\"@gsd/pi-agent-core\": _bundledPiAgentCore,\n\t\"@gsd/pi-tui\": _bundledPiTui,\n\t\"@gsd/pi-ai\": _bundledPiAi,\n\t\"@gsd/pi-ai/oauth\": _bundledPiAiOauth,\n\t\"@gsd/pi-coding-agent\": _bundledPiCodingAgent,\n\t\"yaml\": _bundledYaml,\n\t\"@modelcontextprotocol/sdk/client\": _bundledMcpClient,\n\t\"@modelcontextprotocol/sdk/client/stdio\": _bundledMcpStdio,\n\t\"@modelcontextprotocol/sdk/client/stdio.js\": _bundledMcpStdio,\n\t\"@modelcontextprotocol/sdk/client/streamableHttp\": _bundledMcpStreamableHttp,\n\t\"@modelcontextprotocol/sdk/client/streamableHttp.js\": _bundledMcpStreamableHttp,\n\t\"@modelcontextprotocol/sdk/client/sse\": _bundledMcpSse,\n\t\"@modelcontextprotocol/sdk/client/sse.js\": _bundledMcpSse,\n\t\"@modelcontextprotocol/sdk/server\": _bundledMcpServer,\n\t\"@modelcontextprotocol/sdk/server/stdio\": _bundledMcpServerStdio,\n\t\"@modelcontextprotocol/sdk/server/stdio.js\": _bundledMcpServerStdio,\n\t\"@modelcontextprotocol/sdk/server/sse\": _bundledMcpServerSse,\n\t\"@modelcontextprotocol/sdk/server/sse.js\": _bundledMcpServerSse,\n\t\"@modelcontextprotocol/sdk/server/streamableHttp\": _bundledMcpServerStreamableHttp,\n\t\"@modelcontextprotocol/sdk/server/streamableHttp.js\": _bundledMcpServerStreamableHttp,\n\t\"@modelcontextprotocol/sdk/types\": _bundledMcpTypes,\n\t\"@modelcontextprotocol/sdk/types.js\": _bundledMcpTypes,\n\t// Aliases for external PI ecosystem packages that import from the original scope\n\t\"@mariozechner/pi-agent-core\": _bundledPiAgentCore,\n\t\"@mariozechner/pi-tui\": _bundledPiTui,\n\t\"@mariozechner/pi-ai\": _bundledPiAi,\n\t\"@mariozechner/pi-ai/oauth\": _bundledPiAiOauth,\n\t\"@mariozechner/pi-coding-agent\": _bundledPiCodingAgent,\n};\n\n/** Modules available to extensions via virtualModules (for compiled Bun binary) */\nconst VIRTUAL_MODULES: Record<string, unknown> = { ...STATIC_BUNDLED_MODULES };\n\nconst require = createRequire(import.meta.url);\nconst EXTENSION_TIMING_ENABLED = process.env.GSD_STARTUP_TIMING === \"1\" || process.env.PI_TIMING === \"1\";\n\n/**\n * Bundled npm packages whose subpath exports should be auto-resolved for extensions.\n * Each package listed here will have its `exports` field read from package.json,\n * and all subpath exports will be registered as jiti aliases (Node.js mode) so that\n * extensions can import any standard subpath without hitting jiti's CJS double-resolve bug.\n */\nconst BUNDLED_PACKAGES_WITH_EXPORTS = [\n\t\"@modelcontextprotocol/sdk\",\n\t\"yaml\",\n];\n\n/**\n * Read a package's `exports` field and return alias entries mapping\n * specifiers (e.g. `@modelcontextprotocol/sdk/server`) to resolved file paths.\n *\n * Handles:\n * - Explicit subpath exports: `./client` -> `@pkg/client`\n * - Wildcard exports (`./*`): scans the package's dist directory for actual files\n * - Both `.js`-suffixed and bare specifiers for each subpath\n */\nfunction resolveSubpathExports(packageName: string): Record<string, string> {\n\tconst aliases: Record<string, string> = {};\n\n\tlet packageJsonPath: string;\n\ttry {\n\t\t// Resolve the package's root directory via its package.json\n\t\tpackageJsonPath = require.resolve(`${packageName}/package.json`);\n\t} catch {\n\t\t// Package doesn't allow importing package.json via exports — find it manually\n\t\ttry {\n\t\t\tconst anyEntry = require.resolve(packageName);\n\t\t\t// Walk up from the resolved entry to find package.json\n\t\t\tlet dir = path.dirname(anyEntry);\n\t\t\twhile (dir !== path.dirname(dir)) {\n\t\t\t\tconst candidate = path.join(dir, \"package.json\");\n\t\t\t\tif (fs.existsSync(candidate)) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst pkg = JSON.parse(fs.readFileSync(candidate, \"utf-8\"));\n\t\t\t\t\t\tif (pkg.name === packageName) {\n\t\t\t\t\t\t\tpackageJsonPath = candidate;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// not valid JSON, keep walking\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdir = path.dirname(dir);\n\t\t\t}\n\t\t} catch {\n\t\t\treturn aliases;\n\t\t}\n\t\tif (!packageJsonPath!) return aliases;\n\t}\n\n\tlet pkg: { exports?: Record<string, unknown> };\n\ttry {\n\t\tpkg = JSON.parse(fs.readFileSync(packageJsonPath, \"utf-8\"));\n\t} catch {\n\t\treturn aliases;\n\t}\n\n\tconst exports = pkg.exports;\n\tif (!exports || typeof exports !== \"object\") return aliases;\n\n\tconst packageDir = path.dirname(packageJsonPath);\n\n\tfor (const [subpath, target] of Object.entries(exports)) {\n\t\tif (subpath === \".\") continue; // Root export handled by static imports\n\n\t\t// Handle wildcard exports like \"./*\"\n\t\tif (subpath.includes(\"*\")) {\n\t\t\tresolveWildcardExports(packageName, packageDir, subpath, target, aliases);\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Explicit subpath: \"./client\" -> \"@pkg/client\"\n\t\tconst specifier = `${packageName}/${subpath.replace(/^\\.\\//, \"\")}`;\n\n\t\ttry {\n\t\t\tconst resolved = require.resolve(specifier);\n\t\t\taliases[specifier] = resolved;\n\n\t\t\t// Add .js-suffixed variant if the specifier doesn't already end in .js\n\t\t\tif (!specifier.endsWith(\".js\")) {\n\t\t\t\tconst jsSpecifier = `${specifier}.js`;\n\t\t\t\ttry {\n\t\t\t\t\tconst jsResolved = require.resolve(jsSpecifier);\n\t\t\t\t\taliases[jsSpecifier] = jsResolved;\n\t\t\t\t} catch {\n\t\t\t\t\t// .js variant doesn't resolve — that's fine\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add bare variant (without .js) if it ends in .js\n\t\t\tif (specifier.endsWith(\".js\")) {\n\t\t\t\tconst bareSpecifier = specifier.slice(0, -3);\n\t\t\t\ttry {\n\t\t\t\t\tconst bareResolved = require.resolve(bareSpecifier);\n\t\t\t\t\taliases[bareSpecifier] = bareResolved;\n\t\t\t\t} catch {\n\t\t\t\t\t// bare variant doesn't resolve — that's fine\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Subpath doesn't resolve — skip it\n\t\t}\n\t}\n\n\treturn aliases;\n}\n\n/**\n * Resolve wildcard export patterns (e.g. `./*`) by scanning the package's\n * file structure to find all matching files and generate alias entries.\n */\nfunction resolveWildcardExports(\n\tpackageName: string,\n\tpackageDir: string,\n\tsubpathPattern: string,\n\ttarget: unknown,\n\taliases: Record<string, string>,\n): void {\n\t// Extract the target directory pattern from the export target\n\t// e.g. { \"require\": \"./dist/cjs/*\" } -> \"dist/cjs\"\n\tlet targetDir: string | null = null;\n\n\tif (typeof target === \"string\") {\n\t\ttargetDir = target.replace(/\\/\\*$/, \"\").replace(/^\\.\\//, \"\");\n\t} else if (target && typeof target === \"object\") {\n\t\tconst targetObj = target as Record<string, unknown>;\n\t\t// Prefer \"require\" for CJS compatibility with jiti, fall back to \"import\"\n\t\tconst resolved = targetObj.require ?? targetObj.import ?? targetObj.default;\n\t\tif (typeof resolved === \"string\") {\n\t\t\ttargetDir = resolved.replace(/\\/\\*$/, \"\").replace(/^\\.\\//, \"\");\n\t\t}\n\t}\n\n\tif (!targetDir) return;\n\n\tconst fullTargetDir = path.join(packageDir, targetDir);\n\tif (!fs.existsSync(fullTargetDir)) return;\n\n\t// Scan for .js files and generate specifiers\n\tconst subpathPrefix = subpathPattern.replace(/\\/?\\*$/, \"\").replace(/^\\.\\//, \"\");\n\tscanDirForExports(packageName, fullTargetDir, subpathPrefix, aliases);\n}\n\n/**\n * Recursively scan a directory for .js files and register them as aliases.\n */\nfunction scanDirForExports(\n\tpackageName: string,\n\tdir: string,\n\trelativePath: string,\n\taliases: Record<string, string>,\n): void {\n\tlet entries: fs.Dirent[];\n\ttry {\n\t\tentries = fs.readdirSync(dir, { withFileTypes: true });\n\t} catch {\n\t\treturn;\n\t}\n\n\tfor (const entry of entries) {\n\t\tconst entryRelative = relativePath ? `${relativePath}/${entry.name}` : entry.name;\n\n\t\tif (entry.isDirectory()) {\n\t\t\t// Skip examples/test directories — extensions don't need them\n\t\t\tif (entry.name === \"examples\" || entry.name === \"__tests__\" || entry.name === \"test\") continue;\n\t\t\tscanDirForExports(packageName, path.join(dir, entry.name), entryRelative, aliases);\n\t\t} else if (entry.name.endsWith(\".js\") && !entry.name.endsWith(\".d.js\")) {\n\t\t\tconst filePath = path.join(dir, entry.name);\n\t\t\tconst specifier = `${packageName}/${entryRelative}`;\n\t\t\t// Only add if not already covered by an explicit export\n\t\t\tif (!(specifier in aliases)) {\n\t\t\t\taliases[specifier] = filePath;\n\t\t\t}\n\t\t\t// Also add bare (no .js) variant\n\t\t\tconst bareSpecifier = specifier.replace(/\\.js$/, \"\");\n\t\t\tif (!(bareSpecifier in aliases)) {\n\t\t\t\taliases[bareSpecifier] = filePath;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction logExtensionTiming(extensionPath: string, ms: number, outcome: \"loaded\" | \"failed\"): void {\n\tif (!EXTENSION_TIMING_ENABLED) return;\n\tconsole.error(`[startup] extension ${outcome}: ${extensionPath} (${ms}ms)`);\n}\n\n/**\n * Get aliases for jiti (used in Node.js/development mode).\n * In Bun binary mode, virtualModules is used instead.\n */\nlet _aliases: Record<string, string> | null = null;\nfunction getAliases(): Record<string, string> {\n\tif (_aliases) return _aliases;\n\n\tconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\tconst packageIndex = path.resolve(__dirname, \"../..\", \"index.js\");\n\n\tconst typeboxEntry = require.resolve(\"@sinclair/typebox\");\n\tconst typeboxRoot = typeboxEntry.replace(/[\\\\/]build[\\\\/]cjs[\\\\/]index\\.js$/, \"\");\n\n\tconst yamlEntry = require.resolve(\"yaml\");\n\tconst yamlRoot = yamlEntry.replace(/[\\\\/]dist[\\\\/]index\\.js$/, \"\");\n\n\tconst packagesRoot = path.resolve(__dirname, \"../../../../\");\n\tconst resolveWorkspaceOrImport = (workspaceRelativePath: string, specifier: string): string => {\n\t\tconst workspacePath = path.join(packagesRoot, workspaceRelativePath);\n\t\tif (fs.existsSync(workspacePath)) {\n\t\t\treturn workspacePath;\n\t\t}\n\t\treturn fileURLToPath(import.meta.resolve(specifier));\n\t};\n\n\t// Auto-discover subpath exports from bundled npm packages.\n\t// This ensures extensions can import any standard subpath (e.g. @modelcontextprotocol/sdk/server)\n\t// without hitting jiti's CJS double-resolve bug.\n\tconst autoDiscovered: Record<string, string> = {};\n\tfor (const packageName of BUNDLED_PACKAGES_WITH_EXPORTS) {\n\t\tconst subpathAliases = resolveSubpathExports(packageName);\n\t\tObject.assign(autoDiscovered, subpathAliases);\n\t}\n\n\t_aliases = {\n\t\t// Auto-discovered subpath exports (lowest priority — overridden by manual entries below)\n\t\t...autoDiscovered,\n\t\t// Manual entries for workspace packages and packages needing special resolution\n\t\t\"@gsd/pi-coding-agent\": packageIndex,\n\t\t\"@gsd/pi-agent-core\": resolveWorkspaceOrImport(\"agent/dist/index.js\", \"@gsd/pi-agent-core\"),\n\t\t\"@gsd/pi-tui\": resolveWorkspaceOrImport(\"tui/dist/index.js\", \"@gsd/pi-tui\"),\n\t\t\"@gsd/pi-ai\": resolveWorkspaceOrImport(\"ai/dist/index.js\", \"@gsd/pi-ai\"),\n\t\t\"@gsd/pi-ai/oauth\": resolveWorkspaceOrImport(\"ai/dist/oauth.js\", \"@gsd/pi-ai/oauth\"),\n\t\t\"@sinclair/typebox\": typeboxRoot,\n\t\t\"yaml\": yamlRoot,\n\t\t// Aliases for external PI ecosystem packages that import from the original scope\n\t\t\"@mariozechner/pi-coding-agent\": packageIndex,\n\t\t\"@mariozechner/pi-agent-core\": resolveWorkspaceOrImport(\"agent/dist/index.js\", \"@gsd/pi-agent-core\"),\n\t\t\"@mariozechner/pi-tui\": resolveWorkspaceOrImport(\"tui/dist/index.js\", \"@gsd/pi-tui\"),\n\t\t\"@mariozechner/pi-ai\": resolveWorkspaceOrImport(\"ai/dist/index.js\", \"@gsd/pi-ai\"),\n\t\t\"@mariozechner/pi-ai/oauth\": resolveWorkspaceOrImport(\"ai/dist/oauth.js\", \"@gsd/pi-ai/oauth\"),\n\t};\n\n\treturn _aliases;\n}\n\nfunction getJitiOptions() {\n\treturn isBunBinary ? { virtualModules: VIRTUAL_MODULES, tryNative: false } : { alias: getAliases() };\n}\n\nconst _moduleImporters = new Map<string, ReturnType<typeof createJiti>>();\n\nfunction getModuleImporter(parentModuleUrl: string) {\n\tlet importer = _moduleImporters.get(parentModuleUrl);\n\tif (!importer) {\n\t\timporter = createJiti(parentModuleUrl, {\n\t\t\tmoduleCache: true,\n\t\t\t...getJitiOptions(),\n\t\t});\n\t\t_moduleImporters.set(parentModuleUrl, importer);\n\t}\n\treturn importer;\n}\n\nexport async function importExtensionModule<T = unknown>(parentModuleUrl: string, specifier: string): Promise<T> {\n\tconst importer = getModuleImporter(parentModuleUrl);\n\tconst resolvedPath = fileURLToPath(new URL(specifier, parentModuleUrl));\n\treturn importer.import(resolvedPath) as Promise<T>;\n}\n\nconst UNICODE_SPACES = /[\\u00A0\\u1680\\u2000-\\u200A\\u202F\\u205F\\u3000]/g;\n\nfunction normalizeUnicodeSpaces(str: string): string {\n\treturn str.replace(UNICODE_SPACES, \" \");\n}\n\nfunction expandPath(p: string): string {\n\tconst normalized = normalizeUnicodeSpaces(p);\n\tif (normalized.startsWith(\"~/\")) {\n\t\treturn path.join(os.homedir(), normalized.slice(2));\n\t}\n\tif (normalized.startsWith(\"~\")) {\n\t\treturn path.join(os.homedir(), normalized.slice(1));\n\t}\n\treturn normalized;\n}\n\nfunction resolvePath(extPath: string, cwd: string): string {\n\tconst expanded = expandPath(extPath);\n\tif (path.isAbsolute(expanded)) {\n\t\treturn expanded;\n\t}\n\treturn path.resolve(cwd, expanded);\n}\n\ntype HandlerFn = (...args: unknown[]) => Promise<unknown>;\n\n/**\n * Create a runtime with throwing stubs for action methods.\n * Runner.bindCore() replaces these with real implementations.\n */\nexport function createExtensionRuntime(): ExtensionRuntime {\n\tconst notInitialized = () => {\n\t\tthrow new Error(\"Extension runtime not initialized. Action methods cannot be called during extension loading.\");\n\t};\n\n\tconst runtime: ExtensionRuntime = {\n\t\tsendMessage: notInitialized,\n\t\tsendUserMessage: notInitialized,\n\t\tretryLastTurn: notInitialized,\n\t\tappendEntry: notInitialized,\n\t\tsetSessionName: notInitialized,\n\t\tgetSessionName: notInitialized,\n\t\tsetLabel: notInitialized,\n\t\tgetActiveTools: notInitialized,\n\t\tgetAllTools: notInitialized,\n\t\tsetActiveTools: notInitialized,\n\t\t// registerTool() is valid during extension load; refresh is only needed post-bind.\n\t\trefreshTools: () => {},\n\t\tgetCommands: notInitialized,\n\t\tsetModel: () => Promise.reject(new Error(\"Extension runtime not initialized\")),\n\t\tgetThinkingLevel: notInitialized,\n\t\tsetThinkingLevel: notInitialized,\n\t\tflagValues: new Map(),\n\t\tpendingProviderRegistrations: [],\n\t\t// Pre-bind: queue registrations so bindCore() can flush them once the\n\t\t// model registry is available. bindCore() replaces both with direct calls.\n\t\tregisterProvider: (name, config) => {\n\t\t\truntime.pendingProviderRegistrations.push({ name, config });\n\t\t},\n\t\tunregisterProvider: (name) => {\n\t\t\truntime.pendingProviderRegistrations = runtime.pendingProviderRegistrations.filter((r) => r.name !== name);\n\t\t},\n\t\t// Stub replaced by ExtensionRunner at construction time via bindEmitMethods().\n\t\temitBeforeModelSelect: async () => undefined,\n\t};\n\n\treturn runtime;\n}\n\n/**\n * Create the ExtensionAPI for an extension.\n * Registration methods write to the extension object.\n * Action methods delegate to the shared runtime.\n */\nfunction createExtensionAPI(\n\textension: Extension,\n\truntime: ExtensionRuntime,\n\tcwd: string,\n\teventBus: EventBus,\n): ExtensionAPI {\n\tconst api = {\n\t\t// Registration methods - write to extension\n\t\ton(event: string, handler: HandlerFn): void {\n\t\t\tconst list = extension.handlers.get(event) ?? [];\n\t\t\tlist.push(handler);\n\t\t\textension.handlers.set(event, list);\n\t\t},\n\n\t\tregisterTool(tool: ToolDefinition): void {\n\t\t\textension.tools.set(tool.name, {\n\t\t\t\tdefinition: tool,\n\t\t\t\textensionPath: extension.path,\n\t\t\t});\n\t\t\truntime.refreshTools();\n\t\t},\n\n\t\tregisterCommand(name: string, options: Omit<RegisteredCommand, \"name\">): void {\n\t\t\textension.commands.set(name, { name, ...options });\n\t\t},\n\n\t\tregisterBeforeInstall(handler: LifecycleHookHandler): void {\n\t\t\textension.lifecycleHooks.beforeInstall.push(handler);\n\t\t},\n\n\t\tregisterAfterInstall(handler: LifecycleHookHandler): void {\n\t\t\textension.lifecycleHooks.afterInstall.push(handler);\n\t\t},\n\n\t\tregisterBeforeRemove(handler: LifecycleHookHandler): void {\n\t\t\textension.lifecycleHooks.beforeRemove.push(handler);\n\t\t},\n\n\t\tregisterAfterRemove(handler: LifecycleHookHandler): void {\n\t\t\textension.lifecycleHooks.afterRemove.push(handler);\n\t\t},\n\n\t\tregisterShortcut(\n\t\t\tshortcut: KeyId,\n\t\t\toptions: {\n\t\t\t\tdescription?: string;\n\t\t\t\thandler: (ctx: import(\"./types.js\").ExtensionContext) => Promise<void> | void;\n\t\t\t},\n\t\t): void {\n\t\t\textension.shortcuts.set(shortcut, { shortcut, extensionPath: extension.path, ...options });\n\t\t},\n\n\t\tregisterFlag(\n\t\t\tname: string,\n\t\t\toptions: { description?: string; type: \"boolean\" | \"string\"; default?: boolean | string },\n\t\t): void {\n\t\t\textension.flags.set(name, { name, extensionPath: extension.path, ...options });\n\t\t\tif (options.default !== undefined && !runtime.flagValues.has(name)) {\n\t\t\t\truntime.flagValues.set(name, options.default);\n\t\t\t}\n\t\t},\n\n\t\tregisterMessageRenderer<T>(customType: string, renderer: MessageRenderer<T>): void {\n\t\t\textension.messageRenderers.set(customType, renderer as MessageRenderer);\n\t\t},\n\n\t\t// Flag access - checks extension registered it, reads from runtime\n\t\tgetFlag(name: string): boolean | string | undefined {\n\t\t\tif (!extension.flags.has(name)) return undefined;\n\t\t\treturn runtime.flagValues.get(name);\n\t\t},\n\n\t\t// Action methods - delegate to shared runtime\n\t\tsendMessage(message, options): void {\n\t\t\truntime.sendMessage(message, options);\n\t\t},\n\n\t\tsendUserMessage(content, options): void {\n\t\t\truntime.sendUserMessage(content, options);\n\t\t},\n\n\t\tretryLastTurn(): void {\n\t\t\truntime.retryLastTurn();\n\t\t},\n\n\t\tappendEntry(customType: string, data?: unknown): void {\n\t\t\truntime.appendEntry(customType, data);\n\t\t},\n\n\t\tsetSessionName(name: string): void {\n\t\t\truntime.setSessionName(name);\n\t\t},\n\n\t\tgetSessionName(): string | undefined {\n\t\t\treturn runtime.getSessionName();\n\t\t},\n\n\t\tsetLabel(entryId: string, label: string | undefined): void {\n\t\t\truntime.setLabel(entryId, label);\n\t\t},\n\n\t\texec(command: string, args: string[], options?: ExecOptions) {\n\t\t\treturn execCommand(command, args, options?.cwd ?? cwd, options);\n\t\t},\n\n\t\tgetActiveTools(): string[] {\n\t\t\treturn runtime.getActiveTools();\n\t\t},\n\n\t\tgetAllTools() {\n\t\t\treturn runtime.getAllTools();\n\t\t},\n\n\t\tsetActiveTools(toolNames: string[]): void {\n\t\t\truntime.setActiveTools(toolNames);\n\t\t},\n\n\t\tgetCommands() {\n\t\t\treturn runtime.getCommands();\n\t\t},\n\n\t\tsetModel(model) {\n\t\t\treturn runtime.setModel(model);\n\t\t},\n\n\t\tgetThinkingLevel() {\n\t\t\treturn runtime.getThinkingLevel();\n\t\t},\n\n\t\tsetThinkingLevel(level) {\n\t\t\truntime.setThinkingLevel(level);\n\t\t},\n\n\t\tregisterProvider(name: string, config: ProviderConfig) {\n\t\t\truntime.registerProvider(name, config);\n\t\t},\n\n\t\tunregisterProvider(name: string) {\n\t\t\truntime.unregisterProvider(name);\n\t\t},\n\n\t\tasync emitBeforeModelSelect(event: Omit<import(\"./types.js\").BeforeModelSelectEvent, \"type\">): Promise<import(\"./types.js\").BeforeModelSelectResult | undefined> {\n\t\t\treturn runtime.emitBeforeModelSelect(event);\n\t\t},\n\n\t\tevents: eventBus,\n\t} as ExtensionAPI;\n\n\treturn api;\n}\n\n/**\n * Heuristic patterns that indicate TypeScript syntax in a source file.\n * Used to detect when a .js file accidentally contains TypeScript code\n * and provide a helpful error message instead of a cryptic parse failure.\n */\nconst TS_SYNTAX_PATTERNS: RegExp[] = [\n\t// Variable type annotations: const name: string, let count: number\n\t/\\b(?:const|let|var)\\s+\\w+\\s*:\\s*(?:string|number|boolean|any|void|never|unknown|object|bigint|symbol|undefined|null)\\b/,\n\t// Parameter type annotations: (api: ExtensionAPI)\n\t/\\(\\s*\\w+\\s*:\\s*[A-Z]\\w*/,\n\t// Return type annotations: ): Promise<void> { or ): string =>\n\t/\\)\\s*:\\s*(?:Promise|string|number|boolean|void|any|never|unknown)\\b/,\n\t// Interface declarations\n\t/\\binterface\\s+[A-Z]\\w*\\s*(?:<[^>]*>)?\\s*\\{/,\n\t// Type alias declarations\n\t/\\btype\\s+[A-Z]\\w*\\s*(?:<[^>]*>)?\\s*=/,\n\t// Angle-bracket type assertions: <Type>value\n\t/(?:as\\s+\\w+(?:<[^>]*>)?)\\s*[;,)\\]}]/,\n\t// Generic type parameters on functions: function foo<T>\n\t/\\bfunction\\s+\\w+\\s*<[^>]+>/,\n\t// Enum declarations\n\t/\\benum\\s+[A-Z]\\w*\\s*\\{/,\n];\n\n/**\n * Check whether a source string likely contains TypeScript syntax.\n * This is a heuristic — it may produce false positives for unusual JS,\n * but is tuned to catch the most common TS-in-JS mistakes.\n */\nexport function containsTypeScriptSyntax(source: string): boolean {\n\treturn TS_SYNTAX_PATTERNS.some((pattern) => pattern.test(source));\n}\n\nasync function loadExtensionModule(extensionPath: string) {\n\t// Pre-compiled extension loading: if the source is .ts and a sibling .js\n\t// file exists with matching or newer mtime, use native import() to skip\n\t// jiti JIT compilation entirely. This is the biggest startup win for\n\t// bundled extensions that have already been built.\n\tif (extensionPath.endsWith(\".ts\")) {\n\t\tconst jsPath = extensionPath.replace(/\\.ts$/, \".js\");\n\t\ttry {\n\t\t\tconst [tsStat, jsStat] = [fs.statSync(extensionPath), fs.statSync(jsPath)];\n\t\t\tif (jsStat.mtimeMs >= tsStat.mtimeMs) {\n\t\t\t\tconst module = await import(jsPath);\n\t\t\t\tconst factory = (module.default ?? module) as ExtensionFactory;\n\t\t\t\treturn typeof factory !== \"function\" ? undefined : factory;\n\t\t\t}\n\t\t} catch {\n\t\t\t// .js file doesn't exist or stat failed — fall through to jiti\n\t\t}\n\t}\n\n\tconst jiti = createJiti(import.meta.url, {\n\t\tmoduleCache: false,\n\t\t...getJitiOptions(),\n\t});\n\n\tconst module = await jiti.import(extensionPath, { default: true });\n\tconst factory = module as ExtensionFactory;\n\treturn typeof factory !== \"function\" ? undefined : factory;\n}\n\n/**\n * Check whether a module path belongs to a non-extension library that should\n * be silently skipped rather than reported as an error.\n *\n * A directory is a non-extension library when its package.json has a \"pi\"\n * manifest that declares no extensions (e.g. `\"pi\": {}`). This is the\n * opt-out convention used by shared libraries like cmux that live inside\n * the extensions/ directory but are not extensions themselves.\n *\n * This serves as a defense-in-depth check: even if the upstream discovery\n * layers fail to filter out the library, the loader itself will not emit\n * a spurious error.\n */\nfunction isNonExtensionLibrary(resolvedPath: string): boolean {\n\t// Walk up from the resolved file to find the nearest package.json\n\tlet dir = path.dirname(resolvedPath);\n\tconst root = path.parse(dir).root;\n\twhile (dir !== root) {\n\t\tconst packageJsonPath = path.join(dir, \"package.json\");\n\t\tif (fs.existsSync(packageJsonPath)) {\n\t\t\ttry {\n\t\t\t\tconst content = fs.readFileSync(packageJsonPath, \"utf-8\");\n\t\t\t\tconst pkg = JSON.parse(content);\n\t\t\t\tif (pkg.pi && typeof pkg.pi === \"object\") {\n\t\t\t\t\t// Has a pi manifest — check if it declares any extensions\n\t\t\t\t\tconst extensions = pkg.pi.extensions;\n\t\t\t\t\tif (!Array.isArray(extensions) || extensions.length === 0) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Malformed package.json — not a known library\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tdir = path.dirname(dir);\n\t}\n\treturn false;\n}\n\n/**\n * Create an Extension object with empty collections.\n */\nfunction createExtension(extensionPath: string, resolvedPath: string): Extension {\n\treturn {\n\t\tpath: extensionPath,\n\t\tresolvedPath,\n\t\thandlers: new Map(),\n\t\ttools: new Map(),\n\t\tmessageRenderers: new Map(),\n\t\tcommands: new Map(),\n\t\tflags: new Map(),\n\t\tshortcuts: new Map(),\n\t\tlifecycleHooks: {\n\t\t\tbeforeInstall: [],\n\t\t\tafterInstall: [],\n\t\t\tbeforeRemove: [],\n\t\t\tafterRemove: [],\n\t\t},\n\t};\n}\n\nasync function loadExtension(\n\textensionPath: string,\n\tcwd: string,\n\teventBus: EventBus,\n\truntime: ExtensionRuntime,\n): Promise<{ extension: Extension | null; error: string | null }> {\n\tconst resolvedPath = resolvePath(extensionPath, cwd);\n\tconst start = Date.now();\n\n\ttry {\n\t\tconst factory = await loadExtensionModule(resolvedPath);\n\t\tif (!factory) {\n\t\t\t// Defense-in-depth: if the module is inside a directory that has\n\t\t\t// explicitly opted out of extension loading via its pi manifest,\n\t\t\t// silently skip it instead of reporting a spurious error.\n\t\t\tif (isNonExtensionLibrary(resolvedPath)) {\n\t\t\t\treturn { extension: null, error: null };\n\t\t\t}\n\t\t\tlogExtensionTiming(extensionPath, Date.now() - start, \"failed\");\n\n\t\t\t// Check if a .js file contains TypeScript syntax\n\t\t\tif (resolvedPath.endsWith(\".js\")) {\n\t\t\t\ttry {\n\t\t\t\t\tconst source = fs.readFileSync(resolvedPath, \"utf-8\");\n\t\t\t\t\tif (containsTypeScriptSyntax(source)) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\textension: null,\n\t\t\t\t\t\t\terror: `Extension file \"${extensionPath}\" appears to contain TypeScript syntax but has a .js extension. Rename it to .ts so the loader can compile it.`,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Could not read file — fall through to generic error\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { extension: null, error: `Extension does not export a valid factory function: ${extensionPath}` };\n\t\t}\n\n\t\tconst extension = createExtension(extensionPath, resolvedPath);\n\t\tconst api = createExtensionAPI(extension, runtime, cwd, eventBus);\n\t\tawait factory(api);\n\t\tlogExtensionTiming(extensionPath, Date.now() - start, \"loaded\");\n\n\t\treturn { extension, error: null };\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tlogExtensionTiming(extensionPath, Date.now() - start, \"failed\");\n\n\t\t// Check if a .js file contains TypeScript syntax — the parse error from\n\t\t// jiti/Node is often cryptic, so surface a clearer diagnostic.\n\t\tif (resolvedPath.endsWith(\".js\")) {\n\t\t\ttry {\n\t\t\t\tconst source = fs.readFileSync(resolvedPath, \"utf-8\");\n\t\t\t\tif (containsTypeScriptSyntax(source)) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\textension: null,\n\t\t\t\t\t\terror: `Extension file \"${extensionPath}\" appears to contain TypeScript syntax but has a .js extension. Rename it to .ts so the loader can compile it.`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Could not read file — fall through to generic error\n\t\t\t}\n\t\t}\n\n\t\treturn { extension: null, error: `Failed to load extension: ${message}` };\n\t}\n}\n\n/**\n * Create an Extension from an inline factory function.\n */\nexport async function loadExtensionFromFactory(\n\tfactory: ExtensionFactory,\n\tcwd: string,\n\teventBus: EventBus,\n\truntime: ExtensionRuntime,\n\textensionPath = \"<inline>\",\n): Promise<Extension> {\n\tconst extension = createExtension(extensionPath, extensionPath);\n\tconst api = createExtensionAPI(extension, runtime, cwd, eventBus);\n\tawait factory(api);\n\treturn extension;\n}\n\n/**\n * Load extensions from paths.\n *\n * Extensions are loaded in parallel to reduce wall-clock time (~30-50% faster\n * than sequential loading for I/O-bound jiti compilation).\n */\nexport async function loadExtensions(paths: string[], cwd: string, eventBus?: EventBus): Promise<LoadExtensionsResult> {\n\tconst resolvedEventBus = eventBus ?? createEventBus();\n\tconst runtime = createExtensionRuntime();\n\n\tconst results = await Promise.all(\n\t\tpaths.map((extPath) => loadExtension(extPath, cwd, resolvedEventBus, runtime)),\n\t);\n\n\tconst extensions: Extension[] = [];\n\tconst errors: Array<{ path: string; error: string }> = [];\n\n\tfor (let i = 0; i < results.length; i++) {\n\t\tconst { extension, error } = results[i];\n\t\tif (error) {\n\t\t\terrors.push({ path: paths[i], error });\n\t\t} else if (extension) {\n\t\t\textensions.push(extension);\n\t\t}\n\t}\n\n\treturn {\n\t\textensions,\n\t\terrors,\n\t\truntime,\n\t};\n}\n\ninterface PiManifest {\n\textensions?: string[];\n\tthemes?: string[];\n\tskills?: string[];\n\tprompts?: string[];\n}\n\nfunction readPiManifest(packageJsonPath: string): PiManifest | null {\n\ttry {\n\t\tconst content = fs.readFileSync(packageJsonPath, \"utf-8\");\n\t\tconst pkg = JSON.parse(content);\n\t\tif (pkg.pi && typeof pkg.pi === \"object\") {\n\t\t\treturn pkg.pi as PiManifest;\n\t\t}\n\t\treturn null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction isExtensionFile(name: string): boolean {\n\treturn name.endsWith(\".ts\") || name.endsWith(\".js\");\n}\n\n/**\n * Resolve extension entry points from a directory.\n *\n * Checks for:\n * 1. package.json with \"pi.extensions\" field -> returns declared paths\n * 2. index.ts or index.js -> returns the index file\n *\n * Returns resolved paths or null if no entry points found.\n */\nfunction resolveExtensionEntries(dir: string): string[] | null {\n\t// Check for package.json with \"pi\" field first\n\tconst packageJsonPath = path.join(dir, \"package.json\");\n\tif (fs.existsSync(packageJsonPath)) {\n\t\tconst manifest = readPiManifest(packageJsonPath);\n\t\tif (manifest) {\n\t\t\t// When a pi manifest exists, it is authoritative — don't fall through\n\t\t\t// to index.ts/index.js auto-detection. This allows library directories\n\t\t\t// (like cmux) to opt out by declaring \"pi\": {} with no extensions.\n\t\t\tif (!manifest.extensions?.length) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst entries: string[] = [];\n\t\t\tfor (const extPath of manifest.extensions) {\n\t\t\t\tconst resolvedExtPath = path.resolve(dir, extPath);\n\t\t\t\tif (fs.existsSync(resolvedExtPath)) {\n\t\t\t\t\tentries.push(resolvedExtPath);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn entries.length > 0 ? entries : null;\n\t\t}\n\t}\n\n\t// Check for index.ts or index.js\n\tconst indexTs = path.join(dir, \"index.ts\");\n\tconst indexJs = path.join(dir, \"index.js\");\n\tif (fs.existsSync(indexTs)) {\n\t\treturn [indexTs];\n\t}\n\tif (fs.existsSync(indexJs)) {\n\t\treturn [indexJs];\n\t}\n\n\treturn null;\n}\n\n/**\n * Discover extensions in a directory.\n *\n * Discovery rules:\n * 1. Direct files: `extensions/*.ts` or `*.js` → load\n * 2. Subdirectory with index: `extensions/* /index.ts` or `index.js` → load\n * 3. Subdirectory with package.json: `extensions/* /package.json` with \"pi\" field → load what it declares\n *\n * No recursion beyond one level. Complex packages must use package.json manifest.\n */\nfunction discoverExtensionsInDir(dir: string): string[] {\n\tif (!fs.existsSync(dir)) {\n\t\treturn [];\n\t}\n\n\tconst discovered: string[] = [];\n\n\ttry {\n\t\tconst entries = fs.readdirSync(dir, { withFileTypes: true });\n\n\t\tfor (const entry of entries) {\n\t\t\tconst entryPath = path.join(dir, entry.name);\n\n\t\t\t// 1. Direct files: *.ts or *.js\n\t\t\tif ((entry.isFile() || entry.isSymbolicLink()) && isExtensionFile(entry.name)) {\n\t\t\t\tdiscovered.push(entryPath);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// 2 & 3. Subdirectories\n\t\t\tif (entry.isDirectory() || entry.isSymbolicLink()) {\n\t\t\t\tconst entries = resolveExtensionEntries(entryPath);\n\t\t\t\tif (entries) {\n\t\t\t\t\tdiscovered.push(...entries);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch {\n\t\treturn [];\n\t}\n\n\treturn discovered;\n}\n\n/**\n * Discover and load extensions from standard locations.\n *\n * @deprecated Use DefaultResourceLoader.reload() instead — this function is\n * not called in the GSD loading flow. Extension discovery happens through\n * DefaultPackageManager.resolve() → addAutoDiscoveredResources(). Kept for\n * backwards compatibility with direct pi-coding-agent consumers.\n */\nexport async function discoverAndLoadExtensions(\n\tconfiguredPaths: string[],\n\tcwd: string,\n\tagentDir: string = getAgentDir(),\n\teventBus?: EventBus,\n): Promise<LoadExtensionsResult> {\n\tconst allPaths: string[] = [];\n\tconst seen = new Set<string>();\n\n\tconst addPaths = (paths: string[]) => {\n\t\tfor (const p of paths) {\n\t\t\tconst resolved = path.resolve(p);\n\t\t\tif (!seen.has(resolved)) {\n\t\t\t\tseen.add(resolved);\n\t\t\t\tallPaths.push(p);\n\t\t\t}\n\t\t}\n\t};\n\n\t// 1. Project-local extensions: cwd/.pi/extensions/\n\t// Only loaded when the project path has been explicitly trusted (TOFU model).\n\tconst localExtDir = path.join(cwd, \".pi\", \"extensions\");\n\tconst localDiscovered = discoverExtensionsInDir(localExtDir);\n\tif (localDiscovered.length > 0) {\n\t\tconst untrusted = getUntrustedExtensionPaths(cwd, localDiscovered, agentDir);\n\t\tif (untrusted.length > 0) {\n\t\t\tprocess.stderr.write(\n\t\t\t\t`[pi] Skipping ${untrusted.length} project-local extension(s) in ${localExtDir} — project not trusted. Use trustProject() to enable.\\n`,\n\t\t\t);\n\t\t}\n\t\tconst trusted = localDiscovered.filter((p) => !untrusted.includes(p));\n\t\taddPaths(trusted);\n\t}\n\n\t// 2. Global extensions: agentDir/extensions/\n\tconst globalExtDir = path.join(agentDir, \"extensions\");\n\taddPaths(discoverExtensionsInDir(globalExtDir));\n\n\t// 3. Explicitly configured paths\n\tfor (const p of configuredPaths) {\n\t\tconst resolved = resolvePath(p, cwd);\n\t\tif (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) {\n\t\t\t// Check for package.json with pi manifest or index.ts\n\t\t\tconst entries = resolveExtensionEntries(resolved);\n\t\t\tif (entries) {\n\t\t\t\taddPaths(entries);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// No explicit entries - discover individual files in directory\n\t\t\taddPaths(discoverExtensionsInDir(resolved));\n\t\t\tcontinue;\n\t\t}\n\n\t\taddPaths([resolved]);\n\t}\n\n\treturn loadExtensions(allPaths, cwd, eventBus);\n}\n"]}
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/core/extensions/loader.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Extension loader - loads TypeScript extension modules using jiti.\n *\n * Uses @mariozechner/jiti fork with virtualModules support for compiled Bun binaries.\n */\n\nimport * as fs from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { createJiti } from \"@mariozechner/jiti\";\nimport * as _bundledPiAgentCore from \"@gsd/pi-agent-core\";\nimport * as _bundledPiAi from \"@gsd/pi-ai\";\nimport * as _bundledPiAiOauth from \"@gsd/pi-ai/oauth\";\nimport type { KeyId } from \"@gsd/pi-tui\";\nimport * as _bundledPiTui from \"@gsd/pi-tui\";\n// Static imports of packages that extensions may use.\n// These MUST be static so Bun bundles them into the compiled binary.\n// The virtualModules option then makes them available to extensions.\nimport * as _bundledTypebox from \"@sinclair/typebox\";\nimport * as _bundledYaml from \"yaml\";\nimport * as _bundledMcpClient from \"@modelcontextprotocol/sdk/client\";\nimport * as _bundledMcpStdio from \"@modelcontextprotocol/sdk/client/stdio.js\";\nimport * as _bundledMcpStreamableHttp from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport * as _bundledMcpSse from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport * as _bundledMcpServer from \"@modelcontextprotocol/sdk/server\";\nimport * as _bundledMcpServerStdio from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport * as _bundledMcpServerSse from \"@modelcontextprotocol/sdk/server/sse.js\";\nimport * as _bundledMcpServerStreamableHttp from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport * as _bundledMcpTypes from \"@modelcontextprotocol/sdk/types.js\";\nimport { getAgentDir, isBunBinary } from \"../../config.js\";\n// NOTE: This import works because loader.ts exports are NOT re-exported from index.ts,\n// avoiding a circular dependency. Extensions can import from @gsd/pi-coding-agent.\nimport * as _bundledPiCodingAgent from \"../../index.js\";\nimport { createEventBus, type EventBus } from \"../event-bus.js\";\nimport type { ExecOptions } from \"../exec.js\";\nimport { execCommand } from \"../exec.js\";\nimport { getUntrustedExtensionPaths } from \"./project-trust.js\";\nexport { isProjectTrusted, trustProject, getUntrustedExtensionPaths } from \"./project-trust.js\";\nimport type {\n\tExtension,\n\tExtensionAPI,\n\tExtensionFactory,\n\tLifecycleHookHandler,\n\tExtensionRuntime,\n\tLoadExtensionsResult,\n\tMessageRenderer,\n\tProviderConfig,\n\tRegisteredCommand,\n\tToolDefinition,\n} from \"./types.js\";\n\n/**\n * Statically imported modules for Bun binary virtualModules.\n * Maps specifier -> module object for subpaths that must be available in compiled binaries.\n */\nconst STATIC_BUNDLED_MODULES: Record<string, unknown> = {\n\t\"@sinclair/typebox\": _bundledTypebox,\n\t\"@gsd/pi-agent-core\": _bundledPiAgentCore,\n\t\"@gsd/pi-tui\": _bundledPiTui,\n\t\"@gsd/pi-ai\": _bundledPiAi,\n\t\"@gsd/pi-ai/oauth\": _bundledPiAiOauth,\n\t\"@gsd/pi-coding-agent\": _bundledPiCodingAgent,\n\t\"yaml\": _bundledYaml,\n\t\"@modelcontextprotocol/sdk/client\": _bundledMcpClient,\n\t\"@modelcontextprotocol/sdk/client/stdio\": _bundledMcpStdio,\n\t\"@modelcontextprotocol/sdk/client/stdio.js\": _bundledMcpStdio,\n\t\"@modelcontextprotocol/sdk/client/streamableHttp\": _bundledMcpStreamableHttp,\n\t\"@modelcontextprotocol/sdk/client/streamableHttp.js\": _bundledMcpStreamableHttp,\n\t\"@modelcontextprotocol/sdk/client/sse\": _bundledMcpSse,\n\t\"@modelcontextprotocol/sdk/client/sse.js\": _bundledMcpSse,\n\t\"@modelcontextprotocol/sdk/server\": _bundledMcpServer,\n\t\"@modelcontextprotocol/sdk/server/stdio\": _bundledMcpServerStdio,\n\t\"@modelcontextprotocol/sdk/server/stdio.js\": _bundledMcpServerStdio,\n\t\"@modelcontextprotocol/sdk/server/sse\": _bundledMcpServerSse,\n\t\"@modelcontextprotocol/sdk/server/sse.js\": _bundledMcpServerSse,\n\t\"@modelcontextprotocol/sdk/server/streamableHttp\": _bundledMcpServerStreamableHttp,\n\t\"@modelcontextprotocol/sdk/server/streamableHttp.js\": _bundledMcpServerStreamableHttp,\n\t\"@modelcontextprotocol/sdk/types\": _bundledMcpTypes,\n\t\"@modelcontextprotocol/sdk/types.js\": _bundledMcpTypes,\n\t// Aliases for external PI ecosystem packages that import from the original scope\n\t\"@mariozechner/pi-agent-core\": _bundledPiAgentCore,\n\t\"@mariozechner/pi-tui\": _bundledPiTui,\n\t\"@mariozechner/pi-ai\": _bundledPiAi,\n\t\"@mariozechner/pi-ai/oauth\": _bundledPiAiOauth,\n\t\"@mariozechner/pi-coding-agent\": _bundledPiCodingAgent,\n};\n\n/** Modules available to extensions via virtualModules (for compiled Bun binary) */\nconst VIRTUAL_MODULES: Record<string, unknown> = { ...STATIC_BUNDLED_MODULES };\n\nconst require = createRequire(import.meta.url);\nconst EXTENSION_TIMING_ENABLED = process.env.GSD_STARTUP_TIMING === \"1\" || process.env.PI_TIMING === \"1\";\n\n/**\n * Bundled npm packages whose subpath exports should be auto-resolved for extensions.\n * Each package listed here will have its `exports` field read from package.json,\n * and all subpath exports will be registered as jiti aliases (Node.js mode) so that\n * extensions can import any standard subpath without hitting jiti's CJS double-resolve bug.\n */\nconst BUNDLED_PACKAGES_WITH_EXPORTS = [\n\t\"@modelcontextprotocol/sdk\",\n\t\"yaml\",\n];\n\n/**\n * Read a package's `exports` field and return alias entries mapping\n * specifiers (e.g. `@modelcontextprotocol/sdk/server`) to resolved file paths.\n *\n * Handles:\n * - Explicit subpath exports: `./client` -> `@pkg/client`\n * - Wildcard exports (`./*`): scans the package's dist directory for actual files\n * - Both `.js`-suffixed and bare specifiers for each subpath\n */\nfunction resolveSubpathExports(packageName: string): Record<string, string> {\n\tconst aliases: Record<string, string> = {};\n\n\tlet packageJsonPath: string;\n\ttry {\n\t\t// Resolve the package's root directory via its package.json\n\t\tpackageJsonPath = require.resolve(`${packageName}/package.json`);\n\t} catch {\n\t\t// Package doesn't allow importing package.json via exports — find it manually\n\t\ttry {\n\t\t\tconst anyEntry = require.resolve(packageName);\n\t\t\t// Walk up from the resolved entry to find package.json\n\t\t\tlet dir = path.dirname(anyEntry);\n\t\t\twhile (dir !== path.dirname(dir)) {\n\t\t\t\tconst candidate = path.join(dir, \"package.json\");\n\t\t\t\tif (fs.existsSync(candidate)) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst pkg = JSON.parse(fs.readFileSync(candidate, \"utf-8\"));\n\t\t\t\t\t\tif (pkg.name === packageName) {\n\t\t\t\t\t\t\tpackageJsonPath = candidate;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// not valid JSON, keep walking\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdir = path.dirname(dir);\n\t\t\t}\n\t\t} catch {\n\t\t\treturn aliases;\n\t\t}\n\t\tif (!packageJsonPath!) return aliases;\n\t}\n\n\tlet pkg: { exports?: Record<string, unknown> };\n\ttry {\n\t\tpkg = JSON.parse(fs.readFileSync(packageJsonPath, \"utf-8\"));\n\t} catch {\n\t\treturn aliases;\n\t}\n\n\tconst exports = pkg.exports;\n\tif (!exports || typeof exports !== \"object\") return aliases;\n\n\tconst packageDir = path.dirname(packageJsonPath);\n\n\tfor (const [subpath, target] of Object.entries(exports)) {\n\t\tif (subpath === \".\") continue; // Root export handled by static imports\n\n\t\t// Handle wildcard exports like \"./*\"\n\t\tif (subpath.includes(\"*\")) {\n\t\t\tresolveWildcardExports(packageName, packageDir, subpath, target, aliases);\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Explicit subpath: \"./client\" -> \"@pkg/client\"\n\t\tconst specifier = `${packageName}/${subpath.replace(/^\\.\\//, \"\")}`;\n\n\t\ttry {\n\t\t\tconst resolved = require.resolve(specifier);\n\t\t\taliases[specifier] = resolved;\n\n\t\t\t// Add .js-suffixed variant if the specifier doesn't already end in .js\n\t\t\tif (!specifier.endsWith(\".js\")) {\n\t\t\t\tconst jsSpecifier = `${specifier}.js`;\n\t\t\t\ttry {\n\t\t\t\t\tconst jsResolved = require.resolve(jsSpecifier);\n\t\t\t\t\taliases[jsSpecifier] = jsResolved;\n\t\t\t\t} catch {\n\t\t\t\t\t// .js variant doesn't resolve — that's fine\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add bare variant (without .js) if it ends in .js\n\t\t\tif (specifier.endsWith(\".js\")) {\n\t\t\t\tconst bareSpecifier = specifier.slice(0, -3);\n\t\t\t\ttry {\n\t\t\t\t\tconst bareResolved = require.resolve(bareSpecifier);\n\t\t\t\t\taliases[bareSpecifier] = bareResolved;\n\t\t\t\t} catch {\n\t\t\t\t\t// bare variant doesn't resolve — that's fine\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Subpath doesn't resolve — skip it\n\t\t}\n\t}\n\n\treturn aliases;\n}\n\n/**\n * Resolve wildcard export patterns (e.g. `./*`) by scanning the package's\n * file structure to find all matching files and generate alias entries.\n */\nfunction resolveWildcardExports(\n\tpackageName: string,\n\tpackageDir: string,\n\tsubpathPattern: string,\n\ttarget: unknown,\n\taliases: Record<string, string>,\n): void {\n\t// Extract the target directory pattern from the export target\n\t// e.g. { \"require\": \"./dist/cjs/*\" } -> \"dist/cjs\"\n\tlet targetDir: string | null = null;\n\n\tif (typeof target === \"string\") {\n\t\ttargetDir = target.replace(/\\/\\*$/, \"\").replace(/^\\.\\//, \"\");\n\t} else if (target && typeof target === \"object\") {\n\t\tconst targetObj = target as Record<string, unknown>;\n\t\t// Prefer \"require\" for CJS compatibility with jiti, fall back to \"import\"\n\t\tconst resolved = targetObj.require ?? targetObj.import ?? targetObj.default;\n\t\tif (typeof resolved === \"string\") {\n\t\t\ttargetDir = resolved.replace(/\\/\\*$/, \"\").replace(/^\\.\\//, \"\");\n\t\t}\n\t}\n\n\tif (!targetDir) return;\n\n\tconst fullTargetDir = path.join(packageDir, targetDir);\n\tif (!fs.existsSync(fullTargetDir)) return;\n\n\t// Scan for .js files and generate specifiers\n\tconst subpathPrefix = subpathPattern.replace(/\\/?\\*$/, \"\").replace(/^\\.\\//, \"\");\n\tscanDirForExports(packageName, fullTargetDir, subpathPrefix, aliases);\n}\n\n/**\n * Recursively scan a directory for .js files and register them as aliases.\n */\nfunction scanDirForExports(\n\tpackageName: string,\n\tdir: string,\n\trelativePath: string,\n\taliases: Record<string, string>,\n): void {\n\tlet entries: fs.Dirent[];\n\ttry {\n\t\tentries = fs.readdirSync(dir, { withFileTypes: true });\n\t} catch {\n\t\treturn;\n\t}\n\n\tfor (const entry of entries) {\n\t\tconst entryRelative = relativePath ? `${relativePath}/${entry.name}` : entry.name;\n\n\t\tif (entry.isDirectory()) {\n\t\t\t// Skip examples/test directories — extensions don't need them\n\t\t\tif (entry.name === \"examples\" || entry.name === \"__tests__\" || entry.name === \"test\") continue;\n\t\t\tscanDirForExports(packageName, path.join(dir, entry.name), entryRelative, aliases);\n\t\t} else if (entry.name.endsWith(\".js\") && !entry.name.endsWith(\".d.js\")) {\n\t\t\tconst filePath = path.join(dir, entry.name);\n\t\t\tconst specifier = `${packageName}/${entryRelative}`;\n\t\t\t// Only add if not already covered by an explicit export\n\t\t\tif (!(specifier in aliases)) {\n\t\t\t\taliases[specifier] = filePath;\n\t\t\t}\n\t\t\t// Also add bare (no .js) variant\n\t\t\tconst bareSpecifier = specifier.replace(/\\.js$/, \"\");\n\t\t\tif (!(bareSpecifier in aliases)) {\n\t\t\t\taliases[bareSpecifier] = filePath;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction logExtensionTiming(extensionPath: string, ms: number, outcome: \"loaded\" | \"failed\"): void {\n\tif (!EXTENSION_TIMING_ENABLED) return;\n\tconsole.error(`[startup] extension ${outcome}: ${extensionPath} (${ms}ms)`);\n}\n\n/**\n * Get aliases for jiti (used in Node.js/development mode).\n * In Bun binary mode, virtualModules is used instead.\n */\nlet _aliases: Record<string, string> | null = null;\nfunction getAliases(): Record<string, string> {\n\tif (_aliases) return _aliases;\n\n\tconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\tconst packageIndex = path.resolve(__dirname, \"../..\", \"index.js\");\n\n\tconst typeboxEntry = require.resolve(\"@sinclair/typebox\");\n\tconst typeboxRoot = typeboxEntry.replace(/[\\\\/]build[\\\\/]cjs[\\\\/]index\\.js$/, \"\");\n\n\tconst yamlEntry = require.resolve(\"yaml\");\n\tconst yamlRoot = yamlEntry.replace(/[\\\\/]dist[\\\\/]index\\.js$/, \"\");\n\n\tconst packagesRoot = path.resolve(__dirname, \"../../../../\");\n\tconst resolveWorkspaceOrImport = (workspaceRelativePath: string, specifier: string): string => {\n\t\tconst workspacePath = path.join(packagesRoot, workspaceRelativePath);\n\t\tif (fs.existsSync(workspacePath)) {\n\t\t\treturn workspacePath;\n\t\t}\n\t\treturn fileURLToPath(import.meta.resolve(specifier));\n\t};\n\n\t// Auto-discover subpath exports from bundled npm packages.\n\t// This ensures extensions can import any standard subpath (e.g. @modelcontextprotocol/sdk/server)\n\t// without hitting jiti's CJS double-resolve bug.\n\tconst autoDiscovered: Record<string, string> = {};\n\tfor (const packageName of BUNDLED_PACKAGES_WITH_EXPORTS) {\n\t\tconst subpathAliases = resolveSubpathExports(packageName);\n\t\tObject.assign(autoDiscovered, subpathAliases);\n\t}\n\n\t_aliases = {\n\t\t// Auto-discovered subpath exports (lowest priority — overridden by manual entries below)\n\t\t...autoDiscovered,\n\t\t// Manual entries for workspace packages and packages needing special resolution\n\t\t\"@gsd/pi-coding-agent\": packageIndex,\n\t\t\"@gsd/pi-agent-core\": resolveWorkspaceOrImport(\"agent/dist/index.js\", \"@gsd/pi-agent-core\"),\n\t\t\"@gsd/pi-tui\": resolveWorkspaceOrImport(\"tui/dist/index.js\", \"@gsd/pi-tui\"),\n\t\t\"@gsd/pi-ai\": resolveWorkspaceOrImport(\"ai/dist/index.js\", \"@gsd/pi-ai\"),\n\t\t\"@gsd/pi-ai/oauth\": resolveWorkspaceOrImport(\"ai/dist/oauth.js\", \"@gsd/pi-ai/oauth\"),\n\t\t\"@sinclair/typebox\": typeboxRoot,\n\t\t\"yaml\": yamlRoot,\n\t\t// Aliases for external PI ecosystem packages that import from the original scope\n\t\t\"@mariozechner/pi-coding-agent\": packageIndex,\n\t\t\"@mariozechner/pi-agent-core\": resolveWorkspaceOrImport(\"agent/dist/index.js\", \"@gsd/pi-agent-core\"),\n\t\t\"@mariozechner/pi-tui\": resolveWorkspaceOrImport(\"tui/dist/index.js\", \"@gsd/pi-tui\"),\n\t\t\"@mariozechner/pi-ai\": resolveWorkspaceOrImport(\"ai/dist/index.js\", \"@gsd/pi-ai\"),\n\t\t\"@mariozechner/pi-ai/oauth\": resolveWorkspaceOrImport(\"ai/dist/oauth.js\", \"@gsd/pi-ai/oauth\"),\n\t};\n\n\treturn _aliases;\n}\n\nfunction getJitiOptions() {\n\treturn isBunBinary ? { virtualModules: VIRTUAL_MODULES, tryNative: false } : { alias: getAliases() };\n}\n\nconst _moduleImporters = new Map<string, ReturnType<typeof createJiti>>();\n\nfunction getModuleImporter(parentModuleUrl: string) {\n\tlet importer = _moduleImporters.get(parentModuleUrl);\n\tif (!importer) {\n\t\timporter = createJiti(parentModuleUrl, {\n\t\t\tmoduleCache: true,\n\t\t\t...getJitiOptions(),\n\t\t});\n\t\t_moduleImporters.set(parentModuleUrl, importer);\n\t}\n\treturn importer;\n}\n\nexport async function importExtensionModule<T = unknown>(parentModuleUrl: string, specifier: string): Promise<T> {\n\tconst importer = getModuleImporter(parentModuleUrl);\n\tconst resolvedPath = fileURLToPath(new URL(specifier, parentModuleUrl));\n\treturn importer.import(resolvedPath) as Promise<T>;\n}\n\nconst UNICODE_SPACES = /[\\u00A0\\u1680\\u2000-\\u200A\\u202F\\u205F\\u3000]/g;\n\nfunction normalizeUnicodeSpaces(str: string): string {\n\treturn str.replace(UNICODE_SPACES, \" \");\n}\n\nfunction expandPath(p: string): string {\n\tconst normalized = normalizeUnicodeSpaces(p);\n\tif (normalized.startsWith(\"~/\")) {\n\t\treturn path.join(os.homedir(), normalized.slice(2));\n\t}\n\tif (normalized.startsWith(\"~\")) {\n\t\treturn path.join(os.homedir(), normalized.slice(1));\n\t}\n\treturn normalized;\n}\n\nfunction resolvePath(extPath: string, cwd: string): string {\n\tconst expanded = expandPath(extPath);\n\tif (path.isAbsolute(expanded)) {\n\t\treturn expanded;\n\t}\n\treturn path.resolve(cwd, expanded);\n}\n\ntype HandlerFn = (...args: unknown[]) => Promise<unknown>;\n\n/**\n * Create a runtime with throwing stubs for action methods.\n * Runner.bindCore() replaces these with real implementations.\n */\nexport function createExtensionRuntime(): ExtensionRuntime {\n\tconst notInitialized = () => {\n\t\tthrow new Error(\"Extension runtime not initialized. Action methods cannot be called during extension loading.\");\n\t};\n\n\tconst runtime: ExtensionRuntime = {\n\t\tsendMessage: notInitialized,\n\t\tsendUserMessage: notInitialized,\n\t\tretryLastTurn: notInitialized,\n\t\tappendEntry: notInitialized,\n\t\tsetSessionName: notInitialized,\n\t\tgetSessionName: notInitialized,\n\t\tsetLabel: notInitialized,\n\t\tgetActiveTools: notInitialized,\n\t\tgetAllTools: notInitialized,\n\t\tsetActiveTools: notInitialized,\n\t\t// registerTool() is valid during extension load; refresh is only needed post-bind.\n\t\trefreshTools: () => {},\n\t\tgetCommands: notInitialized,\n\t\tsetModel: () => Promise.reject(new Error(\"Extension runtime not initialized\")),\n\t\tgetThinkingLevel: notInitialized,\n\t\tsetThinkingLevel: notInitialized,\n\t\tflagValues: new Map(),\n\t\tpendingProviderRegistrations: [],\n\t\t// Pre-bind: queue registrations so bindCore() can flush them once the\n\t\t// model registry is available. bindCore() replaces both with direct calls.\n\t\tregisterProvider: (name, config) => {\n\t\t\truntime.pendingProviderRegistrations.push({ name, config });\n\t\t},\n\t\tunregisterProvider: (name) => {\n\t\t\truntime.pendingProviderRegistrations = runtime.pendingProviderRegistrations.filter((r) => r.name !== name);\n\t\t},\n\t\t// Stub replaced by ExtensionRunner at construction time via bindEmitMethods().\n\t\temitBeforeModelSelect: async () => undefined,\n\t};\n\n\treturn runtime;\n}\n\n/**\n * Create the ExtensionAPI for an extension.\n * Registration methods write to the extension object.\n * Action methods delegate to the shared runtime.\n */\nfunction createExtensionAPI(\n\textension: Extension,\n\truntime: ExtensionRuntime,\n\tcwd: string,\n\teventBus: EventBus,\n): ExtensionAPI {\n\tconst api = {\n\t\t// Registration methods - write to extension\n\t\ton(event: string, handler: HandlerFn): void {\n\t\t\tconst list = extension.handlers.get(event) ?? [];\n\t\t\tlist.push(handler);\n\t\t\textension.handlers.set(event, list);\n\t\t},\n\n\t\tregisterTool(tool: ToolDefinition): void {\n\t\t\textension.tools.set(tool.name, {\n\t\t\t\tdefinition: tool,\n\t\t\t\textensionPath: extension.path,\n\t\t\t});\n\t\t\truntime.refreshTools();\n\t\t},\n\n\t\tregisterCommand(name: string, options: Omit<RegisteredCommand, \"name\">): void {\n\t\t\textension.commands.set(name, { name, ...options });\n\t\t},\n\n\t\tregisterBeforeInstall(handler: LifecycleHookHandler): void {\n\t\t\textension.lifecycleHooks.beforeInstall.push(handler);\n\t\t},\n\n\t\tregisterAfterInstall(handler: LifecycleHookHandler): void {\n\t\t\textension.lifecycleHooks.afterInstall.push(handler);\n\t\t},\n\n\t\tregisterBeforeRemove(handler: LifecycleHookHandler): void {\n\t\t\textension.lifecycleHooks.beforeRemove.push(handler);\n\t\t},\n\n\t\tregisterAfterRemove(handler: LifecycleHookHandler): void {\n\t\t\textension.lifecycleHooks.afterRemove.push(handler);\n\t\t},\n\n\t\tregisterShortcut(\n\t\t\tshortcut: KeyId,\n\t\t\toptions: {\n\t\t\t\tdescription?: string;\n\t\t\t\thandler: (ctx: import(\"./types.js\").ExtensionContext) => Promise<void> | void;\n\t\t\t},\n\t\t): void {\n\t\t\textension.shortcuts.set(shortcut, { shortcut, extensionPath: extension.path, ...options });\n\t\t},\n\n\t\tregisterFlag(\n\t\t\tname: string,\n\t\t\toptions: { description?: string; type: \"boolean\" | \"string\"; default?: boolean | string },\n\t\t): void {\n\t\t\textension.flags.set(name, { name, extensionPath: extension.path, ...options });\n\t\t\tif (options.default !== undefined && !runtime.flagValues.has(name)) {\n\t\t\t\truntime.flagValues.set(name, options.default);\n\t\t\t}\n\t\t},\n\n\t\tregisterMessageRenderer<T>(customType: string, renderer: MessageRenderer<T>): void {\n\t\t\textension.messageRenderers.set(customType, renderer as MessageRenderer);\n\t\t},\n\n\t\t// Flag access - checks extension registered it, reads from runtime\n\t\tgetFlag(name: string): boolean | string | undefined {\n\t\t\tif (!extension.flags.has(name)) return undefined;\n\t\t\treturn runtime.flagValues.get(name);\n\t\t},\n\n\t\t// Action methods - delegate to shared runtime\n\t\tsendMessage(message, options): void {\n\t\t\truntime.sendMessage(message, options);\n\t\t},\n\n\t\tsendUserMessage(content, options): void {\n\t\t\truntime.sendUserMessage(content, options);\n\t\t},\n\n\t\tretryLastTurn(): void {\n\t\t\truntime.retryLastTurn();\n\t\t},\n\n\t\tappendEntry(customType: string, data?: unknown): void {\n\t\t\truntime.appendEntry(customType, data);\n\t\t},\n\n\t\tsetSessionName(name: string): void {\n\t\t\truntime.setSessionName(name);\n\t\t},\n\n\t\tgetSessionName(): string | undefined {\n\t\t\treturn runtime.getSessionName();\n\t\t},\n\n\t\tsetLabel(entryId: string, label: string | undefined): void {\n\t\t\truntime.setLabel(entryId, label);\n\t\t},\n\n\t\texec(command: string, args: string[], options?: ExecOptions) {\n\t\t\treturn execCommand(command, args, options?.cwd ?? cwd, options);\n\t\t},\n\n\t\tgetActiveTools(): string[] {\n\t\t\treturn runtime.getActiveTools();\n\t\t},\n\n\t\tgetAllTools() {\n\t\t\treturn runtime.getAllTools();\n\t\t},\n\n\t\tsetActiveTools(toolNames: string[]): void {\n\t\t\truntime.setActiveTools(toolNames);\n\t\t},\n\n\t\tgetCommands() {\n\t\t\treturn runtime.getCommands();\n\t\t},\n\n\t\tsetModel(model) {\n\t\t\treturn runtime.setModel(model);\n\t\t},\n\n\t\tgetThinkingLevel() {\n\t\t\treturn runtime.getThinkingLevel();\n\t\t},\n\n\t\tsetThinkingLevel(level) {\n\t\t\truntime.setThinkingLevel(level);\n\t\t},\n\n\t\tregisterProvider(name: string, config: ProviderConfig) {\n\t\t\truntime.registerProvider(name, config);\n\t\t},\n\n\t\tunregisterProvider(name: string) {\n\t\t\truntime.unregisterProvider(name);\n\t\t},\n\n\t\tasync emitBeforeModelSelect(event: Omit<import(\"./types.js\").BeforeModelSelectEvent, \"type\">): Promise<import(\"./types.js\").BeforeModelSelectResult | undefined> {\n\t\t\treturn runtime.emitBeforeModelSelect(event);\n\t\t},\n\n\t\tevents: eventBus,\n\t} as ExtensionAPI;\n\n\treturn api;\n}\n\n/**\n * Heuristic patterns that indicate TypeScript syntax in a source file.\n * Used to detect when a .js file accidentally contains TypeScript code\n * and provide a helpful error message instead of a cryptic parse failure.\n */\nconst TS_SYNTAX_PATTERNS: RegExp[] = [\n\t// Variable type annotations: const name: string, let count: number\n\t/\\b(?:const|let|var)\\s+\\w+\\s*:\\s*(?:string|number|boolean|any|void|never|unknown|object|bigint|symbol|undefined|null)\\b/,\n\t// Parameter type annotations: (api: ExtensionAPI)\n\t/\\(\\s*\\w+\\s*:\\s*[A-Z]\\w*/,\n\t// Return type annotations: ): Promise<void> { or ): string =>\n\t/\\)\\s*:\\s*(?:Promise|string|number|boolean|void|any|never|unknown)\\b/,\n\t// Interface declarations\n\t/\\binterface\\s+[A-Z]\\w*\\s*(?:<[^>]*>)?\\s*\\{/,\n\t// Type alias declarations\n\t/\\btype\\s+[A-Z]\\w*\\s*(?:<[^>]*>)?\\s*=/,\n\t// Angle-bracket type assertions: <Type>value\n\t/(?:as\\s+\\w+(?:<[^>]*>)?)\\s*[;,)\\]}]/,\n\t// Generic type parameters on functions: function foo<T>\n\t/\\bfunction\\s+\\w+\\s*<[^>]+>/,\n\t// Enum declarations\n\t/\\benum\\s+[A-Z]\\w*\\s*\\{/,\n];\n\n/**\n * Check whether a source string likely contains TypeScript syntax.\n * This is a heuristic — it may produce false positives for unusual JS,\n * but is tuned to catch the most common TS-in-JS mistakes.\n */\nexport function containsTypeScriptSyntax(source: string): boolean {\n\treturn TS_SYNTAX_PATTERNS.some((pattern) => pattern.test(source));\n}\n\n/**\n * Shared jiti instance for loading extension modules.\n *\n * Before this fix (#2108), each extension created a NEW jiti instance with\n * `moduleCache: false`, causing shared dependencies (e.g. @gsd/pi-agent-core)\n * to be recompiled for every extension — turning a ~3s parallel load into a\n * ~15-30s serial compilation bottleneck.\n *\n * Using a single shared instance with `moduleCache: true` means shared modules\n * are compiled once and reused across all extensions.\n */\nlet _extensionLoaderJiti: ReturnType<typeof createJiti> | null = null;\n\n/**\n * Reset the shared jiti singleton so the next call to getExtensionLoaderJiti()\n * creates a fresh instance. This prevents memory leaks in long-running daemon\n * processes (every loaded module stays cached forever) and ensures stale modules\n * are not returned when extension source changes on disk.\n */\nexport function resetExtensionLoaderCache(): void {\n\t_extensionLoaderJiti = null;\n}\n\nfunction getExtensionLoaderJiti() {\n\tif (!_extensionLoaderJiti) {\n\t\t_extensionLoaderJiti = createJiti(import.meta.url, {\n\t\t\tmoduleCache: true,\n\t\t\t...getJitiOptions(),\n\t\t});\n\t}\n\treturn _extensionLoaderJiti;\n}\n\nasync function loadExtensionModule(extensionPath: string) {\n\t// Pre-compiled extension loading: if the source is .ts and a sibling .js\n\t// file exists with matching or newer mtime, use native import() to skip\n\t// jiti JIT compilation entirely. This is the biggest startup win for\n\t// bundled extensions that have already been built.\n\tif (extensionPath.endsWith(\".ts\")) {\n\t\tconst jsPath = extensionPath.replace(/\\.ts$/, \".js\");\n\t\ttry {\n\t\t\tconst [tsStat, jsStat] = [fs.statSync(extensionPath), fs.statSync(jsPath)];\n\t\t\tif (jsStat.mtimeMs >= tsStat.mtimeMs) {\n\t\t\t\tconst module = await import(jsPath);\n\t\t\t\tconst factory = (module.default ?? module) as ExtensionFactory;\n\t\t\t\treturn typeof factory !== \"function\" ? undefined : factory;\n\t\t\t}\n\t\t} catch {\n\t\t\t// .js file doesn't exist or stat failed — fall through to jiti\n\t\t}\n\t}\n\n\tconst jiti = getExtensionLoaderJiti();\n\n\tconst module = await jiti.import(extensionPath, { default: true });\n\tconst factory = module as ExtensionFactory;\n\treturn typeof factory !== \"function\" ? undefined : factory;\n}\n\n/**\n * Check whether a module path belongs to a non-extension library that should\n * be silently skipped rather than reported as an error.\n *\n * A directory is a non-extension library when its package.json has a \"pi\"\n * manifest that declares no extensions (e.g. `\"pi\": {}`). This is the\n * opt-out convention used by shared libraries like cmux that live inside\n * the extensions/ directory but are not extensions themselves.\n *\n * This serves as a defense-in-depth check: even if the upstream discovery\n * layers fail to filter out the library, the loader itself will not emit\n * a spurious error.\n */\nfunction isNonExtensionLibrary(resolvedPath: string): boolean {\n\t// Walk up from the resolved file to find the nearest package.json\n\tlet dir = path.dirname(resolvedPath);\n\tconst root = path.parse(dir).root;\n\twhile (dir !== root) {\n\t\tconst packageJsonPath = path.join(dir, \"package.json\");\n\t\tif (fs.existsSync(packageJsonPath)) {\n\t\t\ttry {\n\t\t\t\tconst content = fs.readFileSync(packageJsonPath, \"utf-8\");\n\t\t\t\tconst pkg = JSON.parse(content);\n\t\t\t\tif (pkg.pi && typeof pkg.pi === \"object\") {\n\t\t\t\t\t// Has a pi manifest — check if it declares any extensions\n\t\t\t\t\tconst extensions = pkg.pi.extensions;\n\t\t\t\t\tif (!Array.isArray(extensions) || extensions.length === 0) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Malformed package.json — not a known library\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tdir = path.dirname(dir);\n\t}\n\treturn false;\n}\n\n/**\n * Create an Extension object with empty collections.\n */\nfunction createExtension(extensionPath: string, resolvedPath: string): Extension {\n\treturn {\n\t\tpath: extensionPath,\n\t\tresolvedPath,\n\t\thandlers: new Map(),\n\t\ttools: new Map(),\n\t\tmessageRenderers: new Map(),\n\t\tcommands: new Map(),\n\t\tflags: new Map(),\n\t\tshortcuts: new Map(),\n\t\tlifecycleHooks: {\n\t\t\tbeforeInstall: [],\n\t\t\tafterInstall: [],\n\t\t\tbeforeRemove: [],\n\t\t\tafterRemove: [],\n\t\t},\n\t};\n}\n\nasync function loadExtension(\n\textensionPath: string,\n\tcwd: string,\n\teventBus: EventBus,\n\truntime: ExtensionRuntime,\n): Promise<{ extension: Extension | null; error: string | null }> {\n\tconst resolvedPath = resolvePath(extensionPath, cwd);\n\tconst start = Date.now();\n\n\ttry {\n\t\tconst factory = await loadExtensionModule(resolvedPath);\n\t\tif (!factory) {\n\t\t\t// Defense-in-depth: if the module is inside a directory that has\n\t\t\t// explicitly opted out of extension loading via its pi manifest,\n\t\t\t// silently skip it instead of reporting a spurious error.\n\t\t\tif (isNonExtensionLibrary(resolvedPath)) {\n\t\t\t\treturn { extension: null, error: null };\n\t\t\t}\n\t\t\tlogExtensionTiming(extensionPath, Date.now() - start, \"failed\");\n\n\t\t\t// Check if a .js file contains TypeScript syntax\n\t\t\tif (resolvedPath.endsWith(\".js\")) {\n\t\t\t\ttry {\n\t\t\t\t\tconst source = fs.readFileSync(resolvedPath, \"utf-8\");\n\t\t\t\t\tif (containsTypeScriptSyntax(source)) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\textension: null,\n\t\t\t\t\t\t\terror: `Extension file \"${extensionPath}\" appears to contain TypeScript syntax but has a .js extension. Rename it to .ts so the loader can compile it.`,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Could not read file — fall through to generic error\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { extension: null, error: `Extension does not export a valid factory function: ${extensionPath}` };\n\t\t}\n\n\t\tconst extension = createExtension(extensionPath, resolvedPath);\n\t\tconst api = createExtensionAPI(extension, runtime, cwd, eventBus);\n\t\tawait factory(api);\n\t\tlogExtensionTiming(extensionPath, Date.now() - start, \"loaded\");\n\n\t\treturn { extension, error: null };\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tlogExtensionTiming(extensionPath, Date.now() - start, \"failed\");\n\n\t\t// Check if a .js file contains TypeScript syntax — the parse error from\n\t\t// jiti/Node is often cryptic, so surface a clearer diagnostic.\n\t\tif (resolvedPath.endsWith(\".js\")) {\n\t\t\ttry {\n\t\t\t\tconst source = fs.readFileSync(resolvedPath, \"utf-8\");\n\t\t\t\tif (containsTypeScriptSyntax(source)) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\textension: null,\n\t\t\t\t\t\terror: `Extension file \"${extensionPath}\" appears to contain TypeScript syntax but has a .js extension. Rename it to .ts so the loader can compile it.`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Could not read file — fall through to generic error\n\t\t\t}\n\t\t}\n\n\t\treturn { extension: null, error: `Failed to load extension: ${message}` };\n\t}\n}\n\n/**\n * Create an Extension from an inline factory function.\n */\nexport async function loadExtensionFromFactory(\n\tfactory: ExtensionFactory,\n\tcwd: string,\n\teventBus: EventBus,\n\truntime: ExtensionRuntime,\n\textensionPath = \"<inline>\",\n): Promise<Extension> {\n\tconst extension = createExtension(extensionPath, extensionPath);\n\tconst api = createExtensionAPI(extension, runtime, cwd, eventBus);\n\tawait factory(api);\n\treturn extension;\n}\n\n/**\n * Load extensions from paths.\n *\n * Extensions are loaded in parallel to reduce wall-clock time (~30-50% faster\n * than sequential loading for I/O-bound jiti compilation).\n */\nexport async function loadExtensions(paths: string[], cwd: string, eventBus?: EventBus): Promise<LoadExtensionsResult> {\n\tconst resolvedEventBus = eventBus ?? createEventBus();\n\tconst runtime = createExtensionRuntime();\n\n\tconst results = await Promise.all(\n\t\tpaths.map((extPath) => loadExtension(extPath, cwd, resolvedEventBus, runtime)),\n\t);\n\n\tconst extensions: Extension[] = [];\n\tconst errors: Array<{ path: string; error: string }> = [];\n\n\tfor (let i = 0; i < results.length; i++) {\n\t\tconst { extension, error } = results[i];\n\t\tif (error) {\n\t\t\terrors.push({ path: paths[i], error });\n\t\t} else if (extension) {\n\t\t\textensions.push(extension);\n\t\t}\n\t}\n\n\treturn {\n\t\textensions,\n\t\terrors,\n\t\truntime,\n\t};\n}\n\ninterface PiManifest {\n\textensions?: string[];\n\tthemes?: string[];\n\tskills?: string[];\n\tprompts?: string[];\n}\n\nfunction readPiManifest(packageJsonPath: string): PiManifest | null {\n\ttry {\n\t\tconst content = fs.readFileSync(packageJsonPath, \"utf-8\");\n\t\tconst pkg = JSON.parse(content);\n\t\tif (pkg.pi && typeof pkg.pi === \"object\") {\n\t\t\treturn pkg.pi as PiManifest;\n\t\t}\n\t\treturn null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction isExtensionFile(name: string): boolean {\n\treturn name.endsWith(\".ts\") || name.endsWith(\".js\");\n}\n\n/**\n * Resolve extension entry points from a directory.\n *\n * Checks for:\n * 1. package.json with \"pi.extensions\" field -> returns declared paths\n * 2. index.ts or index.js -> returns the index file\n *\n * Returns resolved paths or null if no entry points found.\n */\nfunction resolveExtensionEntries(dir: string): string[] | null {\n\t// Check for package.json with \"pi\" field first\n\tconst packageJsonPath = path.join(dir, \"package.json\");\n\tif (fs.existsSync(packageJsonPath)) {\n\t\tconst manifest = readPiManifest(packageJsonPath);\n\t\tif (manifest) {\n\t\t\t// When a pi manifest exists, it is authoritative — don't fall through\n\t\t\t// to index.ts/index.js auto-detection. This allows library directories\n\t\t\t// (like cmux) to opt out by declaring \"pi\": {} with no extensions.\n\t\t\tif (!manifest.extensions?.length) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst entries: string[] = [];\n\t\t\tfor (const extPath of manifest.extensions) {\n\t\t\t\tconst resolvedExtPath = path.resolve(dir, extPath);\n\t\t\t\tif (fs.existsSync(resolvedExtPath)) {\n\t\t\t\t\tentries.push(resolvedExtPath);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn entries.length > 0 ? entries : null;\n\t\t}\n\t}\n\n\t// Check for index.ts or index.js\n\tconst indexTs = path.join(dir, \"index.ts\");\n\tconst indexJs = path.join(dir, \"index.js\");\n\tif (fs.existsSync(indexTs)) {\n\t\treturn [indexTs];\n\t}\n\tif (fs.existsSync(indexJs)) {\n\t\treturn [indexJs];\n\t}\n\n\treturn null;\n}\n\n/**\n * Discover extensions in a directory.\n *\n * Discovery rules:\n * 1. Direct files: `extensions/*.ts` or `*.js` → load\n * 2. Subdirectory with index: `extensions/* /index.ts` or `index.js` → load\n * 3. Subdirectory with package.json: `extensions/* /package.json` with \"pi\" field → load what it declares\n *\n * No recursion beyond one level. Complex packages must use package.json manifest.\n */\nfunction discoverExtensionsInDir(dir: string): string[] {\n\tif (!fs.existsSync(dir)) {\n\t\treturn [];\n\t}\n\n\tconst discovered: string[] = [];\n\n\ttry {\n\t\tconst entries = fs.readdirSync(dir, { withFileTypes: true });\n\n\t\tfor (const entry of entries) {\n\t\t\tconst entryPath = path.join(dir, entry.name);\n\n\t\t\t// 1. Direct files: *.ts or *.js\n\t\t\tif ((entry.isFile() || entry.isSymbolicLink()) && isExtensionFile(entry.name)) {\n\t\t\t\tdiscovered.push(entryPath);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// 2 & 3. Subdirectories\n\t\t\tif (entry.isDirectory() || entry.isSymbolicLink()) {\n\t\t\t\tconst entries = resolveExtensionEntries(entryPath);\n\t\t\t\tif (entries) {\n\t\t\t\t\tdiscovered.push(...entries);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch {\n\t\treturn [];\n\t}\n\n\treturn discovered;\n}\n\n/**\n * Discover and load extensions from standard locations.\n *\n * @deprecated Use DefaultResourceLoader.reload() instead — this function is\n * not called in the GSD loading flow. Extension discovery happens through\n * DefaultPackageManager.resolve() → addAutoDiscoveredResources(). Kept for\n * backwards compatibility with direct pi-coding-agent consumers.\n */\nexport async function discoverAndLoadExtensions(\n\tconfiguredPaths: string[],\n\tcwd: string,\n\tagentDir: string = getAgentDir(),\n\teventBus?: EventBus,\n): Promise<LoadExtensionsResult> {\n\tconst allPaths: string[] = [];\n\tconst seen = new Set<string>();\n\n\tconst addPaths = (paths: string[]) => {\n\t\tfor (const p of paths) {\n\t\t\tconst resolved = path.resolve(p);\n\t\t\tif (!seen.has(resolved)) {\n\t\t\t\tseen.add(resolved);\n\t\t\t\tallPaths.push(p);\n\t\t\t}\n\t\t}\n\t};\n\n\t// 1. Project-local extensions: cwd/.pi/extensions/\n\t// Only loaded when the project path has been explicitly trusted (TOFU model).\n\tconst localExtDir = path.join(cwd, \".pi\", \"extensions\");\n\tconst localDiscovered = discoverExtensionsInDir(localExtDir);\n\tif (localDiscovered.length > 0) {\n\t\tconst untrusted = getUntrustedExtensionPaths(cwd, localDiscovered, agentDir);\n\t\tif (untrusted.length > 0) {\n\t\t\tprocess.stderr.write(\n\t\t\t\t`[pi] Skipping ${untrusted.length} project-local extension(s) in ${localExtDir} — project not trusted. Use trustProject() to enable.\\n`,\n\t\t\t);\n\t\t}\n\t\tconst trusted = localDiscovered.filter((p) => !untrusted.includes(p));\n\t\taddPaths(trusted);\n\t}\n\n\t// 2. Global extensions: agentDir/extensions/\n\tconst globalExtDir = path.join(agentDir, \"extensions\");\n\taddPaths(discoverExtensionsInDir(globalExtDir));\n\n\t// 3. Explicitly configured paths\n\tfor (const p of configuredPaths) {\n\t\tconst resolved = resolvePath(p, cwd);\n\t\tif (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) {\n\t\t\t// Check for package.json with pi manifest or index.ts\n\t\t\tconst entries = resolveExtensionEntries(resolved);\n\t\t\tif (entries) {\n\t\t\t\taddPaths(entries);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// No explicit entries - discover individual files in directory\n\t\t\taddPaths(discoverExtensionsInDir(resolved));\n\t\t\tcontinue;\n\t\t}\n\n\t\taddPaths([resolved]);\n\t}\n\n\treturn loadExtensions(allPaths, cwd, eventBus);\n}\n"]}
@@ -4,7 +4,7 @@ import * as fs from "node:fs";
4
4
  import * as os from "node:os";
5
5
  import * as path from "node:path";
6
6
  import { isProjectTrusted, trustProject, getUntrustedExtensionPaths } from "./project-trust.js";
7
- import { containsTypeScriptSyntax, loadExtensions } from "./loader.js";
7
+ import { containsTypeScriptSyntax, loadExtensions, resetExtensionLoaderCache } from "./loader.js";
8
8
  // ─── helpers ──────────────────────────────────────────────────────────────────
9
9
  function makeTempDir() {
10
10
  return fs.mkdtempSync(path.join(os.tmpdir(), "loader-test-"));
@@ -173,4 +173,31 @@ describe("loadExtensions", () => {
173
173
  assert.ok(/TypeScript/.test(errorMsg) && /\.ts\b/.test(errorMsg), `Expected error to mention TypeScript syntax and .ts extension, got: ${errorMsg}`);
174
174
  });
175
175
  });
176
+ // ─── resetExtensionLoaderCache ───────────────────────────────────────────────
177
+ describe("resetExtensionLoaderCache", () => {
178
+ let tmpDir;
179
+ beforeEach(() => {
180
+ tmpDir = makeTempDir();
181
+ // Always start with a clean cache so tests are independent
182
+ resetExtensionLoaderCache();
183
+ });
184
+ afterEach(() => {
185
+ resetExtensionLoaderCache();
186
+ cleanDir(tmpDir);
187
+ });
188
+ it("clears the jiti singleton so a fresh instance is created on next load", async () => {
189
+ // Write a minimal valid extension that returns a name
190
+ const extPath = path.join(tmpDir, "cache-ext.ts");
191
+ fs.writeFileSync(extPath, `export default function activate(api: any) { return { name: "cache-ext" }; }\n`);
192
+ // First load — creates the jiti singleton and caches the module
193
+ const result1 = await loadExtensions([extPath], tmpDir);
194
+ assert.equal(result1.extensions.length, 1, "first load should succeed");
195
+ // Reset the cache — nulls the singleton
196
+ resetExtensionLoaderCache();
197
+ // Second load — should create a new jiti instance (not reuse the old one)
198
+ // and still successfully load the extension
199
+ const result2 = await loadExtensions([extPath], tmpDir);
200
+ assert.equal(result2.extensions.length, 1, "load after reset should succeed with fresh jiti");
201
+ });
202
+ });
176
203
  //# sourceMappingURL=loader.test.js.map