@greppleai/grip 0.1.4 → 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 (569) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README.md +2 -2
  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 +6 -11
  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 +11 -23
  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 +9 -15
  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 +21 -17
  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 +26 -18
  432. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  433. package/dist/modes/interactive/components/model-selector.js +223 -210
  434. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  435. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  436. package/dist/modes/interactive/components/oauth-selector.js +3 -12
  437. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  438. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  439. package/dist/modes/interactive/components/scoped-models-selector.js +9 -13
  440. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  441. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  442. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  443. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  444. package/dist/modes/interactive/components/session-selector.js +33 -58
  445. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  446. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  447. package/dist/modes/interactive/components/settings-selector.js +0 -4
  448. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  449. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
  450. package/dist/modes/interactive/components/show-images-selector.js +0 -1
  451. package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
  452. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  453. package/dist/modes/interactive/components/skill-invocation-message.js +1 -3
  454. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  455. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
  456. package/dist/modes/interactive/components/theme-selector.js +0 -2
  457. package/dist/modes/interactive/components/theme-selector.js.map +1 -1
  458. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  459. package/dist/modes/interactive/components/thinking-selector.js +0 -1
  460. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  461. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  462. package/dist/modes/interactive/components/tool-execution.js +9 -24
  463. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  464. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  465. package/dist/modes/interactive/components/tree-selector.js +18 -34
  466. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  467. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  468. package/dist/modes/interactive/components/user-message-selector.js +3 -6
  469. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  470. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  471. package/dist/modes/interactive/components/user-message.js +0 -4
  472. package/dist/modes/interactive/components/user-message.js.map +1 -1
  473. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
  474. package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
  475. package/dist/modes/interactive/interactive-mode.d.ts +14 -0
  476. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  477. package/dist/modes/interactive/interactive-mode.js +223 -137
  478. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  479. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  480. package/dist/modes/interactive/theme/theme.js +0 -7
  481. package/dist/modes/interactive/theme/theme.js.map +1 -1
  482. package/dist/modes/json-event.d.ts.map +1 -1
  483. package/dist/modes/json-event.js.map +1 -1
  484. package/dist/modes/print-mode.d.ts.map +1 -1
  485. package/dist/modes/print-mode.js.map +1 -1
  486. package/dist/modes/rpc/jsonl.d.ts.map +1 -1
  487. package/dist/modes/rpc/jsonl.js.map +1 -1
  488. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  489. package/dist/modes/rpc/rpc-client.js +10 -11
  490. package/dist/modes/rpc/rpc-client.js.map +1 -1
  491. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  492. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  493. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  494. package/dist/package-manager-cli.d.ts.map +1 -1
  495. package/dist/package-manager-cli.js.map +1 -1
  496. package/dist/utils/ansi.d.ts.map +1 -1
  497. package/dist/utils/ansi.js.map +1 -1
  498. package/dist/utils/changelog.d.ts.map +1 -1
  499. package/dist/utils/changelog.js.map +1 -1
  500. package/dist/utils/child-process.d.ts.map +1 -1
  501. package/dist/utils/child-process.js.map +1 -1
  502. package/dist/utils/clipboard-image.d.ts.map +1 -1
  503. package/dist/utils/clipboard-image.js.map +1 -1
  504. package/dist/utils/clipboard-native.d.ts.map +1 -1
  505. package/dist/utils/clipboard-native.js.map +1 -1
  506. package/dist/utils/clipboard.d.ts.map +1 -1
  507. package/dist/utils/clipboard.js.map +1 -1
  508. package/dist/utils/deprecation.d.ts.map +1 -1
  509. package/dist/utils/deprecation.js.map +1 -1
  510. package/dist/utils/directory-completions.d.ts.map +1 -1
  511. package/dist/utils/directory-completions.js.map +1 -1
  512. package/dist/utils/exif-orientation.d.ts.map +1 -1
  513. package/dist/utils/exif-orientation.js.map +1 -1
  514. package/dist/utils/frontmatter.d.ts.map +1 -1
  515. package/dist/utils/frontmatter.js.map +1 -1
  516. package/dist/utils/fs-watch.d.ts.map +1 -1
  517. package/dist/utils/fs-watch.js.map +1 -1
  518. package/dist/utils/git.d.ts.map +1 -1
  519. package/dist/utils/git.js.map +1 -1
  520. package/dist/utils/grip-user-agent.d.ts.map +1 -1
  521. package/dist/utils/grip-user-agent.js +1 -1
  522. package/dist/utils/grip-user-agent.js.map +1 -1
  523. package/dist/utils/html.d.ts.map +1 -1
  524. package/dist/utils/html.js.map +1 -1
  525. package/dist/utils/image-convert.d.ts.map +1 -1
  526. package/dist/utils/image-convert.js.map +1 -1
  527. package/dist/utils/image-process.d.ts.map +1 -1
  528. package/dist/utils/image-process.js.map +1 -1
  529. package/dist/utils/image-resize-core.d.ts.map +1 -1
  530. package/dist/utils/image-resize-core.js.map +1 -1
  531. package/dist/utils/image-resize-worker.d.ts.map +1 -1
  532. package/dist/utils/image-resize-worker.js.map +1 -1
  533. package/dist/utils/image-resize.d.ts.map +1 -1
  534. package/dist/utils/image-resize.js.map +1 -1
  535. package/dist/utils/json.d.ts.map +1 -1
  536. package/dist/utils/json.js.map +1 -1
  537. package/dist/utils/mime.d.ts.map +1 -1
  538. package/dist/utils/mime.js.map +1 -1
  539. package/dist/utils/open-browser.d.ts.map +1 -1
  540. package/dist/utils/open-browser.js.map +1 -1
  541. package/dist/utils/paths.d.ts.map +1 -1
  542. package/dist/utils/paths.js.map +1 -1
  543. package/dist/utils/photon.d.ts.map +1 -1
  544. package/dist/utils/photon.js +10 -5
  545. package/dist/utils/photon.js.map +1 -1
  546. package/dist/utils/shell.d.ts.map +1 -1
  547. package/dist/utils/shell.js.map +1 -1
  548. package/dist/utils/sleep.d.ts.map +1 -1
  549. package/dist/utils/sleep.js.map +1 -1
  550. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  551. package/dist/utils/syntax-highlight.js +1 -1
  552. package/dist/utils/syntax-highlight.js.map +1 -1
  553. package/dist/utils/tools-manager.d.ts.map +1 -1
  554. package/dist/utils/tools-manager.js.map +1 -1
  555. package/dist/utils/version-check.d.ts.map +1 -1
  556. package/dist/utils/version-check.js.map +1 -1
  557. package/dist/utils/windows-self-update.d.ts.map +1 -1
  558. package/dist/utils/windows-self-update.js.map +1 -1
  559. package/docs/keybindings.md +3 -1
  560. package/docs/providers.md +3 -1
  561. package/docs/sandbox.md +7 -1
  562. package/docs/sessions.md +1 -1
  563. package/docs/usage.md +39 -2
  564. package/examples/extensions/custom-provider-anthropic/package.json +2 -2
  565. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  566. package/examples/extensions/sandbox/package.json +2 -2
  567. package/examples/extensions/with-deps/package.json +1 -1
  568. package/npm-shrinkwrap.json +601 -833
  569. 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":"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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 +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,14 +1,12 @@
1
- import { type Model } from "@greppleai/grip-ai";
1
+ import { type Api, type Model } from "@greppleai/grip-ai";
2
2
  import { Container, type Focusable, Input, type TUI } from "@greppleai/grip-tui";
3
3
  import type { ModelRegistry } from "../../../core/model-registry.ts";
4
4
  import type { SettingsManager } from "../../../core/settings-manager.ts";
5
5
  interface ScopedModelItem {
6
- model: Model<any>;
6
+ model: Model<Api>;
7
7
  thinkingLevel?: string;
8
8
  }
9
- /**
10
- * Component that renders a model selector with search
11
- */
9
+ /** Native provider/model navigation, with a global model-search entry point. */
12
10
  export declare class ModelSelectorComponent extends Container implements Focusable {
13
11
  private searchInput;
14
12
  private _focused;
@@ -19,33 +17,43 @@ export declare class ModelSelectorComponent extends Container implements Focusab
19
17
  private scopedModelItems;
20
18
  private activeModels;
21
19
  private filteredModels;
20
+ private providers;
21
+ private filteredProviders;
22
+ private selectedProvider;
23
+ private providerQuery;
24
+ private providerIndex;
25
+ private view;
22
26
  private selectedIndex;
23
- private currentModel?;
27
+ private currentModel;
24
28
  private settingsManager;
25
29
  private modelRegistry;
26
30
  private onSelectCallback;
27
31
  private onCancelCallback;
28
- private errorMessage?;
32
+ private errorMessage;
33
+ private loading;
34
+ private listWidth;
29
35
  private tui;
30
36
  private scopedModels;
31
37
  private scope;
32
- private scopeText?;
33
- private scopeHintText?;
38
+ private scopeText;
39
+ private navigationText;
34
40
  private readonly persistDefault;
35
- constructor(tui: TUI, currentModel: Model<any> | undefined, settingsManager: SettingsManager, modelRegistry: ModelRegistry, scopedModels: ReadonlyArray<ScopedModelItem>, onSelect: (model: Model<any>) => void, onCancel: () => void, initialSearchInput?: string, persistDefault?: boolean);
41
+ constructor(tui: TUI, currentModel: Model<Api> | undefined, settingsManager: SettingsManager, modelRegistry: ModelRegistry, scopedModels: ReadonlyArray<ScopedModelItem>, onSelect: (model: Model<Api>) => void, onCancel: () => void, initialSearchInput?: string, persistDefault?: boolean);
36
42
  private loadModels;
37
- private sortModels;
38
- private getScopeText;
39
- private getScopeHintText;
40
- private setScope;
41
- private filterModels;
42
- private appendModelListStatus;
43
+ private rebuildProviders;
44
+ private selectCurrent;
45
+ private getModelItems;
46
+ private filterItems;
47
+ private itemCount;
48
+ private updateHeader;
43
49
  private updateList;
50
+ private appendListStatus;
51
+ private addListLine;
52
+ render(width: number): string[];
44
53
  private toggleModelScope;
45
54
  private moveSelection;
46
- private selectHighlightedModel;
55
+ private confirmSelection;
47
56
  handleInput(keyData: string): void;
48
- private handleSelect;
49
57
  getSearchInput(): Input;
50
58
  }
51
59
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"model-selector.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/model-selector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAkB,MAAM,oBAAoB,CAAC;AAChE,OAAO,EACN,SAAS,EACT,KAAK,SAAS,EAGd,KAAK,EAGL,KAAK,GAAG,EACR,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;AAID;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,SAAU,YAAW,SAAS;IACzE,OAAO,CAAC,WAAW,CAAQ;IAG3B,OAAO,CAAC,QAAQ,CAAS;IACzB,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAGzB;IACD,OAAO,CAAC,aAAa,CAAY;IACjC,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,YAAY,CAAmB;IACvC,OAAO,CAAC,cAAc,CAAmB;IACzC,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,YAAY,CAAC,CAAa;IAClC,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,gBAAgB,CAA8B;IACtD,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,SAAS,CAAC,CAAO;IACzB,OAAO,CAAC,aAAa,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+DrB;YAEa,UAAU;IAoDxB,OAAO,CAAC,UAAU;IAalB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,QAAQ;IAYhB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,qBAAqB;IAe7B,OAAO,CAAC,UAAU;IA6ClB,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,sBAAsB;IAK9B,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAwBjC;IAED,OAAO,CAAC,YAAY;IAMpB,cAAc,IAAI,KAAK,CAEtB;CACD","sourcesContent":["import { 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} 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<any>;\n}\n\ninterface ScopedModelItem {\n\tmodel: Model<any>;\n\tthinkingLevel?: string;\n}\n\ntype ModelScope = \"all\" | \"scoped\";\n\n/**\n * Component that renders a model selector with search\n */\nexport class ModelSelectorComponent extends Container implements Focusable {\n\tprivate searchInput: Input;\n\n\t// Focusable implementation - propagate to searchInput for IME cursor positioning\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.searchInput.focused = value;\n\t}\n\tprivate listContainer: Container;\n\tprivate allModels: ModelItem[] = [];\n\tprivate scopedModelItems: ModelItem[] = [];\n\tprivate activeModels: ModelItem[] = [];\n\tprivate filteredModels: ModelItem[] = [];\n\tprivate selectedIndex: number = 0;\n\tprivate currentModel?: Model<any>;\n\tprivate settingsManager: SettingsManager;\n\tprivate modelRegistry: ModelRegistry;\n\tprivate onSelectCallback: (model: Model<any>) => void;\n\tprivate onCancelCallback: () => void;\n\tprivate errorMessage?: string;\n\tprivate tui: TUI;\n\tprivate scopedModels: ReadonlyArray<ScopedModelItem>;\n\tprivate scope: ModelScope = \"all\";\n\tprivate scopeText?: Text;\n\tprivate scopeHintText?: Text;\n\tprivate readonly persistDefault: boolean;\n\n\tconstructor(\n\t\ttui: TUI,\n\t\tcurrentModel: Model<any> | undefined,\n\t\tsettingsManager: SettingsManager,\n\t\tmodelRegistry: ModelRegistry,\n\t\tscopedModels: ReadonlyArray<ScopedModelItem>,\n\t\tonSelect: (model: Model<any>) => void,\n\t\tonCancel: () => void,\n\t\tinitialSearchInput?: string,\n\t\tpersistDefault = true,\n\t) {\n\t\tsuper();\n\n\t\tthis.tui = tui;\n\t\tthis.currentModel = currentModel;\n\t\tthis.settingsManager = settingsManager;\n\t\tthis.modelRegistry = modelRegistry;\n\t\tthis.scopedModels = scopedModels;\n\t\tthis.scope = scopedModels.length > 0 ? \"scoped\" : \"all\";\n\t\tthis.onSelectCallback = onSelect;\n\t\tthis.onCancelCallback = onCancel;\n\t\tthis.persistDefault = persistDefault;\n\t\t// Add top border\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add hint about model filtering\n\t\tif (scopedModels.length > 0) {\n\t\t\tthis.scopeText = new Text(this.getScopeText(), 0, 0);\n\t\t\tthis.addChild(this.scopeText);\n\t\t\tthis.scopeHintText = new Text(this.getScopeHintText(), 0, 0);\n\t\t\tthis.addChild(this.scopeHintText);\n\t\t} else {\n\t\t\tconst hintText = \"Only showing models from configured providers. Use /login to add providers.\";\n\t\t\tthis.addChild(new Text(theme.fg(\"warning\", hintText), 0, 0));\n\t\t}\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Create search input\n\t\tthis.searchInput = new Input();\n\t\tif (initialSearchInput) {\n\t\t\tthis.searchInput.setValue(initialSearchInput);\n\t\t}\n\t\tthis.searchInput.onSubmit = () => {\n\t\t\t// Enter on search input selects the first filtered item\n\t\t\tif (this.filteredModels[this.selectedIndex]) {\n\t\t\t\tthis.handleSelect(this.filteredModels[this.selectedIndex].model);\n\t\t\t}\n\t\t};\n\t\tthis.addChild(this.searchInput);\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Create list container\n\t\tthis.listContainer = new Container();\n\t\tthis.addChild(this.listContainer);\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add bottom border\n\t\tthis.addChild(new DynamicBorder());\n\n\t\t// Load models and do initial render\n\t\tthis.loadModels().then(() => {\n\t\t\tif (initialSearchInput) {\n\t\t\t\tthis.filterModels(initialSearchInput);\n\t\t\t} else {\n\t\t\t\tthis.updateList();\n\t\t\t}\n\t\t\t// Request re-render after models are loaded\n\t\t\tthis.tui.requestRender();\n\t\t});\n\t}\n\n\tprivate async loadModels(): Promise<void> {\n\t\tlet models: ModelItem[];\n\n\t\t// Refresh to pick up any changes to models.json\n\t\tthis.modelRegistry.refresh();\n\n\t\t// Check for models.json errors\n\t\tconst loadError = this.modelRegistry.getError();\n\t\tif (loadError) {\n\t\t\tthis.errorMessage = loadError;\n\t\t}\n\n\t\t// Load available models (built-in models still work even if models.json failed)\n\t\ttry {\n\t\t\tconst availableModels = await this.modelRegistry.getAvailable();\n\t\t\tmodels = availableModels.map((model: Model<any>) => ({\n\t\t\t\tprovider: model.provider,\n\t\t\t\tid: model.id,\n\t\t\t\tmodel,\n\t\t\t}));\n\t\t} catch (error) {\n\t\t\tthis.allModels = [];\n\t\t\tthis.scopedModelItems = [];\n\t\t\tthis.activeModels = [];\n\t\t\tthis.filteredModels = [];\n\t\t\tthis.errorMessage = error instanceof Error ? error.message : String(error);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.allModels = this.sortModels(models);\n\t\tconst registeredModels = new Map<string, Map<string, Model<any>>>();\n\t\tfor (const model of this.modelRegistry.getAll()) {\n\t\t\tconst providerModels = registeredModels.get(model.provider) ?? new Map<string, Model<any>>();\n\t\t\tif (!providerModels.has(model.id)) providerModels.set(model.id, model);\n\t\t\tregisteredModels.set(model.provider, providerModels);\n\t\t}\n\t\tthis.scopedModels = this.scopedModels.map((scoped) => {\n\t\t\tconst refreshed = registeredModels.get(scoped.model.provider)?.get(scoped.model.id);\n\t\t\treturn refreshed ? { ...scoped, model: refreshed } : scoped;\n\t\t});\n\t\tthis.scopedModelItems = this.scopedModels.map((scoped) => ({\n\t\t\tprovider: scoped.model.provider,\n\t\t\tid: scoped.model.id,\n\t\t\tmodel: scoped.model,\n\t\t}));\n\t\tthis.activeModels = this.scope === \"scoped\" ? this.scopedModelItems : this.allModels;\n\t\tthis.filteredModels = this.activeModels;\n\t\tconst currentIndex = this.filteredModels.findIndex((item) => modelsAreEqual(this.currentModel, item.model));\n\t\tthis.selectedIndex =\n\t\t\tcurrentIndex >= 0 ? currentIndex : Math.min(this.selectedIndex, Math.max(0, this.filteredModels.length - 1));\n\t}\n\n\tprivate sortModels(models: ModelItem[]): ModelItem[] {\n\t\tconst sorted = [...models];\n\t\t// Sort: current model first, then by provider\n\t\tsorted.sort((a, b) => {\n\t\t\tconst aIsCurrent = modelsAreEqual(this.currentModel, a.model);\n\t\t\tconst bIsCurrent = modelsAreEqual(this.currentModel, b.model);\n\t\t\tif (aIsCurrent && !bIsCurrent) return -1;\n\t\t\tif (!aIsCurrent && bIsCurrent) return 1;\n\t\t\treturn a.provider.localeCompare(b.provider);\n\t\t});\n\t\treturn sorted;\n\t}\n\n\tprivate getScopeText(): string {\n\t\tconst allText = this.scope === \"all\" ? theme.fg(\"accent\", \"all\") : theme.fg(\"muted\", \"all\");\n\t\tconst scopedText = this.scope === \"scoped\" ? theme.fg(\"accent\", \"scoped\") : theme.fg(\"muted\", \"scoped\");\n\t\treturn `${theme.fg(\"muted\", \"Scope: \")}${allText}${theme.fg(\"muted\", \" | \")}${scopedText}`;\n\t}\n\n\tprivate getScopeHintText(): string {\n\t\treturn keyHint(\"tui.input.tab\", \"scope\") + theme.fg(\"muted\", \" (all/scoped)\");\n\t}\n\n\tprivate setScope(scope: ModelScope): void {\n\t\tif (this.scope === scope) return;\n\t\tthis.scope = scope;\n\t\tthis.activeModels = this.scope === \"scoped\" ? this.scopedModelItems : this.allModels;\n\t\tconst currentIndex = this.activeModels.findIndex((item) => modelsAreEqual(this.currentModel, item.model));\n\t\tthis.selectedIndex = currentIndex >= 0 ? currentIndex : 0;\n\t\tthis.filterModels(this.searchInput.getValue());\n\t\tif (this.scopeText) {\n\t\t\tthis.scopeText.setText(this.getScopeText());\n\t\t}\n\t}\n\n\tprivate filterModels(query: string): void {\n\t\tthis.filteredModels = query\n\t\t\t? fuzzyFilter(\n\t\t\t\t\tthis.activeModels,\n\t\t\t\t\tquery,\n\t\t\t\t\t({ id, provider }) => `${id} ${provider} ${provider}/${id} ${provider} ${id}`,\n\t\t\t\t)\n\t\t\t: this.activeModels;\n\t\t// A query changes fuzzy-match ranking, so select the best match. When the query\n\t\t// is cleared, preserve the current position and only clamp it to the restored list.\n\t\tthis.selectedIndex = query ? 0 : Math.min(this.selectedIndex, Math.max(0, this.filteredModels.length - 1));\n\t\tthis.updateList();\n\t}\n\n\tprivate appendModelListStatus(): void {\n\t\tif (this.errorMessage) {\n\t\t\tfor (const line of this.errorMessage.split(\"\\n\")) {\n\t\t\t\tthis.listContainer.addChild(new Text(theme.fg(\"error\", line), 0, 0));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (this.filteredModels.length === 0) {\n\t\t\tthis.listContainer.addChild(new Text(theme.fg(\"muted\", \" No matching models\"), 0, 0));\n\t\t\treturn;\n\t\t}\n\t\tconst selected = this.filteredModels[this.selectedIndex];\n\t\tthis.listContainer.addChild(new Spacer(1));\n\t\tthis.listContainer.addChild(new Text(theme.fg(\"muted\", ` Model Name: ${selected.model.name}`), 0, 0));\n\t}\n\tprivate updateList(): void {\n\t\tthis.listContainer.clear();\n\n\t\tconst maxVisible = 10;\n\t\tconst startIndex = Math.max(\n\t\t\t0,\n\t\t\tMath.min(this.selectedIndex - Math.floor(maxVisible / 2), this.filteredModels.length - maxVisible),\n\t\t);\n\t\tconst endIndex = Math.min(startIndex + maxVisible, this.filteredModels.length);\n\n\t\t// Show visible slice of filtered models\n\t\tfor (let i = startIndex; i < endIndex; i++) {\n\t\t\tconst item = this.filteredModels[i];\n\t\t\tif (!item) continue;\n\n\t\t\tconst isSelected = i === this.selectedIndex;\n\t\t\tconst isCurrent = modelsAreEqual(this.currentModel, item.model);\n\n\t\t\tlet line = \"\";\n\t\t\tif (isSelected) {\n\t\t\t\tconst prefix = theme.fg(\"accent\", \"→ \");\n\t\t\t\tconst modelText = `${item.id}`;\n\t\t\t\tconst providerBadge = theme.fg(\"muted\", `[${item.provider}]`);\n\t\t\t\tconst checkmark = isCurrent ? theme.fg(\"success\", \" ✓\") : \"\";\n\t\t\t\tline = `${prefix + theme.fg(\"accent\", modelText)} ${providerBadge}${checkmark}`;\n\t\t\t} else {\n\t\t\t\tconst modelText = ` ${item.id}`;\n\t\t\t\tconst providerBadge = theme.fg(\"muted\", `[${item.provider}]`);\n\t\t\t\tconst checkmark = isCurrent ? theme.fg(\"success\", \" ✓\") : \"\";\n\t\t\t\tline = `${modelText} ${providerBadge}${checkmark}`;\n\t\t\t}\n\n\t\t\tthis.listContainer.addChild(new Text(line, 0, 0));\n\t\t}\n\n\t\t// Add scroll indicator if needed\n\t\tif (startIndex > 0 || endIndex < this.filteredModels.length) {\n\t\t\tconst scrollInfo = theme.fg(\"muted\", ` (${this.selectedIndex + 1}/${this.filteredModels.length})`);\n\t\t\tthis.listContainer.addChild(new Text(scrollInfo, 0, 0));\n\t\t}\n\n\t\t// Show error message or \"no results\" if empty\n\t\tthis.appendModelListStatus();\n\t}\n\n\tprivate toggleModelScope(): void {\n\t\tif (this.scopedModelItems.length === 0) return;\n\t\tconst nextScope: ModelScope = this.scope === \"all\" ? \"scoped\" : \"all\";\n\t\tthis.setScope(nextScope);\n\t\tthis.scopeHintText?.setText(this.getScopeHintText());\n\t}\n\n\tprivate moveSelection(direction: -1 | 1): void {\n\t\tif (this.filteredModels.length === 0) return;\n\t\tif (direction < 0) {\n\t\t\tthis.selectedIndex = this.selectedIndex === 0 ? this.filteredModels.length - 1 : this.selectedIndex - 1;\n\t\t} else {\n\t\t\tthis.selectedIndex = this.selectedIndex === this.filteredModels.length - 1 ? 0 : this.selectedIndex + 1;\n\t\t}\n\t\tthis.updateList();\n\t}\n\n\tprivate selectHighlightedModel(): void {\n\t\tconst selectedModel = this.filteredModels[this.selectedIndex];\n\t\tif (selectedModel) this.handleSelect(selectedModel.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\treturn;\n\t\t}\n\t\tif (kb.matches(keyData, \"tui.select.up\")) {\n\t\t\tthis.moveSelection(-1);\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(keyData, \"tui.select.down\")) {\n\t\t\tthis.moveSelection(1);\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(keyData, \"tui.select.confirm\")) {\n\t\t\tthis.selectHighlightedModel();\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(keyData, \"tui.select.cancel\")) {\n\t\t\tthis.onCancelCallback();\n\t\t\treturn;\n\t\t}\n\t\tthis.searchInput.handleInput(keyData);\n\t\tthis.filterModels(this.searchInput.getValue());\n\t}\n\n\tprivate handleSelect(model: Model<any>): void {\n\t\t// Save as new default\n\t\tif (this.persistDefault) this.settingsManager.setDefaultModelAndProvider(model.provider, model.id);\n\t\tthis.onSelectCallback(model);\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"}