@code-yeongyu/senpi 2026.7.14-3 → 2026.7.16-2

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 (361) hide show
  1. package/CHANGELOG.md +105 -0
  2. package/README.md +6 -6
  3. package/dist/bun/cli.js +2 -0
  4. package/dist/bun/cli.js.map +1 -1
  5. package/dist/cli/args.js +1 -1
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/cli/list-models.d.ts +2 -2
  8. package/dist/cli/list-models.d.ts.map +1 -1
  9. package/dist/cli/list-models.js +3 -3
  10. package/dist/cli/list-models.js.map +1 -1
  11. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  12. package/dist/core/agent-session-runtime.js +3 -0
  13. package/dist/core/agent-session-runtime.js.map +1 -1
  14. package/dist/core/agent-session-services.d.ts +4 -3
  15. package/dist/core/agent-session-services.d.ts.map +1 -1
  16. package/dist/core/agent-session-services.js +14 -5
  17. package/dist/core/agent-session-services.js.map +1 -1
  18. package/dist/core/agent-session.d.ts +8 -4
  19. package/dist/core/agent-session.d.ts.map +1 -1
  20. package/dist/core/agent-session.js +80 -29
  21. package/dist/core/agent-session.js.map +1 -1
  22. package/dist/core/auth-providers.js +1 -1
  23. package/dist/core/auth-providers.js.map +1 -1
  24. package/dist/core/auth-storage.d.ts +32 -87
  25. package/dist/core/auth-storage.d.ts.map +1 -1
  26. package/dist/core/auth-storage.js +158 -221
  27. package/dist/core/auth-storage.js.map +1 -1
  28. package/dist/core/cache-stats.d.ts +2 -2
  29. package/dist/core/cache-stats.d.ts.map +1 -1
  30. package/dist/core/cache-stats.js +1 -1
  31. package/dist/core/cache-stats.js.map +1 -1
  32. package/dist/core/dynamic-prompt/build.d.ts.map +1 -1
  33. package/dist/core/dynamic-prompt/build.js +6 -1
  34. package/dist/core/dynamic-prompt/build.js.map +1 -1
  35. package/dist/core/extensions/builtin/bash-timeout/timeout.js +2 -2
  36. package/dist/core/extensions/builtin/bash-timeout/timeout.js.map +1 -1
  37. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js +8 -8
  38. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js.map +1 -1
  39. package/dist/core/extensions/loader.d.ts.map +1 -1
  40. package/dist/core/extensions/loader.js +8 -2
  41. package/dist/core/extensions/loader.js.map +1 -1
  42. package/dist/core/extensions/runner.d.ts +1 -0
  43. package/dist/core/extensions/runner.d.ts.map +1 -1
  44. package/dist/core/extensions/runner.js +3 -0
  45. package/dist/core/extensions/runner.js.map +1 -1
  46. package/dist/core/extensions/types.d.ts +15 -2
  47. package/dist/core/extensions/types.d.ts.map +1 -1
  48. package/dist/core/extensions/types.js.map +1 -1
  49. package/dist/core/model-config.d.ts +589 -0
  50. package/dist/core/model-config.d.ts.map +1 -0
  51. package/dist/core/model-config.js +288 -0
  52. package/dist/core/model-config.js.map +1 -0
  53. package/dist/core/model-registry.d.ts +17 -146
  54. package/dist/core/model-registry.d.ts.map +1 -1
  55. package/dist/core/model-registry.js +69 -958
  56. package/dist/core/model-registry.js.map +1 -1
  57. package/dist/core/model-resolver.d.ts +8 -5
  58. package/dist/core/model-resolver.d.ts.map +1 -1
  59. package/dist/core/model-resolver.js +18 -18
  60. package/dist/core/model-resolver.js.map +1 -1
  61. package/dist/core/model-runtime.d.ts +81 -0
  62. package/dist/core/model-runtime.d.ts.map +1 -0
  63. package/dist/core/model-runtime.js +442 -0
  64. package/dist/core/model-runtime.js.map +1 -0
  65. package/dist/core/models-store.d.ts +17 -0
  66. package/dist/core/models-store.d.ts.map +1 -0
  67. package/dist/core/models-store.js +46 -0
  68. package/dist/core/models-store.js.map +1 -0
  69. package/dist/core/provider-composer.d.ts +64 -0
  70. package/dist/core/provider-composer.d.ts.map +1 -0
  71. package/dist/core/provider-composer.js +406 -0
  72. package/dist/core/provider-composer.js.map +1 -0
  73. package/dist/core/provider-display-names.js +1 -1
  74. package/dist/core/provider-display-names.js.map +1 -1
  75. package/dist/core/radius.d.ts +0 -19
  76. package/dist/core/radius.d.ts.map +1 -1
  77. package/dist/core/radius.js +0 -28
  78. package/dist/core/radius.js.map +1 -1
  79. package/dist/core/remote-catalog-provider.d.ts +5 -0
  80. package/dist/core/remote-catalog-provider.d.ts.map +1 -0
  81. package/dist/core/remote-catalog-provider.js +83 -0
  82. package/dist/core/remote-catalog-provider.js.map +1 -0
  83. package/dist/core/runtime-credentials.d.ts +15 -0
  84. package/dist/core/runtime-credentials.d.ts.map +1 -0
  85. package/dist/core/runtime-credentials.js +35 -0
  86. package/dist/core/runtime-credentials.js.map +1 -0
  87. package/dist/core/sdk.d.ts +11 -20
  88. package/dist/core/sdk.d.ts.map +1 -1
  89. package/dist/core/sdk.js +61 -89
  90. package/dist/core/sdk.js.map +1 -1
  91. package/dist/core/skills.js +1 -1
  92. package/dist/core/skills.js.map +1 -1
  93. package/dist/index.d.ts +2 -1
  94. package/dist/index.d.ts.map +1 -1
  95. package/dist/index.js +2 -2
  96. package/dist/index.js.map +1 -1
  97. package/dist/main.d.ts.map +1 -1
  98. package/dist/main.js +10 -13
  99. package/dist/main.js.map +1 -1
  100. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  101. package/dist/modes/interactive/components/assistant-message.js +22 -10
  102. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  103. package/dist/modes/interactive/components/footer.js +1 -1
  104. package/dist/modes/interactive/components/footer.js.map +1 -1
  105. package/dist/modes/interactive/components/login-dialog.d.ts +4 -8
  106. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  107. package/dist/modes/interactive/components/login-dialog.js +14 -12
  108. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  109. package/dist/modes/interactive/components/model-selector.d.ts +13 -4
  110. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  111. package/dist/modes/interactive/components/model-selector.js +84 -41
  112. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  113. package/dist/modes/interactive/components/oauth-selector.d.ts +4 -4
  114. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  115. package/dist/modes/interactive/components/oauth-selector.js +14 -25
  116. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  117. package/dist/modes/interactive/interactive-mode.d.ts +5 -1
  118. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  119. package/dist/modes/interactive/interactive-mode.js +154 -128
  120. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  121. package/dist/package-manager-cli.d.ts.map +1 -1
  122. package/dist/package-manager-cli.js +70 -8
  123. package/dist/package-manager-cli.js.map +1 -1
  124. package/docs/custom-provider.md +6 -11
  125. package/docs/extensions.md +78 -555
  126. package/docs/models.md +2 -0
  127. package/docs/packages.md +1 -0
  128. package/docs/providers.md +23 -11
  129. package/docs/sdk.md +79 -105
  130. package/docs/usage.md +1 -0
  131. package/examples/extensions/README.md +1 -0
  132. package/examples/extensions/custom-provider-anthropic/index.ts +1 -1
  133. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  134. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  135. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  136. package/examples/extensions/gondolin/package-lock.json +2 -2
  137. package/examples/extensions/gondolin/package.json +1 -1
  138. package/examples/extensions/kimi-deferred-tools.ts +61 -0
  139. package/examples/extensions/sandbox/package-lock.json +2 -2
  140. package/examples/extensions/sandbox/package.json +1 -1
  141. package/examples/extensions/with-deps/package-lock.json +2 -2
  142. package/examples/extensions/with-deps/package.json +1 -1
  143. package/examples/sdk/02-custom-model.ts +5 -8
  144. package/examples/sdk/09-api-keys-and-oauth.ts +13 -31
  145. package/examples/sdk/12-full-control.ts +8 -13
  146. package/examples/sdk/README.md +14 -18
  147. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +16 -0
  148. package/node_modules/@code-yeongyu/senpi-codemode/package.json +3 -3
  149. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/local-module-loader.ts +2 -2
  150. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/rewrite-imports.ts +4 -4
  151. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/render.ts +32 -32
  152. package/node_modules/@earendil-works/pi-agent-core/package.json +4 -4
  153. package/node_modules/@earendil-works/pi-ai/README.md +77 -23
  154. package/node_modules/@earendil-works/pi-ai/dist/api/lazy.d.ts.map +1 -1
  155. package/node_modules/@earendil-works/pi-ai/dist/api/lazy.js +9 -10
  156. package/node_modules/@earendil-works/pi-ai/dist/api/lazy.js.map +1 -1
  157. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts.map +1 -1
  158. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +3 -2
  159. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
  160. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts +2 -1
  161. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
  162. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +42 -2
  163. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  164. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +2 -0
  165. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  166. package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.d.ts +2 -1
  167. package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.d.ts.map +1 -1
  168. package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.js +3 -0
  169. package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.js.map +1 -1
  170. package/node_modules/@earendil-works/pi-ai/dist/auth/helpers.d.ts +1 -0
  171. package/node_modules/@earendil-works/pi-ai/dist/auth/helpers.d.ts.map +1 -1
  172. package/node_modules/@earendil-works/pi-ai/dist/auth/helpers.js +4 -3
  173. package/node_modules/@earendil-works/pi-ai/dist/auth/helpers.js.map +1 -1
  174. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.d.ts +9 -0
  175. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.d.ts.map +1 -0
  176. package/node_modules/@earendil-works/pi-ai/dist/{utils → auth}/oauth/anthropic.js +51 -116
  177. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.js.map +1 -0
  178. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/device-code.d.ts.map +1 -0
  179. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/device-code.js.map +1 -0
  180. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.d.ts +6 -0
  181. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.d.ts.map +1 -0
  182. package/node_modules/@earendil-works/pi-ai/dist/{utils → auth}/oauth/github-copilot.js +18 -77
  183. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.js.map +1 -0
  184. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.d.ts +23 -0
  185. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.d.ts.map +1 -0
  186. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.js +49 -0
  187. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.js.map +1 -0
  188. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/oauth-page.d.ts.map +1 -0
  189. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/oauth-page.js.map +1 -0
  190. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/openai-codex.d.ts +9 -0
  191. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/openai-codex.d.ts.map +1 -0
  192. package/node_modules/@earendil-works/pi-ai/dist/{utils → auth}/oauth/openai-codex.js +61 -155
  193. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/openai-codex.js.map +1 -0
  194. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/pkce.d.ts.map +1 -0
  195. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/pkce.js.map +1 -0
  196. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/radius.d.ts +16 -0
  197. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/radius.d.ts.map +1 -0
  198. package/node_modules/@earendil-works/pi-ai/dist/{utils → auth}/oauth/radius.js +31 -128
  199. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/radius.js.map +1 -0
  200. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/xai.d.ts +6 -0
  201. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/xai.d.ts.map +1 -0
  202. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/xai.js +189 -0
  203. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/xai.js.map +1 -0
  204. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.d.ts +2 -4
  205. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.d.ts.map +1 -1
  206. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js +9 -7
  207. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js.map +1 -1
  208. package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts +49 -10
  209. package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts.map +1 -1
  210. package/node_modules/@earendil-works/pi-ai/dist/auth/types.js.map +1 -1
  211. package/node_modules/@earendil-works/pi-ai/dist/bun-oauth.d.ts +3 -0
  212. package/node_modules/@earendil-works/pi-ai/dist/bun-oauth.d.ts.map +1 -0
  213. package/node_modules/@earendil-works/pi-ai/dist/bun-oauth.js +17 -0
  214. package/node_modules/@earendil-works/pi-ai/dist/bun-oauth.js.map +1 -0
  215. package/node_modules/@earendil-works/pi-ai/dist/cli.js +58 -76
  216. package/node_modules/@earendil-works/pi-ai/dist/cli.js.map +1 -1
  217. package/node_modules/@earendil-works/pi-ai/dist/compat/extension-oauth-types.d.ts +42 -0
  218. package/node_modules/@earendil-works/pi-ai/dist/compat/extension-oauth-types.d.ts.map +1 -0
  219. package/node_modules/@earendil-works/pi-ai/dist/compat/extension-oauth-types.js +2 -0
  220. package/node_modules/@earendil-works/pi-ai/dist/compat/extension-oauth-types.js.map +1 -0
  221. package/node_modules/@earendil-works/pi-ai/dist/compat.d.ts.map +1 -1
  222. package/node_modules/@earendil-works/pi-ai/dist/compat.js +46 -22
  223. package/node_modules/@earendil-works/pi-ai/dist/compat.js.map +1 -1
  224. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js +1 -1
  225. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js.map +1 -1
  226. package/node_modules/@earendil-works/pi-ai/dist/images-models.d.ts +4 -2
  227. package/node_modules/@earendil-works/pi-ai/dist/images-models.d.ts.map +1 -1
  228. package/node_modules/@earendil-works/pi-ai/dist/images-models.js +5 -4
  229. package/node_modules/@earendil-works/pi-ai/dist/images-models.js.map +1 -1
  230. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +2 -1
  231. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
  232. package/node_modules/@earendil-works/pi-ai/dist/index.js +1 -0
  233. package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
  234. package/node_modules/@earendil-works/pi-ai/dist/models-store.d.ts +25 -0
  235. package/node_modules/@earendil-works/pi-ai/dist/models-store.d.ts.map +1 -0
  236. package/node_modules/@earendil-works/pi-ai/dist/models-store.js +16 -0
  237. package/node_modules/@earendil-works/pi-ai/dist/models-store.js.map +1 -0
  238. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts +69 -30
  239. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
  240. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +270 -114
  241. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
  242. package/node_modules/@earendil-works/pi-ai/dist/models.js +217 -31
  243. package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
  244. package/node_modules/@earendil-works/pi-ai/dist/oauth.d.ts +2 -1
  245. package/node_modules/@earendil-works/pi-ai/dist/oauth.d.ts.map +1 -1
  246. package/node_modules/@earendil-works/pi-ai/dist/oauth.js +1 -1
  247. package/node_modules/@earendil-works/pi-ai/dist/oauth.js.map +1 -1
  248. package/node_modules/@earendil-works/pi-ai/dist/providers/all.d.ts +2 -1
  249. package/node_modules/@earendil-works/pi-ai/dist/providers/all.d.ts.map +1 -1
  250. package/node_modules/@earendil-works/pi-ai/dist/providers/all.js +3 -0
  251. package/node_modules/@earendil-works/pi-ai/dist/providers/all.js.map +1 -1
  252. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
  253. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js +51 -10
  254. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  255. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  256. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js +1 -1
  257. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js.map +1 -1
  258. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.d.ts.map +1 -1
  259. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.js +4 -3
  260. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.js.map +1 -1
  261. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-auth.d.ts.map +1 -1
  262. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-auth.js +13 -20
  263. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-auth.js.map +1 -1
  264. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-stream.d.ts +8 -0
  265. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-stream.d.ts.map +1 -0
  266. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-stream.js +21 -0
  267. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-stream.js.map +1 -0
  268. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-workers-ai.d.ts.map +1 -1
  269. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-workers-ai.js +2 -1
  270. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-workers-ai.js.map +1 -1
  271. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.d.ts.map +1 -1
  272. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.js +11 -1
  273. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.js.map +1 -1
  274. package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.d.ts.map +1 -1
  275. package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.js +56 -5
  276. package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.js.map +1 -1
  277. package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.d.ts +66 -0
  278. package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.d.ts.map +1 -1
  279. package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.js +42 -0
  280. package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.js.map +1 -1
  281. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai-cn.models.d.ts +36 -0
  282. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai-cn.models.d.ts.map +1 -1
  283. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai-cn.models.js +19 -0
  284. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai-cn.models.js.map +1 -1
  285. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai.models.d.ts +36 -0
  286. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai.models.d.ts.map +1 -1
  287. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai.models.js +19 -0
  288. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai.models.js.map +1 -1
  289. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.d.ts.map +1 -1
  290. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.js +1 -1
  291. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.js.map +1 -1
  292. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts +42 -0
  293. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts.map +1 -1
  294. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js +178 -142
  295. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js.map +1 -1
  296. package/node_modules/@earendil-works/pi-ai/dist/providers/radius-config.d.ts +26 -0
  297. package/node_modules/@earendil-works/pi-ai/dist/providers/radius-config.d.ts.map +1 -0
  298. package/node_modules/@earendil-works/pi-ai/dist/providers/radius-config.js +59 -0
  299. package/node_modules/@earendil-works/pi-ai/dist/providers/radius-config.js.map +1 -0
  300. package/node_modules/@earendil-works/pi-ai/dist/providers/radius.d.ts +9 -0
  301. package/node_modules/@earendil-works/pi-ai/dist/providers/radius.d.ts.map +1 -0
  302. package/node_modules/@earendil-works/pi-ai/dist/providers/radius.js +54 -0
  303. package/node_modules/@earendil-works/pi-ai/dist/providers/radius.js.map +1 -0
  304. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.d.ts +84 -0
  305. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.d.ts.map +1 -1
  306. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.js +72 -0
  307. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.js.map +1 -1
  308. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.d.ts +1 -1
  309. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.d.ts.map +1 -1
  310. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.js +15 -3
  311. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.js.map +1 -1
  312. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.models.d.ts +6 -114
  313. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.models.d.ts.map +1 -1
  314. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.models.js +3 -92
  315. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.models.js.map +1 -1
  316. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +2 -0
  317. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  318. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  319. package/node_modules/@earendil-works/pi-ai/package.json +6 -1
  320. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  321. package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts.map +1 -1
  322. package/node_modules/@earendil-works/pi-tui/dist/utils.js +22 -4
  323. package/node_modules/@earendil-works/pi-tui/dist/utils.js.map +1 -1
  324. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  325. package/package.json +6 -6
  326. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/anthropic.d.ts +0 -27
  327. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/anthropic.d.ts.map +0 -1
  328. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/anthropic.js.map +0 -1
  329. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.d.ts.map +0 -1
  330. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.js.map +0 -1
  331. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.d.ts +0 -32
  332. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +0 -1
  333. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.js.map +0 -1
  334. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.d.ts +0 -59
  335. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.d.ts.map +0 -1
  336. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.js +0 -131
  337. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.js.map +0 -1
  338. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/load.d.ts +0 -5
  339. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/load.d.ts.map +0 -1
  340. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/load.js +0 -22
  341. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/load.js.map +0 -1
  342. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/oauth-page.d.ts.map +0 -1
  343. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/oauth-page.js.map +0 -1
  344. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.d.ts +0 -45
  345. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.d.ts.map +0 -1
  346. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.js.map +0 -1
  347. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/pkce.d.ts.map +0 -1
  348. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/pkce.js.map +0 -1
  349. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/radius.d.ts +0 -39
  350. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/radius.d.ts.map +0 -1
  351. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/radius.js.map +0 -1
  352. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/types.d.ts +0 -64
  353. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/types.d.ts.map +0 -1
  354. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/types.js +0 -2
  355. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/types.js.map +0 -1
  356. /package/node_modules/@earendil-works/pi-ai/dist/{utils → auth}/oauth/device-code.d.ts +0 -0
  357. /package/node_modules/@earendil-works/pi-ai/dist/{utils → auth}/oauth/device-code.js +0 -0
  358. /package/node_modules/@earendil-works/pi-ai/dist/{utils → auth}/oauth/oauth-page.d.ts +0 -0
  359. /package/node_modules/@earendil-works/pi-ai/dist/{utils → auth}/oauth/oauth-page.js +0 -0
  360. /package/node_modules/@earendil-works/pi-ai/dist/{utils → auth}/oauth/pkce.d.ts +0 -0
  361. /package/node_modules/@earendil-works/pi-ai/dist/{utils → auth}/oauth/pkce.js +0 -0
@@ -1,4 +1,4 @@
1
- import { type OAuthDeviceCodeInfo } from "@earendil-works/pi-ai/oauth";
1
+ import type { AuthInfoLink, OAuthDeviceCodeInfo } from "@earendil-works/pi-ai";
2
2
  import { Container, type Focusable, type TUI } from "@earendil-works/pi-tui";
3
3
  /**
4
4
  * Login dialog component - replaces editor during OAuth login flow
@@ -35,14 +35,10 @@ export declare class LoginDialogComponent extends Container implements Focusable
35
35
  * Note: Does NOT clear content, appends to existing (preserves URL from showAuth)
36
36
  */
37
37
  showPrompt(message: string, placeholder?: string): Promise<string>;
38
- /**
39
- * Show informational text before another login step.
40
- */
38
+ /** Show informational text before another login step. */
41
39
  showDetails(lines: string[]): void;
42
- /**
43
- * Show informational text without prompting for input.
44
- */
45
- showInfo(lines: string[]): void;
40
+ /** Show provider-owned information and links without starting an auth callback flow. */
41
+ showInfo(message: string, links?: readonly AuthInfoLink[], showCloseHint?: boolean): void;
46
42
  /**
47
43
  * Show waiting message (for polling flows like GitHub Copilot)
48
44
  */
@@ -1 +1 @@
1
- {"version":3,"file":"login-dialog.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/login-dialog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAC1F,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAuC,KAAK,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAMlH;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,SAAU,YAAW,SAAS;IACvE,OAAO,CAAC,gBAAgB,CAAY;IACpC,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,eAAe,CAAyB;IAChD,OAAO,CAAC,aAAa,CAAC,CAA0B;IAChD,OAAO,CAAC,aAAa,CAAC,CAAyB;IAC/C,OAAO,CAAC,UAAU,CAA+C;IAGjE,OAAO,CAAC,QAAQ,CAAS;IACzB,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAGzB;IAED,YACC,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,EACxD,oBAAoB,CAAC,EAAE,MAAM,EAC7B,aAAa,CAAC,EAAE,MAAM,EAqCtB;IAED,IAAI,MAAM,IAAI,WAAW,CAExB;IAED,OAAO,CAAC,6BAA6B;IAMrC,OAAO,CAAC,MAAM;IAUd;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAiBjD;IAED;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,CAa9C;IAED;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAY/C;IAED;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAsBjE;IAED;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAOjC;IAED;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAK9B;IAED;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAKjC;IAED;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAGlC;IAED,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAU9B;CACD"}
1
+ {"version":3,"file":"login-dialog.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/login-dialog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAuC,KAAK,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAMlH;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,SAAU,YAAW,SAAS;IACvE,OAAO,CAAC,gBAAgB,CAAY;IACpC,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,eAAe,CAAyB;IAChD,OAAO,CAAC,aAAa,CAAC,CAA0B;IAChD,OAAO,CAAC,aAAa,CAAC,CAAyB;IAC/C,OAAO,CAAC,UAAU,CAA+C;IAGjE,OAAO,CAAC,QAAQ,CAAS;IACzB,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAGzB;IAED,YACC,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,EACxD,oBAAoB,CAAC,EAAE,MAAM,EAC7B,aAAa,CAAC,EAAE,MAAM,EAoCtB;IAED,IAAI,MAAM,IAAI,WAAW,CAExB;IAED,OAAO,CAAC,6BAA6B;IAMrC,OAAO,CAAC,MAAM;IAUd;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAiBjD;IAED;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,CAa9C;IAED;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAY/C;IAED;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAsBjE;IAED,yDAAyD;IACzD,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAOjC;IAED,wFAAwF;IACxF,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,SAAS,YAAY,EAAO,EAAE,aAAa,UAAQ,GAAG,IAAI,CAa1F;IAED;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAKjC;IAED;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAGlC;IAED,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAU9B;CACD"}
@@ -1,4 +1,3 @@
1
- import { getOAuthProviders } from "@earendil-works/pi-ai/oauth";
2
1
  import { Container, getKeybindings, Input, Spacer, Text } from "@earendil-works/pi-tui";
3
2
  import { openBrowser } from "../../../utils/open-browser.js";
4
3
  import { theme } from "../theme/theme.js";
@@ -22,8 +21,7 @@ export class LoginDialogComponent extends Container {
22
21
  this._focused = false;
23
22
  this.tui = tui;
24
23
  this.onComplete = onComplete;
25
- const providerInfo = getOAuthProviders().find((p) => p.id === providerId);
26
- const providerName = providerNameOverride || providerInfo?.name || providerId;
24
+ const providerName = providerNameOverride || providerId;
27
25
  const title = titleOverride ?? `Login to ${providerName}`;
28
26
  // Top border
29
27
  this.addChild(new DynamicBorder());
@@ -131,9 +129,7 @@ export class LoginDialogComponent extends Container {
131
129
  this.inputRejecter = reject;
132
130
  });
133
131
  }
134
- /**
135
- * Show informational text before another login step.
136
- */
132
+ /** Show informational text before another login step. */
137
133
  showDetails(lines) {
138
134
  this.contentContainer.clear();
139
135
  this.contentContainer.addChild(new Spacer(1));
@@ -142,13 +138,19 @@ export class LoginDialogComponent extends Container {
142
138
  }
143
139
  this.tui.requestRender();
144
140
  }
145
- /**
146
- * Show informational text without prompting for input.
147
- */
148
- showInfo(lines) {
149
- this.showDetails(lines);
141
+ /** Show provider-owned information and links without starting an auth callback flow. */
142
+ showInfo(message, links = [], showCloseHint = false) {
150
143
  this.contentContainer.addChild(new Spacer(1));
151
- this.contentContainer.addChild(new Text(`(${keyHint("tui.select.cancel", "to close")})`, 1, 0));
144
+ this.contentContainer.addChild(new Text(theme.fg("text", message), 1, 0));
145
+ for (const link of links) {
146
+ const text = link.label ? `${link.label}: ${link.url}` : link.url;
147
+ const hyperlink = `\x1b]8;;${link.url}\x07${text}\x1b]8;;\x07`;
148
+ this.contentContainer.addChild(new Text(theme.fg("accent", hyperlink), 1, 0));
149
+ }
150
+ if (showCloseHint) {
151
+ this.contentContainer.addChild(new Spacer(1));
152
+ this.contentContainer.addChild(new Text(`(${keyHint("tui.select.cancel", "to close")})`, 1, 0));
153
+ }
152
154
  this.tui.requestRender();
153
155
  }
154
156
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"login-dialog.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/login-dialog.ts"],"names":[],"mappings":"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","sourcesContent":["import { getOAuthProviders, type OAuthDeviceCodeInfo } from \"@earendil-works/pi-ai/oauth\";\nimport { Container, type Focusable, getKeybindings, Input, Spacer, Text, type TUI } from \"@earendil-works/pi-tui\";\nimport { openBrowser } from \"../../../utils/open-browser.ts\";\nimport { theme } from \"../theme/theme.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\nimport { keyHint } from \"./keybinding-hints.ts\";\n\n/**\n * Login dialog component - replaces editor during OAuth login flow\n */\nexport class LoginDialogComponent extends Container implements Focusable {\n\tprivate contentContainer: Container;\n\tprivate input: Input;\n\tprivate tui: TUI;\n\tprivate abortController = new AbortController();\n\tprivate inputResolver?: (value: string) => void;\n\tprivate inputRejecter?: (error: Error) => void;\n\tprivate onComplete: (success: boolean, message?: string) => void;\n\n\t// Focusable implementation - propagate to input for IME cursor positioning\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.input.focused = value;\n\t}\n\n\tconstructor(\n\t\ttui: TUI,\n\t\tproviderId: string,\n\t\tonComplete: (success: boolean, message?: string) => void,\n\t\tproviderNameOverride?: string,\n\t\ttitleOverride?: string,\n\t) {\n\t\tsuper();\n\t\tthis.tui = tui;\n\t\tthis.onComplete = onComplete;\n\n\t\tconst providerInfo = getOAuthProviders().find((p) => p.id === providerId);\n\t\tconst providerName = providerNameOverride || providerInfo?.name || providerId;\n\t\tconst title = titleOverride ?? `Login to ${providerName}`;\n\n\t\t// Top border\n\t\tthis.addChild(new DynamicBorder());\n\n\t\t// Title\n\t\tthis.addChild(new Text(theme.fg(\"accent\", theme.bold(title)), 1, 0));\n\n\t\t// Dynamic content area\n\t\tthis.contentContainer = new Container();\n\t\tthis.addChild(this.contentContainer);\n\n\t\t// Input (always present, used when needed)\n\t\tthis.input = new Input();\n\t\tthis.input.onSubmit = () => {\n\t\t\tif (this.inputResolver) {\n\t\t\t\tconst value = this.input.getValue();\n\t\t\t\tthis.replaceInputWithSubmittedText(value);\n\t\t\t\tthis.inputResolver(value);\n\t\t\t\tthis.inputResolver = undefined;\n\t\t\t\tthis.inputRejecter = undefined;\n\t\t\t}\n\t\t};\n\t\tthis.input.onEscape = () => {\n\t\t\tthis.cancel();\n\t\t};\n\n\t\t// Bottom border\n\t\tthis.addChild(new DynamicBorder());\n\t}\n\n\tget signal(): AbortSignal {\n\t\treturn this.abortController.signal;\n\t}\n\n\tprivate replaceInputWithSubmittedText(value: string): void {\n\t\tthis.contentContainer.children = this.contentContainer.children.map((child) =>\n\t\t\tchild === this.input ? new Text(`> ${value}`, 0, 0) : child,\n\t\t);\n\t}\n\n\tprivate cancel(): void {\n\t\tthis.abortController.abort();\n\t\tif (this.inputRejecter) {\n\t\t\tthis.inputRejecter(new Error(\"Login cancelled\"));\n\t\t\tthis.inputResolver = undefined;\n\t\t\tthis.inputRejecter = undefined;\n\t\t}\n\t\tthis.onComplete(false, \"Login cancelled\");\n\t}\n\n\t/**\n\t * Called by onAuth callback - show URL and optional instructions\n\t */\n\tshowAuth(url: string, instructions?: string): void {\n\t\tthis.contentContainer.clear();\n\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\tconst linkedUrl = `\\x1b]8;;${url}\\x07${url}\\x1b]8;;\\x07`;\n\t\tthis.contentContainer.addChild(new Text(theme.fg(\"accent\", linkedUrl), 1, 0));\n\n\t\tconst clickHint = process.platform === \"darwin\" ? \"Cmd+click to open\" : \"Ctrl+click to open\";\n\t\tconst hyperlink = `\\x1b]8;;${url}\\x07${clickHint}\\x1b]8;;\\x07`;\n\t\tthis.contentContainer.addChild(new Text(theme.fg(\"dim\", hyperlink), 1, 0));\n\n\t\tif (instructions) {\n\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\tthis.contentContainer.addChild(new Text(theme.fg(\"warning\", instructions), 1, 0));\n\t\t}\n\n\t\topenBrowser(url);\n\t\tthis.tui.requestRender();\n\t}\n\n\t/**\n\t * Called by onDeviceCode callback - show URL and user code.\n\t */\n\tshowDeviceCode(info: OAuthDeviceCodeInfo): void {\n\t\tthis.contentContainer.clear();\n\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\tconst linkedUrl = `\\x1b]8;;${info.verificationUri}\\x07${info.verificationUri}\\x1b]8;;\\x07`;\n\t\tthis.contentContainer.addChild(new Text(theme.fg(\"accent\", linkedUrl), 1, 0));\n\n\t\tconst clickHint = process.platform === \"darwin\" ? \"Cmd+click to open\" : \"Ctrl+click to open\";\n\t\tconst hyperlink = `\\x1b]8;;${info.verificationUri}\\x07${clickHint}\\x1b]8;;\\x07`;\n\t\tthis.contentContainer.addChild(new Text(theme.fg(\"dim\", hyperlink), 1, 0));\n\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\tthis.contentContainer.addChild(new Text(theme.fg(\"warning\", `Enter code: ${info.userCode}`), 1, 0));\n\n\t\tthis.tui.requestRender();\n\t}\n\n\t/**\n\t * Show input for manual code/URL entry (for callback server providers)\n\t */\n\tshowManualInput(prompt: string): Promise<string> {\n\t\tthis.input.setValue(\"\");\n\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\tthis.contentContainer.addChild(new Text(theme.fg(\"dim\", prompt), 1, 0));\n\t\tthis.contentContainer.addChild(this.input);\n\t\tthis.contentContainer.addChild(new Text(`(${keyHint(\"tui.select.cancel\", \"to cancel\")})`, 1, 0));\n\t\tthis.tui.requestRender();\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.inputResolver = resolve;\n\t\t\tthis.inputRejecter = reject;\n\t\t});\n\t}\n\n\t/**\n\t * Called by onPrompt callback - show prompt and wait for input\n\t * Note: Does NOT clear content, appends to existing (preserves URL from showAuth)\n\t */\n\tshowPrompt(message: string, placeholder?: string): Promise<string> {\n\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\tthis.contentContainer.addChild(new Text(theme.fg(\"text\", message), 1, 0));\n\t\tif (placeholder) {\n\t\t\tthis.contentContainer.addChild(new Text(theme.fg(\"dim\", `e.g., ${placeholder}`), 1, 0));\n\t\t}\n\t\tthis.contentContainer.addChild(this.input);\n\t\tthis.contentContainer.addChild(\n\t\t\tnew Text(\n\t\t\t\t`(${keyHint(\"tui.select.cancel\", \"to cancel,\")} ${keyHint(\"tui.select.confirm\", \"to submit\")})`,\n\t\t\t\t1,\n\t\t\t\t0,\n\t\t\t),\n\t\t);\n\n\t\tthis.input.setValue(\"\");\n\t\tthis.tui.requestRender();\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.inputResolver = resolve;\n\t\t\tthis.inputRejecter = reject;\n\t\t});\n\t}\n\n\t/**\n\t * Show informational text before another login step.\n\t */\n\tshowDetails(lines: string[]): void {\n\t\tthis.contentContainer.clear();\n\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\tfor (const line of lines) {\n\t\t\tthis.contentContainer.addChild(new Text(line, 1, 0));\n\t\t}\n\t\tthis.tui.requestRender();\n\t}\n\n\t/**\n\t * Show informational text without prompting for input.\n\t */\n\tshowInfo(lines: string[]): void {\n\t\tthis.showDetails(lines);\n\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\tthis.contentContainer.addChild(new Text(`(${keyHint(\"tui.select.cancel\", \"to close\")})`, 1, 0));\n\t\tthis.tui.requestRender();\n\t}\n\n\t/**\n\t * Show waiting message (for polling flows like GitHub Copilot)\n\t */\n\tshowWaiting(message: string): void {\n\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\tthis.contentContainer.addChild(new Text(theme.fg(\"dim\", message), 1, 0));\n\t\tthis.contentContainer.addChild(new Text(`(${keyHint(\"tui.select.cancel\", \"to cancel\")})`, 1, 0));\n\t\tthis.tui.requestRender();\n\t}\n\n\t/**\n\t * Called by onProgress callback\n\t */\n\tshowProgress(message: string): void {\n\t\tthis.contentContainer.addChild(new Text(theme.fg(\"dim\", message), 1, 0));\n\t\tthis.tui.requestRender();\n\t}\n\n\thandleInput(data: string): void {\n\t\tconst kb = getKeybindings();\n\n\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis.cancel();\n\t\t\treturn;\n\t\t}\n\n\t\t// Pass to input\n\t\tthis.input.handleInput(data);\n\t}\n}\n"]}
1
+ {"version":3,"file":"login-dialog.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/login-dialog.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AuthInfoLink, OAuthDeviceCodeInfo } from \"@earendil-works/pi-ai\";\nimport { Container, type Focusable, getKeybindings, Input, Spacer, Text, type TUI } from \"@earendil-works/pi-tui\";\nimport { openBrowser } from \"../../../utils/open-browser.ts\";\nimport { theme } from \"../theme/theme.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\nimport { keyHint } from \"./keybinding-hints.ts\";\n\n/**\n * Login dialog component - replaces editor during OAuth login flow\n */\nexport class LoginDialogComponent extends Container implements Focusable {\n\tprivate contentContainer: Container;\n\tprivate input: Input;\n\tprivate tui: TUI;\n\tprivate abortController = new AbortController();\n\tprivate inputResolver?: (value: string) => void;\n\tprivate inputRejecter?: (error: Error) => void;\n\tprivate onComplete: (success: boolean, message?: string) => void;\n\n\t// Focusable implementation - propagate to input for IME cursor positioning\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.input.focused = value;\n\t}\n\n\tconstructor(\n\t\ttui: TUI,\n\t\tproviderId: string,\n\t\tonComplete: (success: boolean, message?: string) => void,\n\t\tproviderNameOverride?: string,\n\t\ttitleOverride?: string,\n\t) {\n\t\tsuper();\n\t\tthis.tui = tui;\n\t\tthis.onComplete = onComplete;\n\n\t\tconst providerName = providerNameOverride || providerId;\n\t\tconst title = titleOverride ?? `Login to ${providerName}`;\n\n\t\t// Top border\n\t\tthis.addChild(new DynamicBorder());\n\n\t\t// Title\n\t\tthis.addChild(new Text(theme.fg(\"accent\", theme.bold(title)), 1, 0));\n\n\t\t// Dynamic content area\n\t\tthis.contentContainer = new Container();\n\t\tthis.addChild(this.contentContainer);\n\n\t\t// Input (always present, used when needed)\n\t\tthis.input = new Input();\n\t\tthis.input.onSubmit = () => {\n\t\t\tif (this.inputResolver) {\n\t\t\t\tconst value = this.input.getValue();\n\t\t\t\tthis.replaceInputWithSubmittedText(value);\n\t\t\t\tthis.inputResolver(value);\n\t\t\t\tthis.inputResolver = undefined;\n\t\t\t\tthis.inputRejecter = undefined;\n\t\t\t}\n\t\t};\n\t\tthis.input.onEscape = () => {\n\t\t\tthis.cancel();\n\t\t};\n\n\t\t// Bottom border\n\t\tthis.addChild(new DynamicBorder());\n\t}\n\n\tget signal(): AbortSignal {\n\t\treturn this.abortController.signal;\n\t}\n\n\tprivate replaceInputWithSubmittedText(value: string): void {\n\t\tthis.contentContainer.children = this.contentContainer.children.map((child) =>\n\t\t\tchild === this.input ? new Text(`> ${value}`, 0, 0) : child,\n\t\t);\n\t}\n\n\tprivate cancel(): void {\n\t\tthis.abortController.abort();\n\t\tif (this.inputRejecter) {\n\t\t\tthis.inputRejecter(new Error(\"Login cancelled\"));\n\t\t\tthis.inputResolver = undefined;\n\t\t\tthis.inputRejecter = undefined;\n\t\t}\n\t\tthis.onComplete(false, \"Login cancelled\");\n\t}\n\n\t/**\n\t * Called by onAuth callback - show URL and optional instructions\n\t */\n\tshowAuth(url: string, instructions?: string): void {\n\t\tthis.contentContainer.clear();\n\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\tconst linkedUrl = `\\x1b]8;;${url}\\x07${url}\\x1b]8;;\\x07`;\n\t\tthis.contentContainer.addChild(new Text(theme.fg(\"accent\", linkedUrl), 1, 0));\n\n\t\tconst clickHint = process.platform === \"darwin\" ? \"Cmd+click to open\" : \"Ctrl+click to open\";\n\t\tconst hyperlink = `\\x1b]8;;${url}\\x07${clickHint}\\x1b]8;;\\x07`;\n\t\tthis.contentContainer.addChild(new Text(theme.fg(\"dim\", hyperlink), 1, 0));\n\n\t\tif (instructions) {\n\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\tthis.contentContainer.addChild(new Text(theme.fg(\"warning\", instructions), 1, 0));\n\t\t}\n\n\t\topenBrowser(url);\n\t\tthis.tui.requestRender();\n\t}\n\n\t/**\n\t * Called by onDeviceCode callback - show URL and user code.\n\t */\n\tshowDeviceCode(info: OAuthDeviceCodeInfo): void {\n\t\tthis.contentContainer.clear();\n\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\tconst linkedUrl = `\\x1b]8;;${info.verificationUri}\\x07${info.verificationUri}\\x1b]8;;\\x07`;\n\t\tthis.contentContainer.addChild(new Text(theme.fg(\"accent\", linkedUrl), 1, 0));\n\n\t\tconst clickHint = process.platform === \"darwin\" ? \"Cmd+click to open\" : \"Ctrl+click to open\";\n\t\tconst hyperlink = `\\x1b]8;;${info.verificationUri}\\x07${clickHint}\\x1b]8;;\\x07`;\n\t\tthis.contentContainer.addChild(new Text(theme.fg(\"dim\", hyperlink), 1, 0));\n\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\tthis.contentContainer.addChild(new Text(theme.fg(\"warning\", `Enter code: ${info.userCode}`), 1, 0));\n\n\t\tthis.tui.requestRender();\n\t}\n\n\t/**\n\t * Show input for manual code/URL entry (for callback server providers)\n\t */\n\tshowManualInput(prompt: string): Promise<string> {\n\t\tthis.input.setValue(\"\");\n\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\tthis.contentContainer.addChild(new Text(theme.fg(\"dim\", prompt), 1, 0));\n\t\tthis.contentContainer.addChild(this.input);\n\t\tthis.contentContainer.addChild(new Text(`(${keyHint(\"tui.select.cancel\", \"to cancel\")})`, 1, 0));\n\t\tthis.tui.requestRender();\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.inputResolver = resolve;\n\t\t\tthis.inputRejecter = reject;\n\t\t});\n\t}\n\n\t/**\n\t * Called by onPrompt callback - show prompt and wait for input\n\t * Note: Does NOT clear content, appends to existing (preserves URL from showAuth)\n\t */\n\tshowPrompt(message: string, placeholder?: string): Promise<string> {\n\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\tthis.contentContainer.addChild(new Text(theme.fg(\"text\", message), 1, 0));\n\t\tif (placeholder) {\n\t\t\tthis.contentContainer.addChild(new Text(theme.fg(\"dim\", `e.g., ${placeholder}`), 1, 0));\n\t\t}\n\t\tthis.contentContainer.addChild(this.input);\n\t\tthis.contentContainer.addChild(\n\t\t\tnew Text(\n\t\t\t\t`(${keyHint(\"tui.select.cancel\", \"to cancel,\")} ${keyHint(\"tui.select.confirm\", \"to submit\")})`,\n\t\t\t\t1,\n\t\t\t\t0,\n\t\t\t),\n\t\t);\n\n\t\tthis.input.setValue(\"\");\n\t\tthis.tui.requestRender();\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.inputResolver = resolve;\n\t\t\tthis.inputRejecter = reject;\n\t\t});\n\t}\n\n\t/** Show informational text before another login step. */\n\tshowDetails(lines: string[]): void {\n\t\tthis.contentContainer.clear();\n\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\tfor (const line of lines) {\n\t\t\tthis.contentContainer.addChild(new Text(line, 1, 0));\n\t\t}\n\t\tthis.tui.requestRender();\n\t}\n\n\t/** Show provider-owned information and links without starting an auth callback flow. */\n\tshowInfo(message: string, links: readonly AuthInfoLink[] = [], showCloseHint = false): void {\n\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\tthis.contentContainer.addChild(new Text(theme.fg(\"text\", message), 1, 0));\n\t\tfor (const link of links) {\n\t\t\tconst text = link.label ? `${link.label}: ${link.url}` : link.url;\n\t\t\tconst hyperlink = `\\x1b]8;;${link.url}\\x07${text}\\x1b]8;;\\x07`;\n\t\t\tthis.contentContainer.addChild(new Text(theme.fg(\"accent\", hyperlink), 1, 0));\n\t\t}\n\t\tif (showCloseHint) {\n\t\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\t\tthis.contentContainer.addChild(new Text(`(${keyHint(\"tui.select.cancel\", \"to close\")})`, 1, 0));\n\t\t}\n\t\tthis.tui.requestRender();\n\t}\n\n\t/**\n\t * Show waiting message (for polling flows like GitHub Copilot)\n\t */\n\tshowWaiting(message: string): void {\n\t\tthis.contentContainer.addChild(new Spacer(1));\n\t\tthis.contentContainer.addChild(new Text(theme.fg(\"dim\", message), 1, 0));\n\t\tthis.contentContainer.addChild(new Text(`(${keyHint(\"tui.select.cancel\", \"to cancel\")})`, 1, 0));\n\t\tthis.tui.requestRender();\n\t}\n\n\t/**\n\t * Called by onProgress callback\n\t */\n\tshowProgress(message: string): void {\n\t\tthis.contentContainer.addChild(new Text(theme.fg(\"dim\", message), 1, 0));\n\t\tthis.tui.requestRender();\n\t}\n\n\thandleInput(data: string): void {\n\t\tconst kb = getKeybindings();\n\n\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis.cancel();\n\t\t\treturn;\n\t\t}\n\n\t\t// Pass to input\n\t\tthis.input.handleInput(data);\n\t}\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  import { type Model } from "@earendil-works/pi-ai";
2
2
  import { Container, type Focusable, Input, type TUI } from "@earendil-works/pi-tui";
3
- import type { ModelRegistry } from "../../../core/model-registry.ts";
3
+ import { ModelRegistry } from "../../../core/model-registry.ts";
4
+ import type { ModelRuntime } from "../../../core/model-runtime.ts";
4
5
  import type { SettingsManager } from "../../../core/settings-manager.ts";
5
6
  import { type FavoriteModelIds } from "./model-favorites.ts";
6
7
  interface ScopedModelItem {
@@ -8,6 +9,7 @@ interface ScopedModelItem {
8
9
  thinkingLevel?: string;
9
10
  }
10
11
  type ModelSelectorTui = Pick<TUI, "requestRender">;
12
+ type ModelSelectorSource = ModelRuntime | ModelRegistry;
11
13
  export interface ModelSelectorFavoriteOptions {
12
14
  favoriteModelIds?: FavoriteModelIds;
13
15
  onFavoriteChange?: (favoriteModelIds: FavoriteModelIds, allModels: Model<any>[], toggledModel: Model<any>) => void | Promise<void>;
@@ -28,19 +30,26 @@ export declare class ModelSelectorComponent extends Container implements Focusab
28
30
  private selectedIndex;
29
31
  private currentModel?;
30
32
  private settingsManager;
31
- private modelRegistry;
33
+ private modelRuntime;
32
34
  private onSelectCallback;
33
35
  private onCancelCallback;
34
36
  private favoriteIds;
35
37
  private onFavoriteChangeCallback?;
36
38
  private errorMessage?;
39
+ private refreshStatusMessage;
40
+ private refreshStatusSuccess;
37
41
  private tui;
38
42
  private scopedModels;
39
43
  private scope;
40
44
  private scopeText?;
41
45
  private scopeHintText?;
42
- constructor(tui: ModelSelectorTui, currentModel: Model<any> | undefined, settingsManager: SettingsManager, modelRegistry: ModelRegistry, scopedModels: ReadonlyArray<ScopedModelItem>, onSelect: (model: Model<any>) => void, onCancel: () => void, initialSearchInput?: string, favorites?: ModelSelectorFavoriteOptions);
43
- private loadModels;
46
+ private readonly refreshAbortController;
47
+ private refreshTimeout?;
48
+ private closed;
49
+ constructor(tui: ModelSelectorTui, currentModel: Model<any> | undefined, settingsManager: SettingsManager, modelRuntime: ModelSelectorSource, scopedModels: ReadonlyArray<ScopedModelItem>, onSelect: (model: Model<any>) => void, onCancel: () => void, initialSearchInput?: string, favorites?: ModelSelectorFavoriteOptions);
50
+ private loadModelsFromSnapshot;
51
+ private refreshModels;
52
+ private close;
44
53
  private sortModels;
45
54
  private getScopeText;
46
55
  private getScopeHintText;
@@ -1 +1 @@
1
- {"version":3,"file":"model-selector.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/model-selector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAkB,MAAM,uBAAuB,CAAC;AACnE,OAAO,EACN,SAAS,EACT,KAAK,SAAS,EAGd,KAAK,EAGL,KAAK,GAAG,EACR,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAKzE,OAAO,EAAE,KAAK,gBAAgB,EAAwD,MAAM,sBAAsB,CAAC;AASnH,UAAU,eAAe;IACxB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAGD,KAAK,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;AAEnD,MAAM,WAAW,4BAA4B;IAC5C,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,gBAAgB,CAAC,EAAE,CAClB,gBAAgB,EAAE,gBAAgB,EAClC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,EACvB,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,KACpB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,SAAU,YAAW,SAAS;IACzE,OAAO,CAAC,WAAW,CAAQ;IAG3B,OAAO,CAAC,QAAQ,CAAS;IACzB,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAGzB;IACD,OAAO,CAAC,aAAa,CAAY;IACjC,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,YAAY,CAAmB;IACvC,OAAO,CAAC,cAAc,CAAmB;IACzC,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,YAAY,CAAC,CAAa;IAClC,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,gBAAgB,CAA8B;IACtD,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,WAAW,CAAwB;IAC3C,OAAO,CAAC,wBAAwB,CAAC,CAAmD;IACpF,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,GAAG,CAAmB;IAC9B,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,SAAS,CAAC,CAAO;IACzB,OAAO,CAAC,aAAa,CAAC,CAAO;IAE7B,YACC,GAAG,EAAE,gBAAgB,EACrB,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,EACpC,eAAe,EAAE,eAAe,EAChC,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,aAAa,CAAC,eAAe,CAAC,EAC5C,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,EACrC,QAAQ,EAAE,MAAM,IAAI,EACpB,kBAAkB,CAAC,EAAE,MAAM,EAC3B,SAAS,CAAC,EAAE,4BAA4B,EAyExC;YAEa,UAAU;IA+CxB,OAAO,CAAC,UAAU;IAmBlB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,QAAQ;IAYhB,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,UAAU;IA4DlB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CA4CjC;IAED,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,oBAAoB;IAuB5B,cAAc,IAAI,KAAK,CAEtB;CACD"}
1
+ {"version":3,"file":"model-selector.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/model-selector.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { modelsAreEqual } from "@earendil-works/pi-ai";
2
2
  import { Container, fuzzyFilter, getKeybindings, Input, Spacer, Text, } from "@earendil-works/pi-tui";
3
+ import { ModelRegistry } from "../../../core/model-registry.js";
3
4
  import { getModelSelectorSearchText } from "../model-search.js";
4
5
  import { theme } from "../theme/theme.js";
5
6
  import { DynamicBorder } from "./dynamic-border.js";
@@ -16,7 +17,7 @@ export class ModelSelectorComponent extends Container {
16
17
  this._focused = value;
17
18
  this.searchInput.focused = value;
18
19
  }
19
- constructor(tui, currentModel, settingsManager, modelRegistry, scopedModels, onSelect, onCancel, initialSearchInput, favorites) {
20
+ constructor(tui, currentModel, settingsManager, modelRuntime, scopedModels, onSelect, onCancel, initialSearchInput, favorites) {
20
21
  super();
21
22
  // Focusable implementation - propagate to searchInput for IME cursor positioning
22
23
  this._focused = false;
@@ -26,11 +27,15 @@ export class ModelSelectorComponent extends Container {
26
27
  this.filteredModels = [];
27
28
  this.selectedIndex = 0;
28
29
  this.favoriteIds = [];
30
+ this.refreshStatusMessage = "Refreshing model catalogs…";
31
+ this.refreshStatusSuccess = false;
29
32
  this.scope = "all";
33
+ this.refreshAbortController = new AbortController();
34
+ this.closed = false;
30
35
  this.tui = tui;
31
36
  this.currentModel = currentModel;
32
37
  this.settingsManager = settingsManager;
33
- this.modelRegistry = modelRegistry;
38
+ this.modelRuntime = modelRuntime;
34
39
  this.scopedModels = scopedModels;
35
40
  this.scope = scopedModels.length > 0 ? "narrowed" : "all";
36
41
  this.onSelectCallback = onSelect;
@@ -73,49 +78,31 @@ export class ModelSelectorComponent extends Container {
73
78
  this.addChild(new Spacer(1));
74
79
  // Add bottom border
75
80
  this.addChild(new DynamicBorder());
76
- // Load models and do initial render
77
- this.loadModels().then(() => {
78
- if (initialSearchInput) {
79
- this.filterModels(initialSearchInput);
80
- }
81
- else {
82
- this.updateList();
83
- }
84
- // Request re-render after models are loaded
85
- this.tui.requestRender();
86
- });
81
+ // Render the current snapshot immediately, then refresh in the background.
82
+ this.loadModelsFromSnapshot();
83
+ if (initialSearchInput)
84
+ this.filterModels(initialSearchInput);
85
+ else
86
+ this.updateList();
87
+ this.tui.requestRender();
88
+ void this.refreshModels();
87
89
  }
88
- async loadModels() {
89
- let models;
90
- // Refresh to pick up any changes to models.json
91
- this.modelRegistry.refresh();
92
- // Check for models.json errors
93
- const loadError = this.modelRegistry.getError();
94
- if (loadError) {
95
- this.errorMessage = loadError;
96
- }
97
- // Load available models (built-in models still work even if models.json failed)
98
- try {
99
- const availableModels = this.modelRegistry.getAvailable();
100
- models = availableModels.map((model) => ({
101
- fullId: getModelFullId(model),
102
- provider: model.provider,
103
- id: model.id,
104
- model,
105
- }));
106
- }
107
- catch (error) {
108
- this.allModels = [];
109
- this.scopedModelItems = [];
110
- this.activeModels = [];
111
- this.filteredModels = [];
112
- this.errorMessage = error instanceof Error ? error.message : String(error);
113
- return;
114
- }
90
+ loadModelsFromSnapshot() {
91
+ const availableModels = this.modelRuntime instanceof ModelRegistry
92
+ ? this.modelRuntime.getAvailable()
93
+ : this.modelRuntime.getAvailableSnapshot();
94
+ const models = availableModels.map((model) => ({
95
+ fullId: getModelFullId(model),
96
+ provider: model.provider,
97
+ id: model.id,
98
+ model,
99
+ }));
115
100
  this.allModels = this.sortModels(models);
116
101
  const modelsById = new Map(models.map((model) => [model.fullId, model]));
117
102
  this.scopedModels = this.scopedModels.map((scoped) => {
118
- const refreshed = this.modelRegistry.find(scoped.model.provider, scoped.model.id);
103
+ const refreshed = this.modelRuntime instanceof ModelRegistry
104
+ ? this.modelRuntime.find(scoped.model.provider, scoped.model.id)
105
+ : this.modelRuntime.getModel(scoped.model.provider, scoped.model.id);
119
106
  return refreshed ? { ...scoped, model: refreshed } : scoped;
120
107
  });
121
108
  this.scopedModelItems = this.scopedModels.flatMap((scoped) => {
@@ -128,6 +115,56 @@ export class ModelSelectorComponent extends Container {
128
115
  this.selectedIndex =
129
116
  currentIndex >= 0 ? currentIndex : Math.min(this.selectedIndex, Math.max(0, this.filteredModels.length - 1));
130
117
  }
118
+ async refreshModels() {
119
+ const timeoutMs = 15_000;
120
+ let timedOut = false;
121
+ this.refreshTimeout = setTimeout(() => {
122
+ timedOut = true;
123
+ this.refreshAbortController.abort();
124
+ }, timeoutMs);
125
+ try {
126
+ let result;
127
+ if (this.modelRuntime instanceof ModelRegistry) {
128
+ await this.modelRuntime.refresh();
129
+ result = { aborted: false, errors: new Map() };
130
+ }
131
+ else {
132
+ result = await this.modelRuntime.refresh({ signal: this.refreshAbortController.signal });
133
+ }
134
+ if (this.closed)
135
+ return;
136
+ this.refreshStatusMessage = "";
137
+ if (result.aborted && timedOut) {
138
+ this.errorMessage = "Model refresh timed out; showing cached models.";
139
+ }
140
+ else if (result.errors.size === 1) {
141
+ this.errorMessage = `Could not refresh ${result.errors.keys().next().value}; showing cached models.`;
142
+ }
143
+ else if (result.errors.size > 1) {
144
+ this.errorMessage = `Could not refresh ${result.errors.size} model catalogs; showing cached models.`;
145
+ }
146
+ else {
147
+ this.errorMessage = this.modelRuntime.getError();
148
+ if (!this.errorMessage) {
149
+ this.refreshStatusMessage = "Model catalogs refreshed.";
150
+ this.refreshStatusSuccess = true;
151
+ }
152
+ }
153
+ this.loadModelsFromSnapshot();
154
+ this.filterModels(this.searchInput.getValue());
155
+ this.tui.requestRender();
156
+ }
157
+ finally {
158
+ if (this.refreshTimeout)
159
+ clearTimeout(this.refreshTimeout);
160
+ }
161
+ }
162
+ close() {
163
+ this.closed = true;
164
+ if (this.refreshTimeout)
165
+ clearTimeout(this.refreshTimeout);
166
+ this.refreshAbortController.abort();
167
+ }
131
168
  sortModels(models) {
132
169
  const sorted = [...models];
133
170
  // Sort: current model first, then favorites, then by provider/model.
@@ -230,6 +267,10 @@ export class ModelSelectorComponent extends Container {
230
267
  this.listContainer.addChild(new Spacer(1));
231
268
  this.listContainer.addChild(new Text(theme.fg("muted", ` Model Name: ${selected.model.name}`), 0, 0));
232
269
  }
270
+ if (this.refreshStatusMessage) {
271
+ this.listContainer.addChild(new Spacer(1));
272
+ this.listContainer.addChild(new Text(theme.fg(this.refreshStatusSuccess ? "success" : "muted", ` ${this.refreshStatusMessage}`), 0, 0));
273
+ }
233
274
  }
234
275
  handleInput(keyData) {
235
276
  const kb = getKeybindings();
@@ -270,6 +311,7 @@ export class ModelSelectorComponent extends Container {
270
311
  }
271
312
  // Escape or Ctrl+C
272
313
  else if (kb.matches(keyData, "tui.select.cancel")) {
314
+ this.close();
273
315
  this.onCancelCallback();
274
316
  }
275
317
  // Pass everything else to search input
@@ -279,6 +321,7 @@ export class ModelSelectorComponent extends Container {
279
321
  }
280
322
  }
281
323
  handleSelect(model) {
324
+ this.close();
282
325
  // Save as new default
283
326
  this.settingsManager.setDefaultModelAndProvider(model.provider, model.id);
284
327
  this.onSelectCallback(model);
@@ -1 +1 @@
1
- {"version":3,"file":"model-selector.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/model-selector.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Model, modelsAreEqual } from \"@earendil-works/pi-ai\";\nimport {\n\tContainer,\n\ttype Focusable,\n\tfuzzyFilter,\n\tgetKeybindings,\n\tInput,\n\tSpacer,\n\tText,\n\ttype TUI,\n} from \"@earendil-works/pi-tui\";\nimport type { ModelRegistry } from \"../../../core/model-registry.ts\";\nimport type { SettingsManager } from \"../../../core/settings-manager.ts\";\nimport { getModelSelectorSearchText } from \"../model-search.ts\";\nimport { theme } from \"../theme/theme.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\nimport { keyHint } from \"./keybinding-hints.ts\";\nimport { type FavoriteModelIds, getModelFullId, isFavoriteModel, toggleFavoriteModel } from \"./model-favorites.ts\";\n\ninterface ModelItem {\n\tfullId: string;\n\tprovider: string;\n\tid: string;\n\tmodel: Model<any>;\n}\n\ninterface ScopedModelItem {\n\tmodel: Model<any>;\n\tthinkingLevel?: string;\n}\n\ntype ModelScope = \"all\" | \"narrowed\";\ntype ModelSelectorTui = Pick<TUI, \"requestRender\">;\n\nexport interface ModelSelectorFavoriteOptions {\n\tfavoriteModelIds?: FavoriteModelIds;\n\tonFavoriteChange?: (\n\t\tfavoriteModelIds: FavoriteModelIds,\n\t\tallModels: Model<any>[],\n\t\ttoggledModel: Model<any>,\n\t) => void | Promise<void>;\n}\n\n/**\n * Component that renders a model selector with search\n */\nexport class ModelSelectorComponent extends Container implements Focusable {\n\tprivate searchInput: Input;\n\n\t// Focusable implementation - propagate to searchInput for IME cursor positioning\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.searchInput.focused = value;\n\t}\n\tprivate listContainer: Container;\n\tprivate allModels: ModelItem[] = [];\n\tprivate scopedModelItems: ModelItem[] = [];\n\tprivate activeModels: ModelItem[] = [];\n\tprivate filteredModels: ModelItem[] = [];\n\tprivate selectedIndex: number = 0;\n\tprivate currentModel?: Model<any>;\n\tprivate settingsManager: SettingsManager;\n\tprivate modelRegistry: ModelRegistry;\n\tprivate onSelectCallback: (model: Model<any>) => void;\n\tprivate onCancelCallback: () => void;\n\tprivate favoriteIds: FavoriteModelIds = [];\n\tprivate onFavoriteChangeCallback?: ModelSelectorFavoriteOptions[\"onFavoriteChange\"];\n\tprivate errorMessage?: string;\n\tprivate tui: ModelSelectorTui;\n\tprivate scopedModels: ReadonlyArray<ScopedModelItem>;\n\tprivate scope: ModelScope = \"all\";\n\tprivate scopeText?: Text;\n\tprivate scopeHintText?: Text;\n\n\tconstructor(\n\t\ttui: ModelSelectorTui,\n\t\tcurrentModel: Model<any> | undefined,\n\t\tsettingsManager: SettingsManager,\n\t\tmodelRegistry: ModelRegistry,\n\t\tscopedModels: ReadonlyArray<ScopedModelItem>,\n\t\tonSelect: (model: Model<any>) => void,\n\t\tonCancel: () => void,\n\t\tinitialSearchInput?: string,\n\t\tfavorites?: ModelSelectorFavoriteOptions,\n\t) {\n\t\tsuper();\n\n\t\tthis.tui = tui;\n\t\tthis.currentModel = currentModel;\n\t\tthis.settingsManager = settingsManager;\n\t\tthis.modelRegistry = modelRegistry;\n\t\tthis.scopedModels = scopedModels;\n\t\tthis.scope = scopedModels.length > 0 ? \"narrowed\" : \"all\";\n\t\tthis.onSelectCallback = onSelect;\n\t\tthis.onCancelCallback = onCancel;\n\t\tthis.favoriteIds = favorites?.favoriteModelIds === null ? null : [...(favorites?.favoriteModelIds ?? [])];\n\t\tthis.onFavoriteChangeCallback = favorites?.onFavoriteChange;\n\n\t\t// Add top border\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add hint about model filtering\n\t\tif (scopedModels.length > 0) {\n\t\t\tthis.scopeText = new Text(this.getScopeText(), 0, 0);\n\t\t\tthis.addChild(this.scopeText);\n\t\t\tthis.scopeHintText = new Text(this.getScopeHintText(), 0, 0);\n\t\t\tthis.addChild(this.scopeHintText);\n\t\t} else {\n\t\t\tconst hintText = \"Only showing models from configured providers. Use /login to add providers.\";\n\t\t\tthis.addChild(new Text(theme.fg(\"warning\", hintText), 0, 0));\n\t\t}\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(\n\t\t\tnew Text(\n\t\t\t\t`${keyHint(\"tui.select.confirm\", \"select\")} ${keyHint(\"app.models.toggleFavorite\", \"favorite\")}`,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t),\n\t\t);\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Create search input\n\t\tthis.searchInput = new Input();\n\t\tif (initialSearchInput) {\n\t\t\tthis.searchInput.setValue(initialSearchInput);\n\t\t}\n\t\tthis.searchInput.onSubmit = () => {\n\t\t\t// Enter on search input selects the first filtered item\n\t\t\tif (this.filteredModels[this.selectedIndex]) {\n\t\t\t\tthis.handleSelect(this.filteredModels[this.selectedIndex].model);\n\t\t\t}\n\t\t};\n\t\tthis.addChild(this.searchInput);\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Create list container\n\t\tthis.listContainer = new Container();\n\t\tthis.addChild(this.listContainer);\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add bottom border\n\t\tthis.addChild(new DynamicBorder());\n\n\t\t// Load models and do initial render\n\t\tthis.loadModels().then(() => {\n\t\t\tif (initialSearchInput) {\n\t\t\t\tthis.filterModels(initialSearchInput);\n\t\t\t} else {\n\t\t\t\tthis.updateList();\n\t\t\t}\n\t\t\t// Request re-render after models are loaded\n\t\t\tthis.tui.requestRender();\n\t\t});\n\t}\n\n\tprivate async loadModels(): Promise<void> {\n\t\tlet models: ModelItem[];\n\n\t\t// Refresh to pick up any changes to models.json\n\t\tthis.modelRegistry.refresh();\n\n\t\t// Check for models.json errors\n\t\tconst loadError = this.modelRegistry.getError();\n\t\tif (loadError) {\n\t\t\tthis.errorMessage = loadError;\n\t\t}\n\n\t\t// Load available models (built-in models still work even if models.json failed)\n\t\ttry {\n\t\t\tconst availableModels = this.modelRegistry.getAvailable();\n\t\t\tmodels = availableModels.map((model: Model<any>) => ({\n\t\t\t\tfullId: getModelFullId(model),\n\t\t\t\tprovider: model.provider,\n\t\t\t\tid: model.id,\n\t\t\t\tmodel,\n\t\t\t}));\n\t\t} catch (error) {\n\t\t\tthis.allModels = [];\n\t\t\tthis.scopedModelItems = [];\n\t\t\tthis.activeModels = [];\n\t\t\tthis.filteredModels = [];\n\t\t\tthis.errorMessage = error instanceof Error ? error.message : String(error);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.allModels = this.sortModels(models);\n\t\tconst modelsById = new Map(models.map((model) => [model.fullId, model]));\n\t\tthis.scopedModels = this.scopedModels.map((scoped) => {\n\t\t\tconst refreshed = this.modelRegistry.find(scoped.model.provider, scoped.model.id);\n\t\t\treturn refreshed ? { ...scoped, model: refreshed } : scoped;\n\t\t});\n\t\tthis.scopedModelItems = this.scopedModels.flatMap((scoped) => {\n\t\t\tconst refreshed = modelsById.get(`${scoped.model.provider}/${scoped.model.id}`);\n\t\t\treturn refreshed ? [refreshed] : [];\n\t\t});\n\t\tthis.activeModels = this.scope === \"narrowed\" ? this.scopedModelItems : this.allModels;\n\t\tthis.filteredModels = this.activeModels;\n\t\tconst currentIndex = this.filteredModels.findIndex((item) => modelsAreEqual(this.currentModel, item.model));\n\t\tthis.selectedIndex =\n\t\t\tcurrentIndex >= 0 ? currentIndex : Math.min(this.selectedIndex, Math.max(0, this.filteredModels.length - 1));\n\t}\n\n\tprivate sortModels(models: ModelItem[]): ModelItem[] {\n\t\tconst sorted = [...models];\n\t\t// Sort: current model first, then favorites, then by provider/model.\n\t\tsorted.sort((a, b) => {\n\t\t\tconst aIsCurrent = modelsAreEqual(this.currentModel, a.model);\n\t\t\tconst bIsCurrent = modelsAreEqual(this.currentModel, b.model);\n\t\t\tif (aIsCurrent && !bIsCurrent) return -1;\n\t\t\tif (!aIsCurrent && bIsCurrent) return 1;\n\t\t\tconst aIsFavorite = isFavoriteModel(this.favoriteIds, a.fullId);\n\t\t\tconst bIsFavorite = isFavoriteModel(this.favoriteIds, b.fullId);\n\t\t\tif (aIsFavorite && !bIsFavorite) return -1;\n\t\t\tif (!aIsFavorite && bIsFavorite) return 1;\n\t\t\tconst providerCompare = a.provider.localeCompare(b.provider);\n\t\t\tif (providerCompare !== 0) return providerCompare;\n\t\t\treturn a.id.localeCompare(b.id);\n\t\t});\n\t\treturn sorted;\n\t}\n\n\tprivate getScopeText(): string {\n\t\tconst allText = this.scope === \"all\" ? theme.fg(\"accent\", \"all\") : theme.fg(\"muted\", \"all\");\n\t\tconst narrowedText = this.scope === \"narrowed\" ? theme.fg(\"accent\", \"narrowed\") : theme.fg(\"muted\", \"narrowed\");\n\t\treturn `${theme.fg(\"muted\", \"Catalog: \")}${allText}${theme.fg(\"muted\", \" | \")}${narrowedText}`;\n\t}\n\n\tprivate getScopeHintText(): string {\n\t\treturn keyHint(\"tui.input.tab\", \"catalog\") + theme.fg(\"muted\", \" (all/narrowed)\");\n\t}\n\n\tprivate setScope(scope: ModelScope): void {\n\t\tif (this.scope === scope) return;\n\t\tthis.scope = scope;\n\t\tthis.activeModels = this.scope === \"narrowed\" ? this.scopedModelItems : this.allModels;\n\t\tconst currentIndex = this.activeModels.findIndex((item) => modelsAreEqual(this.currentModel, item.model));\n\t\tthis.selectedIndex = currentIndex >= 0 ? currentIndex : 0;\n\t\tthis.filterModels(this.searchInput.getValue());\n\t\tif (this.scopeText) {\n\t\t\tthis.scopeText.setText(this.getScopeText());\n\t\t}\n\t}\n\n\tprivate filterModels(query: string): void {\n\t\tthis.filteredModels = query\n\t\t\t? fuzzyFilter(this.activeModels, query, ({ id, provider, model }) =>\n\t\t\t\t\tgetModelSelectorSearchText({ id, provider, name: model.name }),\n\t\t\t\t)\n\t\t\t: this.activeModels;\n\t\tthis.selectedIndex = Math.min(this.selectedIndex, Math.max(0, this.filteredModels.length - 1));\n\t\tthis.updateList();\n\t}\n\n\tprivate updateList(): void {\n\t\tthis.listContainer.clear();\n\n\t\tconst maxVisible = 10;\n\t\tconst startIndex = Math.max(\n\t\t\t0,\n\t\t\tMath.min(this.selectedIndex - Math.floor(maxVisible / 2), this.filteredModels.length - maxVisible),\n\t\t);\n\t\tconst endIndex = Math.min(startIndex + maxVisible, this.filteredModels.length);\n\n\t\t// Show visible slice of filtered models\n\t\tfor (let i = startIndex; i < endIndex; i++) {\n\t\t\tconst item = this.filteredModels[i];\n\t\t\tif (!item) continue;\n\n\t\t\tconst isSelected = i === this.selectedIndex;\n\t\t\tconst isCurrent = modelsAreEqual(this.currentModel, item.model);\n\t\t\tconst favoriteMarker = isFavoriteModel(this.favoriteIds, item.fullId)\n\t\t\t\t? theme.fg(\"success\", \"* \")\n\t\t\t\t: theme.fg(\"dim\", \" \");\n\n\t\t\tlet line = \"\";\n\t\t\tif (isSelected) {\n\t\t\t\tconst prefix = theme.fg(\"accent\", \"→ \");\n\t\t\t\tconst modelText = `${favoriteMarker}${theme.fg(\"accent\", item.id)}`;\n\t\t\t\tconst providerBadge = theme.fg(\"muted\", `[${item.provider}]`);\n\t\t\t\tconst checkmark = isCurrent ? theme.fg(\"success\", \" ✓\") : \"\";\n\t\t\t\tline = `${prefix}${modelText} ${providerBadge}${checkmark}`;\n\t\t\t} else {\n\t\t\t\tconst modelText = ` ${favoriteMarker}${item.id}`;\n\t\t\t\tconst providerBadge = theme.fg(\"muted\", `[${item.provider}]`);\n\t\t\t\tconst checkmark = isCurrent ? theme.fg(\"success\", \" ✓\") : \"\";\n\t\t\t\tline = `${modelText} ${providerBadge}${checkmark}`;\n\t\t\t}\n\n\t\t\tthis.listContainer.addChild(new Text(line, 0, 0));\n\t\t}\n\n\t\t// Add scroll indicator if needed\n\t\tif (startIndex > 0 || endIndex < this.filteredModels.length) {\n\t\t\tconst scrollInfo = theme.fg(\"muted\", ` (${this.selectedIndex + 1}/${this.filteredModels.length})`);\n\t\t\tthis.listContainer.addChild(new Text(scrollInfo, 0, 0));\n\t\t}\n\n\t\t// Show error message or \"no results\" if empty\n\t\tif (this.errorMessage) {\n\t\t\t// Show error in red\n\t\t\tconst errorLines = this.errorMessage.split(\"\\n\");\n\t\t\tfor (const line of errorLines) {\n\t\t\t\tthis.listContainer.addChild(new Text(theme.fg(\"error\", line), 0, 0));\n\t\t\t}\n\t\t} else if (this.filteredModels.length === 0) {\n\t\t\tthis.listContainer.addChild(new Text(theme.fg(\"muted\", \" No matching models\"), 0, 0));\n\t\t} else {\n\t\t\tconst selected = this.filteredModels[this.selectedIndex];\n\t\t\tthis.listContainer.addChild(new Spacer(1));\n\t\t\tthis.listContainer.addChild(new Text(theme.fg(\"muted\", ` Model Name: ${selected.model.name}`), 0, 0));\n\t\t}\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getKeybindings();\n\t\tif (kb.matches(keyData, \"tui.input.tab\")) {\n\t\t\tif (this.scopedModelItems.length > 0) {\n\t\t\t\tconst nextScope: ModelScope = this.scope === \"all\" ? \"narrowed\" : \"all\";\n\t\t\t\tthis.setScope(nextScope);\n\t\t\t\tif (this.scopeHintText) {\n\t\t\t\t\tthis.scopeHintText.setText(this.getScopeHintText());\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\t// Up arrow - wrap to bottom when at top\n\t\tif (kb.matches(keyData, \"tui.select.up\")) {\n\t\t\tif (this.filteredModels.length === 0) return;\n\t\t\tthis.selectedIndex = this.selectedIndex === 0 ? this.filteredModels.length - 1 : this.selectedIndex - 1;\n\t\t\tthis.updateList();\n\t\t}\n\t\t// Down arrow - wrap to top when at bottom\n\t\telse if (kb.matches(keyData, \"tui.select.down\")) {\n\t\t\tif (this.filteredModels.length === 0) return;\n\t\t\tthis.selectedIndex = this.selectedIndex === this.filteredModels.length - 1 ? 0 : this.selectedIndex + 1;\n\t\t\tthis.updateList();\n\t\t}\n\t\t// Enter\n\t\telse if (kb.matches(keyData, \"tui.select.confirm\")) {\n\t\t\tconst selectedModel = this.filteredModels[this.selectedIndex];\n\t\t\tif (selectedModel) {\n\t\t\t\tthis.handleSelect(selectedModel.model);\n\t\t\t}\n\t\t}\n\t\t// Toggle favorite for selected model\n\t\telse if (kb.matches(keyData, \"app.models.toggleFavorite\")) {\n\t\t\tthis.handleToggleFavorite();\n\t\t}\n\t\t// Escape or Ctrl+C\n\t\telse if (kb.matches(keyData, \"tui.select.cancel\")) {\n\t\t\tthis.onCancelCallback();\n\t\t}\n\t\t// Pass everything else to search input\n\t\telse {\n\t\t\tthis.searchInput.handleInput(keyData);\n\t\t\tthis.filterModels(this.searchInput.getValue());\n\t\t}\n\t}\n\n\tprivate handleSelect(model: Model<any>): void {\n\t\t// Save as new default\n\t\tthis.settingsManager.setDefaultModelAndProvider(model.provider, model.id);\n\t\tthis.onSelectCallback(model);\n\t}\n\n\tprivate handleToggleFavorite(): void {\n\t\tconst selectedModel = this.filteredModels[this.selectedIndex];\n\t\tif (!selectedModel) return;\n\n\t\tconst allModelIds = this.allModels.map((model) => model.fullId);\n\t\tthis.favoriteIds = toggleFavoriteModel(this.favoriteIds, allModelIds, selectedModel.fullId);\n\t\tthis.allModels = this.sortModels(this.allModels);\n\t\tthis.activeModels = this.scope === \"narrowed\" ? this.scopedModelItems : this.allModels;\n\t\tthis.filterModels(this.searchInput.getValue());\n\t\tconst selectedIndex = this.filteredModels.findIndex((item) => item.fullId === selectedModel.fullId);\n\t\tif (selectedIndex >= 0) {\n\t\t\tthis.selectedIndex = selectedIndex;\n\t\t\tthis.updateList();\n\t\t}\n\t\tconst nextFavoriteIds = this.favoriteIds === null ? null : [...this.favoriteIds];\n\t\tvoid this.onFavoriteChangeCallback?.(\n\t\t\tnextFavoriteIds,\n\t\t\tthis.allModels.map((item) => item.model),\n\t\t\tselectedModel.model,\n\t\t);\n\t\tthis.tui.requestRender();\n\t}\n\n\tgetSearchInput(): Input {\n\t\treturn this.searchInput;\n\t}\n}\n"]}
1
+ {"version":3,"file":"model-selector.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/model-selector.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Model, modelsAreEqual } from \"@earendil-works/pi-ai\";\nimport {\n\tContainer,\n\ttype Focusable,\n\tfuzzyFilter,\n\tgetKeybindings,\n\tInput,\n\tSpacer,\n\tText,\n\ttype TUI,\n} from \"@earendil-works/pi-tui\";\nimport { ModelRegistry } from \"../../../core/model-registry.ts\";\nimport type { ModelRuntime } from \"../../../core/model-runtime.ts\";\nimport type { SettingsManager } from \"../../../core/settings-manager.ts\";\nimport { getModelSelectorSearchText } from \"../model-search.ts\";\nimport { theme } from \"../theme/theme.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\nimport { keyHint } from \"./keybinding-hints.ts\";\nimport { type FavoriteModelIds, getModelFullId, isFavoriteModel, toggleFavoriteModel } from \"./model-favorites.ts\";\n\ninterface ModelItem {\n\tfullId: string;\n\tprovider: string;\n\tid: string;\n\tmodel: Model<any>;\n}\n\ninterface ScopedModelItem {\n\tmodel: Model<any>;\n\tthinkingLevel?: string;\n}\n\ntype ModelScope = \"all\" | \"narrowed\";\ntype ModelSelectorTui = Pick<TUI, \"requestRender\">;\ntype ModelSelectorSource = ModelRuntime | ModelRegistry;\n\nexport interface ModelSelectorFavoriteOptions {\n\tfavoriteModelIds?: FavoriteModelIds;\n\tonFavoriteChange?: (\n\t\tfavoriteModelIds: FavoriteModelIds,\n\t\tallModels: Model<any>[],\n\t\ttoggledModel: Model<any>,\n\t) => void | Promise<void>;\n}\n\n/**\n * Component that renders a model selector with search\n */\nexport class ModelSelectorComponent extends Container implements Focusable {\n\tprivate searchInput: Input;\n\n\t// Focusable implementation - propagate to searchInput for IME cursor positioning\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.searchInput.focused = value;\n\t}\n\tprivate listContainer: Container;\n\tprivate allModels: ModelItem[] = [];\n\tprivate scopedModelItems: ModelItem[] = [];\n\tprivate activeModels: ModelItem[] = [];\n\tprivate filteredModels: ModelItem[] = [];\n\tprivate selectedIndex: number = 0;\n\tprivate currentModel?: Model<any>;\n\tprivate settingsManager: SettingsManager;\n\tprivate modelRuntime: ModelSelectorSource;\n\tprivate onSelectCallback: (model: Model<any>) => void;\n\tprivate onCancelCallback: () => void;\n\tprivate favoriteIds: FavoriteModelIds = [];\n\tprivate onFavoriteChangeCallback?: ModelSelectorFavoriteOptions[\"onFavoriteChange\"];\n\tprivate errorMessage?: string;\n\tprivate refreshStatusMessage = \"Refreshing model catalogs…\";\n\tprivate refreshStatusSuccess = false;\n\tprivate tui: ModelSelectorTui;\n\tprivate scopedModels: ReadonlyArray<ScopedModelItem>;\n\tprivate scope: ModelScope = \"all\";\n\tprivate scopeText?: Text;\n\tprivate scopeHintText?: Text;\n\tprivate readonly refreshAbortController = new AbortController();\n\tprivate refreshTimeout?: ReturnType<typeof setTimeout>;\n\tprivate closed = false;\n\n\tconstructor(\n\t\ttui: ModelSelectorTui,\n\t\tcurrentModel: Model<any> | undefined,\n\t\tsettingsManager: SettingsManager,\n\t\tmodelRuntime: ModelSelectorSource,\n\t\tscopedModels: ReadonlyArray<ScopedModelItem>,\n\t\tonSelect: (model: Model<any>) => void,\n\t\tonCancel: () => void,\n\t\tinitialSearchInput?: string,\n\t\tfavorites?: ModelSelectorFavoriteOptions,\n\t) {\n\t\tsuper();\n\n\t\tthis.tui = tui;\n\t\tthis.currentModel = currentModel;\n\t\tthis.settingsManager = settingsManager;\n\t\tthis.modelRuntime = modelRuntime;\n\t\tthis.scopedModels = scopedModels;\n\t\tthis.scope = scopedModels.length > 0 ? \"narrowed\" : \"all\";\n\t\tthis.onSelectCallback = onSelect;\n\t\tthis.onCancelCallback = onCancel;\n\t\tthis.favoriteIds = favorites?.favoriteModelIds === null ? null : [...(favorites?.favoriteModelIds ?? [])];\n\t\tthis.onFavoriteChangeCallback = favorites?.onFavoriteChange;\n\n\t\t// Add top border\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add hint about model filtering\n\t\tif (scopedModels.length > 0) {\n\t\t\tthis.scopeText = new Text(this.getScopeText(), 0, 0);\n\t\t\tthis.addChild(this.scopeText);\n\t\t\tthis.scopeHintText = new Text(this.getScopeHintText(), 0, 0);\n\t\t\tthis.addChild(this.scopeHintText);\n\t\t} else {\n\t\t\tconst hintText = \"Only showing models from configured providers. Use /login to add providers.\";\n\t\t\tthis.addChild(new Text(theme.fg(\"warning\", hintText), 0, 0));\n\t\t}\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(\n\t\t\tnew Text(\n\t\t\t\t`${keyHint(\"tui.select.confirm\", \"select\")} ${keyHint(\"app.models.toggleFavorite\", \"favorite\")}`,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t),\n\t\t);\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Create search input\n\t\tthis.searchInput = new Input();\n\t\tif (initialSearchInput) {\n\t\t\tthis.searchInput.setValue(initialSearchInput);\n\t\t}\n\t\tthis.searchInput.onSubmit = () => {\n\t\t\t// Enter on search input selects the first filtered item\n\t\t\tif (this.filteredModels[this.selectedIndex]) {\n\t\t\t\tthis.handleSelect(this.filteredModels[this.selectedIndex].model);\n\t\t\t}\n\t\t};\n\t\tthis.addChild(this.searchInput);\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Create list container\n\t\tthis.listContainer = new Container();\n\t\tthis.addChild(this.listContainer);\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add bottom border\n\t\tthis.addChild(new DynamicBorder());\n\n\t\t// Render the current snapshot immediately, then refresh in the background.\n\t\tthis.loadModelsFromSnapshot();\n\t\tif (initialSearchInput) this.filterModels(initialSearchInput);\n\t\telse this.updateList();\n\t\tthis.tui.requestRender();\n\t\tvoid this.refreshModels();\n\t}\n\n\tprivate loadModelsFromSnapshot(): void {\n\t\tconst availableModels =\n\t\t\tthis.modelRuntime instanceof ModelRegistry\n\t\t\t\t? this.modelRuntime.getAvailable()\n\t\t\t\t: this.modelRuntime.getAvailableSnapshot();\n\t\tconst models = availableModels.map((model: Model<any>) => ({\n\t\t\tfullId: getModelFullId(model),\n\t\t\tprovider: model.provider,\n\t\t\tid: model.id,\n\t\t\tmodel,\n\t\t}));\n\t\tthis.allModels = this.sortModels(models);\n\t\tconst modelsById = new Map(models.map((model) => [model.fullId, model]));\n\t\tthis.scopedModels = this.scopedModels.map((scoped) => {\n\t\t\tconst refreshed =\n\t\t\t\tthis.modelRuntime instanceof ModelRegistry\n\t\t\t\t\t? this.modelRuntime.find(scoped.model.provider, scoped.model.id)\n\t\t\t\t\t: this.modelRuntime.getModel(scoped.model.provider, scoped.model.id);\n\t\t\treturn refreshed ? { ...scoped, model: refreshed } : scoped;\n\t\t});\n\t\tthis.scopedModelItems = this.scopedModels.flatMap((scoped) => {\n\t\t\tconst refreshed = modelsById.get(`${scoped.model.provider}/${scoped.model.id}`);\n\t\t\treturn refreshed ? [refreshed] : [];\n\t\t});\n\t\tthis.activeModels = this.scope === \"narrowed\" ? this.scopedModelItems : this.allModels;\n\t\tthis.filteredModels = this.activeModels;\n\t\tconst currentIndex = this.filteredModels.findIndex((item) => modelsAreEqual(this.currentModel, item.model));\n\t\tthis.selectedIndex =\n\t\t\tcurrentIndex >= 0 ? currentIndex : Math.min(this.selectedIndex, Math.max(0, this.filteredModels.length - 1));\n\t}\n\n\tprivate async refreshModels(): Promise<void> {\n\t\tconst timeoutMs = 15_000;\n\t\tlet timedOut = false;\n\t\tthis.refreshTimeout = setTimeout(() => {\n\t\t\ttimedOut = true;\n\t\t\tthis.refreshAbortController.abort();\n\t\t}, timeoutMs);\n\t\ttry {\n\t\t\tlet result: { aborted: boolean; errors: ReadonlyMap<string, Error> };\n\t\t\tif (this.modelRuntime instanceof ModelRegistry) {\n\t\t\t\tawait this.modelRuntime.refresh();\n\t\t\t\tresult = { aborted: false, errors: new Map() };\n\t\t\t} else {\n\t\t\t\tresult = await this.modelRuntime.refresh({ signal: this.refreshAbortController.signal });\n\t\t\t}\n\t\t\tif (this.closed) return;\n\t\t\tthis.refreshStatusMessage = \"\";\n\t\t\tif (result.aborted && timedOut) {\n\t\t\t\tthis.errorMessage = \"Model refresh timed out; showing cached models.\";\n\t\t\t} else if (result.errors.size === 1) {\n\t\t\t\tthis.errorMessage = `Could not refresh ${result.errors.keys().next().value}; showing cached models.`;\n\t\t\t} else if (result.errors.size > 1) {\n\t\t\t\tthis.errorMessage = `Could not refresh ${result.errors.size} model catalogs; showing cached models.`;\n\t\t\t} else {\n\t\t\t\tthis.errorMessage = this.modelRuntime.getError();\n\t\t\t\tif (!this.errorMessage) {\n\t\t\t\t\tthis.refreshStatusMessage = \"Model catalogs refreshed.\";\n\t\t\t\t\tthis.refreshStatusSuccess = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.loadModelsFromSnapshot();\n\t\t\tthis.filterModels(this.searchInput.getValue());\n\t\t\tthis.tui.requestRender();\n\t\t} finally {\n\t\t\tif (this.refreshTimeout) clearTimeout(this.refreshTimeout);\n\t\t}\n\t}\n\n\tprivate close(): void {\n\t\tthis.closed = true;\n\t\tif (this.refreshTimeout) clearTimeout(this.refreshTimeout);\n\t\tthis.refreshAbortController.abort();\n\t}\n\n\tprivate sortModels(models: ModelItem[]): ModelItem[] {\n\t\tconst sorted = [...models];\n\t\t// Sort: current model first, then favorites, then by provider/model.\n\t\tsorted.sort((a, b) => {\n\t\t\tconst aIsCurrent = modelsAreEqual(this.currentModel, a.model);\n\t\t\tconst bIsCurrent = modelsAreEqual(this.currentModel, b.model);\n\t\t\tif (aIsCurrent && !bIsCurrent) return -1;\n\t\t\tif (!aIsCurrent && bIsCurrent) return 1;\n\t\t\tconst aIsFavorite = isFavoriteModel(this.favoriteIds, a.fullId);\n\t\t\tconst bIsFavorite = isFavoriteModel(this.favoriteIds, b.fullId);\n\t\t\tif (aIsFavorite && !bIsFavorite) return -1;\n\t\t\tif (!aIsFavorite && bIsFavorite) return 1;\n\t\t\tconst providerCompare = a.provider.localeCompare(b.provider);\n\t\t\tif (providerCompare !== 0) return providerCompare;\n\t\t\treturn a.id.localeCompare(b.id);\n\t\t});\n\t\treturn sorted;\n\t}\n\n\tprivate getScopeText(): string {\n\t\tconst allText = this.scope === \"all\" ? theme.fg(\"accent\", \"all\") : theme.fg(\"muted\", \"all\");\n\t\tconst narrowedText = this.scope === \"narrowed\" ? theme.fg(\"accent\", \"narrowed\") : theme.fg(\"muted\", \"narrowed\");\n\t\treturn `${theme.fg(\"muted\", \"Catalog: \")}${allText}${theme.fg(\"muted\", \" | \")}${narrowedText}`;\n\t}\n\n\tprivate getScopeHintText(): string {\n\t\treturn keyHint(\"tui.input.tab\", \"catalog\") + theme.fg(\"muted\", \" (all/narrowed)\");\n\t}\n\n\tprivate setScope(scope: ModelScope): void {\n\t\tif (this.scope === scope) return;\n\t\tthis.scope = scope;\n\t\tthis.activeModels = this.scope === \"narrowed\" ? this.scopedModelItems : this.allModels;\n\t\tconst currentIndex = this.activeModels.findIndex((item) => modelsAreEqual(this.currentModel, item.model));\n\t\tthis.selectedIndex = currentIndex >= 0 ? currentIndex : 0;\n\t\tthis.filterModels(this.searchInput.getValue());\n\t\tif (this.scopeText) {\n\t\t\tthis.scopeText.setText(this.getScopeText());\n\t\t}\n\t}\n\n\tprivate filterModels(query: string): void {\n\t\tthis.filteredModels = query\n\t\t\t? fuzzyFilter(this.activeModels, query, ({ id, provider, model }) =>\n\t\t\t\t\tgetModelSelectorSearchText({ id, provider, name: model.name }),\n\t\t\t\t)\n\t\t\t: this.activeModels;\n\t\tthis.selectedIndex = Math.min(this.selectedIndex, Math.max(0, this.filteredModels.length - 1));\n\t\tthis.updateList();\n\t}\n\n\tprivate updateList(): void {\n\t\tthis.listContainer.clear();\n\n\t\tconst maxVisible = 10;\n\t\tconst startIndex = Math.max(\n\t\t\t0,\n\t\t\tMath.min(this.selectedIndex - Math.floor(maxVisible / 2), this.filteredModels.length - maxVisible),\n\t\t);\n\t\tconst endIndex = Math.min(startIndex + maxVisible, this.filteredModels.length);\n\n\t\t// Show visible slice of filtered models\n\t\tfor (let i = startIndex; i < endIndex; i++) {\n\t\t\tconst item = this.filteredModels[i];\n\t\t\tif (!item) continue;\n\n\t\t\tconst isSelected = i === this.selectedIndex;\n\t\t\tconst isCurrent = modelsAreEqual(this.currentModel, item.model);\n\t\t\tconst favoriteMarker = isFavoriteModel(this.favoriteIds, item.fullId)\n\t\t\t\t? theme.fg(\"success\", \"* \")\n\t\t\t\t: theme.fg(\"dim\", \" \");\n\n\t\t\tlet line = \"\";\n\t\t\tif (isSelected) {\n\t\t\t\tconst prefix = theme.fg(\"accent\", \"→ \");\n\t\t\t\tconst modelText = `${favoriteMarker}${theme.fg(\"accent\", item.id)}`;\n\t\t\t\tconst providerBadge = theme.fg(\"muted\", `[${item.provider}]`);\n\t\t\t\tconst checkmark = isCurrent ? theme.fg(\"success\", \" ✓\") : \"\";\n\t\t\t\tline = `${prefix}${modelText} ${providerBadge}${checkmark}`;\n\t\t\t} else {\n\t\t\t\tconst modelText = ` ${favoriteMarker}${item.id}`;\n\t\t\t\tconst providerBadge = theme.fg(\"muted\", `[${item.provider}]`);\n\t\t\t\tconst checkmark = isCurrent ? theme.fg(\"success\", \" ✓\") : \"\";\n\t\t\t\tline = `${modelText} ${providerBadge}${checkmark}`;\n\t\t\t}\n\n\t\t\tthis.listContainer.addChild(new Text(line, 0, 0));\n\t\t}\n\n\t\t// Add scroll indicator if needed\n\t\tif (startIndex > 0 || endIndex < this.filteredModels.length) {\n\t\t\tconst scrollInfo = theme.fg(\"muted\", ` (${this.selectedIndex + 1}/${this.filteredModels.length})`);\n\t\t\tthis.listContainer.addChild(new Text(scrollInfo, 0, 0));\n\t\t}\n\n\t\t// Show error message or \"no results\" if empty\n\t\tif (this.errorMessage) {\n\t\t\t// Show error in red\n\t\t\tconst errorLines = this.errorMessage.split(\"\\n\");\n\t\t\tfor (const line of errorLines) {\n\t\t\t\tthis.listContainer.addChild(new Text(theme.fg(\"error\", line), 0, 0));\n\t\t\t}\n\t\t} else if (this.filteredModels.length === 0) {\n\t\t\tthis.listContainer.addChild(new Text(theme.fg(\"muted\", \" No matching models\"), 0, 0));\n\t\t} else {\n\t\t\tconst selected = this.filteredModels[this.selectedIndex];\n\t\t\tthis.listContainer.addChild(new Spacer(1));\n\t\t\tthis.listContainer.addChild(new Text(theme.fg(\"muted\", ` Model Name: ${selected.model.name}`), 0, 0));\n\t\t}\n\t\tif (this.refreshStatusMessage) {\n\t\t\tthis.listContainer.addChild(new Spacer(1));\n\t\t\tthis.listContainer.addChild(\n\t\t\t\tnew Text(theme.fg(this.refreshStatusSuccess ? \"success\" : \"muted\", ` ${this.refreshStatusMessage}`), 0, 0),\n\t\t\t);\n\t\t}\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getKeybindings();\n\t\tif (kb.matches(keyData, \"tui.input.tab\")) {\n\t\t\tif (this.scopedModelItems.length > 0) {\n\t\t\t\tconst nextScope: ModelScope = this.scope === \"all\" ? \"narrowed\" : \"all\";\n\t\t\t\tthis.setScope(nextScope);\n\t\t\t\tif (this.scopeHintText) {\n\t\t\t\t\tthis.scopeHintText.setText(this.getScopeHintText());\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\t// Up arrow - wrap to bottom when at top\n\t\tif (kb.matches(keyData, \"tui.select.up\")) {\n\t\t\tif (this.filteredModels.length === 0) return;\n\t\t\tthis.selectedIndex = this.selectedIndex === 0 ? this.filteredModels.length - 1 : this.selectedIndex - 1;\n\t\t\tthis.updateList();\n\t\t}\n\t\t// Down arrow - wrap to top when at bottom\n\t\telse if (kb.matches(keyData, \"tui.select.down\")) {\n\t\t\tif (this.filteredModels.length === 0) return;\n\t\t\tthis.selectedIndex = this.selectedIndex === this.filteredModels.length - 1 ? 0 : this.selectedIndex + 1;\n\t\t\tthis.updateList();\n\t\t}\n\t\t// Enter\n\t\telse if (kb.matches(keyData, \"tui.select.confirm\")) {\n\t\t\tconst selectedModel = this.filteredModels[this.selectedIndex];\n\t\t\tif (selectedModel) {\n\t\t\t\tthis.handleSelect(selectedModel.model);\n\t\t\t}\n\t\t}\n\t\t// Toggle favorite for selected model\n\t\telse if (kb.matches(keyData, \"app.models.toggleFavorite\")) {\n\t\t\tthis.handleToggleFavorite();\n\t\t}\n\t\t// Escape or Ctrl+C\n\t\telse if (kb.matches(keyData, \"tui.select.cancel\")) {\n\t\t\tthis.close();\n\t\t\tthis.onCancelCallback();\n\t\t}\n\t\t// Pass everything else to search input\n\t\telse {\n\t\t\tthis.searchInput.handleInput(keyData);\n\t\t\tthis.filterModels(this.searchInput.getValue());\n\t\t}\n\t}\n\n\tprivate handleSelect(model: Model<any>): void {\n\t\tthis.close();\n\t\t// Save as new default\n\t\tthis.settingsManager.setDefaultModelAndProvider(model.provider, model.id);\n\t\tthis.onSelectCallback(model);\n\t}\n\n\tprivate handleToggleFavorite(): void {\n\t\tconst selectedModel = this.filteredModels[this.selectedIndex];\n\t\tif (!selectedModel) return;\n\n\t\tconst allModelIds = this.allModels.map((model) => model.fullId);\n\t\tthis.favoriteIds = toggleFavoriteModel(this.favoriteIds, allModelIds, selectedModel.fullId);\n\t\tthis.allModels = this.sortModels(this.allModels);\n\t\tthis.activeModels = this.scope === \"narrowed\" ? this.scopedModelItems : this.allModels;\n\t\tthis.filterModels(this.searchInput.getValue());\n\t\tconst selectedIndex = this.filteredModels.findIndex((item) => item.fullId === selectedModel.fullId);\n\t\tif (selectedIndex >= 0) {\n\t\t\tthis.selectedIndex = selectedIndex;\n\t\t\tthis.updateList();\n\t\t}\n\t\tconst nextFavoriteIds = this.favoriteIds === null ? null : [...this.favoriteIds];\n\t\tvoid this.onFavoriteChangeCallback?.(\n\t\t\tnextFavoriteIds,\n\t\t\tthis.allModels.map((item) => item.model),\n\t\t\tselectedModel.model,\n\t\t);\n\t\tthis.tui.requestRender();\n\t}\n\n\tgetSearchInput(): Input {\n\t\treturn this.searchInput;\n\t}\n}\n"]}
@@ -1,9 +1,11 @@
1
+ import type { ApiKeyAuth, AuthCheck, OAuthAuth } from "@earendil-works/pi-ai";
1
2
  import { Container, type Focusable } from "@earendil-works/pi-tui";
2
- import type { AuthStatus, AuthStorage } from "../../../core/auth-storage.ts";
3
3
  export type AuthSelectorProvider = {
4
4
  id: string;
5
5
  name: string;
6
6
  authType: "oauth" | "api_key";
7
+ method?: ApiKeyAuth | OAuthAuth;
8
+ status?: AuthCheck;
7
9
  };
8
10
  export declare function formatAuthSelectorProviderType(authType: AuthSelectorProvider["authType"]): string;
9
11
  /**
@@ -19,12 +21,10 @@ export declare class OAuthSelectorComponent extends Container implements Focusab
19
21
  private filteredProviders;
20
22
  private selectedIndex;
21
23
  private mode;
22
- private authStorage;
23
- private getAuthStatus;
24
24
  private onSelectCallback;
25
25
  private onCancelCallback;
26
26
  private showAuthTypeLabels;
27
- constructor(mode: "login" | "logout", authStorage: AuthStorage, providers: AuthSelectorProvider[], onSelect: (providerId: string, authType: AuthSelectorProvider["authType"]) => void, onCancel: () => void, getAuthStatus?: (providerId: string) => AuthStatus, initialSearchInput?: string);
27
+ constructor(mode: "login" | "logout", providers: AuthSelectorProvider[], onSelect: (providerId: string, authType: AuthSelectorProvider["authType"]) => void, onCancel: () => void, initialSearchInput?: string);
28
28
  private filterProviders;
29
29
  private updateList;
30
30
  private formatStatusIndicator;
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-selector.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/oauth-selector.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,SAAS,EACT,KAAK,SAAS,EAMd,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAI7E,MAAM,MAAM,oBAAoB,GAAG;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;CAC9B,CAAC;AAEF,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,oBAAoB,CAAC,UAAU,CAAC,GAAG,MAAM,CAEjG;AAED;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,SAAU,YAAW,SAAS;IACzE,OAAO,CAAC,WAAW,CAAQ;IAG3B,OAAO,CAAC,QAAQ,CAAS;IACzB,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAGzB;IAED,OAAO,CAAC,aAAa,CAAY;IACjC,OAAO,CAAC,YAAY,CAAyB;IAC7C,OAAO,CAAC,iBAAiB,CAAyB;IAClD,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,aAAa,CAAqC;IAC1D,OAAO,CAAC,gBAAgB,CAA2E;IACnG,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,kBAAkB,CAAU;IAEpC,YACC,IAAI,EAAE,OAAO,GAAG,QAAQ,EACxB,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,oBAAoB,EAAE,EACjC,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,oBAAoB,CAAC,UAAU,CAAC,KAAK,IAAI,EAClF,QAAQ,EAAE,MAAM,IAAI,EACpB,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,UAAU,EAClD,kBAAkB,CAAC,EAAE,MAAM,EA8C3B;IAED,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,UAAU;IAkDlB,OAAO,CAAC,qBAAqB;IA0B7B,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CA8BjC;CACD"}
1
+ {"version":3,"file":"oauth-selector.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/oauth-selector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EACN,SAAS,EACT,KAAK,SAAS,EAMd,MAAM,wBAAwB,CAAC;AAIhC,MAAM,MAAM,oBAAoB,GAAG;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAChC,MAAM,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC;AAEF,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,oBAAoB,CAAC,UAAU,CAAC,GAAG,MAAM,CAEjG;AAED;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,SAAU,YAAW,SAAS;IACzE,OAAO,CAAC,WAAW,CAAQ;IAG3B,OAAO,CAAC,QAAQ,CAAS;IACzB,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAGzB;IAED,OAAO,CAAC,aAAa,CAAY;IACjC,OAAO,CAAC,YAAY,CAAyB;IAC7C,OAAO,CAAC,iBAAiB,CAAyB;IAClD,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,gBAAgB,CAA2E;IACnG,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,kBAAkB,CAAU;IAEpC,YACC,IAAI,EAAE,OAAO,GAAG,QAAQ,EACxB,SAAS,EAAE,oBAAoB,EAAE,EACjC,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,oBAAoB,CAAC,UAAU,CAAC,KAAK,IAAI,EAClF,QAAQ,EAAE,MAAM,IAAI,EACpB,kBAAkB,CAAC,EAAE,MAAM,EA4C3B;IAED,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,UAAU;IAkDlB,OAAO,CAAC,qBAAqB;IAmB7B,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CA8BjC;CACD"}