@greppleai/grip 0.1.5 → 0.1.6

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 (565) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +1 -1
  3. package/dist/bun/cli.d.ts.map +1 -1
  4. package/dist/bun/cli.js.map +1 -1
  5. package/dist/bun/embedded-assets.d.ts.map +1 -1
  6. package/dist/bun/embedded-assets.js.map +1 -1
  7. package/dist/bun/register-bedrock.d.ts.map +1 -1
  8. package/dist/bun/restore-sandbox-env.d.ts.map +1 -1
  9. package/dist/bun/restore-sandbox-env.js.map +1 -1
  10. package/dist/cli/args.d.ts.map +1 -1
  11. package/dist/cli/args.js.map +1 -1
  12. package/dist/cli/config-selector.d.ts.map +1 -1
  13. package/dist/cli/config-selector.js.map +1 -1
  14. package/dist/cli/file-processor.d.ts.map +1 -1
  15. package/dist/cli/file-processor.js.map +1 -1
  16. package/dist/cli/initial-message.d.ts +1 -1
  17. package/dist/cli/initial-message.d.ts.map +1 -1
  18. package/dist/cli/initial-message.js.map +1 -1
  19. package/dist/cli/list-models.d.ts.map +1 -1
  20. package/dist/cli/list-models.js.map +1 -1
  21. package/dist/cli/session-picker.d.ts.map +1 -1
  22. package/dist/cli/session-picker.js.map +1 -1
  23. package/dist/cli.d.ts.map +1 -1
  24. package/dist/cli.js.map +1 -1
  25. package/dist/config.d.ts.map +1 -1
  26. package/dist/config.js.map +1 -1
  27. package/dist/core/agent-session.d.ts +27 -0
  28. package/dist/core/agent-session.d.ts.map +1 -1
  29. package/dist/core/agent-session.js +117 -152
  30. package/dist/core/agent-session.js.map +1 -1
  31. package/dist/core/auth-guidance.d.ts.map +1 -1
  32. package/dist/core/auth-guidance.js.map +1 -1
  33. package/dist/core/auth-storage.d.ts +4 -0
  34. package/dist/core/auth-storage.d.ts.map +1 -1
  35. package/dist/core/auth-storage.js +3 -10
  36. package/dist/core/auth-storage.js.map +1 -1
  37. package/dist/core/bash-executor.d.ts.map +1 -1
  38. package/dist/core/bash-executor.js +19 -23
  39. package/dist/core/bash-executor.js.map +1 -1
  40. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  41. package/dist/core/compaction/branch-summarization.js.map +1 -1
  42. package/dist/core/compaction/compaction.d.ts.map +1 -1
  43. package/dist/core/compaction/compaction.js.map +1 -1
  44. package/dist/core/compaction/compression-detection-ledger.d.ts.map +1 -1
  45. package/dist/core/compaction/compression-detection-ledger.js.map +1 -1
  46. package/dist/core/compaction/compression-detector.d.ts +1 -0
  47. package/dist/core/compaction/compression-detector.d.ts.map +1 -1
  48. package/dist/core/compaction/compression-detector.js +10 -21
  49. package/dist/core/compaction/compression-detector.js.map +1 -1
  50. package/dist/core/compaction/compression-economics.d.ts.map +1 -1
  51. package/dist/core/compaction/compression-economics.js.map +1 -1
  52. package/dist/core/compaction/utils.d.ts.map +1 -1
  53. package/dist/core/compaction/utils.js.map +1 -1
  54. package/dist/core/defaults.d.ts.map +1 -1
  55. package/dist/core/diagnostics.d.ts.map +1 -1
  56. package/dist/core/event-bus.d.ts.map +1 -1
  57. package/dist/core/event-bus.js.map +1 -1
  58. package/dist/core/exec.d.ts.map +1 -1
  59. package/dist/core/exec.js.map +1 -1
  60. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
  61. package/dist/core/export-html/ansi-to-html.js.map +1 -1
  62. package/dist/core/export-html/index.d.ts.map +1 -1
  63. package/dist/core/export-html/index.js.map +1 -1
  64. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  65. package/dist/core/export-html/tool-renderer.js.map +1 -1
  66. package/dist/core/extensions/loader.d.ts.map +1 -1
  67. package/dist/core/extensions/loader.js.map +1 -1
  68. package/dist/core/extensions/runner.d.ts.map +1 -1
  69. package/dist/core/extensions/runner.js +18 -30
  70. package/dist/core/extensions/runner.js.map +1 -1
  71. package/dist/core/extensions/types.d.ts.map +1 -1
  72. package/dist/core/extensions/types.js.map +1 -1
  73. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  74. package/dist/core/extensions/wrapper.js.map +1 -1
  75. package/dist/core/footer-data-provider.d.ts.map +1 -1
  76. package/dist/core/footer-data-provider.js +15 -16
  77. package/dist/core/footer-data-provider.js.map +1 -1
  78. package/dist/core/grip-agent.d.ts.map +1 -1
  79. package/dist/core/grip-agent.js +7 -21
  80. package/dist/core/grip-agent.js.map +1 -1
  81. package/dist/core/grip-manifest.d.ts.map +1 -1
  82. package/dist/core/grip-manifest.js.map +1 -1
  83. package/dist/core/hooks/aggregate.d.ts.map +1 -1
  84. package/dist/core/hooks/aggregate.js.map +1 -1
  85. package/dist/core/hooks/config.d.ts.map +1 -1
  86. package/dist/core/hooks/config.js.map +1 -1
  87. package/dist/core/hooks/executor.d.ts.map +1 -1
  88. package/dist/core/hooks/executor.js.map +1 -1
  89. package/dist/core/hooks/index.d.ts.map +1 -1
  90. package/dist/core/hooks/index.js.map +1 -1
  91. package/dist/core/hooks/matcher.d.ts.map +1 -1
  92. package/dist/core/hooks/matcher.js.map +1 -1
  93. package/dist/core/hooks/trust-store.d.ts.map +1 -1
  94. package/dist/core/hooks/trust-store.js +0 -3
  95. package/dist/core/hooks/trust-store.js.map +1 -1
  96. package/dist/core/hooks/types.d.ts.map +1 -1
  97. package/dist/core/hooks/types.js.map +1 -1
  98. package/dist/core/http-dispatcher.d.ts.map +1 -1
  99. package/dist/core/http-dispatcher.js.map +1 -1
  100. package/dist/core/instruction-resource-loader.d.ts.map +1 -1
  101. package/dist/core/instruction-resource-loader.js +0 -3
  102. package/dist/core/instruction-resource-loader.js.map +1 -1
  103. package/dist/core/keybindings.d.ts.map +1 -1
  104. package/dist/core/keybindings.js +0 -1
  105. package/dist/core/keybindings.js.map +1 -1
  106. package/dist/core/lsp/abort.d.ts.map +1 -1
  107. package/dist/core/lsp/abort.js.map +1 -1
  108. package/dist/core/lsp/client.d.ts.map +1 -1
  109. package/dist/core/lsp/client.js +8 -22
  110. package/dist/core/lsp/client.js.map +1 -1
  111. package/dist/core/lsp/config-loader.d.ts.map +1 -1
  112. package/dist/core/lsp/config-loader.js.map +1 -1
  113. package/dist/core/lsp/config.d.ts.map +1 -1
  114. package/dist/core/lsp/config.js.map +1 -1
  115. package/dist/core/lsp/diagnostics.d.ts.map +1 -1
  116. package/dist/core/lsp/diagnostics.js.map +1 -1
  117. package/dist/core/lsp/file-sync.d.ts.map +1 -1
  118. package/dist/core/lsp/file-sync.js +7 -9
  119. package/dist/core/lsp/file-sync.js.map +1 -1
  120. package/dist/core/lsp/integration.d.ts.map +1 -1
  121. package/dist/core/lsp/integration.js.map +1 -1
  122. package/dist/core/lsp/language-map.d.ts.map +1 -1
  123. package/dist/core/lsp/language-map.js +2 -7
  124. package/dist/core/lsp/language-map.js.map +1 -1
  125. package/dist/core/lsp/manager.d.ts.map +1 -1
  126. package/dist/core/lsp/manager.js +18 -29
  127. package/dist/core/lsp/manager.js.map +1 -1
  128. package/dist/core/lsp/navigation.d.ts.map +1 -1
  129. package/dist/core/lsp/navigation.js.map +1 -1
  130. package/dist/core/lsp/portable-path.d.ts.map +1 -1
  131. package/dist/core/lsp/portable-path.js.map +1 -1
  132. package/dist/core/lsp/refactor.d.ts.map +1 -1
  133. package/dist/core/lsp/refactor.js.map +1 -1
  134. package/dist/core/lsp/transport.d.ts.map +1 -1
  135. package/dist/core/lsp/transport.js.map +1 -1
  136. package/dist/core/messages.d.ts.map +1 -1
  137. package/dist/core/messages.js.map +1 -1
  138. package/dist/core/model-registry.d.ts.map +1 -1
  139. package/dist/core/model-registry.js +5 -7
  140. package/dist/core/model-registry.js.map +1 -1
  141. package/dist/core/model-resolver.d.ts.map +1 -1
  142. package/dist/core/model-resolver.js.map +1 -1
  143. package/dist/core/output-guard.d.ts.map +1 -1
  144. package/dist/core/output-guard.js.map +1 -1
  145. package/dist/core/package-manager.d.ts.map +1 -1
  146. package/dist/core/package-manager.js +0 -6
  147. package/dist/core/package-manager.js.map +1 -1
  148. package/dist/core/prompt-templates.d.ts.map +1 -1
  149. package/dist/core/prompt-templates.js.map +1 -1
  150. package/dist/core/provider-display-names.d.ts.map +1 -1
  151. package/dist/core/remote-workspace-protocol/contract.d.ts.map +1 -1
  152. package/dist/core/remote-workspace-protocol/contract.js +4 -2
  153. package/dist/core/remote-workspace-protocol/contract.js.map +1 -1
  154. package/dist/core/remote-workspace-protocol/guest-shared-client.d.ts.map +1 -1
  155. package/dist/core/remote-workspace-protocol/guest-shared-client.js +1 -5
  156. package/dist/core/remote-workspace-protocol/guest-shared-client.js.map +1 -1
  157. package/dist/core/remote-workspace-protocol/guest-shared-outbound-scheduler.d.ts.map +1 -1
  158. package/dist/core/remote-workspace-protocol/guest-shared-outbound-scheduler.js +5 -10
  159. package/dist/core/remote-workspace-protocol/guest-shared-outbound-scheduler.js.map +1 -1
  160. package/dist/core/remote-workspace-protocol/guest-shared-uplink.d.ts.map +1 -1
  161. package/dist/core/remote-workspace-protocol/guest-shared-uplink.js +2 -9
  162. package/dist/core/remote-workspace-protocol/guest-shared-uplink.js.map +1 -1
  163. package/dist/core/remote-workspace-protocol/lima-owner-directory.d.ts.map +1 -1
  164. package/dist/core/remote-workspace-protocol/lima-owner-directory.js.map +1 -1
  165. package/dist/core/remote-workspace-protocol/lima-owner-lock.d.ts.map +1 -1
  166. package/dist/core/remote-workspace-protocol/lima-owner-lock.js.map +1 -1
  167. package/dist/core/remote-workspace-protocol/session.d.ts.map +1 -1
  168. package/dist/core/remote-workspace-protocol/session.js +27 -65
  169. package/dist/core/remote-workspace-protocol/session.js.map +1 -1
  170. package/dist/core/remote-workspace-protocol/shared-transport.d.ts.map +1 -1
  171. package/dist/core/remote-workspace-protocol/shared-transport.js.map +1 -1
  172. package/dist/core/resolve-config-value.d.ts.map +1 -1
  173. package/dist/core/resolve-config-value.js.map +1 -1
  174. package/dist/core/resource-loader.d.ts.map +1 -1
  175. package/dist/core/resource-loader.js +0 -48
  176. package/dist/core/resource-loader.js.map +1 -1
  177. package/dist/core/rules.d.ts.map +1 -1
  178. package/dist/core/rules.js.map +1 -1
  179. package/dist/core/sandbox/command.d.ts.map +1 -1
  180. package/dist/core/sandbox/command.js.map +1 -1
  181. package/dist/core/sandbox/config.d.ts.map +1 -1
  182. package/dist/core/sandbox/config.js.map +1 -1
  183. package/dist/core/sandbox/lima-guest-binary.d.ts.map +1 -1
  184. package/dist/core/sandbox/lima-guest-binary.js.map +1 -1
  185. package/dist/core/sandbox/lima.d.ts +2 -0
  186. package/dist/core/sandbox/lima.d.ts.map +1 -1
  187. package/dist/core/sandbox/lima.js +3 -9
  188. package/dist/core/sandbox/lima.js.map +1 -1
  189. package/dist/core/sandbox/shared-lima-roots.d.ts.map +1 -1
  190. package/dist/core/sandbox/shared-lima-roots.js.map +1 -1
  191. package/dist/core/sandbox/update-shared-guest-binary.d.ts.map +1 -1
  192. package/dist/core/sandbox/update-shared-guest-binary.js.map +1 -1
  193. package/dist/core/session/constants.d.ts.map +1 -1
  194. package/dist/core/session/context-metadata.d.ts.map +1 -1
  195. package/dist/core/session/context-metadata.js.map +1 -1
  196. package/dist/core/session/context.d.ts.map +1 -1
  197. package/dist/core/session/context.js.map +1 -1
  198. package/dist/core/session/ids.d.ts.map +1 -1
  199. package/dist/core/session/ids.js.map +1 -1
  200. package/dist/core/session/in-memory-session-manager.d.ts.map +1 -1
  201. package/dist/core/session/in-memory-session-manager.js +0 -1
  202. package/dist/core/session/in-memory-session-manager.js.map +1 -1
  203. package/dist/core/session/in-memory-session.d.ts.map +1 -1
  204. package/dist/core/session/in-memory-session.js.map +1 -1
  205. package/dist/core/session/jsonl-errors.d.ts.map +1 -1
  206. package/dist/core/session/jsonl-errors.js +0 -11
  207. package/dist/core/session/jsonl-errors.js.map +1 -1
  208. package/dist/core/session/jsonl-helpers.d.ts.map +1 -1
  209. package/dist/core/session/jsonl-helpers.js.map +1 -1
  210. package/dist/core/session/local-session-manager.d.ts.map +1 -1
  211. package/dist/core/session/local-session-manager.js +4 -6
  212. package/dist/core/session/local-session-manager.js.map +1 -1
  213. package/dist/core/session/local-session.d.ts.map +1 -1
  214. package/dist/core/session/local-session.js.map +1 -1
  215. package/dist/core/session/migrations.d.ts.map +1 -1
  216. package/dist/core/session/migrations.js.map +1 -1
  217. package/dist/core/session/remote-session-client.d.ts.map +1 -1
  218. package/dist/core/session/remote-session-client.js +0 -6
  219. package/dist/core/session/remote-session-client.js.map +1 -1
  220. package/dist/core/session/remote-session-manager.d.ts.map +1 -1
  221. package/dist/core/session/remote-session-manager.js +0 -3
  222. package/dist/core/session/remote-session-manager.js.map +1 -1
  223. package/dist/core/session/remote-session.d.ts.map +1 -1
  224. package/dist/core/session/remote-session.js +0 -1
  225. package/dist/core/session/remote-session.js.map +1 -1
  226. package/dist/core/session/session-manager.d.ts.map +1 -1
  227. package/dist/core/session/session.d.ts.map +1 -1
  228. package/dist/core/session/session.js +1 -5
  229. package/dist/core/session/session.js.map +1 -1
  230. package/dist/core/session/stores/in-memory-session-store.d.ts.map +1 -1
  231. package/dist/core/session/stores/in-memory-session-store.js +7 -6
  232. package/dist/core/session/stores/in-memory-session-store.js.map +1 -1
  233. package/dist/core/session/stores/jsonl-session-store.d.ts.map +1 -1
  234. package/dist/core/session/stores/jsonl-session-store.js +6 -14
  235. package/dist/core/session/stores/jsonl-session-store.js.map +1 -1
  236. package/dist/core/session/stores/remote-session-store.d.ts.map +1 -1
  237. package/dist/core/session/stores/remote-session-store.js +3 -8
  238. package/dist/core/session/stores/remote-session-store.js.map +1 -1
  239. package/dist/core/session/stores/session-store.d.ts.map +1 -1
  240. package/dist/core/session/types.d.ts.map +1 -1
  241. package/dist/core/session/usage-ledger.d.ts.map +1 -1
  242. package/dist/core/session/usage-ledger.js.map +1 -1
  243. package/dist/core/session-cwd.d.ts.map +1 -1
  244. package/dist/core/session-cwd.js +0 -1
  245. package/dist/core/session-cwd.js.map +1 -1
  246. package/dist/core/settings-manager.d.ts.map +1 -1
  247. package/dist/core/settings-manager.js +9 -17
  248. package/dist/core/settings-manager.js.map +1 -1
  249. package/dist/core/skills.d.ts.map +1 -1
  250. package/dist/core/skills.js.map +1 -1
  251. package/dist/core/slash-commands.d.ts.map +1 -1
  252. package/dist/core/source-info.d.ts.map +1 -1
  253. package/dist/core/source-info.js.map +1 -1
  254. package/dist/core/system-prompt.d.ts.map +1 -1
  255. package/dist/core/system-prompt.js.map +1 -1
  256. package/dist/core/telemetry.d.ts.map +1 -1
  257. package/dist/core/telemetry.js.map +1 -1
  258. package/dist/core/timings.d.ts.map +1 -1
  259. package/dist/core/timings.js.map +1 -1
  260. package/dist/core/tools/bash.d.ts.map +1 -1
  261. package/dist/core/tools/bash.js +8 -5
  262. package/dist/core/tools/bash.js.map +1 -1
  263. package/dist/core/tools/compress-context.d.ts.map +1 -1
  264. package/dist/core/tools/compress-context.js.map +1 -1
  265. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  266. package/dist/core/tools/edit-diff.js.map +1 -1
  267. package/dist/core/tools/edit.d.ts.map +1 -1
  268. package/dist/core/tools/edit.js.map +1 -1
  269. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
  270. package/dist/core/tools/file-mutation-queue.js.map +1 -1
  271. package/dist/core/tools/find.d.ts.map +1 -1
  272. package/dist/core/tools/find.js.map +1 -1
  273. package/dist/core/tools/grep.d.ts.map +1 -1
  274. package/dist/core/tools/grep.js.map +1 -1
  275. package/dist/core/tools/hash-store.d.ts.map +1 -1
  276. package/dist/core/tools/hash-store.js.map +1 -1
  277. package/dist/core/tools/hashline/apply.d.ts.map +1 -1
  278. package/dist/core/tools/hashline/apply.js.map +1 -1
  279. package/dist/core/tools/hashline/hash.d.ts.map +1 -1
  280. package/dist/core/tools/hashline/hash.js.map +1 -1
  281. package/dist/core/tools/hashline/parse.d.ts.map +1 -1
  282. package/dist/core/tools/hashline/parse.js.map +1 -1
  283. package/dist/core/tools/hashline/resolve.d.ts.map +1 -1
  284. package/dist/core/tools/hashline/resolve.js.map +1 -1
  285. package/dist/core/tools/hashline-utils.d.ts.map +1 -1
  286. package/dist/core/tools/hashline-utils.js.map +1 -1
  287. package/dist/core/tools/index.d.ts.map +1 -1
  288. package/dist/core/tools/index.js.map +1 -1
  289. package/dist/core/tools/ls.d.ts.map +1 -1
  290. package/dist/core/tools/ls.js.map +1 -1
  291. package/dist/core/tools/operations.d.ts +5 -0
  292. package/dist/core/tools/operations.d.ts.map +1 -1
  293. package/dist/core/tools/operations.js +26 -24
  294. package/dist/core/tools/operations.js.map +1 -1
  295. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  296. package/dist/core/tools/output-accumulator.js +12 -18
  297. package/dist/core/tools/output-accumulator.js.map +1 -1
  298. package/dist/core/tools/path-utils.d.ts.map +1 -1
  299. package/dist/core/tools/path-utils.js.map +1 -1
  300. package/dist/core/tools/read.d.ts.map +1 -1
  301. package/dist/core/tools/read.js.map +1 -1
  302. package/dist/core/tools/render-utils.d.ts.map +1 -1
  303. package/dist/core/tools/render-utils.js.map +1 -1
  304. package/dist/core/tools/replace-diff.d.ts.map +1 -1
  305. package/dist/core/tools/replace-diff.js.map +1 -1
  306. package/dist/core/tools/replace-normalize.d.ts.map +1 -1
  307. package/dist/core/tools/replace-normalize.js.map +1 -1
  308. package/dist/core/tools/replace-render.d.ts +1 -1
  309. package/dist/core/tools/replace-render.d.ts.map +1 -1
  310. package/dist/core/tools/replace-render.js.map +1 -1
  311. package/dist/core/tools/runtime.d.ts.map +1 -1
  312. package/dist/core/tools/runtime.js.map +1 -1
  313. package/dist/core/tools/session-history.d.ts.map +1 -1
  314. package/dist/core/tools/session-history.js.map +1 -1
  315. package/dist/core/tools/subagent-agents.d.ts.map +1 -1
  316. package/dist/core/tools/subagent-agents.js.map +1 -1
  317. package/dist/core/tools/subagent.d.ts.map +1 -1
  318. package/dist/core/tools/subagent.js.map +1 -1
  319. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  320. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  321. package/dist/core/tools/truncate.d.ts.map +1 -1
  322. package/dist/core/tools/truncate.js.map +1 -1
  323. package/dist/core/tools/websearch.d.ts.map +1 -1
  324. package/dist/core/tools/websearch.js.map +1 -1
  325. package/dist/core/tools/workspace-tool-host.d.ts +1 -0
  326. package/dist/core/tools/workspace-tool-host.d.ts.map +1 -1
  327. package/dist/core/tools/workspace-tool-host.js +36 -22
  328. package/dist/core/tools/workspace-tool-host.js.map +1 -1
  329. package/dist/core/tools/write.d.ts.map +1 -1
  330. package/dist/core/tools/write.js +0 -1
  331. package/dist/core/tools/write.js.map +1 -1
  332. package/dist/core/workspace-identity.d.ts.map +1 -1
  333. package/dist/daemon/activity-budget.d.ts.map +1 -1
  334. package/dist/daemon/activity-budget.js +2 -3
  335. package/dist/daemon/activity-budget.js.map +1 -1
  336. package/dist/daemon/command.d.ts.map +1 -1
  337. package/dist/daemon/command.js.map +1 -1
  338. package/dist/daemon/config.d.ts +2 -0
  339. package/dist/daemon/config.d.ts.map +1 -1
  340. package/dist/daemon/config.js +4 -0
  341. package/dist/daemon/config.js.map +1 -1
  342. package/dist/daemon/help.d.ts.map +1 -1
  343. package/dist/daemon/help.js +4 -3
  344. package/dist/daemon/help.js.map +1 -1
  345. package/dist/daemon/lsp-config.d.ts.map +1 -1
  346. package/dist/daemon/lsp-config.js.map +1 -1
  347. package/dist/daemon/outbound-budget.d.ts.map +1 -1
  348. package/dist/daemon/outbound-budget.js +2 -4
  349. package/dist/daemon/outbound-budget.js.map +1 -1
  350. package/dist/daemon/security.d.ts.map +1 -1
  351. package/dist/daemon/security.js.map +1 -1
  352. package/dist/daemon/server.d.ts.map +1 -1
  353. package/dist/daemon/server.js.map +1 -1
  354. package/dist/daemon/shared-connection.d.ts.map +1 -1
  355. package/dist/daemon/shared-connection.js +10 -15
  356. package/dist/daemon/shared-connection.js.map +1 -1
  357. package/dist/daemon/shared-revision.d.ts.map +1 -1
  358. package/dist/daemon/shared-revision.js +2 -1
  359. package/dist/daemon/shared-revision.js.map +1 -1
  360. package/dist/daemon/shared-roots.d.ts.map +1 -1
  361. package/dist/daemon/shared-roots.js +0 -1
  362. package/dist/daemon/shared-roots.js.map +1 -1
  363. package/dist/daemon/workspace-runtime.d.ts +2 -0
  364. package/dist/daemon/workspace-runtime.d.ts.map +1 -1
  365. package/dist/daemon/workspace-runtime.js +43 -15
  366. package/dist/daemon/workspace-runtime.js.map +1 -1
  367. package/dist/index.d.ts.map +1 -1
  368. package/dist/main.d.ts.map +1 -1
  369. package/dist/main.js.map +1 -1
  370. package/dist/migrations.d.ts.map +1 -1
  371. package/dist/migrations.js.map +1 -1
  372. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  373. package/dist/modes/interactive/components/assistant-message.js +3 -10
  374. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  375. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  376. package/dist/modes/interactive/components/bash-execution.js +4 -9
  377. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  378. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  379. package/dist/modes/interactive/components/bordered-loader.js +0 -3
  380. package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  381. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  382. package/dist/modes/interactive/components/branch-summary-message.js +1 -3
  383. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  384. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  385. package/dist/modes/interactive/components/compaction-summary-message.js +1 -3
  386. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  387. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  388. package/dist/modes/interactive/components/config-selector.js +6 -16
  389. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  390. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
  391. package/dist/modes/interactive/components/countdown-timer.js +0 -5
  392. package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
  393. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  394. package/dist/modes/interactive/components/custom-editor.js +1 -8
  395. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  396. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  397. package/dist/modes/interactive/components/custom-message.js +1 -6
  398. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  399. package/dist/modes/interactive/components/diff.d.ts.map +1 -1
  400. package/dist/modes/interactive/components/diff.js.map +1 -1
  401. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  402. package/dist/modes/interactive/components/dynamic-border.js +0 -1
  403. package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  404. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  405. package/dist/modes/interactive/components/extension-editor.js +1 -7
  406. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  407. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  408. package/dist/modes/interactive/components/extension-input.js +2 -8
  409. package/dist/modes/interactive/components/extension-input.js.map +1 -1
  410. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  411. package/dist/modes/interactive/components/extension-selector.js +1 -9
  412. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  413. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  414. package/dist/modes/interactive/components/footer.js +1 -3
  415. package/dist/modes/interactive/components/footer.js.map +1 -1
  416. package/dist/modes/interactive/components/hook-execution.d.ts.map +1 -1
  417. package/dist/modes/interactive/components/hook-execution.js +2 -5
  418. package/dist/modes/interactive/components/hook-execution.js.map +1 -1
  419. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  420. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  421. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  422. package/dist/modes/interactive/components/login-dialog.js +3 -9
  423. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  424. package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -1
  425. package/dist/modes/interactive/components/markdown-transform.js.map +1 -1
  426. package/dist/modes/interactive/components/mermaid.d.ts.map +1 -1
  427. package/dist/modes/interactive/components/mermaid.js.map +1 -1
  428. package/dist/modes/interactive/components/message-card.d.ts.map +1 -1
  429. package/dist/modes/interactive/components/message-card.js +0 -1
  430. package/dist/modes/interactive/components/message-card.js.map +1 -1
  431. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  432. package/dist/modes/interactive/components/model-selector.js +13 -28
  433. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  434. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  435. package/dist/modes/interactive/components/oauth-selector.js +3 -12
  436. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  437. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  438. package/dist/modes/interactive/components/scoped-models-selector.js +9 -13
  439. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  440. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  441. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  442. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  443. package/dist/modes/interactive/components/session-selector.js +33 -58
  444. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  445. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  446. package/dist/modes/interactive/components/settings-selector.js +0 -4
  447. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  448. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
  449. package/dist/modes/interactive/components/show-images-selector.js +0 -1
  450. package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
  451. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  452. package/dist/modes/interactive/components/skill-invocation-message.js +1 -3
  453. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  454. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
  455. package/dist/modes/interactive/components/theme-selector.js +0 -2
  456. package/dist/modes/interactive/components/theme-selector.js.map +1 -1
  457. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  458. package/dist/modes/interactive/components/thinking-selector.js +0 -1
  459. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  460. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  461. package/dist/modes/interactive/components/tool-execution.js +9 -24
  462. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  463. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  464. package/dist/modes/interactive/components/tree-selector.js +18 -34
  465. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  466. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  467. package/dist/modes/interactive/components/user-message-selector.js +3 -6
  468. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  469. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  470. package/dist/modes/interactive/components/user-message.js +0 -4
  471. package/dist/modes/interactive/components/user-message.js.map +1 -1
  472. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
  473. package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
  474. package/dist/modes/interactive/interactive-mode.d.ts +14 -0
  475. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  476. package/dist/modes/interactive/interactive-mode.js +159 -135
  477. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  478. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  479. package/dist/modes/interactive/theme/theme.js +0 -7
  480. package/dist/modes/interactive/theme/theme.js.map +1 -1
  481. package/dist/modes/json-event.d.ts.map +1 -1
  482. package/dist/modes/json-event.js.map +1 -1
  483. package/dist/modes/print-mode.d.ts.map +1 -1
  484. package/dist/modes/print-mode.js.map +1 -1
  485. package/dist/modes/rpc/jsonl.d.ts.map +1 -1
  486. package/dist/modes/rpc/jsonl.js.map +1 -1
  487. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  488. package/dist/modes/rpc/rpc-client.js +10 -11
  489. package/dist/modes/rpc/rpc-client.js.map +1 -1
  490. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  491. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  492. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  493. package/dist/package-manager-cli.d.ts.map +1 -1
  494. package/dist/package-manager-cli.js.map +1 -1
  495. package/dist/utils/ansi.d.ts.map +1 -1
  496. package/dist/utils/ansi.js.map +1 -1
  497. package/dist/utils/changelog.d.ts.map +1 -1
  498. package/dist/utils/changelog.js.map +1 -1
  499. package/dist/utils/child-process.d.ts.map +1 -1
  500. package/dist/utils/child-process.js.map +1 -1
  501. package/dist/utils/clipboard-image.d.ts.map +1 -1
  502. package/dist/utils/clipboard-image.js.map +1 -1
  503. package/dist/utils/clipboard-native.d.ts.map +1 -1
  504. package/dist/utils/clipboard-native.js.map +1 -1
  505. package/dist/utils/clipboard.d.ts.map +1 -1
  506. package/dist/utils/clipboard.js.map +1 -1
  507. package/dist/utils/deprecation.d.ts.map +1 -1
  508. package/dist/utils/deprecation.js.map +1 -1
  509. package/dist/utils/directory-completions.d.ts.map +1 -1
  510. package/dist/utils/directory-completions.js.map +1 -1
  511. package/dist/utils/exif-orientation.d.ts.map +1 -1
  512. package/dist/utils/exif-orientation.js.map +1 -1
  513. package/dist/utils/frontmatter.d.ts.map +1 -1
  514. package/dist/utils/frontmatter.js.map +1 -1
  515. package/dist/utils/fs-watch.d.ts.map +1 -1
  516. package/dist/utils/fs-watch.js.map +1 -1
  517. package/dist/utils/git.d.ts.map +1 -1
  518. package/dist/utils/git.js.map +1 -1
  519. package/dist/utils/grip-user-agent.d.ts.map +1 -1
  520. package/dist/utils/grip-user-agent.js.map +1 -1
  521. package/dist/utils/html.d.ts.map +1 -1
  522. package/dist/utils/html.js.map +1 -1
  523. package/dist/utils/image-convert.d.ts.map +1 -1
  524. package/dist/utils/image-convert.js.map +1 -1
  525. package/dist/utils/image-process.d.ts.map +1 -1
  526. package/dist/utils/image-process.js.map +1 -1
  527. package/dist/utils/image-resize-core.d.ts.map +1 -1
  528. package/dist/utils/image-resize-core.js.map +1 -1
  529. package/dist/utils/image-resize-worker.d.ts.map +1 -1
  530. package/dist/utils/image-resize-worker.js.map +1 -1
  531. package/dist/utils/image-resize.d.ts.map +1 -1
  532. package/dist/utils/image-resize.js.map +1 -1
  533. package/dist/utils/json.d.ts.map +1 -1
  534. package/dist/utils/json.js.map +1 -1
  535. package/dist/utils/mime.d.ts.map +1 -1
  536. package/dist/utils/mime.js.map +1 -1
  537. package/dist/utils/open-browser.d.ts.map +1 -1
  538. package/dist/utils/open-browser.js.map +1 -1
  539. package/dist/utils/paths.d.ts.map +1 -1
  540. package/dist/utils/paths.js.map +1 -1
  541. package/dist/utils/photon.d.ts.map +1 -1
  542. package/dist/utils/photon.js +10 -5
  543. package/dist/utils/photon.js.map +1 -1
  544. package/dist/utils/shell.d.ts.map +1 -1
  545. package/dist/utils/shell.js.map +1 -1
  546. package/dist/utils/sleep.d.ts.map +1 -1
  547. package/dist/utils/sleep.js.map +1 -1
  548. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  549. package/dist/utils/syntax-highlight.js +1 -1
  550. package/dist/utils/syntax-highlight.js.map +1 -1
  551. package/dist/utils/tools-manager.d.ts.map +1 -1
  552. package/dist/utils/tools-manager.js.map +1 -1
  553. package/dist/utils/version-check.d.ts.map +1 -1
  554. package/dist/utils/version-check.js.map +1 -1
  555. package/dist/utils/windows-self-update.d.ts.map +1 -1
  556. package/dist/utils/windows-self-update.js.map +1 -1
  557. package/docs/sandbox.md +6 -0
  558. package/docs/sessions.md +1 -1
  559. package/docs/usage.md +2 -1
  560. package/examples/extensions/custom-provider-anthropic/package.json +2 -2
  561. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  562. package/examples/extensions/sandbox/package.json +2 -2
  563. package/examples/extensions/with-deps/package.json +1 -1
  564. package/npm-shrinkwrap.json +601 -833
  565. package/package.json +20 -21
@@ -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,0BAA0B,CAAC;AACvF,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAuC,KAAK,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAM/G,UAAU,uBAAuB;IAChC,eAAe,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;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,EAmCtB;IAED,IAAI,MAAM,IAAI,WAAW,CAExB;IAED,OAAO,CAAC,MAAM;IAUd;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,uBAA4B,GAAG,IAAI,CAmBxF;IAED;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,CAc9C;IAED;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAW/C;IAED;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAsBjE;IAED;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAS9B;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","sourcesContent":["import { getOAuthProviders, type OAuthDeviceCodeInfo } from \"@greppleai/grip-ai/oauth\";\nimport { Container, type Focusable, getKeybindings, Input, Spacer, Text, type TUI } from \"@greppleai/grip-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\ninterface LoginAuthDisplayOptions {\n\tautoOpenBrowser?: boolean;\n}\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\tthis.inputResolver(this.input.getValue());\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 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, options: LoginAuthDisplayOptions = {}): 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\tif (options.autoOpenBrowser ?? true) {\n\t\t\topenBrowser(url);\n\t\t}\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\t// Do not open device-code URLs automatically. These flows need to work in headless environments.\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.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 without prompting for input.\n\t */\n\tshowInfo(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.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.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/login-dialog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACvF,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAuC,KAAK,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAM/G,UAAU,uBAAuB;IAChC,eAAe,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;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,EAmCtB;IAED,IAAI,MAAM,IAAI,WAAW,CAExB;IAED,OAAO,CAAC,MAAM;IAUd;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,uBAA4B,GAAG,IAAI,CAmBxF;IAED;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,CAc9C;IAED;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAW/C;IAED;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAsBjE;IAED;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAS9B;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"}
@@ -8,15 +8,6 @@ import { keyHint } from "./keybinding-hints.js";
8
8
  * Login dialog component - replaces editor during OAuth login flow
9
9
  */
10
10
  export class LoginDialogComponent extends Container {
11
- contentContainer;
12
- input;
13
- tui;
14
- abortController = new AbortController();
15
- inputResolver;
16
- inputRejecter;
17
- onComplete;
18
- // Focusable implementation - propagate to input for IME cursor positioning
19
- _focused = false;
20
11
  get focused() {
21
12
  return this._focused;
22
13
  }
@@ -26,6 +17,9 @@ export class LoginDialogComponent extends Container {
26
17
  }
27
18
  constructor(tui, providerId, onComplete, providerNameOverride, titleOverride) {
28
19
  super();
20
+ this.abortController = new AbortController();
21
+ // Focusable implementation - propagate to input for IME cursor positioning
22
+ this._focused = false;
29
23
  this.tui = tui;
30
24
  this.onComplete = onComplete;
31
25
  const providerInfo = getOAuthProviders().find((p) => p.id === providerId);
@@ -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 \"@greppleai/grip-ai/oauth\";\nimport { Container, type Focusable, getKeybindings, Input, Spacer, Text, type TUI } from \"@greppleai/grip-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\ninterface LoginAuthDisplayOptions {\n\tautoOpenBrowser?: boolean;\n}\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\tthis.inputResolver(this.input.getValue());\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 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, options: LoginAuthDisplayOptions = {}): 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\tif (options.autoOpenBrowser ?? true) {\n\t\t\topenBrowser(url);\n\t\t}\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\t// Do not open device-code URLs automatically. These flows need to work in headless environments.\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.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 without prompting for input.\n\t */\n\tshowInfo(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.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":"AAAA,OAAO,EAAE,iBAAiB,EAA4B,MAAM,0BAA0B,CAAC;AACvF,OAAO,EAAE,SAAS,EAAkB,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAY,MAAM,qBAAqB,CAAC;AAC/G,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAMhD;;GAEG;AACH,MAAM,OAAO,oBAAqB,SAAQ,SAAS;IAWlD,IAAI,OAAO;QACV,OAAO,IAAI,CAAC,QAAQ,CAAC;IACtB,CAAC;IACD,IAAI,OAAO,CAAC,KAAc;QACzB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC;IAC5B,CAAC;IAED,YACC,GAAQ,EACR,UAAkB,EAClB,UAAwD,EACxD,oBAA6B,EAC7B,aAAsB;QAEtB,KAAK,EAAE,CAAC;QAtBD,oBAAe,GAAG,IAAI,eAAe,EAAE,CAAC;QAKhD,2EAA2E;QACnE,aAAQ,GAAG,KAAK,CAAC;QAiBxB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAE7B,MAAM,YAAY,GAAG,iBAAiB,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC;QAC1E,MAAM,YAAY,GAAG,oBAAoB,IAAI,YAAY,EAAE,IAAI,IAAI,UAAU,CAAC;QAC9E,MAAM,KAAK,GAAG,aAAa,IAAI,YAAY,YAAY,EAAE,CAAC;QAE1D,aAAa;QACb,IAAI,CAAC,QAAQ,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC;QAEnC,QAAQ;QACR,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAErE,uBAAuB;QACvB,IAAI,CAAC,gBAAgB,GAAG,IAAI,SAAS,EAAE,CAAC;QACxC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAErC,2CAA2C;QAC3C,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,GAAG,EAAE;YAC1B,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;gBACxB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC1C,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;gBAC/B,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;YAChC,CAAC;QACF,CAAC,CAAC;QACF,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,GAAG,EAAE;YAC1B,IAAI,CAAC,MAAM,EAAE,CAAC;QACf,CAAC,CAAC;QAEF,gBAAgB;QAChB,IAAI,CAAC,QAAQ,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,MAAM;QACT,OAAO,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC;IACpC,CAAC;IAEO,MAAM;QACb,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;YACjD,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;YAC/B,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;QAChC,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,QAAQ,CAAC,GAAW,EAAE,YAAqB,EAAE,OAAO,GAA4B,EAAE;QACjF,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;QAC9B,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,MAAM,SAAS,GAAG,WAAW,GAAG,OAAO,GAAG,cAAc,CAAC;QACzD,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAE9E,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,oBAAoB,CAAC;QAC7F,MAAM,SAAS,GAAG,WAAW,GAAG,OAAO,SAAS,cAAc,CAAC;QAC/D,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAE3E,IAAI,YAAY,EAAE,CAAC;YAClB,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9C,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACnF,CAAC;QAED,IAAI,OAAO,CAAC,eAAe,IAAI,IAAI,EAAE,CAAC;YACrC,WAAW,CAAC,GAAG,CAAC,CAAC;QAClB,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,IAAyB;QACvC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;QAC9B,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,MAAM,SAAS,GAAG,WAAW,IAAI,CAAC,eAAe,OAAO,IAAI,CAAC,eAAe,cAAc,CAAC;QAC3F,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAE9E,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,oBAAoB,CAAC;QAC7F,MAAM,SAAS,GAAG,WAAW,IAAI,CAAC,eAAe,OAAO,SAAS,cAAc,CAAC;QAChF,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3E,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,eAAe,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAEpG,iGAAiG;QACjG,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,eAAe,CAAC,MAAc;QAC7B,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACxE,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,IAAI,OAAO,CAAC,mBAAmB,EAAE,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACjG,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAEzB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACtC,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;YAC7B,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC;QAC7B,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,UAAU,CAAC,OAAe,EAAE,WAAoB;QAC/C,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC1E,IAAI,WAAW,EAAE,CAAC;YACjB,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACzF,CAAC;QACD,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAC7B,IAAI,IAAI,CACP,IAAI,OAAO,CAAC,mBAAmB,EAAE,YAAY,CAAC,IAAI,OAAO,CAAC,oBAAoB,EAAE,WAAW,CAAC,GAAG,EAC/F,CAAC,EACD,CAAC,CACD,CACD,CAAC;QAEF,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACxB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAEzB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACtC,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;YAC7B,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC;QAC7B,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,QAAQ,CAAC,KAAe;QACvB,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;QAC9B,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YAC1B,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACtD,CAAC;QACD,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,IAAI,OAAO,CAAC,mBAAmB,EAAE,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAChG,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,OAAe;QAC1B,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACzE,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,IAAI,OAAO,CAAC,mBAAmB,EAAE,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACjG,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,OAAe;QAC3B,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACzE,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC1B,CAAC;IAED,WAAW,CAAC,IAAY;QACvB,MAAM,EAAE,GAAG,cAAc,EAAE,CAAC;QAE5B,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,mBAAmB,CAAC,EAAE,CAAC;YAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,OAAO;QACR,CAAC;QAED,gBAAgB;QAChB,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;CACD","sourcesContent":["import { getOAuthProviders, type OAuthDeviceCodeInfo } from \"@greppleai/grip-ai/oauth\";\nimport { Container, type Focusable, getKeybindings, Input, Spacer, Text, type TUI } from \"@greppleai/grip-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\ninterface LoginAuthDisplayOptions {\n\tautoOpenBrowser?: boolean;\n}\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\tthis.inputResolver(this.input.getValue());\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 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, options: LoginAuthDisplayOptions = {}): 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\tif (options.autoOpenBrowser ?? true) {\n\t\t\topenBrowser(url);\n\t\t}\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\t// Do not open device-code URLs automatically. These flows need to work in headless environments.\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.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 without prompting for input.\n\t */\n\tshowInfo(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.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 +1 @@
1
- {"version":3,"file":"markdown-transform.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/markdown-transform.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,EACnB,MAAM,mCAAmC,CAAC;AAE3C,wBAAgB,uBAAuB,CACtC,WAAW,EAAE,mBAAmB,EAChC,WAAW,EAAE,OAAO,EACpB,YAAY,EAAE,SAAS,mBAAmB,EAAE,GAC1C,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,MAAM,CAGtD;AAED,wBAAgB,yBAAyB,CACxC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,wBAAwB,EACjC,YAAY,EAAE,SAAS,mBAAmB,EAAE,GAC1C,MAAM,CAaR","sourcesContent":["import type {\n\tMarkdownMessageType,\n\tMarkdownTransformContext,\n\tMarkdownTransformer,\n} from \"../../../core/extensions/types.ts\";\n\nexport function createMarkdownTransform(\n\tmessageType: MarkdownMessageType,\n\tisStreaming: boolean,\n\ttransformers: readonly MarkdownTransformer[],\n): (markdown: string, availableWidth: number) => string {\n\treturn (markdown, availableWidth) =>\n\t\tapplyMarkdownTransformers(markdown, { messageType, isStreaming, availableWidth }, transformers);\n}\n\nexport function applyMarkdownTransformers(\n\tmarkdown: string,\n\tcontext: MarkdownTransformContext,\n\ttransformers: readonly MarkdownTransformer[],\n): string {\n\tlet transformedMarkdown = markdown;\n\tfor (const transformer of transformers) {\n\t\ttry {\n\t\t\tconst transformed: unknown = transformer(transformedMarkdown, context);\n\t\t\tif (typeof transformed === \"string\") {\n\t\t\t\ttransformedMarkdown = transformed;\n\t\t\t}\n\t\t} catch {\n\t\t\t// Preserve the current Markdown and continue with the next transformer.\n\t\t}\n\t}\n\treturn transformedMarkdown;\n}\n"]}
1
+ {"version":3,"file":"markdown-transform.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/markdown-transform.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,EACnB,MAAM,mCAAmC,CAAC;AAE3C,wBAAgB,uBAAuB,CACtC,WAAW,EAAE,mBAAmB,EAChC,WAAW,EAAE,OAAO,EACpB,YAAY,EAAE,SAAS,mBAAmB,EAAE,GAC1C,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,MAAM,CAGtD;AAED,wBAAgB,yBAAyB,CACxC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,wBAAwB,EACjC,YAAY,EAAE,SAAS,mBAAmB,EAAE,GAC1C,MAAM,CAaR"}
@@ -1 +1 @@
1
- {"version":3,"file":"markdown-transform.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/markdown-transform.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,uBAAuB,CACtC,WAAgC,EAChC,WAAoB,EACpB,YAA4C,EACW;IACvD,OAAO,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,CACnC,yBAAyB,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,EAAE,YAAY,CAAC,CAAC;AAAA,CACjG;AAED,MAAM,UAAU,yBAAyB,CACxC,QAAgB,EAChB,OAAiC,EACjC,YAA4C,EACnC;IACT,IAAI,mBAAmB,GAAG,QAAQ,CAAC;IACnC,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;QACxC,IAAI,CAAC;YACJ,MAAM,WAAW,GAAY,WAAW,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;YACvE,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;gBACrC,mBAAmB,GAAG,WAAW,CAAC;YACnC,CAAC;QACF,CAAC;QAAC,MAAM,CAAC;YACR,wEAAwE;QACzE,CAAC;IACF,CAAC;IACD,OAAO,mBAAmB,CAAC;AAAA,CAC3B","sourcesContent":["import type {\n\tMarkdownMessageType,\n\tMarkdownTransformContext,\n\tMarkdownTransformer,\n} from \"../../../core/extensions/types.ts\";\n\nexport function createMarkdownTransform(\n\tmessageType: MarkdownMessageType,\n\tisStreaming: boolean,\n\ttransformers: readonly MarkdownTransformer[],\n): (markdown: string, availableWidth: number) => string {\n\treturn (markdown, availableWidth) =>\n\t\tapplyMarkdownTransformers(markdown, { messageType, isStreaming, availableWidth }, transformers);\n}\n\nexport function applyMarkdownTransformers(\n\tmarkdown: string,\n\tcontext: MarkdownTransformContext,\n\ttransformers: readonly MarkdownTransformer[],\n): string {\n\tlet transformedMarkdown = markdown;\n\tfor (const transformer of transformers) {\n\t\ttry {\n\t\t\tconst transformed: unknown = transformer(transformedMarkdown, context);\n\t\t\tif (typeof transformed === \"string\") {\n\t\t\t\ttransformedMarkdown = transformed;\n\t\t\t}\n\t\t} catch {\n\t\t\t// Preserve the current Markdown and continue with the next transformer.\n\t\t}\n\t}\n\treturn transformedMarkdown;\n}\n"]}
1
+ {"version":3,"file":"markdown-transform.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/markdown-transform.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,uBAAuB,CACtC,WAAgC,EAChC,WAAoB,EACpB,YAA4C;IAE5C,OAAO,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,CACnC,yBAAyB,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,EAAE,YAAY,CAAC,CAAC;AAClG,CAAC;AAED,MAAM,UAAU,yBAAyB,CACxC,QAAgB,EAChB,OAAiC,EACjC,YAA4C;IAE5C,IAAI,mBAAmB,GAAG,QAAQ,CAAC;IACnC,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;QACxC,IAAI,CAAC;YACJ,MAAM,WAAW,GAAY,WAAW,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;YACvE,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;gBACrC,mBAAmB,GAAG,WAAW,CAAC;YACnC,CAAC;QACF,CAAC;QAAC,MAAM,CAAC;YACR,wEAAwE;QACzE,CAAC;IACF,CAAC;IACD,OAAO,mBAAmB,CAAC;AAC5B,CAAC","sourcesContent":["import type {\n\tMarkdownMessageType,\n\tMarkdownTransformContext,\n\tMarkdownTransformer,\n} from \"../../../core/extensions/types.ts\";\n\nexport function createMarkdownTransform(\n\tmessageType: MarkdownMessageType,\n\tisStreaming: boolean,\n\ttransformers: readonly MarkdownTransformer[],\n): (markdown: string, availableWidth: number) => string {\n\treturn (markdown, availableWidth) =>\n\t\tapplyMarkdownTransformers(markdown, { messageType, isStreaming, availableWidth }, transformers);\n}\n\nexport function applyMarkdownTransformers(\n\tmarkdown: string,\n\tcontext: MarkdownTransformContext,\n\ttransformers: readonly MarkdownTransformer[],\n): string {\n\tlet transformedMarkdown = markdown;\n\tfor (const transformer of transformers) {\n\t\ttry {\n\t\t\tconst transformed: unknown = transformer(transformedMarkdown, context);\n\t\t\tif (typeof transformed === \"string\") {\n\t\t\t\ttransformedMarkdown = transformed;\n\t\t\t}\n\t\t} catch {\n\t\t\t// Preserve the current Markdown and continue with the next transformer.\n\t\t}\n\t}\n\treturn transformedMarkdown;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"mermaid.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/mermaid.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAA4B,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACvG,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE/C,YAAY,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAa9E,KAAK,eAAe,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;AAEnD,MAAM,WAAW,yBAAyB;IACzC,OAAO,EAAE,MAAM,oBAAoB,CAAC;IACpC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,qEAAqE;IACrE,aAAa,CAAC,EAAE,eAAe,CAAC;CAChC;AA8OD,2GAA2G;AAC3G,wBAAgB,gCAAgC,CAAC,OAAO,EAAE,yBAAyB,GAAG,mBAAmB,CAcxG","sourcesContent":["import { Marked, type Token, type Tokens, visibleWidth } from \"@greppleai/grip-tui\";\nimport { type MermaidArt, render, type Span } from \"grok-mermaid\";\nimport type { MarkdownTransformContext, MarkdownTransformer } from \"../../../core/extensions/types.ts\";\nimport type { MermaidRenderingMode } from \"../../../core/settings-manager.ts\";\nimport type { Theme } from \"../theme/theme.ts\";\n\nexport type { MermaidRenderingMode } from \"../../../core/settings-manager.ts\";\n\nconst MAX_MERMAID_SOURCE_LENGTH = 64 * 1024;\nconst MAX_MERMAID_ROWS = 200;\nconst MAX_MERMAID_AREA = 50_000;\nconst MAX_MERMAID_WARNINGS = 512;\nconst MAX_MERMAID_WARNING_LENGTH = 4096;\nconst SPAN_CLASSES = new Set<Span[\"cls\"]>([\"border\", \"text\", \"edge\", \"edgeLabel\", \"title\", \"none\"]);\nconst UNSAFE_CONTROL_PATTERN = /[\\u0000-\\u001f\\u007f-\\u009f]/;\nconst SGR_PATTERN = /\\x1b\\[[0-9;]*m/g;\n\nconst markdownParser = new Marked();\n\ntype MermaidRenderer = (source: string) => unknown;\n\nexport interface MermaidTransformerOptions {\n\tgetMode: () => MermaidRenderingMode;\n\ttheme?: Theme;\n\t/** Override the renderer for deterministic fault-injection tests. */\n\trenderMermaid?: MermaidRenderer;\n}\n\ninterface MermaidTransformRuntime {\n\tcontext: MarkdownTransformContext;\n\toptions: MermaidTransformerOptions;\n\trenderMermaid: MermaidRenderer;\n}\n\nfunction isMermaid(token: Token): token is Tokens.Code {\n\treturn token.type === \"code\" && token.lang?.trim().split(/\\s+/, 1)[0]?.toLowerCase() === \"mermaid\";\n}\n\ninterface SourceToken {\n\ttoken: Token;\n\traw: string;\n}\n\ninterface NormalizedMarkdownSource {\n\tnormalized: string;\n\toriginalOffsets: number[];\n}\n\ninterface SourceLineEndings {\n\tlineEnding: string;\n\ttrailingLineEnding: string;\n}\n\nfunction normalizeMarkdownLineEndings(markdown: string): NormalizedMarkdownSource {\n\tlet normalized = \"\";\n\tconst originalOffsets = [0];\n\tfor (let index = 0; index < markdown.length; ) {\n\t\tif (markdown[index] === \"\\r\") {\n\t\t\tnormalized += \"\\n\";\n\t\t\tindex += markdown[index + 1] === \"\\n\" ? 2 : 1;\n\t\t} else {\n\t\t\tnormalized += markdown[index];\n\t\t\tindex++;\n\t\t}\n\t\toriginalOffsets.push(index);\n\t}\n\treturn { normalized, originalOffsets };\n}\n\nfunction lexNormalizedSource(\n\toriginal: string,\n\tnormalized: string,\n\toriginalOffsets?: number[],\n): SourceToken[] | undefined {\n\tlet offset = 0;\n\tconst sourceTokens: SourceToken[] = [];\n\tfor (const token of markdownParser.lexer(normalized)) {\n\t\tif (!normalized.startsWith(token.raw, offset)) return undefined;\n\t\tconst start = offset;\n\t\toffset += token.raw.length;\n\t\tconst raw = originalOffsets ? original.slice(originalOffsets[start], originalOffsets[offset]) : token.raw;\n\t\tsourceTokens.push({ token, raw });\n\t}\n\treturn offset === normalized.length ? sourceTokens : undefined;\n}\n\nfunction lexPreservingSource(markdown: string): SourceToken[] | undefined {\n\tif (!markdown.includes(\"\\r\")) return lexNormalizedSource(markdown, markdown);\n\tconst { normalized, originalOffsets } = normalizeMarkdownLineEndings(markdown);\n\treturn lexNormalizedSource(markdown, normalized, originalOffsets);\n}\nfunction codeSpan(line: string): string {\n\tconst content = line || \"\\u00a0\";\n\tconst longestBacktickRun = Math.max(0, ...Array.from(content.matchAll(/`+/g), (match) => match[0].length));\n\tconst fence = \"`\".repeat(longestBacktickRun + 1);\n\tconst padding = content.startsWith(\"`\") || content.endsWith(\"`\") ? \" \" : \"\";\n\treturn `${fence}${padding}${content}${padding}${fence}`;\n}\n\nfunction sourceLineEndings(raw: string): SourceLineEndings {\n\tconst trailingLineEnding = /(\\r\\n|\\r|\\n)$/.exec(raw)?.[1] ?? \"\";\n\treturn {\n\t\tlineEnding: trailingLineEnding || /(\\r\\n|\\r|\\n)/.exec(raw)?.[1] || \"\\n\",\n\t\ttrailingLineEnding,\n\t};\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasSafeText(value: unknown): value is string {\n\treturn typeof value === \"string\" && !UNSAFE_CONTROL_PATTERN.test(value);\n}\n\nfunction hasSafeWarnings(warnings: unknown[]): warnings is string[] {\n\tif (warnings.length > MAX_MERMAID_WARNINGS) {\n\t\treturn false;\n\t}\n\tfor (let index = 0; index < warnings.length; index++) {\n\t\tconst warning = warnings[index];\n\t\tif (\n\t\t\t!Object.hasOwn(warnings, index) ||\n\t\t\ttypeof warning !== \"string\" ||\n\t\t\twarning.length > MAX_MERMAID_WARNING_LENGTH ||\n\t\t\t!hasSafeText(warning)\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\nfunction validateArtRow(plainRow: unknown, styledRow: unknown, artWidth: number): number | undefined {\n\tif (!hasSafeText(plainRow) || !Array.isArray(styledRow)) return undefined;\n\tconst rowWidth = visibleWidth(plainRow);\n\tif (!Number.isSafeInteger(rowWidth) || rowWidth > artWidth) return undefined;\n\n\tlet reconstructed = \"\";\n\tfor (const span of styledRow) {\n\t\tif (\n\t\t\t!isRecord(span) ||\n\t\t\t!hasSafeText(span.text) ||\n\t\t\ttypeof span.cls !== \"string\" ||\n\t\t\t!SPAN_CLASSES.has(span.cls as Span[\"cls\"])\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\t\treconstructed += span.text;\n\t}\n\treturn reconstructed === plainRow ? rowWidth : undefined;\n}\nfunction validateArt(value: unknown, availableWidth: number): MermaidArt | undefined {\n\tif (!Number.isSafeInteger(availableWidth) || availableWidth < 0 || !isRecord(value)) {\n\t\treturn undefined;\n\t}\n\tconst { plain, styled, warnings, width } = value;\n\tif (\n\t\t!Number.isSafeInteger(width) ||\n\t\t(width as number) < 0 ||\n\t\t(width as number) > availableWidth ||\n\t\t!Array.isArray(plain) ||\n\t\tplain.length === 0 ||\n\t\tplain.length > MAX_MERMAID_ROWS ||\n\t\t!Array.isArray(styled) ||\n\t\tstyled.length !== plain.length ||\n\t\t!Array.isArray(warnings) ||\n\t\t!hasSafeWarnings(warnings) ||\n\t\t(width as number) * plain.length > MAX_MERMAID_AREA\n\t) {\n\t\treturn undefined;\n\t}\n\tconst artWidth = width as number;\n\tlet measuredWidth = 0;\n\tfor (let rowIndex = 0; rowIndex < plain.length; rowIndex++) {\n\t\tconst rowWidth = validateArtRow(plain[rowIndex], styled[rowIndex], artWidth);\n\t\tif (rowWidth === undefined) return undefined;\n\t\tmeasuredWidth = Math.max(measuredWidth, rowWidth);\n\t}\n\tif (measuredWidth !== artWidth) {\n\t\treturn undefined;\n\t}\n\treturn value as unknown as MermaidArt;\n}\n\nfunction styleSpan(span: Span, theme: Theme): string {\n\tswitch (span.cls) {\n\t\tcase \"border\":\n\t\t\treturn theme.fg(\"borderMuted\", span.text);\n\t\tcase \"text\":\n\t\t\treturn theme.fg(\"text\", span.text);\n\t\tcase \"edge\":\n\t\t\treturn theme.fg(\"accent\", span.text);\n\t\tcase \"edgeLabel\":\n\t\t\treturn theme.fg(\"muted\", span.text);\n\t\tcase \"title\":\n\t\t\treturn theme.fg(\"accent\", theme.bold(span.text));\n\t\tcase \"none\":\n\t\t\treturn span.text;\n\t}\n}\n\nfunction isSgrOnlyStyle(styled: string, plain: string): boolean {\n\treturn styled.replace(SGR_PATTERN, \"\") === plain;\n}\n\nfunction themedLines(art: MermaidArt, theme: Theme): string[] | undefined {\n\tconst lines: string[] = [];\n\tfor (let rowIndex = 0; rowIndex < art.styled.length; rowIndex++) {\n\t\tlet line = \"\";\n\t\tfor (const span of art.styled[rowIndex] ?? []) {\n\t\t\tconst styled = styleSpan(span, theme);\n\t\t\tif (!isSgrOnlyStyle(styled, span.text)) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tline += styled;\n\t\t}\n\t\tif (visibleWidth(line) !== visibleWidth(art.plain[rowIndex] ?? \"\")) {\n\t\t\treturn undefined;\n\t\t}\n\t\tlines.push(line);\n\t}\n\treturn lines;\n}\n\nfunction renderWarning(art: MermaidArt, theme: Theme | undefined): string | undefined {\n\tconst suffix = art.warnings.length > 1 ? ` (+${art.warnings.length - 1} more)` : \"\";\n\tconst warning = `Mermaid diagram not rendered: ${art.warnings[0]}${suffix}`;\n\tif (!theme) {\n\t\treturn codeSpan(warning);\n\t}\n\tconst styledWarning = theme.fg(\"warning\", warning);\n\treturn isSgrOnlyStyle(styledWarning, warning) ? codeSpan(styledWarning) : undefined;\n}\n\nfunction transformMermaidSourceToken(sourceToken: SourceToken, runtime: MermaidTransformRuntime): string {\n\tconst { token, raw } = sourceToken;\n\tif (!isMermaid(token) || raw.length > MAX_MERMAID_SOURCE_LENGTH) return raw;\n\ttry {\n\t\tconst art = validateArt(runtime.renderMermaid(token.text), runtime.context.availableWidth);\n\t\tif (!art) return raw;\n\t\tconst { lineEnding, trailingLineEnding } = sourceLineEndings(raw);\n\t\tif (!runtime.context.isStreaming && art.warnings.length > 0) {\n\t\t\tconst warning = renderWarning(art, runtime.options.theme);\n\t\t\tconst separator = trailingLineEnding ? \"\" : lineEnding;\n\t\t\tconst suffix = trailingLineEnding ? ` ${trailingLineEnding}` : \"\";\n\t\t\treturn warning ? `${raw}${separator}${warning}${suffix}` : raw;\n\t\t}\n\t\tconst lines = runtime.options.theme ? themedLines(art, runtime.options.theme) : art.plain;\n\t\tif (!lines) return raw;\n\t\tconst hardBreak = ` ${lineEnding}`;\n\t\tconst suffix = trailingLineEnding ? ` ${trailingLineEnding}` : \"\";\n\t\treturn `${lines.map(codeSpan).join(hardBreak)}${suffix}`;\n\t} catch {\n\t\treturn raw;\n\t}\n}\n\nfunction shouldRenderMermaid(mode: MermaidRenderingMode, context: MarkdownTransformContext): boolean {\n\treturn (\n\t\tmode !== \"off\" && context.messageType !== \"assistant-thinking\" && (!context.isStreaming || mode === \"streaming\")\n\t);\n}\n\n/** Create a pure transformer that replaces eligible top-level Mermaid fences with bounded terminal art. */\nexport function createMermaidMarkdownTransformer(options: MermaidTransformerOptions): MarkdownTransformer {\n\tconst renderMermaid = options.renderMermaid ?? (render as MermaidRenderer);\n\treturn (markdown, context) => {\n\t\tconst mode = options.getMode();\n\t\tif (!shouldRenderMermaid(mode, context)) return markdown;\n\t\ttry {\n\t\t\tconst sourceTokens = lexPreservingSource(markdown);\n\t\t\tif (!sourceTokens) return markdown;\n\t\t\tconst runtime: MermaidTransformRuntime = { context, options, renderMermaid };\n\t\t\treturn sourceTokens.map((sourceToken) => transformMermaidSourceToken(sourceToken, runtime)).join(\"\");\n\t\t} catch {\n\t\t\treturn markdown;\n\t\t}\n\t};\n}\n"]}
1
+ {"version":3,"file":"mermaid.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/mermaid.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAA4B,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACvG,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE/C,YAAY,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAa9E,KAAK,eAAe,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;AAEnD,MAAM,WAAW,yBAAyB;IACzC,OAAO,EAAE,MAAM,oBAAoB,CAAC;IACpC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,qEAAqE;IACrE,aAAa,CAAC,EAAE,eAAe,CAAC;CAChC;AA8OD,2GAA2G;AAC3G,wBAAgB,gCAAgC,CAAC,OAAO,EAAE,yBAAyB,GAAG,mBAAmB,CAcxG"}
@@ -1 +1 @@
1
- {"version":3,"file":"mermaid.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/mermaid.ts"],"names":[],"mappings":"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","sourcesContent":["import { Marked, type Token, type Tokens, visibleWidth } from \"@greppleai/grip-tui\";\nimport { type MermaidArt, render, type Span } from \"grok-mermaid\";\nimport type { MarkdownTransformContext, MarkdownTransformer } from \"../../../core/extensions/types.ts\";\nimport type { MermaidRenderingMode } from \"../../../core/settings-manager.ts\";\nimport type { Theme } from \"../theme/theme.ts\";\n\nexport type { MermaidRenderingMode } from \"../../../core/settings-manager.ts\";\n\nconst MAX_MERMAID_SOURCE_LENGTH = 64 * 1024;\nconst MAX_MERMAID_ROWS = 200;\nconst MAX_MERMAID_AREA = 50_000;\nconst MAX_MERMAID_WARNINGS = 512;\nconst MAX_MERMAID_WARNING_LENGTH = 4096;\nconst SPAN_CLASSES = new Set<Span[\"cls\"]>([\"border\", \"text\", \"edge\", \"edgeLabel\", \"title\", \"none\"]);\nconst UNSAFE_CONTROL_PATTERN = /[\\u0000-\\u001f\\u007f-\\u009f]/;\nconst SGR_PATTERN = /\\x1b\\[[0-9;]*m/g;\n\nconst markdownParser = new Marked();\n\ntype MermaidRenderer = (source: string) => unknown;\n\nexport interface MermaidTransformerOptions {\n\tgetMode: () => MermaidRenderingMode;\n\ttheme?: Theme;\n\t/** Override the renderer for deterministic fault-injection tests. */\n\trenderMermaid?: MermaidRenderer;\n}\n\ninterface MermaidTransformRuntime {\n\tcontext: MarkdownTransformContext;\n\toptions: MermaidTransformerOptions;\n\trenderMermaid: MermaidRenderer;\n}\n\nfunction isMermaid(token: Token): token is Tokens.Code {\n\treturn token.type === \"code\" && token.lang?.trim().split(/\\s+/, 1)[0]?.toLowerCase() === \"mermaid\";\n}\n\ninterface SourceToken {\n\ttoken: Token;\n\traw: string;\n}\n\ninterface NormalizedMarkdownSource {\n\tnormalized: string;\n\toriginalOffsets: number[];\n}\n\ninterface SourceLineEndings {\n\tlineEnding: string;\n\ttrailingLineEnding: string;\n}\n\nfunction normalizeMarkdownLineEndings(markdown: string): NormalizedMarkdownSource {\n\tlet normalized = \"\";\n\tconst originalOffsets = [0];\n\tfor (let index = 0; index < markdown.length; ) {\n\t\tif (markdown[index] === \"\\r\") {\n\t\t\tnormalized += \"\\n\";\n\t\t\tindex += markdown[index + 1] === \"\\n\" ? 2 : 1;\n\t\t} else {\n\t\t\tnormalized += markdown[index];\n\t\t\tindex++;\n\t\t}\n\t\toriginalOffsets.push(index);\n\t}\n\treturn { normalized, originalOffsets };\n}\n\nfunction lexNormalizedSource(\n\toriginal: string,\n\tnormalized: string,\n\toriginalOffsets?: number[],\n): SourceToken[] | undefined {\n\tlet offset = 0;\n\tconst sourceTokens: SourceToken[] = [];\n\tfor (const token of markdownParser.lexer(normalized)) {\n\t\tif (!normalized.startsWith(token.raw, offset)) return undefined;\n\t\tconst start = offset;\n\t\toffset += token.raw.length;\n\t\tconst raw = originalOffsets ? original.slice(originalOffsets[start], originalOffsets[offset]) : token.raw;\n\t\tsourceTokens.push({ token, raw });\n\t}\n\treturn offset === normalized.length ? sourceTokens : undefined;\n}\n\nfunction lexPreservingSource(markdown: string): SourceToken[] | undefined {\n\tif (!markdown.includes(\"\\r\")) return lexNormalizedSource(markdown, markdown);\n\tconst { normalized, originalOffsets } = normalizeMarkdownLineEndings(markdown);\n\treturn lexNormalizedSource(markdown, normalized, originalOffsets);\n}\nfunction codeSpan(line: string): string {\n\tconst content = line || \"\\u00a0\";\n\tconst longestBacktickRun = Math.max(0, ...Array.from(content.matchAll(/`+/g), (match) => match[0].length));\n\tconst fence = \"`\".repeat(longestBacktickRun + 1);\n\tconst padding = content.startsWith(\"`\") || content.endsWith(\"`\") ? \" \" : \"\";\n\treturn `${fence}${padding}${content}${padding}${fence}`;\n}\n\nfunction sourceLineEndings(raw: string): SourceLineEndings {\n\tconst trailingLineEnding = /(\\r\\n|\\r|\\n)$/.exec(raw)?.[1] ?? \"\";\n\treturn {\n\t\tlineEnding: trailingLineEnding || /(\\r\\n|\\r|\\n)/.exec(raw)?.[1] || \"\\n\",\n\t\ttrailingLineEnding,\n\t};\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasSafeText(value: unknown): value is string {\n\treturn typeof value === \"string\" && !UNSAFE_CONTROL_PATTERN.test(value);\n}\n\nfunction hasSafeWarnings(warnings: unknown[]): warnings is string[] {\n\tif (warnings.length > MAX_MERMAID_WARNINGS) {\n\t\treturn false;\n\t}\n\tfor (let index = 0; index < warnings.length; index++) {\n\t\tconst warning = warnings[index];\n\t\tif (\n\t\t\t!Object.hasOwn(warnings, index) ||\n\t\t\ttypeof warning !== \"string\" ||\n\t\t\twarning.length > MAX_MERMAID_WARNING_LENGTH ||\n\t\t\t!hasSafeText(warning)\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\nfunction validateArtRow(plainRow: unknown, styledRow: unknown, artWidth: number): number | undefined {\n\tif (!hasSafeText(plainRow) || !Array.isArray(styledRow)) return undefined;\n\tconst rowWidth = visibleWidth(plainRow);\n\tif (!Number.isSafeInteger(rowWidth) || rowWidth > artWidth) return undefined;\n\n\tlet reconstructed = \"\";\n\tfor (const span of styledRow) {\n\t\tif (\n\t\t\t!isRecord(span) ||\n\t\t\t!hasSafeText(span.text) ||\n\t\t\ttypeof span.cls !== \"string\" ||\n\t\t\t!SPAN_CLASSES.has(span.cls as Span[\"cls\"])\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\t\treconstructed += span.text;\n\t}\n\treturn reconstructed === plainRow ? rowWidth : undefined;\n}\nfunction validateArt(value: unknown, availableWidth: number): MermaidArt | undefined {\n\tif (!Number.isSafeInteger(availableWidth) || availableWidth < 0 || !isRecord(value)) {\n\t\treturn undefined;\n\t}\n\tconst { plain, styled, warnings, width } = value;\n\tif (\n\t\t!Number.isSafeInteger(width) ||\n\t\t(width as number) < 0 ||\n\t\t(width as number) > availableWidth ||\n\t\t!Array.isArray(plain) ||\n\t\tplain.length === 0 ||\n\t\tplain.length > MAX_MERMAID_ROWS ||\n\t\t!Array.isArray(styled) ||\n\t\tstyled.length !== plain.length ||\n\t\t!Array.isArray(warnings) ||\n\t\t!hasSafeWarnings(warnings) ||\n\t\t(width as number) * plain.length > MAX_MERMAID_AREA\n\t) {\n\t\treturn undefined;\n\t}\n\tconst artWidth = width as number;\n\tlet measuredWidth = 0;\n\tfor (let rowIndex = 0; rowIndex < plain.length; rowIndex++) {\n\t\tconst rowWidth = validateArtRow(plain[rowIndex], styled[rowIndex], artWidth);\n\t\tif (rowWidth === undefined) return undefined;\n\t\tmeasuredWidth = Math.max(measuredWidth, rowWidth);\n\t}\n\tif (measuredWidth !== artWidth) {\n\t\treturn undefined;\n\t}\n\treturn value as unknown as MermaidArt;\n}\n\nfunction styleSpan(span: Span, theme: Theme): string {\n\tswitch (span.cls) {\n\t\tcase \"border\":\n\t\t\treturn theme.fg(\"borderMuted\", span.text);\n\t\tcase \"text\":\n\t\t\treturn theme.fg(\"text\", span.text);\n\t\tcase \"edge\":\n\t\t\treturn theme.fg(\"accent\", span.text);\n\t\tcase \"edgeLabel\":\n\t\t\treturn theme.fg(\"muted\", span.text);\n\t\tcase \"title\":\n\t\t\treturn theme.fg(\"accent\", theme.bold(span.text));\n\t\tcase \"none\":\n\t\t\treturn span.text;\n\t}\n}\n\nfunction isSgrOnlyStyle(styled: string, plain: string): boolean {\n\treturn styled.replace(SGR_PATTERN, \"\") === plain;\n}\n\nfunction themedLines(art: MermaidArt, theme: Theme): string[] | undefined {\n\tconst lines: string[] = [];\n\tfor (let rowIndex = 0; rowIndex < art.styled.length; rowIndex++) {\n\t\tlet line = \"\";\n\t\tfor (const span of art.styled[rowIndex] ?? []) {\n\t\t\tconst styled = styleSpan(span, theme);\n\t\t\tif (!isSgrOnlyStyle(styled, span.text)) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tline += styled;\n\t\t}\n\t\tif (visibleWidth(line) !== visibleWidth(art.plain[rowIndex] ?? \"\")) {\n\t\t\treturn undefined;\n\t\t}\n\t\tlines.push(line);\n\t}\n\treturn lines;\n}\n\nfunction renderWarning(art: MermaidArt, theme: Theme | undefined): string | undefined {\n\tconst suffix = art.warnings.length > 1 ? ` (+${art.warnings.length - 1} more)` : \"\";\n\tconst warning = `Mermaid diagram not rendered: ${art.warnings[0]}${suffix}`;\n\tif (!theme) {\n\t\treturn codeSpan(warning);\n\t}\n\tconst styledWarning = theme.fg(\"warning\", warning);\n\treturn isSgrOnlyStyle(styledWarning, warning) ? codeSpan(styledWarning) : undefined;\n}\n\nfunction transformMermaidSourceToken(sourceToken: SourceToken, runtime: MermaidTransformRuntime): string {\n\tconst { token, raw } = sourceToken;\n\tif (!isMermaid(token) || raw.length > MAX_MERMAID_SOURCE_LENGTH) return raw;\n\ttry {\n\t\tconst art = validateArt(runtime.renderMermaid(token.text), runtime.context.availableWidth);\n\t\tif (!art) return raw;\n\t\tconst { lineEnding, trailingLineEnding } = sourceLineEndings(raw);\n\t\tif (!runtime.context.isStreaming && art.warnings.length > 0) {\n\t\t\tconst warning = renderWarning(art, runtime.options.theme);\n\t\t\tconst separator = trailingLineEnding ? \"\" : lineEnding;\n\t\t\tconst suffix = trailingLineEnding ? ` ${trailingLineEnding}` : \"\";\n\t\t\treturn warning ? `${raw}${separator}${warning}${suffix}` : raw;\n\t\t}\n\t\tconst lines = runtime.options.theme ? themedLines(art, runtime.options.theme) : art.plain;\n\t\tif (!lines) return raw;\n\t\tconst hardBreak = ` ${lineEnding}`;\n\t\tconst suffix = trailingLineEnding ? ` ${trailingLineEnding}` : \"\";\n\t\treturn `${lines.map(codeSpan).join(hardBreak)}${suffix}`;\n\t} catch {\n\t\treturn raw;\n\t}\n}\n\nfunction shouldRenderMermaid(mode: MermaidRenderingMode, context: MarkdownTransformContext): boolean {\n\treturn (\n\t\tmode !== \"off\" && context.messageType !== \"assistant-thinking\" && (!context.isStreaming || mode === \"streaming\")\n\t);\n}\n\n/** Create a pure transformer that replaces eligible top-level Mermaid fences with bounded terminal art. */\nexport function createMermaidMarkdownTransformer(options: MermaidTransformerOptions): MarkdownTransformer {\n\tconst renderMermaid = options.renderMermaid ?? (render as MermaidRenderer);\n\treturn (markdown, context) => {\n\t\tconst mode = options.getMode();\n\t\tif (!shouldRenderMermaid(mode, context)) return markdown;\n\t\ttry {\n\t\t\tconst sourceTokens = lexPreservingSource(markdown);\n\t\t\tif (!sourceTokens) return markdown;\n\t\t\tconst runtime: MermaidTransformRuntime = { context, options, renderMermaid };\n\t\t\treturn sourceTokens.map((sourceToken) => transformMermaidSourceToken(sourceToken, runtime)).join(\"\");\n\t\t} catch {\n\t\t\treturn markdown;\n\t\t}\n\t};\n}\n"]}
1
+ {"version":3,"file":"mermaid.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/mermaid.ts"],"names":[],"mappings":"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","sourcesContent":["import { Marked, type Token, type Tokens, visibleWidth } from \"@greppleai/grip-tui\";\nimport { type MermaidArt, render, type Span } from \"grok-mermaid\";\nimport type { MarkdownTransformContext, MarkdownTransformer } from \"../../../core/extensions/types.ts\";\nimport type { MermaidRenderingMode } from \"../../../core/settings-manager.ts\";\nimport type { Theme } from \"../theme/theme.ts\";\n\nexport type { MermaidRenderingMode } from \"../../../core/settings-manager.ts\";\n\nconst MAX_MERMAID_SOURCE_LENGTH = 64 * 1024;\nconst MAX_MERMAID_ROWS = 200;\nconst MAX_MERMAID_AREA = 50_000;\nconst MAX_MERMAID_WARNINGS = 512;\nconst MAX_MERMAID_WARNING_LENGTH = 4096;\nconst SPAN_CLASSES = new Set<Span[\"cls\"]>([\"border\", \"text\", \"edge\", \"edgeLabel\", \"title\", \"none\"]);\nconst UNSAFE_CONTROL_PATTERN = /[\\u0000-\\u001f\\u007f-\\u009f]/;\nconst SGR_PATTERN = /\\x1b\\[[0-9;]*m/g;\n\nconst markdownParser = new Marked();\n\ntype MermaidRenderer = (source: string) => unknown;\n\nexport interface MermaidTransformerOptions {\n\tgetMode: () => MermaidRenderingMode;\n\ttheme?: Theme;\n\t/** Override the renderer for deterministic fault-injection tests. */\n\trenderMermaid?: MermaidRenderer;\n}\n\ninterface MermaidTransformRuntime {\n\tcontext: MarkdownTransformContext;\n\toptions: MermaidTransformerOptions;\n\trenderMermaid: MermaidRenderer;\n}\n\nfunction isMermaid(token: Token): token is Tokens.Code {\n\treturn token.type === \"code\" && token.lang?.trim().split(/\\s+/, 1)[0]?.toLowerCase() === \"mermaid\";\n}\n\ninterface SourceToken {\n\ttoken: Token;\n\traw: string;\n}\n\ninterface NormalizedMarkdownSource {\n\tnormalized: string;\n\toriginalOffsets: number[];\n}\n\ninterface SourceLineEndings {\n\tlineEnding: string;\n\ttrailingLineEnding: string;\n}\n\nfunction normalizeMarkdownLineEndings(markdown: string): NormalizedMarkdownSource {\n\tlet normalized = \"\";\n\tconst originalOffsets = [0];\n\tfor (let index = 0; index < markdown.length; ) {\n\t\tif (markdown[index] === \"\\r\") {\n\t\t\tnormalized += \"\\n\";\n\t\t\tindex += markdown[index + 1] === \"\\n\" ? 2 : 1;\n\t\t} else {\n\t\t\tnormalized += markdown[index];\n\t\t\tindex++;\n\t\t}\n\t\toriginalOffsets.push(index);\n\t}\n\treturn { normalized, originalOffsets };\n}\n\nfunction lexNormalizedSource(\n\toriginal: string,\n\tnormalized: string,\n\toriginalOffsets?: number[],\n): SourceToken[] | undefined {\n\tlet offset = 0;\n\tconst sourceTokens: SourceToken[] = [];\n\tfor (const token of markdownParser.lexer(normalized)) {\n\t\tif (!normalized.startsWith(token.raw, offset)) return undefined;\n\t\tconst start = offset;\n\t\toffset += token.raw.length;\n\t\tconst raw = originalOffsets ? original.slice(originalOffsets[start], originalOffsets[offset]) : token.raw;\n\t\tsourceTokens.push({ token, raw });\n\t}\n\treturn offset === normalized.length ? sourceTokens : undefined;\n}\n\nfunction lexPreservingSource(markdown: string): SourceToken[] | undefined {\n\tif (!markdown.includes(\"\\r\")) return lexNormalizedSource(markdown, markdown);\n\tconst { normalized, originalOffsets } = normalizeMarkdownLineEndings(markdown);\n\treturn lexNormalizedSource(markdown, normalized, originalOffsets);\n}\nfunction codeSpan(line: string): string {\n\tconst content = line || \"\\u00a0\";\n\tconst longestBacktickRun = Math.max(0, ...Array.from(content.matchAll(/`+/g), (match) => match[0].length));\n\tconst fence = \"`\".repeat(longestBacktickRun + 1);\n\tconst padding = content.startsWith(\"`\") || content.endsWith(\"`\") ? \" \" : \"\";\n\treturn `${fence}${padding}${content}${padding}${fence}`;\n}\n\nfunction sourceLineEndings(raw: string): SourceLineEndings {\n\tconst trailingLineEnding = /(\\r\\n|\\r|\\n)$/.exec(raw)?.[1] ?? \"\";\n\treturn {\n\t\tlineEnding: trailingLineEnding || /(\\r\\n|\\r|\\n)/.exec(raw)?.[1] || \"\\n\",\n\t\ttrailingLineEnding,\n\t};\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasSafeText(value: unknown): value is string {\n\treturn typeof value === \"string\" && !UNSAFE_CONTROL_PATTERN.test(value);\n}\n\nfunction hasSafeWarnings(warnings: unknown[]): warnings is string[] {\n\tif (warnings.length > MAX_MERMAID_WARNINGS) {\n\t\treturn false;\n\t}\n\tfor (let index = 0; index < warnings.length; index++) {\n\t\tconst warning = warnings[index];\n\t\tif (\n\t\t\t!Object.hasOwn(warnings, index) ||\n\t\t\ttypeof warning !== \"string\" ||\n\t\t\twarning.length > MAX_MERMAID_WARNING_LENGTH ||\n\t\t\t!hasSafeText(warning)\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\nfunction validateArtRow(plainRow: unknown, styledRow: unknown, artWidth: number): number | undefined {\n\tif (!hasSafeText(plainRow) || !Array.isArray(styledRow)) return undefined;\n\tconst rowWidth = visibleWidth(plainRow);\n\tif (!Number.isSafeInteger(rowWidth) || rowWidth > artWidth) return undefined;\n\n\tlet reconstructed = \"\";\n\tfor (const span of styledRow) {\n\t\tif (\n\t\t\t!isRecord(span) ||\n\t\t\t!hasSafeText(span.text) ||\n\t\t\ttypeof span.cls !== \"string\" ||\n\t\t\t!SPAN_CLASSES.has(span.cls as Span[\"cls\"])\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\t\treconstructed += span.text;\n\t}\n\treturn reconstructed === plainRow ? rowWidth : undefined;\n}\nfunction validateArt(value: unknown, availableWidth: number): MermaidArt | undefined {\n\tif (!Number.isSafeInteger(availableWidth) || availableWidth < 0 || !isRecord(value)) {\n\t\treturn undefined;\n\t}\n\tconst { plain, styled, warnings, width } = value;\n\tif (\n\t\t!Number.isSafeInteger(width) ||\n\t\t(width as number) < 0 ||\n\t\t(width as number) > availableWidth ||\n\t\t!Array.isArray(plain) ||\n\t\tplain.length === 0 ||\n\t\tplain.length > MAX_MERMAID_ROWS ||\n\t\t!Array.isArray(styled) ||\n\t\tstyled.length !== plain.length ||\n\t\t!Array.isArray(warnings) ||\n\t\t!hasSafeWarnings(warnings) ||\n\t\t(width as number) * plain.length > MAX_MERMAID_AREA\n\t) {\n\t\treturn undefined;\n\t}\n\tconst artWidth = width as number;\n\tlet measuredWidth = 0;\n\tfor (let rowIndex = 0; rowIndex < plain.length; rowIndex++) {\n\t\tconst rowWidth = validateArtRow(plain[rowIndex], styled[rowIndex], artWidth);\n\t\tif (rowWidth === undefined) return undefined;\n\t\tmeasuredWidth = Math.max(measuredWidth, rowWidth);\n\t}\n\tif (measuredWidth !== artWidth) {\n\t\treturn undefined;\n\t}\n\treturn value as unknown as MermaidArt;\n}\n\nfunction styleSpan(span: Span, theme: Theme): string {\n\tswitch (span.cls) {\n\t\tcase \"border\":\n\t\t\treturn theme.fg(\"borderMuted\", span.text);\n\t\tcase \"text\":\n\t\t\treturn theme.fg(\"text\", span.text);\n\t\tcase \"edge\":\n\t\t\treturn theme.fg(\"accent\", span.text);\n\t\tcase \"edgeLabel\":\n\t\t\treturn theme.fg(\"muted\", span.text);\n\t\tcase \"title\":\n\t\t\treturn theme.fg(\"accent\", theme.bold(span.text));\n\t\tcase \"none\":\n\t\t\treturn span.text;\n\t}\n}\n\nfunction isSgrOnlyStyle(styled: string, plain: string): boolean {\n\treturn styled.replace(SGR_PATTERN, \"\") === plain;\n}\n\nfunction themedLines(art: MermaidArt, theme: Theme): string[] | undefined {\n\tconst lines: string[] = [];\n\tfor (let rowIndex = 0; rowIndex < art.styled.length; rowIndex++) {\n\t\tlet line = \"\";\n\t\tfor (const span of art.styled[rowIndex] ?? []) {\n\t\t\tconst styled = styleSpan(span, theme);\n\t\t\tif (!isSgrOnlyStyle(styled, span.text)) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tline += styled;\n\t\t}\n\t\tif (visibleWidth(line) !== visibleWidth(art.plain[rowIndex] ?? \"\")) {\n\t\t\treturn undefined;\n\t\t}\n\t\tlines.push(line);\n\t}\n\treturn lines;\n}\n\nfunction renderWarning(art: MermaidArt, theme: Theme | undefined): string | undefined {\n\tconst suffix = art.warnings.length > 1 ? ` (+${art.warnings.length - 1} more)` : \"\";\n\tconst warning = `Mermaid diagram not rendered: ${art.warnings[0]}${suffix}`;\n\tif (!theme) {\n\t\treturn codeSpan(warning);\n\t}\n\tconst styledWarning = theme.fg(\"warning\", warning);\n\treturn isSgrOnlyStyle(styledWarning, warning) ? codeSpan(styledWarning) : undefined;\n}\n\nfunction transformMermaidSourceToken(sourceToken: SourceToken, runtime: MermaidTransformRuntime): string {\n\tconst { token, raw } = sourceToken;\n\tif (!isMermaid(token) || raw.length > MAX_MERMAID_SOURCE_LENGTH) return raw;\n\ttry {\n\t\tconst art = validateArt(runtime.renderMermaid(token.text), runtime.context.availableWidth);\n\t\tif (!art) return raw;\n\t\tconst { lineEnding, trailingLineEnding } = sourceLineEndings(raw);\n\t\tif (!runtime.context.isStreaming && art.warnings.length > 0) {\n\t\t\tconst warning = renderWarning(art, runtime.options.theme);\n\t\t\tconst separator = trailingLineEnding ? \"\" : lineEnding;\n\t\t\tconst suffix = trailingLineEnding ? ` ${trailingLineEnding}` : \"\";\n\t\t\treturn warning ? `${raw}${separator}${warning}${suffix}` : raw;\n\t\t}\n\t\tconst lines = runtime.options.theme ? themedLines(art, runtime.options.theme) : art.plain;\n\t\tif (!lines) return raw;\n\t\tconst hardBreak = ` ${lineEnding}`;\n\t\tconst suffix = trailingLineEnding ? ` ${trailingLineEnding}` : \"\";\n\t\treturn `${lines.map(codeSpan).join(hardBreak)}${suffix}`;\n\t} catch {\n\t\treturn raw;\n\t}\n}\n\nfunction shouldRenderMermaid(mode: MermaidRenderingMode, context: MarkdownTransformContext): boolean {\n\treturn (\n\t\tmode !== \"off\" && context.messageType !== \"assistant-thinking\" && (!context.isStreaming || mode === \"streaming\")\n\t);\n}\n\n/** Create a pure transformer that replaces eligible top-level Mermaid fences with bounded terminal art. */\nexport function createMermaidMarkdownTransformer(options: MermaidTransformerOptions): MarkdownTransformer {\n\tconst renderMermaid = options.renderMermaid ?? (render as MermaidRenderer);\n\treturn (markdown, context) => {\n\t\tconst mode = options.getMode();\n\t\tif (!shouldRenderMermaid(mode, context)) return markdown;\n\t\ttry {\n\t\t\tconst sourceTokens = lexPreservingSource(markdown);\n\t\t\tif (!sourceTokens) return markdown;\n\t\t\tconst runtime: MermaidTransformRuntime = { context, options, renderMermaid };\n\t\t\treturn sourceTokens.map((sourceToken) => transformMermaidSourceToken(sourceToken, runtime)).join(\"\");\n\t\t} catch {\n\t\t\treturn markdown;\n\t\t}\n\t};\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"message-card.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/message-card.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,KAAK,UAAU,EAAS,MAAM,mBAAmB,CAAC;AAE3D,+FAA+F;AAC/F,qBAAa,WAAY,SAAQ,GAAG;IACnC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAa;IAE1C,YAAY,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,UAAU,EAGvE;IAEQ,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAUvC;CACD","sourcesContent":["import { Box } from \"@greppleai/grip-tui\";\nimport { type ThemeColor, theme } from \"../theme/theme.ts\";\n\n/** Message card with internal padding, an optional one-cell stripe, and no trailing spaces. */\nexport class MessageCard extends Box {\n\tprivate readonly stripeColor?: ThemeColor;\n\n\tconstructor(paddingX: number, paddingY: number, stripeColor?: ThemeColor) {\n\t\tsuper(paddingX, paddingY);\n\t\tthis.stripeColor = stripeColor;\n\t}\n\n\toverride render(width: number): string[] {\n\t\tif (!this.stripeColor) return super.render(width).map((line) => line.trimEnd());\n\t\tif (width < 1) return [];\n\n\t\tconst marker = theme.bgFromFg(this.stripeColor, \" \");\n\t\treturn super.render(Math.max(1, width - 2)).map((line) => {\n\t\t\tif (width <= 2) return marker;\n\t\t\tconst content = line.trimEnd();\n\t\t\treturn content ? `${marker} ${content}` : marker;\n\t\t});\n\t}\n}\n"]}
1
+ {"version":3,"file":"message-card.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/message-card.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,KAAK,UAAU,EAAS,MAAM,mBAAmB,CAAC;AAE3D,+FAA+F;AAC/F,qBAAa,WAAY,SAAQ,GAAG;IACnC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAa;IAE1C,YAAY,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,UAAU,EAGvE;IAEQ,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAUvC;CACD"}
@@ -2,7 +2,6 @@ import { Box } from "@greppleai/grip-tui";
2
2
  import { theme } from "../theme/theme.js";
3
3
  /** Message card with internal padding, an optional one-cell stripe, and no trailing spaces. */
4
4
  export class MessageCard extends Box {
5
- stripeColor;
6
5
  constructor(paddingX, paddingY, stripeColor) {
7
6
  super(paddingX, paddingY);
8
7
  this.stripeColor = stripeColor;
@@ -1 +1 @@
1
- {"version":3,"file":"message-card.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/message-card.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAmB,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE3D,+FAA+F;AAC/F,MAAM,OAAO,WAAY,SAAQ,GAAG;IAClB,WAAW,CAAc;IAE1C,YAAY,QAAgB,EAAE,QAAgB,EAAE,WAAwB,EAAE;QACzE,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC1B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IAAA,CAC/B;IAEQ,MAAM,CAAC,KAAa,EAAY;QACxC,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QAChF,IAAI,KAAK,GAAG,CAAC;YAAE,OAAO,EAAE,CAAC;QAEzB,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QACrD,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YACzD,IAAI,KAAK,IAAI,CAAC;gBAAE,OAAO,MAAM,CAAC;YAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC/B,OAAO,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;QAAA,CACjD,CAAC,CAAC;IAAA,CACH;CACD","sourcesContent":["import { Box } from \"@greppleai/grip-tui\";\nimport { type ThemeColor, theme } from \"../theme/theme.ts\";\n\n/** Message card with internal padding, an optional one-cell stripe, and no trailing spaces. */\nexport class MessageCard extends Box {\n\tprivate readonly stripeColor?: ThemeColor;\n\n\tconstructor(paddingX: number, paddingY: number, stripeColor?: ThemeColor) {\n\t\tsuper(paddingX, paddingY);\n\t\tthis.stripeColor = stripeColor;\n\t}\n\n\toverride render(width: number): string[] {\n\t\tif (!this.stripeColor) return super.render(width).map((line) => line.trimEnd());\n\t\tif (width < 1) return [];\n\n\t\tconst marker = theme.bgFromFg(this.stripeColor, \" \");\n\t\treturn super.render(Math.max(1, width - 2)).map((line) => {\n\t\t\tif (width <= 2) return marker;\n\t\t\tconst content = line.trimEnd();\n\t\t\treturn content ? `${marker} ${content}` : marker;\n\t\t});\n\t}\n}\n"]}
1
+ {"version":3,"file":"message-card.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/message-card.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAmB,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE3D,+FAA+F;AAC/F,MAAM,OAAO,WAAY,SAAQ,GAAG;IAGnC,YAAY,QAAgB,EAAE,QAAgB,EAAE,WAAwB;QACvE,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC1B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IAChC,CAAC;IAEQ,MAAM,CAAC,KAAa;QAC5B,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QAChF,IAAI,KAAK,GAAG,CAAC;YAAE,OAAO,EAAE,CAAC;QAEzB,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QACrD,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACxD,IAAI,KAAK,IAAI,CAAC;gBAAE,OAAO,MAAM,CAAC;YAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC/B,OAAO,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;QAClD,CAAC,CAAC,CAAC;IACJ,CAAC;CACD","sourcesContent":["import { Box } from \"@greppleai/grip-tui\";\nimport { type ThemeColor, theme } from \"../theme/theme.ts\";\n\n/** Message card with internal padding, an optional one-cell stripe, and no trailing spaces. */\nexport class MessageCard extends Box {\n\tprivate readonly stripeColor?: ThemeColor;\n\n\tconstructor(paddingX: number, paddingY: number, stripeColor?: ThemeColor) {\n\t\tsuper(paddingX, paddingY);\n\t\tthis.stripeColor = stripeColor;\n\t}\n\n\toverride render(width: number): string[] {\n\t\tif (!this.stripeColor) return super.render(width).map((line) => line.trimEnd());\n\t\tif (width < 1) return [];\n\n\t\tconst marker = theme.bgFromFg(this.stripeColor, \" \");\n\t\treturn super.render(Math.max(1, width - 2)).map((line) => {\n\t\t\tif (width <= 2) return marker;\n\t\t\tconst content = line.trimEnd();\n\t\t\treturn content ? `${marker} ${content}` : marker;\n\t\t});\n\t}\n}\n"]}
@@ -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,GAAG,EAAE,KAAK,KAAK,EAAkB,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EACN,SAAS,EACT,KAAK,SAAS,EAGd,KAAK,EAGL,KAAK,GAAG,EAER,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAWzE,UAAU,eAAe;IACxB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAWD,gFAAgF;AAChF,qBAAa,sBAAuB,SAAQ,SAAU,YAAW,SAAS;IACzE,OAAO,CAAC,WAAW,CAAQ;IAC3B,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,SAAS,CAAsB;IACvC,OAAO,CAAC,iBAAiB,CAAsB;IAC/C,OAAO,CAAC,gBAAgB,CAA6B;IACrD,OAAO,CAAC,aAAa,CAAM;IAC3B,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,YAAY,CAAyB;IAC7C,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,gBAAgB,CAA8B;IACtD,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,SAAS,CAAO;IACxB,OAAO,CAAC,cAAc,CAAO;IAC7B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;IAEzC,YACC,GAAG,EAAE,GAAG,EACR,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,cAAc,UAAO,EA+BrB;YAEa,UAAU;IAwCxB,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,WAAW;IAoBnB,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,YAAY;IAuBpB,OAAO,CAAC,UAAU;IA4BlB,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,WAAW;IAIV,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAMvC;IAED,OAAO,CAAC,gBAAgB;IAexB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,gBAAgB;IAoBxB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CA8BjC;IAED,cAAc,IAAI,KAAK,CAEtB;CACD","sourcesContent":["import { type Api, type Model, modelsAreEqual } from \"@greppleai/grip-ai\";\nimport {\n\tContainer,\n\ttype Focusable,\n\tfuzzyFilter,\n\tgetKeybindings,\n\tInput,\n\tSpacer,\n\tText,\n\ttype TUI,\n\ttruncateToWidth,\n} from \"@greppleai/grip-tui\";\nimport type { ModelRegistry } from \"../../../core/model-registry.ts\";\nimport type { SettingsManager } from \"../../../core/settings-manager.ts\";\nimport { theme } from \"../theme/theme.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\nimport { keyHint } from \"./keybinding-hints.ts\";\n\ninterface ModelItem {\n\tprovider: string;\n\tid: string;\n\tmodel: Model<Api>;\n}\n\ninterface ScopedModelItem {\n\tmodel: Model<Api>;\n\tthinkingLevel?: string;\n}\n\ninterface ProviderItem {\n\tid: string;\n\tname: string;\n\tmodels: ModelItem[];\n}\n\ntype ModelScope = \"all\" | \"scoped\";\ntype PickerView = \"providers\" | \"models\" | \"search\";\n\n/** Native provider/model navigation, with a global model-search entry point. */\nexport class ModelSelectorComponent extends Container implements Focusable {\n\tprivate searchInput: Input;\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 providers: ProviderItem[] = [];\n\tprivate filteredProviders: ProviderItem[] = [];\n\tprivate selectedProvider: ProviderItem | null = null;\n\tprivate providerQuery = \"\";\n\tprivate providerIndex = 0;\n\tprivate view: PickerView;\n\tprivate selectedIndex = 0;\n\tprivate currentModel: Model<Api> | undefined;\n\tprivate settingsManager: SettingsManager;\n\tprivate modelRegistry: ModelRegistry;\n\tprivate onSelectCallback: (model: Model<Api>) => void;\n\tprivate onCancelCallback: () => void;\n\tprivate errorMessage: string | undefined;\n\tprivate loading = true;\n\tprivate listWidth = 80;\n\tprivate tui: TUI;\n\tprivate scopedModels: ReadonlyArray<ScopedModelItem>;\n\tprivate scope: ModelScope;\n\tprivate scopeText: Text;\n\tprivate navigationText: Text;\n\tprivate readonly persistDefault: boolean;\n\n\tconstructor(\n\t\ttui: TUI,\n\t\tcurrentModel: Model<Api> | undefined,\n\t\tsettingsManager: SettingsManager,\n\t\tmodelRegistry: ModelRegistry,\n\t\tscopedModels: ReadonlyArray<ScopedModelItem>,\n\t\tonSelect: (model: Model<Api>) => void,\n\t\tonCancel: () => void,\n\t\tinitialSearchInput?: string,\n\t\tpersistDefault = true,\n\t) {\n\t\tsuper();\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 ? \"scoped\" : \"all\";\n\t\tthis.view = initialSearchInput ? \"search\" : \"providers\";\n\t\tthis.onSelectCallback = onSelect;\n\t\tthis.onCancelCallback = onCancel;\n\t\tthis.persistDefault = persistDefault;\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.scopeText = new Text(\"\", 0, 0);\n\t\tthis.addChild(this.scopeText);\n\t\tthis.navigationText = new Text(\"\", 0, 0);\n\t\tthis.addChild(this.navigationText);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.searchInput = new Input();\n\t\tthis.searchInput.setValue(initialSearchInput ?? \"\");\n\t\tthis.searchInput.onSubmit = () => this.confirmSelection();\n\t\tthis.addChild(this.searchInput);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.listContainer = new Container();\n\t\tthis.addChild(this.listContainer);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.updateList();\n\t\tvoid this.loadModels();\n\t}\n\n\tprivate async loadModels(): Promise<void> {\n\t\ttry {\n\t\t\t// Refresh without introducing provider/network validation.\n\t\t\tthis.modelRegistry.refresh();\n\t\t\tthis.errorMessage = this.modelRegistry.getError();\n\t\t\tconst available = await this.modelRegistry.getAvailable();\n\t\t\tthis.allModels = available.map((model) => ({ provider: model.provider, id: model.id, model }));\n\t\t\tthis.allModels.sort((a, b) => {\n\t\t\t\tconst aCurrent = modelsAreEqual(this.currentModel, a.model);\n\t\t\t\tconst bCurrent = modelsAreEqual(this.currentModel, b.model);\n\t\t\t\tif (aCurrent !== bCurrent) return aCurrent ? -1 : 1;\n\t\t\t\treturn a.provider.localeCompare(b.provider) || a.id.localeCompare(b.id);\n\t\t\t});\n\t\t\tconst registered = new Map<string, Map<string, Model<Api>>>();\n\t\t\tfor (const model of this.modelRegistry.getAll()) {\n\t\t\t\tlet models = registered.get(model.provider);\n\t\t\t\tif (!models) {\n\t\t\t\t\tmodels = new Map();\n\t\t\t\t\tregistered.set(model.provider, models);\n\t\t\t\t}\n\t\t\t\tif (!models.has(model.id)) models.set(model.id, model);\n\t\t\t}\n\t\t\t// Keep scoped order, reconciling stale instances after registry refresh.\n\t\t\tthis.scopedModelItems = this.scopedModels.map(({ model }) => ({\n\t\t\t\tprovider: model.provider,\n\t\t\t\tid: model.id,\n\t\t\t\tmodel: registered.get(model.provider)?.get(model.id) ?? model,\n\t\t\t}));\n\t\t} catch (error) {\n\t\t\tthis.allModels = [];\n\t\t\tthis.scopedModelItems = [];\n\t\t\tthis.errorMessage = error instanceof Error ? error.message : String(error);\n\t\t}\n\t\tthis.loading = false;\n\t\tthis.rebuildProviders();\n\t\tthis.selectCurrent();\n\t\tthis.filterItems(this.searchInput.getValue());\n\t\tthis.tui.requestRender();\n\t}\n\n\tprivate rebuildProviders(): void {\n\t\tthis.activeModels = this.scope === \"scoped\" ? this.scopedModelItems : this.allModels;\n\t\tconst groups = new Map<string, ProviderItem>();\n\t\tfor (const item of this.activeModels) {\n\t\t\tlet provider = groups.get(item.provider);\n\t\t\tif (!provider) {\n\t\t\t\tprovider = {\n\t\t\t\t\tid: item.provider,\n\t\t\t\t\tname: this.modelRegistry.getProviderDisplayName(item.provider),\n\t\t\t\t\tmodels: [],\n\t\t\t\t};\n\t\t\t\tgroups.set(item.provider, provider);\n\t\t\t}\n\t\t\tprovider.models.push(item);\n\t\t}\n\t\tthis.providers = [...groups.values()].sort((a, b) => a.name.localeCompare(b.name) || a.id.localeCompare(b.id));\n\t}\n\n\tprivate selectCurrent(): void {\n\t\tconst index =\n\t\t\tthis.view === \"providers\"\n\t\t\t\t? this.providers.findIndex((item) => item.id === this.currentModel?.provider)\n\t\t\t\t: this.getModelItems().findIndex((item) => modelsAreEqual(this.currentModel, item.model));\n\t\tthis.selectedIndex = Math.max(0, index);\n\t}\n\n\tprivate getModelItems(): ModelItem[] {\n\t\treturn this.view === \"models\" ? (this.selectedProvider?.models ?? []) : this.activeModels;\n\t}\n\n\tprivate filterItems(query: string): void {\n\t\tif (this.view === \"providers\") {\n\t\t\tthis.filteredProviders = query\n\t\t\t\t? fuzzyFilter(this.providers, query, ({ id, name }) => `${name} ${id}`)\n\t\t\t\t: this.providers;\n\t\t} else {\n\t\t\tconst items = this.getModelItems();\n\t\t\tthis.filteredModels = query\n\t\t\t\t? fuzzyFilter(\n\t\t\t\t\t\titems,\n\t\t\t\t\t\tquery,\n\t\t\t\t\t\t({ id, provider, model }) => `${id} ${provider} ${provider}/${id} ${model.name}`,\n\t\t\t\t\t)\n\t\t\t\t: items;\n\t\t}\n\t\t// Query edits select the best match; clearing only clamps the position (7209).\n\t\tthis.selectedIndex = query ? 0 : Math.min(this.selectedIndex, Math.max(0, this.itemCount() - 1));\n\t\tthis.updateList();\n\t}\n\n\tprivate itemCount(): number {\n\t\treturn this.view === \"providers\" ? this.filteredProviders.length : this.filteredModels.length;\n\t}\n\n\tprivate updateHeader(): void {\n\t\tconst all = this.scope === \"all\" ? theme.fg(\"accent\", \"all\") : theme.fg(\"muted\", \"all\");\n\t\tconst scoped = this.scope === \"scoped\" ? theme.fg(\"accent\", \"scoped\") : theme.fg(\"muted\", \"scoped\");\n\t\tconst scopeHint =\n\t\t\tthis.scopedModels.length > 0 ? ` · ${keyHint(\"tui.input.tab\", \"scope\")} (${all}/${scoped})` : \"\";\n\t\tconst title =\n\t\t\tthis.view === \"providers\"\n\t\t\t\t? \"Providers\"\n\t\t\t\t: this.view === \"search\"\n\t\t\t\t\t? \"Search all providers\"\n\t\t\t\t\t: `${this.selectedProvider?.name} [${this.selectedProvider?.id}]`;\n\t\tthis.scopeText.setText(theme.fg(\"muted\", title) + scopeHint);\n\t\tthis.navigationText.setText(\n\t\t\tkeyHint(\"tui.select.up\", \"up\") +\n\t\t\t\t\" · \" +\n\t\t\t\tkeyHint(\"tui.select.down\", \"down\") +\n\t\t\t\t\" · \" +\n\t\t\t\tkeyHint(\"tui.select.confirm\", this.view === \"providers\" ? \"models\" : \"select\") +\n\t\t\t\t\" · \" +\n\t\t\t\tkeyHint(\"tui.select.cancel\", this.view === \"models\" ? \"providers\" : \"cancel\"),\n\t\t);\n\t}\n\n\tprivate updateList(): void {\n\t\tthis.updateHeader();\n\t\tthis.listContainer.clear();\n\t\tconst count = this.itemCount();\n\t\tconst maxVisible = 10;\n\t\tconst start = Math.max(0, Math.min(this.selectedIndex - Math.floor(maxVisible / 2), count - maxVisible));\n\t\tconst end = Math.min(start + maxVisible, count);\n\t\tfor (let i = start; i < end; i++) {\n\t\t\tlet label: string;\n\t\t\tlet current: boolean;\n\t\t\tif (this.view === \"providers\") {\n\t\t\t\tconst item = this.filteredProviders[i];\n\t\t\t\tlabel = `${item.name} [${item.id}] (${item.models.length} models)`;\n\t\t\t\tcurrent = item.id === this.currentModel?.provider;\n\t\t\t} else {\n\t\t\t\tconst item = this.filteredModels[i];\n\t\t\t\tlabel = `${item.id} [${item.provider}]`;\n\t\t\t\tcurrent = modelsAreEqual(this.currentModel, item.model);\n\t\t\t}\n\t\t\tconst selected = i === this.selectedIndex;\n\t\t\tconst prefix = selected ? theme.fg(\"accent\", \"→ \") : \" \";\n\t\t\tconst marker = current ? theme.fg(\"success\", \" ✓\") : \"\";\n\t\t\tthis.addListLine(prefix + (selected ? theme.fg(\"accent\", label) : label) + marker);\n\t\t}\n\t\tif (start > 0 || end < count) this.addListLine(theme.fg(\"muted\", ` (${this.selectedIndex + 1}/${count})`));\n\t\tthis.appendListStatus(count);\n\t}\n\n\tprivate appendListStatus(count: number): void {\n\t\tif (this.loading) {\n\t\t\tthis.addListLine(theme.fg(\"muted\", \" Loading models…\"));\n\t\t} else if (count === 0) {\n\t\t\tconst empty =\n\t\t\t\tthis.view === \"providers\" ? \"No matching providers. Use /login to add providers.\" : \"No matching models\";\n\t\t\tthis.addListLine(theme.fg(\"muted\", ` ${empty}`));\n\t\t} else if (this.view !== \"providers\") {\n\t\t\tthis.listContainer.addChild(new Spacer(1));\n\t\t\tthis.addListLine(theme.fg(\"muted\", ` Model Name: ${this.filteredModels[this.selectedIndex].model.name}`));\n\t\t}\n\t\tif (this.errorMessage) {\n\t\t\tfor (const line of this.errorMessage.split(\"\\n\")) this.addListLine(theme.fg(\"error\", line));\n\t\t}\n\t}\n\n\tprivate addListLine(line: string): void {\n\t\tthis.listContainer.addChild(new Text(truncateToWidth(line, this.listWidth), 0, 0));\n\t}\n\n\toverride render(width: number): string[] {\n\t\tif (this.listWidth !== width) {\n\t\t\tthis.listWidth = width;\n\t\t\tthis.updateList();\n\t\t}\n\t\treturn super.render(width);\n\t}\n\n\tprivate toggleModelScope(): void {\n\t\tif (this.scopedModels.length === 0) return;\n\t\tthis.scope = this.scope === \"all\" ? \"scoped\" : \"all\";\n\t\tif (this.view !== \"search\") {\n\t\t\tthis.view = \"providers\";\n\t\t\tthis.selectedProvider = null;\n\t\t\tthis.providerQuery = \"\";\n\t\t\tthis.providerIndex = 0;\n\t\t\tthis.searchInput.setValue(\"\");\n\t\t}\n\t\tthis.rebuildProviders();\n\t\tthis.selectCurrent();\n\t\tthis.filterItems(this.searchInput.getValue());\n\t}\n\n\tprivate moveSelection(delta: number): void {\n\t\tconst count = this.itemCount();\n\t\tif (count === 0) return;\n\t\tthis.selectedIndex = (this.selectedIndex + delta + count) % count;\n\t\tthis.updateList();\n\t}\n\n\tprivate confirmSelection(): void {\n\t\tif (this.loading) return;\n\t\tif (this.view === \"providers\") {\n\t\t\tconst provider = this.filteredProviders[this.selectedIndex];\n\t\t\tif (!provider) return;\n\t\t\tthis.providerQuery = this.searchInput.getValue();\n\t\t\tthis.providerIndex = this.selectedIndex;\n\t\t\tthis.selectedProvider = provider;\n\t\t\tthis.view = \"models\";\n\t\t\tthis.searchInput.setValue(\"\");\n\t\t\tthis.selectCurrent();\n\t\t\tthis.filterItems(\"\");\n\t\t\treturn;\n\t\t}\n\t\tconst item = this.filteredModels[this.selectedIndex];\n\t\tif (!item) return;\n\t\tif (this.persistDefault) this.settingsManager.setDefaultModelAndProvider(item.provider, item.id);\n\t\tthis.onSelectCallback(item.model);\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\tthis.toggleModelScope();\n\t\t} else if (kb.matches(keyData, \"tui.select.up\")) {\n\t\t\tthis.moveSelection(-1);\n\t\t} else if (kb.matches(keyData, \"tui.select.down\")) {\n\t\t\tthis.moveSelection(1);\n\t\t} else if (kb.matches(keyData, \"tui.select.pageUp\")) {\n\t\t\tthis.moveSelection(-Math.min(10, Math.max(0, this.itemCount() - 1)));\n\t\t} else if (kb.matches(keyData, \"tui.select.pageDown\")) {\n\t\t\tthis.moveSelection(Math.min(10, Math.max(0, this.itemCount() - 1)));\n\t\t} else if (kb.matches(keyData, \"tui.select.confirm\")) {\n\t\t\tthis.confirmSelection();\n\t\t} else if (kb.matches(keyData, \"tui.select.cancel\")) {\n\t\t\tif (this.view === \"models\") {\n\t\t\t\tthis.view = \"providers\";\n\t\t\t\tthis.selectedProvider = null;\n\t\t\t\tthis.searchInput.setValue(this.providerQuery);\n\t\t\t\tthis.filterItems(this.providerQuery);\n\t\t\t\tthis.selectedIndex = Math.min(this.providerIndex, Math.max(0, this.itemCount() - 1));\n\t\t\t\tthis.updateList();\n\t\t\t} else {\n\t\t\t\tthis.onCancelCallback();\n\t\t\t}\n\t\t} else {\n\t\t\tconst query = this.searchInput.getValue();\n\t\t\tthis.searchInput.handleInput(keyData);\n\t\t\tif (query !== this.searchInput.getValue()) this.filterItems(this.searchInput.getValue());\n\t\t}\n\t}\n\n\tgetSearchInput(): Input {\n\t\treturn this.searchInput;\n\t}\n}\n"]}
1
+ {"version":3,"file":"model-selector.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/model-selector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,KAAK,EAAkB,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EACN,SAAS,EACT,KAAK,SAAS,EAGd,KAAK,EAGL,KAAK,GAAG,EAER,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAWzE,UAAU,eAAe;IACxB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAWD,gFAAgF;AAChF,qBAAa,sBAAuB,SAAQ,SAAU,YAAW,SAAS;IACzE,OAAO,CAAC,WAAW,CAAQ;IAC3B,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,SAAS,CAAsB;IACvC,OAAO,CAAC,iBAAiB,CAAsB;IAC/C,OAAO,CAAC,gBAAgB,CAA6B;IACrD,OAAO,CAAC,aAAa,CAAM;IAC3B,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,YAAY,CAAyB;IAC7C,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,gBAAgB,CAA8B;IACtD,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,SAAS,CAAO;IACxB,OAAO,CAAC,cAAc,CAAO;IAC7B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;IAEzC,YACC,GAAG,EAAE,GAAG,EACR,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,cAAc,UAAO,EA+BrB;YAEa,UAAU;IAwCxB,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,WAAW;IAoBnB,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,YAAY;IAuBpB,OAAO,CAAC,UAAU;IA4BlB,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,WAAW;IAIV,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAMvC;IAED,OAAO,CAAC,gBAAgB;IAexB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,gBAAgB;IAoBxB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CA8BjC;IAED,cAAc,IAAI,KAAK,CAEtB;CACD"}
@@ -5,8 +5,6 @@ import { DynamicBorder } from "./dynamic-border.js";
5
5
  import { keyHint } from "./keybinding-hints.js";
6
6
  /** Native provider/model navigation, with a global model-search entry point. */
7
7
  export class ModelSelectorComponent extends Container {
8
- searchInput;
9
- _focused = false;
10
8
  get focused() {
11
9
  return this._focused;
12
10
  }
@@ -14,34 +12,21 @@ export class ModelSelectorComponent extends Container {
14
12
  this._focused = value;
15
13
  this.searchInput.focused = value;
16
14
  }
17
- listContainer;
18
- allModels = [];
19
- scopedModelItems = [];
20
- activeModels = [];
21
- filteredModels = [];
22
- providers = [];
23
- filteredProviders = [];
24
- selectedProvider = null;
25
- providerQuery = "";
26
- providerIndex = 0;
27
- view;
28
- selectedIndex = 0;
29
- currentModel;
30
- settingsManager;
31
- modelRegistry;
32
- onSelectCallback;
33
- onCancelCallback;
34
- errorMessage;
35
- loading = true;
36
- listWidth = 80;
37
- tui;
38
- scopedModels;
39
- scope;
40
- scopeText;
41
- navigationText;
42
- persistDefault;
43
15
  constructor(tui, currentModel, settingsManager, modelRegistry, scopedModels, onSelect, onCancel, initialSearchInput, persistDefault = true) {
44
16
  super();
17
+ this._focused = false;
18
+ this.allModels = [];
19
+ this.scopedModelItems = [];
20
+ this.activeModels = [];
21
+ this.filteredModels = [];
22
+ this.providers = [];
23
+ this.filteredProviders = [];
24
+ this.selectedProvider = null;
25
+ this.providerQuery = "";
26
+ this.providerIndex = 0;
27
+ this.selectedIndex = 0;
28
+ this.loading = true;
29
+ this.listWidth = 80;
45
30
  this.tui = tui;
46
31
  this.currentModel = currentModel;
47
32
  this.settingsManager = settingsManager;
@@ -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 Api, type Model, modelsAreEqual } from \"@greppleai/grip-ai\";\nimport {\n\tContainer,\n\ttype Focusable,\n\tfuzzyFilter,\n\tgetKeybindings,\n\tInput,\n\tSpacer,\n\tText,\n\ttype TUI,\n\ttruncateToWidth,\n} from \"@greppleai/grip-tui\";\nimport type { ModelRegistry } from \"../../../core/model-registry.ts\";\nimport type { SettingsManager } from \"../../../core/settings-manager.ts\";\nimport { theme } from \"../theme/theme.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\nimport { keyHint } from \"./keybinding-hints.ts\";\n\ninterface ModelItem {\n\tprovider: string;\n\tid: string;\n\tmodel: Model<Api>;\n}\n\ninterface ScopedModelItem {\n\tmodel: Model<Api>;\n\tthinkingLevel?: string;\n}\n\ninterface ProviderItem {\n\tid: string;\n\tname: string;\n\tmodels: ModelItem[];\n}\n\ntype ModelScope = \"all\" | \"scoped\";\ntype PickerView = \"providers\" | \"models\" | \"search\";\n\n/** Native provider/model navigation, with a global model-search entry point. */\nexport class ModelSelectorComponent extends Container implements Focusable {\n\tprivate searchInput: Input;\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 providers: ProviderItem[] = [];\n\tprivate filteredProviders: ProviderItem[] = [];\n\tprivate selectedProvider: ProviderItem | null = null;\n\tprivate providerQuery = \"\";\n\tprivate providerIndex = 0;\n\tprivate view: PickerView;\n\tprivate selectedIndex = 0;\n\tprivate currentModel: Model<Api> | undefined;\n\tprivate settingsManager: SettingsManager;\n\tprivate modelRegistry: ModelRegistry;\n\tprivate onSelectCallback: (model: Model<Api>) => void;\n\tprivate onCancelCallback: () => void;\n\tprivate errorMessage: string | undefined;\n\tprivate loading = true;\n\tprivate listWidth = 80;\n\tprivate tui: TUI;\n\tprivate scopedModels: ReadonlyArray<ScopedModelItem>;\n\tprivate scope: ModelScope;\n\tprivate scopeText: Text;\n\tprivate navigationText: Text;\n\tprivate readonly persistDefault: boolean;\n\n\tconstructor(\n\t\ttui: TUI,\n\t\tcurrentModel: Model<Api> | undefined,\n\t\tsettingsManager: SettingsManager,\n\t\tmodelRegistry: ModelRegistry,\n\t\tscopedModels: ReadonlyArray<ScopedModelItem>,\n\t\tonSelect: (model: Model<Api>) => void,\n\t\tonCancel: () => void,\n\t\tinitialSearchInput?: string,\n\t\tpersistDefault = true,\n\t) {\n\t\tsuper();\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 ? \"scoped\" : \"all\";\n\t\tthis.view = initialSearchInput ? \"search\" : \"providers\";\n\t\tthis.onSelectCallback = onSelect;\n\t\tthis.onCancelCallback = onCancel;\n\t\tthis.persistDefault = persistDefault;\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.scopeText = new Text(\"\", 0, 0);\n\t\tthis.addChild(this.scopeText);\n\t\tthis.navigationText = new Text(\"\", 0, 0);\n\t\tthis.addChild(this.navigationText);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.searchInput = new Input();\n\t\tthis.searchInput.setValue(initialSearchInput ?? \"\");\n\t\tthis.searchInput.onSubmit = () => this.confirmSelection();\n\t\tthis.addChild(this.searchInput);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.listContainer = new Container();\n\t\tthis.addChild(this.listContainer);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.updateList();\n\t\tvoid this.loadModels();\n\t}\n\n\tprivate async loadModels(): Promise<void> {\n\t\ttry {\n\t\t\t// Refresh without introducing provider/network validation.\n\t\t\tthis.modelRegistry.refresh();\n\t\t\tthis.errorMessage = this.modelRegistry.getError();\n\t\t\tconst available = await this.modelRegistry.getAvailable();\n\t\t\tthis.allModels = available.map((model) => ({ provider: model.provider, id: model.id, model }));\n\t\t\tthis.allModels.sort((a, b) => {\n\t\t\t\tconst aCurrent = modelsAreEqual(this.currentModel, a.model);\n\t\t\t\tconst bCurrent = modelsAreEqual(this.currentModel, b.model);\n\t\t\t\tif (aCurrent !== bCurrent) return aCurrent ? -1 : 1;\n\t\t\t\treturn a.provider.localeCompare(b.provider) || a.id.localeCompare(b.id);\n\t\t\t});\n\t\t\tconst registered = new Map<string, Map<string, Model<Api>>>();\n\t\t\tfor (const model of this.modelRegistry.getAll()) {\n\t\t\t\tlet models = registered.get(model.provider);\n\t\t\t\tif (!models) {\n\t\t\t\t\tmodels = new Map();\n\t\t\t\t\tregistered.set(model.provider, models);\n\t\t\t\t}\n\t\t\t\tif (!models.has(model.id)) models.set(model.id, model);\n\t\t\t}\n\t\t\t// Keep scoped order, reconciling stale instances after registry refresh.\n\t\t\tthis.scopedModelItems = this.scopedModels.map(({ model }) => ({\n\t\t\t\tprovider: model.provider,\n\t\t\t\tid: model.id,\n\t\t\t\tmodel: registered.get(model.provider)?.get(model.id) ?? model,\n\t\t\t}));\n\t\t} catch (error) {\n\t\t\tthis.allModels = [];\n\t\t\tthis.scopedModelItems = [];\n\t\t\tthis.errorMessage = error instanceof Error ? error.message : String(error);\n\t\t}\n\t\tthis.loading = false;\n\t\tthis.rebuildProviders();\n\t\tthis.selectCurrent();\n\t\tthis.filterItems(this.searchInput.getValue());\n\t\tthis.tui.requestRender();\n\t}\n\n\tprivate rebuildProviders(): void {\n\t\tthis.activeModels = this.scope === \"scoped\" ? this.scopedModelItems : this.allModels;\n\t\tconst groups = new Map<string, ProviderItem>();\n\t\tfor (const item of this.activeModels) {\n\t\t\tlet provider = groups.get(item.provider);\n\t\t\tif (!provider) {\n\t\t\t\tprovider = {\n\t\t\t\t\tid: item.provider,\n\t\t\t\t\tname: this.modelRegistry.getProviderDisplayName(item.provider),\n\t\t\t\t\tmodels: [],\n\t\t\t\t};\n\t\t\t\tgroups.set(item.provider, provider);\n\t\t\t}\n\t\t\tprovider.models.push(item);\n\t\t}\n\t\tthis.providers = [...groups.values()].sort((a, b) => a.name.localeCompare(b.name) || a.id.localeCompare(b.id));\n\t}\n\n\tprivate selectCurrent(): void {\n\t\tconst index =\n\t\t\tthis.view === \"providers\"\n\t\t\t\t? this.providers.findIndex((item) => item.id === this.currentModel?.provider)\n\t\t\t\t: this.getModelItems().findIndex((item) => modelsAreEqual(this.currentModel, item.model));\n\t\tthis.selectedIndex = Math.max(0, index);\n\t}\n\n\tprivate getModelItems(): ModelItem[] {\n\t\treturn this.view === \"models\" ? (this.selectedProvider?.models ?? []) : this.activeModels;\n\t}\n\n\tprivate filterItems(query: string): void {\n\t\tif (this.view === \"providers\") {\n\t\t\tthis.filteredProviders = query\n\t\t\t\t? fuzzyFilter(this.providers, query, ({ id, name }) => `${name} ${id}`)\n\t\t\t\t: this.providers;\n\t\t} else {\n\t\t\tconst items = this.getModelItems();\n\t\t\tthis.filteredModels = query\n\t\t\t\t? fuzzyFilter(\n\t\t\t\t\t\titems,\n\t\t\t\t\t\tquery,\n\t\t\t\t\t\t({ id, provider, model }) => `${id} ${provider} ${provider}/${id} ${model.name}`,\n\t\t\t\t\t)\n\t\t\t\t: items;\n\t\t}\n\t\t// Query edits select the best match; clearing only clamps the position (7209).\n\t\tthis.selectedIndex = query ? 0 : Math.min(this.selectedIndex, Math.max(0, this.itemCount() - 1));\n\t\tthis.updateList();\n\t}\n\n\tprivate itemCount(): number {\n\t\treturn this.view === \"providers\" ? this.filteredProviders.length : this.filteredModels.length;\n\t}\n\n\tprivate updateHeader(): void {\n\t\tconst all = this.scope === \"all\" ? theme.fg(\"accent\", \"all\") : theme.fg(\"muted\", \"all\");\n\t\tconst scoped = this.scope === \"scoped\" ? theme.fg(\"accent\", \"scoped\") : theme.fg(\"muted\", \"scoped\");\n\t\tconst scopeHint =\n\t\t\tthis.scopedModels.length > 0 ? ` · ${keyHint(\"tui.input.tab\", \"scope\")} (${all}/${scoped})` : \"\";\n\t\tconst title =\n\t\t\tthis.view === \"providers\"\n\t\t\t\t? \"Providers\"\n\t\t\t\t: this.view === \"search\"\n\t\t\t\t\t? \"Search all providers\"\n\t\t\t\t\t: `${this.selectedProvider?.name} [${this.selectedProvider?.id}]`;\n\t\tthis.scopeText.setText(theme.fg(\"muted\", title) + scopeHint);\n\t\tthis.navigationText.setText(\n\t\t\tkeyHint(\"tui.select.up\", \"up\") +\n\t\t\t\t\" · \" +\n\t\t\t\tkeyHint(\"tui.select.down\", \"down\") +\n\t\t\t\t\" · \" +\n\t\t\t\tkeyHint(\"tui.select.confirm\", this.view === \"providers\" ? \"models\" : \"select\") +\n\t\t\t\t\" · \" +\n\t\t\t\tkeyHint(\"tui.select.cancel\", this.view === \"models\" ? \"providers\" : \"cancel\"),\n\t\t);\n\t}\n\n\tprivate updateList(): void {\n\t\tthis.updateHeader();\n\t\tthis.listContainer.clear();\n\t\tconst count = this.itemCount();\n\t\tconst maxVisible = 10;\n\t\tconst start = Math.max(0, Math.min(this.selectedIndex - Math.floor(maxVisible / 2), count - maxVisible));\n\t\tconst end = Math.min(start + maxVisible, count);\n\t\tfor (let i = start; i < end; i++) {\n\t\t\tlet label: string;\n\t\t\tlet current: boolean;\n\t\t\tif (this.view === \"providers\") {\n\t\t\t\tconst item = this.filteredProviders[i];\n\t\t\t\tlabel = `${item.name} [${item.id}] (${item.models.length} models)`;\n\t\t\t\tcurrent = item.id === this.currentModel?.provider;\n\t\t\t} else {\n\t\t\t\tconst item = this.filteredModels[i];\n\t\t\t\tlabel = `${item.id} [${item.provider}]`;\n\t\t\t\tcurrent = modelsAreEqual(this.currentModel, item.model);\n\t\t\t}\n\t\t\tconst selected = i === this.selectedIndex;\n\t\t\tconst prefix = selected ? theme.fg(\"accent\", \"→ \") : \" \";\n\t\t\tconst marker = current ? theme.fg(\"success\", \" ✓\") : \"\";\n\t\t\tthis.addListLine(prefix + (selected ? theme.fg(\"accent\", label) : label) + marker);\n\t\t}\n\t\tif (start > 0 || end < count) this.addListLine(theme.fg(\"muted\", ` (${this.selectedIndex + 1}/${count})`));\n\t\tthis.appendListStatus(count);\n\t}\n\n\tprivate appendListStatus(count: number): void {\n\t\tif (this.loading) {\n\t\t\tthis.addListLine(theme.fg(\"muted\", \" Loading models…\"));\n\t\t} else if (count === 0) {\n\t\t\tconst empty =\n\t\t\t\tthis.view === \"providers\" ? \"No matching providers. Use /login to add providers.\" : \"No matching models\";\n\t\t\tthis.addListLine(theme.fg(\"muted\", ` ${empty}`));\n\t\t} else if (this.view !== \"providers\") {\n\t\t\tthis.listContainer.addChild(new Spacer(1));\n\t\t\tthis.addListLine(theme.fg(\"muted\", ` Model Name: ${this.filteredModels[this.selectedIndex].model.name}`));\n\t\t}\n\t\tif (this.errorMessage) {\n\t\t\tfor (const line of this.errorMessage.split(\"\\n\")) this.addListLine(theme.fg(\"error\", line));\n\t\t}\n\t}\n\n\tprivate addListLine(line: string): void {\n\t\tthis.listContainer.addChild(new Text(truncateToWidth(line, this.listWidth), 0, 0));\n\t}\n\n\toverride render(width: number): string[] {\n\t\tif (this.listWidth !== width) {\n\t\t\tthis.listWidth = width;\n\t\t\tthis.updateList();\n\t\t}\n\t\treturn super.render(width);\n\t}\n\n\tprivate toggleModelScope(): void {\n\t\tif (this.scopedModels.length === 0) return;\n\t\tthis.scope = this.scope === \"all\" ? \"scoped\" : \"all\";\n\t\tif (this.view !== \"search\") {\n\t\t\tthis.view = \"providers\";\n\t\t\tthis.selectedProvider = null;\n\t\t\tthis.providerQuery = \"\";\n\t\t\tthis.providerIndex = 0;\n\t\t\tthis.searchInput.setValue(\"\");\n\t\t}\n\t\tthis.rebuildProviders();\n\t\tthis.selectCurrent();\n\t\tthis.filterItems(this.searchInput.getValue());\n\t}\n\n\tprivate moveSelection(delta: number): void {\n\t\tconst count = this.itemCount();\n\t\tif (count === 0) return;\n\t\tthis.selectedIndex = (this.selectedIndex + delta + count) % count;\n\t\tthis.updateList();\n\t}\n\n\tprivate confirmSelection(): void {\n\t\tif (this.loading) return;\n\t\tif (this.view === \"providers\") {\n\t\t\tconst provider = this.filteredProviders[this.selectedIndex];\n\t\t\tif (!provider) return;\n\t\t\tthis.providerQuery = this.searchInput.getValue();\n\t\t\tthis.providerIndex = this.selectedIndex;\n\t\t\tthis.selectedProvider = provider;\n\t\t\tthis.view = \"models\";\n\t\t\tthis.searchInput.setValue(\"\");\n\t\t\tthis.selectCurrent();\n\t\t\tthis.filterItems(\"\");\n\t\t\treturn;\n\t\t}\n\t\tconst item = this.filteredModels[this.selectedIndex];\n\t\tif (!item) return;\n\t\tif (this.persistDefault) this.settingsManager.setDefaultModelAndProvider(item.provider, item.id);\n\t\tthis.onSelectCallback(item.model);\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\tthis.toggleModelScope();\n\t\t} else if (kb.matches(keyData, \"tui.select.up\")) {\n\t\t\tthis.moveSelection(-1);\n\t\t} else if (kb.matches(keyData, \"tui.select.down\")) {\n\t\t\tthis.moveSelection(1);\n\t\t} else if (kb.matches(keyData, \"tui.select.pageUp\")) {\n\t\t\tthis.moveSelection(-Math.min(10, Math.max(0, this.itemCount() - 1)));\n\t\t} else if (kb.matches(keyData, \"tui.select.pageDown\")) {\n\t\t\tthis.moveSelection(Math.min(10, Math.max(0, this.itemCount() - 1)));\n\t\t} else if (kb.matches(keyData, \"tui.select.confirm\")) {\n\t\t\tthis.confirmSelection();\n\t\t} else if (kb.matches(keyData, \"tui.select.cancel\")) {\n\t\t\tif (this.view === \"models\") {\n\t\t\t\tthis.view = \"providers\";\n\t\t\t\tthis.selectedProvider = null;\n\t\t\t\tthis.searchInput.setValue(this.providerQuery);\n\t\t\t\tthis.filterItems(this.providerQuery);\n\t\t\t\tthis.selectedIndex = Math.min(this.providerIndex, Math.max(0, this.itemCount() - 1));\n\t\t\t\tthis.updateList();\n\t\t\t} else {\n\t\t\t\tthis.onCancelCallback();\n\t\t\t}\n\t\t} else {\n\t\t\tconst query = this.searchInput.getValue();\n\t\t\tthis.searchInput.handleInput(keyData);\n\t\t\tif (query !== this.searchInput.getValue()) this.filterItems(this.searchInput.getValue());\n\t\t}\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 Api, type Model, modelsAreEqual } from \"@greppleai/grip-ai\";\nimport {\n\tContainer,\n\ttype Focusable,\n\tfuzzyFilter,\n\tgetKeybindings,\n\tInput,\n\tSpacer,\n\tText,\n\ttype TUI,\n\ttruncateToWidth,\n} from \"@greppleai/grip-tui\";\nimport type { ModelRegistry } from \"../../../core/model-registry.ts\";\nimport type { SettingsManager } from \"../../../core/settings-manager.ts\";\nimport { theme } from \"../theme/theme.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\nimport { keyHint } from \"./keybinding-hints.ts\";\n\ninterface ModelItem {\n\tprovider: string;\n\tid: string;\n\tmodel: Model<Api>;\n}\n\ninterface ScopedModelItem {\n\tmodel: Model<Api>;\n\tthinkingLevel?: string;\n}\n\ninterface ProviderItem {\n\tid: string;\n\tname: string;\n\tmodels: ModelItem[];\n}\n\ntype ModelScope = \"all\" | \"scoped\";\ntype PickerView = \"providers\" | \"models\" | \"search\";\n\n/** Native provider/model navigation, with a global model-search entry point. */\nexport class ModelSelectorComponent extends Container implements Focusable {\n\tprivate searchInput: Input;\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 providers: ProviderItem[] = [];\n\tprivate filteredProviders: ProviderItem[] = [];\n\tprivate selectedProvider: ProviderItem | null = null;\n\tprivate providerQuery = \"\";\n\tprivate providerIndex = 0;\n\tprivate view: PickerView;\n\tprivate selectedIndex = 0;\n\tprivate currentModel: Model<Api> | undefined;\n\tprivate settingsManager: SettingsManager;\n\tprivate modelRegistry: ModelRegistry;\n\tprivate onSelectCallback: (model: Model<Api>) => void;\n\tprivate onCancelCallback: () => void;\n\tprivate errorMessage: string | undefined;\n\tprivate loading = true;\n\tprivate listWidth = 80;\n\tprivate tui: TUI;\n\tprivate scopedModels: ReadonlyArray<ScopedModelItem>;\n\tprivate scope: ModelScope;\n\tprivate scopeText: Text;\n\tprivate navigationText: Text;\n\tprivate readonly persistDefault: boolean;\n\n\tconstructor(\n\t\ttui: TUI,\n\t\tcurrentModel: Model<Api> | undefined,\n\t\tsettingsManager: SettingsManager,\n\t\tmodelRegistry: ModelRegistry,\n\t\tscopedModels: ReadonlyArray<ScopedModelItem>,\n\t\tonSelect: (model: Model<Api>) => void,\n\t\tonCancel: () => void,\n\t\tinitialSearchInput?: string,\n\t\tpersistDefault = true,\n\t) {\n\t\tsuper();\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 ? \"scoped\" : \"all\";\n\t\tthis.view = initialSearchInput ? \"search\" : \"providers\";\n\t\tthis.onSelectCallback = onSelect;\n\t\tthis.onCancelCallback = onCancel;\n\t\tthis.persistDefault = persistDefault;\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.scopeText = new Text(\"\", 0, 0);\n\t\tthis.addChild(this.scopeText);\n\t\tthis.navigationText = new Text(\"\", 0, 0);\n\t\tthis.addChild(this.navigationText);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.searchInput = new Input();\n\t\tthis.searchInput.setValue(initialSearchInput ?? \"\");\n\t\tthis.searchInput.onSubmit = () => this.confirmSelection();\n\t\tthis.addChild(this.searchInput);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.listContainer = new Container();\n\t\tthis.addChild(this.listContainer);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.updateList();\n\t\tvoid this.loadModels();\n\t}\n\n\tprivate async loadModels(): Promise<void> {\n\t\ttry {\n\t\t\t// Refresh without introducing provider/network validation.\n\t\t\tthis.modelRegistry.refresh();\n\t\t\tthis.errorMessage = this.modelRegistry.getError();\n\t\t\tconst available = await this.modelRegistry.getAvailable();\n\t\t\tthis.allModels = available.map((model) => ({ provider: model.provider, id: model.id, model }));\n\t\t\tthis.allModels.sort((a, b) => {\n\t\t\t\tconst aCurrent = modelsAreEqual(this.currentModel, a.model);\n\t\t\t\tconst bCurrent = modelsAreEqual(this.currentModel, b.model);\n\t\t\t\tif (aCurrent !== bCurrent) return aCurrent ? -1 : 1;\n\t\t\t\treturn a.provider.localeCompare(b.provider) || a.id.localeCompare(b.id);\n\t\t\t});\n\t\t\tconst registered = new Map<string, Map<string, Model<Api>>>();\n\t\t\tfor (const model of this.modelRegistry.getAll()) {\n\t\t\t\tlet models = registered.get(model.provider);\n\t\t\t\tif (!models) {\n\t\t\t\t\tmodels = new Map();\n\t\t\t\t\tregistered.set(model.provider, models);\n\t\t\t\t}\n\t\t\t\tif (!models.has(model.id)) models.set(model.id, model);\n\t\t\t}\n\t\t\t// Keep scoped order, reconciling stale instances after registry refresh.\n\t\t\tthis.scopedModelItems = this.scopedModels.map(({ model }) => ({\n\t\t\t\tprovider: model.provider,\n\t\t\t\tid: model.id,\n\t\t\t\tmodel: registered.get(model.provider)?.get(model.id) ?? model,\n\t\t\t}));\n\t\t} catch (error) {\n\t\t\tthis.allModels = [];\n\t\t\tthis.scopedModelItems = [];\n\t\t\tthis.errorMessage = error instanceof Error ? error.message : String(error);\n\t\t}\n\t\tthis.loading = false;\n\t\tthis.rebuildProviders();\n\t\tthis.selectCurrent();\n\t\tthis.filterItems(this.searchInput.getValue());\n\t\tthis.tui.requestRender();\n\t}\n\n\tprivate rebuildProviders(): void {\n\t\tthis.activeModels = this.scope === \"scoped\" ? this.scopedModelItems : this.allModels;\n\t\tconst groups = new Map<string, ProviderItem>();\n\t\tfor (const item of this.activeModels) {\n\t\t\tlet provider = groups.get(item.provider);\n\t\t\tif (!provider) {\n\t\t\t\tprovider = {\n\t\t\t\t\tid: item.provider,\n\t\t\t\t\tname: this.modelRegistry.getProviderDisplayName(item.provider),\n\t\t\t\t\tmodels: [],\n\t\t\t\t};\n\t\t\t\tgroups.set(item.provider, provider);\n\t\t\t}\n\t\t\tprovider.models.push(item);\n\t\t}\n\t\tthis.providers = [...groups.values()].sort((a, b) => a.name.localeCompare(b.name) || a.id.localeCompare(b.id));\n\t}\n\n\tprivate selectCurrent(): void {\n\t\tconst index =\n\t\t\tthis.view === \"providers\"\n\t\t\t\t? this.providers.findIndex((item) => item.id === this.currentModel?.provider)\n\t\t\t\t: this.getModelItems().findIndex((item) => modelsAreEqual(this.currentModel, item.model));\n\t\tthis.selectedIndex = Math.max(0, index);\n\t}\n\n\tprivate getModelItems(): ModelItem[] {\n\t\treturn this.view === \"models\" ? (this.selectedProvider?.models ?? []) : this.activeModels;\n\t}\n\n\tprivate filterItems(query: string): void {\n\t\tif (this.view === \"providers\") {\n\t\t\tthis.filteredProviders = query\n\t\t\t\t? fuzzyFilter(this.providers, query, ({ id, name }) => `${name} ${id}`)\n\t\t\t\t: this.providers;\n\t\t} else {\n\t\t\tconst items = this.getModelItems();\n\t\t\tthis.filteredModels = query\n\t\t\t\t? fuzzyFilter(\n\t\t\t\t\t\titems,\n\t\t\t\t\t\tquery,\n\t\t\t\t\t\t({ id, provider, model }) => `${id} ${provider} ${provider}/${id} ${model.name}`,\n\t\t\t\t\t)\n\t\t\t\t: items;\n\t\t}\n\t\t// Query edits select the best match; clearing only clamps the position (7209).\n\t\tthis.selectedIndex = query ? 0 : Math.min(this.selectedIndex, Math.max(0, this.itemCount() - 1));\n\t\tthis.updateList();\n\t}\n\n\tprivate itemCount(): number {\n\t\treturn this.view === \"providers\" ? this.filteredProviders.length : this.filteredModels.length;\n\t}\n\n\tprivate updateHeader(): void {\n\t\tconst all = this.scope === \"all\" ? theme.fg(\"accent\", \"all\") : theme.fg(\"muted\", \"all\");\n\t\tconst scoped = this.scope === \"scoped\" ? theme.fg(\"accent\", \"scoped\") : theme.fg(\"muted\", \"scoped\");\n\t\tconst scopeHint =\n\t\t\tthis.scopedModels.length > 0 ? ` · ${keyHint(\"tui.input.tab\", \"scope\")} (${all}/${scoped})` : \"\";\n\t\tconst title =\n\t\t\tthis.view === \"providers\"\n\t\t\t\t? \"Providers\"\n\t\t\t\t: this.view === \"search\"\n\t\t\t\t\t? \"Search all providers\"\n\t\t\t\t\t: `${this.selectedProvider?.name} [${this.selectedProvider?.id}]`;\n\t\tthis.scopeText.setText(theme.fg(\"muted\", title) + scopeHint);\n\t\tthis.navigationText.setText(\n\t\t\tkeyHint(\"tui.select.up\", \"up\") +\n\t\t\t\t\" · \" +\n\t\t\t\tkeyHint(\"tui.select.down\", \"down\") +\n\t\t\t\t\" · \" +\n\t\t\t\tkeyHint(\"tui.select.confirm\", this.view === \"providers\" ? \"models\" : \"select\") +\n\t\t\t\t\" · \" +\n\t\t\t\tkeyHint(\"tui.select.cancel\", this.view === \"models\" ? \"providers\" : \"cancel\"),\n\t\t);\n\t}\n\n\tprivate updateList(): void {\n\t\tthis.updateHeader();\n\t\tthis.listContainer.clear();\n\t\tconst count = this.itemCount();\n\t\tconst maxVisible = 10;\n\t\tconst start = Math.max(0, Math.min(this.selectedIndex - Math.floor(maxVisible / 2), count - maxVisible));\n\t\tconst end = Math.min(start + maxVisible, count);\n\t\tfor (let i = start; i < end; i++) {\n\t\t\tlet label: string;\n\t\t\tlet current: boolean;\n\t\t\tif (this.view === \"providers\") {\n\t\t\t\tconst item = this.filteredProviders[i];\n\t\t\t\tlabel = `${item.name} [${item.id}] (${item.models.length} models)`;\n\t\t\t\tcurrent = item.id === this.currentModel?.provider;\n\t\t\t} else {\n\t\t\t\tconst item = this.filteredModels[i];\n\t\t\t\tlabel = `${item.id} [${item.provider}]`;\n\t\t\t\tcurrent = modelsAreEqual(this.currentModel, item.model);\n\t\t\t}\n\t\t\tconst selected = i === this.selectedIndex;\n\t\t\tconst prefix = selected ? theme.fg(\"accent\", \"→ \") : \" \";\n\t\t\tconst marker = current ? theme.fg(\"success\", \" ✓\") : \"\";\n\t\t\tthis.addListLine(prefix + (selected ? theme.fg(\"accent\", label) : label) + marker);\n\t\t}\n\t\tif (start > 0 || end < count) this.addListLine(theme.fg(\"muted\", ` (${this.selectedIndex + 1}/${count})`));\n\t\tthis.appendListStatus(count);\n\t}\n\n\tprivate appendListStatus(count: number): void {\n\t\tif (this.loading) {\n\t\t\tthis.addListLine(theme.fg(\"muted\", \" Loading models…\"));\n\t\t} else if (count === 0) {\n\t\t\tconst empty =\n\t\t\t\tthis.view === \"providers\" ? \"No matching providers. Use /login to add providers.\" : \"No matching models\";\n\t\t\tthis.addListLine(theme.fg(\"muted\", ` ${empty}`));\n\t\t} else if (this.view !== \"providers\") {\n\t\t\tthis.listContainer.addChild(new Spacer(1));\n\t\t\tthis.addListLine(theme.fg(\"muted\", ` Model Name: ${this.filteredModels[this.selectedIndex].model.name}`));\n\t\t}\n\t\tif (this.errorMessage) {\n\t\t\tfor (const line of this.errorMessage.split(\"\\n\")) this.addListLine(theme.fg(\"error\", line));\n\t\t}\n\t}\n\n\tprivate addListLine(line: string): void {\n\t\tthis.listContainer.addChild(new Text(truncateToWidth(line, this.listWidth), 0, 0));\n\t}\n\n\toverride render(width: number): string[] {\n\t\tif (this.listWidth !== width) {\n\t\t\tthis.listWidth = width;\n\t\t\tthis.updateList();\n\t\t}\n\t\treturn super.render(width);\n\t}\n\n\tprivate toggleModelScope(): void {\n\t\tif (this.scopedModels.length === 0) return;\n\t\tthis.scope = this.scope === \"all\" ? \"scoped\" : \"all\";\n\t\tif (this.view !== \"search\") {\n\t\t\tthis.view = \"providers\";\n\t\t\tthis.selectedProvider = null;\n\t\t\tthis.providerQuery = \"\";\n\t\t\tthis.providerIndex = 0;\n\t\t\tthis.searchInput.setValue(\"\");\n\t\t}\n\t\tthis.rebuildProviders();\n\t\tthis.selectCurrent();\n\t\tthis.filterItems(this.searchInput.getValue());\n\t}\n\n\tprivate moveSelection(delta: number): void {\n\t\tconst count = this.itemCount();\n\t\tif (count === 0) return;\n\t\tthis.selectedIndex = (this.selectedIndex + delta + count) % count;\n\t\tthis.updateList();\n\t}\n\n\tprivate confirmSelection(): void {\n\t\tif (this.loading) return;\n\t\tif (this.view === \"providers\") {\n\t\t\tconst provider = this.filteredProviders[this.selectedIndex];\n\t\t\tif (!provider) return;\n\t\t\tthis.providerQuery = this.searchInput.getValue();\n\t\t\tthis.providerIndex = this.selectedIndex;\n\t\t\tthis.selectedProvider = provider;\n\t\t\tthis.view = \"models\";\n\t\t\tthis.searchInput.setValue(\"\");\n\t\t\tthis.selectCurrent();\n\t\t\tthis.filterItems(\"\");\n\t\t\treturn;\n\t\t}\n\t\tconst item = this.filteredModels[this.selectedIndex];\n\t\tif (!item) return;\n\t\tif (this.persistDefault) this.settingsManager.setDefaultModelAndProvider(item.provider, item.id);\n\t\tthis.onSelectCallback(item.model);\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\tthis.toggleModelScope();\n\t\t} else if (kb.matches(keyData, \"tui.select.up\")) {\n\t\t\tthis.moveSelection(-1);\n\t\t} else if (kb.matches(keyData, \"tui.select.down\")) {\n\t\t\tthis.moveSelection(1);\n\t\t} else if (kb.matches(keyData, \"tui.select.pageUp\")) {\n\t\t\tthis.moveSelection(-Math.min(10, Math.max(0, this.itemCount() - 1)));\n\t\t} else if (kb.matches(keyData, \"tui.select.pageDown\")) {\n\t\t\tthis.moveSelection(Math.min(10, Math.max(0, this.itemCount() - 1)));\n\t\t} else if (kb.matches(keyData, \"tui.select.confirm\")) {\n\t\t\tthis.confirmSelection();\n\t\t} else if (kb.matches(keyData, \"tui.select.cancel\")) {\n\t\t\tif (this.view === \"models\") {\n\t\t\t\tthis.view = \"providers\";\n\t\t\t\tthis.selectedProvider = null;\n\t\t\t\tthis.searchInput.setValue(this.providerQuery);\n\t\t\t\tthis.filterItems(this.providerQuery);\n\t\t\t\tthis.selectedIndex = Math.min(this.providerIndex, Math.max(0, this.itemCount() - 1));\n\t\t\t\tthis.updateList();\n\t\t\t} else {\n\t\t\t\tthis.onCancelCallback();\n\t\t\t}\n\t\t} else {\n\t\t\tconst query = this.searchInput.getValue();\n\t\t\tthis.searchInput.handleInput(keyData);\n\t\t\tif (query !== this.searchInput.getValue()) this.filterItems(this.searchInput.getValue());\n\t\t}\n\t}\n\n\tgetSearchInput(): Input {\n\t\treturn this.searchInput;\n\t}\n}\n"]}
@@ -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,qBAAqB,CAAC;AAC7B,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,KAAK,iBAAiB,GAAG,OAAO,GAAG,QAAQ,CAAC;AAC5C;;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,CAAoB;IAChC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,aAAa,CAAqC;IAC1D,OAAO,CAAC,gBAAgB,CAA+B;IACvD,OAAO,CAAC,gBAAgB,CAAa;IAErC,YACC,IAAI,EAAE,iBAAiB,EACvB,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,oBAAoB,EAAE,EACjC,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,EACtC,QAAQ,EAAE,MAAM,IAAI,EACpB,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,UAAU,EA0ClD;IAED,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,UAAU;IA+ClB,OAAO,CAAC,qBAAqB;IA0B7B,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CA8BjC;CACD","sourcesContent":["import {\n\tContainer,\n\ttype Focusable,\n\tfuzzyFilter,\n\tgetKeybindings,\n\tInput,\n\tSpacer,\n\tTruncatedText,\n} from \"@greppleai/grip-tui\";\nimport type { AuthStatus, AuthStorage } from \"../../../core/auth-storage.ts\";\nimport { theme } from \"../theme/theme.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\n\nexport type AuthSelectorProvider = {\n\tid: string;\n\tname: string;\n\tauthType: \"oauth\" | \"api_key\";\n};\n\ntype OAuthSelectorMode = \"login\" | \"logout\";\n/**\n * Component that renders an auth provider selector\n */\nexport class OAuthSelectorComponent extends Container implements Focusable {\n\tprivate searchInput: Input;\n\n\t// Focusable implementation - propagate to search 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.searchInput.focused = value;\n\t}\n\n\tprivate listContainer: Container;\n\tprivate allProviders: AuthSelectorProvider[];\n\tprivate filteredProviders: AuthSelectorProvider[];\n\tprivate selectedIndex: number = 0;\n\tprivate mode: OAuthSelectorMode;\n\tprivate authStorage: AuthStorage;\n\tprivate getAuthStatus: (providerId: string) => AuthStatus;\n\tprivate onSelectCallback: (providerId: string) => void;\n\tprivate onCancelCallback: () => void;\n\n\tconstructor(\n\t\tmode: OAuthSelectorMode,\n\t\tauthStorage: AuthStorage,\n\t\tproviders: AuthSelectorProvider[],\n\t\tonSelect: (providerId: string) => void,\n\t\tonCancel: () => void,\n\t\tgetAuthStatus?: (providerId: string) => AuthStatus,\n\t) {\n\t\tsuper();\n\n\t\tthis.mode = mode;\n\t\tthis.authStorage = authStorage;\n\t\tthis.getAuthStatus = getAuthStatus ?? ((providerId) => this.authStorage.getAuthStatus(providerId));\n\t\tthis.allProviders = providers;\n\t\tthis.filteredProviders = providers;\n\t\tthis.onSelectCallback = onSelect;\n\t\tthis.onCancelCallback = onCancel;\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 title\n\t\tconst title = mode === \"login\" ? \"Select provider to configure:\" : \"Select provider to logout:\";\n\t\tthis.addChild(new TruncatedText(theme.fg(\"accent\", theme.bold(title)), 1, 0));\n\t\tthis.addChild(new Spacer(1));\n\n\t\tthis.searchInput = new Input();\n\t\tthis.searchInput.onSubmit = () => {\n\t\t\tconst selectedProvider = this.filteredProviders[this.selectedIndex];\n\t\t\tif (selectedProvider) {\n\t\t\t\tthis.onSelectCallback(selectedProvider.id);\n\t\t\t}\n\t\t};\n\t\tthis.addChild(this.searchInput);\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// Initial render\n\t\tthis.filterProviders(\"\");\n\t}\n\n\tprivate filterProviders(query: string): void {\n\t\tthis.filteredProviders = query\n\t\t\t? fuzzyFilter(this.allProviders, query, (provider) => `${provider.name} ${provider.id} ${provider.authType}`)\n\t\t\t: this.allProviders;\n\t\tthis.selectedIndex = Math.max(0, Math.min(this.selectedIndex, Math.max(0, this.filteredProviders.length - 1)));\n\t\tthis.updateList();\n\t}\n\n\tprivate updateList(): void {\n\t\tthis.listContainer.clear();\n\n\t\tconst maxVisible = 8;\n\t\tconst startIndex = Math.max(\n\t\t\t0,\n\t\t\tMath.min(this.selectedIndex - Math.floor(maxVisible / 2), this.filteredProviders.length - maxVisible),\n\t\t);\n\t\tconst endIndex = Math.min(startIndex + maxVisible, this.filteredProviders.length);\n\n\t\tfor (let i = startIndex; i < endIndex; i++) {\n\t\t\tconst provider = this.filteredProviders[i];\n\t\t\tif (!provider) continue;\n\n\t\t\tconst isSelected = i === this.selectedIndex;\n\n\t\t\tconst statusIndicator = this.formatStatusIndicator(provider);\n\t\t\tlet line = \"\";\n\t\t\tif (isSelected) {\n\t\t\t\tconst prefix = theme.fg(\"accent\", \"→ \");\n\t\t\t\tconst text = theme.fg(\"accent\", provider.name);\n\t\t\t\tline = prefix + text + statusIndicator;\n\t\t\t} else {\n\t\t\t\tconst text = ` ${theme.fg(\"text\", provider.name)}`;\n\t\t\t\tline = text + statusIndicator;\n\t\t\t}\n\n\t\t\tthis.listContainer.addChild(new TruncatedText(line, 1, 0));\n\t\t}\n\n\t\tif (startIndex > 0 || endIndex < this.filteredProviders.length) {\n\t\t\tconst scrollInfo = theme.fg(\"muted\", ` (${this.selectedIndex + 1}/${this.filteredProviders.length})`);\n\t\t\tthis.listContainer.addChild(new TruncatedText(scrollInfo, 1, 0));\n\t\t}\n\n\t\t// Show \"no providers\" if empty\n\t\tif (this.filteredProviders.length === 0) {\n\t\t\tconst message =\n\t\t\t\tthis.allProviders.length === 0\n\t\t\t\t\t? this.mode === \"login\"\n\t\t\t\t\t\t? \"No providers available\"\n\t\t\t\t\t\t: \"No providers logged in. Use /login first.\"\n\t\t\t\t\t: \"No matching providers\";\n\t\t\tthis.listContainer.addChild(new TruncatedText(theme.fg(\"muted\", ` ${message}`), 1, 0));\n\t\t}\n\t}\n\n\tprivate formatStatusIndicator(provider: AuthSelectorProvider): string {\n\t\tconst credential = this.authStorage.get(provider.id);\n\t\tif (credential?.type === provider.authType) return theme.fg(\"success\", \" ✓ configured\");\n\t\tif (credential) {\n\t\t\tconst label = credential.type === \"oauth\" ? \"subscription configured\" : \"API key configured\";\n\t\t\treturn theme.fg(\"muted\", \" • \") + theme.fg(\"warning\", label);\n\t\t}\n\t\tif (provider.authType !== \"api_key\") return theme.fg(\"muted\", \" • unconfigured\");\n\n\t\tconst status = this.getAuthStatus(provider.id);\n\t\tswitch (status.source) {\n\t\t\tcase \"environment\":\n\t\t\t\treturn theme.fg(\"success\", ` ✓ env: ${status.label ?? \"API key\"}`);\n\t\t\tcase \"runtime\":\n\t\t\t\treturn theme.fg(\"success\", \" ✓ runtime API key\");\n\t\t\tcase \"fallback\":\n\t\t\t\treturn theme.fg(\"success\", \" ✓ custom API key\");\n\t\t\tcase \"models_json_key\":\n\t\t\t\treturn theme.fg(\"success\", \" ✓ key in models.json\");\n\t\t\tcase \"models_json_command\":\n\t\t\t\treturn theme.fg(\"success\", \" ✓ command in models.json\");\n\t\t\tdefault:\n\t\t\t\treturn theme.fg(\"muted\", \" • unconfigured\");\n\t\t}\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getKeybindings();\n\t\t// Up arrow\n\t\tif (kb.matches(keyData, \"tui.select.up\")) {\n\t\t\tif (this.filteredProviders.length === 0) return;\n\t\t\tthis.selectedIndex = Math.max(0, this.selectedIndex - 1);\n\t\t\tthis.updateList();\n\t\t}\n\t\t// Down arrow\n\t\telse if (kb.matches(keyData, \"tui.select.down\")) {\n\t\t\tif (this.filteredProviders.length === 0) return;\n\t\t\tthis.selectedIndex = Math.min(this.filteredProviders.length - 1, 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 selectedProvider = this.filteredProviders[this.selectedIndex];\n\t\t\tif (selectedProvider) {\n\t\t\t\tthis.onSelectCallback(selectedProvider.id);\n\t\t\t}\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.filterProviders(this.searchInput.getValue());\n\t\t}\n\t}\n}\n"]}
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,qBAAqB,CAAC;AAC7B,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,KAAK,iBAAiB,GAAG,OAAO,GAAG,QAAQ,CAAC;AAC5C;;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,CAAoB;IAChC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,aAAa,CAAqC;IAC1D,OAAO,CAAC,gBAAgB,CAA+B;IACvD,OAAO,CAAC,gBAAgB,CAAa;IAErC,YACC,IAAI,EAAE,iBAAiB,EACvB,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,oBAAoB,EAAE,EACjC,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,EACtC,QAAQ,EAAE,MAAM,IAAI,EACpB,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,UAAU,EA0ClD;IAED,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,UAAU;IA+ClB,OAAO,CAAC,qBAAqB;IA0B7B,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CA8BjC;CACD"}